From acf1121d0a7e2c8ca694807c3bf205e1af8169d0 Mon Sep 17 00:00:00 2001 From: Frontendland Date: Mon, 30 Sep 2024 13:18:53 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20Footer=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + src/components/Footer/Footer.astro | 91 ++++++++++++++ src/components/Footer/Footer.svelte | 94 ++++++++++++++ src/components/Footer/Footer.tsx | 107 ++++++++++++++++ src/components/Footer/footer.module.scss | 61 +++++++++ src/components/Footer/footer.ts | 27 ++++ src/data.js | 32 +++++ src/pages/footer.astro | 150 +++++++++++++++++++++++ src/pages/index.astro | 4 + src/static/ComponentWrapper.astro | 2 + src/static/Layout.astro | 45 ++++++- 11 files changed, 610 insertions(+), 4 deletions(-) create mode 100644 src/components/Footer/Footer.astro create mode 100644 src/components/Footer/Footer.svelte create mode 100644 src/components/Footer/Footer.tsx create mode 100644 src/components/Footer/footer.module.scss create mode 100644 src/components/Footer/footer.ts create mode 100644 src/pages/footer.astro diff --git a/README.md b/README.md index 005f1d7..55d75c8 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,7 @@ import { Accordion } from 'webcoreui/react' - [Collapsible](https://github.com/Frontendland/webcoreui/tree/main/src/components/Collapsible) - [ConditionalWrapper](https://github.com/Frontendland/webcoreui/tree/main/src/components/ConditionalWrapper) - [DataTable](https://github.com/Frontendland/webcoreui/tree/main/src/components/DataTable) +- [Footer](https://github.com/Frontendland/webcoreui/tree/main/src/components/Footer) - [Group](https://github.com/Frontendland/webcoreui/tree/main/src/components/Group) - [Icon](https://github.com/Frontendland/webcoreui/tree/main/src/components/Icon) - [Input](https://github.com/Frontendland/webcoreui/tree/main/src/components/Input) diff --git a/src/components/Footer/Footer.astro b/src/components/Footer/Footer.astro new file mode 100644 index 0000000..ae88a9c --- /dev/null +++ b/src/components/Footer/Footer.astro @@ -0,0 +1,91 @@ +--- +import type { FooterProps } from './footer' + +import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.astro' + +import styles from './footer.module.scss' + +interface Props extends FooterProps {} + +const { + logo, + columns, + subText, + className, + wrapperClassName, + subTextClassName +} = Astro.props + +const classes = [ + styles.footer, + className +] + +const containerClasses = [ + styles.container, + wrapperClassName +] + +const subTextClasses = [ + styles.subtext, + subTextClassName +] +--- + + diff --git a/src/components/Footer/Footer.svelte b/src/components/Footer/Footer.svelte new file mode 100644 index 0000000..ff58640 --- /dev/null +++ b/src/components/Footer/Footer.svelte @@ -0,0 +1,94 @@ + + + diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx new file mode 100644 index 0000000..aac13ea --- /dev/null +++ b/src/components/Footer/Footer.tsx @@ -0,0 +1,107 @@ +import React from 'react' +import type { ReactFooterProps } from './footer' + +import ConditionalWrapper from '../ConditionalWrapper/ConditionalWrapper.tsx' + +import { classNames } from '../../utils/classNames' + +import styles from './footer.module.scss' + +const Footer = ({ + logo, + columns, + subText, + className, + wrapperClassName, + subTextClassName, + children +}: ReactFooterProps) => { + const classes = classNames([ + styles.footer, + className + ]) + + const containerClasses = classNames([ + styles.container, + wrapperClassName + ]) + + const subTextClasses = classNames([ + styles.subtext, + subTextClassName + ]) + + return ( + + ) +} + +export default Footer + diff --git a/src/components/Footer/footer.module.scss b/src/components/Footer/footer.module.scss new file mode 100644 index 0000000..c752615 --- /dev/null +++ b/src/components/Footer/footer.module.scss @@ -0,0 +1,61 @@ +@import '../../scss/config.scss'; + +.footer { + @include border(top, primary-50); + + .column-title { + @include spacing(mb-default); + + display: block; + } + + .column { + @include spacing(0); + + list-style-type: none; + + a { + @include typography(primary-10, none); + + &:hover, + &.active { + @include typography(primary, underline); + } + } + } +} + +.container { + @include spacing(auto-default, px-default); + + max-width: 1200px; +} + +.wrapper { + @include layout(flex, column, default, h-between); +} + +.columns { + @include layout(flex, column, default); +} + +.subtext { + @include border(top, primary-60); + @include spacing(mt-default, py-default); + @include layout(flex, column, default, h-between); + + span { + @include typography(md, primary-20); + } +} + +@include media('sm') { + .wrapper, + .subtext { + @include layout(row, none); + } + + .columns { + @include layout(row, '5xl'); + } +} diff --git a/src/components/Footer/footer.ts b/src/components/Footer/footer.ts new file mode 100644 index 0000000..3eb31fe --- /dev/null +++ b/src/components/Footer/footer.ts @@ -0,0 +1,27 @@ +export type FooterProps = { + logo?: { + url?: string + alt?: string + width?: number + height?: number + eager?: boolean + html?: string + } | null + columns?: { + title?: string + items: { + href: string + name: string + target?: '_self' | '_blank' | '_parent' | '_top' | '_unfencedTop' + active?: boolean + }[] + }[] + subText?: string + className?: string + wrapperClassName?: string + subTextClassName?: string +} + +export type ReactFooterProps = { + children?: React.ReactNode +} & FooterProps diff --git a/src/data.js b/src/data.js index d74017e..9aa8d08 100644 --- a/src/data.js +++ b/src/data.js @@ -262,3 +262,35 @@ export const breadcrumbsWithIconsOnly = [ { icon: fileIcon, href: '/docs' }, { icon: componentsIcon, href: '/docs/components' } ] + +export const footerColumn1 = [{ + items: [ + { name: 'Home', href: '#' }, + { name: 'Docs', href: '#' }, + { name: 'Component', href: '#' } + ] +}] + +export const footerColumn2 = [{ + items: [ + { name: 'CSS Config', href: '#' }, + { name: 'Styles', href: '#' }, + { name: 'Utilities', href: '#' } + ] +}] + +export const footerColumns = [ + { items: footerColumn1[0].items }, + { items: footerColumn2[0].items } +] + +export const footerColumnsWithTitle = [ + { + title: 'SITEMAP', + items: footerColumn1[0].items + }, + { + title: 'THEMES', + items: footerColumn2[0].items + } +] diff --git a/src/pages/footer.astro b/src/pages/footer.astro new file mode 100644 index 0000000..1456602 --- /dev/null +++ b/src/pages/footer.astro @@ -0,0 +1,150 @@ +--- +import ComponentWrapper from '@static/ComponentWrapper.astro' +import Layout from '@static/Layout.astro' + +import AstroFooter from '@components/Footer/Footer.astro' +import SvelteFooter from '@components/Footer/Footer.svelte' +import ReactFooter from '@components/Footer/Footer.tsx' +import Icon from '@components/Icon/Icon.astro' + +import logo from '../../public/img/logo.svg?raw' + +import { getSections } from '@helpers' +import { + footerColumn1, + footerColumns, + footerColumnsWithTitle, + menuLogo +} from '@data' + +const sections = getSections({ + title: 'footers', + components: [AstroFooter, SvelteFooter, ReactFooter] +}) + +const subText = `© ${new Date().getFullYear()} Webcore. All Rights Reserved.` +--- + + +

Footer

+
+ + + Built by Webcore with ❤️ + + + + + + Built by Webcore with ❤️ + + + + + + Built by Webcore with ❤️ + + +
+ + {sections.map(section => ( +

{section.title}

+ + {section.subTitle &&

} + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+
+ ))} + diff --git a/src/pages/index.astro b/src/pages/index.astro index e6ebc91..429543a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -14,6 +14,7 @@ import Carousel from '@components/Carousel/Carousel.astro' import Checkbox from '@components/Checkbox/Checkbox.astro' import Collapsible from '@components/Collapsible/Collapsible.astro' import DataTable from '@components/DataTable/DataTable.astro' +import Footer from '@components/Footer/Footer.astro' import Group from '@components/Group/Group.astro' import Icon from '@components/Icon/Icon.astro' import Input from '@components/Input/Input.astro' @@ -144,6 +145,9 @@ const tabItems = [{ data={[['1', 'John Doe']]} /> + +