fulldev-ui 0.5.0-beta.5 → 0.5.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRIBUTING.md CHANGED
@@ -15,19 +15,25 @@ Here lay a few resources we wrote to help you do it!
15
15
  │ ├── content/
16
16
  │ │ ├── pages/
17
17
  │ │ │ └── ...
18
- │ │ ├── settings/
18
+ │ │ ├── presets/
19
19
  │ │ │ └── ...
20
20
  │ │ └── ...
21
21
  │ ├── css/
22
22
  │ │ └── ...
23
+ │ ├── images/
24
+ │ │ └── ...
23
25
  │ ├── integration/
24
26
  │ │ └── ...
25
27
  │ ├── layouts/
26
28
  │ │ └── ...
29
+ │ ├── loaders/
30
+ │ │ └── ...
27
31
  │ ├── pages/
28
32
  │ │ └── ...
29
33
  │ ├── schemas/
30
34
  │ │ └── ...
35
+ │ ├── types/
36
+ │ │ └── ...
31
37
  │ └── utils/
32
38
  │ └── ...
33
39
  ├── public/
@@ -101,9 +107,9 @@ For a faster and easier review we advise you to use [conventional commits](https
101
107
  Have you used fulldev-ui to build a website? Add it to the showcase!
102
108
 
103
109
  1. Fork this repository.
104
- 2. Add a screenshot of your site to the `public/images/showcase/` directory.
105
- 3. Create a file which is your unslugged domain in `src/pages/records/showcase/` for example `src/pages/records/showcase/google-com.mdx`.
106
- 4. Go to the forked repository on your Github and clicke the 'Contribute` button to make a Pull Request.
110
+ 2. Add a screenshot of your site to the `/src/images/showcase/` directory.
111
+ 3. Create a file which in `/src/content/pages/showcase/` for example `/src/content/pages/showcase/google.md`.
112
+ 4. Go to the forked repository on your Github and clicke the "Contribute" button to make a Pull Request.
107
113
 
108
114
  ## Community / Contact
109
115
 
package/astro.config.ts CHANGED
@@ -2,7 +2,6 @@ import mdx from '@astrojs/mdx'
2
2
  import sitemap from '@astrojs/sitemap'
3
3
  // @ts-ignore
4
4
  import liveCode from 'astro-live-code'
5
- import pagefind from 'astro-pagefind'
6
5
  import { defineConfig } from 'astro/config'
7
6
  import integration from 'fulldev-ui/integration'
8
7
 
@@ -19,7 +18,6 @@ export default defineConfig({
19
18
  integrations: [
20
19
  sitemap(),
21
20
  mdx(),
22
- pagefind(),
23
21
  liveCode({
24
22
  layout: '/src/components/experimental/Window.astro',
25
23
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fulldev-ui",
3
- "version": "0.5.0-beta.5",
3
+ "version": "0.5.0-beta.6",
4
4
  "description": "A component library built for Astro",
5
5
  "homepage": "https://ui.full.dev",
6
6
  "bugs": "https://github.com/fulldotdev/ui/issues",
@@ -41,6 +41,7 @@
41
41
  "@astrojs/sitemap": "^3.2.1",
42
42
  "@astrolib/seo": "1.0.0-beta.8",
43
43
  "@iconify-json/tabler": "^1.2.5",
44
+ "@nanostores/persistent": "^0.10.2",
44
45
  "@radix-ui/colors": "^3.0.0",
45
46
  "@rollup/plugin-yaml": "^4.1.2",
46
47
  "@types/js-yaml": "^4.0.9",
@@ -48,7 +49,6 @@
48
49
  "astro": "^4.16.6",
49
50
  "astro-favicons": "^2.0.2",
50
51
  "astro-live-code": "^0.0.3",
51
- "astro-pagefind": "^1.6.0",
52
52
  "astro-seo": "^0.8.4",
53
53
  "bezier-easing": "^2.1.0",
54
54
  "colorjs.io": "^0.5.2",
@@ -56,11 +56,13 @@
56
56
  "fs": "0.0.1-security",
57
57
  "install": "^0.13.0",
58
58
  "js-yaml": "^4.1.0",
59
+ "nanostores": "^0.11.3",
59
60
  "npm": "^10.9.0",
60
61
  "radash": "^12.1.0",
61
62
  "remeda": "2.15.2",
62
63
  "sass": "^1.80.2",
63
64
  "sharp": "^0.33.5",
65
+ "stripe": "^17.2.1",
64
66
  "tailwindcss": "^3.4.14",
65
67
  "typescript": "^5.6.3",
66
68
  "unocss": "^0.63.4",
package/pnpm-lock.yaml CHANGED
@@ -17,6 +17,9 @@ dependencies:
17
17
  '@iconify-json/tabler':
18
18
  specifier: ^1.2.5
19
19
  version: 1.2.5
20
+ '@nanostores/persistent':
21
+ specifier: ^0.10.2
22
+ version: 0.10.2(nanostores@0.11.3)
20
23
  '@radix-ui/colors':
21
24
  specifier: ^3.0.0
22
25
  version: 3.0.0
@@ -38,9 +41,6 @@ dependencies:
38
41
  astro-live-code:
39
42
  specifier: ^0.0.3
40
43
  version: 0.0.3
41
- astro-pagefind:
42
- specifier: ^1.6.0
43
- version: 1.6.0(astro@4.16.6)
44
44
  astro-seo:
45
45
  specifier: ^0.8.4
46
46
  version: 0.8.4(prettier-plugin-astro@0.14.1)(prettier@3.3.3)(typescript@5.6.3)
@@ -62,6 +62,9 @@ dependencies:
62
62
  js-yaml:
63
63
  specifier: ^4.1.0
64
64
  version: 4.1.0
65
+ nanostores:
66
+ specifier: ^0.11.3
67
+ version: 0.11.3
65
68
  npm:
66
69
  specifier: ^10.9.0
67
70
  version: 10.9.0
@@ -77,6 +80,9 @@ dependencies:
77
80
  sharp:
78
81
  specifier: ^0.33.5
79
82
  version: 0.33.5
83
+ stripe:
84
+ specifier: ^17.2.1
85
+ version: 17.2.1
80
86
  tailwindcss:
81
87
  specifier: ^3.4.14
82
88
  version: 3.4.14
@@ -1299,6 +1305,15 @@ packages:
1299
1305
  - supports-color
1300
1306
  dev: false
1301
1307
 
1308
+ /@nanostores/persistent@0.10.2(nanostores@0.11.3):
1309
+ resolution: {integrity: sha512-BEndnLhRC+yP7gXTESepBbSj8XNl8OXK9hu4xAgKC7MWJHKXnEqJMqY47LUyHxK6vYgFnisyHmqq+vq8AUFyIg==}
1310
+ engines: {node: ^18.0.0 || >=20.0.0}
1311
+ peerDependencies:
1312
+ nanostores: ^0.9.0 || ^0.10.0 || ^0.11.0
1313
+ dependencies:
1314
+ nanostores: 0.11.3
1315
+ dev: false
1316
+
1302
1317
  /@nodelib/fs.scandir@2.1.5:
1303
1318
  resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
1304
1319
  engines: {node: '>= 8'}
@@ -1321,50 +1336,6 @@ packages:
1321
1336
  resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
1322
1337
  dev: false
1323
1338
 
1324
- /@pagefind/darwin-arm64@1.1.1:
1325
- resolution: {integrity: sha512-tZ9tysUmQpFs2EqWG2+E1gc+opDAhSyZSsgKmFzhnWfkK02YHZhvL5XJXEZDqYy3s1FAKhwjTg8XDxneuBlDZQ==}
1326
- cpu: [arm64]
1327
- os: [darwin]
1328
- requiresBuild: true
1329
- dev: false
1330
- optional: true
1331
-
1332
- /@pagefind/darwin-x64@1.1.1:
1333
- resolution: {integrity: sha512-ChohLQ39dLwaxQv0jIQB/SavP3TM5K5ENfDTqIdzLkmfs3+JlzSDyQKcJFjTHYcCzQOZVeieeGq8PdqvLJxJxQ==}
1334
- cpu: [x64]
1335
- os: [darwin]
1336
- requiresBuild: true
1337
- dev: false
1338
- optional: true
1339
-
1340
- /@pagefind/default-ui@1.1.1:
1341
- resolution: {integrity: sha512-ZM0zDatWDnac/VGHhQCiM7UgA4ca8jpjA+VfuTJyHJBaxGqZMQnm4WoTz9E0KFcue1Bh9kxpu7uWFZfwpZZk0A==}
1342
- dev: false
1343
-
1344
- /@pagefind/linux-arm64@1.1.1:
1345
- resolution: {integrity: sha512-H5P6wDoCoAbdsWp0Zx0DxnLUrwTGWGLu/VI1rcN2CyFdY2EGSvPQsbGBMrseKRNuIrJDFtxHHHyjZ7UbzaM9EA==}
1346
- cpu: [arm64]
1347
- os: [linux]
1348
- requiresBuild: true
1349
- dev: false
1350
- optional: true
1351
-
1352
- /@pagefind/linux-x64@1.1.1:
1353
- resolution: {integrity: sha512-yJs7tTYbL2MI3HT+ngs9E1BfUbY9M4/YzA0yEM5xBo4Xl8Yu8Qg2xZTOQ1/F6gwvMrjCUFo8EoACs6LRDhtMrQ==}
1354
- cpu: [x64]
1355
- os: [linux]
1356
- requiresBuild: true
1357
- dev: false
1358
- optional: true
1359
-
1360
- /@pagefind/windows-x64@1.1.1:
1361
- resolution: {integrity: sha512-b7/qPqgIl+lMzkQ8fJt51SfguB396xbIIR+VZ3YrL2tLuyifDJ1wL5mEm+ddmHxJ2Fki340paPcDan9en5OmAw==}
1362
- cpu: [x64]
1363
- os: [win32]
1364
- requiresBuild: true
1365
- dev: false
1366
- optional: true
1367
-
1368
1339
  /@parcel/watcher-android-arm64@2.4.1:
1369
1340
  resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==}
1370
1341
  engines: {node: '>= 10.0.0'}
@@ -2257,17 +2228,6 @@ packages:
2257
2228
  unist-util-visit-parents: 6.0.1
2258
2229
  dev: false
2259
2230
 
2260
- /astro-pagefind@1.6.0(astro@4.16.6):
2261
- resolution: {integrity: sha512-U/WuE0ktkZkoFJf6yopWO4DjIJ3+wrnopE2L3kUYiyqNTJpqmp13bFLR8gir6B+KzQ5dsXQtJZYTQtKJg1FxIA==}
2262
- peerDependencies:
2263
- astro: ^2.0.4 || ^3.0.0 || ^4.0.0
2264
- dependencies:
2265
- '@pagefind/default-ui': 1.1.1
2266
- astro: 4.16.6(sass@1.80.2)(typescript@5.6.3)
2267
- pagefind: 1.1.1
2268
- sirv: 2.0.4
2269
- dev: false
2270
-
2271
2231
  /astro-seo@0.8.4(prettier-plugin-astro@0.14.1)(prettier@3.3.3)(typescript@5.6.3):
2272
2232
  resolution: {integrity: sha512-Ou1vzQSXAxa0K8rtNtXNvSpYqOGEgMhh0immMxJeXmbVZac3UKCNWAoXWyOQDFYsZvBugCRSg0N1phBqPMVgCw==}
2273
2233
  dependencies:
@@ -4419,6 +4379,11 @@ packages:
4419
4379
  engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
4420
4380
  hasBin: true
4421
4381
 
4382
+ /nanostores@0.11.3:
4383
+ resolution: {integrity: sha512-TUes3xKIX33re4QzdxwZ6tdbodjmn3tWXCEc1uokiEmo14sI1EaGYNs2k3bU2pyyGNmBqFGAVl6jAGWd06AVIg==}
4384
+ engines: {node: ^18.0.0 || >=20.0.0}
4385
+ dev: false
4386
+
4422
4387
  /napi-build-utils@1.0.2:
4423
4388
  resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}
4424
4389
  dev: false
@@ -4641,17 +4606,6 @@ packages:
4641
4606
  resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==}
4642
4607
  dev: false
4643
4608
 
4644
- /pagefind@1.1.1:
4645
- resolution: {integrity: sha512-U2YR0dQN5B2fbIXrLtt/UXNS0yWSSYfePaad1KcBPTi0p+zRtsVjwmoPaMQgTks5DnHNbmDxyJUL5TGaLljK3A==}
4646
- hasBin: true
4647
- optionalDependencies:
4648
- '@pagefind/darwin-arm64': 1.1.1
4649
- '@pagefind/darwin-x64': 1.1.1
4650
- '@pagefind/linux-arm64': 1.1.1
4651
- '@pagefind/linux-x64': 1.1.1
4652
- '@pagefind/windows-x64': 1.1.1
4653
- dev: false
4654
-
4655
4609
  /parse-entities@4.0.1:
4656
4610
  resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
4657
4611
  dependencies:
@@ -5540,6 +5494,14 @@ packages:
5540
5494
  engines: {node: '>=0.10.0'}
5541
5495
  dev: false
5542
5496
 
5497
+ /stripe@17.2.1:
5498
+ resolution: {integrity: sha512-Mwb0SitV/UjxTLSUiTlUQ0VDE/gfyQ7OHDGdvDdvKIH4CNNqobPKlzlWhoZHFFU0OA/YsZyBtPULK4JG86BAAg==}
5499
+ engines: {node: '>=12.*'}
5500
+ dependencies:
5501
+ '@types/node': 17.0.45
5502
+ qs: 6.13.0
5503
+ dev: false
5504
+
5543
5505
  /style-to-object@0.4.4:
5544
5506
  resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==}
5545
5507
  dependencies:
@@ -31,8 +31,9 @@ const { color = 'brand', size = 'sm', text, ...rest } = Astro.props
31
31
  background-color: var(--color-9);
32
32
  padding: 0 var(--gutter);
33
33
  width: 100%;
34
- height: var(--banner-height);
34
+ min-height: var(--banner-height);
35
35
  overflow: hidden;
36
+ text-align: center;
36
37
 
37
38
  .text {
38
39
  color: var(--color-contrast);
@@ -1,12 +1,10 @@
1
1
  ---
2
- import Button from 'fulldev-ui/components/Button.astro'
2
+ import CartForm from 'fulldev-ui/components/CartForm.astro'
3
3
  import Element from 'fulldev-ui/components/Element.astro'
4
4
  import Gallery from 'fulldev-ui/components/experimental/Gallery.astro'
5
5
  import Heading from 'fulldev-ui/components/Heading.astro'
6
6
  import Image from 'fulldev-ui/components/Image.astro'
7
- import Input from 'fulldev-ui/components/Input.astro'
8
7
  import List from 'fulldev-ui/components/List.astro'
9
- import Price from 'fulldev-ui/components/Price.astro'
10
8
  import Section from 'fulldev-ui/components/Section.astro'
11
9
  import Text from 'fulldev-ui/components/Text.astro'
12
10
 
@@ -21,12 +19,16 @@ const {
21
19
  buttons,
22
20
  text,
23
21
  subheading,
22
+ variants,
24
23
  button,
25
24
  description,
26
25
  form,
27
26
  gallery = 'horizontal',
28
27
  ...rest
29
28
  } = Astro.props
29
+
30
+ const slug = Astro.url.pathname.replace(/^\/|\/$/g, '') || 'index'
31
+ const src = `/src/images/${images?.[0].id}`
30
32
  ---
31
33
 
32
34
  <Section
@@ -53,28 +55,16 @@ const {
53
55
  style={{ maxWidth: '420px' }}
54
56
  text={text || description}
55
57
  />
56
- <Price value={price} />
57
58
  <List
58
59
  items={list}
59
60
  style={{ marginTop: 'var(--space-5)' }}
60
61
  />
61
- <Element class:list="row">
62
- <Input
63
- value={1}
64
- name={'quantity'}
65
- style={{ width: 'var(--space-7)' }}
66
- type="number"
67
- min={1}
68
- />
69
- <Button
70
- color="brand"
71
- text={form?.submit}
72
- />
73
- </Element>
74
- <Button
75
- style={{ marginTop: 'var(--space-3)', width: '100%', maxWidth: '400px' }}
76
- variant="secondary"
77
- {...button}
62
+ <CartForm
63
+ image={src}
64
+ {title}
65
+ {price}
66
+ {slug}
67
+ {variants}
78
68
  />
79
69
  </Element>
80
70
  </Section>
@@ -36,7 +36,7 @@ const page = slug ? (await getEntry('pages', slug)).data : {}
36
36
  const entryProps = {
37
37
  heading: page.title,
38
38
  text: page.description,
39
- href: `/${slug}/`,
39
+ href: slug ? `/${slug}/` : undefined,
40
40
  ...page,
41
41
  }
42
42
 
@@ -0,0 +1,36 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import CartList from 'fulldev-ui/components/CartList.astro'
4
+ import CartSummary from 'fulldev-ui/components/CartSummary.astro'
5
+ import Drawer from 'fulldev-ui/components/Drawer.astro'
6
+
7
+ interface Props extends ComponentProps<typeof Drawer> {}
8
+
9
+ const {
10
+ icon = 'shopping-cart',
11
+ color = 'brand',
12
+ id = 'cart',
13
+ ...rest
14
+ } = Astro.props
15
+ ---
16
+
17
+ <Drawer
18
+ class:list="cart"
19
+ {icon}
20
+ {color}
21
+ {id}
22
+ {...rest}
23
+ >
24
+ <CartList />
25
+ <CartSummary slot="footer" />
26
+ </Drawer>
27
+
28
+ <style lang="scss" is:global>
29
+ @layer fulldev {
30
+ form {
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: var(--space-4);
34
+ }
35
+ }
36
+ </style>
@@ -0,0 +1,121 @@
1
+ ---
2
+ import type { ComponentProps } from 'astro/types'
3
+ import Button from 'fulldev-ui/components/Button.astro'
4
+ import Input from 'fulldev-ui/components/Input.astro'
5
+ import Select from 'fulldev-ui/components/Select.astro'
6
+ import { capitalize } from 'radash'
7
+ import Form from './experimental/Form.astro'
8
+ import Price from './Price.astro'
9
+
10
+ interface Props extends Omit<ComponentProps<typeof Form>, 'fields' | 'submit'> {
11
+ title: string
12
+ slug: string
13
+ price: number
14
+ image?: string | undefined
15
+ variants?:
16
+ | {
17
+ [key: string]: string[]
18
+ }
19
+ | undefined
20
+ }
21
+
22
+ const { title, slug, image, price, variants, ...rest } = Astro.props
23
+ ---
24
+
25
+ <Form
26
+ class:list="cart-form"
27
+ {...rest}
28
+ >
29
+ <Input
30
+ type="hidden"
31
+ name="title"
32
+ value={title}
33
+ />
34
+ <Input
35
+ type="hidden"
36
+ name="slug"
37
+ value={slug}
38
+ />
39
+ <Input
40
+ type="hidden"
41
+ name="url"
42
+ value={Astro.site ? Astro.site.href + slug : undefined}
43
+ />
44
+ <Input
45
+ type="hidden"
46
+ name="image"
47
+ value={image}
48
+ />
49
+ {
50
+ Object.entries(variants ?? {}).map(([key, options]) => (
51
+ <Select
52
+ label={capitalize(key)}
53
+ name={`variant-${key}`}
54
+ options={options}
55
+ />
56
+ ))
57
+ }
58
+ <Price value={price} />
59
+ <Input
60
+ type="hidden"
61
+ name="price"
62
+ value={price}
63
+ />
64
+ <Button
65
+ variant="primary"
66
+ color="brand"
67
+ type="submit"
68
+ class="cart-add"
69
+ text="Toevoegen aan winkelwagen"
70
+ />
71
+ </Form>
72
+
73
+ <script>
74
+ import { $cart } from 'fulldev-ui/stores/cart.ts'
75
+ import { generateProductId, generateProductName } from 'fulldev-ui/utils/cart'
76
+
77
+ document.addEventListener('astro:page-load', () => {
78
+ const cartForm = document.querySelector('.cart-form')
79
+
80
+ cartForm?.addEventListener('submit', (e) => {
81
+ e.preventDefault()
82
+
83
+ if (e.target instanceof HTMLFormElement) {
84
+ const formData = new FormData(e.target)
85
+
86
+ const title = formData.get('title') as string
87
+ const slug = formData.get('slug') as string
88
+ const url = formData.get('url') as string
89
+ const image = formData.get('image') as string
90
+ const price = Number(formData.get('price')) as number
91
+ const variants = Array.from(formData.entries())
92
+ .filter(([key]) => key.startsWith('variant-'))
93
+ .map(([_, value]) => value) as string[]
94
+
95
+ const id = generateProductId(slug, variants)
96
+ const name = generateProductName(title, variants)
97
+
98
+ const currentCart = $cart.get()
99
+ const newCart = [...currentCart, { id, name, price, image, url }]
100
+ $cart.set(newCart)
101
+
102
+ const cartDialog = document?.querySelector('dialog#cart')
103
+ if (cartDialog instanceof HTMLDialogElement) cartDialog.showModal()
104
+ }
105
+ })
106
+ })
107
+ </script>
108
+
109
+ <style is:global lang="scss">
110
+ @layer fulldev {
111
+ .cart-form {
112
+ display: flex;
113
+ flex-direction: column;
114
+ gap: var(--space-4);
115
+
116
+ .input {
117
+ display: none;
118
+ }
119
+ }
120
+ }
121
+ </style>
@@ -0,0 +1,134 @@
1
+ ---
2
+ import Element from 'fulldev-ui/components/Element.astro'
3
+ import Button from './Button.astro'
4
+ import Card from './Card.astro'
5
+ import Heading from './Heading.astro'
6
+ import Text from './Text.astro'
7
+
8
+ const { ...rest } = Astro.props
9
+ ---
10
+
11
+ <Element
12
+ if
13
+ class:list="cart-list"
14
+ {...rest}
15
+ />
16
+
17
+ <template>
18
+ <Card class="cart-list-card">
19
+ <img class="cart-list-image image" />
20
+ <Element class="column">
21
+ <Heading
22
+ if
23
+ level={4}
24
+ class="heading"
25
+ />
26
+ <Element class="row">
27
+ <Text
28
+ if
29
+ class="cart-list-price"
30
+ />
31
+ <Button
32
+ class:list="cart-list-remove"
33
+ variant="tertiary"
34
+ icon="trash"
35
+ type="button"
36
+ />
37
+ </Element>
38
+ </Element>
39
+ </Card>
40
+ </template>
41
+
42
+ <script>
43
+ import { $cart } from 'fulldev-ui/stores/cart.ts'
44
+ import { formatPrice } from 'fulldev-ui/utils/cart'
45
+
46
+ function setCards(items: any) {
47
+ const template = document.querySelector('template')
48
+ const container = document.querySelector('.cart-list')
49
+
50
+ if (!container || !template) return
51
+
52
+ container.innerHTML = ''
53
+
54
+ items.forEach((item: any, index: number) => {
55
+ const clone = template?.content.cloneNode(true)
56
+ if (!(clone instanceof DocumentFragment)) return
57
+ const card = clone.querySelector('.cart-list-card')
58
+ if (!card) return
59
+
60
+ const img = card.querySelector('img')
61
+ if (img) img.src = item.image
62
+
63
+ const h4 = card.querySelector('h4')
64
+ if (h4) h4.textContent = item.name
65
+
66
+ const p = card.querySelector('p')
67
+ if (p) p.textContent = formatPrice(item.price)
68
+
69
+ const button = card.querySelector('button')
70
+ if (button) {
71
+ button.addEventListener('click', () => {
72
+ const currentCart = $cart.get()
73
+ const newCart = [...currentCart]
74
+ newCart.splice(index, 1)
75
+ $cart.set(newCart)
76
+ })
77
+ }
78
+
79
+ container.appendChild(clone)
80
+ })
81
+ }
82
+
83
+ document.addEventListener('astro:page-load', () => {
84
+ setCards($cart.get())
85
+
86
+ $cart.subscribe((items: any) => {
87
+ setCards(items)
88
+ })
89
+ })
90
+ </script>
91
+
92
+ <style lang="scss" is:global>
93
+ @layer fulldev {
94
+ .cart-list {
95
+ display: flex;
96
+ flex-direction: column;
97
+
98
+ .card {
99
+ display: flex;
100
+ flex-direction: row;
101
+ gap: var(--space-5);
102
+ width: 100%;
103
+
104
+ &:not(:first-child) {
105
+ margin-top: var(--space-5);
106
+ border-top: 1px solid var(--color-a6);
107
+ padding-top: var(--space-5);
108
+ }
109
+
110
+ .image {
111
+ display: block;
112
+ width: 100px;
113
+ height: auto;
114
+ }
115
+
116
+ .column {
117
+ display: flex;
118
+ flex-direction: column;
119
+ justify-content: space-between;
120
+ gap: var(--space-3);
121
+ width: 100%;
122
+ height: 100%;
123
+ }
124
+
125
+ .row {
126
+ display: flex;
127
+ flex-direction: row;
128
+ justify-content: space-between;
129
+ align-items: center;
130
+ }
131
+ }
132
+ }
133
+ }
134
+ </style>