@farcaster/snap 1.10.0 → 1.14.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 +8 -0
- package/dist/constants.js +10 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/react/catalog-renderer.js +4 -0
- package/dist/react/components/action-button.js +18 -10
- package/dist/react/components/badge.js +8 -6
- package/dist/react/components/bar-chart.d.ts +5 -0
- package/dist/react/components/bar-chart.js +26 -0
- package/dist/react/components/cell-grid.d.ts +5 -0
- package/dist/react/components/cell-grid.js +82 -0
- package/dist/react/components/icon.js +4 -10
- package/dist/react/components/input.js +12 -6
- package/dist/react/components/item-group.js +3 -1
- package/dist/react/components/item.d.ts +3 -3
- package/dist/react/components/item.js +4 -3
- package/dist/react/components/progress.js +3 -3
- package/dist/react/components/separator.js +3 -1
- package/dist/react/components/slider.js +14 -10
- package/dist/react/components/switch.js +10 -12
- package/dist/react/components/text.js +5 -7
- package/dist/react/components/toggle-group.js +20 -6
- package/dist/react/hooks/use-snap-colors.d.ts +38 -0
- package/dist/react/hooks/use-snap-colors.js +82 -0
- package/dist/react-native/catalog-renderer.js +4 -0
- package/dist/react-native/components/snap-action-button.js +8 -18
- package/dist/react-native/components/snap-bar-chart.d.ts +2 -0
- package/dist/react-native/components/snap-bar-chart.js +39 -0
- package/dist/react-native/components/snap-cell-grid.d.ts +2 -0
- package/dist/react-native/components/snap-cell-grid.js +96 -0
- package/dist/react-native/components/snap-switch.js +1 -1
- package/dist/react-native/components/snap-toggle-group.js +8 -10
- package/dist/react-native/theme.d.ts +6 -0
- package/dist/react-native/theme.js +12 -6
- package/dist/ui/bar-chart.d.ts +30 -0
- package/dist/ui/bar-chart.js +30 -0
- package/dist/ui/catalog.d.ts +65 -0
- package/dist/ui/catalog.js +10 -0
- package/dist/ui/cell-grid.d.ts +33 -0
- package/dist/ui/cell-grid.js +38 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +2 -0
- package/llms.txt +16 -1
- package/package.json +1 -1
- package/src/constants.ts +12 -0
- package/src/index.ts +6 -2
- package/src/react/catalog-renderer.tsx +4 -0
- package/src/react/components/action-button.tsx +24 -17
- package/src/react/components/badge.tsx +14 -17
- package/src/react/components/bar-chart.tsx +69 -0
- package/src/react/components/cell-grid.tsx +124 -0
- package/src/react/components/icon.tsx +5 -18
- package/src/react/components/input.tsx +20 -9
- package/src/react/components/item-group.tsx +4 -1
- package/src/react/components/item.tsx +13 -10
- package/src/react/components/progress.tsx +12 -7
- package/src/react/components/separator.tsx +8 -1
- package/src/react/components/slider.tsx +18 -15
- package/src/react/components/switch.tsx +12 -16
- package/src/react/components/text.tsx +11 -8
- package/src/react/components/toggle-group.tsx +26 -9
- package/src/react/hooks/use-snap-colors.ts +129 -0
- package/src/react-native/catalog-renderer.tsx +4 -0
- package/src/react-native/components/snap-action-button.tsx +8 -20
- package/src/react-native/components/snap-bar-chart.tsx +73 -0
- package/src/react-native/components/snap-cell-grid.tsx +152 -0
- package/src/react-native/components/snap-switch.tsx +1 -1
- package/src/react-native/components/snap-toggle-group.tsx +8 -10
- package/src/react-native/theme.tsx +18 -6
- package/src/ui/bar-chart.ts +38 -0
- package/src/ui/catalog.ts +12 -0
- package/src/ui/cell-grid.ts +48 -0
- package/src/ui/index.ts +6 -0
- package/dist/middleware.d.ts +0 -3
- package/dist/middleware.js +0 -3
- package/dist/react/hooks/use-snap-accent.d.ts +0 -13
- package/dist/react/hooks/use-snap-accent.js +0 -32
- package/src/middleware.ts +0 -7
- package/src/react/hooks/use-snap-accent.ts +0 -45
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { ComponentRenderProps } from "@json-render/react-native";
|
|
2
2
|
import { useStateStore } from "@json-render/react-native";
|
|
3
3
|
import { Pressable, StyleSheet, Text, View } from "react-native";
|
|
4
|
-
import { useSnapPalette } from "../use-snap-palette";
|
|
5
4
|
import { useSnapTheme } from "../theme";
|
|
6
5
|
|
|
7
6
|
export function SnapToggleGroup({
|
|
8
7
|
element: { props },
|
|
9
8
|
}: ComponentRenderProps<Record<string, unknown>>) {
|
|
10
9
|
const { get, set } = useStateStore();
|
|
11
|
-
const { accentHex } = useSnapPalette();
|
|
12
10
|
const { colors } = useSnapTheme();
|
|
13
11
|
const name = String(props.name ?? "toggle_group");
|
|
14
12
|
const path = `/inputs/${name}`;
|
|
@@ -59,7 +57,7 @@ export function SnapToggleGroup({
|
|
|
59
57
|
<View
|
|
60
58
|
style={[
|
|
61
59
|
styles.group,
|
|
62
|
-
{ backgroundColor: colors.
|
|
60
|
+
{ backgroundColor: colors.muted },
|
|
63
61
|
isVertical ? styles.groupVertical : styles.groupHorizontal,
|
|
64
62
|
]}
|
|
65
63
|
>
|
|
@@ -70,8 +68,13 @@ export function SnapToggleGroup({
|
|
|
70
68
|
key={index}
|
|
71
69
|
style={({ pressed }) => [
|
|
72
70
|
styles.option,
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
{
|
|
72
|
+
backgroundColor: isSelected
|
|
73
|
+
? colors.mutedSelected
|
|
74
|
+
: pressed
|
|
75
|
+
? colors.mutedHover
|
|
76
|
+
: colors.mutedSubtle,
|
|
77
|
+
},
|
|
75
78
|
!isVertical && styles.optionHorizontal,
|
|
76
79
|
]}
|
|
77
80
|
onPress={() => handlePress(opt)}
|
|
@@ -80,7 +83,6 @@ export function SnapToggleGroup({
|
|
|
80
83
|
style={[
|
|
81
84
|
styles.optionText,
|
|
82
85
|
{ color: colors.text },
|
|
83
|
-
isSelected && styles.optionTextSelected,
|
|
84
86
|
]}
|
|
85
87
|
>
|
|
86
88
|
{opt}
|
|
@@ -117,12 +119,8 @@ const styles = StyleSheet.create({
|
|
|
117
119
|
optionHorizontal: {
|
|
118
120
|
flex: 1,
|
|
119
121
|
},
|
|
120
|
-
pressed: { opacity: 0.88 },
|
|
121
122
|
optionText: {
|
|
122
123
|
fontSize: 13,
|
|
123
124
|
fontWeight: "500",
|
|
124
125
|
},
|
|
125
|
-
optionTextSelected: {
|
|
126
|
-
color: "#fff",
|
|
127
|
-
},
|
|
128
126
|
});
|
|
@@ -10,6 +10,12 @@ export type SnapNativeColors = {
|
|
|
10
10
|
border: string;
|
|
11
11
|
inputBg: string;
|
|
12
12
|
muted: string;
|
|
13
|
+
/** Subtle tint for toggle button resting state */
|
|
14
|
+
mutedSubtle: string;
|
|
15
|
+
/** Slightly stronger tint for hover/press state */
|
|
16
|
+
mutedHover: string;
|
|
17
|
+
/** Stronger tint for selected state (toggle group) */
|
|
18
|
+
mutedSelected: string;
|
|
13
19
|
};
|
|
14
20
|
|
|
15
21
|
const DEFAULT_LIGHT: SnapNativeColors = {
|
|
@@ -17,9 +23,12 @@ const DEFAULT_LIGHT: SnapNativeColors = {
|
|
|
17
23
|
surface: "#ffffff",
|
|
18
24
|
text: "#111111",
|
|
19
25
|
textSecondary: "#6b7280",
|
|
20
|
-
border: "#
|
|
21
|
-
inputBg: "
|
|
22
|
-
muted: "
|
|
26
|
+
border: "#E5E7EB",
|
|
27
|
+
inputBg: "rgba(0,0,0,0.12)",
|
|
28
|
+
muted: "rgba(0,0,0,0.12)",
|
|
29
|
+
mutedSubtle: "rgba(0,0,0,0.06)",
|
|
30
|
+
mutedHover: "rgba(0,0,0,0.10)",
|
|
31
|
+
mutedSelected: "rgba(0,0,0,0.18)",
|
|
23
32
|
};
|
|
24
33
|
|
|
25
34
|
const DEFAULT_DARK: SnapNativeColors = {
|
|
@@ -27,9 +36,12 @@ const DEFAULT_DARK: SnapNativeColors = {
|
|
|
27
36
|
surface: "#1a1d24",
|
|
28
37
|
text: "#fafafa",
|
|
29
38
|
textSecondary: "#a1a1aa",
|
|
30
|
-
border: "#
|
|
31
|
-
inputBg: "
|
|
32
|
-
muted: "
|
|
39
|
+
border: "#2D2D44",
|
|
40
|
+
inputBg: "rgba(255,255,255,0.03)",
|
|
41
|
+
muted: "rgba(255,255,255,0.03)",
|
|
42
|
+
mutedSubtle: "rgba(255,255,255,0.02)",
|
|
43
|
+
mutedHover: "rgba(255,255,255,0.04)",
|
|
44
|
+
mutedSelected: "rgba(255,255,255,0.10)",
|
|
33
45
|
};
|
|
34
46
|
|
|
35
47
|
// ─── Context ──────────────────────────────────────────
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { BAR_CHART_COLOR_VALUES, PALETTE_COLOR_VALUES } from "../colors.js";
|
|
3
|
+
import {
|
|
4
|
+
BAR_CHART_MAX_BARS,
|
|
5
|
+
BAR_CHART_LABEL_MAX_CHARS,
|
|
6
|
+
} from "../constants.js";
|
|
7
|
+
|
|
8
|
+
export const barChartProps = z
|
|
9
|
+
.object({
|
|
10
|
+
bars: z
|
|
11
|
+
.array(
|
|
12
|
+
z.object({
|
|
13
|
+
label: z.string().min(1).max(BAR_CHART_LABEL_MAX_CHARS),
|
|
14
|
+
value: z.number().nonnegative(),
|
|
15
|
+
color: z.enum(PALETTE_COLOR_VALUES).optional(),
|
|
16
|
+
}),
|
|
17
|
+
)
|
|
18
|
+
.min(1)
|
|
19
|
+
.max(BAR_CHART_MAX_BARS),
|
|
20
|
+
max: z.number().nonnegative().optional(),
|
|
21
|
+
color: z.enum(BAR_CHART_COLOR_VALUES).optional(),
|
|
22
|
+
})
|
|
23
|
+
.superRefine((val, ctx) => {
|
|
24
|
+
if (val.max !== undefined) {
|
|
25
|
+
for (let i = 0; i < val.bars.length; i++) {
|
|
26
|
+
const bar = val.bars[i]!;
|
|
27
|
+
if (bar.value > val.max) {
|
|
28
|
+
ctx.addIssue({
|
|
29
|
+
code: "custom",
|
|
30
|
+
message: `bar value (${bar.value}) exceeds chart max (${val.max})`,
|
|
31
|
+
path: ["bars", i, "value"],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export type BarChartProps = z.infer<typeof barChartProps>;
|
package/src/ui/catalog.ts
CHANGED
|
@@ -15,6 +15,8 @@ import { separatorProps } from "./separator.js";
|
|
|
15
15
|
import { sliderProps } from "./slider.js";
|
|
16
16
|
import { stackProps } from "./stack.js";
|
|
17
17
|
import { textProps } from "./text.js";
|
|
18
|
+
import { barChartProps } from "./bar-chart.js";
|
|
19
|
+
import { cellGridProps } from "./cell-grid.js";
|
|
18
20
|
|
|
19
21
|
const snapClientParams = z.object({
|
|
20
22
|
client_action: z.record(z.string(), z.unknown()),
|
|
@@ -97,6 +99,16 @@ export const snapJsonRenderCatalog = defineCatalog(snapJsonRenderSchema, {
|
|
|
97
99
|
description:
|
|
98
100
|
"Text block — size: md (body, default), sm (caption). Optional weight and align.",
|
|
99
101
|
},
|
|
102
|
+
bar_chart: {
|
|
103
|
+
props: barChartProps,
|
|
104
|
+
description:
|
|
105
|
+
"Horizontal bar chart — 1–6 bars with label, value, and optional per-bar color. Optional max and default color.",
|
|
106
|
+
},
|
|
107
|
+
cell_grid: {
|
|
108
|
+
props: cellGridProps,
|
|
109
|
+
description:
|
|
110
|
+
"Cell grid — sparse colored cells on a rows×cols grid. Optional gap and selection mode (taps write to inputs[name]).",
|
|
111
|
+
},
|
|
100
112
|
},
|
|
101
113
|
actions: {
|
|
102
114
|
submit: {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { PALETTE_COLOR_VALUES } from "../colors.js";
|
|
3
|
+
import {
|
|
4
|
+
GRID_MIN_COLS,
|
|
5
|
+
GRID_MAX_COLS,
|
|
6
|
+
GRID_MIN_ROWS,
|
|
7
|
+
GRID_MAX_ROWS,
|
|
8
|
+
GRID_GAP_VALUES,
|
|
9
|
+
} from "../constants.js";
|
|
10
|
+
|
|
11
|
+
const cellGridCellSchema = z.object({
|
|
12
|
+
row: z.number().int().nonnegative(),
|
|
13
|
+
col: z.number().int().nonnegative(),
|
|
14
|
+
color: z.enum(PALETTE_COLOR_VALUES).optional(),
|
|
15
|
+
content: z.string().optional(),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const cellGridProps = z
|
|
19
|
+
.object({
|
|
20
|
+
name: z.string().min(1).optional(),
|
|
21
|
+
cols: z.number().int().min(GRID_MIN_COLS).max(GRID_MAX_COLS),
|
|
22
|
+
rows: z.number().int().min(GRID_MIN_ROWS).max(GRID_MAX_ROWS),
|
|
23
|
+
cells: z.array(cellGridCellSchema),
|
|
24
|
+
gap: z.enum(GRID_GAP_VALUES).optional(),
|
|
25
|
+
select: z.enum(["off", "single", "multiple"]).optional(),
|
|
26
|
+
})
|
|
27
|
+
.superRefine((val, ctx) => {
|
|
28
|
+
const { cols, rows, cells } = val;
|
|
29
|
+
for (let i = 0; i < cells.length; i++) {
|
|
30
|
+
const c = cells[i]!;
|
|
31
|
+
if (c.row < 0 || c.row >= rows) {
|
|
32
|
+
ctx.addIssue({
|
|
33
|
+
code: "custom",
|
|
34
|
+
message: `cell_grid cell row ${c.row} out of bounds (0–${rows - 1})`,
|
|
35
|
+
path: ["cells", i, "row"],
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (c.col < 0 || c.col >= cols) {
|
|
39
|
+
ctx.addIssue({
|
|
40
|
+
code: "custom",
|
|
41
|
+
message: `cell_grid cell col ${c.col} out of bounds (0–${cols - 1})`,
|
|
42
|
+
path: ["cells", i, "col"],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export type CellGridProps = z.infer<typeof cellGridProps>;
|
package/src/ui/index.ts
CHANGED
|
@@ -42,3 +42,9 @@ export type { StackProps } from "./stack.js";
|
|
|
42
42
|
|
|
43
43
|
export { textProps } from "./text.js";
|
|
44
44
|
export type { TextProps } from "./text.js";
|
|
45
|
+
|
|
46
|
+
export { barChartProps } from "./bar-chart.js";
|
|
47
|
+
export type { BarChartProps } from "./bar-chart.js";
|
|
48
|
+
|
|
49
|
+
export { cellGridProps } from "./cell-grid.js";
|
|
50
|
+
export type { CellGridProps } from "./cell-grid.js";
|
package/dist/middleware.d.ts
DELETED
package/dist/middleware.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type CSSProperties } from "react";
|
|
2
|
-
import type { PaletteColor } from "@farcaster/snap";
|
|
3
|
-
/**
|
|
4
|
-
* CSS variables so Neynar controls (`bg-primary`, `data-checked:bg-primary`, etc.)
|
|
5
|
-
* use the snap `theme.accent` inside json-render catalog components.
|
|
6
|
-
*/
|
|
7
|
-
export declare function useSnapAccentScopeStyle(): CSSProperties;
|
|
8
|
-
/** Active snap palette table for the current docs shell theme. */
|
|
9
|
-
export declare function useSnapPalette(): {
|
|
10
|
-
hex: (name: string) => string;
|
|
11
|
-
map: Record<PaletteColor, string>;
|
|
12
|
-
theme: "light" | "dark";
|
|
13
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { useStateStore } from "@json-render/react";
|
|
4
|
-
import { PALETTE_DARK_HEX, PALETTE_LIGHT_HEX } from "@farcaster/snap";
|
|
5
|
-
import { useColorMode } from "@neynar/ui/color-mode";
|
|
6
|
-
import { resolveSnapPaletteHex } from "../lib/resolve-palette-hex.js";
|
|
7
|
-
import { snapPreviewPrimaryCssProperties } from "../lib/preview-primary-css.js";
|
|
8
|
-
import { useSnapPreviewPageAccent } from "../accent-context.js";
|
|
9
|
-
/**
|
|
10
|
-
* CSS variables so Neynar controls (`bg-primary`, `data-checked:bg-primary`, etc.)
|
|
11
|
-
* use the snap `theme.accent` inside json-render catalog components.
|
|
12
|
-
*/
|
|
13
|
-
export function useSnapAccentScopeStyle() {
|
|
14
|
-
const { get } = useStateStore();
|
|
15
|
-
const { mode } = useColorMode();
|
|
16
|
-
const pageAccent = useSnapPreviewPageAccent();
|
|
17
|
-
const fromState = get("/theme/accent");
|
|
18
|
-
const accentRaw = (typeof pageAccent === "string" && pageAccent.length > 0
|
|
19
|
-
? pageAccent
|
|
20
|
-
: fromState) ?? undefined;
|
|
21
|
-
const accentName = typeof accentRaw === "string" && accentRaw.length > 0
|
|
22
|
-
? accentRaw
|
|
23
|
-
: "purple";
|
|
24
|
-
return useMemo(() => snapPreviewPrimaryCssProperties(accentName, mode), [accentName, mode]);
|
|
25
|
-
}
|
|
26
|
-
/** Active snap palette table for the current docs shell theme. */
|
|
27
|
-
export function useSnapPalette() {
|
|
28
|
-
const { mode } = useColorMode();
|
|
29
|
-
const map = mode === "dark" ? PALETTE_DARK_HEX : PALETTE_LIGHT_HEX;
|
|
30
|
-
const hex = (name) => resolveSnapPaletteHex(name, mode);
|
|
31
|
-
return { hex, map, theme: mode };
|
|
32
|
-
}
|
package/src/middleware.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { useMemo, type CSSProperties } from "react";
|
|
4
|
-
import { useStateStore } from "@json-render/react";
|
|
5
|
-
import type { PaletteColor } from "@farcaster/snap";
|
|
6
|
-
import { PALETTE_DARK_HEX, PALETTE_LIGHT_HEX } from "@farcaster/snap";
|
|
7
|
-
import { useColorMode } from "@neynar/ui/color-mode";
|
|
8
|
-
import { resolveSnapPaletteHex } from "../lib/resolve-palette-hex";
|
|
9
|
-
import { snapPreviewPrimaryCssProperties } from "../lib/preview-primary-css";
|
|
10
|
-
import { useSnapPreviewPageAccent } from "../accent-context";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* CSS variables so Neynar controls (`bg-primary`, `data-checked:bg-primary`, etc.)
|
|
14
|
-
* use the snap `theme.accent` inside json-render catalog components.
|
|
15
|
-
*/
|
|
16
|
-
export function useSnapAccentScopeStyle(): CSSProperties {
|
|
17
|
-
const { get } = useStateStore();
|
|
18
|
-
const { mode } = useColorMode();
|
|
19
|
-
const pageAccent = useSnapPreviewPageAccent();
|
|
20
|
-
const fromState = get("/theme/accent");
|
|
21
|
-
const accentRaw =
|
|
22
|
-
(typeof pageAccent === "string" && pageAccent.length > 0
|
|
23
|
-
? pageAccent
|
|
24
|
-
: fromState) ?? undefined;
|
|
25
|
-
const accentName =
|
|
26
|
-
typeof accentRaw === "string" && accentRaw.length > 0
|
|
27
|
-
? accentRaw
|
|
28
|
-
: "purple";
|
|
29
|
-
return useMemo(
|
|
30
|
-
() => snapPreviewPrimaryCssProperties(accentName, mode),
|
|
31
|
-
[accentName, mode],
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** Active snap palette table for the current docs shell theme. */
|
|
36
|
-
export function useSnapPalette(): {
|
|
37
|
-
hex: (name: string) => string;
|
|
38
|
-
map: Record<PaletteColor, string>;
|
|
39
|
-
theme: "light" | "dark";
|
|
40
|
-
} {
|
|
41
|
-
const { mode } = useColorMode();
|
|
42
|
-
const map = mode === "dark" ? PALETTE_DARK_HEX : PALETTE_LIGHT_HEX;
|
|
43
|
-
const hex = (name: string) => resolveSnapPaletteHex(name, mode);
|
|
44
|
-
return { hex, map, theme: mode };
|
|
45
|
-
}
|