@mfp-design-system/select 0.1.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,7 +71,15 @@ mfp-select::part(chevron) {
71
71
 
72
72
  Same as the rest of the suite — Vue/Nuxt need `isCustomElement`, Angular needs `CUSTOM_ELEMENTS_SCHEMA`.
73
73
 
74
+ ## Forms
75
+
76
+ `<mfp-select>` is form-associated via `ElementInternals`:
77
+
78
+ - Its `value` is submitted with the form under the configured `name`
79
+ - `required` triggers native `valueMissing` validation
80
+ - `error` (when set) becomes a custom validity message
81
+ - `checkValidity()` and `reportValidity()` mirror the native HTMLSelectElement methods
82
+
74
83
  ## Known limitations
75
84
 
76
85
  - Single-select only. Multi-select via the native `<select multiple>` UI is uglier than most teams want — multi-select is on the roadmap as a separate component (`<mfp-multi-select>`) with a checkbox-list pattern.
77
- - Form submission via native form: the inner `<select>` is in shadow DOM, so it does not participate in native form submission yet. Listen for `change` events; full `ElementInternals` form-association is on the roadmap for all form components.
package/dist/select.d.ts CHANGED
@@ -24,6 +24,16 @@ export declare class MfpSelect extends LitElement {
24
24
  error: string;
25
25
  disabled: boolean;
26
26
  required: boolean;
27
+ static formAssociated: boolean;
28
+ private _internals;
29
+ constructor();
30
+ /** The associated <form>, if any. */
31
+ get form(): HTMLFormElement | null;
32
+ checkValidity(): boolean;
33
+ reportValidity(): boolean;
34
+ private _syncFormValue;
35
+ willUpdate(changed: Map<string, unknown>): void;
36
+ connectedCallback(): void;
27
37
  private _id;
28
38
  private _selectEl;
29
39
  private _onChange;
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,KAAK,CAAC;AAGrD,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAI5C;;;;;;;;;;;;GAYG;AACH,qBACa,SAAU,SAAQ,UAAU;IACrC,OAAgB,MAAM,0BA2HpB;IAGF,IAAI,EAAE,UAAU,CAAQ;IAGxB,KAAK,SAAM;IAGX,IAAI,SAAM;IAGV,KAAK,SAAM;IAGX,WAAW,SAAM;IAGjB,IAAI,SAAM;IAGV,KAAK,SAAM;IAGX,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAEjB,OAAO,CAAC,GAAG,CAAqC;IAGhD,OAAO,CAAC,SAAS,CAAqB;IAEtC,OAAO,CAAC,SAAS,CAUf;IAEF,8EAA8E;IAC9E,OAAO,CAAC,aAAa,CAyBnB;IAEO,MAAM;CA4DlB;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,YAAY,EAAE,SAAS,CAAC;KAC3B;CACJ"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAsB,MAAM,KAAK,CAAC;AAGrD,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAI5C;;;;;;;;;;;;GAYG;AACH,qBACa,SAAU,SAAQ,UAAU;IACrC,OAAgB,MAAM,0BA2HpB;IAGF,IAAI,EAAE,UAAU,CAAQ;IAGxB,KAAK,SAAM;IAGX,IAAI,SAAM;IAGV,KAAK,SAAM;IAGX,WAAW,SAAM;IAGjB,IAAI,SAAM;IAGV,KAAK,SAAM;IAGX,QAAQ,UAAS;IAGjB,QAAQ,UAAS;IAEjB,MAAM,CAAC,cAAc,UAAQ;IAE7B,OAAO,CAAC,UAAU,CAAmB;;IAOrC,qCAAqC;IACrC,IAAI,IAAI,IAAI,eAAe,GAAG,IAAI,CAEjC;IAED,aAAa,IAAI,OAAO;IAIxB,cAAc,IAAI,OAAO;IAIzB,OAAO,CAAC,cAAc;IAWb,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAMxC,iBAAiB;IAK1B,OAAO,CAAC,GAAG,CAAqC;IAGhD,OAAO,CAAC,SAAS,CAAqB;IAEtC,OAAO,CAAC,SAAS,CAUf;IAEF,8EAA8E;IAC9E,OAAO,CAAC,aAAa,CAyBnB;IAEO,MAAM;CA4DlB;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,YAAY,EAAE,SAAS,CAAC;KAC3B;CACJ"}
package/dist/select.js CHANGED
@@ -21,51 +21,6 @@ let selectIdCounter = 0;
21
21
  * ring, chevron) is styled via shadow CSS using design tokens.
22
22
  */
23
23
  let MfpSelect = class MfpSelect extends LitElement {
24
- constructor() {
25
- super(...arguments);
26
- this.size = 'md';
27
- this.value = '';
28
- this.name = '';
29
- this.label = '';
30
- this.placeholder = '';
31
- this.hint = '';
32
- this.error = '';
33
- this.disabled = false;
34
- this.required = false;
35
- this._id = `mfp-select-${++selectIdCounter}`;
36
- this._onChange = (e) => {
37
- const select = e.target;
38
- this.value = select.value;
39
- this.dispatchEvent(new CustomEvent('change', {
40
- bubbles: true,
41
- composed: true,
42
- detail: { value: select.value },
43
- }));
44
- };
45
- /** Move slotted <option> elements into the real <select> when they change. */
46
- this._onSlotChange = (e) => {
47
- const slot = e.target;
48
- const select = this._selectEl;
49
- if (!select)
50
- return;
51
- const currentValue = this.value;
52
- const optionLikeNodes = slot
53
- .assignedNodes({ flatten: true })
54
- .filter((n) => n.nodeType === Node.ELEMENT_NODE &&
55
- (n.tagName === 'OPTION' ||
56
- n.tagName === 'OPTGROUP'));
57
- // Replace existing real options (other than the placeholder, which lives in the template)
58
- const placeholder = select.querySelector('option[data-mfp-placeholder]');
59
- select.textContent = '';
60
- if (placeholder)
61
- select.appendChild(placeholder);
62
- for (const node of optionLikeNodes) {
63
- select.appendChild(node.cloneNode(true));
64
- }
65
- // Restore the value (reflect attribute → DOM value)
66
- select.value = currentValue;
67
- };
68
- }
69
24
  static { this.styles = css `
70
25
  :host {
71
26
  display: block;
@@ -103,7 +58,7 @@ let MfpSelect = class MfpSelect extends LitElement {
103
58
  }
104
59
 
105
60
  .control:focus-within {
106
- border-color: var(--color-status-info-solid, #2563eb);
61
+ border-color: var(--color-brand-primary, #2563eb);
107
62
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
108
63
  }
109
64
 
@@ -190,6 +145,84 @@ let MfpSelect = class MfpSelect extends LitElement {
190
145
  }
191
146
  }
192
147
  `; }
148
+ static { this.formAssociated = true; }
149
+ constructor() {
150
+ super();
151
+ this.size = 'md';
152
+ this.value = '';
153
+ this.name = '';
154
+ this.label = '';
155
+ this.placeholder = '';
156
+ this.hint = '';
157
+ this.error = '';
158
+ this.disabled = false;
159
+ this.required = false;
160
+ this._id = `mfp-select-${++selectIdCounter}`;
161
+ this._onChange = (e) => {
162
+ const select = e.target;
163
+ this.value = select.value;
164
+ this.dispatchEvent(new CustomEvent('change', {
165
+ bubbles: true,
166
+ composed: true,
167
+ detail: { value: select.value },
168
+ }));
169
+ };
170
+ /** Move slotted <option> elements into the real <select> when they change. */
171
+ this._onSlotChange = (e) => {
172
+ const slot = e.target;
173
+ const select = this._selectEl;
174
+ if (!select)
175
+ return;
176
+ const currentValue = this.value;
177
+ const optionLikeNodes = slot
178
+ .assignedNodes({ flatten: true })
179
+ .filter((n) => n.nodeType === Node.ELEMENT_NODE &&
180
+ (n.tagName === 'OPTION' ||
181
+ n.tagName === 'OPTGROUP'));
182
+ // Replace existing real options (other than the placeholder, which lives in the template)
183
+ const placeholder = select.querySelector('option[data-mfp-placeholder]');
184
+ select.textContent = '';
185
+ if (placeholder)
186
+ select.appendChild(placeholder);
187
+ for (const node of optionLikeNodes) {
188
+ select.appendChild(node.cloneNode(true));
189
+ }
190
+ // Restore the value (reflect attribute → DOM value)
191
+ select.value = currentValue;
192
+ };
193
+ this._internals = this.attachInternals();
194
+ }
195
+ /** The associated <form>, if any. */
196
+ get form() {
197
+ return this._internals.form;
198
+ }
199
+ checkValidity() {
200
+ return this._internals.checkValidity();
201
+ }
202
+ reportValidity() {
203
+ return this._internals.reportValidity();
204
+ }
205
+ _syncFormValue() {
206
+ this._internals.setFormValue(this.value);
207
+ if (this.error) {
208
+ this._internals.setValidity({ customError: true }, this.error);
209
+ }
210
+ else if (this.required && !this.value) {
211
+ this._internals.setValidity({ valueMissing: true }, 'Please select an option.');
212
+ }
213
+ else {
214
+ this._internals.setValidity({});
215
+ }
216
+ }
217
+ willUpdate(changed) {
218
+ if (changed.has('value') || changed.has('required') || changed.has('error')) {
219
+ this._syncFormValue();
220
+ }
221
+ }
222
+ connectedCallback() {
223
+ super.connectedCallback();
224
+ this._syncFormValue();
225
+ }
193
226
  render() {
194
227
  const invalid = this.error.length > 0;
195
228
  const inputId = this._id;
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mfp-design-system/select",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "Select dropdown web component for the mfp-design-system, built with Lit.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,7 +24,7 @@
24
24
  "lit": "^3.2.1"
25
25
  },
26
26
  "peerDependencies": {
27
- "@mfp-design-system/tokens": "^0.2.0"
27
+ "@mfp-design-system/tokens": "^0.3.0"
28
28
  },
29
29
  "peerDependenciesMeta": {
30
30
  "@mfp-design-system/tokens": {
@@ -34,7 +34,7 @@
34
34
  "devDependencies": {
35
35
  "rimraf": "^6.0.1",
36
36
  "typescript": "^5.6.3",
37
- "@mfp-design-system/tokens": "0.2.0"
37
+ "@mfp-design-system/tokens": "0.3.0"
38
38
  },
39
39
  "publishConfig": {
40
40
  "access": "public"
package/src/select.ts CHANGED
@@ -57,7 +57,7 @@ export class MfpSelect extends LitElement {
57
57
  }
58
58
 
59
59
  .control:focus-within {
60
- border-color: var(--color-status-info-solid, #2563eb);
60
+ border-color: var(--color-brand-primary, #2563eb);
61
61
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
62
62
  }
63
63
 
@@ -172,6 +172,50 @@ export class MfpSelect extends LitElement {
172
172
  @property({ type: Boolean, reflect: true })
173
173
  required = false;
174
174
 
175
+ static formAssociated = true;
176
+
177
+ private _internals: ElementInternals;
178
+
179
+ constructor() {
180
+ super();
181
+ this._internals = this.attachInternals();
182
+ }
183
+
184
+ /** The associated <form>, if any. */
185
+ get form(): HTMLFormElement | null {
186
+ return this._internals.form;
187
+ }
188
+
189
+ checkValidity(): boolean {
190
+ return this._internals.checkValidity();
191
+ }
192
+
193
+ reportValidity(): boolean {
194
+ return this._internals.reportValidity();
195
+ }
196
+
197
+ private _syncFormValue() {
198
+ this._internals.setFormValue(this.value);
199
+ if (this.error) {
200
+ this._internals.setValidity({ customError: true }, this.error);
201
+ } else if (this.required && !this.value) {
202
+ this._internals.setValidity({ valueMissing: true }, 'Please select an option.');
203
+ } else {
204
+ this._internals.setValidity({});
205
+ }
206
+ }
207
+
208
+ override willUpdate(changed: Map<string, unknown>) {
209
+ if (changed.has('value') || changed.has('required') || changed.has('error')) {
210
+ this._syncFormValue();
211
+ }
212
+ }
213
+
214
+ override connectedCallback() {
215
+ super.connectedCallback();
216
+ this._syncFormValue();
217
+ }
218
+
175
219
  private _id = `mfp-select-${++selectIdCounter}`;
176
220
 
177
221
  @query('select')