Skip to content

Commit

Permalink
feat: refactor GUI of DevTools (#4809)
Browse files Browse the repository at this point in the history
  • Loading branch information
Asuka109 authored Oct 18, 2023
1 parent dffbe82 commit 078444a
Show file tree
Hide file tree
Showing 79 changed files with 1,461 additions and 1,090 deletions.
9 changes: 9 additions & 0 deletions packages/devtools/client/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"cssVariables.lookupFiles": [
"./node_modules/@radix-ui/themes/styles.css",
"./src/**/*.css",
"./src/**/*.scss",
"./src/**/*.sass",
"./src/**/*.less"
]
}
11 changes: 9 additions & 2 deletions packages/devtools/client/modern.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@ export default defineConfig<'rspack'>({
port: 8780,
},
source: {
preEntry: [require.resolve('modern-normalize/modern-normalize.css')],
preEntry: [
require.resolve('modern-normalize/modern-normalize.css'),
'./src/styles/theme.scss',
],
globalVars: {
'process.env.PKG_VERSION': version,
},
},
output: {
assetPrefix: ROUTE_BASENAME,
enableCssModuleTSDeclaration: true,
},
tools: {
postcss: (config, { addPlugins }) => {
addPlugins(require('postcss-custom-media'));
},
},
plugins: [appTools({ bundler: 'experimental-rspack' })],
});
46 changes: 25 additions & 21 deletions packages/devtools/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,42 +16,46 @@
"node": ">=14.0.0"
},
"devDependencies": {
"birpc": "0.2.13",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@modern-js-app/eslint-config": "workspace:*",
"@modern-js/app-tools": "workspace:*",
"@modern-js/builder-rspack-provider": "workspace:*",
"@modern-js/builder-shared": "workspace:*",
"@modern-js/devtools-kit": "workspace:*",
"@modern-js/eslint-config": "workspace:*",
"@modern-js/plugin-proxy": "workspace:*",
"@modern-js/runtime": "workspace:*",
"@modern-js/tsconfig": "workspace:*",
"@modern-js/types": "workspace:*",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-popover": "^1.0.6",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/themes": "^1.1.2",
"@radix-ui/themes": "^2.0.0",
"@types/jest": "~29.2.4",
"@types/lodash": "^4.14.196",
"@types/node": "~16.11.7",
"@types/react": "~18.0.26",
"@types/react-dom": "~18.0.10",
"birpc": "0.2.13",
"clsx": "^1.2.1",
"lodash": "^4.17.21",
"p-defer": "3.0.0",
"postcss-custom-media": "^10.0.1",
"react": "~18.2.0",
"react-base16-styling": "^0.9.1",
"react-dom": "~18.2.0",
"react-icons": "^4.11.0",
"react-json-tree": "^0.18.0",
"react-json-view": "^1.21.3",
"react-use": "^17.4.0",
"suspend-react": "^0.1.3",
"ufo": "^1.2.0",
"valtio": "^1.11.1",
"@modern-js-app/eslint-config": "workspace:*",
"@modern-js/app-tools": "workspace:*",
"@modern-js/builder-shared": "workspace:*",
"@modern-js/builder-rspack-provider": "workspace:*",
"@modern-js/eslint-config": "workspace:*",
"@modern-js/plugin-proxy": "workspace:*",
"@modern-js/tsconfig": "workspace:*",
"@types/jest": "~29.2.4",
"@types/lodash": "^4.14.196",
"@types/node": "~16.11.7",
"@types/react": "~18.0.26",
"@types/react-dom": "~18.0.10",
"rimraf": "~3.0.2",
"suspend-react": "^0.1.3",
"type-fest": "^4.1.0",
"typescript": "~5.0.4"
"typescript": "~5.0.4",
"ufo": "^1.2.0",
"valtio": "^1.11.1"
},
"dependencies": {
"thumbhash": "^0.1.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.link {
color: var(--gray-10);
}

.connector {
width: var(--font-size-2);
height: var(--font-size-2);
color: var(--gray-6);
}
75 changes: 44 additions & 31 deletions packages/devtools/client/src/components/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,56 @@
import React from 'react';
import styled from '@emotion/styled';
import { Button, Flex } from '@radix-ui/themes';
import React, { ReactNode } from 'react';
import _ from 'lodash';
import { Flex } from '@radix-ui/themes';
import { ChevronRightIcon } from '@radix-ui/react-icons';
import type { ButtonProps } from '@radix-ui/themes/dist/cjs/components/button';
import type { FlexProps } from '@radix-ui/themes/dist/cjs/components/flex';
import { useMatches } from '@modern-js/runtime/router';
import styles from './Breadcrumbs.module.scss';
import { Link } from './Link';

export type BreadcrumbButtonProps = ButtonProps &
React.RefAttributes<HTMLButtonElement>;
export type BreadcrumbProps = FlexProps & React.RefAttributes<HTMLDivElement>;

export const BreadcrumbButton: React.FC<BreadcrumbButtonProps> = props => {
return <Button color="gray" size="1" variant="ghost" {...props} />;
};
export const Breadcrumbs: React.FC<BreadcrumbProps> = props => {
const elements: React.ReactElement[] = [];
const items: { pathname: string; title: ReactNode; id: string }[] = [];

export interface BreadcrumbsProps {
children?: React.ReactElement[];
}
for (const match of useMatches()) {
const raw: unknown = _.get(match, 'handle.breadcrumb');
if (!raw) continue;
const breadcrumbs = _.castArray(raw).filter(_.isObject);
for (const breadcrumb of breadcrumbs) {
if (!('title' in breadcrumb)) continue;
const pathname =
'pathname' in breadcrumb && _.isString(breadcrumb.pathname)
? breadcrumb.pathname
: match.pathname;
items.push({
title: breadcrumb.title as any,
pathname,
id: match.id,
});
}
}

export const Breadcrumbs: React.FC<BreadcrumbsProps> = ({ children = [] }) => {
const elements: React.ReactElement[] = [];
for (const child of children) {
elements.push(child);
if (child !== children.at(-1)) {
elements.push(<Connector key={`${child.key}__connector`} />);
for (const [i, item] of Object.entries(items)) {
const keyParts = [item.id, item.pathname, i];
elements.push(
<Link key={keyParts.join('_')} color="gray" size="2" to={item.pathname}>
{item.title}
</Link>,
);
if (item !== items.at(-1)) {
keyParts.push('#connector');
elements.push(
<ChevronRightIcon
key={keyParts.join('_')}
className={styles.connector}
/>,
);
}
}
return (
<Flex align="center" gap="1">
<Flex align="center" height="8" gap="1" px="4" {...props}>
{elements}
</Flex>
);
};

(Breadcrumbs as any).Button = BreadcrumbButton;

export default Breadcrumbs as typeof Breadcrumbs & {
Button: typeof BreadcrumbButton;
};

const Connector = styled(ChevronRightIcon)({
width: 'var(--font-size-2)',
height: 'var(--font-size-2)',
color: 'var(--gray-6)',
});
15 changes: 15 additions & 0 deletions packages/devtools/client/src/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
Link as RouterLink,
LinkProps as RouterLinkProps,
} from '@modern-js/runtime/router';
import { Link as BaseLink } from '@radix-ui/themes';
import type { LinkProps as BaseLinkProps } from '@radix-ui/themes/dist/esm/components/link';

// @ts-expect-error
export interface LinkProps extends BaseLinkProps, RouterLinkProps {}

export const Link: React.FC<LinkProps> = ({ to, children, ...props }) => (
<BaseLink {...props} asChild>
<RouterLink to={to}>{children}</RouterLink>
</BaseLink>
);
20 changes: 20 additions & 0 deletions packages/devtools/client/src/components/NavLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
NavLink as RouterNavLink,
NavLinkProps as RouterNavLinkProps,
} from '@modern-js/runtime/router';
import { Link as BaseLink } from '@radix-ui/themes';
import type { LinkProps as BaseLinkProps } from '@radix-ui/themes/dist/esm/components/link';
import React from 'react';

// @ts-expect-error
export interface NavLinkProps extends RouterNavLinkProps, BaseLinkProps {}

export const NavLink: React.FC<NavLinkProps> = React.forwardRef(
({ to, children, ...props }, ref) => (
<BaseLink {...(props as any)} asChild>
<RouterNavLink ref={ref} to={to}>
{children}
</RouterNavLink>
</BaseLink>
),
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.container {
font-size: var(--font-size-2);
}
10 changes: 3 additions & 7 deletions packages/devtools/client/src/components/ObjectInspector.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { Box } from '@radix-ui/themes';
import type { Theme } from 'react-base16-styling';
import { JSONTree } from 'react-json-tree';
import styles from './ObjectInspector.module.scss';

const theme: Theme = {
scheme: 'tomorrow',
Expand All @@ -24,14 +24,10 @@ const theme: Theme = {
base0F: '#a3685a',
};

const Container = styled(Box)({
fontSize: 'var(--font-size-2)',
});

export const ObjectInspector: typeof JSONTree = props => {
return (
<Container>
<Box className={styles.container}>
<JSONTree theme={theme} {...props} />
</Container>
</Box>
);
};
31 changes: 31 additions & 0 deletions packages/devtools/client/src/components/SelectLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { Select } from '@radix-ui/themes';
import {
NavigateOptions,
matchPath,
useLocation,
useNavigate,
} from '@modern-js/runtime/router';

export interface SelectLinkProps {
items: { to: string; options?: NavigateOptions; title: string }[];
}

export const SelectLink: React.FC<SelectLinkProps> = ({ items }) => {
const navigate = useNavigate();
const loc = useLocation();
const active = items.find(item => matchPath(item.to, loc.pathname));

return (
<Select.Root size="1" value={active?.to} onValueChange={navigate}>
<Select.Trigger />
<Select.Content position="popper">
{items.map(({ title, to }) => (
<Select.Item key={to} value={to}>
{title}
</Select.Item>
))}
</Select.Content>
</Select.Root>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.container {
background-color: var(--gray-1);
border-radius: var(--radius-2);
box-shadow: var(--shadow-4);
}

.trigger {
all: unset;
width: 100%;
display: flex;
gap: var(--space-2);
align-items: center;
cursor: pointer;
& * {
cursor: pointer;
}
}

.content {
padding-top: var(--space-2);
overflow: hidden;
&[data-state='open'] {
animation: slideDown 150ms ease-out;
}
&[data-state='closed'] {
animation: slideUp 150ms ease-out;
}

@keyframes slideDown {
from {
height: 0;
opacity: 0;
}
to {
height: var(--radix-collapsible-content-height);
opacity: 1;
}
}

@keyframes slideUp {
from {
height: var(--radix-collapsible-content-height);
opacity: 1;
}
to {
height: 0;
opacity: 0;
}
}
}

.url-text {
color: var(--gray-12);
font-size: var(--font-size-2);
transition: color 200ms;
}

.mark {
height: var(--font-size-5);
width: var(--font-size-5);
border-radius: var(--radius-2);
display: flex;
justify-content: center;
align-items: center;
transition: background-color 100ms;
background-color: transparent;
&[data-open='true'] {
background-color: var(--gray-4);
}
}
Loading

0 comments on commit 078444a

Please sign in to comment.