fulldev-ui 0.5.0-beta.4 → 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/Excerpt.astro +14 -0
- package/src/blocks/Product.astro +51 -22
- 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 +119 -52
- package/src/components/Footer.astro +4 -0
- package/src/components/Form.astro +49 -0
- package/src/components/Header.astro +14 -12
- package/src/components/Input.astro +6 -0
- package/src/components/Menu.astro +56 -0
- package/src/components/Price.astro +7 -11
- package/src/components/Search.astro +1 -4
- package/src/components/Section.astro +2 -0
- package/src/components/Sidebar.astro +61 -111
- package/src/components/ThemeSelect.astro +3 -0
- package/src/components/Toc.astro +36 -94
- package/src/components/experimental/Form.astro +29 -5
- package/src/components/experimental/Gallery.astro +50 -126
- package/src/components/experimental/Prose.astro +32 -0
- package/src/content/pages/base/select.mdx +0 -8
- package/src/content/pages/base/textarea.mdx +0 -5
- package/src/content/pages/blocks/_product.mdx +73 -2
- package/src/content/pages/index.mdx +0 -2
- package/src/content/pages/layouts/_layout.mdx +8 -15
- package/src/content/pages/layouts/docslayout.mdx +10 -1
- package/src/content/pages/overview/components.mdx +5 -0
- package/src/content/pages/overview/content-collections.mdx +139 -0
- package/src/content/pages/overview/installation.mdx +25 -26
- package/src/content/pages/overview/introduction.mdx +16 -10
- package/src/content/pages/overview/theming.mdx +69 -0
- package/src/content/pages/schemas/page.mdx +6 -0
- package/src/content/presets/base.yml +57 -43
- package/src/content/presets/blocks.yml +0 -3
- package/src/content/presets/docs.yml +1 -61
- package/src/env.d.ts +1 -1
- package/src/layouts/Layout.astro +28 -14
- package/src/layouts/PostLayout.astro +24 -0
- package/src/layouts/ProductLayout.astro +5 -2
- package/src/schemas/components/header.ts +7 -9
- package/src/schemas/components/menu.ts +13 -0
- package/src/schemas/components/sidebar.ts +15 -0
- package/src/schemas/components/toc.ts +3 -0
- package/src/schemas/pageSchema.ts +54 -30
- package/src/schemas/presetSchema.ts +2 -32
- package/src/schemas/utils/navigation.ts +3 -53
- package/src/stores/cart.ts +23 -0
- package/src/utils/cart.ts +36 -0
- package/tsconfig.json +1 -3
- package/src/components/experimental/GalleryVertical.astro +0 -161
- package/src/content/pages/overview/content-layer.mdx +0 -128
- package/src/content/pages/overview/customization.mdx +0 -83
- /package/src/types/{global-props.d.ts → global-props.ts} +0 -0
|
@@ -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>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Button from './Button.astro'
|
|
3
|
+
import Element from './Element.astro'
|
|
4
|
+
import Price from './Price.astro'
|
|
5
|
+
import Text from './Text.astro'
|
|
6
|
+
|
|
7
|
+
interface Props {}
|
|
8
|
+
|
|
9
|
+
const { ...rest } = Astro.props
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<Element
|
|
13
|
+
size="md"
|
|
14
|
+
class="cart-summary"
|
|
15
|
+
>
|
|
16
|
+
<div
|
|
17
|
+
class="row"
|
|
18
|
+
{...rest}
|
|
19
|
+
>
|
|
20
|
+
<Text
|
|
21
|
+
class:list="total"
|
|
22
|
+
text="Totaal"
|
|
23
|
+
contrast
|
|
24
|
+
/>
|
|
25
|
+
<Price value={10} />
|
|
26
|
+
</div>
|
|
27
|
+
<Text
|
|
28
|
+
class:list="shipping"
|
|
29
|
+
text="Verzendkosten worden berekend bij het afrekenen."
|
|
30
|
+
/>
|
|
31
|
+
<Button
|
|
32
|
+
class:list="checkout-button"
|
|
33
|
+
variant="primary"
|
|
34
|
+
color="brand"
|
|
35
|
+
text="Afrekenen"
|
|
36
|
+
/>
|
|
37
|
+
</Element>
|
|
38
|
+
|
|
39
|
+
<style is:global lang="scss">
|
|
40
|
+
@layer fulldev {
|
|
41
|
+
.cart-summary {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
gap: var(--space-3);
|
|
45
|
+
|
|
46
|
+
.price,
|
|
47
|
+
.total {
|
|
48
|
+
font-size: var(--text-4);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.row {
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: space-between;
|
|
54
|
+
align-items: center;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.shipping {
|
|
58
|
+
font-size: var(--text-1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
</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
|
+
},
|
|
132
|
+
unit_amount: Math.round(item.price * 100),
|
|
133
|
+
},
|
|
134
|
+
}))
|
|
135
|
+
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
const checkoutSession = await stripe.checkout.sessions.create({
|
|
138
|
+
line_items: lineItems,
|
|
139
|
+
...checkoutConfig,
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
checkoutSession.url && window.location.replace(checkoutSession.url)
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
</script>
|
|
@@ -1,95 +1,162 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { ComponentProps } from 'astro/types'
|
|
2
|
+
import type { ComponentProps, HTMLAttributes } from 'astro/types'
|
|
3
3
|
import Button from 'fulldev-ui/components/Button.astro'
|
|
4
|
-
import Card from 'fulldev-ui/components/Card.astro'
|
|
5
4
|
import Element from 'fulldev-ui/components/Element.astro'
|
|
5
|
+
import Logo from 'fulldev-ui/components/experimental/Logo.astro'
|
|
6
|
+
import Menu from 'fulldev-ui/components/Menu.astro'
|
|
7
|
+
import type { GlobalProps } from 'fulldev-ui/types/global-props'
|
|
8
|
+
import Heading from './Heading.astro'
|
|
6
9
|
|
|
7
|
-
interface Props extends
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
interface Props extends GlobalProps, HTMLAttributes<'aside'> {
|
|
11
|
+
variant?: ComponentProps<typeof Button>['variant']
|
|
12
|
+
text?: ComponentProps<typeof Button>['text']
|
|
13
|
+
icon?: ComponentProps<typeof Button>['icon']
|
|
14
|
+
heading?: ComponentProps<typeof Heading>['text']
|
|
15
|
+
logo?: ComponentProps<typeof Logo> | undefined
|
|
16
|
+
company?: ComponentProps<typeof Logo>['company']
|
|
17
|
+
menu?: ComponentProps<typeof Menu>['groups']
|
|
12
18
|
}
|
|
13
19
|
|
|
14
20
|
const {
|
|
15
21
|
id = 'drawer',
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
size = 'sm',
|
|
23
|
+
icon = 'menu-2',
|
|
24
|
+
color,
|
|
25
|
+
variant,
|
|
26
|
+
text,
|
|
27
|
+
heading,
|
|
28
|
+
logo,
|
|
29
|
+
company,
|
|
30
|
+
menu,
|
|
20
31
|
...rest
|
|
21
32
|
} = Astro.props
|
|
22
33
|
---
|
|
23
34
|
|
|
24
35
|
<Button
|
|
25
|
-
class:list="drawer-button"
|
|
26
36
|
variant="secondary"
|
|
27
|
-
|
|
28
|
-
text={label}
|
|
29
|
-
icon={icon}
|
|
37
|
+
class:list={['drawer-button', `${id}-button`]}
|
|
30
38
|
onclick={`document.getElementById('${id}').showModal()`}
|
|
39
|
+
{variant}
|
|
40
|
+
{text}
|
|
41
|
+
{icon}
|
|
42
|
+
{color}
|
|
31
43
|
/>
|
|
32
44
|
|
|
33
45
|
<Element
|
|
46
|
+
onclick={`event.target === this && this.close()`}
|
|
47
|
+
class:list="drawer"
|
|
34
48
|
as="dialog"
|
|
35
|
-
class="drawer"
|
|
36
49
|
{id}
|
|
37
|
-
{
|
|
38
|
-
|
|
50
|
+
{text}
|
|
51
|
+
{icon}
|
|
52
|
+
{...rest}
|
|
39
53
|
>
|
|
40
|
-
<Element
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
<Element class:list="drawer-body">
|
|
55
|
+
<Element
|
|
56
|
+
class:list="drawer-header"
|
|
57
|
+
as="header"
|
|
58
|
+
>
|
|
59
|
+
<Logo
|
|
60
|
+
{company}
|
|
61
|
+
{...logo}
|
|
62
|
+
/>
|
|
63
|
+
<Heading
|
|
64
|
+
level={4}
|
|
65
|
+
text={heading}
|
|
66
|
+
/>
|
|
67
|
+
<Button
|
|
68
|
+
variant="secondary"
|
|
69
|
+
icon="x"
|
|
70
|
+
onclick={`document.getElementById('${id}').close()`}
|
|
71
|
+
/>
|
|
72
|
+
<slot name="header" />
|
|
73
|
+
</Element>
|
|
74
|
+
<Element class:list="drawer-content">
|
|
75
|
+
<Menu groups={menu} />
|
|
76
|
+
<slot />
|
|
77
|
+
</Element>
|
|
78
|
+
<Element
|
|
79
|
+
class:list="drawer-footer"
|
|
80
|
+
as="footer"
|
|
81
|
+
>
|
|
82
|
+
<slot name="footer" />
|
|
83
|
+
</Element>
|
|
45
84
|
</Element>
|
|
46
85
|
</Element>
|
|
47
86
|
|
|
48
87
|
<style lang="scss" is:global>
|
|
49
88
|
@layer fulldev {
|
|
89
|
+
body:has(dialog[open]) {
|
|
90
|
+
overflow: hidden;
|
|
91
|
+
|
|
92
|
+
@media (min-width: 768px) {
|
|
93
|
+
overflow: auto;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
50
97
|
.drawer {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
margin: 0 !important;
|
|
55
|
-
outline: 0;
|
|
56
|
-
border: 0;
|
|
57
|
-
background: var(--color-2);
|
|
98
|
+
top: 0;
|
|
99
|
+
bottom: 0;
|
|
100
|
+
margin: 0;
|
|
58
101
|
padding: 0;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
height:
|
|
63
|
-
|
|
102
|
+
width: 100%;
|
|
103
|
+
max-width: 100%;
|
|
104
|
+
height: 100%;
|
|
105
|
+
max-height: 100%;
|
|
106
|
+
|
|
107
|
+
@media (min-width: 768px) {
|
|
108
|
+
width: 440px;
|
|
109
|
+
}
|
|
64
110
|
|
|
65
111
|
&::backdrop {
|
|
112
|
+
cursor: pointer;
|
|
66
113
|
background: rgba(0, 0, 0, 0.5);
|
|
67
114
|
}
|
|
68
115
|
|
|
69
|
-
|
|
70
|
-
|
|
116
|
+
.drawer-body {
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-shrink: 1;
|
|
119
|
+
flex-direction: column;
|
|
120
|
+
border-right: 1px solid var(--color-a6);
|
|
121
|
+
height: 100%;
|
|
122
|
+
overflow: auto;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.drawer-content {
|
|
126
|
+
display: flex;
|
|
127
|
+
flex-direction: column;
|
|
128
|
+
padding: var(--space-6) var(--gutter);
|
|
71
129
|
}
|
|
72
130
|
|
|
73
|
-
|
|
74
|
-
|
|
131
|
+
.drawer-header,
|
|
132
|
+
.drawer-footer {
|
|
133
|
+
display: flex;
|
|
134
|
+
position: sticky;
|
|
135
|
+
flex-shrink: 0;
|
|
136
|
+
z-index: 1;
|
|
137
|
+
border-style: solid;
|
|
138
|
+
border-color: var(--color-a6);
|
|
139
|
+
background-color: var(--base-background);
|
|
75
140
|
}
|
|
76
141
|
|
|
77
|
-
.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
142
|
+
.drawer-header {
|
|
143
|
+
top: 0;
|
|
144
|
+
align-items: center;
|
|
145
|
+
border-bottom-width: 1px;
|
|
146
|
+
padding: 0 var(--gutter);
|
|
147
|
+
height: 56px;
|
|
83
148
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
padding-left: var(--gutter);
|
|
149
|
+
.button {
|
|
150
|
+
margin-left: auto;
|
|
87
151
|
}
|
|
152
|
+
}
|
|
88
153
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
154
|
+
.drawer-footer {
|
|
155
|
+
bottom: 0;
|
|
156
|
+
flex-direction: column;
|
|
157
|
+
margin-top: auto;
|
|
158
|
+
border-top-width: 1px;
|
|
159
|
+
padding: var(--space-5) var(--gutter);
|
|
93
160
|
}
|
|
94
161
|
}
|
|
95
162
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { ComponentProps, HTMLAttributes } from 'astro/types'
|
|
3
|
+
import Button from 'fulldev-ui/components/Button.astro'
|
|
4
|
+
import Element from 'fulldev-ui/components/Element.astro'
|
|
5
|
+
import Input from 'fulldev-ui/components/Input.astro'
|
|
6
|
+
import Select from 'fulldev-ui/components/Select.astro'
|
|
7
|
+
import Textarea from 'fulldev-ui/components/Textarea.astro'
|
|
8
|
+
import type { GlobalProps } from 'fulldev-ui/types/global-props'
|
|
9
|
+
|
|
10
|
+
interface Props extends GlobalProps, HTMLAttributes<'form'> {
|
|
11
|
+
fields: (
|
|
12
|
+
| ComponentProps<typeof Input>
|
|
13
|
+
| ComponentProps<typeof Select>
|
|
14
|
+
| (ComponentProps<typeof Textarea> & { type?: 'textarea' | undefined })
|
|
15
|
+
)[]
|
|
16
|
+
submit?: ComponentProps<typeof Button>['text']
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { fields, submit, ...rest } = Astro.props
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<Element
|
|
23
|
+
class:list="form"
|
|
24
|
+
as="form"
|
|
25
|
+
{...rest}
|
|
26
|
+
>
|
|
27
|
+
{
|
|
28
|
+
fields.map((field) => {
|
|
29
|
+
if ('options' in field) return <Select {...field} />
|
|
30
|
+
if ('type' in field && field.type === 'textarea')
|
|
31
|
+
return <Textarea {...field} />
|
|
32
|
+
return <Input {...(field as any)} />
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
<Button
|
|
36
|
+
type="submit"
|
|
37
|
+
text={submit}
|
|
38
|
+
/>
|
|
39
|
+
</Element>
|
|
40
|
+
|
|
41
|
+
<style is:global lang="scss">
|
|
42
|
+
.form {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
gap: var(--space-4);
|
|
46
|
+
width: 100%;
|
|
47
|
+
max-width: calc(var(--space-4) * 44);
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { ComponentProps, HTMLAttributes } from 'astro/types'
|
|
3
|
-
import Button from 'fulldev-ui/components/Button.astro'
|
|
4
3
|
import Buttons from 'fulldev-ui/components/Buttons.astro'
|
|
5
4
|
import Element from 'fulldev-ui/components/Element.astro'
|
|
6
5
|
import Logo from 'fulldev-ui/components/experimental/Logo.astro'
|
|
7
|
-
import Search from 'fulldev-ui/components/Search.astro'
|
|
8
6
|
import ThemeSelect from 'fulldev-ui/components/ThemeSelect.astro'
|
|
9
7
|
import type { GlobalProps } from 'fulldev-ui/types/global-props'
|
|
8
|
+
import Cart from './Cart.astro'
|
|
9
|
+
import Drawer from './Drawer.astro'
|
|
10
|
+
import type Menu from './Menu.astro'
|
|
10
11
|
|
|
11
12
|
interface Props extends GlobalProps, HTMLAttributes<'header'> {
|
|
12
|
-
logo?: ComponentProps<typeof Logo>
|
|
13
|
+
logo?: ComponentProps<typeof Logo>
|
|
13
14
|
company?: ComponentProps<typeof Logo>['company']
|
|
14
15
|
buttons?: ComponentProps<typeof Buttons>['buttons']
|
|
16
|
+
menu?: ComponentProps<typeof Menu>['groups']
|
|
15
17
|
panel?: boolean | undefined
|
|
16
18
|
search?: boolean | undefined
|
|
17
19
|
open?: boolean | undefined
|
|
18
20
|
themeselect?: boolean | undefined
|
|
21
|
+
cart?: string | undefined
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
const {
|
|
@@ -26,7 +29,9 @@ const {
|
|
|
26
29
|
buttons,
|
|
27
30
|
search,
|
|
28
31
|
panel,
|
|
32
|
+
menu,
|
|
29
33
|
themeselect,
|
|
34
|
+
cart,
|
|
30
35
|
...rest
|
|
31
36
|
} = Astro.props
|
|
32
37
|
---
|
|
@@ -47,14 +52,15 @@ const {
|
|
|
47
52
|
{buttons}
|
|
48
53
|
variant="link"
|
|
49
54
|
/>
|
|
50
|
-
{search && <Search />}
|
|
51
55
|
{themeselect && <ThemeSelect />}
|
|
52
|
-
<
|
|
53
|
-
class="menu-button"
|
|
54
|
-
variant="tertiary"
|
|
56
|
+
<Drawer
|
|
55
57
|
icon="menu-2"
|
|
56
|
-
|
|
58
|
+
id="menu"
|
|
59
|
+
{menu}
|
|
60
|
+
{logo}
|
|
61
|
+
{company}
|
|
57
62
|
/>
|
|
63
|
+
<Cart heading={cart} />
|
|
58
64
|
</Element>
|
|
59
65
|
|
|
60
66
|
<style lang="scss" is:global>
|
|
@@ -118,10 +124,6 @@ const {
|
|
|
118
124
|
}
|
|
119
125
|
|
|
120
126
|
.menu-button {
|
|
121
|
-
.icon {
|
|
122
|
-
transform: scale(1.56);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
127
|
@media (min-width: 1024px) {
|
|
126
128
|
display: none;
|
|
127
129
|
}
|
|
@@ -17,6 +17,7 @@ const {
|
|
|
17
17
|
disabled,
|
|
18
18
|
required,
|
|
19
19
|
placeholder,
|
|
20
|
+
readonly,
|
|
20
21
|
name = placeholder,
|
|
21
22
|
type = 'text',
|
|
22
23
|
...rest
|
|
@@ -41,6 +42,7 @@ const {
|
|
|
41
42
|
{value}
|
|
42
43
|
{disabled}
|
|
43
44
|
{required}
|
|
45
|
+
{readonly}
|
|
44
46
|
/>
|
|
45
47
|
<Icon name={icon} />
|
|
46
48
|
</Element>
|
|
@@ -97,6 +99,10 @@ const {
|
|
|
97
99
|
cursor: not-allowed;
|
|
98
100
|
pointer-events: none;
|
|
99
101
|
}
|
|
102
|
+
|
|
103
|
+
&[readonly] {
|
|
104
|
+
pointer-events: none;
|
|
105
|
+
}
|
|
100
106
|
}
|
|
101
107
|
}
|
|
102
108
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { ComponentProps, HTMLAttributes } from 'astro/types'
|
|
3
|
+
import Button from 'fulldev-ui/components/Button.astro'
|
|
4
|
+
import Element from 'fulldev-ui/components/Element.astro'
|
|
5
|
+
import Heading from 'fulldev-ui/components/Heading.astro'
|
|
6
|
+
import type { GlobalProps } from 'fulldev-ui/types/global-props'
|
|
7
|
+
|
|
8
|
+
interface Props extends GlobalProps, HTMLAttributes<'div'> {
|
|
9
|
+
groups?:
|
|
10
|
+
| {
|
|
11
|
+
heading?: ComponentProps<typeof Heading>['text']
|
|
12
|
+
buttons?: ComponentProps<typeof Button>[]
|
|
13
|
+
}[]
|
|
14
|
+
| undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const { groups, ...rest } = Astro.props
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
<Element
|
|
21
|
+
class:list="menu"
|
|
22
|
+
{...rest}
|
|
23
|
+
>
|
|
24
|
+
{
|
|
25
|
+
groups?.map(({ heading, buttons }) => (
|
|
26
|
+
<Element class:list="menu-group">
|
|
27
|
+
<Heading
|
|
28
|
+
level={6}
|
|
29
|
+
text={heading}
|
|
30
|
+
/>
|
|
31
|
+
{buttons?.map((button) => (
|
|
32
|
+
<Button
|
|
33
|
+
variant="link"
|
|
34
|
+
{...button}
|
|
35
|
+
/>
|
|
36
|
+
))}
|
|
37
|
+
</Element>
|
|
38
|
+
))
|
|
39
|
+
}
|
|
40
|
+
</Element>
|
|
41
|
+
|
|
42
|
+
<style lang="scss" is:global>
|
|
43
|
+
@layer fulldev {
|
|
44
|
+
.menu {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
gap: var(--space-5);
|
|
48
|
+
|
|
49
|
+
.menu-group {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
gap: var(--space-4);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
</style>
|