@gradeui/ui 1.3.0 → 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.
@@ -4,7 +4,7 @@ import: "@gradeui/ui"
4
4
  props:
5
5
  - type: "none" | "solid" | "gradient" | "image" | "video" | "shader" — which paint to render (required)
6
6
  - color?: string — solid fill; a token name (`primary`, `card`, `muted`, `accent`, `secondary`, `destructive`, `background`, `transparent`) or any CSS colour
7
- - gradient?: { from?; via?; to?; angle? } — gradient stops (token names or CSS colours) + angle in degrees (default 135)
7
+ - gradient?: { from?; via?; to?; angle?; shape?; at?; size? } — stops are token names or CSS colours. shape: "linear" (default, uses `angle`, default 135°) | "radial" (uses `at` — CSS position like "top" / "30% 20%", default "center" — and optional `size` like "45rem 50rem", default farthest-corner)
8
8
  - src?: string — image or video URL
9
9
  - fit?: "cover" | "contain" | "fill" | "none" — object-fit for image/video (default "cover")
10
10
  - position?: string — CSS object/background position (default "center")
@@ -54,11 +54,24 @@ notes: |
54
54
  ### Type cheat-sheet
55
55
 
56
56
  - solid — `color` (token or CSS colour). Cheapest.
57
- - gradient — `gradient={{ from, via?, to, angle }}`. Tokens get wrapped in oklch() automatically.
57
+ - gradient — `gradient={{ from, via?, to, angle }}` for linear;
58
+ `gradient={{ shape: "radial", at: "top", from, to }}` for a radial
59
+ glow/wash. Tokens get wrapped in oklch() automatically.
58
60
  - image — `src` + `fit` / `position`; set `repeat` (+ `tileSize`) for a tiled texture.
59
61
  - video — `src` (autoplays muted + looped + inline).
60
62
  - shader — `preset` OR `fragmentShader`, + `palette` / `postPreset`. Delegates to ThreeScene.
61
63
 
64
+ Anti-patterns to avoid:
65
+
66
+ - DO NOT build gradients with arbitrary-value Tailwind classes —
67
+ `bg-[radial-gradient(45rem_50rem_at_top,theme(colors.indigo.50),white)]`
68
+ renders NOTHING in the Studio preview (no runtime Tailwind compiler) and
69
+ `theme(colors.*)` colours ignore the active Grade theme. Use
70
+ `type="gradient"` with token stops instead — themeable, and it always renders.
71
+ - DO NOT hand-roll `style={{ backgroundImage: "linear-gradient(…)" }}` on the
72
+ frame itself when a BackgroundFill child does the same job — the fill layer
73
+ keeps the paint selectable/editable as a Fill in Studio's inspector.
74
+
62
75
  `opacity` + `blendMode` apply to every type — the same two controls as
63
76
  the inspector's Blending section, so a loud shader/image can be dialled
64
77
  back to a subtle wash behind text.
@@ -92,6 +105,19 @@ notes: |
92
105
  </Card>
93
106
  ```
94
107
 
108
+ ```jsx
109
+ // Radial glow from the top of a hero — the token-true version of the
110
+ // classic `radial-gradient(45rem 50rem at top, indigo-50, white)` wash.
111
+ <section className="relative overflow-hidden">
112
+ <BackgroundFill
113
+ type="gradient"
114
+ gradient={{ shape: "radial", at: "top", size: "45rem 50rem", from: "primary", to: "background" }}
115
+ opacity={0.2}
116
+ />
117
+ <div className="relative z-10 py-24 text-center">…hero content…</div>
118
+ </section>
119
+ ```
120
+
95
121
  ```jsx
96
122
  // Image background, cover-fit, with a blend mode.
97
123
  <div className="relative h-64 overflow-hidden rounded-lg">
@@ -3,9 +3,11 @@ name: Logo
3
3
  import: "@gradeui/ui"
4
4
  subcomponents: []
5
5
  props:
6
- - sources: LogoSources (required) — artwork keyed by lockup then appearance:
6
+ - sources?: LogoSources — artwork keyed by lockup then appearance:
7
7
  { square?: { light?, dark?, mono? }, horizontal?: {...}, icon?: {...} }.
8
- Each slot is any node (inline <svg>, <img>, component).
8
+ Each slot is any node (inline <svg>, <img>, component). Omit entirely
9
+ and a neutral "Logo" placeholder renders (use this in prototypes
10
+ before real artwork exists).
9
11
  - lockup?: "square" | "horizontal" | "icon" (default "horizontal")
10
12
  - mode?: "light" | "dark" (default "light") — the background the logo sits on
11
13
  - mono?: boolean (default false) — use the single-colour artwork (inherits currentColor)
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: ScreenAnimator
3
+ import: "@gradeui/ui"
4
+ subcomponents: []
5
+ props:
6
+ - shots?: Array<{ zoom?, cx?, cy?, hold?, trans?, label? }> — the tour. Each
7
+ shot is a zoom (1 = fit, >1 push in), focal point cx/cy (0..1 fractions of
8
+ the content), hold (ms dwell), trans (ms glide-in), and a caption label.
9
+ Omit for a static framed view.
10
+ - autoplay?: boolean (default true)
11
+ - loop?: boolean (default true) — fly in → shots → back to start → exit → repeat
12
+ - controls?: boolean (default true) — play / pause / restart transport
13
+ - spotlight?: boolean (default false) — opt in to dim the edges (vignette) when pushed in
14
+ - cursor?: boolean (default true) — synthetic cursor pulse on detail shots
15
+ - enter?: boolean (default true) — fly in from offscreen on start
16
+ - stage?: string — CSS background of the stage behind the screen (default dark)
17
+ - backdrop?: React.ReactNode — a live layer behind the content (image, gradient, or a <ThreeScene> shader)
18
+ - className?: string
19
+ - children: React.ReactNode (the screen to animate)
20
+ when_to_use: Wrap ANY screen or section in a directed camera — a "live demo
21
+ director". Give it a list of shots and it tours them (zoom + pan) over the
22
+ live, still-interactive content, with a focus spotlight, captions, a synthetic
23
+ cursor, and play/pause. Use it to turn a built screen into an auto-playing
24
+ product demo (embed it, or drop it on a marketing page). It's the live,
25
+ editable, re-renderable answer to a screen-recording video.
26
+ composes_with: [AppShell, ThreeScene, Card, Grid, the whole component set (it wraps a screen)]
27
+ aliases: [screen animator, camera, camera tour, director, demo, product demo, zoom pan, spotlight, ken burns, presenter]
28
+ ---
29
+
30
+ ```jsx
31
+ // Wrap a live screen; the camera tours the shots and loops.
32
+ <ScreenAnimator
33
+ shots={[
34
+ { zoom: 1, cx: 0.5, cy: 0.5, hold: 2400, label: "Overview" },
35
+ { zoom: 2.4, cx: 0.2, cy: 0.34, hold: 2600, label: "Revenue up 24%" },
36
+ { zoom: 1.8, cx: 0.5, cy: 0.6, hold: 2800, label: "Pipeline" },
37
+ ]}
38
+ backdrop={<ThreeScene preset="aurora" />}
39
+ >
40
+ <Dashboard />
41
+ </ScreenAnimator>
42
+ ```
43
+
44
+ ### Anti-patterns
45
+
46
+ DO NOT use it as a layout wrapper — it positions `absolute inset-0` and takes
47
+ over the frame. It's for a whole screen/section you want to direct, not a div.
48
+
49
+ DO NOT hand-tune `trans`/`hold` per shot unless you need to — the defaults
50
+ (soft settle on overview, snappier push on detail) read well. `cx`/`cy` are the
51
+ knobs that matter; they're fractions of the screen (0 = left/top, 0.5 = centre).
52
+
53
+ DO NOT worry about reduced motion — it settles on the starter frame and stops
54
+ moving automatically under `prefers-reduced-motion`.