@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/form.d.ts ADDED
@@ -0,0 +1,120 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { FormValues, FormStore, FormState, FormConfig } from '@iris-ui-kit/core';
4
+
5
+ interface IrisFormProps<V extends FormValues> extends Omit<React.FormHTMLAttributes<HTMLFormElement>, 'onSubmit'> {
6
+ /** The store from `useForm(...).form`. */
7
+ form: FormStore<V>;
8
+ children?: React.ReactNode;
9
+ }
10
+ /**
11
+ * Provides the form store to descendant `useField` calls and wires the native
12
+ * `<form>` submit to `handleSubmit` (with `preventDefault`).
13
+ *
14
+ * @example
15
+ * const f = useForm({ initialValues: { email: '' }, onSubmit })
16
+ * <IrisForm form={f.form}>
17
+ * <IrisFormField label="Email"><EmailField /></IrisFormField>
18
+ * <IrisButton type="submit" disabled={f.isSubmitting}>Save</IrisButton>
19
+ * </IrisForm>
20
+ */
21
+ declare function IrisForm<V extends FormValues>({ form, children, ...rest }: IrisFormProps<V>): react_jsx_runtime.JSX.Element;
22
+
23
+ interface UseFormReturn<V extends FormValues> extends FormState<V> {
24
+ /** Underlying subscribable store. */
25
+ store: FormStore<V>['store'];
26
+ /** The form store itself — pass to `<IrisForm form={...}>`. */
27
+ form: FormStore<V>;
28
+ isValid: boolean;
29
+ setFieldValue: FormStore<V>['setFieldValue'];
30
+ setValues: FormStore<V>['setValues'];
31
+ setFieldTouched: FormStore<V>['setFieldTouched'];
32
+ setFieldError: FormStore<V>['setFieldError'];
33
+ setErrors: FormStore<V>['setErrors'];
34
+ validateField: FormStore<V>['validateField'];
35
+ validateForm: FormStore<V>['validateForm'];
36
+ handleSubmit: FormStore<V>['handleSubmit'];
37
+ reset: FormStore<V>['reset'];
38
+ }
39
+ /**
40
+ * React binding for the framework-agnostic form engine. Instantiates the store
41
+ * once (like `useState`'s lazy initializer) and bridges it into React via
42
+ * `useSyncExternalStore`. `initialValues` / `validators` / timing are captured
43
+ * on first render; `onSubmit` and `validate` are read through a ref each render
44
+ * so they always see the latest closures (no stale-callback footgun).
45
+ */
46
+ declare function useForm<V extends FormValues>(config: FormConfig<V>): UseFormReturn<V>;
47
+
48
+ interface FieldInputProps {
49
+ name: string;
50
+ value: string;
51
+ onChange: (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
52
+ onBlur: () => void;
53
+ }
54
+ interface UseFieldReturn<T> {
55
+ name: string;
56
+ value: T;
57
+ error: string | undefined;
58
+ touched: boolean;
59
+ dirty: boolean;
60
+ setValue: (value: T) => void;
61
+ setTouched: (touched?: boolean) => void;
62
+ /**
63
+ * Convenience bundle for a native text input / textarea. Spread onto
64
+ * `IrisInput` / `IrisTextarea`. Non-text controls (checkbox, select,
65
+ * number, custom) should wire `value` + `setValue` directly.
66
+ */
67
+ inputProps: FieldInputProps;
68
+ }
69
+ /**
70
+ * Binds a single field to the surrounding `<IrisForm>`. Re-renders only its
71
+ * host component when the form store changes. `T` is the value type at the
72
+ * call site (the context erases the form's generic).
73
+ *
74
+ * `name` may be a flat top-level key (`'email'`) OR a nested PATH
75
+ * (`'address.city'`, `'items[2].sku'`) — the form keys its per-field state by
76
+ * the canonical path, so a flat key is just a 1-segment path and stays 100%
77
+ * back-compatible (v3 R19).
78
+ */
79
+ declare function useField<T = unknown>(name: string): UseFieldReturn<T>;
80
+
81
+ interface UseFieldArrayReturn<T> {
82
+ name: string;
83
+ /** Current array value (reactive). */
84
+ fields: T[];
85
+ /** Append an item. */
86
+ push: (item: T) => void;
87
+ /** Remove the item at `index`. */
88
+ remove: (index: number) => void;
89
+ /** Insert `item` at `index` (shifting the rest right). */
90
+ insert: (index: number, item: T) => void;
91
+ /** Move the item from `from` to `to`. */
92
+ move: (from: number, to: number) => void;
93
+ /** Replace the whole array. */
94
+ replace: (items: T[]) => void;
95
+ }
96
+ /**
97
+ * Manage a dynamic array field (repeatable rows) inside an `<IrisForm>`. Mutators
98
+ * delegate to the core {@link FormStore} array helpers (`arrayPush`/`arrayInsert`/
99
+ * `arrayRemove`/`arrayMove`), which RE-KEY each element's error/touched/dirty/
100
+ * validating state across the mutation — so a row's per-element validation state
101
+ * FOLLOWS the row when rows are removed or reordered (removing `items[0]` shifts
102
+ * `items[2]`'s error down to `items[1]`). `replace` swaps the whole array.
103
+ *
104
+ * ```tsx
105
+ * const items = useFieldArray<{ sku: string }>('items')
106
+ * items.fields.map((_, i) => <SkuRow key={i} index={i} />)
107
+ * <button onClick={() => items.push({ sku: '' })}>Add</button>
108
+ * ```
109
+ */
110
+ declare function useFieldArray<T = unknown>(name: string): UseFieldArrayReturn<T>;
111
+
112
+ /**
113
+ * Carries the active form's {@link FormStore} down to descendant fields so
114
+ * `useField` can bind without prop drilling. The generic is erased at the
115
+ * context boundary; `useField<T>` re-applies the value type at the call site.
116
+ */
117
+ declare const FormContext: React.Context<FormStore<FormValues> | null>;
118
+ declare function useFormContext(): FormStore<FormValues>;
119
+
120
+ export { type FieldInputProps, FormContext, IrisForm, type IrisFormProps, type UseFieldArrayReturn, type UseFieldReturn, type UseFormReturn, useField, useFieldArray, useForm, useFormContext };
package/dist/form.js ADDED
@@ -0,0 +1,5 @@
1
+ 'use client'
2
+ export { FormContext, IrisForm, useField, useFieldArray, useForm, useFormContext } from './chunk-DE6V6NOI.js';
3
+ import './chunk-RZNYIFV2.js';
4
+ //# sourceMappingURL=form.js.map
5
+ //# sourceMappingURL=form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":";","file":"form.js"}
package/dist/i18n.cjs ADDED
@@ -0,0 +1,100 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ var React2 = require('react');
5
+ var core = require('@iris-ui-kit/core');
6
+ var theme = require('@iris-ui-kit/theme');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
28
+
29
+ // src/i18n/I18nProvider.tsx
30
+ var I18nContext = React2__namespace.createContext(null);
31
+ function IrisI18nProvider({
32
+ locale,
33
+ messages,
34
+ i18n,
35
+ autoDirection,
36
+ directionTarget,
37
+ children
38
+ }) {
39
+ const ref = React2__namespace.useRef(null);
40
+ if (ref.current === null) {
41
+ ref.current = i18n ?? core.createI18n({ locale, messages });
42
+ }
43
+ const instance = ref.current;
44
+ React2__namespace.useEffect(() => {
45
+ if (i18n || !locale) return;
46
+ instance.setLocale(locale);
47
+ }, [locale, i18n, instance]);
48
+ React2__namespace.useEffect(() => {
49
+ if (i18n || !messages) return;
50
+ instance.setMessages(messages);
51
+ }, [messages, i18n, instance]);
52
+ React2__namespace.useEffect(() => {
53
+ if (!autoDirection || !locale || typeof document === "undefined") return;
54
+ const el = directionTarget ?? document.documentElement;
55
+ const applied = theme.applyDirection(core.localeDirection(locale), el);
56
+ const prevLang = el.getAttribute("lang");
57
+ el.setAttribute("lang", locale);
58
+ return () => {
59
+ applied.revert();
60
+ if (prevLang === null) el.removeAttribute("lang");
61
+ else el.setAttribute("lang", prevLang);
62
+ };
63
+ }, [autoDirection, locale, directionTarget]);
64
+ return /* @__PURE__ */ jsxRuntime.jsx(I18nContext.Provider, { value: instance, children });
65
+ }
66
+ function useStore(store) {
67
+ return React2.useSyncExternalStore(
68
+ store.subscribe,
69
+ store.getState,
70
+ store.getState
71
+ // SSR fallback — same as client snapshot in our case.
72
+ );
73
+ }
74
+
75
+ // src/i18n/useI18n.ts
76
+ var fallbackI18n = null;
77
+ function getFallback() {
78
+ if (fallbackI18n === null) fallbackI18n = core.createI18n();
79
+ return fallbackI18n;
80
+ }
81
+ function useI18n() {
82
+ const ctx = React2__namespace.useContext(I18nContext);
83
+ const i18n = ctx ?? getFallback();
84
+ const state = useStore(i18n.store);
85
+ return {
86
+ locale: state.locale,
87
+ t: i18n.t,
88
+ formatDate: i18n.formatDate,
89
+ formatNumber: i18n.formatNumber,
90
+ formatRelativeTime: i18n.formatRelativeTime,
91
+ setLocale: i18n.setLocale,
92
+ setMessages: i18n.setMessages
93
+ };
94
+ }
95
+
96
+ exports.I18nContext = I18nContext;
97
+ exports.IrisI18nProvider = IrisI18nProvider;
98
+ exports.useI18n = useI18n;
99
+ //# sourceMappingURL=i18n.cjs.map
100
+ //# sourceMappingURL=i18n.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/i18n/context.ts","../src/i18n/I18nProvider.tsx","../src/useStore.ts","../src/i18n/useI18n.ts"],"names":["React","React2","createI18n","applyDirection","localeDirection","useSyncExternalStore","React4"],"mappings":"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","file":"i18n.cjs","sourcesContent":["import * as React from 'react'\nimport type { I18n } from '@iris-ui-kit/core'\n\n/** Carries the active {@link I18n} instance to descendants via `useI18n`. */\nexport const I18nContext = React.createContext<I18n | null>(null)\n","import * as React from 'react'\nimport { createI18n, localeDirection, type I18n, type I18nMessages } from '@iris-ui-kit/core'\nimport { applyDirection } from '@iris-ui-kit/theme'\nimport { I18nContext } from './context'\n\nexport interface IrisI18nProviderProps {\n /** BCP-47 locale. Changes are synced to the live instance. */\n locale?: string\n /** Message overrides. Changes are merged into the live instance. */\n messages?: I18nMessages\n /** Provide a pre-created instance instead of `locale` / `messages`. */\n i18n?: I18n\n /**\n * When set, the locale's writing direction ({@link localeDirection}) is\n * applied to `directionTarget` (`dir` + `data-iris-dir`) and `<html lang>` is\n * set whenever `locale` changes — so \"set locale → flip direction + announce\n * language\" needs no manual wiring. Off by default so it never fights an\n * explicit `<ThemeProvider dir>`. Reverts on unmount.\n */\n autoDirection?: boolean\n /** Element to receive dir/lang when `autoDirection` is set. Defaults to `document.documentElement`. */\n directionTarget?: HTMLElement | null\n children?: React.ReactNode\n}\n\n/**\n * Makes a locale + message dictionary available to descendant components via\n * `useI18n`. Either pass `locale` / `messages` (an instance is created and\n * kept in sync) or a pre-built `i18n` instance you control externally.\n */\nexport function IrisI18nProvider({\n locale,\n messages,\n i18n,\n autoDirection,\n directionTarget,\n children,\n}: IrisI18nProviderProps) {\n const ref = React.useRef<I18n | null>(null)\n if (ref.current === null) {\n ref.current = i18n ?? createI18n({ locale, messages })\n }\n const instance = ref.current\n\n React.useEffect(() => {\n if (i18n || !locale) return\n instance.setLocale(locale)\n }, [locale, i18n, instance])\n\n React.useEffect(() => {\n if (i18n || !messages) return\n instance.setMessages(messages)\n }, [messages, i18n, instance])\n\n // Auto-apply writing direction + `lang` from the active locale (opt-in).\n React.useEffect(() => {\n if (!autoDirection || !locale || typeof document === 'undefined') return\n const el = directionTarget ?? document.documentElement\n const applied = applyDirection(localeDirection(locale), el)\n const prevLang = el.getAttribute('lang')\n el.setAttribute('lang', locale)\n return () => {\n applied.revert()\n if (prevLang === null) el.removeAttribute('lang')\n else el.setAttribute('lang', prevLang)\n }\n }, [autoDirection, locale, directionTarget])\n\n return <I18nContext.Provider value={instance}>{children}</I18nContext.Provider>\n}\n","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 * as React from 'react'\nimport { createI18n, type I18n } from '@iris-ui-kit/core'\nimport { useStore } from '../useStore'\nimport { I18nContext } from './context'\n\nexport interface UseI18nReturn {\n locale: string\n t: I18n['t']\n formatDate: I18n['formatDate']\n formatNumber: I18n['formatNumber']\n formatRelativeTime: I18n['formatRelativeTime']\n setLocale: I18n['setLocale']\n setMessages: I18n['setMessages']\n}\n\n// Shared fallback so components can call `useI18n()` without an enclosing\n// provider — they get English defaults rather than throwing.\nlet fallbackI18n: I18n | null = null\nfunction getFallback(): I18n {\n if (fallbackI18n === null) fallbackI18n = createI18n()\n return fallbackI18n\n}\n\n/**\n * Reactive access to the active locale + translation/formatting helpers.\n * Re-renders the host when the locale or messages change. Works with or\n * without an `<IrisI18nProvider>` (falls back to English defaults).\n */\nexport function useI18n(): UseI18nReturn {\n const ctx = React.useContext(I18nContext)\n const i18n = ctx ?? getFallback()\n const state = useStore(i18n.store)\n\n return {\n locale: state.locale,\n t: i18n.t,\n formatDate: i18n.formatDate,\n formatNumber: i18n.formatNumber,\n formatRelativeTime: i18n.formatRelativeTime,\n setLocale: i18n.setLocale,\n setMessages: i18n.setMessages,\n }\n}\n"]}
@@ -0,0 +1,50 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { I18nMessages, I18n } from '@iris-ui-kit/core';
4
+
5
+ interface IrisI18nProviderProps {
6
+ /** BCP-47 locale. Changes are synced to the live instance. */
7
+ locale?: string;
8
+ /** Message overrides. Changes are merged into the live instance. */
9
+ messages?: I18nMessages;
10
+ /** Provide a pre-created instance instead of `locale` / `messages`. */
11
+ i18n?: I18n;
12
+ /**
13
+ * When set, the locale's writing direction ({@link localeDirection}) is
14
+ * applied to `directionTarget` (`dir` + `data-iris-dir`) and `<html lang>` is
15
+ * set whenever `locale` changes — so "set locale → flip direction + announce
16
+ * language" needs no manual wiring. Off by default so it never fights an
17
+ * explicit `<ThemeProvider dir>`. Reverts on unmount.
18
+ */
19
+ autoDirection?: boolean;
20
+ /** Element to receive dir/lang when `autoDirection` is set. Defaults to `document.documentElement`. */
21
+ directionTarget?: HTMLElement | null;
22
+ children?: React.ReactNode;
23
+ }
24
+ /**
25
+ * Makes a locale + message dictionary available to descendant components via
26
+ * `useI18n`. Either pass `locale` / `messages` (an instance is created and
27
+ * kept in sync) or a pre-built `i18n` instance you control externally.
28
+ */
29
+ declare function IrisI18nProvider({ locale, messages, i18n, autoDirection, directionTarget, children, }: IrisI18nProviderProps): react_jsx_runtime.JSX.Element;
30
+
31
+ interface UseI18nReturn {
32
+ locale: string;
33
+ t: I18n['t'];
34
+ formatDate: I18n['formatDate'];
35
+ formatNumber: I18n['formatNumber'];
36
+ formatRelativeTime: I18n['formatRelativeTime'];
37
+ setLocale: I18n['setLocale'];
38
+ setMessages: I18n['setMessages'];
39
+ }
40
+ /**
41
+ * Reactive access to the active locale + translation/formatting helpers.
42
+ * Re-renders the host when the locale or messages change. Works with or
43
+ * without an `<IrisI18nProvider>` (falls back to English defaults).
44
+ */
45
+ declare function useI18n(): UseI18nReturn;
46
+
47
+ /** Carries the active {@link I18n} instance to descendants via `useI18n`. */
48
+ declare const I18nContext: React.Context<I18n | null>;
49
+
50
+ export { I18nContext, IrisI18nProvider, type IrisI18nProviderProps, type UseI18nReturn, useI18n };
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { I18nMessages, I18n } from '@iris-ui-kit/core';
4
+
5
+ interface IrisI18nProviderProps {
6
+ /** BCP-47 locale. Changes are synced to the live instance. */
7
+ locale?: string;
8
+ /** Message overrides. Changes are merged into the live instance. */
9
+ messages?: I18nMessages;
10
+ /** Provide a pre-created instance instead of `locale` / `messages`. */
11
+ i18n?: I18n;
12
+ /**
13
+ * When set, the locale's writing direction ({@link localeDirection}) is
14
+ * applied to `directionTarget` (`dir` + `data-iris-dir`) and `<html lang>` is
15
+ * set whenever `locale` changes — so "set locale → flip direction + announce
16
+ * language" needs no manual wiring. Off by default so it never fights an
17
+ * explicit `<ThemeProvider dir>`. Reverts on unmount.
18
+ */
19
+ autoDirection?: boolean;
20
+ /** Element to receive dir/lang when `autoDirection` is set. Defaults to `document.documentElement`. */
21
+ directionTarget?: HTMLElement | null;
22
+ children?: React.ReactNode;
23
+ }
24
+ /**
25
+ * Makes a locale + message dictionary available to descendant components via
26
+ * `useI18n`. Either pass `locale` / `messages` (an instance is created and
27
+ * kept in sync) or a pre-built `i18n` instance you control externally.
28
+ */
29
+ declare function IrisI18nProvider({ locale, messages, i18n, autoDirection, directionTarget, children, }: IrisI18nProviderProps): react_jsx_runtime.JSX.Element;
30
+
31
+ interface UseI18nReturn {
32
+ locale: string;
33
+ t: I18n['t'];
34
+ formatDate: I18n['formatDate'];
35
+ formatNumber: I18n['formatNumber'];
36
+ formatRelativeTime: I18n['formatRelativeTime'];
37
+ setLocale: I18n['setLocale'];
38
+ setMessages: I18n['setMessages'];
39
+ }
40
+ /**
41
+ * Reactive access to the active locale + translation/formatting helpers.
42
+ * Re-renders the host when the locale or messages change. Works with or
43
+ * without an `<IrisI18nProvider>` (falls back to English defaults).
44
+ */
45
+ declare function useI18n(): UseI18nReturn;
46
+
47
+ /** Carries the active {@link I18n} instance to descendants via `useI18n`. */
48
+ declare const I18nContext: React.Context<I18n | null>;
49
+
50
+ export { I18nContext, IrisI18nProvider, type IrisI18nProviderProps, type UseI18nReturn, useI18n };
package/dist/i18n.js ADDED
@@ -0,0 +1,5 @@
1
+ 'use client'
2
+ export { I18nContext, IrisI18nProvider, useI18n } from './chunk-OMOTUHYI.js';
3
+ import './chunk-RZNYIFV2.js';
4
+ //# sourceMappingURL=i18n.js.map
5
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":";","file":"i18n.js"}