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

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 (55) 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 +65 -50
  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 +6 -11
  15. package/dist/components/grid.js +20 -13
  16. package/dist/components/icon-button.js +1 -1
  17. package/dist/components/icon.js +32 -5
  18. package/dist/components/index.d.ts +2 -1
  19. package/dist/components/index.js +3 -1
  20. package/dist/components/input.js +1 -1
  21. package/dist/components/link.js +1 -1
  22. package/dist/components/list.js +11 -9
  23. package/dist/components/option.js +3 -3
  24. package/dist/components/padding.js +9 -10
  25. package/dist/components/pinned-bar.js +29 -0
  26. package/dist/components/pinned.d.ts +6 -0
  27. package/dist/components/pinned.js +26 -0
  28. package/dist/components/prose.js +23 -20
  29. package/dist/components/rich-text.js +30 -18
  30. package/dist/components/scroll.js +25 -8
  31. package/dist/components/select.js +1 -1
  32. package/dist/components/sheet.js +51 -45
  33. package/dist/components/side-room.js +5 -0
  34. package/dist/components/skeleton.js +1 -1
  35. package/dist/components/slider.js +3 -3
  36. package/dist/components/spinner.js +1 -1
  37. package/dist/components/stack.js +12 -8
  38. package/dist/components/stepper.js +3 -3
  39. package/dist/components/steps.js +17 -14
  40. package/dist/components/tabs.js +72 -26
  41. package/dist/components/text.js +12 -14
  42. package/dist/components/toast.js +3 -3
  43. package/dist/components/toggles.js +13 -9
  44. package/dist/components/tokens.d.ts +16 -0
  45. package/dist/components/tokens.js +20 -1
  46. package/dist/components/view.js +29 -15
  47. package/dist/index.d.ts +2 -1
  48. package/dist/index.js +2 -1
  49. package/dist/page-root.js +9 -3
  50. package/dist/pull-to-refresh.js +1 -1
  51. package/dist/root.js +4 -3
  52. package/dist/styles.css +1 -1
  53. package/dist/theme.d.ts +12 -1
  54. package/dist/theme.js +85 -15
  55. 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 { backgroundColor, 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] ?? SIZES.medium;
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.primaryText;
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,9 +1,10 @@
1
+ import { SHADOW_REACH, SPACE } from "./tokens.js";
1
2
  import { useTheme } from "../theme.js";
2
- import { SPACE } from "./tokens.js";
3
3
  import { clamp } from "./numbers.js";
4
4
  import { paddingStyle } from "./padding.js";
5
+ import { SideRoomContext } from "./side-room.js";
5
6
  import { createEvent } from "@monimesl/dot-core";
6
- import { Children, Fragment, isValidElement, useEffect, useEffectEvent, useRef, useState } from "react";
7
+ import { Children, Fragment, isValidElement, useContext, useEffect, useEffectEvent, useRef, useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
9
  //#region src/components/carousel.tsx
9
10
  const SLIDE_DURATION = 350;
@@ -13,7 +14,8 @@ const SWIPE_SPEED = .4;
13
14
  const EDGE_RESISTANCE = .3;
14
15
  const TAP_SLOP = 6;
15
16
  const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator = "dots", gap = "none", effect = "slide", index, onChange, children, ...padding }) => {
16
- const { colors } = useTheme();
17
+ const { colors, space, elevation } = useTheme();
18
+ const mayUseSides = useContext(SideRoomContext);
17
19
  const slides = slidesOf(children);
18
20
  const count = slides.length;
19
21
  const looping = loop && count > 1;
@@ -23,20 +25,20 @@ const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator
23
25
  const [animated, setAnimated] = useState(true);
24
26
  const [dragOffset, setDragOffset] = useState(0);
25
27
  const [dragging, setDragging] = useState(false);
26
- const [viewportWidth, setViewportWidth] = useState(0);
28
+ const [slideWidth, setSlideWidth] = useState(0);
27
29
  const [previousIndex, setPreviousIndex] = useState(index);
28
- const viewportRef = useRef(null);
30
+ const swipeAreaRef = useRef(null);
29
31
  const gestureRef = useRef(null);
30
32
  const ignoreNextClick = useRef(false);
33
+ const shownPosition = clamp(position, 0, lastPosition);
34
+ const currentIndex = count === 0 ? 0 : wrapIndex(shownPosition - firstPosition, count);
31
35
  if (index !== previousIndex) {
32
36
  setPreviousIndex(index);
33
- if (index !== void 0) {
37
+ if (index !== void 0 && slideIndex(index, count) !== currentIndex) {
34
38
  setAnimated(true);
35
39
  setPosition(firstPosition + slideIndex(index, count));
36
40
  }
37
41
  }
38
- const shownPosition = clamp(position, 0, lastPosition);
39
- const currentIndex = count === 0 ? 0 : wrapIndex(shownPosition - firstPosition, count);
40
42
  const moveTo = (targetPosition) => {
41
43
  const nextPosition = clamp(targetPosition, 0, lastPosition);
42
44
  setAnimated(true);
@@ -98,7 +100,7 @@ const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator
98
100
  };
99
101
  ignoreNextClick.current = false;
100
102
  setDragging(true);
101
- setViewportWidth(viewportRef.current?.clientWidth ?? 0);
103
+ setSlideWidth(swipeAreaRef.current?.clientWidth ?? 0);
102
104
  };
103
105
  const onPointerMove = (event) => {
104
106
  const swipe = gestureOf(event);
@@ -128,13 +130,14 @@ const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator
128
130
  if (!swipe.swiping) return;
129
131
  const movedX = event.clientX - swipe.startX;
130
132
  const speed = Math.abs(movedX) / Math.max(1, event.timeStamp - swipe.startTime);
131
- if (Math.abs(movedX) > viewportWidth * SWIPE_DISTANCE || speed > SWIPE_SPEED) stepBy(movedX < 0 ? 1 : -1);
133
+ if (Math.abs(movedX) > slideWidth * SWIPE_DISTANCE || speed > SWIPE_SPEED) stepBy(movedX < 0 ? 1 : -1);
132
134
  else moveTo(shownPosition);
133
135
  };
134
- const gapWidth = SPACE[gap];
136
+ const gapWidth = mayUseSides && elevation === "raised" ? Math.max(space[gap], SHADOW_REACH.sides) : space[gap];
137
+ const sideRoom = mayUseSides ? gapWidth : 0;
135
138
  const transition = animated ? `transform ${SLIDE_DURATION}ms ${SLIDE_EASING}` : "none";
136
139
  let draggedSlides = 0;
137
- if (viewportWidth > 0) draggedSlides = dragOffset / (viewportWidth + gapWidth);
140
+ if (slideWidth > 0) draggedSlides = dragOffset / (slideWidth + gapWidth);
138
141
  let track = slides;
139
142
  if (looping) track = [
140
143
  {
@@ -156,52 +159,64 @@ const Carousel$1 = ({ autoplay = false, interval = 4e3, loop = false, indicator
156
159
  flexDirection: "column",
157
160
  gap: SPACE.medium,
158
161
  minWidth: 0,
159
- ...paddingStyle(padding)
162
+ ...paddingStyle(padding, space)
160
163
  },
161
164
  children: [/* @__PURE__ */ jsx("div", {
162
- ref: viewportRef,
163
- onPointerDown,
164
- onPointerMove,
165
- onPointerUp,
166
- onPointerCancel: endGesture,
167
- onDragStart: (event) => event.preventDefault(),
168
- onClickCapture: (event) => {
169
- if (ignoreNextClick.current) {
170
- ignoreNextClick.current = false;
171
- event.stopPropagation();
172
- }
173
- },
174
165
  style: {
175
166
  overflow: "hidden",
176
- touchAction: "pan-y",
177
- userSelect: dragging ? "none" : void 0
167
+ paddingTop: SHADOW_REACH.top,
168
+ paddingBottom: SHADOW_REACH.bottom,
169
+ paddingInline: sideRoom,
170
+ marginTop: -SHADOW_REACH.top,
171
+ marginBottom: -SHADOW_REACH.bottom,
172
+ marginInline: -sideRoom,
173
+ pointerEvents: "none"
178
174
  },
179
175
  children: /* @__PURE__ */ jsx("div", {
176
+ ref: swipeAreaRef,
177
+ onPointerDown,
178
+ onPointerMove,
179
+ onPointerUp,
180
+ onPointerCancel: endGesture,
181
+ onDragStart: (event) => event.preventDefault(),
182
+ onClickCapture: (event) => {
183
+ if (ignoreNextClick.current) {
184
+ ignoreNextClick.current = false;
185
+ event.stopPropagation();
186
+ }
187
+ },
180
188
  style: {
181
- display: "flex",
182
- gap: gapWidth,
183
- transform: `translateX(calc(${-shownPosition} * (100% + ${gapWidth}px) + ${dragOffset}px))`,
184
- transition
189
+ pointerEvents: "auto",
190
+ touchAction: "pan-y",
191
+ userSelect: dragging ? "none" : void 0
185
192
  },
186
- children: track.map((slide, trackPosition) => {
187
- const visible = trackPosition === shownPosition;
188
- const distance = Math.abs(trackPosition - shownPosition + draggedSlides);
189
- const scale = 1 - Math.min(distance, 1) * .15000000000000002;
190
- return /* @__PURE__ */ jsx("div", {
191
- role: "group",
192
- "aria-roledescription": "slide",
193
- "aria-label": `${wrapIndex(trackPosition - firstPosition, count) + 1} of ${count}`,
194
- "aria-hidden": !visible,
195
- inert: !visible,
196
- style: {
197
- display: "grid",
198
- flex: "0 0 100%",
199
- minWidth: 0,
200
- transform: effect === "scale" ? `scale(${scale})` : void 0,
201
- transition: effect === "scale" ? transition : void 0
202
- },
203
- children: slide.node
204
- }, slide.key);
193
+ children: /* @__PURE__ */ jsx("div", {
194
+ style: {
195
+ display: "flex",
196
+ gap: gapWidth,
197
+ transform: `translateX(calc(${-shownPosition} * (100% + ${gapWidth}px) + ${dragOffset}px))`,
198
+ transition
199
+ },
200
+ children: track.map((slide, trackPosition) => {
201
+ const visible = trackPosition === shownPosition;
202
+ const distance = Math.abs(trackPosition - shownPosition + draggedSlides);
203
+ const scale = 1 - Math.min(distance, 1) * .15000000000000002;
204
+ return /* @__PURE__ */ jsx("div", {
205
+ role: "group",
206
+ "aria-roledescription": "slide",
207
+ "aria-label": `${wrapIndex(trackPosition - firstPosition, count) + 1} of ${count}`,
208
+ "aria-hidden": !visible,
209
+ inert: !visible,
210
+ style: {
211
+ display: "grid",
212
+ flex: "0 0 100%",
213
+ minWidth: 0,
214
+ transform: effect === "scale" ? `scale(${scale})` : void 0,
215
+ transition: effect === "scale" ? transition : void 0
216
+ },
217
+ children: slide.node
218
+ }, slide.key);
219
+ })
205
220
  })
206
221
  })
207
222
  }), indicator === "dots" && count > 1 ? /* @__PURE__ */ jsx("div", {
@@ -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,21 +1,16 @@
1
- import { useTheme } from "../theme.js";
2
1
  import { SPACE } from "./tokens.js";
3
- import { HOME_INDICATOR, insets, pinnedPaddingStyle } from "./padding.js";
2
+ import { useTheme } from "../theme.js";
3
+ import { insets } from "./padding.js";
4
+ import { pinnedBarStyle } from "./pinned-bar.js";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  //#region src/components/footer.tsx
6
7
  const Footer = ({ children, ...padding }) => {
7
- const { colors } = useTheme();
8
+ const { colors, space } = useTheme();
8
9
  return /* @__PURE__ */ jsx("footer", {
9
- className: "dot-footer",
10
+ className: "dot-footer dot-bar-bottom",
10
11
  style: {
11
- position: "sticky",
12
- bottom: 0,
13
- marginTop: "auto",
14
- display: "flex",
15
- flexDirection: "column",
12
+ ...pinnedBarStyle("bottom", padding, space, insets(SPACE.medium, 0)),
16
13
  gap: SPACE.medium,
17
- ...pinnedPaddingStyle(padding, insets(SPACE.medium, 0)),
18
- marginBottom: `calc(-1 * ${HOME_INDICATOR})`,
19
14
  background: colors.background
20
15
  },
21
16
  children
@@ -1,25 +1,32 @@
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
+ import { SideRoomContext } from "./side-room.js";
5
6
  import { IconGraphic } from "./icon.js";
6
7
  import { pressable } from "./pressable.js";
7
8
  import { createEvent } from "@monimesl/dot-core";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  //#region src/components/grid.tsx
10
11
  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
- });
12
+ const Grid$1 = ({ columns = 4, gap = "medium", children, ...padding }) => {
13
+ const { space } = useTheme();
14
+ return /* @__PURE__ */ jsx("div", {
15
+ className: "dot-grid",
16
+ style: {
17
+ display: "grid",
18
+ gridTemplateColumns: `repeat(${wholeCount(columns)}, minmax(0, 1fr))`,
19
+ gap: space[gap],
20
+ ...paddingStyle(padding, space)
21
+ },
22
+ children: /* @__PURE__ */ jsx(SideRoomContext.Provider, {
23
+ value: false,
24
+ children
25
+ })
26
+ });
27
+ };
21
28
  const GridItem$1 = ({ label, icon, image, badge, onTap }) => {
22
- const { colors, radius } = useTheme();
29
+ const { colors, radius, fontSize } = useTheme();
23
30
  let picture = null;
24
31
  if (image) picture = /* @__PURE__ */ jsx("img", {
25
32
  src: image,
@@ -85,7 +92,7 @@ const GridItem$1 = ({ label, icon, image, badge, onTap }) => {
85
92
  WebkitLineClamp: 2,
86
93
  WebkitBoxOrient: "vertical",
87
94
  color: colors.text,
88
- fontSize: FONT_SIZE.caption,
95
+ fontSize: fontSize.caption,
89
96
  lineHeight: "normal",
90
97
  textAlign: "center"
91
98
  },
@@ -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