@crowdstrike/glide-core 0.12.0 → 0.12.2

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 (49) hide show
  1. package/dist/dropdown.d.ts +1 -0
  2. package/dist/dropdown.js +43 -27
  3. package/dist/dropdown.option.d.ts +3 -0
  4. package/dist/dropdown.option.js +1 -1
  5. package/dist/dropdown.option.styles.js +79 -16
  6. package/dist/dropdown.option.test.basics.js +4 -33
  7. package/dist/dropdown.option.test.basics.multiple.js +9 -0
  8. package/dist/dropdown.option.test.basics.single.js +8 -0
  9. package/dist/dropdown.option.test.interactions.multiple.js +12 -0
  10. package/dist/dropdown.option.test.interactions.single.js +11 -0
  11. package/dist/dropdown.styles.js +20 -17
  12. package/dist/dropdown.test.events.js +67 -0
  13. package/dist/dropdown.test.events.single.js +87 -0
  14. package/dist/dropdown.test.focus.filterable.js +2 -2
  15. package/dist/dropdown.test.focus.js +2 -2
  16. package/dist/dropdown.test.focus.multiple.js +14 -8
  17. package/dist/dropdown.test.focus.single.js +6 -6
  18. package/dist/dropdown.test.form.js +22 -0
  19. package/dist/dropdown.test.interactions.filterable.js +3 -3
  20. package/dist/dropdown.test.interactions.js +175 -3
  21. package/dist/dropdown.test.interactions.multiple.js +74 -5
  22. package/dist/dropdown.test.interactions.single.js +42 -13
  23. package/dist/icons/pencil.d.ts +2 -0
  24. package/dist/icons/pencil.js +1 -0
  25. package/dist/library/localize.d.ts +2 -0
  26. package/dist/menu.js +1 -1
  27. package/dist/menu.options.js +1 -1
  28. package/dist/menu.options.test.events.d.ts +1 -0
  29. package/dist/menu.options.test.events.js +19 -0
  30. package/dist/menu.test.interactions.d.ts +1 -0
  31. package/dist/menu.test.interactions.js +38 -0
  32. package/dist/tab.group.d.ts +8 -1
  33. package/dist/tab.group.js +1 -1
  34. package/dist/tab.group.styles.js +11 -1
  35. package/dist/tab.group.test.basics.js +77 -1
  36. package/dist/tab.panel.js +1 -1
  37. package/dist/tab.panel.styles.js +18 -0
  38. package/dist/tag.d.ts +2 -0
  39. package/dist/tag.js +1 -1
  40. package/dist/tag.styles.js +46 -5
  41. package/dist/tag.test.basics.js +1 -1
  42. package/dist/tag.test.events.js +76 -3
  43. package/dist/tag.test.focus.js +1 -1
  44. package/dist/translations/en.js +1 -1
  45. package/dist/translations/fr.d.ts +1 -1
  46. package/dist/translations/fr.js +1 -1
  47. package/dist/translations/ja.d.ts +1 -1
  48. package/dist/translations/ja.js +1 -1
  49. package/package.json +1 -1
@@ -211,6 +211,22 @@ it('closes on Escape', async () => {
211
211
  await sendKeys({ press: 'Escape' });
212
212
  expect(component.open).to.be.false;
213
213
  });
214
+ it('closes on edit via click', async () => {
215
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
216
+ <glide-core-dropdown-option
217
+ label="One"
218
+ editable
219
+ selected
220
+ ></glide-core-dropdown-option>
221
+
222
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
223
+ </glide-core-dropdown>`);
224
+ component
225
+ .querySelector('glide-core-dropdown-option')
226
+ ?.shadowRoot?.querySelector('[data-test="edit-button"]')
227
+ ?.click();
228
+ expect(component.open).to.be.false;
229
+ });
214
230
  it('opens when open and enabled programmatically', async () => {
215
231
  const component = await fixture(html `<glide-core-dropdown
216
232
  label="Label"
@@ -268,6 +284,7 @@ it('activates an option on "mouseover"', async () => {
268
284
  </glide-core-dropdown>`);
269
285
  const options = component.querySelectorAll('glide-core-dropdown-option');
270
286
  options[1]?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
287
+ expect(options[0]?.privateActive).to.be.false;
271
288
  expect(options[1]?.privateActive).to.be.true;
272
289
  });
273
290
  it('activates the next option on ArrowDown', async () => {
@@ -290,6 +307,47 @@ it('activates the next option on ArrowDown', async () => {
290
307
  expect(options[0]?.privateActive).to.be.false;
291
308
  expect(options[1]?.privateActive).to.be.true;
292
309
  });
310
+ it('activates the Edit button on ArrowDown', async () => {
311
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
312
+ <glide-core-dropdown-option
313
+ label="Label"
314
+ editable
315
+ ></glide-core-dropdown-option>
316
+
317
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
318
+ </glide-core-dropdown>`);
319
+ // Wait for it to open.
320
+ await aTimeout(0);
321
+ const options = component.querySelectorAll('glide-core-dropdown-option');
322
+ options[0]?.focus();
323
+ await sendKeys({ press: 'ArrowDown' });
324
+ expect(options[0]?.privateActive).to.be.true;
325
+ expect(options[0]?.privateIsEditActive).true;
326
+ expect(options[0]?.privateIsOpenTooltip).false;
327
+ expect(options[1]?.privateActive).to.be.false;
328
+ expect(options[1]?.privateIsEditActive).to.be.false;
329
+ });
330
+ it('activates the next option on ArrowDown when the Edit button is active', async () => {
331
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
332
+ <glide-core-dropdown-option
333
+ label="Label"
334
+ editable
335
+ ></glide-core-dropdown-option>
336
+
337
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
338
+ </glide-core-dropdown>`);
339
+ // Wait for it to open.
340
+ await aTimeout(0);
341
+ const options = component.querySelectorAll('glide-core-dropdown-option');
342
+ options[0]?.focus();
343
+ await sendKeys({ press: 'ArrowDown' });
344
+ await sendKeys({ press: 'ArrowDown' });
345
+ expect(options[0]?.privateActive).to.be.false;
346
+ expect(options[0]?.privateIsEditActive).false;
347
+ expect(options[1]?.privateActive).to.be.true;
348
+ expect(options[1]?.privateIsEditActive).to.be.false;
349
+ expect(options[1]?.privateIsOpenTooltip).true;
350
+ });
293
351
  it('activates the previous option on ArrowUp', async () => {
294
352
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
295
353
  <glide-core-dropdown-option
@@ -312,6 +370,56 @@ it('activates the previous option on ArrowUp', async () => {
312
370
  expect(options[0]?.privateActive).to.be.true;
313
371
  expect(options[1]?.privateActive).to.be.false;
314
372
  });
373
+ it('activates the Edit button on on ArrowUp', async () => {
374
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
375
+ <glide-core-dropdown-option
376
+ label="Label"
377
+ editable
378
+ ></glide-core-dropdown-option>
379
+
380
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
381
+ </glide-core-dropdown>`);
382
+ // Wait for it to open.
383
+ await aTimeout(0);
384
+ const options = component.querySelectorAll('glide-core-dropdown-option');
385
+ options[1]?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
386
+ options[1]?.focus();
387
+ expect(options[1]?.privateActive).to.be.true;
388
+ await sendKeys({ press: 'ArrowUp' });
389
+ expect(options[0]?.privateActive).to.be.true;
390
+ expect(options[0]?.privateIsEditActive).to.be.true;
391
+ expect(options[0]?.privateIsOpenTooltip).false;
392
+ expect(options[1]?.privateActive).to.be.false;
393
+ expect(options[1]?.privateIsEditActive).to.be.false;
394
+ expect(options[1]?.privateIsOpenTooltip).to.be.false;
395
+ });
396
+ it('activates the previous option on ArrowUp when the Edit button is active', async () => {
397
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
398
+ <glide-core-dropdown-option
399
+ label="One"
400
+ editable
401
+ ></glide-core-dropdown-option>
402
+
403
+ <glide-core-dropdown-option
404
+ label="Two"
405
+ editable
406
+ ></glide-core-dropdown-option>
407
+
408
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
409
+ </glide-core-dropdown>`);
410
+ // Wait for it to open.
411
+ await aTimeout(0);
412
+ const options = component.querySelectorAll('glide-core-dropdown-option');
413
+ options[1]?.focus();
414
+ await sendKeys({ press: 'ArrowUp' });
415
+ await sendKeys({ press: 'ArrowUp' });
416
+ expect(options[0]?.privateActive).to.be.true;
417
+ expect(options[0]?.privateIsEditActive).to.be.false;
418
+ expect(options[0]?.privateIsOpenTooltip).to.be.true;
419
+ expect(options[1]?.privateActive).to.be.false;
420
+ expect(options[1]?.privateIsEditActive).to.be.false;
421
+ expect(options[1]?.privateIsOpenTooltip).to.be.false;
422
+ });
315
423
  it('activates the first option on Home', async () => {
316
424
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
317
425
  <glide-core-dropdown-option
@@ -332,7 +440,11 @@ it('activates the first option on Home', async () => {
332
440
  options[1].focus();
333
441
  await sendKeys({ press: 'Home' });
334
442
  expect(options[0]?.privateActive).to.be.true;
443
+ expect(options[0]?.privateIsEditActive).to.be.false;
444
+ expect(options[0]?.privateIsOpenTooltip).to.be.true;
335
445
  expect(options[1]?.privateActive).to.be.false;
446
+ expect(options[1]?.privateIsEditActive).to.be.false;
447
+ expect(options[1]?.privateIsOpenTooltip).to.be.false;
336
448
  });
337
449
  it('activates the first option on PageUp', async () => {
338
450
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -354,7 +466,11 @@ it('activates the first option on PageUp', async () => {
354
466
  expect(options[1]?.privateActive).to.be.true;
355
467
  await sendKeys({ press: 'PageUp' });
356
468
  expect(options[0]?.privateActive).to.be.true;
469
+ expect(options[0]?.privateIsEditActive).to.be.false;
470
+ expect(options[0]?.privateIsOpenTooltip).to.be.true;
357
471
  expect(options[1]?.privateActive).to.be.false;
472
+ expect(options[1]?.privateIsEditActive).to.be.false;
473
+ expect(options[1]?.privateIsOpenTooltip).to.be.false;
358
474
  });
359
475
  it('activates the first option on ArrowUp + Meta', async () => {
360
476
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -372,13 +488,16 @@ it('activates the first option on ArrowUp + Meta', async () => {
372
488
  await aTimeout(0);
373
489
  const options = component.querySelectorAll('glide-core-dropdown-option');
374
490
  options[1]?.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));
375
- expect(options[1]?.privateActive).to.be.true;
376
491
  options[1].focus();
377
492
  await sendKeys({ down: 'Meta' });
378
493
  await sendKeys({ press: 'ArrowUp' });
379
494
  await sendKeys({ up: 'Meta' });
380
495
  expect(options[0]?.privateActive).to.be.true;
496
+ expect(options[0]?.privateIsEditActive).to.be.false;
497
+ expect(options[0]?.privateIsOpenTooltip).to.be.true;
381
498
  expect(options[1]?.privateActive).to.be.false;
499
+ expect(options[1]?.privateIsEditActive).to.be.false;
500
+ expect(options[1]?.privateIsOpenTooltip).to.be.false;
382
501
  });
383
502
  it('activates the last option on End', async () => {
384
503
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -398,7 +517,11 @@ it('activates the last option on End', async () => {
398
517
  options[0]?.focus();
399
518
  await sendKeys({ press: 'End' });
400
519
  expect(options[0]?.privateActive).to.be.false;
520
+ expect(options[0]?.privateIsEditActive).to.be.false;
521
+ expect(options[0]?.privateIsOpenTooltip).to.be.false;
401
522
  expect(options[1]?.privateActive).to.be.true;
523
+ expect(options[1]?.privateIsEditActive).to.be.false;
524
+ expect(options[1]?.privateIsOpenTooltip).to.be.true;
402
525
  });
403
526
  it('activates the last option on PageDown', async () => {
404
527
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -418,7 +541,11 @@ it('activates the last option on PageDown', async () => {
418
541
  options[0]?.focus();
419
542
  await sendKeys({ press: 'PageDown' });
420
543
  expect(options[0]?.privateActive).to.be.false;
544
+ expect(options[0]?.privateIsEditActive).to.be.false;
545
+ expect(options[0]?.privateIsOpenTooltip).to.be.false;
421
546
  expect(options[1]?.privateActive).to.be.true;
547
+ expect(options[1]?.privateIsEditActive).to.be.false;
548
+ expect(options[1]?.privateIsOpenTooltip).to.be.true;
422
549
  });
423
550
  it('activates the last option on Meta + ArrowDown', async () => {
424
551
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
@@ -440,7 +567,11 @@ it('activates the last option on Meta + ArrowDown', async () => {
440
567
  await sendKeys({ press: 'ArrowDown' });
441
568
  await sendKeys({ up: 'Meta' });
442
569
  expect(options[0]?.privateActive).to.be.false;
570
+ expect(options[0]?.privateIsEditActive).to.be.false;
571
+ expect(options[0]?.privateIsOpenTooltip).to.be.false;
443
572
  expect(options[1]?.privateActive).to.be.true;
573
+ expect(options[1]?.privateIsEditActive).to.be.false;
574
+ expect(options[1]?.privateIsOpenTooltip).to.be.true;
444
575
  });
445
576
  it('does not wrap on ArrowUp', async () => {
446
577
  const component = await fixture(html `<glide-core-dropdown open>
@@ -498,7 +629,7 @@ it('updates `privateSize` on every option when `size` is changed programmaticall
498
629
  expect(options[0].privateSize).to.equal('small');
499
630
  expect(options[1].privateSize).to.equal('small');
500
631
  });
501
- it('opens when something other than the button is clicked', async () => {
632
+ it('opens when something other than the primary button is clicked', async () => {
502
633
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
503
634
  <glide-core-dropdown-option
504
635
  label="Label"
@@ -516,6 +647,47 @@ it('opens when something other than the button is clicked', async () => {
516
647
  });
517
648
  expect(component.open).to.be.true;
518
649
  });
650
+ it('does not open on edit via click', async () => {
651
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
652
+ <glide-core-dropdown-option
653
+ label="Label"
654
+ editable
655
+ selected
656
+ ></glide-core-dropdown-option>
657
+ </glide-core-dropdown>`);
658
+ component.shadowRoot
659
+ ?.querySelector('[data-test="edit-button"]')
660
+ ?.click();
661
+ expect(component.open).to.be.false;
662
+ });
663
+ it('does not open on edit via Enter', async () => {
664
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
665
+ <glide-core-dropdown-option
666
+ label="Label"
667
+ editable
668
+ selected
669
+ ></glide-core-dropdown-option>
670
+ </glide-core-dropdown>`);
671
+ component.shadowRoot
672
+ ?.querySelector('[data-test="edit-button"]')
673
+ ?.focus();
674
+ await sendKeys({ press: 'Enter' });
675
+ expect(component.open).to.be.false;
676
+ });
677
+ it('does not open on edit via Space', async () => {
678
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
679
+ <glide-core-dropdown-option
680
+ label="Label"
681
+ editable
682
+ selected
683
+ ></glide-core-dropdown-option>
684
+ </glide-core-dropdown>`);
685
+ component.shadowRoot
686
+ ?.querySelector('[data-test="edit-button"]')
687
+ ?.focus();
688
+ await sendKeys({ press: ' ' });
689
+ expect(component.open).to.be.false;
690
+ });
519
691
  it('hides the tooltip of the active option when opened via click', async () => {
520
692
  // The period is arbitrary. 500 of them ensures we exceed the maximum
521
693
  // width even if it's increased.
@@ -531,7 +703,7 @@ it('hides the tooltip of the active option when opened via click', async () => {
531
703
  // and would work. `CustomEvent` is used for completeness and to get us as close as
532
704
  // possible to a real click. See the comment in the handler for more information.
533
705
  component.shadowRoot
534
- ?.querySelector('[data-test="button"]')
706
+ ?.querySelector('[data-test="primary-button"]')
535
707
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
536
708
  // Wait for it to open.
537
709
  await aTimeout(0);
@@ -12,6 +12,7 @@ import { sendKeys } from '@web/test-runner-commands';
12
12
  import { sendMouse } from '@web/test-runner-commands';
13
13
  import GlideCoreDropdown from './dropdown.js';
14
14
  import GlideCoreDropdownOption from './dropdown.option.js';
15
+ import GlideCoreTag from './tag.js';
15
16
  let GlideCoreDropdownInAnotherComponent = class GlideCoreDropdownInAnotherComponent extends LitElement {
16
17
  static { this.shadowRootOptions = {
17
18
  ...LitElement.shadowRootOptions,
@@ -40,6 +41,7 @@ GlideCoreDropdownInAnotherComponent = __decorate([
40
41
  GlideCoreDropdown.shadowRootOptions.mode = 'open';
41
42
  GlideCoreDropdownOption.shadowRootOptions.mode = 'open';
42
43
  GlideCoreDropdownInAnotherComponent.shadowRootOptions.mode = 'open';
44
+ GlideCoreTag.shadowRootOptions.mode = 'open';
43
45
  it('opens on click', async () => {
44
46
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
45
47
  <glide-core-dropdown-option
@@ -57,7 +59,7 @@ it('opens on click', async () => {
57
59
  // and would work. `CustomEvent` is used for completeness and to get us as close as
58
60
  // possible to a real click. See the comment in the handler for more information.
59
61
  component.shadowRoot
60
- ?.querySelector('[data-test="button"]')
62
+ ?.querySelector('[data-test="primary-button"]')
61
63
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
62
64
  // Wait for it to open.
63
65
  await aTimeout(0);
@@ -87,7 +89,7 @@ it('toggles open and closed when the button is clicked', async () => {
87
89
  // and would work. `CustomEvent` is used for completeness and to get us as close as
88
90
  // possible to a real click. See the comment in the handler for more information.
89
91
  component.shadowRoot
90
- ?.querySelector('[data-test="button"]')
92
+ ?.querySelector('[data-test="primary-button"]')
91
93
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
92
94
  await elementUpdated(component);
93
95
  const options = component.shadowRoot?.querySelector('[data-test="options"]');
@@ -359,7 +361,7 @@ it('does not activate the next option on ArrowDown when a tag is focused', async
359
361
  await sendKeys({ press: 'ArrowDown' });
360
362
  expect(options[0]?.privateActive).to.be.true;
361
363
  });
362
- it('updates its tag when the `label` of a selected option is changed programmatically', async () => {
364
+ it('updates its tag when `label` of a selected option is changed programmatically', async () => {
363
365
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
364
366
  <glide-core-dropdown-option
365
367
  label="One"
@@ -375,6 +377,22 @@ it('updates its tag when the `label` of a selected option is changed programmati
375
377
  const tag = component.shadowRoot?.querySelector('[data-test="tag"]');
376
378
  expect(tag?.label).to.equal('Three');
377
379
  });
380
+ it('makes its tag editable when `editable` of a selected option is changed programmatically', async () => {
381
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
382
+ <glide-core-dropdown-option
383
+ label="One"
384
+ selected
385
+ ></glide-core-dropdown-option>
386
+
387
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
388
+ </glide-core-dropdown>`);
389
+ const option = component.querySelector('glide-core-dropdown-option');
390
+ assert(option);
391
+ option.editable = true;
392
+ await elementUpdated(component);
393
+ const tag = component.shadowRoot?.querySelector('[data-test="tag"]');
394
+ expect(tag?.privateEditable).to.be.true;
395
+ });
378
396
  it('selects and deselects options when `value` is changed programmatically', async () => {
379
397
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
380
398
  <glide-core-dropdown-option
@@ -1111,6 +1129,57 @@ it('closes when a tag is clicked', async () => {
1111
1129
  await elementUpdated(component);
1112
1130
  expect(component.open).to.be.false;
1113
1131
  });
1132
+ it('closes on edit via click', async () => {
1133
+ const component = await fixture(html `<glide-core-dropdown open multiple>
1134
+ <glide-core-dropdown-option
1135
+ label="One"
1136
+ editable
1137
+ selected
1138
+ ></glide-core-dropdown-option>
1139
+
1140
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
1141
+ </glide-core-dropdown>`);
1142
+ component.shadowRoot
1143
+ ?.querySelector('glide-core-tag')
1144
+ ?.shadowRoot?.querySelector('[data-test="edit-button"]')
1145
+ ?.click();
1146
+ await elementUpdated(component);
1147
+ expect(component.open).to.be.false;
1148
+ });
1149
+ it('closes on edit via Enter', async () => {
1150
+ const component = await fixture(html `<glide-core-dropdown open multiple>
1151
+ <glide-core-dropdown-option
1152
+ label="One"
1153
+ editable
1154
+ selected
1155
+ ></glide-core-dropdown-option>
1156
+
1157
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
1158
+ </glide-core-dropdown>`);
1159
+ component.shadowRoot
1160
+ ?.querySelector('glide-core-tag')
1161
+ ?.shadowRoot?.querySelector('[data-test="edit-button"]')
1162
+ ?.focus();
1163
+ await sendKeys({ press: 'Enter' });
1164
+ expect(component.open).to.be.false;
1165
+ });
1166
+ it('closes on edit via Space', async () => {
1167
+ const component = await fixture(html `<glide-core-dropdown open multiple>
1168
+ <glide-core-dropdown-option
1169
+ label="One"
1170
+ editable
1171
+ selected
1172
+ ></glide-core-dropdown-option>
1173
+
1174
+ <glide-core-dropdown-option label="Two"></glide-core-dropdown-option>
1175
+ </glide-core-dropdown>`);
1176
+ component.shadowRoot
1177
+ ?.querySelector('glide-core-tag')
1178
+ ?.shadowRoot?.querySelector('[data-test="edit-button"]')
1179
+ ?.focus();
1180
+ await sendKeys({ press: ' ' });
1181
+ expect(component.open).to.be.false;
1182
+ });
1114
1183
  it('cannot be tabbed to when `disabled`', async () => {
1115
1184
  await fixture(html `<glide-core-dropdown
1116
1185
  label="Label"
@@ -1131,7 +1200,7 @@ it('cannot be tabbed to when `disabled`', async () => {
1131
1200
  await sendKeys({ press: 'Tab' });
1132
1201
  expect(document.activeElement).to.equal(document.body);
1133
1202
  });
1134
- it('clicks the button when `click()` is called', async () => {
1203
+ it('clicks the primary button when `click()` is called', async () => {
1135
1204
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" multiple>
1136
1205
  <glide-core-dropdown-option
1137
1206
  label="One"
@@ -1143,7 +1212,7 @@ it('clicks the button when `click()` is called', async () => {
1143
1212
  value="two"
1144
1213
  ></glide-core-dropdown-option>
1145
1214
  </glide-core-dropdown>`);
1146
- const button = component.shadowRoot?.querySelector('[data-test="button"]');
1215
+ const button = component.shadowRoot?.querySelector('[data-test="primary-button"]');
1147
1216
  assert(button);
1148
1217
  setTimeout(() => {
1149
1218
  component.click();
@@ -19,7 +19,7 @@ it('opens on click', async () => {
19
19
  // and would work. `CustomEvent` is used for completeness and to get us as close as
20
20
  // possible to a real click. See the comment in the handler for more information.
21
21
  component.shadowRoot
22
- ?.querySelector('[data-test="button"]')
22
+ ?.querySelector('[data-test="primary-button"]')
23
23
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
24
24
  // Wait for it to open.
25
25
  await aTimeout(0);
@@ -27,7 +27,7 @@ it('opens on click', async () => {
27
27
  expect(component.open).to.be.true;
28
28
  expect(options?.checkVisibility()).to.be.true;
29
29
  });
30
- it('toggles open and closed when the button is clicked', async () => {
30
+ it('toggles open and closed when the primary button is clicked', async () => {
31
31
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
32
32
  <glide-core-dropdown-option
33
33
  label="Label"
@@ -39,7 +39,7 @@ it('toggles open and closed when the button is clicked', async () => {
39
39
  // and would work. `CustomEvent` is used for completeness and to get us as close as
40
40
  // possible to a real click. See the comment in the handler for more information.
41
41
  component.shadowRoot
42
- ?.querySelector('[data-test="button"]')
42
+ ?.querySelector('[data-test="primary-button"]')
43
43
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
44
44
  await elementUpdated(component);
45
45
  const options = component.shadowRoot?.querySelector('[data-test="options"]');
@@ -246,6 +246,21 @@ it('closes when an already selected option is clicked', async () => {
246
246
  component.querySelector('glide-core-dropdown-option')?.click();
247
247
  expect(component.open).to.be.false;
248
248
  });
249
+ it('closes on edit via click', async () => {
250
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder" open>
251
+ <glide-core-dropdown-option
252
+ label="Label"
253
+ editable
254
+ selected
255
+ ></glide-core-dropdown-option>
256
+ </glide-core-dropdown>`);
257
+ // Wait for it to open.
258
+ await aTimeout(0);
259
+ component.shadowRoot
260
+ ?.querySelector('[data-test="edit-button"]')
261
+ ?.click();
262
+ expect(component.open).to.be.false;
263
+ });
249
264
  it('deselects all other options when one is newly selected', async () => {
250
265
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
251
266
  <glide-core-dropdown-option
@@ -265,7 +280,7 @@ it('deselects all other options when one is newly selected', async () => {
265
280
  ></glide-core-dropdown-option>
266
281
  </glide-core-dropdown>`);
267
282
  component.shadowRoot
268
- ?.querySelector('[data-test="button"]')
283
+ ?.querySelector('[data-test="primary-button"]')
269
284
  ?.dispatchEvent(new Event('click'));
270
285
  const options = component.querySelectorAll('glide-core-dropdown-option');
271
286
  options[1].click();
@@ -273,7 +288,7 @@ it('deselects all other options when one is newly selected', async () => {
273
288
  expect(options[1].selected).to.be.true;
274
289
  expect(options[2].selected).to.be.false;
275
290
  });
276
- it('updates its internal label when the `label` of a selected option is changed programmatically', async () => {
291
+ it('updates its internal label when `label` of the selected option is changed programmatically', async () => {
277
292
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
278
293
  <glide-core-dropdown-option
279
294
  label="One"
@@ -287,6 +302,20 @@ it('updates its internal label when the `label` of a selected option is changed
287
302
  const label = component.shadowRoot?.querySelector('[data-test="internal-label"]');
288
303
  expect(label?.textContent?.trim()).to.equal(option?.label);
289
304
  });
305
+ it('shows an Edit button when `editable` of the selected option is changed programmatically', async () => {
306
+ const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
307
+ <glide-core-dropdown-option
308
+ label="One"
309
+ selected
310
+ ></glide-core-dropdown-option>
311
+ </glide-core-dropdown>`);
312
+ const option = component.querySelector('glide-core-dropdown-option');
313
+ assert(option);
314
+ option.editable = true;
315
+ await elementUpdated(component);
316
+ const editButton = component.shadowRoot?.querySelector('[data-test="edit-button"]');
317
+ expect(editButton?.checkVisibility()).to.be.true;
318
+ });
290
319
  it('selects and deselects options when `value` is changed programmatically', async () => {
291
320
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
292
321
  <glide-core-dropdown-option
@@ -360,7 +389,7 @@ it('updates `value` when an option is selected via click', async () => {
360
389
  expect(component.value).to.deep.equal(['two']);
361
390
  // Reopen it.
362
391
  component.shadowRoot
363
- ?.querySelector('[data-test="button"]')
392
+ ?.querySelector('[data-test="primary-button"]')
364
393
  ?.dispatchEvent(new CustomEvent('click', { detail: 1 }));
365
394
  // Wait for it to open.
366
395
  await elementUpdated(component);
@@ -368,7 +397,7 @@ it('updates `value` when an option is selected via click', async () => {
368
397
  expect(component.value).to.deep.equal(['two']);
369
398
  // Reopen it.
370
399
  component.shadowRoot
371
- ?.querySelector('[data-test="button"]')
400
+ ?.querySelector('[data-test="primary-button"]')
372
401
  ?.dispatchEvent(new CustomEvent('click', { detail: 1 }));
373
402
  // Wait for it to open.
374
403
  await elementUpdated(component);
@@ -397,7 +426,7 @@ it('updates `value` when an option is selected via Enter', async () => {
397
426
  expect(component.value).to.deep.equal(['one']);
398
427
  // Reopen it.
399
428
  component.shadowRoot
400
- ?.querySelector('[data-test="button"]')
429
+ ?.querySelector('[data-test="primary-button"]')
401
430
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
402
431
  // Wait for it to open.
403
432
  await aTimeout(0);
@@ -406,7 +435,7 @@ it('updates `value` when an option is selected via Enter', async () => {
406
435
  expect(component.value).to.deep.equal(['two']);
407
436
  // Reopen it.
408
437
  component.shadowRoot
409
- ?.querySelector('[data-test="button"]')
438
+ ?.querySelector('[data-test="primary-button"]')
410
439
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
411
440
  // Wait for it to open.
412
441
  await aTimeout(0);
@@ -436,7 +465,7 @@ it('updates `value` when an option is selected via Space', async () => {
436
465
  expect(component.value).to.deep.equal(['one']);
437
466
  // Reopen it.
438
467
  component.shadowRoot
439
- ?.querySelector('[data-test="button"]')
468
+ ?.querySelector('[data-test="primary-button"]')
440
469
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
441
470
  // Wait for it to open.
442
471
  await aTimeout(0);
@@ -445,7 +474,7 @@ it('updates `value` when an option is selected via Space', async () => {
445
474
  expect(component.value).to.deep.equal(['two']);
446
475
  // Reopen it.
447
476
  component.shadowRoot
448
- ?.querySelector('[data-test="button"]')
477
+ ?.querySelector('[data-test="primary-button"]')
449
478
  ?.dispatchEvent(new CustomEvent('click', { bubbles: true, detail: 1 }));
450
479
  // Wait for it to open.
451
480
  await aTimeout(0);
@@ -564,14 +593,14 @@ it('cannot be tabbed to when `disabled`', async () => {
564
593
  await sendKeys({ down: 'Tab' });
565
594
  expect(document.activeElement).to.equal(document.body);
566
595
  });
567
- it('clicks the button when `click()` is called', async () => {
596
+ it('clicks the primary button when `click()` is called', async () => {
568
597
  const component = await fixture(html `<glide-core-dropdown label="Label" placeholder="Placeholder">
569
598
  <glide-core-dropdown-option
570
599
  label="Label"
571
600
  value="value"
572
601
  ></glide-core-dropdown-option>
573
602
  </glide-core-dropdown>`);
574
- const button = component.shadowRoot?.querySelector('[data-test="button"]');
603
+ const button = component.shadowRoot?.querySelector('[data-test="primary-button"]');
575
604
  assert(button);
576
605
  setTimeout(() => {
577
606
  component.click();
@@ -0,0 +1,2 @@
1
+ declare const _default: import("lit").TemplateResult<1>;
2
+ export default _default;
@@ -0,0 +1 @@
1
+ import{html}from"lit";export default html`<svg aria-hidden="true" width="14" height="14" viewBox="0 0 14 14" fill="none" style="height: var(--size, 0.875rem); width: var(--size, 0.875rem);"><path d="M10.0244 5.95031L8.0395 3.96536M2.06587 11.924L3.74532 11.7374C3.95051 11.7146 4.0531 11.7032 4.149 11.6721C4.23407 11.6446 4.31504 11.6057 4.38969 11.5564C4.47384 11.501 4.54683 11.428 4.69281 11.282L11.5132 4.4616C12.0613 3.91347 12.0613 3.02478 11.5132 2.47665C10.965 1.92852 10.0763 1.92852 9.52821 2.47665L2.70786 9.29703C2.56188 9.44302 2.48889 9.51601 2.4334 9.60015C2.38417 9.67481 2.34526 9.75577 2.31772 9.84085C2.28667 9.93674 2.27527 10.0393 2.25247 10.2445L2.06587 11.924Z" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
@@ -17,6 +17,8 @@ export interface Translation extends DefaultTranslation {
17
17
  announcedCharacterCount: (current: number, maximum: number) => string;
18
18
  displayedCharacterCount: (current: number, maximum: number) => string;
19
19
  clearEntry: (label: string) => string;
20
+ editOption: (name: string) => string;
21
+ editTag: (name: string) => string;
20
22
  removeTag: (name: string) => string;
21
23
  actionsFor: (label: string) => string;
22
24
  }
package/dist/menu.js CHANGED
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n=!1,this.#s="large",this.#l=createRef(),this.#a=()=>{this.#n?this.#n=!1:(this.open=!1,this.#r&&(this.#r.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get offset(){return this.#c??Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}set offset(e){this.#c=e}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#h():this.#p()}get size(){return this.#s}set size(e){this.#s=e,this.#r&&(this.#r.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#a,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#a,{capture:!0})}firstUpdated(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#l.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#m?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#h()),this.#l.value.addEventListener("mouseup",(()=>{this.#n=!0}))}get isTargetDisabled(){const e=this.#u&&"disabled"in this.#u&&this.#u.disabled,t=this.#u&&"true"===this.#u.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#f}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#E}" @keydown="${this.#v}" @slotchange="${this.#g}" ${ref(this.#l)}></slot><slot class="default-slot" @click="${this.#S}" @focusin="${this.#w}" @keydown="${this.#v}" @mouseover="${this.#C}" @slotchange="${this.#y}" ${ref(this.#t)}></slot></div>`}#R;#e;#t;#i;#o;#n;#c;#d;#s;#l;get#k(){return this.#m?.find((({privateActive:e})=>e))}#a;#O(e){this.#u&&"focus"in this.#u&&this.#u?.focus(e)}#p(){this.#R?.(),this.#r&&(this.#r.ariaActivedescendant=""),this.#u&&(this.#u.ariaExpanded="false"),this.#t.value?.hidePopover()}get#r(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#y(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]);const e=this.#m?.at(0);e&&(e.privateActive=!0),this.#r.privateSize=this.size}#S(){this.open=!1}#w(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#k&&this.#r&&(this.#k.privateActive=!1,e.target.privateActive=!0,this.#r.ariaActivedescendant=e.target.id)}#C(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#m)for(const t of this.#m)t.privateActive=t===e.target;this.#r&&(this.#r.ariaActivedescendant=e.target.id)}}#f(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#v(e){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));const t=this.#u instanceof HTMLSpanElement||this.#u instanceof HTMLDivElement;if([" ","Enter"].includes(e.key)&&this.open)return" "===e.key&&t&&e.preventDefault(),this.open=!1,this.#O(),this.#k?.click(),void(this.#i=!0);if([" ","Enter"].includes(e.key)&&t)return e.preventDefault(),void(this.open=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.#O();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#k)return e.preventDefault(),this.open=!0,void(this.#r.ariaActivedescendant=this.#k.id);if(this.open){ow(this.#m,ow.array),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#k,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#m.indexOf(this.#k);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#m.at(t-1);return void(i&&0!==t&&(this.#k.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#m.at(t+1);return void(i&&(this.#k.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#m.at(0);return void(t&&(this.#k.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#m.at(-1);return void(t&&(this.#k.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}}}#g(){owSlot(this.#l.value),ow(this.#u,ow.object.instanceOf(Element)),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((()=>{this.open&&!this.isTargetDisabled?this.#h():this.#p()})).observe(this.#u,{attributes:!0,attributeFilter:["aria-disabled","disabled"]}),this.#u.ariaHasPopup="true",this.#u.id=nanoid(),this.#u.setAttribute("aria-controls",this.#r.id),this.#r.ariaLabelledby=this.#u.id;(this.#u instanceof HTMLSpanElement||this.#u instanceof HTMLDivElement)&&this.#u instanceof HTMLElement&&(this.#u.tabIndex=0),this.open&&!this.isTargetDisabled?this.#h():this.#p()}#E(){this.isTargetDisabled?this.#p():this.#i?this.#i=!1:this.#m&&this.#m.length>0&&(this.open=!this.open)}get#m(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#h(){this.#R?.(),this.#u&&this.#t.value&&(this.#R=autoUpdate(this.#u,this.#t.value,(()=>{(async()=>{if(this.#u&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#u,this.#t.value,{placement:this.placement,middleware:[offset(this.offset),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#r&&this.#k?.id&&(this.#r.ariaActivedescendant=this.#k.id),this.#u&&(this.#u.ariaExpanded="true")})()})))}get#u(){return this.#l.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Number})],GlideCoreMenu.prototype,"offset",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
1
+ var __decorate=this&&this.__decorate||function(e,t,i,o){var n,s=arguments.length,l=s<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,i):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,o);else for(var a=e.length-1;a>=0;a--)(n=e[a])&&(l=(s<3?n(l):s>3?n(t,i,l):n(t,i))||l);return s>3&&l&&Object.defineProperty(t,i,l),l};import{LitElement,html}from"lit";import{autoUpdate,computePosition,flip,offset}from"@floating-ui/dom";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property}from"lit/decorators.js";import{nanoid}from"nanoid";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import GlideCoreMenuOptions from"./menu.options.js";import ow,{owSlot,owSlotType}from"./library/ow.js";import styles from"./menu.styles.js";let GlideCoreMenu=class GlideCoreMenu extends LitElement{constructor(){super(...arguments),this.placement="bottom-start",this.#e=createRef(),this.#t=createRef(),this.#i=!1,this.#o=!1,this.#n=!1,this.#s="large",this.#l=createRef(),this.#a=()=>{this.#n?this.#n=!1:(this.open=!1,this.#r&&(this.#r.ariaActivedescendant=""))}}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}get offset(){return this.#c??Number.parseFloat(window.getComputedStyle(document.body).getPropertyValue("--glide-core-spacing-xxs"))*Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize)}set offset(e){this.#c=e}get open(){return this.#o}set open(e){this.#o=e,e&&!this.isTargetDisabled?this.#h():this.#p()}get size(){return this.#s}set size(e){this.#s=e,this.#r&&(this.#r.privateSize=e)}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this.#a,{capture:!0})}createRenderRoot(){return this.#d=super.createRenderRoot(),this.#d}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this.#a,{capture:!0})}firstUpdated(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlot(this.#l.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#t.value.popover="manual";const e=this.#m?.at(0);this.open&&e&&!this.isTargetDisabled&&(e.privateActive=!0,this.#h()),this.#l.value.addEventListener("mouseup",(()=>{this.#n=!0}))}get isTargetDisabled(){const e=this.#u&&"disabled"in this.#u&&this.#u.disabled,t=this.#u&&"true"===this.#u.ariaDisabled;return Boolean(e)||Boolean(t)}render(){return html`<div class="component" @focusout="${this.#f}" ${ref(this.#e)}><slot class="target-slot" name="target" @click="${this.#E}" @keydown="${this.#v}" @slotchange="${this.#g}" ${ref(this.#l)}></slot><slot class="default-slot" @click="${this.#S}" @focusin="${this.#w}" @keydown="${this.#v}" @mouseover="${this.#C}" @private-slot-change="${this.#y}" @slotchange="${this.#R}" ${ref(this.#t)}></slot></div>`}#k;#e;#t;#i;#o;#n;#c;#d;#s;#l;get#O(){return this.#m?.find((({privateActive:e})=>e))}#a;#b(e){this.#u&&"focus"in this.#u&&this.#u?.focus(e)}#p(){this.#k?.(),this.#r&&(this.#r.ariaActivedescendant=""),this.#u&&(this.#u.ariaExpanded="false"),this.#t.value?.hidePopover()}get#r(){const e=this.#t.value?.assignedElements().at(0);return e instanceof GlideCoreMenuOptions?e:null}#R(){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuOptions]),this.#r.privateSize=this.size}#S(){this.open=!1}#w(e){(e.target instanceof GlideCoreMenuButton||e.target instanceof GlideCoreMenuLink)&&this.#O&&this.#r&&(this.#O.privateActive=!1,e.target.privateActive=!0,this.#r.ariaActivedescendant=e.target.id)}#C(e){if(e.target instanceof GlideCoreMenuLink||e.target instanceof GlideCoreMenuButton){if(this.#m)for(const t of this.#m)t.privateActive=t===e.target;this.#r&&(this.#r.ariaActivedescendant=e.target.id)}}#f(e){const t=e.relatedTarget instanceof HTMLElement&&this.#d?.contains(e.relatedTarget),i=e.relatedTarget instanceof GlideCoreMenuOptions,o=e.relatedTarget instanceof GlideCoreMenuButton||e.relatedTarget instanceof GlideCoreMenuLink;t||i||o||(this.open=!1)}#y(){const e=this.#m?.find((({privateActive:e})=>e)),t=this.#m?.at(0);!e&&t&&(t.privateActive=!0)}#v(e){ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));const t=this.#u instanceof HTMLSpanElement||this.#u instanceof HTMLDivElement;if([" ","Enter"].includes(e.key)&&this.open)return" "===e.key&&t&&e.preventDefault(),this.open=!1,this.#b(),this.#O?.click(),void(this.#i=!0);if([" ","Enter"].includes(e.key)&&t)return e.preventDefault(),void(this.open=!0);if(["Escape"].includes(e.key)&&this.open)return this.open=!1,void this.#b();if(["ArrowUp","ArrowDown"].includes(e.key)&&!this.open&&this.#O)return e.preventDefault(),this.open=!0,void(this.#r.ariaActivedescendant=this.#O.id);if(this.open){ow(this.#m,ow.array),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions)),ow(this.#O,ow.object.is((e=>e instanceof GlideCoreMenuButton||e instanceof GlideCoreMenuLink)));const t=this.#m.indexOf(this.#O);if("ArrowUp"===e.key&&!e.metaKey){e.preventDefault();const i=this.#m.at(t-1);return void(i&&0!==t&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowDown"===e.key&&!e.metaKey){e.preventDefault();const i=this.#m.at(t+1);return void(i&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=i.id,i.privateActive=!0))}if("ArrowUp"===e.key&&e.metaKey||"Home"===e.key||"PageUp"===e.key){e.preventDefault();const t=this.#m.at(0);return void(t&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}if("ArrowDown"===e.key&&e.metaKey||"End"===e.key||"PageDown"===e.key){e.preventDefault();const t=this.#m.at(-1);return void(t&&(this.#O.privateActive=!1,this.#r.ariaActivedescendant=t.id,t.privateActive=!0))}}}#g(){owSlot(this.#l.value),ow(this.#u,ow.object.instanceOf(Element)),ow(this.#r,ow.object.instanceOf(GlideCoreMenuOptions));new MutationObserver((()=>{this.open&&!this.isTargetDisabled?this.#h():this.#p()})).observe(this.#u,{attributes:!0,attributeFilter:["aria-disabled","disabled"]}),this.#u.ariaHasPopup="true",this.#u.id=nanoid(),this.#u.setAttribute("aria-controls",this.#r.id),this.#r.ariaLabelledby=this.#u.id;(this.#u instanceof HTMLSpanElement||this.#u instanceof HTMLDivElement)&&this.#u instanceof HTMLElement&&(this.#u.tabIndex=0),this.open&&!this.isTargetDisabled?this.#h():this.#p()}#E(){this.isTargetDisabled?this.#p():this.#i?this.#i=!1:this.#m&&this.#m.length>0&&(this.open=!this.open)}get#m(){let e=this.#t.value?.assignedElements()?.at(0)?.children;const t=e?.[0];if(t instanceof HTMLSlotElement&&(e=t.assignedElements()),e)return[...e].filter((e=>e instanceof GlideCoreMenuLink||e instanceof GlideCoreMenuButton))}#h(){this.#k?.(),this.#u&&this.#t.value&&(this.#k=autoUpdate(this.#u,this.#t.value,(()=>{(async()=>{if(this.#u&&this.#t.value){const{x:e,y:t,placement:i}=await computePosition(this.#u,this.#t.value,{placement:this.placement,middleware:[offset(this.offset),flip()]});this.#t.value.dataset.placement=i,Object.assign(this.#t.value.style,{left:`${e}px`,top:`${t}px`})}this.#t.value?.showPopover(),this.#r&&this.#O?.id&&(this.#r.ariaActivedescendant=this.#O.id),this.#u&&(this.#u.ariaExpanded="true")})()})))}get#u(){return this.#l.value?.assignedElements().at(0)}};__decorate([property({reflect:!0,type:Number})],GlideCoreMenu.prototype,"offset",null),__decorate([property({reflect:!0,type:Boolean})],GlideCoreMenu.prototype,"open",null),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"placement",void 0),__decorate([property({reflect:!0})],GlideCoreMenu.prototype,"size",null),GlideCoreMenu=__decorate([customElement("glide-core-menu")],GlideCoreMenu);export default GlideCoreMenu;
@@ -1 +1 @@
1
- var __decorate=this&&this.__decorate||function(e,t,o,i){var l,r=arguments.length,n=r<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,o):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,o,i);else for(var a=e.length-1;a>=0;a--)(l=e[a])&&(n=(r<3?l(n):r>3?l(t,o,n):l(t,o))||n);return r>3&&n&&Object.defineProperty(t,o,n),n};import{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{nanoid}from"nanoid";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import styles from"./menu.options.styles.js";let GlideCoreMenuOptions=class GlideCoreMenuOptions extends LitElement{constructor(){super(...arguments),this.ariaActivedescendant="",this.ariaLabelledby="",this.privateSize="large",this.#e=createRef(),this.#t=nanoid()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#t,this.role="menu",this.tabIndex=-1}firstUpdated(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text])}render(){return html`<div class="${classMap({component:!0,large:"large"===this.privateSize,small:"small"===this.privateSize})}" role="none"><slot @slotchange="${this.#o}" ${ref(this.#e)}></slot></div>`}#e;#t;#o(){owSlot(this.#e.value),owSlotType(this.#e.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text])}};__decorate([property({attribute:"aria-activedescendant",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaActivedescendant",void 0),__decorate([property({attribute:"aria-labelledby",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaLabelledby",void 0),__decorate([state()],GlideCoreMenuOptions.prototype,"privateSize",void 0),GlideCoreMenuOptions=__decorate([customElement("glide-core-menu-options")],GlideCoreMenuOptions);export default GlideCoreMenuOptions;
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{LitElement,html}from"lit";import{classMap}from"lit/directives/class-map.js";import{createRef,ref}from"lit/directives/ref.js";import{customElement,property,state}from"lit/decorators.js";import{nanoid}from"nanoid";import{owSlot,owSlotType}from"./library/ow.js";import GlideCoreMenuButton from"./menu.button.js";import GlideCoreMenuLink from"./menu.link.js";import styles from"./menu.options.styles.js";let GlideCoreMenuOptions=class GlideCoreMenuOptions extends LitElement{constructor(){super(...arguments),this.ariaActivedescendant="",this.ariaLabelledby="",this.privateSize="large",this.#e=nanoid(),this.#t=createRef()}static{this.shadowRootOptions={...LitElement.shadowRootOptions,mode:"closed"}}static{this.styles=styles}connectedCallback(){super.connectedCallback(),this.id=this.#e,this.role="menu",this.tabIndex=-1}firstUpdated(){owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text])}render(){return html`<div class="${classMap({component:!0,large:"large"===this.privateSize,small:"small"===this.privateSize})}" role="none"><slot @slotchange="${this.#o}" ${ref(this.#t)}></slot></div>`}#e;#t;#o(){owSlot(this.#t.value),owSlotType(this.#t.value,[GlideCoreMenuButton,GlideCoreMenuLink,Text]),this.dispatchEvent(new Event("private-slot-change",{bubbles:!0}))}};__decorate([property({attribute:"aria-activedescendant",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaActivedescendant",void 0),__decorate([property({attribute:"aria-labelledby",reflect:!0})],GlideCoreMenuOptions.prototype,"ariaLabelledby",void 0),__decorate([state()],GlideCoreMenuOptions.prototype,"privateSize",void 0),GlideCoreMenuOptions=__decorate([customElement("glide-core-menu-options")],GlideCoreMenuOptions);export default GlideCoreMenuOptions;
@@ -0,0 +1 @@
1
+ import './menu.button.js';