@justeattakeaway/pie-checkbox 1.3.5 → 1.4.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.
@@ -122,6 +122,14 @@
122
122
  "privacy": "private",
123
123
  "default": "false"
124
124
  },
125
+ {
126
+ "kind": "field",
127
+ "name": "_contextAria",
128
+ "type": {
129
+ "text": "ContextualAria | undefined"
130
+ },
131
+ "privacy": "private"
132
+ },
125
133
  {
126
134
  "kind": "field",
127
135
  "name": "value",
@@ -218,6 +226,25 @@
218
226
  },
219
227
  "privacy": "private"
220
228
  },
229
+ {
230
+ "kind": "method",
231
+ "name": "_handleClick",
232
+ "privacy": "private",
233
+ "return": {
234
+ "type": {
235
+ "text": "void"
236
+ }
237
+ },
238
+ "parameters": [
239
+ {
240
+ "name": "event",
241
+ "type": {
242
+ "text": "MouseEvent"
243
+ }
244
+ }
245
+ ],
246
+ "description": "Forwards a click dispatched directly on the host (for example from a `pie-list-item` row)\nto the internal input. Clicks on the internal label already toggle the input natively via\nits `for` attribute, so only host-level clicks are forwarded, to avoid a double toggle."
247
+ },
221
248
  {
222
249
  "kind": "field",
223
250
  "name": "validity",
@@ -259,6 +286,17 @@
259
286
  ],
260
287
  "description": "Called after the disabled state of the element changes,\neither because the disabled attribute of this element was added or removed;\nor because the disabled state changed on a <fieldset> that's an ancestor of this element."
261
288
  },
289
+ {
290
+ "kind": "method",
291
+ "name": "_applyContextAria",
292
+ "privacy": "private",
293
+ "return": {
294
+ "type": {
295
+ "text": "void"
296
+ }
297
+ },
298
+ "description": "When an ancestor provides ARIA (for example a `pie-list-item`), applies the fields this\ncontrol cares about to the internal input (the element that carries the checkbox semantics).\nDoes nothing when used standalone, where the name comes from the default slot / label."
299
+ },
262
300
  {
263
301
  "kind": "method",
264
302
  "name": "_handleChange",
package/dist/index.d.ts CHANGED
@@ -70,6 +70,7 @@ export declare class PieCheckbox extends PieCheckbox_base implements CheckboxPro
70
70
  private _disabledByParent;
71
71
  private _visuallyHiddenError;
72
72
  private _isAnimationAllowed;
73
+ private _contextAria?;
73
74
  value: string;
74
75
  name: CheckboxProps['name'];
75
76
  checked: boolean;
@@ -84,6 +85,13 @@ export declare class PieCheckbox extends PieCheckbox_base implements CheckboxPro
84
85
  labelFit: "hug" | "fill";
85
86
  private _abortController;
86
87
  connectedCallback(): void;
88
+ /**
89
+ * Forwards a click dispatched directly on the host (for example from a `pie-list-item` row)
90
+ * to the internal input. Clicks on the internal label already toggle the input natively via
91
+ * its `for` attribute, so only host-level clicks are forwarded, to avoid a double toggle.
92
+ * @param {MouseEvent} event
93
+ */
94
+ private _handleClick;
87
95
  disconnectedCallback(): void;
88
96
  /**
89
97
  * (Read-only) returns a ValidityState with the validity states that this element is in.
@@ -102,6 +110,12 @@ export declare class PieCheckbox extends PieCheckbox_base implements CheckboxPro
102
110
  */
103
111
  formDisabledCallback(disabled: boolean): void;
104
112
  protected updated(): void;
113
+ /**
114
+ * When an ancestor provides ARIA (for example a `pie-list-item`), applies the fields this
115
+ * control cares about to the internal input (the element that carries the checkbox semantics).
116
+ * Does nothing when used standalone, where the name comes from the default slot / label.
117
+ */
118
+ private _applyContextAria;
105
119
  /**
106
120
  * Captures the native change event and wraps it in a custom event.
107
121
  * @param {Event} event - This should be the change event that was listened for on an input element with `type="checkbox"`.
package/dist/index.js CHANGED
@@ -1,18 +1,71 @@
1
- import { LitElement as E, nothing as B, html as f, unsafeCSS as S } from "lit";
1
+ import { LitElement as q, nothing as B, html as m, unsafeCSS as D } from "lit";
2
2
  import { classMap as y } from "lit/directives/class-map.js";
3
- import { state as u, property as i, query as D } from "lit/decorators.js";
3
+ import { state as x, property as n, query as S } from "lit/decorators.js";
4
4
  import { ifDefined as w } from "lit/directives/if-defined.js";
5
- import { live as q } from "lit/directives/live.js";
6
- import { DelegatesFocusMixin as z, FormControlMixin as H, wrapNativeEvent as T, validPropertyValues as g, safeCustomElement as O } from "@justeattakeaway/pie-webc-core";
5
+ import { live as z } from "lit/directives/live.js";
6
+ import { DelegatesFocusMixin as T, FormControlMixin as H, wrapNativeEvent as I, validPropertyValues as f, safeCustomElement as j, ariaContext as L } from "@justeattakeaway/pie-webc-core";
7
7
  import "@justeattakeaway/pie-assistive-text";
8
- const k = class k extends E {
8
+ const k = class k extends q {
9
9
  willUpdate() {
10
10
  this.getAttribute("v") || this.setAttribute("v", k.v);
11
11
  }
12
12
  };
13
- k.v = "1.3.5";
13
+ k.v = "1.4.0";
14
14
  let p = k;
15
- const j = '*,*:after,*:before{box-sizing:inherit}:host{display:block;width:fit-content}:host([labelFit=fill]){width:100%}@keyframes checkboxCheck{0%{width:0;height:0;border-color:#fff;transform:translateZ(0) rotate(45deg)}33%{width:8px;height:0;transform:translateZ(0) rotate(45deg)}to{width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,1px) rotate(45deg)}}@keyframes scaleDown{0%{transform:scale(1)}to{transform:scale(0)}}@keyframes scaleUp{0%{transform:scale(0)}33%{transform:scale(.5)}to{transform:scale(1)}}.c-checkbox-tick{content:"";display:flex;flex:0 0 auto;width:var(--checkbox-width);height:var(--checkbox-height);margin:var(--checkbox-margin);border:1px solid var(--checkbox-border-color);border-radius:var(--checkbox-radius);background-color:var(--checkbox-bg-color)}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick{transition:background-color var(--dt-motion-timing-100) var(--checkbox-motion-easing),border-color var(--dt-motion-timing-100) var(--checkbox-motion-easing)}}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick.is-animated{animation:scaleDown var(--dt-motion-timing-100) var(--checkbox-motion-easing)}}.c-checkbox-tick.is-disabled{--checkbox-bg-color: var(--dt-color-container-strong);--checkbox-border-color: var(--dt-color-disabled-01)}.c-checkbox-tick.c-checkbox-tick--status-error{--checkbox-border-color: var(--dt-color-support-error)}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick.is-animated.is-checked{animation:scaleUp var(--dt-motion-timing-100) var(--checkbox-motion-easing)}}.c-checkbox-tick.is-checked:not(.is-disabled){--checkbox-bg-color: var(--dt-color-interactive-brand);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-checked.c-checkbox-tick--status-error{--checkbox-bg-color: var(--dt-color-support-error);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-checked:before{content:"";position:relative;top:55%;left:14%;border-right:2px solid transparent;border-bottom:2px solid transparent;transform:rotate(45deg);transform-origin:0% 100%}@media(prefers-reduced-motion:reduce){.c-checkbox-tick.is-checked:before{animation-duration:1ms!important;animation-delay:0!important;animation-iteration-count:1!important;width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,0) rotate(45deg)}}@media only percy{.c-checkbox-tick.is-checked:before{animation:none;width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,0) rotate(45deg)}}.c-checkbox-tick.is-checked.is-animated:before{animation:checkboxCheck var(--dt-motion-timing-150) var(--checkbox-motion-easing) forwards}.c-checkbox-tick.is-checked:not(.is-animated):before{width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,0) rotate(45deg)}.c-checkbox-tick.is-checked:dir(rtl):before{left:unset;right:50%}.c-checkbox-tick.is-indeterminate:not(.is-disabled){--checkbox-bg-color: var(--dt-color-interactive-brand);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-indeterminate.c-checkbox-tick--status-error{--checkbox-bg-color: var(--dt-color-support-error);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-indeterminate:after{width:16px}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick.is-indeterminate:after{transition:width var(--dt-motion-timing-100) var(--checkbox-motion-easing) var(--dt-motion-timing-100)}}.c-checkbox-text{display:inline;flex:1 1 auto;align-self:center;min-width:0;margin-inline-start:var(--checkbox-gap);white-space:normal;color:var(--checkbox-content-color);font-family:var(--checkbox-font-family);font-size:var(--checkbox-font-size);line-height:var(--checkbox-line-height);font-weight:var(--checkbox-font-weight)}.c-checkbox-tick:after{content:"";position:relative;top:47%;left:14%;width:0;height:2px;background-color:#fff}.c-checkbox-tick:dir(rtl):after{left:unset;right:14%}.c-checkbox{--checkbox-height: 24px;--checkbox-width: 24px;--checkbox-radius: var(--dt-radius-rounded-a);--checkbox-margin: 1px;--checkbox-gap: var(--dt-spacing-b);--checkbox-font-family: var(--dt-font-body-l-family);--checkbox-font-size: calc(var(--dt-font-body-l-size) * 1px);--checkbox-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--checkbox-font-weight: var(--dt-font-body-l-weight);--checkbox-bg-color: var(--dt-color-container-default);--checkbox-border-color: var(--dt-color-border-form);--checkbox-content-color: var(--dt-color-content-default-solid);--checkbox-motion-easing: var(--dt-motion-easing-persistent-functional);display:flex;flex-direction:column;align-items:flex-start}.c-checkbox input{position:absolute;display:block;height:1px;width:1px;border:0;padding:0;margin:-1px;overflow:hidden;white-space:nowrap;clip:rect(0,0,0,0);clip-path:inset(50%)}.c-checkbox input *{overflow:hidden}.c-checkbox label{display:flex;width:100%;white-space:nowrap;cursor:pointer}.c-checkbox.c-checkbox--leading label{flex-direction:row-reverse}.c-checkbox.c-checkbox--leading .c-checkbox-text{margin-inline-start:0;margin-inline-end:var(--checkbox-gap)}.c-checkbox.c-checkbox--fill{align-items:stretch}.c-checkbox.c-checkbox--fill label{justify-content:space-between}.c-checkbox.c-checkbox--fill .c-checkbox-text{flex:0 1 auto}.c-checkbox:hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-hover-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox:hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-container-default))}}.c-checkbox:hover .c-checkbox-tick{transition:background-color var(--dt-motion-timing-200) var(--checkbox-motion-easing),border-color var(--dt-motion-timing-200) var(--checkbox-motion-easing)}.c-checkbox:active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-active-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox:active .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-container-default))}}.c-checkbox:active .c-checkbox-tick{transition:background-color var(--dt-motion-timing-100) var(--checkbox-motion-easing),border-color var(--dt-motion-timing-100) var(--checkbox-motion-easing)}.c-checkbox.is-disabled label{cursor:not-allowed}.c-checkbox input:focus-visible+label .c-checkbox-tick{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}.c-checkbox.is-disabled:hover .c-checkbox-tick,.c-checkbox.is-disabled:active .c-checkbox-tick{--checkbox-bg-color: var(--dt-color-container-strong);--checkbox-border-color: var(--dt-color-disabled-01)}.c-checkbox.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-hover-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-container-default))}}.c-checkbox.c-checkbox--status-error:active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-active-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.c-checkbox--status-error:active{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-container-default))}}.c-checkbox.is-checked:not(.is-disabled):hover .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) - var(--dt-color-hover-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked:not(.is-disabled):hover .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-interactive-brand));--checkbox-border-color: var(--checkbox-bg-color)}}.c-checkbox.is-checked.c-checkbox--status-error:hover .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) - var(--dt-color-hover-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked.c-checkbox--status-error:hover .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-support-error));--checkbox-border-color: var(--checkbox-bg-color)}}.c-checkbox.is-checked:not(.is-disabled):active .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) - var(--dt-color-active-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked:not(.is-disabled):active .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):active .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-interactive-brand));--checkbox-border-color: var(--checkbox-bg-color)}}.c-checkbox.is-checked.c-checkbox--status-error:active .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) - var(--dt-color-active-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked.c-checkbox--status-error:active .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:active .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-support-error));--checkbox-border-color: var(--checkbox-bg-color)}}', I = ["default", "success", "error"], L = ["leading", "trailing"], M = ["hug", "fill"], r = {
15
+ /**
16
+ * @license
17
+ * Copyright 2021 Google LLC
18
+ * SPDX-License-Identifier: BSD-3-Clause
19
+ */
20
+ let O = class extends Event {
21
+ constructor(c, i, a, t) {
22
+ super("context-request", { bubbles: !0, composed: !0 }), this.context = c, this.contextTarget = i, this.callback = a, this.subscribe = t ?? !1;
23
+ }
24
+ };
25
+ /**
26
+ * @license
27
+ * Copyright 2021 Google LLC
28
+ * SPDX-License-Identifier: BSD-3-Clause
29
+ */
30
+ class _ {
31
+ constructor(c, i, a, t) {
32
+ if (this.subscribe = !1, this.provided = !1, this.value = void 0, this.t = (s, b) => {
33
+ this.unsubscribe && (this.unsubscribe !== b && (this.provided = !1, this.unsubscribe()), this.subscribe || this.unsubscribe()), this.value = s, this.host.requestUpdate(), this.provided && !this.subscribe || (this.provided = !0, this.callback && this.callback(s, b)), this.unsubscribe = b;
34
+ }, this.host = c, i.context !== void 0) {
35
+ const s = i;
36
+ this.context = s.context, this.callback = s.callback, this.subscribe = s.subscribe ?? !1;
37
+ } else this.context = i, this.callback = a, this.subscribe = t ?? !1;
38
+ this.host.addController(this);
39
+ }
40
+ hostConnected() {
41
+ this.dispatchRequest();
42
+ }
43
+ hostDisconnected() {
44
+ this.unsubscribe && (this.unsubscribe(), this.unsubscribe = void 0);
45
+ }
46
+ dispatchRequest() {
47
+ this.host.dispatchEvent(new O(this.context, this.host, this.t, this.subscribe));
48
+ }
49
+ }
50
+ /**
51
+ * @license
52
+ * Copyright 2022 Google LLC
53
+ * SPDX-License-Identifier: BSD-3-Clause
54
+ */
55
+ function U({ context: e, subscribe: c }) {
56
+ return (i, a) => {
57
+ typeof a == "object" ? a.addInitializer((function() {
58
+ new _(this, { context: e, callback: (t) => {
59
+ i.set.call(this, t);
60
+ }, subscribe: c });
61
+ })) : i.constructor.addInitializer(((t) => {
62
+ new _(t, { context: e, callback: (s) => {
63
+ t[a] = s;
64
+ }, subscribe: c });
65
+ }));
66
+ };
67
+ }
68
+ const M = '*,*:after,*:before{box-sizing:inherit}:host{display:block;width:fit-content}:host([labelFit=fill]){width:100%}@keyframes checkboxCheck{0%{width:0;height:0;border-color:#fff;transform:translateZ(0) rotate(45deg)}33%{width:8px;height:0;transform:translateZ(0) rotate(45deg)}to{width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,1px) rotate(45deg)}}@keyframes scaleDown{0%{transform:scale(1)}to{transform:scale(0)}}@keyframes scaleUp{0%{transform:scale(0)}33%{transform:scale(.5)}to{transform:scale(1)}}.c-checkbox-tick{content:"";display:flex;flex:0 0 auto;width:var(--checkbox-width);height:var(--checkbox-height);margin:var(--checkbox-margin);border:1px solid var(--checkbox-border-color);border-radius:var(--checkbox-radius);background-color:var(--checkbox-bg-color)}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick{transition:background-color var(--dt-motion-timing-100) var(--checkbox-motion-easing),border-color var(--dt-motion-timing-100) var(--checkbox-motion-easing)}}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick.is-animated{animation:scaleDown var(--dt-motion-timing-100) var(--checkbox-motion-easing)}}.c-checkbox-tick.is-disabled{--checkbox-bg-color: var(--dt-color-container-strong);--checkbox-border-color: var(--dt-color-disabled-01)}.c-checkbox-tick.c-checkbox-tick--status-error{--checkbox-border-color: var(--dt-color-support-error)}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick.is-animated.is-checked{animation:scaleUp var(--dt-motion-timing-100) var(--checkbox-motion-easing)}}.c-checkbox-tick.is-checked:not(.is-disabled){--checkbox-bg-color: var(--dt-color-interactive-brand);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-checked.c-checkbox-tick--status-error{--checkbox-bg-color: var(--dt-color-support-error);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-checked:before{content:"";position:relative;top:55%;left:14%;border-right:2px solid transparent;border-bottom:2px solid transparent;transform:rotate(45deg);transform-origin:0% 100%}@media(prefers-reduced-motion:reduce){.c-checkbox-tick.is-checked:before{animation-duration:1ms!important;animation-delay:0!important;animation-iteration-count:1!important;width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,0) rotate(45deg)}}@media only percy{.c-checkbox-tick.is-checked:before{animation:none;width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,0) rotate(45deg)}}.c-checkbox-tick.is-checked.is-animated:before{animation:checkboxCheck var(--dt-motion-timing-150) var(--checkbox-motion-easing) forwards}.c-checkbox-tick.is-checked:not(.is-animated):before{width:8px;height:16px;border-color:#fff;border-bottom-right-radius:2px;transform:translate3d(0,-16px,0) rotate(45deg)}.c-checkbox-tick.is-checked:dir(rtl):before{left:unset;right:50%}.c-checkbox-tick.is-indeterminate:not(.is-disabled){--checkbox-bg-color: var(--dt-color-interactive-brand);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-indeterminate.c-checkbox-tick--status-error{--checkbox-bg-color: var(--dt-color-support-error);--checkbox-border-color: var(--checkbox-bg-color)}.c-checkbox-tick.is-indeterminate:after{width:16px}@media(prefers-reduced-motion:no-preference){.c-checkbox-tick.is-indeterminate:after{transition:width var(--dt-motion-timing-100) var(--checkbox-motion-easing) var(--dt-motion-timing-100)}}.c-checkbox-text{display:inline;flex:1 1 auto;align-self:center;min-width:0;margin-inline-start:var(--checkbox-gap);white-space:normal;color:var(--checkbox-content-color);font-family:var(--checkbox-font-family);font-size:var(--checkbox-font-size);line-height:var(--checkbox-line-height);font-weight:var(--checkbox-font-weight)}.c-checkbox-tick:after{content:"";position:relative;top:47%;left:14%;width:0;height:2px;background-color:#fff}.c-checkbox-tick:dir(rtl):after{left:unset;right:14%}.c-checkbox{--checkbox-height: 24px;--checkbox-width: 24px;--checkbox-radius: var(--dt-radius-rounded-a);--checkbox-margin: 1px;--checkbox-gap: var(--dt-spacing-b);--checkbox-font-family: var(--dt-font-body-l-family);--checkbox-font-size: calc(var(--dt-font-body-l-size) * 1px);--checkbox-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--checkbox-font-weight: var(--dt-font-body-l-weight);--checkbox-bg-color: var(--dt-color-container-default);--checkbox-border-color: var(--dt-color-border-form);--checkbox-content-color: var(--dt-color-content-default-solid);--checkbox-motion-easing: var(--dt-motion-easing-persistent-functional);display:flex;flex-direction:column;align-items:flex-start}.c-checkbox input{position:absolute;display:block;height:1px;width:1px;border:0;padding:0;margin:-1px;overflow:hidden;white-space:nowrap;clip:rect(0,0,0,0);clip-path:inset(50%)}.c-checkbox input *{overflow:hidden}.c-checkbox label{display:flex;width:100%;white-space:nowrap;cursor:pointer}.c-checkbox.c-checkbox--leading label{flex-direction:row-reverse}.c-checkbox.c-checkbox--leading .c-checkbox-text{margin-inline-start:0;margin-inline-end:var(--checkbox-gap)}.c-checkbox.c-checkbox--fill{align-items:stretch}.c-checkbox.c-checkbox--fill label{justify-content:space-between}.c-checkbox.c-checkbox--fill .c-checkbox-text{flex:0 1 auto}.c-checkbox:hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-hover-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox:hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-container-default))}}.c-checkbox:hover .c-checkbox-tick{transition:background-color var(--dt-motion-timing-200) var(--checkbox-motion-easing),border-color var(--dt-motion-timing-200) var(--checkbox-motion-easing)}.c-checkbox:active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-active-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox:active .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-container-default))}}.c-checkbox:active .c-checkbox-tick{transition:background-color var(--dt-motion-timing-100) var(--checkbox-motion-easing),border-color var(--dt-motion-timing-100) var(--checkbox-motion-easing)}.c-checkbox.is-disabled label{cursor:not-allowed}.c-checkbox input:focus-visible+label .c-checkbox-tick{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}.c-checkbox.is-disabled:hover .c-checkbox-tick,.c-checkbox.is-disabled:active .c-checkbox-tick{--checkbox-bg-color: var(--dt-color-container-strong);--checkbox-border-color: var(--dt-color-disabled-01)}.c-checkbox.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-hover-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-container-default))}}.c-checkbox.c-checkbox--status-error:active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) - var(--dt-color-active-01)) )}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.c-checkbox--status-error:active{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-container-default))}}.c-checkbox.is-checked:not(.is-disabled):hover .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) - var(--dt-color-hover-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked:not(.is-disabled):hover .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-interactive-brand));--checkbox-border-color: var(--checkbox-bg-color)}}.c-checkbox.is-checked.c-checkbox--status-error:hover .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) - var(--dt-color-hover-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked.c-checkbox--status-error:hover .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:hover .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-hover-01-bg) var(--dt-color-hover-01), var(--dt-color-support-error));--checkbox-border-color: var(--checkbox-bg-color)}}.c-checkbox.is-checked:not(.is-disabled):active .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) - var(--dt-color-active-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked:not(.is-disabled):active .c-checkbox-tick,.c-checkbox.is-indeterminate:not(.is-disabled):active .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-interactive-brand));--checkbox-border-color: var(--checkbox-bg-color)}}.c-checkbox.is-checked.c-checkbox--status-error:active .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:active .c-checkbox-tick{--checkbox-bg-color: hsl( var(--dt-color-support-error-h), var(--dt-color-support-error-s), calc(var(--dt-color-support-error-l) - var(--dt-color-active-01)) );--checkbox-border-color: var(--checkbox-bg-color)}@supports (background-color: color-mix(in srgb,black,white)){.c-checkbox.is-checked.c-checkbox--status-error:active .c-checkbox-tick,.c-checkbox.is-indeterminate.c-checkbox--status-error:active .c-checkbox-tick{--checkbox-bg-color: color-mix(in srgb, var(--dt-color-active-01-bg) var(--dt-color-active-01), var(--dt-color-support-error));--checkbox-border-color: var(--checkbox-bg-color)}}.c-checkbox--in-interactive-container{--checkbox-bg-color: transparent}', R = ["default", "success", "error"], V = ["leading", "trailing"], Z = ["hug", "fill"], l = {
16
69
  // a default value for the html <input type="checkbox" /> value attribute.
17
70
  // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#value
18
71
  value: "on",
@@ -25,24 +78,33 @@ const j = '*,*:after,*:before{box-sizing:inherit}:host{display:block;width:fit-c
25
78
  labelPosition: "trailing",
26
79
  labelFit: "hug"
27
80
  };
28
- var U = Object.defineProperty, V = Object.getOwnPropertyDescriptor, c = (e, t, l, s) => {
29
- for (var a = s > 1 ? void 0 : s ? V(t, l) : t, n = e.length - 1, d; n >= 0; n--)
30
- (d = e[n]) && (a = (s ? d(t, l, a) : d(a)) || a);
31
- return s && a && U(t, l, a), a;
81
+ var N = Object.defineProperty, G = Object.getOwnPropertyDescriptor, r = (e, c, i, a) => {
82
+ for (var t = a > 1 ? void 0 : a ? G(c, i) : c, s = e.length - 1, b; s >= 0; s--)
83
+ (b = e[s]) && (t = (a ? b(c, i, t) : b(t)) || t);
84
+ return a && t && N(c, i, t), t;
32
85
  };
33
- const m = "pie-checkbox", _ = "assistive-text";
34
- let o = class extends z(H(p)) {
86
+ const g = "pie-checkbox", C = "assistive-text";
87
+ let o = class extends T(H(p)) {
35
88
  constructor() {
36
- super(...arguments), this._disabledByParent = !1, this._visuallyHiddenError = !1, this._isAnimationAllowed = !1, this.value = r.value, this.checked = r.checked, this.defaultChecked = r.defaultChecked, this.disabled = r.disabled, this.required = r.required, this.indeterminate = r.indeterminate, this.status = r.status, this.labelPosition = r.labelPosition, this.labelFit = r.labelFit;
89
+ super(...arguments), this._disabledByParent = !1, this._visuallyHiddenError = !1, this._isAnimationAllowed = !1, this.value = l.value, this.checked = l.checked, this.defaultChecked = l.defaultChecked, this.disabled = l.disabled, this.required = l.required, this.indeterminate = l.indeterminate, this.status = l.status, this.labelPosition = l.labelPosition, this.labelFit = l.labelFit;
37
90
  }
38
91
  connectedCallback() {
39
92
  super.connectedCallback(), this._abortController = new AbortController();
40
93
  const { signal: e } = this._abortController;
41
- this.addEventListener("pie-checkbox-group-disabled", (t) => {
42
- this._disabledByParent = t.detail.disabled;
43
- }, { signal: e }), this.addEventListener("pie-checkbox-group-error", (t) => {
44
- this._visuallyHiddenError = t.detail.error;
45
- }, { signal: e });
94
+ this.addEventListener("pie-checkbox-group-disabled", (c) => {
95
+ this._disabledByParent = c.detail.disabled;
96
+ }, { signal: e }), this.addEventListener("pie-checkbox-group-error", (c) => {
97
+ this._visuallyHiddenError = c.detail.error;
98
+ }, { signal: e }), this.addEventListener("click", this._handleClick, { signal: e });
99
+ }
100
+ /**
101
+ * Forwards a click dispatched directly on the host (for example from a `pie-list-item` row)
102
+ * to the internal input. Clicks on the internal label already toggle the input natively via
103
+ * its `for` attribute, so only host-level clicks are forwarded, to avoid a double toggle.
104
+ * @param {MouseEvent} event
105
+ */
106
+ _handleClick(e) {
107
+ e.composedPath()[0] === this && (this.disabled || this._disabledByParent || this._checkbox.click());
46
108
  }
47
109
  disconnectedCallback() {
48
110
  super.disconnectedCallback(), this._abortController.abort();
@@ -70,17 +132,27 @@ let o = class extends z(H(p)) {
70
132
  this.disabled = e;
71
133
  }
72
134
  updated() {
73
- this._handleFormAssociation();
135
+ this._handleFormAssociation(), this._applyContextAria();
136
+ }
137
+ /**
138
+ * When an ancestor provides ARIA (for example a `pie-list-item`), applies the fields this
139
+ * control cares about to the internal input (the element that carries the checkbox semantics).
140
+ * Does nothing when used standalone, where the name comes from the default slot / label.
141
+ */
142
+ _applyContextAria() {
143
+ if (!this._checkbox) return;
144
+ const e = this._contextAria;
145
+ e != null && e.label ? this._checkbox.setAttribute("aria-label", e.label) : this._checkbox.removeAttribute("aria-label"), e != null && e.description ? this._checkbox.setAttribute("aria-description", e.description) : this._checkbox.removeAttribute("aria-description");
74
146
  }
75
147
  /**
76
148
  * Captures the native change event and wraps it in a custom event.
77
149
  * @param {Event} event - This should be the change event that was listened for on an input element with `type="checkbox"`.
78
150
  */
79
151
  _handleChange(e) {
80
- const { checked: t } = e == null ? void 0 : e.currentTarget;
81
- this.checked = t, this._isAnimationAllowed || (this._isAnimationAllowed = !0);
82
- const l = T(e);
83
- this.dispatchEvent(l), this._handleFormAssociation();
152
+ const { checked: c } = e == null ? void 0 : e.currentTarget;
153
+ this.checked = c, this._isAnimationAllowed || (this._isAnimationAllowed = !0);
154
+ const i = I(e);
155
+ this.dispatchEvent(i), this._handleFormAssociation();
84
156
  }
85
157
  /**
86
158
  * Called when the form that contains this component is reset.
@@ -97,125 +169,134 @@ let o = class extends z(H(p)) {
97
169
  render() {
98
170
  const {
99
171
  checked: e,
100
- value: t,
101
- name: l,
102
- disabled: s,
103
- _disabledByParent: a,
104
- _visuallyHiddenError: n,
105
- _isAnimationAllowed: d,
106
- required: C,
107
- indeterminate: x,
108
- assistiveText: v,
109
- status: h,
110
- labelPosition: A,
111
- labelFit: $
112
- } = this, b = s || a, F = {
172
+ value: c,
173
+ name: i,
174
+ disabled: a,
175
+ _disabledByParent: t,
176
+ _visuallyHiddenError: s,
177
+ _isAnimationAllowed: b,
178
+ required: A,
179
+ indeterminate: v,
180
+ assistiveText: u,
181
+ status: d,
182
+ labelPosition: $,
183
+ labelFit: P
184
+ } = this, h = a || t, F = {
113
185
  "c-checkbox": !0,
114
- [`c-checkbox--status-${h}`]: !b,
115
- "is-disabled": b,
186
+ [`c-checkbox--status-${d}`]: !h,
187
+ "is-disabled": h,
116
188
  "is-checked": e,
117
- "is-indeterminate": x && !e,
118
- "c-checkbox--leading": A === "leading",
119
- "c-checkbox--fill": $ === "fill"
120
- }, P = {
189
+ "is-indeterminate": v && !e,
190
+ "c-checkbox--leading": $ === "leading",
191
+ "c-checkbox--fill": P === "fill",
192
+ // Inside a `pie-list-item` the whole row is the hit target and tints on hover/active.
193
+ // A transparent tick lets that row tint show through the (unchecked) box, matching
194
+ // how the radio behaves. Only applies in a list item, so standalone checkboxes are
195
+ // unaffected.
196
+ "c-checkbox--in-interactive-container": !!this._contextAria
197
+ }, E = {
121
198
  "c-checkbox-tick": !0,
122
- [`c-checkbox-tick--status-${h}`]: !b,
123
- "is-disabled": b,
199
+ [`c-checkbox-tick--status-${d}`]: !h,
200
+ "is-disabled": h,
124
201
  "is-checked": e,
125
- "is-indeterminate": x && !e,
126
- "is-animated": d
202
+ "is-indeterminate": v && !e,
203
+ "is-animated": b
127
204
  };
128
- return f`
205
+ return m`
129
206
  <div
130
207
  class="${y(F)}">
131
208
  <input
132
209
  type="checkbox"
133
210
  id="inputId"
134
- .value=${t}
135
- .checked=${q(e)}
136
- name=${w(l)}
137
- ?disabled=${b}
138
- ?required=${C}
139
- .indeterminate=${x}
140
- aria-invalid=${h === "error" ? "true" : "false"}
141
- aria-describedby=${w(v ? _ : void 0)}
211
+ .value=${c}
212
+ .checked=${z(e)}
213
+ name=${w(i)}
214
+ ?disabled=${h}
215
+ ?required=${A}
216
+ .indeterminate=${v}
217
+ aria-invalid=${d === "error" ? "true" : "false"}
218
+ aria-describedby=${w(u ? C : void 0)}
142
219
  @change=${this._handleChange}
143
220
  data-test-id="pie-checkbox-input"
144
221
  />
145
222
  <label for="inputId" data-test-id="pie-checkbox-label">
146
223
  <span
147
- class="${y(P)}"></span>
224
+ class="${y(E)}"></span>
148
225
  <span class="c-checkbox-text">
149
226
  <slot></slot>
150
227
  </span>
151
228
  </label>
152
- ${v ? f`
229
+ ${u ? m`
153
230
  <pie-assistive-text
154
- id="${_}"
155
- variant=${h}
156
- ?isVisuallyHidden=${n}
157
- message=${v}
231
+ id="${C}"
232
+ variant=${d}
233
+ ?isVisuallyHidden=${s}
234
+ message=${u}
158
235
  data-test-id="pie-checkbox-assistive-text">
159
236
  </pie-assistive-text>` : B}
160
237
  </div>`;
161
238
  }
162
239
  };
163
- o.styles = S(j);
164
- c([
165
- u()
240
+ o.styles = D(M);
241
+ r([
242
+ x()
166
243
  ], o.prototype, "_disabledByParent", 2);
167
- c([
168
- u()
244
+ r([
245
+ x()
169
246
  ], o.prototype, "_visuallyHiddenError", 2);
170
- c([
171
- u()
247
+ r([
248
+ x()
172
249
  ], o.prototype, "_isAnimationAllowed", 2);
173
- c([
174
- i({ type: String })
250
+ r([
251
+ U({ context: L, subscribe: !0 }),
252
+ x()
253
+ ], o.prototype, "_contextAria", 2);
254
+ r([
255
+ n({ type: String })
175
256
  ], o.prototype, "value", 2);
176
- c([
177
- i({ type: String, reflect: !0 })
257
+ r([
258
+ n({ type: String, reflect: !0 })
178
259
  ], o.prototype, "name", 2);
179
- c([
180
- i({ type: Boolean, reflect: !0 })
260
+ r([
261
+ n({ type: Boolean, reflect: !0 })
181
262
  ], o.prototype, "checked", 2);
182
- c([
183
- i({ type: Boolean, reflect: !0 })
263
+ r([
264
+ n({ type: Boolean, reflect: !0 })
184
265
  ], o.prototype, "defaultChecked", 2);
185
- c([
186
- i({ type: Boolean, reflect: !0 })
266
+ r([
267
+ n({ type: Boolean, reflect: !0 })
187
268
  ], o.prototype, "disabled", 2);
188
- c([
189
- i({ type: Boolean, reflect: !0 })
269
+ r([
270
+ n({ type: Boolean, reflect: !0 })
190
271
  ], o.prototype, "required", 2);
191
- c([
192
- i({ type: Boolean, reflect: !0 })
272
+ r([
273
+ n({ type: Boolean, reflect: !0 })
193
274
  ], o.prototype, "indeterminate", 2);
194
- c([
195
- D('input[type="checkbox"]')
275
+ r([
276
+ S('input[type="checkbox"]')
196
277
  ], o.prototype, "_checkbox", 2);
197
- c([
198
- i({ type: String })
278
+ r([
279
+ n({ type: String })
199
280
  ], o.prototype, "assistiveText", 2);
200
- c([
201
- i({ type: String }),
202
- g(m, I, r.status)
281
+ r([
282
+ n({ type: String }),
283
+ f(g, R, l.status)
203
284
  ], o.prototype, "status", 2);
204
- c([
205
- i({ type: String, reflect: !0 }),
206
- g(m, L, r.labelPosition)
285
+ r([
286
+ n({ type: String, reflect: !0 }),
287
+ f(g, V, l.labelPosition)
207
288
  ], o.prototype, "labelPosition", 2);
208
- c([
209
- i({ type: String, reflect: !0 }),
210
- g(m, M, r.labelFit)
289
+ r([
290
+ n({ type: String, reflect: !0 }),
291
+ f(g, Z, l.labelFit)
211
292
  ], o.prototype, "labelFit", 2);
212
- o = c([
213
- O("pie-checkbox")
293
+ o = r([
294
+ j("pie-checkbox")
214
295
  ], o);
215
296
  export {
216
297
  o as PieCheckbox,
217
- r as defaultProps,
218
- M as labelFits,
219
- L as labelPositions,
220
- I as statusTypes
298
+ l as defaultProps,
299
+ Z as labelFits,
300
+ V as labelPositions,
301
+ R as statusTypes
221
302
  };
package/dist/react.d.ts CHANGED
@@ -73,6 +73,7 @@ declare class PieCheckbox_2 extends PieCheckbox_base implements CheckboxProps {
73
73
  private _disabledByParent;
74
74
  private _visuallyHiddenError;
75
75
  private _isAnimationAllowed;
76
+ private _contextAria?;
76
77
  value: string;
77
78
  name: CheckboxProps['name'];
78
79
  checked: boolean;
@@ -87,6 +88,13 @@ declare class PieCheckbox_2 extends PieCheckbox_base implements CheckboxProps {
87
88
  labelFit: "hug" | "fill";
88
89
  private _abortController;
89
90
  connectedCallback(): void;
91
+ /**
92
+ * Forwards a click dispatched directly on the host (for example from a `pie-list-item` row)
93
+ * to the internal input. Clicks on the internal label already toggle the input natively via
94
+ * its `for` attribute, so only host-level clicks are forwarded, to avoid a double toggle.
95
+ * @param {MouseEvent} event
96
+ */
97
+ private _handleClick;
90
98
  disconnectedCallback(): void;
91
99
  /**
92
100
  * (Read-only) returns a ValidityState with the validity states that this element is in.
@@ -105,6 +113,12 @@ declare class PieCheckbox_2 extends PieCheckbox_base implements CheckboxProps {
105
113
  */
106
114
  formDisabledCallback(disabled: boolean): void;
107
115
  protected updated(): void;
116
+ /**
117
+ * When an ancestor provides ARIA (for example a `pie-list-item`), applies the fields this
118
+ * control cares about to the internal input (the element that carries the checkbox semantics).
119
+ * Does nothing when used standalone, where the name comes from the default slot / label.
120
+ */
121
+ private _applyContextAria;
108
122
  /**
109
123
  * Captures the native change event and wraps it in a custom event.
110
124
  * @param {Event} event - This should be the change event that was listened for on an input element with `type="checkbox"`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-checkbox",
3
3
  "description": "PIE Design System Checkbox built using Web Components",
4
- "version": "1.3.5",
4
+ "version": "1.4.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/justeattakeaway/pie",
@@ -45,11 +45,12 @@
45
45
  "devDependencies": {
46
46
  "@justeattakeaway/pie-components-config": "0.21.3",
47
47
  "@justeattakeaway/pie-css": "1.3.1",
48
- "@justeattakeaway/pie-monorepo-utils": "0.9.7"
48
+ "@justeattakeaway/pie-monorepo-utils": "0.9.8"
49
49
  },
50
50
  "dependencies": {
51
- "@justeattakeaway/pie-assistive-text": "1.0.5",
52
- "@justeattakeaway/pie-webc-core": "16.0.0"
51
+ "@justeattakeaway/pie-assistive-text": "1.0.6",
52
+ "@justeattakeaway/pie-webc-core": "16.1.0",
53
+ "@lit/context": "1.1.6"
53
54
  },
54
55
  "customElements": "custom-elements.json",
55
56
  "sideEffects": [
package/src/checkbox.scss CHANGED
@@ -418,3 +418,13 @@
418
418
  }
419
419
  }
420
420
  }
421
+
422
+ // Inside an interactive container (such as a `pie-list-item`) the whole container is the interactive
423
+ // hit target and tints on hover/active. Making the resting (unchecked) tick background transparent
424
+ // lets that container tint show through the box, matching the radio (whose control background is
425
+ // transparent too). The tick-level rules for checked / indeterminate / disabled / direct hover
426
+ // still set their own background, so only the resting unchecked state changes, and only when inside
427
+ // such a container.
428
+ .c-checkbox--in-interactive-container {
429
+ --checkbox-bg-color: transparent;
430
+ }
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
4
4
  import { property, query, state } from 'lit/decorators.js';
5
5
  import { ifDefined } from 'lit/directives/if-defined.js';
6
6
  import { live } from 'lit/directives/live.js';
7
+ import { consume } from '@lit/context';
7
8
 
8
9
  import {
9
10
  wrapNativeEvent,
@@ -11,6 +12,8 @@ import {
11
12
  DelegatesFocusMixin,
12
13
  validPropertyValues,
13
14
  safeCustomElement,
15
+ ariaContext,
16
+ type ContextualAria,
14
17
  } from '@justeattakeaway/pie-webc-core';
15
18
  import '@justeattakeaway/pie-assistive-text';
16
19
 
@@ -41,6 +44,13 @@ export class PieCheckbox extends DelegatesFocusMixin(FormControlMixin(PieElement
41
44
  @state()
42
45
  private _isAnimationAllowed = false;
43
46
 
47
+ // Optional ARIA supplied by an ancestor (for example a `pie-list-item`), applied to the
48
+ // internal input (the element carrying the checkbox semantics). Undefined when standalone, so
49
+ // it has no effect there.
50
+ @consume({ context: ariaContext, subscribe: true })
51
+ @state()
52
+ private _contextAria?: ContextualAria;
53
+
44
54
  @property({ type: String })
45
55
  public value = defaultProps.value;
46
56
 
@@ -90,6 +100,23 @@ export class PieCheckbox extends DelegatesFocusMixin(FormControlMixin(PieElement
90
100
 
91
101
  this.addEventListener('pie-checkbox-group-disabled', (e: CustomEventInit) => { this._disabledByParent = e.detail.disabled; }, { signal });
92
102
  this.addEventListener('pie-checkbox-group-error', (e: CustomEventInit) => { this._visuallyHiddenError = e.detail.error; }, { signal });
103
+
104
+ // Allows a click dispatched on the host (for example forwarded from a `pie-list-item`
105
+ // row) to toggle the checkbox.
106
+ this.addEventListener('click', this._handleClick, { signal });
107
+ }
108
+
109
+ /**
110
+ * Forwards a click dispatched directly on the host (for example from a `pie-list-item` row)
111
+ * to the internal input. Clicks on the internal label already toggle the input natively via
112
+ * its `for` attribute, so only host-level clicks are forwarded, to avoid a double toggle.
113
+ * @param {MouseEvent} event
114
+ */
115
+ private _handleClick (event: MouseEvent): void {
116
+ if (event.composedPath()[0] !== this) return;
117
+ if (this.disabled || this._disabledByParent) return;
118
+
119
+ this._checkbox.click();
93
120
  }
94
121
 
95
122
  disconnectedCallback () : void {
@@ -127,6 +154,29 @@ export class PieCheckbox extends DelegatesFocusMixin(FormControlMixin(PieElement
127
154
 
128
155
  protected updated (): void {
129
156
  this._handleFormAssociation();
157
+ this._applyContextAria();
158
+ }
159
+
160
+ /**
161
+ * When an ancestor provides ARIA (for example a `pie-list-item`), applies the fields this
162
+ * control cares about to the internal input (the element that carries the checkbox semantics).
163
+ * Does nothing when used standalone, where the name comes from the default slot / label.
164
+ */
165
+ private _applyContextAria (): void {
166
+ if (!this._checkbox) return;
167
+ const aria = this._contextAria;
168
+
169
+ if (aria?.label) {
170
+ this._checkbox.setAttribute('aria-label', aria.label);
171
+ } else {
172
+ this._checkbox.removeAttribute('aria-label');
173
+ }
174
+
175
+ if (aria?.description) {
176
+ this._checkbox.setAttribute('aria-description', aria.description);
177
+ } else {
178
+ this._checkbox.removeAttribute('aria-description');
179
+ }
130
180
  }
131
181
 
132
182
  /**
@@ -192,6 +242,11 @@ export class PieCheckbox extends DelegatesFocusMixin(FormControlMixin(PieElement
192
242
  'is-indeterminate': indeterminate && !checked,
193
243
  'c-checkbox--leading': labelPosition === 'leading',
194
244
  'c-checkbox--fill': labelFit === 'fill',
245
+ // Inside a `pie-list-item` the whole row is the hit target and tints on hover/active.
246
+ // A transparent tick lets that row tint show through the (unchecked) box, matching
247
+ // how the radio behaves. Only applies in a list item, so standalone checkboxes are
248
+ // unaffected.
249
+ 'c-checkbox--in-interactive-container': Boolean(this._contextAria),
195
250
  };
196
251
 
197
252
  const labelClasses = {