@flickfyi/flkr 0.0.182 → 0.0.185
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/{api-client-CAg1b8Bh.js → api-client-nn4U_Vfn.js} +1 -1
- package/dist/{app-DpM5nhb9.js → app-COXGJhrt.js} +3 -3
- package/dist/{bundler-DNrDcqyk.js → bundler-CW4YC73e.js} +4 -2
- package/dist/cli.js +11 -11
- package/dist/{delegate-DcVye0KE.js → delegate-aUVluBjB.js} +2 -2
- package/dist/{generate-B1l1z_FZ.js → generate-BeL1QPDi.js} +1 -1
- package/dist/{preview-Dqn_Tq6K.js → preview-DTVM8Csb.js} +2 -2
- package/dist/{publish-BmDqO1xU.js → publish-BJG-s-w5.js} +4 -4
- package/dist/{pull-CO80DMn8.js → pull-B_Yfjpi2.js} +1 -1
- package/dist/{save-8crfOeo1.js → save-UrfgmK2-.js} +2 -2
- package/dist/{sdk-app-BXWrf_pf.js → sdk-app-BAxznAf9.js} +3 -3
- package/dist/{sdk-deploy-CaEonlvx.js → sdk-deploy-D1wgQxse.js} +3 -3
- package/dist/{sdk-generation-CF8ATbrL.js → sdk-generation-CLQ-QrVM.js} +1 -1
- package/dist/{sdk-project-CKV3U3u9.js → sdk-project-BaO0fqhW.js} +1 -1
- package/dist/{use-auth-B6nwU2rp.js → use-auth-CtM4_BAY.js} +1 -1
- package/node_modules/@flickfyi/biscuit/.turbo/turbo-build.log +4 -4
- package/node_modules/@flickfyi/core/README.md +19 -9
- package/node_modules/@flickfyi/core/dist/chunks/{default-CuxDsQoM.js → default-BTmKidHV.js} +1 -1
- package/node_modules/@flickfyi/core/dist/chunks/{default-BB6YexEH.cjs → default-JhTq5I_y.cjs} +1 -1
- package/node_modules/@flickfyi/core/dist/chunks/{define-CUJRqVKY.cjs → define-BKCRhpuY.cjs} +1 -1
- package/node_modules/@flickfyi/core/dist/chunks/{define-e_VqSs4M.js → define-DZXgUsy7.js} +5 -5
- package/node_modules/@flickfyi/core/dist/kowalski/catalog.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/kowalski/catalog.js +728 -549
- package/node_modules/@flickfyi/core/dist/kowalski/index.cjs +5 -5
- package/node_modules/@flickfyi/core/dist/kowalski/index.js +4297 -3700
- package/node_modules/@flickfyi/core/dist/kowalski/schemas.cjs +1 -0
- package/node_modules/@flickfyi/core/dist/kowalski/schemas.js +637 -0
- package/node_modules/@flickfyi/core/dist/kowalski-catalog.css +516 -0
- package/node_modules/@flickfyi/core/dist/kowalski.css +10 -0
- package/node_modules/@flickfyi/core/dist/themes/athletic/athletic.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/athletic/athletic.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/compact/compact.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/compact/compact.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/default/default.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/default/default.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/editorial/editorial.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/editorial/editorial.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/handwritten/handwritten.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/handwritten/handwritten.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/index.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/index.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/kids/kids.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/kids/kids.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/rounded/rounded.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/rounded/rounded.js +1 -1
- package/node_modules/@flickfyi/core/dist/themes/technical/technical.cjs +1 -1
- package/node_modules/@flickfyi/core/dist/themes/technical/technical.js +1 -1
- package/node_modules/@flickfyi/core/dist-types/hooks/use-feature-store/index.d.ts +43 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/calculations.d.ts +57 -3
- package/node_modules/@flickfyi/core/dist-types/kowalski/calculator.d.ts +7 -6
- package/node_modules/@flickfyi/core/dist-types/kowalski/catalog.d.cts +524 -809
- package/node_modules/@flickfyi/core/dist-types/kowalski/catalog.d.ts +524 -809
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/bill-split.d.ts +38 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/bookmark.d.ts +48 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/budget.d.ts +39 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/calculator.d.ts +62 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/checklist.d.ts +35 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/color-palette.d.ts +32 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/contact.d.ts +41 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/countdown.d.ts +34 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/event.d.ts +43 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/expense.d.ts +40 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/goal.d.ts +36 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/habit.d.ts +57 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/ledger.d.ts +43 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/note.d.ts +35 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/poll.d.ts +41 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/random-picker.d.ts +69 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/rating.d.ts +33 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/reminder.d.ts +48 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/rotation.d.ts +39 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/scoreboard.d.ts +37 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/shopping-list.d.ts +41 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/task-board.d.ts +39 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/time-zone.d.ts +34 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/timer.d.ts +43 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/trip.d.ts +61 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/components/unit-converter.d.ts +106 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/create-schemas.d.ts +6 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/date-time.d.ts +1 -1
- package/node_modules/@flickfyi/core/dist-types/kowalski/everyday.d.ts +28 -8
- package/node_modules/@flickfyi/core/dist-types/kowalski/feature-schema.d.ts +65 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/format.d.ts +4 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/fortune.d.ts +21 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/frame.d.ts +4 -4
- package/node_modules/@flickfyi/core/dist-types/kowalski/index.d.cts +31 -7
- package/node_modules/@flickfyi/core/dist-types/kowalski/index.d.ts +31 -7
- package/node_modules/@flickfyi/core/dist-types/kowalski/lesson.d.ts +89 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/recipe.d.ts +129 -8
- package/node_modules/@flickfyi/core/dist-types/kowalski/schemas.d.cts +4 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/schemas.d.ts +4 -0
- package/node_modules/@flickfyi/core/dist-types/kowalski/time-since.d.ts +34 -0
- package/node_modules/@flickfyi/core/examples/example-metadata.ts +19 -2
- package/node_modules/@flickfyi/core/examples/kowalski/bill-split/bill-split.stories.tsx +25 -6
- package/node_modules/@flickfyi/core/examples/kowalski/bill-split/bill-split.tsx +6 -12
- package/node_modules/@flickfyi/core/examples/kowalski/bookmark/bookmark.stories.tsx +22 -5
- package/node_modules/@flickfyi/core/examples/kowalski/bookmark/bookmark.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/budget/budget.stories.tsx +26 -5
- package/node_modules/@flickfyi/core/examples/kowalski/budget/budget.tsx +6 -21
- package/node_modules/@flickfyi/core/examples/kowalski/calculator/calculator.stories.tsx +18 -5
- package/node_modules/@flickfyi/core/examples/kowalski/calculator/calculator.tsx +6 -19
- package/node_modules/@flickfyi/core/examples/kowalski/checklist/checklist.stories.tsx +25 -5
- package/node_modules/@flickfyi/core/examples/kowalski/checklist/checklist.tsx +6 -21
- package/node_modules/@flickfyi/core/examples/kowalski/color-palette/color-palette.stories.tsx +19 -6
- package/node_modules/@flickfyi/core/examples/kowalski/color-palette/color-palette.tsx +6 -17
- package/node_modules/@flickfyi/core/examples/kowalski/contact/contact.stories.tsx +30 -5
- package/node_modules/@flickfyi/core/examples/kowalski/contact/contact.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/countdown/countdown.stories.tsx +22 -5
- package/node_modules/@flickfyi/core/examples/kowalski/countdown/countdown.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/event/event.stories.tsx +23 -5
- package/node_modules/@flickfyi/core/examples/kowalski/event/event.tsx +6 -19
- package/node_modules/@flickfyi/core/examples/kowalski/expense/expense.stories.tsx +23 -5
- package/node_modules/@flickfyi/core/examples/kowalski/expense/expense.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/fortune/fortune.stories.tsx +61 -0
- package/node_modules/@flickfyi/core/examples/kowalski/fortune/fortune.tsx +11 -0
- package/node_modules/@flickfyi/core/examples/kowalski/goal/goal.stories.tsx +18 -5
- package/node_modules/@flickfyi/core/examples/kowalski/goal/goal.tsx +3 -19
- package/node_modules/@flickfyi/core/examples/kowalski/habit/habit.stories.tsx +22 -5
- package/node_modules/@flickfyi/core/examples/kowalski/habit/habit.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/ledger/ledger.stories.tsx +25 -5
- package/node_modules/@flickfyi/core/examples/kowalski/ledger/ledger.tsx +6 -20
- package/node_modules/@flickfyi/core/examples/kowalski/lesson/lesson.stories.tsx +99 -0
- package/node_modules/@flickfyi/core/examples/kowalski/lesson/lesson.tsx +11 -0
- package/node_modules/@flickfyi/core/examples/kowalski/note/note.stories.tsx +21 -5
- package/node_modules/@flickfyi/core/examples/kowalski/note/note.tsx +3 -17
- package/node_modules/@flickfyi/core/examples/kowalski/poll/poll.stories.tsx +26 -5
- package/node_modules/@flickfyi/core/examples/kowalski/poll/poll.tsx +3 -21
- package/node_modules/@flickfyi/core/examples/kowalski/random-picker/random-picker.stories.tsx +37 -6
- package/node_modules/@flickfyi/core/examples/kowalski/random-picker/random-picker.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/rating/rating.stories.tsx +18 -5
- package/node_modules/@flickfyi/core/examples/kowalski/rating/rating.tsx +6 -14
- package/node_modules/@flickfyi/core/examples/kowalski/recipe/recipe.stories.tsx +117 -5
- package/node_modules/@flickfyi/core/examples/kowalski/recipe/recipe.tsx +6 -115
- package/node_modules/@flickfyi/core/examples/kowalski/reminder/reminder.stories.tsx +22 -5
- package/node_modules/@flickfyi/core/examples/kowalski/reminder/reminder.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/rotation/rotation.stories.tsx +26 -5
- package/node_modules/@flickfyi/core/examples/kowalski/rotation/rotation.tsx +6 -22
- package/node_modules/@flickfyi/core/examples/kowalski/scoreboard/scoreboard.stories.tsx +26 -5
- package/node_modules/@flickfyi/core/examples/kowalski/scoreboard/scoreboard.tsx +6 -21
- package/node_modules/@flickfyi/core/examples/kowalski/shopping-list/shopping-list.stories.tsx +28 -6
- package/node_modules/@flickfyi/core/examples/kowalski/shopping-list/shopping-list.tsx +6 -22
- package/node_modules/@flickfyi/core/examples/kowalski/task-board/task-board.stories.tsx +27 -6
- package/node_modules/@flickfyi/core/examples/kowalski/task-board/task-board.tsx +6 -22
- package/node_modules/@flickfyi/core/examples/kowalski/time-since/time-since.stories.tsx +33 -0
- package/node_modules/@flickfyi/core/examples/kowalski/time-since/time-since.tsx +12 -0
- package/node_modules/@flickfyi/core/examples/kowalski/time-zone/time-zone.stories.tsx +22 -6
- package/node_modules/@flickfyi/core/examples/kowalski/time-zone/time-zone.tsx +6 -17
- package/node_modules/@flickfyi/core/examples/kowalski/timer/timer.stories.tsx +18 -5
- package/node_modules/@flickfyi/core/examples/kowalski/timer/timer.tsx +6 -18
- package/node_modules/@flickfyi/core/examples/kowalski/trip/trip.stories.tsx +25 -5
- package/node_modules/@flickfyi/core/examples/kowalski/trip/trip.tsx +3 -21
- package/node_modules/@flickfyi/core/examples/kowalski/unit-converter/unit-converter.stories.tsx +19 -6
- package/node_modules/@flickfyi/core/examples/kowalski/unit-converter/unit-converter.tsx +6 -19
- package/node_modules/@flickfyi/core/examples/parrott/calculator/calculator.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/calculator/calculator.tsx +2 -13
- package/node_modules/@flickfyi/core/examples/parrott/checklist/checklist.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/checklist/checklist.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/countdown/countdown.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/countdown/countdown.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/counter/counter.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/counter/counter.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/fortune/fortune.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/fortune/fortune.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/grid/grid.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/grid/grid.tsx +4 -9
- package/node_modules/@flickfyi/core/examples/parrott/kale-smoothie/kale-smoothie.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/kale-smoothie/kale-smoothie.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/list/list.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/list/list.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/log/log.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/log/log.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/timed-task/timed-task.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/timed-task/timed-task.tsx +0 -8
- package/node_modules/@flickfyi/core/examples/parrott/timer/timer.stories.tsx +10 -3
- package/node_modules/@flickfyi/core/examples/parrott/timer/timer.tsx +0 -8
- package/node_modules/@flickfyi/core/package.json +16 -3
- package/node_modules/@flickfyi/core/src/{kowalski/use-configured-feature.ts → hooks/use-configured-feature/index.ts} +1 -1
- package/node_modules/@flickfyi/core/src/{kowalski/use-feature-store.ts → hooks/use-feature-store/index.ts} +37 -12
- package/node_modules/@flickfyi/core/src/kowalski/README.md +13 -0
- package/node_modules/@flickfyi/core/src/kowalski/calculations.ts +36 -8
- package/node_modules/@flickfyi/core/src/kowalski/calculator.ts +15 -7
- package/node_modules/@flickfyi/core/src/kowalski/catalog.ts +110 -704
- package/node_modules/@flickfyi/core/src/kowalski/components/bill-split.tsx +284 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/bookmark.tsx +347 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/budget.tsx +169 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/calculator.tsx +202 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/checklist.tsx +119 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/color-palette.tsx +302 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/contact.tsx +247 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/countdown.tsx +173 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/event.tsx +260 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/expense.tsx +257 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/goal.tsx +182 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/habit.tsx +272 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/ledger.tsx +211 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/note.tsx +188 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/poll.tsx +242 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/random-picker.tsx +308 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/rating.tsx +112 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/reminder.tsx +298 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/rotation.tsx +146 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/scoreboard.tsx +139 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/shopping-list.tsx +144 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/task-board.tsx +146 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/time-zone.tsx +240 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/timer.tsx +225 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/trip.tsx +338 -0
- package/node_modules/@flickfyi/core/src/kowalski/components/unit-converter.tsx +285 -0
- package/node_modules/@flickfyi/core/src/kowalski/create-schemas.ts +8 -0
- package/node_modules/@flickfyi/core/src/kowalski/date-time.tsx +1 -1
- package/node_modules/@flickfyi/core/src/kowalski/everyday.tsx +1 -640
- package/node_modules/@flickfyi/core/src/kowalski/feature-schema.ts +84 -0
- package/node_modules/@flickfyi/core/src/kowalski/format.ts +29 -3
- package/node_modules/@flickfyi/core/src/kowalski/fortune.tsx +67 -0
- package/node_modules/@flickfyi/core/src/kowalski/frame.tsx +5 -6
- package/node_modules/@flickfyi/core/src/kowalski/index.ts +31 -22
- package/node_modules/@flickfyi/core/src/kowalski/lesson.tsx +564 -0
- package/node_modules/@flickfyi/core/src/kowalski/recipe.tsx +78 -37
- package/node_modules/@flickfyi/core/src/kowalski/schemas.ts +67 -0
- package/node_modules/@flickfyi/core/src/kowalski/stories/composition.tsx +22 -20
- package/node_modules/@flickfyi/core/src/kowalski/time-since.tsx +145 -0
- package/node_modules/@flickfyi/core/src/molecules/progress/progress.tsx +4 -1
- package/node_modules/@flickfyi/core/src/oklch.ts +1 -6
- package/node_modules/@flickfyi/core/src/parrott/theme.ts +3 -1
- package/node_modules/@flickfyi/core/src/themes/editorial/editorial.ts +6 -1
- package/node_modules/@flickfyi/core/src/themes/palette.ts +5 -5
- package/node_modules/@flickfyi/core/src/themes/stories/composition.tsx +11 -9
- package/node_modules/@flickfyi/core/src/themes/stories/gallery.tsx +7 -11
- package/node_modules/@flickfyi/core/tsgo.bun.lock +7 -7
- package/node_modules/@flickfyi/core/tsgo.package.json +1 -1
- package/package.json +2 -2
- package/node_modules/@flickfyi/core/dist-types/kowalski/clocks.d.ts +0 -4
- package/node_modules/@flickfyi/core/dist-types/kowalski/details.d.ts +0 -7
- package/node_modules/@flickfyi/core/dist-types/kowalski/productivity.d.ts +0 -5
- package/node_modules/@flickfyi/core/dist-types/kowalski/tools.d.ts +0 -7
- package/node_modules/@flickfyi/core/dist-types/kowalski/use-feature-store.d.ts +0 -15
- package/node_modules/@flickfyi/core/src/kowalski/clocks.tsx +0 -464
- package/node_modules/@flickfyi/core/src/kowalski/details.tsx +0 -1387
- package/node_modules/@flickfyi/core/src/kowalski/productivity.tsx +0 -575
- package/node_modules/@flickfyi/core/src/kowalski/tools.tsx +0 -1213
- /package/node_modules/@flickfyi/core/dist-types/{kowalski/use-clock.d.ts → hooks/use-clock/index.d.ts} +0 -0
- /package/node_modules/@flickfyi/core/dist-types/{kowalski/use-configured-feature.d.ts → hooks/use-configured-feature/index.d.ts} +0 -0
- /package/node_modules/@flickfyi/core/src/{kowalski/use-clock.ts → hooks/use-clock/index.ts} +0 -0
|
@@ -7,23 +7,26 @@ import {
|
|
|
7
7
|
List,
|
|
8
8
|
Stepper,
|
|
9
9
|
} from '@flickfyi/core/molecules'
|
|
10
|
+
import { Recipe as RecipeEntity } from '@flickfyi/schemas/recipe'
|
|
10
11
|
import * as stylex from '@stylexjs/stylex'
|
|
11
12
|
import { formatQuantity } from 'format-quantity'
|
|
12
13
|
import { Duration } from 'luxon'
|
|
13
14
|
import { useState } from 'react'
|
|
15
|
+
import { z } from 'zod/v4'
|
|
14
16
|
|
|
17
|
+
import { useClock } from '~/hooks/use-clock'
|
|
18
|
+
import { useConfiguredFeature } from '~/hooks/use-configured-feature'
|
|
19
|
+
import type { CreateSchemas } from '~/kowalski/create-schemas'
|
|
15
20
|
import { space } from '~/themes/scale.stylex'
|
|
16
21
|
import { appearance, button, roles } from '~/themes/shared'
|
|
17
22
|
|
|
18
|
-
import {
|
|
23
|
+
import { entries, featureFields } from './feature-schema'
|
|
19
24
|
import { format } from './format'
|
|
20
25
|
import { FeatureAction, FeatureFacts, FeatureFrame, FeatureWell, layout } from './frame'
|
|
21
|
-
import { useClock } from './use-clock'
|
|
22
|
-
import { useConfiguredFeature } from './use-configured-feature'
|
|
23
26
|
|
|
24
|
-
type
|
|
25
|
-
type Ingredient =
|
|
26
|
-
type Step =
|
|
27
|
+
type RecipeContent = z.output<typeof RecipeData>
|
|
28
|
+
type Ingredient = RecipeContent['ingredients'][number]
|
|
29
|
+
type Step = RecipeContent['steps'][number]
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
32
|
* Cooks an RGF recipe in two modes. The overview is for reading: ingredients, servings, and
|
|
@@ -31,39 +34,77 @@ type Step = RecipeProps['steps'][number]
|
|
|
31
34
|
* the bottom, or the next timer to go off when nothing is ready; above it, in falling order of
|
|
32
35
|
* attention, the other running timers, the next few steps (greyed until ready), and what's done.
|
|
33
36
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
/** Recipe Graph Format: ingredients, step outputs, and explicit dependency edges. */
|
|
38
|
+
|
|
39
|
+
const defaultId = 'KowalskiRecipe'
|
|
40
|
+
const defaultScope = 'private'
|
|
41
|
+
|
|
42
|
+
export const RecipeData = RecipeEntity
|
|
43
|
+
export type RecipeData = RecipeEntity
|
|
44
|
+
|
|
45
|
+
export const RecipeProps = z.strictObject({
|
|
46
|
+
data: RecipeData,
|
|
47
|
+
...featureFields,
|
|
48
|
+
scope: featureFields.scope.default(defaultScope),
|
|
49
|
+
})
|
|
50
|
+
export type RecipeProps = z.input<typeof RecipeProps> & {
|
|
51
|
+
style?: stylex.StyleXArray<stylex.StyleXStyles>
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const recipeStoreSchema = entries(
|
|
55
|
+
'step_',
|
|
56
|
+
z.strictObject({ done: z.boolean(), endsAt: z.number().nullable() }),
|
|
57
|
+
{
|
|
58
|
+
cooking: z.boolean().default(false),
|
|
59
|
+
servings: z.number().default(1),
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
export const createSchemas: CreateSchemas = ({
|
|
64
|
+
id = defaultId,
|
|
65
|
+
scope = defaultScope,
|
|
66
|
+
} = {}) => ({
|
|
67
|
+
[`stores/${scope}/${id}`]: recipeStoreSchema,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
export function Recipe({
|
|
71
|
+
data,
|
|
72
|
+
id,
|
|
73
|
+
revision = 0,
|
|
74
|
+
scope = defaultScope,
|
|
75
|
+
style,
|
|
76
|
+
}: RecipeProps) {
|
|
77
|
+
const schema = recipeStoreSchema
|
|
78
|
+
const baseServings = data.servings ?? null
|
|
38
79
|
const store = useConfiguredFeature({
|
|
39
|
-
name:
|
|
40
|
-
revision
|
|
80
|
+
name: id ?? defaultId,
|
|
81
|
+
revision,
|
|
41
82
|
schema,
|
|
42
|
-
scope
|
|
83
|
+
scope,
|
|
43
84
|
seed: schema.parse({ servings: baseServings ?? 1 }),
|
|
44
85
|
})
|
|
45
86
|
const [prepOpen, setPrepOpen] = useState(false)
|
|
46
87
|
const [showEarlier, setShowEarlier] = useState(false)
|
|
47
88
|
const [showLater, setShowLater] = useState(false)
|
|
48
|
-
const graph = recipeGraph(
|
|
89
|
+
const graph = recipeGraph(data.steps)
|
|
49
90
|
const checked = (id: string) => store.value[`step_${id}`]?.done
|
|
50
91
|
const endsAt = (id: string) => store.value[`step_${id}`]?.endsAt ?? null
|
|
51
92
|
// The clock runs while any unfinished step has a timer, including one whose time is up.
|
|
52
93
|
// Timer ends are the key, so starting or extending one refreshes the clock before paint.
|
|
53
94
|
const now = useClock(
|
|
54
|
-
|
|
55
|
-
|
|
95
|
+
data.steps.some(step => endsAt(step.id) !== null && !checked(step.id)),
|
|
96
|
+
data.steps.map(step => endsAt(step.id) ?? '').join(',')
|
|
56
97
|
)
|
|
57
98
|
const factor = baseServings === null ? 1 : store.value.servings / baseServings
|
|
58
99
|
const waitingOn = (step: Step) =>
|
|
59
100
|
(graph.prerequisites.get(step.id) ?? []).filter(id => !checked(id))
|
|
60
|
-
const done =
|
|
101
|
+
const done = data.steps.filter(step => checked(step.id))
|
|
61
102
|
const history = showEarlier ? done : done.slice(-1)
|
|
62
|
-
const active =
|
|
103
|
+
const active = data.steps
|
|
63
104
|
.filter(step => !checked(step.id) && endsAt(step.id) !== null)
|
|
64
105
|
.toSorted((a, b) => (endsAt(a.id) ?? 0) - (endsAt(b.id) ?? 0))
|
|
65
106
|
// Ready steps first, longest remaining chain first so long waits start early; then waiting steps in order.
|
|
66
|
-
const queue =
|
|
107
|
+
const queue = data.steps
|
|
67
108
|
.filter(step => !checked(step.id) && endsAt(step.id) === null)
|
|
68
109
|
.toSorted(
|
|
69
110
|
(a, b) =>
|
|
@@ -71,7 +112,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
71
112
|
(waitingOn(a).length > 0
|
|
72
113
|
? 0
|
|
73
114
|
: (graph.chain.get(b.id) ?? 0) - (graph.chain.get(a.id) ?? 0)) ||
|
|
74
|
-
|
|
115
|
+
data.steps.indexOf(a) - data.steps.indexOf(b)
|
|
75
116
|
)
|
|
76
117
|
const [first, ...rest] = queue
|
|
77
118
|
const current = first && waitingOn(first).length === 0 ? first : undefined
|
|
@@ -93,11 +134,11 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
93
134
|
step.doneness ? `Time’s up. Done when ${step.doneness}.` : 'Time’s up'
|
|
94
135
|
// What a step takes: an ingredient with its scaled amount, or an earlier output by name.
|
|
95
136
|
const uses = (step: Step) =>
|
|
96
|
-
step.uses.map(({ id, portion, source }) => {
|
|
137
|
+
(step.uses ?? []).map(({ id, portion, source }) => {
|
|
97
138
|
if (source.kind === 'output') {
|
|
98
139
|
return { id, label: graph.outputs.get(source.outputId) ?? '', value: portion }
|
|
99
140
|
}
|
|
100
|
-
const ingredient =
|
|
141
|
+
const ingredient = data.ingredients.find(item => item.id === source.ingredientId)
|
|
101
142
|
return {
|
|
102
143
|
id,
|
|
103
144
|
label: ingredient?.label ?? '',
|
|
@@ -108,7 +149,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
108
149
|
<>
|
|
109
150
|
<Field label="Ingredients">
|
|
110
151
|
<FeatureFacts>
|
|
111
|
-
{
|
|
152
|
+
{data.ingredients.map(ingredient => (
|
|
112
153
|
<List.Item
|
|
113
154
|
description={ingredient.notes?.join(' · ')}
|
|
114
155
|
key={ingredient.id}
|
|
@@ -123,14 +164,12 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
123
164
|
<Stepper
|
|
124
165
|
decrementDisabled={!store.ready || store.value.servings <= 1}
|
|
125
166
|
decrementLabel="Fewer servings"
|
|
126
|
-
incrementDisabled={!store.ready
|
|
167
|
+
incrementDisabled={!store.ready}
|
|
127
168
|
incrementLabel="More servings"
|
|
128
169
|
onDecrement={() =>
|
|
129
170
|
store.set(current => ({ servings: Math.max(1, current.servings - 1) }))
|
|
130
171
|
}
|
|
131
|
-
onIncrement={() =>
|
|
132
|
-
store.set(current => ({ servings: Math.min(100, current.servings + 1) }))
|
|
133
|
-
}
|
|
172
|
+
onIncrement={() => store.set(current => ({ servings: current.servings + 1 }))}
|
|
134
173
|
>
|
|
135
174
|
<Text {...stylex.props(roles.h2, layout.stepperInput)}>
|
|
136
175
|
{format.formatNumber(store.value.servings)}
|
|
@@ -207,11 +246,12 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
207
246
|
if (!store.value.cooking) {
|
|
208
247
|
return (
|
|
209
248
|
<FeatureFrame
|
|
249
|
+
style={style}
|
|
210
250
|
onRetry={store.retry}
|
|
211
251
|
notice={store.error}
|
|
212
252
|
component="recipe"
|
|
213
|
-
title={
|
|
214
|
-
detail={timeSummary(
|
|
253
|
+
title={data.title}
|
|
254
|
+
detail={timeSummary(data.steps, graph)}
|
|
215
255
|
>
|
|
216
256
|
{prep}
|
|
217
257
|
<FeatureAction
|
|
@@ -229,13 +269,14 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
229
269
|
}
|
|
230
270
|
return (
|
|
231
271
|
<FeatureFrame
|
|
272
|
+
style={style}
|
|
232
273
|
onRetry={store.retry}
|
|
233
274
|
notice={store.error}
|
|
234
275
|
component="recipe"
|
|
235
|
-
title={
|
|
276
|
+
title={data.title}
|
|
236
277
|
trailing={
|
|
237
278
|
<Text {...stylex.props(roles.muted)}>
|
|
238
|
-
{`${format.formatNumber(done.length)} of ${format.formatNumber(
|
|
279
|
+
{`${format.formatNumber(done.length)} of ${format.formatNumber(data.steps.length)} done`}
|
|
239
280
|
</Text>
|
|
240
281
|
}
|
|
241
282
|
>
|
|
@@ -248,7 +289,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
248
289
|
<Disclosure
|
|
249
290
|
label={[
|
|
250
291
|
baseServings === null
|
|
251
|
-
?
|
|
292
|
+
? data.yield
|
|
252
293
|
: format.formatMessage(
|
|
253
294
|
{
|
|
254
295
|
defaultMessage: '{count, plural, one {# serving} other {# servings}}',
|
|
@@ -262,7 +303,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
262
303
|
'{count, plural, one {# ingredient} other {# ingredients}}',
|
|
263
304
|
id: 'kowalski.recipe.ingredients',
|
|
264
305
|
},
|
|
265
|
-
{ count:
|
|
306
|
+
{ count: data.ingredients.length }
|
|
266
307
|
),
|
|
267
308
|
]
|
|
268
309
|
.filter(Boolean)
|
|
@@ -323,7 +364,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
323
364
|
{current ? (
|
|
324
365
|
<>
|
|
325
366
|
<Text {...stylex.props(roles.h2)}>{current.instruction}</Text>
|
|
326
|
-
{current.uses.length > 0 && (
|
|
367
|
+
{(current.uses ?? []).length > 0 && (
|
|
327
368
|
<List>
|
|
328
369
|
{uses(current).map(use => (
|
|
329
370
|
<List.Item key={use.id} label={use.label} trailing={use.value} />
|
|
@@ -403,7 +444,7 @@ export function Recipe(input: KowalskiInput<'recipe'>) {
|
|
|
403
444
|
store.set(() => ({
|
|
404
445
|
cooking: false,
|
|
405
446
|
...Object.fromEntries(
|
|
406
|
-
|
|
447
|
+
data.steps.map(step => [
|
|
407
448
|
`step_${step.id}`,
|
|
408
449
|
{ done: false, endsAt: null },
|
|
409
450
|
])
|
|
@@ -439,7 +480,7 @@ function Disclosure({
|
|
|
439
480
|
)
|
|
440
481
|
}
|
|
441
482
|
|
|
442
|
-
const recipeStyles = stylex.create({
|
|
483
|
+
const recipeStyles = /* @__PURE__ */ stylex.create({
|
|
443
484
|
disclosure: { alignSelf: 'flex-start', paddingLeft: 0, paddingRight: 0 },
|
|
444
485
|
row: { alignItems: 'center', columnGap: space[3], flexDirection: 'row' },
|
|
445
486
|
trailing: { flexShrink: 0 },
|
|
@@ -489,7 +530,7 @@ function recipeGraph(steps: Step[]) {
|
|
|
489
530
|
[
|
|
490
531
|
...new Set([
|
|
491
532
|
...(step.after ?? []),
|
|
492
|
-
...step.uses.flatMap(use =>
|
|
533
|
+
...(step.uses ?? []).flatMap(use =>
|
|
493
534
|
use.source.kind === 'output' ? [producers.get(use.source.outputId) ?? ''] : []
|
|
494
535
|
),
|
|
495
536
|
]),
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Generated from component createSchemas exports. Do not edit.
|
|
2
|
+
import type { CreateSchemas, CreateSchemasInput } from './create-schemas'
|
|
3
|
+
import { createSchemas as generator0 } from "./components/bill-split"
|
|
4
|
+
import { createSchemas as generator1 } from "./components/bookmark"
|
|
5
|
+
import { createSchemas as generator2 } from "./components/budget"
|
|
6
|
+
import { createSchemas as generator3 } from "./components/calculator"
|
|
7
|
+
import { createSchemas as generator4 } from "./components/checklist"
|
|
8
|
+
import { createSchemas as generator5 } from "./components/color-palette"
|
|
9
|
+
import { createSchemas as generator6 } from "./components/contact"
|
|
10
|
+
import { createSchemas as generator7 } from "./components/countdown"
|
|
11
|
+
import { createSchemas as generator8 } from "./components/event"
|
|
12
|
+
import { createSchemas as generator9 } from "./components/expense"
|
|
13
|
+
import { createSchemas as generator10 } from "./components/goal"
|
|
14
|
+
import { createSchemas as generator11 } from "./components/habit"
|
|
15
|
+
import { createSchemas as generator12 } from "./components/ledger"
|
|
16
|
+
import { createSchemas as generator13 } from "./components/note"
|
|
17
|
+
import { createSchemas as generator14 } from "./components/poll"
|
|
18
|
+
import { createSchemas as generator15 } from "./components/random-picker"
|
|
19
|
+
import { createSchemas as generator16 } from "./components/rating"
|
|
20
|
+
import { createSchemas as generator17 } from "./components/reminder"
|
|
21
|
+
import { createSchemas as generator18 } from "./components/rotation"
|
|
22
|
+
import { createSchemas as generator19 } from "./components/scoreboard"
|
|
23
|
+
import { createSchemas as generator20 } from "./components/shopping-list"
|
|
24
|
+
import { createSchemas as generator21 } from "./components/task-board"
|
|
25
|
+
import { createSchemas as generator22 } from "./components/time-zone"
|
|
26
|
+
import { createSchemas as generator23 } from "./components/timer"
|
|
27
|
+
import { createSchemas as generator24 } from "./components/trip"
|
|
28
|
+
import { createSchemas as generator25 } from "./components/unit-converter"
|
|
29
|
+
import { createSchemas as generator26 } from "./lesson"
|
|
30
|
+
import { createSchemas as generator27 } from "./recipe"
|
|
31
|
+
import { createSchemas as generator28 } from "./time-since"
|
|
32
|
+
|
|
33
|
+
const generators = new Map<string, CreateSchemas>([["BillSplit", generator0],
|
|
34
|
+
["Bookmark", generator1],
|
|
35
|
+
["Budget", generator2],
|
|
36
|
+
["Calculator", generator3],
|
|
37
|
+
["Checklist", generator4],
|
|
38
|
+
["ColorPalette", generator5],
|
|
39
|
+
["Contact", generator6],
|
|
40
|
+
["Countdown", generator7],
|
|
41
|
+
["Event", generator8],
|
|
42
|
+
["Expense", generator9],
|
|
43
|
+
["Goal", generator10],
|
|
44
|
+
["Habit", generator11],
|
|
45
|
+
["Ledger", generator12],
|
|
46
|
+
["Note", generator13],
|
|
47
|
+
["Poll", generator14],
|
|
48
|
+
["RandomPicker", generator15],
|
|
49
|
+
["Rating", generator16],
|
|
50
|
+
["Reminder", generator17],
|
|
51
|
+
["Rotation", generator18],
|
|
52
|
+
["Scoreboard", generator19],
|
|
53
|
+
["ShoppingList", generator20],
|
|
54
|
+
["TaskBoard", generator21],
|
|
55
|
+
["TimeZone", generator22],
|
|
56
|
+
["Timer", generator23],
|
|
57
|
+
["Trip", generator24],
|
|
58
|
+
["UnitConverter", generator25],
|
|
59
|
+
["Lesson", generator26],
|
|
60
|
+
["Recipe", generator27],
|
|
61
|
+
["TimeSince", generator28]])
|
|
62
|
+
export const schemaComponents = [...generators.keys()]
|
|
63
|
+
export { kowalskiFeatureId, kowalskiScope } from './feature-schema'
|
|
64
|
+
|
|
65
|
+
export function componentSchemas(name: string, input?: CreateSchemasInput) {
|
|
66
|
+
return generators.get(name)?.(input) ?? {}
|
|
67
|
+
}
|
|
@@ -21,30 +21,27 @@ export function TrainingComposition({ theme = athletic }: { theme?: CompositionT
|
|
|
21
21
|
<Flex {...stylex.props(styles.feature)}>
|
|
22
22
|
<Goal
|
|
23
23
|
id="TrackDayLaps"
|
|
24
|
-
|
|
25
|
-
target={8}
|
|
26
|
-
title="Your laps"
|
|
27
|
-
unit="laps"
|
|
24
|
+
data={{ progress: 3, target: 8, title: 'Your laps', unit: 'laps' }}
|
|
28
25
|
/>
|
|
29
26
|
</Flex>
|
|
30
27
|
<Flex {...stylex.props(styles.feature)}>
|
|
31
28
|
<Timer
|
|
32
|
-
durationSeconds={90}
|
|
33
29
|
id="TrackDayRecovery"
|
|
34
|
-
mode
|
|
35
|
-
title="Catch your breath"
|
|
30
|
+
data={{ durationSeconds: 90, mode: 'break', title: 'Catch your breath' }}
|
|
36
31
|
/>
|
|
37
32
|
</Flex>
|
|
38
33
|
</Flex>
|
|
39
34
|
<Flex {...stylex.props(styles.preparation)}>
|
|
40
35
|
<Checklist
|
|
41
36
|
id="TrackDayPreparation"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
data={{
|
|
38
|
+
items: [
|
|
39
|
+
{ id: 'water', label: 'Fill your water bottle' },
|
|
40
|
+
{ id: 'warmup', label: 'Walk a lap and loosen up' },
|
|
41
|
+
{ id: 'laces', label: 'Check your laces' },
|
|
42
|
+
],
|
|
43
|
+
title: 'Before the first lap',
|
|
44
|
+
}}
|
|
48
45
|
/>
|
|
49
46
|
</Flex>
|
|
50
47
|
</Flex>
|
|
@@ -62,15 +59,20 @@ export function FamilyRoutineComposition({ theme = kids }: { theme?: Composition
|
|
|
62
59
|
</Flex>
|
|
63
60
|
<Checklist
|
|
64
61
|
id="FamilyRoutineEvening"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
data={{
|
|
63
|
+
items: [
|
|
64
|
+
{ id: 'toys', label: 'Give every toy a home' },
|
|
65
|
+
{ id: 'bag', label: 'Pack tomorrow’s bag' },
|
|
66
|
+
{ id: 'teeth', label: 'Brush those teeth' },
|
|
67
|
+
],
|
|
68
|
+
title: 'Three small things',
|
|
69
|
+
}}
|
|
71
70
|
/>
|
|
72
71
|
<Flex {...stylex.props(styles.preparation)}>
|
|
73
|
-
<Timer
|
|
72
|
+
<Timer
|
|
73
|
+
id="FamilyRoutineStory"
|
|
74
|
+
data={{ durationSeconds: 600, title: 'Time for a story' }}
|
|
75
|
+
/>
|
|
74
76
|
</Flex>
|
|
75
77
|
</Flex>
|
|
76
78
|
)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Flex, Text } from '@flickfyi/core'
|
|
2
|
+
import * as stylex from '@stylexjs/stylex'
|
|
3
|
+
import { DateTime } from 'luxon'
|
|
4
|
+
import { z } from 'zod/v4'
|
|
5
|
+
|
|
6
|
+
import { useClock } from '~/hooks/use-clock'
|
|
7
|
+
import { useConfiguredFeature } from '~/hooks/use-configured-feature'
|
|
8
|
+
import type { CreateSchemas } from '~/kowalski/create-schemas'
|
|
9
|
+
import { space, text } from '~/themes/scale.stylex'
|
|
10
|
+
import { appearance, roles } from '~/themes/shared'
|
|
11
|
+
|
|
12
|
+
import { featureFields, store } from './feature-schema'
|
|
13
|
+
import { format } from './format'
|
|
14
|
+
import { FeatureAction, FeatureFrame, FeatureWell, layout } from './frame'
|
|
15
|
+
|
|
16
|
+
const defaultId = 'KowalskiTimeSince'
|
|
17
|
+
const defaultScope = 'public'
|
|
18
|
+
|
|
19
|
+
export const TimeSinceData = /* @__PURE__ */ z
|
|
20
|
+
.strictObject({
|
|
21
|
+
action: z
|
|
22
|
+
.string()
|
|
23
|
+
.describe(
|
|
24
|
+
'The big button that updates it, as a short command for doing it now, e.g. "Give pill" or "Water plants".'
|
|
25
|
+
),
|
|
26
|
+
label: z
|
|
27
|
+
.string()
|
|
28
|
+
.describe(
|
|
29
|
+
'A small line above the title naming the kind of tracker, e.g. "Pill timer". Pass an empty string to hide it.'
|
|
30
|
+
),
|
|
31
|
+
subject: z
|
|
32
|
+
.string()
|
|
33
|
+
.describe(
|
|
34
|
+
'What gets done, as a short noun, e.g. "pill" or "watering". With "pill", the timestamp reads "Last pill today at 5:04 PM".'
|
|
35
|
+
),
|
|
36
|
+
title: z
|
|
37
|
+
.string()
|
|
38
|
+
.describe(
|
|
39
|
+
'Who or what is being tracked, shown as the heading, e.g. "Winnie" or "Fern".'
|
|
40
|
+
),
|
|
41
|
+
})
|
|
42
|
+
.describe(
|
|
43
|
+
'Four short UI strings for an existing TimeSince React component: a heading, tracker label, event noun, and button command. The component already implements the elapsed clock, reset button, and saved state. Supply concise copy for each field, not explanations, implementation instructions, timestamps, or claims about the timer’s current state.'
|
|
44
|
+
)
|
|
45
|
+
export type TimeSinceData = z.input<typeof TimeSinceData>
|
|
46
|
+
|
|
47
|
+
export const TimeSinceProps = z.strictObject({
|
|
48
|
+
data: TimeSinceData,
|
|
49
|
+
...featureFields,
|
|
50
|
+
scope: featureFields.scope.default(defaultScope),
|
|
51
|
+
})
|
|
52
|
+
export type TimeSinceProps = z.input<typeof TimeSinceProps> & {
|
|
53
|
+
style?: stylex.StyleXArray<stylex.StyleXStyles>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const timeSinceStoreSchema = store({ lastAt: z.number().nullable().default(null) })
|
|
57
|
+
|
|
58
|
+
export const createSchemas: CreateSchemas = ({
|
|
59
|
+
id = defaultId,
|
|
60
|
+
scope = defaultScope,
|
|
61
|
+
} = {}) => ({
|
|
62
|
+
[`stores/${scope}/${id}`]: timeSinceStoreSchema,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
export function TimeSince({
|
|
66
|
+
data,
|
|
67
|
+
id = defaultId,
|
|
68
|
+
revision = 0,
|
|
69
|
+
scope = defaultScope,
|
|
70
|
+
style,
|
|
71
|
+
}: TimeSinceProps) {
|
|
72
|
+
const schema = timeSinceStoreSchema
|
|
73
|
+
const store = useConfiguredFeature({
|
|
74
|
+
name: id,
|
|
75
|
+
revision,
|
|
76
|
+
schema,
|
|
77
|
+
scope,
|
|
78
|
+
seed: schema.parse({}),
|
|
79
|
+
})
|
|
80
|
+
const lastAt = store.value.lastAt
|
|
81
|
+
const now = useClock(lastAt !== null, String(lastAt))
|
|
82
|
+
const loading = !store.ready && !store.error
|
|
83
|
+
const since = loading
|
|
84
|
+
? '—'
|
|
85
|
+
: lastAt === null
|
|
86
|
+
? 'Not yet'
|
|
87
|
+
: DateTime.fromMillis(lastAt).toRelative({
|
|
88
|
+
base: DateTime.fromMillis(now),
|
|
89
|
+
locale: format.locale,
|
|
90
|
+
})
|
|
91
|
+
return (
|
|
92
|
+
<FeatureFrame
|
|
93
|
+
onRetry={store.retry}
|
|
94
|
+
notice={store.error}
|
|
95
|
+
component="timeSince"
|
|
96
|
+
header={
|
|
97
|
+
<Flex {...stylex.props(layout.header)}>
|
|
98
|
+
{data.label && (
|
|
99
|
+
<Text {...stylex.props(roles.caption, appearance.accent)}>{data.label}</Text>
|
|
100
|
+
)}
|
|
101
|
+
<Text {...stylex.props(roles.h1)}>{data.title}</Text>
|
|
102
|
+
</Flex>
|
|
103
|
+
}
|
|
104
|
+
style={style}
|
|
105
|
+
title={data.title}
|
|
106
|
+
>
|
|
107
|
+
<FeatureWell style={timeSinceStyles.well}>
|
|
108
|
+
<Flex {...stylex.props(timeSinceStyles.reading)}>
|
|
109
|
+
<Text
|
|
110
|
+
animated={lastAt === null ? undefined : 'numeric'}
|
|
111
|
+
{...stylex.props(roles.display, timeSinceStyles.since)}
|
|
112
|
+
>
|
|
113
|
+
{since}
|
|
114
|
+
</Text>
|
|
115
|
+
{lastAt !== null && (
|
|
116
|
+
<Text {...stylex.props(roles.caption)}>
|
|
117
|
+
{`Last ${data.subject} ${DateTime.fromMillis(lastAt).toRelativeCalendar({
|
|
118
|
+
base: DateTime.fromMillis(now),
|
|
119
|
+
locale: format.locale,
|
|
120
|
+
unit: 'days',
|
|
121
|
+
})} at ${format.formatTime(lastAt, { hour: 'numeric', minute: '2-digit' })}`}
|
|
122
|
+
</Text>
|
|
123
|
+
)}
|
|
124
|
+
</Flex>
|
|
125
|
+
<FeatureAction
|
|
126
|
+
component="timeSince"
|
|
127
|
+
disabled={!store.ready}
|
|
128
|
+
onClick={() => store.set(() => ({ lastAt: Date.now() }))}
|
|
129
|
+
size="lg"
|
|
130
|
+
variant="primary"
|
|
131
|
+
>
|
|
132
|
+
{data.action}
|
|
133
|
+
</FeatureAction>
|
|
134
|
+
</FeatureWell>
|
|
135
|
+
{store.saving && <Text {...stylex.props(roles.muted)}>Saving…</Text>}
|
|
136
|
+
</FeatureFrame>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const timeSinceStyles = /* @__PURE__ */ stylex.create({
|
|
141
|
+
reading: { alignItems: 'flex-start', gap: space[3] },
|
|
142
|
+
// 60px keeps "59 seconds" on one line of a 393pt-wide phone card; "ago" wraps below.
|
|
143
|
+
since: { fontSize: text['6xl'], lineHeight: text['6xlLeading'] },
|
|
144
|
+
well: { alignItems: 'stretch', gap: space[4] },
|
|
145
|
+
})
|
|
@@ -24,7 +24,10 @@ export function Progress({
|
|
|
24
24
|
const fill = stylex.props(styles.progressFill, fillStyle)
|
|
25
25
|
return (
|
|
26
26
|
<Flex {...stylex.props(styles.progressTrack, style)}>
|
|
27
|
-
<Flex
|
|
27
|
+
<Flex
|
|
28
|
+
{...fill}
|
|
29
|
+
style={{ ...fill.style, width: spring.width.to(value => `${value}%`) }}
|
|
30
|
+
/>
|
|
28
31
|
</Flex>
|
|
29
32
|
)
|
|
30
33
|
}
|
|
@@ -64,12 +64,7 @@ export function parseOklch(css: string): string {
|
|
|
64
64
|
return css
|
|
65
65
|
}
|
|
66
66
|
const l = Number(m[1]) / (m[2] === '%' ? 100 : 1)
|
|
67
|
-
return oklchToRgba(
|
|
68
|
-
l,
|
|
69
|
-
Number(m[3]),
|
|
70
|
-
Number(m[4]),
|
|
71
|
-
m[5] === undefined ? 1 : Number(m[5])
|
|
72
|
-
)
|
|
67
|
+
return oklchToRgba(l, Number(m[3]), Number(m[4]), m[5] === undefined ? 1 : Number(m[5]))
|
|
73
68
|
}
|
|
74
69
|
|
|
75
70
|
/**
|
|
@@ -22,7 +22,9 @@ type Foreground = NonNullable<NonNullable<Core.TextProps['style']>['color']>
|
|
|
22
22
|
|
|
23
23
|
/** Opaque styles accepted by the public StyleX composition API. */
|
|
24
24
|
export type ParrotStyle = stylex.StyleXArray<
|
|
25
|
-
|
|
25
|
+
| stylex.StyleXStyles
|
|
26
|
+
| stylex.StyleXStyles<{ color: Foreground }>
|
|
27
|
+
| ReturnType<typeof stylex.createTheme>
|
|
26
28
|
>
|
|
27
29
|
|
|
28
30
|
export type ParrotTheme = {
|
|
@@ -7,7 +7,12 @@ export const spec = {
|
|
|
7
7
|
display: { family: '"Instrument Serif"', step: '6xl', weight: '400' },
|
|
8
8
|
emphasis: { italic: true, weight: '400' },
|
|
9
9
|
fonts: { body: 'Newsreader', ui: '"Libre Franklin"', uiWeight: '600' },
|
|
10
|
-
heading: {
|
|
10
|
+
heading: {
|
|
11
|
+
family: '"Instrument Serif"',
|
|
12
|
+
step: '5xl',
|
|
13
|
+
tracking: 'tight',
|
|
14
|
+
weight: '400',
|
|
15
|
+
},
|
|
11
16
|
label: { uppercase: true },
|
|
12
17
|
radius: 0,
|
|
13
18
|
stroke: 1,
|
|
@@ -186,7 +186,7 @@ const palettes: Record<
|
|
|
186
186
|
},
|
|
187
187
|
}),
|
|
188
188
|
// Newsprint: the paper drifts warm whatever the hue, which becomes a spot ink.
|
|
189
|
-
editorial
|
|
189
|
+
editorial(hue) {
|
|
190
190
|
const paper = toward(hue, 85, 0.8)
|
|
191
191
|
return {
|
|
192
192
|
dark: {
|
|
@@ -218,7 +218,7 @@ const palettes: Record<
|
|
|
218
218
|
}
|
|
219
219
|
},
|
|
220
220
|
// A legal pad: cream paper, ballpoint ink and ruled lines in the hue.
|
|
221
|
-
handwritten
|
|
221
|
+
handwritten(hue) {
|
|
222
222
|
const paper = toward(hue, 95, 0.85)
|
|
223
223
|
return {
|
|
224
224
|
dark: {
|
|
@@ -249,7 +249,7 @@ const palettes: Record<
|
|
|
249
249
|
}
|
|
250
250
|
},
|
|
251
251
|
// Candy pairs: the tray takes the hue's far side, the actions take the hue.
|
|
252
|
-
kids
|
|
252
|
+
kids(hue) {
|
|
253
253
|
const pop = turn(hue, 150)
|
|
254
254
|
return {
|
|
255
255
|
dark: {
|
|
@@ -288,7 +288,7 @@ const palettes: Record<
|
|
|
288
288
|
}
|
|
289
289
|
},
|
|
290
290
|
// Sherbet: the tray warms 40° past the hue and the page cools 25° below it.
|
|
291
|
-
rounded
|
|
291
|
+
rounded(hue) {
|
|
292
292
|
const cool = turn(hue, -25)
|
|
293
293
|
const warm = turn(hue, 40)
|
|
294
294
|
return {
|
|
@@ -323,7 +323,7 @@ const palettes: Record<
|
|
|
323
323
|
}
|
|
324
324
|
},
|
|
325
325
|
// A bench instrument: cool steel housing, and the hue lights the display.
|
|
326
|
-
technical
|
|
326
|
+
technical(hue) {
|
|
327
327
|
const steel = toward(hue, 250, 0.7)
|
|
328
328
|
return {
|
|
329
329
|
dark: {
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { Flex, Text } from '@flickfyi/core'
|
|
2
2
|
import { Button, Container } from '@flickfyi/core/atoms'
|
|
3
|
-
import {
|
|
4
|
-
Card,
|
|
5
|
-
Choice,
|
|
6
|
-
completedTaskStyle,
|
|
7
|
-
List,
|
|
8
|
-
Stat,
|
|
9
|
-
} from '@flickfyi/core/molecules'
|
|
3
|
+
import { Card, Choice, completedTaskStyle, List, Stat } from '@flickfyi/core/molecules'
|
|
10
4
|
import * as stylex from '@stylexjs/stylex'
|
|
11
5
|
import { useState } from 'react'
|
|
12
6
|
|
|
13
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
previewTheme,
|
|
9
|
+
type ThemeGlobals,
|
|
10
|
+
themeSelection,
|
|
11
|
+
} from '~/storybook/theme-fixtures'
|
|
14
12
|
import { space } from '~/themes/scale.stylex'
|
|
15
13
|
import { colors, shape } from '~/themes/tokens.stylex'
|
|
16
14
|
|
|
@@ -261,7 +259,11 @@ export function ThemeComposition({ globals }: { globals: Partial<ThemeGlobals> }
|
|
|
261
259
|
checked ? [...items, item] : items.filter(value => value !== item)
|
|
262
260
|
)
|
|
263
261
|
}
|
|
264
|
-
style={[
|
|
262
|
+
style={[
|
|
263
|
+
theme.surface,
|
|
264
|
+
styles.tile,
|
|
265
|
+
selected.includes(item) && theme.selected,
|
|
266
|
+
]}
|
|
265
267
|
>
|
|
266
268
|
{item}
|
|
267
269
|
</Choice>
|