@solidrt/components 0.0.51 → 0.0.52
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/AGENTS.md +34 -7
- package/README.md +47 -10
- package/demos/README.md +24 -0
- package/demos/assets/icon.png +0 -0
- package/demos/assets/icon.svg +23 -0
- package/demos/package.json +9 -0
- package/demos/src/gallery.tsx +866 -0
- package/demos/tsconfig.json +15 -0
- package/docs/button.md +1 -1
- package/docs/focus-nav.md +1 -1
- package/docs/icon.md +1 -1
- package/docs/item.md +1 -1
- package/docs/policy.md +1 -1
- package/docs/scroll-view.md +22 -1
- package/docs/split-view.md +1 -1
- package/docs/theme.md +14 -2
- package/docs/types.md +4 -0
- package/package.json +4 -3
- package/src/badge.tsx +21 -14
- package/src/button.tsx +13 -7
- package/src/card.tsx +10 -3
- package/src/checkbox.tsx +8 -2
- package/src/context-menu.tsx +9 -6
- package/src/divider.tsx +8 -3
- package/src/editor-field.tsx +18 -11
- package/src/field.tsx +4 -2
- package/src/icon.tsx +8 -4
- package/src/image.tsx +10 -3
- package/src/index.ts +10 -1
- package/src/item.tsx +12 -7
- package/src/nav-shell.tsx +6 -16
- package/src/policy.ts +9 -4
- package/src/pressable.tsx +11 -2
- package/src/progress-bar.tsx +4 -3
- package/src/qrcode.tsx +7 -5
- package/src/radio.tsx +12 -4
- package/src/rich-text-editor.tsx +5 -3
- package/src/scroll-view.tsx +76 -7
- package/src/segmented-control.tsx +14 -5
- package/src/select.tsx +23 -12
- package/src/slider.tsx +31 -5
- package/src/spinner.tsx +5 -2
- package/src/split-view.tsx +3 -4
- package/src/switch.tsx +8 -2
- package/src/text-input.tsx +4 -2
- package/src/text.tsx +22 -2
- package/src/theme.ts +72 -20
- package/src/tooltip.tsx +16 -5
- package/src/types.ts +119 -1
- package/src/view.tsx +11 -2
package/src/types.ts
CHANGED
|
@@ -1,4 +1,122 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Color,
|
|
3
|
+
Gradient,
|
|
4
|
+
LayoutProps,
|
|
5
|
+
Transition,
|
|
6
|
+
TransitionEndEvent,
|
|
7
|
+
TransitionPropName,
|
|
8
|
+
TransitionProps as CoreTransitionProps,
|
|
9
|
+
} from "@solidrt/core"
|
|
10
|
+
|
|
11
|
+
// Native transitions through a component. A component is a root view plus
|
|
12
|
+
// the nodes it draws for `style` (a background d-rect, a stroke d-rect for
|
|
13
|
+
// the border), so a declaration names the STYLE properties - backgroundColor,
|
|
14
|
+
// borderColor, borderWidth, borderRadius - next to the view-level ones, and
|
|
15
|
+
// splitTransition hands each entry to the node that owns it. Core's paint
|
|
16
|
+
// names (color, radius, strokeWidth) are deliberately not accepted: on a
|
|
17
|
+
// component they would land on the root view, which has no paint, and be
|
|
18
|
+
// silently ignored.
|
|
19
|
+
//
|
|
20
|
+
// Controls whose paint is their own (Switch knob, Slider thumb, Checkbox
|
|
21
|
+
// mark, ...) take the view-level entries only for now; see
|
|
22
|
+
// okf/backlog/component-transitions-internal-paint.md.
|
|
23
|
+
export type TransitionViewProp =
|
|
24
|
+
| "opacity"
|
|
25
|
+
| "x"
|
|
26
|
+
| "y"
|
|
27
|
+
| "scale"
|
|
28
|
+
| "scaleX"
|
|
29
|
+
| "scaleY"
|
|
30
|
+
| "rotate"
|
|
31
|
+
| "rotateX"
|
|
32
|
+
| "rotateY"
|
|
33
|
+
| "originX"
|
|
34
|
+
| "originY"
|
|
35
|
+
| "perspective"
|
|
36
|
+
| "clipRadius"
|
|
37
|
+
export type TransitionStyleProp = "backgroundColor" | "borderColor" | "borderWidth" | "borderRadius"
|
|
38
|
+
export type TransitionScrollProp = "scrollX" | "scrollY"
|
|
39
|
+
|
|
40
|
+
type TransitionEntries<P extends string> = {
|
|
41
|
+
/** One spec for every property the component animates (no `from`/`exit` here, as in core). */
|
|
42
|
+
all?: Transition
|
|
43
|
+
/** Group stagger (ms) for descendant enter/exit animations; see core. */
|
|
44
|
+
stagger?: number
|
|
45
|
+
} & { [K in P]?: Transition }
|
|
46
|
+
|
|
47
|
+
/** A component's transition declaration: view-level and style names, `all`, or a shorthand string. */
|
|
48
|
+
export type ComponentTransition<P extends string = TransitionViewProp | TransitionStyleProp> =
|
|
49
|
+
| TransitionEntries<P>
|
|
50
|
+
| string
|
|
51
|
+
| null
|
|
52
|
+
|
|
53
|
+
export interface TransitionProps<P extends string = TransitionViewProp | TransitionStyleProp> {
|
|
54
|
+
/**
|
|
55
|
+
* Animate later writes of the listed properties instead of snapping, like
|
|
56
|
+
* the core `transition` prop but in the component's own vocabulary:
|
|
57
|
+
* `transition={{ opacity: "200ms ease-out", backgroundColor: { duration: 300 } }}`.
|
|
58
|
+
* `all` or a bare string covers every property the component animates.
|
|
59
|
+
*/
|
|
60
|
+
transition?: ComponentTransition<P>
|
|
61
|
+
/** A transition settled; `property` is in the component's vocabulary (`backgroundColor`, not `color`). */
|
|
62
|
+
onTransitionEnd?: (event: { property: P }) => void
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The core transition declarations for a component's root view and its background/border rects. */
|
|
66
|
+
export type SplitTransition = {
|
|
67
|
+
root: CoreTransitionProps["transition"]
|
|
68
|
+
background: CoreTransitionProps["transition"]
|
|
69
|
+
border: CoreTransitionProps["transition"]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const STYLE_TO_BACKGROUND: Record<string, TransitionPropName> = { backgroundColor: "color", borderRadius: "radius" }
|
|
73
|
+
const STYLE_TO_BORDER: Record<string, TransitionPropName> = {
|
|
74
|
+
borderColor: "color",
|
|
75
|
+
borderWidth: "strokeWidth",
|
|
76
|
+
borderRadius: "radius",
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Map a component declaration onto the three nodes a styled component
|
|
81
|
+
* draws. `all`, a shorthand string and `stagger` apply to every node; named
|
|
82
|
+
* entries go to the node owning the property. An entry for a node that is
|
|
83
|
+
* not mounted (no background set) simply never animates.
|
|
84
|
+
*/
|
|
85
|
+
export function splitTransition<P extends string>(t: ComponentTransition<P> | undefined): SplitTransition {
|
|
86
|
+
if (t == null || typeof t === "string") return { root: t, background: t, border: t }
|
|
87
|
+
let root: Record<string, unknown> = {}
|
|
88
|
+
let background: Record<string, unknown> = {}
|
|
89
|
+
let border: Record<string, unknown> = {}
|
|
90
|
+
for (let [key, value] of Object.entries(t)) {
|
|
91
|
+
if (key === "all" || key === "stagger") {
|
|
92
|
+
root[key] = value
|
|
93
|
+
background[key] = value
|
|
94
|
+
border[key] = value
|
|
95
|
+
} else if (key in STYLE_TO_BACKGROUND || key in STYLE_TO_BORDER) {
|
|
96
|
+
if (key in STYLE_TO_BACKGROUND) background[STYLE_TO_BACKGROUND[key]!] = value
|
|
97
|
+
if (key in STYLE_TO_BORDER) border[STYLE_TO_BORDER[key]!] = value
|
|
98
|
+
} else {
|
|
99
|
+
root[key] = value
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
let pick = (o: Record<string, unknown>) => (Object.keys(o).length ? (o as CoreTransitionProps["transition"]) : undefined)
|
|
103
|
+
return { root: pick(root), background: pick(background), border: pick(border) }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Report a settled core property in the component vocabulary for the node it settled on. */
|
|
107
|
+
export function transitionEndFor<P extends string>(
|
|
108
|
+
node: "root" | "background" | "border",
|
|
109
|
+
handler: ((event: { property: P }) => void) | undefined,
|
|
110
|
+
): ((event: TransitionEndEvent) => void) | undefined {
|
|
111
|
+
if (!handler) return undefined
|
|
112
|
+
return (e) => {
|
|
113
|
+
let name: string = e.property
|
|
114
|
+
if (node === "background") name = e.property === "color" ? "backgroundColor" : "borderRadius"
|
|
115
|
+
if (node === "border")
|
|
116
|
+
name = e.property === "color" ? "borderColor" : e.property === "strokeWidth" ? "borderWidth" : "borderRadius"
|
|
117
|
+
handler({ property: name as P })
|
|
118
|
+
}
|
|
119
|
+
}
|
|
2
120
|
|
|
3
121
|
// The split between layout and style follows one rule: layout properties feed
|
|
4
122
|
// into Taffy and changing them triggers a relayout; style properties are
|
package/src/view.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { LayoutProps, PointerProps } from "@solidrt/core"
|
|
2
|
-
import type { StyleProps } from "./types"
|
|
2
|
+
import type { StyleProps, TransitionProps } from "./types"
|
|
3
|
+
import { splitTransition, transitionEndFor } from "./types"
|
|
3
4
|
|
|
4
|
-
export interface ViewProps extends PointerProps {
|
|
5
|
+
export interface ViewProps extends PointerProps, TransitionProps {
|
|
5
6
|
children?: any
|
|
6
7
|
ref?: (node: { id: number }) => void
|
|
7
8
|
layout?: LayoutProps
|
|
@@ -13,8 +14,12 @@ export function View(props: ViewProps) {
|
|
|
13
14
|
props.style?.backgroundColor != null || props.style?.borderRadius != null
|
|
14
15
|
let hasBorder = () => (props.style?.borderWidth ?? 0) > 0
|
|
15
16
|
|
|
17
|
+
let split = () => splitTransition(props.transition)
|
|
18
|
+
|
|
16
19
|
return (
|
|
17
20
|
<view
|
|
21
|
+
transition={split().root}
|
|
22
|
+
onTransitionEnd={transitionEndFor("root", props.onTransitionEnd)}
|
|
18
23
|
ref={props.ref}
|
|
19
24
|
{...props.layout}
|
|
20
25
|
x={props.style?.x}
|
|
@@ -45,6 +50,8 @@ export function View(props: ViewProps) {
|
|
|
45
50
|
>
|
|
46
51
|
{hasBackground() ? (
|
|
47
52
|
<d-rect
|
|
53
|
+
transition={split().background}
|
|
54
|
+
onTransitionEnd={transitionEndFor("background", props.onTransitionEnd)}
|
|
48
55
|
color={props.style?.backgroundColor ?? "transparent"}
|
|
49
56
|
radius={props.style?.borderRadius}
|
|
50
57
|
/>
|
|
@@ -53,6 +60,8 @@ export function View(props: ViewProps) {
|
|
|
53
60
|
{hasBorder() ? (
|
|
54
61
|
<d-rect
|
|
55
62
|
drawStyle="stroke"
|
|
63
|
+
transition={split().border}
|
|
64
|
+
onTransitionEnd={transitionEndFor("border", props.onTransitionEnd)}
|
|
56
65
|
color={props.style?.borderColor ?? "transparent"}
|
|
57
66
|
strokeWidth={props.style?.borderWidth}
|
|
58
67
|
radius={props.style?.borderRadius}
|