diff --git a/build-scripts/gulp/webpack.js b/build-scripts/gulp/webpack.js index 8639296a6e..e257fd58a7 100644 --- a/build-scripts/gulp/webpack.js +++ b/build-scripts/gulp/webpack.js @@ -35,26 +35,29 @@ const isWsl = * listenHost?: string * }} */ -const runDevServer = ({ +const runDevServer = async ({ compiler, contentBase, port, listenHost = "localhost", -}) => - new WebpackDevServer(compiler, { - open: true, - watchContentBase: true, - contentBase, - }).listen(port, listenHost, (err) => { - if (err) { - throw err; - } - // Server listening - log( - "[webpack-dev-server]", - `Project is running at http://localhost:${port}` - ); - }); +}) => { + const server = new WebpackDevServer( + { + open: true, + host: listenHost, + port, + static: { + directory: contentBase, + watch: true, + }, + }, + compiler + ); + + await server.start(); + // Server listening + log("[webpack-dev-server]", `Project is running at http://localhost:${port}`); +}; const doneHandler = (done) => (err, stats) => { if (err) { @@ -107,13 +110,13 @@ gulp.task("webpack-prod-app", () => ) ); -gulp.task("webpack-dev-server-demo", () => { +gulp.task("webpack-dev-server-demo", () => runDevServer({ compiler: webpack(bothBuilds(createDemoConfig, { isProdBuild: false })), contentBase: paths.demo_output_root, port: 8090, - }); -}); + }) +); gulp.task("webpack-prod-demo", () => prodBuild( @@ -123,15 +126,15 @@ gulp.task("webpack-prod-demo", () => ) ); -gulp.task("webpack-dev-server-cast", () => { +gulp.task("webpack-dev-server-cast", () => runDevServer({ compiler: webpack(bothBuilds(createCastConfig, { isProdBuild: false })), contentBase: paths.cast_output_root, port: 8080, // Accessible from the network, because that's how Cast hits it. listenHost: "0.0.0.0", - }); -}); + }) +); gulp.task("webpack-prod-cast", () => prodBuild( @@ -164,14 +167,14 @@ gulp.task("webpack-prod-hassio", () => ) ); -gulp.task("webpack-dev-server-gallery", () => { +gulp.task("webpack-dev-server-gallery", () => runDevServer({ // We don't use the es5 build, but the dev server will fuck up the publicPath if we don't compiler: webpack(bothBuilds(createGalleryConfig, { isProdBuild: false })), contentBase: paths.gallery_output_root, port: 8100, - }); -}); + }) +); gulp.task("webpack-prod-gallery", () => prodBuild( diff --git a/gallery/src/demos/demo-ha-form.ts b/gallery/src/demos/demo-ha-form.ts new file mode 100644 index 0000000000..9f5f9a3d54 --- /dev/null +++ b/gallery/src/demos/demo-ha-form.ts @@ -0,0 +1,212 @@ +/* eslint-disable lit/no-template-arrow */ +import { LitElement, TemplateResult, css, html } from "lit"; +import { customElement } from "lit/decorators"; +import "../../../src/components/ha-form/ha-form"; +import "../../../src/components/ha-card"; +import { applyThemesOnElement } from "../../../src/common/dom/apply_themes_on_element"; +import type { HaFormSchema } from "../../../src/components/ha-form/ha-form"; + +const SCHEMAS: { + title: string; + translations?: Record; + error?: Record; + schema: HaFormSchema[]; +}[] = [ + { + title: "Authentication", + translations: { + username: "Username", + password: "Password", + invalid_login: "Invalid login", + }, + error: { + base: "invalid_login", + }, + schema: [ + { + type: "string", + name: "username", + required: true, + }, + { + type: "string", + name: "password", + required: true, + }, + ], + }, + + { + title: "One of each", + schema: [ + { + type: "constant", + value: "Constant Value", + name: "constant", + required: true, + }, + { + type: "boolean", + name: "bool", + optional: true, + default: false, + }, + { + type: "integer", + name: "int", + optional: true, + default: 10, + }, + { + type: "string", + name: "string", + optional: true, + default: "Default", + }, + { + type: "select", + options: [ + ["default", "default"], + ["other", "other"], + ], + name: "select", + optional: true, + default: "default", + }, + { + type: "multi_select", + options: { + default: "Default", + other: "Other", + }, + name: "multi", + optional: true, + default: ["default"], + }, + ], + }, + { + title: "Multi select", + schema: [ + { + type: "multi_select", + options: { + default: "Default", + other: "Other", + }, + name: "multi", + optional: true, + default: ["default"], + }, + { + type: "multi_select", + options: { + default: "Default", + other: "Other", + uno: "mas", + one: "more", + and: "another_one", + option: "1000", + }, + name: "multi", + optional: true, + default: ["default"], + }, + ], + }, +]; + +@customElement("demo-ha-form") +class DemoHaForm extends LitElement { + private lightModeData: any = []; + + private darkModeData: any = []; + + protected render(): TemplateResult { + return html` + ${SCHEMAS.map((info, idx) => { + const translations = info.translations || {}; + const computeLabel = (schema) => + translations[schema.name] || schema.name; + const computeError = (error) => translations[error] || error; + + return [ + [this.lightModeData, "light"], + [this.darkModeData, "dark"], + ].map( + ([data, type]) => html` +
+ +
+ { + data[idx] = e.detail.value; + this.requestUpdate(); + }} + > +
+
+
${JSON.stringify(data[idx], undefined, 2)}
+
+ ` + ); + })} + `; + } + + firstUpdated(changedProps) { + super.firstUpdated(changedProps); + this.shadowRoot!.querySelectorAll("[data-type=dark]").forEach((el) => { + applyThemesOnElement( + el, + { + default_theme: "default", + default_dark_theme: "default", + themes: {}, + darkMode: false, + }, + "default", + { dark: true } + ); + }); + } + + static styles = css` + .row { + margin: 0 auto; + max-width: 800px; + display: flex; + padding: 50px; + background-color: var(--primary-background-color); + } + ha-card { + width: 100%; + max-width: 384px; + } + pre { + width: 400px; + margin: 0 16px; + overflow: auto; + color: var(--primary-text-color); + } + @media only screen and (max-width: 800px) { + .row { + flex-direction: column; + } + pre { + margin: 16px 0; + } + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-ha-form": DemoHaForm; + } +}