fulldev-ui 0.5.0-beta.4 → 0.5.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 (40) hide show
  1. package/package.json +1 -1
  2. package/src/blocks/Excerpt.astro +14 -0
  3. package/src/blocks/Product.astro +42 -3
  4. package/src/components/Drawer.astro +97 -54
  5. package/src/components/Footer.astro +4 -0
  6. package/src/components/Header.astro +19 -10
  7. package/src/components/Menu.astro +56 -0
  8. package/src/components/Section.astro +2 -0
  9. package/src/components/Sidebar.astro +61 -111
  10. package/src/components/ThemeSelect.astro +3 -0
  11. package/src/components/Toc.astro +36 -94
  12. package/src/components/experimental/Gallery.astro +50 -126
  13. package/src/components/experimental/Prose.astro +32 -0
  14. package/src/content/config.ts +1 -2
  15. package/src/content/pages/blocks/_product.mdx +73 -2
  16. package/src/content/pages/index.mdx +0 -2
  17. package/src/content/pages/layouts/_layout.mdx +8 -15
  18. package/src/content/pages/layouts/docslayout.mdx +10 -1
  19. package/src/content/pages/overview/components.mdx +5 -0
  20. package/src/content/pages/overview/content-collections.mdx +139 -0
  21. package/src/content/pages/overview/installation.mdx +25 -26
  22. package/src/content/pages/overview/introduction.mdx +16 -10
  23. package/src/content/pages/overview/theming.mdx +69 -0
  24. package/src/content/pages/schemas/page.mdx +6 -0
  25. package/src/content/presets/base.yml +57 -43
  26. package/src/content/presets/blocks.yml +0 -3
  27. package/src/content/presets/docs.yml +2 -61
  28. package/src/layouts/Layout.astro +24 -14
  29. package/src/layouts/PostLayout.astro +24 -0
  30. package/src/layouts/ProductLayout.astro +5 -2
  31. package/src/schemas/components/header.ts +7 -9
  32. package/src/schemas/components/menu.ts +13 -0
  33. package/src/schemas/components/sidebar.ts +15 -0
  34. package/src/schemas/components/toc.ts +3 -0
  35. package/src/schemas/pageSchema.ts +5 -6
  36. package/src/schemas/utils/navigation.ts +3 -53
  37. package/src/components/experimental/GalleryVertical.astro +0 -161
  38. package/src/content/pages/overview/content-layer.mdx +0 -128
  39. package/src/content/pages/overview/customization.mdx +0 -83
  40. package/src/schemas/presetSchema.ts +0 -33
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fulldev-ui",
3
- "version": "0.5.0-beta.4",
3
+ "version": "0.5.0-beta.5",
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",
@@ -0,0 +1,14 @@
1
+ ---
2
+ import Section from 'fulldev-ui/components/Section.astro'
3
+
4
+ const { ...rest } = Astro.props
5
+ ---
6
+
7
+ <Section
8
+ level={1}
9
+ size="lg"
10
+ align="center"
11
+ variant="primary"
12
+ color="brand"
13
+ {...rest}
14
+ />
@@ -1,9 +1,11 @@
1
1
  ---
2
2
  import Button from 'fulldev-ui/components/Button.astro'
3
3
  import Element from 'fulldev-ui/components/Element.astro'
4
+ import Gallery from 'fulldev-ui/components/experimental/Gallery.astro'
4
5
  import Heading from 'fulldev-ui/components/Heading.astro'
5
6
  import Image from 'fulldev-ui/components/Image.astro'
6
7
  import Input from 'fulldev-ui/components/Input.astro'
8
+ import List from 'fulldev-ui/components/List.astro'
7
9
  import Price from 'fulldev-ui/components/Price.astro'
8
10
  import Section from 'fulldev-ui/components/Section.astro'
9
11
  import Text from 'fulldev-ui/components/Text.astro'
@@ -22,6 +24,7 @@ const {
22
24
  button,
23
25
  description,
24
26
  form,
27
+ gallery = 'horizontal',
25
28
  ...rest
26
29
  } = Astro.props
27
30
  ---
@@ -31,10 +34,19 @@ const {
31
34
  structure="split"
32
35
  {...rest}
33
36
  >
34
- <Image {...image || images?.[0]} />
37
+ {
38
+ images && images.length > 1 ? (
39
+ <Gallery
40
+ {images}
41
+ direction={gallery}
42
+ />
43
+ ) : (
44
+ <Image {...(image || images?.[0])} />
45
+ )
46
+ }
35
47
  <Element class:list="column">
36
48
  <Heading
37
- level={1}
49
+ level={2}
38
50
  text={heading || title}
39
51
  />
40
52
  <Text
@@ -42,12 +54,17 @@ const {
42
54
  text={text || description}
43
55
  />
44
56
  <Price value={price} />
57
+ <List
58
+ items={list}
59
+ style={{ marginTop: 'var(--space-5)' }}
60
+ />
45
61
  <Element class:list="row">
46
62
  <Input
47
63
  value={1}
48
64
  name={'quantity'}
49
- style={{ width: 'var(--space-6)' }}
65
+ style={{ width: 'var(--space-7)' }}
50
66
  type="number"
67
+ min={1}
51
68
  />
52
69
  <Button
53
70
  color="brand"
@@ -64,14 +81,36 @@ const {
64
81
 
65
82
  <style is:global lang="scss">
66
83
  .product {
84
+ padding-top: 0px;
85
+
86
+ @media (min-width: 1024px) {
87
+ padding-top: var(--space-6);
88
+ }
89
+
67
90
  .column {
68
91
  display: flex;
69
92
  flex-direction: column;
70
93
  align-items: flex-start;
94
+ gap: var(--space-5);
71
95
  }
72
96
 
73
97
  .row {
74
98
  display: flex;
99
+ align-items: center;
100
+ gap: var(--space-5);
101
+ }
102
+
103
+ @media (max-width: 1023.99px) {
104
+ .gallery {
105
+ margin-right: calc(-1 * var(--gutter));
106
+ margin-left: calc(-1 * var(--gutter));
107
+ width: calc(100% + (var(--gutter) * 2));
108
+
109
+ .small-carousel {
110
+ padding-right: var(--gutter);
111
+ padding-left: var(--gutter);
112
+ }
113
+ }
75
114
  }
76
115
  }
77
116
  </style>
@@ -1,95 +1,138 @@
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 Omit<ComponentProps<typeof Card>, 'position'> {
8
- label?: string | undefined
9
- icon?: string | undefined
10
- position?: 'left' | 'right' | undefined
11
- panel?: boolean | undefined
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
- position = 'left',
17
- panel,
18
- label,
19
- icon,
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
- id={`${id}-button`}
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
- {position}
38
- onclick={`event.target === this && this.close()`}
50
+ {text}
51
+ {icon}
52
+ {...rest}
39
53
  >
40
- <Element
41
- class:list={[panel, `position-${position}`]}
42
- {...rest}
43
- >
44
- <slot />
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>
45
78
  </Element>
46
79
  </Element>
47
80
 
48
81
  <style lang="scss" is:global>
49
82
  @layer fulldev {
83
+ body:has(dialog[open]) {
84
+ overflow: hidden;
85
+
86
+ @media (min-width: 768px) {
87
+ overflow: auto;
88
+ }
89
+ }
90
+
50
91
  .drawer {
51
- flex-shrink: 0;
52
- align-items: stretch;
53
- box-sizing: border-box;
54
- margin: 0 !important;
55
- outline: 0;
56
- border: 0;
57
- background: var(--color-2);
92
+ top: 0;
93
+ bottom: 0;
94
+ margin: 0;
58
95
  padding: 0;
59
- padding: var(--space-7) var(--space-7) var(--space-7) var(--gutter);
60
- min-width: 260px;
61
- max-width: 360px;
62
- height: 100vh;
63
- max-height: 100vh;
96
+ width: 100%;
97
+ max-width: 100%;
98
+ height: 100%;
99
+ max-height: 100%;
64
100
 
65
- &::backdrop {
66
- background: rgba(0, 0, 0, 0.5);
101
+ @media (min-width: 768px) {
102
+ width: 360px;
67
103
  }
68
104
 
69
- &.position-left {
70
- margin-right: 0;
105
+ &::backdrop {
106
+ cursor: pointer;
107
+ background: rgba(0, 0, 0, 0.5);
71
108
  }
72
109
 
73
- &.position-right {
74
- right: 0;
110
+ .drawer-body {
111
+ flex-shrink: 1;
112
+ border-right: 1px solid var(--color-a6);
113
+ height: 100%;
114
+ overflow: auto;
75
115
  }
76
116
 
77
- .box {
78
- padding: calc(var(--space-5) * 2) calc(var(--space-7) * 3);
79
- min-width: calc(var(--space-7) * 14);
80
- height: 100vh;
81
- overflow-x: hidden;
82
- overflow-y: auto;
117
+ .drawer-header {
118
+ display: flex;
119
+ position: sticky;
120
+ top: 0;
121
+ align-items: center;
122
+ border-bottom: 1px solid var(--color-a6);
123
+ background-color: var(--base-background);
124
+ padding: 0 var(--gutter);
125
+ height: 56px;
83
126
 
84
- &.position-left {
85
- border-right: 1px solid var(--color-a6);
86
- padding-left: var(--gutter);
127
+ .button {
128
+ margin-left: auto;
87
129
  }
130
+ }
88
131
 
89
- &.position-right {
90
- border-left: 1px solid var(--color-a6);
91
- padding-right: var(--gutter);
92
- }
132
+ .drawer-content {
133
+ display: flex;
134
+ flex-direction: column;
135
+ padding: var(--space-6) var(--gutter);
93
136
  }
94
137
  }
95
138
  }
@@ -132,6 +132,10 @@ const {
132
132
  flex-direction: column;
133
133
  }
134
134
 
135
+ > .column {
136
+ gap: var(--space-4);
137
+ }
138
+
135
139
  .socials {
136
140
  display: flex;
137
141
  }
@@ -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
6
  import Search from 'fulldev-ui/components/Search.astro'
8
7
  import ThemeSelect from 'fulldev-ui/components/ThemeSelect.astro'
9
8
  import type { GlobalProps } from 'fulldev-ui/types/global-props'
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>['src']
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
  ---
@@ -49,11 +54,19 @@ const {
49
54
  />
50
55
  {search && <Search />}
51
56
  {themeselect && <ThemeSelect />}
52
- <Button
53
- class="menu-button"
54
- variant="tertiary"
57
+ <Drawer
55
58
  icon="menu-2"
56
- for="sidebar"
59
+ id="menu"
60
+ {menu}
61
+ {logo}
62
+ {company}
63
+ />
64
+ <Drawer
65
+ icon="shopping-cart"
66
+ class="cart-button"
67
+ color="brand"
68
+ id="cart"
69
+ heading={cart}
57
70
  />
58
71
  </Element>
59
72
 
@@ -118,10 +131,6 @@ const {
118
131
  }
119
132
 
120
133
  .menu-button {
121
- .icon {
122
- transform: scale(1.56);
123
- }
124
-
125
134
  @media (min-width: 1024px) {
126
135
  display: none;
127
136
  }
@@ -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>
@@ -148,7 +148,9 @@ const Component =
148
148
  --inset-right: var(--gutter);
149
149
  --inset-bottom: var(--spacer);
150
150
 
151
+ display: flex;
151
152
  position: relative;
153
+ flex-direction: column;
152
154
  align-items: flex-start;
153
155
  gap: var(--space-6) var(--space-7);
154
156
  padding: var(--spacer) var(--gutter);
@@ -1,151 +1,101 @@
1
1
  ---
2
- import type { HTMLAttributes } from 'astro/types'
3
- import Button from 'fulldev-ui/components/Button.astro'
2
+ import type { ComponentProps, HTMLAttributes } from 'astro/types'
4
3
  import Element from 'fulldev-ui/components/Element.astro'
5
4
  import Logo from 'fulldev-ui/components/experimental/Logo.astro'
6
- import Heading from 'fulldev-ui/components/Heading.astro'
7
- import Search from 'fulldev-ui/components/Search.astro'
5
+ import Menu from 'fulldev-ui/components/Menu.astro'
8
6
  import ThemeSelect from 'fulldev-ui/components/ThemeSelect.astro'
9
7
  import type { GlobalProps } from 'fulldev-ui/types/global-props'
8
+ import Heading from './Heading.astro'
9
+ import Toc from './Toc.astro'
10
10
 
11
11
  interface Props extends GlobalProps, HTMLAttributes<'aside'> {
12
- size?: 'sm' | 'md' | 'lg' | undefined
13
- search?: boolean | undefined
14
- logo?: string | undefined
15
- company?: string | undefined
16
- buttons?: any[] | undefined
17
- open?: boolean | undefined
12
+ menu?: ComponentProps<typeof Menu>['groups']
13
+ heading?: ComponentProps<typeof Heading>['text']
14
+ render?: ComponentProps<typeof Toc>['render']
15
+ logo?: ComponentProps<typeof Logo>
16
+ toc?: ComponentProps<typeof Toc>['heading']
17
+ company?: ComponentProps<typeof Logo>['company']
18
+ themeselect?: boolean | undefined
18
19
  }
19
20
 
20
21
  const {
21
22
  size = 'sm',
22
- open = false,
23
23
  logo,
24
24
  company,
25
- buttons,
26
- search,
25
+ render,
26
+ themeselect,
27
+ menu,
28
+ toc,
29
+ heading,
30
+ ...rest
27
31
  } = Astro.props
28
32
  ---
29
33
 
30
- <input
31
- id="sidebar"
32
- class="sidebar-checkbox"
33
- type="checkbox"
34
- />
35
-
36
34
  <Element
37
35
  class:list="sidebar"
38
36
  as="aside"
39
37
  {size}
40
- {open}
38
+ {...rest}
41
39
  >
42
- <Logo
43
- {company}
44
- {...typeof logo === 'string' ? { src: logo } : logo}
45
- />
46
- {search && <Search />}
47
- <Element class:list="buttons">
48
- {
49
- buttons?.map(({ heading, slug, href, text, buttons }) => (
50
- <>
51
- <Heading
52
- level={6}
53
- text={heading}
54
- />
55
- <Button
56
- variant="link"
57
- {slug}
58
- {href}
59
- {text}
60
- />
61
- {buttons?.map((button: any) => (
62
- <Button
63
- variant="link"
64
- {...button}
65
- />
66
- ))}
67
- </>
68
- ))
69
- }
70
- <ThemeSelect />
40
+ <Element
41
+ class:list="sidebar-header"
42
+ as="header"
43
+ >
44
+ <Logo
45
+ {company}
46
+ {...logo}
47
+ />
48
+ <Heading
49
+ level={4}
50
+ text={heading}
51
+ />
52
+ <slot name="header" />
53
+ </Element>
54
+ <Element class:list="sidebar-content">
55
+ <Menu groups={menu} />
56
+ <ThemeSelect if={themeselect} />
57
+ <slot />
71
58
  </Element>
72
59
  </Element>
73
60
 
74
61
  <style lang="scss" is:global>
75
62
  @layer fulldev {
76
- .sidebar-checkbox {
77
- display: none;
78
- }
79
-
80
- @media (max-width: 1023.999px) {
81
- body:has(.sidebar-checkbox:checked) {
82
- overflow: hidden;
83
- }
84
- }
85
-
86
63
  .sidebar {
87
- --sidebar-width: 240px;
88
-
89
64
  display: none;
90
- position: fixed;
91
- top: var(--header-height, 0px);
92
- bottom: 0;
93
- left: 0;
94
- flex-shrink: 0;
95
- flex-direction: column;
96
- justify-content: flex-start;
97
- z-index: 10;
98
- border-style: solid;
99
- border-color: var(--color-a6);
100
- background-color: var(--base-2);
101
- padding: var(--space-md-5) var(--gutter);
102
- width: 100%;
103
- height: calc(100vh - var(--header-height, 0px));
104
- overflow-y: auto;
105
-
106
- &:is(.sidebar-checkbox:checked + &) {
107
- display: flex;
108
- }
109
65
 
110
66
  @media (min-width: 1024px) {
111
- border-right-width: 1px;
112
- padding: var(--space-md-6) var(--gutter);
113
- width: var(--sidebar-width);
114
-
115
- &.open {
116
- display: flex;
117
- position: sticky;
118
- }
119
- }
120
-
121
- .buttons {
122
67
  display: flex;
68
+ position: sticky;
69
+ top: var(--header-height, 0px);
70
+ bottom: 0;
71
+ flex-shrink: 0;
123
72
  flex-direction: column;
124
- gap: calc(var(--space-4) + var(--space-1));
73
+ justify-content: flex-start;
74
+ z-index: 10;
75
+ border-right: 1px solid var(--color-a6);
76
+ width: calc(var(--space-7) * 4);
77
+ height: calc(100vh - var(--header-height, 0px));
125
78
 
126
- .theme-select {
127
- margin-top: var(--space-5);
79
+ .sidebar-header {
80
+ display: flex;
81
+ position: sticky;
82
+ align-items: center;
83
+ border-bottom: 1px solid var(--color-a6);
84
+ padding: 0 var(--gutter);
85
+ width: 100%;
86
+ height: 56px;
128
87
  }
129
88
 
130
- .button + .heading {
131
- margin-top: var(--space-5);
89
+ .sidebar-content {
90
+ display: flex;
91
+ top: 0;
92
+ flex: 1;
93
+ flex-direction: column;
94
+ padding: var(--space-6) var(--gutter);
95
+ width: 100%;
96
+ overflow-y: auto;
132
97
  }
133
98
  }
134
-
135
- .logo {
136
- display: none;
137
- position: absolute;
138
- top: 0;
139
- left: var(--gutter);
140
- align-items: center;
141
- height: 56px;
142
- }
143
- }
144
-
145
- @media (min-width: 1024px) {
146
- .header:not(.open) ~ .core .sidebar .logo {
147
- display: flex;
148
- }
149
99
  }
150
100
  }
151
101
  </style>
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  import Select from 'fulldev-ui/components/Select.astro'
3
3
  // const defaultTheme = fulldevConfig.colors.theme || 'light'
4
+
5
+ const { ...rest } = Astro.props
4
6
  ---
5
7
 
6
8
  <Select
@@ -9,6 +11,7 @@ import Select from 'fulldev-ui/components/Select.astro'
9
11
  options={['light', 'dark']}
10
12
  value="light"
11
13
  onchange="localStorage.setItem('theme', this.value); window.location.reload();"
14
+ {...rest}
12
15
  />
13
16
 
14
17
  <script>