@genexus/genexus-ide-ui 0.0.23 → 0.0.25

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 (61) hide show
  1. package/dist/cjs/ch-action-group_2.cjs.entry.js +211 -0
  2. package/dist/cjs/ch-dropdown-item.cjs.entry.js +36 -5
  3. package/dist/cjs/ch-dropdown.cjs.entry.js +50 -52
  4. package/dist/cjs/ch-test-action-group.cjs.entry.js +79 -0
  5. package/dist/cjs/ch-test-dropdown.cjs.entry.js +54 -0
  6. package/dist/cjs/ch-window_2.cjs.entry.js +25 -6
  7. package/dist/cjs/genexus-ide-ui.cjs.js +1 -1
  8. package/dist/cjs/gx-ide-team-dev-commit.cjs.entry.js +13 -13
  9. package/dist/cjs/loader.cjs.js +1 -1
  10. package/dist/collection/collection-manifest.json +4 -0
  11. package/dist/collection/components/team-dev-commit/gx-ide-assets/team-dev-commit/langs/team-dev-commit.lang.en.json +1 -1
  12. package/dist/collection/components/team-dev-commit/team-dev-commit.js +34 -15
  13. package/dist/components/action-group-item.js +54 -0
  14. package/dist/components/action-group.js +214 -0
  15. package/dist/components/ch-action-group-item.js +6 -0
  16. package/dist/components/ch-action-group.js +6 -0
  17. package/dist/components/ch-dropdown-item-separator.js +1 -28
  18. package/dist/components/ch-dropdown-item.js +1 -53
  19. package/dist/components/ch-dropdown.js +1 -284
  20. package/dist/components/ch-test-action-group.js +137 -0
  21. package/dist/components/ch-test-dropdown.js +104 -0
  22. package/dist/components/ch-window2.js +25 -6
  23. package/dist/components/dropdown-item-separator.js +30 -0
  24. package/dist/components/dropdown-item.js +109 -0
  25. package/dist/components/dropdown.js +294 -0
  26. package/dist/components/gx-ide-team-dev-commit.js +14 -13
  27. package/dist/components/index.js +4 -0
  28. package/dist/esm/ch-action-group_2.entry.js +206 -0
  29. package/dist/esm/ch-dropdown-item.entry.js +36 -5
  30. package/dist/esm/ch-dropdown.entry.js +50 -52
  31. package/dist/esm/ch-test-action-group.entry.js +75 -0
  32. package/dist/esm/ch-test-dropdown.entry.js +50 -0
  33. package/dist/esm/ch-window_2.entry.js +25 -6
  34. package/dist/esm/genexus-ide-ui.js +1 -1
  35. package/dist/esm/gx-ide-team-dev-commit.entry.js +13 -13
  36. package/dist/esm/loader.js +1 -1
  37. package/dist/genexus-ide-ui/genexus-ide-ui.esm.js +1 -1
  38. package/dist/genexus-ide-ui/gx-ide-assets/team-dev-commit/langs/team-dev-commit.lang.en.json +1 -1
  39. package/dist/genexus-ide-ui/p-097a3eeb.entry.js +1 -0
  40. package/dist/genexus-ide-ui/p-4bbe1c18.entry.js +1 -0
  41. package/dist/genexus-ide-ui/p-5c64c57f.entry.js +1 -0
  42. package/dist/genexus-ide-ui/p-5ff04ebe.entry.js +1 -0
  43. package/dist/genexus-ide-ui/p-9c82381c.entry.js +1 -0
  44. package/dist/genexus-ide-ui/p-dbebb1a0.entry.js +1 -0
  45. package/dist/genexus-ide-ui/p-f8561da6.entry.js +1 -0
  46. package/dist/node_modules/@genexus/chameleon-controls-library/dist/collection/components/action-group/action-group.css +48 -0
  47. package/dist/node_modules/@genexus/chameleon-controls-library/dist/collection/components/action-group-item/action-group-item.css +4 -0
  48. package/dist/node_modules/@genexus/chameleon-controls-library/dist/collection/components/dropdown/dropdown.css +32 -88
  49. package/dist/node_modules/@genexus/chameleon-controls-library/dist/collection/components/dropdown-item/dropdown-item.css +9 -22
  50. package/dist/node_modules/@genexus/chameleon-controls-library/dist/collection/components/test/test-action-group/test-action-group.css +52 -0
  51. package/dist/node_modules/@genexus/chameleon-controls-library/dist/collection/components/test/test-dropdown/test-dropdown.css +36 -0
  52. package/dist/node_modules/@genexus/chameleon-controls-library/dist/collection/components/window/ch-window.css +3 -1
  53. package/dist/types/common/types.d.ts +1 -0
  54. package/dist/types/components/team-dev-commit/team-dev-commit.d.ts +13 -6
  55. package/dist/types/components/team-dev-update/team-dev-update.d.ts +1 -1
  56. package/dist/types/components.d.ts +9 -1
  57. package/package.json +3 -3
  58. package/dist/genexus-ide-ui/p-04f094d1.entry.js +0 -1
  59. package/dist/genexus-ide-ui/p-192f1342.entry.js +0 -1
  60. package/dist/genexus-ide-ui/p-66072dce.entry.js +0 -1
  61. package/dist/genexus-ide-ui/p-c10d5f34.entry.js +0 -1
@@ -0,0 +1,214 @@
1
+ import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
2
+ import { d as defineCustomElement$3 } from './dropdown.js';
3
+ import { d as defineCustomElement$2 } from './ch-window2.js';
4
+ import { d as defineCustomElement$1 } from './ch-window-close2.js';
5
+
6
+ const actionGroupCss = "*,::after,::before{box-sizing:border-box}:host{display:grid;position:relative;width:100%;grid-template:\"more-actions actions\" 1fr/min-content 1fr;overflow:hidden}.more-actions{grid-area:more-actions}.more-actions::part(expandable-button){width:1.375em;height:1.375em}.more-actions::part(expandable-button)::before{content:\"\";width:100%;height:100%;background-color:currentColor;-webkit-mask:url('data:image/svg+xml,<svg viewBox=\"0 0 25 25\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.26837 10.5625C4.16837 10.5625 3.26837 11.4625 3.26837 12.5625C3.26837 13.6625 4.16837 14.5625 5.26837 14.5625C6.36837 14.5625 7.26837 13.6625 7.26837 12.5625C7.26837 11.4625 6.36837 10.5625 5.26837 10.5625ZM19.2684 10.5625C18.1684 10.5625 17.2684 11.4625 17.2684 12.5625C17.2684 13.6625 18.1684 14.5625 19.2684 14.5625C20.3684 14.5625 21.2684 13.6625 21.2684 12.5625C21.2684 11.4625 20.3684 10.5625 19.2684 10.5625ZM12.2684 10.5625C11.1684 10.5625 10.2684 11.4625 10.2684 12.5625C10.2684 13.6625 11.1684 14.5625 12.2684 14.5625C13.3684 14.5625 14.2684 13.6625 14.2684 12.5625C14.2684 11.4625 13.3684 10.5625 12.2684 10.5625Z\"/></svg>') 50% 50%/1.25em 1.25em no-repeat}.actions{grid-area:actions;display:grid;grid-auto-flow:column;grid-auto-columns:max-content;width:100%;max-width:100%}.actions--responsive{position:absolute;inset:0}.actions--scroll{overflow-x:auto}.actions--multiline{display:flex;flex-wrap:wrap}";
7
+
8
+ const FLOATING_POINT_ERROR = 1;
9
+ const ChActionGroup = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
10
+ constructor() {
11
+ super();
12
+ this.__registerHost();
13
+ this.__attachShadow();
14
+ this.displayedItemsCountChange = createEvent(this, "displayedItemsCountChange", 7);
15
+ this.needForRAF = true; // To prevent redundant RAF (request animation frame) calls
16
+ this.totalItems = -1;
17
+ /**
18
+ * The visible actions when `itemsOverflowBehavior === "ResponsiveCollapse"`.
19
+ */
20
+ this.displayedItems = -1;
21
+ /**
22
+ * This attribute lets you specify the label for the more actions button.
23
+ * Important for accessibility.
24
+ */
25
+ this.buttonLabel = "More actions";
26
+ /**
27
+ * This attribute determines how items behave when the content of the ActionGroup overflows horizontal. This property is needed
28
+ * to make the control responsive to changes in the Width of the container of ActionGroup.
29
+ *
30
+ * | Value | Details |
31
+ * | --------------------- | ------------------------------------------------------------------------------------------------ |
32
+ * | `Add Scroll` | The items of the ActionGroup that overflow horizontally are shown by means of a scroll. |
33
+ * | `Multiline` | The ActionGroup items that overflow horizontally are shown in a second line of the control. |
34
+ * | `Responsive Collapse` | The Action Group items, when they start to overflow the control, are placed in the More Actions. |
35
+ */
36
+ this.itemsOverflowBehavior = "ResponsiveCollapse";
37
+ /**
38
+ * Determine which mouse actions on the expandable button display the dropdown
39
+ * section.
40
+ */
41
+ this.expandBehavior = "ClickOrHover";
42
+ /**
43
+ * @todo Check a better convention for this property, for example, "ActionsInlineAlignment"
44
+ * This attribute determines the position of the More Actions button in the Action Group.
45
+ *
46
+ * | Value | Details |
47
+ * | --------| --------------------------------------------------------------------- |
48
+ * | `Start` | The More Actions Button is displayed to the left of the ActionGroup. |
49
+ * | `End` | The More Actions Button is displayed to the right of the ActionGroup. |
50
+ */
51
+ this.moreActionsButtonPosition = "Start";
52
+ /**
53
+ * Specifies the position of the dropdown section that is placed relative to
54
+ * the more actions button.
55
+ */
56
+ this.moreActionsDropdownPosition = "InsideStart_OutsideEnd";
57
+ /**
58
+ * Determine if the dropdowns should be opened when the action is focused.
59
+ */
60
+ this.openOnFocus = false;
61
+ /**
62
+ * Update the visibility of the actions.
63
+ * Only works if itemsOverflowBehavior === "ResponsiveCollapse"
64
+ */
65
+ this.updateDisplayedActions = () => {
66
+ const actionGroupItems = this.slotItems.assignedElements();
67
+ // The column-gap property must be taken into account
68
+ const columnGap = getComputedStyle(this.actionsContainer).columnGap;
69
+ const columnGapValue = columnGap != null && columnGap.endsWith("px")
70
+ ? Number(columnGap.replace("px", ""))
71
+ : 0;
72
+ // Since the last item does not add column-gap, we have to adjust the measurement
73
+ let availableWidth = this.actionsContainer.clientWidth + columnGapValue - FLOATING_POINT_ERROR;
74
+ let displayedItems = 0;
75
+ // Check which items are visible
76
+ actionGroupItems.forEach(action => {
77
+ const actionWidth = action.clientWidth;
78
+ availableWidth -= actionWidth + columnGapValue;
79
+ if (availableWidth >= 0) {
80
+ action.floating = false;
81
+ displayedItems++;
82
+ }
83
+ else {
84
+ action.floating = true;
85
+ }
86
+ });
87
+ this.totalItems = actionGroupItems.length;
88
+ this.displayedItems = displayedItems;
89
+ this.displayedItemsCountChange.emit(displayedItems);
90
+ };
91
+ this.updateDisplayedActionInFrame = () => {
92
+ if (!this.needForRAF) {
93
+ return;
94
+ }
95
+ this.needForRAF = false; // No need to call RAF up until next frame
96
+ requestAnimationFrame(() => {
97
+ this.needForRAF = true; // RAF now consumes the movement instruction so a new one can come
98
+ this.updateDisplayedActions();
99
+ });
100
+ };
101
+ this.updateActionsWatcher = () => {
102
+ if (this.itemsOverflowBehavior !== "ResponsiveCollapse") {
103
+ return;
104
+ }
105
+ // Avoid memory leaks by disconnecting and re-connecting the observer
106
+ this.disconnectActionsObserver();
107
+ this.connectActionsObserver();
108
+ };
109
+ }
110
+ handleOverflowBehaviorChange(newValue) {
111
+ if (newValue !== "ResponsiveCollapse") {
112
+ const actionGroupItems = this.slotItems.assignedElements();
113
+ // Reset floating
114
+ actionGroupItems.forEach(item => {
115
+ item.floating = false;
116
+ });
117
+ }
118
+ this.setResponsiveCollapse();
119
+ }
120
+ connectActionsObserver() {
121
+ this.actionsWatcher = new ResizeObserver(this.updateDisplayedActionInFrame);
122
+ // Observe the actions
123
+ const actionGroupItems = this.slotItems.assignedElements();
124
+ actionGroupItems.forEach(action => {
125
+ this.actionsWatcher.observe(action);
126
+ });
127
+ }
128
+ connectActionsContainerObserver() {
129
+ this.actionsContainerWatcher = new ResizeObserver(this.updateDisplayedActionInFrame);
130
+ this.actionsContainerWatcher.observe(this.el);
131
+ }
132
+ disconnectActionsObserver() {
133
+ if (this.actionsWatcher) {
134
+ this.actionsWatcher.disconnect();
135
+ this.actionsWatcher = null;
136
+ }
137
+ }
138
+ disconnectActionsContainerObserver() {
139
+ if (this.actionsContainerWatcher) {
140
+ this.actionsContainerWatcher.disconnect();
141
+ this.actionsContainerWatcher = null;
142
+ }
143
+ }
144
+ setResponsiveCollapse() {
145
+ this.disconnectActionsObserver();
146
+ this.disconnectActionsContainerObserver();
147
+ if (this.itemsOverflowBehavior !== "ResponsiveCollapse") {
148
+ return;
149
+ }
150
+ this.connectActionsObserver();
151
+ this.connectActionsContainerObserver();
152
+ }
153
+ componentDidLoad() {
154
+ this.setResponsiveCollapse();
155
+ }
156
+ disconnectedCallback() {
157
+ this.disconnectActionsObserver();
158
+ this.disconnectActionsContainerObserver();
159
+ }
160
+ render() {
161
+ // @todo TODO: Improve accessibility and keyboard navigation
162
+ return (h(Host, { role: "menubar", "aria-label": this.accessibleName }, this.itemsOverflowBehavior === "ResponsiveCollapse" &&
163
+ this.totalItems !== this.displayedItems && (h("ch-dropdown", { exportparts: "expandable-button:more-actions-button,separation:more-actions-separation,list:more-actions-list,section:more-actions-section,mask:more-actions-mask", buttonLabel: this.buttonLabel, class: "more-actions", part: "more-actions", expandBehavior: this.expandBehavior, openOnFocus: this.openOnFocus, position: this.moreActionsDropdownPosition }, h("slot", { name: "more-items", slot: "items" }))), h("div", { class: {
164
+ actions: true,
165
+ "actions--scroll": this.itemsOverflowBehavior === "AddScroll",
166
+ "actions--multiline": this.itemsOverflowBehavior === "Multiline",
167
+ "actions--responsive": this.itemsOverflowBehavior === "ResponsiveCollapse"
168
+ }, part: "actions", ref: el => (this.actionsContainer = el) }, h("slot", { name: "items", onSlotchange: this.updateActionsWatcher, ref: el => (this.slotItems = el) }))));
169
+ }
170
+ get el() { return this; }
171
+ static get watchers() { return {
172
+ "itemsOverflowBehavior": ["handleOverflowBehaviorChange"]
173
+ }; }
174
+ static get style() { return actionGroupCss; }
175
+ }, [1, "ch-action-group", {
176
+ "accessibleName": [1, "accessible-name"],
177
+ "buttonLabel": [1, "button-label"],
178
+ "itemsOverflowBehavior": [1, "items-overflow-behavior"],
179
+ "expandBehavior": [1, "expand-behavior"],
180
+ "moreActionsButtonPosition": [1, "more-actions-button-position"],
181
+ "moreActionsDropdownPosition": [1, "more-actions-dropdown-position"],
182
+ "openOnFocus": [4, "open-on-focus"],
183
+ "displayedItems": [32]
184
+ }]);
185
+ function defineCustomElement() {
186
+ if (typeof customElements === "undefined") {
187
+ return;
188
+ }
189
+ const components = ["ch-action-group", "ch-dropdown", "ch-window", "ch-window-close"];
190
+ components.forEach(tagName => { switch (tagName) {
191
+ case "ch-action-group":
192
+ if (!customElements.get(tagName)) {
193
+ customElements.define(tagName, ChActionGroup);
194
+ }
195
+ break;
196
+ case "ch-dropdown":
197
+ if (!customElements.get(tagName)) {
198
+ defineCustomElement$3();
199
+ }
200
+ break;
201
+ case "ch-window":
202
+ if (!customElements.get(tagName)) {
203
+ defineCustomElement$2();
204
+ }
205
+ break;
206
+ case "ch-window-close":
207
+ if (!customElements.get(tagName)) {
208
+ defineCustomElement$1();
209
+ }
210
+ break;
211
+ } });
212
+ }
213
+
214
+ export { ChActionGroup as C, defineCustomElement as d };
@@ -0,0 +1,6 @@
1
+ import { C as ChActionGroupItem$1, d as defineCustomElement$1 } from './action-group-item.js';
2
+
3
+ const ChActionGroupItem = ChActionGroupItem$1;
4
+ const defineCustomElement = defineCustomElement$1;
5
+
6
+ export { ChActionGroupItem, defineCustomElement };
@@ -0,0 +1,6 @@
1
+ import { C as ChActionGroup$1, d as defineCustomElement$1 } from './action-group.js';
2
+
3
+ const ChActionGroup = ChActionGroup$1;
4
+ const defineCustomElement = defineCustomElement$1;
5
+
6
+ export { ChActionGroup, defineCustomElement };
@@ -1,31 +1,4 @@
1
- import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
2
-
3
- const dropdownItemSeparatorCss = ":host{display:flex;height:1px;background-color:#99999980;margin-block:2px}";
4
-
5
- const ChDropDownItemSeparator = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
6
- constructor() {
7
- super();
8
- this.__registerHost();
9
- this.__attachShadow();
10
- }
11
- render() {
12
- return h(Host, { role: "separator" });
13
- }
14
- static get style() { return dropdownItemSeparatorCss; }
15
- }, [1, "ch-dropdown-item-separator"]);
16
- function defineCustomElement$1() {
17
- if (typeof customElements === "undefined") {
18
- return;
19
- }
20
- const components = ["ch-dropdown-item-separator"];
21
- components.forEach(tagName => { switch (tagName) {
22
- case "ch-dropdown-item-separator":
23
- if (!customElements.get(tagName)) {
24
- customElements.define(tagName, ChDropDownItemSeparator);
25
- }
26
- break;
27
- } });
28
- }
1
+ import { C as ChDropDownItemSeparator, d as defineCustomElement$1 } from './dropdown-item-separator.js';
29
2
 
30
3
  const ChDropdownItemSeparator = ChDropDownItemSeparator;
31
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,56 +1,4 @@
1
- import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
2
-
3
- const dropdownItemCss = ":where(a,button){all:unset}*,::before,::after{box-sizing:border-box}@media (prefers-color-scheme: light){.action:focus,.action:hover{background-color:#ccc}.action:active{background-color:#e9e9e9}}@media (prefers-color-scheme: dark){.action:focus,.action:hover{background-color:#3e3e40}.action:active{background-color:#575965}}:host{display:flex;width:100%;height:100%}.action{display:flex;align-items:center;column-gap:8px;width:100%;height:100%;cursor:pointer;padding-block:8px;padding-inline:16px;font-size:0.875em;text-align:start;transition-property:background-color, border-color, box-shadow, color, filter, opacity;transition-duration:250ms}.left-img,.right-img{display:block;width:24px;height:24px;min-width:24px}.content{width:100%}";
4
-
5
- const ChDropDownItem = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
6
- constructor() {
7
- super();
8
- this.__registerHost();
9
- this.__attachShadow();
10
- this.actionClick = createEvent(this, "actionClick", 7);
11
- this.focusChange = createEvent(this, "focusChange", 7);
12
- this.dropDownItemContent = () => [
13
- !!this.leftImgSrc && (h("img", { "aria-hidden": "true", class: "left-img", part: "dropdown-item__left-img", alt: "", src: this.leftImgSrc, loading: "lazy" })),
14
- h("span", { class: "content", part: "dropdown-item__content" }, h("slot", null)),
15
- !!this.rightImgSrc && (h("img", { "aria-hidden": "true", class: "right-img", part: "dropdown-item__right-img", alt: "", src: this.rightImgSrc, loading: "lazy" }))
16
- ];
17
- this.handleActionClick = () => {
18
- this.actionClick.emit(this.element.id);
19
- };
20
- this.handleFocus = () => {
21
- this.focusChange.emit();
22
- };
23
- }
24
- /**
25
- * Focuses the control's anchor or button.
26
- */
27
- async handleFocusElement() {
28
- this.mainElement.focus();
29
- }
30
- render() {
31
- return (h(Host, { role: "listitem" }, this.href ? (h("a", { class: "action", part: "dropdown-item__target", href: this.href, onClick: this.handleActionClick, onFocus: this.handleFocus, ref: el => (this.mainElement = el) }, this.dropDownItemContent())) : (h("button", { class: "action", part: "dropdown-item__button", type: "button", onClick: this.handleActionClick, onFocus: this.handleFocus, ref: el => (this.mainElement = el) }, this.dropDownItemContent()))));
32
- }
33
- get element() { return this; }
34
- static get style() { return dropdownItemCss; }
35
- }, [1, "ch-dropdown-item", {
36
- "href": [1],
37
- "leftImgSrc": [1, "left-img-src"],
38
- "rightImgSrc": [1, "right-img-src"],
39
- "handleFocusElement": [64]
40
- }]);
41
- function defineCustomElement$1() {
42
- if (typeof customElements === "undefined") {
43
- return;
44
- }
45
- const components = ["ch-dropdown-item"];
46
- components.forEach(tagName => { switch (tagName) {
47
- case "ch-dropdown-item":
48
- if (!customElements.get(tagName)) {
49
- customElements.define(tagName, ChDropDownItem);
50
- }
51
- break;
52
- } });
53
- }
1
+ import { C as ChDropDownItem, d as defineCustomElement$1 } from './dropdown-item.js';
54
2
 
55
3
  const ChDropdownItem = ChDropDownItem;
56
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,287 +1,4 @@
1
- import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
2
-
3
- const dropdownCss = ":where(button){all:unset}*,::before,::after{box-sizing:border-box}@media (prefers-color-scheme: light){.section{background-color:#fbfbfb;color:#000}}@media (prefers-color-scheme: dark){.section{background-color:#242426;color:#e9e9e9}}:host{--ch-dropdown-rtl-initial-X:1;--ch-dropdown-translateX:0;--ch-dropdown-translateY:0;display:flex;position:relative;width:100%;height:100%}.expandable-button{display:flex;position:relative;width:100%;height:100%;cursor:pointer;z-index:108}.expandable-button:focus-within{box-shadow:0px 0px 0 1px currentColor;transition:box-shadow 250ms}.dummy-separation{display:flex;position:absolute;z-index:107}.dummy-separation--vertical{width:100%;height:var(--separation-between-button-size)}.dummy-separation--top{inset-block-start:var(--separation-between-button)}.dummy-separation--bottom{inset-block-end:var(--separation-between-button)}.dummy-separation--horizontal{width:var(--separation-between-button-size);height:100%}.dummy-separation--left{inset-inline-start:var(--separation-between-button)}.dummy-separation--right{inset-inline-end:var(--separation-between-button)}.section{position:absolute;border-radius:5px;box-shadow:0 3px 4px #80808024, 0 3px 3px -2px #8080801f, 0 1px 8px #80808030;width:max-content;max-width:350px;z-index:107}.header+.list,.list+.footer{margin-block-start:8px}.list{display:flex;flex-direction:column;gap:4px}.position--top{inset-block-start:var(--separation-between-button);transform:translate(var(--ch-dropdown-translateX), -100%)}.position--right{inset-inline-end:var(--separation-between-button);transform:translate(calc(100% * var(--ch-dropdown-rtl-initial-X)), var(--ch-dropdown-translateY))}.position--bottom{inset-block-end:var(--separation-between-button);transform:translate(var(--ch-dropdown-translateX), 100%)}.position--left{inset-inline-start:var(--separation-between-button);transform:translate(calc(-100% * var(--ch-dropdown-rtl-initial-X)), var(--ch-dropdown-translateY))}.align--left{inset-inline-start:0}.align--center{inset-inline-start:50%;--ch-dropdown-translateX:calc(-50% * var(--ch-dropdown-rtl-initial-X))}.align--right{inset-inline-end:0}.valign--top{inset-block-start:0}.valign--middle{inset-block-start:50%;--ch-dropdown-translateY:calc(-50% * var(--ch-dropdown-rtl-initial-X))}.valign--bottom{inset-block-end:0}";
4
-
5
- const EXPANDABLE_BUTTON_ID = "expandable-button";
6
- const SECTION_ID = "section";
7
- const DROPDOWN_ITEM_TAG_NAME = "ch-dropdown-item";
8
- const DROPDOWN_ITEM_SELECTOR = `:scope > ${DROPDOWN_ITEM_TAG_NAME}`;
9
- // Keys
10
- const TAB_KEY = "Tab";
11
- const ChDropDown = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
12
- constructor() {
13
- super();
14
- this.__registerHost();
15
- this.__attachShadow();
16
- this.expandedChange = createEvent(this, "expandedChange", 7);
17
- this.keyEventsDictionary = {
18
- ArrowDown: (event) => {
19
- event.preventDefault();
20
- if (!this.currentFocusedItem) {
21
- this.focusFirstDropDownItem();
22
- return;
23
- }
24
- const nextDropDownItem = this.findNextDropDownItemSibling();
25
- if (nextDropDownItem) {
26
- // This is wrong, it should call the focusElement Method. StencilJS bug?
27
- nextDropDownItem.handleFocusElement();
28
- }
29
- },
30
- ArrowUp: (event) => {
31
- event.preventDefault();
32
- if (!this.currentFocusedItem) {
33
- this.focusFirstDropDownItem();
34
- return;
35
- }
36
- const previousDropDownItem = this.findPreviousDropDownItemSibling();
37
- if (previousDropDownItem) {
38
- // This is wrong, it should call the focusElement Method. StencilJS bug?
39
- previousDropDownItem.handleFocusElement();
40
- }
41
- },
42
- Escape: () => {
43
- this.closeDropdown();
44
- this.returnFocusToButton();
45
- }
46
- };
47
- this.showHeader = false;
48
- this.showFooter = false;
49
- this.expanded = false;
50
- this.expandedWithHover = false;
51
- /**
52
- * Specifies the horizontal alignment the dropdown section has when using
53
- * `position === "Top"` or `position === "Bottom"`.
54
- */
55
- this.align = "Center";
56
- /**
57
- * This attribute lets you specify the label for the expandable button.
58
- * Important for accessibility.
59
- */
60
- this.buttonLabel = "Show options";
61
- /**
62
- * Determine which actions on the expandable button display the dropdown
63
- * section.
64
- */
65
- this.expandBehavior = "Click or Hover";
66
- /**
67
- * Determine if the dropdown section should be opened when the expandable
68
- * button of the control is focused.
69
- */
70
- this.openOnFocus = false;
71
- /**
72
- * Specifies the position of the dropdown section that is placed relative to
73
- * the expandable button.
74
- */
75
- this.position = "Bottom";
76
- /**
77
- * Specifies the separation (in pixels) between the expandable button and the
78
- * dropdown section of the control.
79
- */
80
- this.dropdownSeparation = 12;
81
- /**
82
- * Specifies the vertical alignment the dropdown section has when using
83
- * `position === "Right"` or `position === "Left"`.
84
- */
85
- this.valign = "Middle";
86
- this.closeDropdown = () => {
87
- this.closeDropdownWithHover();
88
- this.expanded = false;
89
- this.expandedChange.emit(false);
90
- };
91
- this.closeDropdownWithHover = () => {
92
- this.expandedWithHover = false;
93
- // If the control was not expanded with focus
94
- if (!this.expanded) {
95
- this.expandedChange.emit(false);
96
- }
97
- };
98
- this.closeDropdownWhenClickingOutside = (event) => {
99
- if (event.composedPath().find(el => el === this.element) === undefined) {
100
- this.closeDropdown();
101
- }
102
- };
103
- this.handleKeyDownEvents = (event) => {
104
- const keyEventHandler = this.keyEventsDictionary[event.code];
105
- if (keyEventHandler) {
106
- keyEventHandler(event);
107
- }
108
- };
109
- /**
110
- * Check if the next focused element is a child element of the dropdown
111
- * control.
112
- */
113
- this.handleKeyUpEvents = (event) => {
114
- if (event.code !== TAB_KEY) {
115
- return;
116
- }
117
- const nextFocusedElement = event.target;
118
- const isChildElement = nextFocusedElement.closest("ch-dropdown") === this.element;
119
- if (isChildElement) {
120
- return;
121
- }
122
- this.closeDropdown();
123
- };
124
- this.handleMouseLeave = () => {
125
- const focusedElementIsInsideDropDown = document.activeElement.closest("ch-dropdown") === this.element;
126
- if (focusedElementIsInsideDropDown) {
127
- this.expanded = true;
128
- }
129
- this.closeDropdownWithHover();
130
- };
131
- this.handleMouseEnter = () => {
132
- if (this.expandedWithHover) {
133
- return;
134
- }
135
- this.expandedWithHover = true;
136
- // If not previously expanded, emit the event
137
- if (!this.expanded) {
138
- this.expandedChange.emit(true);
139
- }
140
- };
141
- this.handleButtonClick = () => {
142
- this.expandedChange.emit(!this.expanded);
143
- this.expanded = !this.expanded;
144
- };
145
- this.handleButtonFocus = () => {
146
- if (this.expanded) {
147
- return;
148
- }
149
- this.expanded = true;
150
- // If not previously expanded, emit the event
151
- if (!this.expandedWithHover) {
152
- this.expandedChange.emit(true);
153
- }
154
- };
155
- }
156
- handleExpandedChange(newExpandedValue) {
157
- if (newExpandedValue) {
158
- this.currentFocusedItem = undefined;
159
- // Click
160
- document.body.addEventListener("click", this.closeDropdownWhenClickingOutside, {
161
- capture: true
162
- });
163
- // Keyboard events
164
- document.body.addEventListener("keydown", this.handleKeyDownEvents, {
165
- capture: true
166
- });
167
- document.body.addEventListener("keyup", this.handleKeyUpEvents, {
168
- capture: true
169
- });
170
- }
171
- else {
172
- // Click
173
- document.body.removeEventListener("click", this.closeDropdownWhenClickingOutside, {
174
- capture: true
175
- });
176
- // Keyboard events
177
- document.body.removeEventListener("keydown", this.handleKeyDownEvents, {
178
- capture: true
179
- });
180
- document.body.removeEventListener("keyup", this.handleKeyUpEvents, {
181
- capture: true
182
- });
183
- }
184
- }
185
- handleActionClick() {
186
- this.closeDropdown();
187
- // @todo This behavior must be specified by a property
188
- // this.returnFocusToButton();
189
- }
190
- handleDropDownItemFocusChange(event) {
191
- this.currentFocusedItem = event.target;
192
- }
193
- focusFirstDropDownItem() {
194
- this.currentFocusedItem = this.element.querySelector(DROPDOWN_ITEM_SELECTOR);
195
- if (this.currentFocusedItem) {
196
- this.currentFocusedItem.handleFocusElement();
197
- }
198
- }
199
- findNextDropDownItemSibling() {
200
- let nextSibling = this.currentFocusedItem
201
- .nextElementSibling;
202
- while (nextSibling &&
203
- nextSibling.tagName.toLowerCase() !== DROPDOWN_ITEM_TAG_NAME) {
204
- nextSibling = nextSibling.nextElementSibling;
205
- }
206
- return nextSibling;
207
- }
208
- findPreviousDropDownItemSibling() {
209
- let previousSibling = this.currentFocusedItem
210
- .previousElementSibling;
211
- while (previousSibling &&
212
- previousSibling.tagName.toLowerCase() !== DROPDOWN_ITEM_TAG_NAME) {
213
- previousSibling =
214
- previousSibling.previousElementSibling;
215
- }
216
- return previousSibling;
217
- }
218
- /**
219
- * Returns focus to the expandable button when closing the dropdown. Only
220
- * works if `openOnFocus = "false"`
221
- */
222
- returnFocusToButton() {
223
- if (!this.openOnFocus) {
224
- this.expandableButton.focus();
225
- }
226
- }
227
- componentWillLoad() {
228
- this.showHeader = !!this.element.querySelector(':scope > [slot="header"]');
229
- this.showFooter = !!this.element.querySelector(':scope > [slot="footer"]');
230
- }
231
- render() {
232
- const hasVerticalPosition = this.position === "Bottom" || this.position === "Top";
233
- const isExpanded = this.expanded || this.expandedWithHover;
234
- return (h(Host, { onMouseLeave: this.expandBehavior === "Click or Hover"
235
- ? this.handleMouseLeave
236
- : undefined, style: {
237
- "--separation-between-button": `-${this.dropdownSeparation}px`,
238
- "--separation-between-button-size": `${this.dropdownSeparation}px`
239
- } }, h("button", { id: EXPANDABLE_BUTTON_ID, "aria-controls": SECTION_ID, "aria-expanded": this.expanded.toString(), "aria-haspopup": "true", "aria-label": this.buttonLabel, class: "expandable-button", part: "dropdown__expandable-button", type: "button", onClick: this.handleButtonClick, onFocus: this.openOnFocus ? this.handleButtonFocus : undefined, onMouseEnter: this.expandBehavior === "Click or Hover"
240
- ? this.handleMouseEnter
241
- : undefined, ref: el => (this.expandableButton = el) }, h("slot", { name: "action" })), this.expandBehavior === "Click or Hover" && this.expandedWithHover && (
242
- // Necessary since the separation between the button and the section
243
- // triggers the onMouseLeave event
244
- h("div", { "aria-hidden": "true", class: {
245
- "dummy-separation": true,
246
- [`dummy-separation--${this.position.toLowerCase()}`]: true,
247
- "dummy-separation--vertical": hasVerticalPosition,
248
- "dummy-separation--horizontal": !hasVerticalPosition
249
- }, part: "dropdown__separation" })), h("section", { id: SECTION_ID, "aria-labelledby": EXPANDABLE_BUTTON_ID, class: {
250
- section: true,
251
- [`position--${this.position.toLowerCase()}`]: true,
252
- [`align--${this.align.toLowerCase()}`]: hasVerticalPosition,
253
- [`valign--${this.valign.toLowerCase()}`]: !hasVerticalPosition
254
- }, part: "dropdown__section", hidden: !isExpanded }, this.showHeader && (h("header", { class: "header", part: "dropdown__header" }, h("slot", { name: "header" }))), h("div", { role: "list", class: "list", part: "dropdown__list" }, h("slot", { name: "items" })), this.showFooter && (h("footer", { class: "footer", part: "dropdown__footer" }, h("slot", { name: "footer" }))))));
255
- }
256
- get element() { return this; }
257
- static get watchers() { return {
258
- "expanded": ["handleExpandedChange"]
259
- }; }
260
- static get style() { return dropdownCss; }
261
- }, [1, "ch-dropdown", {
262
- "align": [1],
263
- "buttonLabel": [1, "button-label"],
264
- "expandBehavior": [1, "expand-behavior"],
265
- "openOnFocus": [4, "open-on-focus"],
266
- "position": [1],
267
- "dropdownSeparation": [2, "dropdown-separation"],
268
- "valign": [1],
269
- "expanded": [32],
270
- "expandedWithHover": [32]
271
- }, [[0, "actionClick", "handleActionClick"], [0, "focusChange", "handleDropDownItemFocusChange"]]]);
272
- function defineCustomElement$1() {
273
- if (typeof customElements === "undefined") {
274
- return;
275
- }
276
- const components = ["ch-dropdown"];
277
- components.forEach(tagName => { switch (tagName) {
278
- case "ch-dropdown":
279
- if (!customElements.get(tagName)) {
280
- customElements.define(tagName, ChDropDown);
281
- }
282
- break;
283
- } });
284
- }
1
+ import { C as ChDropDown, d as defineCustomElement$1 } from './dropdown.js';
285
2
 
286
3
  const ChDropdown = ChDropDown;
287
4
  const defineCustomElement = defineCustomElement$1;