@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.
Files changed (243) hide show
  1. package/dist/{api-client-CAg1b8Bh.js → api-client-nn4U_Vfn.js} +1 -1
  2. package/dist/{app-DpM5nhb9.js → app-COXGJhrt.js} +3 -3
  3. package/dist/{bundler-DNrDcqyk.js → bundler-CW4YC73e.js} +4 -2
  4. package/dist/cli.js +11 -11
  5. package/dist/{delegate-DcVye0KE.js → delegate-aUVluBjB.js} +2 -2
  6. package/dist/{generate-B1l1z_FZ.js → generate-BeL1QPDi.js} +1 -1
  7. package/dist/{preview-Dqn_Tq6K.js → preview-DTVM8Csb.js} +2 -2
  8. package/dist/{publish-BmDqO1xU.js → publish-BJG-s-w5.js} +4 -4
  9. package/dist/{pull-CO80DMn8.js → pull-B_Yfjpi2.js} +1 -1
  10. package/dist/{save-8crfOeo1.js → save-UrfgmK2-.js} +2 -2
  11. package/dist/{sdk-app-BXWrf_pf.js → sdk-app-BAxznAf9.js} +3 -3
  12. package/dist/{sdk-deploy-CaEonlvx.js → sdk-deploy-D1wgQxse.js} +3 -3
  13. package/dist/{sdk-generation-CF8ATbrL.js → sdk-generation-CLQ-QrVM.js} +1 -1
  14. package/dist/{sdk-project-CKV3U3u9.js → sdk-project-BaO0fqhW.js} +1 -1
  15. package/dist/{use-auth-B6nwU2rp.js → use-auth-CtM4_BAY.js} +1 -1
  16. package/node_modules/@flickfyi/biscuit/.turbo/turbo-build.log +4 -4
  17. package/node_modules/@flickfyi/core/README.md +19 -9
  18. package/node_modules/@flickfyi/core/dist/chunks/{default-CuxDsQoM.js → default-BTmKidHV.js} +1 -1
  19. package/node_modules/@flickfyi/core/dist/chunks/{default-BB6YexEH.cjs → default-JhTq5I_y.cjs} +1 -1
  20. package/node_modules/@flickfyi/core/dist/chunks/{define-CUJRqVKY.cjs → define-BKCRhpuY.cjs} +1 -1
  21. package/node_modules/@flickfyi/core/dist/chunks/{define-e_VqSs4M.js → define-DZXgUsy7.js} +5 -5
  22. package/node_modules/@flickfyi/core/dist/kowalski/catalog.cjs +1 -1
  23. package/node_modules/@flickfyi/core/dist/kowalski/catalog.js +728 -549
  24. package/node_modules/@flickfyi/core/dist/kowalski/index.cjs +5 -5
  25. package/node_modules/@flickfyi/core/dist/kowalski/index.js +4297 -3700
  26. package/node_modules/@flickfyi/core/dist/kowalski/schemas.cjs +1 -0
  27. package/node_modules/@flickfyi/core/dist/kowalski/schemas.js +637 -0
  28. package/node_modules/@flickfyi/core/dist/kowalski-catalog.css +516 -0
  29. package/node_modules/@flickfyi/core/dist/kowalski.css +10 -0
  30. package/node_modules/@flickfyi/core/dist/themes/athletic/athletic.cjs +1 -1
  31. package/node_modules/@flickfyi/core/dist/themes/athletic/athletic.js +1 -1
  32. package/node_modules/@flickfyi/core/dist/themes/compact/compact.cjs +1 -1
  33. package/node_modules/@flickfyi/core/dist/themes/compact/compact.js +1 -1
  34. package/node_modules/@flickfyi/core/dist/themes/default/default.cjs +1 -1
  35. package/node_modules/@flickfyi/core/dist/themes/default/default.js +1 -1
  36. package/node_modules/@flickfyi/core/dist/themes/editorial/editorial.cjs +1 -1
  37. package/node_modules/@flickfyi/core/dist/themes/editorial/editorial.js +1 -1
  38. package/node_modules/@flickfyi/core/dist/themes/handwritten/handwritten.cjs +1 -1
  39. package/node_modules/@flickfyi/core/dist/themes/handwritten/handwritten.js +1 -1
  40. package/node_modules/@flickfyi/core/dist/themes/index.cjs +1 -1
  41. package/node_modules/@flickfyi/core/dist/themes/index.js +1 -1
  42. package/node_modules/@flickfyi/core/dist/themes/kids/kids.cjs +1 -1
  43. package/node_modules/@flickfyi/core/dist/themes/kids/kids.js +1 -1
  44. package/node_modules/@flickfyi/core/dist/themes/rounded/rounded.cjs +1 -1
  45. package/node_modules/@flickfyi/core/dist/themes/rounded/rounded.js +1 -1
  46. package/node_modules/@flickfyi/core/dist/themes/technical/technical.cjs +1 -1
  47. package/node_modules/@flickfyi/core/dist/themes/technical/technical.js +1 -1
  48. package/node_modules/@flickfyi/core/dist-types/hooks/use-feature-store/index.d.ts +43 -0
  49. package/node_modules/@flickfyi/core/dist-types/kowalski/calculations.d.ts +57 -3
  50. package/node_modules/@flickfyi/core/dist-types/kowalski/calculator.d.ts +7 -6
  51. package/node_modules/@flickfyi/core/dist-types/kowalski/catalog.d.cts +524 -809
  52. package/node_modules/@flickfyi/core/dist-types/kowalski/catalog.d.ts +524 -809
  53. package/node_modules/@flickfyi/core/dist-types/kowalski/components/bill-split.d.ts +38 -0
  54. package/node_modules/@flickfyi/core/dist-types/kowalski/components/bookmark.d.ts +48 -0
  55. package/node_modules/@flickfyi/core/dist-types/kowalski/components/budget.d.ts +39 -0
  56. package/node_modules/@flickfyi/core/dist-types/kowalski/components/calculator.d.ts +62 -0
  57. package/node_modules/@flickfyi/core/dist-types/kowalski/components/checklist.d.ts +35 -0
  58. package/node_modules/@flickfyi/core/dist-types/kowalski/components/color-palette.d.ts +32 -0
  59. package/node_modules/@flickfyi/core/dist-types/kowalski/components/contact.d.ts +41 -0
  60. package/node_modules/@flickfyi/core/dist-types/kowalski/components/countdown.d.ts +34 -0
  61. package/node_modules/@flickfyi/core/dist-types/kowalski/components/event.d.ts +43 -0
  62. package/node_modules/@flickfyi/core/dist-types/kowalski/components/expense.d.ts +40 -0
  63. package/node_modules/@flickfyi/core/dist-types/kowalski/components/goal.d.ts +36 -0
  64. package/node_modules/@flickfyi/core/dist-types/kowalski/components/habit.d.ts +57 -0
  65. package/node_modules/@flickfyi/core/dist-types/kowalski/components/ledger.d.ts +43 -0
  66. package/node_modules/@flickfyi/core/dist-types/kowalski/components/note.d.ts +35 -0
  67. package/node_modules/@flickfyi/core/dist-types/kowalski/components/poll.d.ts +41 -0
  68. package/node_modules/@flickfyi/core/dist-types/kowalski/components/random-picker.d.ts +69 -0
  69. package/node_modules/@flickfyi/core/dist-types/kowalski/components/rating.d.ts +33 -0
  70. package/node_modules/@flickfyi/core/dist-types/kowalski/components/reminder.d.ts +48 -0
  71. package/node_modules/@flickfyi/core/dist-types/kowalski/components/rotation.d.ts +39 -0
  72. package/node_modules/@flickfyi/core/dist-types/kowalski/components/scoreboard.d.ts +37 -0
  73. package/node_modules/@flickfyi/core/dist-types/kowalski/components/shopping-list.d.ts +41 -0
  74. package/node_modules/@flickfyi/core/dist-types/kowalski/components/task-board.d.ts +39 -0
  75. package/node_modules/@flickfyi/core/dist-types/kowalski/components/time-zone.d.ts +34 -0
  76. package/node_modules/@flickfyi/core/dist-types/kowalski/components/timer.d.ts +43 -0
  77. package/node_modules/@flickfyi/core/dist-types/kowalski/components/trip.d.ts +61 -0
  78. package/node_modules/@flickfyi/core/dist-types/kowalski/components/unit-converter.d.ts +106 -0
  79. package/node_modules/@flickfyi/core/dist-types/kowalski/create-schemas.d.ts +6 -0
  80. package/node_modules/@flickfyi/core/dist-types/kowalski/date-time.d.ts +1 -1
  81. package/node_modules/@flickfyi/core/dist-types/kowalski/everyday.d.ts +28 -8
  82. package/node_modules/@flickfyi/core/dist-types/kowalski/feature-schema.d.ts +65 -0
  83. package/node_modules/@flickfyi/core/dist-types/kowalski/format.d.ts +4 -0
  84. package/node_modules/@flickfyi/core/dist-types/kowalski/fortune.d.ts +21 -0
  85. package/node_modules/@flickfyi/core/dist-types/kowalski/frame.d.ts +4 -4
  86. package/node_modules/@flickfyi/core/dist-types/kowalski/index.d.cts +31 -7
  87. package/node_modules/@flickfyi/core/dist-types/kowalski/index.d.ts +31 -7
  88. package/node_modules/@flickfyi/core/dist-types/kowalski/lesson.d.ts +89 -0
  89. package/node_modules/@flickfyi/core/dist-types/kowalski/recipe.d.ts +129 -8
  90. package/node_modules/@flickfyi/core/dist-types/kowalski/schemas.d.cts +4 -0
  91. package/node_modules/@flickfyi/core/dist-types/kowalski/schemas.d.ts +4 -0
  92. package/node_modules/@flickfyi/core/dist-types/kowalski/time-since.d.ts +34 -0
  93. package/node_modules/@flickfyi/core/examples/example-metadata.ts +19 -2
  94. package/node_modules/@flickfyi/core/examples/kowalski/bill-split/bill-split.stories.tsx +25 -6
  95. package/node_modules/@flickfyi/core/examples/kowalski/bill-split/bill-split.tsx +6 -12
  96. package/node_modules/@flickfyi/core/examples/kowalski/bookmark/bookmark.stories.tsx +22 -5
  97. package/node_modules/@flickfyi/core/examples/kowalski/bookmark/bookmark.tsx +6 -18
  98. package/node_modules/@flickfyi/core/examples/kowalski/budget/budget.stories.tsx +26 -5
  99. package/node_modules/@flickfyi/core/examples/kowalski/budget/budget.tsx +6 -21
  100. package/node_modules/@flickfyi/core/examples/kowalski/calculator/calculator.stories.tsx +18 -5
  101. package/node_modules/@flickfyi/core/examples/kowalski/calculator/calculator.tsx +6 -19
  102. package/node_modules/@flickfyi/core/examples/kowalski/checklist/checklist.stories.tsx +25 -5
  103. package/node_modules/@flickfyi/core/examples/kowalski/checklist/checklist.tsx +6 -21
  104. package/node_modules/@flickfyi/core/examples/kowalski/color-palette/color-palette.stories.tsx +19 -6
  105. package/node_modules/@flickfyi/core/examples/kowalski/color-palette/color-palette.tsx +6 -17
  106. package/node_modules/@flickfyi/core/examples/kowalski/contact/contact.stories.tsx +30 -5
  107. package/node_modules/@flickfyi/core/examples/kowalski/contact/contact.tsx +6 -18
  108. package/node_modules/@flickfyi/core/examples/kowalski/countdown/countdown.stories.tsx +22 -5
  109. package/node_modules/@flickfyi/core/examples/kowalski/countdown/countdown.tsx +6 -18
  110. package/node_modules/@flickfyi/core/examples/kowalski/event/event.stories.tsx +23 -5
  111. package/node_modules/@flickfyi/core/examples/kowalski/event/event.tsx +6 -19
  112. package/node_modules/@flickfyi/core/examples/kowalski/expense/expense.stories.tsx +23 -5
  113. package/node_modules/@flickfyi/core/examples/kowalski/expense/expense.tsx +6 -18
  114. package/node_modules/@flickfyi/core/examples/kowalski/fortune/fortune.stories.tsx +61 -0
  115. package/node_modules/@flickfyi/core/examples/kowalski/fortune/fortune.tsx +11 -0
  116. package/node_modules/@flickfyi/core/examples/kowalski/goal/goal.stories.tsx +18 -5
  117. package/node_modules/@flickfyi/core/examples/kowalski/goal/goal.tsx +3 -19
  118. package/node_modules/@flickfyi/core/examples/kowalski/habit/habit.stories.tsx +22 -5
  119. package/node_modules/@flickfyi/core/examples/kowalski/habit/habit.tsx +6 -18
  120. package/node_modules/@flickfyi/core/examples/kowalski/ledger/ledger.stories.tsx +25 -5
  121. package/node_modules/@flickfyi/core/examples/kowalski/ledger/ledger.tsx +6 -20
  122. package/node_modules/@flickfyi/core/examples/kowalski/lesson/lesson.stories.tsx +99 -0
  123. package/node_modules/@flickfyi/core/examples/kowalski/lesson/lesson.tsx +11 -0
  124. package/node_modules/@flickfyi/core/examples/kowalski/note/note.stories.tsx +21 -5
  125. package/node_modules/@flickfyi/core/examples/kowalski/note/note.tsx +3 -17
  126. package/node_modules/@flickfyi/core/examples/kowalski/poll/poll.stories.tsx +26 -5
  127. package/node_modules/@flickfyi/core/examples/kowalski/poll/poll.tsx +3 -21
  128. package/node_modules/@flickfyi/core/examples/kowalski/random-picker/random-picker.stories.tsx +37 -6
  129. package/node_modules/@flickfyi/core/examples/kowalski/random-picker/random-picker.tsx +6 -18
  130. package/node_modules/@flickfyi/core/examples/kowalski/rating/rating.stories.tsx +18 -5
  131. package/node_modules/@flickfyi/core/examples/kowalski/rating/rating.tsx +6 -14
  132. package/node_modules/@flickfyi/core/examples/kowalski/recipe/recipe.stories.tsx +117 -5
  133. package/node_modules/@flickfyi/core/examples/kowalski/recipe/recipe.tsx +6 -115
  134. package/node_modules/@flickfyi/core/examples/kowalski/reminder/reminder.stories.tsx +22 -5
  135. package/node_modules/@flickfyi/core/examples/kowalski/reminder/reminder.tsx +6 -18
  136. package/node_modules/@flickfyi/core/examples/kowalski/rotation/rotation.stories.tsx +26 -5
  137. package/node_modules/@flickfyi/core/examples/kowalski/rotation/rotation.tsx +6 -22
  138. package/node_modules/@flickfyi/core/examples/kowalski/scoreboard/scoreboard.stories.tsx +26 -5
  139. package/node_modules/@flickfyi/core/examples/kowalski/scoreboard/scoreboard.tsx +6 -21
  140. package/node_modules/@flickfyi/core/examples/kowalski/shopping-list/shopping-list.stories.tsx +28 -6
  141. package/node_modules/@flickfyi/core/examples/kowalski/shopping-list/shopping-list.tsx +6 -22
  142. package/node_modules/@flickfyi/core/examples/kowalski/task-board/task-board.stories.tsx +27 -6
  143. package/node_modules/@flickfyi/core/examples/kowalski/task-board/task-board.tsx +6 -22
  144. package/node_modules/@flickfyi/core/examples/kowalski/time-since/time-since.stories.tsx +33 -0
  145. package/node_modules/@flickfyi/core/examples/kowalski/time-since/time-since.tsx +12 -0
  146. package/node_modules/@flickfyi/core/examples/kowalski/time-zone/time-zone.stories.tsx +22 -6
  147. package/node_modules/@flickfyi/core/examples/kowalski/time-zone/time-zone.tsx +6 -17
  148. package/node_modules/@flickfyi/core/examples/kowalski/timer/timer.stories.tsx +18 -5
  149. package/node_modules/@flickfyi/core/examples/kowalski/timer/timer.tsx +6 -18
  150. package/node_modules/@flickfyi/core/examples/kowalski/trip/trip.stories.tsx +25 -5
  151. package/node_modules/@flickfyi/core/examples/kowalski/trip/trip.tsx +3 -21
  152. package/node_modules/@flickfyi/core/examples/kowalski/unit-converter/unit-converter.stories.tsx +19 -6
  153. package/node_modules/@flickfyi/core/examples/kowalski/unit-converter/unit-converter.tsx +6 -19
  154. package/node_modules/@flickfyi/core/examples/parrott/calculator/calculator.stories.tsx +10 -3
  155. package/node_modules/@flickfyi/core/examples/parrott/calculator/calculator.tsx +2 -13
  156. package/node_modules/@flickfyi/core/examples/parrott/checklist/checklist.stories.tsx +10 -3
  157. package/node_modules/@flickfyi/core/examples/parrott/checklist/checklist.tsx +0 -8
  158. package/node_modules/@flickfyi/core/examples/parrott/countdown/countdown.stories.tsx +10 -3
  159. package/node_modules/@flickfyi/core/examples/parrott/countdown/countdown.tsx +0 -8
  160. package/node_modules/@flickfyi/core/examples/parrott/counter/counter.stories.tsx +10 -3
  161. package/node_modules/@flickfyi/core/examples/parrott/counter/counter.tsx +0 -8
  162. package/node_modules/@flickfyi/core/examples/parrott/fortune/fortune.stories.tsx +10 -3
  163. package/node_modules/@flickfyi/core/examples/parrott/fortune/fortune.tsx +0 -8
  164. package/node_modules/@flickfyi/core/examples/parrott/grid/grid.stories.tsx +10 -3
  165. package/node_modules/@flickfyi/core/examples/parrott/grid/grid.tsx +4 -9
  166. package/node_modules/@flickfyi/core/examples/parrott/kale-smoothie/kale-smoothie.stories.tsx +10 -3
  167. package/node_modules/@flickfyi/core/examples/parrott/kale-smoothie/kale-smoothie.tsx +0 -8
  168. package/node_modules/@flickfyi/core/examples/parrott/list/list.stories.tsx +10 -3
  169. package/node_modules/@flickfyi/core/examples/parrott/list/list.tsx +0 -8
  170. package/node_modules/@flickfyi/core/examples/parrott/log/log.stories.tsx +10 -3
  171. package/node_modules/@flickfyi/core/examples/parrott/log/log.tsx +0 -8
  172. package/node_modules/@flickfyi/core/examples/parrott/timed-task/timed-task.stories.tsx +10 -3
  173. package/node_modules/@flickfyi/core/examples/parrott/timed-task/timed-task.tsx +0 -8
  174. package/node_modules/@flickfyi/core/examples/parrott/timer/timer.stories.tsx +10 -3
  175. package/node_modules/@flickfyi/core/examples/parrott/timer/timer.tsx +0 -8
  176. package/node_modules/@flickfyi/core/package.json +16 -3
  177. package/node_modules/@flickfyi/core/src/{kowalski/use-configured-feature.ts → hooks/use-configured-feature/index.ts} +1 -1
  178. package/node_modules/@flickfyi/core/src/{kowalski/use-feature-store.ts → hooks/use-feature-store/index.ts} +37 -12
  179. package/node_modules/@flickfyi/core/src/kowalski/README.md +13 -0
  180. package/node_modules/@flickfyi/core/src/kowalski/calculations.ts +36 -8
  181. package/node_modules/@flickfyi/core/src/kowalski/calculator.ts +15 -7
  182. package/node_modules/@flickfyi/core/src/kowalski/catalog.ts +110 -704
  183. package/node_modules/@flickfyi/core/src/kowalski/components/bill-split.tsx +284 -0
  184. package/node_modules/@flickfyi/core/src/kowalski/components/bookmark.tsx +347 -0
  185. package/node_modules/@flickfyi/core/src/kowalski/components/budget.tsx +169 -0
  186. package/node_modules/@flickfyi/core/src/kowalski/components/calculator.tsx +202 -0
  187. package/node_modules/@flickfyi/core/src/kowalski/components/checklist.tsx +119 -0
  188. package/node_modules/@flickfyi/core/src/kowalski/components/color-palette.tsx +302 -0
  189. package/node_modules/@flickfyi/core/src/kowalski/components/contact.tsx +247 -0
  190. package/node_modules/@flickfyi/core/src/kowalski/components/countdown.tsx +173 -0
  191. package/node_modules/@flickfyi/core/src/kowalski/components/event.tsx +260 -0
  192. package/node_modules/@flickfyi/core/src/kowalski/components/expense.tsx +257 -0
  193. package/node_modules/@flickfyi/core/src/kowalski/components/goal.tsx +182 -0
  194. package/node_modules/@flickfyi/core/src/kowalski/components/habit.tsx +272 -0
  195. package/node_modules/@flickfyi/core/src/kowalski/components/ledger.tsx +211 -0
  196. package/node_modules/@flickfyi/core/src/kowalski/components/note.tsx +188 -0
  197. package/node_modules/@flickfyi/core/src/kowalski/components/poll.tsx +242 -0
  198. package/node_modules/@flickfyi/core/src/kowalski/components/random-picker.tsx +308 -0
  199. package/node_modules/@flickfyi/core/src/kowalski/components/rating.tsx +112 -0
  200. package/node_modules/@flickfyi/core/src/kowalski/components/reminder.tsx +298 -0
  201. package/node_modules/@flickfyi/core/src/kowalski/components/rotation.tsx +146 -0
  202. package/node_modules/@flickfyi/core/src/kowalski/components/scoreboard.tsx +139 -0
  203. package/node_modules/@flickfyi/core/src/kowalski/components/shopping-list.tsx +144 -0
  204. package/node_modules/@flickfyi/core/src/kowalski/components/task-board.tsx +146 -0
  205. package/node_modules/@flickfyi/core/src/kowalski/components/time-zone.tsx +240 -0
  206. package/node_modules/@flickfyi/core/src/kowalski/components/timer.tsx +225 -0
  207. package/node_modules/@flickfyi/core/src/kowalski/components/trip.tsx +338 -0
  208. package/node_modules/@flickfyi/core/src/kowalski/components/unit-converter.tsx +285 -0
  209. package/node_modules/@flickfyi/core/src/kowalski/create-schemas.ts +8 -0
  210. package/node_modules/@flickfyi/core/src/kowalski/date-time.tsx +1 -1
  211. package/node_modules/@flickfyi/core/src/kowalski/everyday.tsx +1 -640
  212. package/node_modules/@flickfyi/core/src/kowalski/feature-schema.ts +84 -0
  213. package/node_modules/@flickfyi/core/src/kowalski/format.ts +29 -3
  214. package/node_modules/@flickfyi/core/src/kowalski/fortune.tsx +67 -0
  215. package/node_modules/@flickfyi/core/src/kowalski/frame.tsx +5 -6
  216. package/node_modules/@flickfyi/core/src/kowalski/index.ts +31 -22
  217. package/node_modules/@flickfyi/core/src/kowalski/lesson.tsx +564 -0
  218. package/node_modules/@flickfyi/core/src/kowalski/recipe.tsx +78 -37
  219. package/node_modules/@flickfyi/core/src/kowalski/schemas.ts +67 -0
  220. package/node_modules/@flickfyi/core/src/kowalski/stories/composition.tsx +22 -20
  221. package/node_modules/@flickfyi/core/src/kowalski/time-since.tsx +145 -0
  222. package/node_modules/@flickfyi/core/src/molecules/progress/progress.tsx +4 -1
  223. package/node_modules/@flickfyi/core/src/oklch.ts +1 -6
  224. package/node_modules/@flickfyi/core/src/parrott/theme.ts +3 -1
  225. package/node_modules/@flickfyi/core/src/themes/editorial/editorial.ts +6 -1
  226. package/node_modules/@flickfyi/core/src/themes/palette.ts +5 -5
  227. package/node_modules/@flickfyi/core/src/themes/stories/composition.tsx +11 -9
  228. package/node_modules/@flickfyi/core/src/themes/stories/gallery.tsx +7 -11
  229. package/node_modules/@flickfyi/core/tsgo.bun.lock +7 -7
  230. package/node_modules/@flickfyi/core/tsgo.package.json +1 -1
  231. package/package.json +2 -2
  232. package/node_modules/@flickfyi/core/dist-types/kowalski/clocks.d.ts +0 -4
  233. package/node_modules/@flickfyi/core/dist-types/kowalski/details.d.ts +0 -7
  234. package/node_modules/@flickfyi/core/dist-types/kowalski/productivity.d.ts +0 -5
  235. package/node_modules/@flickfyi/core/dist-types/kowalski/tools.d.ts +0 -7
  236. package/node_modules/@flickfyi/core/dist-types/kowalski/use-feature-store.d.ts +0 -15
  237. package/node_modules/@flickfyi/core/src/kowalski/clocks.tsx +0 -464
  238. package/node_modules/@flickfyi/core/src/kowalski/details.tsx +0 -1387
  239. package/node_modules/@flickfyi/core/src/kowalski/productivity.tsx +0 -575
  240. package/node_modules/@flickfyi/core/src/kowalski/tools.tsx +0 -1213
  241. /package/node_modules/@flickfyi/core/dist-types/{kowalski/use-clock.d.ts → hooks/use-clock/index.d.ts} +0 -0
  242. /package/node_modules/@flickfyi/core/dist-types/{kowalski/use-configured-feature.d.ts → hooks/use-configured-feature/index.d.ts} +0 -0
  243. /package/node_modules/@flickfyi/core/src/{kowalski/use-clock.ts → hooks/use-clock/index.ts} +0 -0
@@ -1,648 +1,9 @@
1
- import { Flex, Icon, Text } from '@flickfyi/core'
2
- import { Button, Input, Picker } from '@flickfyi/core/atoms'
3
- import {
4
- Choice,
5
- completedTaskStyle,
6
- Field,
7
- List,
8
- Segmented,
9
- Stat,
10
- Stepper,
11
- } from '@flickfyi/core/molecules'
12
1
  import * as stylex from '@stylexjs/stylex'
13
- import { useState } from 'react'
14
2
 
15
3
  import { size, space } from '~/themes/scale.stylex'
16
- import { appearance, button, roles } from '~/themes/shared'
17
4
  import { colors } from '~/themes/tokens.stylex'
18
5
 
19
- import { formatCurrency } from './calculations'
20
- import { kowalskiCatalog, type KowalskiInput } from './catalog'
21
- import { format, parseNumberInput } from './format'
22
- import {
23
- FeatureAction,
24
- FeatureFacts,
25
- FeatureField,
26
- FeatureFrame,
27
- FeatureProgress,
28
- FeatureWell,
29
- layout,
30
- } from './frame'
31
- import { useConfiguredFeature } from './use-configured-feature'
32
-
33
- export function Budget(input: KowalskiInput<'budget'>) {
34
- const props = kowalskiCatalog.budget.props.parse(input)
35
- const categories = props.categories
36
- const schema = kowalskiCatalog.budget.storeSchema
37
- const store = useConfiguredFeature({
38
- name: props.id ?? 'KowalskiBudget',
39
- revision: props.revision,
40
- schema,
41
- scope: props.scope,
42
- seed: schema.parse({}),
43
- })
44
- const [categoryId, setCategoryId] = useState(categories[0].id)
45
- const [amount, setAmount] = useState({ value: '' })
46
- const money = (value: number) => formatCurrency(value, props.currency)
47
- const spentOn = (id: string) => store.value[`spent_${id}`] ?? 0
48
- const spent = categories.reduce((total, category) => total + spentOn(category.id), 0)
49
- const limit = categories.reduce((total, category) => total + category.limit, 0)
50
- const left = limit - spent
51
- const category = categories.find(option => option.id === categoryId) ?? categories[0]
52
- const parsed = parseNumberInput(amount.value, props.currency)
53
- const valid =
54
- Number.isFinite(parsed) && parsed > 0 && parsed <= 1e12 - spentOn(category.id)
55
- return (
56
- <FeatureFrame
57
- onRetry={store.retry}
58
- notice={store.error}
59
- component="budget"
60
- title={props.title}
61
- trailing={
62
- <Text {...stylex.props(roles.muted, left < 0 && layout.notice)}>
63
- {left < 0 ? `${money(-left)} over` : `${money(left)} left`}
64
- </Text>
65
- }
66
- >
67
- <FeatureWell>
68
- <Stat>
69
- <Stat.Value>{money(spent)}</Stat.Value>
70
- <Stat.Caption>{`Spent of ${money(limit)}`}</Stat.Caption>
71
- </Stat>
72
- <FeatureProgress component="budget" value={Math.min(1, spent / limit)} />
73
- </FeatureWell>
74
- <FeatureFacts>
75
- {categories.map(option => (
76
- <List.Item
77
- description={
78
- spentOn(option.id) > option.limit
79
- ? `${money(spentOn(option.id) - option.limit)} over`
80
- : undefined
81
- }
82
- key={option.id}
83
- label={option.label}
84
- trailing={`${money(spentOn(option.id))} of ${money(option.limit)}`}
85
- />
86
- ))}
87
- </FeatureFacts>
88
- <Field
89
- error={amount.value && !valid && 'Enter an amount within the supported range.'}
90
- label="Add spending"
91
- >
92
- <Picker label="Category" value={category.id} onChange={setCategoryId}>
93
- {categories.map(option => (
94
- <Text key={option.id} value={option.id}>
95
- {option.label}
96
- </Text>
97
- ))}
98
- </Picker>
99
- <Input
100
- placeholder="Amount"
101
- value={amount.value}
102
- onChange={value => setAmount({ value })}
103
- style={[layout.input]}
104
- />
105
- </Field>
106
- <FeatureAction
107
- component="budget"
108
- disabled={!valid || !store.ready || store.saving}
109
- icon="plus"
110
- size="lg"
111
- variant="primary"
112
- onClick={() =>
113
- store.set(
114
- current => ({
115
- [`spent_${category.id}`]: (current[`spent_${category.id}`] ?? 0) + parsed,
116
- }),
117
- () => setAmount(current => (current === amount ? { value: '' } : current))
118
- )
119
- }
120
- >
121
- {`Add to ${category.label}`}
122
- </FeatureAction>
123
- </FeatureFrame>
124
- )
125
- }
126
-
127
- export function Scoreboard(input: KowalskiInput<'scoreboard'>) {
128
- const props = kowalskiCatalog.scoreboard.props.parse(input)
129
- const players = props.players
130
- const schema = kowalskiCatalog.scoreboard.storeSchema
131
- const store = useConfiguredFeature({
132
- name: props.id ?? 'KowalskiScoreboard',
133
- revision: props.revision,
134
- schema,
135
- scope: props.scope,
136
- seed: schema.parse({}),
137
- })
138
- const scoreOf = (id: string) => store.value[`score_${id}`] ?? 0
139
- const best = Math.max(...players.map(player => scoreOf(player.id)))
140
- const leaders = players.filter(player => scoreOf(player.id) === best)
141
- const started = players.some(player => scoreOf(player.id) !== 0)
142
- const change = (id: string, direction: -1 | 1) =>
143
- store.set(current => ({
144
- [`score_${id}`]: (current[`score_${id}`] ?? 0) + direction * props.step,
145
- }))
146
- return (
147
- <FeatureFrame
148
- onRetry={store.retry}
149
- notice={store.error}
150
- component="scoreboard"
151
- title={props.title}
152
- trailing={
153
- <Text
154
- {...stylex.props(
155
- roles.muted,
156
- started && leaders.length === 1 && appearance.accent
157
- )}
158
- >
159
- {started
160
- ? leaders.length === 1
161
- ? `${leaders[0].label} leads`
162
- : `Tied at ${format.formatNumber(best)}`
163
- : 'No scores yet'}
164
- </Text>
165
- }
166
- >
167
- <FeatureFacts>
168
- {players.map(player => (
169
- <List.Item
170
- key={player.id}
171
- label={player.label}
172
- trailing={
173
- <Stepper
174
- decrementDisabled={!store.ready}
175
- decrementLabel={`Lower ${player.label}`}
176
- incrementDisabled={!store.ready}
177
- incrementLabel={`Raise ${player.label}`}
178
- onDecrement={() => change(player.id, -1)}
179
- onIncrement={() => change(player.id, 1)}
180
- >
181
- <Text {...stylex.props(roles.h2, everydayStyles.score)}>
182
- {format.formatNumber(scoreOf(player.id))}
183
- </Text>
184
- </Stepper>
185
- }
186
- />
187
- ))}
188
- </FeatureFacts>
189
- {started && (
190
- <FeatureAction
191
- component="scoreboard"
192
- disabled={!store.ready}
193
- icon="arrow.counterclockwise"
194
- onClick={() =>
195
- store.set(() =>
196
- Object.fromEntries(players.map(player => [`score_${player.id}`, 0]))
197
- )
198
- }
199
- >
200
- New game
201
- </FeatureAction>
202
- )}
203
- </FeatureFrame>
204
- )
205
- }
206
-
207
- export function TaskBoard(input: KowalskiInput<'taskBoard'>) {
208
- const props = kowalskiCatalog.taskBoard.props.parse(input)
209
- const tasks = props.tasks
210
- const schema = kowalskiCatalog.taskBoard.storeSchema
211
- const store = useConfiguredFeature({
212
- name: props.id ?? 'KowalskiTaskBoard',
213
- revision: props.revision,
214
- schema,
215
- scope: props.scope,
216
- seed: schema.parse({}),
217
- })
218
- const [column, setColumn] = useState<TaskStatus>('todo')
219
- const statusOf = (id: string): TaskStatus => store.value[`status_${id}`] ?? 'todo'
220
- const visible = tasks.filter(task => statusOf(task.id) === column)
221
- return (
222
- <FeatureFrame
223
- onRetry={store.retry}
224
- notice={store.error}
225
- component="taskBoard"
226
- title={props.title}
227
- trailing={
228
- <Text {...stylex.props(roles.muted)}>
229
- {`${format.formatNumber(tasks.filter(task => statusOf(task.id) === 'done').length)} of ${format.formatNumber(tasks.length)} done`}
230
- </Text>
231
- }
232
- >
233
- <Segmented
234
- options={taskColumns.map(option => ({
235
- label: `${option.label} ${format.formatNumber(tasks.filter(task => statusOf(task.id) === option.value).length)}`,
236
- value: option.value,
237
- }))}
238
- value={column}
239
- onChange={setColumn}
240
- />
241
- {visible.length === 0 ? (
242
- <FeatureWell style={everydayStyles.empty}>
243
- <Text {...stylex.props(roles.muted)}>
244
- {column === 'done' ? 'Nothing finished yet.' : 'Nothing here.'}
245
- </Text>
246
- </FeatureWell>
247
- ) : (
248
- <FeatureFacts>
249
- {visible.map(task => {
250
- const next: TaskStatus =
251
- column === 'todo' ? 'doing' : column === 'doing' ? 'done' : 'todo'
252
- return (
253
- <List.Item
254
- key={task.id}
255
- label={task.label}
256
- trailing={
257
- <Button
258
- accessibilityLabel={`${moveLabels[column]}: ${task.label}`}
259
- disabled={!store.ready}
260
- onClick={() => {
261
- store.set(() => ({ [`status_${task.id}`]: next }))
262
- }}
263
- style={[button.quiet, button.sm, layout.trailingAction]}
264
- >
265
- <Text>{moveLabels[column]}</Text>
266
- </Button>
267
- }
268
- />
269
- )
270
- })}
271
- </FeatureFacts>
272
- )}
273
- </FeatureFrame>
274
- )
275
- }
276
-
277
- export function Rotation(input: KowalskiInput<'rotation'>) {
278
- const props = kowalskiCatalog.rotation.props.parse(input)
279
- const people = props.people
280
- const schema = kowalskiCatalog.rotation.storeSchema
281
- const store = useConfiguredFeature({
282
- name: props.id ?? 'KowalskiRotation',
283
- revision: props.revision,
284
- schema,
285
- scope: props.scope,
286
- seed: schema.parse({}),
287
- })
288
- // A saved turn for someone no longer in the group falls back to the first person.
289
- const position = (turn: string | null) =>
290
- Math.max(
291
- 0,
292
- people.findIndex(person => person.id === turn)
293
- )
294
- const current = people[position(store.value.turn)]
295
- const pass = (completed: boolean) =>
296
- store.set(state => ({
297
- completed: state.completed + (completed ? 1 : 0),
298
- turn: people[(position(state.turn) + 1) % people.length].id,
299
- }))
300
- return (
301
- <FeatureFrame
302
- onRetry={store.retry}
303
- notice={store.error}
304
- component="rotation"
305
- title={props.title}
306
- detail={props.task}
307
- >
308
- <Field
309
- label={
310
- store.value.completed > 0
311
- ? `Order · ${format.formatNumber(store.value.completed)} done so far`
312
- : 'Order'
313
- }
314
- >
315
- <FeatureFacts>
316
- {people.map(person => (
317
- <List.Item
318
- key={person.id}
319
- label={person.label}
320
- trailing={
321
- person.id === current.id ? (
322
- <Text {...stylex.props(roles.muted, appearance.accent)}>Now</Text>
323
- ) : undefined
324
- }
325
- />
326
- ))}
327
- </FeatureFacts>
328
- </Field>
329
- <FeatureWell style={everydayStyles.centered}>
330
- <Text {...stylex.props(roles.label, layout.fieldLabel)}>Up now</Text>
331
- <Text {...stylex.props(roles.h1)}>{current.label}</Text>
332
- </FeatureWell>
333
- <Flex {...stylex.props(layout.actions)}>
334
- <FeatureAction
335
- component="rotation"
336
- disabled={!store.ready}
337
- size="lg"
338
- onClick={() => pass(false)}
339
- >
340
- Skip
341
- </FeatureAction>
342
- <FeatureAction
343
- component="rotation"
344
- disabled={!store.ready}
345
- icon="checkmark"
346
- size="lg"
347
- variant="primary"
348
- onClick={() => pass(true)}
349
- >
350
- Done
351
- </FeatureAction>
352
- </Flex>
353
- </FeatureFrame>
354
- )
355
- }
356
-
357
- export function ShoppingList(input: KowalskiInput<'shoppingList'>) {
358
- const props = kowalskiCatalog.shoppingList.props.parse(input)
359
- const items = props.items
360
- const schema = kowalskiCatalog.shoppingList.storeSchema
361
- const store = useConfiguredFeature({
362
- name: props.id ?? 'KowalskiShoppingList',
363
- revision: props.revision,
364
- schema,
365
- scope: props.scope,
366
- seed: schema.parse({}),
367
- })
368
- const money = (value: number) => formatCurrency(value, props.currency)
369
- const got = (id: string) => Boolean(store.value[`got_${id}`])
370
- const priced = items.filter(item => item.price !== undefined)
371
- const cost = (item: (typeof items)[number]) => (item.price ?? 0) * item.quantity
372
- const total = priced.reduce((sum, item) => sum + cost(item), 0)
373
- const cart = priced
374
- .filter(item => got(item.id))
375
- .reduce((sum, item) => sum + cost(item), 0)
376
- const count = items.filter(item => got(item.id)).length
377
- return (
378
- <FeatureFrame
379
- onRetry={store.retry}
380
- notice={store.error}
381
- component="shoppingList"
382
- title={props.title}
383
- trailing={
384
- <Text {...stylex.props(roles.muted)}>
385
- {`${format.formatNumber(count)} of ${format.formatNumber(items.length)}`}
386
- </Text>
387
- }
388
- >
389
- {priced.length > 0 && (
390
- <FeatureWell>
391
- <Stat>
392
- <Stat.Value>{money(cart)}</Stat.Value>
393
- <Stat.Caption>{`In the cart of ${money(total)}`}</Stat.Caption>
394
- </Stat>
395
- </FeatureWell>
396
- )}
397
- <List style={completedTaskStyle}>
398
- {items.map(item => (
399
- <Choice
400
- checked={got(item.id)}
401
- description={
402
- item.price === undefined
403
- ? item.quantity > 1
404
- ? `× ${format.formatNumber(item.quantity)}`
405
- : undefined
406
- : item.quantity > 1
407
- ? `${format.formatNumber(item.quantity)} × ${money(item.price)}`
408
- : money(item.price)
409
- }
410
- disabled={!store.ready}
411
- key={item.id}
412
- onCheckedChange={checked =>
413
- store.set(() => ({ [`got_${item.id}`]: checked }))
414
- }
415
- >
416
- {item.label}
417
- </Choice>
418
- ))}
419
- </List>
420
- {count > 0 && (
421
- <FeatureAction
422
- component="shoppingList"
423
- disabled={!store.ready}
424
- onClick={() =>
425
- store.set(() =>
426
- Object.fromEntries(items.map(item => [`got_${item.id}`, false]))
427
- )
428
- }
429
- >
430
- Start a new trip
431
- </FeatureAction>
432
- )}
433
- </FeatureFrame>
434
- )
435
- }
436
-
437
- export function Rating(input: KowalskiInput<'rating'>) {
438
- const props = kowalskiCatalog.rating.props.parse(input)
439
- const schema = kowalskiCatalog.rating.storeSchema
440
- const store = useConfiguredFeature({
441
- name: props.id ?? 'KowalskiRating',
442
- revision: props.revision,
443
- schema,
444
- scope: props.scope,
445
- seed: schema.parse({}),
446
- })
447
- const stars = store.value.stars
448
- return (
449
- <FeatureFrame
450
- onRetry={store.retry}
451
- notice={store.error}
452
- component="rating"
453
- title={props.title}
454
- detail={props.subject}
455
- >
456
- <FeatureField
457
- component="rating"
458
- label="Note"
459
- multiline
460
- ready={store.ready}
461
- saving={store.saving}
462
- validate={value => value.length <= 2000}
463
- value={store.value.note.value}
464
- onChange={(note, onSaved) =>
465
- store.set(() => ({ note: { value: note } }), onSaved)
466
- }
467
- />
468
- <FeatureWell style={everydayStyles.centered}>
469
- <Flex {...stylex.props(everydayStyles.stars)}>
470
- {[1, 2, 3, 4, 5].map(value => (
471
- <Button
472
- accessibilityLabel={`${value} ${value === 1 ? 'star' : 'stars'}`}
473
- disabled={!store.ready}
474
- key={value}
475
- onClick={() => {
476
- store.set(() => ({ stars: stars === value ? 0 : value }))
477
- }}
478
- selected={value === stars}
479
- style={[button.quiet, everydayStyles.star]}
480
- >
481
- <Icon
482
- name="star"
483
- {...stylex.props(
484
- roles.h1,
485
- value <= stars ? appearance.accent : everydayStyles.emptyStar
486
- )}
487
- />
488
- </Button>
489
- ))}
490
- </Flex>
491
- <Text {...stylex.props(roles.muted)}>{ratingLabels[stars]}</Text>
492
- </FeatureWell>
493
- </FeatureFrame>
494
- )
495
- }
496
-
497
- export function Ledger(input: KowalskiInput<'ledger'>) {
498
- const props = kowalskiCatalog.ledger.props.parse(input)
499
- const schema = kowalskiCatalog.ledger.storeSchema
500
- const store = useConfiguredFeature({
501
- name: props.id ?? 'KowalskiLedger',
502
- revision: props.revision,
503
- schema,
504
- scope: props.scope,
505
- seed: schema.parse({}),
506
- })
507
- const [first, second] = props.people
508
- const [label, setLabel] = useState({ value: '' })
509
- const [amount, setAmount] = useState({ value: '' })
510
- const [paidBy, setPaidBy] = useState(first.id)
511
- const money = (value: number) => formatCurrency(value, props.currency)
512
- const nameOf = (id: string) => (id === first.id ? first.label : second.label)
513
- const parsed = parseNumberInput(amount.value, props.currency)
514
- const validLabel = schema.shape.entries
515
- .unwrap()
516
- .element.shape.label.safeParse(label.value.trim()).success
517
- const valid = validLabel && Number.isFinite(parsed) && parsed > 0 && parsed <= 1e12
518
- // Every cost is shared evenly, so whoever paid is owed half of it.
519
- const balance = store.value.entries.reduce(
520
- (sum, entry) => sum + (entry.paidBy === first.id ? entry.amount : -entry.amount) / 2,
521
- 0
522
- )
523
- const settled = Math.abs(balance) < 0.005
524
- return (
525
- <FeatureFrame
526
- onRetry={store.retry}
527
- notice={store.error}
528
- component="ledger"
529
- title={props.title}
530
- detail={`${first.label} and ${second.label} · costs split evenly`}
531
- >
532
- <FeatureWell style={everydayStyles.centered}>
533
- <Text {...stylex.props(roles.h1)}>
534
- {settled ? 'All square' : money(Math.abs(balance))}
535
- </Text>
536
- {!settled && (
537
- <Text {...stylex.props(roles.muted)}>
538
- {balance > 0
539
- ? `${second.label} owes ${first.label}`
540
- : `${first.label} owes ${second.label}`}
541
- </Text>
542
- )}
543
- </FeatureWell>
544
- {store.value.entries.length > 0 && (
545
- <>
546
- <FeatureAction
547
- component="ledger"
548
- disabled={!store.ready}
549
- onClick={() => store.set(() => ({ entries: [] }))}
550
- >
551
- Settle up
552
- </FeatureAction>
553
- <FeatureFacts>
554
- {store.value.entries.slice(0, 20).map(entry => (
555
- <List.Item
556
- description={`Paid by ${nameOf(entry.paidBy)}`}
557
- key={entry.id}
558
- label={entry.label || 'Shared cost'}
559
- trailing={money(entry.amount)}
560
- />
561
- ))}
562
- </FeatureFacts>
563
- </>
564
- )}
565
- <Field
566
- error={!validLabel && 'Keep the description within 160 characters.'}
567
- label="What for"
568
- >
569
- <Input
570
- placeholder="What for"
571
- value={label.value}
572
- onChange={value => setLabel({ value })}
573
- style={[layout.input]}
574
- />
575
- </Field>
576
- <Field
577
- error={amount.value && !valid && 'Enter an amount within the supported range.'}
578
- label="Amount"
579
- >
580
- <Input
581
- placeholder="Amount"
582
- value={amount.value}
583
- onChange={value => setAmount({ value })}
584
- style={[layout.input]}
585
- />
586
- </Field>
587
- <Field label="Paid by">
588
- <Segmented
589
- options={props.people.map(person => ({
590
- label: person.label,
591
- value: person.id,
592
- }))}
593
- value={paidBy}
594
- onChange={setPaidBy}
595
- />
596
- </Field>
597
- <FeatureAction
598
- component="ledger"
599
- disabled={
600
- !valid || !store.ready || store.saving || store.value.entries.length >= 200
601
- }
602
- icon="plus"
603
- size="lg"
604
- variant="primary"
605
- onClick={() =>
606
- store.set(
607
- current => ({
608
- entries: [
609
- {
610
- amount: parsed,
611
- id: `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`,
612
- label: label.value.trim(),
613
- paidBy,
614
- },
615
- ...current.entries,
616
- ],
617
- }),
618
- () => {
619
- setAmount(current => (current === amount ? { value: '' } : current))
620
- setLabel(current => (current === label ? { value: '' } : current))
621
- }
622
- )
623
- }
624
- >
625
- Add to the tab
626
- </FeatureAction>
627
- </FeatureFrame>
628
- )
629
- }
630
-
631
- type TaskStatus = 'doing' | 'done' | 'todo'
632
-
633
- const moveLabels: Record<TaskStatus, string> = {
634
- doing: 'Finish',
635
- done: 'Reopen',
636
- todo: 'Start',
637
- }
638
- const ratingLabels = ['Tap a star to rate', 'Poor', 'Fair', 'Good', 'Great', 'Excellent']
639
- const taskColumns: { label: string; value: TaskStatus }[] = [
640
- { label: 'To do', value: 'todo' },
641
- { label: 'Doing', value: 'doing' },
642
- { label: 'Done', value: 'done' },
643
- ]
644
-
645
- const everydayStyles = stylex.create({
6
+ export const everydayStyles = /* @__PURE__ */ stylex.create({
646
7
  centered: { alignItems: 'center', textAlign: 'center' },
647
8
  empty: { alignItems: 'center', padding: space[6] },
648
9
  emptyStar: { color: colors.border },