@farcaster/snap 1.3.1 → 1.3.3
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/dist/index.d.ts +1 -1
- package/dist/schemas.d.ts +3 -2
- package/dist/schemas.js +1 -1
- package/dist/server/parseRequest.d.ts +1 -1
- package/dist/server/parseRequest.js +1 -1
- package/dist/ui/bar-chart.d.ts +30 -0
- package/dist/ui/bar-chart.js +14 -0
- package/dist/ui/button-group.d.ts +11 -0
- package/dist/ui/button-group.js +10 -0
- package/dist/ui/button.d.ts +32 -0
- package/dist/ui/button.js +10 -0
- package/dist/ui/catalog.d.ts +271 -0
- package/dist/ui/catalog.js +114 -0
- package/dist/ui/divider.d.ts +3 -0
- package/dist/ui/divider.js +2 -0
- package/dist/ui/grid.d.ts +22 -0
- package/dist/ui/grid.js +16 -0
- package/dist/ui/group.d.ts +8 -0
- package/dist/ui/group.js +4 -0
- package/dist/ui/image.d.ts +13 -0
- package/dist/ui/image.js +7 -0
- package/dist/ui/index.d.ts +32 -0
- package/dist/ui/index.js +17 -0
- package/dist/ui/list.d.ts +13 -0
- package/dist/ui/list.js +13 -0
- package/dist/ui/progress.d.ts +18 -0
- package/dist/ui/progress.js +8 -0
- package/dist/ui/schema.d.ts +32 -0
- package/dist/ui/schema.js +31 -0
- package/dist/ui/slider.d.ts +12 -0
- package/dist/ui/slider.js +11 -0
- package/dist/ui/spacer.d.ts +9 -0
- package/dist/ui/spacer.js +5 -0
- package/dist/ui/stack.d.ts +3 -0
- package/dist/ui/stack.js +2 -0
- package/dist/ui/text-input.d.ts +7 -0
- package/dist/ui/text-input.js +12 -0
- package/dist/ui/text.d.ts +16 -0
- package/dist/ui/text.js +7 -0
- package/dist/ui/toggle.d.ts +7 -0
- package/dist/ui/toggle.js +6 -0
- package/dist/validator.d.ts +1 -1
- package/package.json +83 -2
- package/src/index.ts +1 -0
- package/src/schemas.ts +3 -2
- package/src/server/parseRequest.ts +1 -1
- package/src/ui/README.md +50 -0
- package/src/ui/bar-chart.ts +23 -0
- package/src/ui/button-group.ts +13 -0
- package/src/ui/button.ts +15 -0
- package/src/ui/catalog.ts +128 -0
- package/src/ui/divider.ts +5 -0
- package/src/ui/grid.ts +25 -0
- package/src/ui/group.ts +7 -0
- package/src/ui/image.ts +10 -0
- package/src/ui/index.ts +47 -0
- package/src/ui/list.ts +17 -0
- package/src/ui/progress.ts +11 -0
- package/src/ui/schema.ts +37 -0
- package/src/ui/slider.ts +14 -0
- package/src/ui/spacer.ts +8 -0
- package/src/ui/stack.ts +5 -0
- package/src/ui/text-input.ts +15 -0
- package/src/ui/text.ts +10 -0
- package/src/ui/toggle.ts +9 -0
- package/src/validator.ts +1 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export { snapJsonRenderSchema } from "./schema.js";
|
|
2
|
+
export { snapJsonRenderCatalog } from "./catalog.js";
|
|
3
|
+
export { textProps } from "./text.js";
|
|
4
|
+
export type { TextProps } from "./text.js";
|
|
5
|
+
export { imageProps } from "./image.js";
|
|
6
|
+
export type { ImageProps } from "./image.js";
|
|
7
|
+
export { dividerProps } from "./divider.js";
|
|
8
|
+
export type { DividerProps } from "./divider.js";
|
|
9
|
+
export { spacerProps } from "./spacer.js";
|
|
10
|
+
export type { SpacerProps } from "./spacer.js";
|
|
11
|
+
export { progressProps } from "./progress.js";
|
|
12
|
+
export type { ProgressProps } from "./progress.js";
|
|
13
|
+
export { listProps } from "./list.js";
|
|
14
|
+
export type { ListProps } from "./list.js";
|
|
15
|
+
export { gridProps } from "./grid.js";
|
|
16
|
+
export type { GridProps } from "./grid.js";
|
|
17
|
+
export { textInputProps } from "./text-input.js";
|
|
18
|
+
export type { TextInputProps } from "./text-input.js";
|
|
19
|
+
export { sliderProps } from "./slider.js";
|
|
20
|
+
export type { SliderProps } from "./slider.js";
|
|
21
|
+
export { buttonGroupProps } from "./button-group.js";
|
|
22
|
+
export type { ButtonGroupProps } from "./button-group.js";
|
|
23
|
+
export { toggleProps } from "./toggle.js";
|
|
24
|
+
export type { ToggleProps } from "./toggle.js";
|
|
25
|
+
export { barChartProps } from "./bar-chart.js";
|
|
26
|
+
export type { BarChartProps } from "./bar-chart.js";
|
|
27
|
+
export { groupProps } from "./group.js";
|
|
28
|
+
export type { GroupProps } from "./group.js";
|
|
29
|
+
export { stackProps } from "./stack.js";
|
|
30
|
+
export type { StackProps } from "./stack.js";
|
|
31
|
+
export { actionButtonProps, buttonProps } from "./button.js";
|
|
32
|
+
export type { ActionButtonProps, ButtonProps } from "./button.js";
|
package/dist/ui/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { snapJsonRenderSchema } from "./schema.js";
|
|
2
|
+
export { snapJsonRenderCatalog } from "./catalog.js";
|
|
3
|
+
export { textProps } from "./text.js";
|
|
4
|
+
export { imageProps } from "./image.js";
|
|
5
|
+
export { dividerProps } from "./divider.js";
|
|
6
|
+
export { spacerProps } from "./spacer.js";
|
|
7
|
+
export { progressProps } from "./progress.js";
|
|
8
|
+
export { listProps } from "./list.js";
|
|
9
|
+
export { gridProps } from "./grid.js";
|
|
10
|
+
export { textInputProps } from "./text-input.js";
|
|
11
|
+
export { sliderProps } from "./slider.js";
|
|
12
|
+
export { buttonGroupProps } from "./button-group.js";
|
|
13
|
+
export { toggleProps } from "./toggle.js";
|
|
14
|
+
export { barChartProps } from "./bar-chart.js";
|
|
15
|
+
export { groupProps } from "./group.js";
|
|
16
|
+
export { stackProps } from "./stack.js";
|
|
17
|
+
export { actionButtonProps, buttonProps } from "./button.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const listProps: z.ZodObject<{
|
|
3
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
4
|
+
ordered: "ordered";
|
|
5
|
+
unordered: "unordered";
|
|
6
|
+
plain: "plain";
|
|
7
|
+
}>>;
|
|
8
|
+
items: z.ZodArray<z.ZodObject<{
|
|
9
|
+
content: z.ZodString;
|
|
10
|
+
trailing: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
export type ListProps = z.infer<typeof listProps>;
|
package/dist/ui/list.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { LIMITS, LIST_STYLE_VALUES } from "../constants.js";
|
|
3
|
+
const listItemZ = z.object({
|
|
4
|
+
content: z.string(),
|
|
5
|
+
trailing: z.string().optional(),
|
|
6
|
+
});
|
|
7
|
+
export const listProps = z.object({
|
|
8
|
+
style: z.enum(LIST_STYLE_VALUES).optional(),
|
|
9
|
+
items: z
|
|
10
|
+
.array(listItemZ)
|
|
11
|
+
.min(LIMITS.minListItems)
|
|
12
|
+
.max(LIMITS.maxListItems),
|
|
13
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const progressProps: z.ZodObject<{
|
|
3
|
+
value: z.ZodNumber;
|
|
4
|
+
max: z.ZodNumber;
|
|
5
|
+
label: z.ZodOptional<z.ZodString>;
|
|
6
|
+
color: z.ZodOptional<z.ZodEnum<{
|
|
7
|
+
gray: "gray";
|
|
8
|
+
blue: "blue";
|
|
9
|
+
red: "red";
|
|
10
|
+
amber: "amber";
|
|
11
|
+
green: "green";
|
|
12
|
+
teal: "teal";
|
|
13
|
+
purple: "purple";
|
|
14
|
+
pink: "pink";
|
|
15
|
+
accent: "accent";
|
|
16
|
+
}>>;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type ProgressProps = z.infer<typeof progressProps>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* json-render spec shape: flat `root` + `elements` map (see [json-render](https://json-render.dev/)).
|
|
3
|
+
* Component `type` strings must match keys in {@link ./catalog.ts}.
|
|
4
|
+
*/
|
|
5
|
+
export declare const snapJsonRenderSchema: import("@json-render/core").Schema<{
|
|
6
|
+
spec: import("@json-render/core").SchemaType<"object", {
|
|
7
|
+
root: import("@json-render/core").SchemaType<"string", unknown>;
|
|
8
|
+
elements: import("@json-render/core").SchemaType<"record", import("@json-render/core").SchemaType<"object", {
|
|
9
|
+
type: import("@json-render/core").SchemaType<"ref", string>;
|
|
10
|
+
props: import("@json-render/core").SchemaType<"propsOf", string>;
|
|
11
|
+
children: {
|
|
12
|
+
optional: true;
|
|
13
|
+
kind: "array";
|
|
14
|
+
inner?: import("@json-render/core").SchemaType<"string", unknown> | undefined;
|
|
15
|
+
};
|
|
16
|
+
}>>;
|
|
17
|
+
}>;
|
|
18
|
+
catalog: import("@json-render/core").SchemaType<"object", {
|
|
19
|
+
components: import("@json-render/core").SchemaType<"map", {
|
|
20
|
+
props: import("@json-render/core").SchemaType<"zod", unknown>;
|
|
21
|
+
description: import("@json-render/core").SchemaType<"string", unknown>;
|
|
22
|
+
}>;
|
|
23
|
+
actions: import("@json-render/core").SchemaType<"map", {
|
|
24
|
+
description: import("@json-render/core").SchemaType<"string", unknown>;
|
|
25
|
+
params: {
|
|
26
|
+
optional: true;
|
|
27
|
+
kind: "zod";
|
|
28
|
+
inner?: unknown;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
}>;
|
|
32
|
+
}>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { defineSchema } from "@json-render/core";
|
|
2
|
+
/**
|
|
3
|
+
* json-render spec shape: flat `root` + `elements` map (see [json-render](https://json-render.dev/)).
|
|
4
|
+
* Component `type` strings must match keys in {@link ./catalog.ts}.
|
|
5
|
+
*/
|
|
6
|
+
export const snapJsonRenderSchema = defineSchema((s) => ({
|
|
7
|
+
spec: s.object({
|
|
8
|
+
root: s.string(),
|
|
9
|
+
elements: s.record(s.object({
|
|
10
|
+
type: s.ref("catalog.components"),
|
|
11
|
+
props: s.propsOf("catalog.components"),
|
|
12
|
+
children: { ...s.array(s.string()), optional: true },
|
|
13
|
+
})),
|
|
14
|
+
}),
|
|
15
|
+
catalog: s.object({
|
|
16
|
+
components: s.map({
|
|
17
|
+
props: s.zod(),
|
|
18
|
+
description: s.string(),
|
|
19
|
+
}),
|
|
20
|
+
actions: s.map({
|
|
21
|
+
description: s.string(),
|
|
22
|
+
params: { ...s.zod(), optional: true },
|
|
23
|
+
}),
|
|
24
|
+
}),
|
|
25
|
+
}), {
|
|
26
|
+
defaultRules: [
|
|
27
|
+
"You are generating auxiliary UI for a Farcaster Snap. Prefer components matching snap element types (Text, Image, ButtonGroup, …).",
|
|
28
|
+
"Snap pages use a Stack root with at most 5 body children and 1 media element (Image or Grid); keep generated trees small.",
|
|
29
|
+
"Bottom-of-card snap buttons are ActionButton components; use actions post / link / mini_app / sdk per SPEC.md.",
|
|
30
|
+
],
|
|
31
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const sliderProps: z.ZodObject<{
|
|
3
|
+
name: z.ZodString;
|
|
4
|
+
min: z.ZodNumber;
|
|
5
|
+
max: z.ZodNumber;
|
|
6
|
+
step: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
value: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
label: z.ZodOptional<z.ZodString>;
|
|
9
|
+
minLabel: z.ZodOptional<z.ZodString>;
|
|
10
|
+
maxLabel: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export type SliderProps = z.infer<typeof sliderProps>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const sliderProps = z.object({
|
|
3
|
+
name: z.string().min(1),
|
|
4
|
+
min: z.number(),
|
|
5
|
+
max: z.number(),
|
|
6
|
+
step: z.number().optional(),
|
|
7
|
+
value: z.number().optional(),
|
|
8
|
+
label: z.string().optional(),
|
|
9
|
+
minLabel: z.string().optional(),
|
|
10
|
+
maxLabel: z.string().optional(),
|
|
11
|
+
});
|
package/dist/ui/stack.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { LIMITS } from "../constants.js";
|
|
3
|
+
export const textInputProps = z.object({
|
|
4
|
+
name: z.string().min(1),
|
|
5
|
+
placeholder: z.string().optional(),
|
|
6
|
+
maxLength: z
|
|
7
|
+
.number()
|
|
8
|
+
.int()
|
|
9
|
+
.positive()
|
|
10
|
+
.max(LIMITS.maxTextInputChars)
|
|
11
|
+
.optional(),
|
|
12
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const textProps: z.ZodObject<{
|
|
3
|
+
style: z.ZodEnum<{
|
|
4
|
+
title: "title";
|
|
5
|
+
body: "body";
|
|
6
|
+
caption: "caption";
|
|
7
|
+
label: "label";
|
|
8
|
+
}>;
|
|
9
|
+
content: z.ZodString;
|
|
10
|
+
align: z.ZodOptional<z.ZodEnum<{
|
|
11
|
+
left: "left";
|
|
12
|
+
center: "center";
|
|
13
|
+
right: "right";
|
|
14
|
+
}>>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type TextProps = z.infer<typeof textProps>;
|
package/dist/ui/text.js
ADDED
package/dist/validator.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farcaster/snap",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "Farcaster Snaps 🫰",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,6 +20,86 @@
|
|
|
20
20
|
"types": "./dist/server/index.d.ts",
|
|
21
21
|
"import": "./dist/server/index.js",
|
|
22
22
|
"default": "./dist/server/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./ui": {
|
|
25
|
+
"types": "./dist/ui/index.d.ts",
|
|
26
|
+
"import": "./dist/ui/index.js",
|
|
27
|
+
"default": "./dist/ui/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./ui/text": {
|
|
30
|
+
"types": "./dist/ui/text.d.ts",
|
|
31
|
+
"import": "./dist/ui/text.js",
|
|
32
|
+
"default": "./dist/ui/text.js"
|
|
33
|
+
},
|
|
34
|
+
"./ui/image": {
|
|
35
|
+
"types": "./dist/ui/image.d.ts",
|
|
36
|
+
"import": "./dist/ui/image.js",
|
|
37
|
+
"default": "./dist/ui/image.js"
|
|
38
|
+
},
|
|
39
|
+
"./ui/divider": {
|
|
40
|
+
"types": "./dist/ui/divider.d.ts",
|
|
41
|
+
"import": "./dist/ui/divider.js",
|
|
42
|
+
"default": "./dist/ui/divider.js"
|
|
43
|
+
},
|
|
44
|
+
"./ui/spacer": {
|
|
45
|
+
"types": "./dist/ui/spacer.d.ts",
|
|
46
|
+
"import": "./dist/ui/spacer.js",
|
|
47
|
+
"default": "./dist/ui/spacer.js"
|
|
48
|
+
},
|
|
49
|
+
"./ui/progress": {
|
|
50
|
+
"types": "./dist/ui/progress.d.ts",
|
|
51
|
+
"import": "./dist/ui/progress.js",
|
|
52
|
+
"default": "./dist/ui/progress.js"
|
|
53
|
+
},
|
|
54
|
+
"./ui/list": {
|
|
55
|
+
"types": "./dist/ui/list.d.ts",
|
|
56
|
+
"import": "./dist/ui/list.js",
|
|
57
|
+
"default": "./dist/ui/list.js"
|
|
58
|
+
},
|
|
59
|
+
"./ui/grid": {
|
|
60
|
+
"types": "./dist/ui/grid.d.ts",
|
|
61
|
+
"import": "./dist/ui/grid.js",
|
|
62
|
+
"default": "./dist/ui/grid.js"
|
|
63
|
+
},
|
|
64
|
+
"./ui/text-input": {
|
|
65
|
+
"types": "./dist/ui/text-input.d.ts",
|
|
66
|
+
"import": "./dist/ui/text-input.js",
|
|
67
|
+
"default": "./dist/ui/text-input.js"
|
|
68
|
+
},
|
|
69
|
+
"./ui/slider": {
|
|
70
|
+
"types": "./dist/ui/slider.d.ts",
|
|
71
|
+
"import": "./dist/ui/slider.js",
|
|
72
|
+
"default": "./dist/ui/slider.js"
|
|
73
|
+
},
|
|
74
|
+
"./ui/button-group": {
|
|
75
|
+
"types": "./dist/ui/button-group.d.ts",
|
|
76
|
+
"import": "./dist/ui/button-group.js",
|
|
77
|
+
"default": "./dist/ui/button-group.js"
|
|
78
|
+
},
|
|
79
|
+
"./ui/toggle": {
|
|
80
|
+
"types": "./dist/ui/toggle.d.ts",
|
|
81
|
+
"import": "./dist/ui/toggle.js",
|
|
82
|
+
"default": "./dist/ui/toggle.js"
|
|
83
|
+
},
|
|
84
|
+
"./ui/bar-chart": {
|
|
85
|
+
"types": "./dist/ui/bar-chart.d.ts",
|
|
86
|
+
"import": "./dist/ui/bar-chart.js",
|
|
87
|
+
"default": "./dist/ui/bar-chart.js"
|
|
88
|
+
},
|
|
89
|
+
"./ui/group": {
|
|
90
|
+
"types": "./dist/ui/group.d.ts",
|
|
91
|
+
"import": "./dist/ui/group.js",
|
|
92
|
+
"default": "./dist/ui/group.js"
|
|
93
|
+
},
|
|
94
|
+
"./ui/stack": {
|
|
95
|
+
"types": "./dist/ui/stack.d.ts",
|
|
96
|
+
"import": "./dist/ui/stack.js",
|
|
97
|
+
"default": "./dist/ui/stack.js"
|
|
98
|
+
},
|
|
99
|
+
"./ui/button": {
|
|
100
|
+
"types": "./dist/ui/button.d.ts",
|
|
101
|
+
"import": "./dist/ui/button.js",
|
|
102
|
+
"default": "./dist/ui/button.js"
|
|
23
103
|
}
|
|
24
104
|
},
|
|
25
105
|
"files": [
|
|
@@ -32,10 +112,11 @@
|
|
|
32
112
|
"license": "MIT",
|
|
33
113
|
"dependencies": {
|
|
34
114
|
"@farcaster/jfs": "^0.3.0",
|
|
115
|
+
"@json-render/core": "^0.15.0",
|
|
35
116
|
"viem": "^2.21.0"
|
|
36
117
|
},
|
|
37
118
|
"peerDependencies": {
|
|
38
|
-
"zod": "^
|
|
119
|
+
"zod": "^4.0.0"
|
|
39
120
|
},
|
|
40
121
|
"devDependencies": {
|
|
41
122
|
"@types/node": "^25.5.0",
|
package/src/index.ts
CHANGED
package/src/schemas.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from "zod
|
|
1
|
+
import { z } from "zod";
|
|
2
2
|
import {
|
|
3
3
|
BAR_CHART_COLOR_VALUES,
|
|
4
4
|
BUTTON_ACTION,
|
|
@@ -536,6 +536,7 @@ export const payloadSchema = z
|
|
|
536
536
|
.strict();
|
|
537
537
|
|
|
538
538
|
export type SnapResponse = z.infer<typeof rootSchema>;
|
|
539
|
+
export type SnapResponseInput = z.input<typeof rootSchema>;
|
|
539
540
|
export type SnapPage = SnapResponse["page"];
|
|
540
541
|
export type SnapPayload = z.infer<typeof payloadSchema>;
|
|
541
542
|
|
|
@@ -560,4 +561,4 @@ export type SnapContext = {
|
|
|
560
561
|
request: Request;
|
|
561
562
|
};
|
|
562
563
|
|
|
563
|
-
export type SnapFunction = (ctx: SnapContext) => Promise<
|
|
564
|
+
export type SnapFunction = (ctx: SnapContext) => Promise<SnapResponseInput>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { payloadSchema, type SnapAction } from "../schemas";
|
|
2
2
|
import { decodePayload, verifyJFSRequestBody } from "./verify";
|
|
3
|
-
import { z } from "zod
|
|
3
|
+
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
/** Default replay window per SPEC.md § Replay Protection (5 minutes). */
|
|
6
6
|
const DEFAULT_SNAP_POST_MAX_SKEW_SECONDS = 300 as const;
|
package/src/ui/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Theme colors in `@farcaster/snap/ui`
|
|
2
|
+
|
|
3
|
+
This document explains how colors flow through snap pages — from the snap JSON spec to what clients render.
|
|
4
|
+
|
|
5
|
+
## Named palette
|
|
6
|
+
|
|
7
|
+
Snaps use a fixed set of named colors called the **palette**:
|
|
8
|
+
|
|
9
|
+
| Name | Light hex | Dark hex |
|
|
10
|
+
| -------- | --------- | --------- |
|
|
11
|
+
| `gray` | `#8F8F8F` | `#8F8F8F` |
|
|
12
|
+
| `blue` | `#006BFF` | `#006FFE` |
|
|
13
|
+
| `red` | `#FC0036` | `#F13342` |
|
|
14
|
+
| `amber` | `#FFAE00` | `#FFAE00` |
|
|
15
|
+
| `green` | `#28A948` | `#00AC3A` |
|
|
16
|
+
| `teal` | `#00AC96` | `#00AA96` |
|
|
17
|
+
| `purple` | `#8B5CF6` | `#A78BFA` |
|
|
18
|
+
| `pink` | `#F32782` | `#F12B82` |
|
|
19
|
+
|
|
20
|
+
These are exported from `@farcaster/snap` as `PALETTE_LIGHT_HEX`, `PALETTE_DARK_HEX`, and the `PaletteColor` type. Clients resolve the correct hex for their current light/dark mode.
|
|
21
|
+
|
|
22
|
+
## Page-level accent (`page.theme.accent`)
|
|
23
|
+
|
|
24
|
+
A snap page may declare a single accent color for the whole page:
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"page": {
|
|
29
|
+
"theme": { "accent": "blue" }
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`accent` must be a `PaletteColor` name. When `theme` is omitted, schema validation defaults it to `"purple"` (`DEFAULT_THEME_ACCENT`).
|
|
35
|
+
|
|
36
|
+
The accent is the color used for all components on the page that don't have an explicit color set.
|
|
37
|
+
|
|
38
|
+
## Per-element explicit colors
|
|
39
|
+
|
|
40
|
+
Some elements accept a `color` prop:
|
|
41
|
+
|
|
42
|
+
- `progress` — color name or `"accent"`
|
|
43
|
+
- `bar_chart` — color name or `"accent"` at chart level; color name only per-bar
|
|
44
|
+
- `grid` cells — `#rrggbb` hex
|
|
45
|
+
|
|
46
|
+
When `color` is `"accent"` (or omitted), the element uses the accent color. When it is a specific color name or hex value, that color is **explicit** and independent of `page.theme.accent`.
|
|
47
|
+
|
|
48
|
+
## Light/dark mode
|
|
49
|
+
|
|
50
|
+
Mode is determined by the **client**, not by snap JSON. Snap JSON carries no light/dark setting. Clients select `PALETTE_LIGHT_HEX` or `PALETTE_DARK_HEX` based on their current mode.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
BAR_CHART_COLOR_VALUES,
|
|
4
|
+
LIMITS,
|
|
5
|
+
PALETTE_COLOR_VALUES,
|
|
6
|
+
} from "../constants.js";
|
|
7
|
+
|
|
8
|
+
export const barChartProps = z.object({
|
|
9
|
+
bars: z
|
|
10
|
+
.array(
|
|
11
|
+
z.object({
|
|
12
|
+
label: z.string(),
|
|
13
|
+
value: z.number().nonnegative(),
|
|
14
|
+
color: z.enum(PALETTE_COLOR_VALUES).optional(),
|
|
15
|
+
}),
|
|
16
|
+
)
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(LIMITS.maxBarChartBars),
|
|
19
|
+
max: z.number().nonnegative().optional(),
|
|
20
|
+
color: z.enum(BAR_CHART_COLOR_VALUES).optional(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type BarChartProps = z.infer<typeof barChartProps>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { BUTTON_GROUP_STYLE_VALUES, LIMITS } from "../constants.js";
|
|
3
|
+
|
|
4
|
+
export const buttonGroupProps = z.object({
|
|
5
|
+
name: z.string().min(1),
|
|
6
|
+
options: z
|
|
7
|
+
.array(z.string())
|
|
8
|
+
.min(LIMITS.minButtonGroupOptions)
|
|
9
|
+
.max(LIMITS.maxButtonGroupOptions),
|
|
10
|
+
style: z.enum(BUTTON_GROUP_STYLE_VALUES).optional(),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export type ButtonGroupProps = z.infer<typeof buttonGroupProps>;
|
package/src/ui/button.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { BUTTON_ACTION_VALUES, BUTTON_STYLE_VALUES } from "../constants.js";
|
|
3
|
+
|
|
4
|
+
export const actionButtonProps = z.object({
|
|
5
|
+
label: z.string(),
|
|
6
|
+
action: z.enum(BUTTON_ACTION_VALUES),
|
|
7
|
+
target: z.string(),
|
|
8
|
+
style: z.enum(BUTTON_STYLE_VALUES).optional(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export type ActionButtonProps = z.infer<typeof actionButtonProps>;
|
|
12
|
+
|
|
13
|
+
/** Same schema as `actionButtonProps` (legacy export name). */
|
|
14
|
+
export const buttonProps = actionButtonProps;
|
|
15
|
+
export type ButtonProps = ActionButtonProps;
|