@harborclient/sdk 1.3.3 → 1.3.5
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.
- package/CHANGELOG.md +24 -0
- package/dist/components/AnchorMenuPanel/index.d.ts +35 -0
- package/dist/components/AnchorMenuPanel/index.d.ts.map +1 -0
- package/dist/components/AnchorMenuPanel/index.js +364 -0
- package/dist/components/Breadcrumb/SegmentShell.d.ts +12 -1
- package/dist/components/Breadcrumb/SegmentShell.d.ts.map +1 -1
- package/dist/components/Breadcrumb/SegmentShell.js +7 -5
- package/dist/components/CodeEditor/index.d.ts +7 -4
- package/dist/components/CodeEditor/index.d.ts.map +1 -1
- package/dist/components/CodeEditor/index.js +15 -176
- package/dist/components/CodeEditor/selectionActionToolbar.d.ts +162 -0
- package/dist/components/CodeEditor/selectionActionToolbar.d.ts.map +1 -0
- package/dist/components/CodeEditor/selectionActionToolbar.js +319 -0
- package/dist/components/CopyToChatButton/constants.d.ts +18 -0
- package/dist/components/CopyToChatButton/constants.d.ts.map +1 -0
- package/dist/components/CopyToChatButton/constants.js +19 -0
- package/dist/components/CopyToChatButton/index.d.ts +49 -0
- package/dist/components/CopyToChatButton/index.d.ts.map +1 -0
- package/dist/components/CopyToChatButton/index.js +43 -0
- package/dist/components/FloatingDialog/floatingDialogPosition.d.ts +52 -0
- package/dist/components/FloatingDialog/floatingDialogPosition.d.ts.map +1 -0
- package/dist/components/FloatingDialog/floatingDialogPosition.js +33 -0
- package/dist/components/FloatingDialog/index.d.ts +95 -0
- package/dist/components/FloatingDialog/index.d.ts.map +1 -0
- package/dist/components/FloatingDialog/index.js +275 -0
- package/dist/components/FormGroup/index.d.ts +7 -1
- package/dist/components/FormGroup/index.d.ts.map +1 -1
- package/dist/components/FormGroup/index.js +8 -11
- package/dist/components/PageHeader/index.d.ts +2 -1
- package/dist/components/PageHeader/index.d.ts.map +1 -1
- package/dist/components/PageHeader/index.js +3 -2
- package/dist/components/PageSidebar/index.d.ts +1 -0
- package/dist/components/PageSidebar/index.d.ts.map +1 -1
- package/dist/components/PageSidebar/index.js +4 -13
- package/dist/components/Resizable/useResizable.d.ts +6 -0
- package/dist/components/Resizable/useResizable.d.ts.map +1 -1
- package/dist/components/Resizable/useResizable.js +113 -11
- package/dist/components/SettingFieldActions/index.d.ts +42 -0
- package/dist/components/SettingFieldActions/index.d.ts.map +1 -0
- package/dist/components/SettingFieldActions/index.js +66 -0
- package/dist/components/SidebarItem/SidebarEnvironmentItem.d.ts +42 -4
- package/dist/components/SidebarItem/SidebarEnvironmentItem.d.ts.map +1 -1
- package/dist/components/SidebarItem/SidebarEnvironmentItem.js +34 -5
- package/dist/components/SidebarItem/SidebarHistoryItem.d.ts +5 -1
- package/dist/components/SidebarItem/SidebarHistoryItem.d.ts.map +1 -1
- package/dist/components/SidebarItem/SidebarHistoryItem.js +2 -2
- package/dist/components/SidebarItem/SidebarWorkspaceItem.d.ts +9 -1
- package/dist/components/SidebarItem/SidebarWorkspaceItem.d.ts.map +1 -1
- package/dist/components/SidebarItem/SidebarWorkspaceItem.js +15 -2
- package/dist/components/TabBar/TabContextMenu.d.ts +3 -0
- package/dist/components/TabBar/TabContextMenu.d.ts.map +1 -1
- package/dist/components/TabBar/TabContextMenu.js +25 -16
- package/dist/components/VariableTable/index.d.ts +1 -1
- package/dist/components/VariableTable/index.d.ts.map +1 -1
- package/dist/components/VariableTable/index.js +14 -3
- package/dist/components/index.d.ts +6 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -1
- package/dist/runtime/createBridgedPluginContext.js +240 -2
- package/dist/snippets.d.ts +48 -2
- package/dist/styles.css +16 -0
- package/dist/types.d.ts +1159 -30
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -0
- package/package.json +1 -1
- package/dist/components/SelectionActionToolbar/index.d.ts +0 -41
- package/dist/components/SelectionActionToolbar/index.d.ts.map +0 -1
- package/dist/components/SelectionActionToolbar/index.js +0 -13
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from '@harborclient/sdk/react';
|
|
3
|
+
import { cn } from '../utils.js';
|
|
4
|
+
import { FLOATING_DIALOG_DEFAULT_LEFT, FLOATING_DIALOG_DEFAULT_TOP, FLOATING_DIALOG_VIEWPORT_MARGIN_PX, isFloatingDialogFullyOnScreen } from './floatingDialogPosition.js';
|
|
5
|
+
/**
|
|
6
|
+
* Clamps a proposed size into min/max and remaining viewport space.
|
|
7
|
+
*
|
|
8
|
+
* @param width - Proposed width.
|
|
9
|
+
* @param height - Proposed height.
|
|
10
|
+
* @param left - Current panel left.
|
|
11
|
+
* @param top - Current panel top.
|
|
12
|
+
* @param minWidth - Minimum width.
|
|
13
|
+
* @param minHeight - Minimum height.
|
|
14
|
+
* @param maxWidth - Optional max width cap.
|
|
15
|
+
* @param maxHeight - Optional max height cap.
|
|
16
|
+
* @returns Clamped size.
|
|
17
|
+
*/
|
|
18
|
+
function clampFloatingDialogSize(width, height, left, top, minWidth, minHeight, maxWidth, maxHeight) {
|
|
19
|
+
const margin = FLOATING_DIALOG_VIEWPORT_MARGIN_PX;
|
|
20
|
+
const viewportWidth = typeof window !== 'undefined' ? window.innerWidth : width;
|
|
21
|
+
const viewportHeight = typeof window !== 'undefined' ? window.innerHeight : height;
|
|
22
|
+
const roomWidth = Math.max(minWidth, viewportWidth - left - margin);
|
|
23
|
+
const roomHeight = Math.max(minHeight, viewportHeight - top - margin);
|
|
24
|
+
const widthCap = maxWidth != null ? Math.min(maxWidth, roomWidth) : roomWidth;
|
|
25
|
+
const heightCap = maxHeight != null ? Math.min(maxHeight, roomHeight) : roomHeight;
|
|
26
|
+
return {
|
|
27
|
+
width: Math.min(Math.max(width, minWidth), widthCap),
|
|
28
|
+
height: Math.min(Math.max(height, minHeight), heightCap)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Non-blocking, draggable dialog panel with no modal mask.
|
|
33
|
+
*
|
|
34
|
+
* Clicks pass through to the UI behind the panel. Drag by the handle region.
|
|
35
|
+
* When `initialWidth` and `initialHeight` are provided, a southeast resize
|
|
36
|
+
* handle appears (pointer + arrow-key accessible). Parents persist geometry via
|
|
37
|
+
* `onPositionChange` / `onSizeChange`. If the panel would open or remain
|
|
38
|
+
* off-screen after a window resize, it relocates to the default corner.
|
|
39
|
+
*
|
|
40
|
+
* @param props - Dialog labelling, geometry, and content props.
|
|
41
|
+
* @returns Floating dialog element.
|
|
42
|
+
*/
|
|
43
|
+
export function FloatingDialog({ label, labelledBy, onClose, disableEscape = false, className, bodyClassName, initialLeft = FLOATING_DIALOG_DEFAULT_LEFT, initialTop = FLOATING_DIALOG_DEFAULT_TOP, onPositionChange, initialWidth, initialHeight, minWidth = 240, minHeight = 120, maxWidth, maxHeight, onSizeChange, dragHandle, children }) {
|
|
44
|
+
const resizable = initialWidth != null && initialHeight != null;
|
|
45
|
+
const panelRef = useRef(null);
|
|
46
|
+
const [position, setPosition] = useState({
|
|
47
|
+
left: initialLeft,
|
|
48
|
+
top: initialTop
|
|
49
|
+
});
|
|
50
|
+
const [size, setSize] = useState(() => resizable
|
|
51
|
+
? clampFloatingDialogSize(initialWidth, initialHeight, initialLeft, initialTop, minWidth, minHeight, maxWidth, maxHeight)
|
|
52
|
+
: null);
|
|
53
|
+
const positionRef = useRef(position);
|
|
54
|
+
const sizeRef = useRef(size);
|
|
55
|
+
const onPositionChangeRef = useRef(onPositionChange);
|
|
56
|
+
const onSizeChangeRef = useRef(onSizeChange);
|
|
57
|
+
const dragStateRef = useRef(null);
|
|
58
|
+
const resizeStateRef = useRef(null);
|
|
59
|
+
/**
|
|
60
|
+
* Keeps the latest position available to resize handlers without rebinding.
|
|
61
|
+
*/
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
positionRef.current = position;
|
|
64
|
+
}, [position]);
|
|
65
|
+
/**
|
|
66
|
+
* Keeps the latest size available to relocate / resize handlers.
|
|
67
|
+
*/
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
sizeRef.current = size;
|
|
70
|
+
}, [size]);
|
|
71
|
+
/**
|
|
72
|
+
* Keeps the latest position-change callback available to layout/resize handlers.
|
|
73
|
+
*/
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
onPositionChangeRef.current = onPositionChange;
|
|
76
|
+
}, [onPositionChange]);
|
|
77
|
+
/**
|
|
78
|
+
* Keeps the latest size-change callback available to resize handlers.
|
|
79
|
+
*/
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
onSizeChangeRef.current = onSizeChange;
|
|
82
|
+
}, [onSizeChange]);
|
|
83
|
+
/**
|
|
84
|
+
* Moves the panel to the default corner when it would sit outside the viewport.
|
|
85
|
+
*/
|
|
86
|
+
const relocateToCornerIfOffScreen = useCallback(() => {
|
|
87
|
+
const panel = panelRef.current;
|
|
88
|
+
if (panel == null) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const measured = sizeRef.current ?? {
|
|
92
|
+
width: panel.offsetWidth,
|
|
93
|
+
height: panel.offsetHeight
|
|
94
|
+
};
|
|
95
|
+
const current = positionRef.current;
|
|
96
|
+
if (isFloatingDialogFullyOnScreen(current, measured)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const corner = {
|
|
100
|
+
left: FLOATING_DIALOG_DEFAULT_LEFT,
|
|
101
|
+
top: FLOATING_DIALOG_DEFAULT_TOP
|
|
102
|
+
};
|
|
103
|
+
positionRef.current = corner;
|
|
104
|
+
setPosition(corner);
|
|
105
|
+
onPositionChangeRef.current?.(corner);
|
|
106
|
+
}, []);
|
|
107
|
+
/**
|
|
108
|
+
* After first paint and whenever the window resizes, relocates only when off-screen.
|
|
109
|
+
*/
|
|
110
|
+
useLayoutEffect(() => {
|
|
111
|
+
relocateToCornerIfOffScreen();
|
|
112
|
+
window.addEventListener('resize', relocateToCornerIfOffScreen);
|
|
113
|
+
return () => window.removeEventListener('resize', relocateToCornerIfOffScreen);
|
|
114
|
+
}, [relocateToCornerIfOffScreen]);
|
|
115
|
+
/**
|
|
116
|
+
* Closes the dialog when Escape is pressed unless disabled.
|
|
117
|
+
*/
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (disableEscape) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Dismisses the floating dialog on Escape.
|
|
124
|
+
*
|
|
125
|
+
* @param event - Keyboard event.
|
|
126
|
+
*/
|
|
127
|
+
const handleKeyDown = (event) => {
|
|
128
|
+
if (event.key === 'Escape') {
|
|
129
|
+
onClose();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
133
|
+
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
134
|
+
}, [disableEscape, onClose]);
|
|
135
|
+
/**
|
|
136
|
+
* Begins a pointer drag from the header handle.
|
|
137
|
+
*
|
|
138
|
+
* @param event - Pointer down event on the drag handle.
|
|
139
|
+
*/
|
|
140
|
+
const handlePointerDown = useCallback((event) => {
|
|
141
|
+
if (event.button !== 0) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
145
|
+
dragStateRef.current = {
|
|
146
|
+
pointerId: event.pointerId,
|
|
147
|
+
originX: event.clientX,
|
|
148
|
+
originY: event.clientY,
|
|
149
|
+
startLeft: position.left,
|
|
150
|
+
startTop: position.top
|
|
151
|
+
};
|
|
152
|
+
}, [position.left, position.top]);
|
|
153
|
+
/**
|
|
154
|
+
* Updates panel position while dragging.
|
|
155
|
+
*
|
|
156
|
+
* @param event - Pointer move event.
|
|
157
|
+
*/
|
|
158
|
+
const handlePointerMove = useCallback((event) => {
|
|
159
|
+
const drag = dragStateRef.current;
|
|
160
|
+
if (drag == null || drag.pointerId !== event.pointerId) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const next = {
|
|
164
|
+
left: Math.max(FLOATING_DIALOG_VIEWPORT_MARGIN_PX, drag.startLeft + (event.clientX - drag.originX)),
|
|
165
|
+
top: Math.max(FLOATING_DIALOG_VIEWPORT_MARGIN_PX, drag.startTop + (event.clientY - drag.originY))
|
|
166
|
+
};
|
|
167
|
+
positionRef.current = next;
|
|
168
|
+
setPosition(next);
|
|
169
|
+
}, []);
|
|
170
|
+
/**
|
|
171
|
+
* Ends an active pointer drag and notifies the parent of the final position.
|
|
172
|
+
*
|
|
173
|
+
* @param event - Pointer up/cancel event.
|
|
174
|
+
*/
|
|
175
|
+
const handlePointerUp = useCallback((event) => {
|
|
176
|
+
const drag = dragStateRef.current;
|
|
177
|
+
if (drag == null || drag.pointerId !== event.pointerId) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
dragStateRef.current = null;
|
|
181
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
182
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
183
|
+
}
|
|
184
|
+
onPositionChangeRef.current?.(positionRef.current);
|
|
185
|
+
}, []);
|
|
186
|
+
/**
|
|
187
|
+
* Begins a southeast resize from the resize handle.
|
|
188
|
+
*
|
|
189
|
+
* @param event - Pointer down on the resize handle.
|
|
190
|
+
*/
|
|
191
|
+
const handleResizePointerDown = useCallback((event) => {
|
|
192
|
+
if (!resizable || size == null || event.button !== 0) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
event.stopPropagation();
|
|
196
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
197
|
+
resizeStateRef.current = {
|
|
198
|
+
pointerId: event.pointerId,
|
|
199
|
+
originX: event.clientX,
|
|
200
|
+
originY: event.clientY,
|
|
201
|
+
startWidth: size.width,
|
|
202
|
+
startHeight: size.height
|
|
203
|
+
};
|
|
204
|
+
}, [resizable, size]);
|
|
205
|
+
/**
|
|
206
|
+
* Updates panel size while resizing from the SE handle.
|
|
207
|
+
*
|
|
208
|
+
* @param event - Pointer move on the resize handle.
|
|
209
|
+
*/
|
|
210
|
+
const handleResizePointerMove = useCallback((event) => {
|
|
211
|
+
const resize = resizeStateRef.current;
|
|
212
|
+
if (resize == null || resize.pointerId !== event.pointerId) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const next = clampFloatingDialogSize(resize.startWidth + (event.clientX - resize.originX), resize.startHeight + (event.clientY - resize.originY), positionRef.current.left, positionRef.current.top, minWidth, minHeight, maxWidth, maxHeight);
|
|
216
|
+
sizeRef.current = next;
|
|
217
|
+
setSize(next);
|
|
218
|
+
}, [maxHeight, maxWidth, minHeight, minWidth]);
|
|
219
|
+
/**
|
|
220
|
+
* Ends an active resize and notifies the parent of the final size.
|
|
221
|
+
*
|
|
222
|
+
* @param event - Pointer up/cancel on the resize handle.
|
|
223
|
+
*/
|
|
224
|
+
const handleResizePointerUp = useCallback((event) => {
|
|
225
|
+
const resize = resizeStateRef.current;
|
|
226
|
+
if (resize == null || resize.pointerId !== event.pointerId) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
resizeStateRef.current = null;
|
|
230
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) {
|
|
231
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
232
|
+
}
|
|
233
|
+
if (sizeRef.current != null) {
|
|
234
|
+
onSizeChangeRef.current?.(sizeRef.current);
|
|
235
|
+
}
|
|
236
|
+
}, []);
|
|
237
|
+
/**
|
|
238
|
+
* Adjusts size with arrow keys when the resize handle is focused.
|
|
239
|
+
*
|
|
240
|
+
* @param event - Keyboard event on the resize handle.
|
|
241
|
+
*/
|
|
242
|
+
const handleResizeKeyDown = useCallback((event) => {
|
|
243
|
+
if (size == null) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const step = event.shiftKey ? 24 : 8;
|
|
247
|
+
let deltaW = 0;
|
|
248
|
+
let deltaH = 0;
|
|
249
|
+
if (event.key === 'ArrowRight') {
|
|
250
|
+
deltaW = step;
|
|
251
|
+
}
|
|
252
|
+
else if (event.key === 'ArrowLeft') {
|
|
253
|
+
deltaW = -step;
|
|
254
|
+
}
|
|
255
|
+
else if (event.key === 'ArrowDown') {
|
|
256
|
+
deltaH = step;
|
|
257
|
+
}
|
|
258
|
+
else if (event.key === 'ArrowUp') {
|
|
259
|
+
deltaH = -step;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
event.preventDefault();
|
|
265
|
+
const next = clampFloatingDialogSize(size.width + deltaW, size.height + deltaH, positionRef.current.left, positionRef.current.top, minWidth, minHeight, maxWidth, maxHeight);
|
|
266
|
+
sizeRef.current = next;
|
|
267
|
+
setSize(next);
|
|
268
|
+
onSizeChangeRef.current?.(next);
|
|
269
|
+
}, [maxHeight, maxWidth, minHeight, minWidth, size]);
|
|
270
|
+
return (_jsxs("div", { ref: panelRef, role: "dialog", "aria-modal": "false", "aria-label": labelledBy ? undefined : label, "aria-labelledby": labelledBy, className: cn('hc-floating-dialog fixed z-[60] flex min-w-[240px] flex-col overflow-hidden rounded-lg border border-separator bg-surface shadow-xl', className), style: {
|
|
271
|
+
left: position.left,
|
|
272
|
+
top: position.top,
|
|
273
|
+
...(size != null ? { width: size.width, height: size.height } : {})
|
|
274
|
+
}, children: [_jsx("div", { className: "hc-floating-dialog-handle shrink-0 cursor-grab touch-none active:cursor-grabbing", onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerCancel: handlePointerUp, children: dragHandle }), _jsx("div", { className: cn('hc-floating-dialog-body min-h-0 flex-1 overflow-auto p-3', bodyClassName), children: children }), resizable ? (_jsx("button", { type: "button", "aria-label": "Resize dialog", className: "absolute right-0 bottom-0 h-4 w-4 cursor-se-resize border-0 bg-transparent p-0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent", onPointerDown: handleResizePointerDown, onPointerMove: handleResizePointerMove, onPointerUp: handleResizePointerUp, onPointerCancel: handleResizePointerUp, onKeyDown: handleResizeKeyDown, children: _jsx("span", { className: "pointer-events-none absolute right-1 bottom-1 h-2 w-2 border-r-2 border-b-2 border-muted", "aria-hidden": true }) })) : null] }));
|
|
275
|
+
}
|
|
@@ -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;
|
|
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"}
|
|
@@ -2,21 +2,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
|
2
2
|
import { useId } from '@harborclient/sdk/react';
|
|
3
3
|
import { FieldError } from '../FieldError/index.js';
|
|
4
4
|
import { enhanceControl } from '../enhanceControl.js';
|
|
5
|
-
/**
|
|
6
|
-
* Returns Tailwind classes for the label text based on tone and visibility.
|
|
7
|
-
*
|
|
8
|
-
* @returns Class string for the label element.
|
|
9
|
-
*/
|
|
10
5
|
/**
|
|
11
6
|
* Returns wrapper classes for bordered stacked, checkbox, and inline layouts.
|
|
12
7
|
*
|
|
13
8
|
* @param bordered - Whether the default border and padding should be applied.
|
|
14
9
|
* @param layoutClasses - Layout-specific flex and sizing classes.
|
|
15
10
|
* @param extra - Caller-supplied className override.
|
|
11
|
+
* @param modified - When true with `bordered`, adds a left unsaved-tab color border.
|
|
16
12
|
*/
|
|
17
|
-
function borderedWrapperClasses(bordered, layoutClasses, extra) {
|
|
13
|
+
function borderedWrapperClasses(bordered, layoutClasses, extra, modified = false) {
|
|
18
14
|
const frame = bordered ? 'p-4 border border-separator rounded-md' : '';
|
|
19
|
-
const
|
|
15
|
+
const accent = bordered && modified ? 'border-l-2 border-l-[var(--color-tab-unsaved)]' : '';
|
|
16
|
+
const base = `hc-form-group ${layoutClasses} ${frame} ${accent}`.trim();
|
|
20
17
|
return extra ? `${base} ${extra}` : base;
|
|
21
18
|
}
|
|
22
19
|
/**
|
|
@@ -39,7 +36,7 @@ function labelClasses(tone, srOnly, inline) {
|
|
|
39
36
|
* Supports stacked fields, checkboxes, inline rows, radio options, and
|
|
40
37
|
* adjacent checkbox rows used in list pickers.
|
|
41
38
|
*/
|
|
42
|
-
export function FormGroup({ label, children, htmlFor, description, error, errorId, descriptionId, layout = 'stacked', labelTone = 'default', srOnly = false, className, labelClassName, bordered = true, ...props }) {
|
|
39
|
+
export function FormGroup({ label, children, htmlFor, description, error, errorId, descriptionId, layout = 'stacked', labelTone = 'default', srOnly = false, className, labelClassName, bordered = true, modified = false, ...props }) {
|
|
43
40
|
const generatedId = useId();
|
|
44
41
|
const controlId = htmlFor ?? generatedId;
|
|
45
42
|
const extra = className ?? '';
|
|
@@ -78,11 +75,11 @@ export function FormGroup({ label, children, htmlFor, description, error, errorI
|
|
|
78
75
|
id: controlId,
|
|
79
76
|
invalid: resolvedErrorId != null
|
|
80
77
|
});
|
|
81
|
-
const wrapperClasses = borderedWrapperClasses(bordered, 'flex flex-col gap-1', extra);
|
|
78
|
+
const wrapperClasses = borderedWrapperClasses(bordered, 'flex flex-col gap-1', extra, modified);
|
|
82
79
|
return (_jsxs("div", { ...props, className: wrapperClasses, children: [_jsxs("label", { htmlFor: controlId, className: "hc-form-group-label flex flex-col gap-1", children: [_jsxs("span", { className: "hc-form-group-label-row flex items-center gap-2", children: [linkedChildren, _jsx("span", { className: labelClasses(labelTone, srOnly, false), children: label })] }), resolvedDescriptionId ? (_jsx("p", { id: resolvedDescriptionId, className: "hc-form-group-description m-0 pl-[26px] text-[14px] text-muted", children: description })) : null] }), resolvedErrorId ? (_jsx(FieldError, { id: resolvedErrorId, spacing: "field", children: error })) : null] }));
|
|
83
80
|
}
|
|
84
81
|
if (layout === 'inline') {
|
|
85
|
-
const wrapperClasses = borderedWrapperClasses(bordered, 'flex min-w-0 flex-1 items-center gap-2', extra);
|
|
82
|
+
const wrapperClasses = borderedWrapperClasses(bordered, 'flex min-w-0 flex-1 items-center gap-2', extra, modified);
|
|
86
83
|
const linkedChildren = enhanceControl(children, { id: controlId });
|
|
87
84
|
return (_jsxs("label", { htmlFor: controlId, className: wrapperClasses, children: [_jsx("span", { className: labelClasses(labelTone, srOnly, true), children: label }), linkedChildren] }));
|
|
88
85
|
}
|
|
@@ -97,6 +94,6 @@ export function FormGroup({ label, children, htmlFor, description, error, errorI
|
|
|
97
94
|
invalid: resolvedErrorId != null,
|
|
98
95
|
id: htmlFor
|
|
99
96
|
});
|
|
100
|
-
const wrapperClasses = borderedWrapperClasses(bordered, 'flex flex-col gap-1', extra);
|
|
97
|
+
const wrapperClasses = borderedWrapperClasses(bordered, 'flex flex-col gap-1', extra, modified);
|
|
101
98
|
return (_jsxs("div", { ...props, className: wrapperClasses, children: [_jsxs("label", { htmlFor: htmlFor, className: "hc-form-group-label flex flex-col gap-1", children: [_jsx("span", { className: labelClasses(labelTone, srOnly, false), children: label }), resolvedDescriptionId ? (_jsx("p", { id: resolvedDescriptionId, className: "hc-form-group-description m-0 text-[14px] text-muted", children: description })) : null, control] }), resolvedErrorId ? (_jsx(FieldError, { id: resolvedErrorId, spacing: "field", children: error })) : null] }));
|
|
102
99
|
}
|
|
@@ -20,7 +20,8 @@ interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {
|
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* Full-bleed page header with a bordered bottom edge, title block on the left,
|
|
23
|
-
* and optional action controls on the right.
|
|
23
|
+
* and optional action controls on the right. Sticks to the top of its nearest
|
|
24
|
+
* scroll ancestor so title and actions stay visible while page content scrolls.
|
|
24
25
|
*/
|
|
25
26
|
export declare function PageHeader({ title, description, icon, children, className, ...props }: Props): JSX.Element;
|
|
26
27
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PageHeader/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACvE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PageHeader/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACvE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA6BrB"}
|
|
@@ -3,8 +3,9 @@ import { FaIcon } from '../FaIcon/index.js';
|
|
|
3
3
|
import { cn } from '../utils.js';
|
|
4
4
|
/**
|
|
5
5
|
* Full-bleed page header with a bordered bottom edge, title block on the left,
|
|
6
|
-
* and optional action controls on the right.
|
|
6
|
+
* and optional action controls on the right. Sticks to the top of its nearest
|
|
7
|
+
* scroll ancestor so title and actions stay visible while page content scrolls.
|
|
7
8
|
*/
|
|
8
9
|
export function PageHeader({ title, description, icon, children, className, ...props }) {
|
|
9
|
-
return (_jsxs("div", { ...props, className: cn('hc-page-header -mx-6 mb-4 flex flex-wrap items-center gap-2 border-b border-separator px-6 py-4', className), children: [_jsxs("div", { className: "hc-page-header-content min-w-0 flex-1", children: [_jsxs("h2", { className: "hc-page-header-title m-0 flex items-center gap-2 text-[22px] leading-[1.15] font-bold tracking-[-0.01em] text-text", children: [icon ? (_jsx(FaIcon, { icon: icon, className: "hc-page-header-title-icon h-4 w-4 shrink-0 text-muted", "aria-hidden": true })) : null, title] }), description ? (_jsx("p", { className: "hc-page-header-description m-0 mt-1 leading-6 text-muted", children: description })) : null] }), children ? (_jsx("div", { className: "hc-page-header-actions flex flex-wrap items-center gap-2", children: children })) : null] }));
|
|
10
|
+
return (_jsxs("div", { ...props, className: cn('hc-page-header sticky top-0 z-10 -mx-6 mb-4 flex flex-wrap items-center gap-2 border-b border-separator bg-surface px-6 py-4', className), children: [_jsxs("div", { className: "hc-page-header-content min-w-0 flex-1", children: [_jsxs("h2", { className: "hc-page-header-title m-0 flex items-center gap-2 text-[22px] leading-[1.15] font-bold tracking-[-0.01em] text-text", children: [icon ? (_jsx(FaIcon, { icon: icon, className: "hc-page-header-title-icon h-4 w-4 shrink-0 text-muted", "aria-hidden": true })) : null, title] }), description ? (_jsx("p", { className: "hc-page-header-description m-0 mt-1 leading-6 text-muted", children: description })) : null] }), children ? (_jsx("div", { className: "hc-page-header-actions flex flex-wrap items-center gap-2", children: children })) : null] }));
|
|
10
11
|
}
|
|
@@ -37,6 +37,7 @@ interface Props<T extends string> extends Omit<ComponentPropsWithoutRef<'nav'>,
|
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* Narrow sidebar navigation for multi-section pages such as settings overlays.
|
|
40
|
+
* Row chrome matches collections sidebar items via {@link sourceRow}.
|
|
40
41
|
*/
|
|
41
42
|
export declare function PageSidebar<T extends string>({ items, selected, onSelect, ariaLabel, className, ...props }: Props<T>): JSX.Element;
|
|
42
43
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PageSidebar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PageSidebar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAK3D;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACxD;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAED,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,IAAI,CAC5C,wBAAwB,CAAC,KAAK,CAAC,EAC/B,YAAY,GAAG,UAAU,CAC1B;IACC;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5B;;OAEG;IACH,QAAQ,EAAE,CAAC,CAAC;IAEZ;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAE7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EAC5C,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAuCxB"}
|
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
2
|
import { FaIcon } from '../FaIcon/index.js';
|
|
3
|
+
import { sourceRow } from '../SidebarItem/sidebarItemClasses.js';
|
|
3
4
|
import { cn } from '../utils.js';
|
|
4
|
-
/**
|
|
5
|
-
* Tailwind classes for a sidebar navigation row.
|
|
6
|
-
*/
|
|
7
|
-
function sidebarRow(active) {
|
|
8
|
-
return active
|
|
9
|
-
? 'group flex cursor-pointer items-center gap-1 rounded-md bg-selection px-1.5 py-2 app-no-drag'
|
|
10
|
-
: 'group flex cursor-pointer items-center gap-1 rounded-md px-1.5 py-2 hover:bg-selection/60 app-no-drag';
|
|
11
|
-
}
|
|
12
5
|
/**
|
|
13
6
|
* Narrow sidebar navigation for multi-section pages such as settings overlays.
|
|
7
|
+
* Row chrome matches collections sidebar items via {@link sourceRow}.
|
|
14
8
|
*/
|
|
15
9
|
export function PageSidebar({ items, selected, onSelect, ariaLabel, className, ...props }) {
|
|
16
|
-
return (_jsx("nav", { ...props, className: cn('hc-page-sidebar flex w-[220px] shrink-0 flex-col gap-
|
|
10
|
+
return (_jsx("nav", { ...props, className: cn('hc-page-sidebar flex w-[220px] shrink-0 flex-col gap-0 border-r border-separator bg-sidebar px-2 py-3', className), "aria-label": ariaLabel, children: items.map((item) => {
|
|
17
11
|
const active = selected === item.value;
|
|
18
|
-
|
|
19
|
-
? `hc-page-sidebar-item ${sidebarRow(active)} w-full gap-2 border-none text-left text-[15px] app-no-drag`
|
|
20
|
-
: `hc-page-sidebar-item ${sidebarRow(active)} w-full border-none text-left text-[15px] app-no-drag`;
|
|
21
|
-
return (_jsxs("button", { type: "button", className: rowClass, "aria-current": active ? 'page' : undefined, onClick: () => onSelect(item.value), children: [item.icon ? (_jsx(FaIcon, { icon: item.icon, className: cn('hc-page-sidebar-item-icon h-[18px] w-[18px] shrink-0', active ? 'text-text' : 'text-muted'), "aria-hidden": true })) : null, _jsx("span", { className: "hc-page-sidebar-item-label min-w-0 truncate", children: item.label })] }, item.value));
|
|
12
|
+
return (_jsxs("button", { type: "button", className: cn('hc-sidebar-item hc-page-sidebar-item', sourceRow(active, true), 'min-h-[30px] w-full cursor-pointer border-none text-left text-inherit', item.icon && 'gap-2'), "aria-current": active ? 'page' : undefined, onClick: () => onSelect(item.value), children: [item.icon ? (_jsx(FaIcon, { icon: item.icon, className: "hc-page-sidebar-item-icon h-3.5 w-3.5 shrink-0 text-muted", "aria-hidden": true })) : null, _jsx("span", { className: "hc-page-sidebar-item-label min-w-0 truncate", children: item.label })] }, item.value));
|
|
22
13
|
}) }));
|
|
23
14
|
}
|
|
@@ -39,5 +39,11 @@ export interface UseResizableResult {
|
|
|
39
39
|
onResizeStart: (event: ReactMouseEvent) => void;
|
|
40
40
|
onKeyboardResize: (event: ReactKeyboardEvent) => void;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Tracks resizable panel size with pointer drag and optional persistence.
|
|
44
|
+
*
|
|
45
|
+
* During drag, pointer movement sets a target size; the displayed size eases
|
|
46
|
+
* toward that target each frame unless the user prefers reduced motion.
|
|
47
|
+
*/
|
|
42
48
|
export declare function useResizable({ axis, direction, defaultSize, minSize, getMaxSize, storageKey, onPersist }: UseResizableOptions): UseResizableResult;
|
|
43
49
|
//# sourceMappingURL=useResizable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useResizable.d.ts","sourceRoot":"","sources":["../../../src/components/Resizable/useResizable.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,IAAI,kBAAkB,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,OAAO,CAAC;AAGhG,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErF,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"useResizable.d.ts","sourceRoot":"","sources":["../../../src/components/Resizable/useResizable.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,IAAI,kBAAkB,EAAE,UAAU,IAAI,eAAe,EAAE,MAAM,OAAO,CAAC;AAGhG,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErF,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAyEtB,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;OAEG;IACH,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;IAE1B;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,aAAa,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,gBAAgB,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAiED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,SAAS,EACT,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,SAAS,EACV,EAAE,mBAAmB,GAAG,kBAAkB,CA8P1C"}
|