@jirawatpyk/aura-react 4.4.2 → 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 +9 -3
- package/dist/aura.bundle.js +2558 -2059
- package/dist/cjs/index.cjs +2556 -2059
- package/dist/esm/Button.js +9 -9
- package/dist/esm/Checkbox.js +41 -33
- package/dist/esm/Combobox.js +145 -127
- package/dist/esm/DataTable.js +637 -496
- package/dist/esm/DatePicker.js +379 -306
- package/dist/esm/Dialog.js +49 -60
- package/dist/esm/DropdownMenu.js +10 -13
- 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 +113 -85
- package/dist/esm/forms.js +144 -113
- package/dist/esm/internal.js +33 -23
- package/dist/esm/layout.js +114 -129
- package/dist/esm/layout2.js +69 -45
- package/dist/esm/locale.js +15 -9
- package/dist/esm/overlay.js +22 -19
- package/dist/esm/theme.js +101 -49
- package/dist/index.d.ts +916 -753
- package/package.json +11 -8
- package/scripts/aura-theme.mjs +1 -1
- package/src/theme.js +0 -147
package/dist/esm/TimePicker.js
CHANGED
|
@@ -5,55 +5,61 @@ import { cx, uid, useMaybeControlled, useMounted, useIsoLayoutEffect, useMergedR
|
|
|
5
5
|
import { useStrings } from "./locale.js";
|
|
6
6
|
import { Icon } from "./Icon.js";
|
|
7
7
|
import { Field } from "./forms.js";
|
|
8
|
-
const h = React.createElement;
|
|
9
8
|
function pad(n) {
|
|
10
9
|
return (n < 10 ? "0" : "") + n;
|
|
11
10
|
}
|
|
12
11
|
function toMin(t) {
|
|
13
|
-
|
|
12
|
+
const m = /^(\d{2}):(\d{2})$/.exec(t || "");
|
|
14
13
|
return m ? +m[1] * 60 + +m[2] : null;
|
|
15
14
|
}
|
|
16
15
|
function fromMin(n) {
|
|
17
16
|
return pad(Math.floor(n / 60)) + ":" + pad(n % 60);
|
|
18
17
|
}
|
|
19
18
|
function parseTime(text) {
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
let s = String(text || "").trim().toLowerCase().replace(/\s*(น\.?|นาฬิกา)$/, "").trim();
|
|
20
|
+
const pm = /\s*(pm|p\.m\.)$/.test(s), am = /\s*(am|a\.m\.)$/.test(s);
|
|
22
21
|
s = s.replace(/\s*(am|pm|a\.m\.|p\.m\.)$/, "");
|
|
23
|
-
|
|
22
|
+
const m = /^(\d{1,2})(?:[:.](\d{2}))?$/.exec(s) || /^(\d{1,2})(\d{2})$/.exec(s);
|
|
24
23
|
if (!m) return null;
|
|
25
|
-
|
|
24
|
+
let hh = +m[1], mm = m[2] ? +m[2] : 0;
|
|
26
25
|
if (pm && hh < 12) hh += 12;
|
|
27
26
|
if (am && hh === 12) hh = 0;
|
|
28
27
|
if (hh > 23 || mm > 59) return null;
|
|
29
28
|
return pad(hh) + ":" + pad(mm);
|
|
30
29
|
}
|
|
31
30
|
const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
const t = useStrings();
|
|
32
|
+
const auto = uid(), id = props.id || auto, listId = id + "-list";
|
|
33
|
+
const st = useMaybeControlled(
|
|
34
|
+
props.value,
|
|
35
|
+
props.defaultValue == null ? null : props.defaultValue,
|
|
36
|
+
props.onChange
|
|
37
|
+
);
|
|
38
|
+
const value = st[0];
|
|
39
|
+
const step = props.step || 30, lo = toMin(props.min) != null ? toMin(props.min) : 0, hi = toMin(props.max) != null ? toMin(props.max) : 24 * 60 - 1;
|
|
40
|
+
const slots = React.useMemo(
|
|
41
|
+
function() {
|
|
42
|
+
const out = [];
|
|
43
|
+
for (let m = lo; m <= hi; m += step) out.push(fromMin(m));
|
|
44
|
+
return out;
|
|
45
|
+
},
|
|
46
|
+
[lo, hi, step]
|
|
47
|
+
);
|
|
42
48
|
function blocked(v) {
|
|
43
|
-
|
|
49
|
+
const n = toMin(v);
|
|
44
50
|
return n == null || n < lo || n > hi || props.isTimeDisabled && props.isTimeDisabled(v);
|
|
45
51
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
const openState = React.useState(false), open = openState[0], setOpen = openState[1];
|
|
53
|
+
const editState = React.useState(null), editing = editState[0], setEditing = editState[1];
|
|
54
|
+
const aState = React.useState(0), active = aState[0], setActive = aState[1];
|
|
55
|
+
const errState = React.useState(null);
|
|
56
|
+
const pos = React.useState(null);
|
|
57
|
+
const boxRef = React.useRef(null), inputRef = React.useRef(null), listRef = React.useRef(null), inputMerged = useMergedRef(ref, inputRef);
|
|
58
|
+
const mounted = useMounted();
|
|
53
59
|
function nearest(v) {
|
|
54
|
-
|
|
60
|
+
const n = toMin(v);
|
|
55
61
|
if (n == null) return 0;
|
|
56
|
-
|
|
62
|
+
let best = 0;
|
|
57
63
|
slots.forEach(function(s, i) {
|
|
58
64
|
if (Math.abs(toMin(s) - n) < Math.abs(toMin(slots[best]) - n)) best = i;
|
|
59
65
|
});
|
|
@@ -61,35 +67,51 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
61
67
|
}
|
|
62
68
|
function place() {
|
|
63
69
|
if (!boxRef.current) return;
|
|
64
|
-
|
|
65
|
-
pos[1]({
|
|
70
|
+
const r = boxRef.current.getBoundingClientRect(), below = window.innerHeight - r.bottom - 8, up = below < 200 && r.top > below;
|
|
71
|
+
pos[1]({
|
|
72
|
+
left: r.left,
|
|
73
|
+
width: Math.max(r.width, 160),
|
|
74
|
+
top: up ? void 0 : r.bottom + 4,
|
|
75
|
+
bottom: up ? window.innerHeight - r.top + 4 : void 0,
|
|
76
|
+
maxHeight: Math.min(280, (up ? r.top : below) - 8)
|
|
77
|
+
});
|
|
66
78
|
}
|
|
67
|
-
useIsoLayoutEffect(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
window.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
79
|
+
useIsoLayoutEffect(
|
|
80
|
+
function() {
|
|
81
|
+
if (open) place();
|
|
82
|
+
},
|
|
83
|
+
[open]
|
|
84
|
+
);
|
|
85
|
+
React.useEffect(
|
|
86
|
+
function() {
|
|
87
|
+
if (!open) return;
|
|
88
|
+
function outside(e) {
|
|
89
|
+
if (boxRef.current && boxRef.current.contains(e.target) || listRef.current && listRef.current.contains(e.target))
|
|
90
|
+
return;
|
|
91
|
+
setOpen(false);
|
|
92
|
+
}
|
|
93
|
+
function onScroll(e) {
|
|
94
|
+
if (!listRef.current || !listRef.current.contains(e.target)) place();
|
|
95
|
+
}
|
|
96
|
+
document.addEventListener("pointerdown", outside, true);
|
|
97
|
+
window.addEventListener("scroll", onScroll, true);
|
|
98
|
+
window.addEventListener("resize", place);
|
|
99
|
+
return function() {
|
|
100
|
+
document.removeEventListener("pointerdown", outside, true);
|
|
101
|
+
window.removeEventListener("scroll", onScroll, true);
|
|
102
|
+
window.removeEventListener("resize", place);
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
[open]
|
|
106
|
+
);
|
|
107
|
+
React.useEffect(
|
|
108
|
+
function() {
|
|
109
|
+
if (!open || !listRef.current) return;
|
|
110
|
+
const el = listRef.current.querySelector('[data-idx="' + active + '"]');
|
|
111
|
+
if (el && el.scrollIntoView) el.scrollIntoView({ block: "nearest" });
|
|
112
|
+
},
|
|
113
|
+
[active, open]
|
|
114
|
+
);
|
|
93
115
|
function show() {
|
|
94
116
|
if (open || props.disabled || props.readOnly) return;
|
|
95
117
|
setActive(nearest(value || props.suggest || fromMin(lo)));
|
|
@@ -110,7 +132,7 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
110
132
|
return true;
|
|
111
133
|
}
|
|
112
134
|
function choose(i) {
|
|
113
|
-
|
|
135
|
+
const v = slots[i];
|
|
114
136
|
if (!v || blocked(v)) return;
|
|
115
137
|
commit(v);
|
|
116
138
|
setEditing(null);
|
|
@@ -119,25 +141,25 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
119
141
|
}
|
|
120
142
|
function commitTyped() {
|
|
121
143
|
if (editing == null) return;
|
|
122
|
-
|
|
144
|
+
const txt = editing.trim();
|
|
123
145
|
if (!txt) commit(null);
|
|
124
146
|
else {
|
|
125
|
-
|
|
147
|
+
const v = parseTime(txt);
|
|
126
148
|
if (v) commit(v);
|
|
127
149
|
else errState[1](t.timeInvalid);
|
|
128
150
|
}
|
|
129
151
|
setEditing(null);
|
|
130
152
|
}
|
|
131
153
|
function move(d) {
|
|
132
|
-
|
|
133
|
-
for (
|
|
154
|
+
let i = active;
|
|
155
|
+
for (let k = 0; k < slots.length; k++) {
|
|
134
156
|
i = Math.min(slots.length - 1, Math.max(0, i + d));
|
|
135
157
|
if (!blocked(slots[i])) break;
|
|
136
158
|
}
|
|
137
159
|
setActive(i);
|
|
138
160
|
}
|
|
139
161
|
function onKeyDown(e) {
|
|
140
|
-
|
|
162
|
+
const k = e.key;
|
|
141
163
|
if (k === "ArrowDown") {
|
|
142
164
|
e.preventDefault();
|
|
143
165
|
if (!open) show();
|
|
@@ -178,52 +200,56 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
178
200
|
if (open) setOpen(false);
|
|
179
201
|
}
|
|
180
202
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
})
|
|
215
|
-
)
|
|
216
|
-
),
|
|
203
|
+
const error = errState[0] || props.error;
|
|
204
|
+
const list = open && mounted && pos[0] ? createPortal(
|
|
205
|
+
/* @__PURE__ */ React.createElement("div", { ref: listRef, className: "aura-combo__popover aura-time__popover", style: pos[0] }, /* @__PURE__ */ React.createElement("ul", { id: listId, role: "listbox", "aria-label": props.label, className: "aura-combo__list" }, slots.map(function(s, i) {
|
|
206
|
+
const dis = blocked(s), sel = s === value;
|
|
207
|
+
return /* @__PURE__ */ React.createElement(
|
|
208
|
+
"li",
|
|
209
|
+
{
|
|
210
|
+
key: s,
|
|
211
|
+
id: id + "-opt-" + i,
|
|
212
|
+
role: "option",
|
|
213
|
+
"data-idx": i,
|
|
214
|
+
"aria-selected": sel,
|
|
215
|
+
"aria-disabled": dis || void 0,
|
|
216
|
+
className: cx(
|
|
217
|
+
"aura-combo__option aura-time__option",
|
|
218
|
+
i === active && "is-active",
|
|
219
|
+
sel && "is-selected",
|
|
220
|
+
dis && "is-disabled"
|
|
221
|
+
),
|
|
222
|
+
onPointerDown: function(e) {
|
|
223
|
+
e.preventDefault();
|
|
224
|
+
},
|
|
225
|
+
onClick: function() {
|
|
226
|
+
choose(i);
|
|
227
|
+
},
|
|
228
|
+
onPointerMove: function() {
|
|
229
|
+
if (active !== i) setActive(i);
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
/* @__PURE__ */ React.createElement("span", { className: "aura-combo__label" }, s),
|
|
233
|
+
sel ? /* @__PURE__ */ React.createElement(Icon, { name: "check", className: "aura-combo__check" }) : null
|
|
234
|
+
);
|
|
235
|
+
}))),
|
|
217
236
|
document.body
|
|
218
237
|
) : null;
|
|
219
|
-
return
|
|
238
|
+
return /* @__PURE__ */ React.createElement(
|
|
220
239
|
Field,
|
|
221
|
-
{
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
240
|
+
{
|
|
241
|
+
id,
|
|
242
|
+
label: props.label,
|
|
243
|
+
hint: props.hint,
|
|
244
|
+
error,
|
|
245
|
+
required: props.required,
|
|
246
|
+
optional: props.optional,
|
|
247
|
+
disabled: props.disabled,
|
|
248
|
+
className: props.className
|
|
249
|
+
},
|
|
250
|
+
/* @__PURE__ */ React.createElement("div", { ref: boxRef, className: cx("aura-input aura-combo aura-time has-icon", open && "is-open") }, /* @__PURE__ */ React.createElement(Icon, { name: "clock", className: "aura-input__icon" }), /* @__PURE__ */ React.createElement(
|
|
251
|
+
"input",
|
|
252
|
+
{
|
|
227
253
|
ref: inputMerged,
|
|
228
254
|
id,
|
|
229
255
|
type: "text",
|
|
@@ -245,7 +271,7 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
245
271
|
value: editing != null ? editing : value || "",
|
|
246
272
|
onChange: function(e) {
|
|
247
273
|
setEditing(e.target.value);
|
|
248
|
-
|
|
274
|
+
const v = parseTime(e.target.value);
|
|
249
275
|
if (v) {
|
|
250
276
|
if (!open) show();
|
|
251
277
|
setActive(nearest(v));
|
|
@@ -260,8 +286,10 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
260
286
|
setOpen(false);
|
|
261
287
|
}, 0);
|
|
262
288
|
}
|
|
263
|
-
}
|
|
264
|
-
|
|
289
|
+
}
|
|
290
|
+
), props.clearable !== false && value != null && !props.disabled ? /* @__PURE__ */ React.createElement(
|
|
291
|
+
"button",
|
|
292
|
+
{
|
|
265
293
|
type: "button",
|
|
266
294
|
className: "aura-combo__clear",
|
|
267
295
|
"aria-label": t.clear(props.label),
|
|
@@ -271,28 +299,28 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
271
299
|
setEditing(null);
|
|
272
300
|
if (inputRef.current) inputRef.current.focus();
|
|
273
301
|
}
|
|
274
|
-
},
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
onClick: function() {
|
|
286
|
-
if (open) setOpen(false);
|
|
287
|
-
else {
|
|
288
|
-
show();
|
|
289
|
-
inputRef.current && inputRef.current.focus();
|
|
290
|
-
}
|
|
291
|
-
}
|
|
302
|
+
},
|
|
303
|
+
/* @__PURE__ */ React.createElement(Icon, { name: "x" })
|
|
304
|
+
) : null, /* @__PURE__ */ React.createElement(
|
|
305
|
+
"button",
|
|
306
|
+
{
|
|
307
|
+
type: "button",
|
|
308
|
+
tabIndex: -1,
|
|
309
|
+
"aria-hidden": true,
|
|
310
|
+
className: "aura-combo__toggle",
|
|
311
|
+
onPointerDown: function(e) {
|
|
312
|
+
e.preventDefault();
|
|
292
313
|
},
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
314
|
+
onClick: function() {
|
|
315
|
+
if (open) setOpen(false);
|
|
316
|
+
else {
|
|
317
|
+
show();
|
|
318
|
+
inputRef.current && inputRef.current.focus();
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
/* @__PURE__ */ React.createElement(Icon, { name: "chevron-down" })
|
|
323
|
+
)),
|
|
296
324
|
list
|
|
297
325
|
);
|
|
298
326
|
});
|