@jirawatpyk/aura-react 5.1.0 → 5.1.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.
Files changed (42) hide show
  1. package/dist/aura.bundle.js +418 -148
  2. package/dist/cjs/index.cjs +418 -148
  3. package/dist/esm/AppShell.js +10 -2
  4. package/dist/esm/Avatar.js +4 -3
  5. package/dist/esm/BottomNav.js +2 -1
  6. package/dist/esm/Checkbox.js +3 -2
  7. package/dist/esm/Combobox.js +19 -19
  8. package/dist/esm/Command.js +1 -0
  9. package/dist/esm/DataTable.js +44 -14
  10. package/dist/esm/DatePicker.js +81 -18
  11. package/dist/esm/DropdownMenu.js +12 -0
  12. package/dist/esm/FileUpload.js +15 -0
  13. package/dist/esm/FormErrorSummary.js +19 -4
  14. package/dist/esm/Menu.js +20 -7
  15. package/dist/esm/NumberField.js +3 -1
  16. package/dist/esm/Pagination.js +3 -3
  17. package/dist/esm/Popover.js +11 -1
  18. package/dist/esm/RadioGroup.js +14 -1
  19. package/dist/esm/SideNav.js +2 -1
  20. package/dist/esm/Switch.js +1 -1
  21. package/dist/esm/Table.js +3 -2
  22. package/dist/esm/Tabs.js +11 -7
  23. package/dist/esm/TextField.js +2 -2
  24. package/dist/esm/Textarea.js +2 -2
  25. package/dist/esm/ThemeStyle.js +13 -3
  26. package/dist/esm/Toaster.js +1 -0
  27. package/dist/esm/Tooltip.js +54 -29
  28. package/dist/esm/colorScheme.js +7 -3
  29. package/dist/esm/colorSchemeScript.js +3 -3
  30. package/dist/esm/dates.js +6 -3
  31. package/dist/esm/internal.js +18 -7
  32. package/dist/esm/locale.js +6 -5
  33. package/dist/esm/theme.js +3 -1
  34. package/dist/esm/useModal.js +31 -8
  35. package/dist/index.d.cts +1508 -0
  36. package/dist/index.d.ts +1 -1
  37. package/dist/server/index.cjs +6 -4
  38. package/dist/server/index.d.cts +176 -0
  39. package/dist/server/index.js +6 -4
  40. package/dist/styles.css +19 -3
  41. package/dist/styles.layer.css +19 -3
  42. package/package.json +19 -8
@@ -46,6 +46,21 @@ const FileUpload = React.forwardRef(function FileUpload2(props, ref) {
46
46
  });
47
47
  };
48
48
  }, []);
49
+ React.useEffect(
50
+ function() {
51
+ const el = inputRef.current;
52
+ if (!el || !props.name || typeof DataTransfer === "undefined") return;
53
+ try {
54
+ const dt = new DataTransfer();
55
+ items.forEach(function(i) {
56
+ if (i.file && !i.error) dt.items.add(i.file);
57
+ });
58
+ el.files = dt.files;
59
+ } catch (e) {
60
+ }
61
+ },
62
+ [items, props.name]
63
+ );
49
64
  function thumb(it) {
50
65
  if (!it.file || !/^image\//.test(it.type || "") || typeof URL === "undefined" || !URL.createObjectURL) return null;
51
66
  if (!urls.current[it.id]) urls.current[it.id] = URL.createObjectURL(it.file);
@@ -6,15 +6,30 @@ import { useStrings } from "./locale.js";
6
6
  function items(errors) {
7
7
  if (Array.isArray(errors)) return errors;
8
8
  const out = [];
9
- for (const k in errors || {}) {
10
- const e = errors[k];
11
- if (e && e.message) out.push({ field: k, message: e.message });
9
+ function walk(e, path, depth) {
10
+ if (!e || typeof e !== "object" || depth > 8) return;
11
+ const o = e;
12
+ if (o.message) out.push({ field: path, message: o.message });
13
+ for (const k in o) {
14
+ if (k === "ref" || k === "type" || k === "types" || k === "message") continue;
15
+ walk(o[k], path ? path + "." + k : k, depth + 1);
16
+ }
12
17
  }
18
+ walk(errors, "", 0);
13
19
  return out;
14
20
  }
15
21
  function fieldElement(field) {
16
22
  if (typeof document === "undefined") return null;
17
- return document.getElementById(field) || document.querySelector('[name="' + field.replace(/"/g, '\\"') + '"]');
23
+ const byId = document.getElementById(field);
24
+ if (byId) return byId;
25
+ const named = document.querySelector('[name="' + field.replace(/"/g, '\\"') + '"]');
26
+ if (named && named.getAttribute("type") === "hidden") {
27
+ const box = named.closest(".aura-field") || named.parentElement;
28
+ return box && box.querySelector(
29
+ 'input:not([type="hidden"]), [role="combobox"], select, textarea, button:not([tabindex="-1"])'
30
+ ) || named;
31
+ }
32
+ return named;
18
33
  }
19
34
  const FormErrorSummary = React.forwardRef(
20
35
  function FormErrorSummary2(props, ref) {
package/dist/esm/Menu.js CHANGED
@@ -15,11 +15,17 @@ const Menu = React.forwardRef(function Menu2(props, ref) {
15
15
  function() {
16
16
  const a = props.anchor, m = own.current;
17
17
  if (!a || !m) return;
18
- const r = a.getBoundingClientRect(), mh = m.offsetHeight, mw = m.offsetWidth;
19
- let top = r.bottom + 4;
20
- if (top + mh > window.innerHeight - 8 && r.top - mh - 4 > 8) top = r.top - mh - 4;
18
+ const r = a.getBoundingClientRect(), mh = m.scrollHeight, mw = m.offsetWidth, below = window.innerHeight - r.bottom - 12, above = r.top - 12;
19
+ let top = r.bottom + 4, maxHeight;
20
+ if (mh > below) {
21
+ if (mh <= above) top = r.top - mh - 4;
22
+ else if (above > below) {
23
+ maxHeight = above;
24
+ top = r.top - above - 4;
25
+ } else maxHeight = below;
26
+ }
21
27
  const left = Math.max(8, Math.min(r.right - mw, window.innerWidth - mw - 8));
22
- setPos({ top, left });
28
+ setPos({ top, left, maxHeight });
23
29
  },
24
30
  [props.anchor, mounted]
25
31
  );
@@ -63,6 +69,9 @@ const Menu = React.forwardRef(function Menu2(props, ref) {
63
69
  } else if (e.key === "End") {
64
70
  e.preventDefault();
65
71
  list[list.length - 1].focus();
72
+ } else if (e.key === " " && document.activeElement && document.activeElement.tagName === "A") {
73
+ e.preventDefault();
74
+ document.activeElement.click();
66
75
  } else if (e.key === "Escape") {
67
76
  e.preventDefault();
68
77
  props.onClose(true);
@@ -103,9 +112,9 @@ const Menu = React.forwardRef(function Menu2(props, ref) {
103
112
  tabIndex: -1,
104
113
  role: "menuitem",
105
114
  className: cls,
106
- onClick: function() {
115
+ onClick: function(e) {
107
116
  if (it.onSelect) it.onSelect();
108
- props.onClose(false);
117
+ props.onClose(e.detail === 0);
109
118
  }
110
119
  },
111
120
  body
@@ -136,7 +145,11 @@ const Menu = React.forwardRef(function Menu2(props, ref) {
136
145
  "aria-label": props.label,
137
146
  className: "aura-menu",
138
147
  onKeyDown,
139
- style: { top: pos ? pos.top : -9999, left: pos ? pos.left : -9999 }
148
+ style: {
149
+ top: pos ? pos.top : -9999,
150
+ left: pos ? pos.left : -9999,
151
+ maxHeight: pos && pos.maxHeight ? pos.maxHeight : void 0
152
+ }
140
153
  },
141
154
  groupItems(items).map(function(block, bi) {
142
155
  const rendered = block.items.map(function(x) {
@@ -10,7 +10,9 @@ function decimalsOf(n) {
10
10
  return i < 0 ? 0 : s.length - i - 1;
11
11
  }
12
12
  function parse(text) {
13
- const s = text.replace(/[,\s ]/g, "");
13
+ let t = text.trim();
14
+ if (t.indexOf(".") < 0 && /^-?\d+,\d+$/.test(t.replace(/[\s ]/g, "")) && !/,\d{3}$/.test(t)) t = t.replace(",", ".");
15
+ const s = t.replace(/[,\s ]/g, "");
14
16
  if (!/^-?(\d+\.?\d*|\.\d+)$/.test(s)) return NaN;
15
17
  return Number(s);
16
18
  }
@@ -2,7 +2,7 @@
2
2
  import * as React from "react";
3
3
  import { Icon } from "./Icon.js";
4
4
  import { IconButton } from "./IconButton.js";
5
- import { cx, useMaybeControlled } from "./internal.js";
5
+ import { cx, plainClick, useMaybeControlled } from "./internal.js";
6
6
  import { useLinkComponent, useStrings } from "./locale.js";
7
7
  function pageList(page, count, sib) {
8
8
  let out = [], lo = Math.max(2, page - sib), hi = Math.min(count - 1, page + sib);
@@ -47,7 +47,7 @@ const Pagination = React.forwardRef(function Pagination2(props, ref) {
47
47
  {
48
48
  href: link(p),
49
49
  onClick: function(e) {
50
- if (props.onChange) {
50
+ if (props.onChange && plainClick(e)) {
51
51
  e.preventDefault();
52
52
  go(p);
53
53
  }
@@ -89,7 +89,7 @@ const Pagination = React.forwardRef(function Pagination2(props, ref) {
89
89
  "aria-label": label,
90
90
  title: label,
91
91
  onClick: function(e) {
92
- if (props.onChange) {
92
+ if (props.onChange && plainClick(e)) {
93
93
  e.preventDefault();
94
94
  go(p);
95
95
  }
@@ -30,6 +30,7 @@ const Popover = React.forwardRef(function Popover2(props, ref) {
30
30
  const open = !!st[0];
31
31
  const wrap = React.useRef(null), pop = React.useRef(null), popMerged = useMergedRef(ref, pop);
32
32
  const pos = React.useState(null), mounted = useMounted();
33
+ const inTree = React.useRef(false);
33
34
  function trigger() {
34
35
  return wrap.current && (wrap.current.querySelector('button, [role="button"], a, input') || wrap.current.firstElementChild);
35
36
  }
@@ -63,13 +64,19 @@ const Popover = React.forwardRef(function Popover2(props, ref) {
63
64
  const f = pop.current.querySelector("[data-autofocus]") || pop.current.querySelector(FOCUSABLE);
64
65
  (f || pop.current).focus();
65
66
  }
67
+ let timer;
66
68
  function outside(e) {
67
69
  if (pop.current && pop.current.contains(e.target)) return;
68
70
  if (wrap.current && wrap.current.contains(e.target)) return;
69
- close(false);
71
+ inTree.current = false;
72
+ clearTimeout(timer);
73
+ timer = setTimeout(function() {
74
+ if (!inTree.current) close(false);
75
+ }, 0);
70
76
  }
71
77
  document.addEventListener("pointerdown", outside, true);
72
78
  return function() {
79
+ clearTimeout(timer);
73
80
  document.removeEventListener("pointerdown", outside, true);
74
81
  };
75
82
  },
@@ -88,6 +95,9 @@ const Popover = React.forwardRef(function Popover2(props, ref) {
88
95
  "aria-label": props.title ? void 0 : props.label,
89
96
  "aria-labelledby": props.title ? id + "-title" : void 0,
90
97
  tabIndex: -1,
98
+ onPointerDownCapture: function() {
99
+ inTree.current = true;
100
+ },
91
101
  className: cx("aura-popover", pos[0] && "is-" + pos[0].side, props.className),
92
102
  style: Object.assign(
93
103
  { top: pos[0] ? pos[0].top : -9999, left: pos[0] ? pos[0].left : -9999 },
@@ -11,10 +11,22 @@ const RadioGroup = React.forwardRef(function RadioGroup2(props, ref) {
11
11
  props.onChange
12
12
  );
13
13
  const name = props.name || id;
14
+ const setRef = React.useCallback(
15
+ function(el) {
16
+ if (el)
17
+ el.focus = function(opts) {
18
+ const r = el.querySelector('input[type="radio"]:checked') || el.querySelector('input[type="radio"]:not(:disabled)');
19
+ if (r) r.focus(opts);
20
+ };
21
+ if (typeof ref === "function") ref(el);
22
+ else if (ref) ref.current = el;
23
+ },
24
+ [ref]
25
+ );
14
26
  return /* @__PURE__ */ React.createElement(
15
27
  "fieldset",
16
28
  {
17
- ref,
29
+ ref: setRef,
18
30
  className: cx("aura-field aura-radio-group", props.error && "is-invalid", props.className),
19
31
  "aria-describedby": describedBy(id, props),
20
32
  "aria-invalid": props.error ? true : void 0,
@@ -31,6 +43,7 @@ const RadioGroup = React.forwardRef(function RadioGroup2(props, ref) {
31
43
  name,
32
44
  value: v.value,
33
45
  disabled: v.disabled,
46
+ required: props.required || void 0,
34
47
  checked: st[0] === v.value,
35
48
  onChange: function() {
36
49
  st[1](v.value);
@@ -3,7 +3,7 @@ import * as React from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { Icon } from "./Icon.js";
5
5
  import { IconButton } from "./IconButton.js";
6
- import { cx, uid, useMaybeControlled } from "./internal.js";
6
+ import { cx, plainClick, uid, useMaybeControlled } from "./internal.js";
7
7
  import { useLinkComponent, useStrings } from "./locale.js";
8
8
  function contains(it, id) {
9
9
  return !!id && !!it.children && it.children.some(function(c) {
@@ -154,6 +154,7 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
154
154
  style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
155
155
  onClick: function(e) {
156
156
  if (!it.href) e.preventDefault();
157
+ else if (!plainClick(e)) return;
157
158
  st[1](it.id);
158
159
  }
159
160
  };
@@ -34,7 +34,7 @@ const Switch = React.forwardRef(function Switch2(props, ref) {
34
34
  },
35
35
  /* @__PURE__ */ React.createElement("span", { className: "aura-switch__thumb" })
36
36
  ),
37
- props.label ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : null
37
+ props.label ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React.createElement("label", { className: "aura-choice__label", id: id + "-label", htmlFor: id }, props.label), props.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__desc", id: id + "-desc" }, props.description) : null) : props.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-sr-only", id: id + "-desc" }, props.description) : null
38
38
  );
39
39
  });
40
40
  export {
package/dist/esm/Table.js CHANGED
@@ -26,8 +26,9 @@ const Table = React.forwardRef(function Table2(props, ref) {
26
26
  className: "aura-tbl-wrap",
27
27
  "data-density": density,
28
28
  tabIndex: scrolls ? 0 : void 0,
29
- role: scrolls ? "region" : void 0,
30
- "aria-labelledby": scrolls && caption != null ? capId : void 0
29
+ role: scrolls && (caption != null || rest["aria-label"]) ? "region" : void 0,
30
+ "aria-labelledby": scrolls && caption != null ? capId : void 0,
31
+ "aria-label": scrolls && caption == null ? rest["aria-label"] : void 0
31
32
  },
32
33
  /* @__PURE__ */ React.createElement("table", { ref, className: cx("aura-tbl", className), ...rest }, caption != null ? /* @__PURE__ */ React.createElement("caption", { id: capId, className: cx("aura-tbl__caption", captionHidden && "aura-sr-only") }, caption) : null, children)
33
34
  );
package/dist/esm/Tabs.js CHANGED
@@ -5,19 +5,23 @@ import { cx, uid, useMaybeControlled } from "./internal.js";
5
5
  import { useLinkComponent } from "./locale.js";
6
6
  const Tabs = React.forwardRef(function Tabs2(props, ref) {
7
7
  const items = props.tabs || [], base = uid();
8
+ const asLinks = items.length > 0 && items.every(function(t) {
9
+ return !!t.href;
10
+ });
11
+ const firstOn = items.filter(function(t) {
12
+ return !t.disabled;
13
+ })[0];
8
14
  const st = useMaybeControlled(
9
15
  props.value,
10
- props.defaultValue || items[0] && items[0].id,
16
+ props.defaultValue || (asLinks ? void 0 : firstOn && firstOn.id),
11
17
  props.onChange
12
18
  );
19
+ const cur = asLinks && "value" in props ? props.value : st[0];
13
20
  const refs = React.useRef({});
14
21
  const current = items.filter(function(t) {
15
- return t.id === st[0];
16
- })[0] || items[0];
22
+ return t.id === cur;
23
+ })[0] || firstOn || items[0];
17
24
  const Link = useLinkComponent(props.linkComponent);
18
- const asLinks = items.length > 0 && items.every(function(t) {
19
- return !!t.href;
20
- });
21
25
  if (asLinks)
22
26
  return /* @__PURE__ */ React.createElement(
23
27
  "nav",
@@ -27,7 +31,7 @@ const Tabs = React.forwardRef(function Tabs2(props, ref) {
27
31
  className: cx("aura-tabs aura-tabs--links", props.className)
28
32
  },
29
33
  /* @__PURE__ */ React.createElement("div", { className: "aura-tabs__list" }, items.map(function(t) {
30
- const on = t.id === st[0];
34
+ const on = t.id === cur;
31
35
  const inner = [
32
36
  t.icon ? /* @__PURE__ */ React.createElement(Icon, { key: "i", name: t.icon }) : null,
33
37
  t.label,
@@ -28,8 +28,8 @@ const TextField = React.forwardRef(function TextField2(props, ref) {
28
28
  className: "aura-input__control",
29
29
  placeholder: props.placeholder,
30
30
  required: props.required,
31
- "aria-invalid": props.error ? true : void 0,
32
- "aria-describedby": describedBy(id, props)
31
+ "aria-invalid": props.error ? true : rest["aria-invalid"],
32
+ "aria-describedby": [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0
33
33
  }
34
34
  ), props.suffix ? /* @__PURE__ */ React.createElement("span", { className: "aura-input__suffix" }, props.suffix) : null)
35
35
  );
@@ -27,8 +27,8 @@ const Textarea = React.forwardRef(function Textarea2(props, ref) {
27
27
  className: "aura-input aura-textarea",
28
28
  placeholder: props.placeholder,
29
29
  required: props.required,
30
- "aria-invalid": props.error ? true : void 0,
31
- "aria-describedby": describedBy(id, props)
30
+ "aria-invalid": props.error ? true : rest["aria-invalid"],
31
+ "aria-describedby": [describedBy(id, props), rest["aria-describedby"]].filter(Boolean).join(" ") || void 0
32
32
  }
33
33
  )
34
34
  );
@@ -1,15 +1,25 @@
1
1
  'use client';
2
2
  import * as React from "react";
3
3
  import { createTheme } from "./theme.js";
4
+ import { devWarnOnce } from "./internal.js";
4
5
  function ThemeStyle(props) {
5
6
  const css = React.useMemo(
6
7
  function() {
7
- return createTheme({ brand: props.brand, signal: props.signal, primary: props.primary, name: props.name }).css(
8
- props.selector
9
- );
8
+ try {
9
+ return createTheme({
10
+ brand: props.brand,
11
+ signal: props.signal,
12
+ primary: props.primary,
13
+ name: props.name
14
+ }).css(props.selector);
15
+ } catch (e) {
16
+ devWarnOnce("theme-style", "ThemeStyle ignored: " + e.message);
17
+ return null;
18
+ }
10
19
  },
11
20
  [props.brand, props.signal, props.primary, props.name, props.selector]
12
21
  );
22
+ if (css === null) return null;
13
23
  return /* @__PURE__ */ React.createElement("style", { "data-aura-theme": props.name || props.brand, dangerouslySetInnerHTML: { __html: css } });
14
24
  }
15
25
  export {
@@ -158,6 +158,7 @@ function Toaster(props) {
158
158
  const s = React.useState(toastState.list);
159
159
  React.useEffect(function() {
160
160
  toastState.subs.push(s[1]);
161
+ s[1](toastState.list.slice());
161
162
  return function() {
162
163
  toastState.subs = toastState.subs.filter(function(f) {
163
164
  return f !== s[1];
@@ -1,11 +1,11 @@
1
1
  'use client';
2
2
  import * as React from "react";
3
- import { uid, useIsoLayoutEffect, useMergedRef } from "./internal.js";
3
+ import { uid, useIsoLayoutEffect, useMergedRef, useMounted } from "./internal.js";
4
4
  import { createPortal } from "react-dom";
5
5
  const Tooltip = React.forwardRef(function Tooltip2(props, ref) {
6
6
  const id = uid(), st = React.useState(false), open = props.open !== void 0 ? props.open : st[0], set = st[1];
7
7
  const anchor = React.useRef(null), anchorMerged = useMergedRef(ref, anchor), tip = React.useRef(null), timer = React.useRef(void 0);
8
- const pos = React.useState(null);
8
+ const pos = React.useState(null), mounted = useMounted();
9
9
  function show(now) {
10
10
  clearTimeout(timer.current);
11
11
  timer.current = setTimeout(
@@ -19,34 +19,55 @@ const Tooltip = React.forwardRef(function Tooltip2(props, ref) {
19
19
  clearTimeout(timer.current);
20
20
  set(false);
21
21
  }
22
+ function hideSoon() {
23
+ clearTimeout(timer.current);
24
+ timer.current = setTimeout(function() {
25
+ set(false);
26
+ }, 120);
27
+ }
28
+ React.useEffect(function() {
29
+ return function() {
30
+ clearTimeout(timer.current);
31
+ };
32
+ }, []);
33
+ function place() {
34
+ if (!anchor.current || !tip.current) return;
35
+ const r = anchor.current.getBoundingClientRect(), t = tip.current.getBoundingClientRect();
36
+ const vw = window.innerWidth, vh = window.innerHeight, gap = 8, m = 8;
37
+ let side = props.side || "top";
38
+ if (side === "top" && r.top - t.height - gap < m && r.bottom + gap + t.height <= vh - m) side = "bottom";
39
+ else if (side === "bottom" && r.bottom + gap + t.height > vh - m && r.top - t.height - gap >= m) side = "top";
40
+ else if (side === "left" && r.left - t.width - gap < m && r.right + gap + t.width <= vw - m) side = "right";
41
+ else if (side === "right" && r.right + gap + t.width > vw - m && r.left - t.width - gap >= m) side = "left";
42
+ const clampX = function(x) {
43
+ return Math.max(m, Math.min(x, vw - t.width - m));
44
+ };
45
+ const clampY = function(y) {
46
+ return Math.max(m, Math.min(y, vh - t.height - m));
47
+ };
48
+ let top, left;
49
+ if (side === "top" || side === "bottom") {
50
+ top = clampY(side === "top" ? r.top - t.height - gap : r.bottom + gap);
51
+ left = clampX(r.left + r.width / 2 - t.width / 2);
52
+ } else {
53
+ left = side === "left" ? r.left - t.width - gap : r.right + gap;
54
+ left = clampX(left);
55
+ top = clampY(r.top + r.height / 2 - t.height / 2);
56
+ }
57
+ pos[1]({ top, left });
58
+ }
22
59
  useIsoLayoutEffect(
23
60
  function() {
24
- if (!open || !anchor.current || !tip.current) return;
25
- const r = anchor.current.getBoundingClientRect(), t = tip.current.getBoundingClientRect();
26
- const vw = window.innerWidth, vh = window.innerHeight, gap = 8, m = 8;
27
- let side = props.side || "top";
28
- if (side === "top" && r.top - t.height - gap < m && r.bottom + gap + t.height <= vh - m) side = "bottom";
29
- else if (side === "bottom" && r.bottom + gap + t.height > vh - m && r.top - t.height - gap >= m) side = "top";
30
- else if (side === "left" && r.left - t.width - gap < m && r.right + gap + t.width <= vw - m) side = "right";
31
- else if (side === "right" && r.right + gap + t.width > vw - m && r.left - t.width - gap >= m) side = "left";
32
- const clampX = function(x) {
33
- return Math.max(m, Math.min(x, vw - t.width - m));
34
- };
35
- const clampY = function(y) {
36
- return Math.max(m, Math.min(y, vh - t.height - m));
61
+ if (!open) return;
62
+ place();
63
+ window.addEventListener("scroll", place, true);
64
+ window.addEventListener("resize", place);
65
+ return function() {
66
+ window.removeEventListener("scroll", place, true);
67
+ window.removeEventListener("resize", place);
37
68
  };
38
- let top, left;
39
- if (side === "top" || side === "bottom") {
40
- top = clampY(side === "top" ? r.top - t.height - gap : r.bottom + gap);
41
- left = clampX(r.left + r.width / 2 - t.width / 2);
42
- } else {
43
- left = side === "left" ? r.left - t.width - gap : r.right + gap;
44
- left = clampX(left);
45
- top = clampY(r.top + r.height / 2 - t.height / 2);
46
- }
47
- pos[1]({ top, left });
48
69
  },
49
- [open]
70
+ [open, mounted]
50
71
  );
51
72
  React.useEffect(
52
73
  function() {
@@ -70,7 +91,7 @@ const Tooltip = React.forwardRef(function Tooltip2(props, ref) {
70
91
  onMouseEnter: function() {
71
92
  show(false);
72
93
  },
73
- onMouseLeave: hide,
94
+ onMouseLeave: hideSoon,
74
95
  onFocus: function() {
75
96
  show(true);
76
97
  },
@@ -78,14 +99,18 @@ const Tooltip = React.forwardRef(function Tooltip2(props, ref) {
78
99
  },
79
100
  React.cloneElement(child, { "aria-describedby": open ? id : child.props["aria-describedby"] })
80
101
  );
81
- return /* @__PURE__ */ React.createElement(React.Fragment, null, trigger, open ? createPortal(
102
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, trigger, open && mounted ? createPortal(
82
103
  /* @__PURE__ */ React.createElement(
83
104
  "div",
84
105
  {
85
106
  ref: tip,
86
107
  id,
87
108
  role: "tooltip",
88
- className: "aura-tooltip",
109
+ onMouseEnter: function() {
110
+ clearTimeout(timer.current);
111
+ },
112
+ onMouseLeave: hideSoon,
113
+ className: "aura-tooltip aura-tooltip--hoverable",
89
114
  style: { top: pos[0] ? pos[0].top : -9999, left: pos[0] ? pos[0].left : -9999 }
90
115
  },
91
116
  props.content
@@ -37,16 +37,20 @@ function useColorScheme(options) {
37
37
  if (readScheme(fallback) === "system") apply("system");
38
38
  cb();
39
39
  }
40
+ function onStorage(e) {
41
+ if (e.key === key) apply(valid(e.newValue) ? e.newValue : fallback);
42
+ cb();
43
+ }
40
44
  if (mq) mq.addEventListener("change", onSystem);
41
45
  window.addEventListener(EVENT, cb);
42
- window.addEventListener("storage", cb);
46
+ window.addEventListener("storage", onStorage);
43
47
  return function() {
44
48
  if (mq) mq.removeEventListener("change", onSystem);
45
49
  window.removeEventListener(EVENT, cb);
46
- window.removeEventListener("storage", cb);
50
+ window.removeEventListener("storage", onStorage);
47
51
  };
48
52
  },
49
- [fallback]
53
+ [fallback, key]
50
54
  );
51
55
  const snapshot = React.useSyncExternalStore(
52
56
  subscribe,
@@ -6,9 +6,9 @@ function valid(v) {
6
6
  return typeof v === "string" && SCHEMES.indexOf(v) >= 0;
7
7
  }
8
8
  function colorSchemeScript(options) {
9
- const key = JSON.stringify(options && options.storageKey || DEFAULT_KEY);
10
- const fallback = JSON.stringify(options && options.defaultScheme || "system");
11
- return "(function(){try{var s=localStorage.getItem(" + key + ");if(s!=='light'&&s!=='dark'&&s!=='system')s=" + fallback + `;var d=document.documentElement;d.setAttribute("data-theme",s);var dark=s==='dark'||(s==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);d.classList.toggle("dark",dark);}catch(e){}})();`;
9
+ const key = JSON.stringify(options && options.storageKey || DEFAULT_KEY).replace(/</g, "\\u003c");
10
+ const fallback = JSON.stringify(options && options.defaultScheme || "system").replace(/</g, "\\u003c");
11
+ return "(function(){try{var s=localStorage.getItem(" + key + ");if(s!=='light'&&s!=='dark'&&s!=='system')s=" + fallback + `;var d=document.documentElement;d.setAttribute("data-theme",s);var m=window.matchMedia('(prefers-color-scheme: dark)');d.classList.toggle('dark',s==='dark'||(s==='system'&&m.matches));if(m.addEventListener)m.addEventListener('change',function(e){if(d.getAttribute('data-theme')==='system')d.classList.toggle('dark',e.matches)});}catch(e){}})();`;
12
12
  }
13
13
  export {
14
14
  DEFAULT_KEY,
package/dist/esm/dates.js CHANGED
@@ -46,7 +46,8 @@ const DATE_TEXT = {
46
46
  rangePlaceholder: "\u0E27\u0E27/\u0E14\u0E14/\u0E1B\u0E1B\u0E1B\u0E1B \u2013 \u0E27\u0E27/\u0E14\u0E14/\u0E1B\u0E1B\u0E1B\u0E1B",
47
47
  clearDates: "\u0E25\u0E49\u0E32\u0E07\u0E0A\u0E48\u0E27\u0E07\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48",
48
48
  chooseStart: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E40\u0E23\u0E34\u0E48\u0E21\u0E15\u0E49\u0E19",
49
- chooseEnd: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E2A\u0E34\u0E49\u0E19\u0E2A\u0E38\u0E14"
49
+ chooseEnd: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E2A\u0E34\u0E49\u0E19\u0E2A\u0E38\u0E14",
50
+ dateUnavailable: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E19\u0E35\u0E49\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49 \u0E25\u0E2D\u0E07\u0E40\u0E1B\u0E34\u0E14\u0E1B\u0E0F\u0E34\u0E17\u0E34\u0E19\u0E14\u0E39\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E14\u0E49"
50
51
  },
51
52
  en: {
52
53
  prevYears: "Previous years",
@@ -63,7 +64,8 @@ const DATE_TEXT = {
63
64
  rangePlaceholder: "DD/MM/YYYY \u2013 DD/MM/YYYY",
64
65
  clearDates: "Clear dates",
65
66
  chooseStart: "Choose the start date",
66
- chooseEnd: "Choose the end date"
67
+ chooseEnd: "Choose the end date",
68
+ dateUnavailable: "That date can't be chosen. Open the calendar to see the dates you can pick."
67
69
  },
68
70
  sv: {
69
71
  prevYears: "Tidigare \xE5r",
@@ -80,7 +82,8 @@ const DATE_TEXT = {
80
82
  rangePlaceholder: "\xE5\xE5\xE5\xE5-mm-dd \u2013 \xE5\xE5\xE5\xE5-mm-dd",
81
83
  clearDates: "Rensa datumen",
82
84
  chooseStart: "V\xE4lj startdatum",
83
- chooseEnd: "V\xE4lj slutdatum"
85
+ chooseEnd: "V\xE4lj slutdatum",
86
+ dateUnavailable: "Det datumet g\xE5r inte att v\xE4lja. \xD6ppna kalendern f\xF6r att se vilka datum som g\xE5r."
84
87
  }
85
88
  };
86
89
  function dateText(locale) {
@@ -12,14 +12,21 @@ function omit(src, keys) {
12
12
  }
13
13
  function useMaybeControlled(value, initial, onChange) {
14
14
  const s = React.useState(initial);
15
+ const wasSet = React.useState(value !== void 0);
16
+ if (value !== void 0 && !wasSet[0]) wasSet[1](true);
17
+ else if (value === void 0 && wasSet[0]) {
18
+ wasSet[1](false);
19
+ s[1](initial);
20
+ }
15
21
  const controlled = value !== void 0;
16
- return [
17
- controlled ? value : s[0],
18
- function(next) {
19
- if (!controlled) s[1](next);
20
- if (onChange) onChange(next);
21
- }
22
- ];
22
+ const latest = React.useRef({ controlled, onChange, set: s[1] });
23
+ latest.current = { controlled, onChange, set: s[1] };
24
+ const set = React.useCallback(function(next) {
25
+ const l = latest.current;
26
+ if (!l.controlled) l.set(next);
27
+ if (l.onChange) l.onChange(next);
28
+ }, []);
29
+ return [controlled ? value : s[0], set];
23
30
  }
24
31
  const collator = typeof Intl !== "undefined" ? new Intl.Collator(["th", "en"], { numeric: true, sensitivity: "base" }) : null;
25
32
  function compare(a, b) {
@@ -84,6 +91,9 @@ function tone(t) {
84
91
  return TONES.indexOf(t) >= 0 ? t : "neutral";
85
92
  }
86
93
  const warned = {};
94
+ function plainClick(e) {
95
+ return !e.defaultPrevented && e.button === 0 && !e.metaKey && !e.ctrlKey && !e.shiftKey && !e.altKey;
96
+ }
87
97
  function devWarnOnce(key, message) {
88
98
  if (warned[key]) return;
89
99
  let dev = false;
@@ -103,6 +113,7 @@ export {
103
113
  cx,
104
114
  devWarnOnce,
105
115
  omit,
116
+ plainClick,
106
117
  tone,
107
118
  trapTab,
108
119
  uid,
@@ -8,17 +8,18 @@ function AuraProvider(props) {
8
8
  const timeZone = props.timeZone || outer && outer.timeZone || null;
9
9
  const value = React.useMemo(
10
10
  function() {
11
- const base = props.locale && STRINGS[props.locale] || STRINGS.en;
11
+ const own = !!props.locale || !outer || !outer.locale;
12
+ const base = own ? props.locale && STRINGS[props.locale] || STRINGS.en : outer.strings;
12
13
  return {
13
- locale: props.locale || "en",
14
- calendar: props.calendar || null,
14
+ locale: props.locale || outer && outer.locale || "en",
15
+ calendar: props.calendar || (own ? null : outer.calendar),
15
16
  strings: props.strings ? Object.assign({}, base, props.strings) : base,
16
- linkComponent: props.linkComponent || null,
17
+ linkComponent: props.linkComponent || outer && outer.linkComponent || null,
17
18
  density,
18
19
  timeZone
19
20
  };
20
21
  },
21
- [props.locale, props.calendar, props.strings, props.linkComponent, density, timeZone]
22
+ [props.locale, props.calendar, props.strings, props.linkComponent, density, timeZone, outer]
22
23
  );
23
24
  return /* @__PURE__ */ React.createElement(LocaleContext.Provider, { value }, props.density ? /* @__PURE__ */ React.createElement("div", { className: "aura-density", "data-density": props.density }, props.children) : props.children);
24
25
  }