From f2d2901e76b392e87b61970b62e2fdb0f99e7a95 Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Mon, 17 Jun 2024 03:21:06 +0530 Subject: [PATCH 01/14] feat: css variables --- .idea/.gitignore | 5 + .idea/cloud-components.iml | 12 + .idea/codeStyles/Project.xml | 59 +++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .../demo/collection/index.html | 8 +- .../ecc-utils-design/demo/details/index.html | 9 +- .../ecc-utils-design/demo/form/index.html | 49 +- .../collection/collection.styles.ts | 87 +++- .../src/components/collection/collection.ts | 10 +- .../src/components/details/details.styles.ts | 95 ++++ .../src/components/details/details.ts | 80 +-- .../src/components/form/form.styles.ts | 168 +++++-- .../src/components/form/form.ts | 20 +- .../src/styles/primitive.styles.ts | 361 ++++++++++++++ .../src/styles/shoelace.styles.ts | 470 +++++++++--------- 18 files changed, 1059 insertions(+), 399 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/cloud-components.iml create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 packages/ecc-utils-design/src/components/details/details.styles.ts create mode 100644 packages/ecc-utils-design/src/styles/primitive.styles.ts diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..b58b603f --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/cloud-components.iml b/.idea/cloud-components.iml new file mode 100644 index 00000000..24643cc3 --- /dev/null +++ b/.idea/cloud-components.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..c5b88c74 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..79ee123c --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..03d9549e --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..6338d9de --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/packages/ecc-utils-design/demo/collection/index.html b/packages/ecc-utils-design/demo/collection/index.html index 8f6d7333..1bbdd4d2 100644 --- a/packages/ecc-utils-design/demo/collection/index.html +++ b/packages/ecc-utils-design/demo/collection/index.html @@ -3,13 +3,13 @@ + ecc-utils-design + - ecc-utils-design -
diff --git a/packages/ecc-utils-design/demo/details/index.html b/packages/ecc-utils-design/demo/details/index.html index 809673e5..394c19be 100644 --- a/packages/ecc-utils-design/demo/details/index.html +++ b/packages/ecc-utils-design/demo/details/index.html @@ -2,13 +2,8 @@ - - + + ecc-utils-design diff --git a/packages/ecc-utils-design/demo/form/index.html b/packages/ecc-utils-design/demo/form/index.html index c882e2d9..7e82c0fd 100644 --- a/packages/ecc-utils-design/demo/form/index.html +++ b/packages/ecc-utils-design/demo/form/index.html @@ -2,8 +2,8 @@ - - + --> ecc-utils-design @@ -118,6 +118,23 @@ tooltip: "Your email address", }, }, + { + key: "18+", + label: "18+", + type: "switch", + fieldOptions: { + tooltip: "Are you over 18 years old?", + }, + }, + { + key: "id", + label: "ID", + type: "file", + fieldOptions: { + required: true, + tooltip: "Your ID document", + }, + }, { key: "address", label: "Address", @@ -186,25 +203,17 @@ }, ], }, + { + key: "country", + label: "Country", + type: "text", + fieldOptions: { + required: true, + tooltip: "Your country name", + }, + }, ], }, - { - key: "18+", - label: "18+", - type: "switch", - fieldOptions: { - tooltip: "Are you over 18 years old?", - }, - }, - { - key: "id", - label: "ID", - type: "file", - fieldOptions: { - required: true, - tooltip: "Your ID document", - }, - }, ]; render( diff --git a/packages/ecc-utils-design/src/components/collection/collection.styles.ts b/packages/ecc-utils-design/src/components/collection/collection.styles.ts index 637a81a9..d1a0707b 100644 --- a/packages/ecc-utils-design/src/components/collection/collection.styles.ts +++ b/packages/ecc-utils-design/src/components/collection/collection.styles.ts @@ -4,54 +4,89 @@ const styles = css` :host { display: block; } - .collection { - position: relative; - } - .title { - width: 100%; - display: flex; - justify-content: space-between; - margin-right: 1rem; - align-items: center; + /* Header */ + .header { + margin-bottom: var(--ecc-spacing-x-large); } .filters { display: flex; justify-content: flex-end; - gap: 1rem; + gap: var(--ecc-spacing-medium); } - .header { - margin-bottom: 1rem; + /* Error Popup */ + .error { + width: 100%; + position: absolute; + top: var(--ecc-spacing-x-large); + display: flex; + justify-content: center; + z-index: var(--ecc-z-index-tooltip); } + /* Footer */ .footer { - margin-top: 1rem; + margin-top: var(--ecc-spacing-x-large); display: flex; justify-content: center; } + .page { + height: var(--ecc-input-height-medium); + width: var(--ecc-input-height-medium); + } + /* Items */ + sl-details { + margin-bottom: var(--ecc-spacing-medium); + margin-top: var(--ecc-spacing-medium); + } + .title { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + margin-right: var(--ecc-spacing-medium); + height: var(--ecc-input-height-small); + font-size: var(--ecc-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); + } .skeleton-title { width: 30%; - height: 1.5rem; + height: var(--ecc-font-size-medium); } - .skeleton-body { - width: 100%; - height: 1rem; + .badge { + height: var(--ecc-input-height-small); + } + .badge::part(base) { + font-size: var(--ecc-font-size-small); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); + border-radius: var(--ecc-input-border-radius-small); } .lazy { display: flex; flex-direction: column; - gap: 0.5rem; + gap: var(--ecc-spacing-medium); } - .badge { - height: 1.5rem; + .skeleton-body { + width: 100%; + height: var(--ecc-font-size-medium); + } + sl-skeleton::part(base) { + border-radius: var(--ecc-input-border-radius-medium); + overflow: hidden; + } + .content { + font-size: var(--ecc-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); } .hidden { visibility: hidden; } - .error { - width: 100%; - position: absolute; - top: 1rem; - display: flex; - justify-content: center; + .collection { + position: relative; } `; diff --git a/packages/ecc-utils-design/src/components/collection/collection.ts b/packages/ecc-utils-design/src/components/collection/collection.ts index 7905d311..726eea82 100644 --- a/packages/ecc-utils-design/src/components/collection/collection.ts +++ b/packages/ecc-utils-design/src/components/collection/collection.ts @@ -13,6 +13,8 @@ import "@shoelace-style/shoelace/dist/components/alert/alert.js"; import { hostStyles } from "../../styles/host.styles.js"; import collectionStyles from "./collection.styles.js"; +import { primitiveStylesheet } from "../../styles/primitive.styles.js"; + export interface ItemProp { index: number; name: string; @@ -52,6 +54,7 @@ export interface FilterProp { */ export default class EccUtilsDesignCollection extends LitElement { static styles = [ + primitiveStylesheet, getShoelaceStyles( document.querySelector("html")?.classList.contains("dark") ), @@ -142,6 +145,7 @@ export default class EccUtilsDesignCollection extends LitElement { return html` - + ${item.lazy ? html`
${field.copy ? html`` : ""}
@@ -269,7 +211,8 @@ export default class EccUtilsDesignDetails extends LitElement { ${field.label} ${field.copy ? html`` : ""}
@@ -298,7 +241,7 @@ export default class EccUtilsDesignDetails extends LitElement { ${field.label} ${field.copy ? html`` : ""} @@ -373,7 +316,7 @@ export default class EccUtilsDesignDetails extends LitElement { ${fieldwithProps.copy ? html`` : ""} @@ -396,7 +339,7 @@ export default class EccUtilsDesignDetails extends LitElement { private _renderAction(action: Action) { if (action.type === "link") { return html` window.open(action.linkOptions?.url, "_blank")} @@ -405,6 +348,7 @@ export default class EccUtilsDesignDetails extends LitElement { `; } return html` this.dispatchEvent( new CustomEvent("ecc-utils-button-click", { diff --git a/packages/ecc-utils-design/src/components/form/form.styles.ts b/packages/ecc-utils-design/src/components/form/form.styles.ts index e1d7d32b..dba270c0 100644 --- a/packages/ecc-utils-design/src/components/form/form.styles.ts +++ b/packages/ecc-utils-design/src/components/form/form.styles.ts @@ -8,23 +8,76 @@ const styles = css` display: flex; flex-direction: column; } + .success-icon { + height: var(--ecc-input-font-size-medium); + } + .error-icon { + height: var(--ecc-input-font-size-medium); + } form sl-input { - margin-top: 0.5rem; - margin-bottom: 0.5rem; + margin-top: var(--ecc-spacing-medium); + margin-bottom: var(--ecc-spacing-medium); + } + /* Group Styles */ + sl-details::part(base) { + border: 0px; } - form sl-switch { - margin-top: 0.5rem; - margin-bottom: 0.5rem; + sl-details::part(header) { + padding-left: 0px; + padding-right: 0px; + padding-top: 0px; + border-bottom: var(--ecc-input-border-width) solid + var(--ecc-input-border-color); + } + sl-details::part(header):hover { + border-color: var(--ecc-input-border-width) solid + var(--ecc-input-border-color-hover); + } + sl-details::part(content) { + padding-left: 0px; + padding-right: 0px; + padding-bottom: 0px; + } + sl-details::part(summary) { + font-size: var(--ecc-input-label-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); } .group-container { - margin: 1rem 0; + margin-top: var(--ecc-spacing-medium); + margin-bottom: var(--ecc-spacing-medium); + } + .group-label { + width: 100%; + font-size: var(--ecc-input-label-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); + } + .group-header { + padding-bottom: var(--ecc-spacing-medium); + border-bottom: var(--ecc-input-border-width) solid + var(--ecc-input-border-color); + } + .group-header:hover { + border-bottom: var(--ecc-input-border-width) solid + var(--ecc-input-border-color-hover); + } + .group-content { + padding-top: var(--ecc-spacing-medium); + } + /* Array Styles */ + .array-label { + font-size: var(--ecc-input-label-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); } - .array-item, - .group-item { - margin: 1rem 0; + .array-item { border-style: solid; - border-width: 0px 0px 1px 0px; - border-color: var(--sl-color-gray-300); + border-width: 0px 0px var(--ecc-input-border-width) 0px; + border-color: var(--ecc-input-border-color-disabled); } .array-item { display: flex; @@ -35,51 +88,86 @@ const styles = css` display: flex; justify-content: space-between; align-items: center; - margin-bottom: 1rem; + margin-bottom: var(--ecc-spacing-medium); } .array-item-container { width: 100%; } .delete-icon { - height: 1.25rem; + height: var(--ecc-input-font-size-large); } .add-icon { - height: 1.1rem; + height: var(--ecc-input-font-size-medium); } + /* switch styles */ .switch-container { + margin-top: var(--ecc-spacing-medium); + margin-bottom: var(--ecc-spacing-medium); display: flex; - flex-direction: row; justify-content: space-between; + align-items: center; } - input[type="file"]::file-selector-button { - height: 100%; - background-color: #fff; - border: 0px; - border-right: 1px solid #d4d4d8; - padding-right: 20px; - padding-left: 20px; - margin-right: 10px; - font-size: 1rem; - } - input[type="file"] { - background-color: #fff; - border: 1px solid #d4d4d8; - border-radius: 4px; - margin-top: 0.5rem; - margin-bottom: 0.5rem; - height: 2.5rem; - font-size: 1rem; - color: #000; - } - .row { + .switch-label { + font-size: var(--ecc-input-label-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); + } + /* file input styles */ + .file-container { display: flex; flex-direction: column; } - .success-icon { - height: 1.25rem; + .file-input-label { + width: max-content; + font-size: var(--ecc-input-label-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); } - .error-icon { - height: 1.25rem; + .file-input::file-selector-button { + cursor: pointer; + height: 100%; + background-color: var(--ecc-color-neutral-0); + font-size: var(--ecc-input-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); + background-color: var(--ecc-input-background-color); + border: 0px; + border-right: solid var(--ecc-input-border-width) + var(--ecc-input-border-color); + padding: 0px var(--ecc-spacing-2x-large); + margin-right: var(--ecc-spacing-x-large); + } + .file-input { + background-color: var(--ecc-color-neutral-0); + border-radius: var(--ecc-input-border-radius-medium); + font-size: var(--ecc-input-font-size-medium); + font-family: var(--ecc-input-font-family); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); + border: solid var(--ecc-input-border-width) var(--ecc-input-border-color); + height: var(--ecc-input-height-medium); + margin-top: var(--ecc-spacing-medium); + margin-bottom: var(--ecc-spacing-medium); + } + .file-input:hover, + .file-input::file-selector-button:hover { + background-color: var(--ecc-input-background-color-hover); + border-color: var(--ecc-input-border-color-hover); + } + .file-input:focus, + .file-input::file-selector-button:focus { + background-color: var(--ecc-input-background-color-focus); + border-color: var(--ecc-input-border-color-focus); + box-shadow: 0 0 0 var(--ecc-focus-ring-width) + var(--ecc-input-focus-ring-color); + } + /* Submit Button */ + .submit-button { + margin-top: var(--ecc-spacing-large); + margin-bottom: var(--ecc-spacing-large); } `; diff --git a/packages/ecc-utils-design/src/components/form/form.ts b/packages/ecc-utils-design/src/components/form/form.ts index 2e49dcf2..d58e6008 100644 --- a/packages/ecc-utils-design/src/components/form/form.ts +++ b/packages/ecc-utils-design/src/components/form/form.ts @@ -11,6 +11,7 @@ import _ from "lodash-es"; import getShoelaceStyles from "../../styles/shoelace.styles.js"; import { hostStyles } from "../../styles/host.styles.js"; import formStyles from "./form.styles.js"; +import { primitiveStylesheet } from "../../styles/primitive.styles.js"; export interface Field { key: string; @@ -65,6 +66,7 @@ export interface Field { export default class EccUtilsDesignForm extends LitElement { static styles = [ + primitiveStylesheet, getShoelaceStyles( document.querySelector("html")?.classList.contains("dark") ), @@ -171,25 +173,31 @@ export default class EccUtilsDesignForm extends LitElement { this.cssParts; if (field.type === "file") { return html` -
+
${field.fieldOptions?.tooltip && field.fieldOptions.tooltip !== "" ? html` - ` : html` -
- ${renderChildren()} +
${renderChildren()}
`}
`; } @@ -562,6 +570,8 @@ export default class EccUtilsDesignForm extends LitElement { Date: Mon, 17 Jun 2024 03:23:57 +0530 Subject: [PATCH 02/14] chore: rm .idea --- .idea/.gitignore | 5 -- .idea/cloud-components.iml | 12 ---- .idea/codeStyles/Project.xml | 59 -------------------- .idea/codeStyles/codeStyleConfig.xml | 5 -- .idea/inspectionProfiles/Project_Default.xml | 6 -- .idea/modules.xml | 8 --- .idea/vcs.xml | 6 -- 7 files changed, 101 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/cloud-components.iml delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603f..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/cloud-components.iml b/.idea/cloud-components.iml deleted file mode 100644 index 24643cc3..00000000 --- a/.idea/cloud-components.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index c5b88c74..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549e..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 6338d9de..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From f95ec07204bd42d27e284cf3f80ed2e50e6b4839 Mon Sep 17 00:00:00 2001 From: Anurag Gupta Date: Mon, 24 Jun 2024 05:24:40 +0530 Subject: [PATCH 03/14] feat: code component --- .../packages/design/code/codeIndentation.tsx | 2 +- .../packages/design/code/codeJSON.tsx | 2 +- package-lock.json | 15 +- .../ecc-utils-design/demo/code/index.html | 40 +- packages/ecc-utils-design/package.json | 11 +- .../src/components/code/code.styles.ts | 41 +- .../src/components/code/code.ts | 349 +++--------------- 7 files changed, 125 insertions(+), 335 deletions(-) diff --git a/apps/documentation/components/packages/design/code/codeIndentation.tsx b/apps/documentation/components/packages/design/code/codeIndentation.tsx index ff3f7520..ed2f8ebe 100644 --- a/apps/documentation/components/packages/design/code/codeIndentation.tsx +++ b/apps/documentation/components/packages/design/code/codeIndentation.tsx @@ -13,7 +13,7 @@ const EccUtilsDesignCode = dynamic(() => import('@elixir-cloud/design/dist/react export default function Code() { return (
- +
); } diff --git a/apps/documentation/components/packages/design/code/codeJSON.tsx b/apps/documentation/components/packages/design/code/codeJSON.tsx index 6a63d3e5..33d7928c 100644 --- a/apps/documentation/components/packages/design/code/codeJSON.tsx +++ b/apps/documentation/components/packages/design/code/codeJSON.tsx @@ -13,7 +13,7 @@ const EccUtilsDesignCode = dynamic(() => import('@elixir-cloud/design/dist/react export default function Code() { return (
- +
); } diff --git a/package-lock.json b/package-lock.json index bcfee571..69451605 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4297,6 +4297,12 @@ "@types/node": "*" } }, + "node_modules/@types/ace": { + "version": "0.0.52", + "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.52.tgz", + "integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==", + "dev": true + }, "node_modules/@types/acorn": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", @@ -6686,6 +6692,11 @@ "node": ">=12" } }, + "node_modules/ace-builds": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.35.0.tgz", + "integrity": "sha512-bwDKqjqNccC/MSujqnYTeAS5dIR8UmGLP0R90mvsJY0FRC8NUWBSTfj34+EIzo2NWc/gV8IZTqv4fXaiZJpCtA==" + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -26033,7 +26044,7 @@ "license": "Apache-2.0", "dependencies": { "@shoelace-style/shoelace": "^2.8.0", - "js-yaml": "^4.1.0", + "ace-builds": "^1.35.0", "lit": "^2.8.0", "lodash-es": "^4.17.21" }, @@ -26043,7 +26054,7 @@ "@lit/react": "*", "@open-wc/eslint-config": "*", "@open-wc/testing": "*", - "@types/js-yaml": "^4.0.9", + "@types/ace": "^0.0.52", "@types/lodash-es": "^4.17.10", "@web/dev-server": "*", "@web/dev-server-esbuild": "^0.4.3", diff --git a/packages/ecc-utils-design/demo/code/index.html b/packages/ecc-utils-design/demo/code/index.html index d7d7ca07..425e90c9 100644 --- a/packages/ecc-utils-design/demo/code/index.html +++ b/packages/ecc-utils-design/demo/code/index.html @@ -1,24 +1,24 @@ - - - - - ecc-utils-design - - - -
-
-
- + + +
+
+
+ - + render( + html` `, + document.querySelector("#demo") + ); + + diff --git a/packages/ecc-utils-design/package.json b/packages/ecc-utils-design/package.json index 331ca5ce..e2588237 100644 --- a/packages/ecc-utils-design/package.json +++ b/packages/ecc-utils-design/package.json @@ -7,7 +7,10 @@ "module": "./dist/index.mjs", "types": "./dist/index.d.ts", "exports": { - ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" }, + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, "./dist/custom-elements.json": "./dist/custom-elements.json", "./dist/index.js": "./dist/index.js", "./dist/components/*": "./dist/components/*", @@ -40,10 +43,11 @@ }, "devDependencies": { "@custom-elements-manifest/analyzer": "^0.8.4", + "@elixir-cloud/eslint-config": "*", "@lit/react": "*", "@open-wc/eslint-config": "*", "@open-wc/testing": "*", - "@types/js-yaml": "^4.0.9", + "@types/ace": "^0.0.52", "@types/lodash-es": "^4.17.10", "@web/dev-server": "*", "@web/dev-server-esbuild": "^0.4.3", @@ -54,7 +58,6 @@ "custom-element-vs-code-integration": "*", "esbuild": "0.18.20", "eslint": "*", - "@elixir-cloud/eslint-config": "*", "eslint-plugin-prettier": "^4.2.1", "globby": "^14.0.0", "react": "*", @@ -64,7 +67,7 @@ }, "dependencies": { "@shoelace-style/shoelace": "^2.8.0", - "js-yaml": "^4.1.0", + "ace-builds": "^1.35.0", "lit": "^2.8.0", "lodash-es": "^4.17.21" } diff --git a/packages/ecc-utils-design/src/components/code/code.styles.ts b/packages/ecc-utils-design/src/components/code/code.styles.ts index 23606b6f..6d46ee49 100644 --- a/packages/ecc-utils-design/src/components/code/code.styles.ts +++ b/packages/ecc-utils-design/src/components/code/code.styles.ts @@ -1,15 +1,46 @@ import { css } from "lit"; const codeStyles = css` - sl-textarea::part(form-control-label) { - display: flex; - gap: var(--sl-spacing-x-small); - } #label { + color: var(--ecc-input-label-color); + font-size: var(--ecc-input-label-font-size-medium); + font-family: var(--ecc-font-sans); + font-weight: var(--ecc-input-font-weight); + letter-spacing: var(--ecc-input-letter-spacing); + } + #editor { + width: 100%; + height: 12.5ex; + resize: vertical; + overflow: auto; + font-family: var(--ecc-font-mono); + background-color: var(--ecc-input-background-color); + border: solid var(--ecc-input-border-width) var(--ecc-input-border-color); + border-radius: var(--ecc-input-border-radius-medium); + font-size: var(--ecc-input-font-size-medium); + margin-top: var(--ecc-spacing-medium); + margin-bottom: var(--ecc-spacing-medium); + } + #editor:hover { + background-color: var(--ecc-input-background-color-hover); + border-color: var(--ecc-input-border-color-hover); + } + #editor:focus { + background-color: var(--ecc-input-background-color-focus); + border-color: var(--ecc-input-border-color-focus); + box-shadow: 0 0 0 var(--ecc-focus-ring-width) + var(--ecc-input-focus-ring-color); + } + .disabled { + background-color: var(--ecc-input-background-color-disabled); + border-color: var(--ecc-input-border-color-disabled); + opacity: 0.5; + cursor: not-allowed !important; + } + .header { display: flex; justify-content: space-between; align-items: center; - gap: var(--sl-spacing-x-small); } `; diff --git a/packages/ecc-utils-design/src/components/code/code.ts b/packages/ecc-utils-design/src/components/code/code.ts index 7a689289..034d9885 100644 --- a/packages/ecc-utils-design/src/components/code/code.ts +++ b/packages/ecc-utils-design/src/components/code/code.ts @@ -1,18 +1,19 @@ import { LitElement, html } from "lit"; import { property, state } from "lit/decorators.js"; -import "@shoelace-style/shoelace/dist/components/input/input.js"; -import "@shoelace-style/shoelace/dist/components/badge/badge.js"; -import "@shoelace-style/shoelace/dist/components/textarea/textarea.js"; -import "@shoelace-style/shoelace/dist/components/copy-button/copy-button.js"; -import jsyaml from "js-yaml"; +import "ace-builds/src-noconflict/ace.js"; +import "ace-builds/src-noconflict/theme-github.js"; +import "@shoelace-style/shoelace/dist/components/tag/tag.js"; +import _ from "lodash-es"; +import codeStyles from "./code.styles.js"; +import { primitiveStylesheet } from "../../styles/primitive.styles.js"; import { hostStyles } from "../../styles/host.styles.js"; import getShoelaceStyles from "../../styles/shoelace.styles.js"; -import codeStyles from "./code.styles.js"; -export type Language = "YAML" | "JSON" | "Text"; +export type Language = "yaml" | "json" | "xml" | "makefile"; export default class EccUtilsDesignCode extends LitElement { static styles = [ + primitiveStylesheet, getShoelaceStyles( document.querySelector("html")?.classList.contains("dark") ), @@ -21,321 +22,65 @@ export default class EccUtilsDesignCode extends LitElement { ]; @property({ type: String }) code = ""; - @property({ type: String }) label = "Code"; - @property({ type: String }) language: Language = "YAML"; - @property({ type: Number }) indentation = 2; - @property({ type: Number }) blurDelay = 150; - @property({ type: Boolean }) required = true; + @property({ type: String }) label = "Code block"; + @property({ type: String }) language: Language = "json"; @property({ type: Boolean }) disabled = false; - @state() elTextarea: HTMLTextAreaElement | null = null; - @state() error = false; - @state() indent = ""; - @state() currentIndentation = ""; - @state() opening = ["(", "{", "[", "'", '"']; - @state() closing = [")", "}", "]", "'", '"']; - @state() lastTabPressTime = 0; - @state() errorLanguage: Language = "Text"; - - private cssParts = {}; - - private _getTextAreaEle(): HTMLTextAreaElement { - const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); - const ele = slTextarea?.shadowRoot?.querySelector("textarea"); - if (!ele || !(ele instanceof HTMLTextAreaElement)) { - throw new Error("Could not find textarea element"); - } - return ele; - } + @state() editor: any; firstUpdated() { - const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); - const ele = slTextarea?.shadowRoot?.querySelector("textarea"); - if (ele instanceof HTMLTextAreaElement) { - ele.value = this.code; - } - this.indent = " ".repeat(this.indentation); - this._updateTextarea(); - } - - public getCode() { - return this.code; - } - - private _setCursor(pos: number) { - this.elTextarea = this._getTextAreaEle(); - this.elTextarea.setSelectionRange(pos, pos); - } - - private _setSelect(from: number, to: number) { - this.elTextarea = this._getTextAreaEle(); - this.elTextarea.setSelectionRange(from, to); - } - - private _getCurrentLineIndent() { - const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); - const ele = slTextarea?.shadowRoot?.querySelector("textarea"); - if (!ele || !(ele instanceof HTMLTextAreaElement)) { - throw new Error("Could not find textarea element"); - } - this.elTextarea = ele; - - const selStart = this.elTextarea.selectionStart; - const selEnd = this.elTextarea.selectionEnd; - - const indentStart = this.code.lastIndexOf("\n", selStart - 1) + 1; - const spaces = (() => { - let pos = indentStart; - while (this.code[pos] === " " && pos < selEnd) pos += 1; - return pos - indentStart; - })(); - return " ".repeat(spaces); - } - - private _updateTextarea() { - if (!this.elTextarea) return; - this.elTextarea.value = this.code; - - this.dispatchEvent( - new CustomEvent("ecc-utils-change", { detail: this.code }) - ); - } - - private _insertCode(pos: number, text: string, placeCursor = true) { - this.code = this.code.substring(0, pos) + text + this.code.substring(pos); - this._updateTextarea(); - if (placeCursor) this._setCursor(pos + text.length); - } - - private _replaceCode( - posFrom: number, - posTo: number, - text = "", - placeCursor = true - ) { - this.code = - this.code.substring(0, posFrom) + text + this.code.substring(posTo); - this._updateTextarea(); - if (placeCursor) this._setCursor(posFrom + text.length); - } - - private _handleInput(e: InputEvent) { - this.code = (e.target as HTMLInputElement).value; - this._validateCode(); - this.dispatchEvent( - new CustomEvent("ecc-utils-change", { detail: this.code }) - ); - } - - private _handleTabs(e: KeyboardEvent) { - e.preventDefault(); - const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); - const ele = slTextarea?.shadowRoot?.querySelector("textarea"); - if (!ele || !(ele instanceof HTMLTextAreaElement)) { - throw new Error("Could not find textarea element"); - } - this.elTextarea = ele; - const selStart = this.elTextarea.selectionStart; - const selEnd = this.elTextarea.selectionEnd; - - if (selStart !== selEnd) { - // multiline indent - const selLineStart = Math.max( - 0, - this.code.lastIndexOf("\n", selStart - 1) - ); - const selLineEnd = Math.max(this.code.indexOf("\n", selEnd), selEnd); - - let linesInChunk = 0; - let codeChunk = this.code.substring(selLineStart, selLineEnd); - let lenShift = this.indent.length; - if (selLineStart === 0) codeChunk = `\n${codeChunk}`; - - if (e.shiftKey) { - // Unindent - lenShift = -lenShift; - linesInChunk = ( - codeChunk.match(new RegExp(`\n${this.indent}`, "g")) || [] - ).length; - codeChunk = codeChunk.split(`\n${this.indent}`).join("\n"); - } else { - // Indent - linesInChunk = (codeChunk.match(/\n/g) || []).length; - codeChunk = codeChunk.split("\n").join(`\n${this.indent}`); - } - - if (selLineStart === 0) codeChunk = codeChunk.replace(/^\n/, ""); - this._replaceCode(selLineStart, selLineEnd, codeChunk, false); - - const newStart = Math.max(selLineStart + 1, selStart + lenShift); - const newEnd = selEnd + linesInChunk * lenShift; - this._setSelect(newStart, newEnd); - } else { - this._insertCode(selStart, this.indent, true); - } - } - - private _handleBackspace(e: KeyboardEvent) { - this.elTextarea = this._getTextAreaEle(); - const selStart = this.elTextarea.selectionStart; - const selEnd = this.elTextarea.selectionEnd; - if (e.ctrlKey || selStart !== selEnd) return; - - e.preventDefault(); - - const prevSymbol = this.code[selStart - 1]; - const curSymbol = this.code[selStart]; - const isInPairs = - this.opening.includes(prevSymbol) && this.closing.includes(curSymbol); - const isPair = this.closing[this.opening.indexOf(prevSymbol)] === curSymbol; - - if (isInPairs && isPair) { - this._replaceCode(selStart - 1, selStart + 1); - } else { - const chunkStart = selStart - this.indent.length; - const chunkEnd = selStart; - const chunk = this.code.substring(chunkStart, chunkEnd); - - if (chunk === this.indent) this._replaceCode(chunkStart, chunkEnd); - else this._replaceCode(selStart - 1, selStart); - } + this.initializeAceEditor(); } - private _handleAutoClose(e: KeyboardEvent) { - this.elTextarea = this._getTextAreaEle(); - const selStart = this.elTextarea.selectionStart; - const selEnd = this.elTextarea.selectionEnd; - if (this.code[selStart] === "'" || this.code[selStart] === '"') { - this._handleAutoSkip(e); - return; - } - e.preventDefault(); + async initializeAceEditor() { + const editorElement = this.shadowRoot?.getElementById("editor"); + if (editorElement) { + this.editor = ace.edit(editorElement); + this.editor.setTheme("ace/theme/twilight"); + this.editor.renderer.attachToShadowRoot(); + this.editor.setValue(this.code); - if (selStart === selEnd) { - const opening = e.key; - const closing = this.closing[this.opening.indexOf(opening)]; + await this.setEditorLanguage(this.language); + if (this.disabled) this.editor.setReadOnly(true); - if ( - opening === "{" && - (this.code[selStart] === "\n" || this.code.length === selStart) - ) { - const lineShift = `\n${this._getCurrentLineIndent()}`; - this._insertCode( - selStart, - opening + lineShift + this.indent + lineShift + closing - ); - this._setCursor(selStart + lineShift.length + this.indent.length + 1); - } else { - this._insertCode(selStart, opening + closing); - this._setCursor(selStart + 1); - } + this.editor.on("change", () => { + this.code = this.editor.getValue(); + }); } } - private _handleAutoSkip(e: KeyboardEvent): void { - this.elTextarea = this._getTextAreaEle(); - const selStart = this.elTextarea.selectionStart; - - if (this.code[selStart] === e.key) { - e.preventDefault(); - this._setCursor(selStart + 1); + async setEditorLanguage(language: Language) { + if (!this.editor) return; + try { + await import(`ace-builds/src-noconflict/mode-${language}.js`); + this.editor.session.setMode(`ace/mode/${language}`); + } catch (error) { + console.error(`Failed to load Ace mode for ${language}`, error); + this.editor.session.setMode("ace/mode/text"); } } - private _handleNewLine(e: KeyboardEvent) { - e.preventDefault(); - this.elTextarea = this._getTextAreaEle(); - this._insertCode( - this.elTextarea.selectionStart, - `\n${this._getCurrentLineIndent()}` - ); - } - - private _handleKeys(e: KeyboardEvent) { - const currentTime = new Date().getTime(); - const timeSinceLastTabPress = currentTime - this.lastTabPressTime; - - switch (e.code) { - case "Tab": - if (timeSinceLastTabPress > this.blurDelay) { - this._handleTabs(e); - } else { - this.shadowRoot?.querySelector("sl-textarea")?.blur(); - e.preventDefault(); - } - - this.lastTabPressTime = currentTime; - break; - case "Enter": - this._handleNewLine(e); - break; - case "Backspace": - this._handleBackspace(e); - break; - default: - if (this.opening.includes(e.key)) this._handleAutoClose(e); - else if (this.closing.includes(e.key)) this._handleAutoSkip(e); + updated(changedProperties: Map) { + if (changedProperties.has("language")) { + this.setEditorLanguage(this.language); } - this._validateCode(); - this.dispatchEvent( - new CustomEvent("ecc-utils-change", { detail: this.code }) - ); - } - - private _validateCode(): void { - if (this.code === "") { - this.error = false; - return; + if (changedProperties.has("disabled") && this.editor) { + this.editor.setReadOnly(this.disabled); } - - if (this.language === "JSON") { - try { - JSON.parse(this.code); - this.error = false; - } catch (error) { - try { - jsyaml.loadAll(this.code); - this.errorLanguage = "YAML"; - } catch (err) { - this.errorLanguage = "Text"; - } - this.error = true; - } - } else if (this.language === "YAML") { - try { - jsyaml.loadAll(this.code); - this.error = false; - } catch (error) { - this.error = true; - this.errorLanguage = "Text"; - } - } else this.error = false; } render() { return html` - -
- ${this.label} - ${this.language} - ${this.error - ? html`${this.errorLanguage}` - : html``} - -
-
+
+
${this.label}
+ ${_.upperCase(this.language)}
+ +
+
+
`; } } From f380ec3e947ff3bbf21308c8c5a118539fbabc0a Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Sat, 29 Jun 2024 21:33:05 +0100 Subject: [PATCH 04/14] improve modularization for form component --- .../src/components/form/form.ts | 427 +++++------------- .../form/templates/arrayTemplate.ts | 84 ++++ .../form/templates/errorTemplate.ts | 21 + .../form/templates/groupTemplate.ts | 32 ++ .../form/templates/inputTemplate.ts | 61 +++ .../form/templates/successTemplate.ts | 24 + .../form/templates/switchTemplate.ts | 34 ++ .../src/components/form/types.ts | 37 ++ .../src/components/form/utils.ts | 31 ++ 9 files changed, 439 insertions(+), 312 deletions(-) create mode 100644 packages/ecc-utils-design/src/components/form/templates/arrayTemplate.ts create mode 100644 packages/ecc-utils-design/src/components/form/templates/errorTemplate.ts create mode 100644 packages/ecc-utils-design/src/components/form/templates/groupTemplate.ts create mode 100644 packages/ecc-utils-design/src/components/form/templates/inputTemplate.ts create mode 100644 packages/ecc-utils-design/src/components/form/templates/successTemplate.ts create mode 100644 packages/ecc-utils-design/src/components/form/templates/switchTemplate.ts create mode 100644 packages/ecc-utils-design/src/components/form/types.ts create mode 100644 packages/ecc-utils-design/src/components/form/utils.ts diff --git a/packages/ecc-utils-design/src/components/form/form.ts b/packages/ecc-utils-design/src/components/form/form.ts index d58e6008..429e6d1c 100644 --- a/packages/ecc-utils-design/src/components/form/form.ts +++ b/packages/ecc-utils-design/src/components/form/form.ts @@ -1,55 +1,18 @@ import { html, LitElement, TemplateResult } from "lit"; import { property, state } from "lit/decorators.js"; -import "@shoelace-style/shoelace/dist/components/input/input.js"; import "@shoelace-style/shoelace/dist/components/button/button.js"; -import "@shoelace-style/shoelace/dist/components/switch/switch.js"; -import "@shoelace-style/shoelace/dist/components/icon-button/icon-button.js"; -import "@shoelace-style/shoelace/dist/components/alert/alert.js"; -import "@shoelace-style/shoelace/dist/components/details/details.js"; -import "@shoelace-style/shoelace/dist/components/tooltip/tooltip.js"; import _ from "lodash-es"; import getShoelaceStyles from "../../styles/shoelace.styles.js"; import { hostStyles } from "../../styles/host.styles.js"; import formStyles from "./form.styles.js"; +import { Field } from "./types.js"; import { primitiveStylesheet } from "../../styles/primitive.styles.js"; - -export interface Field { - key: string; - label: string; - type?: - | "text" - | "date" - | "number" - | "email" - | "password" - | "tel" - | "url" - | "search" - | "datetime-local" - | "time" - | "array" - | "switch" - | "file" - | "group"; - fieldOptions?: { - required?: boolean; - default?: string | boolean; - multiple?: boolean; - accept?: string; - returnIfEmpty?: string; - tooltip?: string; - }; - arrayOptions?: { - defaultInstances?: number; - max?: number; - min?: number; - }; - groupOptions?: { - collapsible: boolean; - }; - error?: string; - children?: Array; -} +import inputTemplate from "./templates/inputTemplate.js"; +import arrayTemplate from "./templates/arrayTemplate.js"; +import groupTemplate from "./templates/groupTemplate.js"; +import errorTemplate from "./templates/errorTemplate.js"; +import successTemplate from "./templates/successTemplate.js"; +import switchTemplate from "./templates/switchTemplate.js"; /** * @summary This component is used to render a form with the given fields. @@ -63,7 +26,6 @@ export interface Field { * * @event ecc-utils-submit - This event is fired when the form is submitted. The event detail contains the form data. */ - export default class EccUtilsDesignForm extends LitElement { static styles = [ primitiveStylesheet, @@ -129,39 +91,22 @@ export default class EccUtilsDesignForm extends LitElement { const { switchControl, switchThumb, label, switchLabel, formControl } = this.cssParts; - return html` -
- ${field.fieldOptions?.tooltip && field.fieldOptions.tooltip !== "" - ? html` - - - - ` - : html` - - `} - { - _.set(this.form, path, (e.target as HTMLInputElement).checked); - this.requestUpdate(); - }} - > - -
- `; + + const parts = [ + formControl, + `${label} ${switchLabel}`, + `control: ${switchControl}, thumb: ${switchThumb}`, + ]; + + const changeAction = (e: Event) => { + _.set(this.form, path, (e.target as HTMLInputElement).checked); + this.requestUpdate(); + }; + + return switchTemplate(field, parts, _.get(this.form, path), changeAction); } - renderInputTemplate(field: Field, path: string): TemplateResult { + private renderInputTemplate(field: Field, path: string): TemplateResult { if ( field.type === "array" || field.type === "switch" || @@ -171,94 +116,54 @@ export default class EccUtilsDesignForm extends LitElement { const { formControl, formControlLabel, input, inputBase, label } = this.cssParts; - if (field.type === "file") { - return html` -
- ${field.fieldOptions?.tooltip && field.fieldOptions.tooltip !== "" - ? html` - - - - ` - : html` - - `} - { - const { files } = e.target as HTMLInputElement; - _.set(this.form, path, files); - this.requestUpdate(); - }} - /> -
- `; - } - if (!_.get(this.form, path)) { - if (field.fieldOptions?.default && !this.hasUpdated) { - _.set(this.form, path, field.fieldOptions.default); - } else if (field.fieldOptions?.returnIfEmpty) { - _.set(this.form, path, ""); - } - } - - return html` - { - const { value } = e.target as HTMLInputElement; - if (!value) { - _.unset(this.form, path); - } else { - _.set(this.form, path, value); + const changeAction = + field.type === "file" + ? (e: Event) => { + const { files } = e.target as HTMLInputElement; + _.set(this.form, path, files); + this.requestUpdate(); } + : (e: Event) => { + const { value } = e.target as HTMLInputElement; + if (!value) { + _.unset(this.form, path); + } else { + _.set(this.form, path, value); + } - this.requestUpdate(); - }} - > - - ` - : html` `} - - - `; + this.requestUpdate(); + }; + + const emptyFieldAction = () => { + if (!_.get(this.form, path)) { + if (field.fieldOptions?.default && !this.hasUpdated) { + _.set(this.form, path, field.fieldOptions.default); + } else if (field.fieldOptions?.returnIfEmpty) { + _.set(this.form, path, ""); + } + } + }; + + return inputTemplate( + field, + [ + formControl, + `${label} ${formControlLabel}`, + `${inputBase} ${input}`, + `form-control: ${formControl}, form-control-label: ${formControlLabel}, form-control-label: ${label}, input: ${input}, base: ${inputBase}`, + ], + changeAction, + emptyFieldAction, + _.get(this.form, path) + ); } private renderArrayTemplate(field: Field, path: string): TemplateResult { const { arrayOptions } = field; if (!_.get(this.form, path)) { - const defaultCount = field.arrayOptions?.defaultInstances; + const defaultCount = arrayOptions?.defaultInstances; if (defaultCount) { _.set( this.form, @@ -293,95 +198,49 @@ export default class EccUtilsDesignForm extends LitElement { arrayItem, item, } = this.cssParts; - return html` -
-
- ${field.fieldOptions?.tooltip && field.fieldOptions.tooltip !== "" - ? html` - - - - ` - : html` - - `} - { - if (resolveAddButtonIsActive()) { - const instances: [] = _.get(this.form, path) || []; - _.set(this.form, path, [...instances, {}]); - this.requestUpdate(); - } - }} - > - - - - Add - -
- ${_.get(this.form, path)?.map( - (_item: any, index: number) => html` -
- { - resolveDeleteButtonIsActive() && - _.get(this.form, path).splice(index, 1) && - this.requestUpdate(); - }} - > - - - - -
- ${field.children?.map((child) => - this.renderTemplate(child, `${path}[${index}]`) - )} -
-
- ` - )} -
- `; + + const parts = [ + `${container} ${arrayContainer}`, + `header: ${arrayHeader}, header: ${header}`, + `${label} ${arrayLabel}`, + `base: ${button}, base: ${addButton}`, + `${item} ${arrayItem}`, + `base: ${button}, base: ${removeButton}`, + ]; + + const addAction = () => { + if (resolveAddButtonIsActive()) { + const instances: [] = _.get(this.form, path) || []; + _.set(this.form, path, [...instances, {}]); + this.requestUpdate(); + } + }; + + const deleteAction = (index: number) => { + resolveDeleteButtonIsActive() && + _.get(this.form, path).splice(index, 1) && + this.requestUpdate(); + }; + + const renderChildren = (index: number) => { + if (field.children?.length) + return html` ${field.children?.map((child) => + this.renderTemplate(child, `${path}[${index}]`) + )}`; + + return html``; + }; + + return arrayTemplate( + field, + parts, + resolveAddButtonIsActive(), + resolveDeleteButtonIsActive(), + addAction, + deleteAction, + renderChildren, + _.get(this.form, path) + ); } private renderGroupTemplate(field: Field, path: string): TemplateResult { @@ -398,6 +257,12 @@ export default class EccUtilsDesignForm extends LitElement { groupLabel, groupToggleIcon, } = this.cssParts; + + const parts = [ + `base: ${groupBase}, header: ${groupHeader}, header: ${header}, summary: ${label}, summary: ${groupLabel}, summary-icon: ${groupToggleIcon}, content: ${groupContent}`, + `${header} ${groupHeader}`, + `${label} ${groupLabel}`, + ]; const renderChildren = () => html`
@@ -407,35 +272,7 @@ export default class EccUtilsDesignForm extends LitElement {
`; - return html`
- ${field.groupOptions?.collapsible - ? html` - ${renderChildren()} - ` - : html` -
- ${field.fieldOptions?.tooltip && field.fieldOptions.tooltip !== "" - ? html` - - - - ` - : html` - - `} -
-
${renderChildren()}
- `} -
`; + return groupTemplate(field, parts, renderChildren); } private renderTemplate(field: Field, path: string): TemplateResult { @@ -458,49 +295,13 @@ export default class EccUtilsDesignForm extends LitElement { private renderErrorTemplate(): TemplateResult { if (this.formState !== "error") return html``; - return html` - - - - ${this.errorMessage} - `; + return errorTemplate(this.errorMessage); } private renderSuccessTemplate(): TemplateResult { if (this.formState !== "success") return html``; - return html` - - - - - - ${this.successMessage} - - `; + + return successTemplate(this.successMessage); } public disableSubmit(disable = true) { @@ -584,3 +385,5 @@ export default class EccUtilsDesignForm extends LitElement { `; } } + +export { Field }; diff --git a/packages/ecc-utils-design/src/components/form/templates/arrayTemplate.ts b/packages/ecc-utils-design/src/components/form/templates/arrayTemplate.ts new file mode 100644 index 00000000..5ca39455 --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/templates/arrayTemplate.ts @@ -0,0 +1,84 @@ +import { TemplateResult, html } from "lit"; +import { Field } from "../types.js"; +import { renderLabel } from "../utils.js"; +import "@shoelace-style/shoelace/dist/components/button/button.js"; + +export default ( + field: Field, + parts: Array, + addButtonIsActive: boolean, + deleteButtonIsActive: boolean, + addAction: () => void, + deleteAction: (index: number) => void, + renderChildren: (index: number) => TemplateResult, + children = [] +) => { + const arrayItem = (index: number) => html` +
+ deleteAction(index)} + > + + + + +
${renderChildren(index)}
+
+ `; + + return html` +
+
+ ${renderLabel( + { + part: parts[2], + class: "array-label", + content: field.label, + required: field.fieldOptions?.required, + }, + { content: field.fieldOptions?.tooltip } + )} + + + + + Add + +
+ ${children.map((_item: any, index: number) => arrayItem(index))} +
+ `; +}; diff --git a/packages/ecc-utils-design/src/components/form/templates/errorTemplate.ts b/packages/ecc-utils-design/src/components/form/templates/errorTemplate.ts new file mode 100644 index 00000000..16e93487 --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/templates/errorTemplate.ts @@ -0,0 +1,21 @@ +import { html } from "lit"; +import "@shoelace-style/shoelace/dist/components/alert/alert.js"; + +export default (errorMessage: string) => html` + + + + ${errorMessage} + `; diff --git a/packages/ecc-utils-design/src/components/form/templates/groupTemplate.ts b/packages/ecc-utils-design/src/components/form/templates/groupTemplate.ts new file mode 100644 index 00000000..6431385c --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/templates/groupTemplate.ts @@ -0,0 +1,32 @@ +import { TemplateResult, html } from "lit"; +import { Field } from "../types.js"; +import { renderLabel } from "../utils.js"; +import "@shoelace-style/shoelace/dist/components/details/details.js"; + +export default ( + field: Field, + parts: Array, + renderChildren: () => TemplateResult +) => html`
+ ${field.groupOptions?.collapsible + ? html` + ${renderChildren()} + ` + : html` +
+ ${renderLabel( + { + part: parts[2], + class: "group-label", + content: field.label, + required: field.fieldOptions?.required, + }, + { content: field.fieldOptions?.tooltip } + )} +
+
${renderChildren()}
+ `} +
`; diff --git a/packages/ecc-utils-design/src/components/form/templates/inputTemplate.ts b/packages/ecc-utils-design/src/components/form/templates/inputTemplate.ts new file mode 100644 index 00000000..082f0862 --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/templates/inputTemplate.ts @@ -0,0 +1,61 @@ +import { html } from "lit"; +import { renderLabel } from "../utils.js"; +import { Field } from "../types.js"; +import "@shoelace-style/shoelace/dist/components/input/input.js"; +import "@shoelace-style/shoelace/dist/components/button/button.js"; + +export default function ( + field: Field, + parts: Array, + changeAction: (e: Event) => void, + emptyFieldAction: () => void, + value = "" +) { + if (field.type === "file") { + return html` +
+ ${renderLabel( + { + part: parts[1], + class: "file-input-label", + content: field.label, + required: field.fieldOptions?.required, + }, + { content: field.fieldOptions?.tooltip } + )} + +
+ `; + } + + emptyFieldAction(); + + return html` + + + + `; +} diff --git a/packages/ecc-utils-design/src/components/form/templates/successTemplate.ts b/packages/ecc-utils-design/src/components/form/templates/successTemplate.ts new file mode 100644 index 00000000..a57b90b4 --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/templates/successTemplate.ts @@ -0,0 +1,24 @@ +import { html } from "lit"; +import "@shoelace-style/shoelace/dist/components/alert/alert.js"; + +export default (successMessage: string) => html` + + + + + + ${successMessage} + +`; diff --git a/packages/ecc-utils-design/src/components/form/templates/switchTemplate.ts b/packages/ecc-utils-design/src/components/form/templates/switchTemplate.ts new file mode 100644 index 00000000..243deb52 --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/templates/switchTemplate.ts @@ -0,0 +1,34 @@ +import { html } from "lit"; +import { Field } from "../types.js"; +import { renderLabel } from "../utils.js"; +import "@shoelace-style/shoelace/dist/components/switch/switch.js"; + +export default ( + field: Field, + parts: Array, + checked: boolean, + changeAction: (e: Event) => void +) => html` +
+ ${renderLabel( + { + part: parts[1], + class: "switch-label", + content: field.label, + required: field.fieldOptions?.required, + }, + { content: field.fieldOptions?.tooltip } + )} + + + +
+`; diff --git a/packages/ecc-utils-design/src/components/form/types.ts b/packages/ecc-utils-design/src/components/form/types.ts new file mode 100644 index 00000000..f883e2b7 --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/types.ts @@ -0,0 +1,37 @@ +export interface Field { + key: string; + label: string; + type?: + | "text" + | "date" + | "number" + | "email" + | "password" + | "tel" + | "url" + | "search" + | "datetime-local" + | "time" + | "array" + | "switch" + | "file" + | "group"; + fieldOptions?: { + required?: boolean; + default?: string | boolean; + multiple?: boolean; + accept?: string; + returnIfEmpty?: string; + tooltip?: string; + }; + arrayOptions?: { + defaultInstances?: number; + max?: number; + min?: number; + }; + groupOptions?: { + collapsible: boolean; + }; + error?: string; + children?: Array; +} diff --git a/packages/ecc-utils-design/src/components/form/utils.ts b/packages/ecc-utils-design/src/components/form/utils.ts new file mode 100644 index 00000000..87444ec5 --- /dev/null +++ b/packages/ecc-utils-design/src/components/form/utils.ts @@ -0,0 +1,31 @@ +import { html } from "lit"; +import "@shoelace-style/shoelace/dist/components/tooltip/tooltip.js"; + +export interface Label { + part?: string; + class?: string; + content: string; + required?: boolean; +} + +export interface Tooltip { + content: string | undefined; +} + +export const renderLabel = (label: Label, tooltip: Tooltip) => { + const labelComponent = () => html` + + `; + + if (tooltip.content) { + return html` + + ${labelComponent()} + + `; + } + + return labelComponent(); +}; From b7ce7988e2e7183e1848e9e2f059d65934d8687b Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 20:45:09 +0100 Subject: [PATCH 05/14] Revert "feat: code component" This reverts commit f95ec07204bd42d27e284cf3f80ed2e50e6b4839. --- .../packages/design/code/codeIndentation.tsx | 2 +- .../packages/design/code/codeJSON.tsx | 2 +- package-lock.json | 15 +- .../ecc-utils-design/demo/code/index.html | 40 +- packages/ecc-utils-design/package.json | 11 +- .../src/components/code/code.styles.ts | 41 +- .../src/components/code/code.ts | 349 +++++++++++++++--- 7 files changed, 335 insertions(+), 125 deletions(-) diff --git a/apps/documentation/components/packages/design/code/codeIndentation.tsx b/apps/documentation/components/packages/design/code/codeIndentation.tsx index ed2f8ebe..ff3f7520 100644 --- a/apps/documentation/components/packages/design/code/codeIndentation.tsx +++ b/apps/documentation/components/packages/design/code/codeIndentation.tsx @@ -13,7 +13,7 @@ const EccUtilsDesignCode = dynamic(() => import('@elixir-cloud/design/dist/react export default function Code() { return (
- +
); } diff --git a/apps/documentation/components/packages/design/code/codeJSON.tsx b/apps/documentation/components/packages/design/code/codeJSON.tsx index 33d7928c..6a63d3e5 100644 --- a/apps/documentation/components/packages/design/code/codeJSON.tsx +++ b/apps/documentation/components/packages/design/code/codeJSON.tsx @@ -13,7 +13,7 @@ const EccUtilsDesignCode = dynamic(() => import('@elixir-cloud/design/dist/react export default function Code() { return (
- +
); } diff --git a/package-lock.json b/package-lock.json index aeff60e1..b2e79572 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4297,12 +4297,6 @@ "@types/node": "*" } }, - "node_modules/@types/ace": { - "version": "0.0.52", - "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.52.tgz", - "integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==", - "dev": true - }, "node_modules/@types/acorn": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", @@ -6692,11 +6686,6 @@ "node": ">=12" } }, - "node_modules/ace-builds": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.35.0.tgz", - "integrity": "sha512-bwDKqjqNccC/MSujqnYTeAS5dIR8UmGLP0R90mvsJY0FRC8NUWBSTfj34+EIzo2NWc/gV8IZTqv4fXaiZJpCtA==" - }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -26044,7 +26033,7 @@ "license": "Apache-2.0", "dependencies": { "@shoelace-style/shoelace": "^2.8.0", - "ace-builds": "^1.35.0", + "js-yaml": "^4.1.0", "lit": "^2.8.0", "lodash-es": "^4.17.21" }, @@ -26054,7 +26043,7 @@ "@lit/react": "*", "@open-wc/eslint-config": "*", "@open-wc/testing": "*", - "@types/ace": "^0.0.52", + "@types/js-yaml": "^4.0.9", "@types/lodash-es": "^4.17.10", "@web/dev-server": "*", "@web/dev-server-esbuild": "^0.4.3", diff --git a/packages/ecc-utils-design/demo/code/index.html b/packages/ecc-utils-design/demo/code/index.html index 425e90c9..d7d7ca07 100644 --- a/packages/ecc-utils-design/demo/code/index.html +++ b/packages/ecc-utils-design/demo/code/index.html @@ -1,24 +1,24 @@ - - - - - ecc-utils-design - - - -
-
-
- + + +
+
+
+ - + render( + html` `, + document.querySelector("#demo") + ); + + diff --git a/packages/ecc-utils-design/package.json b/packages/ecc-utils-design/package.json index e2588237..331ca5ce 100644 --- a/packages/ecc-utils-design/package.json +++ b/packages/ecc-utils-design/package.json @@ -7,10 +7,7 @@ "module": "./dist/index.mjs", "types": "./dist/index.d.ts", "exports": { - ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js" - }, + ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" }, "./dist/custom-elements.json": "./dist/custom-elements.json", "./dist/index.js": "./dist/index.js", "./dist/components/*": "./dist/components/*", @@ -43,11 +40,10 @@ }, "devDependencies": { "@custom-elements-manifest/analyzer": "^0.8.4", - "@elixir-cloud/eslint-config": "*", "@lit/react": "*", "@open-wc/eslint-config": "*", "@open-wc/testing": "*", - "@types/ace": "^0.0.52", + "@types/js-yaml": "^4.0.9", "@types/lodash-es": "^4.17.10", "@web/dev-server": "*", "@web/dev-server-esbuild": "^0.4.3", @@ -58,6 +54,7 @@ "custom-element-vs-code-integration": "*", "esbuild": "0.18.20", "eslint": "*", + "@elixir-cloud/eslint-config": "*", "eslint-plugin-prettier": "^4.2.1", "globby": "^14.0.0", "react": "*", @@ -67,7 +64,7 @@ }, "dependencies": { "@shoelace-style/shoelace": "^2.8.0", - "ace-builds": "^1.35.0", + "js-yaml": "^4.1.0", "lit": "^2.8.0", "lodash-es": "^4.17.21" } diff --git a/packages/ecc-utils-design/src/components/code/code.styles.ts b/packages/ecc-utils-design/src/components/code/code.styles.ts index 6d46ee49..23606b6f 100644 --- a/packages/ecc-utils-design/src/components/code/code.styles.ts +++ b/packages/ecc-utils-design/src/components/code/code.styles.ts @@ -1,46 +1,15 @@ import { css } from "lit"; const codeStyles = css` - #label { - color: var(--ecc-input-label-color); - font-size: var(--ecc-input-label-font-size-medium); - font-family: var(--ecc-font-sans); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); - } - #editor { - width: 100%; - height: 12.5ex; - resize: vertical; - overflow: auto; - font-family: var(--ecc-font-mono); - background-color: var(--ecc-input-background-color); - border: solid var(--ecc-input-border-width) var(--ecc-input-border-color); - border-radius: var(--ecc-input-border-radius-medium); - font-size: var(--ecc-input-font-size-medium); - margin-top: var(--ecc-spacing-medium); - margin-bottom: var(--ecc-spacing-medium); - } - #editor:hover { - background-color: var(--ecc-input-background-color-hover); - border-color: var(--ecc-input-border-color-hover); - } - #editor:focus { - background-color: var(--ecc-input-background-color-focus); - border-color: var(--ecc-input-border-color-focus); - box-shadow: 0 0 0 var(--ecc-focus-ring-width) - var(--ecc-input-focus-ring-color); - } - .disabled { - background-color: var(--ecc-input-background-color-disabled); - border-color: var(--ecc-input-border-color-disabled); - opacity: 0.5; - cursor: not-allowed !important; + sl-textarea::part(form-control-label) { + display: flex; + gap: var(--sl-spacing-x-small); } - .header { + #label { display: flex; justify-content: space-between; align-items: center; + gap: var(--sl-spacing-x-small); } `; diff --git a/packages/ecc-utils-design/src/components/code/code.ts b/packages/ecc-utils-design/src/components/code/code.ts index 034d9885..7a689289 100644 --- a/packages/ecc-utils-design/src/components/code/code.ts +++ b/packages/ecc-utils-design/src/components/code/code.ts @@ -1,19 +1,18 @@ import { LitElement, html } from "lit"; import { property, state } from "lit/decorators.js"; -import "ace-builds/src-noconflict/ace.js"; -import "ace-builds/src-noconflict/theme-github.js"; -import "@shoelace-style/shoelace/dist/components/tag/tag.js"; -import _ from "lodash-es"; -import codeStyles from "./code.styles.js"; -import { primitiveStylesheet } from "../../styles/primitive.styles.js"; +import "@shoelace-style/shoelace/dist/components/input/input.js"; +import "@shoelace-style/shoelace/dist/components/badge/badge.js"; +import "@shoelace-style/shoelace/dist/components/textarea/textarea.js"; +import "@shoelace-style/shoelace/dist/components/copy-button/copy-button.js"; +import jsyaml from "js-yaml"; import { hostStyles } from "../../styles/host.styles.js"; import getShoelaceStyles from "../../styles/shoelace.styles.js"; +import codeStyles from "./code.styles.js"; -export type Language = "yaml" | "json" | "xml" | "makefile"; +export type Language = "YAML" | "JSON" | "Text"; export default class EccUtilsDesignCode extends LitElement { static styles = [ - primitiveStylesheet, getShoelaceStyles( document.querySelector("html")?.classList.contains("dark") ), @@ -22,65 +21,321 @@ export default class EccUtilsDesignCode extends LitElement { ]; @property({ type: String }) code = ""; - @property({ type: String }) label = "Code block"; - @property({ type: String }) language: Language = "json"; + @property({ type: String }) label = "Code"; + @property({ type: String }) language: Language = "YAML"; + @property({ type: Number }) indentation = 2; + @property({ type: Number }) blurDelay = 150; + @property({ type: Boolean }) required = true; @property({ type: Boolean }) disabled = false; - @state() editor: any; + @state() elTextarea: HTMLTextAreaElement | null = null; + @state() error = false; + @state() indent = ""; + @state() currentIndentation = ""; + @state() opening = ["(", "{", "[", "'", '"']; + @state() closing = [")", "}", "]", "'", '"']; + @state() lastTabPressTime = 0; + @state() errorLanguage: Language = "Text"; + + private cssParts = {}; + + private _getTextAreaEle(): HTMLTextAreaElement { + const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); + const ele = slTextarea?.shadowRoot?.querySelector("textarea"); + if (!ele || !(ele instanceof HTMLTextAreaElement)) { + throw new Error("Could not find textarea element"); + } + return ele; + } firstUpdated() { - this.initializeAceEditor(); + const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); + const ele = slTextarea?.shadowRoot?.querySelector("textarea"); + if (ele instanceof HTMLTextAreaElement) { + ele.value = this.code; + } + this.indent = " ".repeat(this.indentation); + this._updateTextarea(); + } + + public getCode() { + return this.code; + } + + private _setCursor(pos: number) { + this.elTextarea = this._getTextAreaEle(); + this.elTextarea.setSelectionRange(pos, pos); + } + + private _setSelect(from: number, to: number) { + this.elTextarea = this._getTextAreaEle(); + this.elTextarea.setSelectionRange(from, to); + } + + private _getCurrentLineIndent() { + const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); + const ele = slTextarea?.shadowRoot?.querySelector("textarea"); + if (!ele || !(ele instanceof HTMLTextAreaElement)) { + throw new Error("Could not find textarea element"); + } + this.elTextarea = ele; + + const selStart = this.elTextarea.selectionStart; + const selEnd = this.elTextarea.selectionEnd; + + const indentStart = this.code.lastIndexOf("\n", selStart - 1) + 1; + const spaces = (() => { + let pos = indentStart; + while (this.code[pos] === " " && pos < selEnd) pos += 1; + return pos - indentStart; + })(); + return " ".repeat(spaces); + } + + private _updateTextarea() { + if (!this.elTextarea) return; + this.elTextarea.value = this.code; + + this.dispatchEvent( + new CustomEvent("ecc-utils-change", { detail: this.code }) + ); + } + + private _insertCode(pos: number, text: string, placeCursor = true) { + this.code = this.code.substring(0, pos) + text + this.code.substring(pos); + this._updateTextarea(); + if (placeCursor) this._setCursor(pos + text.length); + } + + private _replaceCode( + posFrom: number, + posTo: number, + text = "", + placeCursor = true + ) { + this.code = + this.code.substring(0, posFrom) + text + this.code.substring(posTo); + this._updateTextarea(); + if (placeCursor) this._setCursor(posFrom + text.length); + } + + private _handleInput(e: InputEvent) { + this.code = (e.target as HTMLInputElement).value; + this._validateCode(); + this.dispatchEvent( + new CustomEvent("ecc-utils-change", { detail: this.code }) + ); + } + + private _handleTabs(e: KeyboardEvent) { + e.preventDefault(); + const slTextarea = this.shadowRoot?.querySelector("sl-textarea"); + const ele = slTextarea?.shadowRoot?.querySelector("textarea"); + if (!ele || !(ele instanceof HTMLTextAreaElement)) { + throw new Error("Could not find textarea element"); + } + this.elTextarea = ele; + const selStart = this.elTextarea.selectionStart; + const selEnd = this.elTextarea.selectionEnd; + + if (selStart !== selEnd) { + // multiline indent + const selLineStart = Math.max( + 0, + this.code.lastIndexOf("\n", selStart - 1) + ); + const selLineEnd = Math.max(this.code.indexOf("\n", selEnd), selEnd); + + let linesInChunk = 0; + let codeChunk = this.code.substring(selLineStart, selLineEnd); + let lenShift = this.indent.length; + if (selLineStart === 0) codeChunk = `\n${codeChunk}`; + + if (e.shiftKey) { + // Unindent + lenShift = -lenShift; + linesInChunk = ( + codeChunk.match(new RegExp(`\n${this.indent}`, "g")) || [] + ).length; + codeChunk = codeChunk.split(`\n${this.indent}`).join("\n"); + } else { + // Indent + linesInChunk = (codeChunk.match(/\n/g) || []).length; + codeChunk = codeChunk.split("\n").join(`\n${this.indent}`); + } + + if (selLineStart === 0) codeChunk = codeChunk.replace(/^\n/, ""); + this._replaceCode(selLineStart, selLineEnd, codeChunk, false); + + const newStart = Math.max(selLineStart + 1, selStart + lenShift); + const newEnd = selEnd + linesInChunk * lenShift; + this._setSelect(newStart, newEnd); + } else { + this._insertCode(selStart, this.indent, true); + } + } + + private _handleBackspace(e: KeyboardEvent) { + this.elTextarea = this._getTextAreaEle(); + const selStart = this.elTextarea.selectionStart; + const selEnd = this.elTextarea.selectionEnd; + if (e.ctrlKey || selStart !== selEnd) return; + + e.preventDefault(); + + const prevSymbol = this.code[selStart - 1]; + const curSymbol = this.code[selStart]; + const isInPairs = + this.opening.includes(prevSymbol) && this.closing.includes(curSymbol); + const isPair = this.closing[this.opening.indexOf(prevSymbol)] === curSymbol; + + if (isInPairs && isPair) { + this._replaceCode(selStart - 1, selStart + 1); + } else { + const chunkStart = selStart - this.indent.length; + const chunkEnd = selStart; + const chunk = this.code.substring(chunkStart, chunkEnd); + + if (chunk === this.indent) this._replaceCode(chunkStart, chunkEnd); + else this._replaceCode(selStart - 1, selStart); + } } - async initializeAceEditor() { - const editorElement = this.shadowRoot?.getElementById("editor"); - if (editorElement) { - this.editor = ace.edit(editorElement); - this.editor.setTheme("ace/theme/twilight"); - this.editor.renderer.attachToShadowRoot(); - this.editor.setValue(this.code); + private _handleAutoClose(e: KeyboardEvent) { + this.elTextarea = this._getTextAreaEle(); + const selStart = this.elTextarea.selectionStart; + const selEnd = this.elTextarea.selectionEnd; + if (this.code[selStart] === "'" || this.code[selStart] === '"') { + this._handleAutoSkip(e); + return; + } + e.preventDefault(); - await this.setEditorLanguage(this.language); - if (this.disabled) this.editor.setReadOnly(true); + if (selStart === selEnd) { + const opening = e.key; + const closing = this.closing[this.opening.indexOf(opening)]; - this.editor.on("change", () => { - this.code = this.editor.getValue(); - }); + if ( + opening === "{" && + (this.code[selStart] === "\n" || this.code.length === selStart) + ) { + const lineShift = `\n${this._getCurrentLineIndent()}`; + this._insertCode( + selStart, + opening + lineShift + this.indent + lineShift + closing + ); + this._setCursor(selStart + lineShift.length + this.indent.length + 1); + } else { + this._insertCode(selStart, opening + closing); + this._setCursor(selStart + 1); + } } } - async setEditorLanguage(language: Language) { - if (!this.editor) return; - try { - await import(`ace-builds/src-noconflict/mode-${language}.js`); - this.editor.session.setMode(`ace/mode/${language}`); - } catch (error) { - console.error(`Failed to load Ace mode for ${language}`, error); - this.editor.session.setMode("ace/mode/text"); + private _handleAutoSkip(e: KeyboardEvent): void { + this.elTextarea = this._getTextAreaEle(); + const selStart = this.elTextarea.selectionStart; + + if (this.code[selStart] === e.key) { + e.preventDefault(); + this._setCursor(selStart + 1); } } - updated(changedProperties: Map) { - if (changedProperties.has("language")) { - this.setEditorLanguage(this.language); + private _handleNewLine(e: KeyboardEvent) { + e.preventDefault(); + this.elTextarea = this._getTextAreaEle(); + this._insertCode( + this.elTextarea.selectionStart, + `\n${this._getCurrentLineIndent()}` + ); + } + + private _handleKeys(e: KeyboardEvent) { + const currentTime = new Date().getTime(); + const timeSinceLastTabPress = currentTime - this.lastTabPressTime; + + switch (e.code) { + case "Tab": + if (timeSinceLastTabPress > this.blurDelay) { + this._handleTabs(e); + } else { + this.shadowRoot?.querySelector("sl-textarea")?.blur(); + e.preventDefault(); + } + + this.lastTabPressTime = currentTime; + break; + case "Enter": + this._handleNewLine(e); + break; + case "Backspace": + this._handleBackspace(e); + break; + default: + if (this.opening.includes(e.key)) this._handleAutoClose(e); + else if (this.closing.includes(e.key)) this._handleAutoSkip(e); } - if (changedProperties.has("disabled") && this.editor) { - this.editor.setReadOnly(this.disabled); + this._validateCode(); + this.dispatchEvent( + new CustomEvent("ecc-utils-change", { detail: this.code }) + ); + } + + private _validateCode(): void { + if (this.code === "") { + this.error = false; + return; } + + if (this.language === "JSON") { + try { + JSON.parse(this.code); + this.error = false; + } catch (error) { + try { + jsyaml.loadAll(this.code); + this.errorLanguage = "YAML"; + } catch (err) { + this.errorLanguage = "Text"; + } + this.error = true; + } + } else if (this.language === "YAML") { + try { + jsyaml.loadAll(this.code); + this.error = false; + } catch (error) { + this.error = true; + this.errorLanguage = "Text"; + } + } else this.error = false; } render() { return html` -
-
${this.label}
- ${_.upperCase(this.language)}
- -
-
-
+ +
+ ${this.label} + ${this.language} + ${this.error + ? html`${this.errorLanguage}` + : html``} + +
+
`; } } From 76ceade038cbc82dcdd232ec52b9e9a4cb711c3f Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 20:45:32 +0100 Subject: [PATCH 06/14] Revert "chore: rm .idea" This reverts commit f46ed88811313ec92bb1e6b2613ab8178bd33df6. --- .idea/.gitignore | 5 ++ .idea/cloud-components.iml | 12 ++++ .idea/codeStyles/Project.xml | 59 ++++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ .idea/inspectionProfiles/Project_Default.xml | 6 ++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 6 ++ 7 files changed, 101 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/cloud-components.iml create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..b58b603f --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/cloud-components.iml b/.idea/cloud-components.iml new file mode 100644 index 00000000..24643cc3 --- /dev/null +++ b/.idea/cloud-components.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..c5b88c74 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..79ee123c --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..03d9549e --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..6338d9de --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 4d674b85681965a645a6025332a26b5b48e241af Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 20:49:07 +0100 Subject: [PATCH 07/14] Revert "feat: css variables" This reverts commit f2d2901e76b392e87b61970b62e2fdb0f99e7a95. --- .idea/.gitignore | 5 - .idea/cloud-components.iml | 12 - .idea/codeStyles/Project.xml | 59 --- .idea/codeStyles/codeStyleConfig.xml | 5 - .idea/inspectionProfiles/Project_Default.xml | 6 - .idea/modules.xml | 8 - .idea/vcs.xml | 6 - .../demo/collection/index.html | 10 +- .../ecc-utils-design/demo/details/index.html | 9 +- .../ecc-utils-design/demo/form/index.html | 49 +- .../collection/collection.styles.ts | 87 +--- .../src/components/collection/collection.ts | 10 +- .../src/components/details/details.styles.ts | 95 ---- .../src/components/details/details.ts | 80 ++- .../src/components/form/form.styles.ts | 168 ++----- .../src/components/form/form.ts | 3 - .../src/styles/primitive.styles.ts | 361 -------------- .../src/styles/shoelace.styles.ts | 470 +++++++++--------- 18 files changed, 395 insertions(+), 1048 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/cloud-components.iml delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 packages/ecc-utils-design/src/components/details/details.styles.ts delete mode 100644 packages/ecc-utils-design/src/styles/primitive.styles.ts diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603f..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/cloud-components.iml b/.idea/cloud-components.iml deleted file mode 100644 index 24643cc3..00000000 --- a/.idea/cloud-components.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index c5b88c74..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549e..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 6338d9de..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/packages/ecc-utils-design/demo/collection/index.html b/packages/ecc-utils-design/demo/collection/index.html index c2dc29f6..8f6d7333 100644 --- a/packages/ecc-utils-design/demo/collection/index.html +++ b/packages/ecc-utils-design/demo/collection/index.html @@ -2,14 +2,14 @@ - - ecc-utils-design - + + ecc-utils-design +
diff --git a/packages/ecc-utils-design/demo/details/index.html b/packages/ecc-utils-design/demo/details/index.html index 394c19be..809673e5 100644 --- a/packages/ecc-utils-design/demo/details/index.html +++ b/packages/ecc-utils-design/demo/details/index.html @@ -2,8 +2,13 @@ - - + + ecc-utils-design diff --git a/packages/ecc-utils-design/demo/form/index.html b/packages/ecc-utils-design/demo/form/index.html index 7e82c0fd..c882e2d9 100644 --- a/packages/ecc-utils-design/demo/form/index.html +++ b/packages/ecc-utils-design/demo/form/index.html @@ -2,8 +2,8 @@ - - + ecc-utils-design @@ -118,23 +118,6 @@ tooltip: "Your email address", }, }, - { - key: "18+", - label: "18+", - type: "switch", - fieldOptions: { - tooltip: "Are you over 18 years old?", - }, - }, - { - key: "id", - label: "ID", - type: "file", - fieldOptions: { - required: true, - tooltip: "Your ID document", - }, - }, { key: "address", label: "Address", @@ -203,17 +186,25 @@ }, ], }, - { - key: "country", - label: "Country", - type: "text", - fieldOptions: { - required: true, - tooltip: "Your country name", - }, - }, ], }, + { + key: "18+", + label: "18+", + type: "switch", + fieldOptions: { + tooltip: "Are you over 18 years old?", + }, + }, + { + key: "id", + label: "ID", + type: "file", + fieldOptions: { + required: true, + tooltip: "Your ID document", + }, + }, ]; render( diff --git a/packages/ecc-utils-design/src/components/collection/collection.styles.ts b/packages/ecc-utils-design/src/components/collection/collection.styles.ts index d1a0707b..637a81a9 100644 --- a/packages/ecc-utils-design/src/components/collection/collection.styles.ts +++ b/packages/ecc-utils-design/src/components/collection/collection.styles.ts @@ -4,89 +4,54 @@ const styles = css` :host { display: block; } - /* Header */ - .header { - margin-bottom: var(--ecc-spacing-x-large); + .collection { + position: relative; + } + .title { + width: 100%; + display: flex; + justify-content: space-between; + margin-right: 1rem; + align-items: center; } .filters { display: flex; justify-content: flex-end; - gap: var(--ecc-spacing-medium); + gap: 1rem; } - /* Error Popup */ - .error { - width: 100%; - position: absolute; - top: var(--ecc-spacing-x-large); - display: flex; - justify-content: center; - z-index: var(--ecc-z-index-tooltip); + .header { + margin-bottom: 1rem; } - /* Footer */ .footer { - margin-top: var(--ecc-spacing-x-large); + margin-top: 1rem; display: flex; justify-content: center; } - .page { - height: var(--ecc-input-height-medium); - width: var(--ecc-input-height-medium); - } - /* Items */ - sl-details { - margin-bottom: var(--ecc-spacing-medium); - margin-top: var(--ecc-spacing-medium); - } - .title { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - margin-right: var(--ecc-spacing-medium); - height: var(--ecc-input-height-small); - font-size: var(--ecc-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); - } .skeleton-title { width: 30%; - height: var(--ecc-font-size-medium); - } - .badge { - height: var(--ecc-input-height-small); + height: 1.5rem; } - .badge::part(base) { - font-size: var(--ecc-font-size-small); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); - border-radius: var(--ecc-input-border-radius-small); + .skeleton-body { + width: 100%; + height: 1rem; } .lazy { display: flex; flex-direction: column; - gap: var(--ecc-spacing-medium); - } - .skeleton-body { - width: 100%; - height: var(--ecc-font-size-medium); + gap: 0.5rem; } - sl-skeleton::part(base) { - border-radius: var(--ecc-input-border-radius-medium); - overflow: hidden; - } - .content { - font-size: var(--ecc-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); + .badge { + height: 1.5rem; } .hidden { visibility: hidden; } - .collection { - position: relative; + .error { + width: 100%; + position: absolute; + top: 1rem; + display: flex; + justify-content: center; } `; diff --git a/packages/ecc-utils-design/src/components/collection/collection.ts b/packages/ecc-utils-design/src/components/collection/collection.ts index 726eea82..7905d311 100644 --- a/packages/ecc-utils-design/src/components/collection/collection.ts +++ b/packages/ecc-utils-design/src/components/collection/collection.ts @@ -13,8 +13,6 @@ import "@shoelace-style/shoelace/dist/components/alert/alert.js"; import { hostStyles } from "../../styles/host.styles.js"; import collectionStyles from "./collection.styles.js"; -import { primitiveStylesheet } from "../../styles/primitive.styles.js"; - export interface ItemProp { index: number; name: string; @@ -54,7 +52,6 @@ export interface FilterProp { */ export default class EccUtilsDesignCollection extends LitElement { static styles = [ - primitiveStylesheet, getShoelaceStyles( document.querySelector("html")?.classList.contains("dark") ), @@ -145,7 +142,6 @@ export default class EccUtilsDesignCollection extends LitElement { return html` - + ${item.lazy ? html`
${field.copy ? html`` : ""}
@@ -211,8 +269,7 @@ export default class EccUtilsDesignDetails extends LitElement { ${field.label} ${field.copy ? html`` : ""}
@@ -241,7 +298,7 @@ export default class EccUtilsDesignDetails extends LitElement { ${field.label} ${field.copy ? html`` : ""} @@ -316,7 +373,7 @@ export default class EccUtilsDesignDetails extends LitElement { ${fieldwithProps.copy ? html`` : ""} @@ -339,7 +396,7 @@ export default class EccUtilsDesignDetails extends LitElement { private _renderAction(action: Action) { if (action.type === "link") { return html` window.open(action.linkOptions?.url, "_blank")} @@ -348,7 +405,6 @@ export default class EccUtilsDesignDetails extends LitElement { `; } return html` this.dispatchEvent( new CustomEvent("ecc-utils-button-click", { diff --git a/packages/ecc-utils-design/src/components/form/form.styles.ts b/packages/ecc-utils-design/src/components/form/form.styles.ts index dba270c0..e1d7d32b 100644 --- a/packages/ecc-utils-design/src/components/form/form.styles.ts +++ b/packages/ecc-utils-design/src/components/form/form.styles.ts @@ -8,76 +8,23 @@ const styles = css` display: flex; flex-direction: column; } - .success-icon { - height: var(--ecc-input-font-size-medium); - } - .error-icon { - height: var(--ecc-input-font-size-medium); - } form sl-input { - margin-top: var(--ecc-spacing-medium); - margin-bottom: var(--ecc-spacing-medium); - } - /* Group Styles */ - sl-details::part(base) { - border: 0px; + margin-top: 0.5rem; + margin-bottom: 0.5rem; } - sl-details::part(header) { - padding-left: 0px; - padding-right: 0px; - padding-top: 0px; - border-bottom: var(--ecc-input-border-width) solid - var(--ecc-input-border-color); - } - sl-details::part(header):hover { - border-color: var(--ecc-input-border-width) solid - var(--ecc-input-border-color-hover); - } - sl-details::part(content) { - padding-left: 0px; - padding-right: 0px; - padding-bottom: 0px; - } - sl-details::part(summary) { - font-size: var(--ecc-input-label-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); + form sl-switch { + margin-top: 0.5rem; + margin-bottom: 0.5rem; } .group-container { - margin-top: var(--ecc-spacing-medium); - margin-bottom: var(--ecc-spacing-medium); - } - .group-label { - width: 100%; - font-size: var(--ecc-input-label-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); - } - .group-header { - padding-bottom: var(--ecc-spacing-medium); - border-bottom: var(--ecc-input-border-width) solid - var(--ecc-input-border-color); - } - .group-header:hover { - border-bottom: var(--ecc-input-border-width) solid - var(--ecc-input-border-color-hover); - } - .group-content { - padding-top: var(--ecc-spacing-medium); - } - /* Array Styles */ - .array-label { - font-size: var(--ecc-input-label-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); + margin: 1rem 0; } - .array-item { + .array-item, + .group-item { + margin: 1rem 0; border-style: solid; - border-width: 0px 0px var(--ecc-input-border-width) 0px; - border-color: var(--ecc-input-border-color-disabled); + border-width: 0px 0px 1px 0px; + border-color: var(--sl-color-gray-300); } .array-item { display: flex; @@ -88,86 +35,51 @@ const styles = css` display: flex; justify-content: space-between; align-items: center; - margin-bottom: var(--ecc-spacing-medium); + margin-bottom: 1rem; } .array-item-container { width: 100%; } .delete-icon { - height: var(--ecc-input-font-size-large); + height: 1.25rem; } .add-icon { - height: var(--ecc-input-font-size-medium); + height: 1.1rem; } - /* switch styles */ .switch-container { - margin-top: var(--ecc-spacing-medium); - margin-bottom: var(--ecc-spacing-medium); display: flex; + flex-direction: row; justify-content: space-between; - align-items: center; } - .switch-label { - font-size: var(--ecc-input-label-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); - } - /* file input styles */ - .file-container { + input[type="file"]::file-selector-button { + height: 100%; + background-color: #fff; + border: 0px; + border-right: 1px solid #d4d4d8; + padding-right: 20px; + padding-left: 20px; + margin-right: 10px; + font-size: 1rem; + } + input[type="file"] { + background-color: #fff; + border: 1px solid #d4d4d8; + border-radius: 4px; + margin-top: 0.5rem; + margin-bottom: 0.5rem; + height: 2.5rem; + font-size: 1rem; + color: #000; + } + .row { display: flex; flex-direction: column; } - .file-input-label { - width: max-content; - font-size: var(--ecc-input-label-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); + .success-icon { + height: 1.25rem; } - .file-input::file-selector-button { - cursor: pointer; - height: 100%; - background-color: var(--ecc-color-neutral-0); - font-size: var(--ecc-input-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); - background-color: var(--ecc-input-background-color); - border: 0px; - border-right: solid var(--ecc-input-border-width) - var(--ecc-input-border-color); - padding: 0px var(--ecc-spacing-2x-large); - margin-right: var(--ecc-spacing-x-large); - } - .file-input { - background-color: var(--ecc-color-neutral-0); - border-radius: var(--ecc-input-border-radius-medium); - font-size: var(--ecc-input-font-size-medium); - font-family: var(--ecc-input-font-family); - font-weight: var(--ecc-input-font-weight); - letter-spacing: var(--ecc-input-letter-spacing); - border: solid var(--ecc-input-border-width) var(--ecc-input-border-color); - height: var(--ecc-input-height-medium); - margin-top: var(--ecc-spacing-medium); - margin-bottom: var(--ecc-spacing-medium); - } - .file-input:hover, - .file-input::file-selector-button:hover { - background-color: var(--ecc-input-background-color-hover); - border-color: var(--ecc-input-border-color-hover); - } - .file-input:focus, - .file-input::file-selector-button:focus { - background-color: var(--ecc-input-background-color-focus); - border-color: var(--ecc-input-border-color-focus); - box-shadow: 0 0 0 var(--ecc-focus-ring-width) - var(--ecc-input-focus-ring-color); - } - /* Submit Button */ - .submit-button { - margin-top: var(--ecc-spacing-large); - margin-bottom: var(--ecc-spacing-large); + .error-icon { + height: 1.25rem; } `; diff --git a/packages/ecc-utils-design/src/components/form/form.ts b/packages/ecc-utils-design/src/components/form/form.ts index 429e6d1c..10147696 100644 --- a/packages/ecc-utils-design/src/components/form/form.ts +++ b/packages/ecc-utils-design/src/components/form/form.ts @@ -28,7 +28,6 @@ import switchTemplate from "./templates/switchTemplate.js"; */ export default class EccUtilsDesignForm extends LitElement { static styles = [ - primitiveStylesheet, getShoelaceStyles( document.querySelector("html")?.classList.contains("dark") ), @@ -371,8 +370,6 @@ export default class EccUtilsDesignForm extends LitElement { Date: Fri, 12 Jul 2024 20:57:09 +0100 Subject: [PATCH 08/14] Revert "chore: rm .idea" This reverts commit f46ed88811313ec92bb1e6b2613ab8178bd33df6. --- .idea/.gitignore | 5 ++ .idea/cloud-components.iml | 12 ++++ .idea/codeStyles/Project.xml | 59 ++++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ .idea/inspectionProfiles/Project_Default.xml | 6 ++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 6 ++ 7 files changed, 101 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/cloud-components.iml create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..b58b603f --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/cloud-components.iml b/.idea/cloud-components.iml new file mode 100644 index 00000000..24643cc3 --- /dev/null +++ b/.idea/cloud-components.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..c5b88c74 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..79ee123c --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..03d9549e --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..6338d9de --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 8f0101cf8a7300291078fc47c0e0498ab2e92850 Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 21:02:02 +0100 Subject: [PATCH 09/14] Revert "Revert "chore: rm .idea"" This reverts commit bff1b2ff71008143c09d5280c154c5a752fe18e2. --- .idea/.gitignore | 5 -- .idea/cloud-components.iml | 12 ---- .idea/codeStyles/Project.xml | 59 -------------------- .idea/codeStyles/codeStyleConfig.xml | 5 -- .idea/inspectionProfiles/Project_Default.xml | 6 -- .idea/modules.xml | 8 --- .idea/vcs.xml | 6 -- 7 files changed, 101 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/cloud-components.iml delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603f..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/cloud-components.iml b/.idea/cloud-components.iml deleted file mode 100644 index 24643cc3..00000000 --- a/.idea/cloud-components.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index c5b88c74..00000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549e..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 6338d9de..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From d7ab952cd1df3842845379337278684680e6bafe Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 21:08:12 +0100 Subject: [PATCH 10/14] Revert "feat: css variables" This reverts commit f2d2901e76b392e87b61970b62e2fdb0f99e7a95. --- .../src/components/form/form.ts | 151 ++++++++---------- 1 file changed, 71 insertions(+), 80 deletions(-) diff --git a/packages/ecc-utils-design/src/components/form/form.ts b/packages/ecc-utils-design/src/components/form/form.ts index 10147696..36419c6a 100644 --- a/packages/ecc-utils-design/src/components/form/form.ts +++ b/packages/ecc-utils-design/src/components/form/form.ts @@ -1,18 +1,18 @@ -import { html, LitElement, TemplateResult } from "lit"; -import { property, state } from "lit/decorators.js"; -import "@shoelace-style/shoelace/dist/components/button/button.js"; -import _ from "lodash-es"; -import getShoelaceStyles from "../../styles/shoelace.styles.js"; -import { hostStyles } from "../../styles/host.styles.js"; -import formStyles from "./form.styles.js"; -import { Field } from "./types.js"; -import { primitiveStylesheet } from "../../styles/primitive.styles.js"; -import inputTemplate from "./templates/inputTemplate.js"; -import arrayTemplate from "./templates/arrayTemplate.js"; -import groupTemplate from "./templates/groupTemplate.js"; -import errorTemplate from "./templates/errorTemplate.js"; -import successTemplate from "./templates/successTemplate.js"; -import switchTemplate from "./templates/switchTemplate.js"; +import { html, LitElement, TemplateResult } from 'lit'; +import { property, state } from 'lit/decorators.js'; +import '@shoelace-style/shoelace/dist/components/button/button.js'; +import _ from 'lodash-es'; +import getShoelaceStyles from '../../styles/shoelace.styles.js'; +import { hostStyles } from '../../styles/host.styles.js'; +import formStyles from './form.styles.js'; +import { Field } from './types.js'; +import { primitiveStylesheet } from '../../styles/primitive.styles.js'; +import inputTemplate from './templates/inputTemplate.js'; +import arrayTemplate from './templates/arrayTemplate.js'; +import groupTemplate from './templates/groupTemplate.js'; +import errorTemplate from './templates/errorTemplate.js'; +import successTemplate from './templates/successTemplate.js'; +import switchTemplate from './templates/switchTemplate.js'; /** * @summary This component is used to render a form with the given fields. @@ -28,61 +28,59 @@ import switchTemplate from "./templates/switchTemplate.js"; */ export default class EccUtilsDesignForm extends LitElement { static styles = [ - getShoelaceStyles( - document.querySelector("html")?.classList.contains("dark") - ), + getShoelaceStyles(document.querySelector('html')?.classList.contains('dark')), hostStyles, formStyles, ]; @property({ type: Array, reflect: true }) fields: Array = []; @state() private form: object = {}; - @state() private formState: "idle" | "loading" | "error" | "success" = "idle"; + @state() private formState: 'idle' | 'loading' | 'error' | 'success' = 'idle'; @state() private canSubmit = false; @state() private submitDisabledByUser = false; - @state() private errorMessage = "Something went wrong"; - @state() private successMessage = "Form submitted successfully"; + @state() private errorMessage = 'Something went wrong'; + @state() private successMessage = 'Form submitted successfully'; @state() private requiredButEmpty: string[] = []; protected cssParts = { - switchControl: "switch", - switchThumb: "switch-thumb", - switchLabel: "switch-label", - formControl: "field", - formControlLabel: "input-label", - input: "input", - inputBase: "input-base", - button: "button", - addButton: "add-button", - removeButton: "remove-button", - submitButton: "submit-button", - header: "header", - label: "label", - arrayHeader: "array-header", - arrayContainer: "array-container", - arrayLabel: "array-label", - arrayItem: "array-item", - groupBase: "group", - groupHeader: "group-header", - groupItem: "group-item", - groupLabel: "group-label", - groupToggleIcon: "group-toggle-icon", - groupContent: "group-content", - container: "container", - item: "item", - form: "form", + switchControl: 'switch', + switchThumb: 'switch-thumb', + switchLabel: 'switch-label', + formControl: 'field', + formControlLabel: 'input-label', + input: 'input', + inputBase: 'input-base', + button: 'button', + addButton: 'add-button', + removeButton: 'remove-button', + submitButton: 'submit-button', + header: 'header', + label: 'label', + arrayHeader: 'array-header', + arrayContainer: 'array-container', + arrayLabel: 'array-label', + arrayItem: 'array-item', + groupBase: 'group', + groupHeader: 'group-header', + groupItem: 'group-item', + groupLabel: 'group-label', + groupToggleIcon: 'group-toggle-icon', + groupContent: 'group-content', + container: 'container', + item: 'item', + form: 'form', }; connectedCallback() { super.connectedCallback(); if (!this.fields) { - throw new Error("Fields is required"); + throw new Error('Fields is required'); } } private renderSwitchTemplate(field: Field, path: string): TemplateResult { - if (field.type !== "switch") return html``; + if (field.type !== 'switch') return html``; if (!_.get(this.form, path) && !this.hasUpdated) { _.set(this.form, path, field.fieldOptions?.default || false); @@ -106,18 +104,13 @@ export default class EccUtilsDesignForm extends LitElement { } private renderInputTemplate(field: Field, path: string): TemplateResult { - if ( - field.type === "array" || - field.type === "switch" || - field.type === "group" - ) + if (field.type === 'array' || field.type === 'switch' || field.type === 'group') return html``; - const { formControl, formControlLabel, input, inputBase, label } = - this.cssParts; + const { formControl, formControlLabel, input, inputBase, label } = this.cssParts; const changeAction = - field.type === "file" + field.type === 'file' ? (e: Event) => { const { files } = e.target as HTMLInputElement; _.set(this.form, path, files); @@ -139,7 +132,7 @@ export default class EccUtilsDesignForm extends LitElement { if (field.fieldOptions?.default && !this.hasUpdated) { _.set(this.form, path, field.fieldOptions.default); } else if (field.fieldOptions?.returnIfEmpty) { - _.set(this.form, path, ""); + _.set(this.form, path, ''); } } }; @@ -265,9 +258,7 @@ export default class EccUtilsDesignForm extends LitElement { const renderChildren = () => html`
- ${field.children?.map((child) => - this.renderTemplate(child, `${path}`) - )} + ${field.children?.map((child) => this.renderTemplate(child, `${path}`))}
`; @@ -276,29 +267,29 @@ export default class EccUtilsDesignForm extends LitElement { private renderTemplate(field: Field, path: string): TemplateResult { const newPath = `${path}.${field.key}`; - if (field.type === "group") { + if (field.type === 'group') { return this.renderGroupTemplate(field, newPath); } - if (field.type === "array") { + if (field.type === 'array') { return this.renderArrayTemplate(field, newPath); } if (field.fieldOptions?.required && !_.get(this.form, newPath)) { this.requiredButEmpty.push(field.key); } - if (field.type === "switch") { + if (field.type === 'switch') { return this.renderSwitchTemplate(field, newPath); } return this.renderInputTemplate(field, newPath); } private renderErrorTemplate(): TemplateResult { - if (this.formState !== "error") return html``; + if (this.formState !== 'error') return html``; return errorTemplate(this.errorMessage); } private renderSuccessTemplate(): TemplateResult { - if (this.formState !== "success") return html``; + if (this.formState !== 'success') return html``; return successTemplate(this.successMessage); } @@ -308,29 +299,29 @@ export default class EccUtilsDesignForm extends LitElement { } public loading() { - this.formState = "loading"; + this.formState = 'loading'; } public success({ message }: { message?: string }) { - this.formState = "success"; - this.successMessage = message || "Form submitted successfully"; + this.formState = 'success'; + this.successMessage = message || 'Form submitted successfully'; } public error({ message }: { message?: string }) { - this.formState = "error"; - this.errorMessage = message || "Something went wrong"; + this.formState = 'error'; + this.errorMessage = message || 'Something went wrong'; } public idle() { - this.formState = "idle"; + this.formState = 'idle'; } render() { this.requiredButEmpty = []; if (!this.fields || this.fields.length === 0) { - throw new Error("Fields is required & should not be empty array"); + throw new Error('Fields is required & should not be empty array'); } - if (this.formState === "success") { + if (this.formState === 'success') { return html` ${this.renderSuccessTemplate()} `; } @@ -341,7 +332,7 @@ export default class EccUtilsDesignForm extends LitElement { this.canSubmit = true; } - return ""; + return ''; }; const { button, submitButton, form: csspartForm } = this.cssParts; @@ -350,12 +341,12 @@ export default class EccUtilsDesignForm extends LitElement { part="${csspartForm}" @submit=${(e: Event) => { e.preventDefault(); - const form = this.shadowRoot?.querySelector("form"); + const form = this.shadowRoot?.querySelector('form'); const isValid = form?.reportValidity(); if (!isValid) { return; } - const event = new CustomEvent("ecc-utils-submit", { + const event = new CustomEvent('ecc-utils-submit', { detail: { form: this.form, }, @@ -365,16 +356,16 @@ export default class EccUtilsDesignForm extends LitElement { this.dispatchEvent(event); }} > - ${this.fields.map((field) => this.renderTemplate(field, "data"))} + ${this.fields.map((field) => this.renderTemplate(field, 'data'))} ${this.renderErrorTemplate()} ${toggleButtonState()} Submit From edf9f8db144d4963c4cad843567f25cd77e4c7ef Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 21:09:29 +0100 Subject: [PATCH 11/14] Revert "feat: css variables" This reverts commit f2d2901e76b392e87b61970b62e2fdb0f99e7a95. --- .../src/components/form/form.ts | 150 +++++++++--------- 1 file changed, 79 insertions(+), 71 deletions(-) diff --git a/packages/ecc-utils-design/src/components/form/form.ts b/packages/ecc-utils-design/src/components/form/form.ts index 36419c6a..3da95a63 100644 --- a/packages/ecc-utils-design/src/components/form/form.ts +++ b/packages/ecc-utils-design/src/components/form/form.ts @@ -1,18 +1,17 @@ -import { html, LitElement, TemplateResult } from 'lit'; -import { property, state } from 'lit/decorators.js'; -import '@shoelace-style/shoelace/dist/components/button/button.js'; -import _ from 'lodash-es'; -import getShoelaceStyles from '../../styles/shoelace.styles.js'; -import { hostStyles } from '../../styles/host.styles.js'; -import formStyles from './form.styles.js'; -import { Field } from './types.js'; -import { primitiveStylesheet } from '../../styles/primitive.styles.js'; -import inputTemplate from './templates/inputTemplate.js'; -import arrayTemplate from './templates/arrayTemplate.js'; -import groupTemplate from './templates/groupTemplate.js'; -import errorTemplate from './templates/errorTemplate.js'; -import successTemplate from './templates/successTemplate.js'; -import switchTemplate from './templates/switchTemplate.js'; +import { html, LitElement, TemplateResult } from "lit"; +import { property, state } from "lit/decorators.js"; +import "@shoelace-style/shoelace/dist/components/button/button.js"; +import _ from "lodash-es"; +import getShoelaceStyles from "../../styles/shoelace.styles.js"; +import { hostStyles } from "../../styles/host.styles.js"; +import formStyles from "./form.styles.js"; +import { Field } from "./types.js"; +import inputTemplate from "./templates/inputTemplate.js"; +import arrayTemplate from "./templates/arrayTemplate.js"; +import groupTemplate from "./templates/groupTemplate.js"; +import errorTemplate from "./templates/errorTemplate.js"; +import successTemplate from "./templates/successTemplate.js"; +import switchTemplate from "./templates/switchTemplate.js"; /** * @summary This component is used to render a form with the given fields. @@ -28,59 +27,61 @@ import switchTemplate from './templates/switchTemplate.js'; */ export default class EccUtilsDesignForm extends LitElement { static styles = [ - getShoelaceStyles(document.querySelector('html')?.classList.contains('dark')), + getShoelaceStyles( + document.querySelector("html")?.classList.contains("dark") + ), hostStyles, formStyles, ]; @property({ type: Array, reflect: true }) fields: Array = []; @state() private form: object = {}; - @state() private formState: 'idle' | 'loading' | 'error' | 'success' = 'idle'; + @state() private formState: "idle" | "loading" | "error" | "success" = "idle"; @state() private canSubmit = false; @state() private submitDisabledByUser = false; - @state() private errorMessage = 'Something went wrong'; - @state() private successMessage = 'Form submitted successfully'; + @state() private errorMessage = "Something went wrong"; + @state() private successMessage = "Form submitted successfully"; @state() private requiredButEmpty: string[] = []; protected cssParts = { - switchControl: 'switch', - switchThumb: 'switch-thumb', - switchLabel: 'switch-label', - formControl: 'field', - formControlLabel: 'input-label', - input: 'input', - inputBase: 'input-base', - button: 'button', - addButton: 'add-button', - removeButton: 'remove-button', - submitButton: 'submit-button', - header: 'header', - label: 'label', - arrayHeader: 'array-header', - arrayContainer: 'array-container', - arrayLabel: 'array-label', - arrayItem: 'array-item', - groupBase: 'group', - groupHeader: 'group-header', - groupItem: 'group-item', - groupLabel: 'group-label', - groupToggleIcon: 'group-toggle-icon', - groupContent: 'group-content', - container: 'container', - item: 'item', - form: 'form', + switchControl: "switch", + switchThumb: "switch-thumb", + switchLabel: "switch-label", + formControl: "field", + formControlLabel: "input-label", + input: "input", + inputBase: "input-base", + button: "button", + addButton: "add-button", + removeButton: "remove-button", + submitButton: "submit-button", + header: "header", + label: "label", + arrayHeader: "array-header", + arrayContainer: "array-container", + arrayLabel: "array-label", + arrayItem: "array-item", + groupBase: "group", + groupHeader: "group-header", + groupItem: "group-item", + groupLabel: "group-label", + groupToggleIcon: "group-toggle-icon", + groupContent: "group-content", + container: "container", + item: "item", + form: "form", }; connectedCallback() { super.connectedCallback(); if (!this.fields) { - throw new Error('Fields is required'); + throw new Error("Fields is required"); } } private renderSwitchTemplate(field: Field, path: string): TemplateResult { - if (field.type !== 'switch') return html``; + if (field.type !== "switch") return html``; if (!_.get(this.form, path) && !this.hasUpdated) { _.set(this.form, path, field.fieldOptions?.default || false); @@ -104,13 +105,18 @@ export default class EccUtilsDesignForm extends LitElement { } private renderInputTemplate(field: Field, path: string): TemplateResult { - if (field.type === 'array' || field.type === 'switch' || field.type === 'group') + if ( + field.type === "array" || + field.type === "switch" || + field.type === "group" + ) return html``; - const { formControl, formControlLabel, input, inputBase, label } = this.cssParts; + const { formControl, formControlLabel, input, inputBase, label } = + this.cssParts; const changeAction = - field.type === 'file' + field.type === "file" ? (e: Event) => { const { files } = e.target as HTMLInputElement; _.set(this.form, path, files); @@ -132,7 +138,7 @@ export default class EccUtilsDesignForm extends LitElement { if (field.fieldOptions?.default && !this.hasUpdated) { _.set(this.form, path, field.fieldOptions.default); } else if (field.fieldOptions?.returnIfEmpty) { - _.set(this.form, path, ''); + _.set(this.form, path, ""); } } }; @@ -258,7 +264,9 @@ export default class EccUtilsDesignForm extends LitElement { const renderChildren = () => html`
- ${field.children?.map((child) => this.renderTemplate(child, `${path}`))} + ${field.children?.map((child) => + this.renderTemplate(child, `${path}`) + )}
`; @@ -267,29 +275,29 @@ export default class EccUtilsDesignForm extends LitElement { private renderTemplate(field: Field, path: string): TemplateResult { const newPath = `${path}.${field.key}`; - if (field.type === 'group') { + if (field.type === "group") { return this.renderGroupTemplate(field, newPath); } - if (field.type === 'array') { + if (field.type === "array") { return this.renderArrayTemplate(field, newPath); } if (field.fieldOptions?.required && !_.get(this.form, newPath)) { this.requiredButEmpty.push(field.key); } - if (field.type === 'switch') { + if (field.type === "switch") { return this.renderSwitchTemplate(field, newPath); } return this.renderInputTemplate(field, newPath); } private renderErrorTemplate(): TemplateResult { - if (this.formState !== 'error') return html``; + if (this.formState !== "error") return html``; return errorTemplate(this.errorMessage); } private renderSuccessTemplate(): TemplateResult { - if (this.formState !== 'success') return html``; + if (this.formState !== "success") return html``; return successTemplate(this.successMessage); } @@ -299,29 +307,29 @@ export default class EccUtilsDesignForm extends LitElement { } public loading() { - this.formState = 'loading'; + this.formState = "loading"; } public success({ message }: { message?: string }) { - this.formState = 'success'; - this.successMessage = message || 'Form submitted successfully'; + this.formState = "success"; + this.successMessage = message || "Form submitted successfully"; } public error({ message }: { message?: string }) { - this.formState = 'error'; - this.errorMessage = message || 'Something went wrong'; + this.formState = "error"; + this.errorMessage = message || "Something went wrong"; } public idle() { - this.formState = 'idle'; + this.formState = "idle"; } render() { this.requiredButEmpty = []; if (!this.fields || this.fields.length === 0) { - throw new Error('Fields is required & should not be empty array'); + throw new Error("Fields is required & should not be empty array"); } - if (this.formState === 'success') { + if (this.formState === "success") { return html` ${this.renderSuccessTemplate()} `; } @@ -332,7 +340,7 @@ export default class EccUtilsDesignForm extends LitElement { this.canSubmit = true; } - return ''; + return ""; }; const { button, submitButton, form: csspartForm } = this.cssParts; @@ -341,12 +349,12 @@ export default class EccUtilsDesignForm extends LitElement { part="${csspartForm}" @submit=${(e: Event) => { e.preventDefault(); - const form = this.shadowRoot?.querySelector('form'); + const form = this.shadowRoot?.querySelector("form"); const isValid = form?.reportValidity(); if (!isValid) { return; } - const event = new CustomEvent('ecc-utils-submit', { + const event = new CustomEvent("ecc-utils-submit", { detail: { form: this.form, }, @@ -356,16 +364,16 @@ export default class EccUtilsDesignForm extends LitElement { this.dispatchEvent(event); }} > - ${this.fields.map((field) => this.renderTemplate(field, 'data'))} + ${this.fields.map((field) => this.renderTemplate(field, "data"))} ${this.renderErrorTemplate()} ${toggleButtonState()} Submit From f8fe1c32181c0bee9c11c50a1c644a75b7fe4e3e Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 21:11:47 +0100 Subject: [PATCH 12/14] Revert "feat: css variables" This reverts commit f2d2901e76b392e87b61970b62e2fdb0f99e7a95. --- .../src/components/form/form.ts | 149 ++++++++---------- 1 file changed, 70 insertions(+), 79 deletions(-) diff --git a/packages/ecc-utils-design/src/components/form/form.ts b/packages/ecc-utils-design/src/components/form/form.ts index 3da95a63..012cd85d 100644 --- a/packages/ecc-utils-design/src/components/form/form.ts +++ b/packages/ecc-utils-design/src/components/form/form.ts @@ -1,17 +1,17 @@ -import { html, LitElement, TemplateResult } from "lit"; -import { property, state } from "lit/decorators.js"; -import "@shoelace-style/shoelace/dist/components/button/button.js"; -import _ from "lodash-es"; -import getShoelaceStyles from "../../styles/shoelace.styles.js"; -import { hostStyles } from "../../styles/host.styles.js"; -import formStyles from "./form.styles.js"; -import { Field } from "./types.js"; -import inputTemplate from "./templates/inputTemplate.js"; -import arrayTemplate from "./templates/arrayTemplate.js"; -import groupTemplate from "./templates/groupTemplate.js"; -import errorTemplate from "./templates/errorTemplate.js"; -import successTemplate from "./templates/successTemplate.js"; -import switchTemplate from "./templates/switchTemplate.js"; +import { html, LitElement, TemplateResult } from 'lit'; +import { property, state } from 'lit/decorators.js'; +import '@shoelace-style/shoelace/dist/components/button/button.js'; +import _ from 'lodash-es'; +import getShoelaceStyles from '../../styles/shoelace.styles.js'; +import { hostStyles } from '../../styles/host.styles.js'; +import formStyles from './form.styles.js'; +import { Field } from './types.js'; +import inputTemplate from './templates/inputTemplate.js'; +import arrayTemplate from './templates/arrayTemplate.js'; +import groupTemplate from './templates/groupTemplate.js'; +import errorTemplate from './templates/errorTemplate.js'; +import successTemplate from './templates/successTemplate.js'; +import switchTemplate from './templates/switchTemplate.js'; /** * @summary This component is used to render a form with the given fields. @@ -27,61 +27,59 @@ import switchTemplate from "./templates/switchTemplate.js"; */ export default class EccUtilsDesignForm extends LitElement { static styles = [ - getShoelaceStyles( - document.querySelector("html")?.classList.contains("dark") - ), + getShoelaceStyles(document.querySelector('html')?.classList.contains('dark')), hostStyles, formStyles, ]; @property({ type: Array, reflect: true }) fields: Array = []; @state() private form: object = {}; - @state() private formState: "idle" | "loading" | "error" | "success" = "idle"; + @state() private formState: 'idle' | 'loading' | 'error' | 'success' = 'idle'; @state() private canSubmit = false; @state() private submitDisabledByUser = false; - @state() private errorMessage = "Something went wrong"; - @state() private successMessage = "Form submitted successfully"; + @state() private errorMessage = 'Something went wrong'; + @state() private successMessage = 'Form submitted successfully'; @state() private requiredButEmpty: string[] = []; protected cssParts = { - switchControl: "switch", - switchThumb: "switch-thumb", - switchLabel: "switch-label", - formControl: "field", - formControlLabel: "input-label", - input: "input", - inputBase: "input-base", - button: "button", - addButton: "add-button", - removeButton: "remove-button", - submitButton: "submit-button", - header: "header", - label: "label", - arrayHeader: "array-header", - arrayContainer: "array-container", - arrayLabel: "array-label", - arrayItem: "array-item", - groupBase: "group", - groupHeader: "group-header", - groupItem: "group-item", - groupLabel: "group-label", - groupToggleIcon: "group-toggle-icon", - groupContent: "group-content", - container: "container", - item: "item", - form: "form", + switchControl: 'switch', + switchThumb: 'switch-thumb', + switchLabel: 'switch-label', + formControl: 'field', + formControlLabel: 'input-label', + input: 'input', + inputBase: 'input-base', + button: 'button', + addButton: 'add-button', + removeButton: 'remove-button', + submitButton: 'submit-button', + header: 'header', + label: 'label', + arrayHeader: 'array-header', + arrayContainer: 'array-container', + arrayLabel: 'array-label', + arrayItem: 'array-item', + groupBase: 'group', + groupHeader: 'group-header', + groupItem: 'group-item', + groupLabel: 'group-label', + groupToggleIcon: 'group-toggle-icon', + groupContent: 'group-content', + container: 'container', + item: 'item', + form: 'form', }; connectedCallback() { super.connectedCallback(); if (!this.fields) { - throw new Error("Fields is required"); + throw new Error('Fields is required'); } } private renderSwitchTemplate(field: Field, path: string): TemplateResult { - if (field.type !== "switch") return html``; + if (field.type !== 'switch') return html``; if (!_.get(this.form, path) && !this.hasUpdated) { _.set(this.form, path, field.fieldOptions?.default || false); @@ -105,18 +103,13 @@ export default class EccUtilsDesignForm extends LitElement { } private renderInputTemplate(field: Field, path: string): TemplateResult { - if ( - field.type === "array" || - field.type === "switch" || - field.type === "group" - ) + if (field.type === 'array' || field.type === 'switch' || field.type === 'group') return html``; - const { formControl, formControlLabel, input, inputBase, label } = - this.cssParts; + const { formControl, formControlLabel, input, inputBase, label } = this.cssParts; const changeAction = - field.type === "file" + field.type === 'file' ? (e: Event) => { const { files } = e.target as HTMLInputElement; _.set(this.form, path, files); @@ -138,7 +131,7 @@ export default class EccUtilsDesignForm extends LitElement { if (field.fieldOptions?.default && !this.hasUpdated) { _.set(this.form, path, field.fieldOptions.default); } else if (field.fieldOptions?.returnIfEmpty) { - _.set(this.form, path, ""); + _.set(this.form, path, ''); } } }; @@ -264,9 +257,7 @@ export default class EccUtilsDesignForm extends LitElement { const renderChildren = () => html`
- ${field.children?.map((child) => - this.renderTemplate(child, `${path}`) - )} + ${field.children?.map((child) => this.renderTemplate(child, `${path}`))}
`; @@ -275,29 +266,29 @@ export default class EccUtilsDesignForm extends LitElement { private renderTemplate(field: Field, path: string): TemplateResult { const newPath = `${path}.${field.key}`; - if (field.type === "group") { + if (field.type === 'group') { return this.renderGroupTemplate(field, newPath); } - if (field.type === "array") { + if (field.type === 'array') { return this.renderArrayTemplate(field, newPath); } if (field.fieldOptions?.required && !_.get(this.form, newPath)) { this.requiredButEmpty.push(field.key); } - if (field.type === "switch") { + if (field.type === 'switch') { return this.renderSwitchTemplate(field, newPath); } return this.renderInputTemplate(field, newPath); } private renderErrorTemplate(): TemplateResult { - if (this.formState !== "error") return html``; + if (this.formState !== 'error') return html``; return errorTemplate(this.errorMessage); } private renderSuccessTemplate(): TemplateResult { - if (this.formState !== "success") return html``; + if (this.formState !== 'success') return html``; return successTemplate(this.successMessage); } @@ -307,29 +298,29 @@ export default class EccUtilsDesignForm extends LitElement { } public loading() { - this.formState = "loading"; + this.formState = 'loading'; } public success({ message }: { message?: string }) { - this.formState = "success"; - this.successMessage = message || "Form submitted successfully"; + this.formState = 'success'; + this.successMessage = message || 'Form submitted successfully'; } public error({ message }: { message?: string }) { - this.formState = "error"; - this.errorMessage = message || "Something went wrong"; + this.formState = 'error'; + this.errorMessage = message || 'Something went wrong'; } public idle() { - this.formState = "idle"; + this.formState = 'idle'; } render() { this.requiredButEmpty = []; if (!this.fields || this.fields.length === 0) { - throw new Error("Fields is required & should not be empty array"); + throw new Error('Fields is required & should not be empty array'); } - if (this.formState === "success") { + if (this.formState === 'success') { return html` ${this.renderSuccessTemplate()} `; } @@ -340,7 +331,7 @@ export default class EccUtilsDesignForm extends LitElement { this.canSubmit = true; } - return ""; + return ''; }; const { button, submitButton, form: csspartForm } = this.cssParts; @@ -349,12 +340,12 @@ export default class EccUtilsDesignForm extends LitElement { part="${csspartForm}" @submit=${(e: Event) => { e.preventDefault(); - const form = this.shadowRoot?.querySelector("form"); + const form = this.shadowRoot?.querySelector('form'); const isValid = form?.reportValidity(); if (!isValid) { return; } - const event = new CustomEvent("ecc-utils-submit", { + const event = new CustomEvent('ecc-utils-submit', { detail: { form: this.form, }, @@ -364,16 +355,16 @@ export default class EccUtilsDesignForm extends LitElement { this.dispatchEvent(event); }} > - ${this.fields.map((field) => this.renderTemplate(field, "data"))} + ${this.fields.map((field) => this.renderTemplate(field, 'data'))} ${this.renderErrorTemplate()} ${toggleButtonState()} Submit From 4cde242f8c1eed37e6e33133ac849075501df556 Mon Sep 17 00:00:00 2001 From: salihuDickson Date: Fri, 12 Jul 2024 21:15:28 +0100 Subject: [PATCH 13/14] revert lint --- .../ecc-utils-design/demo/code/index.html | 40 ++--- .../demo/collection/index.html | 2 +- .../ecc-utils-design/demo/details/index.html | 2 +- .../src/components/form/form.ts | 149 ++++++++++-------- 4 files changed, 101 insertions(+), 92 deletions(-) diff --git a/packages/ecc-utils-design/demo/code/index.html b/packages/ecc-utils-design/demo/code/index.html index d7d7ca07..425e90c9 100644 --- a/packages/ecc-utils-design/demo/code/index.html +++ b/packages/ecc-utils-design/demo/code/index.html @@ -1,24 +1,24 @@ - - - - - ecc-utils-design - - - -
-
-
- + + +
+
+
+ - + render( + html` `, + document.querySelector("#demo") + ); + + diff --git a/packages/ecc-utils-design/demo/collection/index.html b/packages/ecc-utils-design/demo/collection/index.html index 8f6d7333..123ba632 100644 --- a/packages/ecc-utils-design/demo/collection/index.html +++ b/packages/ecc-utils-design/demo/collection/index.html @@ -2,7 +2,7 @@ - +