fulldev-ui 0.4.28 → 0.5.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 (313) hide show
  1. package/.astro/assets.mjs +1 -0
  2. package/.astro/astro/content.d.ts +547 -0
  3. package/.astro/collections/blocks.schema.json +851 -0
  4. package/.astro/collections/collections.json +63 -0
  5. package/.astro/collections/images.schema.json +22 -0
  6. package/.astro/collections/layouts.schema.json +826 -0
  7. package/.astro/collections/pages.schema.json +568 -0
  8. package/.astro/collections/presets.schema.json +489 -0
  9. package/.astro/collections/records.schema.json +822 -0
  10. package/.astro/collections/settings.schema.json +822 -0
  11. package/.astro/data-store.json +1 -0
  12. package/.astro/modules.mjs +1 -0
  13. package/.astro/settings.json +5 -0
  14. package/.astro/types.d.ts +2 -0
  15. package/CHANGELOG.md +2 -98
  16. package/CONTRIBUTING.md +2 -2
  17. package/astro.config.ts +20 -4
  18. package/package.json +26 -16
  19. package/public/favicon/android-chrome-192x192.png +0 -0
  20. package/public/favicon/android-chrome-512x512.png +0 -0
  21. package/public/favicon/apple-touch-icon.png +0 -0
  22. package/public/favicon/browserconfig.xml +7 -7
  23. package/public/favicon/favicon-16x16-dark.png +0 -0
  24. package/public/favicon/favicon-16x16.png +0 -0
  25. package/public/favicon/favicon-32x32-dark.png +0 -0
  26. package/public/favicon/favicon-32x32.png +0 -0
  27. package/public/favicon/favicon-48x48-dark.png +0 -0
  28. package/public/favicon/favicon-48x48.png +0 -0
  29. package/public/favicon/favicon-dark.ico +0 -0
  30. package/public/favicon/favicon.ico +0 -0
  31. package/public/favicon/favicon.svg +16 -0
  32. package/public/favicon/manifest.webmanifest +26 -0
  33. package/public/favicon/mstile-150x150.png +0 -0
  34. package/public/favicon/safari-pinned-tab.svg +14 -15
  35. package/public/favicon/yandex-browser-50x50.png +0 -0
  36. package/public/favicon/yandex-browser-manifest.json +9 -0
  37. package/src/blocks/Article.astro +21 -0
  38. package/src/blocks/Banner.astro +47 -0
  39. package/src/blocks/Colleagues.astro +2 -1
  40. package/src/blocks/Contact.astro +84 -99
  41. package/src/blocks/Cta.astro +2 -1
  42. package/src/blocks/Hero.astro +1 -2
  43. package/src/blocks/Intro.astro +1 -1
  44. package/src/blocks/Jobs.astro +1 -1
  45. package/src/blocks/Prices.astro +1 -1
  46. package/src/blocks/Product.astro +23 -10
  47. package/src/blocks/Reviews.astro +1 -1
  48. package/src/components/Avatar.astro +3 -20
  49. package/src/components/Badge.astro +17 -54
  50. package/src/components/Badges.astro +50 -0
  51. package/src/components/Button.astro +63 -45
  52. package/src/components/Buttons.astro +49 -0
  53. package/src/components/Card.astro +94 -177
  54. package/src/components/Cards.astro +135 -0
  55. package/src/components/Channel.astro +70 -0
  56. package/src/components/Channels.astro +37 -0
  57. package/src/components/Checkbox.astro +16 -19
  58. package/src/components/Dialog.astro +10 -11
  59. package/src/components/Drawer.astro +16 -22
  60. package/src/components/Element.astro +58 -0
  61. package/src/components/Footer.astro +141 -97
  62. package/src/components/Head.astro +7 -45
  63. package/src/components/Header.astro +78 -160
  64. package/src/components/Heading.astro +18 -26
  65. package/src/components/Icon.astro +9 -9
  66. package/src/components/Image.astro +43 -152
  67. package/src/components/Input.astro +10 -28
  68. package/src/components/Label.astro +14 -17
  69. package/src/components/Link.astro +22 -44
  70. package/src/components/List.astro +12 -10
  71. package/src/components/LocaleSwitcher.astro +25 -0
  72. package/src/components/Price.astro +38 -0
  73. package/src/components/Rating.astro +29 -25
  74. package/src/components/Search.astro +3 -3
  75. package/src/components/Section.astro +196 -236
  76. package/src/components/Select.astro +16 -34
  77. package/src/components/Sidebar.astro +112 -46
  78. package/src/components/Social.astro +28 -0
  79. package/src/components/Socials.astro +37 -0
  80. package/src/components/Switch.astro +14 -22
  81. package/src/components/Table.astro +23 -36
  82. package/src/components/Tagline.astro +11 -16
  83. package/src/components/Text.astro +17 -19
  84. package/src/components/Textarea.astro +8 -22
  85. package/src/components/ThemeSelect.astro +38 -0
  86. package/src/components/Toc.astro +100 -23
  87. package/src/components/Writeup.astro +90 -0
  88. package/src/components/docs/PropsTable.astro +229 -56
  89. package/src/components/experimental/Form.astro +10 -17
  90. package/src/components/experimental/Logo.astro +26 -9
  91. package/src/components/experimental/Prose.astro +9 -5
  92. package/src/components/experimental/Video.astro +1 -1
  93. package/src/components/experimental/Window.astro +3 -4
  94. package/src/components/sections.astro +28 -0
  95. package/src/content/config.ts +10 -7
  96. package/src/content/pages/base/_dialog.mdx +1 -2
  97. package/src/content/pages/base/_drawer.mdx +1 -2
  98. package/src/content/pages/base/_localeswitcher.mdx +17 -0
  99. package/src/content/pages/base/_switch.mdx +1 -2
  100. package/src/content/pages/base/badge.mdx +1 -12
  101. package/src/content/pages/base/button.mdx +1 -12
  102. package/src/content/pages/base/card.mdx +2 -29
  103. package/src/content/pages/base/checkbox.mdx +7 -8
  104. package/src/content/pages/base/icon.mdx +3 -2
  105. package/src/content/pages/base/image.mdx +42 -0
  106. package/src/content/pages/base/input.mdx +1 -12
  107. package/src/content/pages/base/rating.mdx +3 -14
  108. package/src/content/pages/base/section.mdx +17 -60
  109. package/src/content/pages/base/select.mdx +1 -12
  110. package/src/content/pages/base/table.mdx +1 -28
  111. package/src/content/pages/base/textarea.mdx +1 -11
  112. package/src/content/pages/base/theme-select.mdx +15 -0
  113. package/src/content/pages/blocks/_categories.mdx +3 -5
  114. package/src/content/pages/blocks/{footer.mdx → _footer.mdx} +10 -4
  115. package/src/content/pages/blocks/{header.mdx → _header.mdx} +2 -7
  116. package/src/content/pages/blocks/_jobs.mdx +1 -2
  117. package/src/content/pages/blocks/{prices.mdx → _prices.mdx} +5 -7
  118. package/src/content/pages/blocks/_product.mdx +1 -2
  119. package/src/content/pages/blocks/_products.mdx +1 -2
  120. package/src/content/pages/blocks/_stats.mdx +1 -1
  121. package/src/content/pages/blocks/{_banner.mdx → banner.mdx} +2 -2
  122. package/src/content/pages/blocks/colleagues.mdx +6 -8
  123. package/src/content/pages/blocks/contact.mdx +69 -0
  124. package/src/content/pages/blocks/content.mdx +1 -19
  125. package/src/content/pages/blocks/cta.mdx +2 -25
  126. package/src/content/pages/blocks/features.mdx +2 -3
  127. package/src/content/pages/blocks/hero.mdx +5 -3
  128. package/src/content/pages/blocks/intro.mdx +2 -5
  129. package/src/content/pages/blocks/posts.mdx +9 -2
  130. package/src/content/pages/blocks/reviews.mdx +23 -18
  131. package/src/content/pages/index.mdx +19 -20
  132. package/src/content/pages/layouts/docslayout.mdx +5 -0
  133. package/src/content/pages/layouts/layout.mdx +21 -0
  134. package/src/content/pages/layouts/pagelayout.mdx +21 -0
  135. package/src/content/pages/overview/components.mdx +70 -0
  136. package/src/content/pages/overview/content-layer.mdx +128 -0
  137. package/src/content/pages/overview/{theming.mdx → customization.mdx} +6 -6
  138. package/src/content/pages/overview/frameworks.mdx +4 -4
  139. package/src/content/pages/overview/installation.mdx +37 -3
  140. package/src/content/pages/overview/introduction.mdx +6 -2
  141. package/src/content/pages/schemas/page.mdx +11 -0
  142. package/src/content/pages/schemas/preset.mdx +9 -0
  143. package/src/content/pages/showcase/anti-slip-profiles.md +5 -0
  144. package/src/content/pages/showcase/fulldev-ui.md +5 -0
  145. package/src/content/pages/showcase/lavis-detailing.md +5 -0
  146. package/src/content/pages/showcase/leren-trainingsacteren.md +5 -0
  147. package/src/content/pages/showcase/miele-witgoedcenter-amsterdam.md +5 -0
  148. package/src/content/{records/record.yml → pages/showcase/record.md} +2 -0
  149. package/src/content/pages/showcase/sloepverhuur-bolsward.md +5 -0
  150. package/src/content/pages/showcase/stark-vulcanising-products.md +5 -0
  151. package/src/content/pages/showcase/the-gym-haren.md +5 -0
  152. package/src/content/pages/showcase/van-dillen-antieke-bouwmaterialen.md +5 -0
  153. package/src/content/pages/showcase.mdx +11 -41
  154. package/src/content/pages/typography/_tagline.mdx +1 -2
  155. package/src/content/pages/typography/heading.mdx +1 -2
  156. package/src/content/pages/typography/label.mdx +1 -2
  157. package/src/content/pages/typography/link.mdx +1 -13
  158. package/src/content/pages/typography/list.mdx +1 -2
  159. package/src/content/pages/typography/text.mdx +1 -2
  160. package/src/content/presets/base.yml +70 -0
  161. package/src/content/presets/blocks.yml +4 -0
  162. package/src/content/presets/docs.yml +65 -0
  163. package/src/css/color.css +0 -82
  164. package/src/css/custom.css +9 -56
  165. package/src/css/size.css +10 -0
  166. package/src/css/space.css +0 -8
  167. package/src/css/styles.css +0 -15
  168. package/src/images/avatar-1.yml +1 -0
  169. package/src/images/favicon.svg +16 -0
  170. package/src/integration/generate-colors.ts +2 -0
  171. package/src/integration/index.ts +49 -7
  172. package/src/layouts/BlockLayout.astro +10 -15
  173. package/src/layouts/ContactLayout.astro +21 -0
  174. package/src/layouts/ContentLayout.astro +16 -0
  175. package/src/layouts/DocsLayout.astro +85 -0
  176. package/src/layouts/Layout.astro +111 -133
  177. package/src/layouts/OverviewLayout.astro +22 -32
  178. package/src/layouts/PageLayout.astro +7 -24
  179. package/src/layouts/PostLayout.astro +8 -19
  180. package/src/layouts/ProductLayout.astro +9 -22
  181. package/src/loaders/imageLoader.ts +26 -0
  182. package/src/pages/[...page].astro +26 -23
  183. package/src/schemas/components/avatar.ts +3 -0
  184. package/src/schemas/components/avatars.ts +4 -0
  185. package/src/schemas/components/badge.ts +13 -0
  186. package/src/schemas/components/button.ts +16 -0
  187. package/src/schemas/components/buttons.ts +4 -0
  188. package/src/schemas/components/card.ts +25 -0
  189. package/src/schemas/components/cards.ts +4 -0
  190. package/src/schemas/components/channel.ts +13 -0
  191. package/src/schemas/components/channels.ts +4 -0
  192. package/src/schemas/components/footer.ts +24 -0
  193. package/src/schemas/components/header.ts +10 -0
  194. package/src/schemas/components/heading.ts +3 -0
  195. package/src/schemas/components/icon.ts +3 -0
  196. package/src/schemas/components/image.ts +18 -0
  197. package/src/schemas/components/images.ts +4 -0
  198. package/src/schemas/components/list.ts +3 -0
  199. package/src/schemas/components/logo.ts +3 -0
  200. package/src/schemas/components/price.ts +3 -0
  201. package/src/schemas/components/rating.ts +15 -0
  202. package/src/schemas/components/section.ts +15 -0
  203. package/src/schemas/components/sections.ts +3 -0
  204. package/src/schemas/components/social.ts +3 -0
  205. package/src/schemas/components/socials.ts +4 -0
  206. package/src/schemas/components/tagline.ts +3 -0
  207. package/src/schemas/components/text.ts +3 -0
  208. package/src/schemas/components/writeup.ts +20 -0
  209. package/src/schemas/imageSchema.ts +12 -0
  210. package/src/schemas/pageSchema.ts +63 -0
  211. package/src/schemas/presetSchema.ts +29 -0
  212. package/src/schemas/utils/categories.ts +3 -0
  213. package/src/schemas/utils/component.ts +17 -0
  214. package/src/schemas/utils/navigation.ts +53 -0
  215. package/src/schemas/{utils.ts → utils/pathSchema.ts} +2 -11
  216. package/src/types/global-props.d.ts +16 -0
  217. package/src/types/virtual-modules.d.ts +5 -0
  218. package/src/utils/_archive/Childmorphic.ts +1 -1
  219. package/src/utils/_archive/mergeEntries.ts +28 -0
  220. package/src/utils/getCategoryPages.ts +11 -0
  221. package/src/utils/getChildPages.ts +16 -0
  222. package/src/utils/getSiblingPages.ts +14 -0
  223. package/tsconfig.json +1 -2
  224. package/public/favicon/site.webmanifest +0 -19
  225. package/public/images/avatars/1.jpeg +0 -0
  226. package/public/images/avatars/2.jpeg +0 -0
  227. package/public/images/avatars/3.jpeg +0 -0
  228. package/public/images/avatars/300/1.jpeg +0 -0
  229. package/public/images/avatars/300/2.jpeg +0 -0
  230. package/public/images/avatars/300/3.jpeg +0 -0
  231. package/public/images/avatars/300/4.jpeg +0 -0
  232. package/public/images/avatars/4.jpeg +0 -0
  233. package/public/images/avatars/5.jpeg +0 -0
  234. package/public/images/avatars/6.jpeg +0 -0
  235. package/public/images/avatars/7.jpeg +0 -0
  236. package/public/images/avatars/8.jpeg +0 -0
  237. package/public/images/blocks/colleagues.png +0 -0
  238. package/public/images/blocks/content.png +0 -0
  239. package/public/images/blocks/cta.png +0 -0
  240. package/public/images/blocks/features.png +0 -0
  241. package/public/images/blocks/footer.png +0 -0
  242. package/public/images/blocks/header.png +0 -0
  243. package/public/images/blocks/hero.png +0 -0
  244. package/public/images/blocks/intro.png +0 -0
  245. package/public/images/blocks/posts.png +0 -0
  246. package/public/images/blocks/prices.png +0 -0
  247. package/public/images/blocks/reviews.png +0 -0
  248. package/public/images/logo-placeholder.svg +0 -1
  249. package/src/components/Bento.astro +0 -43
  250. package/src/components/Block.astro +0 -157
  251. package/src/components/Blocks.astro +0 -5
  252. package/src/components/Box.astro +0 -63
  253. package/src/components/Carousel.astro +0 -54
  254. package/src/components/Column.astro +0 -73
  255. package/src/components/Grid.astro +0 -32
  256. package/src/components/Masonry.astro +0 -42
  257. package/src/components/Root.astro +0 -94
  258. package/src/components/Row.astro +0 -49
  259. package/src/components/Split.astro +0 -59
  260. package/src/components/Spread.astro +0 -46
  261. package/src/components/Stack.astro +0 -36
  262. package/src/components/Wrap.astro +0 -42
  263. package/src/components/docs/NavigationButtons.astro +0 -59
  264. package/src/components/experimental/Channel.astro +0 -74
  265. package/src/components/experimental/Price.astro +0 -40
  266. package/src/content/pages/_changelog.mdx +0 -10
  267. package/src/content/pages/_segment/footer.mdx +0 -244
  268. package/src/content/pages/_segment/header.mdx +0 -210
  269. package/src/content/pages/base/_image.mdx +0 -14
  270. package/src/content/pages/blocks.mdx +0 -10
  271. package/src/content/pages/overview/integration.mdx +0 -37
  272. package/src/content/pages/structure/_row.mdx +0 -23
  273. package/src/content/pages/structure/_wrap.mdx +0 -25
  274. package/src/content/pages/structure/carousel.mdx +0 -31
  275. package/src/content/pages/structure/column.mdx +0 -21
  276. package/src/content/pages/structure/grid.mdx +0 -26
  277. package/src/content/pages/structure/masonry.mdx +0 -32
  278. package/src/content/pages/structure/split.mdx +0 -21
  279. package/src/content/pages/structure/spread.mdx +0 -21
  280. package/src/content/pages/structure/stack.mdx +0 -22
  281. package/src/content/settings/base.yml +0 -55
  282. package/src/content/settings/components.yml +0 -29
  283. package/src/layouts/BlockOverviewLayout.astro +0 -39
  284. package/src/layouts/ComponentLayout.astro +0 -23
  285. package/src/layouts/JobsLayout.astro +0 -40
  286. package/src/schemas/base.ts +0 -90
  287. package/src/schemas/block.ts +0 -15
  288. package/src/schemas/card.ts +0 -3
  289. package/src/schemas/page.ts +0 -43
  290. package/src/utils/mergeEntries.ts +0 -28
  291. /package/{public/showcase → src/images}/anti-slip-profiles.webp +0 -0
  292. /package/{public/images/avatars/500/1.jpeg → src/images/avatar-1.jpeg} +0 -0
  293. /package/{public/images/avatars/500/2.jpeg → src/images/avatar-2.jpeg} +0 -0
  294. /package/{public/images/avatars/500/3.jpeg → src/images/avatar-3.jpeg} +0 -0
  295. /package/{public/images/avatars/500/4.jpeg → src/images/avatar-4.jpeg} +0 -0
  296. /package/{public → src}/images/avatar-placeholder.jpg +0 -0
  297. /package/{public → src}/images/block-code.png +0 -0
  298. /package/{public → src}/images/component-code.png +0 -0
  299. /package/{public/showcase → src/images}/fulldev-ui.webp +0 -0
  300. /package/{public/showcase → src/images}/lavis-detailing.webp +0 -0
  301. /package/{public/showcase → src/images}/leren-trainingsacteren.webp +0 -0
  302. /package/{public/showcase → src/images}/miele-witgoedcenter-amsterdam.webp +0 -0
  303. /package/{public → src}/images/og-image.png +0 -0
  304. /package/{public → src}/images/placeholder-center.webp +0 -0
  305. /package/{public → src}/images/placeholder-landscape-dark.png +0 -0
  306. /package/{public → src}/images/placeholder-landscape.webp +0 -0
  307. /package/{public → src}/images/placeholder-portrait.webp +0 -0
  308. /package/{public → src}/images/placeholder-right.webp +0 -0
  309. /package/{public → src}/images/placeholder.webp +0 -0
  310. /package/{public/showcase → src/images}/sloepverhuur-bolsward.webp +0 -0
  311. /package/{public/showcase → src/images}/stark-vulcanising-products.webp +0 -0
  312. /package/{public/showcase → src/images}/the-gym-haren.webp +0 -0
  313. /package/{public/showcase → src/images}/van-dillen-antieke-bouwmaterialen.webp +0 -0
@@ -1,54 +1,131 @@
1
1
  ---
2
- import Column from 'fulldev-ui/components/Column.astro'
3
- import Link from 'fulldev-ui/components/Link.astro'
4
- import Heading from './Heading.astro'
2
+ import type { HTMLAttributes } from 'astro/types'
3
+ import type { CollectionEntry } from 'astro:content'
4
+ import Button from 'fulldev-ui/components/Button.astro'
5
+ import Element from 'fulldev-ui/components/Element.astro'
6
+ import Heading from 'fulldev-ui/components/Heading.astro'
7
+ import type { GlobalProps } from 'fulldev-ui/types/global-props'
5
8
 
6
- const { toc, headings } = Astro.props
9
+ interface Props extends GlobalProps, HTMLAttributes<'aside'> {
10
+ render?: CollectionEntry<'pages'>['render'] | undefined
11
+ }
12
+
13
+ const { size = 'sm', render } = Astro.props
14
+
15
+ const headings = render ? (await render())?.headings : []
16
+ const filteredHeadings = headings?.filter(
17
+ (heading: any) => heading.depth >= 2 && heading.depth <= 4
18
+ )
7
19
  ---
8
20
 
9
- <Column
21
+ <input
22
+ id="toc"
23
+ class="toc-checkbox"
24
+ type="checkbox"
25
+ />
26
+
27
+ <Element
10
28
  class:list="toc"
11
29
  as="aside"
30
+ {size}
12
31
  >
13
32
  {
14
- toc?.length && headings?.length > 0 && (
33
+ filteredHeadings?.length > 0 && (
15
34
  <>
16
35
  <Heading
17
36
  text="On this page"
18
37
  level={6}
19
38
  />
20
- {headings.map(
21
- (heading: { slug: string; depth: number; text: string }) => (
22
- <Link
39
+ <nav class="toc-nav">
40
+ <Button
41
+ variant="link"
42
+ href={`#${filteredHeadings[0]?.slug}`}
43
+ text="Overview"
44
+ class="toc-link toc-link-h2"
45
+ />
46
+ {filteredHeadings.map((heading: any) => (
47
+ <Button
48
+ variant="link"
23
49
  href={`#${heading.slug}`}
24
- class="toc-link"
25
50
  text={heading.text}
51
+ class={`toc-link toc-link-h${heading.depth}`}
26
52
  />
27
- )
28
- )}
53
+ ))}
54
+ </nav>
29
55
  </>
30
56
  )
31
57
  }
32
- </Column>
58
+ </Element>
33
59
 
34
60
  <style lang="scss" is:global>
35
61
  @layer fulldev {
62
+ .toc-checkbox {
63
+ display: none;
64
+ }
65
+
66
+ @media (max-width: 1023.999px) {
67
+ body:has(.toc-checkbox:checked) {
68
+ overflow: hidden;
69
+ }
70
+ }
71
+
36
72
  .toc {
37
- display: none !important;
38
- box-sizing: border-box;
39
- border-left: 1px solid var(--color-a6);
40
- padding: var(--space-6) 0 var(--space-6)
41
- min(var(--space-5), var(--gutter));
42
- height: 100vh;
43
- max-height: 100vh;
73
+ --toc-width: 240px;
74
+
75
+ display: none;
76
+ position: fixed;
77
+ top: var(--header-height, 0px);
78
+ right: 0;
79
+ flex-shrink: 0;
80
+ flex-direction: column;
81
+ justify-content: flex-start;
82
+ gap: calc(var(--space-4) + var(--space-1));
83
+ z-index: 10;
84
+ border-left-width: 1px;
85
+ border-style: solid;
86
+ border-color: var(--color-a6);
87
+ background-color: var(--color-background);
88
+ padding: var(--space-md-6) var(--gutter);
89
+ width: 100%;
90
+ max-height: calc(100vh - var(--header-height, 0px));
44
91
  overflow-y: auto;
45
92
 
46
- .toc-link {
47
- font-size: var(--text-2);
93
+ &:is(.toc-checkbox:checked + &) {
94
+ display: flex;
48
95
  }
49
96
 
50
97
  @media (min-width: 1024px) {
51
- display: flex !important;
98
+ display: flex;
99
+ position: sticky;
100
+ border-left-width: 1px;
101
+ width: var(--toc-width);
102
+ }
103
+
104
+ .button + .heading {
105
+ margin-top: var(--space-5);
106
+ }
107
+
108
+ .toc-nav {
109
+ display: flex;
110
+ flex-direction: column;
111
+ }
112
+
113
+ .toc-link {
114
+ text-align: left;
115
+ }
116
+
117
+ .toc-link-h2 {
118
+ margin-top: var(--space-3);
119
+ }
120
+
121
+ .toc-link-h3 {
122
+ margin-top: var(--space-3);
123
+ margin-left: var(--space-4);
124
+ }
125
+
126
+ .toc-link-h4 {
127
+ margin-top: var(--space-2);
128
+ margin-left: var(--space-5);
52
129
  }
53
130
  }
54
131
  }
@@ -0,0 +1,90 @@
1
+ ---
2
+ import type { ComponentProps, HTMLAttributes } from 'astro/types'
3
+ import Badge from 'fulldev-ui/components/Badge.astro'
4
+ import Element from 'fulldev-ui/components/Element.astro'
5
+ import Heading from 'fulldev-ui/components/Heading.astro'
6
+ import List from 'fulldev-ui/components/List.astro'
7
+ import Price from 'fulldev-ui/components/Price.astro'
8
+ import Rating from 'fulldev-ui/components/Rating.astro'
9
+ import Tagline from 'fulldev-ui/components/Tagline.astro'
10
+ import Text from 'fulldev-ui/components/Text.astro'
11
+ import type { GlobalProps } from 'fulldev-ui/types/global-props'
12
+
13
+ interface Props extends GlobalProps, HTMLAttributes<'div'> {
14
+ level?: ComponentProps<typeof Heading>['level']
15
+ badge?: ComponentProps<typeof Badge> | undefined
16
+ tagline?: ComponentProps<typeof Tagline>['text']
17
+ heading?: ComponentProps<typeof Heading>['text']
18
+ text?: ComponentProps<typeof Text>['text']
19
+ list?: ComponentProps<typeof List>['items']
20
+ align?: 'start' | 'center' | 'end' | undefined
21
+ price?: ComponentProps<typeof Price>['value']
22
+ rating?:
23
+ | ComponentProps<typeof Rating>
24
+ | ComponentProps<typeof Rating>['value']
25
+ }
26
+
27
+ const {
28
+ level = 2,
29
+ rating,
30
+ badge,
31
+ tagline,
32
+ heading,
33
+ text,
34
+ list,
35
+ price,
36
+ ...rest
37
+ } = Astro.props
38
+ ---
39
+
40
+ <Element
41
+ class:list="writeup"
42
+ {...rest}
43
+ >
44
+ <slot>
45
+ <Rating
46
+ color="brand"
47
+ {...typeof rating === 'number' ? { value: rating } : rating}
48
+ />
49
+ <Tagline text={tagline} />
50
+ <Badge {...badge} />
51
+ <Heading
52
+ {level}
53
+ text={heading}
54
+ />
55
+ <Text
56
+ lead={level === 1}
57
+ text={text}
58
+ />
59
+ <List items={list} />
60
+ <Price value={price} />
61
+ </slot>
62
+ </Element>
63
+
64
+ <style is:global lang="scss">
65
+ @layer fulldev {
66
+ .writeup {
67
+ display: flex;
68
+ position: relative;
69
+ flex-direction: column;
70
+ align-items: inherit;
71
+ gap: var(--space-3);
72
+ text-align: inherit;
73
+
74
+ &.align-start {
75
+ align-items: flex-start;
76
+ text-align: left;
77
+ }
78
+
79
+ &.align-center {
80
+ align-items: center;
81
+ text-align: center;
82
+ }
83
+
84
+ &.align-end {
85
+ align-items: flex-end;
86
+ text-align: right;
87
+ }
88
+ }
89
+ }
90
+ </style>
@@ -1,43 +1,105 @@
1
1
  ---
2
2
  import Table from 'fulldev-ui/components/Table.astro'
3
3
  import { readFileSync } from 'node:fs'
4
+ import { pascal } from 'radash'
4
5
 
5
- const pathnameWithoutTrailingSlash = Astro.url.pathname.replace(/\/$/, '')
6
- const slug = pathnameWithoutTrailingSlash.split('/').pop() || ''
7
- const component = slug.charAt(0).toUpperCase() + slug.slice(1)
6
+ const slug = Astro.url.pathname.replace(/\/$/, '').split('/').pop() || ''
7
+ const componentName = pascal(slug)
8
8
 
9
- const allComponents = await Astro.glob('../../components/**/*.astro')
10
- const found = allComponents.find(
11
- (c) => c.file.split('/').pop()?.replace('.astro', '') === component
12
- )
9
+ const allComponents = import.meta.glob('src/**/*.astro', { eager: true })
10
+ const foundComponent = Object.entries(allComponents).find(
11
+ ([key]) => key.split('/').pop() === `${componentName}.astro`
12
+ )?.[1] as any
13
+ const componentFileContent =
14
+ (foundComponent && readFileSync(foundComponent.file, 'utf-8')) || ''
15
+
16
+ interface Prop {
17
+ name: string
18
+ type: string
19
+ }
20
+
21
+ // Regular expression to match the Props interface or type
22
+ const staticProps = /(?:interface|type)\s+Props[\s\S]*?{([\s\S]*?)}/
23
+
24
+ // Function to extract props from the component file
25
+ const extractProps = (content: string): Prop[] => {
26
+ const props: Prop[] = []
27
+
28
+ // Extract static props from Props interface or type
29
+ const staticPropsMatch = content.match(staticProps)
30
+ if (staticPropsMatch && staticPropsMatch[1]) {
31
+ const propsContent = staticPropsMatch[1]
32
+ const propLines = propsContent.split('\n')
33
+
34
+ let currentProp: Prop | null = null
13
35
 
14
- if (!found) return
36
+ propLines.forEach((line) => {
37
+ const trimmedLine = line.trim()
38
+ if (trimmedLine === '') return
15
39
 
16
- const componentFileContent = readFileSync(found.file, 'utf-8')
40
+ // Match prop name and type
41
+ const match = trimmedLine.match(/^(\w+)(\??):(.*)/)
42
+ if (match && match[1] && match[3]) {
43
+ if (currentProp) props.push(currentProp)
44
+ currentProp = {
45
+ name: match[1],
46
+ type: match[3].trim(),
47
+ }
48
+ } else if (currentProp) {
49
+ // Continue adding to type if it spans multiple lines
50
+ currentProp.type += ' ' + trimmedLine
51
+ }
52
+ })
17
53
 
18
- const extractProps = (content: string) => {
19
- const propsMatch = content.match(
20
- /type Props(?:<[^>]+>)?\s*=\s*(?:HTMLAttributes<'[^']+'>\s*&\s*)?(?:Polymorphic<[^>]+>\s*&\s*)?([\s\S]*?)(?:}|$)/
54
+ if (currentProp) props.push(currentProp)
55
+ }
56
+
57
+ // Extract props from type intersections
58
+ const intersectionProps = content.match(
59
+ /Props(?:<[^>]+>)?\s*=\s*([\s\S]*?)(?:$|\n\n)/
21
60
  )
22
- if (propsMatch) {
23
- const propsContent = propsMatch[1]
24
- const props = [
25
- ...propsContent.matchAll(/(\w+)(?:\??:\s*((?:[^;\n]|\n\s*\|)*)|,)/g),
26
- ].map(([, name, type]) => ({
27
- name,
28
- type: type
29
- ? type
30
- .replace(/^\s*\|\s*/, '')
31
- .trim()
32
- .replace(/\n\s*\|/g, ' | ')
33
- : 'unknown',
34
- }))
35
- return props
61
+ if (intersectionProps && intersectionProps[1]) {
62
+ const intersectionContent = intersectionProps[1]
63
+ let currentProp: Prop | null = null
64
+ const lines = intersectionContent.split('\n')
65
+
66
+ lines.forEach((line) => {
67
+ const trimmedLine = line.trim()
68
+ if (trimmedLine === '') return
69
+
70
+ // Match prop name and type
71
+ const match = trimmedLine.match(/(\w+)(\??):(.*)/)
72
+ if (match && match[1] && match[3]) {
73
+ if (currentProp) props.push(currentProp)
74
+ currentProp = {
75
+ name: match[1],
76
+ type: match[3].trim(),
77
+ }
78
+ } else if (currentProp) {
79
+ // Continue adding to type if it spans multiple lines
80
+ currentProp.type += ' ' + trimmedLine
81
+ }
82
+ })
83
+
84
+ if (currentProp) props.push(currentProp)
36
85
  }
37
- return []
86
+
87
+ // Clean up the type of the last prop
88
+ if (props.length > 0) {
89
+ const lastProp = props[props.length - 1]
90
+ if (lastProp) {
91
+ lastProp.type = lastProp.type.replace(/\s*}\s*$/, '')
92
+ }
93
+ }
94
+
95
+ // Filter out 'as' prop and props starting with underscore
96
+ return props.filter(
97
+ (prop) => prop.name !== 'as' && !prop.name.startsWith('_')
98
+ )
38
99
  }
39
100
 
40
- const extractDefaultProps = (content: string) => {
101
+ // Function to extract default prop values from Astro.props
102
+ const extractDefaultProps = (content: string): Record<string, string> => {
41
103
  const defaultPropsMatch = content.match(
42
104
  /const\s*{[\s\S]*?}\s*=\s*Astro\.props/
43
105
  )
@@ -47,11 +109,14 @@ const extractDefaultProps = (content: string) => {
47
109
  /(\w+)\s*=\s*('[^']*'|"[^"]*"|[^,\n]+)/g
48
110
  ),
49
111
  ].reduce(
50
- (acc, [, name, value]) => {
51
- acc[name] =
52
- value.startsWith("'") || value.startsWith('"')
53
- ? value.slice(1, -1)
54
- : value
112
+ (acc, match) => {
113
+ const [, name, value] = match
114
+ if (name && name !== 'as' && value !== undefined) {
115
+ acc[name] =
116
+ value.startsWith("'") || value.startsWith('"')
117
+ ? value.slice(1, -1)
118
+ : value
119
+ }
55
120
  return acc
56
121
  },
57
122
  {} as Record<string, string>
@@ -59,40 +124,148 @@ const extractDefaultProps = (content: string) => {
59
124
  : {}
60
125
  }
61
126
 
62
- const extractAsDefault = (content: string) => {
63
- const asDefaultMatch = content.match(/as\s*=\s*([^,\n]+)/)
64
- return asDefaultMatch
65
- ? asDefaultMatch[1]
66
- .trim()
67
- .split(' : ')[0]
68
- .replace(/['"]/g, '')
69
- .replace(/href \? a : /, '')
70
- .replace(/href \? 'a' : /, '')
71
- : 'div'
127
+ // Function to extract the default 'As' prop value from the interface or type
128
+ const extractAsDefault = (content: string): string => {
129
+ const asTypeMatch = content.match(/type Props<As extends ([^>]+)>/)
130
+ if (asTypeMatch && asTypeMatch[1]) {
131
+ return asTypeMatch[1].trim().replace(/['"]/g, '')
132
+ }
133
+
134
+ const asInterfaceMatch = content.match(/interface Props<As extends ([^>]+)>/)
135
+ if (asInterfaceMatch && asInterfaceMatch[1]) {
136
+ return asInterfaceMatch[1].trim().replace(/['"]/g, '')
137
+ }
138
+
139
+ return ''
72
140
  }
73
141
 
74
142
  const parsedProps = extractProps(componentFileContent)
75
143
  const parsedAstroProps = extractDefaultProps(componentFileContent)
76
144
  const asDefault = extractAsDefault(componentFileContent)
145
+
146
+ // Function to get the default value for a prop
147
+ const getDefaultValue = (name: string): string => {
148
+ if (name in parsedAstroProps) {
149
+ return parsedAstroProps[name] || '-'
150
+ }
151
+
152
+ return '-'
153
+ }
154
+
155
+ // Check if the component extends Element.astro
156
+ const extendsElement = componentFileContent.includes('GlobalProps')
157
+
158
+ // Check if the component extends Writeup.astro
159
+ const extendsWriteup = componentFileContent.includes(
160
+ 'ComponentProps<typeof Writeup>'
161
+ )
162
+
163
+ // Prepare the table body data
164
+ const tableBody = new Map()
165
+
166
+ // Add component-specific props
167
+ parsedProps.forEach((item) => {
168
+ tableBody.set(item.name, [
169
+ item.name,
170
+ item.type.replace(/\s*\|?\s*(undefined|null)/, '').trim(),
171
+ getDefaultValue(item.name),
172
+ ])
173
+ })
174
+
175
+ // Add Element props if the component extends Element.astro
176
+ if (extendsElement) {
177
+ const elementProps = extractProps(
178
+ readFileSync('src/components/Element.astro', 'utf-8')
179
+ )
180
+ elementProps
181
+ .filter((item) => item.name !== '[key: string | number | symbol]')
182
+ .forEach((item) => {
183
+ if (!tableBody.has(item.name)) {
184
+ let type = item.type
185
+ .replace(/\s*\|?\s*(undefined|null)/, '')
186
+ .trim()
187
+ .replace(/\s*\|\s*any/, '')
188
+ .replace(/\s*\[key: string \| number \| symbol\]: any/, '')
189
+
190
+ // Remove [key: string | number | symbol]: any from the last prop
191
+ if (item === elementProps[elementProps.length - 1]) {
192
+ type = type.replace(/\s*\[key: string \| number \| symbol\]: any/, '')
193
+ }
194
+
195
+ if (item.name === 'size') {
196
+ type = "'sm' | 'md' | 'lg'"
197
+ } else if (item.name === 'color') {
198
+ type = "'base' | 'brand'"
199
+ }
200
+
201
+ tableBody.set(item.name, [item.name, type, getDefaultValue(item.name)])
202
+ }
203
+ })
204
+ }
205
+
206
+ // Add Writeup props if the component extends Writeup.astro
207
+ if (extendsWriteup) {
208
+ const writeupProps = extractProps(
209
+ readFileSync('src/components/Writeup.astro', 'utf-8')
210
+ )
211
+ writeupProps
212
+ .filter((item) => item.name !== '[key: string | number | symbol]')
213
+ .forEach((item) => {
214
+ if (!tableBody.has(item.name)) {
215
+ let type = item.type
216
+ .replace(/\s*\|?\s*(undefined|null)/, '')
217
+ .trim()
218
+ .replace(/\s*\|\s*any/, '')
219
+ .replace(/\s*\[key: string \| number \| symbol\]: any/, '')
220
+
221
+ // Remove [key: string | number | symbol]: any from the last prop
222
+ if (item === writeupProps[writeupProps.length - 1]) {
223
+ type = type.replace(/\s*\[key: string \| number \| symbol\]: any/, '')
224
+ }
225
+
226
+ tableBody.set(item.name, [item.name, type, getDefaultValue(item.name)])
227
+ }
228
+ })
229
+ }
230
+
231
+ // Add 'as' prop only if asDefault is not empty
232
+ if (asDefault) {
233
+ tableBody.set('as', ['as', 'HTMLTag', asDefault])
234
+ }
235
+
236
+ // Check if the component is polymorphic
237
+ const isPolymorphic = componentFileContent.includes('Polymorphic<')
238
+
239
+ // Extract HTMLAttributes from the component
240
+ const htmlAttributesMatch = componentFileContent.match(
241
+ /HTMLAttributes<'(\w+)'>/
242
+ )
243
+ let htmlElement = htmlAttributesMatch ? htmlAttributesMatch[1] : ''
244
+
245
+ // Special handling for List and Button components
246
+ if (componentName === 'List') {
247
+ htmlElement = "'ul' | 'ol'"
248
+ } else if (componentName === 'Button') {
249
+ htmlElement = "'button' | 'a' | 'label'"
250
+ }
251
+
252
+ // Add HTML Attributes row
253
+ if (isPolymorphic && asDefault) {
254
+ tableBody.set('HTML Attributes', [
255
+ 'HTML Attributes',
256
+ `Polymorphic<${asDefault}>`,
257
+ '-',
258
+ ])
259
+ } else if (htmlElement) {
260
+ tableBody.set('HTML Attributes', ['HTML Attributes', `${htmlElement}`, '-'])
261
+ }
77
262
  ---
78
263
 
79
264
  <Table
80
265
  size="md"
81
266
  class:list={['props-table']}
82
267
  header={['Prop', 'Type', 'Default']}
83
- body={[
84
- ...parsedProps.map((item) => [
85
- item.name,
86
- item.type,
87
- parsedAstroProps[item.name] ?? '-',
88
- ]),
89
- ...(asDefault !== 'div'
90
- ? [
91
- ['as', 'HTMLTag', asDefault],
92
- ['HTML Attributes', `Polymorphic<${asDefault}>`, '-'],
93
- ]
94
- : []),
95
- ]}
268
+ body={Array.from(tableBody.values())}
96
269
  />
97
270
 
98
271
  <style is:global lang="scss">
@@ -1,29 +1,22 @@
1
1
  ---
2
- import type { HTMLTag, Polymorphic } from 'astro/types'
3
- import Root from 'fulldev-ui/components/Root.astro'
2
+ import type { HTMLAttributes } from 'astro/types'
3
+ import Element from 'fulldev-ui/components/Element.astro'
4
+ import type { GlobalProps } from 'fulldev-ui/types/global-props'
4
5
 
5
- type Props<As extends HTMLTag = 'form'> = Polymorphic<{ as: As }> & {
6
- structure?: 'column' | 'row' | 'group'
7
- space?: 'none' | 'auto'
6
+ interface Props extends GlobalProps, HTMLAttributes<'form'> {
7
+ structure?: 'column' | 'row' | 'group' | undefined
8
8
  }
9
9
 
10
- const {
11
- as = 'form',
12
- space = 'auto',
13
- structure = 'column',
14
- ...rest
15
- } = Astro.props
10
+ const { structure = 'column', ...rest } = Astro.props
16
11
  ---
17
12
 
18
- <Root
19
- class:list="form"
20
- {as}
21
- {structure}
22
- {space}
13
+ <Element
14
+ class:list={`form ${structure}`}
15
+ as="form"
23
16
  {...rest}
24
17
  >
25
18
  <slot />
26
- </Root>
19
+ </Element>
27
20
 
28
21
  <style is:global lang="scss">
29
22
  .form {
@@ -1,21 +1,38 @@
1
1
  ---
2
2
  import type { ComponentProps } from 'astro/types'
3
+ import Element from 'fulldev-ui/components/Element.astro'
3
4
  import Image from 'fulldev-ui/components/Image.astro'
4
5
 
5
- type Props = Omit<ComponentProps<typeof Image>, 'position' | 'frame'> & {}
6
+ interface Props extends ComponentProps<typeof Image> {
7
+ company?: string | undefined
8
+ }
6
9
 
7
- const { ...rest } = Astro.props
10
+ const { company, ...rest } = Astro.props as Props
8
11
  ---
9
12
 
10
- <Image
13
+ <Element
14
+ as="a"
15
+ href="/"
11
16
  class:list="logo"
12
- {...rest}
13
- />
17
+ >
18
+ {company ? <Fragment set:html={company} /> : <Image {...rest} />}
19
+ </Element>
14
20
 
15
21
  <style is:global lang="scss">
16
- .logo {
17
- max-width: calc(15 * var(--space-2));
18
- height: 100%;
19
- object-fit: contain;
22
+ @layer fulldev {
23
+ .logo {
24
+ display: flex;
25
+ align-items: center;
26
+ color: var(--color-12);
27
+ font-weight: 700;
28
+ font-size: var(--text-6);
29
+ line-height: 1.1;
30
+
31
+ .image {
32
+ max-width: calc(15 * var(--space-2));
33
+ height: 100%;
34
+ object-fit: contain;
35
+ }
36
+ }
20
37
  }
21
38
  </style>