@mfp-design-system/select 0.1.0 → 0.2.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 +9 -1
- package/dist/select.d.ts +10 -0
- package/dist/select.d.ts.map +1 -1
- package/dist/select.js +78 -45
- package/dist/select.js.map +1 -1
- package/package.json +1 -1
- package/src/select.ts +44 -0
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;
|
package/dist/select.d.ts.map
CHANGED
|
@@ -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;
|
|
@@ -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;
|
package/dist/select.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAInE,IAAI,eAAe,GAAG,CAAC,CAAC;AAExB;;;;;;;;;;;;GAYG;AAEI,IAAM,SAAS,GAAf,MAAM,SAAU,SAAQ,UAAU;
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/select.ts
CHANGED
|
@@ -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')
|