fulldev-ui 0.5.0-beta.9 → 0.6.0-beta.0

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 (236) hide show
  1. package/.env.example +3 -0
  2. package/.prettierrc.yaml +1 -0
  3. package/astro.config.ts +6 -32
  4. package/package.json +21 -30
  5. package/pnpm-lock.yaml +696 -2176
  6. package/public/favicon/android-chrome-192x192.png +0 -0
  7. package/public/favicon/android-chrome-512x512.png +0 -0
  8. package/public/favicon/apple-touch-icon.png +0 -0
  9. package/public/favicon/manifest.webmanifest +7 -3
  10. package/public/favicon/mstile-150x150.png +0 -0
  11. package/src/blocks/Banner.astro +6 -19
  12. package/src/blocks/Colleagues.astro +0 -1
  13. package/src/blocks/Contact.astro +75 -74
  14. package/src/blocks/Content.astro +124 -6
  15. package/src/blocks/Cta.astro +0 -2
  16. package/src/blocks/Excerpt.astro +0 -2
  17. package/src/blocks/Footer.astro +107 -3
  18. package/src/blocks/Hero.astro +238 -9
  19. package/src/blocks/Intro.astro +89 -11
  20. package/src/blocks/Prices.astro +1 -1
  21. package/src/blocks/Product.astro +49 -70
  22. package/src/blocks/Products.astro +114 -5
  23. package/src/blocks/Reviews.astro +0 -1
  24. package/src/blocks/_Contact.astro +112 -0
  25. package/src/components/Avatar.astro +28 -9
  26. package/src/components/Avatars.astro +36 -0
  27. package/src/components/Badge.astro +73 -26
  28. package/src/components/Badges.astro +16 -23
  29. package/src/components/Breadcrumb.astro +58 -0
  30. package/src/components/Button.astro +56 -112
  31. package/src/components/Buttons.astro +23 -13
  32. package/src/components/Card.astro +129 -115
  33. package/src/components/Cards.astro +33 -35
  34. package/src/components/Carousel.astro +106 -0
  35. package/src/components/Cart.astro +1 -1
  36. package/src/components/CartForm.astro +10 -10
  37. package/src/components/CartList.astro +11 -28
  38. package/src/components/CartSummary.astro +11 -14
  39. package/src/components/Channel.astro +40 -22
  40. package/src/components/Channels.astro +20 -6
  41. package/src/components/Checkbox.astro +52 -27
  42. package/src/components/Code.astro +52 -0
  43. package/src/components/Dialog.astro +2 -2
  44. package/src/components/Drawer.astro +34 -64
  45. package/src/components/Element.astro +16 -8
  46. package/src/components/Form.astro +14 -13
  47. package/src/components/Gallery.astro +172 -0
  48. package/src/components/Head.astro +52 -1
  49. package/src/components/Header.astro +73 -83
  50. package/src/components/Heading.astro +74 -30
  51. package/src/components/Icon.astro +25 -30
  52. package/src/components/Image.astro +23 -38
  53. package/src/components/Input.astro +59 -53
  54. package/src/components/Label.astro +20 -15
  55. package/src/components/Lead.astro +46 -0
  56. package/src/components/Link.astro +51 -26
  57. package/src/components/Links.astro +42 -0
  58. package/src/components/List.astro +41 -16
  59. package/src/components/LocaleSwitcher.astro +2 -2
  60. package/src/components/Logo.astro +45 -0
  61. package/src/components/Menu.astro +21 -17
  62. package/src/components/Paragraph.astro +38 -0
  63. package/src/components/Price.astro +1 -1
  64. package/src/components/Prose.astro +169 -0
  65. package/src/components/Rating.astro +50 -38
  66. package/src/components/Search.astro +1 -1
  67. package/src/components/Section.astro +196 -158
  68. package/src/components/Select.astro +44 -55
  69. package/src/components/Sidebar.astro +31 -38
  70. package/src/components/Social.astro +3 -8
  71. package/src/components/Socials.astro +9 -5
  72. package/src/components/Subheader.astro +59 -0
  73. package/src/components/Switch.astro +72 -29
  74. package/src/components/Table.astro +1 -1
  75. package/src/components/Tagline.astro +40 -12
  76. package/src/components/Text.astro +4 -4
  77. package/src/components/Textarea.astro +40 -50
  78. package/src/components/Themer.astro +76 -0
  79. package/src/components/Toc.astro +24 -32
  80. package/src/components/Writeup.astro +26 -8
  81. package/src/components/docs/PropsTable.astro +38 -264
  82. package/src/components/experimental/Window.astro +5 -57
  83. package/src/components/sections.astro +1 -1
  84. package/src/content/pages/blocks/_categories.mdx +1 -1
  85. package/src/content/pages/blocks/_footer.mdx +1 -1
  86. package/src/content/pages/blocks/_header.mdx +1 -3
  87. package/src/content/pages/blocks/_jobs.mdx +1 -1
  88. package/src/content/pages/blocks/_prices.mdx +1 -1
  89. package/src/content/pages/blocks/_product.mdx +1 -1
  90. package/src/content/pages/blocks/_products.mdx +1 -1
  91. package/src/content/pages/blocks/_stats.mdx +1 -1
  92. package/src/content/pages/blocks/banner.mdx +1 -1
  93. package/src/content/pages/blocks/colleagues.mdx +1 -2
  94. package/src/content/pages/blocks/contact.mdx +1 -1
  95. package/src/content/pages/blocks/content.mdx +1 -5
  96. package/src/content/pages/blocks/cta.mdx +1 -9
  97. package/src/content/pages/blocks/features.mdx +1 -4
  98. package/src/content/pages/blocks/hero.mdx +1 -4
  99. package/src/content/pages/blocks/intro.mdx +1 -4
  100. package/src/content/pages/blocks/posts.mdx +1 -1
  101. package/src/content/pages/blocks/reviews.mdx +1 -2
  102. package/src/content/pages/docs/_internationalization.mdx +55 -0
  103. package/src/content/pages/docs/_using-blocks.mdx +33 -0
  104. package/src/content/pages/docs/_using-presets.mdx +49 -0
  105. package/src/content/pages/docs/blocks.mdx +33 -0
  106. package/src/content/pages/docs/collections/images.mdx +100 -0
  107. package/src/content/pages/docs/collections/pages.mdx +119 -0
  108. package/src/content/pages/docs/collections/presets.mdx +60 -0
  109. package/src/content/pages/docs/collections.mdx +42 -0
  110. package/src/content/pages/{base/card.mdx → docs/components/_card.mdx} +1 -3
  111. package/src/content/pages/{base → docs/components}/_switch.mdx +2 -2
  112. package/src/content/pages/{typography → docs/components}/_tagline.mdx +2 -2
  113. package/src/content/pages/docs/components/_toggle.mdx +31 -0
  114. package/src/content/pages/docs/components/avatar.mdx +35 -0
  115. package/src/content/pages/{base → docs/components}/badge.mdx +27 -8
  116. package/src/content/pages/docs/components/badges.mdx +47 -0
  117. package/src/content/pages/{base → docs/components}/button.mdx +29 -10
  118. package/src/content/pages/docs/components/buttons.mdx +52 -0
  119. package/src/content/pages/docs/components/channel.mdx +92 -0
  120. package/src/content/pages/docs/components/channels.mdx +90 -0
  121. package/src/content/pages/{base → docs/components}/checkbox.mdx +10 -17
  122. package/src/content/pages/docs/components/code.mdx +46 -0
  123. package/src/content/pages/docs/components/heading.mdx +60 -0
  124. package/src/content/pages/docs/components/icon.mdx +49 -0
  125. package/src/content/pages/docs/components/image.mdx +26 -0
  126. package/src/content/pages/docs/components/input.mdx +41 -0
  127. package/src/content/pages/{typography → docs/components}/label.mdx +8 -4
  128. package/src/content/pages/docs/components/lead.mdx +51 -0
  129. package/src/content/pages/{typography → docs/components}/link.mdx +23 -8
  130. package/src/content/pages/docs/components/links.mdx +100 -0
  131. package/src/content/pages/docs/components/list.mdx +45 -0
  132. package/src/content/pages/docs/components/logo.mdx +37 -0
  133. package/src/content/pages/docs/components/menu.mdx +90 -0
  134. package/src/content/pages/docs/components/paragraph.mdx +51 -0
  135. package/src/content/pages/docs/components/prose.mdx +37 -0
  136. package/src/content/pages/docs/components/rating.mdx +77 -0
  137. package/src/content/pages/{base → docs/components}/section.mdx +1 -1
  138. package/src/content/pages/{base → docs/components}/select.mdx +0 -9
  139. package/src/content/pages/docs/components/social.mdx +95 -0
  140. package/src/content/pages/docs/components/socials.mdx +103 -0
  141. package/src/content/pages/docs/components/switch.mdx +35 -0
  142. package/src/content/pages/{base → docs/components}/table.mdx +0 -2
  143. package/src/content/pages/docs/components/tagline.mdx +47 -0
  144. package/src/content/pages/docs/components/textarea.mdx +35 -0
  145. package/src/content/pages/docs/components/themer.mdx +50 -0
  146. package/src/content/pages/docs/components.mdx +40 -0
  147. package/src/content/pages/docs/customization.mdx +151 -0
  148. package/src/content/pages/docs/frameworks.mdx +29 -0
  149. package/src/content/pages/docs/generating-pages.mdx +129 -0
  150. package/src/content/pages/docs/index.mdx +23 -0
  151. package/src/content/pages/docs/installation.mdx +50 -0
  152. package/src/content/pages/docs/layouts.mdx +33 -0
  153. package/src/content/pages/index.mdx +11 -9
  154. package/src/content/pages/showcase.mdx +4 -2
  155. package/src/content/presets/base.yml +80 -63
  156. package/src/content/presets/docs.yml +2 -2
  157. package/src/css/color.css +0 -10
  158. package/src/css/custom.css +10 -12
  159. package/src/css/size.css +2 -11
  160. package/src/css/theme.css +93 -0
  161. package/src/images/logo-1.svg +11 -0
  162. package/src/images/logo-2.svg +13 -0
  163. package/src/images/logo-basic.svg +10 -0
  164. package/src/images/logo-simple.svg +13 -0
  165. package/src/images/logo-thin.svg +15 -0
  166. package/src/images/logo.svg +14 -0
  167. package/src/images/logofat.svg +11 -0
  168. package/src/integration/index.ts +71 -144
  169. package/src/layouts/CategoryLayout.astro +135 -0
  170. package/src/layouts/Layout.astro +62 -117
  171. package/src/layouts/PageLayout.astro +26 -0
  172. package/src/layouts/PostLayout.astro +13 -8
  173. package/src/layouts/ProductLayout.astro +94 -10
  174. package/src/pages/[...page].astro +14 -22
  175. package/src/pages/test.astro +20 -0
  176. package/src/schemas/components/button.ts +21 -13
  177. package/src/schemas/components/card.ts +36 -18
  178. package/src/schemas/components/footer.ts +2 -10
  179. package/src/schemas/components/global.ts +16 -0
  180. package/src/schemas/components/header.ts +8 -0
  181. package/src/schemas/components/image.ts +8 -3
  182. package/src/schemas/components/link.ts +16 -0
  183. package/src/schemas/components/links.ts +4 -0
  184. package/src/schemas/components/menu.ts +2 -0
  185. package/src/schemas/components/sidebar.ts +2 -2
  186. package/src/schemas/components/subheader.ts +9 -0
  187. package/src/schemas/components/themer.ts +3 -0
  188. package/src/schemas/pageSchema.ts +14 -21
  189. package/src/utils/cart.ts +1 -10
  190. package/src/utils/getDeepReferenceChildren.ts +14 -0
  191. package/src/utils/getReferenceChildren.ts +1 -1
  192. package/src/utils/setTheme.ts +18 -0
  193. package/src/utils/slugify.ts +6 -0
  194. package/tailwind.config.ts +67 -0
  195. package/src/blocks/Article.astro +0 -40
  196. package/src/components/Footer.astro +0 -193
  197. package/src/components/ThemeSelect.astro +0 -41
  198. package/src/components/experimental/Form.astro +0 -53
  199. package/src/components/experimental/Gallery.astro +0 -104
  200. package/src/components/experimental/Logo.astro +0 -38
  201. package/src/components/experimental/Prose.astro +0 -192
  202. package/src/content/pages/base/icon.mdx +0 -55
  203. package/src/content/pages/base/image.mdx +0 -42
  204. package/src/content/pages/base/input.mdx +0 -56
  205. package/src/content/pages/base/rating.mdx +0 -55
  206. package/src/content/pages/base/textarea.mdx +0 -58
  207. package/src/content/pages/base/theme-select.mdx +0 -15
  208. package/src/content/pages/layouts/_layout.mdx +0 -14
  209. package/src/content/pages/layouts/docslayout.mdx +0 -14
  210. package/src/content/pages/overview/components.mdx +0 -75
  211. package/src/content/pages/overview/content-collections.mdx +0 -139
  212. package/src/content/pages/overview/frameworks.mdx +0 -198
  213. package/src/content/pages/overview/installation.mdx +0 -53
  214. package/src/content/pages/overview/introduction.mdx +0 -30
  215. package/src/content/pages/overview/theming.mdx +0 -69
  216. package/src/content/pages/schemas/page.mdx +0 -17
  217. package/src/content/pages/schemas/preset.mdx +0 -9
  218. package/src/content/pages/showcase/record.md +0 -3
  219. package/src/content/pages/typography/heading.mdx +0 -73
  220. package/src/content/pages/typography/list.mdx +0 -51
  221. package/src/content/pages/typography/text.mdx +0 -61
  222. package/src/content/presets/blocks.yml +0 -1
  223. package/src/css/space.css +0 -77
  224. package/src/css/styles.css +0 -0
  225. package/src/images/avatar-1.yml +0 -1
  226. package/src/integration/generate-colors.ts +0 -639
  227. package/src/integration/tailwind-plugin.ts +0 -80
  228. package/src/integration/unocss-preset.ts +0 -84
  229. package/src/layouts/BlockLayout.astro +0 -19
  230. package/src/layouts/ContactLayout.astro +0 -21
  231. package/src/layouts/DocsLayout.astro +0 -73
  232. package/src/layouts/OverviewLayout.astro +0 -42
  233. /package/src/content/pages/{base → docs/components}/_dialog.mdx +0 -0
  234. /package/src/content/pages/{base → docs/components}/_drawer.mdx +0 -0
  235. /package/src/content/pages/{base → docs/components}/_localeswitcher.mdx +0 -0
  236. /package/src/schemas/utils/{parents.ts → categories.ts} +0 -0
@@ -0,0 +1,112 @@
1
+ ---
2
+ import Button from 'fulldev-ui/components/Button.astro'
3
+ import Buttons from 'fulldev-ui/components/Buttons.astro'
4
+ import Channels from 'fulldev-ui/components/Channels.astro'
5
+ import Element from 'fulldev-ui/components/Element.astro'
6
+ import Form from 'fulldev-ui/components/Form.astro'
7
+ import Heading from 'fulldev-ui/components/Heading.astro'
8
+ import Image from 'fulldev-ui/components/Image.astro'
9
+ import Input from 'fulldev-ui/components/Input.astro'
10
+ import Section from 'fulldev-ui/components/Section.astro'
11
+ import Socials from 'fulldev-ui/components/Socials.astro'
12
+ import Tagline from 'fulldev-ui/components/Tagline.astro'
13
+ import Text from 'fulldev-ui/components/Text.astro'
14
+ import Textarea from 'fulldev-ui/components/Textarea.astro'
15
+
16
+ const {
17
+ heading,
18
+ form,
19
+ text,
20
+ tagline,
21
+ googleMaps,
22
+ buttons,
23
+ socials,
24
+ position,
25
+ image,
26
+ channels,
27
+ level = 1,
28
+ ...rest
29
+ } = Astro.props
30
+ ---
31
+
32
+ <Section
33
+ class:list="contact"
34
+ structure="split"
35
+ {...rest}
36
+ >
37
+ <Element class:list="column">
38
+ <Tagline text={tagline} />
39
+ <Heading
40
+ size={'sm'}
41
+ level={level}
42
+ text={heading}
43
+ />
44
+ <Text text={text} />
45
+ <Buttons {buttons} />
46
+ <Channels {channels} />
47
+ <Socials {socials} />
48
+ <Form
49
+ action="/thank-you"
50
+ method="POST"
51
+ >
52
+ {
53
+ form.fields.map((field: any) => {
54
+ if (field.type === 'textarea') {
55
+ return (
56
+ <Textarea
57
+ label={field.label}
58
+ id={field.name}
59
+ name={field.name}
60
+ required={field.required}
61
+ />
62
+ )
63
+ }
64
+ return (
65
+ <Input
66
+ label={field.label}
67
+ id={field.name}
68
+ name={field.name}
69
+ type={field.type}
70
+ required={field.required}
71
+ />
72
+ )
73
+ })
74
+ }
75
+ <Button
76
+ type="submit"
77
+ variant="primary"
78
+ text={form.button}
79
+ />
80
+ </Form>
81
+ </Element>
82
+
83
+ <Image
84
+ {position}
85
+ {...image}
86
+ />
87
+ </Section>
88
+
89
+ <style is:global>
90
+ @layer fulldev {
91
+ .oldcontact {
92
+ .column {
93
+ display: flex;
94
+ flex-direction: column;
95
+ align-items: flex-start;
96
+ }
97
+
98
+ > .column {
99
+ gap: var(--space-5);
100
+ }
101
+
102
+ .channel + .channel {
103
+ margin-top: var(--space-3) !important;
104
+ }
105
+
106
+ .socials {
107
+ display: flex;
108
+ gap: var(--space-2);
109
+ }
110
+ }
111
+ }
112
+ </style>
@@ -1,26 +1,45 @@
1
1
  ---
2
2
  import type { ComponentProps } from 'astro/types'
3
3
  import Image from 'fulldev-ui/components/Image.astro'
4
+ import type { GlobalProps } from 'fulldev-ui/types/global-props'
4
5
 
5
- interface Props extends ComponentProps<typeof Image> {}
6
+ interface Props extends GlobalProps, ComponentProps<typeof Image> {
7
+ size?: 'sm' | 'md' | 'lg' | undefined
8
+ }
6
9
 
7
- const { ...rest } = Astro.props
10
+ const { size = 'md', ...rest } = Astro.props
11
+
12
+ const sizeMap = {
13
+ sm: 36,
14
+ md: 40,
15
+ lg: 44,
16
+ }
8
17
  ---
9
18
 
10
19
  <Image
11
20
  class:list={'avatar'}
21
+ width={sizeMap[size]}
22
+ height={sizeMap[size]}
23
+ {size}
12
24
  {...rest}
13
25
  />
14
26
 
15
- <style is:global lang="scss">
27
+ <style is:global>
16
28
  @layer fulldev {
17
29
  .avatar {
18
- display: block;
19
- border: 1px solid var(--base-a6);
20
- border-radius: 999px;
21
- width: calc(2.8 * var(--space-4));
22
- height: calc(2.8 * var(--space-4));
23
- object-fit: cover;
30
+ @apply aspect-square shrink-0 rounded-full bg-muted object-cover;
31
+
32
+ &.size-sm {
33
+ @apply size-9;
34
+ }
35
+
36
+ &.size-md {
37
+ @apply size-10;
38
+ }
39
+
40
+ &.size-lg {
41
+ @apply size-11;
42
+ }
24
43
  }
25
44
  }
26
45
  </style>
@@ -0,0 +1,36 @@
1
+ ---
2
+ import type { ComponentProps, HTMLAttributes } from 'astro/types'
3
+ import Element from 'fulldev-ui/components/Element.astro'
4
+ import Avatar from './Avatar.astro'
5
+
6
+ interface Props extends HTMLAttributes<'div'> {
7
+ size?: any
8
+ avatars?: ComponentProps<typeof Avatar>[] | undefined
9
+ avatar?: ComponentProps<typeof Avatar>['id'] | undefined
10
+ }
11
+
12
+ const { size = 'md', avatars = [], avatar, ...rest } = Astro.props
13
+ ---
14
+
15
+ <Element
16
+ class:list="avatars"
17
+ {size}
18
+ {...rest}
19
+ >
20
+ {
21
+ [avatar, ...avatars].filter(Boolean).map((id) => (
22
+ <Avatar
23
+ {size}
24
+ {id}
25
+ />
26
+ ))
27
+ }
28
+ </Element>
29
+
30
+ <style is:global>
31
+ @layer fulldev {
32
+ .avatars {
33
+ @apply inline-flex -space-x-3;
34
+ }
35
+ }
36
+ </style>
@@ -1,45 +1,92 @@
1
1
  ---
2
- import type { ComponentProps } from 'astro/types'
2
+ import type { ComponentProps, HTMLAttributes, HTMLTag } from 'astro/types'
3
+ import type { CollectionEntry } from 'astro:content'
4
+ import { getEntry } from 'astro:content'
5
+ import Element from 'fulldev-ui/components/Element.astro'
3
6
  import Icon from 'fulldev-ui/components/Icon.astro'
4
- import Button from './Button.astro'
7
+ import type { GlobalProps } from 'fulldev-ui/types/global-props'
5
8
 
6
- interface Props extends ComponentProps<typeof Button> {}
9
+ interface Props
10
+ extends GlobalProps,
11
+ HTMLAttributes<'div'>,
12
+ HTMLAttributes<'a'> {
13
+ as?: HTMLTag
14
+ href?: string | null | undefined
15
+ icon?: ComponentProps<typeof Icon>['name']
16
+ slug?: CollectionEntry<'pages'>['slug'] | undefined
17
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | undefined
18
+ text?: string | undefined
19
+ }
7
20
 
8
21
  const {
9
- variant = 'tertiary',
10
- color = 'base',
11
- href,
12
- text,
22
+ slug,
23
+ href = slug === 'index' ? '/' : slug ? `/${slug}/` : undefined,
24
+ text = slug ? (await getEntry('pages', slug)).data.title : undefined,
25
+ as = href ? 'a' : 'div',
26
+ target = href?.startsWith('http') ? '_blank' : undefined,
27
+ variant = 'outline',
28
+ size = 'md',
13
29
  icon,
14
30
  ...rest
15
31
  } = Astro.props
16
32
  ---
17
33
 
18
- <Button
34
+ <Element
19
35
  class:list="badge"
20
- {variant}
36
+ {as}
21
37
  {href}
22
- {color}
38
+ {target}
39
+ {variant}
40
+ {size}
23
41
  {...rest}
24
42
  >
25
- <slot />
26
- <Fragment set:html={text} />
27
- <Icon name={icon} />
28
- </Button>
43
+ <Icon
44
+ size="sm"
45
+ name={icon}
46
+ />
47
+ <Element as="span">
48
+ <Fragment set:html={text} />
49
+ <slot />
50
+ </Element>
51
+ </Element>
29
52
 
30
- <style is:global lang="scss">
53
+ <style is:global>
31
54
  @layer fulldev {
32
- .button.badge {
33
- gap: var(--space-2);
34
- transition: all 0.15s ease;
35
- border: 1px solid var(--color-a7);
36
- border-radius: 999px;
37
- padding: 0 var(--space-3);
38
- height: calc(var(--text-1) + 2 * var(--space-2));
39
- font-size: var(--text-1);
40
-
41
- &:hover {
42
- border-color: var(--color-a8);
55
+ .badge {
56
+ @apply inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-full text-sm font-medium leading-none ring-offset-background transition-colors;
57
+ @apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2;
58
+ @apply disabled:pointer-events-none disabled:opacity-50;
59
+
60
+ &.size-sm {
61
+ @apply h-6 min-w-6 px-2;
62
+ }
63
+
64
+ &.size-md {
65
+ @apply h-7 min-w-7 px-3;
66
+ }
67
+
68
+ &.size-lg {
69
+ @apply h-8 min-w-8 px-3.5;
70
+ }
71
+
72
+ &.variant-primary {
73
+ @apply bg-primary text-primary-foreground hover:bg-primary-hover;
74
+ }
75
+
76
+ &.variant-secondary {
77
+ @apply bg-secondary text-secondary-foreground hover:bg-secondary-hover;
78
+ }
79
+
80
+ &.variant-outline {
81
+ @apply border border-input text-accent-foreground hover:bg-accent;
82
+ }
83
+
84
+ .icon {
85
+ @apply first:last:absolute;
86
+ }
87
+
88
+ span {
89
+ @apply text-inherit;
43
90
  }
44
91
  }
45
92
  }
@@ -1,26 +1,22 @@
1
1
  ---
2
2
  import type { ComponentProps, HTMLAttributes } from 'astro/types'
3
- import Button from 'fulldev-ui/components/Button.astro'
4
3
  import Element from 'fulldev-ui/components/Element.astro'
5
- import type { GlobalProps } from 'fulldev-ui/types/global-props'
6
4
  import Badge from './Badge.astro'
7
5
 
8
- interface Props extends GlobalProps, HTMLAttributes<'div'> {
9
- variant?: ComponentProps<typeof Button>['variant']
6
+ interface Props extends HTMLAttributes<'div'> {
7
+ variant?: ComponentProps<typeof Badge>['variant']
8
+ size?: ComponentProps<typeof Badge>['size']
10
9
  badges?: ComponentProps<typeof Badge>[] | undefined
10
+ badge?: ComponentProps<typeof Badge> | undefined
11
11
  }
12
12
 
13
- const { variant = 'secondary', badges, ...rest } = Astro.props
14
-
15
- const buttonVariant = (i: number) => {
16
- if (variant === 'primary' && i === 0) return 'primary'
17
- else if (variant === 'primary' && i === 1) return 'secondary'
18
- else if (variant === 'primary' && i > 1) return 'tertiary'
19
- else if (variant === 'secondary' && i === 0) return 'secondary'
20
- else if (variant === 'secondary' && i > 0) return 'tertiary'
21
- else if (variant === 'tertiary') return 'tertiary'
22
- else return 'tertiary'
23
- }
13
+ const {
14
+ variant = 'outline',
15
+ size = 'md',
16
+ badges = [],
17
+ badge,
18
+ ...rest
19
+ } = Astro.props
24
20
  ---
25
21
 
26
22
  <Element
@@ -28,23 +24,20 @@ const buttonVariant = (i: number) => {
28
24
  {...rest}
29
25
  >
30
26
  {
31
- badges?.map((badge, i) => (
27
+ [badge, ...badges].filter(Boolean).map((badge) => (
32
28
  <Badge
33
- variant={variant === 'link' ? 'link' : buttonVariant(i)}
29
+ {variant}
30
+ {size}
34
31
  {...badge}
35
32
  />
36
33
  ))
37
34
  }
38
35
  </Element>
39
36
 
40
- <style is:global lang="scss">
37
+ <style is:global>
41
38
  @layer fulldev {
42
39
  .badges {
43
- display: inline-flex;
44
- flex-wrap: wrap;
45
- justify-content: stretch;
46
- gap: var(--space-2);
47
- width: auto;
40
+ @apply inline-flex w-auto flex-wrap justify-stretch gap-1.5;
48
41
  }
49
42
  }
50
43
  </style>
@@ -0,0 +1,58 @@
1
+ ---
2
+ import type { HTMLAttributes, HTMLTag } from 'astro/types'
3
+ import type { CollectionEntry } from 'astro:content'
4
+ import Element from 'fulldev-ui/components/Element.astro'
5
+ import Icon from 'fulldev-ui/components/Icon.astro'
6
+ import Link from 'fulldev-ui/components/Link.astro'
7
+
8
+ interface Props extends HTMLAttributes<'div'> {
9
+ as?: HTMLTag
10
+ slug?: CollectionEntry<'pages'>['slug'] | undefined
11
+ }
12
+
13
+ const { size = 'sm', slug, ...rest } = Astro.props
14
+ ---
15
+
16
+ <Element
17
+ class:list="breadcrumb"
18
+ {...rest}
19
+ >
20
+ <Link
21
+ as="a"
22
+ href="/"
23
+ icon="home"
24
+ {size}
25
+ />
26
+ {
27
+ slug?.split('/').map((part, i) => (
28
+ <>
29
+ <Icon
30
+ {size}
31
+ name="chevron-right"
32
+ />
33
+ <Link
34
+ {size}
35
+ variant="muted"
36
+ href={`/${slug
37
+ ?.split('/')
38
+ .slice(0, i + 1)
39
+ .join('/')}/`}
40
+ >
41
+ {part}
42
+ </Link>
43
+ </>
44
+ ))
45
+ }
46
+ </Element>
47
+
48
+ <style is:global>
49
+ @layer fulldev {
50
+ .breadcrumb {
51
+ @apply flex items-center gap-2;
52
+
53
+ .icon {
54
+ @apply text-muted-foreground;
55
+ }
56
+ }
57
+ }
58
+ </style>
@@ -1,8 +1,7 @@
1
1
  ---
2
- import type { ComponentProps, HTMLAttributes } from 'astro/types'
2
+ import type { ComponentProps, HTMLAttributes, HTMLTag } from 'astro/types'
3
3
  import type { CollectionEntry } from 'astro:content'
4
4
  import { getEntry } from 'astro:content'
5
- import Avatar from 'fulldev-ui/components/Avatar.astro'
6
5
  import Element from 'fulldev-ui/components/Element.astro'
7
6
  import Icon from 'fulldev-ui/components/Icon.astro'
8
7
  import type { GlobalProps } from 'fulldev-ui/types/global-props'
@@ -10,151 +9,96 @@ import type { GlobalProps } from 'fulldev-ui/types/global-props'
10
9
  interface Props
11
10
  extends GlobalProps,
12
11
  HTMLAttributes<'button'>,
13
- HTMLAttributes<'a'>,
14
- HTMLAttributes<'label'> {
12
+ HTMLAttributes<'a'> {
13
+ as?: HTMLTag
14
+ href?: string | null | undefined
15
15
  type?: HTMLAttributes<'button'>['type'] & HTMLAttributes<'a'>['type']
16
16
  icon?: ComponentProps<typeof Icon>['name']
17
- avatar?: ComponentProps<typeof Avatar>['src']
18
17
  slug?: CollectionEntry<'pages'>['slug'] | undefined
19
- variant?: 'primary' | 'secondary' | 'tertiary' | 'link' | undefined
20
- reverse?: boolean | undefined
18
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | undefined
21
19
  text?: string | undefined
20
+ reverse?: boolean | undefined
22
21
  }
23
22
 
24
- const { variant = 'secondary', slug, text, avatar, icon, ...rest } = Astro.props
25
-
26
- const entry = slug && !text ? await getEntry('pages', slug) : undefined
27
- const hrefString =
28
- rest.href && typeof rest.href !== 'string' ? rest.href.href : rest.href
29
- const href =
30
- hrefString ?? (slug ? (slug === 'index' ? '/' : `/${slug}/`) : undefined)
31
- const as = href ? 'a' : rest.for ? 'label' : 'button'
32
- const color =
33
- variant === 'link' && href === Astro.url.pathname ? 'brand' : rest.color
23
+ const {
24
+ slug,
25
+ href = slug === 'index' ? '/' : slug ? `/${slug}/` : undefined,
26
+ text = slug ? (await getEntry('pages', slug)).data.title : undefined,
27
+ as = href ? 'a' : 'button',
28
+ type = as === 'button' ? 'button' : undefined,
29
+ target = href?.startsWith('http') ? '_blank' : undefined,
30
+ variant = 'primary',
31
+ size = 'md',
32
+ icon,
33
+ reverse,
34
+ ...rest
35
+ } = Astro.props
34
36
  ---
35
37
 
36
38
  <Element
37
- class:list="button"
38
- _target={href?.startsWith('http') ? '_blank' : undefined}
39
- type={as === 'button' ? 'button' : undefined}
40
- {as}
39
+ class:list={['button']}
41
40
  {href}
42
- {color}
41
+ {as}
42
+ {type}
43
+ {target}
43
44
  {variant}
45
+ {size}
46
+ {reverse}
44
47
  {...rest}
45
48
  >
46
- <slot>
47
- <Avatar src={avatar} />
48
- <Icon name={icon} />
49
- <Fragment set:html={text ?? entry?.data.title} />
50
- </slot>
49
+ <Icon name={icon} />
50
+ <Element as="span">
51
+ <Fragment set:html={text} />
52
+ <slot />
53
+ </Element>
51
54
  </Element>
52
55
 
53
- <style is:global lang="scss">
56
+ <style is:global>
54
57
  @layer fulldev {
55
58
  .button {
56
- display: inline-flex;
57
- flex-shrink: 0;
58
- justify-content: center;
59
- align-items: center;
60
- vertical-align: top;
61
- gap: var(--space-2);
62
- appearance: none;
63
- transition: all 0.15s ease;
64
- cursor: pointer;
65
- outline: none;
66
- box-shadow: none;
67
- border-width: 0px;
68
- border-radius: var(--radius-1);
69
- padding: 0 var(--space-4);
70
- height: calc(var(--text-2) + 2 * var(--space-4));
71
- color: var(--text);
72
- font-weight: 500;
73
- font-size: var(--text-2);
74
- line-height: 1;
75
- text-align: center;
76
- text-decoration: none;
77
- white-space: nowrap;
78
-
79
- .avatar {
80
- margin-right: calc(-1 * (var(--space-4)));
81
- margin-left: var(--space-1);
82
- padding: calc(var(--space-1) / 3);
83
- width: calc(var(--text-2) + 2 * var(--space-4)) !important;
84
- height: calc(var(--text-2) + 2 * var(--space-4)) !important;
85
- }
59
+ @apply inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium leading-none ring-offset-background transition-colors;
60
+ @apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2;
61
+ @apply disabled:pointer-events-none disabled:opacity-50;
86
62
 
87
- &:focus-visible {
88
- outline: 2px solid var(--focus) !important;
89
- outline-offset: 2px;
63
+ &.size-sm {
64
+ @apply h-9 min-h-9 min-w-9 px-2;
90
65
  }
91
66
 
92
- &.reverse > * {
93
- order: 999;
67
+ &.size-md {
68
+ @apply h-10 min-h-10 min-w-10 px-4;
94
69
  }
95
70
 
96
- &:disabled {
97
- opacity: 0.5;
98
- cursor: not-allowed;
99
- pointer-events: none;
71
+ &.size-lg {
72
+ @apply h-11 min-h-11 min-w-11 px-5;
100
73
  }
101
74
 
102
75
  &.variant-primary {
103
- background-color: var(--color-9);
104
- color: var(--color-contrast);
105
-
106
- .icon {
107
- color: inherit;
108
- }
109
-
110
- &:hover,
111
- &:active {
112
- background-color: var(--color-10);
113
- }
76
+ @apply bg-primary text-primary-foreground hover:bg-primary-hover;
114
77
  }
115
78
 
116
79
  &.variant-secondary {
117
- border-style: solid;
118
- border-color: var(--color-7);
119
- background-color: var(--color-3);
120
- color: var(--color-11);
121
-
122
- &:hover {
123
- border-color: var(--color-8);
124
- background-color: var(--color-4);
125
- }
126
-
127
- &:active {
128
- border-color: var(--color-8);
129
- background-color: var(--color-5);
130
- }
80
+ @apply bg-secondary text-secondary-foreground hover:bg-secondary-hover;
131
81
  }
132
82
 
133
- &.variant-tertiary {
134
- color: var(--color-11);
135
-
136
- &:hover {
137
- background-color: var(--color-3);
138
- }
83
+ &.variant-outline {
84
+ @apply border border-input text-accent-foreground hover:bg-accent;
85
+ }
139
86
 
140
- &:active {
141
- background-color: var(--color-4);
142
- }
87
+ &.variant-ghost {
88
+ @apply text-accent-foreground hover:bg-accent;
143
89
  }
144
90
 
145
- &.variant-link {
146
- justify-content: flex-start;
147
- padding: 0;
148
- height: auto;
149
- color: var(--color-11);
150
- font-weight: 400;
91
+ .icon {
92
+ @apply first:last:absolute;
93
+ }
151
94
 
152
- &:hover {
153
- color: var(--color-12);
154
- }
95
+ span {
96
+ @apply text-inherit;
97
+ }
155
98
 
156
- &:active {
157
- color: var(--color-12);
99
+ &.reverse {
100
+ .icon {
101
+ @apply order-last;
158
102
  }
159
103
  }
160
104
  }