fulldev-ui 0.5.0-beta.9 → 0.6.0-beta-5

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 (342) hide show
  1. package/.env.example +3 -0
  2. package/.prettierrc.yaml +1 -0
  3. package/astro.config.ts +10 -34
  4. package/cloudcannon.config.yml +235 -0
  5. package/package.json +25 -29
  6. package/pnpm-lock.yaml +943 -2157
  7. package/public/favicon/android-chrome-192x192.png +0 -0
  8. package/public/favicon/android-chrome-512x512.png +0 -0
  9. package/public/favicon/apple-touch-icon.png +0 -0
  10. package/public/favicon/manifest.webmanifest +7 -3
  11. package/public/favicon/mstile-150x150.png +0 -0
  12. package/src/blocks/Banner.astro +14 -29
  13. package/src/blocks/Contact1.astro +92 -0
  14. package/src/blocks/Content1.astro +77 -0
  15. package/src/blocks/Content2.astro +91 -0
  16. package/src/blocks/Content3.astro +70 -0
  17. package/src/blocks/Content4.astro +72 -0
  18. package/src/blocks/Cta1.astro +58 -0
  19. package/src/blocks/Feature1.astro +61 -0
  20. package/src/blocks/Features1.astro +66 -0
  21. package/src/blocks/Footer.astro +100 -3
  22. package/src/blocks/Header.astro +192 -3
  23. package/src/blocks/Hero1.astro +60 -0
  24. package/src/blocks/Logos1.astro +55 -0
  25. package/src/blocks/Products1.astro +90 -0
  26. package/src/blocks/Reviews1.astro +75 -0
  27. package/src/blocks/_Hero.astro +245 -0
  28. package/src/components/Avatar.astro +28 -9
  29. package/src/components/Avatars.astro +36 -0
  30. package/src/components/Badge.astro +63 -24
  31. package/src/components/Badges.astro +16 -23
  32. package/src/components/Block.astro +30 -0
  33. package/src/components/Blocks.astro +26 -0
  34. package/src/components/Breadcrumb.astro +58 -0
  35. package/src/components/Button.astro +49 -119
  36. package/src/components/Buttons.astro +23 -13
  37. package/src/components/Card.astro +9 -137
  38. package/src/components/Cards.astro +33 -35
  39. package/src/components/Carousel.astro +106 -0
  40. package/src/components/Cart.astro +18 -14
  41. package/src/components/CartAdd.svelte +76 -0
  42. package/src/components/CartCheckout.svelte +58 -0
  43. package/src/components/CartForm.svelte +130 -0
  44. package/src/components/CartList.svelte +88 -0
  45. package/src/components/CartQuantity.svelte +81 -0
  46. package/src/components/CartSummary.astro +16 -105
  47. package/src/components/CartTotal.svelte +15 -0
  48. package/src/components/Channel.astro +44 -35
  49. package/src/components/Channels.astro +20 -6
  50. package/src/components/Checkbox.astro +52 -27
  51. package/src/components/Code.astro +52 -0
  52. package/src/components/Container.astro +25 -0
  53. package/src/components/Dialog.astro +3 -2
  54. package/src/components/Drawer.astro +55 -146
  55. package/src/components/DrawerOld.astro +143 -0
  56. package/src/components/Element.astro +18 -8
  57. package/src/components/Form.astro +16 -13
  58. package/src/components/Gallery.astro +174 -0
  59. package/src/components/Group.astro +25 -0
  60. package/src/components/Head.astro +62 -25
  61. package/src/components/Header.astro +10 -115
  62. package/src/components/Heading.astro +51 -44
  63. package/src/components/Icon.astro +29 -33
  64. package/src/components/Image.astro +18 -68
  65. package/src/components/Input.astro +65 -51
  66. package/src/components/Label.astro +20 -15
  67. package/src/components/Layout.astro +35 -0
  68. package/src/components/Link.astro +51 -32
  69. package/src/components/Links.astro +42 -0
  70. package/src/components/List.astro +41 -16
  71. package/src/components/LocaleSwitcher.astro +2 -2
  72. package/src/components/Logo.astro +56 -0
  73. package/src/components/Menu.astro +21 -17
  74. package/src/components/Navigation.astro +39 -0
  75. package/src/components/Panel.astro +25 -0
  76. package/src/components/Paragraph.astro +55 -0
  77. package/src/components/Price.astro +4 -4
  78. package/src/components/Prose.astro +86 -0
  79. package/src/components/Rating.astro +23 -62
  80. package/src/components/Search.astro +107 -43
  81. package/src/components/Section.astro +13 -242
  82. package/src/components/Select.astro +45 -55
  83. package/src/components/Sidebar.astro +53 -76
  84. package/src/components/Social.astro +11 -9
  85. package/src/components/Socials.astro +9 -5
  86. package/src/components/Stack.astro +25 -0
  87. package/src/components/Subheader.astro +59 -0
  88. package/src/components/Switch.astro +72 -29
  89. package/src/components/Table.astro +1 -1
  90. package/src/components/Tagline.astro +31 -13
  91. package/src/components/Textarea.astro +40 -50
  92. package/src/components/Themer.astro +76 -0
  93. package/src/components/Toc.astro +30 -37
  94. package/src/components/Writeup.astro +34 -65
  95. package/src/components/_Author.astro +90 -0
  96. package/src/components/_Header.astro +129 -0
  97. package/src/components/_Image.astro +79 -0
  98. package/src/components/_Prose copy.astro +172 -0
  99. package/src/components/_Sidebar copy.astro +87 -0
  100. package/src/components/docs/PropsTable.astro +38 -264
  101. package/src/components/experimental/Window.astro +5 -57
  102. package/src/content/config.ts +3 -10
  103. package/src/content/{presets → layouts}/base.yml +52 -73
  104. package/src/content/pages/blocks/_categories.mdx +0 -2
  105. package/src/content/pages/blocks/_footer.mdx +0 -2
  106. package/src/content/pages/blocks/_header.mdx +0 -4
  107. package/src/content/pages/blocks/_jobs.mdx +0 -2
  108. package/src/content/pages/blocks/_prices.mdx +0 -2
  109. package/src/content/pages/blocks/_product.mdx +0 -2
  110. package/src/content/pages/blocks/_products.mdx +0 -2
  111. package/src/content/pages/blocks/_stats.mdx +0 -2
  112. package/src/content/pages/blocks/banner.mdx +0 -2
  113. package/src/content/pages/blocks/colleagues.mdx +0 -3
  114. package/src/content/pages/blocks/contact.mdx +0 -2
  115. package/src/content/pages/blocks/content.mdx +0 -6
  116. package/src/content/pages/blocks/cta.mdx +0 -10
  117. package/src/content/pages/blocks/features.mdx +0 -5
  118. package/src/content/pages/blocks/hero.mdx +0 -5
  119. package/src/content/pages/blocks/intro.mdx +0 -5
  120. package/src/content/pages/blocks/posts.mdx +0 -2
  121. package/src/content/pages/blocks/reviews.mdx +0 -3
  122. package/src/content/pages/categories/category.md +7 -0
  123. package/src/content/pages/docs/_internationalization.mdx +55 -0
  124. package/src/content/pages/docs/_using-blocks.mdx +33 -0
  125. package/src/content/pages/docs/_using-presets.mdx +49 -0
  126. package/src/content/pages/docs/blocks.mdx +33 -0
  127. package/src/content/pages/docs/collections/images.mdx +102 -0
  128. package/src/content/pages/docs/collections/pages.mdx +119 -0
  129. package/src/content/pages/docs/collections/presets.mdx +60 -0
  130. package/src/content/pages/docs/collections.mdx +42 -0
  131. package/src/content/pages/{base/card.mdx → docs/components/_card.mdx} +2 -5
  132. package/src/content/pages/{base → docs/components}/_dialog.mdx +1 -2
  133. package/src/content/pages/{base → docs/components}/_drawer.mdx +1 -2
  134. package/src/content/pages/{base → docs/components}/_localeswitcher.mdx +1 -2
  135. package/src/content/pages/{base → docs/components}/_switch.mdx +3 -4
  136. package/src/content/pages/{typography → docs/components}/_tagline.mdx +3 -4
  137. package/src/content/pages/docs/components/_toggle.mdx +30 -0
  138. package/src/content/pages/docs/components/avatar.mdx +34 -0
  139. package/src/content/pages/{base → docs/components}/badge.mdx +28 -10
  140. package/src/content/pages/docs/components/badges.mdx +46 -0
  141. package/src/content/pages/docs/components/button.mdx +78 -0
  142. package/src/content/pages/docs/components/buttons.mdx +51 -0
  143. package/src/content/pages/docs/components/channel.mdx +91 -0
  144. package/src/content/pages/docs/components/channels.mdx +89 -0
  145. package/src/content/pages/docs/components/checkbox.mdx +34 -0
  146. package/src/content/pages/docs/components/code.mdx +45 -0
  147. package/src/content/pages/docs/components/heading.mdx +59 -0
  148. package/src/content/pages/docs/components/icon.mdx +48 -0
  149. package/src/content/pages/docs/components/image.mdx +25 -0
  150. package/src/content/pages/docs/components/input.mdx +40 -0
  151. package/src/content/pages/{typography → docs/components}/label.mdx +9 -6
  152. package/src/content/pages/{typography → docs/components}/link.mdx +24 -10
  153. package/src/content/pages/docs/components/links.mdx +99 -0
  154. package/src/content/pages/docs/components/list.mdx +44 -0
  155. package/src/content/pages/docs/components/logo.mdx +36 -0
  156. package/src/content/pages/docs/components/menu.mdx +89 -0
  157. package/src/content/pages/docs/components/prose.mdx +36 -0
  158. package/src/content/pages/docs/components/rating.mdx +76 -0
  159. package/src/content/pages/{base → docs/components}/section.mdx +2 -3
  160. package/src/content/pages/{base → docs/components}/select.mdx +1 -11
  161. package/src/content/pages/docs/components/social.mdx +94 -0
  162. package/src/content/pages/docs/components/socials.mdx +102 -0
  163. package/src/content/pages/docs/components/switch.mdx +34 -0
  164. package/src/content/pages/{base → docs/components}/table.mdx +1 -4
  165. package/src/content/pages/docs/components/tagline.mdx +46 -0
  166. package/src/content/pages/docs/components/text.mdx +48 -0
  167. package/src/content/pages/docs/components/textarea.mdx +34 -0
  168. package/src/content/pages/docs/components/themer.mdx +49 -0
  169. package/src/content/pages/docs/components.mdx +37 -0
  170. package/src/content/pages/docs/customization.mdx +151 -0
  171. package/src/content/pages/docs/frameworks.mdx +29 -0
  172. package/src/content/pages/docs/generating-pages.mdx +129 -0
  173. package/src/content/pages/docs/index.mdx +20 -0
  174. package/src/content/pages/docs/installation.mdx +50 -0
  175. package/src/content/pages/docs/layouts.mdx +33 -0
  176. package/src/content/pages/index.mdx +25 -33
  177. package/src/content/pages/posts/post.md +7 -0
  178. package/src/content/pages/products/product.md +20 -0
  179. package/src/content/pages/showcase/anti-slip-profiles.md +2 -2
  180. package/src/content/pages/showcase/fulldev-ui.md +1 -1
  181. package/src/content/pages/showcase/lavis-detailing.md +1 -1
  182. package/src/content/pages/showcase/leren-trainingsacteren.md +1 -1
  183. package/src/content/pages/showcase/miele-witgoedcenter-amsterdam.md +1 -1
  184. package/src/content/pages/showcase/sloepverhuur-bolsward.md +1 -1
  185. package/src/content/pages/showcase/stark-vulcanising-products.md +1 -1
  186. package/src/content/pages/showcase/the-gym-haren.md +1 -1
  187. package/src/content/pages/showcase/van-dillen-antieke-bouwmaterialen.md +1 -1
  188. package/src/content/pages/showcase.mdx +4 -3
  189. package/src/css/color.css +0 -10
  190. package/src/css/custom.css +10 -12
  191. package/src/css/size.css +2 -11
  192. package/src/css/theme.css +95 -0
  193. package/src/env.d.ts +1 -0
  194. package/src/images/favicon/android-chrome-192x192.png +0 -0
  195. package/src/images/favicon/android-chrome-512x512.png +0 -0
  196. package/src/images/favicon/apple-touch-icon.png +0 -0
  197. package/src/images/favicon/browserconfig.xml +9 -0
  198. package/src/images/favicon/favicon-16x16.png +0 -0
  199. package/src/images/favicon/favicon-32x32.png +0 -0
  200. package/src/images/favicon/favicon-48x48.png +0 -0
  201. package/src/images/favicon/favicon.ico +0 -0
  202. package/src/images/favicon/favicon.svg +16 -0
  203. package/src/images/favicon/manifest.webmanifest +30 -0
  204. package/src/images/favicon/mstile-150x150.png +0 -0
  205. package/src/images/favicon/safari-pinned-tab.svg +16 -0
  206. package/src/images/favicon/yandex-browser-50x50.png +0 -0
  207. package/src/images/favicon/yandex-browser-manifest.json +9 -0
  208. package/src/images/logo-1.svg +11 -0
  209. package/src/images/logo-2.svg +13 -0
  210. package/src/images/logo-basic.svg +10 -0
  211. package/src/images/logo-simple.svg +13 -0
  212. package/src/images/logo-thin.svg +15 -0
  213. package/src/images/logo.svg +14 -0
  214. package/src/images/logofat.svg +11 -0
  215. package/src/integration/index.ts +110 -140
  216. package/src/layouts/Category.astro +136 -0
  217. package/src/layouts/Doc.astro +56 -0
  218. package/src/layouts/Job.astro +60 -0
  219. package/src/layouts/Page.astro +29 -0
  220. package/src/layouts/Post.astro +52 -0
  221. package/src/layouts/Product.astro +114 -0
  222. package/src/pages/[...page].astro +29 -24
  223. package/src/pages/test.astro +37 -0
  224. package/src/schemas/components/avatar.ts +4 -1
  225. package/src/schemas/components/badge.ts +16 -11
  226. package/src/schemas/components/block.ts +60 -0
  227. package/src/schemas/components/button.ts +17 -14
  228. package/src/schemas/components/channel.ts +15 -9
  229. package/src/schemas/components/footer.ts +15 -21
  230. package/src/schemas/components/head.ts +17 -0
  231. package/src/schemas/components/header.ts +19 -7
  232. package/src/schemas/components/heading.ts +7 -1
  233. package/src/schemas/components/icon.ts +7 -1
  234. package/src/schemas/components/image.ts +38 -16
  235. package/src/schemas/components/link.ts +17 -0
  236. package/src/schemas/components/logo.ts +12 -2
  237. package/src/schemas/components/menu.ts +11 -11
  238. package/src/schemas/components/navigation.ts +10 -0
  239. package/src/schemas/components/paragraph.ts +9 -0
  240. package/src/schemas/components/price.ts +7 -1
  241. package/src/schemas/components/rating.ts +8 -13
  242. package/src/schemas/components/sidebar.ts +14 -11
  243. package/src/schemas/components/social.ts +16 -1
  244. package/src/schemas/components/tagline.ts +7 -1
  245. package/src/schemas/imageSchema.ts +33 -4
  246. package/src/schemas/page.ts +39 -0
  247. package/src/stores/cart.svelte.ts +79 -0
  248. package/src/stores/cart.ts +59 -6
  249. package/src/types/global-props.ts +0 -9
  250. package/src/types/{virtual-modules.d.ts → virtual.d.ts} +1 -1
  251. package/src/utils/cart.ts +1 -10
  252. package/src/utils/formatEntries.ts +8 -0
  253. package/src/utils/formatEntry.ts +29 -0
  254. package/src/utils/getDeepReferenceChildren.ts +14 -0
  255. package/src/utils/getHref.ts +6 -0
  256. package/src/utils/getReferenceChildren.ts +1 -1
  257. package/src/utils/setTheme.ts +18 -0
  258. package/src/utils/slugify.ts +6 -0
  259. package/svelte.config.js +5 -0
  260. package/tailwind.config.ts +71 -0
  261. package/tsconfig.json +1 -3
  262. package/src/blocks/Article.astro +0 -40
  263. package/src/blocks/Categories.astro +0 -12
  264. package/src/blocks/Colleagues.astro +0 -13
  265. package/src/blocks/Contact.astro +0 -116
  266. package/src/blocks/Content.astro +0 -12
  267. package/src/blocks/Cta.astro +0 -15
  268. package/src/blocks/Excerpt.astro +0 -14
  269. package/src/blocks/Features.astro +0 -11
  270. package/src/blocks/Hero.astro +0 -15
  271. package/src/blocks/Intro.astro +0 -23
  272. package/src/blocks/Jobs.astro +0 -12
  273. package/src/blocks/Posts.astro +0 -11
  274. package/src/blocks/Prices.astro +0 -24
  275. package/src/blocks/Product.astro +0 -110
  276. package/src/blocks/Products.astro +0 -11
  277. package/src/blocks/Reviews.astro +0 -13
  278. package/src/components/CartForm.astro +0 -121
  279. package/src/components/CartList.astro +0 -134
  280. package/src/components/Footer.astro +0 -193
  281. package/src/components/Text.astro +0 -43
  282. package/src/components/ThemeSelect.astro +0 -41
  283. package/src/components/experimental/Form.astro +0 -53
  284. package/src/components/experimental/Gallery.astro +0 -104
  285. package/src/components/experimental/Logo.astro +0 -38
  286. package/src/components/experimental/Prose.astro +0 -192
  287. package/src/components/sections.astro +0 -28
  288. package/src/content/pages/base/button.mdx +0 -60
  289. package/src/content/pages/base/checkbox.mdx +0 -42
  290. package/src/content/pages/base/icon.mdx +0 -55
  291. package/src/content/pages/base/image.mdx +0 -42
  292. package/src/content/pages/base/input.mdx +0 -56
  293. package/src/content/pages/base/rating.mdx +0 -55
  294. package/src/content/pages/base/textarea.mdx +0 -58
  295. package/src/content/pages/base/theme-select.mdx +0 -15
  296. package/src/content/pages/layouts/_layout.mdx +0 -14
  297. package/src/content/pages/layouts/docslayout.mdx +0 -14
  298. package/src/content/pages/overview/components.mdx +0 -75
  299. package/src/content/pages/overview/content-collections.mdx +0 -139
  300. package/src/content/pages/overview/frameworks.mdx +0 -198
  301. package/src/content/pages/overview/installation.mdx +0 -53
  302. package/src/content/pages/overview/introduction.mdx +0 -30
  303. package/src/content/pages/overview/theming.mdx +0 -69
  304. package/src/content/pages/schemas/page.mdx +0 -17
  305. package/src/content/pages/schemas/preset.mdx +0 -9
  306. package/src/content/pages/showcase/record.md +0 -3
  307. package/src/content/pages/typography/heading.mdx +0 -73
  308. package/src/content/pages/typography/list.mdx +0 -51
  309. package/src/content/pages/typography/text.mdx +0 -61
  310. package/src/content/presets/blocks.yml +0 -1
  311. package/src/content/presets/docs.yml +0 -6
  312. package/src/css/space.css +0 -77
  313. package/src/css/styles.css +0 -0
  314. package/src/images/avatar-1.yml +0 -1
  315. package/src/integration/generate-colors.ts +0 -639
  316. package/src/integration/tailwind-plugin.ts +0 -80
  317. package/src/integration/unocss-preset.ts +0 -84
  318. package/src/layouts/BlockLayout.astro +0 -19
  319. package/src/layouts/ContactLayout.astro +0 -21
  320. package/src/layouts/DocsLayout.astro +0 -73
  321. package/src/layouts/Layout.astro +0 -163
  322. package/src/layouts/OverviewLayout.astro +0 -42
  323. package/src/layouts/PostLayout.astro +0 -21
  324. package/src/layouts/ProductLayout.astro +0 -21
  325. package/src/loaders/imageLoader.ts +0 -26
  326. package/src/schemas/components/avatars.ts +0 -4
  327. package/src/schemas/components/buttons.ts +0 -4
  328. package/src/schemas/components/card.ts +0 -25
  329. package/src/schemas/components/cards.ts +0 -4
  330. package/src/schemas/components/channels.ts +0 -4
  331. package/src/schemas/components/images.ts +0 -4
  332. package/src/schemas/components/list.ts +0 -3
  333. package/src/schemas/components/section.ts +0 -15
  334. package/src/schemas/components/sections.ts +0 -3
  335. package/src/schemas/components/socials.ts +0 -4
  336. package/src/schemas/components/text.ts +0 -3
  337. package/src/schemas/components/toc.ts +0 -3
  338. package/src/schemas/components/writeup.ts +0 -20
  339. package/src/schemas/pageSchema.ts +0 -101
  340. package/src/schemas/presetSchema.ts +0 -3
  341. package/src/schemas/utils/navigation.ts +0 -8
  342. package/src/schemas/utils/parents.ts +0 -3
@@ -1,33 +1,37 @@
1
1
  ---
2
2
  import type { ComponentProps } from 'astro/types'
3
- import CartList from 'fulldev-ui/components/CartList.astro'
3
+ import CartList from 'fulldev-ui/components/CartList.svelte'
4
4
  import CartSummary from 'fulldev-ui/components/CartSummary.astro'
5
5
  import Drawer from 'fulldev-ui/components/Drawer.astro'
6
+ import Button from './Button.astro'
7
+ import Icon from './Icon.astro'
8
+ import Input from './Input.astro'
9
+ import Select from './Select.astro'
6
10
 
7
- interface Props extends ComponentProps<typeof Drawer> {}
11
+ interface Props extends Omit<ComponentProps<typeof Drawer>, 'id' | 'icon'> {}
8
12
 
9
- const {
10
- icon = 'shopping-cart',
11
- color = 'brand',
12
- id = 'cart',
13
- if: ifProp,
14
- ...rest
15
- } = Astro.props
13
+ const { variant = 'ghost', size = 'md', ...rest } = Astro.props
16
14
  ---
17
15
 
16
+ <Select if={false} />
17
+ <Button if={false} />
18
+ <Input if={false} />
19
+ <Icon if={false} />
20
+
18
21
  <Drawer
19
- if={ifProp}
20
22
  class:list="cart"
23
+ id="cart"
24
+ icon="shopping-cart"
25
+ {variant}
26
+ {size}
21
27
  {icon}
22
- {color}
23
- {id}
24
28
  {...rest}
25
29
  >
26
- <CartList />
30
+ <CartList client:load />
27
31
  <CartSummary slot="footer" />
28
32
  </Drawer>
29
33
 
30
- <style lang="scss" is:global>
34
+ <style is:global>
31
35
  @layer fulldev {
32
36
  form {
33
37
  display: flex;
@@ -0,0 +1,76 @@
1
+ <script lang="ts">
2
+ import { updateQuantity } from 'fulldev-ui/stores/cart.svelte.ts'
3
+ import { tick } from 'svelte'
4
+
5
+ let { uid, quantity } = $props()
6
+ let inputElement: HTMLInputElement | null = $state(null)
7
+
8
+ async function onQuantityChange(e: Event) {
9
+ const target = e.target as HTMLInputElement
10
+ const value = Number(target.value)
11
+ updateQuantity(uid, value)
12
+
13
+ if (value === 11) {
14
+ await tick()
15
+ inputElement?.focus()
16
+ }
17
+ }
18
+ </script>
19
+
20
+ <label
21
+ class="quantity input select size-md"
22
+ for="quantity"
23
+ >
24
+ {#if quantity > 10}
25
+ <input
26
+ bind:this={inputElement}
27
+ class="input-input"
28
+ name="quantity"
29
+ type="number"
30
+ value={quantity}
31
+ min={0}
32
+ onchange={onQuantityChange}
33
+ />
34
+ {:else}
35
+ <svg
36
+ xmlns="http://www.w3.org/2000/svg"
37
+ viewBox="0 0 24 24"
38
+ class="icon size-md"
39
+ >
40
+ <path
41
+ fill="none"
42
+ stroke="currentColor"
43
+ stroke-linecap="round"
44
+ stroke-linejoin="round"
45
+ stroke-width="2"
46
+ d="m6 9l6 6l6-6"
47
+ ></path>
48
+ </svg>
49
+ <select
50
+ class="select-select"
51
+ value={quantity}
52
+ onchange={onQuantityChange}
53
+ >
54
+ {#each Array(10) as _, i}
55
+ <option
56
+ value={i + 1}
57
+ selected={quantity === i + 1}
58
+ >
59
+ {i + 1}
60
+ </option>
61
+ {/each}
62
+ <option
63
+ value="11"
64
+ selected={quantity > 10}
65
+ >
66
+ Meer
67
+ </option>
68
+ </select>
69
+ {/if}
70
+ </label>
71
+
72
+ <style lang="postcss">
73
+ .quantity {
74
+ @apply w-24;
75
+ }
76
+ </style>
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ import { cart } from 'fulldev-ui/stores/cart.svelte.ts'
3
+ import Stripe from 'stripe'
4
+
5
+ const { STRIPE_RESTRICTED_KEY, URL } = $props()
6
+
7
+ async function handeClick() {
8
+ if (!STRIPE_RESTRICTED_KEY) {
9
+ console.error('Stripe key is missing')
10
+ return
11
+ }
12
+ const stripe = new Stripe(STRIPE_RESTRICTED_KEY)
13
+ const checkoutConfig = {
14
+ success_url: `${URL}/checkout`,
15
+ mode: 'payment',
16
+ customer_creation: 'always',
17
+ shipping_address_collection: {
18
+ allowed_countries: ['NL'],
19
+ },
20
+ phone_number_collection: {
21
+ enabled: true,
22
+ },
23
+ }
24
+
25
+ const lineItems = $cart.map((item) => ({
26
+ quantity: item.quantity,
27
+ adjustable_quantity: {
28
+ enabled: true,
29
+ maximum: 999999,
30
+ },
31
+ price_data: {
32
+ currency: 'eur',
33
+ product_data: {
34
+ name:
35
+ item.variants && Object.values(item.variants || {}).length
36
+ ? `${item.title} - ${Object.values(item.variants).join(' / ')}`
37
+ : item.title,
38
+ // images: [item.image ? URL + item.image : ''],
39
+ },
40
+ unit_amount: Math.round(item.price || 0 * 100),
41
+ },
42
+ }))
43
+
44
+ const checkoutSession = await stripe.checkout.sessions.create({
45
+ line_items: lineItems,
46
+ ...checkoutConfig,
47
+ })
48
+
49
+ checkoutSession.url && window.location.replace(checkoutSession.url)
50
+ }
51
+ </script>
52
+
53
+ <button
54
+ class="button variant-primary size-md"
55
+ onclick={handeClick}
56
+ >
57
+ Afrekenennn
58
+ </button>
@@ -0,0 +1,130 @@
1
+ <script lang="ts">
2
+ import { cart, getUid, openCart } from 'fulldev-ui/stores/cart.svelte'
3
+
4
+ import { capitalize } from 'radash'
5
+ import CartQuantity from './CartQuantity.svelte'
6
+ import { formatPrice } from 'fulldev-ui/utils/cart'
7
+ import type { CollectionEntry } from 'astro:content'
8
+
9
+ interface Props {
10
+ product: CollectionEntry<'products'>
11
+ }
12
+
13
+ const { product }: Props = $props()
14
+ const { slug, data } = product
15
+
16
+ const form = $state({
17
+ slug: slug,
18
+ title: data.title,
19
+ price: data.price,
20
+ image: data.images?.[0]?.src || `/${data.images?.[0]?.id}`,
21
+ variants: Object.fromEntries(
22
+ Object.entries(data.variants ?? {}).map(([key, value]) => [key, value[0]])
23
+ ),
24
+ quantity: 1,
25
+ })
26
+
27
+ function handleSubmit(event: Event) {
28
+ event.preventDefault()
29
+
30
+ const variants = { ...form.variants }
31
+ const uid = getUid(slug, variants)
32
+ const item = { ...form, uid, variants }
33
+
34
+ const index = $cart.findIndex((i) => i.uid === item.uid)
35
+ if (index === -1) $cart = [...$cart, item]
36
+ else if ($cart[index]) $cart[index].quantity += form.quantity
37
+
38
+ openCart()
39
+ }
40
+ </script>
41
+
42
+ <form
43
+ class="cart-form"
44
+ onsubmit={handleSubmit}
45
+ >
46
+ <input
47
+ name="slug"
48
+ type="hidden"
49
+ bind:value={form.slug}
50
+ />
51
+ <input
52
+ name="title"
53
+ type="hidden"
54
+ bind:value={form.title}
55
+ />
56
+ <input
57
+ name="price"
58
+ type="hidden"
59
+ bind:value={form.price}
60
+ />
61
+ <input
62
+ name="image"
63
+ type="hidden"
64
+ bind:value={form.image}
65
+ />
66
+ {#if form.variants}
67
+ {#each Object.entries(data.variants ?? {}) as [key, options]}
68
+ <label
69
+ class="select size-md"
70
+ for={`variant-${key}`}
71
+ >
72
+ <p class="label">
73
+ {capitalize(key)}
74
+ </p>
75
+ <svg
76
+ xmlns="http://www.w3.org/2000/svg"
77
+ viewBox="0 0 24 24"
78
+ class="icon size-md"
79
+ >
80
+ <path
81
+ fill="none"
82
+ stroke="currentColor"
83
+ stroke-linecap="round"
84
+ stroke-linejoin="round"
85
+ stroke-width="2"
86
+ d="m6 9l6 6l6-6"
87
+ ></path>
88
+ </svg>
89
+ <select
90
+ class="select-select"
91
+ name={key}
92
+ disabled={data.soldout}
93
+ bind:value={form.variants[key]}
94
+ >
95
+ {#each options as option}
96
+ <option value={option}>{option}</option>
97
+ {/each}
98
+ </select>
99
+ </label>
100
+ {/each}
101
+ {/if}
102
+ {#if data.price}
103
+ <div class="price">
104
+ {formatPrice(data.price)}
105
+ </div>
106
+ {/if}
107
+
108
+ <div class="inputs">
109
+ <CartQuantity bind:value={form.quantity} />
110
+ <button
111
+ class="variant-primary button size-md cart-add"
112
+ type="submit"
113
+ disabled={data.soldout}
114
+ >
115
+ {data.soldout ? 'Uitverkocht' : 'Toevoegen aan winkelwagen'}
116
+ </button>
117
+ </div>
118
+ </form>
119
+
120
+ <style lang="postcss">
121
+ @layer fulldev {
122
+ .cart-form {
123
+ @apply flex flex-col gap-4;
124
+
125
+ .inputs {
126
+ @apply flex gap-2;
127
+ }
128
+ }
129
+ }
130
+ </style>
@@ -0,0 +1,88 @@
1
+ <script lang="ts">
2
+ import { cart } from 'fulldev-ui/stores/cart.svelte.ts'
3
+ import { formatPrice } from 'fulldev-ui/utils/cart'
4
+ import CartQuantity from './CartQuantity.svelte'
5
+
6
+ function removeItem(index: number) {
7
+ cart.update((currentCart) => {
8
+ currentCart.splice(index, 1)
9
+ return [...currentCart]
10
+ })
11
+ }
12
+ </script>
13
+
14
+ <div class="cart-list">
15
+ {#each $cart as item, index}
16
+ <div
17
+ class="cart-list-card"
18
+ data-slug={item.slug}
19
+ >
20
+ <img
21
+ class="image"
22
+ src={item.image}
23
+ alt={item.title}
24
+ />
25
+ <div class="cart-list-card-segment">
26
+ <div class="cart-list-card-content">
27
+ <h3 class="heading">{item.title}</h3>
28
+ {#if item.price}
29
+ <div class="price">{formatPrice(item.price)}</div>
30
+ {/if}
31
+ </div>
32
+ <div class="cart-list-card-actions">
33
+ <CartQuantity bind:value={item.quantity} />
34
+ <button
35
+ class="button variant-outline size-sm"
36
+ type="button"
37
+ aria-label="trash"
38
+ on:click={() => removeItem(index)}
39
+ >
40
+ <svg
41
+ xmlns="http://www.w3.org/2000/svg"
42
+ viewBox="0 0 24 24"
43
+ class="icon size-md"
44
+ >
45
+ <path
46
+ fill="none"
47
+ stroke="currentColor"
48
+ stroke-linecap="round"
49
+ stroke-linejoin="round"
50
+ stroke-width="2"
51
+ d="M4 7h16m-10 4v6m4-6v6M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2l1-12M9 7V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3"
52
+ ></path>
53
+ </svg>
54
+ </button>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ {/each}
59
+ </div>
60
+
61
+ <style lang="postcss">
62
+ @layer fulldev {
63
+ .cart-list {
64
+ @apply flex flex-col text-foreground;
65
+
66
+ .cart-list-card {
67
+ @apply flex w-full gap-5;
68
+
69
+ &:not(:first-child) {
70
+ @apply mt-5 border-t pt-5;
71
+ }
72
+ }
73
+
74
+ .image {
75
+ @apply block h-auto w-24;
76
+ }
77
+
78
+ .cart-list-card-segment {
79
+ @apply flex h-full w-full flex-col justify-between gap-4;
80
+ }
81
+
82
+ .cart-list-card-content,
83
+ .cart-list-card-actions {
84
+ @apply flex justify-between gap-2;
85
+ }
86
+ }
87
+ }
88
+ </style>
@@ -0,0 +1,81 @@
1
+ <script lang="ts">
2
+ import { tick } from 'svelte'
3
+
4
+ interface Props {
5
+ value: number
6
+ size?: 'sm' | 'md' | 'lg'
7
+ change?: (quantity: number) => void
8
+ }
9
+
10
+ let { value = $bindable(), size = 'md', change }: Props = $props()
11
+ let inputElement: HTMLInputElement | null = $state(null)
12
+
13
+ let quantity = $state(value)
14
+
15
+ async function handleChange() {
16
+ value = quantity
17
+ if (change) change(value)
18
+ if (value === 11) {
19
+ await tick()
20
+ inputElement?.focus()
21
+ }
22
+ }
23
+ </script>
24
+
25
+ <label
26
+ class="quantity input select size-{size}"
27
+ for="quantity"
28
+ >
29
+ {#if value > 10}
30
+ <input
31
+ bind:this={inputElement}
32
+ bind:value={quantity}
33
+ class="input-input"
34
+ name="quantity"
35
+ type="number"
36
+ min={1}
37
+ onchange={handleChange}
38
+ />
39
+ {:else}
40
+ <svg
41
+ xmlns="http://www.w3.org/2000/svg"
42
+ viewBox="0 0 24 24"
43
+ class="icon size-{size}"
44
+ >
45
+ <path
46
+ fill="none"
47
+ stroke="currentColor"
48
+ stroke-linecap="round"
49
+ stroke-linejoin="round"
50
+ stroke-width="2"
51
+ d="m6 9l6 6l6-6"
52
+ ></path>
53
+ </svg>
54
+ <select
55
+ class="select-select"
56
+ bind:value={quantity}
57
+ onchange={handleChange}
58
+ >
59
+ {#each Array(10) as _, i}
60
+ <option
61
+ value={i + 1}
62
+ selected={value === i + 1}
63
+ >
64
+ {i + 1}
65
+ </option>
66
+ {/each}
67
+ <option
68
+ value={11}
69
+ selected={value > 10}
70
+ >
71
+ Meer
72
+ </option>
73
+ </select>
74
+ {/if}
75
+ </label>
76
+
77
+ <style lang="postcss">
78
+ .quantity {
79
+ @apply w-20;
80
+ }
81
+ </style>
@@ -1,8 +1,9 @@
1
1
  ---
2
- import Button from './Button.astro'
2
+ import { STRIPE_RESTRICTED_KEY, URL } from 'astro:env/client'
3
+ import CartCheckout from './CartCheckout.svelte'
4
+ import CartTotal from './CartTotal.svelte'
3
5
  import Element from './Element.astro'
4
- import Price from './Price.astro'
5
- import Text from './Text.astro'
6
+ import Paragraph from './Paragraph.astro'
6
7
 
7
8
  interface Props {}
8
9
 
@@ -17,131 +18,41 @@ const { ...rest } = Astro.props
17
18
  class="row"
18
19
  {...rest}
19
20
  >
20
- <Text
21
+ <Paragraph
21
22
  class:list="total"
22
23
  text="Totaal"
23
24
  contrast
24
25
  />
25
- <Price value={10} />
26
+ <CartTotal client:load />
26
27
  </div>
27
- <Text
28
+ <Paragraph
28
29
  class:list="shipping"
29
30
  text="Verzendkosten worden berekend bij het afrekenen."
30
31
  />
31
- <Button
32
- class:list="checkout-button"
33
- variant="primary"
34
- color="brand"
35
- text="Afrekenen"
32
+ <CartCheckout
33
+ {STRIPE_RESTRICTED_KEY}
34
+ {URL}
35
+ client:load
36
36
  />
37
37
  </Element>
38
38
 
39
- <style is:global lang="scss">
39
+ <style is:global>
40
40
  @layer fulldev {
41
41
  .cart-summary {
42
- display: flex;
43
- flex-direction: column;
44
- gap: var(--space-3);
42
+ @apply flex flex-col gap-3 text-foreground;
45
43
 
46
44
  .price,
47
45
  .total {
48
- font-size: var(--text-4);
46
+ @apply text-lg;
49
47
  }
50
48
 
51
49
  .row {
52
- display: flex;
53
- justify-content: space-between;
54
- align-items: center;
50
+ @apply flex w-full justify-between;
55
51
  }
56
52
 
57
53
  .shipping {
58
- font-size: var(--text-1);
54
+ @apply text-sm text-muted-foreground;
59
55
  }
60
56
  }
61
57
  }
62
58
  </style>
63
-
64
- <script>
65
- import { $cart } from 'fulldev-ui/stores/cart.ts'
66
- import { formatPrice } from 'fulldev-ui/utils/cart'
67
- import Stripe from 'stripe'
68
-
69
- const stripe = new Stripe(import.meta.env.PUBLIC_STRIPE_CHECKOUT_KEY)
70
-
71
- function setPrice(items: any) {
72
- const price = document.querySelector('.cart-summary .price')
73
- if (price)
74
- price.textContent = formatPrice(
75
- items.reduce(
76
- (acc: number, item: { price: number }) => acc + item.price,
77
- 0
78
- )
79
- )
80
- }
81
-
82
- document.addEventListener('astro:page-load', () => {
83
- setPrice($cart.get())
84
-
85
- $cart.subscribe((items: any) => {
86
- setPrice(items)
87
- })
88
-
89
- const button = document.querySelector('.cart-summary .checkout-button')
90
-
91
- button?.addEventListener('click', async () => {
92
- const items = $cart.get()
93
-
94
- const checkoutConfig = {
95
- success_url: `${import.meta.env.PUBLIC_SITE_URL}/checkout`,
96
- mode: 'payment',
97
- customer_creation: 'always',
98
- shipping_address_collection: {
99
- allowed_countries: ['NL'],
100
- },
101
- phone_number_collection: {
102
- enabled: true,
103
- },
104
- }
105
-
106
- try {
107
- const lineItems = items.map((item: any) => ({
108
- price_data: {
109
- currency: 'eur',
110
- product: item.id,
111
- },
112
- quantity: 1,
113
- }))
114
-
115
- // @ts-ignore
116
- const checkoutSession = await stripe.checkout.sessions.create({
117
- line_items: lineItems,
118
- ...checkoutConfig,
119
- })
120
-
121
- checkoutSession.url && window.location.replace(checkoutSession.url)
122
- } catch (error) {
123
- console.error(error)
124
-
125
- const lineItems = items.map((item: any) => ({
126
- quantity: 1,
127
- price_data: {
128
- currency: 'eur',
129
- product_data: {
130
- name: item.name,
131
- images: [window],
132
- },
133
- unit_amount: Math.round(item.price * 100),
134
- },
135
- }))
136
-
137
- // @ts-ignore
138
- const checkoutSession = await stripe.checkout.sessions.create({
139
- line_items: lineItems,
140
- ...checkoutConfig,
141
- })
142
-
143
- checkoutSession.url && window.location.replace(checkoutSession.url)
144
- }
145
- })
146
- })
147
- </script>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cart } from 'fulldev-ui/stores/cart.svelte.ts'
3
+ import { formatPrice } from 'fulldev-ui/utils/cart'
4
+
5
+ let total = $derived(
6
+ $cart.reduce(
7
+ (acc, item) => acc + (item.price || 0) * (item.quantity || 0),
8
+ 0
9
+ )
10
+ )
11
+ </script>
12
+
13
+ <div>
14
+ {formatPrice(total)}
15
+ </div>