From 917276ffd0392be543800f74636ac6d284b63a20 Mon Sep 17 00:00:00 2001 From: kudindmitriy Date: Tue, 27 Jan 2026 12:27:34 +0200 Subject: [PATCH] Content edit: set hero title to Sub, buds! --- registry.zip | Bin 0 -> 340011 bytes registry/README.md | 84 + registry/components/AboutMetric.json | 49 + .../components/AnimatedAuroraBackground.json | 21 + .../components/AnimatedGridBackground.json | 25 + registry/components/AuroraBackground.json | 20 + registry/components/AvatarGroup.json | 33 + registry/components/BlogCardEleven.json | 65 + registry/components/BlogCardFive.json | 108 + registry/components/BlogCardOne.json | 64 + registry/components/BlogCardSix.json | 99 + registry/components/BlogCardThree.json | 67 + registry/components/BlogCardTwo.json | 64 + registry/components/BlurBottomBackground.json | 19 + registry/components/ButtonBounceEffect.json | 33 + .../components/ButtonDirectionalHover.json | 33 + registry/components/ButtonElasticEffect.json | 33 + registry/components/ButtonExpandHover.json | 33 + registry/components/ButtonHoverBubble.json | 33 + registry/components/ButtonHoverMagnetic.json | 34 + registry/components/ButtonIconArrow.json | 33 + registry/components/ButtonShiftHover.json | 35 + registry/components/ButtonTextShift.json | 33 + registry/components/ButtonTextStagger.json | 33 + registry/components/ButtonTextUnderline.json | 33 + registry/components/CardStack.json | 55 + .../components/CircleGradientBackground.json | 20 + registry/components/ContactCenter.json | 73 + registry/components/ContactFaq.json | 70 + registry/components/ContactForm.json | 73 + registry/components/ContactSplit.json | 78 + registry/components/ContactSplitForm.json | 57 + registry/components/ContactText.json | 48 + registry/components/DotGridBackground.json | 23 + .../components/DownwardRaysBackground.json | 26 + registry/components/EmailSignupForm.json | 39 + registry/components/FaqBase.json | 72 + registry/components/FaqDouble.json | 71 + registry/components/FaqSplitMedia.json | 98 + registry/components/FaqSplitText.json | 71 + registry/components/FeatureCardEight.json | 111 + registry/components/FeatureCardMedia.json | 70 + registry/components/FeatureCardNine.json | 130 ++ registry/components/FeatureCardNineteen.json | 111 + registry/components/FeatureCardOne.json | 73 + registry/components/FeatureCardSeven.json | 103 + registry/components/FeatureCardSix.json | 102 + registry/components/FeatureCardSixteen.json | 80 + registry/components/FeatureCardThree.json | 90 + registry/components/FeatureCardTwelve.json | 98 + registry/components/FeatureCardTwentyOne.json | 86 + registry/components/FeatureProcessSteps.json | 67 + .../FloatingGradientBackground.json | 19 + registry/components/FluidBackground.json | 19 + registry/components/FooterBase.json | 71 + registry/components/FooterBaseCard.json | 54 + registry/components/FooterBaseReveal.json | 62 + registry/components/FooterCard.json | 53 + registry/components/FooterLogoEmphasis.json | 61 + registry/components/FooterLogoReveal.json | 37 + registry/components/FooterMedia.json | 86 + registry/components/FooterSimple.json | 68 + registry/components/Globe.json | 27 + .../components/GradientBarsBackground.json | 25 + registry/components/GridBackround.json | 23 + registry/components/HeroBillboard.json | 85 + .../components/HeroBillboardCarousel.json | 75 + registry/components/HeroBillboardGallery.json | 75 + .../HeroBillboardRotatedCarousel.json | 80 + registry/components/HeroBillboardScroll.json | 100 + registry/components/HeroCarouselLogo.json | 78 + registry/components/HeroLogo.json | 82 + registry/components/HeroLogoBillboard.json | 72 + .../components/HeroLogoBillboardSplit.json | 91 + registry/components/HeroOverlay.json | 105 + registry/components/HeroSplit.json | 96 + registry/components/HeroSplitKpi.json | 105 + .../components/InlineImageSplitTextAbout.json | 61 + registry/components/Input.json | 35 + registry/components/MediaAbout.json | 84 + registry/components/MediaSplitTabsAbout.json | 90 + registry/components/MetricCardEleven.json | 95 + registry/components/MetricCardFourteen.json | 69 + registry/components/MetricCardOne.json | 91 + registry/components/MetricCardSeven.json | 90 + registry/components/MetricCardTen.json | 106 + registry/components/MetricCardThree.json | 85 + registry/components/MetricCardTwo.json | 79 + .../components/MetricSplitMediaAbout.json | 63 + .../NavbarLayoutFloatingInline.json | 69 + .../NavbarLayoutFloatingOverlay.json | 69 + registry/components/NavbarStyleApple.json | 51 + registry/components/NavbarStyleCentered.json | 72 + .../components/NavbarStyleFullscreen.json | 67 + registry/components/NavbarStyleMinimal.json | 45 + registry/components/PlainBackground.json | 18 + registry/components/PricingCardEight.json | 84 + registry/components/PricingCardFive.json | 106 + registry/components/PricingCardNine.json | 99 + registry/components/PricingCardOne.json | 100 + registry/components/PricingCardThree.json | 111 + registry/components/PricingCardTwo.json | 111 + registry/components/ProductCardFour.json | 92 + registry/components/ProductCardOne.json | 89 + registry/components/ProductCardThree.json | 94 + registry/components/ProductCardTwo.json | 106 + .../components/RadialGradientBackground.json | 24 + .../components/RotatedRaysBackground.json | 25 + registry/components/SplitAbout.json | 95 + registry/components/TeamCardEleven.json | 110 + registry/components/TeamCardFive.json | 106 + registry/components/TeamCardOne.json | 89 + registry/components/TeamCardSix.json | 91 + registry/components/TeamCardTen.json | 74 + registry/components/TeamCardTwo.json | 106 + registry/components/TestimonialAboutCard.json | 75 + .../components/TestimonialCardFifteen.json | 63 + registry/components/TestimonialCardFive.json | 137 ++ registry/components/TestimonialCardOne.json | 103 + registry/components/TestimonialCardSix.json | 108 + registry/components/TestimonialCardTen.json | 109 + .../components/TestimonialCardThirteen.json | 101 + .../components/TestimonialCardTwelve.json | 80 + registry/components/TestimonialCardTwo.json | 100 + registry/components/TextAbout.json | 45 + registry/components/TextAnimation.json | 35 + registry/components/TextBox.json | 56 + registry/components/TextNumberCount.json | 39 + registry/components/TextSplitAbout.json | 58 + registry/components/Textarea.json | 35 + registry/components/TimelineCardStack.json | 63 + .../TimelineHorizontalCardStack.json | 88 + registry/components/TimelinePhoneView.json | 69 + registry/components/TimelineProcessFlow.json | 80 + registry/index.json | 2000 +++++++++++++++++ registry/intents.json | 174 ++ registry/schemas/AboutMetric.schema.json | 17 + .../AnimatedAuroraBackground.schema.json | 8 + .../AnimatedGridBackground.schema.json | 10 + registry/schemas/AuroraBackground.schema.json | 6 + registry/schemas/AvatarGroup.schema.json | 12 + registry/schemas/BlogCardEleven.schema.json | 36 + registry/schemas/BlogCardFive.schema.json | 35 + registry/schemas/BlogCardOne.schema.json | 42 + registry/schemas/BlogCardSix.schema.json | 40 + registry/schemas/BlogCardThree.schema.json | 39 + registry/schemas/BlogCardTwo.schema.json | 40 + .../schemas/BlurBottomBackground.schema.json | 6 + .../schemas/ButtonBounceEffect.schema.json | 14 + .../ButtonDirectionalHover.schema.json | 15 + .../schemas/ButtonElasticEffect.schema.json | 13 + .../schemas/ButtonExpandHover.schema.json | 15 + .../schemas/ButtonHoverBubble.schema.json | 15 + .../schemas/ButtonHoverMagnetic.schema.json | 14 + registry/schemas/ButtonIconArrow.schema.json | 14 + registry/schemas/ButtonShiftHover.schema.json | 14 + registry/schemas/ButtonTextShift.schema.json | 14 + .../schemas/ButtonTextStagger.schema.json | 14 + .../schemas/ButtonTextUnderline.schema.json | 12 + registry/schemas/CardStack.schema.json | 33 + .../CircleGradientBackground.schema.json | 7 + registry/schemas/ContactCenter.schema.json | 27 + registry/schemas/ContactFaq.schema.json | 31 + registry/schemas/ContactForm.schema.json | 24 + registry/schemas/ContactSplit.schema.json | 35 + registry/schemas/ContactSplitForm.schema.json | 28 + registry/schemas/ContactText.schema.json | 16 + .../schemas/DotGridBackground.schema.json | 8 + .../DownwardRaysBackground.schema.json | 9 + registry/schemas/EmailSignupForm.schema.json | 12 + registry/schemas/FaqBase.schema.json | 35 + registry/schemas/FaqDouble.schema.json | 34 + registry/schemas/FaqSplitMedia.schema.json | 43 + registry/schemas/FaqSplitText.schema.json | 30 + registry/schemas/FeatureCardEight.schema.json | 34 + registry/schemas/FeatureCardMedia.schema.json | 42 + registry/schemas/FeatureCardNine.schema.json | 38 + .../schemas/FeatureCardNineteen.schema.json | 34 + registry/schemas/FeatureCardOne.schema.json | 39 + registry/schemas/FeatureCardSeven.schema.json | 34 + registry/schemas/FeatureCardSix.schema.json | 32 + .../schemas/FeatureCardSixteen.schema.json | 34 + registry/schemas/FeatureCardThree.schema.json | 37 + .../schemas/FeatureCardTwelve.schema.json | 35 + .../schemas/FeatureCardTwentyOne.schema.json | 39 + .../schemas/FeatureProcessSteps.schema.json | 32 + .../FloatingGradientBackground.schema.json | 6 + registry/schemas/FluidBackground.schema.json | 6 + registry/schemas/FooterBase.schema.json | 20 + registry/schemas/FooterBaseCard.schema.json | 21 + registry/schemas/FooterBaseReveal.schema.json | 21 + registry/schemas/FooterCard.schema.json | 19 + .../schemas/FooterLogoEmphasis.schema.json | 16 + registry/schemas/FooterLogoReveal.schema.json | 12 + registry/schemas/FooterMedia.schema.json | 26 + registry/schemas/FooterSimple.schema.json | 19 + registry/schemas/Globe.schema.json | 7 + .../GradientBarsBackground.schema.json | 10 + registry/schemas/GridBackround.schema.json | 8 + registry/schemas/HeroBillboard.schema.json | 26 + .../schemas/HeroBillboardCarousel.schema.json | 22 + .../schemas/HeroBillboardGallery.schema.json | 23 + .../HeroBillboardRotatedCarousel.schema.json | 24 + .../schemas/HeroBillboardScroll.schema.json | 27 + registry/schemas/HeroCarouselLogo.schema.json | 27 + registry/schemas/HeroLogo.schema.json | 28 + .../schemas/HeroLogoBillboard.schema.json | 23 + .../HeroLogoBillboardSplit.schema.json | 28 + registry/schemas/HeroOverlay.schema.json | 31 + registry/schemas/HeroSplit.schema.json | 31 + registry/schemas/HeroSplitKpi.schema.json | 35 + .../InlineImageSplitTextAbout.schema.json | 17 + registry/schemas/Input.schema.json | 13 + registry/schemas/MediaAbout.schema.json | 26 + .../schemas/MediaSplitTabsAbout.schema.json | 27 + registry/schemas/MetricCardEleven.schema.json | 34 + .../schemas/MetricCardFourteen.schema.json | 18 + registry/schemas/MetricCardOne.schema.json | 39 + registry/schemas/MetricCardSeven.schema.json | 38 + registry/schemas/MetricCardTen.schema.json | 40 + registry/schemas/MetricCardThree.schema.json | 37 + registry/schemas/MetricCardTwo.schema.json | 36 + .../schemas/MetricSplitMediaAbout.schema.json | 31 + .../NavbarLayoutFloatingInline.schema.json | 12 + .../NavbarLayoutFloatingOverlay.schema.json | 11 + registry/schemas/NavbarStyleApple.schema.json | 7 + .../schemas/NavbarStyleCentered.schema.json | 9 + .../schemas/NavbarStyleFullscreen.schema.json | 10 + .../schemas/NavbarStyleMinimal.schema.json | 10 + registry/schemas/PlainBackground.schema.json | 6 + registry/schemas/PricingCardEight.schema.json | 40 + registry/schemas/PricingCardFive.schema.json | 40 + registry/schemas/PricingCardNine.schema.json | 39 + registry/schemas/PricingCardOne.schema.json | 38 + registry/schemas/PricingCardThree.schema.json | 40 + registry/schemas/PricingCardTwo.schema.json | 40 + registry/schemas/ProductCardFour.schema.json | 39 + registry/schemas/ProductCardOne.schema.json | 37 + registry/schemas/ProductCardThree.schema.json | 37 + registry/schemas/ProductCardTwo.schema.json | 40 + .../RadialGradientBackground.schema.json | 10 + .../schemas/RotatedRaysBackground.schema.json | 9 + registry/schemas/SplitAbout.schema.json | 37 + registry/schemas/TeamCardEleven.schema.json | 34 + registry/schemas/TeamCardFive.schema.json | 33 + registry/schemas/TeamCardOne.schema.json | 38 + registry/schemas/TeamCardSix.schema.json | 38 + registry/schemas/TeamCardTen.schema.json | 20 + registry/schemas/TeamCardTwo.schema.json | 41 + .../schemas/TestimonialAboutCard.schema.json | 30 + .../TestimonialCardFifteen.schema.json | 19 + .../schemas/TestimonialCardFive.schema.json | 38 + .../schemas/TestimonialCardOne.schema.json | 40 + .../schemas/TestimonialCardSix.schema.json | 38 + .../schemas/TestimonialCardTen.schema.json | 36 + .../TestimonialCardThirteen.schema.json | 42 + .../schemas/TestimonialCardTwelve.schema.json | 18 + .../schemas/TestimonialCardTwo.schema.json | 39 + registry/schemas/TextAbout.schema.json | 15 + registry/schemas/TextAnimation.schema.json | 16 + registry/schemas/TextBox.schema.json | 28 + registry/schemas/TextNumberCount.schema.json | 15 + registry/schemas/TextSplitAbout.schema.json | 18 + registry/schemas/Textarea.schema.json | 13 + .../schemas/TimelineCardStack.schema.json | 25 + .../TimelineHorizontalCardStack.schema.json | 30 + .../schemas/TimelinePhoneView.schema.json | 33 + .../schemas/TimelineProcessFlow.schema.json | 31 + src/app/page.tsx | 33 +- 269 files changed, 14777 insertions(+), 11 deletions(-) create mode 100644 registry.zip create mode 100644 registry/README.md create mode 100644 registry/components/AboutMetric.json create mode 100644 registry/components/AnimatedAuroraBackground.json create mode 100644 registry/components/AnimatedGridBackground.json create mode 100644 registry/components/AuroraBackground.json create mode 100644 registry/components/AvatarGroup.json create mode 100644 registry/components/BlogCardEleven.json create mode 100644 registry/components/BlogCardFive.json create mode 100644 registry/components/BlogCardOne.json create mode 100644 registry/components/BlogCardSix.json create mode 100644 registry/components/BlogCardThree.json create mode 100644 registry/components/BlogCardTwo.json create mode 100644 registry/components/BlurBottomBackground.json create mode 100644 registry/components/ButtonBounceEffect.json create mode 100644 registry/components/ButtonDirectionalHover.json create mode 100644 registry/components/ButtonElasticEffect.json create mode 100644 registry/components/ButtonExpandHover.json create mode 100644 registry/components/ButtonHoverBubble.json create mode 100644 registry/components/ButtonHoverMagnetic.json create mode 100644 registry/components/ButtonIconArrow.json create mode 100644 registry/components/ButtonShiftHover.json create mode 100644 registry/components/ButtonTextShift.json create mode 100644 registry/components/ButtonTextStagger.json create mode 100644 registry/components/ButtonTextUnderline.json create mode 100644 registry/components/CardStack.json create mode 100644 registry/components/CircleGradientBackground.json create mode 100644 registry/components/ContactCenter.json create mode 100644 registry/components/ContactFaq.json create mode 100644 registry/components/ContactForm.json create mode 100644 registry/components/ContactSplit.json create mode 100644 registry/components/ContactSplitForm.json create mode 100644 registry/components/ContactText.json create mode 100644 registry/components/DotGridBackground.json create mode 100644 registry/components/DownwardRaysBackground.json create mode 100644 registry/components/EmailSignupForm.json create mode 100644 registry/components/FaqBase.json create mode 100644 registry/components/FaqDouble.json create mode 100644 registry/components/FaqSplitMedia.json create mode 100644 registry/components/FaqSplitText.json create mode 100644 registry/components/FeatureCardEight.json create mode 100644 registry/components/FeatureCardMedia.json create mode 100644 registry/components/FeatureCardNine.json create mode 100644 registry/components/FeatureCardNineteen.json create mode 100644 registry/components/FeatureCardOne.json create mode 100644 registry/components/FeatureCardSeven.json create mode 100644 registry/components/FeatureCardSix.json create mode 100644 registry/components/FeatureCardSixteen.json create mode 100644 registry/components/FeatureCardThree.json create mode 100644 registry/components/FeatureCardTwelve.json create mode 100644 registry/components/FeatureCardTwentyOne.json create mode 100644 registry/components/FeatureProcessSteps.json create mode 100644 registry/components/FloatingGradientBackground.json create mode 100644 registry/components/FluidBackground.json create mode 100644 registry/components/FooterBase.json create mode 100644 registry/components/FooterBaseCard.json create mode 100644 registry/components/FooterBaseReveal.json create mode 100644 registry/components/FooterCard.json create mode 100644 registry/components/FooterLogoEmphasis.json create mode 100644 registry/components/FooterLogoReveal.json create mode 100644 registry/components/FooterMedia.json create mode 100644 registry/components/FooterSimple.json create mode 100644 registry/components/Globe.json create mode 100644 registry/components/GradientBarsBackground.json create mode 100644 registry/components/GridBackround.json create mode 100644 registry/components/HeroBillboard.json create mode 100644 registry/components/HeroBillboardCarousel.json create mode 100644 registry/components/HeroBillboardGallery.json create mode 100644 registry/components/HeroBillboardRotatedCarousel.json create mode 100644 registry/components/HeroBillboardScroll.json create mode 100644 registry/components/HeroCarouselLogo.json create mode 100644 registry/components/HeroLogo.json create mode 100644 registry/components/HeroLogoBillboard.json create mode 100644 registry/components/HeroLogoBillboardSplit.json create mode 100644 registry/components/HeroOverlay.json create mode 100644 registry/components/HeroSplit.json create mode 100644 registry/components/HeroSplitKpi.json create mode 100644 registry/components/InlineImageSplitTextAbout.json create mode 100644 registry/components/Input.json create mode 100644 registry/components/MediaAbout.json create mode 100644 registry/components/MediaSplitTabsAbout.json create mode 100644 registry/components/MetricCardEleven.json create mode 100644 registry/components/MetricCardFourteen.json create mode 100644 registry/components/MetricCardOne.json create mode 100644 registry/components/MetricCardSeven.json create mode 100644 registry/components/MetricCardTen.json create mode 100644 registry/components/MetricCardThree.json create mode 100644 registry/components/MetricCardTwo.json create mode 100644 registry/components/MetricSplitMediaAbout.json create mode 100644 registry/components/NavbarLayoutFloatingInline.json create mode 100644 registry/components/NavbarLayoutFloatingOverlay.json create mode 100644 registry/components/NavbarStyleApple.json create mode 100644 registry/components/NavbarStyleCentered.json create mode 100644 registry/components/NavbarStyleFullscreen.json create mode 100644 registry/components/NavbarStyleMinimal.json create mode 100644 registry/components/PlainBackground.json create mode 100644 registry/components/PricingCardEight.json create mode 100644 registry/components/PricingCardFive.json create mode 100644 registry/components/PricingCardNine.json create mode 100644 registry/components/PricingCardOne.json create mode 100644 registry/components/PricingCardThree.json create mode 100644 registry/components/PricingCardTwo.json create mode 100644 registry/components/ProductCardFour.json create mode 100644 registry/components/ProductCardOne.json create mode 100644 registry/components/ProductCardThree.json create mode 100644 registry/components/ProductCardTwo.json create mode 100644 registry/components/RadialGradientBackground.json create mode 100644 registry/components/RotatedRaysBackground.json create mode 100644 registry/components/SplitAbout.json create mode 100644 registry/components/TeamCardEleven.json create mode 100644 registry/components/TeamCardFive.json create mode 100644 registry/components/TeamCardOne.json create mode 100644 registry/components/TeamCardSix.json create mode 100644 registry/components/TeamCardTen.json create mode 100644 registry/components/TeamCardTwo.json create mode 100644 registry/components/TestimonialAboutCard.json create mode 100644 registry/components/TestimonialCardFifteen.json create mode 100644 registry/components/TestimonialCardFive.json create mode 100644 registry/components/TestimonialCardOne.json create mode 100644 registry/components/TestimonialCardSix.json create mode 100644 registry/components/TestimonialCardTen.json create mode 100644 registry/components/TestimonialCardThirteen.json create mode 100644 registry/components/TestimonialCardTwelve.json create mode 100644 registry/components/TestimonialCardTwo.json create mode 100644 registry/components/TextAbout.json create mode 100644 registry/components/TextAnimation.json create mode 100644 registry/components/TextBox.json create mode 100644 registry/components/TextNumberCount.json create mode 100644 registry/components/TextSplitAbout.json create mode 100644 registry/components/Textarea.json create mode 100644 registry/components/TimelineCardStack.json create mode 100644 registry/components/TimelineHorizontalCardStack.json create mode 100644 registry/components/TimelinePhoneView.json create mode 100644 registry/components/TimelineProcessFlow.json create mode 100644 registry/index.json create mode 100644 registry/intents.json create mode 100644 registry/schemas/AboutMetric.schema.json create mode 100644 registry/schemas/AnimatedAuroraBackground.schema.json create mode 100644 registry/schemas/AnimatedGridBackground.schema.json create mode 100644 registry/schemas/AuroraBackground.schema.json create mode 100644 registry/schemas/AvatarGroup.schema.json create mode 100644 registry/schemas/BlogCardEleven.schema.json create mode 100644 registry/schemas/BlogCardFive.schema.json create mode 100644 registry/schemas/BlogCardOne.schema.json create mode 100644 registry/schemas/BlogCardSix.schema.json create mode 100644 registry/schemas/BlogCardThree.schema.json create mode 100644 registry/schemas/BlogCardTwo.schema.json create mode 100644 registry/schemas/BlurBottomBackground.schema.json create mode 100644 registry/schemas/ButtonBounceEffect.schema.json create mode 100644 registry/schemas/ButtonDirectionalHover.schema.json create mode 100644 registry/schemas/ButtonElasticEffect.schema.json create mode 100644 registry/schemas/ButtonExpandHover.schema.json create mode 100644 registry/schemas/ButtonHoverBubble.schema.json create mode 100644 registry/schemas/ButtonHoverMagnetic.schema.json create mode 100644 registry/schemas/ButtonIconArrow.schema.json create mode 100644 registry/schemas/ButtonShiftHover.schema.json create mode 100644 registry/schemas/ButtonTextShift.schema.json create mode 100644 registry/schemas/ButtonTextStagger.schema.json create mode 100644 registry/schemas/ButtonTextUnderline.schema.json create mode 100644 registry/schemas/CardStack.schema.json create mode 100644 registry/schemas/CircleGradientBackground.schema.json create mode 100644 registry/schemas/ContactCenter.schema.json create mode 100644 registry/schemas/ContactFaq.schema.json create mode 100644 registry/schemas/ContactForm.schema.json create mode 100644 registry/schemas/ContactSplit.schema.json create mode 100644 registry/schemas/ContactSplitForm.schema.json create mode 100644 registry/schemas/ContactText.schema.json create mode 100644 registry/schemas/DotGridBackground.schema.json create mode 100644 registry/schemas/DownwardRaysBackground.schema.json create mode 100644 registry/schemas/EmailSignupForm.schema.json create mode 100644 registry/schemas/FaqBase.schema.json create mode 100644 registry/schemas/FaqDouble.schema.json create mode 100644 registry/schemas/FaqSplitMedia.schema.json create mode 100644 registry/schemas/FaqSplitText.schema.json create mode 100644 registry/schemas/FeatureCardEight.schema.json create mode 100644 registry/schemas/FeatureCardMedia.schema.json create mode 100644 registry/schemas/FeatureCardNine.schema.json create mode 100644 registry/schemas/FeatureCardNineteen.schema.json create mode 100644 registry/schemas/FeatureCardOne.schema.json create mode 100644 registry/schemas/FeatureCardSeven.schema.json create mode 100644 registry/schemas/FeatureCardSix.schema.json create mode 100644 registry/schemas/FeatureCardSixteen.schema.json create mode 100644 registry/schemas/FeatureCardThree.schema.json create mode 100644 registry/schemas/FeatureCardTwelve.schema.json create mode 100644 registry/schemas/FeatureCardTwentyOne.schema.json create mode 100644 registry/schemas/FeatureProcessSteps.schema.json create mode 100644 registry/schemas/FloatingGradientBackground.schema.json create mode 100644 registry/schemas/FluidBackground.schema.json create mode 100644 registry/schemas/FooterBase.schema.json create mode 100644 registry/schemas/FooterBaseCard.schema.json create mode 100644 registry/schemas/FooterBaseReveal.schema.json create mode 100644 registry/schemas/FooterCard.schema.json create mode 100644 registry/schemas/FooterLogoEmphasis.schema.json create mode 100644 registry/schemas/FooterLogoReveal.schema.json create mode 100644 registry/schemas/FooterMedia.schema.json create mode 100644 registry/schemas/FooterSimple.schema.json create mode 100644 registry/schemas/Globe.schema.json create mode 100644 registry/schemas/GradientBarsBackground.schema.json create mode 100644 registry/schemas/GridBackround.schema.json create mode 100644 registry/schemas/HeroBillboard.schema.json create mode 100644 registry/schemas/HeroBillboardCarousel.schema.json create mode 100644 registry/schemas/HeroBillboardGallery.schema.json create mode 100644 registry/schemas/HeroBillboardRotatedCarousel.schema.json create mode 100644 registry/schemas/HeroBillboardScroll.schema.json create mode 100644 registry/schemas/HeroCarouselLogo.schema.json create mode 100644 registry/schemas/HeroLogo.schema.json create mode 100644 registry/schemas/HeroLogoBillboard.schema.json create mode 100644 registry/schemas/HeroLogoBillboardSplit.schema.json create mode 100644 registry/schemas/HeroOverlay.schema.json create mode 100644 registry/schemas/HeroSplit.schema.json create mode 100644 registry/schemas/HeroSplitKpi.schema.json create mode 100644 registry/schemas/InlineImageSplitTextAbout.schema.json create mode 100644 registry/schemas/Input.schema.json create mode 100644 registry/schemas/MediaAbout.schema.json create mode 100644 registry/schemas/MediaSplitTabsAbout.schema.json create mode 100644 registry/schemas/MetricCardEleven.schema.json create mode 100644 registry/schemas/MetricCardFourteen.schema.json create mode 100644 registry/schemas/MetricCardOne.schema.json create mode 100644 registry/schemas/MetricCardSeven.schema.json create mode 100644 registry/schemas/MetricCardTen.schema.json create mode 100644 registry/schemas/MetricCardThree.schema.json create mode 100644 registry/schemas/MetricCardTwo.schema.json create mode 100644 registry/schemas/MetricSplitMediaAbout.schema.json create mode 100644 registry/schemas/NavbarLayoutFloatingInline.schema.json create mode 100644 registry/schemas/NavbarLayoutFloatingOverlay.schema.json create mode 100644 registry/schemas/NavbarStyleApple.schema.json create mode 100644 registry/schemas/NavbarStyleCentered.schema.json create mode 100644 registry/schemas/NavbarStyleFullscreen.schema.json create mode 100644 registry/schemas/NavbarStyleMinimal.schema.json create mode 100644 registry/schemas/PlainBackground.schema.json create mode 100644 registry/schemas/PricingCardEight.schema.json create mode 100644 registry/schemas/PricingCardFive.schema.json create mode 100644 registry/schemas/PricingCardNine.schema.json create mode 100644 registry/schemas/PricingCardOne.schema.json create mode 100644 registry/schemas/PricingCardThree.schema.json create mode 100644 registry/schemas/PricingCardTwo.schema.json create mode 100644 registry/schemas/ProductCardFour.schema.json create mode 100644 registry/schemas/ProductCardOne.schema.json create mode 100644 registry/schemas/ProductCardThree.schema.json create mode 100644 registry/schemas/ProductCardTwo.schema.json create mode 100644 registry/schemas/RadialGradientBackground.schema.json create mode 100644 registry/schemas/RotatedRaysBackground.schema.json create mode 100644 registry/schemas/SplitAbout.schema.json create mode 100644 registry/schemas/TeamCardEleven.schema.json create mode 100644 registry/schemas/TeamCardFive.schema.json create mode 100644 registry/schemas/TeamCardOne.schema.json create mode 100644 registry/schemas/TeamCardSix.schema.json create mode 100644 registry/schemas/TeamCardTen.schema.json create mode 100644 registry/schemas/TeamCardTwo.schema.json create mode 100644 registry/schemas/TestimonialAboutCard.schema.json create mode 100644 registry/schemas/TestimonialCardFifteen.schema.json create mode 100644 registry/schemas/TestimonialCardFive.schema.json create mode 100644 registry/schemas/TestimonialCardOne.schema.json create mode 100644 registry/schemas/TestimonialCardSix.schema.json create mode 100644 registry/schemas/TestimonialCardTen.schema.json create mode 100644 registry/schemas/TestimonialCardThirteen.schema.json create mode 100644 registry/schemas/TestimonialCardTwelve.schema.json create mode 100644 registry/schemas/TestimonialCardTwo.schema.json create mode 100644 registry/schemas/TextAbout.schema.json create mode 100644 registry/schemas/TextAnimation.schema.json create mode 100644 registry/schemas/TextBox.schema.json create mode 100644 registry/schemas/TextNumberCount.schema.json create mode 100644 registry/schemas/TextSplitAbout.schema.json create mode 100644 registry/schemas/Textarea.schema.json create mode 100644 registry/schemas/TimelineCardStack.schema.json create mode 100644 registry/schemas/TimelineHorizontalCardStack.schema.json create mode 100644 registry/schemas/TimelinePhoneView.schema.json create mode 100644 registry/schemas/TimelineProcessFlow.schema.json diff --git a/registry.zip b/registry.zip new file mode 100644 index 0000000000000000000000000000000000000000..57e1dbdb48d7a52cfe9f1d7aa139f24c17e1d103 GIT binary patch literal 340011 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%0A`PB0-9Rs{HPs=L0{3T_D4MJ{BLD8DQCI+Oi~5 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

2*qo%~yS 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", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'About metrics section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\nimport { TrendingUp, ShoppingCart, Users, Globe } from 'lucide-react';\n\n\n \n", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for about pages", + "Use for company information", + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/AnimatedAuroraBackground.json b/registry/components/AnimatedAuroraBackground.json new file mode 100644 index 0000000..c014a17 --- /dev/null +++ b/registry/components/AnimatedAuroraBackground.json @@ -0,0 +1,21 @@ +{ + "name": "AnimatedAuroraBackground", + "description": "Aurora borealis effect with animated repeating gradients and mix-blend-difference.", + "constraints": {}, + "propsSchema": { + "className?": "string", + "showRadialGradient?": "boolean (default: true)", + "invertColors": "boolean (REQUIRED - true for light backgrounds, false for dark backgrounds)" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/AnimatedGridBackground.json b/registry/components/AnimatedGridBackground.json new file mode 100644 index 0000000..3048590 --- /dev/null +++ b/registry/components/AnimatedGridBackground.json @@ -0,0 +1,25 @@ +{ + "name": "AnimatedGridBackground", + "description": "Grid pattern with animated pulsing squares using Framer Motion and optional 3D perspective.", + "constraints": {}, + "propsSchema": { + "squareSize?": "number (default: 100)", + "numSquares?": "number (default: 50)", + "maxOpacity?": "number (default: 0.15)", + "perspectiveThreeD?": "boolean (default: true)", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/AuroraBackground.json b/registry/components/AuroraBackground.json new file mode 100644 index 0000000..6143169 --- /dev/null +++ b/registry/components/AuroraBackground.json @@ -0,0 +1,20 @@ +{ + "name": "AuroraBackground", + "description": "Aurora borealis-style background with multiple rotated gradient bars and blur effect.", + "constraints": {}, + "propsSchema": { + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/AvatarGroup.json b/registry/components/AvatarGroup.json new file mode 100644 index 0000000..5e84eea --- /dev/null +++ b/registry/components/AvatarGroup.json @@ -0,0 +1,33 @@ +{ + "name": "AvatarGroup", + "description": "Displays a group of user avatars with overlapping layout and optional text label.", + "constraints": { + "textRules": { + "text": { + "required": false, + "example": "Join 1,000+ members", + "minChars": 2, + "maxChars": 50 + } + } + }, + "propsSchema": { + "avatars": "Array<{ src: string, alt?: string }> - User avatar images", + "text?": "string", + "maxVisible?": "number (default: 5)", + "className?": "string", + "ariaLabel?": "string (default: 'User avatars')" + }, + "usageExample": "", + "do": [ + "Use for social proof", + "Use for customer reviews", + "Requires avatars[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/BlogCardEleven.json b/registry/components/BlogCardEleven.json new file mode 100644 index 0000000..9975b67 --- /dev/null +++ b/registry/components/BlogCardEleven.json @@ -0,0 +1,65 @@ +{ + "name": "BlogCardEleven", + "description": "Two-column blog card list with title, author, description, tags, and media.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Latest News", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Stay updated with our latest announcements", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "News", + "minChars": 2, + "maxChars": 30 + } + }, + "itemRules": { + "minItems": 1, + "maxItems": 10, + "recommendedItems": "2-4", + "note": "Each blog requires id, title, author, description, tags array. Media uses discriminated union: either imageSrc (with optional imageAlt) OR videoSrc (with optional videoAriaLabel)." + } + }, + "propsSchema": { + "blogs": "Array<{ id: string, title: string, author: string, description: string, tags: string[], imageSrc?: string, imageAlt?: string, videoSrc?: string, videoAriaLabel?: string, onBlogClick?: () => void }> - Blog card items (requires imageSrc or videoSrc)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string (required)", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string (required)", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault' (required)", + "ariaLabel?": "string (default: 'Blog section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for blog listings", + "Use for article grids", + "Requires blogs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items", + "Do not use more than 10 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/BlogCardFive.json b/registry/components/BlogCardFive.json new file mode 100644 index 0000000..680f0cc --- /dev/null +++ b/registry/components/BlogCardFive.json @@ -0,0 +1,108 @@ +{ + "name": "BlogCardFive", + "description": "Blog section with TextBox header and fixed 2-column grid layout with horizontal blog cards and metadata items.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Latest Articles", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Discover our latest insights and stories", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Blog", + "minChars": 2, + "maxChars": 30 + } + }, + "blogRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "title": { + "required": true, + "example": "The Future of Web Development: Exploring New Technologies and Trends", + "minChars": 10, + "maxChars": 150, + "note": "Blog post title shown at text-3xl size, supports longer titles" + }, + "items": { + "required": true, + "minItems": 1, + "maxItems": 5, + "structure": "string[]", + "example": "['Technology', 'Jan 15, 2025', '5 min read']", + "note": "Flexible metadata items (category, date, author, read time, etc.) displayed inline with bullet separators" + }, + "imageSrc": { + "required": false, + "example": "/blog-1.jpg", + "note": "Either imageSrc or videoSrc should be provided" + }, + "videoSrc": { + "required": false, + "example": "/blog-1.mp4", + "note": "Either imageSrc or videoSrc should be provided" + }, + "imageAlt": { + "required": false, + "example": "Future of web development illustration", + "note": "Falls back to blog title if not provided" + }, + "videoAriaLabel": { + "required": false, + "example": "Future of web development video", + "note": "Falls back to blog title if not provided" + } + }, + "itemRules": { + "minItems": 1, + "maxItems": 10, + "recommendedItems": "2-6", + "note": "Always displays as 2-column grid on desktop, 1 column on mobile. Works best with even number of posts (2, 4, 6)." + } + }, + "propsSchema": { + "blogs": "Array<{ id: string, title: string, items: string[], imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Blog section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for blog listings", + "Use for article grids", + "Requires blogs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items", + "Do not use more than 10 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/BlogCardOne.json b/registry/components/BlogCardOne.json new file mode 100644 index 0000000..bababbf --- /dev/null +++ b/registry/components/BlogCardOne.json @@ -0,0 +1,64 @@ +{ + "name": "BlogCardOne", + "description": "Blog section with card grid/carousel layout featuring image, category, title, excerpt, and author info.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Latest Articles", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Insights and updates from our team", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Blog", + "minChars": 2, + "maxChars": 30 + } + }, + "blogRules": { + "blogs": { + "required": true, + "minItems": 1, + "example": "[{\"id\": \"1\", \"category\": \"Design\", \"title\": \"UX review presentations\", \"excerpt\": \"How to create compelling presentations\", \"imageSrc\": \"/blog-1.jpg\", \"authorName\": \"John Doe\", \"authorAvatar\": \"/avatar-1.jpg\", \"date\": \"20 Jan 2025\"}]", + "note": "Array of blog items. Each item requires id, category, title, excerpt, imageSrc, authorName, authorAvatar, and date." + } + } + }, + "propsSchema": { + "blogs": "Array<{ id: string, category: string, title: string, excerpt: string, imageSrc: string, imageAlt?: string, authorName: string, authorAvatar: string, date: string, onBlogClick?: () => void }> - Blog card items", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Blog section')", + "className?": "string" + }, + "usageExample": " console.log('clicked')}]} title=\"Latest Articles\" description=\"Stay updated with our latest insights\" textboxLayout=\"default\" useInvertedBackground={\"noInvert\"} animationType=\"slide-up\" carouselMode=\"buttons\" />", + "do": [ + "Use for blog listings", + "Use for article grids", + "Requires blogs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/BlogCardSix.json b/registry/components/BlogCardSix.json new file mode 100644 index 0000000..953e452 --- /dev/null +++ b/registry/components/BlogCardSix.json @@ -0,0 +1,99 @@ +{ + "name": "BlogCardSix", + "description": "Blog section with separate media and card layout, featuring tags and arrow navigation.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Recent articles", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Stay updated with the latest trends and insights", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Blog", + "minChars": 2, + "maxChars": 30 + } + }, + "blogRules": { + "id": { + "required": true, + "example": "1", + "note": "Unique identifier for the blog post" + }, + "title": { + "required": true, + "example": "Discover the essential features of our app", + "minChars": 10, + "maxChars": 100 + }, + "tags": { + "required": true, + "minItems": 1, + "maxItems": 4, + "structure": "string[]", + "example": "['Features', 'Jan 29, 2025']", + "note": "Array of tag strings displayed using Tag component" + }, + "imageSrc": { + "required": false, + "example": "/blog-1.jpg", + "note": "Either imageSrc or videoSrc should be provided" + }, + "videoSrc": { + "required": false, + "example": "/blog-1.mp4", + "note": "Either imageSrc or videoSrc should be provided" + }, + "imageAlt": { + "required": false, + "example": "Blog post preview image", + "note": "Falls back to blog title if not provided" + }, + "videoAriaLabel": { + "required": false, + "example": "Blog post video", + "note": "Falls back to blog title if not provided" + } + } + }, + "propsSchema": { + "blogs": "Array<{ id: string, title: string, tags: string[], imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string, onBlogClick?: () => void }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "ariaLabel?": "string (default: 'Blog section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for blog listings", + "Use for article grids", + "Requires blogs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/BlogCardThree.json b/registry/components/BlogCardThree.json new file mode 100644 index 0000000..5856635 --- /dev/null +++ b/registry/components/BlogCardThree.json @@ -0,0 +1,67 @@ +{ + "name": "BlogCardThree", + "description": "Blog section with vertical card layout featuring tag, title, description, and media with overlay button.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Featured Articles", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Explore our latest insights", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Blog", + "minChars": 2, + "maxChars": 30 + } + }, + "blogRules": { + "blogs": { + "required": true, + "minItems": 1, + "example": "[{\"id\": \"1\", \"category\": \"Software Development\", \"title\": \"Redefining Digital Performance\", \"description\": \"Optimizing speed and scalability\", \"imageSrc\": \"/blog-1.jpg\"}]", + "note": "Array of blog items. Each item requires id, category, title, description, and either imageSrc or videoSrc." + } + } + }, + "propsSchema": { + "blogs": "Array<{ id: string, category: string, categoryIcon?: LucideIcon, title: string, description: string, imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string, onBlogClick?: () => void }> - Blog card items", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-[600px]')", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Blog section')", + "className?": "string" + }, + "usageExample": " console.log('clicked')}]} title=\"Featured Articles\" description=\"Explore our latest insights\" textboxLayout=\"default\" useInvertedBackground={\"noInvert\"} animationType=\"slide-up\" />", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for blog listings", + "Use for article grids", + "Requires blogs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/BlogCardTwo.json b/registry/components/BlogCardTwo.json new file mode 100644 index 0000000..b423359 --- /dev/null +++ b/registry/components/BlogCardTwo.json @@ -0,0 +1,64 @@ +{ + "name": "BlogCardTwo", + "description": "Blog section with card grid/carousel layout featuring image, author/date, title, excerpt, and multiple tags.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Latest Articles", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Insights and updates from our team", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Blog", + "minChars": 2, + "maxChars": 30 + } + }, + "blogRules": { + "blogs": { + "required": true, + "minItems": 1, + "example": "[{\"id\": \"1\", \"tags\": [\"Design\", \"Research\"], \"title\": \"UX review presentations\", \"excerpt\": \"How to create compelling presentations\", \"imageSrc\": \"/blog-1.jpg\", \"authorName\": \"Olivia Rhye\", \"date\": \"20 Jan 2025\"}]", + "note": "Array of blog items. Each item requires id, tags (array), title, excerpt, imageSrc, authorName, and date." + } + } + }, + "propsSchema": { + "blogs": "Array<{ id: string, tags: string[], title: string, excerpt: string, imageSrc: string, imageAlt?: string, authorName: string, date: string, onBlogClick?: () => void }> - Blog card items", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Blog section')", + "className?": "string" + }, + "usageExample": " console.log('clicked')}]} title=\"Latest Articles\" description=\"Stay updated with our latest insights\" textboxLayout=\"default\" useInvertedBackground={\"noInvert\"} animationType=\"slide-up\" carouselMode=\"buttons\" />", + "do": [ + "Use for blog listings", + "Use for article grids", + "Requires blogs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/BlurBottomBackground.json b/registry/components/BlurBottomBackground.json new file mode 100644 index 0000000..0132514 --- /dev/null +++ b/registry/components/BlurBottomBackground.json @@ -0,0 +1,19 @@ +{ + "name": "BlurBottomBackground", + "description": "Backdrop blur effect positioned at the bottom of the page with linear gradient mask.", + "constraints": {}, + "propsSchema": { + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonBounceEffect.json b/registry/components/ButtonBounceEffect.json new file mode 100644 index 0000000..c46ce9b --- /dev/null +++ b/registry/components/ButtonBounceEffect.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonBounceEffect", + "description": "CTA button with bouncing character animation on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Get Started", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonDirectionalHover.json b/registry/components/ButtonDirectionalHover.json new file mode 100644 index 0000000..b4979be --- /dev/null +++ b/registry/components/ButtonDirectionalHover.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonDirectionalHover", + "description": "CTA button with a circle that expands from the mouse entry point on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Get Started", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonElasticEffect.json b/registry/components/ButtonElasticEffect.json new file mode 100644 index 0000000..2f26a22 --- /dev/null +++ b/registry/components/ButtonElasticEffect.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonElasticEffect", + "description": "CTA button with elastic scale animation on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Get Started", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonExpandHover.json b/registry/components/ButtonExpandHover.json new file mode 100644 index 0000000..164f612 --- /dev/null +++ b/registry/components/ButtonExpandHover.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonExpandHover", + "description": "CTA button with expanding background animation from right to left on hover, with a fixed arrow icon.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Get Started", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonHoverBubble.json b/registry/components/ButtonHoverBubble.json new file mode 100644 index 0000000..eae496e --- /dev/null +++ b/registry/components/ButtonHoverBubble.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonHoverBubble", + "description": "CTA button with expanding bubble animation where an arrow icon slides out and the text expands on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Contact Us", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonHoverMagnetic.json b/registry/components/ButtonHoverMagnetic.json new file mode 100644 index 0000000..4b8599e --- /dev/null +++ b/registry/components/ButtonHoverMagnetic.json @@ -0,0 +1,34 @@ +{ + "name": "ButtonHoverMagnetic", + "description": "CTA button that subtly follows the cursor with a magnetic hover effect.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Button", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "strengthFactor?": "number (default: 20)", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonIconArrow.json b/registry/components/ButtonIconArrow.json new file mode 100644 index 0000000..67a33c3 --- /dev/null +++ b/registry/components/ButtonIconArrow.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonIconArrow", + "description": "Button with a trailing arrow icon that transforms on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Button", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonShiftHover.json b/registry/components/ButtonShiftHover.json new file mode 100644 index 0000000..4109308 --- /dev/null +++ b/registry/components/ButtonShiftHover.json @@ -0,0 +1,35 @@ +{ + "name": "ButtonShiftHover", + "description": "CTA button where the label nudges upward on hover and a trailing dot fills from outline to solid.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Get Started", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [ + "Do not use multiple items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonTextShift.json b/registry/components/ButtonTextShift.json new file mode 100644 index 0000000..7c9b7e6 --- /dev/null +++ b/registry/components/ButtonTextShift.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonTextShift", + "description": "CTA button with synchronized character shift animation on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Get Started", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonTextStagger.json b/registry/components/ButtonTextStagger.json new file mode 100644 index 0000000..8c4c724 --- /dev/null +++ b/registry/components/ButtonTextStagger.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonTextStagger", + "description": "CTA button with character stagger animation on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Get Started", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ButtonTextUnderline.json b/registry/components/ButtonTextUnderline.json new file mode 100644 index 0000000..c37ba41 --- /dev/null +++ b/registry/components/ButtonTextUnderline.json @@ -0,0 +1,33 @@ +{ + "name": "ButtonTextUnderline", + "description": "Text-only button where an underline animates in on hover.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Learn more", + "minChars": 2, + "maxChars": 25 + } + } + }, + "propsSchema": { + "text": "string", + "onClick?": "() => void", + "href?": "string - External URLs open in new tab, internal values scroll to section", + "className?": "string", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "type?": "'button' | 'submit' | 'reset' (default: 'button')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/CardStack.json b/registry/components/CardStack.json new file mode 100644 index 0000000..cf886f1 --- /dev/null +++ b/registry/components/CardStack.json @@ -0,0 +1,55 @@ +{ + "name": "CardStack", + "description": "Adaptive layout component that displays children in a grid, timeline, or carousel based on item count and variant.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Features", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Discover our products", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "New", + "minChars": 2, + "maxChars": 30 + } + } + }, + "propsSchema": { + "children": "React.ReactNode", + "mode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant?": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (default: 'uniform-all-items-equal')", + "uniformGridCustomHeightClasses?": "string (default: varies by usage)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title?": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description?": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground?": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Card stack')", + "className?": "string" + }, + "usageExample": "{/* Card components */}", + "do": [ + "Use for general use", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/CircleGradientBackground.json b/registry/components/CircleGradientBackground.json new file mode 100644 index 0000000..8a24188 --- /dev/null +++ b/registry/components/CircleGradientBackground.json @@ -0,0 +1,20 @@ +{ + "name": "CircleGradientBackground", + "description": "Two large gradient circles positioned diagonally in corners.", + "constraints": {}, + "propsSchema": { + "diagonal?": "'primary' | 'secondary' (default: 'primary')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ContactCenter.json b/registry/components/ContactCenter.json new file mode 100644 index 0000000..2d4209b --- /dev/null +++ b/registry/components/ContactCenter.json @@ -0,0 +1,73 @@ +{ + "name": "ContactCenter", + "description": "Centered contact section with tag, animated title and description, email signup form, and terms text.", + "constraints": { + "textRules": { + "tag": { + "required": true, + "example": "Newsletter", + "minChars": 2, + "maxChars": 20 + }, + "title": { + "required": true, + "example": "Medium length heading goes here", + "minChars": 4, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.", + "minChars": 20, + "maxChars": 200 + }, + "inputPlaceholder": { + "required": false, + "default": "Enter your email", + "example": "Your email address", + "minChars": 5, + "maxChars": 30 + }, + "buttonText": { + "required": false, + "default": "Sign Up", + "example": "Subscribe", + "minChars": 2, + "maxChars": 15 + }, + "termsText": { + "required": false, + "default": "By clicking Sign Up you're confirming that you agree with our Terms and Conditions.", + "example": "We respect your privacy. Unsubscribe at any time.", + "minChars": 10, + "maxChars": 150 + } + } + }, + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "tagIcon?": "LucideIcon", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "inputPlaceholder?": "string (default: 'Enter your email')", + "buttonText?": "string (default: 'Sign Up')", + "termsText?": "string (default: 'By clicking Sign Up you're confirming that you agree with our Terms and Conditions.')", + "onSubmit?": "(email: string) => void", + "ariaLabel?": "string (default: 'Contact section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\n\n console.log(email)} />\n", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for contact pages", + "Use for lead generation" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ContactFaq.json b/registry/components/ContactFaq.json new file mode 100644 index 0000000..dd0c9fa --- /dev/null +++ b/registry/components/ContactFaq.json @@ -0,0 +1,70 @@ +{ + "name": "ContactFaq", + "description": "Split-panel contact section with CTA card on left and FAQ accordions on right.", + "constraints": { + "textRules": { + "ctaTitle": { + "required": true, + "example": "Book an intro call", + "minChars": 2, + "maxChars": 50 + }, + "ctaDescription": { + "required": true, + "example": "Let's get started with a brief intro call.", + "minChars": 5, + "maxChars": 100 + } + }, + "faqRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "title": { + "required": true, + "example": "What's included in the subscription?", + "minChars": 5, + "maxChars": 100 + }, + "content": { + "required": true, + "example": "Your subscription covers end-to-end digital design services...", + "minChars": 10, + "maxChars": 500, + "note": "Supports HTML content" + } + } + }, + "propsSchema": { + "faqs": "Array<{ id: string, title: string, content: string }>", + "ctaTitle": "string", + "ctaDescription": "string", + "ctaButton": "{text: string, onClick?: () => void, href?: string}", + "ctaIcon": "LucideIcon (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect on panels)", + "accordionAnimationType?": "'smooth' | 'instant' (default: 'smooth')", + "showCard?": "boolean (default: true - controls accordion card styling)", + "ariaLabel?": "string (default: 'Contact and FAQ section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for contact pages", + "Use for lead generation", + "Use for help pages", + "Use for support sections", + "Requires faqs[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ContactForm.json b/registry/components/ContactForm.json new file mode 100644 index 0000000..7a8e098 --- /dev/null +++ b/registry/components/ContactForm.json @@ -0,0 +1,73 @@ +{ + "name": "ContactForm", + "description": "Complete contact form component with tag, animated title and description, email signup form, and terms text.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Join our newsletter", + "minChars": 4, + "maxChars": 60 + }, + "description": { + "required": true, + "example": "Get the latest updates and exclusive content delivered to your inbox", + "minChars": 10, + "maxChars": 200 + }, + "tag": { + "required": true, + "example": "Newsletter", + "minChars": 2, + "maxChars": 30 + }, + "inputPlaceholder": { + "required": false, + "default": "Enter your email", + "example": "Your email address", + "minChars": 5, + "maxChars": 50 + }, + "buttonText": { + "required": false, + "default": "Sign Up", + "example": "Subscribe", + "minChars": 2, + "maxChars": 15 + }, + "termsText": { + "required": false, + "default": "By clicking Sign Up you're confirming that you agree with our Terms and Conditions.", + "example": "We respect your privacy. Unsubscribe anytime.", + "minChars": 10, + "maxChars": 200 + } + } + }, + "propsSchema": { + "title": "string (required)", + "description": "string (required)", + "tag": "string (required)", + "tagIcon?": "LucideIcon", + "inputPlaceholder?": "string (default: 'Enter your email')", + "buttonText?": "string (default: 'Sign Up')", + "termsText?": "string (default: 'By clicking Sign Up you're confirming that you agree with our Terms and Conditions.')", + "onSubmit?": "(email: string) => void", + "centered?": "boolean (default: false)", + "className?": "string" + }, + "usageExample": " console.log(email)} />", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for contact pages", + "Use for lead generation" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ContactSplit.json b/registry/components/ContactSplit.json new file mode 100644 index 0000000..e68e6b3 --- /dev/null +++ b/registry/components/ContactSplit.json @@ -0,0 +1,78 @@ +{ + "name": "ContactSplit", + "description": "Split layout contact section with tag, animated title and description on one side, media content on the other, and email signup form.", + "constraints": { + "textRules": { + "tag": { + "required": true, + "example": "Newsletter", + "minChars": 2, + "maxChars": 20 + }, + "title": { + "required": true, + "example": "Medium length heading goes here", + "minChars": 4, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.", + "minChars": 20, + "maxChars": 200 + }, + "inputPlaceholder": { + "required": false, + "default": "Enter your email", + "example": "Your email address", + "minChars": 5, + "maxChars": 30 + }, + "buttonText": { + "required": false, + "default": "Sign Up", + "example": "Subscribe", + "minChars": 2, + "maxChars": 15 + }, + "termsText": { + "required": false, + "default": "By clicking Sign Up you're confirming that you agree with our Terms and Conditions.", + "example": "We respect your privacy. Unsubscribe at any time.", + "minChars": 10, + "maxChars": 150 + } + } + }, + "propsSchema": { + "tag": "string", + "title": "string", + "description": "string", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Contact section video')", + "mediaPosition?": "'left' | 'right' (default: 'right')", + "tagIcon?": "LucideIcon", + "inputPlaceholder?": "string (default: 'Enter your email')", + "buttonText?": "string (default: 'Sign Up')", + "termsText?": "string (default: 'By clicking Sign Up you're confirming that you agree with our Terms and Conditions.')", + "onSubmit?": "(email: string) => void", + "ariaLabel?": "string (default: 'Contact section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\n\n console.log(email)} />\n", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for contact pages", + "Use for lead generation" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ContactSplitForm.json b/registry/components/ContactSplitForm.json new file mode 100644 index 0000000..9d8b827 --- /dev/null +++ b/registry/components/ContactSplitForm.json @@ -0,0 +1,57 @@ +{ + "name": "ContactSplitForm", + "description": "Split layout contact form with animated title and description, dynamic input fields, optional textarea, submit button, and media content.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Medium length heading goes here", + "minChars": 4, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique.", + "minChars": 20, + "maxChars": 200 + }, + "buttonText": { + "required": false, + "default": "Submit", + "example": "Send Message", + "minChars": 2, + "maxChars": 15 + } + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "inputs": "Array<{ name: string, type: string, placeholder: string, required?: boolean, className?: string }> - Form input fields (min 2 required)", + "textarea?": "{ name: string, placeholder: string, rows?: number, required?: boolean, className?: string } - Optional textarea field", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Contact section video')", + "mediaPosition?": "'left' | 'right' (default: 'right')", + "buttonText?": "string (default: 'Submit')", + "onSubmit?": "(data: Record) => void", + "ariaLabel?": "string (default: 'Contact section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\n\n console.log(data)} />\n", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for contact pages", + "Use for lead generation", + "Requires inputs[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ContactText.json b/registry/components/ContactText.json new file mode 100644 index 0000000..b03b1aa --- /dev/null +++ b/registry/components/ContactText.json @@ -0,0 +1,48 @@ +{ + "name": "ContactText", + "description": "Centered contact section with animated text and action buttons in a card container.", + "constraints": { + "textRules": { + "text": { + "required": true, + "example": "Ready to start your next project? Let's create something amazing together.", + "minChars": 10, + "maxChars": 200 + }, + "animationType": { + "required": false, + "default": "entrance-slide", + "options": [ + "entrance-slide", + "reveal-blur", + "background-highlight" + ], + "note": "GSAP scroll-triggered animation type for text" + } + }, + "buttonRules": { + "maxButtons": 2, + "note": "Supports up to 2 buttons with px-8 spacing. Buttons use theme.defaultButtonVariant." + } + }, + "propsSchema": { + "text": "string", + "animationType?": "'entrance-slide' | 'reveal-blur' | 'background-highlight' (default: 'entrance-slide')", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Contact section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for contact pages", + "Use for lead generation", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/DotGridBackground.json b/registry/components/DotGridBackground.json new file mode 100644 index 0000000..102e61d --- /dev/null +++ b/registry/components/DotGridBackground.json @@ -0,0 +1,23 @@ +{ + "name": "DotGridBackground", + "description": "Dot pattern background with radial gradient dots and optional 3D perspective effect.", + "constraints": {}, + "propsSchema": { + "size?": "'small' | 'medium' | 'large' (default: 'medium')", + "perspectiveThreeD?": "boolean (default: false)", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/DownwardRaysBackground.json b/registry/components/DownwardRaysBackground.json new file mode 100644 index 0000000..b157144 --- /dev/null +++ b/registry/components/DownwardRaysBackground.json @@ -0,0 +1,26 @@ +{ + "name": "DownwardRaysBackground", + "description": "Atmospheric light rays emanating from top center directly downward with blur and radial gradient effects, with optional grid overlay.", + "constraints": {}, + "propsSchema": { + "animated": "boolean - Required. When true, rays animate with pulsing opacity. When false, rays display static opacity.", + "showGrid": "boolean - Required. When true, displays a grid overlay fading from top center. When false, no grid is shown.", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for statistics displays", + "Use for achievement showcases" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/EmailSignupForm.json b/registry/components/EmailSignupForm.json new file mode 100644 index 0000000..d7ec253 --- /dev/null +++ b/registry/components/EmailSignupForm.json @@ -0,0 +1,39 @@ +{ + "name": "EmailSignupForm", + "description": "Compact email signup form with inline input and submit button in card container.", + "constraints": { + "textRules": { + "inputPlaceholder": { + "required": false, + "default": "Enter your email", + "example": "Your email address", + "minChars": 5, + "maxChars": 50 + }, + "buttonText": { + "required": false, + "default": "Sign Up", + "example": "Subscribe", + "minChars": 2, + "maxChars": 15 + } + } + }, + "propsSchema": { + "inputPlaceholder?": "string (default: 'Enter your email')", + "buttonText?": "string (default: 'Sign Up')", + "onSubmit?": "(email: string) => void", + "className?": "string" + }, + "usageExample": " console.log(email)} />", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FaqBase.json b/registry/components/FaqBase.json new file mode 100644 index 0000000..8c13f4a --- /dev/null +++ b/registry/components/FaqBase.json @@ -0,0 +1,72 @@ +{ + "name": "FaqBase", + "description": "FAQ section with accordion items and optional header.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Frequently Asked Questions", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Find answers to common questions about our products and services", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Help", + "minChars": 2, + "maxChars": 30 + } + }, + "faqRules": { + "faqs": { + "required": true, + "minItems": 1, + "example": "[{\"id\": \"1\", \"title\": \"What is your return policy?\", \"content\": \"We offer a 30-day money-back guarantee.\"}]", + "note": "Array of FAQ items. Each item requires unique id, title (question), and content (answer with HTML support)." + }, + "animationType": { + "required": false, + "default": "smooth", + "options": [ + "smooth", + "instant" + ], + "note": "Animation type for accordion open/close. 'smooth' uses height transition, 'instant' shows/hides immediately." + } + } + }, + "propsSchema": { + "faqs": "Array<{ id: string, title: string, content: string }> - FAQ items", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "animationType?": "'smooth' | 'instant' (default: 'smooth')", + "showCard?": "boolean (default: true)", + "ariaLabel?": "string (default: 'FAQ section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for help pages", + "Use for support sections", + "Requires faqs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FaqDouble.json b/registry/components/FaqDouble.json new file mode 100644 index 0000000..4e1283c --- /dev/null +++ b/registry/components/FaqDouble.json @@ -0,0 +1,71 @@ +{ + "name": "FaqDouble", + "description": "FAQ section with two-column accordion layout and optional header.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Frequently Asked Questions", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Find answers to common questions about our products and services", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Help", + "minChars": 2, + "maxChars": 30 + } + }, + "faqRules": { + "faqs": { + "required": true, + "minItems": 1, + "example": "[{\"id\": \"1\", \"title\": \"What is your return policy?\", \"content\": \"We offer a 30-day money-back guarantee.\"}]", + "note": "Array of FAQ items. Each item requires unique id, title (question), and content (answer with HTML support). Items are automatically split into two columns." + }, + "animationType": { + "required": false, + "default": "smooth", + "options": [ + "smooth", + "instant" + ], + "note": "Animation type for accordion open/close. 'smooth' uses height transition, 'instant' shows/hides immediately." + } + } + }, + "propsSchema": { + "faqs": "Array<{ id: string, title: string, content: string }> - FAQ items", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "animationType?": "'smooth' | 'instant' (default: 'smooth')", + "ariaLabel?": "string (default: 'FAQ section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for help pages", + "Use for support sections", + "Requires faqs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FaqSplitMedia.json b/registry/components/FaqSplitMedia.json new file mode 100644 index 0000000..1230577 --- /dev/null +++ b/registry/components/FaqSplitMedia.json @@ -0,0 +1,98 @@ +{ + "name": "FaqSplitMedia", + "description": "FAQ section with split layout featuring media (image/video) on one side and accordion list on the other.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Frequently Asked Questions", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Find answers to common questions about our products and services", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Help", + "minChars": 2, + "maxChars": 30 + } + }, + "faqRules": { + "faqs": { + "required": true, + "minItems": 1, + "example": "[{\"id\": \"1\", \"title\": \"What is your return policy?\", \"content\": \"We offer a 30-day money-back guarantee.\"}]", + "note": "Array of FAQ items. Each item requires unique id, title (question), and content (answer with HTML support)." + }, + "animationType": { + "required": false, + "default": "smooth", + "options": [ + "smooth", + "instant" + ], + "note": "Animation type for accordion open/close. 'smooth' uses height transition, 'instant' shows/hides immediately." + }, + "mediaPosition": { + "required": false, + "default": "left", + "options": [ + "left", + "right" + ], + "note": "Position of media relative to FAQ list." + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "note": "Path to image file. Either imageSrc or videoSrc should be provided." + }, + "videoSrc": { + "required": false, + "note": "Path to video file. Either imageSrc or videoSrc should be provided." + } + } + }, + "propsSchema": { + "faqs": "Array<{ id: string, title: string, content: string }> - FAQ items", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'FAQ section video')", + "mediaPosition?": "'left' | 'right' (default: 'left')", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "animationType?": "'smooth' | 'instant' (default: 'smooth')", + "showCard?": "boolean (default: true)", + "ariaLabel?": "string (default: 'FAQ section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for help pages", + "Use for support sections", + "Requires faqs[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FaqSplitText.json b/registry/components/FaqSplitText.json new file mode 100644 index 0000000..59d9256 --- /dev/null +++ b/registry/components/FaqSplitText.json @@ -0,0 +1,71 @@ +{ + "name": "FaqSplitText", + "description": "FAQ section with split layout featuring animated text on one side and accordion list on the other.", + "constraints": { + "textRules": { + "sideTitle": { + "required": true, + "example": "Frequently Asked Questions", + "minChars": 2, + "maxChars": 100 + }, + "sideDescription": { + "required": false, + "example": "Everything you need to know", + "minChars": 5, + "maxChars": 250 + } + }, + "faqRules": { + "faqs": { + "required": true, + "minItems": 1, + "example": "[{\"id\": \"1\", \"title\": \"What is your return policy?\", \"content\": \"We offer a 30-day money-back guarantee.\"}]", + "note": "Array of FAQ items. Each item requires unique id, title (question), and content (answer with HTML support)." + }, + "animationType": { + "required": false, + "default": "smooth", + "options": [ + "smooth", + "instant" + ], + "note": "Animation type for accordion open/close. 'smooth' uses height transition, 'instant' shows/hides immediately." + }, + "textPosition": { + "required": false, + "default": "left", + "options": [ + "left", + "right" + ], + "note": "Position of title/description text relative to FAQ list." + } + } + }, + "propsSchema": { + "faqs": "Array<{ id: string, title: string, content: string }> - FAQ items", + "sideTitle": "string", + "sideDescription?": "string", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textPosition?": "'left' | 'right' (default: 'left')", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "animationType?": "'smooth' | 'instant' (default: 'smooth')", + "showCard?": "boolean (default: true)", + "ariaLabel?": "string (default: 'FAQ section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for help pages", + "Use for support sections", + "Requires faqs[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardEight.json b/registry/components/FeatureCardEight.json new file mode 100644 index 0000000..cf16ec4 --- /dev/null +++ b/registry/components/FeatureCardEight.json @@ -0,0 +1,111 @@ +{ + "name": "FeatureCardEight", + "description": "Horizontal timeline feature section with auto-advancing progress bars, numbered step badges, and shared media display.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Process", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Discover how we bring ideas to life", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "How It Works", + "minChars": 2, + "maxChars": 30 + } + }, + "featureCardRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 3, + "note": "Step number displayed in circular badge" + }, + "title": { + "required": true, + "example": "Research & Planning", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Understanding user needs, market trends, and project requirements", + "minChars": 10, + "maxChars": 300 + } + }, + "mediaRules": { + "imageSrc": { + "required": true, + "example": "/feature1.jpg", + "note": "Either imageSrc or videoSrc required per card (discriminated union)" + }, + "videoSrc": { + "required": true, + "example": "/feature1.mp4", + "note": "Either imageSrc or videoSrc required per card (discriminated union)" + }, + "imageAlt": { + "required": false, + "example": "Research and planning illustration", + "note": "Falls back to feature title if not provided" + }, + "videoAriaLabel": { + "required": false, + "example": "Research and planning video", + "note": "Falls back to feature title if not provided" + } + }, + "itemRules": { + "minItems": 2, + "maxItems": 4, + "recommendedItems": "2-4", + "note": "Works best with 2-4 features. Grid layout adapts based on item count." + } + }, + "propsSchema": { + "features": "Array<{ id: number, title: string, description: string } & ({ imageSrc: string, imageAlt?: string } | { videoSrc: string, videoAriaLabel?: string })>", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for process flows", + "Use for roadmaps", + "Use for step-by-step explanation", + "Use for feature showcases", + "Use for capability displays", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use non-sequential content", + "Do not use single item", + "Do not use more than 4 items", + "Do not use less than 2 items", + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardMedia.json b/registry/components/FeatureCardMedia.json new file mode 100644 index 0000000..555a49d --- /dev/null +++ b/registry/components/FeatureCardMedia.json @@ -0,0 +1,70 @@ +{ + "name": "FeatureCardMedia", + "description": "Feature section with media cards displaying tag overlay, title, description, and optional buttons.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "From concept to launch, we've got you covered", + "minChars": 10, + "maxChars": 100 + }, + "description": { + "required": true, + "example": "Discover how we bring ideas to life through a proven methodology", + "minChars": 20, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Our Process", + "minChars": 2, + "maxChars": 30 + } + }, + "featuresRules": { + "minItems": 2, + "recommendedItems": 3, + "maxItems": 6, + "structure": { + "id": "string - Unique identifier (required)", + "title": "string - Card title (required)", + "description": "string - Card description (required)", + "tag": "string - Tag displayed on media top-right (required)", + "imageSrc": "string - Image source URL (optional)", + "videoSrc": "string - Video source URL (optional)", + "buttons": "ButtonConfig[] - Optional action buttons for the card" + }, + "note": "Each card requires id, title, description, and tag. Media (imageSrc or videoSrc) recommended. Buttons are optional per card." + } + }, + "propsSchema": { + "features": "Array<{ id: string, title: string, description: string, tag: string, imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string, buttons?: ButtonConfig[], onCardClick?: () => void }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal'", + "title": "string", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image'", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }>", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "ButtonConfig[]", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "ariaLabel?": "string (default: 'Features section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires features[]", + "Requires titleSegments?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardNine.json b/registry/components/FeatureCardNine.json new file mode 100644 index 0000000..56cb5d5 --- /dev/null +++ b/registry/components/FeatureCardNine.json @@ -0,0 +1,130 @@ +{ + "name": "FeatureCardNine", + "description": "Scroll-based timeline feature section with two animated phone frames and centered content.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Powerful Features", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Everything you need to build amazing products", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "featureCardRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 3, + "note": "Feature identifier" + }, + "title": { + "required": true, + "example": "Seamless Integration", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Connect your tools and workflows effortlessly. Our platform integrates with your existing systems.", + "minChars": 10, + "maxChars": 300 + } + }, + "phoneMediaRules": { + "phoneOne": { + "imageSrc": { + "required": true, + "example": "/phone1.jpg", + "note": "Either imageSrc or videoSrc required for phoneOne (discriminated union)" + }, + "videoSrc": { + "required": true, + "example": "/phone1.mp4", + "note": "Either imageSrc or videoSrc required for phoneOne (discriminated union)" + }, + "imageAlt": { + "required": false, + "example": "First phone mockup", + "note": "Falls back to '[title] - Phone 1' if not provided" + }, + "videoAriaLabel": { + "required": false, + "example": "First phone video", + "note": "Falls back to '[title] - Phone 1 video' if not provided" + } + }, + "phoneTwo": { + "imageSrc": { + "required": true, + "example": "/phone2.jpg", + "note": "Either imageSrc or videoSrc required for phoneTwo (discriminated union)" + }, + "videoSrc": { + "required": true, + "example": "/phone2.mp4", + "note": "Either imageSrc or videoSrc required for phoneTwo (discriminated union)" + }, + "imageAlt": { + "required": false, + "example": "Second phone mockup", + "note": "Falls back to '[title] - Phone 2' if not provided" + }, + "videoAriaLabel": { + "required": false, + "example": "Second phone video", + "note": "Falls back to '[title] - Phone 2 video' if not provided" + } + } + }, + "itemRules": { + "minItems": 2, + "maxItems": 4, + "recommendedItems": "2-4", + "note": "Each feature takes 100vh height. Recommend 2-4 features to avoid excessive scroll." + } + }, + "propsSchema": { + "features": "Array<{ id: number, title: string, description: string, phoneOne: ({ imageSrc: string, imageAlt?: string } | { videoSrc: string, videoAriaLabel?: string }), phoneTwo: ({ imageSrc: string, imageAlt?: string } | { videoSrc: string, videoAriaLabel?: string }) }>", + "showStepNumbers": "boolean (required - controls whether step number badges display)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use less than 2 items", + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardNineteen.json b/registry/components/FeatureCardNineteen.json new file mode 100644 index 0000000..378ccc1 --- /dev/null +++ b/registry/components/FeatureCardNineteen.json @@ -0,0 +1,111 @@ +{ + "name": "FeatureCardNineteen", + "description": "Timeline feature section with full-width cards showing step numbers and rotated media.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Process", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Discover how we bring ideas to life", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "How it works", + "minChars": 2, + "maxChars": 30 + } + }, + "featureCardRules": { + "id": { + "required": true, + "example": 1, + "note": "Numeric ID used to generate step number (01, 02, etc.)" + }, + "tag": { + "required": true, + "example": "Expertise", + "minChars": 2, + "maxChars": 30 + }, + "title": { + "required": true, + "example": "Strategy", + "minChars": 2, + "maxChars": 30 + }, + "subtitle": { + "required": true, + "example": "Data-driven decisions for growth.", + "minChars": 5, + "maxChars": 60 + }, + "description": { + "required": true, + "example": "We analyze market trends and user behavior to create strategies that drive real results.", + "minChars": 10, + "maxChars": 250 + }, + "imageSrc": { + "required": false, + "example": "/images/strategy.webp", + "note": "Image source URL (either imageSrc or videoSrc)" + }, + "videoSrc": { + "required": false, + "example": "/videos/strategy.mp4", + "note": "Video source URL (either imageSrc or videoSrc)" + }, + "buttons": { + "required": false, + "example": [ + { + "text": "Learn more", + "href": "/strategy" + } + ], + "note": "Optional buttons per feature card (max 2)" + } + } + }, + "propsSchema": { + "features": "Array<{ id: number, tag: string, title: string, subtitle: string, description: string, imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string, buttons?: Array<{text: string, onClick?: () => void, href?: string}> }> (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for process flows", + "Use for roadmaps", + "Use for step-by-step explanation", + "Use for feature showcases", + "Use for capability displays", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use multiple items", + "Do not use non-sequential content", + "Do not use single item" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardOne.json b/registry/components/FeatureCardOne.json new file mode 100644 index 0000000..eeb40dc --- /dev/null +++ b/registry/components/FeatureCardOne.json @@ -0,0 +1,73 @@ +{ + "name": "FeatureCardOne", + "description": "Adaptive feature section with image/video-based cards in customizable bento grid layouts or carousel.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Features", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Discover the tools and capabilities that make our platform powerful", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "featureCardRules": { + "title": { + "required": true, + "example": "Advanced Analytics", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Get detailed insights into your business performance", + "minChars": 10, + "maxChars": 250 + } + } + }, + "propsSchema": { + "features": "Array<{ title: string, description: string, button?: {text: string, onClick?: () => void, href?: string} } & ({ imageSrc: string, imageAlt?: string } | { videoSrc: string, videoAriaLabel?: string })>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string", + "useInvertedBackground": "'noInvert' | 'invertDefault'" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for statistics displays", + "Use for achievement showcases", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardSeven.json b/registry/components/FeatureCardSeven.json new file mode 100644 index 0000000..c3c7fd4 --- /dev/null +++ b/registry/components/FeatureCardSeven.json @@ -0,0 +1,103 @@ +{ + "name": "FeatureCardSeven", + "description": "Vertical stack feature section with alternating left/right layouts and numbered step cards with square images.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Features", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Sequential features with numbered badges", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "featureCardRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 3, + "note": "Step number displayed in circular badge" + }, + "title": { + "required": true, + "example": "Modern Architecture", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Built with the latest technologies and best practices", + "minChars": 10, + "maxChars": 300 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/feature1.jpg", + "note": "Either imageSrc or videoSrc required per card" + }, + "videoSrc": { + "required": false, + "example": "/feature1.mp4", + "note": "Either imageSrc or videoSrc required per card" + }, + "imageAlt": { + "required": false, + "example": "Modern architecture illustration", + "note": "Falls back to feature title if not provided" + }, + "videoAriaLabel": { + "required": false, + "example": "Modern architecture video", + "note": "Falls back to feature title if not provided" + } + } + }, + "propsSchema": { + "features": "Array<{ id: number, title: string, description: string } & ({ imageSrc: string, imageAlt?: string } | { videoSrc: string, videoAriaLabel?: string })>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for process flows", + "Use for roadmaps", + "Use for step-by-step explanation", + "Use for feature showcases", + "Use for capability displays", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use non-sequential content", + "Do not use single item" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardSix.json b/registry/components/FeatureCardSix.json new file mode 100644 index 0000000..db05762 --- /dev/null +++ b/registry/components/FeatureCardSix.json @@ -0,0 +1,102 @@ +{ + "name": "FeatureCardSix", + "description": "Timeline-based feature section with scroll-triggered stacking animations and numbered step cards.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Process", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Discover how we bring ideas to life", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Process", + "minChars": 2, + "maxChars": 30 + } + }, + "featureCardRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 3, + "note": "Step number displayed in circular badge" + }, + "title": { + "required": true, + "example": "Research & Planning", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Understanding user needs, market trends, and project requirements", + "minChars": 10, + "maxChars": 300 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/step1.jpg", + "note": "Either imageSrc or videoSrc required per card" + }, + "videoSrc": { + "required": false, + "example": "/step1.mp4", + "note": "Either imageSrc or videoSrc required per card" + }, + "imageAlt": { + "required": false, + "example": "Research phase illustration", + "note": "Falls back to feature title if not provided" + }, + "videoAriaLabel": { + "required": false, + "example": "Research phase video", + "note": "Falls back to feature title if not provided" + } + } + }, + "propsSchema": { + "features": "Array<{ id: number, title: string, description: string } & ({ imageSrc: string, imageAlt?: string } | { videoSrc: string, videoAriaLabel?: string })>", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for process flows", + "Use for roadmaps", + "Use for step-by-step explanation", + "Use for feature showcases", + "Use for capability displays", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use non-sequential content", + "Do not use single item" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardSixteen.json b/registry/components/FeatureCardSixteen.json new file mode 100644 index 0000000..eee2328 --- /dev/null +++ b/registry/components/FeatureCardSixteen.json @@ -0,0 +1,80 @@ +{ + "name": "FeatureCardSixteen", + "description": "Comparison section with negative and positive cards showing contrasting features.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "What makes us stand out", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "See how we compare to traditional approaches", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Why us", + "minChars": 2, + "maxChars": 30 + } + }, + "negativeCardRules": { + "items": { + "required": true, + "example": [ + "Time-consuming processes", + "Limited scalability", + "Higher costs" + ], + "minItems": 2, + "maxItems": 10, + "note": "List of negative aspects displayed with X icons" + } + }, + "positiveCardRules": { + "items": { + "required": true, + "example": [ + "Streamlined workflow", + "Scalable solutions", + "Better value" + ], + "minItems": 2, + "maxItems": 10, + "note": "List of positive aspects displayed with Check icons" + } + } + }, + "propsSchema": { + "negativeCard": "{ items: string[] } (required)", + "positiveCard": "{ items: string[] } (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Feature comparison section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardThree.json b/registry/components/FeatureCardThree.json new file mode 100644 index 0000000..e27905a --- /dev/null +++ b/registry/components/FeatureCardThree.json @@ -0,0 +1,90 @@ +{ + "name": "FeatureCardThree", + "description": "Adaptive feature section with hover-reveal cards displaying numbered features with images.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Features", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Discover what makes us different", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "featureCardRules": { + "id": { + "required": true, + "example": "01", + "minChars": 1, + "maxChars": 3, + "note": "Displayed in the flip badge" + }, + "title": { + "required": true, + "example": "Advanced Analytics", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Get detailed insights into your business performance", + "minChars": 10, + "maxChars": 250 + } + }, + "mediaRules": { + "imageSrc": { + "required": true, + "example": "/feature.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "imageAlt": { + "required": false, + "example": "Feature background", + "note": "Empty string marks image as decorative (aria-hidden)" + } + } + }, + "propsSchema": { + "features": "Array<{ id: string, title: string, description: string, imageSrc: string, imageAlt?: string }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string", + "useInvertedBackground": "'noInvert' | 'invertDefault'" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardTwelve.json b/registry/components/FeatureCardTwelve.json new file mode 100644 index 0000000..1823b74 --- /dev/null +++ b/registry/components/FeatureCardTwelve.json @@ -0,0 +1,98 @@ +{ + "name": "FeatureCardTwelve", + "description": "List-based feature section with large label on left and content with bullet points on right.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Choose Your Plan", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Find the perfect fit for your needs", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Plans", + "minChars": 2, + "maxChars": 30 + } + }, + "featureRules": { + "id": { + "required": true, + "example": "premium", + "note": "Unique identifier for the feature" + }, + "label": { + "required": true, + "example": "Premium", + "minChars": 2, + "maxChars": 30, + "note": "Large display label shown on left side (5xl mobile, 6xl desktop)" + }, + "title": { + "required": true, + "example": "Premium features for your most demanding needs", + "minChars": 10, + "maxChars": 120, + "note": "Feature heading shown at xl (mobile) / 3xl (desktop)" + }, + "items": { + "required": true, + "minItems": 1, + "maxItems": 8, + "structure": "string[]", + "note": "Inline bullet list with accent-colored dots. Each item should be 5-50 characters." + }, + "buttons": { + "required": false, + "maxButtons": 2, + "structure": "Array<{text: string, onClick?: () => void, href?: string}>", + "note": "Optional buttons at bottom of content area. First button is primary, second is secondary." + } + }, + "itemRules": { + "minItems": 1, + "maxItems": 8, + "recommendedItems": "2-5", + "note": "Works best with 2-5 features for clear comparison" + } + }, + "propsSchema": { + "features": "Array<{ id: string, label: string, title: string, items: string[], buttons?: Array<{text: string, onClick?: () => void, href?: string}> }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string" + }, + "usageExample": " console.log('clicked') }] }]} animationType=\"opacity\" variant=\"border\" title=\"Choose Your Plan\" description=\"Find the perfect fit for your needs\" textboxLayout=\"default\" useInvertedBackground={\"noInvert\"} />", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Requires features[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 8 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureCardTwentyOne.json b/registry/components/FeatureCardTwentyOne.json new file mode 100644 index 0000000..6571269 --- /dev/null +++ b/registry/components/FeatureCardTwentyOne.json @@ -0,0 +1,86 @@ +{ + "name": "FeatureCardTwentyOne", + "description": "Split layout with media on one side and TextBox with accordion items on the other.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Custom designs", + "minChars": 2, + "maxChars": 60 + }, + "description": { + "required": true, + "example": "Explore our range of customizable solutions designed to meet your unique needs.", + "minChars": 10, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "accordionRules": { + "id": { + "required": true, + "example": "1", + "note": "Unique identifier for each accordion item" + }, + "title": { + "required": true, + "example": "Inspiration + innovation", + "minChars": 2, + "maxChars": 60, + "note": "Accordion header text" + }, + "content": { + "required": true, + "example": "From custom colourways to bespoke elements built from the ground up.", + "minChars": 10, + "maxChars": 500, + "note": "Accordion expanded content (supports HTML)" + } + }, + "itemRules": { + "minItems": 2, + "maxItems": 6, + "recommendedItems": 3 + } + }, + "propsSchema": { + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "accordionItems": "Array<{ id: string, title: string, content: string }>", + "imageSrc?": "string (either imageSrc or videoSrc required)", + "imageAlt?": "string", + "videoSrc?": "string (either imageSrc or videoSrc required)", + "videoAriaLabel?": "string", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "mediaPosition?": "'left' | 'right' (default: 'left')", + "ariaLabel?": "string (default: 'Feature section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires titleSegments?[]", + "Requires buttons?[]", + "Requires accordionItems[]" + ], + "dont": [ + "Do not use less than 2 items", + "Do not use more than 6 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FeatureProcessSteps.json b/registry/components/FeatureProcessSteps.json new file mode 100644 index 0000000..333eb4a --- /dev/null +++ b/registry/components/FeatureProcessSteps.json @@ -0,0 +1,67 @@ +{ + "name": "FeatureProcessSteps", + "description": "Split-layout feature section with text on left and numbered process steps with timeline on right.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Getting you results without the complexity", + "minChars": 10, + "maxChars": 100 + }, + "description": { + "required": true, + "example": "Our three-step process takes you from identifying opportunities to launching systems, with clear communication and support at every stage.", + "minChars": 20, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "How we work", + "minChars": 2, + "maxChars": 30 + } + }, + "stepsRules": { + "minSteps": 2, + "recommendedSteps": 3, + "maxSteps": 6, + "structure": { + "number": "string - Step number to display (required, e.g., '01', '02', '1', '2')", + "title": "string - Step title (required, e.g., 'Discovery & Assessment')", + "description": "string - Step description (required)", + "tag": "string - Optional tag/badge for the step (e.g., 'Week 1', 'Ongoing')" + }, + "note": "Minimum 2 steps required, but 3+ steps recommended for optimal visual balance. Each step shows a numbered card with a connecting timeline line." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "steps": "Array<{ number: string, title: string, description: string, tag?: string }>", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "ButtonConfig[]", + "ariaLabel?": "string (default: 'Process steps section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\nimport { Sparkles } from 'lucide-react';\n\n\n \n", + "do": [ + "Use for process flows", + "Use for roadmaps", + "Use for step-by-step explanation", + "Use for feature showcases", + "Use for capability displays", + "Requires steps[]" + ], + "dont": [ + "Do not use non-sequential content", + "Do not use single item" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FloatingGradientBackground.json b/registry/components/FloatingGradientBackground.json new file mode 100644 index 0000000..d8c75a8 --- /dev/null +++ b/registry/components/FloatingGradientBackground.json @@ -0,0 +1,19 @@ +{ + "name": "FloatingGradientBackground", + "description": "Five animated gradient circles with CSS animations and vertical gradient mask.", + "constraints": {}, + "propsSchema": { + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FluidBackground.json b/registry/components/FluidBackground.json new file mode 100644 index 0000000..171c1d3 --- /dev/null +++ b/registry/components/FluidBackground.json @@ -0,0 +1,19 @@ +{ + "name": "FluidBackground", + "description": "Generative fluid patterns using CPPN shader with theme color integration.", + "constraints": {}, + "propsSchema": { + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterBase.json b/registry/components/FooterBase.json new file mode 100644 index 0000000..fa301ea --- /dev/null +++ b/registry/components/FooterBase.json @@ -0,0 +1,71 @@ +{ + "name": "FooterBase", + "description": "Classic footer with logo, multi-column navigation, copyright text, and privacy policy link.", + "constraints": { + "textRules": { + "logoText": { + "required": false, + "default": "Webild", + "example": "Company Name", + "minChars": 2, + "maxChars": 30 + }, + "copyrightText": { + "required": false, + "default": "© 2025 | Webild", + "example": "© 2025 Company Name", + "minChars": 5, + "maxChars": 50 + }, + "columnTitle": { + "required": true, + "example": "Product", + "minChars": 2, + "maxChars": 20 + }, + "itemLabel": { + "required": true, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "structureRules": { + "columns": { + "required": true, + "minColumns": 1, + "maxColumns": 3, + "note": "Each column must have title and items array" + }, + "items": { + "required": true, + "minItems": 1, + "structure": { + "label": "string - Link text (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)" + } + } + } + }, + "propsSchema": { + "columns": "Array<{ title: string, items: Array<{ label: string, href: string }> }> - Footer navigation columns (required)", + "logoText?": "string (default: 'Webild')", + "copyrightText?": "string (default: '© 2025 | Webild')", + "onPrivacyClick?": "() => void", + "ariaLabel?": "string (default: 'Site footer')", + "className?": "string" + }, + "usageExample": " console.log('Privacy clicked')} />", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires columns[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterBaseCard.json b/registry/components/FooterBaseCard.json new file mode 100644 index 0000000..256b272 --- /dev/null +++ b/registry/components/FooterBaseCard.json @@ -0,0 +1,54 @@ +{ + "name": "FooterBaseCard", + "description": "Card-wrapped footer with logo, navigation columns, copyright, and privacy policy link.", + "constraints": { + "textRules": { + "copyrightText": { + "required": false, + "example": "© 2025 | Webild", + "minChars": 5, + "maxChars": 100, + "note": "Copyright text displayed at bottom left" + }, + "logoText": { + "required": false, + "example": "Webild", + "minChars": 2, + "maxChars": 30, + "note": "Text used for h2 heading" + } + }, + "columnsRules": { + "required": true, + "structure": { + "title": "string - Column heading (required)", + "items": "Array<{ label: string, href: string }> - Navigation links (required)" + }, + "minColumns": 1, + "maxColumns": 5, + "note": "Array of footer column objects. Each column must have title and items array." + }, + "logoRules": { + "note": "Uses logoText as h2 heading." + } + }, + "propsSchema": { + "logoText?": "string (default: 'Webild')", + "columns": "Array<{ title: string, items: Array<{ label: string, href: string }> }> - Footer navigation columns (required)", + "copyrightText?": "string (default: '© 2025 | Webild')", + "onPrivacyClick?": "() => void", + "ariaLabel?": "string (default: 'Site footer')", + "className?": "string" + }, + "usageExample": " console.log('Privacy clicked')} />", + "do": [ + "Use for general use", + "Requires columns[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterBaseReveal.json b/registry/components/FooterBaseReveal.json new file mode 100644 index 0000000..164e249 --- /dev/null +++ b/registry/components/FooterBaseReveal.json @@ -0,0 +1,62 @@ +{ + "name": "FooterBaseReveal", + "description": "Animated footer reveal wrapper that creates a fixed footer with scroll-triggered reveal effect.", + "constraints": { + "textRules": { + "copyrightText": { + "required": false, + "default": "© 2025 | Webild", + "example": "© 2025 Company Name", + "minChars": 5, + "maxChars": 50 + }, + "columnTitle": { + "required": true, + "example": "Product", + "minChars": 2, + "maxChars": 20 + }, + "itemLabel": { + "required": true, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "structureRules": { + "columns": { + "required": true, + "minColumns": 1, + "maxColumns": 3, + "note": "Each column must have title and items array" + }, + "items": { + "required": true, + "minItems": 1, + "structure": { + "label": "string - Link text (required)", + "href": "string - Link destination (optional). External URLs open in new tab, internal values scroll to sections", + "onClick": "() => void - Additional click handler (optional)" + } + } + } + }, + "propsSchema": { + "columns": "Array<{ title: string, items: Array<{ label: string, href: string }> }> - Footer navigation columns (required)", + "copyrightText?": "string", + "onPrivacyClick?": "() => void", + "ariaLabel?": "string", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for general use", + "Requires columns[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterCard.json b/registry/components/FooterCard.json new file mode 100644 index 0000000..5678b6a --- /dev/null +++ b/registry/components/FooterCard.json @@ -0,0 +1,53 @@ +{ + "name": "FooterCard", + "description": "Minimalist footer with card wrapper containing logo, divider, copyright, and optional social links.", + "constraints": { + "textRules": { + "copyrightText": { + "required": false, + "example": "© 2025 | Webild", + "minChars": 5, + "maxChars": 100, + "note": "Copyright text displayed at bottom left" + }, + "logoText": { + "required": false, + "example": "Webild", + "minChars": 2, + "maxChars": 30, + "note": "Text used for SVG logo" + } + }, + "socialLinksRules": { + "required": false, + "structure": { + "icon": "LucideIcon - Icon component (required)", + "href": "string - Social profile URL (required)", + "ariaLabel": "string - Accessibility label (required)" + }, + "note": "Optional array of social links. Only renders if provided and has length > 0." + }, + "logoRules": { + "note": "Uses logoText for SVG text logo via FooterLogo component." + } + }, + "propsSchema": { + "logoText?": "string (default: 'Webild')", + "copyrightText?": "string (default: '© 2025 | Webild')", + "socialLinks?": "Array<{ icon: LucideIcon, href: string, ariaLabel: string }> - Social media links", + "ariaLabel?": "string (default: 'Site footer')", + "className?": "string", + "logoLineHeight?": "number (default: 1.1)" + }, + "usageExample": "", + "do": [ + "Use for general use", + "Requires socialLinks?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterLogoEmphasis.json b/registry/components/FooterLogoEmphasis.json new file mode 100644 index 0000000..42415b6 --- /dev/null +++ b/registry/components/FooterLogoEmphasis.json @@ -0,0 +1,61 @@ +{ + "name": "FooterLogoEmphasis", + "description": "Footer with prominent centered logo emphasis and grid-based navigation layout with chevron icons.", + "constraints": { + "textRules": { + "logoText": { + "required": false, + "default": "Webild", + "example": "Company Name", + "minChars": 2, + "maxChars": 30 + }, + "itemLabel": { + "required": true, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "structureRules": { + "columns": { + "required": true, + "minColumns": 1, + "maxColumns": 5, + "note": "Grid automatically adjusts from 1-5 columns based on array length" + }, + "items": { + "required": true, + "minItems": 1, + "structure": { + "label": "string - Link text (required)", + "href": "string - Link destination (optional). External URLs open in new tab, internal values scroll to sections", + "onClick": "() => void - Additional click handler (optional)" + } + }, + "logo": { + "note": "Uses logoText for SVG text logo" + } + } + }, + "propsSchema": { + "columns": "Array<{ items: Array<{ label: string, href?: string, onClick?: () => void }> }> - Footer navigation columns (required, max 5)", + "logoText?": "string (default: 'Webild')", + "ariaLabel?": "string (default: 'Site footer')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires columns[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterLogoReveal.json b/registry/components/FooterLogoReveal.json new file mode 100644 index 0000000..8722402 --- /dev/null +++ b/registry/components/FooterLogoReveal.json @@ -0,0 +1,37 @@ +{ + "name": "FooterLogoReveal", + "description": "Minimalist footer with logo that reveals on scroll using fixed positioning and clip-path.", + "constraints": { + "textRules": { + "logoText": { + "required": false, + "example": "Webild", + "minChars": 2, + "maxChars": 30, + "note": "Text used for SVG logo" + } + }, + "logoRules": { + "note": "Uses logoText for SVG text logo via FooterLogo component." + }, + "revealEffectRules": { + "note": "Component uses fixed positioning and clip-path for scroll reveal effect. Requires page content above footer to trigger scroll. ResizeObserver dynamically updates footer height for responsive reveal." + } + }, + "propsSchema": { + "logoText?": "string (default: 'Webild')", + "logoLineHeight?": "number (default: 1.1)", + "ariaLabel?": "string (default: 'Site footer')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterMedia.json b/registry/components/FooterMedia.json new file mode 100644 index 0000000..42b2f3d --- /dev/null +++ b/registry/components/FooterMedia.json @@ -0,0 +1,86 @@ +{ + "name": "FooterMedia", + "description": "Footer with full-width media (image/video) above classic navigation layout.", + "constraints": { + "textRules": { + "logoText": { + "required": false, + "default": "Webild", + "example": "Company Name", + "minChars": 2, + "maxChars": 30 + }, + "copyrightText": { + "required": false, + "default": "© 2025 | Webild", + "example": "© 2025 Company Name", + "minChars": 5, + "maxChars": 50 + }, + "columnTitle": { + "required": true, + "example": "Product", + "minChars": 2, + "maxChars": 20 + }, + "itemLabel": { + "required": true, + "example": "Features", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "note": "Either imageSrc or videoSrc is required (discriminated union)", + "imageSrc": { + "required": "conditional - required if no videoSrc", + "example": "https://images.unsplash.com/photo-1497215728101-856f4ea42174?w=1920" + }, + "videoSrc": { + "required": "conditional - required if no imageSrc", + "example": "/videos/footer-background.mp4" + } + }, + "structureRules": { + "columns": { + "required": true, + "minColumns": 1, + "maxColumns": 3, + "note": "Each column must have title and items array" + }, + "items": { + "required": true, + "minItems": 1, + "structure": { + "label": "string - Link text (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Additional click handler (optional)" + } + } + } + }, + "propsSchema": { + "imageSrc": "string (required if no videoSrc)", + "imageAlt?": "string (default: '')", + "videoSrc": "string (required if no imageSrc)", + "videoAriaLabel?": "string (default: 'Footer video')", + "columns": "Array<{ title: string, items: Array<{ label: string, href: string }> }> - Footer navigation columns (required)", + "logoText?": "string (default: 'Webild')", + "copyrightText?": "string (default: '© 2025 | Webild')", + "onPrivacyClick?": "() => void", + "ariaLabel?": "string (default: 'Site footer')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires columns[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/FooterSimple.json b/registry/components/FooterSimple.json new file mode 100644 index 0000000..2756a19 --- /dev/null +++ b/registry/components/FooterSimple.json @@ -0,0 +1,68 @@ +{ + "name": "FooterSimple", + "description": "Minimal footer with navigation columns, divider, and bottom text row.", + "constraints": { + "textRules": { + "bottomLeftText": { + "required": true, + "example": "© 2025 Company. All rights reserved.", + "minChars": 5, + "maxChars": 60 + }, + "bottomRightText": { + "required": true, + "example": "Made with Webild", + "minChars": 2, + "maxChars": 50 + }, + "columnTitle": { + "required": true, + "example": "Navigate", + "minChars": 2, + "maxChars": 20 + }, + "itemLabel": { + "required": true, + "example": "Home", + "minChars": 2, + "maxChars": 30 + } + }, + "structureRules": { + "columns": { + "required": true, + "minColumns": 2, + "maxColumns": 5, + "note": "Each column must have title and items array. Columns spread evenly across width." + }, + "items": { + "required": true, + "minItems": 1, + "structure": { + "label": "string - Link text (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)" + } + } + } + }, + "propsSchema": { + "columns": "Array<{ title: string, items: Array<{ label: string, href?: string, onClick?: () => void }> }>", + "bottomLeftText": "string", + "bottomRightText": "string", + "ariaLabel?": "string (default: 'Site footer')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires columns[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/Globe.json b/registry/components/Globe.json new file mode 100644 index 0000000..8a2f50b --- /dev/null +++ b/registry/components/Globe.json @@ -0,0 +1,27 @@ +{ + "name": "Globe", + "description": "Interactive 3D rotating globe component using COBE library with theme-aware colors and customizable markers.", + "constraints": { + "globeRules": { + "config": { + "required": false, + "note": "Optional COBEOptions object to customize globe appearance. Default config uses theme colors: baseColor and glowColor use --card, markerColor uses --primary-cta. Can override: phi (rotation), theta (tilt), dark (darkness 0-1), diffuse (lighting), mapSamples, mapBrightness, markers (array of {location: [lat, lng], size: number}), and more. See COBE documentation for full options." + } + } + }, + "propsSchema": { + "className?": "string", + "config?": "COBEOptions - Custom globe configuration (see COBE docs)" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/GradientBarsBackground.json b/registry/components/GradientBarsBackground.json new file mode 100644 index 0000000..5431ecc --- /dev/null +++ b/registry/components/GradientBarsBackground.json @@ -0,0 +1,25 @@ +{ + "name": "GradientBarsBackground", + "description": "Vertical gradient bars with dynamic height distribution creating a wave-like pattern.", + "constraints": {}, + "propsSchema": { + "className?": "string", + "numBars?": "number (default: 15)", + "gradientFrom?": "string (default: 'var(--color-primary-cta)')", + "gradientTo?": "string (default: 'transparent')", + "opacity?": "number (default: 0.5)" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for statistics displays", + "Use for achievement showcases" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/GridBackround.json b/registry/components/GridBackround.json new file mode 100644 index 0000000..2278cfe --- /dev/null +++ b/registry/components/GridBackround.json @@ -0,0 +1,23 @@ +{ + "name": "GridBackround", + "description": "Grid pattern background with line-based grid and optional 3D perspective effect.", + "constraints": {}, + "propsSchema": { + "size?": "'small' | 'medium' | 'large' (default: 'medium')", + "perspectiveThreeD?": "boolean (default: false)", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroBillboard.json b/registry/components/HeroBillboard.json new file mode 100644 index 0000000..f86420d --- /dev/null +++ b/registry/components/HeroBillboard.json @@ -0,0 +1,85 @@ +{ + "name": "HeroBillboard", + "description": "Full-width hero section with centered text content, optional tag, buttons, and single image/video below in a card frame.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Welcome to Our Platform", + "minChars": 2, + "maxChars": 40 + }, + "description": { + "required": true, + "example": "Create beautiful, responsive web experiences", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "New Release", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/hero-image.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "videoSrc": { + "required": false, + "example": "/hero-video.mp4", + "note": "Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "Hero background", + "note": "Empty string marks image as decorative (aria-hidden)" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Learn More', href: 'about' }" + ], + "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Requires buttons?[]" + ], + "dont": [ + "Do not use multiple items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroBillboardCarousel.json b/registry/components/HeroBillboardCarousel.json new file mode 100644 index 0000000..82ff847 --- /dev/null +++ b/registry/components/HeroBillboardCarousel.json @@ -0,0 +1,75 @@ +{ + "name": "HeroBillboardCarousel", + "description": "Full-width hero section with centered text and 5+ auto-scrolling images in carousel layout.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Portfolio", + "minChars": 2, + "maxChars": 40 + }, + "description": { + "required": true, + "example": "Browse through our collection of projects", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "Portfolio", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "mediaItems": { + "required": true, + "example": "[{ imageSrc: '/img1.jpg', imageAlt: 'Product 1' }, { imageSrc: '/img2.jpg', imageAlt: 'Product 2' }, { imageSrc: '/img3.jpg', imageAlt: 'Product 3' }, { imageSrc: '/img4.jpg', imageAlt: 'Product 4' }, { imageSrc: '/img5.jpg', imageAlt: 'Product 5' }]", + "note": "Array of 5+ MediaItem objects. Each item can have imageSrc, videoSrc, imageAlt, videoAriaLabel. Requires minimum 5 images." + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'View Portfolio', href: 'https://example.com' }", + "{ text: 'Contact Us', href: 'contact' }" + ], + "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "mediaItems": "Array<{ imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }> - Each item requires either imageSrc or videoSrc", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for portfolios", + "Use for image galleries", + "Requires buttons?[]", + "Requires mediaItems[]" + ], + "dont": [ + "Do not use less than 5 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroBillboardGallery.json b/registry/components/HeroBillboardGallery.json new file mode 100644 index 0000000..08efd22 --- /dev/null +++ b/registry/components/HeroBillboardGallery.json @@ -0,0 +1,75 @@ +{ + "name": "HeroBillboardGallery", + "description": "Full-width hero section with centered text and 3-5 overlapping rotated images in gallery layout.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Explore Our Collection", + "minChars": 2, + "maxChars": 40 + }, + "description": { + "required": true, + "example": "Discover amazing products and experiences", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "Featured", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "mediaItems": { + "required": true, + "example": "[{ imageSrc: '/img1.jpg', imageAlt: 'Gallery 1' }, { imageSrc: '/img2.jpg', imageAlt: 'Gallery 2' }, { imageSrc: '/img3.jpg', imageAlt: 'Gallery 3' }]", + "note": "Array of 3-5 MediaItem objects. Each item can have imageSrc, videoSrc, imageAlt, videoAriaLabel. Supports 3-5 images maximum." + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'View Gallery', href: 'https://example.com' }", + "{ text: 'Learn More', href: 'about' }" + ], + "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "mediaItems": "Array<{ imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }> - Each item requires either imageSrc or videoSrc", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for portfolios", + "Use for image galleries", + "Requires buttons?[]", + "Requires mediaItems[]" + ], + "dont": [ + "Do not use less than 5 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroBillboardRotatedCarousel.json b/registry/components/HeroBillboardRotatedCarousel.json new file mode 100644 index 0000000..640675a --- /dev/null +++ b/registry/components/HeroBillboardRotatedCarousel.json @@ -0,0 +1,80 @@ +{ + "name": "HeroBillboardRotatedCarousel", + "description": "Hero section with centered text content and angled/rotated carousel below. Features auto-playing carousel with scaled and rotated side cards.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Transform Your Workflow", + "minChars": 2, + "maxChars": 60 + }, + "description": { + "required": true, + "example": "Experience the power of seamless collaboration and productivity tools designed for modern teams", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "New Release", + "minChars": 2, + "maxChars": 30 + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "Button variant controlled by ThemeProvider's defaultButtonVariant. All sections should be wrapped in a single ThemeProvider at the app/page level." + }, + "carouselItemRules": { + "required": true, + "minItems": 6, + "structure": { + "id": "string - Unique identifier (required)", + "imageSrc": "string - Image URL (optional)", + "videoSrc": "string - Video URL (optional, takes precedence over imageSrc)", + "imageAlt": "string - Alt text for image (optional)", + "videoAriaLabel": "string - ARIA label for video (optional)" + }, + "note": "Minimum 6 items required to prevent duplicate keys. Carousel displays 5 positions simultaneously (-2, -1, 0, 1, 2). Each item should have either imageSrc or videoSrc. Uses MediaContent component for rendering." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "carouselItems": "Array<{ id: string, imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }> - Carousel items (minimum 6 items)", + "autoPlay?": "boolean (default: true)", + "autoPlayInterval?": "number (default: 4000)", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for portfolios", + "Use for image galleries", + "Use for product catalogs", + "Use for e-commerce", + "Requires buttons?[]", + "Requires carouselItems[]" + ], + "dont": [ + "Do not use less than 5 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroBillboardScroll.json b/registry/components/HeroBillboardScroll.json new file mode 100644 index 0000000..b12039d --- /dev/null +++ b/registry/components/HeroBillboardScroll.json @@ -0,0 +1,100 @@ +{ + "name": "HeroBillboardScroll", + "description": "Full-screen hero section with centered text and media card that animates with 3D perspective transforms on scroll (desktop only).", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Scroll Animations", + "minChars": 2, + "maxChars": 60 + }, + "description": { + "required": true, + "example": "Experience smooth, performant animations as you scroll through your content", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "Unleash the Power", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/dashboard.jpg", + "note": "Image to display in the animated card. Supports external URLs with unoptimized prop" + }, + "videoSrc": { + "required": false, + "example": "/demo.mp4", + "note": "Video to display in the animated card. Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "Dashboard preview", + "note": "Empty string marks image as decorative (aria-hidden)" + }, + "animationBehavior": { + "desktop": { + "rotateX": "Animates from 20deg to 0deg based on scroll progress", + "scale": "Animates from 1.05 to 1 based on scroll progress", + "height": "h-[75svh] (75% of viewport height)", + "note": "Uses Framer Motion's useScroll and useTransform for smooth scroll-linked animations" + }, + "mobile": { + "rotateX": "Static 20deg rotation (no animation)", + "scale": "No scale animation", + "height": "h-[50svh] (50% of viewport height)", + "note": "Separate static div implementation to prevent performance issues and hydration errors" + }, + "perspective": "1000px applied to container for 3D effect" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'Get Started', onClick: () => console.log('Get Started clicked') }", + "{ text: 'Learn More', href: 'about' }" + ], + "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n console.log('Get Started clicked') }, { text: 'Learn More', href: 'about' }]} \n />\n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for product catalogs", + "Use for e-commerce", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroCarouselLogo.json b/registry/components/HeroCarouselLogo.json new file mode 100644 index 0000000..9fb957b --- /dev/null +++ b/registry/components/HeroCarouselLogo.json @@ -0,0 +1,78 @@ +{ + "name": "HeroCarouselLogo", + "description": "Full-screen hero section with auto-playing carousel background, large text logo at bottom that scales to fill container width, description and button row above, with progress bars and linear gradient blur overlay.", + "constraints": { + "textRules": { + "logoText": { + "required": true, + "example": "WEBILD", + "minChars": 2, + "maxChars": 20 + }, + "description": { + "required": true, + "example": "Create stunning, responsive websites with our comprehensive component library", + "minChars": 5, + "maxChars": 200 + } + }, + "mediaRules": { + "slides": { + "required": true, + "example": "[{ imageSrc: '/slide1.jpg', imageAlt: 'Slide 1' }, { imageSrc: '/slide2.jpg', imageAlt: 'Slide 2' }]", + "note": "Array of CarouselSlide objects. Each slide can have imageSrc, videoSrc, imageAlt, videoAriaLabel. Video takes precedence over image if both provided in a slide." + }, + "autoplayDelay": { + "required": false, + "default": 3000, + "note": "Milliseconds between automatic slide transitions" + }, + "showDimOverlay": { + "required": false, + "default": false, + "note": "Adds semi-transparent dark overlay (bg-background/20) over background media for improved text and logo contrast" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'Get Started', href: 'https://github.com' }", + "{ text: 'Learn More', href: 'about' }" + ], + "note": "Buttons are required (cannot be empty array). Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "logoText": "string", + "description": "string", + "buttons": "Array<{text: string, onClick?: () => void, href?: string}>", + "slides": "Array<{ imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }> - Carousel slide items", + "autoplayDelay?": "number (default: 3000)", + "showDimOverlay?": "boolean (default: false)", + "logoLineHeight?": "number (default: 1.1)", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Requires buttons[]", + "Requires slides[]" + ], + "dont": [ + "Do not use less than 5 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroLogo.json b/registry/components/HeroLogo.json new file mode 100644 index 0000000..c11b16a --- /dev/null +++ b/registry/components/HeroLogo.json @@ -0,0 +1,82 @@ +{ + "name": "HeroLogo", + "description": "Full-screen hero section with background media, large text logo at bottom that scales to fill container width, description and button row above, featuring a linear gradient blur overlay.", + "constraints": { + "textRules": { + "logoText": { + "required": true, + "example": "Webild", + "minChars": 2, + "maxChars": 20 + }, + "description": { + "required": true, + "example": "Building the future of web design with innovative solutions", + "minChars": 5, + "maxChars": 200 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/hero-background.jpg", + "note": "Background image that fills the viewport. Supports external URLs with unoptimized prop" + }, + "videoSrc": { + "required": false, + "example": "/hero-background.mp4", + "note": "Background video that fills the viewport. Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "Hero background", + "note": "Empty string marks image as decorative (aria-hidden)" + }, + "showDimOverlay": { + "required": false, + "default": false, + "note": "Adds semi-transparent dark overlay (bg-background/20) over background media for improved text and logo contrast" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'Get Started', href: 'https://github.com' }", + "{ text: 'Learn More', href: 'about' }" + ], + "note": "Buttons are required (cannot be empty array). Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "logoText": "string", + "description": "string", + "buttons": "Array<{text: string, onClick?: () => void, href?: string}>", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "showDimOverlay?": "boolean (default: false)", + "logoLineHeight?": "number (default: 1.1)", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Requires buttons[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroLogoBillboard.json b/registry/components/HeroLogoBillboard.json new file mode 100644 index 0000000..9f56bc2 --- /dev/null +++ b/registry/components/HeroLogoBillboard.json @@ -0,0 +1,72 @@ +{ + "name": "HeroLogoBillboard", + "description": "Hero section with large text logo at top that scales to fill container width, description text, and single framed media (card or browser style) below.", + "constraints": { + "textRules": { + "logoText": { + "required": true, + "example": "klime studio", + "minChars": 2, + "maxChars": 30 + }, + "description": { + "required": true, + "example": "we help driven founders build the brands of tomorrow through websites, product design & branding.", + "minChars": 5, + "maxChars": 300 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/hero-image.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "videoSrc": { + "required": false, + "example": "/hero-video.mp4", + "note": "Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "Product showcase", + "note": "Empty string marks image as decorative (aria-hidden)" + }, + "frameStyle": { + "required": false, + "options": [ + "card", + "browser" + ], + "default": "card", + "note": "'card' displays media in simple card with padding. 'browser' wraps media in browser mockup with address bar and window controls." + } + } + }, + "propsSchema": { + "logoText": "string", + "description": "string", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "frameStyle?": "'card' | 'browser' (default: 'card')", + "logoLineHeight?": "number (default: 1.1)", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [ + "Do not use multiple items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroLogoBillboardSplit.json b/registry/components/HeroLogoBillboardSplit.json new file mode 100644 index 0000000..3282070 --- /dev/null +++ b/registry/components/HeroLogoBillboardSplit.json @@ -0,0 +1,91 @@ +{ + "name": "HeroLogoBillboardSplit", + "description": "Hero section with split layout (description left, buttons right), large text logo that scales to fill container width, and single framed media at bottom. Supports flex-col or flex-col-reverse layout order.", + "constraints": { + "textRules": { + "logoText": { + "required": true, + "example": "ACME", + "minChars": 2, + "maxChars": 30 + }, + "description": { + "required": true, + "example": "Create stunning, responsive websites with our comprehensive component library", + "minChars": 5, + "maxChars": 300 + } + }, + "layoutRules": { + "layoutOrder": { + "required": true, + "options": [ + "default", + "reverse" + ], + "note": "'default' displays split section (description/buttons) then logo (flex-col). 'reverse' displays logo then split section (flex-col-reverse)." + } + }, + "buttonRules": { + "buttons": { + "required": true, + "minItems": 1, + "maxItems": 2, + "note": "Only first 2 buttons are displayed using slice(0, 2). Uses theme.defaultButtonVariant for styling." + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/hero-image.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "videoSrc": { + "required": false, + "example": "/hero-video.mp4", + "note": "Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "Product showcase", + "note": "Empty string marks image as decorative (aria-hidden)" + }, + "frameStyle": { + "required": false, + "options": [ + "card", + "browser" + ], + "default": "card", + "note": "'card' displays media in simple card with padding. 'browser' wraps media in browser mockup with address bar and window controls." + } + } + }, + "propsSchema": { + "logoText": "string", + "description": "string", + "buttons": "Array<{text: string, onClick?: () => void, href?: string}>", + "layoutOrder": "'default' | 'reverse'", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "frameStyle?": "'card' | 'browser' (default: 'card')", + "logoLineHeight?": "number (default: 1.1)", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Requires buttons[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroOverlay.json b/registry/components/HeroOverlay.json new file mode 100644 index 0000000..576feab --- /dev/null +++ b/registry/components/HeroOverlay.json @@ -0,0 +1,105 @@ +{ + "name": "HeroOverlay", + "description": "Full-screen hero section with background image/video overlay, circular blur effect, and configurable text positioning (center or bottom-left).", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Build Modern Web Experiences", + "minChars": 2, + "maxChars": 40 + }, + "description": { + "required": true, + "example": "Create stunning, responsive websites with our comprehensive component library", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "New Release", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/hero-background.jpg", + "note": "Background image that fills the viewport. Supports external URLs with unoptimized prop" + }, + "videoSrc": { + "required": false, + "example": "/hero-background.mp4", + "note": "Background video that fills the viewport. Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "Hero background", + "note": "Empty string marks image as decorative (aria-hidden)" + }, + "textPosition": { + "required": false, + "options": [ + "center", + "bottom-left" + ], + "default": "bottom-left", + "note": "'center' positions text in the center of viewport, 'bottom-left' positions text at bottom-left corner" + }, + "showBlur": { + "required": false, + "default": true, + "note": "Controls circular blur effect with radial gradient. Blur follows text position (centered or bottom-left corner)" + }, + "showDimOverlay": { + "required": false, + "default": false, + "note": "Adds semi-transparent dark overlay (bg-background/20) over background media for improved text contrast" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Learn More', href: 'about' }" + ], + "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "textPosition?": "'center' | 'bottom-left' (default: 'bottom-left')", + "showDimOverlay?": "boolean (default: false)", + "showBlur?": "boolean (default: true)", + "ariaLabel?": "string (default: 'Hero section')", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroSplit.json b/registry/components/HeroSplit.json new file mode 100644 index 0000000..b470bf7 --- /dev/null +++ b/registry/components/HeroSplit.json @@ -0,0 +1,96 @@ +{ + "name": "HeroSplit", + "description": "Split-layout hero section with text content on one side and single image/video on the other, with responsive centering.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Build Better Products", + "minChars": 2, + "maxChars": 36 + }, + "description": { + "required": true, + "example": "Create exceptional user experiences with our design system", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "New Release", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/hero-image.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "videoSrc": { + "required": false, + "example": "/hero-video.mp4", + "note": "Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "Product showcase", + "note": "Empty string marks image as decorative (aria-hidden)" + }, + "imagePosition": { + "required": false, + "options": [ + "left", + "right" + ], + "default": "right" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional). External URLs (https://, http://, www.) open in new tab. Internal values (e.g., 'about', 'contact') scroll to #about, #contact sections", + "onClick": "() => void - Additional click handler (optional)", + "props": "Partial - Additional button props like className, textClassName (optional)" + }, + "examples": [ + "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Learn More', href: 'about' }" + ], + "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "avatars?": "Avatar[] - Array of avatar objects with src and alt properties", + "avatarText?": "string - Text displayed next to the avatar group", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "ariaLabel?": "string (default: 'Hero section')", + "imagePosition?": "'left' | 'right' (default: 'right')", + "fixedMediaHeight?": "boolean (default: true) - When true, media wrapper is aspect-square on mobile and md:h-[65vh] on desktop", + "className?": "string" + }, + "usageExample": "\n \n", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Requires buttons?[]", + "Requires avatars?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/HeroSplitKpi.json b/registry/components/HeroSplitKpi.json new file mode 100644 index 0000000..f4d9885 --- /dev/null +++ b/registry/components/HeroSplitKpi.json @@ -0,0 +1,105 @@ +{ + "name": "HeroSplitKpi", + "description": "Split-layout hero with media image/video and three KPI metric boxes positioned around it.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "The Future of Supply Chain", + "minChars": 2, + "maxChars": 36 + }, + "description": { + "required": true, + "example": "Ship globally within 3 days post-production with smart fulfillment", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "Trusted by 150+ Brands", + "minChars": 2, + "maxChars": 30 + } + }, + "kpiRules": { + "kpis": { + "required": true, + "note": "Array of exactly 3 KPI items. Each item has 'value' (the metric) and 'label' (description)", + "structure": { + "value": "string - The metric value (e.g., '99.8%', '10x', '4-10 Days')", + "label": "string - Description of the metric (e.g., 'Order Accuracy')" + }, + "example": "[{ value: '4-10 Days', label: 'Worldwide Delivery' }, { value: '99.8%', label: 'Order Accuracy' }, { value: '10x', label: 'Faster Lead Times' }]" + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/hero-image.jpg", + "note": "Image displayed in scaled card wrapper" + }, + "videoSrc": { + "required": false, + "example": "/hero-video.mp4", + "note": "Video takes precedence over image if both provided" + }, + "imageAlt": { + "required": false, + "example": "Product showcase", + "note": "Empty string marks image as decorative (aria-hidden)" + }, + "imagePosition": { + "required": false, + "options": [ + "left", + "right" + ], + "default": "right" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Additional click handler (optional)" + } + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "kpis": "[KpiItem, KpiItem, KpiItem] - Array of exactly 3 KPI items with value and label", + "enableKpiAnimation": "boolean - Enable/disable mouse-following animation on KPI boxes", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "avatars?": "Avatar[] - Array of avatar objects with src and alt properties", + "avatarText?": "string - Text displayed next to the avatar group", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'Hero video')", + "ariaLabel?": "string (default: 'Hero section')", + "imagePosition?": "'left' | 'right' (default: 'right')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for statistics displays", + "Use for achievement showcases", + "Requires kpis[]", + "Requires buttons?[]", + "Requires avatars?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/InlineImageSplitTextAbout.json b/registry/components/InlineImageSplitTextAbout.json new file mode 100644 index 0000000..40cf29f --- /dev/null +++ b/registry/components/InlineImageSplitTextAbout.json @@ -0,0 +1,61 @@ +{ + "name": "InlineImageSplitTextAbout", + "description": "About section with dynamic heading composed of alternating text and inline image segments.", + "constraints": { + "textRules": { + "heading[].content": { + "required": "text segments require content", + "example": "Building the future with", + "minChars": 1, + "maxChars": 100, + "note": "Each text segment in the heading array" + } + }, + "imageRules": { + "heading[].src": { + "required": "image segments require src", + "example": "/brand/logo.png or https://example.com/image.png", + "note": "Supports local paths and external URLs. External URLs are rendered with unoptimized flag." + }, + "heading[].alt": { + "required": false, + "example": "Company logo", + "note": "Optional alt text for images. Omit or use empty string for decorative images (aria-hidden=true when empty)." + } + }, + "headingRules": { + "minSegments": 1, + "note": "heading array can contain any number of text and image segments in any order. Images automatically alternate rotation direction (1st: -rotate-12, 2nd: rotate-12, etc.)." + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "Button variant controlled by ThemeProvider's defaultButtonVariant. Border radius controlled by ThemeProvider's borderRadius." + } + }, + "propsSchema": { + "heading": "Array<{ type: 'text'; content: string } | { type: 'image'; src: string; alt?: string }>", + "buttons?": "Array<{ text: string, onClick?: () => void, href?: string, props?: Partial> }>", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'About section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\n\n \n", + "do": [ + "Use for about pages", + "Use for company information", + "Requires heading[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/Input.json b/registry/components/Input.json new file mode 100644 index 0000000..85fc7cf --- /dev/null +++ b/registry/components/Input.json @@ -0,0 +1,35 @@ +{ + "name": "Input", + "description": "Styled text input field with secondary-button styling and rounded-theme borders.", + "constraints": { + "textRules": { + "placeholder": { + "required": false, + "example": "Enter your name", + "minChars": 2, + "maxChars": 50 + } + } + }, + "propsSchema": { + "value": "string (required)", + "onChange": "(value: string) => void (required)", + "type?": "string (default: 'text')", + "placeholder?": "string", + "required?": "boolean (default: false)", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "className?": "string" + }, + "usageExample": " setName(value)} type=\"text\" placeholder=\"Name\" required />", + "do": [ + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MediaAbout.json b/registry/components/MediaAbout.json new file mode 100644 index 0000000..3dba4ea --- /dev/null +++ b/registry/components/MediaAbout.json @@ -0,0 +1,84 @@ +{ + "name": "MediaAbout", + "description": "Full-width media about section with centered TextBox content overlaid on image or video.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Elevate Your Experience", + "minChars": 2, + "maxChars": 100 + }, + "description": { + "required": true, + "example": "Discover a new way to connect, create, and inspire with our innovative solutions.", + "minChars": 10, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "About Us", + "minChars": 2, + "maxChars": 30 + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/about-hero.jpg", + "note": "Either imageSrc or videoSrc should be provided. Image is recommended for static visuals." + }, + "videoSrc": { + "required": false, + "example": "/about-video.mp4", + "note": "Either imageSrc or videoSrc should be provided. Video is recommended for motion content." + }, + "imageAlt": { + "required": false, + "example": "Our team in action", + "note": "Alt text for image. Defaults to empty string (decorative)." + }, + "videoAriaLabel": { + "required": false, + "example": "About us video", + "note": "ARIA label for video accessibility." + } + }, + "buttonRules": { + "maxButtons": 2, + "minButtons": 0, + "note": "Buttons are part of TextBox, centered and overlaid on media. First button is primary, second is secondary. Button variant controlled by ThemeProvider's defaultButtonVariant." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string", + "videoAriaLabel?": "string", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'About section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for about pages", + "Use for company information", + "Use for product catalogs", + "Use for e-commerce", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MediaSplitTabsAbout.json b/registry/components/MediaSplitTabsAbout.json new file mode 100644 index 0000000..c416874 --- /dev/null +++ b/registry/components/MediaSplitTabsAbout.json @@ -0,0 +1,90 @@ +{ + "name": "MediaSplitTabsAbout", + "description": "Split-layout about section with interactive tabs, animated descriptions, and 60/40 grid with media.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Why Choose Us", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": false, + "example": "We deliver excellence across every aspect of our work", + "minChars": 10, + "maxChars": 200 + } + }, + "tabRules": { + "minTabs": 2, + "maxTabs": 5, + "structure": { + "id": "string - Unique identifier (required)", + "label": "string - Tab button text (required)", + "description": "string - Description shown when tab is active (required)" + }, + "note": "First tab is selected by default. Tab indicator dot animates smoothly between tabs." + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/team-photo.jpg", + "note": "Either imageSrc or videoSrc should be provided." + }, + "videoSrc": { + "required": false, + "example": "/intro-video.mp4", + "note": "Either imageSrc or videoSrc should be provided." + }, + "imageAlt": { + "required": false, + "example": "Team collaboration", + "note": "Alt text for image." + }, + "videoAriaLabel": { + "required": false, + "example": "Introduction video", + "note": "ARIA label for video accessibility." + }, + "imagePosition": { + "required": false, + "default": "right", + "options": [ + "left", + "right" + ], + "note": "Position of media card relative to content card." + } + } + }, + "propsSchema": { + "title": "string", + "description?": "string", + "tabs": "Array<{ id: string, label: string, description: string }> - Tab options for content switching", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string", + "videoAriaLabel?": "string", + "imagePosition?": "'left' | 'right' (default: 'right')", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'About section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for about pages", + "Use for company information", + "Requires tabs[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricCardEleven.json b/registry/components/MetricCardEleven.json new file mode 100644 index 0000000..57cacef --- /dev/null +++ b/registry/components/MetricCardEleven.json @@ -0,0 +1,95 @@ +{ + "name": "MetricCardEleven", + "description": "Metrics section with paired text and media cards. Each metric displays a value card alongside an image/video card in a 2-column layout.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Impact", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "See the results we've delivered for our clients", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Results", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "value": { + "required": true, + "example": "10M+", + "minChars": 1, + "maxChars": 15, + "note": "Large metric value displayed prominently at top of text card" + }, + "title": { + "required": true, + "example": "Organic Views", + "minChars": 2, + "maxChars": 50, + "note": "Metric title displayed at bottom of text card, truncates" + }, + "description": { + "required": true, + "example": "Growth through smart content strategy", + "minChars": 5, + "maxChars": 100, + "note": "Metric description below accent divider, truncates to single line" + }, + "media": { + "required": true, + "note": "Either imageSrc or videoSrc must be provided for each metric" + } + }, + "itemRules": { + "minItems": 1, + "maxItems": 6, + "recommendedItems": "2-4" + } + }, + "propsSchema": { + "metrics": "Array<{ id: string, value: string, title: string, description: string, imageSrc?: string, imageAlt?: string, videoSrc?: string, videoAriaLabel?: string }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal'", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image'", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Metrics section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items", + "Do not use more than 6 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricCardFourteen.json b/registry/components/MetricCardFourteen.json new file mode 100644 index 0000000..c74626c --- /dev/null +++ b/registry/components/MetricCardFourteen.json @@ -0,0 +1,69 @@ +{ + "name": "MetricCardFourteen", + "description": "Metrics section with animated title, tag badge, and metric cards with large values and descriptions.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "We're committed to sustainability and reducing our environmental impact.", + "minChars": 10, + "maxChars": 200 + }, + "tag": { + "required": true, + "example": "Impact", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "id": { + "required": true, + "example": "1", + "note": "Unique identifier for each metric" + }, + "value": { + "required": true, + "example": "16x", + "minChars": 1, + "maxChars": 10, + "note": "Large metric value displayed prominently" + }, + "description": { + "required": true, + "example": "By using 80% less steel, we've lowered our carbon footprint by 16x.", + "minChars": 10, + "maxChars": 200, + "note": "Description text below the divider" + } + }, + "itemRules": { + "minItems": 1, + "maxItems": 4, + "recommendedItems": 2 + } + }, + "propsSchema": { + "title": "string", + "tag": "string", + "metrics": "Array<{ id: string, value: string, description: string }>", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Metrics section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]" + ], + "dont": [ + "Do not use more than 4 items", + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricCardOne.json b/registry/components/MetricCardOne.json new file mode 100644 index 0000000..08d1471 --- /dev/null +++ b/registry/components/MetricCardOne.json @@ -0,0 +1,91 @@ +{ + "name": "MetricCardOne", + "description": "Metric card with large gradient value text, title, description, and icon badge.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Impact", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Key metrics that showcase our growth and success", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Statistics", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "value": { + "required": true, + "example": "100", + "minChars": 1, + "maxChars": 5, + "note": "Large metric value displayed with gradient effect." + }, + "title": { + "required": true, + "example": "million", + "minChars": 2, + "maxChars": 30, + "note": "Metric label displayed below value with negative margin overlap" + }, + "description": { + "required": true, + "example": "Active users worldwide", + "minChars": 5, + "maxChars": 150, + "note": "Supporting description text displayed below title" + }, + "icon": { + "required": true, + "example": "TrendingUp", + "note": "Lucide icon displayed in bottom-left corner with primary-button styling" + } + } + }, + "propsSchema": { + "metrics": "Array<{ id: string, value: string, title: string, description: string, icon: LucideIcon }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Metrics section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricCardSeven.json b/registry/components/MetricCardSeven.json new file mode 100644 index 0000000..fadbaf5 --- /dev/null +++ b/registry/components/MetricCardSeven.json @@ -0,0 +1,90 @@ +{ + "name": "MetricCardSeven", + "description": "Metric card with large accent value, title, and feature list with checkmarks.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Our Impact", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Key metrics that showcase our growth", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Stats", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "value": { + "required": true, + "example": "15+", + "minChars": 1, + "maxChars": 10, + "note": "Large metric value displayed at top of card in accent color" + }, + "title": { + "required": true, + "example": "Years in business consulting", + "minChars": 5, + "maxChars": 60, + "note": "Metric description displayed below value" + }, + "items": { + "required": true, + "example": "['8+ industries served', '5+ countries reached']", + "minItems": 1, + "maxItems": 5, + "note": "Array of supporting bullet points displayed with checkmarks" + } + } + }, + "propsSchema": { + "metrics": "Array<{ id: string, value: string, title: string, items: string[] }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Metrics section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricCardTen.json b/registry/components/MetricCardTen.json new file mode 100644 index 0000000..f5475e5 --- /dev/null +++ b/registry/components/MetricCardTen.json @@ -0,0 +1,106 @@ +{ + "name": "MetricCardTen", + "description": "Job listing style metric cards with title, subtitle, category indicator, value, and optional footer buttons.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Open Positions", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Join our team and help shape the future of AI", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Careers", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "title": { + "required": true, + "example": "Senior Software Engineer, Platform", + "minChars": 5, + "maxChars": 80, + "note": "Main title displayed at top of card, truncates if too long" + }, + "subtitle": { + "required": true, + "example": "San Francisco, CA · Full-time · Remote eligible", + "minChars": 5, + "maxChars": 100, + "note": "Secondary info like location, type, or details" + }, + "category": { + "required": true, + "example": "Engineering", + "minChars": 2, + "maxChars": 30, + "note": "Category label with dot indicator, truncates on overflow" + }, + "value": { + "required": true, + "example": "$185K – $265K", + "minChars": 1, + "maxChars": 25, + "note": "Value displayed on bottom right (salary, price, etc.)" + }, + "buttons": { + "required": false, + "maxItems": 2, + "note": "Optional buttons in footer section with accent background" + } + }, + "itemRules": { + "minItems": 1, + "maxItems": 12, + "recommendedItems": "3-6" + } + }, + "propsSchema": { + "metrics": "Array<{ id: string, title: string, subtitle: string, category: string, value: string, buttons?: Array<{text: string, onClick?: () => void, href?: string}> }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal'", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'centered' | 'left' | 'right' | 'spread'", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Metrics section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for pricing pages", + "Use for subscription tiers", + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 12 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricCardThree.json b/registry/components/MetricCardThree.json new file mode 100644 index 0000000..2e7dfa5 --- /dev/null +++ b/registry/components/MetricCardThree.json @@ -0,0 +1,85 @@ +{ + "name": "MetricCardThree", + "description": "Metric card with icon badge, title header, and large value display.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Performance Metrics", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Track your key performance indicators", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "KPIs", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "icon": { + "required": true, + "example": "TrendingUp", + "note": "Lucide icon displayed in primary-button styled circular badge" + }, + "title": { + "required": true, + "example": "Conversions", + "minChars": 2, + "maxChars": 30, + "note": "Metric category/label displayed next to icon" + }, + "value": { + "required": true, + "example": "7,000+", + "minChars": 1, + "maxChars": 15, + "note": "Large metric value displayed below icon and title" + } + } + }, + "propsSchema": { + "metrics": "Array<{ id: string, icon: LucideIcon, title: string, value: string }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Metrics section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricCardTwo.json b/registry/components/MetricCardTwo.json new file mode 100644 index 0000000..edeb636 --- /dev/null +++ b/registry/components/MetricCardTwo.json @@ -0,0 +1,79 @@ +{ + "name": "MetricCardTwo", + "description": "Simple metric card with large value and description text.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Key Metrics", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Performance indicators at a glance", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Stats", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "value": { + "required": true, + "example": "98%", + "minChars": 1, + "maxChars": 15, + "note": "Large metric value displayed prominently" + }, + "description": { + "required": true, + "example": "Customer Satisfaction Rate", + "minChars": 5, + "maxChars": 100, + "note": "Metric label/description displayed below value" + } + } + }, + "propsSchema": { + "metrics": "Array<{ id: string, value: string, description: string }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Metrics section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/MetricSplitMediaAbout.json b/registry/components/MetricSplitMediaAbout.json new file mode 100644 index 0000000..46ef7bc --- /dev/null +++ b/registry/components/MetricSplitMediaAbout.json @@ -0,0 +1,63 @@ +{ + "name": "MetricSplitMediaAbout", + "description": "Split-layout about section with text, metrics cards, and media in a 2-column grid.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "We help automate what matters most", + "minChars": 10, + "maxChars": 100 + }, + "description": { + "required": true, + "example": "Hamilton, a growing e-commerce business, was overwhelmed by repetitive tasks. We built custom automation that integrated with their tools.", + "minChars": 20, + "maxChars": 500 + }, + "tag": { + "required": false, + "example": "Case study", + "minChars": 2, + "maxChars": 30 + } + }, + "metricRules": { + "minMetrics": 1, + "maxMetrics": 2, + "structure": { + "value": "string - Large metric value (required, e.g., '50+', '40%', '10x')", + "title": "string - Metric label/title (required, e.g., 'Hours saved every month')" + }, + "note": "Provide 1-2 metrics for optimal layout. Grid displays 1 metric as single column, 2 metrics as 2 columns on desktop." + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "metrics": "Array<{ value: string, title: string }>", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string", + "videoAriaLabel?": "string (default: 'About section video')", + "ariaLabel?": "string (default: 'About section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\nimport { Sparkles } from 'lucide-react';\n\n\n \n", + "do": [ + "Use for about pages", + "Use for company information", + "Use for statistics displays", + "Use for achievement showcases", + "Requires metrics[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/NavbarLayoutFloatingInline.json b/registry/components/NavbarLayoutFloatingInline.json new file mode 100644 index 0000000..03f0992 --- /dev/null +++ b/registry/components/NavbarLayoutFloatingInline.json @@ -0,0 +1,69 @@ +{ + "name": "NavbarLayoutFloatingInline", + "description": "Floating inline navbar with centered links, left-aligned logo, and right-aligned call-to-action button.", + "constraints": { + "minLinks": 3, + "maxLinks": 6, + "preferredCount": 4, + "brandRules": { + "required": false, + "minChars": 2, + "maxChars": 20, + "example": "Webild", + "fallbackBehavior": "Shows brandName text" + }, + "buttonRules": { + "text": { + "required": true, + "minChars": 2, + "maxChars": 24, + "example": "Get Started" + }, + "href": { + "required": false, + "format": "url | section-id", + "example": "https://webild.io" + }, + "onClick": { + "required": false, + "note": "Optional click handler" + } + }, + "linkRules": { + "name": { + "required": true, + "minChars": 2, + "maxChars": 15, + "example": "About" + }, + "id": { + "required": true, + "format": "section-id | url", + "examples": [ + "about", + "services", + "https://github.com", + "www.example.com" + ], + "behavior": "Internal IDs scroll to section, URLs open in new tab" + } + } + }, + "propsSchema": { + "navItems": "Array<{name: string, id: string}>", + "brandName?": "string (default: 'Webild')", + "button": "{text: string, onClick?: () => void, href?: string}", + "className?": "string (default: '')" + }, + "usageExample": "", + "do": [ + "Use for general use", + "Requires navItems[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/NavbarLayoutFloatingOverlay.json b/registry/components/NavbarLayoutFloatingOverlay.json new file mode 100644 index 0000000..16b67d5 --- /dev/null +++ b/registry/components/NavbarLayoutFloatingOverlay.json @@ -0,0 +1,69 @@ +{ + "name": "NavbarLayoutFloatingOverlay", + "description": "Floating rounded navbar with right‑side CTA and a circular menu button. Clicking the button opens a rounded overlay panel with the site menu.", + "constraints": { + "minLinks": 2, + "maxLinks": 8, + "preferredCount": 5, + "brandRules": { + "required": false, + "minChars": 2, + "maxChars": 20, + "example": "Webild", + "fallbackBehavior": "Shows brandName text" + }, + "buttonRules": { + "text": { + "required": true, + "minChars": 2, + "maxChars": 24, + "example": "Get Started" + }, + "href": { + "required": false, + "format": "url | section-id", + "example": "https://webild.io" + }, + "onClick": { + "required": false, + "note": "Optional click handler" + } + }, + "linkRules": { + "name": { + "required": true, + "minChars": 2, + "maxChars": 15, + "example": "About" + }, + "id": { + "required": true, + "format": "section-id | url", + "examples": [ + "about", + "services", + "https://github.com", + "www.example.com" + ], + "behavior": "Internal IDs scroll to section, URLs open in new tab" + } + } + }, + "propsSchema": { + "navItems": "Array<{name: string, id: string}>", + "className?": "string", + "brandName?": "string (default: 'Webild')", + "button": "{text: string, onClick?: () => void, href?: string}" + }, + "usageExample": "", + "do": [ + "Use for general use", + "Requires navItems[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/NavbarStyleApple.json b/registry/components/NavbarStyleApple.json new file mode 100644 index 0000000..99fbdf7 --- /dev/null +++ b/registry/components/NavbarStyleApple.json @@ -0,0 +1,51 @@ +{ + "name": "NavbarStyleApple", + "description": "Minimal Apple-style navigation bar with brand/logo on the left and inline navigation links aligned right.", + "constraints": { + "minLinks": 3, + "maxLinks": 7, + "preferredCount": 5, + "brandRules": { + "required": false, + "minChars": 2, + "maxChars": 20, + "example": "Webild", + "fallbackBehavior": "Shows brandName text" + }, + "linkRules": { + "name": { + "required": true, + "minChars": 2, + "maxChars": 15, + "example": "About" + }, + "id": { + "required": true, + "format": "section-id | url", + "examples": [ + "about", + "services", + "https://github.com", + "www.example.com" + ], + "behavior": "Internal IDs scroll to section, URLs open in new tab" + } + } + }, + "propsSchema": { + "navItems": "Array<{name: string, id: string}>", + "brandName?": "string (default: 'Webild')" + }, + "usageExample": "", + "do": [ + "Use for product catalogs", + "Use for e-commerce", + "Requires navItems[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/NavbarStyleCentered.json b/registry/components/NavbarStyleCentered.json new file mode 100644 index 0000000..9785b4b --- /dev/null +++ b/registry/components/NavbarStyleCentered.json @@ -0,0 +1,72 @@ +{ + "name": "NavbarStyleCentered", + "description": "Centered dropdown navigation with animated expand/collapse and staggered link reveals.", + "constraints": { + "minLinks": 3, + "maxLinks": 6, + "preferredCount": 5, + "brandRules": { + "required": false, + "minChars": 2, + "maxChars": 20, + "example": "Webild", + "fallbackBehavior": "Shows brandName text" + }, + "buttonRules": { + "text": { + "required": true, + "minChars": 2, + "maxChars": 15, + "example": "Get Started" + }, + "href": { + "required": false, + "format": "url | section-id", + "example": "contact" + }, + "onClick": { + "required": false, + "note": "Optional click handler" + } + }, + "linkRules": { + "name": { + "required": true, + "minChars": 2, + "maxChars": 15, + "example": "About" + }, + "id": { + "required": true, + "format": "section-id | url", + "examples": [ + "about", + "services", + "https://github.com", + "www.example.com" + ], + "behavior": "Internal IDs scroll to section, URLs open in new tab" + } + } + }, + "propsSchema": { + "navItems": "Array<{name: string, id: string}>", + "button": "{text: string, onClick?: () => void, href?: string}", + "brandName?": "string (default: 'Webild')", + "className?": "string (default: '')" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires navItems[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/NavbarStyleFullscreen.json b/registry/components/NavbarStyleFullscreen.json new file mode 100644 index 0000000..b5ec216 --- /dev/null +++ b/registry/components/NavbarStyleFullscreen.json @@ -0,0 +1,67 @@ +{ + "name": "NavbarStyleFullscreen", + "description": "Fullscreen overlay navigation with animated menu reveal and staggered link animations.", + "constraints": { + "minLinks": 3, + "maxLinks": 5, + "preferredCount": 5, + "brandRules": { + "required": false, + "minChars": 2, + "maxChars": 20, + "example": "Webild", + "fallbackBehavior": "Shows brandName text" + }, + "linkRules": { + "name": { + "required": true, + "minChars": 2, + "maxChars": 15, + "example": "About" + }, + "id": { + "required": true, + "format": "section-id | url", + "examples": [ + "about", + "services", + "https://github.com", + "www.example.com" + ], + "behavior": "Internal IDs scroll to section, URLs open in new tab" + } + }, + "bottomTextRules": { + "bottomLeftText": { + "required": false, + "minChars": 2, + "maxChars": 30, + "example": "Global Community" + }, + "bottomRightText": { + "required": false, + "minChars": 2, + "maxChars": 30, + "example": "hello@example.com" + } + } + }, + "propsSchema": { + "navItems": "Array<{name: string, id: string}>", + "brandName?": "string (default: 'Webild')", + "bottomLeftText?": "string (default: 'Global Community')", + "bottomRightText?": "string (default: 'hello@example.com')" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Requires navItems[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/NavbarStyleMinimal.json b/registry/components/NavbarStyleMinimal.json new file mode 100644 index 0000000..a7f1cdb --- /dev/null +++ b/registry/components/NavbarStyleMinimal.json @@ -0,0 +1,45 @@ +{ + "name": "NavbarStyleMinimal", + "description": "A minimal navbar with left-aligned logo and optional right-aligned call-to-action button.", + "constraints": { + "brandRules": { + "required": false, + "minChars": 2, + "maxChars": 20, + "example": "Webild", + "fallbackBehavior": "Shows brandName text" + }, + "buttonRules": { + "text": { + "required": true, + "minChars": 2, + "maxChars": 24, + "example": "Get Started" + }, + "href": { + "required": false, + "format": "url | section-id", + "example": "https://webild.io" + }, + "onClick": { + "required": false, + "note": "Optional click handler" + } + } + }, + "propsSchema": { + "brandName?": "string (default: 'Webild')", + "button": "{text: string, onClick?: () => void, href?: string}", + "className?": "string (default: '')" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/PlainBackground.json b/registry/components/PlainBackground.json new file mode 100644 index 0000000..436c889 --- /dev/null +++ b/registry/components/PlainBackground.json @@ -0,0 +1,18 @@ +{ + "name": "PlainBackground", + "description": "Simple solid background using theme background color.", + "constraints": {}, + "propsSchema": { + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/PricingCardEight.json b/registry/components/PricingCardEight.json new file mode 100644 index 0000000..b75e418 --- /dev/null +++ b/registry/components/PricingCardEight.json @@ -0,0 +1,84 @@ +{ + "name": "PricingCardEight", + "description": "Pricing card with nested card layout featuring badge, price, buttons in secondary-button container, and feature list below.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Choose Your Plan", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Select the perfect plan for your needs", + "minChars": 10, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "Pricing", + "minChars": 2, + "maxChars": 30 + } + }, + "planRules": { + "minPlans": 1, + "maxPlans": 6, + "structure": { + "id": "string - Unique identifier (required)", + "badge": "string - Badge text, e.g., 'Most Popular' (required)", + "badgeIcon": "LucideIcon - Optional icon for badge", + "price": "string - Price display, e.g., '$29/mo' (required)", + "subtitle": "string - Subtitle below price, e.g., 'Perfect for small teams' (required)", + "buttons": "Array<{text: string, onClick?: () => void, href?: string}> - Action buttons, max 2 (required)", + "features": "string[] - List of features included (required)" + }, + "note": "Each plan displays in a nested card layout with secondary-button styling for the top section." + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "Buttons render full-width inside secondary-button container. Button variant controlled by ThemeProvider." + } + }, + "propsSchema": { + "plans": "Array<{ id: string, badge: string, badgeIcon?: LucideIcon, price: string, subtitle: string, buttons: Array<{text: string, onClick?: () => void, href?: string}>, features: string[] }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal'", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image'", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Pricing section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Requires plans[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/PricingCardFive.json b/registry/components/PricingCardFive.json new file mode 100644 index 0000000..58bd7cc --- /dev/null +++ b/registry/components/PricingCardFive.json @@ -0,0 +1,106 @@ +{ + "name": "PricingCardFive", + "description": "Vertical stack pricing cards with split layout showing plan details and feature checklist.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Simple, Transparent Pricing", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Choose the plan that fits your needs", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Pricing", + "minChars": 2, + "maxChars": 30 + } + }, + "planRules": { + "id": { + "required": true, + "example": "monthly-retainer", + "minChars": 1, + "maxChars": 30 + }, + "tag": { + "required": true, + "example": "Monthly Retainer Plan", + "minChars": 2, + "maxChars": 40 + }, + "price": { + "required": true, + "example": "$5,000", + "minChars": 1, + "maxChars": 20 + }, + "period": { + "required": true, + "example": "/m", + "minChars": 1, + "maxChars": 10 + }, + "description": { + "required": true, + "example": "Scale design, no-code builds & copy quicker than recruiting in-house.", + "minChars": 10, + "maxChars": 200 + }, + "button": { + "required": true, + "note": "ButtonConfig with text and href or onClick" + }, + "featuresTitle": { + "required": true, + "example": "What's Included:", + "minChars": 2, + "maxChars": 50 + }, + "features": { + "required": true, + "example": [ + "Unlimited design requests", + "48-hour turnaround" + ], + "note": "Array of feature strings displayed as checklist" + } + } + }, + "propsSchema": { + "plans": "Array<{ id: string, tag: string, tagIcon?: LucideIcon, price: string, period: string, description: string, button: {text: string, onClick?: () => void, href?: string}, featuresTitle: string, features: string[] }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Pricing section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Requires plans[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/PricingCardNine.json b/registry/components/PricingCardNine.json new file mode 100644 index 0000000..43056cd --- /dev/null +++ b/registry/components/PricingCardNine.json @@ -0,0 +1,99 @@ +{ + "name": "PricingCardNine", + "description": "Pricing cards with image, price tag, title, feature checklist, and CTA button.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Coaching Plans", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Choose the plan that fits your goals", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Pricing", + "minChars": 2, + "maxChars": 30 + } + }, + "planRules": { + "id": { + "required": true, + "example": "basic", + "minChars": 1, + "maxChars": 30 + }, + "title": { + "required": true, + "example": "Basic", + "minChars": 2, + "maxChars": 40 + }, + "price": { + "required": true, + "example": "$59", + "minChars": 1, + "maxChars": 20 + }, + "period": { + "required": true, + "example": "/month", + "minChars": 1, + "maxChars": 10 + }, + "imageSrc": { + "required": true, + "example": "/images/coaching-basic.jpg", + "note": "Image for the plan card" + }, + "button": { + "required": true, + "note": "ButtonConfig with text and href or onClick" + }, + "features": { + "required": true, + "example": [ + "Free initial consultation", + "Weekly checking" + ], + "note": "Array of feature strings displayed as checklist" + } + } + }, + "propsSchema": { + "plans": "Array<{ id: string, title: string, price: string, period: string, features: string[], button: {text: string, onClick?: () => void, href?: string}, imageSrc: string, imageAlt?: string }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Pricing section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Requires plans[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/PricingCardOne.json b/registry/components/PricingCardOne.json new file mode 100644 index 0000000..6209ebf --- /dev/null +++ b/registry/components/PricingCardOne.json @@ -0,0 +1,100 @@ +{ + "name": "PricingCardOne", + "description": "Pricing card with badge, price, subtitle, and feature list with checkmarks.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Choose Your Plan", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Select the perfect plan for your needs", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Pricing", + "minChars": 2, + "maxChars": 30 + } + }, + "pricingPlanRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "badge": { + "required": true, + "example": "Most Popular", + "minChars": 2, + "maxChars": 30, + "note": "Required for visual consistency across all cards" + }, + "price": { + "required": true, + "example": "$29/mo", + "minChars": 1, + "maxChars": 20 + }, + "subtitle": { + "required": true, + "example": "Perfect for small teams", + "minChars": 5, + "maxChars": 100, + "note": "Required for visual consistency across all cards" + }, + "features": { + "required": true, + "example": [ + "Up to 10 team members", + "100GB storage", + "Priority support" + ], + "note": "Array of feature strings, required for visual consistency" + }, + "badgeIcon": { + "required": false, + "example": "Sparkles", + "note": "Optional Lucide icon to display next to badge" + } + } + }, + "propsSchema": { + "plans": "Array<{ id: string, badge: string, badgeIcon?: LucideIcon, price: string, subtitle: string, features: string[] }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Pricing section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Requires plans[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/PricingCardThree.json b/registry/components/PricingCardThree.json new file mode 100644 index 0000000..8288ffd --- /dev/null +++ b/registry/components/PricingCardThree.json @@ -0,0 +1,111 @@ +{ + "name": "PricingCardThree", + "description": "Pricing card with optional floating badge, price, plan name, two CTA buttons, and feature list.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Choose Your Plan", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Select the perfect plan for your needs", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Pricing", + "minChars": 2, + "maxChars": 30 + } + }, + "pricingPlanRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "badge": { + "required": false, + "example": "Most popular plan", + "minChars": 2, + "maxChars": 40, + "note": "Optional badge that floats above the card. Can be on ANY plan. Always exists but uses visible/invisible for consistent spacing." + }, + "badgeIcon": { + "required": false, + "example": "Sparkles", + "note": "Optional Lucide icon to display next to badge" + }, + "price": { + "required": true, + "example": "$29/mo", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Business plan", + "minChars": 2, + "maxChars": 50, + "note": "Plan name displayed below price" + }, + "buttons": { + "required": true, + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "First button (index 0) = primary-button, second (index 1) = secondary-button. Button variant controlled by ThemeProvider's defaultButtonVariant. Border radius controlled by ThemeProvider's borderRadius. All sections should be wrapped in a single ThemeProvider at the app/page level." + }, + "features": { + "required": true, + "example": [ + "Up to 10 team members", + "100GB storage", + "Priority support" + ], + "note": "Array of feature strings, required for visual consistency" + } + } + }, + "propsSchema": { + "plans": "Array<{ id: string, badge?: string, badgeIcon?: LucideIcon, price: string, name: string, buttons: Array<{text: string, onClick?: () => void, href?: string}>, features: string[] }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Pricing section')", + "className?": "string" + }, + "usageExample": " console.log('clicked') }, { text: 'Chat to sales', onClick: () => console.log('chat') }], features: ['Up to 10 users', '20GB storage', 'Email support'] }, { id: '2', badge: 'Most popular plan', badgeIcon: Sparkles, price: '$20/mo', name: 'Business plan', buttons: [{ text: 'Get started', onClick: () => console.log('clicked') }, { text: 'Chat to sales', onClick: () => console.log('chat') }], features: ['Up to 20 users', '40GB storage', 'Priority support'] }]} title=\"Choose Your Plan\" description=\"Find the perfect plan for your needs\" textboxLayout=\"default\" animationType=\"slide-up\" useInvertedBackground={\"noInvert\"} />", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Requires plans[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/PricingCardTwo.json b/registry/components/PricingCardTwo.json new file mode 100644 index 0000000..96ffcc6 --- /dev/null +++ b/registry/components/PricingCardTwo.json @@ -0,0 +1,111 @@ +{ + "name": "PricingCardTwo", + "description": "Pricing card with badge, price, subtitle, two CTA buttons, and feature list with checkmarks.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Choose Your Plan", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Select the perfect plan for your needs", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Pricing", + "minChars": 2, + "maxChars": 30 + } + }, + "pricingPlanRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "badge": { + "required": true, + "example": "Business Plan", + "minChars": 2, + "maxChars": 30, + "note": "Required for visual consistency across all cards" + }, + "price": { + "required": true, + "example": "$29/mo", + "minChars": 1, + "maxChars": 20 + }, + "subtitle": { + "required": true, + "example": "Perfect for small teams", + "minChars": 5, + "maxChars": 100, + "note": "Required for visual consistency across all cards" + }, + "buttons": { + "required": true, + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "First button (index 0) = primary-button, second (index 1) = secondary-button. Button variant controlled by ThemeProvider's defaultButtonVariant. Border radius controlled by ThemeProvider's borderRadius. All sections should be wrapped in a single ThemeProvider at the app/page level." + }, + "features": { + "required": true, + "example": [ + "Up to 10 team members", + "100GB storage", + "Priority support" + ], + "note": "Array of feature strings, required for visual consistency" + }, + "badgeIcon": { + "required": false, + "example": "Sparkles", + "note": "Optional Lucide icon to display next to badge" + } + } + }, + "propsSchema": { + "plans": "Array<{ id: string, badge: string, badgeIcon?: LucideIcon, price: string, subtitle: string, buttons: Array<{text: string, onClick?: () => void, href?: string}>, features: string[] }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Pricing section')", + "className?": "string" + }, + "usageExample": " console.log('clicked') }, { text: 'Chat to Sales', onClick: () => console.log('chat') }], features: ['Up to 10 team members', '100GB storage', 'Priority support'] }]} title=\"Choose Your Plan\" description=\"Find the perfect plan for your needs\" textboxLayout=\"default\" animationType=\"slide-up\" useInvertedBackground={\"noInvert\"} />", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for pricing pages", + "Use for subscription tiers", + "Requires plans[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ProductCardFour.json b/registry/components/ProductCardFour.json new file mode 100644 index 0000000..4ddfd2a --- /dev/null +++ b/registry/components/ProductCardFour.json @@ -0,0 +1,92 @@ +{ + "name": "ProductCardFour", + "description": "E-commerce product card with name, variant description, and price in horizontal layout with favorite toggle.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Featured Products", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Discover our latest collection of premium apparel", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "New Arrivals", + "minChars": 2, + "maxChars": 30 + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "Button variant controlled by ThemeProvider's defaultButtonVariant. All sections should be wrapped in a single ThemeProvider at the app/page level." + }, + "productCardRules": { + "name": { + "required": true, + "example": "Represent X Puma Graphic T-Shirt", + "minChars": 2, + "maxChars": 100 + }, + "price": { + "required": true, + "example": "$100", + "note": "Display price with currency symbol" + }, + "variant": { + "required": true, + "example": "Dark Grey 3 Colors", + "minChars": 2, + "maxChars": 100, + "note": "Product variant description (color, size options, etc.)" + }, + "imageSrc": { + "required": true, + "example": "/product.jpg", + "note": "Product image URL" + } + } + }, + "propsSchema": { + "products": "Array<{ id: string, name: string, price: string, variant: string, imageSrc: string, imageAlt?: string, onFavorite?: () => void, onProductClick?: () => void, isFavorited?: boolean }> - Product items", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault' (required)", + "ariaLabel?": "string (default: 'Product section')", + "className?": "string" + }, + "usageExample": " console.log('favorited'), onProductClick: () => window.open('/product', '_blank') }]} title=\"Featured Products\" description=\"Discover our latest collection\" tag=\"New Arrivals\" tagIcon={Package} textboxLayout=\"default\" gridVariant=\"uniform-all-items-equal\" animationType=\"slide-up\" useInvertedBackground={\"noInvert\"} />", + "do": [ + "Use for product catalogs", + "Use for e-commerce", + "Requires products[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ProductCardOne.json b/registry/components/ProductCardOne.json new file mode 100644 index 0000000..45a6178 --- /dev/null +++ b/registry/components/ProductCardOne.json @@ -0,0 +1,89 @@ +{ + "name": "ProductCardOne", + "description": "Simple product card showing name, price, and arrow icon for viewing details.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Featured Products", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Discover our latest collection of premium products", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "New Arrivals", + "minChars": 2, + "maxChars": 30 + } + }, + "productCardRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Eclipse Motion Pro", + "minChars": 2, + "maxChars": 50 + }, + "price": { + "required": true, + "example": "$150", + "minChars": 1, + "maxChars": 20 + } + }, + "mediaRules": { + "imageSrc": { + "required": true, + "example": "/product.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "imageAlt": { + "required": false, + "example": "Product name", + "note": "Empty string marks image as decorative (aria-hidden)" + } + } + }, + "propsSchema": { + "products": "Array<{ id: string, name: string, price: string, imageSrc: string, imageAlt?: string, onFavorite?: () => void, onProductClick?: () => void, isFavorited?: boolean }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Product section')", + "className?": "string" + }, + "usageExample": " window.open('https://example.com', '_blank') }]} title=\"Featured Products\" description=\"Explore our curated collection\" textboxLayout=\"default\" animationType=\"slide-up\" useInvertedBackground={\"noInvert\"} />", + "do": [ + "Use for product catalogs", + "Use for e-commerce", + "Requires products[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ProductCardThree.json b/registry/components/ProductCardThree.json new file mode 100644 index 0000000..9bcccdf --- /dev/null +++ b/registry/components/ProductCardThree.json @@ -0,0 +1,94 @@ +{ + "name": "ProductCardThree", + "description": "E-commerce product card with quantity selector and add-to-cart price button.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Shop Now", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Add your favorite items to cart", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Limited Stock", + "minChars": 2, + "maxChars": 30 + } + }, + "productCardRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "TIMBUK2 Classic Messenger Bag", + "minChars": 2, + "maxChars": 50 + }, + "price": { + "required": true, + "example": "$119.00", + "minChars": 1, + "maxChars": 20 + }, + "initialQuantity": { + "required": false, + "example": 1, + "note": "Default quantity value (default: 1)" + } + }, + "mediaRules": { + "imageSrc": { + "required": true, + "example": "/product.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "imageAlt": { + "required": false, + "example": "Product name", + "note": "Empty string marks image as decorative (aria-hidden)" + } + } + }, + "propsSchema": { + "products": "Array<{ id: string, name: string, price: string, imageSrc: string, imageAlt?: string, onFavorite?: () => void, onProductClick?: () => void, onQuantityChange?: (quantity: number) => void, isFavorited?: boolean, initialQuantity?: number, priceButtonProps?: Partial> }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Product section')", + "className?": "string" + }, + "usageExample": " window.open('https://example.com', '_blank'), onQuantityChange: (qty) => console.log(qty) }]} title=\"Shop Now\" description=\"Explore our curated collection\" textboxLayout=\"default\" animationType=\"slide-up\" useInvertedBackground={\"noInvert\"} />", + "do": [ + "Use for product catalogs", + "Use for e-commerce", + "Requires products[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/ProductCardTwo.json b/registry/components/ProductCardTwo.json new file mode 100644 index 0000000..0e7434d --- /dev/null +++ b/registry/components/ProductCardTwo.json @@ -0,0 +1,106 @@ +{ + "name": "ProductCardTwo", + "description": "Product card displaying brand name, star rating, and review count for social proof.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Premium Collection", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "Curated selection of top-rated products", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Best Sellers", + "minChars": 2, + "maxChars": 30 + } + }, + "productCardRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "brand": { + "required": true, + "example": "Wofurnitures", + "minChars": 2, + "maxChars": 30 + }, + "name": { + "required": true, + "example": "Single Accent Chair", + "minChars": 2, + "maxChars": 50 + }, + "price": { + "required": true, + "example": "$650.00", + "minChars": 1, + "maxChars": 20 + }, + "rating": { + "required": true, + "example": 4, + "note": "Number from 1-5 representing star rating" + }, + "reviewCount": { + "required": true, + "example": "23.9k", + "minChars": 1, + "maxChars": 10 + } + }, + "mediaRules": { + "imageSrc": { + "required": true, + "example": "/product.jpg", + "note": "Supports external URLs with unoptimized prop" + }, + "imageAlt": { + "required": false, + "example": "Product name", + "note": "Empty string marks image as decorative (aria-hidden)" + } + } + }, + "propsSchema": { + "products": "Array<{ id: string, brand: string, name: string, price: string, rating: number, reviewCount: string, imageSrc: string, imageAlt?: string, onFavorite?: () => void, onProductClick?: () => void, isFavorited?: boolean }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Product section')", + "className?": "string" + }, + "usageExample": " window.open('https://example.com', '_blank') }]} title=\"Premium Collection\" description=\"Explore our curated collection\" textboxLayout=\"default\" animationType=\"slide-up\" useInvertedBackground={\"noInvert\"} />", + "do": [ + "Use for product catalogs", + "Use for e-commerce", + "Requires products[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/RadialGradientBackground.json b/registry/components/RadialGradientBackground.json new file mode 100644 index 0000000..5e93945 --- /dev/null +++ b/registry/components/RadialGradientBackground.json @@ -0,0 +1,24 @@ +{ + "name": "RadialGradientBackground", + "description": "Customizable radial gradient background with theme color integration.", + "constraints": {}, + "propsSchema": { + "className?": "string", + "centerColor?": "string (default: 'var(--background)')", + "edgeColor?": "string (default: 'var(--color-primary-cta)')", + "size?": "string (default: '125% 125%')", + "position?": "string (default: '50% 10%')" + }, + "usageExample": "", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/RotatedRaysBackground.json b/registry/components/RotatedRaysBackground.json new file mode 100644 index 0000000..4da2d79 --- /dev/null +++ b/registry/components/RotatedRaysBackground.json @@ -0,0 +1,25 @@ +{ + "name": "RotatedRaysBackground", + "description": "Atmospheric light rays emanating from a rotated origin point with blur and radial gradient effects, with optional grid overlay.", + "constraints": {}, + "propsSchema": { + "animated": "boolean - Required. When true, rays animate with pulsing opacity. When false, rays display static opacity.", + "showGrid": "boolean - Required. When true, displays a grid overlay fading from top center. When false, no grid is shown.", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays" + ], + "dont": [ + "Do not use multiple items", + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/SplitAbout.json b/registry/components/SplitAbout.json new file mode 100644 index 0000000..476eb90 --- /dev/null +++ b/registry/components/SplitAbout.json @@ -0,0 +1,95 @@ +{ + "name": "SplitAbout", + "description": "Split-layout about section with bullet points on one side and image/video on the other.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "About Us", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Learn more about our mission, values, and what drives us forward", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Our Story", + "minChars": 2, + "maxChars": 30 + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "Button variant controlled by ThemeProvider's defaultButtonVariant. All sections should be wrapped in a single ThemeProvider at the app/page level." + }, + "bulletPointRules": { + "structure": { + "title": "string - Bullet point heading (required)", + "description": "string - Bullet point text (required)", + "icon": "LucideIcon - Optional icon displayed above title" + }, + "note": "Bullet points are separated by horizontal dividers. Border radius controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level." + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/about-image.jpg", + "note": "Supports external URLs" + }, + "videoSrc": { + "required": false, + "example": "/about-video.mp4", + "note": "Takes precedence over imageSrc if both provided" + }, + "imageAlt": { + "required": false, + "example": "About us", + "note": "Empty string marks image as decorative (aria-hidden)" + } + } + }, + "propsSchema": { + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "bulletPoints": "Array<{ title: string, description: string, icon?: LucideIcon }>", + "imageSrc?": "string", + "videoSrc?": "string", + "imageAlt?": "string (default: '')", + "videoAriaLabel?": "string (default: 'About section video')", + "ariaLabel?": "string (default: 'About section')", + "imagePosition?": "'left' | 'right' (default: 'right')", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\n\n \n", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for about pages", + "Use for company information", + "Requires titleSegments?[]", + "Requires buttons?[]", + "Requires bulletPoints[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TeamCardEleven.json b/registry/components/TeamCardEleven.json new file mode 100644 index 0000000..4bbc0fa --- /dev/null +++ b/registry/components/TeamCardEleven.json @@ -0,0 +1,110 @@ +{ + "name": "TeamCardEleven", + "description": "Team directory section with groups of members displayed in a list layout with avatar, title, subtitle, and detail.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Meet Our Team", + "minChars": 2, + "maxChars": 60 + }, + "description": { + "required": true, + "example": "The talented people behind our success", + "minChars": 5, + "maxChars": 200 + }, + "tag": { + "required": false, + "example": "Team", + "minChars": 2, + "maxChars": 30 + } + }, + "groupRules": { + "minItems": 1, + "maxItems": 4, + "recommendedItems": "1-3", + "id": { + "required": true, + "example": "global", + "note": "Unique identifier for the group" + }, + "groupTitle": { + "required": true, + "example": "Global", + "minChars": 2, + "maxChars": 30 + } + }, + "memberRules": { + "minItems": 1, + "maxItems": 10, + "recommendedItems": "2-6", + "id": { + "required": true, + "example": "1", + "note": "Unique identifier for the member" + }, + "title": { + "required": true, + "example": "Mihai Toma", + "minChars": 2, + "maxChars": 50 + }, + "subtitle": { + "required": true, + "example": "Partner", + "minChars": 2, + "maxChars": 50 + }, + "detail": { + "required": true, + "example": "mihai@company.com", + "minChars": 2, + "maxChars": 100 + }, + "imageSrc": { + "required": false, + "example": "/team/mihai.jpg", + "note": "Avatar image" + }, + "videoSrc": { + "required": false, + "example": "/team/mihai.mp4", + "note": "Video alternative to image" + } + } + }, + "propsSchema": { + "groups": "Array<{ id: string, groupTitle: string, members: Array<{ id: string, title: string, subtitle: string, detail: string, imageSrc?: string, imageAlt?: string, videoSrc?: string, videoAriaLabel?: string }> }> (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Team section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for contact pages", + "Use for lead generation", + "Use for team pages", + "Use for staff directories", + "Requires groups[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TeamCardFive.json b/registry/components/TeamCardFive.json new file mode 100644 index 0000000..4c3dbe6 --- /dev/null +++ b/registry/components/TeamCardFive.json @@ -0,0 +1,106 @@ +{ + "name": "TeamCardFive", + "description": "Team section with overlapping portrait cards in responsive flex layout showing centered vertical cards with name and role.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Meet Our Team", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "The talented people behind our success", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Team", + "minChars": 2, + "maxChars": 30 + } + }, + "teamMemberRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Sarah Johnson", + "minChars": 2, + "maxChars": 50, + "note": "Team member name displayed at 2xl font-medium, centered with truncate" + }, + "role": { + "required": true, + "example": "CEO & Founder", + "minChars": 2, + "maxChars": 50, + "note": "Role/title displayed at base size with 75% opacity, centered with truncate" + }, + "imageSrc": { + "required": false, + "example": "/team/sarah.jpg", + "note": "Image path for team member photo (aspect-square in card wrapper with p-2, rounded-theme)" + }, + "videoSrc": { + "required": false, + "example": "/team/sarah.mp4", + "note": "Video path for team member (aspect-square in card wrapper with p-2, rounded-theme)" + }, + "imageAlt": { + "required": false, + "example": "Portrait of Sarah Johnson", + "note": "Alt text for image (defaults to member name if not provided)" + }, + "videoAriaLabel": { + "required": false, + "example": "Video of Sarah Johnson", + "note": "ARIA label for video (defaults to member name if not provided)" + } + }, + "itemRules": { + "minItems": 2, + "maxItems": 12, + "recommendedItems": "4-8", + "note": "Works best with 4-8 team members. Mobile: 2 per row with overlap. Desktop: up to 4 per row with overlap and wrap support for additional rows." + } + }, + "propsSchema": { + "team": "Array<{ id: string, name: string, role: string, imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Team section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for team pages", + "Use for staff directories", + "Requires team[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items", + "Do not use less than 2 items", + "Do not use more than 12 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TeamCardOne.json b/registry/components/TeamCardOne.json new file mode 100644 index 0000000..4159d38 --- /dev/null +++ b/registry/components/TeamCardOne.json @@ -0,0 +1,89 @@ +{ + "name": "TeamCardOne", + "description": "Team member card with image background, overlay info card at bottom-left corner.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Meet Our Team", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "The people behind our success", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Team", + "minChars": 2, + "maxChars": 30 + } + }, + "teamMemberRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Sophie P.", + "minChars": 2, + "maxChars": 50, + "note": "Team member name displayed in overlay card" + }, + "role": { + "required": true, + "example": "Digital Nomad", + "minChars": 2, + "maxChars": 40, + "note": "Role/title displayed in primary-button badge" + }, + "imageSrc": { + "required": true, + "example": "/team/sophie.jpg", + "note": "Image path for team member photo (displays as square with rounded-theme)" + }, + "imageAlt": { + "required": false, + "example": "Portrait of Sophie P.", + "note": "Alt text for image (defaults to member name if not provided)" + } + } + }, + "propsSchema": { + "members": "Array<{ id: string, name: string, role: string, imageSrc: string, imageAlt?: string }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Team section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for team pages", + "Use for staff directories", + "Requires members[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TeamCardSix.json b/registry/components/TeamCardSix.json new file mode 100644 index 0000000..dec42c9 --- /dev/null +++ b/registry/components/TeamCardSix.json @@ -0,0 +1,91 @@ +{ + "name": "TeamCardSix", + "description": "Team member card with full-bleed image background and blurred gradient overlay with name and role text at bottom.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Meet Our Team", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "The talented people behind our success", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Team", + "minChars": 2, + "maxChars": 30 + } + }, + "teamMemberRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Sarah Johnson", + "minChars": 2, + "maxChars": 50, + "note": "Team member name displayed at 2xl font-medium with truncate in blurred overlay" + }, + "role": { + "required": true, + "example": "CEO & Founder", + "minChars": 2, + "maxChars": 50, + "note": "Role/title displayed at base size with truncate in blurred overlay" + }, + "imageSrc": { + "required": true, + "example": "/team/sarah.jpg", + "note": "Image path for team member photo (full-bleed with rounded-theme-capped)" + }, + "imageAlt": { + "required": false, + "example": "Portrait of Sarah Johnson", + "note": "Alt text for image (defaults to member name if not provided)" + } + } + }, + "propsSchema": { + "members": "Array<{ id: string, name: string, role: string, imageSrc: string, imageAlt?: string }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required - determines grid layout or carousel trigger)", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Team section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for about pages", + "Use for company information", + "Use for team pages", + "Use for staff directories", + "Requires members[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TeamCardTen.json b/registry/components/TeamCardTen.json new file mode 100644 index 0000000..239095e --- /dev/null +++ b/registry/components/TeamCardTen.json @@ -0,0 +1,74 @@ +{ + "name": "TeamCardTen", + "description": "Team section with animated title at top, Tag label, and member cards with images and names.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Growing fast means tough calls. We help you turn pricing from doubt into conviction.", + "minChars": 20, + "maxChars": 300 + }, + "tag": { + "required": true, + "example": "Team", + "minChars": 2, + "maxChars": 30 + } + }, + "memberRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Johan van der Poel", + "minChars": 2, + "maxChars": 50 + }, + "imageSrc": { + "required": false, + "example": "/team/johan.jpg", + "note": "Portrait image (3:3.5 aspect ratio)" + }, + "videoSrc": { + "required": false, + "example": "/team/johan.mp4", + "note": "Video alternative to image" + } + }, + "itemRules": { + "minItems": 1, + "maxItems": 6, + "recommendedItems": "2-4" + } + }, + "propsSchema": { + "title": "string", + "tag": "string", + "members": "Array<{ id: string, name: string, imageSrc?: string, imageAlt?: string, videoSrc?: string, videoAriaLabel?: string }>", + "memberVariant": "'default' | 'card' (required - 'default': no card styling, 'card': each member wrapped in card with rounded corners)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Team section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for team pages", + "Use for staff directories", + "Requires members[]" + ], + "dont": [ + "Do not use multiple items", + "Do not use more than 4 items", + "Do not use more than 6 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TeamCardTwo.json b/registry/components/TeamCardTwo.json new file mode 100644 index 0000000..6d212a2 --- /dev/null +++ b/registry/components/TeamCardTwo.json @@ -0,0 +1,106 @@ +{ + "name": "TeamCardTwo", + "description": "Team member card with image background, overlay info card, and social links.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Meet Our Team", + "minChars": 2, + "maxChars": 35 + }, + "description": { + "required": true, + "example": "The talented people behind our success", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Team", + "minChars": 2, + "maxChars": 30 + } + }, + "teamMemberRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Alisa Hester", + "minChars": 2, + "maxChars": 50, + "note": "Team member name displayed in overlay header" + }, + "role": { + "required": true, + "example": "Founder & CEO", + "minChars": 2, + "maxChars": 40, + "note": "Role/title displayed in secondary-button badge" + }, + "description": { + "required": true, + "example": "Former co-founder of Opendoor. Early staff at Spotify and Clearbit.", + "minChars": 10, + "maxChars": 200, + "note": "Brief bio or description" + }, + "imageSrc": { + "required": true, + "example": "/team/member-1.jpg", + "note": "Image path for team member photo" + }, + "imageAlt": { + "required": false, + "example": "Portrait of Alisa Hester", + "note": "Alt text for image (defaults to member name if not provided)" + }, + "socialLinks": { + "required": false, + "structure": { + "icon": "LucideIcon - Any Lucide icon component (required)", + "url": "string - Social profile URL (required)" + }, + "note": "Flexible social links array. Pass any Lucide icon (Twitter, Linkedin, Globe, Github, etc.) with corresponding URL. Icons display in primary-button styled circles." + } + } + }, + "propsSchema": { + "members": "Array<{ id: string, name: string, role: string, description: string, imageSrc: string, imageAlt?: string, socialLinks?: Array<{ icon: LucideIcon, url: string }> }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Team section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for about pages", + "Use for company information", + "Use for team pages", + "Use for staff directories", + "Requires members[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialAboutCard.json b/registry/components/TestimonialAboutCard.json new file mode 100644 index 0000000..4f916fc --- /dev/null +++ b/registry/components/TestimonialAboutCard.json @@ -0,0 +1,75 @@ +{ + "name": "TestimonialAboutCard", + "description": "Card-based about section with tag, title, description footer, icon box, and required media.", + "constraints": { + "textRules": { + "tag": { + "required": true, + "example": "Testimonial", + "minChars": 2, + "maxChars": 30 + }, + "title": { + "required": true, + "example": "They took social media off our plate completely and our audience has never been more engaged.", + "minChars": 10, + "maxChars": 300 + }, + "description": { + "required": true, + "example": "Elena Chen", + "minChars": 2, + "maxChars": 50 + }, + "subdescription": { + "required": true, + "example": "Bloom Skincare", + "minChars": 2, + "maxChars": 50 + } + }, + "mediaRules": { + "note": "Either imageSrc or videoSrc is required (discriminated union)", + "imageSrc": { + "required": "conditional - required if no videoSrc", + "example": "https://images.unsplash.com/photo-1616394584738-fc6e612e71b9?w=800" + }, + "videoSrc": { + "required": "conditional - required if no imageSrc", + "example": "/videos/testimonial.mp4" + } + } + }, + "propsSchema": { + "tag": "string (required)", + "tagIcon?": "LucideIcon", + "title": "string (required)", + "description": "string (required)", + "subdescription": "string (required)", + "icon": "LucideIcon (required - displayed in the icon box)", + "imageSrc": "string (required if no videoSrc)", + "imageAlt?": "string (default: '')", + "videoSrc": "string (required if no imageSrc)", + "videoAriaLabel?": "string (default: 'Testimonial video')", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Testimonial section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for social proof", + "Use for customer reviews", + "Use for about pages", + "Use for company information" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardFifteen.json b/registry/components/TestimonialCardFifteen.json new file mode 100644 index 0000000..6f493ce --- /dev/null +++ b/registry/components/TestimonialCardFifteen.json @@ -0,0 +1,63 @@ +{ + "name": "TestimonialCardFifteen", + "description": "Centered testimonial with star rating, animated text, author, and avatar group.", + "constraints": { + "textRules": { + "testimonial": { + "required": true, + "example": "This product has completely transformed how we work. The results speak for themselves.", + "minChars": 20, + "maxChars": 300 + }, + "author": { + "required": true, + "example": "James Carter, Journalist", + "minChars": 2, + "maxChars": 60 + } + }, + "ratingRules": { + "rating": { + "required": true, + "min": 0, + "max": 5, + "example": 5, + "note": "Number of filled stars (0-5)" + } + }, + "avatarRules": { + "avatars": { + "required": true, + "minItems": 1, + "example": "[{ src: '/avatars/user1.jpg', alt: 'User 1' }]", + "note": "Array of avatar objects with src and alt. Shows 3 on mobile, 6 on desktop." + } + } + }, + "propsSchema": { + "testimonial": "string", + "rating": "number (0-5)", + "author": "string", + "avatars": "Array<{ src: string, alt: string }>", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Testimonial section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for landing pages", + "Use for feature showcases", + "Use for capability displays", + "Use for social proof", + "Use for customer reviews", + "Requires avatars[]" + ], + "dont": [ + "Do not use multiple items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardFive.json b/registry/components/TestimonialCardFive.json new file mode 100644 index 0000000..b6cf52d --- /dev/null +++ b/registry/components/TestimonialCardFive.json @@ -0,0 +1,137 @@ +{ + "name": "TestimonialCardFive", + "description": "Full-width carousel testimonial section with split card layout showing text content and square image side-by-side.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "What Our Clients Say", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Hear from those who've experienced our work", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Testimonials", + "minChars": 2, + "maxChars": 30 + } + }, + "testimonialRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Alisa Hester, CEO of Ecomflow", + "minChars": 2, + "maxChars": 80, + "note": "Full name including role and company (e.g., 'John Smith, CTO of Tech Corp')" + }, + "date": { + "required": true, + "example": "Date: 28 October 2024", + "minChars": 5, + "maxChars": 50, + "note": "Date string including 'Date:' prefix" + }, + "title": { + "required": true, + "example": "We've got only good things to say!", + "minChars": 5, + "maxChars": 100, + "note": "Testimonial headline shown at 4xl, truncated to 3 lines" + }, + "quote": { + "required": true, + "example": "We have been working with them for over 6 months now, and have been able to scale our business to new heights.", + "minChars": 20, + "maxChars": 500, + "note": "Full testimonial text shown at base/lg size, truncated to 10 lines" + }, + "tag": { + "required": true, + "example": "Standard Line", + "minChars": 2, + "maxChars": 30, + "note": "Category or plan tag displayed at top of card" + }, + "avatarSrc": { + "required": true, + "example": "/client-avatar.jpg", + "note": "Avatar image shown in TestimonialAuthor component (h-11 aspect-square)" + } + }, + "mediaRules": { + "imageSrc": { + "required": false, + "example": "/testimonial-image.jpg", + "note": "Either imageSrc or videoSrc should be provided for optimal display" + }, + "videoSrc": { + "required": false, + "example": "/testimonial-video.mp4", + "note": "Either imageSrc or videoSrc should be provided for optimal display" + }, + "imageAlt": { + "required": false, + "example": "Team collaboration", + "note": "Alt text for testimonial image" + }, + "videoAriaLabel": { + "required": false, + "example": "Client testimonial video", + "note": "ARIA label for testimonial video" + }, + "avatarAlt": { + "required": false, + "example": "Alisa Hester", + "note": "Alt text for avatar image" + } + }, + "itemRules": { + "minItems": 3, + "maxItems": 10, + "recommendedItems": "5-6", + "note": "Works best with 5-6 testimonials. Auto-advances every 5 seconds with loop enabled." + } + }, + "propsSchema": { + "testimonials": "Array<{ id: string, name: string, date: string, title: string, quote: string, tag: string, avatarSrc: string, avatarAlt?: string, imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }>", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Testimonials section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for social proof", + "Use for customer reviews", + "Requires testimonials[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use less than 3 items", + "Do not use more than 10 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardOne.json b/registry/components/TestimonialCardOne.json new file mode 100644 index 0000000..808cb73 --- /dev/null +++ b/registry/components/TestimonialCardOne.json @@ -0,0 +1,103 @@ +{ + "name": "TestimonialCardOne", + "description": "Testimonial card with image background, star rating, name, role, and company overlay.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "What Our Customers Say", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Real feedback from our valued customers", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Testimonials", + "minChars": 2, + "maxChars": 30 + } + }, + "testimonialRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Alisa Hester", + "minChars": 2, + "maxChars": 50, + "note": "Customer name displayed in overlay" + }, + "role": { + "required": true, + "example": "PM, Hourglass", + "minChars": 2, + "maxChars": 50, + "note": "Customer role/position" + }, + "company": { + "required": true, + "example": "Web Design Agency", + "minChars": 2, + "maxChars": 50, + "note": "Customer company name" + }, + "rating": { + "required": true, + "example": 5, + "min": 1, + "max": 5, + "note": "Star rating (1-5 stars)" + }, + "imageSrc": { + "required": true, + "example": "/testimonials/alisa.jpg", + "note": "Image path for customer photo" + }, + "imageAlt": { + "required": false, + "example": "Portrait of Alisa Hester", + "note": "Alt text for image (defaults to customer name if not provided)" + } + } + }, + "propsSchema": { + "testimonials": "Array<{ id: string, name: string, role: string, company: string, rating: number, imageSrc: string, imageAlt?: string }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-95 2xl:min-h-105')", + "gridVariant": "'uniform-all-items-equal' | 'uniform-alternating-sizes' | 'uniform-alternating-sizes-inverted' | 'two-items-tall-short' | 'two-items-short-tall' | 'bento-grid' | 'bento-grid-inverted' | 'two-columns-alternating-heights' | 'asymmetric-60-wide-40-narrow' | 'three-columns-all-equal-width' | 'four-items-2x2-equal-grid' | 'one-large-right-three-stacked-left' | 'items-top-row-full-width-bottom' | 'full-width-top-items-bottom-row' | 'one-large-left-three-stacked-right' | 'timeline' | 'timeline-three-columns' (required)", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Testimonials section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for social proof", + "Use for customer reviews", + "Requires testimonials[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardSix.json b/registry/components/TestimonialCardSix.json new file mode 100644 index 0000000..edf023c --- /dev/null +++ b/registry/components/TestimonialCardSix.json @@ -0,0 +1,108 @@ +{ + "name": "TestimonialCardSix", + "description": "Dual auto-scrolling marquee testimonial section with reversed testimonial cards moving in opposite directions.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "What Our Clients Say", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Hear from those who've experienced our work", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Testimonials", + "minChars": 2, + "maxChars": 30 + } + }, + "testimonialRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Sarah Johnson", + "minChars": 2, + "maxChars": 50 + }, + "handle": { + "required": true, + "example": "@sarahj", + "minChars": 2, + "maxChars": 50, + "note": "Social media handle or role/company" + }, + "testimonial": { + "required": true, + "example": "This component library has transformed our development workflow. The quality and attention to detail is exceptional.", + "minChars": 20, + "maxChars": 200, + "note": "Testimonial text automatically clamped to 2 lines for consistent card heights" + }, + "imageSrc": { + "required": false, + "example": "/avatar.jpg", + "note": "Avatar image shown in TestimonialAuthor (aspect-square)" + }, + "imageAlt": { + "required": false, + "example": "Sarah Johnson", + "note": "Alt text for avatar image" + }, + "icon": { + "required": false, + "example": "Quote", + "note": "LucideIcon component to display if no imageSrc provided (defaults to Quote icon)" + } + }, + "itemRules": { + "minItems": 6, + "maxItems": 20, + "recommendedItems": "8-12", + "note": "Works best with 8-12 testimonials. Continuously scrolls with top and bottom marquees in opposite directions." + } + }, + "propsSchema": { + "testimonials": "Array<{ id: string, name: string, handle: string, testimonial: string, imageSrc?: string, imageAlt?: string, icon?: LucideIcon }>", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "speed?": "number (default: 40)", + "topMarqueeDirection?": "'left' | 'right' (default: 'left')", + "ariaLabel?": "string (default: 'Testimonials section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for social proof", + "Use for customer reviews", + "Requires testimonials[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use less than 6 items", + "Do not use more than 20 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardTen.json b/registry/components/TestimonialCardTen.json new file mode 100644 index 0000000..e5ec9c7 --- /dev/null +++ b/registry/components/TestimonialCardTen.json @@ -0,0 +1,109 @@ +{ + "name": "TestimonialCardTen", + "description": "Split layout testimonial section with titled quote card, navigation arrows, and media display. Supports card and border variants.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Trusted by industry leaders", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "See what our customers have to say", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Testimonials", + "minChars": 2, + "maxChars": 30 + } + }, + "testimonialRules": { + "id": { + "required": true, + "example": "1", + "note": "Unique identifier for the testimonial" + }, + "title": { + "required": true, + "example": "Personalized AI, redefined with Mindex", + "minChars": 10, + "maxChars": 80, + "note": "Headline/title displayed at top of quote card" + }, + "quote": { + "required": true, + "example": "Working with this AI has been a game changer! It feels like the system really listens and adapts to what I need.", + "minChars": 20, + "maxChars": 500 + }, + "name": { + "required": true, + "example": "Sarah Mitchell", + "minChars": 2, + "maxChars": 50 + }, + "role": { + "required": true, + "example": "CEO of BrightPath Solutions", + "minChars": 2, + "maxChars": 100 + }, + "imageSrc": { + "required": false, + "example": "/images/testimonial1.webp", + "note": "Image source URL (either imageSrc or videoSrc required)" + }, + "videoSrc": { + "required": false, + "example": "/videos/testimonial.mp4", + "note": "Video source URL (either imageSrc or videoSrc required)" + }, + "imageAlt": { + "required": false, + "example": "Sarah Mitchell headshot", + "note": "Alt text for images" + }, + "videoAriaLabel": { + "required": false, + "example": "Testimonial video", + "note": "Aria label for videos" + } + } + }, + "propsSchema": { + "testimonials": "Array<{ id: string, title: string, quote: string, name: string, role: string, imageSrc?: string, videoSrc?: string, imageAlt?: string, videoAriaLabel?: string }>", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Testimonials section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for social proof", + "Use for customer reviews", + "Requires testimonials[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use more than 4 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardThirteen.json b/registry/components/TestimonialCardThirteen.json new file mode 100644 index 0000000..429ae4e --- /dev/null +++ b/registry/components/TestimonialCardThirteen.json @@ -0,0 +1,101 @@ +{ + "name": "TestimonialCardThirteen", + "description": "Testimonial cards with star ratings or quote icon, testimonial text, and author details.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "What Our Clients Say", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "Hear from those who've experienced our work", + "minChars": 5, + "maxChars": 300 + }, + "tag": { + "required": false, + "example": "Testimonials", + "minChars": 2, + "maxChars": 30 + } + }, + "testimonialRules": { + "id": { + "required": true, + "example": "1", + "note": "Unique identifier for the testimonial" + }, + "name": { + "required": true, + "example": "Sarah Johnson", + "minChars": 2, + "maxChars": 50 + }, + "handle": { + "required": true, + "example": "@sarahj", + "minChars": 2, + "maxChars": 30 + }, + "testimonial": { + "required": true, + "example": "Amazing product that transformed our workflow!", + "minChars": 10, + "maxChars": 500 + }, + "rating": { + "required": true, + "example": 5, + "note": "Number from 1-5 indicating star rating" + }, + "imageSrc": { + "required": false, + "example": "/testimonials/sarah.jpg", + "note": "Author avatar image (either imageSrc or icon required)" + }, + "icon": { + "required": false, + "example": "Quote", + "note": "LucideIcon for author avatar (either imageSrc or icon required)" + } + } + }, + "propsSchema": { + "testimonials": "Array<{ id: string, name: string, handle: string, testimonial: string, rating: number, imageSrc?: string, imageAlt?: string, icon?: LucideIcon }>", + "showRating": "boolean - true for star ratings, false for quote icon (required)", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-none')", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "ariaLabel?": "string (default: 'Testimonials section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for social proof", + "Use for customer reviews", + "Use for product catalogs", + "Use for e-commerce", + "Requires testimonials[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [ + "Do not use multiple items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardTwelve.json b/registry/components/TestimonialCardTwelve.json new file mode 100644 index 0000000..efb2798 --- /dev/null +++ b/registry/components/TestimonialCardTwelve.json @@ -0,0 +1,80 @@ +{ + "name": "TestimonialCardTwelve", + "description": "Minimal testimonial card with avatar group, title, and tag in a single centered card layout.", + "constraints": { + "textRules": { + "cardTitle": { + "required": true, + "example": "Over 10,000 customers trust us to deliver exceptional results", + "minChars": 10, + "maxChars": 120 + }, + "cardTag": { + "required": true, + "example": "See what they say", + "minChars": 5, + "maxChars": 40 + } + }, + "testimonialRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Sarah Johnson", + "minChars": 2, + "maxChars": 50, + "note": "Used as fallback for imageAlt" + }, + "imageSrc": { + "required": true, + "example": "/testimonials/sarah.jpg", + "note": "Image path for customer photo" + }, + "imageAlt": { + "required": false, + "example": "Sarah Johnson", + "minChars": 2, + "maxChars": 50, + "note": "Alt text for accessibility (defaults to name)" + } + }, + "itemRules": { + "minItems": 3, + "maxItems": 10, + "recommendedItems": "4-6", + "note": "Shows 3 avatars on mobile, 4 on desktop. Remaining count displayed as '+N'. Works best with 4-6 testimonials." + } + }, + "propsSchema": { + "testimonials": "Array<{ id: string, name: string, imageSrc: string, imageAlt?: string }>", + "cardTitle": "string", + "cardTag": "string", + "cardTagIcon?": "LucideIcon", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Testimonials section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for social proof", + "Use for customer reviews", + "Requires testimonials[]" + ], + "dont": [ + "Do not use multiple items", + "Do not use less than 3 items", + "Do not use more than 10 items" + ], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TestimonialCardTwo.json b/registry/components/TestimonialCardTwo.json new file mode 100644 index 0000000..3efbaf1 --- /dev/null +++ b/registry/components/TestimonialCardTwo.json @@ -0,0 +1,100 @@ +{ + "name": "TestimonialCardTwo", + "description": "Testimonial card with circular image or icon, name, role, and testimonial text.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Customer Reviews", + "minChars": 2, + "maxChars": 50 + }, + "description": { + "required": true, + "example": "See what our customers have to say", + "minChars": 5, + "maxChars": 250 + }, + "tag": { + "required": false, + "example": "Reviews", + "minChars": 2, + "maxChars": 30 + } + }, + "testimonialRules": { + "id": { + "required": true, + "example": "1", + "minChars": 1, + "maxChars": 20 + }, + "name": { + "required": true, + "example": "Sarah Mitchell", + "minChars": 2, + "maxChars": 50, + "note": "Customer name" + }, + "role": { + "required": true, + "example": "Director of Operations", + "minChars": 2, + "maxChars": 80, + "note": "Customer role/position" + }, + "testimonial": { + "required": true, + "example": "The attention to detail and commitment to excellence was outstanding throughout the entire project.", + "minChars": 10, + "maxChars": 500, + "note": "Testimonial text content" + }, + "imageSrc": { + "required": false, + "example": "/testimonials/sarah.jpg", + "note": "Optional image path for customer photo. If not provided, icon will be displayed instead." + }, + "imageAlt": { + "required": false, + "example": "Portrait of Sarah Mitchell", + "note": "Alt text for image (defaults to customer name if not provided)" + }, + "icon": { + "required": false, + "example": "Package", + "note": "Optional Lucide icon to display when no image is provided. Defaults to Quote icon." + } + } + }, + "propsSchema": { + "testimonials": "Array<{ id: string, name: string, role: string, testimonial: string, imageSrc?: string, imageAlt?: string, icon?: LucideIcon }>", + "carouselMode?": "'auto' | 'buttons' (default: 'buttons')", + "uniformGridCustomHeightClasses?": "string (default: 'min-h-none')", + "animationType": "'none' | 'opacity' | 'slide-up' | 'scale-rotate' | 'blur-reveal' (required - controls GSAP scroll animations with stagger effect)", + "title": "string", + "titleSegments?": "Array<{ type: 'text', content: string } | { type: 'image', src: string, alt?: string }> - For inline images in title", + "description": "string", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' | 'inline-image' (required - 'inline-image' uses titleSegments for rich text with images)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'Testimonials section')", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for social proof", + "Use for customer reviews", + "Requires testimonials[]", + "Requires titleSegments?[]", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TextAbout.json b/registry/components/TextAbout.json new file mode 100644 index 0000000..f7f5221 --- /dev/null +++ b/registry/components/TextAbout.json @@ -0,0 +1,45 @@ +{ + "name": "TextAbout", + "description": "Centered about section with large animated text and optional buttons below.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "We build products that empower teams to create exceptional digital experiences", + "minChars": 10, + "maxChars": 200 + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "Button variant controlled by ThemeProvider's defaultButtonVariant. Border radius controlled by ThemeProvider's borderRadius. All sections should be wrapped in a single ThemeProvider at the app/page level." + } + }, + "propsSchema": { + "title": "string", + "buttons?": "Array<{ text: string, onClick?: () => void, href?: string, props?: Partial> }>", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'About section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\n\n \n", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for about pages", + "Use for company information", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TextAnimation.json b/registry/components/TextAnimation.json new file mode 100644 index 0000000..386e353 --- /dev/null +++ b/registry/components/TextAnimation.json @@ -0,0 +1,35 @@ +{ + "name": "TextAnimation", + "description": "Unified scroll-triggered text animation component with three distinct animation types and two trigger variants.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "This animation responds to scroll. Watch as the text comes to life." + } + } + }, + "propsSchema": { + "type?": "'entrance-slide' | 'reveal-blur' | 'background-highlight'", + "title": "string", + "children?": "React.ReactNode", + "variant?": "'trigger' | 'words-trigger'", + "className?": "string", + "duration?": "number", + "stagger?": "number", + "start?": "string", + "end?": "string", + "ariaLabel?": "string", + "gradientColors?": "{ from: string, to: string }" + }, + "usageExample": "", + "do": [ + "Use for general use" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TextBox.json b/registry/components/TextBox.json new file mode 100644 index 0000000..58916ad --- /dev/null +++ b/registry/components/TextBox.json @@ -0,0 +1,56 @@ +{ + "name": "TextBox", + "description": "Flexible text composition component with animated title and description.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "Welcome to Our Platform", + "minChars": 2, + "maxChars": 100 + }, + "description": { + "required": true, + "example": "Discover amazing features and capabilities", + "minChars": 5, + "maxChars": 500 + }, + "tag": { + "required": false, + "example": "New", + "minChars": 2, + "maxChars": 30 + } + } + }, + "propsSchema": { + "title": "string", + "description": "string", + "type?": "'entrance-slide' | 'reveal-blur' | 'background-highlight'", + "textboxLayout": "'default' | 'split' | 'split-actions' | 'split-description' (required)", + "center?": "boolean (default: false)", + "tag?": "string", + "tagIcon?": "LucideIcon", + "buttons?": "Array<{text: string, onClick?: () => void, href?: string}>", + "duration?": "number (default: 1)", + "start?": "string (default: 'top 80%')", + "end?": "string (default: 'top 20%')", + "gradientColors?": "{ from: string, to: string }", + "children?": "React.ReactNode", + "className?": "string", + "avatars?": "Array<{ src: string, alt?: string }> - User avatar images", + "avatarText?": "string" + }, + "usageExample": "", + "do": [ + "Use for general use", + "Requires buttons?[]", + "Requires avatars?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TextNumberCount.json b/registry/components/TextNumberCount.json new file mode 100644 index 0000000..9f5f4e0 --- /dev/null +++ b/registry/components/TextNumberCount.json @@ -0,0 +1,39 @@ +{ + "name": "TextNumberCount", + "description": "Animated number counter that increments smoothly from a start to an end value.", + "constraints": { + "numberRules": { + "value": { + "required": true, + "example": 99.99 + }, + "startFrom": { + "required": false, + "example": 0 + } + } + }, + "propsSchema": { + "value": "number", + "startFrom?": "number", + "duration?": "number", + "format?": "Intl.NumberFormatOptions", + "locales?": "string", + "prefix?": "string", + "suffix?": "string", + "animateOnScroll?": "boolean", + "threshold?": "number", + "className?": "string" + }, + "usageExample": "", + "do": [ + "Use for statistics displays", + "Use for achievement showcases" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/TextSplitAbout.json b/registry/components/TextSplitAbout.json new file mode 100644 index 0000000..a43e7cf --- /dev/null +++ b/registry/components/TextSplitAbout.json @@ -0,0 +1,58 @@ +{ + "name": "TextSplitAbout", + "description": "Split-layout about section with large heading on left and multiple description paragraphs with optional buttons on right.", + "constraints": { + "textRules": { + "title": { + "required": true, + "example": "About Us", + "minChars": 2, + "maxChars": 30 + }, + "description": { + "required": true, + "type": "array of strings", + "example": [ + "We're a team passionate about creating exceptional digital experiences", + "Our mission is to empower designers and developers" + ], + "minChars": 10, + "maxChars": 300, + "note": "Each description paragraph should be 10-300 characters" + } + }, + "buttonRules": { + "maxButtons": 2, + "structure": { + "text": "string - Button label (required)", + "href": "string - Link destination (optional)", + "onClick": "() => void - Click handler (optional)", + "props": "Partial - Additional button props (optional)" + }, + "note": "Button variant controlled by ThemeProvider's defaultButtonVariant. Border radius controlled by ThemeProvider's borderRadius. All sections should be wrapped in a single ThemeProvider at the app/page level." + } + }, + "propsSchema": { + "title": "string", + "description": "string[]", + "buttons?": "Array<{ text: string, onClick?: () => void, href?: string, props?: Partial> }>", + "showBorder?": "boolean (default: false)", + "useInvertedBackground": "'noInvert' | 'invertDefault'", + "ariaLabel?": "string (default: 'About section')", + "className?": "string" + }, + "usageExample": "// Wrap in ThemeProvider\n\n \n", + "do": [ + "Use for feature showcases", + "Use for capability displays", + "Use for about pages", + "Use for company information", + "Requires buttons?[]" + ], + "dont": [], + "editRules": { + "textOnly": true, + "layoutLocked": true, + "styleLocked": true + } +} \ No newline at end of file diff --git a/registry/components/Textarea.json b/registry/components/Textarea.json new file mode 100644 index 0000000..80ea8cb --- /dev/null +++ b/registry/components/Textarea.json @@ -0,0 +1,35 @@ +{ + "name": "Textarea", + "description": "Styled textarea field with secondary-button styling and rounded-theme-capped borders.", + "constraints": { + "textRules": { + "placeholder": { + "required": false, + "example": "Type your message...", + "minChars": 2, + "maxChars": 100 + } + } + }, + "propsSchema": { + "value": "string (required)", + "onChange": "(value: string) => void (required)", + "placeholder?": "string", + "rows?": "number (default: 5)", + "required?": "boolean (default: false)", + "disabled?": "boolean (default: false)", + "ariaLabel?": "string", + "className?": "string" + }, + "usageExample": "