Merge version_2 into main #16
@@ -269,7 +269,7 @@ Buttons are rendered with automatic primary/secondary styling:
|
||||
|
||||
```tsx
|
||||
const buttons: ButtonConfig[] = [
|
||||
{ text: "Get Started", href: "/signup" }, // Primary
|
||||
{ text: "Download Now", href: "/signup" }, // Primary
|
||||
{ text: "Learn More", onClick: () => {} } // Secondary
|
||||
];
|
||||
```
|
||||
|
||||
@@ -351,7 +351,7 @@ For button text and short labels:
|
||||
{
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 15
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export default function SectionPreviewPage() {
|
||||
title="Preview Section Title"
|
||||
description="This is a preview of the section component with example content."
|
||||
buttons={[
|
||||
{ text: "Get Started", href: "#" },
|
||||
{ text: "Download Now", href: "#" },
|
||||
{ text: "Learn More", onClick: () => console.log("Learn more") }
|
||||
]}
|
||||
// Add section-specific props
|
||||
@@ -308,7 +308,7 @@ Customize theme settings when:
|
||||
title="Build Amazing Websites Faster"
|
||||
description="Create stunning, responsive websites with our modern component library. Ship faster, iterate quicker."
|
||||
buttons={[
|
||||
{ text: "Get Started", href: "/signup" },
|
||||
{ text: "Download Now", href: "/signup" },
|
||||
{ text: "View Demo", onClick: () => window.open("/demo") }
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -163,7 +163,7 @@ Defines text length constraints for string props.
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 15
|
||||
}
|
||||
@@ -267,12 +267,12 @@ Single-line example showing typical implementation.
|
||||
|
||||
**Button:**
|
||||
```json
|
||||
"usage": "<ButtonTextStagger text=\"Get Started\" onClick={() => console.log('clicked')} />"
|
||||
"usage": "<ButtonTextStagger text=\"Download Now\" onClick={() => console.log('clicked')} />"
|
||||
```
|
||||
|
||||
**Section with minimal props:**
|
||||
```json
|
||||
"usage": "<HeroBillboard title=\"Welcome\" description=\"Start building today\" buttons={[{ text: 'Get Started', href: '/signup' }]} />"
|
||||
"usage": "<HeroBillboard title=\"Welcome\" description=\"Start building today\" buttons={[{ text: 'Download Now', href: '/signup' }]} />"
|
||||
```
|
||||
|
||||
**CardStack section:**
|
||||
@@ -308,7 +308,7 @@ Single-line example showing typical implementation.
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 15
|
||||
}
|
||||
@@ -380,7 +380,7 @@ Single-line example showing typical implementation.
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 15
|
||||
}
|
||||
@@ -396,7 +396,7 @@ Single-line example showing typical implementation.
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usage": "<ButtonTextStagger text=\"Get Started\" onClick={() => console.log('clicked')} />"
|
||||
"usage": "<ButtonTextStagger text=\"Download Now\" onClick={() => console.log('clicked')} />"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 25
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usageExample": "<ButtonBounceEffect text=\"Get Started\" href=\"contact\" />",
|
||||
"usageExample": "<ButtonBounceEffect text=\"Download Now\" href=\"contact\" />",
|
||||
"do": [
|
||||
"Use for general use"
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 25
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usageExample": "<ButtonDirectionalHover text=\"Get Started\" href=\"contact\" />",
|
||||
"usageExample": "<ButtonDirectionalHover text=\"Download Now\" href=\"contact\" />",
|
||||
"do": [
|
||||
"Use for general use"
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 25
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usageExample": "<ButtonElasticEffect text=\"Get Started\" href=\"contact\" />",
|
||||
"usageExample": "<ButtonElasticEffect text=\"Download Now\" href=\"contact\" />",
|
||||
"do": [
|
||||
"Use for general use"
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 25
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usageExample": "<ButtonExpandHover text=\"Get Started\" href=\"contact\" />",
|
||||
"usageExample": "<ButtonExpandHover text=\"Download Now\" href=\"contact\" />",
|
||||
"do": [
|
||||
"Use for general use"
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 25
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usageExample": "<ButtonShiftHover text=\"Get Started\" href=\"pricing\" />",
|
||||
"usageExample": "<ButtonShiftHover text=\"Download Now\" href=\"pricing\" />",
|
||||
"do": [
|
||||
"Use for general use"
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 25
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usageExample": "<ButtonTextShift text=\"Get Started\" href=\"contact\" />",
|
||||
"usageExample": "<ButtonTextShift text=\"Download Now\" href=\"contact\" />",
|
||||
"do": [
|
||||
"Use for general use"
|
||||
],
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"textRules": {
|
||||
"text": {
|
||||
"required": true,
|
||||
"example": "Get Started",
|
||||
"example": "Download Now",
|
||||
"minChars": 2,
|
||||
"maxChars": 25
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
"ariaLabel?": "string",
|
||||
"type?": "'button' | 'submit' | 'reset' (default: 'button')"
|
||||
},
|
||||
"usageExample": "<ButtonTextStagger text=\"Get Started\" href=\"https://example.com\" />",
|
||||
"usageExample": "<ButtonTextStagger text=\"Download Now\" href=\"https://example.com\" />",
|
||||
"do": [
|
||||
"Use for general use"
|
||||
],
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://example.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroBillboardRotatedCarousel \n title=\"Transform Your Workflow\" \n description=\"Experience seamless collaboration and productivity\" \n tag=\"New Release\" \n tagIcon={Sparkles}\n buttons={[{ text: 'Get Started' }, { text: 'Learn More' }]}\n carouselItems={[\n { id: '1', imageSrc: '/image1.jpg', imageAlt: 'Product 1' },\n { id: '2', imageSrc: '/image2.jpg', imageAlt: 'Product 2' },\n { id: '3', imageSrc: '/image3.jpg', imageAlt: 'Product 3' },\n { id: '4', imageSrc: '/image4.jpg', imageAlt: 'Product 4' },\n { id: '5', imageSrc: '/image5.jpg', imageAlt: 'Product 5' },\n { id: '6', imageSrc: '/image6.jpg', imageAlt: 'Product 6' }\n ]}\n autoPlay={true}\n autoPlayInterval={4000}\n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroBillboardRotatedCarousel \n title=\"Transform Your Workflow\" \n description=\"Experience seamless collaboration and productivity\" \n tag=\"New Release\" \n tagIcon={Sparkles}\n buttons={[{ text: 'Download Now' }, { text: 'Learn More' }]}\n carouselItems={[\n { id: '1', imageSrc: '/image1.jpg', imageAlt: 'Product 1' },\n { id: '2', imageSrc: '/image2.jpg', imageAlt: 'Product 2' },\n { id: '3', imageSrc: '/image3.jpg', imageAlt: 'Product 3' },\n { id: '4', imageSrc: '/image4.jpg', imageAlt: 'Product 4' },\n { id: '5', imageSrc: '/image5.jpg', imageAlt: 'Product 5' },\n { id: '6', imageSrc: '/image6.jpg', imageAlt: 'Product 6' }\n ]}\n autoPlay={true}\n autoPlayInterval={4000}\n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages",
|
||||
"Use for feature showcases",
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', onClick: () => console.log('Get Started clicked') }",
|
||||
"{ text: 'Download Now', onClick: () => console.log('Download Now 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."
|
||||
@@ -85,7 +85,7 @@
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroBillboardScroll \n title=\"Scroll Animations\" \n description=\"Experience smooth, performant animations as you scroll through your content\" \n tag=\"Unleash the Power\" \n imageSrc=\"/dashboard.jpg\" \n imageAlt=\"Dashboard preview\"\n buttons={[{ text: 'Get Started', onClick: () => console.log('Get Started clicked') }, { text: 'Learn More', href: 'about' }]} \n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroBillboardScroll \n title=\"Scroll Animations\" \n description=\"Experience smooth, performant animations as you scroll through your content\" \n tag=\"Unleash the Power\" \n imageSrc=\"/dashboard.jpg\" \n imageAlt=\"Dashboard preview\"\n buttons={[{ text: 'Download Now', onClick: () => console.log('Download Now clicked') }, { text: 'Learn More', href: 'about' }]} \n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages",
|
||||
"Use for feature showcases",
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://example.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
@@ -124,7 +124,7 @@
|
||||
"marqueeTextClassName?": "string",
|
||||
"marqueeIconClassName?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <HeroBillboardTestimonial \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n background={{ variant: 'glowing-orb' }}\n tag=\"New Release\"\n tagIcon={Sparkles}\n imageSrc=\"/hero.jpg\"\n imageAlt=\"Product showcase\"\n mediaAnimation=\"slide-up\"\n buttons={[{ text: 'Get Started', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]}\n buttonAnimation=\"blur-reveal\"\n testimonials={[\n { name: 'Sarah Johnson', handle: 'CEO, TechCorp', testimonial: 'This transformed our workflow!', rating: 5, imageSrc: '/avatar.jpg' },\n { name: 'Michael Chen', handle: 'CTO, StartupXYZ', testimonial: 'Best investment we made.', rating: 5, imageSrc: '/avatar2.jpg' }\n ]}\n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <HeroBillboardTestimonial \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n background={{ variant: 'glowing-orb' }}\n tag=\"New Release\"\n tagIcon={Sparkles}\n imageSrc=\"/hero.jpg\"\n imageAlt=\"Product showcase\"\n mediaAnimation=\"slide-up\"\n buttons={[{ text: 'Download Now', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]}\n buttonAnimation=\"blur-reveal\"\n testimonials={[\n { name: 'Sarah Johnson', handle: 'CEO, TechCorp', testimonial: 'This transformed our workflow!', rating: 5, imageSrc: '/avatar.jpg' },\n { name: 'Michael Chen', handle: 'CTO, StartupXYZ', testimonial: 'Best investment we made.', rating: 5, imageSrc: '/avatar2.jpg' }\n ]}\n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages with social proof",
|
||||
"Use for product showcases with testimonials",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://github.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
@@ -59,7 +59,7 @@
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroCarouselLogo \n logoText=\"WEBILD\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n buttons={[{ text: 'Get Started', href: 'https://github.com' }, { text: 'Learn More', href: 'about' }]} \n slides={[{ imageSrc: '/slide1.jpg', imageAlt: 'Slide 1' }, { imageSrc: '/slide2.jpg', imageAlt: 'Slide 2' }, { imageSrc: '/slide3.jpg', imageAlt: 'Slide 3' }]}\n autoplayDelay={5000}\n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroCarouselLogo \n logoText=\"WEBILD\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n buttons={[{ text: 'Download Now', href: 'https://github.com' }, { text: 'Learn More', href: 'about' }]} \n slides={[{ imageSrc: '/slide1.jpg', imageAlt: 'Slide 1' }, { imageSrc: '/slide2.jpg', imageAlt: 'Slide 2' }, { imageSrc: '/slide3.jpg', imageAlt: 'Slide 3' }]}\n autoplayDelay={5000}\n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages",
|
||||
"Use for feature showcases",
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
"marqueeTextClassName?": "string",
|
||||
"marqueeIconClassName?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" borderRadius=\"rounded\">\n <HeroCentered\n title=\"Build Modern Web Experiences\"\n description=\"Create stunning, responsive websites with our component library.\"\n background={{ variant: 'plain' }}\n avatars={[\n { src: '/avatar1.jpg', alt: 'User 1' },\n { src: '/avatar2.jpg', alt: 'User 2' },\n { src: '/avatar3.jpg', alt: 'User 3' }\n ]}\n avatarText=\"Trusted by 1000+ users\"\n buttons={[{ text: 'Get Started', href: '#' }]}\n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" borderRadius=\"rounded\">\n <HeroCentered\n title=\"Build Modern Web Experiences\"\n description=\"Create stunning, responsive websites with our component library.\"\n background={{ variant: 'plain' }}\n avatars={[\n { src: '/avatar1.jpg', alt: 'User 1' },\n { src: '/avatar2.jpg', alt: 'User 2' },\n { src: '/avatar3.jpg', alt: 'User 3' }\n ]}\n avatarText=\"Trusted by 1000+ users\"\n buttons={[{ text: 'Download Now', href: '#' }]}\n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for impactful landing pages with social proof emphasis",
|
||||
"Include avatars for social proof",
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://github.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
@@ -67,7 +67,7 @@
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroLogo \n logoText=\"Webild\" \n description=\"Building the future of web design with innovative solutions\" \n buttons={[{ text: 'Get Started', href: 'https://github.com' }, { text: 'Learn More', href: 'about' }]} \n imageSrc=\"/placeholders/placeholder5.jpg\" \n imageAlt=\"Hero background\"\n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroLogo \n logoText=\"Webild\" \n description=\"Building the future of web design with innovative solutions\" \n buttons={[{ text: 'Download Now', href: 'https://github.com' }, { text: 'Learn More', href: 'about' }]} \n imageSrc=\"/placeholders/placeholder5.jpg\" \n imageAlt=\"Hero background\"\n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages",
|
||||
"Use for feature showcases",
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"text-stagger\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" cardStyle=\"layered-gradient\">\n <HeroLogoBillboardSplit \n logoText=\"ACME\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n buttons={[\n { text: 'Get Started', href: '#' },\n { text: 'Learn More', href: '#' }\n ]}\n layoutOrder=\"default\"\n imageSrc=\"/hero.jpg\"\n imageAlt=\"Hero showcase\"\n frameStyle=\"browser\"\n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"text-stagger\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" cardStyle=\"layered-gradient\">\n <HeroLogoBillboardSplit \n logoText=\"ACME\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n buttons={[\n { text: 'Download Now', href: '#' },\n { text: 'Learn More', href: '#' }\n ]}\n layoutOrder=\"default\"\n imageSrc=\"/hero.jpg\"\n imageAlt=\"Hero showcase\"\n frameStyle=\"browser\"\n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages",
|
||||
"Use for feature showcases",
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://example.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
@@ -91,7 +91,7 @@
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroOverlay \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n tag=\"New Release\" \n imageSrc=\"/hero-background.jpg\" \n imageAlt=\"Hero background\"\n textPosition=\"bottom-left\"\n showBlur={true}\n showDimOverlay={false}\n buttons={[{ text: 'Get Started', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]} \n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"hover-bubble\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\">\n <HeroOverlay \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n tag=\"New Release\" \n imageSrc=\"/hero-background.jpg\" \n imageAlt=\"Hero background\"\n textPosition=\"bottom-left\"\n showBlur={true}\n showDimOverlay={false}\n buttons={[{ text: 'Download Now', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]} \n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages",
|
||||
"Use for feature showcases",
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"tagIcon?": "LucideIcon",
|
||||
"tagAnimation?": "'none' | 'opacity' | 'slide-up' | 'blur-reveal'",
|
||||
"inputPlaceholder?": "string (default: 'Enter your email')",
|
||||
"buttonText?": "string (default: 'Get Started')",
|
||||
"buttonText?": "string (default: 'Download Now')",
|
||||
"onSubmit?": "(email: string) => void",
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string",
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://example.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://example.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
@@ -86,7 +86,7 @@
|
||||
"showMarqueeCard?": "boolean (default: true)",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <HeroSplitDoubleCarousel \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n background={{ variant: 'glowing-orb' }}\n tag=\"New Release\"\n carouselPosition=\"right\" \n leftCarouselItems={[\n { imageSrc: '/placeholder1.jpg', imageAlt: 'Gallery 1' },\n { imageSrc: '/placeholder2.jpg', imageAlt: 'Gallery 2' },\n { imageSrc: '/placeholder3.jpg', imageAlt: 'Gallery 3' },\n { imageSrc: '/placeholder4.jpg', imageAlt: 'Gallery 4' }\n ]}\n rightCarouselItems={[\n { imageSrc: '/placeholder5.jpg', imageAlt: 'Gallery 5' },\n { imageSrc: '/placeholder6.jpg', imageAlt: 'Gallery 6' },\n { imageSrc: '/placeholder7.jpg', imageAlt: 'Gallery 7' },\n { imageSrc: '/placeholder8.jpg', imageAlt: 'Gallery 8' }\n ]}\n buttons={[{ text: 'Get Started', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]} \n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <HeroSplitDoubleCarousel \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n background={{ variant: 'glowing-orb' }}\n tag=\"New Release\"\n carouselPosition=\"right\" \n leftCarouselItems={[\n { imageSrc: '/placeholder1.jpg', imageAlt: 'Gallery 1' },\n { imageSrc: '/placeholder2.jpg', imageAlt: 'Gallery 2' },\n { imageSrc: '/placeholder3.jpg', imageAlt: 'Gallery 3' },\n { imageSrc: '/placeholder4.jpg', imageAlt: 'Gallery 4' }\n ]}\n rightCarouselItems={[\n { imageSrc: '/placeholder5.jpg', imageAlt: 'Gallery 5' },\n { imageSrc: '/placeholder6.jpg', imageAlt: 'Gallery 6' },\n { imageSrc: '/placeholder7.jpg', imageAlt: 'Gallery 7' },\n { imageSrc: '/placeholder8.jpg', imageAlt: 'Gallery 8' }\n ]}\n buttons={[{ text: 'Download Now', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]} \n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages with visual portfolios",
|
||||
"Use for image galleries and creative showcases",
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
"imagePosition?": "'left' | 'right' (default: 'right')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<HeroSplitKpi title=\"The Future of Supply Chain\" description=\"Ship globally within 3 days with smart fulfillment\" background={{ variant: \"radial-gradient\" }} enableKpiAnimation={true} kpis={[{ value: '4-10 Days', label: 'Worldwide Delivery' }, { value: '99.8%', label: 'Order Accuracy' }, { value: '10x', label: 'Faster Lead Times' }]} imageSrc=\"/hero-image.jpg\" imageAlt=\"Supply chain\" buttons={[{ text: 'Get Started', href: 'https://example.com' }]} />",
|
||||
"usageExample": "<HeroSplitKpi title=\"The Future of Supply Chain\" description=\"Ship globally within 3 days with smart fulfillment\" background={{ variant: \"radial-gradient\" }} enableKpiAnimation={true} kpis={[{ value: '4-10 Days', label: 'Worldwide Delivery' }, { value: '99.8%', label: 'Order Accuracy' }, { value: '10x', label: 'Faster Lead Times' }]} imageSrc=\"/hero-image.jpg\" imageAlt=\"Supply chain\" buttons={[{ text: 'Download Now', href: 'https://example.com' }]} />",
|
||||
"do": [
|
||||
"Use for landing pages",
|
||||
"Use for feature showcases",
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
"props": "Partial<ButtonPropsForVariant> - Additional button props like className, textClassName (optional)"
|
||||
},
|
||||
"examples": [
|
||||
"{ text: 'Get Started', href: 'https://example.com' }",
|
||||
"{ text: 'Download Now', 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."
|
||||
@@ -134,7 +134,7 @@
|
||||
"marqueeTextClassName?": "string",
|
||||
"marqueeIconClassName?": "string"
|
||||
},
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <HeroSplitTestimonial \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n background={{ variant: 'glowing-orb' }}\n tag=\"New Release\"\n tagIcon={Sparkles}\n imagePosition=\"right\" \n imageSrc=\"/hero.jpg\"\n imageAlt=\"Product showcase\"\n mediaAnimation=\"slide-up\"\n buttons={[{ text: 'Get Started', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]}\n buttonAnimation=\"blur-reveal\"\n testimonials={[\n { name: 'Sarah Johnson', handle: 'CEO, TechCorp', testimonial: 'This transformed our workflow!', rating: 5, imageSrc: '/avatar.jpg' },\n { name: 'Michael Chen', handle: 'CTO, StartupXYZ', testimonial: 'Best investment we made.', rating: 5, imageSrc: '/avatar2.jpg' }\n ]}\n />\n</ThemeProvider>",
|
||||
"usageExample": "<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"pill\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <HeroSplitTestimonial \n title=\"Build Modern Web Experiences\" \n description=\"Create stunning, responsive websites with our comprehensive component library\" \n background={{ variant: 'glowing-orb' }}\n tag=\"New Release\"\n tagIcon={Sparkles}\n imagePosition=\"right\" \n imageSrc=\"/hero.jpg\"\n imageAlt=\"Product showcase\"\n mediaAnimation=\"slide-up\"\n buttons={[{ text: 'Download Now', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]}\n buttonAnimation=\"blur-reveal\"\n testimonials={[\n { name: 'Sarah Johnson', handle: 'CEO, TechCorp', testimonial: 'This transformed our workflow!', rating: 5, imageSrc: '/avatar.jpg' },\n { name: 'Michael Chen', handle: 'CTO, StartupXYZ', testimonial: 'Best investment we made.', rating: 5, imageSrc: '/avatar2.jpg' }\n ]}\n />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for landing pages with social proof",
|
||||
"Use for product showcases with testimonials",
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"ariaLabel?": "string (default: 'About section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "// Wrap in ThemeProvider\n<ThemeProvider defaultButtonVariant=\"text-stagger\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"rounded\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <InlineImageSplitTextAbout heading={[{ type: 'text', content: 'Building the future with' }, { type: 'image', src: '/brand/logo.png', alt: 'Company logo' }, { type: 'text', content: 'innovative solutions' }]} useInvertedBackground={false} buttons={[{ text: 'Get Started', href: '/signup' }, { text: 'Learn More', href: '/about' }]} />\n</ThemeProvider>",
|
||||
"usageExample": "// Wrap in ThemeProvider\n<ThemeProvider defaultButtonVariant=\"text-stagger\" defaultTextAnimation=\"entrance-slide\" borderRadius=\"rounded\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <InlineImageSplitTextAbout heading={[{ type: 'text', content: 'Building the future with' }, { type: 'image', src: '/brand/logo.png', alt: 'Company logo' }, { type: 'text', content: 'innovative solutions' }]} useInvertedBackground={false} buttons={[{ text: 'Download Now', href: '/signup' }, { text: 'Learn More', href: '/about' }]} />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for about pages",
|
||||
"Use for company information",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"required": true,
|
||||
"minChars": 2,
|
||||
"maxChars": 24,
|
||||
"example": "Get Started"
|
||||
"example": "Download Now"
|
||||
},
|
||||
"href": {
|
||||
"required": false,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"required": true,
|
||||
"minChars": 2,
|
||||
"maxChars": 24,
|
||||
"example": "Get Started"
|
||||
"example": "Download Now"
|
||||
},
|
||||
"href": {
|
||||
"required": false,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"required": true,
|
||||
"minChars": 2,
|
||||
"maxChars": 15,
|
||||
"example": "Get Started"
|
||||
"example": "Download Now"
|
||||
},
|
||||
"href": {
|
||||
"required": false,
|
||||
@@ -55,7 +55,7 @@
|
||||
"brandName?": "string (default: 'Webild')",
|
||||
"className?": "string (default: '')"
|
||||
},
|
||||
"usageExample": "<NavbarStyleCentered navItems={[{name: 'Home', id: 'home'}, {name: 'About', id: 'about'}, {name: 'Services', id: 'services'}, {name: 'Blog', id: 'blog'}, {name: 'Contact', id: 'contact'}]} button={{text: 'Get Started', href: 'contact'}} />",
|
||||
"usageExample": "<NavbarStyleCentered navItems={[{name: 'Home', id: 'home'}, {name: 'About', id: 'about'}, {name: 'Services', id: 'services'}, {name: 'Blog', id: 'blog'}, {name: 'Contact', id: 'contact'}]} button={{text: 'Download Now', href: 'contact'}} />",
|
||||
"do": [
|
||||
"Use for feature showcases",
|
||||
"Use for capability displays",
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"ariaLabel?": "string (default: 'Pricing section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<PricingCardEight plans={[{ id: '1', badge: 'Most Popular', price: '$29/mo', subtitle: 'Perfect for small teams', buttons: [{ text: 'Get Started', href: '/signup' }], features: ['Up to 10 team members', '100GB storage', 'Priority support'] }]} animationType=\"slide-up\" title=\"Choose Your Plan\" description=\"Select the perfect plan for your needs\" textboxLayout=\"default\" useInvertedBackground={false} />",
|
||||
"usageExample": "<PricingCardEight plans={[{ id: '1', badge: 'Most Popular', price: '$29/mo', subtitle: 'Perfect for small teams', buttons: [{ text: 'Download Now', href: '/signup' }], features: ['Up to 10 team members', '100GB storage', 'Priority support'] }]} animationType=\"slide-up\" title=\"Choose Your Plan\" description=\"Select the perfect plan for your needs\" textboxLayout=\"default\" useInvertedBackground={false} />",
|
||||
"do": [
|
||||
"Use for feature showcases",
|
||||
"Use for capability displays",
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
"ariaLabel?": "string (default: 'Pricing section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "<PricingCardTwo plans={[{ id: '1', badge: 'Business Plan', price: '$29/mo', subtitle: 'Perfect for small teams', buttons: [{ text: 'Get Started', onClick: () => 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={false} />",
|
||||
"usageExample": "<PricingCardTwo plans={[{ id: '1', badge: 'Business Plan', price: '$29/mo', subtitle: 'Perfect for small teams', buttons: [{ text: 'Download Now', onClick: () => 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={false} />",
|
||||
"do": [
|
||||
"Use for feature showcases",
|
||||
"Use for capability displays",
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"ariaLabel?": "string (default: 'About section')",
|
||||
"className?": "string"
|
||||
},
|
||||
"usageExample": "// Wrap in ThemeProvider\n<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"reveal-blur\" borderRadius=\"soft\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <TextAbout title=\"We create exceptional digital experiences\" useInvertedBackground={false} buttons={[{ text: 'Get Started', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]} />\n</ThemeProvider>",
|
||||
"usageExample": "// Wrap in ThemeProvider\n<ThemeProvider defaultButtonVariant=\"icon-arrow\" defaultTextAnimation=\"reveal-blur\" borderRadius=\"soft\" background=\"aurora\" cardStyle=\"glass-elevated\" primaryButtonStyle=\"gradient\" secondaryButtonStyle=\"glass\">\n <TextAbout title=\"We create exceptional digital experiences\" useInvertedBackground={false} buttons={[{ text: 'Download Now', href: 'https://example.com' }, { text: 'Learn More', href: 'about' }]} />\n</ThemeProvider>",
|
||||
"do": [
|
||||
"Use for feature showcases",
|
||||
"Use for capability displays",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"tagIcon?": "LucideIcon",
|
||||
"tagAnimation?": "'none' | 'opacity' | 'slide-up' | 'blur-reveal'",
|
||||
"inputPlaceholder?": "string (default: 'Enter your email')",
|
||||
"buttonText?": "string (default: 'Get Started')",
|
||||
"buttonText?": "string (default: 'Download Now')",
|
||||
"onSubmit?": "(email: string) => void",
|
||||
"ariaLabel?": "string (default: 'Hero section')",
|
||||
"className?": "string",
|
||||
|
||||
@@ -6,18 +6,8 @@ import "./globals.css";
|
||||
import { ServiceWrapper } from "@/components/ServiceWrapper";
|
||||
import Tag from "@/tag/Tag";
|
||||
|
||||
const halant = Halant({
|
||||
variable: "--font-halant", subsets: ["latin"],
|
||||
weight: ["300", "400", "500", "600", "700"],
|
||||
});
|
||||
|
||||
const inter = Inter({
|
||||
variable: "--font-inter", subsets: ["latin"],
|
||||
});
|
||||
|
||||
const openSans = Open_Sans({
|
||||
variable: "--font-open-sans", subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Torah Lock - iOS Torah Lock for Jewish Morning Prayers", description: "Start your day with Hashem. Torah Lock is a beautiful iOS app designed to help Jewish users pray every morning with guided prayers, reminders, and community connection.", keywords: "prayer app, iOS, Jewish, morning prayers, spiritual growth, Torah Lock", metadataBase: new URL("https://shachar-prayer.com"),
|
||||
@@ -33,6 +23,15 @@ export const metadata: Metadata = {
|
||||
},
|
||||
};
|
||||
|
||||
const inter = Inter({
|
||||
variable: "--font-inter",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
const openSans = Open_Sans({
|
||||
variable: "--font-open-sans",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
@@ -41,9 +40,7 @@ export default function RootLayout({
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<ServiceWrapper>
|
||||
<body
|
||||
className={`${halant.variable} ${inter.variable} ${openSans.variable} antialiased`}
|
||||
>
|
||||
<body className={`${inter.variable} ${openSans.variable} antialiased`}>
|
||||
<Tag />
|
||||
{children}
|
||||
|
||||
@@ -288,9 +285,7 @@ export default function RootLayout({
|
||||
const getElementInfo = (element, assignId = false) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const tagName = element.tagName.toLowerCase();
|
||||
const selector = getUniqueSelector(element, assignId);
|
||||
const sectionId = getSectionId(element);
|
||||
|
||||
|
||||
let className = undefined;
|
||||
try {
|
||||
if (element.className) {
|
||||
@@ -318,8 +313,7 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
if (tagName === 'img') {
|
||||
const originalSrc = extractOriginalUrl(element.src);
|
||||
info.imageData = {
|
||||
info.imageData = {
|
||||
src: originalSrc,
|
||||
alt: element.alt || undefined,
|
||||
naturalWidth: element.naturalWidth,
|
||||
@@ -330,8 +324,7 @@ export default function RootLayout({
|
||||
|
||||
if (tagName === 'video') {
|
||||
const rawSrc = element.src || element.currentSrc || (element.querySelector('source') && element.querySelector('source').src) || '';
|
||||
const resolvedSrc = extractOriginalUrl(rawSrc);
|
||||
info.imageData = {
|
||||
info.imageData = {
|
||||
src: resolvedSrc,
|
||||
alt: element.getAttribute('aria-label') || undefined,
|
||||
isBackground: false,
|
||||
@@ -344,8 +337,7 @@ export default function RootLayout({
|
||||
if (backgroundImage && backgroundImage !== 'none') {
|
||||
const urlMatch = backgroundImage.match(/url(['"]?([^'")]+)['"]?)/);
|
||||
if (urlMatch) {
|
||||
const originalBgSrc = extractOriginalUrl(urlMatch[1]);
|
||||
if (tagName !== 'img') {
|
||||
if (tagName !== 'img') {
|
||||
info.imageData = {
|
||||
src: originalBgSrc,
|
||||
isBackground: true
|
||||
@@ -357,8 +349,7 @@ export default function RootLayout({
|
||||
}
|
||||
}
|
||||
|
||||
const elementType = getElementType(element);
|
||||
info.elementType = elementType;
|
||||
info.elementType = elementType;
|
||||
|
||||
if (elementType === 'Button') {
|
||||
const buttonText = element.textContent?.trim() || element.value || element.getAttribute('aria-label') || '';
|
||||
@@ -451,13 +442,11 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
const isTextElement = (element) => {
|
||||
const elementType = getElementType(element);
|
||||
return elementType === 'Text';
|
||||
return elementType === 'Text';
|
||||
};
|
||||
|
||||
const isButtonElement = (element) => {
|
||||
const elementType = getElementType(element);
|
||||
return elementType === 'Button';
|
||||
return elementType === 'Button';
|
||||
};
|
||||
|
||||
const updateButtonText = (element, newText) => {
|
||||
@@ -532,8 +521,7 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
const handleInput = () => {
|
||||
const elementInfo = getElementInfo(element);
|
||||
let currentText = element.textContent;
|
||||
let currentText = element.textContent;
|
||||
|
||||
// Ensure there's always at least a space to keep the element editable
|
||||
if (currentText === '' || currentText === null || currentText.length === 0) {
|
||||
@@ -646,8 +634,7 @@ export default function RootLayout({
|
||||
}, '*');
|
||||
|
||||
if (save && originalContent !== element.textContent) {
|
||||
const elementInfo = getElementInfo(element);
|
||||
let finalText = element.textContent;
|
||||
let finalText = element.textContent;
|
||||
|
||||
// Trim the final text and convert space-only to empty string for saving
|
||||
if (finalText === ' ' || finalText.trim() === '') {
|
||||
@@ -776,7 +763,7 @@ export default function RootLayout({
|
||||
lastMouseX = e.clientX;
|
||||
lastMouseY = e.clientY;
|
||||
|
||||
const target = getMostSpecificElement(e.clientX, e.clientY) || e.target;
|
||||
|| e.target;
|
||||
|
||||
if (!isValidElement(target) || target === hoveredElement || target === selectedElement) {
|
||||
return;
|
||||
@@ -808,8 +795,7 @@ export default function RootLayout({
|
||||
hoverOverlay = createHoverOverlay(target);
|
||||
}
|
||||
|
||||
const elementType = getElementType(target);
|
||||
showElementTypeLabel(target, elementType);
|
||||
showElementTypeLabel(target, elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
type: 'webild-element-hover',
|
||||
@@ -851,7 +837,7 @@ export default function RootLayout({
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const target = getMostSpecificElement(e.clientX, e.clientY) || e.target;
|
||||
|| e.target;
|
||||
if (!isValidElement(target)) return;
|
||||
|
||||
if (selectedElement && selectedElement !== target) {
|
||||
@@ -896,8 +882,7 @@ export default function RootLayout({
|
||||
hoveredElement = null;
|
||||
}
|
||||
|
||||
const elementInfo = getElementInfo(target, true);
|
||||
selectedElement.dataset.webildSelector = elementInfo.selector;
|
||||
selectedElement.dataset.webildSelector = elementInfo.selector;
|
||||
showElementTypeLabel(target, elementInfo.elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
@@ -980,8 +965,7 @@ export default function RootLayout({
|
||||
isScrolling = false;
|
||||
|
||||
if (lastMouseX > 0 && lastMouseY > 0) {
|
||||
const target = getMostSpecificElement(lastMouseX, lastMouseY);
|
||||
if (target && isValidElement(target) && target !== selectedElement) {
|
||||
if (target && isValidElement(target) && target !== selectedElement) {
|
||||
hoveredElement = target;
|
||||
|
||||
const computedStyle = window.getComputedStyle(target);
|
||||
@@ -995,8 +979,7 @@ export default function RootLayout({
|
||||
hoveredElement.classList.add(hoverClass);
|
||||
hoverOverlay = createHoverOverlay(target);
|
||||
|
||||
const elementType = getElementType(target);
|
||||
showElementTypeLabel(target, elementType);
|
||||
showElementTypeLabel(target, elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
type: 'webild-element-hover',
|
||||
@@ -1019,8 +1002,7 @@ export default function RootLayout({
|
||||
|
||||
const saveChangeToStorage = (change) => {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]');
|
||||
const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]');
|
||||
|
||||
const filteredChanges = existingChanges.filter(c => {
|
||||
return !(c.oldValue === change.oldValue && c.sectionId === change.sectionId);
|
||||
@@ -1040,8 +1022,7 @@ export default function RootLayout({
|
||||
|
||||
const clearLocalChanges = () => {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
localStorage.removeItem(storageKey);
|
||||
localStorage.removeItem(storageKey);
|
||||
window.parent.postMessage({
|
||||
type: 'webild-local-changes-cleared',
|
||||
data: {}
|
||||
@@ -1090,8 +1071,7 @@ export default function RootLayout({
|
||||
|
||||
if (e.data.type === 'webild-cancel-changes') {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
const savedChanges = localStorage.getItem(storageKey);
|
||||
const savedChanges = localStorage.getItem(storageKey);
|
||||
if (savedChanges) {
|
||||
const changes = JSON.parse(savedChanges);
|
||||
changes.forEach(change => {
|
||||
@@ -1113,8 +1093,7 @@ export default function RootLayout({
|
||||
if (isBackground) {
|
||||
element.style.backgroundImage = change.oldValue ? 'url(' + change.oldValue + ')' : '';
|
||||
} else {
|
||||
const oldMediaType = getMediaTypeFromUrl(change.oldValue);
|
||||
if (revertTag === 'video' && oldMediaType === 'image') {
|
||||
if (revertTag === 'video' && oldMediaType === 'image') {
|
||||
swapMediaElement(element, 'img', change.oldValue);
|
||||
} else if (revertTag === 'img' && oldMediaType === 'video') {
|
||||
swapMediaElement(element, 'video', change.oldValue);
|
||||
@@ -1162,8 +1141,7 @@ export default function RootLayout({
|
||||
const el = textElements[i];
|
||||
if (isTextElement(el) && el.textContent.trim() === (oldValue || '').trim()) {
|
||||
element = el;
|
||||
const newSelector = getUniqueSelector(element, true);
|
||||
if (newSelector) {
|
||||
if (newSelector) {
|
||||
element.dataset.webildSelector = newSelector;
|
||||
}
|
||||
break;
|
||||
@@ -1254,10 +1232,8 @@ export default function RootLayout({
|
||||
replaced = true;
|
||||
} else if (element.tagName.toLowerCase() === 'img') {
|
||||
oldValue = element.src;
|
||||
const newMediaType = getMediaTypeFromUrl(newSrc);
|
||||
if (newMediaType === 'video' && allowMediaTypeSwap) {
|
||||
const swapped = swapMediaElement(element, 'video', newSrc);
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
if (newMediaType === 'video' && allowMediaTypeSwap) {
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
element = swapped;
|
||||
} else {
|
||||
element.src = newSrc;
|
||||
@@ -1265,11 +1241,9 @@ export default function RootLayout({
|
||||
replaced = true;
|
||||
} else if (element.tagName.toLowerCase() === 'video') {
|
||||
oldValue = element.src || element.currentSrc || '';
|
||||
const newMediaType = getMediaTypeFromUrl(newSrc);
|
||||
const sources = element.querySelectorAll('source');
|
||||
const sources = element.querySelectorAll('source');
|
||||
if (newMediaType === 'image' && allowMediaTypeSwap) {
|
||||
const swapped = swapMediaElement(element, 'img', newSrc);
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
element = swapped;
|
||||
} else {
|
||||
if (sources.length > 0) {
|
||||
@@ -1291,8 +1265,7 @@ export default function RootLayout({
|
||||
}
|
||||
|
||||
if (replaced) {
|
||||
const elementInfo = getElementInfo(element);
|
||||
|
||||
|
||||
let cleanOldValue = oldValue;
|
||||
if (oldValue.includes('url(')) {
|
||||
const urlMatch = oldValue.match(/url(['"]?([^'")]+)['"]?)/);
|
||||
@@ -1363,13 +1336,7 @@ export default function RootLayout({
|
||||
}
|
||||
}, true);
|
||||
|
||||
const urlCheckInterval = setInterval(() => {
|
||||
if (lastPathname !== window.location.pathname) {
|
||||
lastPathname = window.location.pathname;
|
||||
notifyPageChange();
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
||||
notifyPageChange();
|
||||
|
||||
window.webildCleanup = () => {
|
||||
@@ -1655,9 +1622,7 @@ export default function RootLayout({
|
||||
const getElementInfo = (element, assignId = false) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const tagName = element.tagName.toLowerCase();
|
||||
const selector = getUniqueSelector(element, assignId);
|
||||
const sectionId = getSectionId(element);
|
||||
|
||||
|
||||
let className = undefined;
|
||||
try {
|
||||
if (element.className) {
|
||||
@@ -1685,8 +1650,7 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
if (tagName === 'img') {
|
||||
const originalSrc = extractOriginalUrl(element.src);
|
||||
info.imageData = {
|
||||
info.imageData = {
|
||||
src: originalSrc,
|
||||
alt: element.alt || undefined,
|
||||
naturalWidth: element.naturalWidth,
|
||||
@@ -1697,8 +1661,7 @@ export default function RootLayout({
|
||||
|
||||
if (tagName === 'video') {
|
||||
const rawSrc = element.src || element.currentSrc || (element.querySelector('source') && element.querySelector('source').src) || '';
|
||||
const resolvedSrc = extractOriginalUrl(rawSrc);
|
||||
info.imageData = {
|
||||
info.imageData = {
|
||||
src: resolvedSrc,
|
||||
alt: element.getAttribute('aria-label') || undefined,
|
||||
isBackground: false,
|
||||
@@ -1711,8 +1674,7 @@ export default function RootLayout({
|
||||
if (backgroundImage && backgroundImage !== 'none') {
|
||||
const urlMatch = backgroundImage.match(/url(['"]?([^'")]+)['"]?)/);
|
||||
if (urlMatch) {
|
||||
const originalBgSrc = extractOriginalUrl(urlMatch[1]);
|
||||
if (tagName !== 'img') {
|
||||
if (tagName !== 'img') {
|
||||
info.imageData = {
|
||||
src: originalBgSrc,
|
||||
isBackground: true
|
||||
@@ -1724,8 +1686,7 @@ export default function RootLayout({
|
||||
}
|
||||
}
|
||||
|
||||
const elementType = getElementType(element);
|
||||
info.elementType = elementType;
|
||||
info.elementType = elementType;
|
||||
|
||||
if (elementType === 'Button') {
|
||||
const buttonText = element.textContent?.trim() || element.value || element.getAttribute('aria-label') || '';
|
||||
@@ -1818,13 +1779,11 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
const isTextElement = (element) => {
|
||||
const elementType = getElementType(element);
|
||||
return elementType === 'Text';
|
||||
return elementType === 'Text';
|
||||
};
|
||||
|
||||
const isButtonElement = (element) => {
|
||||
const elementType = getElementType(element);
|
||||
return elementType === 'Button';
|
||||
return elementType === 'Button';
|
||||
};
|
||||
|
||||
const updateButtonText = (element, newText) => {
|
||||
@@ -1899,8 +1858,7 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
const handleInput = () => {
|
||||
const elementInfo = getElementInfo(element);
|
||||
let currentText = element.textContent;
|
||||
let currentText = element.textContent;
|
||||
|
||||
// Ensure there's always at least a space to keep the element editable
|
||||
if (currentText === '' || currentText === null || currentText.length === 0) {
|
||||
@@ -2013,8 +1971,7 @@ export default function RootLayout({
|
||||
}, '*');
|
||||
|
||||
if (save && originalContent !== element.textContent) {
|
||||
const elementInfo = getElementInfo(element);
|
||||
let finalText = element.textContent;
|
||||
let finalText = element.textContent;
|
||||
|
||||
// Trim the final text and convert space-only to empty string for saving
|
||||
if (finalText === ' ' || finalText.trim() === '') {
|
||||
@@ -2143,7 +2100,7 @@ export default function RootLayout({
|
||||
lastMouseX = e.clientX;
|
||||
lastMouseY = e.clientY;
|
||||
|
||||
const target = getMostSpecificElement(e.clientX, e.clientY) || e.target;
|
||||
|| e.target;
|
||||
|
||||
if (!isValidElement(target) || target === hoveredElement || target === selectedElement) {
|
||||
return;
|
||||
@@ -2175,8 +2132,7 @@ export default function RootLayout({
|
||||
hoverOverlay = createHoverOverlay(target);
|
||||
}
|
||||
|
||||
const elementType = getElementType(target);
|
||||
showElementTypeLabel(target, elementType);
|
||||
showElementTypeLabel(target, elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
type: 'webild-element-hover',
|
||||
@@ -2218,7 +2174,7 @@ export default function RootLayout({
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const target = getMostSpecificElement(e.clientX, e.clientY) || e.target;
|
||||
|| e.target;
|
||||
if (!isValidElement(target)) return;
|
||||
|
||||
if (selectedElement && selectedElement !== target) {
|
||||
@@ -2263,8 +2219,7 @@ export default function RootLayout({
|
||||
hoveredElement = null;
|
||||
}
|
||||
|
||||
const elementInfo = getElementInfo(target, true);
|
||||
selectedElement.dataset.webildSelector = elementInfo.selector;
|
||||
selectedElement.dataset.webildSelector = elementInfo.selector;
|
||||
showElementTypeLabel(target, elementInfo.elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
@@ -2347,8 +2302,7 @@ export default function RootLayout({
|
||||
isScrolling = false;
|
||||
|
||||
if (lastMouseX > 0 && lastMouseY > 0) {
|
||||
const target = getMostSpecificElement(lastMouseX, lastMouseY);
|
||||
if (target && isValidElement(target) && target !== selectedElement) {
|
||||
if (target && isValidElement(target) && target !== selectedElement) {
|
||||
hoveredElement = target;
|
||||
|
||||
const computedStyle = window.getComputedStyle(target);
|
||||
@@ -2362,8 +2316,7 @@ export default function RootLayout({
|
||||
hoveredElement.classList.add(hoverClass);
|
||||
hoverOverlay = createHoverOverlay(target);
|
||||
|
||||
const elementType = getElementType(target);
|
||||
showElementTypeLabel(target, elementType);
|
||||
showElementTypeLabel(target, elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
type: 'webild-element-hover',
|
||||
@@ -2386,8 +2339,7 @@ export default function RootLayout({
|
||||
|
||||
const saveChangeToStorage = (change) => {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]');
|
||||
const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]');
|
||||
|
||||
const filteredChanges = existingChanges.filter(c => {
|
||||
return !(c.oldValue === change.oldValue && c.sectionId === change.sectionId);
|
||||
@@ -2407,8 +2359,7 @@ export default function RootLayout({
|
||||
|
||||
const clearLocalChanges = () => {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
localStorage.removeItem(storageKey);
|
||||
localStorage.removeItem(storageKey);
|
||||
window.parent.postMessage({
|
||||
type: 'webild-local-changes-cleared',
|
||||
data: {}
|
||||
@@ -2457,8 +2408,7 @@ export default function RootLayout({
|
||||
|
||||
if (e.data.type === 'webild-cancel-changes') {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
const savedChanges = localStorage.getItem(storageKey);
|
||||
const savedChanges = localStorage.getItem(storageKey);
|
||||
if (savedChanges) {
|
||||
const changes = JSON.parse(savedChanges);
|
||||
changes.forEach(change => {
|
||||
@@ -2480,8 +2430,7 @@ export default function RootLayout({
|
||||
if (isBackground) {
|
||||
element.style.backgroundImage = change.oldValue ? 'url(' + change.oldValue + ')' : '';
|
||||
} else {
|
||||
const oldMediaType = getMediaTypeFromUrl(change.oldValue);
|
||||
if (revertTag === 'video' && oldMediaType === 'image') {
|
||||
if (revertTag === 'video' && oldMediaType === 'image') {
|
||||
swapMediaElement(element, 'img', change.oldValue);
|
||||
} else if (revertTag === 'img' && oldMediaType === 'video') {
|
||||
swapMediaElement(element, 'video', change.oldValue);
|
||||
@@ -2529,8 +2478,7 @@ export default function RootLayout({
|
||||
const el = textElements[i];
|
||||
if (isTextElement(el) && el.textContent.trim() === (oldValue || '').trim()) {
|
||||
element = el;
|
||||
const newSelector = getUniqueSelector(element, true);
|
||||
if (newSelector) {
|
||||
if (newSelector) {
|
||||
element.dataset.webildSelector = newSelector;
|
||||
}
|
||||
break;
|
||||
@@ -2621,10 +2569,8 @@ export default function RootLayout({
|
||||
replaced = true;
|
||||
} else if (element.tagName.toLowerCase() === 'img') {
|
||||
oldValue = element.src;
|
||||
const newMediaType = getMediaTypeFromUrl(newSrc);
|
||||
if (newMediaType === 'video' && allowMediaTypeSwap) {
|
||||
const swapped = swapMediaElement(element, 'video', newSrc);
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
if (newMediaType === 'video' && allowMediaTypeSwap) {
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
element = swapped;
|
||||
} else {
|
||||
element.src = newSrc;
|
||||
@@ -2632,11 +2578,9 @@ export default function RootLayout({
|
||||
replaced = true;
|
||||
} else if (element.tagName.toLowerCase() === 'video') {
|
||||
oldValue = element.src || element.currentSrc || '';
|
||||
const newMediaType = getMediaTypeFromUrl(newSrc);
|
||||
const sources = element.querySelectorAll('source');
|
||||
const sources = element.querySelectorAll('source');
|
||||
if (newMediaType === 'image' && allowMediaTypeSwap) {
|
||||
const swapped = swapMediaElement(element, 'img', newSrc);
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
element = swapped;
|
||||
} else {
|
||||
if (sources.length > 0) {
|
||||
@@ -2658,8 +2602,7 @@ export default function RootLayout({
|
||||
}
|
||||
|
||||
if (replaced) {
|
||||
const elementInfo = getElementInfo(element);
|
||||
|
||||
|
||||
let cleanOldValue = oldValue;
|
||||
if (oldValue.includes('url(')) {
|
||||
const urlMatch = oldValue.match(/url(['"]?([^'")]+)['"]?)/);
|
||||
@@ -2730,13 +2673,7 @@ export default function RootLayout({
|
||||
}
|
||||
}, true);
|
||||
|
||||
const urlCheckInterval = setInterval(() => {
|
||||
if (lastPathname !== window.location.pathname) {
|
||||
lastPathname = window.location.pathname;
|
||||
notifyPageChange();
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
||||
notifyPageChange();
|
||||
|
||||
window.webildCleanup = () => {
|
||||
|
||||
@@ -41,11 +41,11 @@ export default function LandingPage() {
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroSplitDualMedia
|
||||
title="Start your day with Hashem"
|
||||
description="A beautiful iOS app designed to help you pray every morning."
|
||||
description="begin your day before your phone begins you "
|
||||
background={{ variant: "plain" }}
|
||||
tag="Torah Lock"
|
||||
buttons={[
|
||||
{ text: "Get Started", href: "https://apps.apple.com" },
|
||||
{ text: "Download Now", href: "https://apps.apple.com" },
|
||||
{ text: "Learn More", href: "#about" }
|
||||
]}
|
||||
mediaItems={[
|
||||
@@ -58,7 +58,7 @@ export default function LandingPage() {
|
||||
]}
|
||||
mediaAnimation="none"
|
||||
rating={5}
|
||||
ratingText="Trusted by 50K+ users"
|
||||
ratingText="Used by over 1.5k+ Jews "
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ const HeroSignup = ({
|
||||
tagIcon,
|
||||
tagAnimation,
|
||||
inputPlaceholder = "Enter your email",
|
||||
buttonText = "Get Started",
|
||||
buttonText = "Download Now",
|
||||
onSubmit,
|
||||
ariaLabel = "Hero section",
|
||||
className = "",
|
||||
|
||||
Reference in New Issue
Block a user