@adecore/ui 0.49.6 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/SlidingColumn.d.ts +2 -1
  2. package/dist/SlidingColumn.js +90 -87
  3. package/dist/file-tree/helpers.js +13 -4
  4. package/dist/index.d.ts +5 -0
  5. package/dist/index.js +5 -0
  6. package/dist/locales/en.d.ts +3 -0
  7. package/dist/locales/en.js +4 -1
  8. package/dist/locales/nl.d.ts +3 -0
  9. package/dist/locales/nl.js +4 -1
  10. package/dist/tabs/use-tab-drag.d.ts +52 -0
  11. package/dist/tabs/use-tab-drag.js +218 -0
  12. package/dist/theme.css +65 -13
  13. package/dist/workspace/PaneBar.d.ts +39 -0
  14. package/dist/workspace/PaneBar.js +399 -0
  15. package/dist/workspace/Workspace.d.ts +4 -1
  16. package/dist/workspace/Workspace.js +207 -155
  17. package/dist/workspace/WorkspaceRail.d.ts +13 -0
  18. package/dist/workspace/WorkspaceRail.js +125 -0
  19. package/dist/workspace/WorkspaceTopRow.d.ts +15 -0
  20. package/dist/workspace/WorkspaceTopRow.js +81 -0
  21. package/dist/workspace/context.d.ts +4 -0
  22. package/dist/workspace/context.js +5 -0
  23. package/dist/workspace/model.js +9 -1
  24. package/dist/workspace/top-row-slot.d.ts +2 -0
  25. package/dist/workspace/top-row-slot.js +6 -0
  26. package/package.json +1 -1
  27. package/src/SlidingColumn.tsx +21 -2
  28. package/src/file-tree/helpers.ts +17 -4
  29. package/src/index.ts +5 -0
  30. package/src/locales/en.ts +4 -1
  31. package/src/locales/nl.ts +4 -1
  32. package/src/tabs/use-tab-drag.ts +256 -0
  33. package/src/theme.css +65 -13
  34. package/src/workspace/PaneBar.tsx +276 -0
  35. package/src/workspace/Workspace.tsx +28 -12
  36. package/src/workspace/WorkspaceRail.tsx +30 -0
  37. package/src/workspace/WorkspaceTopRow.tsx +37 -0
  38. package/src/workspace/context.ts +6 -0
  39. package/src/workspace/model.ts +11 -1
  40. package/src/workspace/top-row-slot.ts +7 -0
package/dist/theme.css CHANGED
@@ -91,6 +91,8 @@
91
91
  --media-handle-text: #18181b;
92
92
  --media-handle-edge: 0 0 0 1px rgb(0 0 0 / 0.3);
93
93
  --media-handle-shadow: 0 2px 12px rgb(0 0 0 / 0.35);
94
+ /* Around a workspace's sheet; light carries half the blur of dark. */
95
+ --sheet-shadow: 0 0 7px rgb(30 30 50 / 0.06);
94
96
  /* The file type palette. A file icon is the one thing in the interface that is not tinted by the
95
97
  theme: TypeScript is blue and Vue is green wherever the file shows up, which is what makes a
96
98
  row readable before the name is. The sprite of the file icons reads these, inside a tree's
@@ -151,6 +153,7 @@
151
153
  --thumb-shadow:
152
154
  0 1px 2px rgb(0 0 0 / 0.5),
153
155
  0 2px 4px -1px rgb(0 0 0 / 0.4);
156
+ --sheet-shadow: 0 0 14px rgb(0 0 0 / 0.3);
154
157
  --status-running: #60a5fa;
155
158
  --status-needs-you: #fbbf24;
156
159
  --status-idle: #4ade80;
@@ -818,16 +821,32 @@
818
821
  }
819
822
 
820
823
  @layer components {
824
+ /* The sidebar and the content lie on one sheet, which stands over the side panel and the rail with its
825
+ own edge and shadow; those two sit a step darker, in the well behind it. */
821
826
  .ade-workspace {
827
+ --workspace-well: color-mix(in srgb, var(--surface) 70%, var(--surface-sunken));
822
828
  display: flex;
823
829
  width: 100%;
824
830
  height: 100%;
825
831
  min-width: 0;
826
832
  min-height: 0;
827
833
  overflow: hidden;
828
- background: var(--separator);
834
+ background: var(--workspace-well);
829
835
  --border: var(--separator);
830
836
  }
837
+ .ade-workspace-sheet {
838
+ position: relative;
839
+ z-index: 1;
840
+ display: flex;
841
+ flex: 1;
842
+ min-width: 0;
843
+ min-height: 0;
844
+ overflow: hidden;
845
+ border-radius: 0 12px 12px 0;
846
+ /* The surface its regions draw, so no lighter ground shows where the rounded edge cuts them. Roomy shows its gaps in it. */
847
+ background: var(--surface);
848
+ box-shadow: 0 0 0 1px var(--border), var(--sheet-shadow);
849
+ }
831
850
  .ade-workspace-center {
832
851
  display: flex;
833
852
  flex: 1;
@@ -843,7 +862,8 @@
843
862
  background: var(--surface);
844
863
  }
845
864
  .ade-workspace-sidebar { border-right: 1px solid var(--separator); }
846
- .ade-workspace-side-panel { border-left: 1px solid var(--separator); }
865
+ /* What draws a surface inside the panel draws the well instead. Its left edge is the sheet's. */
866
+ .ade-workspace-side-panel { --surface: var(--workspace-well); }
847
867
  .ade-workspace-toolbar {
848
868
  flex: none;
849
869
  overflow: hidden;
@@ -858,15 +878,46 @@
858
878
  overflow: hidden;
859
879
  background: var(--surface);
860
880
  }
861
- .ade-workspace[data-layout="roomy"] > .ade-workspace-center { gap: 8px; }
862
- .ade-workspace[data-layout="roomy"] > .ade-workspace-sidebar:not([data-auto]) { margin-right: 8px; }
863
- .ade-workspace[data-layout="roomy"] > .ade-workspace-side-panel:not([data-auto]) { margin-left: 8px; }
864
881
  .ade-workspace-sidebar[data-auto], .ade-workspace-side-panel[data-auto] { display: contents; }
865
- .ade-workspace[data-layout="roomy"] > .ade-workspace-sidebar,
866
- .ade-workspace[data-layout="roomy"] > .ade-workspace-side-panel,
867
- .ade-workspace[data-layout="roomy"] > .ade-workspace-center > .ade-workspace-toolbar { border: 0; }
868
- .ade-workspace[data-layout="roomy"][data-sidebar] > .ade-workspace-center > .ade-workspace-toolbar { border-bottom-left-radius: 8px; }
869
- .ade-workspace[data-layout="roomy"][data-side-panel] > .ade-workspace-center > .ade-workspace-toolbar { border-bottom-right-radius: 8px; }
882
+ .ade-workspace[data-layout="roomy"],
883
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-sheet { background: var(--separator); }
884
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-sheet > .ade-workspace-center { gap: 8px; }
885
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-sheet > .ade-workspace-sidebar:not([data-auto]) { margin-right: 8px; }
886
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-side-panel:not([data-auto]) { margin-left: 8px; }
887
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-sheet > .ade-workspace-sidebar,
888
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-sheet > .ade-workspace-center > .ade-workspace-toolbar { border: 0; }
889
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-sheet > .ade-workspace-center > .ade-workspace-toolbar { border-radius: 0 0 8px 8px; }
890
+ .ade-workspace[data-layout="roomy"][data-toolbar] > .ade-workspace-sheet > .ade-workspace-center > .ade-workspace-content { border-radius: 8px 8px 0 0; }
891
+
892
+ .ade-workspace-rail {
893
+ display: flex;
894
+ flex: none;
895
+ flex-direction: column;
896
+ align-items: center;
897
+ gap: 4px;
898
+ width: 48px;
899
+ min-height: 0;
900
+ /* The 7 pixels and the first separator's 3 put that separator on the bottom line of a 47 pixel toolbar. */
901
+ padding: 7px 0 8px;
902
+ background: var(--workspace-well, var(--surface));
903
+ /* As long as a sliding column takes to open, so the line comes and goes with the panel. */
904
+ transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1);
905
+ }
906
+ /* No line beside the sheet, whose rounded edge shows while the panel is closed; one beside an open panel. */
907
+ .ade-workspace[data-side-panel] > .ade-workspace-rail { box-shadow: inset 1px 0 var(--separator); }
908
+ .ade-workspace[data-layout="roomy"] > .ade-workspace-rail { margin-left: 8px; box-shadow: none; }
909
+ .ade-workspace-rail-separator {
910
+ flex: none;
911
+ width: 20px;
912
+ height: 1px;
913
+ margin: 4px 0;
914
+ background: var(--separator);
915
+ }
916
+ .ade-workspace-rail > :nth-child(1 of .ade-workspace-rail-separator) { margin-top: 3px; }
917
+ .ade-workspace-rail-spacer { flex: 1; }
918
+ /* The window drags by the top row, except where a control or a pane's title answers the pointer. */
919
+ .ade-workspace-top-row { -webkit-app-region: drag; }
920
+ .ade-workspace-top-row :is(button, input, a, [role="tab"], .ade-pane-title) { -webkit-app-region: no-drag; }
870
921
  .ade-split-view {
871
922
  position: relative;
872
923
  isolation: isolate;
@@ -915,8 +966,6 @@
915
966
  .ade-split-divider[aria-orientation="horizontal"]::after { inset-inline: 0; top: -1px; height: 2px; }
916
967
  .ade-split-view[data-layout="roomy"] > .ade-split-divider[aria-orientation="vertical"]::after { left: 3px; }
917
968
  .ade-split-view[data-layout="roomy"] > .ade-split-divider[aria-orientation="horizontal"]::after { top: 3px; }
918
- .ade-workspace[data-layout="roomy"][data-toolbar][data-sidebar] > .ade-workspace-center > .ade-workspace-content { border-top-left-radius: 8px; }
919
- .ade-workspace[data-layout="roomy"][data-toolbar][data-side-panel] > .ade-workspace-center > .ade-workspace-content { border-top-right-radius: 8px; }
920
969
  .ade-split-divider:is(:hover, :focus-visible, [data-resizing])::after { background: var(--accent); }
921
970
  .ade-drop-preview {
922
971
  position: absolute;
@@ -959,6 +1008,8 @@
959
1008
  gap: 4px;
960
1009
  padding: 0 8px 0 12px;
961
1010
  color: var(--text-muted);
1011
+ /* The weight of a pane's title, so a view reads the same as a tab and as the only view of its pane. */
1012
+ font-weight: 500;
962
1013
  }
963
1014
  .ade-document-tab:hover { color: var(--text); background: var(--surface-raised); }
964
1015
  .ade-document-tab[data-active] { color: var(--text); }
@@ -977,7 +1028,8 @@
977
1028
  min-width: 0;
978
1029
  max-width: 160px;
979
1030
  align-items: center;
980
- gap: 6px;
1031
+ /* As far from its icon as a pane's title stands from its glyph. */
1032
+ gap: 8px;
981
1033
  font-size: var(--text-sm);
982
1034
  color: inherit;
983
1035
  outline-offset: -2px;
@@ -0,0 +1,39 @@
1
+ import { type ComponentProps, type DragEvent, type ReactNode } from 'react';
2
+ import type { Shortcut } from '../shortcut.ts';
3
+ export interface PaneBarProps extends Omit<ComponentProps<'header'>, 'title' | 'children' | 'onDragStart' | 'onDragEnd'> {
4
+ /** What the pane is: a glyph and a name, or a `TabStrip` when `tabs` is set. */
5
+ title: ReactNode;
6
+ /** The title is a strip of tabs, which takes the bar's room and keeps the bar whatever tab is in front. */
7
+ tabs?: boolean;
8
+ /** The pane's own controls. They fold into a "More actions" popover once the title has given way and they still do not fit. */
9
+ actions?: ReactNode;
10
+ /** Keeps the actions in the bar of a pane with tabs, rather than in a bar of their own under it. */
11
+ compactActions?: boolean;
12
+ /** A separator between the title and the actions of a pane without tabs. */
13
+ separated?: boolean;
14
+ /** Between the title and the actions, such as a mark that lives on the line over the body. */
15
+ accessory?: ReactNode;
16
+ /** Before the close button, such as a sign that the pane fills the view. */
17
+ trailing?: ReactNode;
18
+ focused?: boolean;
19
+ onClose?(): void;
20
+ closeLabel?: string;
21
+ closeShortcut?: Shortcut | string;
22
+ moreActionsLabel?: string;
23
+ /** The items of the bar's context menu. Leave it out for a bar without one. */
24
+ menu?: ReactNode;
25
+ /** With `onDragStart`, the bar is a handle that drags the pane; a press on a control in it never starts one. */
26
+ onDragStart?(event: DragEvent<HTMLElement>): void;
27
+ onDragEnd?(event: DragEvent<HTMLElement>): void;
28
+ /**
29
+ * An element to draw the bar in instead of over the pane, such as the slot of a `WorkspaceTopRow`. The bar
30
+ * stays the pane's in the tree, so its events still reach the pane's handlers. A separator leads it there.
31
+ */
32
+ container?: HTMLElement | null;
33
+ }
34
+ /**
35
+ * The bar over a pane: its title or its tabs, its actions and its close button. Drawn in a `container` it
36
+ * takes that element's height and background, and only its title answers the pointer, so a window can be
37
+ * dragged by the rest.
38
+ */
39
+ export declare function PaneBar({ title, tabs, actions, compactActions, separated, accessory, trailing, focused, onClose, closeLabel, closeShortcut, moreActionsLabel, menu, onDragStart, onDragEnd, container, className, ...props }: PaneBarProps): import("react").JSX.Element;
@@ -0,0 +1,399 @@
1
+ import { c as _c } from "react/compiler-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { createPortal } from 'react-dom';
4
+ import clsx from 'clsx';
5
+ import { MoreHorizontal } from 'lucide-react';
6
+ import { useTranslation } from 'react-i18next';
7
+ import { CloseButton } from "../CloseButton.js";
8
+ import * as ContextMenu from '../context-menu/index.parts.js';
9
+ import { IconButton } from "../IconButton.js";
10
+ import * as Popover from '../popover/index.parts.js';
11
+ import { Separator } from "../Separator.js";
12
+ /* What the bar holds that is not the bar: a press on one of these is not the start of a drag. */
13
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
14
+ const CONTROLS = 'input, textarea, select, button, a, [contenteditable=""], [contenteditable="true"], [role="button"]';
15
+ /* Without this margin, a bar right at the fold point would fold and unfold on every pixel of a splitter drag. */
16
+ const UNFOLD_MARGIN = 24;
17
+ /*
18
+ * Whether the actions are folded into the overflow menu: only once the title has shrunk to its glyph and
19
+ * the actions still do not fit. The width where that happened is remembered, since a folded bar fits by
20
+ * definition and can no longer tell by overflowing when there is room again.
21
+ */
22
+ function useFolded(bar, actions, enabled) {
23
+ const $ = _c(9);
24
+ const [foldedAt, setFoldedAt] = useState(null);
25
+ let t0;
26
+ if ($[0] !== actions || $[1] !== bar.current || $[2] !== enabled) {
27
+ t0 = () => {
28
+ const element = bar.current;
29
+ if (!enabled || element === null || typeof ResizeObserver === "undefined") {
30
+ return;
31
+ }
32
+ const measure = () => {
33
+ const width = element.clientWidth;
34
+ setFoldedAt(current => {
35
+ if (current !== null) {
36
+ return width > current + UNFOLD_MARGIN ? null : current;
37
+ }
38
+ return element.scrollWidth > width + 1 ? width : null;
39
+ });
40
+ };
41
+ const observer = new ResizeObserver(measure);
42
+ observer.observe(element);
43
+ if (actions.current) {
44
+ observer.observe(actions.current);
45
+ }
46
+ measure();
47
+ return () => observer.disconnect();
48
+ };
49
+ $[0] = actions;
50
+ $[1] = bar.current;
51
+ $[2] = enabled;
52
+ $[3] = t0;
53
+ } else {
54
+ t0 = $[3];
55
+ }
56
+ let t1;
57
+ if ($[4] !== actions || $[5] !== bar || $[6] !== enabled || $[7] !== foldedAt) {
58
+ t1 = [bar, actions, enabled, foldedAt];
59
+ $[4] = actions;
60
+ $[5] = bar;
61
+ $[6] = enabled;
62
+ $[7] = foldedAt;
63
+ $[8] = t1;
64
+ } else {
65
+ t1 = $[8];
66
+ }
67
+ useEffect(t0, t1);
68
+ return enabled && foldedAt !== null;
69
+ }
70
+ /**
71
+ * The bar over a pane: its title or its tabs, its actions and its close button. Drawn in a `container` it
72
+ * takes that element's height and background, and only its title answers the pointer, so a window can be
73
+ * dragged by the rest.
74
+ */
75
+ export function PaneBar(t0) {
76
+ const $ = _c(86);
77
+ let accessory;
78
+ let actions;
79
+ let className;
80
+ let closeLabel;
81
+ let closeShortcut;
82
+ let menu;
83
+ let moreActionsLabel;
84
+ let onClose;
85
+ let onDragEnd;
86
+ let onDragStart;
87
+ let props;
88
+ let t1;
89
+ let t2;
90
+ let t3;
91
+ let t4;
92
+ let t5;
93
+ let title;
94
+ let trailing;
95
+ if ($[0] !== t0) {
96
+ ({
97
+ title,
98
+ tabs: t1,
99
+ actions,
100
+ compactActions: t2,
101
+ separated: t3,
102
+ accessory,
103
+ trailing,
104
+ focused: t4,
105
+ onClose,
106
+ closeLabel,
107
+ closeShortcut,
108
+ moreActionsLabel,
109
+ menu,
110
+ onDragStart,
111
+ onDragEnd,
112
+ container: t5,
113
+ className,
114
+ ...props
115
+ } = t0);
116
+ $[0] = t0;
117
+ $[1] = accessory;
118
+ $[2] = actions;
119
+ $[3] = className;
120
+ $[4] = closeLabel;
121
+ $[5] = closeShortcut;
122
+ $[6] = menu;
123
+ $[7] = moreActionsLabel;
124
+ $[8] = onClose;
125
+ $[9] = onDragEnd;
126
+ $[10] = onDragStart;
127
+ $[11] = props;
128
+ $[12] = t1;
129
+ $[13] = t2;
130
+ $[14] = t3;
131
+ $[15] = t4;
132
+ $[16] = t5;
133
+ $[17] = title;
134
+ $[18] = trailing;
135
+ } else {
136
+ accessory = $[1];
137
+ actions = $[2];
138
+ className = $[3];
139
+ closeLabel = $[4];
140
+ closeShortcut = $[5];
141
+ menu = $[6];
142
+ moreActionsLabel = $[7];
143
+ onClose = $[8];
144
+ onDragEnd = $[9];
145
+ onDragStart = $[10];
146
+ props = $[11];
147
+ t1 = $[12];
148
+ t2 = $[13];
149
+ t3 = $[14];
150
+ t4 = $[15];
151
+ t5 = $[16];
152
+ title = $[17];
153
+ trailing = $[18];
154
+ }
155
+ const tabs = t1 === undefined ? false : t1;
156
+ const compactActions = t2 === undefined ? false : t2;
157
+ const separated = t3 === undefined ? false : t3;
158
+ const focused = t4 === undefined ? false : t4;
159
+ const container = t5 === undefined ? null : t5;
160
+ const {
161
+ t
162
+ } = useTranslation("ui");
163
+ const [grabbable, setGrabbable] = useState(true);
164
+ const [menuOpen, setMenuOpen] = useState(false);
165
+ const bar = useRef(null);
166
+ const actionsBar = useRef(null);
167
+ const actionsRef = useRef(null);
168
+ const hasActions = actions !== undefined && actions !== null && actions !== false;
169
+ const separate = tabs && !compactActions;
170
+ const folded = useFolded(separate ? actionsBar : bar, actionsRef, hasActions);
171
+ const inContainer = container !== null;
172
+ const draggable = onDragStart !== undefined;
173
+ let t6;
174
+ if ($[19] !== actions || $[20] !== compactActions || $[21] !== folded || $[22] !== hasActions || $[23] !== menuOpen || $[24] !== moreActionsLabel || $[25] !== separated || $[26] !== t || $[27] !== tabs) {
175
+ t6 = hasActions && /*#__PURE__*/_jsxs(_Fragment, {
176
+ children: [!folded && /*#__PURE__*/_jsxs(_Fragment, {
177
+ children: [!tabs && separated && /*#__PURE__*/_jsx(Separator, {}), /*#__PURE__*/_jsx("span", {
178
+ ref: actionsRef,
179
+ className: clsx("flex min-w-min items-center", tabs && compactActions ? "shrink-0" : "grow"),
180
+ children: actions
181
+ })]
182
+ }), folded && /*#__PURE__*/_jsxs(Popover.Root, {
183
+ open: menuOpen,
184
+ onOpenChange: setMenuOpen,
185
+ children: [/*#__PURE__*/_jsx(IconButton, {
186
+ icon: MoreHorizontal,
187
+ size: "sm",
188
+ label: moreActionsLabel ?? t("workspace.moreActions"),
189
+ className: "cursor-default",
190
+ render: /*#__PURE__*/_jsx(Popover.Trigger, {})
191
+ }), /*#__PURE__*/_jsx(Popover.Popup, {
192
+ sideOffset: 6,
193
+ align: "end",
194
+ className: "flex min-w-72 items-center gap-2 p-2 text-xs",
195
+ children: actions
196
+ })]
197
+ }), folded && !menuOpen && /*#__PURE__*/_jsx("span", {
198
+ hidden: true,
199
+ className: "hidden",
200
+ children: actions
201
+ })]
202
+ });
203
+ $[19] = actions;
204
+ $[20] = compactActions;
205
+ $[21] = folded;
206
+ $[22] = hasActions;
207
+ $[23] = menuOpen;
208
+ $[24] = moreActionsLabel;
209
+ $[25] = separated;
210
+ $[26] = t;
211
+ $[27] = tabs;
212
+ $[28] = t6;
213
+ } else {
214
+ t6 = $[28];
215
+ }
216
+ const actionsPart = t6;
217
+ const t7 = inContainer ? "container" : undefined;
218
+ const t8 = draggable && grabbable;
219
+ const t9 = draggable && "cursor-grab active:cursor-grabbing";
220
+ let t10;
221
+ if ($[29] !== className || $[30] !== focused || $[31] !== inContainer || $[32] !== t9 || $[33] !== tabs) {
222
+ t10 = clsx("ade-pane-bar flex items-center gap-2 overflow-hidden text-xs", t9, inContainer ? "h-full min-w-0 grow text-text" : clsx("h-10 shrink-0 border-b border-border pr-1.5", !tabs && "pl-2", focused ? "bg-surface text-text" : "bg-surface-idle text-text-muted"), className);
223
+ $[29] = className;
224
+ $[30] = focused;
225
+ $[31] = inContainer;
226
+ $[32] = t9;
227
+ $[33] = tabs;
228
+ $[34] = t10;
229
+ } else {
230
+ t10 = $[34];
231
+ }
232
+ let t11;
233
+ let t12;
234
+ if ($[35] !== props) {
235
+ t11 = event => {
236
+ setGrabbable(!event.target?.closest(CONTROLS));
237
+ props.onPointerDown?.(event);
238
+ };
239
+ t12 = event_0 => {
240
+ setGrabbable(true);
241
+ props.onPointerUp?.(event_0);
242
+ };
243
+ $[35] = props;
244
+ $[36] = t11;
245
+ $[37] = t12;
246
+ } else {
247
+ t11 = $[36];
248
+ t12 = $[37];
249
+ }
250
+ const t13 = tabs ? "min-w-24 self-stretch" : "min-w-5";
251
+ const t14 = inContainer ? tabs ? "-ml-1" : "pl-2" : !tabs && "pl-1";
252
+ const t15 = tabs || (folded || !hasActions) && !inContainer ? "grow" : "shrink-100";
253
+ let t16;
254
+ if ($[38] !== t13 || $[39] !== t14 || $[40] !== t15) {
255
+ t16 = clsx("ade-pane-title flex items-center gap-2", t13, t14, t15);
256
+ $[38] = t13;
257
+ $[39] = t14;
258
+ $[40] = t15;
259
+ $[41] = t16;
260
+ } else {
261
+ t16 = $[41];
262
+ }
263
+ let t17;
264
+ if ($[42] !== t16 || $[43] !== title) {
265
+ t17 = /*#__PURE__*/_jsx("span", {
266
+ "data-pane-title": "",
267
+ className: t16,
268
+ children: title
269
+ });
270
+ $[42] = t16;
271
+ $[43] = title;
272
+ $[44] = t17;
273
+ } else {
274
+ t17 = $[44];
275
+ }
276
+ const t18 = !separate && actionsPart;
277
+ let t19;
278
+ if ($[45] !== folded || $[46] !== hasActions || $[47] !== inContainer || $[48] !== tabs) {
279
+ t19 = inContainer && !tabs && (folded || !hasActions) && /*#__PURE__*/_jsx("span", {
280
+ "aria-hidden": "true",
281
+ className: "grow self-stretch"
282
+ });
283
+ $[45] = folded;
284
+ $[46] = hasActions;
285
+ $[47] = inContainer;
286
+ $[48] = tabs;
287
+ $[49] = t19;
288
+ } else {
289
+ t19 = $[49];
290
+ }
291
+ let t20;
292
+ if ($[50] !== closeLabel || $[51] !== closeShortcut || $[52] !== onClose || $[53] !== t) {
293
+ t20 = onClose && /*#__PURE__*/_jsx(CloseButton, {
294
+ label: closeLabel ?? t("workspace.closePane"),
295
+ kbd: closeShortcut,
296
+ size: "sm",
297
+ className: "cursor-default",
298
+ onClick: onClose
299
+ });
300
+ $[50] = closeLabel;
301
+ $[51] = closeShortcut;
302
+ $[52] = onClose;
303
+ $[53] = t;
304
+ $[54] = t20;
305
+ } else {
306
+ t20 = $[54];
307
+ }
308
+ let t21;
309
+ if ($[55] !== accessory || $[56] !== onDragEnd || $[57] !== onDragStart || $[58] !== props || $[59] !== t10 || $[60] !== t11 || $[61] !== t12 || $[62] !== t17 || $[63] !== t18 || $[64] !== t19 || $[65] !== t20 || $[66] !== t7 || $[67] !== t8 || $[68] !== trailing) {
310
+ t21 = /*#__PURE__*/_jsxs("header", {
311
+ ...props,
312
+ ref: bar,
313
+ "data-pane-bar": "",
314
+ "data-placement": t7,
315
+ draggable: t8,
316
+ className: t10,
317
+ onPointerDown: t11,
318
+ onPointerUp: t12,
319
+ onDragStart: onDragStart,
320
+ onDragEnd: onDragEnd,
321
+ children: [t17, accessory, t18, t19, trailing, t20]
322
+ });
323
+ $[55] = accessory;
324
+ $[56] = onDragEnd;
325
+ $[57] = onDragStart;
326
+ $[58] = props;
327
+ $[59] = t10;
328
+ $[60] = t11;
329
+ $[61] = t12;
330
+ $[62] = t17;
331
+ $[63] = t18;
332
+ $[64] = t19;
333
+ $[65] = t20;
334
+ $[66] = t7;
335
+ $[67] = t8;
336
+ $[68] = trailing;
337
+ $[69] = t21;
338
+ } else {
339
+ t21 = $[69];
340
+ }
341
+ const header = t21;
342
+ let t22;
343
+ if ($[70] !== header || $[71] !== menu) {
344
+ t22 = menu === undefined ? header : /*#__PURE__*/_jsxs(ContextMenu.Root, {
345
+ children: [/*#__PURE__*/_jsx(ContextMenu.Trigger, {
346
+ render: header
347
+ }), /*#__PURE__*/_jsx(ContextMenu.Popup, {
348
+ children: menu
349
+ })]
350
+ });
351
+ $[70] = header;
352
+ $[71] = menu;
353
+ $[72] = t22;
354
+ } else {
355
+ t22 = $[72];
356
+ }
357
+ const placed = t22;
358
+ let t23;
359
+ if ($[73] !== container || $[74] !== inContainer || $[75] !== placed) {
360
+ t23 = inContainer ? createPortal(/*#__PURE__*/_jsxs(_Fragment, {
361
+ children: [/*#__PURE__*/_jsx(Separator, {}), placed]
362
+ }), container) : placed;
363
+ $[73] = container;
364
+ $[74] = inContainer;
365
+ $[75] = placed;
366
+ $[76] = t23;
367
+ } else {
368
+ t23 = $[76];
369
+ }
370
+ let t24;
371
+ if ($[77] !== actionsPart || $[78] !== focused || $[79] !== folded || $[80] !== hasActions || $[81] !== separate) {
372
+ t24 = separate && hasActions && /*#__PURE__*/_jsx("div", {
373
+ ref: actionsBar,
374
+ "data-pane-actions": "",
375
+ className: clsx("flex h-10 shrink-0 items-center gap-2 overflow-hidden border-b border-border px-2 text-xs", folded && "justify-end", focused ? "bg-surface text-text" : "bg-surface-idle text-text-muted"),
376
+ children: actionsPart
377
+ });
378
+ $[77] = actionsPart;
379
+ $[78] = focused;
380
+ $[79] = folded;
381
+ $[80] = hasActions;
382
+ $[81] = separate;
383
+ $[82] = t24;
384
+ } else {
385
+ t24 = $[82];
386
+ }
387
+ let t25;
388
+ if ($[83] !== t23 || $[84] !== t24) {
389
+ t25 = /*#__PURE__*/_jsxs(_Fragment, {
390
+ children: [t23, t24]
391
+ });
392
+ $[83] = t23;
393
+ $[84] = t24;
394
+ $[85] = t25;
395
+ } else {
396
+ t25 = $[85];
397
+ }
398
+ return t25;
399
+ }
@@ -6,10 +6,13 @@ export interface WorkspaceProps extends useRender.ComponentProps<'div'> {
6
6
  toolbar?: ReactNode;
7
7
  sidebar?: ReactNode;
8
8
  sidePanel?: ReactNode;
9
+ /** A column at the window's right edge, after the side panel, usually a `WorkspaceRail`. */
10
+ rail?: ReactNode;
9
11
  /** Auto-sized regions keep their own width, separators and opening animation. */
10
12
  sidebarWidth?: number | 'auto';
11
13
  sidePanelWidth?: number | 'auto';
12
14
  sidebarOpen?: boolean;
13
15
  sidePanelOpen?: boolean;
14
16
  }
15
- export declare function Workspace({ layout, toolbar, sidebar, sidePanel, sidebarWidth, sidePanelWidth, sidebarOpen, sidePanelOpen, children, className, ref, render, style, ...props }: WorkspaceProps): import("react").JSX.Element;
17
+ /** The sidebar, the toolbar and the content on one raised sheet, with the side panel and the rail behind it. */
18
+ export declare function Workspace({ layout, toolbar, sidebar, sidePanel, rail, sidebarWidth, sidePanelWidth, sidebarOpen, sidePanelOpen, children, className, ref, render, style, ...props }: WorkspaceProps): import("react").JSX.Element;