@stratum-hq/react 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/components/ConfigEditor.d.ts +5 -0
  2. package/dist/components/ConfigEditor.d.ts.map +1 -0
  3. package/dist/components/ConfigEditor.js +71 -0
  4. package/dist/components/ConfigEditor.js.map +1 -0
  5. package/dist/components/ConfigEditor.stories.d.ts +35 -0
  6. package/dist/components/ConfigEditor.stories.d.ts.map +1 -0
  7. package/dist/components/ConfigEditor.stories.js +73 -0
  8. package/dist/components/ConfigEditor.stories.js.map +1 -0
  9. package/dist/components/PermissionEditor.d.ts +5 -0
  10. package/dist/components/PermissionEditor.d.ts.map +1 -0
  11. package/dist/components/PermissionEditor.js +46 -0
  12. package/dist/components/PermissionEditor.js.map +1 -0
  13. package/dist/components/PermissionEditor.stories.d.ts +34 -0
  14. package/dist/components/PermissionEditor.stories.d.ts.map +1 -0
  15. package/dist/components/PermissionEditor.stories.js +90 -0
  16. package/dist/components/PermissionEditor.stories.js.map +1 -0
  17. package/dist/components/Skeleton.d.ts +14 -0
  18. package/dist/components/Skeleton.d.ts.map +1 -0
  19. package/dist/components/Skeleton.js +25 -0
  20. package/dist/components/Skeleton.js.map +1 -0
  21. package/dist/components/Skeleton.stories.d.ts +46 -0
  22. package/dist/components/Skeleton.stories.d.ts.map +1 -0
  23. package/dist/components/Skeleton.stories.js +125 -0
  24. package/dist/components/Skeleton.stories.js.map +1 -0
  25. package/dist/components/TableSkeleton.d.ts +10 -0
  26. package/dist/components/TableSkeleton.d.ts.map +1 -0
  27. package/dist/components/TableSkeleton.js +6 -0
  28. package/dist/components/TableSkeleton.js.map +1 -0
  29. package/dist/components/TenantSwitcher.d.ts +7 -0
  30. package/dist/components/TenantSwitcher.d.ts.map +1 -0
  31. package/dist/components/TenantSwitcher.js +40 -0
  32. package/dist/components/TenantSwitcher.js.map +1 -0
  33. package/dist/components/TenantSwitcher.stories.d.ts +30 -0
  34. package/dist/components/TenantSwitcher.stories.d.ts.map +1 -0
  35. package/dist/components/TenantSwitcher.stories.js +76 -0
  36. package/dist/components/TenantSwitcher.stories.js.map +1 -0
  37. package/dist/components/TenantTree.d.ts +7 -0
  38. package/dist/components/TenantTree.d.ts.map +1 -0
  39. package/dist/components/TenantTree.js +19 -0
  40. package/dist/components/TenantTree.js.map +1 -0
  41. package/dist/components/TenantTree.stories.d.ts +28 -0
  42. package/dist/components/TenantTree.stories.d.ts.map +1 -0
  43. package/dist/components/TenantTree.stories.js +71 -0
  44. package/dist/components/TenantTree.stories.js.map +1 -0
  45. package/dist/components/Toast.d.ts +18 -0
  46. package/dist/components/Toast.d.ts.map +1 -0
  47. package/dist/components/Toast.js +22 -0
  48. package/dist/components/Toast.js.map +1 -0
  49. package/dist/components/Toast.stories.d.ts +36 -0
  50. package/dist/components/Toast.stories.d.ts.map +1 -0
  51. package/dist/components/Toast.stories.js +105 -0
  52. package/dist/components/Toast.stories.js.map +1 -0
  53. package/dist/components/ToastContainer.d.ts +11 -0
  54. package/dist/components/ToastContainer.d.ts.map +1 -0
  55. package/dist/components/ToastContainer.js +9 -0
  56. package/dist/components/ToastContainer.js.map +1 -0
  57. package/dist/components/headless/ConfigEditor.d.ts +15 -0
  58. package/dist/components/headless/ConfigEditor.d.ts.map +1 -0
  59. package/dist/components/headless/ConfigEditor.js +7 -0
  60. package/dist/components/headless/ConfigEditor.js.map +1 -0
  61. package/dist/components/headless/PermissionEditor.d.ts +15 -0
  62. package/dist/components/headless/PermissionEditor.d.ts.map +1 -0
  63. package/dist/components/headless/PermissionEditor.js +7 -0
  64. package/dist/components/headless/PermissionEditor.js.map +1 -0
  65. package/dist/components/headless/TenantSwitcher.d.ts +39 -0
  66. package/dist/components/headless/TenantSwitcher.d.ts.map +1 -0
  67. package/dist/components/headless/TenantSwitcher.js +61 -0
  68. package/dist/components/headless/TenantSwitcher.js.map +1 -0
  69. package/dist/components/headless/TenantTree.d.ts +21 -0
  70. package/dist/components/headless/TenantTree.d.ts.map +1 -0
  71. package/dist/components/headless/TenantTree.js +22 -0
  72. package/dist/components/headless/TenantTree.js.map +1 -0
  73. package/dist/components/storybook-helpers.d.ts +96 -0
  74. package/dist/components/storybook-helpers.d.ts.map +1 -0
  75. package/dist/components/storybook-helpers.js +473 -0
  76. package/dist/components/storybook-helpers.js.map +1 -0
  77. package/dist/hooks/use-config.d.ts +16 -0
  78. package/dist/hooks/use-config.d.ts.map +1 -0
  79. package/dist/hooks/use-config.js +54 -0
  80. package/dist/hooks/use-config.js.map +1 -0
  81. package/dist/hooks/use-messages.d.ts +11 -0
  82. package/dist/hooks/use-messages.d.ts.map +1 -0
  83. package/dist/hooks/use-messages.js +23 -0
  84. package/dist/hooks/use-messages.js.map +1 -0
  85. package/dist/hooks/use-permissions.d.ts +10 -0
  86. package/dist/hooks/use-permissions.d.ts.map +1 -0
  87. package/dist/hooks/use-permissions.js +48 -0
  88. package/dist/hooks/use-permissions.js.map +1 -0
  89. package/dist/hooks/use-tenant-tree.d.ts +13 -0
  90. package/dist/hooks/use-tenant-tree.d.ts.map +1 -0
  91. package/dist/hooks/use-tenant-tree.js +65 -0
  92. package/dist/hooks/use-tenant-tree.js.map +1 -0
  93. package/dist/hooks/use-tenant.d.ts +23 -0
  94. package/dist/hooks/use-tenant.d.ts.map +1 -0
  95. package/dist/hooks/use-tenant.js +6 -0
  96. package/dist/hooks/use-tenant.js.map +1 -0
  97. package/dist/hooks/use-toast.d.ts +14 -0
  98. package/dist/hooks/use-toast.d.ts.map +1 -0
  99. package/dist/hooks/use-toast.js +46 -0
  100. package/dist/hooks/use-toast.js.map +1 -0
  101. package/dist/i18n.d.ts +57 -0
  102. package/dist/i18n.d.ts.map +1 -0
  103. package/dist/i18n.js +59 -0
  104. package/dist/i18n.js.map +1 -0
  105. package/dist/index.d.ts +38 -0
  106. package/dist/index.d.ts.map +1 -0
  107. package/dist/index.js +26 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/provider.d.ts +30 -0
  110. package/dist/provider.d.ts.map +1 -0
  111. package/dist/provider.js +82 -0
  112. package/dist/provider.js.map +1 -0
  113. package/package.json +53 -0
@@ -0,0 +1,125 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Skeleton } from "./Skeleton.js";
3
+ import { TableSkeleton } from "./TableSkeleton.js";
4
+ const meta = {
5
+ title: "Components/Skeleton",
6
+ component: Skeleton,
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: "Placeholder loading skeleton used while data is being fetched. " +
11
+ "Supports text, rectangle, and circle variants with customizable " +
12
+ "dimensions and count. Used internally by TableSkeleton.",
13
+ },
14
+ },
15
+ },
16
+ };
17
+ export default meta;
18
+ /**
19
+ * Text variant — default skeleton for loading text lines.
20
+ * Full width, 13px height matching the base font size.
21
+ */
22
+ export const Text = {
23
+ args: {
24
+ variant: "text",
25
+ },
26
+ decorators: [
27
+ (Story) => (_jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(Story, {}) })),
28
+ ],
29
+ };
30
+ /**
31
+ * Multiple text lines simulating a paragraph or list loading state.
32
+ */
33
+ export const TextMultipleLines = {
34
+ args: {
35
+ variant: "text",
36
+ count: 4,
37
+ },
38
+ decorators: [
39
+ (Story) => (_jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(Story, {}) })),
40
+ ],
41
+ };
42
+ /**
43
+ * Rectangle variant — for cards, images, or block-level placeholders.
44
+ */
45
+ export const Rect = {
46
+ args: {
47
+ variant: "rect",
48
+ width: "300px",
49
+ height: "120px",
50
+ },
51
+ decorators: [
52
+ (Story) => (_jsx("div", { style: { padding: "24px" }, children: _jsx(Story, {}) })),
53
+ ],
54
+ };
55
+ /**
56
+ * Circle variant — for avatar or icon placeholders.
57
+ */
58
+ export const Circle = {
59
+ args: {
60
+ variant: "circle",
61
+ width: "48px",
62
+ height: "48px",
63
+ },
64
+ decorators: [
65
+ (Story) => (_jsx("div", { style: { padding: "24px" }, children: _jsx(Story, {}) })),
66
+ ],
67
+ };
68
+ /**
69
+ * Composite layout: avatar circle next to text lines,
70
+ * simulating a tenant detail card loading state.
71
+ */
72
+ export const CompositeLayout = {
73
+ render: () => (_jsxs("div", { style: { padding: "24px", maxWidth: 400 }, children: [_jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "flex-start" }, children: [_jsx(Skeleton, { variant: "circle", width: "40px", height: "40px" }), _jsxs("div", { style: { flex: 1 }, children: [_jsx(Skeleton, { variant: "text", width: "60%" }), _jsx("div", { style: { height: "8px" } }), _jsx(Skeleton, { variant: "text", width: "40%" })] })] }), _jsx("div", { style: { marginTop: "16px" }, children: _jsx(Skeleton, { variant: "rect", height: "80px" }) })] })),
74
+ };
75
+ /**
76
+ * Custom sizing with small dimensions for inline placeholders.
77
+ */
78
+ export const CustomSizing = {
79
+ args: {
80
+ variant: "text",
81
+ width: "120px",
82
+ height: "10px",
83
+ },
84
+ decorators: [
85
+ (Story) => (_jsx("div", { style: { padding: "24px" }, children: _jsx(Story, {}) })),
86
+ ],
87
+ };
88
+ // ---------------------------------------------------------------------------
89
+ // TableSkeleton stories
90
+ // ---------------------------------------------------------------------------
91
+ const tableMeta = {
92
+ title: "Components/TableSkeleton",
93
+ component: TableSkeleton,
94
+ parameters: {
95
+ docs: {
96
+ description: {
97
+ component: "Table placeholder shown while config or permission data is loading. " +
98
+ "Uses Skeleton components in a table layout with configurable row and column counts.",
99
+ },
100
+ },
101
+ },
102
+ };
103
+ // We export the table stories under a second meta via a named story export
104
+ // pattern. Storybook CSF only supports one default export per file, so
105
+ // TableSkeleton stories are included here as additional stories.
106
+ /**
107
+ * Default TableSkeleton with 5 rows and 4 columns, matching the
108
+ * ConfigEditor table layout.
109
+ */
110
+ export const TableDefault = {
111
+ render: () => (_jsx("div", { style: { padding: "24px", maxWidth: 900 }, children: _jsx(TableSkeleton, { rows: 5, columns: 4 }) })),
112
+ };
113
+ /**
114
+ * Config-style table skeleton with 5 columns (Key, Value, Source, Status, Actions).
115
+ */
116
+ export const TableConfigLayout = {
117
+ render: () => (_jsx("div", { style: { padding: "24px", maxWidth: 900 }, children: _jsx(TableSkeleton, { rows: 7, columns: 5 }) })),
118
+ };
119
+ /**
120
+ * Minimal skeleton — 2 rows, 2 columns.
121
+ */
122
+ export const TableMinimal = {
123
+ render: () => (_jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(TableSkeleton, { rows: 2, columns: 2 }) })),
124
+ };
125
+ //# sourceMappingURL=Skeleton.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Skeleton.stories.js","sourceRoot":"","sources":["../../src/components/Skeleton.stories.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface TableSkeletonProps {
2
+ /** Number of placeholder rows */
3
+ rows?: number;
4
+ /** Number of columns */
5
+ columns?: number;
6
+ /** Additional CSS class name */
7
+ className?: string;
8
+ }
9
+ export declare function TableSkeleton({ rows, columns, className, }: TableSkeletonProps): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=TableSkeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableSkeleton.d.ts","sourceRoot":"","sources":["../../src/components/TableSkeleton.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAQ,EACR,OAAW,EACX,SAAS,GACV,EAAE,kBAAkB,2CA8BpB"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Skeleton } from "./Skeleton.js";
3
+ export function TableSkeleton({ rows = 5, columns = 4, className, }) {
4
+ return (_jsx("div", { className: `stratum-table-skeleton ${className || ""}`, role: "status", "aria-label": "Loading table data", "aria-busy": "true", children: _jsxs("table", { className: "stratum-table-skeleton__table", children: [_jsx("thead", { children: _jsx("tr", { children: Array.from({ length: columns }, (_, colIndex) => (_jsx("th", { children: _jsx(Skeleton, { variant: "text", width: "60%", height: "0.75rem" }) }, colIndex))) }) }), _jsx("tbody", { children: Array.from({ length: rows }, (_, rowIndex) => (_jsx("tr", { children: Array.from({ length: columns }, (_, colIndex) => (_jsx("td", { children: _jsx(Skeleton, { variant: "text", width: colIndex === 0 ? "70%" : colIndex === columns - 1 ? "40%" : "55%" }) }, colIndex))) }, rowIndex))) })] }) }));
5
+ }
6
+ //# sourceMappingURL=TableSkeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableSkeleton.js","sourceRoot":"","sources":["../../src/components/TableSkeleton.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAWzC,MAAM,UAAU,aAAa,CAAC,EAC5B,IAAI,GAAG,CAAC,EACR,OAAO,GAAG,CAAC,EACX,SAAS,GACU;IACnB,OAAO,CACL,cAAK,SAAS,EAAE,0BAA0B,SAAS,IAAI,EAAE,EAAE,EAAE,IAAI,EAAC,QAAQ,gBAAY,oBAAoB,eAAW,MAAM,YACzH,iBAAO,SAAS,EAAC,+BAA+B,aAC9C,0BACE,uBACG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,CAChD,uBACE,KAAC,QAAQ,IAAC,OAAO,EAAC,MAAM,EAAC,KAAK,EAAC,KAAK,EAAC,MAAM,EAAC,SAAS,GAAG,IADjD,QAAQ,CAEZ,CACN,CAAC,GACC,GACC,EACR,0BACG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,CAC7C,uBACG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,CAChD,uBACE,KAAC,QAAQ,IACP,OAAO,EAAC,MAAM,EACd,KAAK,EAAE,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GACxE,IAJK,QAAQ,CAKZ,CACN,CAAC,IARK,QAAQ,CASZ,CACN,CAAC,GACI,IACF,GACJ,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface TenantSwitcherProps {
2
+ rootId?: string;
3
+ onTenantChange?: (tenantId: string) => void;
4
+ className?: string;
5
+ }
6
+ export declare function TenantSwitcher({ rootId, onTenantChange, className }: TenantSwitcherProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=TenantSwitcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantSwitcher.d.ts","sourceRoot":"","sources":["../../src/components/TenantSwitcher.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,mBAAmB,2CAkFxF"}
@@ -0,0 +1,40 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useMemo } from "react";
3
+ import { useTenantTree } from "../hooks/use-tenant-tree.js";
4
+ import { useTenant } from "../hooks/use-tenant.js";
5
+ import { useMessages } from "../hooks/use-messages.js";
6
+ export function TenantSwitcher({ rootId, onTenantChange, className }) {
7
+ const { tree, loading } = useTenantTree(rootId);
8
+ const { tenant, switchTenant } = useTenant();
9
+ const { t } = useMessages();
10
+ const [isOpen, setIsOpen] = useState(false);
11
+ const [search, setSearch] = useState("");
12
+ const flattenTree = useMemo(() => {
13
+ const result = [];
14
+ function walk(nodes, depth) {
15
+ for (const node of nodes) {
16
+ result.push({ node, depth });
17
+ walk(node.children, depth + 1);
18
+ }
19
+ }
20
+ walk(tree, 0);
21
+ return result;
22
+ }, [tree]);
23
+ const filtered = useMemo(() => {
24
+ if (!search)
25
+ return flattenTree;
26
+ const lower = search.toLowerCase();
27
+ return flattenTree.filter(({ node }) => node.name.toLowerCase().includes(lower) ||
28
+ node.slug.toLowerCase().includes(lower));
29
+ }, [flattenTree, search]);
30
+ const handleSelect = async (tenantId) => {
31
+ await switchTenant(tenantId);
32
+ onTenantChange?.(tenantId);
33
+ setIsOpen(false);
34
+ setSearch("");
35
+ };
36
+ if (loading)
37
+ return _jsx("div", { className: className, children: t("tenantSwitcher.loading") });
38
+ return (_jsxs("div", { className: `stratum-tenant-switcher ${className || ""}`, children: [_jsxs("button", { type: "button", onClick: () => setIsOpen(!isOpen), className: "stratum-tenant-switcher__trigger", "aria-haspopup": "listbox", "aria-expanded": isOpen, children: [tenant ? tenant.name : t("tenantSwitcher.placeholder"), _jsx("span", { "aria-hidden": "true", children: " \u25BE" })] }), isOpen && (_jsxs("div", { className: "stratum-tenant-switcher__dropdown", role: "listbox", children: [_jsx("input", { type: "text", value: search, onChange: (e) => setSearch(e.target.value), placeholder: t("tenantSwitcher.searchPlaceholder"), className: "stratum-tenant-switcher__search", "aria-label": t("tenantSwitcher.searchLabel") }), _jsx("ul", { className: "stratum-tenant-switcher__list", children: filtered.map(({ node, depth }) => (_jsxs("li", { role: "option", "aria-selected": tenant?.id === node.id, className: `stratum-tenant-switcher__item ${tenant?.id === node.id ? "stratum-tenant-switcher__item--active" : ""}`, style: { paddingInlineStart: `calc(${depth} * var(--space-lg) + var(--space-sm))` }, onClick: () => handleSelect(node.id), onKeyDown: (e) => e.key === "Enter" && handleSelect(node.id), tabIndex: 0, children: [node.name, _jsxs("span", { className: "stratum-tenant-switcher__slug", children: [" (", node.slug, ")"] })] }, node.id))) })] }))] }));
39
+ }
40
+ //# sourceMappingURL=TenantSwitcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantSwitcher.js","sourceRoot":"","sources":["../../src/components/TenantSwitcher.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { TenantSwitcher } from "./TenantSwitcher.js";
3
+ declare const meta: Meta<typeof TenantSwitcher>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof TenantSwitcher>;
6
+ /**
7
+ * Default state with a realistic MSSP/MSP/client hierarchy.
8
+ * Click the trigger to open the dropdown and browse the tenant tree.
9
+ */
10
+ export declare const Default: Story;
11
+ /**
12
+ * Loading state shown while tenant list is being fetched.
13
+ */
14
+ export declare const Loading: Story;
15
+ /**
16
+ * Empty state when no tenants exist yet.
17
+ * The dropdown opens but shows an empty list.
18
+ */
19
+ export declare const Empty: Story;
20
+ /**
21
+ * Stress test with 25+ tenants to verify scrolling, search filtering,
22
+ * and performance with a large tenant list.
23
+ */
24
+ export declare const ManyTenants: Story;
25
+ /**
26
+ * With a pre-selected tenant. The trigger shows "CyberShield MSP"
27
+ * and the dropdown highlights it as the active selection.
28
+ */
29
+ export declare const WithSelectedTenant: Story;
30
+ //# sourceMappingURL=TenantSwitcher.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantSwitcher.stories.d.ts","sourceRoot":"","sources":["../../src/components/TenantSwitcher.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAOrD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,cAAc,CAiCrC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,KAWnB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,KAazB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAahC,CAAC"}
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TenantSwitcher } from "./TenantSwitcher.js";
3
+ import { MockStratumProvider, mockTenants, generateManyTenants, } from "./storybook-helpers.js";
4
+ const meta = {
5
+ title: "Components/TenantSwitcher",
6
+ component: TenantSwitcher,
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: "Dropdown for switching between tenants in a hierarchical tree. " +
11
+ "Shows tenant names indented by depth with a search filter. " +
12
+ "Connects to the Stratum API via StratumProvider context.",
13
+ },
14
+ },
15
+ },
16
+ decorators: [
17
+ (Story, context) => {
18
+ const { tenants = mockTenants, initialTenantId, loading = false, } = context.args ?? {};
19
+ return (_jsx(MockStratumProvider, { tenants: tenants, initialTenantId: initialTenantId, loading: loading, children: _jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(Story, {}) }) }));
20
+ },
21
+ ],
22
+ };
23
+ export default meta;
24
+ /**
25
+ * Default state with a realistic MSSP/MSP/client hierarchy.
26
+ * Click the trigger to open the dropdown and browse the tenant tree.
27
+ */
28
+ export const Default = {
29
+ args: {
30
+ onTenantChange: (id) => console.log("Switched to:", id),
31
+ },
32
+ };
33
+ /**
34
+ * Loading state shown while tenant list is being fetched.
35
+ */
36
+ export const Loading = {
37
+ args: {},
38
+ decorators: [
39
+ (Story) => (_jsx(MockStratumProvider, { loading: true, children: _jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(Story, {}) }) })),
40
+ ],
41
+ };
42
+ /**
43
+ * Empty state when no tenants exist yet.
44
+ * The dropdown opens but shows an empty list.
45
+ */
46
+ export const Empty = {
47
+ args: {},
48
+ decorators: [
49
+ (Story) => (_jsx(MockStratumProvider, { tenants: [], children: _jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(Story, {}) }) })),
50
+ ],
51
+ };
52
+ /**
53
+ * Stress test with 25+ tenants to verify scrolling, search filtering,
54
+ * and performance with a large tenant list.
55
+ */
56
+ export const ManyTenants = {
57
+ args: {
58
+ onTenantChange: (id) => console.log("Switched to:", id),
59
+ },
60
+ decorators: [
61
+ (Story) => (_jsx(MockStratumProvider, { tenants: generateManyTenants(25), children: _jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(Story, {}) }) })),
62
+ ],
63
+ };
64
+ /**
65
+ * With a pre-selected tenant. The trigger shows "CyberShield MSP"
66
+ * and the dropdown highlights it as the active selection.
67
+ */
68
+ export const WithSelectedTenant = {
69
+ args: {
70
+ onTenantChange: (id) => console.log("Switched to:", id),
71
+ },
72
+ decorators: [
73
+ (Story) => (_jsx(MockStratumProvider, { initialTenantId: "00000000-0000-0000-0000-000000000003", children: _jsx("div", { style: { padding: "24px", maxWidth: 400 }, children: _jsx(Story, {}) }) })),
74
+ ],
75
+ };
76
+ //# sourceMappingURL=TenantSwitcher.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantSwitcher.stories.js","sourceRoot":"","sources":["../../src/components/TenantSwitcher.stories.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface TenantTreeProps {
2
+ rootId?: string;
3
+ onSelect?: (tenantId: string) => void;
4
+ className?: string;
5
+ }
6
+ export declare function TenantTree({ rootId, onSelect, className }: TenantTreeProps): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=TenantTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantTree.d.ts","sourceRoot":"","sources":["../../src/components/TenantTree.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsED,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,eAAe,2CAyB1E"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTenantTree } from "../hooks/use-tenant-tree.js";
3
+ import { useTenant } from "../hooks/use-tenant.js";
4
+ import { useMessages } from "../hooks/use-messages.js";
5
+ function TreeNode({ node, selectedId, onSelect, onToggle, depth, t, }) {
6
+ const hasChildren = node.children.length > 0;
7
+ return (_jsxs("li", { role: "treeitem", "aria-expanded": hasChildren ? node.expanded : undefined, children: [_jsxs("div", { className: `stratum-tree__node ${selectedId === node.id ? "stratum-tree__node--selected" : ""}`, style: { paddingInlineStart: `calc(${depth} * var(--space-xl) + var(--space-sm))` }, children: [hasChildren ? (_jsx("button", { type: "button", className: "stratum-tree__toggle", onClick: () => onToggle(node.id), "aria-label": node.expanded ? t("tenantTree.collapse") : t("tenantTree.expand"), children: node.expanded ? "\u25BC" : "\u25B6" })) : (_jsx("span", { className: "stratum-tree__spacer", children: " " })), _jsx("span", { className: "stratum-tree__label", onClick: () => onSelect?.(node.id), onKeyDown: (e) => e.key === "Enter" && onSelect?.(node.id), tabIndex: 0, role: "button", children: node.name }), _jsx("span", { className: "stratum-tree__badge", children: t("tenantTree.badgeRls") }), _jsx("span", { className: "stratum-tree__meta", children: node.status === "archived" ? t("tenantTree.archived") : "" })] }), hasChildren && node.expanded && (_jsx("ul", { role: "group", children: node.children.map((child) => (_jsx(TreeNode, { node: child, selectedId: selectedId, onSelect: onSelect, onToggle: onToggle, depth: depth + 1, t: t }, child.id))) }))] }));
8
+ }
9
+ export function TenantTree({ rootId, onSelect, className }) {
10
+ const { tree, loading, error, toggleExpand } = useTenantTree(rootId);
11
+ const { tenant } = useTenant();
12
+ const { t } = useMessages();
13
+ if (loading)
14
+ return _jsx("div", { className: className, children: t("tenantTree.loading") });
15
+ if (error)
16
+ return _jsx("div", { className: className, children: t("tenantTree.error", { message: error.message }) });
17
+ return (_jsx("div", { className: `stratum-tree ${className || ""}`, children: _jsx("ul", { role: "tree", className: "stratum-tree__root", children: tree.map((node) => (_jsx(TreeNode, { node: node, selectedId: tenant?.id, onSelect: onSelect, onToggle: toggleExpand, depth: 0, t: t }, node.id))) }) }));
18
+ }
19
+ //# sourceMappingURL=TenantTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantTree.js","sourceRoot":"","sources":["../../src/components/TenantTree.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { TenantTree } from "./TenantTree.js";
3
+ declare const meta: Meta<typeof TenantTree>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof TenantTree>;
6
+ /**
7
+ * Default 3-level hierarchy: Acme Corp -> MSSP/Direct channels ->
8
+ * MSPs and clients. Expand nodes to browse the tree.
9
+ */
10
+ export declare const Default: Story;
11
+ /**
12
+ * Loading state while the tenant tree is being fetched from the API.
13
+ */
14
+ export declare const Loading: Story;
15
+ /**
16
+ * Empty state when no tenants exist in the hierarchy.
17
+ */
18
+ export declare const Empty: Story;
19
+ /**
20
+ * Deep 5-level hierarchy: Global Platform -> Region -> MSSP -> MSP -> Client.
21
+ * Tests indentation and readability at deep nesting levels.
22
+ */
23
+ export declare const DeepHierarchy: Story;
24
+ /**
25
+ * Single root node with no children. Minimal tree display.
26
+ */
27
+ export declare const SingleRootNode: Story;
28
+ //# sourceMappingURL=TenantTree.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantTree.stories.d.ts","sourceRoot":"","sources":["../../src/components/TenantTree.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQ7C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAsBjC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,UAAU,CAAC,CAAC;AAEzC;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,KAWrB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,KAAK,EAAE,KAWnB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAa3B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,KAa5B,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { TenantTree } from "./TenantTree.js";
3
+ import { MockStratumProvider, deepHierarchyTenants, singleRootTenant, } from "./storybook-helpers.js";
4
+ const meta = {
5
+ title: "Components/TenantTree",
6
+ component: TenantTree,
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: "Interactive tree view of the tenant hierarchy. " +
11
+ "Nodes can be expanded/collapsed to reveal children. " +
12
+ "Displays RLS badges and archived status indicators.",
13
+ },
14
+ },
15
+ },
16
+ decorators: [
17
+ (Story) => (_jsx(MockStratumProvider, { children: _jsx("div", { style: { padding: "24px", maxWidth: 500 }, children: _jsx(Story, {}) }) })),
18
+ ],
19
+ };
20
+ export default meta;
21
+ /**
22
+ * Default 3-level hierarchy: Acme Corp -> MSSP/Direct channels ->
23
+ * MSPs and clients. Expand nodes to browse the tree.
24
+ */
25
+ export const Default = {
26
+ args: {
27
+ onSelect: (id) => console.log("Selected tenant:", id),
28
+ },
29
+ };
30
+ /**
31
+ * Loading state while the tenant tree is being fetched from the API.
32
+ */
33
+ export const Loading = {
34
+ args: {},
35
+ decorators: [
36
+ (Story) => (_jsx(MockStratumProvider, { loading: true, children: _jsx("div", { style: { padding: "24px", maxWidth: 500 }, children: _jsx(Story, {}) }) })),
37
+ ],
38
+ };
39
+ /**
40
+ * Empty state when no tenants exist in the hierarchy.
41
+ */
42
+ export const Empty = {
43
+ args: {},
44
+ decorators: [
45
+ (Story) => (_jsx(MockStratumProvider, { tenants: [], children: _jsx("div", { style: { padding: "24px", maxWidth: 500 }, children: _jsx(Story, {}) }) })),
46
+ ],
47
+ };
48
+ /**
49
+ * Deep 5-level hierarchy: Global Platform -> Region -> MSSP -> MSP -> Client.
50
+ * Tests indentation and readability at deep nesting levels.
51
+ */
52
+ export const DeepHierarchy = {
53
+ args: {
54
+ onSelect: (id) => console.log("Selected tenant:", id),
55
+ },
56
+ decorators: [
57
+ (Story) => (_jsx(MockStratumProvider, { tenants: deepHierarchyTenants, children: _jsx("div", { style: { padding: "24px", maxWidth: 500 }, children: _jsx(Story, {}) }) })),
58
+ ],
59
+ };
60
+ /**
61
+ * Single root node with no children. Minimal tree display.
62
+ */
63
+ export const SingleRootNode = {
64
+ args: {
65
+ onSelect: (id) => console.log("Selected tenant:", id),
66
+ },
67
+ decorators: [
68
+ (Story) => (_jsx(MockStratumProvider, { tenants: singleRootTenant, children: _jsx("div", { style: { padding: "24px", maxWidth: 500 }, children: _jsx(Story, {}) }) })),
69
+ ],
70
+ };
71
+ //# sourceMappingURL=TenantTree.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TenantTree.stories.js","sourceRoot":"","sources":["../../src/components/TenantTree.stories.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,mBAAmB,EAEnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,IAAI,GAA4B;IACpC,KAAK,EAAE,uBAAuB;IAC9B,SAAS,EAAE,UAAU;IACrB,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,WAAW,EAAE;gBACX,SAAS,EACP,iDAAiD;oBACjD,sDAAsD;oBACtD,qDAAqD;aACxD;SACF;KACF;IACD,UAAU,EAAE;QACV,CAAC,KAAK,EAAE,EAAE,CAAC,CACT,KAAC,mBAAmB,cAClB,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,YAC5C,KAAC,KAAK,KAAG,GACL,GACc,CACvB;KACF;CACF,CAAC;AAEF,eAAe,IAAI,CAAC;AAGpB;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,CAAC;KAC9D;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAU;IAC5B,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,CAAC,KAAK,EAAE,EAAE,CAAC,CACT,KAAC,mBAAmB,IAAC,OAAO,EAAE,IAAI,YAChC,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,YAC5C,KAAC,KAAK,KAAG,GACL,GACc,CACvB;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,IAAI,EAAE,EAAE;IACR,UAAU,EAAE;QACV,CAAC,KAAK,EAAE,EAAE,CAAC,CACT,KAAC,mBAAmB,IAAC,OAAO,EAAE,EAAE,YAC9B,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,YAC5C,KAAC,KAAK,KAAG,GACL,GACc,CACvB;KACF;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAU;IAClC,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,CAAC;KAC9D;IACD,UAAU,EAAE;QACV,CAAC,KAAK,EAAE,EAAE,CAAC,CACT,KAAC,mBAAmB,IAAC,OAAO,EAAE,oBAAoB,YAChD,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,YAC5C,KAAC,KAAK,KAAG,GACL,GACc,CACvB;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAU;IACnC,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,CAAC;KAC9D;IACD,UAAU,EAAE;QACV,CAAC,KAAK,EAAE,EAAE,CAAC,CACT,KAAC,mBAAmB,IAAC,OAAO,EAAE,gBAAgB,YAC5C,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,YAC5C,KAAC,KAAK,KAAG,GACL,GACc,CACvB;KACF;CACF,CAAC"}
@@ -0,0 +1,18 @@
1
+ export type ToastType = "success" | "error" | "warning" | "info";
2
+ export interface ToastData {
3
+ id: string;
4
+ message: string;
5
+ type: ToastType;
6
+ }
7
+ export interface ToastProps {
8
+ /** Toast message text */
9
+ message: string;
10
+ /** Semantic type controlling color and behavior */
11
+ type: ToastType;
12
+ /** Called when toast should be removed */
13
+ onDismiss: () => void;
14
+ /** Auto-dismiss delay in ms. Set to 0 to disable. Error toasts never auto-dismiss. Default: 4000 */
15
+ autoDismiss?: number;
16
+ }
17
+ export declare function Toast({ message, type, onDismiss, autoDismiss, }: ToastProps): import("react/jsx-runtime").JSX.Element;
18
+ //# sourceMappingURL=Toast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../src/components/Toast.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,IAAI,EAAE,SAAS,CAAC;IAChB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,oGAAoG;IACpG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AASD,wBAAgB,KAAK,CAAC,EACpB,OAAO,EACP,IAAI,EACJ,SAAS,EACT,WAAkB,GACnB,EAAE,UAAU,2CA8BZ"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useCallback } from "react";
3
+ const TYPE_CLASSES = {
4
+ success: "stratum-toast--success",
5
+ error: "stratum-toast--error",
6
+ warning: "stratum-toast--warning",
7
+ info: "stratum-toast--info",
8
+ };
9
+ export function Toast({ message, type, onDismiss, autoDismiss = 4000, }) {
10
+ const handleDismiss = useCallback(() => {
11
+ onDismiss();
12
+ }, [onDismiss]);
13
+ useEffect(() => {
14
+ // Error toasts never auto-dismiss
15
+ if (type === "error" || autoDismiss === 0)
16
+ return;
17
+ const timer = setTimeout(handleDismiss, autoDismiss);
18
+ return () => clearTimeout(timer);
19
+ }, [type, autoDismiss, handleDismiss]);
20
+ return (_jsxs("div", { className: `stratum-toast ${TYPE_CLASSES[type]}`, role: "alert", "aria-live": "polite", children: [_jsx("span", { className: "stratum-toast__message", children: message }), _jsx("button", { type: "button", className: "stratum-toast__dismiss", onClick: handleDismiss, "aria-label": "Dismiss notification", children: "\u00D7" })] }));
21
+ }
22
+ //# sourceMappingURL=Toast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.js","sourceRoot":"","sources":["../../src/components/Toast.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAqBtD,MAAM,YAAY,GAA8B;IAC9C,OAAO,EAAE,wBAAwB;IACjC,KAAK,EAAE,sBAAsB;IAC7B,OAAO,EAAE,wBAAwB;IACjC,IAAI,EAAE,qBAAqB;CAC5B,CAAC;AAEF,MAAM,UAAU,KAAK,CAAC,EACpB,OAAO,EACP,IAAI,EACJ,SAAS,EACT,WAAW,GAAG,IAAI,GACP;IACX,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;QACrC,SAAS,EAAE,CAAC;IACd,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,SAAS,CAAC,GAAG,EAAE;QACb,kCAAkC;QAClC,IAAI,IAAI,KAAK,OAAO,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO;QAElD,MAAM,KAAK,GAAG,UAAU,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;QACrD,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;IAEvC,OAAO,CACL,eACE,SAAS,EAAE,iBAAiB,YAAY,CAAC,IAAI,CAAC,EAAE,EAChD,IAAI,EAAC,OAAO,eACF,QAAQ,aAElB,eAAM,SAAS,EAAC,wBAAwB,YAAE,OAAO,GAAQ,EACzD,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,wBAAwB,EAClC,OAAO,EAAE,aAAa,gBACX,sBAAsB,uBAG1B,IACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Toast } from "./Toast.js";
3
+ declare const meta: Meta<typeof Toast>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof Toast>;
6
+ /**
7
+ * Success toast — used after saving config, creating a tenant, etc.
8
+ * Auto-dismisses after 4 seconds.
9
+ */
10
+ export declare const Success: Story;
11
+ /**
12
+ * Error toast — used for API failures, permission errors, etc.
13
+ * Does not auto-dismiss; requires manual close.
14
+ */
15
+ export declare const Error: Story;
16
+ /**
17
+ * Warning toast — used for non-critical issues like approaching
18
+ * rate limits or deprecated config keys.
19
+ */
20
+ export declare const Warning: Story;
21
+ /**
22
+ * Info toast — used for general notifications like tenant context
23
+ * switches or background operations completing.
24
+ */
25
+ export declare const Info: Story;
26
+ /**
27
+ * All four toast variants displayed together, matching the top-right
28
+ * stacked layout from the ToastContainer.
29
+ */
30
+ export declare const AllVariants: Story;
31
+ /**
32
+ * Interactive ToastContainer demo. Click buttons to trigger different
33
+ * toast types and see the stacking behavior (max 3 visible).
34
+ */
35
+ export declare const InteractiveContainer: Story;
36
+ //# sourceMappingURL=Toast.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.stories.d.ts","sourceRoot":"","sources":["../../src/components/Toast.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,KAAK,CAc5B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,KAAK,CAAC,CAAC;AAEpC;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAcrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,KAanB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAcrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,IAAI,EAAE,KAclB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,KA4BzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAsDlC,CAAC"}