create-smoodly-app 0.0.44 → 0.0.46

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 (387) hide show
  1. package/README.md +15 -10
  2. package/dist/index.js +75 -33
  3. package/package.json +2 -2
  4. package/templates/astro-blank/AGENTS.md +55 -0
  5. package/templates/astro-blank/CLAUDE.md +1 -0
  6. package/templates/astro-blank/README.md +88 -0
  7. package/templates/astro-blank/_gitignore +5 -0
  8. package/templates/astro-blank/astro.config.ts +15 -0
  9. package/templates/astro-blank/package.json +24 -0
  10. package/templates/astro-blank/scripts/seed.ts +80 -0
  11. package/templates/astro-blank/src/components/LocaleNav.astro +15 -0
  12. package/templates/astro-blank/src/components/elements/Button.schema.ts +22 -0
  13. package/templates/astro-blank/src/components/pages/Home.schema.ts +17 -0
  14. package/templates/astro-blank/src/components/pages/Page.schema.ts +14 -0
  15. package/templates/astro-blank/src/components/sections/Text.schema.ts +24 -0
  16. package/templates/astro-blank/src/elements/button.astro +10 -0
  17. package/templates/astro-blank/src/entry-pages/posts.astro +23 -0
  18. package/templates/astro-blank/src/layouts/Layout.astro +25 -0
  19. package/templates/astro-blank/src/live.config.ts +13 -0
  20. package/templates/astro-blank/src/page-types/home.astro +15 -0
  21. package/templates/astro-blank/src/page-types/page.astro +15 -0
  22. package/templates/astro-blank/src/pages/404.astro +7 -0
  23. package/templates/astro-blank/src/sections/text.astro +18 -0
  24. package/templates/astro-blank/src/smoodly/collections.ts +24 -0
  25. package/templates/astro-blank/src/smoodly/config.ts +28 -0
  26. package/templates/astro-blank/src/smoodly/elements.ts +5 -0
  27. package/templates/astro-blank/src/smoodly/globals.ts +18 -0
  28. package/templates/astro-blank/src/smoodly/sections.ts +5 -0
  29. package/templates/astro-blank/src/smoodly/toolsets.ts +14 -0
  30. package/templates/astro-blank/src/styles/global.css +57 -0
  31. package/templates/astro-blank/supabase/migrations/20260926120000_smoodly_v1.sql +535 -0
  32. package/templates/astro-blank/supabase/migrations/20260926130000_smoodly_v2.sql +26 -0
  33. package/templates/astro-blank/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
  34. package/templates/astro-blank/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
  35. package/templates/astro-blank/supabase/migrations/20260929120000_smoodly_v5.sql +56 -0
  36. package/templates/astro-blank/supabase/migrations/20260929135523_smoodly_v6.sql +200 -0
  37. package/templates/astro-blank/supabase/migrations/20260930040956_smoodly_v7.sql +84 -0
  38. package/templates/astro-blank/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  39. package/templates/astro-blank/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  40. package/templates/{blank/supabase/migrations/20260930041056_smoodly_views.sql → astro-blank/supabase/migrations/20261007200100_smoodly_views.sql} +1 -1
  41. package/templates/astro-blank/tsconfig.json +17 -0
  42. package/templates/astro-blank-intl/AGENTS.md +55 -0
  43. package/templates/astro-blank-intl/CLAUDE.md +1 -0
  44. package/templates/astro-blank-intl/README.md +89 -0
  45. package/templates/astro-blank-intl/_gitignore +5 -0
  46. package/templates/astro-blank-intl/astro.config.ts +17 -0
  47. package/templates/astro-blank-intl/package.json +24 -0
  48. package/templates/astro-blank-intl/scripts/seed.ts +80 -0
  49. package/templates/astro-blank-intl/src/components/LocaleNav.astro +15 -0
  50. package/templates/astro-blank-intl/src/components/elements/Button.schema.ts +22 -0
  51. package/templates/astro-blank-intl/src/components/pages/Home.schema.ts +17 -0
  52. package/templates/astro-blank-intl/src/components/pages/Page.schema.ts +14 -0
  53. package/templates/astro-blank-intl/src/components/sections/Text.schema.ts +24 -0
  54. package/templates/astro-blank-intl/src/elements/button.astro +10 -0
  55. package/templates/astro-blank-intl/src/entry-pages/posts.astro +23 -0
  56. package/templates/astro-blank-intl/src/layouts/Layout.astro +25 -0
  57. package/templates/astro-blank-intl/src/live.config.ts +13 -0
  58. package/templates/astro-blank-intl/src/page-types/home.astro +15 -0
  59. package/templates/astro-blank-intl/src/page-types/page.astro +15 -0
  60. package/templates/astro-blank-intl/src/pages/404.astro +7 -0
  61. package/templates/astro-blank-intl/src/sections/text.astro +18 -0
  62. package/templates/astro-blank-intl/src/smoodly/collections.ts +24 -0
  63. package/templates/astro-blank-intl/src/smoodly/config.ts +29 -0
  64. package/templates/astro-blank-intl/src/smoodly/elements.ts +5 -0
  65. package/templates/astro-blank-intl/src/smoodly/globals.ts +18 -0
  66. package/templates/astro-blank-intl/src/smoodly/sections.ts +5 -0
  67. package/templates/astro-blank-intl/src/smoodly/toolsets.ts +14 -0
  68. package/templates/astro-blank-intl/src/styles/global.css +57 -0
  69. package/templates/astro-blank-intl/supabase/migrations/20260926120000_smoodly_v1.sql +535 -0
  70. package/templates/astro-blank-intl/supabase/migrations/20260926130000_smoodly_v2.sql +26 -0
  71. package/templates/astro-blank-intl/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
  72. package/templates/astro-blank-intl/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
  73. package/templates/astro-blank-intl/supabase/migrations/20260929120000_smoodly_v5.sql +56 -0
  74. package/templates/astro-blank-intl/supabase/migrations/20260929135523_smoodly_v6.sql +200 -0
  75. package/templates/astro-blank-intl/supabase/migrations/20260930040956_smoodly_v7.sql +84 -0
  76. package/templates/astro-blank-intl/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  77. package/templates/astro-blank-intl/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  78. package/templates/{blank-intl/supabase/migrations/20260930041056_smoodly_views.sql → astro-blank-intl/supabase/migrations/20261007200100_smoodly_views.sql} +1 -1
  79. package/templates/astro-blank-intl/tsconfig.json +17 -0
  80. package/templates/astro-blank-intl.tsconfig.json +24 -0
  81. package/templates/astro-blank.tsconfig.json +24 -0
  82. package/templates/astro-lorem/AGENTS.md +55 -0
  83. package/templates/astro-lorem/CLAUDE.md +1 -0
  84. package/templates/astro-lorem/README.md +60 -0
  85. package/templates/astro-lorem/_gitignore +5 -0
  86. package/templates/astro-lorem/astro.config.ts +15 -0
  87. package/templates/astro-lorem/package.json +24 -0
  88. package/templates/astro-lorem/public/images/about_main.jpg +0 -0
  89. package/templates/astro-lorem/public/images/article_photo.jpg +0 -0
  90. package/templates/astro-lorem/public/images/hero_image.jpg +0 -0
  91. package/templates/astro-lorem/public/images/home_section_2.jpg +0 -0
  92. package/templates/astro-lorem/scripts/seed.ts +405 -0
  93. package/templates/astro-lorem/src/components/ArticleCard.astro +19 -0
  94. package/templates/astro-lorem/src/components/articles.ts +42 -0
  95. package/templates/astro-lorem/src/components/elements/Callout.schema.ts +24 -0
  96. package/templates/astro-lorem/src/components/elements/Cta.schema.ts +21 -0
  97. package/templates/astro-lorem/src/components/news.ts +13 -0
  98. package/templates/astro-lorem/src/components/pages/Articles.schema.ts +20 -0
  99. package/templates/astro-lorem/src/components/pages/Home.schema.ts +26 -0
  100. package/templates/astro-lorem/src/components/pages/News.schema.ts +17 -0
  101. package/templates/astro-lorem/src/components/pages/Page.schema.ts +24 -0
  102. package/templates/astro-lorem/src/components/sections/FavouriteArticles.schema.ts +17 -0
  103. package/templates/astro-lorem/src/components/sections/Footer.schema.ts +31 -0
  104. package/templates/astro-lorem/src/components/sections/Header.schema.ts +21 -0
  105. package/templates/astro-lorem/src/components/sections/Hero.schema.ts +24 -0
  106. package/templates/astro-lorem/src/components/sections/ImageText.schema.ts +30 -0
  107. package/templates/astro-lorem/src/components/sections/PageHero.schema.ts +21 -0
  108. package/templates/astro-lorem/src/components/sections/People.schema.ts +15 -0
  109. package/templates/astro-lorem/src/components/sections/Points.schema.ts +21 -0
  110. package/templates/astro-lorem/src/components/sections/Quote.schema.ts +23 -0
  111. package/templates/astro-lorem/src/elements/callout.astro +13 -0
  112. package/templates/astro-lorem/src/elements/cta.astro +15 -0
  113. package/templates/astro-lorem/src/entry-pages/articles.astro +71 -0
  114. package/templates/astro-lorem/src/entry-pages/news.astro +29 -0
  115. package/templates/astro-lorem/src/layouts/Layout.astro +39 -0
  116. package/templates/astro-lorem/src/live.config.ts +20 -0
  117. package/templates/astro-lorem/src/messages/en.json +7 -0
  118. package/templates/astro-lorem/src/messages/fi.json +7 -0
  119. package/templates/astro-lorem/src/page-types/articlesIndex.astro +24 -0
  120. package/templates/astro-lorem/src/page-types/home.astro +14 -0
  121. package/templates/astro-lorem/src/page-types/newsIndex.astro +28 -0
  122. package/templates/astro-lorem/src/page-types/page.astro +27 -0
  123. package/templates/astro-lorem/src/pages/404.astro +7 -0
  124. package/templates/astro-lorem/src/sections/favouriteArticles.astro +26 -0
  125. package/templates/astro-lorem/src/sections/footer.astro +37 -0
  126. package/templates/astro-lorem/src/sections/header.astro +27 -0
  127. package/templates/astro-lorem/src/sections/hero.astro +28 -0
  128. package/templates/astro-lorem/src/sections/imageText.astro +22 -0
  129. package/templates/astro-lorem/src/sections/pageHero.astro +20 -0
  130. package/templates/astro-lorem/src/sections/peopleSection.astro +24 -0
  131. package/templates/astro-lorem/src/sections/points.astro +33 -0
  132. package/templates/astro-lorem/src/sections/quote.astro +16 -0
  133. package/templates/astro-lorem/src/smoodly/collections.ts +63 -0
  134. package/templates/astro-lorem/src/smoodly/config.ts +48 -0
  135. package/templates/astro-lorem/src/smoodly/elements.ts +6 -0
  136. package/templates/astro-lorem/src/smoodly/globals.ts +29 -0
  137. package/templates/astro-lorem/src/smoodly/sections.ts +18 -0
  138. package/templates/astro-lorem/src/smoodly/toolsets.ts +16 -0
  139. package/templates/astro-lorem/src/strings.ts +17 -0
  140. package/templates/astro-lorem/src/styles/global.css +228 -0
  141. package/templates/astro-lorem/supabase/migrations/20260926120000_smoodly_v1.sql +535 -0
  142. package/templates/astro-lorem/supabase/migrations/20260926130000_smoodly_v2.sql +26 -0
  143. package/templates/astro-lorem/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
  144. package/templates/astro-lorem/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
  145. package/templates/astro-lorem/supabase/migrations/20260929120000_smoodly_v5.sql +56 -0
  146. package/templates/astro-lorem/supabase/migrations/20260929135523_smoodly_v6.sql +200 -0
  147. package/templates/astro-lorem/supabase/migrations/20260930040956_smoodly_v7.sql +84 -0
  148. package/templates/astro-lorem/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  149. package/templates/astro-lorem/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  150. package/templates/{lorem/supabase/migrations/20260930041056_smoodly_views.sql → astro-lorem/supabase/migrations/20261007200100_smoodly_views.sql} +1 -1
  151. package/templates/astro-lorem/tsconfig.json +17 -0
  152. package/templates/astro-lorem-intl/AGENTS.md +55 -0
  153. package/templates/astro-lorem-intl/CLAUDE.md +1 -0
  154. package/templates/astro-lorem-intl/README.md +62 -0
  155. package/templates/astro-lorem-intl/_gitignore +5 -0
  156. package/templates/astro-lorem-intl/astro.config.ts +17 -0
  157. package/templates/astro-lorem-intl/package.json +24 -0
  158. package/templates/astro-lorem-intl/public/images/about_main.jpg +0 -0
  159. package/templates/astro-lorem-intl/public/images/article_photo.jpg +0 -0
  160. package/templates/astro-lorem-intl/public/images/hero_image.jpg +0 -0
  161. package/templates/astro-lorem-intl/public/images/home_section_2.jpg +0 -0
  162. package/templates/astro-lorem-intl/scripts/seed.ts +405 -0
  163. package/templates/astro-lorem-intl/src/components/ArticleCard.astro +19 -0
  164. package/templates/astro-lorem-intl/src/components/articles.ts +42 -0
  165. package/templates/astro-lorem-intl/src/components/elements/Callout.schema.ts +24 -0
  166. package/templates/astro-lorem-intl/src/components/elements/Cta.schema.ts +21 -0
  167. package/templates/astro-lorem-intl/src/components/news.ts +13 -0
  168. package/templates/astro-lorem-intl/src/components/pages/Articles.schema.ts +20 -0
  169. package/templates/astro-lorem-intl/src/components/pages/Home.schema.ts +26 -0
  170. package/templates/astro-lorem-intl/src/components/pages/News.schema.ts +17 -0
  171. package/templates/astro-lorem-intl/src/components/pages/Page.schema.ts +24 -0
  172. package/templates/astro-lorem-intl/src/components/sections/FavouriteArticles.schema.ts +17 -0
  173. package/templates/astro-lorem-intl/src/components/sections/Footer.schema.ts +31 -0
  174. package/templates/astro-lorem-intl/src/components/sections/Header.schema.ts +21 -0
  175. package/templates/astro-lorem-intl/src/components/sections/Hero.schema.ts +24 -0
  176. package/templates/astro-lorem-intl/src/components/sections/ImageText.schema.ts +30 -0
  177. package/templates/astro-lorem-intl/src/components/sections/PageHero.schema.ts +21 -0
  178. package/templates/astro-lorem-intl/src/components/sections/People.schema.ts +15 -0
  179. package/templates/astro-lorem-intl/src/components/sections/Points.schema.ts +21 -0
  180. package/templates/astro-lorem-intl/src/components/sections/Quote.schema.ts +23 -0
  181. package/templates/astro-lorem-intl/src/elements/callout.astro +13 -0
  182. package/templates/astro-lorem-intl/src/elements/cta.astro +15 -0
  183. package/templates/astro-lorem-intl/src/entry-pages/articles.astro +71 -0
  184. package/templates/astro-lorem-intl/src/entry-pages/news.astro +29 -0
  185. package/templates/astro-lorem-intl/src/layouts/Layout.astro +39 -0
  186. package/templates/astro-lorem-intl/src/live.config.ts +20 -0
  187. package/templates/astro-lorem-intl/src/messages/en.json +7 -0
  188. package/templates/astro-lorem-intl/src/messages/fi.json +7 -0
  189. package/templates/astro-lorem-intl/src/page-types/articlesIndex.astro +24 -0
  190. package/templates/astro-lorem-intl/src/page-types/home.astro +14 -0
  191. package/templates/astro-lorem-intl/src/page-types/newsIndex.astro +28 -0
  192. package/templates/astro-lorem-intl/src/page-types/page.astro +27 -0
  193. package/templates/astro-lorem-intl/src/pages/404.astro +7 -0
  194. package/templates/astro-lorem-intl/src/sections/favouriteArticles.astro +26 -0
  195. package/templates/astro-lorem-intl/src/sections/footer.astro +37 -0
  196. package/templates/astro-lorem-intl/src/sections/header.astro +27 -0
  197. package/templates/astro-lorem-intl/src/sections/hero.astro +28 -0
  198. package/templates/astro-lorem-intl/src/sections/imageText.astro +22 -0
  199. package/templates/astro-lorem-intl/src/sections/pageHero.astro +20 -0
  200. package/templates/astro-lorem-intl/src/sections/peopleSection.astro +24 -0
  201. package/templates/astro-lorem-intl/src/sections/points.astro +33 -0
  202. package/templates/astro-lorem-intl/src/sections/quote.astro +16 -0
  203. package/templates/astro-lorem-intl/src/smoodly/collections.ts +63 -0
  204. package/templates/astro-lorem-intl/src/smoodly/config.ts +48 -0
  205. package/templates/astro-lorem-intl/src/smoodly/elements.ts +6 -0
  206. package/templates/astro-lorem-intl/src/smoodly/globals.ts +29 -0
  207. package/templates/astro-lorem-intl/src/smoodly/sections.ts +18 -0
  208. package/templates/astro-lorem-intl/src/smoodly/toolsets.ts +16 -0
  209. package/templates/astro-lorem-intl/src/strings.ts +17 -0
  210. package/templates/astro-lorem-intl/src/styles/global.css +228 -0
  211. package/templates/astro-lorem-intl/supabase/migrations/20260926120000_smoodly_v1.sql +535 -0
  212. package/templates/astro-lorem-intl/supabase/migrations/20260926130000_smoodly_v2.sql +26 -0
  213. package/templates/astro-lorem-intl/supabase/migrations/20260926140000_smoodly_v3.sql +38 -0
  214. package/templates/astro-lorem-intl/supabase/migrations/20260926150000_smoodly_v4.sql +41 -0
  215. package/templates/astro-lorem-intl/supabase/migrations/20260929120000_smoodly_v5.sql +56 -0
  216. package/templates/astro-lorem-intl/supabase/migrations/20260929135523_smoodly_v6.sql +200 -0
  217. package/templates/astro-lorem-intl/supabase/migrations/20260930040956_smoodly_v7.sql +84 -0
  218. package/templates/astro-lorem-intl/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  219. package/templates/astro-lorem-intl/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  220. package/templates/{lorem-intl/supabase/migrations/20260930041056_smoodly_views.sql → astro-lorem-intl/supabase/migrations/20261007200100_smoodly_views.sql} +1 -1
  221. package/templates/astro-lorem-intl/tsconfig.json +17 -0
  222. package/templates/astro-lorem-intl.tsconfig.json +24 -0
  223. package/templates/astro-lorem.tsconfig.json +24 -0
  224. package/templates/blank/AGENTS.md +23 -16
  225. package/templates/blank/README.md +20 -15
  226. package/templates/blank/app/(smoodly)/admin/[[...segments]]/route.ts +8 -0
  227. package/templates/blank/components/elements/Button.schema.ts +22 -0
  228. package/templates/blank/components/elements/Button.tsx +2 -20
  229. package/templates/blank/components/pages/Home.schema.ts +17 -0
  230. package/templates/blank/components/pages/Home.tsx +2 -16
  231. package/templates/blank/components/pages/Page.schema.ts +14 -0
  232. package/templates/blank/components/pages/Page.tsx +2 -14
  233. package/templates/blank/components/pages/Post.tsx +5 -4
  234. package/templates/blank/components/sections/Text.schema.ts +24 -0
  235. package/templates/blank/components/sections/Text.tsx +7 -27
  236. package/templates/blank/package.json +1 -1
  237. package/templates/blank/scripts/seed.ts +2 -2
  238. package/templates/blank/smoodly/config.ts +8 -7
  239. package/templates/blank/smoodly/elements.ts +4 -4
  240. package/templates/blank/smoodly/globals.ts +4 -2
  241. package/templates/blank/smoodly/richtext.tsx +4 -5
  242. package/templates/blank/smoodly/sections.ts +4 -4
  243. package/templates/blank/smoodly/server.ts +22 -44
  244. package/templates/blank/smoodly/toolsets.ts +2 -2
  245. package/templates/blank/smoodly/views.ts +15 -0
  246. package/templates/blank/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  247. package/templates/blank/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  248. package/templates/blank/supabase/migrations/20261007200100_smoodly_views.sql +20 -0
  249. package/templates/blank-intl/AGENTS.md +23 -16
  250. package/templates/blank-intl/README.md +20 -15
  251. package/templates/blank-intl/app/(smoodly)/admin/[[...segments]]/route.ts +8 -0
  252. package/templates/blank-intl/components/elements/Button.schema.ts +22 -0
  253. package/templates/blank-intl/components/elements/Button.tsx +2 -20
  254. package/templates/blank-intl/components/pages/Home.schema.ts +17 -0
  255. package/templates/blank-intl/components/pages/Home.tsx +2 -16
  256. package/templates/blank-intl/components/pages/Page.schema.ts +14 -0
  257. package/templates/blank-intl/components/pages/Page.tsx +2 -14
  258. package/templates/blank-intl/components/pages/Post.tsx +5 -4
  259. package/templates/blank-intl/components/sections/Text.schema.ts +24 -0
  260. package/templates/blank-intl/components/sections/Text.tsx +7 -27
  261. package/templates/blank-intl/package.json +1 -1
  262. package/templates/blank-intl/scripts/seed.ts +2 -2
  263. package/templates/blank-intl/smoodly/config.ts +8 -7
  264. package/templates/blank-intl/smoodly/elements.ts +4 -4
  265. package/templates/blank-intl/smoodly/globals.ts +4 -2
  266. package/templates/blank-intl/smoodly/richtext.tsx +4 -5
  267. package/templates/blank-intl/smoodly/sections.ts +4 -4
  268. package/templates/blank-intl/smoodly/server.ts +22 -44
  269. package/templates/blank-intl/smoodly/toolsets.ts +2 -2
  270. package/templates/blank-intl/smoodly/views.ts +15 -0
  271. package/templates/blank-intl/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  272. package/templates/blank-intl/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  273. package/templates/blank-intl/supabase/migrations/20261007200100_smoodly_views.sql +20 -0
  274. package/templates/lorem/AGENTS.md +23 -16
  275. package/templates/lorem/README.md +3 -3
  276. package/templates/lorem/app/(smoodly)/admin/[[...segments]]/route.ts +8 -0
  277. package/templates/lorem/components/elements/Callout.schema.ts +24 -0
  278. package/templates/lorem/components/elements/Callout.tsx +2 -24
  279. package/templates/lorem/components/elements/Cta.schema.ts +21 -0
  280. package/templates/lorem/components/elements/Cta.tsx +2 -21
  281. package/templates/lorem/components/pages/Article.tsx +1 -1
  282. package/templates/lorem/components/pages/Articles.schema.ts +20 -0
  283. package/templates/lorem/components/pages/Articles.tsx +2 -20
  284. package/templates/lorem/components/pages/Home.schema.ts +26 -0
  285. package/templates/lorem/components/pages/Home.tsx +2 -26
  286. package/templates/lorem/components/pages/News.schema.ts +17 -0
  287. package/templates/lorem/components/pages/News.tsx +2 -17
  288. package/templates/lorem/components/pages/NewsPost.tsx +1 -1
  289. package/templates/lorem/components/pages/Page.schema.ts +24 -0
  290. package/templates/lorem/components/pages/Page.tsx +2 -24
  291. package/templates/lorem/components/sections/FavouriteArticles.schema.ts +17 -0
  292. package/templates/lorem/components/sections/FavouriteArticles.tsx +2 -17
  293. package/templates/lorem/components/sections/Footer.schema.ts +31 -0
  294. package/templates/lorem/components/sections/Footer.tsx +4 -32
  295. package/templates/lorem/components/sections/Header.schema.ts +21 -0
  296. package/templates/lorem/components/sections/Header.tsx +2 -21
  297. package/templates/lorem/components/sections/Hero.schema.ts +24 -0
  298. package/templates/lorem/components/sections/Hero.tsx +2 -24
  299. package/templates/lorem/components/sections/ImageText.schema.ts +30 -0
  300. package/templates/lorem/components/sections/ImageText.tsx +2 -30
  301. package/templates/lorem/components/sections/PageHero.schema.ts +21 -0
  302. package/templates/lorem/components/sections/PageHero.tsx +2 -21
  303. package/templates/lorem/components/sections/People.schema.ts +15 -0
  304. package/templates/lorem/components/sections/People.tsx +2 -14
  305. package/templates/lorem/components/sections/Points.schema.ts +21 -0
  306. package/templates/lorem/components/sections/Points.tsx +2 -21
  307. package/templates/lorem/components/sections/Quote.schema.ts +23 -0
  308. package/templates/lorem/components/sections/Quote.tsx +2 -23
  309. package/templates/lorem/package.json +1 -1
  310. package/templates/lorem/scripts/seed.ts +18 -18
  311. package/templates/lorem/smoodly/collections.ts +2 -2
  312. package/templates/lorem/smoodly/config.ts +14 -15
  313. package/templates/lorem/smoodly/elements.ts +5 -5
  314. package/templates/lorem/smoodly/globals.ts +10 -7
  315. package/templates/lorem/smoodly/richtext.tsx +5 -5
  316. package/templates/lorem/smoodly/sections.ts +12 -13
  317. package/templates/lorem/smoodly/server.ts +22 -44
  318. package/templates/lorem/smoodly/toolsets.ts +3 -3
  319. package/templates/lorem/smoodly/views.ts +33 -0
  320. package/templates/lorem/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  321. package/templates/lorem/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  322. package/templates/lorem/supabase/migrations/20261007200100_smoodly_views.sql +58 -0
  323. package/templates/lorem-intl/AGENTS.md +23 -16
  324. package/templates/lorem-intl/README.md +3 -3
  325. package/templates/lorem-intl/app/(smoodly)/admin/[[...segments]]/route.ts +8 -0
  326. package/templates/lorem-intl/components/elements/Callout.schema.ts +24 -0
  327. package/templates/lorem-intl/components/elements/Callout.tsx +2 -24
  328. package/templates/lorem-intl/components/elements/Cta.schema.ts +21 -0
  329. package/templates/lorem-intl/components/elements/Cta.tsx +2 -21
  330. package/templates/lorem-intl/components/pages/Article.tsx +1 -1
  331. package/templates/lorem-intl/components/pages/Articles.schema.ts +20 -0
  332. package/templates/lorem-intl/components/pages/Articles.tsx +2 -20
  333. package/templates/lorem-intl/components/pages/Home.schema.ts +26 -0
  334. package/templates/lorem-intl/components/pages/Home.tsx +2 -26
  335. package/templates/lorem-intl/components/pages/News.schema.ts +17 -0
  336. package/templates/lorem-intl/components/pages/News.tsx +2 -17
  337. package/templates/lorem-intl/components/pages/NewsPost.tsx +1 -1
  338. package/templates/lorem-intl/components/pages/Page.schema.ts +24 -0
  339. package/templates/lorem-intl/components/pages/Page.tsx +2 -24
  340. package/templates/lorem-intl/components/sections/FavouriteArticles.schema.ts +17 -0
  341. package/templates/lorem-intl/components/sections/FavouriteArticles.tsx +2 -17
  342. package/templates/lorem-intl/components/sections/Footer.schema.ts +31 -0
  343. package/templates/lorem-intl/components/sections/Footer.tsx +4 -32
  344. package/templates/lorem-intl/components/sections/Header.schema.ts +21 -0
  345. package/templates/lorem-intl/components/sections/Header.tsx +2 -21
  346. package/templates/lorem-intl/components/sections/Hero.schema.ts +24 -0
  347. package/templates/lorem-intl/components/sections/Hero.tsx +2 -24
  348. package/templates/lorem-intl/components/sections/ImageText.schema.ts +30 -0
  349. package/templates/lorem-intl/components/sections/ImageText.tsx +2 -30
  350. package/templates/lorem-intl/components/sections/PageHero.schema.ts +21 -0
  351. package/templates/lorem-intl/components/sections/PageHero.tsx +2 -21
  352. package/templates/lorem-intl/components/sections/People.schema.ts +15 -0
  353. package/templates/lorem-intl/components/sections/People.tsx +2 -14
  354. package/templates/lorem-intl/components/sections/Points.schema.ts +21 -0
  355. package/templates/lorem-intl/components/sections/Points.tsx +2 -21
  356. package/templates/lorem-intl/components/sections/Quote.schema.ts +23 -0
  357. package/templates/lorem-intl/components/sections/Quote.tsx +2 -23
  358. package/templates/lorem-intl/package.json +1 -1
  359. package/templates/lorem-intl/scripts/seed.ts +18 -18
  360. package/templates/lorem-intl/smoodly/collections.ts +2 -2
  361. package/templates/lorem-intl/smoodly/config.ts +14 -15
  362. package/templates/lorem-intl/smoodly/elements.ts +5 -5
  363. package/templates/lorem-intl/smoodly/globals.ts +10 -7
  364. package/templates/lorem-intl/smoodly/richtext.tsx +5 -5
  365. package/templates/lorem-intl/smoodly/sections.ts +12 -13
  366. package/templates/lorem-intl/smoodly/server.ts +22 -44
  367. package/templates/lorem-intl/smoodly/toolsets.ts +3 -3
  368. package/templates/lorem-intl/smoodly/views.ts +33 -0
  369. package/templates/lorem-intl/supabase/migrations/20261007120000_smoodly_v8.sql +154 -0
  370. package/templates/lorem-intl/supabase/migrations/20261007200000_smoodly_v9.sql +30 -0
  371. package/templates/lorem-intl/supabase/migrations/20261007200100_smoodly_views.sql +58 -0
  372. package/templates/blank/app/(smoodly)/admin/[[...segments]]/page.tsx +0 -1
  373. package/templates/blank/app/(smoodly)/admin/layout.tsx +0 -15
  374. package/templates/blank/smoodly/admin.tsx +0 -6
  375. package/templates/blank/smoodly/ops.ts +0 -11
  376. package/templates/blank-intl/app/(smoodly)/admin/[[...segments]]/page.tsx +0 -1
  377. package/templates/blank-intl/app/(smoodly)/admin/layout.tsx +0 -15
  378. package/templates/blank-intl/smoodly/admin.tsx +0 -6
  379. package/templates/blank-intl/smoodly/ops.ts +0 -11
  380. package/templates/lorem/app/(smoodly)/admin/[[...segments]]/page.tsx +0 -1
  381. package/templates/lorem/app/(smoodly)/admin/layout.tsx +0 -15
  382. package/templates/lorem/smoodly/admin.tsx +0 -6
  383. package/templates/lorem/smoodly/ops.ts +0 -11
  384. package/templates/lorem-intl/app/(smoodly)/admin/[[...segments]]/page.tsx +0 -1
  385. package/templates/lorem-intl/app/(smoodly)/admin/layout.tsx +0 -15
  386. package/templates/lorem-intl/smoodly/admin.tsx +0 -6
  387. package/templates/lorem-intl/smoodly/ops.ts +0 -11
@@ -0,0 +1,20 @@
1
+ import { smoodly, z } from "smoodly";
2
+ import { pageHeroSchema } from "../sections/PageHero.schema";
3
+
4
+ // The Articles index: a fixed page whose slugs are the collection's own
5
+ // segments (smoodly/collections.ts), which makes it the collection's
6
+ // index page — the mount in the Pages list opens this page's editor. The
7
+ // editor owns the hero; the grid below is developer JSX that reads the
8
+ // articles through `q`, newest first (the collection's `order`), cached
9
+ // under the collection's tag. In the editor canvas the site runs in draft
10
+ // mode, so the grid reads the live rows too: an unpublished article shows
11
+ // there as it will (spec 2026-09-11 §2).
12
+ export const articlesSchema = smoodly.schema.page({
13
+ name: "articlesIndex",
14
+ title: "Articles",
15
+ slug: "posts",
16
+ zones: {
17
+ hero: z.locked(pageHeroSchema),
18
+ },
19
+ seo: true,
20
+ });
@@ -1,27 +1,9 @@
1
- import { smoodly, z, Zone, type Props } from "smoodly";
2
- import { PageHero } from "../sections/PageHero";
1
+ import { smoodly, Zone, type Props } from "smoodly/react";
3
2
  import { ArticleCard } from "../ArticleCard";
4
3
  import { PageFrame } from "../PageFrame";
5
4
  import { ui } from "../strings";
6
5
  import { q } from "@/smoodly/server";
7
-
8
- // The Articles index: a fixed page whose slugs are the collection's own
9
- // segments (smoodly/collections.ts), which makes it the collection's
10
- // index page — the mount in the Pages list opens this page's editor. The
11
- // editor owns the hero; the grid below is developer JSX that reads the
12
- // articles through `q`, newest first (the collection's `order`), cached
13
- // under the collection's tag. In the editor canvas the site runs in draft
14
- // mode, so the grid reads the live rows too: an unpublished article shows
15
- // there as it will (spec 2026-09-11 §2).
16
- export const articlesSchema = smoodly.schema.page({
17
- name: "articlesIndex",
18
- title: "Articles",
19
- slug: "posts",
20
- zones: {
21
- hero: z.locked(PageHero),
22
- },
23
- seo: true,
24
- });
6
+ import { articlesSchema } from "./Articles.schema";
25
7
 
26
8
  async function ArticlesView({ zones, page }: Props<typeof articlesSchema>) {
27
9
  const { locale, url } = await ui();
@@ -0,0 +1,26 @@
1
+ import { smoodly, z } from "smoodly";
2
+ import { heroSchema } from "../sections/Hero.schema";
3
+ import { imageTextSchema } from "../sections/ImageText.schema";
4
+ import { pointsSchema } from "../sections/Points.schema";
5
+ import { favouriteArticlesSchema } from "../sections/FavouriteArticles.schema";
6
+ import { peopleSchema } from "../sections/People.schema";
7
+ import { quoteSchema } from "../sections/Quote.schema";
8
+
9
+ // A page type: zones declared here, placed by the page type's view (DESIGN.md §3).
10
+ // `slug` makes it fixed — one record the editor can neither delete nor
11
+ // duplicate — and the config's homePageSlug maps that record to "/".
12
+ // The hero is locked: fields only, never added, moved or removed. The
13
+ // body is freeform over five sections. Quote is among them because the
14
+ // picker offers a global item only where the zone allows its section: an
15
+ // editor may drop a one-off quote, or place the global one from the
16
+ // picker's Global group.
17
+ export const homeSchema = smoodly.schema.page({
18
+ name: "home",
19
+ title: "Home",
20
+ slug: "home",
21
+ zones: {
22
+ hero: z.locked(heroSchema),
23
+ body: z.freeform({ sections: [imageTextSchema, pointsSchema, favouriteArticlesSchema, peopleSchema, quoteSchema], custom: true }),
24
+ },
25
+ seo: true,
26
+ });
@@ -1,30 +1,6 @@
1
- import { smoodly, z, Zone, type Props } from "smoodly";
2
- import { Hero } from "../sections/Hero";
3
- import { ImageText } from "../sections/ImageText";
4
- import { Points } from "../sections/Points";
5
- import { FavouriteArticles } from "../sections/FavouriteArticles";
6
- import { People } from "../sections/People";
7
- import { Quote } from "../sections/Quote";
1
+ import { smoodly, Zone, type Props } from "smoodly/react";
8
2
  import { PageFrame } from "../PageFrame";
9
-
10
- // A page shape: zones declared, <Zone /> placed, one file (DESIGN.md §3).
11
- // `slug` makes it fixed — one record the editor can neither delete nor
12
- // duplicate — and the config's homePageSlug maps that record to "/".
13
- // The hero is locked: fields only, never added, moved or removed. The
14
- // body is freeform over five sections. Quote is among them because the
15
- // picker offers a global item only where the zone allows its section: an
16
- // editor may drop a one-off quote, or place the global one from the
17
- // picker's Global group.
18
- export const homeSchema = smoodly.schema.page({
19
- name: "home",
20
- title: "Home",
21
- slug: "home",
22
- zones: {
23
- hero: z.locked(Hero),
24
- body: z.freeform({ sections: [ImageText, Points, FavouriteArticles, People, Quote], custom: true }),
25
- },
26
- seo: true,
27
- });
3
+ import { homeSchema } from "./Home.schema";
28
4
 
29
5
  function HomeView({ zones, page }: Props<typeof homeSchema>) {
30
6
  return (
@@ -0,0 +1,17 @@
1
+ import { smoodly, z } from "smoodly";
2
+ import { pageHeroSchema } from "../sections/PageHero.schema";
3
+
4
+ // The News index: a fixed page on the news collection's own nested
5
+ // address (smoodly/collections.ts), so it is the collection's index page.
6
+ // Code owns /company/news whole: the Company page above it is an
7
+ // editor's, and renaming it leaves the news where it is. The editor owns
8
+ // the hero; the list below reads the posts through `q`, newest first.
9
+ export const newsSchema = smoodly.schema.page({
10
+ name: "newsIndex",
11
+ title: "News",
12
+ slug: "company/news",
13
+ zones: {
14
+ hero: z.locked(pageHeroSchema),
15
+ },
16
+ seo: true,
17
+ });
@@ -1,24 +1,9 @@
1
- import { smoodly, z, Zone, type Props } from "smoodly";
2
- import { PageHero } from "../sections/PageHero";
1
+ import { smoodly, Zone, type Props } from "smoodly/react";
3
2
  import { PageFrame } from "../PageFrame";
4
3
  import { formatDate } from "../articles";
5
4
  import { ui } from "../strings";
6
5
  import { q } from "@/smoodly/server";
7
-
8
- // The News index: a fixed page on the news collection's own nested
9
- // address (smoodly/collections.ts), so it is the collection's index page.
10
- // Code owns /company/news whole: the Company page above it is an
11
- // editor's, and renaming it leaves the news where it is. The editor owns
12
- // the hero; the list below reads the posts through `q`, newest first.
13
- export const newsSchema = smoodly.schema.page({
14
- name: "newsIndex",
15
- title: "News",
16
- slug: "company/news",
17
- zones: {
18
- hero: z.locked(PageHero),
19
- },
20
- seo: true,
21
- });
6
+ import { newsSchema } from "./News.schema";
22
7
 
23
8
  async function NewsView({ zones, page }: Props<typeof newsSchema>) {
24
9
  const { locale, url } = await ui();
@@ -1,4 +1,4 @@
1
- import { smoodly } from "smoodly";
1
+ import { smoodly } from "smoodly/react";
2
2
  import { RichText } from "@/smoodly/richtext";
3
3
  import { news } from "@/smoodly/collections";
4
4
  import { PageFrame } from "../PageFrame";
@@ -0,0 +1,24 @@
1
+ import { f, smoodly, z } from "smoodly";
2
+ import { pageHeroSchema } from "../sections/PageHero.schema";
3
+ import { imageTextSchema } from "../sections/ImageText.schema";
4
+ import { pointsSchema } from "../sections/Points.schema";
5
+ import { favouriteArticlesSchema } from "../sections/FavouriteArticles.schema";
6
+ import { peopleSchema } from "../sections/People.schema";
7
+ import { quoteSchema } from "../sections/Quote.schema";
8
+
9
+ // Open registration: editors create as many of these as they like, at
10
+ // any depth the config allows. `page` is where this one sits in the tree.
11
+ // Its locked hero is the page hero, not the home one: each shape locks
12
+ // its own.
13
+ export const pageSchema = smoodly.schema.page({
14
+ name: "page",
15
+ title: "Page",
16
+ zones: {
17
+ hero: z.locked(pageHeroSchema),
18
+ body: z.freeform({ sections: [imageTextSchema, pointsSchema, favouriteArticlesSchema, peopleSchema, quoteSchema], custom: true }),
19
+ },
20
+ seo: true,
21
+ // A page field (spec 2026-09-10 page fields §7): the parent's view lists
22
+ // the children that keep this on. Edited on the Settings tab.
23
+ fields: { showInNavigation: f.boolean().default(true) },
24
+ });
@@ -1,29 +1,7 @@
1
1
  import Link from "next/link";
2
- import { f, smoodly, z, Zone, type Props } from "smoodly";
3
- import { PageHero } from "../sections/PageHero";
4
- import { ImageText } from "../sections/ImageText";
5
- import { Points } from "../sections/Points";
6
- import { FavouriteArticles } from "../sections/FavouriteArticles";
7
- import { People } from "../sections/People";
8
- import { Quote } from "../sections/Quote";
2
+ import { smoodly, Zone, type Props } from "smoodly/react";
9
3
  import { PageFrame } from "../PageFrame";
10
-
11
- // Open registration: editors create as many of these as they like, at
12
- // any depth the config allows. `page` is where this one sits in the tree.
13
- // Its locked hero is the page hero, not the home one: each shape locks
14
- // its own.
15
- export const pageSchema = smoodly.schema.page({
16
- name: "page",
17
- title: "Page",
18
- zones: {
19
- hero: z.locked(PageHero),
20
- body: z.freeform({ sections: [ImageText, Points, FavouriteArticles, People, Quote], custom: true }),
21
- },
22
- seo: true,
23
- // A page field (spec 2026-09-10 page fields §7): the parent's view lists
24
- // the children that keep this on. Edited on the Settings tab.
25
- fields: { showInNavigation: f.boolean().default(true) },
26
- });
4
+ import { pageSchema } from "./Page.schema";
27
5
 
28
6
  function PageView({ zones, page }: Props<typeof pageSchema>) {
29
7
  // Sub-navigation: the published children that opted in through their page field.
@@ -0,0 +1,17 @@
1
+ import { f, smoodly } from "smoodly";
2
+ import { articles } from "@/smoodly/collections";
3
+
4
+ // Articles an editor picks by hand (refList), as cards. The resolve pass
5
+ // hydrates each ref before render, so the view gets article fields, not
6
+ // ids; an article unpublished after this page went live resolves to
7
+ // null and is skipped.
8
+ export const favouriteArticlesSchema = smoodly.schema.section({
9
+ name: "favouriteArticles",
10
+ title: "Favourite articles",
11
+ description: "Articles picked by hand, as cards.",
12
+ fields: {
13
+ heading: f.text(),
14
+ items: f.refList(() => articles).max(6),
15
+ },
16
+ sample: { heading: "From the journal", items: [] },
17
+ });
@@ -1,22 +1,7 @@
1
- import { f, smoodly, type Props } from "smoodly";
2
- import { articles } from "@/smoodly/collections";
1
+ import { smoodly, type Props } from "smoodly/react";
3
2
  import { ArticleCard } from "@/components/ArticleCard";
4
3
  import { ui } from "@/components/strings";
5
-
6
- // Articles an editor picks by hand (refList), as cards. The resolve pass
7
- // hydrates each ref before render, so the view gets article fields, not
8
- // ids; an article unpublished after this page went live resolves to
9
- // null and is skipped.
10
- export const favouriteArticlesSchema = smoodly.schema.section({
11
- name: "favouriteArticles",
12
- title: "Favourite articles",
13
- description: "Articles picked by hand, as cards.",
14
- fields: {
15
- heading: f.text(),
16
- items: f.refList(() => articles).max(6),
17
- },
18
- sample: { heading: "From the journal", items: [] },
19
- });
4
+ import { favouriteArticlesSchema } from "./FavouriteArticles.schema";
20
5
 
21
6
  const m = smoodly.marks(favouriteArticlesSchema);
22
7
 
@@ -0,0 +1,31 @@
1
+ import { f, smoodly } from "smoodly";
2
+
3
+ // The site footer — a VISUAL global item (smoodly/globals.ts): one row,
4
+ // edited under Global content, rendered by the layout. Three link columns
5
+ // as top-level objects, each localized as a whole (an object holding a
6
+ // list — one level, which the list field allows; a list of columns each
7
+ // holding a list would be a nested list, which it refuses).
8
+ const column = () =>
9
+ f.object({ title: f.text(), links: f.list(f.object({ label: f.text(), href: f.link() })) }).localized();
10
+
11
+ export const footerSchema = smoodly.schema.section({
12
+ name: "footer",
13
+ title: "Footer",
14
+ description: "The site footer: tagline, three link columns, copyright.",
15
+ fields: {
16
+ tagline: f.text().localized(),
17
+ company: column(),
18
+ legal: column(),
19
+ social: column(),
20
+ copyright: f.text(),
21
+ },
22
+ sample: {
23
+ tagline: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
24
+ company: { title: "Company", links: [{ label: "About", href: "/company/about-us" }] },
25
+ legal: { title: "Legal", links: [{ label: "Privacy", href: "#" }] },
26
+ social: { title: "Social", links: [{ label: "Instagram", href: "#" }] },
27
+ copyright: "© 2026 Lorem Co. Built with Smoodly.",
28
+ },
29
+ // The layout's footer keeps the design's spacing: no Spacing & layout group.
30
+ styles: false,
31
+ });
@@ -1,36 +1,8 @@
1
- import { f, smoodly, type Props, type Scope } from "smoodly";
1
+ import { smoodly, type Props, type Scope } from "smoodly/react";
2
+ import { footerSchema } from "./Footer.schema";
2
3
 
3
- // The site footer — a VISUAL global item (smoodly/globals.ts): one row,
4
- // edited under Global content, rendered by the layout. Three link columns
5
- // as top-level objects, each localized as a whole (an object holding a
6
- // list — one level, which the list field allows; a list of columns each
7
- // holding a list would be a nested list, which it refuses). The layout
8
- // renders FooterView directly to hand it the contact object item, which
9
- // is not a footer field.
10
- const column = () =>
11
- f.object({ title: f.text(), links: f.list(f.object({ label: f.text(), href: f.link() })) }).localized();
12
-
13
- export const footerSchema = smoodly.schema.section({
14
- name: "footer",
15
- title: "Footer",
16
- description: "The site footer: tagline, three link columns, copyright.",
17
- fields: {
18
- tagline: f.text().localized(),
19
- company: column(),
20
- legal: column(),
21
- social: column(),
22
- copyright: f.text(),
23
- },
24
- sample: {
25
- tagline: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
26
- company: { title: "Company", links: [{ label: "About", href: "/company/about-us" }] },
27
- legal: { title: "Legal", links: [{ label: "Privacy", href: "#" }] },
28
- social: { title: "Social", links: [{ label: "Instagram", href: "#" }] },
29
- copyright: "© 2026 Lorem Co. Built with Smoodly.",
30
- },
31
- // The layout's footer keeps the design's spacing: no Spacing & layout group.
32
- styles: false,
33
- });
4
+ // The site footer's view. The layout renders FooterView directly to hand
5
+ // it the contact object item, which is not a footer field.
34
6
 
35
7
  export type ContactFields = { email: string; phone?: string; address: string };
36
8
  type Column = { title: string; links: { label: string; href: string }[] };
@@ -0,0 +1,21 @@
1
+ import { f, smoodly } from "smoodly";
2
+
3
+ // The site header — a VISUAL global item (smoodly/globals.ts): one row,
4
+ // edited under Global content, rendered by the layout, never placed in a
5
+ // page. The brand is the same in every language; the nav is a list of
6
+ // links localized as a whole, so each language has its own labels and
7
+ // hrefs. The layout renders HeaderView directly to hand it the locale
8
+ // links (a paired component takes only its schema's props); the paired
9
+ // Header is what the registry and the admin know.
10
+ export const headerSchema = smoodly.schema.section({
11
+ name: "header",
12
+ title: "Header",
13
+ description: "The site header: brand and navigation.",
14
+ fields: {
15
+ brand: f.text(),
16
+ nav: f.list(f.object({ label: f.text(), href: f.link() })).localized(),
17
+ },
18
+ sample: { brand: "Lorem Co.", nav: [{ label: "Home", href: "/" }] },
19
+ // Nobody pads the header from the editor: no Spacing & layout group.
20
+ styles: false,
21
+ });
@@ -1,24 +1,5 @@
1
- import { f, smoodly, type Props } from "smoodly";
2
-
3
- // The site header — a VISUAL global item (smoodly/globals.ts): one row,
4
- // edited under Global content, rendered by the layout, never placed in a
5
- // page. The brand is the same in every language; the nav is a list of
6
- // links localized as a whole, so each language has its own labels and
7
- // hrefs. The layout renders HeaderView directly to hand it the locale
8
- // links (a paired component takes only its schema's props); the paired
9
- // Header is what the registry and the admin know.
10
- export const headerSchema = smoodly.schema.section({
11
- name: "header",
12
- title: "Header",
13
- description: "The site header: brand and navigation.",
14
- fields: {
15
- brand: f.text(),
16
- nav: f.list(f.object({ label: f.text(), href: f.link() })).localized(),
17
- },
18
- sample: { brand: "Lorem Co.", nav: [{ label: "Home", href: "/" }] },
19
- // Nobody pads the header from the editor: no Spacing & layout group.
20
- styles: false,
21
- });
1
+ import { smoodly, type Props } from "smoodly/react";
2
+ import { headerSchema } from "./Header.schema";
22
3
 
23
4
  export type LocaleLink = { code: string; url: string; current: boolean };
24
5
 
@@ -0,0 +1,24 @@
1
+ import { f, smoodly } from "smoodly";
2
+
3
+ // The home page opener: kicker, heading, text, up to two buttons and a
4
+ // portrait photo. Home locks it (`z.locked(heroSchema)`): one node an editor
5
+ // fills but cannot add, move or remove. `sample` is what the editor
6
+ // materializes into an empty locked zone, so it is a complete value.
7
+ export const heroSchema = smoodly.schema.section({
8
+ name: "hero",
9
+ title: "Hero",
10
+ description: "The home page opener: heading, text, buttons and a photo.",
11
+ fields: {
12
+ kicker: f.text().optional(),
13
+ heading: f.text(),
14
+ text: f.text(),
15
+ buttons: f.list(f.object({ label: f.text(), href: f.link() })).max(2),
16
+ image: f.image({ aspect: "4:5" }),
17
+ },
18
+ sample: {
19
+ kicker: "Lorem ipsum dolor",
20
+ heading: "Consectetur adipiscing elit sed do eiusmod",
21
+ text: "Tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.",
22
+ buttons: [{ label: "About us", href: "/company/about-us" }],
23
+ },
24
+ });
@@ -1,28 +1,6 @@
1
- import { f, smoodly, type Props } from "smoodly";
1
+ import { smoodly, type Props } from "smoodly/react";
2
2
  import { SmoodlyImage } from "smoodly/image";
3
-
4
- // The home page opener: kicker, heading, text, up to two buttons and a
5
- // portrait photo. Home locks it (`z.locked(Hero)`): one node an editor
6
- // fills but cannot add, move or remove. `sample` is what the editor
7
- // materializes into an empty locked zone, so it is a complete value.
8
- export const heroSchema = smoodly.schema.section({
9
- name: "hero",
10
- title: "Hero",
11
- description: "The home page opener: heading, text, buttons and a photo.",
12
- fields: {
13
- kicker: f.text().optional(),
14
- heading: f.text(),
15
- text: f.text(),
16
- buttons: f.list(f.object({ label: f.text(), href: f.link() })).max(2),
17
- image: f.image({ aspect: "4:5" }),
18
- },
19
- sample: {
20
- kicker: "Lorem ipsum dolor",
21
- heading: "Consectetur adipiscing elit sed do eiusmod",
22
- text: "Tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.",
23
- buttons: [{ label: "About us", href: "/company/about-us" }],
24
- },
25
- });
3
+ import { heroSchema } from "./Hero.schema";
26
4
 
27
5
  const m = smoodly.marks(heroSchema);
28
6
 
@@ -0,0 +1,30 @@
1
+ import { f, smoodly } from "smoodly";
2
+
3
+ // A photo beside a heading and richtext, the photo on either side (a
4
+ // setting, not a field: settings are never translated). Without a photo the
5
+ // heading takes the left column and the text the right — the About
6
+ // page's text block. The richtext renders through the package's
7
+ // RichText: paragraphs, headings, lists, quotes.
8
+ export const imageTextSchema = smoodly.schema.section({
9
+ name: "imageText",
10
+ title: "Image and text",
11
+ description: "A photo beside a heading and text; text alone in two columns without one.",
12
+ fields: {
13
+ image: f.image({ aspect: "4:3" }).optional(),
14
+ heading: f.text(),
15
+ // Body copy beside a photo: emphasis and links, no headings — the block's
16
+ // own heading field owns that. Every other richtext field takes the default.
17
+ text: f.richtext({ toolset: smoodly.toolset({ marks: ["bold", "italic", "link"] }) }),
18
+ link: f.object({ label: f.text(), href: f.link() }).optional(),
19
+ },
20
+ settings: {
21
+ imageSide: f.radio([{ value: "left", label: "Image left" }, { value: "right", label: "Image right" }]).default("left"),
22
+ },
23
+ sample: {
24
+ heading: "Duis aute irure dolor in reprehenderit",
25
+ text: {
26
+ type: "doc",
27
+ content: [{ type: "paragraph", content: [{ type: "text", text: "In voluptate velit esse cillum dolore eu fugiat nulla pariatur." }] }],
28
+ },
29
+ },
30
+ });
@@ -1,35 +1,7 @@
1
- import { f, smoodly, type Props } from "smoodly";
1
+ import { smoodly, type Props } from "smoodly/react";
2
2
  import { RichText } from "@/smoodly/richtext";
3
3
  import { SmoodlyImage } from "smoodly/image";
4
-
5
- // A photo beside a heading and richtext, the photo on either side (a
6
- // setting, not a field: settings are never translated). Without a photo the
7
- // heading takes the left column and the text the right — the About
8
- // page's text block. The richtext renders through the package's
9
- // RichText: paragraphs, headings, lists, quotes.
10
- export const imageTextSchema = smoodly.schema.section({
11
- name: "imageText",
12
- title: "Image and text",
13
- description: "A photo beside a heading and text; text alone in two columns without one.",
14
- fields: {
15
- image: f.image({ aspect: "4:3" }).optional(),
16
- heading: f.text(),
17
- // Body copy beside a photo: emphasis and links, no headings — the block's
18
- // own heading field owns that. Every other richtext field takes the default.
19
- text: f.richtext({ toolset: smoodly.toolset({ marks: ["bold", "italic", "link"] }) }),
20
- link: f.object({ label: f.text(), href: f.link() }).optional(),
21
- },
22
- settings: {
23
- imageSide: f.radio([{ value: "left", label: "Image left" }, { value: "right", label: "Image right" }]).default("left"),
24
- },
25
- sample: {
26
- heading: "Duis aute irure dolor in reprehenderit",
27
- text: {
28
- type: "doc",
29
- content: [{ type: "paragraph", content: [{ type: "text", text: "In voluptate velit esse cillum dolore eu fugiat nulla pariatur." }] }],
30
- },
31
- },
32
- });
4
+ import { imageTextSchema } from "./ImageText.schema";
33
5
 
34
6
  const m = smoodly.marks(imageTextSchema);
35
7
 
@@ -0,0 +1,21 @@
1
+ import { f, smoodly } from "smoodly";
2
+
3
+ // The opener of every page that is not the home page: kicker, heading,
4
+ // text and an optional wide photo. Page and Articles lock it — each page
5
+ // shape locks its own hero, which is the point: a locked zone is per
6
+ // shape. Without an image the copy stands alone (the Articles index).
7
+ export const pageHeroSchema = smoodly.schema.section({
8
+ name: "pageHero",
9
+ title: "Page hero",
10
+ description: "A page opener: kicker, heading, text and an optional wide photo.",
11
+ fields: {
12
+ kicker: f.text().optional(),
13
+ heading: f.text(),
14
+ text: f.text(),
15
+ image: f.image({ aspect: "21:9" }).optional(),
16
+ },
17
+ sample: {
18
+ heading: "About us",
19
+ text: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.",
20
+ },
21
+ });
@@ -1,25 +1,6 @@
1
- import { f, smoodly, type Props } from "smoodly";
1
+ import { smoodly, type Props } from "smoodly/react";
2
2
  import { SmoodlyImage } from "smoodly/image";
3
-
4
- // The opener of every page that is not the home page: kicker, heading,
5
- // text and an optional wide photo. Page and Articles lock it — each page
6
- // shape locks its own hero, which is the point: a locked zone is per
7
- // shape. Without an image the copy stands alone (the Articles index).
8
- export const pageHeroSchema = smoodly.schema.section({
9
- name: "pageHero",
10
- title: "Page hero",
11
- description: "A page opener: kicker, heading, text and an optional wide photo.",
12
- fields: {
13
- kicker: f.text().optional(),
14
- heading: f.text(),
15
- text: f.text(),
16
- image: f.image({ aspect: "21:9" }).optional(),
17
- },
18
- sample: {
19
- heading: "About us",
20
- text: "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.",
21
- },
22
- });
3
+ import { pageHeroSchema } from "./PageHero.schema";
23
4
 
24
5
  const m = smoodly.marks(pageHeroSchema);
25
6
 
@@ -0,0 +1,15 @@
1
+ import { f, smoodly } from "smoodly";
2
+ import { people } from "@/smoodly/collections";
3
+
4
+ // People picked by hand (refList), four to a row: name and role, the
5
+ // role in the page's language because it is a localized field.
6
+ export const peopleSchema = smoodly.schema.section({
7
+ name: "peopleSection",
8
+ title: "People",
9
+ description: "A heading and a row of people.",
10
+ fields: {
11
+ heading: f.text(),
12
+ people: f.refList(() => people),
13
+ },
14
+ sample: { heading: "Our people", people: [] },
15
+ });
@@ -1,18 +1,6 @@
1
- import { f, smoodly, type Props } from "smoodly";
1
+ import { smoodly, type Props } from "smoodly/react";
2
2
  import { people } from "@/smoodly/collections";
3
-
4
- // People picked by hand (refList), four to a row: name and role, the
5
- // role in the page's language because it is a localized field.
6
- export const peopleSchema = smoodly.schema.section({
7
- name: "peopleSection",
8
- title: "People",
9
- description: "A heading and a row of people.",
10
- fields: {
11
- heading: f.text(),
12
- people: f.refList(() => people),
13
- },
14
- sample: { heading: "Our people", people: [] },
15
- });
3
+ import { peopleSchema } from "./People.schema";
16
4
 
17
5
  const m = smoodly.marks(peopleSchema);
18
6
 
@@ -0,0 +1,21 @@
1
+ import { f, smoodly } from "smoodly";
2
+
3
+ // A heading over one to six points, each an icon, a heading and a line
4
+ // of text: the list field with min/max, and an object inside the list.
5
+ export const pointsSchema = smoodly.schema.section({
6
+ name: "points",
7
+ title: "Points",
8
+ description: "A heading and one to six points with an icon each.",
9
+ fields: {
10
+ heading: f.text(),
11
+ points: f.list(f.object({
12
+ icon: f.select([{ value: "circle", label: "Circle" }, { value: "square", label: "Square" }, { value: "diamond", label: "Diamond" }]),
13
+ heading: f.text(),
14
+ text: f.text(),
15
+ })).min(1).max(6),
16
+ },
17
+ sample: {
18
+ heading: "Quis autem vel eum",
19
+ points: [{ icon: "circle", heading: "Iure reprehenderit", text: "Qui in ea voluptate velit esse quam nihil molestiae consequatur." }],
20
+ },
21
+ });