@jirawatpyk/aura-react 4.12.0 → 4.14.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 +48 -16
- package/dist/aura.bundle.js +966 -437
- package/dist/cjs/index.cjs +965 -436
- package/dist/esm/Command.js +215 -0
- package/dist/esm/DataTable.js +11 -1
- package/dist/esm/Dialog.js +5 -3
- package/dist/esm/FilterBar.js +112 -0
- package/dist/esm/FormErrorSummary.js +76 -0
- package/dist/esm/PasswordField.js +38 -0
- package/dist/esm/Popover.js +3 -1
- package/dist/esm/Toaster.js +60 -14
- package/dist/esm/index.js +10 -1
- package/dist/esm/locale.js +50 -3
- package/dist/index.d.ts +119 -1
- package/dist/styles.css +124 -8
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -16,6 +16,10 @@ import { Combobox, defaultFilter } from "./Combobox.js";
|
|
|
16
16
|
import { DatePicker, DateRangePicker, Calendar, formatDate, parseDate, useFormatDate } from "./DatePicker.js";
|
|
17
17
|
import { Alert } from "./Alert.js";
|
|
18
18
|
import { Toaster, toast } from "./Toaster.js";
|
|
19
|
+
import { PasswordField } from "./PasswordField.js";
|
|
20
|
+
import { FormErrorSummary } from "./FormErrorSummary.js";
|
|
21
|
+
import { FilterBar } from "./FilterBar.js";
|
|
22
|
+
import { Command } from "./Command.js";
|
|
19
23
|
import { Tooltip } from "./Tooltip.js";
|
|
20
24
|
import { Dialog, Drawer } from "./Dialog.js";
|
|
21
25
|
import { DataTable } from "./DataTable.js";
|
|
@@ -30,7 +34,7 @@ import { Container } from "./Container.js";
|
|
|
30
34
|
import { AppShell } from "./AppShell.js";
|
|
31
35
|
import { useBreakpoint, useResponsive, breakpoints } from "./responsive.js";
|
|
32
36
|
import { Surface } from "./Surface.js";
|
|
33
|
-
import { AuraProvider, useAuraLocale, STRINGS } from "./locale.js";
|
|
37
|
+
import { AuraProvider, useAuraLocale, useDensity, STRINGS } from "./locale.js";
|
|
34
38
|
import { Stat } from "./Stat.js";
|
|
35
39
|
import { TimePicker, parseTime } from "./TimePicker.js";
|
|
36
40
|
import { FileUpload, formatBytes } from "./FileUpload.js";
|
|
@@ -63,6 +67,7 @@ export {
|
|
|
63
67
|
ColorSchemeScript,
|
|
64
68
|
ColorSchemeToggle,
|
|
65
69
|
Combobox,
|
|
70
|
+
Command,
|
|
66
71
|
Container,
|
|
67
72
|
DataTable,
|
|
68
73
|
DatePicker,
|
|
@@ -73,6 +78,8 @@ export {
|
|
|
73
78
|
EmptyState,
|
|
74
79
|
Field,
|
|
75
80
|
FileUpload,
|
|
81
|
+
FilterBar,
|
|
82
|
+
FormErrorSummary,
|
|
76
83
|
Grid,
|
|
77
84
|
ICONS,
|
|
78
85
|
Icon,
|
|
@@ -80,6 +87,7 @@ export {
|
|
|
80
87
|
Menu,
|
|
81
88
|
NumberField,
|
|
82
89
|
Pagination,
|
|
90
|
+
PasswordField,
|
|
83
91
|
Popover,
|
|
84
92
|
Progress,
|
|
85
93
|
RadioGroup,
|
|
@@ -118,6 +126,7 @@ export {
|
|
|
118
126
|
useAuraLocale,
|
|
119
127
|
useBreakpoint,
|
|
120
128
|
useColorScheme,
|
|
129
|
+
useDensity,
|
|
121
130
|
useFormatDate,
|
|
122
131
|
useResponsive
|
|
123
132
|
};
|
package/dist/esm/locale.js
CHANGED
|
@@ -11,6 +11,19 @@ const STRINGS = {
|
|
|
11
11
|
close: "Close",
|
|
12
12
|
dismiss: "Dismiss",
|
|
13
13
|
dismissToast: "Dismiss notification",
|
|
14
|
+
showPassword: "Show password",
|
|
15
|
+
filters: "Filters",
|
|
16
|
+
search: "Search",
|
|
17
|
+
clearFilters: "Clear all",
|
|
18
|
+
results: function(n2) {
|
|
19
|
+
return n2 === 1 ? "1 result" : n2.toLocaleString("en") + " results";
|
|
20
|
+
},
|
|
21
|
+
commandMenu: "Command menu",
|
|
22
|
+
commandPlaceholder: "Type a command or search\u2026",
|
|
23
|
+
commandHint: "\u2191\u2193 to move \xB7 Enter to open \xB7 Esc to close",
|
|
24
|
+
errorSummary: function(n2) {
|
|
25
|
+
return n2 === 1 ? "Fix 1 field to continue" : "Fix " + n2 + " fields to continue";
|
|
26
|
+
},
|
|
14
27
|
notifications: "Notifications",
|
|
15
28
|
mainNav: "Main",
|
|
16
29
|
breadcrumb: "Breadcrumb",
|
|
@@ -109,6 +122,19 @@ const STRINGS = {
|
|
|
109
122
|
close: "\u0E1B\u0E34\u0E14",
|
|
110
123
|
dismiss: "\u0E1B\u0E34\u0E14",
|
|
111
124
|
dismissToast: "\u0E1B\u0E34\u0E14\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19",
|
|
125
|
+
showPassword: "\u0E41\u0E2A\u0E14\u0E07\u0E23\u0E2B\u0E31\u0E2A\u0E1C\u0E48\u0E32\u0E19",
|
|
126
|
+
filters: "\u0E15\u0E31\u0E27\u0E01\u0E23\u0E2D\u0E07",
|
|
127
|
+
search: "\u0E04\u0E49\u0E19\u0E2B\u0E32",
|
|
128
|
+
clearFilters: "\u0E25\u0E49\u0E32\u0E07\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
|
|
129
|
+
results: function(n2) {
|
|
130
|
+
return n2.toLocaleString("en") + " \u0E23\u0E32\u0E22\u0E01\u0E32\u0E23";
|
|
131
|
+
},
|
|
132
|
+
commandMenu: "\u0E40\u0E21\u0E19\u0E39\u0E04\u0E33\u0E2A\u0E31\u0E48\u0E07",
|
|
133
|
+
commandPlaceholder: "\u0E1E\u0E34\u0E21\u0E1E\u0E4C\u0E04\u0E33\u0E2A\u0E31\u0E48\u0E07\u0E2B\u0E23\u0E37\u0E2D\u0E04\u0E49\u0E19\u0E2B\u0E32\u2026",
|
|
134
|
+
commandHint: "\u2191\u2193 \u0E40\u0E25\u0E37\u0E48\u0E2D\u0E19 \xB7 Enter \u0E40\u0E1B\u0E34\u0E14 \xB7 Esc \u0E1B\u0E34\u0E14",
|
|
135
|
+
errorSummary: function(n2) {
|
|
136
|
+
return "\u0E41\u0E01\u0E49\u0E44\u0E02 " + n2 + " \u0E0A\u0E48\u0E2D\u0E07\u0E01\u0E48\u0E2D\u0E19\u0E44\u0E1B\u0E15\u0E48\u0E2D";
|
|
137
|
+
},
|
|
112
138
|
notifications: "\u0E01\u0E32\u0E23\u0E41\u0E08\u0E49\u0E07\u0E40\u0E15\u0E37\u0E2D\u0E19",
|
|
113
139
|
mainNav: "\u0E40\u0E21\u0E19\u0E39\u0E2B\u0E25\u0E31\u0E01",
|
|
114
140
|
breadcrumb: "\u0E40\u0E2A\u0E49\u0E19\u0E17\u0E32\u0E07",
|
|
@@ -207,6 +233,19 @@ const STRINGS = {
|
|
|
207
233
|
close: "St\xE4ng",
|
|
208
234
|
dismiss: "St\xE4ng",
|
|
209
235
|
dismissToast: "St\xE4ng aviseringen",
|
|
236
|
+
showPassword: "Visa l\xF6senord",
|
|
237
|
+
filters: "Filter",
|
|
238
|
+
search: "S\xF6k",
|
|
239
|
+
clearFilters: "Rensa alla",
|
|
240
|
+
results: function(n2) {
|
|
241
|
+
return n2 === 1 ? "1 tr\xE4ff" : n2.toLocaleString("sv-SE") + " tr\xE4ffar";
|
|
242
|
+
},
|
|
243
|
+
commandMenu: "Kommandomeny",
|
|
244
|
+
commandPlaceholder: "Skriv ett kommando eller s\xF6k\u2026",
|
|
245
|
+
commandHint: "\u2191\u2193 flytta \xB7 Enter \xF6ppna \xB7 Esc st\xE4ng",
|
|
246
|
+
errorSummary: function(n2) {
|
|
247
|
+
return n2 === 1 ? "R\xE4tta 1 f\xE4lt f\xF6r att forts\xE4tta" : "R\xE4tta " + n2 + " f\xE4lt f\xF6r att forts\xE4tta";
|
|
248
|
+
},
|
|
210
249
|
notifications: "Aviseringar",
|
|
211
250
|
mainNav: "Huvudmeny",
|
|
212
251
|
breadcrumb: "Br\xF6dsmulor",
|
|
@@ -304,6 +343,8 @@ const STRINGS = {
|
|
|
304
343
|
};
|
|
305
344
|
const LocaleContext = React.createContext(null);
|
|
306
345
|
function AuraProvider(props) {
|
|
346
|
+
const outer = React.useContext(LocaleContext);
|
|
347
|
+
const density = props.density || outer && outer.density || null;
|
|
307
348
|
const value = React.useMemo(
|
|
308
349
|
function() {
|
|
309
350
|
const base = props.locale && STRINGS[props.locale] || STRINGS.en;
|
|
@@ -311,12 +352,13 @@ function AuraProvider(props) {
|
|
|
311
352
|
locale: props.locale || "en",
|
|
312
353
|
calendar: props.calendar || null,
|
|
313
354
|
strings: props.strings ? Object.assign({}, base, props.strings) : base,
|
|
314
|
-
linkComponent: props.linkComponent || null
|
|
355
|
+
linkComponent: props.linkComponent || null,
|
|
356
|
+
density
|
|
315
357
|
};
|
|
316
358
|
},
|
|
317
|
-
[props.locale, props.calendar, props.strings, props.linkComponent]
|
|
359
|
+
[props.locale, props.calendar, props.strings, props.linkComponent, density]
|
|
318
360
|
);
|
|
319
|
-
return /* @__PURE__ */ React.createElement(LocaleContext.Provider, { value }, props.children);
|
|
361
|
+
return /* @__PURE__ */ React.createElement(LocaleContext.Provider, { value }, props.density ? /* @__PURE__ */ React.createElement("div", { className: "aura-density", "data-density": props.density }, props.children) : props.children);
|
|
320
362
|
}
|
|
321
363
|
function useAuraLocale() {
|
|
322
364
|
return React.useContext(LocaleContext) || { locale: null, calendar: null, strings: STRINGS.en };
|
|
@@ -325,6 +367,10 @@ function useLinkComponent(own) {
|
|
|
325
367
|
const ctx = React.useContext(LocaleContext);
|
|
326
368
|
return own || ctx && ctx.linkComponent || "a";
|
|
327
369
|
}
|
|
370
|
+
function useDensity() {
|
|
371
|
+
const ctx = React.useContext(LocaleContext);
|
|
372
|
+
return ctx && ctx.density || void 0;
|
|
373
|
+
}
|
|
328
374
|
function useStrings() {
|
|
329
375
|
return useAuraLocale().strings;
|
|
330
376
|
}
|
|
@@ -332,6 +378,7 @@ export {
|
|
|
332
378
|
AuraProvider,
|
|
333
379
|
STRINGS,
|
|
334
380
|
useAuraLocale,
|
|
381
|
+
useDensity,
|
|
335
382
|
useLinkComponent,
|
|
336
383
|
useStrings
|
|
337
384
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -149,6 +149,8 @@ export interface DataTableProps {
|
|
|
149
149
|
/** Controlled pinned columns (keys); pair with onPinnedColumnsChange. */
|
|
150
150
|
pinnedColumns?: string[];
|
|
151
151
|
onPinnedColumnsChange?: (keys: string[]) => void;
|
|
152
|
+
/** `compact` = 40px rows (48px on touch screens). Default: the surrounding density. */
|
|
153
|
+
density?: "comfortable" | "compact";
|
|
152
154
|
/** Container width in px below which rows render as stacked cards (phones). Try 640. Measured with ResizeObserver, so it follows the container, not the window. */
|
|
153
155
|
stackBelow?: number;
|
|
154
156
|
className?: string;
|
|
@@ -184,6 +186,8 @@ export interface AuraProviderProps {
|
|
|
184
186
|
calendar?: "buddhist" | "gregory";
|
|
185
187
|
/** Override individual strings. */
|
|
186
188
|
strings?: Partial<Record<string, string | ((...args: any[]) => string)>>;
|
|
189
|
+
/** `compact`: 36px fields and buttons, 40px table rows — dense admin screens. Touch screens keep 44px. Default: comfortable (or an ancestor's `data-density`). */
|
|
190
|
+
density?: "comfortable" | "compact";
|
|
187
191
|
/** Your router's link (e.g. `Link` from `next/link`), used by every AURA component that renders a link: Button with `href`, SideNav, Breadcrumb, Stat, Pagination, DataTable row links. It gets `href`, `className`, `aria-current`, the children and the ref. A component's own `linkComponent` wins. */
|
|
188
192
|
linkComponent?: React$1.ElementType;
|
|
189
193
|
children?: React$1.ReactNode;
|
|
@@ -268,6 +272,96 @@ export interface TextFieldProps extends FieldProps, Omit<React$1.InputHTMLAttrib
|
|
|
268
272
|
/** Trailing unit, e.g. "THB". */
|
|
269
273
|
suffix?: React$1.ReactNode;
|
|
270
274
|
}
|
|
275
|
+
/** A password input with a show/hide button. All TextField props; `ref` reaches the input (react-hook-form `register`). */
|
|
276
|
+
export interface PasswordFieldProps extends Omit<TextFieldProps, "type" | "suffix"> {
|
|
277
|
+
/** Set false to hide the show/hide button. Default true. */
|
|
278
|
+
toggle?: boolean;
|
|
279
|
+
}
|
|
280
|
+
/** One entry of a FormErrorSummary: the field's `id` (or `name`) and what to fix. */
|
|
281
|
+
export interface FormErrorItem {
|
|
282
|
+
field: string;
|
|
283
|
+
message: React$1.ReactNode;
|
|
284
|
+
}
|
|
285
|
+
/** The list of problems at the top of a form after a failed submit; each links to its field (GOV.UK pattern). */
|
|
286
|
+
export interface FormErrorSummaryProps {
|
|
287
|
+
/** A list, or react-hook-form's `formState.errors` as is (`{ name: { message } }`). Empty → renders nothing. */
|
|
288
|
+
errors: FormErrorItem[] | Record<string, {
|
|
289
|
+
message?: React$1.ReactNode;
|
|
290
|
+
} | undefined>;
|
|
291
|
+
/** Default "Fix N fields to continue" in the provider's language. */
|
|
292
|
+
title?: React$1.ReactNode;
|
|
293
|
+
/** Called with the field when a link is followed, e.g. react-hook-form's `setFocus`. Default: focus the element whose id (or name) is the field. */
|
|
294
|
+
onSelect?: (field: string) => void;
|
|
295
|
+
/** Change it on every submit (e.g. `formState.submitCount`) to move focus to the summary again. It also takes focus when errors first appear. */
|
|
296
|
+
focusKey?: unknown;
|
|
297
|
+
className?: string;
|
|
298
|
+
id?: string;
|
|
299
|
+
}
|
|
300
|
+
/** An applied filter, shown as a removable chip. */
|
|
301
|
+
export interface ActiveFilter {
|
|
302
|
+
id: string;
|
|
303
|
+
label: React$1.ReactNode;
|
|
304
|
+
onRemove: () => void;
|
|
305
|
+
}
|
|
306
|
+
/** The row above a table: search, filter controls, applied-filter chips, result count and actions. Wraps below md. */
|
|
307
|
+
export interface FilterBarProps {
|
|
308
|
+
/** Search text (controlled). Omit `onSearchChange` to hide the search field. */
|
|
309
|
+
search?: string;
|
|
310
|
+
/** Called after typing pauses (`searchDelay`), and at once on Enter or clear — ready to write to the URL. */
|
|
311
|
+
onSearchChange?: (value: string) => void;
|
|
312
|
+
/** ms to wait after the last keystroke. Default 300. */
|
|
313
|
+
searchDelay?: number;
|
|
314
|
+
searchLabel?: string;
|
|
315
|
+
searchPlaceholder?: string;
|
|
316
|
+
/** Filter controls beside the search: Select, SegmentedControl, a Popover of options… */
|
|
317
|
+
children?: React$1.ReactNode;
|
|
318
|
+
/** Applied filters as chips, each with its own remove button. */
|
|
319
|
+
filters?: ActiveFilter[];
|
|
320
|
+
/** Adds "Clear all" while any filter or search is set. */
|
|
321
|
+
onClearAll?: () => void;
|
|
322
|
+
/** A number ("312 results", announced politely) or your own node. */
|
|
323
|
+
resultCount?: number | React$1.ReactNode;
|
|
324
|
+
/** Trailing slot: export, a New button… */
|
|
325
|
+
actions?: React$1.ReactNode;
|
|
326
|
+
/** Accessible name of the region. Default "Filters". */
|
|
327
|
+
label?: string;
|
|
328
|
+
className?: string;
|
|
329
|
+
}
|
|
330
|
+
/** One command in the palette. */
|
|
331
|
+
export interface CommandItem {
|
|
332
|
+
id: string;
|
|
333
|
+
/** Text shown and searched. */
|
|
334
|
+
label: string;
|
|
335
|
+
/** Items with the same group are listed together under its heading, in first-seen order. */
|
|
336
|
+
group?: string;
|
|
337
|
+
icon?: IconInput;
|
|
338
|
+
description?: string;
|
|
339
|
+
/** Extra words that find it ("invoice" → Billing). */
|
|
340
|
+
keywords?: string[];
|
|
341
|
+
/** A shortcut shown at the right, e.g. "G I". Display only. */
|
|
342
|
+
shortcut?: string;
|
|
343
|
+
disabled?: boolean;
|
|
344
|
+
/** Runs when chosen (Enter or click); the palette then closes. */
|
|
345
|
+
onSelect?: () => void;
|
|
346
|
+
}
|
|
347
|
+
/** A command palette: a modal search over commands and pages, grouped, fully keyboard-driven. */
|
|
348
|
+
export interface CommandProps {
|
|
349
|
+
open: boolean;
|
|
350
|
+
onOpenChange: (open: boolean) => void;
|
|
351
|
+
items: CommandItem[];
|
|
352
|
+
/** Also called with the chosen item (after its own onSelect). */
|
|
353
|
+
onSelect?: (item: CommandItem) => void;
|
|
354
|
+
/** Accessible name. Default "Command menu". */
|
|
355
|
+
label?: string;
|
|
356
|
+
placeholder?: string;
|
|
357
|
+
/** Default "No matches". */
|
|
358
|
+
emptyText?: string;
|
|
359
|
+
/** ⌘K / Ctrl+K toggles the palette from anywhere on the page. Default true. */
|
|
360
|
+
hotkey?: boolean;
|
|
361
|
+
/** Replace the Thai-aware default filter. */
|
|
362
|
+
filter?: (item: CommandItem, query: string) => boolean;
|
|
363
|
+
className?: string;
|
|
364
|
+
}
|
|
271
365
|
export interface TextareaProps extends FieldProps, Omit<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, "required"> {
|
|
272
366
|
}
|
|
273
367
|
export type SelectOption = string | {
|
|
@@ -332,9 +426,11 @@ export interface ToastOptions {
|
|
|
332
426
|
};
|
|
333
427
|
/** ms before it closes itself. Default 5000; Infinity keeps it until dismissed. */
|
|
334
428
|
duration?: number;
|
|
335
|
-
/** Reuse an id to replace a toast in place. */
|
|
429
|
+
/** Reuse an id to replace a toast in place (same position, timer restarts) — never a second toast. */
|
|
336
430
|
id?: string;
|
|
337
431
|
}
|
|
432
|
+
/** Options for the shorthands (`toast.success(title, opts)` …): everything but the title and tone. */
|
|
433
|
+
export type ToastShorthandOptions = Omit<ToastOptions, "title" | "tone">;
|
|
338
434
|
export interface TooltipProps {
|
|
339
435
|
content: React$1.ReactNode;
|
|
340
436
|
/** One focusable element. */
|
|
@@ -979,6 +1075,11 @@ export declare const Alert: React$1.ForwardRefExoticComponent<AlertProps & React
|
|
|
979
1075
|
/** Show a toast; returns its id. Needs `<Toaster />` mounted once. */
|
|
980
1076
|
export declare function toast(opts: ToastOptions | string): string;
|
|
981
1077
|
export declare namespace toast {
|
|
1078
|
+
var success: (title: string, opts?: ToastShorthandOptions) => string;
|
|
1079
|
+
var error: (title: string, opts?: ToastShorthandOptions) => string;
|
|
1080
|
+
var warning: (title: string, opts?: ToastShorthandOptions) => string;
|
|
1081
|
+
var info: (title: string, opts?: ToastShorthandOptions) => string;
|
|
1082
|
+
var loading: (title: string, opts?: ToastShorthandOptions) => string;
|
|
982
1083
|
var dismiss: (id: string) => void;
|
|
983
1084
|
}
|
|
984
1085
|
export interface ToasterProps {
|
|
@@ -986,6 +1087,10 @@ export interface ToasterProps {
|
|
|
986
1087
|
position?: "bottom" | "top";
|
|
987
1088
|
}
|
|
988
1089
|
export declare function Toaster(props: ToasterProps): React$1.ReactElement | null;
|
|
1090
|
+
export declare const PasswordField: React$1.ForwardRefExoticComponent<PasswordFieldProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
1091
|
+
export declare const FormErrorSummary: React$1.ForwardRefExoticComponent<FormErrorSummaryProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1092
|
+
export declare const FilterBar: React$1.ForwardRefExoticComponent<FilterBarProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1093
|
+
export declare function Command(props: CommandProps): React$1.ReactElement | null;
|
|
989
1094
|
export declare const Tooltip: React$1.ForwardRefExoticComponent<TooltipProps & React$1.RefAttributes<HTMLSpanElement>>;
|
|
990
1095
|
export declare const Dialog: React$1.ForwardRefExoticComponent<DialogProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
991
1096
|
/** Side panel over the page: record detail, filters, mobile navigation. Modal (focus trap, scroll lock, focus restore). */
|
|
@@ -1032,6 +1137,15 @@ export interface AuraStrings {
|
|
|
1032
1137
|
close: string;
|
|
1033
1138
|
dismiss: string;
|
|
1034
1139
|
dismissToast: string;
|
|
1140
|
+
showPassword: string;
|
|
1141
|
+
filters: string;
|
|
1142
|
+
search: string;
|
|
1143
|
+
clearFilters: string;
|
|
1144
|
+
results: (n: number) => string;
|
|
1145
|
+
commandMenu: string;
|
|
1146
|
+
commandPlaceholder: string;
|
|
1147
|
+
commandHint: string;
|
|
1148
|
+
errorSummary: (n: number) => string;
|
|
1035
1149
|
notifications: string;
|
|
1036
1150
|
mainNav: string;
|
|
1037
1151
|
breadcrumb: string;
|
|
@@ -1106,11 +1220,15 @@ export interface AuraLocaleValue {
|
|
|
1106
1220
|
strings: AuraStrings;
|
|
1107
1221
|
/** The router link set on AuraProvider, if any. */
|
|
1108
1222
|
linkComponent?: React$1.ElementType | null;
|
|
1223
|
+
/** The density set on the nearest AuraProvider that sets one (null: none, i.e. comfortable unless an ancestor's data-density says otherwise). */
|
|
1224
|
+
density?: "comfortable" | "compact" | null;
|
|
1109
1225
|
}
|
|
1110
1226
|
/** Sets the language of built-in labels (and the default date locale) for everything inside. */
|
|
1111
1227
|
export declare function AuraProvider(props: AuraProviderProps): React$1.ReactElement;
|
|
1112
1228
|
/** { locale, calendar, strings } from the nearest AuraProvider (English strings when there is none). */
|
|
1113
1229
|
export declare function useAuraLocale(): AuraLocaleValue;
|
|
1230
|
+
/** The provider's density, for portals that render outside its wrapper. */
|
|
1231
|
+
export declare function useDensity(): "comfortable" | "compact" | undefined;
|
|
1114
1232
|
export declare const Stat: React$1.ForwardRefExoticComponent<StatProps & React$1.RefAttributes<HTMLElement>>;
|
|
1115
1233
|
/** Parse typed time: 9 · 09 · 930 · 0930 · 9:30 · 9.30 · 09.30 น. · 9:30 pm → "HH:mm" (24-hour) or null. */
|
|
1116
1234
|
export declare function parseTime(text: string | null | undefined): string | null;
|
package/dist/styles.css
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
box-sizing: border-box;
|
|
8
8
|
height: var(--aura-button-height);
|
|
9
9
|
white-space: nowrap; flex-shrink: 0; /* a pill never wraps its label */
|
|
10
|
-
padding: 0 var(--aura-space-6);
|
|
10
|
+
padding: 0 var(--aura-button-padding-x, var(--aura-space-6));
|
|
11
11
|
border-radius: var(--aura-button-radius);
|
|
12
12
|
border: 0;
|
|
13
13
|
background: transparent;
|
|
@@ -74,14 +74,14 @@ a.aura-btn { text-decoration: none; }
|
|
|
74
74
|
}
|
|
75
75
|
.aura-table__scroll { position: relative; overflow: auto; overscroll-behavior: contain; }
|
|
76
76
|
.aura-table__head {
|
|
77
|
-
position: sticky; top: 0; z-index: 3;
|
|
78
|
-
display: flex; height: var(--aura-
|
|
77
|
+
position: sticky; top: 0; z-index: 3; box-sizing: border-box; /* the hairline is inside the row height */
|
|
78
|
+
display: flex; height: var(--aura-table-row-height);
|
|
79
79
|
background: var(--aura-bg-canvas);
|
|
80
80
|
border-bottom: 1px solid var(--aura-border-default);
|
|
81
81
|
font-family: var(--font-mono); font-size: 12px; color: var(--aura-fg-secondary);
|
|
82
82
|
}
|
|
83
83
|
.aura-table__row {
|
|
84
|
-
display: flex; height: var(--aura-
|
|
84
|
+
box-sizing: border-box; display: flex; height: var(--aura-table-row-height); /* exactly the virtual row height */
|
|
85
85
|
background: var(--aura-bg-surface);
|
|
86
86
|
border-bottom: 1px solid var(--aura-border-default);
|
|
87
87
|
font-size: 13px;
|
|
@@ -105,7 +105,7 @@ a.aura-btn { text-decoration: none; }
|
|
|
105
105
|
/* Server mode refresh: the previous page stays, inactive, under a progress bar until the next one arrives */
|
|
106
106
|
.aura-table.is-refreshing .aura-table__row, .aura-table.is-refreshing .aura-table__card { opacity: 0.6; pointer-events: none; }
|
|
107
107
|
.aura-table__busy-bar {
|
|
108
|
-
position: absolute; z-index: 6; top: calc(var(--aura-
|
|
108
|
+
position: absolute; z-index: 6; top: calc(var(--aura-table-row-height) - 2px); left: 0; right: 0; height: 2px; overflow: hidden;
|
|
109
109
|
border-radius: var(--aura-radius-full); pointer-events: none;
|
|
110
110
|
}
|
|
111
111
|
.aura-table--stacked .aura-table__busy-bar { top: 0; }
|
|
@@ -117,7 +117,7 @@ a.aura-btn { text-decoration: none; }
|
|
|
117
117
|
|
|
118
118
|
/* Cells: text cells stay block so long values end in an ellipsis */
|
|
119
119
|
.aura-table__td {
|
|
120
|
-
box-sizing: border-box; height: 100%; line-height: calc(var(--aura-
|
|
120
|
+
box-sizing: border-box; height: 100%; line-height: calc(var(--aura-table-row-height) - 1px);
|
|
121
121
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: var(--aura-space-4);
|
|
122
122
|
}
|
|
123
123
|
.aura-table__td .aura-pill, .aura-table__td .aura-dropdown, .aura-table__td > .aura-icon-btn, .aura-table__td > .aura-btn { vertical-align: middle; }
|
|
@@ -130,7 +130,7 @@ a.aura-btn { text-decoration: none; }
|
|
|
130
130
|
.aura-table__gutter { flex: none; width: var(--aura-space-6); position: sticky; left: 0; z-index: 2; background: inherit; }
|
|
131
131
|
.aura-table__gutter--end { position: static; }
|
|
132
132
|
.aura-table__picker {
|
|
133
|
-
position: absolute; top: 0; right: 0; z-index: 5; width: var(--aura-space-12); height: calc(var(--aura-
|
|
133
|
+
position: absolute; top: 0; right: 0; z-index: 5; width: var(--aura-space-12); height: calc(var(--aura-table-row-height) - 1px);
|
|
134
134
|
display: flex; align-items: center; justify-content: center; background: var(--aura-bg-canvas); border-top-right-radius: calc(var(--aura-card-radius) - 1px);
|
|
135
135
|
}
|
|
136
136
|
.aura-table__gutter--end.has-picker {
|
|
@@ -228,7 +228,7 @@ a.aura-btn { text-decoration: none; }
|
|
|
228
228
|
|
|
229
229
|
/* Footer + pager */
|
|
230
230
|
.aura-table__foot {
|
|
231
|
-
height: var(--aura-
|
|
231
|
+
height: var(--aura-table-row-height); display: flex; align-items: center; justify-content: space-between;
|
|
232
232
|
padding: 0 var(--aura-space-3) 0 var(--aura-space-6);
|
|
233
233
|
border-top: 1px solid var(--aura-border-default); background: var(--aura-bg-surface);
|
|
234
234
|
font-size: 13px; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums;
|
|
@@ -1141,3 +1141,119 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1141
1141
|
.aura-radio-group__list { gap: 0; }
|
|
1142
1142
|
.aura-radio-group__list.is-horizontal { gap: 0 var(--aura-space-6); }
|
|
1143
1143
|
}
|
|
1144
|
+
|
|
1145
|
+
/* PasswordField: the show/hide IconButton sits in the suffix slot, 6px from the edge */
|
|
1146
|
+
.aura-password .aura-input__suffix { padding-right: 6px; display: flex; align-items: center; }
|
|
1147
|
+
|
|
1148
|
+
/* FormErrorSummary: a danger alert whose items link to their fields */
|
|
1149
|
+
.aura-error-summary:focus-visible, .aura-error-summary:focus { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
|
|
1150
|
+
.aura-error-summary h2.aura-alert__title { font-family: inherit; }
|
|
1151
|
+
.aura-error-summary__list { margin: var(--aura-space-2) 0 0; padding-left: var(--aura-space-5); display: grid; gap: var(--aura-space-1); font-size: 14px; line-height: 20px; }
|
|
1152
|
+
.aura-error-summary__list a { color: var(--aura-alert-danger-fg); text-decoration: underline; text-underline-offset: 2px; font-weight: 500; }
|
|
1153
|
+
.aura-error-summary__list a:hover { text-decoration-thickness: 2px; }
|
|
1154
|
+
.aura-error-summary__list a:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 2px; border-radius: var(--aura-radius-xs); }
|
|
1155
|
+
|
|
1156
|
+
/* aura-prose: sanitised rich text (editor output, e-mail previews). Styles exactly p, h1–h4, ul/ol/li, blockquote,
|
|
1157
|
+
* hr, a, strong, em, u with AURA type and spacing, in both themes. */
|
|
1158
|
+
.aura-prose { font-family: var(--font-sans); font-size: 14px; line-height: 1.7; color: var(--aura-fg-primary); overflow-wrap: anywhere; }
|
|
1159
|
+
.aura-prose > :first-child { margin-top: 0; }
|
|
1160
|
+
.aura-prose > :last-child { margin-bottom: 0; }
|
|
1161
|
+
.aura-prose p { margin: 0 0 var(--aura-space-4); }
|
|
1162
|
+
.aura-prose h1, .aura-prose h2, .aura-prose h3, .aura-prose h4 { color: var(--aura-fg-primary); margin: var(--aura-space-8) 0 var(--aura-space-3); }
|
|
1163
|
+
.aura-prose h1 { font-family: var(--font-display); font-weight: 600; font-size: 30px; line-height: 1.2; letter-spacing: -0.01em; }
|
|
1164
|
+
.aura-prose h2 { font-weight: 600; font-size: 22px; line-height: 1.3; }
|
|
1165
|
+
.aura-prose h3 { font-weight: 600; font-size: 17px; line-height: 1.45; }
|
|
1166
|
+
.aura-prose h4 { font-weight: 600; font-size: 15px; line-height: 1.5; }
|
|
1167
|
+
.aura-prose ul, .aura-prose ol { margin: 0 0 var(--aura-space-4); padding-left: var(--aura-space-6); }
|
|
1168
|
+
.aura-prose li { margin: var(--aura-space-1) 0; }
|
|
1169
|
+
.aura-prose li > ul, .aura-prose li > ol { margin: var(--aura-space-1) 0 0; }
|
|
1170
|
+
.aura-prose ul { list-style: disc; }
|
|
1171
|
+
.aura-prose ol { list-style: decimal; }
|
|
1172
|
+
.aura-prose li::marker { color: var(--aura-fg-secondary); }
|
|
1173
|
+
.aura-prose blockquote { margin: 0 0 var(--aura-space-4); padding: var(--aura-space-1) 0 var(--aura-space-1) var(--aura-space-4); border-left: 3px solid var(--aura-border-control); color: var(--aura-fg-secondary); }
|
|
1174
|
+
.aura-prose hr { margin: var(--aura-space-8) 0; border: 0; border-top: 1px solid var(--aura-border-default); }
|
|
1175
|
+
.aura-prose a { color: var(--aura-fg-accent); text-decoration: underline; text-underline-offset: 2px; }
|
|
1176
|
+
.aura-prose a:hover { text-decoration-thickness: 2px; }
|
|
1177
|
+
.aura-prose a:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: 2px; border-radius: var(--aura-radius-xs); }
|
|
1178
|
+
.aura-prose strong { font-weight: 600; }
|
|
1179
|
+
.aura-prose em { font-style: italic; }
|
|
1180
|
+
.aura-prose u { text-decoration: underline; text-underline-offset: 2px; }
|
|
1181
|
+
|
|
1182
|
+
/* FilterBar: search + controls + count + actions on one row, applied-filter chips below; wraps on small screens */
|
|
1183
|
+
.aura-filterbar { display: flex; flex-direction: column; gap: var(--aura-space-3); font-family: var(--font-sans); }
|
|
1184
|
+
.aura-filterbar__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-3); }
|
|
1185
|
+
.aura-filterbar__search { flex: 1 1 240px; max-width: 360px; width: auto; }
|
|
1186
|
+
.aura-filterbar__search .aura-input__control::-webkit-search-cancel-button { display: none; }
|
|
1187
|
+
.aura-filterbar__clear-search { margin-right: 6px; }
|
|
1188
|
+
.aura-filterbar__controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-3); }
|
|
1189
|
+
.aura-filterbar__spacer { flex: 1 1 0; }
|
|
1190
|
+
.aura-filterbar__count { font-size: 13px; color: var(--aura-fg-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
|
|
1191
|
+
.aura-filterbar__actions { display: flex; align-items: center; gap: var(--aura-space-2); }
|
|
1192
|
+
.aura-filterbar__chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-2); }
|
|
1193
|
+
.aura-filterbar__clear {
|
|
1194
|
+
border: 0; background: transparent; padding: 4px var(--aura-space-2); border-radius: var(--aura-radius-sm);
|
|
1195
|
+
font: inherit; font-size: 13px; font-weight: 500; color: var(--aura-fg-accent); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
|
|
1196
|
+
}
|
|
1197
|
+
.aura-filterbar__clear:hover { background: var(--aura-bg-surface-hover); }
|
|
1198
|
+
.aura-filterbar__clear:focus-visible { outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: var(--aura-focus-ring-offset); }
|
|
1199
|
+
@media (max-width: 767.98px) {
|
|
1200
|
+
.aura-filterbar__search { flex-basis: 100%; max-width: none; }
|
|
1201
|
+
.aura-filterbar__spacer { display: none; }
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
/* Command palette: a search field over a grouped list, above everything else (it can open from a Dialog) */
|
|
1205
|
+
.aura-dialog-layer.aura-command-layer { z-index: var(--aura-z-menu); align-items: flex-start; padding: 12vh var(--aura-space-4) var(--aura-space-4); }
|
|
1206
|
+
.aura-command {
|
|
1207
|
+
position: relative; box-sizing: border-box; width: 100%; max-width: 640px; max-height: 70vh; display: flex; flex-direction: column; overflow: hidden;
|
|
1208
|
+
background: var(--aura-bg-surface); color: var(--aura-fg-primary); font-family: var(--font-sans);
|
|
1209
|
+
border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-xl); box-shadow: var(--aura-shadow-overlay);
|
|
1210
|
+
animation: aura-dialog-in var(--aura-duration-base) var(--aura-ease);
|
|
1211
|
+
}
|
|
1212
|
+
.aura-command:focus { outline: none; }
|
|
1213
|
+
.aura-command__search { display: flex; align-items: center; gap: var(--aura-space-3); padding: 0 var(--aura-space-4); border-bottom: 1px solid var(--aura-border-default); }
|
|
1214
|
+
.aura-command__search-icon { color: var(--aura-fg-secondary); }
|
|
1215
|
+
.aura-command__input {
|
|
1216
|
+
flex: 1; min-width: 0; height: 52px; border: 0; background: transparent; color: inherit; outline: none;
|
|
1217
|
+
font: inherit; font-size: max(16px, var(--aura-input-font-size));
|
|
1218
|
+
}
|
|
1219
|
+
.aura-command__input::placeholder { color: var(--aura-fg-tertiary); opacity: 1; }
|
|
1220
|
+
.aura-command__list { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: var(--aura-space-2); }
|
|
1221
|
+
.aura-command__group + .aura-command__group { margin-top: var(--aura-space-2); }
|
|
1222
|
+
.aura-command__heading { padding: var(--aura-space-2) var(--aura-space-2) var(--aura-space-1); font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--aura-fg-secondary); }
|
|
1223
|
+
.aura-command__item { display: flex; align-items: center; gap: var(--aura-space-3); min-height: 40px; padding: 6px var(--aura-space-2); border-radius: var(--aura-radius-sm); cursor: pointer; font-size: 14px; }
|
|
1224
|
+
.aura-command__item > .aura-icon { color: var(--aura-fg-secondary); }
|
|
1225
|
+
.aura-command__item.is-active { background: var(--aura-bg-surface-hover); outline: var(--aura-focus-ring-width) solid var(--aura-focus-ring); outline-offset: calc(-1 * var(--aura-focus-ring-width)); }
|
|
1226
|
+
.aura-command__item.is-disabled { opacity: var(--aura-disabled-opacity); cursor: default; }
|
|
1227
|
+
.aura-command__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
1228
|
+
.aura-command__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1229
|
+
.aura-command__desc { font-size: 12px; line-height: 1.5; color: var(--aura-fg-secondary); }
|
|
1230
|
+
.aura-command__kbd {
|
|
1231
|
+
flex: none; padding: 2px 6px; border: 1px solid var(--aura-border-default); border-radius: var(--aura-radius-xs);
|
|
1232
|
+
font-family: var(--font-mono); font-size: 11px; line-height: 16px; color: var(--aura-fg-secondary); background: var(--aura-bg-canvas);
|
|
1233
|
+
}
|
|
1234
|
+
.aura-command__empty { margin: 0; padding: var(--aura-space-6) var(--aura-space-2); text-align: center; font-size: 14px; color: var(--aura-fg-secondary); }
|
|
1235
|
+
.aura-command__foot { display: flex; justify-content: space-between; gap: var(--aura-space-3); padding: var(--aura-space-2) var(--aura-space-4); border-top: 1px solid var(--aura-border-default); font-size: 12px; color: var(--aura-fg-secondary); }
|
|
1236
|
+
@media (max-width: 639.98px) {
|
|
1237
|
+
.aura-dialog-layer.aura-command-layer { align-items: flex-start; padding: var(--aura-space-4); }
|
|
1238
|
+
.aura-command { max-height: 80vh; }
|
|
1239
|
+
.aura-command__foot { display: none; }
|
|
1240
|
+
.aura-command__item { min-height: 44px; }
|
|
1241
|
+
}
|
|
1242
|
+
@media (prefers-reduced-motion: reduce) { .aura-command { animation: none; } }
|
|
1243
|
+
|
|
1244
|
+
/* Density. data-density="compact" on <html> or any container (AuraProvider density="compact" and DataTable
|
|
1245
|
+
* density do it for you): 36px fields and buttons, 40px table rows, less button padding — for dense admin screens.
|
|
1246
|
+
* Touch screens keep 44px targets whatever the density. "comfortable" inside compact switches back. */
|
|
1247
|
+
[data-density='compact'] {
|
|
1248
|
+
--aura-input-height: 36px; --aura-button-height: 36px; --aura-table-row-height: 40px;
|
|
1249
|
+
--aura-button-padding-x: var(--aura-space-4);
|
|
1250
|
+
}
|
|
1251
|
+
[data-density='comfortable'] {
|
|
1252
|
+
--aura-input-height: 44px; --aura-button-height: 44px; --aura-table-row-height: 48px;
|
|
1253
|
+
--aura-button-padding-x: var(--aura-space-6);
|
|
1254
|
+
}
|
|
1255
|
+
@media (pointer: coarse) {
|
|
1256
|
+
[data-density='compact'] { --aura-input-height: 44px; --aura-button-height: 44px; --aura-table-row-height: 48px; --aura-button-padding-x: var(--aura-space-6); }
|
|
1257
|
+
}
|
|
1258
|
+
.aura-density { display: contents; }
|
|
1259
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.0",
|
|
4
4
|
"description": "AURA Design System — React components (Enterprise Standard, Human Creative). Thai-first: Buddhist-era dates, Thai collation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|