@stll/ui 0.27.3 → 0.28.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/components/button-variants.d.ts +1 -1
- package/dist/components/view-toolbar.d.ts +11 -0
- package/dist/components/view-toolbar.js +26 -0
- package/dist/kanban/card-shell.d.ts +3 -1
- package/dist/kanban/card-shell.js +3 -3
- package/dist/kanban/column-header.js +1 -1
- package/dist/kanban/subgroup-board.d.ts +3 -2
- package/dist/kanban/subgroup-board.js +13 -7
- package/dist/kanban/virtual-cell.js +1 -1
- package/package.json +5 -1
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
export declare const buttonAccessibleDisabledClass = "cursor-not-allowed opacity-64";
|
|
12
12
|
export declare const buttonVariants: (props?: ({
|
|
13
13
|
size?: "default" | "chip" | "icon" | "icon-lg" | "icon-sm" | "icon-xl" | "icon-xs" | "lg" | "sm" | "xl" | "xs" | null | undefined;
|
|
14
|
-
variant?: "
|
|
14
|
+
variant?: "default" | "link" | "destructive" | "destructive-outline" | "ghost" | "outline" | "secondary" | null | undefined;
|
|
15
15
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
16
16
|
//#endregion
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Button } from "./button.js";
|
|
2
|
+
import { ComponentProps } from "react";
|
|
3
|
+
//#region src/components/view-toolbar.d.ts
|
|
4
|
+
/** Shared view controls stay compact and scroll horizontally on small screens. */
|
|
5
|
+
export declare const ViewToolbarChrome: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
6
|
+
type ViewFilterButtonProps = Omit<ComponentProps<typeof Button>, "children" | "size" | "variant" | "aria-label" | "title"> & {
|
|
7
|
+
label: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const ViewFilterButton: ({ label, ...props }: ViewFilterButtonProps) => import("react").JSX.Element;
|
|
10
|
+
export declare const ViewFilterChip: ({ className, ...props }: Omit<ComponentProps<typeof Button>, "size" | "variant">) => import("react").JSX.Element;
|
|
11
|
+
//#endregion
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { Button } from "./button.js";
|
|
3
|
+
import { FilterIcon } from "lucide-react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/view-toolbar.tsx
|
|
6
|
+
/** Shared view controls stay compact and scroll horizontally on small screens. */
|
|
7
|
+
const ViewToolbarChrome = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
8
|
+
className: cn("flex min-w-0 shrink-0 [scrollbar-width:none] flex-nowrap items-center gap-1 overflow-x-auto px-2 py-1 [-ms-overflow-style:none] md:flex-wrap md:overflow-visible [&::-webkit-scrollbar]:hidden", className),
|
|
9
|
+
...props
|
|
10
|
+
});
|
|
11
|
+
const ViewFilterButton = ({ label, ...props }) => /* @__PURE__ */ jsx(Button, {
|
|
12
|
+
...props,
|
|
13
|
+
"aria-label": label,
|
|
14
|
+
size: "icon-xs",
|
|
15
|
+
title: label,
|
|
16
|
+
variant: "ghost",
|
|
17
|
+
children: /* @__PURE__ */ jsx(FilterIcon, { className: "size-3.5" })
|
|
18
|
+
});
|
|
19
|
+
const ViewFilterChip = ({ className, ...props }) => /* @__PURE__ */ jsx(Button, {
|
|
20
|
+
...props,
|
|
21
|
+
className: cn("gap-1.5 font-normal", className),
|
|
22
|
+
size: "xs",
|
|
23
|
+
variant: "secondary"
|
|
24
|
+
});
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ViewFilterButton, ViewFilterChip, ViewToolbarChrome };
|
|
@@ -2,6 +2,8 @@ import { ReactNode, RefObject } from "react";
|
|
|
2
2
|
//#region src/kanban/card-shell.d.ts
|
|
3
3
|
export type KanbanCardShellProps = {
|
|
4
4
|
children: ReactNode;
|
|
5
|
+
/** Proposed work stays visually distinct until a person accepts it. */
|
|
6
|
+
appearance?: "standard" | "proposal" | undefined;
|
|
5
7
|
/** Overlay slot pinned to the top-end corner (row actions). */
|
|
6
8
|
actions?: ReactNode;
|
|
7
9
|
/**
|
|
@@ -66,5 +68,5 @@ export type KanbanCardShellProps = {
|
|
|
66
68
|
* Nothing here clips its overflow: a pinned identity row stops sticking the
|
|
67
69
|
* moment anything between it and the scroll container clips.
|
|
68
70
|
*/
|
|
69
|
-
export declare const KanbanCardShell: ({ children, actions, actionsVisibility, stickyHeader, active, onOpen, bodyRef, dragRef, className }: KanbanCardShellProps) => import("react").JSX.Element;
|
|
71
|
+
export declare const KanbanCardShell: ({ children, appearance, actions, actionsVisibility, stickyHeader, active, onOpen, bodyRef, dragRef, className }: KanbanCardShellProps) => import("react").JSX.Element;
|
|
70
72
|
//#endregion
|
|
@@ -15,7 +15,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
15
15
|
* Nothing here clips its overflow: a pinned identity row stops sticking the
|
|
16
16
|
* moment anything between it and the scroll container clips.
|
|
17
17
|
*/
|
|
18
|
-
const KanbanCardShell = ({ children, actions, actionsVisibility = "always", stickyHeader, active, onOpen, bodyRef, dragRef, className }) => {
|
|
18
|
+
const KanbanCardShell = ({ children, appearance = "standard", actions, actionsVisibility = "always", stickyHeader, active, onOpen, bodyRef, dragRef, className }) => {
|
|
19
19
|
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
20
20
|
stickyHeader === void 0 || stickyHeader === null ? null : /* @__PURE__ */ jsx("div", {
|
|
21
21
|
className: cn(STICKY_HEADER_CLASS, KANBAN_CARD_STICKY_TOP_CLASS),
|
|
@@ -34,7 +34,7 @@ const KanbanCardShell = ({ children, actions, actionsVisibility = "always", stic
|
|
|
34
34
|
"data-active": active ? "true" : void 0,
|
|
35
35
|
ref: dragRef,
|
|
36
36
|
children: /* @__PURE__ */ jsx("div", {
|
|
37
|
-
className: cn(CARD_CLASS, active && ACTIVE_CLASS, className),
|
|
37
|
+
className: cn(CARD_CLASS, appearance === "proposal" && "border-dashed", active && ACTIVE_CLASS, className),
|
|
38
38
|
ref: bodyRef,
|
|
39
39
|
children: body
|
|
40
40
|
})
|
|
@@ -44,7 +44,7 @@ const KanbanCardShell = ({ children, actions, actionsVisibility = "always", stic
|
|
|
44
44
|
"data-active": active ? "true" : void 0,
|
|
45
45
|
ref: dragRef,
|
|
46
46
|
children: /* @__PURE__ */ jsx("div", {
|
|
47
|
-
className: cn(CARD_CLASS, "cursor-pointer transition-shadow hover:shadow-md", active && ACTIVE_CLASS, className),
|
|
47
|
+
className: cn(CARD_CLASS, appearance === "proposal" && "border-dashed", "cursor-pointer transition-shadow hover:shadow-md", active && ACTIVE_CLASS, className),
|
|
48
48
|
onClick: containedEventHandler(onOpen),
|
|
49
49
|
onKeyDown: (event) => {
|
|
50
50
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
@@ -20,7 +20,7 @@ const KanbanColumnHeader = ({ swatch, title, meta, calculation, dragHandle, acti
|
|
|
20
20
|
className: "sticky start-0 z-10 flex w-fit max-w-full items-center gap-2 bg-inherit",
|
|
21
21
|
"data-kanban-column-title": "",
|
|
22
22
|
children: [swatch, /* @__PURE__ */ jsxs("span", {
|
|
23
|
-
className: "flex min-w-0 flex-1 items-center gap-1.5 truncate",
|
|
23
|
+
className: "flex min-w-0 flex-1 items-center gap-1.5 truncate text-sm font-medium",
|
|
24
24
|
children: [title, meta !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
25
25
|
className: "text-muted-foreground text-xs",
|
|
26
26
|
children: meta
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { KanbanBandToggleActivation } from "./column-band-header.js";
|
|
2
2
|
import { KanbanColumnBand, KanbanGroup } from "./grouping.js";
|
|
3
3
|
import { KanbanBoardCell, KanbanBoardColumn, KanbanBoardMatrix } from "./matrix.js";
|
|
4
|
-
import { ReactNode } from "react";
|
|
4
|
+
import { ReactNode, Ref } from "react";
|
|
5
5
|
//#region src/kanban/subgroup-board.d.ts
|
|
6
6
|
export type KanbanSubgroupColumnHeaderContext = {
|
|
7
7
|
column: KanbanBoardColumn;
|
|
@@ -73,6 +73,7 @@ type KanbanSubgroupCollapseControl = {
|
|
|
73
73
|
onLaneCollapsedChange: (group: KanbanGroup, collapsed: boolean) => void;
|
|
74
74
|
};
|
|
75
75
|
export type KanbanSubgroupBoardProps<TRow> = {
|
|
76
|
+
scrollRef?: Ref<HTMLDivElement> | undefined;
|
|
76
77
|
matrix: KanbanBoardMatrix<TRow>;
|
|
77
78
|
renderColumnHeader: (context: KanbanSubgroupColumnHeaderContext) => ReactNode;
|
|
78
79
|
renderLaneIdentity: (context: KanbanSubgroupLaneIdentityContext) => ReactNode;
|
|
@@ -152,5 +153,5 @@ export type KanbanSubgroupBoardProps<TRow> = {
|
|
|
152
153
|
* in every state; the caption line never grows past its own height, so a
|
|
153
154
|
* folded band costs no vertical space.
|
|
154
155
|
*/
|
|
155
|
-
export declare const KanbanSubgroupBoard: <TRow>({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, renderLaneColumnSummary, renderLaneColumnAction, renderBandHeader, renderCollapsedBandCell, formatBandToggleLabel, formatCount, isLaneCollapsed, onLaneCollapsedChange, isBandCollapsed, onBandCollapsedChange, footer, className, dragOverBandId, isDragging }: KanbanSubgroupBoardProps<TRow>) => import("react").JSX.Element;
|
|
156
|
+
export declare const KanbanSubgroupBoard: <TRow>({ scrollRef, matrix, renderColumnHeader, renderLaneIdentity, renderCell, renderLaneColumnSummary, renderLaneColumnAction, renderBandHeader, renderCollapsedBandCell, formatBandToggleLabel, formatCount, isLaneCollapsed, onLaneCollapsedChange, isBandCollapsed, onBandCollapsedChange, footer, className, dragOverBandId, isDragging }: KanbanSubgroupBoardProps<TRow>) => import("react").JSX.Element;
|
|
156
157
|
//#endregion
|
|
@@ -42,7 +42,7 @@ const rowsIn = (cells) => cells.reduce((sum, cell) => sum + cell.rows.length, 0)
|
|
|
42
42
|
* in every state; the caption line never grows past its own height, so a
|
|
43
43
|
* folded band costs no vertical space.
|
|
44
44
|
*/
|
|
45
|
-
const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, renderLaneColumnSummary, renderLaneColumnAction, renderBandHeader, renderCollapsedBandCell, formatBandToggleLabel, formatCount = String, isLaneCollapsed, onLaneCollapsedChange, isBandCollapsed, onBandCollapsedChange, footer, className, dragOverBandId, isDragging }) => {
|
|
45
|
+
const KanbanSubgroupBoard = ({ scrollRef, matrix, renderColumnHeader, renderLaneIdentity, renderCell, renderLaneColumnSummary, renderLaneColumnAction, renderBandHeader, renderCollapsedBandCell, formatBandToggleLabel, formatCount = String, isLaneCollapsed, onLaneCollapsedChange, isBandCollapsed, onBandCollapsedChange, footer, className, dragOverBandId, isDragging }) => {
|
|
46
46
|
const [collapsedLaneValues, setCollapsedLaneValues] = useState(() => /* @__PURE__ */ new Set());
|
|
47
47
|
const [expandedEmptyLaneValues, setExpandedEmptyLaneValues] = useState(() => /* @__PURE__ */ new Set());
|
|
48
48
|
const [collapsedBandIds, setCollapsedBandIds] = useState(() => /* @__PURE__ */ new Set());
|
|
@@ -251,17 +251,17 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
|
|
|
251
251
|
});
|
|
252
252
|
};
|
|
253
253
|
/** One column's cell in a lane's row: what it holds, then what it offers. */
|
|
254
|
-
const laneColumnCell = (group, column, count) => /* @__PURE__ */ jsxs("div", {
|
|
254
|
+
const laneColumnCell = ({ group, column, count, laneCount }) => /* @__PURE__ */ jsxs("div", {
|
|
255
255
|
className: cn("flex items-center gap-1 px-3", "h-9"),
|
|
256
256
|
"data-kanban-lane-column-count": count,
|
|
257
|
-
children: [renderLaneColumnSummary ? renderLaneColumnSummary({
|
|
257
|
+
children: [laneCount > 0 && (renderLaneColumnSummary ? renderLaneColumnSummary({
|
|
258
258
|
column,
|
|
259
259
|
count,
|
|
260
260
|
lane: group
|
|
261
261
|
}) : /* @__PURE__ */ jsx("span", {
|
|
262
262
|
className: "text-muted-foreground text-xs tabular-nums",
|
|
263
263
|
children: formatCount(count)
|
|
264
|
-
}), renderLaneColumnAction === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
264
|
+
})), renderLaneColumnAction === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
265
265
|
className: "ms-auto flex items-center",
|
|
266
266
|
children: renderLaneColumnAction({
|
|
267
267
|
column,
|
|
@@ -279,6 +279,7 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
|
|
|
279
279
|
const laneCellsStickyTopStyle = { [KANBAN_STICKY_TOP_VAR]: `${String(headerHeight + LANE_ROW_HEIGHT_PX)}px` };
|
|
280
280
|
return /* @__PURE__ */ jsx("div", {
|
|
281
281
|
className: cn("h-full overflow-auto px-4 pb-4", className),
|
|
282
|
+
ref: scrollRef,
|
|
282
283
|
style: stickyTopStyle,
|
|
283
284
|
children: /* @__PURE__ */ jsxs("div", {
|
|
284
285
|
className: "min-w-max",
|
|
@@ -358,7 +359,7 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
|
|
|
358
359
|
"data-kanban-lane-identity": "",
|
|
359
360
|
children: /* @__PURE__ */ jsxs("button", {
|
|
360
361
|
"aria-expanded": !collapsed,
|
|
361
|
-
className: cn("hover:bg-muted/60 flex items-center gap-2 rounded-lg px-2 text-start transition-[background-color]", "h-9", KANBAN_CHROME_TOGGLE_COARSE_TARGET_CLASS),
|
|
362
|
+
className: cn("hover:bg-muted/60 flex items-center gap-2 rounded-lg px-2 text-start text-sm font-medium transition-[background-color]", "h-9", KANBAN_CHROME_TOGGLE_COARSE_TARGET_CLASS),
|
|
362
363
|
onClick: () => setLaneCollapsed(group, count, !collapsed),
|
|
363
364
|
type: "button",
|
|
364
365
|
children: [
|
|
@@ -379,8 +380,13 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
|
|
|
379
380
|
})
|
|
380
381
|
}), renderRow({
|
|
381
382
|
label: "Lane column summaries",
|
|
382
|
-
renderColumn: (column) => laneColumnCell(
|
|
383
|
-
|
|
383
|
+
renderColumn: (column) => laneColumnCell({
|
|
384
|
+
group,
|
|
385
|
+
column,
|
|
386
|
+
count: cellFor(column)?.rows.length ?? 0,
|
|
387
|
+
laneCount: count
|
|
388
|
+
}),
|
|
389
|
+
renderFoldedBand: (_band, span) => count > 0 ? foldedCount(span, cells) : null
|
|
384
390
|
})]
|
|
385
391
|
}), !collapsed && /* @__PURE__ */ jsx("div", {
|
|
386
392
|
style: laneCellsStickyTopStyle,
|
|
@@ -128,7 +128,7 @@ const KanbanVirtualCell = ({ rows, getRowKey, renderRow, pagination, sortable, c
|
|
|
128
128
|
})
|
|
129
129
|
}) : null;
|
|
130
130
|
const content = /* @__PURE__ */ jsxs("div", {
|
|
131
|
-
className: cn(KANBAN_CELL_SURFACE_CLASS, "
|
|
131
|
+
className: cn(KANBAN_CELL_SURFACE_CLASS, "min-h-20 rounded-xl p-2 transition-[background-color,outline-color]", rows.length === 0 ? "overflow-visible" : "max-h-[min(60vh,40rem)] overflow-y-auto overscroll-y-contain", active && accentVariants === void 0 && "bg-primary/5 ring-primary/50 ring-2", className),
|
|
132
132
|
"data-kanban-cell": sortable?.dropTarget.id,
|
|
133
133
|
"data-kanban-cell-accent": accentVariants === void 0 ? void 0 : "true",
|
|
134
134
|
onScroll: handleScroll,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Stella's design system: bidi-aware React primitives built on Base UI, the dockable inspector pane, and the Tailwind v4 theme they are styled with.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"base-ui",
|
|
@@ -33,6 +33,10 @@
|
|
|
33
33
|
"types": "./dist/index.d.ts",
|
|
34
34
|
"import": "./dist/index.js"
|
|
35
35
|
},
|
|
36
|
+
"./view-toolbar": {
|
|
37
|
+
"types": "./dist/components/view-toolbar.d.ts",
|
|
38
|
+
"import": "./dist/components/view-toolbar.js"
|
|
39
|
+
},
|
|
36
40
|
"./accordion": {
|
|
37
41
|
"types": "./dist/components/accordion.d.ts",
|
|
38
42
|
"import": "./dist/components/accordion.js"
|