@jirawatpyk/aura-react 4.13.0 → 4.15.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 +45 -16
- package/dist/aura.bundle.js +116 -16
- package/dist/cjs/index.cjs +116 -16
- package/dist/esm/AppShell.js +4 -1
- package/dist/esm/Command.js +3 -1
- package/dist/esm/DataTable.js +11 -1
- package/dist/esm/Dialog.js +5 -3
- package/dist/esm/Icon.js +1 -1
- package/dist/esm/Popover.js +3 -1
- package/dist/esm/SideNav.js +72 -4
- package/dist/esm/index.js +2 -1
- package/dist/esm/locale.js +17 -3
- package/dist/index.d.ts +20 -1
- package/dist/styles.css +48 -8
- package/package.json +1 -1
package/dist/esm/Popover.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
useMergedRef,
|
|
12
12
|
useMounted
|
|
13
13
|
} from "./internal.js";
|
|
14
|
-
import { useStrings } from "./locale.js";
|
|
14
|
+
import { useDensity, useStrings } from "./locale.js";
|
|
15
15
|
import { createPortal } from "react-dom";
|
|
16
16
|
function position(anchor, pop, placement) {
|
|
17
17
|
const r = anchor.getBoundingClientRect(), pw = pop.offsetWidth, ph = pop.offsetHeight, vw = window.innerWidth, vh = window.innerHeight, gap = 6;
|
|
@@ -24,6 +24,7 @@ function position(anchor, pop, placement) {
|
|
|
24
24
|
}
|
|
25
25
|
const Popover = React.forwardRef(function Popover2(props, ref) {
|
|
26
26
|
const t = useStrings();
|
|
27
|
+
const density = useDensity();
|
|
27
28
|
const auto = uid(), id = props.id || auto;
|
|
28
29
|
const st = useMaybeControlled(props.open, !!props.defaultOpen, props.onOpenChange);
|
|
29
30
|
const open = !!st[0];
|
|
@@ -81,6 +82,7 @@ const Popover = React.forwardRef(function Popover2(props, ref) {
|
|
|
81
82
|
{
|
|
82
83
|
ref: popMerged,
|
|
83
84
|
id,
|
|
85
|
+
"data-density": density,
|
|
84
86
|
role: "dialog",
|
|
85
87
|
"aria-modal": false,
|
|
86
88
|
"aria-label": props.title ? void 0 : props.label,
|
package/dist/esm/SideNav.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
3
4
|
import { Icon } from "./Icon.js";
|
|
5
|
+
import { IconButton } from "./IconButton.js";
|
|
4
6
|
import { cx, uid, useMaybeControlled } from "./internal.js";
|
|
5
7
|
import { useLinkComponent, useStrings } from "./locale.js";
|
|
6
8
|
function contains(it, id) {
|
|
@@ -18,6 +20,39 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
|
|
|
18
20
|
props.onChange
|
|
19
21
|
);
|
|
20
22
|
const active = st[0];
|
|
23
|
+
const col = useMaybeControlled(props.collapsed, !!props.defaultCollapsed, props.onCollapsedChange);
|
|
24
|
+
const collapsed = col[0];
|
|
25
|
+
const tipState = React.useState(null), tip = tipState[0], setTip = tipState[1];
|
|
26
|
+
React.useEffect(
|
|
27
|
+
function() {
|
|
28
|
+
if (!collapsed) setTip(null);
|
|
29
|
+
},
|
|
30
|
+
[collapsed]
|
|
31
|
+
);
|
|
32
|
+
React.useEffect(
|
|
33
|
+
function() {
|
|
34
|
+
if (!tip) return;
|
|
35
|
+
function esc(e) {
|
|
36
|
+
if (e.key === "Escape") setTip(null);
|
|
37
|
+
}
|
|
38
|
+
document.addEventListener("keydown", esc);
|
|
39
|
+
return function() {
|
|
40
|
+
document.removeEventListener("keydown", esc);
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
[tip]
|
|
44
|
+
);
|
|
45
|
+
function tipHandlers(label) {
|
|
46
|
+
if (!collapsed) return {};
|
|
47
|
+
function show(e) {
|
|
48
|
+
const r = e.currentTarget.getBoundingClientRect();
|
|
49
|
+
setTip({ text: label, top: r.top + r.height / 2, left: r.right + 8 });
|
|
50
|
+
}
|
|
51
|
+
function hide() {
|
|
52
|
+
setTip(null);
|
|
53
|
+
}
|
|
54
|
+
return { onMouseEnter: show, onFocus: show, onMouseLeave: hide, onBlur: hide };
|
|
55
|
+
}
|
|
21
56
|
const sections = props.sections || [{ items: props.items || [] }];
|
|
22
57
|
const openState = React.useState({}), toggled = openState[0], setToggled = openState[1];
|
|
23
58
|
function isOpen(it) {
|
|
@@ -63,8 +98,10 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
|
|
|
63
98
|
visible[j].focus();
|
|
64
99
|
}
|
|
65
100
|
function inner(it, group, open) {
|
|
101
|
+
const marked = it.count != null && it.count > 0 || it.badge != null;
|
|
66
102
|
return [
|
|
67
|
-
it.icon ? /* @__PURE__ */ React.createElement(Icon, { key: "i", name: it.icon }) : null,
|
|
103
|
+
it.icon ? /* @__PURE__ */ React.createElement(Icon, { key: "i", name: it.icon }) : collapsed ? /* @__PURE__ */ React.createElement("span", { key: "i", className: "aura-nav__initial", "aria-hidden": "true" }, it.label.charAt(0)) : null,
|
|
104
|
+
collapsed && marked ? /* @__PURE__ */ React.createElement("span", { key: "d", className: "aura-nav__dot", "aria-hidden": "true" }) : null,
|
|
68
105
|
/* @__PURE__ */ React.createElement("span", { key: "l", className: "aura-nav__label" }, it.label),
|
|
69
106
|
it.badge != null ? /* @__PURE__ */ React.createElement("span", { key: "b", className: "aura-nav__badge" }, it.badge) : null,
|
|
70
107
|
it.count != null ? /* @__PURE__ */ React.createElement("span", { key: "c", className: "aura-nav__count" }, it.count) : null,
|
|
@@ -73,7 +110,7 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
|
|
|
73
110
|
}
|
|
74
111
|
function item(it, depth) {
|
|
75
112
|
if (it.children) {
|
|
76
|
-
const open = isOpen(it);
|
|
113
|
+
const open = !collapsed && isOpen(it);
|
|
77
114
|
const listId = base + "-" + it.id;
|
|
78
115
|
const holdsActive = contains(it, active);
|
|
79
116
|
return /* @__PURE__ */ React.createElement("li", { key: it.id, className: "aura-nav__group" }, /* @__PURE__ */ React.createElement(
|
|
@@ -84,10 +121,15 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
|
|
|
84
121
|
"aria-expanded": open,
|
|
85
122
|
"aria-controls": listId,
|
|
86
123
|
style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
|
|
124
|
+
...tipHandlers(it.label),
|
|
87
125
|
onClick: function() {
|
|
88
126
|
const next = Object.assign({}, toggled);
|
|
89
127
|
next[it.id] = !open;
|
|
90
128
|
setToggled(next);
|
|
129
|
+
if (collapsed) {
|
|
130
|
+
setTip(null);
|
|
131
|
+
col[1](false);
|
|
132
|
+
}
|
|
91
133
|
},
|
|
92
134
|
onKeyDown: function(e) {
|
|
93
135
|
if (e.key === "ArrowRight" && !open) {
|
|
@@ -106,6 +148,7 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
|
|
|
106
148
|
}
|
|
107
149
|
const on = active === it.id;
|
|
108
150
|
const common = {
|
|
151
|
+
...tipHandlers(it.label),
|
|
109
152
|
className: cx("aura-nav__item", on && "is-active"),
|
|
110
153
|
"aria-current": on ? "page" : void 0,
|
|
111
154
|
style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
|
|
@@ -124,7 +167,8 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
|
|
|
124
167
|
if (typeof ref === "function") ref(el);
|
|
125
168
|
else if (ref) ref.current = el;
|
|
126
169
|
},
|
|
127
|
-
className: cx("aura-nav", props.className),
|
|
170
|
+
className: cx("aura-nav", collapsed && "aura-nav--collapsed", props.className),
|
|
171
|
+
"data-collapsed": collapsed ? "" : void 0,
|
|
128
172
|
"aria-label": props.label || t.mainNav,
|
|
129
173
|
onKeyDown
|
|
130
174
|
},
|
|
@@ -134,7 +178,31 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
|
|
|
134
178
|
return item(it, 0);
|
|
135
179
|
})));
|
|
136
180
|
})),
|
|
137
|
-
props.footer ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__footer" }, props.footer) : null
|
|
181
|
+
props.footer ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__footer" }, props.footer) : null,
|
|
182
|
+
props.collapsible ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__toggle" }, /* @__PURE__ */ React.createElement(
|
|
183
|
+
IconButton,
|
|
184
|
+
{
|
|
185
|
+
icon: collapsed ? "panel-left-open" : "panel-left-close",
|
|
186
|
+
label: collapsed ? t.expandNav : t.collapseNav,
|
|
187
|
+
size: "md",
|
|
188
|
+
onClick: function() {
|
|
189
|
+
setTip(null);
|
|
190
|
+
col[1](!collapsed);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
)) : null,
|
|
194
|
+
tip && typeof document !== "undefined" ? createPortal(
|
|
195
|
+
/* @__PURE__ */ React.createElement(
|
|
196
|
+
"div",
|
|
197
|
+
{
|
|
198
|
+
className: "aura-tooltip aura-tooltip--right",
|
|
199
|
+
"aria-hidden": "true",
|
|
200
|
+
style: { top: tip.top, left: tip.left }
|
|
201
|
+
},
|
|
202
|
+
tip.text
|
|
203
|
+
),
|
|
204
|
+
document.body
|
|
205
|
+
) : null
|
|
138
206
|
);
|
|
139
207
|
});
|
|
140
208
|
export {
|
package/dist/esm/index.js
CHANGED
|
@@ -34,7 +34,7 @@ import { Container } from "./Container.js";
|
|
|
34
34
|
import { AppShell } from "./AppShell.js";
|
|
35
35
|
import { useBreakpoint, useResponsive, breakpoints } from "./responsive.js";
|
|
36
36
|
import { Surface } from "./Surface.js";
|
|
37
|
-
import { AuraProvider, useAuraLocale, STRINGS } from "./locale.js";
|
|
37
|
+
import { AuraProvider, useAuraLocale, useDensity, STRINGS } from "./locale.js";
|
|
38
38
|
import { Stat } from "./Stat.js";
|
|
39
39
|
import { TimePicker, parseTime } from "./TimePicker.js";
|
|
40
40
|
import { FileUpload, formatBytes } from "./FileUpload.js";
|
|
@@ -126,6 +126,7 @@ export {
|
|
|
126
126
|
useAuraLocale,
|
|
127
127
|
useBreakpoint,
|
|
128
128
|
useColorScheme,
|
|
129
|
+
useDensity,
|
|
129
130
|
useFormatDate,
|
|
130
131
|
useResponsive
|
|
131
132
|
};
|
package/dist/esm/locale.js
CHANGED
|
@@ -29,6 +29,8 @@ const STRINGS = {
|
|
|
29
29
|
breadcrumb: "Breadcrumb",
|
|
30
30
|
navigation: "Navigation",
|
|
31
31
|
openNav: "Open navigation",
|
|
32
|
+
collapseNav: "Collapse sidebar",
|
|
33
|
+
expandNav: "Expand sidebar",
|
|
32
34
|
searching: "Searching\u2026",
|
|
33
35
|
noMatches: "No matches",
|
|
34
36
|
clear: function(what) {
|
|
@@ -140,6 +142,8 @@ const STRINGS = {
|
|
|
140
142
|
breadcrumb: "\u0E40\u0E2A\u0E49\u0E19\u0E17\u0E32\u0E07",
|
|
141
143
|
navigation: "\u0E40\u0E21\u0E19\u0E39",
|
|
142
144
|
openNav: "\u0E40\u0E1B\u0E34\u0E14\u0E40\u0E21\u0E19\u0E39",
|
|
145
|
+
collapseNav: "\u0E22\u0E48\u0E2D\u0E41\u0E16\u0E1A\u0E40\u0E21\u0E19\u0E39",
|
|
146
|
+
expandNav: "\u0E02\u0E22\u0E32\u0E22\u0E41\u0E16\u0E1A\u0E40\u0E21\u0E19\u0E39",
|
|
143
147
|
searching: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E04\u0E49\u0E19\u0E2B\u0E32\u2026",
|
|
144
148
|
noMatches: "\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E17\u0E35\u0E48\u0E15\u0E23\u0E07\u0E01\u0E31\u0E19",
|
|
145
149
|
clear: function(what) {
|
|
@@ -251,6 +255,8 @@ const STRINGS = {
|
|
|
251
255
|
breadcrumb: "Br\xF6dsmulor",
|
|
252
256
|
navigation: "Navigering",
|
|
253
257
|
openNav: "\xD6ppna menyn",
|
|
258
|
+
collapseNav: "F\xE4ll ihop sidof\xE4ltet",
|
|
259
|
+
expandNav: "F\xE4ll ut sidof\xE4ltet",
|
|
254
260
|
searching: "S\xF6ker\u2026",
|
|
255
261
|
noMatches: "Inga tr\xE4ffar",
|
|
256
262
|
clear: function(what) {
|
|
@@ -343,6 +349,8 @@ const STRINGS = {
|
|
|
343
349
|
};
|
|
344
350
|
const LocaleContext = React.createContext(null);
|
|
345
351
|
function AuraProvider(props) {
|
|
352
|
+
const outer = React.useContext(LocaleContext);
|
|
353
|
+
const density = props.density || outer && outer.density || null;
|
|
346
354
|
const value = React.useMemo(
|
|
347
355
|
function() {
|
|
348
356
|
const base = props.locale && STRINGS[props.locale] || STRINGS.en;
|
|
@@ -350,12 +358,13 @@ function AuraProvider(props) {
|
|
|
350
358
|
locale: props.locale || "en",
|
|
351
359
|
calendar: props.calendar || null,
|
|
352
360
|
strings: props.strings ? Object.assign({}, base, props.strings) : base,
|
|
353
|
-
linkComponent: props.linkComponent || null
|
|
361
|
+
linkComponent: props.linkComponent || null,
|
|
362
|
+
density
|
|
354
363
|
};
|
|
355
364
|
},
|
|
356
|
-
[props.locale, props.calendar, props.strings, props.linkComponent]
|
|
365
|
+
[props.locale, props.calendar, props.strings, props.linkComponent, density]
|
|
357
366
|
);
|
|
358
|
-
return /* @__PURE__ */ React.createElement(LocaleContext.Provider, { value }, props.children);
|
|
367
|
+
return /* @__PURE__ */ React.createElement(LocaleContext.Provider, { value }, props.density ? /* @__PURE__ */ React.createElement("div", { className: "aura-density", "data-density": props.density }, props.children) : props.children);
|
|
359
368
|
}
|
|
360
369
|
function useAuraLocale() {
|
|
361
370
|
return React.useContext(LocaleContext) || { locale: null, calendar: null, strings: STRINGS.en };
|
|
@@ -364,6 +373,10 @@ function useLinkComponent(own) {
|
|
|
364
373
|
const ctx = React.useContext(LocaleContext);
|
|
365
374
|
return own || ctx && ctx.linkComponent || "a";
|
|
366
375
|
}
|
|
376
|
+
function useDensity() {
|
|
377
|
+
const ctx = React.useContext(LocaleContext);
|
|
378
|
+
return ctx && ctx.density || void 0;
|
|
379
|
+
}
|
|
367
380
|
function useStrings() {
|
|
368
381
|
return useAuraLocale().strings;
|
|
369
382
|
}
|
|
@@ -371,6 +384,7 @@ export {
|
|
|
371
384
|
AuraProvider,
|
|
372
385
|
STRINGS,
|
|
373
386
|
useAuraLocale,
|
|
387
|
+
useDensity,
|
|
374
388
|
useLinkComponent,
|
|
375
389
|
useStrings
|
|
376
390
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -149,13 +149,15 @@ 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;
|
|
155
157
|
}
|
|
156
158
|
/** An AURA icon name, or any icon element (e.g. `<Building />` from lucide-react). AURA sizes it and hides it from screen readers. */
|
|
157
159
|
export type IconInput = IconName | React$1.ReactElement;
|
|
158
|
-
export type IconName = "check" | "x" | "plus" | "minus" | "search" | "chevron-down" | "chevron-up" | "chevron-left" | "chevron-right" | "arrow-right" | "arrow-up-right" | "arrow-up-down" | "loader-circle" | "circle-alert" | "circle-check" | "info" | "triangle-alert" | "settings" | "user" | "users" | "filter" | "ellipsis" | "external-link" | "copy" | "trash-2" | "pencil" | "download" | "upload" | "calendar" | "bell" | "menu" | "eye" | "log-out" | "circle" | "circle-dot-dashed" | "ban" | "arrow-up" | "arrow-down" | "inbox" | "pin" | "pin-off" | "eye-off" | "columns-3" | "arrow-left" | "rotate-ccw" | "house" | "layout-dashboard" | "folder" | "chart-column" | "file-text" | "mail" | "lock" | "clock" | "trending-up" | "trending-down" | "image" | "paperclip" | "cloud-upload" | "file" | "sun" | "moon" | "monitor";
|
|
160
|
+
export type IconName = "check" | "x" | "plus" | "minus" | "search" | "chevron-down" | "chevron-up" | "chevron-left" | "chevron-right" | "arrow-right" | "arrow-up-right" | "arrow-up-down" | "loader-circle" | "circle-alert" | "circle-check" | "info" | "triangle-alert" | "settings" | "user" | "users" | "filter" | "ellipsis" | "external-link" | "copy" | "trash-2" | "pencil" | "download" | "upload" | "calendar" | "bell" | "menu" | "eye" | "log-out" | "circle" | "circle-dot-dashed" | "ban" | "arrow-up" | "arrow-down" | "inbox" | "pin" | "pin-off" | "eye-off" | "columns-3" | "arrow-left" | "rotate-ccw" | "house" | "layout-dashboard" | "folder" | "chart-column" | "file-text" | "mail" | "lock" | "clock" | "trending-up" | "trending-down" | "image" | "paperclip" | "cloud-upload" | "file" | "sun" | "moon" | "monitor" | "panel-left-close" | "panel-left-open";
|
|
159
161
|
/** Lucide stroke icon drawn inline in currentColor. */
|
|
160
162
|
export interface IconProps {
|
|
161
163
|
/** A name from the set, or an icon element of your own (sized and styled the same way). */
|
|
@@ -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;
|
|
@@ -525,6 +529,15 @@ export interface SideNavProps {
|
|
|
525
529
|
label?: string;
|
|
526
530
|
/** Router link for items with `href`; defaults to the AuraProvider's `linkComponent`, then `<a>`. */
|
|
527
531
|
linkComponent?: React$1.ElementType;
|
|
532
|
+
/** Icon-only rail (`aura-sidenav-rail-width`, 64px). Labels show as tooltips and stay the accessible names; a group
|
|
533
|
+
* expands the rail when clicked. Controlled; pair with `onCollapsedChange`. */
|
|
534
|
+
collapsed?: boolean;
|
|
535
|
+
/** Starting state when `collapsed` isn't controlled. Default false. */
|
|
536
|
+
defaultCollapsed?: boolean;
|
|
537
|
+
/** Called by the toggle button, and by a group clicked in the rail (with `false`). Save it to keep the choice. */
|
|
538
|
+
onCollapsedChange?: (collapsed: boolean) => void;
|
|
539
|
+
/** Adds a collapse / expand button at the bottom. AppShell hides it in its phone drawer. */
|
|
540
|
+
collapsible?: boolean;
|
|
528
541
|
className?: string;
|
|
529
542
|
}
|
|
530
543
|
export interface BreadcrumbProps {
|
|
@@ -1147,6 +1160,8 @@ export interface AuraStrings {
|
|
|
1147
1160
|
breadcrumb: string;
|
|
1148
1161
|
navigation: string;
|
|
1149
1162
|
openNav: string;
|
|
1163
|
+
collapseNav: string;
|
|
1164
|
+
expandNav: string;
|
|
1150
1165
|
searching: string;
|
|
1151
1166
|
noMatches: string;
|
|
1152
1167
|
clear: (what?: string) => string;
|
|
@@ -1216,11 +1231,15 @@ export interface AuraLocaleValue {
|
|
|
1216
1231
|
strings: AuraStrings;
|
|
1217
1232
|
/** The router link set on AuraProvider, if any. */
|
|
1218
1233
|
linkComponent?: React$1.ElementType | null;
|
|
1234
|
+
/** The density set on the nearest AuraProvider that sets one (null: none, i.e. comfortable unless an ancestor's data-density says otherwise). */
|
|
1235
|
+
density?: "comfortable" | "compact" | null;
|
|
1219
1236
|
}
|
|
1220
1237
|
/** Sets the language of built-in labels (and the default date locale) for everything inside. */
|
|
1221
1238
|
export declare function AuraProvider(props: AuraProviderProps): React$1.ReactElement;
|
|
1222
1239
|
/** { locale, calendar, strings } from the nearest AuraProvider (English strings when there is none). */
|
|
1223
1240
|
export declare function useAuraLocale(): AuraLocaleValue;
|
|
1241
|
+
/** The provider's density, for portals that render outside its wrapper. */
|
|
1242
|
+
export declare function useDensity(): "comfortable" | "compact" | undefined;
|
|
1224
1243
|
export declare const Stat: React$1.ForwardRefExoticComponent<StatProps & React$1.RefAttributes<HTMLElement>>;
|
|
1225
1244
|
/** Parse typed time: 9 · 09 · 930 · 0930 · 9:30 · 9.30 · 09.30 น. · 9:30 pm → "HH:mm" (24-hour) or null. */
|
|
1226
1245
|
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;
|
|
@@ -596,6 +596,30 @@ a.aura-btn { text-decoration: none; }
|
|
|
596
596
|
.aura-nav__sub { margin-top: 2px; }
|
|
597
597
|
.aura-nav__sub[hidden] { display: none; }
|
|
598
598
|
.aura-nav__footer { padding: var(--aura-space-3); border-top: 1px solid var(--aura-border-default); }
|
|
599
|
+
/* Collapse toggle and the icon-only rail (4.15). */
|
|
600
|
+
.aura-nav { transition: width var(--aura-duration-base) var(--aura-ease); }
|
|
601
|
+
.aura-nav__toggle { display: flex; padding: var(--aura-space-2) var(--aura-space-3); border-top: 1px solid var(--aura-border-default); }
|
|
602
|
+
.aura-nav--collapsed { width: var(--aura-sidenav-rail-width); }
|
|
603
|
+
.aura-nav--collapsed .aura-nav__toggle { justify-content: center; }
|
|
604
|
+
.aura-nav--collapsed .aura-nav__header, .aura-nav--collapsed .aura-nav__footer { padding-left: var(--aura-space-2); padding-right: var(--aura-space-2); overflow: hidden; }
|
|
605
|
+
.aura-nav--collapsed .aura-nav__item { position: relative; justify-content: center; gap: 0; padding: 0; }
|
|
606
|
+
.aura-nav--collapsed .aura-nav__label, .aura-nav--collapsed .aura-nav__count, .aura-nav--collapsed .aura-nav__badge, .aura-nav--collapsed .aura-nav__title {
|
|
607
|
+
position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
|
|
608
|
+
}
|
|
609
|
+
.aura-nav--collapsed .aura-nav__chevron { display: none; }
|
|
610
|
+
.aura-nav--collapsed .aura-nav__section + .aura-nav__section { margin-top: var(--aura-space-3); padding-top: var(--aura-space-3); border-top: 1px solid var(--aura-border-default); }
|
|
611
|
+
.aura-nav--collapsed .aura-nav__item--group.has-active { background: var(--aura-bg-selected); }
|
|
612
|
+
.aura-nav--collapsed .aura-nav__item--group.has-active .aura-icon { color: var(--aura-fg-accent); }
|
|
613
|
+
.aura-nav__initial {
|
|
614
|
+
display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: var(--aura-radius-sm);
|
|
615
|
+
background: var(--aura-status-neutral-bg); color: var(--aura-status-neutral-fg); font-size: 12px; font-weight: 600; text-transform: uppercase;
|
|
616
|
+
}
|
|
617
|
+
.aura-nav__dot {
|
|
618
|
+
position: absolute; top: 6px; left: calc(50% + 5px); width: 8px; height: 8px; border-radius: var(--aura-radius-full);
|
|
619
|
+
background: var(--aura-fg-accent); box-shadow: 0 0 0 2px var(--aura-bg-canvas);
|
|
620
|
+
}
|
|
621
|
+
.aura-tooltip--right { transform: translateY(-50%); white-space: nowrap; }
|
|
622
|
+
@media (prefers-reduced-motion: reduce) { .aura-nav { transition: none; } }
|
|
599
623
|
|
|
600
624
|
/* ---------- Breadcrumb ---------- */
|
|
601
625
|
.aura-crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--aura-space-1) var(--aura-space-2); list-style: none; margin: 0; padding: 0; font-family: var(--font-sans); font-size: 13px; }
|
|
@@ -1241,3 +1265,19 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
|
|
|
1241
1265
|
}
|
|
1242
1266
|
@media (prefers-reduced-motion: reduce) { .aura-command { animation: none; } }
|
|
1243
1267
|
|
|
1268
|
+
/* Density. data-density="compact" on <html> or any container (AuraProvider density="compact" and DataTable
|
|
1269
|
+
* density do it for you): 36px fields and buttons, 40px table rows, less button padding — for dense admin screens.
|
|
1270
|
+
* Touch screens keep 44px targets whatever the density. "comfortable" inside compact switches back. */
|
|
1271
|
+
[data-density='compact'] {
|
|
1272
|
+
--aura-input-height: 36px; --aura-button-height: 36px; --aura-table-row-height: 40px;
|
|
1273
|
+
--aura-button-padding-x: var(--aura-space-4);
|
|
1274
|
+
}
|
|
1275
|
+
[data-density='comfortable'] {
|
|
1276
|
+
--aura-input-height: 44px; --aura-button-height: 44px; --aura-table-row-height: 48px;
|
|
1277
|
+
--aura-button-padding-x: var(--aura-space-6);
|
|
1278
|
+
}
|
|
1279
|
+
@media (pointer: coarse) {
|
|
1280
|
+
[data-density='compact'] { --aura-input-height: 44px; --aura-button-height: 44px; --aura-table-row-height: 48px; --aura-button-padding-x: var(--aura-space-6); }
|
|
1281
|
+
}
|
|
1282
|
+
.aura-density { display: contents; }
|
|
1283
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.15.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",
|