@geotab/zenith 3.6.3 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/README.md +15 -0
  2. package/dist/absolute/absolute.d.ts +3 -1
  3. package/dist/absolute/absolute.js +4 -4
  4. package/dist/checkbox/checkbox.d.ts +3 -1
  5. package/dist/checkbox/checkbox.js +5 -8
  6. package/dist/checkboxListWithAction/checkboxListWithAction.d.ts +3 -1
  7. package/dist/checkboxListWithAction/checkboxListWithAction.js +185 -3
  8. package/dist/controlledPopup/controlledPopup.d.ts +3 -1
  9. package/dist/controlledPopup/controlledPopup.js +2 -2
  10. package/dist/dropdown/dropdownPopup.d.ts +1 -1
  11. package/dist/dropdown/dropdownTrigger.d.ts +1 -1
  12. package/dist/dropdownRaw/dropdownList.d.ts +2 -1
  13. package/dist/dropdownRaw/dropdownList.js +15 -4
  14. package/dist/dropdownRaw/dropdownPopup.d.ts +3 -1
  15. package/dist/dropdownRaw/dropdownPopup.js +35 -5
  16. package/dist/dropdownRaw/dropdownRaw.js +82 -7
  17. package/dist/dropdownRaw/dropdownSearchableTrigger.d.ts +2 -1
  18. package/dist/dropdownRaw/dropdownSearchableTrigger.js +7 -2
  19. package/dist/dropdownRaw/dropdownTrigger.d.ts +2 -1
  20. package/dist/dropdownRaw/dropdownTrigger.js +3 -5
  21. package/dist/footerButtons/footerButtons.d.ts +6 -4
  22. package/dist/footerButtons/footerButtons.js +3 -8
  23. package/dist/groupsFilterRaw/groupsFilterCurrentlySelectedState.js +8 -2
  24. package/dist/groupsFilterRaw/groupsFilterInitialState.js +16 -0
  25. package/dist/groupsFilterRaw/groupsFilterRaw.js +43 -9
  26. package/dist/groupsFilterRaw/groupsFilterTrigger.d.ts +2 -1
  27. package/dist/groupsFilterRaw/groupsFilterTrigger.js +13 -2
  28. package/dist/index.css +222 -18
  29. package/dist/index.d.ts +1 -1
  30. package/dist/list/hooks/useDragAndDrop.d.ts +3 -1
  31. package/dist/list/hooks/useDragAndDrop.js +11 -4
  32. package/dist/menu/components/menuItem.js +12 -2
  33. package/dist/menu/contexts/pathContext.d.ts +3 -1
  34. package/dist/menu/contexts/pathProvider.d.ts +1 -1
  35. package/dist/menu/contexts/pathProvider.js +1 -1
  36. package/dist/menu/controlledMenu.js +97 -29
  37. package/dist/nav/nav.d.ts +2 -1
  38. package/dist/nav/nav.js +3 -2
  39. package/dist/nav/navEditList/navEditList.js +2 -1
  40. package/dist/nav/navItem/navItem.d.ts +1 -0
  41. package/dist/nav/navItem/navItem.js +4 -1
  42. package/dist/pillExpandable/pillContent.d.ts +2 -1
  43. package/dist/pillExpandable/pillContent.js +8 -3
  44. package/dist/pillExpandable/pillExpandable.d.ts +27 -4
  45. package/dist/pillExpandable/pillExpandable.js +426 -196
  46. package/dist/pillExpandable/pillExpandablePopoverContent.d.ts +19 -0
  47. package/dist/pillExpandable/pillExpandablePopoverContent.js +7 -0
  48. package/dist/pillExpandable/pillExpandableSimple.d.ts +5 -3
  49. package/dist/pillExpandable/pillExpandableSimple.js +12 -5
  50. package/dist/summary/summary.js +29 -1
  51. package/dist/summaryTile/summaryTile.d.ts +2 -1
  52. package/dist/summaryTile/summaryTile.js +175 -65
  53. package/dist/summaryTile/summaryTileTrigger.d.ts +1 -1
  54. package/dist/summaryTile/summaryTileTrigger.js +1 -1
  55. package/dist/toggleButtonRaw/toggleButtonRaw.js +2 -1
  56. package/dist/utils/localization/getSupportedLanguage.d.ts +2 -2
  57. package/dist/utils/localization/getSupportedLanguage.js +28 -8
  58. package/dist/utils/localization/languageContext.d.ts +1 -1
  59. package/dist/utils/localization/translations/cs.json +2 -1
  60. package/dist/utils/localization/translations/de.json +2 -1
  61. package/dist/utils/localization/translations/en.json +2 -1
  62. package/dist/utils/localization/translations/es.json +2 -1
  63. package/dist/utils/localization/translations/fr-FR.json +2 -1
  64. package/dist/utils/localization/translations/fr.json +2 -1
  65. package/dist/utils/localization/translations/id.json +2 -1
  66. package/dist/utils/localization/translations/it.json +2 -1
  67. package/dist/utils/localization/translations/ja.json +2 -1
  68. package/dist/utils/localization/translations/ms.json +2 -1
  69. package/dist/utils/localization/translations/nl.json +2 -1
  70. package/dist/utils/localization/translations/pl.json +2 -1
  71. package/dist/utils/localization/translations/pt-BR.json +2 -1
  72. package/dist/utils/localization/translations/sv.json +2 -1
  73. package/dist/utils/localization/translations/th.json +2 -1
  74. package/dist/utils/localization/translations/tr.json +2 -1
  75. package/dist/utils/localization/translations/zh-Hans.json +2 -1
  76. package/esm/absolute/absolute.d.ts +3 -1
  77. package/esm/absolute/absolute.js +4 -4
  78. package/esm/checkbox/checkbox.d.ts +3 -1
  79. package/esm/checkbox/checkbox.js +5 -8
  80. package/esm/checkboxListWithAction/checkboxListWithAction.d.ts +3 -1
  81. package/esm/checkboxListWithAction/checkboxListWithAction.js +186 -4
  82. package/esm/controlledPopup/controlledPopup.d.ts +3 -1
  83. package/esm/controlledPopup/controlledPopup.js +2 -2
  84. package/esm/dropdown/dropdownPopup.d.ts +1 -1
  85. package/esm/dropdown/dropdownTrigger.d.ts +1 -1
  86. package/esm/dropdownRaw/dropdownList.d.ts +2 -1
  87. package/esm/dropdownRaw/dropdownList.js +16 -5
  88. package/esm/dropdownRaw/dropdownPopup.d.ts +3 -1
  89. package/esm/dropdownRaw/dropdownPopup.js +37 -7
  90. package/esm/dropdownRaw/dropdownRaw.js +82 -7
  91. package/esm/dropdownRaw/dropdownSearchableTrigger.d.ts +2 -1
  92. package/esm/dropdownRaw/dropdownSearchableTrigger.js +7 -2
  93. package/esm/dropdownRaw/dropdownTrigger.d.ts +2 -1
  94. package/esm/dropdownRaw/dropdownTrigger.js +3 -5
  95. package/esm/footerButtons/footerButtons.d.ts +6 -4
  96. package/esm/footerButtons/footerButtons.js +3 -8
  97. package/esm/groupsFilterRaw/groupsFilterCurrentlySelectedState.js +9 -3
  98. package/esm/groupsFilterRaw/groupsFilterInitialState.js +16 -0
  99. package/esm/groupsFilterRaw/groupsFilterRaw.js +43 -9
  100. package/esm/groupsFilterRaw/groupsFilterTrigger.d.ts +2 -1
  101. package/esm/groupsFilterRaw/groupsFilterTrigger.js +13 -2
  102. package/esm/index.d.ts +1 -1
  103. package/esm/list/hooks/useDragAndDrop.d.ts +3 -1
  104. package/esm/list/hooks/useDragAndDrop.js +11 -4
  105. package/esm/menu/components/menuItem.js +12 -2
  106. package/esm/menu/contexts/pathContext.d.ts +3 -1
  107. package/esm/menu/contexts/pathProvider.d.ts +1 -1
  108. package/esm/menu/contexts/pathProvider.js +1 -1
  109. package/esm/menu/controlledMenu.js +98 -30
  110. package/esm/nav/nav.d.ts +2 -1
  111. package/esm/nav/nav.js +3 -2
  112. package/esm/nav/navEditList/navEditList.js +2 -1
  113. package/esm/nav/navItem/navItem.d.ts +1 -0
  114. package/esm/nav/navItem/navItem.js +5 -2
  115. package/esm/pillExpandable/pillContent.d.ts +2 -1
  116. package/esm/pillExpandable/pillContent.js +8 -3
  117. package/esm/pillExpandable/pillExpandable.d.ts +27 -4
  118. package/esm/pillExpandable/pillExpandable.js +427 -197
  119. package/esm/pillExpandable/pillExpandablePopoverContent.d.ts +19 -0
  120. package/esm/pillExpandable/pillExpandablePopoverContent.js +3 -0
  121. package/esm/pillExpandable/pillExpandableSimple.d.ts +5 -3
  122. package/esm/pillExpandable/pillExpandableSimple.js +12 -5
  123. package/esm/summary/summary.js +29 -1
  124. package/esm/summaryTile/summaryTile.d.ts +2 -1
  125. package/esm/summaryTile/summaryTile.js +140 -43
  126. package/esm/summaryTile/summaryTileTrigger.d.ts +1 -1
  127. package/esm/summaryTile/summaryTileTrigger.js +1 -1
  128. package/esm/toggleButtonRaw/toggleButtonRaw.js +2 -1
  129. package/esm/utils/localization/getSupportedLanguage.d.ts +2 -2
  130. package/esm/utils/localization/getSupportedLanguage.js +28 -8
  131. package/esm/utils/localization/languageContext.d.ts +1 -1
  132. package/esm/utils/localization/translations/cs.json +2 -1
  133. package/esm/utils/localization/translations/de.json +2 -1
  134. package/esm/utils/localization/translations/en.json +2 -1
  135. package/esm/utils/localization/translations/es.json +2 -1
  136. package/esm/utils/localization/translations/fr-FR.json +2 -1
  137. package/esm/utils/localization/translations/fr.json +2 -1
  138. package/esm/utils/localization/translations/id.json +2 -1
  139. package/esm/utils/localization/translations/it.json +2 -1
  140. package/esm/utils/localization/translations/ja.json +2 -1
  141. package/esm/utils/localization/translations/ms.json +2 -1
  142. package/esm/utils/localization/translations/nl.json +2 -1
  143. package/esm/utils/localization/translations/pl.json +2 -1
  144. package/esm/utils/localization/translations/pt-BR.json +2 -1
  145. package/esm/utils/localization/translations/sv.json +2 -1
  146. package/esm/utils/localization/translations/th.json +2 -1
  147. package/esm/utils/localization/translations/tr.json +2 -1
  148. package/esm/utils/localization/translations/zh-Hans.json +2 -1
  149. package/package.json +4 -7
@@ -8,32 +8,6 @@ Object.defineProperty(exports, "__esModule", {
8
8
  });
9
9
  exports.TRANSLATIONS = exports.PillExpandable = void 0;
10
10
  const jsx_runtime_1 = require("react/jsx-runtime");
11
- injectString("cs", "Expand", "Rozbalit");
12
- injectString("da-DK", "Expand", "Udvid");
13
- injectString("de", "Expand", "Erweitern");
14
- injectString("en", "Expand", "Expand");
15
- injectString("es", "Expand", "Expandir");
16
- injectString("fi-FI", "Expand", "Laajenna");
17
- injectString("fr", "Expand", "D\xE9velopper");
18
- injectString("fr-FR", "Expand", "D\xE9velopper");
19
- injectString("hu-HU", "Expand", "B\u0151v\xEDtsd ki");
20
- injectString("id", "Expand", "Perluas");
21
- injectString("it", "Expand", "Espandere");
22
- injectString("ja", "Expand", "\u5C55\u958B");
23
- injectString("ko-KR", "Expand", "\uD655\uC7A5");
24
- injectString("ms", "Expand", "Kembangkan");
25
- injectString("nb-NO", "Expand", "Utvide");
26
- injectString("nl", "Expand", "Uitvouwen");
27
- injectString("pl", "Expand", "Rozwi\u0144");
28
- injectString("pt-BR", "Expand", "Expandir");
29
- injectString("pt-PT", "Expand", "Expandir");
30
- injectString("sk-SK", "Expand", "Roz\u0161\xEDr.");
31
- injectString("sv", "Expand", "Expandera");
32
- injectString("th", "Expand", "\u0E02\u0E22\u0E32\u0E22");
33
- injectString("tr", "Expand", "Geni\u015Flet");
34
- injectString("zh-Hans", "Expand", "\u5C55\u5F00");
35
- injectString("zh-TW", "Expand", "\u5C55\u958B");
36
- injectString("ro-RO", "Expand", "Extinde\u021Bi");
37
11
  injectString("cs", "View all", "Zobrazit v\u0161e");
38
12
  injectString("da-DK", "View all", "Se alle");
39
13
  injectString("de", "View all", "Alle anzeigen");
@@ -60,18 +34,51 @@ injectString("tr", "View all", "T\xFCm\xFCn\xFC g\xF6r\xFCnt\xFCle");
60
34
  injectString("zh-Hans", "View all", "\u67E5\u770B\u5168\u90E8");
61
35
  injectString("zh-TW", "View all", "\u6AA2\u8996\u5168\u90E8");
62
36
  injectString("ro-RO", "View all", "Afi\u0219a\u021Bi tot");
37
+ injectString("cs", "Expand", "Rozbalit");
38
+ injectString("da-DK", "Expand", "Udvid");
39
+ injectString("de", "Expand", "Erweitern");
40
+ injectString("en", "Expand", "Expand");
41
+ injectString("es", "Expand", "Expandir");
42
+ injectString("fi-FI", "Expand", "Laajenna");
43
+ injectString("fr", "Expand", "D\xE9velopper");
44
+ injectString("fr-FR", "Expand", "D\xE9velopper");
45
+ injectString("hu-HU", "Expand", "B\u0151v\xEDtsd ki");
46
+ injectString("id", "Expand", "Perluas");
47
+ injectString("it", "Expand", "Espandere");
48
+ injectString("ja", "Expand", "\u5C55\u958B");
49
+ injectString("ko-KR", "Expand", "\uD655\uC7A5");
50
+ injectString("ms", "Expand", "Kembangkan");
51
+ injectString("nb-NO", "Expand", "Utvide");
52
+ injectString("nl", "Expand", "Uitvouwen");
53
+ injectString("pl", "Expand", "Rozwi\u0144");
54
+ injectString("pt-BR", "Expand", "Expandir");
55
+ injectString("pt-PT", "Expand", "Expandir");
56
+ injectString("sk-SK", "Expand", "Roz\u0161\xEDr.");
57
+ injectString("sv", "Expand", "Expandera");
58
+ injectString("th", "Expand", "\u0E02\u0E22\u0E32\u0E22");
59
+ injectString("tr", "Expand", "Geni\u015Flet");
60
+ injectString("zh-Hans", "Expand", "\u5C55\u5F00");
61
+ injectString("zh-TW", "Expand", "\u5C55\u958B");
62
+ injectString("ro-RO", "Expand", "Extinde\u021Bi");
63
63
  const react_1 = require("react");
64
64
  const absolute_1 = require("../absolute/absolute");
65
+ const focusableSelector_1 = require("../utils/focusableSelector");
65
66
  const button_1 = require("../button/button");
67
+ const divider_1 = require("../divider/divider");
66
68
  const pillContent_1 = require("./pillContent");
67
69
  const pillExpandableSimple_1 = require("./pillExpandableSimple");
70
+ const pillExpandablePopoverContent_1 = require("./pillExpandablePopoverContent");
68
71
  const pillExpandableAlignments_1 = require("./pillExpandableAlignments");
69
72
  const useLanguage_1 = require("../utils/localization/useLanguage");
70
73
  const classNames_1 = require("../commonHelpers/classNames/classNames");
71
74
  const getProps_1 = require("./getProps");
75
+ const iconUnlocked_1 = require("../icons/iconUnlocked");
72
76
  const skeleton_1 = require("../skeleton/skeleton");
73
77
  const reactHelpers_1 = require("../commonHelpers/reactHelpers/reactHelpers");
74
- const divider_1 = require("../divider/divider");
78
+ const mobileSheet_1 = require("../mobileSheet/mobileSheet");
79
+ const useDrive_1 = require("../utils/theme/useDrive");
80
+ const deviceType_1 = require("../commonHelpers/hooks/deviceType");
81
+ const useDeviceType_1 = require("../commonHelpers/hooks/useDeviceType");
75
82
  const MAX_PILLS_TO_DISPLAY_IN_POPUP = 2;
76
83
  const PillContext = (0, react_1.createContext)({
77
84
  level: 0,
@@ -80,13 +87,197 @@ const PillContext = (0, react_1.createContext)({
80
87
  expandedChildPillIds: new Set(),
81
88
  autoExpand: false
82
89
  });
83
- const paddingX = 26;
84
- const paddingY = 52;
90
+ const PillExpandablePopover = ({
91
+ useMobileSheet,
92
+ isOpen,
93
+ popupId,
94
+ popupClassName,
95
+ text,
96
+ triggerRef,
97
+ onClose,
98
+ onToggle,
99
+ onChange,
100
+ isPopupContentReady,
101
+ setContainerNode,
102
+ popoverSize,
103
+ popoverContentProps,
104
+ showFooter,
105
+ moreCounter,
106
+ buttonMoreProps,
107
+ title
108
+ }) => {
109
+ const {
110
+ translate
111
+ } = (0, useLanguage_1.useLanguage)();
112
+ const popoverRef = (0, react_1.useRef)(null);
113
+ const handlePopoverRef = (0, react_1.useCallback)(node => {
114
+ popoverRef.current = node;
115
+ setContainerNode(node);
116
+ }, [setContainerNode]);
117
+ // Focus first focusable element in desktop popover when content is ready.
118
+ // Mobile MobileSheet handles its own first-focus (close button).
119
+ (0, react_1.useEffect)(() => {
120
+ if (!useMobileSheet && isPopupContentReady && popoverRef.current) {
121
+ const firstFocusable = popoverRef.current.querySelector(focusableSelector_1.FOCUSABLE_SELECTOR);
122
+ firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();
123
+ }
124
+ }, [useMobileSheet, isPopupContentReady]);
125
+ const titleItem = title && (0, jsx_runtime_1.jsx)("div", {
126
+ className: "zen-status-pill-popup__title-item",
127
+ children: (0, jsx_runtime_1.jsx)("span", {
128
+ className: "zen-status-pill-popup__title-item-text",
129
+ children: title
130
+ })
131
+ });
132
+ const footer = showFooter && (0, jsx_runtime_1.jsxs)("div", {
133
+ className: "zen-status-pill-popup__footer",
134
+ children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, {
135
+ className: "zen-status-pill-popup__divider"
136
+ }), (0, jsx_runtime_1.jsxs)(button_1.Button, Object.assign({}, buttonMoreProps, {
137
+ type: "tertiary",
138
+ className: "zen-status-pill-popup__view-more-button",
139
+ children: [(0, jsx_runtime_1.jsx)("span", {
140
+ children: translate("View all")
141
+ }), (0, jsx_runtime_1.jsx)("span", {
142
+ className: "zen-status-pill-popup__view-more-badge",
143
+ children: moreCounter
144
+ })]
145
+ }))]
146
+ });
147
+ if (useMobileSheet) {
148
+ return (0, jsx_runtime_1.jsxs)(mobileSheet_1.MobileSheet, {
149
+ className: (0, classNames_1.classNames)(["zen-status-pill-popup--mobile", popupClassName || ""]),
150
+ label: text,
151
+ triggerRef: triggerRef,
152
+ isOpen: isOpen,
153
+ onHidePanel: onClose,
154
+ onCloseClick: onClose,
155
+ id: popupId,
156
+ children: [(0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Title, {
157
+ className: "zen-status-pill-popup__mobile-title",
158
+ children: title || text
159
+ }), (0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Content, {
160
+ children: (0, jsx_runtime_1.jsxs)("div", {
161
+ className: "zen-status-pill-popup__mobile-content",
162
+ children: [(0, jsx_runtime_1.jsx)(pillExpandablePopoverContent_1.PillExpandablePopoverContent, Object.assign({}, popoverContentProps, {
163
+ onActionClick: onClose
164
+ })), footer]
165
+ })
166
+ })]
167
+ });
168
+ }
169
+ return (0, jsx_runtime_1.jsx)(absolute_1.Absolute, {
170
+ recalculateTrigger: isPopupContentReady,
171
+ recalculateOnScroll: true,
172
+ useTrapFocusWithTrigger: "on",
173
+ className: popupClassName,
174
+ id: popupId,
175
+ onOpenChange: onChange,
176
+ isOpen: isOpen,
177
+ triggerRef: triggerRef,
178
+ alignmentsFn: pillExpandableAlignments_1.alignments,
179
+ children: (0, jsx_runtime_1.jsxs)("div", {
180
+ ref: handlePopoverRef,
181
+ className: "zen-status-pill-popup",
182
+ tabIndex: -1,
183
+ children: [titleItem, (0, jsx_runtime_1.jsx)("div", {
184
+ className: (0, classNames_1.classNames)(["zen-status-pill-popup__container", `zen-status-pill-popup__container--${popoverSize}`]),
185
+ children: (0, jsx_runtime_1.jsx)(pillExpandablePopoverContent_1.PillExpandablePopoverContent, Object.assign({}, popoverContentProps, {
186
+ onActionClick: onToggle
187
+ }))
188
+ }), footer]
189
+ })
190
+ });
191
+ };
192
+ const PillExpandableChild = ({
193
+ icon,
194
+ text,
195
+ type,
196
+ errorHandler,
197
+ content,
198
+ autoExpandChildren
199
+ }) => {
200
+ const pillId = (0, react_1.useId)();
201
+ const descriptionId = (0, react_1.useId)();
202
+ const {
203
+ translate
204
+ } = (0, useLanguage_1.useLanguage)();
205
+ const {
206
+ level,
207
+ expandedChildPillIds,
208
+ onChildPillExpand,
209
+ onChildPillCollapse,
210
+ autoExpand
211
+ } = (0, react_1.useContext)(PillContext);
212
+ const [currentExpandedPills, setCurrentExpandedPills] = (0, react_1.useState)(new Set());
213
+ const isExpanded = expandedChildPillIds.has(pillId);
214
+ (0, react_1.useEffect)(() => {
215
+ if (autoExpand) {
216
+ onChildPillExpand(pillId);
217
+ }
218
+ }, [autoExpand, onChildPillExpand, pillId]);
219
+ const handleChildToggle = (0, react_1.useCallback)(e => {
220
+ e === null || e === void 0 ? void 0 : e.stopPropagation();
221
+ if (isExpanded) {
222
+ onChildPillCollapse(pillId);
223
+ } else {
224
+ if (!autoExpand) {
225
+ expandedChildPillIds.forEach(pill => onChildPillCollapse(pill));
226
+ }
227
+ onChildPillExpand(pillId);
228
+ }
229
+ }, [isExpanded, expandedChildPillIds, pillId, autoExpand, onChildPillCollapse, onChildPillExpand]);
230
+ const addExpandedChild = (0, react_1.useCallback)(id => {
231
+ setCurrentExpandedPills(prev => {
232
+ const next = new Set(prev);
233
+ next.add(id);
234
+ return next;
235
+ });
236
+ }, []);
237
+ const removeExpandedChild = (0, react_1.useCallback)(id => {
238
+ setCurrentExpandedPills(prev => {
239
+ const next = new Set(prev);
240
+ next.delete(id);
241
+ return next;
242
+ });
243
+ }, []);
244
+ return (0, jsx_runtime_1.jsxs)(PillContext.Provider, {
245
+ value: {
246
+ level: level + 1,
247
+ onChildPillExpand: addExpandedChild,
248
+ onChildPillCollapse: removeExpandedChild,
249
+ expandedChildPillIds: currentExpandedPills,
250
+ autoExpand: autoExpandChildren || false
251
+ },
252
+ children: [(0, jsx_runtime_1.jsx)(pillExpandableSimple_1.PillExpandableSimple, {
253
+ icon: icon,
254
+ text: text,
255
+ expanded: isExpanded,
256
+ onExpand: handleChildToggle,
257
+ expandAriaText: translate("Expand"),
258
+ type: type,
259
+ errorHandler: errorHandler,
260
+ descriptionId: descriptionId
261
+ }), (0, jsx_runtime_1.jsx)(pillContent_1.PillContent, {
262
+ onActionClick: handleChildToggle,
263
+ descriptionText: content.description,
264
+ date: content.date,
265
+ count: content.count,
266
+ mainAction: content.mainAction,
267
+ secondaryAction: content.secondaryAction,
268
+ tertiaryAction: content.tertiaryAction,
269
+ isVisible: isExpanded,
270
+ errorHandler: errorHandler,
271
+ descriptionId: descriptionId
272
+ })]
273
+ });
274
+ };
85
275
  const getDefaultContent = ({
86
276
  description,
87
277
  date,
88
278
  count,
89
279
  secondaryAction,
280
+ tertiaryAction,
90
281
  mainAction,
91
282
  getData
92
283
  }) => {
@@ -110,6 +301,12 @@ const getDefaultContent = ({
110
301
  text: ""
111
302
  }
112
303
  },
304
+ tertiaryAction: {
305
+ isLoading: true,
306
+ data: {
307
+ text: ""
308
+ }
309
+ },
113
310
  mainAction: {
114
311
  isLoading: true,
115
312
  data: {
@@ -124,6 +321,7 @@ const getDefaultContent = ({
124
321
  date,
125
322
  count,
126
323
  secondaryAction,
324
+ tertiaryAction,
127
325
  mainAction,
128
326
  getData: undefined
129
327
  };
@@ -139,47 +337,56 @@ const getValue = (parameter, setContent, paramName, errorHandler) => {
139
337
  });
140
338
  }
141
339
  };
142
- const PillExpandableBase = ({
143
- children,
144
- errorHandler,
145
- getData,
146
- text,
340
+ const usePillContentState = ({
147
341
  description,
148
342
  date,
149
343
  count,
150
344
  mainAction,
151
345
  secondaryAction,
152
- viewMoreAction,
153
- uniquePills,
154
- type,
155
- className,
156
- popupClassName,
157
- isLoading,
158
- isFlat,
159
- icon,
160
- secondaryIcon,
161
- isBeta,
162
- loadingWidth = 200,
163
- hideCounterNumber,
164
- autoExpandChildren
346
+ tertiaryAction,
347
+ getData,
348
+ isPopupOpen,
349
+ errorHandler
165
350
  }) => {
166
- const popupId = (0, react_1.useId)();
167
- const pillId = (0, react_1.useId)();
168
- const descriptionId = (0, react_1.useId)();
169
- const {
170
- translate
171
- } = (0, useLanguage_1.useLanguage)();
172
351
  const [content, setContent] = (0, react_1.useState)(getDefaultContent({
173
352
  description,
174
353
  date,
175
354
  count,
176
355
  secondaryAction,
356
+ tertiaryAction,
177
357
  mainAction,
178
358
  getData
179
359
  }));
180
- const [isPopupOpen, setIsPopupOpen] = (0, react_1.useState)(false);
360
+ (0, react_1.useEffect)(() => {
361
+ if (!isPopupOpen || !(0, reactHelpers_1.isFunction)(getData)) {
362
+ return;
363
+ }
364
+ void getData().then(result => {
365
+ setContent(result);
366
+ }).catch(e => {
367
+ if (errorHandler) {
368
+ void errorHandler(e);
369
+ }
370
+ });
371
+ }, [getData, isPopupOpen, errorHandler]);
372
+ (0, react_1.useEffect)(() => {
373
+ if (!isPopupOpen) {
374
+ return;
375
+ }
376
+ getValue(description, setContent, "description", errorHandler);
377
+ getValue(date, setContent, "date", errorHandler);
378
+ getValue(count, setContent, "count", errorHandler);
379
+ getValue(secondaryAction, setContent, "secondaryAction", errorHandler);
380
+ getValue(tertiaryAction, setContent, "tertiaryAction", errorHandler);
381
+ getValue(mainAction, setContent, "mainAction", errorHandler);
382
+ }, [content, isPopupOpen, description, date, count, secondaryAction, tertiaryAction, mainAction, errorHandler]);
383
+ return content;
384
+ };
385
+ const usePopupContentReady = ({
386
+ isPopupOpen,
387
+ containerNode
388
+ }) => {
181
389
  const [isPopupContentReady, setIsPopupContentReady] = (0, react_1.useState)(false);
182
- const [containerNode, setContainerNode] = (0, react_1.useState)(null);
183
390
  (0, react_1.useEffect)(() => {
184
391
  if (!isPopupOpen) {
185
392
  setIsPopupContentReady(false);
@@ -199,67 +406,76 @@ const PillExpandableBase = ({
199
406
  observer.unobserve(containerNode);
200
407
  };
201
408
  }, [isPopupOpen, containerNode]);
202
- (0, react_1.useEffect)(() => {
203
- const fetchData = function () {
204
- if (!isPopupOpen) {
205
- return;
206
- }
207
- if ((0, reactHelpers_1.isFunction)(getData)) {
208
- void getData().then(result => {
209
- setContent(result);
210
- }).catch(e => {
211
- if (errorHandler) {
212
- void errorHandler(e);
213
- }
214
- });
215
- }
216
- };
217
- fetchData();
218
- }, [getData, isPopupOpen, errorHandler]);
219
- (0, react_1.useEffect)(() => {
220
- if (!isPopupOpen) {
221
- return;
222
- }
223
- getValue(description, setContent, "description", errorHandler);
224
- getValue(date, setContent, "date", errorHandler);
225
- getValue(count, setContent, "count", errorHandler);
226
- getValue(secondaryAction, setContent, "secondaryAction", errorHandler);
227
- getValue(mainAction, setContent, "mainAction", errorHandler);
228
- }, [content, isPopupOpen, description, date, count, secondaryAction, mainAction, errorHandler]);
409
+ return isPopupContentReady;
410
+ };
411
+ const PillExpandableBase = ({
412
+ children,
413
+ errorHandler,
414
+ getData,
415
+ text,
416
+ description,
417
+ date,
418
+ count,
419
+ mainAction,
420
+ secondaryAction,
421
+ tertiaryAction,
422
+ viewMoreAction,
423
+ uniquePills,
424
+ type,
425
+ className,
426
+ popupClassName,
427
+ isLoading,
428
+ isFlat,
429
+ icon,
430
+ secondaryIcon,
431
+ isBeta,
432
+ loadingWidth = 200,
433
+ hideCounterNumber,
434
+ autoExpandChildren,
435
+ popoverSize = "medium",
436
+ title
437
+ }) => {
438
+ const popupId = (0, react_1.useId)();
439
+ const descriptionId = (0, react_1.useId)();
229
440
  const {
230
- level,
231
- expandedChildPillIds,
232
- onChildPillExpand,
233
- onChildPillCollapse,
234
- autoExpand
441
+ translate
442
+ } = (0, useLanguage_1.useLanguage)();
443
+ const isDrive = (0, useDrive_1.useDrive)();
444
+ const [isMobile, setIsMobile] = (0, react_1.useState)(false);
445
+ const handleDeviceTypeChange = (0, react_1.useCallback)(deviceType => {
446
+ setIsMobile(deviceType === deviceType_1.DeviceType.Mobile);
447
+ }, []);
448
+ (0, useDeviceType_1.useDeviceType)(handleDeviceTypeChange);
449
+ const useMobileSheet = isMobile || isDrive;
450
+ const [isPopupOpen, setIsPopupOpen] = (0, react_1.useState)(false);
451
+ const [containerNode, setContainerNode] = (0, react_1.useState)(null);
452
+ const content = usePillContentState({
453
+ description,
454
+ date,
455
+ count,
456
+ mainAction,
457
+ secondaryAction,
458
+ tertiaryAction,
459
+ getData,
460
+ isPopupOpen,
461
+ errorHandler
462
+ });
463
+ const isPopupContentReady = usePopupContentReady({
464
+ isPopupOpen,
465
+ containerNode
466
+ });
467
+ const {
468
+ level
235
469
  } = (0, react_1.useContext)(PillContext);
236
470
  const triggerRef = (0, react_1.useRef)(null);
237
471
  const isChild = level !== 0;
238
472
  const [currentExpandedPills, setCurrentExpandedPills] = (0, react_1.useState)(new Set());
239
- (0, react_1.useEffect)(() => {
240
- if (isChild && autoExpand) {
241
- onChildPillExpand(pillId);
242
- }
243
- }, [autoExpand, isChild, onChildPillExpand, pillId]);
244
473
  const handlePopupToggle = (0, react_1.useCallback)(e => {
245
474
  var _a;
246
475
  e === null || e === void 0 ? void 0 : e.stopPropagation();
247
476
  setIsPopupOpen(!isPopupOpen);
248
477
  isPopupOpen && ((_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus());
249
478
  }, [isPopupOpen]);
250
- const handleChildToggle = (0, react_1.useCallback)(e => {
251
- e === null || e === void 0 ? void 0 : e.stopPropagation();
252
- const isExpanded = expandedChildPillIds.has(pillId);
253
- if (isExpanded) {
254
- onChildPillCollapse(pillId);
255
- } else {
256
- if (!autoExpand) {
257
- // Prevent multiple child pills being expanded at the same time
258
- expandedChildPillIds.forEach(pill => onChildPillCollapse(pill));
259
- }
260
- onChildPillExpand(pillId);
261
- }
262
- }, [expandedChildPillIds, pillId, autoExpand, onChildPillCollapse, onChildPillExpand]);
263
479
  const addExpandedChild = (0, react_1.useCallback)(id => {
264
480
  setCurrentExpandedPills(prev => {
265
481
  const next = new Set(prev);
@@ -277,16 +493,80 @@ const PillExpandableBase = ({
277
493
  const onChange = (0, react_1.useCallback)(() => {
278
494
  setIsPopupOpen(!isPopupOpen);
279
495
  }, [isPopupOpen]);
280
- const buttonMoreProps = (0, react_1.useMemo)(() => (0, getProps_1.getButtonMoreProps)(viewMoreAction), [viewMoreAction]);
281
- const validChildren = (0, react_1.useMemo)(() => react_1.Children.toArray(children).filter(child => {
496
+ const handlePopupClose = (0, react_1.useCallback)(() => {
282
497
  var _a;
283
- return ((_a = child === null || child === void 0 ? void 0 : child.type) === null || _a === void 0 ? void 0 : _a.displayName) === "PillExpandable";
284
- }), [children]);
498
+ setIsPopupOpen(false);
499
+ (_a = triggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
500
+ }, []);
501
+ const buttonMoreProps = (0, react_1.useMemo)(() => (0, getProps_1.getButtonMoreProps)(viewMoreAction), [viewMoreAction]);
502
+ // For upsell type, force IconUnlocked icon
503
+ const effectiveIcon = type === "upsell" ? iconUnlocked_1.IconUnlocked : icon;
504
+ // Analyze children to determine variant and extract config
505
+ const childrenAnalysis = (0, react_1.useMemo)(() => {
506
+ const childArray = react_1.Children.toArray(children);
507
+ const pillChildren = childArray.filter(child => {
508
+ var _a;
509
+ const displayName = (_a = child === null || child === void 0 ? void 0 : child.type) === null || _a === void 0 ? void 0 : _a.displayName;
510
+ return displayName === "PillExpandable";
511
+ });
512
+ // Custom content = children that are not PillExpandable or PillExpandable.List
513
+ const customChildren = childArray.filter(child => {
514
+ var _a;
515
+ const displayName = (_a = child === null || child === void 0 ? void 0 : child.type) === null || _a === void 0 ? void 0 : _a.displayName;
516
+ return displayName !== "PillExpandable" && displayName !== "PillExpandable.List";
517
+ });
518
+ return {
519
+ hasPillChildren: pillChildren.length > 0,
520
+ hasCustomChildren: customChildren.length > 0,
521
+ customChildren
522
+ };
523
+ }, [children]);
524
+ // Auto-detect variant based on children
525
+ // Priority: placeholder (custom children) > default
526
+ const effectiveVariant = childrenAnalysis.hasCustomChildren ? "placeholder" : "default";
527
+ // For upsell type, silently ignore nested children
528
+ const validChildren = (0, react_1.useMemo)(() => {
529
+ if (type === "upsell") {
530
+ return [];
531
+ }
532
+ return react_1.Children.toArray(children).filter(child => {
533
+ var _a;
534
+ const displayName = (_a = child === null || child === void 0 ? void 0 : child.type) === null || _a === void 0 ? void 0 : _a.displayName;
535
+ // Filter out PillExpandable.List config component and keep only PillExpandable children
536
+ return displayName === "PillExpandable";
537
+ });
538
+ }, [children, type]);
285
539
  const childToDisplay = (0, react_1.useMemo)(() => validChildren.slice(0, MAX_PILLS_TO_DISPLAY_IN_POPUP), [validChildren]);
286
- const childCount = (0, react_1.useMemo)(() => validChildren.length, [validChildren]);
287
- const flatVsChildCounter = isFlat ? `${childCount + 1}` : `${childCount}`;
288
- const moreCounter = uniquePills ? `${uniquePills}` : flatVsChildCounter;
289
- const uniqueChildren = uniquePills ? `${uniquePills}` : `${childCount || ""}`;
540
+ const childCount = validChildren.length;
541
+ const {
542
+ moreCounter,
543
+ uniqueChildren,
544
+ counterText
545
+ } = (0, react_1.useMemo)(() => {
546
+ const flatVsChildCounter = isFlat ? `${childCount + 1}` : `${childCount}`;
547
+ const more = uniquePills ? `${uniquePills}` : flatVsChildCounter;
548
+ const unique = uniquePills ? `${uniquePills}` : childCount ? `${childCount}` : "";
549
+ const counter = unique ? isFlat ? `+${unique}` : unique : "";
550
+ return {
551
+ moreCounter: more,
552
+ uniqueChildren: unique,
553
+ counterText: counter
554
+ };
555
+ }, [isFlat, uniquePills, childCount]);
556
+ const popoverContentProps = (0, react_1.useMemo)(() => ({
557
+ variant: effectiveVariant,
558
+ customContent: childrenAnalysis.hasCustomChildren ? childrenAnalysis.customChildren : undefined,
559
+ descriptionText: content.description,
560
+ date: content.date,
561
+ count: content.count,
562
+ mainAction: content.mainAction,
563
+ secondaryAction: content.secondaryAction,
564
+ tertiaryAction: content.tertiaryAction,
565
+ errorHandler: errorHandler,
566
+ descriptionId,
567
+ childToDisplay
568
+ }), [effectiveVariant, childrenAnalysis, content, errorHandler, descriptionId, childToDisplay]);
569
+ const showFooter = Boolean(moreCounter && viewMoreAction && childCount > MAX_PILLS_TO_DISPLAY_IN_POPUP);
290
570
  if (isLoading) {
291
571
  return (0, jsx_runtime_1.jsx)(skeleton_1.Skeleton, {
292
572
  type: "pill",
@@ -294,35 +574,13 @@ const PillExpandableBase = ({
294
574
  });
295
575
  }
296
576
  if (isChild) {
297
- const isExpanded = expandedChildPillIds.has(pillId);
298
- return (0, jsx_runtime_1.jsxs)(PillContext.Provider, {
299
- value: {
300
- level: level + 1,
301
- onChildPillExpand: addExpandedChild,
302
- onChildPillCollapse: removeExpandedChild,
303
- expandedChildPillIds: currentExpandedPills,
304
- autoExpand: autoExpandChildren || false
305
- },
306
- children: [(0, jsx_runtime_1.jsx)(pillExpandableSimple_1.PillExpandableSimple, {
307
- icon: icon,
308
- text: text,
309
- expanded: isExpanded,
310
- onExpand: handleChildToggle,
311
- expandAriaText: translate("Expand"),
312
- type: type,
313
- errorHandler: errorHandler,
314
- descriptionId: descriptionId
315
- }), (0, jsx_runtime_1.jsx)(pillContent_1.PillContent, {
316
- onActionClick: handleChildToggle,
317
- descriptionText: content.description,
318
- date: content.date,
319
- count: content.count,
320
- mainAction: content.mainAction,
321
- secondaryAction: content.secondaryAction,
322
- isVisible: isExpanded,
323
- errorHandler: errorHandler,
324
- descriptionId: descriptionId
325
- })]
577
+ return (0, jsx_runtime_1.jsx)(PillExpandableChild, {
578
+ icon: icon,
579
+ text: text,
580
+ type: type,
581
+ errorHandler: errorHandler,
582
+ content: content,
583
+ autoExpandChildren: autoExpandChildren
326
584
  });
327
585
  }
328
586
  return (0, jsx_runtime_1.jsx)(PillContext.Provider, {
@@ -340,75 +598,47 @@ const PillExpandableBase = ({
340
598
  className: "zen-status-pill__pill-container",
341
599
  onClick: handlePopupToggle,
342
600
  children: [(0, jsx_runtime_1.jsx)(pillExpandableSimple_1.PillExpandableSimple, {
343
- icon: icon,
601
+ icon: effectiveIcon,
344
602
  text: text,
345
603
  expanded: isPopupOpen,
346
604
  expandAriaText: translate("Expand"),
347
605
  ref: triggerRef,
348
606
  type: type,
349
607
  errorHandler: errorHandler,
350
- isBeta: isBeta
608
+ isBeta: isBeta,
609
+ isMobile: isMobile
351
610
  }), uniqueChildren && (0, jsx_runtime_1.jsx)(pillExpandableSimple_1.PillExpandableSimple, {
352
- icon: secondaryIcon || icon,
353
- text: hideCounterNumber ? "" : `${isFlat ? "+" : ""}${uniqueChildren}`,
611
+ icon: secondaryIcon || effectiveIcon,
612
+ text: hideCounterNumber ? "" : counterText,
354
613
  includeExpandIcon: false,
355
614
  type: type,
356
615
  errorHandler: errorHandler,
357
- className: "zen-status-pill__counter"
616
+ className: "zen-status-pill__counter",
617
+ isMobile: isMobile
358
618
  })]
359
- }), (0, jsx_runtime_1.jsx)(absolute_1.Absolute, {
360
- recalculateTrigger: isPopupContentReady,
361
- recalculateOnScroll: true,
362
- useTrapFocusWithTrigger: "on",
363
- className: popupClassName,
364
- id: popupId,
365
- onOpenChange: onChange,
366
- paddingX: paddingX,
367
- paddingY: paddingY,
619
+ }), (0, jsx_runtime_1.jsx)(PillExpandablePopover, {
620
+ useMobileSheet: useMobileSheet,
368
621
  isOpen: isPopupOpen,
622
+ popupId: popupId,
623
+ popupClassName: popupClassName,
624
+ text: text,
369
625
  triggerRef: triggerRef,
370
- alignmentsFn: pillExpandableAlignments_1.alignments,
371
- children: (0, jsx_runtime_1.jsx)("div", {
372
- ref: node => setContainerNode(node),
373
- className: "zen-status-pill-popup",
374
- children: (0, jsx_runtime_1.jsxs)("div", {
375
- className: "zen-status-pill-popup__container",
376
- children: [(0, jsx_runtime_1.jsx)("div", {
377
- className: "zen-status-pill-popup__main-pill",
378
- children: (0, jsx_runtime_1.jsx)(pillExpandableSimple_1.PillExpandableSimple, {
379
- icon: icon,
380
- text: text,
381
- expanded: true,
382
- onExpand: handlePopupToggle,
383
- expandAriaText: translate("Expand"),
384
- type: type,
385
- errorHandler: errorHandler,
386
- isBeta: isBeta,
387
- descriptionId: descriptionId
388
- })
389
- }), (0, jsx_runtime_1.jsx)(pillContent_1.PillContent, {
390
- onActionClick: handlePopupToggle,
391
- descriptionText: content.description,
392
- date: content.date,
393
- count: content.count,
394
- mainAction: content.mainAction,
395
- secondaryAction: content.secondaryAction,
396
- errorHandler: errorHandler,
397
- descriptionId: descriptionId
398
- }), childToDisplay, moreCounter && viewMoreAction && childCount > MAX_PILLS_TO_DISPLAY_IN_POPUP && (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
399
- children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, {
400
- className: "zen-status-pill-popup__divider"
401
- }), (0, jsx_runtime_1.jsxs)(button_1.Button, Object.assign({}, buttonMoreProps, {
402
- type: "tertiary",
403
- children: [translate("View all"), " (", moreCounter, ")"]
404
- }))]
405
- })]
406
- })
407
- })
626
+ onClose: handlePopupClose,
627
+ onToggle: handlePopupToggle,
628
+ onChange: onChange,
629
+ isPopupContentReady: isPopupContentReady,
630
+ setContainerNode: setContainerNode,
631
+ popoverSize: popoverSize,
632
+ popoverContentProps: popoverContentProps,
633
+ showFooter: showFooter,
634
+ moreCounter: moreCounter,
635
+ buttonMoreProps: buttonMoreProps,
636
+ title: title
408
637
  })]
409
638
  })
410
639
  });
411
640
  };
412
- exports.PillExpandable = (0, react_1.memo)(PillExpandableBase);
413
- exports.PillExpandable.displayName = "PillExpandable";
641
+ const PillExpandableMemo = (0, react_1.memo)(PillExpandableBase);
642
+ PillExpandableMemo.displayName = "PillExpandable";
643
+ exports.PillExpandable = PillExpandableMemo;
414
644
  exports.TRANSLATIONS = ["Expand", "View all"];