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 +10 -4
- package/astro.config.ts +0 -2
- package/package.json +4 -2
- package/pnpm-lock.yaml +31 -69
- package/src/blocks/Banner.astro +2 -1
- package/src/blocks/Product.astro +11 -21
- package/src/components/Card.astro +1 -1
- package/src/components/Cart.astro +36 -0
- package/src/components/CartForm.astro +121 -0
- package/src/components/CartList.astro +134 -0
- package/src/components/CartSummary.astro +146 -0
- package/src/components/Drawer.astro +31 -7
- package/src/components/Form.astro +49 -0
- package/src/components/Header.astro +2 -9
- package/src/components/Input.astro +6 -0
- package/src/components/Price.astro +7 -11
- package/src/components/Search.astro +1 -4
- package/src/components/experimental/Form.astro +29 -5
- package/src/content/config.ts +2 -1
- package/src/content/pages/base/select.mdx +0 -8
- package/src/content/pages/base/textarea.mdx +0 -5
- package/src/content/presets/docs.yml +0 -1
- package/src/env.d.ts +1 -1
- package/src/layouts/Layout.astro +4 -0
- package/src/schemas/pageSchema.ts +53 -28
- package/src/schemas/presetSchema.ts +3 -0
- package/src/stores/cart.ts +23 -0
- package/src/utils/cart.ts +36 -0
- package/tsconfig.json +1 -3
- /package/src/types/{global-props.d.ts → global-props.ts} +0 -0
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
|
-
│ │ ├──
|
|
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
|
|
105
|
-
3. Create a file which
|
|
106
|
-
4. Go to the forked repository on your Github and clicke the
|
|
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.
|
|
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:
|
package/src/blocks/Banner.astro
CHANGED
|
@@ -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);
|
package/src/blocks/Product.astro
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
import
|
|
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
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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>
|
|
@@ -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>
|