@godxjp/ui 9.1.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -29
- package/dist/app/index.d.ts +1 -1
- package/dist/app/index.js +4 -4
- package/dist/{app.prop-DnIXFzLi.d.ts → app.prop-Cy6dJnU8.d.ts} +18 -35
- package/dist/aspect-ratio-CZZJd9Km.d.ts +9 -0
- package/dist/{checkbox-ChRsR7Nk.d.ts → checkbox-em-oFM5D.d.ts} +1 -1
- package/dist/{chunk-LJLGABFV.js → chunk-2HXZT2WJ.js} +17 -9
- package/dist/{chunk-QLMXEJSY.js → chunk-3Q4A4U2P.js} +24 -1
- package/dist/{chunk-26CPAKUP.js → chunk-44YRPSZ7.js} +1 -2
- package/dist/{chunk-HB2OHB5X.js → chunk-5NCFLCM7.js} +27 -16
- package/dist/{chunk-FXFJF4YA.js → chunk-6CSBMMZS.js} +262 -31
- package/dist/{chunk-ZRRLOOBX.js → chunk-6HHSU6RG.js} +8 -6
- package/dist/{chunk-INSF6K3Y.js → chunk-7Q45MBFW.js} +7 -5
- package/dist/{chunk-O24Z3ULJ.js → chunk-BE6GJGKJ.js} +1 -1
- package/dist/{chunk-5D42MFB4.js → chunk-BG5RNXTH.js} +71 -2
- package/dist/{chunk-AINW5WYN.js → chunk-COD66MFF.js} +1 -2
- package/dist/{chunk-IOGU3ZWF.js → chunk-DNGJHWJZ.js} +3 -3
- package/dist/{chunk-3TS3G4U3.js → chunk-EE5DKOHX.js} +3 -1
- package/dist/{chunk-KXOAZGPA.js → chunk-EQZP53KI.js} +33 -8
- package/dist/{chunk-BHV2FUOA.js → chunk-EZHHJQWQ.js} +1 -1
- package/dist/{chunk-N3JPLJ3B.js → chunk-GDDCSKCB.js} +12 -5
- package/dist/{chunk-RLGHEV4A.js → chunk-HTG5VHU7.js} +10 -1
- package/dist/{chunk-R2W2FX5Q.js → chunk-I7NQ2LIL.js} +1 -9
- package/dist/{chunk-XQMPK4GM.js → chunk-IHRMOJXD.js} +86 -39
- package/dist/{chunk-TILFZBTE.js → chunk-INIIF7F7.js} +1 -4
- package/dist/{chunk-UIYEAUWA.js → chunk-IY347EQA.js} +2 -2
- package/dist/{chunk-HCM4JAC2.js → chunk-JWGLJXQU.js} +39 -11
- package/dist/{chunk-TO33OY4L.js → chunk-LMKUKCTN.js} +1 -1
- package/dist/chunk-NXVCI6YB.js +453 -0
- package/dist/{chunk-JBHXILI4.js → chunk-O6DQZYNI.js} +63 -44
- package/dist/{chunk-O2OUNXV4.js → chunk-P5KPCT6R.js} +3 -3
- package/dist/{chunk-56NYZNVY.js → chunk-PDXFQS7M.js} +112 -49
- package/dist/{chunk-F7PG4OEV.js → chunk-QSGW3ZWK.js} +12 -4
- package/dist/{chunk-25RYBC5T.js → chunk-S2IJKT3D.js} +1 -1
- package/dist/{chunk-OJZ6C2HM.js → chunk-SARQRCKO.js} +54 -48
- package/dist/chunk-T2QO2S65.js +126 -0
- package/dist/{chunk-442ULAA6.js → chunk-TGNBXS7H.js} +142 -62
- package/dist/{chunk-6J7GRCDA.js → chunk-UNVRNJCB.js} +71 -11
- package/dist/{chunk-6YBYAEXD.js → chunk-VSM44AYE.js} +94 -24
- package/dist/chunk-VSUYVT2Q.js +163 -0
- package/dist/{chunk-4R7QL3MW.js → chunk-X2VY4MOW.js} +14 -29
- package/dist/{chunk-FRU44GA2.js → chunk-XK3M3VRR.js} +16 -2
- package/dist/{chunk-6YK3IJXW.js → chunk-Z46J47FY.js} +73 -77
- package/dist/components/admin/index.d.ts +23 -13
- package/dist/components/admin/index.js +29 -30
- package/dist/components/data-display/badge.js +3 -3
- package/dist/components/data-display/card.d.ts +3 -3
- package/dist/components/data-display/card.js +1 -1
- package/dist/components/data-display/carousel.js +3 -1
- package/dist/components/data-display/index.js +55 -33
- package/dist/components/data-entry/calendar.d.ts +1 -1
- package/dist/components/data-entry/calendar.js +1 -1
- package/dist/components/data-entry/cascader.d.ts +1 -1
- package/dist/components/data-entry/cascader.js +5 -5
- package/dist/components/data-entry/checkbox.d.ts +2 -2
- package/dist/components/data-entry/checkbox.js +2 -2
- package/dist/components/data-entry/color-picker.d.ts +1 -1
- package/dist/components/data-entry/color-picker.js +3 -3
- package/dist/components/data-entry/date-picker.d.ts +2 -2
- package/dist/components/data-entry/date-picker.js +4 -4
- package/dist/components/data-entry/date-range-picker.d.ts +2 -2
- package/dist/components/data-entry/date-range-picker.js +4 -4
- package/dist/components/data-entry/index.d.ts +9 -25
- package/dist/components/data-entry/index.js +22 -26
- package/dist/components/data-entry/radio.d.ts +1 -1
- package/dist/components/data-entry/radio.js +2 -2
- package/dist/components/data-entry/select.d.ts +2 -2
- package/dist/components/data-entry/select.js +3 -4
- package/dist/components/data-entry/slider.d.ts +1 -1
- package/dist/components/data-entry/switch.d.ts +2 -2
- package/dist/components/data-entry/switch.js +1 -1
- package/dist/components/data-entry/time-input.js +2 -2
- package/dist/components/data-entry/time-picker.d.ts +3 -1
- package/dist/components/data-entry/time-picker.js +3 -3
- package/dist/components/data-entry/transfer.d.ts +2 -2
- package/dist/components/data-entry/transfer.js +5 -5
- package/dist/components/data-entry/tree-select.d.ts +1 -1
- package/dist/components/data-entry/tree-select.js +5 -5
- package/dist/components/data-entry/upload.d.ts +2 -2
- package/dist/components/data-entry/upload.js +5 -5
- package/dist/components/feedback/alert.js +5 -5
- package/dist/components/feedback/dialog.d.ts +20 -1
- package/dist/components/feedback/dialog.js +3 -3
- package/dist/components/feedback/index.d.ts +10 -18
- package/dist/components/feedback/index.js +9 -9
- package/dist/components/feedback/sheet.js +1 -1
- package/dist/components/layout/index.d.ts +27 -15
- package/dist/components/layout/index.js +7 -5
- package/dist/components/navigation/dropdown-menu.js +1 -1
- package/dist/components/navigation/index.d.ts +15 -17
- package/dist/components/navigation/index.js +7 -8
- package/dist/components/navigation/pagination.d.ts +25 -4
- package/dist/components/navigation/pagination.js +4 -5
- package/dist/components/navigation/steps.d.ts +3 -3
- package/dist/components/navigation/steps.js +3 -1
- package/dist/components/query/index.d.ts +1 -5
- package/dist/components/query/index.js +6 -8
- package/dist/components/ui/index.d.ts +13 -12
- package/dist/components/ui/index.js +30 -32
- package/dist/{data-entry.prop-CDkOajPj.d.ts → data-entry.prop-BR4vNA1j.d.ts} +7 -35
- package/dist/filter-bar-BxjSJJnQ.d.ts +7 -0
- package/dist/{inline-DCqn4O29.d.ts → flex-D_EXRFSW.d.ts} +2 -8
- package/dist/form/index.js +1 -1
- package/dist/i18n/index.d.ts +82 -10
- package/dist/i18n/index.js +2 -2
- package/dist/index.d.ts +7 -7
- package/dist/index.js +41 -44
- package/dist/{layout.prop-DwJKI6ka.d.ts → layout.prop-JE2TcRyL.d.ts} +8 -2
- package/dist/lib/datetime/index.js +1 -1
- package/dist/{navigation.prop-8DgElO0c.d.ts → navigation.prop-DMcXkR-J.d.ts} +9 -11
- package/dist/{toggle-group-BulJgKh3.d.ts → password-strength-DVRvXEOK.d.ts} +24 -3
- package/dist/props/components/index.d.ts +4 -4
- package/dist/props/index.d.ts +4 -4
- package/dist/props/index.js +1 -1
- package/dist/props/registry.d.ts +84 -39
- package/dist/props/registry.js +1 -1
- package/dist/{search-input-cezAxpgb.d.ts → search-input-DpqDMXcn.d.ts} +2 -4
- package/dist/{skeleton-uWAjSacg.d.ts → skeleton-cj9kh5wo.d.ts} +1 -3
- package/dist/styles/control.css +176 -41
- package/dist/styles/data-display-layout.css +41 -15
- package/dist/styles/data-entry-layout.css +71 -0
- package/dist/styles/feedback-layout.css +44 -12
- package/dist/styles/index.css +45 -1
- package/dist/styles/layout.css +66 -17
- package/dist/styles/navigation-layout.css +3 -1
- package/dist/styles/shell-layout.css +3 -3
- package/dist/styles/table-layout.css +13 -0
- package/dist/tokens/foundation.css +12 -1
- package/dist/tokens/semantic/layout.css +2 -2
- package/dist/tooltip-Bf2KjRy8.d.ts +14 -0
- package/package.json +7 -7
- package/scripts/ui-audit.mjs +31 -2
- package/dist/aspect-ratio-DGoYrOry.d.ts +0 -6
- package/dist/chunk-CAEL2ZD2.js +0 -222
- package/dist/chunk-FYM3MJSK.js +0 -59
- package/dist/chunk-GKXPALFT.js +0 -32
- package/dist/chunk-JKHWLPM5.js +0 -101
- package/dist/chunk-KDBGFJJI.js +0 -220
- package/dist/chunk-VN72SWHX.js +0 -189
- package/dist/components/data-entry/autocomplete.d.ts +0 -24
- package/dist/components/data-entry/autocomplete.js +0 -10
- package/dist/components/data-entry/combobox.d.ts +0 -22
- package/dist/components/data-entry/combobox.js +0 -6
- package/dist/filter-bar-BycYH10i.d.ts +0 -14
- /package/dist/{chunk-LDSLS6HE.js → chunk-7CFO5FFE.js} +0 -0
package/README.md
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
# @godxjp/ui
|
|
2
2
|
|
|
3
3
|
The shared React UI framework for every godx surface (admin, agency portal,
|
|
4
|
-
handheld). Built on shadcn + Radix UI + Tailwind CSS v4.
|
|
4
|
+
handheld). Built on shadcn + Radix UI + Tailwind CSS v4. **~98 components**, fully catalogued.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
- 📦 **npm:** `@godxjp/ui` (published) · MCP server `@godxjp/ui-mcp`
|
|
7
|
+
- 🌐 **Live preview / catalog:** **https://godx-jp.github.io/godxjp-ui/** (components · tokens · props)
|
|
8
|
+
- 🤖 **Agents:** the `@godxjp/ui-mcp` server exposes the full catalog (`get_component`, `list_primitives`, `search_components`) so coding agents use the real API instead of hand-rolling.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm i @godxjp/ui
|
|
12
|
+
```
|
|
8
13
|
|
|
9
14
|
---
|
|
10
15
|
|
|
@@ -22,6 +27,11 @@ infrastructure, which means two things are non-negotiable:
|
|
|
22
27
|
logic, no product copy, no raw colors. Those are **consumer-layer** concerns — they
|
|
23
28
|
must never leak into this package. The framework ships **its own theme**, so a
|
|
24
29
|
consumer imports the styles and needs **zero** extra theme configuration.
|
|
30
|
+
- **The root export is runtime-neutral.** Importing `@godxjp/ui` (or its primitive
|
|
31
|
+
subpaths) forces **no** foreign runtime — React Router, TanStack Query, react-hook-form
|
|
32
|
+
and the i18n singleton live ONLY on their adapter subpaths (`./form`, `./query`, `./app`).
|
|
33
|
+
A CI guard (`pnpm check:core-isolation`) traces the root dist graph and fails the build if
|
|
34
|
+
an adapter ever leaks into the root barrel.
|
|
25
35
|
|
|
26
36
|
> Deciding whether a component belongs here vs. app-level? Use the
|
|
27
37
|
> **`godx-ui-component-placement`** skill.
|
|
@@ -33,17 +43,17 @@ Full contributor rules: **[docs/DEVELOPMENT.md](./docs/DEVELOPMENT.md)**.
|
|
|
33
43
|
## Architecture (bottom-up)
|
|
34
44
|
|
|
35
45
|
```
|
|
36
|
-
src/tokens/ Design tokens —
|
|
37
|
-
foundation.css :root + .dark:
|
|
38
|
-
|
|
46
|
+
src/tokens/ Design tokens — 3-tier: primitive → semantic → component
|
|
47
|
+
foundation.css primitive :root + .dark: raw palette, fonts, type scale, spacing, radius, wa-iro
|
|
48
|
+
semantic/ UI-role aliases (--primary, --destructive, --muted, …)
|
|
49
|
+
components/ per-component tokens (--card-*, --badge-*, …) aliasing semantic/primitive
|
|
39
50
|
src/styles/ CSS that styles components by [data-slot]; density.css = the one density knob
|
|
40
51
|
index.css Entry: fontsource → tailwindcss → @theme (token→utility map) → *-layout.css
|
|
41
52
|
src/components/ React components by group (data-display, data-entry, layout, feedback, …)
|
|
42
|
-
src/props/ Prop type system: vocabulary/ (atomic) + components/ + registry.ts
|
|
43
|
-
src/lib/ cn(), control-styles, variants
|
|
44
|
-
examples/ *.preview.tsx — Storybook-style stories
|
|
45
|
-
|
|
46
|
-
preview/ The preview app (vite, :6008) rendering examples + docs
|
|
53
|
+
src/props/ Prop type system: vocabulary/ (atomic) + components/ + registry.ts (NORMATIVE, CI-checked)
|
|
54
|
+
src/lib/ cn(), control-styles, variants, hooks
|
|
55
|
+
examples/ *.preview.tsx — Storybook-style stories (rendered by the preview app + Pages site)
|
|
56
|
+
preview/ The preview app (vite, :6008) → also deployed to GitHub Pages
|
|
47
57
|
```
|
|
48
58
|
|
|
49
59
|
A value is defined **once** as a CSS var (`--primary`), mapped to a utility in the
|
|
@@ -55,19 +65,25 @@ Components emit `data-slot` / `data-*`; the look lives in `styles/*-layout.css`.
|
|
|
55
65
|
|
|
56
66
|
## Component groups
|
|
57
67
|
|
|
58
|
-
| Group | Import | Examples
|
|
59
|
-
| ------------------ | ------------------------- |
|
|
60
|
-
| **Layout** | `@godxjp/ui/layout` | `PageContainer`, `
|
|
61
|
-
| **General** | `@godxjp/ui/general` | `Button`
|
|
62
|
-
| **Data Entry** | `@godxjp/ui/data-entry` | `Input`, `Select`, `FormField`, `DatePicker`, `Switch`
|
|
63
|
-
| **Data Display** | `@godxjp/ui/data-display` | `Table`, `DataTable`, `Card`, `Badge`, `
|
|
64
|
-
| **Feedback** | `@godxjp/ui/feedback` | `Dialog`, `
|
|
65
|
-
| **Query** | `@godxjp/ui/query` | `DataState`, `InfiniteQueryState`, `PrefetchLink
|
|
66
|
-
| **Navigation** | `@godxjp/ui/navigation` | `Tabs`, `FilterBar
|
|
67
|
-
| **App** | `@godxjp/ui/app` | `AppProvider`, `useDateTime`
|
|
68
|
-
| **Datetime** | `@godxjp/ui/datetime` | `formatDate` (mandatory for display)
|
|
69
|
-
| **
|
|
70
|
-
| **
|
|
68
|
+
| Group | Import | Examples |
|
|
69
|
+
| ------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
70
|
+
| **Layout** | `@godxjp/ui/layout` | `Flex` (+ `Stack`/`Inline`), `PageContainer`, `ResponsiveGrid`, `AppShell`, `Sidebar`, `Separator`, `AspectRatio`, `Resizable` |
|
|
71
|
+
| **General** | `@godxjp/ui/general` | `Button` |
|
|
72
|
+
| **Data Entry** | `@godxjp/ui/data-entry` | `Input`, `Select`, `FormField`, `Field`, `DatePicker`, `TimePicker`, `Combobox`, `Switch`, `Toggle`, `Upload`, `Cascader`, `TreeSelect`, `ColorPicker`, `Slider`, `PasswordInput`, `PasswordStrength`, `InputOTP`, `Rating`, `TagInput` |
|
|
73
|
+
| **Data Display** | `@godxjp/ui/data-display` | `Table`, `DataTable`, `Card`, `StatCard`, `Badge`, `Avatar`, `Descriptions`, `Timeline`, `EmptyState`, `Progress`, `Accordion`, `HoverCard`, `Carousel`, `Popover`, `Collapsible` |
|
|
74
|
+
| **Feedback** | `@godxjp/ui/feedback` | `Dialog`, `AlertDialog`, `Sheet` (side), `Drawer` (bottom-sheet), `Toast`, `Skeleton`, `Alert`, `Tooltip` |
|
|
75
|
+
| **Query** | `@godxjp/ui/query` | `DataState`, `InfiniteQueryState`, `PrefetchLink` (adapter subpath — pulls TanStack Query) |
|
|
76
|
+
| **Navigation** | `@godxjp/ui/navigation` | `Tabs`, `Toolbar` (+ `FilterBar`), `DropdownMenu`, `ContextMenu`, `Menubar`, `NavigationMenu`, `Steps`, `Pagination`, `Breadcrumb`, `LocalePicker` |
|
|
77
|
+
| **App** | `@godxjp/ui/app` | `AppProvider`, `useDateTime` (adapter — i18n/datetime singleton) |
|
|
78
|
+
| **Datetime** | `@godxjp/ui/datetime` | `formatDate` (mandatory for display) |
|
|
79
|
+
| **Form** | `@godxjp/ui/form` | `useZodForm`, `FormRoot` (adapter subpath — pulls react-hook-form) |
|
|
80
|
+
| **Hooks** | `@godxjp/ui/hooks` | `useIsMobile`, `useMediaQuery` |
|
|
81
|
+
| **shadcn paths** | `@godxjp/ui/ui` | Thin re-exports for shadcn-style imports (tree-shakeable) |
|
|
82
|
+
| **Admin (legacy)** | `@godxjp/ui/admin` | Compound admin exports |
|
|
83
|
+
|
|
84
|
+
> **Renamed in 8.0** (thin aliases kept): `Stack`/`Inline`→`Flex`, `KeyValueGrid`→`Descriptions`,
|
|
85
|
+
> `ProgressMeter`→`Progress`, `CardStat`→`StatCard`, `FilterBar`→`Toolbar`, `ChoiceField`→`Field`,
|
|
86
|
+
> `SkeletonCard`→`SkeletonStat`. `StatusBadge`→`Badge` (`status`/`tone`), `DialogConfirm`/`Dialog mode="confirm"`→`AlertDialog`.
|
|
71
87
|
|
|
72
88
|
---
|
|
73
89
|
|
|
@@ -123,15 +139,25 @@ control + table heights together.
|
|
|
123
139
|
|
|
124
140
|
```bash
|
|
125
141
|
pnpm preview # preview app → http://localhost:6008 (fixed port, kills stale)
|
|
126
|
-
pnpm preview:build # static build —
|
|
127
|
-
pnpm
|
|
128
|
-
pnpm typecheck && pnpm audit && pnpm test
|
|
129
|
-
pnpm check:mcp-sync # MCP registry ↔ library export drift guard (also in verify)
|
|
142
|
+
pnpm preview:build # static build — also what deploys to GitHub Pages
|
|
143
|
+
pnpm verify # typecheck · lint · format · the 5 guards · test
|
|
130
144
|
pnpm release --ui <patch|minor|major> --mcp <…|skip> # publish lib + MCP in lockstep
|
|
131
145
|
```
|
|
132
146
|
|
|
147
|
+
**Five CI guards** (wired into `verify` / `verify:release`) keep the library honest:
|
|
148
|
+
|
|
149
|
+
| Guard | Enforces |
|
|
150
|
+
| ----------------------- | -------------------------------------------------------------------- |
|
|
151
|
+
| `check:prop-vocabulary` | every public `*Prop` field maps to the registry (no ad-hoc props) |
|
|
152
|
+
| `check:token-tiers` | 3-tier tokens; no domain/raw-palette tokens in component CSS |
|
|
153
|
+
| `check:mcp-sync` | every MCP catalog entry is a real export (no stale agent guidance) |
|
|
154
|
+
| `check:mcp-orphans` | every public component HAS a catalog entry (catalog can't rot) |
|
|
155
|
+
| `check:core-isolation` | the root export pulls no foreign runtime (adapters stay on subpaths) |
|
|
156
|
+
|
|
133
157
|
This repo ships two packages — `@godxjp/ui` (this dir) and `@godxjp/ui-mcp` (`mcp/`). They keep
|
|
134
158
|
separate version lines but release together via `pnpm release`; see DEVELOPMENT.md §6.
|
|
159
|
+
The **preview app auto-deploys to [GitHub Pages](https://godx-jp.github.io/godxjp-ui/)** on every push to `main`
|
|
160
|
+
(`.github/workflows/preview-pages.yml`) — which doubles as the CI gate for `preview:build`.
|
|
135
161
|
|
|
136
162
|
→ **[docs/DEVELOPMENT.md](./docs/DEVELOPMENT.md)** is the contributor guideline (the
|
|
137
163
|
boundary, the layers, how to add/extend a component, verification).
|
|
@@ -139,7 +165,10 @@ boundary, the layers, how to add/extend a component, verification).
|
|
|
139
165
|
## Docs index
|
|
140
166
|
|
|
141
167
|
- [docs/DEVELOPMENT.md](./docs/DEVELOPMENT.md) — contributor guideline (start here to edit the package)
|
|
168
|
+
- [docs/STANDARDS-vocabulary-tokens.md](./docs/STANDARDS-vocabulary-tokens.md) — the 22 vocabulary + token rules (CI-enforced)
|
|
169
|
+
- [docs/roadmap/post-7.0.0.md](./docs/roadmap/post-7.0.0.md) — shipped log (7.0→9.2) + key decisions
|
|
142
170
|
- [docs/COMPONENTS.md](./docs/COMPONENTS.md) · [docs/TOKENS.md](./docs/TOKENS.md) · [docs/SPACING.md](./docs/SPACING.md)
|
|
143
171
|
- [docs/PROPS-VOCABULARY.md](./docs/PROPS-VOCABULARY.md) · [docs/PROPS-REGISTRY.md](./docs/PROPS-REGISTRY.md)
|
|
144
172
|
- [docs/DATETIME.md](./docs/DATETIME.md) · [docs/FORMS.md](./docs/FORMS.md) · [docs/TESTING.md](./docs/TESTING.md)
|
|
145
|
-
-
|
|
173
|
+
- **Architecture decisions** under `debate/*/04-Decision.md` (ADRs from the design debates)
|
|
174
|
+
- MCP: **godxjp-ui-mcp** (`.mcp.json`) — live catalog for agents
|
package/dist/app/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as date_fns from 'date-fns';
|
|
|
5
5
|
import { Locale } from 'date-fns';
|
|
6
6
|
import { vi } from 'react-day-picker/locale';
|
|
7
7
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
8
|
-
import { a as AppProviderProp, A as AppContextValue } from '../app.prop-
|
|
8
|
+
import { a as AppProviderProp, A as AppContextValue } from '../app.prop-Cy6dJnU8.js';
|
|
9
9
|
import { j as formatDate, a as FormatDateOptions } from '../format-date-ByyZoqI5.js';
|
|
10
10
|
export { F as FormatDateKind, b as FormatDatetimeOptions, d as detectFormatDateKind, f as formatAppDate, c as formatAppDateLong, e as formatAppDateTime, g as formatAppRelative, h as formatAppTime, i as formatCalendarDate, k as formatTimeOfDay, m as isFormatDateValue } from '../format-date-ByyZoqI5.js';
|
|
11
11
|
export { getDatetimeContext, isValidHhmm, normalizeHhmm, parseDateInput, syncDatetimeContext } from '../lib/datetime/index.js';
|
package/dist/app/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useAppContext } from '../chunk-
|
|
2
|
-
export { APP_LOCALES, APP_REQUEST_HEADER_LOCALE, APP_REQUEST_HEADER_TIMEZONE, APP_TIMEZONE_OPTIONS, APP_TIMEZONE_PRESET, APP_TIME_FORMAT_OPTIONS, AppProvider, DEFAULT_STORAGE_KEY, TIMEZONE_ALIASES, formatTimezoneDisplayLabel, getAllIanaTimezones, getAppRequestHeaders, getBrowserTimezone, getTimeFormatLabel, getTimezoneCityName, getTimezoneLabel, getTimezoneOffsetLabel, isKnownAppTimezone, isValidIanaTimezone, readStoredPreferences, resetAppRequestHeaders, resetIanaTimezoneCacheForTests, resolveDefaultTimeFormat, resolveDefaultTimezone, resolveTimezoneForIntl, resolveTimezonePickerOptions, syncAppRequestHeaders, useAppContext, useAppDateFormat, useAppLocale, useAppTimeFormat, useAppTimezone, useOptionalAppContext, usePickerLocales, useTranslation, writeStoredPreferences } from '../chunk-
|
|
3
|
-
import { formatDate } from '../chunk-
|
|
4
|
-
export { APP_DATE_FORMATS, APP_DATE_FORMAT_OPTIONS, APP_LOCALE_CONFIG, APP_REQUEST_HEADER_DATE_FORMAT, APP_REQUEST_HEADER_TIME_FORMAT, APP_TIME_FORMATS, detectFormatDateKind, formatAppDate, formatAppDateLong, formatAppDateTime, formatAppRelative, formatAppTime, formatCalendarDate, formatDate, formatTimeOfDay, getDateFnsLocale, getDateFormatLabel, getDatePattern, getDateTimePattern, getDatetimeContext, getDayPickerLocale, getTimePattern, isAppDateFormat, isAppLocale, isAppTimeFormat, isFormatDateValue, isValidHhmm, normalizeHhmm, parseDateInput, resolveDefaultDateFormat, syncDatetimeContext } from '../chunk-
|
|
1
|
+
import { useAppContext } from '../chunk-HTG5VHU7.js';
|
|
2
|
+
export { APP_LOCALES, APP_REQUEST_HEADER_LOCALE, APP_REQUEST_HEADER_TIMEZONE, APP_TIMEZONE_OPTIONS, APP_TIMEZONE_PRESET, APP_TIME_FORMAT_OPTIONS, AppProvider, DEFAULT_STORAGE_KEY, TIMEZONE_ALIASES, formatTimezoneDisplayLabel, getAllIanaTimezones, getAppRequestHeaders, getBrowserTimezone, getTimeFormatLabel, getTimezoneCityName, getTimezoneLabel, getTimezoneOffsetLabel, isKnownAppTimezone, isValidIanaTimezone, readStoredPreferences, resetAppRequestHeaders, resetIanaTimezoneCacheForTests, resolveDefaultTimeFormat, resolveDefaultTimezone, resolveTimezoneForIntl, resolveTimezonePickerOptions, syncAppRequestHeaders, useAppContext, useAppDateFormat, useAppLocale, useAppTimeFormat, useAppTimezone, useOptionalAppContext, usePickerLocales, useTranslation, writeStoredPreferences } from '../chunk-HTG5VHU7.js';
|
|
3
|
+
import { formatDate } from '../chunk-6CSBMMZS.js';
|
|
4
|
+
export { APP_DATE_FORMATS, APP_DATE_FORMAT_OPTIONS, APP_LOCALE_CONFIG, APP_REQUEST_HEADER_DATE_FORMAT, APP_REQUEST_HEADER_TIME_FORMAT, APP_TIME_FORMATS, detectFormatDateKind, formatAppDate, formatAppDateLong, formatAppDateTime, formatAppRelative, formatAppTime, formatCalendarDate, formatDate, formatTimeOfDay, getDateFnsLocale, getDateFormatLabel, getDatePattern, getDateTimePattern, getDatetimeContext, getDayPickerLocale, getTimePattern, isAppDateFormat, isAppLocale, isAppTimeFormat, isFormatDateValue, isValidHhmm, normalizeHhmm, parseDateInput, resolveDefaultDateFormat, syncDatetimeContext } from '../chunk-6CSBMMZS.js';
|
|
5
5
|
import { useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
function useFormatting() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Locale } from 'date-fns';
|
|
2
2
|
import { DayPickerProps } from 'react-day-picker';
|
|
3
3
|
import { h as AppLocale, l as AppTimezoneDefault, k as AppTimezone, j as AppTimeFormat, g as AppDateFormat, i as AppRequestHeaders } from './types-mvzYGrma.js';
|
|
4
|
-
import { C as ChildrenProp, a as ClassNameProp, c as DisabledProp, I as IdProp, V as ValueProp, g as OnValueChangeProp } from './shared.prop-BsNSXeqD.js';
|
|
4
|
+
import { C as ChildrenProp, a as ClassNameProp, c as DisabledProp, I as IdProp, N as NameProp, V as ValueProp, g as OnValueChangeProp } from './shared.prop-BsNSXeqD.js';
|
|
5
5
|
|
|
6
6
|
/** App shell prop types — @see docs/COMPONENTS.md#app */
|
|
7
7
|
|
|
@@ -21,7 +21,7 @@ type AppProviderProp = {
|
|
|
21
21
|
/** Initial date display format. `"locale"` derives from `defaultLocale`. Default: `"locale"`. */
|
|
22
22
|
defaultDateFormat?: AppDateFormat | "locale";
|
|
23
23
|
/**
|
|
24
|
-
* IANA ids
|
|
24
|
+
* IANA ids offered by the timezone-picker recipe (`useAppContext().timezoneOptions`).
|
|
25
25
|
* Omit for the full IANA list; set to restrict (e.g. `APP_TIMEZONE_PRESET`).
|
|
26
26
|
*/
|
|
27
27
|
timezoneOptions?: readonly AppTimezone[];
|
|
@@ -34,40 +34,23 @@ type AppProviderProp = {
|
|
|
34
34
|
onTimeFormatChange?: (timeFormat: AppTimeFormat) => void;
|
|
35
35
|
onDateFormatChange?: (dateFormat: AppDateFormat) => void;
|
|
36
36
|
};
|
|
37
|
-
/** @
|
|
38
|
-
type
|
|
37
|
+
/** Which AppProvider setting the {@link AppSettingPicker} reads/writes. */
|
|
38
|
+
type AppSettingKind = "locale" | "timezone" | "dateFormat" | "timeFormat";
|
|
39
|
+
/**
|
|
40
|
+
* @see AppSettingPicker — one provider-bound Select for any single AppProvider setting.
|
|
41
|
+
* Replaces the former Locale/Timezone/Date-format/Time-format pickers; pick the target
|
|
42
|
+
* via `kind`. Bound to `<AppProvider>` by default; pass value + onValueChange to control.
|
|
43
|
+
*/
|
|
44
|
+
type AppSettingPickerProp = {
|
|
45
|
+
kind: AppSettingKind;
|
|
39
46
|
className?: ClassNameProp;
|
|
40
47
|
disabled?: DisabledProp;
|
|
41
48
|
id?: IdProp;
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
type TimezonePickerProp = {
|
|
48
|
-
className?: ClassNameProp;
|
|
49
|
-
disabled?: DisabledProp;
|
|
50
|
-
id?: IdProp;
|
|
51
|
-
value?: ValueProp<AppTimezone>;
|
|
52
|
-
onValueChange?: OnValueChangeProp<AppTimezone>;
|
|
53
|
-
/** Override AppProvider list; omit to use context or full IANA. */
|
|
54
|
-
options?: readonly AppTimezone[];
|
|
55
|
-
};
|
|
56
|
-
/** @see TimeFormatPicker */
|
|
57
|
-
type TimeFormatPickerProp = {
|
|
58
|
-
className?: ClassNameProp;
|
|
59
|
-
disabled?: DisabledProp;
|
|
60
|
-
id?: IdProp;
|
|
61
|
-
value?: ValueProp<AppTimeFormat>;
|
|
62
|
-
onValueChange?: OnValueChangeProp<AppTimeFormat>;
|
|
63
|
-
};
|
|
64
|
-
/** @see DateFormatPicker */
|
|
65
|
-
type DateFormatPickerProp = {
|
|
66
|
-
className?: ClassNameProp;
|
|
67
|
-
disabled?: DisabledProp;
|
|
68
|
-
id?: IdProp;
|
|
69
|
-
value?: ValueProp<AppDateFormat>;
|
|
70
|
-
onValueChange?: OnValueChangeProp<AppDateFormat>;
|
|
49
|
+
/** Form field name — submits the selected value with the form. */
|
|
50
|
+
name?: NameProp;
|
|
51
|
+
/** Controlled value; default reads/writes the matching AppProvider context. */
|
|
52
|
+
value?: ValueProp<string>;
|
|
53
|
+
onValueChange?: OnValueChangeProp<string>;
|
|
71
54
|
};
|
|
72
55
|
/** Value exposed by `useAppContext`. */
|
|
73
56
|
type AppContextValue = {
|
|
@@ -79,7 +62,7 @@ type AppContextValue = {
|
|
|
79
62
|
dateFnsLocale: Locale;
|
|
80
63
|
dayPickerLocale: NonNullable<DayPickerProps["locale"]>;
|
|
81
64
|
requestHeaders: AppRequestHeaders;
|
|
82
|
-
/** Configured
|
|
65
|
+
/** Configured timezone list; `undefined` → full IANA in the timezone-picker recipe. */
|
|
83
66
|
timezoneOptions?: readonly AppTimezone[];
|
|
84
67
|
setLocale: (locale: AppLocale) => void;
|
|
85
68
|
setTimezone: (timezone: AppTimezone) => void;
|
|
@@ -87,4 +70,4 @@ type AppContextValue = {
|
|
|
87
70
|
setDateFormat: (dateFormat: AppDateFormat) => void;
|
|
88
71
|
};
|
|
89
72
|
|
|
90
|
-
export type { AppContextValue as A,
|
|
73
|
+
export type { AppContextValue as A, AppProviderProp as a, AppSettingKind as b, AppSettingPickerProp as c };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
3
|
+
import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
|
|
4
|
+
|
|
5
|
+
declare const Separator: React.ForwardRefExoticComponent<Omit<SeparatorPrimitive.SeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
6
|
+
|
|
7
|
+
declare const AspectRatio: React.ForwardRefExoticComponent<Omit<AspectRatioPrimitive.AspectRatioProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
|
|
9
|
+
export { AspectRatio as A, Separator as S };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
-
import { c as CheckboxGroupProp } from './data-entry.prop-
|
|
4
|
+
import { c as CheckboxGroupProp } from './data-entry.prop-BR4vNA1j.js';
|
|
5
5
|
|
|
6
6
|
declare function CheckboxGroup({ value: controlledValue, defaultValue, onValueChange, options, orientation, disabled, name, className, children, }: CheckboxGroupProp): react_jsx_runtime.JSX.Element;
|
|
7
7
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Calendar } from './chunk-
|
|
1
|
+
import { Calendar } from './chunk-DNGJHWJZ.js';
|
|
2
2
|
import { Input } from './chunk-VOHTRR5X.js';
|
|
3
3
|
import { Button } from './chunk-M4PZNAMV.js';
|
|
4
4
|
import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
|
|
5
|
-
import { useTranslation, usePickerLocales } from './chunk-
|
|
6
|
-
import { toIsoDate, parseDateInput } from './chunk-
|
|
5
|
+
import { useTranslation, usePickerLocales } from './chunk-HTG5VHU7.js';
|
|
6
|
+
import { toIsoDate, parseDateInput } from './chunk-6CSBMMZS.js';
|
|
7
7
|
import { cn } from './chunk-U7N2A7A3.js';
|
|
8
8
|
import * as React from 'react';
|
|
9
9
|
import { CalendarIcon } from 'lucide-react';
|
|
@@ -11,7 +11,8 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
11
11
|
|
|
12
12
|
var ISO_HINT = "yyyy-mm-dd";
|
|
13
13
|
function DatePicker({
|
|
14
|
-
value,
|
|
14
|
+
value: valueProp,
|
|
15
|
+
defaultValue,
|
|
15
16
|
onValueChange,
|
|
16
17
|
placeholder,
|
|
17
18
|
disabled,
|
|
@@ -25,6 +26,13 @@ function DatePicker({
|
|
|
25
26
|
const { t } = useTranslation();
|
|
26
27
|
const { dayPickerLocale } = usePickerLocales(localeProp);
|
|
27
28
|
const [open, setOpen] = React.useState(false);
|
|
29
|
+
const isControlled = React.useRef(valueProp !== void 0).current;
|
|
30
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
31
|
+
const value = isControlled ? valueProp : internalValue;
|
|
32
|
+
const emit = (next) => {
|
|
33
|
+
if (!isControlled) setInternalValue(next);
|
|
34
|
+
onValueChange?.(next);
|
|
35
|
+
};
|
|
28
36
|
const [text, setText] = React.useState(() => toIsoDate(value));
|
|
29
37
|
React.useEffect(() => {
|
|
30
38
|
setText(toIsoDate(value));
|
|
@@ -33,12 +41,12 @@ function DatePicker({
|
|
|
33
41
|
const commit = (raw) => {
|
|
34
42
|
const trimmed = raw.trim();
|
|
35
43
|
if (trimmed === "") {
|
|
36
|
-
|
|
44
|
+
emit(void 0);
|
|
37
45
|
return;
|
|
38
46
|
}
|
|
39
47
|
const parsed = parseDateInput(trimmed);
|
|
40
48
|
if (parsed) {
|
|
41
|
-
|
|
49
|
+
emit(parsed);
|
|
42
50
|
}
|
|
43
51
|
};
|
|
44
52
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
|
|
@@ -55,7 +63,7 @@ function DatePicker({
|
|
|
55
63
|
role: "combobox",
|
|
56
64
|
"aria-expanded": open,
|
|
57
65
|
"aria-haspopup": "dialog",
|
|
58
|
-
className: "
|
|
66
|
+
className: "pe-10",
|
|
59
67
|
onChange: (event) => {
|
|
60
68
|
setText(event.target.value);
|
|
61
69
|
commit(event.target.value);
|
|
@@ -76,7 +84,7 @@ function DatePicker({
|
|
|
76
84
|
disabled,
|
|
77
85
|
tabIndex: -1,
|
|
78
86
|
"aria-label": t("dataEntry.datePicker.openCalendar") ?? "Open calendar",
|
|
79
|
-
className: "text-muted-foreground absolute inset-y-0
|
|
87
|
+
className: "text-muted-foreground absolute inset-y-0 end-0 h-full px-2 hover:bg-transparent",
|
|
80
88
|
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4 shrink-0", "aria-hidden": "true" })
|
|
81
89
|
}
|
|
82
90
|
) }),
|
|
@@ -86,7 +94,7 @@ function DatePicker({
|
|
|
86
94
|
mode: "single",
|
|
87
95
|
selected: value,
|
|
88
96
|
onSelect: (date) => {
|
|
89
|
-
|
|
97
|
+
emit(date);
|
|
90
98
|
setText(toIsoDate(date));
|
|
91
99
|
setOpen(false);
|
|
92
100
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { normalizeHhmm, isValidHhmm } from './chunk-
|
|
1
|
+
import { normalizeHhmm, isValidHhmm } from './chunk-6CSBMMZS.js';
|
|
2
2
|
import { cn } from './chunk-U7N2A7A3.js';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
@@ -24,6 +24,14 @@ function maskTime(raw) {
|
|
|
24
24
|
if (digits.length <= 2) return digits;
|
|
25
25
|
return `${digits.slice(0, 2)}:${digits.slice(2)}`;
|
|
26
26
|
}
|
|
27
|
+
function stepTime(value, deltaMinutes) {
|
|
28
|
+
const normalized = normalizeHhmm(value) ?? "00:00";
|
|
29
|
+
const [hourText, minuteText] = normalized.split(":");
|
|
30
|
+
const total = (Number(hourText) * 60 + Number(minuteText) + deltaMinutes + 24 * 60) % (24 * 60);
|
|
31
|
+
const hour = Math.floor(total / 60);
|
|
32
|
+
const minute = total % 60;
|
|
33
|
+
return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
|
|
34
|
+
}
|
|
27
35
|
function TimeInput({
|
|
28
36
|
value: controlledValue,
|
|
29
37
|
defaultValue = "",
|
|
@@ -66,6 +74,7 @@ function TimeInput({
|
|
|
66
74
|
},
|
|
67
75
|
[isControlled, onValueChange, safeStep, value]
|
|
68
76
|
);
|
|
77
|
+
const valid = isValidHhmm(value);
|
|
69
78
|
return /* @__PURE__ */ jsx(
|
|
70
79
|
"input",
|
|
71
80
|
{
|
|
@@ -74,6 +83,11 @@ function TimeInput({
|
|
|
74
83
|
value: displayValue,
|
|
75
84
|
"data-slot": "time-input",
|
|
76
85
|
className: cn("ui-time-input", className),
|
|
86
|
+
role: "spinbutton",
|
|
87
|
+
"aria-valuemin": 0,
|
|
88
|
+
"aria-valuemax": 24 * 60 - 1,
|
|
89
|
+
"aria-valuenow": valid ? Number(value.slice(0, 2)) * 60 + Number(value.slice(3, 5)) : void 0,
|
|
90
|
+
"aria-valuetext": valid ? value : void 0,
|
|
77
91
|
"aria-invalid": displayValue !== "" && !isValidHhmm(displayValue) ? "true" : void 0,
|
|
78
92
|
placeholder: placeholder ?? "HH:mm",
|
|
79
93
|
inputMode: "numeric",
|
|
@@ -104,6 +118,15 @@ function TimeInput({
|
|
|
104
118
|
onKeyDown: (event) => {
|
|
105
119
|
if (event.key === "Enter") {
|
|
106
120
|
commit(event.currentTarget.value, true);
|
|
121
|
+
} else if (event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
const base = isValidHhmm(displayValue) ? displayValue : value || "00:00";
|
|
124
|
+
const next = stepTime(base, event.key === "ArrowUp" ? safeStep : -safeStep);
|
|
125
|
+
setDisplayValue(next);
|
|
126
|
+
if (!isControlled) {
|
|
127
|
+
setInternal(next);
|
|
128
|
+
}
|
|
129
|
+
onValueChange?.(next);
|
|
107
130
|
}
|
|
108
131
|
props.onKeyDown?.(event);
|
|
109
132
|
}
|
|
@@ -11,11 +11,10 @@ function Field({ id, label, description, className, children }) {
|
|
|
11
11
|
] })
|
|
12
12
|
] });
|
|
13
13
|
}
|
|
14
|
-
var ChoiceField = Field;
|
|
15
14
|
|
|
16
15
|
// src/components/data-entry/choice-option.ts
|
|
17
16
|
function choiceGroupClassName(_orientation = "vertical", className) {
|
|
18
17
|
return cn("ui-choice-group", className);
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
export {
|
|
20
|
+
export { Field, choiceGroupClassName };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { normalizeTreeOptions, formatPathLabels, getNodeByPath, filterTreeOptions, pathsEqual, pathKey } from './chunk-SMLKNECP.js';
|
|
2
|
-
import { Checkbox } from './chunk-O24Z3ULJ.js';
|
|
3
2
|
import { Command, CommandInput } from './chunk-HTEL5DQI.js';
|
|
3
|
+
import { Checkbox } from './chunk-BE6GJGKJ.js';
|
|
4
4
|
import { Button } from './chunk-M4PZNAMV.js';
|
|
5
5
|
import { Popover, PopoverTrigger, PopoverContent } from './chunk-DY5C44UP.js';
|
|
6
6
|
import { ScrollArea, ScrollBar } from './chunk-3KPEZ5CF.js';
|
|
7
|
-
import { useTranslation } from './chunk-
|
|
7
|
+
import { useTranslation } from './chunk-HTG5VHU7.js';
|
|
8
8
|
import { cn } from './chunk-U7N2A7A3.js';
|
|
9
9
|
import * as React from 'react';
|
|
10
10
|
import { X, ChevronsUpDown, Check, ChevronRight } from 'lucide-react';
|
|
@@ -117,17 +117,24 @@ function Cascader({
|
|
|
117
117
|
/* @__PURE__ */ jsx("div", { className: "flex max-h-[min(280px,50vh)]", children: columns.map((col, colIndex) => /* @__PURE__ */ jsx(
|
|
118
118
|
"ul",
|
|
119
119
|
{
|
|
120
|
-
|
|
120
|
+
role: "listbox",
|
|
121
|
+
"aria-orientation": "vertical",
|
|
122
|
+
"aria-multiselectable": multiple ? true : void 0,
|
|
123
|
+
className: "min-w-[9rem] border-e last:border-e-0",
|
|
121
124
|
onMouseLeave: expandTrigger === "hover" ? () => setActivePath(activePath.slice(0, colIndex)) : void 0,
|
|
122
125
|
children: col.map((node) => {
|
|
123
126
|
const path = [...activePath.slice(0, colIndex), node.value];
|
|
124
127
|
const hasChildren = (node.children?.length ?? 0) > 0 && node.isLeaf !== true;
|
|
125
128
|
const active = activePath[colIndex] === node.value;
|
|
126
129
|
const selected = multiple ? pathInValues(path, multiValue) : pathsEqual(path, singleValue);
|
|
127
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
130
|
+
return /* @__PURE__ */ jsx("li", { role: "none", children: /* @__PURE__ */ jsxs(
|
|
128
131
|
"button",
|
|
129
132
|
{
|
|
130
133
|
type: "button",
|
|
134
|
+
role: "option",
|
|
135
|
+
"aria-selected": selected,
|
|
136
|
+
"aria-haspopup": hasChildren ? "menu" : void 0,
|
|
137
|
+
"aria-expanded": hasChildren ? active : void 0,
|
|
131
138
|
disabled: node.disabled,
|
|
132
139
|
className: cn(
|
|
133
140
|
"flex w-full items-center gap-1 px-3 py-2 text-sm outline-none",
|
|
@@ -143,13 +150,13 @@ function Cascader({
|
|
|
143
150
|
{
|
|
144
151
|
checked: selected,
|
|
145
152
|
disabled: node.disabled,
|
|
146
|
-
className: "
|
|
153
|
+
className: "me-1",
|
|
147
154
|
"aria-hidden": true,
|
|
148
155
|
tabIndex: -1
|
|
149
156
|
}
|
|
150
157
|
),
|
|
151
|
-
!multiple && selected && /* @__PURE__ */ jsx(Check, { className: "
|
|
152
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-
|
|
158
|
+
!multiple && selected && /* @__PURE__ */ jsx(Check, { className: "me-1 size-4 shrink-0", "aria-hidden": "true" }),
|
|
159
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate text-start", children: node.label }),
|
|
153
160
|
hasChildren && /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 shrink-0 opacity-50", "aria-hidden": "true" })
|
|
154
161
|
]
|
|
155
162
|
}
|
|
@@ -177,13 +184,15 @@ function Cascader({
|
|
|
177
184
|
),
|
|
178
185
|
children: [
|
|
179
186
|
/* @__PURE__ */ jsx("span", { className: "truncate", children: displayLabel ?? resolvedPlaceholder }),
|
|
180
|
-
/* @__PURE__ */ jsxs("span", { className: "
|
|
187
|
+
/* @__PURE__ */ jsxs("span", { className: "ms-2 flex shrink-0 items-center gap-1", children: [
|
|
181
188
|
allowClear && displayLabel && !disabled && /* @__PURE__ */ jsx(
|
|
182
|
-
|
|
189
|
+
"button",
|
|
183
190
|
{
|
|
184
|
-
|
|
185
|
-
"aria-
|
|
186
|
-
|
|
191
|
+
type: "button",
|
|
192
|
+
"aria-label": t("dataEntry.cascader.clear"),
|
|
193
|
+
className: "flex size-4 items-center justify-center rounded-sm opacity-50 hover:opacity-100 focus-visible:opacity-100",
|
|
194
|
+
onClick: clearValue,
|
|
195
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4", "aria-hidden": "true" })
|
|
187
196
|
}
|
|
188
197
|
),
|
|
189
198
|
/* @__PURE__ */ jsx(ChevronsUpDown, { className: "size-4 opacity-50", "aria-hidden": "true" })
|
|
@@ -205,13 +214,15 @@ function Cascader({
|
|
|
205
214
|
onValueChange: setSearch
|
|
206
215
|
}
|
|
207
216
|
) }) }),
|
|
208
|
-
isSearching ? /* @__PURE__ */ jsx(ScrollArea, { className: "max-h-[min(300px,50vh)]", children: /* @__PURE__ */ jsx("div", { className: "p-1", children: searchResults.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground py-6 text-center text-sm", children: t("dataEntry.cascader.empty") }) : searchResults.map(({ path, labels }) => {
|
|
217
|
+
isSearching ? /* @__PURE__ */ jsx(ScrollArea, { className: "max-h-[min(300px,50vh)]", children: /* @__PURE__ */ jsx("div", { className: "p-1", role: "listbox", "aria-multiselectable": multiple ? true : void 0, children: searchResults.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground py-6 text-center text-sm", children: t("dataEntry.cascader.empty") }) : searchResults.map(({ path, labels }) => {
|
|
209
218
|
const label = labels.join(" / ");
|
|
210
219
|
const selected = multiple ? pathInValues(path, multiValue) : pathsEqual(path, singleValue);
|
|
211
220
|
return /* @__PURE__ */ jsxs(
|
|
212
221
|
"button",
|
|
213
222
|
{
|
|
214
223
|
type: "button",
|
|
224
|
+
role: "option",
|
|
225
|
+
"aria-selected": selected,
|
|
215
226
|
className: cn(
|
|
216
227
|
"flex w-full items-center rounded-sm px-2 py-1.5 text-sm outline-none",
|
|
217
228
|
"hover:bg-accent hover:text-accent-foreground",
|
|
@@ -219,17 +230,17 @@ function Cascader({
|
|
|
219
230
|
),
|
|
220
231
|
onClick: () => handleSelectNode({ value: path.at(-1)}, path),
|
|
221
232
|
children: [
|
|
222
|
-
multiple ? /* @__PURE__ */ jsx(Checkbox, { checked: selected, className: "
|
|
233
|
+
multiple ? /* @__PURE__ */ jsx(Checkbox, { checked: selected, className: "me-2", "aria-hidden": true, tabIndex: -1 }) : /* @__PURE__ */ jsx(
|
|
223
234
|
Check,
|
|
224
235
|
{
|
|
225
236
|
className: cn(
|
|
226
|
-
"
|
|
237
|
+
"me-2 size-4 shrink-0",
|
|
227
238
|
selected ? "opacity-100" : "opacity-0"
|
|
228
239
|
),
|
|
229
240
|
"aria-hidden": "true"
|
|
230
241
|
}
|
|
231
242
|
),
|
|
232
|
-
/* @__PURE__ */ jsx("span", { className: "truncate text-
|
|
243
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-start", children: label })
|
|
233
244
|
]
|
|
234
245
|
},
|
|
235
246
|
pathKey(path)
|