@justeattakeaway/pie-select 0.6.11 → 0.7.1
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 +20 -8
- package/custom-elements.json +17 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.js +89 -71
- package/dist/react.d.ts +9 -2
- package/package.json +2 -2
- package/src/defs.ts +8 -2
- package/src/index.ts +69 -21
package/README.md
CHANGED
|
@@ -34,10 +34,11 @@ Ideally, you should install the component using the **`@justeattakeaway/pie-webc
|
|
|
34
34
|
|----------------|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|
|
|
35
35
|
| `size` | `"small"`, `"medium"`, `"large"` | The size of the select component. | `medium` |
|
|
36
36
|
| `disabled` | `boolean` | Whether the select is disabled. | `false` |
|
|
37
|
-
| `assistiveText`| `string` | An optional assistive text to display below the select element. Must be provided when the status is `error`.
|
|
37
|
+
| `assistiveText`| `string` | An optional assistive text to display below the select element. Must be provided when the status is `error`. | `undefined` |
|
|
38
38
|
| `status` | `"default"`, `"error"` | The status of the select component / assistive text. | `default` |
|
|
39
|
-
| `name` | `string` | The name of the select (used as a key/value pair with `value`). This is required in order to work properly with forms.
|
|
40
|
-
| `options` | `array` | The options to display in the select. Can be an array of option objects or option group objects. See [Using the options prop](#using-the-options-prop) for more details.
|
|
39
|
+
| `name` | `string` | The name of the select (used as a key/value pair with `value`). This is required in order to work properly with forms. | `undefined` |
|
|
40
|
+
| `options` | `array` | The options to display in the select. Can be an array of option objects or option group objects. See [Using the options prop](#using-the-options-prop) for more details. | `[]` |
|
|
41
|
+
| `value` | `string` | The programatically set value of the select. It overrides any option set as selected. | `` |
|
|
41
42
|
|
|
42
43
|
#### Using the options prop
|
|
43
44
|
The `options` prop accepts an array of option objects or option group objects:
|
|
@@ -88,14 +89,21 @@ import '@justeattakeaway/pie-icons-webc/dist/IconPlaceholder.js';
|
|
|
88
89
|
```html
|
|
89
90
|
<pie-select
|
|
90
91
|
name="my-select"
|
|
91
|
-
|
|
92
|
-
{ tag: 'option', text: 'Select an option' },
|
|
93
|
-
{ tag: 'option', text: 'Option 1', value: 'option1' }
|
|
94
|
-
]">
|
|
92
|
+
value="option2">
|
|
95
93
|
<icon-placeholder slot="leadingIcon"></icon-placeholder>
|
|
96
94
|
</pie-select>
|
|
97
95
|
```
|
|
98
96
|
|
|
97
|
+
```js
|
|
98
|
+
// Set options programmatically
|
|
99
|
+
const select = document.querySelector('pie-select');
|
|
100
|
+
select.options = [
|
|
101
|
+
{ tag: 'option', text: 'Select an option' },
|
|
102
|
+
{ tag: 'option', text: 'Option 1', value: 'option1' },
|
|
103
|
+
{ tag: 'option', text: 'Option 2', value: 'option2' }
|
|
104
|
+
];
|
|
105
|
+
```
|
|
106
|
+
|
|
99
107
|
**For Native JS Applications, Vue, Angular, Svelte, etc.:**
|
|
100
108
|
|
|
101
109
|
```js
|
|
@@ -105,9 +113,11 @@ import '@justeattakeaway/pie-icons-webc/dist/IconPlaceholder.js';
|
|
|
105
113
|
|
|
106
114
|
<pie-select
|
|
107
115
|
name="my-select"
|
|
116
|
+
value="option2"
|
|
108
117
|
:options="[
|
|
109
118
|
{ tag: 'option', text: 'Select an option' },
|
|
110
119
|
{ tag: 'option', text: 'Option 1', value: 'option1' }
|
|
120
|
+
{ tag: 'option', text: 'Option 2', value: 'option2' }
|
|
111
121
|
]">
|
|
112
122
|
<icon-placeholder slot="leadingIcon"></icon-placeholder>
|
|
113
123
|
</pie-select>
|
|
@@ -120,9 +130,11 @@ import { IconPlaceholder } from '@justeattakeaway/pie-icons-webc/dist/react/Icon
|
|
|
120
130
|
|
|
121
131
|
<PieSelect
|
|
122
132
|
name="my-select"
|
|
133
|
+
value="option2"
|
|
123
134
|
options={[
|
|
124
135
|
{ tag: 'option', text: 'Select an option' },
|
|
125
|
-
{ tag: 'option', text: 'Option 1', value: 'option1' }
|
|
136
|
+
{ tag: 'option', text: 'Option 1', value: 'option1' },
|
|
137
|
+
{ tag: 'option', text: 'Option 2', value: 'option2' },
|
|
126
138
|
]}>
|
|
127
139
|
<IconPlaceholder slot="leadingIcon"></IconPlaceholder>
|
|
128
140
|
</PieSelect>
|
package/custom-elements.json
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"type": {
|
|
35
35
|
"text": "DefaultProps"
|
|
36
36
|
},
|
|
37
|
-
"default": "{\n size: 'medium',\n status: 'default',\n disabled: false,\n options: [],\n}"
|
|
37
|
+
"default": "{\n size: 'medium',\n status: 'default',\n disabled: false,\n options: [],\n value: '',\n}"
|
|
38
38
|
}
|
|
39
39
|
],
|
|
40
40
|
"exports": [
|
|
@@ -121,6 +121,14 @@
|
|
|
121
121
|
},
|
|
122
122
|
"privacy": "public"
|
|
123
123
|
},
|
|
124
|
+
{
|
|
125
|
+
"kind": "field",
|
|
126
|
+
"name": "_value",
|
|
127
|
+
"type": {
|
|
128
|
+
"text": "SelectProps['value']"
|
|
129
|
+
},
|
|
130
|
+
"privacy": "private"
|
|
131
|
+
},
|
|
124
132
|
{
|
|
125
133
|
"kind": "field",
|
|
126
134
|
"name": "focusTarget",
|
|
@@ -154,6 +162,14 @@
|
|
|
154
162
|
"privacy": "private",
|
|
155
163
|
"default": "false"
|
|
156
164
|
},
|
|
165
|
+
{
|
|
166
|
+
"kind": "field",
|
|
167
|
+
"name": "value",
|
|
168
|
+
"type": {
|
|
169
|
+
"text": "SelectProps['value']"
|
|
170
|
+
},
|
|
171
|
+
"privacy": "public"
|
|
172
|
+
},
|
|
157
173
|
{
|
|
158
174
|
"kind": "field",
|
|
159
175
|
"name": "validity",
|
package/dist/index.d.ts
CHANGED
|
@@ -27,11 +27,14 @@ export declare class PieSelect extends PieSelect_base implements SelectProps {
|
|
|
27
27
|
assistiveText: SelectProps['assistiveText'];
|
|
28
28
|
name: SelectProps['name'];
|
|
29
29
|
options: SelectProps['options'];
|
|
30
|
+
private _value;
|
|
30
31
|
focusTarget: HTMLSelectElement;
|
|
31
32
|
private _select;
|
|
32
33
|
private _leadingIconSlot;
|
|
33
34
|
private _hasLeadingIcon;
|
|
34
35
|
protected firstUpdated(): void;
|
|
36
|
+
get value(): SelectProps['value'];
|
|
37
|
+
set value(newValue: SelectProps['value']);
|
|
35
38
|
/**
|
|
36
39
|
* (Read-only) returns a ValidityState with the validity states that this element is in.
|
|
37
40
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/validity
|
|
@@ -72,7 +75,7 @@ export declare class PieSelect extends PieSelect_base implements SelectProps {
|
|
|
72
75
|
|
|
73
76
|
declare const PieSelect_base: GenericConstructor<FormControlInterface> & GenericConstructor<RTLInterface> & typeof PieElement;
|
|
74
77
|
|
|
75
|
-
declare interface SelectOptionGroupProps {
|
|
78
|
+
export declare interface SelectOptionGroupProps {
|
|
76
79
|
/**
|
|
77
80
|
* What HTML element the option should be such option or optgroup.
|
|
78
81
|
*/
|
|
@@ -91,7 +94,7 @@ declare interface SelectOptionGroupProps {
|
|
|
91
94
|
disabled?: boolean;
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
declare interface SelectOptionProps {
|
|
97
|
+
export declare interface SelectOptionProps {
|
|
95
98
|
/**
|
|
96
99
|
* What HTML element the option should be such option or optgroup.
|
|
97
100
|
*/
|
|
@@ -139,6 +142,10 @@ export declare interface SelectProps {
|
|
|
139
142
|
* The options to display in the select. Can be an array of option objects or option group objects.
|
|
140
143
|
*/
|
|
141
144
|
options: (SelectOptionProps | SelectOptionGroupProps)[];
|
|
145
|
+
/**
|
|
146
|
+
* The value of the selected option
|
|
147
|
+
*/
|
|
148
|
+
value?: string | number;
|
|
142
149
|
}
|
|
143
150
|
|
|
144
151
|
export declare const sizes: readonly ["small", "medium", "large"];
|
package/dist/index.js
CHANGED
|
@@ -1,40 +1,50 @@
|
|
|
1
1
|
import { LitElement as b, html as p, nothing as _, unsafeCSS as $ } from "lit";
|
|
2
2
|
import { FormControlMixin as I, RtlMixin as w, wrapNativeEvent as z, validPropertyValues as f, safeCustomElement as k } from "@justeattakeaway/pie-webc-core";
|
|
3
|
-
import { property as
|
|
4
|
-
import { ifDefined as
|
|
5
|
-
import { classMap as
|
|
6
|
-
import { live as
|
|
3
|
+
import { property as n, query as m, queryAssignedElements as S, state as C } from "lit/decorators.js";
|
|
4
|
+
import { ifDefined as u } from "lit/directives/if-defined.js";
|
|
5
|
+
import { classMap as V } from "lit/directives/class-map.js";
|
|
6
|
+
import { live as L } from "lit/directives/live.js";
|
|
7
7
|
import "@justeattakeaway/pie-icons-webc/dist/IconChevronDown.js";
|
|
8
8
|
import "@justeattakeaway/pie-assistive-text";
|
|
9
|
-
const
|
|
9
|
+
const h = class h extends b {
|
|
10
10
|
willUpdate() {
|
|
11
|
-
this.getAttribute("v") || this.setAttribute("v",
|
|
11
|
+
this.getAttribute("v") || this.setAttribute("v", h.v);
|
|
12
12
|
}
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
let g =
|
|
16
|
-
const
|
|
14
|
+
h.v = "0.7.1";
|
|
15
|
+
let g = h;
|
|
16
|
+
const T = "*,*:after,*:before{box-sizing:inherit}:host{display:block}.c-select{--select-padding-block: var(--dt-spacing-c);--select-padding-inline-start: var(--dt-spacing-d);--select-padding-inline-end: 52px;--select-background-color: var(--dt-color-container-default);--select-text-color: var(--dt-color-content-default);--select-border-color: var(--dt-color-border-form);--select-font-size: calc(var(--dt-font-body-l-size) * 1px);--select-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--select-height: 48px;--select-cursor: pointer;position:relative;color:var(--select-text-color);font-size:var(--select-font-size);line-height:var(--select-line-height)}.c-select select{height:var(--select-height);width:100%;border:1px solid var(--select-border-color);border-radius:var(--dt-radius-rounded-c);padding-inline-start:var(--select-padding-inline-start);padding-inline-end:var(--select-padding-inline-end);padding-block-start:var(--select-padding-block);padding-block-end:var(--select-padding-block);background-color:var(--select-background-color);font-family:inherit;font-size:inherit;line-height:inherit;color:inherit;outline:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:var(--select-cursor);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.c-select select:focus-within{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}.c-select.c-select--small{--select-padding-block: var(--dt-spacing-b);--select-height: 40px}.c-select.c-select--large{--select-padding-block: var(--dt-spacing-d);--select-height: 56px}.c-select.c-select--error{--select-border-color: var(--dt-color-support-error)}.c-select.c-select--withLeadingIcon{--select-padding-inline-start: calc(var(--dt-spacing-h) - var(--dt-spacing-a))}.c-select ::slotted([slot=leadingIcon]),.c-select .c-select-trailingIcon{position:absolute;top:50%;transform:translateY(-50%);pointer-events:none}.c-select:not(.is-disabled) ::slotted([slot=leadingIcon]),.c-select:not(.is-disabled) .c-select-trailingIcon{color:var(--dt-color-content-subdued)}.c-select ::slotted([slot=leadingIcon]){--icon-display-override: block;--icon-size-override: 24px;inset-inline-start:var(--dt-spacing-d)}.c-select .c-select-trailingIcon{inset-inline-end:var(--dt-spacing-d)}@media (hover: hover){.c-select:hover{--select-background-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) + calc(-1 * var(--dt-color-hover-01))))}@supports (background-color: color-mix(in srgb,black,white)){.c-select:hover{--select-background-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-container-default))}}}.c-select.is-disabled{--select-background-color: var(--dt-color-disabled-01);--select-border-color: var(--dt-color-disabled-01);--select-text-color: var(--dt-color-content-disabled);--select-cursor: auto}", O = ["small", "medium", "large"], A = ["default", "error"], c = {
|
|
17
17
|
size: "medium",
|
|
18
18
|
status: "default",
|
|
19
19
|
disabled: !1,
|
|
20
|
-
options: []
|
|
20
|
+
options: [],
|
|
21
|
+
value: ""
|
|
21
22
|
};
|
|
22
|
-
var
|
|
23
|
-
for (var
|
|
24
|
-
(d = t[
|
|
25
|
-
return
|
|
23
|
+
var F = Object.defineProperty, P = Object.getOwnPropertyDescriptor, o = (t, e, r, i) => {
|
|
24
|
+
for (var s = i > 1 ? void 0 : i ? P(e, r) : e, a = t.length - 1, d; a >= 0; a--)
|
|
25
|
+
(d = t[a]) && (s = (i ? d(e, r, s) : d(s)) || s);
|
|
26
|
+
return i && s && F(e, r, s), s;
|
|
26
27
|
};
|
|
27
|
-
const x = "pie-select",
|
|
28
|
-
let
|
|
28
|
+
const x = "pie-select", v = "assistive-text";
|
|
29
|
+
let l = class extends I(w(g)) {
|
|
29
30
|
constructor() {
|
|
30
|
-
super(...arguments), this.size =
|
|
31
|
-
const e =
|
|
32
|
-
this.
|
|
31
|
+
super(...arguments), this.size = c.size, this.disabled = c.disabled, this.status = c.status, this.options = c.options, this._value = c.value, this._hasLeadingIcon = !1, this._handleChange = (t) => {
|
|
32
|
+
const { value: e } = this._select;
|
|
33
|
+
this._value = e, this._internals.setFormValue(e);
|
|
34
|
+
const r = z(t);
|
|
35
|
+
this.dispatchEvent(r);
|
|
33
36
|
};
|
|
34
37
|
}
|
|
35
38
|
firstUpdated() {
|
|
36
39
|
this._internals.setFormValue(this._select.value);
|
|
37
40
|
}
|
|
41
|
+
get value() {
|
|
42
|
+
return this._value === "" ? this._select ? this._select.value : "" : this._value;
|
|
43
|
+
}
|
|
44
|
+
set value(t) {
|
|
45
|
+
const e = t ? String(t) : "";
|
|
46
|
+
this._internals.setFormValue(e), this._value = e, this.requestUpdate();
|
|
47
|
+
}
|
|
38
48
|
/**
|
|
39
49
|
* (Read-only) returns a ValidityState with the validity states that this element is in.
|
|
40
50
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/validity
|
|
@@ -56,8 +66,8 @@ let s = class extends I(w(g)) {
|
|
|
56
66
|
* Resets the value to the default select value.
|
|
57
67
|
*/
|
|
58
68
|
formResetCallback() {
|
|
59
|
-
const t = this.
|
|
60
|
-
this._select.value =
|
|
69
|
+
const t = this.options.reduce((s, a) => a.tag === "optgroup" ? s.concat(a.options) : (s.push(a), s), []), e = t.length > 0 ? t[0].value : "", r = t.find((s) => s.selected === !0), i = r ? r.value : e;
|
|
70
|
+
this._select.value = i || "", this._internals.setFormValue(i || null), this._value = i || "", this.requestUpdate();
|
|
61
71
|
}
|
|
62
72
|
_handleLeadingIconSlotchange() {
|
|
63
73
|
this._hasLeadingIcon = !!this._leadingIconSlot.length;
|
|
@@ -69,21 +79,26 @@ let s = class extends I(w(g)) {
|
|
|
69
79
|
*/
|
|
70
80
|
renderChildren(t) {
|
|
71
81
|
return p`
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
${t.map((e) => {
|
|
83
|
+
if (e.tag === "optgroup")
|
|
84
|
+
return p`
|
|
85
|
+
<optgroup
|
|
86
|
+
?disabled="${e.disabled}"
|
|
87
|
+
label="${u(e.label)}">
|
|
88
|
+
${this.renderChildren(e.options)}
|
|
89
|
+
</optgroup>
|
|
90
|
+
`;
|
|
91
|
+
const i = this._value !== "" ? this._value === e.value : e.selected;
|
|
92
|
+
return p`
|
|
93
|
+
<option
|
|
94
|
+
.value="${L(e.value || "")}"
|
|
95
|
+
?disabled="${e.disabled}"
|
|
96
|
+
?selected="${i}">
|
|
97
|
+
${e.text}
|
|
98
|
+
</option>
|
|
86
99
|
`;
|
|
100
|
+
})}
|
|
101
|
+
`;
|
|
87
102
|
}
|
|
88
103
|
/**
|
|
89
104
|
* Renders the assistive text if available.
|
|
@@ -92,8 +107,8 @@ let s = class extends I(w(g)) {
|
|
|
92
107
|
renderAssistiveText() {
|
|
93
108
|
return this.assistiveText ? p`
|
|
94
109
|
<pie-assistive-text
|
|
95
|
-
id="${
|
|
96
|
-
variant="${
|
|
110
|
+
id="${v}"
|
|
111
|
+
variant="${u(this.status)}"
|
|
97
112
|
data-test-id="pie-select-assistive-text">
|
|
98
113
|
${this.assistiveText}
|
|
99
114
|
</pie-assistive-text>
|
|
@@ -104,31 +119,31 @@ let s = class extends I(w(g)) {
|
|
|
104
119
|
assistiveText: t,
|
|
105
120
|
disabled: e,
|
|
106
121
|
status: r,
|
|
107
|
-
size:
|
|
108
|
-
name:
|
|
109
|
-
options:
|
|
122
|
+
size: i,
|
|
123
|
+
name: s,
|
|
124
|
+
options: a,
|
|
110
125
|
_hasLeadingIcon: d
|
|
111
126
|
} = this, y = {
|
|
112
127
|
"c-select": !0,
|
|
113
|
-
[`c-select--${
|
|
128
|
+
[`c-select--${i}`]: !0,
|
|
114
129
|
[`c-select--${r}`]: !0,
|
|
115
130
|
"c-select--withLeadingIcon": d,
|
|
116
131
|
"is-disabled": e
|
|
117
132
|
};
|
|
118
133
|
return p`
|
|
119
134
|
<div
|
|
120
|
-
class="${
|
|
135
|
+
class="${V(y)}"
|
|
121
136
|
data-test-id="pie-select-shell">
|
|
122
137
|
<slot name="leadingIcon" @slotchange=${this._handleLeadingIconSlotchange}></slot>
|
|
123
138
|
<select
|
|
124
139
|
data-test-id="pie-select-element"
|
|
125
|
-
name="${
|
|
140
|
+
name="${u(s)}"
|
|
126
141
|
?disabled="${e}"
|
|
127
|
-
aria-describedby="${
|
|
142
|
+
aria-describedby="${u(t ? v : void 0)}"
|
|
128
143
|
aria-invalid="${r === "error" ? "true" : "false"}"
|
|
129
|
-
aria-errormessage="${
|
|
144
|
+
aria-errormessage="${u(r === "error" ? v : void 0)}"
|
|
130
145
|
@change=${this._handleChange}>
|
|
131
|
-
${this.renderChildren(
|
|
146
|
+
${this.renderChildren(a)}
|
|
132
147
|
</select>
|
|
133
148
|
<icon-chevron-down size='s' class='c-select-trailingIcon'></icon-chevron-down>
|
|
134
149
|
</div>
|
|
@@ -136,46 +151,49 @@ let s = class extends I(w(g)) {
|
|
|
136
151
|
`;
|
|
137
152
|
}
|
|
138
153
|
};
|
|
139
|
-
|
|
140
|
-
|
|
154
|
+
l.shadowRootOptions = { ...b.shadowRootOptions, delegatesFocus: !0 };
|
|
155
|
+
l.styles = $(T);
|
|
141
156
|
o([
|
|
142
|
-
|
|
143
|
-
f(x, O,
|
|
144
|
-
],
|
|
157
|
+
n({ type: String }),
|
|
158
|
+
f(x, O, c.size)
|
|
159
|
+
], l.prototype, "size", 2);
|
|
145
160
|
o([
|
|
146
|
-
|
|
147
|
-
],
|
|
161
|
+
n({ type: Boolean })
|
|
162
|
+
], l.prototype, "disabled", 2);
|
|
148
163
|
o([
|
|
149
|
-
|
|
150
|
-
f(x,
|
|
151
|
-
],
|
|
164
|
+
n({ type: String }),
|
|
165
|
+
f(x, A, c.status)
|
|
166
|
+
], l.prototype, "status", 2);
|
|
152
167
|
o([
|
|
153
|
-
|
|
154
|
-
],
|
|
168
|
+
n({ type: String })
|
|
169
|
+
], l.prototype, "assistiveText", 2);
|
|
155
170
|
o([
|
|
156
|
-
|
|
157
|
-
],
|
|
171
|
+
n({ type: String, reflect: !0 })
|
|
172
|
+
], l.prototype, "name", 2);
|
|
158
173
|
o([
|
|
159
|
-
|
|
160
|
-
],
|
|
174
|
+
n({ type: Array })
|
|
175
|
+
], l.prototype, "options", 2);
|
|
161
176
|
o([
|
|
162
177
|
m("select")
|
|
163
|
-
],
|
|
178
|
+
], l.prototype, "focusTarget", 2);
|
|
164
179
|
o([
|
|
165
180
|
m("select")
|
|
166
|
-
],
|
|
181
|
+
], l.prototype, "_select", 2);
|
|
167
182
|
o([
|
|
168
183
|
S({ slot: "leadingIcon", flatten: !0 })
|
|
169
|
-
],
|
|
184
|
+
], l.prototype, "_leadingIconSlot", 2);
|
|
170
185
|
o([
|
|
171
186
|
C()
|
|
172
|
-
],
|
|
173
|
-
|
|
187
|
+
], l.prototype, "_hasLeadingIcon", 2);
|
|
188
|
+
o([
|
|
189
|
+
n()
|
|
190
|
+
], l.prototype, "value", 1);
|
|
191
|
+
l = o([
|
|
174
192
|
k("pie-select")
|
|
175
|
-
],
|
|
193
|
+
], l);
|
|
176
194
|
export {
|
|
177
|
-
|
|
178
|
-
|
|
195
|
+
l as PieSelect,
|
|
196
|
+
c as defaultProps,
|
|
179
197
|
O as sizes,
|
|
180
|
-
|
|
198
|
+
A as statusTypes
|
|
181
199
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -30,11 +30,14 @@ declare class PieSelect_2 extends PieSelect_base implements SelectProps {
|
|
|
30
30
|
assistiveText: SelectProps['assistiveText'];
|
|
31
31
|
name: SelectProps['name'];
|
|
32
32
|
options: SelectProps['options'];
|
|
33
|
+
private _value;
|
|
33
34
|
focusTarget: HTMLSelectElement;
|
|
34
35
|
private _select;
|
|
35
36
|
private _leadingIconSlot;
|
|
36
37
|
private _hasLeadingIcon;
|
|
37
38
|
protected firstUpdated(): void;
|
|
39
|
+
get value(): SelectProps['value'];
|
|
40
|
+
set value(newValue: SelectProps['value']);
|
|
38
41
|
/**
|
|
39
42
|
* (Read-only) returns a ValidityState with the validity states that this element is in.
|
|
40
43
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/validity
|
|
@@ -81,7 +84,7 @@ declare type PieSelectEvents = {
|
|
|
81
84
|
|
|
82
85
|
declare type ReactBaseType = Omit<React_2.HTMLAttributes<HTMLSelectElement>, 'onChange'>;
|
|
83
86
|
|
|
84
|
-
declare interface SelectOptionGroupProps {
|
|
87
|
+
export declare interface SelectOptionGroupProps {
|
|
85
88
|
/**
|
|
86
89
|
* What HTML element the option should be such option or optgroup.
|
|
87
90
|
*/
|
|
@@ -100,7 +103,7 @@ declare interface SelectOptionGroupProps {
|
|
|
100
103
|
disabled?: boolean;
|
|
101
104
|
}
|
|
102
105
|
|
|
103
|
-
declare interface SelectOptionProps {
|
|
106
|
+
export declare interface SelectOptionProps {
|
|
104
107
|
/**
|
|
105
108
|
* What HTML element the option should be such option or optgroup.
|
|
106
109
|
*/
|
|
@@ -148,6 +151,10 @@ export declare interface SelectProps {
|
|
|
148
151
|
* The options to display in the select. Can be an array of option objects or option group objects.
|
|
149
152
|
*/
|
|
150
153
|
options: (SelectOptionProps | SelectOptionGroupProps)[];
|
|
154
|
+
/**
|
|
155
|
+
* The value of the selected option
|
|
156
|
+
*/
|
|
157
|
+
value?: string | number;
|
|
151
158
|
}
|
|
152
159
|
|
|
153
160
|
export declare const sizes: readonly ["small", "medium", "large"];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justeattakeaway/pie-select",
|
|
3
3
|
"description": "PIE Design System Select built using Web Components",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.7.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/justeattakeaway/pie",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@custom-elements-manifest/analyzer": "0.9.0",
|
|
42
42
|
"@justeattakeaway/pie-components-config": "0.21.0",
|
|
43
|
-
"@justeattakeaway/pie-css": "0.
|
|
43
|
+
"@justeattakeaway/pie-css": "0.21.0",
|
|
44
44
|
"@justeattakeaway/pie-monorepo-utils": "0.7.0",
|
|
45
45
|
"cem-plugin-module-file-extensions": "0.0.5"
|
|
46
46
|
},
|
package/src/defs.ts
CHANGED
|
@@ -4,7 +4,7 @@ export const sizes = ['small', 'medium', 'large'] as const;
|
|
|
4
4
|
|
|
5
5
|
export const statusTypes = ['default', 'error'] as const;
|
|
6
6
|
|
|
7
|
-
interface SelectOptionProps {
|
|
7
|
+
export interface SelectOptionProps {
|
|
8
8
|
/**
|
|
9
9
|
* What HTML element the option should be such option or optgroup.
|
|
10
10
|
*/
|
|
@@ -31,7 +31,7 @@ interface SelectOptionProps {
|
|
|
31
31
|
selected?: boolean;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
interface SelectOptionGroupProps {
|
|
34
|
+
export interface SelectOptionGroupProps {
|
|
35
35
|
/**
|
|
36
36
|
* What HTML element the option should be such option or optgroup.
|
|
37
37
|
*/
|
|
@@ -83,6 +83,11 @@ export interface SelectProps {
|
|
|
83
83
|
* The options to display in the select. Can be an array of option objects or option group objects.
|
|
84
84
|
*/
|
|
85
85
|
options: (SelectOptionProps | SelectOptionGroupProps)[];
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The value of the selected option
|
|
89
|
+
*/
|
|
90
|
+
value?: string | number;
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
type DefaultProps = ComponentDefaultProps<SelectProps, keyof Omit<SelectProps, 'name' | 'assistiveText'>>;
|
|
@@ -92,4 +97,5 @@ export const defaultProps: DefaultProps = {
|
|
|
92
97
|
status: 'default',
|
|
93
98
|
disabled: false,
|
|
94
99
|
options: [],
|
|
100
|
+
value: '',
|
|
95
101
|
};
|
package/src/index.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
sizes,
|
|
32
32
|
statusTypes,
|
|
33
33
|
type SelectProps,
|
|
34
|
+
type SelectOptionProps,
|
|
34
35
|
} from './defs';
|
|
35
36
|
|
|
36
37
|
// Valid values available to consumers
|
|
@@ -67,6 +68,8 @@ export class PieSelect extends FormControlMixin(RtlMixin(PieElement)) implements
|
|
|
67
68
|
@property({ type: Array })
|
|
68
69
|
public options: SelectProps['options'] = defaultProps.options;
|
|
69
70
|
|
|
71
|
+
private _value: SelectProps['value'] = defaultProps.value;
|
|
72
|
+
|
|
70
73
|
@query('select')
|
|
71
74
|
public focusTarget!: HTMLSelectElement;
|
|
72
75
|
|
|
@@ -83,6 +86,29 @@ export class PieSelect extends FormControlMixin(RtlMixin(PieElement)) implements
|
|
|
83
86
|
this._internals.setFormValue(this._select.value);
|
|
84
87
|
}
|
|
85
88
|
|
|
89
|
+
@property()
|
|
90
|
+
public get value (): SelectProps['value'] {
|
|
91
|
+
// If no value was assigned
|
|
92
|
+
// and the select element is available
|
|
93
|
+
// return its value as by default it will pick the first available option
|
|
94
|
+
if (this._value === '') {
|
|
95
|
+
if (!this._select) {
|
|
96
|
+
return '';
|
|
97
|
+
}
|
|
98
|
+
return this._select.value;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return this._value;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public set value (newValue: SelectProps['value']) {
|
|
105
|
+
const safeNewValue = newValue ? String(newValue) : '';
|
|
106
|
+
this._internals.setFormValue(safeNewValue);
|
|
107
|
+
this._value = safeNewValue;
|
|
108
|
+
|
|
109
|
+
this.requestUpdate();
|
|
110
|
+
}
|
|
111
|
+
|
|
86
112
|
/**
|
|
87
113
|
* (Read-only) returns a ValidityState with the validity states that this element is in.
|
|
88
114
|
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/validity
|
|
@@ -106,10 +132,26 @@ export class PieSelect extends FormControlMixin(RtlMixin(PieElement)) implements
|
|
|
106
132
|
* Resets the value to the default select value.
|
|
107
133
|
*/
|
|
108
134
|
public formResetCallback (): void {
|
|
109
|
-
|
|
110
|
-
this.
|
|
111
|
-
|
|
112
|
-
|
|
135
|
+
// Flatten a possibly nested options list into a flat one
|
|
136
|
+
const flatOptions: SelectOptionProps[] = this.options.reduce<SelectOptionProps[]>((acc, option) => {
|
|
137
|
+
if (option.tag === 'optgroup') {
|
|
138
|
+
return acc.concat(option.options);
|
|
139
|
+
}
|
|
140
|
+
acc.push(option);
|
|
141
|
+
return acc;
|
|
142
|
+
}, []);
|
|
143
|
+
|
|
144
|
+
// Infer the value to reset to
|
|
145
|
+
const firstValue = flatOptions.length > 0 ? flatOptions[0].value : '';
|
|
146
|
+
const selectedValue = flatOptions.find((option) => option.selected === true);
|
|
147
|
+
const resetValue = selectedValue ? selectedValue.value : firstValue;
|
|
148
|
+
|
|
149
|
+
// Perform the necessary updates
|
|
150
|
+
// _select, _internals, and _value must be synchronized to the same value
|
|
151
|
+
this._select.value = resetValue || '';
|
|
152
|
+
this._internals.setFormValue(resetValue || null);
|
|
153
|
+
this._value = resetValue || '';
|
|
154
|
+
this.requestUpdate();
|
|
113
155
|
}
|
|
114
156
|
|
|
115
157
|
/**
|
|
@@ -117,6 +159,11 @@ export class PieSelect extends FormControlMixin(RtlMixin(PieElement)) implements
|
|
|
117
159
|
* @param event - The change event.
|
|
118
160
|
*/
|
|
119
161
|
private _handleChange = (event: Event) => {
|
|
162
|
+
// Update value state
|
|
163
|
+
const { value } = this._select;
|
|
164
|
+
this._value = value;
|
|
165
|
+
this._internals.setFormValue(value);
|
|
166
|
+
|
|
120
167
|
// We have to create our own change event because the native one
|
|
121
168
|
// does not penetrate the shadow boundary.
|
|
122
169
|
|
|
@@ -124,8 +171,6 @@ export class PieSelect extends FormControlMixin(RtlMixin(PieElement)) implements
|
|
|
124
171
|
// Reference: https://javascript.info/shadow-dom-events#event-composed
|
|
125
172
|
const customChangeEvent = wrapNativeEvent(event);
|
|
126
173
|
this.dispatchEvent(customChangeEvent);
|
|
127
|
-
|
|
128
|
-
this._internals.setFormValue(this._select.value);
|
|
129
174
|
};
|
|
130
175
|
|
|
131
176
|
private _handleLeadingIconSlotchange () {
|
|
@@ -139,27 +184,30 @@ export class PieSelect extends FormControlMixin(RtlMixin(PieElement)) implements
|
|
|
139
184
|
*/
|
|
140
185
|
private renderChildren (options: SelectProps['options']): TemplateResult {
|
|
141
186
|
return html`
|
|
142
|
-
|
|
187
|
+
${options.map((option) => {
|
|
143
188
|
if (option.tag === 'optgroup') {
|
|
144
189
|
return html`
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
190
|
+
<optgroup
|
|
191
|
+
?disabled="${option.disabled}"
|
|
192
|
+
label="${ifDefined(option.label)}">
|
|
193
|
+
${this.renderChildren(option.options)}
|
|
194
|
+
</optgroup>
|
|
195
|
+
`;
|
|
151
196
|
}
|
|
152
197
|
|
|
198
|
+
const hasValue = this._value !== '';
|
|
199
|
+
const selected = hasValue ? this._value === option.value : option.selected;
|
|
200
|
+
|
|
153
201
|
return html`
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
`;
|
|
161
|
-
})}
|
|
202
|
+
<option
|
|
203
|
+
.value="${live(option.value || '')}"
|
|
204
|
+
?disabled="${option.disabled}"
|
|
205
|
+
?selected="${selected}">
|
|
206
|
+
${option.text}
|
|
207
|
+
</option>
|
|
162
208
|
`;
|
|
209
|
+
})}
|
|
210
|
+
`;
|
|
163
211
|
}
|
|
164
212
|
|
|
165
213
|
/**
|