@anguszhu/kroma-ui 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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +185 -0
  3. package/dist/core/focusTrap.d.ts +3 -0
  4. package/dist/core/toastTimer.d.ts +13 -0
  5. package/dist/core/types.d.ts +35 -0
  6. package/dist/kroma-react.cjs +2 -0
  7. package/dist/kroma-react.cjs.map +1 -0
  8. package/dist/kroma-react.d.ts +2 -0
  9. package/dist/kroma-react.js +600 -0
  10. package/dist/kroma-react.js.map +1 -0
  11. package/dist/kroma-ui.css +804 -0
  12. package/dist/kroma-vue.cjs +2 -0
  13. package/dist/kroma-vue.cjs.map +1 -0
  14. package/dist/kroma-vue.d.ts +2 -0
  15. package/dist/kroma-vue.js +706 -0
  16. package/dist/kroma-vue.js.map +1 -0
  17. package/dist/kroma.css +804 -0
  18. package/dist/react/components/KrButton.d.ts +7 -0
  19. package/dist/react/components/KrChevron.d.ts +3 -0
  20. package/dist/react/components/KrDialog.d.ts +14 -0
  21. package/dist/react/components/KrEmpty.d.ts +7 -0
  22. package/dist/react/components/KrMenuItem.d.ts +7 -0
  23. package/dist/react/components/KrOverlay.d.ts +11 -0
  24. package/dist/react/components/KrSearchInput.d.ts +11 -0
  25. package/dist/react/components/KrSection.d.ts +6 -0
  26. package/dist/react/components/KrSelectGroup.d.ts +21 -0
  27. package/dist/react/components/KrSelectItem.d.ts +17 -0
  28. package/dist/react/components/KrSwitch.d.ts +7 -0
  29. package/dist/react/components/KrTextField.d.ts +10 -0
  30. package/dist/react/components/KrToast.d.ts +15 -0
  31. package/dist/react/components/KrToggleRow.d.ts +10 -0
  32. package/dist/react/hooks/useCssTransition.d.ts +12 -0
  33. package/dist/react/index.d.ts +28 -0
  34. package/dist/react/utils/cx.d.ts +1 -0
  35. package/dist/vue/components/KrButton.vue.d.ts +20 -0
  36. package/dist/vue/components/KrChevron.vue.d.ts +3 -0
  37. package/dist/vue/components/KrDialog.vue.d.ts +34 -0
  38. package/dist/vue/components/KrEmpty.vue.d.ts +17 -0
  39. package/dist/vue/components/KrMenuItem.vue.d.ts +15 -0
  40. package/dist/vue/components/KrOverlay.vue.d.ts +28 -0
  41. package/dist/vue/components/KrSearchInput.vue.d.ts +30 -0
  42. package/dist/vue/components/KrSection.vue.d.ts +17 -0
  43. package/dist/vue/components/KrSelectGroup.vue.d.ts +44 -0
  44. package/dist/vue/components/KrSelectItem.vue.d.ts +25 -0
  45. package/dist/vue/components/KrSwitch.vue.d.ts +12 -0
  46. package/dist/vue/components/KrTextField.vue.d.ts +13 -0
  47. package/dist/vue/components/KrToast.vue.d.ts +32 -0
  48. package/dist/vue/components/KrToggleRow.vue.d.ts +18 -0
  49. package/dist/vue/index.d.ts +20 -0
  50. package/package.json +92 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kroma contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # Kroma
2
+
3
+ A small, themeable component library — buttons, dialogs, toasts, switches,
4
+ selects, and a few other primitives, extracted from a real production app and
5
+ generalized for reuse. Ships idiomatic **Vue 3** and **React** implementations
6
+ from the same package, sharing CSS and framework-agnostic logic (focus
7
+ trapping, dismiss timers) so the two stay in lockstep.
8
+
9
+ - **Vue 3 `<script setup>`, or React 18+/19** — both fully typed, both
10
+ idiomatic to their framework (`v-model` in Vue, controlled props in React)
11
+ rather than a lowest-common-denominator API.
12
+ - **Themeable by design** — every color, spacing and radius is a CSS custom
13
+ property (`--kr-*`). Override any of them at `:root` or on a wrapper element
14
+ to reskin the whole library; nothing is hardcoded. The same stylesheet
15
+ styles both frameworks identically.
16
+ - **Light/dark for free** via native CSS `light-dark()` — components follow
17
+ `color-scheme`, no dark-mode class toggling required.
18
+ - **No icon font dependency.** Components that need an icon (search, clear,
19
+ toast status) ship a small inline SVG default and expose a slot (Vue) or a
20
+ `ReactNode` prop (React) to replace it with your own.
21
+ - **Tree-shakeable** — ESM + CJS builds, each component is a separate export.
22
+ - **Minimal dependencies** — `vue` and `react`/`react-dom` are the only peer
23
+ dependencies, and each is optional: installing Kroma for a React project
24
+ never pulls in Vue, and vice versa.
25
+
26
+ ## Requirements
27
+
28
+ Kroma's default theme uses `light-dark()` and `color-mix()`, so it targets
29
+ evergreen browsers (Chrome 123+, Safari 17.5+, Firefox 120+). `vue` (`^3.4.0`)
30
+ and `react`/`react-dom` (`^18.0.0 || ^19.0.0`) are both optional peer
31
+ dependencies — install whichever framework you're using.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ # Vue
37
+ npm install @anguszhu/kroma-ui vue
38
+
39
+ # React
40
+ npm install @anguszhu/kroma-ui react react-dom
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ Import the stylesheet once (usually in your app's entry point) — it's shared
46
+ by both frameworks:
47
+
48
+ ```ts
49
+ import '@anguszhu/kroma-ui/style.css'
50
+ ```
51
+
52
+ ### Vue
53
+
54
+ ```vue
55
+ <script setup lang="ts">
56
+ import { ref } from 'vue'
57
+ import { KrButton, KrDialog, KrTextField } from '@anguszhu/kroma-ui/vue'
58
+
59
+ const showDialog = ref(false)
60
+ const name = ref('')
61
+ </script>
62
+
63
+ <template>
64
+ <KrButton @click="showDialog = true">Rename</KrButton>
65
+
66
+ <KrDialog
67
+ v-model:show="showDialog"
68
+ title="Rename bookmark"
69
+ :actions="[{ text: 'Save', action: () => save() }]"
70
+ >
71
+ <KrTextField v-model="name" label="Name" autofocus />
72
+ </KrDialog>
73
+ </template>
74
+ ```
75
+
76
+ ### React
77
+
78
+ ```tsx
79
+ import { useState } from 'react'
80
+ import { KrButton, KrDialog, KrTextField } from '@anguszhu/kroma-ui/react'
81
+
82
+ export function RenameButton() {
83
+ const [showDialog, setShowDialog] = useState(false)
84
+ const [name, setName] = useState('')
85
+
86
+ return (
87
+ <>
88
+ <KrButton onClick={() => setShowDialog(true)}>Rename</KrButton>
89
+
90
+ <KrDialog
91
+ show={showDialog}
92
+ onShowChange={setShowDialog}
93
+ title="Rename bookmark"
94
+ actions={[{ text: 'Save', action: () => save() }]}
95
+ >
96
+ <KrTextField value={name} onValueChange={setName} label="Name" autofocus />
97
+ </KrDialog>
98
+ </>
99
+ )
100
+ }
101
+ ```
102
+
103
+ Prop names carry the same meaning across both frameworks, translated to each
104
+ framework's own idiom: Vue's `v-model:show` / `@update:show` pairs with
105
+ React's `show` / `onShowChange`; Vue's `provide`/`inject` (used internally by
106
+ `KrSelectGroup`) pairs with a React `Context`. Component and prop names
107
+ otherwise match 1:1.
108
+
109
+ ## Components
110
+
111
+ | Component | Description |
112
+ | --- | --- |
113
+ | `KrButton` | `primary` / `secondary` / `link` button variants. |
114
+ | `KrOverlay` | Fixed-position scrim + content slot with enter/leave transitions. Building block for dialogs, menus and popovers. |
115
+ | `KrDialog` | Modal dialog built on `KrOverlay` — title, body text, a default slot for arbitrary form content, and an `actions` array. Handles Escape-to-close and Tab focus trapping. |
116
+ | `KrSection` | A titled card/section wrapper. |
117
+ | `KrSelectGroup` / `KrSelectItem` | Single-select radio group with `default` / `color` / `icon` / `card` / `text` visual variants, and shapes `square` / `circle` / `rounded`. Use `KrSelectItem` standalone or let the group render items from a data array. |
118
+ | `KrSwitch` | Visual toggle switch (presentational — pair it with a native checkbox, the way `KrToggleRow` does, for accessible standalone use). |
119
+ | `KrToggleRow` | An accessible label + native checkbox + `KrSwitch`, with optional title/subtitle. |
120
+ | `KrTextField` | Labeled text input with an error state (shake animation + red outline). |
121
+ | `KrSearchInput` | Pill-shaped search input with a clear button; `label` / `clearLabel` props for i18n. |
122
+ | `KrToast` | Auto-dismissing status toast with an optional action button and countdown. |
123
+ | `KrEmpty` | Empty-state placeholder: icon slot, title, description. |
124
+ | `KrMenuItem` | A single menu row (or `type="divider"`), with an optional icon slot/prop. |
125
+ | `KrChevron` | A tiny CSS-only directional triangle, handy as a disclosure indicator. |
126
+
127
+ Every component's props and emitted events are typed — import the exported
128
+ `Kr*` types (e.g. `KrSelectItemData`, `KrDialogAction`) from `@anguszhu/kroma-ui/vue` or
129
+ `@anguszhu/kroma-ui/react` alongside the components for full autocomplete.
130
+
131
+ ## Theming
132
+
133
+ Everything reads from a small set of semantic tokens defined in
134
+ `@anguszhu/kroma-ui/style.css` (see `src/styles/tokens.css` in this repo). To restyle,
135
+ override the tokens you care about — no build step, no config:
136
+
137
+ ```css
138
+ :root {
139
+ --kr-theme: #7c3aed; /* your brand accent */
140
+ --kr-theme-secondary: #a78bfa;
141
+ --kr-surface: #ffffff;
142
+ --kr-spacing-3: 20px;
143
+ --kr-font-family: "Inter", -apple-system, system-ui, sans-serif;
144
+ }
145
+ ```
146
+
147
+ Every component sets its own `font-family: var(--kr-font-family)` rather than
148
+ relying on inheriting whatever font the host page happens to have in scope at
149
+ that point in the DOM — the default is a system-font stack, so components
150
+ look right out of the box even before you override it.
151
+
152
+ Because the accent tokens are defined with `light-dark()`, you can supply a
153
+ dark-mode value in the same declaration: `--kr-theme: light-dark(#7c3aed,
154
+ #c4b5fd);`. Pair that with `color-scheme: light dark` (already set by the
155
+ `[data-kr-color-scheme="auto"]` selector Kroma ships) to switch automatically
156
+ with the OS.
157
+
158
+ ## Development
159
+
160
+ ```bash
161
+ npm install
162
+ npm run test # vitest — core logic + every component, both frameworks
163
+ npm run typecheck # vue-tsc (src/vue + src/core) and tsc (src/react + src/core)
164
+ npm run build # type declarations + ESM/CJS bundles for both entries + style.css
165
+ npm run storybook:vue # preview the Vue components at http://localhost:6006
166
+ npm run storybook:react # preview the React components at http://localhost:6007
167
+ ```
168
+
169
+ Source is split into `src/core` (framework-agnostic logic and types, not
170
+ published on its own), `src/vue`, and `src/react` — each component gets an
171
+ idiomatic, hand-authored implementation per framework, sharing one CSS file
172
+ per component (`src/styles/components/`) so the two can never visually drift
173
+ apart. Each component has a colocated `*.stories.ts`/`*.stories.tsx` file.
174
+ Storybook itself, `@storybook/*`, `.storybook*/`, and `*.stories.*` files are
175
+ dev-only tooling — `package.json`'s `files` field publishes only `dist/`, so
176
+ none of it ships to npm. `npm run build-storybook:vue` /
177
+ `npm run build-storybook:react` produce static `storybook-static/` sites if
178
+ you want to deploy a hosted preview separately.
179
+
180
+ ## What's not in here
181
+
182
+ This package intentionally ships only generic, product-agnostic UI. Anything
183
+ tied to a specific app's domain model (e.g. a bookmark tree, browser-specific
184
+ favicon fetching) stays in that app rather than leaking into a shared
185
+ component library.
@@ -0,0 +1,3 @@
1
+ export declare function focusableElements(container: HTMLElement | null): HTMLElement[];
2
+ export declare function focusNext(container: HTMLElement | null): void;
3
+ export declare function focusPrev(container: HTMLElement | null): void;
@@ -0,0 +1,13 @@
1
+ export interface DismissTimerCallbacks {
2
+ onDismiss: () => void;
3
+ onTick?: (remainingSeconds: number) => void;
4
+ }
5
+ export interface DismissTimerStartOptions {
6
+ timeoutSeconds: number;
7
+ showCountdown?: boolean;
8
+ }
9
+ export interface DismissTimer {
10
+ start(options: DismissTimerStartOptions): void;
11
+ clear(): void;
12
+ }
13
+ export declare function createDismissTimer(callbacks: DismissTimerCallbacks): DismissTimer;
@@ -0,0 +1,35 @@
1
+ export type KrButtonType = 'primary' | 'secondary' | 'link';
2
+ export interface KrDialogAction {
3
+ text: string;
4
+ action: () => void | Promise<void>;
5
+ disabled?: boolean;
6
+ }
7
+ export type KrToastIcon = 'success' | 'error';
8
+ export type KrSelectVariant = 'default' | 'color' | 'image' | 'icon' | 'card' | 'text';
9
+ export type KrSelectShape = 'square' | 'circle' | 'rounded';
10
+ export interface KrSelectItemData {
11
+ label: string;
12
+ value: string | number;
13
+ disabled?: boolean;
14
+ hex?: string;
15
+ icon?: string;
16
+ description?: string;
17
+ }
18
+ export interface KrSelectItemProps {
19
+ value: string | number;
20
+ label?: string;
21
+ title?: string;
22
+ selected?: string | number;
23
+ disabled?: boolean;
24
+ variant?: KrSelectVariant;
25
+ shape?: KrSelectShape;
26
+ circle?: boolean;
27
+ stretch?: boolean;
28
+ showItemLabel?: boolean;
29
+ }
30
+ export interface KrMenuItemData {
31
+ title?: string;
32
+ value?: unknown;
33
+ disabled?: boolean;
34
+ type?: string;
35
+ }
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("react/jsx-runtime"),t=require("react");function n(...e){return e.filter(Boolean).join(` `)}function r({className:t,...r}){return(0,e.jsx)(`div`,{className:n(`kr-chevron`,t),...r})}var i=(0,e.jsxs)(`svg`,{viewBox:`0 0 64 64`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`,children:[(0,e.jsx)(`rect`,{x:`10`,y:`24`,width:`44`,height:`30`,rx:`4`,stroke:`var(--kr-on-surface-tertiary)`,strokeWidth:`2`}),(0,e.jsx)(`path`,{d:`M10 26L18 10H46L54 26`,stroke:`var(--kr-on-surface-tertiary)`,strokeWidth:`2`,strokeLinejoin:`round`}),(0,e.jsx)(`path`,{d:`M24 34H40`,stroke:`var(--kr-theme)`,strokeWidth:`2`,strokeLinecap:`round`})]});function a({title:t,description:r,icon:a,className:o,...s}){return(0,e.jsxs)(`div`,{className:n(`kr-empty`,o),...s,children:[(0,e.jsx)(`div`,{className:`kr-empty__icon`,children:a??i}),(0,e.jsx)(`h1`,{className:`kr-empty__title`,children:t}),(0,e.jsx)(`p`,{className:`kr-empty__description`,children:r})]})}function o({title:t,subtitle:r,className:i,children:a,...o}){return(0,e.jsxs)(`section`,{className:n(`kr-section`,i),...o,children:[(t||r)&&(0,e.jsxs)(`header`,{className:`kr-section__header`,children:[t&&(0,e.jsx)(`h1`,{className:`kr-section__title`,children:t}),r&&(0,e.jsx)(`h2`,{className:`kr-section__subtitle`,children:r})]}),(0,e.jsx)(`div`,{className:`kr-section__content`,children:a})]})}function s({title:t,value:r,disabled:i,type:a,icon:o,className:s,...c}){return a===`divider`?(0,e.jsx)(`hr`,{className:n(`kr-menu-item--divider`,s)}):(0,e.jsxs)(`button`,{className:n(`kr-menu-item`,s),disabled:i,role:`menuitem`,...c,children:[(0,e.jsx)(`div`,{className:`kr-menu-item__content`,children:t}),o&&(0,e.jsx)(`div`,{className:`kr-menu-item__icon`,"aria-hidden":`true`,children:o})]})}function c({type:t=`primary`,className:r,children:i,...a}){return(0,e.jsx)(`button`,{className:n(`kr-button`,`kr-button--${t}`,r),...a,children:i})}function l({checked:t=!1,disabled:r=!1,inset:i=!1,className:a,...o}){return(0,e.jsxs)(`div`,{className:n(`kr-switch`,i&&`kr-switch--inset`,a),"data-checked":t,"data-disabled":r,"aria-hidden":`true`,...o,children:[(0,e.jsx)(`div`,{className:`kr-switch__track`}),(0,e.jsx)(`div`,{className:`kr-switch__thumb`})]})}function u({checked:t=!1,onCheckedChange:r,title:i,subtitle:a,disabled:o=!1,hideSeparator:s=!1,className:c,...u}){function d(e){r?.(e.target.checked)}return(0,e.jsxs)(`label`,{className:n(`kr-toggle-row`,!s&&`kr-toggle-row--with-separator`,o&&`kr-toggle-row--disabled`,c),...u,children:[(0,e.jsx)(`input`,{className:`kr-toggle-row__native`,type:`checkbox`,role:`switch`,checked:t,disabled:o,"aria-label":i,onChange:d}),(0,e.jsxs)(`div`,{className:`kr-toggle-row__label`,children:[i&&(0,e.jsx)(`div`,{className:`kr-toggle-row__title`,children:i}),a&&(0,e.jsx)(`div`,{className:`kr-toggle-row__subtitle`,children:a})]}),(0,e.jsx)(l,{checked:t,disabled:o})]})}function d({value:t,onValueChange:r,label:i,error:a,autofocus:o,className:s,...c}){function l(e){r?.(e.target.value.trim())}return(0,e.jsxs)(`label`,{className:n(`kr-textfield`,s),children:[i&&(0,e.jsx)(`span`,{className:`kr-textfield__label-text`,children:i}),(0,e.jsx)(`input`,{type:`text`,className:n(`kr-textfield__input`,a&&`kr-textfield__input--error`),value:t,onChange:l,autoFocus:o,...c})]})}var f=(0,e.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,width:`1em`,height:`1em`,children:[(0,e.jsx)(`circle`,{cx:`11`,cy:`11`,r:`7`,stroke:`currentColor`,strokeWidth:`2`}),(0,e.jsx)(`path`,{d:`M20 20L16.65 16.65`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`})]}),p=(0,e.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,width:`1em`,height:`1em`,children:(0,e.jsx)(`path`,{d:`M6 6L18 18M18 6L6 18`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`})});function m({value:n=``,onValueChange:r,autofocus:i=!0,label:a=`Search`,clearLabel:o=`Clear`,icon:s,clearIcon:c}){let l=(0,t.useRef)(null);function u(e){r?.(e),i&&l.current?.focus()}function d(e){u(e.target.value)}function m(){u(``)}function h(e){e.key===`Enter`&&m()}return(0,e.jsxs)(`div`,{className:`kr-search-input`,children:[(0,e.jsx)(`div`,{className:`kr-search-input__icon`,children:s??f}),(0,e.jsx)(`input`,{ref:l,className:`kr-search-input__input`,type:`text`,value:n,onChange:d,autoFocus:i,"aria-label":a}),(0,e.jsx)(`div`,{className:`kr-search-input__icon kr-search-input__icon--clear`,style:{display:n?void 0:`none`},onClick:m,role:`button`,tabIndex:0,"aria-label":o,onKeyDown:h,children:c??p})]})}var h=(0,t.createContext)(null);function g({value:r,label:i,title:a,selected:o,disabled:s,variant:c=`default`,shape:l=`rounded`,circle:u,stretch:d,showItemLabel:f=!0,onSelect:p,children:m}){let g=(0,t.useContext)(h),_=(g?.value??o)===r,v=g?.variant??c,y=u?`circle`:g?.shape??l,b=g?.showItemLabel??f?i??a:``;function x(e){s||(p?.(r),g?.onSelect(r))}return(0,e.jsxs)(`label`,{className:n(`kr-select-item`,_&&`kr-select-item--selected`,s&&`kr-select-item--disabled`,d&&`kr-select-item--stretch`,`kr-select-item--${v}`,`kr-select-item--${y}`),title:a,children:[(0,e.jsx)(`input`,{className:`kr-select-item__input`,type:`radio`,name:g?.name,value:r,checked:_,disabled:s,"aria-label":i||a||String(r),onChange:x}),(0,e.jsx)(`div`,{className:`kr-select-item__content`,children:m}),b&&(0,e.jsx)(`div`,{className:`kr-select-item__label`,children:b})]})}function _({title:r,subtitle:i,items:a,showItemLabel:o=!0,showTooltip:s=!0,value:c,onValueChange:l,hideSeparator:u,columns:d=`auto`,gap:f=`12px`,variant:p=`default`,shape:m=`rounded`,className:_,style:v,renderItem:y}){let[b]=(0,t.useState)(()=>`kr-select-group-${Math.random().toString(36).slice(2)}`),x=d===`auto`?{display:`flex`,flexWrap:`wrap`,gap:f}:{display:`grid`,gridTemplateColumns:`repeat(${d}, 1fr)`,gap:f};function S(e){l?.(e)}let C=(0,t.useMemo)(()=>({value:c,variant:p,shape:m,showItemLabel:o,name:b,onSelect:S}),[c,p,m,o,b,l]);return(0,e.jsxs)(`div`,{className:n(`kr-select-group`,!u&&`kr-select-group--with-separator`,_),style:v,children:[(r||i)&&(0,e.jsxs)(`div`,{className:`kr-select-group__header`,children:[r&&(0,e.jsx)(`div`,{className:`kr-select-group__header__title`,children:r}),i&&(0,e.jsx)(`div`,{className:`kr-select-group__header__subtitle`,children:i})]}),(0,e.jsx)(`div`,{className:`kr-select-group__items`,style:x,children:(0,e.jsx)(h.Provider,{value:C,children:y?a.map(t=>(0,e.jsx)(`div`,{children:y(t,c===t.value,S)},t.value)):a.map(t=>(0,e.jsx)(g,{value:t.value,label:t.label,selected:c,disabled:t.disabled,variant:p,shape:m,showItemLabel:o,title:s?t.label:void 0,children:p===`color`?(0,e.jsx)(`div`,{className:`kr-color-swatch`,style:{background:t.hex}}):p===`icon`&&t.icon?(0,e.jsx)(`svg`,{className:`kr-select-item-icon`,viewBox:`0 0 32 32`,children:(0,e.jsx)(`path`,{d:t.icon})}):t.label},t.value))})})]})}function v(e,r){let[i,a]=(0,t.useState)(e?`entered`:`left`),[o,s]=(0,t.useState)(!1),c=(0,t.useRef)(null);return(0,t.useEffect)(()=>{a(e?e=>e===`entering`||e===`entered`?e:(s(!0),`entering`):e=>e===`leaving`||e===`left`?e:(s(!1),`leaving`))},[e]),(0,t.useEffect)(()=>{let e=i===`entering`&&o?!1:i===`leaving`&&!o||null;if(e===null)return;let t=-1,n=requestAnimationFrame(()=>{t=requestAnimationFrame(()=>s(e))});return()=>{cancelAnimationFrame(n),cancelAnimationFrame(t)}},[i,o]),(0,t.useEffect)(()=>{if(i!==`entering`&&i!==`leaving`)return;let e=c.current;if(!e)return;function t(t){t.target===e&&a(e=>e===`entering`?`entered`:e===`leaving`?`left`:e)}return e.addEventListener(`transitionend`,t),()=>e.removeEventListener(`transitionend`,t)},[i]),{shouldRender:i!==`left`,transitionClassName:i===`entering`?n(`${r}-enter-active`,o&&`${r}-enter-from`):i===`leaving`?n(`${r}-leave-active`,o&&`${r}-leave-to`):void 0,ref:c}}function y({show:t,onShowChange:r,centered:i=!1,background:a,contentStyle:o,contentTransition:s=`fade-in`,children:c}){let{shouldRender:l,transitionClassName:u,ref:d}=v(t,`kr-${s}-content`);return l?(0,e.jsxs)(`div`,{ref:d,className:n(`kr-overlay`,i&&`kr-overlay--centered`,u),style:{"--kr-overlay-background":a},role:`application`,children:[(0,e.jsx)(`div`,{className:`kr-overlay__scrim`,onClick:()=>r?.(!1)}),(0,e.jsx)(`div`,{className:`kr-overlay__content`,style:o,children:c})]}):null}function b(e){let t,n;function r(){t!==void 0&&(clearTimeout(t),t=void 0),n!==void 0&&(clearInterval(n),n=void 0)}function i({timeoutSeconds:i,showCountdown:a}){if(r(),e.onTick?.(Math.max(0,Math.ceil(i))),i<=0)return;let o=Date.now()+i*1e3;t=setTimeout(()=>{e.onDismiss()},i*1e3),a&&(n=setInterval(()=>{e.onTick?.(Math.max(0,Math.ceil((o-Date.now())/1e3)))},200))}return{start:i,clear:r}}var x=(0,e.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,width:`1em`,height:`1em`,children:(0,e.jsx)(`path`,{d:`M20 6L9 17L4 12`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`})}),S=(0,e.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,width:`1em`,height:`1em`,children:[(0,e.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`,stroke:`currentColor`,strokeWidth:`2`}),(0,e.jsx)(`path`,{d:`M12 8V13`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`}),(0,e.jsx)(`circle`,{cx:`12`,cy:`16`,r:`1`,fill:`currentColor`})]});function C({show:r=!1,onShowChange:i,text:a,icon:o,iconContent:s,timeout:c=3,actionText:l,onAction:u,showCountdown:d}){let[f,p]=(0,t.useState)(c),m=(0,t.useRef)(i);m.current=i;let h=(0,t.useRef)(null);h.current||=b({onDismiss:()=>m.current?.(!1),onTick:e=>p(e)}),(0,t.useEffect)(()=>{r?h.current.start({timeoutSeconds:c,showCountdown:d}):h.current.clear()},[r]),(0,t.useEffect)(()=>()=>h.current?.clear(),[]);let{shouldRender:g,transitionClassName:_,ref:y}=v(r,`kr-fade-in-up`);function C(e){e.stopPropagation(),u?.(),m.current?.(!1)}function w(){l||m.current?.(!1)}return g?(0,e.jsxs)(`div`,{ref:y,className:n(`kr-toast`,_),role:`status`,"aria-live":`polite`,onClick:w,children:[o&&(0,e.jsx)(`div`,{className:`kr-toast__icon`,children:s??(o===`success`?x:S)}),(0,e.jsx)(`div`,{className:`kr-toast__text`,children:a}),l&&(0,e.jsxs)(`div`,{className:`kr-toast__actions`,children:[(0,e.jsx)(`button`,{className:`kr-toast__action`,type:`button`,onClick:C,children:l}),d&&(0,e.jsxs)(`span`,{className:`kr-toast__countdown`,"aria-hidden":`true`,children:[f,`s`]})]})]}):null}function w(e){return Array.from(e?.querySelectorAll(`button:not([disabled]), input:not([disabled])`)??[])}function T(e){let t=w(e),n=t.findIndex(e=>e===document.activeElement);(n===t.length-1?t[0]:t[n+1])?.focus()}function E(e){let t=w(e),n=t.findIndex(e=>e===document.activeElement);(n<=0?t[t.length-1]:t[n-1])?.focus()}function D({show:n=!1,onShowChange:r,title:i=``,text:a=``,actions:o=[],cancelText:s=`Cancel`,hideCancel:l=!1,children:u}){let[d,f]=(0,t.useState)(!1),p=(0,t.useRef)(null);function m(){r?.(!1)}async function h(e){if(!d){f(!0);try{await e()}finally{f(!1)}}}function g(e){if(e.key===`Escape`){e.preventDefault(),r?.(!1);return}e.key===`Tab`&&(e.preventDefault(),e.shiftKey?E(p.current):T(p.current))}return(0,e.jsx)(y,{show:n,onShowChange:r,centered:!0,children:(0,e.jsxs)(`dialog`,{ref:p,className:`kr-dialog`,open:n,onKeyDown:g,children:[i&&(0,e.jsx)(`h2`,{className:`kr-dialog__title`,children:i}),(0,e.jsxs)(`div`,{className:`kr-dialog__content`,children:[a&&(0,e.jsx)(`div`,{className:`kr-dialog__content__text`,children:a}),u&&(0,e.jsx)(`div`,{className:`kr-dialog__content__form`,children:u})]}),(0,e.jsxs)(`div`,{className:`kr-dialog__actions`,children:[!l&&(0,e.jsx)(c,{type:`secondary`,disabled:d,onClick:m,children:s}),o.map(t=>(0,e.jsx)(c,{disabled:d||t.disabled,onClick:()=>h(t.action),children:t.text},t.text))]})]})})}exports.KrButton=c,exports.KrChevron=r,exports.KrDialog=D,exports.KrEmpty=a,exports.KrMenuItem=s,exports.KrOverlay=y,exports.KrSearchInput=m,exports.KrSection=o,exports.KrSelectGroup=_,exports.KrSelectGroupContext=h,exports.KrSelectItem=g,exports.KrSwitch=l,exports.KrTextField=d,exports.KrToast=C,exports.KrToggleRow=u;
2
+ //# sourceMappingURL=kroma-react.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kroma-react.cjs","names":[],"sources":["../src/react/utils/cx.ts","../src/react/components/KrChevron.tsx","../src/react/components/KrEmpty.tsx","../src/react/components/KrSection.tsx","../src/react/components/KrMenuItem.tsx","../src/react/components/KrButton.tsx","../src/react/components/KrSwitch.tsx","../src/react/components/KrToggleRow.tsx","../src/react/components/KrTextField.tsx","../src/react/components/KrSearchInput.tsx","../src/react/components/KrSelectItem.tsx","../src/react/components/KrSelectGroup.tsx","../src/react/hooks/useCssTransition.ts","../src/react/components/KrOverlay.tsx","../src/core/toastTimer.ts","../src/react/components/KrToast.tsx","../src/core/focusTrap.ts","../src/react/components/KrDialog.tsx"],"sourcesContent":["export function cx(...classes: Array<string | false | null | undefined>): string {\n return classes.filter(Boolean).join(' ')\n}\n","import '../../styles/components/KrChevron.css'\nimport type { ComponentPropsWithoutRef } from 'react'\nimport { cx } from '../utils/cx'\n\nexport type KrChevronProps = ComponentPropsWithoutRef<'div'>\n\nexport function KrChevron({ className, ...rest }: KrChevronProps) {\n return <div className={cx('kr-chevron', className)} {...rest} />\n}\n","import '../../styles/components/KrEmpty.css'\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react'\nimport { cx } from '../utils/cx'\n\nexport interface KrEmptyProps extends ComponentPropsWithoutRef<'div'> {\n title?: string\n description?: string\n icon?: ReactNode\n}\n\nconst defaultIcon = (\n <svg viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"10\" y=\"24\" width=\"44\" height=\"30\" rx=\"4\" stroke=\"var(--kr-on-surface-tertiary)\" strokeWidth=\"2\" />\n <path d=\"M10 26L18 10H46L54 26\" stroke=\"var(--kr-on-surface-tertiary)\" strokeWidth=\"2\" strokeLinejoin=\"round\" />\n <path d=\"M24 34H40\" stroke=\"var(--kr-theme)\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n)\n\nexport function KrEmpty({ title, description, icon, className, ...rest }: KrEmptyProps) {\n return (\n <div className={cx('kr-empty', className)} {...rest}>\n <div className=\"kr-empty__icon\">{icon ?? defaultIcon}</div>\n <h1 className=\"kr-empty__title\">{title}</h1>\n <p className=\"kr-empty__description\">{description}</p>\n </div>\n )\n}\n","import '../../styles/components/KrSection.css'\nimport type { ComponentPropsWithoutRef } from 'react'\nimport { cx } from '../utils/cx'\n\nexport interface KrSectionProps extends ComponentPropsWithoutRef<'section'> {\n title?: string\n subtitle?: string\n}\n\nexport function KrSection({ title, subtitle, className, children, ...rest }: KrSectionProps) {\n return (\n <section className={cx('kr-section', className)} {...rest}>\n {(title || subtitle) && (\n <header className=\"kr-section__header\">\n {title && <h1 className=\"kr-section__title\">{title}</h1>}\n {subtitle && <h2 className=\"kr-section__subtitle\">{subtitle}</h2>}\n </header>\n )}\n <div className=\"kr-section__content\">{children}</div>\n </section>\n )\n}\n","import '../../styles/components/KrMenuItem.css'\nimport type { ComponentPropsWithoutRef, ReactNode } from 'react'\nimport type { KrMenuItemData } from '../../core/types'\nimport { cx } from '../utils/cx'\n\nexport type { KrMenuItemData }\n\nexport interface KrMenuItemProps extends KrMenuItemData, Omit<ComponentPropsWithoutRef<'button'>, 'type' | 'value' | 'title'> {\n icon?: ReactNode\n}\n\nexport function KrMenuItem({ title, value: _value, disabled, type, icon, className, ...rest }: KrMenuItemProps) {\n if (type === 'divider') {\n return <hr className={cx('kr-menu-item--divider', className)} />\n }\n\n return (\n <button className={cx('kr-menu-item', className)} disabled={disabled} role=\"menuitem\" {...rest}>\n <div className=\"kr-menu-item__content\">{title}</div>\n {icon && (\n <div className=\"kr-menu-item__icon\" aria-hidden=\"true\">\n {icon}\n </div>\n )}\n </button>\n )\n}\n","import '../../styles/components/KrButton.css'\nimport type { ComponentPropsWithoutRef } from 'react'\nimport type { KrButtonType } from '../../core/types'\nimport { cx } from '../utils/cx'\n\nexport type { KrButtonType }\n\nexport interface KrButtonProps extends Omit<ComponentPropsWithoutRef<'button'>, 'type'> {\n type?: KrButtonType\n}\n\nexport function KrButton({ type = 'primary', className, children, ...rest }: KrButtonProps) {\n return (\n <button className={cx('kr-button', `kr-button--${type}`, className)} {...rest}>\n {children}\n </button>\n )\n}\n","import '../../styles/components/KrSwitch.css'\nimport type { ComponentPropsWithoutRef } from 'react'\nimport { cx } from '../utils/cx'\n\nexport interface KrSwitchProps extends ComponentPropsWithoutRef<'div'> {\n checked?: boolean\n disabled?: boolean\n inset?: boolean\n}\n\nexport function KrSwitch({ checked = false, disabled = false, inset = false, className, ...rest }: KrSwitchProps) {\n return (\n <div\n className={cx('kr-switch', inset && 'kr-switch--inset', className)}\n data-checked={checked}\n data-disabled={disabled}\n aria-hidden=\"true\"\n {...rest}\n >\n <div className=\"kr-switch__track\" />\n <div className=\"kr-switch__thumb\" />\n </div>\n )\n}\n","import '../../styles/components/KrToggleRow.css'\nimport type { ChangeEvent, ComponentPropsWithoutRef } from 'react'\nimport { KrSwitch } from './KrSwitch'\nimport { cx } from '../utils/cx'\n\nexport interface KrToggleRowProps extends Omit<ComponentPropsWithoutRef<'label'>, 'title'> {\n checked?: boolean\n onCheckedChange?: (checked: boolean) => void\n title?: string\n subtitle?: string\n disabled?: boolean\n hideSeparator?: boolean\n}\n\nexport function KrToggleRow({\n checked = false,\n onCheckedChange,\n title,\n subtitle,\n disabled = false,\n hideSeparator = false,\n className,\n ...rest\n}: KrToggleRowProps) {\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n onCheckedChange?.(event.target.checked)\n }\n\n return (\n <label\n className={cx('kr-toggle-row', !hideSeparator && 'kr-toggle-row--with-separator', disabled && 'kr-toggle-row--disabled', className)}\n {...rest}\n >\n <input\n className=\"kr-toggle-row__native\"\n type=\"checkbox\"\n role=\"switch\"\n checked={checked}\n disabled={disabled}\n aria-label={title}\n onChange={handleChange}\n />\n <div className=\"kr-toggle-row__label\">\n {title && <div className=\"kr-toggle-row__title\">{title}</div>}\n {subtitle && <div className=\"kr-toggle-row__subtitle\">{subtitle}</div>}\n </div>\n <KrSwitch checked={checked} disabled={disabled} />\n </label>\n )\n}\n","import '../../styles/components/KrTextField.css'\nimport type { ChangeEvent, ComponentPropsWithoutRef } from 'react'\nimport { cx } from '../utils/cx'\n\nexport interface KrTextFieldProps\n extends Omit<ComponentPropsWithoutRef<'input'>, 'type' | 'value' | 'onChange' | 'className' | 'autoFocus'> {\n value?: string\n onValueChange?: (value: string) => void\n label?: string\n error?: boolean\n autofocus?: boolean\n className?: string\n}\n\nexport function KrTextField({ value, onValueChange, label, error, autofocus, className, ...rest }: KrTextFieldProps) {\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n onValueChange?.(event.target.value.trim())\n }\n\n return (\n <label className={cx('kr-textfield', className)}>\n {label && <span className=\"kr-textfield__label-text\">{label}</span>}\n <input\n type=\"text\"\n className={cx('kr-textfield__input', error && 'kr-textfield__input--error')}\n value={value}\n onChange={handleChange}\n autoFocus={autofocus}\n {...rest}\n />\n </label>\n )\n}\n","import '../../styles/components/KrSearchInput.css'\nimport { useRef, type ChangeEvent, type KeyboardEvent, type ReactNode } from 'react'\n\nexport interface KrSearchInputProps {\n value?: string\n onValueChange?: (value: string) => void\n autofocus?: boolean\n label?: string\n clearLabel?: string\n icon?: ReactNode\n clearIcon?: ReactNode\n}\n\nconst defaultIcon = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" width=\"1em\" height=\"1em\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <path d=\"M20 20L16.65 16.65\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n)\n\nconst defaultClearIcon = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" width=\"1em\" height=\"1em\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n)\n\nexport function KrSearchInput({\n value = '',\n onValueChange,\n autofocus = true,\n label = 'Search',\n clearLabel = 'Clear',\n icon,\n clearIcon,\n}: KrSearchInputProps) {\n const inputRef = useRef<HTMLInputElement | null>(null)\n\n function setValue(next: string) {\n onValueChange?.(next)\n if (autofocus) {\n inputRef.current?.focus()\n }\n }\n\n function handleChange(event: ChangeEvent<HTMLInputElement>) {\n setValue(event.target.value)\n }\n\n function clear() {\n setValue('')\n }\n\n function handleClearKeyDown(event: KeyboardEvent<HTMLDivElement>) {\n if (event.key === 'Enter') clear()\n }\n\n return (\n <div className=\"kr-search-input\">\n <div className=\"kr-search-input__icon\">{icon ?? defaultIcon}</div>\n <input\n ref={inputRef}\n className=\"kr-search-input__input\"\n type=\"text\"\n value={value}\n onChange={handleChange}\n autoFocus={autofocus}\n aria-label={label}\n />\n <div\n className=\"kr-search-input__icon kr-search-input__icon--clear\"\n style={{ display: value ? undefined : 'none' }}\n onClick={clear}\n role=\"button\"\n tabIndex={0}\n aria-label={clearLabel}\n onKeyDown={handleClearKeyDown}\n >\n {clearIcon ?? defaultClearIcon}\n </div>\n </div>\n )\n}\n","import '../../styles/components/KrSelectItem.css'\nimport { createContext, useContext, type ChangeEvent, type ReactNode } from 'react'\nimport type { KrSelectVariant, KrSelectShape, KrSelectItemProps } from '../../core/types'\nimport { cx } from '../utils/cx'\n\nexport type { KrSelectVariant, KrSelectShape, KrSelectItemProps }\n\nexport interface KrSelectGroupContextValue {\n value: string | number\n variant?: KrSelectVariant\n shape?: KrSelectShape\n showItemLabel: boolean\n name: string\n onSelect: (value: string | number) => void\n}\n\n// Present when nested inside a <KrSelectGroup>; absent when used standalone.\nexport const KrSelectGroupContext = createContext<KrSelectGroupContextValue | null>(null)\n\nexport interface KrSelectItemComponentProps extends KrSelectItemProps {\n onSelect?: (value: string | number) => void\n children?: ReactNode\n}\n\nexport function KrSelectItem({\n value,\n label,\n title,\n selected,\n disabled,\n variant = 'default',\n shape = 'rounded',\n circle,\n stretch,\n showItemLabel = true,\n onSelect,\n children,\n}: KrSelectItemComponentProps) {\n const groupContext = useContext(KrSelectGroupContext)\n\n const currentValue = groupContext?.value ?? selected\n const isSelected = currentValue === value\n\n const finalVariant = groupContext?.variant ?? variant\n const finalShape = circle ? 'circle' : (groupContext?.shape ?? shape)\n const showLabel = groupContext?.showItemLabel ?? showItemLabel\n const displayLabel = showLabel ? (label ?? title) : ''\n\n function handleChange(_event: ChangeEvent<HTMLInputElement>) {\n if (disabled) return\n onSelect?.(value)\n groupContext?.onSelect(value)\n }\n\n return (\n <label\n className={cx(\n 'kr-select-item',\n isSelected && 'kr-select-item--selected',\n disabled && 'kr-select-item--disabled',\n stretch && 'kr-select-item--stretch',\n `kr-select-item--${finalVariant}`,\n `kr-select-item--${finalShape}`,\n )}\n title={title}\n >\n <input\n className=\"kr-select-item__input\"\n type=\"radio\"\n name={groupContext?.name}\n value={value}\n checked={isSelected}\n disabled={disabled}\n aria-label={label || title || String(value)}\n onChange={handleChange}\n />\n <div className=\"kr-select-item__content\">{children}</div>\n {displayLabel && <div className=\"kr-select-item__label\">{displayLabel}</div>}\n </label>\n )\n}\n","import '../../styles/components/KrSelectGroup.css'\nimport { useMemo, useState, type CSSProperties, type ReactNode } from 'react'\nimport { KrSelectItem, KrSelectGroupContext } from './KrSelectItem'\nimport type { KrSelectShape, KrSelectVariant, KrSelectItemData } from '../../core/types'\nimport { cx } from '../utils/cx'\n\nexport type { KrSelectItemData }\n\nexport interface KrSelectGroupProps {\n title?: string\n subtitle?: string\n items: KrSelectItemData[]\n showItemLabel?: boolean\n showTooltip?: boolean\n value: string | number\n onValueChange?: (value: string | number) => void\n hideSeparator?: boolean\n columns?: number | 'auto'\n gap?: string\n variant?: KrSelectVariant\n shape?: KrSelectShape\n className?: string\n style?: CSSProperties\n renderItem?: (item: KrSelectItemData, selected: boolean, setSelected: (value: string | number) => void) => ReactNode\n}\n\nexport function KrSelectGroup({\n title,\n subtitle,\n items,\n showItemLabel = true,\n showTooltip = true,\n value,\n onValueChange,\n hideSeparator,\n columns = 'auto',\n gap = '12px',\n variant = 'default',\n shape = 'rounded',\n className,\n style,\n renderItem,\n}: KrSelectGroupProps) {\n const [groupName] = useState(() => `kr-select-group-${Math.random().toString(36).slice(2)}`)\n\n const layoutStyle: CSSProperties =\n columns === 'auto'\n ? { display: 'flex', flexWrap: 'wrap', gap }\n : { display: 'grid', gridTemplateColumns: `repeat(${columns}, 1fr)`, gap }\n\n function handleSelect(next: string | number) {\n onValueChange?.(next)\n }\n\n const contextValue = useMemo(\n () => ({ value, variant, shape, showItemLabel, name: groupName, onSelect: handleSelect }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [value, variant, shape, showItemLabel, groupName, onValueChange],\n )\n\n return (\n <div className={cx('kr-select-group', !hideSeparator && 'kr-select-group--with-separator', className)} style={style}>\n {(title || subtitle) && (\n <div className=\"kr-select-group__header\">\n {title && <div className=\"kr-select-group__header__title\">{title}</div>}\n {subtitle && <div className=\"kr-select-group__header__subtitle\">{subtitle}</div>}\n </div>\n )}\n\n <div className=\"kr-select-group__items\" style={layoutStyle}>\n <KrSelectGroupContext.Provider value={contextValue}>\n {renderItem\n ? items.map((item) => <div key={item.value}>{renderItem(item, value === item.value, handleSelect)}</div>)\n : items.map((item) => (\n <KrSelectItem\n key={item.value}\n value={item.value}\n label={item.label}\n selected={value}\n disabled={item.disabled}\n variant={variant}\n shape={shape}\n showItemLabel={showItemLabel}\n title={showTooltip ? item.label : undefined}\n >\n {variant === 'color' ? (\n <div className=\"kr-color-swatch\" style={{ background: item.hex }} />\n ) : variant === 'icon' && item.icon ? (\n <svg className=\"kr-select-item-icon\" viewBox=\"0 0 32 32\">\n <path d={item.icon} />\n </svg>\n ) : (\n item.label\n )}\n </KrSelectItem>\n ))}\n </KrSelectGroupContext.Provider>\n </div>\n </div>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport { cx } from '../utils/cx'\n\ntype Phase = 'entering' | 'entered' | 'leaving' | 'left'\n\n/**\n * Reproduces Vue's <Transition> enter/leave class sequencing (name-enter-active\n * / name-enter-from / name-leave-active / name-leave-to) for a single root\n * element, so React can reuse the exact same transition CSS Kroma already\n * ships for the Vue components. No animation library — just the class\n * toggling Vue's compiler would otherwise generate.\n */\nexport function useCssTransition(show: boolean, name: string) {\n const [phase, setPhase] = useState<Phase>(show ? 'entered' : 'left')\n const [edgeActive, setEdgeActive] = useState(false)\n const elementRef = useRef<HTMLElement | null>(null)\n\n useEffect(() => {\n if (show) {\n setPhase((current) => {\n if (current === 'entering' || current === 'entered') return current\n setEdgeActive(true) // apply -enter-from synchronously\n return 'entering'\n })\n } else {\n setPhase((current) => {\n if (current === 'leaving' || current === 'left') return current\n setEdgeActive(false) // -leave-to is applied a frame later\n return 'leaving'\n })\n }\n }, [show])\n\n useEffect(() => {\n const flipEdge = phase === 'entering' && edgeActive ? false : phase === 'leaving' && !edgeActive ? true : null\n if (flipEdge === null) return\n\n let inner = -1\n const outer = requestAnimationFrame(() => {\n inner = requestAnimationFrame(() => setEdgeActive(flipEdge))\n })\n return () => {\n cancelAnimationFrame(outer)\n cancelAnimationFrame(inner)\n }\n }, [phase, edgeActive])\n\n useEffect(() => {\n if (phase !== 'entering' && phase !== 'leaving') return\n const el = elementRef.current\n if (!el) return\n\n function onTransitionEnd(event: TransitionEvent) {\n if (event.target !== el) return\n setPhase((current) => {\n if (current === 'entering') return 'entered'\n if (current === 'leaving') return 'left'\n return current\n })\n }\n\n el.addEventListener('transitionend', onTransitionEnd)\n return () => el.removeEventListener('transitionend', onTransitionEnd)\n }, [phase])\n\n const shouldRender = phase !== 'left'\n const transitionClassName =\n phase === 'entering'\n ? cx(`${name}-enter-active`, edgeActive && `${name}-enter-from`)\n : phase === 'leaving'\n ? cx(`${name}-leave-active`, edgeActive && `${name}-leave-to`)\n : undefined\n\n return { shouldRender, transitionClassName, ref: elementRef }\n}\n","import '../../styles/components/KrOverlay.css'\nimport type { CSSProperties, ReactNode, RefObject } from 'react'\nimport { useCssTransition } from '../hooks/useCssTransition'\nimport { cx } from '../utils/cx'\n\nexport interface KrOverlayProps {\n show: boolean\n onShowChange?: (show: boolean) => void\n centered?: boolean\n background?: string\n contentStyle?: CSSProperties\n contentTransition?: 'fade-in' | 'fade-in-up'\n children?: ReactNode\n}\n\nexport function KrOverlay({\n show,\n onShowChange,\n centered = false,\n background,\n contentStyle,\n contentTransition = 'fade-in',\n children,\n}: KrOverlayProps) {\n const { shouldRender, transitionClassName, ref } = useCssTransition(show, `kr-${contentTransition}-content`)\n\n if (!shouldRender) return null\n\n return (\n <div\n ref={ref as RefObject<HTMLDivElement>}\n className={cx('kr-overlay', centered && 'kr-overlay--centered', transitionClassName)}\n style={{ '--kr-overlay-background': background } as CSSProperties}\n role=\"application\"\n >\n <div className=\"kr-overlay__scrim\" onClick={() => onShowChange?.(false)} />\n <div className=\"kr-overlay__content\" style={contentStyle}>\n {children}\n </div>\n </div>\n )\n}\n","export interface DismissTimerCallbacks {\n onDismiss: () => void\n onTick?: (remainingSeconds: number) => void\n}\n\nexport interface DismissTimerStartOptions {\n timeoutSeconds: number\n showCountdown?: boolean\n}\n\nexport interface DismissTimer {\n start(options: DismissTimerStartOptions): void\n clear(): void\n}\n\nexport function createDismissTimer(callbacks: DismissTimerCallbacks): DismissTimer {\n let dismissTimer: ReturnType<typeof setTimeout> | undefined\n let countdownTimer: ReturnType<typeof setInterval> | undefined\n\n function clear(): void {\n if (dismissTimer !== undefined) {\n clearTimeout(dismissTimer)\n dismissTimer = undefined\n }\n if (countdownTimer !== undefined) {\n clearInterval(countdownTimer)\n countdownTimer = undefined\n }\n }\n\n function start({ timeoutSeconds, showCountdown }: DismissTimerStartOptions): void {\n clear()\n callbacks.onTick?.(Math.max(0, Math.ceil(timeoutSeconds)))\n\n if (timeoutSeconds <= 0) return\n\n const deadline = Date.now() + timeoutSeconds * 1000\n dismissTimer = setTimeout(() => {\n callbacks.onDismiss()\n }, timeoutSeconds * 1000)\n\n if (showCountdown) {\n countdownTimer = setInterval(() => {\n callbacks.onTick?.(Math.max(0, Math.ceil((deadline - Date.now()) / 1000)))\n }, 200)\n }\n }\n\n return { start, clear }\n}\n","import '../../styles/components/KrToast.css'\nimport { useEffect, useRef, useState, type MouseEvent, type ReactNode, type RefObject } from 'react'\nimport type { KrToastIcon } from '../../core/types'\nimport { createDismissTimer, type DismissTimer } from '../../core/toastTimer'\nimport { useCssTransition } from '../hooks/useCssTransition'\nimport { cx } from '../utils/cx'\n\nexport type { KrToastIcon }\n\nexport interface KrToastProps {\n show?: boolean\n onShowChange?: (show: boolean) => void\n text?: string\n icon?: KrToastIcon\n iconContent?: ReactNode\n timeout?: number\n actionText?: string\n onAction?: () => void\n showCountdown?: boolean\n}\n\nconst successIcon = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" width=\"1em\" height=\"1em\">\n <path d=\"M20 6L9 17L4 12\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n)\n\nconst errorIcon = (\n <svg viewBox=\"0 0 24 24\" fill=\"none\" width=\"1em\" height=\"1em\">\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <path d=\"M12 8V13\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\" />\n </svg>\n)\n\nexport function KrToast({\n show = false,\n onShowChange,\n text,\n icon,\n iconContent,\n timeout = 3,\n actionText,\n onAction,\n showCountdown,\n}: KrToastProps) {\n const [remainingSeconds, setRemainingSeconds] = useState(timeout)\n const onShowChangeRef = useRef(onShowChange)\n onShowChangeRef.current = onShowChange\n\n const dismissTimerRef = useRef<DismissTimer | null>(null)\n if (!dismissTimerRef.current) {\n dismissTimerRef.current = createDismissTimer({\n onDismiss: () => onShowChangeRef.current?.(false),\n onTick: (seconds) => setRemainingSeconds(seconds),\n })\n }\n\n useEffect(() => {\n if (show) {\n dismissTimerRef.current!.start({ timeoutSeconds: timeout, showCountdown })\n } else {\n dismissTimerRef.current!.clear()\n }\n // Deliberately only re-runs on `show`, matching the Vue version's\n // `watch(() => props.show, ...)` — timeout/showCountdown are read fresh\n // but changing them alone doesn't restart an already-running timer.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [show])\n\n useEffect(() => () => dismissTimerRef.current?.clear(), [])\n\n const { shouldRender, transitionClassName, ref } = useCssTransition(show, 'kr-fade-in-up')\n\n function runAction(event: MouseEvent<HTMLButtonElement>) {\n event.stopPropagation()\n onAction?.()\n onShowChangeRef.current?.(false)\n }\n\n function dismissFromClick() {\n if (!actionText) {\n onShowChangeRef.current?.(false)\n }\n }\n\n if (!shouldRender) return null\n\n return (\n <div\n ref={ref as RefObject<HTMLDivElement>}\n className={cx('kr-toast', transitionClassName)}\n role=\"status\"\n aria-live=\"polite\"\n onClick={dismissFromClick}\n >\n {icon && <div className=\"kr-toast__icon\">{iconContent ?? (icon === 'success' ? successIcon : errorIcon)}</div>}\n <div className=\"kr-toast__text\">{text}</div>\n {actionText && (\n <div className=\"kr-toast__actions\">\n <button className=\"kr-toast__action\" type=\"button\" onClick={runAction}>\n {actionText}\n </button>\n {showCountdown && (\n <span className=\"kr-toast__countdown\" aria-hidden=\"true\">\n {remainingSeconds}s\n </span>\n )}\n </div>\n )}\n </div>\n )\n}\n","export function focusableElements(container: HTMLElement | null): HTMLElement[] {\n return Array.from(container?.querySelectorAll<HTMLElement>('button:not([disabled]), input:not([disabled])') ?? [])\n}\n\nexport function focusNext(container: HTMLElement | null): void {\n const elements = focusableElements(container)\n const index = elements.findIndex((el) => el === document.activeElement)\n const next = index === elements.length - 1 ? elements[0] : elements[index + 1]\n next?.focus()\n}\n\nexport function focusPrev(container: HTMLElement | null): void {\n const elements = focusableElements(container)\n const index = elements.findIndex((el) => el === document.activeElement)\n const prev = index <= 0 ? elements[elements.length - 1] : elements[index - 1]\n prev?.focus()\n}\n","import '../../styles/components/KrDialog.css'\nimport { useRef, useState, type KeyboardEvent, type ReactNode } from 'react'\nimport { KrOverlay } from './KrOverlay'\nimport { KrButton } from './KrButton'\nimport type { KrDialogAction } from '../../core/types'\nimport { focusNext as coreFocusNext, focusPrev as coreFocusPrev } from '../../core/focusTrap'\n\nexport type { KrDialogAction }\n\nexport interface KrDialogProps {\n show?: boolean\n onShowChange?: (show: boolean) => void\n title?: string\n text?: string\n actions?: KrDialogAction[]\n cancelText?: string\n hideCancel?: boolean\n children?: ReactNode\n}\n\nexport function KrDialog({\n show = false,\n onShowChange,\n title = '',\n text = '',\n actions = [],\n cancelText = 'Cancel',\n hideCancel = false,\n children,\n}: KrDialogProps) {\n const [submitting, setSubmitting] = useState(false)\n const dialogRef = useRef<HTMLDialogElement | null>(null)\n\n function onCancel() {\n onShowChange?.(false)\n }\n\n async function onConfirm(action: () => void | Promise<void>) {\n if (submitting) return\n\n setSubmitting(true)\n try {\n await action()\n } finally {\n setSubmitting(false)\n }\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLDialogElement>) {\n if (event.key === 'Escape') {\n event.preventDefault()\n onShowChange?.(false)\n return\n }\n if (event.key === 'Tab') {\n event.preventDefault()\n if (event.shiftKey) {\n coreFocusPrev(dialogRef.current)\n } else {\n coreFocusNext(dialogRef.current)\n }\n }\n }\n\n return (\n <KrOverlay show={show} onShowChange={onShowChange} centered>\n <dialog ref={dialogRef} className=\"kr-dialog\" open={show} onKeyDown={handleKeyDown}>\n {title && <h2 className=\"kr-dialog__title\">{title}</h2>}\n <div className=\"kr-dialog__content\">\n {text && <div className=\"kr-dialog__content__text\">{text}</div>}\n {children && <div className=\"kr-dialog__content__form\">{children}</div>}\n </div>\n\n <div className=\"kr-dialog__actions\">\n {!hideCancel && (\n <KrButton type=\"secondary\" disabled={submitting} onClick={onCancel}>\n {cancelText}\n </KrButton>\n )}\n {actions.map((action) => (\n <KrButton key={action.text} disabled={submitting || action.disabled} onClick={() => onConfirm(action.action)}>\n {action.text}\n </KrButton>\n ))}\n </div>\n </dialog>\n </KrOverlay>\n )\n}\n"],"mappings":"yHAAA,SAAgB,EAAG,GAAG,EAA2D,CAC/E,OAAO,EAAQ,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,CACzC,CCIA,SAAgB,EAAU,CAAE,YAAW,GAAG,GAAwB,CAChE,OAAO,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAG,aAAc,CAAS,EAAG,GAAI,CAAO,CAAA,CACjE,CCEA,IAAM,GACJ,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,6BAA3C,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,KAAK,EAAE,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,IAAI,OAAO,gCAAgC,YAAY,GAAK,CAAA,GAC1G,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,wBAAwB,OAAO,gCAAgC,YAAY,IAAI,eAAe,OAAS,CAAA,GAC/G,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,YAAY,OAAO,kBAAkB,YAAY,IAAI,cAAc,OAAS,CAAA,CACjF,IAGP,SAAgB,EAAQ,CAAE,QAAO,cAAa,OAAM,YAAW,GAAG,GAAsB,CACtF,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAG,WAAY,CAAS,EAAG,GAAI,EAA/C,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,iBAAkB,SAAA,GAAQ,CAAiB,CAAA,GAC1D,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,kBAAmB,SAAA,CAAU,CAAA,GAC3C,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,wBAAyB,SAAA,CAAe,CAAA,CAClD,GAET,CCjBA,SAAgB,EAAU,CAAE,QAAO,WAAU,YAAW,WAAU,GAAG,GAAwB,CAC3F,OACE,EAAA,EAAA,KAAA,CAAC,UAAD,CAAS,UAAW,EAAG,aAAc,CAAS,EAAG,GAAI,EAArD,SAAA,EACI,GAAS,KACT,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,UAAU,qBAAlB,SAAA,CACG,IAAS,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,oBAAqB,SAAA,CAAU,CAAA,EACtD,IAAY,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,uBAAwB,SAAA,CAAa,CAAA,CAC1D,CAEV,CAAA,GAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,sBAAuB,UAAc,CAAA,CAC7C,GAEb,CCVA,SAAgB,EAAW,CAAE,QAAO,MAAO,EAAQ,WAAU,OAAM,OAAM,YAAW,GAAG,GAAyB,CAK9G,OAJI,IAAS,WACJ,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAG,wBAAyB,CAAS,CAAI,CAAA,GAI/D,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,UAAW,EAAG,eAAgB,CAAS,EAAa,WAAU,KAAK,WAAW,GAAI,EAA1F,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wBAAyB,SAAA,CAAW,CAAA,EAClD,IACC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,qBAAqB,cAAY,OAC7C,SAAA,CACE,CAAA,CAED,GAEZ,CCfA,SAAgB,EAAS,CAAE,OAAO,UAAW,YAAW,WAAU,GAAG,GAAuB,CAC1F,OACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAW,EAAG,YAAa,cAAc,IAAQ,CAAS,EAAG,GAAI,EACtE,UACK,CAAA,CAEZ,CCPA,SAAgB,EAAS,CAAE,UAAU,GAAO,WAAW,GAAO,QAAQ,GAAO,YAAW,GAAG,GAAuB,CAChH,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAW,EAAG,YAAa,GAAS,mBAAoB,CAAS,EACjE,eAAc,EACd,gBAAe,EACf,cAAY,OACZ,GAAI,EALN,SAAA,EAOE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,kBAAoB,CAAA,GACnC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,kBAAoB,CAAA,CAChC,GAET,CCTA,SAAgB,EAAY,CAC1B,UAAU,GACV,kBACA,QACA,WACA,WAAW,GACX,gBAAgB,GAChB,YACA,GAAG,GACgB,CACnB,SAAS,EAAa,EAAsC,CAC1D,IAAkB,EAAM,OAAO,OAAO,CACxC,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,QAAD,CACE,UAAW,EAAG,gBAAiB,CAAC,GAAiB,gCAAiC,GAAY,0BAA2B,CAAS,EAClI,GAAI,EAFN,SAAA,EAIE,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,UAAU,wBACV,KAAK,WACL,KAAK,SACI,UACC,WACV,aAAY,EACZ,SAAU,CACX,CAAA,GACD,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uBAAf,SAAA,CACG,IAAS,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,uBAAwB,SAAA,CAAW,CAAA,EAC3D,IAAY,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,0BAA2B,SAAA,CAAc,CAAA,CAClE,KACL,EAAA,EAAA,IAAA,CAAC,EAAD,CAAmB,UAAmB,UAAW,CAAA,CAC5C,GAEX,CCnCA,SAAgB,EAAY,CAAE,QAAO,gBAAe,QAAO,QAAO,YAAW,YAAW,GAAG,GAA0B,CACnH,SAAS,EAAa,EAAsC,CAC1D,IAAgB,EAAM,OAAO,MAAM,KAAK,CAAC,CAC3C,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,QAAD,CAAO,UAAW,EAAG,eAAgB,CAAS,EAA9C,SAAA,CACG,IAAS,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,2BAA4B,SAAA,CAAY,CAAA,GAClE,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,KAAK,OACL,UAAW,EAAG,sBAAuB,GAAS,4BAA4B,EACnE,QACP,SAAU,EACV,UAAW,EACX,GAAI,CACL,CAAA,CACI,GAEX,CCnBA,IAAM,GACJ,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,MAAM,OAAO,MAAxD,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,OAAO,eAAe,YAAY,GAAK,CAAA,GACrE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,qBAAqB,OAAO,eAAe,YAAY,IAAI,cAAc,OAAS,CAAA,CACvF,IAGD,GACJ,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,MAAM,OAAO,MACtD,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,uBAAuB,OAAO,eAAe,YAAY,IAAI,cAAc,OAAS,CAAA,CACzF,CAAA,EAGP,SAAgB,EAAc,CAC5B,QAAQ,GACR,gBACA,YAAY,GACZ,QAAQ,SACR,aAAa,QACb,OACA,aACqB,CACrB,IAAM,GAAA,EAAW,EAAA,OAAA,CAAgC,IAAI,EAErD,SAAS,EAAS,EAAc,CAC9B,IAAgB,CAAI,EAChB,GACF,EAAS,SAAS,MAAM,CAE5B,CAEA,SAAS,EAAa,EAAsC,CAC1D,EAAS,EAAM,OAAO,KAAK,CAC7B,CAEA,SAAS,GAAQ,CACf,EAAS,EAAE,CACb,CAEA,SAAS,EAAmB,EAAsC,CAC5D,EAAM,MAAQ,SAAS,EAAM,CACnC,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,kBAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wBAAyB,SAAA,GAAQ,CAAiB,CAAA,GACjE,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,IAAK,EACL,UAAU,yBACV,KAAK,OACE,QACP,SAAU,EACV,UAAW,EACX,aAAY,CACb,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,UAAU,qDACV,MAAO,CAAE,QAAS,EAAQ,IAAA,GAAY,MAAO,EAC7C,QAAS,EACT,KAAK,SACL,SAAU,EACV,aAAY,EACZ,UAAW,EAEV,SAAA,GAAa,CACX,CAAA,CACF,GAET,CChEA,IAAa,GAAA,EAAuB,EAAA,cAAA,CAAgD,IAAI,EAOxF,SAAgB,EAAa,CAC3B,QACA,QACA,QACA,WACA,WACA,UAAU,UACV,QAAQ,UACR,SACA,UACA,gBAAgB,GAChB,WACA,YAC6B,CAC7B,IAAM,GAAA,EAAe,EAAA,WAAA,CAAW,CAAoB,EAG9C,GADe,GAAc,OAAS,KACR,EAE9B,EAAe,GAAc,SAAW,EACxC,EAAa,EAAS,SAAY,GAAc,OAAS,EAEzD,EADY,GAAc,eAAiB,EACf,GAAS,EAAS,GAEpD,SAAS,EAAa,EAAuC,CACvD,IACJ,IAAW,CAAK,EAChB,GAAc,SAAS,CAAK,EAC9B,CAEA,OACE,EAAA,EAAA,KAAA,CAAC,QAAD,CACE,UAAW,EACT,iBACA,GAAc,2BACd,GAAY,2BACZ,GAAW,0BACX,mBAAmB,IACnB,mBAAmB,GACrB,EACO,QATT,SAAA,EAWE,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,UAAU,wBACV,KAAK,QACL,KAAM,GAAc,KACb,QACP,QAAS,EACC,WACV,aAAY,GAAS,GAAS,OAAO,CAAK,EAC1C,SAAU,CACX,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,0BAA2B,UAAc,CAAA,EACvD,IAAgB,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,wBAAyB,SAAA,CAAkB,CAAA,CACtE,GAEX,CCtDA,SAAgB,EAAc,CAC5B,QACA,WACA,QACA,gBAAgB,GAChB,cAAc,GACd,QACA,gBACA,gBACA,UAAU,OACV,MAAM,OACN,UAAU,UACV,QAAQ,UACR,YACA,QACA,cACqB,CACrB,GAAM,CAAC,IAAA,EAAa,EAAA,SAAA,KAAe,mBAAmB,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAErF,EACJ,IAAY,OACR,CAAE,QAAS,OAAQ,SAAU,OAAQ,KAAI,EACzC,CAAE,QAAS,OAAQ,oBAAqB,UAAU,EAAQ,QAAS,KAAI,EAE7E,SAAS,EAAa,EAAuB,CAC3C,IAAgB,CAAI,CACtB,CAEA,IAAM,GAAA,EAAe,EAAA,QAAA,MACZ,CAAE,QAAO,UAAS,QAAO,gBAAe,KAAM,EAAW,SAAU,CAAa,GAEvF,CAAC,EAAO,EAAS,EAAO,EAAe,EAAW,CAAa,CACjE,EAEA,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAG,kBAAmB,CAAC,GAAiB,kCAAmC,CAAS,EAAU,QAA9G,SAAA,EACI,GAAS,KACT,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0BAAf,SAAA,CACG,IAAS,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,iCAAkC,SAAA,CAAW,CAAA,EACrE,IAAY,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,oCAAqC,SAAA,CAAc,CAAA,CAC5E,CAGP,CAAA,GAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,yBAAyB,MAAO,EAC7C,UAAA,EAAA,EAAA,IAAA,CAAC,EAAqB,SAAtB,CAA+B,MAAO,EACnC,SAAA,EACG,EAAM,IAAK,IAAS,EAAA,EAAA,IAAA,CAAC,MAAD,CAAA,SAAuB,EAAW,EAAM,IAAU,EAAK,MAAO,CAAY,CAAO,EAAvE,EAAK,KAAkE,CAAC,EACtG,EAAM,IAAK,IACT,EAAA,EAAA,IAAA,CAAC,EAAD,CAEE,MAAO,EAAK,MACZ,MAAO,EAAK,MACZ,SAAU,EACV,SAAU,EAAK,SACN,UACF,QACQ,gBACf,MAAO,EAAc,EAAK,MAAQ,IAAA,GAEjC,SAAA,IAAY,SACX,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,kBAAkB,MAAO,CAAE,WAAY,EAAK,GAAI,CAAI,CAAA,EACjE,IAAY,QAAU,EAAK,MAC7B,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,sBAAsB,QAAQ,YAC3C,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAG,EAAK,IAAO,CAAA,CAClB,CAAA,EAEL,EAAK,KAEK,EAnBP,EAAK,KAmBE,CACf,CACwB,CAAA,CAC5B,CAAA,CACF,GAET,CCxFA,SAAgB,EAAiB,EAAe,EAAc,CAC5D,GAAM,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAgB,EAAO,UAAY,MAAM,EAC7D,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,CAAS,EAAK,EAC5C,GAAA,EAAa,EAAA,OAAA,CAA2B,IAAI,EA0DlD,OAxDA,EAAA,EAAA,UAAA,KAAgB,CAEZ,EADE,EACQ,GACJ,IAAY,YAAc,IAAY,UAAkB,GAC5D,EAAc,EAAI,EACX,YAGC,GACJ,IAAY,WAAa,IAAY,OAAe,GACxD,EAAc,EAAK,EACZ,UACR,CAEL,EAAG,CAAC,CAAI,CAAC,GAET,EAAA,EAAA,UAAA,KAAgB,CACd,IAAM,EAAW,IAAU,YAAc,EAAa,GAAQ,IAAU,WAAa,CAAC,GAAoB,KAC1G,GAAI,IAAa,KAAM,OAEvB,IAAI,EAAQ,GACN,EAAQ,0BAA4B,CACxC,EAAQ,0BAA4B,EAAc,CAAQ,CAAC,CAC7D,CAAC,EACD,UAAa,CACX,qBAAqB,CAAK,EAC1B,qBAAqB,CAAK,CAC5B,CACF,EAAG,CAAC,EAAO,CAAU,CAAC,GAEtB,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,IAAU,YAAc,IAAU,UAAW,OACjD,IAAM,EAAK,EAAW,QACtB,GAAI,CAAC,EAAI,OAET,SAAS,EAAgB,EAAwB,CAC3C,EAAM,SAAW,GACrB,EAAU,GACJ,IAAY,WAAmB,UAC/B,IAAY,UAAkB,OAC3B,CACR,CACH,CAGA,OADA,EAAG,iBAAiB,gBAAiB,CAAe,MACvC,EAAG,oBAAoB,gBAAiB,CAAe,CACtE,EAAG,CAAC,CAAK,CAAC,EAUH,CAAE,aARY,IAAU,OAQR,oBANrB,IAAU,WACN,EAAG,GAAG,EAAK,eAAgB,GAAc,GAAG,EAAK,YAAY,EAC7D,IAAU,UACR,EAAG,GAAG,EAAK,eAAgB,GAAc,GAAG,EAAK,UAAU,EAC3D,IAAA,GAEoC,IAAK,CAAW,CAC9D,CC3DA,SAAgB,EAAU,CACxB,OACA,eACA,WAAW,GACX,aACA,eACA,oBAAoB,UACpB,YACiB,CACjB,GAAM,CAAE,eAAc,sBAAqB,OAAQ,EAAiB,EAAM,MAAM,EAAkB,SAAS,EAI3G,OAFK,GAGH,EAAA,EAAA,KAAA,CAAC,MAAD,CACO,MACL,UAAW,EAAG,aAAc,GAAY,uBAAwB,CAAmB,EACnF,MAAO,CAAE,0BAA2B,CAAW,EAC/C,KAAK,cAJP,SAAA,EAME,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,oBAAoB,YAAe,IAAe,EAAK,CAAI,CAAA,GAC1E,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,sBAAsB,MAAO,EACzC,UACE,CAAA,CACF,IAbmB,IAe5B,CC1BA,SAAgB,EAAmB,EAAgD,CACjF,IAAI,EACA,EAEJ,SAAS,GAAc,CACjB,IAAiB,IAAA,KACnB,aAAa,CAAY,EACzB,EAAe,IAAA,IAEb,IAAmB,IAAA,KACrB,cAAc,CAAc,EAC5B,EAAiB,IAAA,GAErB,CAEA,SAAS,EAAM,CAAE,iBAAgB,iBAAiD,CAIhF,GAHA,EAAM,EACN,EAAU,SAAS,KAAK,IAAI,EAAG,KAAK,KAAK,CAAc,CAAC,CAAC,EAErD,GAAkB,EAAG,OAEzB,IAAM,EAAW,KAAK,IAAI,EAAI,EAAiB,IAC/C,EAAe,eAAiB,CAC9B,EAAU,UAAU,CACtB,EAAG,EAAiB,GAAI,EAEpB,IACF,EAAiB,gBAAkB,CACjC,EAAU,SAAS,KAAK,IAAI,EAAG,KAAK,MAAM,EAAW,KAAK,IAAI,GAAK,GAAI,CAAC,CAAC,CAC3E,EAAG,GAAG,EAEV,CAEA,MAAO,CAAE,QAAO,OAAM,CACxB,CC5BA,IAAM,GACJ,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,MAAM,OAAO,MACtD,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,kBAAkB,OAAO,eAAe,YAAY,IAAI,cAAc,QAAQ,eAAe,OAAS,CAAA,CAC3G,CAAA,EAGD,GACJ,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,QAAQ,YAAY,KAAK,OAAO,MAAM,MAAM,OAAO,MAAxD,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,OAAO,eAAe,YAAY,GAAK,CAAA,GACrE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,WAAW,OAAO,eAAe,YAAY,IAAI,cAAc,OAAS,CAAA,GAChF,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,KAAK,cAAgB,CAAA,CAChD,IAGP,SAAgB,EAAQ,CACtB,OAAO,GACP,eACA,OACA,OACA,cACA,UAAU,EACV,aACA,WACA,iBACe,CACf,GAAM,CAAC,EAAkB,IAAA,EAAuB,EAAA,SAAA,CAAS,CAAO,EAC1D,GAAA,EAAkB,EAAA,OAAA,CAAO,CAAY,EAC3C,EAAgB,QAAU,EAE1B,IAAM,GAAA,EAAkB,EAAA,OAAA,CAA4B,IAAI,EACxD,AACE,EAAgB,UAAU,EAAmB,CAC3C,cAAiB,EAAgB,UAAU,EAAK,EAChD,OAAS,GAAY,EAAoB,CAAO,CAClD,CAAC,GAGH,EAAA,EAAA,UAAA,KAAgB,CACV,EACF,EAAgB,QAAS,MAAM,CAAE,eAAgB,EAAS,eAAc,CAAC,EAEzE,EAAgB,QAAS,MAAM,CAMnC,EAAG,CAAC,CAAI,CAAC,GAET,EAAA,EAAA,UAAA,SAAsB,EAAgB,SAAS,MAAM,EAAG,CAAC,CAAC,EAE1D,GAAM,CAAE,eAAc,sBAAqB,OAAQ,EAAiB,EAAM,eAAe,EAEzF,SAAS,EAAU,EAAsC,CACvD,EAAM,gBAAgB,EACtB,IAAW,EACX,EAAgB,UAAU,EAAK,CACjC,CAEA,SAAS,GAAmB,CACrB,GACH,EAAgB,UAAU,EAAK,CAEnC,CAIA,OAFK,GAGH,EAAA,EAAA,KAAA,CAAC,MAAD,CACO,MACL,UAAW,EAAG,WAAY,CAAmB,EAC7C,KAAK,SACL,YAAU,SACV,QAAS,EALX,SAAA,CAOG,IAAQ,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,iBAAkB,SAAA,IAAgB,IAAS,UAAY,EAAc,EAAgB,CAAA,GAC7G,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,iBAAkB,SAAA,CAAU,CAAA,EAC1C,IACC,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,oBAAf,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAU,mBAAmB,KAAK,SAAS,QAAS,EACzD,SAAA,CACK,CAAA,EACP,IACC,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,sBAAsB,cAAY,OAAlD,SAAA,CACG,EAAiB,GACd,CAEL,CAAA,CAAA,GAEJ,IAxBmB,IA0B5B,CChHA,SAAgB,EAAkB,EAA8C,CAC9E,OAAO,MAAM,KAAK,GAAW,iBAA8B,+CAA+C,GAAK,CAAC,CAAC,CACnH,CAEA,SAAgB,EAAU,EAAqC,CAC7D,IAAM,EAAW,EAAkB,CAAS,EACtC,EAAQ,EAAS,UAAW,GAAO,IAAO,SAAS,aAAa,GACzD,IAAU,EAAS,OAAS,EAAI,EAAS,GAAK,EAAS,EAAQ,GAAA,EACtE,MAAM,CACd,CAEA,SAAgB,EAAU,EAAqC,CAC7D,IAAM,EAAW,EAAkB,CAAS,EACtC,EAAQ,EAAS,UAAW,GAAO,IAAO,SAAS,aAAa,GACzD,GAAS,EAAI,EAAS,EAAS,OAAS,GAAK,EAAS,EAAQ,GAAA,EACrE,MAAM,CACd,CCIA,SAAgB,EAAS,CACvB,OAAO,GACP,eACA,QAAQ,GACR,OAAO,GACP,UAAU,CAAC,EACX,aAAa,SACb,aAAa,GACb,YACgB,CAChB,GAAM,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,CAAS,EAAK,EAC5C,GAAA,EAAY,EAAA,OAAA,CAAiC,IAAI,EAEvD,SAAS,GAAW,CAClB,IAAe,EAAK,CACtB,CAEA,eAAe,EAAU,EAAoC,CACvD,MAEJ,GAAc,EAAI,EAClB,GAAI,CACF,MAAM,EAAO,CACf,QAAU,CACR,EAAc,EAAK,CACrB,CALkB,CAMpB,CAEA,SAAS,EAAc,EAAyC,CAC9D,GAAI,EAAM,MAAQ,SAAU,CAC1B,EAAM,eAAe,EACrB,IAAe,EAAK,EACpB,MACF,CACI,EAAM,MAAQ,QAChB,EAAM,eAAe,EACjB,EAAM,SACR,EAAc,EAAU,OAAO,EAE/B,EAAc,EAAU,OAAO,EAGrC,CAEA,OACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiB,OAAoB,eAAc,SAAA,GACjD,UAAA,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,IAAK,EAAW,UAAU,YAAY,KAAM,EAAM,UAAW,EAArE,SAAA,CACG,IAAS,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,mBAAoB,SAAA,CAAU,CAAA,GACtD,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,qBAAf,SAAA,CACG,IAAQ,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,2BAA4B,SAAA,CAAU,CAAA,EAC7D,IAAY,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,2BAA4B,UAAc,CAAA,CACnE,KAEL,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,qBAAf,SAAA,CACG,CAAC,IACA,EAAA,EAAA,IAAA,CAAC,EAAD,CAAU,KAAK,YAAY,SAAU,EAAY,QAAS,EACvD,SAAA,CACO,CAAA,EAEX,EAAQ,IAAK,IACZ,EAAA,EAAA,IAAA,CAAC,EAAD,CAA4B,SAAU,GAAc,EAAO,SAAU,YAAe,EAAU,EAAO,MAAM,EACxG,SAAA,EAAO,IACA,EAFK,EAAO,IAEZ,CACX,CACE,GACC,GACC,CAAA,CAEf"}
@@ -0,0 +1,2 @@
1
+ export * from './react/index.js'
2
+ export {}