From 7520d950b8d6537a90395a72200a50e147a24ed8 Mon Sep 17 00:00:00 2001 From: TechQuery Date: Tue, 9 Jan 2024 04:35:06 +0800 Subject: [PATCH] [refactor] rewrite Navigator Bar based on Bootstrap 5 [remove] useless Cell Router model --- .eslintrc.json | 3 +- ReadMe.md | 8 ++-- package.json | 8 ++-- pnpm-lock.yaml | 18 ++++---- src/component/Grid.tsx | 24 ++++++++++ src/component/Nav.tsx | 22 ++++++++++ src/component/Navbar.tsx | 57 ++++++++++++++++++++++++ src/component/Offcanvas.tsx | 87 +++++++++++++++++++++++++++++++++++++ src/component/index.ts | 5 +++ src/component/type.ts | 22 ++++++++++ src/index.html | 2 +- src/index.webmanifest | 2 +- src/model/index.ts | 3 -- src/page/index.tsx | 57 +++++++++++++++--------- 14 files changed, 275 insertions(+), 43 deletions(-) create mode 100644 src/component/Grid.tsx create mode 100644 src/component/Nav.tsx create mode 100644 src/component/Navbar.tsx create mode 100644 src/component/Offcanvas.tsx create mode 100644 src/component/index.ts create mode 100644 src/component/type.ts delete mode 100644 src/model/index.ts diff --git a/.eslintrc.json b/.eslintrc.json index e3b805f..5a3d9d2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,8 +18,9 @@ "prettier" ], "rules": { - "no-unused-vars": "warn", "prefer-const": "warn", + "no-unused-vars": "warn", + "@typescript-eslint/no-unused-vars": "warn", "@typescript-eslint/explicit-module-boundary-types": "off" } } diff --git a/ReadMe.md b/ReadMe.md index ac4bb66..59d3b8a 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -2,7 +2,7 @@ # WebCell scaffold -App Project scaffold of **WebCell** v2 +App Project scaffold of **WebCell** v3 https://web-cell.dev/scaffold/ @@ -20,15 +20,15 @@ https://web-cell.dev/scaffold/ ## Development ```shell -npm install - +npm i pnpm -g +pnpm i npm start ``` ## Deployment ```shell -npm run build +pnpm build ``` [1]: https://david-dm.org/EasyWebApp/scaffold diff --git a/package.json b/package.json index eb25f56..5be12e1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "webcell-scaffold", - "version": "0.3.0", - "description": "App Project scaffold of WebCell v2", + "version": "0.4.0", + "description": "App Project scaffold of WebCell v3", "keywords": [ "web-component", "typescript", @@ -17,7 +17,7 @@ }, "dependencies": { "browser-unhandled-rejection": "^1.0.2", - "cell-router": "3.0.0-rc.1", + "cell-router": "^3.0.0-rc.1", "classnames": "^2.5.1", "dom-renderer": "^2.0.4", "mobx": "^6.12.0", @@ -30,7 +30,7 @@ "@parcel/transformer-less": "2.11.0", "@parcel/transformer-typescript-tsc": "~2.11.0", "@parcel/transformer-webmanifest": "~2.11.0", - "@types/node": "^18.19.4", + "@types/node": "^18.19.5", "@typescript-eslint/eslint-plugin": "^6.18.0", "@typescript-eslint/parser": "^6.18.0", "eslint": "^8.56.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7cd4c6..9151302 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,7 +9,7 @@ dependencies: specifier: ^1.0.2 version: 1.0.2 cell-router: - specifier: 3.0.0-rc.1 + specifier: ^3.0.0-rc.1 version: 3.0.0-rc.1(typescript@5.3.3) classnames: specifier: ^2.5.1 @@ -44,8 +44,8 @@ devDependencies: specifier: ~2.11.0 version: 2.11.0 '@types/node': - specifier: ^18.19.4 - version: 18.19.4 + specifier: ^18.19.5 + version: 18.19.5 '@typescript-eslint/eslint-plugin': specifier: ^6.18.0 version: 6.18.0(@typescript-eslint/parser@6.18.0)(eslint@8.56.0)(typescript@5.3.3) @@ -2589,15 +2589,15 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 18.19.4 + '@types/node': 18.19.5 dev: true /@types/minimist@1.2.5: resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} dev: true - /@types/node@18.19.4: - resolution: {integrity: sha512-xNzlUhzoHotIsnFoXmJB+yWmBvFZgKCI9TtPIEdYIMM1KWfwuY8zh7wvc1u1OAXlC7dlf6mZVx/s+Y5KfFz19A==} + /@types/node@18.19.5: + resolution: {integrity: sha512-22MG6T02Hos2JWfa1o5jsIByn+bc5iOt1IS4xyg6OG68Bu+wMonVZzdrgCw693++rpLE9RUT/Bx15BeDzO0j+g==} dependencies: undici-types: 5.26.5 dev: true @@ -2609,13 +2609,13 @@ packages: /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 18.19.4 + '@types/node': 18.19.5 dev: true /@types/responselike@1.0.3: resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} dependencies: - '@types/node': 18.19.4 + '@types/node': 18.19.5 dev: true /@types/semver@7.5.6: @@ -4535,7 +4535,7 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.19.4 + '@types/node': 18.19.5 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true diff --git a/src/component/Grid.tsx b/src/component/Grid.tsx new file mode 100644 index 0000000..80f7033 --- /dev/null +++ b/src/component/Grid.tsx @@ -0,0 +1,24 @@ +import { JsxProps } from 'dom-renderer'; +import { FC } from 'web-cell'; + +import { Size } from './type'; + +export interface ContainerProps extends JsxProps { + fluid?: boolean | Size; +} + +export const Container: FC = ({ + className = '', + fluid, + children, + ...props +}) => ( +
+ {children} +
+); diff --git a/src/component/Nav.tsx b/src/component/Nav.tsx new file mode 100644 index 0000000..7d5d0a3 --- /dev/null +++ b/src/component/Nav.tsx @@ -0,0 +1,22 @@ +import { JsxProps } from 'dom-renderer'; +import { FC } from 'web-cell'; + +export interface NavLinkProps extends JsxProps { + active?: boolean; +} + +export const NavLink: FC = ({ + className = '', + active, + children, + ...props +}) => ( +
  • + + {children} + +
  • +); diff --git a/src/component/Navbar.tsx b/src/component/Navbar.tsx new file mode 100644 index 0000000..340cad1 --- /dev/null +++ b/src/component/Navbar.tsx @@ -0,0 +1,57 @@ +import { JsxProps } from 'dom-renderer'; +import { FC } from 'web-cell'; + +import { BackgroundColor, PositionY, Size } from './type'; + +export type NavbarBrandProps = JsxProps; + +export const NavbarBrand: FC = ({ + className = '', + children, + ...props +}) => ( + + {children} + +); + +export type NavbarToggleProps = JsxProps; + +export const NavbarToggle: FC = ({ + className = '', + type, + children, + ...props +}) => ( + +); + +export interface NavbarProps extends JsxProps { + variant?: 'light' | 'dark'; + bg?: BackgroundColor; + expand?: boolean | Size; + fixed?: PositionY; + sticky?: PositionY; +} + +export const Navbar: FC = ({ + variant = 'light', + bg = 'body-tertiary', + fixed, + sticky, + expand, + children +}) => ( + +); diff --git a/src/component/Offcanvas.tsx b/src/component/Offcanvas.tsx new file mode 100644 index 0000000..a9ed296 --- /dev/null +++ b/src/component/Offcanvas.tsx @@ -0,0 +1,87 @@ +import { JsxProps } from 'dom-renderer'; +import { FC } from 'web-cell'; +import { uniqueID } from 'web-utility'; + +export const OffcanvasTitle: FC> = ({ + className = '', + children, + ...props +}) => ( +
    + {children} +
    +); + +export interface OffcanvasHeaderProps extends JsxProps { + closeButton?: boolean; +} + +export const OffcanvasHeader: FC = ({ + className = '', + closeButton, + children, + ...props +}) => ( +
    + {children} + + {closeButton && ( +
    +); + +export const OffcanvasBody: FC> = ({ + className = '', + children, + ...props +}) => ( +
    + {children} +
    +); + +export interface OffcanvasProps extends JsxProps { + show?: boolean; +} + +export const Offcanvas: FC = ({ + className = '', + show, + children, + ...props +}) => ( +
    + {children} +
    +); + +export interface OffcanvasBoxProps + extends OffcanvasProps, + OffcanvasHeaderProps { + titleId?: string; +} + +export const OffcanvasBox: FC = ({ + title, + titleId = uniqueID(), + closeButton, + children, + ...props +}) => ( + + + {title} + + {children} + +); diff --git a/src/component/index.ts b/src/component/index.ts new file mode 100644 index 0000000..67901f5 --- /dev/null +++ b/src/component/index.ts @@ -0,0 +1,5 @@ +export * from './type'; +export * from './Grid'; +export * from './Nav'; +export * from './Navbar'; +export * from './Offcanvas'; diff --git a/src/component/type.ts b/src/component/type.ts new file mode 100644 index 0000000..cd541c3 --- /dev/null +++ b/src/component/type.ts @@ -0,0 +1,22 @@ +type Subtle = `${T}${'' | '-subtle'}`; + +export type Color = + | 'primary' + | 'secondary' + | 'success' + | 'danger' + | 'warning' + | 'info' + | 'light' + | 'dark'; + +export type BackgroundColor = + | Subtle + | `body${'' | '-secondary' | '-tertiary'}` + | 'black' + | 'white' + | 'transparent'; + +export type Size = 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; + +export type PositionY = 'top' | 'bottom'; diff --git a/src/index.html b/src/index.html index c204255..fe52087 100644 --- a/src/index.html +++ b/src/index.html @@ -7,7 +7,7 @@ /> WebCell scaffold - + diff --git a/src/index.webmanifest b/src/index.webmanifest index 95469b0..58245c3 100644 --- a/src/index.webmanifest +++ b/src/index.webmanifest @@ -2,7 +2,7 @@ "name": "WebCell scaffold", "short_name": "WC Demo", "start_url": ".", - "description": "App Project scaffold of WebCell v2", + "description": "App Project scaffold of WebCell v3", "scope": "/", "display": "standalone", "orientation": "any", diff --git a/src/model/index.ts b/src/model/index.ts deleted file mode 100644 index 0eb1d26..0000000 --- a/src/model/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { History } from 'cell-router'; - -export const history = new History(); diff --git a/src/page/index.tsx b/src/page/index.tsx index f57cbd4..c412887 100644 --- a/src/page/index.tsx +++ b/src/page/index.tsx @@ -1,10 +1,20 @@ import { PageProps, createRouter } from 'cell-router'; -import WebCell_0 from '../image/WebCell-0.png'; +import { + Container, + NavLink, + Navbar, + NavbarBrand, + NavbarToggle, + OffcanvasBox +} from '../component'; + import { CellClock } from './Clock'; import { Hello } from './Hello'; import { HomePage } from './Home'; +import WebCell_0 from '../image/WebCell-0.png'; + const menu = [ { title: 'Hello', @@ -20,32 +30,39 @@ const menu = [ } ]; -const { Route, Link } = createRouter({ +const { Route } = createRouter({ startClass: 'start', endClass: 'end' }); export const PageFrame = () => ( <> - {/* + + + WebCell + WebCell scaffold + + - } - > */} - - {/* */} + +
      + {menu.map(({ title, href }) => ( + {title} + ))} +
    +
    + +