@askrjs/themes 0.0.19 → 0.0.21
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/README.md +24 -3
- package/THEMING.md +11 -4
- package/dist/components/_internal/block-layout.js +1 -1
- package/dist/components/_internal/block-layout.js.map +1 -1
- package/dist/components/_internal/style.js +9 -21
- package/dist/components/_internal/style.js.map +1 -1
- package/dist/components/grid/grid.js +5 -42
- package/dist/components/grid/grid.js.map +1 -1
- package/dist/components/jsx-types.d.ts +0 -3
- package/dist/components/theme/theme.js +11 -12
- package/dist/components/theme/theme.js.map +1 -1
- package/dist/entries/accordion.d.ts +1 -0
- package/dist/entries/accordion.js +1 -0
- package/dist/entries/alert-dialog.d.ts +1 -0
- package/dist/entries/alert-dialog.js +1 -0
- package/dist/entries/alert.d.ts +4 -0
- package/dist/entries/alert.js +2 -0
- package/dist/entries/aspect-ratio.d.ts +4 -0
- package/dist/entries/aspect-ratio.js +2 -0
- package/dist/entries/avatar.d.ts +1 -0
- package/dist/entries/avatar.js +1 -0
- package/dist/entries/badge.d.ts +4 -0
- package/dist/entries/badge.js +2 -0
- package/dist/entries/breadcrumb.d.ts +2 -0
- package/dist/entries/breadcrumb.js +2 -0
- package/dist/entries/button-group.d.ts +4 -0
- package/dist/entries/button-group.js +2 -0
- package/dist/entries/button.d.ts +1 -0
- package/dist/entries/button.js +1 -0
- package/dist/entries/calendar.d.ts +2 -0
- package/dist/entries/calendar.js +2 -0
- package/dist/entries/card.d.ts +4 -0
- package/dist/entries/card.js +2 -0
- package/dist/entries/carousel.d.ts +2 -0
- package/dist/entries/carousel.js +2 -0
- package/dist/entries/checkbox.d.ts +1 -0
- package/dist/entries/checkbox.js +1 -0
- package/dist/entries/collapsible.d.ts +1 -0
- package/dist/entries/collapsible.js +1 -0
- package/dist/entries/combobox.d.ts +2 -0
- package/dist/entries/combobox.js +2 -0
- package/dist/entries/command.d.ts +2 -0
- package/dist/entries/command.js +2 -0
- package/dist/entries/context-menu.d.ts +3 -0
- package/dist/entries/context-menu.js +3 -0
- package/dist/entries/data-table.d.ts +2 -0
- package/dist/entries/data-table.js +2 -0
- package/dist/entries/date-picker.d.ts +2 -0
- package/dist/entries/date-picker.js +2 -0
- package/dist/entries/dialog.d.ts +1 -0
- package/dist/entries/dialog.js +1 -0
- package/dist/entries/direction.d.ts +2 -0
- package/dist/entries/direction.js +2 -0
- package/dist/entries/drawer.d.ts +2 -0
- package/dist/entries/drawer.js +2 -0
- package/dist/entries/dropdown-menu.d.ts +3 -0
- package/dist/entries/dropdown-menu.js +3 -0
- package/dist/entries/empty.d.ts +2 -0
- package/dist/entries/empty.js +2 -0
- package/dist/entries/field.d.ts +4 -0
- package/dist/entries/field.js +2 -0
- package/dist/entries/form.d.ts +1 -0
- package/dist/entries/form.js +1 -0
- package/dist/entries/hover-card.d.ts +1 -0
- package/dist/entries/hover-card.js +1 -0
- package/dist/entries/input-group.d.ts +4 -0
- package/dist/entries/input-group.js +2 -0
- package/dist/entries/input-otp.d.ts +2 -0
- package/dist/entries/input-otp.js +2 -0
- package/dist/entries/input.d.ts +1 -0
- package/dist/entries/input.js +1 -0
- package/dist/entries/item.d.ts +2 -0
- package/dist/entries/item.js +2 -0
- package/dist/entries/kbd.d.ts +2 -0
- package/dist/entries/kbd.js +2 -0
- package/dist/entries/label.d.ts +1 -0
- package/dist/entries/label.js +1 -0
- package/dist/entries/menubar.d.ts +1 -0
- package/dist/entries/menubar.js +1 -0
- package/dist/entries/native-select.d.ts +2 -0
- package/dist/entries/native-select.js +2 -0
- package/dist/entries/navigation-menu.d.ts +2 -0
- package/dist/entries/navigation-menu.js +2 -0
- package/dist/entries/pagination.d.ts +2 -0
- package/dist/entries/pagination.js +2 -0
- package/dist/entries/popover.d.ts +1 -0
- package/dist/entries/popover.js +1 -0
- package/dist/entries/progress.d.ts +1 -0
- package/dist/entries/progress.js +1 -0
- package/dist/entries/radio-group.d.ts +1 -0
- package/dist/entries/radio-group.js +1 -0
- package/dist/entries/resizable.d.ts +2 -0
- package/dist/entries/resizable.js +2 -0
- package/dist/entries/scroll-area.d.ts +1 -0
- package/dist/entries/scroll-area.js +1 -0
- package/dist/entries/select.d.ts +1 -0
- package/dist/entries/select.js +1 -0
- package/dist/entries/separator.d.ts +4 -0
- package/dist/entries/separator.js +2 -0
- package/dist/entries/sheet.d.ts +3 -0
- package/dist/entries/sheet.js +3 -0
- package/dist/entries/sidebar.d.ts +4 -0
- package/dist/entries/sidebar.js +2 -0
- package/dist/entries/skeleton.d.ts +4 -0
- package/dist/entries/skeleton.js +2 -0
- package/dist/entries/slider.d.ts +1 -0
- package/dist/entries/slider.js +1 -0
- package/dist/entries/sonner.d.ts +2 -0
- package/dist/entries/sonner.js +2 -0
- package/dist/entries/spinner.d.ts +4 -0
- package/dist/entries/spinner.js +2 -0
- package/dist/entries/switch.d.ts +1 -0
- package/dist/entries/switch.js +1 -0
- package/dist/entries/table.d.ts +1 -0
- package/dist/entries/table.js +1 -0
- package/dist/entries/tabs.d.ts +4 -0
- package/dist/entries/tabs.js +3 -0
- package/dist/entries/textarea.d.ts +1 -0
- package/dist/entries/textarea.js +1 -0
- package/dist/entries/toast.d.ts +1 -0
- package/dist/entries/toast.js +1 -0
- package/dist/entries/toggle-group.d.ts +1 -0
- package/dist/entries/toggle-group.js +1 -0
- package/dist/entries/toggle.d.ts +1 -0
- package/dist/entries/toggle.js +1 -0
- package/dist/entries/tooltip.d.ts +1 -0
- package/dist/entries/tooltip.js +1 -0
- package/dist/entries/typography.d.ts +2 -0
- package/dist/entries/typography.js +2 -0
- package/dist/ssr.js +23 -11
- package/dist/ssr.js.map +1 -1
- package/dist/themes/default/index.css +1 -1
- package/package.json +25 -240
- package/src/components/_internal/block-layout.ts +2 -2
- package/src/components/_internal/style.ts +8 -26
- package/src/components/grid/grid.tsx +6 -57
- package/src/components/jsx-types.ts +0 -5
- package/src/components/theme/theme.tsx +22 -22
- package/src/entries/accordion.ts +1 -0
- package/src/entries/alert-dialog.ts +1 -0
- package/src/entries/alert.ts +1 -0
- package/src/entries/aspect-ratio.ts +1 -0
- package/src/entries/avatar.ts +1 -0
- package/src/entries/badge.ts +1 -0
- package/src/entries/breadcrumb.ts +9 -0
- package/src/entries/button-group.ts +1 -0
- package/src/entries/button.ts +1 -0
- package/src/entries/calendar.ts +14 -0
- package/src/entries/card.ts +1 -0
- package/src/entries/carousel.ts +7 -0
- package/src/entries/checkbox.ts +1 -0
- package/src/entries/collapsible.ts +1 -0
- package/src/entries/combobox.ts +1 -0
- package/src/entries/command.ts +13 -0
- package/src/entries/context-menu.ts +10 -0
- package/src/entries/data-table.ts +1 -0
- package/src/entries/date-picker.ts +1 -0
- package/src/entries/dialog.ts +1 -0
- package/src/entries/direction.ts +1 -0
- package/src/entries/drawer.ts +10 -0
- package/src/entries/dropdown-menu.ts +10 -0
- package/src/entries/empty.ts +8 -0
- package/src/entries/field.ts +1 -0
- package/src/entries/form.ts +1 -0
- package/src/entries/hover-card.ts +1 -0
- package/src/entries/input-group.ts +1 -0
- package/src/entries/input-otp.ts +1 -0
- package/src/entries/input.ts +1 -0
- package/src/entries/item.ts +11 -0
- package/src/entries/kbd.ts +1 -0
- package/src/entries/label.ts +1 -0
- package/src/entries/menubar.ts +1 -0
- package/src/entries/native-select.ts +1 -0
- package/src/entries/navigation-menu.ts +10 -0
- package/src/entries/pagination.ts +9 -0
- package/src/entries/popover.ts +1 -0
- package/src/entries/progress.ts +1 -0
- package/src/entries/radio-group.ts +1 -0
- package/src/entries/resizable.ts +1 -0
- package/src/entries/scroll-area.ts +1 -0
- package/src/entries/select.ts +1 -0
- package/src/entries/separator.ts +1 -0
- package/src/entries/sheet.ts +14 -0
- package/src/entries/sidebar.ts +1 -0
- package/src/entries/skeleton.ts +1 -0
- package/src/entries/slider.ts +1 -0
- package/src/entries/sonner.ts +1 -0
- package/src/entries/spinner.ts +1 -0
- package/src/entries/switch.ts +1 -0
- package/src/entries/table.ts +1 -0
- package/src/entries/tabs.ts +2 -0
- package/src/entries/textarea.ts +1 -0
- package/src/entries/toast.ts +1 -0
- package/src/entries/toggle-group.ts +1 -0
- package/src/entries/toggle.ts +1 -0
- package/src/entries/tooltip.ts +1 -0
- package/src/entries/typography.ts +12 -0
- package/src/parity.ts +3 -3
- package/src/ssr.ts +45 -20
- package/src/themes/default/foundations.css +6 -0
- package/src/themes/default/tokens.css +1 -1
- package/templates/theme/tokens.css +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JSX } from "@askrjs/askr/jsx-runtime";
|
|
2
2
|
import { defineScope, getSignal, readScope, state } from "@askrjs/askr";
|
|
3
|
-
import type
|
|
3
|
+
import { cloneElement, isElement, type JSXElement } from "@askrjs/askr/foundations/structures";
|
|
4
4
|
import { Button } from "@askrjs/ui";
|
|
5
5
|
import type { ButtonNativeProps, PressEvent } from "@askrjs/ui";
|
|
6
6
|
|
|
@@ -67,7 +67,6 @@ export const CAT_THEME_OPTIONS: readonly ThemeOption[] = [
|
|
|
67
67
|
|
|
68
68
|
const DEFAULT_STORAGE_KEY = "askr-theme";
|
|
69
69
|
const STATIC_CHILDREN = Symbol.for("askr.static-children");
|
|
70
|
-
const STATIC_CHILD_SLOTS_CACHE = Symbol.for("__askrStaticChildSlots");
|
|
71
70
|
const documentThemeCoordinators = new WeakMap<Document, ThemeCoordinator>();
|
|
72
71
|
type ThemeCoordinator = ReturnType<typeof createThemeCoordinator>;
|
|
73
72
|
type InternalThemeScopeValue = ThemeScopeValue & {
|
|
@@ -198,6 +197,20 @@ function getDefaultThemeCoordinator(): ThemeCoordinator {
|
|
|
198
197
|
return coordinator;
|
|
199
198
|
}
|
|
200
199
|
|
|
200
|
+
function removeEmptyGeneratedStyleRegistries(root: Node | null): void {
|
|
201
|
+
const ownerDocument =
|
|
202
|
+
root?.nodeType === 9
|
|
203
|
+
? (root as Document)
|
|
204
|
+
: (root?.ownerDocument ?? (typeof document === "undefined" ? null : document));
|
|
205
|
+
if (!ownerDocument) return;
|
|
206
|
+
|
|
207
|
+
for (const registry of ownerDocument.querySelectorAll<HTMLStyleElement>(
|
|
208
|
+
"style[data-askr-style-registry]",
|
|
209
|
+
)) {
|
|
210
|
+
if (!registry.textContent?.trim()) registry.remove();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
201
214
|
function createThemeCoordinator() {
|
|
202
215
|
const scopes = new Map<
|
|
203
216
|
symbol,
|
|
@@ -239,6 +252,7 @@ function createThemeCoordinator() {
|
|
|
239
252
|
setTimeout(() => {
|
|
240
253
|
scheduled = false;
|
|
241
254
|
syncActive();
|
|
255
|
+
if (scopes.size === 0) removeEmptyGeneratedStyleRegistries(root);
|
|
242
256
|
}, 0);
|
|
243
257
|
};
|
|
244
258
|
|
|
@@ -462,16 +476,6 @@ function renderThemeToggleIconSlots(
|
|
|
462
476
|
));
|
|
463
477
|
}
|
|
464
478
|
|
|
465
|
-
function isJSXElement(value: unknown): value is JSXElement {
|
|
466
|
-
return (
|
|
467
|
-
typeof value === "object" &&
|
|
468
|
-
value !== null &&
|
|
469
|
-
"$$typeof" in value &&
|
|
470
|
-
"type" in value &&
|
|
471
|
-
"props" in value
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
479
|
function cloneThemeToggleIcon(icon: unknown, key?: string): unknown {
|
|
476
480
|
if (Array.isArray(icon)) {
|
|
477
481
|
const clonedChildren = icon.map((child) => cloneThemeToggleIcon(child));
|
|
@@ -484,7 +488,7 @@ function cloneThemeToggleIcon(icon: unknown, key?: string): unknown {
|
|
|
484
488
|
return clonedChildren;
|
|
485
489
|
}
|
|
486
490
|
|
|
487
|
-
if (!
|
|
491
|
+
if (!isElement(icon)) return icon;
|
|
488
492
|
|
|
489
493
|
const props = icon.props as Record<string, unknown> | undefined;
|
|
490
494
|
const clonedProps = props ? { ...props } : {};
|
|
@@ -493,15 +497,11 @@ function cloneThemeToggleIcon(icon: unknown, key?: string): unknown {
|
|
|
493
497
|
clonedProps.children = cloneThemeToggleIcon(clonedProps.children);
|
|
494
498
|
}
|
|
495
499
|
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
...
|
|
499
|
-
key:
|
|
500
|
-
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
delete (clonedIcon as Record<symbol, unknown>)[STATIC_CHILD_SLOTS_CACHE];
|
|
504
|
-
return clonedIcon;
|
|
500
|
+
const clonedIcon = cloneElement(icon, clonedProps);
|
|
501
|
+
return {
|
|
502
|
+
...clonedIcon,
|
|
503
|
+
key: icon.key ?? key ?? null,
|
|
504
|
+
} satisfies JSXElement;
|
|
505
505
|
}
|
|
506
506
|
|
|
507
507
|
function syncThemeTarget(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/accordion";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/alert-dialog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/alert";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/aspect-ratio";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/avatar";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/badge";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/button-group";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/button";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Calendar,
|
|
3
|
+
CalendarHeader,
|
|
4
|
+
CalendarCaption,
|
|
5
|
+
CalendarNav,
|
|
6
|
+
CalendarPreviousButton,
|
|
7
|
+
CalendarNextButton,
|
|
8
|
+
CalendarGrid,
|
|
9
|
+
CalendarHead,
|
|
10
|
+
CalendarBody,
|
|
11
|
+
CalendarRow,
|
|
12
|
+
CalendarCell,
|
|
13
|
+
CalendarDay,
|
|
14
|
+
} from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/card";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/checkbox";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/collapsible";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Combobox, ComboboxInput, ComboboxList, ComboboxOption } from "../components/catalog";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Dropdown as ContextMenu,
|
|
3
|
+
DropdownGroup as ContextMenuGroup,
|
|
4
|
+
DropdownItem as ContextMenuItem,
|
|
5
|
+
DropdownLabel as ContextMenuLabel,
|
|
6
|
+
DropdownPortal as ContextMenuPortal,
|
|
7
|
+
DropdownSeparator as ContextMenuSeparator,
|
|
8
|
+
DropdownTrigger as ContextMenuTrigger,
|
|
9
|
+
} from "@askrjs/ui/dropdown";
|
|
10
|
+
export { DropdownContent as ContextMenuContent } from "../components/overlays/dropdown-content";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DataTable } from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DatePicker, DatePickerInput } from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/dialog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Direction } from "../components/catalog";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Dialog as Drawer,
|
|
3
|
+
DialogClose as DrawerClose,
|
|
4
|
+
DialogContent as DrawerContent,
|
|
5
|
+
DialogDescription as DrawerDescription,
|
|
6
|
+
DialogOverlay as DrawerOverlay,
|
|
7
|
+
DialogPortal as DrawerPortal,
|
|
8
|
+
DialogTitle as DrawerTitle,
|
|
9
|
+
DialogTrigger as DrawerTrigger,
|
|
10
|
+
} from "@askrjs/ui/dialog";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Dropdown as DropdownMenu,
|
|
3
|
+
DropdownGroup as DropdownMenuGroup,
|
|
4
|
+
DropdownItem as DropdownMenuItem,
|
|
5
|
+
DropdownLabel as DropdownMenuLabel,
|
|
6
|
+
DropdownPortal as DropdownMenuPortal,
|
|
7
|
+
DropdownSeparator as DropdownMenuSeparator,
|
|
8
|
+
DropdownTrigger as DropdownMenuTrigger,
|
|
9
|
+
} from "@askrjs/ui/dropdown";
|
|
10
|
+
export { DropdownContent as DropdownMenuContent } from "../components/overlays/dropdown-content";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/field";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/form";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/hover-card";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/input-group";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/input";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Kbd } from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/label";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/menubar";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NativeSelect } from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/popover";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/progress";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/radio-group";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/scroll-area";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/select";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/separator";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export {
|
|
2
|
+
Dialog as Sheet,
|
|
3
|
+
DialogClose as SheetClose,
|
|
4
|
+
DialogOverlay as SheetOverlay,
|
|
5
|
+
DialogPortal as SheetPortal,
|
|
6
|
+
DialogTrigger as SheetTrigger,
|
|
7
|
+
} from "@askrjs/ui/dialog";
|
|
8
|
+
export {
|
|
9
|
+
SheetContent,
|
|
10
|
+
SheetDescription,
|
|
11
|
+
SheetFooter,
|
|
12
|
+
SheetHeader,
|
|
13
|
+
SheetTitle,
|
|
14
|
+
} from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/sidebar";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/skeleton";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/slider";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Sonner, Toaster } from "../components/catalog";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../components/spinner";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/switch";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/table";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/textarea";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/toast";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/toggle-group";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/toggle";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "@askrjs/ui/tooltip";
|
package/src/parity.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const THEME_COMPONENTS = [
|
|
2
2
|
"Accordion",
|
|
3
3
|
"Alert",
|
|
4
4
|
"AlertDialog",
|
|
@@ -60,9 +60,9 @@ export const SHADCN_THEME_COMPONENTS = [
|
|
|
60
60
|
"Typography",
|
|
61
61
|
] as const;
|
|
62
62
|
|
|
63
|
-
export const
|
|
63
|
+
export const EXCLUDED_CHART_COMPONENT = "Chart" as const;
|
|
64
64
|
|
|
65
|
-
export const
|
|
65
|
+
export const THEME_COMPONENT_SUBPATHS = [
|
|
66
66
|
"accordion",
|
|
67
67
|
"alert",
|
|
68
68
|
"alert-dialog",
|
package/src/ssr.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { styleRulesForHtml } from "./components/_internal/style";
|
|
2
|
-
|
|
3
1
|
const STYLE_REGISTRY_ATTR = "data-askr-style-registry";
|
|
2
|
+
const STYLE_CLASS_PREFIX = "ak-style-";
|
|
3
|
+
const CLASS_ATTRIBUTE_PATTERN = /\sclass=(?:"([^"]*)"|'([^']*)')/g;
|
|
4
|
+
const MAX_STYLE_RULES = 512;
|
|
4
5
|
|
|
5
6
|
type DocumentRenderArgsLike = {
|
|
6
7
|
appHtml: string;
|
|
@@ -22,6 +23,16 @@ function escapeStyleRawText(value: string): string {
|
|
|
22
23
|
return value.replace(/<\/style/gi, "<\\/style");
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
function generatedStyleClasses(html: string): Set<string> {
|
|
27
|
+
const classes = new Set<string>();
|
|
28
|
+
for (const attribute of html.matchAll(CLASS_ATTRIBUTE_PATTERN)) {
|
|
29
|
+
for (const className of (attribute[1] ?? attribute[2] ?? "").split(/\s+/)) {
|
|
30
|
+
if (className.startsWith(STYLE_CLASS_PREFIX)) classes.add(className);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return classes;
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
function findHeadEnd(html: string): number {
|
|
26
37
|
let index = 0;
|
|
27
38
|
while (index < html.length) {
|
|
@@ -72,24 +83,38 @@ export function withThemeStyles<TArgs extends DocumentRenderArgsLike>(
|
|
|
72
83
|
return (args) => {
|
|
73
84
|
const documentHtml = documentRenderer(args);
|
|
74
85
|
const registeredStyles = args.context.styles;
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
const generatedClasses = generatedStyleClasses(documentHtml);
|
|
87
|
+
if (registeredStyles === undefined) {
|
|
88
|
+
if (generatedClasses.size > 0) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"Generated theme classes require request-local SSR style registrations from @askrjs/askr.",
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return documentHtml;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const styles = new Map<string, string>();
|
|
97
|
+
for (const style of registeredStyles) {
|
|
98
|
+
if (!style.id || !style.cssText) {
|
|
99
|
+
throw new TypeError("Invalid SSR theme style registration.");
|
|
100
|
+
}
|
|
101
|
+
const existing = styles.get(style.id);
|
|
102
|
+
if (existing !== undefined && existing !== style.cssText) {
|
|
103
|
+
throw new RangeError(`SSR style registration collision for ${JSON.stringify(style.id)}.`);
|
|
104
|
+
}
|
|
105
|
+
styles.set(style.id, style.cssText);
|
|
106
|
+
if (styles.size > MAX_STYLE_RULES) {
|
|
107
|
+
throw new RangeError("Theme style registry capacity exceeded.");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
for (const className of generatedClasses) {
|
|
111
|
+
if (!styles.has(className)) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Missing request-local SSR style registration for ${JSON.stringify(className)}.`,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const rules = Array.from(styles.values());
|
|
93
118
|
if (rules.length === 0) return documentHtml;
|
|
94
119
|
|
|
95
120
|
const nonce =
|