@jirawatpyk/aura-react 4.15.0 → 4.17.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 +76 -5
- package/dist/aura.bundle.js +239 -142
- package/dist/cjs/index.cjs +239 -142
- package/dist/esm/AppShell.js +9 -9
- package/dist/esm/Breadcrumb.js +1 -1
- package/dist/esm/Button.js +12 -3
- package/dist/esm/Command.js +69 -49
- package/dist/esm/DataTable.js +43 -16
- package/dist/esm/DatePicker.js +17 -146
- package/dist/esm/FileUpload.js +1 -10
- package/dist/esm/Pagination.js +35 -23
- package/dist/esm/Skeleton.js +4 -1
- package/dist/esm/Stat.js +1 -1
- package/dist/esm/StatusPill.js +4 -13
- package/dist/esm/TimePicker.js +1 -12
- package/dist/esm/breakpoints.js +5 -0
- package/dist/esm/colorScheme.js +1 -11
- package/dist/esm/colorSchemeScript.js +19 -0
- package/dist/esm/dates.js +164 -0
- package/dist/esm/locale.js +1 -347
- package/dist/esm/responsive.js +1 -1
- package/dist/esm/status.js +17 -0
- package/dist/esm/strings.js +351 -0
- package/dist/esm/text.js +30 -0
- package/dist/index.d.ts +537 -503
- package/dist/server/index.cjs +791 -0
- package/dist/server/index.d.ts +171 -0
- package/dist/server/index.js +768 -0
- package/dist/styles.css +69 -4
- package/dist/styles.layer.css +1352 -0
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -41,13 +41,15 @@ npm i @jirawatpyk/aura-react @jirawatpyk/aura-tokens # React 18 or 19; import
|
|
|
41
41
|
npm i @aura/react@npm:@jirawatpyk/aura-react @aura/tokens@npm:@jirawatpyk/aura-tokens
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
React 18.3 and 19 are both tested: the dev dependencies pin 18, and CI switches the whole workspace to 19 (`node scripts/use-react.mjs 19 && npm install`) and runs every suite again — contrast, token lint, SSR, types, build, hydration with 0 warnings, layout before hydration, the three pilot pages and Storybook (axe + behaviour).
|
|
45
|
+
|
|
44
46
|
Public on npmjs; internal projects can use GitHub Packages instead ([repository README](https://github.com/Jirawatpyk/Aura-design#use-it-in-a-project)).
|
|
45
47
|
|
|
46
48
|
```tsx
|
|
47
49
|
// app root (once)
|
|
48
50
|
import '@aura/tokens/aura.css'; // tokens (light + dark)
|
|
49
51
|
import '@aura/react/styles.css'; // component styles
|
|
50
|
-
// fonts:
|
|
52
|
+
// fonts: '@jirawatpyk/aura-tokens/aura-fonts.local.css' (self-hosted, CSP font-src 'self'), next/font, or Google Fonts — see the tokens README
|
|
51
53
|
|
|
52
54
|
import { AuraProvider, AppShell, SideNav, DataTable, DatePicker } from '@aura/react';
|
|
53
55
|
|
|
@@ -74,16 +76,31 @@ export default function Root() {
|
|
|
74
76
|
|
|
75
77
|
## Components (49)
|
|
76
78
|
|
|
77
|
-
Actions: Button, IconButton, Menu, DropdownMenu, Tag · Forms: TextField, PasswordField, Textarea, NumberField, Select, RadioGroup, Checkbox, Switch, SegmentedControl, Combobox (one value, or `multiple`), FileUpload (+ `formatBytes`) · Dates & times: DatePicker, DateRangePicker, Calendar, TimePicker (+ `useFormatDate`, `formatDate`, `parseDate`, `parseTime`) · Feedback: Alert, FormErrorSummary, Toaster/`toast()` (+ `.success/.error/.warning/.info/.loading`), Tooltip, StatusPill, Badge, Progress, Skeleton, EmptyState · Overlays: Dialog, Drawer, Popover · Data: DataTable, FilterBar, Stat · Navigation: Command (⌘K palette) · Layout: AppShell, Container, Stack, Grid, Accordion, Pagination, Card, Tabs, Stepper, SideNav, Breadcrumb, Avatar, Surface, Icon · Theme: ColorSchemeToggle, ColorSchemeScript, `useColorScheme`, ThemeStyle/`createTheme` · Hooks: `useBreakpoint`, `useResponsive`, `breakpoints`, `useAuraLocale`, `useDensity`.
|
|
79
|
+
Actions: Button (`ghost`, `size="sm"`), IconButton, Menu, DropdownMenu, Tag · Forms: TextField, PasswordField, Textarea, NumberField, Select, RadioGroup, Checkbox, Switch, SegmentedControl, Combobox (one value, or `multiple`), FileUpload (+ `formatBytes`) · Dates & times: DatePicker, DateRangePicker, Calendar, TimePicker (+ `useFormatDate`, `formatDate`, `parseDate`, `parseTime`) · Feedback: Alert, FormErrorSummary, Toaster/`toast()` (+ `.success/.error/.warning/.info/.loading`), Tooltip, StatusPill, Badge, Progress, Skeleton, EmptyState · Overlays: Dialog, Drawer, Popover · Data: DataTable, FilterBar, Stat · Navigation: Command (⌘K palette) · Layout: AppShell, Container, Stack, Grid, Accordion, Pagination, Card, Tabs, Stepper, SideNav, Breadcrumb, Avatar, Surface, Icon · Theme: ColorSchemeToggle, ColorSchemeScript, `useColorScheme`, ThemeStyle/`createTheme` · Hooks: `useBreakpoint`, `useResponsive`, `breakpoints`, `useAuraLocale`, `useDensity`.
|
|
78
80
|
|
|
79
81
|
## Router links, Swedish, motion
|
|
80
82
|
|
|
83
|
+
Next.js App Router: `next/link` is a function, and a Server Component (your layout) can't pass functions to a client component. Put the provider in a small `'use client'` file:
|
|
84
|
+
|
|
81
85
|
```tsx
|
|
86
|
+
// app/providers.tsx
|
|
87
|
+
'use client';
|
|
82
88
|
import Link from 'next/link';
|
|
83
|
-
|
|
89
|
+
import { AuraProvider } from '@jirawatpyk/aura-react';
|
|
90
|
+
export function Providers({ children, locale }: { children: React.ReactNode; locale: 'th' | 'en' | 'sv' }) {
|
|
91
|
+
return (
|
|
92
|
+
<AuraProvider locale={locale} linkComponent={Link}>
|
|
93
|
+
{children}
|
|
94
|
+
</AuraProvider>
|
|
95
|
+
);
|
|
96
|
+
{
|
|
97
|
+
/* th | en | sv */
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// app/layout.tsx (a Server Component): <body><Providers locale="th">{children}</Providers></body>
|
|
84
101
|
```
|
|
85
102
|
|
|
86
|
-
`linkComponent` is used by Button `href`, Breadcrumb, Pagination `getHref
|
|
103
|
+
`linkComponent` is used by Button `href`, Breadcrumb, Pagination `getHref` (page numbers and, since 4.17, the previous / next arrows), Stat `href`, SideNav and DataTable row/pager links. Each of them also takes its own `linkComponent`, which wins over the provider's. Pass `getHref` from a client component (it's a function too). The Next.js starter does all of this, and CI clicks every AURA link in it to check none triggers a full page load. Only `th` shows Buddhist-era years; `en` and `sv` are Gregorian (`sv` weeks start Monday). **Without a provider, components are English with Gregorian dates** — wrap Thai apps in `<AuraProvider locale="th">`. For dates in your own components use `useFormatDate()` — it follows the provider (`const fmt = useFormatDate(); fmt(iso, { format: 'long' })`). Plain `formatDate()` from the package root has no provider to read and stays Thai unless you pass `locale` (until 5.0); the one in `@jirawatpyk/aura-react/server` defaults to English and Gregorian. Values are always Gregorian ISO dates.
|
|
87
104
|
|
|
88
105
|
## Compact density
|
|
89
106
|
|
|
@@ -121,9 +138,30 @@ toast.error('Could not save'); // danger = role="alert"; the rest
|
|
|
121
138
|
<Command open={open} onOpenChange={setOpen} items={commands} /> {/* ⌘K / Ctrl+K toggles it */}
|
|
122
139
|
```
|
|
123
140
|
|
|
141
|
+
Server search in the palette (4.17): control the query and hand over what the server found. The active item is kept by id while results change, and `loading` announces "Searching…" and then the count.
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
<Command
|
|
145
|
+
open={open}
|
|
146
|
+
onOpenChange={setOpen}
|
|
147
|
+
query={q}
|
|
148
|
+
onQueryChange={setQ} // fetch results for q (debounced)
|
|
149
|
+
items={results}
|
|
150
|
+
filter={false}
|
|
151
|
+
loading={isFetching}
|
|
152
|
+
empty={
|
|
153
|
+
<Button size="sm" icon="plus">
|
|
154
|
+
Create member
|
|
155
|
+
</Button>
|
|
156
|
+
}
|
|
157
|
+
/>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
DataTable with sort and page in the URL (4.17): `onStateChange={({ sort, page }) => router.push(…)}` reports a sort click once, as `{ sort, page: 1 }`, instead of `onSortChange` and then `onPageChange(1)`. That's one history entry and one server render.
|
|
161
|
+
|
|
124
162
|
## Phones and touch
|
|
125
163
|
|
|
126
|
-
Under 640px every text control uses 16px text (iOS Safari doesn't zoom). On touch screens (`pointer: coarse`) IconButton
|
|
164
|
+
Under 640px every text control uses 16px text (iOS Safari doesn't zoom). On touch screens (`pointer: coarse`) IconButton and `<Button size="sm">` keep their 32px look with a 44px hit area, and Radio, Checkbox and Switch rows are at least 44px with the whole row as the target. Since 4.17 so are menu items, page numbers, segments and calendar days (44px); Combobox and DatePicker toggles and the Tag remove button get 44px hit areas. A Dialog sheet on a phone is capped at `92dvh`, so the browser toolbar never hides its footer. `<Button fullWidth>` fills its row and wraps long Thai or Swedish labels.
|
|
127
165
|
|
|
128
166
|
## Light and dark
|
|
129
167
|
|
|
@@ -159,6 +197,39 @@ Values are ISO strings (`2026-09-18`); with `locale="th"` display is Thai with B
|
|
|
159
197
|
|
|
160
198
|
Portals (Dialog, Drawer, menus, pickers, toasts) wait until after hydration; `useBreakpoint()` returns `lg` on the server and corrects on the client through `useSyncExternalStore`, so there are no hydration mismatches. `npm run test:ssr` renders every component with `react-dom/server` (ESM and CJS builds).
|
|
161
199
|
|
|
200
|
+
Layout is right before hydration (4.16). AppShell's sidebar-or-drawer switch is CSS (a 1024px media query), so a phone gets the menu button from the server's HTML. A DataTable with `stackBelow` renders cards and grid together until it has measured itself, and a container query shows the right one. It supports `stackBelow` 360, 400, 480, 520, 560, 600, 640, 720, 768, 800, 900, 960 and 1024; other widths stack once JavaScript runs. `npm run test:layout` loads both at 390 and 1280px with JavaScript off, then hydrated, and requires CLS 0. Columns with `hideBelow` still settle after hydration.
|
|
201
|
+
|
|
202
|
+
## Next to another Tailwind theme (shadcn), page by page
|
|
203
|
+
|
|
204
|
+
`styles.css` is unlayered, so it beats utilities. For a migration next to an existing theme, use the layered stylesheet and the prefixed Tailwind theme (4.17):
|
|
205
|
+
|
|
206
|
+
```css
|
|
207
|
+
@layer aura-tokens, theme, base, aura, components, utilities;
|
|
208
|
+
@import 'tailwindcss';
|
|
209
|
+
@import '@jirawatpyk/aura-tokens/aura.css' layer(aura-tokens); /* your theme wins for --font-sans / --font-mono */
|
|
210
|
+
@import '@jirawatpyk/aura-tokens/tailwind.prefixed.css'; /* bg-aura-bg-surface, font-aura-sans … no @custom-variant */
|
|
211
|
+
@import '@jirawatpyk/aura-react/styles.layer.css'; /* components in @layer aura: a utility className wins */
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Nothing an existing page uses is redefined: `npm run check:tailwind4` compiles a shadcn-style page alone and next to this setup, with AURA imported first and last. It checks that the computed styles are identical, and that `rounded-none` overrides `.aura-btn` with no `!important`. While both run, AURA components use your `--font-sans` / `--font-mono`; set them to AURA's stacks in your token bridge when a page moves over.
|
|
215
|
+
|
|
216
|
+
## Server Components
|
|
217
|
+
|
|
218
|
+
Everything in the package root is a client module (`'use client'`), so a Server Component can render AURA components but can't call AURA functions. The pure helpers have their own entry with no `'use client'` and no React (4.17):
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
// app/invoices/[id]/page.tsx — a Server Component
|
|
222
|
+
import { formatDate, createTheme, statusTone, STRINGS } from '@jirawatpyk/aura-react/server';
|
|
223
|
+
formatDate('2026-09-24'); // "24 Sept 2026" — English and Gregorian by default
|
|
224
|
+
formatDate('2026-09-24', { locale: 'th' }); // "24 ก.ย. 2569"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
It exports `formatDate`, `parseDate`, `toISO`, `fromISO`, `parseTime`, `formatBytes`, `statusTone`, `STRINGS`, `createTheme`, `contrast`, `brandScale`, `colorSchemeScript` and `breakpoints`. `npm run test:ssr` loads it under Node's `react-server` condition, and the Next.js starter formats a date with it in a Server Component.
|
|
228
|
+
|
|
229
|
+
## TypeScript
|
|
230
|
+
|
|
231
|
+
Every optional prop takes `undefined` (4.16), so apps on `exactOptionalPropertyTypes` can write `hint={t.hint}` or `icon={x ?? undefined}`. `types-test/exact-optional.tsx` checks every exported component against the published declarations under `strict`, `exactOptionalPropertyTypes` and `noUncheckedIndexedAccess`.
|
|
232
|
+
|
|
162
233
|
## Scripts
|
|
163
234
|
|
|
164
235
|
```bash
|