@monimesl/dot-renderer-react 1.0.0-beta.0 → 1.0.0-beta.10
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.
- package/README.md +3 -3
- package/dist/components/amount-input.js +1 -1
- package/dist/components/avatar.js +1 -1
- package/dist/components/box.js +9 -3
- package/dist/components/button.js +64 -14
- package/dist/components/carousel.js +65 -50
- package/dist/components/chip.js +4 -5
- package/dist/components/code-input.js +1 -1
- package/dist/components/detail-row.js +5 -5
- package/dist/components/disclosure.js +11 -6
- package/dist/components/empty-state.js +7 -6
- package/dist/components/feedback.js +7 -7
- package/dist/components/field-box.js +1 -1
- package/dist/components/field.js +5 -4
- package/dist/components/footer.js +6 -11
- package/dist/components/grid.js +25 -15
- package/dist/components/hidden-view.js +5 -0
- package/dist/components/icon-button.js +1 -1
- package/dist/components/icon.js +32 -5
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.js +3 -1
- package/dist/components/input.js +1 -1
- package/dist/components/link.js +11 -3
- package/dist/components/list.js +62 -33
- package/dist/components/option.js +6 -5
- package/dist/components/padding.js +9 -10
- package/dist/components/pinned-bar.js +29 -0
- package/dist/components/pinned.d.ts +6 -0
- package/dist/components/pinned.js +26 -0
- package/dist/components/pressable.js +3 -1
- package/dist/components/prose.js +23 -20
- package/dist/components/rich-text.js +30 -18
- package/dist/components/scroll.js +33 -10
- package/dist/components/select.js +1 -1
- package/dist/components/sheet.js +55 -46
- package/dist/components/side-room.js +5 -0
- package/dist/components/skeleton.js +1 -1
- package/dist/components/slider.js +3 -3
- package/dist/components/spinner.js +1 -1
- package/dist/components/stack.js +12 -8
- package/dist/components/stepper.js +4 -5
- package/dist/components/steps.js +17 -14
- package/dist/components/tabs.js +74 -27
- package/dist/components/text.js +12 -14
- package/dist/components/toast.js +3 -3
- package/dist/components/toggles.js +14 -11
- package/dist/components/tokens.d.ts +16 -0
- package/dist/components/tokens.js +26 -1
- package/dist/components/view.js +40 -18
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/page-root.js +9 -3
- package/dist/pull-to-refresh.js +1 -1
- package/dist/root.js +4 -3
- package/dist/styles.css +1 -1
- package/dist/theme.d.ts +12 -1
- package/dist/theme.js +85 -15
- package/package.json +4 -4
package/dist/components/text.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { SELECTABLE, WEIGHTS } from "./tokens.js";
|
|
1
2
|
import { useTheme } from "../theme.js";
|
|
2
|
-
import { FONT_SIZE, SELECTABLE, WEIGHTS } from "./tokens.js";
|
|
3
3
|
import { paddingStyle } from "./padding.js";
|
|
4
|
-
import {
|
|
4
|
+
import { textToneColor } from "./box.js";
|
|
5
5
|
import { InsideProse } from "./prose-context.js";
|
|
6
|
-
import {
|
|
6
|
+
import { DEFAULT_VARIANTS } from "@monimesl/dot-core";
|
|
7
7
|
import { createContext, useContext } from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
|
9
9
|
//#region src/components/text.tsx
|
|
@@ -50,10 +50,12 @@ const DECORATION = {
|
|
|
50
50
|
underline: "underline",
|
|
51
51
|
strikethrough: "line-through"
|
|
52
52
|
};
|
|
53
|
-
const Text = ({ variant
|
|
53
|
+
const Text$1 = ({ variant: namedVariant, tone, weight, align, maxLines, decoration, numeric, leading, italic, selectable, children, ...padding }) => {
|
|
54
54
|
const theme = useTheme();
|
|
55
55
|
const insideText = useContext(InsideText);
|
|
56
56
|
const inProse = useContext(InsideProse);
|
|
57
|
+
let variant = namedVariant ?? DEFAULT_VARIANTS.Text;
|
|
58
|
+
if (!Object.hasOwn(VARIANTS, variant)) variant = DEFAULT_VARIANTS.Text;
|
|
57
59
|
const { heading, lineHeight, weight: defaultWeight } = VARIANTS[variant];
|
|
58
60
|
const defaultLeading = inProse && !heading ? "relaxed" : "normal";
|
|
59
61
|
const style = {
|
|
@@ -61,16 +63,17 @@ const Text = ({ variant = "body", tone, weight, align, maxLines, decoration, num
|
|
|
61
63
|
marginInline: 0,
|
|
62
64
|
marginBlockEnd: 0,
|
|
63
65
|
marginBlockStart: inProse && heading ? void 0 : 0,
|
|
64
|
-
fontSize:
|
|
65
|
-
|
|
66
|
+
fontSize: theme.fontSize[variant],
|
|
67
|
+
fontFamily: heading ? theme.headingFontFamily : void 0,
|
|
68
|
+
fontWeight: WEIGHTS[weight ?? (heading ? theme.headingWeight : void 0) ?? defaultWeight],
|
|
66
69
|
fontStyle: italic ? "italic" : void 0,
|
|
67
70
|
letterSpacing: variant === "display" ? "-0.02em" : "normal",
|
|
68
|
-
color: tone ?
|
|
71
|
+
color: tone ? textToneColor(tone, theme) : "inherit",
|
|
69
72
|
textAlign: align,
|
|
70
73
|
textDecorationLine: decoration ? DECORATION[decoration] : void 0,
|
|
71
74
|
fontVariantNumeric: numeric ? "tabular-nums" : void 0,
|
|
72
75
|
...selectable ? SELECTABLE : void 0,
|
|
73
|
-
...paddingStyle(padding)
|
|
76
|
+
...paddingStyle(padding, theme.space)
|
|
74
77
|
};
|
|
75
78
|
if (!insideText) {
|
|
76
79
|
style.lineHeight = lineHeight + LEADING_CHANGE[leading ?? defaultLeading];
|
|
@@ -98,10 +101,5 @@ const Text = ({ variant = "body", tone, weight, align, maxLines, decoration, num
|
|
|
98
101
|
children: content
|
|
99
102
|
});
|
|
100
103
|
};
|
|
101
|
-
function textColor(tone, theme) {
|
|
102
|
-
if (isTone(tone)) return toneColor(theme.colors, tone);
|
|
103
|
-
if (tone === "onPrimary") return theme.colors.onPrimary;
|
|
104
|
-
return customColor(tone, theme);
|
|
105
|
-
}
|
|
106
104
|
//#endregion
|
|
107
|
-
export { Text };
|
|
105
|
+
export { Text$1 as Text };
|
package/dist/components/toast.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { ICON_SIZE, SPACE } from "./tokens.js";
|
|
1
2
|
import { useTheme } from "../theme.js";
|
|
2
|
-
import { FONT_SIZE, ICON_SIZE, SPACE } from "./tokens.js";
|
|
3
3
|
import { IconSvg } from "./icon-svg.js";
|
|
4
4
|
import { STATUS_ARTWORK } from "./tones.js";
|
|
5
5
|
import { createEvent } from "@monimesl/dot-core";
|
|
@@ -7,7 +7,7 @@ import { useEffect, useEffectEvent, useState } from "react";
|
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/toast.tsx
|
|
9
9
|
const Toast$1 = ({ message, tone = "default", duration = 2500, onHide }) => {
|
|
10
|
-
const { colors, radius } = useTheme();
|
|
10
|
+
const { colors, radius, fontSize } = useTheme();
|
|
11
11
|
const [hidden, setHidden] = useState(false);
|
|
12
12
|
const [previousMessage, setPreviousMessage] = useState(message);
|
|
13
13
|
if (message !== previousMessage) {
|
|
@@ -42,7 +42,7 @@ const Toast$1 = ({ message, tone = "default", duration = 2500, onHide }) => {
|
|
|
42
42
|
borderRadius: radius,
|
|
43
43
|
background: colors.primary,
|
|
44
44
|
color: colors.onPrimary,
|
|
45
|
-
fontSize:
|
|
45
|
+
fontSize: fontSize.body,
|
|
46
46
|
boxShadow: "0 4px 16px rgba(0, 0, 0, 0.2)"
|
|
47
47
|
},
|
|
48
48
|
children: [tone === "default" ? null : /* @__PURE__ */ jsx(IconSvg, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { CENTERED, ICON_SIZE, SPACE, pressLook } from "./tokens.js";
|
|
1
2
|
import { useTheme } from "../theme.js";
|
|
2
|
-
import { CENTERED, DISABLED_OPACITY, FONT_SIZE, ICON_SIZE, SPACE } from "./tokens.js";
|
|
3
3
|
import { FieldLabel } from "./field.js";
|
|
4
4
|
import { CHECK_ARTWORK } from "./icon-artwork.js";
|
|
5
5
|
import { IconSvg } from "./icon-svg.js";
|
|
@@ -14,7 +14,8 @@ import { createEvent } from "@monimesl/dot-core";
|
|
|
14
14
|
import { useId } from "react";
|
|
15
15
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
16
|
//#region src/components/toggles.tsx
|
|
17
|
-
function rowStyle(
|
|
17
|
+
function rowStyle(theme, disabled) {
|
|
18
|
+
const { colors, fontSize } = theme;
|
|
18
19
|
return {
|
|
19
20
|
display: "flex",
|
|
20
21
|
alignItems: "center",
|
|
@@ -24,10 +25,9 @@ function rowStyle(colors, disabled) {
|
|
|
24
25
|
border: "none",
|
|
25
26
|
background: "transparent",
|
|
26
27
|
color: colors.text,
|
|
27
|
-
fontSize:
|
|
28
|
+
fontSize: fontSize.body,
|
|
28
29
|
textAlign: "start",
|
|
29
|
-
|
|
30
|
-
cursor: disabled ? "default" : "pointer"
|
|
30
|
+
...pressLook(disabled)
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
function ChoiceMark({ round, checked, children }) {
|
|
@@ -47,14 +47,15 @@ function ChoiceMark({ round, checked, children }) {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
const Switch$1 = ({ checked = false, label, disabled, onChange }) => {
|
|
50
|
-
const
|
|
50
|
+
const theme = useTheme();
|
|
51
|
+
const { colors } = theme;
|
|
51
52
|
return /* @__PURE__ */ jsxs(SwitchRoot, {
|
|
52
53
|
className: "dot-switch",
|
|
53
54
|
checked,
|
|
54
55
|
disabled,
|
|
55
56
|
onCheckedChange: (next) => onChange?.(createEvent("change", { checked: next })),
|
|
56
57
|
style: {
|
|
57
|
-
...rowStyle(
|
|
58
|
+
...rowStyle(theme, disabled),
|
|
58
59
|
justifyContent: "space-between"
|
|
59
60
|
},
|
|
60
61
|
children: [label ? /* @__PURE__ */ jsx("span", { children: label }) : null, /* @__PURE__ */ jsx("span", {
|
|
@@ -81,13 +82,14 @@ const Switch$1 = ({ checked = false, label, disabled, onChange }) => {
|
|
|
81
82
|
});
|
|
82
83
|
};
|
|
83
84
|
const Checkbox$1 = ({ checked = false, label, disabled, onChange }) => {
|
|
84
|
-
const
|
|
85
|
+
const theme = useTheme();
|
|
86
|
+
const { colors } = theme;
|
|
85
87
|
return /* @__PURE__ */ jsxs(CheckboxRoot, {
|
|
86
88
|
className: "dot-checkbox",
|
|
87
89
|
checked,
|
|
88
90
|
disabled,
|
|
89
91
|
onCheckedChange: (next) => onChange?.(createEvent("change", { checked: next })),
|
|
90
|
-
style: rowStyle(
|
|
92
|
+
style: rowStyle(theme, disabled),
|
|
91
93
|
children: [/* @__PURE__ */ jsx(ChoiceMark, {
|
|
92
94
|
round: false,
|
|
93
95
|
checked,
|
|
@@ -122,13 +124,14 @@ const RadioGroup$1 = ({ value, label, disabled = false, onChange, children }) =>
|
|
|
122
124
|
});
|
|
123
125
|
};
|
|
124
126
|
const Radio$1 = ({ value, label, disabled }) => {
|
|
125
|
-
const
|
|
127
|
+
const theme = useTheme();
|
|
128
|
+
const { colors } = theme;
|
|
126
129
|
if (value === void 0) return null;
|
|
127
130
|
return /* @__PURE__ */ jsx(RadioRoot, {
|
|
128
131
|
className: "dot-radio",
|
|
129
132
|
value,
|
|
130
133
|
disabled,
|
|
131
|
-
style: (state) => rowStyle(
|
|
134
|
+
style: (state) => rowStyle(theme, state.disabled),
|
|
132
135
|
render: (props, state) => /* @__PURE__ */ jsxs("span", {
|
|
133
136
|
...props,
|
|
134
137
|
children: [/* @__PURE__ */ jsx(ChoiceMark, {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/components/tokens.d.ts
|
|
2
|
+
export declare const SPACE: {
|
|
3
|
+
readonly none: 0;
|
|
4
|
+
readonly small: 4;
|
|
5
|
+
readonly medium: 8;
|
|
6
|
+
readonly large: 16;
|
|
7
|
+
};
|
|
8
|
+
export declare const FONT_SIZE: {
|
|
9
|
+
readonly caption: 13;
|
|
10
|
+
readonly body: 15;
|
|
11
|
+
readonly lead: 17;
|
|
12
|
+
readonly subtitle: 17;
|
|
13
|
+
readonly title: 20;
|
|
14
|
+
readonly display: 32;
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
@@ -20,6 +20,31 @@ const WEIGHTS = {
|
|
|
20
20
|
};
|
|
21
21
|
const CARD_RADIUS_SCALE = 1.5;
|
|
22
22
|
const DISABLED_OPACITY = .6;
|
|
23
|
+
function pressLook(disabled) {
|
|
24
|
+
return {
|
|
25
|
+
opacity: disabled ? DISABLED_OPACITY : 1,
|
|
26
|
+
cursor: disabled ? "default" : "pointer"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const SHADOWS = {
|
|
30
|
+
light: {
|
|
31
|
+
low: "0 1px 2px rgba(0, 0, 0, 0.06), 0 2px 8px rgba(0, 0, 0, 0.06)",
|
|
32
|
+
high: "0 4px 12px rgba(0, 0, 0, 0.08), 0 12px 32px rgba(0, 0, 0, 0.14)"
|
|
33
|
+
},
|
|
34
|
+
dark: {
|
|
35
|
+
low: "0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 8px rgba(0, 0, 0, 0.3)",
|
|
36
|
+
high: "0 4px 12px rgba(0, 0, 0, 0.5), 0 12px 32px rgba(0, 0, 0, 0.5)"
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const SHADOW_REACH = {
|
|
40
|
+
top: 20,
|
|
41
|
+
sides: 32,
|
|
42
|
+
bottom: 44
|
|
43
|
+
};
|
|
44
|
+
const SCROLL_SHADOW_ROOM = {
|
|
45
|
+
top: 6,
|
|
46
|
+
bottom: 10
|
|
47
|
+
};
|
|
23
48
|
const CENTERED = {
|
|
24
49
|
display: "flex",
|
|
25
50
|
alignItems: "center",
|
|
@@ -46,4 +71,4 @@ const SELECTABLE = {
|
|
|
46
71
|
WebkitUserSelect: "text"
|
|
47
72
|
};
|
|
48
73
|
//#endregion
|
|
49
|
-
export { CARD_RADIUS_SCALE, CENTERED, DISABLED_OPACITY, FONT_SIZE, ICON_SIZE, PILL_STYLE, SELECTABLE, SPACE, WEIGHTS };
|
|
74
|
+
export { CARD_RADIUS_SCALE, CENTERED, DISABLED_OPACITY, FONT_SIZE, ICON_SIZE, PILL_STYLE, SCROLL_SHADOW_ROOM, SELECTABLE, SHADOWS, SHADOW_REACH, SPACE, WEIGHTS, pressLook };
|
package/dist/components/view.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { DISABLED_OPACITY, SHADOWS } from "./tokens.js";
|
|
1
2
|
import { useTheme } from "../theme.js";
|
|
2
|
-
import { SPACE } from "./tokens.js";
|
|
3
3
|
import { insets, paddingStyle } from "./padding.js";
|
|
4
|
-
import {
|
|
5
|
-
import { pressable } from "./pressable.js";
|
|
4
|
+
import { SideRoomContext } from "./side-room.js";
|
|
6
5
|
import { boxStyle } from "./box.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { pressable } from "./pressable.js";
|
|
7
|
+
import { HiddenViewContext } from "./hidden-view.js";
|
|
8
|
+
import { DEFAULT_VARIANTS, createEvent } from "@monimesl/dot-core";
|
|
9
|
+
import { useContext } from "react";
|
|
9
10
|
import { jsx } from "react/jsx-runtime";
|
|
10
11
|
//#region src/components/view.tsx
|
|
11
12
|
const ALIGN = {
|
|
@@ -25,37 +26,58 @@ const CARD_LOOK = {
|
|
|
25
26
|
border: "subtle",
|
|
26
27
|
radius: "large"
|
|
27
28
|
};
|
|
29
|
+
const RAISED_CARD_LOOK = {
|
|
30
|
+
...CARD_LOOK,
|
|
31
|
+
border: "none"
|
|
32
|
+
};
|
|
28
33
|
const View$1 = (props) => {
|
|
29
|
-
const { direction = "column", gap = "medium", align = "stretch", justify = "start", wrap = false, grow = false, variant =
|
|
34
|
+
const { id, hidden = false, disabled = false, direction = "column", gap = "medium", align = "stretch", justify = "start", wrap = false, grow = false, variant = DEFAULT_VARIANTS.View, onTap, children } = props;
|
|
30
35
|
const theme = useTheme();
|
|
36
|
+
const sideRoomAround = useContext(SideRoomContext);
|
|
37
|
+
const hiddenAround = useContext(HiddenViewContext);
|
|
31
38
|
const card = variant === "card";
|
|
39
|
+
const raisedCard = card && theme.elevation === "raised" && props.elevation !== "none";
|
|
40
|
+
let cardLook;
|
|
41
|
+
if (card) cardLook = raisedCard ? RAISED_CARD_LOOK : CARD_LOOK;
|
|
42
|
+
const elevation = props.elevation ?? (raisedCard ? "low" : "none");
|
|
43
|
+
const padding = paddingStyle(props, theme.space, card ? insets(theme.space.large) : void 0);
|
|
32
44
|
const style = {
|
|
33
|
-
display: "flex",
|
|
45
|
+
display: hidden ? "none" : "flex",
|
|
34
46
|
flexDirection: direction,
|
|
35
47
|
alignItems: ALIGN[align],
|
|
36
48
|
justifyContent: JUSTIFY[justify],
|
|
37
49
|
flexWrap: wrap ? "wrap" : "nowrap",
|
|
38
|
-
gap:
|
|
39
|
-
...
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
gap: theme.space[gap],
|
|
51
|
+
...padding,
|
|
52
|
+
"--dot-view-top": `${padding.paddingTop}px`,
|
|
53
|
+
"--dot-view-bottom": `${padding.paddingBottom}px`,
|
|
54
|
+
"--dot-view-start": `${padding.paddingInlineStart}px`,
|
|
55
|
+
"--dot-view-end": `${padding.paddingInlineEnd}px`,
|
|
56
|
+
...boxStyle(props, theme, cardLook),
|
|
57
|
+
opacity: disabled ? DISABLED_OPACITY : void 0,
|
|
58
|
+
cursor: onTap && !disabled ? "pointer" : void 0
|
|
42
59
|
};
|
|
43
|
-
if (
|
|
60
|
+
if (elevation !== "none") style.boxShadow = SHADOWS[theme.scheme][elevation];
|
|
44
61
|
if (grow) {
|
|
45
62
|
style.flexGrow = 1;
|
|
46
63
|
style.minWidth = 0;
|
|
47
64
|
}
|
|
48
|
-
const press = onTap ? pressable(() => onTap(createEvent("tap"))) : void 0;
|
|
65
|
+
const press = onTap && !disabled ? pressable(() => onTap(createEvent("tap"))) : void 0;
|
|
49
66
|
return /* @__PURE__ */ jsx("div", {
|
|
50
67
|
className: "dot-view",
|
|
68
|
+
"data-dot-view": id,
|
|
69
|
+
hidden,
|
|
70
|
+
inert: disabled,
|
|
51
71
|
style,
|
|
52
72
|
...press,
|
|
53
|
-
children
|
|
73
|
+
children: /* @__PURE__ */ jsx(HiddenViewContext.Provider, {
|
|
74
|
+
value: hiddenAround || hidden,
|
|
75
|
+
children: /* @__PURE__ */ jsx(SideRoomContext.Provider, {
|
|
76
|
+
value: sideRoomAround && direction !== "row",
|
|
77
|
+
children
|
|
78
|
+
})
|
|
79
|
+
})
|
|
54
80
|
});
|
|
55
81
|
};
|
|
56
|
-
function endsWithFooter(children) {
|
|
57
|
-
const last = Children.toArray(children).at(-1);
|
|
58
|
-
return isValidElement(last) && last.type === Footer$1;
|
|
59
|
-
}
|
|
60
82
|
//#endregion
|
|
61
83
|
export { View$1 as View };
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { Input } from "./components/input.js";
|
|
|
20
20
|
import { Link } from "./components/link.js";
|
|
21
21
|
import { List, ListItem } from "./components/list.js";
|
|
22
22
|
import { Option } from "./components/option.js";
|
|
23
|
+
import { Pinned } from "./components/pinned.js";
|
|
23
24
|
import { Bullet, BulletList, Prose, Quote } from "./components/prose.js";
|
|
24
25
|
import { QRCode } from "./components/qr-code.js";
|
|
25
26
|
import { RichText } from "./components/rich-text.js";
|
|
@@ -40,4 +41,4 @@ import { Checkbox, Radio, RadioGroup, Switch } from "./components/toggles.js";
|
|
|
40
41
|
import { View } from "./components/view.js";
|
|
41
42
|
import "./components/index.js";
|
|
42
43
|
import { ResolvedColors, ResolvedTheme, resolveTheme, useTheme } from "./theme.js";
|
|
43
|
-
export { AmountInput, Avatar, Badge, type BuiltinReactComponents, Bullet, BulletList, Button, Carousel, Checkbox, Chip, CodeInput, type CreateReactRendererOptions, DetailRow, Disclosure, Divider, EmptyState, Footer, Grid, GridItem, Icon, Image, Input, Link, List, ListItem, Notice, Option, ProgressBar, Prose, QRCode, Quote, Radio, RadioGroup, type ReactComponent, type ReactComponents, type ReactRendererOptions, type ResolvedColors, type ResolvedTheme, RichText, Scroll, Select, Sheet, Skeleton, Slider, Spinner, Stack, Step, Stepper, Steps, Switch, Tab, Tabs, Text, TextArea, Toast, View, type Wrapper, createReactRenderer, reactRenderer as default, resolveTheme, useTheme };
|
|
44
|
+
export { AmountInput, Avatar, Badge, type BuiltinReactComponents, Bullet, BulletList, Button, Carousel, Checkbox, Chip, CodeInput, type CreateReactRendererOptions, DetailRow, Disclosure, Divider, EmptyState, Footer, Grid, GridItem, Icon, Image, Input, Link, List, ListItem, Notice, Option, Pinned, ProgressBar, Prose, QRCode, Quote, Radio, RadioGroup, type ReactComponent, type ReactComponents, type ReactRendererOptions, type ResolvedColors, type ResolvedTheme, RichText, Scroll, Select, Sheet, Skeleton, Slider, Spinner, Stack, Step, Stepper, Steps, Switch, Tab, Tabs, Text, TextArea, Toast, View, type Wrapper, createReactRenderer, reactRenderer as default, resolveTheme, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import { Input } from "./components/input.js";
|
|
|
19
19
|
import { Link } from "./components/link.js";
|
|
20
20
|
import { List, ListItem } from "./components/list.js";
|
|
21
21
|
import { Option } from "./components/option.js";
|
|
22
|
+
import { Pinned } from "./components/pinned.js";
|
|
22
23
|
import { Bullet, BulletList, Prose, Quote } from "./components/prose.js";
|
|
23
24
|
import { QRCode } from "./components/qr-code.js";
|
|
24
25
|
import { Text } from "./components/text.js";
|
|
@@ -40,4 +41,4 @@ import { createReactRenderer, reactRenderer } from "./renderer.js";
|
|
|
40
41
|
//#region src/index.ts
|
|
41
42
|
var src_default = reactRenderer;
|
|
42
43
|
//#endregion
|
|
43
|
-
export { AmountInput, Avatar, Badge, Bullet, BulletList, Button, Carousel, Checkbox, Chip, CodeInput, DetailRow, Disclosure, Divider, EmptyState, Footer, Grid, GridItem, Icon, Image, Input, Link, List, ListItem, Notice, Option, ProgressBar, Prose, QRCode, Quote, Radio, RadioGroup, RichText, Scroll, Select, Sheet, Skeleton, Slider, Spinner, Stack, Step, Stepper, Steps, Switch, Tab, Tabs, Text, TextArea, Toast, View, createReactRenderer, src_default as default, resolveTheme, useTheme };
|
|
44
|
+
export { AmountInput, Avatar, Badge, Bullet, BulletList, Button, Carousel, Checkbox, Chip, CodeInput, DetailRow, Disclosure, Divider, EmptyState, Footer, Grid, GridItem, Icon, Image, Input, Link, List, ListItem, Notice, Option, Pinned, ProgressBar, Prose, QRCode, Quote, Radio, RadioGroup, RichText, Scroll, Select, Sheet, Skeleton, Slider, Spinner, Stack, Step, Stepper, Steps, Switch, Tab, Tabs, Text, TextArea, Toast, View, createReactRenderer, src_default as default, resolveTheme, useTheme };
|
package/dist/page-root.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useTheme } from "./theme.js";
|
|
2
|
+
import { toList, toText, withComponentDefaults } from "@monimesl/dot-core";
|
|
2
3
|
import { Fragment, createElement, useMemo, useSyncExternalStore } from "react";
|
|
3
4
|
//#region src/page-root.tsx
|
|
4
5
|
function PageRoot({ page, components }) {
|
|
5
6
|
const state = useSyncExternalStore(page.subscribe, page.getState);
|
|
7
|
+
const themeComponents = useTheme().components;
|
|
6
8
|
const context = useMemo(() => ({
|
|
7
9
|
h(type, props, ...children) {
|
|
8
10
|
const component = components[type];
|
|
9
11
|
if (!component) throw new Error(`The renderer has no component for <${type}>. Check the tag's name, or pass a component for it to the renderer.`);
|
|
10
|
-
return createElement(component, props, ...children);
|
|
12
|
+
return createElement(component, withComponentDefaults(type, props, themeComponents), ...children);
|
|
11
13
|
},
|
|
12
14
|
text: toText,
|
|
13
15
|
on: (handler, data) => page.on(handler, data),
|
|
14
16
|
each: (items, render, key) => createElement(Fragment, null, toList(items).map((item, index) => createElement(Fragment, { key: key ? String(key(item, index)) : index }, ...render(item, index))))
|
|
15
|
-
}), [
|
|
17
|
+
}), [
|
|
18
|
+
page,
|
|
19
|
+
components,
|
|
20
|
+
themeComponents
|
|
21
|
+
]);
|
|
16
22
|
if (!state) return null;
|
|
17
23
|
return page.viewRenderer(state, context);
|
|
18
24
|
}
|
package/dist/pull-to-refresh.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useTheme } from "./theme.js";
|
|
2
1
|
import { CENTERED } from "./components/tokens.js";
|
|
2
|
+
import { useTheme } from "./theme.js";
|
|
3
3
|
import { LoadingIcon } from "./components/spinner.js";
|
|
4
4
|
import { useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
package/dist/root.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ThemeContext, resolveTheme, useTheme } from "./theme.js";
|
|
2
2
|
import { HOME_INDICATOR } from "./components/padding.js";
|
|
3
3
|
import { PortalContainerContext } from "./portal.js";
|
|
4
4
|
import { PageRoot } from "./page-root.js";
|
|
@@ -27,6 +27,7 @@ function Root({ page, dotContext, components, wrapper: Wrapper }) {
|
|
|
27
27
|
ref: setRootElement,
|
|
28
28
|
className: "dot-theme-root",
|
|
29
29
|
"data-dot-scheme": resolvedTheme.scheme,
|
|
30
|
+
style: { overflow: "clip" },
|
|
30
31
|
children: /* @__PURE__ */ jsx(PortalContainerContext.Provider, {
|
|
31
32
|
value: rootElement,
|
|
32
33
|
children: /* @__PURE__ */ jsx(PullToRefresh, {
|
|
@@ -51,7 +52,7 @@ function withPageColors(theme, scheme, pageColors) {
|
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
function DefaultSurface({ children }) {
|
|
54
|
-
const { colors } = useTheme();
|
|
55
|
+
const { colors, fontFamily } = useTheme();
|
|
55
56
|
return /* @__PURE__ */ jsx("div", {
|
|
56
57
|
className: "dot-surface",
|
|
57
58
|
style: {
|
|
@@ -62,7 +63,7 @@ function DefaultSurface({ children }) {
|
|
|
62
63
|
flexDirection: "column",
|
|
63
64
|
background: colors.background,
|
|
64
65
|
color: colors.text,
|
|
65
|
-
fontFamily
|
|
66
|
+
fontFamily
|
|
66
67
|
},
|
|
67
68
|
children
|
|
68
69
|
});
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer base{.dot-theme-root,.dot-theme-root *,.dot-theme-root :before,.dot-theme-root :after{box-sizing:border-box}.dot-theme-root :is(button,input,select,textarea){font:inherit}[data-dot-scheme=light]{color-scheme:light}[data-dot-scheme=dark]{color-scheme:dark}.dot-theme-root{-webkit-user-select:none;user-select:none}.dot-theme-root :is(input,textarea){-webkit-user-select:text;user-select:text}}@keyframes dot-skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}.dot-image{max-width:100%;display:block}.dot-list>.dot-list-item:not(:last-child){border-bottom:1px solid var(--dot-list-divider)}.dot-scroll
|
|
1
|
+
@layer base{.dot-theme-root,.dot-theme-root *,.dot-theme-root :before,.dot-theme-root :after{box-sizing:border-box}.dot-theme-root :is(button,input,select,textarea){font:inherit}[data-dot-scheme=light]{color-scheme:light}[data-dot-scheme=dark]{color-scheme:dark}.dot-theme-root{-webkit-user-select:none;user-select:none}.dot-theme-root :is(input,textarea){-webkit-user-select:text;user-select:text}}@keyframes dot-skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}.dot-image{max-width:100%;display:block}.dot-list>.dot-list-item:not(:last-child){border-bottom:1px solid var(--dot-list-divider)}.dot-scroll::-webkit-scrollbar{display:none}.dot-scroll>*{scroll-snap-align:var(--dot-scroll-snap);flex:none;width:min-content}.dot-scroll .dot-image{max-width:none}.dot-bar-top:not(:not(.dot-toast,[hidden])~*){margin-top:calc(-1 * var(--dot-view-top,0px))}.dot-bar-bottom:not(:has(~:not(.dot-toast,[hidden]))){margin-bottom:calc(-1 * var(--dot-view-bottom,0px) - env(safe-area-inset-bottom,0px))}.dot-disclosure>summary{list-style:none}.dot-disclosure>summary::-webkit-details-marker{display:none}.dot-steps>.dot-step:last-child .dot-step-line{display:none}.dot-sheet-backdrop{transition:opacity .2s}.dot-sheet{transition:transform .2s ease-out}.dot-sheet-backdrop:is([data-starting-style],[data-ending-style]){opacity:0}.dot-sheet:is([data-starting-style],[data-ending-style]){transform:translateY(100%)}.dot-prose>.dot-heading{margin-block-start:.5em}.dot-prose>.dot-heading:first-child{margin-block-start:0}
|
package/dist/theme.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FONT_SIZE, SPACE } from "./components/tokens.js";
|
|
2
|
+
import { ColorScheme, PageColors, Theme, ThemeComponents, ThemeElevation, ThemeShape, ThemeWeight } from "@monimesl/dot-core";
|
|
2
3
|
//#region src/theme.d.ts
|
|
3
4
|
export interface ResolvedColors {
|
|
4
5
|
primary: string;
|
|
5
6
|
onPrimary: string;
|
|
7
|
+
primaryText: string;
|
|
6
8
|
background: string;
|
|
7
9
|
surface: string;
|
|
8
10
|
text: string;
|
|
@@ -20,6 +22,15 @@ export interface ResolvedTheme {
|
|
|
20
22
|
customColors: Readonly<Record<string, string>>;
|
|
21
23
|
shape: ThemeShape;
|
|
22
24
|
radius: number;
|
|
25
|
+
fontFamily: string;
|
|
26
|
+
headingFontFamily: string;
|
|
27
|
+
headingWeight: ThemeWeight | undefined;
|
|
28
|
+
fontSize: Readonly<Record<keyof typeof FONT_SIZE, number>>;
|
|
29
|
+
components: ThemeComponents;
|
|
30
|
+
icons: Readonly<Record<string, string>>;
|
|
31
|
+
gradients: Readonly<Record<string, string>>;
|
|
32
|
+
space: Readonly<Record<keyof typeof SPACE, number>>;
|
|
33
|
+
elevation: ThemeElevation;
|
|
23
34
|
}
|
|
24
35
|
export declare function resolveTheme(theme: Theme, systemScheme: ColorScheme, pageColors?: PageColors): ResolvedTheme;
|
|
25
36
|
export declare function useTheme(): ResolvedTheme;
|
package/dist/theme.js
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
|
+
import { FONT_SIZE, SPACE } from "./components/tokens.js";
|
|
1
2
|
import { darken, mix } from "./color.js";
|
|
2
3
|
import { DEFAULT_BACKGROUND, READABLE_CONTRAST, contrast, isDark, pageBackground, textOn, themeScheme } from "@monimesl/dot-core";
|
|
3
4
|
import { createContext, useContext } from "react";
|
|
4
5
|
//#region src/theme.ts
|
|
5
|
-
const
|
|
6
|
+
const DENSITY_SCALE = {
|
|
7
|
+
compact: .75,
|
|
8
|
+
regular: 1,
|
|
9
|
+
comfortable: 1.25
|
|
10
|
+
};
|
|
11
|
+
const TEXT_SCALE = {
|
|
12
|
+
small: .9,
|
|
13
|
+
regular: 1,
|
|
14
|
+
large: 1.1
|
|
15
|
+
};
|
|
16
|
+
const GRADIENT_DIRECTIONS = {
|
|
17
|
+
down: "to bottom",
|
|
18
|
+
right: "to right",
|
|
19
|
+
diagonal: "to bottom right"
|
|
20
|
+
};
|
|
21
|
+
const FONT_FAMILIES = {
|
|
22
|
+
system: "system-ui, sans-serif",
|
|
23
|
+
rounded: "ui-rounded, \"SF Pro Rounded\", system-ui, sans-serif",
|
|
24
|
+
serif: "ui-serif, \"New York\", Georgia, serif",
|
|
25
|
+
mono: "ui-monospace, \"SF Mono\", Menlo, monospace"
|
|
26
|
+
};
|
|
6
27
|
const SHAPE_RADIUS = {
|
|
7
28
|
square: 0,
|
|
8
29
|
subtle: 4,
|
|
@@ -51,22 +72,71 @@ function resolveTheme(theme, systemScheme, pageColors = {}) {
|
|
|
51
72
|
const text = ownColor("text") ?? readableText(defaults.text, background);
|
|
52
73
|
let subtle = defaults.subtle;
|
|
53
74
|
if (!onDashBackground) subtle = quieterText(text, background, surface);
|
|
54
|
-
const primary = ownColor("primary") ?? defaults.primary;
|
|
75
|
+
const { primary, onPrimary } = primaryAndOnPrimary(ownColor("primary") ?? defaults.primary, surface, text, scheme);
|
|
76
|
+
const primaryReads = contrast(primary, background) >= READABLE_CONTRAST && contrast(primary, surface) >= READABLE_CONTRAST;
|
|
77
|
+
const colors = {
|
|
78
|
+
...defaults,
|
|
79
|
+
primary,
|
|
80
|
+
onPrimary,
|
|
81
|
+
primaryText: primaryReads ? primary : text,
|
|
82
|
+
background,
|
|
83
|
+
surface,
|
|
84
|
+
text,
|
|
85
|
+
muted: ownColor("muted") ?? surfaces.muted,
|
|
86
|
+
border: ownColor("border") ?? surfaces.border,
|
|
87
|
+
subtle: ownColor("subtle") ?? subtle,
|
|
88
|
+
info: ownColor("info") ?? defaults.info,
|
|
89
|
+
success: ownColor("success") ?? defaults.success,
|
|
90
|
+
warning: ownColor("warning") ?? defaults.warning,
|
|
91
|
+
danger: ownColor("danger") ?? defaults.danger
|
|
92
|
+
};
|
|
93
|
+
const customColors = resolveCustomColors(themeColors.custom ?? {}, scheme);
|
|
94
|
+
const fontFamily = FONT_FAMILIES[theme.font ?? "system"] ?? FONT_FAMILIES.system;
|
|
95
|
+
let headingFontFamily = fontFamily;
|
|
96
|
+
if (theme.headingFont) headingFontFamily = FONT_FAMILIES[theme.headingFont] ?? fontFamily;
|
|
55
97
|
return {
|
|
56
98
|
scheme,
|
|
57
|
-
colors
|
|
58
|
-
|
|
59
|
-
...primaryAndOnPrimary(primary, surface, text, scheme),
|
|
60
|
-
background,
|
|
61
|
-
surface,
|
|
62
|
-
text,
|
|
63
|
-
muted: ownColor("muted") ?? surfaces.muted,
|
|
64
|
-
border: ownColor("border") ?? surfaces.border,
|
|
65
|
-
subtle: ownColor("subtle") ?? subtle
|
|
66
|
-
},
|
|
67
|
-
customColors: resolveCustomColors(themeColors.custom ?? {}, scheme),
|
|
99
|
+
colors,
|
|
100
|
+
customColors,
|
|
68
101
|
shape,
|
|
69
|
-
radius: SHAPE_RADIUS[shape]
|
|
102
|
+
radius: SHAPE_RADIUS[shape],
|
|
103
|
+
fontFamily,
|
|
104
|
+
headingFontFamily,
|
|
105
|
+
headingWeight: theme.headingWeight,
|
|
106
|
+
fontSize: scaledFontSize(TEXT_SCALE[theme.textSize ?? "regular"] ?? 1),
|
|
107
|
+
components: theme.components ?? {},
|
|
108
|
+
icons: theme.icons ?? {},
|
|
109
|
+
gradients: resolveGradients(theme.gradients ?? {}, colors, customColors),
|
|
110
|
+
space: scaledSpace(DENSITY_SCALE[theme.density ?? "regular"] ?? 1),
|
|
111
|
+
elevation: theme.elevation === "raised" ? "raised" : "flat"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function scaledFontSize(scale) {
|
|
115
|
+
const sizes = { ...FONT_SIZE };
|
|
116
|
+
for (const variant of Object.keys(sizes)) sizes[variant] = Math.round(FONT_SIZE[variant] * scale);
|
|
117
|
+
return sizes;
|
|
118
|
+
}
|
|
119
|
+
function resolveGradients(gradients, colors, customColors) {
|
|
120
|
+
const resolved = {};
|
|
121
|
+
for (const [name, gradient] of Object.entries(gradients)) {
|
|
122
|
+
if (!gradient) continue;
|
|
123
|
+
const from = themeColor(gradient.from, colors, customColors);
|
|
124
|
+
const to = themeColor(gradient.to, colors, customColors);
|
|
125
|
+
const direction = GRADIENT_DIRECTIONS[gradient.direction ?? "down"] ?? GRADIENT_DIRECTIONS.down;
|
|
126
|
+
if (from && to) resolved[name] = `linear-gradient(${direction}, ${from}, ${to})`;
|
|
127
|
+
}
|
|
128
|
+
return resolved;
|
|
129
|
+
}
|
|
130
|
+
function themeColor(name, colors, customColors) {
|
|
131
|
+
if (Object.hasOwn(colors, name)) return colors[name];
|
|
132
|
+
if (Object.hasOwn(customColors, name)) return customColors[name];
|
|
133
|
+
}
|
|
134
|
+
function scaledSpace(scale) {
|
|
135
|
+
return {
|
|
136
|
+
none: SPACE.none,
|
|
137
|
+
small: Math.round(SPACE.small * scale),
|
|
138
|
+
medium: Math.round(SPACE.medium * scale),
|
|
139
|
+
large: Math.round(SPACE.large * scale)
|
|
70
140
|
};
|
|
71
141
|
}
|
|
72
142
|
function surfacesOn(background) {
|
|
@@ -126,4 +196,4 @@ function useTheme() {
|
|
|
126
196
|
return useContext(ThemeContext);
|
|
127
197
|
}
|
|
128
198
|
//#endregion
|
|
129
|
-
export {
|
|
199
|
+
export { ThemeContext, resolveTheme, useTheme };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monimesl/dot-renderer-react",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.10",
|
|
4
4
|
"description": "React renderer for Dot webviews",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"react": "19.3.0",
|
|
30
30
|
"react-dom": "19.3.0",
|
|
31
31
|
"uqr": "^0.1.3",
|
|
32
|
-
"@monimesl/dot-core": "1.0.0-beta.
|
|
33
|
-
"@monimesl/dot-webview": "1.0.0-beta.
|
|
32
|
+
"@monimesl/dot-core": "1.0.0-beta.10",
|
|
33
|
+
"@monimesl/dot-webview": "1.0.0-beta.10"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@base-ui/react": "1.8.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"tsdown": "^0.23.0",
|
|
47
47
|
"typescript": "^5.9.3",
|
|
48
48
|
"vitest": "^5.0.1",
|
|
49
|
-
"@monimesl/dot-service": "1.0.0-beta.
|
|
49
|
+
"@monimesl/dot-service": "1.0.0-beta.10"
|
|
50
50
|
},
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|