@jirawatpyk/aura-react 4.5.0 → 4.5.1
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 +2 -2
- package/dist/aura.bundle.js +2518 -2028
- package/dist/cjs/index.cjs +2516 -2028
- package/dist/esm/Button.js +9 -9
- package/dist/esm/Checkbox.js +41 -33
- package/dist/esm/Combobox.js +143 -125
- package/dist/esm/DataTable.js +629 -495
- package/dist/esm/DatePicker.js +378 -305
- package/dist/esm/Dialog.js +48 -59
- package/dist/esm/DropdownMenu.js +9 -12
- package/dist/esm/FileUpload.js +91 -73
- package/dist/esm/Icon.js +27 -22
- package/dist/esm/IconButton.js +13 -9
- package/dist/esm/Menu.js +78 -66
- package/dist/esm/Stat.js +9 -26
- package/dist/esm/StatusPill.js +12 -13
- package/dist/esm/Surface.js +17 -13
- package/dist/esm/ThemeStyle.js +9 -5
- package/dist/esm/TimePicker.js +155 -127
- package/dist/esm/extra.js +270 -186
- package/dist/esm/feedback.js +112 -84
- package/dist/esm/forms.js +144 -113
- package/dist/esm/internal.js +33 -23
- package/dist/esm/layout.js +113 -128
- package/dist/esm/layout2.js +67 -45
- package/dist/esm/locale.js +15 -9
- package/dist/esm/overlay.js +21 -18
- package/dist/esm/theme.js +101 -49
- package/dist/index.d.ts +6 -6
- package/package.json +5 -3
package/dist/esm/overlay.js
CHANGED
|
@@ -2,22 +2,25 @@
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { FOCUSABLE, useMounted } from "./internal.js";
|
|
4
4
|
function useModal(open, ref, opts) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
React.useEffect(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
5
|
+
const mounted = useMounted();
|
|
6
|
+
const prev = React.useRef(null);
|
|
7
|
+
const o = opts || {};
|
|
8
|
+
React.useEffect(
|
|
9
|
+
function() {
|
|
10
|
+
if (!open || !mounted) return;
|
|
11
|
+
prev.current = document.activeElement;
|
|
12
|
+
const body = document.body, overflow = body.style.overflow;
|
|
13
|
+
body.style.overflow = "hidden";
|
|
14
|
+
const el = ref.current;
|
|
15
|
+
const target = el && (el.querySelector("[data-autofocus]") || el.querySelector(o.bodySelector + " " + FOCUSABLE) || el.querySelector(o.footSelector + " " + FOCUSABLE) || el);
|
|
16
|
+
if (target && o.autoFocus !== false) target.focus();
|
|
17
|
+
return function() {
|
|
18
|
+
body.style.overflow = overflow;
|
|
19
|
+
if (prev.current && prev.current.focus) prev.current.focus();
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
[open, mounted]
|
|
23
|
+
);
|
|
21
24
|
function onKeyDown(e) {
|
|
22
25
|
if (e.key === "Escape") {
|
|
23
26
|
e.stopPropagation();
|
|
@@ -25,12 +28,12 @@ function useModal(open, ref, opts) {
|
|
|
25
28
|
return;
|
|
26
29
|
}
|
|
27
30
|
if (e.key !== "Tab" || !ref.current) return;
|
|
28
|
-
|
|
31
|
+
const list = Array.prototype.slice.call(ref.current.querySelectorAll(FOCUSABLE));
|
|
29
32
|
if (!list.length) {
|
|
30
33
|
e.preventDefault();
|
|
31
34
|
return;
|
|
32
35
|
}
|
|
33
|
-
|
|
36
|
+
const first = list[0], last = list[list.length - 1];
|
|
34
37
|
if (e.shiftKey && (document.activeElement === first || document.activeElement === ref.current)) {
|
|
35
38
|
e.preventDefault();
|
|
36
39
|
last.focus();
|
package/dist/esm/theme.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
function hexToRgb(hex) {
|
|
3
|
-
|
|
4
|
-
if (h.length === 3)
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
let h = String(hex).trim().replace("#", "");
|
|
4
|
+
if (h.length === 3)
|
|
5
|
+
h = h.split("").map(function(c) {
|
|
6
|
+
return c + c;
|
|
7
|
+
}).join("");
|
|
7
8
|
if (!/^[0-9a-f]{6}$/i.test(h)) throw new Error('createTheme: "' + hex + '" is not a #rgb or #rrggbb colour');
|
|
8
9
|
return [0, 2, 4].map(function(i) {
|
|
9
10
|
return parseInt(h.slice(i, i + 2), 16) / 255;
|
|
@@ -11,7 +12,7 @@ function hexToRgb(hex) {
|
|
|
11
12
|
}
|
|
12
13
|
function rgbToHex(rgb) {
|
|
13
14
|
return "#" + rgb.map(function(v) {
|
|
14
|
-
|
|
15
|
+
const n = Math.round(Math.min(1, Math.max(0, v)) * 255);
|
|
15
16
|
return (n < 16 ? "0" : "") + n.toString(16);
|
|
16
17
|
}).join("");
|
|
17
18
|
}
|
|
@@ -22,20 +23,20 @@ function delin(c) {
|
|
|
22
23
|
return c <= 31308e-7 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
|
|
23
24
|
}
|
|
24
25
|
function rgbToOklch(rgb) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
const r = lin(rgb[0]), g = lin(rgb[1]), b = lin(rgb[2]);
|
|
27
|
+
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
28
|
+
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
29
|
+
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
30
|
+
const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
|
|
31
|
+
const A = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
|
|
32
|
+
const B = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
|
|
32
33
|
return [L, Math.sqrt(A * A + B * B), (Math.atan2(B, A) * 180 / Math.PI + 360) % 360];
|
|
33
34
|
}
|
|
34
35
|
function oklchToRgbRaw(L, C, H) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
const a = C * Math.cos(H * Math.PI / 180), b = C * Math.sin(H * Math.PI / 180);
|
|
37
|
+
const l = Math.pow(L + 0.3963377774 * a + 0.2158037573 * b, 3);
|
|
38
|
+
const m = Math.pow(L - 0.1055613458 * a - 0.0638541728 * b, 3);
|
|
39
|
+
const s = Math.pow(L - 0.0894841775 * a - 1.291485548 * b, 3);
|
|
39
40
|
return [
|
|
40
41
|
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
41
42
|
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
@@ -48,56 +49,70 @@ function inGamut(rgb) {
|
|
|
48
49
|
});
|
|
49
50
|
}
|
|
50
51
|
function oklchToHex(L, C, H) {
|
|
51
|
-
|
|
52
|
+
let lo = 0, hi = C, rgb = oklchToRgbRaw(L, C, H);
|
|
52
53
|
if (inGamut(rgb)) return rgbToHex(rgb);
|
|
53
|
-
for (
|
|
54
|
-
|
|
54
|
+
for (let i = 0; i < 24; i++) {
|
|
55
|
+
const mid = (lo + hi) / 2;
|
|
55
56
|
if (inGamut(oklchToRgbRaw(L, mid, H))) lo = mid;
|
|
56
57
|
else hi = mid;
|
|
57
58
|
}
|
|
58
59
|
return rgbToHex(oklchToRgbRaw(L, lo, H));
|
|
59
60
|
}
|
|
60
61
|
function luminance(hex) {
|
|
61
|
-
|
|
62
|
+
const c = hexToRgb(hex).map(lin);
|
|
62
63
|
return 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];
|
|
63
64
|
}
|
|
64
65
|
function contrast(a, b) {
|
|
65
|
-
|
|
66
|
+
const x = luminance(a), y = luminance(b);
|
|
66
67
|
return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05);
|
|
67
68
|
}
|
|
68
69
|
function mix(a, b, t) {
|
|
69
|
-
|
|
70
|
-
return rgbToHex(
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
const x = hexToRgb(a), y = hexToRgb(b);
|
|
71
|
+
return rgbToHex(
|
|
72
|
+
x.map(function(v, i) {
|
|
73
|
+
return v + (y[i] - v) * t;
|
|
74
|
+
})
|
|
75
|
+
);
|
|
73
76
|
}
|
|
74
|
-
|
|
77
|
+
const STEPS = {
|
|
78
|
+
50: [0.975, 0.18],
|
|
79
|
+
100: [0.945, 0.3],
|
|
80
|
+
200: [0.895, 0.5],
|
|
81
|
+
300: [0.81, 0.72],
|
|
82
|
+
400: [0.715, 0.9],
|
|
83
|
+
500: [0.635, 1],
|
|
84
|
+
600: [0.555, 1],
|
|
85
|
+
700: [0.49, 0.95],
|
|
86
|
+
800: [0.43, 0.85],
|
|
87
|
+
900: [0.38, 0.72]
|
|
88
|
+
};
|
|
75
89
|
function scale(hex) {
|
|
76
|
-
|
|
90
|
+
const o = rgbToOklch(hexToRgb(hex)), C = Math.max(o[1], 0.02), out = {};
|
|
77
91
|
Object.keys(STEPS).forEach(function(k) {
|
|
78
92
|
out[k] = oklchToHex(STEPS[k][0], C * STEPS[k][1] / 0.95 * (o[1] < 0.03 ? 0.4 : 1), o[2]);
|
|
79
93
|
});
|
|
80
94
|
return out;
|
|
81
95
|
}
|
|
82
96
|
function fit(hex, grounds, target, dir) {
|
|
83
|
-
|
|
84
|
-
for (
|
|
97
|
+
let o = rgbToOklch(hexToRgb(hex)), L = o[0], c = hex;
|
|
98
|
+
for (let i = 0; i < 80; i++) {
|
|
85
99
|
if (grounds.every(function(g) {
|
|
86
100
|
return contrast(c, g) >= target;
|
|
87
|
-
}))
|
|
101
|
+
}))
|
|
102
|
+
return c;
|
|
88
103
|
L = Math.min(1, Math.max(0, L + dir * 0.01));
|
|
89
104
|
c = oklchToHex(L, o[1], o[2]);
|
|
90
105
|
}
|
|
91
106
|
return c;
|
|
92
107
|
}
|
|
93
|
-
|
|
94
|
-
|
|
108
|
+
const ZINC = { 0: "#ffffff", 50: "#fafafa", 100: "#f4f4f5", 800: "#27272a", 900: "#18181b", 950: "#09090b" };
|
|
109
|
+
const INK = "#18181b";
|
|
95
110
|
function createTheme(opts) {
|
|
96
|
-
|
|
111
|
+
const o = opts || {};
|
|
97
112
|
if (!o.brand) throw new Error('createTheme: pass { brand: "#rrggbb" }');
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
113
|
+
const b = scale(o.brand), s = o.signal ? scale(o.signal) : null;
|
|
114
|
+
const lightGrounds = [ZINC[0], ZINC[50]], darkGrounds = [ZINC[900], ZINC[950]];
|
|
115
|
+
const L = {}, D = {};
|
|
101
116
|
L["fg-accent"] = fit(b[700], lightGrounds, 4.5, -1);
|
|
102
117
|
L["accent-violet"] = L["fg-accent"];
|
|
103
118
|
L["focus-ring"] = fit(b[700], lightGrounds.concat([b[50]]), 3, -1);
|
|
@@ -125,7 +140,7 @@ function createTheme(opts) {
|
|
|
125
140
|
D["accent-lime"] = s[200];
|
|
126
141
|
D["mesh-to"] = s[200];
|
|
127
142
|
}
|
|
128
|
-
|
|
143
|
+
const shadowLight = INK, shadowDark = D["accent-violet"];
|
|
129
144
|
if (o.primary === "brand") {
|
|
130
145
|
L["button-primary-bg"] = fit(b[600], [ZINC[0]], 4.5, -1);
|
|
131
146
|
L["button-primary-fg"] = ZINC[0];
|
|
@@ -140,16 +155,30 @@ function createTheme(opts) {
|
|
|
140
155
|
D["shadow-creative"] = "4px 4px 0px " + shadowDark;
|
|
141
156
|
D["shadow-creative-hover"] = "6px 6px 0px " + shadowDark;
|
|
142
157
|
D["card-shadow-creative"] = "8px 8px 0px " + shadowDark;
|
|
143
|
-
|
|
158
|
+
const checks = [];
|
|
144
159
|
function check(theme, fg, bg, target, fgHex, bgHex) {
|
|
145
|
-
|
|
146
|
-
checks.push({
|
|
160
|
+
const r = contrast(fgHex, bgHex);
|
|
161
|
+
checks.push({
|
|
162
|
+
theme,
|
|
163
|
+
pair: fg + " on " + bg,
|
|
164
|
+
ratio: Math.round(r * 100) / 100,
|
|
165
|
+
target,
|
|
166
|
+
pass: r >= target - 5e-3
|
|
167
|
+
});
|
|
147
168
|
}
|
|
148
|
-
[
|
|
169
|
+
[
|
|
170
|
+
["bg-surface", ZINC[0]],
|
|
171
|
+
["bg-canvas", ZINC[50]],
|
|
172
|
+
["bg-selected", L["bg-selected"]]
|
|
173
|
+
].forEach(function(g) {
|
|
149
174
|
check("light", "fg-accent", g[0], 4.5, L["fg-accent"], g[1]);
|
|
150
175
|
check("light", "focus-ring", g[0], 3, L["focus-ring"], g[1]);
|
|
151
176
|
});
|
|
152
|
-
[
|
|
177
|
+
[
|
|
178
|
+
["bg-surface", ZINC[900]],
|
|
179
|
+
["bg-canvas", ZINC[950]],
|
|
180
|
+
["bg-selected", D["bg-selected"]]
|
|
181
|
+
].forEach(function(g) {
|
|
153
182
|
check("dark", "fg-accent", g[0], 4.5, D["fg-accent"], g[1]);
|
|
154
183
|
check("dark", "focus-ring", g[0], 3, D["focus-ring"], g[1]);
|
|
155
184
|
});
|
|
@@ -160,14 +189,28 @@ function createTheme(opts) {
|
|
|
160
189
|
check("dark", "alert-info-fg", "alert-info-bg", 4.5, D["alert-info-fg"], D["alert-info-bg"]);
|
|
161
190
|
if (o.primary === "brand") {
|
|
162
191
|
check("light", "button-primary-fg", "button-primary-bg", 4.5, L["button-primary-fg"], L["button-primary-bg"]);
|
|
163
|
-
check(
|
|
192
|
+
check(
|
|
193
|
+
"light",
|
|
194
|
+
"button-primary-fg",
|
|
195
|
+
"button-primary-bg-hover",
|
|
196
|
+
4.5,
|
|
197
|
+
L["button-primary-fg"],
|
|
198
|
+
L["button-primary-bg-hover"]
|
|
199
|
+
);
|
|
164
200
|
check("dark", "button-primary-fg", "button-primary-bg", 4.5, D["button-primary-fg"], D["button-primary-bg"]);
|
|
165
|
-
check(
|
|
201
|
+
check(
|
|
202
|
+
"dark",
|
|
203
|
+
"button-primary-fg",
|
|
204
|
+
"button-primary-bg-hover",
|
|
205
|
+
4.5,
|
|
206
|
+
D["button-primary-fg"],
|
|
207
|
+
D["button-primary-bg-hover"]
|
|
208
|
+
);
|
|
166
209
|
}
|
|
167
210
|
if (s) check("light", "ink", "accent-lime (signal)", 4.5, INK, s[200]);
|
|
168
211
|
function css(selector) {
|
|
169
|
-
|
|
170
|
-
|
|
212
|
+
const light = selector ? selector : ':root, [data-theme="light"]';
|
|
213
|
+
const dark = selector ? selector + ".dark, .dark " + selector + ", " + selector + '[data-theme="dark"], [data-theme="dark"] ' + selector : '.dark, [data-theme="dark"]';
|
|
171
214
|
function block(sel, m) {
|
|
172
215
|
return sel + " {\n" + Object.keys(m).map(function(k) {
|
|
173
216
|
return " --aura-" + k + ": " + m[k] + ";";
|
|
@@ -175,9 +218,18 @@ function createTheme(opts) {
|
|
|
175
218
|
}
|
|
176
219
|
return "/* AURA theme" + (o.name ? ' "' + o.name + '"' : "") + ": brand " + o.brand + (o.signal ? ", signal " + o.signal : "") + (o.primary === "brand" ? ", brand primary buttons" : "") + ". Load after aura.css. Generated by createTheme. */\n" + block(light, L) + "\n" + block(dark, D) + "\n";
|
|
177
220
|
}
|
|
178
|
-
return {
|
|
179
|
-
|
|
180
|
-
|
|
221
|
+
return {
|
|
222
|
+
name: o.name || null,
|
|
223
|
+
brand: b,
|
|
224
|
+
signal: s,
|
|
225
|
+
light: L,
|
|
226
|
+
dark: D,
|
|
227
|
+
checks,
|
|
228
|
+
ok: checks.every(function(c) {
|
|
229
|
+
return c.pass;
|
|
230
|
+
}),
|
|
231
|
+
css
|
|
232
|
+
};
|
|
181
233
|
}
|
|
182
234
|
export {
|
|
183
235
|
contrast,
|
package/dist/index.d.ts
CHANGED
|
@@ -554,7 +554,7 @@ export interface AppShellProps {
|
|
|
554
554
|
children?: React$1.ReactNode;
|
|
555
555
|
navLabel?: string;
|
|
556
556
|
menuLabel?: string;
|
|
557
|
-
/** id of
|
|
557
|
+
/** id of `<main>`, for a skip link. Default `main`. */
|
|
558
558
|
mainId?: string;
|
|
559
559
|
className?: string;
|
|
560
560
|
}
|
|
@@ -624,7 +624,7 @@ export interface FileUploadProps extends FieldProps {
|
|
|
624
624
|
defaultValue?: UploadItem[];
|
|
625
625
|
onChange?: (items: UploadItem[]) => void;
|
|
626
626
|
onRemove?: (item: UploadItem) => void;
|
|
627
|
-
/** Same syntax as
|
|
627
|
+
/** Same syntax as `<input accept>`: "image/*,.pdf". Checked on drop too. */
|
|
628
628
|
accept?: string;
|
|
629
629
|
multiple?: boolean;
|
|
630
630
|
/** Bytes per file. */
|
|
@@ -775,7 +775,7 @@ export type IconShape = [
|
|
|
775
775
|
string,
|
|
776
776
|
Record<string, string>
|
|
777
777
|
];
|
|
778
|
-
export declare
|
|
778
|
+
export declare const ICONS: Record<IconName, IconShape[]>;
|
|
779
779
|
export declare const Icon: React$1.ForwardRefExoticComponent<IconProps & React$1.RefAttributes<SVGSVGElement>>;
|
|
780
780
|
/** Every icon name the bundle carries. */
|
|
781
781
|
export declare const iconNames: IconName[];
|
|
@@ -826,7 +826,7 @@ export declare const Calendar: React$1.ForwardRefExoticComponent<CalendarProps &
|
|
|
826
826
|
export declare const DatePicker: React$1.ForwardRefExoticComponent<DatePickerProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
827
827
|
export declare const DateRangePicker: React$1.ForwardRefExoticComponent<DateRangePickerProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
828
828
|
export declare const Alert: React$1.ForwardRefExoticComponent<AlertProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
829
|
-
/** Show a toast; returns its id. Needs
|
|
829
|
+
/** Show a toast; returns its id. Needs `<Toaster />` mounted once. */
|
|
830
830
|
export declare function toast(opts: ToastOptions | string): string;
|
|
831
831
|
export declare namespace toast {
|
|
832
832
|
var dismiss: (id: string) => void;
|
|
@@ -857,7 +857,7 @@ export interface ContainerProps {
|
|
|
857
857
|
children?: React$1.ReactNode;
|
|
858
858
|
}
|
|
859
859
|
/** Min-width breakpoints in px, mirroring the aura-bp-* tokens. */
|
|
860
|
-
export declare
|
|
860
|
+
export declare const breakpoints: {
|
|
861
861
|
sm: 640;
|
|
862
862
|
md: 768;
|
|
863
863
|
lg: 1024;
|
|
@@ -935,7 +935,7 @@ export interface AuraStrings {
|
|
|
935
935
|
pageN: (p: number) => string;
|
|
936
936
|
accepts: (list?: string, max?: number | string) => string;
|
|
937
937
|
}
|
|
938
|
-
export declare
|
|
938
|
+
export declare const STRINGS: {
|
|
939
939
|
en: AuraStrings;
|
|
940
940
|
th: AuraStrings;
|
|
941
941
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jirawatpyk/aura-react",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.1",
|
|
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",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"theme": "node scripts/aura-theme.mjs",
|
|
37
37
|
"prepack": "npm run build",
|
|
38
38
|
"pretest:ssr": "node scripts/build.mjs",
|
|
39
|
-
"prethemes": "node scripts/build.mjs"
|
|
39
|
+
"prethemes": "node scripts/build.mjs",
|
|
40
|
+
"test:hydrate": "node scripts/hydrate-test.mjs"
|
|
40
41
|
},
|
|
41
42
|
"peerDependencies": {
|
|
42
43
|
"react": ">=18",
|
|
@@ -51,7 +52,8 @@
|
|
|
51
52
|
"react": "^18.3.1",
|
|
52
53
|
"react-dom": "^18.3.1",
|
|
53
54
|
"react-hook-form": "^7.53.0",
|
|
54
|
-
"typescript": "^5.6.0"
|
|
55
|
+
"typescript": "^5.6.0",
|
|
56
|
+
"@playwright/test": "^1.45.0"
|
|
55
57
|
},
|
|
56
58
|
"bin": {
|
|
57
59
|
"aura-theme": "scripts/aura-theme.mjs"
|