@tulip-systems/core 0.9.0 → 0.10.1
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/commands.d.mts +3 -2
- package/dist/commands.mjs +2 -1
- package/dist/components/client.d.mts +2 -1
- package/dist/components/client.mjs +2 -1
- package/dist/components/editor/extensions/file-handler/extension.d.mts +1 -1
- package/dist/components/editor/extensions/image/extension.d.mts +1 -1
- package/dist/components/editor/extensions/skeleton/extension.mjs +1 -1
- package/dist/components/editor/lib/constants.d.mts +1 -1
- package/dist/components/editor/lib/extensions.d.mts +1 -1
- package/dist/components/editor/lib/helpers.d.mts +5 -1
- package/dist/components/editor/lib/helpers.mjs +8 -1
- package/dist/components/layouts/root-layout.server.d.mts +3 -2
- package/dist/components/layouts/root-layout.server.mjs +1 -3
- package/dist/components/server.d.mts +2 -2
- package/dist/components/themes/color-theme-provider.client.d.mts +27 -0
- package/dist/components/themes/color-theme-provider.client.mjs +59 -0
- package/dist/components/themes/color-theme.d.mts +29 -0
- package/dist/components/themes/color-theme.mjs +32 -0
- package/dist/components/ui/badge.d.mts +1 -1
- package/dist/components/ui/button.d.mts +1 -1
- package/dist/components/ui/item.d.mts +1 -1
- package/dist/components.d.mts +3 -2
- package/dist/components.mjs +3 -2
- package/dist/data-tables/client.d.mts +2 -1
- package/dist/data-tables/client.mjs +2 -1
- package/dist/modules/auth/handler/create-client.client.d.mts +4 -4
- package/dist/modules/commands/components/menus/context-menu.client.d.mts +6 -7
- package/dist/modules/commands/components/menus/dropdown-menu.client.d.mts +6 -7
- package/dist/modules/commands/components/menus/floating-menu.client.d.mts +6 -7
- package/dist/modules/commands/components/menus/inline-menu.client.d.mts +6 -7
- package/dist/modules/commands/components/menus/responsive-menu.client.d.mts +5 -6
- package/dist/modules/commands/components/render-command.mjs +3 -5
- package/dist/modules/commands/lib/builder.d.mts +114 -18
- package/dist/modules/commands/lib/builder.mjs +42 -7
- package/dist/modules/commands/lib/registery.d.mts +47 -14
- package/dist/modules/commands/lib/registery.mjs +76 -16
- package/dist/modules/commands/lib/utils.d.mts +11 -0
- package/dist/modules/commands/lib/utils.mjs +14 -0
- package/dist/modules/data-tables/components/footer.mjs +3 -0
- package/dist/modules/data-tables/hooks/use-context.client.d.mts +2 -2
- package/dist/modules/data-tables/lib/types.d.mts +3 -3
- package/dist/modules/data-tables/strategies/local/components.mjs +25 -0
- package/dist/modules/data-tables/strategies/local/strategy.d.mts +12 -0
- package/dist/modules/data-tables/strategies/local/strategy.mjs +31 -0
- package/dist/modules/inline/components/inputs/combobox-dropdown.client.d.mts +4 -3
- package/dist/modules/inline/components/inputs/combobox.client.d.mts +4 -3
- package/dist/modules/inline/components/inputs/date-time.client.d.mts +4 -3
- package/dist/modules/inline/components/inputs/editor.client.d.mts +4 -3
- package/dist/modules/inline/components/inputs/input.client.d.mts +7 -5
- package/dist/modules/inline/components/inputs/select.client.d.mts +4 -3
- package/dist/modules/inline/components/inputs/switch.client.d.mts +4 -3
- package/dist/modules/inline/lib/variants.d.mts +1 -1
- package/dist/modules/router/lib/query-client.d.mts +2 -1
- package/dist/modules/router/lib/query-client.mjs +2 -2
- package/dist/modules/storage/components/dropzone.client.d.mts +2 -2
- package/dist/modules/storage/lib/service.server.d.mts +21 -21
- package/dist/router.d.mts +2 -1
- package/dist/router.mjs +2 -1
- package/dist/src/components/editor/extensions/file-handler/extension.d.mts +1 -1
- package/dist/src/components/editor/extensions/image/extension.d.mts +1 -1
- package/dist/src/components/editor/extensions/skeleton/extension.mjs +1 -1
- package/dist/src/components/editor/lib/constants.d.mts +1 -1
- package/dist/src/components/editor/lib/extensions.d.mts +1 -1
- package/dist/src/components/editor/lib/helpers.d.mts +5 -1
- package/dist/src/components/editor/lib/helpers.mjs +8 -1
- package/dist/src/components/layouts/root-layout.server.d.mts +3 -2
- package/dist/src/components/layouts/root-layout.server.mjs +1 -3
- package/dist/src/components/themes/color-theme-provider.client.d.mts +27 -0
- package/dist/src/components/themes/color-theme-provider.client.mjs +59 -0
- package/dist/src/components/themes/color-theme.d.mts +29 -0
- package/dist/src/components/themes/color-theme.mjs +32 -0
- package/dist/src/components/ui/badge.d.mts +1 -1
- package/dist/src/components/ui/button-group.d.mts +1 -1
- package/dist/src/components/ui/button.d.mts +2 -2
- package/dist/src/components/ui/field.client.d.mts +1 -1
- package/dist/src/modules/commands/components/menus/context-menu.client.d.mts +6 -7
- package/dist/src/modules/commands/components/menus/dropdown-menu.client.d.mts +6 -7
- package/dist/src/modules/commands/components/menus/floating-menu.client.d.mts +6 -7
- package/dist/src/modules/commands/components/menus/inline-menu.client.d.mts +6 -7
- package/dist/src/modules/commands/components/menus/responsive-menu.client.d.mts +5 -6
- package/dist/src/modules/commands/components/render-command.mjs +3 -5
- package/dist/src/modules/commands/lib/builder.d.mts +114 -18
- package/dist/src/modules/commands/lib/builder.mjs +42 -7
- package/dist/src/modules/commands/lib/registery.d.mts +47 -14
- package/dist/src/modules/commands/lib/registery.mjs +76 -16
- package/dist/src/modules/commands/lib/utils.d.mts +11 -0
- package/dist/src/modules/commands/lib/utils.mjs +14 -0
- package/dist/src/modules/data-tables/components/footer.mjs +3 -0
- package/dist/src/modules/data-tables/hooks/use-context.client.d.mts +2 -2
- package/dist/src/modules/data-tables/lib/types.d.mts +3 -3
- package/dist/src/modules/data-tables/strategies/local/components.mjs +25 -0
- package/dist/src/modules/data-tables/strategies/local/strategy.d.mts +12 -0
- package/dist/src/modules/data-tables/strategies/local/strategy.mjs +31 -0
- package/dist/src/modules/inline/components/inputs/combobox-dropdown.client.d.mts +4 -3
- package/dist/src/modules/inline/components/inputs/combobox.client.d.mts +4 -3
- package/dist/src/modules/inline/components/inputs/date-time.client.d.mts +4 -3
- package/dist/src/modules/inline/components/inputs/editor.client.d.mts +4 -3
- package/dist/src/modules/inline/components/inputs/input.client.d.mts +7 -5
- package/dist/src/modules/inline/components/inputs/select.client.d.mts +4 -3
- package/dist/src/modules/inline/components/inputs/switch.client.d.mts +4 -3
- package/dist/src/modules/router/lib/query-client.d.mts +2 -1
- package/dist/src/modules/router/lib/query-client.mjs +2 -2
- package/package.json +1 -1
- package/src/components/editor/lib/helpers.ts +8 -0
- package/src/components/entry.client.ts +1 -1
- package/src/components/entry.ts +1 -1
- package/src/components/layouts/root-layout.server.tsx +4 -2
- package/src/components/themes/color-theme-provider.client.tsx +82 -0
- package/src/components/themes/color-theme.ts +32 -0
- package/src/modules/commands/components/menus/context-menu.client.tsx +11 -11
- package/src/modules/commands/components/menus/dropdown-menu.client.tsx +9 -10
- package/src/modules/commands/components/menus/floating-menu.client.tsx +9 -10
- package/src/modules/commands/components/menus/inline-menu.client.tsx +9 -10
- package/src/modules/commands/components/menus/responsive-menu.client.tsx +7 -8
- package/src/modules/commands/components/render-command.tsx +17 -13
- package/src/modules/commands/entry.ts +1 -0
- package/src/modules/commands/lib/builder.ts +216 -36
- package/src/modules/commands/lib/registery.ts +210 -47
- package/src/modules/commands/lib/utils.ts +10 -0
- package/src/modules/data-tables/components/footer.tsx +9 -0
- package/src/modules/data-tables/entry.client.ts +1 -0
- package/src/modules/data-tables/hooks/use-context.client.tsx +2 -2
- package/src/modules/data-tables/lib/types.ts +3 -3
- package/src/modules/data-tables/strategies/local/components.tsx +17 -0
- package/src/modules/data-tables/strategies/local/strategy.ts +33 -0
- package/src/modules/inline/components/inputs/combobox-dropdown.client.tsx +11 -5
- package/src/modules/inline/components/inputs/combobox.client.tsx +11 -5
- package/src/modules/inline/components/inputs/date-time.client.tsx +11 -5
- package/src/modules/inline/components/inputs/editor.client.tsx +11 -5
- package/src/modules/inline/components/inputs/input.client.tsx +21 -9
- package/src/modules/inline/components/inputs/select.client.tsx +11 -5
- package/src/modules/inline/components/inputs/switch.client.tsx +11 -5
- package/src/modules/router/entry.ts +1 -0
- package/src/modules/router/lib/query-client.ts +2 -2
- package/src/styles.css +317 -2
|
@@ -1,39 +1,99 @@
|
|
|
1
1
|
//#region src/modules/commands/lib/registery.ts
|
|
2
|
-
function
|
|
2
|
+
function resolveKeys(input) {
|
|
3
3
|
if (Array.isArray(input)) return [...input];
|
|
4
4
|
return Object.entries(input).filter(([, enabled]) => enabled === true).map(([key]) => key);
|
|
5
5
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
function dedupe(tags) {
|
|
7
|
+
return [...new Set(tags)];
|
|
8
|
+
}
|
|
9
|
+
function hasEveryTag(command, tags) {
|
|
10
|
+
return tags.every((tag) => command.tags.includes(tag));
|
|
11
|
+
}
|
|
12
|
+
function hasSomeTag(command, tags) {
|
|
13
|
+
return tags.some((tag) => command.tags.includes(tag));
|
|
14
|
+
}
|
|
15
|
+
function hasExactTags(command, tags) {
|
|
16
|
+
const ctags = dedupe(command.tags);
|
|
17
|
+
const ftags = dedupe(tags);
|
|
18
|
+
return ctags.length === ftags.length && ftags.every((t) => ctags.includes(t));
|
|
19
|
+
}
|
|
20
|
+
function injectIds(commands) {
|
|
21
|
+
return Object.fromEntries(Object.entries(commands).map(([id, c]) => [id, {
|
|
22
|
+
...c,
|
|
23
|
+
id
|
|
24
|
+
}]));
|
|
25
|
+
}
|
|
26
|
+
function pickCommands(commands, input) {
|
|
27
|
+
const keys = resolveKeys(input);
|
|
28
|
+
return Object.fromEntries(keys.filter((k) => k in commands).map((k) => [k, commands[k]]));
|
|
29
|
+
}
|
|
30
|
+
function omitCommands(commands, input) {
|
|
31
|
+
const keys = new Set(resolveKeys(input));
|
|
32
|
+
return Object.fromEntries(Object.entries(commands).filter(([k]) => !keys.has(k)));
|
|
33
|
+
}
|
|
34
|
+
function createTagFilterRegistry(commands) {
|
|
35
|
+
function apply(predicate) {
|
|
36
|
+
return (...tags) => {
|
|
37
|
+
return createTagFilterRegistry(commands.filter((c) => predicate(c, tags)));
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
every: apply(hasEveryTag),
|
|
42
|
+
some: apply(hasSomeTag),
|
|
43
|
+
exact: apply(hasExactTags),
|
|
44
|
+
without: apply((c, ts) => !hasSomeTag(c, ts)),
|
|
45
|
+
toArray() {
|
|
46
|
+
return commands;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function createKeyFilterRegistry(commands) {
|
|
51
|
+
return {
|
|
52
|
+
pick(input) {
|
|
53
|
+
return createKeyFilterRegistry(pickCommands(commands, input));
|
|
54
|
+
},
|
|
55
|
+
omit(input) {
|
|
56
|
+
return createKeyFilterRegistry(omitCommands(commands, input));
|
|
57
|
+
},
|
|
58
|
+
toArray() {
|
|
59
|
+
return Object.values(commands);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
9
63
|
function createRegistry(commands) {
|
|
64
|
+
const withIds = injectIds(commands);
|
|
10
65
|
return {
|
|
11
|
-
commands,
|
|
66
|
+
commands: withIds,
|
|
67
|
+
keys: createKeyFilterRegistry(withIds),
|
|
68
|
+
tags: createTagFilterRegistry(Object.values(withIds)),
|
|
12
69
|
extend(extension) {
|
|
13
70
|
return createRegistry({
|
|
14
|
-
...
|
|
71
|
+
...withIds,
|
|
15
72
|
...extension
|
|
16
73
|
});
|
|
17
74
|
},
|
|
18
75
|
pick(input) {
|
|
19
|
-
|
|
20
|
-
return createRegistry(Object.fromEntries(keys.flatMap((key) => key in commands ? [[key, commands[key]]] : [])));
|
|
76
|
+
return createRegistry(pickCommands(withIds, input));
|
|
21
77
|
},
|
|
22
78
|
omit(input) {
|
|
23
|
-
|
|
24
|
-
const blacklist = new Set(keys);
|
|
25
|
-
return createRegistry(Object.fromEntries(Object.entries(commands).filter(([key]) => !blacklist.has(key))));
|
|
79
|
+
return createRegistry(omitCommands(withIds, input));
|
|
26
80
|
},
|
|
27
81
|
toArray() {
|
|
28
|
-
return Object.values(
|
|
82
|
+
return Object.values(withIds);
|
|
29
83
|
}
|
|
30
84
|
};
|
|
31
85
|
}
|
|
32
86
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
87
|
+
* Define commands from a map of name → `CommandDef`.
|
|
88
|
+
*
|
|
89
|
+
* Returns a `CommandRegistry` with key-based and tag-based filtering, plus
|
|
90
|
+
* `extend` for composition. Filter chains are immutable — each call produces
|
|
91
|
+
* a new registry.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* const registry = defineCommands({ edit, delete, archive });
|
|
95
|
+
* registry.tags.every("danger", "table").toArray();
|
|
96
|
+
* registry.keys.omit({ delete: true }).toArray();
|
|
37
97
|
*/
|
|
38
98
|
function defineCommands(commands) {
|
|
39
99
|
return createRegistry(commands);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/modules/commands/lib/utils.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes command data into an array.
|
|
4
|
+
*
|
|
5
|
+
* Use this as a command transform when the same command should support both
|
|
6
|
+
* single-item and bulk contexts. After `.transform(ensureArray)`, command
|
|
7
|
+
* callbacks can safely use array helpers like `.map` and `.every`.
|
|
8
|
+
*/
|
|
9
|
+
declare function ensureArray<T>(data: T | T[]): T[];
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ensureArray };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/modules/commands/lib/utils.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes command data into an array.
|
|
4
|
+
*
|
|
5
|
+
* Use this as a command transform when the same command should support both
|
|
6
|
+
* single-item and bulk contexts. After `.transform(ensureArray)`, command
|
|
7
|
+
* callbacks can safely use array helpers like `.map` and `.every`.
|
|
8
|
+
*/
|
|
9
|
+
function ensureArray(data) {
|
|
10
|
+
return Array.isArray(data) ? data : [data];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ensureArray };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { InfinteTableBottombar, InfinteTableFooter } from "../strategies/infinite/components.mjs";
|
|
4
|
+
import { LocalTableFooter } from "../strategies/local/components.mjs";
|
|
4
5
|
import { PaginationTableFooter } from "../strategies/pagination/components.mjs";
|
|
5
6
|
import { jsx } from "react/jsx-runtime";
|
|
6
7
|
|
|
@@ -12,6 +13,7 @@ function TableFooter({ table }) {
|
|
|
12
13
|
const meta = table.options.meta;
|
|
13
14
|
if (meta.strategy.name === "pagination") return null;
|
|
14
15
|
if (meta.strategy.name === "infinite") return /* @__PURE__ */ jsx(InfinteTableFooter, { table });
|
|
16
|
+
if (meta.strategy.name === "local") return null;
|
|
15
17
|
throw new Error(`Unknown strategy: ${meta.strategy.name}`);
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
@@ -21,6 +23,7 @@ function TableBottombar({ table }) {
|
|
|
21
23
|
const meta = table.options.meta;
|
|
22
24
|
if (meta.strategy.name === "pagination") return /* @__PURE__ */ jsx(PaginationTableFooter, { table });
|
|
23
25
|
if (meta.strategy.name === "infinite") return /* @__PURE__ */ jsx(InfinteTableBottombar, { table });
|
|
26
|
+
if (meta.strategy.name === "local") return /* @__PURE__ */ jsx(LocalTableFooter, { table });
|
|
24
27
|
throw new Error(`Unknown strategy: ${meta.strategy.name}`);
|
|
25
28
|
}
|
|
26
29
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommandFor } from "../../commands/lib/builder.mjs";
|
|
2
2
|
import { TableFiltersResult } from "../lib/filters/config.mjs";
|
|
3
3
|
import { Selection, TableColumnDef, TableMetaInput, TableStrategy } from "../lib/types.mjs";
|
|
4
4
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
@@ -21,7 +21,7 @@ type TableConfigContextValue<TData, TFilters extends TableFiltersResult = TableF
|
|
|
21
21
|
strategy: TableStrategy;
|
|
22
22
|
selection?: Selection;
|
|
23
23
|
columnVisibility?: VisibilityState;
|
|
24
|
-
commands?:
|
|
24
|
+
commands?: CommandFor<TData[], TMeta>[];
|
|
25
25
|
meta?: TMeta;
|
|
26
26
|
where?: TFilters;
|
|
27
27
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Permission } from "../../auth/lib/permissions.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { CommandFor } from "../../commands/lib/builder.mjs";
|
|
3
3
|
import { UseQueryStatesKeysMap } from "nuqs";
|
|
4
4
|
import { ColumnDef, PaginationState, RowSelectionState, SortingState, TableMeta, Updater } from "@tanstack/react-table";
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ type TableMetaInput<TData> = TableMeta<TData>;
|
|
|
11
11
|
type TableMeta$1<TData, TMeta = TableMetaInput<TData>> = {
|
|
12
12
|
strategy: TableStrategy;
|
|
13
13
|
selectedData: TData[];
|
|
14
|
-
commands?:
|
|
14
|
+
commands?: CommandFor<TData[], TMeta>[];
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
17
|
* Table column definition
|
|
@@ -24,7 +24,7 @@ type TableColumnDef<TData> = ColumnDef<TData> & {
|
|
|
24
24
|
* Data table strategy
|
|
25
25
|
*/
|
|
26
26
|
type TableStrategy = {
|
|
27
|
-
name: "pagination" | "infinite";
|
|
27
|
+
name: "pagination" | "infinite" | "local";
|
|
28
28
|
rowCount?: number;
|
|
29
29
|
paginationState?: PaginationState;
|
|
30
30
|
manualPagination?: boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/modules/data-tables/strategies/local/components.tsx
|
|
6
|
+
function LocalTableFooter({ table }) {
|
|
7
|
+
const selected = Object.keys(table.getState().rowSelection).length;
|
|
8
|
+
const total = table.getRowCount();
|
|
9
|
+
return /* @__PURE__ */ jsx("div", {
|
|
10
|
+
className: "flex flex-col gap-y-2 px-2 md:flex-row md:items-center md:justify-between",
|
|
11
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
12
|
+
className: "text-muted-foreground text-sm",
|
|
13
|
+
children: [
|
|
14
|
+
selected ?? table.getFilteredSelectedRowModel().rows.length,
|
|
15
|
+
" of",
|
|
16
|
+
" ",
|
|
17
|
+
total ?? table.getRowModel().rows.length,
|
|
18
|
+
" row(s) selected."
|
|
19
|
+
]
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
export { LocalTableFooter };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TableStrategy } from "../../lib/types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/modules/data-tables/strategies/local/strategy.d.ts
|
|
4
|
+
type UseLocalStrategyInput = {
|
|
5
|
+
total?: number;
|
|
6
|
+
};
|
|
7
|
+
type LocalStrategy = typeof useLocalStrategy;
|
|
8
|
+
declare function useLocalStrategy({
|
|
9
|
+
total
|
|
10
|
+
}?: UseLocalStrategyInput): TableStrategy;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { LocalStrategy, UseLocalStrategyInput, useLocalStrategy };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { tableSearchParams } from "../../lib/search-params.mjs";
|
|
4
|
+
import { handleSortingChange } from "../helpers/sorting.mjs";
|
|
5
|
+
import { useQueryStates } from "nuqs";
|
|
6
|
+
|
|
7
|
+
//#region src/modules/data-tables/strategies/local/strategy.ts
|
|
8
|
+
function useLocalStrategy({ total } = {}) {
|
|
9
|
+
const [query, setQuery] = useQueryStates(tableSearchParams);
|
|
10
|
+
const sortingState = query.sort ? [{
|
|
11
|
+
id: query.sort,
|
|
12
|
+
desc: query.order === "desc"
|
|
13
|
+
}] : [];
|
|
14
|
+
const resetCursor = () => null;
|
|
15
|
+
return {
|
|
16
|
+
name: "local",
|
|
17
|
+
rowCount: total,
|
|
18
|
+
resetCursor,
|
|
19
|
+
tableSearchParams,
|
|
20
|
+
sortingState,
|
|
21
|
+
manualSorting: true,
|
|
22
|
+
onSortingChange: handleSortingChange({
|
|
23
|
+
sortingState,
|
|
24
|
+
setQuery,
|
|
25
|
+
resetCursor
|
|
26
|
+
})
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { useLocalStrategy };
|
|
@@ -7,10 +7,11 @@ import { DefaultError } from "@tanstack/react-query";
|
|
|
7
7
|
|
|
8
8
|
//#region src/modules/inline/components/inputs/combobox-dropdown.client.d.ts
|
|
9
9
|
type ComboboxDropdownInlineTrigger = "commit";
|
|
10
|
-
type
|
|
10
|
+
type InlineStringSchema = z$1.ZodType<string | null, string | null> | z$1.ZodType<string, string>;
|
|
11
|
+
type InlineEditComboboxDropdownProps<TValue extends ComboboxDropdownItem, TSchema extends InlineStringSchema = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown> = useInlineEditOptions<ComboboxDropdownInlineTrigger, TSchema, TData, TError, TVariables, TOnMutateResult> & InlineEditVariantsProps & Omit<ComboboxDropdownProps<TValue>, "onSelect"> & {
|
|
11
12
|
onSelect?: ComboboxDropdownProps<TValue>["onSelect"];
|
|
12
13
|
};
|
|
13
|
-
declare function InlineComboboxDropdown<TValue extends ComboboxDropdownItem, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
14
|
+
declare function InlineComboboxDropdown<TValue extends ComboboxDropdownItem, TSchema extends InlineStringSchema = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
14
15
|
selectedItem,
|
|
15
16
|
variant,
|
|
16
17
|
className,
|
|
@@ -22,6 +23,6 @@ declare function InlineComboboxDropdown<TValue extends ComboboxDropdownItem, TDa
|
|
|
22
23
|
strategy,
|
|
23
24
|
disabled,
|
|
24
25
|
...props
|
|
25
|
-
}: InlineEditComboboxDropdownProps<TValue, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
26
|
+
}: InlineEditComboboxDropdownProps<TValue, TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
26
27
|
//#endregion
|
|
27
28
|
export { InlineComboboxDropdown, InlineEditComboboxDropdownProps };
|
|
@@ -6,8 +6,9 @@ import { DefaultError } from "@tanstack/react-query";
|
|
|
6
6
|
|
|
7
7
|
//#region src/modules/inline/components/inputs/combobox.client.d.ts
|
|
8
8
|
type ComboboxInlineTrigger = "commit";
|
|
9
|
-
type
|
|
10
|
-
|
|
9
|
+
type InlineStringSchema = z$1.ZodType<string | null, string | null> | z$1.ZodType<string, string>;
|
|
10
|
+
type InlineComboboxProps<TValue, TSchema extends InlineStringSchema = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown> = useInlineEditOptions<ComboboxInlineTrigger, TSchema, TData, TError, TVariables, TOnMutateResult> & Omit<ComboboxProps<TValue>, "value">;
|
|
11
|
+
declare function InlineCombobox<TValue, TSchema extends InlineStringSchema = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
11
12
|
initialValue,
|
|
12
13
|
variables,
|
|
13
14
|
mutation,
|
|
@@ -17,6 +18,6 @@ declare function InlineCombobox<TValue, TData = unknown, TError = DefaultError,
|
|
|
17
18
|
disabled,
|
|
18
19
|
strategy,
|
|
19
20
|
...props
|
|
20
|
-
}: InlineComboboxProps<TValue, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
21
|
+
}: InlineComboboxProps<TValue, TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
21
22
|
//#endregion
|
|
22
23
|
export { InlineCombobox, InlineComboboxProps };
|
|
@@ -8,8 +8,9 @@ import { DefaultError } from "@tanstack/react-query";
|
|
|
8
8
|
|
|
9
9
|
//#region src/modules/inline/components/inputs/date-time.client.d.ts
|
|
10
10
|
type DateTimeInlineTrigger = "change" | "blur";
|
|
11
|
-
type
|
|
12
|
-
|
|
11
|
+
type InlineDateTimeSchema = z$1.ZodType<Date | null, Date | null> | z$1.ZodType<Date, Date>;
|
|
12
|
+
type InlineDateTimeInputProps<TSchema extends InlineDateTimeSchema = z$1.ZodType<Date | null, Date | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown> = ComponentProps<typeof DateTimeInput> & useInlineEditOptions<DateTimeInlineTrigger, TSchema, TData, TError, TVariables, TOnMutateResult> & InlineEditVariantsProps;
|
|
13
|
+
declare function InlineDateTimeInput<TSchema extends InlineDateTimeSchema = z$1.ZodType<Date | null, Date | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
13
14
|
initialValue,
|
|
14
15
|
variables,
|
|
15
16
|
mutation,
|
|
@@ -19,6 +20,6 @@ declare function InlineDateTimeInput<TData = unknown, TError = DefaultError, TVa
|
|
|
19
20
|
strategy,
|
|
20
21
|
disabled,
|
|
21
22
|
...props
|
|
22
|
-
}: InlineDateTimeInputProps<TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
23
|
+
}: InlineDateTimeInputProps<TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
23
24
|
//#endregion
|
|
24
25
|
export { InlineDateTimeInput };
|
|
@@ -8,8 +8,9 @@ import { DefaultError } from "@tanstack/react-query";
|
|
|
8
8
|
|
|
9
9
|
//#region src/modules/inline/components/inputs/editor.client.d.ts
|
|
10
10
|
type EditorInlineTrigger = "change" | "blur";
|
|
11
|
-
type
|
|
12
|
-
|
|
11
|
+
type InlineEditorSchema = z$1.ZodType<EditorJSONContent | null, EditorJSONContent | null> | z$1.ZodType<EditorJSONContent, EditorJSONContent>;
|
|
12
|
+
type InlineEditorProps<TSchema extends InlineEditorSchema = z$1.ZodType<EditorJSONContent | null, EditorJSONContent | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown> = useInlineEditOptions<EditorInlineTrigger, TSchema, TData, TError, TVariables, TOnMutateResult> & InlineEditVariantsProps & Omit<EditorProps, "value" | "onUpdate" | "onBlur" | "variant">;
|
|
13
|
+
declare function InlineEditor<TSchema extends InlineEditorSchema = z$1.ZodType<EditorJSONContent | null, EditorJSONContent | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
13
14
|
initialValue,
|
|
14
15
|
variables,
|
|
15
16
|
mutation,
|
|
@@ -20,6 +21,6 @@ declare function InlineEditor<TData = unknown, TError = DefaultError, TVariables
|
|
|
20
21
|
strategy,
|
|
21
22
|
className,
|
|
22
23
|
children
|
|
23
|
-
}: InlineEditorProps<TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
24
|
+
}: InlineEditorProps<TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
24
25
|
//#endregion
|
|
25
26
|
export { InlineEditor, InlineEditorProps };
|
|
@@ -8,11 +8,13 @@ import { DefaultError } from "@tanstack/react-query";
|
|
|
8
8
|
|
|
9
9
|
//#region src/modules/inline/components/inputs/input.client.d.ts
|
|
10
10
|
type InputInlineTrigger = "change" | "blur";
|
|
11
|
+
type InlineStringSchema = z$1.ZodType<string | null, string | null> | z$1.ZodType<string, string>;
|
|
12
|
+
type InlineNumberSchema = z$1.ZodType<number | null, number | null> | z$1.ZodType<number, number>;
|
|
11
13
|
type InlineEditInputProps<TSchema extends z$1.ZodType, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown> = Omit<ComponentProps<typeof Input>, "type"> & useInlineEditOptions<InputInlineTrigger, TSchema, TData, TError, TVariables, TOnMutateResult> & InlineEditVariantsProps;
|
|
12
14
|
/**
|
|
13
15
|
* The inline edit string input component.
|
|
14
16
|
*/
|
|
15
|
-
declare function InlineStringInput<TSchema extends z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
17
|
+
declare function InlineStringInput<TSchema extends InlineStringSchema = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
16
18
|
initialValue,
|
|
17
19
|
variables,
|
|
18
20
|
mutation,
|
|
@@ -23,7 +25,7 @@ declare function InlineStringInput<TSchema extends z$1.ZodType<string | null, st
|
|
|
23
25
|
disabled,
|
|
24
26
|
...props
|
|
25
27
|
}: InlineEditInputProps<TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
26
|
-
declare function InlineNumberInput<TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
28
|
+
declare function InlineNumberInput<TSchema extends InlineNumberSchema = z$1.ZodType<number | null, number | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
27
29
|
initialValue,
|
|
28
30
|
variables,
|
|
29
31
|
mutation,
|
|
@@ -33,11 +35,11 @@ declare function InlineNumberInput<TData = unknown, TError = DefaultError, TVari
|
|
|
33
35
|
strategy,
|
|
34
36
|
disabled,
|
|
35
37
|
...props
|
|
36
|
-
}: InlineEditInputProps<
|
|
38
|
+
}: InlineEditInputProps<TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
37
39
|
/**
|
|
38
40
|
* The inline edit decimal input component.
|
|
39
41
|
*/
|
|
40
|
-
declare function InlineDecimalInput<TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
42
|
+
declare function InlineDecimalInput<TSchema extends z$1.ZodType<string | null, string | null> | z$1.ZodType<string, string> = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
41
43
|
initialValue,
|
|
42
44
|
variables,
|
|
43
45
|
mutation,
|
|
@@ -47,6 +49,6 @@ declare function InlineDecimalInput<TData = unknown, TError = DefaultError, TVar
|
|
|
47
49
|
strategy,
|
|
48
50
|
disabled,
|
|
49
51
|
...props
|
|
50
|
-
}: InlineEditInputProps<
|
|
52
|
+
}: InlineEditInputProps<TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
51
53
|
//#endregion
|
|
52
54
|
export { InlineDecimalInput, InlineNumberInput, InlineStringInput };
|
|
@@ -8,8 +8,9 @@ import { DefaultError } from "@tanstack/react-query";
|
|
|
8
8
|
|
|
9
9
|
//#region src/modules/inline/components/inputs/select.client.d.ts
|
|
10
10
|
type SelectInlineTrigger = "commit";
|
|
11
|
-
type
|
|
12
|
-
|
|
11
|
+
type InlineStringSchema = z$1.ZodType<string | null, string | null> | z$1.ZodType<string, string>;
|
|
12
|
+
type InlineSelectProps<TSchema extends InlineStringSchema = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown> = Omit<ComponentProps<typeof Select>, "value" | "defaultValue"> & useInlineEditOptions<SelectInlineTrigger, TSchema, TData, TError, TVariables, TOnMutateResult>;
|
|
13
|
+
declare function InlineSelect<TSchema extends InlineStringSchema = z$1.ZodType<string | null, string | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
13
14
|
initialValue,
|
|
14
15
|
variables,
|
|
15
16
|
mutation,
|
|
@@ -18,7 +19,7 @@ declare function InlineSelect<TData = unknown, TError = DefaultError, TVariables
|
|
|
18
19
|
disabled,
|
|
19
20
|
onValueChange,
|
|
20
21
|
...props
|
|
21
|
-
}: InlineSelectProps<TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
22
|
+
}: InlineSelectProps<TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
22
23
|
declare function InlineSelectTrigger({
|
|
23
24
|
variant,
|
|
24
25
|
className,
|
|
@@ -7,8 +7,9 @@ import { DefaultError } from "@tanstack/react-query";
|
|
|
7
7
|
|
|
8
8
|
//#region src/modules/inline/components/inputs/switch.client.d.ts
|
|
9
9
|
type SwitchInlineTrigger = "commit";
|
|
10
|
-
type
|
|
11
|
-
|
|
10
|
+
type InlineBooleanSchema = z$1.ZodType<boolean | null, boolean | null> | z$1.ZodType<boolean, boolean>;
|
|
11
|
+
type InlineSwitchProps<TSchema extends InlineBooleanSchema = z$1.ZodType<boolean | null, boolean | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown> = ComponentProps<typeof Switch> & useInlineEditOptions<SwitchInlineTrigger, TSchema, TData, TError, TVariables, TOnMutateResult>;
|
|
12
|
+
declare function InlineSwitch<TSchema extends InlineBooleanSchema = z$1.ZodType<boolean | null, boolean | null>, TData = unknown, TError = DefaultError, TVariables = unknown, TOnMutateResult = unknown>({
|
|
12
13
|
initialValue,
|
|
13
14
|
variables,
|
|
14
15
|
mutation,
|
|
@@ -16,6 +17,6 @@ declare function InlineSwitch<TData = unknown, TError = DefaultError, TVariables
|
|
|
16
17
|
strategy,
|
|
17
18
|
disabled,
|
|
18
19
|
...props
|
|
19
|
-
}: InlineSwitchProps<TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
20
|
+
}: InlineSwitchProps<TSchema, TData, TError, TVariables, TOnMutateResult>): react_jsx_runtime0.JSX.Element;
|
|
20
21
|
//#endregion
|
|
21
22
|
export { InlineSwitch };
|
|
@@ -5,5 +5,6 @@ import { QueryClient } from "@tanstack/react-query";
|
|
|
5
5
|
* Create a new query client
|
|
6
6
|
*/
|
|
7
7
|
declare function createQueryClient(): QueryClient;
|
|
8
|
+
declare function getQueryClient(): QueryClient;
|
|
8
9
|
//#endregion
|
|
9
|
-
export { createQueryClient };
|
|
10
|
+
export { createQueryClient, getQueryClient };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { serializer } from "./helpers.mjs";
|
|
2
|
-
import { MutationCache, QueryClient,
|
|
2
|
+
import { MutationCache, QueryClient, environmentManager } from "@tanstack/react-query";
|
|
3
3
|
|
|
4
4
|
//#region src/modules/router/lib/query-client.ts
|
|
5
5
|
/**
|
|
@@ -41,7 +41,7 @@ function createQueryClient() {
|
|
|
41
41
|
*/
|
|
42
42
|
let browserQueryClient;
|
|
43
43
|
function getQueryClient() {
|
|
44
|
-
if (isServer) return createQueryClient();
|
|
44
|
+
if (environmentManager.isServer()) return createQueryClient();
|
|
45
45
|
if (!browserQueryClient) browserQueryClient = createQueryClient();
|
|
46
46
|
return browserQueryClient;
|
|
47
47
|
}
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateText } from "@tiptap/core";
|
|
1
2
|
import Blockquote from "@tiptap/extension-blockquote";
|
|
2
3
|
import Bold from "@tiptap/extension-bold";
|
|
3
4
|
import Document from "@tiptap/extension-document";
|
|
@@ -68,3 +69,10 @@ export function convertEditorContentToMarkdown(content: EditorJSONContent): stri
|
|
|
68
69
|
extensions: EXTENSIONS_FOR_GENERATION,
|
|
69
70
|
});
|
|
70
71
|
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Convert editor content to plain text
|
|
75
|
+
*/
|
|
76
|
+
export function convertEditorContentToPlainText(content: EditorJSONContent): string {
|
|
77
|
+
return generateText(content, EXTENSIONS_FOR_GENERATION);
|
|
78
|
+
}
|
|
@@ -20,11 +20,11 @@ export * from "./header/top-bar.client";
|
|
|
20
20
|
*/
|
|
21
21
|
export * from "./layouts/admin-content.client";
|
|
22
22
|
export * from "./layouts/providers.client";
|
|
23
|
-
|
|
24
23
|
/**
|
|
25
24
|
* Components Navigation
|
|
26
25
|
*/
|
|
27
26
|
export * from "./navigation/admin-sidebar-paths.client";
|
|
27
|
+
export * from "./themes/color-theme-provider.client";
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Components UI
|
package/src/components/entry.ts
CHANGED
|
@@ -19,12 +19,12 @@ export * from "./layouts/list-layout";
|
|
|
19
19
|
export * from "./layouts/root-error-pages";
|
|
20
20
|
export * from "./layouts/root-loading";
|
|
21
21
|
export * from "./layouts/tab-layout";
|
|
22
|
-
|
|
23
22
|
/**
|
|
24
23
|
* Components Lists
|
|
25
24
|
*/
|
|
26
25
|
export * from "./lists/data-list";
|
|
27
26
|
export * from "./lists/data-stack";
|
|
27
|
+
export * from "./themes/color-theme";
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Components UI
|
|
@@ -38,9 +38,11 @@ export const generateRootLayoutMetadata = (config: TulipConfig) => ({
|
|
|
38
38
|
/**
|
|
39
39
|
* Root layout
|
|
40
40
|
*/
|
|
41
|
-
export
|
|
41
|
+
export type RootLayoutProps = PropsWithChildren;
|
|
42
|
+
|
|
43
|
+
export function RootLayout({ children }: RootLayoutProps) {
|
|
42
44
|
return (
|
|
43
|
-
<html lang="nl">
|
|
45
|
+
<html lang="nl" data-theme="tulip">
|
|
44
46
|
<body className={cn("bg-background font-sans antialiased", registerFonts())}>{children}</body>
|
|
45
47
|
</html>
|
|
46
48
|
);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { PropsWithChildren } from "react";
|
|
4
|
+
import {
|
|
5
|
+
createContext,
|
|
6
|
+
use,
|
|
7
|
+
useCallback,
|
|
8
|
+
useEffect,
|
|
9
|
+
useLayoutEffect,
|
|
10
|
+
useMemo,
|
|
11
|
+
useState,
|
|
12
|
+
} from "react";
|
|
13
|
+
import { COLOR_THEME_STORAGE_KEY, type ColorTheme, colorThemes } from "./color-theme";
|
|
14
|
+
|
|
15
|
+
type ColorThemeContextValue = {
|
|
16
|
+
colorTheme: ColorTheme;
|
|
17
|
+
setColorTheme: (theme: ColorTheme) => void;
|
|
18
|
+
colorThemes: readonly ColorTheme[];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const ColorThemeContext = createContext<ColorThemeContextValue | null>(null);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Persists the chosen theme in a cookie so the server can resolve it on the next request.
|
|
25
|
+
* Cookie failures are ignored because theme changes should still work in local React state.
|
|
26
|
+
*/
|
|
27
|
+
function setStoredColorTheme(theme: ColorTheme) {
|
|
28
|
+
try {
|
|
29
|
+
// biome-ignore lint/suspicious/noDocumentCookie: client theme changes need to persist for the next server render
|
|
30
|
+
document.cookie = `${COLOR_THEME_STORAGE_KEY}=${theme}; path=/; max-age=31536000; samesite=lax`;
|
|
31
|
+
} catch {
|
|
32
|
+
// Ignore cookie failures.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Provides the current color theme and a setter to the component tree.
|
|
38
|
+
* The server provides the initial theme, then client interactions keep local state and the cookie in sync.
|
|
39
|
+
*/
|
|
40
|
+
export function ColorThemeProvider({ children, theme }: PropsWithChildren<{ theme: ColorTheme }>) {
|
|
41
|
+
const [colorTheme, setColorThemeState] = useState(theme);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
setColorThemeState(theme);
|
|
45
|
+
}, [theme]);
|
|
46
|
+
|
|
47
|
+
useLayoutEffect(() => {
|
|
48
|
+
document.documentElement.dataset.theme = colorTheme;
|
|
49
|
+
}, [colorTheme]);
|
|
50
|
+
|
|
51
|
+
const setColorTheme = useCallback((theme: ColorTheme) => {
|
|
52
|
+
setColorThemeState(theme);
|
|
53
|
+
setStoredColorTheme(theme);
|
|
54
|
+
}, []);
|
|
55
|
+
|
|
56
|
+
const value = useMemo(
|
|
57
|
+
() => ({ colorTheme, setColorTheme, colorThemes }),
|
|
58
|
+
[colorTheme, setColorTheme],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<ColorThemeContext.Provider value={value}>
|
|
63
|
+
<div className="contents" data-theme={colorTheme}>
|
|
64
|
+
{children}
|
|
65
|
+
</div>
|
|
66
|
+
</ColorThemeContext.Provider>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Returns the active color theme context for client components.
|
|
72
|
+
* It throws early when used outside the provider so incorrect usage fails loudly.
|
|
73
|
+
*/
|
|
74
|
+
export function useColorTheme() {
|
|
75
|
+
const context = use(ColorThemeContext);
|
|
76
|
+
|
|
77
|
+
if (!context) {
|
|
78
|
+
throw new Error("useColorTheme must be used within a ColorThemeProvider");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return context;
|
|
82
|
+
}
|