react-os-shell 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +10 -6
- package/dist/index.js +65 -47
- package/dist/index.js.map +1 -1
- package/dist/styles.css +15 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -455,13 +455,14 @@ interface EditableGridProps {
|
|
|
455
455
|
declare function EditableGrid({ columns, data, onChange, onColumnsChange, fixedRows, minRows, maxHeight, cellStyles, onFocusChange, onSelectionChange }: EditableGridProps): react_jsx_runtime.JSX.Element;
|
|
456
456
|
|
|
457
457
|
/**
|
|
458
|
-
* Two-pane layout with a drag-to-resize left
|
|
458
|
+
* Two-pane layout with a drag-to-resize sidebar (left or right).
|
|
459
459
|
*
|
|
460
460
|
* Renders flush (`h-full w-full`) — pair it with a `flushBody` window so the
|
|
461
461
|
* sidebar runs from just under the title bar to the very bottom with no
|
|
462
|
-
* surrounding padding. The user can drag the
|
|
463
|
-
*
|
|
464
|
-
*
|
|
462
|
+
* surrounding padding. The user can drag the sidebar's inner edge to resize
|
|
463
|
+
* it; pass `storageKey` to persist that width across reopens, or double-click
|
|
464
|
+
* the handle to reset to `defaultWidth`. Set `side="right"` to put the sidebar
|
|
465
|
+
* on the right (e.g. a detail-panel layout).
|
|
465
466
|
*
|
|
466
467
|
* @example
|
|
467
468
|
* <SidebarLayout sidebar={<MyNav />} storageKey="todo.sidebarWidth">
|
|
@@ -471,8 +472,11 @@ declare function EditableGrid({ columns, data, onChange, onColumnsChange, fixedR
|
|
|
471
472
|
interface SidebarLayoutProps {
|
|
472
473
|
/** Content of the left sidebar pane. */
|
|
473
474
|
sidebar: ReactNode;
|
|
474
|
-
/** Content of the main pane (
|
|
475
|
+
/** Content of the main pane (opposite the sidebar). */
|
|
475
476
|
children: ReactNode;
|
|
477
|
+
/** Which side the sidebar sits on. Default `'left'`. When `'right'`, the
|
|
478
|
+
* sidebar renders on the right with the resize handle on its left edge. */
|
|
479
|
+
side?: 'left' | 'right';
|
|
476
480
|
/** localStorage key to persist the sidebar width across reopens. When set,
|
|
477
481
|
* the last dragged width is restored on mount. Omit for session-only width. */
|
|
478
482
|
storageKey?: string;
|
|
@@ -491,7 +495,7 @@ interface SidebarLayoutProps {
|
|
|
491
495
|
/** Classes for the main content pane. Defaults to a white background. */
|
|
492
496
|
contentClassName?: string;
|
|
493
497
|
}
|
|
494
|
-
declare function SidebarLayout({ sidebar, children, storageKey, defaultWidth, minWidth, maxWidth, className, sidebarClassName, contentClassName, }: SidebarLayoutProps): react_jsx_runtime.JSX.Element;
|
|
498
|
+
declare function SidebarLayout({ sidebar, children, side, storageKey, defaultWidth, minWidth, maxWidth, className, sidebarClassName, contentClassName, }: SidebarLayoutProps): react_jsx_runtime.JSX.Element;
|
|
495
499
|
|
|
496
500
|
/** Generic notification shape consumed by the shell. Consumer-specific
|
|
497
501
|
* fields live on `extra` (or just on additional properties — TS structural
|
package/dist/index.js
CHANGED
|
@@ -564,14 +564,16 @@ var clamp = (n, lo, hi) => Math.min(Math.max(n, lo), hi);
|
|
|
564
564
|
function SidebarLayout({
|
|
565
565
|
sidebar,
|
|
566
566
|
children,
|
|
567
|
+
side = "left",
|
|
567
568
|
storageKey,
|
|
568
569
|
defaultWidth = 256,
|
|
569
570
|
minWidth = 180,
|
|
570
571
|
maxWidth = 480,
|
|
571
572
|
className = "",
|
|
572
|
-
sidebarClassName = "border-r border-gray-200 bg-gray-50",
|
|
573
|
+
sidebarClassName = side === "right" ? "border-l border-gray-200 bg-gray-50" : "border-r border-gray-200 bg-gray-50",
|
|
573
574
|
contentClassName = "bg-white"
|
|
574
575
|
}) {
|
|
576
|
+
const sideRight = side === "right";
|
|
575
577
|
const [width, setWidth] = useState(() => {
|
|
576
578
|
if (storageKey && typeof window !== "undefined") {
|
|
577
579
|
const saved = window.localStorage.getItem(storageKey);
|
|
@@ -584,8 +586,9 @@ function SidebarLayout({
|
|
|
584
586
|
const onMove = useCallback((e) => {
|
|
585
587
|
const d = dragRef.current;
|
|
586
588
|
if (!d) return;
|
|
587
|
-
|
|
588
|
-
|
|
589
|
+
const delta = (e.clientX - d.startX) * (sideRight ? -1 : 1);
|
|
590
|
+
setWidth(clamp(d.startWidth + delta, minWidth, maxWidth));
|
|
591
|
+
}, [minWidth, maxWidth, sideRight]);
|
|
589
592
|
const onUp = useCallback(() => {
|
|
590
593
|
dragRef.current = null;
|
|
591
594
|
window.removeEventListener("pointermove", onMove);
|
|
@@ -615,22 +618,28 @@ function SidebarLayout({
|
|
|
615
618
|
window.removeEventListener("pointermove", onMove);
|
|
616
619
|
window.removeEventListener("pointerup", onUp);
|
|
617
620
|
}, [onMove, onUp]);
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
] }),
|
|
632
|
-
/* @__PURE__ */ jsx("div", { className: `flex min-w-0 flex-1 flex-col ${contentClassName}`, children })
|
|
621
|
+
const edge = sideRight ? "left-0" : "right-0";
|
|
622
|
+
const sidebarPane = /* @__PURE__ */ jsxs("div", { className: "relative flex h-full shrink-0 flex-col", style: { width }, children: [
|
|
623
|
+
/* @__PURE__ */ jsx("div", { className: `flex h-full flex-col overflow-y-auto ${sidebarClassName}`, children: sidebar }),
|
|
624
|
+
/* @__PURE__ */ jsx(
|
|
625
|
+
"div",
|
|
626
|
+
{
|
|
627
|
+
onPointerDown: startDrag,
|
|
628
|
+
onDoubleClick: () => setWidth(clamp(defaultWidth, minWidth, maxWidth)),
|
|
629
|
+
title: "Drag to resize \xB7 double-click to reset",
|
|
630
|
+
className: `group absolute inset-y-0 ${edge} z-10 w-2 cursor-col-resize`,
|
|
631
|
+
children: /* @__PURE__ */ jsx("div", { className: `absolute inset-y-0 ${edge} w-px bg-transparent transition-colors group-hover:bg-blue-400` })
|
|
632
|
+
}
|
|
633
|
+
)
|
|
633
634
|
] });
|
|
635
|
+
const contentPane = /* @__PURE__ */ jsx("div", { className: `flex min-w-0 flex-1 flex-col ${contentClassName}`, children });
|
|
636
|
+
return /* @__PURE__ */ jsx("div", { className: `flex h-full w-full overflow-hidden ${className}`, children: sideRight ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
637
|
+
contentPane,
|
|
638
|
+
sidebarPane
|
|
639
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
640
|
+
sidebarPane,
|
|
641
|
+
contentPane
|
|
642
|
+
] }) });
|
|
634
643
|
}
|
|
635
644
|
function timeAgo(dateStr) {
|
|
636
645
|
const diff = Date.now() - new Date(dateStr).getTime();
|
|
@@ -1472,7 +1481,7 @@ function WidgetManager({ open, onClose }) {
|
|
|
1472
1481
|
}
|
|
1473
1482
|
|
|
1474
1483
|
// src/version.ts
|
|
1475
|
-
var VERSION = "0.
|
|
1484
|
+
var VERSION = "0.12.0" ;
|
|
1476
1485
|
var APP_VERSION = VERSION;
|
|
1477
1486
|
|
|
1478
1487
|
// src/changelog.ts
|
|
@@ -5701,34 +5710,43 @@ function SystemPreferences({
|
|
|
5701
5710
|
const initial = defaultSelected && sections2.some((s) => s.key === defaultSelected) ? defaultSelected : sections2[0]?.key ?? "";
|
|
5702
5711
|
const [selected, setSelected] = useState(initial);
|
|
5703
5712
|
const active = sections2.find((s) => s.key === selected) ?? sections2[0];
|
|
5704
|
-
return /* @__PURE__ */
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
),
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5713
|
+
return /* @__PURE__ */ jsx(
|
|
5714
|
+
SidebarLayout,
|
|
5715
|
+
{
|
|
5716
|
+
storageKey: "shell.systemPreferences.sidebarWidth",
|
|
5717
|
+
defaultWidth: 240,
|
|
5718
|
+
minWidth: 200,
|
|
5719
|
+
maxWidth: 360,
|
|
5720
|
+
className,
|
|
5721
|
+
sidebarClassName: "border-r border-gray-200 bg-gray-50",
|
|
5722
|
+
sidebar: /* @__PURE__ */ jsx("nav", { className: "py-1.5", children: sections2.map((item) => {
|
|
5723
|
+
const isActive = item.key === selected;
|
|
5724
|
+
return /* @__PURE__ */ jsxs(
|
|
5725
|
+
"button",
|
|
5726
|
+
{
|
|
5727
|
+
type: "button",
|
|
5728
|
+
onClick: () => setSelected(item.key),
|
|
5729
|
+
className: `w-full text-left px-3 py-2.5 text-sm transition-colors flex items-start gap-2.5 ${isActive ? "bg-blue-50 text-blue-700" : "hover:bg-gray-100 text-gray-700"}`,
|
|
5730
|
+
children: [
|
|
5731
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: `mt-0.5 ${isActive ? "text-blue-600" : "text-gray-400"}`, children: item.icon }),
|
|
5732
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
|
|
5733
|
+
/* @__PURE__ */ jsx(
|
|
5734
|
+
"span",
|
|
5735
|
+
{
|
|
5736
|
+
className: `block ${isActive ? "font-semibold text-blue-700" : "font-medium text-gray-800"}`,
|
|
5737
|
+
children: item.label
|
|
5738
|
+
}
|
|
5739
|
+
),
|
|
5740
|
+
item.description && /* @__PURE__ */ jsx("span", { className: "block text-[11px] text-gray-500 mt-0.5", children: item.description })
|
|
5741
|
+
] })
|
|
5742
|
+
]
|
|
5743
|
+
},
|
|
5744
|
+
item.key
|
|
5745
|
+
);
|
|
5746
|
+
}) }),
|
|
5747
|
+
children: /* @__PURE__ */ jsx("main", { className: "flex-1 min-w-0 overflow-auto p-4", children: active?.render() })
|
|
5748
|
+
}
|
|
5749
|
+
);
|
|
5732
5750
|
}
|
|
5733
5751
|
function useTableNav(items, onSelect, onToggle, onSelectAll, onSelectRange) {
|
|
5734
5752
|
const [focusIdx, setFocusIdx] = useState(-1);
|