@harborclient/sdk 1.3.2 → 1.3.4

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 (102) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/components/AnchorMenuPanel/index.d.ts +35 -0
  3. package/dist/components/AnchorMenuPanel/index.d.ts.map +1 -0
  4. package/dist/components/AnchorMenuPanel/index.js +364 -0
  5. package/dist/components/ColorPicker/index.d.ts +5 -1
  6. package/dist/components/ColorPicker/index.d.ts.map +1 -1
  7. package/dist/components/ColorPicker/index.js +2 -2
  8. package/dist/components/FilterButton/FilterButtonIcon.d.ts +29 -0
  9. package/dist/components/FilterButton/FilterButtonIcon.d.ts.map +1 -0
  10. package/dist/components/FilterButton/FilterButtonIcon.js +18 -0
  11. package/dist/components/FilterButton/index.d.ts +26 -0
  12. package/dist/components/FilterButton/index.d.ts.map +1 -0
  13. package/dist/components/FilterButton/index.js +14 -0
  14. package/dist/components/FormGroup/index.d.ts +7 -1
  15. package/dist/components/FormGroup/index.d.ts.map +1 -1
  16. package/dist/components/FormGroup/index.js +8 -11
  17. package/dist/components/PageSidebar/index.d.ts +1 -0
  18. package/dist/components/PageSidebar/index.d.ts.map +1 -1
  19. package/dist/components/PageSidebar/index.js +4 -13
  20. package/dist/components/Resizable/applyResizableSizes.d.ts +11 -0
  21. package/dist/components/Resizable/applyResizableSizes.d.ts.map +1 -0
  22. package/dist/components/Resizable/applyResizableSizes.js +34 -0
  23. package/dist/components/Resizable/footerPanelUtils.d.ts +1 -1
  24. package/dist/components/Resizable/footerPanelUtils.js +4 -4
  25. package/dist/components/Resizable/index.d.ts +1 -0
  26. package/dist/components/Resizable/index.d.ts.map +1 -1
  27. package/dist/components/Resizable/index.js +1 -0
  28. package/dist/components/Resizable/useResizable.d.ts +7 -1
  29. package/dist/components/Resizable/useResizable.d.ts.map +1 -1
  30. package/dist/components/Resizable/useResizable.js +141 -11
  31. package/dist/components/RowActionsMenu/index.d.ts +7 -1
  32. package/dist/components/RowActionsMenu/index.d.ts.map +1 -1
  33. package/dist/components/RowActionsMenu/index.js +40 -18
  34. package/dist/components/SettingFieldActions/index.d.ts +42 -0
  35. package/dist/components/SettingFieldActions/index.d.ts.map +1 -0
  36. package/dist/components/SettingFieldActions/index.js +66 -0
  37. package/dist/components/SidebarItem/SidebarDocumentItem.d.ts +6 -6
  38. package/dist/components/SidebarItem/SidebarDocumentItem.d.ts.map +1 -1
  39. package/dist/components/SidebarItem/SidebarDocumentItem.js +4 -4
  40. package/dist/components/SidebarItem/SidebarEnvironmentItem.d.ts +4 -4
  41. package/dist/components/SidebarItem/SidebarEnvironmentItem.d.ts.map +1 -1
  42. package/dist/components/SidebarItem/SidebarEnvironmentItem.js +3 -3
  43. package/dist/components/SidebarItem/SidebarFolderItem.d.ts +5 -5
  44. package/dist/components/SidebarItem/SidebarFolderItem.d.ts.map +1 -1
  45. package/dist/components/SidebarItem/SidebarFolderItem.js +4 -4
  46. package/dist/components/SidebarItem/SidebarHistoryItem.d.ts +13 -1
  47. package/dist/components/SidebarItem/SidebarHistoryItem.d.ts.map +1 -1
  48. package/dist/components/SidebarItem/SidebarHistoryItem.js +3 -3
  49. package/dist/components/SidebarItem/SidebarMarkerDot.d.ts +22 -0
  50. package/dist/components/SidebarItem/SidebarMarkerDot.d.ts.map +1 -0
  51. package/dist/components/SidebarItem/SidebarMarkerDot.js +11 -0
  52. package/dist/components/SidebarItem/SidebarMethodBadge.d.ts +9 -1
  53. package/dist/components/SidebarItem/SidebarMethodBadge.d.ts.map +1 -1
  54. package/dist/components/SidebarItem/SidebarMethodBadge.js +7 -5
  55. package/dist/components/SidebarItem/SidebarRequestItem.d.ts +9 -5
  56. package/dist/components/SidebarItem/SidebarRequestItem.d.ts.map +1 -1
  57. package/dist/components/SidebarItem/SidebarRequestItem.js +4 -4
  58. package/dist/components/SidebarItem/SidebarRunItem.d.ts +9 -1
  59. package/dist/components/SidebarItem/SidebarRunItem.d.ts.map +1 -1
  60. package/dist/components/SidebarItem/SidebarRunItem.js +2 -2
  61. package/dist/components/SidebarItem/SidebarStatusDot.d.ts +11 -1
  62. package/dist/components/SidebarItem/SidebarStatusDot.d.ts.map +1 -1
  63. package/dist/components/SidebarItem/SidebarStatusDot.js +10 -1
  64. package/dist/components/SidebarItem/{SidebarTabGroupItem.d.ts → SidebarWorkspaceItem.d.ts} +9 -9
  65. package/dist/components/SidebarItem/SidebarWorkspaceItem.d.ts.map +1 -0
  66. package/dist/components/SidebarItem/{SidebarTabGroupItem.js → SidebarWorkspaceItem.js} +4 -4
  67. package/dist/components/SidebarItem/index.d.ts +3 -3
  68. package/dist/components/SidebarItem/index.d.ts.map +1 -1
  69. package/dist/components/SidebarItem/index.js +3 -3
  70. package/dist/components/SidebarItem/sidebarItemClasses.d.ts +17 -0
  71. package/dist/components/SidebarItem/sidebarItemClasses.d.ts.map +1 -1
  72. package/dist/components/SidebarItem/sidebarItemClasses.js +26 -2
  73. package/dist/components/SidebarSection/SectionItem.d.ts.map +1 -1
  74. package/dist/components/SidebarSection/SectionItem.js +3 -1
  75. package/dist/components/SortButton/SortButtonIcon.d.ts +29 -0
  76. package/dist/components/SortButton/SortButtonIcon.d.ts.map +1 -0
  77. package/dist/components/SortButton/SortButtonIcon.js +18 -0
  78. package/dist/components/SortButton/SortMenu.d.ts +42 -0
  79. package/dist/components/SortButton/SortMenu.d.ts.map +1 -0
  80. package/dist/components/SortButton/SortMenu.js +137 -0
  81. package/dist/components/SortButton/SortMenuOption.d.ts +35 -0
  82. package/dist/components/SortButton/SortMenuOption.d.ts.map +1 -0
  83. package/dist/components/SortButton/SortMenuOption.js +18 -0
  84. package/dist/components/SortButton/index.d.ts +32 -0
  85. package/dist/components/SortButton/index.d.ts.map +1 -0
  86. package/dist/components/SortButton/index.js +15 -0
  87. package/dist/components/SortButton/sortOptions.d.ts +14 -0
  88. package/dist/components/SortButton/sortOptions.d.ts.map +1 -0
  89. package/dist/components/SortButton/sortOptions.js +1 -0
  90. package/dist/components/TabBar/types.d.ts +1 -1
  91. package/dist/components/index.d.ts +9 -2
  92. package/dist/components/index.d.ts.map +1 -1
  93. package/dist/components/index.js +8 -2
  94. package/dist/runtime/createBridgedPluginContext.js +170 -2
  95. package/dist/snippets.d.ts +22 -0
  96. package/dist/types.d.ts +913 -1
  97. package/dist/types.d.ts.map +1 -1
  98. package/package.json +3 -3
  99. package/dist/components/SidebarItem/SidebarColorDot.d.ts +0 -22
  100. package/dist/components/SidebarItem/SidebarColorDot.d.ts.map +0 -1
  101. package/dist/components/SidebarItem/SidebarColorDot.js +0 -11
  102. package/dist/components/SidebarItem/SidebarTabGroupItem.d.ts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 1.3.4 - 2026-07-28
8
+
9
+ - Implement hc.ask API for one-shot AI completions. (`aed2809f`)
10
+ - Enhance plugin library and sidebar selection handling. (`5a919ac6`)
11
+ - Enhance settings management and UI components. (`31e7f975`)
12
+ - Refactor settings draft management and enhance default handling. (`5650b3e6`)
13
+ - Refactor BodyEditor and enhance selection handling. (`d28dd6b7`)
14
+ - Refactor shortcuts handling and update UI components. (`a85cf446`)
15
+ - Enhance response handling and UI features. (`b076b194`)
16
+
17
+ ## 1.3.3 - 2026-07-27
18
+
19
+ - Update @harborclient/team-hub-api dependency to version 0.4.1 and enhance documentation for import handlers. (`516c9dae`)
20
+ - Add OpenCollection Import Functionality. (`ac4dc71a`)
21
+ - Add Appearance Options for Storage Locations, Color Markers, Highlights, and Indicators. (`ee9e54d5`)
22
+ - Rename `SidebarTabGroupItem` to `SidebarWorkspaceItem`. Breaking export rename; requires a major release.
23
+ - Refactor sidebar color handling to markers. (`6f53f3d7`)
24
+ - Add Filters and Sorting Options to Sidebar Menu. (`d17dea07`)
25
+ - Enhance menu functionality and visibility options. (`89cf8584`)
26
+
7
27
  ## 1.3.2 - 2026-07-26
8
28
 
9
29
  - Add dismissedRequestEditorNotices to general settings. (`22551faa`)
@@ -0,0 +1,35 @@
1
+ import type { JSX } from 'react';
2
+ import type { MenuItem } from '../RowActionsMenu/index.js';
3
+ import { type MenuPosition } from '../menuPosition.js';
4
+ interface Props {
5
+ /**
6
+ * Grouped menu entries. Each inner array is one visual group separated by a divider.
7
+ */
8
+ groups: MenuItem[][];
9
+ /**
10
+ * Host viewport coordinates for the panel top-left corner (before clamping).
11
+ */
12
+ anchor: MenuPosition;
13
+ /**
14
+ * Called when the menu dismisses (outside click, Escape, Tab, or item select).
15
+ */
16
+ onDismiss: () => void;
17
+ /**
18
+ * Unique id for this menu instance (used for a11y ids). Defaults to `anchor-menu`.
19
+ */
20
+ menuId?: string;
21
+ /**
22
+ * Optional class names merged onto the portaled panel.
23
+ */
24
+ className?: string;
25
+ }
26
+ /**
27
+ * Portaled context menu panel anchored to viewport coordinates (no hamburger trigger).
28
+ *
29
+ * Used by the host for plugin-requested entity menus (`showEntityContextMenu`) and any
30
+ * other cursor-anchored menu that should match {@link RowActionsMenu} keyboard and
31
+ * submenu behavior without owning a row trigger button.
32
+ */
33
+ export declare function AnchorMenuPanel({ groups, anchor, onDismiss, menuId, className }: Props): JSX.Element | null;
34
+ export {};
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/AnchorMenuPanel/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAGhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAqB,KAAK,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAU7F,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,SAAS,EACT,MAAsB,EACtB,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CA+c5B"}
@@ -0,0 +1,364 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@harborclient/sdk/jsx-runtime";
2
+ import { faCaretRight, faCheck } from '@fortawesome/free-solid-svg-icons';
3
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from '@harborclient/sdk/react';
4
+ import { FaIcon } from '../FaIcon/index.js';
5
+ import { Submenu } from '../RowActionsMenu/Submenu.js';
6
+ import { MENU_MIN_WIDTH_PX, clampMenuPosition } from '../menuPosition.js';
7
+ import { portalToBody } from '../portalToBody.js';
8
+ import { findAdjacentEnabledIndex, findEdgeEnabledIndex, isMenuItemEnabled, menuItemClass } from '../rowActionsMenuHelpers.js';
9
+ import { cn, resolveMenuTypeahead } from '../utils.js';
10
+ const TYPEAHEAD_TIMEOUT_MS = 500;
11
+ /** Delay before a hovered row's submenu opens. */
12
+ const SUBMENU_OPEN_DELAY_MS = 120;
13
+ /** Delay before a submenu closes after the pointer leaves its row and panel. */
14
+ const SUBMENU_CLOSE_DELAY_MS = 200;
15
+ /**
16
+ * Portaled context menu panel anchored to viewport coordinates (no hamburger trigger).
17
+ *
18
+ * Used by the host for plugin-requested entity menus (`showEntityContextMenu`) and any
19
+ * other cursor-anchored menu that should match {@link RowActionsMenu} keyboard and
20
+ * submenu behavior without owning a row trigger button.
21
+ */
22
+ export function AnchorMenuPanel({ groups, anchor, onDismiss, menuId = 'anchor-menu', className }) {
23
+ const menuElementId = `${menuId}-menu`;
24
+ const submenuElementId = `${menuId}-submenu`;
25
+ const panelRef = useRef(null);
26
+ const itemRefs = useRef([]);
27
+ const typeaheadBuffer = useRef('');
28
+ const typeaheadTimer = useRef(null);
29
+ const submenuOpenTimer = useRef(null);
30
+ const submenuCloseTimer = useRef(null);
31
+ const [focusedIndex, setFocusedIndex] = useState(0);
32
+ const [menuPosition, setMenuPosition] = useState(anchor);
33
+ const [openSubmenuIndex, setOpenSubmenuIndex] = useState(null);
34
+ /**
35
+ * Flattens grouped items once for keyboard navigation and typeahead.
36
+ */
37
+ const flatItems = useMemo(() => groups.flat(), [groups]);
38
+ /**
39
+ * Labels used by typeahead matching.
40
+ */
41
+ const itemLabels = useMemo(() => flatItems.map((item) => item.label), [flatItems]);
42
+ /**
43
+ * Whether any item can receive focus / activation.
44
+ */
45
+ const hasEnabledItems = useMemo(() => flatItems.some((item) => isMenuItemEnabled(item)), [flatItems]);
46
+ /**
47
+ * Clears the accumulated typeahead buffer.
48
+ */
49
+ const clearTypeahead = useCallback(() => {
50
+ typeaheadBuffer.current = '';
51
+ if (typeaheadTimer.current != null) {
52
+ window.clearTimeout(typeaheadTimer.current);
53
+ typeaheadTimer.current = null;
54
+ }
55
+ }, []);
56
+ /**
57
+ * Cancels any pending submenu open/close timers.
58
+ */
59
+ const clearSubmenuTimers = useCallback(() => {
60
+ if (submenuOpenTimer.current != null) {
61
+ window.clearTimeout(submenuOpenTimer.current);
62
+ submenuOpenTimer.current = null;
63
+ }
64
+ if (submenuCloseTimer.current != null) {
65
+ window.clearTimeout(submenuCloseTimer.current);
66
+ submenuCloseTimer.current = null;
67
+ }
68
+ }, []);
69
+ /**
70
+ * Dismisses the menu and clears transient keyboard/submenu state.
71
+ */
72
+ const dismiss = useCallback(() => {
73
+ clearTypeahead();
74
+ clearSubmenuTimers();
75
+ onDismiss();
76
+ }, [clearSubmenuTimers, clearTypeahead, onDismiss]);
77
+ /**
78
+ * Opens the submenu belonging to the item at `index` immediately.
79
+ *
80
+ * @param index - Flat item index that owns a submenu.
81
+ */
82
+ const openSubmenuAt = useCallback((index) => {
83
+ clearSubmenuTimers();
84
+ setOpenSubmenuIndex(index);
85
+ }, [clearSubmenuTimers]);
86
+ /**
87
+ * Closes the currently open submenu and returns focus to its parent row.
88
+ */
89
+ const closeSubmenuAndRefocus = useCallback(() => {
90
+ clearSubmenuTimers();
91
+ setOpenSubmenuIndex((current) => {
92
+ if (current != null) {
93
+ requestAnimationFrame(() => {
94
+ itemRefs.current[current]?.focus();
95
+ });
96
+ }
97
+ return null;
98
+ });
99
+ }, [clearSubmenuTimers]);
100
+ /**
101
+ * Schedules opening the submenu at `index` after a short hover-intent delay.
102
+ *
103
+ * @param index - Flat item index that owns a submenu.
104
+ */
105
+ const scheduleOpenSubmenu = useCallback((index) => {
106
+ clearSubmenuTimers();
107
+ submenuOpenTimer.current = window.setTimeout(() => {
108
+ submenuOpenTimer.current = null;
109
+ setOpenSubmenuIndex(index);
110
+ }, SUBMENU_OPEN_DELAY_MS);
111
+ }, [clearSubmenuTimers]);
112
+ /**
113
+ * Schedules closing the open submenu after a short delay.
114
+ */
115
+ const scheduleCloseSubmenu = useCallback(() => {
116
+ if (submenuOpenTimer.current != null) {
117
+ window.clearTimeout(submenuOpenTimer.current);
118
+ submenuOpenTimer.current = null;
119
+ }
120
+ submenuCloseTimer.current = window.setTimeout(() => {
121
+ submenuCloseTimer.current = null;
122
+ setOpenSubmenuIndex(null);
123
+ }, SUBMENU_CLOSE_DELAY_MS);
124
+ }, []);
125
+ /**
126
+ * Handles pointer hover over a row: opens that row's submenu or schedules close.
127
+ *
128
+ * @param item - Menu item under the pointer.
129
+ * @param itemIndex - Flat index of that item.
130
+ */
131
+ const handleItemMouseEnter = useCallback((item, itemIndex) => {
132
+ if (item.submenu) {
133
+ if (openSubmenuIndex === itemIndex) {
134
+ clearSubmenuTimers();
135
+ }
136
+ else if (openSubmenuIndex != null) {
137
+ openSubmenuAt(itemIndex);
138
+ }
139
+ else {
140
+ scheduleOpenSubmenu(itemIndex);
141
+ }
142
+ return;
143
+ }
144
+ if (openSubmenuIndex != null) {
145
+ scheduleCloseSubmenu();
146
+ }
147
+ else {
148
+ clearSubmenuTimers();
149
+ }
150
+ }, [clearSubmenuTimers, openSubmenuAt, openSubmenuIndex, scheduleCloseSubmenu, scheduleOpenSubmenu]);
151
+ /**
152
+ * Focuses a menu item by index and updates roving tabindex state.
153
+ *
154
+ * @param index - Flat item index to focus.
155
+ */
156
+ const focusItem = useCallback((index) => {
157
+ setFocusedIndex(index);
158
+ requestAnimationFrame(() => {
159
+ itemRefs.current[index]?.focus();
160
+ });
161
+ }, []);
162
+ /**
163
+ * Clamps the panel so it stays fully inside the viewport using measured size.
164
+ */
165
+ const updateMenuPosition = useCallback(() => {
166
+ const panelRect = panelRef.current?.getBoundingClientRect();
167
+ const menuSize = {
168
+ width: panelRect?.width ?? MENU_MIN_WIDTH_PX,
169
+ height: panelRect?.height ?? 0
170
+ };
171
+ if (menuSize.height > 0) {
172
+ setMenuPosition(clampMenuPosition(anchor, menuSize));
173
+ return;
174
+ }
175
+ setMenuPosition(anchor);
176
+ }, [anchor]);
177
+ /**
178
+ * Focuses the first enabled item after mount.
179
+ */
180
+ useEffect(() => {
181
+ if (!hasEnabledItems) {
182
+ return;
183
+ }
184
+ const edgeIndex = findEdgeEnabledIndex(flatItems, false);
185
+ if (edgeIndex == null) {
186
+ return;
187
+ }
188
+ setFocusedIndex(edgeIndex);
189
+ requestAnimationFrame(() => {
190
+ itemRefs.current[edgeIndex]?.focus();
191
+ });
192
+ }, [flatItems, hasEnabledItems]);
193
+ /**
194
+ * Re-clamps the portaled menu after mount once panel dimensions are known.
195
+ */
196
+ useLayoutEffect(() => {
197
+ updateMenuPosition();
198
+ }, [groups, updateMenuPosition]);
199
+ /**
200
+ * Re-clamps on scroll/resize while the panel is open.
201
+ */
202
+ useEffect(() => {
203
+ updateMenuPosition();
204
+ window.addEventListener('scroll', updateMenuPosition, true);
205
+ window.addEventListener('resize', updateMenuPosition);
206
+ return () => {
207
+ window.removeEventListener('scroll', updateMenuPosition, true);
208
+ window.removeEventListener('resize', updateMenuPosition);
209
+ };
210
+ }, [updateMenuPosition]);
211
+ /**
212
+ * Dismisses on outside click; Escape closes submenu first, then the panel.
213
+ */
214
+ useEffect(() => {
215
+ const handleMouseDown = (e) => {
216
+ const target = e.target;
217
+ if (panelRef.current?.contains(target) ||
218
+ document.getElementById(submenuElementId)?.contains(target)) {
219
+ return;
220
+ }
221
+ dismiss();
222
+ };
223
+ const handleKeyDown = (e) => {
224
+ if (e.key === 'Escape') {
225
+ e.preventDefault();
226
+ if (openSubmenuIndex != null) {
227
+ closeSubmenuAndRefocus();
228
+ }
229
+ else {
230
+ dismiss();
231
+ }
232
+ }
233
+ };
234
+ document.addEventListener('mousedown', handleMouseDown);
235
+ document.addEventListener('keydown', handleKeyDown);
236
+ return () => {
237
+ document.removeEventListener('mousedown', handleMouseDown);
238
+ document.removeEventListener('keydown', handleKeyDown);
239
+ };
240
+ }, [closeSubmenuAndRefocus, dismiss, openSubmenuIndex, submenuElementId]);
241
+ /**
242
+ * Clears timers on unmount.
243
+ */
244
+ useEffect(() => {
245
+ return () => {
246
+ clearTypeahead();
247
+ clearSubmenuTimers();
248
+ };
249
+ }, [clearSubmenuTimers, clearTypeahead]);
250
+ /**
251
+ * Handles keyboard navigation within the open menu.
252
+ *
253
+ * @param event - Keyboard event from the menu panel.
254
+ */
255
+ const handleMenuKeyDown = (event) => {
256
+ if (!hasEnabledItems)
257
+ return;
258
+ if (event.key === 'Tab') {
259
+ dismiss();
260
+ return;
261
+ }
262
+ if (event.key === 'ArrowRight') {
263
+ const candidate = flatItems[focusedIndex];
264
+ if (candidate?.submenu) {
265
+ event.preventDefault();
266
+ openSubmenuAt(focusedIndex);
267
+ }
268
+ return;
269
+ }
270
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
271
+ const direction = event.key === 'ArrowDown' ? 1 : -1;
272
+ const nextIndex = findAdjacentEnabledIndex(flatItems, focusedIndex, direction);
273
+ if (nextIndex != null) {
274
+ event.preventDefault();
275
+ clearTypeahead();
276
+ focusItem(nextIndex);
277
+ }
278
+ return;
279
+ }
280
+ if (event.key === 'Home') {
281
+ const firstIndex = findEdgeEnabledIndex(flatItems, false);
282
+ if (firstIndex != null) {
283
+ event.preventDefault();
284
+ clearTypeahead();
285
+ focusItem(firstIndex);
286
+ }
287
+ return;
288
+ }
289
+ if (event.key === 'End') {
290
+ const lastIndex = findEdgeEnabledIndex(flatItems, true);
291
+ if (lastIndex != null) {
292
+ event.preventDefault();
293
+ clearTypeahead();
294
+ focusItem(lastIndex);
295
+ }
296
+ return;
297
+ }
298
+ const typeahead = resolveMenuTypeahead(itemLabels, focusedIndex, event.key, typeaheadBuffer.current);
299
+ if (typeahead) {
300
+ const candidate = flatItems[typeahead.index];
301
+ if (!candidate || !isMenuItemEnabled(candidate)) {
302
+ return;
303
+ }
304
+ event.preventDefault();
305
+ typeaheadBuffer.current = typeahead.buffer;
306
+ if (typeaheadTimer.current != null) {
307
+ window.clearTimeout(typeaheadTimer.current);
308
+ }
309
+ typeaheadTimer.current = window.setTimeout(() => {
310
+ typeaheadBuffer.current = '';
311
+ typeaheadTimer.current = null;
312
+ }, TYPEAHEAD_TIMEOUT_MS);
313
+ focusItem(typeahead.index);
314
+ }
315
+ };
316
+ if (!hasEnabledItems) {
317
+ return null;
318
+ }
319
+ const openSubmenuItem = openSubmenuIndex != null ? flatItems[openSubmenuIndex] : undefined;
320
+ const openSubmenuAnchorRect = openSubmenuIndex != null ? itemRefs.current[openSubmenuIndex]?.getBoundingClientRect() : null;
321
+ const menuPanel = (_jsx("div", { ref: panelRef, id: menuElementId, role: "menu", className: cn('hc-anchor-menu-panel hc-row-actions-menu-panel app-no-drag fixed z-50 min-w-[200px] rounded-md border border-separator bg-surface py-1 shadow-md', className), style: { left: menuPosition.x, top: menuPosition.y }, onKeyDown: handleMenuKeyDown, onMouseLeave: () => {
322
+ if (openSubmenuIndex != null) {
323
+ scheduleCloseSubmenu();
324
+ }
325
+ }, children: groups.map((group, groupIndex) => {
326
+ let flatIndex = groups.slice(0, groupIndex).reduce((count, g) => count + g.length, 0);
327
+ return (_jsx("div", { className: groupIndex > 0
328
+ ? 'hc-row-actions-menu-group border-t border-separator'
329
+ : 'hc-row-actions-menu-group', children: group.map((item) => {
330
+ const itemIndex = flatIndex++;
331
+ const isCheckboxItem = item.checked !== undefined;
332
+ const isDisabled = item.disabled === true;
333
+ const hasSubmenu = item.submenu !== undefined;
334
+ return (_jsxs("button", { ref: (el) => {
335
+ itemRefs.current[itemIndex] = isDisabled ? null : el;
336
+ }, type: "button", role: isCheckboxItem ? 'menuitemcheckbox' : 'menuitem', "aria-checked": isCheckboxItem ? item.checked : undefined, "aria-disabled": isDisabled || undefined, "aria-haspopup": hasSubmenu ? 'menu' : undefined, "aria-expanded": hasSubmenu ? openSubmenuIndex === itemIndex : undefined, "aria-controls": hasSubmenu && openSubmenuIndex === itemIndex ? submenuElementId : undefined, disabled: isDisabled, tabIndex: isDisabled ? -1 : itemIndex === focusedIndex ? 0 : -1, className: cn('hc-row-actions-menu-item', menuItemClass(item.variant, isDisabled)), onMouseEnter: () => {
337
+ if (!isDisabled) {
338
+ handleItemMouseEnter(item, itemIndex);
339
+ }
340
+ }, onClick: (e) => {
341
+ e.stopPropagation();
342
+ if (isDisabled) {
343
+ return;
344
+ }
345
+ if (item.submenu) {
346
+ if (openSubmenuIndex === itemIndex) {
347
+ closeSubmenuAndRefocus();
348
+ }
349
+ else {
350
+ openSubmenuAt(itemIndex);
351
+ }
352
+ return;
353
+ }
354
+ dismiss();
355
+ item.onSelect();
356
+ }, children: [isCheckboxItem ? (_jsx("span", { className: "hc-row-actions-menu-item-check inline-flex w-4 shrink-0 justify-center", "aria-hidden": true, children: item.checked ? _jsx(FaIcon, { icon: faCheck, className: "h-3 w-3" }) : null })) : null, _jsx("span", { className: "hc-row-actions-menu-item-label min-w-0", children: item.label }), hasSubmenu ? (_jsx(FaIcon, { icon: faCaretRight, className: "ml-auto h-3 w-3 shrink-0", "aria-hidden": true })) : null] }, item.label));
357
+ }) }, groupIndex));
358
+ }) }));
359
+ const submenuPanel = openSubmenuItem?.submenu && openSubmenuAnchorRect ? (_jsx(Submenu, { groups: openSubmenuItem.submenu, anchorRect: openSubmenuAnchorRect, menuElementId: submenuElementId, onSelectItem: (item) => {
360
+ dismiss();
361
+ item.onSelect?.();
362
+ }, onRequestClose: closeSubmenuAndRefocus, onCloseAll: dismiss, onMouseEnter: clearSubmenuTimers, onMouseLeave: scheduleCloseSubmenu })) : null;
363
+ return (_jsxs(_Fragment, { children: [portalToBody(menuPanel), submenuPanel] }));
364
+ }
@@ -12,6 +12,10 @@ export interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
12
12
  * Called when the user clears the current color. Omitted when clearing is disabled.
13
13
  */
14
14
  onClear?: () => void;
15
+ /**
16
+ * Label for the clear button, so hosts can name what is being cleared.
17
+ */
18
+ clearLabel?: string;
15
19
  /**
16
20
  * Fixed preset swatches (defaults to two rows of five HarborClient colors).
17
21
  */
@@ -35,5 +39,5 @@ export interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
35
39
  * Custom slots open the native OS color picker via a hidden `<input type="color">`.
36
40
  * Chosen custom colors are saved to localStorage for reuse.
37
41
  */
38
- export declare function ColorPicker({ value, onChange, onClear, presets, customSwatchesStorageKey, 'aria-label': ariaLabel, className, ...props }: Props): JSX.Element;
42
+ export declare function ColorPicker({ value, onChange, onClear, clearLabel, presets, customSwatchesStorageKey, 'aria-label': ariaLabel, className, ...props }: Props): JSX.Element;
39
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ColorPicker/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAW1E,MAAM,WAAW,KAAM,SAAQ,IAAI,CACjC,wBAAwB,CAAC,KAAK,CAAC,EAC/B,UAAU,GAAG,WAAW,GAAG,UAAU,CACtC;IACC;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE5B;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAElC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,OAAsC,EACtC,wBAA8D,EAC9D,YAAY,EAAE,SAA4B,EAC1C,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAgLrB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ColorPicker/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAW1E,MAAM,WAAW,KAAM,SAAQ,IAAI,CACjC,wBAAwB,CAAC,KAAK,CAAC,EAC/B,UAAU,GAAG,WAAW,GAAG,UAAU,CACtC;IACC;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE5B;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAElC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,OAAO,EACP,UAA0B,EAC1B,OAAsC,EACtC,wBAA8D,EAC9D,YAAY,EAAE,SAA4B,EAC1C,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAgLrB"}
@@ -11,7 +11,7 @@ import { DEFAULT_CUSTOM_SWATCHES_STORAGE_KEY, loadCustomSwatches, padCustomSwatc
11
11
  * Custom slots open the native OS color picker via a hidden `<input type="color">`.
12
12
  * Chosen custom colors are saved to localStorage for reuse.
13
13
  */
14
- export function ColorPicker({ value, onChange, onClear, presets = DEFAULT_COLOR_PICKER_PRESETS, customSwatchesStorageKey = DEFAULT_CUSTOM_SWATCHES_STORAGE_KEY, 'aria-label': ariaLabel = 'Choose a color', className, ...props }) {
14
+ export function ColorPicker({ value, onChange, onClear, clearLabel = 'Clear color', presets = DEFAULT_COLOR_PICKER_PRESETS, customSwatchesStorageKey = DEFAULT_CUSTOM_SWATCHES_STORAGE_KEY, 'aria-label': ariaLabel = 'Choose a color', className, ...props }) {
15
15
  const groupId = useId();
16
16
  const nativeInputRef = useRef(null);
17
17
  const pendingCustomSlotRef = useRef(null);
@@ -99,5 +99,5 @@ export function ColorPicker({ value, onChange, onClear, presets = DEFAULT_COLOR_
99
99
  }
100
100
  openNativePickerForSlot(index, slotColor);
101
101
  }, () => openNativePickerForSlot(index, slotColor));
102
- }) }), onClear != null && value != null && value.trim() !== '' ? (_jsx("button", { type: "button", className: "self-start text-[14px] text-muted hover:text-text focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent", onClick: onClear, children: "Clear color" })) : null, _jsx("input", { ref: nativeInputRef, type: "color", className: "sr-only", tabIndex: -1, "aria-hidden": true, onChange: (event) => applyNativePickerColor(event.target.value) })] }));
102
+ }) }), onClear != null && value != null && value.trim() !== '' ? (_jsx("button", { type: "button", className: "self-start text-[14px] text-muted hover:text-text focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent", onClick: onClear, children: clearLabel })) : null, _jsx("input", { ref: nativeInputRef, type: "color", className: "sr-only", tabIndex: -1, "aria-hidden": true, onChange: (event) => applyNativePickerColor(event.target.value) })] }));
103
103
  }
@@ -0,0 +1,29 @@
1
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
2
+ import type { JSX } from 'react';
3
+ interface Props {
4
+ /**
5
+ * When true, shows a SegmentedTabs-matching accent dot on the icon corner.
6
+ */
7
+ active?: boolean;
8
+ /**
9
+ * Font Awesome icon to render. Defaults to the filter funnel.
10
+ */
11
+ icon?: IconDefinition;
12
+ /**
13
+ * Additional classes merged onto the icon wrapper.
14
+ */
15
+ className?: string;
16
+ }
17
+ /**
18
+ * Filter funnel icon with an optional accent corner indicator when filters are
19
+ * applied. Shared by {@link FilterButton} and filter-style `RowActionsMenu`
20
+ * triggers so the active affordance stays consistent.
21
+ *
22
+ * @param active - When true, shows the accent status dot.
23
+ * @param icon - Icon to render; defaults to `faFilter`.
24
+ * @param className - Extra classes for the wrapper.
25
+ * @returns Relative icon wrapper with optional active indicator.
26
+ */
27
+ export declare function FilterButtonIcon({ active, icon, className }: Props): JSX.Element;
28
+ export {};
29
+ //# sourceMappingURL=FilterButtonIcon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilterButtonIcon.d.ts","sourceRoot":"","sources":["../../../src/components/FilterButton/FilterButtonIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAExE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAKjC,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAc,EACd,IAAe,EACf,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAcrB"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ import { faFilter } from '@fortawesome/free-solid-svg-icons';
3
+ import { FaIcon } from '../FaIcon/index.js';
4
+ import { StatusDot } from '../StatusDot/index.js';
5
+ import { cn } from '../utils.js';
6
+ /**
7
+ * Filter funnel icon with an optional accent corner indicator when filters are
8
+ * applied. Shared by {@link FilterButton} and filter-style `RowActionsMenu`
9
+ * triggers so the active affordance stays consistent.
10
+ *
11
+ * @param active - When true, shows the accent status dot.
12
+ * @param icon - Icon to render; defaults to `faFilter`.
13
+ * @param className - Extra classes for the wrapper.
14
+ * @returns Relative icon wrapper with optional active indicator.
15
+ */
16
+ export function FilterButtonIcon({ active = false, icon = faFilter, className }) {
17
+ return (_jsxs("span", { className: cn('hc-filter-button-icon relative inline-flex shrink-0', className), children: [_jsx(FaIcon, { icon: icon, className: "h-3.5 w-3.5", "aria-hidden": true }), active ? (_jsx(StatusDot, { variant: "accent", size: "sm", label: "Filters applied", className: "absolute -top-0.5 -right-0.5" })) : null] }));
18
+ }
@@ -0,0 +1,26 @@
1
+ import type { ComponentPropsWithoutRef, JSX, RefObject } from 'react';
2
+ interface Props extends Omit<ComponentPropsWithoutRef<'button'>, 'children' | 'aria-label'> {
3
+ /**
4
+ * When true, shows the accent filter-active indicator and full-contrast icon
5
+ * color. When false, the icon uses muted text until hover.
6
+ */
7
+ active?: boolean;
8
+ /**
9
+ * Accessible name for the icon-only control.
10
+ */
11
+ 'aria-label': string;
12
+ /**
13
+ * Ref forwarded to the underlying native button for popover anchoring.
14
+ */
15
+ innerRef?: RefObject<HTMLButtonElement | null>;
16
+ }
17
+ /**
18
+ * Toolbar filter trigger with an optional accent corner indicator when filters
19
+ * are in effect. Matches the SegmentedTabs indicator color (`bg-accent`).
20
+ *
21
+ * Defaults to `type="button"`. Pass `title` for a native tooltip; when omitted,
22
+ * the tooltip falls back to `aria-label`.
23
+ */
24
+ export declare function FilterButton({ active, className, title, innerRef, type, 'aria-label': ariaLabel, ...props }: Props): JSX.Element;
25
+ export {};
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FilterButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKtE,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACzF;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CAChD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAc,EACd,SAAS,EACT,KAAK,EACL,QAAQ,EACR,IAAe,EACf,YAAY,EAAE,SAAS,EACvB,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAkBrB"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
2
+ import { Button } from '../Button/index.js';
3
+ import { cn } from '../utils.js';
4
+ import { FilterButtonIcon } from './FilterButtonIcon.js';
5
+ /**
6
+ * Toolbar filter trigger with an optional accent corner indicator when filters
7
+ * are in effect. Matches the SegmentedTabs indicator color (`bg-accent`).
8
+ *
9
+ * Defaults to `type="button"`. Pass `title` for a native tooltip; when omitted,
10
+ * the tooltip falls back to `aria-label`.
11
+ */
12
+ export function FilterButton({ active = false, className, title, innerRef, type = 'button', 'aria-label': ariaLabel, ...props }) {
13
+ return (_jsx(Button, { ...props, type: type, variant: "toolbar", innerRef: innerRef, "aria-label": ariaLabel, title: title ?? ariaLabel, className: cn('hc-filter-button', active ? 'text-text hover:text-text' : 'text-muted hover:text-text', className), children: _jsx(FilterButtonIcon, { active: active }) }));
14
+ }
@@ -62,12 +62,18 @@ interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'clas
62
62
  * inline layouts for fields nested inside an already-bordered section.
63
63
  */
64
64
  bordered?: boolean;
65
+ /**
66
+ * When true and `bordered`, draws a left border using the unsaved-tab color
67
+ * (`--color-tab-unsaved`) to indicate the field value differs from its factory
68
+ * default — the same token used for dirty request tab titles.
69
+ */
70
+ modified?: boolean;
65
71
  }
66
72
  /**
67
73
  * Reusable form field wrapper that pairs a label with one or more controls.
68
74
  * Supports stacked fields, checkboxes, inline rows, radio options, and
69
75
  * adjacent checkbox rows used in list pickers.
70
76
  */
71
- export declare function FormGroup({ label, children, htmlFor, description, error, errorId, descriptionId, layout, labelTone, srOnly, className, labelClassName, bordered, ...props }: Props): JSX.Element;
77
+ export declare function FormGroup({ label, children, htmlFor, description, error, errorId, descriptionId, layout, labelTone, srOnly, className, labelClassName, bordered, modified, ...props }: Props): JSX.Element;
72
78
  export {};
73
79
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FormGroup/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,UAAU,GACV,QAAQ,GACR,OAAO,GACP,kBAAkB,GAClB,YAAY,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,CAAC;AAErD,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACrF;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IAEzB;;OAEG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAE/B;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAoCD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,KAAK,EACL,OAAO,EACP,aAAa,EACb,MAAkB,EAClB,SAAqB,EACrB,MAAc,EACd,SAAS,EACT,cAAc,EACd,QAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA8IrB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FormGroup/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,UAAU,GACV,QAAQ,GACR,OAAO,GACP,kBAAkB,GAClB,YAAY,CAAC;AAEjB;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,OAAO,CAAC;AAErD,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;IACrF;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IAEzB;;OAEG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAE/B;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAsCD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAW,EACX,KAAK,EACL,OAAO,EACP,aAAa,EACb,MAAkB,EAClB,SAAqB,EACrB,MAAc,EACd,SAAS,EACT,cAAc,EACd,QAAe,EACf,QAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA+IrB"}