@arbidocs/blocks 0.5.23 → 0.5.25
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/{ConnectedNativeDocxComparison-GMQHSY3Z.js → ConnectedNativeDocxComparison-MZX222GC.js} +6 -6
- package/dist/{ConnectedNativeDocxComparison-GMQHSY3Z.js.map → ConnectedNativeDocxComparison-MZX222GC.js.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-HH3PHNXU.cjs → ConnectedNativeDocxComparison-WRO3J6VV.cjs} +7 -7
- package/dist/{ConnectedNativeDocxComparison-HH3PHNXU.cjs.map → ConnectedNativeDocxComparison-WRO3J6VV.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-4IAKVBEF.js → ConnectedNativeDocxEditor-OJ6SYZ3W.js} +5 -5
- package/dist/{ConnectedNativeDocxEditor-4IAKVBEF.js.map → ConnectedNativeDocxEditor-OJ6SYZ3W.js.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-JNHNZG3P.cjs → ConnectedNativeDocxEditor-XTUJWL25.cjs} +7 -7
- package/dist/{ConnectedNativeDocxEditor-JNHNZG3P.cjs.map → ConnectedNativeDocxEditor-XTUJWL25.cjs.map} +1 -1
- package/dist/{ConnectedStreamedWordArtifact-CZZOH667.cjs → ConnectedStreamedWordArtifact-5JURNV4L.cjs} +7 -7
- package/dist/ConnectedStreamedWordArtifact-5JURNV4L.cjs.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-GLJCJPTP.js → ConnectedStreamedWordArtifact-KURJRZH3.js} +6 -6
- package/dist/{ConnectedStreamedWordArtifact-GLJCJPTP.js.map → ConnectedStreamedWordArtifact-KURJRZH3.js.map} +1 -1
- package/dist/{WorkspaceTableView-ECPHGWHF.js → WorkspaceTableView-2XI6FIOO.js} +7 -7
- package/dist/WorkspaceTableView-2XI6FIOO.js.map +1 -0
- package/dist/{WorkspaceTableView-6JVHGDUB.cjs → WorkspaceTableView-KG4D53SK.cjs} +13 -13
- package/dist/WorkspaceTableView-KG4D53SK.cjs.map +1 -0
- package/dist/agents/index.cjs +326 -326
- package/dist/agents/index.js +4 -4
- package/dist/{chunk-X4Y7ZHFB.js → chunk-2GDKBLD5.js} +11 -6
- package/dist/chunk-2GDKBLD5.js.map +1 -0
- package/dist/{chunk-DXO2RXVQ.cjs → chunk-3FQHFFV5.cjs} +4 -4
- package/dist/{chunk-DXO2RXVQ.cjs.map → chunk-3FQHFFV5.cjs.map} +1 -1
- package/dist/{chunk-AAVFCPKD.js → chunk-3OATYBZK.js} +4 -4
- package/dist/{chunk-AAVFCPKD.js.map → chunk-3OATYBZK.js.map} +1 -1
- package/dist/{chunk-AF24CV6J.js → chunk-4I2V55LL.js} +3 -3
- package/dist/{chunk-AF24CV6J.js.map → chunk-4I2V55LL.js.map} +1 -1
- package/dist/{chunk-VNHLFS6T.cjs → chunk-4KLBM5K5.cjs} +4 -4
- package/dist/{chunk-VNHLFS6T.cjs.map → chunk-4KLBM5K5.cjs.map} +1 -1
- package/dist/{chunk-7DDMF3DZ.cjs → chunk-53T2FY4Z.cjs} +5 -31
- package/dist/chunk-53T2FY4Z.cjs.map +1 -0
- package/dist/{chunk-BTF4AZMG.js → chunk-57CG33XJ.js} +5 -5
- package/dist/chunk-57CG33XJ.js.map +1 -0
- package/dist/chunk-5ZBXFHZW.js +434 -0
- package/dist/chunk-5ZBXFHZW.js.map +1 -0
- package/dist/{chunk-KJVDYWAM.cjs → chunk-6UKNYQ7Q.cjs} +13 -8
- package/dist/chunk-6UKNYQ7Q.cjs.map +1 -0
- package/dist/{chunk-TTJGCJWX.cjs → chunk-6UZ6YTML.cjs} +46 -6
- package/dist/chunk-6UZ6YTML.cjs.map +1 -0
- package/dist/{chunk-NVRJ6WTR.js → chunk-7RFDYAK7.js} +3 -3
- package/dist/{chunk-NVRJ6WTR.js.map → chunk-7RFDYAK7.js.map} +1 -1
- package/dist/{chunk-ZYGQFD5Y.js → chunk-BSDZXG55.js} +3 -3
- package/dist/{chunk-ZYGQFD5Y.js.map → chunk-BSDZXG55.js.map} +1 -1
- package/dist/{chunk-O4EQYPLO.cjs → chunk-C2SZQKX2.cjs} +169 -27
- package/dist/chunk-C2SZQKX2.cjs.map +1 -0
- package/dist/{chunk-I5RK4WAE.cjs → chunk-FGZQUH2Y.cjs} +3 -3
- package/dist/{chunk-I5RK4WAE.cjs.map → chunk-FGZQUH2Y.cjs.map} +1 -1
- package/dist/{chunk-7S76Q5RK.js → chunk-GA2A7OX6.js} +3 -3
- package/dist/{chunk-7S76Q5RK.js.map → chunk-GA2A7OX6.js.map} +1 -1
- package/dist/{chunk-XL55UDLO.js → chunk-IJJKUTKM.js} +5 -30
- package/dist/chunk-IJJKUTKM.js.map +1 -0
- package/dist/{chunk-BL74GYSA.cjs → chunk-JGCYM3II.cjs} +9 -9
- package/dist/{chunk-BL74GYSA.cjs.map → chunk-JGCYM3II.cjs.map} +1 -1
- package/dist/{chunk-ZX663X3X.cjs → chunk-KNRAKOCO.cjs} +6 -428
- package/dist/chunk-KNRAKOCO.cjs.map +1 -0
- package/dist/chunk-KUQOHPKP.cjs +443 -0
- package/dist/chunk-KUQOHPKP.cjs.map +1 -0
- package/dist/{chunk-JUUOJP7I.cjs → chunk-KWJW5TMH.cjs} +5 -5
- package/dist/chunk-KWJW5TMH.cjs.map +1 -0
- package/dist/{chunk-FZVAJFRH.cjs → chunk-LAGHW4JM.cjs} +24 -10
- package/dist/chunk-LAGHW4JM.cjs.map +1 -0
- package/dist/{chunk-6XW3CMU4.js → chunk-N3KNAQ55.js} +144 -4
- package/dist/chunk-N3KNAQ55.js.map +1 -0
- package/dist/{chunk-C6P2QW36.js → chunk-NZIVQ4Q4.js} +4 -4
- package/dist/{chunk-C6P2QW36.js.map → chunk-NZIVQ4Q4.js.map} +1 -1
- package/dist/{chunk-44FPFTU2.js → chunk-ORUV4MEP.js} +3 -3
- package/dist/{chunk-44FPFTU2.js.map → chunk-ORUV4MEP.js.map} +1 -1
- package/dist/{chunk-75Z5AUMM.js → chunk-QB6JCNVG.js} +3 -3
- package/dist/{chunk-75Z5AUMM.js.map → chunk-QB6JCNVG.js.map} +1 -1
- package/dist/{chunk-S4G3DNMA.cjs → chunk-QZTA2M4U.cjs} +9 -9
- package/dist/{chunk-S4G3DNMA.cjs.map → chunk-QZTA2M4U.cjs.map} +1 -1
- package/dist/{chunk-F2BYURQZ.cjs → chunk-T67EFI43.cjs} +5 -5
- package/dist/{chunk-F2BYURQZ.cjs.map → chunk-T67EFI43.cjs.map} +1 -1
- package/dist/{chunk-RVKVGS72.js → chunk-TDFL676I.js} +25 -11
- package/dist/chunk-TDFL676I.js.map +1 -0
- package/dist/{chunk-YD3RN2FY.cjs → chunk-U72QI2W3.cjs} +3 -3
- package/dist/{chunk-YD3RN2FY.cjs.map → chunk-U72QI2W3.cjs.map} +1 -1
- package/dist/{chunk-75UVQKQ5.cjs → chunk-WTGJHS7F.cjs} +48 -48
- package/dist/{chunk-75UVQKQ5.cjs.map → chunk-WTGJHS7F.cjs.map} +1 -1
- package/dist/{chunk-SLRVI2YU.js → chunk-X6U6L6BG.js} +29 -4
- package/dist/chunk-X6U6L6BG.js.map +1 -0
- package/dist/{chunk-SQ5F5BFW.cjs → chunk-XDU3HHUU.cjs} +32 -6
- package/dist/chunk-XDU3HHUU.cjs.map +1 -0
- package/dist/{chunk-SKVVOEMX.js → chunk-XXUPUXBF.js} +8 -423
- package/dist/chunk-XXUPUXBF.js.map +1 -0
- package/dist/{chunk-PZRTRYPD.js → chunk-ZKAIT3M2.js} +46 -7
- package/dist/chunk-ZKAIT3M2.js.map +1 -0
- package/dist/connect/docx.cjs +9 -9
- package/dist/connect/docx.js +5 -5
- package/dist/connect/index.cjs +1393 -891
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +739 -242
- package/dist/connect/index.js.map +1 -1
- package/dist/connect/viewer.cjs +4 -4
- package/dist/connect/viewer.js +4 -4
- package/dist/connection/auth/CompactLogin.d.ts +26 -0
- package/dist/connection/auth/ConnectedLoginPage.d.ts +9 -1
- package/dist/connection/auth/index.d.ts +3 -1
- package/dist/connection/auth/sso-popup.d.ts +13 -0
- package/dist/connection/auth/sso-sign-in.d.ts +38 -0
- package/dist/connection/auth/useLoginActions.d.ts +4 -2
- package/dist/connection/projects/ConnectedProjectsPanel.d.ts +9 -1
- package/dist/connection/projects/ProjectsListPage.d.ts +41 -0
- package/dist/connection/projects/index.d.ts +1 -0
- package/dist/connection/settings-page/appearanceSection.d.ts +30 -0
- package/dist/connection/settings-page/index.d.ts +1 -0
- package/dist/facts/index.cjs +55 -55
- package/dist/facts/index.js +3 -3
- package/dist/index.cjs +498 -526
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +15 -54
- package/dist/index.js.map +1 -1
- package/dist/settings/AppearanceSettings.d.ts +1 -2
- package/dist/settings/index.cjs +162 -162
- package/dist/settings/index.d.ts +2 -1
- package/dist/settings/index.js +2 -2
- package/dist/site/index.cjs +82 -74
- package/dist/site/index.d.ts +2 -0
- package/dist/site/index.js +3 -3
- package/dist/studio/index.cjs +73 -73
- package/dist/studio/index.js +5 -5
- package/dist/theme/appearance.d.ts +47 -0
- package/dist/theme/fromCss.d.ts +33 -0
- package/dist/workflow-canvas/index.cjs +20 -18
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workflow-canvas/index.js +8 -6
- package/dist/workflow-canvas/index.js.map +1 -1
- package/dist/workspaces/index.cjs +43 -43
- package/dist/workspaces/index.js +3 -3
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/ConnectedStreamedWordArtifact-CZZOH667.cjs.map +0 -1
- package/dist/WorkspaceTableView-6JVHGDUB.cjs.map +0 -1
- package/dist/WorkspaceTableView-ECPHGWHF.js.map +0 -1
- package/dist/chunk-6XW3CMU4.js.map +0 -1
- package/dist/chunk-7DDMF3DZ.cjs.map +0 -1
- package/dist/chunk-AMTWY22T.js +0 -11
- package/dist/chunk-AMTWY22T.js.map +0 -1
- package/dist/chunk-BTF4AZMG.js.map +0 -1
- package/dist/chunk-FZVAJFRH.cjs.map +0 -1
- package/dist/chunk-JUUOJP7I.cjs.map +0 -1
- package/dist/chunk-KJVDYWAM.cjs.map +0 -1
- package/dist/chunk-O4EQYPLO.cjs.map +0 -1
- package/dist/chunk-PZRTRYPD.js.map +0 -1
- package/dist/chunk-RVKVGS72.js.map +0 -1
- package/dist/chunk-SKVVOEMX.js.map +0 -1
- package/dist/chunk-SLRVI2YU.js.map +0 -1
- package/dist/chunk-SQ5F5BFW.cjs.map +0 -1
- package/dist/chunk-TTJGCJWX.cjs.map +0 -1
- package/dist/chunk-X4Y7ZHFB.js.map +0 -1
- package/dist/chunk-XL55UDLO.js.map +0 -1
- package/dist/chunk-ZU2B2RZK.cjs +0 -13
- package/dist/chunk-ZU2B2RZK.cjs.map +0 -1
- package/dist/chunk-ZX663X3X.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkJGCYM3II_cjs = require('./chunk-JGCYM3II.cjs');
|
|
5
5
|
var chunk4S34OHJX_cjs = require('./chunk-4S34OHJX.cjs');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
|
|
@@ -9,10 +9,10 @@ function ConnectedNativeDocxComparison({
|
|
|
9
9
|
fontBaseUrl,
|
|
10
10
|
...props
|
|
11
11
|
}) {
|
|
12
|
-
const adapter =
|
|
12
|
+
const adapter = chunkJGCYM3II_cjs.useConnectedNativeDocxAdapter(fontBaseUrl);
|
|
13
13
|
return /* @__PURE__ */ jsxRuntime.jsx(chunk4S34OHJX_cjs.NativeDocxComparison, { ...props, adapter, onCompared: adapter.onVersionSaved });
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
exports.ConnectedNativeDocxComparison = ConnectedNativeDocxComparison;
|
|
17
|
-
//# sourceMappingURL=chunk-
|
|
18
|
-
//# sourceMappingURL=chunk-
|
|
17
|
+
//# sourceMappingURL=chunk-4KLBM5K5.cjs.map
|
|
18
|
+
//# sourceMappingURL=chunk-4KLBM5K5.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection/docx/ConnectedNativeDocxComparison.tsx"],"names":["useConnectedNativeDocxAdapter","NativeDocxComparison"],"mappings":";;;;;;AAOO,SAAS,6BAAA,CAA8B;AAAA,EAC5C,WAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAyF;AACvF,EAAA,MAAM,OAAA,GAAUA,gDAA8B,WAAW,CAAA;AACzD,EAAA,sCAAQC,sCAAA,EAAA,EAAsB,GAAG,OAAO,OAAA,EAAkB,UAAA,EAAY,QAAQ,cAAA,EAAgB,CAAA;AAChG","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/connection/docx/ConnectedNativeDocxComparison.tsx"],"names":["useConnectedNativeDocxAdapter","NativeDocxComparison"],"mappings":";;;;;;AAOO,SAAS,6BAAA,CAA8B;AAAA,EAC5C,WAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAyF;AACvF,EAAA,MAAM,OAAA,GAAUA,gDAA8B,WAAW,CAAA;AACzD,EAAA,sCAAQC,sCAAA,EAAA,EAAsB,GAAG,OAAO,OAAA,EAAkB,UAAA,EAAY,QAAQ,cAAA,EAAgB,CAAA;AAChG","file":"chunk-4KLBM5K5.cjs","sourcesContent":["import {\n NativeDocxComparison,\n type NativeDocxComparisonProps,\n} from '../../docx/NativeDocxComparison'\nimport { useConnectedNativeDocxAdapter } from './ConnectedNativeDocxEditor'\n\n/** The Word redline of two documents or versions, on the signed-in session. */\nexport function ConnectedNativeDocxComparison({\n fontBaseUrl,\n ...props\n}: Omit<NativeDocxComparisonProps, 'adapter' | 'onCompared'> & { fontBaseUrl?: string }) {\n const adapter = useConnectedNativeDocxAdapter(fontBaseUrl)\n return <NativeDocxComparison {...props} adapter={adapter} onCompared={adapter.onVersionSaved} />\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkXDU3HHUU_cjs = require('./chunk-XDU3HHUU.cjs');
|
|
5
5
|
var chunkQW3SVHGM_cjs = require('./chunk-QW3SVHGM.cjs');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
-
var ui = require('@arbidocs/react/ui');
|
|
8
7
|
var lucideReact = require('lucide-react');
|
|
8
|
+
var ui = require('@arbidocs/react/ui');
|
|
9
9
|
|
|
10
10
|
function DataTableBlock({ columns, rows, caption, emptyText, testId }) {
|
|
11
11
|
const area = testId ?? "data-table-block";
|
|
@@ -26,7 +26,7 @@ function DataTableBlock({ columns, rows, caption, emptyText, testId }) {
|
|
|
26
26
|
}
|
|
27
27
|
) : null,
|
|
28
28
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29
|
-
|
|
29
|
+
chunkXDU3HHUU_cjs.DataTable,
|
|
30
30
|
{
|
|
31
31
|
columns: tableColumns,
|
|
32
32
|
rows: tableRows,
|
|
@@ -37,31 +37,6 @@ function DataTableBlock({ columns, rows, caption, emptyText, testId }) {
|
|
|
37
37
|
)
|
|
38
38
|
] });
|
|
39
39
|
}
|
|
40
|
-
function PageHeader({
|
|
41
|
-
title,
|
|
42
|
-
eyebrow,
|
|
43
|
-
description,
|
|
44
|
-
leading,
|
|
45
|
-
actions,
|
|
46
|
-
tabs,
|
|
47
|
-
className,
|
|
48
|
-
testId
|
|
49
|
-
}) {
|
|
50
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cn("flex flex-col gap-3", className), "data-testid": testId, children: [
|
|
51
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between", children: [
|
|
52
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
53
|
-
leading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", "data-slot": "page-header-leading", children: leading }),
|
|
54
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
55
|
-
eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground", children: eyebrow }),
|
|
56
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "font-display text-2xl font-semibold tracking-tight text-foreground", children: title }),
|
|
57
|
-
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 max-w-2xl text-sm text-muted-foreground", children: description })
|
|
58
|
-
] })
|
|
59
|
-
] }),
|
|
60
|
-
actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
61
|
-
] }),
|
|
62
|
-
tabs && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "page-header-tabs", children: tabs })
|
|
63
|
-
] });
|
|
64
|
-
}
|
|
65
40
|
function MetricCard({
|
|
66
41
|
label,
|
|
67
42
|
value,
|
|
@@ -154,7 +129,6 @@ function StatGroup({ items, testId }) {
|
|
|
154
129
|
|
|
155
130
|
exports.DataTableBlock = DataTableBlock;
|
|
156
131
|
exports.MetricCard = MetricCard;
|
|
157
|
-
exports.PageHeader = PageHeader;
|
|
158
132
|
exports.StatGroup = StatGroup;
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
160
|
-
//# sourceMappingURL=chunk-
|
|
133
|
+
//# sourceMappingURL=chunk-53T2FY4Z.cjs.map
|
|
134
|
+
//# sourceMappingURL=chunk-53T2FY4Z.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/DataTableBlock.tsx","../src/components/MetricCard.tsx","../src/components/StatGroup.tsx"],"names":["jsxs","jsx","DataTable","Card","cn","ArrowUpRight","ArrowDownRight","ActionLink"],"mappings":"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","file":"chunk-53T2FY4Z.cjs","sourcesContent":["/**\n * A **serializable** data table for the Puck builder.\n *\n * The library's developer-facing {@link DataTable} is driven by `Column<T>` whose\n * `header`/`render` are React nodes and functions — powerful, but non-serializable,\n * so it can never be a Puck block. `DataTableBlock` closes that gap with a flat,\n * JSON-safe schema (string headers, string field keys, string cells) and rebuilds\n * the non-serializable `Column<Row>[]` internally, rendering through the very same\n * {@link DataTable} so it inherits the library's markup and tokens verbatim.\n */\nimport { DataTable, type Column } from './DataTable'\n\nexport interface DataTableBlockColumn {\n /** Column heading text. */\n header: string\n /** Key used to look a cell up in each row record. */\n field: string\n /** Cell/heading alignment. */\n align?: 'left' | 'right' | 'center'\n}\n\nexport interface DataTableBlockProps {\n /** Serializable column schema. */\n columns: DataTableBlockColumn[]\n /** One record per row; cells are looked up by each column's `field`. */\n rows: Array<Record<string, string>>\n /** Optional caption rendered above the table. */\n caption?: string\n /** Empty-state title shown when there are no rows. */\n emptyText?: string\n /** testid area prefix; also set on the wrapper element. */\n testId?: string\n}\n\n/** A row wrapper so {@link DataTable} gets a stable id without polluting the record. */\ninterface TableRowData {\n __id: string\n cells: Record<string, string>\n}\n\n/**\n * Renders a {@link DataTable} from a flat, serializable schema. Columns are mapped\n * to `Column<TableRowData>[]` (header string, positional-stable key, alignment) and\n * each cell is resolved by `field`; rows carry a synthetic id for React keys/testids.\n */\nexport function DataTableBlock({ columns, rows, caption, emptyText, testId }: DataTableBlockProps) {\n const area = testId ?? 'data-table-block'\n\n const tableColumns: Column<TableRowData>[] = columns.map((col, index) => ({\n key: col.field || `col-${index}`,\n header: col.header,\n align: col.align,\n render: (row) => row.cells[col.field] ?? '',\n }))\n\n const tableRows: TableRowData[] = rows.map((cells, index) => ({ __id: String(index), cells }))\n\n return (\n <div data-testid={testId}>\n {caption ? (\n <p\n className=\"mb-2 text-sm text-muted-foreground\"\n data-testid={testId ? `${testId}-caption` : undefined}\n >\n {caption}\n </p>\n ) : null}\n <DataTable\n columns={tableColumns}\n rows={tableRows}\n getRowId={(row) => row.__id}\n area={area}\n emptyTitle={emptyText}\n />\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { ArrowDownRight, ArrowUpRight } from 'lucide-react'\nimport { Card, cn } from '@arbidocs/react/ui'\nimport { ActionLink } from './ActionLink'\n\nexport interface MetricCardProps {\n label: ReactNode\n value: ReactNode\n icon?: LucideIcon\n hint?: ReactNode\n delta?: { value: string; direction: 'up' | 'down'; good?: boolean }\n /**\n * Icon accent as a theme colour-token key (e.g. `primary`, `success`, or the host's own brand\n * token). Resolved to `var(--color-<accent>)` at render. `'default'` inherits `foreground`.\n */\n accent?: string\n /** Show a placeholder instead of the value (the figure is still being fetched). */\n isLoading?: boolean\n /** Makes the tile a real link (ctrl/cmd-click works). */\n href?: string\n /** Click handler; with `href`, a plain click calls it instead of navigating. */\n onSelect?: () => void\n className?: string\n testId?: string\n}\n\n/** The one true KPI tile. Used across every dashboard and module header. */\nexport function MetricCard({\n label,\n value,\n icon: Icon,\n hint,\n delta,\n accent = 'default',\n isLoading = false,\n href,\n onSelect,\n className,\n testId,\n}: MetricCardProps) {\n const accentStyle =\n accent && accent !== 'default' ? { color: `var(--color-${accent})` } : undefined\n const deltaGood = delta?.good ?? delta?.direction === 'up'\n const isInteractive = Boolean(href || onSelect)\n const card = (\n <Card\n variant=\"elevated\"\n className={cn('card-hover min-w-0 rounded-xl p-5', className)}\n data-testid={isInteractive ? undefined : testId}\n aria-busy={isLoading || undefined}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <p className=\"min-w-0 text-xs font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </p>\n {Icon && <Icon className=\"size-4 shrink-0\" style={accentStyle} />}\n </div>\n {isLoading ? (\n <div\n className=\"mt-2 h-8 w-20 animate-pulse rounded bg-muted\"\n data-slot=\"metric-card-skeleton\"\n />\n ) : (\n <p\n className=\"mt-2 font-display text-2xl font-semibold tracking-tight [overflow-wrap:anywhere]\"\n data-testid={testId && `${testId}-value`}\n >\n {value}\n </p>\n )}\n <div className=\"mt-1 flex items-center gap-2\">\n {delta && !isLoading && (\n <span\n className={cn(\n 'inline-flex items-center gap-0.5 text-xs font-medium',\n deltaGood ? 'text-success' : 'text-destructive'\n )}\n >\n {delta.direction === 'up' ? (\n <ArrowUpRight className=\"size-3\" />\n ) : (\n <ArrowDownRight className=\"size-3\" />\n )}\n {delta.value}\n </span>\n )}\n {hint && <span className=\"text-xs text-muted-foreground\">{hint}</span>}\n </div>\n </Card>\n )\n if (!isInteractive) return card\n return (\n <ActionLink\n href={href}\n onSelect={onSelect}\n className=\"block rounded-xl text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-testid={testId}\n >\n {card}\n </ActionLink>\n )\n}\n","import { cn } from '@arbidocs/react/ui'\n\nexport interface StatItem {\n value: string\n label: string\n /** Optional caption under the label (e.g. a qualifier or unit). */\n sub?: string\n}\n\nexport interface StatGroupProps {\n items: StatItem[]\n testId?: string\n}\n\nconst GRID: Record<number, string> = {\n 1: 'grid-cols-1',\n 2: 'grid-cols-2',\n 3: 'grid-cols-2 sm:grid-cols-3',\n 4: 'grid-cols-2 lg:grid-cols-4',\n}\n\n/** Big-number stat group — headline metrics with captions. */\nexport function StatGroup({ items, testId }: StatGroupProps) {\n const list = items ?? []\n const cols = GRID[Math.min(list.length, 4)] ?? GRID[4]\n return (\n <dl className={cn('grid gap-8', cols)} data-testid={testId}>\n {list.map((item, i) => (\n <div key={i} className=\"min-w-0 text-center\" data-testid={testId && `${testId}-item-${i}`}>\n <dt className=\"sr-only\">{item.label}</dt>\n <dd className=\"text-4xl font-semibold tracking-tight [overflow-wrap:anywhere] sm:text-5xl\">\n {item.value}\n </dd>\n <p className=\"mt-2 text-sm text-muted-foreground\">{item.label}</p>\n {item.sub && <p className=\"mt-1 text-xs text-muted-foreground/80\">{item.sub}</p>}\n </div>\n ))}\n </dl>\n )\n}\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { entityNoun } from '@arbidocs/react/ui';
|
|
3
|
+
|
|
2
4
|
// src/workspaces/workspace-type.ts
|
|
3
5
|
function getHumanUserCount(users) {
|
|
4
6
|
if (!users) return 0;
|
|
@@ -33,8 +35,6 @@ function getVariantBorderClass(variant) {
|
|
|
33
35
|
return "border-gray-600";
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
// src/workspaces/workspace-groups.ts
|
|
38
38
|
var NO_PROJECT_GROUP_KEY = "__none__";
|
|
39
39
|
var isListedWorkspace = (workspace) => workspace.workspace_type !== "skills";
|
|
40
40
|
var byPinThenName = (pinned) => (a, b) => {
|
|
@@ -66,7 +66,7 @@ function groupWorkspacesByProject(workspaces, {
|
|
|
66
66
|
groups.push({
|
|
67
67
|
key: projectExtId ?? NO_PROJECT_GROUP_KEY,
|
|
68
68
|
projectExtId,
|
|
69
|
-
title: projectExtId ? name || (isOwned ? "Personal" :
|
|
69
|
+
title: projectExtId ? name || (isOwned ? "Personal" : `Unnamed ${entityNoun("PROJECT")}`) : isCommon ? "Common" : workspacesLabel,
|
|
70
70
|
isOwned,
|
|
71
71
|
isCommon,
|
|
72
72
|
workspaces: [...list].sort(byPinThenName(pinned))
|
|
@@ -144,5 +144,5 @@ function workspaceFilterAttributes(workspace, { selfId, pinned }) {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
export { NO_PROJECT_GROUP_KEY, WORKSPACE_CATEGORY_FILTERS, byRecentUpdate, getHumanUserCount, getVariantBgClass, getVariantBorderClass, getWorkspaceTypeInfo, groupWorkspacesByProject, isAgentAccount, isListedWorkspace, projectFilterId, workspaceConversationCount, workspaceDocumentCount, workspaceFilterAttributes, workspaceGroupStats };
|
|
147
|
-
//# sourceMappingURL=chunk-
|
|
148
|
-
//# sourceMappingURL=chunk-
|
|
147
|
+
//# sourceMappingURL=chunk-57CG33XJ.js.map
|
|
148
|
+
//# sourceMappingURL=chunk-57CG33XJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/workspaces/workspace-type.ts","../src/workspaces/workspace-groups.ts"],"names":[],"mappings":"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","file":"chunk-57CG33XJ.js","sourcesContent":["/**\n * Workspace Type Utilities\n *\n * Helper functions for determining workspace type information.\n */\n\nexport type WorkspaceVariant = 'primary' | 'secondary' | 'gray'\n\n/**\n * Count non-agent users in a workspace.\n * Workspace users with agent_ext_id are agents and should not count\n * for determining workspace type (individual vs group).\n */\nexport function getHumanUserCount(users?: { agent_ext_id?: string | null }[]): number {\n if (!users) return 0\n return users.filter((u) => !u.agent_ext_id).length\n}\n\n/**\n * Helper to determine workspace type and variant\n */\nexport function getWorkspaceTypeInfo(\n isPublic: boolean,\n userCount: number\n): { type: string; variant: WorkspaceVariant } {\n if (isPublic) {\n return { type: 'Common', variant: 'gray' }\n }\n if (userCount > 1) {\n return { type: 'Group', variant: 'secondary' }\n }\n return { type: 'Individual', variant: 'primary' }\n}\n\n/**\n * Returns the Tailwind background color class for a workspace type variant\n */\nexport function getVariantBgClass(variant: WorkspaceVariant): string {\n switch (variant) {\n case 'primary':\n return 'bg-primary'\n case 'secondary':\n return 'bg-secondary'\n case 'gray':\n return 'bg-gray-600'\n }\n}\n\n/**\n * Returns the Tailwind border color class for a workspace type variant\n */\nexport function getVariantBorderClass(variant: WorkspaceVariant): string {\n switch (variant) {\n case 'primary':\n return 'border-primary'\n case 'secondary':\n return 'border-secondary'\n case 'gray':\n return 'border-gray-600'\n }\n}\n","/**\n * The user's workspaces grouped by project, as the workspace list shows them (cards and table\n * alike): one group per project, the user's own projects first (an owned project with no\n * workspace yet still gets its group, to invite the first one), other people's projects by name,\n * and the workspaces with no visible project last. Plus the tri-state filter over the list\n * (projects and workspace categories) and the totals a group's heading shows.\n *\n * Pure: a host maps nothing; these read the API's workspace and project records as they come.\n */\nimport type { components } from '@arbidocs/client'\nimport { getHumanUserCount, getWorkspaceTypeInfo } from './workspace-type'\nimport { entityNoun } from '@arbidocs/react/ui'\n\nexport type GroupedWorkspace = components['schemas']['WorkspaceResponse']\ntype Project = Pick<\n components['schemas']['ProjectResponse'],\n 'external_id' | 'name' | 'subscription' | 'created_by'\n>\n\n/** Group key of the workspaces that have no visible project. */\nexport const NO_PROJECT_GROUP_KEY = '__none__'\n\nexport interface WorkspaceProjectGroup {\n /** Stable key (the project's id, or `NO_PROJECT_GROUP_KEY`): collapse state and row ids. */\n key: string\n projectExtId: string | null\n /** The project's name with the fallbacks applied (\"Personal\", \"Common\", \"Workspaces\"…). */\n title: string\n /** The user owns the project. */\n isOwned: boolean\n /**\n * The no-project group of public workspaces the user is not a member of (\"Common\"): shared\n * with everyone, so it starts collapsed.\n */\n isCommon: boolean\n /** Pinned first, then by name. */\n workspaces: GroupedWorkspace[]\n}\n\nexport interface GroupWorkspacesOptions {\n /** The signed-in user (`usr-…`): whose projects and workspaces are \"own\". */\n selfId: string | undefined\n /** Pinned workspace ids: first within their group. */\n pinned?: ReadonlySet<string>\n /** The user's projects: fresher names, and a group for each owned project with no workspace. */\n projects?: readonly Project[]\n /** The plural word for workspaces (the own no-project group's title). */\n workspacesLabel?: string\n}\n\n/** The skills marketplace is a system workspace: reached through the skills UI, never listed. */\nexport const isListedWorkspace = (workspace: Pick<GroupedWorkspace, 'workspace_type'>): boolean =>\n workspace.workspace_type !== 'skills'\n\nconst byPinThenName =\n (pinned: ReadonlySet<string>) => (a: GroupedWorkspace, b: GroupedWorkspace) => {\n const aPinned = pinned.has(a.external_id)\n const bPinned = pinned.has(b.external_id)\n if (aPinned !== bPinned) return aPinned ? -1 : 1\n return a.name.localeCompare(b.name)\n }\n\n/**\n * Group `workspaces` (already filtered) by project. The order: own projects (by name, then the\n * own projects with no workspace), other people's projects by name, the no-project group last.\n */\nexport function groupWorkspacesByProject(\n workspaces: readonly GroupedWorkspace[],\n {\n selfId,\n pinned = new Set(),\n projects = [],\n workspacesLabel = 'Workspaces',\n }: GroupWorkspacesOptions\n): WorkspaceProjectGroup[] {\n const byProject = new Map<string | null, GroupedWorkspace[]>()\n for (const workspace of workspaces) {\n const key = workspace.project_ext_id ?? null\n const list = byProject.get(key)\n if (list) list.push(workspace)\n else byProject.set(key, [workspace])\n }\n\n const projectById = new Map(projects.map((p) => [p.external_id, p]))\n const groups: WorkspaceProjectGroup[] = []\n for (const [projectExtId, list] of byProject) {\n const first = list[0]\n const isOwned = !!projectExtId && first.project_owner_ext_id === selfId\n const isCommon = !projectExtId && !list.some((w) => w.is_member)\n const name = projectExtId\n ? projectById.get(projectExtId)?.name || first.project_name || null\n : null\n groups.push({\n key: projectExtId ?? NO_PROJECT_GROUP_KEY,\n projectExtId,\n title: projectExtId\n ? name || (isOwned ? 'Personal' : `Unnamed ${entityNoun('PROJECT')}`)\n : isCommon\n ? 'Common'\n : workspacesLabel,\n isOwned,\n isCommon,\n workspaces: [...list].sort(byPinThenName(pinned)),\n })\n }\n\n groups.sort((a, b) => {\n if (!a.projectExtId !== !b.projectExtId) return a.projectExtId ? -1 : 1\n if (a.isOwned !== b.isOwned) return a.isOwned ? -1 : 1\n return a.title.localeCompare(b.title)\n })\n\n // An own project with no workspace yet keeps its group (after the own projects with some).\n const empty = projects\n .filter((p) => p.created_by === selfId && !byProject.has(p.external_id))\n .map<WorkspaceProjectGroup>((p) => ({\n key: p.external_id,\n projectExtId: p.external_id,\n title: p.name || 'Personal',\n isOwned: true,\n isCommon: false,\n workspaces: [],\n }))\n const ownedCount = groups.filter((g) => g.isOwned).length\n groups.splice(ownedCount, 0, ...empty)\n return groups\n}\n\n/** Most recently updated first (the cards' order within a group). */\nexport function byRecentUpdate(a: GroupedWorkspace, b: GroupedWorkspace): number {\n const time = (w: GroupedWorkspace) => {\n const t = Date.parse(w.updated_at ?? '')\n return Number.isNaN(t) ? 0 : t\n }\n return time(b) - time(a)\n}\n\n/** What a group's heading reports about its workspaces: sums, and distinct people (no agents). */\nexport interface WorkspaceGroupStats {\n workspaces: number\n documents: number\n conversations: number\n members: number\n /** The most recent activity (ISO), `''` when none. */\n updatedAt: string\n}\n\nexport const workspaceDocumentCount = (w: GroupedWorkspace): number =>\n (w.shared_document_count ?? 0) + (w.private_document_count ?? 0)\n\nexport const workspaceConversationCount = (w: GroupedWorkspace): number =>\n (w.shared_conversation_count ?? 0) + (w.private_conversation_count ?? 0)\n\n/** An agent account (`agt-…`): kept out of member counts and faces. */\nexport const isAgentAccount = (user: { external_id: string }): boolean =>\n user.external_id.startsWith('agt-')\n\nexport function workspaceGroupStats(workspaces: readonly GroupedWorkspace[]): WorkspaceGroupStats {\n let documents = 0\n let conversations = 0\n let updatedAt = ''\n const members = new Set<string>()\n for (const workspace of workspaces) {\n documents += workspaceDocumentCount(workspace)\n conversations += workspaceConversationCount(workspace)\n const at = workspace.updated_at || workspace.created_at || ''\n if (at > updatedAt) updatedAt = at\n for (const member of workspace.users ?? []) {\n if (isAgentAccount(member.user)) continue\n members.add(member.user.external_id || member.user.email)\n }\n }\n return {\n workspaces: workspaces.length,\n documents,\n conversations,\n members: members.size,\n updatedAt,\n }\n}\n\n// ── Filtering ────────────────────────────────────────────────────────────────\n\n/** The category filters, in menu order. */\nexport const WORKSPACE_CATEGORY_FILTERS = [\n { id: 'owned', label: 'Owned by me' },\n { id: 'pinned', label: 'Pinned' },\n { id: 'individual', label: 'Individual' },\n { id: 'group', label: 'Group' },\n { id: 'common', label: 'Common' },\n] as const\n\n/** A project filter's id. */\nexport const projectFilterId = (projectExtId: string): string => `project:${projectExtId}`\n\n/** Which filters a workspace matches: its category, pinned, owned, and its project. */\nexport function workspaceFilterAttributes(\n workspace: GroupedWorkspace,\n { selfId, pinned }: { selfId: string | undefined; pinned: ReadonlySet<string> }\n): Record<string, boolean> {\n const { type } = getWorkspaceTypeInfo(workspace.is_public, getHumanUserCount(workspace.users))\n const attributes: Record<string, boolean> = {\n individual: type === 'Individual',\n group: type === 'Group',\n common: type === 'Common',\n pinned: pinned.has(workspace.external_id),\n owned: workspace.created_by_ext_id === selfId,\n }\n if (workspace.project_ext_id) attributes[projectFilterId(workspace.project_ext_id)] = true\n return attributes\n}\n"]}
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { matchFontPairing, FONT_PAIRINGS } from './chunk-NHZK64TQ.js';
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
import { RotateCcw, ChevronDown, Palette, Check, Save } from 'lucide-react';
|
|
5
|
+
import { Input, Card, CardHeader, CardTitle, CardContent } from '@arbidocs/react/ui';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
// src/theme/tokens.ts
|
|
9
|
+
var THEME_STYLE_ID = "arbi-theme-vars";
|
|
10
|
+
var TRIPLET_RE = /^-?\d+(?:\.\d+)?\s+-?\d+(?:\.\d+)?%\s+-?\d+(?:\.\d+)?%$/;
|
|
11
|
+
function parseRgb(color) {
|
|
12
|
+
if (color.startsWith("#")) {
|
|
13
|
+
let hex = color.slice(1);
|
|
14
|
+
if (hex.length === 3) {
|
|
15
|
+
hex = hex.split("").map((ch) => ch + ch).join("");
|
|
16
|
+
}
|
|
17
|
+
if (hex.length === 6 && /^[0-9a-fA-F]{6}$/.test(hex)) {
|
|
18
|
+
return {
|
|
19
|
+
r: parseInt(hex.slice(0, 2), 16),
|
|
20
|
+
g: parseInt(hex.slice(2, 4), 16),
|
|
21
|
+
b: parseInt(hex.slice(4, 6), 16)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const m = color.match(/^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)/i);
|
|
27
|
+
if (m) return { r: Number(m[1]), g: Number(m[2]), b: Number(m[3]) };
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
function rgbToHslTriplet(r, g, b) {
|
|
31
|
+
const rn = r / 255;
|
|
32
|
+
const gn = g / 255;
|
|
33
|
+
const bn = b / 255;
|
|
34
|
+
const max = Math.max(rn, gn, bn);
|
|
35
|
+
const min = Math.min(rn, gn, bn);
|
|
36
|
+
const l = (max + min) / 2;
|
|
37
|
+
const d = max - min;
|
|
38
|
+
let h = 0;
|
|
39
|
+
let s = 0;
|
|
40
|
+
if (d !== 0) {
|
|
41
|
+
s = d / (1 - Math.abs(2 * l - 1));
|
|
42
|
+
switch (max) {
|
|
43
|
+
case rn:
|
|
44
|
+
h = 60 * ((gn - bn) / d % 6);
|
|
45
|
+
break;
|
|
46
|
+
case gn:
|
|
47
|
+
h = 60 * ((bn - rn) / d + 2);
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
h = 60 * ((rn - gn) / d + 4);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (h < 0) h += 360;
|
|
55
|
+
return `${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
|
|
56
|
+
}
|
|
57
|
+
function toHslTriplet(color) {
|
|
58
|
+
const c = color.trim();
|
|
59
|
+
if (TRIPLET_RE.test(c)) return c;
|
|
60
|
+
const rgb = parseRgb(c);
|
|
61
|
+
if (!rgb) return c;
|
|
62
|
+
return rgbToHslTriplet(rgb.r, rgb.g, rgb.b);
|
|
63
|
+
}
|
|
64
|
+
function renderTripletBlock(colors) {
|
|
65
|
+
return Object.entries(colors).map(([key, value]) => ` --${key}: ${toHslTriplet(value)};`).join("\n");
|
|
66
|
+
}
|
|
67
|
+
function emitCssVars(theme, dark) {
|
|
68
|
+
if (typeof document === "undefined") return;
|
|
69
|
+
const meta = [
|
|
70
|
+
` --font-display: ${theme.fonts.display};`,
|
|
71
|
+
` --font-sans: ${theme.fonts.sans};`,
|
|
72
|
+
` --radius: ${theme.radius}rem;`
|
|
73
|
+
].join("\n");
|
|
74
|
+
let css = `:root {
|
|
75
|
+
${renderTripletBlock(theme.colors)}
|
|
76
|
+
${meta}
|
|
77
|
+
}`;
|
|
78
|
+
if (dark) {
|
|
79
|
+
css += `
|
|
80
|
+
:root.dark {
|
|
81
|
+
${renderTripletBlock(dark)}
|
|
82
|
+
}`;
|
|
83
|
+
}
|
|
84
|
+
let style = document.getElementById(THEME_STYLE_ID);
|
|
85
|
+
if (!style) {
|
|
86
|
+
style = document.createElement("style");
|
|
87
|
+
style.id = THEME_STYLE_ID;
|
|
88
|
+
document.head.appendChild(style);
|
|
89
|
+
}
|
|
90
|
+
style.textContent = css;
|
|
91
|
+
}
|
|
92
|
+
function removeCssVars() {
|
|
93
|
+
if (typeof document === "undefined") return;
|
|
94
|
+
document.getElementById(THEME_STYLE_ID)?.remove();
|
|
95
|
+
}
|
|
96
|
+
function normalizeOptions(optionsOrRoot) {
|
|
97
|
+
if (typeof HTMLElement !== "undefined" && optionsOrRoot instanceof HTMLElement) {
|
|
98
|
+
return { root: optionsOrRoot };
|
|
99
|
+
}
|
|
100
|
+
return optionsOrRoot;
|
|
101
|
+
}
|
|
102
|
+
function applyThemeVars(theme, optionsOrRoot = {}) {
|
|
103
|
+
const { mode = "flat", dark, root = document.documentElement } = normalizeOptions(optionsOrRoot);
|
|
104
|
+
if (mode === "cssVars") {
|
|
105
|
+
emitCssVars(theme, dark);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
for (const [key, value] of Object.entries(theme.colors)) {
|
|
109
|
+
root.style.setProperty(`--color-${key}`, value);
|
|
110
|
+
}
|
|
111
|
+
root.style.setProperty("--font-display", theme.fonts.display);
|
|
112
|
+
root.style.setProperty("--font-sans", theme.fonts.sans);
|
|
113
|
+
root.style.setProperty("--radius", `${theme.radius}rem`);
|
|
114
|
+
}
|
|
115
|
+
function applyFontVars(fonts, root = document.documentElement) {
|
|
116
|
+
root.style.setProperty("--font-display", fonts.display);
|
|
117
|
+
root.style.setProperty("--font-sans", fonts.sans);
|
|
118
|
+
}
|
|
119
|
+
function clearFontVars(root = document.documentElement) {
|
|
120
|
+
root.style.removeProperty("--font-display");
|
|
121
|
+
root.style.removeProperty("--font-sans");
|
|
122
|
+
}
|
|
123
|
+
function clearThemeVars(theme, optionsOrRoot = {}) {
|
|
124
|
+
const { mode = "flat", root = document.documentElement } = normalizeOptions(optionsOrRoot);
|
|
125
|
+
if (mode === "cssVars") {
|
|
126
|
+
removeCssVars();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
for (const key of Object.keys(theme.colors)) {
|
|
130
|
+
root.style.removeProperty(`--color-${key}`);
|
|
131
|
+
}
|
|
132
|
+
root.style.removeProperty("--font-display");
|
|
133
|
+
root.style.removeProperty("--font-sans");
|
|
134
|
+
root.style.removeProperty("--radius");
|
|
135
|
+
}
|
|
136
|
+
function ThemeEditor({
|
|
137
|
+
bundle,
|
|
138
|
+
variant = "panel",
|
|
139
|
+
preview,
|
|
140
|
+
onSave,
|
|
141
|
+
testIdPrefix = "theme",
|
|
142
|
+
defaultOpen = false
|
|
143
|
+
}) {
|
|
144
|
+
const { useStore, tokens, presets, groupLabels, mode, darkColors } = bundle;
|
|
145
|
+
const colors = useStore((s) => s.colors);
|
|
146
|
+
const fonts = useStore((s) => s.fonts);
|
|
147
|
+
const radius = useStore((s) => s.radius);
|
|
148
|
+
const activePresetId = useStore((s) => s.activePresetId);
|
|
149
|
+
const setColor = useStore((s) => s.setColor);
|
|
150
|
+
const setFont = useStore((s) => s.setFont);
|
|
151
|
+
const setFontPairing = useStore((s) => s.setFontPairing);
|
|
152
|
+
const setRadius = useStore((s) => s.setRadius);
|
|
153
|
+
const applyPreset = useStore((s) => s.applyPreset);
|
|
154
|
+
const reset = useStore((s) => s.reset);
|
|
155
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
156
|
+
const [saving, setSaving] = useState(false);
|
|
157
|
+
const [savedVia, setSavedVia] = useState(null);
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
applyThemeVars({ colors, fonts, radius }, { mode, dark: darkColors });
|
|
160
|
+
}, [colors, fonts, radius, mode, darkColors]);
|
|
161
|
+
const tid2 = (suffix) => `${testIdPrefix}-${suffix}`;
|
|
162
|
+
const groups = [...new Set(tokens.map((t) => t.group))];
|
|
163
|
+
const save = async () => {
|
|
164
|
+
if (!onSave) return;
|
|
165
|
+
setSaving(true);
|
|
166
|
+
try {
|
|
167
|
+
const via = await onSave();
|
|
168
|
+
setSavedVia(typeof via === "string" ? via : "saved");
|
|
169
|
+
} catch {
|
|
170
|
+
setSavedVia(null);
|
|
171
|
+
} finally {
|
|
172
|
+
setSaving(false);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const Presets = /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
176
|
+
presets.map((p) => /* @__PURE__ */ jsx(
|
|
177
|
+
"button",
|
|
178
|
+
{
|
|
179
|
+
type: "button",
|
|
180
|
+
onClick: () => applyPreset(p.id),
|
|
181
|
+
className: `rounded-full border px-3 py-1 text-xs font-medium transition-colors ${activePresetId === p.id ? "border-primary bg-primary text-primary-foreground" : "border-border text-foreground hover:border-primary"}`,
|
|
182
|
+
"data-testid": tid2(`preset-${p.id}`),
|
|
183
|
+
children: p.label
|
|
184
|
+
},
|
|
185
|
+
p.id
|
|
186
|
+
)),
|
|
187
|
+
/* @__PURE__ */ jsxs(
|
|
188
|
+
"button",
|
|
189
|
+
{
|
|
190
|
+
type: "button",
|
|
191
|
+
onClick: reset,
|
|
192
|
+
className: "ml-auto inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
193
|
+
"data-testid": tid2("reset"),
|
|
194
|
+
children: [
|
|
195
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "size-3" }),
|
|
196
|
+
" Reset"
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
] });
|
|
201
|
+
const colorRow = (k, label) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
202
|
+
/* @__PURE__ */ jsx(
|
|
203
|
+
"input",
|
|
204
|
+
{
|
|
205
|
+
type: "color",
|
|
206
|
+
value: colors[k] ?? "#000000",
|
|
207
|
+
onChange: (e) => setColor(k, e.target.value),
|
|
208
|
+
className: "size-9 shrink-0 cursor-pointer rounded-md border border-border bg-transparent",
|
|
209
|
+
"aria-label": label,
|
|
210
|
+
"data-testid": tid2(`color-${k}`)
|
|
211
|
+
}
|
|
212
|
+
),
|
|
213
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
214
|
+
/* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: label }),
|
|
215
|
+
/* @__PURE__ */ jsx(
|
|
216
|
+
Input,
|
|
217
|
+
{
|
|
218
|
+
value: colors[k] ?? "",
|
|
219
|
+
onChange: (e) => setColor(k, e.target.value),
|
|
220
|
+
"aria-label": `${label} hex value`,
|
|
221
|
+
className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring h-7 font-mono text-xs",
|
|
222
|
+
"data-testid": tid2(`hex-${k}`)
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
] })
|
|
226
|
+
] }, k);
|
|
227
|
+
const activePairing = matchFontPairing(fonts);
|
|
228
|
+
const Typography = /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
229
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
230
|
+
/* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: "Typeface" }),
|
|
231
|
+
/* @__PURE__ */ jsxs(
|
|
232
|
+
"select",
|
|
233
|
+
{
|
|
234
|
+
value: activePairing?.id ?? "",
|
|
235
|
+
onChange: (e) => setFontPairing(e.target.value),
|
|
236
|
+
"aria-label": "Typeface",
|
|
237
|
+
className: "mt-1 h-8 w-full rounded-md border border-border bg-card px-2 text-xs text-foreground focus-visible:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
238
|
+
"data-testid": tid2("font-pairing"),
|
|
239
|
+
children: [
|
|
240
|
+
!activePairing && /* @__PURE__ */ jsx("option", { value: "", children: "Custom" }),
|
|
241
|
+
FONT_PAIRINGS.map((pairing) => /* @__PURE__ */ jsx("option", { value: pairing.id, children: pairing.label }, pairing.id))
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
),
|
|
245
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: activePairing?.description ?? "Hand-edited font stacks." })
|
|
246
|
+
] }),
|
|
247
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
248
|
+
/* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: "Display font stack" }),
|
|
249
|
+
/* @__PURE__ */ jsx(
|
|
250
|
+
Input,
|
|
251
|
+
{
|
|
252
|
+
value: fonts.display,
|
|
253
|
+
onChange: (e) => setFont("display", e.target.value),
|
|
254
|
+
"aria-label": "Display font stack",
|
|
255
|
+
className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs",
|
|
256
|
+
"data-testid": tid2("font-display")
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
] }),
|
|
260
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
261
|
+
/* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: "Body font stack" }),
|
|
262
|
+
/* @__PURE__ */ jsx(
|
|
263
|
+
Input,
|
|
264
|
+
{
|
|
265
|
+
value: fonts.sans,
|
|
266
|
+
onChange: (e) => setFont("sans", e.target.value),
|
|
267
|
+
"aria-label": "Body font stack",
|
|
268
|
+
className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs",
|
|
269
|
+
"data-testid": tid2("font-sans")
|
|
270
|
+
}
|
|
271
|
+
)
|
|
272
|
+
] }),
|
|
273
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
274
|
+
/* @__PURE__ */ jsxs("span", { className: "block text-xs text-muted-foreground", children: [
|
|
275
|
+
"Base radius \u2014 ",
|
|
276
|
+
radius,
|
|
277
|
+
"rem"
|
|
278
|
+
] }),
|
|
279
|
+
/* @__PURE__ */ jsx(
|
|
280
|
+
"input",
|
|
281
|
+
{
|
|
282
|
+
type: "range",
|
|
283
|
+
min: 0,
|
|
284
|
+
max: 1.5,
|
|
285
|
+
step: 0.125,
|
|
286
|
+
value: radius,
|
|
287
|
+
onChange: (e) => setRadius(Number(e.target.value)),
|
|
288
|
+
"aria-label": "Base radius",
|
|
289
|
+
className: "mt-2 w-full accent-[color:var(--color-primary)]",
|
|
290
|
+
"data-testid": tid2("radius")
|
|
291
|
+
}
|
|
292
|
+
)
|
|
293
|
+
] })
|
|
294
|
+
] });
|
|
295
|
+
const Preview = /* @__PURE__ */ jsxs(Card, { variant: "elevated", className: "rounded-lg", "data-testid": tid2("preview"), children: [
|
|
296
|
+
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Live preview" }) }),
|
|
297
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-3", children: [
|
|
298
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-[var(--radius)] bg-primary p-4 text-primary-foreground", children: [
|
|
299
|
+
/* @__PURE__ */ jsx("p", { className: "font-display text-lg font-semibold", children: preview?.title ?? "Preview" }),
|
|
300
|
+
preview?.subtitle && /* @__PURE__ */ jsx("p", { className: "text-xs opacity-80", children: preview.subtitle })
|
|
301
|
+
] }),
|
|
302
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-6 gap-1.5", children: tokens.map((t) => /* @__PURE__ */ jsx(
|
|
303
|
+
"div",
|
|
304
|
+
{
|
|
305
|
+
title: t.label,
|
|
306
|
+
className: "aspect-square rounded-md border border-border",
|
|
307
|
+
style: { background: `var(--color-${t.key})` }
|
|
308
|
+
},
|
|
309
|
+
t.key
|
|
310
|
+
)) }),
|
|
311
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-[var(--radius)] border border-border bg-[color:var(--color-ai-accent-soft,var(--color-accent))] p-3", children: [
|
|
312
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[color:var(--color-ai-accent,var(--color-primary))]", children: "AI action surface" }),
|
|
313
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Themed by the AI-kit accent tokens." })
|
|
314
|
+
] })
|
|
315
|
+
] })
|
|
316
|
+
] });
|
|
317
|
+
const SaveBar = onSave && /* @__PURE__ */ jsxs("div", { className: "mt-6 flex items-center gap-3", children: [
|
|
318
|
+
/* @__PURE__ */ jsxs(
|
|
319
|
+
"button",
|
|
320
|
+
{
|
|
321
|
+
type: "button",
|
|
322
|
+
onClick: () => void save(),
|
|
323
|
+
disabled: saving,
|
|
324
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90 disabled:opacity-60",
|
|
325
|
+
"data-testid": tid2("save"),
|
|
326
|
+
children: [
|
|
327
|
+
savedVia ? /* @__PURE__ */ jsx(Check, { className: "size-4" }) : /* @__PURE__ */ jsx(Save, { className: "size-4" }),
|
|
328
|
+
saving ? "Saving\u2026" : savedVia ? "Saved" : "Save theme"
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
),
|
|
332
|
+
savedVia && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", "data-testid": tid2("via"), children: [
|
|
333
|
+
"stored via ",
|
|
334
|
+
savedVia
|
|
335
|
+
] })
|
|
336
|
+
] });
|
|
337
|
+
if (variant === "collapsed") {
|
|
338
|
+
const controlsId = `${testIdPrefix}-controls`;
|
|
339
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", "data-testid": testIdPrefix, children: [
|
|
340
|
+
Presets,
|
|
341
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-8 gap-1.5 @xl:grid-cols-12", "aria-hidden": "true", children: tokens.slice(0, 12).map((t) => /* @__PURE__ */ jsx(
|
|
342
|
+
"div",
|
|
343
|
+
{
|
|
344
|
+
title: t.label,
|
|
345
|
+
className: "aspect-square rounded-md border border-border",
|
|
346
|
+
style: { background: `var(--color-${t.key})` }
|
|
347
|
+
},
|
|
348
|
+
t.key
|
|
349
|
+
)) }),
|
|
350
|
+
/* @__PURE__ */ jsxs(
|
|
351
|
+
"button",
|
|
352
|
+
{
|
|
353
|
+
type: "button",
|
|
354
|
+
onClick: () => setOpen((o) => !o),
|
|
355
|
+
"aria-expanded": open,
|
|
356
|
+
"aria-controls": controlsId,
|
|
357
|
+
className: "inline-flex items-center gap-1.5 text-sm font-medium text-foreground hover:text-primary",
|
|
358
|
+
"data-testid": tid2("customize"),
|
|
359
|
+
children: [
|
|
360
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `size-4 transition-transform ${open ? "rotate-180" : ""}` }),
|
|
361
|
+
"Customize colours and type"
|
|
362
|
+
]
|
|
363
|
+
}
|
|
364
|
+
),
|
|
365
|
+
open && /* @__PURE__ */ jsxs(
|
|
366
|
+
"div",
|
|
367
|
+
{
|
|
368
|
+
id: controlsId,
|
|
369
|
+
className: "max-h-[28rem] overflow-y-auto rounded-md border border-border bg-card p-4",
|
|
370
|
+
"data-testid": tid2("controls"),
|
|
371
|
+
children: [
|
|
372
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Colours" }),
|
|
373
|
+
/* @__PURE__ */ jsx("div", { className: "grid gap-3 @xl:grid-cols-2", children: tokens.map((t) => colorRow(t.key, t.label)) }),
|
|
374
|
+
/* @__PURE__ */ jsx("p", { className: "mt-6 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Typography & shape" }),
|
|
375
|
+
Typography
|
|
376
|
+
]
|
|
377
|
+
}
|
|
378
|
+
),
|
|
379
|
+
SaveBar
|
|
380
|
+
] });
|
|
381
|
+
}
|
|
382
|
+
if (variant === "drawer") {
|
|
383
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col overflow-y-auto bg-card p-5", "data-testid": testIdPrefix, children: [
|
|
384
|
+
/* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center justify-between", children: /* @__PURE__ */ jsx("h2", { className: "font-display text-lg font-semibold text-foreground", children: "Theme" }) }),
|
|
385
|
+
Presets,
|
|
386
|
+
/* @__PURE__ */ jsx("p", { className: "mt-5 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Colours" }),
|
|
387
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-3", children: tokens.map((t) => colorRow(t.key, t.label)) }),
|
|
388
|
+
/* @__PURE__ */ jsx("p", { className: "mt-6 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Typography & shape" }),
|
|
389
|
+
Typography,
|
|
390
|
+
SaveBar
|
|
391
|
+
] });
|
|
392
|
+
}
|
|
393
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid gap-6 lg:grid-cols-[1fr_320px]", "data-testid": testIdPrefix, children: [
|
|
394
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
395
|
+
/* @__PURE__ */ jsxs(Card, { variant: "elevated", className: "rounded-lg", children: [
|
|
396
|
+
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 text-base", children: [
|
|
397
|
+
/* @__PURE__ */ jsx(Palette, { className: "size-4 text-[color:var(--color-primary)]" }),
|
|
398
|
+
" Presets"
|
|
399
|
+
] }) }),
|
|
400
|
+
/* @__PURE__ */ jsx(CardContent, { children: Presets })
|
|
401
|
+
] }),
|
|
402
|
+
groups.map((group) => /* @__PURE__ */ jsxs(
|
|
403
|
+
Card,
|
|
404
|
+
{
|
|
405
|
+
variant: "elevated",
|
|
406
|
+
className: "rounded-lg",
|
|
407
|
+
"data-testid": tid2(`group-${group}`),
|
|
408
|
+
children: [
|
|
409
|
+
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: groupLabels[group] ?? group }) }),
|
|
410
|
+
/* @__PURE__ */ jsx(CardContent, { className: "grid gap-3 @xl:grid-cols-2", children: tokens.filter((t) => t.group === group).map((t) => colorRow(t.key, t.label)) })
|
|
411
|
+
]
|
|
412
|
+
},
|
|
413
|
+
group
|
|
414
|
+
)),
|
|
415
|
+
/* @__PURE__ */ jsxs(Card, { variant: "elevated", className: "rounded-lg", children: [
|
|
416
|
+
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: "Typography & shape" }) }),
|
|
417
|
+
/* @__PURE__ */ jsx(CardContent, { children: Typography })
|
|
418
|
+
] }),
|
|
419
|
+
SaveBar
|
|
420
|
+
] }),
|
|
421
|
+
/* @__PURE__ */ jsx("div", { className: "lg:sticky lg:top-4 lg:self-start", children: Preview })
|
|
422
|
+
] });
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/lib/testid.ts
|
|
426
|
+
function tid(...parts) {
|
|
427
|
+
return parts.filter((p) => p !== void 0 && p !== false && p !== "").map(
|
|
428
|
+
(p) => String(p).trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "")
|
|
429
|
+
).join("-");
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export { THEME_STYLE_ID, ThemeEditor, applyFontVars, applyThemeVars, clearFontVars, clearThemeVars, tid, toHslTriplet };
|
|
433
|
+
//# sourceMappingURL=chunk-5ZBXFHZW.js.map
|
|
434
|
+
//# sourceMappingURL=chunk-5ZBXFHZW.js.map
|