@jirawatpyk/aura-react 4.8.0 → 4.10.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.
@@ -1,35 +1,141 @@
1
1
  'use client';
2
2
  import * as React from "react";
3
3
  import { Icon } from "./Icon.js";
4
- import { cx, useMaybeControlled } from "./internal.js";
5
- import { useStrings } from "./locale.js";
4
+ import { cx, uid, useMaybeControlled } from "./internal.js";
5
+ import { useLinkComponent, useStrings } from "./locale.js";
6
+ function contains(it, id) {
7
+ return !!id && !!it.children && it.children.some(function(c) {
8
+ return c.id === id || contains(c, id);
9
+ });
10
+ }
6
11
  const SideNav = React.forwardRef(function SideNav2(props, ref) {
7
12
  const t = useStrings();
13
+ const Link = useLinkComponent(props.linkComponent);
14
+ const base = uid();
8
15
  const st = useMaybeControlled(
9
16
  props.value,
10
17
  props.defaultValue,
11
18
  props.onChange
12
19
  );
13
- function item(it) {
14
- const on = st[0] === it.id;
15
- const inner = [
20
+ const active = st[0];
21
+ const sections = props.sections || [{ items: props.items || [] }];
22
+ const openState = React.useState({}), toggled = openState[0], setToggled = openState[1];
23
+ function isOpen(it) {
24
+ if (toggled[it.id] != null) return toggled[it.id];
25
+ return !!it.defaultOpen || contains(it, active);
26
+ }
27
+ React.useEffect(
28
+ function() {
29
+ if (!active) return;
30
+ const next = {};
31
+ let changed = false;
32
+ sections.forEach(function(s) {
33
+ (function walk(list) {
34
+ list.forEach(function(it) {
35
+ if (it.children) {
36
+ if (contains(it, active) && toggled[it.id] !== true) {
37
+ next[it.id] = true;
38
+ changed = true;
39
+ }
40
+ walk(it.children);
41
+ }
42
+ });
43
+ })(s.items);
44
+ });
45
+ if (changed) setToggled(Object.assign({}, toggled, next));
46
+ },
47
+ [active]
48
+ );
49
+ const navRef = React.useRef(null);
50
+ function onKeyDown(e) {
51
+ const k = e.key;
52
+ if (k !== "ArrowDown" && k !== "ArrowUp" && k !== "Home" && k !== "End") return;
53
+ const root = navRef.current;
54
+ if (!root) return;
55
+ const items = Array.prototype.slice.call(root.querySelectorAll(".aura-nav__item"));
56
+ const visible = items.filter(function(el) {
57
+ return el.offsetParent !== null || el === document.activeElement;
58
+ });
59
+ const i = visible.indexOf(document.activeElement);
60
+ if (i < 0) return;
61
+ e.preventDefault();
62
+ const j = k === "Home" ? 0 : k === "End" ? visible.length - 1 : Math.max(0, Math.min(visible.length - 1, i + (k === "ArrowDown" ? 1 : -1)));
63
+ visible[j].focus();
64
+ }
65
+ function inner(it, group, open) {
66
+ return [
16
67
  it.icon ? /* @__PURE__ */ React.createElement(Icon, { key: "i", name: it.icon }) : null,
17
68
  /* @__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
69
+ it.badge != null ? /* @__PURE__ */ React.createElement("span", { key: "b", className: "aura-nav__badge" }, it.badge) : null,
70
+ it.count != null ? /* @__PURE__ */ React.createElement("span", { key: "c", className: "aura-nav__count" }, it.count) : null,
71
+ group ? /* @__PURE__ */ React.createElement(Icon, { key: "g", name: "chevron-down", className: cx("aura-nav__chevron", open && "is-open") }) : null
19
72
  ];
73
+ }
74
+ function item(it, depth) {
75
+ if (it.children) {
76
+ const open = isOpen(it);
77
+ const listId = base + "-" + it.id;
78
+ const holdsActive = contains(it, active);
79
+ return /* @__PURE__ */ React.createElement("li", { key: it.id, className: "aura-nav__group" }, /* @__PURE__ */ React.createElement(
80
+ "button",
81
+ {
82
+ type: "button",
83
+ className: cx("aura-nav__item", "aura-nav__item--group", holdsActive && "has-active"),
84
+ "aria-expanded": open,
85
+ "aria-controls": listId,
86
+ style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
87
+ onClick: function() {
88
+ const next = Object.assign({}, toggled);
89
+ next[it.id] = !open;
90
+ setToggled(next);
91
+ },
92
+ onKeyDown: function(e) {
93
+ if (e.key === "ArrowRight" && !open) {
94
+ e.preventDefault();
95
+ setToggled(Object.assign({}, toggled, { [it.id]: true }));
96
+ } else if (e.key === "ArrowLeft" && open) {
97
+ e.preventDefault();
98
+ setToggled(Object.assign({}, toggled, { [it.id]: false }));
99
+ }
100
+ }
101
+ },
102
+ inner(it, true, open)
103
+ ), /* @__PURE__ */ React.createElement("ul", { id: listId, className: "aura-nav__list aura-nav__sub", hidden: !open }, it.children.map(function(c) {
104
+ return item(c, depth + 1);
105
+ })));
106
+ }
107
+ const on = active === it.id;
20
108
  const common = {
21
109
  className: cx("aura-nav__item", on && "is-active"),
22
110
  "aria-current": on ? "page" : void 0,
111
+ style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
23
112
  onClick: function(e) {
24
113
  if (!it.href) e.preventDefault();
25
114
  st[1](it.id);
26
115
  }
27
116
  };
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));
117
+ return /* @__PURE__ */ React.createElement("li", { key: it.id }, it.href ? /* @__PURE__ */ React.createElement(Link, { href: it.href, ...common }, inner(it, false, false)) : /* @__PURE__ */ React.createElement("button", { type: "button", ...common }, inner(it, false, false)));
29
118
  }
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);
119
+ return /* @__PURE__ */ React.createElement(
120
+ "nav",
121
+ {
122
+ ref: function(el) {
123
+ navRef.current = el;
124
+ if (typeof ref === "function") ref(el);
125
+ else if (ref) ref.current = el;
126
+ },
127
+ className: cx("aura-nav", props.className),
128
+ "aria-label": props.label || t.mainNav,
129
+ onKeyDown
130
+ },
131
+ props.header ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__header" }, props.header) : null,
132
+ /* @__PURE__ */ React.createElement("div", { className: "aura-nav__scroll" }, sections.map(function(s, i) {
133
+ 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(function(it) {
134
+ return item(it, 0);
135
+ })));
136
+ })),
137
+ props.footer ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__footer" }, props.footer) : null
138
+ );
33
139
  });
34
140
  export {
35
141
  SideNav
package/dist/esm/Stat.js CHANGED
@@ -2,12 +2,16 @@
2
2
  import * as React from "react";
3
3
  import { cx } from "./internal.js";
4
4
  import { Icon } from "./Icon.js";
5
+ import { useLinkComponent } from "./locale.js";
5
6
  const Stat = React.forwardRef(function Stat2(props, ref) {
6
7
  const ch = props.change;
7
8
  const dir = ch && (ch.direction || "flat");
8
9
  const tone = ch && (ch.tone || (dir === "up" ? "positive" : dir === "down" ? "negative" : "neutral"));
9
- const Tag = props.href ? "a" : props.onClick ? "button" : "div";
10
- const interactive = Tag !== "div";
10
+ const Link = useLinkComponent();
11
+ const v = props.value;
12
+ const numeric = typeof v === "number" || typeof v === "string" && /\d/.test(v) && /^[\s\d.,:+\-\u2212%()\u0E3F$\u20AC\u00A3\u00A5kKmMbB]+$/.test(v.replace(/\b[A-Z]{3}\b/g, ""));
13
+ const Tag = props.href ? Link : props.onClick ? "button" : "div";
14
+ const interactive = !!(props.href || props.onClick);
11
15
  return /* @__PURE__ */ React.createElement(
12
16
  Tag,
13
17
  {
@@ -19,7 +23,7 @@ const Stat = React.forwardRef(function Stat2(props, ref) {
19
23
  "aria-busy": props.loading || void 0
20
24
  },
21
25
  /* @__PURE__ */ React.createElement("span", { className: "aura-stat__head" }, /* @__PURE__ */ React.createElement("span", { className: "aura-stat__label" }, props.label), props.icon ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__icon" }, /* @__PURE__ */ React.createElement(Icon, { name: props.icon })) : null),
22
- props.loading ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__value" }, /* @__PURE__ */ React.createElement("span", { className: "aura-skel aura-stat__skel" })) : /* @__PURE__ */ React.createElement("span", { className: "aura-stat__value" }, props.value, props.unit ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__unit" }, props.unit) : null),
26
+ props.loading ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__value" }, /* @__PURE__ */ React.createElement("span", { className: "aura-skel aura-stat__skel" })) : /* @__PURE__ */ React.createElement("span", { className: cx("aura-stat__value", numeric && "is-numeric") }, props.value, props.unit ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__unit" }, props.unit) : null),
23
27
  ch && !props.loading || props.caption ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__foot" }, ch && !props.loading ? /* @__PURE__ */ React.createElement("span", { className: cx("aura-stat__change", "is-" + tone) }, /* @__PURE__ */ React.createElement(Icon, { name: dir === "up" ? "trending-up" : dir === "down" ? "trending-down" : "minus", size: 14 }), /* @__PURE__ */ React.createElement("span", null, ch.value)) : null, ch && ch.label && !props.loading ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__caption" }, ch.label) : null, props.caption ? /* @__PURE__ */ React.createElement("span", { className: "aura-stat__caption" }, props.caption) : null) : null
24
28
  );
25
29
  });
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { Icon } from "./Icon.js";
4
+ import { cx } from "./internal.js";
5
+ import { useStrings } from "./locale.js";
6
+ const Stepper = React.forwardRef(function Stepper2(props, ref) {
7
+ const t = useStrings();
8
+ const steps = props.steps || [];
9
+ let at = -1;
10
+ steps.forEach(function(s, i) {
11
+ if (s.id === props.current) at = i;
12
+ });
13
+ if (at < 0) at = 0;
14
+ const vertical = props.orientation === "vertical";
15
+ const cur = steps[at];
16
+ return /* @__PURE__ */ React.createElement(
17
+ "nav",
18
+ {
19
+ ref,
20
+ "aria-label": props.label,
21
+ className: cx("aura-stepper", vertical ? "aura-stepper--vertical" : "aura-stepper--horizontal", props.className)
22
+ },
23
+ /* @__PURE__ */ React.createElement("ol", { className: "aura-stepper__list" }, steps.map(function(s, i) {
24
+ const state = i < at ? "done" : i === at ? "current" : "upcoming";
25
+ const marker = /* @__PURE__ */ React.createElement("span", { className: "aura-stepper__marker", "aria-hidden": true }, state === "done" ? /* @__PURE__ */ React.createElement(Icon, { name: "check" }) : i + 1);
26
+ const text = /* @__PURE__ */ React.createElement("span", { className: "aura-stepper__text" }, /* @__PURE__ */ React.createElement("span", { className: "aura-stepper__label" }, s.label, state === "done" ? /* @__PURE__ */ React.createElement("span", { className: "aura-sr-only" }, ", " + t.stepDone) : null), s.description ? /* @__PURE__ */ React.createElement("span", { className: "aura-stepper__desc" }, s.description) : null);
27
+ const clickable = state === "done" && !!props.onStepClick;
28
+ return /* @__PURE__ */ React.createElement(
29
+ "li",
30
+ {
31
+ key: s.id,
32
+ className: cx("aura-stepper__item", "is-" + state),
33
+ "aria-current": state === "current" ? "step" : void 0
34
+ },
35
+ clickable ? /* @__PURE__ */ React.createElement(
36
+ "button",
37
+ {
38
+ type: "button",
39
+ className: "aura-stepper__step aura-focusable",
40
+ onClick: function() {
41
+ props.onStepClick(s.id);
42
+ }
43
+ },
44
+ marker,
45
+ text
46
+ ) : /* @__PURE__ */ React.createElement("span", { className: "aura-stepper__step" }, marker, text)
47
+ );
48
+ })),
49
+ !vertical && cur ? /* @__PURE__ */ React.createElement("p", { className: "aura-stepper__compact", "aria-hidden": true }, /* @__PURE__ */ React.createElement("span", { className: "aura-stepper__count" }, t.stepOf(at + 1, steps.length)), /* @__PURE__ */ React.createElement("span", { className: "aura-stepper__compact-label" }, cur.label)) : null
50
+ );
51
+ });
52
+ export {
53
+ Stepper
54
+ };
@@ -15,7 +15,14 @@ function colorSchemeScript(options) {
15
15
  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){}})();`;
16
16
  }
17
17
  function ColorSchemeScript(props) {
18
- return /* @__PURE__ */ React.createElement("script", { "data-aura-color-scheme": "", dangerouslySetInnerHTML: { __html: colorSchemeScript(props) } });
18
+ return /* @__PURE__ */ React.createElement(
19
+ "script",
20
+ {
21
+ "data-aura-color-scheme": "",
22
+ nonce: props.nonce,
23
+ dangerouslySetInnerHTML: { __html: colorSchemeScript(props) }
24
+ }
25
+ );
19
26
  }
20
27
  function systemDark() {
21
28
  return typeof window !== "undefined" && !!window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
package/dist/esm/index.js CHANGED
@@ -45,6 +45,9 @@ import { EmptyState } from "./EmptyState.js";
45
45
  import { Pagination } from "./Pagination.js";
46
46
  import { Accordion } from "./Accordion.js";
47
47
  import { Popover } from "./Popover.js";
48
+ import { NumberField } from "./NumberField.js";
49
+ import { Stepper } from "./Stepper.js";
50
+ import { SegmentedControl } from "./SegmentedControl.js";
48
51
  export {
49
52
  Accordion,
50
53
  Alert,
@@ -75,17 +78,20 @@ export {
75
78
  Icon,
76
79
  IconButton,
77
80
  Menu,
81
+ NumberField,
78
82
  Pagination,
79
83
  Popover,
80
84
  Progress,
81
85
  RadioGroup,
82
86
  STRINGS,
87
+ SegmentedControl,
83
88
  Select,
84
89
  SideNav,
85
90
  Skeleton,
86
91
  Stack,
87
92
  Stat,
88
93
  StatusPill,
94
+ Stepper,
89
95
  Surface,
90
96
  Switch,
91
97
  Tabs,
@@ -3,6 +3,9 @@ import * as React from "react";
3
3
  const n = function(x) {
4
4
  return Number(x).toLocaleString("en");
5
5
  };
6
+ const nsv = function(x) {
7
+ return Number(x).toLocaleString("sv-SE");
8
+ };
6
9
  const STRINGS = {
7
10
  en: {
8
11
  close: "Close",
@@ -83,6 +86,12 @@ const STRINGS = {
83
86
  return "Up to " + n2 + " files";
84
87
  },
85
88
  colorScheme: "Colour scheme",
89
+ increase: "Increase",
90
+ decrease: "Decrease",
91
+ stepDone: "completed",
92
+ stepOf: function(i, total) {
93
+ return "Step " + i + " of " + total;
94
+ },
86
95
  schemeLight: "Light",
87
96
  schemeDark: "Dark",
88
97
  schemeSystem: "System",
@@ -175,6 +184,12 @@ const STRINGS = {
175
184
  return "\u0E41\u0E19\u0E1A\u0E44\u0E14\u0E49\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 " + n2 + " \u0E44\u0E1F\u0E25\u0E4C";
176
185
  },
177
186
  colorScheme: "\u0E42\u0E2B\u0E21\u0E14\u0E2A\u0E35",
187
+ increase: "\u0E40\u0E1E\u0E34\u0E48\u0E21",
188
+ decrease: "\u0E25\u0E14",
189
+ stepDone: "\u0E40\u0E2A\u0E23\u0E47\u0E08\u0E41\u0E25\u0E49\u0E27",
190
+ stepOf: function(i, total) {
191
+ return "\u0E02\u0E31\u0E49\u0E19\u0E17\u0E35\u0E48 " + i + " \u0E08\u0E32\u0E01 " + total;
192
+ },
178
193
  schemeLight: "\u0E2A\u0E27\u0E48\u0E32\u0E07",
179
194
  schemeDark: "\u0E21\u0E37\u0E14",
180
195
  schemeSystem: "\u0E15\u0E32\u0E21\u0E23\u0E30\u0E1A\u0E1A",
@@ -187,6 +202,104 @@ const STRINGS = {
187
202
  accepts: function(list, max) {
188
203
  return [list, max && "\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 " + max + " \u0E15\u0E48\u0E2D\u0E44\u0E1F\u0E25\u0E4C"].filter(Boolean).join(" \xB7 ");
189
204
  }
205
+ },
206
+ sv: {
207
+ close: "St\xE4ng",
208
+ dismiss: "St\xE4ng",
209
+ dismissToast: "St\xE4ng aviseringen",
210
+ notifications: "Aviseringar",
211
+ mainNav: "Huvudmeny",
212
+ breadcrumb: "Br\xF6dsmulor",
213
+ navigation: "Navigering",
214
+ openNav: "\xD6ppna menyn",
215
+ searching: "S\xF6ker\u2026",
216
+ noMatches: "Inga tr\xE4ffar",
217
+ clear: function(what) {
218
+ return "Rensa " + (what || "urvalet");
219
+ },
220
+ keepTyping: function(total) {
221
+ return "Skriv mer f\xF6r att begr\xE4nsa " + nsv(total) + " alternativ";
222
+ },
223
+ sortAsc: "Sortera stigande",
224
+ sortDesc: "Sortera fallande",
225
+ pin: "F\xE4st till v\xE4nster",
226
+ unpin: "Lossa kolumnen",
227
+ moveLeft: "Flytta v\xE4nster",
228
+ moveRight: "Flytta h\xF6ger",
229
+ hideColumn: "D\xF6lj kolumnen",
230
+ resetColumns: "\xC5terst\xE4ll kolumner",
231
+ selectRows: "V\xE4lj rader",
232
+ selectAllRows: "V\xE4lj alla rader",
233
+ deselectAllRows: "Avmarkera alla rader",
234
+ selectAll: "V\xE4lj alla",
235
+ selectRow: function(k) {
236
+ return "V\xE4lj " + k;
237
+ },
238
+ selectedCount: function(c) {
239
+ return nsv(c) + " valda";
240
+ },
241
+ pinned: "F\xE4st",
242
+ columnOptions: function(label) {
243
+ return "Alternativ f\xF6r kolumnen " + label;
244
+ },
245
+ column: function(label) {
246
+ return label ? "Kolumnen " + label : "Kolumn";
247
+ },
248
+ columns: "Kolumner",
249
+ showHideColumns: "Visa eller d\xF6lj kolumner",
250
+ empty: "Inget h\xE4r \xE4nnu",
251
+ loading: "Laddar\u2026",
252
+ loadingRows: "Laddar rader",
253
+ range: function(a, b, total) {
254
+ return a + "\u2013" + b + " av " + nsv(total);
255
+ },
256
+ page: function(p, total) {
257
+ return "Sida " + p + " av " + total;
258
+ },
259
+ prevPage: "F\xF6reg\xE5ende sida",
260
+ nextPage: "N\xE4sta sida",
261
+ rowCount: function(c) {
262
+ return nsv(c) + " rader";
263
+ },
264
+ actions: "\xC5tg\xE4rder",
265
+ optional: "valfritt",
266
+ timePlaceholder: "tt:mm",
267
+ timeInvalid: "Skriv en tid som 09:30",
268
+ timeOutOfRange: function(a, b) {
269
+ return "V\xE4lj en tid mellan " + a + " och " + b;
270
+ },
271
+ dropFiles: "Dra filer hit eller",
272
+ browse: "V\xE4lj filer",
273
+ browseOne: "V\xE4lj en fil",
274
+ remove: function(n2) {
275
+ return "Ta bort " + n2;
276
+ },
277
+ fileTooBig: function(max) {
278
+ return "St\xF6rre \xE4n " + max;
279
+ },
280
+ fileWrongType: "Den h\xE4r filtypen godtas inte",
281
+ tooManyFiles: function(n2) {
282
+ return "H\xF6gst " + n2 + " filer";
283
+ },
284
+ colorScheme: "F\xE4rgl\xE4ge",
285
+ increase: "\xD6ka",
286
+ decrease: "Minska",
287
+ stepDone: "klart",
288
+ stepOf: function(i, total) {
289
+ return "Steg " + i + " av " + total;
290
+ },
291
+ schemeLight: "Ljust",
292
+ schemeDark: "M\xF6rkt",
293
+ schemeSystem: "System",
294
+ uploading: "Laddar upp\u2026",
295
+ images: "Bilder",
296
+ pagination: "Sidnumrering",
297
+ pageN: function(p) {
298
+ return "Sida " + p;
299
+ },
300
+ accepts: function(list, max) {
301
+ return [list, max && "h\xF6gst " + max + " per fil"].filter(Boolean).join(", ");
302
+ }
190
303
  }
191
304
  };
192
305
  const LocaleContext = React.createContext(null);
@@ -197,16 +310,21 @@ function AuraProvider(props) {
197
310
  return {
198
311
  locale: props.locale || "en",
199
312
  calendar: props.calendar || null,
200
- strings: props.strings ? Object.assign({}, base, props.strings) : base
313
+ strings: props.strings ? Object.assign({}, base, props.strings) : base,
314
+ linkComponent: props.linkComponent || null
201
315
  };
202
316
  },
203
- [props.locale, props.calendar, props.strings]
317
+ [props.locale, props.calendar, props.strings, props.linkComponent]
204
318
  );
205
319
  return /* @__PURE__ */ React.createElement(LocaleContext.Provider, { value }, props.children);
206
320
  }
207
321
  function useAuraLocale() {
208
322
  return React.useContext(LocaleContext) || { locale: null, calendar: null, strings: STRINGS.en };
209
323
  }
324
+ function useLinkComponent(own) {
325
+ const ctx = React.useContext(LocaleContext);
326
+ return own || ctx && ctx.linkComponent || "a";
327
+ }
210
328
  function useStrings() {
211
329
  return useAuraLocale().strings;
212
330
  }
@@ -214,5 +332,6 @@ export {
214
332
  AuraProvider,
215
333
  STRINGS,
216
334
  useAuraLocale,
335
+ useLinkComponent,
217
336
  useStrings
218
337
  };
package/dist/esm/theme.js CHANGED
@@ -105,6 +105,20 @@ function fit(hex, grounds, target, dir) {
105
105
  }
106
106
  return c;
107
107
  }
108
+ function atLuminance(hex, Y) {
109
+ const o = rgbToOklch(hexToRgb(hex)), C = Math.max(o[1], 0.02);
110
+ let lo = 0, hi = 1, c = hex;
111
+ for (let i = 0; i < 30; i++) {
112
+ const mid = (lo + hi) / 2;
113
+ c = oklchToHex(mid, C, o[2]);
114
+ if (luminance(c) < Y) lo = mid;
115
+ else hi = mid;
116
+ }
117
+ return c;
118
+ }
119
+ const CHART_Y = { light: 0.075, dark: 0.46 };
120
+ const SEQ_Y = { light: [0.26, 0.165, 0.1, 0.055, 0.028], dark: [0.14, 0.22, 0.34, 0.5, 0.7] };
121
+ const CHART_2 = "#0a8b7a";
108
122
  const ZINC = { 0: "#ffffff", 50: "#fafafa", 100: "#f4f4f5", 800: "#27272a", 900: "#18181b", 950: "#09090b" };
109
123
  const INK = "#18181b";
110
124
  function createTheme(opts) {
@@ -123,6 +137,14 @@ function createTheme(opts) {
123
137
  L["alert-info-fg"] = fit(b[800], [b[50]], 4.5, -1);
124
138
  L["alert-info-border"] = b[200];
125
139
  L["mesh-from"] = b[400];
140
+ L["chart-1"] = atLuminance(o.brand, CHART_Y.light);
141
+ D["chart-1"] = atLuminance(o.brand, CHART_Y.dark);
142
+ SEQ_Y.light.forEach(function(y, i) {
143
+ L["chart-seq-" + (i + 1)] = atLuminance(o.brand, y);
144
+ });
145
+ SEQ_Y.dark.forEach(function(y, i) {
146
+ D["chart-seq-" + (i + 1)] = atLuminance(o.brand, y);
147
+ });
126
148
  D["fg-accent"] = fit(b[300], darkGrounds, 4.5, 1);
127
149
  D["accent-violet"] = fit(b[400], darkGrounds, 3, 1);
128
150
  D["focus-ring"] = fit(b[400], darkGrounds, 3, 1);
@@ -182,6 +204,19 @@ function createTheme(opts) {
182
204
  check("dark", "fg-accent", g[0], 4.5, D["fg-accent"], g[1]);
183
205
  check("dark", "focus-ring", g[0], 3, D["focus-ring"], g[1]);
184
206
  });
207
+ [
208
+ ["light", ZINC[0], L],
209
+ ["light", ZINC[50], L],
210
+ ["dark", ZINC[900], D],
211
+ ["dark", ZINC[950], D]
212
+ ].forEach(function(g) {
213
+ const t = g[0], ground = g[1], m = g[2], name = ground === ZINC[0] || ground === ZINC[900] ? "bg-surface" : "bg-canvas";
214
+ ["chart-1", "chart-seq-1", "chart-seq-5"].forEach(function(k) {
215
+ check(t, k, name, 3, m[k], ground);
216
+ });
217
+ });
218
+ check("light", "chart-1", "chart-2 (lightness step)", 1.8, L["chart-1"], CHART_2);
219
+ check("dark", "chart-1", "chart-2 (lightness step)", 1.8, D["chart-1"], CHART_2);
185
220
  check("light", "fg-primary", "bg-selected", 4.5, INK, L["bg-selected"]);
186
221
  check("dark", "fg-primary", "bg-selected", 4.5, "#ffffff", D["bg-selected"]);
187
222
  check("light", "status-progress-fg", "status-progress-bg", 4.5, L["status-progress-fg"], L["status-progress-bg"]);