@repraze/kernelkit 0.1.0-alpha.0 → 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/calendar.js +1 -1
- package/dist/components/calendar.js.map +1 -1
- package/dist/components/carousel.d.ts +6 -1
- package/dist/components/carousel.d.ts.map +1 -1
- package/dist/components/carousel.js +30 -2
- package/dist/components/carousel.js.map +1 -1
- package/dist/components/command.d.ts +1 -1
- package/dist/components/command.d.ts.map +1 -1
- package/dist/components/command.js +2 -2
- package/dist/components/command.js.map +1 -1
- package/dist/components/dropdown-menu.js +1 -1
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/hero.d.ts +14 -2
- package/dist/components/hero.d.ts.map +1 -1
- package/dist/components/hero.js +41 -8
- package/dist/components/hero.js.map +1 -1
- package/dist/components/navigation-menu.d.ts.map +1 -1
- package/dist/components/navigation-menu.js +3 -1
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/sidebar.d.ts.map +1 -1
- package/dist/components/sidebar.js +3 -2
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/site-header.d.ts +3 -3
- package/dist/components/site-header.d.ts.map +1 -1
- package/dist/components/site-header.js +5 -7
- package/dist/components/site-header.js.map +1 -1
- package/dist/components/theme-menu.d.ts +49 -0
- package/dist/components/theme-menu.d.ts.map +1 -0
- package/dist/components/theme-menu.js +75 -0
- package/dist/components/theme-menu.js.map +1 -0
- package/dist/lib/recipes.d.ts +7 -1
- package/dist/lib/recipes.d.ts.map +1 -1
- package/dist/lib/recipes.js +7 -1
- package/dist/lib/recipes.js.map +1 -1
- package/dist/provider/theme-provider.d.ts +4 -0
- package/dist/provider/theme-provider.d.ts.map +1 -1
- package/dist/provider/theme-provider.js +14 -1
- package/dist/provider/theme-provider.js.map +1 -1
- package/package.json +1 -1
- package/src/components/calendar.tsx +1 -1
- package/src/components/carousel.tsx +35 -0
- package/src/components/command.tsx +2 -3
- package/src/components/dropdown-menu.tsx +1 -1
- package/src/components/hero.tsx +77 -7
- package/src/components/navigation-menu.tsx +4 -0
- package/src/components/sidebar.tsx +3 -2
- package/src/components/site-header.tsx +6 -7
- package/src/components/theme-menu.tsx +243 -0
- package/src/lib/recipes.ts +9 -2
- package/src/provider/theme-provider.tsx +18 -1
|
@@ -66,19 +66,17 @@ function SiteNav({ className, render, ...props }) {
|
|
|
66
66
|
/**
|
|
67
67
|
* A nav link, styled like the suite's other navigation (GUIDELINES §7c): muted at rest, a hover wash,
|
|
68
68
|
* and when current (`aria-current="page"`, `data-status="active"` from TanStack Router, or `data-active`)
|
|
69
|
-
* foreground text
|
|
70
|
-
*
|
|
71
|
-
*
|
|
69
|
+
* the sidebar's current-row look: accent tint, foreground text and a 2px accent pill. In SiteNav the pill
|
|
70
|
+
* runs along the link's bottom edge (like NavigationMenu); elsewhere (the phone menu) it sits on the
|
|
71
|
+
* left edge, like a sidebar row.
|
|
72
72
|
*/
|
|
73
73
|
function SiteNavLink({ className, render, ...props }) {
|
|
74
74
|
return useRender({
|
|
75
75
|
defaultTagName: "a",
|
|
76
76
|
props: mergeProps({
|
|
77
77
|
className: cn("relative flex h-8 items-center rounded-md px-2.5 font-mono text-sm text-muted-foreground transition-colors hover:bg-hover hover:text-foreground motion-reduce:transition-none", focusRing,
|
|
78
|
-
// indicator:
|
|
79
|
-
"after:pointer-events-none after:absolute after:top-1.5 after:bottom-1.5 after:left-0 after:w-0.5 after:rounded-pill after:bg-primary-text after:opacity-0", "in-data-[slot=site-nav]:after:top-auto in-data-[slot=site-nav]:after:right-2.5 in-data-[slot=site-nav]:after
|
|
80
|
-
// outside the header row: the sidebar's current-row tint
|
|
81
|
-
"not-in-data-[slot=site-nav]:aria-[current=page]:bg-primary-tint not-in-data-[slot=site-nav]:data-[status=active]:bg-primary-tint not-in-data-[slot=site-nav]:data-active:bg-primary-tint", className),
|
|
78
|
+
// indicator: left edge by default, bottom edge inside SiteNav
|
|
79
|
+
"after:pointer-events-none after:absolute after:top-1.5 after:bottom-1.5 after:left-0 after:w-0.5 after:rounded-pill after:bg-primary-text after:opacity-0", "in-data-[slot=site-nav]:after:top-auto in-data-[slot=site-nav]:after:right-2.5 in-data-[slot=site-nav]:after:bottom-0 in-data-[slot=site-nav]:after:left-2.5 in-data-[slot=site-nav]:after:h-0.5 in-data-[slot=site-nav]:after:w-auto", "aria-[current=page]:text-foreground aria-[current=page]:after:opacity-100 data-[status=active]:text-foreground data-[status=active]:after:opacity-100 data-active:text-foreground data-active:after:opacity-100", "aria-[current=page]:bg-primary-tint data-[status=active]:bg-primary-tint data-active:bg-primary-tint", className),
|
|
82
80
|
}, props),
|
|
83
81
|
render,
|
|
84
82
|
state: { slot: "site-nav-link" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-header.js","sourceRoot":"","sources":["../../src/components/site-header.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAC,SAAS,EAAC,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAC5D,OAAO,EAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,qCAAqC,CAAC;AAC/G,OAAO,EAAC,SAAS,EAAC,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAC,EAAE,EAAC,MAAM,IAAI,CAAC;AACtB,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AAGtC;;;;;;;;;;;;;;GAcG;AACH,SAAS,UAAU,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAqC;IACjF,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,QAAQ;QACxB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,0IAA0I,EAC1I,SAAS,CACZ;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,aAAa,EAAC;KAC/B,CAAC,CAAC;AACP,CAAC;AAED,qFAAqF;AACrF,SAAS,iBAAiB,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAkC;IACrF,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,KAAK;QACrB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,2FAA2F,EAC3F,SAAS,CACZ;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,qBAAqB,EAAC;KACvC,CAAC,CAAC;AACP,CAAC;AAED,mEAAmE;AACnE,SAAS,eAAe,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAgC;IACjF,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,GAAG;QACnB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,4FAA4F,EAC5F,SAAS,EACT,kBAAkB,EAClB,SAAS,CACZ;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,mBAAmB,EAAC;KACrC,CAAC,CAAC;AACP,CAAC;AAED,kFAAkF;AAClF,SAAS,OAAO,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAkC;IAC3E,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,KAAK;QACrB,KAAK,EAAE,UAAU,CACb,EAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,mCAAmC,EAAE,SAAS,CAAC,EAAC,EACrF,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,UAAU,EAAC;KAC5B,CAAC,CAAC;AACP,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAgC;IAC7E,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,GAAG;QACnB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,+KAA+K,EAC/K,SAAS;YACT,
|
|
1
|
+
{"version":3,"file":"site-header.js","sourceRoot":"","sources":["../../src/components/site-header.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAC,UAAU,EAAC,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAC,SAAS,EAAC,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAC5D,OAAO,EAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,qCAAqC,CAAC;AAC/G,OAAO,EAAC,SAAS,EAAC,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAC,EAAE,EAAC,MAAM,IAAI,CAAC;AACtB,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AAGtC;;;;;;;;;;;;;;GAcG;AACH,SAAS,UAAU,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAqC;IACjF,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,QAAQ;QACxB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,0IAA0I,EAC1I,SAAS,CACZ;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,aAAa,EAAC;KAC/B,CAAC,CAAC;AACP,CAAC;AAED,qFAAqF;AACrF,SAAS,iBAAiB,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAkC;IACrF,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,KAAK;QACrB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,2FAA2F,EAC3F,SAAS,CACZ;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,qBAAqB,EAAC;KACvC,CAAC,CAAC;AACP,CAAC;AAED,mEAAmE;AACnE,SAAS,eAAe,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAgC;IACjF,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,GAAG;QACnB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,4FAA4F,EAC5F,SAAS,EACT,kBAAkB,EAClB,SAAS,CACZ;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,mBAAmB,EAAC;KACrC,CAAC,CAAC;AACP,CAAC;AAED,kFAAkF;AAClF,SAAS,OAAO,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAkC;IAC3E,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,KAAK;QACrB,KAAK,EAAE,UAAU,CACb,EAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,mCAAmC,EAAE,SAAS,CAAC,EAAC,EACrF,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,UAAU,EAAC;KAC5B,CAAC,CAAC;AACP,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAgC;IAC7E,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,GAAG;QACnB,KAAK,EAAE,UAAU,CACb;YACI,SAAS,EAAE,EAAE,CACT,+KAA+K,EAC/K,SAAS;YACT,8DAA8D;YAC9D,2JAA2J,EAC3J,uOAAuO,EACvO,iNAAiN,EACjN,sGAAsG,EACtG,SAAS,CACZ;SACJ,EACD,KAAK,CACR;QACD,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,eAAe,EAAC;KACjC,CAAC,CAAC;AACP,CAAC;AAED,qEAAqE;AACrE,SAAS,iBAAiB,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,EAAkC;IACrF,OAAO,SAAS,CAAC;QACb,cAAc,EAAE,KAAK;QACrB,KAAK,EAAE,UAAU,CAAQ,EAAC,SAAS,EAAE,EAAE,CAAC,iCAAiC,EAAE,SAAS,CAAC,EAAC,EAAE,KAAK,CAAC;QAC9F,MAAM;QACN,KAAK,EAAE,EAAC,IAAI,EAAE,qBAAqB,EAAC;KACvC,CAAC,CAAC;AACP,CAAC;AASD;;;GAGG;AACH,SAAS,cAAc,CAAC,EAAC,KAAK,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAsB;IACxF,OAAO,CACH,MAAC,KAAK,OAAK,KAAK,aACZ,KAAC,YAAY,IACT,MAAM,EAAE,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAC,SAAS,EAAC,SAAS,EAAC,mBAAmB,gBAAY,MAAM,GAAG,YAEjG,KAAC,QAAQ,KAAG,GACD,EACf,MAAC,YAAY,IACT,IAAI,EAAC,MAAM,eACD,kBAAkB,EAC5B,SAAS,EAAE,EAAE,CAAC,mDAAmD,EAAE,SAAS,CAAC,aAE7E,KAAC,WAAW,IAAC,SAAS,EAAC,wBAAwB,YAC3C,KAAC,UAAU,IAAC,SAAS,EAAC,yBAAyB,YAAE,KAAK,GAAc,GAC1D,EACd,cAAK,SAAS,EAAC,yBAAyB,YAAE,QAAQ,GAAO,IAC9C,IACX,CACX,CAAC;AACN,CAAC;AAED,OAAO,EAAC,UAAU,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Button } from "@repraze/kernelkit/components/button";
|
|
2
|
+
import { type Mode } from "@repraze/kernelkit/provider";
|
|
3
|
+
import { type LucideIcon } from "lucide-react";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
/** The icon for the chosen mode (not the resolved one): sun, moon, or monitor for "system". */
|
|
6
|
+
declare function ThemeModeIcon({ mode, ...props }: {
|
|
7
|
+
mode?: Mode;
|
|
8
|
+
} & React.ComponentProps<LucideIcon>): React.JSX.Element;
|
|
9
|
+
/** Light / dark / system as a segmented control. */
|
|
10
|
+
declare function ThemeModePicker({ className }: {
|
|
11
|
+
className?: string;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
/** The eight TermiColor accents as swatches; sets the theme's accent. */
|
|
14
|
+
declare function ThemeAccentPicker({ className }: {
|
|
15
|
+
className?: string;
|
|
16
|
+
}): React.JSX.Element;
|
|
17
|
+
/** The radius scale as a segmented control; sets the theme's radius. */
|
|
18
|
+
declare function ThemeRadiusPicker({ className }: {
|
|
19
|
+
className?: string;
|
|
20
|
+
}): React.JSX.Element;
|
|
21
|
+
/** High contrast on/off, with its label. */
|
|
22
|
+
declare function ThemeContrastSwitch({ className }: {
|
|
23
|
+
className?: string;
|
|
24
|
+
}): React.JSX.Element;
|
|
25
|
+
/** A labelled block inside the menu. */
|
|
26
|
+
declare function ThemeMenuSection({ label, children, className, }: {
|
|
27
|
+
label: string;
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
className?: string;
|
|
30
|
+
}): React.JSX.Element;
|
|
31
|
+
interface ThemeMenuProps extends Omit<React.ComponentProps<typeof Button>, "children" | "title"> {
|
|
32
|
+
/** Popover title. */
|
|
33
|
+
title?: React.ReactNode;
|
|
34
|
+
/** Extra controls, after the built-in ones and before Reset. */
|
|
35
|
+
children?: React.ReactNode;
|
|
36
|
+
/** Popover alignment against the trigger. */
|
|
37
|
+
align?: "start" | "center" | "end";
|
|
38
|
+
contentClassName?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The suite's theme control (GUIDELINES §7b): one ghost icon button in `SiteHeaderActions` showing the
|
|
42
|
+
* chosen mode (sun, moon, monitor), opening a popover with mode, accent, high contrast, radius and a
|
|
43
|
+
* Reset to the provider's defaults. Reads and writes `useTheme()`, so it needs a `ThemeProvider`.
|
|
44
|
+
* Trigger props (`aria-label`, `className`, `data-*`) pass through to the button.
|
|
45
|
+
*/
|
|
46
|
+
declare function ThemeMenu({ title, children, align, contentClassName, className, ...props }: ThemeMenuProps): React.JSX.Element;
|
|
47
|
+
export { ThemeAccentPicker, ThemeContrastSwitch, ThemeMenu, ThemeMenuSection, ThemeModeIcon, ThemeModePicker, ThemeRadiusPicker, };
|
|
48
|
+
export type { ThemeMenuProps };
|
|
49
|
+
//# sourceMappingURL=theme-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-menu.d.ts","sourceRoot":"","sources":["../../src/components/theme-menu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAY5D,OAAO,EAAuB,KAAK,IAAI,EAA+B,MAAM,6BAA6B,CAAC;AAE1G,OAAO,EAAY,KAAK,UAAU,EAAgD,MAAM,cAAc,CAAC;AACvG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,+FAA+F;AAC/F,iBAAS,aAAa,CAAC,EAAC,IAAI,EAAE,GAAG,KAAK,EAAC,EAAE;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAC,GAAG,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,qBAIxF;AAED,oDAAoD;AACpD,iBAAS,eAAe,CAAC,EAAC,SAAS,EAAC,EAAE;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAC,qBAmBzD;AAQD,yEAAyE;AACzE,iBAAS,iBAAiB,CAAC,EAAC,SAAS,EAAC,EAAE;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAC,qBAsC3D;AAED,wEAAwE;AACxE,iBAAS,iBAAiB,CAAC,EAAC,SAAS,EAAC,EAAE;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAC,qBAmB3D;AAED,4CAA4C;AAC5C,iBAAS,mBAAmB,CAAC,EAAC,SAAS,EAAC,EAAE;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAC,qBAa7D;AAED,wCAAwC;AACxC,iBAAS,gBAAgB,CAAC,EACtB,KAAK,EACL,QAAQ,EACR,SAAS,GACZ,EAAE;IACC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,qBAOA;AAED,UAAU,cAAe,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5F,qBAAqB;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,iBAAS,SAAS,CAAC,EAAC,KAAe,EAAE,QAAQ,EAAE,KAAa,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,KAAK,EAAC,EAAE,cAAc,qBAuDnH;AAED,OAAO,EACH,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,iBAAiB,GACpB,CAAC;AACF,YAAY,EAAC,cAAc,EAAC,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from "@repraze/kernelkit/components/button";
|
|
4
|
+
import { Label } from "@repraze/kernelkit/components/label";
|
|
5
|
+
import { Popover, PopoverContent, PopoverHeader, PopoverTitle, PopoverTrigger, } from "@repraze/kernelkit/components/popover";
|
|
6
|
+
import { Switch } from "@repraze/kernelkit/components/switch";
|
|
7
|
+
import { ToggleGroup, ToggleGroupItem } from "@repraze/kernelkit/components/toggle-group";
|
|
8
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "@repraze/kernelkit/components/tooltip";
|
|
9
|
+
import { ACCENTS, RADII, useTheme } from "@repraze/kernelkit/provider";
|
|
10
|
+
import { cn } from "cn";
|
|
11
|
+
import { CheckIcon, MonitorIcon, MoonIcon, RotateCcwIcon, SunIcon } from "lucide-react";
|
|
12
|
+
import * as React from "react";
|
|
13
|
+
/** Mode choices in display order, with the icon the trigger shows for each. */
|
|
14
|
+
const THEME_MODES = [
|
|
15
|
+
{ value: "light", label: "Light", icon: SunIcon },
|
|
16
|
+
{ value: "dark", label: "Dark", icon: MoonIcon },
|
|
17
|
+
{ value: "system", label: "System", icon: MonitorIcon },
|
|
18
|
+
];
|
|
19
|
+
const modeOption = (mode) => THEME_MODES.find((m) => m.value === mode) ?? THEME_MODES[2];
|
|
20
|
+
/** The icon for the chosen mode (not the resolved one): sun, moon, or monitor for "system". */
|
|
21
|
+
function ThemeModeIcon({ mode, ...props }) {
|
|
22
|
+
const theme = useTheme();
|
|
23
|
+
const Icon = modeOption(mode ?? theme.mode).icon;
|
|
24
|
+
return _jsx(Icon, { "data-slot": "theme-mode-icon", ...props });
|
|
25
|
+
}
|
|
26
|
+
/** Light / dark / system as a segmented control. */
|
|
27
|
+
function ThemeModePicker({ className }) {
|
|
28
|
+
const theme = useTheme();
|
|
29
|
+
return (_jsx(ToggleGroup, { "data-slot": "theme-mode-picker", "aria-label": "Mode", variant: "outline", size: "sm", value: [theme.mode], onValueChange: (v) => v[0] && theme.setMode(v[0]), className: cn("w-full", className), children: THEME_MODES.map(({ value, label, icon: Icon }) => (_jsxs(ToggleGroupItem, { value: value, className: "flex-1", children: [_jsx(Icon, {}), " ", label] }, value))) }));
|
|
30
|
+
}
|
|
31
|
+
/** Swatch per accent: the vivid fill tier, with that accent's own on-fill color for the check mark. */
|
|
32
|
+
const swatch = (accent) => ({
|
|
33
|
+
background: `var(--tc-accent-${accent}-accent-fill)`,
|
|
34
|
+
color: `var(--tc-accent-${accent}-on-accent-fill)`,
|
|
35
|
+
});
|
|
36
|
+
/** The eight TermiColor accents as swatches; sets the theme's accent. */
|
|
37
|
+
function ThemeAccentPicker({ className }) {
|
|
38
|
+
const theme = useTheme();
|
|
39
|
+
return (_jsx("div", { "data-slot": "theme-accent-picker", role: "group", "aria-label": "Accent", className: cn("grid grid-cols-8 gap-1.5", className), children: ACCENTS.map((accent) => {
|
|
40
|
+
const on = theme.accent === accent;
|
|
41
|
+
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: _jsx("button", { type: "button", "aria-label": accent, "aria-pressed": on, onClick: () => theme.setAccent(accent), style: swatch(accent), className: cn("flex aspect-square items-center justify-center rounded-md outline-none", "ring-offset-2 ring-offset-transparent transition-shadow duration-100 motion-reduce:transition-none", "hover:ring-2 hover:ring-input focus-visible:ring-2 focus-visible:ring-ring", on && "ring-2 ring-foreground hover:ring-foreground") }), children: on ? _jsx(CheckIcon, { className: "size-3.5", strokeWidth: 3 }) : null }), _jsx(TooltipContent, { className: "capitalize", children: accent })] }, accent));
|
|
42
|
+
}) }));
|
|
43
|
+
}
|
|
44
|
+
/** The radius scale as a segmented control; sets the theme's radius. */
|
|
45
|
+
function ThemeRadiusPicker({ className }) {
|
|
46
|
+
const theme = useTheme();
|
|
47
|
+
return (_jsx(ToggleGroup, { "data-slot": "theme-radius-picker", "aria-label": "Radius", variant: "outline", size: "sm", value: [theme.radius], onValueChange: (v) => v[0] && theme.setRadius(v[0]), className: cn("w-full", className), children: RADII.map((radius) => (_jsx(ToggleGroupItem, { value: radius, className: "flex-1 font-mono", children: radius }, radius))) }));
|
|
48
|
+
}
|
|
49
|
+
/** High contrast on/off, with its label. */
|
|
50
|
+
function ThemeContrastSwitch({ className }) {
|
|
51
|
+
const theme = useTheme();
|
|
52
|
+
const id = React.useId();
|
|
53
|
+
return (_jsxs("div", { "data-slot": "theme-contrast-switch", className: cn("flex items-center justify-between gap-2", className), children: [_jsx(Label, { htmlFor: id, children: "High contrast" }), _jsx(Switch, { id: id, checked: theme.contrast === "high", onCheckedChange: (on) => theme.setContrast(on ? "high" : "normal") })] }));
|
|
54
|
+
}
|
|
55
|
+
/** A labelled block inside the menu. */
|
|
56
|
+
function ThemeMenuSection({ label, children, className, }) {
|
|
57
|
+
return (_jsxs("div", { "data-slot": "theme-menu-section", className: cn("flex flex-col gap-2", className), children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: label }), children] }));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The suite's theme control (GUIDELINES §7b): one ghost icon button in `SiteHeaderActions` showing the
|
|
61
|
+
* chosen mode (sun, moon, monitor), opening a popover with mode, accent, high contrast, radius and a
|
|
62
|
+
* Reset to the provider's defaults. Reads and writes `useTheme()`, so it needs a `ThemeProvider`.
|
|
63
|
+
* Trigger props (`aria-label`, `className`, `data-*`) pass through to the button.
|
|
64
|
+
*/
|
|
65
|
+
function ThemeMenu({ title = "Theme", children, align = "end", contentClassName, className, ...props }) {
|
|
66
|
+
const theme = useTheme();
|
|
67
|
+
const { defaults } = theme;
|
|
68
|
+
const isDefault = theme.mode === defaults.mode &&
|
|
69
|
+
theme.accent === defaults.accent &&
|
|
70
|
+
theme.contrast === defaults.contrast &&
|
|
71
|
+
theme.radius === defaults.radius;
|
|
72
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { render: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": `Theme: ${modeOption(theme.mode).label}`, "data-slot": "theme-menu-trigger", "data-mode": theme.mode, className: className, ...props }), children: _jsx(ThemeModeIcon, {}) }), _jsxs(PopoverContent, { "data-slot": "theme-menu-content", align: align, className: cn("w-72 gap-4", contentClassName), children: [_jsx(PopoverHeader, { children: _jsx(PopoverTitle, { children: title }) }), _jsx(ThemeMenuSection, { label: "Mode", children: _jsx(ThemeModePicker, {}) }), _jsx(ThemeMenuSection, { label: "Accent", children: _jsx(ThemeAccentPicker, {}) }), _jsx(ThemeContrastSwitch, {}), _jsx(ThemeMenuSection, { label: "Radius", children: _jsx(ThemeRadiusPicker, {}) }), children, _jsx("div", { className: "-mx-3 -mb-3 border-t border-border p-3", children: _jsxs(Button, { variant: "outline", size: "sm", "data-slot": "theme-menu-reset", className: "w-full", disabled: isDefault, onClick: theme.resetTheme, children: [_jsx(RotateCcwIcon, { "data-icon": "inline-start" }), " Reset to defaults"] }) })] })] }));
|
|
73
|
+
}
|
|
74
|
+
export { ThemeAccentPicker, ThemeContrastSwitch, ThemeMenu, ThemeMenuSection, ThemeModeIcon, ThemeModePicker, ThemeRadiusPicker, };
|
|
75
|
+
//# sourceMappingURL=theme-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-menu.js","sourceRoot":"","sources":["../../src/components/theme-menu.tsx"],"names":[],"mappings":"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"}
|
package/dist/lib/recipes.d.ts
CHANGED
|
@@ -13,8 +13,14 @@ export declare const fieldSurface = "rounded-lg border border-input bg-field tra
|
|
|
13
13
|
export declare const popupSurface = "rounded-lg border border-border bg-popover text-popover-foreground shadow-lg shadow-(color:--shadow-color)";
|
|
14
14
|
/** Popup open/close motion (§6). */
|
|
15
15
|
export declare const popupMotion = "origin-(--transform-origin) duration-100 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 motion-reduce:animate-none";
|
|
16
|
+
/**
|
|
17
|
+
* The sidebar's current-row indicator (§7c): a 2px accent pill inset on the row's left edge, hidden until
|
|
18
|
+
* the row's state shows it (`data-highlighted:after:opacity-100`, `data-active:after:opacity-100`...).
|
|
19
|
+
* The row keeps its own rounding on every corner.
|
|
20
|
+
*/
|
|
21
|
+
export declare const rowIndicator = "after:pointer-events-none after:absolute after:top-1.5 after:bottom-1.5 after:left-0 after:w-0.5 after:rounded-pill after:bg-primary-text after:opacity-0";
|
|
16
22
|
/** Row inside a popup or list: menu item, select item, command item (§4, §6). */
|
|
17
|
-
export declare const listItem = "relative flex min-h-8 cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-highlighted:[&_svg:not([class*='text-'])]:text-accent-foreground";
|
|
23
|
+
export declare const listItem = "after:pointer-events-none after:absolute after:top-1.5 after:bottom-1.5 after:left-0 after:w-0.5 after:rounded-pill after:bg-primary-text after:opacity-0 data-highlighted:after:opacity-100 relative flex min-h-8 cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-highlighted:[&_svg:not([class*='text-'])]:text-accent-foreground";
|
|
18
24
|
/** Group label inside a popup or list. */
|
|
19
25
|
export declare const listLabel = "px-2 py-1.5 text-xs font-medium text-muted-foreground";
|
|
20
26
|
/** Separator inside a popup or list. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,eAAO,MAAM,SAAS,2FAA2F,CAAC;AAElH,2CAA2C;AAC3C,eAAO,MAAM,WAAW,gHACyF,CAAC;AAElH,iGAAiG;AACjG,eAAO,MAAM,YAAY,qNAC6L,CAAC;AAEvN,iFAAiF;AACjF,eAAO,MAAM,YAAY,+GACuF,CAAC;AAEjH,oCAAoC;AACpC,eAAO,MAAM,WAAW,yWACkV,CAAC;AAE3W,iFAAiF;AACjF,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,eAAO,MAAM,SAAS,2FAA2F,CAAC;AAElH,2CAA2C;AAC3C,eAAO,MAAM,WAAW,gHACyF,CAAC;AAElH,iGAAiG;AACjG,eAAO,MAAM,YAAY,qNAC6L,CAAC;AAEvN,iFAAiF;AACjF,eAAO,MAAM,YAAY,+GACuF,CAAC;AAEjH,oCAAoC;AACpC,eAAO,MAAM,WAAW,yWACkV,CAAC;AAE3W;;;;GAIG;AACH,eAAO,MAAM,YAAY,8JACsI,CAAC;AAEhK,iFAAiF;AACjF,eAAO,MAAM,QAAQ,6nBAAmf,CAAC;AAEzgB,0CAA0C;AAC1C,eAAO,MAAM,SAAS,0DAA0D,CAAC;AAEjF,wCAAwC;AACxC,eAAO,MAAM,aAAa,8BAA8B,CAAC;AAEzD,8DAA8D;AAC9D,eAAO,MAAM,QAAQ,0LACsK,CAAC;AAE5L,4EAA4E;AAC5E,eAAO,MAAM,OAAO,4CAA4C,CAAC;AAEjE,iHAAiH;AACjH,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAE/D,yGAAyG;AACzG,eAAO,MAAM,WAAW,gFAAgF,CAAC"}
|
package/dist/lib/recipes.js
CHANGED
|
@@ -13,8 +13,14 @@ export const fieldSurface = "rounded-lg border border-input bg-field transition-
|
|
|
13
13
|
export const popupSurface = "rounded-lg border border-border bg-popover text-popover-foreground shadow-lg shadow-(color:--shadow-color)";
|
|
14
14
|
/** Popup open/close motion (§6). */
|
|
15
15
|
export const popupMotion = "origin-(--transform-origin) duration-100 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 motion-reduce:animate-none";
|
|
16
|
+
/**
|
|
17
|
+
* The sidebar's current-row indicator (§7c): a 2px accent pill inset on the row's left edge, hidden until
|
|
18
|
+
* the row's state shows it (`data-highlighted:after:opacity-100`, `data-active:after:opacity-100`...).
|
|
19
|
+
* The row keeps its own rounding on every corner.
|
|
20
|
+
*/
|
|
21
|
+
export const rowIndicator = "after:pointer-events-none after:absolute after:top-1.5 after:bottom-1.5 after:left-0 after:w-0.5 after:rounded-pill after:bg-primary-text after:opacity-0";
|
|
16
22
|
/** Row inside a popup or list: menu item, select item, command item (§4, §6). */
|
|
17
|
-
export const listItem =
|
|
23
|
+
export const listItem = `${rowIndicator} data-highlighted:after:opacity-100 relative flex min-h-8 cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-highlighted:[&_svg:not([class*='text-'])]:text-accent-foreground`;
|
|
18
24
|
/** Group label inside a popup or list. */
|
|
19
25
|
export const listLabel = "px-2 py-1.5 text-xs font-medium text-muted-foreground";
|
|
20
26
|
/** Separator inside a popup or list. */
|
package/dist/lib/recipes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,wFAAwF,CAAC;AAElH,2CAA2C;AAC3C,MAAM,CAAC,MAAM,WAAW,GACpB,6GAA6G,CAAC;AAElH,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GACrB,kNAAkN,CAAC;AAEvN,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GACrB,4GAA4G,CAAC;AAEjH,oCAAoC;AACpC,MAAM,CAAC,MAAM,WAAW,GACpB,sWAAsW,CAAC;AAE3W,iFAAiF;AACjF,MAAM,CAAC,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../../src/lib/recipes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,wFAAwF,CAAC;AAElH,2CAA2C;AAC3C,MAAM,CAAC,MAAM,WAAW,GACpB,6GAA6G,CAAC;AAElH,iGAAiG;AACjG,MAAM,CAAC,MAAM,YAAY,GACrB,kNAAkN,CAAC;AAEvN,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GACrB,4GAA4G,CAAC;AAEjH,oCAAoC;AACpC,MAAM,CAAC,MAAM,WAAW,GACpB,sWAAsW,CAAC;AAE3W;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GACrB,2JAA2J,CAAC;AAEhK,iFAAiF;AACjF,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,YAAY,ieAAie,CAAC;AAEzgB,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAG,uDAAuD,CAAC;AAEjF,wCAAwC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAEzD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,QAAQ,GACjB,uLAAuL,CAAC,CAAC,0CAA0C;AAEvO,4EAA4E;AAC5E,MAAM,CAAC,MAAM,OAAO,GAAG,yCAAyC,CAAC;AAEjE,iHAAiH;AACjH,MAAM,CAAC,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAE/D,yGAAyG;AACzG,MAAM,CAAC,MAAM,WAAW,GAAG,6EAA6E,CAAC"}
|
|
@@ -8,6 +8,10 @@ export interface ThemeContextValue extends ThemeState {
|
|
|
8
8
|
setContrast: (contrast: ThemeState["contrast"]) => void;
|
|
9
9
|
setAccent: (accent: ThemeState["accent"]) => void;
|
|
10
10
|
setRadius: (radius: ThemeState["radius"]) => void;
|
|
11
|
+
/** The values `resetTheme` restores: the provider's `defaultTheme` over the kit defaults. */
|
|
12
|
+
defaults: ThemeState;
|
|
13
|
+
/** Forget the stored choice and go back to `defaults`. */
|
|
14
|
+
resetTheme: () => void;
|
|
11
15
|
}
|
|
12
16
|
export interface ThemeProviderProps {
|
|
13
17
|
children?: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/provider/theme-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,SAAS,EAQjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAIH,KAAK,YAAY,EAIjB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EAClB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACjD,+DAA+D;IAC/D,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACxD,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/provider/theme-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,SAAS,EAQjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAIH,KAAK,YAAY,EAIjB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EAClB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACjD,+DAA+D;IAC/D,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACxD,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAClD,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IAClD,6FAA6F;IAC7F,QAAQ,EAAE,UAAU,CAAC;IACrB,0DAA0D;IAC1D,UAAU,EAAE,MAAM,IAAI,CAAC;CAC1B;AAoCD,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,qGAAqG;IACrG,YAAY,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,uFAAuF;IACvF,WAAW,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC1B,QAAQ,EACR,YAAY,EACZ,UAAgC,EAChC,WAAW,GACd,EAAE,kBAAkB,+BA+EpB;AAED,qEAAqE;AACrE,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,EAAC,KAAK,EAAE,GAAG,OAAO,EAAC,EAAE,kBAAkB,GAAG;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,+BAErF;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAClF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,uFAAuF;IACvF,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAClC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAC,EAAE,eAAe,+BAoB1G;AAED,gGAAgG;AAChG,wBAAgB,kBAAkB,IAAI,WAAW,GAAG,SAAS,CAE5D"}
|
|
@@ -72,6 +72,17 @@ export function ThemeProvider({ children, defaultTheme, storageKey = DEFAULT_STO
|
|
|
72
72
|
return next;
|
|
73
73
|
});
|
|
74
74
|
}, [storageKey, fallback]);
|
|
75
|
+
const resetTheme = useCallback(() => {
|
|
76
|
+
if (storageKey) {
|
|
77
|
+
try {
|
|
78
|
+
window.localStorage.removeItem(storageKey);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// storage blocked: the in-memory reset still applies
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
setStored(fallback);
|
|
85
|
+
}, [storageKey, fallback]);
|
|
75
86
|
const value = useMemo(() => ({
|
|
76
87
|
...theme,
|
|
77
88
|
resolvedMode,
|
|
@@ -80,7 +91,9 @@ export function ThemeProvider({ children, defaultTheme, storageKey = DEFAULT_STO
|
|
|
80
91
|
setContrast: (contrast) => setTheme({ contrast }),
|
|
81
92
|
setAccent: (accent) => setTheme({ accent }),
|
|
82
93
|
setRadius: (radius) => setTheme({ radius }),
|
|
83
|
-
|
|
94
|
+
defaults: fallback,
|
|
95
|
+
resetTheme,
|
|
96
|
+
}), [theme, resolvedMode, setTheme, fallback, resetTheme]);
|
|
84
97
|
return _jsx(ThemeContext.Provider, { value: value, children: children });
|
|
85
98
|
}
|
|
86
99
|
/** Current theme and setters. Must be used under <ThemeProvider>. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-provider.js","sourceRoot":"","sources":["../../src/provider/theme-provider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EACH,aAAa,EAEb,WAAW,EACX,UAAU,EACV,SAAS,EACT,eAAe,EACf,OAAO,EACP,QAAQ,EACR,oBAAoB,GACvB,MAAM,OAAO,CAAC;AAEf,OAAO,EACH,UAAU,EACV,mBAAmB,EACnB,aAAa,EAEb,aAAa,EACb,cAAc,EACd,WAAW,GAGd,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"theme-provider.js","sourceRoot":"","sources":["../../src/provider/theme-provider.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -32,7 +32,7 @@ function Calendar({
|
|
|
32
32
|
<DayPicker
|
|
33
33
|
showOutsideDays={showOutsideDays}
|
|
34
34
|
className={cn(
|
|
35
|
-
"group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(8)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
|
|
35
|
+
"group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(8)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent in-data-[slot=date-picker-content]:bg-transparent",
|
|
36
36
|
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
37
37
|
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
38
38
|
className,
|
|
@@ -17,6 +17,11 @@ type CarouselProps = {
|
|
|
17
17
|
plugins?: CarouselPlugin;
|
|
18
18
|
orientation?: "horizontal" | "vertical";
|
|
19
19
|
setApi?: (api: CarouselApi) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Advance every `autoplay` ms, wrapping to the first slide. Pauses while the pointer is over the
|
|
22
|
+
* carousel or focus is inside it, while the tab is hidden, and never runs under reduced motion.
|
|
23
|
+
*/
|
|
24
|
+
autoplay?: number;
|
|
20
25
|
};
|
|
21
26
|
|
|
22
27
|
type CarouselContextProps = {
|
|
@@ -45,6 +50,7 @@ function Carousel({
|
|
|
45
50
|
opts,
|
|
46
51
|
setApi,
|
|
47
52
|
plugins,
|
|
53
|
+
autoplay,
|
|
48
54
|
className,
|
|
49
55
|
children,
|
|
50
56
|
...props
|
|
@@ -109,6 +115,34 @@ function Carousel({
|
|
|
109
115
|
};
|
|
110
116
|
}, [api, onSelect]);
|
|
111
117
|
|
|
118
|
+
const rootRef = React.useRef<HTMLDivElement>(null);
|
|
119
|
+
React.useEffect(() => {
|
|
120
|
+
const root = rootRef.current;
|
|
121
|
+
if (!api || !autoplay || !root || window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
let hovered = false;
|
|
125
|
+
const onEnter = () => (hovered = true);
|
|
126
|
+
const onLeave = () => (hovered = false);
|
|
127
|
+
root.addEventListener("pointerenter", onEnter);
|
|
128
|
+
root.addEventListener("pointerleave", onLeave);
|
|
129
|
+
const timer = window.setInterval(() => {
|
|
130
|
+
if (hovered || root.contains(document.activeElement) || document.hidden) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (api.canScrollNext()) {
|
|
134
|
+
api.scrollNext();
|
|
135
|
+
} else {
|
|
136
|
+
api.scrollTo(0);
|
|
137
|
+
}
|
|
138
|
+
}, autoplay);
|
|
139
|
+
return () => {
|
|
140
|
+
window.clearInterval(timer);
|
|
141
|
+
root.removeEventListener("pointerenter", onEnter);
|
|
142
|
+
root.removeEventListener("pointerleave", onLeave);
|
|
143
|
+
};
|
|
144
|
+
}, [api, autoplay]);
|
|
145
|
+
|
|
112
146
|
return (
|
|
113
147
|
<CarouselContext.Provider
|
|
114
148
|
value={{
|
|
@@ -123,6 +157,7 @@ function Carousel({
|
|
|
123
157
|
}}
|
|
124
158
|
>
|
|
125
159
|
<div
|
|
160
|
+
ref={rootRef}
|
|
126
161
|
onKeyDownCapture={handleKeyDown}
|
|
127
162
|
className={cn("relative", className)}
|
|
128
163
|
role="region"
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
DialogHeader,
|
|
8
8
|
DialogTitle,
|
|
9
9
|
} from "@repraze/kernelkit/components/dialog";
|
|
10
|
-
import {fieldSurface, listSeparator} from "@repraze/kernelkit/lib/recipes";
|
|
10
|
+
import {fieldSurface, listSeparator, rowIndicator} from "@repraze/kernelkit/lib/recipes";
|
|
11
11
|
import {Command as CommandPrimitive} from "cmdk";
|
|
12
12
|
import {cn} from "cn";
|
|
13
13
|
import {CheckIcon, SearchIcon} from "lucide-react";
|
|
@@ -17,8 +17,7 @@ import * as React from "react";
|
|
|
17
17
|
* cmdk renders `data-selected` / `data-disabled` as "true" | "false", so the `listItem` recipe (which keys on
|
|
18
18
|
* attribute presence) can't be used as is: this is the same row, keyed on `=true`.
|
|
19
19
|
*/
|
|
20
|
-
const commandItemClass =
|
|
21
|
-
"group/command-item relative flex min-h-8 cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[selected=true]:[&_svg:not([class*='text-'])]:text-accent-foreground";
|
|
20
|
+
const commandItemClass = `${rowIndicator} data-[selected=true]:after:opacity-100 group/command-item relative flex min-h-8 cursor-default items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-hidden select-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[selected=true]:[&_svg:not([class*='text-'])]:text-accent-foreground`;
|
|
22
21
|
|
|
23
22
|
function Command({className, ...props}: React.ComponentProps<typeof CommandPrimitive>) {
|
|
24
23
|
return (
|
|
@@ -23,7 +23,7 @@ const menuItemVariants = cva([listItem, "group/menu-item data-inset:pl-8"], {
|
|
|
23
23
|
variants: {
|
|
24
24
|
variant: {
|
|
25
25
|
default: "",
|
|
26
|
-
danger: "text-danger data-highlighted:bg-danger/15 data-highlighted:text-danger [&_svg:not([class*='text-'])]:text-danger data-highlighted:[&_svg:not([class*='text-'])]:text-danger",
|
|
26
|
+
danger: "text-danger after:bg-danger data-highlighted:bg-danger/15 data-highlighted:text-danger [&_svg:not([class*='text-'])]:text-danger data-highlighted:[&_svg:not([class*='text-'])]:text-danger",
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
29
|
defaultVariants: {variant: "default"},
|
package/src/components/hero.tsx
CHANGED
|
@@ -22,23 +22,30 @@ import type * as React from "react";
|
|
|
22
22
|
*/
|
|
23
23
|
interface HeroProps extends Omit<React.ComponentProps<"section">, "children"> {
|
|
24
24
|
children?: React.ReactNode;
|
|
25
|
+
/**
|
|
26
|
+
* `center` (default): one centered column. `split`: from `lg`, a `HeroBody` on the left and a
|
|
27
|
+
* `HeroShowcase` on the right; below `lg` it falls back to the centered column and hides the showcase.
|
|
28
|
+
*/
|
|
29
|
+
layout?: "center" | "split";
|
|
25
30
|
/** Replaces the dot grid behind the content. `null` for none. */
|
|
26
31
|
background?: React.ReactNode;
|
|
27
32
|
/** Classes for the centered content column. */
|
|
28
33
|
contentClassName?: string;
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
function Hero({className, contentClassName, background, children, ...props}: HeroProps) {
|
|
36
|
+
function Hero({className, contentClassName, background, layout = "center", children, ...props}: HeroProps) {
|
|
32
37
|
return (
|
|
33
38
|
<section
|
|
34
39
|
data-slot="hero"
|
|
35
|
-
|
|
40
|
+
data-layout={layout}
|
|
41
|
+
className={cn("group/hero relative isolate overflow-hidden border-b border-border bg-muted/40", className)}
|
|
36
42
|
{...props}
|
|
37
43
|
>
|
|
38
44
|
{background === undefined ? <HeroDots /> : background}
|
|
39
45
|
<div
|
|
40
46
|
className={cn(
|
|
41
47
|
"relative mx-auto flex w-full max-w-(--kk-site-width) flex-col items-center gap-5 px-4 py-10 text-center md:px-6 md:py-14",
|
|
48
|
+
layout === "split" && "lg:grid lg:grid-cols-2 lg:gap-12 lg:text-left",
|
|
42
49
|
contentClassName,
|
|
43
50
|
)}
|
|
44
51
|
>
|
|
@@ -65,7 +72,13 @@ function HeroMedia({className, render, ...props}: useRender.ComponentProps<"div"
|
|
|
65
72
|
return useRender({
|
|
66
73
|
defaultTagName: "div",
|
|
67
74
|
props: mergeProps<"div">(
|
|
68
|
-
{
|
|
75
|
+
{
|
|
76
|
+
className: cn(
|
|
77
|
+
"flex items-center justify-center [&_svg]:shrink-0",
|
|
78
|
+
"lg:group-data-[layout=split]/hero:justify-start",
|
|
79
|
+
className,
|
|
80
|
+
),
|
|
81
|
+
},
|
|
69
82
|
props,
|
|
70
83
|
),
|
|
71
84
|
render,
|
|
@@ -77,7 +90,15 @@ function HeroMedia({className, render, ...props}: useRender.ComponentProps<"div"
|
|
|
77
90
|
function HeroEyebrow({className, render, ...props}: useRender.ComponentProps<"div">) {
|
|
78
91
|
return useRender({
|
|
79
92
|
defaultTagName: "div",
|
|
80
|
-
props: mergeProps<"div">(
|
|
93
|
+
props: mergeProps<"div">(
|
|
94
|
+
{
|
|
95
|
+
className: cn(
|
|
96
|
+
"flex flex-wrap items-center justify-center gap-2 lg:group-data-[layout=split]/hero:justify-start",
|
|
97
|
+
className,
|
|
98
|
+
),
|
|
99
|
+
},
|
|
100
|
+
props,
|
|
101
|
+
),
|
|
81
102
|
render,
|
|
82
103
|
state: {slot: "hero-eyebrow"},
|
|
83
104
|
});
|
|
@@ -91,6 +112,8 @@ function HeroTitle({className, render, ...props}: useRender.ComponentProps<"h1">
|
|
|
91
112
|
{
|
|
92
113
|
className: cn(
|
|
93
114
|
"max-w-4xl font-heading text-4xl font-semibold tracking-tight text-balance md:text-5xl xl:text-6xl",
|
|
115
|
+
// half the width beside a showcase: one step smaller
|
|
116
|
+
"xl:group-data-[layout=split]/hero:text-5xl",
|
|
94
117
|
className,
|
|
95
118
|
),
|
|
96
119
|
},
|
|
@@ -118,7 +141,15 @@ function HeroDescription({className, render, ...props}: useRender.ComponentProps
|
|
|
118
141
|
function HeroActions({className, render, ...props}: useRender.ComponentProps<"div">) {
|
|
119
142
|
return useRender({
|
|
120
143
|
defaultTagName: "div",
|
|
121
|
-
props: mergeProps<"div">(
|
|
144
|
+
props: mergeProps<"div">(
|
|
145
|
+
{
|
|
146
|
+
className: cn(
|
|
147
|
+
"flex flex-wrap items-center justify-center gap-2 lg:group-data-[layout=split]/hero:justify-start",
|
|
148
|
+
className,
|
|
149
|
+
),
|
|
150
|
+
},
|
|
151
|
+
props,
|
|
152
|
+
),
|
|
122
153
|
render,
|
|
123
154
|
state: {slot: "hero-actions"},
|
|
124
155
|
});
|
|
@@ -128,10 +159,49 @@ function HeroActions({className, render, ...props}: useRender.ComponentProps<"di
|
|
|
128
159
|
function HeroFooter({className, render, ...props}: useRender.ComponentProps<"div">) {
|
|
129
160
|
return useRender({
|
|
130
161
|
defaultTagName: "div",
|
|
131
|
-
props: mergeProps<"div">(
|
|
162
|
+
props: mergeProps<"div">(
|
|
163
|
+
{
|
|
164
|
+
className: cn(
|
|
165
|
+
"flex w-full flex-col items-center gap-3 lg:group-data-[layout=split]/hero:items-start",
|
|
166
|
+
className,
|
|
167
|
+
),
|
|
168
|
+
},
|
|
169
|
+
props,
|
|
170
|
+
),
|
|
132
171
|
render,
|
|
133
172
|
state: {slot: "hero-footer"},
|
|
134
173
|
});
|
|
135
174
|
}
|
|
136
175
|
|
|
137
|
-
|
|
176
|
+
/** The text column of a split hero: media, eyebrow, title, description, actions, footer. */
|
|
177
|
+
function HeroBody({className, render, ...props}: useRender.ComponentProps<"div">) {
|
|
178
|
+
return useRender({
|
|
179
|
+
defaultTagName: "div",
|
|
180
|
+
props: mergeProps<"div">(
|
|
181
|
+
{
|
|
182
|
+
className: cn(
|
|
183
|
+
"flex w-full min-w-0 flex-col items-center gap-5 lg:group-data-[layout=split]/hero:items-start",
|
|
184
|
+
className,
|
|
185
|
+
),
|
|
186
|
+
},
|
|
187
|
+
props,
|
|
188
|
+
),
|
|
189
|
+
render,
|
|
190
|
+
state: {slot: "hero-body"},
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The right column of a split hero: a carousel, a demo, a screenshot. Hidden below `lg`, where the hero
|
|
196
|
+
* is one centered column; give it a fixed height so heroes across the suite line up.
|
|
197
|
+
*/
|
|
198
|
+
function HeroShowcase({className, render, ...props}: useRender.ComponentProps<"div">) {
|
|
199
|
+
return useRender({
|
|
200
|
+
defaultTagName: "div",
|
|
201
|
+
props: mergeProps<"div">({className: cn("hidden w-full min-w-0 text-left lg:block", className)}, props),
|
|
202
|
+
render,
|
|
203
|
+
state: {slot: "hero-showcase"},
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export {Hero, HeroActions, HeroBody, HeroDescription, HeroEyebrow, HeroFooter, HeroMedia, HeroShowcase, HeroTitle};
|
|
@@ -152,6 +152,10 @@ function NavigationMenuLink({className, ...props}: NavigationMenuPrimitive.Link.
|
|
|
152
152
|
"transition-[color,background-color,border-color,box-shadow] duration-100 motion-reduce:transition-none",
|
|
153
153
|
"hover:bg-hover focus-visible:ring-3 focus-visible:ring-ring/50",
|
|
154
154
|
"data-active:bg-accent data-active:font-medium data-active:text-accent-foreground",
|
|
155
|
+
// current page (§7c): the sidebar's pill, on the bottom edge in the bar and on the left edge in a panel
|
|
156
|
+
"relative after:pointer-events-none after:absolute after:rounded-pill after:bg-primary-text after:opacity-0 data-active:after:opacity-100",
|
|
157
|
+
"in-data-[slot=navigation-menu-list]:after:inset-x-2.5 in-data-[slot=navigation-menu-list]:after:bottom-0 in-data-[slot=navigation-menu-list]:after:h-0.5",
|
|
158
|
+
"in-data-[slot=navigation-menu-content]:after:top-1.5 in-data-[slot=navigation-menu-content]:after:bottom-1.5 in-data-[slot=navigation-menu-content]:after:left-0 in-data-[slot=navigation-menu-content]:after:w-0.5",
|
|
155
159
|
"in-data-[slot=navigation-menu-list]:h-8 in-data-[slot=navigation-menu-list]:font-medium",
|
|
156
160
|
"in-data-[slot=navigation-menu-content]:rounded-md in-data-[slot=navigation-menu-content]:px-2 in-data-[slot=navigation-menu-content]:focus-visible:bg-accent in-data-[slot=navigation-menu-content]:focus-visible:text-accent-foreground in-data-[slot=navigation-menu-content]:focus-visible:ring-0",
|
|
157
161
|
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
|
|
@@ -10,7 +10,7 @@ import {Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle} from "@r
|
|
|
10
10
|
import {Skeleton} from "@repraze/kernelkit/components/skeleton";
|
|
11
11
|
import {Tooltip, TooltipContent, TooltipTrigger} from "@repraze/kernelkit/components/tooltip";
|
|
12
12
|
import {useIsMobile} from "@repraze/kernelkit/hooks/use-mobile";
|
|
13
|
-
import {focusRing} from "@repraze/kernelkit/lib/recipes";
|
|
13
|
+
import {focusRing, rowIndicator} from "@repraze/kernelkit/lib/recipes";
|
|
14
14
|
import {cva, type VariantProps} from "class-variance-authority";
|
|
15
15
|
import {cn} from "cn";
|
|
16
16
|
import {PanelLeftIcon} from "lucide-react";
|
|
@@ -482,7 +482,8 @@ const sidebarMenuButtonVariants = cva(
|
|
|
482
482
|
"hover:bg-hover data-popup-open:bg-hover",
|
|
483
483
|
"disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
|
|
484
484
|
// current row (GUIDELINES §7c): accent tint, foreground text, 2px accent indicator on the left edge
|
|
485
|
-
"relative
|
|
485
|
+
"relative data-active:after:opacity-100",
|
|
486
|
+
rowIndicator,
|
|
486
487
|
"data-active:bg-primary-tint data-active:font-medium data-active:text-foreground data-active:[&_svg:not([class*='text-'])]:text-primary-text",
|
|
487
488
|
"[&_svg]:size-4 [&_svg]:shrink-0 [&_svg:not([class*='text-'])]:text-muted-foreground [&>span:last-child]:truncate",
|
|
488
489
|
],
|