@haiilo/catalyst 14.4.0 → 14.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/catalyst/catalyst.css +15 -4
  2. package/dist/catalyst/catalyst.esm.js +1 -1
  3. package/dist/catalyst/{p-CFGROHMy.js → p-7uZgmxXB.js} +2 -2
  4. package/dist/catalyst/p-7uZgmxXB.js.map +1 -0
  5. package/dist/catalyst/p-c04eb2d3.entry.js +10 -0
  6. package/dist/catalyst/p-c04eb2d3.entry.js.map +1 -0
  7. package/dist/catalyst/scss/core/_nav.scss +2 -1
  8. package/dist/catalyst/scss/core/sanitize-overwrite.scss +3 -0
  9. package/dist/catalyst/scss/index.scss +1 -0
  10. package/dist/cjs/{cat-alert_30.cjs.entry.js → cat-alert_32.cjs.entry.js} +348 -102
  11. package/dist/cjs/catalyst.cjs.js +2 -2
  12. package/dist/cjs/{index-B8-TCsLD.js → index-Ddad39qn.js} +7 -4
  13. package/dist/cjs/index-Ddad39qn.js.map +1 -0
  14. package/dist/cjs/loader.cjs.js +2 -2
  15. package/dist/collection/collection-manifest.json +3 -1
  16. package/dist/collection/components/cat-alert/cat-alert.js +1 -1
  17. package/dist/collection/components/cat-badge/cat-badge.js +1 -1
  18. package/dist/collection/components/cat-button/cat-button.css +13 -2
  19. package/dist/collection/components/cat-button-group/cat-button-group.js +1 -1
  20. package/dist/collection/components/cat-card/cat-card.js +1 -1
  21. package/dist/collection/components/cat-checkbox/cat-checkbox.js +2 -2
  22. package/dist/collection/components/cat-date/cat-date.js +2 -2
  23. package/dist/collection/components/cat-date-inline/cat-date-inline.js +4 -4
  24. package/dist/collection/components/cat-datepicker/cat-datepicker.js +3 -3
  25. package/dist/collection/components/cat-datepicker-inline/cat-datepicker-inline.js +2 -2
  26. package/dist/collection/components/cat-dropdown/cat-dropdown.js +133 -47
  27. package/dist/collection/components/cat-dropdown/cat-dropdown.js.map +1 -1
  28. package/dist/collection/components/cat-menu/cat-menu.css +9 -0
  29. package/dist/collection/components/cat-menu/cat-menu.js +652 -0
  30. package/dist/collection/components/cat-menu/cat-menu.js.map +1 -0
  31. package/dist/collection/components/cat-menu-item/cat-menu-item.js +387 -0
  32. package/dist/collection/components/cat-menu-item/cat-menu-item.js.map +1 -0
  33. package/dist/collection/components/cat-pagination/cat-pagination.js +2 -2
  34. package/dist/collection/components/cat-radio/cat-radio.js +2 -2
  35. package/dist/collection/components/cat-radio-group/cat-radio-group.js +1 -1
  36. package/dist/collection/components/cat-scrollable/cat-scrollable.js +3 -3
  37. package/dist/collection/components/cat-select/cat-select.js +14 -18
  38. package/dist/collection/components/cat-select/cat-select.js.map +1 -1
  39. package/dist/collection/components/cat-select-demo/cat-select-demo.js +1 -1
  40. package/dist/collection/components/cat-skeleton/cat-skeleton.js +1 -1
  41. package/dist/collection/components/cat-spinner/cat-spinner.js +2 -2
  42. package/dist/collection/components/cat-tab/cat-tab.js +1 -1
  43. package/dist/collection/components/cat-tabs/cat-tabs.js +1 -1
  44. package/dist/collection/components/cat-tag/cat-tag.js +1 -1
  45. package/dist/collection/components/cat-textarea/cat-textarea.js +3 -3
  46. package/dist/collection/components/cat-time/cat-time.css +0 -9
  47. package/dist/collection/components/cat-time/cat-time.js +4 -5
  48. package/dist/collection/components/cat-time/cat-time.js.map +1 -1
  49. package/dist/collection/components/cat-toggle/cat-toggle.js +2 -2
  50. package/dist/collection/index.js.map +1 -1
  51. package/dist/collection/scss/core/_nav.scss +2 -1
  52. package/dist/collection/scss/core/sanitize-overwrite.scss +3 -0
  53. package/dist/collection/scss/index.scss +1 -0
  54. package/dist/components/cat-alert.js +1 -1
  55. package/dist/components/cat-badge.js +1 -1
  56. package/dist/components/cat-button-group.js +1 -1
  57. package/dist/components/cat-button2.js +1 -1
  58. package/dist/components/cat-button2.js.map +1 -1
  59. package/dist/components/cat-card.js +1 -1
  60. package/dist/components/cat-checkbox2.js +2 -2
  61. package/dist/components/cat-date-inline2.js +4 -4
  62. package/dist/components/cat-date.js +2 -2
  63. package/dist/components/cat-datepicker-inline.js +2 -2
  64. package/dist/components/cat-datepicker.js +3 -3
  65. package/dist/components/cat-dropdown2.js +77 -44
  66. package/dist/components/cat-dropdown2.js.map +1 -1
  67. package/dist/components/cat-menu-item.d.ts +11 -0
  68. package/dist/components/cat-menu-item.js +9 -0
  69. package/dist/components/cat-menu-item.js.map +1 -0
  70. package/dist/components/cat-menu-item2.js +111 -0
  71. package/dist/components/cat-menu-item2.js.map +1 -0
  72. package/dist/components/cat-menu.d.ts +11 -0
  73. package/dist/components/cat-menu.js +9 -0
  74. package/dist/components/cat-menu.js.map +1 -0
  75. package/dist/components/cat-menu2.js +227 -0
  76. package/dist/components/cat-menu2.js.map +1 -0
  77. package/dist/components/cat-pagination.js +2 -2
  78. package/dist/components/cat-radio-group.js +1 -1
  79. package/dist/components/cat-radio.js +2 -2
  80. package/dist/components/cat-scrollable2.js +3 -3
  81. package/dist/components/cat-select-demo.js +1 -1
  82. package/dist/components/cat-select2.js +5 -5
  83. package/dist/components/cat-select2.js.map +1 -1
  84. package/dist/components/cat-skeleton2.js +1 -1
  85. package/dist/components/cat-spinner2.js +2 -2
  86. package/dist/components/cat-tab.js +1 -1
  87. package/dist/components/cat-tabs.js +1 -1
  88. package/dist/components/cat-tag.js +1 -1
  89. package/dist/components/cat-textarea.js +3 -3
  90. package/dist/components/cat-time.js +25 -14
  91. package/dist/components/cat-time.js.map +1 -1
  92. package/dist/components/cat-toggle.js +2 -2
  93. package/dist/esm/{cat-alert_30.entry.js → cat-alert_32.entry.js} +347 -103
  94. package/dist/esm/catalyst.js +3 -3
  95. package/dist/esm/{index-CFGROHMy.js → index-7uZgmxXB.js} +7 -4
  96. package/dist/esm/index-7uZgmxXB.js.map +1 -0
  97. package/dist/esm/loader.js +3 -3
  98. package/dist/types/components/cat-dropdown/cat-dropdown.d.ts +17 -2
  99. package/dist/types/components/cat-menu/cat-menu.d.ts +124 -0
  100. package/dist/types/components/cat-menu-item/cat-menu-item.d.ts +80 -0
  101. package/dist/types/components/cat-select/cat-select.d.ts +3 -2
  102. package/dist/types/components.d.ts +416 -9
  103. package/dist/types/index.d.ts +2 -1
  104. package/package.json +2 -2
  105. package/dist/catalyst/p-76436f4e.entry.js +0 -10
  106. package/dist/catalyst/p-76436f4e.entry.js.map +0 -1
  107. package/dist/catalyst/p-CFGROHMy.js.map +0 -1
  108. package/dist/cjs/index-B8-TCsLD.js.map +0 -1
  109. package/dist/esm/index-CFGROHMy.js.map +0 -1
@@ -13,12 +13,13 @@ export class CatDropdown {
13
13
  constructor() {
14
14
  this.id = nextUniqueId++;
15
15
  this._isOpen = false;
16
+ this.tabbableOptions = { getShadowRoot: true };
16
17
  /**
17
18
  * Tracking the origin of opening the dropdown and specify if initial focus should be set.
18
19
  * Currently we set it only when the origin is keyboard.
19
20
  * We might not need to track this in future when focus-visible support is improved across browsers
20
21
  */
21
- this.hasInitialFocus = false;
22
+ this.isFocusVisible = false;
22
23
  /**
23
24
  * The placement of the dropdown.
24
25
  */
@@ -35,6 +36,7 @@ export class CatDropdown {
35
36
  this.noAutoClose = false;
36
37
  /**
37
38
  * Do not navigate focus inside the dropdown via vertical arrow keys.
39
+ * @deprecated use cat-menu
38
40
  */
39
41
  this.arrowNavigation = 'vertical';
40
42
  /**
@@ -57,6 +59,7 @@ export class CatDropdown {
57
59
  this.noInitialFocus = false;
58
60
  /**
59
61
  * Trigger element will not receive focus when dropdown is closed.
62
+ * Please use this property carefully, consider using cat-menu over using this property
60
63
  */
61
64
  this.noReturnFocus = false;
62
65
  /**
@@ -64,6 +67,12 @@ export class CatDropdown {
64
67
  * Can be useful when trigger is rendered dynamically.
65
68
  */
66
69
  this.delayedTriggerInit = false;
70
+ /**
71
+ * Whether the focus should be trapped inside dropdown popup.
72
+ * Use it only when the dropdown popup content has role dialog.
73
+ * @internal
74
+ */
75
+ this.focusTrap = true;
67
76
  }
68
77
  /**
69
78
  * Whether the dropdown is open.
@@ -74,7 +83,7 @@ export class CatDropdown {
74
83
  }
75
84
  clickHandler(event) {
76
85
  if (!this.trigger && this.delayedTriggerInit) {
77
- this.hasInitialFocus = this.isEventOriginFromKeyboard(event.detail);
86
+ this.isFocusVisible = this.isEventOriginFromKeyboard(event.detail);
78
87
  this.initTrigger();
79
88
  this.toggle();
80
89
  }
@@ -90,6 +99,20 @@ export class CatDropdown {
90
99
  this.close();
91
100
  }
92
101
  }
102
+ keydownHandler(event) {
103
+ if (this.isOpen && event.key === 'Escape') {
104
+ this.close();
105
+ }
106
+ }
107
+ globalClickHandler(event) {
108
+ this.handleClickOutside(event);
109
+ }
110
+ globalMouseDownHandler(event) {
111
+ this.handleClickOutside(event);
112
+ }
113
+ globalTouchStartHandler(event) {
114
+ this.handleClickOutside(event);
115
+ }
93
116
  /**
94
117
  * Toggles the dropdown.
95
118
  */
@@ -109,58 +132,55 @@ export class CatDropdown {
109
132
  }
110
133
  this._isOpen = null;
111
134
  this.content.style.display = 'block';
112
- this.hasInitialFocus = isFocusVisible ?? this.hasInitialFocus;
135
+ this.isFocusVisible = isFocusVisible ?? this.isFocusVisible;
113
136
  const trigger = this.anchor || this.trigger;
114
137
  if (trigger) {
115
138
  this.cleanupFloatingUi = autoUpdate(trigger, this.content, () => this.update(trigger));
116
139
  }
117
140
  // give CSS transition time to apply
118
- setTimeout(() => {
141
+ requestAnimationFrame(() => {
119
142
  this._isOpen = true;
120
143
  this.content.classList.add('show');
121
144
  this.trigger?.setAttribute('aria-expanded', 'true');
122
- this.trap = this.trap
123
- ? this.trap.updateContainerElements(this.content)
124
- : focusTrap.createFocusTrap(this.content, {
125
- tabbableOptions: {
126
- getShadowRoot: true
127
- },
128
- allowOutsideClick: true,
129
- clickOutsideDeactivates: event => !this.noAutoClose &&
130
- // check if click was outside of the dropdown content
131
- !event.composedPath().includes(this.content) &&
132
- // check if click was not on an element marked with data-dropdown-no-close
133
- !event.composedPath().find(el => this.hasAttribute(el, 'data-dropdown-no-close')),
134
- onPostDeactivate: () => this.close(),
135
- onPostActivate: () => this.catOpen.emit(),
136
- setReturnFocus: elem => (this.noReturnFocus ? false : this.trigger || elem),
137
- isKeyForward: event => {
138
- if ((this.arrowNavigation === 'horizontal' && event.key === 'ArrowRight') ||
139
- (this.arrowNavigation === 'vertical' && event.key === 'ArrowDown')) {
140
- event.preventDefault();
141
- return true;
142
- }
143
- return event.key === 'Tab';
144
- },
145
- isKeyBackward: event => {
146
- if ((this.arrowNavigation === 'horizontal' && event.key === 'ArrowLeft') ||
147
- (this.arrowNavigation === 'vertical' && event.key === 'ArrowUp')) {
148
- event.preventDefault();
149
- return true;
145
+ if (this.focusTrap) {
146
+ this.trap = this.trap
147
+ ? this.trap.updateContainerElements(this.content)
148
+ : focusTrap.createFocusTrap(this.content, {
149
+ tabbableOptions: this.tabbableOptions,
150
+ allowOutsideClick: true,
151
+ onPostActivate: () => this.catOpen.emit(),
152
+ setReturnFocus: elem => (!this.isFocusVisible || this.noReturnFocus ? false : this.trigger || elem),
153
+ isKeyForward: event => {
154
+ if ((this.arrowNavigation === 'horizontal' && event.key === 'ArrowRight') ||
155
+ (this.arrowNavigation === 'vertical' && event.key === 'ArrowDown')) {
156
+ event.preventDefault();
157
+ return true;
158
+ }
159
+ return event.key === 'Tab';
160
+ },
161
+ isKeyBackward: event => {
162
+ if ((this.arrowNavigation === 'horizontal' && event.key === 'ArrowLeft') ||
163
+ (this.arrowNavigation === 'vertical' && event.key === 'ArrowUp')) {
164
+ event.preventDefault();
165
+ return true;
166
+ }
167
+ return event.key === 'Tab' && event.shiftKey;
168
+ },
169
+ initialFocus: () => {
170
+ return this.isFocusVisible ? undefined : false;
150
171
  }
151
- return event.key === 'Tab' && event.shiftKey;
152
- },
153
- initialFocus: () => {
154
- return this.hasInitialFocus && !this.noInitialFocus ? undefined : false;
155
- }
156
- });
157
- this.trap.activate();
172
+ });
173
+ this.trap.activate();
174
+ }
175
+ else {
176
+ this.catOpen.emit();
177
+ }
158
178
  });
159
179
  }
160
180
  /**
161
181
  * Closes the dropdown.
162
182
  */
163
- async close() {
183
+ async close(shouldReturnFocus = this.isFocusVisible) {
164
184
  if (!this._isOpen) {
165
185
  return; // busy or closed
166
186
  }
@@ -168,6 +188,9 @@ export class CatDropdown {
168
188
  this.trap?.deactivate();
169
189
  this.trap = undefined;
170
190
  this.content.classList.remove('show');
191
+ if (shouldReturnFocus) {
192
+ this.trigger?.focus();
193
+ }
171
194
  // give CSS transition time to apply
172
195
  setTimeout(() => {
173
196
  this._isOpen = false;
@@ -192,7 +215,16 @@ export class CatDropdown {
192
215
  this.cleanupFloatingUi = undefined;
193
216
  }
194
217
  render() {
195
- return (h(Host, { key: '0b02719eae82077fd11262620f260c86f6ef5854' }, h("slot", { key: '809f803bad06e9b9dfab850809709191f8a3bc2e', name: "anchor", ref: el => (this.anchorSlot = el) }), h("slot", { key: 'b6e32999e3cb4e4e4e9a4c534a22a17ae7708486', name: "trigger", ref: el => (this.triggerSlot = el) }), h("div", { key: '47592ef2faeb4a5ba26185a98952c56c3b0804f6', id: this.contentId, class: { content: true, 'overflow-auto': !this.overflow, justified: this.justify, aligned: !this.justify }, ref: el => (this.content = el) }, h("slot", { key: '8b6ba45f55abf7983a66550f161652e5a40205d7', name: "content" }))));
218
+ return (h(Host, { key: 'b3cd898551dc3e6d5396db1a4a14bc97cf4a2024' }, h("slot", { key: '6875cfad353891deb54ebcd5155d7ea466384131', name: "anchor", ref: el => (this.anchorSlot = el) }), h("slot", { key: '93fdda4c49a7a956f72548699200feb309779081', name: "trigger", ref: el => (this.triggerSlot = el) }), h("div", { key: '13a68b5f706e61e87599c463e58f1bf932b2d261', id: this.contentId, class: { content: true, 'overflow-auto': !this.overflow, justified: this.justify, aligned: !this.justify }, ref: el => (this.content = el) }, h("slot", { key: '06357a4a970241938900853d78c88427c6a9e69a', name: "content" }))));
219
+ }
220
+ handleClickOutside(event) {
221
+ if (!this.noAutoClose &&
222
+ // check if click was outside of the dropdown content
223
+ !event.composedPath().includes(this.content) &&
224
+ // check if click was not on an element marked with data-dropdown-no-close
225
+ !event.composedPath().find(el => this.hasAttribute(el, 'data-dropdown-no-close'))) {
226
+ this.close();
227
+ }
196
228
  }
197
229
  get contentId() {
198
230
  return `cat-dropdown-${this.id}`;
@@ -204,7 +236,7 @@ export class CatDropdown {
204
236
  this.trigger.setAttribute('aria-expanded', 'false');
205
237
  this.trigger.setAttribute('aria-controls', this.contentId);
206
238
  this.trigger.addEventListener('click', (event) => {
207
- this.hasInitialFocus = this.isEventOriginFromKeyboard(event);
239
+ this.isFocusVisible = this.isEventOriginFromKeyboard(event);
208
240
  this.toggle();
209
241
  });
210
242
  }
@@ -282,7 +314,7 @@ export class CatDropdown {
282
314
  computePosition(anchorElement, this.content, {
283
315
  strategy: 'fixed',
284
316
  placement: this.placement,
285
- middleware: [offset(CatDropdown.OFFSET), ...middleware, ...resize]
317
+ middleware: [...middleware, ...resize]
286
318
  }).then(({ x, y, placement }) => {
287
319
  this.content.dataset.placement = placement;
288
320
  Object.assign(this.content.style, {
@@ -386,7 +418,10 @@ export class CatDropdown {
386
418
  "required": false,
387
419
  "optional": false,
388
420
  "docs": {
389
- "tags": [],
421
+ "tags": [{
422
+ "name": "deprecated",
423
+ "text": "use cat-menu"
424
+ }],
390
425
  "text": "Do not navigate focus inside the dropdown via vertical arrow keys."
391
426
  },
392
427
  "getter": false,
@@ -492,7 +527,7 @@ export class CatDropdown {
492
527
  "optional": false,
493
528
  "docs": {
494
529
  "tags": [],
495
- "text": "Trigger element will not receive focus when dropdown is closed."
530
+ "text": "Trigger element will not receive focus when dropdown is closed.\nPlease use this property carefully, consider using cat-menu over using this property"
496
531
  },
497
532
  "getter": false,
498
533
  "setter": false,
@@ -519,6 +554,29 @@ export class CatDropdown {
519
554
  "reflect": false,
520
555
  "attribute": "delayed-trigger-init",
521
556
  "defaultValue": "false"
557
+ },
558
+ "focusTrap": {
559
+ "type": "boolean",
560
+ "mutable": false,
561
+ "complexType": {
562
+ "original": "boolean",
563
+ "resolved": "boolean",
564
+ "references": {}
565
+ },
566
+ "required": false,
567
+ "optional": false,
568
+ "docs": {
569
+ "tags": [{
570
+ "name": "internal",
571
+ "text": undefined
572
+ }],
573
+ "text": "Whether the focus should be trapped inside dropdown popup.\nUse it only when the dropdown popup content has role dialog."
574
+ },
575
+ "getter": false,
576
+ "setter": false,
577
+ "reflect": false,
578
+ "attribute": "focus-trap",
579
+ "defaultValue": "true"
522
580
  }
523
581
  };
524
582
  }
@@ -610,8 +668,12 @@ export class CatDropdown {
610
668
  },
611
669
  "close": {
612
670
  "complexType": {
613
- "signature": "() => Promise<void>",
614
- "parameters": [],
671
+ "signature": "(shouldReturnFocus?: boolean) => Promise<void>",
672
+ "parameters": [{
673
+ "name": "shouldReturnFocus",
674
+ "type": "boolean",
675
+ "docs": ""
676
+ }],
615
677
  "references": {
616
678
  "Promise": {
617
679
  "location": "global",
@@ -634,6 +696,30 @@ export class CatDropdown {
634
696
  "target": undefined,
635
697
  "capture": false,
636
698
  "passive": false
699
+ }, {
700
+ "name": "keydown",
701
+ "method": "keydownHandler",
702
+ "target": undefined,
703
+ "capture": false,
704
+ "passive": false
705
+ }, {
706
+ "name": "click",
707
+ "method": "globalClickHandler",
708
+ "target": "document",
709
+ "capture": true,
710
+ "passive": false
711
+ }, {
712
+ "name": "mousedown",
713
+ "method": "globalMouseDownHandler",
714
+ "target": "document",
715
+ "capture": true,
716
+ "passive": true
717
+ }, {
718
+ "name": "touchstart",
719
+ "method": "globalTouchStartHandler",
720
+ "target": "document",
721
+ "capture": true,
722
+ "passive": false
637
723
  }];
638
724
  }
639
725
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cat-dropdown.js","sourceRoot":"","sources":["../../../src/components/cat-dropdown/cat-dropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import { autoUpdate, computePosition, flip, offset, Placement, ReferenceElement, shift, size } from '@floating-ui/dom';\nimport { timeTransitionS } from '@haiilo/catalyst-tokens';\nimport { Component, Event, EventEmitter, h, Host, Listen, Method, Prop } from '@stencil/core';\nimport * as focusTrap from 'focus-trap';\nimport type { FocusableElement } from 'tabbable';\nimport firstTabbable from '../../utils/first-tabbable';\nimport findFirstTabbableIncludeHidden from '../../utils/first-tabbable-with-visibility-hidden';\n\nlet nextUniqueId = 0;\n\n/**\n * A dropdown component to display a list of actions in a dropdown menu or to\n * show additional content on demand.\n */\n@Component({\n tag: 'cat-dropdown',\n styleUrl: 'cat-dropdown.scss',\n shadow: true\n})\nexport class CatDropdown {\n private static readonly OFFSET = 4;\n private readonly id = nextUniqueId++;\n private triggerSlot!: HTMLSlotElement;\n private trigger?: FocusableElement;\n private anchorSlot!: HTMLSlotElement;\n private anchor?: Element;\n private content!: HTMLElement;\n private trap?: focusTrap.FocusTrap;\n private _isOpen: boolean | null = false;\n private cleanupFloatingUi?: () => void;\n /**\n * Tracking the origin of opening the dropdown and specify if initial focus should be set.\n * Currently we set it only when the origin is keyboard.\n * We might not need to track this in future when focus-visible support is improved across browsers\n */\n private hasInitialFocus = false;\n\n /**\n * The placement of the dropdown.\n */\n @Prop() placement: Placement = 'bottom-start';\n\n /**\n * Make the dropdown match the width of the reference regardless of its\n * contents. Note that this only applies to the minimum width of the\n * dropdown. The maximum width is still limited by the viewport.\n */\n @Prop() justify = false;\n\n /**\n * Do not close the dropdown on outside clicks.\n */\n @Prop() noAutoClose = false;\n\n /**\n * Do not navigate focus inside the dropdown via vertical arrow keys.\n */\n @Prop() arrowNavigation: 'horizontal' | 'vertical' | 'none' = 'vertical';\n\n /**\n * Do not change the size of the dropdown to ensure it isn’t too big to fit\n * in the viewport (or more specifically, its clipping context).\n */\n @Prop() noResize = false;\n\n /**\n * Allow overflow when dropdown is open.\n */\n @Prop() overflow = false;\n\n /**\n * No element in dropdown will receive focus when dropdown is open.\n * By default, the first element in tab order will receive a focus.\n * @deprecated\n * Using noInitialFocus property would be a bad practice from a11y perspective.\n * We always want visible focus to jump inside the dropdown when user uses keyboard and noInitialFocus allows to turn it off which might introduce a bug.\n * hasInitialFocus should resolve the cause of the original problem instead.\n */\n @Prop() noInitialFocus = false;\n\n /**\n * Whether the dropdown is open.\n * @readonly\n */\n @Prop() get isOpen(): boolean {\n return this._isOpen ?? false;\n }\n\n /**\n * Trigger element will not receive focus when dropdown is closed.\n */\n @Prop() noReturnFocus = false;\n\n /**\n * Whether the dropdown trigger should be initialized only before first opening.\n * Can be useful when trigger is rendered dynamically.\n */\n @Prop() delayedTriggerInit = false;\n\n /**\n * Emitted when the dropdown is opened.\n */\n @Event() catOpen!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the dropdown is closed.\n */\n @Event() catClose!: EventEmitter<FocusEvent>;\n\n @Listen('catClick')\n clickHandler(event: CustomEvent<MouseEvent>) {\n if (!this.trigger && this.delayedTriggerInit) {\n this.hasInitialFocus = this.isEventOriginFromKeyboard(event.detail);\n this.initTrigger();\n this.toggle();\n }\n\n // hide dropdown on button clicks inside the dropdown content\n const path = event.composedPath();\n if (\n !this.noAutoClose &&\n // check if click was inside of the dropdown content\n path.includes(this.content) &&\n // check if click was not on a trigger for a sub-dropdown\n (event.target as Element)?.slot !== 'trigger' &&\n // check if click was not an element marked with data-dropdown-no-close\n !path.slice(0, path.indexOf(this.content)).find(el => this.hasAttribute(el, 'data-dropdown-no-close'))\n ) {\n this.close();\n }\n }\n\n /**\n * Toggles the dropdown.\n */\n @Method()\n async toggle(): Promise<void> {\n this._isOpen ? this.close() : this.open();\n }\n\n /**\n * Opens the dropdown.\n * @param isFocusVisible is dropdown should receive visible focus when it's opened.\n */\n @Method()\n async open(isFocusVisible?: boolean): Promise<void> {\n if (!this.trigger && this.delayedTriggerInit) {\n this.initTrigger();\n }\n\n if (this.isOpen === null || this.isOpen) {\n return; // busy or open\n }\n\n this._isOpen = null;\n this.content.style.display = 'block';\n this.hasInitialFocus = isFocusVisible ?? this.hasInitialFocus;\n\n const trigger = this.anchor || this.trigger;\n if (trigger) {\n this.cleanupFloatingUi = autoUpdate(trigger, this.content, () => this.update(trigger));\n }\n // give CSS transition time to apply\n setTimeout(() => {\n this._isOpen = true;\n this.content.classList.add('show');\n this.trigger?.setAttribute('aria-expanded', 'true');\n this.trap = this.trap\n ? this.trap.updateContainerElements(this.content)\n : focusTrap.createFocusTrap(this.content, {\n tabbableOptions: {\n getShadowRoot: true\n },\n allowOutsideClick: true,\n clickOutsideDeactivates: event =>\n !this.noAutoClose &&\n // check if click was outside of the dropdown content\n !event.composedPath().includes(this.content) &&\n // check if click was not on an element marked with data-dropdown-no-close\n !event.composedPath().find(el => this.hasAttribute(el, 'data-dropdown-no-close')),\n onPostDeactivate: () => this.close(),\n onPostActivate: () => this.catOpen.emit(),\n setReturnFocus: elem => (this.noReturnFocus ? false : this.trigger || elem),\n isKeyForward: event => {\n if (\n (this.arrowNavigation === 'horizontal' && event.key === 'ArrowRight') ||\n (this.arrowNavigation === 'vertical' && event.key === 'ArrowDown')\n ) {\n event.preventDefault();\n return true;\n }\n return event.key === 'Tab';\n },\n isKeyBackward: event => {\n if (\n (this.arrowNavigation === 'horizontal' && event.key === 'ArrowLeft') ||\n (this.arrowNavigation === 'vertical' && event.key === 'ArrowUp')\n ) {\n event.preventDefault();\n return true;\n }\n return event.key === 'Tab' && event.shiftKey;\n },\n initialFocus: () => {\n return this.hasInitialFocus && !this.noInitialFocus ? undefined : false;\n }\n });\n this.trap.activate();\n });\n }\n\n /**\n * Closes the dropdown.\n */\n @Method()\n async close(): Promise<void> {\n if (!this._isOpen) {\n return; // busy or closed\n }\n\n this._isOpen = null;\n this.trap?.deactivate();\n this.trap = undefined;\n this.content.classList.remove('show');\n // give CSS transition time to apply\n setTimeout(() => {\n this._isOpen = false;\n this.content.classList.remove('show');\n this.content.style.display = '';\n this.trigger?.setAttribute('aria-expanded', 'false');\n this.cleanupFloatingUi?.();\n this.cleanupFloatingUi = undefined;\n this.catClose.emit();\n }, timeTransitionS);\n }\n\n componentDidLoad() {\n this.initAnchor();\n if (!this.delayedTriggerInit) {\n this.initTrigger();\n }\n }\n\n disconnectedCallback() {\n this.trap?.deactivate();\n this.trap = undefined;\n this.cleanupFloatingUi?.();\n this.cleanupFloatingUi = undefined;\n }\n\n render() {\n return (\n <Host>\n <slot name=\"anchor\" ref={el => (this.anchorSlot = el as HTMLSlotElement)}></slot>\n <slot name=\"trigger\" ref={el => (this.triggerSlot = el as HTMLSlotElement)}></slot>\n <div\n id={this.contentId}\n class={{ content: true, 'overflow-auto': !this.overflow, justified: this.justify, aligned: !this.justify }}\n ref={el => (this.content = el as HTMLElement)}\n >\n <slot name=\"content\"></slot>\n </div>\n </Host>\n );\n }\n\n private get contentId() {\n return `cat-dropdown-${this.id}`;\n }\n\n private initTrigger() {\n this.trigger = this.findTrigger();\n const ariaHaspopup = this.trigger.getAttribute('aria-haspopup');\n this.trigger.setAttribute('aria-haspopup', ariaHaspopup ?? 'true');\n this.trigger.setAttribute('aria-expanded', 'false');\n this.trigger.setAttribute('aria-controls', this.contentId);\n this.trigger.addEventListener('click', (event: Event) => {\n this.hasInitialFocus = this.isEventOriginFromKeyboard(event as UIEvent);\n this.toggle();\n });\n }\n\n private isEventOriginFromKeyboard(event: UIEvent): boolean {\n return event.detail === 0;\n }\n\n private initAnchor() {\n this.anchor = (this.anchorSlot?.assignedElements?.() || [])[0];\n }\n\n private findTrigger() {\n let trigger: FocusableElement | undefined;\n let elems = this.triggerSlot?.assignedElements?.() || [];\n while (!trigger && elems.length) {\n const elem = elems.shift();\n trigger = elem?.hasAttribute('data-trigger')\n ? (elem as HTMLElement)\n : (elem?.querySelector('[data-trigger]') ?? undefined);\n }\n if (!trigger) {\n trigger = firstTabbable(this.triggerSlot);\n }\n // if no tabbable element is still found let's attempt to search through elements with visibility:hidden styles\n // which stencil assigns to component in prehydration state\n if (!trigger) {\n elems = this.triggerSlot?.assignedElements?.() || [];\n while (!trigger && elems.length) {\n const elem = elems.shift();\n trigger = findFirstTabbableIncludeHidden(elem as HTMLElement);\n }\n }\n if (!trigger) {\n throw new Error('Cannot find tabbable element. Use [data-trigger] to set the trigger.');\n }\n return trigger;\n }\n\n private update(anchorElement: ReferenceElement | undefined, justify = this.justify) {\n if (anchorElement) {\n const resize = this.noResize\n ? []\n : [\n size({\n padding: CatDropdown.OFFSET,\n apply({ rects, availableWidth, availableHeight, elements }) {\n if (justify) {\n Object.assign(elements.floating.style, {\n minWidth: `${rects.reference.width}px`,\n maxWidth: `${rects.reference.width}px`,\n maxHeight: `${availableHeight}px`\n });\n } else {\n Object.assign(elements.floating.style, {\n maxWidth: `${availableWidth}px`,\n maxHeight: `${availableHeight}px`\n });\n }\n }\n })\n ];\n const middleware = [offset(CatDropdown.OFFSET)];\n const flipMiddleware = flip({\n // Ensure we flip to the perpendicular axis if it doesn't fit\n // on narrow viewports.\n crossAxis: 'alignment',\n fallbackAxisSideDirection: 'end'\n });\n const shiftMiddleware = shift();\n\n // Prioritize flip over shift for edge-aligned placements only.\n if (this.placement.includes('-')) {\n middleware.push(flipMiddleware, shiftMiddleware);\n } else {\n middleware.push(shiftMiddleware, flipMiddleware);\n }\n computePosition(anchorElement, this.content, {\n strategy: 'fixed',\n placement: this.placement,\n middleware: [offset(CatDropdown.OFFSET), ...middleware, ...resize]\n }).then(({ x, y, placement }) => {\n this.content.dataset.placement = placement;\n Object.assign(this.content.style, {\n left: `${x}px`,\n top: `${y}px`\n });\n });\n }\n }\n\n private hasAttribute(elem: EventTarget, attr: string) {\n return elem instanceof HTMLElement && elem.hasAttribute(attr);\n }\n}\n"]}
1
+ {"version":3,"file":"cat-dropdown.js","sourceRoot":"","sources":["../../../src/components/cat-dropdown/cat-dropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import { autoUpdate, computePosition, flip, offset, Placement, ReferenceElement, shift, size } from '@floating-ui/dom';\nimport { timeTransitionS } from '@haiilo/catalyst-tokens';\nimport { Component, Event, EventEmitter, h, Host, Listen, Method, Prop } from '@stencil/core';\nimport * as focusTrap from 'focus-trap';\nimport { FocusableElement } from 'tabbable';\nimport firstTabbable from '../../utils/first-tabbable';\nimport findFirstTabbableIncludeHidden from '../../utils/first-tabbable-with-visibility-hidden';\n\nlet nextUniqueId = 0;\nexport type DropdownPlacement = Placement;\n\n/**\n * A dropdown component to display a list of actions in a dropdown menu or to\n * show additional content on demand.\n */\n@Component({\n tag: 'cat-dropdown',\n styleUrl: 'cat-dropdown.scss',\n shadow: true\n})\nexport class CatDropdown {\n private static readonly OFFSET = 4;\n private readonly id = nextUniqueId++;\n private triggerSlot!: HTMLSlotElement;\n private trigger?: FocusableElement;\n private anchorSlot!: HTMLSlotElement;\n private anchor?: Element;\n private content!: HTMLElement;\n private trap?: focusTrap.FocusTrap;\n private _isOpen: boolean | null = false;\n private cleanupFloatingUi?: () => void;\n private readonly tabbableOptions = { getShadowRoot: true };\n /**\n * Tracking the origin of opening the dropdown and specify if initial focus should be set.\n * Currently we set it only when the origin is keyboard.\n * We might not need to track this in future when focus-visible support is improved across browsers\n */\n private isFocusVisible = false;\n\n /**\n * The placement of the dropdown.\n */\n @Prop() placement: Placement = 'bottom-start';\n\n /**\n * Make the dropdown match the width of the reference regardless of its\n * contents. Note that this only applies to the minimum width of the\n * dropdown. The maximum width is still limited by the viewport.\n */\n @Prop() justify = false;\n\n /**\n * Do not close the dropdown on outside clicks.\n */\n @Prop() noAutoClose = false;\n\n /**\n * Do not navigate focus inside the dropdown via vertical arrow keys.\n * @deprecated use cat-menu\n */\n @Prop() arrowNavigation: 'horizontal' | 'vertical' | 'none' = 'vertical';\n\n /**\n * Do not change the size of the dropdown to ensure it isn’t too big to fit\n * in the viewport (or more specifically, its clipping context).\n */\n @Prop() noResize = false;\n\n /**\n * Allow overflow when dropdown is open.\n */\n @Prop() overflow = false;\n\n /**\n * No element in dropdown will receive focus when dropdown is open.\n * By default, the first element in tab order will receive a focus.\n * @deprecated\n * Using noInitialFocus property would be a bad practice from a11y perspective.\n * We always want visible focus to jump inside the dropdown when user uses keyboard and noInitialFocus allows to turn it off which might introduce a bug.\n * hasInitialFocus should resolve the cause of the original problem instead.\n */\n @Prop() noInitialFocus = false;\n\n /**\n * Whether the dropdown is open.\n * @readonly\n */\n @Prop() get isOpen(): boolean {\n return this._isOpen ?? false;\n }\n\n /**\n * Trigger element will not receive focus when dropdown is closed.\n * Please use this property carefully, consider using cat-menu over using this property\n */\n @Prop() noReturnFocus = false;\n\n /**\n * Whether the dropdown trigger should be initialized only before first opening.\n * Can be useful when trigger is rendered dynamically.\n */\n @Prop() delayedTriggerInit = false;\n\n /**\n * Whether the focus should be trapped inside dropdown popup.\n * Use it only when the dropdown popup content has role dialog.\n * @internal\n */\n @Prop() focusTrap = true;\n\n /**\n * Emitted when the dropdown is opened.\n */\n @Event() catOpen!: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when the dropdown is closed.\n */\n @Event() catClose!: EventEmitter<FocusEvent>;\n\n @Listen('catClick')\n clickHandler(event: CustomEvent<MouseEvent>) {\n if (!this.trigger && this.delayedTriggerInit) {\n this.isFocusVisible = this.isEventOriginFromKeyboard(event.detail);\n this.initTrigger();\n this.toggle();\n }\n\n // hide dropdown on button clicks inside the dropdown content\n const path = event.composedPath();\n if (\n !this.noAutoClose &&\n // check if click was inside of the dropdown content\n path.includes(this.content) &&\n // check if click was not on a trigger for a sub-dropdown\n (event.target as Element)?.slot !== 'trigger' &&\n // check if click was not an element marked with data-dropdown-no-close\n !path.slice(0, path.indexOf(this.content)).find(el => this.hasAttribute(el, 'data-dropdown-no-close'))\n ) {\n this.close();\n }\n }\n\n @Listen('keydown')\n keydownHandler(event: KeyboardEvent) {\n if (this.isOpen && event.key === 'Escape') {\n this.close();\n }\n }\n\n @Listen('click', { target: 'document', capture: true })\n globalClickHandler(event: MouseEvent) {\n this.handleClickOutside(event);\n }\n\n @Listen('mousedown', { target: 'document', capture: true })\n globalMouseDownHandler(event: MouseEvent) {\n this.handleClickOutside(event);\n }\n\n @Listen('touchstart', { target: 'document', capture: true, passive: false })\n globalTouchStartHandler(event: MouseEvent) {\n this.handleClickOutside(event);\n }\n\n /**\n * Toggles the dropdown.\n */\n @Method()\n async toggle(): Promise<void> {\n this._isOpen ? this.close() : this.open();\n }\n\n /**\n * Opens the dropdown.\n * @param isFocusVisible is dropdown should receive visible focus when it's opened.\n */\n @Method()\n async open(isFocusVisible?: boolean): Promise<void> {\n if (!this.trigger && this.delayedTriggerInit) {\n this.initTrigger();\n }\n\n if (this.isOpen === null || this.isOpen) {\n return; // busy or open\n }\n\n this._isOpen = null;\n this.content.style.display = 'block';\n this.isFocusVisible = isFocusVisible ?? this.isFocusVisible;\n\n const trigger = this.anchor || this.trigger;\n if (trigger) {\n this.cleanupFloatingUi = autoUpdate(trigger, this.content, () => this.update(trigger));\n }\n // give CSS transition time to apply\n requestAnimationFrame(() => {\n this._isOpen = true;\n this.content.classList.add('show');\n this.trigger?.setAttribute('aria-expanded', 'true');\n\n if (this.focusTrap) {\n this.trap = this.trap\n ? this.trap.updateContainerElements(this.content)\n : focusTrap.createFocusTrap(this.content, {\n tabbableOptions: this.tabbableOptions,\n allowOutsideClick: true,\n onPostActivate: () => this.catOpen.emit(),\n setReturnFocus: elem => (!this.isFocusVisible || this.noReturnFocus ? false : this.trigger || elem),\n isKeyForward: event => {\n if (\n (this.arrowNavigation === 'horizontal' && event.key === 'ArrowRight') ||\n (this.arrowNavigation === 'vertical' && event.key === 'ArrowDown')\n ) {\n event.preventDefault();\n return true;\n }\n return event.key === 'Tab';\n },\n isKeyBackward: event => {\n if (\n (this.arrowNavigation === 'horizontal' && event.key === 'ArrowLeft') ||\n (this.arrowNavigation === 'vertical' && event.key === 'ArrowUp')\n ) {\n event.preventDefault();\n return true;\n }\n return event.key === 'Tab' && event.shiftKey;\n },\n initialFocus: () => {\n return this.isFocusVisible ? undefined : false;\n }\n });\n this.trap.activate();\n } else {\n this.catOpen.emit();\n }\n });\n }\n\n /**\n * Closes the dropdown.\n */\n @Method()\n async close(shouldReturnFocus = this.isFocusVisible): Promise<void> {\n if (!this._isOpen) {\n return; // busy or closed\n }\n\n this._isOpen = null;\n this.trap?.deactivate();\n this.trap = undefined;\n this.content.classList.remove('show');\n if (shouldReturnFocus) {\n this.trigger?.focus();\n }\n // give CSS transition time to apply\n setTimeout(() => {\n this._isOpen = false;\n this.content.classList.remove('show');\n this.content.style.display = '';\n this.trigger?.setAttribute('aria-expanded', 'false');\n this.cleanupFloatingUi?.();\n this.cleanupFloatingUi = undefined;\n this.catClose.emit();\n }, timeTransitionS);\n }\n\n componentDidLoad() {\n this.initAnchor();\n if (!this.delayedTriggerInit) {\n this.initTrigger();\n }\n }\n\n disconnectedCallback() {\n this.trap?.deactivate();\n this.trap = undefined;\n this.cleanupFloatingUi?.();\n this.cleanupFloatingUi = undefined;\n }\n\n render() {\n return (\n <Host>\n <slot name=\"anchor\" ref={el => (this.anchorSlot = el as HTMLSlotElement)}></slot>\n <slot name=\"trigger\" ref={el => (this.triggerSlot = el as HTMLSlotElement)}></slot>\n <div\n id={this.contentId}\n class={{ content: true, 'overflow-auto': !this.overflow, justified: this.justify, aligned: !this.justify }}\n ref={el => (this.content = el as HTMLElement)}\n >\n <slot name=\"content\"></slot>\n </div>\n </Host>\n );\n }\n\n private handleClickOutside(event: MouseEvent): void {\n if (\n !this.noAutoClose &&\n // check if click was outside of the dropdown content\n !event.composedPath().includes(this.content) &&\n // check if click was not on an element marked with data-dropdown-no-close\n !event.composedPath().find(el => this.hasAttribute(el, 'data-dropdown-no-close'))\n ) {\n this.close();\n }\n }\n\n private get contentId() {\n return `cat-dropdown-${this.id}`;\n }\n\n private initTrigger() {\n this.trigger = this.findTrigger();\n const ariaHaspopup = this.trigger.getAttribute('aria-haspopup');\n this.trigger.setAttribute('aria-haspopup', ariaHaspopup ?? 'true');\n this.trigger.setAttribute('aria-expanded', 'false');\n this.trigger.setAttribute('aria-controls', this.contentId);\n this.trigger.addEventListener('click', (event: Event) => {\n this.isFocusVisible = this.isEventOriginFromKeyboard(event as UIEvent);\n this.toggle();\n });\n }\n\n private isEventOriginFromKeyboard(event: UIEvent): boolean {\n return event.detail === 0;\n }\n\n private initAnchor() {\n this.anchor = (this.anchorSlot?.assignedElements?.() || [])[0];\n }\n\n private findTrigger() {\n let trigger: FocusableElement | undefined;\n let elems = this.triggerSlot?.assignedElements?.() || [];\n while (!trigger && elems.length) {\n const elem = elems.shift();\n trigger = elem?.hasAttribute('data-trigger')\n ? (elem as HTMLElement)\n : (elem?.querySelector('[data-trigger]') ?? undefined);\n }\n if (!trigger) {\n trigger = firstTabbable(this.triggerSlot);\n }\n // if no tabbable element is still found let's attempt to search through elements with visibility:hidden styles\n // which stencil assigns to component in prehydration state\n if (!trigger) {\n elems = this.triggerSlot?.assignedElements?.() || [];\n while (!trigger && elems.length) {\n const elem = elems.shift();\n trigger = findFirstTabbableIncludeHidden(elem as HTMLElement);\n }\n }\n if (!trigger) {\n throw new Error('Cannot find tabbable element. Use [data-trigger] to set the trigger.');\n }\n return trigger;\n }\n\n private update(anchorElement: ReferenceElement | undefined, justify = this.justify) {\n if (anchorElement) {\n const resize = this.noResize\n ? []\n : [\n size({\n padding: CatDropdown.OFFSET,\n apply({ rects, availableWidth, availableHeight, elements }) {\n if (justify) {\n Object.assign(elements.floating.style, {\n minWidth: `${rects.reference.width}px`,\n maxWidth: `${rects.reference.width}px`,\n maxHeight: `${availableHeight}px`\n });\n } else {\n Object.assign(elements.floating.style, {\n maxWidth: `${availableWidth}px`,\n maxHeight: `${availableHeight}px`\n });\n }\n }\n })\n ];\n const middleware = [offset(CatDropdown.OFFSET)];\n const flipMiddleware = flip({\n // Ensure we flip to the perpendicular axis if it doesn't fit\n // on narrow viewports.\n crossAxis: 'alignment',\n fallbackAxisSideDirection: 'end'\n });\n const shiftMiddleware = shift();\n\n // Prioritize flip over shift for edge-aligned placements only.\n if (this.placement.includes('-')) {\n middleware.push(flipMiddleware, shiftMiddleware);\n } else {\n middleware.push(shiftMiddleware, flipMiddleware);\n }\n computePosition(anchorElement, this.content, {\n strategy: 'fixed',\n placement: this.placement,\n middleware: [...middleware, ...resize]\n }).then(({ x, y, placement }) => {\n this.content.dataset.placement = placement;\n Object.assign(this.content.style, {\n left: `${x}px`,\n top: `${y}px`\n });\n });\n }\n }\n\n private hasAttribute(elem: EventTarget, attr: string) {\n return elem instanceof HTMLElement && elem.hasAttribute(attr);\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ :host(.cat-time-menu) nav {
2
+ max-height: 16rem;
3
+ }
4
+
5
+ ul {
6
+ list-style: none;
7
+ margin: 0;
8
+ padding: 0;
9
+ }