@jirawatpyk/aura-react 4.7.1 → 4.8.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.
Files changed (45) hide show
  1. package/README.md +1 -1
  2. package/dist/aura.bundle.js +451 -379
  3. package/dist/cjs/index.cjs +451 -379
  4. package/dist/esm/Accordion.js +66 -0
  5. package/dist/esm/Alert.js +31 -0
  6. package/dist/esm/AppShell.js +55 -0
  7. package/dist/esm/Avatar.js +39 -0
  8. package/dist/esm/Badge.js +26 -0
  9. package/dist/esm/Breadcrumb.js +16 -0
  10. package/dist/esm/Card.js +26 -0
  11. package/dist/esm/Combobox.js +1 -1
  12. package/dist/esm/Container.js +18 -0
  13. package/dist/esm/DatePicker.js +1 -1
  14. package/dist/esm/Dialog.js +1 -1
  15. package/dist/esm/EmptyState.js +22 -0
  16. package/dist/esm/Field.js +46 -0
  17. package/dist/esm/FileUpload.js +1 -1
  18. package/dist/esm/Grid.js +21 -0
  19. package/dist/esm/Pagination.js +94 -0
  20. package/dist/esm/Popover.js +131 -0
  21. package/dist/esm/Progress.js +40 -0
  22. package/dist/esm/RadioGroup.js +46 -0
  23. package/dist/esm/Select.js +48 -0
  24. package/dist/esm/SideNav.js +36 -0
  25. package/dist/esm/Skeleton.js +29 -0
  26. package/dist/esm/Stack.js +20 -0
  27. package/dist/esm/Switch.js +30 -0
  28. package/dist/esm/Tabs.js +89 -0
  29. package/dist/esm/Tag.js +42 -0
  30. package/dist/esm/TextField.js +39 -0
  31. package/dist/esm/Textarea.js +38 -0
  32. package/dist/esm/TimePicker.js +1 -1
  33. package/dist/esm/Toaster.js +124 -0
  34. package/dist/esm/Tooltip.js +80 -0
  35. package/dist/esm/index.js +27 -5
  36. package/dist/esm/internal.js +5 -0
  37. package/dist/esm/responsive.js +50 -0
  38. package/dist/index.d.ts +8 -8
  39. package/package.json +1 -1
  40. package/dist/esm/extra.js +0 -412
  41. package/dist/esm/feedback.js +0 -220
  42. package/dist/esm/forms.js +0 -212
  43. package/dist/esm/layout.js +0 -183
  44. package/dist/esm/layout2.js +0 -138
  45. /package/dist/esm/{overlay.js → useModal.js} +0 -0
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { cx, tone, uid } from "./internal.js";
4
+ const Progress = React.forwardRef(function Progress2(props, ref) {
5
+ const auto = uid(), id = props.id || auto;
6
+ const max = props.max || 100, det = props.value != null;
7
+ const pct = det ? Math.max(0, Math.min(100, props.value / max * 100)) : 0;
8
+ const shown = props.valueLabel != null ? props.valueLabel : det ? Math.round(pct) + "%" : null;
9
+ return /* @__PURE__ */ React.createElement(
10
+ "div",
11
+ {
12
+ ref,
13
+ className: cx(
14
+ "aura-progress",
15
+ "aura-progress--" + tone(props.tone || "accent"),
16
+ props.size === "sm" && "is-sm",
17
+ props.className
18
+ )
19
+ },
20
+ props.label || props.showValue && shown ? /* @__PURE__ */ React.createElement("div", { className: "aura-progress__head" }, props.label ? /* @__PURE__ */ React.createElement("span", { className: "aura-progress__label", id: id + "-label" }, props.label) : /* @__PURE__ */ React.createElement("span", null), props.showValue && shown ? /* @__PURE__ */ React.createElement("span", { className: "aura-progress__value" }, shown) : null) : null,
21
+ /* @__PURE__ */ React.createElement(
22
+ "div",
23
+ {
24
+ className: cx("aura-progress__track", !det && "is-indeterminate"),
25
+ role: "progressbar",
26
+ "aria-labelledby": props.label ? id + "-label" : void 0,
27
+ "aria-label": props.label ? void 0 : props["aria-label"],
28
+ "aria-valuemin": det ? 0 : void 0,
29
+ "aria-valuemax": det ? max : void 0,
30
+ "aria-valuenow": det ? props.value : void 0,
31
+ "aria-valuetext": det && props.valueLabel != null ? String(props.valueLabel) : void 0
32
+ },
33
+ /* @__PURE__ */ React.createElement("span", { className: "aura-progress__bar", style: det ? { width: pct + "%" } : void 0 })
34
+ ),
35
+ props.hint ? /* @__PURE__ */ React.createElement("p", { className: "aura-progress__hint" }, props.hint) : null
36
+ );
37
+ });
38
+ export {
39
+ Progress
40
+ };
@@ -0,0 +1,46 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { describedBy } from "./Field.js";
4
+ import { Icon } from "./Icon.js";
5
+ import { cx, uid, useMaybeControlled } from "./internal.js";
6
+ const RadioGroup = React.forwardRef(function RadioGroup2(props, ref) {
7
+ const auto = uid(), id = props.id || auto;
8
+ const st = useMaybeControlled(
9
+ props.value,
10
+ props.defaultValue,
11
+ props.onChange
12
+ );
13
+ const name = props.name || id;
14
+ return /* @__PURE__ */ React.createElement(
15
+ "fieldset",
16
+ {
17
+ ref,
18
+ className: cx("aura-field aura-radio-group", props.error && "is-invalid", props.className),
19
+ "aria-describedby": describedBy(id, props),
20
+ "aria-invalid": props.error ? true : void 0,
21
+ disabled: props.disabled
22
+ },
23
+ props.label ? /* @__PURE__ */ React.createElement("legend", { className: "aura-field__label" }, props.label, props.required ? /* @__PURE__ */ React.createElement("span", { className: "aura-field__req", "aria-hidden": true }, " *") : null) : null,
24
+ /* @__PURE__ */ React.createElement("div", { className: cx("aura-radio-group__list", props.orientation === "horizontal" && "is-horizontal") }, (props.options || []).map(function(o) {
25
+ const v = typeof o === "object" ? o : { value: o, label: o };
26
+ return /* @__PURE__ */ React.createElement("label", { key: v.value, className: cx("aura-choice", v.disabled && "is-disabled") }, /* @__PURE__ */ React.createElement(
27
+ "input",
28
+ {
29
+ type: "radio",
30
+ className: "aura-radio",
31
+ name,
32
+ value: v.value,
33
+ disabled: v.disabled,
34
+ checked: st[0] === v.value,
35
+ onChange: function() {
36
+ st[1](v.value);
37
+ }
38
+ }
39
+ ), /* @__PURE__ */ React.createElement("span", { className: "aura-choice__text" }, /* @__PURE__ */ React.createElement("span", { className: "aura-choice__label" }, v.label), v.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-choice__desc" }, v.description) : null));
40
+ })),
41
+ props.error ? /* @__PURE__ */ React.createElement("p", { className: "aura-field__error", id: id + "-error" }, /* @__PURE__ */ React.createElement(Icon, { name: "circle-alert", size: 14 }), props.error) : props.hint ? /* @__PURE__ */ React.createElement("p", { className: "aura-field__hint", id: id + "-hint" }, props.hint) : null
42
+ );
43
+ });
44
+ export {
45
+ RadioGroup
46
+ };
@@ -0,0 +1,48 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { FIELD_KEYS, Field, describedBy } from "./Field.js";
4
+ import { Icon } from "./Icon.js";
5
+ import { cx, omit, uid } from "./internal.js";
6
+ const h = React.createElement;
7
+ const Select = React.forwardRef(function Select2(props, ref) {
8
+ const auto = uid(), id = props.id || auto;
9
+ const rest = omit(props, FIELD_KEYS.concat(["children"]));
10
+ const opts = (props.options || []).map(function(o) {
11
+ const v = typeof o === "object" ? o : { value: o, label: o };
12
+ return /* @__PURE__ */ React.createElement("option", { key: v.value, value: v.value, disabled: v.disabled }, v.label);
13
+ });
14
+ if (props.placeholder)
15
+ opts.unshift(
16
+ /* @__PURE__ */ React.createElement("option", { key: "__ph", value: "", disabled: true }, props.placeholder)
17
+ );
18
+ const extra = props.value === void 0 && props.defaultValue === void 0 && props.placeholder ? { defaultValue: "" } : {};
19
+ return /* @__PURE__ */ React.createElement(
20
+ Field,
21
+ {
22
+ id,
23
+ label: props.label,
24
+ hint: props.hint,
25
+ error: props.error,
26
+ required: props.required,
27
+ optional: props.optional,
28
+ disabled: props.disabled,
29
+ className: props.className
30
+ },
31
+ /* @__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(
32
+ "select",
33
+ Object.assign(extra, rest, {
34
+ ref,
35
+ id,
36
+ className: "aura-input__control",
37
+ required: props.required,
38
+ "aria-invalid": props.error ? true : void 0,
39
+ "aria-describedby": describedBy(id, props)
40
+ }),
41
+ opts,
42
+ props.children
43
+ ), /* @__PURE__ */ React.createElement(Icon, { name: "chevron-down", className: "aura-select__chevron" }))
44
+ );
45
+ });
46
+ export {
47
+ Select
48
+ };
@@ -0,0 +1,36 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { Icon } from "./Icon.js";
4
+ import { cx, useMaybeControlled } from "./internal.js";
5
+ import { useStrings } from "./locale.js";
6
+ const SideNav = React.forwardRef(function SideNav2(props, ref) {
7
+ const t = useStrings();
8
+ const st = useMaybeControlled(
9
+ props.value,
10
+ props.defaultValue,
11
+ props.onChange
12
+ );
13
+ function item(it) {
14
+ const on = st[0] === it.id;
15
+ const inner = [
16
+ it.icon ? /* @__PURE__ */ React.createElement(Icon, { key: "i", name: it.icon }) : null,
17
+ /* @__PURE__ */ React.createElement("span", { key: "l", className: "aura-nav__label" }, it.label),
18
+ it.count != null ? /* @__PURE__ */ React.createElement("span", { key: "c", className: "aura-nav__count" }, it.count) : null
19
+ ];
20
+ const common = {
21
+ className: cx("aura-nav__item", on && "is-active"),
22
+ "aria-current": on ? "page" : void 0,
23
+ onClick: function(e) {
24
+ if (!it.href) e.preventDefault();
25
+ st[1](it.id);
26
+ }
27
+ };
28
+ return /* @__PURE__ */ React.createElement("li", { key: it.id }, it.href ? /* @__PURE__ */ React.createElement("a", { href: it.href, ...common }, inner) : /* @__PURE__ */ React.createElement("button", { type: "button", ...common }, inner));
29
+ }
30
+ return /* @__PURE__ */ React.createElement("nav", { ref, className: cx("aura-nav", props.className), "aria-label": props.label || t.mainNav }, props.header ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__header" }, props.header) : null, /* @__PURE__ */ React.createElement("div", { className: "aura-nav__scroll" }, (props.sections || [{ items: props.items || [] }]).map(function(s, i) {
31
+ return /* @__PURE__ */ React.createElement("div", { key: i, className: "aura-nav__section" }, s.title ? /* @__PURE__ */ React.createElement("p", { className: "aura-nav__title" }, s.title) : null, /* @__PURE__ */ React.createElement("ul", { className: "aura-nav__list" }, s.items.map(item)));
32
+ })), props.footer ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__footer" }, props.footer) : null);
33
+ });
34
+ export {
35
+ SideNav
36
+ };
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { cx } from "./internal.js";
4
+ const Skeleton = React.forwardRef(function Skeleton2(props, ref) {
5
+ const v = props.variant || "text";
6
+ if (v === "text" && (props.lines || 1) > 1) {
7
+ const n = props.lines, rows = [];
8
+ for (let i = 0; i < n; i++)
9
+ rows.push(/* @__PURE__ */ React.createElement("span", { key: i, className: "aura-skel aura-skel--text", style: { width: i === n - 1 ? "60%" : "100%" } }));
10
+ return /* @__PURE__ */ React.createElement(
11
+ "span",
12
+ {
13
+ ref,
14
+ className: cx("aura-skel-lines", props.className),
15
+ "aria-hidden": true,
16
+ style: props.width ? { width: props.width } : void 0
17
+ },
18
+ rows
19
+ );
20
+ }
21
+ const style = { width: props.width, height: props.height };
22
+ if (v === "circle") {
23
+ style.width = style.height = props.size || props.width || 40;
24
+ }
25
+ return /* @__PURE__ */ React.createElement("span", { ref, "aria-hidden": true, className: cx("aura-skel", "aura-skel--" + v, props.className), style });
26
+ });
27
+ export {
28
+ Skeleton
29
+ };
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { cx } from "./internal.js";
4
+ import { respVars, space } from "./responsive.js";
5
+ const h = React.createElement;
6
+ const Stack = React.forwardRef(function Stack2(props, ref) {
7
+ const style = Object.assign(
8
+ {},
9
+ respVars("aura-stack-dir", props.direction || "column"),
10
+ respVars("aura-stack-gap", props.gap == null ? 4 : props.gap, space),
11
+ respVars("aura-stack-align", props.align || "stretch"),
12
+ props.justify ? { justifyContent: props.justify } : null,
13
+ props.wrap ? { flexWrap: "wrap" } : null,
14
+ props.style
15
+ );
16
+ return h(props.as || "div", { ref, className: cx("aura-stack", props.className), style }, props.children);
17
+ });
18
+ export {
19
+ Stack
20
+ };
@@ -0,0 +1,30 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { cx, uid, useMaybeControlled } from "./internal.js";
4
+ const Switch = React.forwardRef(function Switch2(props, ref) {
5
+ const auto = uid(), id = props.id || auto;
6
+ const st = useMaybeControlled(props.checked, !!props.defaultChecked, props.onChange);
7
+ const on = !!st[0];
8
+ return /* @__PURE__ */ React.createElement("div", { className: cx("aura-switch-row", props.disabled && "is-disabled", props.className) }, /* @__PURE__ */ React.createElement(
9
+ "button",
10
+ {
11
+ ref,
12
+ type: "button",
13
+ role: "switch",
14
+ id,
15
+ "aria-checked": on,
16
+ disabled: props.disabled,
17
+ "aria-labelledby": props.label ? id + "-label" : void 0,
18
+ "aria-label": props.label ? void 0 : props["aria-label"],
19
+ "aria-describedby": props.description ? id + "-desc" : void 0,
20
+ className: cx("aura-switch", on && "is-on"),
21
+ onClick: function() {
22
+ st[1](!on);
23
+ }
24
+ },
25
+ /* @__PURE__ */ React.createElement("span", { className: "aura-switch__thumb" })
26
+ ), 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);
27
+ });
28
+ export {
29
+ Switch
30
+ };
@@ -0,0 +1,89 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { Icon } from "./Icon.js";
4
+ import { cx, uid, useMaybeControlled } from "./internal.js";
5
+ const Tabs = React.forwardRef(function Tabs2(props, ref) {
6
+ const items = props.tabs || [], base = uid();
7
+ const st = useMaybeControlled(
8
+ props.value,
9
+ props.defaultValue || items[0] && items[0].id,
10
+ props.onChange
11
+ );
12
+ const refs = React.useRef({});
13
+ const current = items.filter(function(t) {
14
+ return t.id === st[0];
15
+ })[0] || items[0];
16
+ function go(i) {
17
+ const enabled = items.filter(function(t2) {
18
+ return !t2.disabled;
19
+ });
20
+ const t = enabled[(i + enabled.length) % enabled.length];
21
+ st[1](t.id);
22
+ if (refs.current[t.id]) refs.current[t.id].focus();
23
+ }
24
+ return /* @__PURE__ */ React.createElement("div", { ref, className: cx("aura-tabs", props.className) }, /* @__PURE__ */ React.createElement(
25
+ "div",
26
+ {
27
+ role: "tablist",
28
+ "aria-label": props.label,
29
+ className: "aura-tabs__list",
30
+ onKeyDown: function(e) {
31
+ const enabled = items.filter(function(t) {
32
+ return !t.disabled;
33
+ }), i = enabled.indexOf(current);
34
+ if (e.key === "ArrowRight") {
35
+ e.preventDefault();
36
+ go(i + 1);
37
+ } else if (e.key === "ArrowLeft") {
38
+ e.preventDefault();
39
+ go(i - 1);
40
+ } else if (e.key === "Home") {
41
+ e.preventDefault();
42
+ go(0);
43
+ } else if (e.key === "End") {
44
+ e.preventDefault();
45
+ go(enabled.length - 1);
46
+ }
47
+ }
48
+ },
49
+ items.map(function(t) {
50
+ const on = current && t.id === current.id;
51
+ return /* @__PURE__ */ React.createElement(
52
+ "button",
53
+ {
54
+ key: t.id,
55
+ type: "button",
56
+ role: "tab",
57
+ id: base + "-tab-" + t.id,
58
+ "aria-selected": on,
59
+ "aria-controls": base + "-panel-" + t.id,
60
+ tabIndex: on ? 0 : -1,
61
+ disabled: t.disabled,
62
+ ref: function(el) {
63
+ refs.current[t.id] = el;
64
+ },
65
+ className: cx("aura-tab", on && "is-active"),
66
+ onClick: function() {
67
+ st[1](t.id);
68
+ }
69
+ },
70
+ t.icon ? /* @__PURE__ */ React.createElement(Icon, { name: t.icon }) : null,
71
+ t.label,
72
+ t.count != null ? /* @__PURE__ */ React.createElement("span", { className: "aura-tab__count" }, t.count) : null
73
+ );
74
+ })
75
+ ), current && current.content !== void 0 ? /* @__PURE__ */ React.createElement(
76
+ "div",
77
+ {
78
+ role: "tabpanel",
79
+ id: base + "-panel-" + current.id,
80
+ "aria-labelledby": base + "-tab-" + current.id,
81
+ tabIndex: 0,
82
+ className: "aura-tabs__panel"
83
+ },
84
+ current.content
85
+ ) : null);
86
+ });
87
+ export {
88
+ Tabs
89
+ };
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { Icon } from "./Icon.js";
4
+ import { cx, omit } from "./internal.js";
5
+ import { useStrings } from "./locale.js";
6
+ const Tag = React.forwardRef(function Tag2(props, ref) {
7
+ const t = useStrings();
8
+ const selectable = props.onClick != null || props.selected != null;
9
+ const rest = omit(props, ["onRemove", "selected", "icon", "className", "children", "disabled", "removeLabel"]);
10
+ const inner = [
11
+ props.icon ? /* @__PURE__ */ React.createElement(Icon, { key: "i", name: props.icon, size: 14 }) : null,
12
+ /* @__PURE__ */ React.createElement("span", { key: "t", className: "aura-tag__text" }, props.children)
13
+ ];
14
+ if (selectable) {
15
+ return /* @__PURE__ */ React.createElement(
16
+ "button",
17
+ {
18
+ ...rest,
19
+ ref,
20
+ type: "button",
21
+ "aria-pressed": !!props.selected,
22
+ disabled: props.disabled,
23
+ className: cx("aura-tag is-selectable", props.selected && "is-selected", props.className)
24
+ },
25
+ props.selected ? /* @__PURE__ */ React.createElement(Icon, { name: "check", size: 14 }) : inner[0],
26
+ inner[1]
27
+ );
28
+ }
29
+ return /* @__PURE__ */ React.createElement("span", { ...rest, ref, className: cx("aura-tag", props.disabled && "is-disabled", props.className) }, inner, props.onRemove && !props.disabled ? /* @__PURE__ */ React.createElement(
30
+ "button",
31
+ {
32
+ type: "button",
33
+ className: "aura-tag__remove",
34
+ "aria-label": props.removeLabel || t.remove(typeof props.children === "string" ? props.children : ""),
35
+ onClick: props.onRemove
36
+ },
37
+ /* @__PURE__ */ React.createElement(Icon, { name: "x", size: 12 })
38
+ ) : null);
39
+ });
40
+ export {
41
+ Tag
42
+ };
@@ -0,0 +1,39 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { FIELD_KEYS, Field, describedBy } from "./Field.js";
4
+ import { Icon } from "./Icon.js";
5
+ import { cx, omit, uid } from "./internal.js";
6
+ const TextField = React.forwardRef(function TextField2(props, ref) {
7
+ const auto = uid(), id = props.id || auto;
8
+ const rest = omit(props, FIELD_KEYS);
9
+ return /* @__PURE__ */ React.createElement(
10
+ Field,
11
+ {
12
+ id,
13
+ label: props.label,
14
+ hint: props.hint,
15
+ error: props.error,
16
+ required: props.required,
17
+ optional: props.optional,
18
+ disabled: props.disabled,
19
+ className: props.className
20
+ },
21
+ /* @__PURE__ */ React.createElement("div", { className: cx("aura-input", props.icon && "has-icon", props.suffix && "has-suffix") }, props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, className: "aura-input__icon" }) : null, /* @__PURE__ */ React.createElement(
22
+ "input",
23
+ {
24
+ type: "text",
25
+ ...rest,
26
+ ref,
27
+ id,
28
+ className: "aura-input__control",
29
+ placeholder: props.placeholder,
30
+ required: props.required,
31
+ "aria-invalid": props.error ? true : void 0,
32
+ "aria-describedby": describedBy(id, props)
33
+ }
34
+ ), props.suffix ? /* @__PURE__ */ React.createElement("span", { className: "aura-input__suffix" }, props.suffix) : null)
35
+ );
36
+ });
37
+ export {
38
+ TextField
39
+ };
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { FIELD_KEYS, Field, describedBy } from "./Field.js";
4
+ import { omit, uid } from "./internal.js";
5
+ const Textarea = React.forwardRef(function Textarea2(props, ref) {
6
+ const auto = uid(), id = props.id || auto;
7
+ const rest = omit(props, FIELD_KEYS);
8
+ return /* @__PURE__ */ React.createElement(
9
+ Field,
10
+ {
11
+ id,
12
+ label: props.label,
13
+ hint: props.hint,
14
+ error: props.error,
15
+ required: props.required,
16
+ optional: props.optional,
17
+ disabled: props.disabled,
18
+ className: props.className
19
+ },
20
+ /* @__PURE__ */ React.createElement(
21
+ "textarea",
22
+ {
23
+ rows: 4,
24
+ ...rest,
25
+ ref,
26
+ id,
27
+ className: "aura-input aura-textarea",
28
+ placeholder: props.placeholder,
29
+ required: props.required,
30
+ "aria-invalid": props.error ? true : void 0,
31
+ "aria-describedby": describedBy(id, props)
32
+ }
33
+ )
34
+ );
35
+ });
36
+ export {
37
+ Textarea
38
+ };
@@ -4,7 +4,7 @@ import { createPortal } from "react-dom";
4
4
  import { cx, uid, useMaybeControlled, useMounted, useIsoLayoutEffect, useMergedRef } from "./internal.js";
5
5
  import { useStrings } from "./locale.js";
6
6
  import { Icon } from "./Icon.js";
7
- import { Field } from "./forms.js";
7
+ import { Field } from "./Field.js";
8
8
  function pad(n) {
9
9
  return (n < 10 ? "0" : "") + n;
10
10
  }
@@ -0,0 +1,124 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { ALERT_ICON } from "./Alert.js";
4
+ import { Icon } from "./Icon.js";
5
+ import { IconButton } from "./IconButton.js";
6
+ import { cx, useMounted } from "./internal.js";
7
+ import { useStrings } from "./locale.js";
8
+ import { createPortal } from "react-dom";
9
+ const toastState = {
10
+ list: [],
11
+ subs: [],
12
+ n: 0
13
+ };
14
+ function emitToasts() {
15
+ toastState.subs.forEach(function(f) {
16
+ f(toastState.list.slice());
17
+ });
18
+ }
19
+ function toast(opts) {
20
+ if (typeof opts === "string") opts = { title: opts };
21
+ const id = opts.id || "t" + ++toastState.n;
22
+ toastState.list = toastState.list.filter(function(t) {
23
+ return t.id !== id;
24
+ }).concat([Object.assign({ tone: "info" }, opts, { id })]).slice(-3);
25
+ emitToasts();
26
+ return id;
27
+ }
28
+ toast.dismiss = function(id) {
29
+ toastState.list = toastState.list.filter(function(t) {
30
+ return t.id !== id;
31
+ });
32
+ emitToasts();
33
+ };
34
+ function ToastItem(props) {
35
+ const str = useStrings();
36
+ const t = props.toast, timer = React.useRef(null), left = React.useRef(t.duration || 5e3), since = React.useRef(0);
37
+ function start() {
38
+ if (left.current === Infinity) return;
39
+ since.current = Date.now();
40
+ timer.current = setTimeout(function() {
41
+ toast.dismiss(t.id);
42
+ }, left.current);
43
+ }
44
+ function pause() {
45
+ if (timer.current) {
46
+ clearTimeout(timer.current);
47
+ timer.current = null;
48
+ left.current -= Date.now() - since.current;
49
+ }
50
+ }
51
+ React.useEffect(function() {
52
+ start();
53
+ return pause;
54
+ }, []);
55
+ return /* @__PURE__ */ React.createElement(
56
+ "div",
57
+ {
58
+ className: cx("aura-toast", "aura-toast--" + t.tone),
59
+ role: t.tone === "danger" ? "alert" : "status",
60
+ onMouseEnter: pause,
61
+ onMouseLeave: start,
62
+ onFocus: pause,
63
+ onBlur: start
64
+ },
65
+ /* @__PURE__ */ React.createElement(Icon, { name: ALERT_ICON[t.tone] || "info", className: "aura-toast__icon" }),
66
+ /* @__PURE__ */ React.createElement("div", { className: "aura-toast__body" }, /* @__PURE__ */ React.createElement("p", { className: "aura-toast__title" }, t.title), t.description ? /* @__PURE__ */ React.createElement("p", { className: "aura-toast__text" }, t.description) : null),
67
+ t.action ? /* @__PURE__ */ React.createElement(
68
+ "button",
69
+ {
70
+ type: "button",
71
+ className: "aura-toast__action",
72
+ onClick: function() {
73
+ t.action.onClick && t.action.onClick();
74
+ toast.dismiss(t.id);
75
+ }
76
+ },
77
+ t.action.label
78
+ ) : null,
79
+ /* @__PURE__ */ React.createElement(
80
+ IconButton,
81
+ {
82
+ icon: "x",
83
+ label: str.dismissToast,
84
+ className: "aura-toast__close",
85
+ onClick: function() {
86
+ toast.dismiss(t.id);
87
+ }
88
+ }
89
+ )
90
+ );
91
+ }
92
+ function Toaster(props) {
93
+ const t = useStrings();
94
+ const mounted = useMounted();
95
+ const s = React.useState(toastState.list);
96
+ React.useEffect(function() {
97
+ toastState.subs.push(s[1]);
98
+ return function() {
99
+ toastState.subs = toastState.subs.filter(function(f) {
100
+ return f !== s[1];
101
+ });
102
+ };
103
+ }, []);
104
+ if (!mounted) return null;
105
+ return createPortal(
106
+ /* @__PURE__ */ React.createElement(
107
+ "div",
108
+ {
109
+ className: cx("aura-toaster", props && props.position === "top" && "is-top"),
110
+ role: "region",
111
+ "aria-live": "polite",
112
+ "aria-label": t.notifications
113
+ },
114
+ s[0].map(function(t2) {
115
+ return /* @__PURE__ */ React.createElement(ToastItem, { key: t2.id, toast: t2 });
116
+ })
117
+ ),
118
+ document.body
119
+ );
120
+ }
121
+ export {
122
+ Toaster,
123
+ toast
124
+ };