@harborclient/sdk 0.6.3 → 0.6.6
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/dist/components/BusyIndicator/index.d.ts +3 -2
- package/dist/components/BusyIndicator/index.d.ts.map +1 -1
- package/dist/components/BusyIndicator/index.js +11 -3
- package/dist/components/Button/index.d.ts +23 -8
- package/dist/components/Button/index.d.ts.map +1 -1
- package/dist/components/Button/index.js +6 -4
- package/dist/components/CodeEditor/index.d.ts +9 -1
- package/dist/components/CodeEditor/index.d.ts.map +1 -1
- package/dist/components/CodeEditor/index.js +186 -62
- package/dist/components/FieldError/index.d.ts.map +1 -1
- package/dist/components/FieldError/index.js +1 -1
- package/dist/components/FormDataEditor/index.d.ts.map +1 -1
- package/dist/components/FormDataEditor/index.js +10 -38
- package/dist/components/FormDataEditor/utils.d.ts +19 -0
- package/dist/components/FormDataEditor/utils.d.ts.map +1 -0
- package/dist/components/FormDataEditor/utils.js +28 -0
- package/dist/components/FormGroup/index.d.ts +6 -1
- package/dist/components/FormGroup/index.d.ts.map +1 -1
- package/dist/components/FormGroup/index.js +25 -31
- package/dist/components/KeyValueEditor/index.d.ts.map +1 -1
- package/dist/components/KeyValueEditor/index.js +2 -3
- package/dist/components/Modal/ModalFormLayout.d.ts.map +1 -1
- package/dist/components/Modal/ModalFormLayout.js +2 -1
- package/dist/components/Modal/ModalHeader.d.ts +5 -1
- package/dist/components/Modal/ModalHeader.d.ts.map +1 -1
- package/dist/components/Modal/ModalHeader.js +2 -2
- package/dist/components/Modal/index.d.ts.map +1 -1
- package/dist/components/Modal/index.js +4 -2
- package/dist/components/OverlayCloseButton/index.d.ts.map +1 -1
- package/dist/components/OverlayCloseButton/index.js +1 -2
- package/dist/components/Page/index.d.ts +46 -0
- package/dist/components/Page/index.d.ts.map +1 -0
- package/dist/components/Page/index.js +18 -0
- package/dist/components/PageSidebar/index.d.ts +45 -0
- package/dist/components/PageSidebar/index.d.ts.map +1 -0
- package/dist/components/PageSidebar/index.js +24 -0
- package/dist/components/Resizable/Resizable.d.ts.map +1 -1
- package/dist/components/Resizable/Resizable.js +1 -1
- package/dist/components/Resizable/ResizeHandle.js +2 -2
- package/dist/components/ResourceList/index.d.ts +11 -1
- package/dist/components/ResourceList/index.d.ts.map +1 -1
- package/dist/components/ResourceList/index.js +4 -2
- package/dist/components/RowActionsMenu/index.d.ts.map +1 -1
- package/dist/components/RowActionsMenu/index.js +150 -11
- package/dist/components/SegmentedTabs/index.d.ts.map +1 -1
- package/dist/components/SegmentedTabs/index.js +2 -2
- package/dist/components/SidebarLayout/index.d.ts +22 -0
- package/dist/components/SidebarLayout/index.d.ts.map +1 -0
- package/dist/components/SidebarLayout/index.js +11 -0
- package/dist/components/TabCloseButton/index.d.ts +1 -1
- package/dist/components/TabCloseButton/index.js +2 -2
- package/dist/components/Table/index.d.ts +103 -0
- package/dist/components/Table/index.d.ts.map +1 -0
- package/dist/components/Table/index.js +99 -0
- package/dist/components/VariableInput/index.d.ts.map +1 -1
- package/dist/components/VariableInput/index.js +84 -10
- package/dist/components/VariableTable/index.d.ts.map +1 -1
- package/dist/components/VariableTable/index.js +2 -2
- package/dist/components/enhanceControl.d.ts +28 -0
- package/dist/components/enhanceControl.d.ts.map +1 -0
- package/dist/components/enhanceControl.js +84 -0
- package/dist/components/enhanceControl.test.d.ts +2 -0
- package/dist/components/enhanceControl.test.d.ts.map +1 -0
- package/dist/components/enhanceControl.test.js +83 -0
- package/dist/components/index.d.ts +6 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -1
- package/dist/components/useDialogFocus.d.ts +3 -2
- package/dist/components/useDialogFocus.d.ts.map +1 -1
- package/dist/components/useDialogFocus.js +61 -4
- package/dist/components/utils.d.ts +25 -0
- package/dist/components/utils.d.ts.map +1 -1
- package/dist/components/utils.js +24 -0
- package/dist/components/utils.test.js +18 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/variables/index.d.ts +1 -1
- package/dist/variables/index.d.ts.map +1 -1
- package/dist/variables/index.js +1 -1
- package/dist/variables/tokens.d.ts +31 -0
- package/dist/variables/tokens.d.ts.map +1 -1
- package/dist/variables/tokens.js +38 -1
- package/dist/variables/tokens.test.js +46 -1
- package/package.json +1 -1
- package/dist/components/OverlayPage/index.d.ts +0 -40
- package/dist/components/OverlayPage/index.d.ts.map +0 -1
- package/dist/components/OverlayPage/index.js +0 -18
|
@@ -32,6 +32,10 @@ interface Props {
|
|
|
32
32
|
* Explicit id for the error element; defaults to `${htmlFor}-error` when `htmlFor` is set.
|
|
33
33
|
*/
|
|
34
34
|
errorId?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Explicit id for the description element; defaults to `${htmlFor}-description` when `htmlFor` is set.
|
|
37
|
+
*/
|
|
38
|
+
descriptionId?: string;
|
|
35
39
|
/**
|
|
36
40
|
* Label and control placement. Defaults to stacked (label above control).
|
|
37
41
|
*/
|
|
@@ -64,12 +68,13 @@ interface Props {
|
|
|
64
68
|
* @param description - Optional helper text below the control.
|
|
65
69
|
* @param error - Optional validation error below the control.
|
|
66
70
|
* @param errorId - Explicit error element id for `aria-describedby`.
|
|
71
|
+
* @param descriptionId - Explicit description element id for `aria-describedby`.
|
|
67
72
|
* @param layout - Label/control placement preset.
|
|
68
73
|
* @param labelTone - Label color style.
|
|
69
74
|
* @param srOnly - Hide label visually for screen-reader-only labels.
|
|
70
75
|
* @param className - Extra classes on the outer wrapper.
|
|
71
76
|
* @param labelClassName - Extra classes on the label element.
|
|
72
77
|
*/
|
|
73
|
-
export declare function FormGroup({ label, children, htmlFor, description, error, errorId, layout, labelTone, srOnly, className, labelClassName }: Props): JSX.Element;
|
|
78
|
+
export declare function FormGroup({ label, children, htmlFor, description, error, errorId, descriptionId, layout, labelTone, srOnly, className, labelClassName }: Props): JSX.Element;
|
|
74
79
|
export {};
|
|
75
80
|
//# 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,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FormGroup/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5C;;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,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;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;CACzB;AAqBD;;;;;;;;;;;;;;;;;GAiBG;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,EACf,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAsGrB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useId } from '@harborclient/sdk/react';
|
|
3
3
|
import { FieldError } from '../FieldError/index.js';
|
|
4
|
+
import { enhanceControl } from '../enhanceControl.js';
|
|
4
5
|
/**
|
|
5
6
|
* Returns Tailwind classes for the label text based on tone and visibility.
|
|
6
7
|
*
|
|
@@ -19,29 +20,6 @@ function labelClasses(tone, srOnly, inline) {
|
|
|
19
20
|
const color = tone === 'muted' ? 'text-muted' : 'font-medium text-text';
|
|
20
21
|
return `${base} ${color} ${visibility}`.trim();
|
|
21
22
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Merges accessibility attributes onto a single control when a field error is present.
|
|
24
|
-
*
|
|
25
|
-
* @param child - Form control element to enhance.
|
|
26
|
-
* @param describedBy - Id of the error element for `aria-describedby`.
|
|
27
|
-
* @returns The original node or a cloned element with invalid/describedby props.
|
|
28
|
-
*/
|
|
29
|
-
function enhanceControl(child, describedBy) {
|
|
30
|
-
if (!describedBy ||
|
|
31
|
-
!isValidElement(child)) {
|
|
32
|
-
return child;
|
|
33
|
-
}
|
|
34
|
-
const existingDescribedBy = typeof child.props['aria-describedby'] === 'string'
|
|
35
|
-
? child.props['aria-describedby']
|
|
36
|
-
: undefined;
|
|
37
|
-
const mergedDescribedBy = existingDescribedBy
|
|
38
|
-
? `${existingDescribedBy} ${describedBy}`
|
|
39
|
-
: describedBy;
|
|
40
|
-
return cloneElement(child, {
|
|
41
|
-
'aria-invalid': true,
|
|
42
|
-
'aria-describedby': mergedDescribedBy
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
23
|
/**
|
|
46
24
|
* Reusable form field wrapper that pairs a label with one or more controls.
|
|
47
25
|
* Supports stacked fields, checkboxes, inline rows, radio options, and
|
|
@@ -53,13 +31,16 @@ function enhanceControl(child, describedBy) {
|
|
|
53
31
|
* @param description - Optional helper text below the control.
|
|
54
32
|
* @param error - Optional validation error below the control.
|
|
55
33
|
* @param errorId - Explicit error element id for `aria-describedby`.
|
|
34
|
+
* @param descriptionId - Explicit description element id for `aria-describedby`.
|
|
56
35
|
* @param layout - Label/control placement preset.
|
|
57
36
|
* @param labelTone - Label color style.
|
|
58
37
|
* @param srOnly - Hide label visually for screen-reader-only labels.
|
|
59
38
|
* @param className - Extra classes on the outer wrapper.
|
|
60
39
|
* @param labelClassName - Extra classes on the label element.
|
|
61
40
|
*/
|
|
62
|
-
export function FormGroup({ label, children, htmlFor, description, error, errorId, layout = 'stacked', labelTone = 'default', srOnly = false, className, labelClassName }) {
|
|
41
|
+
export function FormGroup({ label, children, htmlFor, description, error, errorId, descriptionId, layout = 'stacked', labelTone = 'default', srOnly = false, className, labelClassName }) {
|
|
42
|
+
const generatedId = useId();
|
|
43
|
+
const controlId = htmlFor ?? generatedId;
|
|
63
44
|
const extra = className ?? '';
|
|
64
45
|
if (layout === 'associated') {
|
|
65
46
|
const associatedClasses = labelClassName ?? 'text-[14px] text-text';
|
|
@@ -68,28 +49,41 @@ export function FormGroup({ label, children, htmlFor, description, error, errorI
|
|
|
68
49
|
if (layout === 'checkboxAdjacent') {
|
|
69
50
|
const wrapperClasses = extra ? `flex items-start gap-2 ${extra}` : 'flex items-start gap-2';
|
|
70
51
|
const adjacentLabelClasses = labelClassName ?? 'min-w-0 flex-1 text-[14px] text-text';
|
|
71
|
-
|
|
52
|
+
const linkedChildren = enhanceControl(children, { id: controlId });
|
|
53
|
+
return (_jsxs("div", { className: wrapperClasses, children: [linkedChildren, _jsx("label", { htmlFor: controlId, className: adjacentLabelClasses, children: label })] }));
|
|
72
54
|
}
|
|
73
55
|
if (layout === 'radio') {
|
|
74
56
|
const wrapperClasses = extra
|
|
75
57
|
? `inline-flex cursor-pointer items-center gap-1.5 text-[14px] text-text app-no-drag ${extra}`
|
|
76
58
|
: 'inline-flex cursor-pointer items-center gap-1.5 text-[14px] text-text app-no-drag';
|
|
77
|
-
|
|
59
|
+
const linkedChildren = enhanceControl(children, { id: controlId });
|
|
60
|
+
return (_jsxs("label", { htmlFor: controlId, className: wrapperClasses, children: [linkedChildren, label] }));
|
|
78
61
|
}
|
|
79
62
|
if (layout === 'checkbox') {
|
|
80
63
|
const wrapperClasses = extra ? `flex items-center gap-2 ${extra}` : 'flex items-center gap-2';
|
|
81
|
-
|
|
64
|
+
const linkedChildren = enhanceControl(children, { id: controlId });
|
|
65
|
+
return (_jsxs("label", { htmlFor: controlId, className: wrapperClasses, children: [linkedChildren, _jsx("span", { className: labelClasses(labelTone, srOnly, false), children: label })] }));
|
|
82
66
|
}
|
|
83
67
|
if (layout === 'inline') {
|
|
84
68
|
const wrapperClasses = extra
|
|
85
69
|
? `flex min-w-0 flex-1 items-center gap-2 ${extra}`
|
|
86
70
|
: 'flex min-w-0 flex-1 items-center gap-2';
|
|
87
|
-
|
|
71
|
+
const linkedChildren = enhanceControl(children, { id: controlId });
|
|
72
|
+
return (_jsxs("label", { htmlFor: controlId, className: wrapperClasses, children: [_jsx("span", { className: labelClasses(labelTone, srOnly, true), children: label }), linkedChildren] }));
|
|
88
73
|
}
|
|
74
|
+
const resolvedDescriptionId = description != null && description !== ''
|
|
75
|
+
? (descriptionId ?? (htmlFor ? `${htmlFor}-description` : undefined))
|
|
76
|
+
: undefined;
|
|
89
77
|
const resolvedErrorId = error != null && error !== ''
|
|
90
78
|
? (errorId ?? (htmlFor ? `${htmlFor}-error` : undefined))
|
|
91
79
|
: undefined;
|
|
92
|
-
const
|
|
80
|
+
const describedByIds = [resolvedDescriptionId, resolvedErrorId].filter((id) => id != null);
|
|
81
|
+
const describedBy = describedByIds.length > 0 ? describedByIds.join(' ') : undefined;
|
|
82
|
+
const control = enhanceControl(children, {
|
|
83
|
+
describedBy,
|
|
84
|
+
invalid: resolvedErrorId != null,
|
|
85
|
+
id: htmlFor
|
|
86
|
+
});
|
|
93
87
|
const wrapperClasses = extra ? `flex flex-col gap-1 ${extra}` : 'flex flex-col gap-1';
|
|
94
|
-
return (_jsxs("div", { className: wrapperClasses, children: [_jsxs("label", { htmlFor: htmlFor, className: "flex flex-col gap-1", children: [_jsx("span", { className: labelClasses(labelTone, srOnly, false), children: label }), control,
|
|
88
|
+
return (_jsxs("div", { className: wrapperClasses, children: [_jsxs("label", { htmlFor: htmlFor, className: "flex flex-col gap-1", children: [_jsx("span", { className: labelClasses(labelTone, srOnly, false), children: label }), control, resolvedDescriptionId ? (_jsx("p", { id: resolvedDescriptionId, className: "m-0 text-[14px] text-muted", children: description })) : null] }), resolvedErrorId ? (_jsx(FieldError, { id: resolvedErrorId, spacing: "field", children: error })) : null] }));
|
|
95
89
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/KeyValueEditor/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/KeyValueEditor/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAOzD,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,IAAI,EAAE,QAAQ,EAAE,CAAC;IAEjB;;;;OAIG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IAErC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,SAAS,EAAE,QAAQ,EAAE,CAAC;IAEtB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,QAAQ,EACR,cAAsB,EACtB,gBAA0B,EAC1B,SAAS,EACT,cAAc,EACf,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA4FrB"}
|
|
@@ -3,9 +3,8 @@ import { faXmark } from '@fortawesome/free-solid-svg-icons';
|
|
|
3
3
|
import { Button } from '../Button/index.js';
|
|
4
4
|
import { FaIcon } from '../FaIcon/index.js';
|
|
5
5
|
import { Input, fieldFrame } from '../forms/index.js';
|
|
6
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader } from '../Table/index.js';
|
|
6
7
|
import { VariableInput } from '../VariableInput/index.js';
|
|
7
|
-
const thClass = 'border-r border-b border-separator p-3 text-left text-[14px] font-medium uppercase tracking-wide text-muted last:border-r-0';
|
|
8
|
-
const tdClass = 'border-r border-b border-separator p-3 last:border-r-0';
|
|
9
8
|
/**
|
|
10
9
|
* Editable table of key-value rows with enable toggles for headers and params.
|
|
11
10
|
*/
|
|
@@ -36,5 +35,5 @@ export function KeyValueEditor({ rows, onChange, placeholderKey = 'Key', placeho
|
|
|
36
35
|
}
|
|
37
36
|
onChange(rows.filter((_, i) => i !== index));
|
|
38
37
|
};
|
|
39
|
-
return (
|
|
38
|
+
return (_jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs("tr", { children: [_jsx(TableHead, { className: "w-6 p-0", children: _jsx("span", { className: "sr-only", children: "Enable" }) }), _jsx(TableHead, { children: "Key" }), _jsx(TableHead, { children: "Value" }), _jsx(TableHead, { className: "w-7 p-0" })] }) }), _jsx(TableBody, { children: rows.map((row, index) => (_jsxs("tr", { children: [_jsx(TableCell, { className: "w-6 p-1 text-center", children: _jsx(Input, { type: "checkbox", className: "app-no-drag", checked: row.enabled, onChange: (e) => updateRow(index, { enabled: e.target.checked }), "aria-label": `Enable row ${index + 1}`, title: "Enable" }) }), _jsx(TableCell, { children: _jsx(Input, { type: "text", className: "w-full", value: row.key, placeholder: placeholderKey, "aria-label": `Key, row ${index + 1}`, onChange: (e) => updateRow(index, { key: e.target.value }) }) }), _jsx(TableCell, { children: _jsx(VariableInput, { wrapperClassName: `${fieldFrame} w-full`, className: "app-no-drag", value: row.value, onChange: (value) => updateRow(index, { value }), variables: variables, placeholder: placeholderValue, "aria-label": `Value, row ${index + 1}`, onEditVariable: onEditVariable }) }), _jsx(TableCell, { className: "w-7 p-1 text-center", children: _jsx(Button, { type: "button", variant: "iconDanger", onClick: () => removeRow(index), title: "Remove", "aria-label": `Remove row ${index + 1}`, children: _jsx(FaIcon, { icon: faXmark, className: "h-3.5 w-3.5" }) }) })] }, index))) })] }));
|
|
40
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalFormLayout.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/ModalFormLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ModalFormLayout.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/ModalFormLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5C,UAAU,KAAK;IACb;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,KAAK,EACL,OAAO,EACP,aAAoB,EACrB,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAQrB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
+
import { FieldError } from '../FieldError/index.js';
|
|
2
3
|
import { ModalFooter } from './ModalFooter.js';
|
|
3
4
|
/**
|
|
4
5
|
* Stacks modal body content, an optional error block, and a trailing action footer
|
|
@@ -10,5 +11,5 @@ import { ModalFooter } from './ModalFooter.js';
|
|
|
10
11
|
* @param actionsSpaced - Whether the footer row receives `mt-4`.
|
|
11
12
|
*/
|
|
12
13
|
export function ModalFormLayout({ children, error, actions, actionsSpaced = true }) {
|
|
13
|
-
return (_jsxs(_Fragment, { children: [children, error, actions ? _jsx(ModalFooter, { spaced: actionsSpaced, children: actions }) : null] }));
|
|
14
|
+
return (_jsxs(_Fragment, { children: [children, error != null && error !== '' ? _jsx(FieldError, { spacing: "modal", children: error }) : null, actions ? _jsx(ModalFooter, { spaced: actionsSpaced, children: actions }) : null] }));
|
|
14
15
|
}
|
|
@@ -12,6 +12,10 @@ interface Props {
|
|
|
12
12
|
* Optional muted summary shown below the title.
|
|
13
13
|
*/
|
|
14
14
|
description?: ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* Id referenced by the dialog's `aria-describedby` when `description` is set.
|
|
17
|
+
*/
|
|
18
|
+
descriptionId?: string;
|
|
15
19
|
/**
|
|
16
20
|
* Extra action controls rendered before the Close button.
|
|
17
21
|
*/
|
|
@@ -29,6 +33,6 @@ interface Props {
|
|
|
29
33
|
* Modal header row with a bordered bottom edge, title block on the left,
|
|
30
34
|
* optional actions, and a close icon on the right.
|
|
31
35
|
*/
|
|
32
|
-
export declare function ModalHeader({ titleId, title, description, headerActions, closeDisabled, onClose }: Props): JSX.Element;
|
|
36
|
+
export declare function ModalHeader({ titleId, title, description, descriptionId, headerActions, closeDisabled, onClose }: Props): JSX.Element;
|
|
33
37
|
export {};
|
|
34
38
|
//# sourceMappingURL=ModalHeader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModalHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/ModalHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAK5C,UAAU,KAAK;IACb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;OAEG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,WAAW,EACX,aAAa,EACb,aAAqB,EACrB,OAAO,EACR,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"ModalHeader.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/ModalHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAK5C,UAAU,KAAK;IACb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAqB,EACrB,OAAO,EACR,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA+BrB"}
|
|
@@ -6,6 +6,6 @@ import { FaIcon } from '../FaIcon/index.js';
|
|
|
6
6
|
* Modal header row with a bordered bottom edge, title block on the left,
|
|
7
7
|
* optional actions, and a close icon on the right.
|
|
8
8
|
*/
|
|
9
|
-
export function ModalHeader({ titleId, title, description, headerActions, closeDisabled = false, onClose }) {
|
|
10
|
-
return (_jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b border-separator px-4 py-4", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h2", { id: titleId, className: "m-0 flex flex-wrap items-center gap-2 text-[17px] font-semibold text-text", children: title }), description ? _jsx("p", { className: "m-0 mt-1 text-[14px] text-muted", children: description }) : null] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [headerActions, _jsx(Button, { type: "button", variant: "icon", className: "shrink-0
|
|
9
|
+
export function ModalHeader({ titleId, title, description, descriptionId, headerActions, closeDisabled = false, onClose }) {
|
|
10
|
+
return (_jsxs("div", { className: "flex flex-wrap items-center gap-2 border-b border-separator px-4 py-4", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h2", { id: titleId, className: "m-0 flex flex-wrap items-center gap-2 text-[17px] font-semibold text-text", children: title }), description ? (_jsx("p", { id: descriptionId, className: "m-0 mt-1 text-[14px] text-muted", children: description })) : null] }), _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [headerActions, _jsx(Button, { type: "button", variant: "icon", className: "shrink-0", "aria-label": "Close", disabled: closeDisabled, onClick: onClose, children: _jsx(FaIcon, { icon: faXmark, className: "h-4 w-4" }) })] })] }));
|
|
11
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,UAAU,SAAS;IACjB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;OAEG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,KAAK,KAAK,GAAG,SAAS,GACpB,CACI;IACE;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,GACD;IACE,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CACJ,CAAC;AAEJ;;GAEG;AACH,wBAAgB,KAAK,CAAC,EACpB,OAAO,EACP,SAAkB,EAClB,gBAAgB,EAChB,aAAqB,EACrB,KAAK,EACL,WAAW,EACX,aAAa,EACb,aAAqB,EACrB,UAAU,EACV,KAAK,EACL,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Modal/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,UAAU,SAAS;IACjB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;OAEG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAE1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,KAAK,KAAK,GAAG,SAAS,GACpB,CACI;IACE;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,GACD;IACE,UAAU,CAAC,EAAE,KAAK,CAAC;IACnB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf,CACJ,CAAC;AAEJ;;GAEG;AACH,wBAAgB,KAAK,CAAC,EACpB,OAAO,EACP,SAAkB,EAClB,gBAAgB,EAChB,aAAqB,EACrB,KAAK,EACL,WAAW,EACX,aAAa,EACb,aAAqB,EACrB,UAAU,EACV,KAAK,EACL,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAyErB"}
|
|
@@ -9,7 +9,8 @@ export { ModalFormLayout } from './ModalFormLayout.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export function Modal({ onClose, className = 'w-96', overlayClassName, disableEscape = false, title, description, headerActions, closeDisabled = false, labelledBy, label, children }) {
|
|
11
11
|
const panelRef = useRef(null);
|
|
12
|
-
|
|
12
|
+
const overlayRef = useRef(null);
|
|
13
|
+
useDialogFocus(overlayRef);
|
|
13
14
|
/**
|
|
14
15
|
* Closes the modal when Escape is pressed unless disabled.
|
|
15
16
|
*/
|
|
@@ -33,5 +34,6 @@ export function Modal({ onClose, className = 'w-96', overlayClassName, disableEs
|
|
|
33
34
|
const panelClass = title
|
|
34
35
|
? `${className} flex max-h-[85vh] flex-col overflow-hidden rounded-lg border border-separator bg-surface shadow-xl`
|
|
35
36
|
: `${className} rounded-lg border border-separator bg-surface p-4 shadow-xl`;
|
|
36
|
-
|
|
37
|
+
const descriptionId = description && labelledBy ? `${labelledBy}-description` : undefined;
|
|
38
|
+
return (_jsxs("div", { ref: overlayRef, className: overlayClass, children: [_jsx("div", { ref: panelRef, role: "dialog", "aria-modal": "true", "aria-labelledby": labelledBy, "aria-describedby": descriptionId, "aria-label": label, className: `relative z-10 ${panelClass}`, onClick: (event) => event.stopPropagation(), children: title && labelledBy ? (_jsxs(_Fragment, { children: [_jsx(ModalHeader, { titleId: labelledBy, title: title, description: description, descriptionId: descriptionId, headerActions: headerActions, closeDisabled: closeDisabled, onClose: onClose }), _jsx("div", { className: "flex-1 overflow-y-auto p-4", children: children })] })) : (children) }), _jsx("button", { type: "button", tabIndex: -1, className: "absolute inset-0 z-0 cursor-default border-none bg-transparent p-0", "aria-label": "Close dialog", onClick: onClose })] }));
|
|
37
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/OverlayCloseButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAKjC,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAe,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/OverlayCloseButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAKjC,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAe,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAQ9F"}
|
|
@@ -10,7 +10,6 @@ import { FaIcon } from '../FaIcon/index.js';
|
|
|
10
10
|
* @param className - Extra classes appended after the overlay preset.
|
|
11
11
|
*/
|
|
12
12
|
export function OverlayCloseButton({ label = 'Close', onClose, className }) {
|
|
13
|
-
const
|
|
14
|
-
const classes = className ? `${base} ${className}` : base;
|
|
13
|
+
const classes = className ? `text-[28px] ${className}` : 'text-[28px]';
|
|
15
14
|
return (_jsx(Button, { type: "button", variant: "icon", className: classes, "aria-label": label, onClick: onClose, children: _jsx(FaIcon, { icon: faXmark, className: "h-4 w-4" }) }));
|
|
16
15
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
2
|
+
import type { JSX, ReactNode } from 'react';
|
|
3
|
+
interface Props {
|
|
4
|
+
/**
|
|
5
|
+
* Page heading rendered in the header row.
|
|
6
|
+
*/
|
|
7
|
+
title: string;
|
|
8
|
+
/**
|
|
9
|
+
* Optional muted summary shown below the title.
|
|
10
|
+
*/
|
|
11
|
+
description?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional decorative icon shown before the title.
|
|
14
|
+
*/
|
|
15
|
+
icon?: IconDefinition;
|
|
16
|
+
/**
|
|
17
|
+
* Action controls aligned to the right side of the header row, such as close
|
|
18
|
+
* or back buttons.
|
|
19
|
+
*/
|
|
20
|
+
actions?: ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* Optional trailing action row below the body, such as Save/Cancel footers.
|
|
23
|
+
*/
|
|
24
|
+
footer?: ReactNode;
|
|
25
|
+
/**
|
|
26
|
+
* When true, omits the scroll container and padding so the page can render
|
|
27
|
+
* inside a parent that already scrolls (for example {@link SidebarLayout}).
|
|
28
|
+
*/
|
|
29
|
+
embedded?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Additional Tailwind classes merged onto the outer wrapper.
|
|
32
|
+
*/
|
|
33
|
+
className?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Main page body content below the header.
|
|
36
|
+
*/
|
|
37
|
+
children?: ReactNode;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Full-area page shell with a {@link PageHeader}, scrollable body, and optional
|
|
41
|
+
* footer. Use the default mode for self-contained overlay pages; set
|
|
42
|
+
* `embedded` when the parent already provides scroll and padding.
|
|
43
|
+
*/
|
|
44
|
+
export declare function Page({ title, description, icon, actions, footer, embedded, className, children }: Props): JSX.Element;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Page/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5C,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IAEtB;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,OAAO,EACP,MAAM,EACN,QAAgB,EAChB,SAAS,EACT,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA+BrB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
+
import { PageHeader } from '../PageHeader/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Full-area page shell with a {@link PageHeader}, scrollable body, and optional
|
|
5
|
+
* footer. Use the default mode for self-contained overlay pages; set
|
|
6
|
+
* `embedded` when the parent already provides scroll and padding.
|
|
7
|
+
*/
|
|
8
|
+
export function Page({ title, description, icon, actions, footer, embedded = false, className, children }) {
|
|
9
|
+
const header = (_jsx(PageHeader, { title: title, description: description, icon: icon, children: actions }));
|
|
10
|
+
if (embedded) {
|
|
11
|
+
const outer = className ?? undefined;
|
|
12
|
+
return (_jsxs("div", { className: outer, children: [header, children, footer] }));
|
|
13
|
+
}
|
|
14
|
+
const outer = className
|
|
15
|
+
? `flex min-h-0 flex-1 flex-col overflow-y-auto p-6 ${className}`
|
|
16
|
+
: 'flex min-h-0 flex-1 flex-col overflow-y-auto p-6';
|
|
17
|
+
return (_jsx("div", { className: outer, children: _jsxs("div", { className: "mx-auto w-full", children: [header, children, footer] }) }));
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
2
|
+
import type { JSX } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* One entry in a {@link PageSidebar} navigation list.
|
|
5
|
+
*/
|
|
6
|
+
export interface PageSidebarItem<T extends string = string> {
|
|
7
|
+
/**
|
|
8
|
+
* Stable section identifier passed to `onSelect` when the row is activated.
|
|
9
|
+
*/
|
|
10
|
+
value: T;
|
|
11
|
+
/**
|
|
12
|
+
* Visible label for the navigation row.
|
|
13
|
+
*/
|
|
14
|
+
label: string;
|
|
15
|
+
/**
|
|
16
|
+
* Optional decorative icon shown before the label.
|
|
17
|
+
*/
|
|
18
|
+
icon?: IconDefinition;
|
|
19
|
+
}
|
|
20
|
+
interface Props<T extends string> {
|
|
21
|
+
/**
|
|
22
|
+
* Navigation entries to render in the sidebar.
|
|
23
|
+
*/
|
|
24
|
+
items: PageSidebarItem<T>[];
|
|
25
|
+
/**
|
|
26
|
+
* Currently selected section value.
|
|
27
|
+
*/
|
|
28
|
+
selected: T;
|
|
29
|
+
/**
|
|
30
|
+
* Called when the user selects a different section.
|
|
31
|
+
*
|
|
32
|
+
* @param value - Newly selected section value.
|
|
33
|
+
*/
|
|
34
|
+
onSelect: (value: T) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Accessible name for the sidebar `nav` element.
|
|
37
|
+
*/
|
|
38
|
+
ariaLabel: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Narrow sidebar navigation for multi-section pages such as settings overlays.
|
|
42
|
+
*/
|
|
43
|
+
export declare function PageSidebar<T extends string>({ items, selected, onSelect, ariaLabel }: Props<T>): JSX.Element;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,GAAG,EAAE,MAAM,OAAO,CAAC;AAGjC;;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;IAC9B;;OAEG;IACH,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5B;;OAEG;IACH,QAAQ,EAAE,CAAC,CAAC;IAEZ;;;;OAIG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAE7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAaD;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EAC5C,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,EACV,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAiCxB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
+
import { FaIcon } from '../FaIcon/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Tailwind classes for a sidebar navigation row.
|
|
5
|
+
*
|
|
6
|
+
* @param active - Whether this row is the current selection.
|
|
7
|
+
*/
|
|
8
|
+
function sidebarRow(active) {
|
|
9
|
+
return active
|
|
10
|
+
? 'group flex items-center gap-1 rounded-md bg-selection px-1.5 py-0.5 app-no-drag'
|
|
11
|
+
: 'group flex items-center gap-1 rounded-md px-1.5 py-0.5 hover:bg-selection/60 app-no-drag';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Narrow sidebar navigation for multi-section pages such as settings overlays.
|
|
15
|
+
*/
|
|
16
|
+
export function PageSidebar({ items, selected, onSelect, ariaLabel }) {
|
|
17
|
+
return (_jsx("nav", { className: "flex w-[180px] shrink-0 flex-col gap-0.5 border-r border-separator bg-sidebar px-2 py-3", "aria-label": ariaLabel, children: items.map((item) => {
|
|
18
|
+
const active = selected === item.value;
|
|
19
|
+
const rowClass = item.icon
|
|
20
|
+
? `${sidebarRow(active)} w-full gap-2 border-none text-left text-[14px] app-no-drag`
|
|
21
|
+
: `${sidebarRow(active)} w-full border-none text-left text-[14px] app-no-drag`;
|
|
22
|
+
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: `h-3.5 w-3.5 shrink-0 ${active ? 'text-text' : 'text-muted'}`, "aria-hidden": true })) : null, _jsx("span", { className: "min-w-0 truncate", children: item.label })] }, item.value));
|
|
23
|
+
}) }));
|
|
24
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Resizable.d.ts","sourceRoot":"","sources":["../../../src/components/Resizable/Resizable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAa5C,UAAU,KAAK;IACb;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,EAAE,EACF,IAAI,EACJ,OAAO,EACP,UAAU,EACV,UAAU,EACV,KAAK,EACL,UAAkB,EAClB,iBAAyB,EACzB,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"Resizable.d.ts","sourceRoot":"","sources":["../../../src/components/Resizable/Resizable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAa5C,UAAU,KAAK;IACb;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,EAAE,EACF,IAAI,EACJ,OAAO,EACP,UAAU,EACV,UAAU,EACV,KAAK,EACL,UAAkB,EAClB,iBAAyB,EACzB,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAiFrB"}
|
|
@@ -28,5 +28,5 @@ export function Resizable({ id, open, onClose, closeLabel, storageKey, title, he
|
|
|
28
28
|
});
|
|
29
29
|
const closeButton = (_jsx("button", { type: "button", className: footerPanelCloseButtonClassName, onClick: onClose, "aria-label": `Close ${closeLabel}`, children: _jsx(FaIcon, { icon: faXmark, className: "h-3.5 w-3.5" }) }));
|
|
30
30
|
const body = unmountWhenClosed && !open ? null : children;
|
|
31
|
-
return (_jsxs("div", { ref: containerRef, id: id, className: footerPanelClassName(open), style: { height }, "aria-hidden": !open, children: [_jsx(ResizeHandle, { orientation: "horizontal", value: height, min: panelMinSize, max: panelMaxSize, onResizeStart: onResizeStart, onKeyboardResize: onKeyboardResize, ariaLabel: `Resize ${closeLabel} panel` }), headerless ? (_jsxs("div", { className: "relative flex min-h-0 flex-1 flex-col overflow-hidden", children: [_jsx("button", { type: "button", className: `absolute right-2 top-2 z-10 ${footerPanelCloseButtonClassName}`, onClick: onClose, "aria-label": `Close ${closeLabel}`, children: _jsx(FaIcon, { icon: faXmark, className: "h-3.5 w-3.5" }) }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: body })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex shrink-0 items-center justify-between border-b border-separator px-3 py-2", children: [_jsx("div", { className: "min-w-0 flex-1", children: title }), closeButton] }), body] }))] }));
|
|
31
|
+
return (_jsxs("div", { ref: containerRef, id: id, className: footerPanelClassName(open), style: { height }, role: "region", "aria-label": `${closeLabel} panel`, "aria-hidden": !open, inert: !open || undefined, children: [_jsx(ResizeHandle, { orientation: "horizontal", value: height, min: panelMinSize, max: panelMaxSize, onResizeStart: onResizeStart, onKeyboardResize: onKeyboardResize, ariaLabel: `Resize ${closeLabel} panel` }), headerless ? (_jsxs("div", { className: "relative flex min-h-0 flex-1 flex-col overflow-hidden", children: [_jsx("button", { type: "button", className: `absolute right-2 top-2 z-10 ${footerPanelCloseButtonClassName}`, onClick: onClose, "aria-label": `Close ${closeLabel}`, children: _jsx(FaIcon, { icon: faXmark, className: "h-3.5 w-3.5" }) }), _jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: body })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex shrink-0 items-center justify-between border-b border-separator px-3 py-2", children: [_jsx("div", { className: "min-w-0 flex-1", children: title }), closeButton] }), body] }))] }));
|
|
32
32
|
}
|
|
@@ -5,7 +5,7 @@ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
|
|
|
5
5
|
export function ResizeHandle({ orientation, value, min, max, onResizeStart, onKeyboardResize, ariaLabel, className }) {
|
|
6
6
|
const isHorizontal = orientation === 'horizontal';
|
|
7
7
|
const containerClassName = [
|
|
8
|
-
'm-0 flex shrink-0 items-center justify-center bg-control p-0 font-inherit text-inherit
|
|
8
|
+
'm-0 flex shrink-0 items-center justify-center bg-control p-0 font-inherit text-inherit hover:bg-selection/60 app-no-drag',
|
|
9
9
|
isHorizontal
|
|
10
10
|
? 'h-1.5 w-full cursor-row-resize border-b border-separator'
|
|
11
11
|
: 'h-full w-1.5 cursor-col-resize border-r border-separator',
|
|
@@ -13,5 +13,5 @@ export function ResizeHandle({ orientation, value, min, max, onResizeStart, onKe
|
|
|
13
13
|
]
|
|
14
14
|
.filter(Boolean)
|
|
15
15
|
.join(' ');
|
|
16
|
-
return (_jsx("
|
|
16
|
+
return (_jsx("div", { role: "separator", tabIndex: 0, className: containerClassName, onMouseDown: onResizeStart, onKeyDown: onKeyboardResize, "aria-orientation": orientation, "aria-label": ariaLabel, "aria-valuenow": Math.round(value), "aria-valuemin": min, "aria-valuemax": Math.round(max), children: _jsx("div", { className: isHorizontal ? 'h-0.5 w-8 rounded-full bg-muted/50' : 'h-8 w-0.5 rounded-full bg-muted/50', "aria-hidden": true }) }));
|
|
17
17
|
}
|
|
@@ -8,14 +8,24 @@ interface ResourceListProps {
|
|
|
8
8
|
* Additional Tailwind classes merged onto the list element.
|
|
9
9
|
*/
|
|
10
10
|
className?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Accessible name when no visible heading labels the list.
|
|
13
|
+
*/
|
|
14
|
+
'aria-label'?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Id of the element that labels this list when using a visible heading.
|
|
17
|
+
*/
|
|
18
|
+
'aria-labelledby'?: string;
|
|
11
19
|
}
|
|
12
20
|
/**
|
|
13
21
|
* Vertical list shell used for bordered resource rows in settings and Team Hub.
|
|
14
22
|
*
|
|
15
23
|
* @param children - List item elements.
|
|
16
24
|
* @param className - Extra classes appended after the layout preset.
|
|
25
|
+
* @param aria-label - Accessible name when surrounding context does not name the list.
|
|
26
|
+
* @param aria-labelledby - Id of a visible heading that names the list.
|
|
17
27
|
*/
|
|
18
|
-
export declare function ResourceList({ children, className }: ResourceListProps): JSX.Element;
|
|
28
|
+
export declare function ResourceList({ children, className, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy }: ResourceListProps): JSX.Element;
|
|
19
29
|
interface ResourceListRowProps {
|
|
20
30
|
/**
|
|
21
31
|
* Primary title or name for the resource.
|
|
@@ -1 +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;
|
|
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;IAEnB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,SAAS,EACT,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EAClC,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CASjC;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"}
|
|
@@ -4,11 +4,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
|
4
4
|
*
|
|
5
5
|
* @param children - List item elements.
|
|
6
6
|
* @param className - Extra classes appended after the layout preset.
|
|
7
|
+
* @param aria-label - Accessible name when surrounding context does not name the list.
|
|
8
|
+
* @param aria-labelledby - Id of a visible heading that names the list.
|
|
7
9
|
*/
|
|
8
|
-
export function ResourceList({ children, className }) {
|
|
10
|
+
export function ResourceList({ children, className, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy }) {
|
|
9
11
|
const base = 'm-0 flex list-none flex-col gap-2 p-0';
|
|
10
12
|
const classes = className ? `${base} ${className}` : base;
|
|
11
|
-
return _jsx("ul", { className: classes, children: children });
|
|
13
|
+
return (_jsx("ul", { className: classes, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, children: children }));
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* Bordered list row with primary text, optional secondary line, metadata, and actions.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RowActionsMenu/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RowActionsMenu/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAMhD,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;AAkBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA+O/F"}
|