Extracted AdminX design system to a separate package (#18878)

refs https://github.com/TryGhost/Product/issues/4105

---

<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 2edba98</samp>

This pull request introduces a new monorepo package called
`admin-x-design`, which contains components, design guidelines and
documentation for building apps in Ghost Admin. It also moves some
existing components and files from the deprecated `admin-x-settings`
package to the new `admin-x-design` package, and updates some styles and
rules to use TailwindCSS. The purpose of these changes is to improve the
consistency, maintainability and usability of the Ghost Admin UI.
This commit is contained in:
Jono M 2023-11-08 12:33:18 +00:00 committed by GitHub
parent 3909de2f17
commit 048dac30ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
414 changed files with 1669 additions and 2150 deletions

View File

@ -50,20 +50,26 @@ const COMMAND_TYPESCRIPT = {
env: {}
};
const COMMAND_ADMINX = {
const COMMANDS_ADMINX = [{
name: 'adminXDS',
command: 'nx watch --projects=apps/admin-x-design -- nx run \\$NX_PROJECT_NAME:build --skip-nx-cache',
cwd: path.resolve(__dirname, '../..'),
prefixColor: '#C35831',
env: {}
}, {
name: 'adminX',
command: 'yarn dev',
command: 'yarn nx build && yarn dev',
cwd: path.resolve(__dirname, '../../apps/admin-x-settings'),
prefixColor: '#C35831',
env: {}
};
}];
if (DASH_DASH_ARGS.includes('ghost')) {
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT];
} else if (DASH_DASH_ARGS.includes('admin')) {
commands = [COMMAND_ADMIN, COMMAND_ADMINX];
commands = [COMMAND_ADMIN, ...COMMANDS_ADMINX];
} else {
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT, COMMAND_ADMIN, COMMAND_ADMINX];
commands = [COMMAND_GHOST, COMMAND_TYPESCRIPT, COMMAND_ADMIN, ...COMMANDS_ADMINX];
}
if (DASH_DASH_ARGS.includes('portal') || DASH_DASH_ARGS.includes('all')) {

View File

@ -0,0 +1,41 @@
module.exports = {
extends: [
'plugin:ghost/ts',
'plugin:react/recommended',
'plugin:react-hooks/recommended'
],
plugins: [
'ghost',
'react-refresh',
'tailwindcss'
],
settings: {
react: {
version: 'detect'
}
},
rules: {
// suppress errors for missing 'import React' in JSX files, as we don't need it
'react/react-in-jsx-scope': 'off',
// ignore prop-types for now
'react/prop-types': 'off',
'react/jsx-sort-props': ['error', {
reservedFirst: true,
callbacksLast: true,
shorthandLast: true,
locale: 'en'
}],
'react/button-has-type': 'error',
'react/no-array-index-key': 'error',
'react/jsx-key': 'off',
'tailwindcss/classnames-order': ['error', {config: 'tailwind.config.cjs'}],
'tailwindcss/enforces-negative-arbitrary-values': ['warn', {config: 'tailwind.config.cjs'}],
'tailwindcss/enforces-shorthand': ['warn', {config: 'tailwind.config.cjs'}],
'tailwindcss/migration-from-tailwind-2': ['warn', {config: 'tailwind.config.cjs'}],
'tailwindcss/no-arbitrary-value': 'off',
'tailwindcss/no-custom-classname': 'off',
'tailwindcss/no-contradicting-classname': ['error', {config: 'tailwind.config.cjs'}]
}
};

2
apps/admin-x-design/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
es
types

View File

@ -1,5 +1,5 @@
import {resolve} from "path";
import type { StorybookConfig } from "@storybook/react-vite";
const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
@ -17,14 +17,11 @@ const config: StorybookConfig = {
docs: {
autodocs: "tag",
},
// staticDirs: ['../public/fonts'],
async viteFinal(config, options) {
config.resolve.alias = {
crypto: require.resolve('rollup-plugin-node-builtins'),
// @TODO: Remove this when @tryghost/nql is updated
mingo: resolve(__dirname, '../../../node_modules/mingo/dist/mingo.js')
async viteFinal(config, options) {
config.resolve!.alias = {
crypto: require.resolve('rollup-plugin-node-builtins')
}
return config;
},
}
};
export default config;

View File

@ -1,13 +1,11 @@
import React from 'react';
import '../src/styles/demo.css';
import type { Preview } from "@storybook/react";
import '../src/admin-x-ds/providers/DesignSystemProvider';
import DesignSystemProvider from '../src/admin-x-ds/providers/DesignSystemProvider';
import adminxTheme from './adminx-theme';
import { themes } from '@storybook/theming';
import '../styles.css';
import './storybook.css';
import '../src/admin-x-ds/assets/styles/storybook.css';
import type { Preview } from "@storybook/react";
import DesignSystemProvider from '../src/providers/DesignSystemProvider';
import adminxTheme from './adminx-theme';
const preview: Preview = {
parameters: {
@ -33,12 +31,12 @@ const preview: Preview = {
let {scheme} = context.globals;
return (
<div className={`admin-x-settings ${scheme === 'dark' ? 'dark' : ''}`} style={{
<div className={`admin-x-design admin-x-base ${scheme === 'dark' ? 'dark' : ''}`} style={{
padding: '24px',
background: (scheme === 'dark' ? '#131416' : '')
}}>
{/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it */}
<DesignSystemProvider>
<DesignSystemProvider fetchKoenigLexical={async () => {}}>
<Story />
</DesignSystemProvider>
</div>);

View File

@ -1,3 +1,32 @@
/*
* We load Inter in Ember admin, so loading it explicitly here makes the final rendering
* in Storybook match the final rendering when embedded in Ember
*/
@font-face {
font-family: "Inter";
src: url("./Inter.ttf") format("truetype-variations");
font-weight: 100 900;
}
:root {
font-size: 62.5%;
line-height: 1.5;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
html, body, #root {
width: 100%;
height: 100%;
margin: 0;
letter-spacing: unset;
}
.sbdocs-wrapper {
padding: 3vmin !important;
}
@ -211,4 +240,4 @@
display: grid;
grid-template-columns: auto 240px;
gap: 32px;
}
}

View File

@ -0,0 +1,23 @@
# Admin X Design
Components, design guidelines and documentation for building apps in Ghost Admin
## Usage
## Develop
This is a monorepo package.
Follow the instructions for the top-level repo.
1. `git clone` this repo & `cd` into it as usual
2. Run `yarn` to install top-level dependencies.
## Test
- `yarn lint` run just eslint
- `yarn test` run lint and tests

View File

@ -0,0 +1,75 @@
{
"name": "@tryghost/admin-x-design",
"type": "module",
"version": "0.0.0",
"repository": "https://github.com/TryGhost/Ghost/tree/main/packages/admin-x-design",
"author": "Ghost Foundation",
"private": true,
"main": "es/index.js",
"types": "types/index.d.ts",
"sideEffects": false,
"scripts": {
"build": "vite build && tsc -p tsconfig.declaration.json",
"prepare": "yarn build",
"test": "yarn test:types",
"test:types": "tsc --noEmit",
"lint:code": "eslint --ext .js,.ts,.cjs,.tsx src/ --cache",
"lint": "yarn lint:code && yarn lint:test",
"lint:test": "eslint -c test/.eslintrc.cjs --ext .js,.ts,.cjs,.tsx test/ --cache",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"files": [
"es",
"types",
"tailwind.cjs",
"tailwind.config.cjs"
],
"devDependencies": {
"@codemirror/lang-html": "^6.4.5",
"@storybook/addon-essentials": "7.4.0",
"@storybook/addon-interactions": "7.4.0",
"@storybook/addon-links": "7.4.0",
"@storybook/addon-styling": "1.3.7",
"@storybook/blocks": "7.4.0",
"@storybook/react": "7.4.0",
"@storybook/react-vite": "7.4.0",
"@storybook/testing-library": "0.2.2",
"@vitejs/plugin-react": "4.1.1",
"c8": "8.0.1",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-react-refresh": "0.4.3",
"eslint-plugin-tailwindcss": "3.13.0",
"mocha": "10.2.0",
"rollup-plugin-node-builtins": "2.1.2",
"sinon": "17.0.0",
"ts-node": "10.9.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"storybook": "7.4.0",
"typescript": "5.2.2",
"vite": "4.5.0",
"vite-plugin-svgr": "3.3.0"
},
"dependencies": {
"@dnd-kit/core": "6.0.8",
"@dnd-kit/sortable": "7.0.2",
"@ebay/nice-modal-react": "1.2.13",
"@sentry/react": "7.77.0",
"@tailwindcss/forms": "0.5.6",
"@tailwindcss/line-clamp": "0.4.4",
"@uiw/react-codemirror": "^4.21.9",
"autoprefixer": "10.4.16",
"clsx": "2.0.0",
"postcss": "8.4.31",
"postcss-import": "15.1.0",
"react-colorful": "^5.1.2",
"react-hot-toast": "2.4.1",
"react-select": "5.8.0",
"tailwindcss": "3.3.5"
},
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}

View File

@ -0,0 +1,8 @@
export default {
plugins: {
'postcss-import': {},
'tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {}
}
};

View File

@ -1,5 +1,4 @@
.admin-x-settings {
.admin-x-base {
/*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
@ -329,7 +328,7 @@
input::placeholder,
textarea::placeholder {
opacity: 1; /* 1 */
color: theme('colors.grey.500'); /* 2 */
@apply text-grey-500; /* 2 */
}
button:focus-visible,
@ -364,5 +363,4 @@
max-width: 100%;
height: auto;
}
}
}

View File

@ -0,0 +1,27 @@
import clsx from 'clsx';
import React from 'react';
import {FetchKoenigLexical} from './global/form/HtmlEditor';
import DesignSystemProvider from './providers/DesignSystemProvider';
export interface DesignSystemAppProps extends React.HTMLProps<HTMLDivElement> {
darkMode: boolean;
fetchKoenigLexical: FetchKoenigLexical;
}
const DesignSystemApp: React.FC<DesignSystemAppProps> = ({darkMode, fetchKoenigLexical, className, children, ...props}) => {
const appClassName = clsx(
'admin-x-base',
darkMode && 'dark',
className
);
return (
<div className={appClassName} {...props}>
<DesignSystemProvider fetchKoenigLexical={fetchKoenigLexical}>
{children}
</DesignSystemProvider>
</div>
);
};
export default DesignSystemApp;

View File

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 401 B

View File

Before

Width:  |  Height:  |  Size: 364 B

After

Width:  |  Height:  |  Size: 364 B

View File

Before

Width:  |  Height:  |  Size: 363 B

After

Width:  |  Height:  |  Size: 363 B

View File

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 608 B

View File

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 403 B

View File

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 402 B

View File

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 451 B

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

View File

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 452 B

View File

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 354 B

View File

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 354 B

View File

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 448 B

View File

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 532 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 851 B

View File

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 608 B

View File

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 423 B

View File

Before

Width:  |  Height:  |  Size: 275 B

After

Width:  |  Height:  |  Size: 275 B

View File

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

View File

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

View File

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

View File

Before

Width:  |  Height:  |  Size: 314 B

After

Width:  |  Height:  |  Size: 314 B

View File

Before

Width:  |  Height:  |  Size: 417 B

After

Width:  |  Height:  |  Size: 417 B

View File

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 352 B

View File

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 502 B

View File

Before

Width:  |  Height:  |  Size: 645 B

After

Width:  |  Height:  |  Size: 645 B

View File

Before

Width:  |  Height:  |  Size: 642 B

After

Width:  |  Height:  |  Size: 642 B

View File

Before

Width:  |  Height:  |  Size: 388 B

After

Width:  |  Height:  |  Size: 388 B

View File

Before

Width:  |  Height:  |  Size: 1019 B

After

Width:  |  Height:  |  Size: 1019 B

View File

Before

Width:  |  Height:  |  Size: 479 B

After

Width:  |  Height:  |  Size: 479 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 347 B

After

Width:  |  Height:  |  Size: 347 B

View File

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 420 B

View File

Before

Width:  |  Height:  |  Size: 827 B

After

Width:  |  Height:  |  Size: 827 B

View File

Before

Width:  |  Height:  |  Size: 587 B

After

Width:  |  Height:  |  Size: 587 B

View File

Before

Width:  |  Height:  |  Size: 469 B

After

Width:  |  Height:  |  Size: 469 B

View File

Before

Width:  |  Height:  |  Size: 848 B

After

Width:  |  Height:  |  Size: 848 B

View File

Before

Width:  |  Height:  |  Size: 904 B

After

Width:  |  Height:  |  Size: 904 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 636 B

After

Width:  |  Height:  |  Size: 636 B

View File

Before

Width:  |  Height:  |  Size: 924 B

After

Width:  |  Height:  |  Size: 924 B

View File

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 741 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 543 B

View File

Before

Width:  |  Height:  |  Size: 547 B

After

Width:  |  Height:  |  Size: 547 B

View File

Before

Width:  |  Height:  |  Size: 436 B

After

Width:  |  Height:  |  Size: 436 B

View File

Before

Width:  |  Height:  |  Size: 698 B

After

Width:  |  Height:  |  Size: 698 B

View File

Before

Width:  |  Height:  |  Size: 906 B

After

Width:  |  Height:  |  Size: 906 B

View File

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 419 B

View File

Before

Width:  |  Height:  |  Size: 977 B

After

Width:  |  Height:  |  Size: 977 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 885 B

After

Width:  |  Height:  |  Size: 885 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 575 B

After

Width:  |  Height:  |  Size: 575 B

View File

Before

Width:  |  Height:  |  Size: 729 B

After

Width:  |  Height:  |  Size: 729 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 827 B

After

Width:  |  Height:  |  Size: 827 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 706 B

View File

Before

Width:  |  Height:  |  Size: 601 B

After

Width:  |  Height:  |  Size: 601 B

View File

Before

Width:  |  Height:  |  Size: 990 B

After

Width:  |  Height:  |  Size: 990 B

View File

Before

Width:  |  Height:  |  Size: 516 B

After

Width:  |  Height:  |  Size: 516 B

View File

Before

Width:  |  Height:  |  Size: 516 B

After

Width:  |  Height:  |  Size: 516 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 631 B

After

Width:  |  Height:  |  Size: 631 B

View File

Before

Width:  |  Height:  |  Size: 176 B

After

Width:  |  Height:  |  Size: 176 B

View File

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 524 B

View File

Before

Width:  |  Height:  |  Size: 825 B

After

Width:  |  Height:  |  Size: 825 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 479 B

After

Width:  |  Height:  |  Size: 479 B

View File

Before

Width:  |  Height:  |  Size: 237 B

After

Width:  |  Height:  |  Size: 237 B

View File

Before

Width:  |  Height:  |  Size: 723 B

After

Width:  |  Height:  |  Size: 723 B

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 607 B

After

Width:  |  Height:  |  Size: 607 B

View File

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 230 B

Some files were not shown because too many files have changed in this diff Show More