@estiva-app/ui 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/Breadcrumb.d.ts +7 -1
- package/dist/Breadcrumb.d.ts.map +1 -1
- package/dist/Chip.d.ts.map +1 -1
- package/dist/CollapsibleSection.d.ts +42 -0
- package/dist/CollapsibleSection.d.ts.map +1 -0
- package/dist/EmptyState.d.ts +19 -5
- package/dist/EmptyState.d.ts.map +1 -1
- package/dist/NavItem.d.ts.map +1 -1
- package/dist/ScrollArea.d.ts.map +1 -1
- package/dist/SectionHeader.d.ts +31 -10
- package/dist/SectionHeader.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +126 -55
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/src/Breadcrumb.mdx +6 -0
- package/src/Breadcrumb.stories.tsx +12 -0
- package/src/Breadcrumb.test.tsx +10 -0
- package/src/Breadcrumb.tsx +17 -2
- package/src/Chip.tsx +10 -2
- package/src/CollapsibleSection.mdx +72 -0
- package/src/CollapsibleSection.stories.tsx +38 -0
- package/src/CollapsibleSection.test.tsx +81 -0
- package/src/CollapsibleSection.tsx +92 -0
- package/src/EmptyState.mdx +30 -11
- package/src/EmptyState.stories.tsx +7 -3
- package/src/EmptyState.test.tsx +39 -0
- package/src/EmptyState.tsx +23 -6
- package/src/NavItem.tsx +5 -1
- package/src/ScrollArea.mdx +6 -0
- package/src/ScrollArea.stories.tsx +29 -0
- package/src/ScrollArea.test.tsx +15 -0
- package/src/ScrollArea.tsx +17 -4
- package/src/SectionHeader.mdx +26 -17
- package/src/SectionHeader.stories.tsx +4 -35
- package/src/SectionHeader.test.tsx +40 -0
- package/src/SectionHeader.tsx +70 -39
- package/src/Sidebar.mdx +14 -10
- package/src/Sidebar.stories.tsx +17 -15
- package/src/index.ts +1 -0
- package/stories/Choosing.mdx +2 -1
package/dist/Breadcrumb.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MouseEventHandler } from 'react';
|
|
1
|
+
import { type MouseEventHandler, type ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* A trail: "Documents / Quarterly plan / DOC-12". Ship's Breadcrumb
|
|
4
4
|
* (2026-09-01), which knows nothing about what the places are.
|
|
@@ -26,6 +26,12 @@ export interface Crumb {
|
|
|
26
26
|
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
27
27
|
/** Set the item in the mono face — a ref, an id. */
|
|
28
28
|
mono?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* 16px, stroke 1.5, before the label — what kind of place this is, so a
|
|
31
|
+
* container's name is not mistaken for an item's (Katerina, 2026-09-09).
|
|
32
|
+
* Decorative: the label says where you are; the icon says what it is.
|
|
33
|
+
*/
|
|
34
|
+
icon?: ReactNode;
|
|
29
35
|
/** Quieter — a label that is not a place. */
|
|
30
36
|
muted?: boolean;
|
|
31
37
|
}
|
package/dist/Breadcrumb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb.d.ts","sourceRoot":"","sources":["../src/Breadcrumb.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"Breadcrumb.d.ts","sourceRoot":"","sources":["../src/Breadcrumb.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIxH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,OAAO,CAAC,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;IAC9C,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,EAAE,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,+BAkF/D"}
|
package/dist/Chip.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../src/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAErF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAWD,wBAAgB,IAAI,CAAC,EAAE,IAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,SAAS,+
|
|
1
|
+
{"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../src/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAErF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAWD,wBAAgB,IAAI,CAAC,EAAE,IAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,SAAS,+BAkBhG"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type SectionAction } from './SectionHeader';
|
|
3
|
+
/**
|
|
4
|
+
* A section that opens and closes: a `SectionHeader` whose title is the
|
|
5
|
+
* toggle, and the rows under it, sliding shut and open (Katerina,
|
|
6
|
+
* 2026-09-09, for the sidebars of both apps). On Base UI's `Collapsible`
|
|
7
|
+
* (D6): the state, the title button's `aria-expanded` and `aria-controls`,
|
|
8
|
+
* Enter and Space, the panel's height for the slide, and `hiddenUntilFound`
|
|
9
|
+
* — the browser's find-in-page can find a row inside a closed section and
|
|
10
|
+
* open it, because the rows stay in the DOM while closed.
|
|
11
|
+
*
|
|
12
|
+
* Three ways to hold the state, from least to most work for the caller:
|
|
13
|
+
*
|
|
14
|
+
* - none: `defaultOpen` (open unless told otherwise), kept while mounted;
|
|
15
|
+
* - `storageKey`: the same, and this browser remembers it under that key
|
|
16
|
+
* across reloads — one prop for a sidebar that stays how you left it;
|
|
17
|
+
* - `open` + `onOpenChange`: the caller owns it.
|
|
18
|
+
*
|
|
19
|
+
* A closed section stays closed whatever is selected inside it (her
|
|
20
|
+
* ruling, 2026-09-09) — the reader closed it.
|
|
21
|
+
*/
|
|
22
|
+
export interface CollapsibleSectionProps {
|
|
23
|
+
title: string;
|
|
24
|
+
/** Open unless told otherwise. */
|
|
25
|
+
defaultOpen?: boolean;
|
|
26
|
+
/** The caller owns the state. */
|
|
27
|
+
open?: boolean;
|
|
28
|
+
onOpenChange?: (open: boolean) => void;
|
|
29
|
+
/** Remember open or closed in this browser, under this key. The app prefixes it. */
|
|
30
|
+
storageKey?: string;
|
|
31
|
+
/** Beside the title, revealed on hover or focus — `SectionHeader`'s. */
|
|
32
|
+
actions?: SectionAction[];
|
|
33
|
+
showActions?: 'hover' | 'always';
|
|
34
|
+
/** The rows. */
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
/** On the section's box: `mt-2` between groups, `shrink-0` in a scrolling column. */
|
|
37
|
+
className?: string;
|
|
38
|
+
/** On the box the rows sit in: the gap between them. */
|
|
39
|
+
contentClassName?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function CollapsibleSection({ title, defaultOpen, open: openProp, onOpenChange, storageKey, actions, showActions, children, className, contentClassName }: CollapsibleSectionProps): import("react").JSX.Element;
|
|
42
|
+
//# sourceMappingURL=CollapsibleSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollapsibleSection.d.ts","sourceRoot":"","sources":["../src/CollapsibleSection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGhD,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEnE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAChC,gBAAgB;IAChB,QAAQ,EAAE,SAAS,CAAA;IACnB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAwBD,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,WAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,uBAAuB,+BAyB/L"}
|
package/dist/EmptyState.d.ts
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* The place where content will be once there is some, in two manners
|
|
4
|
+
* (Katerina, 2026-09-09):
|
|
5
|
+
*
|
|
6
|
+
* - `page` — the whole page is empty: a 16px icon over a centred line of
|
|
7
|
+
* secondary text, **in the middle of its box both ways** (Katerina,
|
|
8
|
+
* 2026-09-09: it sat near the top). It grows to the room a flex column
|
|
9
|
+
* gives it (`flex-1`) and centres inside that; a caller that draws it
|
|
10
|
+
* straight into a page hands it the height (`className="h-full"`).
|
|
11
|
+
* Peek's EmptyState (2026-08-28) otherwise; the default.
|
|
12
|
+
* - `section` — one section of a page is empty, and the page has other
|
|
13
|
+
* things on it: the line alone, left-aligned, no icon. A section's
|
|
14
|
+
* emptiness is a line among the page's content, not a stage of its own.
|
|
15
|
+
*
|
|
16
|
+
* The message is the caller's — a shared component has no words of its own
|
|
17
|
+
* for what is missing.
|
|
6
18
|
*/
|
|
7
19
|
export interface EmptyStateProps {
|
|
8
|
-
/** 16px, stroke 1.5. A speech bubble when absent. */
|
|
20
|
+
/** 16px, stroke 1.5. A speech bubble when absent. Drawn for a `page` only. */
|
|
9
21
|
icon?: ReactNode;
|
|
10
22
|
message: string;
|
|
23
|
+
/** `page` when the whole page is empty; `section` when one part of it is. */
|
|
24
|
+
scope?: 'page' | 'section';
|
|
11
25
|
className?: string;
|
|
12
26
|
}
|
|
13
|
-
export declare function EmptyState({ icon, message, className }: EmptyStateProps): import("react").JSX.Element;
|
|
27
|
+
export declare function EmptyState({ icon, message, scope, className }: EmptyStateProps): import("react").JSX.Element;
|
|
14
28
|
//# sourceMappingURL=EmptyState.d.ts.map
|
package/dist/EmptyState.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.d.ts","sourceRoot":"","sources":["../src/EmptyState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC
|
|
1
|
+
{"version":3,"file":"EmptyState.d.ts","sourceRoot":"","sources":["../src/EmptyState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAc,EAAE,SAAS,EAAE,EAAE,eAAe,+BAUvF"}
|
package/dist/NavItem.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavItem.d.ts","sourceRoot":"","sources":["../src/NavItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAIhE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAC/E,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,MAAc,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+
|
|
1
|
+
{"version":3,"file":"NavItem.d.ts","sourceRoot":"","sources":["../src/NavItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAIhE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAC/E,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,wBAAwB;IACxB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,MAAc,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BA4BlH"}
|
package/dist/ScrollArea.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScrollArea.d.ts","sourceRoot":"","sources":["../src/ScrollArea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAA;IAChD,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAKD,wBAAgB,UAAU,CAAC,EAAE,WAAwB,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,eAAe,+
|
|
1
|
+
{"version":3,"file":"ScrollArea.d.ts","sourceRoot":"","sources":["../src/ScrollArea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAA;IAChD,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAKD,wBAAgB,UAAU,CAAC,EAAE,WAAwB,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,eAAe,+BA0CjI"}
|
package/dist/SectionHeader.d.ts
CHANGED
|
@@ -1,16 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
3
|
/**
|
|
3
4
|
* The 32px row a section starts with (Peek's SectionHeader, 2026-09-01):
|
|
4
|
-
* a SectionLabel, an optional collapse chevron that makes the
|
|
5
|
-
* toggle, and actions that appear
|
|
5
|
+
* a SectionLabel, an optional collapse chevron that makes the title the
|
|
6
|
+
* toggle, and actions that appear while the row is hovered or focused, as
|
|
6
7
|
* IconButtons with tooltips.
|
|
7
8
|
*
|
|
9
|
+
* Three things changed on 2026-09-09, for `CollapsibleSection`:
|
|
10
|
+
*
|
|
11
|
+
* - **The title is a button when it toggles.** It was a `div` with an
|
|
12
|
+
* `onClick`, so the keyboard could not open or close a section at all.
|
|
13
|
+
* The button fills the row up to the actions, so the whole row is still
|
|
14
|
+
* the hit target; the actions sit beside it rather than inside it,
|
|
15
|
+
* because a button inside a button is invalid HTML — and was why every
|
|
16
|
+
* action had to stop its click from also toggling.
|
|
17
|
+
* - **The hover is CSS.** The fill and the actions' reveal were React
|
|
18
|
+
* state (`isHovered`), which the README forbids — a mount cannot stay in
|
|
19
|
+
* step with a transition. `group-hover` now; the actions are in the row
|
|
20
|
+
* at `opacity-0` until hovered or focused, so a keyboard user reaches
|
|
21
|
+
* them too.
|
|
22
|
+
* - **`render`** lets `CollapsibleSection` hand in Base UI's
|
|
23
|
+
* `Collapsible.Trigger` as the title button — one header for the
|
|
24
|
+
* hand-held section (`isExpanded` / `onToggle`) and the Base UI one,
|
|
25
|
+
* with no second click handler.
|
|
26
|
+
*
|
|
8
27
|
* One API change from Peek's original, safe because no call site used the
|
|
9
28
|
* old shape yet: the two hard-wired action slots (add, sort) became
|
|
10
|
-
* `actions` — the caller brings the icon, the tooltip and the handler
|
|
11
|
-
* header owns the hover reveal and stops the click from also toggling the
|
|
12
|
-
* section. Peek's add/sort pair is the WithActions story, in its original
|
|
13
|
-
* order.
|
|
29
|
+
* `actions` — the caller brings the icon, the tooltip and the handler.
|
|
14
30
|
*/
|
|
15
31
|
export interface SectionAction {
|
|
16
32
|
/** 16px, stroke 1.5. */
|
|
@@ -20,15 +36,20 @@ export interface SectionAction {
|
|
|
20
36
|
}
|
|
21
37
|
export interface SectionHeaderProps {
|
|
22
38
|
title: string;
|
|
23
|
-
/** Collapsible: draws the chevron and makes the
|
|
39
|
+
/** Collapsible: draws the chevron and makes the title a button that toggles. */
|
|
24
40
|
chevron?: boolean;
|
|
25
41
|
isExpanded?: boolean;
|
|
26
42
|
onToggle?: () => void;
|
|
27
43
|
/** Right-aligned, in the order given. */
|
|
28
44
|
actions?: SectionAction[];
|
|
29
|
-
/** `hover` reveals the actions
|
|
45
|
+
/** `hover` reveals the actions while the row is hovered or focused; `always` keeps them. */
|
|
30
46
|
showActions?: 'hover' | 'always';
|
|
47
|
+
/**
|
|
48
|
+
* What the title renders as, in Base UI's manner. A plain button with
|
|
49
|
+
* `onToggle` by default; `CollapsibleSection` hands in `Collapsible.Trigger`.
|
|
50
|
+
*/
|
|
51
|
+
render?: useRender.RenderProp;
|
|
31
52
|
className?: string;
|
|
32
53
|
}
|
|
33
|
-
export declare function SectionHeader({ title, chevron, isExpanded, onToggle, actions, showActions, className }: SectionHeaderProps): import("react").JSX.Element;
|
|
54
|
+
export declare function SectionHeader({ title, chevron, isExpanded, onToggle, actions, showActions, render, className }: SectionHeaderProps): import("react").JSX.Element;
|
|
34
55
|
//# sourceMappingURL=SectionHeader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionHeader.d.ts","sourceRoot":"","sources":["../src/SectionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"SectionHeader.d.ts","sourceRoot":"","sources":["../src/SectionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAKrD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,yCAAyC;IACzC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAChC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC,UAAU,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,OAAe,EAAE,UAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAqB,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,+BAuD3J"}
|
package/dist/index.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ export { Property, type PropertyProps } from './Property';
|
|
|
49
49
|
export { Reaction, type ReactionProps } from './Reaction';
|
|
50
50
|
export { SearchInput, type SearchInputProps } from './SearchInput';
|
|
51
51
|
export { SectionHeader, type SectionAction, type SectionHeaderProps } from './SectionHeader';
|
|
52
|
+
export { CollapsibleSection, type CollapsibleSectionProps } from './CollapsibleSection';
|
|
52
53
|
export { SectionLabel } from './SectionLabel';
|
|
53
54
|
export { Tabs, type TabDef, type TabsProps } from './Tabs';
|
|
54
55
|
export { Toast, ToastProvider, useToast, type ToastOptions, type ToastProps, type ToastType } from './Toast';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -419,9 +419,17 @@ var typeStyles = {
|
|
|
419
419
|
error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
|
|
420
420
|
};
|
|
421
421
|
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
|
|
422
|
-
return /* @__PURE__ */ jsxs6("div", { className: cn("inline-flex items-center justify-center gap-1.5 rounded-full max-h-[20px]
|
|
422
|
+
return /* @__PURE__ */ jsxs6("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: [
|
|
423
423
|
leadingIcon && /* @__PURE__ */ jsx11("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
424
|
-
label &&
|
|
424
|
+
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
425
|
+
// of growing past it — Ship's project chip on an issue row
|
|
426
|
+
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
427
|
+
// `truncate`, because `truncate` is `overflow: hidden` on both axes and
|
|
428
|
+
// the label's line box (11px under Signal) is tighter than its glyphs —
|
|
429
|
+
// the screenshot diff caught every descender cut off. `clip` is the
|
|
430
|
+
// one overflow that leaves the other axis visible. A chip with no cap
|
|
431
|
+
// draws exactly as before.
|
|
432
|
+
/* @__PURE__ */ jsx11("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 }),
|
|
425
433
|
trailingIcon && /* @__PURE__ */ jsx11("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
426
434
|
] });
|
|
427
435
|
}
|
|
@@ -468,7 +476,16 @@ function ScrollArea({ orientation = "vertical", className, viewportClassName, co
|
|
|
468
476
|
const vertical = orientation !== "horizontal";
|
|
469
477
|
const horizontal = orientation !== "vertical";
|
|
470
478
|
return /* @__PURE__ */ jsxs7(BaseScrollArea.Root, { className: cn("relative min-h-0 min-w-0", className), children: [
|
|
471
|
-
/* @__PURE__ */ jsx12(
|
|
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
|
+
),
|
|
472
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") }) }),
|
|
473
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") }) }),
|
|
474
491
|
vertical && horizontal && /* @__PURE__ */ jsx12(BaseScrollArea.Corner, {})
|
|
@@ -1428,8 +1445,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1428
1445
|
// src/EmptyState.tsx
|
|
1429
1446
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1430
1447
|
import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1431
|
-
function EmptyState({ icon, message, className }) {
|
|
1432
|
-
|
|
1448
|
+
function EmptyState({ icon, message, scope = "page", className }) {
|
|
1449
|
+
if (scope === "section") {
|
|
1450
|
+
return /* @__PURE__ */ jsx27("p", { className: cn("text-body-2 text-text-secondary", className), children: message });
|
|
1451
|
+
}
|
|
1452
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1433
1453
|
/* @__PURE__ */ jsx27("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx27(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1434
1454
|
/* @__PURE__ */ jsx27("p", { className: "text-body-2 text-text-secondary text-center", children: message })
|
|
1435
1455
|
] });
|
|
@@ -1475,13 +1495,14 @@ function Breadcrumb({ items, className }) {
|
|
|
1475
1495
|
}, [measure, items]);
|
|
1476
1496
|
return /* @__PURE__ */ jsx29("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-[14px] leading-[140%]", className), children: items.map((item, index) => {
|
|
1477
1497
|
const last = index === items.length - 1;
|
|
1498
|
+
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
1478
1499
|
const text = cn(
|
|
1479
1500
|
"truncate",
|
|
1480
1501
|
// A mono crumb is a ref — the identity. It never gives up width to a
|
|
1481
1502
|
// long name beside it (the LongName story always claimed "the ref
|
|
1482
1503
|
// stays"; flexbox was squeezing it anyway until this line).
|
|
1483
1504
|
item.mono && "shrink-0 font-mono text-[12px] leading-[120%]",
|
|
1484
|
-
|
|
1505
|
+
tone
|
|
1485
1506
|
);
|
|
1486
1507
|
const setLabelRef = (el) => {
|
|
1487
1508
|
labelRefs.current[index] = el;
|
|
@@ -1489,6 +1510,7 @@ function Breadcrumb({ items, className }) {
|
|
|
1489
1510
|
const crumb = item.href ? /* @__PURE__ */ jsx29("a", { ref: setLabelRef, href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label }) : /* @__PURE__ */ jsx29("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
1490
1511
|
return /* @__PURE__ */ jsxs20(Fragment4, { children: [
|
|
1491
1512
|
index > 0 && /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
1513
|
+
item.icon && /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
1492
1514
|
truncated.has(index) ? (
|
|
1493
1515
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
1494
1516
|
// must keep truncating inside it, or wrapping it would widen the
|
|
@@ -1519,7 +1541,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
1519
1541
|
children: [
|
|
1520
1542
|
icon && /* @__PURE__ */ jsx30("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
1521
1543
|
/* @__PURE__ */ jsx30("span", { className: "flex-1 truncate", children: label }),
|
|
1522
|
-
count ? /* @__PURE__ */ jsx30(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx30("span", { className: "shrink-0 font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
1544
|
+
count ? /* @__PURE__ */ jsx30(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx30("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
1523
1545
|
]
|
|
1524
1546
|
}
|
|
1525
1547
|
);
|
|
@@ -1818,58 +1840,106 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
1818
1840
|
}
|
|
1819
1841
|
|
|
1820
1842
|
// src/SectionHeader.tsx
|
|
1821
|
-
import { useState as useState6 } from "react";
|
|
1822
1843
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
1823
|
-
import {
|
|
1824
|
-
|
|
1825
|
-
|
|
1844
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
1845
|
+
import { Fragment as Fragment5, jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
1846
|
+
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, actions, showActions = "hover", render, className }) {
|
|
1847
|
+
const titleElement = useRender({
|
|
1848
|
+
render: render ?? (chevron ? /* @__PURE__ */ jsx41("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx41("span", {})),
|
|
1849
|
+
props: {
|
|
1850
|
+
// `text-left`: a button centres its text. `h-full` and `flex-1`: the
|
|
1851
|
+
// whole row up to the actions is the hit target, as it was when the
|
|
1852
|
+
// row itself carried the click.
|
|
1853
|
+
className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
|
|
1854
|
+
children: /* @__PURE__ */ jsxs28(Fragment5, { children: [
|
|
1855
|
+
chevron && /* @__PURE__ */ jsx41(
|
|
1856
|
+
IconChevronRight2,
|
|
1857
|
+
{
|
|
1858
|
+
size: 12,
|
|
1859
|
+
stroke: 1.5,
|
|
1860
|
+
className: cn("shrink-0 text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
|
|
1861
|
+
}
|
|
1862
|
+
),
|
|
1863
|
+
/* @__PURE__ */ jsx41(SectionLabel, { children: title })
|
|
1864
|
+
] })
|
|
1865
|
+
}
|
|
1866
|
+
});
|
|
1826
1867
|
return /* @__PURE__ */ jsxs28(
|
|
1827
1868
|
"div",
|
|
1828
1869
|
{
|
|
1829
1870
|
className: cn(
|
|
1830
|
-
"flex h-[32px] items-center
|
|
1831
|
-
|
|
1832
|
-
|
|
1871
|
+
"group flex h-[32px] items-center gap-1 rounded-lg px-2 transition-colors",
|
|
1872
|
+
// The fill says "this does something": a row with a toggle or actions
|
|
1873
|
+
// lights up, a fixed heading over rows does not (2026-09-09, the
|
|
1874
|
+
// Sidebar's fixed group).
|
|
1875
|
+
(chevron || actions && actions.length > 0) && "hover:bg-bg-hover",
|
|
1833
1876
|
className
|
|
1834
1877
|
),
|
|
1835
|
-
onClick: chevron ? onToggle : void 0,
|
|
1836
|
-
onMouseEnter: () => setIsHovered(true),
|
|
1837
|
-
onMouseLeave: () => setIsHovered(false),
|
|
1838
1878
|
children: [
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
{
|
|
1843
|
-
size: 12,
|
|
1844
|
-
stroke: 1.5,
|
|
1845
|
-
className: cn("text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
|
|
1846
|
-
}
|
|
1847
|
-
),
|
|
1848
|
-
/* @__PURE__ */ jsx41(SectionLabel, { children: title })
|
|
1849
|
-
] }),
|
|
1850
|
-
(showActions === "always" || isHovered) && actions && actions.length > 0 && /* @__PURE__ */ jsx41("div", { className: "flex items-center gap-1", children: actions.map((action) => /* @__PURE__ */ jsx41(
|
|
1851
|
-
IconButton,
|
|
1879
|
+
titleElement,
|
|
1880
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx41(
|
|
1881
|
+
"div",
|
|
1852
1882
|
{
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
},
|
|
1861
|
-
action.tooltip
|
|
1862
|
-
)) })
|
|
1883
|
+
className: cn(
|
|
1884
|
+
"-mr-1 flex shrink-0 items-center gap-1",
|
|
1885
|
+
showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
|
|
1886
|
+
),
|
|
1887
|
+
children: actions.map((action) => /* @__PURE__ */ jsx41(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
|
|
1888
|
+
}
|
|
1889
|
+
)
|
|
1863
1890
|
]
|
|
1864
1891
|
}
|
|
1865
1892
|
);
|
|
1866
1893
|
}
|
|
1867
1894
|
|
|
1895
|
+
// src/CollapsibleSection.tsx
|
|
1896
|
+
import { useState as useState6 } from "react";
|
|
1897
|
+
import { Collapsible } from "@base-ui/react/collapsible";
|
|
1898
|
+
import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
1899
|
+
var OPEN = "open";
|
|
1900
|
+
var CLOSED = "closed";
|
|
1901
|
+
function readStored(key) {
|
|
1902
|
+
if (!key) return void 0;
|
|
1903
|
+
try {
|
|
1904
|
+
const value = window.localStorage.getItem(key);
|
|
1905
|
+
return value === OPEN ? true : value === CLOSED ? false : void 0;
|
|
1906
|
+
} catch {
|
|
1907
|
+
return void 0;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
function writeStored(key, open) {
|
|
1911
|
+
if (!key) return;
|
|
1912
|
+
try {
|
|
1913
|
+
window.localStorage.setItem(key, open ? OPEN : CLOSED);
|
|
1914
|
+
} catch {
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, actions, showActions, children, className, contentClassName }) {
|
|
1918
|
+
const [openState, setOpenState] = useState6(() => readStored(storageKey) ?? defaultOpen);
|
|
1919
|
+
const open = openProp ?? openState;
|
|
1920
|
+
const setOpen = (next) => {
|
|
1921
|
+
setOpenState(next);
|
|
1922
|
+
writeStored(storageKey, next);
|
|
1923
|
+
onOpenChange?.(next);
|
|
1924
|
+
};
|
|
1925
|
+
return /* @__PURE__ */ jsxs29(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
1926
|
+
/* @__PURE__ */ jsx42(SectionHeader, { title, chevron: true, isExpanded: open, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx42(Collapsible.Trigger, {}) }),
|
|
1927
|
+
/* @__PURE__ */ jsx42(
|
|
1928
|
+
Collapsible.Panel,
|
|
1929
|
+
{
|
|
1930
|
+
hiddenUntilFound: true,
|
|
1931
|
+
className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0",
|
|
1932
|
+
children: /* @__PURE__ */ jsx42("div", { className: cn("flex flex-col", contentClassName), children })
|
|
1933
|
+
}
|
|
1934
|
+
)
|
|
1935
|
+
] });
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1868
1938
|
// src/Tabs.tsx
|
|
1869
1939
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
1870
|
-
import { jsx as
|
|
1940
|
+
import { jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
1871
1941
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
1872
|
-
return /* @__PURE__ */
|
|
1942
|
+
return /* @__PURE__ */ jsx43(
|
|
1873
1943
|
BaseTabs.Root,
|
|
1874
1944
|
{
|
|
1875
1945
|
value: active,
|
|
@@ -1877,14 +1947,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1877
1947
|
if (details.reason === "none") onChange(value);
|
|
1878
1948
|
},
|
|
1879
1949
|
className,
|
|
1880
|
-
children: /* @__PURE__ */
|
|
1950
|
+
children: /* @__PURE__ */ jsx43(
|
|
1881
1951
|
BaseTabs.List,
|
|
1882
1952
|
{
|
|
1883
1953
|
activateOnFocus: true,
|
|
1884
1954
|
"aria-label": aria["aria-label"],
|
|
1885
1955
|
"aria-labelledby": aria["aria-labelledby"],
|
|
1886
1956
|
className: "flex items-center gap-2",
|
|
1887
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
1957
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs30(
|
|
1888
1958
|
BaseTabs.Tab,
|
|
1889
1959
|
{
|
|
1890
1960
|
value: tab.id,
|
|
@@ -1897,9 +1967,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1897
1967
|
),
|
|
1898
1968
|
children: [
|
|
1899
1969
|
tab.icon,
|
|
1900
|
-
/* @__PURE__ */
|
|
1970
|
+
/* @__PURE__ */ jsxs30("span", { className: "flex items-baseline", children: [
|
|
1901
1971
|
tab.label,
|
|
1902
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
1972
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx43("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
1903
1973
|
] })
|
|
1904
1974
|
]
|
|
1905
1975
|
},
|
|
@@ -1915,7 +1985,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1915
1985
|
import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo3, useState as useState7 } from "react";
|
|
1916
1986
|
import { createPortal as createPortal2 } from "react-dom";
|
|
1917
1987
|
import { IconCircleCheck } from "@tabler/icons-react";
|
|
1918
|
-
import { jsx as
|
|
1988
|
+
import { jsx as jsx44, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
1919
1989
|
var SURFACE_STYLES = {
|
|
1920
1990
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
|
|
1921
1991
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
|
|
@@ -1933,7 +2003,7 @@ var ACTION_BORDER_STYLES = {
|
|
|
1933
2003
|
};
|
|
1934
2004
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
1935
2005
|
const hasAction = !!(actionLabel && onAction);
|
|
1936
|
-
return /* @__PURE__ */
|
|
2006
|
+
return /* @__PURE__ */ jsxs31(
|
|
1937
2007
|
"div",
|
|
1938
2008
|
{
|
|
1939
2009
|
className: cn(
|
|
@@ -1945,11 +2015,11 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
1945
2015
|
className
|
|
1946
2016
|
),
|
|
1947
2017
|
children: [
|
|
1948
|
-
/* @__PURE__ */
|
|
1949
|
-
leadingIcon && /* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
2018
|
+
/* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
2019
|
+
leadingIcon && /* @__PURE__ */ jsx44(IconCircleCheck, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
|
|
2020
|
+
/* @__PURE__ */ jsx44("span", { className: "font-normal text-[14px] leading-[1.4] text-text-primary whitespace-nowrap", children: label })
|
|
1951
2021
|
] }),
|
|
1952
|
-
hasAction && /* @__PURE__ */
|
|
2022
|
+
hasAction && /* @__PURE__ */ jsx44(
|
|
1953
2023
|
"button",
|
|
1954
2024
|
{
|
|
1955
2025
|
type: "button",
|
|
@@ -1959,7 +2029,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
1959
2029
|
ACTION_BORDER_STYLES[type],
|
|
1960
2030
|
type === "neutral" ? "hover:border-border-strong" : "hover:opacity-80"
|
|
1961
2031
|
),
|
|
1962
|
-
children: /* @__PURE__ */
|
|
2032
|
+
children: /* @__PURE__ */ jsx44("span", { className: "font-medium text-[12px] leading-[12px] text-text-primary whitespace-nowrap", children: actionLabel })
|
|
1963
2033
|
}
|
|
1964
2034
|
)
|
|
1965
2035
|
]
|
|
@@ -1986,10 +2056,10 @@ function ToastProvider({ children }) {
|
|
|
1986
2056
|
return () => clearTimeout(timer);
|
|
1987
2057
|
}, [toast]);
|
|
1988
2058
|
const value = useMemo3(() => ({ showToast, dismissToast }), [showToast, dismissToast]);
|
|
1989
|
-
return /* @__PURE__ */
|
|
2059
|
+
return /* @__PURE__ */ jsxs31(ToastContext.Provider, { value, children: [
|
|
1990
2060
|
children,
|
|
1991
2061
|
toast && createPortal2(
|
|
1992
|
-
/* @__PURE__ */
|
|
2062
|
+
/* @__PURE__ */ jsx44("div", { className: "fixed bottom-4 left-4 z-[100] pointer-events-none", children: /* @__PURE__ */ jsx44(
|
|
1993
2063
|
Toast,
|
|
1994
2064
|
{
|
|
1995
2065
|
className: "pointer-events-auto",
|
|
@@ -2022,6 +2092,7 @@ export {
|
|
|
2022
2092
|
Checkbox,
|
|
2023
2093
|
Chip,
|
|
2024
2094
|
ChipInput,
|
|
2095
|
+
CollapsibleSection,
|
|
2025
2096
|
ConfirmDialog,
|
|
2026
2097
|
DialogShell,
|
|
2027
2098
|
Divider,
|