@jirawatpyk/aura-react 4.7.2 → 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,80 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { uid, useIsoLayoutEffect, useMergedRef } from "./internal.js";
4
+ import { createPortal } from "react-dom";
5
+ const Tooltip = React.forwardRef(function Tooltip2(props, ref) {
6
+ const id = uid(), st = React.useState(false), open = props.open !== void 0 ? props.open : st[0], set = st[1];
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);
9
+ function show(now) {
10
+ clearTimeout(timer.current);
11
+ timer.current = setTimeout(
12
+ function() {
13
+ set(true);
14
+ },
15
+ now ? 0 : props.delay == null ? 400 : props.delay
16
+ );
17
+ }
18
+ function hide() {
19
+ clearTimeout(timer.current);
20
+ set(false);
21
+ }
22
+ useIsoLayoutEffect(
23
+ function() {
24
+ if (!open || !anchor.current || !tip.current) return;
25
+ const r = anchor.current.getBoundingClientRect(), t = tip.current.getBoundingClientRect();
26
+ let side = props.side || "top", top = side === "top" ? r.top - t.height - 8 : r.bottom + 8;
27
+ if (side === "top" && top < 8) top = r.bottom + 8;
28
+ const left = Math.max(8, Math.min(r.left + r.width / 2 - t.width / 2, window.innerWidth - t.width - 8));
29
+ pos[1]({ top, left });
30
+ },
31
+ [open]
32
+ );
33
+ React.useEffect(
34
+ function() {
35
+ if (!open) return;
36
+ function esc(e) {
37
+ if (e.key === "Escape") hide();
38
+ }
39
+ document.addEventListener("keydown", esc);
40
+ return function() {
41
+ document.removeEventListener("keydown", esc);
42
+ };
43
+ },
44
+ [open]
45
+ );
46
+ const child = React.Children.only(props.children);
47
+ const trigger = /* @__PURE__ */ React.createElement(
48
+ "span",
49
+ {
50
+ ref: anchorMerged,
51
+ className: "aura-tooltip-anchor",
52
+ onMouseEnter: function() {
53
+ show(false);
54
+ },
55
+ onMouseLeave: hide,
56
+ onFocus: function() {
57
+ show(true);
58
+ },
59
+ onBlur: hide
60
+ },
61
+ React.cloneElement(child, { "aria-describedby": open ? id : child.props["aria-describedby"] })
62
+ );
63
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, trigger, open ? createPortal(
64
+ /* @__PURE__ */ React.createElement(
65
+ "div",
66
+ {
67
+ ref: tip,
68
+ id,
69
+ role: "tooltip",
70
+ className: "aura-tooltip",
71
+ style: { top: pos[0] ? pos[0].top : -9999, left: pos[0] ? pos[0].left : -9999 }
72
+ },
73
+ props.content
74
+ ),
75
+ document.body
76
+ ) : null);
77
+ });
78
+ export {
79
+ Tooltip
80
+ };
package/dist/esm/index.js CHANGED
@@ -6,14 +6,29 @@ import { Menu } from "./Menu.js";
6
6
  import { DropdownMenu } from "./DropdownMenu.js";
7
7
  import { Checkbox } from "./Checkbox.js";
8
8
  import { StatusPill, statusTone } from "./StatusPill.js";
9
- import { Field, TextField, Textarea, Select, RadioGroup, Switch } from "./forms.js";
9
+ import { Field } from "./Field.js";
10
+ import { TextField } from "./TextField.js";
11
+ import { Textarea } from "./Textarea.js";
12
+ import { Select } from "./Select.js";
13
+ import { RadioGroup } from "./RadioGroup.js";
14
+ import { Switch } from "./Switch.js";
10
15
  import { Combobox, defaultFilter } from "./Combobox.js";
11
16
  import { DatePicker, DateRangePicker, Calendar, formatDate, parseDate } from "./DatePicker.js";
12
- import { Alert, Toaster, toast, Tooltip } from "./feedback.js";
17
+ import { Alert } from "./Alert.js";
18
+ import { Toaster, toast } from "./Toaster.js";
19
+ import { Tooltip } from "./Tooltip.js";
13
20
  import { Dialog, Drawer } from "./Dialog.js";
14
21
  import { DataTable } from "./DataTable.js";
15
- import { Card, Tabs, SideNav, Breadcrumb, Avatar } from "./layout.js";
16
- import { Stack, Grid, Container, AppShell, useBreakpoint, useResponsive, breakpoints } from "./layout2.js";
22
+ import { Card } from "./Card.js";
23
+ import { Tabs } from "./Tabs.js";
24
+ import { SideNav } from "./SideNav.js";
25
+ import { Breadcrumb } from "./Breadcrumb.js";
26
+ import { Avatar } from "./Avatar.js";
27
+ import { Stack } from "./Stack.js";
28
+ import { Grid } from "./Grid.js";
29
+ import { Container } from "./Container.js";
30
+ import { AppShell } from "./AppShell.js";
31
+ import { useBreakpoint, useResponsive, breakpoints } from "./responsive.js";
17
32
  import { Surface } from "./Surface.js";
18
33
  import { AuraProvider, useAuraLocale, STRINGS } from "./locale.js";
19
34
  import { Stat } from "./Stat.js";
@@ -22,7 +37,14 @@ import { FileUpload, formatBytes } from "./FileUpload.js";
22
37
  import { createTheme, contrast, scale } from "./theme.js";
23
38
  import { ThemeStyle } from "./ThemeStyle.js";
24
39
  import { ColorSchemeScript, ColorSchemeToggle, colorSchemeScript, useColorScheme } from "./colorScheme.js";
25
- import { Badge, Tag, Progress, Skeleton, EmptyState, Pagination, Accordion, Popover } from "./extra.js";
40
+ import { Badge } from "./Badge.js";
41
+ import { Tag } from "./Tag.js";
42
+ import { Progress } from "./Progress.js";
43
+ import { Skeleton } from "./Skeleton.js";
44
+ import { EmptyState } from "./EmptyState.js";
45
+ import { Pagination } from "./Pagination.js";
46
+ import { Accordion } from "./Accordion.js";
47
+ import { Popover } from "./Popover.js";
26
48
  export {
27
49
  Accordion,
28
50
  Alert,
@@ -79,12 +79,17 @@ function useMergedRef(a, b) {
79
79
  [a, b]
80
80
  );
81
81
  }
82
+ const TONES = ["neutral", "accent", "success", "warning", "danger"];
83
+ function tone(t) {
84
+ return TONES.indexOf(t) >= 0 ? t : "neutral";
85
+ }
82
86
  export {
83
87
  FOCUSABLE,
84
88
  collator,
85
89
  compare,
86
90
  cx,
87
91
  omit,
92
+ tone,
88
93
  trapTab,
89
94
  uid,
90
95
  useIsoLayoutEffect,
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ const breakpoints = { sm: 640, md: 768, lg: 1024, xl: 1280 };
4
+ const ORDER = ["base", "sm", "md", "lg", "xl"];
5
+ function useBreakpoint() {
6
+ return React.useSyncExternalStore(subscribe, current, function() {
7
+ return "lg";
8
+ });
9
+ }
10
+ function current() {
11
+ let w = window.innerWidth, bp = "base";
12
+ ORDER.slice(1).forEach(function(k) {
13
+ if (w >= breakpoints[k]) bp = k;
14
+ });
15
+ return bp;
16
+ }
17
+ function subscribe(cb) {
18
+ window.addEventListener("resize", cb);
19
+ return function() {
20
+ window.removeEventListener("resize", cb);
21
+ };
22
+ }
23
+ function useResponsive(value) {
24
+ const bp = useBreakpoint();
25
+ if (value == null || typeof value !== "object") return value;
26
+ const map = value;
27
+ for (let i = ORDER.indexOf(bp); i >= 0; i--) if (map[ORDER[i]] !== void 0) return map[ORDER[i]];
28
+ return void 0;
29
+ }
30
+ function respVars(prefix, value, map) {
31
+ const style = {};
32
+ if (value == null) return style;
33
+ if (typeof value !== "object") value = { base: value };
34
+ let byBp = value, cur;
35
+ ORDER.forEach(function(k) {
36
+ if (byBp[k] !== void 0) cur = map ? map(byBp[k]) : byBp[k];
37
+ if (cur !== void 0) style["--" + prefix + "-" + k] = cur;
38
+ });
39
+ return style;
40
+ }
41
+ const space = function(v) {
42
+ return typeof v === "number" ? "var(--aura-space-" + v + ")" : v;
43
+ };
44
+ export {
45
+ breakpoints,
46
+ respVars,
47
+ space,
48
+ useBreakpoint,
49
+ useResponsive
50
+ };
package/dist/index.d.ts CHANGED
@@ -870,6 +870,10 @@ export declare const Tabs: React$1.ForwardRefExoticComponent<TabsProps & React$1
870
870
  export declare const SideNav: React$1.ForwardRefExoticComponent<SideNavProps & React$1.RefAttributes<HTMLElement>>;
871
871
  export declare const Breadcrumb: React$1.ForwardRefExoticComponent<BreadcrumbProps & React$1.RefAttributes<HTMLElement>>;
872
872
  export declare const Avatar: React$1.ForwardRefExoticComponent<AvatarProps & React$1.RefAttributes<HTMLSpanElement>>;
873
+ /** Stack — one direction, even gaps. direction and gap may be responsive: { base: 'column', md: 'row' }. */
874
+ export declare const Stack: React$1.ForwardRefExoticComponent<StackProps & React$1.RefAttributes<HTMLElement>>;
875
+ /** Grid — equal columns. columns may be responsive ({ base: 1, md: 2, lg: 3 }), or use minItemWidth to fit as many as fit. */
876
+ export declare const Grid: React$1.ForwardRefExoticComponent<GridProps & React$1.RefAttributes<HTMLElement>>;
873
877
  /** Centred page column. */
874
878
  export interface ContainerProps {
875
879
  /** `narrow` caps it at aura-container-narrow (720px). Default `default` (1280px). */
@@ -879,6 +883,10 @@ export interface ContainerProps {
879
883
  style?: React$1.CSSProperties;
880
884
  children?: React$1.ReactNode;
881
885
  }
886
+ /** Container — centres content up to aura-container-max (1280px) with responsive side padding. */
887
+ export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps & React$1.RefAttributes<HTMLElement>>;
888
+ /** AppShell — side navigation + top bar + content. The nav is fixed from lg (1024px) up and a Drawer below it. */
889
+ export declare const AppShell: React$1.ForwardRefExoticComponent<AppShellProps & React$1.RefAttributes<HTMLDivElement>>;
882
890
  /** Min-width breakpoints in px, mirroring the aura-bp-* tokens. */
883
891
  export declare const breakpoints: {
884
892
  sm: 640;
@@ -890,14 +898,6 @@ export declare const breakpoints: {
890
898
  export declare function useBreakpoint(): Breakpoint;
891
899
  /** Pick a value for the current breakpoint from { base, sm, md, lg, xl } (falls back to the next smaller one). */
892
900
  export declare function useResponsive<T>(value: Responsive<T>): T | undefined;
893
- /** Stack — one direction, even gaps. direction and gap may be responsive: { base: 'column', md: 'row' }. */
894
- export declare const Stack: React$1.ForwardRefExoticComponent<StackProps & React$1.RefAttributes<HTMLElement>>;
895
- /** Grid — equal columns. columns may be responsive ({ base: 1, md: 2, lg: 3 }), or use minItemWidth to fit as many as fit. */
896
- export declare const Grid: React$1.ForwardRefExoticComponent<GridProps & React$1.RefAttributes<HTMLElement>>;
897
- /** Container — centres content up to aura-container-max (1280px) with responsive side padding. */
898
- export declare const Container: React$1.ForwardRefExoticComponent<ContainerProps & React$1.RefAttributes<HTMLElement>>;
899
- /** AppShell — side navigation + top bar + content. The nav is fixed from lg (1024px) up and a Drawer below it. */
900
- export declare const AppShell: React$1.ForwardRefExoticComponent<AppShellProps & React$1.RefAttributes<HTMLDivElement>>;
901
901
  export declare const Surface: React$1.ForwardRefExoticComponent<SurfaceProps & React$1.RefAttributes<HTMLElement>>;
902
902
  /** Every built-in label. Function entries build the text from their arguments. */
903
903
  export interface AuraStrings {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "4.7.2",
3
+ "version": "4.8.0",
4
4
  "description": "AURA Design System — React components (Enterprise Standard, Human Creative). Thai-first: Buddhist-era dates, Thai collation.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/dist/esm/extra.js DELETED
@@ -1,412 +0,0 @@
1
- 'use client';
2
- import * as React from "react";
3
- import { createPortal } from "react-dom";
4
- import {
5
- cx,
6
- omit,
7
- uid,
8
- useMaybeControlled,
9
- useMergedRef,
10
- useMounted,
11
- useIsoLayoutEffect,
12
- trapTab,
13
- FOCUSABLE
14
- } from "./internal.js";
15
- import { useStrings } from "./locale.js";
16
- import { Icon } from "./Icon.js";
17
- import { IconButton } from "./IconButton.js";
18
- const TONES = ["neutral", "accent", "success", "warning", "danger"];
19
- function tone(t) {
20
- return TONES.indexOf(t) >= 0 ? t : "neutral";
21
- }
22
- const Badge = React.forwardRef(function Badge2(props, ref) {
23
- const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
24
- return /* @__PURE__ */ React.createElement(
25
- "span",
26
- {
27
- ...rest,
28
- ref,
29
- className: cx(
30
- "aura-badge",
31
- "aura-badge--" + tone(props.tone),
32
- props.variant === "solid" && "is-solid",
33
- props.variant === "outline" && "is-outline",
34
- props.className
35
- )
36
- },
37
- props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, size: 12 }) : null,
38
- props.children
39
- );
40
- });
41
- const Tag = React.forwardRef(function Tag2(props, ref) {
42
- const t = useStrings();
43
- const selectable = props.onClick != null || props.selected != null;
44
- const rest = omit(props, ["onRemove", "selected", "icon", "className", "children", "disabled", "removeLabel"]);
45
- const inner = [
46
- props.icon ? /* @__PURE__ */ React.createElement(Icon, { key: "i", name: props.icon, size: 14 }) : null,
47
- /* @__PURE__ */ React.createElement("span", { key: "t", className: "aura-tag__text" }, props.children)
48
- ];
49
- if (selectable) {
50
- return /* @__PURE__ */ React.createElement(
51
- "button",
52
- {
53
- ...rest,
54
- ref,
55
- type: "button",
56
- "aria-pressed": !!props.selected,
57
- disabled: props.disabled,
58
- className: cx("aura-tag is-selectable", props.selected && "is-selected", props.className)
59
- },
60
- props.selected ? /* @__PURE__ */ React.createElement(Icon, { name: "check", size: 14 }) : inner[0],
61
- inner[1]
62
- );
63
- }
64
- 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(
65
- "button",
66
- {
67
- type: "button",
68
- className: "aura-tag__remove",
69
- "aria-label": props.removeLabel || t.remove(typeof props.children === "string" ? props.children : ""),
70
- onClick: props.onRemove
71
- },
72
- /* @__PURE__ */ React.createElement(Icon, { name: "x", size: 12 })
73
- ) : null);
74
- });
75
- const Progress = React.forwardRef(function Progress2(props, ref) {
76
- const auto = uid(), id = props.id || auto;
77
- const max = props.max || 100, det = props.value != null;
78
- const pct = det ? Math.max(0, Math.min(100, props.value / max * 100)) : 0;
79
- const shown = props.valueLabel != null ? props.valueLabel : det ? Math.round(pct) + "%" : null;
80
- return /* @__PURE__ */ React.createElement(
81
- "div",
82
- {
83
- ref,
84
- className: cx(
85
- "aura-progress",
86
- "aura-progress--" + tone(props.tone || "accent"),
87
- props.size === "sm" && "is-sm",
88
- props.className
89
- )
90
- },
91
- 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,
92
- /* @__PURE__ */ React.createElement(
93
- "div",
94
- {
95
- className: cx("aura-progress__track", !det && "is-indeterminate"),
96
- role: "progressbar",
97
- "aria-labelledby": props.label ? id + "-label" : void 0,
98
- "aria-label": props.label ? void 0 : props["aria-label"],
99
- "aria-valuemin": det ? 0 : void 0,
100
- "aria-valuemax": det ? max : void 0,
101
- "aria-valuenow": det ? props.value : void 0,
102
- "aria-valuetext": det && props.valueLabel != null ? String(props.valueLabel) : void 0
103
- },
104
- /* @__PURE__ */ React.createElement("span", { className: "aura-progress__bar", style: det ? { width: pct + "%" } : void 0 })
105
- ),
106
- props.hint ? /* @__PURE__ */ React.createElement("p", { className: "aura-progress__hint" }, props.hint) : null
107
- );
108
- });
109
- const Skeleton = React.forwardRef(function Skeleton2(props, ref) {
110
- const v = props.variant || "text";
111
- if (v === "text" && (props.lines || 1) > 1) {
112
- const n = props.lines, rows = [];
113
- for (let i = 0; i < n; i++)
114
- rows.push(/* @__PURE__ */ React.createElement("span", { key: i, className: "aura-skel aura-skel--text", style: { width: i === n - 1 ? "60%" : "100%" } }));
115
- return /* @__PURE__ */ React.createElement(
116
- "span",
117
- {
118
- ref,
119
- className: cx("aura-skel-lines", props.className),
120
- "aria-hidden": true,
121
- style: props.width ? { width: props.width } : void 0
122
- },
123
- rows
124
- );
125
- }
126
- const style = { width: props.width, height: props.height };
127
- if (v === "circle") {
128
- style.width = style.height = props.size || props.width || 40;
129
- }
130
- return /* @__PURE__ */ React.createElement("span", { ref, "aria-hidden": true, className: cx("aura-skel", "aura-skel--" + v, props.className), style });
131
- });
132
- const EmptyState = React.forwardRef(function EmptyState2(props, ref) {
133
- const HT = "h" + (props.headingLevel || 3);
134
- return /* @__PURE__ */ React.createElement(
135
- "div",
136
- {
137
- ref,
138
- className: cx("aura-empty", props.size === "sm" && "is-sm", props.bordered && "is-bordered", props.className)
139
- },
140
- /* @__PURE__ */ React.createElement("span", { className: "aura-empty__icon", "aria-hidden": true }, /* @__PURE__ */ React.createElement(Icon, { name: props.icon || "inbox", size: props.size === "sm" ? "md" : "lg" })),
141
- /* @__PURE__ */ React.createElement(HT, { className: "aura-empty__title" }, props.title),
142
- props.description ? /* @__PURE__ */ React.createElement("p", { className: "aura-empty__text" }, props.description) : null,
143
- props.action ? /* @__PURE__ */ React.createElement("div", { className: "aura-empty__action" }, props.action) : null
144
- );
145
- });
146
- function pageList(page, count, sib) {
147
- let out = [], lo = Math.max(2, page - sib), hi = Math.min(count - 1, page + sib);
148
- if (page - sib <= 3) {
149
- lo = 2;
150
- hi = Math.min(count - 1, Math.max(hi, 3 + 2 * sib));
151
- }
152
- if (page + sib >= count - 2) {
153
- hi = count - 1;
154
- lo = Math.max(2, Math.min(lo, count - 2 - 2 * sib));
155
- }
156
- out.push(1);
157
- if (lo === 3) out.push(2);
158
- else if (lo > 3) out.push("\u2026a");
159
- for (let i = lo; i <= hi; i++) out.push(i);
160
- if (hi === count - 2) out.push(count - 1);
161
- else if (hi < count - 2) out.push("\u2026b");
162
- if (count > 1) out.push(count);
163
- return out;
164
- }
165
- const Pagination = React.forwardRef(function Pagination2(props, ref) {
166
- const t = useStrings();
167
- const count = Math.max(1, props.pageCount || 1);
168
- const st = useMaybeControlled(props.page, props.defaultPage || 1, props.onChange);
169
- const page = Math.min(count, Math.max(1, st[0]));
170
- function go(p) {
171
- if (p >= 1 && p <= count && p !== page) st[1](p);
172
- }
173
- const link = props.getHref;
174
- function item(p, label, extra) {
175
- const common = Object.assign(
176
- {
177
- className: cx("aura-page", p === page && "is-current"),
178
- "aria-current": p === page ? "page" : void 0,
179
- "aria-label": t.pageN(p)
180
- },
181
- extra
182
- );
183
- return link ? /* @__PURE__ */ React.createElement(
184
- "a",
185
- {
186
- href: link(p),
187
- onClick: function(e) {
188
- if (props.onChange) {
189
- e.preventDefault();
190
- go(p);
191
- }
192
- },
193
- ...common
194
- },
195
- label
196
- ) : /* @__PURE__ */ React.createElement(
197
- "button",
198
- {
199
- type: "button",
200
- onClick: function() {
201
- go(p);
202
- },
203
- ...common
204
- },
205
- label
206
- );
207
- }
208
- return /* @__PURE__ */ React.createElement("nav", { ref, className: cx("aura-pagination", props.className), "aria-label": props.label || t.pagination }, /* @__PURE__ */ React.createElement(
209
- IconButton,
210
- {
211
- icon: "chevron-left",
212
- label: t.prevPage,
213
- disabled: page <= 1,
214
- onClick: function() {
215
- go(page - 1);
216
- }
217
- }
218
- ), /* @__PURE__ */ React.createElement("ol", { className: "aura-pagination__list" }, pageList(page, count, props.siblingCount == null ? 1 : props.siblingCount).map(function(p) {
219
- return typeof p === "number" ? /* @__PURE__ */ React.createElement("li", { key: p }, item(p, p)) : /* @__PURE__ */ React.createElement("li", { key: p, className: "aura-pagination__gap", "aria-hidden": true }, "\u2026");
220
- })), /* @__PURE__ */ React.createElement("span", { className: "aura-pagination__compact", "aria-hidden": true }, t.page(page, count)), /* @__PURE__ */ React.createElement(
221
- IconButton,
222
- {
223
- icon: "chevron-right",
224
- label: t.nextPage,
225
- disabled: page >= count,
226
- onClick: function() {
227
- go(page + 1);
228
- }
229
- }
230
- ));
231
- });
232
- const Accordion = React.forwardRef(function Accordion2(props, ref) {
233
- const auto = uid(), base = props.id || auto;
234
- const multiple = props.type === "multiple";
235
- const st = useMaybeControlled(
236
- props.value,
237
- props.defaultValue != null ? props.defaultValue : multiple ? [] : null,
238
- props.onChange
239
- );
240
- const open = multiple ? st[0] || [] : st[0] ? [st[0]] : [];
241
- const HT = "h" + (props.headingLevel || 3);
242
- const items = props.items || [];
243
- function toggle(id) {
244
- const isOpen = open.indexOf(id) >= 0;
245
- if (multiple)
246
- st[1](
247
- isOpen ? open.filter(function(x) {
248
- return x !== id;
249
- }) : open.concat([id])
250
- );
251
- else st[1](isOpen ? props.collapsible === false ? id : null : id);
252
- }
253
- function onKey(e) {
254
- const btns = Array.prototype.slice.call(
255
- e.currentTarget.querySelectorAll(
256
- ":scope > .aura-accordion__item > .aura-accordion__heading > button:not([disabled])"
257
- )
258
- );
259
- let i = btns.indexOf(document.activeElement), k = e.key, n = null;
260
- if (i < 0) return;
261
- if (k === "ArrowDown") n = btns[(i + 1) % btns.length];
262
- else if (k === "ArrowUp") n = btns[(i - 1 + btns.length) % btns.length];
263
- else if (k === "Home") n = btns[0];
264
- else if (k === "End") n = btns[btns.length - 1];
265
- if (n) {
266
- e.preventDefault();
267
- n.focus();
268
- }
269
- }
270
- return /* @__PURE__ */ React.createElement("div", { ref, className: cx("aura-accordion", props.className), onKeyDown: onKey }, items.map(function(it) {
271
- const on = open.indexOf(it.id) >= 0, bid = base + "-btn-" + it.id, pid = base + "-panel-" + it.id;
272
- return /* @__PURE__ */ React.createElement("div", { key: it.id, className: cx("aura-accordion__item", on && "is-open") }, /* @__PURE__ */ React.createElement(HT, { className: "aura-accordion__heading" }, /* @__PURE__ */ React.createElement(
273
- "button",
274
- {
275
- type: "button",
276
- id: bid,
277
- "aria-expanded": on,
278
- "aria-controls": pid,
279
- disabled: it.disabled,
280
- onClick: function() {
281
- toggle(it.id);
282
- }
283
- },
284
- it.icon ? /* @__PURE__ */ React.createElement(Icon, { name: it.icon, className: "aura-accordion__lead" }) : null,
285
- /* @__PURE__ */ React.createElement("span", { className: "aura-accordion__title" }, it.title, it.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-accordion__desc" }, it.description) : null),
286
- /* @__PURE__ */ React.createElement(Icon, { name: "chevron-down", className: "aura-accordion__chevron" })
287
- )), /* @__PURE__ */ React.createElement("div", { id: pid, role: "region", "aria-labelledby": bid, className: "aura-accordion__panel", hidden: !on }, it.content));
288
- }));
289
- });
290
- function position(anchor, pop, placement) {
291
- const r = anchor.getBoundingClientRect(), pw = pop.offsetWidth, ph = pop.offsetHeight, vw = window.innerWidth, vh = window.innerHeight, gap = 6;
292
- let side = (placement || "bottom-start").split("-")[0], align = (placement || "bottom-start").split("-")[1] || "start";
293
- if (side === "bottom" && r.bottom + gap + ph > vh - 8 && r.top - gap - ph > 8) side = "top";
294
- else if (side === "top" && r.top - gap - ph < 8 && r.bottom + gap + ph < vh - 8) side = "bottom";
295
- const top = side === "top" ? r.top - gap - ph : r.bottom + gap;
296
- const left = align === "end" ? r.right - pw : align === "center" ? r.left + r.width / 2 - pw / 2 : r.left;
297
- return { top: Math.max(8, top), left: Math.max(8, Math.min(left, vw - pw - 8)), side };
298
- }
299
- const Popover = React.forwardRef(function Popover2(props, ref) {
300
- const t = useStrings();
301
- const auto = uid(), id = props.id || auto;
302
- const st = useMaybeControlled(props.open, !!props.defaultOpen, props.onOpenChange);
303
- const open = !!st[0];
304
- const wrap = React.useRef(null), pop = React.useRef(null), popMerged = useMergedRef(ref, pop);
305
- const pos = React.useState(null), mounted = useMounted();
306
- function trigger() {
307
- return wrap.current && (wrap.current.querySelector('button, [role="button"], a, input') || wrap.current.firstElementChild);
308
- }
309
- function close(restore) {
310
- st[1](false);
311
- if (restore) {
312
- const tr = trigger();
313
- if (tr && tr.focus) tr.focus();
314
- }
315
- }
316
- useIsoLayoutEffect(
317
- function() {
318
- if (!open || !pop.current || !trigger()) return;
319
- function place() {
320
- if (pop.current && trigger()) pos[1](position(trigger(), pop.current, props.placement));
321
- }
322
- place();
323
- window.addEventListener("resize", place);
324
- window.addEventListener("scroll", place, true);
325
- return function() {
326
- window.removeEventListener("resize", place);
327
- window.removeEventListener("scroll", place, true);
328
- };
329
- },
330
- [open, mounted, props.placement]
331
- );
332
- React.useEffect(
333
- function() {
334
- if (!open || !mounted) return;
335
- if (props.autoFocus !== false && pop.current) {
336
- const f = pop.current.querySelector("[data-autofocus]") || pop.current.querySelector(FOCUSABLE);
337
- (f || pop.current).focus();
338
- }
339
- function outside(e) {
340
- if (pop.current && pop.current.contains(e.target)) return;
341
- if (wrap.current && wrap.current.contains(e.target)) return;
342
- close(false);
343
- }
344
- document.addEventListener("pointerdown", outside, true);
345
- return function() {
346
- document.removeEventListener("pointerdown", outside, true);
347
- };
348
- },
349
- [open, mounted]
350
- );
351
- const child = React.Children.only(props.trigger);
352
- const panel = open && mounted ? createPortal(
353
- /* @__PURE__ */ React.createElement(
354
- "div",
355
- {
356
- ref: popMerged,
357
- id,
358
- role: "dialog",
359
- "aria-modal": false,
360
- "aria-label": props.title ? void 0 : props.label,
361
- "aria-labelledby": props.title ? id + "-title" : void 0,
362
- tabIndex: -1,
363
- className: cx("aura-popover", pos[0] && "is-" + pos[0].side, props.className),
364
- style: Object.assign(
365
- { top: pos[0] ? pos[0].top : -9999, left: pos[0] ? pos[0].left : -9999 },
366
- props.width ? { width: props.width } : null
367
- ),
368
- onKeyDown: function(e) {
369
- if (e.key === "Escape") {
370
- e.stopPropagation();
371
- close(true);
372
- } else trapTab(e, pop.current);
373
- }
374
- },
375
- props.title ? /* @__PURE__ */ React.createElement("div", { className: "aura-popover__head" }, /* @__PURE__ */ React.createElement("p", { className: "aura-popover__title", id: id + "-title" }, props.title), /* @__PURE__ */ React.createElement(
376
- IconButton,
377
- {
378
- icon: "x",
379
- label: t.close,
380
- onClick: function() {
381
- close(true);
382
- }
383
- }
384
- )) : null,
385
- /* @__PURE__ */ React.createElement("div", { className: "aura-popover__body" }, typeof props.children === "function" ? props.children({
386
- close: function() {
387
- close(true);
388
- }
389
- }) : props.children)
390
- ),
391
- document.body
392
- ) : null;
393
- return /* @__PURE__ */ React.createElement("span", { ref: wrap, className: "aura-popover-anchor" }, React.cloneElement(child, {
394
- onClick: function(e) {
395
- if (child.props.onClick) child.props.onClick(e);
396
- st[1](!open);
397
- },
398
- "aria-haspopup": "dialog",
399
- "aria-expanded": open,
400
- "aria-controls": open ? id : void 0
401
- }), panel);
402
- });
403
- export {
404
- Accordion,
405
- Badge,
406
- EmptyState,
407
- Pagination,
408
- Popover,
409
- Progress,
410
- Skeleton,
411
- Tag
412
- };