@vibes.diy/prompts 14.3.202 → 14.3.204
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/llms/access.md +4 -4
- package/llms/backend.md +1 -1
- package/llms/blockly.md +2 -2
- package/llms/bluesky.md +1 -1
- package/llms/board-games.md +95 -1
- package/llms/calendar.md +1 -1
- package/llms/callai.md +4 -4
- package/llms/connections.md +1 -1
- package/llms/create-vibe.md +3 -3
- package/llms/fireproof.md +7 -7
- package/llms/github.md +6 -2
- package/llms/image-gen.md +2 -2
- package/llms/index.d.ts +28 -28
- package/llms/index.js +84 -84
- package/llms/index.js.map +1 -1
- package/llms/maps.js +14 -2
- package/llms/maps.js.map +1 -1
- package/llms/maps.md +212 -9
- package/llms/match-style.md +1 -1
- package/llms/motion.md +7 -7
- package/llms/p5.md +1 -1
- package/llms/physics.md +2 -2
- package/llms/reskin.js +8 -1
- package/llms/reskin.js.map +1 -1
- package/llms/reskin.md +99 -20
- package/llms/richtext.md +5 -5
- package/llms/spotify.md +1 -1
- package/llms/stripe-subscriptions.md +1 -1
- package/llms/stripe.md +3 -3
- package/llms/strudel.md +3 -3
- package/llms/three-js.md +4 -4
- package/llms/touch-games.js +1 -1
- package/llms/touch-games.js.map +1 -1
- package/llms/touch-games.md +3 -3
- package/llms/ui-blog.d.ts +2 -0
- package/llms/ui-blog.js +7 -0
- package/llms/ui-blog.js.map +1 -0
- package/llms/{pouf-blog.md → ui-blog.md} +10 -10
- package/llms/ui-booking.d.ts +2 -0
- package/llms/ui-booking.js +7 -0
- package/llms/ui-booking.js.map +1 -0
- package/llms/{pouf-booking.md → ui-booking.md} +8 -8
- package/llms/ui-calendar.d.ts +2 -0
- package/llms/ui-calendar.js +7 -0
- package/llms/ui-calendar.js.map +1 -0
- package/llms/{pouf-calendar.md → ui-calendar.md} +5 -5
- package/llms/ui-chat.d.ts +2 -0
- package/llms/ui-chat.js +7 -0
- package/llms/ui-chat.js.map +1 -0
- package/llms/{pouf-chat.md → ui-chat.md} +4 -4
- package/llms/ui-contact.d.ts +2 -0
- package/llms/ui-contact.js +7 -0
- package/llms/ui-contact.js.map +1 -0
- package/llms/{pouf-contact.md → ui-contact.md} +7 -7
- package/llms/ui-course.d.ts +2 -0
- package/llms/ui-course.js +7 -0
- package/llms/ui-course.js.map +1 -0
- package/llms/{pouf-course.md → ui-course.md} +9 -9
- package/llms/ui-crm.d.ts +2 -0
- package/llms/ui-crm.js +7 -0
- package/llms/ui-crm.js.map +1 -0
- package/llms/{pouf-crm.md → ui-crm.md} +5 -5
- package/llms/ui-dashboard.d.ts +2 -0
- package/llms/ui-dashboard.js +7 -0
- package/llms/ui-dashboard.js.map +1 -0
- package/llms/{pouf-dashboard.md → ui-dashboard.md} +7 -7
- package/llms/ui-editorial.d.ts +2 -0
- package/llms/ui-editorial.js +7 -0
- package/llms/ui-editorial.js.map +1 -0
- package/llms/{pouf-editorial.md → ui-editorial.md} +5 -5
- package/llms/ui-event.d.ts +2 -0
- package/llms/ui-event.js +7 -0
- package/llms/ui-event.js.map +1 -0
- package/llms/{pouf-event.md → ui-event.md} +5 -5
- package/llms/ui-feed.d.ts +2 -0
- package/llms/ui-feed.js +7 -0
- package/llms/ui-feed.js.map +1 -0
- package/llms/{pouf-feed.md → ui-feed.md} +5 -5
- package/llms/ui-game.d.ts +2 -0
- package/llms/ui-game.js +7 -0
- package/llms/ui-game.js.map +1 -0
- package/llms/{pouf-game.md → ui-game.md} +6 -6
- package/llms/ui-inbox.d.ts +2 -0
- package/llms/ui-inbox.js +7 -0
- package/llms/ui-inbox.js.map +1 -0
- package/llms/{pouf-inbox.md → ui-inbox.md} +5 -5
- package/llms/ui-inventory.d.ts +2 -0
- package/llms/ui-inventory.js +7 -0
- package/llms/ui-inventory.js.map +1 -0
- package/llms/{pouf-inventory.md → ui-inventory.md} +5 -5
- package/llms/ui-kanban.d.ts +2 -0
- package/llms/ui-kanban.js +7 -0
- package/llms/ui-kanban.js.map +1 -0
- package/llms/{pouf-kanban.md → ui-kanban.md} +5 -5
- package/llms/ui-landing.d.ts +2 -0
- package/llms/ui-landing.js +7 -0
- package/llms/ui-landing.js.map +1 -0
- package/llms/{pouf-landing.md → ui-landing.md} +6 -6
- package/llms/ui-login.d.ts +2 -0
- package/llms/ui-login.js +7 -0
- package/llms/ui-login.js.map +1 -0
- package/llms/{pouf-login.md → ui-login.md} +7 -7
- package/llms/ui-music.d.ts +2 -0
- package/llms/ui-music.js +7 -0
- package/llms/ui-music.js.map +1 -0
- package/llms/{pouf-music.md → ui-music.md} +6 -6
- package/llms/ui-onboarding.d.ts +2 -0
- package/llms/ui-onboarding.js +7 -0
- package/llms/ui-onboarding.js.map +1 -0
- package/llms/{pouf-onboarding.md → ui-onboarding.md} +5 -5
- package/llms/ui-pricing.d.ts +2 -0
- package/llms/ui-pricing.js +7 -0
- package/llms/ui-pricing.js.map +1 -0
- package/llms/{pouf-pricing.md → ui-pricing.md} +5 -5
- package/llms/ui-profile.d.ts +2 -0
- package/llms/ui-profile.js +7 -0
- package/llms/ui-profile.js.map +1 -0
- package/llms/{pouf-profile.md → ui-profile.md} +4 -4
- package/llms/ui-quiz.d.ts +2 -0
- package/llms/ui-quiz.js +7 -0
- package/llms/ui-quiz.js.map +1 -0
- package/llms/{pouf-quiz.md → ui-quiz.md} +6 -6
- package/llms/ui-settings.d.ts +2 -0
- package/llms/ui-settings.js +7 -0
- package/llms/ui-settings.js.map +1 -0
- package/llms/{pouf-settings.md → ui-settings.md} +5 -5
- package/llms/ui-storefront.d.ts +2 -0
- package/llms/ui-storefront.js +7 -0
- package/llms/ui-storefront.js.map +1 -0
- package/llms/{pouf-storefront.md → ui-storefront.md} +9 -9
- package/llms/ui-support.d.ts +2 -0
- package/llms/ui-support.js +7 -0
- package/llms/ui-support.js.map +1 -0
- package/llms/{pouf-support.md → ui-support.md} +5 -5
- package/llms/ui-testimonials.d.ts +2 -0
- package/llms/ui-testimonials.js +7 -0
- package/llms/ui-testimonials.js.map +1 -0
- package/llms/{pouf-testimonials.md → ui-testimonials.md} +6 -6
- package/llms/ui-todo.d.ts +2 -0
- package/llms/ui-todo.js +7 -0
- package/llms/ui-todo.js.map +1 -0
- package/llms/{pouf-todo.md → ui-todo.md} +5 -5
- package/llms/ui-weather.d.ts +2 -0
- package/llms/ui-weather.js +7 -0
- package/llms/ui-weather.js.map +1 -0
- package/llms/{pouf-weather.md → ui-weather.md} +5 -5
- package/llms/use-vibe.md +4 -4
- package/llms/use-viewer.md +5 -5
- package/llms/voxel.md +1 -1
- package/llms/web-audio.md +49 -26
- package/llms/worlds.md +3 -3
- package/llms/youtube.md +1 -1
- package/package.json +5 -5
- package/system-prompt-initial-instant.md +3 -3
- package/system-prompt.md +3 -3
- package/themes/colorsets.js +7 -7
- package/themes/colorsets.js.map +1 -1
- package/themes/looks/pouf/brief.md +87 -85
- package/themes/looks/pouf/catalog.generated.d.ts +1 -1
- package/themes/looks/pouf/catalog.generated.js +47 -17
- package/themes/looks/pouf/catalog.generated.js.map +1 -1
- package/themes/looks/pouf/variety.js +4 -4
- package/themes/looks/pouf/variety.js.map +1 -1
- package/llms/pouf-blog.d.ts +0 -2
- package/llms/pouf-blog.js +0 -6
- package/llms/pouf-blog.js.map +0 -1
- package/llms/pouf-booking.d.ts +0 -2
- package/llms/pouf-booking.js +0 -6
- package/llms/pouf-booking.js.map +0 -1
- package/llms/pouf-calendar.d.ts +0 -2
- package/llms/pouf-calendar.js +0 -6
- package/llms/pouf-calendar.js.map +0 -1
- package/llms/pouf-chat.d.ts +0 -2
- package/llms/pouf-chat.js +0 -6
- package/llms/pouf-chat.js.map +0 -1
- package/llms/pouf-contact.d.ts +0 -2
- package/llms/pouf-contact.js +0 -6
- package/llms/pouf-contact.js.map +0 -1
- package/llms/pouf-course.d.ts +0 -2
- package/llms/pouf-course.js +0 -6
- package/llms/pouf-course.js.map +0 -1
- package/llms/pouf-crm.d.ts +0 -2
- package/llms/pouf-crm.js +0 -6
- package/llms/pouf-crm.js.map +0 -1
- package/llms/pouf-dashboard.d.ts +0 -2
- package/llms/pouf-dashboard.js +0 -6
- package/llms/pouf-dashboard.js.map +0 -1
- package/llms/pouf-editorial.d.ts +0 -2
- package/llms/pouf-editorial.js +0 -6
- package/llms/pouf-editorial.js.map +0 -1
- package/llms/pouf-event.d.ts +0 -2
- package/llms/pouf-event.js +0 -6
- package/llms/pouf-event.js.map +0 -1
- package/llms/pouf-feed.d.ts +0 -2
- package/llms/pouf-feed.js +0 -6
- package/llms/pouf-feed.js.map +0 -1
- package/llms/pouf-game.d.ts +0 -2
- package/llms/pouf-game.js +0 -6
- package/llms/pouf-game.js.map +0 -1
- package/llms/pouf-inbox.d.ts +0 -2
- package/llms/pouf-inbox.js +0 -6
- package/llms/pouf-inbox.js.map +0 -1
- package/llms/pouf-inventory.d.ts +0 -2
- package/llms/pouf-inventory.js +0 -6
- package/llms/pouf-inventory.js.map +0 -1
- package/llms/pouf-kanban.d.ts +0 -2
- package/llms/pouf-kanban.js +0 -6
- package/llms/pouf-kanban.js.map +0 -1
- package/llms/pouf-landing.d.ts +0 -2
- package/llms/pouf-landing.js +0 -6
- package/llms/pouf-landing.js.map +0 -1
- package/llms/pouf-login.d.ts +0 -2
- package/llms/pouf-login.js +0 -6
- package/llms/pouf-login.js.map +0 -1
- package/llms/pouf-music.d.ts +0 -2
- package/llms/pouf-music.js +0 -6
- package/llms/pouf-music.js.map +0 -1
- package/llms/pouf-onboarding.d.ts +0 -2
- package/llms/pouf-onboarding.js +0 -6
- package/llms/pouf-onboarding.js.map +0 -1
- package/llms/pouf-pricing.d.ts +0 -2
- package/llms/pouf-pricing.js +0 -6
- package/llms/pouf-pricing.js.map +0 -1
- package/llms/pouf-profile.d.ts +0 -2
- package/llms/pouf-profile.js +0 -6
- package/llms/pouf-profile.js.map +0 -1
- package/llms/pouf-quiz.d.ts +0 -2
- package/llms/pouf-quiz.js +0 -6
- package/llms/pouf-quiz.js.map +0 -1
- package/llms/pouf-settings.d.ts +0 -2
- package/llms/pouf-settings.js +0 -6
- package/llms/pouf-settings.js.map +0 -1
- package/llms/pouf-storefront.d.ts +0 -2
- package/llms/pouf-storefront.js +0 -6
- package/llms/pouf-storefront.js.map +0 -1
- package/llms/pouf-support.d.ts +0 -2
- package/llms/pouf-support.js +0 -6
- package/llms/pouf-support.js.map +0 -1
- package/llms/pouf-testimonials.d.ts +0 -2
- package/llms/pouf-testimonials.js +0 -6
- package/llms/pouf-testimonials.js.map +0 -1
- package/llms/pouf-todo.d.ts +0 -2
- package/llms/pouf-todo.js +0 -6
- package/llms/pouf-todo.js.map +0 -1
- package/llms/pouf-weather.d.ts +0 -2
- package/llms/pouf-weather.js +0 -6
- package/llms/pouf-weather.js.map +0 -1
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Music
|
|
2
2
|
|
|
3
3
|
A player screen for a short list of tracks: a band's demos, a choir's rehearsal parts, a podcast's episodes, a class's listening list. Reach for it whenever the app's core is picking something from a queue and moving through it with play, skip and a scrubber. The track list stays inline in the code and playback lives in the page; each like is its own document per person and track, so a visitor's favourites are still marked on the next visit and on every device, and the like count is real.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
9
|
-
One view with one job: choose a track and move through it. A `Card` holds the player: a decorative `orange` `
|
|
9
|
+
One view with one job: choose a track and move through it. A `Card` holds the player: a decorative `orange` `IconTile` as the cover, a `Badge` for the transport's state (`up` playing, `idle` paused), the title as the `Heading` with the artist and like count in muted `Text`, a quiet heart `IconButton` to like the track, a `Slider` scrubber with numeric elapsed and total times, and the transport row of quiet `IconButton`s (previous, play/pause, next). The scrubber's filled range is the view's one lead mark: `Slider` always paints its range in the lead colour and takes no `tone`, so every button beside it stays quiet. Nothing plays until the person presses play, and the example carries no audio of its own: the track list is placeholder metadata and the scrubber is driven by a timer, ready to be wired to the app's own files. Under the player an `Eyebrow` heads the queue, one clickable `RowCard` per track with its title and artist in `Text`, a heart `Icon` on the visitor's liked tracks and the length in numeric muted `Text`. Liking waits on its `can` verdict from `useVibe("music")`, the database the likes live in: a `Skeleton` inside an `aria-busy` wrapper while it resolves, the heart wired to `useViewer().requestLogin()` with the label `Sign in to like` for a visitor who has not signed in, and a sentence in the app's own words when likes are closed; unliking waits on `can.delete` of the visitor's own like.
|
|
10
10
|
|
|
11
11
|
### `App.jsx`
|
|
12
12
|
```jsx
|
|
13
13
|
import React, { useEffect, useState } from "react";
|
|
14
14
|
import { useFireproof } from "use-fireproof";
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
|
-
import { Badge,
|
|
17
|
-
import { Slider } from "@vibes.diy/
|
|
16
|
+
import { Badge, IconTile, Card, Eyebrow, Heading, Icon, IconButton, Row, RowCard, Skeleton, Spacer, Stack, Text } from "@vibes.diy/ui";
|
|
17
|
+
import { Slider } from "@vibes.diy/ui/interactive";
|
|
18
18
|
|
|
19
19
|
// Placeholder metadata: swap in the app's own tracks. No audio ships with this example.
|
|
20
20
|
const QUEUE = [
|
|
@@ -110,7 +110,7 @@ export default function App() {
|
|
|
110
110
|
<Card>
|
|
111
111
|
<Stack gap={5}>
|
|
112
112
|
<Row justify="between" align="top">
|
|
113
|
-
<
|
|
113
|
+
<IconTile icon="music" tone="orange" size="lg" />
|
|
114
114
|
<Badge tone={playing ? "up" : "idle"}>{playing ? "Playing" : "Paused"}</Badge>
|
|
115
115
|
</Row>
|
|
116
116
|
<Row justify="between" align="top" wrap={false}>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-onboarding.js","sourceRoot":"","sources":["../../jsr/llms/ui-onboarding.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,CAAC,iBAAiB,CAAC;IAC5B,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,kEAAkE;CAChF,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Onboarding
|
|
2
2
|
|
|
3
3
|
A short setup wizard that walks a newcomer through a few questions, one at a time: a study group's "who are you and which team", a freelance tool's business name and plan, a club's first-visit questions. Reach for it whenever the app needs a handful of answers before it is useful and they read better as steps than as one long form. The answers persist as the person's own document, so a finished setup stays finished and can be revisited and changed later.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ One `Card` with one job per step. An `Eyebrow` names the step ("Step 2 of 3 · W
|
|
|
13
13
|
import React, { useState } from "react";
|
|
14
14
|
import { useFireproof } from "use-fireproof";
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
|
-
import { Button, Card, Eyebrow, Field, Heading, Input, Row, Skeleton, Spacer, Stack, Text } from "@vibes.diy/
|
|
17
|
-
import { Progress, RadioGroup, Toaster, toast } from "@vibes.diy/
|
|
16
|
+
import { Button, Card, Eyebrow, Field, Heading, Input, Row, Skeleton, Spacer, Stack, Text } from "@vibes.diy/ui";
|
|
17
|
+
import { Progress, RadioGroup, Toaster, toast } from "@vibes.diy/ui/interactive";
|
|
18
18
|
|
|
19
19
|
const STEPS = ["About you", "Workspace", "How you'll use it"];
|
|
20
20
|
const PLANS = [
|
|
@@ -208,7 +208,7 @@ export default function App() {
|
|
|
208
208
|
</form>
|
|
209
209
|
)}
|
|
210
210
|
</Card>
|
|
211
|
-
<div className="
|
|
211
|
+
<div className="ui-toasts">
|
|
212
212
|
<Toaster />
|
|
213
213
|
</div>
|
|
214
214
|
</main>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-pricing.js","sourceRoot":"","sources":["../../jsr/llms/ui-pricing.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,CAAC,cAAc,CAAC;IACzB,KAAK,EAAE,eAAe;IACtB,WAAW,EAAE,8EAA8E;CAC5F,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Pricing
|
|
2
2
|
|
|
3
3
|
A plans page that compares a few tiers and lets someone ask for one: a yoga studio's memberships, a tutor's packages, a club's season passes, a freelancer's retainers. Reach for it whenever the app's core is "here is what each option costs, pick one". The plans themselves stay inline in the code. Picking a paid plan saves a request document, so the person sees what they asked for on the next visit and the app keeps a record of who asked for what; the owner's view of those requests is a short addition sketched under Adapting. It takes no payment and pretends to take none: settling up is arranged after the request, or by a separate payment integration.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ One view with one job: compare and choose. An `Eyebrow` and a `Heading` with one
|
|
|
13
13
|
import React, { useState } from "react";
|
|
14
14
|
import { useFireproof } from "use-fireproof";
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
|
-
import { Badge, Button, Card, Eyebrow, Grid, Heading, Highlight, Icon, Row, Segmented, Skeleton, Stack, Text } from "@vibes.diy/
|
|
17
|
-
import { Toaster, toast } from "@vibes.diy/
|
|
16
|
+
import { Badge, Button, Card, Eyebrow, Grid, Heading, Highlight, Icon, Row, Segmented, Skeleton, Stack, Text } from "@vibes.diy/ui";
|
|
17
|
+
import { Toaster, toast } from "@vibes.diy/ui/interactive";
|
|
18
18
|
|
|
19
19
|
const PLANS = [
|
|
20
20
|
{ id: "taster", name: "Taster", monthly: 0, blurb: "Try a class before you choose.", features: ["Your first class free", "Mat hire included"] },
|
|
@@ -174,7 +174,7 @@ export default function App() {
|
|
|
174
174
|
No card needed here. Choosing a plan sends us a request, and we arrange payment with you before it starts.
|
|
175
175
|
</Text>
|
|
176
176
|
</Stack>
|
|
177
|
-
<div className="
|
|
177
|
+
<div className="ui-toasts">
|
|
178
178
|
<Toaster />
|
|
179
179
|
</div>
|
|
180
180
|
</main>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-profile.js","sourceRoot":"","sources":["../../jsr/llms/ui-profile.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,CAAC,cAAc,CAAC;IACzB,KAAK,EAAE,eAAe;IACtB,WAAW,EAAE,gEAAgE;CAC9E,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Profile
|
|
2
2
|
|
|
3
3
|
A public page about one maker, coach or group that visitors can follow: an illustrator's page, a running coach's profile, a band's home, a club captain's corner. Reach for it whenever the app's core is "who is this, what have they made, and how do I keep up". The profile's own words and posts stay inline in the code; each follow is its own document, so the follower count is real, it survives the next visit, and two people following at once both count.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ One view with one job: get to know the person, then follow. A `Card` holds the h
|
|
|
13
13
|
import React, { useState } from "react";
|
|
14
14
|
import { useFireproof } from "use-fireproof";
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
|
-
import { Badge, Button, Card, Empty, Eyebrow, Heading, Metric, Row, RowCard, Skeleton, Stack, Text } from "@vibes.diy/
|
|
17
|
-
import { Avatar, Tabs } from "@vibes.diy/
|
|
16
|
+
import { Badge, Button, Card, Empty, Eyebrow, Heading, Metric, Row, RowCard, Skeleton, Stack, Text } from "@vibes.diy/ui";
|
|
17
|
+
import { Avatar, Tabs } from "@vibes.diy/ui/interactive";
|
|
18
18
|
|
|
19
19
|
const PROFILE = {
|
|
20
20
|
name: "Mira Okafor",
|
package/llms/ui-quiz.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-quiz.js","sourceRoot":"","sources":["../../jsr/llms/ui-quiz.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,YAAY,GAAc;IACrC,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,CAAC,WAAW,CAAC;IACtB,KAAK,EAAE,YAAY;IACnB,WAAW,EAAE,gFAAgF;CAC9F,CAAC"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Quiz
|
|
2
2
|
|
|
3
3
|
A short multiple-choice quiz that keeps score: an astronomy club's star-chart check, a refresher round before a test, a pub quiz warm-up, a training check for new staff. Reach for it when the app asks a handful of questions one at a time, says right or wrong after each answer, ends on a score and lets people come back to beat it. Each finished attempt someone saves is its own document, so their past scores are there on the next visit and on any device.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
9
|
-
One view with one job: answer the questions, then keep the score. A `Heading` and a muted line open the page. The quiz sits on a `Card`: an `Eyebrow` with the question number beside an `info` `Badge` counting correct answers so far (it steps aside on the result, which states the score once), and a `Progress` (`info`) across the top. Each question is a `Heading level={2}` over a `RadioGroup`; `Check answer` is the view's one lead, then the answer shows as a `Badge` (`up` right, `down` wrong) with the right option in muted `Text`, and the lead becomes `Next question`. The result swaps in
|
|
9
|
+
One view with one job: answer the questions, then keep the score. A `Heading` and a muted line open the page. The quiz sits on a `Card`: an `Eyebrow` with the question number beside an `info` `Badge` counting correct answers so far (it steps aside on the result, which states the score once), and a `Progress` (`info`) across the top. Each question is a `Heading level={2}` over a `RadioGroup`; `Check answer` is the view's one lead, then the answer shows as a `Badge` (`up` right, `down` wrong) with the right option in muted `Text`, and the lead becomes `Next question`. The result swaps in an `IconTile` (`up` for a pass, `warn` otherwise), the score and a recap of every question with its own `up` or `down` `Badge`. `Save score` is then the lead, with `loading` while the write lands, beside a quiet `Play again`. A signed-in person's earlier attempts sit below as `RowCard`s, newest first, each with a `Badge` toned by how it went. Saving waits on its `can` verdict from `useVibe("quiz")`, the database the attempts live in: a `Skeleton` inside an `aria-busy` wrapper while it resolves, a `Sign in to save your score` lead wired to `useViewer().requestLogin()` for a visitor who has not signed in, and a sentence in the app's own words when saving is closed. Anyone can take the quiz without signing in; the attempt lives only in the page until it is saved, and the copy says so.
|
|
10
10
|
|
|
11
11
|
### `App.jsx`
|
|
12
12
|
```jsx
|
|
13
13
|
import React, { useState } from "react";
|
|
14
14
|
import { useFireproof } from "use-fireproof";
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
|
-
import { Badge,
|
|
17
|
-
import { Progress, RadioGroup } from "@vibes.diy/
|
|
16
|
+
import { Badge, IconTile, Button, Card, Eyebrow, Heading, Row, RowCard, Skeleton, Stack, Text } from "@vibes.diy/ui";
|
|
17
|
+
import { Progress, RadioGroup } from "@vibes.diy/ui/interactive";
|
|
18
18
|
|
|
19
19
|
const QUIZ_ID = "houseplants";
|
|
20
20
|
const QUESTIONS = [
|
|
@@ -177,7 +177,7 @@ export default function App() {
|
|
|
177
177
|
{done ? (
|
|
178
178
|
<Stack gap={4}>
|
|
179
179
|
<Row gap={3} wrap={false}>
|
|
180
|
-
<
|
|
180
|
+
<IconTile icon={passed ? "trophy" : "flame"} tone={passed ? "up" : "warn"} />
|
|
181
181
|
<Stack gap={1}>
|
|
182
182
|
<Heading level={2}>{score === TOTAL ? "Perfect score!" : passed ? "Nice work" : "Keep practising"}</Heading>
|
|
183
183
|
<Text muted>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-settings.js","sourceRoot":"","sources":["../../jsr/llms/ui-settings.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,gBAAgB,GAAc;IACzC,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC,eAAe,CAAC;IAC1B,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,wDAAwD;CACtE,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Settings
|
|
2
2
|
|
|
3
3
|
A settings screen for each person's own preferences: the display name in a sleep log, reminder emails for a reading log, a compact or comfortable layout, how loud an alert should be. Reach for it whenever the app lets someone tune how it treats them and expects those choices to stick. Each person's settings persist as their own document, so a choice made on the phone is there on the laptop.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ One view with one job: change your settings and save them. An `Eyebrow`, the `He
|
|
|
13
13
|
import React, { useEffect, useState } from "react";
|
|
14
14
|
import { useFireproof } from "use-fireproof";
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
|
-
import { Badge, Button, Card, Eyebrow, Field, Heading, Input, Row, Skeleton, Stack, Text, Textarea } from "@vibes.diy/
|
|
17
|
-
import { RadioGroup, Separator, Slider, Switch, Tabs, Toaster, toast } from "@vibes.diy/
|
|
16
|
+
import { Badge, Button, Card, Eyebrow, Field, Heading, Input, Row, Skeleton, Stack, Text, Textarea } from "@vibes.diy/ui";
|
|
17
|
+
import { RadioGroup, Separator, Slider, Switch, Tabs, Toaster, toast } from "@vibes.diy/ui/interactive";
|
|
18
18
|
|
|
19
19
|
const DEFAULTS = { name: "", bio: "", density: "comfortable", emailNotif: true, pushNotif: false, volume: 60 };
|
|
20
20
|
const KEYS = Object.keys(DEFAULTS);
|
|
@@ -201,7 +201,7 @@ export default function App() {
|
|
|
201
201
|
// Re-keyed when the saved copy first arrives, so the form starts from it.
|
|
202
202
|
<SettingsForm key={saved ? "saved" : "new"} saved={saved} database={database} can={can} me={me} />
|
|
203
203
|
)}
|
|
204
|
-
<div className="
|
|
204
|
+
<div className="ui-toasts">
|
|
205
205
|
<Toaster />
|
|
206
206
|
</div>
|
|
207
207
|
</main>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-storefront.js","sourceRoot":"","sources":["../../jsr/llms/ui-storefront.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,CAAC,iBAAiB,CAAC;IAC5B,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,qEAAqE;CACnF,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Storefront
|
|
2
2
|
|
|
3
3
|
A small shop: product cards to browse, a category filter and a search, a bag that adds things up, and a checkout that places the order. It fits a potter's ceramics, a bakery's preorders, a club's merch table or a school fair's stall. Reach for it whenever the app's core is a short catalogue that people pick from and then order. The catalogue stays inline in the code, and the bag lives in the page while someone shops. Each placed order persists as its own document, so the shop can see what to make and the buyer can see what they ordered. It records orders only; taking payment is a separate integration this block does not pretend to do.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
9
|
-
One view with one job: fill the bag and place the order. A `Navbar` carries the brand and a quiet bag button with a live count, and the `Heading` puts an `orange` `Highlight` on one word beside a muted line. A `Segmented` category filter (`tone="info"`) and a search `Input` in a `Field` sit above a `Grid cols="sidebar"`: on the main side a two-column grid of product `Card`s, each with a decorative `orange` `
|
|
9
|
+
One view with one job: fill the bag and place the order. A `Navbar` carries the brand and a quiet bag button with a live count, and the `Heading` puts an `orange` `Highlight` on one word beside a muted line. A `Segmented` category filter (`tone="info"`) and a search `Input` in a `Field` sit above a `Grid cols="sidebar"`: on the main side a two-column grid of product `Card`s, each with a decorative `orange` `IconTile`, an `info` `Badge` for "New" or "Bestseller", the price in numeric `Text` and a quiet `Add to bag` (an `Empty` stands in when nothing matches); on the side the bag's `Card`, one line per product with its total and `IconButton`s to take one away or add one, then the subtotal, shipping and total. `Place order` is the view's one lead; it shows `loading` while the write lands, and the bag empties only after it does. An order is one document holding a snapshot of each line's name, price and quantity, the totals and the buyer's handle, so a later price change never rewrites an order already placed; the person's own orders list under the bag, each with a `Badge` for its status (`info` received, `warn` ready to collect, `up` collected). Checkout waits on its `can` verdict from `useVibe("shop")`: a `Skeleton` inside an `aria-busy` wrapper while it resolves, a sentence in the app's own words when ordering is closed, and for a visitor who has not signed in a `Sign in to place your order` lead wired to `useViewer().requestLogin()`, with the bag they filled kept in place. Sign-in is required here, unlike a local-first note, because a signed-out write stays on the device until sign-in: an order placed that way would never reach the shop.
|
|
10
10
|
|
|
11
11
|
### `App.jsx`
|
|
12
12
|
```jsx
|
|
@@ -15,7 +15,7 @@ import { useFireproof } from "use-fireproof";
|
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
16
|
import {
|
|
17
17
|
Badge,
|
|
18
|
-
|
|
18
|
+
IconTile,
|
|
19
19
|
Button,
|
|
20
20
|
Card,
|
|
21
21
|
Empty,
|
|
@@ -34,8 +34,8 @@ import {
|
|
|
34
34
|
Spacer,
|
|
35
35
|
Stack,
|
|
36
36
|
Text,
|
|
37
|
-
} from "@vibes.diy/
|
|
38
|
-
import { Separator, Toaster, toast } from "@vibes.diy/
|
|
37
|
+
} from "@vibes.diy/ui";
|
|
38
|
+
import { Separator, Toaster, toast } from "@vibes.diy/ui/interactive";
|
|
39
39
|
|
|
40
40
|
const PRODUCTS = [
|
|
41
41
|
{ id: "mug", name: "Speckled mug", blurb: "Holds a generous coffee, glazed oatmeal.", price: 28, category: "table", icon: "drop", badge: "Bestseller" },
|
|
@@ -133,7 +133,7 @@ export default function App() {
|
|
|
133
133
|
<Navbar
|
|
134
134
|
brand={
|
|
135
135
|
<Row gap={2} wrap={false}>
|
|
136
|
-
<
|
|
136
|
+
<IconTile icon="sparkle" tone="orange" size="sm" />
|
|
137
137
|
<Text>Kiln & Co.</Text>
|
|
138
138
|
</Row>
|
|
139
139
|
}
|
|
@@ -171,7 +171,7 @@ export default function App() {
|
|
|
171
171
|
<Card key={p.id}>
|
|
172
172
|
<Stack gap={3}>
|
|
173
173
|
<Row justify="between" align="top">
|
|
174
|
-
<
|
|
174
|
+
<IconTile icon={p.icon} tone="orange" />
|
|
175
175
|
{p.badge && <Badge tone="info">{p.badge}</Badge>}
|
|
176
176
|
</Row>
|
|
177
177
|
<Stack gap={1}>
|
|
@@ -274,7 +274,7 @@ export default function App() {
|
|
|
274
274
|
</div>
|
|
275
275
|
</Grid>
|
|
276
276
|
</Stack>
|
|
277
|
-
<div className="
|
|
277
|
+
<div className="ui-toasts">
|
|
278
278
|
<Toaster />
|
|
279
279
|
</div>
|
|
280
280
|
</main>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-support.js","sourceRoot":"","sources":["../../jsr/llms/ui-support.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,CAAC,cAAc,CAAC;IACzB,KAAK,EAAE,eAAe;IACtB,WAAW,EAAE,+DAA+D;CAC7E,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Support
|
|
2
2
|
|
|
3
3
|
A help desk where questions come in as tickets and get answered, chased and closed: a small shop's customer questions, an IT volunteer queue, a landlord's repair requests, a club's member help. Reach for it whenever the app's core is requests that each carry a status (open, waiting on the asker, solved) and get worked through by replying. Tickets, their status and every reply persist, so the queue is where it was left on the next visit and for everyone working it.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ Two views, one job each. The queue opens with the `Heading` and a muted count of
|
|
|
13
13
|
import React, { useState } from "react";
|
|
14
14
|
import { useFireproof } from "use-fireproof";
|
|
15
15
|
import { useViewer, useVibe } from "use-vibes";
|
|
16
|
-
import { Badge, Button, Card, Empty, Field, Heading, Icon, IconButton, Input, Row, RowCard, Skeleton, Spacer, Stack, Text, Textarea } from "@vibes.diy/
|
|
17
|
-
import { Checkbox, Dialog, Select, Toaster, toast } from "@vibes.diy/
|
|
16
|
+
import { Badge, Button, Card, Empty, Field, Heading, Icon, IconButton, Input, Row, RowCard, Skeleton, Spacer, Stack, Text, Textarea } from "@vibes.diy/ui";
|
|
17
|
+
import { Checkbox, Dialog, Select, Toaster, toast } from "@vibes.diy/ui/interactive";
|
|
18
18
|
|
|
19
19
|
const STATUS = {
|
|
20
20
|
open: { label: "Open", tone: "info" },
|
|
@@ -313,7 +313,7 @@ export default function App() {
|
|
|
313
313
|
)}
|
|
314
314
|
</Stack>
|
|
315
315
|
)}
|
|
316
|
-
<div className="
|
|
316
|
+
<div className="ui-toasts">
|
|
317
317
|
<Toaster />
|
|
318
318
|
</div>
|
|
319
319
|
</main>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const uiTestimonialsConfig = {
|
|
2
|
+
name: "ui-testimonials",
|
|
3
|
+
aliases: ["pouf-testimonials"],
|
|
4
|
+
label: "Testimonials block",
|
|
5
|
+
description: "Testimonials section with category filter, story carousel and reported outcomes",
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=ui-testimonials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-testimonials.js","sourceRoot":"","sources":["../../jsr/llms/ui-testimonials.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,oBAAoB,GAAc;IAC7C,IAAI,EAAE,iBAAiB;IACvB,OAAO,EAAE,CAAC,mBAAmB,CAAC;IAC9B,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EAAE,iFAAiF;CAC/F,CAAC"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Testimonials
|
|
2
2
|
|
|
3
3
|
A section of client stories: the reviews on a cleaning business's site, quotes from a design studio's clients, what students said about a course, thank-you notes for a wedding band. Reach for it when the app shows a handful of quotes the owner has gathered, one at a time with the outcome each person reported, and lets the reader filter them by kind of work and step through them. The stories are written into the page by the owner, so the block keeps nothing; `## Adapting` covers collecting new ones from visitors.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
9
|
-
One view with one job: read what clients say. An `Eyebrow`, the `Heading` and a muted story count open it, then a `Segmented` filter (`tone="info"`) narrows the stories by service and returns to the first. `Grid cols="sidebar"` sets the quote beside its outcome. The story sits on a tilted `Card`, its quote and attribution inside a polite live region so a screen reader hears each new story (the step buttons stay outside it): a decorative `orange` `
|
|
9
|
+
One view with one job: read what clients say. An `Eyebrow`, the `Heading` and a muted story count open it, then a `Segmented` filter (`tone="info"`) narrows the stories by service and returns to the first. `Grid cols="sidebar"` sets the quote beside its outcome. The story sits on a tilted `Card`, its quote and attribution inside a polite live region so a screen reader hears each new story (the step buttons stay outside it): a decorative `orange` `IconTile` and an `info` `Badge` for the service, the quote as a `Heading level={2}`, the client as an `Avatar` (decorative `orange`, initials) with their name and role in `Text`, and two `IconButton`s to step back and forward. `Next story` is the view's one lead (`variant="solid"`); `Previous story` stays quiet. Beside it, the reported outcome is a `Stat` toned `up`, and a row of `Dot`s marks the reader's place (`info` for the current story, `idle` for the rest) above a muted "2 of 4". Nothing is written: the filter and position are page state.
|
|
10
10
|
|
|
11
11
|
### `App.jsx`
|
|
12
12
|
```jsx
|
|
13
13
|
import React, { useState } from "react";
|
|
14
|
-
import { Badge,
|
|
15
|
-
import { Avatar } from "@vibes.diy/
|
|
14
|
+
import { Badge, IconTile, Card, Dot, Eyebrow, Grid, Heading, Icon, IconButton, Row, Segmented, Stack, Stat, Text } from "@vibes.diy/ui";
|
|
15
|
+
import { Avatar } from "@vibes.diy/ui/interactive";
|
|
16
16
|
|
|
17
17
|
// The owner's own collection of quotes, written into the page.
|
|
18
18
|
const STORIES = [
|
|
@@ -99,7 +99,7 @@ export default function App() {
|
|
|
99
99
|
<div aria-live="polite" aria-atomic="true">
|
|
100
100
|
<Stack gap={5}>
|
|
101
101
|
<Row justify="between" wrap={false}>
|
|
102
|
-
<
|
|
102
|
+
<IconTile icon="comment" tone="orange" />
|
|
103
103
|
<Badge tone="info">{serviceLabel(story.service)}</Badge>
|
|
104
104
|
</Row>
|
|
105
105
|
<blockquote className="m-0">
|
package/llms/ui-todo.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-todo.js","sourceRoot":"","sources":["../../jsr/llms/ui-todo.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,YAAY,GAAc;IACrC,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,CAAC,WAAW,CAAC;IACtB,KAAK,EAAE,YAAY;IACnB,WAAW,EAAE,uDAAuD;CACrE,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Todo
|
|
2
2
|
|
|
3
3
|
A checklist the person adds to, filters and ticks off: a beekeeper's hive inspection steps, a seed-swap shelf's restock run, today's errands, a quilting circle's supply checklist. Reach for it whenever the app's core is a list of short items that are either done or not. The tasks persist, so the list is still there on the next visit and on every device that opens the app.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof. Every write surface is gated on `useVibe(dbName).can`.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
@@ -27,8 +27,8 @@ import {
|
|
|
27
27
|
Skeleton,
|
|
28
28
|
Stack,
|
|
29
29
|
Text,
|
|
30
|
-
} from "@vibes.diy/
|
|
31
|
-
import { Checkbox, Confirm, Toaster, toast } from "@vibes.diy/
|
|
30
|
+
} from "@vibes.diy/ui";
|
|
31
|
+
import { Checkbox, Confirm, Toaster, toast } from "@vibes.diy/ui/interactive";
|
|
32
32
|
|
|
33
33
|
const FILTERS = [
|
|
34
34
|
{ value: "all", label: "All" },
|
|
@@ -160,7 +160,7 @@ export default function App() {
|
|
|
160
160
|
</Stack>
|
|
161
161
|
)}
|
|
162
162
|
</Stack>
|
|
163
|
-
<div className="
|
|
163
|
+
<div className="ui-toasts">
|
|
164
164
|
<Toaster />
|
|
165
165
|
</div>
|
|
166
166
|
</main>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-weather.js","sourceRoot":"","sources":["../../jsr/llms/ui-weather.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,CAAC,cAAc,CAAC;IACzB,KAAK,EAAE,eAAe;IACtB,WAAW,EAAE,oEAAoE;CAClF,CAAC"}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Weather
|
|
2
2
|
|
|
3
3
|
A weather card for a few places someone cares about: the cities a remote team works from, the allotment and the cabin, the stops on a trip, the towns a delivery round covers. Reach for it when the app shows conditions and a short forecast and lets the person switch place, units and day. The example runs on a small sample forecast written into the page, labelled as a sample on screen, so it renders the same everywhere with no key and no network call; `## Adapting` shows where real forecasts come from.
|
|
4
4
|
|
|
5
|
-
Built from @vibes.diy/
|
|
5
|
+
Built from @vibes.diy/ui components; persisted state lives in Fireproof.
|
|
6
6
|
|
|
7
7
|
## The block
|
|
8
8
|
|
|
9
|
-
One view with one job: read the weather for a place. A `Heading` names the place under an `Eyebrow`, with an `idle` `Badge` saying the figures are a sample. Two `Segmented` pickers (`tone="info"`) switch the place and the units (°C with km/h, or °F with mph, so temperature and wind always change together). The chosen day's high is a `Stat` (`info`, its icon from the day's condition), with the condition and the low in muted `Text` and three `Metric`s for that day's humidity, wind and UV. An hourly strip on a tight `Card` shows six times of day, each a muted time, an `Icon` and a numeric `Text`. The five-day forecast is one clickable `RowCard` per day with a decorative `orange` `
|
|
9
|
+
One view with one job: read the weather for a place. A `Heading` names the place under an `Eyebrow`, with an `idle` `Badge` saying the figures are a sample. Two `Segmented` pickers (`tone="info"`) switch the place and the units (°C with km/h, or °F with mph, so temperature and wind always change together). The chosen day's high is a `Stat` (`info`, its icon from the day's condition), with the condition and the low in muted `Text` and three `Metric`s for that day's humidity, wind and UV. An hourly strip on a tight `Card` shows six times of day, each a muted time, an `Icon` and a numeric `Text`. The five-day forecast is one clickable `RowCard` per day with a decorative `orange` `IconTile`; the chosen day is the `selected` row, and that selected row is the view's one lead, so nothing else wears the lead tone. Picking a place swaps every figure and returns to today; picking a day moves the high, the condition, all three readings and the hourly strip to that day. Nothing is written: the place, units and day are page state.
|
|
10
10
|
|
|
11
11
|
### `App.jsx`
|
|
12
12
|
```jsx
|
|
13
13
|
import React, { useState } from "react";
|
|
14
|
-
import { Badge,
|
|
14
|
+
import { Badge, IconTile, Card, Eyebrow, Heading, Icon, Metric, Row, RowCard, Segmented, Stack, Stat, Text } from "@vibes.diy/ui";
|
|
15
15
|
|
|
16
16
|
// A sample forecast, written into the page and labelled as one on screen. Real figures come
|
|
17
17
|
// from the app's backend (see Adapting); the shape below is the shape those documents keep.
|
|
@@ -150,7 +150,7 @@ export default function App() {
|
|
|
150
150
|
<RowCard key={i} selected={i === dayIndex} onClick={() => setDayIndex(i)}>
|
|
151
151
|
<Row justify="between" wrap={false}>
|
|
152
152
|
<Row gap={3} wrap={false}>
|
|
153
|
-
<
|
|
153
|
+
<IconTile icon={d.icon} tone="orange" size="sm" />
|
|
154
154
|
<Stack gap={1}>
|
|
155
155
|
<Text>{dayName(i)}</Text>
|
|
156
156
|
<Text size="sm" muted>
|
package/llms/use-vibe.md
CHANGED
|
@@ -22,7 +22,7 @@ The same order carries a creator-only line. Check `ready` first and the founder
|
|
|
22
22
|
|
|
23
23
|
```jsx
|
|
24
24
|
import { useVibe } from "use-vibes";
|
|
25
|
-
import { Button, Skeleton, Text } from "@vibes.diy/
|
|
25
|
+
import { Button, Skeleton, Text } from "@vibes.diy/ui";
|
|
26
26
|
|
|
27
27
|
function InviteRow({ guild, onInvite }) {
|
|
28
28
|
const { can, me, ready } = useVibe("quiltGuilds");
|
|
@@ -47,7 +47,7 @@ Gate every write affordance on `can.*`. Hold it while `pending`, and write your
|
|
|
47
47
|
```jsx
|
|
48
48
|
import { useState } from "react";
|
|
49
49
|
import { useVibe } from "use-vibes";
|
|
50
|
-
import { Button, Field, Input, Row, Skeleton, Text } from "@vibes.diy/
|
|
50
|
+
import { Button, Field, Input, Row, Skeleton, Text } from "@vibes.diy/ui";
|
|
51
51
|
|
|
52
52
|
function PromptBar({ database }) {
|
|
53
53
|
const { can, me } = useVibe("aestheticBoard");
|
|
@@ -103,7 +103,7 @@ if (url.pathname === "/setup" && request.method === "GET") {
|
|
|
103
103
|
|
|
104
104
|
```jsx
|
|
105
105
|
// App.jsx — one hook, one surface, the verdict decides what each person sees
|
|
106
|
-
// (imports: useEffect, useRef, useState from react; apiFetch from use-vibes;
|
|
106
|
+
// (imports: useEffect, useRef, useState from react; apiFetch from use-vibes; UI components)
|
|
107
107
|
function useSetup() {
|
|
108
108
|
const [setup, setSetup] = useState(null);
|
|
109
109
|
const latest = useRef(0);
|
|
@@ -157,7 +157,7 @@ export default function App() {
|
|
|
157
157
|
}
|
|
158
158
|
```
|
|
159
159
|
|
|
160
|
-
Not the same thing: a *visitor's* first-run answers — who are you, which team — are per-person onboarding (the
|
|
160
|
+
Not the same thing: a *visitor's* first-run answers — who are you, which team — are per-person onboarding (the onboarding block), saved as that person's own document, and stay as they are. Owner setup is the app's, done once, and lives on the Setup surface.
|
|
161
161
|
|
|
162
162
|
## The server is still the authority
|
|
163
163
|
|