diff --git a/package-lock.json b/package-lock.json
index aea5f140..8976e6d4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,9 @@
"@floating-ui/dom": "^0.5.4",
"@fontsource/rubik": "^4.5.9",
"@lit-labs/react": "^1.0.7",
+ "@open-wc/form-control": "^0.4.1",
+ "@open-wc/form-helpers": "^0.1.2",
+ "element-internals-polyfill": "^1.1.11",
"lit": "^2.2.3"
},
"devDependencies": {
@@ -3411,6 +3414,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@open-wc/form-control": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@open-wc/form-control/-/form-control-0.4.1.tgz",
+ "integrity": "sha512-9mUrlKgB9No56LtcOeG9sTy16r9aQsOR/9fKh3r9xtkAgaU6tK9nlI8u9z/6CHsvMeyumxuWjE5sypajVN7qBA=="
+ },
+ "node_modules/@open-wc/form-helpers": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@open-wc/form-helpers/-/form-helpers-0.1.2.tgz",
+ "integrity": "sha512-nENxFIlvk5l/jjEmWjO8xpSKQmv9HT2E1QY++/pY5GsjsTxBOYRhiG6BSyjysLBb7hBvLWfCL05qefzie6Juqw=="
+ },
"node_modules/@open-wc/scoped-elements": {
"version": "2.0.1",
"dev": true,
@@ -12889,6 +12902,11 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/element-internals-polyfill": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/element-internals-polyfill/-/element-internals-polyfill-1.1.11.tgz",
+ "integrity": "sha512-+izpja9BOt31/LK/p/sjyN5x0Vu6STkwnBju5e9X3yIARrzgOz83M9QZE0Kn42v4Z7dKHhXG4AIYPwXvkzkEyQ=="
+ },
"node_modules/element-resize-detector": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.4.tgz",
@@ -13221,22 +13239,6 @@
"esbuild-windows-arm64": "0.14.50"
}
},
- "node_modules/esbuild-darwin-arm64": {
- "version": "0.14.50",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.50.tgz",
- "integrity": "sha512-36nNs5OjKIb/Q50Sgp8+rYW/PqirRiFN0NFc9hEvgPzNJxeJedktXwzfJSln4EcRFRh5Vz4IlqFRScp+aiBBzA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/esbuild-plugin-lit-css": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/esbuild-plugin-lit-css/-/esbuild-plugin-lit-css-2.0.0.tgz",
@@ -13562,27 +13564,22 @@
}
},
"node_modules/espree": {
- "version": "9.3.3",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
- "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
+ "version": "9.3.1",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "acorn": "^8.8.0",
- "acorn-jsx": "^5.3.2",
+ "acorn": "^8.7.0",
+ "acorn-jsx": "^5.3.1",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
}
},
"node_modules/espree/node_modules/acorn": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
- "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+ "version": "8.7.0",
"dev": true,
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -26689,10 +26686,9 @@
"license": "MIT"
},
"node_modules/tslib": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
- "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
- "dev": true
+ "version": "2.3.1",
+ "dev": true,
+ "license": "0BSD"
},
"node_modules/tsscmp": {
"version": "1.0.6",
@@ -31386,6 +31382,16 @@
"version": "1.3.0",
"dev": true
},
+ "@open-wc/form-control": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@open-wc/form-control/-/form-control-0.4.1.tgz",
+ "integrity": "sha512-9mUrlKgB9No56LtcOeG9sTy16r9aQsOR/9fKh3r9xtkAgaU6tK9nlI8u9z/6CHsvMeyumxuWjE5sypajVN7qBA=="
+ },
+ "@open-wc/form-helpers": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@open-wc/form-helpers/-/form-helpers-0.1.2.tgz",
+ "integrity": "sha512-nENxFIlvk5l/jjEmWjO8xpSKQmv9HT2E1QY++/pY5GsjsTxBOYRhiG6BSyjysLBb7hBvLWfCL05qefzie6Juqw=="
+ },
"@open-wc/scoped-elements": {
"version": "2.0.1",
"dev": true,
@@ -38428,6 +38434,11 @@
"version": "1.4.144",
"dev": true
},
+ "element-internals-polyfill": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/element-internals-polyfill/-/element-internals-polyfill-1.1.11.tgz",
+ "integrity": "sha512-+izpja9BOt31/LK/p/sjyN5x0Vu6STkwnBju5e9X3yIARrzgOz83M9QZE0Kn42v4Z7dKHhXG4AIYPwXvkzkEyQ=="
+ },
"element-resize-detector": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.4.tgz",
@@ -38702,13 +38713,6 @@
"esbuild-windows-arm64": "0.14.50"
}
},
- "esbuild-darwin-arm64": {
- "version": "0.14.50",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.50.tgz",
- "integrity": "sha512-36nNs5OjKIb/Q50Sgp8+rYW/PqirRiFN0NFc9hEvgPzNJxeJedktXwzfJSln4EcRFRh5Vz4IlqFRScp+aiBBzA==",
- "dev": true,
- "optional": true
- },
"esbuild-plugin-lit-css": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/esbuild-plugin-lit-css/-/esbuild-plugin-lit-css-2.0.0.tgz",
@@ -38927,20 +38931,16 @@
"dev": true
},
"espree": {
- "version": "9.3.3",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
- "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
+ "version": "9.3.1",
"dev": true,
"requires": {
- "acorn": "^8.8.0",
- "acorn-jsx": "^5.3.2",
+ "acorn": "^8.7.0",
+ "acorn-jsx": "^5.3.1",
"eslint-visitor-keys": "^3.3.0"
},
"dependencies": {
"acorn": {
- "version": "8.8.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
- "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
+ "version": "8.7.0",
"dev": true
},
"eslint-visitor-keys": {
@@ -48629,9 +48629,7 @@
"dev": true
},
"tslib": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
- "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+ "version": "2.3.1",
"dev": true
},
"tsscmp": {
diff --git a/package.json b/package.json
index 92d36dd8..2cfd8c64 100644
--- a/package.json
+++ b/package.json
@@ -59,6 +59,9 @@
"@floating-ui/dom": "^0.5.4",
"@fontsource/rubik": "^4.5.9",
"@lit-labs/react": "^1.0.7",
+ "@open-wc/form-control": "^0.4.1",
+ "@open-wc/form-helpers": "^0.1.2",
+ "element-internals-polyfill": "^1.1.11",
"lit": "^2.2.3"
},
"engines": {
diff --git a/src/components/button/bl-button.ts b/src/components/button/bl-button.ts
index 52089e5d..8a43fdb9 100644
--- a/src/components/button/bl-button.ts
+++ b/src/components/button/bl-button.ts
@@ -72,6 +72,12 @@ export default class BlButton extends LitElement {
@property({ type: String })
target?: TargetType = '_self';
+ /**
+ * Sets the type of the button. Set `submit` to use button as the submitter of parent form.
+ */
+ @property({ type: String })
+ type: 'submit' | null;
+
/**
* Fires when button clicked
*/
diff --git a/src/components/input/bl-input.css b/src/components/input/bl-input.css
index 61abe0b1..28e1dc91 100644
--- a/src/components/input/bl-input.css
+++ b/src/components/input/bl-input.css
@@ -37,14 +37,14 @@ input:focus {
--bl-input-border-color: var(--bl-color-primary);
}
-input:focus ~ bl-icon {
- --bl-input-icon-color: var(--bl-color-primary);
-}
-
:host([label-fixed]) bl-icon {
top: calc(var(--bl-input-padding-vertical) + var(--bl-size-m));
}
+input:focus ~ bl-icon {
+ --bl-input-icon-color: var(--bl-color-primary);
+}
+
:host ::placeholder {
color: var(--bl-color-content-tertiary);
}
diff --git a/src/components/input/bl-input.stories.mdx b/src/components/input/bl-input.stories.mdx
index 3676b313..dc7b39c9 100644
--- a/src/components/input/bl-input.stories.mdx
+++ b/src/components/input/bl-input.stories.mdx
@@ -99,7 +99,7 @@ export const LabelStylesTemplate = args => html`
Input component is the component for taking text input from user.
-
${this._invalidText}
` + const invalidMessage = !this.checkValidity() + ? html`${this.validationMessage}
` : ``; const helpMessage = this.helpText ? html`${this.helpText}
` : ``; const icon = this.icon @@ -182,8 +205,8 @@ export default class BlInput extends LitElement { const classes = { 'dirty': this.dirty, - 'has-icon': this.icon || (this.dirty && this._invalidState), - 'has-value': this.hasValue, + 'has-icon': this.icon || (this.dirty && !this.checkValidity()), + 'has-value': this.value !== null && this.value !== '', }; return html` diff --git a/src/utilities/form-control.test.ts b/src/utilities/form-control.test.ts new file mode 100644 index 00000000..9287ec42 --- /dev/null +++ b/src/utilities/form-control.test.ts @@ -0,0 +1,41 @@ +import { elementUpdated, expect, fixture, fixtureCleanup } from "@open-wc/testing"; +import { html, LitElement } from "lit"; +import { customElement, query } from "lit/decorators.js"; +import { innerInputValidators } from "./form-control" + +@customElement('my-valid-input') +class MyValidInput extends LitElement { + validationTarget: HTMLInputElement; +} + + +@customElement('my-invalid-input') +class MyInvalidInput extends LitElement { + @query('input') + validationTarget: HTMLInputElement; + + render() { + return html`` + } +} + +describe('Form Control Validators', () => { + afterEach(fixtureCleanup); + + it('should return true if validationTarget is not present', async () => { + + const el = await fixture