@farcaster/snap 1.6.0 → 1.7.1

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 (65) hide show
  1. package/dist/dataStore.d.ts +1 -4
  2. package/dist/dataStore.js +4 -17
  3. package/dist/index.d.ts +1 -1
  4. package/dist/react-native/catalog-renderer.d.ts +5 -0
  5. package/dist/react-native/catalog-renderer.js +36 -0
  6. package/dist/react-native/components/snap-action-button.d.ts +2 -0
  7. package/dist/react-native/components/snap-action-button.js +68 -0
  8. package/dist/react-native/components/snap-badge.d.ts +2 -0
  9. package/dist/react-native/components/snap-badge.js +38 -0
  10. package/dist/react-native/components/snap-icon.d.ts +5 -0
  11. package/dist/react-native/components/snap-icon.js +56 -0
  12. package/dist/react-native/components/snap-image.d.ts +2 -0
  13. package/dist/react-native/components/snap-image.js +24 -0
  14. package/dist/react-native/components/snap-input.d.ts +2 -0
  15. package/dist/react-native/components/snap-input.js +36 -0
  16. package/dist/react-native/components/snap-item-group.d.ts +5 -0
  17. package/dist/react-native/components/snap-item-group.js +23 -0
  18. package/dist/react-native/components/snap-item.d.ts +5 -0
  19. package/dist/react-native/components/snap-item.js +45 -0
  20. package/dist/react-native/components/snap-progress.d.ts +2 -0
  21. package/dist/react-native/components/snap-progress.js +26 -0
  22. package/dist/react-native/components/snap-separator.d.ts +2 -0
  23. package/dist/react-native/components/snap-separator.js +23 -0
  24. package/dist/react-native/components/snap-slider.d.ts +2 -0
  25. package/dist/react-native/components/snap-slider.js +42 -0
  26. package/dist/react-native/components/snap-stack.d.ts +5 -0
  27. package/dist/react-native/components/snap-stack.js +49 -0
  28. package/dist/react-native/components/snap-switch.d.ts +2 -0
  29. package/dist/react-native/components/snap-switch.js +30 -0
  30. package/dist/react-native/components/snap-text.d.ts +2 -0
  31. package/dist/react-native/components/snap-text.js +37 -0
  32. package/dist/react-native/components/snap-toggle-group.d.ts +2 -0
  33. package/dist/react-native/components/snap-toggle-group.js +100 -0
  34. package/dist/react-native/index.d.ts +52 -0
  35. package/dist/react-native/index.js +155 -0
  36. package/dist/react-native/theme.d.ts +21 -0
  37. package/dist/react-native/theme.js +37 -0
  38. package/dist/react-native/use-snap-palette.d.ts +13 -0
  39. package/dist/react-native/use-snap-palette.js +48 -0
  40. package/dist/ui/badge.d.ts +2 -2
  41. package/dist/ui/button.d.ts +2 -2
  42. package/dist/ui/catalog.d.ts +7 -7
  43. package/dist/ui/icon.d.ts +2 -2
  44. package/dist/ui/schema.d.ts +1 -1
  45. package/package.json +7 -2
  46. package/src/dataStore.ts +5 -29
  47. package/src/index.ts +0 -1
  48. package/src/react-native/catalog-renderer.tsx +37 -0
  49. package/src/react-native/components/snap-action-button.tsx +92 -0
  50. package/src/react-native/components/snap-badge.tsx +57 -0
  51. package/src/react-native/components/snap-icon.tsx +102 -0
  52. package/src/react-native/components/snap-image.tsx +38 -0
  53. package/src/react-native/components/snap-input.tsx +57 -0
  54. package/src/react-native/components/snap-item-group.tsx +43 -0
  55. package/src/react-native/components/snap-item.tsx +70 -0
  56. package/src/react-native/components/snap-progress.tsx +40 -0
  57. package/src/react-native/components/snap-separator.tsx +32 -0
  58. package/src/react-native/components/snap-slider.tsx +82 -0
  59. package/src/react-native/components/snap-stack.tsx +66 -0
  60. package/src/react-native/components/snap-switch.tsx +45 -0
  61. package/src/react-native/components/snap-text.tsx +53 -0
  62. package/src/react-native/components/snap-toggle-group.tsx +128 -0
  63. package/src/react-native/index.tsx +267 -0
  64. package/src/react-native/theme.tsx +73 -0
  65. package/src/react-native/use-snap-palette.ts +64 -0
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { StyleSheet, Text, View } from "react-native";
3
+ import { useSnapTheme } from "../theme.js";
4
+ const SIZE_STYLES = {
5
+ lg: { fontSize: 20, fontWeight: "700" },
6
+ md: { fontSize: 16, lineHeight: 24 },
7
+ sm: { fontSize: 13 },
8
+ };
9
+ const WEIGHT_MAP = {
10
+ bold: "700",
11
+ medium: "500",
12
+ normal: "400",
13
+ };
14
+ export function SnapText({ element: { props }, }) {
15
+ const { colors } = useSnapTheme();
16
+ const content = String(props.content ?? "");
17
+ const size = String(props.size ?? "md");
18
+ const weight = props.weight ? String(props.weight) : undefined;
19
+ const align = props.align ?? undefined;
20
+ const sizeStyle = SIZE_STYLES[size] ?? SIZE_STYLES.md;
21
+ const resolvedWeight = weight ? WEIGHT_MAP[weight] : sizeStyle?.fontWeight;
22
+ const textAlign = align === "center" ? "center" : align === "right" ? "right" : "left";
23
+ return (_jsx(View, { style: styles.wrap, children: _jsx(Text, { style: [
24
+ styles.base,
25
+ {
26
+ color: colors.text,
27
+ fontSize: sizeStyle.fontSize,
28
+ lineHeight: sizeStyle.lineHeight,
29
+ fontWeight: resolvedWeight,
30
+ textAlign,
31
+ },
32
+ ], children: content }) }));
33
+ }
34
+ const styles = StyleSheet.create({
35
+ wrap: { flex: 1, width: "100%" },
36
+ base: {},
37
+ });
@@ -0,0 +1,2 @@
1
+ import type { ComponentRenderProps } from "@json-render/react-native";
2
+ export declare function SnapToggleGroup({ element: { props }, }: ComponentRenderProps<Record<string, unknown>>): import("react").JSX.Element;
@@ -0,0 +1,100 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useStateStore } from "@json-render/react-native";
3
+ import { Pressable, StyleSheet, Text, View } from "react-native";
4
+ import { useSnapPalette } from "../use-snap-palette.js";
5
+ import { useSnapTheme } from "../theme.js";
6
+ export function SnapToggleGroup({ element: { props }, }) {
7
+ const { get, set } = useStateStore();
8
+ const { accentHex } = useSnapPalette();
9
+ const { colors } = useSnapTheme();
10
+ const name = String(props.name ?? "toggle_group");
11
+ const path = `/inputs/${name}`;
12
+ const label = props.label ? String(props.label) : undefined;
13
+ const isMultiple = Boolean(props.multiple);
14
+ const orientation = String(props.orientation ?? "horizontal");
15
+ const options = Array.isArray(props.options)
16
+ ? props.options
17
+ : [];
18
+ const raw = get(path);
19
+ const defaultValue = props.defaultValue;
20
+ const selected = (() => {
21
+ if (raw !== undefined && raw !== null) {
22
+ return isMultiple
23
+ ? Array.isArray(raw)
24
+ ? raw
25
+ : []
26
+ : typeof raw === "string"
27
+ ? [raw]
28
+ : [];
29
+ }
30
+ if (defaultValue !== undefined) {
31
+ return Array.isArray(defaultValue)
32
+ ? defaultValue
33
+ : [String(defaultValue)];
34
+ }
35
+ return [];
36
+ })();
37
+ const isVertical = orientation === "vertical";
38
+ const handlePress = (opt) => {
39
+ if (isMultiple) {
40
+ const next = selected.includes(opt)
41
+ ? selected.filter((s) => s !== opt)
42
+ : [...selected, opt];
43
+ set(path, next);
44
+ }
45
+ else {
46
+ if (opt && opt !== selected[0])
47
+ set(path, opt);
48
+ }
49
+ };
50
+ return (_jsxs(View, { style: styles.wrap, children: [label ? _jsx(Text, { style: [styles.label, { color: colors.text }], children: label }) : null, _jsx(View, { style: [
51
+ styles.group,
52
+ { backgroundColor: colors.border + "33" },
53
+ isVertical ? styles.groupVertical : styles.groupHorizontal,
54
+ ], children: options.map((opt, index) => {
55
+ const isSelected = selected.includes(opt);
56
+ return (_jsx(Pressable, { style: ({ pressed }) => [
57
+ styles.option,
58
+ isSelected && { backgroundColor: accentHex },
59
+ pressed && styles.pressed,
60
+ !isVertical && styles.optionHorizontal,
61
+ ], onPress: () => handlePress(opt), children: _jsx(Text, { style: [
62
+ styles.optionText,
63
+ { color: colors.text },
64
+ isSelected && styles.optionTextSelected,
65
+ ], children: opt }) }, index));
66
+ }) })] }));
67
+ }
68
+ const styles = StyleSheet.create({
69
+ wrap: { width: "100%", gap: 6 },
70
+ label: { fontSize: 13, fontWeight: "500" },
71
+ group: {
72
+ padding: 4,
73
+ borderRadius: 8,
74
+ gap: 4,
75
+ },
76
+ groupHorizontal: {
77
+ flexDirection: "row",
78
+ },
79
+ groupVertical: {
80
+ flexDirection: "column",
81
+ },
82
+ option: {
83
+ paddingVertical: 8,
84
+ paddingHorizontal: 12,
85
+ borderRadius: 6,
86
+ alignItems: "center",
87
+ justifyContent: "center",
88
+ },
89
+ optionHorizontal: {
90
+ flex: 1,
91
+ },
92
+ pressed: { opacity: 0.88 },
93
+ optionText: {
94
+ fontSize: 13,
95
+ fontWeight: "500",
96
+ },
97
+ optionTextSelected: {
98
+ color: "#fff",
99
+ },
100
+ });
@@ -0,0 +1,52 @@
1
+ import type { Spec } from "@json-render/core";
2
+ import { useSnapTheme, type SnapNativeColors } from "./theme.js";
3
+ import { hexToRgba } from "./use-snap-palette.js";
4
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
5
+ [key: string]: JsonValue;
6
+ };
7
+ export type SnapPage = {
8
+ version: string;
9
+ theme?: {
10
+ accent?: string;
11
+ };
12
+ effects?: string[];
13
+ ui: Spec;
14
+ };
15
+ export type SnapActionHandlers = {
16
+ submit: (target: string, inputs: Record<string, JsonValue>) => void;
17
+ open_url: (target: string) => void;
18
+ open_mini_app: (target: string) => void;
19
+ view_cast: (params: {
20
+ hash: string;
21
+ }) => void;
22
+ view_profile: (params: {
23
+ fid: number;
24
+ }) => void;
25
+ compose_cast: (params: {
26
+ text?: string;
27
+ channelKey?: string;
28
+ embeds?: string[];
29
+ }) => void;
30
+ view_token: (params: {
31
+ token: string;
32
+ }) => void;
33
+ send_token: (params: {
34
+ token: string;
35
+ amount?: string;
36
+ recipientFid?: number;
37
+ recipientAddress?: string;
38
+ }) => void;
39
+ swap_token: (params: {
40
+ sellToken?: string;
41
+ buyToken?: string;
42
+ }) => void;
43
+ };
44
+ export { useSnapTheme, hexToRgba };
45
+ export type { SnapNativeColors };
46
+ export declare function SnapView({ snap, handlers, loading, appearance, colors, }: {
47
+ snap: SnapPage;
48
+ handlers: SnapActionHandlers;
49
+ loading?: boolean;
50
+ appearance?: "light" | "dark";
51
+ colors?: Partial<SnapNativeColors>;
52
+ }): import("react").JSX.Element;
@@ -0,0 +1,155 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { snapJsonRenderCatalog } from "@farcaster/snap/ui";
3
+ import { SnapCatalogView } from "./catalog-renderer.js";
4
+ import { SnapThemeProvider, useSnapTheme } from "./theme.js";
5
+ import { hexToRgba } from "./use-snap-palette.js";
6
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
+ import { ActivityIndicator, StyleSheet, View } from "react-native";
8
+ import { DEFAULT_THEME_ACCENT, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, } from "@farcaster/snap";
9
+ // ─── Re-exports ───────────────────────────────────────
10
+ export { useSnapTheme, hexToRgba };
11
+ // ─── Internal helpers ─────────────────────────────────
12
+ function applyStatePaths(model, changes) {
13
+ const entries = Array.isArray(changes)
14
+ ? changes.map((c) => [c.path, c.value])
15
+ : Object.entries(changes);
16
+ for (const [path, value] of entries) {
17
+ const trimmed = path.startsWith("/") ? path : `/${path}`;
18
+ const parts = trimmed.split("/").filter(Boolean);
19
+ if (parts.length < 2)
20
+ continue;
21
+ const [top, ...rest] = parts;
22
+ if (top === "inputs") {
23
+ if (typeof model.inputs !== "object" || model.inputs === null) {
24
+ model.inputs = {};
25
+ }
26
+ const inputs = model.inputs;
27
+ if (rest.length === 1) {
28
+ inputs[rest[0]] = value;
29
+ }
30
+ continue;
31
+ }
32
+ if (top === "theme") {
33
+ if (typeof model.theme !== "object" || model.theme === null) {
34
+ model.theme = {};
35
+ }
36
+ const theme = model.theme;
37
+ if (rest.length === 1) {
38
+ theme[rest[0]] = value;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ function resolveAccentHex(accent, appearance) {
44
+ const map = appearance === "dark" ? PALETTE_DARK_HEX : PALETTE_LIGHT_HEX;
45
+ const name = accent && Object.hasOwn(map, accent) ? accent : DEFAULT_THEME_ACCENT;
46
+ return map[name];
47
+ }
48
+ // ─── SnapView ─────────────────────────────────────────
49
+ function SnapViewInner({ snap, handlers, loading = false, }) {
50
+ const { mode } = useSnapTheme();
51
+ const spec = snap.ui;
52
+ const accentHex = resolveAccentHex(snap.theme?.accent, mode);
53
+ const initialState = useMemo(() => ({
54
+ ...(spec.state ?? {}),
55
+ inputs: { ...(spec.state?.inputs ?? {}) },
56
+ theme: {
57
+ ...(spec.state?.theme ?? {}),
58
+ ...(snap.theme ? { accent: snap.theme.accent } : {}),
59
+ },
60
+ }), [spec, snap.theme]);
61
+ const stateRef = useRef(initialState);
62
+ useEffect(() => {
63
+ stateRef.current = {
64
+ inputs: {
65
+ ...(initialState.inputs ?? {}),
66
+ },
67
+ theme: {
68
+ ...(initialState.theme ?? {}),
69
+ },
70
+ };
71
+ }, [initialState]);
72
+ useEffect(() => {
73
+ const result = snapJsonRenderCatalog.validate(spec);
74
+ if (!result.success) {
75
+ // eslint-disable-next-line no-console
76
+ console.warn("[SnapView] catalog validation issues:", result.error);
77
+ }
78
+ }, [spec]);
79
+ const [pageKey, setPageKey] = useState(0);
80
+ useEffect(() => {
81
+ setPageKey((k) => k + 1);
82
+ }, [spec]);
83
+ const handlersRef = useRef(handlers);
84
+ handlersRef.current = handlers;
85
+ const handleAction = useCallback((name, params) => {
86
+ const inputs = (stateRef.current.inputs ?? {});
87
+ const p = (params ?? {});
88
+ const h = handlersRef.current;
89
+ switch (name) {
90
+ case "submit":
91
+ h.submit(String(p.target ?? ""), inputs);
92
+ break;
93
+ case "open_url":
94
+ h.open_url(String(p.target ?? ""));
95
+ break;
96
+ case "open_mini_app":
97
+ h.open_mini_app(String(p.target ?? ""));
98
+ break;
99
+ case "view_cast":
100
+ h.view_cast({ hash: String(p.hash ?? "") });
101
+ break;
102
+ case "view_profile":
103
+ h.view_profile({ fid: Number(p.fid ?? 0) });
104
+ break;
105
+ case "compose_cast":
106
+ h.compose_cast({
107
+ text: p.text ? String(p.text) : undefined,
108
+ channelKey: p.channelKey ? String(p.channelKey) : undefined,
109
+ embeds: Array.isArray(p.embeds) ? p.embeds : undefined,
110
+ });
111
+ break;
112
+ case "view_token":
113
+ h.view_token({ token: String(p.token ?? "") });
114
+ break;
115
+ case "send_token":
116
+ h.send_token({
117
+ token: String(p.token ?? ""),
118
+ amount: p.amount ? String(p.amount) : undefined,
119
+ recipientFid: p.recipientFid ? Number(p.recipientFid) : undefined,
120
+ recipientAddress: p.recipientAddress ? String(p.recipientAddress) : undefined,
121
+ });
122
+ break;
123
+ case "swap_token":
124
+ h.swap_token({
125
+ sellToken: p.sellToken ? String(p.sellToken) : undefined,
126
+ buyToken: p.buyToken ? String(p.buyToken) : undefined,
127
+ });
128
+ break;
129
+ default:
130
+ break;
131
+ }
132
+ }, []);
133
+ return (_jsxs(View, { style: styles.container, children: [loading && (_jsx(View, { style: [
134
+ styles.overlay,
135
+ {
136
+ backgroundColor: mode === "dark" ? "rgba(0,0,0,0.6)" : "rgba(255,255,255,0.75)",
137
+ },
138
+ ], children: _jsx(ActivityIndicator, { size: "large", color: accentHex }) })), _jsx(SnapCatalogView, { spec: spec, state: initialState, loading: false, onStateChange: (changes) => {
139
+ applyStatePaths(stateRef.current, changes);
140
+ }, onAction: handleAction }, pageKey)] }));
141
+ }
142
+ export function SnapView({ snap, handlers, loading = false, appearance = "dark", colors, }) {
143
+ return (_jsx(SnapThemeProvider, { appearance: appearance, colors: colors, children: _jsx(SnapViewInner, { snap: snap, handlers: handlers, loading: loading }) }));
144
+ }
145
+ const styles = StyleSheet.create({
146
+ container: {
147
+ width: "100%",
148
+ },
149
+ overlay: {
150
+ ...StyleSheet.absoluteFillObject,
151
+ alignItems: "center",
152
+ justifyContent: "center",
153
+ zIndex: 10,
154
+ },
155
+ });
@@ -0,0 +1,21 @@
1
+ import { type ReactNode } from "react";
2
+ export type SnapNativeColors = {
3
+ bg: string;
4
+ surface: string;
5
+ text: string;
6
+ textSecondary: string;
7
+ border: string;
8
+ inputBg: string;
9
+ muted: string;
10
+ };
11
+ interface SnapThemeValue {
12
+ mode: "light" | "dark";
13
+ colors: SnapNativeColors;
14
+ }
15
+ export declare function SnapThemeProvider({ appearance, colors, children, }: {
16
+ appearance: "light" | "dark";
17
+ colors?: Partial<SnapNativeColors>;
18
+ children: ReactNode;
19
+ }): import("react").JSX.Element;
20
+ export declare function useSnapTheme(): SnapThemeValue;
21
+ export {};
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from "react";
3
+ const DEFAULT_LIGHT = {
4
+ bg: "#dfe3e8",
5
+ surface: "#ffffff",
6
+ text: "#111111",
7
+ textSecondary: "#6b7280",
8
+ border: "#d1d5db",
9
+ inputBg: "#ffffff",
10
+ muted: "#f9fafb",
11
+ };
12
+ const DEFAULT_DARK = {
13
+ bg: "#111318",
14
+ surface: "#1a1d24",
15
+ text: "#fafafa",
16
+ textSecondary: "#a1a1aa",
17
+ border: "#374151",
18
+ inputBg: "#1a1d24",
19
+ muted: "#27272a",
20
+ };
21
+ const SnapThemeContext = createContext({
22
+ mode: "dark",
23
+ colors: DEFAULT_DARK,
24
+ });
25
+ export function SnapThemeProvider({ appearance, colors, children, }) {
26
+ const value = useMemo(() => {
27
+ const defaults = appearance === "dark" ? DEFAULT_DARK : DEFAULT_LIGHT;
28
+ return {
29
+ mode: appearance,
30
+ colors: colors ? { ...defaults, ...colors } : defaults,
31
+ };
32
+ }, [appearance, colors]);
33
+ return (_jsx(SnapThemeContext.Provider, { value: value, children: children }));
34
+ }
35
+ export function useSnapTheme() {
36
+ return useContext(SnapThemeContext);
37
+ }
@@ -0,0 +1,13 @@
1
+ export declare function useSnapPalette(): {
2
+ appearance: "light" | "dark";
3
+ accentName: "gray" | "blue" | "red" | "amber" | "green" | "teal" | "purple" | "pink";
4
+ accentHex: string;
5
+ hex: (semantic: string) => string;
6
+ };
7
+ /** `#RRGGBB` + alpha → `rgba(...)` for React Native styles. */
8
+ export declare function hexToRgba(hex: string, alpha: number): string;
9
+ export declare function useSnapPreviewChromePalette(themeAccent: string | undefined): {
10
+ appearance: "light" | "dark";
11
+ accentName: "gray" | "blue" | "red" | "amber" | "green" | "teal" | "purple" | "pink";
12
+ accentHex: string;
13
+ };
@@ -0,0 +1,48 @@
1
+ import { DEFAULT_THEME_ACCENT, PALETTE_COLOR_VALUES, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, } from "@farcaster/snap";
2
+ import { useStateStore } from "@json-render/react-native";
3
+ import { useSnapTheme } from "./theme.js";
4
+ function resolveHex(name, appearance) {
5
+ const map = appearance === "dark" ? PALETTE_DARK_HEX : PALETTE_LIGHT_HEX;
6
+ if (Object.hasOwn(map, name)) {
7
+ return map[name];
8
+ }
9
+ return map.purple;
10
+ }
11
+ function isPaletteColor(s) {
12
+ return PALETTE_COLOR_VALUES.includes(s);
13
+ }
14
+ function themeAccentFromStore(get) {
15
+ const raw = get("/theme/accent");
16
+ if (typeof raw === "string" && isPaletteColor(raw)) {
17
+ return raw;
18
+ }
19
+ return DEFAULT_THEME_ACCENT;
20
+ }
21
+ export function useSnapPalette() {
22
+ const { mode } = useSnapTheme();
23
+ const { get } = useStateStore();
24
+ const accentName = themeAccentFromStore(get);
25
+ const accentHex = resolveHex(accentName, mode);
26
+ const hex = (semantic) => semantic === "accent" ? accentHex : resolveHex(semantic, mode);
27
+ return { appearance: mode, accentName, accentHex, hex };
28
+ }
29
+ /** `#RRGGBB` + alpha → `rgba(...)` for React Native styles. */
30
+ export function hexToRgba(hex, alpha) {
31
+ const m = /^#([0-9a-fA-F]{6})$/.exec(hex.trim());
32
+ if (!m) {
33
+ return `rgba(0,0,0,${alpha})`;
34
+ }
35
+ const n = Number.parseInt(m[1], 16);
36
+ const r = (n >> 16) & 255;
37
+ const g = (n >> 8) & 255;
38
+ const b = n & 255;
39
+ return `rgba(${r},${g},${b},${alpha})`;
40
+ }
41
+ export function useSnapPreviewChromePalette(themeAccent) {
42
+ const { mode } = useSnapTheme();
43
+ const accentName = typeof themeAccent === "string" && isPaletteColor(themeAccent)
44
+ ? themeAccent
45
+ : DEFAULT_THEME_ACCENT;
46
+ const accentHex = resolveHex(accentName, mode);
47
+ return { appearance: mode, accentName, accentHex };
48
+ }
@@ -14,18 +14,18 @@ export declare const badgeProps: z.ZodObject<{
14
14
  accent: "accent";
15
15
  }>>;
16
16
  icon: z.ZodOptional<z.ZodEnum<{
17
- check: "check";
18
- repeat: "repeat";
19
17
  "arrow-right": "arrow-right";
20
18
  "arrow-left": "arrow-left";
21
19
  "external-link": "external-link";
22
20
  "chevron-right": "chevron-right";
21
+ check: "check";
23
22
  x: "x";
24
23
  "alert-triangle": "alert-triangle";
25
24
  info: "info";
26
25
  clock: "clock";
27
26
  heart: "heart";
28
27
  "message-circle": "message-circle";
28
+ repeat: "repeat";
29
29
  share: "share";
30
30
  user: "user";
31
31
  users: "users";
@@ -10,18 +10,18 @@ export declare const buttonProps: z.ZodObject<{
10
10
  ghost: "ghost";
11
11
  }>>;
12
12
  icon: z.ZodOptional<z.ZodEnum<{
13
- check: "check";
14
- repeat: "repeat";
15
13
  "arrow-right": "arrow-right";
16
14
  "arrow-left": "arrow-left";
17
15
  "external-link": "external-link";
18
16
  "chevron-right": "chevron-right";
17
+ check: "check";
19
18
  x: "x";
20
19
  "alert-triangle": "alert-triangle";
21
20
  info: "info";
22
21
  clock: "clock";
23
22
  heart: "heart";
24
23
  "message-circle": "message-circle";
24
+ repeat: "repeat";
25
25
  share: "share";
26
26
  user: "user";
27
27
  users: "users";
@@ -14,7 +14,7 @@ export declare const snapJsonRenderCatalog: import("@json-render/core").Catalog<
14
14
  children: {
15
15
  optional: true;
16
16
  kind: "array";
17
- inner?: import("@json-render/core").SchemaType<"string", unknown> | undefined;
17
+ inner?: import("@json-render/core").SchemaType<"string", unknown>;
18
18
  };
19
19
  }>>;
20
20
  }>;
@@ -49,18 +49,18 @@ export declare const snapJsonRenderCatalog: import("@json-render/core").Catalog<
49
49
  accent: "accent";
50
50
  }>>;
51
51
  icon: z.ZodOptional<z.ZodEnum<{
52
- check: "check";
53
- repeat: "repeat";
54
52
  "arrow-right": "arrow-right";
55
53
  "arrow-left": "arrow-left";
56
54
  "external-link": "external-link";
57
55
  "chevron-right": "chevron-right";
56
+ check: "check";
58
57
  x: "x";
59
58
  "alert-triangle": "alert-triangle";
60
59
  info: "info";
61
60
  clock: "clock";
62
61
  heart: "heart";
63
62
  "message-circle": "message-circle";
63
+ repeat: "repeat";
64
64
  share: "share";
65
65
  user: "user";
66
66
  users: "users";
@@ -96,18 +96,18 @@ export declare const snapJsonRenderCatalog: import("@json-render/core").Catalog<
96
96
  ghost: "ghost";
97
97
  }>>;
98
98
  icon: z.ZodOptional<z.ZodEnum<{
99
- check: "check";
100
- repeat: "repeat";
101
99
  "arrow-right": "arrow-right";
102
100
  "arrow-left": "arrow-left";
103
101
  "external-link": "external-link";
104
102
  "chevron-right": "chevron-right";
103
+ check: "check";
105
104
  x: "x";
106
105
  "alert-triangle": "alert-triangle";
107
106
  info: "info";
108
107
  clock: "clock";
109
108
  heart: "heart";
110
109
  "message-circle": "message-circle";
110
+ repeat: "repeat";
111
111
  share: "share";
112
112
  user: "user";
113
113
  users: "users";
@@ -201,18 +201,18 @@ export declare const snapJsonRenderCatalog: import("@json-render/core").Catalog<
201
201
  icon: {
202
202
  props: z.ZodObject<{
203
203
  name: z.ZodEnum<{
204
- check: "check";
205
- repeat: "repeat";
206
204
  "arrow-right": "arrow-right";
207
205
  "arrow-left": "arrow-left";
208
206
  "external-link": "external-link";
209
207
  "chevron-right": "chevron-right";
208
+ check: "check";
210
209
  x: "x";
211
210
  "alert-triangle": "alert-triangle";
212
211
  info: "info";
213
212
  clock: "clock";
214
213
  heart: "heart";
215
214
  "message-circle": "message-circle";
215
+ repeat: "repeat";
216
216
  share: "share";
217
217
  user: "user";
218
218
  users: "users";
package/dist/ui/icon.d.ts CHANGED
@@ -3,18 +3,18 @@ export declare const ICON_NAMES: readonly ["arrow-right", "arrow-left", "externa
3
3
  export declare const ICON_SIZES: readonly ["sm", "md"];
4
4
  export declare const iconProps: z.ZodObject<{
5
5
  name: z.ZodEnum<{
6
- check: "check";
7
- repeat: "repeat";
8
6
  "arrow-right": "arrow-right";
9
7
  "arrow-left": "arrow-left";
10
8
  "external-link": "external-link";
11
9
  "chevron-right": "chevron-right";
10
+ check: "check";
12
11
  x: "x";
13
12
  "alert-triangle": "alert-triangle";
14
13
  info: "info";
15
14
  clock: "clock";
16
15
  heart: "heart";
17
16
  "message-circle": "message-circle";
17
+ repeat: "repeat";
18
18
  share: "share";
19
19
  user: "user";
20
20
  users: "users";
@@ -11,7 +11,7 @@ export declare const snapJsonRenderSchema: import("@json-render/core").Schema<{
11
11
  children: {
12
12
  optional: true;
13
13
  kind: "array";
14
- inner?: import("@json-render/core").SchemaType<"string", unknown> | undefined;
14
+ inner?: import("@json-render/core").SchemaType<"string", unknown>;
15
15
  };
16
16
  }>>;
17
17
  }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farcaster/snap",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "description": "Farcaster Snaps 🫰",
5
5
  "repository": {
6
6
  "type": "git",
@@ -100,6 +100,11 @@
100
100
  "types": "./dist/react/index.d.ts",
101
101
  "import": "./dist/react/index.js",
102
102
  "default": "./dist/react/index.js"
103
+ },
104
+ "./react-native": {
105
+ "types": "./dist/react-native/index.d.ts",
106
+ "import": "./dist/react-native/index.js",
107
+ "default": "./dist/react-native/index.js"
103
108
  }
104
109
  },
105
110
  "files": [
@@ -147,7 +152,7 @@
147
152
  "zod": "^4.0.0"
148
153
  },
149
154
  "scripts": {
150
- "build": "tsc && tsc-alias --resolve-full-paths --resolve-full-extension .js",
155
+ "build": "tsc && (tsc -p tsconfig.react-native.json || true) && tsc-alias --resolve-full-paths --resolve-full-extension .js",
151
156
  "clean": "rm -rf dist",
152
157
  "test": "vitest run",
153
158
  "typecheck": "tsc --noEmit"