Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
3f40a24
Apply data-slot conventions to remaining UI components
silveltman Oct 9, 2026
ccaabd8
Add data-slot markers and resolved data-variant to remaining UI parts
silveltman Oct 9, 2026
779a838
Use logical directions, native link props, and overridable data-slot …
silveltman Oct 9, 2026
d92073b
Regenerate registry output for UI component consistency changes
silveltman Oct 9, 2026
f45fea1
Let Video callers override allow and allowfullscreen
silveltman Oct 9, 2026
1239b44
Honor align=left on Typography table head and cell
silveltman Oct 9, 2026
bcf7d51
Render Item and Logo as div when href is undefined or null
silveltman Oct 9, 2026
9fcdd31
Render nothing for empty optional arrays in blocks
silveltman Oct 9, 2026
b8de288
Scope Doc1 copy behavior and forward native attributes in docs shells
silveltman Oct 9, 2026
c242989
Mark active header navigation links on desktop and mobile
silveltman Oct 9, 2026
a616988
Open the FAQs1 default item through Accordion defaultValue
silveltman Oct 9, 2026
fd7696c
Name the Services6 arrow link and describe the Contact1 message field
silveltman Oct 9, 2026
1bb6598
Fetch GitHub stars in the base layout and pass them to Sidebar1
silveltman Oct 9, 2026
118022b
Drop registry dependencies that Links2 and Sidebar1 no longer import
silveltman Oct 9, 2026
1bde61d
Match the Doc labels example and Links prose to the current blocks
silveltman Oct 9, 2026
cfa0d7b
Regenerate registry output for compatible block cleanups
silveltman Oct 9, 2026
3255b9e
Remove dead Links2, CTA7, header and doc pagination fields
silveltman Oct 9, 2026
a729e59
Fix button styles in block code instead of caller variants
silveltman Oct 9, 2026
d5d7e0e
Require fixed block sections and drop props no caller uses
silveltman Oct 9, 2026
822968e
Take block control and screen reader copy from props
silveltman Oct 9, 2026
e7efafe
Render cards without a destination as plain wrappers
silveltman Oct 9, 2026
750e26d
Match block registry dependencies to their imports
silveltman Oct 9, 2026
c62f4d2
Pass banner and sidebar labels and banner storage key from callers
silveltman Oct 9, 2026
946182d
Add changeset for block prop simplification
silveltman Oct 9, 2026
bbfd744
Let Breadcrumb callers override its aria-label
silveltman Oct 9, 2026
f7c0e48
Regenerate registry for simplified block contracts
silveltman Oct 9, 2026
1871b62
Pass Reviews3 carousel labels and role descriptions from callers
silveltman Oct 9, 2026
d63079d
Regenerate registry for localized carousel labels
silveltman Oct 9, 2026
7f0b756
Add pnpm a11y: axe scan of every built page in headless Chromium
silveltman Oct 9, 2026
a197b2e
Render Section, Header, Carousel and SidebarRail attributes once
silveltman Oct 9, 2026
de172fe
Let PriceValue take a discount label and keep zero prices
silveltman Oct 9, 2026
00e4253
Rebuild Marquee on Embla Auto Scroll with one track and a pause toggle
silveltman Oct 9, 2026
25ad900
Use quote semantics in reviews and run Logos2 and Reviews4-5 on the n…
silveltman Oct 9, 2026
9df1d91
Make hero and CTA backdrops and social proof avatars decorative
silveltman Oct 9, 2026
3a3033f
Show header actions in the mobile menu and drop new-tab inference
silveltman Oct 9, 2026
430ee47
Give footer columns headings and render socials only when present
silveltman Oct 9, 2026
1b2be25
Use one optional link per feature and service, without fake hover
silveltman Oct 9, 2026
c5f13a1
Render the contact form from the default slot
silveltman Oct 9, 2026
e1aa73b
Pass locale and discount labels through pricing and product blocks
silveltman Oct 9, 2026
267fb9c
Wrap article pages in one article and style only linked article cards
silveltman Oct 9, 2026
934c326
Take currentPath in Sidebar1 and label the desktop sidebar
silveltman Oct 9, 2026
6548d07
Write out Content, FAQ, Links and docs block layouts and size content…
silveltman Oct 9, 2026
bbab40d
Make SectionContainer a neutral width container
silveltman Oct 9, 2026
f00ce80
Match registry items to the marquee parts and block imports, and upda…
silveltman Oct 9, 2026
7e0ab51
Render nothing for empty Features1 buttons and CTA5 lists
silveltman Oct 9, 2026
81be7bb
Regenerate registry for the blocks quality pass
silveltman Oct 9, 2026
b4e70a1
Report locatable incomplete axe results and compare request origins e…
silveltman Oct 9, 2026
892b6af
Move Marquee only with an enabled toggle and keep caller tabindex
silveltman Oct 9, 2026
9593421
Regenerate registry for the Marquee toggle and tabindex fix
silveltman Oct 9, 2026
77dc379
Highlight light-mode code with github-light-high-contrast
silveltman Oct 9, 2026
6ade0c7
Let finite animations settle before the axe scan
silveltman Oct 9, 2026
2a08209
Move Marquee only while its toggle can be pressed and seen
silveltman Oct 9, 2026
e159979
Regenerate registry for the Marquee toggle availability fix
silveltman Oct 9, 2026
4760a67
Read Marquee toggle visibility apart from its own hiding
silveltman Oct 9, 2026
6304ae8
Regenerate registry for the Marquee toggle visibility fix
silveltman Oct 9, 2026
2a13f2c
Set foreground text on the dark Hero4, Hero9 and CTA4 sections
silveltman Oct 9, 2026
96d0494
Regenerate registry for the dark section text color fix
silveltman Oct 9, 2026
8abd559
Stack the Header5 menu card copy under its image
silveltman Oct 9, 2026
da7bf94
Regenerate registry for the Header5 menu card layout
silveltman Oct 9, 2026
5b37bbe
Skip paused animations in the axe settling wait
silveltman Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 15 additions & 0 deletions .changeset/block-props-simplification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"fulldev-ui": minor
---

Simplify block props and improve block semantics (breaking).

- Blocks drop unused fields and button variants: button styles are fixed in each block. User-facing copy such as screen reader labels, close labels and rating labels is passed in by the caller. Banner1 takes an optional `storageKey` for dismissal instead of a shared hardcoded key. `BannerContainer` gains an optional `closeLabel` and `Sidebar` gains optional `mobileTitle` and `mobileDescription`.
- `SectionContainer` only sets width, gutter and position. It no longer adds `flex flex-col gap-8`; add the layout classes your content needs, such as `class="flex flex-col gap-8"`.
- Marquee renders its items once and moves them with Embla and its Auto Scroll plugin. Compose it from `Marquee`, `MarqueeContent` (`reverse` replaces `direction`), `MarqueeItem` and `MarqueeToggle` (`playLabel`, `pauseLabel`). It stays static without an enabled, visible toggle, with reduced motion, or when the items do not fill the row. The `duration`, `gap`, `infinite` and `pauseOnHover` props are removed; set `--marquee-gap` for spacing. Logos2, Reviews4 and Reviews5 take `labels: { play, pause }`.
- `PriceValue` takes `discountLabel` for the savings badge, keeps a `0` price or compare-at price, and only shows a compare-at price above the price. Pricing1-3, Product1 and Products1-5 take `locale` and `discountLabel`, and every price is `{ value, compareAt?, currency, unit }`. Pricing2 emphasizes plans with `featured` instead of the first plan.
- Header1-5 render their `buttons` in the mobile menu too and no longer have a default or `mobile` slot. Buttons always show their label and open in the same tab unless they set `target: "_blank"`. The logo takes typed images without `alt`, and Header4 and Header5 menu images are decorative.
- Features1 and Features4 take `link?: { label, href }` instead of `href` and `linkText`. Services4 and Services5 take a `link` per service instead of `linkLabel`.
- Contact1-3 render your form from their default slot instead of building one from `form` props. Contact items link their visible text.
- Sidebar1 takes `currentPath` and native attributes for its root, and `labels.sidebar` names the sidebar while `labels.sidebarToggle` names its trigger.
- Hero1's badge is optional. Background images in Hero3, Hero4, Hero9-11 and CTA4 are decorative and take no `alt`; social proof avatars no longer take `name`.
2 changes: 1 addition & 1 deletion astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default defineConfig({
processor: unified(),
shikiConfig: {
themes: {
light: "github-light",
light: "github-light-high-contrast",
dark: "github-dark-default",
},
},
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"images": "node scripts/images.ts",
"ui:add": "node scripts/ui-add.ts",
"build": "astro build && html-validate dist && linkinator dist",
"a11y": "pnpm build && playwright install chromium --only-shell && node scripts/a11y.mjs",
"registry:build": "pnpm registry:meta && node scripts/registry-adapt.mjs && shadcn build --output node_modules/.cache/fulldev-registry && node scripts/registry-styles.mjs && prettier --write registry.json public/r registry/styles/adapted --log-level warn",
"registry:check": "pnpm registry:validate && pnpm registry:build && git diff --exit-code -- registry.json public/r registry/styles/adapted",
"registry:validate": "node scripts/registry-validate.mjs",
Expand Down Expand Up @@ -97,6 +98,7 @@
"class-variance-authority": "^0.7.1",
"cn": "^0.4.0",
"embla-carousel": "8.6.0",
"embla-carousel-auto-scroll": "8.6.0",
"lucide-static": "^1.49.0",
"shadcn": "^4.21.0",
"simple-icons": "^16.33.0",
Expand All @@ -111,6 +113,7 @@
"@astrojs/markdown-remark": "^7.3.1",
"@astrojs/mdx": "^8.0.2",
"@astrojs/sitemap": "^3.7.4",
"@axe-core/playwright": "4.13.0",
"@changesets/changelog-github": "^0.7.0",
"@changesets/cli": "^2.31.0",
"@eslint/js": "^10.0.1",
Expand All @@ -128,6 +131,7 @@
"html-validate": "^11.16.1",
"knip": "^6.39.0",
"linkinator": "^8.1.0",
"playwright": "1.64.0",
"posthog-js": "1.434.15",
"prettier": "^3.9.9",
"prettier-plugin-astro": "^1.1.0",
Expand Down
44 changes: 44 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions public/r/article-1.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
"description": "Editorial article layouts for long-form stories, interviews, and analysis.",
"registryDependencies": [
"@fulldev/avatar",
"@fulldev/badge",
"@fulldev/section"
],
"files": [
{
"path": "src/components/blocks/article-1.astro",
"content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n author,\n image,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"mx-auto max-w-2xl gap-8\">\n <div class=\"mx-auto flex w-full max-w-2xl flex-col gap-6\">\n {badge && (\n <Badge variant=\"secondary\" class=\"w-fit\">\n {badge}\n </Badge>\n )}\n <div class=\"flex flex-col gap-4\">\n <h1 class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\">\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\">\n <AvatarImage src={author.image} alt={author.name} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{author.name}</p>\n <p class=\"text-muted-foreground text-xs\">{author.date}</p>\n </div>\n </div>\n </div>\n\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n />\n\n <article class=\"mx-auto flex w-full max-w-2xl flex-col gap-6 text-base leading-8\">\n <slot />\n </article>\n </SectionContainer>\n</Section>\n",
"content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n title,\n description,\n author,\n image,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"max-w-2xl\">\n <article class=\"flex flex-col gap-8\">\n <header class=\"flex flex-col gap-6\">\n <div class=\"flex flex-col gap-4\">\n <h1 class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\">\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\" aria-hidden=\"true\">\n <AvatarImage src={author.image} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{author.name}</p>\n <p class=\"text-muted-foreground text-xs\">{author.date}</p>\n </div>\n </div>\n </header>\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960, 1280]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n loading=\"eager\"\n fetchpriority=\"high\"\n />\n <div class=\"flex flex-col gap-6 text-base leading-8\">\n <slot />\n </div>\n </article>\n </SectionContainer>\n</Section>\n",
"type": "registry:block"
}
],
Expand Down
3 changes: 1 addition & 2 deletions public/r/article-2.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
"description": "Editorial article layouts for long-form stories, interviews, and analysis.",
"registryDependencies": [
"@fulldev/avatar",
"@fulldev/badge",
"@fulldev/section"
],
"files": [
{
"path": "src/components/blocks/article-2.astro",
"content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n readingTime: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n author,\n image,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"mx-auto max-w-2xl items-center gap-8 text-center\">\n <div class=\"mx-auto flex w-full max-w-2xl flex-col items-center gap-6\">\n {badge && <Badge variant=\"secondary\">{badge}</Badge>}\n <div class=\"flex flex-col gap-4\">\n <h1 class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\">\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\">\n <AvatarImage src={author.image} alt={author.name} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col text-left\">\n <p class=\"text-sm font-medium\">\n {author.name}{\" \"}\n <span class=\"text-muted-foreground font-normal\">\n &middot; {author.date}\n </span>\n </p>\n <p class=\"text-muted-foreground text-xs\">{author.readingTime}</p>\n </div>\n </div>\n </div>\n\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n />\n\n <article class=\"mx-auto flex w-full max-w-2xl flex-col gap-6 text-left text-base leading-8\">\n <slot />\n </article>\n </SectionContainer>\n</Section>\n",
"content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n readingTime: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n title,\n description,\n author,\n image,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"max-w-2xl\">\n <article class=\"flex flex-col gap-8\">\n <header class=\"flex flex-col items-center gap-6 text-center\">\n <div class=\"flex flex-col gap-4\">\n <h1 class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\">\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\" aria-hidden=\"true\">\n <AvatarImage src={author.image} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col text-left\">\n <p class=\"text-sm font-medium\">\n {author.name}{\" \"}\n <span class=\"text-muted-foreground font-normal\">\n &middot; {author.date}\n </span>\n </p>\n <p class=\"text-muted-foreground text-xs\">{author.readingTime}</p>\n </div>\n </div>\n </header>\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960, 1280]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n loading=\"eager\"\n fetchpriority=\"high\"\n />\n <div class=\"flex flex-col gap-6 text-base leading-8\">\n <slot />\n </div>\n </article>\n </SectionContainer>\n</Section>\n",
"type": "registry:block"
}
],
Expand Down
Loading
Loading