@octavius2929-personal/design-system 0.3.0 → 0.4.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.
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  // src/theme/theme.css.ts
2
+ var colorVars = { bg1: "var(--bg1__e3grur2c)", bg2: "var(--bg2__e3grur2d)", bg3: "var(--bg3__e3grur2e)", bgInset: "var(--bgInset__e3grur2f)", fg1: "var(--fg1__e3grur2g)", fg2: "var(--fg2__e3grur2h)", fg3: "var(--fg3__e3grur2i)", fgOnAccent: "var(--fgOnAccent__e3grur2j)", border1: "var(--border1__e3grur2k)", border2: "var(--border2__e3grur2l)", borderStrong: "var(--borderStrong__e3grur2m)", accent: "var(--accent__e3grur2n)", accentHover: "var(--accentHover__e3grur2o)", accentSoft: "var(--accentSoft__e3grur2p)", ok: "var(--ok__e3grur2q)", warn: "var(--warn__e3grur2r)", danger: "var(--danger__e3grur2s)", info: "var(--info__e3grur2t)", focus: "var(--focus__e3grur2u)", scrim: "var(--scrim__e3grur2v)" };
2
3
  var modeNames = ["light", "dark", "sepia", "contrast"];
3
4
  var schemaNames = ["tinta"];
4
- var themes = { tinta: { light: "theme_themes_tinta_light__e3grur2v", dark: "theme_themes_tinta_dark__e3grur2w", sepia: "theme_themes_tinta_sepia__e3grur2x", contrast: "theme_themes_tinta_contrast__e3grur2y" } };
5
- var vars = { font: { display: "var(--font-display__e3grur0)", text: "var(--font-text__e3grur1)", mono: "var(--font-mono__e3grur2)", black: "var(--font-black__e3grur3)" }, text: { eyebrow: { size: "var(--text-eyebrow-size__e3grur4)", lineHeight: "var(--text-eyebrow-lineHeight__e3grur5)", weight: "var(--text-eyebrow-weight__e3grur6)", letterSpacing: "var(--text-eyebrow-letterSpacing__e3grur7)" }, display: { size: "var(--text-display-size__e3grur8)", lineHeight: "var(--text-display-lineHeight__e3grur9)", weight: "var(--text-display-weight__e3grura)", letterSpacing: "var(--text-display-letterSpacing__e3grurb)" }, h1: { size: "var(--text-h1-size__e3grurc)", lineHeight: "var(--text-h1-lineHeight__e3grurd)", weight: "var(--text-h1-weight__e3grure)", letterSpacing: "var(--text-h1-letterSpacing__e3grurf)" }, h2: { size: "var(--text-h2-size__e3grurg)", lineHeight: "var(--text-h2-lineHeight__e3grurh)", weight: "var(--text-h2-weight__e3gruri)", letterSpacing: "var(--text-h2-letterSpacing__e3grurj)" }, h3: { size: "var(--text-h3-size__e3grurk)", lineHeight: "var(--text-h3-lineHeight__e3grurl)", weight: "var(--text-h3-weight__e3grurm)", letterSpacing: "var(--text-h3-letterSpacing__e3grurn)" }, h4: { size: "var(--text-h4-size__e3gruro)", lineHeight: "var(--text-h4-lineHeight__e3grurp)", weight: "var(--text-h4-weight__e3grurq)", letterSpacing: "var(--text-h4-letterSpacing__e3grurr)" }, body: { size: "var(--text-body-size__e3grurs)", lineHeight: "var(--text-body-lineHeight__e3grurt)", weight: "var(--text-body-weight__e3gruru)", letterSpacing: "var(--text-body-letterSpacing__e3grurv)" }, lead: { size: "var(--text-lead-size__e3grurw)", lineHeight: "var(--text-lead-lineHeight__e3grurx)", weight: "var(--text-lead-weight__e3grury)", letterSpacing: "var(--text-lead-letterSpacing__e3grurz)" }, small: { size: "var(--text-small-size__e3grur10)", lineHeight: "var(--text-small-lineHeight__e3grur11)", weight: "var(--text-small-weight__e3grur12)", letterSpacing: "var(--text-small-letterSpacing__e3grur13)" }, caption: { size: "var(--text-caption-size__e3grur14)", lineHeight: "var(--text-caption-lineHeight__e3grur15)", weight: "var(--text-caption-weight__e3grur16)", letterSpacing: "var(--text-caption-letterSpacing__e3grur17)" } }, space: { none: "var(--space-none__e3grur18)", xs: "var(--space-xs__e3grur19)", sm: "var(--space-sm__e3grur1a)", md: "var(--space-md__e3grur1b)", lg: "var(--space-lg__e3grur1c)", xl: "var(--space-xl__e3grur1d)", "2xl": "var(--space-2xl__e3grur1e)", "3xl": "var(--space-3xl__e3grur1f)", "4xl": "var(--space-4xl__e3grur1g)", "5xl": "var(--space-5xl__e3grur1h)" }, radius: { none: "var(--radius-none__e3grur1i)", sm: "var(--radius-sm__e3grur1j)", md: "var(--radius-md__e3grur1k)", lg: "var(--radius-lg__e3grur1l)", base: "var(--radius-base__e3grur1m)", full: "var(--radius-full__e3grur1n)" }, border: { hair: "var(--border-hair__e3grur1o)", rule: "var(--border-rule__e3grur1p)", heavy: "var(--border-heavy__e3grur1q)" }, tracking: { tight: "var(--tracking-tight__e3grur1r)", normal: "var(--tracking-normal__e3grur1s)", wide: "var(--tracking-wide__e3grur1t)", wider: "var(--tracking-wider__e3grur1u)", widest: "var(--tracking-widest__e3grur1v)" }, leading: { tight: "var(--leading-tight__e3grur1w)", snug: "var(--leading-snug__e3grur1x)", normal: "var(--leading-normal__e3grur1y)", relaxed: "var(--leading-relaxed__e3grur1z)" }, weight: { light: "var(--weight-light__e3grur20)", regular: "var(--weight-regular__e3grur21)", medium: "var(--weight-medium__e3grur22)", semibold: "var(--weight-semibold__e3grur23)", bold: "var(--weight-bold__e3grur24)" }, dur: { fast: "var(--dur-fast__e3grur25)", base: "var(--dur-base__e3grur26)", slow: "var(--dur-slow__e3grur27)" }, ease: { ink: "var(--ease-ink__e3grur28)" }, shadow: { sm: "var(--shadow-sm__e3grur29)", md: "var(--shadow-md__e3grur2a)", lg: "var(--shadow-lg__e3grur2b)" }, color: { bg1: "var(--color-bg1__e3grur2c)", bg2: "var(--color-bg2__e3grur2d)", bg3: "var(--color-bg3__e3grur2e)", bgInset: "var(--color-bgInset__e3grur2f)", fg1: "var(--color-fg1__e3grur2g)", fg2: "var(--color-fg2__e3grur2h)", fg3: "var(--color-fg3__e3grur2i)", fgOnAccent: "var(--color-fgOnAccent__e3grur2j)", border1: "var(--color-border1__e3grur2k)", border2: "var(--color-border2__e3grur2l)", borderStrong: "var(--color-borderStrong__e3grur2m)", accent: "var(--color-accent__e3grur2n)", accentHover: "var(--color-accentHover__e3grur2o)", accentSoft: "var(--color-accentSoft__e3grur2p)", ok: "var(--color-ok__e3grur2q)", warn: "var(--color-warn__e3grur2r)", danger: "var(--color-danger__e3grur2s)", info: "var(--color-info__e3grur2t)", scrim: "var(--color-scrim__e3grur2u)" } };
5
+ var themes = { tinta: { light: "theme_themes_tinta_light__e3grur2w", dark: "theme_themes_tinta_dark__e3grur2x", sepia: "theme_themes_tinta_sepia__e3grur2y", contrast: "theme_themes_tinta_contrast__e3grur2z" } };
6
+ var vars = { font: { display: "var(--font-display__e3grur0)", text: "var(--font-text__e3grur1)", mono: "var(--font-mono__e3grur2)", black: "var(--font-black__e3grur3)" }, text: { eyebrow: { size: "var(--text-eyebrow-size__e3grur4)", lineHeight: "var(--text-eyebrow-lineHeight__e3grur5)", weight: "var(--text-eyebrow-weight__e3grur6)", letterSpacing: "var(--text-eyebrow-letterSpacing__e3grur7)" }, display: { size: "var(--text-display-size__e3grur8)", lineHeight: "var(--text-display-lineHeight__e3grur9)", weight: "var(--text-display-weight__e3grura)", letterSpacing: "var(--text-display-letterSpacing__e3grurb)" }, h1: { size: "var(--text-h1-size__e3grurc)", lineHeight: "var(--text-h1-lineHeight__e3grurd)", weight: "var(--text-h1-weight__e3grure)", letterSpacing: "var(--text-h1-letterSpacing__e3grurf)" }, h2: { size: "var(--text-h2-size__e3grurg)", lineHeight: "var(--text-h2-lineHeight__e3grurh)", weight: "var(--text-h2-weight__e3gruri)", letterSpacing: "var(--text-h2-letterSpacing__e3grurj)" }, h3: { size: "var(--text-h3-size__e3grurk)", lineHeight: "var(--text-h3-lineHeight__e3grurl)", weight: "var(--text-h3-weight__e3grurm)", letterSpacing: "var(--text-h3-letterSpacing__e3grurn)" }, h4: { size: "var(--text-h4-size__e3gruro)", lineHeight: "var(--text-h4-lineHeight__e3grurp)", weight: "var(--text-h4-weight__e3grurq)", letterSpacing: "var(--text-h4-letterSpacing__e3grurr)" }, body: { size: "var(--text-body-size__e3grurs)", lineHeight: "var(--text-body-lineHeight__e3grurt)", weight: "var(--text-body-weight__e3gruru)", letterSpacing: "var(--text-body-letterSpacing__e3grurv)" }, lead: { size: "var(--text-lead-size__e3grurw)", lineHeight: "var(--text-lead-lineHeight__e3grurx)", weight: "var(--text-lead-weight__e3grury)", letterSpacing: "var(--text-lead-letterSpacing__e3grurz)" }, small: { size: "var(--text-small-size__e3grur10)", lineHeight: "var(--text-small-lineHeight__e3grur11)", weight: "var(--text-small-weight__e3grur12)", letterSpacing: "var(--text-small-letterSpacing__e3grur13)" }, caption: { size: "var(--text-caption-size__e3grur14)", lineHeight: "var(--text-caption-lineHeight__e3grur15)", weight: "var(--text-caption-weight__e3grur16)", letterSpacing: "var(--text-caption-letterSpacing__e3grur17)" } }, space: { none: "var(--space-none__e3grur18)", xs: "var(--space-xs__e3grur19)", sm: "var(--space-sm__e3grur1a)", md: "var(--space-md__e3grur1b)", lg: "var(--space-lg__e3grur1c)", xl: "var(--space-xl__e3grur1d)", "2xl": "var(--space-2xl__e3grur1e)", "3xl": "var(--space-3xl__e3grur1f)", "4xl": "var(--space-4xl__e3grur1g)", "5xl": "var(--space-5xl__e3grur1h)" }, radius: { none: "var(--radius-none__e3grur1i)", sm: "var(--radius-sm__e3grur1j)", md: "var(--radius-md__e3grur1k)", lg: "var(--radius-lg__e3grur1l)", base: "var(--radius-base__e3grur1m)", full: "var(--radius-full__e3grur1n)" }, border: { hair: "var(--border-hair__e3grur1o)", rule: "var(--border-rule__e3grur1p)", heavy: "var(--border-heavy__e3grur1q)" }, tracking: { tight: "var(--tracking-tight__e3grur1r)", normal: "var(--tracking-normal__e3grur1s)", wide: "var(--tracking-wide__e3grur1t)", wider: "var(--tracking-wider__e3grur1u)", widest: "var(--tracking-widest__e3grur1v)" }, leading: { tight: "var(--leading-tight__e3grur1w)", snug: "var(--leading-snug__e3grur1x)", normal: "var(--leading-normal__e3grur1y)", relaxed: "var(--leading-relaxed__e3grur1z)" }, weight: { light: "var(--weight-light__e3grur20)", regular: "var(--weight-regular__e3grur21)", medium: "var(--weight-medium__e3grur22)", semibold: "var(--weight-semibold__e3grur23)", bold: "var(--weight-bold__e3grur24)" }, dur: { fast: "var(--dur-fast__e3grur25)", base: "var(--dur-base__e3grur26)", slow: "var(--dur-slow__e3grur27)" }, ease: { ink: "var(--ease-ink__e3grur28)" }, shadow: { sm: "var(--shadow-sm__e3grur29)", md: "var(--shadow-md__e3grur2a)", lg: "var(--shadow-lg__e3grur2b)" }, color: colorVars };
6
7
 
7
8
  // src/hooks/use-previous/index.ts
8
9
  import { useEffect, useRef } from "react";
@@ -26,36 +27,86 @@ function useToggle(initial = false) {
26
27
  import { useMemo as useMemo2 } from "react";
27
28
 
28
29
  // src/theme/context/theme-context.tsx
29
- import { createContext, useContext, useMemo, useState as useState2 } from "react";
30
+ import { createContext, useContext, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
30
31
  import { jsx } from "react/jsx-runtime";
31
32
  var noop = () => {
32
33
  };
33
34
  var DEFAULT_VALUE = {
34
35
  schema: "tinta",
35
36
  mode: "light",
37
+ preference: "light",
36
38
  themeClass: themes.tinta.light,
37
39
  setSchema: noop,
38
40
  setMode: noop,
39
- toggleMode: noop
41
+ toggleMode: noop,
42
+ cycleMode: noop
40
43
  };
41
44
  var ThemeContext = createContext(null);
45
+ function resolveSystemMode() {
46
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return "light";
47
+ if (window.matchMedia("(prefers-contrast: more)").matches) return "contrast";
48
+ if (window.matchMedia("(prefers-color-scheme: dark)").matches) return "dark";
49
+ return "light";
50
+ }
51
+ function readStored(key) {
52
+ if (typeof window === "undefined") return null;
53
+ try {
54
+ const raw = window.localStorage.getItem(key);
55
+ return raw ? JSON.parse(raw) : null;
56
+ } catch {
57
+ return null;
58
+ }
59
+ }
60
+ function writeStored(key, value) {
61
+ if (typeof window === "undefined") return;
62
+ try {
63
+ window.localStorage.setItem(key, JSON.stringify(value));
64
+ } catch {
65
+ }
66
+ }
42
67
  function ThemeProvider({
43
68
  children,
44
69
  defaultSchema = "tinta",
45
- defaultMode = "light"
70
+ defaultMode = "light",
71
+ storageKey = "ds-theme",
72
+ persist = true
46
73
  }) {
47
- const [schema, setSchema] = useState2(defaultSchema);
48
- const [mode, setMode] = useState2(defaultMode);
74
+ const [schema, setSchema] = useState2(
75
+ () => persist && readStored(storageKey)?.schema || defaultSchema
76
+ );
77
+ const [preference, setPreference] = useState2(
78
+ () => (persist ? readStored(storageKey)?.preference : null) ?? defaultMode
79
+ );
80
+ const [systemMode, setSystemMode] = useState2(resolveSystemMode);
81
+ useEffect2(() => {
82
+ if (preference !== "system") return;
83
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
84
+ const mqls = ["(prefers-contrast: more)", "(prefers-color-scheme: dark)"].map(
85
+ (q) => window.matchMedia(q)
86
+ );
87
+ const onChange = () => setSystemMode(resolveSystemMode());
88
+ onChange();
89
+ for (const mql of mqls) mql.addEventListener?.("change", onChange);
90
+ return () => {
91
+ for (const mql of mqls) mql.removeEventListener?.("change", onChange);
92
+ };
93
+ }, [preference]);
94
+ const mode = preference === "system" ? systemMode : preference;
95
+ useEffect2(() => {
96
+ if (persist) writeStored(storageKey, { schema, preference });
97
+ }, [schema, preference, persist, storageKey]);
49
98
  const value = useMemo(
50
99
  () => ({
51
100
  schema,
52
101
  mode,
102
+ preference,
53
103
  themeClass: themes[schema][mode],
54
104
  setSchema,
55
- setMode,
56
- toggleMode: () => setMode((current2) => current2 === "dark" ? "light" : "dark")
105
+ setMode: setPreference,
106
+ toggleMode: () => setPreference(mode === "dark" ? "light" : "dark"),
107
+ cycleMode: () => setPreference(modeNames[(modeNames.indexOf(mode) + 1) % modeNames.length])
57
108
  }),
58
- [schema, mode]
109
+ [schema, mode, preference]
59
110
  );
60
111
  return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
61
112
  }
@@ -994,7 +1045,7 @@ function Tooltip({ label: label7, children, placement: placement2 }) {
994
1045
  }
995
1046
 
996
1047
  // src/components/select/index.tsx
997
- import { useEffect as useEffect2, useId as useId3, useRef as useRef2, useState as useState5 } from "react";
1048
+ import { useEffect as useEffect3, useId as useId3, useRef as useRef2, useState as useState5 } from "react";
998
1049
 
999
1050
  // src/components/icons/chevron-down/index.tsx
1000
1051
  import { jsx as jsx24 } from "react/jsx-runtime";
@@ -1070,7 +1121,7 @@ function Select({ options, value, onChange, placeholder: placeholder2, label: la
1070
1121
  menu: menu2,
1071
1122
  optionClass
1072
1123
  } = useStyles15({ open });
1073
- useEffect2(() => {
1124
+ useEffect3(() => {
1074
1125
  if (!open) return;
1075
1126
  const onPointerDown = (event) => {
1076
1127
  if (rootRef.current && !rootRef.current.contains(event.target)) {
@@ -1581,7 +1632,7 @@ function Tabs({ items, value, onChange }) {
1581
1632
  // src/components/menu/index.tsx
1582
1633
  import {
1583
1634
  cloneElement as cloneElement2,
1584
- useEffect as useEffect3,
1635
+ useEffect as useEffect4,
1585
1636
  useRef as useRef3,
1586
1637
  useState as useState7
1587
1638
  } from "react";
@@ -1632,7 +1683,7 @@ function Menu({ trigger: trigger2, items }) {
1632
1683
  setOpen(false);
1633
1684
  triggerRef.current?.focus();
1634
1685
  };
1635
- useEffect3(() => {
1686
+ useEffect4(() => {
1636
1687
  if (!open) return;
1637
1688
  listRef.current?.querySelector('[role="menuitem"]')?.focus();
1638
1689
  const onDocMouseDown = (event) => {
@@ -1719,10 +1770,11 @@ function Menu({ trigger: trigger2, items }) {
1719
1770
 
1720
1771
  // src/components/dialog/index.tsx
1721
1772
  import {
1722
- useEffect as useEffect4,
1773
+ useEffect as useEffect5,
1723
1774
  useId as useId4,
1724
1775
  useRef as useRef4
1725
1776
  } from "react";
1777
+ import { createPortal } from "react-dom";
1726
1778
 
1727
1779
  // src/components/dialog/use-styles.ts
1728
1780
  import { useMemo as useMemo24 } from "react";
@@ -1758,7 +1810,7 @@ function Dialog({ open, onClose, title, actions: actions3, children }) {
1758
1810
  const previouslyFocused = useRef4(null);
1759
1811
  const generatedId = useId4();
1760
1812
  const titleId = title != null ? generatedId : void 0;
1761
- useEffect4(() => {
1813
+ useEffect5(() => {
1762
1814
  if (!open) return;
1763
1815
  const onKeyDown = (event) => {
1764
1816
  if (event.key === "Escape") onClose();
@@ -1766,13 +1818,13 @@ function Dialog({ open, onClose, title, actions: actions3, children }) {
1766
1818
  document.addEventListener("keydown", onKeyDown);
1767
1819
  return () => document.removeEventListener("keydown", onKeyDown);
1768
1820
  }, [open, onClose]);
1769
- useEffect4(() => {
1821
+ useEffect5(() => {
1770
1822
  if (!open) return;
1771
1823
  previouslyFocused.current = document.activeElement;
1772
1824
  surfaceRef.current?.focus();
1773
1825
  return () => previouslyFocused.current?.focus?.();
1774
1826
  }, [open]);
1775
- useEffect4(() => {
1827
+ useEffect5(() => {
1776
1828
  if (!open) return;
1777
1829
  const previousOverflow = document.body.style.overflow;
1778
1830
  document.body.style.overflow = "hidden";
@@ -1780,7 +1832,7 @@ function Dialog({ open, onClose, title, actions: actions3, children }) {
1780
1832
  document.body.style.overflow = previousOverflow;
1781
1833
  };
1782
1834
  }, [open]);
1783
- if (!open) return null;
1835
+ if (!open || typeof document === "undefined") return null;
1784
1836
  const stop = (event) => event.stopPropagation();
1785
1837
  const onSurfaceKeyDown = (event) => {
1786
1838
  if (event.key !== "Tab") return;
@@ -1807,7 +1859,7 @@ function Dialog({ open, onClose, title, actions: actions3, children }) {
1807
1859
  first.focus();
1808
1860
  }
1809
1861
  };
1810
- return (
1862
+ return createPortal(
1811
1863
  // biome-ignore lint/a11y/useKeyWithClickEvents: ESC handled by a document keydown listener.
1812
1864
  /* @__PURE__ */ jsx35("div", { className: overlay2, "data-testid": "dialog-overlay", onClick: onClose, children: /* @__PURE__ */ jsxs25(
1813
1865
  "div",
@@ -1826,10 +1878,14 @@ function Dialog({ open, onClose, title, actions: actions3, children }) {
1826
1878
  actions3 != null && /* @__PURE__ */ jsx35("div", { className: actionsClass, children: actions3 })
1827
1879
  ]
1828
1880
  }
1829
- ) })
1881
+ ) }),
1882
+ document.body
1830
1883
  );
1831
1884
  }
1832
1885
 
1886
+ // src/components/snackbar/index.tsx
1887
+ import { createPortal as createPortal2 } from "react-dom";
1888
+
1833
1889
  // src/components/snackbar/use-styles.ts
1834
1890
  import { useMemo as useMemo25 } from "react";
1835
1891
 
@@ -1855,12 +1911,15 @@ function useStyles24() {
1855
1911
  import { jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
1856
1912
  function Snackbar({ open, message: message2, action, onClose }) {
1857
1913
  const { root: root24, message: messageClass, closeBtn: closeBtn2 } = useStyles24();
1858
- if (!open) return null;
1859
- return /* @__PURE__ */ jsxs26("div", { role: "status", className: root24, children: [
1860
- /* @__PURE__ */ jsx36("span", { className: messageClass, children: message2 }),
1861
- action,
1862
- onClose && /* @__PURE__ */ jsx36("button", { type: "button", "aria-label": "Close", className: closeBtn2, onClick: onClose, children: /* @__PURE__ */ jsx36(XIcon, { size: 18 }) })
1863
- ] });
1914
+ if (!open || typeof document === "undefined") return null;
1915
+ return createPortal2(
1916
+ /* @__PURE__ */ jsxs26("div", { role: "status", className: root24, children: [
1917
+ /* @__PURE__ */ jsx36("span", { className: messageClass, children: message2 }),
1918
+ action,
1919
+ onClose && /* @__PURE__ */ jsx36("button", { type: "button", "aria-label": "Close", className: closeBtn2, onClick: onClose, children: /* @__PURE__ */ jsx36(XIcon, { size: 18 }) })
1920
+ ] }),
1921
+ document.body
1922
+ );
1864
1923
  }
1865
1924
 
1866
1925
  // src/components/table/use-styles.ts
@@ -2134,6 +2193,7 @@ export {
2134
2193
  Tooltip,
2135
2194
  TriangleAlertIcon,
2136
2195
  XIcon,
2196
+ colorVars,
2137
2197
  modeNames,
2138
2198
  schemaNames,
2139
2199
  text,
@@ -2143,3 +2203,4 @@ export {
2143
2203
  useTheme,
2144
2204
  useToggle
2145
2205
  };
2206
+ //# sourceMappingURL=index.js.map