@monimesl/dot-renderer-react 1.0.0-beta.7 → 1.0.0-beta.8

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 (43) hide show
  1. package/dist/components/amount-input.js +1 -1
  2. package/dist/components/avatar.js +1 -1
  3. package/dist/components/box.js +8 -2
  4. package/dist/components/button.js +64 -14
  5. package/dist/components/carousel.js +4 -4
  6. package/dist/components/chip.js +3 -3
  7. package/dist/components/code-input.js +1 -1
  8. package/dist/components/detail-row.js +5 -5
  9. package/dist/components/disclosure.js +4 -4
  10. package/dist/components/empty-state.js +7 -6
  11. package/dist/components/feedback.js +7 -7
  12. package/dist/components/field-box.js +1 -1
  13. package/dist/components/field.js +5 -4
  14. package/dist/components/footer.js +3 -3
  15. package/dist/components/grid.js +16 -13
  16. package/dist/components/icon-button.js +1 -1
  17. package/dist/components/icon.js +32 -5
  18. package/dist/components/input.js +1 -1
  19. package/dist/components/list.js +10 -8
  20. package/dist/components/option.js +3 -3
  21. package/dist/components/padding.js +9 -10
  22. package/dist/components/prose.js +23 -20
  23. package/dist/components/scroll.js +4 -3
  24. package/dist/components/select.js +1 -1
  25. package/dist/components/sheet.js +8 -7
  26. package/dist/components/skeleton.js +1 -1
  27. package/dist/components/slider.js +3 -3
  28. package/dist/components/spinner.js +1 -1
  29. package/dist/components/stepper.js +3 -3
  30. package/dist/components/steps.js +17 -14
  31. package/dist/components/tabs.js +7 -7
  32. package/dist/components/text.js +10 -14
  33. package/dist/components/toast.js +3 -3
  34. package/dist/components/toggles.js +13 -9
  35. package/dist/components/tokens.d.ts +16 -0
  36. package/dist/components/tokens.js +11 -1
  37. package/dist/components/view.js +16 -7
  38. package/dist/page-root.js +9 -3
  39. package/dist/pull-to-refresh.js +1 -1
  40. package/dist/root.js +3 -3
  41. package/dist/theme.d.ts +11 -1
  42. package/dist/theme.js +80 -14
  43. package/package.json +4 -4
@@ -1,5 +1,5 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { SPACE, WEIGHTS } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { Field } from "./field.js";
4
4
  import { BARE_INPUT_STYLE, useFieldBox, useFieldNote } from "./field-box.js";
5
5
  import { useTypedText } from "./typed-text.js";
@@ -1,5 +1,5 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { WEIGHTS } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { USER_ARTWORK } from "./icon-artwork.js";
4
4
  import { IconSvg } from "./icon-svg.js";
5
5
  import { useState } from "react";
@@ -1,5 +1,5 @@
1
1
  import { CARD_RADIUS_SCALE } from "./tokens.js";
2
- import { isTone, toneBackground } from "./tones.js";
2
+ import { isTone, toneBackground, toneColor } from "./tones.js";
3
3
  import { BACKGROUNDS } from "@monimesl/dot-core";
4
4
  //#region src/components/box.ts
5
5
  const RADIUS_SCALE = {
@@ -38,6 +38,7 @@ function boxStyle(props, theme, look = {}) {
38
38
  function backgroundColor(background, theme) {
39
39
  if (isTone(background)) return toneBackground(theme.colors, background);
40
40
  if (BACKGROUND_WORDS.has(background)) return theme.colors[background];
41
+ if (Object.hasOwn(theme.gradients, background)) return theme.gradients[background];
41
42
  return customColor(background, theme);
42
43
  }
43
44
  const unknownColors = /* @__PURE__ */ new Set();
@@ -52,5 +53,10 @@ function customColor(name, theme) {
52
53
  function cssLength(value) {
53
54
  return value === "fill" ? "100%" : value;
54
55
  }
56
+ function textToneColor(tone, theme) {
57
+ if (isTone(tone)) return toneColor(theme.colors, tone);
58
+ if (tone === "onPrimary") return theme.colors.onPrimary;
59
+ return customColor(tone, theme);
60
+ }
55
61
  //#endregion
56
- export { boxStyle, customColor };
62
+ export { boxStyle, customColor, textToneColor };
@@ -1,15 +1,31 @@
1
+ import { DISABLED_OPACITY, ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { DISABLED_OPACITY, FONT_SIZE, ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
3
3
  import { LoadingIcon } from "./spinner.js";
4
- import { createEvent } from "@monimesl/dot-core";
4
+ import { toneBackground } from "./tones.js";
5
+ import { DEFAULT_VARIANTS, createEvent, textOn } from "@monimesl/dot-core";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/components/button.tsx
7
- const Button$1 = ({ variant = "primary", disabled, loading, onClick, children }) => {
8
- const { colors, radius } = useTheme();
9
- const filled = variant === "primary" && !disabled;
10
- let color = colors.text;
11
- if (filled) color = colors.onPrimary;
12
- else if (disabled) color = colors.subtle;
8
+ const SIZES = {
9
+ small: {
10
+ minHeight: 36,
11
+ padding: "8px 14px",
12
+ text: "caption"
13
+ },
14
+ medium: {
15
+ minHeight: 48,
16
+ padding: "12px 20px",
17
+ text: "body"
18
+ },
19
+ large: {
20
+ minHeight: 56,
21
+ padding: "16px 24px",
22
+ text: "lead"
23
+ }
24
+ };
25
+ const Button$1 = ({ variant = DEFAULT_VARIANTS.Button, tone = "default", size = "medium", disabled, loading, onClick, children }) => {
26
+ const { colors, radius, fontSize } = useTheme();
27
+ const look = buttonLook(colors, variant, tone, Boolean(disabled));
28
+ const sizing = SIZES[size];
13
29
  return /* @__PURE__ */ jsxs("button", {
14
30
  type: "button",
15
31
  className: "dot-button",
@@ -23,13 +39,13 @@ const Button$1 = ({ variant = "primary", disabled, loading, onClick, children })
23
39
  alignItems: "center",
24
40
  justifyContent: "center",
25
41
  gap: SPACE.medium,
26
- minHeight: 48,
27
- padding: "12px 20px",
28
- border: "none",
42
+ minHeight: sizing.minHeight,
43
+ padding: sizing.padding,
44
+ border: look.border,
29
45
  borderRadius: radius,
30
- background: filled ? colors.primary : colors.muted,
31
- color,
32
- fontSize: FONT_SIZE.body,
46
+ background: look.background,
47
+ color: look.color,
48
+ fontSize: fontSize[sizing.text],
33
49
  fontWeight: WEIGHTS.bold,
34
50
  lineHeight: "normal",
35
51
  opacity: disabled ? DISABLED_OPACITY : 1,
@@ -38,5 +54,39 @@ const Button$1 = ({ variant = "primary", disabled, loading, onClick, children })
38
54
  children: [loading ? /* @__PURE__ */ jsx(LoadingIcon, { size: ICON_SIZE.small }) : null, children]
39
55
  });
40
56
  };
57
+ function buttonLook(colors, variant, tone, disabled) {
58
+ const toneColor = tone === "default" ? void 0 : colors[tone];
59
+ if (variant === "outline" || variant === "ghost") {
60
+ let color = toneColor ?? colors.primary;
61
+ if (disabled) color = colors.subtle;
62
+ let border = "none";
63
+ if (variant === "outline") border = `1px solid ${disabled ? colors.border : color}`;
64
+ return {
65
+ background: "transparent",
66
+ color,
67
+ border
68
+ };
69
+ }
70
+ if (disabled) return {
71
+ background: colors.muted,
72
+ color: colors.subtle,
73
+ border: "none"
74
+ };
75
+ if (variant === "secondary") return {
76
+ background: toneBackground(colors, tone),
77
+ color: toneColor ?? colors.text,
78
+ border: "none"
79
+ };
80
+ if (toneColor) return {
81
+ background: toneColor,
82
+ color: textOn(toneColor),
83
+ border: "none"
84
+ };
85
+ return {
86
+ background: colors.primary,
87
+ color: colors.onPrimary,
88
+ border: "none"
89
+ };
90
+ }
41
91
  //#endregion
42
92
  export { Button$1 as Button };
@@ -1,5 +1,5 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { SPACE } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { clamp } from "./numbers.js";
4
4
  import { paddingStyle } from "./padding.js";
5
5
  import { createEvent } from "@monimesl/dot-core";
@@ -13,7 +13,7 @@ const SWIPE_SPEED = .4;
13
13
  const EDGE_RESISTANCE = .3;
14
14
  const TAP_SLOP = 6;
15
15
  const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator = "dots", gap = "none", effect = "slide", index, onChange, children, ...padding }) => {
16
- const { colors } = useTheme();
16
+ const { colors, space } = useTheme();
17
17
  const slides = slidesOf(children);
18
18
  const count = slides.length;
19
19
  const looping = loop && count > 1;
@@ -131,7 +131,7 @@ const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator
131
131
  if (Math.abs(movedX) > viewportWidth * SWIPE_DISTANCE || speed > SWIPE_SPEED) stepBy(movedX < 0 ? 1 : -1);
132
132
  else moveTo(shownPosition);
133
133
  };
134
- const gapWidth = SPACE[gap];
134
+ const gapWidth = space[gap];
135
135
  const transition = animated ? `transform ${SLIDE_DURATION}ms ${SLIDE_EASING}` : "none";
136
136
  let draggedSlides = 0;
137
137
  if (viewportWidth > 0) draggedSlides = dragOffset / (viewportWidth + gapWidth);
@@ -156,7 +156,7 @@ const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator
156
156
  flexDirection: "column",
157
157
  gap: SPACE.medium,
158
158
  minWidth: 0,
159
- ...paddingStyle(padding)
159
+ ...paddingStyle(padding, space)
160
160
  },
161
161
  children: [/* @__PURE__ */ jsx("div", {
162
162
  ref: viewportRef,
@@ -1,11 +1,11 @@
1
+ import { DISABLED_OPACITY, ICON_SIZE, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { DISABLED_OPACITY, FONT_SIZE, ICON_SIZE, WEIGHTS } from "./tokens.js";
3
3
  import { IconGraphic } from "./icon.js";
4
4
  import { createEvent } from "@monimesl/dot-core";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/components/chip.tsx
7
7
  const Chip$1 = ({ label, icon, selected = false, disabled, onTap }) => {
8
- const { colors } = useTheme();
8
+ const { colors, fontSize } = useTheme();
9
9
  return /* @__PURE__ */ jsxs("button", {
10
10
  type: "button",
11
11
  className: "dot-chip",
@@ -23,7 +23,7 @@ const Chip$1 = ({ label, icon, selected = false, disabled, onTap }) => {
23
23
  border: `1px solid ${selected ? colors.primary : colors.border}`,
24
24
  background: selected ? colors.primary : colors.surface,
25
25
  color: selected ? colors.onPrimary : colors.text,
26
- fontSize: FONT_SIZE.caption,
26
+ fontSize: fontSize.caption,
27
27
  fontWeight: WEIGHTS.medium,
28
28
  lineHeight: "normal",
29
29
  whiteSpace: "nowrap",
@@ -1,5 +1,5 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { CENTERED, DISABLED_OPACITY, SPACE, WEIGHTS } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { Field } from "./field.js";
4
4
  import { fieldBorderColor, useFieldNote } from "./field-box.js";
5
5
  import { useTypedText } from "./typed-text.js";
@@ -1,11 +1,11 @@
1
+ import { WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { FONT_SIZE, WEIGHTS } from "./tokens.js";
3
- import { insets, paddingStyle } from "./padding.js";
4
3
  import { toneColor } from "./tones.js";
4
+ import { insets, paddingStyle } from "./padding.js";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/components/detail-row.tsx
7
7
  const DetailRow = ({ label, value, tone, weight = "regular", ...padding }) => {
8
- const { colors } = useTheme();
8
+ const { colors, space, fontSize } = useTheme();
9
9
  return /* @__PURE__ */ jsxs("div", {
10
10
  className: "dot-detail-row",
11
11
  style: {
@@ -13,8 +13,8 @@ const DetailRow = ({ label, value, tone, weight = "regular", ...padding }) => {
13
13
  alignItems: "baseline",
14
14
  justifyContent: "space-between",
15
15
  gap: 16,
16
- ...paddingStyle(padding, insets(6, 0)),
17
- fontSize: FONT_SIZE.body,
16
+ ...paddingStyle(padding, space, insets(6, 0)),
17
+ fontSize: fontSize.body,
18
18
  lineHeight: "normal"
19
19
  },
20
20
  children: [/* @__PURE__ */ jsx("span", {
@@ -1,5 +1,5 @@
1
+ import { ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { FONT_SIZE, ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
3
3
  import { CHEVRON_DOWN_ARTWORK } from "./icon-artwork.js";
4
4
  import { IconSvg } from "./icon-svg.js";
5
5
  import { createEvent } from "@monimesl/dot-core";
@@ -7,7 +7,7 @@ import { useState } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/components/disclosure.tsx
9
9
  const Disclosure$1 = ({ title, subtitle, open: startsOpen = false, children, onToggle }) => {
10
- const { colors } = useTheme();
10
+ const { colors, fontSize } = useTheme();
11
11
  const [open, setOpen] = useState(startsOpen);
12
12
  return /* @__PURE__ */ jsxs("details", {
13
13
  className: "dot-disclosure",
@@ -38,13 +38,13 @@ const Disclosure$1 = ({ title, subtitle, open: startsOpen = false, children, onT
38
38
  },
39
39
  children: [/* @__PURE__ */ jsx("span", {
40
40
  style: {
41
- fontSize: FONT_SIZE.body,
41
+ fontSize: fontSize.body,
42
42
  fontWeight: WEIGHTS.medium
43
43
  },
44
44
  children: title
45
45
  }), subtitle ? /* @__PURE__ */ jsx("span", {
46
46
  style: {
47
- fontSize: FONT_SIZE.caption,
47
+ fontSize: fontSize.caption,
48
48
  color: colors.subtle
49
49
  },
50
50
  children: subtitle
@@ -1,11 +1,11 @@
1
+ import { CENTERED, ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { CENTERED, FONT_SIZE, ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
3
3
  import { insets, paddingStyle } from "./padding.js";
4
4
  import { IconGraphic } from "./icon.js";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/components/empty-state.tsx
7
7
  const EmptyState = ({ icon, title, text, children, ...padding }) => {
8
- const { colors } = useTheme();
8
+ const { colors, space, fontSize, headingFontFamily, headingWeight } = useTheme();
9
9
  return /* @__PURE__ */ jsxs("div", {
10
10
  className: "dot-empty-state",
11
11
  style: {
@@ -13,7 +13,7 @@ const EmptyState = ({ icon, title, text, children, ...padding }) => {
13
13
  flexDirection: "column",
14
14
  alignItems: "center",
15
15
  gap: SPACE.medium,
16
- ...paddingStyle(padding, insets(32, 16)),
16
+ ...paddingStyle(padding, space, insets(32, 16)),
17
17
  textAlign: "center",
18
18
  color: colors.text
19
19
  },
@@ -34,8 +34,9 @@ const EmptyState = ({ icon, title, text, children, ...padding }) => {
34
34
  }) : null,
35
35
  title ? /* @__PURE__ */ jsx("span", {
36
36
  style: {
37
- fontSize: 17,
38
- fontWeight: WEIGHTS.bold,
37
+ fontSize: fontSize.subtitle,
38
+ fontFamily: headingFontFamily,
39
+ fontWeight: WEIGHTS[headingWeight ?? "bold"],
39
40
  lineHeight: "normal"
40
41
  },
41
42
  children: title
@@ -43,7 +44,7 @@ const EmptyState = ({ icon, title, text, children, ...padding }) => {
43
44
  text ? /* @__PURE__ */ jsx("span", {
44
45
  style: {
45
46
  maxWidth: 300,
46
- fontSize: FONT_SIZE.body,
47
+ fontSize: fontSize.body,
47
48
  lineHeight: "normal",
48
49
  color: colors.subtle
49
50
  },
@@ -1,10 +1,10 @@
1
+ import { ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { FONT_SIZE, ICON_SIZE, SPACE, WEIGHTS } from "./tokens.js";
3
3
  import { CLOSE_ARTWORK } from "./icon-artwork.js";
4
4
  import { IconSvg } from "./icon-svg.js";
5
+ import { STATUS_ARTWORK, toneBackground, toneColor } from "./tones.js";
5
6
  import { clamp } from "./numbers.js";
6
7
  import { insets, paddingStyle } from "./padding.js";
7
- import { STATUS_ARTWORK, toneBackground, toneColor } from "./tones.js";
8
8
  import { IconButton } from "./icon-button.js";
9
9
  import { createEvent } from "@monimesl/dot-core";
10
10
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -34,18 +34,18 @@ const ProgressBar$1 = ({ value = 0 }) => {
34
34
  });
35
35
  };
36
36
  const Notice$1 = ({ tone = "default", title, children, onClose, ...padding }) => {
37
- const { colors, radius } = useTheme();
37
+ const { colors, radius, space, fontSize } = useTheme();
38
38
  return /* @__PURE__ */ jsxs("div", {
39
39
  className: "dot-notice",
40
40
  role: tone === "danger" ? "alert" : "status",
41
41
  style: {
42
42
  display: "flex",
43
43
  gap: SPACE.medium,
44
- ...paddingStyle(padding, insets(12, 14)),
44
+ ...paddingStyle(padding, space, insets(12, 14)),
45
45
  borderRadius: radius,
46
46
  background: toneBackground(colors, tone),
47
47
  color: colors.text,
48
- fontSize: FONT_SIZE.body,
48
+ fontSize: fontSize.body,
49
49
  lineHeight: "normal"
50
50
  },
51
51
  children: [
@@ -79,7 +79,7 @@ const Notice$1 = ({ tone = "default", title, children, onClose, ...padding }) =>
79
79
  });
80
80
  };
81
81
  const Badge$1 = ({ tone = "default", children }) => {
82
- const { colors } = useTheme();
82
+ const { colors, fontSize } = useTheme();
83
83
  return /* @__PURE__ */ jsx("span", {
84
84
  className: "dot-badge",
85
85
  style: {
@@ -89,7 +89,7 @@ const Badge$1 = ({ tone = "default", children }) => {
89
89
  borderRadius: 999,
90
90
  background: toneBackground(colors, tone),
91
91
  color: toneColor(colors, tone),
92
- fontSize: FONT_SIZE.caption,
92
+ fontSize: fontSize.caption,
93
93
  fontWeight: WEIGHTS.bold,
94
94
  lineHeight: "normal",
95
95
  whiteSpace: "nowrap"
@@ -1,5 +1,5 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { DISABLED_OPACITY } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { useId, useState } from "react";
4
4
  //#region src/components/field-box.ts
5
5
  const BARE_INPUT_STYLE = {
@@ -1,9 +1,9 @@
1
+ import { SPACE, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { FONT_SIZE, SPACE, WEIGHTS } from "./tokens.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/field.tsx
5
5
  function Field({ label, hint, error, labelId, noteId, children }) {
6
- const { colors } = useTheme();
6
+ const { colors, fontSize } = useTheme();
7
7
  const note = error || hint;
8
8
  return /* @__PURE__ */ jsxs("label", {
9
9
  className: "dot-field",
@@ -21,7 +21,7 @@ function Field({ label, hint, error, labelId, noteId, children }) {
21
21
  note ? /* @__PURE__ */ jsx("span", {
22
22
  id: noteId,
23
23
  style: {
24
- fontSize: FONT_SIZE.caption,
24
+ fontSize: fontSize.caption,
25
25
  color: error ? colors.danger : colors.subtle
26
26
  },
27
27
  children: note
@@ -30,10 +30,11 @@ function Field({ label, hint, error, labelId, noteId, children }) {
30
30
  });
31
31
  }
32
32
  function FieldLabel({ id, children }) {
33
+ const { fontSize } = useTheme();
33
34
  return /* @__PURE__ */ jsx("span", {
34
35
  id,
35
36
  style: {
36
- fontSize: FONT_SIZE.caption,
37
+ fontSize: fontSize.caption,
37
38
  fontWeight: WEIGHTS.medium
38
39
  },
39
40
  children
@@ -1,10 +1,10 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { SPACE } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { HOME_INDICATOR, insets, pinnedPaddingStyle } from "./padding.js";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/footer.tsx
6
6
  const Footer = ({ children, ...padding }) => {
7
- const { colors } = useTheme();
7
+ const { colors, space } = useTheme();
8
8
  return /* @__PURE__ */ jsx("footer", {
9
9
  className: "dot-footer",
10
10
  style: {
@@ -14,7 +14,7 @@ const Footer = ({ children, ...padding }) => {
14
14
  display: "flex",
15
15
  flexDirection: "column",
16
16
  gap: SPACE.medium,
17
- ...pinnedPaddingStyle(padding, insets(SPACE.medium, 0)),
17
+ ...pinnedPaddingStyle(padding, space, insets(SPACE.medium, 0)),
18
18
  marginBottom: `calc(-1 * ${HOME_INDICATOR})`,
19
19
  background: colors.background
20
20
  },
@@ -1,5 +1,5 @@
1
+ import { CARD_RADIUS_SCALE, CENTERED, PILL_STYLE } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { CARD_RADIUS_SCALE, CENTERED, FONT_SIZE, PILL_STYLE, SPACE } from "./tokens.js";
3
3
  import { wholeCount } from "./numbers.js";
4
4
  import { paddingStyle } from "./padding.js";
5
5
  import { IconGraphic } from "./icon.js";
@@ -8,18 +8,21 @@ import { createEvent } from "@monimesl/dot-core";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/components/grid.tsx
10
10
  const TILE_SIZE = 52;
11
- const Grid$1 = ({ columns = 4, gap = "medium", children, ...padding }) => /* @__PURE__ */ jsx("div", {
12
- className: "dot-grid",
13
- style: {
14
- display: "grid",
15
- gridTemplateColumns: `repeat(${wholeCount(columns)}, minmax(0, 1fr))`,
16
- gap: SPACE[gap],
17
- ...paddingStyle(padding)
18
- },
19
- children
20
- });
11
+ const Grid$1 = ({ columns = 4, gap = "medium", children, ...padding }) => {
12
+ const { space } = useTheme();
13
+ return /* @__PURE__ */ jsx("div", {
14
+ className: "dot-grid",
15
+ style: {
16
+ display: "grid",
17
+ gridTemplateColumns: `repeat(${wholeCount(columns)}, minmax(0, 1fr))`,
18
+ gap: space[gap],
19
+ ...paddingStyle(padding, space)
20
+ },
21
+ children
22
+ });
23
+ };
21
24
  const GridItem$1 = ({ label, icon, image, badge, onTap }) => {
22
- const { colors, radius } = useTheme();
25
+ const { colors, radius, fontSize } = useTheme();
23
26
  let picture = null;
24
27
  if (image) picture = /* @__PURE__ */ jsx("img", {
25
28
  src: image,
@@ -85,7 +88,7 @@ const GridItem$1 = ({ label, icon, image, badge, onTap }) => {
85
88
  WebkitLineClamp: 2,
86
89
  WebkitBoxOrient: "vertical",
87
90
  color: colors.text,
88
- fontSize: FONT_SIZE.caption,
91
+ fontSize: fontSize.caption,
89
92
  lineHeight: "normal",
90
93
  textAlign: "center"
91
94
  },
@@ -1,5 +1,5 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { ICON_SIZE } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { IconSvg } from "./icon-svg.js";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/icon-button.tsx
@@ -1,24 +1,51 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { ICON_SIZE } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { ICON_ARTWORK } from "./icon-artwork.js";
4
4
  import { IconSvg } from "./icon-svg.js";
5
- import { toneColor } from "./tones.js";
5
+ import { textToneColor } from "./box.js";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  //#region src/components/icon.tsx
8
+ const ICON_PATH = /^statics\/(?!.*\.\.)[\w./-]+\.svg$/;
9
+ const unknownIcons = /* @__PURE__ */ new Set();
8
10
  function IconGraphic({ name, size, color }) {
9
- return /* @__PURE__ */ jsx(IconSvg, {
11
+ const { icons } = useTheme();
12
+ if (Object.hasOwn(ICON_ARTWORK, name)) return /* @__PURE__ */ jsx(IconSvg, {
10
13
  artwork: ICON_ARTWORK[name],
11
14
  size,
12
15
  color
13
16
  });
17
+ const path = Object.hasOwn(icons, name) ? icons[name] : void 0;
18
+ if (path === void 0 || !ICON_PATH.test(path)) {
19
+ if (!unknownIcons.has(name)) {
20
+ unknownIcons.add(name);
21
+ console.warn(`The theme has no icon named "${name}". Add it to theme.icons in dot.ts.`);
22
+ }
23
+ return null;
24
+ }
25
+ const mask = `url("${path}") center / contain no-repeat`;
26
+ return /* @__PURE__ */ jsx("span", {
27
+ className: "dot-icon",
28
+ "aria-hidden": "true",
29
+ style: {
30
+ display: "inline-flex",
31
+ width: size,
32
+ height: size,
33
+ verticalAlign: "middle",
34
+ flexShrink: 0,
35
+ backgroundColor: color,
36
+ mask,
37
+ WebkitMask: mask
38
+ }
39
+ });
14
40
  }
15
41
  const Icon = ({ name, size = "medium", tone = "default" }) => {
16
- const { colors } = useTheme();
42
+ const theme = useTheme();
17
43
  if (!name) return null;
44
+ const color = textToneColor(tone, theme) ?? theme.colors.text;
18
45
  return /* @__PURE__ */ jsx(IconGraphic, {
19
46
  name,
20
47
  size: ICON_SIZE[size],
21
- color: toneColor(colors, tone)
48
+ color
22
49
  });
23
50
  };
24
51
  //#endregion
@@ -1,5 +1,5 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { ICON_SIZE, SPACE } from "./tokens.js";
2
+ import { useTheme } from "../theme.js";
3
3
  import { Field } from "./field.js";
4
4
  import { BARE_INPUT_STYLE, useFieldBox, useFieldNote } from "./field-box.js";
5
5
  import { useTypedText } from "./typed-text.js";
@@ -1,5 +1,5 @@
1
+ import { CARD_RADIUS_SCALE, CENTERED, ICON_SIZE, SHADOWS, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { CARD_RADIUS_SCALE, CENTERED, FONT_SIZE, ICON_SIZE, WEIGHTS } from "./tokens.js";
3
3
  import { CHEVRON_RIGHT_ARTWORK } from "./icon-artwork.js";
4
4
  import { IconSvg } from "./icon-svg.js";
5
5
  import { insets, paddingStyle } from "./padding.js";
@@ -27,7 +27,8 @@ const ROW_SIZES = {
27
27
  };
28
28
  const ListSizeContext = createContext("sm");
29
29
  const List$1 = ({ size = "sm", onEndReached, children, ...padding }) => {
30
- const { colors, radius } = useTheme();
30
+ const { colors, radius, space, elevation, scheme } = useTheme();
31
+ const raised = elevation === "raised";
31
32
  const listRef = useRef(null);
32
33
  const lastRowReached = useRef(null);
33
34
  useEffect(() => {
@@ -51,11 +52,12 @@ const List$1 = ({ size = "sm", onEndReached, children, ...padding }) => {
51
52
  display: "flex",
52
53
  flexDirection: "column",
53
54
  margin: 0,
54
- ...paddingStyle(padding),
55
+ ...paddingStyle(padding, space),
55
56
  overflow: "hidden",
56
57
  listStyle: "none",
57
58
  borderRadius: radius * CARD_RADIUS_SCALE,
58
- border: `1px solid ${colors.border}`,
59
+ border: raised ? "none" : `1px solid ${colors.border}`,
60
+ boxShadow: raised ? SHADOWS[scheme].low : void 0,
59
61
  background: colors.surface,
60
62
  "--dot-list-divider": colors.border
61
63
  },
@@ -64,7 +66,7 @@ const List$1 = ({ size = "sm", onEndReached, children, ...padding }) => {
64
66
  });
65
67
  };
66
68
  const ListItem$1 = ({ title, subtitle, value, icon, image, onTap, children, ...padding }) => {
67
- const { colors, radius } = useTheme();
69
+ const { colors, radius, space, fontSize } = useTheme();
68
70
  const rowSize = ROW_SIZES[useContext(ListSizeContext)];
69
71
  let leading = null;
70
72
  if (image) leading = /* @__PURE__ */ jsx("img", {
@@ -112,7 +114,7 @@ const ListItem$1 = ({ title, subtitle, value, icon, image, onTap, children, ...p
112
114
  children: title
113
115
  }) : null, subtitle ? /* @__PURE__ */ jsx("span", {
114
116
  style: {
115
- fontSize: FONT_SIZE.caption,
117
+ fontSize: fontSize.caption,
116
118
  lineHeight: "normal",
117
119
  color: colors.subtle
118
120
  },
@@ -138,11 +140,11 @@ const ListItem$1 = ({ title, subtitle, value, icon, image, onTap, children, ...p
138
140
  display: "flex",
139
141
  alignItems: "center",
140
142
  gap: rowSize.gap,
141
- ...paddingStyle(padding, insets(rowSize.block, 16)),
143
+ ...paddingStyle(padding, space, insets(rowSize.block, 16)),
142
144
  width: "100%",
143
145
  background: colors.surface,
144
146
  color: colors.text,
145
- fontSize: FONT_SIZE.body,
147
+ fontSize: fontSize.body,
146
148
  textAlign: "start"
147
149
  };
148
150
  return /* @__PURE__ */ jsx("li", {
@@ -1,5 +1,5 @@
1
+ import { ICON_SIZE, WEIGHTS } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { FONT_SIZE, ICON_SIZE, WEIGHTS } from "./tokens.js";
3
3
  import { CHECK_ARTWORK } from "./icon-artwork.js";
4
4
  import { IconSvg } from "./icon-svg.js";
5
5
  import { OptionPlaceContext } from "./option-place.js";
@@ -7,7 +7,7 @@ import { useContext } from "react";
7
7
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/components/option.tsx
9
9
  const Option = ({ value, label }) => {
10
- const { colors } = useTheme();
10
+ const { colors, fontSize } = useTheme();
11
11
  const place = useContext(OptionPlaceContext);
12
12
  const chosen = value !== void 0 && value === place.value;
13
13
  if (place.inField) return chosen ? /* @__PURE__ */ jsx(Fragment$1, { children: label }) : null;
@@ -28,7 +28,7 @@ const Option = ({ value, label }) => {
28
28
  borderBottom: `1px solid ${colors.border}`,
29
29
  background: "transparent",
30
30
  color: colors.text,
31
- fontSize: FONT_SIZE.body,
31
+ fontSize: fontSize.body,
32
32
  fontWeight: chosen ? WEIGHTS.bold : WEIGHTS.regular,
33
33
  textAlign: "start",
34
34
  cursor: "pointer"