@farcaster/snap 1.21.0 → 1.22.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.
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/react-native/components/snap-cell-grid.js +4 -6
- package/dist/react-native/v2/snap-view.js +5 -4
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/react-native/components/snap-cell-grid.tsx +4 -6
- package/src/react-native/v2/snap-view.tsx +12 -6
package/dist/constants.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const SPEC_VERSION_1: "1.0";
|
|
2
2
|
export declare const SPEC_VERSION_2: "2.0";
|
|
3
|
-
export declare const SPEC_VERSION: "
|
|
3
|
+
export declare const SPEC_VERSION: "2.0";
|
|
4
4
|
export declare const SUPPORTED_SPEC_VERSIONS: readonly ["1.0", "2.0"];
|
|
5
5
|
export type SpecVersion = (typeof SUPPORTED_SPEC_VERSIONS)[number];
|
|
6
6
|
export declare const MEDIA_TYPE: "application/vnd.farcaster.snap+json";
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const SPEC_VERSION_1 = "1.0";
|
|
2
2
|
export const SPEC_VERSION_2 = "2.0";
|
|
3
|
-
export const SPEC_VERSION =
|
|
3
|
+
export const SPEC_VERSION = SPEC_VERSION_2;
|
|
4
4
|
export const SUPPORTED_SPEC_VERSIONS = [SPEC_VERSION_1, SPEC_VERSION_2];
|
|
5
5
|
export const MEDIA_TYPE = "application/vnd.farcaster.snap+json";
|
|
6
6
|
export const EFFECT_VALUES = ["confetti"];
|
|
@@ -11,6 +11,7 @@ export function SnapCellGrid({ element: { props }, }) {
|
|
|
11
11
|
const cols = Number(props.cols ?? 2);
|
|
12
12
|
const rows = Number(props.rows ?? 2);
|
|
13
13
|
const cells = Array.isArray(props.cells) ? props.cells : [];
|
|
14
|
+
const rowHeight = typeof props.rowHeight === "number" ? props.rowHeight : 28;
|
|
14
15
|
const gap = String(props.gap ?? "sm");
|
|
15
16
|
const gapMap = { none: 0, sm: 1, md: 2, lg: 4 };
|
|
16
17
|
const gapPx = gapMap[gap] ?? 1;
|
|
@@ -60,10 +61,10 @@ export function SnapCellGrid({ element: { props }, }) {
|
|
|
60
61
|
const bg = cell?.color ? hex(cell.color) : "transparent";
|
|
61
62
|
const cellContent = cell?.content ? (_jsx(Text, { style: [styles.cellText, { color: colors.textPrimary }], children: cell.content })) : null;
|
|
62
63
|
// Two-tone ring: outer View with contrasting border, inner View with inverse border
|
|
63
|
-
const cellView = selected ? (_jsx(View, { style: [styles.cell, { borderWidth: 1, borderColor: ringOuter, borderRadius: 4 }], children: _jsx(View, { style: [
|
|
64
|
+
const cellView = selected ? (_jsx(View, { style: [styles.cell, { height: rowHeight, borderWidth: 1, borderColor: ringOuter, borderRadius: 4 }], children: _jsx(View, { style: [
|
|
64
65
|
styles.innerCell,
|
|
65
66
|
{ backgroundColor: bg, borderWidth: 1, borderColor: ringInner, borderRadius: 3 },
|
|
66
|
-
], children: cellContent }) })) : (_jsx(View, { style: [styles.cell, { backgroundColor: bg }], children: cellContent }));
|
|
67
|
+
], children: cellContent }) })) : (_jsx(View, { style: [styles.cell, { height: rowHeight, backgroundColor: bg }], children: cellContent }));
|
|
67
68
|
rowCells.push(interactive ? (_jsx(Pressable, { onPress: () => handleTap(r, c), style: styles.cellWrap, children: cellView }, `${r}-${c}`)) : (_jsx(View, { style: styles.cellWrap, children: cellView }, `${r}-${c}`)));
|
|
68
69
|
}
|
|
69
70
|
rowEls.push(_jsx(View, { style: [styles.gridRow, { gap: gapPx }], children: rowCells }, r));
|
|
@@ -78,16 +79,13 @@ const styles = StyleSheet.create({
|
|
|
78
79
|
gridRow: { flexDirection: "row" },
|
|
79
80
|
cellWrap: { flex: 1 },
|
|
80
81
|
cell: {
|
|
81
|
-
flex: 1,
|
|
82
|
-
minHeight: 28,
|
|
83
82
|
borderRadius: 4,
|
|
84
83
|
alignItems: "center",
|
|
85
84
|
justifyContent: "center",
|
|
86
85
|
},
|
|
87
86
|
innerCell: {
|
|
88
|
-
flex: 1,
|
|
89
87
|
width: "100%",
|
|
90
|
-
|
|
88
|
+
height: "100%",
|
|
91
89
|
alignItems: "center",
|
|
92
90
|
justifyContent: "center",
|
|
93
91
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useMemo } from "react";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { Platform, StyleSheet, Text, View } from "react-native";
|
|
4
4
|
import { SnapThemeProvider, useSnapTheme } from "../theme.js";
|
|
5
5
|
import { SnapViewCoreInner } from "../snap-view-core.js";
|
|
@@ -52,20 +52,21 @@ export function SnapViewV2({ snap, handlers, loading = false, appearance = "dark
|
|
|
52
52
|
// ─── SnapCardV2 (card frame + height limits) ─────────
|
|
53
53
|
function SnapCardV2Inner({ snap, handlers, loading, borderRadius, showOverflowWarning, onValidationError, validationErrorFallback, actionError, appearance, plain, }) {
|
|
54
54
|
const { colors } = useSnapTheme();
|
|
55
|
-
const
|
|
55
|
+
const [contentHeight, setContentHeight] = useState(0);
|
|
56
56
|
const content = (_jsx(SnapViewV2Inner, { snap: snap, handlers: handlers, loading: loading, onValidationError: onValidationError, validationErrorFallback: validationErrorFallback }));
|
|
57
57
|
if (plain) {
|
|
58
58
|
return content;
|
|
59
59
|
}
|
|
60
|
+
const overflowAmount = showOverflowWarning ? contentHeight - SNAP_MAX_HEIGHT : 0;
|
|
60
61
|
return (_jsxs(_Fragment, { children: [_jsxs(View, { style: {
|
|
61
62
|
borderRadius,
|
|
62
63
|
borderWidth: 1,
|
|
63
64
|
borderColor: colors.border,
|
|
64
65
|
backgroundColor: colors.surface,
|
|
65
|
-
maxHeight:
|
|
66
|
+
maxHeight: showOverflowWarning ? undefined : SNAP_MAX_HEIGHT,
|
|
66
67
|
overflow: "hidden",
|
|
67
68
|
minHeight: 120,
|
|
68
|
-
}, children: [_jsx(View, { style: { paddingHorizontal: 16, paddingVertical: 16 }, children: content }), showOverflowWarning && (_jsxs(View, { style: { position: "absolute", top: SNAP_MAX_HEIGHT, left: 0, right: 0,
|
|
69
|
+
}, children: [_jsx(View, { collapsable: false, onLayout: (e) => setContentHeight(Math.round(e.nativeEvent.layout.height)), style: { paddingHorizontal: 16, paddingVertical: 16 }, children: content }), showOverflowWarning && contentHeight > SNAP_MAX_HEIGHT && (_jsxs(View, { style: { position: "absolute", top: SNAP_MAX_HEIGHT, left: 0, right: 0, height: overflowAmount, zIndex: 10, pointerEvents: "none" }, children: [_jsx(View, { style: { height: 1, borderTopWidth: 1, borderStyle: "dashed", borderColor: "rgba(255,100,100,0.6)" } }), _jsx(View, { style: { position: "absolute", top: -10, right: 4, backgroundColor: "rgba(0,0,0,0.7)", paddingHorizontal: 4, paddingVertical: 1, borderRadius: 3 }, children: _jsxs(Text, { style: { fontSize: 10, color: "rgba(255,100,100,0.7)", fontFamily: Platform.select({ ios: "Menlo", default: "monospace" }) }, children: [SNAP_MAX_HEIGHT, "px"] }) }), _jsx(View, { style: { flex: 1, backgroundColor: "rgba(255,50,50,0.15)" } })] }))] }), actionError && (_jsx(Text, { style: {
|
|
69
70
|
paddingHorizontal: 12,
|
|
70
71
|
paddingVertical: 8,
|
|
71
72
|
fontSize: 13,
|
package/llms.txt
CHANGED
|
@@ -8,7 +8,7 @@ Every snap handler returns a `SnapResponse`:
|
|
|
8
8
|
|
|
9
9
|
```json
|
|
10
10
|
{
|
|
11
|
-
"version": "
|
|
11
|
+
"version": "2.0",
|
|
12
12
|
"theme": { "accent": "purple" },
|
|
13
13
|
"effects": ["confetti"],
|
|
14
14
|
"ui": {
|
|
@@ -26,7 +26,7 @@ Every snap handler returns a `SnapResponse`:
|
|
|
26
26
|
}
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
Top-level fields: `version` (required, `"1.0"`), `theme` (optional, `{ accent: PaletteColor }`), `effects` (optional, `["confetti"]`), `ui` (required).
|
|
29
|
+
Top-level fields: `version` (required, `"1.0"` or `"2.0"`), `theme` (optional, `{ accent: PaletteColor }`), `effects` (optional, `["confetti"]`), `ui` (required).
|
|
30
30
|
|
|
31
31
|
`ui.root` is the ID of the root element. `ui.elements` is a flat map of element ID to element definition.
|
|
32
32
|
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const SPEC_VERSION_1 = "1.0" as const;
|
|
2
2
|
export const SPEC_VERSION_2 = "2.0" as const;
|
|
3
|
-
export const SPEC_VERSION =
|
|
3
|
+
export const SPEC_VERSION = SPEC_VERSION_2;
|
|
4
4
|
export const SUPPORTED_SPEC_VERSIONS = [SPEC_VERSION_1, SPEC_VERSION_2] as const;
|
|
5
5
|
export type SpecVersion = (typeof SUPPORTED_SPEC_VERSIONS)[number];
|
|
6
6
|
|
|
@@ -14,6 +14,7 @@ export function SnapCellGrid({
|
|
|
14
14
|
const cols = Number(props.cols ?? 2);
|
|
15
15
|
const rows = Number(props.rows ?? 2);
|
|
16
16
|
const cells = Array.isArray(props.cells) ? props.cells : [];
|
|
17
|
+
const rowHeight = typeof props.rowHeight === "number" ? props.rowHeight : 28;
|
|
17
18
|
const gap = String(props.gap ?? "sm");
|
|
18
19
|
const gapMap: Record<string, number> = { none: 0, sm: 1, md: 2, lg: 4 };
|
|
19
20
|
const gapPx = gapMap[gap] ?? 1;
|
|
@@ -74,7 +75,7 @@ export function SnapCellGrid({
|
|
|
74
75
|
|
|
75
76
|
// Two-tone ring: outer View with contrasting border, inner View with inverse border
|
|
76
77
|
const cellView = selected ? (
|
|
77
|
-
<View style={[styles.cell, { borderWidth: 1, borderColor: ringOuter, borderRadius: 4 }]}>
|
|
78
|
+
<View style={[styles.cell, { height: rowHeight, borderWidth: 1, borderColor: ringOuter, borderRadius: 4 }]}>
|
|
78
79
|
<View
|
|
79
80
|
style={[
|
|
80
81
|
styles.innerCell,
|
|
@@ -85,7 +86,7 @@ export function SnapCellGrid({
|
|
|
85
86
|
</View>
|
|
86
87
|
</View>
|
|
87
88
|
) : (
|
|
88
|
-
<View style={[styles.cell, { backgroundColor: bg }]}>
|
|
89
|
+
<View style={[styles.cell, { height: rowHeight, backgroundColor: bg }]}>
|
|
89
90
|
{cellContent}
|
|
90
91
|
</View>
|
|
91
92
|
);
|
|
@@ -134,16 +135,13 @@ const styles = StyleSheet.create({
|
|
|
134
135
|
gridRow: { flexDirection: "row" },
|
|
135
136
|
cellWrap: { flex: 1 },
|
|
136
137
|
cell: {
|
|
137
|
-
flex: 1,
|
|
138
|
-
minHeight: 28,
|
|
139
138
|
borderRadius: 4,
|
|
140
139
|
alignItems: "center",
|
|
141
140
|
justifyContent: "center",
|
|
142
141
|
},
|
|
143
142
|
innerCell: {
|
|
144
|
-
flex: 1,
|
|
145
143
|
width: "100%",
|
|
146
|
-
|
|
144
|
+
height: "100%",
|
|
147
145
|
alignItems: "center",
|
|
148
146
|
justifyContent: "center",
|
|
149
147
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
import { useEffect, useMemo } from "react";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
3
|
import { Platform, StyleSheet, Text, View } from "react-native";
|
|
4
4
|
import { SnapThemeProvider, useSnapTheme, type SnapNativeColors } from "../theme";
|
|
5
5
|
import { SnapViewCoreInner } from "../snap-view-core";
|
|
@@ -137,7 +137,7 @@ function SnapCardV2Inner({
|
|
|
137
137
|
plain: boolean;
|
|
138
138
|
}) {
|
|
139
139
|
const { colors } = useSnapTheme();
|
|
140
|
-
const
|
|
140
|
+
const [contentHeight, setContentHeight] = useState(0);
|
|
141
141
|
|
|
142
142
|
const content = (
|
|
143
143
|
<SnapViewV2Inner
|
|
@@ -153,6 +153,8 @@ function SnapCardV2Inner({
|
|
|
153
153
|
return content;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
const overflowAmount = showOverflowWarning ? contentHeight - SNAP_MAX_HEIGHT : 0;
|
|
157
|
+
|
|
156
158
|
return (
|
|
157
159
|
<>
|
|
158
160
|
<View
|
|
@@ -161,16 +163,20 @@ function SnapCardV2Inner({
|
|
|
161
163
|
borderWidth: 1,
|
|
162
164
|
borderColor: colors.border,
|
|
163
165
|
backgroundColor: colors.surface,
|
|
164
|
-
maxHeight:
|
|
166
|
+
maxHeight: showOverflowWarning ? undefined : SNAP_MAX_HEIGHT,
|
|
165
167
|
overflow: "hidden",
|
|
166
168
|
minHeight: 120,
|
|
167
169
|
}}
|
|
168
170
|
>
|
|
169
|
-
<View
|
|
171
|
+
<View
|
|
172
|
+
collapsable={false}
|
|
173
|
+
onLayout={(e) => setContentHeight(Math.round(e.nativeEvent.layout.height))}
|
|
174
|
+
style={{ paddingHorizontal: 16, paddingVertical: 16 }}
|
|
175
|
+
>
|
|
170
176
|
{content}
|
|
171
177
|
</View>
|
|
172
|
-
{showOverflowWarning && (
|
|
173
|
-
<View style={{ position: "absolute", top: SNAP_MAX_HEIGHT, left: 0, right: 0,
|
|
178
|
+
{showOverflowWarning && contentHeight > SNAP_MAX_HEIGHT && (
|
|
179
|
+
<View style={{ position: "absolute", top: SNAP_MAX_HEIGHT, left: 0, right: 0, height: overflowAmount, zIndex: 10, pointerEvents: "none" }}>
|
|
174
180
|
<View style={{ height: 1, borderTopWidth: 1, borderStyle: "dashed", borderColor: "rgba(255,100,100,0.6)" }} />
|
|
175
181
|
<View style={{ position: "absolute", top: -10, right: 4, backgroundColor: "rgba(0,0,0,0.7)", paddingHorizontal: 4, paddingVertical: 1, borderRadius: 3 }}>
|
|
176
182
|
<Text style={{ fontSize: 10, color: "rgba(255,100,100,0.7)", fontFamily: Platform.select({ ios: "Menlo", default: "monospace" }) }}>{SNAP_MAX_HEIGHT}px</Text>
|