@estiva-app/ui 0.12.0 → 0.12.1
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/AppShell.d.ts.map +1 -1
- package/dist/index.js +88 -86
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/src/AppShell.mdx +15 -0
- package/src/AppShell.stories.tsx +15 -0
- package/src/AppShell.test.tsx +39 -0
- package/src/AppShell.tsx +22 -7
- package/src/EmptyState.mdx +5 -4
package/dist/AppShell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../src/AppShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"AppShell.d.ts","sourceRoot":"","sources":["../src/AppShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;IAC9B,uEAAuE;IACvE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,oEAAoE;IACpE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,gEAAgE;IAChE,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,qFAAqF;IACrF,GAAG,EAAE,SAAS,CAAA;IACd,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,OAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,aAAa,+BA6DjH"}
|
package/dist/index.js
CHANGED
|
@@ -34,11 +34,36 @@ function cn(...inputs) {
|
|
|
34
34
|
return twMerge(clsx(inputs));
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// src/
|
|
37
|
+
// src/ScrollArea.tsx
|
|
38
|
+
import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
|
|
38
39
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
40
|
+
var BAR = "flex touch-none select-none rounded-full opacity-0 transition-opacity delay-300 data-[hovering]:opacity-100 data-[hovering]:delay-0 data-[scrolling]:opacity-100 data-[scrolling]:delay-0";
|
|
41
|
+
var THUMB = "rounded-full bg-border-strong";
|
|
42
|
+
function ScrollArea({ orientation = "vertical", className, viewportClassName, contentClassName, children }) {
|
|
43
|
+
const vertical = orientation !== "horizontal";
|
|
44
|
+
const horizontal = orientation !== "vertical";
|
|
45
|
+
return /* @__PURE__ */ jsxs(BaseScrollArea.Root, { className: cn("relative min-h-0 min-w-0", className), children: [
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
BaseScrollArea.Viewport,
|
|
48
|
+
{
|
|
49
|
+
className: cn(
|
|
50
|
+
"h-full w-full outline-none data-[has-overflow-x]:overscroll-x-contain data-[has-overflow-y]:overscroll-y-contain",
|
|
51
|
+
viewportClassName
|
|
52
|
+
),
|
|
53
|
+
children: /* @__PURE__ */ jsx(BaseScrollArea.Content, { className: contentClassName, style: horizontal ? void 0 : { minWidth: 0 }, children })
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
vertical && /* @__PURE__ */ jsx(BaseScrollArea.Scrollbar, { orientation: "vertical", className: cn(BAR, "w-1.5 justify-center py-0.5 pr-0.5"), children: /* @__PURE__ */ jsx(BaseScrollArea.Thumb, { className: cn(THUMB, "w-full") }) }),
|
|
57
|
+
horizontal && /* @__PURE__ */ jsx(BaseScrollArea.Scrollbar, { orientation: "horizontal", className: cn(BAR, "h-1.5 flex-col justify-center px-0.5 pb-0.5"), children: /* @__PURE__ */ jsx(BaseScrollArea.Thumb, { className: cn(THUMB, "h-full") }) }),
|
|
58
|
+
vertical && horizontal && /* @__PURE__ */ jsx(BaseScrollArea.Corner, {})
|
|
59
|
+
] });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// src/TopBar.tsx
|
|
63
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
39
64
|
function TopBar({ variant = "solid", menu, logo, search, right, className }) {
|
|
40
65
|
const floating = variant === "floating";
|
|
41
|
-
return /* @__PURE__ */
|
|
66
|
+
return /* @__PURE__ */ jsxs2(
|
|
42
67
|
"header",
|
|
43
68
|
{
|
|
44
69
|
className: cn(
|
|
@@ -47,27 +72,27 @@ function TopBar({ variant = "solid", menu, logo, search, right, className }) {
|
|
|
47
72
|
className
|
|
48
73
|
),
|
|
49
74
|
children: [
|
|
50
|
-
(menu || logo) && /* @__PURE__ */
|
|
75
|
+
(menu || logo) && /* @__PURE__ */ jsxs2("div", { className: cn("flex shrink-0 items-center gap-2", floating && "pointer-events-auto"), children: [
|
|
51
76
|
menu,
|
|
52
|
-
logo && /* @__PURE__ */
|
|
77
|
+
logo && /* @__PURE__ */ jsx2("div", { className: "flex items-center text-body-2-strong text-text-primary", children: logo })
|
|
53
78
|
] }),
|
|
54
|
-
/* @__PURE__ */
|
|
55
|
-
/* @__PURE__ */
|
|
79
|
+
/* @__PURE__ */ jsx2("div", { className: cn("flex min-w-0 flex-1 items-center justify-center", floating && "pointer-events-auto"), children: search }),
|
|
80
|
+
/* @__PURE__ */ jsx2("div", { className: cn("flex shrink-0 items-center gap-[6px]", floating && "pointer-events-auto"), children: right })
|
|
56
81
|
]
|
|
57
82
|
}
|
|
58
83
|
);
|
|
59
84
|
}
|
|
60
85
|
|
|
61
86
|
// src/AppShell.tsx
|
|
62
|
-
import { jsx as
|
|
87
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
63
88
|
function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav, children }) {
|
|
64
|
-
const bar = /* @__PURE__ */
|
|
89
|
+
const bar = /* @__PURE__ */ jsx3(TopBar, { variant, menu, logo, search, right: identity });
|
|
65
90
|
if (variant === "floating") {
|
|
66
|
-
return /* @__PURE__ */
|
|
91
|
+
return /* @__PURE__ */ jsxs3("div", { className: "relative h-full min-h-0 overflow-hidden bg-bg-base", children: [
|
|
67
92
|
bar,
|
|
68
|
-
/* @__PURE__ */
|
|
93
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex h-full pb-4 pr-4 pt-[52px]", children: [
|
|
69
94
|
nav,
|
|
70
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ jsxs3(
|
|
71
96
|
"div",
|
|
72
97
|
{
|
|
73
98
|
className: cn(
|
|
@@ -76,7 +101,7 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
76
101
|
),
|
|
77
102
|
children: [
|
|
78
103
|
banner,
|
|
79
|
-
/* @__PURE__ */
|
|
104
|
+
/* @__PURE__ */ jsx3("main", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", children })
|
|
80
105
|
]
|
|
81
106
|
}
|
|
82
107
|
)
|
|
@@ -84,20 +109,22 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
84
109
|
] });
|
|
85
110
|
}
|
|
86
111
|
return (
|
|
87
|
-
/* `relative overflow-hidden` is the seal the floating manner already has
|
|
112
|
+
/* `relative overflow-hidden` is the seal the floating manner already has
|
|
113
|
+
(and the ScrollArea's own root is `relative`, so an absolutely placed
|
|
114
|
+
stray inside a page now belongs to the region and scrolls with it),
|
|
88
115
|
and it takes both halves: an absolutely positioned descendant with no
|
|
89
116
|
positioned ancestor belongs to the *viewport*, so a scroll container
|
|
90
117
|
never clips it and the document itself gains its position as scroll
|
|
91
118
|
range — the whole page scrolls, navigation and top bar included.
|
|
92
119
|
`relative` claims such strays for the shell; `overflow-hidden` clips
|
|
93
120
|
them at its edge. Either alone seals nothing. */
|
|
94
|
-
/* @__PURE__ */
|
|
121
|
+
/* @__PURE__ */ jsxs3("div", { className: "relative flex h-full min-h-0 flex-col overflow-hidden bg-bg-base text-text-primary", children: [
|
|
95
122
|
bar,
|
|
96
|
-
/* @__PURE__ */
|
|
123
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-1", children: [
|
|
97
124
|
nav,
|
|
98
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: [
|
|
99
126
|
banner,
|
|
100
|
-
/* @__PURE__ */
|
|
127
|
+
/* @__PURE__ */ jsx3(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex min-h-full flex-col", children: /* @__PURE__ */ jsx3("main", { className: "flex min-w-0 flex-1 flex-col", children }) })
|
|
101
128
|
] })
|
|
102
129
|
] })
|
|
103
130
|
] })
|
|
@@ -107,7 +134,7 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
107
134
|
// src/Avatar.tsx
|
|
108
135
|
import { useState } from "react";
|
|
109
136
|
import { IconUserFilled } from "@tabler/icons-react";
|
|
110
|
-
import { jsx as
|
|
137
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
111
138
|
var HUES = ["#56c8ff", "#ff8f6b", "#4ade8c", "#b18cff", "#ffc94d", "#ff7eb0", "#7ea8ff", "#5fdfd6"];
|
|
112
139
|
var hueFor = (key) => {
|
|
113
140
|
let h = 0;
|
|
@@ -123,13 +150,13 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
123
150
|
const [broken, setBroken] = useState(false);
|
|
124
151
|
const label = name || alt;
|
|
125
152
|
const picture = src && !broken ? src : void 0;
|
|
126
|
-
return /* @__PURE__ */
|
|
153
|
+
return /* @__PURE__ */ jsx4(
|
|
127
154
|
"div",
|
|
128
155
|
{
|
|
129
156
|
...spoken ? { role: "img", "aria-label": spoken } : { "aria-hidden": true },
|
|
130
157
|
className: cn("rounded-sm overflow-hidden shrink-0 bg-bg-inset", className),
|
|
131
158
|
style: { width: size, height: size },
|
|
132
|
-
children: picture ? /* @__PURE__ */
|
|
159
|
+
children: picture ? /* @__PURE__ */ jsx4("img", { src: picture, alt: "", className: "w-full h-full object-cover", onError: () => setBroken(true) }) : label ? /* @__PURE__ */ jsx4(
|
|
133
160
|
"div",
|
|
134
161
|
{
|
|
135
162
|
className: "w-full h-full flex items-center justify-center font-semibold leading-none",
|
|
@@ -143,29 +170,29 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
143
170
|
},
|
|
144
171
|
children: initialsFor(label)
|
|
145
172
|
}
|
|
146
|
-
) : /* @__PURE__ */
|
|
173
|
+
) : /* @__PURE__ */ jsx4("div", { className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx4(IconUserFilled, { size: Math.round(size * 0.5) }) })
|
|
147
174
|
}
|
|
148
175
|
);
|
|
149
176
|
}
|
|
150
177
|
|
|
151
178
|
// src/AvatarGroup.tsx
|
|
152
|
-
import { jsx as
|
|
179
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
153
180
|
function AvatarGroup({ members, size = 24 }) {
|
|
154
181
|
const visible = members.slice(0, 3);
|
|
155
182
|
const overlap = Math.round(size / 3);
|
|
156
183
|
const ring = size / 12;
|
|
157
|
-
return /* @__PURE__ */
|
|
184
|
+
return /* @__PURE__ */ jsx5("div", { className: "flex items-center", style: { paddingRight: overlap }, children: visible.map((member, i) => (
|
|
158
185
|
/*
|
|
159
186
|
The wrapper carries the overlap and the ring; the face carries
|
|
160
187
|
neither. It must never clip — see the note at the top of the file —
|
|
161
188
|
so it has the avatar's own radius and no overflow of its own.
|
|
162
189
|
*/
|
|
163
|
-
/* @__PURE__ */
|
|
190
|
+
/* @__PURE__ */ jsx5(
|
|
164
191
|
"span",
|
|
165
192
|
{
|
|
166
193
|
className: "relative flex rounded-sm",
|
|
167
194
|
style: { marginRight: -overlap, boxShadow: `0 0 0 ${ring}px var(--bg-surface)` },
|
|
168
|
-
children: /* @__PURE__ */
|
|
195
|
+
children: /* @__PURE__ */ jsx5(Avatar, { size, name: member.name, src: member.picture, label: member.name })
|
|
169
196
|
},
|
|
170
197
|
i
|
|
171
198
|
)
|
|
@@ -182,9 +209,9 @@ import { Button as BaseButton } from "@base-ui/react/button";
|
|
|
182
209
|
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
183
210
|
|
|
184
211
|
// src/Kbd.tsx
|
|
185
|
-
import { jsx as
|
|
212
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
186
213
|
function Kbd({ children, className }) {
|
|
187
|
-
return /* @__PURE__ */
|
|
214
|
+
return /* @__PURE__ */ jsx6(
|
|
188
215
|
"kbd",
|
|
189
216
|
{
|
|
190
217
|
className: cn(
|
|
@@ -199,21 +226,21 @@ function Kbd({ children, className }) {
|
|
|
199
226
|
}
|
|
200
227
|
|
|
201
228
|
// src/Tooltip.tsx
|
|
202
|
-
import { jsx as
|
|
229
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
203
230
|
var OPEN_DELAY = 300;
|
|
204
231
|
function TooltipProvider({ delay = OPEN_DELAY, closeDelay, timeout, children }) {
|
|
205
|
-
return /* @__PURE__ */
|
|
232
|
+
return /* @__PURE__ */ jsx7(BaseTooltip.Provider, { delay, closeDelay, timeout, children });
|
|
206
233
|
}
|
|
207
234
|
function Tooltip({ label, shortcut, className, ...props }) {
|
|
208
|
-
return /* @__PURE__ */
|
|
209
|
-
/* @__PURE__ */
|
|
210
|
-
shortcut && /* @__PURE__ */
|
|
235
|
+
return /* @__PURE__ */ jsxs4("div", { role: "tooltip", className: cn("bg-bg-elevated border border-border-default rounded-lg h-[30px] flex items-center justify-center gap-1.5 px-2 shadow-lg", className), ...props, children: [
|
|
236
|
+
/* @__PURE__ */ jsx7("span", { className: "text-caption text-text-primary whitespace-nowrap", children: label }),
|
|
237
|
+
shortcut && /* @__PURE__ */ jsx7(Kbd, { children: shortcut })
|
|
211
238
|
] });
|
|
212
239
|
}
|
|
213
240
|
var GAP = 6;
|
|
214
241
|
var VIEWPORT_PAD = 8;
|
|
215
242
|
function TooltipSurface({ label, shortcut, placement }) {
|
|
216
|
-
return /* @__PURE__ */
|
|
243
|
+
return /* @__PURE__ */ jsx7(BaseTooltip.Portal, { children: /* @__PURE__ */ jsx7(
|
|
217
244
|
BaseTooltip.Positioner,
|
|
218
245
|
{
|
|
219
246
|
side: placement,
|
|
@@ -222,10 +249,10 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
222
249
|
collisionPadding: VIEWPORT_PAD,
|
|
223
250
|
positionMethod: "fixed",
|
|
224
251
|
className: "pointer-events-none z-[9999]",
|
|
225
|
-
children: /* @__PURE__ */
|
|
252
|
+
children: /* @__PURE__ */ jsx7(
|
|
226
253
|
BaseTooltip.Popup,
|
|
227
254
|
{
|
|
228
|
-
render: /* @__PURE__ */
|
|
255
|
+
render: /* @__PURE__ */ jsx7(
|
|
229
256
|
Tooltip,
|
|
230
257
|
{
|
|
231
258
|
label,
|
|
@@ -245,20 +272,20 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
245
272
|
) });
|
|
246
273
|
}
|
|
247
274
|
function WithTooltip({ label, shortcut, placement = "top", wrapperClassName, children }) {
|
|
248
|
-
return /* @__PURE__ */
|
|
249
|
-
/* @__PURE__ */
|
|
250
|
-
/* @__PURE__ */
|
|
275
|
+
return /* @__PURE__ */ jsxs4(BaseTooltip.Root, { disableHoverablePopup: true, children: [
|
|
276
|
+
/* @__PURE__ */ jsx7(BaseTooltip.Trigger, { delay: OPEN_DELAY, render: /* @__PURE__ */ jsx7("div", { className: cn("inline-flex shrink-0", wrapperClassName) }), children }),
|
|
277
|
+
/* @__PURE__ */ jsx7(TooltipSurface, { label, shortcut, placement })
|
|
251
278
|
] });
|
|
252
279
|
}
|
|
253
280
|
function TooltipTrigger({ label, shortcut, placement = "top", children }) {
|
|
254
|
-
return /* @__PURE__ */
|
|
255
|
-
/* @__PURE__ */
|
|
256
|
-
/* @__PURE__ */
|
|
281
|
+
return /* @__PURE__ */ jsxs4(BaseTooltip.Root, { disableHoverablePopup: true, children: [
|
|
282
|
+
/* @__PURE__ */ jsx7(BaseTooltip.Trigger, { delay: OPEN_DELAY, render: children }),
|
|
283
|
+
/* @__PURE__ */ jsx7(TooltipSurface, { label, shortcut, placement })
|
|
257
284
|
] });
|
|
258
285
|
}
|
|
259
286
|
|
|
260
287
|
// src/IconButton.tsx
|
|
261
|
-
import { jsx as
|
|
288
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
262
289
|
function IconButton({
|
|
263
290
|
variant = "muted",
|
|
264
291
|
className,
|
|
@@ -271,7 +298,7 @@ function IconButton({
|
|
|
271
298
|
type = "button",
|
|
272
299
|
...props
|
|
273
300
|
}) {
|
|
274
|
-
const button = /* @__PURE__ */
|
|
301
|
+
const button = /* @__PURE__ */ jsx8(
|
|
275
302
|
BaseButton,
|
|
276
303
|
{
|
|
277
304
|
type,
|
|
@@ -299,13 +326,13 @@ function IconButton({
|
|
|
299
326
|
);
|
|
300
327
|
const label = disabledReason ?? tooltip;
|
|
301
328
|
if (label) {
|
|
302
|
-
return /* @__PURE__ */
|
|
329
|
+
return /* @__PURE__ */ jsx8(TooltipTrigger, { label, shortcut: disabledReason ? void 0 : tooltipShortcut, placement: tooltipPlacement, children: button });
|
|
303
330
|
}
|
|
304
331
|
return button;
|
|
305
332
|
}
|
|
306
333
|
|
|
307
334
|
// src/Banner.tsx
|
|
308
|
-
import { jsx as
|
|
335
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
309
336
|
var TONE_STYLES = {
|
|
310
337
|
ok: "bg-success-muted text-success-default",
|
|
311
338
|
error: "bg-error-muted text-error-default",
|
|
@@ -315,17 +342,17 @@ var TONE_STYLES = {
|
|
|
315
342
|
function Banner({ tone, children, onDismiss, dismissLabel = "Dismiss", className }) {
|
|
316
343
|
const role = tone === "error" ? "alert" : "status";
|
|
317
344
|
if (!onDismiss) {
|
|
318
|
-
return /* @__PURE__ */
|
|
345
|
+
return /* @__PURE__ */ jsx9("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
|
|
319
346
|
}
|
|
320
|
-
return /* @__PURE__ */
|
|
321
|
-
/* @__PURE__ */
|
|
322
|
-
/* @__PURE__ */
|
|
347
|
+
return /* @__PURE__ */ jsxs5("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
|
|
348
|
+
/* @__PURE__ */ jsx9("span", { className: "min-w-0 flex-1", children }),
|
|
349
|
+
/* @__PURE__ */ jsx9(IconButton, { "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0 text-current hover:text-current", children: /* @__PURE__ */ jsx9(IconX, { size: 16, stroke: 1.5 }) })
|
|
323
350
|
] });
|
|
324
351
|
}
|
|
325
352
|
|
|
326
353
|
// src/Button.tsx
|
|
327
354
|
import { Button as BaseButton2 } from "@base-ui/react/button";
|
|
328
|
-
import { jsx as
|
|
355
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
329
356
|
function Button({
|
|
330
357
|
variant = "muted",
|
|
331
358
|
size = "default",
|
|
@@ -338,7 +365,7 @@ function Button({
|
|
|
338
365
|
...props
|
|
339
366
|
}) {
|
|
340
367
|
const hasLeadingIcon = !!leadingIcon;
|
|
341
|
-
const button = /* @__PURE__ */
|
|
368
|
+
const button = /* @__PURE__ */ jsxs6(
|
|
342
369
|
BaseButton2,
|
|
343
370
|
{
|
|
344
371
|
type,
|
|
@@ -372,13 +399,13 @@ function Button({
|
|
|
372
399
|
]
|
|
373
400
|
}
|
|
374
401
|
);
|
|
375
|
-
return disabledReason ? /* @__PURE__ */
|
|
402
|
+
return disabledReason ? /* @__PURE__ */ jsx10(TooltipTrigger, { label: disabledReason, children: button }) : button;
|
|
376
403
|
}
|
|
377
404
|
|
|
378
405
|
// src/Checkbox.tsx
|
|
379
406
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
380
407
|
import { IconCheck } from "@tabler/icons-react";
|
|
381
|
-
import { jsx as
|
|
408
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
382
409
|
function squareClasses(checked, disabled, interactive, className) {
|
|
383
410
|
return cn(
|
|
384
411
|
"inline-flex items-center justify-center size-4 shrink-0 rounded-[4px] border transition-colors",
|
|
@@ -391,9 +418,9 @@ function squareClasses(checked, disabled, interactive, className) {
|
|
|
391
418
|
var tickClasses = (checked) => cn("flex", !checked && "invisible");
|
|
392
419
|
function Checkbox({ checked, onChange, disabled = false, className, ...aria }) {
|
|
393
420
|
if (!onChange) {
|
|
394
|
-
return /* @__PURE__ */
|
|
421
|
+
return /* @__PURE__ */ jsx11("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx11("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx11(IconCheck, { size: 12, stroke: 3 }) }) });
|
|
395
422
|
}
|
|
396
|
-
return /* @__PURE__ */
|
|
423
|
+
return /* @__PURE__ */ jsx11(
|
|
397
424
|
BaseCheckbox.Root,
|
|
398
425
|
{
|
|
399
426
|
checked,
|
|
@@ -403,13 +430,13 @@ function Checkbox({ checked, onChange, disabled = false, className, ...aria }) {
|
|
|
403
430
|
onCheckedChange: (next) => onChange(next),
|
|
404
431
|
onClick: (e) => e.stopPropagation(),
|
|
405
432
|
className: (state) => squareClasses(state.checked, state.disabled, true, className),
|
|
406
|
-
children: /* @__PURE__ */
|
|
433
|
+
children: /* @__PURE__ */ jsx11(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx11(IconCheck, { size: 12, stroke: 3 }) })
|
|
407
434
|
}
|
|
408
435
|
);
|
|
409
436
|
}
|
|
410
437
|
|
|
411
438
|
// src/Chip.tsx
|
|
412
|
-
import { jsx as
|
|
439
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
413
440
|
var typeStyles = {
|
|
414
441
|
neutral: "bg-bg-inset text-text-primary",
|
|
415
442
|
brand: "bg-accent-muted text-accent-primary signal:border signal:border-accent-outline",
|
|
@@ -419,8 +446,8 @@ var typeStyles = {
|
|
|
419
446
|
error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
|
|
420
447
|
};
|
|
421
448
|
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
|
|
422
|
-
return /* @__PURE__ */
|
|
423
|
-
leadingIcon && /* @__PURE__ */
|
|
449
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-full max-h-[20px] px-2 py-1", typeStyles[type], className), children: [
|
|
450
|
+
leadingIcon && /* @__PURE__ */ jsx12("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
424
451
|
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
425
452
|
// of growing past it — Ship's project chip on an issue row
|
|
426
453
|
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
@@ -429,8 +456,8 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
429
456
|
// the screenshot diff caught every descender cut off. `clip` is the
|
|
430
457
|
// one overflow that leaves the other axis visible. A chip with no cap
|
|
431
458
|
// draws exactly as before.
|
|
432
|
-
/* @__PURE__ */
|
|
433
|
-
trailingIcon && /* @__PURE__ */
|
|
459
|
+
/* @__PURE__ */ jsx12("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-[10px] signal:font-semibold signal:tracking-[0.02em] signal:tabular-nums", children: label }),
|
|
460
|
+
trailingIcon && /* @__PURE__ */ jsx12("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
434
461
|
] });
|
|
435
462
|
}
|
|
436
463
|
|
|
@@ -467,31 +494,6 @@ function triggerDisabled(trigger) {
|
|
|
467
494
|
return !!(props.disabled || props.disabledReason);
|
|
468
495
|
}
|
|
469
496
|
|
|
470
|
-
// src/ScrollArea.tsx
|
|
471
|
-
import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
|
|
472
|
-
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
473
|
-
var BAR = "flex touch-none select-none rounded-full opacity-0 transition-opacity delay-300 data-[hovering]:opacity-100 data-[hovering]:delay-0 data-[scrolling]:opacity-100 data-[scrolling]:delay-0";
|
|
474
|
-
var THUMB = "rounded-full bg-border-strong";
|
|
475
|
-
function ScrollArea({ orientation = "vertical", className, viewportClassName, contentClassName, children }) {
|
|
476
|
-
const vertical = orientation !== "horizontal";
|
|
477
|
-
const horizontal = orientation !== "vertical";
|
|
478
|
-
return /* @__PURE__ */ jsxs7(BaseScrollArea.Root, { className: cn("relative min-h-0 min-w-0", className), children: [
|
|
479
|
-
/* @__PURE__ */ jsx12(
|
|
480
|
-
BaseScrollArea.Viewport,
|
|
481
|
-
{
|
|
482
|
-
className: cn(
|
|
483
|
-
"h-full w-full outline-none data-[has-overflow-x]:overscroll-x-contain data-[has-overflow-y]:overscroll-y-contain",
|
|
484
|
-
viewportClassName
|
|
485
|
-
),
|
|
486
|
-
children: /* @__PURE__ */ jsx12(BaseScrollArea.Content, { className: contentClassName, style: horizontal ? void 0 : { minWidth: 0 }, children })
|
|
487
|
-
}
|
|
488
|
-
),
|
|
489
|
-
vertical && /* @__PURE__ */ jsx12(BaseScrollArea.Scrollbar, { orientation: "vertical", className: cn(BAR, "w-1.5 justify-center py-0.5 pr-0.5"), children: /* @__PURE__ */ jsx12(BaseScrollArea.Thumb, { className: cn(THUMB, "w-full") }) }),
|
|
490
|
-
horizontal && /* @__PURE__ */ jsx12(BaseScrollArea.Scrollbar, { orientation: "horizontal", className: cn(BAR, "h-1.5 flex-col justify-center px-0.5 pb-0.5"), children: /* @__PURE__ */ jsx12(BaseScrollArea.Thumb, { className: cn(THUMB, "h-full") }) }),
|
|
491
|
-
vertical && horizontal && /* @__PURE__ */ jsx12(BaseScrollArea.Corner, {})
|
|
492
|
-
] });
|
|
493
|
-
}
|
|
494
|
-
|
|
495
497
|
// src/SectionLabel.tsx
|
|
496
498
|
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
497
499
|
function SectionLabel({ children, className }) {
|