@crowdstrike/glide-core 0.29.2 → 0.30.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.
Files changed (122) hide show
  1. package/dist/accordion.js +240 -1
  2. package/dist/accordion.styles.js +13 -7
  3. package/dist/button-group.button.js +143 -1
  4. package/dist/button-group.button.styles.js +43 -15
  5. package/dist/button-group.js +249 -1
  6. package/dist/button-group.styles.js +10 -5
  7. package/dist/button.js +206 -1
  8. package/dist/button.styles.js +12 -7
  9. package/dist/checkbox-group.js +479 -14
  10. package/dist/checkbox-group.styles.js +5 -2
  11. package/dist/checkbox.js +519 -32
  12. package/dist/checkbox.styles.js +10 -5
  13. package/dist/drawer.js +168 -1
  14. package/dist/drawer.styles.js +5 -2
  15. package/dist/dropdown.js +2423 -123
  16. package/dist/dropdown.option.js +536 -1
  17. package/dist/dropdown.option.styles.js +5 -2
  18. package/dist/dropdown.styles.js +14 -7
  19. package/dist/form-controls-layout.js +102 -1
  20. package/dist/form-controls-layout.styles.js +5 -2
  21. package/dist/icon-button.js +139 -1
  22. package/dist/icon-button.styles.js +19 -7
  23. package/dist/icons/checked.js +28 -1
  24. package/dist/icons/chevron.js +21 -1
  25. package/dist/icons/magnifying-glass.js +23 -1
  26. package/dist/icons/pencil.js +21 -1
  27. package/dist/icons/severity-critical.js +20 -1
  28. package/dist/icons/severity-informational.js +20 -1
  29. package/dist/icons/severity-medium.js +20 -1
  30. package/dist/icons/x.js +21 -1
  31. package/dist/inline-alert.js +118 -1
  32. package/dist/inline-alert.styles.js +5 -2
  33. package/dist/input.d.ts +8 -2
  34. package/dist/input.js +505 -41
  35. package/dist/input.styles.js +25 -4
  36. package/dist/label.js +303 -1
  37. package/dist/label.styles.js +11 -5
  38. package/dist/library/assert-slot.js +136 -1
  39. package/dist/library/expect-unhandled-rejection.js +14 -1
  40. package/dist/library/expect-window-error.js +26 -1
  41. package/dist/library/final.js +18 -1
  42. package/dist/library/form-control.js +1 -1
  43. package/dist/library/localize.js +10 -1
  44. package/dist/library/mouse.js +35 -1
  45. package/dist/library/on-resize.js +24 -1
  46. package/dist/library/required.js +35 -1
  47. package/dist/library/shadow-root-mode.js +4 -1
  48. package/dist/library/unique-id.js +3 -1
  49. package/dist/link.js +92 -1
  50. package/dist/link.styles.js +10 -5
  51. package/dist/menu.d.ts +3 -2
  52. package/dist/menu.js +1259 -1
  53. package/dist/menu.styles.js +34 -17
  54. package/dist/modal.d.ts +4 -0
  55. package/dist/modal.icon-button.js +60 -1
  56. package/dist/modal.icon-button.styles.js +5 -2
  57. package/dist/modal.js +473 -1
  58. package/dist/modal.styles.js +71 -22
  59. package/dist/option.d.ts +74 -0
  60. package/dist/option.js +498 -0
  61. package/dist/option.styles.js +140 -0
  62. package/dist/{menu.options.d.ts → options.d.ts} +5 -6
  63. package/dist/options.js +130 -0
  64. package/dist/options.styles.js +21 -0
  65. package/dist/popover.js +620 -1
  66. package/dist/popover.styles.js +11 -5
  67. package/dist/radio-group.js +624 -17
  68. package/dist/radio-group.radio.js +211 -1
  69. package/dist/radio-group.radio.styles.js +9 -4
  70. package/dist/radio-group.styles.js +5 -2
  71. package/dist/slider.js +1040 -61
  72. package/dist/slider.styles.js +9 -4
  73. package/dist/spinner.js +60 -1
  74. package/dist/spinner.styles.js +5 -2
  75. package/dist/split-button.js +116 -1
  76. package/dist/split-button.primary-button.js +100 -1
  77. package/dist/split-button.primary-button.styles.js +13 -6
  78. package/dist/split-button.primary-link.js +102 -1
  79. package/dist/split-button.secondary-button.d.ts +2 -3
  80. package/dist/split-button.secondary-button.js +121 -1
  81. package/dist/split-button.secondary-button.styles.js +12 -7
  82. package/dist/split-button.styles.js +9 -4
  83. package/dist/styles/focus-outline.js +9 -3
  84. package/dist/styles/fonts.css +6 -1
  85. package/dist/styles/opacity-and-scale-animation.js +6 -3
  86. package/dist/styles/skeleton.js +6 -3
  87. package/dist/styles/variables.css +410 -1
  88. package/dist/styles/visually-hidden.js +6 -3
  89. package/dist/tab.group.js +386 -1
  90. package/dist/tab.group.styles.js +5 -2
  91. package/dist/tab.js +133 -1
  92. package/dist/tab.panel.js +93 -1
  93. package/dist/tab.panel.styles.js +11 -5
  94. package/dist/tab.styles.js +9 -4
  95. package/dist/tag.js +207 -1
  96. package/dist/tag.styles.js +10 -5
  97. package/dist/textarea.js +353 -19
  98. package/dist/textarea.styles.js +23 -4
  99. package/dist/toast.js +130 -1
  100. package/dist/toast.toasts.js +248 -25
  101. package/dist/toast.toasts.styles.js +9 -4
  102. package/dist/toggle.js +178 -1
  103. package/dist/toggle.styles.js +25 -5
  104. package/dist/tooltip.container.js +130 -1
  105. package/dist/tooltip.container.styles.js +5 -2
  106. package/dist/tooltip.js +484 -1
  107. package/dist/tooltip.styles.js +21 -5
  108. package/dist/translations/en.js +36 -1
  109. package/dist/translations/fr.js +37 -1
  110. package/dist/translations/ja.js +37 -1
  111. package/package.json +8 -12
  112. package/dist/menu.button.d.ts +0 -42
  113. package/dist/menu.button.js +0 -1
  114. package/dist/menu.button.styles.js +0 -32
  115. package/dist/menu.link.d.ts +0 -44
  116. package/dist/menu.link.js +0 -1
  117. package/dist/menu.link.styles.js +0 -35
  118. package/dist/menu.options.js +0 -1
  119. package/dist/menu.options.styles.d.ts +0 -2
  120. package/dist/menu.options.styles.js +0 -20
  121. /package/dist/{menu.button.styles.d.ts → option.styles.d.ts} +0 -0
  122. /package/dist/{menu.link.styles.d.ts → options.styles.d.ts} +0 -0
@@ -1,59 +1,273 @@
1
- var __decorate=this&&this.__decorate||function(t,e,i,s){var o,r=arguments.length,a=r<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,i):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,i,s);else for(var n=t.length-1;n>=0;n--)(o=t[n])&&(a=(r<3?o(a):r>3?o(e,i,a):o(e,i))||a);return r>3&&a&&Object.defineProperty(e,i,a),a};import"./icon-button.js";import{html,LitElement}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{classMap}from"lit/directives/class-map.js";import{styleMap}from"lit/directives/style-map.js";import{choose}from"lit/directives/choose.js";import{when}from"lit/directives/when.js";import{unsafeHTML}from"lit/directives/unsafe-html.js";import xIcon from"./icons/x.js";import{LocalizeController}from"./library/localize.js";import styles from"./toast.toasts.styles.js";import shadowRootMode from"./library/shadow-root-mode.js";import final from"./library/final.js";import Toast from"./toast.js";import Link from"./link.js";let Toasts=class Toasts extends LitElement{constructor(){super(...arguments),this.toasts=[],this.#t=createRef(),this.#e=new LocalizeController(this)}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:shadowRootMode}}static{this.styles=styles}dismiss(t){const e=this.toasts.indexOf(t);this.toasts=[...this.toasts.slice(0,e),...this.toasts.slice(e+1)],t.dismiss(),0===this.toasts.length&&this.remove()}firstUpdated(){this.#t.value&&(this.#t.value.popover="manual")}render(){return html`<div
2
- aria-label=${this.#e.term("notifications")}
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import './icon-button.js';
8
+ import { html, LitElement } from 'lit';
9
+ import { createRef, ref } from 'lit/directives/ref.js';
10
+ import { customElement, property } from 'lit/decorators.js';
11
+ import { repeat } from 'lit/directives/repeat.js';
12
+ import { classMap } from 'lit/directives/class-map.js';
13
+ import { styleMap } from 'lit/directives/style-map.js';
14
+ import { choose } from 'lit/directives/choose.js';
15
+ import { when } from 'lit/directives/when.js';
16
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
17
+ import xIcon from './icons/x.js';
18
+ import { LocalizeController } from './library/localize.js';
19
+ import styles from './toast.toasts.styles.js';
20
+ import shadowRootMode from './library/shadow-root-mode.js';
21
+ import final from './library/final.js';
22
+ import Toast from './toast.js';
23
+ import Link from './link.js';
24
+ /**
25
+ * @attr {Toast[]} [toasts=[]]
26
+ *
27
+ * @method dismiss
28
+ * @param {Toast} toast
29
+ *
30
+ * @method show
31
+ * @param {Toast} toast
32
+ * @returns Promise<void>
33
+ *
34
+ * @method showPopover
35
+ */
36
+ let Toasts = class Toasts extends LitElement {
37
+ constructor() {
38
+ super(...arguments);
39
+ this.toasts = [];
40
+ this.#componentElementRef = createRef();
41
+ this.#localize = new LocalizeController(this);
42
+ }
43
+ static { this.shadowRootOptions = {
44
+ ...LitElement.shadowRootOptions,
45
+ mode: shadowRootMode,
46
+ }; }
47
+ static { this.styles = styles; }
48
+ dismiss(toast) {
49
+ const index = this.toasts.indexOf(toast);
50
+ this.toasts = [
51
+ ...this.toasts.slice(0, index),
52
+ ...this.toasts.slice(index + 1),
53
+ ];
54
+ toast.dismiss();
55
+ if (this.toasts.length === 0) {
56
+ this.remove();
57
+ }
58
+ }
59
+ firstUpdated() {
60
+ if (this.#componentElementRef.value) {
61
+ this.#componentElementRef.value.popover = 'manual';
62
+ }
63
+ }
64
+ render() {
65
+ // Lit-ally doesn't know that our "mouseover" listener is only an affordance for
66
+ // mouse users. It also doesn't know that the purpose of the "click" listener on
67
+ // ".description" is only so that we can programmatically click the consumer's
68
+ // Toast.
69
+ //
70
+ /* eslint-disable lit-a11y/click-events-have-key-events, lit-a11y/mouse-events-have-key-events */
71
+ return html `<div
72
+ aria-label=${this.#localize.term('notifications')}
3
73
  class="component"
4
74
  data-test="component"
5
75
  role="region"
6
76
  tabindex="-1"
7
- ${ref(this.#t)}
77
+ ${ref(this.#componentElementRef)}
8
78
  >
9
79
  <div class="toasts">
10
- ${repeat(this.toasts,(t=>t.privateId),(t=>html`<div
80
+ ${repeat(this.toasts, (toast) => toast.privateId, (toast) => {
81
+ return html `<div
11
82
  aria-labelledby="prefix label description"
12
- class=${classMap({toast:!0,error:"error"===t.variant,informational:"informational"===t.variant,success:"success"===t.variant,show:Boolean(t.privateShow),dismissing:Boolean(t.privateDismissing),"dismissing-via-button":Boolean(t.privateDismissingViaButton)})}
83
+ class=${classMap({
84
+ toast: true,
85
+ error: toast.variant === 'error',
86
+ informational: toast.variant === 'informational',
87
+ success: toast.variant === 'success',
88
+ show: Boolean(toast.privateShow),
89
+ dismissing: Boolean(toast.privateDismissing),
90
+ 'dismissing-via-button': Boolean(toast.privateDismissingViaButton),
91
+ })}
13
92
  data-test="toast"
14
93
  role="alert"
15
- @mouseover=${this.#i.bind(this,t)}
16
- @mouseout=${this.#s.bind(this,t)}
17
- @transitionend=${this.#o.bind(this,t)}
94
+ @mouseover=${this.#onToastMouseOver.bind(this, toast)}
95
+ @mouseout=${this.#onToastMouseOut.bind(this, toast)}
96
+ @transitionend=${this.#onToastTransitionEnd.bind(this, toast)}
18
97
  >
19
98
  <span class="prefix" id="prefix">
20
- ${this.#e.term(t.variant)}
99
+ ${this.#localize.term(toast.variant)}
21
100
  </span>
22
101
 
23
- ${choose(t.variant,[["success",()=>icons.success],["error",()=>icons.error]],(()=>icons.warningInformational))}
102
+ ${choose(toast.variant, [
103
+ ['success', () => icons.success],
104
+ ['error', () => icons.error],
105
+ ], () => icons.warningInformational)}
24
106
 
25
107
  <div class="label" data-test="label" id="label">
26
- ${t.label}
108
+ ${toast.label}
27
109
  </div>
28
110
 
29
111
  <glide-core-icon-button
30
112
  class="dismiss-button"
31
113
  data-test="dismiss-button"
32
- label=${this.#e.term("dismiss")}
114
+ label=${this.#localize.term('dismiss')}
33
115
  variant="tertiary"
34
- @click=${this.#r.bind(this,t)}
116
+ @click=${this.#onToastDismissButtonClick.bind(this, toast)}
35
117
  >
36
118
  ${xIcon}
37
119
  </glide-core-icon-button>
38
120
 
39
- ${when(t.privateDescription,(()=>html`
121
+ ${when(toast.privateDescription, () => {
122
+ return html `
40
123
  <div
41
124
  class="description"
42
125
  data-test="description"
43
126
  id="description"
44
- @click=${this.#a.bind(this,t)}
127
+ @click=${this.#onDescriptionClick.bind(this, toast)}
45
128
  >
46
- ${unsafeHTML(t.privateDescription)}
129
+ ${unsafeHTML(toast.privateDescription)}
47
130
  </div>
48
- `))}
49
- </div>`))}
131
+ `;
132
+ })}
133
+ </div>`;
134
+ })}
50
135
  </div>
51
- </div>`}showPopover(){this.#t.value?.showPopover()}static async show(t){let e=document.querySelector("glide-core-private-toasts");if(e||(e=document.createElement("glide-core-private-toasts"),document.body.append(e)),t.childNodes.length>0){let e="";for(const i of t.childNodes)i instanceof Element?e+=i.outerHTML:i instanceof Text&&(e+=i.textContent);t.privateDescription=e.trim()}e.toasts=[t,...e.toasts],await e.updateComplete,e.showPopover(),t.privateShow=!0,setTimeout((()=>{e.requestUpdate()})),t.duration<Number.POSITIVE_INFINITY&&(t.privateTimeoutId=setTimeout((()=>{window.matchMedia("(prefers-reduced-motion: reduce)").matches?e?.dismiss(t):(t.privateDismissing=!0,e.requestUpdate())}),t.duration))}#t;#e;#a(t,e){e.target instanceof Link&&e.preventDefault();const i=[...t.querySelectorAll("*")].find((t=>{if(e.target instanceof Link)return t instanceof Link&&t.label===e.target.label&&t.href===e.target.href}));i instanceof Link&&i.click()}#r(t){window.matchMedia("(prefers-reduced-motion: reduce)").matches?this.dismiss(t):(t.privateDismissing=!0,t.privateDismissingViaButton=!0,this.requestUpdate())}#s(t){t.duration<Number.POSITIVE_INFINITY&&(t.privateTimeoutId=setTimeout((()=>{window.matchMedia("(prefers-reduced-motion: reduce)").matches?this.dismiss(t):(t.privateDismissing=!0,this.requestUpdate())}),t.duration))}#i(t){clearTimeout(t.privateTimeoutId)}#o(t){document.querySelector("glide-core-private-toasts")&&t.privateDismissing&&this.dismiss(t)}};__decorate([property({type:Array})],Toasts.prototype,"toasts",void 0),Toasts=__decorate([customElement("glide-core-private-toasts"),final],Toasts);export default Toasts;const icons={error:html`<svg
136
+ </div>`;
137
+ }
138
+ showPopover() {
139
+ this.#componentElementRef.value?.showPopover();
140
+ }
141
+ static async show(toast) {
142
+ let toasts = document.querySelector('glide-core-private-toasts');
143
+ if (!toasts) {
144
+ toasts = document.createElement('glide-core-private-toasts');
145
+ document.body.append(toasts);
146
+ }
147
+ if (toast.childNodes.length > 0) {
148
+ let description = '';
149
+ // Toast's inner HTML will include comments (`<!--?lit$277222571$-->`) used by
150
+ // Lit in rendering. There's a good chance Lit will misbehave if we copy those
151
+ // comments. So, to be safe, we only copy Element and Text nodes.
152
+ for (const node of toast.childNodes) {
153
+ if (node instanceof Element) {
154
+ description += node.outerHTML;
155
+ }
156
+ else if (node instanceof Text) {
157
+ description += node.textContent;
158
+ }
159
+ }
160
+ toast.privateDescription = description.trim();
161
+ }
162
+ toasts.toasts = [toast, ...toasts.toasts];
163
+ // The transition won't play if the toast is added to the DOM in the same
164
+ // tick that the `.show` class is added to `.toast`. So we first add the
165
+ // toast to the DOM (above), then we set `privateShow` to apply the class.
166
+ // Then we force a render in the next frame (below).
167
+ await toasts.updateComplete;
168
+ toasts.showPopover();
169
+ toast.privateShow = true;
170
+ setTimeout(() => {
171
+ // Because `privateShow` is only a reactive property of Toast, Toasts won't
172
+ // know it needs to rerender. So we let it know.
173
+ toasts.requestUpdate();
174
+ });
175
+ if (toast.duration < Number.POSITIVE_INFINITY) {
176
+ toast.privateTimeoutId = setTimeout(() => {
177
+ const isReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
178
+ if (isReducedMotion) {
179
+ toasts?.dismiss(toast);
180
+ }
181
+ else {
182
+ toast.privateDismissing = true;
183
+ // Because `privateDismissing` is only a reactive property of Toast, Toasts won't
184
+ // know it needs to rerender. So we let it know.
185
+ toasts.requestUpdate();
186
+ }
187
+ }, toast.duration);
188
+ }
189
+ }
190
+ #componentElementRef;
191
+ #localize;
192
+ #onDescriptionClick(toast, event) {
193
+ // We want to let the consumer decide if navigation should occur. So we
194
+ // cancel the event here, and then programmatically click the consumer's
195
+ // link. The consumer can cancel that link's "click" event if he wants to
196
+ // prevent navigation.
197
+ if (event.target instanceof Link) {
198
+ event.preventDefault();
199
+ }
200
+ const link = [...toast.querySelectorAll('*')].find((element) => {
201
+ if (event.target instanceof Link) {
202
+ return (element instanceof Link &&
203
+ element.label === event.target.label &&
204
+ element.href === event.target.href);
205
+ }
206
+ });
207
+ if (link instanceof Link) {
208
+ link.click();
209
+ }
210
+ }
211
+ #onToastDismissButtonClick(toast) {
212
+ const isReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
213
+ if (isReducedMotion) {
214
+ this.dismiss(toast);
215
+ }
216
+ else {
217
+ toast.privateDismissing = true;
218
+ toast.privateDismissingViaButton = true;
219
+ // Because `privateDismissing` and `privateDismissViaButton` are only reactive
220
+ // properties of Toast, Toasts won't know it needs to rerender. So we let it know.
221
+ this.requestUpdate();
222
+ }
223
+ }
224
+ #onToastMouseOut(toast) {
225
+ if (toast.duration < Number.POSITIVE_INFINITY) {
226
+ toast.privateTimeoutId = setTimeout(() => {
227
+ const isReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
228
+ if (isReducedMotion) {
229
+ this.dismiss(toast);
230
+ }
231
+ else {
232
+ toast.privateDismissing = true;
233
+ // Because `privateDismissing` is only a reactive property of Toast, Toasts
234
+ // won't know it needs to rerender. So we let it know.
235
+ this.requestUpdate();
236
+ }
237
+ }, toast.duration);
238
+ }
239
+ }
240
+ #onToastMouseOver(toast) {
241
+ clearTimeout(toast.privateTimeoutId);
242
+ }
243
+ #onToastTransitionEnd(toast) {
244
+ const toasts = document.querySelector('glide-core-private-toasts');
245
+ // Checking `privateDismissing` ensures we don't dismiss Toasts when the
246
+ // "transitionend" event comes from the transition that's played when they're
247
+ // shown instead of the one played when they're dismissed.
248
+ if (toasts && toast.privateDismissing) {
249
+ this.dismiss(toast);
250
+ }
251
+ }
252
+ };
253
+ __decorate([
254
+ property({ type: Array })
255
+ ], Toasts.prototype, "toasts", void 0);
256
+ Toasts = __decorate([
257
+ customElement('glide-core-private-toasts'),
258
+ final
259
+ ], Toasts);
260
+ export default Toasts;
261
+ const icons = {
262
+ error: html `<svg
52
263
  aria-hidden="true"
53
264
  class="icon error"
54
265
  fill="none"
55
266
  viewBox="0 0 20 20"
56
- style=${styleMap({height:"1.25rem",width:"1.25rem"})}
267
+ style=${styleMap({
268
+ height: '1.25rem',
269
+ width: '1.25rem',
270
+ })}
57
271
  >
58
272
  <path
59
273
  fill-rule="evenodd"
@@ -61,12 +275,16 @@ var __decorate=this&&this.__decorate||function(t,e,i,s){var o,r=arguments.length
61
275
  d="M9.99998 0.833328C4.93737 0.833328 0.833313 4.93738 0.833313 9.99999C0.833313 15.0626 4.93737 19.1667 9.99998 19.1667C15.0626 19.1667 19.1666 15.0626 19.1666 9.99999C19.1666 4.93738 15.0626 0.833328 9.99998 0.833328ZM13.0892 6.91074C13.4147 7.23618 13.4147 7.76381 13.0892 8.08925L11.1785 9.99999L13.0892 11.9107C13.4147 12.2362 13.4147 12.7638 13.0892 13.0892C12.7638 13.4147 12.2362 13.4147 11.9107 13.0892L9.99998 11.1785L8.08923 13.0892C7.7638 13.4147 7.23616 13.4147 6.91072 13.0892C6.58529 12.7638 6.58529 12.2362 6.91072 11.9107L8.82147 9.99999L6.91072 8.08925C6.58529 7.76381 6.58529 7.23618 6.91072 6.91074C7.23616 6.5853 7.7638 6.5853 8.08923 6.91074L9.99998 8.82148L11.9107 6.91074C12.2362 6.5853 12.7638 6.5853 13.0892 6.91074Z"
62
276
  fill="currentColor"
63
277
  />
64
- </svg>`,success:html`<svg
278
+ </svg>`,
279
+ success: html `<svg
65
280
  aria-hidden="true"
66
281
  class="icon success"
67
282
  fill="none"
68
283
  viewBox="0 0 20 20"
69
- style=${styleMap({height:"1.25rem",width:"1.25rem"})}
284
+ style=${styleMap({
285
+ height: '1.25rem',
286
+ width: '1.25rem',
287
+ })}
70
288
  >
71
289
  <path
72
290
  fill-rule="evenodd"
@@ -74,12 +292,16 @@ var __decorate=this&&this.__decorate||function(t,e,i,s){var o,r=arguments.length
74
292
  d="M9.99999 0.833336C4.93738 0.833336 0.833328 4.93739 0.833328 10C0.833328 15.0626 4.93738 19.1667 9.99999 19.1667C15.0626 19.1667 19.1667 15.0626 19.1667 10C19.1667 4.93739 15.0626 0.833336 9.99999 0.833336ZM14.3392 8.08926C14.6647 7.76382 14.6647 7.23618 14.3392 6.91075C14.0138 6.58531 13.4862 6.58531 13.1607 6.91075L8.74999 11.3215L6.83925 9.41075C6.51381 9.08531 5.98618 9.08531 5.66074 9.41075C5.3353 9.73618 5.3353 10.2638 5.66074 10.5893L8.16074 13.0893C8.48618 13.4147 9.01381 13.4147 9.33925 13.0893L14.3392 8.08926Z"
75
293
  fill="currentColor"
76
294
  />
77
- </svg>`,warningInformational:html`<svg
295
+ </svg>`,
296
+ warningInformational: html `<svg
78
297
  aria-hidden="true"
79
298
  class="icon informational"
80
299
  fill="none"
81
300
  viewBox="0 0 20 20"
82
- style=${styleMap({height:"1.25rem",width:"1.25rem"})}
301
+ style=${styleMap({
302
+ height: '1.25rem',
303
+ width: '1.25rem',
304
+ })}
83
305
  >
84
306
  <path
85
307
  fill-rule="evenodd"
@@ -87,4 +309,5 @@ var __decorate=this&&this.__decorate||function(t,e,i,s){var o,r=arguments.length
87
309
  d="M9.99999 0.833328C4.93738 0.833328 0.833328 4.93738 0.833328 9.99999C0.833328 15.0626 4.93738 19.1667 9.99999 19.1667C15.0626 19.1667 19.1667 15.0626 19.1667 9.99999C19.1667 4.93738 15.0626 0.833328 9.99999 0.833328ZM10.8333 6.66666C10.8333 6.20642 10.4602 5.83333 9.99999 5.83333C9.53976 5.83333 9.16666 6.20642 9.16666 6.66666V9.99999C9.16666 10.4602 9.53976 10.8333 9.99999 10.8333C10.4602 10.8333 10.8333 10.4602 10.8333 9.99999V6.66666ZM9.99999 12.5C9.53976 12.5 9.16666 12.8731 9.16666 13.3333C9.16666 13.7936 9.53976 14.1667 9.99999 14.1667H10.0083C10.4686 14.1667 10.8417 13.7936 10.8417 13.3333C10.8417 12.8731 10.4686 12.5 10.0083 12.5H9.99999Z"
88
310
  fill="currentColor"
89
311
  />
90
- </svg>`};
312
+ </svg>`,
313
+ };
@@ -1,6 +1,10 @@
1
- import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";export default[css`
2
- ${visuallyHidden(".prefix")}
3
- `,css`
1
+ import { css } from 'lit';
2
+ import visuallyHidden from './styles/visually-hidden.js';
3
+ export default [
4
+ css `
5
+ ${visuallyHidden('.prefix')}
6
+ `,
7
+ css `
4
8
  .component {
5
9
  background-color: transparent;
6
10
  border: none;
@@ -125,4 +129,5 @@ import{css}from"lit";import visuallyHidden from"./styles/visually-hidden.js";exp
125
129
  color: var(--glide-core-color-static-text-default);
126
130
  grid-column: 2;
127
131
  }
128
- `];
132
+ `,
133
+ ];
package/dist/toggle.js CHANGED
@@ -1 +1,178 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,i){var r,l=arguments.length,s=l<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,o,i);else for(var n=e.length-1;n>=0;n--)(r=e[n])&&(s=(l<3?r(s):l>3?r(t,o,s):r(t,o))||s);return l>3&&s&&Object.defineProperty(t,o,s),s};import"./label.js";import{html,LitElement}from"lit";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{ifDefined}from"lit/directives/if-defined.js";import{when}from"lit/directives/when.js";import packageJson from"../package.json"with{type:"json"};import styles from"./toggle.styles.js";import shadowRootMode from"./library/shadow-root-mode.js";import final from"./library/final.js";import required from"./library/required.js";let Toggle=class Toggle extends LitElement{constructor(){super(...arguments),this.checked=!1,this.disabled=!1,this.hideLabel=!1,this.orientation="horizontal",this.version=packageJson.version,this.#e=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:shadowRootMode}}static{this.styles=styles}click(){this.#e.value?.click()}focus(e){this.#e.value?.focus(e)}render(){return html`<div data-test="component"><glide-core-private-label label="${ifDefined(this.label)}" orientation="${this.orientation}" split="${ifDefined(this.privateSplit??void 0)}" tooltip="${ifDefined(this.tooltip)}" ?disabled="${this.disabled}" ?hide="${this.hideLabel}"><label for="input">${this.label}</label><div class="toggle-and-input" slot="control"><input aria-checked="${this.checked}" aria-describedby="summary description" data-test="input" id="input" role="switch" type="checkbox" .checked="${this.checked}" ?disabled="${this.disabled}" @change="${this.#t}" @input="${this.#t}" ${ref(this.#e)}></div>${when(this.summary,(()=>html`<div id="summary" slot="summary">${this.summary}</div>`))}<slot class="description" id="description" name="description" slot="description"></slot></glide-core-private-label></div>`}#e;#t(e){e.target instanceof HTMLInputElement&&(this.checked=e.target.checked),"change"===e.type&&this.dispatchEvent(new Event("change",{bubbles:!0,composed:!0}))}};__decorate([property({reflect:!0}),required],Toggle.prototype,"label",void 0),__decorate([property({type:Boolean})],Toggle.prototype,"checked",void 0),__decorate([property({reflect:!0,type:Boolean})],Toggle.prototype,"disabled",void 0),__decorate([property({attribute:"hide-label",type:Boolean})],Toggle.prototype,"hideLabel",void 0),__decorate([property({reflect:!0,useDefault:!0})],Toggle.prototype,"orientation",void 0),__decorate([property()],Toggle.prototype,"privateSplit",void 0),__decorate([property({reflect:!0})],Toggle.prototype,"summary",void 0),__decorate([property({reflect:!0})],Toggle.prototype,"tooltip",void 0),__decorate([property({reflect:!0})],Toggle.prototype,"version",void 0),Toggle=__decorate([customElement("glide-core-toggle"),final],Toggle);export default Toggle;
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import './label.js';
8
+ import { html, LitElement } from 'lit';
9
+ import { createRef, ref } from 'lit/directives/ref.js';
10
+ import { customElement, property } from 'lit/decorators.js';
11
+ import { ifDefined } from 'lit/directives/if-defined.js';
12
+ import { when } from 'lit/directives/when.js';
13
+ import packageJson from '../package.json' with { type: 'json' };
14
+ import styles from './toggle.styles.js';
15
+ import shadowRootMode from './library/shadow-root-mode.js';
16
+ import final from './library/final.js';
17
+ import required from './library/required.js';
18
+ /**
19
+ * @attr {string} label
20
+ * @attr {boolean} [checked=false]
21
+ * @attr {boolean} [disabled=false]
22
+ * @attr {boolean} [hide-label=false]
23
+ * @attr {'horizontal'|'vertical'} [orientation='horizontal']
24
+ * @attr {string} [summary]
25
+ * @attr {string} [tooltip]
26
+ *
27
+ * @readonly
28
+ * @attr {string} [version]
29
+ *
30
+ * @slot {Element | string} [description] - Additional information or context
31
+ *
32
+ * @fires {Event} change
33
+ */
34
+ let Toggle = class Toggle extends LitElement {
35
+ constructor() {
36
+ super(...arguments);
37
+ this.checked = false;
38
+ this.disabled = false;
39
+ this.hideLabel = false;
40
+ this.orientation = 'horizontal';
41
+ this.version = packageJson.version;
42
+ this.#inputElementRef = createRef();
43
+ }
44
+ static { this.shadowRootOptions = {
45
+ ...LitElement.shadowRootOptions,
46
+ mode: shadowRootMode,
47
+ }; }
48
+ static { this.styles = styles; }
49
+ click() {
50
+ this.#inputElementRef.value?.click();
51
+ }
52
+ focus(options) {
53
+ this.#inputElementRef.value?.focus(options);
54
+ }
55
+ render() {
56
+ return html `<div data-test="component">
57
+ <glide-core-private-label
58
+ label=${ifDefined(this.label)}
59
+ orientation=${this.orientation}
60
+ split=${ifDefined(this.privateSplit ?? undefined)}
61
+ tooltip=${ifDefined(this.tooltip)}
62
+ ?disabled=${this.disabled}
63
+ ?hide=${this.hideLabel}
64
+ >
65
+ <label for="input"> ${this.label} </label>
66
+
67
+ <div class="toggle-and-input" slot="control">
68
+ <!--
69
+ The input is described by the summary and description but not the tooltip.
70
+ Screenreaders will come across the tooltip naturally as they move focus
71
+ through Toggle.
72
+
73
+ Describing the input additionally by the tooltip is possible. We'd have to:
74
+
75
+ 1. Get the content of the tooltip slot.
76
+ 2. Dump the content into a DIV.
77
+ 3. Visually hide the DIV.
78
+ 4. Describe the input using the DIV.
79
+ 5. Hide the tooltip using "aria-hidden" so its content isn't doubly read.
80
+
81
+ Even then, the tooltip would still receive focus to support sighted keyboard
82
+ users. Screenreaders would likewise focus the tooltip. But its contents would
83
+ not be read aloud because they would be hidden. This would be pretty confusing.
84
+ -->
85
+ <input
86
+ aria-checked=${this.checked}
87
+ aria-describedby="summary description"
88
+ data-test="input"
89
+ id="input"
90
+ role="switch"
91
+ type="checkbox"
92
+ .checked=${this.checked}
93
+ ?disabled=${this.disabled}
94
+ @change=${this.#onChangeOrInput}
95
+ @input=${this.#onChangeOrInput}
96
+ ${ref(this.#inputElementRef)}
97
+ />
98
+ </div>
99
+
100
+ ${when(this.summary, () => html `<div id="summary" slot="summary">${this.summary}</div>`)}
101
+
102
+ <slot
103
+ class="description"
104
+ id="description"
105
+ name="description"
106
+ slot="description"
107
+ >
108
+ <!--
109
+ Additional information or context
110
+ @type {Element | string}
111
+ -->
112
+ </slot>
113
+ </glide-core-private-label>
114
+ </div>`;
115
+ }
116
+ #inputElementRef;
117
+ // Only "change" would need to be handled if not for some consumers needing
118
+ // to force Toggle checked or unchecked until the user has completed some action.
119
+ //
120
+ // The way to force Toggle checked or unchecked is to add an "input" or
121
+ // "change" handler and then immediately set `checked` back to its desired
122
+ // state inside that handler.
123
+ //
124
+ // To do that, consumers need to await `this.updateComplete` so `checked` isn't
125
+ // immediately reverted after Toggle updates, which happens asynchronously and
126
+ // so would happen after their handler runs.
127
+ //
128
+ // To await `this.updateComplete`, however, an update has to be pending. That's
129
+ // why we're handling "input" as well: so that "input", like "change", results
130
+ // in an update that can be awaited.
131
+ //
132
+ // If "input" events were dispatched after "change" events, only handling
133
+ // "change" here would suffice because an update from "change" would already
134
+ // be pending by the time "input" is dispatched.
135
+ #onChangeOrInput(event) {
136
+ if (event.target instanceof HTMLInputElement) {
137
+ this.checked = event.target.checked;
138
+ }
139
+ if (event.type === 'change') {
140
+ // Unlike "input" events, "change" events aren't composed. So we have to
141
+ // manually dispatch them.
142
+ this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
143
+ }
144
+ }
145
+ };
146
+ __decorate([
147
+ property({ reflect: true }),
148
+ required
149
+ ], Toggle.prototype, "label", void 0);
150
+ __decorate([
151
+ property({ type: Boolean })
152
+ ], Toggle.prototype, "checked", void 0);
153
+ __decorate([
154
+ property({ reflect: true, type: Boolean })
155
+ ], Toggle.prototype, "disabled", void 0);
156
+ __decorate([
157
+ property({ attribute: 'hide-label', type: Boolean })
158
+ ], Toggle.prototype, "hideLabel", void 0);
159
+ __decorate([
160
+ property({ reflect: true, useDefault: true })
161
+ ], Toggle.prototype, "orientation", void 0);
162
+ __decorate([
163
+ property()
164
+ ], Toggle.prototype, "privateSplit", void 0);
165
+ __decorate([
166
+ property({ reflect: true })
167
+ ], Toggle.prototype, "summary", void 0);
168
+ __decorate([
169
+ property({ reflect: true })
170
+ ], Toggle.prototype, "tooltip", void 0);
171
+ __decorate([
172
+ property({ reflect: true })
173
+ ], Toggle.prototype, "version", void 0);
174
+ Toggle = __decorate([
175
+ customElement('glide-core-toggle'),
176
+ final
177
+ ], Toggle);
178
+ export default Toggle;
@@ -1,6 +1,10 @@
1
- import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export default[css`
2
- ${focusOutline(".toggle-and-input:has(input:focus-visible)")}
3
- `,css`
1
+ import { css } from 'lit';
2
+ import focusOutline from './styles/focus-outline.js';
3
+ export default [
4
+ css `
5
+ ${focusOutline('.toggle-and-input:has(input:focus-visible)')}
6
+ `,
7
+ css `
4
8
  .toggle-and-input-and-summary {
5
9
  align-items: center;
6
10
  display: flex;
@@ -22,6 +26,8 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
22
26
  inline-size: var(--private-inline-size);
23
27
  justify-content: center;
24
28
  position: relative;
29
+ transition: background-color var(--glide-core-duration-moderate-02)
30
+ var(--glide-core-animation-swoop);
25
31
 
26
32
  &:has(input:checked:not(:disabled)) {
27
33
  background-color: var(
@@ -32,6 +38,12 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
32
38
  &::before {
33
39
  transform: translateX(0);
34
40
  }
41
+
42
+ &:hover {
43
+ background-color: var(
44
+ --glide-core-color-interactive-surface-container-active--hover
45
+ );
46
+ }
35
47
  }
36
48
 
37
49
  &:has(input:disabled) {
@@ -54,6 +66,12 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
54
66
  }
55
67
  }
56
68
 
69
+ &:has(input:not(:disabled, :checked):hover) {
70
+ background-color: var(
71
+ --glide-core-color-interactive-surface-container-inactive--hover
72
+ );
73
+ }
74
+
57
75
  &::before {
58
76
  background: var(--glide-core-color-interactive-icon-onsolid);
59
77
  block-size: 0.875rem;
@@ -67,7 +85,8 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
67
85
  inset-inline-end: 0;
68
86
  position: absolute;
69
87
  transform: translateX(calc(var(--private-inline-size) * -1 + 100%));
70
- transition: 150ms transform;
88
+ transition: transform var(--glide-core-duration-moderate-02)
89
+ var(--glide-core-animation-swoop);
71
90
  }
72
91
  }
73
92
 
@@ -81,4 +100,5 @@ import{css}from"lit";import focusOutline from"./styles/focus-outline.js";export
81
100
  opacity: 0;
82
101
  position: absolute;
83
102
  }
84
- `];
103
+ `,
104
+ ];