@justeattakeaway/pie-select 0.0.1 → 0.1.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.
@@ -11,8 +11,58 @@
11
11
  {
12
12
  "kind": "javascript-module",
13
13
  "path": "src/defs.js",
14
- "declarations": [],
15
- "exports": []
14
+ "declarations": [
15
+ {
16
+ "kind": "variable",
17
+ "name": "sizes",
18
+ "type": {
19
+ "text": "['small', 'medium', 'large']"
20
+ },
21
+ "default": "['small', 'medium', 'large']"
22
+ },
23
+ {
24
+ "kind": "variable",
25
+ "name": "statusTypes",
26
+ "type": {
27
+ "text": "['default', 'error']"
28
+ },
29
+ "default": "['default', 'error']"
30
+ },
31
+ {
32
+ "kind": "variable",
33
+ "name": "defaultProps",
34
+ "type": {
35
+ "text": "DefaultProps"
36
+ },
37
+ "default": "{\n size: 'medium',\n status: 'default',\n disabled: false,\n}"
38
+ }
39
+ ],
40
+ "exports": [
41
+ {
42
+ "kind": "js",
43
+ "name": "sizes",
44
+ "declaration": {
45
+ "name": "sizes",
46
+ "module": "src/defs.js"
47
+ }
48
+ },
49
+ {
50
+ "kind": "js",
51
+ "name": "statusTypes",
52
+ "declaration": {
53
+ "name": "statusTypes",
54
+ "module": "src/defs.js"
55
+ }
56
+ },
57
+ {
58
+ "kind": "js",
59
+ "name": "defaultProps",
60
+ "declaration": {
61
+ "name": "defaultProps",
62
+ "module": "src/defs.js"
63
+ }
64
+ }
65
+ ]
16
66
  },
17
67
  {
18
68
  "kind": "javascript-module",
@@ -22,7 +72,116 @@
22
72
  "kind": "class",
23
73
  "description": "",
24
74
  "name": "PieSelect",
25
- "members": [],
75
+ "members": [
76
+ {
77
+ "kind": "field",
78
+ "name": "shadowRootOptions",
79
+ "type": {
80
+ "text": "object"
81
+ },
82
+ "static": true,
83
+ "default": "{ ...LitElement.shadowRootOptions, delegatesFocus: true }"
84
+ },
85
+ {
86
+ "kind": "field",
87
+ "name": "size",
88
+ "privacy": "public",
89
+ "attribute": "size"
90
+ },
91
+ {
92
+ "kind": "field",
93
+ "name": "disabled",
94
+ "privacy": "public",
95
+ "attribute": "disabled"
96
+ },
97
+ {
98
+ "kind": "field",
99
+ "name": "status",
100
+ "privacy": "public",
101
+ "attribute": "status"
102
+ },
103
+ {
104
+ "kind": "field",
105
+ "name": "assistiveText",
106
+ "type": {
107
+ "text": "SelectProps['assistiveText']"
108
+ },
109
+ "privacy": "public",
110
+ "attribute": "assistiveText"
111
+ },
112
+ {
113
+ "kind": "field",
114
+ "name": "name",
115
+ "type": {
116
+ "text": "SelectProps['name']"
117
+ },
118
+ "privacy": "public",
119
+ "attribute": "name"
120
+ },
121
+ {
122
+ "kind": "field",
123
+ "name": "focusTarget",
124
+ "type": {
125
+ "text": "HTMLElement"
126
+ },
127
+ "privacy": "public"
128
+ },
129
+ {
130
+ "kind": "field",
131
+ "name": "_leadingIconSlot",
132
+ "type": {
133
+ "text": "Array<HTMLElement>"
134
+ },
135
+ "privacy": "private"
136
+ },
137
+ {
138
+ "kind": "field",
139
+ "name": "_hasLeadingIcon",
140
+ "type": {
141
+ "text": "boolean"
142
+ },
143
+ "privacy": "private",
144
+ "default": "false"
145
+ },
146
+ {
147
+ "kind": "method",
148
+ "name": "_handleLeadingIconSlotchange",
149
+ "privacy": "private"
150
+ },
151
+ {
152
+ "kind": "method",
153
+ "name": "renderAssistiveText",
154
+ "privacy": "private"
155
+ }
156
+ ],
157
+ "attributes": [
158
+ {
159
+ "name": "size",
160
+ "fieldName": "size"
161
+ },
162
+ {
163
+ "name": "disabled",
164
+ "fieldName": "disabled"
165
+ },
166
+ {
167
+ "name": "status",
168
+ "fieldName": "status"
169
+ },
170
+ {
171
+ "name": "assistiveText",
172
+ "type": {
173
+ "text": "SelectProps['assistiveText']"
174
+ },
175
+ "fieldName": "assistiveText"
176
+ },
177
+ {
178
+ "name": "name",
179
+ "type": {
180
+ "text": "SelectProps['name']"
181
+ },
182
+ "fieldName": "name"
183
+ }
184
+ ],
26
185
  "mixins": [
27
186
  {
28
187
  "name": "RtlMixin",
package/dist/index.d.ts CHANGED
@@ -1,13 +1,33 @@
1
+ import { ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
1
2
  import type { CSSResult } from 'lit';
2
3
  import type { GenericConstructor } from '@justeattakeaway/pie-webc-core';
3
4
  import type { LitElement } from 'lit';
4
5
  import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
5
6
  import type { TemplateResult } from 'lit-html';
6
7
 
8
+ declare type DefaultProps = ComponentDefaultProps<SelectProps, keyof Omit<SelectProps, 'name' | 'assistiveText'>>;
9
+
10
+ export declare const defaultProps: DefaultProps;
11
+
7
12
  /**
8
13
  * @tagname pie-select
9
14
  */
10
15
  export declare class PieSelect extends PieSelect_base implements SelectProps {
16
+ static shadowRootOptions: {
17
+ delegatesFocus: boolean;
18
+ mode: ShadowRootMode;
19
+ slotAssignment?: SlotAssignmentMode | undefined;
20
+ };
21
+ size: "small" | "medium" | "large";
22
+ disabled: boolean;
23
+ status: "default" | "error";
24
+ assistiveText: SelectProps['assistiveText'];
25
+ name: SelectProps['name'];
26
+ focusTarget: HTMLElement;
27
+ private _leadingIconSlot;
28
+ private _hasLeadingIcon;
29
+ private _handleLeadingIconSlotchange;
30
+ private renderAssistiveText;
11
31
  render(): TemplateResult<1>;
12
32
  static styles: CSSResult;
13
33
  }
@@ -15,6 +35,30 @@ export declare class PieSelect extends PieSelect_base implements SelectProps {
15
35
  declare const PieSelect_base: GenericConstructor<RTLInterface> & typeof LitElement;
16
36
 
17
37
  export declare interface SelectProps {
38
+ /**
39
+ * The size of the select component. Can be `small`, `medium` or `large`. Defaults to `medium`.
40
+ */
41
+ size?: typeof sizes[number];
42
+ /**
43
+ * Same as the HTML disabled attribute - indicates whether the select is disabled.
44
+ */
45
+ disabled?: boolean;
46
+ /**
47
+ * An optional assistive text to display below the select element. Must be provided when the status is success or error.
48
+ */
49
+ assistiveText?: string;
50
+ /**
51
+ * The status of the select component / assistive text. Can be default or error.
52
+ */
53
+ status?: typeof statusTypes[number];
54
+ /**
55
+ * The name of the select (used as a key/value pair with `value`). This is required in order to work properly with forms.
56
+ */
57
+ name?: string;
18
58
  }
19
59
 
60
+ export declare const sizes: readonly ["small", "medium", "large"];
61
+
62
+ export declare const statusTypes: readonly ["default", "error"];
63
+
20
64
  export { }
package/dist/index.js CHANGED
@@ -1,13 +1,104 @@
1
- import { LitElement as s, html as o, unsafeCSS as n } from "lit";
2
- import { RtlMixin as r, defineCustomElement as i } from "@justeattakeaway/pie-webc-core";
3
- const l = "*,*:after,*:before{box-sizing:inherit}", m = "pie-select", e = class e extends r(s) {
1
+ import { LitElement as u, nothing as x, html as b, unsafeCSS as y } from "lit";
2
+ import { RtlMixin as I, validPropertyValues as f, defineCustomElement as k } from "@justeattakeaway/pie-webc-core";
3
+ import { property as c, query as z, queryAssignedElements as $, state as w } from "lit/decorators.js";
4
+ import { ifDefined as d } from "lit/directives/if-defined.js";
5
+ import { classMap as _ } from "lit/directives/class-map.js";
6
+ import "@justeattakeaway/pie-icons-webc/dist/IconChevronDown.js";
7
+ const L = "*,*:after,*:before{box-sizing:inherit}.c-select{--select-padding-block: var(--dt-spacing-c);--select-padding-inline-start: var(--dt-spacing-d);--select-padding-inline-end: var(--dt-spacing-h);--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-size:inherit;line-height:inherit;color:inherit;outline:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:var(--select-cursor)}.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}", T = ["small", "medium", "large"], S = ["default", "error"], i = {
8
+ size: "medium",
9
+ status: "default",
10
+ disabled: !1
11
+ };
12
+ var C = Object.defineProperty, s = (h, a, o, n) => {
13
+ for (var t = void 0, r = h.length - 1, l; r >= 0; r--)
14
+ (l = h[r]) && (t = l(a, o, t) || t);
15
+ return t && C(a, o, t), t;
16
+ };
17
+ const v = "pie-select", g = "assistive-text", p = class p extends I(u) {
18
+ constructor() {
19
+ super(...arguments), this.size = i.size, this.disabled = i.disabled, this.status = i.status, this._hasLeadingIcon = !1;
20
+ }
21
+ _handleLeadingIconSlotchange() {
22
+ this._hasLeadingIcon = !!this._leadingIconSlot.length;
23
+ }
24
+ renderAssistiveText() {
25
+ return this.assistiveText ? b`
26
+ <pie-assistive-text
27
+ id="${g}"
28
+ variant=${d(this.status)}
29
+ data-test-id="pie-textarea-assistive-text">
30
+ ${this.assistiveText}
31
+ </pie-assistive-text>
32
+ ` : x;
33
+ }
4
34
  render() {
5
- return o`<h1 data-test-id="pie-select">Hello world!</h1>`;
35
+ const {
36
+ assistiveText: a,
37
+ disabled: o,
38
+ status: n,
39
+ size: t,
40
+ name: r,
41
+ _hasLeadingIcon: l
42
+ } = this, m = {
43
+ "c-select": !0,
44
+ [`c-select--${t}`]: !0,
45
+ [`c-select--${n}`]: !0,
46
+ "c-select--withLeadingIcon": l,
47
+ "is-disabled": o
48
+ };
49
+ return b`
50
+ <div
51
+ class="${_(m)}"
52
+ data-test-id="pie-select-shell">
53
+ <slot name="leadingIcon" @slotchange=${this._handleLeadingIconSlotchange}></slot>
54
+ <select
55
+ name=${d(r)}
56
+ ?disabled=${o}
57
+ aria-describedby=${d(a ? g : void 0)}
58
+ aria-invalid=${n === "error" ? "true" : "false"}
59
+ aria-errormessage="${d(n === "error" ? g : void 0)}">
60
+ <option value="dog">Dog</option>
61
+ <option value="cat">Cat</option>
62
+ <option value="hamster">Hamster</option>
63
+ </select>
64
+ <icon-chevron-down size='s' class='c-select-trailingIcon'></icon-chevron-down>
65
+ </div>
66
+ ${this.renderAssistiveText()}
67
+ `;
6
68
  }
7
69
  };
8
- e.styles = n(l);
9
- let t = e;
10
- i(m, t);
70
+ p.shadowRootOptions = { ...u.shadowRootOptions, delegatesFocus: !0 }, p.styles = y(L);
71
+ let e = p;
72
+ s([
73
+ c({ type: String }),
74
+ f(v, T, i.size)
75
+ ], e.prototype, "size");
76
+ s([
77
+ c({ type: Boolean })
78
+ ], e.prototype, "disabled");
79
+ s([
80
+ c({ type: String }),
81
+ f(v, S, i.status)
82
+ ], e.prototype, "status");
83
+ s([
84
+ c({ type: String })
85
+ ], e.prototype, "assistiveText");
86
+ s([
87
+ c({ type: String })
88
+ ], e.prototype, "name");
89
+ s([
90
+ z("select")
91
+ ], e.prototype, "focusTarget");
92
+ s([
93
+ $({ slot: "leadingIcon", flatten: !0 })
94
+ ], e.prototype, "_leadingIconSlot");
95
+ s([
96
+ w()
97
+ ], e.prototype, "_hasLeadingIcon");
98
+ k(v, e);
11
99
  export {
12
- t as PieSelect
100
+ e as PieSelect,
101
+ i as defaultProps,
102
+ T as sizes,
103
+ S as statusTypes
13
104
  };
package/dist/react.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
1
2
  import type { CSSResult } from 'lit';
2
3
  import type { GenericConstructor } from '@justeattakeaway/pie-webc-core';
3
4
  import type { LitElement } from 'lit';
@@ -5,21 +6,64 @@ import * as React_2 from 'react';
5
6
  import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
6
7
  import type { TemplateResult } from 'lit-html';
7
8
 
9
+ declare type DefaultProps = ComponentDefaultProps<SelectProps, keyof Omit<SelectProps, 'name' | 'assistiveText'>>;
10
+
11
+ export declare const defaultProps: DefaultProps;
12
+
8
13
  export declare const PieSelect: React_2.ForwardRefExoticComponent<SelectProps & React_2.RefAttributes<PieSelect_2> & ReactBaseType>;
9
14
 
10
15
  /**
11
16
  * @tagname pie-select
12
17
  */
13
18
  declare class PieSelect_2 extends PieSelect_base implements SelectProps {
19
+ static shadowRootOptions: {
20
+ delegatesFocus: boolean;
21
+ mode: ShadowRootMode;
22
+ slotAssignment?: SlotAssignmentMode | undefined;
23
+ };
24
+ size: "small" | "medium" | "large";
25
+ disabled: boolean;
26
+ status: "default" | "error";
27
+ assistiveText: SelectProps['assistiveText'];
28
+ name: SelectProps['name'];
29
+ focusTarget: HTMLElement;
30
+ private _leadingIconSlot;
31
+ private _hasLeadingIcon;
32
+ private _handleLeadingIconSlotchange;
33
+ private renderAssistiveText;
14
34
  render(): TemplateResult<1>;
15
35
  static styles: CSSResult;
16
36
  }
17
37
 
18
38
  declare const PieSelect_base: GenericConstructor<RTLInterface> & typeof LitElement;
19
39
 
20
- declare type ReactBaseType = React_2.HTMLAttributes<HTMLElement>;
40
+ declare type ReactBaseType = React_2.HTMLAttributes<HTMLSelectElement>;
21
41
 
22
42
  export declare interface SelectProps {
43
+ /**
44
+ * The size of the select component. Can be `small`, `medium` or `large`. Defaults to `medium`.
45
+ */
46
+ size?: typeof sizes[number];
47
+ /**
48
+ * Same as the HTML disabled attribute - indicates whether the select is disabled.
49
+ */
50
+ disabled?: boolean;
51
+ /**
52
+ * An optional assistive text to display below the select element. Must be provided when the status is success or error.
53
+ */
54
+ assistiveText?: string;
55
+ /**
56
+ * The status of the select component / assistive text. Can be default or error.
57
+ */
58
+ status?: typeof statusTypes[number];
59
+ /**
60
+ * The name of the select (used as a key/value pair with `value`). This is required in order to work properly with forms.
61
+ */
62
+ name?: string;
23
63
  }
24
64
 
65
+ export declare const sizes: readonly ["small", "medium", "large"];
66
+
67
+ export declare const statusTypes: readonly ["default", "error"];
68
+
25
69
  export { }
package/dist/react.js CHANGED
@@ -1,13 +1,17 @@
1
1
  import * as e from "react";
2
2
  import { createComponent as t } from "@lit/react";
3
- import { PieSelect as c } from "./index.js";
4
- const a = t({
3
+ import { PieSelect as s } from "./index.js";
4
+ import { defaultProps as l, sizes as p, statusTypes as n } from "./index.js";
5
+ const o = t({
5
6
  displayName: "PieSelect",
6
- elementClass: c,
7
+ elementClass: s,
7
8
  react: e,
8
9
  tagName: "pie-select",
9
10
  events: {}
10
- }), m = a;
11
+ }), r = o;
11
12
  export {
12
- m as PieSelect
13
+ r as PieSelect,
14
+ l as defaultProps,
15
+ p as sizes,
16
+ n as statusTypes
13
17
  };
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.0.1",
4
+ "version": "0.1.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -34,7 +34,7 @@
34
34
  "devDependencies": {
35
35
  "@custom-elements-manifest/analyzer": "0.9.0",
36
36
  "@justeattakeaway/pie-components-config": "0.18.0",
37
- "@justeattakeaway/pie-css": "0.14.1",
37
+ "@justeattakeaway/pie-css": "0.16.0",
38
38
  "cem-plugin-module-file-extensions": "0.0.5"
39
39
  },
40
40
  "dependencies": {
package/src/defs-react.ts CHANGED
@@ -1,8 +1,3 @@
1
1
  import type React from 'react';
2
- /**
3
- * TODO: Verify if ReactBaseType can be set as a more specific React interface
4
- * Use the React IntrinsicElements interface to find how to map standard HTML elements to existing React Interfaces
5
- * Example: an HTML button maps to `React.ButtonHTMLAttributes<HTMLButtonElement>`
6
- * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0bb210867d16170c4a08d9ce5d132817651a0f80/types/react/index.d.ts#L2829
7
- */
8
- export type ReactBaseType = React.HTMLAttributes<HTMLElement>
2
+
3
+ export type ReactBaseType = React.HTMLAttributes<HTMLSelectElement>
package/src/defs.ts CHANGED
@@ -1,3 +1,40 @@
1
- // TODO - please remove the eslint disable comment below when you add props to this interface
2
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
3
- export interface SelectProps {}
1
+ import { type ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
2
+
3
+ export const sizes = ['small', 'medium', 'large'] as const;
4
+
5
+ export const statusTypes = ['default', 'error'] as const;
6
+
7
+ export interface SelectProps {
8
+ /**
9
+ * The size of the select component. Can be `small`, `medium` or `large`. Defaults to `medium`.
10
+ */
11
+ size?: typeof sizes[number];
12
+
13
+ /**
14
+ * Same as the HTML disabled attribute - indicates whether the select is disabled.
15
+ */
16
+ disabled?: boolean;
17
+
18
+ /**
19
+ * An optional assistive text to display below the select element. Must be provided when the status is success or error.
20
+ */
21
+ assistiveText?: string;
22
+
23
+ /**
24
+ * The status of the select component / assistive text. Can be default or error.
25
+ */
26
+ status?: typeof statusTypes[number];
27
+
28
+ /**
29
+ * The name of the select (used as a key/value pair with `value`). This is required in order to work properly with forms.
30
+ */
31
+ name?: string;
32
+ }
33
+
34
+ type DefaultProps = ComponentDefaultProps<SelectProps, keyof Omit<SelectProps, 'name' | 'assistiveText' >>;
35
+
36
+ export const defaultProps: DefaultProps = {
37
+ size: 'medium',
38
+ status: 'default',
39
+ disabled: false,
40
+ };
package/src/index.ts CHANGED
@@ -1,20 +1,126 @@
1
- import { LitElement, html, unsafeCSS } from 'lit';
2
- import { RtlMixin, defineCustomElement } from '@justeattakeaway/pie-webc-core';
1
+ import {
2
+ LitElement,
3
+ html,
4
+ nothing,
5
+ unsafeCSS,
6
+ } from 'lit';
7
+ import {
8
+ RtlMixin,
9
+ defineCustomElement,
10
+ validPropertyValues,
11
+ } from '@justeattakeaway/pie-webc-core';
12
+ import {
13
+ property,
14
+ query,
15
+ queryAssignedElements,
16
+ state,
17
+ } from 'lit/decorators.js';
18
+ import { ifDefined } from 'lit/directives/if-defined.js';
19
+ import { classMap, type ClassInfo } from 'lit/directives/class-map.js';
20
+ import '@justeattakeaway/pie-icons-webc/dist/IconChevronDown.js';
3
21
 
4
22
  import styles from './select.scss?inline';
5
- import { type SelectProps } from './defs';
23
+ import {
24
+ defaultProps,
25
+ sizes,
26
+ statusTypes,
27
+ type SelectProps,
28
+ } from './defs';
6
29
 
7
30
  // Valid values available to consumers
8
31
  export * from './defs';
9
32
 
10
33
  const componentSelector = 'pie-select';
34
+ const assistiveTextIdValue = 'assistive-text';
11
35
 
12
36
  /**
13
37
  * @tagname pie-select
14
38
  */
15
39
  export class PieSelect extends RtlMixin(LitElement) implements SelectProps {
40
+ static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };
41
+
42
+ @property({ type: String })
43
+ @validPropertyValues(componentSelector, sizes, defaultProps.size)
44
+ public size = defaultProps.size;
45
+
46
+ @property({ type: Boolean })
47
+ public disabled = defaultProps.disabled;
48
+
49
+ @property({ type: String })
50
+ @validPropertyValues(componentSelector, statusTypes, defaultProps.status)
51
+ public status = defaultProps.status;
52
+
53
+ @property({ type: String })
54
+ public assistiveText: SelectProps['assistiveText'];
55
+
56
+ @property({ type: String })
57
+ public name: SelectProps['name'];
58
+
59
+ @query('select')
60
+ public focusTarget!: HTMLElement;
61
+
62
+ @queryAssignedElements({ slot: 'leadingIcon', flatten: true })
63
+ private _leadingIconSlot!: Array<HTMLElement>;
64
+
65
+ @state()
66
+ private _hasLeadingIcon = false;
67
+
68
+ private _handleLeadingIconSlotchange () {
69
+ this._hasLeadingIcon = Boolean(this._leadingIconSlot.length);
70
+ }
71
+
72
+ private renderAssistiveText () {
73
+ if (!this.assistiveText) {
74
+ return nothing;
75
+ }
76
+
77
+ return html`
78
+ <pie-assistive-text
79
+ id="${assistiveTextIdValue}"
80
+ variant=${ifDefined(this.status)}
81
+ data-test-id="pie-textarea-assistive-text">
82
+ ${this.assistiveText}
83
+ </pie-assistive-text>
84
+ `;
85
+ }
86
+
16
87
  render () {
17
- return html`<h1 data-test-id="pie-select">Hello world!</h1>`;
88
+ const {
89
+ assistiveText,
90
+ disabled,
91
+ status,
92
+ size,
93
+ name,
94
+ _hasLeadingIcon,
95
+ } = this;
96
+
97
+ const classes : ClassInfo = {
98
+ 'c-select': true,
99
+ [`c-select--${size}`]: true,
100
+ [`c-select--${status}`]: true,
101
+ 'c-select--withLeadingIcon': _hasLeadingIcon,
102
+ 'is-disabled': disabled,
103
+ };
104
+
105
+ return html`
106
+ <div
107
+ class="${classMap(classes)}"
108
+ data-test-id="pie-select-shell">
109
+ <slot name="leadingIcon" @slotchange=${this._handleLeadingIconSlotchange}></slot>
110
+ <select
111
+ name=${ifDefined(name)}
112
+ ?disabled=${disabled}
113
+ aria-describedby=${ifDefined(assistiveText ? assistiveTextIdValue : undefined)}
114
+ aria-invalid=${status === 'error' ? 'true' : 'false'}
115
+ aria-errormessage="${ifDefined(status === 'error' ? assistiveTextIdValue : undefined)}">
116
+ <option value="dog">Dog</option>
117
+ <option value="cat">Cat</option>
118
+ <option value="hamster">Hamster</option>
119
+ </select>
120
+ <icon-chevron-down size='s' class='c-select-trailingIcon'></icon-chevron-down>
121
+ </div>
122
+ ${this.renderAssistiveText()}
123
+ `;
18
124
  }
19
125
 
20
126
  // Renders a `CSSResult` generated from SCSS by Vite
package/src/react.ts CHANGED
@@ -13,7 +13,7 @@ const PieSelectReact = createComponent({
13
13
  events: {},
14
14
  });
15
15
 
16
- type ReactBaseType = React.HTMLAttributes<HTMLElement>
16
+ type ReactBaseType = React.HTMLAttributes<HTMLSelectElement>
17
17
 
18
18
  export const PieSelect = PieSelectReact as React.ForwardRefExoticComponent<React.PropsWithoutRef<SelectProps>
19
19
  & React.RefAttributes<PieSelectLit> & ReactBaseType>;
package/src/select.scss CHANGED
@@ -1 +1,101 @@
1
1
  @use '@justeattakeaway/pie-css/scss' as p;
2
+
3
+ .c-select {
4
+ --select-padding-block: var(--dt-spacing-c);
5
+ --select-padding-inline-start: var(--dt-spacing-d);
6
+ --select-padding-inline-end: var(--dt-spacing-h);
7
+ --select-background-color: var(--dt-color-container-default);
8
+ --select-text-color: var(--dt-color-content-default);
9
+ --select-border-color: var(--dt-color-border-form);
10
+ --select-font-size: #{p.font-size(--dt-font-body-l-size)};
11
+ --select-line-height: #{p.font-size(--dt-font-body-l-line-height)};
12
+ --select-height: 48px;
13
+ --select-cursor: pointer;
14
+
15
+ position: relative;
16
+ color: var(--select-text-color);
17
+ font-size: var(--select-font-size);
18
+ line-height: var(--select-line-height);
19
+
20
+ select {
21
+ height: var(--select-height);
22
+ width: 100%;
23
+ border: 1px solid var(--select-border-color);
24
+ border-radius: var(--dt-radius-rounded-c);
25
+ padding-inline-start: var(--select-padding-inline-start);
26
+ padding-inline-end: var(--select-padding-inline-end);
27
+ padding-block-start: var(--select-padding-block);
28
+ padding-block-end: var(--select-padding-block);
29
+ background-color: var(--select-background-color);
30
+ font-size: inherit;
31
+ line-height: inherit;
32
+ color: inherit;
33
+ outline: 0;
34
+ -webkit-appearance: none;
35
+ -moz-appearance: none;
36
+ appearance: none;
37
+ cursor: var(--select-cursor);
38
+
39
+ &:focus-within {
40
+ @include p.focus;
41
+ }
42
+ }
43
+
44
+ &.c-select--small {
45
+ --select-padding-block: var(--dt-spacing-b);
46
+ --select-height: 40px;
47
+ }
48
+
49
+ &.c-select--large {
50
+ --select-padding-block: var(--dt-spacing-d);
51
+ --select-height: 56px;
52
+ }
53
+
54
+ &.c-select--error {
55
+ --select-border-color: var(--dt-color-support-error);
56
+ }
57
+
58
+ &.c-select--withLeadingIcon {
59
+ --select-padding-inline-start: calc(var(--dt-spacing-h) - var(--dt-spacing-a));
60
+ }
61
+
62
+ ::slotted([slot="leadingIcon"]),
63
+ .c-select-trailingIcon {
64
+ position: absolute;
65
+ top: 50%;
66
+ transform: translateY(-50%);
67
+ pointer-events: none;
68
+ }
69
+
70
+ &:not(.is-disabled) ::slotted([slot="leadingIcon"]),
71
+ &:not(.is-disabled) .c-select-trailingIcon {
72
+ color: var(--dt-color-content-subdued);
73
+ }
74
+
75
+ ::slotted([slot="leadingIcon"]) {
76
+ --icon-display-override: block;
77
+ --icon-size-override: 24px;
78
+ inset-inline-start: var(--dt-spacing-d);
79
+ }
80
+
81
+ .c-select-trailingIcon {
82
+ inset-inline-end: var(--dt-spacing-d);
83
+ }
84
+
85
+ @media (hover: hover) {
86
+ &:hover {
87
+ --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))));
88
+
89
+ @supports (background-color: color-mix(in srgb, black, white)) {
90
+ --select-background-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-container-default));
91
+ }
92
+ }
93
+ }
94
+
95
+ &.is-disabled {
96
+ --select-background-color: var(--dt-color-disabled-01);
97
+ --select-border-color: var(--dt-color-disabled-01);
98
+ --select-text-color: var(--dt-color-content-disabled);
99
+ --select-cursor: auto;
100
+ }
101
+ }