fulldev-ui 0.5.0-beta.5 → 0.5.0-beta.7
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 +2 -3
- package/package.json +4 -2
- package/pnpm-lock.yaml +31 -69
- package/src/blocks/Article.astro +31 -12
- 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 +38 -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 +41 -8
- package/src/components/Footer.astro +0 -1
- package/src/components/Form.astro +49 -0
- package/src/components/Header.astro +5 -8
- package/src/components/Image.astro +0 -1
- package/src/components/Input.astro +6 -0
- package/src/components/Price.astro +7 -11
- package/src/components/Search.astro +1 -4
- package/src/components/Section.astro +0 -1
- package/src/components/Sidebar.astro +1 -1
- package/src/components/Toc.astro +3 -6
- package/src/components/docs/PropsTable.astro +1 -1
- 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/base.yml +1 -2
- package/src/content/presets/docs.yml +4 -4
- package/src/env.d.ts +1 -1
- package/src/layouts/DocsLayout.astro +23 -35
- package/src/layouts/Layout.astro +12 -16
- package/src/layouts/OverviewLayout.astro +5 -2
- package/src/layouts/PostLayout.astro +7 -10
- package/src/schemas/pageSchema.ts +53 -28
- package/src/schemas/presetSchema.ts +3 -0
- package/src/schemas/utils/navigation.ts +5 -1
- 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/src/content/config.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { defineCollection } from 'astro:content'
|
|
|
2
2
|
import imageLoader from 'fulldev-ui/loaders/imageLoader.ts'
|
|
3
3
|
import imageSchema from 'fulldev-ui/schemas/imageSchema.ts'
|
|
4
4
|
import pageSchema from 'fulldev-ui/schemas/pageSchema.ts'
|
|
5
|
+
import presetSchema from 'fulldev-ui/schemas/presetSchema.ts'
|
|
5
6
|
|
|
6
7
|
export const collections = {
|
|
7
8
|
pages: defineCollection({
|
|
@@ -10,7 +11,7 @@ export const collections = {
|
|
|
10
11
|
}),
|
|
11
12
|
presets: defineCollection({
|
|
12
13
|
type: 'data',
|
|
13
|
-
schema:
|
|
14
|
+
schema: presetSchema,
|
|
14
15
|
}),
|
|
15
16
|
images: defineCollection({
|
|
16
17
|
loader: imageLoader,
|
|
@@ -10,9 +10,8 @@ code:
|
|
|
10
10
|
posthog.init('phc_mVacbe8Xydu0UZlh4bNw5EGisvzyRcpqXEEuEEp5lOY',{api_host:'https://eu.i.posthog.com', person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well
|
|
11
11
|
})
|
|
12
12
|
</script>
|
|
13
|
-
header: true
|
|
14
13
|
navigation:
|
|
15
|
-
|
|
14
|
+
header: true
|
|
16
15
|
company: Fulldev UI
|
|
17
16
|
buttons:
|
|
18
17
|
- text: Docs
|
package/src/env.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/// <reference types="astro/client" />
|
|
2
|
-
/// <reference path="../.astro/types.d.ts" />
|
|
2
|
+
/// <reference path="../.astro/types.d.ts" />
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
import type { ComponentProps } from 'astro/types'
|
|
3
3
|
import Button from 'fulldev-ui/components/Button.astro'
|
|
4
4
|
import Element from 'fulldev-ui/components/Element.astro'
|
|
5
|
-
import Prose from 'fulldev-ui/components/experimental/Prose.astro'
|
|
6
5
|
import Layout from 'fulldev-ui/layouts/Layout.astro'
|
|
7
6
|
import { crush } from 'radash'
|
|
7
|
+
import PostLayout from './PostLayout.astro'
|
|
8
8
|
|
|
9
9
|
type Props = ComponentProps<typeof Layout>
|
|
10
10
|
|
|
11
|
-
const {
|
|
12
|
-
const { Content } = await render()
|
|
11
|
+
const { slug, navigation } = Astro.props
|
|
13
12
|
|
|
14
13
|
const flatButtons = crush((navigation as any)?.buttons ?? {})
|
|
15
14
|
const slugs = Object.entries(flatButtons)
|
|
@@ -21,45 +20,34 @@ const prevSlug = slugs[slugIndex - 1]
|
|
|
21
20
|
const nextSlug = slugs[slugIndex + 1]
|
|
22
21
|
---
|
|
23
22
|
|
|
24
|
-
<
|
|
23
|
+
<PostLayout
|
|
25
24
|
class:list="docs-layout"
|
|
26
|
-
{
|
|
27
|
-
{slug}
|
|
28
|
-
{navigation}
|
|
29
|
-
{...rest}
|
|
25
|
+
{...Astro.props}
|
|
30
26
|
>
|
|
31
|
-
<
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</
|
|
49
|
-
</
|
|
27
|
+
<Element
|
|
28
|
+
class:list={['prev-next', { 'next-only': !prevSlug }]}
|
|
29
|
+
slot="prose"
|
|
30
|
+
>
|
|
31
|
+
<Button
|
|
32
|
+
if={prevSlug}
|
|
33
|
+
slug={prevSlug}
|
|
34
|
+
icon="arrow-left"
|
|
35
|
+
variant="secondary"
|
|
36
|
+
/>
|
|
37
|
+
<Button
|
|
38
|
+
if={nextSlug}
|
|
39
|
+
slug={nextSlug}
|
|
40
|
+
icon="arrow-right"
|
|
41
|
+
variant="secondary"
|
|
42
|
+
reverse={true}
|
|
43
|
+
/>
|
|
44
|
+
</Element>
|
|
45
|
+
</PostLayout>
|
|
50
46
|
|
|
51
47
|
<style lang="scss" is:global>
|
|
52
48
|
@layer fulldev {
|
|
53
49
|
.docs-layout {
|
|
54
50
|
.prose {
|
|
55
|
-
--screen: 768px;
|
|
56
|
-
padding: var(--space-6) var(--gutter);
|
|
57
|
-
color: var(--color-12);
|
|
58
|
-
|
|
59
|
-
> h1 + p {
|
|
60
|
-
color: var(--color-11);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
51
|
> a,
|
|
64
52
|
> p > a {
|
|
65
53
|
color: var(--brand-11);
|
package/src/layouts/Layout.astro
CHANGED
|
@@ -7,9 +7,9 @@ import Footer from 'fulldev-ui/blocks/Footer.astro'
|
|
|
7
7
|
import Element from 'fulldev-ui/components/Element.astro'
|
|
8
8
|
import Head from 'fulldev-ui/components/Head.astro'
|
|
9
9
|
import Header from 'fulldev-ui/components/Header.astro'
|
|
10
|
+
import Section from 'fulldev-ui/components/Section.astro'
|
|
10
11
|
import Sections from 'fulldev-ui/components/sections.astro'
|
|
11
12
|
import Sidebar from 'fulldev-ui/components/Sidebar.astro'
|
|
12
|
-
import Toc from 'fulldev-ui/components/Toc.astro'
|
|
13
13
|
import type { GlobalProps } from 'fulldev-ui/types/global-props'
|
|
14
14
|
|
|
15
15
|
type Props = GlobalProps &
|
|
@@ -19,6 +19,7 @@ type Props = GlobalProps &
|
|
|
19
19
|
header?: ComponentProps<typeof Header>
|
|
20
20
|
footer?: ComponentProps<typeof Footer>
|
|
21
21
|
sections?: ComponentProps<typeof Sections>['sections']
|
|
22
|
+
section?: ComponentProps<typeof Section> | undefined
|
|
22
23
|
banner?: any
|
|
23
24
|
toc?: any
|
|
24
25
|
sidebar?: any
|
|
@@ -47,6 +48,7 @@ const {
|
|
|
47
48
|
toc,
|
|
48
49
|
sections,
|
|
49
50
|
theme,
|
|
51
|
+
section,
|
|
50
52
|
banner,
|
|
51
53
|
code,
|
|
52
54
|
themeselect,
|
|
@@ -66,34 +68,30 @@ const {
|
|
|
66
68
|
</slot>
|
|
67
69
|
<slot name="header">
|
|
68
70
|
<Header
|
|
69
|
-
|
|
70
|
-
'for-sidebar': sidebar,
|
|
71
|
-
}}
|
|
72
|
-
if={navigation || header}
|
|
73
|
-
{...navigation}
|
|
71
|
+
{...navigation?.header === true ? navigation : {}}
|
|
74
72
|
{...header}
|
|
75
73
|
/>
|
|
76
74
|
</slot>
|
|
77
75
|
<div class="core">
|
|
78
76
|
<slot name="sidebar">
|
|
79
77
|
<Sidebar
|
|
80
|
-
|
|
81
|
-
{
|
|
78
|
+
{...navigation?.sidebar === true ? navigation : {}}
|
|
79
|
+
logo={navigation?.sidebar?.header
|
|
80
|
+
? undefined
|
|
81
|
+
: navigation?.sidebar?.logo}
|
|
82
|
+
company={navigation?.sidebar?.header
|
|
83
|
+
? undefined
|
|
84
|
+
: navigation?.sidebar?.company}
|
|
82
85
|
{...sidebar}
|
|
83
86
|
/>
|
|
84
87
|
</slot>
|
|
85
88
|
<main data-pagefind-body>
|
|
86
89
|
<slot>
|
|
90
|
+
<Section {...section} />
|
|
87
91
|
<Article />
|
|
88
92
|
<Sections {sections} />
|
|
89
93
|
</slot>
|
|
90
94
|
</main>
|
|
91
|
-
<slot name="toc">
|
|
92
|
-
<Toc
|
|
93
|
-
heading={toc}
|
|
94
|
-
{render}
|
|
95
|
-
/>
|
|
96
|
-
</slot>
|
|
97
95
|
</div>
|
|
98
96
|
<slot name="footer">
|
|
99
97
|
<Footer {...footer} />
|
|
@@ -112,7 +110,6 @@ const {
|
|
|
112
110
|
}
|
|
113
111
|
|
|
114
112
|
body {
|
|
115
|
-
--screen: 100vw;
|
|
116
113
|
display: flex;
|
|
117
114
|
flex-direction: column;
|
|
118
115
|
background-color: var(--base-background);
|
|
@@ -144,7 +141,6 @@ const {
|
|
|
144
141
|
background-color: var(--color-background);
|
|
145
142
|
width: 100%;
|
|
146
143
|
max-width: 100vw;
|
|
147
|
-
overflow-x: hidden;
|
|
148
144
|
}
|
|
149
145
|
}
|
|
150
146
|
}
|
|
@@ -11,7 +11,7 @@ import { getReferenceChildren } from 'fulldev-ui/utils/getReferenceChildren'
|
|
|
11
11
|
|
|
12
12
|
type Props = ComponentProps<typeof Layout>
|
|
13
13
|
|
|
14
|
-
const { slug, sections, title, description } = Astro.props
|
|
14
|
+
const { slug, sections, title, description, render } = Astro.props
|
|
15
15
|
|
|
16
16
|
const folderChildren = await getFolderChildren(slug)
|
|
17
17
|
const referenceChildren = await getReferenceChildren(slug)
|
|
@@ -33,7 +33,10 @@ const referenceChildren = await getReferenceChildren(slug)
|
|
|
33
33
|
cards={referenceChildren}
|
|
34
34
|
structure="grid"
|
|
35
35
|
/>
|
|
36
|
-
<Article
|
|
36
|
+
<Article
|
|
37
|
+
{render}
|
|
38
|
+
toc={false}
|
|
39
|
+
/>
|
|
37
40
|
<Sections {sections} />
|
|
38
41
|
<slot />
|
|
39
42
|
</Layout>
|
|
@@ -3,22 +3,19 @@ import type { ComponentProps } from 'astro/types'
|
|
|
3
3
|
import Article from 'fulldev-ui/blocks/Article.astro'
|
|
4
4
|
import Sections from 'fulldev-ui/components/sections.astro'
|
|
5
5
|
import Layout from 'fulldev-ui/layouts/Layout.astro'
|
|
6
|
-
import Excerpt from '../blocks/Excerpt.astro'
|
|
7
6
|
|
|
8
7
|
type Props = ComponentProps<typeof Layout>
|
|
9
8
|
|
|
10
|
-
const { sections,
|
|
9
|
+
const { sections, render, toc } = Astro.props
|
|
11
10
|
---
|
|
12
11
|
|
|
13
12
|
<Layout {...Astro.props}>
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
/>
|
|
21
|
-
<Article />
|
|
13
|
+
<Article
|
|
14
|
+
{render}
|
|
15
|
+
{toc}
|
|
16
|
+
>
|
|
17
|
+
<slot name="prose" />
|
|
18
|
+
</Article>
|
|
22
19
|
<Sections {sections} />
|
|
23
20
|
<slot />
|
|
24
21
|
</Layout>
|
|
@@ -4,6 +4,9 @@ import fulldevConfig from 'virtual:fulldev-ui/config'
|
|
|
4
4
|
import footer from './components/footer'
|
|
5
5
|
import header from './components/header'
|
|
6
6
|
import image from './components/image'
|
|
7
|
+
import images from './components/images'
|
|
8
|
+
import price from './components/price'
|
|
9
|
+
import section from './components/section'
|
|
7
10
|
import sections from './components/sections'
|
|
8
11
|
import sidebar from './components/sidebar'
|
|
9
12
|
import toc from './components/toc'
|
|
@@ -12,7 +15,7 @@ import navigation from './utils/navigation'
|
|
|
12
15
|
import parents from './utils/parents'
|
|
13
16
|
import pathSchema from './utils/pathSchema'
|
|
14
17
|
|
|
15
|
-
const i18n = z
|
|
18
|
+
export const i18n = z
|
|
16
19
|
.object({
|
|
17
20
|
i18n: pathSchema('pages').optional(),
|
|
18
21
|
})
|
|
@@ -24,7 +27,7 @@ const i18n = z
|
|
|
24
27
|
return merged as typeof rest
|
|
25
28
|
})
|
|
26
29
|
|
|
27
|
-
const presets = z
|
|
30
|
+
export const presets = z
|
|
28
31
|
.object({
|
|
29
32
|
presets: z.array(pathSchema('presets')).optional(),
|
|
30
33
|
})
|
|
@@ -48,29 +51,51 @@ const presets = z
|
|
|
48
51
|
return mergedData as typeof rest
|
|
49
52
|
})
|
|
50
53
|
|
|
51
|
-
export
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
export const basePreset = z
|
|
55
|
+
.object({})
|
|
56
|
+
.passthrough()
|
|
57
|
+
.transform(async (data) => {
|
|
58
|
+
if (!fulldevConfig.basePreset) return data
|
|
59
|
+
const baseEntry = await getEntry('presets', fulldevConfig.basePreset)
|
|
60
|
+
const mergedData = assign(baseEntry?.data ?? {}, data)
|
|
61
|
+
return mergedData as typeof data
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
export const page = z
|
|
65
|
+
.object({
|
|
66
|
+
component,
|
|
67
|
+
parents,
|
|
68
|
+
theme: z.enum(['light', 'dark']),
|
|
69
|
+
lang: z.string(),
|
|
70
|
+
seo: z
|
|
71
|
+
.object({
|
|
72
|
+
title: z.string().optional(),
|
|
73
|
+
description: z.string().optional(),
|
|
74
|
+
})
|
|
75
|
+
.optional(),
|
|
76
|
+
title: z.string(),
|
|
77
|
+
description: z.string().optional(),
|
|
78
|
+
image,
|
|
79
|
+
images,
|
|
80
|
+
section,
|
|
81
|
+
sections,
|
|
82
|
+
footer,
|
|
83
|
+
header: header,
|
|
84
|
+
sidebar: sidebar,
|
|
85
|
+
navigation,
|
|
86
|
+
toc,
|
|
87
|
+
price,
|
|
88
|
+
code: z.any(),
|
|
89
|
+
sizes: z.any(),
|
|
90
|
+
banner: z.any(),
|
|
91
|
+
_schema: z.any(),
|
|
92
|
+
uitverkocht: z.any(),
|
|
93
|
+
rating: z.any(),
|
|
94
|
+
variants: z.any(),
|
|
95
|
+
heading: z.any(),
|
|
96
|
+
href: z.any(),
|
|
97
|
+
})
|
|
98
|
+
.partial()
|
|
99
|
+
.strict()
|
|
100
|
+
|
|
101
|
+
export default i18n.pipe(basePreset).pipe(presets).pipe(page)
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { z } from 'astro:content'
|
|
1
2
|
import header from '../components/header'
|
|
2
3
|
import sidebar from '../components/sidebar'
|
|
3
4
|
|
|
4
|
-
export default sidebar.merge(header)
|
|
5
|
+
export default sidebar.merge(header).extend({
|
|
6
|
+
header: z.boolean().optional(),
|
|
7
|
+
sidebar: z.boolean().optional(),
|
|
8
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { persistentAtom } from '@nanostores/persistent'
|
|
2
|
+
import { computed } from 'nanostores'
|
|
3
|
+
|
|
4
|
+
// type Item = CollectionEntry<'products'>['data'] & {
|
|
5
|
+
// quantity: number
|
|
6
|
+
// }
|
|
7
|
+
|
|
8
|
+
type Item = any
|
|
9
|
+
|
|
10
|
+
export const $cart = persistentAtom<Item[] | []>('cart', [], {
|
|
11
|
+
encode: JSON.stringify,
|
|
12
|
+
decode: JSON.parse,
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
// export const cartIsOpen = atom(false)
|
|
16
|
+
|
|
17
|
+
export const $totalPrice = computed($cart, ($cart) =>
|
|
18
|
+
$cart.reduce((a, b) => +a + b.price * b.quantity, 0)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
// export const totalQuantity = computed(cart, ($cart) =>
|
|
22
|
+
// $cart.reduce((a, b) => +a + b.quantity, 0)
|
|
23
|
+
// )
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// import Stripe from 'stripe'
|
|
2
|
+
|
|
3
|
+
// const stripe = new Stripe(import.meta.env.STRIPE_SECRET_KEY)
|
|
4
|
+
|
|
5
|
+
const slugify = (input: string): string => {
|
|
6
|
+
return input
|
|
7
|
+
.toLowerCase()
|
|
8
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
9
|
+
.replace(/^-+|-+$/g, '')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const generateProductId = (
|
|
13
|
+
slug: string,
|
|
14
|
+
variants?: string[] | undefined
|
|
15
|
+
): string => {
|
|
16
|
+
const slugified = slugify(slug)
|
|
17
|
+
|
|
18
|
+
if (variants && variants.length > 0)
|
|
19
|
+
return `${slugified}--${variants.map((variant) => slugify(variant)).join('--')}`
|
|
20
|
+
|
|
21
|
+
return slugified
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const generateProductName = (
|
|
25
|
+
title: string,
|
|
26
|
+
variants?: string[] | undefined
|
|
27
|
+
): string => {
|
|
28
|
+
if (variants && variants.length > 0)
|
|
29
|
+
return `${title} / ${variants.join(' / ')}`
|
|
30
|
+
|
|
31
|
+
return title
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const formatPrice = (price: number): string => {
|
|
35
|
+
return `€${price?.toFixed(2).replace('.', ',')}`
|
|
36
|
+
}
|
package/tsconfig.json
CHANGED
|
File without changes
|