@justeattakeaway/pie-radio-group 0.2.1 → 0.3.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 CHANGED
@@ -8,15 +8,6 @@
8
8
  </a>
9
9
  </p>
10
10
 
11
- # Table of Contents
12
-
13
- 1. [Introduction](#pie-radio-group)
14
- 2. [Installation](#installation)
15
- 3. [Importing the component](#importing-the-component)
16
- 4. [Peer Dependencies](#peer-dependencies)
17
- 5. [Props](#props)
18
- 6. [Contributing](#contributing)
19
-
20
11
  ## pie-radio-group
21
12
 
22
13
  `pie-radio-group` is a Web Component built using the Lit library.
@@ -29,63 +20,22 @@ This component can be easily integrated into various frontend frameworks and cus
29
20
  To install `pie-radio-group` in your application, run the following on your command line:
30
21
 
31
22
  ```bash
32
- # npm
33
- $ npm i @justeattakeaway/pie-radio-group
34
-
35
- # yarn
36
- $ yarn add @justeattakeaway/pie-radio-group
37
- ```
38
-
39
- For full information on using PIE components as part of an application, check out the [Getting Started Guide](https://github.com/justeattakeaway/pie/wiki/Getting-started-with-PIE-Web-Components).
40
-
41
-
42
- ### Importing the component
43
-
44
- #### JavaScript
45
- ```js
46
- // Default – for Native JS Applications, Vue, Angular, Svelte, etc.
47
- import { PieRadioGroup } from '@justeattakeaway/pie-radio-group';
48
-
49
- // If you don't need to reference the imported object, you can simply
50
- // import the module which registers the component as a custom element.
51
- import '@justeattakeaway/pie-radio-group';
23
+ npm i @justeattakeaway/pie-radio-group
52
24
  ```
53
-
54
- #### React
55
- ```js
56
- // React
57
- // For React, you will need to import our React-specific component build
58
- // which wraps the web component using ​@lit/react
59
- import { PieRadioGroup } from '@justeattakeaway/pie-radio-group/dist/react';
25
+ ```bash
26
+ yarn add @justeattakeaway/pie-radio-group
60
27
  ```
61
28
 
62
- > [!NOTE]
63
- > When using the React version of the component, please make sure to also
64
- > include React as a [peer dependency](#peer-dependencies) in your project.
65
-
66
-
67
- ## Peer Dependencies
68
-
69
- > [!IMPORTANT]
70
- > When using `pie-radio-group`, you will also need to include a couple of dependencies to ensure the component renders as expected. See [the PIE Wiki](https://github.com/justeattakeaway/pie/wiki/Getting-started-with-PIE-Web-Components#expected-dependencies) for more information and how to include these in your application.
71
-
72
-
73
- ## Props
29
+ For full information on using PIE components as part of an application, check out the [Getting Started Guide](https://github.com/justeattakeaway/pie/wiki/Getting-started-with-PIE-Web-Components).
74
30
 
75
- | Property | Type | Default | Description |
76
- |---|---|---|---|
77
- | - | - | - | - |
31
+ ## Documentation
78
32
 
79
- In your markup or JSX, you can then use these to set the properties for the `pie-radio-group` component:
33
+ Visit [Radio Group | PIE Design System](https://pie.design/components/radio-group/code) to view more information on this component.
80
34
 
81
- ```html
82
- <!-- Native HTML -->
83
- <pie-radio-group></pie-radio-group>
35
+ ## Questions
84
36
 
85
- <!-- JSX -->
86
- <PieRadioGroup></PieRadioGroup>
87
- ```
37
+ Please head to [FAQs | PIE Design System](https://pie.design/support/contact-us/) to see our FAQs and get in touch.
88
38
 
89
39
  ## Contributing
90
40
 
91
- Check out our [contributing guide](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide) for more information on [local development](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#local-development) and how to run specific [component tests](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#testing).
41
+ Check out our [contributing guide](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide) for more information on [local development](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#local-development) and how to run specific [component tests](https://github.com/justeattakeaway/pie/wiki/Contributing-Guide#testing).
@@ -12,6 +12,14 @@
12
12
  "kind": "javascript-module",
13
13
  "path": "src/defs.js",
14
14
  "declarations": [
15
+ {
16
+ "kind": "variable",
17
+ "name": "statusTypes",
18
+ "type": {
19
+ "text": "['default', 'success', 'error']"
20
+ },
21
+ "default": "['default', 'success', 'error']"
22
+ },
15
23
  {
16
24
  "kind": "variable",
17
25
  "name": "ON_RADIO_GROUP_DISABLED",
@@ -27,10 +35,18 @@
27
35
  "type": {
28
36
  "text": "DefaultProps"
29
37
  },
30
- "default": "{\n disabled: false,\n isInline: false,\n value: '',\n}"
38
+ "default": "{\n status: 'default',\n disabled: false,\n isInline: false,\n value: '',\n}"
31
39
  }
32
40
  ],
33
41
  "exports": [
42
+ {
43
+ "kind": "js",
44
+ "name": "statusTypes",
45
+ "declaration": {
46
+ "name": "statusTypes",
47
+ "module": "src/defs.js"
48
+ }
49
+ },
34
50
  {
35
51
  "kind": "js",
36
52
  "name": "ON_RADIO_GROUP_DISABLED",
@@ -105,6 +121,21 @@
105
121
  "attribute": "disabled",
106
122
  "reflects": true
107
123
  },
124
+ {
125
+ "kind": "field",
126
+ "name": "assistiveText",
127
+ "type": {
128
+ "text": "RadioGroupProps['assistiveText'] | undefined"
129
+ },
130
+ "privacy": "public",
131
+ "attribute": "assistiveText"
132
+ },
133
+ {
134
+ "kind": "field",
135
+ "name": "status",
136
+ "privacy": "public",
137
+ "attribute": "status"
138
+ },
108
139
  {
109
140
  "kind": "field",
110
141
  "name": "_slottedChildren",
@@ -131,6 +162,17 @@
131
162
  },
132
163
  "description": "Dispatches a custom event to notify each slotted child radio element\nwhen the radio group is disabled."
133
164
  },
165
+ {
166
+ "kind": "method",
167
+ "name": "_handleStatus",
168
+ "privacy": "private",
169
+ "return": {
170
+ "type": {
171
+ "text": "void"
172
+ }
173
+ },
174
+ "description": "Updates the `status` attribute of all slotted children."
175
+ },
134
176
  {
135
177
  "kind": "method",
136
178
  "name": "_handleRadioSelection",
@@ -231,6 +273,17 @@
231
273
  {
232
274
  "name": "disabled",
233
275
  "fieldName": "disabled"
276
+ },
277
+ {
278
+ "name": "assistiveText",
279
+ "type": {
280
+ "text": "RadioGroupProps['assistiveText'] | undefined"
281
+ },
282
+ "fieldName": "assistiveText"
283
+ },
284
+ {
285
+ "name": "status",
286
+ "fieldName": "status"
234
287
  }
235
288
  ],
236
289
  "mixins": [
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import type { PropertyValues } from 'lit';
7
7
  import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
8
8
  import type { TemplateResult } from 'lit';
9
9
 
10
- export declare type DefaultProps = ComponentDefaultProps<RadioGroupProps, keyof Omit<RadioGroupProps, 'name'>>;
10
+ export declare type DefaultProps = ComponentDefaultProps<RadioGroupProps, keyof Omit<RadioGroupProps, 'assistiveText' | 'name'>>;
11
11
 
12
12
  export declare const defaultProps: DefaultProps;
13
13
 
@@ -30,6 +30,8 @@ export declare class PieRadioGroup extends PieRadioGroup_base implements RadioGr
30
30
  value: string;
31
31
  isInline: boolean;
32
32
  disabled: boolean;
33
+ assistiveText?: RadioGroupProps['assistiveText'];
34
+ status: "default" | "error" | "success";
33
35
  _slottedChildren: Array<HTMLInputElement>;
34
36
  private _abortController;
35
37
  /**
@@ -38,6 +40,12 @@ export declare class PieRadioGroup extends PieRadioGroup_base implements RadioGr
38
40
  * @private
39
41
  */
40
42
  private _handleDisabled;
43
+ /**
44
+ * Updates the `status` attribute of all slotted children.
45
+ * @private
46
+ * @returns {void}
47
+ */
48
+ private _handleStatus;
41
49
  /**
42
50
  * Unselects all radios that are not the selected value.
43
51
  * @param {string} selectedValue - The value of the currently selected radio.
@@ -88,6 +96,16 @@ export declare interface RadioGroupProps {
88
96
  * The value of the radio group (used as a key/value pair in HTML forms with `name`).
89
97
  */
90
98
  value?: string;
99
+ /**
100
+ * The status of the radio group component / assistive text. Can be default, success or error.
101
+ */
102
+ status?: typeof statusTypes[number];
103
+ /**
104
+ * An optional assistive text to display below the checkbox group.
105
+ */
106
+ assistiveText?: string;
91
107
  }
92
108
 
109
+ export declare const statusTypes: readonly ["default", "success", "error"];
110
+
93
111
  export { }
package/dist/index.js CHANGED
@@ -1,22 +1,23 @@
1
- import { LitElement as g, html as r, unsafeCSS as b } from "lit";
2
- import { state as u, property as s, queryAssignedElements as f } from "lit/decorators.js";
3
- import { FormControlMixin as m, RtlMixin as _, wrapNativeEvent as v, defineCustomElement as C } from "@justeattakeaway/pie-webc-core";
4
- import { ifDefined as y } from "lit/directives/if-defined.js";
5
- import { classMap as E } from "lit/directives/class-map.js";
1
+ import { LitElement as v, html as p, nothing as u, unsafeCSS as m } from "lit";
2
+ import { state as _, property as l, queryAssignedElements as y } from "lit/decorators.js";
3
+ import { FormControlMixin as C, RtlMixin as x, wrapNativeEvent as S, validPropertyValues as E, defineCustomElement as $ } from "@justeattakeaway/pie-webc-core";
4
+ import { ifDefined as w } from "lit/directives/if-defined.js";
5
+ import { classMap as L } from "lit/directives/class-map.js";
6
6
  import "@justeattakeaway/pie-assistive-text";
7
- const S = "*,*:after,*:before{box-sizing:inherit}.c-radioGroup{--radio-group-gap: var(--dt-spacing-c);--radio-group-gap--inline: var(--dt-spacing-c) var(--dt-spacing-e);margin:0;padding:0;border:0;min-width:0;display:flex;flex-flow:column wrap;gap:var(--radio-group-gap)}.c-radioGroup.c-radioGroup--inline{flex-flow:row wrap;gap:var(--radio-group-gap--inline)}", w = "pie-radio-group-disabled", d = {
7
+ const A = "*,*:after,*:before{box-sizing:inherit}.c-radioGroup{--radio-group-gap: var(--dt-spacing-c);--radio-group-gap--inline: var(--dt-spacing-c) var(--dt-spacing-e);margin:0;padding:0;border:0;min-width:0;display:flex;flex-flow:column wrap;gap:var(--radio-group-gap)}.c-radioGroup.c-radioGroup--inline{flex-flow:row wrap;gap:var(--radio-group-gap--inline)}.c-radioGroup.c-radioGroup--hasAssistiveText{margin-block-end:var(--dt-spacing-a)}", I = ["default", "success", "error"], G = "pie-radio-group-disabled", n = {
8
+ status: "default",
8
9
  disabled: !1,
9
10
  isInline: !1,
10
11
  value: ""
11
12
  };
12
- var L = Object.defineProperty, l = (h, e, t, o) => {
13
- for (var i = void 0, n = h.length - 1, c; n >= 0; n--)
14
- (c = h[n]) && (i = c(e, t, i) || i);
15
- return i && L(e, t, i), i;
13
+ var R = Object.defineProperty, o = (c, e, t, d) => {
14
+ for (var a = void 0, i = c.length - 1, r; i >= 0; i--)
15
+ (r = c[i]) && (a = r(e, t, a) || a);
16
+ return a && R(e, t, a), a;
16
17
  };
17
- const x = "pie-radio-group", p = class p extends m(_(g)) {
18
+ const b = "pie-radio-group", g = "assistive-text", h = class h extends C(x(v)) {
18
19
  constructor() {
19
- super(...arguments), this._hasLabel = !1, this.value = d.value, this.isInline = d.isInline, this.disabled = d.disabled;
20
+ super(...arguments), this._hasLabel = !1, this.value = n.value, this.isInline = n.isInline, this.disabled = n.disabled, this.status = n.status;
20
21
  }
21
22
  /**
22
23
  * Dispatches a custom event to notify each slotted child radio element
@@ -24,12 +25,20 @@ const x = "pie-radio-group", p = class p extends m(_(g)) {
24
25
  * @private
25
26
  */
26
27
  _handleDisabled() {
27
- this._slottedChildren.forEach((e) => e.dispatchEvent(new CustomEvent(w, {
28
+ this._slottedChildren.forEach((e) => e.dispatchEvent(new CustomEvent(G, {
28
29
  bubbles: !1,
29
30
  composed: !1,
30
31
  detail: { disabled: this.disabled }
31
32
  })));
32
33
  }
34
+ /**
35
+ * Updates the `status` attribute of all slotted children.
36
+ * @private
37
+ * @returns {void}
38
+ */
39
+ _handleStatus() {
40
+ this._slottedChildren.forEach((e) => e.setAttribute("status", this.status === "error" ? "error" : "default"));
41
+ }
33
42
  /**
34
43
  * Unselects all radios that are not the selected value.
35
44
  * @param {string} selectedValue - The value of the currently selected radio.
@@ -49,8 +58,8 @@ const x = "pie-radio-group", p = class p extends m(_(g)) {
49
58
  e.stopPropagation();
50
59
  const t = e.target;
51
60
  this._handleRadioSelection(t.value);
52
- const o = v(e);
53
- this.dispatchEvent(o);
61
+ const d = S(e);
62
+ this.dispatchEvent(d);
54
63
  }
55
64
  /**
56
65
  * Updates the `_hasLabel` state when content is added to the label slot.
@@ -67,10 +76,10 @@ const x = "pie-radio-group", p = class p extends m(_(g)) {
67
76
  * @private
68
77
  */
69
78
  _renderWrappedLabel() {
70
- return this._hasLabel ? r`<legend><slot name='label' @slotchange=${this._handleSlotChange}></slot></legend>` : r`<slot name='label' @slotchange=${this._handleSlotChange}></slot>`;
79
+ return this._hasLabel ? p`<legend><slot name='label' @slotchange=${this._handleSlotChange}></slot></legend>` : p`<slot name='label' @slotchange=${this._handleSlotChange}></slot>`;
71
80
  }
72
81
  updated(e) {
73
- e.has("disabled") && this._handleDisabled(), e.has("value") && this._handleRadioSelection(this.value);
82
+ e.has("disabled") && this._handleDisabled(), e.has("value") && this._handleRadioSelection(this.value), e.has("status") && this._handleStatus();
74
83
  }
75
84
  connectedCallback() {
76
85
  var t;
@@ -85,46 +94,65 @@ const x = "pie-radio-group", p = class p extends m(_(g)) {
85
94
  const {
86
95
  name: e,
87
96
  isInline: t,
88
- disabled: o
89
- } = this, i = {
97
+ disabled: d,
98
+ status: a,
99
+ assistiveText: i
100
+ } = this, r = !!(i != null && i.length), f = {
90
101
  "c-radioGroup": !0,
91
- "c-radioGroup--inline": t
102
+ "c-radioGroup--inline": t,
103
+ "c-radioGroup--hasAssistiveText": r
92
104
  };
93
- return r`
105
+ return p`
94
106
  <fieldset
95
- name=${y(e)}
96
- ?disabled=${o}
107
+ name=${w(e)}
108
+ ?disabled=${d}
97
109
  data-test-id="pie-radio-group"
98
- class="${E(i)}">
110
+ aria-describedby=${r ? g : u}
111
+ class="${L(f)}">
99
112
  ${this._renderWrappedLabel()}
100
113
  <slot></slot>
101
114
  </fieldset>
115
+ ${r ? p`
116
+ <pie-assistive-text
117
+ id=${g}
118
+ variant=${a}
119
+ data-test-id="pie-radio-group-assistive-text">
120
+ ${i}
121
+ </pie-assistive-text>` : u}
102
122
  `;
103
123
  }
104
124
  };
105
- p.styles = b(S);
106
- let a = p;
107
- l([
108
- u()
109
- ], a.prototype, "_hasLabel");
110
- l([
111
- s({ type: String })
112
- ], a.prototype, "name");
113
- l([
114
- s({ type: String })
115
- ], a.prototype, "value");
116
- l([
117
- s({ type: Boolean })
118
- ], a.prototype, "isInline");
119
- l([
120
- s({ type: Boolean, reflect: !0 })
121
- ], a.prototype, "disabled");
122
- l([
123
- f({ selector: "pie-radio" })
124
- ], a.prototype, "_slottedChildren");
125
- C(x, a);
125
+ h.styles = m(A);
126
+ let s = h;
127
+ o([
128
+ _()
129
+ ], s.prototype, "_hasLabel");
130
+ o([
131
+ l({ type: String })
132
+ ], s.prototype, "name");
133
+ o([
134
+ l({ type: String })
135
+ ], s.prototype, "value");
136
+ o([
137
+ l({ type: Boolean })
138
+ ], s.prototype, "isInline");
139
+ o([
140
+ l({ type: Boolean, reflect: !0 })
141
+ ], s.prototype, "disabled");
142
+ o([
143
+ l({ type: String })
144
+ ], s.prototype, "assistiveText");
145
+ o([
146
+ l({ type: String }),
147
+ E(b, I, n.status)
148
+ ], s.prototype, "status");
149
+ o([
150
+ y({ selector: "pie-radio" })
151
+ ], s.prototype, "_slottedChildren");
152
+ $(b, s);
126
153
  export {
127
- w as ON_RADIO_GROUP_DISABLED,
128
- a as PieRadioGroup,
129
- d as defaultProps
154
+ G as ON_RADIO_GROUP_DISABLED,
155
+ s as PieRadioGroup,
156
+ n as defaultProps,
157
+ I as statusTypes
130
158
  };
package/dist/react.d.ts CHANGED
@@ -8,7 +8,7 @@ import * as React_2 from 'react';
8
8
  import type { RTLInterface } from '@justeattakeaway/pie-webc-core';
9
9
  import type { TemplateResult } from 'lit';
10
10
 
11
- export declare type DefaultProps = ComponentDefaultProps<RadioGroupProps, keyof Omit<RadioGroupProps, 'name'>>;
11
+ export declare type DefaultProps = ComponentDefaultProps<RadioGroupProps, keyof Omit<RadioGroupProps, 'assistiveText' | 'name'>>;
12
12
 
13
13
  export declare const defaultProps: DefaultProps;
14
14
 
@@ -33,6 +33,8 @@ declare class PieRadioGroup_2 extends PieRadioGroup_base implements RadioGroupPr
33
33
  value: string;
34
34
  isInline: boolean;
35
35
  disabled: boolean;
36
+ assistiveText?: RadioGroupProps['assistiveText'];
37
+ status: "default" | "error" | "success";
36
38
  _slottedChildren: Array<HTMLInputElement>;
37
39
  private _abortController;
38
40
  /**
@@ -41,6 +43,12 @@ declare class PieRadioGroup_2 extends PieRadioGroup_base implements RadioGroupPr
41
43
  * @private
42
44
  */
43
45
  private _handleDisabled;
46
+ /**
47
+ * Updates the `status` attribute of all slotted children.
48
+ * @private
49
+ * @returns {void}
50
+ */
51
+ private _handleStatus;
44
52
  /**
45
53
  * Unselects all radios that are not the selected value.
46
54
  * @param {string} selectedValue - The value of the currently selected radio.
@@ -95,8 +103,18 @@ export declare interface RadioGroupProps {
95
103
  * The value of the radio group (used as a key/value pair in HTML forms with `name`).
96
104
  */
97
105
  value?: string;
106
+ /**
107
+ * The status of the radio group component / assistive text. Can be default, success or error.
108
+ */
109
+ status?: typeof statusTypes[number];
110
+ /**
111
+ * An optional assistive text to display below the checkbox group.
112
+ */
113
+ assistiveText?: string;
98
114
  }
99
115
 
100
116
  declare type ReactBaseType = React_2.HTMLAttributes<HTMLElement>;
101
117
 
118
+ export declare const statusTypes: readonly ["default", "success", "error"];
119
+
102
120
  export { }
package/dist/react.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as o from "react";
2
2
  import { createComponent as e } from "@lit/react";
3
3
  import { PieRadioGroup as a } from "./index.js";
4
- import { ON_RADIO_GROUP_DISABLED as s, defaultProps as R } from "./index.js";
4
+ import { ON_RADIO_GROUP_DISABLED as n, defaultProps as R, statusTypes as d } from "./index.js";
5
5
  const r = e({
6
6
  displayName: "PieRadioGroup",
7
7
  elementClass: a,
@@ -13,7 +13,8 @@ const r = e({
13
13
  }
14
14
  }), p = r;
15
15
  export {
16
- s as ON_RADIO_GROUP_DISABLED,
16
+ n as ON_RADIO_GROUP_DISABLED,
17
17
  p as PieRadioGroup,
18
- R as defaultProps
18
+ R as defaultProps,
19
+ d as statusTypes
19
20
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-radio-group",
3
3
  "description": "PIE Design System Radio Group built using Web Components",
4
- "version": "0.2.1",
4
+ "version": "0.3.1",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -38,11 +38,11 @@
38
38
  "@custom-elements-manifest/analyzer": "0.9.0",
39
39
  "@justeattakeaway/pie-components-config": "0.18.0",
40
40
  "@justeattakeaway/pie-css": "0.13.1",
41
- "@justeattakeaway/pie-radio": "0.4.0",
41
+ "@justeattakeaway/pie-radio": "0.5.0",
42
42
  "cem-plugin-module-file-extensions": "0.0.5"
43
43
  },
44
44
  "dependencies": {
45
- "@justeattakeaway/pie-assistive-text": "0.7.5",
45
+ "@justeattakeaway/pie-assistive-text": "0.8.1",
46
46
  "@justeattakeaway/pie-webc-core": "0.24.2"
47
47
  },
48
48
  "volta": {
package/src/defs.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { type ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
2
2
 
3
+ export const statusTypes = ['default', 'success', 'error'] as const;
4
+
3
5
  export interface RadioGroupProps {
4
6
  /**
5
7
  * The name associated with the group.
@@ -20,6 +22,16 @@ export interface RadioGroupProps {
20
22
  * The value of the radio group (used as a key/value pair in HTML forms with `name`).
21
23
  */
22
24
  value?: string;
25
+
26
+ /**
27
+ * The status of the radio group component / assistive text. Can be default, success or error.
28
+ */
29
+ status?: typeof statusTypes[number];
30
+
31
+ /**
32
+ * An optional assistive text to display below the checkbox group.
33
+ */
34
+ assistiveText?: string;
23
35
  }
24
36
 
25
37
  /**
@@ -29,9 +41,10 @@ export interface RadioGroupProps {
29
41
  */
30
42
  export const ON_RADIO_GROUP_DISABLED = 'pie-radio-group-disabled';
31
43
 
32
- export type DefaultProps = ComponentDefaultProps<RadioGroupProps, keyof Omit<RadioGroupProps, 'name'>>;
44
+ export type DefaultProps = ComponentDefaultProps<RadioGroupProps, keyof Omit<RadioGroupProps, 'assistiveText' | 'name'>>;
33
45
 
34
46
  export const defaultProps: DefaultProps = {
47
+ status: 'default',
35
48
  disabled: false,
36
49
  isInline: false,
37
50
  value: '',
package/src/index.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import {
2
- LitElement, html, unsafeCSS, type PropertyValues, type TemplateResult,
2
+ LitElement,
3
+ html,
4
+ unsafeCSS,
5
+ nothing,
6
+ type PropertyValues,
7
+ type TemplateResult,
3
8
  } from 'lit';
4
9
  import { property, queryAssignedElements, state } from 'lit/decorators.js';
5
10
  import {
@@ -7,6 +12,7 @@ import {
7
12
  defineCustomElement,
8
13
  FormControlMixin,
9
14
  wrapNativeEvent,
15
+ validPropertyValues,
10
16
  } from '@justeattakeaway/pie-webc-core';
11
17
  import { ifDefined } from 'lit/directives/if-defined.js';
12
18
  import { classMap } from 'lit/directives/class-map.js';
@@ -14,6 +20,7 @@ import styles from './radio-group.scss?inline';
14
20
  import {
15
21
  type RadioGroupProps,
16
22
  defaultProps,
23
+ statusTypes,
17
24
  ON_RADIO_GROUP_DISABLED,
18
25
  } from './defs';
19
26
  import '@justeattakeaway/pie-assistive-text';
@@ -22,6 +29,7 @@ import '@justeattakeaway/pie-assistive-text';
22
29
  export * from './defs';
23
30
 
24
31
  const componentSelector = 'pie-radio-group';
32
+ const assistiveTextId = 'assistive-text';
25
33
 
26
34
  /**
27
35
  * @tagname pie-radio-group
@@ -45,6 +53,13 @@ export class PieRadioGroup extends FormControlMixin(RtlMixin(LitElement)) implem
45
53
  @property({ type: Boolean, reflect: true })
46
54
  public disabled = defaultProps.disabled;
47
55
 
56
+ @property({ type: String })
57
+ public assistiveText?: RadioGroupProps['assistiveText'];
58
+
59
+ @property({ type: String })
60
+ @validPropertyValues(componentSelector, statusTypes, defaultProps.status)
61
+ public status = defaultProps.status;
62
+
48
63
  @queryAssignedElements({ selector: 'pie-radio' })
49
64
  _slottedChildren!: Array<HTMLInputElement>;
50
65
 
@@ -61,6 +76,15 @@ export class PieRadioGroup extends FormControlMixin(RtlMixin(LitElement)) implem
61
76
  })));
62
77
  }
63
78
 
79
+ /**
80
+ * Updates the `status` attribute of all slotted children.
81
+ * @private
82
+ * @returns {void}
83
+ */
84
+ private _handleStatus (): void {
85
+ this._slottedChildren.forEach((child) => child.setAttribute('status', this.status === 'error' ? 'error' : 'default'));
86
+ }
87
+
64
88
  /**
65
89
  * Unselects all radios that are not the selected value.
66
90
  * @param {string} selectedValue - The value of the currently selected radio.
@@ -117,6 +141,10 @@ export class PieRadioGroup extends FormControlMixin(RtlMixin(LitElement)) implem
117
141
  if (_changedProperties.has('value')) {
118
142
  this._handleRadioSelection(this.value);
119
143
  }
144
+
145
+ if (_changedProperties.has('status')) {
146
+ this._handleStatus();
147
+ }
120
148
  }
121
149
 
122
150
  connectedCallback (): void {
@@ -137,11 +165,16 @@ export class PieRadioGroup extends FormControlMixin(RtlMixin(LitElement)) implem
137
165
  name,
138
166
  isInline,
139
167
  disabled,
168
+ status,
169
+ assistiveText,
140
170
  } = this;
141
171
 
172
+ const hasAssistiveText = Boolean(assistiveText?.length);
173
+
142
174
  const classes = {
143
175
  'c-radioGroup': true,
144
176
  'c-radioGroup--inline': isInline,
177
+ 'c-radioGroup--hasAssistiveText': hasAssistiveText,
145
178
  };
146
179
 
147
180
  return html`
@@ -149,10 +182,19 @@ export class PieRadioGroup extends FormControlMixin(RtlMixin(LitElement)) implem
149
182
  name=${ifDefined(name)}
150
183
  ?disabled=${disabled}
151
184
  data-test-id="pie-radio-group"
185
+ aria-describedby=${hasAssistiveText ? assistiveTextId : nothing}
152
186
  class="${classMap(classes)}">
153
187
  ${this._renderWrappedLabel()}
154
188
  <slot></slot>
155
189
  </fieldset>
190
+ ${hasAssistiveText ? html`
191
+ <pie-assistive-text
192
+ id=${assistiveTextId}
193
+ variant=${status}
194
+ data-test-id="pie-radio-group-assistive-text">
195
+ ${assistiveText}
196
+ </pie-assistive-text>`
197
+ : nothing}
156
198
  `;
157
199
  }
158
200
 
@@ -16,4 +16,8 @@
16
16
  flex-flow: row wrap;
17
17
  gap: var(--radio-group-gap--inline);
18
18
  }
19
+
20
+ &.c-radioGroup--hasAssistiveText {
21
+ margin-block-end: var(--dt-spacing-a);
22
+ }
19
23
  }