From e0d7da8f40d623d031d806099c0f53911184c683 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Thu, 14 Aug 2025 09:31:18 +0200 Subject: [PATCH 01/10] WIP add tabs --- src/App.tsx | 61 +++++++++++++++--- src/components/common/organisms/Tabs/Tabs.tsx | 62 +++++++++++++++++++ src/components/common/organisms/Tabs/index.ts | 3 + .../common/organisms/Tabs/styled.ts | 45 ++++++++++++++ src/components/common/styled.ts | 14 +++++ src/core/theme.ts | 2 +- src/index.css | 1 + 7 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 src/components/common/organisms/Tabs/Tabs.tsx create mode 100644 src/components/common/organisms/Tabs/index.ts create mode 100644 src/components/common/organisms/Tabs/styled.ts create mode 100644 src/components/common/styled.ts diff --git a/src/App.tsx b/src/App.tsx index c3b203f..02c991d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,61 @@ -import { Typography } from './core/typography' +import Tabs from './components/common/organisms/Tabs' +import { Main } from './components/common/styled' +import { Typography as T } from './core/typography' function App() { return ( <> - - Welcome to React Vite Template - - - This is a simple template to get you started with React and Vite. - +
+ + Welcome to React Vite Template + + + This is a simple template to get you started with React and Vite. + +
+ +
+ + Overview content goes here. Describe the template, goals, etc. + + ), + }, + { + key: 'components', + label: 'Components', + content: ( + + Components content goes here. Buttons, badges, modals… + + ), + }, + { + key: 'hooks', + label: 'Hooks', + content: ( + + Hooks content goes here. useToggle, useLocalStorage, + useCounter… + + ), + }, + ]} + /> +
) } diff --git a/src/components/common/organisms/Tabs/Tabs.tsx b/src/components/common/organisms/Tabs/Tabs.tsx new file mode 100644 index 0000000..a171759 --- /dev/null +++ b/src/components/common/organisms/Tabs/Tabs.tsx @@ -0,0 +1,62 @@ +import { useEffect, useMemo, useState } from 'react' +import * as S from './styled' + +type TabItem = { key: string; label: string; content: React.ReactNode } +type Props = { items: TabItem[]; defaultKey?: string } + +export default function Tabs({ items, defaultKey }: Props) { + const keys = useMemo(() => items.map((i) => i.key), [items]) + const [active, setActive] = useState(defaultKey ?? keys[0]) + + useEffect(() => { + if (!keys.includes(active)) setActive(keys[0]) + }, [keys, active]) + + const onKeyDown = (e: React.KeyboardEvent) => { + const i = keys.indexOf(active) + if (e.key === 'ArrowRight') setActive(keys[(i + 1) % keys.length]) + if (e.key === 'ArrowLeft') + setActive(keys[(i - 1 + keys.length) % keys.length]) + if (e.key === 'Home') setActive(keys[0]) + if (e.key === 'End') setActive(keys[keys.length - 1]) + } + + return ( + <> + + {items.map((t) => { + const isActive = t.key === active + return ( + setActive(t.key)} + > + {t.label} + + ) + })} + + + {items.map((t) => { + const isActive = t.key === active + return ( + + ) + })} + + ) +} diff --git a/src/components/common/organisms/Tabs/index.ts b/src/components/common/organisms/Tabs/index.ts new file mode 100644 index 0000000..d094ea3 --- /dev/null +++ b/src/components/common/organisms/Tabs/index.ts @@ -0,0 +1,3 @@ +import Tabs from './Tabs' + +export default Tabs diff --git a/src/components/common/organisms/Tabs/styled.ts b/src/components/common/organisms/Tabs/styled.ts new file mode 100644 index 0000000..9f9ba47 --- /dev/null +++ b/src/components/common/organisms/Tabs/styled.ts @@ -0,0 +1,45 @@ +import styled from '@emotion/styled' +import tokens from '../../../../core/tokens' + +const DIVIDER_W = `${tokens.size.BASELINE / 8}px` // ~1px +const INDICATOR_H = '2px' + +export const Bar = styled.nav` + display: flex; + align-items: flex-end; /* tabs sit on the divider */ + gap: ${tokens.gap.LARGE}px; + margin: ${tokens.spacing.BASELINE * 2}px 0 ${tokens.spacing.BASELINE}px; + border-bottom: ${DIVIDER_W} solid ${({ theme }) => theme.colors.scrollBar}; +` + +export const TabBtn = styled.button<{ active: boolean }>` + position: relative; + background: transparent; + border: none; + cursor: pointer; + color: ${(p) => + p.active ? p.theme.colors.primary : p.theme.colors.text.primary}; + font-size: ${tokens.text.fontSize.BASELINE}px; + font-weight: ${({ active }) => + active ? tokens.text.fontWeight.semiBold : tokens.text.fontWeight.normal}; + + padding: ${tokens.spacing.BASELINE}px ${tokens.spacing.BASELINE * 2}px; + padding-bottom: ${tokens.spacing.BASELINE * 1.5}px; + + &::after { + content: ''; + position: absolute; + left: 0; + right: 0; + bottom: calc(-1 * ${DIVIDER_W}); + height: ${INDICATOR_H}; + background: ${({ theme }) => theme.colors.primary}; + transform: ${({ active }) => (active ? 'scaleX(1)' : 'scaleX(0)')}; + transform-origin: left; + transition: transform 160ms ease; + } +` + +export const Panel = styled.section` + padding-top: ${tokens.spacing.BASELINE * 2}px; +` diff --git a/src/components/common/styled.ts b/src/components/common/styled.ts new file mode 100644 index 0000000..d02fab4 --- /dev/null +++ b/src/components/common/styled.ts @@ -0,0 +1,14 @@ +import styled from '@emotion/styled' +import tokens from '../../core/tokens' + +export const Main = styled.nav` + padding: ${tokens.padding.BASELINE * 2}px; +` + +export const DividerBar = styled.hr` + width: 100%; + margin: 0; + border: 0; + border-top: ${tokens.size.BASELINE / 8}px solid + ${({ theme }) => theme.colors.scrollBar}; +` diff --git a/src/core/theme.ts b/src/core/theme.ts index 9147816..553d7eb 100644 --- a/src/core/theme.ts +++ b/src/core/theme.ts @@ -13,7 +13,7 @@ const brandColors = { } const background = { - primaryGrey: '#f4f4f4', + primaryGrey: '#EFEFE9', secondaryGrey: '#F5F5F5', tertiaryGrey: '#CCCCCC', } diff --git a/src/index.css b/src/index.css index 8b89f1d..7d028ba 100644 --- a/src/index.css +++ b/src/index.css @@ -26,4 +26,5 @@ select { body { margin: 0; + padding: 0; } From a8549493decd1be2451241246f387c3df34571de Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Thu, 14 Aug 2025 10:44:07 +0200 Subject: [PATCH 02/10] Refactor App.tsx --- src/App.tsx | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 02c991d..cd46ba2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,22 +5,12 @@ import { Typography as T } from './core/typography' function App() { return ( <> -
- - Welcome to React Vite Template - - - This is a simple template to get you started with React and Vite. - -
+ + Welcome to React Vite Template + + + This is a simple template to get you started with React and Vite. +
Date: Thu, 14 Aug 2025 11:40:36 +0200 Subject: [PATCH 03/10] Move intro text (header) and tabs to LibraryPage and wire routing --- src/App.tsx | 58 +++---------------- src/components/common/organisms/Tabs/Tabs.tsx | 7 ++- src/components/common/organisms/Tabs/index.ts | 5 +- src/main.tsx | 14 +++-- src/pages/LiberyPage/index.tsx | 22 +++++++ src/pages/LiberyPage/tabs.config.tsx | 11 ++++ .../LiberyPage/tabs/Components/index.tsx | 5 ++ .../Components/previews/ButtonPreview.tsx | 0 src/pages/LiberyPage/tabs/Hooks/index.tsx | 9 +++ .../LiberyPage/tabs/Overview/IntroCard.tsx | 0 src/pages/LiberyPage/tabs/Overview/index.tsx | 9 +++ 11 files changed, 81 insertions(+), 59 deletions(-) create mode 100644 src/pages/LiberyPage/index.tsx create mode 100644 src/pages/LiberyPage/tabs.config.tsx create mode 100644 src/pages/LiberyPage/tabs/Components/index.tsx create mode 100644 src/pages/LiberyPage/tabs/Components/previews/ButtonPreview.tsx create mode 100644 src/pages/LiberyPage/tabs/Hooks/index.tsx create mode 100644 src/pages/LiberyPage/tabs/Overview/IntroCard.tsx create mode 100644 src/pages/LiberyPage/tabs/Overview/index.tsx diff --git a/src/App.tsx b/src/App.tsx index cd46ba2..cfd773a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,53 +1,13 @@ -import Tabs from './components/common/organisms/Tabs' -import { Main } from './components/common/styled' -import { Typography as T } from './core/typography' +// src/App.tsx (optional) +import { BrowserRouter, Routes, Route } from 'react-router-dom' +import LibraryPage from './pages/LiberyPage' -function App() { +export default function App() { return ( - <> - - Welcome to React Vite Template - - - This is a simple template to get you started with React and Vite. - - -
- - Overview content goes here. Describe the template, goals, etc. - - ), - }, - { - key: 'components', - label: 'Components', - content: ( - - Components content goes here. Buttons, badges, modals… - - ), - }, - { - key: 'hooks', - label: 'Hooks', - content: ( - - Hooks content goes here. useToggle, useLocalStorage, - useCounter… - - ), - }, - ]} - /> -
- + + + } /> + + ) } - -export default App diff --git a/src/components/common/organisms/Tabs/Tabs.tsx b/src/components/common/organisms/Tabs/Tabs.tsx index a171759..2c78eb9 100644 --- a/src/components/common/organisms/Tabs/Tabs.tsx +++ b/src/components/common/organisms/Tabs/Tabs.tsx @@ -1,7 +1,12 @@ import { useEffect, useMemo, useState } from 'react' import * as S from './styled' -type TabItem = { key: string; label: string; content: React.ReactNode } +export type TabItem = { + key: string + label: string + content: React.ReactNode +} + type Props = { items: TabItem[]; defaultKey?: string } export default function Tabs({ items, defaultKey }: Props) { diff --git a/src/components/common/organisms/Tabs/index.ts b/src/components/common/organisms/Tabs/index.ts index d094ea3..7cb9e7e 100644 --- a/src/components/common/organisms/Tabs/index.ts +++ b/src/components/common/organisms/Tabs/index.ts @@ -1,3 +1,2 @@ -import Tabs from './Tabs' - -export default Tabs +export { default } from './Tabs' +export type { TabItem } from './Tabs' diff --git a/src/main.tsx b/src/main.tsx index 284468d..7924446 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,18 +1,20 @@ +// src/main.tsx import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.tsx' -import { BrowserRouter, Route, Routes } from 'react-router' +import { BrowserRouter, Routes, Route } from 'react-router-dom' import { ThemeProvider } from '@emotion/react' -import theme from './core/theme.ts' +import theme from './core/theme' +import './index.css' + +import LibraryPage from './pages/LiberyPage' createRoot(document.getElementById('root')!).render( - //TODO: Add more routes that takes you to different template pages - } /> + {/* One route that renders the whole page */} + } /> diff --git a/src/pages/LiberyPage/index.tsx b/src/pages/LiberyPage/index.tsx new file mode 100644 index 0000000..c5dbe43 --- /dev/null +++ b/src/pages/LiberyPage/index.tsx @@ -0,0 +1,22 @@ +// src/pages/LibraryPage/index.tsx +import { Typography as T } from '../../core/typography' +import Tabs from '../../components/common/organisms/Tabs' +import { Main } from '../../components/common/styled' +import { LIBRARY_TABS } from './tabs.config' + +export default function LibraryPage() { + return ( + <> + + Welcome to React Vite Template + + + This is a simple template to get you started with React and Vite. + + +
+ +
+ + ) +} diff --git a/src/pages/LiberyPage/tabs.config.tsx b/src/pages/LiberyPage/tabs.config.tsx new file mode 100644 index 0000000..21ebfb6 --- /dev/null +++ b/src/pages/LiberyPage/tabs.config.tsx @@ -0,0 +1,11 @@ +// src/pages/LibraryPage/tabs.config.tsx +import type { TabItem } from '../../components/common/organisms/Tabs' +import OverviewTab from './tabs/Overview' +import ComponentsTab from './tabs/Components' +import HooksTab from './tabs/Hooks' + +export const LIBRARY_TABS: TabItem[] = [ + { key: 'overview', label: 'Overview', content: }, + { key: 'components', label: 'Components', content: }, + { key: 'hooks', label: 'Hooks', content: }, +] diff --git a/src/pages/LiberyPage/tabs/Components/index.tsx b/src/pages/LiberyPage/tabs/Components/index.tsx new file mode 100644 index 0000000..a8c9f7c --- /dev/null +++ b/src/pages/LiberyPage/tabs/Components/index.tsx @@ -0,0 +1,5 @@ +import { Typography as T } from '../../../../core/typography' + +export default function ComponentsTab() { + return Components content… Buttons, badges, modals… +} diff --git a/src/pages/LiberyPage/tabs/Components/previews/ButtonPreview.tsx b/src/pages/LiberyPage/tabs/Components/previews/ButtonPreview.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/LiberyPage/tabs/Hooks/index.tsx b/src/pages/LiberyPage/tabs/Hooks/index.tsx new file mode 100644 index 0000000..2abd84c --- /dev/null +++ b/src/pages/LiberyPage/tabs/Hooks/index.tsx @@ -0,0 +1,9 @@ +import { Typography as T } from '../../../../core/typography' + +export default function HooksTab() { + return ( + + Hooks content… useToggle, useLocalStorage, useCounter… + + ) +} diff --git a/src/pages/LiberyPage/tabs/Overview/IntroCard.tsx b/src/pages/LiberyPage/tabs/Overview/IntroCard.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/LiberyPage/tabs/Overview/index.tsx b/src/pages/LiberyPage/tabs/Overview/index.tsx new file mode 100644 index 0000000..9f4e33c --- /dev/null +++ b/src/pages/LiberyPage/tabs/Overview/index.tsx @@ -0,0 +1,9 @@ +import { Typography as T } from '../../../../core/typography' + +export default function OverviewTab() { + return ( + + Overview content goes here. Describe the template, goals, etc. + + ) +} From 94b48c68a6d461c0b36ffd95940231d2d741bd27 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Thu, 14 Aug 2025 11:42:46 +0200 Subject: [PATCH 04/10] Refactor --- src/App.tsx | 1 - src/main.tsx | 3 --- src/pages/LiberyPage/index.tsx | 1 - src/pages/LiberyPage/tabs.config.tsx | 1 - 4 files changed, 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index cfd773a..22701ea 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,3 @@ -// src/App.tsx (optional) import { BrowserRouter, Routes, Route } from 'react-router-dom' import LibraryPage from './pages/LiberyPage' diff --git a/src/main.tsx b/src/main.tsx index 7924446..e8798a1 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,11 +1,9 @@ -// src/main.tsx import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import { BrowserRouter, Routes, Route } from 'react-router-dom' import { ThemeProvider } from '@emotion/react' import theme from './core/theme' import './index.css' - import LibraryPage from './pages/LiberyPage' createRoot(document.getElementById('root')!).render( @@ -13,7 +11,6 @@ createRoot(document.getElementById('root')!).render( - {/* One route that renders the whole page */} } /> diff --git a/src/pages/LiberyPage/index.tsx b/src/pages/LiberyPage/index.tsx index c5dbe43..ff82f86 100644 --- a/src/pages/LiberyPage/index.tsx +++ b/src/pages/LiberyPage/index.tsx @@ -1,4 +1,3 @@ -// src/pages/LibraryPage/index.tsx import { Typography as T } from '../../core/typography' import Tabs from '../../components/common/organisms/Tabs' import { Main } from '../../components/common/styled' diff --git a/src/pages/LiberyPage/tabs.config.tsx b/src/pages/LiberyPage/tabs.config.tsx index 21ebfb6..539bb11 100644 --- a/src/pages/LiberyPage/tabs.config.tsx +++ b/src/pages/LiberyPage/tabs.config.tsx @@ -1,4 +1,3 @@ -// src/pages/LibraryPage/tabs.config.tsx import type { TabItem } from '../../components/common/organisms/Tabs' import OverviewTab from './tabs/Overview' import ComponentsTab from './tabs/Components' From 892d7f21af5d580109efc216441d21a401ed2fd0 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Thu, 21 Aug 2025 14:35:11 +0200 Subject: [PATCH 05/10] add focus-visible and aria-hidden for accessibility --- src/App.tsx | 4 +++- src/components/common/organisms/Tabs/Tabs.tsx | 1 + src/components/common/organisms/Tabs/styled.ts | 2 +- src/components/common/styled.ts | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 22701ea..84bd389 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom' import LibraryPage from './pages/LiberyPage' -export default function App() { +function App() { return ( @@ -10,3 +10,5 @@ export default function App() { ) } + +export default App diff --git a/src/components/common/organisms/Tabs/Tabs.tsx b/src/components/common/organisms/Tabs/Tabs.tsx index 2c78eb9..2b973be 100644 --- a/src/components/common/organisms/Tabs/Tabs.tsx +++ b/src/components/common/organisms/Tabs/Tabs.tsx @@ -57,6 +57,7 @@ export default function Tabs({ items, defaultKey }: Props) { id={`${t.key}-panel`} aria-labelledby={`${t.key}-tab`} hidden={!isActive} + aria-hidden={!isActive} > {isActive && t.content} diff --git a/src/components/common/organisms/Tabs/styled.ts b/src/components/common/organisms/Tabs/styled.ts index 9f9ba47..0b50ff3 100644 --- a/src/components/common/organisms/Tabs/styled.ts +++ b/src/components/common/organisms/Tabs/styled.ts @@ -1,7 +1,7 @@ import styled from '@emotion/styled' import tokens from '../../../../core/tokens' -const DIVIDER_W = `${tokens.size.BASELINE / 8}px` // ~1px +const DIVIDER_W = `${tokens.size.BASELINE / 8}px` const INDICATOR_H = '2px' export const Bar = styled.nav` diff --git a/src/components/common/styled.ts b/src/components/common/styled.ts index d02fab4..55e0232 100644 --- a/src/components/common/styled.ts +++ b/src/components/common/styled.ts @@ -1,7 +1,7 @@ import styled from '@emotion/styled' import tokens from '../../core/tokens' -export const Main = styled.nav` +export const Main = styled.main` padding: ${tokens.padding.BASELINE * 2}px; ` From fc7166695d63443a6da5ac9c555893f33e4f5c9a Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Thu, 21 Aug 2025 14:53:22 +0200 Subject: [PATCH 06/10] git merge tab branch --- package-lock.json | 25 +++++++++++++++++++++---- package.json | 3 ++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3eec3ee..3d1413b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,8 @@ "fs": "^0.0.1-security", "react": "^19.1.0", "react-dom": "^19.1.0", - "react-router": "^7.7.1" + "react-router": "^7.7.1", + "react-router-dom": "^7.8.1" }, "devDependencies": { "@eslint/js": "^9.30.1", @@ -3529,9 +3530,9 @@ } }, "node_modules/react-router": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.7.1.tgz", - "integrity": "sha512-jVKHXoWRIsD/qS6lvGveckwb862EekvapdHJN/cGmzw40KnJH5gg53ujOJ4qX6EKIK9LSBfFed/xiQ5yeXNrUA==", + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.1.tgz", + "integrity": "sha512-5cy/M8DHcG51/KUIka1nfZ2QeylS4PJRs6TT8I4PF5axVsI5JUxp0hC0NZ/AEEj8Vw7xsEoD7L/6FY+zoYaOGA==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -3550,6 +3551,22 @@ } } }, + "node_modules/react-router-dom": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.1.tgz", + "integrity": "sha512-NkgBCF3sVgCiAWIlSt89GR2PLaksMpoo3HDCorpRfnCEfdtRPLiuTf+CNXvqZMI5SJLZCLpVCvcZrTdtGW64xQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.8.1" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", diff --git a/package.json b/package.json index a874ef1..3d08f46 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "fs": "^0.0.1-security", "react": "^19.1.0", "react-dom": "^19.1.0", - "react-router": "^7.7.1" + "react-router": "^7.7.1", + "react-router-dom": "^7.8.1" }, "devDependencies": { "@eslint/js": "^9.30.1", From b719d09bd08ad02bdac64003982366bb83366aee Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Thu, 21 Aug 2025 14:57:49 +0200 Subject: [PATCH 07/10] Add sectionCard Componet --- src/components/common/styled.ts | 4 ++++ .../templates/SectionCard/SectionCard.tsx | 23 +++++++++++++++++++ .../common/templates/SectionCard/index.ts | 3 +++ .../common/templates/SectionCard/styled.ts | 19 +++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 src/components/common/templates/SectionCard/SectionCard.tsx create mode 100644 src/components/common/templates/SectionCard/index.ts create mode 100644 src/components/common/templates/SectionCard/styled.ts diff --git a/src/components/common/styled.ts b/src/components/common/styled.ts index 55e0232..33df40d 100644 --- a/src/components/common/styled.ts +++ b/src/components/common/styled.ts @@ -12,3 +12,7 @@ export const DividerBar = styled.hr` border-top: ${tokens.size.BASELINE / 8}px solid ${({ theme }) => theme.colors.scrollBar}; ` + +export const BaseContainer = styled.div` + padding: ${tokens.padding.BASELINE * 2.5}px; +` diff --git a/src/components/common/templates/SectionCard/SectionCard.tsx b/src/components/common/templates/SectionCard/SectionCard.tsx new file mode 100644 index 0000000..74e2008 --- /dev/null +++ b/src/components/common/templates/SectionCard/SectionCard.tsx @@ -0,0 +1,23 @@ +import type { ReactNode } from 'react' +import * as S from './styled' +import { Typography as T } from '../../../../core/typography' +import { DividerBar } from '../../styled' + +type Props = { + title: string + children: ReactNode +} + +export default function SectionCard({ title, children }: Props) { + return ( + + + + {title} + + + + {children} + + ) +} diff --git a/src/components/common/templates/SectionCard/index.ts b/src/components/common/templates/SectionCard/index.ts new file mode 100644 index 0000000..321bbc7 --- /dev/null +++ b/src/components/common/templates/SectionCard/index.ts @@ -0,0 +1,3 @@ +import SectionCard from './SectionCard' + +export default SectionCard diff --git a/src/components/common/templates/SectionCard/styled.ts b/src/components/common/templates/SectionCard/styled.ts new file mode 100644 index 0000000..832a2ee --- /dev/null +++ b/src/components/common/templates/SectionCard/styled.ts @@ -0,0 +1,19 @@ +import styled from '@emotion/styled' +import { BaseContainer } from '../../styled' +import tokens from '../../../../core/tokens' + +export const Wrapper = styled.section` + background: ${({ theme }) => theme.colors.white}; + border-radius: ${tokens.borderRadius.BASELINE}px; + box-shadow: 0 1px 3px 0 ${({ theme }) => theme.colors.boxShadow}; + margin: ${tokens.margin.BASELINE * 2}px; +` + +export const Header = styled(BaseContainer)` + display: flex; + align-items: center; + justify-content: space-between; + gap: ${tokens.gap.LARGE}px; +` + +export const Body = styled(BaseContainer)`` From 197c961aa82f879f4495b1a2f2b510c768aed5e3 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Fri, 22 Aug 2025 09:59:31 +0200 Subject: [PATCH 08/10] Add content under Overview tab section. Add ListComponet. --- src/components/common/molecules/List/List.tsx | 22 +++++++++++++ src/components/common/molecules/List/index.ts | 3 ++ .../common/molecules/List/styled.ts | 16 ++++++++++ src/components/common/styled.ts | 9 ++++++ .../common/templates/SectionCard/styled.ts | 8 +++-- .../LiberyPage/tabs/Overview/IntroCard.tsx | 0 src/pages/LiberyPage/tabs/Overview/index.tsx | 17 ++++++++-- .../tabs/Overview/overview.config.ts | 32 +++++++++++++++++++ 8 files changed, 101 insertions(+), 6 deletions(-) delete mode 100644 src/pages/LiberyPage/tabs/Overview/IntroCard.tsx create mode 100644 src/pages/LiberyPage/tabs/Overview/overview.config.ts diff --git a/src/components/common/molecules/List/List.tsx b/src/components/common/molecules/List/List.tsx index e69de29..367790b 100644 --- a/src/components/common/molecules/List/List.tsx +++ b/src/components/common/molecules/List/List.tsx @@ -0,0 +1,22 @@ +import { Typography as T } from '../../../../core/typography' +import * as S from './styled' + +type ListProps = { + title: string + items: string[] +} + +export default function List({ title, items }: ListProps) { + return ( + + + {title} + + + {items.map((item) => ( + {item} + ))} + + + ) +} diff --git a/src/components/common/molecules/List/index.ts b/src/components/common/molecules/List/index.ts index e69de29..6cd88f9 100644 --- a/src/components/common/molecules/List/index.ts +++ b/src/components/common/molecules/List/index.ts @@ -0,0 +1,3 @@ +import List from './List' + +export default List diff --git a/src/components/common/molecules/List/styled.ts b/src/components/common/molecules/List/styled.ts index e69de29..c5a6958 100644 --- a/src/components/common/molecules/List/styled.ts +++ b/src/components/common/molecules/List/styled.ts @@ -0,0 +1,16 @@ +import styled from '@emotion/styled' +import tokens from '../../../../core/tokens' +import { FlexContainer } from '../../styled' + +export const ListWrapper = styled(FlexContainer)`` + +export const List = styled.ul` + margin: ${tokens.spacing.BASELINE}px 0; + padding-left: ${tokens.spacing.BASELINE * 2}px; + list-style-type: disc; +` + +export const ListItem = styled.li` + margin-bottom: ${tokens.spacing.BASELINE}px; + color: ${({ theme }) => theme.colors.text.primary}; +` diff --git a/src/components/common/styled.ts b/src/components/common/styled.ts index 33df40d..f832d8b 100644 --- a/src/components/common/styled.ts +++ b/src/components/common/styled.ts @@ -16,3 +16,12 @@ export const DividerBar = styled.hr` export const BaseContainer = styled.div` padding: ${tokens.padding.BASELINE * 2.5}px; ` +export const FlexContainer = styled.div` + display: flex; + flex-direction: column; + gap: ${tokens.gap.BASELINE}px; +` + +export const TabContainer = styled(FlexContainer)` + gap: ${tokens.gap.BASELINE * 2.5}px; +` diff --git a/src/components/common/templates/SectionCard/styled.ts b/src/components/common/templates/SectionCard/styled.ts index 832a2ee..968f384 100644 --- a/src/components/common/templates/SectionCard/styled.ts +++ b/src/components/common/templates/SectionCard/styled.ts @@ -1,12 +1,11 @@ import styled from '@emotion/styled' -import { BaseContainer } from '../../styled' +import { BaseContainer, FlexContainer } from '../../styled' import tokens from '../../../../core/tokens' export const Wrapper = styled.section` background: ${({ theme }) => theme.colors.white}; border-radius: ${tokens.borderRadius.BASELINE}px; box-shadow: 0 1px 3px 0 ${({ theme }) => theme.colors.boxShadow}; - margin: ${tokens.margin.BASELINE * 2}px; ` export const Header = styled(BaseContainer)` @@ -16,4 +15,7 @@ export const Header = styled(BaseContainer)` gap: ${tokens.gap.LARGE}px; ` -export const Body = styled(BaseContainer)`` +export const Body = styled(FlexContainer)` + gap: ${tokens.gap.LARGE}px; + padding: ${tokens.padding.BASELINE * 2.5}px; +` diff --git a/src/pages/LiberyPage/tabs/Overview/IntroCard.tsx b/src/pages/LiberyPage/tabs/Overview/IntroCard.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/pages/LiberyPage/tabs/Overview/index.tsx b/src/pages/LiberyPage/tabs/Overview/index.tsx index 9f4e33c..2d3c6e7 100644 --- a/src/pages/LiberyPage/tabs/Overview/index.tsx +++ b/src/pages/LiberyPage/tabs/Overview/index.tsx @@ -1,9 +1,20 @@ +import List from '../../../../components/common/molecules/List/List' +import { TabContainer } from '../../../../components/common/styled' +import SectionCard from '../../../../components/common/templates/SectionCard' import { Typography as T } from '../../../../core/typography' +import { overviewSections } from './overview.config' export default function OverviewTab() { return ( - - Overview content goes here. Describe the template, goals, etc. - + + {overviewSections.map((section) => ( + + {section.content && {section.content}} + {section.lists?.map((list) => ( + + ))} + + ))} + ) } diff --git a/src/pages/LiberyPage/tabs/Overview/overview.config.ts b/src/pages/LiberyPage/tabs/Overview/overview.config.ts new file mode 100644 index 0000000..9851be2 --- /dev/null +++ b/src/pages/LiberyPage/tabs/Overview/overview.config.ts @@ -0,0 +1,32 @@ +export const overviewSections = [ + { + title: '🚀 React-Vite Template', + content: `A modern, production-ready React template built with Vite, + featuring reusable components, custom hooks, and best practices + for scalable applications.`, + }, + { + title: "📦 What's Included", + lists: [ + { + title: 'Components', + items: [ + 'Button (multiple variants & sizes)', + 'Card (flexible content container)', + 'Modal (accessible & responsive)', + 'Badge (status indicators)', + 'Tabs (navigation component)', + ], + }, + { + title: 'Custom Hooks', + items: [ + 'useLocalStorage (persistent state)', + 'useToggle (boolean state management)', + 'useCounter (numeric state with actions)', + 'useTheme (theme switching)', + ], + }, + ], + }, +] From 0d54b553f2fc2bac0f2987422df48040dd3d6221 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Fri, 22 Aug 2025 10:58:29 +0200 Subject: [PATCH 09/10] Refactor --- src/components/common/molecules/List/List.tsx | 5 ++-- .../common/molecules/List/styled.ts | 3 --- src/components/common/styled.ts | 26 ++++++++++--------- .../templates/SectionCard/SectionCard.tsx | 7 ++--- .../common/templates/SectionCard/styled.ts | 10 ++----- src/pages/LiberyPage/tabs/Overview/index.tsx | 7 ++--- 6 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/components/common/molecules/List/List.tsx b/src/components/common/molecules/List/List.tsx index 367790b..21f022e 100644 --- a/src/components/common/molecules/List/List.tsx +++ b/src/components/common/molecules/List/List.tsx @@ -1,4 +1,5 @@ import { Typography as T } from '../../../../core/typography' +import { FlexContainer } from '../../styled' import * as S from './styled' type ListProps = { @@ -8,7 +9,7 @@ type ListProps = { export default function List({ title, items }: ListProps) { return ( - + {title} @@ -17,6 +18,6 @@ export default function List({ title, items }: ListProps) { {item} ))} - + ) } diff --git a/src/components/common/molecules/List/styled.ts b/src/components/common/molecules/List/styled.ts index c5a6958..e04adb7 100644 --- a/src/components/common/molecules/List/styled.ts +++ b/src/components/common/molecules/List/styled.ts @@ -1,8 +1,5 @@ import styled from '@emotion/styled' import tokens from '../../../../core/tokens' -import { FlexContainer } from '../../styled' - -export const ListWrapper = styled(FlexContainer)`` export const List = styled.ul` margin: ${tokens.spacing.BASELINE}px 0; diff --git a/src/components/common/styled.ts b/src/components/common/styled.ts index f832d8b..74f4340 100644 --- a/src/components/common/styled.ts +++ b/src/components/common/styled.ts @@ -1,10 +1,12 @@ import styled from '@emotion/styled' import tokens from '../../core/tokens' -export const Main = styled.main` - padding: ${tokens.padding.BASELINE * 2}px; +export const PaddedContainer = styled.div<{ padding?: number }>` + padding: ${(p) => p.padding ?? tokens.padding.BASELINE * 2}px; ` +export const Main = styled(PaddedContainer)`` + export const DividerBar = styled.hr` width: 100%; margin: 0; @@ -13,15 +15,15 @@ export const DividerBar = styled.hr` ${({ theme }) => theme.colors.scrollBar}; ` -export const BaseContainer = styled.div` - padding: ${tokens.padding.BASELINE * 2.5}px; -` -export const FlexContainer = styled.div` +export const FlexContainer = styled.div<{ + direction?: 'row' | 'column' + gap?: number + align?: string + justify?: string +}>` display: flex; - flex-direction: column; - gap: ${tokens.gap.BASELINE}px; -` - -export const TabContainer = styled(FlexContainer)` - gap: ${tokens.gap.BASELINE * 2.5}px; + flex-direction: ${(p) => p.direction ?? 'column'}; + gap: ${(p) => p.gap ?? tokens.gap.BASELINE}px; + align-items: ${(p) => p.align ?? 'stretch'}; + justify-content: ${(p) => p.justify ?? 'flex-start'}; ` diff --git a/src/components/common/templates/SectionCard/SectionCard.tsx b/src/components/common/templates/SectionCard/SectionCard.tsx index 74e2008..8738fa0 100644 --- a/src/components/common/templates/SectionCard/SectionCard.tsx +++ b/src/components/common/templates/SectionCard/SectionCard.tsx @@ -1,7 +1,8 @@ import type { ReactNode } from 'react' import * as S from './styled' import { Typography as T } from '../../../../core/typography' -import { DividerBar } from '../../styled' +import { DividerBar, PaddedContainer } from '../../styled' +import tokens from '../../../../core/tokens' type Props = { title: string @@ -11,11 +12,11 @@ type Props = { export default function SectionCard({ title, children }: Props) { return ( - + {title} - + {children} diff --git a/src/components/common/templates/SectionCard/styled.ts b/src/components/common/templates/SectionCard/styled.ts index 968f384..3b0ba2b 100644 --- a/src/components/common/templates/SectionCard/styled.ts +++ b/src/components/common/templates/SectionCard/styled.ts @@ -1,18 +1,12 @@ import styled from '@emotion/styled' -import { BaseContainer, FlexContainer } from '../../styled' import tokens from '../../../../core/tokens' +import { FlexContainer } from '../../styled' export const Wrapper = styled.section` background: ${({ theme }) => theme.colors.white}; border-radius: ${tokens.borderRadius.BASELINE}px; box-shadow: 0 1px 3px 0 ${({ theme }) => theme.colors.boxShadow}; -` - -export const Header = styled(BaseContainer)` - display: flex; - align-items: center; - justify-content: space-between; - gap: ${tokens.gap.LARGE}px; + overflow: hidden; ` export const Body = styled(FlexContainer)` diff --git a/src/pages/LiberyPage/tabs/Overview/index.tsx b/src/pages/LiberyPage/tabs/Overview/index.tsx index 2d3c6e7..1052f64 100644 --- a/src/pages/LiberyPage/tabs/Overview/index.tsx +++ b/src/pages/LiberyPage/tabs/Overview/index.tsx @@ -1,12 +1,13 @@ import List from '../../../../components/common/molecules/List/List' -import { TabContainer } from '../../../../components/common/styled' +import { FlexContainer } from '../../../../components/common/styled' import SectionCard from '../../../../components/common/templates/SectionCard' +import tokens from '../../../../core/tokens' import { Typography as T } from '../../../../core/typography' import { overviewSections } from './overview.config' export default function OverviewTab() { return ( - + {overviewSections.map((section) => ( {section.content && {section.content}} @@ -15,6 +16,6 @@ export default function OverviewTab() { ))} ))} - + ) } From 006d7d83c5bc66fd619c20704a6bfaaeede58556 Mon Sep 17 00:00:00 2001 From: Linn-Devoteam Date: Wed, 27 Aug 2025 11:14:19 +0200 Subject: [PATCH 10/10] Refactor --- src/App.tsx | 10 ++++------ src/main.tsx | 8 +++----- src/pages/LiberyPage/index.tsx | 4 ++-- src/pages/LiberyPage/tabs.config.tsx | 2 +- src/pages/LiberyPage/tabs/Overview/index.tsx | 2 +- .../tabs/Overview/{overview.config.ts => overview.ts} | 0 6 files changed, 11 insertions(+), 15 deletions(-) rename src/pages/LiberyPage/tabs/Overview/{overview.config.ts => overview.ts} (100%) diff --git a/src/App.tsx b/src/App.tsx index 84bd389..251f609 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,13 +1,11 @@ -import { BrowserRouter, Routes, Route } from 'react-router-dom' +import { Routes, Route } from 'react-router-dom' import LibraryPage from './pages/LiberyPage' function App() { return ( - - - } /> - - + + } /> + ) } diff --git a/src/main.tsx b/src/main.tsx index e8798a1..8218efb 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,18 +1,16 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' -import { BrowserRouter, Routes, Route } from 'react-router-dom' +import { BrowserRouter } from 'react-router-dom' import { ThemeProvider } from '@emotion/react' import theme from './core/theme' import './index.css' -import LibraryPage from './pages/LiberyPage' +import App from './App' createRoot(document.getElementById('root')!).render( - - } /> - + diff --git a/src/pages/LiberyPage/index.tsx b/src/pages/LiberyPage/index.tsx index ff82f86..e613d85 100644 --- a/src/pages/LiberyPage/index.tsx +++ b/src/pages/LiberyPage/index.tsx @@ -1,7 +1,7 @@ import { Typography as T } from '../../core/typography' import Tabs from '../../components/common/organisms/Tabs' import { Main } from '../../components/common/styled' -import { LIBRARY_TABS } from './tabs.config' +import { LiberyTabs } from './tabs.config' export default function LibraryPage() { return ( @@ -14,7 +14,7 @@ export default function LibraryPage() {
- +
) diff --git a/src/pages/LiberyPage/tabs.config.tsx b/src/pages/LiberyPage/tabs.config.tsx index 539bb11..308524e 100644 --- a/src/pages/LiberyPage/tabs.config.tsx +++ b/src/pages/LiberyPage/tabs.config.tsx @@ -3,7 +3,7 @@ import OverviewTab from './tabs/Overview' import ComponentsTab from './tabs/Components' import HooksTab from './tabs/Hooks' -export const LIBRARY_TABS: TabItem[] = [ +export const LiberyTabs: TabItem[] = [ { key: 'overview', label: 'Overview', content: }, { key: 'components', label: 'Components', content: }, { key: 'hooks', label: 'Hooks', content: }, diff --git a/src/pages/LiberyPage/tabs/Overview/index.tsx b/src/pages/LiberyPage/tabs/Overview/index.tsx index 1052f64..19e7333 100644 --- a/src/pages/LiberyPage/tabs/Overview/index.tsx +++ b/src/pages/LiberyPage/tabs/Overview/index.tsx @@ -3,7 +3,7 @@ import { FlexContainer } from '../../../../components/common/styled' import SectionCard from '../../../../components/common/templates/SectionCard' import tokens from '../../../../core/tokens' import { Typography as T } from '../../../../core/typography' -import { overviewSections } from './overview.config' +import { overviewSections } from './overview' export default function OverviewTab() { return ( diff --git a/src/pages/LiberyPage/tabs/Overview/overview.config.ts b/src/pages/LiberyPage/tabs/Overview/overview.ts similarity index 100% rename from src/pages/LiberyPage/tabs/Overview/overview.config.ts rename to src/pages/LiberyPage/tabs/Overview/overview.ts