From dcc13dd0fe19ac1ce7a03ba38a461370135f6939 Mon Sep 17 00:00:00 2001 From: Andrea Simone Porceddu Date: Fri, 15 Oct 2021 00:01:30 +0200 Subject: [PATCH] feat(devtool): generic slice route and ui improvements --- devtool/src/_shared/components/Link/index.tsx | 7 +- .../src/_shared/components/Route/index.tsx | 2 +- .../components/Slices}/Colors/index.tsx | 26 +++-- .../components/Slices/Colors/style.module.css | 13 +++ .../src/_shared/components/Slices/index.tsx | 100 ++++++++++++++++++ devtool/src/_shared/components/index.ts | 1 + .../src/_shared/contexts/Routing/Routing.tsx | 11 +- .../src/_shared/contexts/Routing/routes.ts | 10 ++ .../src/_shared/contexts/Routing/types.tsx | 41 ++++++- devtool/src/_shared/css/dark-components.css | 12 ++- devtool/src/_shared/css/light-components.css | 12 ++- devtool/src/_shared/hooks/useRouter.ts | 20 ++-- .../src/_shared/styles/components/button.ts | 10 ++ devtool/src/_shared/template/Page/index.tsx | 23 ++++ .../src/_shared/template/Page/page.module.css | 21 ++++ .../src/_shared/template/SideBar/Menus.tsx | 4 +- .../src/_shared/template/SideBar/index.tsx | 2 +- .../_shared/template/SideBar/style.module.css | 6 +- devtool/src/devtool/Devtool.tsx | 6 +- .../src/devtool/pages/Colors/style.module.css | 33 ------ devtool/src/devtool/pages/Home/index.tsx | 18 ++-- .../src/devtool/pages/Home/style.module.css | 16 --- devtool/src/devtool/pages/Slice/index.tsx | 36 +++++++ devtool/src/devtool/pages/index.ts | 2 +- 24 files changed, 328 insertions(+), 104 deletions(-) rename devtool/src/{devtool/pages => _shared/components/Slices}/Colors/index.tsx (62%) create mode 100644 devtool/src/_shared/components/Slices/Colors/style.module.css create mode 100644 devtool/src/_shared/components/Slices/index.tsx create mode 100644 devtool/src/_shared/contexts/Routing/routes.ts create mode 100644 devtool/src/_shared/template/Page/index.tsx create mode 100644 devtool/src/_shared/template/Page/page.module.css delete mode 100644 devtool/src/devtool/pages/Colors/style.module.css delete mode 100644 devtool/src/devtool/pages/Home/style.module.css create mode 100644 devtool/src/devtool/pages/Slice/index.tsx diff --git a/devtool/src/_shared/components/Link/index.tsx b/devtool/src/_shared/components/Link/index.tsx index 59670c13..e9411010 100644 --- a/devtool/src/_shared/components/Link/index.tsx +++ b/devtool/src/_shared/components/Link/index.tsx @@ -1,14 +1,17 @@ import { useCallback } from 'react'; import { RouteName } from '../../contexts'; import { useRouter } from '../../hooks'; +import { RouteState } from '../../contexts/Routing/types'; type Props = React.HTMLProps & { to: RouteName; + state?: RouteState; onNavigate?: () => void; }; export const Link: React.FC = ({ to, + state, children, onNavigate, ...props @@ -16,11 +19,11 @@ export const Link: React.FC = ({ const { navigate } = useRouter(); const onClick = useCallback(() => { - navigate(to); + navigate(to, state); if (onNavigate) { onNavigate(); } - }, [navigate, onNavigate, to]); + }, [navigate, onNavigate, to, state]); return ( = ({ name, children }) => { const { route, direction } = useRouter(); - const isVisible = name === route; + const isVisible = name === route.name; const renderChildren = useCallback( (state: TransitionStatus) => ( diff --git a/devtool/src/devtool/pages/Colors/index.tsx b/devtool/src/_shared/components/Slices/Colors/index.tsx similarity index 62% rename from devtool/src/devtool/pages/Colors/index.tsx rename to devtool/src/_shared/components/Slices/Colors/index.tsx index 41cc47ae..0fcaba86 100644 --- a/devtool/src/devtool/pages/Colors/index.tsx +++ b/devtool/src/_shared/components/Slices/Colors/index.tsx @@ -1,12 +1,16 @@ import React, { useMemo } from 'react'; import { Color, useTheme } from '@morfeo/react'; import clsx from 'clsx'; -import { Card } from '../../../_shared/components'; +import { Card } from '../../Card'; import styles from './style.module.css'; +import { useRouter } from '../../../hooks/useRouter'; +import { RouteName } from '../../../contexts'; +import { SliceName } from '../../../contexts/Routing/types'; export const Colors: React.FC = () => { const theme = useTheme(); const slice = useMemo(() => (theme || {})['colors'] || {}, [theme]); + const { navigate } = useRouter(); const sliceKeys = useMemo( () => @@ -19,7 +23,11 @@ export const Colors: React.FC = () => { const section = useMemo(() => { return sliceKeys.map(key => { return ( -
+
navigate(RouteName.SLICE, { slice: SliceName.COLORS, detailKey: key})} + >

{

); }); - }, [sliceKeys]); + }, [navigate, sliceKeys]); - return ( -
-
-

Colors

-

- {'slices > colors'} -

-
-
{section}
-
- ); + return <>{section}; }; diff --git a/devtool/src/_shared/components/Slices/Colors/style.module.css b/devtool/src/_shared/components/Slices/Colors/style.module.css new file mode 100644 index 00000000..92abb758 --- /dev/null +++ b/devtool/src/_shared/components/Slices/Colors/style.module.css @@ -0,0 +1,13 @@ +.colorContainer { + display: flex; + align-items: flex-start; + flex-direction: column; + padding: var(--spacings-xs); +} + +.colorName { + max-width: 10rem; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} \ No newline at end of file diff --git a/devtool/src/_shared/components/Slices/index.tsx b/devtool/src/_shared/components/Slices/index.tsx new file mode 100644 index 00000000..a6046821 --- /dev/null +++ b/devtool/src/_shared/components/Slices/index.tsx @@ -0,0 +1,100 @@ +import { SliceName } from '../../contexts'; +import { Colors } from './Colors/index'; + +export const slices = { + [SliceName.COLORS]: { + render: , + renderDetail: <>, + displayName: 'colors', + }, + [SliceName.RADII]: { + render: <>, + renderDetail: <>, + displayName: 'radii', + }, + [SliceName.SIZES]: { + render: <>, + renderDetail: <>, + displayName: 'sizes', + }, + [SliceName.FONTS]: { + render: <>, + renderDetail: <>, + displayName: 'fonts', + }, + [SliceName.SHADOWS]: { + render: <>, + renderDetail: <>, + displayName: 'shadows', + }, + [SliceName.BORDERS]: { + render: <>, + renderDetail: <>, + displayName: 'borders', + }, + [SliceName.SPACINGS]: { + render: <>, + renderDetail: <>, + displayName: 'spacings', + }, + [SliceName.Z_INDICES]: { + render: <>, + renderDetail: <>, + displayName: 'zIndices', + }, + [SliceName.FONT_SIZES]: { + render: <>, + renderDetail: <>, + displayName: 'fontSizes', + }, + [SliceName.GRADIENTS]: { + render: <>, + renderDetail: <>, + displayName: 'gradients', + }, + [SliceName.OPACITIES]: { + render: <>, + renderDetail: <>, + displayName: 'opacities', + }, + [SliceName.FONT_WEIGHTS]: { + render: <>, + renderDetail: <>, + displayName: 'fontWeights', + }, + [SliceName.LINE_HEIGHTS]: { + render: <>, + renderDetail: <>, + displayName: 'lineHeights', + }, + [SliceName.BREAKPOINTS]: { + render: <>, + renderDetail: <>, + displayName: 'breakpoints', + }, + [SliceName.TRANSITIONS]: { + render: <>, + renderDetail: <>, + displayName: 'transitions', + }, + [SliceName.BORDER_WIDTHS]: { + render: <>, + renderDetail: <>, + displayName: 'borderWidths', + }, + [SliceName.MEDIA_QUERIES]: { + render: <>, + renderDetail: <>, + displayName: 'mediaQueries', + }, + [SliceName.BORDER_STYLES]: { + render: <>, + renderDetail: <>, + displayName: 'borderStyles', + }, + [SliceName.LETTER_SPACINGS]: { + render: <>, + renderDetail: <>, + displayName: 'letterSpacings', + }, +}; diff --git a/devtool/src/_shared/components/index.ts b/devtool/src/_shared/components/index.ts index e61d9d1c..a45553c1 100644 --- a/devtool/src/_shared/components/index.ts +++ b/devtool/src/_shared/components/index.ts @@ -4,3 +4,4 @@ export * from './Card'; export * from './Route'; export * from './Accordion'; export * from './CopyButton'; +export * from './Slices'; diff --git a/devtool/src/_shared/contexts/Routing/Routing.tsx b/devtool/src/_shared/contexts/Routing/Routing.tsx index 94bf5d40..a12f0e45 100644 --- a/devtool/src/_shared/contexts/Routing/Routing.tsx +++ b/devtool/src/_shared/contexts/Routing/Routing.tsx @@ -1,16 +1,17 @@ import React, { createContext, useState, useMemo } from "react"; -import { RouteName, RoutingContextType } from "./types"; +import { RouteName, RoutingContextType, RouteType } from './types'; +import { routes } from './routes'; export const routingContext = createContext({ - index: RouteName.HOME, - current: RouteName.HOME, + index: routes.index.name, + current: routes.index, } as RoutingContextType); const { Provider } = routingContext; export const RoutingProvider: React.FC = ({ children }) => { - const [current, setCurrent] = useState(RouteName.HOME); - const [history, setHistory] = useState([]); + const [current, setCurrent] = useState(routes.index); + const [history, setHistory] = useState([]); const value = useMemo( () => ({ index: RouteName.HOME, current, history, setCurrent, setHistory }), diff --git a/devtool/src/_shared/contexts/Routing/routes.ts b/devtool/src/_shared/contexts/Routing/routes.ts new file mode 100644 index 00000000..d22879bb --- /dev/null +++ b/devtool/src/_shared/contexts/Routing/routes.ts @@ -0,0 +1,10 @@ +import { RouteName } from './types'; + +export const routes = { + [RouteName.HOME]: { + name: RouteName.HOME, + }, + [RouteName.SLICE]: { + name: RouteName.SLICE, + }, +} \ No newline at end of file diff --git a/devtool/src/_shared/contexts/Routing/types.tsx b/devtool/src/_shared/contexts/Routing/types.tsx index eb85566c..e995f30e 100644 --- a/devtool/src/_shared/contexts/Routing/types.tsx +++ b/devtool/src/_shared/contexts/Routing/types.tsx @@ -2,15 +2,48 @@ import React from "react"; export enum RouteName { HOME = "index", + SLICE = "slice" +} + +export enum SliceName { COLORS = "colors", + RADII = "radii", + SIZES = "sizes", + FONTS = "fonts", + SHADOWS = "shadows", + BORDERS = "borders", + SPACINGS = "spacings", + Z_INDICES = "zIndices", + FONT_SIZES = "fontSizes", + GRADIENTS = "gradients", + OPACITIES = "opacities", + FONT_WEIGHTS = "fontWeights", + LINE_HEIGHTS = "lineHeights", + BREAKPOINTS = "breakpoints", + TRANSITIONS = "transitions", + BORDER_WIDTHS = "borderWidths", + MEDIA_QUERIES = "mediaQueries", + BORDER_STYLES = "borderStyles", + LETTER_SPACINGS = "letterSpacings", +} + +export type RouteState = { + slice: SliceName, + detailKey?: string +} + +export type RouteType = { + name: RouteName, + state?: RouteState, + parentRoute?: RouteName } export type RoutingDirection = "right" | "left"; export type RoutingContextType = { index: RouteName; - current: RouteName; - history: RouteName[]; - setCurrent: React.Dispatch>; - setHistory: React.Dispatch>; + current: RouteType; + history: RouteType[]; + setCurrent: React.Dispatch>; + setHistory: React.Dispatch>; }; diff --git a/devtool/src/_shared/css/dark-components.css b/devtool/src/_shared/css/dark-components.css index ab44ad82..3729b51f 100644 --- a/devtool/src/_shared/css/dark-components.css +++ b/devtool/src/_shared/css/dark-components.css @@ -41,6 +41,7 @@ color: var(--colors-inverted-text-color); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-xs); @@ -50,23 +51,29 @@ padding-bottom: var(--spacings-xs); background-color: var(--colors-primary); } -[data-morfeo-theme="dark"] .morfeo-button-round { +[data-morfeo-theme="dark"] .morfeo-button-side { color: var(--colors-inverted-text-color); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-none); padding-left: var(--spacings-none); - border-radius: var(--radii-round); + border-radius: var(--radii-xs); padding-right: var(--spacings-none); padding-bottom: var(--spacings-none); background-color: var(--colors-primary); + border-top-left-radius: var(--radii-none); + border-top-right-radius: var(--radii-round); + border-bottom-left-radius: var(--radii-none); + border-bottom-right-radius: var(--radii-round); } [data-morfeo-theme="dark"] .morfeo-button-error { color: var(--colors-error); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-xs); @@ -80,6 +87,7 @@ color: var(--colors-inverted-text-color); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-xs); diff --git a/devtool/src/_shared/css/light-components.css b/devtool/src/_shared/css/light-components.css index 9237d136..b07a445a 100644 --- a/devtool/src/_shared/css/light-components.css +++ b/devtool/src/_shared/css/light-components.css @@ -41,6 +41,7 @@ color: var(--colors-inverted-text-color); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-xs); @@ -50,23 +51,29 @@ padding-bottom: var(--spacings-xs); background-color: var(--colors-primary); } -[data-morfeo-theme="light"] .morfeo-button-round { +[data-morfeo-theme="light"] .morfeo-button-side { color: var(--colors-inverted-text-color); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-none); padding-left: var(--spacings-none); - border-radius: var(--radii-round); + border-radius: var(--radii-xs); padding-right: var(--spacings-none); padding-bottom: var(--spacings-none); background-color: var(--colors-primary); + border-top-left-radius: var(--radii-none); + border-top-right-radius: var(--radii-round); + border-bottom-left-radius: var(--radii-none); + border-bottom-right-radius: var(--radii-round); } [data-morfeo-theme="light"] .morfeo-button-error { color: var(--colors-error); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-xs); @@ -80,6 +87,7 @@ color: var(--colors-inverted-text-color); border: var(--border-widths-none) var(--border-styles-none); cursor: pointer; + outline: none; font-size: var(--font-sizes-m); font-weight: var(--font-weights-bold); padding-top: var(--spacings-xs); diff --git a/devtool/src/_shared/hooks/useRouter.ts b/devtool/src/_shared/hooks/useRouter.ts index 1c8cd55f..2494ac17 100644 --- a/devtool/src/_shared/hooks/useRouter.ts +++ b/devtool/src/_shared/hooks/useRouter.ts @@ -1,13 +1,15 @@ import { useCallback, useContext, useState } from 'react'; -import { RouteName, routingContext, RoutingDirection } from '../contexts'; +import { routingContext, RoutingDirection } from '../contexts'; +import { RouteType, RouteName, RouteState } from '../contexts/Routing/types'; +import { routes } from '../contexts/Routing/routes'; export function useRouter() { const [direction, setDirection] = useState('right'); - const { index, current, history, setCurrent, setHistory } = + const { current, history, setCurrent, setHistory } = useContext(routingContext); const updateCurrentRoute = useCallback( - (route: RouteName) => { + (route: RouteType) => { setCurrent(route); window.scrollTo({ top: 0, behavior: 'auto' }); }, @@ -15,13 +17,13 @@ export function useRouter() { ); const navigate = useCallback( - (route: RouteName) => { - if (current === route) { + (routeName: RouteName, state?: RouteState) => { + if (!state && current.name === routeName) { return; } - setHistory(prev => [...prev, route]); + setHistory(prev => [...prev, { ...routes[routeName], state }]); setDirection('right'); - updateCurrentRoute(route); + updateCurrentRoute({ ...routes[routeName], state }); }, [current, updateCurrentRoute, setHistory], ); @@ -30,8 +32,8 @@ export function useRouter() { const [newRoute] = history.slice(-2); setHistory(history.slice(0, -1)); setDirection('left'); - updateCurrentRoute(history.length === 1 ? index : newRoute); - }, [history, index, setHistory, updateCurrentRoute]); + updateCurrentRoute(history.length === 1 ? routes.index : newRoute); + }, [history, setHistory, updateCurrentRoute]); return { route: current, diff --git a/devtool/src/_shared/styles/components/button.ts b/devtool/src/_shared/styles/components/button.ts index ad0c1e68..40b5b8f1 100644 --- a/devtool/src/_shared/styles/components/button.ts +++ b/devtool/src/_shared/styles/components/button.ts @@ -21,6 +21,16 @@ export const Button: ComponentConfig = { py: 'none', }, }, + side: { + style: { + borderTopRightRadius: 'round', + borderBottomRightRadius: 'round', + borderTopLeftRadius: 'none', + borderBottomLeftRadius: 'none', + px: 'none', + py: 'none', + }, + }, error: { style: { bg: 'light', diff --git a/devtool/src/_shared/template/Page/index.tsx b/devtool/src/_shared/template/Page/index.tsx new file mode 100644 index 00000000..6fa5da28 --- /dev/null +++ b/devtool/src/_shared/template/Page/index.tsx @@ -0,0 +1,23 @@ +import styles from './page.module.css'; +import clsx from 'clsx'; + +type Props = { + breadcrumb?: string[]; + title?: string; +}; + +export const Page: React.FC = ({ children, title, breadcrumb }) => { + return ( +
+ {title && breadcrumb && ( +
+

{title}

+

+ {breadcrumb.join(' > ')} +

+
+ )} +
{children}
+
+ ); +}; diff --git a/devtool/src/_shared/template/Page/page.module.css b/devtool/src/_shared/template/Page/page.module.css new file mode 100644 index 00000000..3b57d042 --- /dev/null +++ b/devtool/src/_shared/template/Page/page.module.css @@ -0,0 +1,21 @@ +.page { + display: flex; + flex-direction: column; + padding-top: 8rem; +} + +.header { + padding-left: var(--spacings-xs); + padding-right: var(--spacings-xs); + padding-bottom: var(--spacings-s); +} + +.breadcrumb { + color: var(--colors-gray-light) !important; +} + +.section { + display: flex; + flex-wrap: wrap; + justify-content: space-between; +} \ No newline at end of file diff --git a/devtool/src/_shared/template/SideBar/Menus.tsx b/devtool/src/_shared/template/SideBar/Menus.tsx index a6d818c9..b5047696 100644 --- a/devtool/src/_shared/template/SideBar/Menus.tsx +++ b/devtool/src/_shared/template/SideBar/Menus.tsx @@ -5,6 +5,7 @@ import { RouteName } from '../../contexts'; import { useThemeSlices } from '../../hooks'; import { IconName } from '../../components/Icon/icons'; import styles from './style.module.css'; +import { SliceName } from '../../contexts/Routing/types'; type Props = { onNavigate?: () => void; @@ -26,7 +27,8 @@ const MenuItem: React.FC = ({ text, icon, onNavigate }) => {
= ({ open, setOpen }) => {