@jirawatpyk/aura-react 5.1.1 → 5.3.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 +18 -1
- package/dist/aura.bundle.js +639 -74
- package/dist/cjs/index.cjs +639 -74
- package/dist/esm/Combobox.js +3 -2
- package/dist/esm/DataTable.js +72 -15
- package/dist/esm/DatePicker.js +4 -4
- package/dist/esm/FileUpload.js +2 -1
- package/dist/esm/Popover.js +15 -4
- package/dist/esm/Select.js +471 -15
- package/dist/esm/TimePicker.js +2 -1
- package/dist/esm/dates.js +28 -10
- package/dist/esm/strings.js +21 -0
- package/dist/esm/text.js +1 -0
- package/dist/index.d.cts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/server/index.cjs +45 -6
- package/dist/server/index.d.cts +6 -0
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.js +45 -6
- package/dist/styles.css +16 -2
- package/dist/styles.layer.css +16 -2
- package/package.json +1 -1
- package/scripts/aura-theme.mjs +31 -6
package/dist/esm/Select.js
CHANGED
|
@@ -1,9 +1,55 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
3
4
|
import { FIELD_KEYS, Field, describedBy } from "./Field.js";
|
|
4
5
|
import { Icon } from "./Icon.js";
|
|
5
|
-
import {
|
|
6
|
+
import { useDensity } from "./locale.js";
|
|
7
|
+
import { cx, omit, uid, useIsoLayoutEffect, useMergedRef, useMounted } from "./internal.js";
|
|
6
8
|
const h = React.createElement;
|
|
9
|
+
const FORM_KEYS = ["name", "form", "value", "defaultValue", "disabled", "autoComplete", "onInput", "onInvalid"];
|
|
10
|
+
const HANDLED_KEYS = FORM_KEYS.concat([
|
|
11
|
+
"onChange",
|
|
12
|
+
"onBlur",
|
|
13
|
+
"onFocus",
|
|
14
|
+
"onKeyDown",
|
|
15
|
+
"onClick",
|
|
16
|
+
"autoFocus",
|
|
17
|
+
"tabIndex",
|
|
18
|
+
"aria-label",
|
|
19
|
+
"aria-labelledby",
|
|
20
|
+
"aria-describedby",
|
|
21
|
+
"multiple",
|
|
22
|
+
"size"
|
|
23
|
+
]);
|
|
24
|
+
function pick(o, keys) {
|
|
25
|
+
const r = {};
|
|
26
|
+
for (const k of keys) if (k in o) r[k] = o[k];
|
|
27
|
+
return r;
|
|
28
|
+
}
|
|
29
|
+
function readItems(el) {
|
|
30
|
+
if (!el) return [];
|
|
31
|
+
return Array.prototype.map.call(el.options, function(o, i) {
|
|
32
|
+
const g = o.parentElement && o.parentElement.tagName === "OPTGROUP" ? o.parentElement : null;
|
|
33
|
+
return {
|
|
34
|
+
value: o.value,
|
|
35
|
+
label: o.textContent || "",
|
|
36
|
+
disabled: o.disabled || !!(g && g.disabled),
|
|
37
|
+
group: g ? g.label : null,
|
|
38
|
+
index: i
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function initialLabel(props) {
|
|
43
|
+
const opts = (props.options || []).map(function(o) {
|
|
44
|
+
return typeof o === "object" ? o : { value: o, label: o };
|
|
45
|
+
});
|
|
46
|
+
const v = props.value !== void 0 && props.value !== null ? String(props.value) : props.defaultValue !== void 0 && props.defaultValue !== null ? String(props.defaultValue) : props.placeholder ? "" : opts[0] ? opts[0].value : "";
|
|
47
|
+
const hit = opts.filter(function(o) {
|
|
48
|
+
return o.value === v;
|
|
49
|
+
})[0];
|
|
50
|
+
if (hit) return { label: hit.label, empty: false };
|
|
51
|
+
return { label: props.placeholder || "", empty: true };
|
|
52
|
+
}
|
|
7
53
|
const Select = React.forwardRef(function Select2(props, ref) {
|
|
8
54
|
const auto = uid(), id = props.id || auto;
|
|
9
55
|
const rest = omit(props, FIELD_KEYS.concat(["children"]));
|
|
@@ -16,10 +62,259 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
16
62
|
/* @__PURE__ */ React.createElement("option", { key: "__ph", value: "", disabled: true }, props.placeholder)
|
|
17
63
|
);
|
|
18
64
|
const extra = props.value === void 0 && props.defaultValue === void 0 && props.placeholder ? { defaultValue: "" } : {};
|
|
19
|
-
|
|
65
|
+
const native = !!props.multiple || props.size != null && props.size > 1;
|
|
66
|
+
const mounted = useMounted();
|
|
67
|
+
const live = !native && mounted;
|
|
68
|
+
const density = useDensity();
|
|
69
|
+
const selRef = React.useRef(null), trigRef = React.useRef(null), listRef = React.useRef(null);
|
|
70
|
+
const shown = React.useState(function() {
|
|
71
|
+
return initialLabel(props);
|
|
72
|
+
});
|
|
73
|
+
const openState = React.useState(false), open = openState[0];
|
|
74
|
+
const activeState = React.useState(-1), active = activeState[0];
|
|
75
|
+
const items = React.useState([]);
|
|
76
|
+
const pos = React.useState(null);
|
|
77
|
+
const typed = React.useRef({ text: "", at: 0 });
|
|
78
|
+
const sync = React.useCallback(function() {
|
|
79
|
+
const el = selRef.current;
|
|
80
|
+
if (!el) return;
|
|
81
|
+
const o = el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null;
|
|
82
|
+
const next = o ? { label: o.textContent || "", empty: o.value === "" } : { label: "", empty: true };
|
|
83
|
+
shown[1](function(cur) {
|
|
84
|
+
return cur.label === next.label && cur.empty === next.empty ? cur : next;
|
|
85
|
+
});
|
|
86
|
+
}, []);
|
|
87
|
+
const hook = React.useCallback(
|
|
88
|
+
function(el) {
|
|
89
|
+
selRef.current = el;
|
|
90
|
+
if (!el || native || el.__auraHooked) return;
|
|
91
|
+
el.__auraHooked = true;
|
|
92
|
+
const proto = HTMLSelectElement.prototype;
|
|
93
|
+
const pv = Object.getOwnPropertyDescriptor(proto, "value"), pi = Object.getOwnPropertyDescriptor(proto, "selectedIndex");
|
|
94
|
+
if (pv && pv.set && pv.get)
|
|
95
|
+
Object.defineProperty(el, "value", {
|
|
96
|
+
configurable: true,
|
|
97
|
+
get: function() {
|
|
98
|
+
return pv.get.call(el);
|
|
99
|
+
},
|
|
100
|
+
set: function(v) {
|
|
101
|
+
pv.set.call(el, v);
|
|
102
|
+
sync();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
if (pi && pi.set && pi.get)
|
|
106
|
+
Object.defineProperty(el, "selectedIndex", {
|
|
107
|
+
configurable: true,
|
|
108
|
+
get: function() {
|
|
109
|
+
return pi.get.call(el);
|
|
110
|
+
},
|
|
111
|
+
set: function(v) {
|
|
112
|
+
pi.set.call(el, v);
|
|
113
|
+
sync();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
el.focus = function(o) {
|
|
117
|
+
if (trigRef.current) trigRef.current.focus(o);
|
|
118
|
+
else proto.focus.call(el, o);
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
[native, sync]
|
|
122
|
+
);
|
|
123
|
+
const selMerged = useMergedRef(ref, hook);
|
|
124
|
+
React.useEffect(
|
|
125
|
+
function() {
|
|
126
|
+
const f = selRef.current && selRef.current.form;
|
|
127
|
+
if (!f || native) return;
|
|
128
|
+
function onReset() {
|
|
129
|
+
setTimeout(sync, 0);
|
|
130
|
+
}
|
|
131
|
+
f.addEventListener("reset", onReset);
|
|
132
|
+
return function() {
|
|
133
|
+
f.removeEventListener("reset", onReset);
|
|
134
|
+
};
|
|
135
|
+
},
|
|
136
|
+
[native, sync]
|
|
137
|
+
);
|
|
138
|
+
const focusedOnce = React.useRef(false);
|
|
139
|
+
React.useEffect(
|
|
140
|
+
function() {
|
|
141
|
+
if (!live || focusedOnce.current || !trigRef.current) return;
|
|
142
|
+
focusedOnce.current = true;
|
|
143
|
+
if (props.autoFocus || selRef.current && document.activeElement === selRef.current) trigRef.current.focus();
|
|
144
|
+
},
|
|
145
|
+
[live]
|
|
146
|
+
);
|
|
147
|
+
useIsoLayoutEffect(function() {
|
|
148
|
+
if (!live) return;
|
|
149
|
+
sync();
|
|
150
|
+
if (!open) return;
|
|
151
|
+
const now = readItems(selRef.current), was = items[0];
|
|
152
|
+
const same = now.length === was.length && now.every(function(it, i) {
|
|
153
|
+
const w = was[i];
|
|
154
|
+
return w.value === it.value && w.label === it.label && w.disabled === it.disabled && w.group === it.group;
|
|
155
|
+
});
|
|
156
|
+
if (same) return;
|
|
157
|
+
items[1](now);
|
|
158
|
+
if (!choices(now).length) {
|
|
159
|
+
close(false);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const hv = was[active] ? was[active].value : null;
|
|
163
|
+
const again = now.filter(function(it) {
|
|
164
|
+
return !it.disabled && it.value === hv;
|
|
165
|
+
})[0];
|
|
166
|
+
const cur = selRef.current ? selRef.current.selectedIndex : -1;
|
|
167
|
+
activeState[1](again ? again.index : now[cur] && !now[cur].disabled ? cur : choices(now)[0].index);
|
|
168
|
+
});
|
|
169
|
+
function choices(list) {
|
|
170
|
+
return list.filter(function(i) {
|
|
171
|
+
return !i.disabled;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function choose(it) {
|
|
175
|
+
const el = selRef.current;
|
|
176
|
+
if (!el || it.disabled) return;
|
|
177
|
+
if (el.value !== it.value) {
|
|
178
|
+
el.value = it.value;
|
|
179
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
180
|
+
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
181
|
+
}
|
|
182
|
+
sync();
|
|
183
|
+
close(true);
|
|
184
|
+
}
|
|
185
|
+
function openList(at) {
|
|
186
|
+
if (props.disabled || trigRef.current && trigRef.current.disabled) return;
|
|
187
|
+
const list = readItems(selRef.current);
|
|
188
|
+
const ok = choices(list);
|
|
189
|
+
if (!ok.length) return;
|
|
190
|
+
items[1](list);
|
|
191
|
+
const cur = selRef.current ? selRef.current.selectedIndex : -1;
|
|
192
|
+
let a = at === "first" ? ok[0].index : at === "last" ? ok[ok.length - 1].index : cur;
|
|
193
|
+
if (typeof at === "number") a = at;
|
|
194
|
+
if (a < 0 || !list[a] || list[a].disabled) a = ok[0].index;
|
|
195
|
+
activeState[1](a);
|
|
196
|
+
openState[1](true);
|
|
197
|
+
}
|
|
198
|
+
function close(focus) {
|
|
199
|
+
openState[1](false);
|
|
200
|
+
pos[1](null);
|
|
201
|
+
if (focus && trigRef.current) trigRef.current.focus();
|
|
202
|
+
}
|
|
203
|
+
function step(from, dir, list) {
|
|
204
|
+
for (let i = from + dir; i >= 0 && i < list.length; i += dir) if (!list[i].disabled) return i;
|
|
205
|
+
return from;
|
|
206
|
+
}
|
|
207
|
+
function typing() {
|
|
208
|
+
return !!typed.current.text && Date.now() - typed.current.at < 500;
|
|
209
|
+
}
|
|
210
|
+
function typeahead(ch, list, from) {
|
|
211
|
+
const now = Date.now(), t = typed.current;
|
|
212
|
+
t.text = now - t.at < 500 ? t.text + ch : ch;
|
|
213
|
+
t.at = now;
|
|
214
|
+
const q = t.text.toLocaleLowerCase();
|
|
215
|
+
for (let k = 1; k <= list.length; k++) {
|
|
216
|
+
const i = (from + (t.text.length > 1 ? 0 : 1) + k - 1 + list.length) % list.length;
|
|
217
|
+
if (!list[i].disabled && list[i].label.toLocaleLowerCase().indexOf(q) === 0) return i;
|
|
218
|
+
}
|
|
219
|
+
t.text = "";
|
|
220
|
+
return -1;
|
|
221
|
+
}
|
|
222
|
+
function onKeyDown(e) {
|
|
223
|
+
const k = e.key;
|
|
224
|
+
const printable = k.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey;
|
|
225
|
+
const search = printable && (k !== " " || typing());
|
|
226
|
+
if (!open) {
|
|
227
|
+
if (search) {
|
|
228
|
+
const list2 = readItems(selRef.current);
|
|
229
|
+
const i = typeahead(k, list2, selRef.current ? selRef.current.selectedIndex : -1);
|
|
230
|
+
e.preventDefault();
|
|
231
|
+
if (i >= 0) openList(i);
|
|
232
|
+
} else if (k === "ArrowDown" || k === "ArrowUp" || k === "Enter" || k === " ") {
|
|
233
|
+
e.preventDefault();
|
|
234
|
+
openList(k === "ArrowUp" && !(selRef.current && selRef.current.value) ? "last" : void 0);
|
|
235
|
+
}
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const list = items[0];
|
|
239
|
+
if (search) {
|
|
240
|
+
e.preventDefault();
|
|
241
|
+
const i = typeahead(k, list, active);
|
|
242
|
+
if (i >= 0) activeState[1](i);
|
|
243
|
+
} else if (k === "ArrowDown") {
|
|
244
|
+
e.preventDefault();
|
|
245
|
+
activeState[1](step(active, 1, list));
|
|
246
|
+
} else if (k === "ArrowUp") {
|
|
247
|
+
e.preventDefault();
|
|
248
|
+
activeState[1](step(active, -1, list));
|
|
249
|
+
} else if (k === "Home" || k === "PageUp") {
|
|
250
|
+
e.preventDefault();
|
|
251
|
+
activeState[1](k === "Home" ? step(-1, 1, list) : Math.max(step(-1, 1, list), step(active - 9, 1, list)));
|
|
252
|
+
} else if (k === "End" || k === "PageDown") {
|
|
253
|
+
e.preventDefault();
|
|
254
|
+
activeState[1](
|
|
255
|
+
k === "End" ? step(list.length, -1, list) : Math.min(step(list.length, -1, list), step(active + 9, -1, list))
|
|
256
|
+
);
|
|
257
|
+
} else if (k === "Enter" || k === " ") {
|
|
258
|
+
e.preventDefault();
|
|
259
|
+
if (list[active]) choose(list[active]);
|
|
260
|
+
} else if (k === "Escape") {
|
|
261
|
+
e.preventDefault();
|
|
262
|
+
e.stopPropagation();
|
|
263
|
+
close(true);
|
|
264
|
+
} else if (k === "Tab") {
|
|
265
|
+
close(false);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
useIsoLayoutEffect(
|
|
269
|
+
function() {
|
|
270
|
+
if (!open) return;
|
|
271
|
+
function place() {
|
|
272
|
+
const t = trigRef.current && trigRef.current.parentElement;
|
|
273
|
+
if (!t) return;
|
|
274
|
+
const r = t.getBoundingClientRect(), below = window.innerHeight - r.bottom - 8, above = r.top - 8, want = listRef.current ? listRef.current.scrollHeight : 320, up = below < Math.min(want, 200) && above > below;
|
|
275
|
+
pos[1]({
|
|
276
|
+
left: r.left,
|
|
277
|
+
width: r.width,
|
|
278
|
+
top: up ? void 0 : r.bottom + 4,
|
|
279
|
+
bottom: up ? window.innerHeight - r.top + 4 : void 0,
|
|
280
|
+
maxHeight: Math.min(320, (up ? above : below) - 4)
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
place();
|
|
284
|
+
function outside(e) {
|
|
285
|
+
const n = e.target;
|
|
286
|
+
if (listRef.current && listRef.current.contains(n)) return;
|
|
287
|
+
if (trigRef.current && trigRef.current.contains(n)) return;
|
|
288
|
+
close(false);
|
|
289
|
+
}
|
|
290
|
+
function onScroll(e) {
|
|
291
|
+
if (!listRef.current || !listRef.current.contains(e.target)) place();
|
|
292
|
+
}
|
|
293
|
+
document.addEventListener("pointerdown", outside, true);
|
|
294
|
+
window.addEventListener("scroll", onScroll, true);
|
|
295
|
+
window.addEventListener("resize", place);
|
|
296
|
+
return function() {
|
|
297
|
+
document.removeEventListener("pointerdown", outside, true);
|
|
298
|
+
window.removeEventListener("scroll", onScroll, true);
|
|
299
|
+
window.removeEventListener("resize", place);
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
[open]
|
|
303
|
+
);
|
|
304
|
+
React.useEffect(
|
|
305
|
+
function() {
|
|
306
|
+
if (!open || !listRef.current || active < 0) return;
|
|
307
|
+
const el = listRef.current.querySelector('[data-idx="' + active + '"]');
|
|
308
|
+
if (el && el.scrollIntoView) el.scrollIntoView({ block: "nearest" });
|
|
309
|
+
},
|
|
310
|
+
[open, active, pos[0] != null]
|
|
311
|
+
);
|
|
312
|
+
const described = [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0;
|
|
313
|
+
const field = (child) => /* @__PURE__ */ React.createElement(
|
|
20
314
|
Field,
|
|
21
315
|
{
|
|
22
316
|
id,
|
|
317
|
+
labelId: native ? void 0 : id + "-label",
|
|
23
318
|
label: props.label,
|
|
24
319
|
hint: props.hint,
|
|
25
320
|
error: props.error,
|
|
@@ -28,19 +323,180 @@ const Select = React.forwardRef(function Select2(props, ref) {
|
|
|
28
323
|
disabled: props.disabled,
|
|
29
324
|
className: props.className
|
|
30
325
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
326
|
+
child
|
|
327
|
+
);
|
|
328
|
+
if (!live)
|
|
329
|
+
return field(
|
|
330
|
+
/* @__PURE__ */ React.createElement("div", { className: cx("aura-input aura-select", props.icon && "has-icon") }, props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, h(
|
|
331
|
+
"select",
|
|
332
|
+
Object.assign(extra, rest, {
|
|
333
|
+
ref: native ? ref : selMerged,
|
|
334
|
+
id,
|
|
335
|
+
className: "aura-input__control",
|
|
336
|
+
required: props.required,
|
|
337
|
+
"aria-invalid": props.error ? true : void 0,
|
|
338
|
+
"aria-describedby": described
|
|
339
|
+
}),
|
|
340
|
+
opts,
|
|
341
|
+
props.children
|
|
342
|
+
), /* @__PURE__ */ React.createElement(Icon, { name: "chevron-down", className: "aura-select__chevron" }))
|
|
343
|
+
);
|
|
344
|
+
const listId = id + "-list", labelId = id + "-label";
|
|
345
|
+
const optId = function(i) {
|
|
346
|
+
return id + "-opt-" + i;
|
|
347
|
+
};
|
|
348
|
+
const labelledBy = rest["aria-labelledby"] || (props.label ? labelId : void 0);
|
|
349
|
+
const selIndex = selRef.current ? selRef.current.selectedIndex : -1;
|
|
350
|
+
const option = function(it) {
|
|
351
|
+
const sel = selIndex === it.index;
|
|
352
|
+
return /* @__PURE__ */ React.createElement(
|
|
353
|
+
"div",
|
|
354
|
+
{
|
|
355
|
+
key: it.index,
|
|
356
|
+
id: optId(it.index),
|
|
357
|
+
role: "option",
|
|
358
|
+
"data-idx": it.index,
|
|
359
|
+
"aria-selected": sel,
|
|
360
|
+
"aria-disabled": it.disabled || void 0,
|
|
361
|
+
className: cx(
|
|
362
|
+
"aura-combo__option",
|
|
363
|
+
it.index === active && "is-active",
|
|
364
|
+
sel && "is-selected",
|
|
365
|
+
it.disabled && "is-disabled"
|
|
366
|
+
),
|
|
367
|
+
onPointerDown: function(e) {
|
|
368
|
+
e.preventDefault();
|
|
369
|
+
},
|
|
370
|
+
onPointerMove: function() {
|
|
371
|
+
if (!it.disabled && active !== it.index) activeState[1](it.index);
|
|
372
|
+
},
|
|
373
|
+
onClick: function() {
|
|
374
|
+
choose(it);
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
/* @__PURE__ */ React.createElement("span", { className: "aura-combo__text" }, /* @__PURE__ */ React.createElement("span", { className: "aura-combo__label" }, it.label)),
|
|
378
|
+
sel ? /* @__PURE__ */ React.createElement(Icon, { name: "check", className: "aura-combo__check" }) : null
|
|
379
|
+
);
|
|
380
|
+
};
|
|
381
|
+
const runs = [];
|
|
382
|
+
items[0].forEach(function(it) {
|
|
383
|
+
if (it.value === "" && it.disabled) return;
|
|
384
|
+
const last = runs[runs.length - 1];
|
|
385
|
+
if (last && last.group === it.group) last.items.push(it);
|
|
386
|
+
else runs.push({ group: it.group, items: [it] });
|
|
387
|
+
});
|
|
388
|
+
const popup = open ? createPortal(
|
|
389
|
+
/* @__PURE__ */ React.createElement(
|
|
390
|
+
"div",
|
|
391
|
+
{
|
|
392
|
+
ref: listRef,
|
|
393
|
+
"data-density": density,
|
|
394
|
+
className: "aura-combo__popover aura-select__popover",
|
|
395
|
+
style: pos[0] ? {
|
|
396
|
+
left: pos[0].left,
|
|
397
|
+
minWidth: pos[0].width,
|
|
398
|
+
top: pos[0].top,
|
|
399
|
+
bottom: pos[0].bottom,
|
|
400
|
+
maxHeight: pos[0].maxHeight
|
|
401
|
+
} : { left: -9999, top: -9999 }
|
|
402
|
+
},
|
|
403
|
+
/* @__PURE__ */ React.createElement(
|
|
404
|
+
"div",
|
|
405
|
+
{
|
|
406
|
+
id: listId,
|
|
407
|
+
role: "listbox",
|
|
408
|
+
"aria-labelledby": labelledBy,
|
|
409
|
+
"aria-label": labelledBy ? void 0 : rest["aria-label"],
|
|
410
|
+
className: "aura-combo__list"
|
|
411
|
+
},
|
|
412
|
+
runs.map(function(r, n) {
|
|
413
|
+
if (r.group === null) return /* @__PURE__ */ React.createElement(React.Fragment, { key: "r" + n }, r.items.map(option));
|
|
414
|
+
const gid = id + "-group-" + n;
|
|
415
|
+
return /* @__PURE__ */ React.createElement("div", { key: "r" + n, role: "group", "aria-labelledby": gid }, /* @__PURE__ */ React.createElement("div", { id: gid, className: "aura-select__group" }, r.group), r.items.map(option));
|
|
416
|
+
})
|
|
417
|
+
)
|
|
418
|
+
),
|
|
419
|
+
document.body
|
|
420
|
+
) : null;
|
|
421
|
+
const userFocus = rest.onFocus, userBlur = rest.onBlur, userKey = rest.onKeyDown, userClick = rest.onClick;
|
|
422
|
+
return field(
|
|
423
|
+
/* @__PURE__ */ React.createElement(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
className: cx("aura-input aura-select aura-select--custom", props.icon && "has-icon", open && "is-open"),
|
|
427
|
+
"data-invalid": props.error ? "" : void 0
|
|
428
|
+
},
|
|
429
|
+
props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null,
|
|
430
|
+
h(
|
|
431
|
+
"select",
|
|
432
|
+
Object.assign(extra, pick(rest, FORM_KEYS), {
|
|
433
|
+
ref: selMerged,
|
|
434
|
+
id: id + "-select",
|
|
435
|
+
className: "aura-select__native",
|
|
436
|
+
tabIndex: -1,
|
|
437
|
+
"aria-hidden": true,
|
|
438
|
+
required: props.required,
|
|
439
|
+
onChange: function(e) {
|
|
440
|
+
sync();
|
|
441
|
+
if (props.onChange) props.onChange(e);
|
|
442
|
+
},
|
|
443
|
+
/* A browser focusing the <select> (the required bubble, a label click) hands focus to the button. */
|
|
444
|
+
onFocus: function() {
|
|
445
|
+
if (trigRef.current) trigRef.current.focus();
|
|
446
|
+
},
|
|
447
|
+
/* Only the blur the button reports (below): the <select>'s own, while it hands focus over, is not one. */
|
|
448
|
+
onBlur: function(e) {
|
|
449
|
+
if (!e.nativeEvent.isTrusted && userBlur) userBlur(e);
|
|
450
|
+
}
|
|
451
|
+
}),
|
|
452
|
+
opts,
|
|
453
|
+
props.children
|
|
454
|
+
),
|
|
455
|
+
/* @__PURE__ */ React.createElement(
|
|
456
|
+
"button",
|
|
457
|
+
{
|
|
458
|
+
...omit(rest, HANDLED_KEYS),
|
|
459
|
+
ref: trigRef,
|
|
460
|
+
type: "button",
|
|
461
|
+
role: "combobox",
|
|
462
|
+
form: id + "-no-form",
|
|
463
|
+
className: "aura-input__control aura-select__trigger",
|
|
464
|
+
disabled: props.disabled,
|
|
465
|
+
tabIndex: rest.tabIndex,
|
|
466
|
+
"aria-haspopup": "listbox",
|
|
467
|
+
"aria-expanded": open,
|
|
468
|
+
"aria-controls": open ? listId : void 0,
|
|
469
|
+
"aria-activedescendant": open && active >= 0 ? optId(active) : void 0,
|
|
470
|
+
id,
|
|
471
|
+
"aria-label": rest["aria-label"],
|
|
472
|
+
"aria-labelledby": rest["aria-labelledby"],
|
|
473
|
+
"aria-required": props.required || void 0,
|
|
474
|
+
"aria-invalid": props.error ? true : void 0,
|
|
475
|
+
"aria-describedby": described,
|
|
476
|
+
onFocus: function(e) {
|
|
477
|
+
if (userFocus) userFocus(e);
|
|
478
|
+
},
|
|
479
|
+
onClick: function(e) {
|
|
480
|
+
if (userClick) userClick(e);
|
|
481
|
+
if (e.defaultPrevented) return;
|
|
482
|
+
if (open) close(true);
|
|
483
|
+
else openList();
|
|
484
|
+
},
|
|
485
|
+
onKeyDown: function(e) {
|
|
486
|
+
if (userKey) userKey(e);
|
|
487
|
+
if (!e.defaultPrevented) onKeyDown(e);
|
|
488
|
+
},
|
|
489
|
+
onBlur: function(e) {
|
|
490
|
+
if (listRef.current && e.relatedTarget && listRef.current.contains(e.relatedTarget)) return;
|
|
491
|
+
if (open) close(false);
|
|
492
|
+
if (selRef.current) selRef.current.dispatchEvent(new FocusEvent("focusout", { bubbles: true }));
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
/* @__PURE__ */ React.createElement("span", { id: id + "-value", className: cx("aura-select__value", shown[0].empty && "is-placeholder") }, shown[0].label || " ")
|
|
496
|
+
),
|
|
497
|
+
/* @__PURE__ */ React.createElement(Icon, { name: "chevron-down", className: "aura-select__chevron" }),
|
|
498
|
+
popup
|
|
499
|
+
)
|
|
44
500
|
);
|
|
45
501
|
});
|
|
46
502
|
export {
|
package/dist/esm/TimePicker.js
CHANGED
|
@@ -113,7 +113,8 @@ const TimePicker = React.forwardRef(function TimePicker2(props, ref) {
|
|
|
113
113
|
return true;
|
|
114
114
|
}
|
|
115
115
|
if (blocked(v)) {
|
|
116
|
-
|
|
116
|
+
const n = toMin(v);
|
|
117
|
+
errState[1](n != null && n >= lo && n <= hi ? t.timeUnavailable : t.timeOutOfRange(fromMin(lo), fromMin(hi)));
|
|
117
118
|
return false;
|
|
118
119
|
}
|
|
119
120
|
errState[1](null);
|
package/dist/esm/dates.js
CHANGED
|
@@ -4,20 +4,29 @@ const pad = function(n) {
|
|
|
4
4
|
return (n < 10 ? "0" : "") + n;
|
|
5
5
|
};
|
|
6
6
|
function toISO(d) {
|
|
7
|
-
|
|
7
|
+
if (!d) return null;
|
|
8
|
+
const y = String(d.getFullYear());
|
|
9
|
+
return ("000" + y).slice(-Math.max(4, y.length)) + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate());
|
|
10
|
+
}
|
|
11
|
+
function makeDate(y, monthIndex2, day) {
|
|
12
|
+
const d = new Date(2e3, 0, 1);
|
|
13
|
+
d.setFullYear(y, monthIndex2, day);
|
|
14
|
+
return d;
|
|
8
15
|
}
|
|
9
16
|
function fromISO(s) {
|
|
10
17
|
if (!s) return null;
|
|
11
18
|
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
|
|
12
|
-
|
|
19
|
+
if (!m) return null;
|
|
20
|
+
const d = makeDate(+m[1], +m[2] - 1, +m[3]);
|
|
21
|
+
return d.getMonth() === +m[2] - 1 && d.getDate() === +m[3] ? d : null;
|
|
13
22
|
}
|
|
14
23
|
function addDays(d, n) {
|
|
15
|
-
return
|
|
24
|
+
return makeDate(d.getFullYear(), d.getMonth(), d.getDate() + n);
|
|
16
25
|
}
|
|
17
26
|
function addMonths(d, n) {
|
|
18
|
-
const t =
|
|
19
|
-
const last =
|
|
20
|
-
return
|
|
27
|
+
const t = makeDate(d.getFullYear(), d.getMonth() + n, 1);
|
|
28
|
+
const last = makeDate(t.getFullYear(), t.getMonth() + 1, 0).getDate();
|
|
29
|
+
return makeDate(t.getFullYear(), t.getMonth(), Math.min(d.getDate(), last));
|
|
21
30
|
}
|
|
22
31
|
function same(a, b) {
|
|
23
32
|
return !!a && !!b && a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
@@ -125,7 +134,15 @@ function monthIndex(word) {
|
|
|
125
134
|
return MONTHS[k] != null ? MONTHS[k] : -1;
|
|
126
135
|
}
|
|
127
136
|
function parseDate(text) {
|
|
128
|
-
const
|
|
137
|
+
const raw = String(text || "").trim();
|
|
138
|
+
const gregorian = /ค\.ศ\.|\d\s*(AD|CE)\b|^\s*(AD|CE)\s/i.test(raw);
|
|
139
|
+
let s = raw.replace(/พ\.ศ\.|ค\.ศ\./g, " ").replace(/(\d)\s*(BE|AD|CE)\b/gi, "$1 ").replace(/^\s*(BE|AD|CE)\s+/i, " ").replace(/\s+/g, " ").trim();
|
|
140
|
+
const eight = /^(\d{2})(\d{2})(\d{4})$/.exec(s);
|
|
141
|
+
if (eight) {
|
|
142
|
+
const a = +eight[3] >= 1e3 ? parseDate(eight[1] + "/" + eight[2] + "/" + eight[3] + (gregorian ? " \u0E04.\u0E28." : "")) : null;
|
|
143
|
+
if (a) return a;
|
|
144
|
+
s = s.slice(0, 4) + "-" + s.slice(4, 6) + "-" + s.slice(6);
|
|
145
|
+
}
|
|
129
146
|
let m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(s), y, mo, d;
|
|
130
147
|
if (m) {
|
|
131
148
|
y = +m[1];
|
|
@@ -135,13 +152,13 @@ function parseDate(text) {
|
|
|
135
152
|
d = +m[1];
|
|
136
153
|
mo = +m[2];
|
|
137
154
|
y = +m[3];
|
|
138
|
-
} else if ((m = /^(\d{1,2})\s+(\S+)\s+(\d{4})$/.exec(s
|
|
155
|
+
} else if ((m = /^(\d{1,2})\s+(\S+)\s+(\d{4})$/.exec(s)) && monthIndex(m[2]) >= 0) {
|
|
139
156
|
d = +m[1];
|
|
140
157
|
mo = monthIndex(m[2]) + 1;
|
|
141
158
|
y = +m[3];
|
|
142
159
|
} else return null;
|
|
143
|
-
if (y >= 2400) y -= 543;
|
|
144
|
-
const dt =
|
|
160
|
+
if (y >= 2400 && !gregorian) y -= 543;
|
|
161
|
+
const dt = makeDate(y, mo - 1, d);
|
|
145
162
|
return dt.getMonth() === mo - 1 && dt.getDate() === d ? toISO(dt) : null;
|
|
146
163
|
}
|
|
147
164
|
function todayIn(timeZone) {
|
|
@@ -173,6 +190,7 @@ export {
|
|
|
173
190
|
formatDate,
|
|
174
191
|
fromISO,
|
|
175
192
|
localeTag,
|
|
193
|
+
makeDate,
|
|
176
194
|
monthIndex,
|
|
177
195
|
pad,
|
|
178
196
|
parseDate,
|
package/dist/esm/strings.js
CHANGED
|
@@ -74,6 +74,12 @@ const STRINGS = {
|
|
|
74
74
|
page: function(p, total) {
|
|
75
75
|
return "Page " + p + " of " + total;
|
|
76
76
|
},
|
|
77
|
+
rangeOpen: function(a, b) {
|
|
78
|
+
return a + "\u2013" + b + " of many";
|
|
79
|
+
},
|
|
80
|
+
pageOpen: function(p) {
|
|
81
|
+
return "Page " + p;
|
|
82
|
+
},
|
|
77
83
|
prevPage: "Previous page",
|
|
78
84
|
nextPage: "Next page",
|
|
79
85
|
totals: "Totals",
|
|
@@ -87,6 +93,7 @@ const STRINGS = {
|
|
|
87
93
|
timeOutOfRange: function(a, b) {
|
|
88
94
|
return "Choose a time between " + a + " and " + b;
|
|
89
95
|
},
|
|
96
|
+
timeUnavailable: "That time isn't available. Choose another.",
|
|
90
97
|
dropFiles: "Drag files here or",
|
|
91
98
|
browse: "Choose files",
|
|
92
99
|
browseOne: "Choose a file",
|
|
@@ -188,6 +195,12 @@ const STRINGS = {
|
|
|
188
195
|
page: function(p, total) {
|
|
189
196
|
return "\u0E2B\u0E19\u0E49\u0E32 " + p + " / " + total;
|
|
190
197
|
},
|
|
198
|
+
rangeOpen: function(a, b) {
|
|
199
|
+
return a + "\u2013" + b + " \u0E08\u0E32\u0E01\u0E2B\u0E25\u0E32\u0E22\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23";
|
|
200
|
+
},
|
|
201
|
+
pageOpen: function(p) {
|
|
202
|
+
return "\u0E2B\u0E19\u0E49\u0E32 " + p;
|
|
203
|
+
},
|
|
191
204
|
prevPage: "\u0E2B\u0E19\u0E49\u0E32\u0E01\u0E48\u0E2D\u0E19\u0E2B\u0E19\u0E49\u0E32",
|
|
192
205
|
nextPage: "\u0E2B\u0E19\u0E49\u0E32\u0E16\u0E31\u0E14\u0E44\u0E1B",
|
|
193
206
|
totals: "\u0E23\u0E27\u0E21",
|
|
@@ -201,6 +214,7 @@ const STRINGS = {
|
|
|
201
214
|
timeOutOfRange: function(a, b) {
|
|
202
215
|
return "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E40\u0E27\u0E25\u0E32\u0E23\u0E30\u0E2B\u0E27\u0E48\u0E32\u0E07 " + a + "\u2013" + b + " \u0E19.";
|
|
203
216
|
},
|
|
217
|
+
timeUnavailable: "\u0E40\u0E27\u0E25\u0E32\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E27\u0E48\u0E32\u0E07 \u0E40\u0E25\u0E37\u0E2D\u0E01\u0E40\u0E27\u0E25\u0E32\u0E2D\u0E37\u0E48\u0E19",
|
|
204
218
|
dropFiles: "\u0E25\u0E32\u0E01\u0E44\u0E1F\u0E25\u0E4C\u0E21\u0E32\u0E27\u0E32\u0E07 \u0E2B\u0E23\u0E37\u0E2D",
|
|
205
219
|
browse: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C",
|
|
206
220
|
browseOne: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C",
|
|
@@ -302,6 +316,12 @@ const STRINGS = {
|
|
|
302
316
|
page: function(p, total) {
|
|
303
317
|
return "Sida " + p + " av " + total;
|
|
304
318
|
},
|
|
319
|
+
rangeOpen: function(a, b) {
|
|
320
|
+
return a + "\u2013" + b + " av m\xE5nga";
|
|
321
|
+
},
|
|
322
|
+
pageOpen: function(p) {
|
|
323
|
+
return "Sida " + p;
|
|
324
|
+
},
|
|
305
325
|
prevPage: "F\xF6reg\xE5ende sida",
|
|
306
326
|
nextPage: "N\xE4sta sida",
|
|
307
327
|
totals: "Summa",
|
|
@@ -315,6 +335,7 @@ const STRINGS = {
|
|
|
315
335
|
timeOutOfRange: function(a, b) {
|
|
316
336
|
return "V\xE4lj en tid mellan " + a + " och " + b;
|
|
317
337
|
},
|
|
338
|
+
timeUnavailable: "Den tiden \xE4r inte ledig. V\xE4lj en annan.",
|
|
318
339
|
dropFiles: "Dra filer hit eller",
|
|
319
340
|
browse: "V\xE4lj filer",
|
|
320
341
|
browseOne: "V\xE4lj en fil",
|
package/dist/esm/text.js
CHANGED
|
@@ -19,6 +19,7 @@ function parseTime(text) {
|
|
|
19
19
|
const m = /^(\d{1,2})(?:[:.](\d{2}))?$/.exec(s) || /^(\d{1,2})(\d{2})$/.exec(s);
|
|
20
20
|
if (!m) return null;
|
|
21
21
|
let hh = +m[1], mm = m[2] ? +m[2] : 0;
|
|
22
|
+
if ((am || pm) && (hh < 1 || hh > 12)) return null;
|
|
22
23
|
if (pm && hh < 12) hh += 12;
|
|
23
24
|
if (am && hh === 12) hh = 0;
|
|
24
25
|
if (hh > 23 || mm > 59) return null;
|