Skip to content

Commit 22d826a

Browse files
committed
✨ Add ProductPage template
1 parent 0793385 commit 22d826a

24 files changed

+795
-9
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,7 @@ import { Accordion } from 'webcoreui/react'
292292
- [SocialProof](https://github.com/Frontendland/webcoreui/tree/main/src/blocks/SocialProof)
293293
- [Tiles](https://github.com/Frontendland/webcoreui/tree/main/src/blocks/Tiles)
294294
- [User](https://github.com/Frontendland/webcoreui/tree/main/src/blocks/User)
295+
296+
## Templates
297+
298+
- [ProductPage](https://github.com/Frontendland/webcoreui/tree/main/src/templates/ProductPage)

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export default [
9696
allowExpressions: true
9797
}],
9898
'react/jsx-tag-spacing': ['error'],
99-
'react/no-unused-prop-types': 'error',
99+
'react/prop-types': 'off',
100100
'radix': 'error',
101101
'semi': ['error', 'never'],
102102
'simple-import-sort/imports': ['error', {

src/blocks/Button/Button.astro

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
import { classNames } from 'webcoreui'
3+
import {
4+
Badge,
5+
Button as WebcoreButton,
6+
Icon,
7+
type IconProps
8+
} from 'webcoreui/astro'
9+
10+
import type { ButtonProps } from './button'
11+
import styles from './button.module.scss'
12+
13+
interface Props extends ButtonProps {}
14+
15+
const {
16+
icon,
17+
text,
18+
badge,
19+
className,
20+
...rest
21+
} = Astro.props
22+
23+
const Component = badge ? Badge : WebcoreButton
24+
---
25+
26+
<Component {...rest} className={classNames([styles.button, className])}>
27+
{icon && (
28+
<Fragment>
29+
{icon.startsWith('<svg')
30+
? <Fragment set:html={icon} />
31+
: <Icon type={icon as IconProps['type']} />
32+
}
33+
</Fragment>
34+
)}
35+
{text}
36+
</Component>

src/blocks/Button/Button.svelte

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script lang="ts">
2+
import { classNames } from 'webcoreui'
3+
import {
4+
Badge,
5+
Button as WebcoreButton
6+
} from 'webcoreui/svelte'
7+
8+
import type { ButtonProps } from './button'
9+
import styles from './button.module.scss'
10+
11+
const {
12+
icon,
13+
text,
14+
badge,
15+
className,
16+
...rest
17+
}: ButtonProps = $props()
18+
19+
const SvelteComponent = $derived(badge ? Badge : WebcoreButton)
20+
</script>
21+
22+
<SvelteComponent
23+
{...rest}
24+
className={classNames([styles.button, className])}
25+
>
26+
{#if icon}
27+
{@html icon}
28+
{/if}
29+
{text}
30+
</SvelteComponent>

src/blocks/Button/Button.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react'
2+
import { classNames } from 'webcoreui'
3+
import {
4+
Badge,
5+
Button as WebcoreButton
6+
} from 'webcoreui/react'
7+
8+
import type { ReactButtonProps } from './button'
9+
import styles from './button.module.scss'
10+
11+
const Button = ({
12+
icon,
13+
text,
14+
badge,
15+
className,
16+
...rest
17+
}: ReactButtonProps) => {
18+
const Component = badge ? Badge : WebcoreButton
19+
20+
return (
21+
<Component
22+
{...rest}
23+
className={classNames([styles.button, className])}
24+
dangerouslySetInnerHTML={{ __html: icon
25+
? `${icon} ${text}`
26+
: text
27+
}}
28+
/>
29+
)
30+
}
31+
32+
export default Button

src/blocks/Button/button.module.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@use 'webcoreui/config' as *;
2+
3+
.button svg {
4+
@include size(18px);
5+
}

src/blocks/Button/button.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type {
2+
BadgeProps,
3+
ButtonProps as WebcoreButtonProps,
4+
IconProps
5+
} from 'webcoreui/astro'
6+
7+
export type ButtonProps = {
8+
icon?: IconProps['type'] | string
9+
text?: string
10+
badge?: boolean
11+
className?: string
12+
} & WebcoreButtonProps & BadgeProps
13+
14+
export type ReactButtonProps = {
15+
children?: React.ReactNode
16+
} & ButtonProps

src/blocks/Layout/Layout.astro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const {
1212
seo,
1313
menu,
1414
footer,
15+
className,
1516
...rest
1617
} = Astro.props
1718
@@ -40,7 +41,7 @@ const containerClasses = [
4041
<main class:list={containerClasses}>
4142
<slot name="left-sidebar" />
4243
<ConditionalWrapper condition={hasSidebar}>
43-
<div slot="wrapper">children</div>
44+
<div slot="wrapper" class:list={className}>children</div>
4445
<slot />
4546
</ConditionalWrapper>
4647
<slot name="right-sidebar" />

src/blocks/Layout/Layout.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
seo,
1212
menu,
1313
footer,
14+
className,
1415
insideMenu,
1516
atf,
1617
leftSidebar,
@@ -43,7 +44,7 @@
4344
{@render atf?.()}
4445
<main class={containerClasses}>
4546
{@render leftSidebar?.()}
46-
<ConditionalWrapper condition={!!hasSidebar}>
47+
<ConditionalWrapper condition={!!hasSidebar} class={className}>
4748
{@render children?.()}
4849
</ConditionalWrapper>
4950
{@render rightSidebar?.()}

src/blocks/Layout/Layout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const Layout = ({
1111
seo,
1212
menu,
1313
footer,
14+
className,
1415
insideMenu,
1516
atf,
1617
leftSidebar,
@@ -44,7 +45,7 @@ const Layout = ({
4445
{leftSidebar}
4546
<ConditionalWrapper
4647
condition={!!hasSidebar}
47-
wrapper={children => <div>{children}</div>}
48+
wrapper={children => <div className={className}>{children}</div>}
4849
>
4950
{children}
5051
</ConditionalWrapper>

src/blocks/Layout/layout.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type LayoutProps = {
77
seo: SEOProps
88
menu?: MenuProps
99
footer?: FooterProps
10+
className?: string
1011
[key: string]: any
1112
}
1213

src/data.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import SvelteBox from '@static/Box.svelte'
99
import ReactAlert from '@components/Alert/Alert.tsx'
1010
import ReactBox from '@static/Box.tsx'
1111

12+
import logo from '../public/img/logo.svg?raw'
1213
import alertIcon from './icons/alert.svg?raw'
1314
import successIcon from './icons/circle-check.svg?raw'
1415
import componentsIcon from './icons/components.svg?raw'
@@ -18,6 +19,8 @@ import homeIcon from './icons/home.svg?raw'
1819
import infoIcon from './icons/info.svg?raw'
1920
import moonIcon from './icons/moon.svg?raw'
2021

22+
import type { PaginationProps } from 'webcoreui/astro'
23+
2124
export const accordionItems = [{
2225
title: 'Do you offer support?',
2326
content: 'We provide 30 days of support.'
@@ -447,3 +450,77 @@ export const bottomNavigationItems = [
447450
name: 'GitHub'
448451
}
449452
]
453+
454+
export const getProductPageTemplateData = (theme = 'success') => ({
455+
layout: {
456+
seo: {
457+
title: 'Product Page Template - Webcore',
458+
url: 'https://webcoreui.dev/',
459+
description: 'A customizable and easy to use template for products.',
460+
faviconUrl: '/logo.svg'
461+
},
462+
menu: {
463+
logo: {
464+
html: logo
465+
}
466+
},
467+
footer: {
468+
logo: {
469+
html: logo
470+
},
471+
columns: [
472+
{
473+
title: 'Sitemap',
474+
items: [
475+
{ href: '/', name: 'Home' }
476+
]
477+
}
478+
],
479+
subText: ${new Date().getFullYear()} Webcore. All Rights Reserved.`
480+
}
481+
},
482+
images: Array
483+
.from({ length: 4 }, (_, i) => i + 1)
484+
.map(i => ({
485+
src: `/img/placeholder${i}.png`,
486+
alt: 'img',
487+
width: 500,
488+
height: 250
489+
})),
490+
carousel: {
491+
pagination: {
492+
type: 'dots' as PaginationProps['type']
493+
}
494+
},
495+
recommended: {
496+
items: Array
497+
.from({ length: 3 }, (_, i) => i + 5)
498+
.map(i => ({
499+
href: '#',
500+
img: {
501+
src: `/img/placeholder${i}.png`,
502+
alt: 'img',
503+
width: 500,
504+
height: 250
505+
},
506+
title: `Recommended Card #${i - 4}`,
507+
text: 'You can also pass <b>HTML</b> tags to your recommended cards.'
508+
}))
509+
},
510+
buttons: [
511+
{ text: 'Get Started ->', theme: theme as ButtonProps['theme'] },
512+
{ text: 'Demo', theme: 'secondary' as ButtonProps['theme'] }
513+
],
514+
features: [
515+
'Easily configure your menu and footer',
516+
'Add carousel for preview images',
517+
'Define your main content the way you want',
518+
'Customize your call to actions',
519+
'List features',
520+
'Add recommendations'
521+
].map(feature => ({
522+
icon: successIcon,
523+
color: `var(--w-color-${theme})`,
524+
text: feature
525+
}))
526+
})

src/pages/index.astro

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,9 @@ import {
386386
@include size('w100%');
387387
}
388388

389-
.menu-example {
390-
z-index: 0;
389+
.menu-example,
390+
.bottom-navigation-example {
391+
@include layer(default);
391392
}
392393

393394
.switcher {

src/pages/templates/index.astro

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
import Layout from '@static/Layout.astro'
3+
4+
import BlogCard from '@blocks/BlogCard/BlogCard.astro'
5+
6+
const templates = [
7+
{ name: 'Product Page', url: 'product-page' }
8+
]
9+
---
10+
11+
<Layout>
12+
<h1 class="reset">Templates</h1>
13+
14+
<div class="grid md-2 lg-3">
15+
{templates.map(template => (
16+
<Fragment>
17+
{['Astro', 'Svelte', 'React'].map((framework, index) => (
18+
<BlogCard
19+
href={`templates/${template.url}/${framework.toLowerCase()}`}
20+
title={`${framework} ${template.name}`}
21+
img={{
22+
src: `/img/placeholder${index + 1}.png`,
23+
alt: framework,
24+
width: 200,
25+
height: 200
26+
}}
27+
/>
28+
))}
29+
</Fragment>
30+
))}
31+
</div>
32+
</Layout>

0 commit comments

Comments
 (0)