@harborclient/sdk 0.4.6 → 0.5.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 (178) hide show
  1. package/dist/components/AsyncListState/index.d.ts +85 -0
  2. package/dist/components/AsyncListState/index.d.ts.map +1 -0
  3. package/dist/components/AsyncListState/index.js +51 -0
  4. package/dist/components/BackButton/index.d.ts +32 -0
  5. package/dist/components/BackButton/index.d.ts.map +1 -0
  6. package/dist/components/BackButton/index.js +19 -0
  7. package/dist/components/Badge/index.d.ts +29 -0
  8. package/dist/components/Badge/index.d.ts.map +1 -0
  9. package/dist/components/Badge/index.js +32 -0
  10. package/dist/components/BusyIndicator/index.d.ts +16 -0
  11. package/dist/components/BusyIndicator/index.d.ts.map +1 -0
  12. package/dist/components/BusyIndicator/index.js +78 -0
  13. package/dist/components/Button/index.d.ts +29 -0
  14. package/dist/components/Button/index.d.ts.map +1 -0
  15. package/dist/components/Button/index.js +25 -0
  16. package/dist/components/CodeEditor/config.d.ts +51 -0
  17. package/dist/components/CodeEditor/config.d.ts.map +1 -0
  18. package/dist/components/CodeEditor/config.js +64 -0
  19. package/dist/components/CodeEditor/index.d.ts +77 -0
  20. package/dist/components/CodeEditor/index.d.ts.map +1 -0
  21. package/dist/components/CodeEditor/index.js +319 -0
  22. package/dist/components/CodeEditor/themes.d.ts +19 -0
  23. package/dist/components/CodeEditor/themes.d.ts.map +1 -0
  24. package/dist/components/CodeEditor/themes.js +37 -0
  25. package/dist/components/EmptyState/index.d.ts +26 -0
  26. package/dist/components/EmptyState/index.d.ts.map +1 -0
  27. package/dist/components/EmptyState/index.js +25 -0
  28. package/dist/components/FaIcon/index.d.ts +22 -0
  29. package/dist/components/FaIcon/index.d.ts.map +1 -0
  30. package/dist/components/FaIcon/index.js +13 -0
  31. package/dist/components/FieldError/index.d.ts +39 -0
  32. package/dist/components/FieldError/index.d.ts.map +1 -0
  33. package/dist/components/FieldError/index.js +34 -0
  34. package/dist/components/FooterButton/index.d.ts +30 -0
  35. package/dist/components/FooterButton/index.d.ts.map +1 -0
  36. package/dist/components/FooterButton/index.js +19 -0
  37. package/dist/components/FooterIcon/index.d.ts +32 -0
  38. package/dist/components/FooterIcon/index.d.ts.map +1 -0
  39. package/dist/components/FooterIcon/index.js +21 -0
  40. package/dist/components/FormDataEditor/index.d.ts +31 -0
  41. package/dist/components/FormDataEditor/index.d.ts.map +1 -0
  42. package/dist/components/FormDataEditor/index.js +109 -0
  43. package/dist/components/FormGroup/index.d.ts +75 -0
  44. package/dist/components/FormGroup/index.d.ts.map +1 -0
  45. package/dist/components/FormGroup/index.js +95 -0
  46. package/dist/components/KeyValueEditor/index.d.ts +35 -0
  47. package/dist/components/KeyValueEditor/index.d.ts.map +1 -0
  48. package/dist/components/KeyValueEditor/index.js +40 -0
  49. package/dist/components/MethodSelect/index.d.ts +20 -0
  50. package/dist/components/MethodSelect/index.d.ts.map +1 -0
  51. package/dist/components/MethodSelect/index.js +9 -0
  52. package/dist/components/Modal/ModalFooter.d.ts +25 -0
  53. package/dist/components/Modal/ModalFooter.d.ts.map +1 -0
  54. package/dist/components/Modal/ModalFooter.js +13 -0
  55. package/dist/components/Modal/ModalFormLayout.d.ts +31 -0
  56. package/dist/components/Modal/ModalFormLayout.d.ts.map +1 -0
  57. package/dist/components/Modal/ModalFormLayout.js +14 -0
  58. package/dist/components/Modal/ModalHeader.d.ts +34 -0
  59. package/dist/components/Modal/ModalHeader.d.ts.map +1 -0
  60. package/dist/components/Modal/ModalHeader.js +11 -0
  61. package/dist/components/Modal/index.d.ts +59 -0
  62. package/dist/components/Modal/index.d.ts.map +1 -0
  63. package/dist/components/Modal/index.js +37 -0
  64. package/dist/components/OverlayCloseButton/index.d.ts +25 -0
  65. package/dist/components/OverlayCloseButton/index.d.ts.map +1 -0
  66. package/dist/components/OverlayCloseButton/index.js +16 -0
  67. package/dist/components/OverlayPage/index.d.ts +40 -0
  68. package/dist/components/OverlayPage/index.d.ts.map +1 -0
  69. package/dist/components/OverlayPage/index.js +18 -0
  70. package/dist/components/PageHeader/index.d.ts +31 -0
  71. package/dist/components/PageHeader/index.d.ts.map +1 -0
  72. package/dist/components/PageHeader/index.js +12 -0
  73. package/dist/components/PanelCloseButton/index.d.ts +30 -0
  74. package/dist/components/PanelCloseButton/index.d.ts.map +1 -0
  75. package/dist/components/PanelCloseButton/index.js +17 -0
  76. package/dist/components/Resizable/Resizable.d.ts +48 -0
  77. package/dist/components/Resizable/Resizable.d.ts.map +1 -0
  78. package/dist/components/Resizable/Resizable.js +32 -0
  79. package/dist/components/Resizable/ResizeHandle.d.ts +41 -0
  80. package/dist/components/Resizable/ResizeHandle.d.ts.map +1 -0
  81. package/dist/components/Resizable/ResizeHandle.js +17 -0
  82. package/dist/components/Resizable/footerPanelUtils.d.ts +25 -0
  83. package/dist/components/Resizable/footerPanelUtils.d.ts.map +1 -0
  84. package/dist/components/Resizable/footerPanelUtils.js +59 -0
  85. package/dist/components/Resizable/index.d.ts +4 -0
  86. package/dist/components/Resizable/index.d.ts.map +1 -0
  87. package/dist/components/Resizable/index.js +3 -0
  88. package/dist/components/Resizable/useResizable.d.ts +42 -0
  89. package/dist/components/Resizable/useResizable.d.ts.map +1 -0
  90. package/dist/components/Resizable/useResizable.js +151 -0
  91. package/dist/components/ResourceList/index.d.ts +73 -0
  92. package/dist/components/ResourceList/index.d.ts.map +1 -0
  93. package/dist/components/ResourceList/index.js +44 -0
  94. package/dist/components/RowActionsMenu/index.d.ts +33 -0
  95. package/dist/components/RowActionsMenu/index.d.ts.map +1 -0
  96. package/dist/components/RowActionsMenu/index.js +54 -0
  97. package/dist/components/SegmentedTabs/index.d.ts +107 -0
  98. package/dist/components/SegmentedTabs/index.d.ts.map +1 -0
  99. package/dist/components/SegmentedTabs/index.js +111 -0
  100. package/dist/components/Spinner/index.d.ts +26 -0
  101. package/dist/components/Spinner/index.d.ts.map +1 -0
  102. package/dist/components/Spinner/index.js +22 -0
  103. package/dist/components/StatusMessage/index.d.ts +29 -0
  104. package/dist/components/StatusMessage/index.d.ts.map +1 -0
  105. package/dist/components/StatusMessage/index.js +13 -0
  106. package/dist/components/TabCloseButton/index.d.ts +25 -0
  107. package/dist/components/TabCloseButton/index.d.ts.map +1 -0
  108. package/dist/components/TabCloseButton/index.js +13 -0
  109. package/dist/components/VariableInput/index.d.ts +58 -0
  110. package/dist/components/VariableInput/index.d.ts.map +1 -0
  111. package/dist/components/VariableInput/index.js +90 -0
  112. package/dist/components/VariableTable/index.d.ts +22 -0
  113. package/dist/components/VariableTable/index.d.ts.map +1 -0
  114. package/dist/components/VariableTable/index.js +43 -0
  115. package/dist/components/classes.d.ts +11 -0
  116. package/dist/components/classes.d.ts.map +1 -0
  117. package/dist/components/classes.js +14 -0
  118. package/dist/components/forms/Input.d.ts +22 -0
  119. package/dist/components/forms/Input.d.ts.map +1 -0
  120. package/dist/components/forms/Input.js +9 -0
  121. package/dist/components/forms/Select.d.ts +24 -0
  122. package/dist/components/forms/Select.d.ts.map +1 -0
  123. package/dist/components/forms/Select.js +10 -0
  124. package/dist/components/forms/Textarea.d.ts +22 -0
  125. package/dist/components/forms/Textarea.d.ts.map +1 -0
  126. package/dist/components/forms/Textarea.js +8 -0
  127. package/dist/components/forms/classes.d.ts +24 -0
  128. package/dist/components/forms/classes.d.ts.map +1 -0
  129. package/dist/components/forms/classes.js +32 -0
  130. package/dist/components/forms/index.d.ts +5 -0
  131. package/dist/components/forms/index.d.ts.map +1 -0
  132. package/dist/components/forms/index.js +4 -0
  133. package/dist/components/index.d.ts +51 -0
  134. package/dist/components/index.d.ts.map +1 -0
  135. package/dist/components/index.js +37 -0
  136. package/dist/components/rowActionsMenuHelpers.d.ts +13 -0
  137. package/dist/components/rowActionsMenuHelpers.d.ts.map +1 -0
  138. package/dist/components/rowActionsMenuHelpers.js +29 -0
  139. package/dist/components/useDialogFocus.d.ts +16 -0
  140. package/dist/components/useDialogFocus.d.ts.map +1 -0
  141. package/dist/components/useDialogFocus.js +81 -0
  142. package/dist/components/utils.d.ts +29 -0
  143. package/dist/components/utils.d.ts.map +1 -0
  144. package/dist/components/utils.js +89 -0
  145. package/dist/components/utils.test.d.ts +2 -0
  146. package/dist/components/utils.test.d.ts.map +1 -0
  147. package/dist/components/utils.test.js +27 -0
  148. package/dist/http/substitute.d.ts.map +1 -1
  149. package/dist/http/substitute.js +9 -3
  150. package/dist/http/substitute.test.js +8 -0
  151. package/dist/main.d.ts +1 -1
  152. package/dist/main.d.ts.map +1 -1
  153. package/dist/runtime/react.d.ts +16 -1
  154. package/dist/runtime/react.js +40 -0
  155. package/dist/types.d.ts +100 -0
  156. package/dist/types.d.ts.map +1 -1
  157. package/dist/ui/codeEditorSettings.d.ts +29 -0
  158. package/dist/ui/codeEditorSettings.d.ts.map +1 -0
  159. package/dist/ui/codeEditorSettings.js +52 -0
  160. package/dist/ui/index.d.ts +1 -0
  161. package/dist/ui/index.d.ts.map +1 -1
  162. package/dist/ui/index.js +1 -0
  163. package/dist/variables/dynamic.d.ts +49 -0
  164. package/dist/variables/dynamic.d.ts.map +1 -0
  165. package/dist/variables/dynamic.js +735 -0
  166. package/dist/variables/dynamic.test.d.ts +2 -0
  167. package/dist/variables/dynamic.test.d.ts.map +1 -0
  168. package/dist/variables/dynamic.test.js +60 -0
  169. package/dist/variables/index.d.ts +3 -0
  170. package/dist/variables/index.d.ts.map +1 -0
  171. package/dist/variables/index.js +2 -0
  172. package/dist/variables/tokens.d.ts +44 -0
  173. package/dist/variables/tokens.d.ts.map +1 -0
  174. package/dist/variables/tokens.js +76 -0
  175. package/dist/variables/tokens.test.d.ts +2 -0
  176. package/dist/variables/tokens.test.d.ts.map +1 -0
  177. package/dist/variables/tokens.test.js +115 -0
  178. package/package.json +75 -14
@@ -0,0 +1,151 @@
1
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from '@harborclient/sdk/react';
2
+ /**
3
+ * Loads a persisted size from localStorage.
4
+ */
5
+ function loadStoredSize(storageKey, defaultSize) {
6
+ try {
7
+ const raw = localStorage.getItem(storageKey);
8
+ if (!raw)
9
+ return defaultSize;
10
+ const size = Number(raw);
11
+ return Number.isFinite(size) ? size : defaultSize;
12
+ }
13
+ catch {
14
+ return defaultSize;
15
+ }
16
+ }
17
+ /**
18
+ * Persists a size to localStorage.
19
+ */
20
+ function persistSize(storageKey, size) {
21
+ try {
22
+ localStorage.setItem(storageKey, String(size));
23
+ }
24
+ catch {
25
+ // Ignore quota or privacy-mode failures.
26
+ }
27
+ }
28
+ /**
29
+ * Clamps a size between min and optional max bounds.
30
+ */
31
+ function clampSize(size, minSize, getMaxSize) {
32
+ const rawMax = getMaxSize?.() ?? Number.POSITIVE_INFINITY;
33
+ const maxSize = Math.max(minSize, rawMax);
34
+ return Math.min(maxSize, Math.max(minSize, size));
35
+ }
36
+ /**
37
+ * Tracks resizable panel size with pointer drag and optional persistence.
38
+ */
39
+ export function useResizable({ axis, direction, defaultSize, minSize, getMaxSize, storageKey }) {
40
+ const [size, setSizeState] = useState(() => {
41
+ const initial = storageKey ? loadStoredSize(storageKey, defaultSize) : defaultSize;
42
+ return clampSize(initial, minSize, getMaxSize);
43
+ });
44
+ const [maxSize, setMaxSizeState] = useState(() => getMaxSize?.() ?? Number.POSITIVE_INFINITY);
45
+ const resizingRef = useRef(false);
46
+ const startPosRef = useRef(0);
47
+ const startSizeRef = useRef(defaultSize);
48
+ const sizeRef = useRef(size);
49
+ /**
50
+ * Keeps a ref in sync with state so drag handlers read the latest size.
51
+ */
52
+ useEffect(() => {
53
+ sizeRef.current = size;
54
+ }, [size]);
55
+ /**
56
+ * Refreshes the computed max size when layout changes or the panel is resized.
57
+ */
58
+ useLayoutEffect(() => {
59
+ /**
60
+ * Re-reads dynamic max bounds from the optional getter.
61
+ */
62
+ const updateMaxSize = () => {
63
+ setMaxSizeState(getMaxSize?.() ?? Number.POSITIVE_INFINITY);
64
+ };
65
+ updateMaxSize();
66
+ window.addEventListener('resize', updateMaxSize);
67
+ return () => window.removeEventListener('resize', updateMaxSize);
68
+ }, [getMaxSize, size]);
69
+ /**
70
+ * Updates panel size with min/max clamping applied.
71
+ */
72
+ const setSize = useCallback((nextSize) => {
73
+ setSizeState(clampSize(nextSize, minSize, getMaxSize));
74
+ }, [getMaxSize, minSize]);
75
+ /**
76
+ * Captures pointer position and current size when a resize drag begins.
77
+ */
78
+ const onResizeStart = useCallback((event) => {
79
+ event.preventDefault();
80
+ resizingRef.current = true;
81
+ startPosRef.current = axis === 'x' ? event.clientX : event.clientY;
82
+ startSizeRef.current = sizeRef.current;
83
+ }, [axis]);
84
+ /**
85
+ * Nudges panel size from arrow keys using the same axis/direction math as drag.
86
+ */
87
+ const onKeyboardResize = useCallback((event) => {
88
+ if (event.key === 'Enter' || event.key === ' ') {
89
+ event.preventDefault();
90
+ return;
91
+ }
92
+ const step = event.shiftKey ? 1 : 10;
93
+ let keyDelta = 0;
94
+ if (axis === 'x') {
95
+ if (event.key === 'ArrowRight')
96
+ keyDelta = step;
97
+ else if (event.key === 'ArrowLeft')
98
+ keyDelta = -step;
99
+ }
100
+ else if (event.key === 'ArrowDown') {
101
+ keyDelta = step;
102
+ }
103
+ else if (event.key === 'ArrowUp') {
104
+ keyDelta = -step;
105
+ }
106
+ if (keyDelta === 0)
107
+ return;
108
+ event.preventDefault();
109
+ const nextSize = clampSize(sizeRef.current + keyDelta * direction, minSize, getMaxSize);
110
+ setSizeState(nextSize);
111
+ if (storageKey) {
112
+ persistSize(storageKey, nextSize);
113
+ }
114
+ }, [axis, direction, getMaxSize, minSize, storageKey]);
115
+ /**
116
+ * Applies pointer delta to panel size during drag and persists on mouse up.
117
+ */
118
+ useEffect(() => {
119
+ /**
120
+ * Updates size from pointer movement while a resize drag is active.
121
+ *
122
+ * @param event - Window mousemove event.
123
+ */
124
+ const handleMouseMove = (event) => {
125
+ if (!resizingRef.current)
126
+ return;
127
+ const currentPos = axis === 'x' ? event.clientX : event.clientY;
128
+ const delta = (currentPos - startPosRef.current) * direction;
129
+ const nextSize = clampSize(startSizeRef.current + delta, minSize, getMaxSize);
130
+ setSizeState(nextSize);
131
+ };
132
+ /**
133
+ * Ends the resize drag and writes the final size to localStorage when configured.
134
+ */
135
+ const handleMouseUp = () => {
136
+ if (!resizingRef.current)
137
+ return;
138
+ resizingRef.current = false;
139
+ if (storageKey) {
140
+ persistSize(storageKey, sizeRef.current);
141
+ }
142
+ };
143
+ window.addEventListener('mousemove', handleMouseMove);
144
+ window.addEventListener('mouseup', handleMouseUp);
145
+ return () => {
146
+ window.removeEventListener('mousemove', handleMouseMove);
147
+ window.removeEventListener('mouseup', handleMouseUp);
148
+ };
149
+ }, [axis, direction, getMaxSize, minSize, storageKey]);
150
+ return { size, minSize, maxSize, setSize, onResizeStart, onKeyboardResize };
151
+ }
@@ -0,0 +1,73 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ interface ResourceListProps {
3
+ /**
4
+ * List row elements, typically {@link ResourceListRow} items.
5
+ */
6
+ children: ReactNode;
7
+ /**
8
+ * Additional Tailwind classes merged onto the list element.
9
+ */
10
+ className?: string;
11
+ }
12
+ /**
13
+ * Vertical list shell used for bordered resource rows in settings and Team Hub.
14
+ *
15
+ * @param children - List item elements.
16
+ * @param className - Extra classes appended after the layout preset.
17
+ */
18
+ export declare function ResourceList({ children, className }: ResourceListProps): JSX.Element;
19
+ interface ResourceListRowProps {
20
+ /**
21
+ * Primary title or name for the resource.
22
+ */
23
+ primary: ReactNode;
24
+ /**
25
+ * Optional secondary line such as a URL or identifier.
26
+ */
27
+ secondary?: ReactNode;
28
+ /**
29
+ * Optional metadata rendered below primary/secondary content, e.g. badges.
30
+ */
31
+ meta?: ReactNode;
32
+ /**
33
+ * Trailing action buttons or menus.
34
+ */
35
+ actions?: ReactNode;
36
+ /**
37
+ * When true, allows primary content and actions to wrap on narrow widths.
38
+ */
39
+ wrap?: boolean;
40
+ /**
41
+ * Additional Tailwind classes merged onto the row element.
42
+ */
43
+ className?: string;
44
+ }
45
+ /**
46
+ * Bordered list row with primary text, optional secondary line, metadata, and actions.
47
+ *
48
+ * @param primary - Main label for the resource.
49
+ * @param secondary - Optional muted secondary line.
50
+ * @param meta - Optional content below the title block.
51
+ * @param actions - Trailing controls aligned to the row end.
52
+ * @param wrap - Whether the row uses flex-wrap for narrow layouts.
53
+ * @param className - Extra classes appended after the layout preset.
54
+ */
55
+ export declare function ResourceListRow({ primary, secondary, meta, actions, wrap, className }: ResourceListRowProps): JSX.Element;
56
+ /**
57
+ * Primary title styling for {@link ResourceListRow}.
58
+ *
59
+ * @param children - Title content.
60
+ */
61
+ export declare function ResourceListPrimary({ children }: {
62
+ children: ReactNode;
63
+ }): JSX.Element;
64
+ /**
65
+ * Inline empty-state row rendered inside a {@link ResourceList}.
66
+ *
67
+ * @param children - Empty message content.
68
+ */
69
+ export declare function ResourceListEmptyItem({ children }: {
70
+ children: ReactNode;
71
+ }): JSX.Element;
72
+ export {};
73
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ResourceList/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,UAAU,iBAAiB;IACzB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CAKpF;AAED,UAAU,oBAAoB;IAC5B;;OAEG;IACH,OAAO,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,SAAS,EACT,IAAI,EACJ,OAAO,EACP,IAAY,EACZ,SAAS,EACV,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CAoBpC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAExF"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ /**
3
+ * Vertical list shell used for bordered resource rows in settings and Team Hub.
4
+ *
5
+ * @param children - List item elements.
6
+ * @param className - Extra classes appended after the layout preset.
7
+ */
8
+ export function ResourceList({ children, className }) {
9
+ const base = 'm-0 flex list-none flex-col gap-2 p-0';
10
+ const classes = className ? `${base} ${className}` : base;
11
+ return _jsx("ul", { className: classes, children: children });
12
+ }
13
+ /**
14
+ * Bordered list row with primary text, optional secondary line, metadata, and actions.
15
+ *
16
+ * @param primary - Main label for the resource.
17
+ * @param secondary - Optional muted secondary line.
18
+ * @param meta - Optional content below the title block.
19
+ * @param actions - Trailing controls aligned to the row end.
20
+ * @param wrap - Whether the row uses flex-wrap for narrow layouts.
21
+ * @param className - Extra classes appended after the layout preset.
22
+ */
23
+ export function ResourceListRow({ primary, secondary, meta, actions, wrap = false, className }) {
24
+ const wrapClass = wrap ? 'flex-wrap' : '';
25
+ const base = `flex items-center justify-between gap-3 rounded-md border border-separator px-3 py-2 ${wrapClass}`.trim();
26
+ const classes = className ? `${base} ${className}` : base;
27
+ return (_jsxs("li", { className: classes, children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "min-w-0", children: primary }), secondary != null ? (_jsx("div", { className: "truncate text-[14px] text-muted", children: secondary })) : null, meta] }), actions ? (_jsx("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-2", children: actions })) : null] }));
28
+ }
29
+ /**
30
+ * Primary title styling for {@link ResourceListRow}.
31
+ *
32
+ * @param children - Title content.
33
+ */
34
+ export function ResourceListPrimary({ children }) {
35
+ return _jsx("div", { className: "truncate text-[14px] font-medium text-text", children: children });
36
+ }
37
+ /**
38
+ * Inline empty-state row rendered inside a {@link ResourceList}.
39
+ *
40
+ * @param children - Empty message content.
41
+ */
42
+ export function ResourceListEmptyItem({ children }) {
43
+ return _jsx("li", { className: "text-[14px] text-muted", children: children });
44
+ }
@@ -0,0 +1,33 @@
1
+ import type { JSX } from 'react';
2
+ export type MenuItem = {
3
+ label: string;
4
+ onSelect: () => void;
5
+ variant?: 'default' | 'danger';
6
+ };
7
+ interface Props {
8
+ /**
9
+ * Grouped menu entries shown when the trigger is open. Each inner array is
10
+ * one visual group separated by a divider line.
11
+ */
12
+ groups: MenuItem[][];
13
+ /**
14
+ * Unique id for this menu instance (e.g. "collection-3").
15
+ */
16
+ menuId: string;
17
+ /**
18
+ * Id of the currently open menu, or null when all are closed.
19
+ */
20
+ openMenuId: string | null;
21
+ /**
22
+ * Called when the user opens or closes a menu.
23
+ *
24
+ * @param id - Open menu id, or null to close.
25
+ */
26
+ onOpenChange: (id: string | null) => void;
27
+ }
28
+ /**
29
+ * Hamburger-triggered dropdown for row-level actions (rename, delete, etc.).
30
+ */
31
+ export declare function RowActionsMenu({ groups, menuId, openMenuId, onOpenChange }: Props): JSX.Element;
32
+ export {};
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RowActionsMenu/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAKjC,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAChC,CAAC;AAEF,UAAU,KAAK;IACb;;;OAGG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;;;OAIG;IACH,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC3C;AAgBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA+E/F"}
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ import { useEffect, useRef } from '@harborclient/sdk/react';
3
+ import { Button } from '../Button/index.js';
4
+ import { FaIcon } from '../FaIcon/index.js';
5
+ import { faBars } from '@fortawesome/free-solid-svg-icons';
6
+ /**
7
+ * Tailwind classes for a single menu item button.
8
+ *
9
+ * @param variant - Visual variant for default or destructive actions.
10
+ */
11
+ function menuItemClass(variant) {
12
+ const base = 'block w-full cursor-pointer border-none bg-transparent px-3.5 py-1.5 text-left text-[14px] app-no-drag';
13
+ return variant === 'danger'
14
+ ? `${base} text-text hover:bg-danger/15 hover:text-danger`
15
+ : `${base} text-text hover:bg-selection`;
16
+ }
17
+ /**
18
+ * Hamburger-triggered dropdown for row-level actions (rename, delete, etc.).
19
+ */
20
+ export function RowActionsMenu({ groups, menuId, openMenuId, onOpenChange }) {
21
+ const isOpen = openMenuId === menuId;
22
+ const rootRef = useRef(null);
23
+ /**
24
+ * Closes the menu on outside click or Escape while it is open.
25
+ */
26
+ useEffect(() => {
27
+ if (!isOpen)
28
+ return;
29
+ const handleMouseDown = (e) => {
30
+ if (rootRef.current && !rootRef.current.contains(e.target)) {
31
+ onOpenChange(null);
32
+ }
33
+ };
34
+ const handleKeyDown = (e) => {
35
+ if (e.key === 'Escape') {
36
+ onOpenChange(null);
37
+ }
38
+ };
39
+ document.addEventListener('mousedown', handleMouseDown);
40
+ document.addEventListener('keydown', handleKeyDown);
41
+ return () => {
42
+ document.removeEventListener('mousedown', handleMouseDown);
43
+ document.removeEventListener('keydown', handleKeyDown);
44
+ };
45
+ }, [isOpen, onOpenChange]);
46
+ return (_jsxs("div", { ref: rootRef, className: "relative shrink-0", children: [_jsx(Button, { type: "button", variant: "icon", className: isOpen ? 'opacity-100' : undefined, title: "Actions", "aria-label": "Row actions", "aria-haspopup": "menu", "aria-expanded": isOpen, onClick: (e) => {
47
+ e.stopPropagation();
48
+ onOpenChange(isOpen ? null : menuId);
49
+ }, children: _jsx(FaIcon, { icon: faBars, className: "h-3.5 w-3.5" }) }), isOpen && (_jsx("div", { role: "menu", className: "absolute right-0 top-full z-10 mt-0.5 min-w-[120px] rounded-md border border-separator bg-surface py-1 shadow-md app-no-drag", children: groups.map((group, groupIndex) => (_jsx("div", { role: "group", className: groupIndex > 0 ? 'border-t border-separator' : undefined, children: group.map((item) => (_jsx("button", { type: "button", role: "menuitem", className: menuItemClass(item.variant), onClick: (e) => {
50
+ e.stopPropagation();
51
+ onOpenChange(null);
52
+ item.onSelect();
53
+ }, children: item.label }, item.label))) }, groupIndex))) }))] }));
54
+ }
@@ -0,0 +1,107 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ export interface TabItem<T extends string> {
3
+ /**
4
+ * Unique tab identifier.
5
+ */
6
+ value: T;
7
+ /**
8
+ * Tab label or custom content.
9
+ */
10
+ label: ReactNode;
11
+ /**
12
+ * When true, the tab is not rendered.
13
+ */
14
+ hidden?: boolean;
15
+ /**
16
+ * When true, the tab button is disabled.
17
+ */
18
+ disabled?: boolean;
19
+ /**
20
+ * When true, renders a small dot indicating the tab has values set.
21
+ */
22
+ indicator?: boolean;
23
+ }
24
+ interface GroupProps<T extends string> {
25
+ /**
26
+ * Currently selected tab value.
27
+ */
28
+ value: T;
29
+ /**
30
+ * Called when the user selects a different tab.
31
+ *
32
+ * @param value - Newly selected tab value.
33
+ */
34
+ onChange: (value: T) => void;
35
+ /**
36
+ * Accessible name for the tab list.
37
+ */
38
+ ariaLabel: string;
39
+ /**
40
+ * Tab list and linked tab panels.
41
+ */
42
+ children: ReactNode;
43
+ }
44
+ /**
45
+ * Provides tab selection state and stable ids for `SegmentedTabs` and
46
+ * `SegmentedTabPanel` children.
47
+ */
48
+ export declare function SegmentedTabsGroup<T extends string>({ value, onChange, ariaLabel, children }: GroupProps<T>): JSX.Element;
49
+ interface PanelProps<T extends string> {
50
+ /**
51
+ * Tab value that controls visibility of this panel.
52
+ */
53
+ value: T;
54
+ /**
55
+ * Panel content shown when this tab is selected.
56
+ */
57
+ children: ReactNode;
58
+ /**
59
+ * Additional CSS classes for the panel container.
60
+ */
61
+ className?: string;
62
+ }
63
+ /**
64
+ * Renders a WAI-ARIA tab panel linked to the matching tab in the parent group.
65
+ */
66
+ export declare function SegmentedTabPanel<T extends string>({ value, children, className }: PanelProps<T>): JSX.Element | null;
67
+ interface Props<T extends string> {
68
+ /**
69
+ * Tab definitions to render.
70
+ */
71
+ tabs: TabItem<T>[];
72
+ /**
73
+ * Currently selected tab value. Omit when used inside `SegmentedTabsGroup`.
74
+ */
75
+ value?: T;
76
+ /**
77
+ * Called when the user selects a different tab. Omit when used inside
78
+ * `SegmentedTabsGroup`.
79
+ *
80
+ * @param value - Newly selected tab value.
81
+ */
82
+ onChange?: (value: T) => void;
83
+ /**
84
+ * When true, the group and each tab stretch to full width.
85
+ */
86
+ fullWidth?: boolean;
87
+ /**
88
+ * Additional CSS classes for the tab group container.
89
+ */
90
+ className?: string;
91
+ /**
92
+ * ARIA pattern for the control. Use `radiogroup` for single-choice settings
93
+ * pickers; use `tabs` with `SegmentedTabsGroup` for content switchers.
94
+ */
95
+ pattern?: 'tabs' | 'radiogroup';
96
+ /**
97
+ * Accessible name for the tab list or radio group. Omit when used inside
98
+ * `SegmentedTabsGroup`.
99
+ */
100
+ ariaLabel?: string;
101
+ }
102
+ /**
103
+ * macOS-style segmented tab control with WAI-ARIA tabs or radiogroup semantics.
104
+ */
105
+ export declare function SegmentedTabs<T extends string>({ tabs, value: valueProp, onChange: onChangeProp, fullWidth, className, pattern, ariaLabel: ariaLabelProp }: Props<T>): JSX.Element;
106
+ export {};
107
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SegmentedTabs/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,GAAG,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3D,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM;IACvC;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA+BD,UAAU,UAAU,CAAC,CAAC,SAAS,MAAM;IACnC;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC;IAET;;;;OAIG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAE7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EAAE,EACnD,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACT,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAmB7B;AAED,UAAU,UAAU,CAAC,CAAC,SAAS,MAAM;IACnC;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC;IAET;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAAE,EAClD,KAAK,EACL,QAAQ,EACR,SAAS,EACV,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAkBpC;AAED,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM;IAC9B;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,CAAC;IAEV;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAE9B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAEhC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,EAC9C,IAAI,EACJ,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,YAAY,EACtB,SAAiB,EACjB,SAAS,EACT,OAAgB,EAChB,SAAS,EAAE,aAAa,EACzB,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CA8GxB"}
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ import { createContext, createElement, useCallback, useContext, useId, useMemo, useRef } from '@harborclient/sdk/react';
3
+ import { resolveTabListKeyAction } from '../utils.js';
4
+ import { segment, segmentGroup } from '../classes.js';
5
+ const SegmentedTabsContext = createContext(null);
6
+ /**
7
+ * Provides tab selection state and stable ids for `SegmentedTabs` and
8
+ * `SegmentedTabPanel` children.
9
+ */
10
+ export function SegmentedTabsGroup({ value, onChange, ariaLabel, children }) {
11
+ const baseId = useId();
12
+ /**
13
+ * Memoizes context so tab ids stay stable across renders while value updates
14
+ * propagate to list and panel children.
15
+ */
16
+ const contextValue = useMemo(() => ({
17
+ value,
18
+ onChange: (nextValue) => onChange(nextValue),
19
+ ariaLabel,
20
+ getTabId: (tabValue) => `${baseId}-tab-${tabValue}`,
21
+ getPanelId: (tabValue) => `${baseId}-panel-${tabValue}`
22
+ }), [value, onChange, ariaLabel, baseId]);
23
+ return createElement(SegmentedTabsContext.Provider, { value: contextValue }, children);
24
+ }
25
+ /**
26
+ * Renders a WAI-ARIA tab panel linked to the matching tab in the parent group.
27
+ */
28
+ export function SegmentedTabPanel({ value, children, className }) {
29
+ const context = useContext(SegmentedTabsContext);
30
+ if (!context) {
31
+ throw new Error('SegmentedTabPanel must be used within SegmentedTabsGroup');
32
+ }
33
+ if (context.value !== value)
34
+ return null;
35
+ return (_jsx("div", { role: "tabpanel", id: context.getPanelId(value), "aria-labelledby": context.getTabId(value), className: className, children: children }));
36
+ }
37
+ /**
38
+ * macOS-style segmented tab control with WAI-ARIA tabs or radiogroup semantics.
39
+ */
40
+ export function SegmentedTabs({ tabs, value: valueProp, onChange: onChangeProp, fullWidth = false, className, pattern = 'tabs', ariaLabel: ariaLabelProp }) {
41
+ const context = useContext(SegmentedTabsContext);
42
+ const standaloneId = useId();
43
+ const tabRefs = useRef(new Map());
44
+ const value = context?.value ?? valueProp;
45
+ /**
46
+ * Resolves the change handler from group context or standalone props so the
47
+ * keyboard handler dependency stays stable across renders.
48
+ */
49
+ const onChange = useMemo(() => {
50
+ if (context)
51
+ return (nextValue) => context.onChange(nextValue);
52
+ return onChangeProp;
53
+ }, [context, onChangeProp]);
54
+ const ariaLabel = context?.ariaLabel ?? ariaLabelProp;
55
+ if (value === undefined || onChange === undefined) {
56
+ throw new Error('SegmentedTabs requires value and onChange, or must be used within SegmentedTabsGroup');
57
+ }
58
+ const getTabId = context
59
+ ? (tabValue) => context.getTabId(tabValue)
60
+ : (tabValue) => `${standaloneId}-tab-${tabValue}`;
61
+ const getPanelId = context
62
+ ? (tabValue) => context.getPanelId(tabValue)
63
+ : (tabValue) => `${standaloneId}-panel-${tabValue}`;
64
+ const visibleTabs = tabs.filter((tab) => !tab.hidden);
65
+ const groupClassName = [segmentGroup, fullWidth ? 'w-full' : '', className]
66
+ .filter(Boolean)
67
+ .join(' ');
68
+ /**
69
+ * Moves selection with arrow, Home, and End keys and focuses the newly
70
+ * selected tab or radio control.
71
+ *
72
+ * @param event - Keyboard event from the tab list or radio group container.
73
+ */
74
+ const handleKeyDown = useCallback((event) => {
75
+ const currentIndex = visibleTabs.findIndex((tab) => tab.value === value);
76
+ const disabledIndices = visibleTabs
77
+ .map((tab, index) => (tab.disabled ? index : -1))
78
+ .filter((index) => index >= 0);
79
+ const nextIndex = resolveTabListKeyAction(event.key, currentIndex, visibleTabs.length, {
80
+ disabledIndices
81
+ });
82
+ if (nextIndex === null)
83
+ return;
84
+ event.preventDefault();
85
+ const nextTab = visibleTabs[nextIndex];
86
+ if (nextTab.value !== value) {
87
+ onChange(nextTab.value);
88
+ }
89
+ requestAnimationFrame(() => {
90
+ tabRefs.current.get(nextTab.value)?.focus();
91
+ });
92
+ }, [visibleTabs, value, onChange]);
93
+ const isRadiogroup = pattern === 'radiogroup';
94
+ return (_jsx("div", { className: groupClassName, role: isRadiogroup ? 'radiogroup' : 'tablist', "aria-label": ariaLabel, onKeyDown: handleKeyDown, children: visibleTabs.map((tab) => {
95
+ const selected = value === tab.value;
96
+ const tabClassName = `${segment(selected)}${fullWidth ? ' flex-1' : ''}`;
97
+ return (_jsx("button", { ref: (element) => {
98
+ if (element)
99
+ tabRefs.current.set(tab.value, element);
100
+ else
101
+ tabRefs.current.delete(tab.value);
102
+ }, type: "button", className: tabClassName, disabled: tab.disabled, tabIndex: selected ? 0 : -1, onClick: () => onChange(tab.value), ...(isRadiogroup
103
+ ? { role: 'radio', 'aria-checked': selected }
104
+ : {
105
+ role: 'tab',
106
+ id: getTabId(tab.value),
107
+ 'aria-selected': selected,
108
+ 'aria-controls': getPanelId(tab.value)
109
+ }), children: _jsxs("span", { className: "inline-flex items-center gap-1.5", children: [tab.label, tab.indicator && _jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-accent", "aria-hidden": true })] }) }, tab.value));
110
+ }) }));
111
+ }
@@ -0,0 +1,26 @@
1
+ import type { JSX } from 'react';
2
+ type SpinnerSize = 'sm' | 'md';
3
+ interface Props {
4
+ /**
5
+ * Visual size preset for the spinner SVG.
6
+ */
7
+ size?: SpinnerSize;
8
+ /**
9
+ * Accessible label announced while the spinner is visible.
10
+ */
11
+ label?: string;
12
+ /**
13
+ * Additional Tailwind classes merged onto the wrapper element.
14
+ */
15
+ className?: string;
16
+ }
17
+ /**
18
+ * Accent-colored spinning indicator shared by busy overlays, tabs, and modals.
19
+ *
20
+ * @param size - Visual size (`sm` or `md`).
21
+ * @param label - Accessible status label; when set, exposes `role="status"`.
22
+ * @param className - Extra classes on the wrapper span.
23
+ */
24
+ export declare function Spinner({ size, label, className }: 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/Spinner/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/B,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EAAE,IAAW,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA4B7E"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ /**
3
+ * Returns width and height classes for the spinner size preset.
4
+ *
5
+ * @param size - Spinner size preset.
6
+ * @returns Tailwind dimension classes.
7
+ */
8
+ function sizeClasses(size) {
9
+ return size === 'sm' ? 'h-3 w-3' : 'h-4 w-4';
10
+ }
11
+ /**
12
+ * Accent-colored spinning indicator shared by busy overlays, tabs, and modals.
13
+ *
14
+ * @param size - Visual size (`sm` or `md`).
15
+ * @param label - Accessible status label; when set, exposes `role="status"`.
16
+ * @param className - Extra classes on the wrapper span.
17
+ */
18
+ export function Spinner({ size = 'md', label, className }) {
19
+ const wrapperBase = 'inline-flex items-center justify-center';
20
+ const wrapperClasses = className ? `${wrapperBase} ${className}` : wrapperBase;
21
+ return (_jsx("span", { className: wrapperClasses, role: label ? 'status' : undefined, "aria-label": label, children: _jsxs("svg", { className: `${sizeClasses(size)} animate-spin text-accent`, viewBox: "0 0 24 24", fill: "none", "aria-hidden": label ? true : undefined, children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }) }));
22
+ }
@@ -0,0 +1,29 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ interface Props {
3
+ /**
4
+ * Status or helper text content.
5
+ */
6
+ children: ReactNode;
7
+ /**
8
+ * When true, exposes the message as a live region for assistive technologies.
9
+ */
10
+ live?: boolean;
11
+ /**
12
+ * Optional element id for `aria-describedby` linkage.
13
+ */
14
+ id?: string;
15
+ /**
16
+ * Additional Tailwind classes merged onto the status paragraph.
17
+ */
18
+ className?: string;
19
+ }
20
+ /**
21
+ * Muted helper or progress text with optional polite live-region semantics.
22
+ *
23
+ * @param children - Status message content.
24
+ * @param live - Whether to set `role="status"` and `aria-live="polite"`.
25
+ * @param className - Extra classes appended after the preset.
26
+ */
27
+ export declare function StatusMessage({ children, live, id, className }: Props): JSX.Element;
28
+ export {};
29
+ //# sourceMappingURL=index.d.ts.map