@jonmilner/ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/THIRD_PARTY_NOTICES.md +51 -0
  2. package/dist/AlertDialog/index.d.mts +21 -0
  3. package/dist/AlertDialog/index.mjs +29 -0
  4. package/dist/Badge/Badge.css +2 -0
  5. package/dist/Badge/Badge.css.mjs +24 -0
  6. package/dist/Badge/index.d.mts +11 -0
  7. package/dist/Badge/index.mjs +54 -0
  8. package/dist/Box/Box.css +2 -0
  9. package/dist/Box/Box.css.mjs +8 -0
  10. package/dist/Box/index.d.mts +10 -0
  11. package/dist/Box/index.mjs +15 -0
  12. package/dist/Button/Button.css +2 -0
  13. package/dist/Button/Button.css.mjs +25 -0
  14. package/dist/Button/index.d.mts +20 -0
  15. package/dist/Button/index.mjs +97 -0
  16. package/dist/Checkbox/Checkbox.css +2 -0
  17. package/dist/Checkbox/Checkbox.css.mjs +8 -0
  18. package/dist/Checkbox/index.d.mts +6 -0
  19. package/dist/Checkbox/index.mjs +45 -0
  20. package/dist/Chip/Chip.css +2 -0
  21. package/dist/Chip/Chip.css.mjs +17 -0
  22. package/dist/Chip/index.d.mts +13 -0
  23. package/dist/Chip/index.mjs +73 -0
  24. package/dist/Clickable/Clickable.css +2 -0
  25. package/dist/Clickable/Clickable.css.mjs +8 -0
  26. package/dist/Clickable/index.d.mts +13 -0
  27. package/dist/Clickable/index.mjs +28 -0
  28. package/dist/Dialog/Dialog.css +2 -0
  29. package/dist/Dialog/Dialog.css.d.mts +3 -0
  30. package/dist/Dialog/Dialog.css.mjs +12 -0
  31. package/dist/Dialog/client.d.mts +12 -0
  32. package/dist/Dialog/client.mjs +31 -0
  33. package/dist/Dialog/index.d.mts +30 -0
  34. package/dist/Dialog/index.mjs +85 -0
  35. package/dist/Field/Field.css +2 -0
  36. package/dist/Field/Field.css.mjs +8 -0
  37. package/dist/Field/client.mjs +26 -0
  38. package/dist/Field/index.d.mts +20 -0
  39. package/dist/Field/index.mjs +88 -0
  40. package/dist/Heading/Heading.css +2 -0
  41. package/dist/Heading/Heading.css.mjs +8 -0
  42. package/dist/Heading/index.d.mts +9 -0
  43. package/dist/Heading/index.mjs +27 -0
  44. package/dist/Icon/Icon.css +2 -0
  45. package/dist/Icon/Icon.css.mjs +17 -0
  46. package/dist/Icon/index.d.mts +12 -0
  47. package/dist/Icon/index.mjs +24 -0
  48. package/dist/IconButton/IconButton.css +2 -0
  49. package/dist/IconButton/IconButton.css.mjs +24 -0
  50. package/dist/IconButton/index.d.mts +17 -0
  51. package/dist/IconButton/index.mjs +25 -0
  52. package/dist/Inline/Inline.css +2 -0
  53. package/dist/Inline/Inline.css.mjs +8 -0
  54. package/dist/Inline/index.d.mts +15 -0
  55. package/dist/Inline/index.mjs +17 -0
  56. package/dist/Menu/Menu.css +2 -0
  57. package/dist/Menu/Menu.css.mjs +8 -0
  58. package/dist/Menu/client.d.mts +9 -0
  59. package/dist/Menu/client.mjs +27 -0
  60. package/dist/Menu/index.d.mts +34 -0
  61. package/dist/Menu/index.mjs +107 -0
  62. package/dist/MultiSelect/MultiSelect.css +2 -0
  63. package/dist/MultiSelect/MultiSelect.css.mjs +8 -0
  64. package/dist/MultiSelect/client.d.mts +8 -0
  65. package/dist/MultiSelect/client.mjs +93 -0
  66. package/dist/MultiSelect/index.d.mts +23 -0
  67. package/dist/MultiSelect/index.mjs +75 -0
  68. package/dist/SearchField/SearchField.css +2 -0
  69. package/dist/SearchField/SearchField.css.mjs +27 -0
  70. package/dist/SearchField/client.mjs +71 -0
  71. package/dist/SearchField/index.d.mts +22 -0
  72. package/dist/SearchField/index.mjs +35 -0
  73. package/dist/Stack/Stack.css +2 -0
  74. package/dist/Stack/Stack.css.mjs +8 -0
  75. package/dist/Stack/index.d.mts +15 -0
  76. package/dist/Stack/index.mjs +15 -0
  77. package/dist/Tabs/Tabs.css +2 -0
  78. package/dist/Tabs/Tabs.css.mjs +8 -0
  79. package/dist/Tabs/index.d.mts +20 -0
  80. package/dist/Tabs/index.mjs +88 -0
  81. package/dist/Tag/Tag.css +2 -0
  82. package/dist/Tag/Tag.css.mjs +17 -0
  83. package/dist/Tag/index.d.mts +13 -0
  84. package/dist/Tag/index.mjs +82 -0
  85. package/dist/Text/Text.css +2 -0
  86. package/dist/Text/Text.css.mjs +32 -0
  87. package/dist/Text/index.d.mts +18 -0
  88. package/dist/Text/index.mjs +25 -0
  89. package/dist/Toast/Toast.css +2 -0
  90. package/dist/Toast/Toast.css.mjs +18 -0
  91. package/dist/Toast/client.d.mts +46 -0
  92. package/dist/Toast/client.mjs +219 -0
  93. package/dist/Toast/index.d.mts +7 -0
  94. package/dist/Toast/index.mjs +5 -0
  95. package/dist/base.css +6 -0
  96. package/dist/brands/brand.d.mts +9 -0
  97. package/dist/brands/brand.mjs +4 -0
  98. package/dist/brands/check-fonts.mjs +15 -0
  99. package/dist/brands/default.d.mts +4 -0
  100. package/dist/brands/default.mjs +74 -0
  101. package/dist/brands/font.d.mts +17 -0
  102. package/dist/brands/font.mjs +35 -0
  103. package/dist/brands/forced-colors.mjs +18 -0
  104. package/dist/brands/index.d.mts +8 -0
  105. package/dist/brands/index.mjs +5 -0
  106. package/dist/brands/metrics.mjs +40 -0
  107. package/dist/contrast/color.d.mts +3 -0
  108. package/dist/contrast/color.mjs +222 -0
  109. package/dist/contrast/contrast.d.mts +18 -0
  110. package/dist/contrast/contrast.mjs +52 -0
  111. package/dist/contrast/mixes.mjs +33 -0
  112. package/dist/docs/AlertDialog.md +113 -0
  113. package/dist/docs/Badge.md +76 -0
  114. package/dist/docs/Box.md +74 -0
  115. package/dist/docs/Button.md +98 -0
  116. package/dist/docs/Checkbox.md +107 -0
  117. package/dist/docs/Chip.md +92 -0
  118. package/dist/docs/Clickable.md +82 -0
  119. package/dist/docs/Dialog.md +166 -0
  120. package/dist/docs/Field.md +143 -0
  121. package/dist/docs/Heading.md +69 -0
  122. package/dist/docs/Icon.md +116 -0
  123. package/dist/docs/IconButton.md +83 -0
  124. package/dist/docs/Inline.md +79 -0
  125. package/dist/docs/Menu.md +181 -0
  126. package/dist/docs/MultiSelect.md +120 -0
  127. package/dist/docs/SearchField.md +106 -0
  128. package/dist/docs/Stack.md +79 -0
  129. package/dist/docs/Tabs.md +130 -0
  130. package/dist/docs/Tag.md +97 -0
  131. package/dist/docs/Text.md +90 -0
  132. package/dist/docs/Toast.md +115 -0
  133. package/dist/docs/llms.txt +33 -0
  134. package/dist/docs/manifest.json +2632 -0
  135. package/dist/docs/manifest.schema.json +96 -0
  136. package/dist/docs/migrations/README.md +27 -0
  137. package/dist/docs/theming.md +59 -0
  138. package/dist/icons/ArrowLeftIcon.d.mts +4 -0
  139. package/dist/icons/ArrowLeftIcon.mjs +11 -0
  140. package/dist/icons/ArrowRightIcon.d.mts +4 -0
  141. package/dist/icons/ArrowRightIcon.mjs +11 -0
  142. package/dist/icons/CheckIcon.d.mts +4 -0
  143. package/dist/icons/CheckIcon.mjs +11 -0
  144. package/dist/icons/ChevronDownIcon.d.mts +4 -0
  145. package/dist/icons/ChevronDownIcon.mjs +11 -0
  146. package/dist/icons/ChevronRightIcon.d.mts +4 -0
  147. package/dist/icons/ChevronRightIcon.mjs +11 -0
  148. package/dist/icons/CircleAlertIcon.d.mts +4 -0
  149. package/dist/icons/CircleAlertIcon.mjs +15 -0
  150. package/dist/icons/CircleCheckIcon.d.mts +4 -0
  151. package/dist/icons/CircleCheckIcon.mjs +15 -0
  152. package/dist/icons/CircleDotIcon.d.mts +4 -0
  153. package/dist/icons/CircleDotIcon.mjs +19 -0
  154. package/dist/icons/CircleSlashIcon.d.mts +4 -0
  155. package/dist/icons/CircleSlashIcon.mjs +15 -0
  156. package/dist/icons/GitMergeIcon.d.mts +4 -0
  157. package/dist/icons/GitMergeIcon.mjs +23 -0
  158. package/dist/icons/GitPullRequestClosedIcon.d.mts +4 -0
  159. package/dist/icons/GitPullRequestClosedIcon.mjs +23 -0
  160. package/dist/icons/GitPullRequestDraftIcon.d.mts +4 -0
  161. package/dist/icons/GitPullRequestDraftIcon.mjs +23 -0
  162. package/dist/icons/GitPullRequestIcon.d.mts +4 -0
  163. package/dist/icons/GitPullRequestIcon.mjs +23 -0
  164. package/dist/icons/InboxIcon.d.mts +4 -0
  165. package/dist/icons/InboxIcon.mjs +11 -0
  166. package/dist/icons/InfoIcon.d.mts +4 -0
  167. package/dist/icons/InfoIcon.mjs +15 -0
  168. package/dist/icons/LoaderCircleIcon.d.mts +4 -0
  169. package/dist/icons/LoaderCircleIcon.mjs +11 -0
  170. package/dist/icons/RefreshCwIcon.d.mts +4 -0
  171. package/dist/icons/RefreshCwIcon.mjs +15 -0
  172. package/dist/icons/SearchIcon.d.mts +4 -0
  173. package/dist/icons/SearchIcon.mjs +15 -0
  174. package/dist/icons/SettingsIcon.d.mts +4 -0
  175. package/dist/icons/SettingsIcon.mjs +15 -0
  176. package/dist/icons/XIcon.d.mts +4 -0
  177. package/dist/icons/XIcon.mjs +11 -0
  178. package/dist/icons/index.d.mts +25 -0
  179. package/dist/icons/index.mjs +45 -0
  180. package/dist/index.d.mts +27 -0
  181. package/dist/index.mjs +25 -0
  182. package/dist/popup/client.d.mts +9 -0
  183. package/dist/popup/client.mjs +31 -0
  184. package/dist/styles/atoms.css +2 -0
  185. package/dist/styles/atoms.css.d.mts +219 -0
  186. package/dist/styles/atoms.css.mjs +2579 -0
  187. package/dist/styles/button-fills.mjs +17 -0
  188. package/dist/styles/highlight.mjs +8 -0
  189. package/dist/styles/hover-tint.mjs +4 -0
  190. package/dist/styles/join.mjs +4 -0
  191. package/dist/styles/layers.css +2 -0
  192. package/dist/styles/part-props.d.mts +8 -0
  193. package/dist/styles/split-style-props.mjs +9 -0
  194. package/dist/testing/index.d.mts +4 -0
  195. package/dist/testing/index.mjs +3 -0
  196. package/dist/testing/motion.d.mts +22 -0
  197. package/dist/testing/motion.mjs +49 -0
  198. package/dist/theme/FontCheck.mjs +11 -0
  199. package/dist/theme/ThemeProvider.d.mts +15 -0
  200. package/dist/theme/ThemeProvider.mjs +23 -0
  201. package/dist/theme/define-theme.d.mts +9 -0
  202. package/dist/theme/define-theme.mjs +84 -0
  203. package/dist/theme/use-theme-container.mjs +15 -0
  204. package/dist/tokens/contract.d.mts +105 -0
  205. package/dist/tokens/contract.mjs +17 -0
  206. package/dist/tokens/index.d.mts +2 -0
  207. package/dist/tokens/index.mjs +1 -0
  208. package/dist/tokens/roles.d.mts +6 -0
  209. package/dist/tokens/roles.mjs +24 -0
  210. package/dist/tokens/scales.d.mts +95 -0
  211. package/dist/tokens/scales.mjs +98 -0
  212. package/dist/types.d.mts +3 -0
  213. package/package.json +159 -3
  214. package/README.md +0 -3
@@ -0,0 +1,17 @@
1
+ //#region src/styles/button-fills.ts
2
+ var e = {
3
+ primary: {
4
+ backgroundColor: "accent",
5
+ color: "accentFg"
6
+ },
7
+ secondary: {
8
+ backgroundColor: "bg",
9
+ color: "fg"
10
+ },
11
+ danger: {
12
+ backgroundColor: "danger",
13
+ color: "dangerFg"
14
+ }
15
+ };
16
+ //#endregion
17
+ export { e as fills };
@@ -0,0 +1,8 @@
1
+ //#region src/styles/highlight.ts
2
+ var e = (e) => `light-dark(${e.bgMuted}, color-mix(in srgb, ${e.fg} 10%, ${e.bgRaised}))`, t = [
3
+ "fg",
4
+ "fgMuted",
5
+ "danger"
6
+ ];
7
+ //#endregion
8
+ export { e as highlightFill, t as highlightText };
@@ -0,0 +1,4 @@
1
+ //#region src/styles/hover-tint.ts
2
+ var e = (e, t) => `color-mix(in srgb, ${e} 15%, ${t})`;
3
+ //#endregion
4
+ export { e as hoverFill };
@@ -0,0 +1,4 @@
1
+ //#region src/styles/join.ts
2
+ var e = (...e) => e.filter(Boolean).join(" ");
3
+ //#endregion
4
+ export { e as join };
@@ -0,0 +1,2 @@
1
+ @layer tokens, reset, atoms, components.box, components.checkbox, components.clickable, components.icon, components.icon-button, components.inline, components.stack, components.text, components.badge, components.button, components.chip, components.field, components.heading, components.dialog, components.alert-dialog, components.menu, components.multiselect, components.search-field, components.tabs, components.tag, components.toast;
2
+ @layer tokens,reset,atoms,components;
@@ -0,0 +1,8 @@
1
+ import { StyleProps } from "../Box/index.mjs";
2
+ import { CSSProperties } from "react";
3
+ //#region src/styles/part-props.d.ts
4
+ export type PartProps<P> = StyleProps & Omit<P, "render" | "className" | "style" | keyof StyleProps> & {
5
+ className?: string;
6
+ style?: CSSProperties;
7
+ };
8
+ //#endregion
@@ -0,0 +1,9 @@
1
+ import { sprinkles as e } from "./atoms.css.mjs";
2
+ //#region src/styles/split-style-props.ts
3
+ function t(t) {
4
+ let n = {}, r = {};
5
+ for (let [i, a] of Object.entries(t)) (e.properties.has(i) ? n : r)[i] = a;
6
+ return [n, r];
7
+ }
8
+ //#endregion
9
+ export { t as splitStyleProps };
@@ -0,0 +1,4 @@
1
+ import { Mode } from "../contrast/color.mjs";
2
+ import { ContrastFailure, ContrastPair, checkContrast, contrastPairs, contrastRatio } from "../contrast/contrast.mjs";
3
+ import { MediaEmulator, MotionLocator, MotionStyle, MotionTarget, emulateReducedMotion, expectCrossfadeOnly, expectNoMotion, readMotionStyle } from "./motion.mjs";
4
+ export { type ContrastFailure, type ContrastPair, type MediaEmulator, type Mode, type MotionLocator, type MotionStyle, type MotionTarget, checkContrast, contrastPairs, contrastRatio, emulateReducedMotion, expectCrossfadeOnly, expectNoMotion, readMotionStyle };
@@ -0,0 +1,3 @@
1
+ import { checkContrast as e, contrastPairs as t, contrastRatio as n } from "../contrast/contrast.mjs";
2
+ import { emulateReducedMotion as r, expectCrossfadeOnly as i, expectNoMotion as a, readMotionStyle as o } from "./motion.mjs";
3
+ export { e as checkContrast, t as contrastPairs, n as contrastRatio, r as emulateReducedMotion, i as expectCrossfadeOnly, a as expectNoMotion, o as readMotionStyle };
@@ -0,0 +1,22 @@
1
+ //#region src/testing/motion.d.ts
2
+ export interface MediaEmulator {
3
+ emulateMedia(options: {
4
+ reducedMotion: "reduce" | "no-preference" | null;
5
+ }): Promise<void>;
6
+ }
7
+ export interface MotionLocator {
8
+ evaluate<R>(fn: (el: Element) => R): Promise<R>;
9
+ }
10
+ export type MotionTarget = Element | MotionLocator;
11
+ export interface MotionStyle {
12
+ displaced: string[];
13
+ transitions: {
14
+ ms: number;
15
+ property: string;
16
+ }[];
17
+ }
18
+ export declare function emulateReducedMotion(page: MediaEmulator): Promise<() => Promise<void>>;
19
+ export declare const readMotionStyle: (el: Element) => MotionStyle;
20
+ export declare function expectNoMotion(target: MotionTarget): Promise<void>;
21
+ export declare function expectCrossfadeOnly(target: MotionTarget): Promise<void>;
22
+ //#endregion
@@ -0,0 +1,49 @@
1
+ //#region src/testing/motion.ts
2
+ async function e(e) {
3
+ return await e.emulateMedia({ reducedMotion: "reduce" }), () => e.emulateMedia({ reducedMotion: null });
4
+ }
5
+ var t = (e) => {
6
+ let t = getComputedStyle(e), n = (e) => (e.match(/-?[\d.]+(?:e[-+]?\d+)?/g) ?? []).map(Number), r = (e, t) => Math.abs(e - t) < 1e-6, i = Object.entries({
7
+ translate: (e) => n(e.replace(/-?[\d.]+%/g, "")).every((e) => r(e, 0)),
8
+ scale: (e) => n(e).every((e) => r(e, 1)),
9
+ rotate: (e) => r(n(e).at(-1) ?? 0, 0),
10
+ transform: (e) => {
11
+ let t = n(e.replace(/^matrix(3d)?/, "")), i = t.length === 16 ? [
12
+ 0,
13
+ 5,
14
+ 10,
15
+ 15
16
+ ] : [0, 3];
17
+ return t.every((e, t) => r(e, +!!i.includes(t)));
18
+ }
19
+ }).map(([e, n]) => [
20
+ e,
21
+ t.getPropertyValue(e),
22
+ n
23
+ ]).filter(([, e, t]) => e !== "none" && !t(e)).map(([e, t]) => `${e}: ${t}`), a = (e) => parseFloat(e) * (e.endsWith("ms") ? 1 : 1e3), o = t.transitionProperty.split(",").map((e) => e.trim()), s = t.transitionDuration.split(",").map((e) => a(e.trim()));
24
+ return {
25
+ displaced: i,
26
+ transitions: o.map((e, t) => ({
27
+ property: e,
28
+ ms: s[t % s.length] ?? 0
29
+ }))
30
+ };
31
+ };
32
+ function n(e) {
33
+ return "evaluate" in e ? e.evaluate(t) : Promise.resolve(t(e));
34
+ }
35
+ function r({ displaced: e }) {
36
+ if (e.length > 0) throw Error(`Expected no motion, got ${e.join("; ")}`);
37
+ }
38
+ async function i(e) {
39
+ r(await n(e));
40
+ }
41
+ async function a(e) {
42
+ let t = await n(e);
43
+ if (r(t), !t.transitions.some(({ property: e, ms: t }) => (e === "opacity" || e === "all") && t > 0)) {
44
+ let e = t.transitions.map(({ property: e, ms: t }) => `${e} ${t}ms`).join(", ");
45
+ throw Error(`Expected an opacity transition over 0ms, got ${e}`);
46
+ }
47
+ }
48
+ //#endregion
49
+ export { e as emulateReducedMotion, a as expectCrossfadeOnly, i as expectNoMotion, t as readMotionStyle };
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import { checkFonts as e } from "../brands/check-fonts.mjs";
3
+ import { useEffect as t } from "react";
4
+ //#region src/theme/FontCheck.tsx
5
+ function n({ font: n }) {
6
+ return t(() => {
7
+ e({ font: n });
8
+ }, [n]), null;
9
+ }
10
+ //#endregion
11
+ export { n as FontCheck };
@@ -0,0 +1,15 @@
1
+ import { presets } from "../brands/index.mjs";
2
+ import { Theme } from "./define-theme.mjs";
3
+ import { ComponentPropsWithRef } from "react";
4
+ //#region src/theme/ThemeProvider.d.ts
5
+ export type ThemeProviderProps = ComponentPropsWithRef<"div"> & {
6
+ mode?: "light" | "dark" | "system";
7
+ } & ({
8
+ brand?: keyof typeof presets;
9
+ theme?: undefined;
10
+ } | {
11
+ brand?: undefined;
12
+ theme: Theme;
13
+ });
14
+ export declare function ThemeProvider({ brand, mode, theme, children, ...props }: ThemeProviderProps): import("react").JSX.Element;
15
+ //#endregion
@@ -0,0 +1,23 @@
1
+ import { presets as e } from "../brands/index.mjs";
2
+ import { FontCheck as t } from "./FontCheck.mjs";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/theme/ThemeProvider.tsx
5
+ function i({ brand: i = "default", mode: a = "system", theme: o, children: s, ...c }) {
6
+ let l = o?.brand.name ?? i, u = o?.brand ?? e[i];
7
+ return /* @__PURE__ */ r("div", {
8
+ ...c,
9
+ "data-brand": l,
10
+ "data-mode": a,
11
+ children: [
12
+ o && /* @__PURE__ */ n("style", {
13
+ href: o.href,
14
+ precedence: "ui-theme",
15
+ children: o.css
16
+ }),
17
+ process.env.NODE_ENV !== "production" && u && /* @__PURE__ */ n(t, { font: u.font }),
18
+ s
19
+ ]
20
+ });
21
+ }
22
+ //#endregion
23
+ export { i as ThemeProvider };
@@ -0,0 +1,9 @@
1
+ import { Brand } from "../brands/brand.mjs";
2
+ //#region src/theme/define-theme.d.ts
3
+ export interface Theme {
4
+ readonly brand: Brand;
5
+ readonly href: string;
6
+ readonly css: string;
7
+ }
8
+ export declare function defineTheme(brand: Brand): Theme;
9
+ //#endregion
@@ -0,0 +1,84 @@
1
+ import { fallbackFaces as e, fallbackFamily as t, fontStack as n, fontTrim as r } from "../brands/font.mjs";
2
+ import { forcedColors as i } from "../brands/forced-colors.mjs";
3
+ import { presets as a } from "../brands/index.mjs";
4
+ import { resolveColor as o } from "../contrast/color.mjs";
5
+ import { checkContrast as s, contrastPairs as c } from "../contrast/contrast.mjs";
6
+ import { checkMixes as l, contrastMixes as u } from "../contrast/mixes.mjs";
7
+ import { colorRoles as d, fontRoles as f } from "../tokens/roles.mjs";
8
+ import { vars as p } from "../tokens/contract.mjs";
9
+ //#region src/theme/define-theme.ts
10
+ var m = (e) => e.slice(4, -1), h = (e) => e.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`), g = (e, t) => `${e} {\n${t.map(([e, t]) => ` ${e}: ${t};\n`).join("")}}`;
11
+ function _(o) {
12
+ let s = (e) => {
13
+ throw Error(`defineTheme("${o.name}"): ${e}`);
14
+ };
15
+ /^[a-z][\w-]*$/i.test(o.name) || s("the name must be a CSS identifier");
16
+ for (let [e, t] of Object.entries(o.color)) v.test(t) && s(`color.${e} must be a single color value`);
17
+ for (let [e, { metrics: t, fallback: n }] of Object.entries(o.font)) for (let r of [t, n].flatMap((e) => [
18
+ e.familyName,
19
+ e.fullName,
20
+ e.postscriptName
21
+ ])) r !== void 0 && (v.test(r) || /["'\n]/.test(r)) && s(`font.${e} has a font name with quotes or CSS syntax: ${r}`);
22
+ process.env.NODE_ENV !== "production" && C(o, s);
23
+ let c = `[data-brand="${o.name}"]`, l = Object.values(o.font), u = Object.values(a).flatMap((e) => Object.values(e.font)), _;
24
+ try {
25
+ _ = e([...u, ...l]);
26
+ } catch (e) {
27
+ return s(e.message);
28
+ }
29
+ let b = new Set(l.map(t));
30
+ for (let e of u) b.delete(t(e));
31
+ let x = [
32
+ ...[..._].filter(([e]) => b.has(e)).map(([e, t]) => g("@font-face", [["font-family", `"${e}"`], ...Object.entries(t).map(([e, t]) => [h(e), t])])),
33
+ g(c, [...d.map((e) => [m(p.color[e]), o.color[e]]), ...f.flatMap((e) => {
34
+ let t = r(o.font[e].metrics);
35
+ return [
36
+ [m(p.font[e]), n(o.font[e])],
37
+ [m(p.fontTrim[e].cap), t.cap],
38
+ [m(p.fontTrim[e].baseline), t.baseline]
39
+ ];
40
+ })]),
41
+ `@media (forced-colors: active) {\n${g(c, d.map((e) => [m(p.color[e]), i[e]])).split("\n").map((e) => ` ${e}`).join("\n")}\n}`
42
+ ].join("\n");
43
+ return {
44
+ brand: o,
45
+ href: `ui-theme-${o.name}-${y(x)}`,
46
+ css: x
47
+ };
48
+ }
49
+ var v = /[;{}<>\\!]|\/\*/;
50
+ function y(e) {
51
+ let t = 2166136261;
52
+ for (let n = 0; n < e.length; n++) t = Math.imul(t ^ e.charCodeAt(n), 16777619);
53
+ return (t >>> 0).toString(36);
54
+ }
55
+ var b = /var\(\s*--color-([a-z-]+)\s*\)/g, x = new Map(d.map((e) => [h(e), e])), S = new Set(c.map((e) => e.bg));
56
+ function C(e, t) {
57
+ let n = (r, i = []) => (i.includes(r) && t(`color.${r} references itself through var()`), e.color[r].replace(b, (e, t) => {
58
+ let a = x.get(t);
59
+ return a ? n(a, [...i, r]) : e;
60
+ })), r = Object.fromEntries(d.map((e) => [e, n(e)]));
61
+ for (let n of d) {
62
+ r[n].includes("var(") && t(`color.${n} is ${e.color[n]}: the contrast check needs literal colors, so use var() only to reference another color role`);
63
+ for (let i of ["light", "dark"]) {
64
+ let a;
65
+ try {
66
+ ({alpha: a} = o(r[n], i));
67
+ } catch (r) {
68
+ return t(`color.${n} is ${e.color[n]}, which the contrast check cannot resolve (${r.message}). Use hex, rgb(), oklab(), oklch(), color-mix() or light-dark(); named colors other than white, black and transparent are not supported`);
69
+ }
70
+ a < 1 && S.has(n) && t(`color.${n} is translucent in ${i} mode, but it is a background in a contrast pair and must be opaque`);
71
+ }
72
+ }
73
+ for (let { name: e, fill: n } of u) for (let i of ["light", "dark"]) o(n(r), i).alpha < 1 && t(`the ${e} is translucent in ${i} mode: the roles it mixes must be opaque`);
74
+ let i = {
75
+ ...e,
76
+ color: r
77
+ }, a = s(i), c = [...a, ...l(i).filter((e) => !a.some((t) => t.fg === e.fg && t.mode === e.mode && t.ratio === e.ratio)).map(({ mix: e, ...t }) => ({
78
+ ...t,
79
+ bg: `the ${e}`
80
+ }))].toSorted((e, t) => e.mode === t.mode ? 0 : e.mode === "light" ? -1 : 1);
81
+ c.length > 0 && t(`fails WCAG AA contrast:\n${c.map(({ fg: e, bg: t, mode: n, ratio: r, min: i }) => ` ${e} on ${t} (${n}): ${r.toFixed(2)}, needs ${i}`).join("\n")}`);
82
+ }
83
+ //#endregion
84
+ export { _ as defineTheme };
@@ -0,0 +1,15 @@
1
+ import { useCallback as e, useMemo as t, useRef as n } from "react";
2
+ //#region src/theme/use-theme-container.ts
3
+ function r() {
4
+ let r = n(null), i = e((e) => {
5
+ r.current = e;
6
+ }, []);
7
+ return t(() => ({
8
+ container: { get current() {
9
+ return r.current?.closest("[data-brand]") ?? null;
10
+ } },
11
+ ref: i
12
+ }), [i]);
13
+ }
14
+ //#endregion
15
+ export { r as useThemeContainer };
@@ -0,0 +1,105 @@
1
+ //#region src/tokens/contract.d.ts
2
+ type CssVar = `var(--${string})`;
3
+ export type Contract<T> = { readonly [K in keyof T]: T[K] extends string ? CssVar : Contract<T[K]>; };
4
+ export declare const contract: {
5
+ space: {
6
+ 0: string;
7
+ 1: string;
8
+ 12: string;
9
+ 16: string;
10
+ 2: string;
11
+ 20: string;
12
+ 24: string;
13
+ 32: string;
14
+ 4: string;
15
+ 40: string;
16
+ 48: string;
17
+ 6: string;
18
+ 64: string;
19
+ 8: string;
20
+ 80: string;
21
+ 96: string;
22
+ };
23
+ size: {
24
+ xs: string;
25
+ sm: string;
26
+ med: string;
27
+ lg: string;
28
+ xl: string;
29
+ };
30
+ radius: {
31
+ none: string;
32
+ sm: string;
33
+ med: string;
34
+ lg: string;
35
+ xl: string;
36
+ full: string;
37
+ };
38
+ fontSize: {
39
+ xs: string;
40
+ sm: string;
41
+ med: string;
42
+ lg: string;
43
+ xl: string;
44
+ "2xl": string;
45
+ "3xl": string;
46
+ "4xl": string;
47
+ };
48
+ fontWeight: {
49
+ regular: string;
50
+ medium: string;
51
+ semibold: string;
52
+ bold: string;
53
+ };
54
+ lineHeight: {
55
+ sm: string;
56
+ med: string;
57
+ lg: string;
58
+ };
59
+ zIndex: {
60
+ base: string;
61
+ raised: string;
62
+ dropdown: string;
63
+ sticky: string;
64
+ overlay: string;
65
+ modal: string;
66
+ popover: string;
67
+ toast: string;
68
+ tooltip: string;
69
+ };
70
+ duration: {
71
+ fast: string;
72
+ med: string;
73
+ slow: string;
74
+ };
75
+ easing: {
76
+ standard: string;
77
+ enter: string;
78
+ exit: string;
79
+ };
80
+ distance: {
81
+ sm: string;
82
+ med: string;
83
+ lg: string;
84
+ };
85
+ scale: {
86
+ sm: string;
87
+ med: string;
88
+ lg: string;
89
+ };
90
+ dir: string;
91
+ shadow: {
92
+ sm: string;
93
+ med: string;
94
+ lg: string;
95
+ };
96
+ color: Record<"accent" | "accentFg" | "bg" | "bgMuted" | "bgRaised" | "border" | "borderStrong" | "danger" | "dangerFg" | "fg" | "fgMuted" | "focus" | "shadow", string>;
97
+ font: Record<"body" | "display" | "heading" | "label" | "mono", string>;
98
+ fontTrim: Record<"body" | "display" | "heading" | "label" | "mono", {
99
+ cap: string;
100
+ baseline: string;
101
+ }>;
102
+ };
103
+ export declare const vars: Contract<typeof contract>;
104
+ //#endregion
105
+ export {};
@@ -0,0 +1,17 @@
1
+ import { tokens as e } from "./scales.mjs";
2
+ import { colorRoles as t, fontRoles as n } from "./roles.mjs";
3
+ //#region src/tokens/contract.ts
4
+ function r(e, t) {
5
+ return typeof e == "string" ? `var(--${t.join("-").replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`)})` : Object.fromEntries(Object.entries(e).map(([e, n]) => [e, r(n, [...t, e])]));
6
+ }
7
+ var i = (e, t) => Object.fromEntries(e.map((e) => [e, t])), a = {
8
+ ...e,
9
+ color: i(t, ""),
10
+ font: i(n, ""),
11
+ fontTrim: i(n, {
12
+ cap: "",
13
+ baseline: ""
14
+ })
15
+ }, o = r(a, []);
16
+ //#endregion
17
+ export { a as contract, o as vars };
@@ -0,0 +1,2 @@
1
+ import { vars } from "./contract.mjs";
2
+ export { vars };
@@ -0,0 +1 @@
1
+ export { vars } from "./contract.mjs";
@@ -0,0 +1,6 @@
1
+ //#region src/tokens/roles.d.ts
2
+ export declare const colorRoles: readonly ["bg", "bgMuted", "bgRaised", "fg", "fgMuted", "border", "borderStrong", "accent", "accentFg", "danger", "dangerFg", "focus", "shadow"];
3
+ export type ColorRole = (typeof colorRoles)[number];
4
+ export declare const fontRoles: readonly ["body", "heading", "display", "label", "mono"];
5
+ export type FontRole = (typeof fontRoles)[number];
6
+ //#endregion
@@ -0,0 +1,24 @@
1
+ //#region src/tokens/roles.ts
2
+ var e = [
3
+ "bg",
4
+ "bgMuted",
5
+ "bgRaised",
6
+ "fg",
7
+ "fgMuted",
8
+ "border",
9
+ "borderStrong",
10
+ "accent",
11
+ "accentFg",
12
+ "danger",
13
+ "dangerFg",
14
+ "focus",
15
+ "shadow"
16
+ ], t = [
17
+ "body",
18
+ "heading",
19
+ "display",
20
+ "label",
21
+ "mono"
22
+ ];
23
+ //#endregion
24
+ export { e as colorRoles, t as fontRoles };
@@ -0,0 +1,95 @@
1
+ //#region src/tokens/scales.d.ts
2
+ export declare const tokens: {
3
+ space: {
4
+ 0: string;
5
+ 1: string;
6
+ 12: string;
7
+ 16: string;
8
+ 2: string;
9
+ 20: string;
10
+ 24: string;
11
+ 32: string;
12
+ 4: string;
13
+ 40: string;
14
+ 48: string;
15
+ 6: string;
16
+ 64: string;
17
+ 8: string;
18
+ 80: string;
19
+ 96: string;
20
+ };
21
+ size: {
22
+ xs: string;
23
+ sm: string;
24
+ med: string;
25
+ lg: string;
26
+ xl: string;
27
+ };
28
+ radius: {
29
+ none: string;
30
+ sm: string;
31
+ med: string;
32
+ lg: string;
33
+ xl: string;
34
+ full: string;
35
+ };
36
+ fontSize: {
37
+ xs: string;
38
+ sm: string;
39
+ med: string;
40
+ lg: string;
41
+ xl: string;
42
+ "2xl": string;
43
+ "3xl": string;
44
+ "4xl": string;
45
+ };
46
+ fontWeight: {
47
+ regular: string;
48
+ medium: string;
49
+ semibold: string;
50
+ bold: string;
51
+ };
52
+ lineHeight: {
53
+ sm: string;
54
+ med: string;
55
+ lg: string;
56
+ };
57
+ zIndex: {
58
+ base: string;
59
+ raised: string;
60
+ dropdown: string;
61
+ sticky: string;
62
+ overlay: string;
63
+ modal: string;
64
+ popover: string;
65
+ toast: string;
66
+ tooltip: string;
67
+ };
68
+ duration: {
69
+ fast: string;
70
+ med: string;
71
+ slow: string;
72
+ };
73
+ easing: {
74
+ standard: string;
75
+ enter: string;
76
+ exit: string;
77
+ };
78
+ distance: {
79
+ sm: string;
80
+ med: string;
81
+ lg: string;
82
+ };
83
+ scale: {
84
+ sm: string;
85
+ med: string;
86
+ lg: string;
87
+ };
88
+ dir: string;
89
+ shadow: {
90
+ sm: string;
91
+ med: string;
92
+ lg: string;
93
+ };
94
+ };
95
+ //#endregion
@@ -0,0 +1,98 @@
1
+ //#region src/tokens/scales.ts
2
+ var e = (e) => `${e / 16}rem`, t = Object.fromEntries([
3
+ 0,
4
+ 1,
5
+ 2,
6
+ 4,
7
+ 6,
8
+ 8,
9
+ 12,
10
+ 16,
11
+ 20,
12
+ 24,
13
+ 32,
14
+ 40,
15
+ 48,
16
+ 64,
17
+ 80,
18
+ 96
19
+ ].map((t) => [String(t), e(t)])), n = {
20
+ xs: e(24),
21
+ sm: e(32),
22
+ med: e(40),
23
+ lg: e(48),
24
+ xl: e(56)
25
+ }, r = {
26
+ none: "0",
27
+ sm: e(4),
28
+ med: e(8),
29
+ lg: e(12),
30
+ xl: e(16),
31
+ full: "9999px"
32
+ }, i = {
33
+ xs: e(12),
34
+ sm: e(14),
35
+ med: e(16),
36
+ lg: e(18),
37
+ xl: e(20),
38
+ "2xl": e(24),
39
+ "3xl": e(30),
40
+ "4xl": e(36)
41
+ }, a = {
42
+ regular: "400",
43
+ medium: "500",
44
+ semibold: "600",
45
+ bold: "700"
46
+ }, o = {
47
+ sm: "1.25",
48
+ med: "1.5",
49
+ lg: "1.75"
50
+ }, s = {
51
+ base: "0",
52
+ raised: "1",
53
+ dropdown: "1000",
54
+ sticky: "1100",
55
+ overlay: "1200",
56
+ modal: "1300",
57
+ popover: "1400",
58
+ toast: "1500",
59
+ tooltip: "1600"
60
+ }, c = {
61
+ fast: "120ms",
62
+ med: "200ms",
63
+ slow: "320ms"
64
+ }, l = {
65
+ standard: "cubic-bezier(0.2, 0, 0, 1)",
66
+ enter: "cubic-bezier(0, 0, 0, 1)",
67
+ exit: "cubic-bezier(0.3, 0, 1, 1)"
68
+ }, u = {
69
+ sm: e(4),
70
+ med: e(8),
71
+ lg: e(16)
72
+ }, d = {
73
+ sm: "0.02",
74
+ med: "0.05",
75
+ lg: "0.1"
76
+ }, f = (e) => `color-mix(in srgb, var(--color-shadow) ${e}%, transparent)`, p = {
77
+ sm: `0 1px 2px ${f(12)}`,
78
+ med: `0 2px 8px ${f(14)}, 0 1px 2px ${f(8)}`,
79
+ lg: `0 8px 24px ${f(16)}, 0 2px 6px ${f(8)}`
80
+ }, m = "0 0 0 1px color-mix(in srgb, var(--color-fg) 10%, transparent)";
81
+ `${m}${f(40)}`, `${m}${f(48)}${f(32)}`, `${m}${f(56)}${f(32)}`, c.fast, c.fast, c.fast;
82
+ var h = {
83
+ space: t,
84
+ size: n,
85
+ radius: r,
86
+ fontSize: i,
87
+ fontWeight: a,
88
+ lineHeight: o,
89
+ zIndex: s,
90
+ duration: c,
91
+ easing: l,
92
+ distance: u,
93
+ scale: d,
94
+ dir: "1",
95
+ shadow: p
96
+ };
97
+ //#endregion
98
+ export { u as distance, c as duration, l as easing, i as fontSize, a as fontWeight, o as lineHeight, r as radius, d as scale, p as shadow, n as size, t as space, h as tokens, s as zIndex };
@@ -0,0 +1,3 @@
1
+ //#region src/types.d.ts
2
+ export type OmitEach<P, K extends PropertyKey> = P extends unknown ? Omit<P, K> : never;
3
+ //#endregion