@farcaster/snap 1.5.1 → 2.0.0

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 (156) hide show
  1. package/dist/constants.d.ts +0 -107
  2. package/dist/constants.js +0 -148
  3. package/dist/dataStore.d.ts +12 -0
  4. package/dist/dataStore.js +35 -0
  5. package/dist/index.d.ts +6 -3
  6. package/dist/index.js +5 -3
  7. package/dist/middleware.d.ts +3 -0
  8. package/dist/middleware.js +3 -0
  9. package/dist/react/accent-context.d.ts +6 -0
  10. package/dist/react/accent-context.js +10 -0
  11. package/dist/react/catalog-renderer.d.ts +5 -0
  12. package/dist/react/catalog-renderer.js +37 -0
  13. package/dist/react/components/action-button.d.ts +6 -0
  14. package/dist/react/components/action-button.js +22 -0
  15. package/dist/react/components/badge.d.ts +5 -0
  16. package/dist/react/components/badge.js +18 -0
  17. package/dist/react/components/icon.d.ts +7 -0
  18. package/dist/react/components/icon.js +60 -0
  19. package/dist/react/components/image.d.ts +5 -0
  20. package/dist/react/components/image.js +15 -0
  21. package/dist/react/components/input.d.ts +5 -0
  22. package/dist/react/components/input.js +18 -0
  23. package/dist/react/components/item-group.d.ts +7 -0
  24. package/dist/react/components/item-group.js +17 -0
  25. package/dist/react/components/item.d.ts +7 -0
  26. package/dist/react/components/item.js +9 -0
  27. package/dist/react/components/progress.d.ts +5 -0
  28. package/dist/react/components/progress.js +11 -0
  29. package/dist/react/components/separator.d.ts +5 -0
  30. package/dist/react/components/separator.js +7 -0
  31. package/dist/react/components/slider.d.ts +5 -0
  32. package/dist/react/components/slider.js +21 -0
  33. package/dist/react/components/stack.d.ts +7 -0
  34. package/dist/react/components/stack.js +32 -0
  35. package/dist/react/components/switch.d.ts +5 -0
  36. package/dist/react/components/switch.js +23 -0
  37. package/dist/react/components/text.d.ts +5 -0
  38. package/dist/react/components/text.js +25 -0
  39. package/dist/react/components/toggle-group.d.ts +5 -0
  40. package/dist/react/components/toggle-group.js +52 -0
  41. package/dist/react/hooks/use-snap-accent.d.ts +13 -0
  42. package/dist/react/hooks/use-snap-accent.js +32 -0
  43. package/dist/react/index.d.ts +47 -0
  44. package/dist/react/index.js +191 -0
  45. package/dist/react/lib/preview-primary-css.d.ts +6 -0
  46. package/dist/react/lib/preview-primary-css.js +43 -0
  47. package/dist/react/lib/resolve-palette-hex.d.ts +2 -0
  48. package/dist/react/lib/resolve-palette-hex.js +10 -0
  49. package/dist/schemas.d.ts +14 -1629
  50. package/dist/schemas.js +14 -526
  51. package/dist/ui/badge.d.ts +52 -0
  52. package/dist/ui/badge.js +9 -0
  53. package/dist/ui/button.d.ts +42 -28
  54. package/dist/ui/button.js +7 -9
  55. package/dist/ui/catalog.d.ts +280 -155
  56. package/dist/ui/catalog.js +102 -83
  57. package/dist/ui/icon.d.ts +56 -0
  58. package/dist/ui/icon.js +51 -0
  59. package/dist/ui/image.d.ts +1 -0
  60. package/dist/ui/image.js +2 -2
  61. package/dist/ui/index.d.ts +20 -22
  62. package/dist/ui/index.js +10 -11
  63. package/dist/ui/input.d.ts +17 -0
  64. package/dist/ui/input.js +13 -0
  65. package/dist/ui/item-group.d.ts +12 -0
  66. package/dist/ui/item-group.js +7 -0
  67. package/dist/ui/item.d.ts +14 -0
  68. package/dist/ui/item.js +9 -0
  69. package/dist/ui/progress.d.ts +1 -11
  70. package/dist/ui/progress.js +21 -4
  71. package/dist/ui/schema.js +3 -3
  72. package/dist/ui/separator.d.ts +9 -0
  73. package/dist/ui/separator.js +5 -0
  74. package/dist/ui/slider.d.ts +4 -3
  75. package/dist/ui/slider.js +34 -5
  76. package/dist/ui/stack.d.ts +22 -1
  77. package/dist/ui/stack.js +8 -1
  78. package/dist/ui/switch.d.ts +8 -0
  79. package/dist/ui/switch.js +7 -0
  80. package/dist/ui/text.d.ts +15 -7
  81. package/dist/ui/text.js +8 -4
  82. package/dist/ui/toggle-group.d.ts +23 -0
  83. package/dist/ui/toggle-group.js +19 -0
  84. package/dist/validator.d.ts +5 -1
  85. package/dist/validator.js +6 -136
  86. package/package.json +72 -52
  87. package/src/constants.ts +0 -179
  88. package/src/dataStore.ts +62 -0
  89. package/src/index.ts +11 -20
  90. package/src/middleware.ts +7 -0
  91. package/src/react/accent-context.tsx +29 -0
  92. package/src/react/catalog-renderer.tsx +39 -0
  93. package/src/react/components/action-button.tsx +48 -0
  94. package/src/react/components/badge.tsx +37 -0
  95. package/src/react/components/icon.tsx +115 -0
  96. package/src/react/components/image.tsx +33 -0
  97. package/src/react/components/input.tsx +36 -0
  98. package/src/react/components/item-group.tsx +43 -0
  99. package/src/react/components/item.tsx +33 -0
  100. package/src/react/components/progress.tsx +29 -0
  101. package/src/react/components/separator.tsx +14 -0
  102. package/src/react/components/slider.tsx +43 -0
  103. package/src/react/components/stack.tsx +55 -0
  104. package/src/react/components/switch.tsx +46 -0
  105. package/src/react/components/text.tsx +43 -0
  106. package/src/react/components/toggle-group.tsx +85 -0
  107. package/src/react/hooks/use-snap-accent.ts +45 -0
  108. package/src/react/index.tsx +321 -0
  109. package/src/react/lib/preview-primary-css.ts +57 -0
  110. package/src/react/lib/resolve-palette-hex.ts +20 -0
  111. package/src/schemas.ts +18 -644
  112. package/src/ui/badge.ts +13 -0
  113. package/src/ui/button.ts +9 -12
  114. package/src/ui/catalog.ts +106 -86
  115. package/src/ui/icon.ts +56 -0
  116. package/src/ui/image.ts +3 -2
  117. package/src/ui/index.ts +26 -29
  118. package/src/ui/input.ts +17 -0
  119. package/src/ui/item-group.ts +11 -0
  120. package/src/ui/item.ts +13 -0
  121. package/src/ui/progress.ts +25 -7
  122. package/src/ui/schema.ts +3 -3
  123. package/src/ui/separator.ts +9 -0
  124. package/src/ui/slider.ts +40 -10
  125. package/src/ui/stack.ts +9 -1
  126. package/src/ui/switch.ts +11 -0
  127. package/src/ui/text.ts +9 -4
  128. package/src/ui/toggle-group.ts +23 -0
  129. package/src/validator.ts +6 -176
  130. package/dist/ui/bar-chart.d.ts +0 -30
  131. package/dist/ui/bar-chart.js +0 -15
  132. package/dist/ui/button-group.d.ts +0 -19
  133. package/dist/ui/button-group.js +0 -18
  134. package/dist/ui/divider.d.ts +0 -3
  135. package/dist/ui/divider.js +0 -2
  136. package/dist/ui/grid.d.ts +0 -22
  137. package/dist/ui/grid.js +0 -16
  138. package/dist/ui/group.d.ts +0 -7
  139. package/dist/ui/group.js +0 -5
  140. package/dist/ui/list.d.ts +0 -13
  141. package/dist/ui/list.js +0 -13
  142. package/dist/ui/spacer.d.ts +0 -9
  143. package/dist/ui/spacer.js +0 -5
  144. package/dist/ui/text-input.d.ts +0 -7
  145. package/dist/ui/text-input.js +0 -12
  146. package/dist/ui/toggle.d.ts +0 -7
  147. package/dist/ui/toggle.js +0 -6
  148. package/src/ui/bar-chart.ts +0 -20
  149. package/src/ui/button-group.ts +0 -26
  150. package/src/ui/divider.ts +0 -5
  151. package/src/ui/grid.ts +0 -25
  152. package/src/ui/group.ts +0 -8
  153. package/src/ui/list.ts +0 -17
  154. package/src/ui/spacer.ts +0 -8
  155. package/src/ui/text-input.ts +0 -15
  156. package/src/ui/toggle.ts +0 -9
@@ -1,117 +1,136 @@
1
1
  import { defineCatalog } from "@json-render/core";
2
2
  import { z } from "zod";
3
- import { BUTTON_STYLE_VALUES } from "../constants.js";
4
3
  import { snapJsonRenderSchema } from "./schema.js";
5
- import { textProps } from "./text.js";
4
+ import { badgeProps } from "./badge.js";
5
+ import { buttonProps } from "./button.js";
6
+ import { switchProps } from "./switch.js";
7
+ import { toggleGroupProps } from "./toggle-group.js";
8
+ import { iconProps } from "./icon.js";
9
+ import { inputProps } from "./input.js";
10
+ import { itemProps } from "./item.js";
11
+ import { itemGroupProps } from "./item-group.js";
6
12
  import { imageProps } from "./image.js";
7
- import { dividerProps } from "./divider.js";
8
- import { spacerProps } from "./spacer.js";
9
13
  import { progressProps } from "./progress.js";
10
- import { listProps } from "./list.js";
11
- import { gridProps } from "./grid.js";
12
- import { textInputProps } from "./text-input.js";
14
+ import { separatorProps } from "./separator.js";
13
15
  import { sliderProps } from "./slider.js";
14
- import { buttonGroupProps } from "./button-group.js";
15
- import { toggleProps } from "./toggle.js";
16
- import { barChartProps } from "./bar-chart.js";
17
- import { groupProps } from "./group.js";
18
16
  import { stackProps } from "./stack.js";
19
- import { actionButtonProps } from "./button.js";
20
- const snapPostParams = z.object({
21
- button_index: z.number().int().nonnegative(),
22
- target: z.string(),
23
- label: z.string().optional(),
24
- style: z.enum(BUTTON_STYLE_VALUES).optional(),
25
- });
26
- const snapTargetParams = z.object({
27
- target: z.string(),
28
- });
17
+ import { textProps } from "./text.js";
29
18
  const snapClientParams = z.object({
30
19
  client_action: z.record(z.string(), z.unknown()),
31
20
  });
32
21
  /**
33
- * Basic catalog: one json-render component per snap element type, plus ActionButton for snap buttons.
34
- * Does not validate cross-field rules (media count, height budget); snap JSON still goes through `@farcaster/snap` validation.
22
+ * json-render catalog for snap elements.
23
+ *
24
+ * Component keys match the snap wire-format `type` strings.
25
+ * Action names are used directly in `on.press` bindings.
35
26
  */
36
27
  export const snapJsonRenderCatalog = defineCatalog(snapJsonRenderSchema, {
37
28
  components: {
38
- Text: {
39
- props: textProps,
40
- description: "Snap text block style: title | body | caption | label; optional align.",
29
+ badge: {
30
+ props: badgeProps,
31
+ description: "Inline labelvariant: default | secondary | destructive | outline.",
41
32
  },
42
- Image: {
43
- props: imageProps,
44
- description: "HTTPS image with fixed aspect ratio.",
45
- },
46
- Divider: {
47
- props: dividerProps,
48
- description: "Horizontal rule between blocks.",
33
+ button: {
34
+ props: buttonProps,
35
+ description: "Action button — use with on.press to bind snap or client actions.",
49
36
  },
50
- Spacer: {
51
- props: spacerProps,
52
- description: "Vertical whitespace size small | medium | large.",
37
+ switch: {
38
+ props: switchProps,
39
+ description: "Boolean toggle; `name` becomes POST inputs key. Optional label.",
53
40
  },
54
- Progress: {
55
- props: progressProps,
56
- description: "Horizontal progress bar (value/max, optional label and color).",
41
+ toggle_group: {
42
+ props: toggleGroupProps,
43
+ description: "Single or multi-select choice group; `name` becomes POST inputs key. mode: single (default) | multiple. Optional label.",
57
44
  },
58
- List: {
59
- props: listProps,
60
- description: "Ordered / unordered / plain list; max 4 items per snap spec.",
45
+ input: {
46
+ props: inputProps,
47
+ description: "Text input; `name` becomes POST inputs key. Optional label and placeholder.",
61
48
  },
62
- Grid: {
63
- props: gridProps,
64
- description: "Rows×cols cell grid; optional interactive empty cells for games.",
49
+ item: {
50
+ props: itemProps,
51
+ description: "Content row with title and optional description. Children render in the actions slot (right side) — use badge, button, or text elements.",
65
52
  },
66
- TextInput: {
67
- props: textInputProps,
68
- description: "Single-line input; `name` becomes POST inputs key.",
53
+ item_group: {
54
+ props: itemGroupProps,
55
+ description: "Groups item children into a styled list. Optional border around the group and separator lines between items.",
69
56
  },
70
- Slider: {
71
- props: sliderProps,
72
- description: "Numeric slider; `name` becomes POST inputs key.",
57
+ icon: {
58
+ props: iconProps,
59
+ description: "Inline icon from the curated set. Optional color (palette) and size (sm | md).",
73
60
  },
74
- ButtonGroup: {
75
- props: buttonGroupProps,
76
- description: "Exclusive choice; `name` and selected option go into POST inputs.",
61
+ image: {
62
+ props: imageProps,
63
+ description: "HTTPS image with fixed aspect ratio.",
77
64
  },
78
- Toggle: {
79
- props: toggleProps,
80
- description: "Boolean toggle; `name` becomes POST inputs key.",
65
+ progress: {
66
+ props: progressProps,
67
+ description: "Horizontal progress bar (value/max, optional label and color).",
81
68
  },
82
- BarChart: {
83
- props: barChartProps,
84
- description: "Vertical bar chart for labeled values poll results, rankings, breakdowns.",
69
+ separator: {
70
+ props: separatorProps,
71
+ description: "Visual divider orientation: horizontal (default) | vertical.",
85
72
  },
86
- Group: {
87
- props: groupProps,
88
- description: "Button row (`layout: row`) or 2-column grid (`layout: grid`); use `children` element ids only (no nested JSON objects).",
73
+ slider: {
74
+ props: sliderProps,
75
+ description: "Numeric slider; `name` becomes POST inputs key. Optional label.",
89
76
  },
90
- Stack: {
77
+ stack: {
91
78
  props: stackProps,
92
- description: "Vertical stack for snap page body; maps from snap `page.elements` (`type: stack`). Children are element ids in order top to bottom.",
79
+ description: "Layout container direction: vertical (default) | horizontal. Children are element ids in order.",
93
80
  },
94
- ActionButton: {
95
- props: actionButtonProps,
96
- description: "Snap action button: post (next page), link (browser), mini_app, client target is HTTPS URL or client_action object.",
81
+ text: {
82
+ props: textProps,
83
+ description: "Text block — size: lg (heading), md (body, default), sm (caption). Optional weight and align.",
97
84
  },
98
85
  },
99
86
  actions: {
100
- snap_post: {
101
- description: "POST to snap `target` with signed body (fid, inputs, button_index, timestamp, signature); response is next snap page JSON.",
102
- params: snapPostParams,
103
- },
104
- snap_link: {
105
- description: "Open `target` in the system browser; no server round-trip.",
106
- params: snapTargetParams,
107
- },
108
- snap_mini_app: {
109
- description: "Open `target` as an in-app Farcaster mini app.",
110
- params: snapTargetParams,
111
- },
112
- snap_client: {
113
- description: "Trigger a Farcaster client action (view_cast, view_profile, compose_cast, …).",
114
- params: snapClientParams,
87
+ submit: {
88
+ description: "POST to snap server with signed body (fid, inputs, timestamp, signature); response is next snap page.",
89
+ params: z.object({ target: z.string() }),
90
+ },
91
+ open_url: {
92
+ description: "Open target URL in the system browser.",
93
+ params: z.object({ target: z.string() }),
94
+ },
95
+ open_mini_app: {
96
+ description: "Open target URL as a Farcaster mini app.",
97
+ params: z.object({ target: z.string() }),
98
+ },
99
+ view_cast: {
100
+ description: "Navigate to a cast by hash.",
101
+ params: z.object({ hash: z.string() }),
102
+ },
103
+ view_profile: {
104
+ description: "Navigate to a user profile by FID.",
105
+ params: z.object({ fid: z.number() }),
106
+ },
107
+ compose_cast: {
108
+ description: "Open the cast composer with optional pre-filled content.",
109
+ params: z.object({
110
+ text: z.string().optional(),
111
+ channelKey: z.string().optional(),
112
+ embeds: z.array(z.string()).optional(),
113
+ }),
114
+ },
115
+ view_token: {
116
+ description: "View a token in the wallet. Token is a CAIP-19 identifier.",
117
+ params: z.object({ token: z.string() }),
118
+ },
119
+ send_token: {
120
+ description: "Open send flow for a token. Token is CAIP-19.",
121
+ params: z.object({
122
+ token: z.string(),
123
+ amount: z.string().optional(),
124
+ recipientFid: z.number().optional(),
125
+ recipientAddress: z.string().optional(),
126
+ }),
127
+ },
128
+ swap_token: {
129
+ description: "Open swap flow between two tokens. Tokens are CAIP-19.",
130
+ params: z.object({
131
+ sellToken: z.string().optional(),
132
+ buyToken: z.string().optional(),
133
+ }),
115
134
  },
116
135
  },
117
136
  });
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ export declare const ICON_NAMES: readonly ["arrow-right", "arrow-left", "external-link", "chevron-right", "check", "x", "alert-triangle", "info", "clock", "heart", "message-circle", "repeat", "share", "user", "users", "star", "trophy", "zap", "flame", "gift", "image", "play", "pause", "wallet", "coins", "plus", "minus", "refresh-cw", "bookmark", "thumbs-up", "thumbs-down", "trending-up", "trending-down"];
3
+ export declare const ICON_SIZES: readonly ["sm", "md"];
4
+ export declare const iconProps: z.ZodObject<{
5
+ name: z.ZodEnum<{
6
+ check: "check";
7
+ repeat: "repeat";
8
+ "arrow-right": "arrow-right";
9
+ "arrow-left": "arrow-left";
10
+ "external-link": "external-link";
11
+ "chevron-right": "chevron-right";
12
+ x: "x";
13
+ "alert-triangle": "alert-triangle";
14
+ info: "info";
15
+ clock: "clock";
16
+ heart: "heart";
17
+ "message-circle": "message-circle";
18
+ share: "share";
19
+ user: "user";
20
+ users: "users";
21
+ star: "star";
22
+ trophy: "trophy";
23
+ zap: "zap";
24
+ flame: "flame";
25
+ gift: "gift";
26
+ image: "image";
27
+ play: "play";
28
+ pause: "pause";
29
+ wallet: "wallet";
30
+ coins: "coins";
31
+ plus: "plus";
32
+ minus: "minus";
33
+ "refresh-cw": "refresh-cw";
34
+ bookmark: "bookmark";
35
+ "thumbs-up": "thumbs-up";
36
+ "thumbs-down": "thumbs-down";
37
+ "trending-up": "trending-up";
38
+ "trending-down": "trending-down";
39
+ }>;
40
+ color: z.ZodOptional<z.ZodEnum<{
41
+ gray: "gray";
42
+ blue: "blue";
43
+ red: "red";
44
+ amber: "amber";
45
+ green: "green";
46
+ teal: "teal";
47
+ purple: "purple";
48
+ pink: "pink";
49
+ accent: "accent";
50
+ }>>;
51
+ size: z.ZodOptional<z.ZodEnum<{
52
+ sm: "sm";
53
+ md: "md";
54
+ }>>;
55
+ }, z.core.$strip>;
56
+ export type IconProps = z.infer<typeof iconProps>;
@@ -0,0 +1,51 @@
1
+ import { z } from "zod";
2
+ import { PROGRESS_COLOR_VALUES } from "../colors.js";
3
+ export const ICON_NAMES = [
4
+ // Navigation/Actions
5
+ "arrow-right",
6
+ "arrow-left",
7
+ "external-link",
8
+ "chevron-right",
9
+ // Status
10
+ "check",
11
+ "x",
12
+ "alert-triangle",
13
+ "info",
14
+ "clock",
15
+ // Social
16
+ "heart",
17
+ "message-circle",
18
+ "repeat",
19
+ "share",
20
+ "user",
21
+ "users",
22
+ // Content
23
+ "star",
24
+ "trophy",
25
+ "zap",
26
+ "flame",
27
+ "gift",
28
+ // Media
29
+ "image",
30
+ "play",
31
+ "pause",
32
+ // Commerce
33
+ "wallet",
34
+ "coins",
35
+ // Common actions
36
+ "plus",
37
+ "minus",
38
+ "refresh-cw",
39
+ "bookmark",
40
+ // Feedback/data
41
+ "thumbs-up",
42
+ "thumbs-down",
43
+ "trending-up",
44
+ "trending-down",
45
+ ];
46
+ export const ICON_SIZES = ["sm", "md"];
47
+ export const iconProps = z.object({
48
+ name: z.enum(ICON_NAMES),
49
+ color: z.enum(PROGRESS_COLOR_VALUES).optional(),
50
+ size: z.enum(ICON_SIZES).optional(),
51
+ });
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ export declare const IMAGE_ASPECTS: readonly ["1:1", "16:9", "4:3", "3:4", "9:16"];
2
3
  export declare const imageProps: z.ZodObject<{
3
4
  url: z.ZodString;
4
5
  aspect: z.ZodEnum<{
package/dist/ui/image.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
- import { IMAGE_ASPECT_VALUES } from "../constants.js";
2
+ export const IMAGE_ASPECTS = ["1:1", "16:9", "4:3", "3:4", "9:16"];
3
3
  export const imageProps = z.object({
4
4
  url: z.string(),
5
- aspect: z.enum(IMAGE_ASPECT_VALUES),
5
+ aspect: z.enum(IMAGE_ASPECTS),
6
6
  alt: z.string().optional(),
7
7
  });
@@ -1,32 +1,30 @@
1
1
  export { snapJsonRenderSchema } from "./schema.js";
2
2
  export { snapJsonRenderCatalog } from "./catalog.js";
3
- export { textProps } from "./text.js";
4
- export type { TextProps } from "./text.js";
3
+ export { badgeProps } from "./badge.js";
4
+ export type { BadgeProps } from "./badge.js";
5
+ export { buttonProps } from "./button.js";
6
+ export type { ButtonProps } from "./button.js";
7
+ export { switchProps } from "./switch.js";
8
+ export type { SwitchProps } from "./switch.js";
9
+ export { toggleGroupProps } from "./toggle-group.js";
10
+ export type { ToggleGroupProps } from "./toggle-group.js";
11
+ export { inputProps } from "./input.js";
12
+ export type { InputProps } from "./input.js";
13
+ export { itemProps } from "./item.js";
14
+ export type { ItemProps } from "./item.js";
15
+ export { itemGroupProps } from "./item-group.js";
16
+ export type { ItemGroupProps } from "./item-group.js";
17
+ export { iconProps, ICON_NAMES } from "./icon.js";
18
+ export type { IconProps } from "./icon.js";
5
19
  export { imageProps } from "./image.js";
6
20
  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
21
  export { progressProps } from "./progress.js";
12
22
  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";
23
+ export { separatorProps } from "./separator.js";
24
+ export type { SeparatorProps } from "./separator.js";
19
25
  export { sliderProps } from "./slider.js";
20
26
  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
27
  export { stackProps } from "./stack.js";
30
28
  export type { StackProps } from "./stack.js";
31
- export { actionButtonProps, buttonProps } from "./button.js";
32
- export type { ActionButtonProps, ButtonProps } from "./button.js";
29
+ export { textProps } from "./text.js";
30
+ export type { TextProps } from "./text.js";
package/dist/ui/index.js CHANGED
@@ -1,17 +1,16 @@
1
1
  export { snapJsonRenderSchema } from "./schema.js";
2
2
  export { snapJsonRenderCatalog } from "./catalog.js";
3
- export { textProps } from "./text.js";
3
+ export { badgeProps } from "./badge.js";
4
+ export { buttonProps } from "./button.js";
5
+ export { switchProps } from "./switch.js";
6
+ export { toggleGroupProps } from "./toggle-group.js";
7
+ export { inputProps } from "./input.js";
8
+ export { itemProps } from "./item.js";
9
+ export { itemGroupProps } from "./item-group.js";
10
+ export { iconProps, ICON_NAMES } from "./icon.js";
4
11
  export { imageProps } from "./image.js";
5
- export { dividerProps } from "./divider.js";
6
- export { spacerProps } from "./spacer.js";
7
12
  export { progressProps } from "./progress.js";
8
- export { listProps } from "./list.js";
9
- export { gridProps } from "./grid.js";
10
- export { textInputProps } from "./text-input.js";
13
+ export { separatorProps } from "./separator.js";
11
14
  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
15
  export { stackProps } from "./stack.js";
17
- export { actionButtonProps, buttonProps } from "./button.js";
16
+ export { textProps } from "./text.js";
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ export declare const INPUT_TYPES: readonly ["text", "number"];
3
+ export declare const INPUT_MAX_CHARS = 280;
4
+ export declare const INPUT_MAX_LABEL_CHARS = 60;
5
+ export declare const INPUT_MAX_PLACEHOLDER_CHARS = 60;
6
+ export declare const inputProps: z.ZodObject<{
7
+ name: z.ZodString;
8
+ type: z.ZodOptional<z.ZodEnum<{
9
+ number: "number";
10
+ text: "text";
11
+ }>>;
12
+ label: z.ZodOptional<z.ZodString>;
13
+ placeholder: z.ZodOptional<z.ZodString>;
14
+ defaultValue: z.ZodOptional<z.ZodString>;
15
+ maxLength: z.ZodOptional<z.ZodNumber>;
16
+ }, z.core.$strip>;
17
+ export type InputProps = z.infer<typeof inputProps>;
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ export const INPUT_TYPES = ["text", "number"];
3
+ export const INPUT_MAX_CHARS = 280;
4
+ export const INPUT_MAX_LABEL_CHARS = 60;
5
+ export const INPUT_MAX_PLACEHOLDER_CHARS = 60;
6
+ export const inputProps = z.object({
7
+ name: z.string().min(1),
8
+ type: z.enum(INPUT_TYPES).optional(),
9
+ label: z.string().max(INPUT_MAX_LABEL_CHARS).optional(),
10
+ placeholder: z.string().max(INPUT_MAX_PLACEHOLDER_CHARS).optional(),
11
+ defaultValue: z.string().optional(),
12
+ maxLength: z.number().int().min(1).max(INPUT_MAX_CHARS).optional(),
13
+ });
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+ export declare const itemGroupProps: z.ZodObject<{
3
+ border: z.ZodOptional<z.ZodBoolean>;
4
+ separator: z.ZodOptional<z.ZodBoolean>;
5
+ gap: z.ZodOptional<z.ZodEnum<{
6
+ sm: "sm";
7
+ md: "md";
8
+ none: "none";
9
+ lg: "lg";
10
+ }>>;
11
+ }, z.core.$strip>;
12
+ export type ItemGroupProps = z.infer<typeof itemGroupProps>;
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+ import { STACK_GAPS } from "./stack.js";
3
+ export const itemGroupProps = z.object({
4
+ border: z.boolean().optional(),
5
+ separator: z.boolean().optional(),
6
+ gap: z.enum(STACK_GAPS).optional(),
7
+ });
@@ -0,0 +1,14 @@
1
+ import { z } from "zod";
2
+ export declare const ITEM_VARIANTS: readonly ["default", "outline", "muted"];
3
+ export declare const ITEM_MAX_TITLE_CHARS = 100;
4
+ export declare const ITEM_MAX_DESCRIPTION_CHARS = 160;
5
+ export declare const itemProps: z.ZodObject<{
6
+ title: z.ZodString;
7
+ description: z.ZodOptional<z.ZodString>;
8
+ variant: z.ZodOptional<z.ZodEnum<{
9
+ default: "default";
10
+ outline: "outline";
11
+ muted: "muted";
12
+ }>>;
13
+ }, z.core.$strip>;
14
+ export type ItemProps = z.infer<typeof itemProps>;
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ export const ITEM_VARIANTS = ["default", "outline", "muted"];
3
+ export const ITEM_MAX_TITLE_CHARS = 100;
4
+ export const ITEM_MAX_DESCRIPTION_CHARS = 160;
5
+ export const itemProps = z.object({
6
+ title: z.string().min(1).max(ITEM_MAX_TITLE_CHARS),
7
+ description: z.string().max(ITEM_MAX_DESCRIPTION_CHARS).optional(),
8
+ variant: z.enum(ITEM_VARIANTS).optional(),
9
+ });
@@ -1,18 +1,8 @@
1
1
  import { z } from "zod";
2
+ export declare const PROGRESS_MAX_LABEL_CHARS = 60;
2
3
  export declare const progressProps: z.ZodObject<{
3
4
  value: z.ZodNumber;
4
5
  max: z.ZodNumber;
5
6
  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
7
  }, z.core.$strip>;
18
8
  export type ProgressProps = z.infer<typeof progressProps>;
@@ -1,8 +1,25 @@
1
1
  import { z } from "zod";
2
- import { PROGRESS_COLOR_VALUES } from "../colors.js";
3
- export const progressProps = z.object({
2
+ export const PROGRESS_MAX_LABEL_CHARS = 60;
3
+ export const progressProps = z
4
+ .object({
4
5
  value: z.number(),
5
6
  max: z.number(),
6
- label: z.string().optional(),
7
- color: z.enum(PROGRESS_COLOR_VALUES).optional(),
7
+ label: z.string().max(PROGRESS_MAX_LABEL_CHARS).optional(),
8
+ })
9
+ .superRefine((val, ctx) => {
10
+ if (!Number.isFinite(val.max) || val.max <= 0) {
11
+ ctx.addIssue({
12
+ code: "custom",
13
+ message: `progress max must be a finite number > 0 (got ${val.max})`,
14
+ path: ["max"],
15
+ });
16
+ return;
17
+ }
18
+ if (!Number.isFinite(val.value) || val.value < 0 || val.value > val.max) {
19
+ ctx.addIssue({
20
+ code: "custom",
21
+ message: `progress value (${val.value}) must be between 0 and max (${val.max})`,
22
+ path: ["value"],
23
+ });
24
+ }
8
25
  });
package/dist/ui/schema.js CHANGED
@@ -24,8 +24,8 @@ export const snapJsonRenderSchema = defineSchema((s) => ({
24
24
  }),
25
25
  }), {
26
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 / client.",
27
+ "You are generating auxiliary UI for a Farcaster Snap. Prefer components matching snap element types (Item, Badge, ButtonGroup, Input, Switch, ToggleGroup, Slider, Progress, Image, Separator).",
28
+ "Snap pages use a Stack root with at most 6 body children and 1 media element (Image); keep generated trees small.",
29
+ "Bottom-of-card snap buttons are Button components; use actions post / link / mini_app / sdk per SPEC.md.",
30
30
  ],
31
31
  });
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ export declare const SEPARATOR_ORIENTATIONS: readonly ["horizontal", "vertical"];
3
+ export declare const separatorProps: z.ZodObject<{
4
+ orientation: z.ZodOptional<z.ZodEnum<{
5
+ horizontal: "horizontal";
6
+ vertical: "vertical";
7
+ }>>;
8
+ }, z.core.$strip>;
9
+ export type SeparatorProps = z.infer<typeof separatorProps>;
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ export const SEPARATOR_ORIENTATIONS = ["horizontal", "vertical"];
3
+ export const separatorProps = z.object({
4
+ orientation: z.enum(SEPARATOR_ORIENTATIONS).optional(),
5
+ });
@@ -1,12 +1,13 @@
1
1
  import { z } from "zod";
2
+ export declare const SLIDER_MAX_LABEL_CHARS = 60;
3
+ export declare const SLIDER_DEFAULT_STEP = 1;
4
+ export declare const SLIDER_STEP_ALIGN_EPS = 0.000001;
2
5
  export declare const sliderProps: z.ZodObject<{
3
6
  name: z.ZodString;
4
7
  min: z.ZodNumber;
5
8
  max: z.ZodNumber;
6
9
  step: z.ZodOptional<z.ZodNumber>;
7
- value: z.ZodOptional<z.ZodNumber>;
10
+ defaultValue: z.ZodOptional<z.ZodNumber>;
8
11
  label: z.ZodOptional<z.ZodString>;
9
- minLabel: z.ZodOptional<z.ZodString>;
10
- maxLabel: z.ZodOptional<z.ZodString>;
11
12
  }, z.core.$strip>;
12
13
  export type SliderProps = z.infer<typeof sliderProps>;