@harborclient/sdk 1.3.6 → 1.3.8
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 +10 -0
- package/dist/components/Breadcrumb/SegmentShell.d.ts +2 -2
- package/dist/components/Breadcrumb/SegmentShell.d.ts.map +1 -1
- package/dist/components/Breadcrumb/SegmentShell.js +5 -5
- package/dist/components/Breadcrumb/index.d.ts +2 -2
- package/dist/components/Breadcrumb/index.d.ts.map +1 -1
- package/dist/components/Breadcrumb/index.js +3 -5
- package/dist/components/FloatingDialog/index.d.ts +0 -4
- package/dist/components/FloatingDialog/index.d.ts.map +1 -1
- package/dist/components/FloatingDialog/index.js +1 -5
- package/dist/components/FooterPanel/index.d.ts +6 -1
- package/dist/components/FooterPanel/index.d.ts.map +1 -1
- package/dist/components/FooterPanel/index.js +2 -2
- package/dist/components/Resizable/Resizable.d.ts +6 -1
- package/dist/components/Resizable/Resizable.d.ts.map +1 -1
- package/dist/components/Resizable/Resizable.js +2 -2
- package/dist/components/Sidebar/index.d.ts +9 -1
- package/dist/components/Sidebar/index.d.ts.map +1 -1
- package/dist/components/Sidebar/index.js +2 -2
- package/dist/components/SidebarItem/SidebarWebsiteItem.d.ts +49 -0
- package/dist/components/SidebarItem/SidebarWebsiteItem.d.ts.map +1 -0
- package/dist/components/SidebarItem/SidebarWebsiteItem.js +41 -0
- package/dist/components/SidebarItem/index.d.ts +1 -0
- package/dist/components/SidebarItem/index.d.ts.map +1 -1
- package/dist/components/SidebarItem/index.js +1 -0
- package/dist/components/SidebarRail/SidebarRailItem.d.ts +66 -0
- package/dist/components/SidebarRail/SidebarRailItem.d.ts.map +1 -0
- package/dist/components/SidebarRail/SidebarRailItem.js +59 -0
- package/dist/components/SidebarRail/SidebarRailSeparator.d.ts +11 -0
- package/dist/components/SidebarRail/SidebarRailSeparator.d.ts.map +1 -0
- package/dist/components/SidebarRail/SidebarRailSeparator.js +12 -0
- package/dist/components/SidebarRail/index.d.ts +49 -0
- package/dist/components/SidebarRail/index.d.ts.map +1 -0
- package/dist/components/SidebarRail/index.js +66 -0
- package/dist/components/TabBar/TabContextMenu.d.ts +5 -1
- package/dist/components/TabBar/TabContextMenu.d.ts.map +1 -1
- package/dist/components/TabBar/TabContextMenu.js +2 -2
- package/dist/components/classes.js +2 -2
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -1
- package/dist/runtime/createBridgedPluginContext.js +58 -1
- package/dist/snippets.d.ts +6 -0
- package/dist/types.d.ts +143 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.3.8 - 2026-07-30
|
|
8
|
+
|
|
9
|
+
- Add browser-related features and tests. (`2f8eb307`)
|
|
10
|
+
|
|
11
|
+
## 1.3.7 - 2026-07-29
|
|
12
|
+
|
|
13
|
+
- Implement workflow run history management and UI enhancements. (`c87feda3`)
|
|
14
|
+
- Enhance development and testing workflow in AGENTS.md and CONTRIBUTING.md. (`181dc04a`)
|
|
15
|
+
- Refactor styling in WorkflowRecordingDialog and TimelineBlock components. (`3f0b9348`)
|
|
16
|
+
|
|
7
17
|
## 1.3.6 - 2026-07-29
|
|
8
18
|
|
|
9
19
|
- Enhance Response Editor and Summary with Close Functionality. (`e14d7c7d`)
|
|
@@ -50,8 +50,8 @@ interface Props {
|
|
|
50
50
|
* Renders the arrow-shaped background shell shared by crumb and editable segments.
|
|
51
51
|
*
|
|
52
52
|
* First and only shapes use an overflow-hidden rounded wrapper so the left (or
|
|
53
|
-
* full) edge
|
|
54
|
-
* clip-path layer for chevron interlocking.
|
|
53
|
+
* full) edge matches the URL bar's `rounded-md` corners; middle and last keep a
|
|
54
|
+
* single clip-path layer for chevron interlocking.
|
|
55
55
|
*/
|
|
56
56
|
export declare function SegmentShell({ shape, tone, grow, density, className, children }: Props): JSX.Element;
|
|
57
57
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SegmentShell.d.ts","sourceRoot":"","sources":["../../../src/components/Breadcrumb/SegmentShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAM5C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,CAAC;AAsBnD;;GAEG;AACH,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAa,EACb,IAAY,EACZ,OAAmB,EACnB,SAAS,EACT,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"SegmentShell.d.ts","sourceRoot":"","sources":["../../../src/components/Breadcrumb/SegmentShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAM5C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,CAAC;AAsBnD;;GAEG;AACH,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,IAAa,EACb,IAAY,EACZ,OAAmB,EACnB,SAAS,EACT,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA8DrB"}
|
|
@@ -25,8 +25,8 @@ function clipPathForShape(shape) {
|
|
|
25
25
|
* Renders the arrow-shaped background shell shared by crumb and editable segments.
|
|
26
26
|
*
|
|
27
27
|
* First and only shapes use an overflow-hidden rounded wrapper so the left (or
|
|
28
|
-
* full) edge
|
|
29
|
-
* clip-path layer for chevron interlocking.
|
|
28
|
+
* full) edge matches the URL bar's `rounded-md` corners; middle and last keep a
|
|
29
|
+
* single clip-path layer for chevron interlocking.
|
|
30
30
|
*/
|
|
31
31
|
export function SegmentShell({ shape, tone = 'path', grow = false, density = 'default', className, children }) {
|
|
32
32
|
const hasChevron = shape !== 'only';
|
|
@@ -38,12 +38,12 @@ export function SegmentShell({ shape, tone = 'path', grow = false, density = 'de
|
|
|
38
38
|
: tone === 'selection'
|
|
39
39
|
? 'bg-selection'
|
|
40
40
|
: 'bg-breadcrumb-segment';
|
|
41
|
-
const
|
|
41
|
+
const usesRoundedCap = shape === 'first' || shape === 'only';
|
|
42
42
|
const leadingInsetPx = CHEVRON_PX + (isCompact ? 10 : 16);
|
|
43
43
|
const layoutClass = cn('hc-breadcrumb-segment relative flex min-w-0 items-center', isCompact ? 'min-h-0 py-1' : 'min-h-[26px] py-2', grow ? 'min-w-[6rem] flex-1' : isCompact ? 'shrink-0' : 'max-w-[45%] shrink-0', hasChevron && shape !== 'last' && '-mr-[6px]', !needsLeadingInset && (isCompact ? 'pl-2.5' : 'pl-5'), isCompact ? 'pr-3' : 'pr-5', className);
|
|
44
44
|
const content = (_jsx("div", { className: cn('relative min-w-0', isCompact ? 'flex items-center gap-1.5' : 'w-full truncate'), children: children }));
|
|
45
|
-
if (
|
|
46
|
-
return (_jsxs("div", { className: cn(layoutClass, 'overflow-hidden',
|
|
45
|
+
if (usesRoundedCap) {
|
|
46
|
+
return (_jsxs("div", { className: cn(layoutClass, 'overflow-hidden', 'rounded-md!'), style: needsLeadingInset ? { paddingLeft: `${leadingInsetPx}px` } : undefined, children: [_jsx("div", { "aria-hidden": true, className: cn('pointer-events-none absolute inset-0', toneClass), style: clipPath !== 'none' ? { clipPath } : undefined }), content] }));
|
|
47
47
|
}
|
|
48
48
|
return (_jsx("div", { className: cn(layoutClass, toneClass), style: {
|
|
49
49
|
...(clipPath !== 'none' ? { clipPath } : {}),
|
|
@@ -35,8 +35,8 @@ interface Props {
|
|
|
35
35
|
/**
|
|
36
36
|
* Full-width breadcrumb bar with interlocking arrow-shaped segments. Leading
|
|
37
37
|
* segments are optionally clickable; the trailing segment is inline-editable.
|
|
38
|
-
* The track background is clipped to the segments'
|
|
39
|
-
* rounded
|
|
38
|
+
* The track background is clipped to the segments' silhouette so the
|
|
39
|
+
* `rounded-md` ends read against the surrounding surface instead of a square band.
|
|
40
40
|
*/
|
|
41
41
|
export declare function Breadcrumb({ segments, value, placeholder, editableLabel, onValueChange, className, flush }: Props): JSX.Element;
|
|
42
42
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Breadcrumb/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAsC,MAAM,OAAO,CAAC;AAKrE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,UAAU,KAAK;IACb;;OAEG;IACH,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,KAAK,EACL,WAAgB,EAChB,aAAsB,EACtB,aAAa,EACb,SAAS,EACT,KAAa,EACd,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Breadcrumb/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAsC,MAAM,OAAO,CAAC;AAKrE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,UAAU,KAAK;IACb;;OAEG;IACH,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,KAAK,EACL,WAAgB,EAChB,aAAsB,EACtB,aAAa,EACb,SAAS,EACT,KAAa,EACd,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA2DrB"}
|
|
@@ -6,8 +6,8 @@ import { EditableSegment } from './EditableSegment.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* Full-width breadcrumb bar with interlocking arrow-shaped segments. Leading
|
|
8
8
|
* segments are optionally clickable; the trailing segment is inline-editable.
|
|
9
|
-
* The track background is clipped to the segments'
|
|
10
|
-
* rounded
|
|
9
|
+
* The track background is clipped to the segments' silhouette so the
|
|
10
|
+
* `rounded-md` ends read against the surrounding surface instead of a square band.
|
|
11
11
|
*/
|
|
12
12
|
export function Breadcrumb({ segments, value, placeholder = '', editableLabel = 'Name', onValueChange, className, flush = false }) {
|
|
13
13
|
const [editing, setEditing] = useState(false);
|
|
@@ -36,7 +36,5 @@ export function Breadcrumb({ segments, value, placeholder = '', editableLabel =
|
|
|
36
36
|
return 'middle';
|
|
37
37
|
};
|
|
38
38
|
const editableShape = segments.length === 0 ? 'only' : 'last';
|
|
39
|
-
return (_jsxs("nav", { id: navId, "aria-label": "Breadcrumb", className: cn('hc-breadcrumb flex min-w-0 items-stretch bg-breadcrumb-background', flush
|
|
40
|
-
? '-mx-3 -mt-3 w-[calc(100%+1.5rem)]'
|
|
41
|
-
: cn('w-full overflow-hidden', editableShape === 'only' ? 'rounded-full' : 'rounded-l-full'), className), children: [segments.map((segment, index) => (_jsx(CrumbSegment, { segment: segment, shape: leadingShape(index) }, segment.id ?? `${segment.label}-${index}`))), _jsx(EditableSegment, { value: value, placeholder: placeholder, editableLabel: editableLabel, editing: editing, shape: editableShape, inputRef: inputRef, onStartEditing: () => setEditing(true), onStopEditing: () => setEditing(false), onValueChange: onValueChange })] }));
|
|
39
|
+
return (_jsxs("nav", { id: navId, "aria-label": "Breadcrumb", className: cn('hc-breadcrumb flex min-w-0 items-stretch bg-breadcrumb-background', flush ? '-mx-3 -mt-3 w-[calc(100%+1.5rem)]' : 'w-full overflow-hidden rounded-md', className), children: [segments.map((segment, index) => (_jsx(CrumbSegment, { segment: segment, shape: leadingShape(index) }, segment.id ?? `${segment.label}-${index}`))), _jsx(EditableSegment, { value: value, placeholder: placeholder, editableLabel: editableLabel, editing: editing, shape: editableShape, inputRef: inputRef, onStartEditing: () => setEditing(true), onStopEditing: () => setEditing(false), onValueChange: onValueChange })] }));
|
|
42
40
|
}
|
|
@@ -87,10 +87,6 @@ interface Props {
|
|
|
87
87
|
* `onPositionChange` / `onSizeChange`. If the panel would open or remain
|
|
88
88
|
* off-screen after a window resize, it relocates to the default corner.
|
|
89
89
|
*
|
|
90
|
-
* Uses the elevated `bg-control` fill (not `bg-surface`) with a stronger border
|
|
91
|
-
* and theme-aware shadow so the panel stays readable against the app chrome in
|
|
92
|
-
* both light and dark themes.
|
|
93
|
-
*
|
|
94
90
|
* @param props - Dialog labelling, geometry, and content props.
|
|
95
91
|
* @returns Floating dialog element.
|
|
96
92
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FloatingDialog/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAqD,SAAS,EAAE,MAAM,OAAO,CAAC;AAE/F,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EAExB,MAAM,6BAA6B,CAAC;AAErC,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAE9D;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAElD;;OAEG;IACH,UAAU,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAuCD
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FloatingDialog/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAqD,SAAS,EAAE,MAAM,OAAO,CAAC;AAE/F,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EAExB,MAAM,6BAA6B,CAAC;AAErC,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAE9D;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAElD;;OAEG;IACH,UAAU,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAuCD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,UAAU,EACV,OAAO,EACP,aAAqB,EACrB,SAAS,EACT,aAAa,EACb,WAA0C,EAC1C,UAAwC,EACxC,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,QAAc,EACd,SAAe,EACf,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,UAAU,EACV,QAAQ,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA+VrB"}
|
|
@@ -37,10 +37,6 @@ function clampFloatingDialogSize(width, height, left, top, minWidth, minHeight,
|
|
|
37
37
|
* `onPositionChange` / `onSizeChange`. If the panel would open or remain
|
|
38
38
|
* off-screen after a window resize, it relocates to the default corner.
|
|
39
39
|
*
|
|
40
|
-
* Uses the elevated `bg-control` fill (not `bg-surface`) with a stronger border
|
|
41
|
-
* and theme-aware shadow so the panel stays readable against the app chrome in
|
|
42
|
-
* both light and dark themes.
|
|
43
|
-
*
|
|
44
40
|
* @param props - Dialog labelling, geometry, and content props.
|
|
45
41
|
* @returns Floating dialog element.
|
|
46
42
|
*/
|
|
@@ -271,7 +267,7 @@ export function FloatingDialog({ label, labelledBy, onClose, disableEscape = fal
|
|
|
271
267
|
setSize(next);
|
|
272
268
|
onSizeChangeRef.current?.(next);
|
|
273
269
|
}, [maxHeight, maxWidth, minHeight, minWidth, size]);
|
|
274
|
-
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-
|
|
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: {
|
|
275
271
|
left: position.left,
|
|
276
272
|
top: position.top,
|
|
277
273
|
...(size != null ? { width: size.width, height: size.height } : {})
|
|
@@ -41,10 +41,15 @@ interface Props {
|
|
|
41
41
|
* When true, does not render children while the panel is closed.
|
|
42
42
|
*/
|
|
43
43
|
unmountWhenClosed?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Id of a visible heading that names this panel region. When set, forwarded
|
|
46
|
+
* to {@link Resizable} as `aria-labelledby`.
|
|
47
|
+
*/
|
|
48
|
+
labelledBy?: string;
|
|
44
49
|
}
|
|
45
50
|
/**
|
|
46
51
|
* Resizable panel that slides up from the footer.
|
|
47
52
|
*/
|
|
48
|
-
export declare function FooterPanel({ id, title, badge, description, closeLabel, storageKey, buttons, open, onClose, children, unmountWhenClosed }: Props): JSX.Element;
|
|
53
|
+
export declare function FooterPanel({ id, title, badge, description, closeLabel, storageKey, buttons, open, onClose, children, unmountWhenClosed, labelledBy }: Props): JSX.Element;
|
|
49
54
|
export {};
|
|
50
55
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FooterPanel/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAIxC,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;IAE5B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/FooterPanel/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AAIxC,UAAU,KAAK;IACb,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAE9B;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;IAE5B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,EAAE,EACF,KAAK,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,UAAU,EACV,OAAO,EACP,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,iBAAyB,EACzB,UAAU,EACX,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAwCrB"}
|
|
@@ -5,7 +5,7 @@ import { RoundButton } from '../RoundButton/index.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* Resizable panel that slides up from the footer.
|
|
7
7
|
*/
|
|
8
|
-
export function FooterPanel({ id, title, badge, description, closeLabel, storageKey, buttons, open, onClose, children, unmountWhenClosed = false }) {
|
|
8
|
+
export function FooterPanel({ id, title, badge, description, closeLabel, storageKey, buttons, open, onClose, children, unmountWhenClosed = false, labelledBy }) {
|
|
9
9
|
const closeButton = (_jsx(RoundButton, { icon: faXmark, title: "Close", ariaLabel: `Close ${closeLabel}`, onClick: onClose, className: "hc-footer-panel-close" }));
|
|
10
|
-
return (_jsxs(Resizable, { id: id, open: open, onClose: onClose, closeLabel: closeLabel, storageKey: storageKey, unmountWhenClosed: unmountWhenClosed, showCloseButton: false, headerless: true, children: [_jsxs("div", { className: "hc-footer-panel flex shrink-0 items-center justify-between border-b border-separator px-3 py-2", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 font-medium text-text", children: [title, badge && _jsx("span", { className: "hc-footer-panel-badge font-normal text-muted", children: badge })] }), description && _jsx("span", { className: "truncate text-muted", children: description })] }), _jsxs("div", { className: "flex gap-2", children: [buttons, closeButton] })] }), _jsx("div", { className: "hc-footer-panel-body min-h-0 flex-1 overflow-auto", children: children })] }));
|
|
10
|
+
return (_jsxs(Resizable, { id: id, open: open, onClose: onClose, closeLabel: closeLabel, storageKey: storageKey, unmountWhenClosed: unmountWhenClosed, labelledBy: labelledBy, showCloseButton: false, headerless: true, children: [_jsxs("div", { className: "hc-footer-panel flex shrink-0 items-center justify-between border-b border-separator px-3 py-2", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 font-medium text-text", children: [title, badge && _jsx("span", { className: "hc-footer-panel-badge font-normal text-muted", children: badge })] }), description && _jsx("span", { className: "truncate text-muted", children: description })] }), _jsxs("div", { className: "flex gap-2", children: [buttons, closeButton] })] }), _jsx("div", { className: "hc-footer-panel-body min-h-0 flex-1 overflow-auto", children: children })] }));
|
|
11
11
|
}
|
|
@@ -36,6 +36,11 @@ interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'id'
|
|
|
36
36
|
* Whether or not to show the close button.
|
|
37
37
|
*/
|
|
38
38
|
showCloseButton?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Id of a visible heading that names this panel region. When set, used as
|
|
41
|
+
* `aria-labelledby` instead of the default `aria-label`.
|
|
42
|
+
*/
|
|
43
|
+
labelledBy?: string;
|
|
39
44
|
/**
|
|
40
45
|
* Panel body content.
|
|
41
46
|
*/
|
|
@@ -47,6 +52,6 @@ interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'id'
|
|
|
47
52
|
* Encapsulates resize handle wiring, height persistence, open/close animation,
|
|
48
53
|
* and close affordance shared by Console, Variables, and plugin footer panels.
|
|
49
54
|
*/
|
|
50
|
-
export declare function Resizable({ id, open, onClose, closeLabel, storageKey, title, headerless, unmountWhenClosed, showCloseButton, children, className, ...props }: Props): JSX.Element;
|
|
55
|
+
export declare function Resizable({ id, open, onClose, closeLabel, storageKey, title, headerless, unmountWhenClosed, showCloseButton, labelledBy, children, className, ...props }: Props): JSX.Element;
|
|
51
56
|
export {};
|
|
52
57
|
//# sourceMappingURL=Resizable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Resizable.d.ts","sourceRoot":"","sources":["../../../src/components/Resizable/Resizable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYtE,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC;IACxF;;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,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;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,eAAsB,EACtB,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"Resizable.d.ts","sourceRoot":"","sources":["../../../src/components/Resizable/Resizable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAYtE,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC;IACxF;;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,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;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,eAAsB,EACtB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAiFrB"}
|
|
@@ -12,7 +12,7 @@ import { useResizable } from './useResizable.js';
|
|
|
12
12
|
* Encapsulates resize handle wiring, height persistence, open/close animation,
|
|
13
13
|
* and close affordance shared by Console, Variables, and plugin footer panels.
|
|
14
14
|
*/
|
|
15
|
-
export function Resizable({ id, open, onClose, closeLabel, storageKey, title, headerless = false, unmountWhenClosed = false, showCloseButton = true, children, className, ...props }) {
|
|
15
|
+
export function Resizable({ id, open, onClose, closeLabel, storageKey, title, headerless = false, unmountWhenClosed = false, showCloseButton = true, labelledBy, children, className, ...props }) {
|
|
16
16
|
const containerRef = useRef(null);
|
|
17
17
|
/**
|
|
18
18
|
* Keeps max-size measurement stable across re-renders so useResizable
|
|
@@ -29,5 +29,5 @@ export function Resizable({ id, open, onClose, closeLabel, storageKey, title, he
|
|
|
29
29
|
});
|
|
30
30
|
const closeButton = (_jsx(RoundButton, { icon: faXmark, ariaLabel: `Close ${closeLabel}`, onClick: onClose, className: "hc-resizable-close" }));
|
|
31
31
|
const body = unmountWhenClosed && !open ? null : children;
|
|
32
|
-
return (_jsxs("div", { ref: containerRef, ...props, id: id, className: cn('hc-resizable', footerPanelClassName(open), className), style: { height }, role: "region", "aria-label": `${closeLabel} panel
|
|
32
|
+
return (_jsxs("div", { ref: containerRef, ...props, id: id, className: cn('hc-resizable', footerPanelClassName(open), className), style: { height }, role: "region", "aria-labelledby": labelledBy, "aria-label": labelledBy == null ? `${closeLabel} panel` : undefined, "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: "hc-resizable-headerless relative flex min-h-0 flex-1 flex-col overflow-hidden", children: [showCloseButton && (_jsx(RoundButton, { icon: faXmark, ariaLabel: `Close ${closeLabel}`, onClick: onClose, className: "hc-resizable-headerless-close absolute top-2 right-2 z-10" })), _jsx("div", { className: "hc-resizable-body flex min-h-0 flex-1 flex-col", children: body })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "hc-resizable-header flex shrink-0 items-center justify-between border-b border-separator px-3 py-2", children: [_jsx("div", { className: "hc-resizable-header-title min-w-0 flex-1", children: title }), showCloseButton && closeButton] }), body] }))] }));
|
|
33
33
|
}
|
|
@@ -36,6 +36,14 @@ interface Props {
|
|
|
36
36
|
* Additional classes for the scrollable body wrapper.
|
|
37
37
|
*/
|
|
38
38
|
bodyClassName?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Optional id for the body wrapper (e.g. rail `aria-controls` target).
|
|
41
|
+
*/
|
|
42
|
+
bodyId?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Optional ARIA role for the body wrapper (e.g. `tabpanel` with a rail tablist).
|
|
45
|
+
*/
|
|
46
|
+
bodyRole?: string;
|
|
39
47
|
/**
|
|
40
48
|
* Additional classes for the resizable aside element.
|
|
41
49
|
*/
|
|
@@ -70,6 +78,6 @@ interface Props {
|
|
|
70
78
|
*
|
|
71
79
|
* Left sidebars render `[aside][handle]`; right sidebars render `[handle][aside]`.
|
|
72
80
|
*/
|
|
73
|
-
export declare function Sidebar({ side, ariaLabel, header, children, scroll, scrollAxis, scrollbarAutoHide, bodyClassName, asideClassName, resizeHandleClassName, resizeAriaLabel, defaultSize, minSize, getMaxSize, storageKey }: Props): JSX.Element;
|
|
81
|
+
export declare function Sidebar({ side, ariaLabel, header, children, scroll, scrollAxis, scrollbarAutoHide, bodyClassName, bodyId, bodyRole, asideClassName, resizeHandleClassName, resizeAriaLabel, defaultSize, minSize, getMaxSize, storageKey }: Props): JSX.Element;
|
|
74
82
|
export {};
|
|
75
83
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Sidebar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKjD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;IAEhD;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;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,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,MAAa,EACb,UAAuB,EACvB,iBAAwB,EACxB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACX,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Sidebar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKjD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;IAEhD;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;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,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,MAAa,EACb,UAAuB,EACvB,iBAAwB,EACxB,aAAa,EACb,MAAM,EACN,QAAQ,EACR,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACX,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAsFrB"}
|
|
@@ -7,7 +7,7 @@ import { cn } from '../utils.js';
|
|
|
7
7
|
*
|
|
8
8
|
* Left sidebars render `[aside][handle]`; right sidebars render `[handle][aside]`.
|
|
9
9
|
*/
|
|
10
|
-
export function Sidebar({ side, ariaLabel, header, children, scroll = true, scrollAxis = 'vertical', scrollbarAutoHide = true, bodyClassName, asideClassName, resizeHandleClassName, resizeAriaLabel, defaultSize, minSize, getMaxSize, storageKey }) {
|
|
10
|
+
export function Sidebar({ side, ariaLabel, header, children, scroll = true, scrollAxis = 'vertical', scrollbarAutoHide = true, bodyClassName, bodyId, bodyRole, asideClassName, resizeHandleClassName, resizeAriaLabel, defaultSize, minSize, getMaxSize, storageKey }) {
|
|
11
11
|
const resizableOptions = {
|
|
12
12
|
axis: 'x',
|
|
13
13
|
direction: side === 'left' ? 1 : -1,
|
|
@@ -23,7 +23,7 @@ export function Sidebar({ side, ariaLabel, header, children, scroll = true, scro
|
|
|
23
23
|
* scroll viewport height while still allowing overflow scroll when content grows.
|
|
24
24
|
*/
|
|
25
25
|
const scrollBody = _jsx("div", { className: "flex min-h-full min-w-0 flex-col", children: children });
|
|
26
|
-
const body = scroll ? (_jsx(Scrollbars, { axis: scrollAxis, autoHide: scrollbarAutoHide, className: cn('min-h-0 flex-1', bodyClassName), children: scrollBody })) : (_jsx("div", { className: cn('flex min-h-0 flex-1 flex-col', bodyClassName), children: children }));
|
|
26
|
+
const body = scroll ? (_jsx(Scrollbars, { id: bodyId, role: bodyRole, axis: scrollAxis, autoHide: scrollbarAutoHide, className: cn('min-h-0 flex-1', bodyClassName), children: scrollBody })) : (_jsx("div", { id: bodyId, role: bodyRole, className: cn('flex min-h-0 flex-1 flex-col', bodyClassName), children: children }));
|
|
27
27
|
const aside = (_jsxs("aside", { className: cn('hc-sidebar flex shrink-0 flex-col overflow-x-hidden bg-sidebar', side === 'right' && 'h-full min-h-0', asideClassName), style: { width }, "aria-label": ariaLabel, children: [header, body] }));
|
|
28
28
|
if (side === 'left') {
|
|
29
29
|
return (_jsxs(_Fragment, { children: [aside, handle] }));
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
2
|
+
import { type JSX, type MouseEvent, type ReactNode } from 'react';
|
|
3
|
+
interface Props {
|
|
4
|
+
/**
|
|
5
|
+
* Website display name (last page title).
|
|
6
|
+
*/
|
|
7
|
+
name: string;
|
|
8
|
+
/**
|
|
9
|
+
* Favicon data URL when available; globe fallback when missing or broken.
|
|
10
|
+
*/
|
|
11
|
+
faviconDataUrl?: string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Globe (or other) icon used when no favicon is available.
|
|
14
|
+
*/
|
|
15
|
+
fallbackIcon: IconDefinition;
|
|
16
|
+
/**
|
|
17
|
+
* Whether this row is part of a multi-selection or is the active open website.
|
|
18
|
+
*/
|
|
19
|
+
selected?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Called when the user right-clicks the row container.
|
|
22
|
+
*/
|
|
23
|
+
onContextMenu?: (event: MouseEvent<HTMLElement>) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Called when the primary row area is activated.
|
|
26
|
+
*/
|
|
27
|
+
onClick?: (event: MouseEvent<HTMLElement>) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Called when Enter is pressed on the primary row area.
|
|
30
|
+
*/
|
|
31
|
+
onEnter?: () => void;
|
|
32
|
+
/**
|
|
33
|
+
* Trailing actions slot, typically a row actions menu.
|
|
34
|
+
*/
|
|
35
|
+
actions?: ReactNode;
|
|
36
|
+
/**
|
|
37
|
+
* HTML element for the row container. Use `li` inside {@link SidebarListbox}.
|
|
38
|
+
*/
|
|
39
|
+
as?: 'div' | 'li';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Renders a website row in the Collections sidebar Websites section.
|
|
43
|
+
*
|
|
44
|
+
* Shows the site favicon when available, otherwise a globe fallback icon, plus
|
|
45
|
+
* the last known page title.
|
|
46
|
+
*/
|
|
47
|
+
export declare function SidebarWebsiteItem({ name, faviconDataUrl, fallbackIcon, selected, onContextMenu, onClick, onEnter, actions, as }: Props): JSX.Element;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=SidebarWebsiteItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SidebarWebsiteItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarWebsiteItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,KAAK,GAAG,EAAsB,KAAK,UAAU,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAKhG,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/B;;OAEG;IACH,YAAY,EAAE,cAAc,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,cAAc,EACd,YAAY,EACZ,QAAgB,EAChB,aAAa,EACb,OAAO,EACP,OAAO,EACP,OAAO,EACP,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA0DrB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { FaIcon } from '../FaIcon/index.js';
|
|
4
|
+
import { SidebarItem } from './SidebarItem.js';
|
|
5
|
+
import { SIDEBAR_ITEM_BUTTON_CLASS } from './sidebarItemClasses.js';
|
|
6
|
+
/**
|
|
7
|
+
* Renders a website row in the Collections sidebar Websites section.
|
|
8
|
+
*
|
|
9
|
+
* Shows the site favicon when available, otherwise a globe fallback icon, plus
|
|
10
|
+
* the last known page title.
|
|
11
|
+
*/
|
|
12
|
+
export function SidebarWebsiteItem({ name, faviconDataUrl, fallbackIcon, selected = false, onContextMenu, onClick, onEnter, actions, as = 'li' }) {
|
|
13
|
+
const useListboxOption = as === 'li';
|
|
14
|
+
const [brokenFaviconUrl, setBrokenFaviconUrl] = useState(null);
|
|
15
|
+
const showFavicon = Boolean(faviconDataUrl) && brokenFaviconUrl !== faviconDataUrl;
|
|
16
|
+
/**
|
|
17
|
+
* Opens the website when Enter is pressed on the row.
|
|
18
|
+
*/
|
|
19
|
+
const handleKeyDown = (event) => {
|
|
20
|
+
if (event.key !== 'Enter' || onEnter == null) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
event.preventDefault();
|
|
24
|
+
event.stopPropagation();
|
|
25
|
+
onEnter();
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Marks the current favicon as unloadable so the globe fallback is shown.
|
|
29
|
+
*/
|
|
30
|
+
const handleFaviconError = () => {
|
|
31
|
+
if (faviconDataUrl) {
|
|
32
|
+
setBrokenFaviconUrl(faviconDataUrl);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return (_jsx(SidebarItem, { selected: selected, onContextMenu: onContextMenu, actions: actions, as: as, listboxOption: useListboxOption
|
|
36
|
+
? {
|
|
37
|
+
onClick,
|
|
38
|
+
onKeyDown: onEnter != null ? handleKeyDown : undefined
|
|
39
|
+
}
|
|
40
|
+
: undefined, children: _jsxs("span", { className: `${SIDEBAR_ITEM_BUTTON_CLASS} gap-2 rounded-md px-2 py-1`, children: [showFavicon && faviconDataUrl ? (_jsx("img", { src: faviconDataUrl, alt: "", "aria-hidden": true, className: "h-3.5 w-3.5 shrink-0 object-contain", onError: handleFaviconError })) : (_jsx(FaIcon, { icon: fallbackIcon, className: "h-3.5 w-3.5 shrink-0 text-muted", "aria-hidden": true })), _jsx("span", { className: "min-w-0 flex-1 truncate", children: name })] }) }));
|
|
41
|
+
}
|
|
@@ -19,5 +19,6 @@ export { SidebarRunItem } from './SidebarRunItem.js';
|
|
|
19
19
|
export { SidebarHistoryItem } from './SidebarHistoryItem.js';
|
|
20
20
|
export { SidebarEnvironmentItem } from './SidebarEnvironmentItem.js';
|
|
21
21
|
export { SidebarWorkspaceItem } from './SidebarWorkspaceItem.js';
|
|
22
|
+
export { SidebarWebsiteItem } from './SidebarWebsiteItem.js';
|
|
22
23
|
export { SidebarCommitItem, type SidebarCommitPushStatus } from './SidebarCommitItem.js';
|
|
23
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,kCAAkC,EACnC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,yBAAyB,EACzB,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,kCAAkC,EACnC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -19,4 +19,5 @@ export { SidebarRunItem } from './SidebarRunItem.js';
|
|
|
19
19
|
export { SidebarHistoryItem } from './SidebarHistoryItem.js';
|
|
20
20
|
export { SidebarEnvironmentItem } from './SidebarEnvironmentItem.js';
|
|
21
21
|
export { SidebarWorkspaceItem } from './SidebarWorkspaceItem.js';
|
|
22
|
+
export { SidebarWebsiteItem } from './SidebarWebsiteItem.js';
|
|
22
23
|
export { SidebarCommitItem } from './SidebarCommitItem.js';
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
|
2
|
+
import type { JSX, KeyboardEvent, Ref } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* One entry in a {@link SidebarRail} navigation list.
|
|
5
|
+
*/
|
|
6
|
+
export interface SidebarRailItemData {
|
|
7
|
+
/**
|
|
8
|
+
* Stable identifier passed to `onSelect` when the item is activated.
|
|
9
|
+
*/
|
|
10
|
+
id: string;
|
|
11
|
+
/**
|
|
12
|
+
* Font Awesome icon shown for this rail item.
|
|
13
|
+
*/
|
|
14
|
+
icon: IconDefinition;
|
|
15
|
+
/**
|
|
16
|
+
* Accessible name; also shown as visible text when the rail is expanded.
|
|
17
|
+
*/
|
|
18
|
+
label: string;
|
|
19
|
+
/**
|
|
20
|
+
* When true, shows a small notification badge on the icon.
|
|
21
|
+
*/
|
|
22
|
+
badge?: boolean;
|
|
23
|
+
}
|
|
24
|
+
interface Props {
|
|
25
|
+
/**
|
|
26
|
+
* Declarative rail item to render.
|
|
27
|
+
*/
|
|
28
|
+
item: SidebarRailItemData;
|
|
29
|
+
/**
|
|
30
|
+
* Whether this item is the active selection.
|
|
31
|
+
*/
|
|
32
|
+
active: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the rail shows labels beside icons.
|
|
35
|
+
*/
|
|
36
|
+
expanded: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Roving tabindex value: `0` for the selected tab, `-1` for others.
|
|
39
|
+
*/
|
|
40
|
+
tabIndex: number;
|
|
41
|
+
/**
|
|
42
|
+
* Optional id of the sidebar panel this tab controls.
|
|
43
|
+
*/
|
|
44
|
+
panelId?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Called when the user activates this item.
|
|
47
|
+
*/
|
|
48
|
+
onSelect: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* Keyboard handler for tablist arrow-key navigation.
|
|
51
|
+
*/
|
|
52
|
+
onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;
|
|
53
|
+
/**
|
|
54
|
+
* Ref attached to the item button for focus management.
|
|
55
|
+
*/
|
|
56
|
+
buttonRef?: Ref<HTMLButtonElement>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Single rail navigation tab: full-width active chrome with an icon button.
|
|
60
|
+
*
|
|
61
|
+
* @param props - Item identity, active/expanded chrome, and activation handlers.
|
|
62
|
+
* @returns Rail section with decorative icon and optional badge.
|
|
63
|
+
*/
|
|
64
|
+
export declare function SidebarRailItem({ item, active, expanded, tabIndex, panelId, onSelect, onKeyDown, buttonRef }: Props): JSX.Element;
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=SidebarRailItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SidebarRailItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarRail/SidebarRailItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAUrD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,mBAAmB,CAAC;IAE1B;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAE7D;;OAEG;IACH,SAAS,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;CACpC;AAiDD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,SAAS,EACT,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA8CrB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
+
import { FaIcon } from '../FaIcon/index.js';
|
|
3
|
+
import { cn } from '../utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Shared focus-visible outline for rail tabs (matches TabBar / segment chrome).
|
|
6
|
+
*/
|
|
7
|
+
const railItemFocusVisible = 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-accent';
|
|
8
|
+
/**
|
|
9
|
+
* Builds the accessible name for a rail tab, including badge status when present.
|
|
10
|
+
*
|
|
11
|
+
* @param label - Visible item label.
|
|
12
|
+
* @param badge - Whether the item shows a notification badge.
|
|
13
|
+
* @returns Accessible name string for `aria-label` or visually hidden text.
|
|
14
|
+
*/
|
|
15
|
+
function railItemAccessibleName(label, badge) {
|
|
16
|
+
return badge === true ? `${label}, notification` : label;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Tailwind classes for the full-width rail section chrome.
|
|
20
|
+
*
|
|
21
|
+
* Active/hover fill the entire section between separators — not an inset
|
|
22
|
+
* pill around the control.
|
|
23
|
+
*
|
|
24
|
+
* @param active - Whether this item is the current selection.
|
|
25
|
+
* @returns Class string for the section wrapper.
|
|
26
|
+
*/
|
|
27
|
+
function railItemSectionClasses(active) {
|
|
28
|
+
return cn('hc-sidebar-rail-item-section w-full shrink-0 text-sidebar-rail-text', active ? 'bg-sidebar-rail-active' : 'bg-transparent');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Tailwind classes for the interactive control inside a rail section.
|
|
32
|
+
*
|
|
33
|
+
* Kept visually flat so selection chrome lives on the section, not the button.
|
|
34
|
+
* Focus outline always applies (including when active) so keyboard users can
|
|
35
|
+
* see focus on the current mode.
|
|
36
|
+
*
|
|
37
|
+
* @param active - Whether this item is the current selection.
|
|
38
|
+
* @param expanded - Whether the rail shows labels.
|
|
39
|
+
* @returns Class string for the item button.
|
|
40
|
+
*/
|
|
41
|
+
function railItemButtonClasses(active, expanded) {
|
|
42
|
+
return cn('hc-sidebar-rail-item app-no-drag relative inline-flex min-h-12 w-full shrink-0 cursor-pointer items-center rounded-none border-none bg-transparent py-5', expanded ? 'gap-2 px-3' : 'justify-center', !active && 'hover:bg-sidebar-rail-active', railItemFocusVisible);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Single rail navigation tab: full-width active chrome with an icon button.
|
|
46
|
+
*
|
|
47
|
+
* @param props - Item identity, active/expanded chrome, and activation handlers.
|
|
48
|
+
* @returns Rail section with decorative icon and optional badge.
|
|
49
|
+
*/
|
|
50
|
+
export function SidebarRailItem({ item, active, expanded, tabIndex, panelId, onSelect, onKeyDown, buttonRef }) {
|
|
51
|
+
const accessibleName = railItemAccessibleName(item.label, item.badge);
|
|
52
|
+
/**
|
|
53
|
+
* Icon-only (collapsed) uses aria-label. Expanded uses visible text (plus
|
|
54
|
+
* optional visually hidden badge status) as the accessible name so AT is not
|
|
55
|
+
* left with a color-only cue and is not announced twice via aria-label.
|
|
56
|
+
*/
|
|
57
|
+
const ariaLabel = expanded ? undefined : accessibleName;
|
|
58
|
+
return (_jsx("div", { className: railItemSectionClasses(active), children: _jsxs("button", { type: "button", role: "tab", ref: buttonRef, className: railItemButtonClasses(active, expanded), title: item.label, tabIndex: tabIndex, "aria-label": ariaLabel, "aria-selected": active, "aria-controls": panelId, onClick: onSelect, onKeyDown: onKeyDown, children: [_jsxs("span", { className: "relative inline-flex shrink-0 items-center justify-center", children: [_jsx(FaIcon, { icon: item.icon, className: "hc-sidebar-rail-item-icon h-[22.5px]! w-[22.5px]!", "aria-hidden": true }), item.badge ? (_jsx("span", { className: "hc-sidebar-rail-item-badge absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-accent", "aria-hidden": true })) : null] }), expanded ? (_jsx("span", { className: "hc-sidebar-rail-item-label min-w-0 truncate text-left", children: item.label })) : null, expanded && item.badge === true ? _jsx("span", { className: "sr-only", children: ", notification" }) : null] }) }));
|
|
59
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Horizontal hairline divider between {@link SidebarRail} navigation items.
|
|
4
|
+
*
|
|
5
|
+
* Spans the full rail width (no horizontal inset) so separators read as
|
|
6
|
+
* section boundaries. Uses `sidebar-rail-separator`, a soft mix of rail fill
|
|
7
|
+
* and rail text so dividers stay close to the background in every theme.
|
|
8
|
+
* Decorative only — hidden from the accessibility tree so focus stays on tabs.
|
|
9
|
+
*/
|
|
10
|
+
export declare function SidebarRailSeparator(): JSX.Element;
|
|
11
|
+
//# sourceMappingURL=SidebarRailSeparator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SidebarRailSeparator.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarRail/SidebarRailSeparator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,GAAG,CAAC,OAAO,CAOlD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Horizontal hairline divider between {@link SidebarRail} navigation items.
|
|
4
|
+
*
|
|
5
|
+
* Spans the full rail width (no horizontal inset) so separators read as
|
|
6
|
+
* section boundaries. Uses `sidebar-rail-separator`, a soft mix of rail fill
|
|
7
|
+
* and rail text so dividers stay close to the background in every theme.
|
|
8
|
+
* Decorative only — hidden from the accessibility tree so focus stays on tabs.
|
|
9
|
+
*/
|
|
10
|
+
export function SidebarRailSeparator() {
|
|
11
|
+
return (_jsx("div", { className: "hc-sidebar-rail-separator h-px w-full shrink-0 bg-sidebar-rail-separator", "aria-hidden": true }));
|
|
12
|
+
}
|