@iris-ui-kit/react 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 (154) hide show
  1. package/LICENSE +21 -0
  2. package/dist/SidebarLayout-fWQRvK0a.d.cts +26 -0
  3. package/dist/SidebarLayout-fWQRvK0a.d.ts +26 -0
  4. package/dist/admin.cjs +1583 -0
  5. package/dist/admin.cjs.map +1 -0
  6. package/dist/admin.d.cts +183 -0
  7. package/dist/admin.d.ts +183 -0
  8. package/dist/admin.js +9 -0
  9. package/dist/admin.js.map +1 -0
  10. package/dist/async.cjs +97 -0
  11. package/dist/async.cjs.map +1 -0
  12. package/dist/async.d.cts +57 -0
  13. package/dist/async.d.ts +57 -0
  14. package/dist/async.js +5 -0
  15. package/dist/async.js.map +1 -0
  16. package/dist/behaviors.cjs +569 -0
  17. package/dist/behaviors.cjs.map +1 -0
  18. package/dist/behaviors.d.cts +188 -0
  19. package/dist/behaviors.d.ts +188 -0
  20. package/dist/behaviors.js +4 -0
  21. package/dist/behaviors.js.map +1 -0
  22. package/dist/chunk-2TQSTINK.js +541 -0
  23. package/dist/chunk-2TQSTINK.js.map +1 -0
  24. package/dist/chunk-53KFLVIZ.js +68 -0
  25. package/dist/chunk-53KFLVIZ.js.map +1 -0
  26. package/dist/chunk-6BMFMCMQ.js +140 -0
  27. package/dist/chunk-6BMFMCMQ.js.map +1 -0
  28. package/dist/chunk-AUA5GBT6.js +143 -0
  29. package/dist/chunk-AUA5GBT6.js.map +1 -0
  30. package/dist/chunk-DE6V6NOI.js +122 -0
  31. package/dist/chunk-DE6V6NOI.js.map +1 -0
  32. package/dist/chunk-HEJGN6UI.js +78 -0
  33. package/dist/chunk-HEJGN6UI.js.map +1 -0
  34. package/dist/chunk-IDD35UJ6.js +83 -0
  35. package/dist/chunk-IDD35UJ6.js.map +1 -0
  36. package/dist/chunk-J5FB2UB2.js +166 -0
  37. package/dist/chunk-J5FB2UB2.js.map +1 -0
  38. package/dist/chunk-OMOTUHYI.js +66 -0
  39. package/dist/chunk-OMOTUHYI.js.map +1 -0
  40. package/dist/chunk-RZNYIFV2.js +34 -0
  41. package/dist/chunk-RZNYIFV2.js.map +1 -0
  42. package/dist/chunk-SJO74IB3.js +54 -0
  43. package/dist/chunk-SJO74IB3.js.map +1 -0
  44. package/dist/chunk-SORLRLS4.js +53 -0
  45. package/dist/chunk-SORLRLS4.js.map +1 -0
  46. package/dist/chunk-TO7YVSAI.js +64 -0
  47. package/dist/chunk-TO7YVSAI.js.map +1 -0
  48. package/dist/chunk-TQ33XJIK.js +22 -0
  49. package/dist/chunk-TQ33XJIK.js.map +1 -0
  50. package/dist/chunk-UWUUEZCD.js +950 -0
  51. package/dist/chunk-UWUUEZCD.js.map +1 -0
  52. package/dist/chunk-VWCJJRSC.js +1200 -0
  53. package/dist/chunk-VWCJJRSC.js.map +1 -0
  54. package/dist/chunk-WIHBIDVJ.js +54 -0
  55. package/dist/chunk-WIHBIDVJ.js.map +1 -0
  56. package/dist/chunk-XCK4RIXB.js +66 -0
  57. package/dist/chunk-XCK4RIXB.js.map +1 -0
  58. package/dist/chunk-YAHXR2CJ.js +48 -0
  59. package/dist/chunk-YAHXR2CJ.js.map +1 -0
  60. package/dist/chunk-YXIO5THG.js +4 -0
  61. package/dist/chunk-YXIO5THG.js.map +1 -0
  62. package/dist/chunk-ZKBDUWUD.js +156 -0
  63. package/dist/chunk-ZKBDUWUD.js.map +1 -0
  64. package/dist/data.cjs +112 -0
  65. package/dist/data.cjs.map +1 -0
  66. package/dist/data.d.cts +53 -0
  67. package/dist/data.d.ts +53 -0
  68. package/dist/data.js +5 -0
  69. package/dist/data.js.map +1 -0
  70. package/dist/error-boundary.cjs +106 -0
  71. package/dist/error-boundary.cjs.map +1 -0
  72. package/dist/error-boundary.d.cts +41 -0
  73. package/dist/error-boundary.d.ts +41 -0
  74. package/dist/error-boundary.js +6 -0
  75. package/dist/error-boundary.js.map +1 -0
  76. package/dist/floating.cjs +163 -0
  77. package/dist/floating.cjs.map +1 -0
  78. package/dist/floating.d.cts +92 -0
  79. package/dist/floating.d.ts +92 -0
  80. package/dist/floating.js +5 -0
  81. package/dist/floating.js.map +1 -0
  82. package/dist/form.cjs +159 -0
  83. package/dist/form.cjs.map +1 -0
  84. package/dist/form.d.cts +120 -0
  85. package/dist/form.d.ts +120 -0
  86. package/dist/form.js +5 -0
  87. package/dist/form.js.map +1 -0
  88. package/dist/i18n.cjs +100 -0
  89. package/dist/i18n.cjs.map +1 -0
  90. package/dist/i18n.d.cts +50 -0
  91. package/dist/i18n.d.ts +50 -0
  92. package/dist/i18n.js +5 -0
  93. package/dist/i18n.js.map +1 -0
  94. package/dist/index.cjs +16635 -0
  95. package/dist/index.cjs.map +1 -0
  96. package/dist/index.d.cts +2964 -0
  97. package/dist/index.d.ts +2964 -0
  98. package/dist/index.js +12217 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/layouts.cjs +386 -0
  101. package/dist/layouts.cjs.map +1 -0
  102. package/dist/layouts.d.cts +92 -0
  103. package/dist/layouts.d.ts +92 -0
  104. package/dist/layouts.js +6 -0
  105. package/dist/layouts.js.map +1 -0
  106. package/dist/modal-utils.cjs +168 -0
  107. package/dist/modal-utils.cjs.map +1 -0
  108. package/dist/modal-utils.d.cts +43 -0
  109. package/dist/modal-utils.d.ts +43 -0
  110. package/dist/modal-utils.js +4 -0
  111. package/dist/modal-utils.js.map +1 -0
  112. package/dist/motion.cjs +104 -0
  113. package/dist/motion.cjs.map +1 -0
  114. package/dist/motion.d.cts +41 -0
  115. package/dist/motion.d.ts +41 -0
  116. package/dist/motion.js +4 -0
  117. package/dist/motion.js.map +1 -0
  118. package/dist/provider.cjs +191 -0
  119. package/dist/provider.cjs.map +1 -0
  120. package/dist/provider.d.cts +62 -0
  121. package/dist/provider.d.ts +62 -0
  122. package/dist/provider.js +8 -0
  123. package/dist/provider.js.map +1 -0
  124. package/dist/resource.cjs +61 -0
  125. package/dist/resource.cjs.map +1 -0
  126. package/dist/resource.d.cts +21 -0
  127. package/dist/resource.d.ts +21 -0
  128. package/dist/resource.js +5 -0
  129. package/dist/resource.js.map +1 -0
  130. package/dist/skeletons.cjs +1304 -0
  131. package/dist/skeletons.cjs.map +1 -0
  132. package/dist/skeletons.d.cts +70 -0
  133. package/dist/skeletons.d.ts +70 -0
  134. package/dist/skeletons.js +8 -0
  135. package/dist/skeletons.js.map +1 -0
  136. package/dist/skins.cjs +134 -0
  137. package/dist/skins.cjs.map +1 -0
  138. package/dist/skins.d.cts +45 -0
  139. package/dist/skins.d.ts +45 -0
  140. package/dist/skins.js +5 -0
  141. package/dist/skins.js.map +1 -0
  142. package/dist/theme.cjs +100 -0
  143. package/dist/theme.cjs.map +1 -0
  144. package/dist/theme.d.cts +71 -0
  145. package/dist/theme.d.ts +71 -0
  146. package/dist/theme.js +5 -0
  147. package/dist/theme.js.map +1 -0
  148. package/dist/undo.cjs +73 -0
  149. package/dist/undo.cjs.map +1 -0
  150. package/dist/undo.d.cts +47 -0
  151. package/dist/undo.d.ts +47 -0
  152. package/dist/undo.js +4 -0
  153. package/dist/undo.js.map +1 -0
  154. package/package.json +61 -0
package/dist/theme.cjs ADDED
@@ -0,0 +1,100 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ var React2 = require('react');
5
+ var theme = require('@iris-ui-kit/theme');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
27
+
28
+ // src/theme/ThemeProvider.tsx
29
+ function useStore(store) {
30
+ return React2.useSyncExternalStore(
31
+ store.subscribe,
32
+ store.getState,
33
+ store.getState
34
+ // SSR fallback — same as client snapshot in our case.
35
+ );
36
+ }
37
+ var IrisThemeContext = React2.createContext(null);
38
+ function ThemeProvider({
39
+ store,
40
+ target = null,
41
+ dir = "ltr",
42
+ cspNonce,
43
+ children
44
+ }) {
45
+ const current = useStore(store.store);
46
+ const appliedRef = React2.useRef(null);
47
+ React2.useEffect(() => {
48
+ theme.injectGlobalStyles(cspNonce);
49
+ const el = target ?? document.documentElement;
50
+ appliedRef.current?.revert();
51
+ appliedRef.current = theme.applyTheme(current, el);
52
+ const dirApplied = theme.applyDirection(dir, el);
53
+ return () => {
54
+ appliedRef.current?.revert();
55
+ appliedRef.current = null;
56
+ dirApplied.revert();
57
+ };
58
+ }, [current, target, dir]);
59
+ return /* @__PURE__ */ jsxRuntime.jsx(IrisThemeContext.Provider, { value: { store, current, dir }, children });
60
+ }
61
+ function useThemeContext() {
62
+ const ctx = React2.useContext(IrisThemeContext);
63
+ if (!ctx) {
64
+ throw new Error("[iris-ui] useTheme(): no <ThemeProvider> ancestor found");
65
+ }
66
+ return ctx;
67
+ }
68
+ function useThemeOptional() {
69
+ return React2.useContext(IrisThemeContext)?.current;
70
+ }
71
+ function useDirection() {
72
+ return React2.useContext(IrisThemeContext)?.dir ?? "ltr";
73
+ }
74
+
75
+ // src/theme/useTheme.ts
76
+ function useTheme() {
77
+ const ctx = useThemeContext();
78
+ return {
79
+ theme: ctx.current,
80
+ setTheme: ctx.store.setTheme,
81
+ availableThemes: ctx.store.availableThemes
82
+ };
83
+ }
84
+ function useColorScheme() {
85
+ const [scheme, setScheme] = React2__namespace.useState(theme.getColorScheme);
86
+ React2__namespace.useEffect(() => {
87
+ setScheme(theme.getColorScheme());
88
+ return theme.watchColorScheme(setScheme);
89
+ }, []);
90
+ return scheme;
91
+ }
92
+
93
+ exports.ThemeProvider = ThemeProvider;
94
+ exports.useColorScheme = useColorScheme;
95
+ exports.useDirection = useDirection;
96
+ exports.useTheme = useTheme;
97
+ exports.useThemeContext = useThemeContext;
98
+ exports.useThemeOptional = useThemeOptional;
99
+ //# sourceMappingURL=theme.cjs.map
100
+ //# sourceMappingURL=theme.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useStore.ts","../src/theme/ThemeProvider.tsx","../src/theme/useTheme.ts","../src/theme/useColorScheme.ts"],"names":["useSyncExternalStore","createContext","useRef","useEffect","injectGlobalStyles","applyTheme","applyDirection","jsx","useContext","React2","getColorScheme","watchColorScheme"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUO,SAAS,SAAY,KAAA,EAA4B;AACtD,EAAA,OAAOA,2BAAA;AAAA,IACL,KAAA,CAAM,SAAA;AAAA,IACN,KAAA,CAAM,QAAA;AAAA,IACN,KAAA,CAAM;AAAA;AAAA,GACR;AACF;ACEA,IAAM,gBAAA,GAAmBC,qBAA4C,IAAI,CAAA;AAqBlE,SAAS,aAAA,CAAc;AAAA,EAC5B,KAAA;AAAA,EACA,MAAA,GAAS,IAAA;AAAA,EACT,GAAA,GAAM,KAAA;AAAA,EACN,QAAA;AAAA,EACA;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,KAAA,CAAM,KAAK,CAAA;AACpC,EAAA,MAAM,UAAA,GAAaC,cAAgC,IAAI,CAAA;AAEvD,EAAAC,iBAAU,MAAM;AACd,IAAAC,wBAAA,CAAmB,QAAQ,CAAA;AAC3B,IAAA,MAAM,EAAA,GAAK,UAAU,QAAA,CAAS,eAAA;AAC9B,IAAA,UAAA,CAAW,SAAS,MAAA,EAAO;AAC3B,IAAA,UAAA,CAAW,OAAA,GAAUC,gBAAA,CAAW,OAAA,EAAS,EAAE,CAAA;AAC3C,IAAA,MAAM,UAAA,GAAaC,oBAAA,CAAe,GAAA,EAAK,EAAE,CAAA;AACzC,IAAA,OAAO,MAAM;AACX,MAAA,UAAA,CAAW,SAAS,MAAA,EAAO;AAC3B,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,MAAA,UAAA,CAAW,MAAA,EAAO;AAAA,IACpB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,MAAA,EAAQ,GAAG,CAAC,CAAA;AAEzB,EAAA,uBACEC,cAAA,CAAC,gBAAA,CAAiB,QAAA,EAAjB,EAA0B,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,GAAA,EAAI,EACrD,QAAA,EACH,CAAA;AAEJ;AAEO,SAAS,eAAA,GAAyC;AACvD,EAAA,MAAM,GAAA,GAAMC,kBAAW,gBAAgB,CAAA;AACvC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAAA,EAC3E;AACA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,gBAAA,GAA0C;AACxD,EAAA,OAAOA,iBAAA,CAAW,gBAAgB,CAAA,EAAG,OAAA;AACvC;AAOO,SAAS,YAAA,GAA0B;AACxC,EAAA,OAAOA,iBAAA,CAAW,gBAAgB,CAAA,EAAG,GAAA,IAAO,KAAA;AAC9C;;;AC7EO,SAAS,QAAA,GAA2B;AACzC,EAAA,MAAM,MAAM,eAAA,EAAgB;AAC5B,EAAA,OAAO;AAAA,IACL,OAAO,GAAA,CAAI,OAAA;AAAA,IACX,QAAA,EAAU,IAAI,KAAA,CAAM,QAAA;AAAA,IACpB,eAAA,EAAiB,IAAI,KAAA,CAAM;AAAA,GAC7B;AACF;ACTO,SAAS,cAAA,GAA8B;AAC5C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUC,2BAAsBC,oBAAc,CAAA;AACtE,EAAMD,4BAAU,MAAM;AAEpB,IAAA,SAAA,CAAUC,sBAAgB,CAAA;AAC1B,IAAA,OAAOC,uBAAiB,SAAS,CAAA;AAAA,EACnC,CAAA,EAAG,EAAE,CAAA;AACL,EAAA,OAAO,MAAA;AACT","file":"theme.cjs","sourcesContent":["import * as React from 'react'\nimport { useSyncExternalStore } from 'react'\nimport type { ReadonlyStore, Store } from '@iris-ui-kit/core'\n\n/**\n * Bridge a framework-agnostic `@iris-ui-kit/core` store into React reactivity.\n * Uses React 18's `useSyncExternalStore` — the contract is identical to the\n * one Vue uses via `ref + onMounted` and Solid uses via `createSignal`. The\n * **same** store can power Button, Popover, Dialog, etc. on any framework.\n */\nexport function useStore<T>(store: ReadonlyStore<T>): T {\n return useSyncExternalStore(\n store.subscribe,\n store.getState,\n store.getState, // SSR fallback — same as client snapshot in our case.\n )\n}\n\n/**\n * Subscribe to a DERIVED slice of a core store — the component re-renders only\n * when `selector(state)` changes per `isEqual` (default `Object.is`), not on\n * every store emission. Built on {@link Store.subscribeWith}. Inline closures\n * for `selector`/`isEqual` are fine (captured via refs; the subscription is not\n * re-created between renders).\n */\nexport function useStoreSelector<T, U>(\n store: Store<T>,\n selector: (state: T) => U,\n isEqual?: (a: U, b: U) => boolean,\n): U {\n const [slice, setSlice] = React.useState(() => selector(store.getState()))\n const selRef = React.useRef(selector)\n selRef.current = selector\n const eqRef = React.useRef(isEqual)\n eqRef.current = isEqual\n React.useEffect(() => {\n const read = (s: T): U => selRef.current(s)\n const eq = (a: U, b: U): boolean => (eqRef.current ?? Object.is)(a, b)\n // Re-sync in case the store moved between render and this effect.\n setSlice((prev) => {\n const next = read(store.getState())\n return eq(prev, next) ? prev : next\n })\n return store.subscribeWith(read, setSlice, eq)\n }, [store])\n return slice\n}\n","import { createContext, useContext, useEffect, useRef, type ReactNode } from 'react'\nimport {\n applyDirection,\n applyTheme,\n injectGlobalStyles,\n type ApplyThemeResult,\n type Direction,\n type ThemeStore,\n} from '@iris-ui-kit/theme'\nimport type { IrisTheme } from '@iris-ui-kit/tokens'\nimport { useStore } from '../useStore'\n\ninterface IrisThemeContextValue {\n store: ThemeStore\n current: IrisTheme\n dir: Direction\n}\n\nconst IrisThemeContext = createContext<IrisThemeContextValue | null>(null)\n\nexport interface ThemeProviderProps {\n store: ThemeStore\n target?: HTMLElement | null\n /** Writing direction; sets `dir` on the target for RTL. Default `'ltr'`. */\n dir?: Direction\n /** CSP nonce for the injected global stylesheet. Pass the `nonce` from your\n * server-rendered CSP header when you use `style-src: 'nonce-...'`. */\n cspNonce?: string\n children?: ReactNode\n}\n\n/**\n * Renderless provider that mirrors `<IrisThemeProvider>` from `@iris-ui-kit/vue`:\n * subscribes to the theme store, applies CSS variables to `target` (or\n * `document.documentElement`), reverts on unmount.\n *\n * **Zero business logic** — `applyTheme` / `createThemeStore` come straight\n * from `@iris-ui-kit/theme`. This component is just a 30-line React adapter.\n */\nexport function ThemeProvider({\n store,\n target = null,\n dir = 'ltr',\n cspNonce,\n children,\n}: ThemeProviderProps) {\n const current = useStore(store.store)\n const appliedRef = useRef<ApplyThemeResult | null>(null)\n\n useEffect(() => {\n injectGlobalStyles(cspNonce)\n const el = target ?? document.documentElement\n appliedRef.current?.revert()\n appliedRef.current = applyTheme(current, el)\n const dirApplied = applyDirection(dir, el)\n return () => {\n appliedRef.current?.revert()\n appliedRef.current = null\n dirApplied.revert()\n }\n }, [current, target, dir])\n\n return (\n <IrisThemeContext.Provider value={{ store, current, dir }}>\n {children}\n </IrisThemeContext.Provider>\n )\n}\n\nexport function useThemeContext(): IrisThemeContextValue {\n const ctx = useContext(IrisThemeContext)\n if (!ctx) {\n throw new Error('[iris-ui] useTheme(): no <ThemeProvider> ancestor found')\n }\n return ctx\n}\n\n/**\n * Read the current theme without throwing when there is no `<ThemeProvider>`\n * ancestor. Returns `undefined` outside a provider. Used by theme-aware\n * primitives (e.g. `IrisIcon`) that must still render standalone.\n */\nexport function useThemeOptional(): IrisTheme | undefined {\n return useContext(IrisThemeContext)?.current\n}\n\n/**\n * Current writing direction (`'ltr'` / `'rtl'`) from the nearest\n * `<ThemeProvider>`, or `'ltr'` when there is none. For components that need to\n * branch on direction beyond what CSS logical properties already handle.\n */\nexport function useDirection(): Direction {\n return useContext(IrisThemeContext)?.dir ?? 'ltr'\n}\n","import type { IrisTheme } from '@iris-ui-kit/tokens'\nimport { useThemeContext } from './ThemeProvider'\n\nexport interface UseThemeReturn {\n theme: IrisTheme\n setTheme: (target: string | IrisTheme) => void\n availableThemes: Record<string, IrisTheme>\n}\n\n/**\n * Read and write the current theme from anywhere inside a `<ThemeProvider>`.\n *\n * @example\n * const { theme, setTheme } = useTheme()\n * setTheme('dark')\n */\nexport function useTheme(): UseThemeReturn {\n const ctx = useThemeContext()\n return {\n theme: ctx.current,\n setTheme: ctx.store.setTheme,\n availableThemes: ctx.store.availableThemes,\n }\n}\n","import * as React from 'react'\nimport { getColorScheme, watchColorScheme, type ColorScheme } from '@iris-ui-kit/theme'\n\n/**\n * Reactive system color scheme (`'light'` / `'dark'`) from\n * `prefers-color-scheme`. Re-renders the host when the OS preference flips.\n * SSR-safe (reports `'light'` until mounted). Wire it to a theme store to\n * auto-follow the system:\n *\n * ```tsx\n * const scheme = useColorScheme()\n * React.useEffect(() => store.setTheme(scheme === 'dark' ? 'dark' : 'light'), [scheme])\n * ```\n */\nexport function useColorScheme(): ColorScheme {\n const [scheme, setScheme] = React.useState<ColorScheme>(getColorScheme)\n React.useEffect(() => {\n // Re-sync in case the preference changed between render and effect.\n setScheme(getColorScheme())\n return watchColorScheme(setScheme)\n }, [])\n return scheme\n}\n"]}
@@ -0,0 +1,71 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { ThemeStore, Direction, ColorScheme } from '@iris-ui-kit/theme';
4
+ import { IrisTheme } from '@iris-ui-kit/tokens';
5
+
6
+ interface IrisThemeContextValue {
7
+ store: ThemeStore;
8
+ current: IrisTheme;
9
+ dir: Direction;
10
+ }
11
+ interface ThemeProviderProps {
12
+ store: ThemeStore;
13
+ target?: HTMLElement | null;
14
+ /** Writing direction; sets `dir` on the target for RTL. Default `'ltr'`. */
15
+ dir?: Direction;
16
+ /** CSP nonce for the injected global stylesheet. Pass the `nonce` from your
17
+ * server-rendered CSP header when you use `style-src: 'nonce-...'`. */
18
+ cspNonce?: string;
19
+ children?: ReactNode;
20
+ }
21
+ /**
22
+ * Renderless provider that mirrors `<IrisThemeProvider>` from `@iris-ui-kit/vue`:
23
+ * subscribes to the theme store, applies CSS variables to `target` (or
24
+ * `document.documentElement`), reverts on unmount.
25
+ *
26
+ * **Zero business logic** — `applyTheme` / `createThemeStore` come straight
27
+ * from `@iris-ui-kit/theme`. This component is just a 30-line React adapter.
28
+ */
29
+ declare function ThemeProvider({ store, target, dir, cspNonce, children, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
30
+ declare function useThemeContext(): IrisThemeContextValue;
31
+ /**
32
+ * Read the current theme without throwing when there is no `<ThemeProvider>`
33
+ * ancestor. Returns `undefined` outside a provider. Used by theme-aware
34
+ * primitives (e.g. `IrisIcon`) that must still render standalone.
35
+ */
36
+ declare function useThemeOptional(): IrisTheme | undefined;
37
+ /**
38
+ * Current writing direction (`'ltr'` / `'rtl'`) from the nearest
39
+ * `<ThemeProvider>`, or `'ltr'` when there is none. For components that need to
40
+ * branch on direction beyond what CSS logical properties already handle.
41
+ */
42
+ declare function useDirection(): Direction;
43
+
44
+ interface UseThemeReturn {
45
+ theme: IrisTheme;
46
+ setTheme: (target: string | IrisTheme) => void;
47
+ availableThemes: Record<string, IrisTheme>;
48
+ }
49
+ /**
50
+ * Read and write the current theme from anywhere inside a `<ThemeProvider>`.
51
+ *
52
+ * @example
53
+ * const { theme, setTheme } = useTheme()
54
+ * setTheme('dark')
55
+ */
56
+ declare function useTheme(): UseThemeReturn;
57
+
58
+ /**
59
+ * Reactive system color scheme (`'light'` / `'dark'`) from
60
+ * `prefers-color-scheme`. Re-renders the host when the OS preference flips.
61
+ * SSR-safe (reports `'light'` until mounted). Wire it to a theme store to
62
+ * auto-follow the system:
63
+ *
64
+ * ```tsx
65
+ * const scheme = useColorScheme()
66
+ * React.useEffect(() => store.setTheme(scheme === 'dark' ? 'dark' : 'light'), [scheme])
67
+ * ```
68
+ */
69
+ declare function useColorScheme(): ColorScheme;
70
+
71
+ export { ThemeProvider, type ThemeProviderProps, type UseThemeReturn, useColorScheme, useDirection, useTheme, useThemeContext, useThemeOptional };
@@ -0,0 +1,71 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { ThemeStore, Direction, ColorScheme } from '@iris-ui-kit/theme';
4
+ import { IrisTheme } from '@iris-ui-kit/tokens';
5
+
6
+ interface IrisThemeContextValue {
7
+ store: ThemeStore;
8
+ current: IrisTheme;
9
+ dir: Direction;
10
+ }
11
+ interface ThemeProviderProps {
12
+ store: ThemeStore;
13
+ target?: HTMLElement | null;
14
+ /** Writing direction; sets `dir` on the target for RTL. Default `'ltr'`. */
15
+ dir?: Direction;
16
+ /** CSP nonce for the injected global stylesheet. Pass the `nonce` from your
17
+ * server-rendered CSP header when you use `style-src: 'nonce-...'`. */
18
+ cspNonce?: string;
19
+ children?: ReactNode;
20
+ }
21
+ /**
22
+ * Renderless provider that mirrors `<IrisThemeProvider>` from `@iris-ui-kit/vue`:
23
+ * subscribes to the theme store, applies CSS variables to `target` (or
24
+ * `document.documentElement`), reverts on unmount.
25
+ *
26
+ * **Zero business logic** — `applyTheme` / `createThemeStore` come straight
27
+ * from `@iris-ui-kit/theme`. This component is just a 30-line React adapter.
28
+ */
29
+ declare function ThemeProvider({ store, target, dir, cspNonce, children, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
30
+ declare function useThemeContext(): IrisThemeContextValue;
31
+ /**
32
+ * Read the current theme without throwing when there is no `<ThemeProvider>`
33
+ * ancestor. Returns `undefined` outside a provider. Used by theme-aware
34
+ * primitives (e.g. `IrisIcon`) that must still render standalone.
35
+ */
36
+ declare function useThemeOptional(): IrisTheme | undefined;
37
+ /**
38
+ * Current writing direction (`'ltr'` / `'rtl'`) from the nearest
39
+ * `<ThemeProvider>`, or `'ltr'` when there is none. For components that need to
40
+ * branch on direction beyond what CSS logical properties already handle.
41
+ */
42
+ declare function useDirection(): Direction;
43
+
44
+ interface UseThemeReturn {
45
+ theme: IrisTheme;
46
+ setTheme: (target: string | IrisTheme) => void;
47
+ availableThemes: Record<string, IrisTheme>;
48
+ }
49
+ /**
50
+ * Read and write the current theme from anywhere inside a `<ThemeProvider>`.
51
+ *
52
+ * @example
53
+ * const { theme, setTheme } = useTheme()
54
+ * setTheme('dark')
55
+ */
56
+ declare function useTheme(): UseThemeReturn;
57
+
58
+ /**
59
+ * Reactive system color scheme (`'light'` / `'dark'`) from
60
+ * `prefers-color-scheme`. Re-renders the host when the OS preference flips.
61
+ * SSR-safe (reports `'light'` until mounted). Wire it to a theme store to
62
+ * auto-follow the system:
63
+ *
64
+ * ```tsx
65
+ * const scheme = useColorScheme()
66
+ * React.useEffect(() => store.setTheme(scheme === 'dark' ? 'dark' : 'light'), [scheme])
67
+ * ```
68
+ */
69
+ declare function useColorScheme(): ColorScheme;
70
+
71
+ export { ThemeProvider, type ThemeProviderProps, type UseThemeReturn, useColorScheme, useDirection, useTheme, useThemeContext, useThemeOptional };
package/dist/theme.js ADDED
@@ -0,0 +1,5 @@
1
+ 'use client'
2
+ export { ThemeProvider, useColorScheme, useDirection, useTheme, useThemeContext, useThemeOptional } from './chunk-XCK4RIXB.js';
3
+ import './chunk-RZNYIFV2.js';
4
+ //# sourceMappingURL=theme.js.map
5
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":";","file":"theme.js"}
package/dist/undo.cjs ADDED
@@ -0,0 +1,73 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+ var undo = require('@iris-ui-kit/core/undo');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
26
+
27
+ // src/undo/useUndoStack.ts
28
+ function useUndoStack(options) {
29
+ const stackRef = React__namespace.useRef(null);
30
+ if (stackRef.current === null) {
31
+ stackRef.current = undo.createUndoStack(options);
32
+ }
33
+ const stack = stackRef.current;
34
+ const [, setTick] = React__namespace.useState(0);
35
+ const bump = React__namespace.useCallback(() => setTick((n) => n + 1), []);
36
+ const push = React__namespace.useCallback(
37
+ (snapshot) => {
38
+ const result = stack.push(snapshot);
39
+ bump();
40
+ return result;
41
+ },
42
+ [stack, bump]
43
+ );
44
+ const undo$1 = React__namespace.useCallback(() => {
45
+ const result = stack.undo();
46
+ if (result !== void 0) bump();
47
+ return result;
48
+ }, [stack, bump]);
49
+ const redo = React__namespace.useCallback(() => {
50
+ const result = stack.redo();
51
+ if (result !== void 0) bump();
52
+ return result;
53
+ }, [stack, bump]);
54
+ const clear = React__namespace.useCallback(() => {
55
+ stack.clear();
56
+ bump();
57
+ }, [stack, bump]);
58
+ const state = {
59
+ canUndo: stack.canUndo(),
60
+ canRedo: stack.canRedo(),
61
+ depth: stack.depth,
62
+ index: stack.index
63
+ };
64
+ return { push, undo: undo$1, redo, clear, stack, state };
65
+ }
66
+
67
+ Object.defineProperty(exports, "createUndoStack", {
68
+ enumerable: true,
69
+ get: function () { return undo.createUndoStack; }
70
+ });
71
+ exports.useUndoStack = useUndoStack;
72
+ //# sourceMappingURL=undo.cjs.map
73
+ //# sourceMappingURL=undo.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/undo/useUndoStack.ts"],"names":["React","createUndoStack","undo"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCO,SAAS,aAAgB,OAAA,EAa9B;AAEA,EAAA,MAAM,QAAA,GAAiBA,wBAA4B,IAAI,CAAA;AACvD,EAAA,IAAI,QAAA,CAAS,YAAY,IAAA,EAAM;AAC7B,IAAA,QAAA,CAAS,OAAA,GAAUC,qBAAmB,OAAO,CAAA;AAAA,EAC/C;AACA,EAAA,MAAM,QAAQ,QAAA,CAAS,OAAA;AAKvB,EAAA,MAAM,GAAG,OAAO,CAAA,GAAUD,0BAAS,CAAC,CAAA;AACpC,EAAA,MAAM,IAAA,GAAaA,gBAAA,CAAA,WAAA,CAAY,MAAM,OAAA,CAAQ,CAAC,MAAM,CAAA,GAAI,CAAC,CAAA,EAAG,EAAE,CAAA;AAG9D,EAAA,MAAM,IAAA,GAAaA,gBAAA,CAAA,WAAA;AAAA,IACjB,CAAC,QAAA,KAAmB;AAClB,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,QAAQ,CAAA;AAClC,MAAA,IAAA,EAAK;AACL,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,CAAC,OAAO,IAAI;AAAA,GACd;AAEA,EAAA,MAAME,MAAA,GAAaF,6BAAY,MAAqB;AAClD,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,EAAK;AAC1B,IAAA,IAAI,MAAA,KAAW,QAAW,IAAA,EAAK;AAC/B,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAEhB,EAAA,MAAM,IAAA,GAAaA,6BAAY,MAAqB;AAClD,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,EAAK;AAC1B,IAAA,IAAI,MAAA,KAAW,QAAW,IAAA,EAAK;AAC/B,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAEhB,EAAA,MAAM,KAAA,GAAcA,6BAAY,MAAM;AACpC,IAAA,KAAA,CAAM,KAAA,EAAM;AACZ,IAAA,IAAA,EAAK;AAAA,EACP,CAAA,EAAG,CAAC,KAAA,EAAO,IAAI,CAAC,CAAA;AAIhB,EAAA,MAAM,KAAA,GAAgC;AAAA,IACpC,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,IACvB,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,IACvB,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,OAAO,KAAA,CAAM;AAAA,GACf;AAEA,EAAA,OAAO,EAAE,IAAA,QAAME,MAAA,EAAM,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA,EAAM;AACjD","file":"undo.cjs","sourcesContent":["import * as React from 'react'\nimport { createUndoStack, type UndoStack, type UndoStackOptions } from '@iris-ui-kit/core/undo'\n\n/**\n * Reactive snapshot metadata for the UndoStack: convenience booleans that\n * update on every push/undo/redo/clear for use in UI bindings (enable/disable\n * undo/redo buttons).\n */\nexport interface UndoStackReactiveState {\n canUndo: boolean\n canRedo: boolean\n depth: number\n index: number\n}\n\n/**\n * React bridge over the framework-agnostic {@link createUndoStack}.\n * Creates the stack once (via a factory memo) and returns a stable controller\n * plus a reactive `state` that tracks `canUndo`/`canRedo`/`depth`/`index` for\n * easy UI binding. Re-renders only when those metadata change.\n *\n * The returned `push`/`undo`/`redo`/`clear` are stable refs that automatically\n * update the reactive state — no manual `setState` needed.\n *\n * @example\n * const { push, undo, redo, state } = useUndoStack({ initial: formValues })\n * // After mutation:\n * push(currentValues)\n * // In UI:\n * <button disabled={!state.canUndo} onClick={undo}>Undo</button>\n * <button disabled={!state.canRedo} onClick={redo}>Redo</button>\n */\nexport function useUndoStack<T>(options?: UndoStackOptions<T>): {\n /** Push a new snapshot onto the stack. Returns the stored value. */\n push: (snapshot: T) => T\n /** Undo: returns the previous snapshot, or undefined if nothing to undo. */\n undo: () => T | undefined\n /** Redo: returns the next snapshot, or undefined if nothing to redo. */\n redo: () => T | undefined\n /** Clear all history. */\n clear: () => void\n /** The raw undo stack (stable reference, same across renders). */\n stack: UndoStack<T>\n /** Reactive metadata: canUndo, canRedo, depth, index. */\n state: UndoStackReactiveState\n} {\n // Create the stack once via factory — stable across renders.\n const stackRef = React.useRef<UndoStack<T> | null>(null)\n if (stackRef.current === null) {\n stackRef.current = createUndoStack<T>(options)\n }\n const stack = stackRef.current\n\n // Key to trigger re-render when undo/redo/push state changes.\n // Incremented on every mutation so canUndo/canRedo/depth/index are\n // always fresh in the returned `state`.\n const [, setTick] = React.useState(0)\n const bump = React.useCallback(() => setTick((n) => n + 1), [])\n\n // Stable wrappers that bump the tick after each operation.\n const push = React.useCallback(\n (snapshot: T): T => {\n const result = stack.push(snapshot)\n bump()\n return result\n },\n [stack, bump],\n )\n\n const undo = React.useCallback((): T | undefined => {\n const result = stack.undo()\n if (result !== undefined) bump()\n return result\n }, [stack, bump])\n\n const redo = React.useCallback((): T | undefined => {\n const result = stack.redo()\n if (result !== undefined) bump()\n return result\n }, [stack, bump])\n\n const clear = React.useCallback(() => {\n stack.clear()\n bump()\n }, [stack, bump])\n\n // Compute reactive state. `canUndo`/`canRedo` are methods on the interface,\n // so we call them each render to get current values.\n const state: UndoStackReactiveState = {\n canUndo: stack.canUndo(),\n canRedo: stack.canRedo(),\n depth: stack.depth,\n index: stack.index,\n }\n\n return { push, undo, redo, clear, stack, state }\n}\n"]}
@@ -0,0 +1,47 @@
1
+ import { UndoStackOptions, UndoStack } from '@iris-ui-kit/core/undo';
2
+ export { UndoStack, UndoStackOptions, createUndoStack } from '@iris-ui-kit/core/undo';
3
+
4
+ /**
5
+ * Reactive snapshot metadata for the UndoStack: convenience booleans that
6
+ * update on every push/undo/redo/clear for use in UI bindings (enable/disable
7
+ * undo/redo buttons).
8
+ */
9
+ interface UndoStackReactiveState {
10
+ canUndo: boolean;
11
+ canRedo: boolean;
12
+ depth: number;
13
+ index: number;
14
+ }
15
+ /**
16
+ * React bridge over the framework-agnostic {@link createUndoStack}.
17
+ * Creates the stack once (via a factory memo) and returns a stable controller
18
+ * plus a reactive `state` that tracks `canUndo`/`canRedo`/`depth`/`index` for
19
+ * easy UI binding. Re-renders only when those metadata change.
20
+ *
21
+ * The returned `push`/`undo`/`redo`/`clear` are stable refs that automatically
22
+ * update the reactive state — no manual `setState` needed.
23
+ *
24
+ * @example
25
+ * const { push, undo, redo, state } = useUndoStack({ initial: formValues })
26
+ * // After mutation:
27
+ * push(currentValues)
28
+ * // In UI:
29
+ * <button disabled={!state.canUndo} onClick={undo}>Undo</button>
30
+ * <button disabled={!state.canRedo} onClick={redo}>Redo</button>
31
+ */
32
+ declare function useUndoStack<T>(options?: UndoStackOptions<T>): {
33
+ /** Push a new snapshot onto the stack. Returns the stored value. */
34
+ push: (snapshot: T) => T;
35
+ /** Undo: returns the previous snapshot, or undefined if nothing to undo. */
36
+ undo: () => T | undefined;
37
+ /** Redo: returns the next snapshot, or undefined if nothing to redo. */
38
+ redo: () => T | undefined;
39
+ /** Clear all history. */
40
+ clear: () => void;
41
+ /** The raw undo stack (stable reference, same across renders). */
42
+ stack: UndoStack<T>;
43
+ /** Reactive metadata: canUndo, canRedo, depth, index. */
44
+ state: UndoStackReactiveState;
45
+ };
46
+
47
+ export { type UndoStackReactiveState, useUndoStack };
package/dist/undo.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { UndoStackOptions, UndoStack } from '@iris-ui-kit/core/undo';
2
+ export { UndoStack, UndoStackOptions, createUndoStack } from '@iris-ui-kit/core/undo';
3
+
4
+ /**
5
+ * Reactive snapshot metadata for the UndoStack: convenience booleans that
6
+ * update on every push/undo/redo/clear for use in UI bindings (enable/disable
7
+ * undo/redo buttons).
8
+ */
9
+ interface UndoStackReactiveState {
10
+ canUndo: boolean;
11
+ canRedo: boolean;
12
+ depth: number;
13
+ index: number;
14
+ }
15
+ /**
16
+ * React bridge over the framework-agnostic {@link createUndoStack}.
17
+ * Creates the stack once (via a factory memo) and returns a stable controller
18
+ * plus a reactive `state` that tracks `canUndo`/`canRedo`/`depth`/`index` for
19
+ * easy UI binding. Re-renders only when those metadata change.
20
+ *
21
+ * The returned `push`/`undo`/`redo`/`clear` are stable refs that automatically
22
+ * update the reactive state — no manual `setState` needed.
23
+ *
24
+ * @example
25
+ * const { push, undo, redo, state } = useUndoStack({ initial: formValues })
26
+ * // After mutation:
27
+ * push(currentValues)
28
+ * // In UI:
29
+ * <button disabled={!state.canUndo} onClick={undo}>Undo</button>
30
+ * <button disabled={!state.canRedo} onClick={redo}>Redo</button>
31
+ */
32
+ declare function useUndoStack<T>(options?: UndoStackOptions<T>): {
33
+ /** Push a new snapshot onto the stack. Returns the stored value. */
34
+ push: (snapshot: T) => T;
35
+ /** Undo: returns the previous snapshot, or undefined if nothing to undo. */
36
+ undo: () => T | undefined;
37
+ /** Redo: returns the next snapshot, or undefined if nothing to redo. */
38
+ redo: () => T | undefined;
39
+ /** Clear all history. */
40
+ clear: () => void;
41
+ /** The raw undo stack (stable reference, same across renders). */
42
+ stack: UndoStack<T>;
43
+ /** Reactive metadata: canUndo, canRedo, depth, index. */
44
+ state: UndoStackReactiveState;
45
+ };
46
+
47
+ export { type UndoStackReactiveState, useUndoStack };
package/dist/undo.js ADDED
@@ -0,0 +1,4 @@
1
+ 'use client'
2
+ export { createUndoStack, useUndoStack } from './chunk-YAHXR2CJ.js';
3
+ //# sourceMappingURL=undo.js.map
4
+ //# sourceMappingURL=undo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":";","file":"undo.js"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@iris-ui-kit/react",
3
+ "version": "0.1.0",
4
+ "description": "React 18/19 adapter for Iris UI — full component set",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ },
16
+ "./*": {
17
+ "types": "./dist/*.d.ts",
18
+ "import": "./dist/*.js",
19
+ "require": "./dist/*.cjs"
20
+ },
21
+ "./package.json": "./package.json"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "sideEffects": false,
27
+ "dependencies": {
28
+ "@floating-ui/dom": "^1.7.6",
29
+ "@iris-ui-kit/core": "0.1.0",
30
+ "@iris-ui-kit/icons": "0.1.0",
31
+ "@iris-ui-kit/skins": "0.0.1",
32
+ "@iris-ui-kit/theme": "0.1.0",
33
+ "@iris-ui-kit/tokens": "0.1.0"
34
+ },
35
+ "peerDependencies": {
36
+ "react": "^18.0.0 || ^19.0.0",
37
+ "react-dom": "^18.0.0 || ^19.0.0"
38
+ },
39
+ "devDependencies": {
40
+ "@testing-library/react": "^16.1.0",
41
+ "@types/react": "^18.3.0",
42
+ "@types/react-dom": "^18.3.0",
43
+ "react": "^18.3.1",
44
+ "react-dom": "^18.3.1"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/nousresearch/iris-ui.git"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "scripts": {
54
+ "build": "tsup",
55
+ "dev": "tsup --watch",
56
+ "test": "vitest run",
57
+ "typecheck": "tsc --noEmit",
58
+ "lint": "eslint src",
59
+ "clean": "rm -rf dist .turbo"
60
+ }
61
+ }