@flanksource/clicky-ui 0.2.17 → 0.2.19
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/FilterBar.cjs +5 -0
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.js +5 -0
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +2 -0
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components.cjs +7 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +4 -1
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +8 -1
- package/dist/components.js.map +1 -1
- package/dist/data/TabButton.cjs +17 -2
- package/dist/data/TabButton.cjs.map +1 -1
- package/dist/data/TabButton.d.ts +5 -1
- package/dist/data/TabButton.d.ts.map +1 -1
- package/dist/data/TabButton.js +17 -2
- package/dist/data/TabButton.js.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.cjs +8 -1
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +8 -1
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +6 -0
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +5 -1
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +6 -0
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +7 -0
- package/dist/data/test-runner/context.d.ts.map +1 -1
- package/dist/data/test-runner/context.js.map +1 -1
- package/dist/data/test-runner/index.d.ts +1 -0
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/routePath.cjs +39 -0
- package/dist/data/test-runner/routePath.cjs.map +1 -0
- package/dist/data/test-runner/routePath.d.ts +11 -0
- package/dist/data/test-runner/routePath.d.ts.map +1 -0
- package/dist/data/test-runner/routePath.js +39 -0
- package/dist/data/test-runner/routePath.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +4 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +1 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +4 -0
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +11 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.cjs +182 -0
- package/dist/layout/AppShell.cjs.map +1 -0
- package/dist/layout/AppShell.d.ts +75 -0
- package/dist/layout/AppShell.d.ts.map +1 -0
- package/dist/layout/AppShell.js +182 -0
- package/dist/layout/AppShell.js.map +1 -0
- package/dist/layout/Panel.cjs +66 -0
- package/dist/layout/Panel.cjs.map +1 -0
- package/dist/layout/Panel.d.ts +34 -0
- package/dist/layout/Panel.d.ts.map +1 -0
- package/dist/layout/Panel.js +66 -0
- package/dist/layout/Panel.js.map +1 -0
- package/dist/layout/Tabs.cjs +36 -0
- package/dist/layout/Tabs.cjs.map +1 -0
- package/dist/layout/Tabs.d.ts +36 -0
- package/dist/layout/Tabs.d.ts.map +1 -0
- package/dist/layout/Tabs.js +36 -0
- package/dist/layout/Tabs.js.map +1 -0
- package/dist/styles.cjs +1 -0
- package/dist/styles.cjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.d.ts.map +1 -1
- package/dist/styles.js +1 -0
- package/dist/styles.js.map +1 -1
- package/dist/tailwind-preset.cjs +36 -19
- package/dist/tailwind-preset.cjs.map +1 -1
- package/dist/tailwind-preset.d.ts.map +1 -1
- package/dist/tailwind-preset.js +36 -19
- package/dist/tailwind-preset.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StaticIconComponent } from '../data/Icon';
|
|
3
|
+
export type PanelTone = "default" | "danger" | "warning" | "success" | "info";
|
|
4
|
+
export type PanelProps = {
|
|
5
|
+
/** Header title. Omit (with no icon/count/actions) to render a headerless card. */
|
|
6
|
+
title?: ReactNode;
|
|
7
|
+
/** Optional leading icon. */
|
|
8
|
+
icon?: string | StaticIconComponent;
|
|
9
|
+
/** Optional count pill shown after the title. */
|
|
10
|
+
count?: number;
|
|
11
|
+
/** Right-aligned header content (copy buttons, summaries, links). */
|
|
12
|
+
actions?: ReactNode;
|
|
13
|
+
/** Optional footer row below the body. */
|
|
14
|
+
footer?: ReactNode;
|
|
15
|
+
/** Semantic left-border accent. */
|
|
16
|
+
tone?: PanelTone;
|
|
17
|
+
/** Pad the body. Defaults to true; pass false for flush row lists. */
|
|
18
|
+
padded?: boolean;
|
|
19
|
+
/** Classes applied to the panel root. */
|
|
20
|
+
className?: string;
|
|
21
|
+
/** Classes applied to the header row. */
|
|
22
|
+
headerClassName?: string;
|
|
23
|
+
/** Classes applied to the body. */
|
|
24
|
+
bodyClassName?: string;
|
|
25
|
+
/** Panel content. */
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* A non-collapsible carded surface with an optional header. Use for content
|
|
30
|
+
* panels (checks, results, comments) where {@link Section}'s disclosure
|
|
31
|
+
* behaviour isn't wanted. Sits on `bg-card` with a border and rounded corners.
|
|
32
|
+
*/
|
|
33
|
+
export declare function Panel({ title, icon, count, actions, footer, tone, padded, className, headerClassName, bodyClassName, children, }: PanelProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
//# sourceMappingURL=Panel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.d.ts","sourceRoot":"","sources":["../../src/layout/Panel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAQ,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE9D,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9E,MAAM,MAAM,UAAU,GAAG;IACvB,mFAAmF;IACnF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,mCAAmC;IACnC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qBAAqB;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAUF;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,IAAI,EACJ,KAAK,EACL,OAAO,EACP,MAAM,EACN,IAAgB,EAChB,MAAa,EACb,SAAS,EACT,eAAe,EACf,aAAa,EACb,QAAQ,GACT,EAAE,UAAU,2CAwCZ"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { Icon } from "../data/Icon.js";
|
|
4
|
+
const toneRing = {
|
|
5
|
+
default: "",
|
|
6
|
+
danger: "border-l-2 border-l-red-500",
|
|
7
|
+
warning: "border-l-2 border-l-yellow-500",
|
|
8
|
+
success: "border-l-2 border-l-green-500",
|
|
9
|
+
info: "border-l-2 border-l-blue-500"
|
|
10
|
+
};
|
|
11
|
+
function Panel({
|
|
12
|
+
title,
|
|
13
|
+
icon,
|
|
14
|
+
count,
|
|
15
|
+
actions,
|
|
16
|
+
footer,
|
|
17
|
+
tone = "default",
|
|
18
|
+
padded = true,
|
|
19
|
+
className,
|
|
20
|
+
headerClassName,
|
|
21
|
+
bodyClassName,
|
|
22
|
+
children
|
|
23
|
+
}) {
|
|
24
|
+
const hasHeader = title !== void 0 || icon !== void 0 || actions !== void 0;
|
|
25
|
+
return /* @__PURE__ */ jsxs(
|
|
26
|
+
"div",
|
|
27
|
+
{
|
|
28
|
+
className: cn(
|
|
29
|
+
"rounded-md border border-border bg-card overflow-hidden",
|
|
30
|
+
toneRing[tone],
|
|
31
|
+
className
|
|
32
|
+
),
|
|
33
|
+
children: [
|
|
34
|
+
hasHeader && /* @__PURE__ */ jsxs(
|
|
35
|
+
"div",
|
|
36
|
+
{
|
|
37
|
+
className: cn(
|
|
38
|
+
"flex items-center gap-2 px-density-3 py-density-2 border-b border-border",
|
|
39
|
+
headerClassName
|
|
40
|
+
),
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
43
|
+
icon && /* @__PURE__ */ jsx(
|
|
44
|
+
Icon,
|
|
45
|
+
{
|
|
46
|
+
...typeof icon === "string" ? { name: icon } : { icon },
|
|
47
|
+
className: "text-base text-muted-foreground"
|
|
48
|
+
}
|
|
49
|
+
),
|
|
50
|
+
title !== void 0 && /* @__PURE__ */ jsx("span", { className: "font-medium text-sm truncate text-card-foreground", children: title }),
|
|
51
|
+
count !== void 0 && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center rounded-full bg-muted px-1.5 text-[11px] font-semibold text-muted-foreground", children: count })
|
|
52
|
+
] }),
|
|
53
|
+
actions && /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-1", children: actions })
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
/* @__PURE__ */ jsx("div", { className: cn(padded && "px-density-3 py-density-2", bodyClassName), children }),
|
|
58
|
+
footer && /* @__PURE__ */ jsx("div", { className: "px-density-3 py-density-2 border-t border-border", children: footer })
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
Panel
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=Panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Panel.js","sources":["../../src/layout/Panel.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\n\nexport type PanelTone = \"default\" | \"danger\" | \"warning\" | \"success\" | \"info\";\n\nexport type PanelProps = {\n /** Header title. Omit (with no icon/count/actions) to render a headerless card. */\n title?: ReactNode;\n /** Optional leading icon. */\n icon?: string | StaticIconComponent;\n /** Optional count pill shown after the title. */\n count?: number;\n /** Right-aligned header content (copy buttons, summaries, links). */\n actions?: ReactNode;\n /** Optional footer row below the body. */\n footer?: ReactNode;\n /** Semantic left-border accent. */\n tone?: PanelTone;\n /** Pad the body. Defaults to true; pass false for flush row lists. */\n padded?: boolean;\n /** Classes applied to the panel root. */\n className?: string;\n /** Classes applied to the header row. */\n headerClassName?: string;\n /** Classes applied to the body. */\n bodyClassName?: string;\n /** Panel content. */\n children: ReactNode;\n};\n\nconst toneRing: Record<PanelTone, string> = {\n default: \"\",\n danger: \"border-l-2 border-l-red-500\",\n warning: \"border-l-2 border-l-yellow-500\",\n success: \"border-l-2 border-l-green-500\",\n info: \"border-l-2 border-l-blue-500\",\n};\n\n/**\n * A non-collapsible carded surface with an optional header. Use for content\n * panels (checks, results, comments) where {@link Section}'s disclosure\n * behaviour isn't wanted. Sits on `bg-card` with a border and rounded corners.\n */\nexport function Panel({\n title,\n icon,\n count,\n actions,\n footer,\n tone = \"default\",\n padded = true,\n className,\n headerClassName,\n bodyClassName,\n children,\n}: PanelProps) {\n const hasHeader = title !== undefined || icon !== undefined || actions !== undefined;\n return (\n <div\n className={cn(\n \"rounded-md border border-border bg-card overflow-hidden\",\n toneRing[tone],\n className,\n )}\n >\n {hasHeader && (\n <div\n className={cn(\n \"flex items-center gap-2 px-density-3 py-density-2 border-b border-border\",\n headerClassName,\n )}\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n {icon && (\n <Icon\n {...(typeof icon === \"string\" ? { name: icon } : { icon })}\n className=\"text-base text-muted-foreground\"\n />\n )}\n {title !== undefined && (\n <span className=\"font-medium text-sm truncate text-card-foreground\">{title}</span>\n )}\n {count !== undefined && (\n <span className=\"inline-flex items-center justify-center rounded-full bg-muted px-1.5 text-[11px] font-semibold text-muted-foreground\">\n {count}\n </span>\n )}\n </div>\n {actions && <div className=\"flex shrink-0 items-center gap-1\">{actions}</div>}\n </div>\n )}\n <div className={cn(padded && \"px-density-3 py-density-2\", bodyClassName)}>{children}</div>\n {footer && <div className=\"px-density-3 py-density-2 border-t border-border\">{footer}</div>}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AA+BA,MAAM,WAAsC;AAAA,EAC1C,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AACR;AAOO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAe;AACb,QAAM,YAAY,UAAU,UAAa,SAAS,UAAa,YAAY;AAC3E,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,SAAS,IAAI;AAAA,QACb;AAAA,MAAA;AAAA,MAGD,UAAA;AAAA,QAAA,aACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA;AAAA,YAAA;AAAA,YAGF,UAAA;AAAA,cAAA,qBAAC,OAAA,EAAI,WAAU,0CACZ,UAAA;AAAA,gBAAA,QACC;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACE,GAAI,OAAO,SAAS,WAAW,EAAE,MAAM,KAAA,IAAS,EAAE,KAAA;AAAA,oBACnD,WAAU;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAGb,UAAU,UACT,oBAAC,QAAA,EAAK,WAAU,qDAAqD,UAAA,OAAM;AAAA,gBAE5E,UAAU,UACT,oBAAC,QAAA,EAAK,WAAU,wHACb,UAAA,MAAA,CACH;AAAA,cAAA,GAEJ;AAAA,cACC,WAAW,oBAAC,OAAA,EAAI,WAAU,oCAAoC,UAAA,QAAA,CAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAG3E,oBAAC,SAAI,WAAW,GAAG,UAAU,6BAA6B,aAAa,GAAI,UAAS;AAAA,QACnF,UAAU,oBAAC,OAAA,EAAI,WAAU,oDAAoD,UAAA,OAAA,CAAO;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG3F;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const utils = require("../lib/utils.cjs");
|
|
5
|
+
const TabButton = require("../data/TabButton.cjs");
|
|
6
|
+
function Tabs({ tabs, value, onChange, variant = "underline", className }) {
|
|
7
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8
|
+
"div",
|
|
9
|
+
{
|
|
10
|
+
role: "tablist",
|
|
11
|
+
className: utils.cn(
|
|
12
|
+
"flex items-center gap-density-1",
|
|
13
|
+
variant === "underline" && "border-b border-border",
|
|
14
|
+
className
|
|
15
|
+
),
|
|
16
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
17
|
+
TabButton.TabButton,
|
|
18
|
+
{
|
|
19
|
+
active: tab.id === value,
|
|
20
|
+
onClick: () => {
|
|
21
|
+
if (!tab.disabled) onChange(tab.id);
|
|
22
|
+
},
|
|
23
|
+
label: tab.label,
|
|
24
|
+
variant,
|
|
25
|
+
...tab.icon !== void 0 ? { icon: tab.icon } : {},
|
|
26
|
+
...tab.count !== void 0 ? { count: tab.count } : {},
|
|
27
|
+
...tab.countColor !== void 0 ? { countColor: tab.countColor } : {},
|
|
28
|
+
...tab.disabled ? { className: "opacity-50 pointer-events-none" } : {}
|
|
29
|
+
},
|
|
30
|
+
tab.id
|
|
31
|
+
))
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
exports.Tabs = Tabs;
|
|
36
|
+
//# sourceMappingURL=Tabs.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.cjs","sources":["../../src/layout/Tabs.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { TabButton, type TabButtonVariant } from \"../data/TabButton\";\nimport type { StaticIconComponent } from \"../data/Icon\";\n\nexport type TabItem = {\n /** Stable id; also the value compared against the selected `value`. */\n id: string;\n /** Visible label. */\n label: ReactNode;\n /** Optional leading icon (icon name or component). */\n icon?: string | StaticIconComponent;\n /** Optional count badge; hidden when zero. */\n count?: number;\n /** Classes for the count badge background. */\n countColor?: string;\n /** Disables selecting this tab. */\n disabled?: boolean;\n};\n\nexport type TabsProps = {\n /** Tabs to render, in order. */\n tabs: TabItem[];\n /** Currently selected tab id. */\n value: string;\n /** Called with the next tab id when a tab is clicked. */\n onChange: (id: string) => void;\n /** Visual style. Defaults to `underline`. */\n variant?: TabButtonVariant;\n /** Classes applied to the tablist row. */\n className?: string;\n};\n\n/**\n * A controlled tab strip built on {@link TabButton}. Defaults to the\n * `underline` variant — the row carries a bottom border and the active tab's\n * underline overlaps it. Render the matching panel yourself based on `value`.\n */\nexport function Tabs({ tabs, value, onChange, variant = \"underline\", className }: TabsProps) {\n return (\n <div\n role=\"tablist\"\n className={cn(\n \"flex items-center gap-density-1\",\n variant === \"underline\" && \"border-b border-border\",\n className,\n )}\n >\n {tabs.map((tab) => (\n <TabButton\n key={tab.id}\n active={tab.id === value}\n onClick={() => {\n if (!tab.disabled) onChange(tab.id);\n }}\n label={tab.label}\n variant={variant}\n {...(tab.icon !== undefined ? { icon: tab.icon } : {})}\n {...(tab.count !== undefined ? { count: tab.count } : {})}\n {...(tab.countColor !== undefined ? { countColor: tab.countColor } : {})}\n {...(tab.disabled ? { className: \"opacity-50 pointer-events-none\" } : {})}\n />\n ))}\n </div>\n );\n}\n"],"names":["jsx","cn","TabButton"],"mappings":";;;;;AAsCO,SAAS,KAAK,EAAE,MAAM,OAAO,UAAU,UAAU,aAAa,aAAwB;AAC3F,SACEA,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAWC,MAAAA;AAAAA,QACT;AAAA,QACA,YAAY,eAAe;AAAA,QAC3B;AAAA,MAAA;AAAA,MAGD,UAAA,KAAK,IAAI,CAAC,QACTD,2BAAAA;AAAAA,QAACE,UAAAA;AAAAA,QAAA;AAAA,UAEC,QAAQ,IAAI,OAAO;AAAA,UACnB,SAAS,MAAM;AACb,gBAAI,CAAC,IAAI,SAAU,UAAS,IAAI,EAAE;AAAA,UACpC;AAAA,UACA,OAAO,IAAI;AAAA,UACX;AAAA,UACC,GAAI,IAAI,SAAS,SAAY,EAAE,MAAM,IAAI,KAAA,IAAS,CAAA;AAAA,UAClD,GAAI,IAAI,UAAU,SAAY,EAAE,OAAO,IAAI,MAAA,IAAU,CAAA;AAAA,UACrD,GAAI,IAAI,eAAe,SAAY,EAAE,YAAY,IAAI,WAAA,IAAe,CAAA;AAAA,UACpE,GAAI,IAAI,WAAW,EAAE,WAAW,iCAAA,IAAqC,CAAA;AAAA,QAAC;AAAA,QAVlE,IAAI;AAAA,MAAA,CAYZ;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { TabButtonVariant } from '../data/TabButton';
|
|
3
|
+
import { StaticIconComponent } from '../data/Icon';
|
|
4
|
+
export type TabItem = {
|
|
5
|
+
/** Stable id; also the value compared against the selected `value`. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Visible label. */
|
|
8
|
+
label: ReactNode;
|
|
9
|
+
/** Optional leading icon (icon name or component). */
|
|
10
|
+
icon?: string | StaticIconComponent;
|
|
11
|
+
/** Optional count badge; hidden when zero. */
|
|
12
|
+
count?: number;
|
|
13
|
+
/** Classes for the count badge background. */
|
|
14
|
+
countColor?: string;
|
|
15
|
+
/** Disables selecting this tab. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type TabsProps = {
|
|
19
|
+
/** Tabs to render, in order. */
|
|
20
|
+
tabs: TabItem[];
|
|
21
|
+
/** Currently selected tab id. */
|
|
22
|
+
value: string;
|
|
23
|
+
/** Called with the next tab id when a tab is clicked. */
|
|
24
|
+
onChange: (id: string) => void;
|
|
25
|
+
/** Visual style. Defaults to `underline`. */
|
|
26
|
+
variant?: TabButtonVariant;
|
|
27
|
+
/** Classes applied to the tablist row. */
|
|
28
|
+
className?: string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* A controlled tab strip built on {@link TabButton}. Defaults to the
|
|
32
|
+
* `underline` variant — the row carries a bottom border and the active tab's
|
|
33
|
+
* underline overlaps it. Render the matching panel yourself based on `value`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function Tabs({ tabs, value, onChange, variant, className }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
//# sourceMappingURL=Tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/layout/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,MAAM,OAAO,GAAG;IACpB,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,qBAAqB;IACrB,KAAK,EAAE,SAAS,CAAC;IACjB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,gCAAgC;IAChC,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,6CAA6C;IAC7C,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAqB,EAAE,SAAS,EAAE,EAAE,SAAS,2CA2B1F"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/utils.js";
|
|
3
|
+
import { TabButton } from "../data/TabButton.js";
|
|
4
|
+
function Tabs({ tabs, value, onChange, variant = "underline", className }) {
|
|
5
|
+
return /* @__PURE__ */ jsx(
|
|
6
|
+
"div",
|
|
7
|
+
{
|
|
8
|
+
role: "tablist",
|
|
9
|
+
className: cn(
|
|
10
|
+
"flex items-center gap-density-1",
|
|
11
|
+
variant === "underline" && "border-b border-border",
|
|
12
|
+
className
|
|
13
|
+
),
|
|
14
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsx(
|
|
15
|
+
TabButton,
|
|
16
|
+
{
|
|
17
|
+
active: tab.id === value,
|
|
18
|
+
onClick: () => {
|
|
19
|
+
if (!tab.disabled) onChange(tab.id);
|
|
20
|
+
},
|
|
21
|
+
label: tab.label,
|
|
22
|
+
variant,
|
|
23
|
+
...tab.icon !== void 0 ? { icon: tab.icon } : {},
|
|
24
|
+
...tab.count !== void 0 ? { count: tab.count } : {},
|
|
25
|
+
...tab.countColor !== void 0 ? { countColor: tab.countColor } : {},
|
|
26
|
+
...tab.disabled ? { className: "opacity-50 pointer-events-none" } : {}
|
|
27
|
+
},
|
|
28
|
+
tab.id
|
|
29
|
+
))
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
Tabs
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=Tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.js","sources":["../../src/layout/Tabs.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { TabButton, type TabButtonVariant } from \"../data/TabButton\";\nimport type { StaticIconComponent } from \"../data/Icon\";\n\nexport type TabItem = {\n /** Stable id; also the value compared against the selected `value`. */\n id: string;\n /** Visible label. */\n label: ReactNode;\n /** Optional leading icon (icon name or component). */\n icon?: string | StaticIconComponent;\n /** Optional count badge; hidden when zero. */\n count?: number;\n /** Classes for the count badge background. */\n countColor?: string;\n /** Disables selecting this tab. */\n disabled?: boolean;\n};\n\nexport type TabsProps = {\n /** Tabs to render, in order. */\n tabs: TabItem[];\n /** Currently selected tab id. */\n value: string;\n /** Called with the next tab id when a tab is clicked. */\n onChange: (id: string) => void;\n /** Visual style. Defaults to `underline`. */\n variant?: TabButtonVariant;\n /** Classes applied to the tablist row. */\n className?: string;\n};\n\n/**\n * A controlled tab strip built on {@link TabButton}. Defaults to the\n * `underline` variant — the row carries a bottom border and the active tab's\n * underline overlaps it. Render the matching panel yourself based on `value`.\n */\nexport function Tabs({ tabs, value, onChange, variant = \"underline\", className }: TabsProps) {\n return (\n <div\n role=\"tablist\"\n className={cn(\n \"flex items-center gap-density-1\",\n variant === \"underline\" && \"border-b border-border\",\n className,\n )}\n >\n {tabs.map((tab) => (\n <TabButton\n key={tab.id}\n active={tab.id === value}\n onClick={() => {\n if (!tab.disabled) onChange(tab.id);\n }}\n label={tab.label}\n variant={variant}\n {...(tab.icon !== undefined ? { icon: tab.icon } : {})}\n {...(tab.count !== undefined ? { count: tab.count } : {})}\n {...(tab.countColor !== undefined ? { countColor: tab.countColor } : {})}\n {...(tab.disabled ? { className: \"opacity-50 pointer-events-none\" } : {})}\n />\n ))}\n </div>\n );\n}\n"],"names":[],"mappings":";;;AAsCO,SAAS,KAAK,EAAE,MAAM,OAAO,UAAU,UAAU,aAAa,aAAwB;AAC3F,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA,YAAY,eAAe;AAAA,QAC3B;AAAA,MAAA;AAAA,MAGD,UAAA,KAAK,IAAI,CAAC,QACT;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,QAAQ,IAAI,OAAO;AAAA,UACnB,SAAS,MAAM;AACb,gBAAI,CAAC,IAAI,SAAU,UAAS,IAAI,EAAE;AAAA,UACpC;AAAA,UACA,OAAO,IAAI;AAAA,UACX;AAAA,UACC,GAAI,IAAI,SAAS,SAAY,EAAE,MAAM,IAAI,KAAA,IAAS,CAAA;AAAA,UAClD,GAAI,IAAI,UAAU,SAAY,EAAE,OAAO,IAAI,MAAA,IAAU,CAAA;AAAA,UACrD,GAAI,IAAI,eAAe,SAAY,EAAE,YAAY,IAAI,WAAA,IAAe,CAAA;AAAA,UACpE,GAAI,IAAI,WAAW,EAAE,WAAW,iCAAA,IAAqC,CAAA;AAAA,QAAC;AAAA,QAVlE,IAAI;AAAA,MAAA,CAYZ;AAAA,IAAA;AAAA,EAAA;AAGP;"}
|
package/dist/styles.cjs
CHANGED
package/dist/styles.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"styles.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|