Merge pull request #240 from widgeter/astro-v3
Add Brands widget, call to action to Content widget and small ui fixes
This commit is contained in:
@ -1,23 +1,18 @@
|
|||||||
---
|
---
|
||||||
import { Icon } from "astro-icon/components";
|
import { twMerge } from 'tailwind-merge';
|
||||||
import { twMerge } from "tailwind-merge";
|
import type { ItemGrid } from '~/types';
|
||||||
import type { ItemGrid } from "~/types";
|
import CTA from './CTA.astro';
|
||||||
import CTA from "./CTA.astro";
|
import { Icon } from 'astro-icon/components';
|
||||||
|
|
||||||
|
const { items = [], columns, defaultIcon = '', classes = {} } = Astro.props as ItemGrid;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
items = [],
|
container: containerClass = '',
|
||||||
columns,
|
panel: panelClass = '',
|
||||||
defaultIcon = "",
|
title: titleClass = '',
|
||||||
classes = {},
|
description: descriptionClass = '',
|
||||||
} = Astro.props as ItemGrid;
|
icon: defaultIconClass = 'text-primary',
|
||||||
|
action: actionClass = '',
|
||||||
const {
|
|
||||||
container: containerClass = "",
|
|
||||||
// container: containerClass = "md:grid-cols-2",
|
|
||||||
panel: panelClass = "",
|
|
||||||
title: titleClass = "",
|
|
||||||
description: descriptionClass = "",
|
|
||||||
icon: defaultIconClass = "text-primary",
|
|
||||||
} = classes;
|
} = classes;
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -27,74 +22,50 @@ const {
|
|||||||
class={twMerge(
|
class={twMerge(
|
||||||
`grid mx-auto gap-8 md:gap-y-12 ${
|
`grid mx-auto gap-8 md:gap-y-12 ${
|
||||||
columns === 4
|
columns === 4
|
||||||
? "lg:grid-cols-4 md:grid-cols-3 sm:grid-cols-2"
|
? 'lg:grid-cols-4 md:grid-cols-3 sm:grid-cols-2'
|
||||||
: columns === 3
|
: columns === 3
|
||||||
? "lg:grid-cols-3 sm:grid-cols-2"
|
? 'lg:grid-cols-3 sm:grid-cols-2'
|
||||||
: columns === 2
|
: columns === 2
|
||||||
? "sm:grid-cols-2 "
|
? 'sm:grid-cols-2 '
|
||||||
: ""
|
: ''
|
||||||
}`,
|
}`,
|
||||||
containerClass
|
containerClass
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{items.map(
|
{items.map(({ title, description, icon, callToAction, classes: itemClasses = {} }) => (
|
||||||
({
|
<div>
|
||||||
title,
|
<div class={twMerge('flex flex-row max-w-md', panelClass, itemClasses?.panel)}>
|
||||||
description,
|
<div class="flex justify-center">
|
||||||
icon,
|
{(icon || defaultIcon) && (
|
||||||
callToAction,
|
<Icon
|
||||||
classes: itemClasses = {},
|
name={icon || defaultIcon}
|
||||||
}) => (
|
class={twMerge('w-7 h-7 mr-2 rtl:mr-0 rtl:ml-2', defaultIconClass, itemClasses?.icon)}
|
||||||
<div>
|
/>
|
||||||
<div
|
|
||||||
class={twMerge(
|
|
||||||
"flex flex-row max-w-md",
|
|
||||||
panelClass,
|
|
||||||
itemClasses?.panel
|
|
||||||
)}
|
)}
|
||||||
>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="mt-0.5">
|
||||||
{(icon || defaultIcon) && (
|
{title && <h3 class={twMerge('text-xl font-bold', titleClass, itemClasses?.title)}>{title}</h3>}
|
||||||
<Icon
|
{description && (
|
||||||
name={icon || defaultIcon}
|
<p
|
||||||
class={twMerge(
|
class={twMerge(`${title ? 'mt-3' : ''} text-muted`, descriptionClass, itemClasses?.description)}
|
||||||
"w-7 h-7 mr-2 rtl:mr-0 rtl:ml-2",
|
set:html={description}
|
||||||
defaultIconClass,
|
/>
|
||||||
itemClasses?.icon
|
)}
|
||||||
)}
|
{callToAction && (
|
||||||
/>
|
<div
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3
|
|
||||||
class={twMerge(
|
class={twMerge(
|
||||||
"text-xl font-bold",
|
`${title || description ? 'mt-3' : ''} text-primary cursor-pointer`,
|
||||||
titleClass,
|
actionClass,
|
||||||
itemClasses?.title
|
itemClasses?.actionClass
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{title}
|
<CTA callToAction={callToAction} />
|
||||||
</h3>
|
</div>
|
||||||
{description && (
|
)}
|
||||||
<p
|
|
||||||
class={twMerge(
|
|
||||||
`${title ? "mt-3" : ""} text-muted`,
|
|
||||||
descriptionClass,
|
|
||||||
itemClasses?.description
|
|
||||||
)}
|
|
||||||
set:html={description}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{callToAction && (
|
|
||||||
<div class="mt-2 text-primary cursor-pointer">
|
|
||||||
<CTA callToAction={callToAction} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
</div>
|
||||||
)}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
36
src/components/widgets/Brands.astro
Normal file
36
src/components/widgets/Brands.astro
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
import { Icon } from 'astro-icon/components';
|
||||||
|
import type { Brands } from '~/types';
|
||||||
|
import Headline from '~/components/ui/Headline.astro';
|
||||||
|
import WidgetWrapper from '~/components/ui/WidgetWrapper.astro';
|
||||||
|
const {
|
||||||
|
title = '',
|
||||||
|
subtitle = '',
|
||||||
|
tagline = '',
|
||||||
|
icons = [],
|
||||||
|
images = [],
|
||||||
|
id,
|
||||||
|
isDark = false,
|
||||||
|
classes = {},
|
||||||
|
bg = await Astro.slots.render('bg'),
|
||||||
|
} = Astro.props as Brands;
|
||||||
|
---
|
||||||
|
|
||||||
|
<WidgetWrapper id={id} isDark={isDark} containerClass={`max-w-6xl mx-auto ${classes?.container ?? ''}`} bg={bg}>
|
||||||
|
<Headline title={title} subtitle={subtitle} tagline={tagline} />
|
||||||
|
|
||||||
|
<div class="flex flex-wrap justify-center gap-x-6 sm:gap-x-12 lg:gap-x-24">
|
||||||
|
{icons && icons.map((icon) => <Icon name={icon} class="py-3 lg:py-5 w-12 h-auto mx-auto sm:mx-0 text-gray-500" />)}
|
||||||
|
{
|
||||||
|
images &&
|
||||||
|
images.map(
|
||||||
|
(image) =>
|
||||||
|
image.src && (
|
||||||
|
<div class="flex justify-center col-span-1 my-2 lg:my-4 py-1 px-3 rounded-md dark:bg-gray-200">
|
||||||
|
<img src={image.src} alt={image.alt || ''} class="max-h-12" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</WidgetWrapper>
|
@ -1,16 +1,19 @@
|
|||||||
---
|
---
|
||||||
import { Icon } from 'astro-icon/components';
|
|
||||||
import type { Content } from '~/types';
|
import type { Content } from '~/types';
|
||||||
import Headline from '../ui/Headline.astro';
|
import Headline from '../ui/Headline.astro';
|
||||||
import WidgetWrapper from '../ui/WidgetWrapper.astro';
|
import WidgetWrapper from '../ui/WidgetWrapper.astro';
|
||||||
import Image from '~/components/common/Image.astro';
|
import Image from '~/components/common/Image.astro';
|
||||||
|
import CTA from '../ui/CTA.astro';
|
||||||
|
import ItemGrid from '../ui/ItemGrid.astro';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
title = await Astro.slots.render('title'),
|
title = await Astro.slots.render('title'),
|
||||||
subtitle = await Astro.slots.render('subtitle'),
|
subtitle = await Astro.slots.render('subtitle'),
|
||||||
tagline,
|
tagline,
|
||||||
content = await Astro.slots.render('content'),
|
content = await Astro.slots.render('content'),
|
||||||
|
callToAction,
|
||||||
items = [],
|
items = [],
|
||||||
|
columns,
|
||||||
image = await Astro.slots.render('image'),
|
image = await Astro.slots.render('image'),
|
||||||
isReversed = false,
|
isReversed = false,
|
||||||
isAfterContent = false,
|
isAfterContent = false,
|
||||||
@ -44,24 +47,26 @@ const {
|
|||||||
{content && <div class="mb-12 text-lg dark:text-slate-400" set:html={content} />}
|
{content && <div class="mb-12 text-lg dark:text-slate-400" set:html={content} />}
|
||||||
|
|
||||||
{
|
{
|
||||||
items && (
|
callToAction && (
|
||||||
<div class="space-y-8">
|
<div class="mt-[-40px] mb-8 text-primary cursor-pointer">
|
||||||
{items.map(({ title: title2, description, icon }) => (
|
<CTA callToAction={callToAction} />
|
||||||
<div class="flex">
|
|
||||||
<div class="flex-shrink-0">
|
|
||||||
<div class="flex h-7 w-7 items-center justify-center rounded-full bg-green-600 dark:bg-green-700 text-gray-50">
|
|
||||||
<Icon name={icon ? icon : 'tabler:check'} class="w-5 h-5" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ml-4 rtl:ml-0 rtl:mr-4">
|
|
||||||
{title2 && <h3 class="text-lg font-medium leading-6 dark:text-white">{title2}</h3>}
|
|
||||||
{description && <p class="mt-2 text-muted dark:text-slate-400" set:html={description} />}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<ItemGrid
|
||||||
|
items={items}
|
||||||
|
columns={columns}
|
||||||
|
defaultIcon="tabler:check"
|
||||||
|
classes={{
|
||||||
|
container: `gap-y-4 md:gap-y-8`,
|
||||||
|
panel: 'max-w-none',
|
||||||
|
title: 'text-lg font-medium leading-6 dark:text-white ml-2 rtl:ml-0 rtl:mr-2',
|
||||||
|
description: 'text-muted dark:text-slate-400 ml-2 rtl:ml-0 rtl:mr-2',
|
||||||
|
icon: 'flex h-7 w-7 items-center justify-center rounded-full bg-green-600 dark:bg-green-700 text-gray-50 p-1',
|
||||||
|
action: 'text-lg font-medium leading-6 dark:text-white ml-2 rtl:ml-0 rtl:mr-2',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div aria-hidden="true" class="mt-10 md:mt-0 md:basis-1/2">
|
<div aria-hidden="true" class="mt-10 md:mt-0 md:basis-1/2">
|
||||||
{
|
{
|
||||||
|
@ -62,7 +62,8 @@ const {
|
|||||||
container: 'mt-12',
|
container: 'mt-12',
|
||||||
panel: 'max-w-full sm:max-w-md',
|
panel: 'max-w-full sm:max-w-md',
|
||||||
title: 'text-lg font-semibold',
|
title: 'text-lg font-semibold',
|
||||||
icon: 'flex-shrink-0 mt-0.5 text-primary w-6 h-6',
|
description: 'mt-0.5',
|
||||||
|
icon: 'flex-shrink-0 mt-1 text-primary w-6 h-6',
|
||||||
...((classes?.items as {}) ?? {}),
|
...((classes?.items as {}) ?? {}),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -52,18 +52,31 @@ const metadata = {
|
|||||||
|
|
||||||
<Content
|
<Content
|
||||||
id="about"
|
id="about"
|
||||||
|
columns={3}
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
title: 'Dribbble',
|
|
||||||
icon: 'tabler:brand-dribbble',
|
icon: 'tabler:brand-dribbble',
|
||||||
|
callToAction: {
|
||||||
|
targetBlank: true,
|
||||||
|
text: 'Dribbble',
|
||||||
|
href: '#',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Behance',
|
|
||||||
icon: 'tabler:brand-behance',
|
icon: 'tabler:brand-behance',
|
||||||
|
callToAction: {
|
||||||
|
targetBlank: true,
|
||||||
|
text: 'Behance',
|
||||||
|
href: '#',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Pinterest',
|
|
||||||
icon: 'tabler:brand-pinterest',
|
icon: 'tabler:brand-pinterest',
|
||||||
|
callToAction: {
|
||||||
|
targetBlank: true,
|
||||||
|
text: 'Pinterest',
|
||||||
|
href: '#',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
image={{
|
image={{
|
||||||
@ -201,6 +214,12 @@ const metadata = {
|
|||||||
src: 'https://images.unsplash.com/photo-1658248165252-71e116af1b34?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=928&q=80',
|
src: 'https://images.unsplash.com/photo-1658248165252-71e116af1b34?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=928&q=80',
|
||||||
alt: 'Tech Design Image',
|
alt: 'Tech Design Image',
|
||||||
}}
|
}}
|
||||||
|
callToAction={{
|
||||||
|
targetBlank: true,
|
||||||
|
text: 'Go to the project',
|
||||||
|
icon: 'tabler:chevron-right',
|
||||||
|
href: '#',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Fragment slot="content">
|
<Fragment slot="content">
|
||||||
<h3 class="text-2xl font-bold tracking-tight dark:text-white sm:text-3xl mb-2">
|
<h3 class="text-2xl font-bold tracking-tight dark:text-white sm:text-3xl mb-2">
|
||||||
@ -233,6 +252,12 @@ const metadata = {
|
|||||||
src: 'https://images.unsplash.com/photo-1619983081563-430f63602796?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80',
|
src: 'https://images.unsplash.com/photo-1619983081563-430f63602796?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=774&q=80',
|
||||||
alt: 'Art and Music Poster Image',
|
alt: 'Art and Music Poster Image',
|
||||||
}}
|
}}
|
||||||
|
callToAction={{
|
||||||
|
targetBlank: true,
|
||||||
|
text: 'Go to the project',
|
||||||
|
icon: 'tabler:chevron-right',
|
||||||
|
href: '#',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Fragment slot="content">
|
<Fragment slot="content">
|
||||||
<h3 class="text-2xl font-bold tracking-tight dark:text-white sm:text-3xl mb-2">
|
<h3 class="text-2xl font-bold tracking-tight dark:text-white sm:text-3xl mb-2">
|
||||||
@ -264,6 +289,12 @@ const metadata = {
|
|||||||
src: 'https://plus.unsplash.com/premium_photo-1683288295841-782fa47e4770?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
|
src: 'https://plus.unsplash.com/premium_photo-1683288295841-782fa47e4770?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=870&q=80',
|
||||||
alt: 'Fashion e-commerce Image',
|
alt: 'Fashion e-commerce Image',
|
||||||
}}
|
}}
|
||||||
|
callToAction={{
|
||||||
|
targetBlank: true,
|
||||||
|
text: 'Go to the project',
|
||||||
|
icon: 'tabler:chevron-right',
|
||||||
|
href: '#',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Fragment slot="content">
|
<Fragment slot="content">
|
||||||
<h3 class="text-2xl font-bold tracking-tight dark:text-white sm:text-3xl mb-2">
|
<h3 class="text-2xl font-bold tracking-tight dark:text-white sm:text-3xl mb-2">
|
||||||
|
@ -9,6 +9,7 @@ import Features from '~/components/widgets/Features.astro';
|
|||||||
import Stats from '~/components/widgets/Stats.astro';
|
import Stats from '~/components/widgets/Stats.astro';
|
||||||
import Features3 from '~/components/widgets/Features3.astro';
|
import Features3 from '~/components/widgets/Features3.astro';
|
||||||
import FAQs from '~/components/widgets/FAQs.astro';
|
import FAQs from '~/components/widgets/FAQs.astro';
|
||||||
|
import Brands from '~/components/widgets/Brands.astro';
|
||||||
|
|
||||||
const metadata = {
|
const metadata = {
|
||||||
title: 'Startup Landing Page',
|
title: 'Startup Landing Page',
|
||||||
@ -64,7 +65,8 @@ const metadata = {
|
|||||||
<!-- Stats Widget ****************** -->
|
<!-- Stats Widget ****************** -->
|
||||||
|
|
||||||
<Stats
|
<Stats
|
||||||
title="Our impressive statistics"
|
title="Discover the impressive impact of Astrowind"
|
||||||
|
subtitle="The numbers below reflect the trust our users have placed in us and the remarkable outcomes we've helped them achieve."
|
||||||
stats={[
|
stats={[
|
||||||
{ title: 'Downloads', amount: '182K' },
|
{ title: 'Downloads', amount: '182K' },
|
||||||
{ title: 'Websites Launched', amount: '87' },
|
{ title: 'Websites Launched', amount: '87' },
|
||||||
@ -73,6 +75,53 @@ const metadata = {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- Brands Widget ****************** -->
|
||||||
|
|
||||||
|
<Brands
|
||||||
|
title="Partnerships & Collaborations"
|
||||||
|
subtitle="At Astrowind, we believe in the power of collaboration to drive innovation and create exceptional experiences."
|
||||||
|
icons={[]}
|
||||||
|
images={[
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2015/05/26/09/37/paypal-784404_1280.png',
|
||||||
|
alt: 'Paypal',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2021/12/06/13/48/visa-6850402_1280.png',
|
||||||
|
alt: 'Visa',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2013/10/01/10/29/ebay-189064_1280.png',
|
||||||
|
alt: 'Ebay',
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2015/04/13/17/45/icon-720944_1280.png',
|
||||||
|
alt: 'Youtube',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2013/02/12/09/07/microsoft-80658_1280.png',
|
||||||
|
alt: 'Microsoft',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2015/04/23/17/41/node-js-736399_1280.png',
|
||||||
|
alt: 'Node JS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2015/10/31/12/54/google-1015751_1280.png',
|
||||||
|
alt: 'Google',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2021/12/06/13/45/meta-6850393_1280.png',
|
||||||
|
alt: 'Meta',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: 'https://cdn.pixabay.com/photo/2013/01/29/22/53/yahoo-76684_1280.png',
|
||||||
|
alt: 'Yahoo',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Features2 Widget ************** -->
|
<!-- Features2 Widget ************** -->
|
||||||
|
|
||||||
<Features2
|
<Features2
|
||||||
|
3
src/types.d.ts
vendored
3
src/types.d.ts
vendored
@ -229,7 +229,7 @@ export interface Testimonials extends Headline, Widget {
|
|||||||
callToAction?: CallToAction;
|
callToAction?: CallToAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Clients extends Headline, Widget {
|
export interface Brands extends Headline, Widget {
|
||||||
icons?: Array<string>;
|
icons?: Array<string>;
|
||||||
images?: Array<Image>;
|
images?: Array<Image>;
|
||||||
}
|
}
|
||||||
@ -273,6 +273,7 @@ export interface Content extends Headline, Widget {
|
|||||||
columns?: number;
|
columns?: number;
|
||||||
isReversed?: boolean;
|
isReversed?: boolean;
|
||||||
isAfterContent?: boolean;
|
isAfterContent?: boolean;
|
||||||
|
callToAction?: CallToAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Contact extends Headline, Form, Widget {}
|
export interface Contact extends Headline, Form, Widget {}
|
||||||
|
Reference in New Issue
Block a user