This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
const tailwindCssConfig = `${__dirname}/../admin/src/index.css`;
|
||||
|
||||
module.exports = {
|
||||
extends: [
|
||||
'plugin:ghost/ts',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended'
|
||||
],
|
||||
plugins: [
|
||||
'ghost',
|
||||
'react-refresh',
|
||||
'tailwindcss'
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect'
|
||||
},
|
||||
tailwindcss: {
|
||||
config: tailwindCssConfig
|
||||
}
|
||||
},
|
||||
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',
|
||||
|
||||
// Enforce kebab-case (lowercase with hyphens) for all filenames
|
||||
'ghost/filenames/match-regex': ['error', '^[a-z0-9.-]+$', false],
|
||||
|
||||
'tailwindcss/classnames-order': 'error',
|
||||
'tailwindcss/enforces-negative-arbitrary-values': 'warn',
|
||||
'tailwindcss/enforces-shorthand': 'warn',
|
||||
'tailwindcss/migration-from-tailwind-2': 'warn',
|
||||
'tailwindcss/no-arbitrary-value': 'off',
|
||||
'tailwindcss/no-custom-classname': 'off',
|
||||
'tailwindcss/no-contradicting-classname': 'error'
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,2 @@
|
||||
es
|
||||
types
|
||||
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
import {create} from '@storybook/theming/create';
|
||||
|
||||
export default create({
|
||||
base: 'light',
|
||||
// Typography
|
||||
fontBase: '"Inter", sans-serif',
|
||||
fontCode: 'monospace',
|
||||
|
||||
brandTitle: 'AdminX Design System',
|
||||
brandUrl: 'https://ghost.org',
|
||||
brandImage: 'https://github.com/peterzimon/playground/assets/353959/c4358b4e-232f-4dba-8abb-adb3142ccd89',
|
||||
brandTarget: '_self',
|
||||
|
||||
//
|
||||
colorPrimary: '#30CF43',
|
||||
colorSecondary: '#15171A',
|
||||
|
||||
// UI
|
||||
appBg: '#ffffff',
|
||||
appContentBg: '#ffffff',
|
||||
appBorderColor: '#EBEEF0',
|
||||
appBorderRadius: 0,
|
||||
|
||||
// Text colors
|
||||
textColor: '#15171A',
|
||||
textInverseColor: '#ffffff',
|
||||
|
||||
// Toolbar default and active colors
|
||||
barTextColor: '#9E9E9E',
|
||||
barSelectedColor: '#15171A',
|
||||
barBg: '#ffffff',
|
||||
|
||||
// Form colors
|
||||
inputBg: '#ffffff',
|
||||
inputBorder: '#15171A',
|
||||
inputTextColor: '#15171A',
|
||||
inputBorderRadius: 2,
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { StorybookConfig } from "@storybook/react-vite";
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
||||
addons: [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-interactions",
|
||||
{
|
||||
name: '@storybook/addon-styling',
|
||||
},
|
||||
],
|
||||
framework: {
|
||||
name: "@storybook/react-vite",
|
||||
options: {},
|
||||
},
|
||||
docs: {
|
||||
autodocs: "tag",
|
||||
},
|
||||
async viteFinal(config, options) {
|
||||
config.resolve!.alias = {
|
||||
crypto: require.resolve('rollup-plugin-node-builtins')
|
||||
}
|
||||
return config;
|
||||
}
|
||||
};
|
||||
export default config;
|
||||
@@ -0,0 +1,6 @@
|
||||
import {addons} from '@storybook/manager-api';
|
||||
import adminxTheme from './adminx-theme';
|
||||
|
||||
addons.setConfig({
|
||||
theme: adminxTheme
|
||||
});
|
||||
@@ -0,0 +1,107 @@
|
||||
import React from 'react';
|
||||
|
||||
import '../styles.css';
|
||||
import './storybook.css';
|
||||
|
||||
import type { Preview } from "@storybook/react";
|
||||
import DesignSystemProvider from '../src/providers/design-system-provider';
|
||||
import adminxTheme from './adminx-theme';
|
||||
|
||||
// import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport';
|
||||
|
||||
const customViewports = {
|
||||
sm: {
|
||||
name: 'sm',
|
||||
styles: {
|
||||
width: '480px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
md: {
|
||||
name: 'md',
|
||||
styles: {
|
||||
width: '640px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
lg: {
|
||||
name: 'lg',
|
||||
styles: {
|
||||
width: '1024px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
xl: {
|
||||
name: 'xl',
|
||||
styles: {
|
||||
width: '1320px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
tablet: {
|
||||
name: 'tablet',
|
||||
styles: {
|
||||
width: '860px',
|
||||
height: '801px',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
options: {
|
||||
storySort: {
|
||||
method: 'alphabetical',
|
||||
order: ['Welcome', 'Foundations', ['Style Guide', 'Colors', 'Icons', 'ErrorHandling'], 'Global', ['Form', 'Chrome', 'Modal', 'Layout', ['View Container', 'Page Header', 'Page'], 'List', 'Table', '*'], 'Settings', ['Setting Section', 'Setting Group', '*'], 'Experimental'],
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
theme: adminxTheme,
|
||||
},
|
||||
viewport: {
|
||||
viewports: {
|
||||
...customViewports,
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story, context) => {
|
||||
let {scheme} = context.globals;
|
||||
|
||||
return (
|
||||
<div className={`admin-x-design-system admin-x-base ${scheme === 'dark' ? 'dark' : ''}`} style={{
|
||||
// padding: '24px',
|
||||
// width: 'unset',
|
||||
height: 'unset',
|
||||
// overflow: 'unset',
|
||||
background: (scheme === 'dark' ? '#131416' : '')
|
||||
}}>
|
||||
{/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it */}
|
||||
<DesignSystemProvider fetchKoenigLexical={async () => {}}>
|
||||
<Story />
|
||||
</DesignSystemProvider>
|
||||
</div>);
|
||||
},
|
||||
],
|
||||
globalTypes: {
|
||||
scheme: {
|
||||
name: "Scheme",
|
||||
description: "Select light or dark mode",
|
||||
defaultValue: "light",
|
||||
toolbar: {
|
||||
icon: "mirror",
|
||||
items: ["light", "dark"],
|
||||
dynamicTitle: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default preview;
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
.sbdocs-wrapper .sbdocs-content {
|
||||
max-width: 1320px;
|
||||
}
|
||||
|
||||
.sb-doc {
|
||||
max-width: 740px;
|
||||
width: 100%;
|
||||
margin: 0 auto !important;
|
||||
}
|
||||
|
||||
.sb-doc,
|
||||
.sb-doc a,
|
||||
.sb-doc h1,
|
||||
.sb-doc h2,
|
||||
.sb-doc h3,
|
||||
.sb-doc h4,
|
||||
.sb-doc h5,
|
||||
.sb-doc h6,
|
||||
.sb-doc p,
|
||||
.sb-doc ul li,
|
||||
.sbdocs-title,
|
||||
.sb-doc ol li {
|
||||
font-family: Inter, sans-serif !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.sb-doc a {
|
||||
color: #30CF43;
|
||||
}
|
||||
|
||||
.sb-doc h1 {
|
||||
font-size: 48px !important;
|
||||
letter-spacing: -0.04em !important;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.sb-doc h2 {
|
||||
margin-top: 40px !important;
|
||||
font-size: 27px;
|
||||
border: none;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.sb-doc h3 {
|
||||
margin-top: 40px !important;
|
||||
margin-bottom: 4px !important;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.sb-doc h4 {
|
||||
margin: 0 0 4px !important;
|
||||
}
|
||||
|
||||
.sb-doc p,
|
||||
.sb-doc div,
|
||||
.sb-doc ul li,
|
||||
.sb-doc ol li {
|
||||
font-size: 15px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.sb-doc ul li,
|
||||
.sb-doc ol li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sb-doc h2 + p,
|
||||
.sb-doc h3 + p {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.sb-doc img,
|
||||
.sb-wide img {
|
||||
margin-top: 40px !important;
|
||||
margin-bottom: 40px !important;
|
||||
}
|
||||
|
||||
.sb-doc img.small {
|
||||
max-width: 520px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sb-doc p.excerpt {
|
||||
font-size: 19px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.sb-doc .highlight {
|
||||
padding: 12px 20px;
|
||||
border-radius: 4px;
|
||||
background: #EBEEF0;
|
||||
}
|
||||
|
||||
.sb-doc .highlight.purple {
|
||||
background: #F0E9FA;
|
||||
}
|
||||
|
||||
.sb-doc .highlight.purple a {
|
||||
color: #8E42FF;
|
||||
}
|
||||
|
||||
/* Welcome */
|
||||
.sb-doc img.main-image {
|
||||
margin-top: -2vmin !important;
|
||||
margin-left: -44px;
|
||||
margin-right: -32px;
|
||||
margin-bottom: 0 !important;
|
||||
max-width: unset;
|
||||
width: calc(100% + 64px);
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
margin: 32px 0 80px;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div {
|
||||
flex-basis: 33%;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div p {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container img {
|
||||
margin: 12px 0 !important;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div h4 {
|
||||
border-bottom: 1px solid #EBEEF0;
|
||||
padding-bottom: 8px !important;
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.sb-doc .main-structure-container div p {
|
||||
margin: 0;
|
||||
font-size: 13.5px;
|
||||
}
|
||||
|
||||
/* Colors */
|
||||
.color-grid {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.color-grid div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #EBEEF0;
|
||||
}
|
||||
|
||||
.color-grid .swatch {
|
||||
display: block;
|
||||
background: #EFEFEF;
|
||||
border-radius: 100%;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.swatch.green {
|
||||
background: #30CF43;
|
||||
}
|
||||
|
||||
.swatch.black {
|
||||
background: #15171A;
|
||||
}
|
||||
|
||||
.swatch.white {
|
||||
background: #FFFFFF;
|
||||
border: 1px solid #EBEEF0;
|
||||
}
|
||||
|
||||
.swatch.lime {
|
||||
background: #B5FF18;
|
||||
}
|
||||
.swatch.blue {
|
||||
background: #14B8FF;
|
||||
}
|
||||
.swatch.purple {
|
||||
background: #8E42FF;
|
||||
}
|
||||
.swatch.pink {
|
||||
background: #FB2D8D;
|
||||
}
|
||||
.swatch.yellow {
|
||||
background: #FFB41F;
|
||||
}
|
||||
.swatch.red {
|
||||
background: #F50B23;
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
|
||||
.sb-doc .streamline {
|
||||
display: grid;
|
||||
grid-template-columns: auto 240px;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.sbdocs-a {
|
||||
color: #30CF43 !important;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Admin X Design
|
||||
|
||||
Components, design guidelines and documentation for building apps in Ghost Admin
|
||||
|
||||
## 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 `pnpm` to install top-level dependencies.
|
||||
|
||||
## Test
|
||||
|
||||
- `pnpm lint` run just eslint
|
||||
- `pnpm test` run lint and tests
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"name": "@tryghost/admin-x-design-system",
|
||||
"type": "module",
|
||||
"version": "0.0.0",
|
||||
"repository": "https://github.com/TryGhost/Ghost/tree/main/packages/admin-x-design-system",
|
||||
"author": "Ghost Foundation",
|
||||
"private": true,
|
||||
"main": "es/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"dev": "vite build --watch",
|
||||
"build": "tsc -p tsconfig.declaration.json && vite build",
|
||||
"test": "pnpm test:unit",
|
||||
"test:unit": "pnpm test:types && vitest run",
|
||||
"test:types": "tsc --noEmit",
|
||||
"lint:code": "eslint --ext .js,.ts,.cjs,.tsx src/ --cache",
|
||||
"lint": "pnpm lint:code && pnpm 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"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@codemirror/lang-html": "6.4.11",
|
||||
"@codemirror/state": "6.6.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@radix-ui/react-tooltip": "1.2.8",
|
||||
"@storybook/addon-essentials": "8.6.14",
|
||||
"@storybook/addon-interactions": "8.6.14",
|
||||
"@storybook/addon-links": "8.6.14",
|
||||
"@storybook/addon-styling": "1.3.7",
|
||||
"@storybook/blocks": "8.6.14",
|
||||
"@storybook/preview-api": "^8.6.14",
|
||||
"@storybook/react": "8.6.14",
|
||||
"@storybook/react-vite": "8.6.14",
|
||||
"@storybook/testing-library": "0.2.2",
|
||||
"@tailwindcss/postcss": "4.2.1",
|
||||
"@testing-library/react": "14.3.1",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/react": "18.3.28",
|
||||
"@types/react-dom": "18.3.7",
|
||||
"@types/validator": "13.15.10",
|
||||
"@vitejs/plugin-react": "4.7.0",
|
||||
"autoprefixer": "10.4.21",
|
||||
"c8": "10.1.3",
|
||||
"chai": "4.5.0",
|
||||
"eslint": "catalog:",
|
||||
"eslint-plugin-react-hooks": "4.6.2",
|
||||
"eslint-plugin-react-refresh": "0.4.24",
|
||||
"eslint-plugin-tailwindcss": "4.0.0-beta.0",
|
||||
"glob": "^10.5.0",
|
||||
"jsdom": "28.1.0",
|
||||
"lodash-es": "4.18.1",
|
||||
"postcss": "8.5.6",
|
||||
"postcss-import": "16.1.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"rollup-plugin-node-builtins": "2.1.2",
|
||||
"sinon": "18.0.1",
|
||||
"storybook": "8.6.15",
|
||||
"tailwindcss": "4.2.1",
|
||||
"typescript": "5.9.3",
|
||||
"validator": "13.12.0",
|
||||
"vite": "5.4.21",
|
||||
"vite-plugin-svgr": "3.3.0",
|
||||
"vitest": "1.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "6.3.1",
|
||||
"@dnd-kit/sortable": "7.0.2",
|
||||
"@ebay/nice-modal-react": "1.2.13",
|
||||
"@radix-ui/react-avatar": "1.1.11",
|
||||
"@radix-ui/react-checkbox": "1.3.3",
|
||||
"@radix-ui/react-form": "0.1.8",
|
||||
"@radix-ui/react-popover": "1.1.15",
|
||||
"@radix-ui/react-radio-group": "1.3.8",
|
||||
"@radix-ui/react-separator": "1.1.8",
|
||||
"@radix-ui/react-switch": "1.2.6",
|
||||
"@radix-ui/react-tabs": "1.1.13",
|
||||
"@radix-ui/react-tooltip": "1.2.8",
|
||||
"@sentry/react": "7.120.4",
|
||||
"@tryghost/shade": "workspace:*",
|
||||
"@uiw/react-codemirror": "4.25.2",
|
||||
"clsx": "2.1.1",
|
||||
"react-colorful": "5.6.1",
|
||||
"react-hot-toast": "2.6.0",
|
||||
"react-select": "5.10.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"nx": {
|
||||
"targets": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
},
|
||||
"test:unit": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-import': {},
|
||||
'@tailwindcss/postcss': {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,381 @@
|
||||
.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)
|
||||
*/
|
||||
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box; /* 1 */
|
||||
max-width: revert;
|
||||
max-height: revert;
|
||||
min-width: revert;
|
||||
min-height: revert;
|
||||
border-width: 0; /* 2 */
|
||||
border-style: solid; /* 2 */
|
||||
border-color: theme('borderColor.DEFAULT', currentColor); /* 2 */
|
||||
}
|
||||
|
||||
::before,
|
||||
::after {
|
||||
--tw-content: '';
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use a consistent sensible line-height in all browsers.
|
||||
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
3. Use a more readable tab size.
|
||||
4. Use the user's configured `sans` font-family by default.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.5; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-moz-tab-size: 4; /* 3 */
|
||||
tab-size: 4; /* 3 */
|
||||
font-family: theme('fontFamily.sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); /* 4 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove the margin in all browsers.
|
||||
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0; /* 1 */
|
||||
line-height: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Add the correct height in Firefox.
|
||||
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||
3. Ensure horizontal rules are visible by default.
|
||||
*/
|
||||
|
||||
hr {
|
||||
height: 0; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
border-top-width: 1px; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
abbr:where([title]) {
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the default font size and weight for headings.
|
||||
*/
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Reset links to optimize for opt-in styling instead of opt-out.
|
||||
*/
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font weight in Edge and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use the user's configured `mono` font family by default.
|
||||
2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp,
|
||||
pre {
|
||||
font-family: theme('fontFamily.mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace); /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
||||
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||
3. Remove gaps between table borders by default.
|
||||
*/
|
||||
|
||||
table {
|
||||
text-indent: 0; /* 1 */
|
||||
border-color: inherit; /* 2 */
|
||||
border-collapse: collapse; /* 3 */
|
||||
margin: 0;
|
||||
width: auto;
|
||||
max-width: auto;
|
||||
}
|
||||
|
||||
table td, table th {
|
||||
padding: unset;
|
||||
vertical-align: middle;
|
||||
text-align: left;
|
||||
line-height: auto;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Change the font styles in all browsers.
|
||||
2. Remove the margin in Firefox and Safari.
|
||||
3. Remove default padding in all browsers.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
font-weight: inherit; /* 1 */
|
||||
line-height: inherit; /* 1 */
|
||||
color: inherit; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
padding: 0; /* 3 */
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inheritance of text transform in Edge and Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
letter-spacing: inherit;
|
||||
border-radius: inherit;
|
||||
appearance: auto;
|
||||
-webkit-appearance: auto;
|
||||
background: unset;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Remove default button styles.
|
||||
*/
|
||||
|
||||
button,
|
||||
/* [type='button'], */
|
||||
[type='reset'],
|
||||
[type='submit'] {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
background-color: transparent; /* 2 */
|
||||
background-image: none; /* 2 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Use the modern Firefox focus style for all focusable elements.
|
||||
*/
|
||||
|
||||
:-moz-focusring {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
||||
*/
|
||||
|
||||
:-moz-ui-invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct vertical alignment in Chrome and Firefox.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/*
|
||||
Correct the cursor style of increment and decrement buttons in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-inner-spin-button,
|
||||
::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the odd appearance in Chrome and Safari.
|
||||
2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type='search'] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct display in Chrome and Safari.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/*
|
||||
Removes the default spacing and border for appropriate elements.
|
||||
*/
|
||||
|
||||
blockquote,
|
||||
dl,
|
||||
dd,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
hr,
|
||||
figure,
|
||||
p,
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: unset;
|
||||
line-height: unset;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent resizing textareas horizontally by default.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
||||
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||
*/
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
opacity: 1; /* 1 */
|
||||
@apply text-grey-500; /* 2 */
|
||||
}
|
||||
|
||||
button:focus-visible,
|
||||
input:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
||||
This can trigger a poorly considered lint error in some tools but is included by design.
|
||||
*/
|
||||
|
||||
img,
|
||||
svg,
|
||||
video,
|
||||
canvas,
|
||||
audio,
|
||||
iframe,
|
||||
embed,
|
||||
object {
|
||||
display: block; /* 1 */
|
||||
vertical-align: middle; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
*/
|
||||
|
||||
img,
|
||||
video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import type {Meta, StoryObj} from '@storybook/react';
|
||||
|
||||
import BoilerPlate from './boilerplate';
|
||||
|
||||
const meta = {
|
||||
title: 'Meta / Boilerplate',
|
||||
component: BoilerPlate,
|
||||
tags: ['autodocs']
|
||||
} satisfies Meta<typeof BoilerPlate>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof BoilerPlate>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
children: 'This is a boilerplate component. Use as a basis to create new components.'
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
interface BoilerPlateProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const BoilerPlate: React.FC<BoilerPlateProps> = ({children}) => {
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default BoilerPlate;
|
||||
@@ -0,0 +1,26 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import {FetchKoenigLexical} from './global/form/html-editor';
|
||||
import DesignSystemProvider from './providers/design-system-provider';
|
||||
|
||||
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',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={appClassName} {...props}>
|
||||
<DesignSystemProvider darkMode={darkMode} fetchKoenigLexical={fetchKoenigLexical}>
|
||||
{children}
|
||||
</DesignSystemProvider>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DesignSystemApp;
|
||||
@@ -0,0 +1,177 @@
|
||||
export {ReactComponent as FacebookLogo} from './assets/images/facebook-logo.svg';
|
||||
export {ReactComponent as GhostLogo} from './assets/images/ghost-logo.svg';
|
||||
export {ReactComponent as GhostOrb} from './assets/images/ghost-orb.svg';
|
||||
export {ReactComponent as GoogleLogo} from './assets/images/google-logo.svg';
|
||||
export {ReactComponent as TwitterLogo} from './assets/images/twitter-logo.svg';
|
||||
export {ReactComponent as XLogo} from './assets/images/x-logo.svg';
|
||||
|
||||
export {default as DesktopChrome} from './global/chrome/desktop-chrome';
|
||||
export type {DesktopChromeProps} from './global/chrome/desktop-chrome';
|
||||
export {default as DesktopChromeHeader} from './global/chrome/desktop-chrome-header';
|
||||
export type {DesktopChromeHeaderProps} from './global/chrome/desktop-chrome-header';
|
||||
export {default as MobileChrome} from './global/chrome/mobile-chrome';
|
||||
export type {MobileChromeProps} from './global/chrome/mobile-chrome';
|
||||
|
||||
export {default as Checkbox} from './global/form/checkbox';
|
||||
export type {CheckboxProps} from './global/form/checkbox';
|
||||
export {default as CheckboxGroup} from './global/form/checkbox-group';
|
||||
export type {CheckboxGroupProps} from './global/form/checkbox-group';
|
||||
export {default as CodeEditor} from './global/form/code-editor';
|
||||
export type {CodeEditorProps, FetchKoenigLexical} from './global/form/code-editor';
|
||||
export {default as ColorIndicator} from './global/form/color-indicator';
|
||||
export type {ColorIndicatorProps} from './global/form/color-indicator';
|
||||
export {default as ColorPicker} from './global/form/color-picker';
|
||||
export type {ColorPickerProps} from './global/form/color-picker';
|
||||
export {default as ColorPickerField} from './global/form/color-picker-field';
|
||||
export type {ColorPickerFieldProps} from './global/form/color-picker-field';
|
||||
export {default as CurrencyField} from './global/form/currency-field';
|
||||
export type {CurrencyFieldProps} from './global/form/currency-field';
|
||||
export {default as FileUpload} from './global/form/file-upload';
|
||||
export type {FileUploadProps} from './global/form/file-upload';
|
||||
export {default as Form} from './global/form/form';
|
||||
export type {FormProps} from './global/form/form';
|
||||
export {default as HtmlEditor} from './global/form/html-editor';
|
||||
export type {HtmlEditorProps} from './global/form/html-editor';
|
||||
export {default as HtmlField} from './global/form/html-field';
|
||||
export type {HtmlFieldProps} from './global/form/html-field';
|
||||
export {default as KoenigEditorBase, loadKoenig} from './global/form/koenig-editor-base';
|
||||
export type {KoenigEditorBaseProps, KoenigInstance, NodeType} from './global/form/koenig-editor-base';
|
||||
export {default as ImageUpload} from './global/form/image-upload';
|
||||
export type {ImageUploadProps} from './global/form/image-upload';
|
||||
export {default as MultiSelect} from './global/form/multi-select';
|
||||
export type {LoadMultiSelectOptions, MultiSelectOption, MultiSelectProps} from './global/form/multi-select';
|
||||
export {default as Radio} from './global/form/radio';
|
||||
export type {RadioProps} from './global/form/radio';
|
||||
export {default as Select} from './global/form/select';
|
||||
export type {LoadSelectOptions, SelectOption, SelectOptionGroup, SelectProps} from './global/form/select';
|
||||
export {default as SelectWithOther} from './global/form/select-with-other';
|
||||
export type {SelectWithOtherProps} from './global/form/select-with-other';
|
||||
export {default as TextArea} from './global/form/text-area';
|
||||
export type {TextAreaProps} from './global/form/text-area';
|
||||
export {default as TextField} from './global/form/text-field';
|
||||
export type {TextFieldProps} from './global/form/text-field';
|
||||
export {default as Toggle} from './global/form/toggle';
|
||||
export type {ToggleProps} from './global/form/toggle';
|
||||
export {default as ToggleGroup} from './global/form/toggle-group';
|
||||
export type {ToggleGroupProps} from './global/form/toggle-group';
|
||||
export {default as URLTextField} from './global/form/url-text-field';
|
||||
export type {URLTextFieldProps} from './global/form/url-text-field';
|
||||
|
||||
export {default as ConfirmationModal, ConfirmationModalContent} from './global/modal/confirmation-modal';
|
||||
export type {ConfirmationModalProps} from './global/modal/confirmation-modal';
|
||||
export {default as LimitModal, LimitModalContent} from './global/modal/limit-modal';
|
||||
export type {LimitModalProps} from './global/modal/limit-modal';
|
||||
export {default as Modal, topLevelBackdropClasses} from './global/modal/modal';
|
||||
export type {ModalProps} from './global/modal/modal';
|
||||
export {default as ModalPage} from './global/modal/modal-page';
|
||||
export type {ModalPageProps} from './global/modal/modal-page';
|
||||
export {default as PreviewModal, PreviewModalContent} from './global/modal/preview-modal';
|
||||
export type {PreviewModalProps} from './global/modal/preview-modal';
|
||||
|
||||
export {default as Avatar} from './global/avatar';
|
||||
export type {AvatarProps} from './global/avatar';
|
||||
export {default as Banner} from './global/banner';
|
||||
export type {BannerProps} from './global/banner';
|
||||
export {default as Breadcrumbs} from './global/breadcrumbs';
|
||||
export type {BreadcrumbItem, BreadcrumbsProps} from './global/breadcrumbs';
|
||||
export {default as Button} from './global/button';
|
||||
export type {ButtonColor, ButtonProps} from './global/button';
|
||||
export {default as ButtonGroup} from './global/button-group';
|
||||
export type {ButtonGroupProps} from './global/button-group';
|
||||
export {default as ErrorBoundary, withErrorBoundary} from './global/error-boundary';
|
||||
export type {ErrorBoundaryProps} from './global/error-boundary';
|
||||
export {default as Heading} from './global/heading';
|
||||
export type {HeadingProps} from './global/heading';
|
||||
export {default as Hint} from './global/hint';
|
||||
export type {HintProps} from './global/hint';
|
||||
export {default as Icon} from './global/icon';
|
||||
export type {IconProps} from './global/icon';
|
||||
export {default as IconLabel} from './global/icon-label';
|
||||
export type {IconLabelProps} from './global/icon-label';
|
||||
export {default as InfiniteScrollListener} from './global/infinite-scroll-listener';
|
||||
export type {InfiniteScrollListenerProps} from './global/infinite-scroll-listener';
|
||||
export {default as Link} from './global/link';
|
||||
export type {LinkProps} from './global/link';
|
||||
export {default as List} from './global/list';
|
||||
export type {ListProps} from './global/list';
|
||||
export {default as ListHeading} from './global/list-heading';
|
||||
export type {ListHeadingProps} from './global/list-heading';
|
||||
export {default as ListItem} from './global/list-item';
|
||||
export type {ListItemProps} from './global/list-item';
|
||||
export {LoadingIndicator} from './global/loading-indicator';
|
||||
export type {LoadingIndicatorProps} from './global/loading-indicator';
|
||||
export {default as Menu} from './global/menu';
|
||||
export type {MenuItem, MenuProps} from './global/menu';
|
||||
export {default as NoValueLabel} from './global/no-value-label';
|
||||
export type {NoValueLabelProps} from './global/no-value-label';
|
||||
export {default as Pagination} from './global/pagination';
|
||||
export type {PaginationProps} from './global/pagination';
|
||||
export {default as Popover} from './global/popover';
|
||||
export type {PopoverProps} from './global/popover';
|
||||
export {default as Separator} from './global/separator';
|
||||
export type {SeparatorProps} from './global/separator';
|
||||
export {DragIndicator, default as SortableList} from './global/sortable-list';
|
||||
export type {DragIndicatorProps, SortableItemContainerProps, SortableListProps} from './global/sortable-list';
|
||||
export {default as SortMenu} from './global/sort-menu';
|
||||
export type {SortMenuProps} from './global/sort-menu';
|
||||
export {default as StickyFooter} from './global/sticky-footer';
|
||||
export type {StickyFooterProps} from './global/sticky-footer';
|
||||
export {default as TabView} from './global/tab-view';
|
||||
export type {Tab, TabViewProps} from './global/tab-view';
|
||||
export {default as Table} from './global/table';
|
||||
export type {ShowMoreData, TableProps} from './global/table';
|
||||
export {default as TableCell} from './global/table-cell';
|
||||
export type {TableCellProps} from './global/table-cell';
|
||||
export {default as TableHead} from './global/table-head';
|
||||
export type {TableHeadProps} from './global/table-head';
|
||||
export {default as TableRow} from './global/table-row';
|
||||
export type {TableRowProps} from './global/table-row';
|
||||
export {default as Toast, dismissAllToasts, showToast} from './global/toast';
|
||||
export type {ToastProps} from './global/toast';
|
||||
export {default as Tooltip} from './global/tooltip';
|
||||
export type {TooltipProps} from './global/tooltip';
|
||||
export {default as PageHeader} from './global/layout/page-header';
|
||||
export type {PageHeaderProps} from './global/layout/page-header';
|
||||
export {default as Page} from './global/layout/page';
|
||||
export type {PageTab} from './global/layout/page';
|
||||
export type {CustomGlobalAction} from './global/layout/page';
|
||||
export {default as ViewContainer} from './global/layout/view-container';
|
||||
export type {View} from './global/layout/view-container';
|
||||
export type {ViewTab} from './global/layout/view-container';
|
||||
export type {PrimaryActionProps} from './global/layout/view-container';
|
||||
export {default as DynamicTable} from './global/table/dynamic-table';
|
||||
export type {DynamicTableProps} from './global/table/dynamic-table';
|
||||
export type {DynamicTableColumn} from './global/table/dynamic-table';
|
||||
export type {DynamicTableRow} from './global/table/dynamic-table';
|
||||
|
||||
export {default as SettingGroup} from './settings/setting-group';
|
||||
export type {SettingGroupProps} from './settings/setting-group';
|
||||
export {default as SettingGroupContent} from './settings/setting-group-content';
|
||||
export type {SettingGroupContentProps} from './settings/setting-group-content';
|
||||
export {default as SettingGroupHeader} from './settings/setting-group-header';
|
||||
export type {SettingGroupHeaderProps} from './settings/setting-group-header';
|
||||
export {default as SettingNavItem} from './settings/setting-nav-item';
|
||||
export type {SettingNavItemProps} from './settings/setting-nav-item';
|
||||
export {default as SettingNavSection} from './settings/setting-nav-section';
|
||||
export type {SettingNavSectionProps} from './settings/setting-nav-section';
|
||||
export {default as SettingSection} from './settings/setting-section';
|
||||
export type {SettingSectionProps} from './settings/setting-section';
|
||||
export {default as SettingSectionHeader} from './settings/setting-section-header';
|
||||
export type {SettingSectionHeaderProps} from './settings/setting-section-header';
|
||||
export {default as SettingValue} from './settings/setting-value';
|
||||
export type {SettingValueProps} from './settings/setting-value';
|
||||
export {default as StripeButton} from './settings/stripe-button';
|
||||
export type {StripeButtonProps} from './settings/stripe-button';
|
||||
|
||||
export {default as useGlobalDirtyState} from './hooks/use-global-dirty-state';
|
||||
export {usePagination} from './hooks/use-pagination';
|
||||
export type {PaginationData} from './hooks/use-pagination';
|
||||
export {default as useSortableIndexedList} from './hooks/use-sortable-indexed-list';
|
||||
|
||||
export {debounce} from './utils/debounce';
|
||||
export {confirmIfDirty} from './utils/modals';
|
||||
export {formatUrl} from './utils/format-url';
|
||||
|
||||
export {default as DesignSystemApp} from './design-system-app';
|
||||
export type {DesignSystemAppProps} from './design-system-app';
|
||||
export {useFocusContext, useDesignSystem} from './providers/design-system-provider';
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
declare module '*.svg' {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
import React = require('react');
|
||||
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
@import './preflight.css';
|
||||
|
||||
@import 'tailwindcss/theme.css';
|
||||
@import '@tryghost/shade/tailwind.theme.css';
|
||||
|
||||
@import url(https://fonts.bunny.net/css?family=cardo:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=manrope:300,500,700);
|
||||
@import url(https://fonts.bunny.net/css?family=merriweather:300,700);
|
||||
@import url(https://fonts.bunny.net/css?family=nunito:400,600,700);
|
||||
@import url(https://fonts.bunny.net/css?family=old-standard-tt:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=prata:400);
|
||||
@import url(https://fonts.bunny.net/css?family=roboto:400,500,700);
|
||||
@import url(https://fonts.bunny.net/css?family=rufina:400,500,700);
|
||||
@import url(https://fonts.bunny.net/css?family=tenor-sans:400);
|
||||
@import url(https://fonts.bunny.net/css?family=space-grotesk:700);
|
||||
@import url(https://fonts.bunny.net/css?family=chakra-petch:400);
|
||||
@import url(https://fonts.bunny.net/css?family=noto-sans:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=poppins:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=fira-sans:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=inter:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=noto-serif:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=lora:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=ibm-plex-serif:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=space-mono:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=fira-mono:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=jetbrains-mono:400,700);
|
||||
|
||||
/* Defaults */
|
||||
@layer base {
|
||||
/* This just serves as a placeholder; we actually load Inter from a font file in Ember admin */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: local("Inter") format("truetype-variations");
|
||||
font-weight: 100 900;
|
||||
}
|
||||
|
||||
.admin-x-base {
|
||||
& {
|
||||
@apply font-sans text-black text-base leading-normal;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
@apply font-bold tracking-tight leading-tighter;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-4xl leading-supertight;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply text-2xl;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@apply text-xl;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@apply text-lg;
|
||||
}
|
||||
|
||||
h5 {
|
||||
@apply text-md leading-supertight;
|
||||
}
|
||||
|
||||
h6 {
|
||||
@apply text-md leading-normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-x-base {
|
||||
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%;
|
||||
letter-spacing: unset;
|
||||
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Used to be for fixed bottom mobile menu bar
|
||||
@media (max-width: 800px) {
|
||||
.admin-x-base {
|
||||
height: calc(100vh - 55px);
|
||||
}
|
||||
} */
|
||||
|
||||
.dark .admin-x-base {
|
||||
color: #FAFAFB;
|
||||
}
|
||||
|
||||
.dark .admin-x-base .gh-loading-orb-container {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.dark .admin-x-base .gh-loading-orb {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.admin-x-base .no-scrollbar::-webkit-scrollbar {
|
||||
display: none; /* Chrome */
|
||||
}
|
||||
|
||||
.admin-x-base .no-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
/* Prose classes are for formatting arbitrary HTML that comes from the API */
|
||||
.gh-prose-links a {
|
||||
color: #30CF43;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
@import './preflight.css';
|
||||
|
||||
@import 'tailwindcss/theme.css';
|
||||
@import '@tryghost/shade/tailwind.theme.css';
|
||||
@import 'tailwindcss/utilities.css';
|
||||
|
||||
@import url(https://fonts.bunny.net/css?family=cardo:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=manrope:300,500,700);
|
||||
@import url(https://fonts.bunny.net/css?family=merriweather:300,700);
|
||||
@import url(https://fonts.bunny.net/css?family=nunito:400,600,700);
|
||||
@import url(https://fonts.bunny.net/css?family=old-standard-tt:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=prata:400);
|
||||
@import url(https://fonts.bunny.net/css?family=roboto:400,500,700);
|
||||
@import url(https://fonts.bunny.net/css?family=rufina:400,500,700);
|
||||
@import url(https://fonts.bunny.net/css?family=tenor-sans:400);
|
||||
@import url(https://fonts.bunny.net/css?family=space-grotesk:700);
|
||||
@import url(https://fonts.bunny.net/css?family=chakra-petch:400);
|
||||
@import url(https://fonts.bunny.net/css?family=noto-sans:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=poppins:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=fira-sans:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=inter:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=noto-serif:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=lora:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=ibm-plex-serif:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=space-mono:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=fira-mono:400,700);
|
||||
@import url(https://fonts.bunny.net/css?family=jetbrains-mono:400,700);
|
||||
|
||||
/* Defaults */
|
||||
@layer base {
|
||||
/* This just serves as a placeholder; we actually load Inter from a font file in Ember admin */
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
src: local("Inter") format("truetype-variations");
|
||||
font-weight: 100 900;
|
||||
}
|
||||
|
||||
.admin-x-base {
|
||||
& {
|
||||
@apply font-sans text-black text-base leading-normal;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
@apply font-bold tracking-tight leading-tighter;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-4xl leading-supertight;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@apply text-2xl;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@apply text-xl;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@apply text-lg;
|
||||
}
|
||||
|
||||
h5 {
|
||||
@apply text-md leading-supertight;
|
||||
}
|
||||
|
||||
h6 {
|
||||
@apply text-md leading-normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-x-base {
|
||||
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%;
|
||||
letter-spacing: unset;
|
||||
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Used to be for fixed bottom mobile menu bar
|
||||
@media (max-width: 800px) {
|
||||
.admin-x-base {
|
||||
height: calc(100vh - 55px);
|
||||
}
|
||||
} */
|
||||
|
||||
.dark .admin-x-base {
|
||||
color: #FAFAFB;
|
||||
}
|
||||
|
||||
.dark .admin-x-base .gh-loading-orb-container {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.dark .admin-x-base .gh-loading-orb {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.admin-x-base .no-scrollbar::-webkit-scrollbar {
|
||||
display: none; /* Chrome */
|
||||
}
|
||||
|
||||
.admin-x-base .no-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
/* Prose classes are for formatting arbitrary HTML that comes from the API */
|
||||
.gh-prose-links a {
|
||||
color: #30CF43;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['ghost'],
|
||||
extends: [
|
||||
'plugin:ghost/test'
|
||||
],
|
||||
rules: {
|
||||
// Enforce kebab-case (lowercase with hyphens) for all filenames
|
||||
'ghost/filenames/match-regex': ['error', '^[a-z0-9.-]+$', false]
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": false,
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"declarationDir": "./types",
|
||||
"emitDeclarationOnly": true,
|
||||
"tsBuildInfoFile": "./types/tsconfig.tsbuildinfo",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["src/**/*.stories.tsx", "src/**/*.test.ts", "src/**/*.test.tsx"]
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"types": ["vite/client"],
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts", "package.json"]
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import react from '@vitejs/plugin-react';
|
||||
import {globSync} from 'glob';
|
||||
import {resolve} from 'path';
|
||||
import svgr from 'vite-plugin-svgr';
|
||||
import {defineConfig} from 'vitest/config';
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default (function viteConfig() {
|
||||
return defineConfig({
|
||||
logLevel: process.env.CI ? 'info' : 'warn',
|
||||
plugins: [
|
||||
svgr(),
|
||||
react()
|
||||
],
|
||||
define: {
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
||||
'process.env.VITEST_SEGFAULT_RETRY': 3
|
||||
},
|
||||
preview: {
|
||||
port: 4174
|
||||
},
|
||||
build: {
|
||||
reportCompressedSize: false,
|
||||
minify: false,
|
||||
sourcemap: true,
|
||||
outDir: 'es',
|
||||
lib: {
|
||||
formats: ['es'],
|
||||
entry: globSync(resolve(__dirname, 'src/**/*.{ts,tsx}')).reduce((entries, path) => {
|
||||
if (path.includes('.stories.') || path.endsWith('.d.ts')) {
|
||||
return entries;
|
||||
}
|
||||
|
||||
const outPath = path.replace(resolve(__dirname, 'src') + '/', '').replace(/\.(ts|tsx)$/, '');
|
||||
entries[outPath] = path;
|
||||
return entries;
|
||||
}, {} as Record<string, string>)
|
||||
},
|
||||
commonjsOptions: {
|
||||
include: [/packages/, /node_modules/]
|
||||
},
|
||||
rollupOptions: {
|
||||
external: (source) => {
|
||||
if (source.startsWith('.')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source.includes('node_modules')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return !source.includes(__dirname);
|
||||
}
|
||||
}
|
||||
},
|
||||
test: {
|
||||
globals: true, // required for @testing-library/jest-dom extensions
|
||||
environment: 'jsdom',
|
||||
include: ['./test/unit/**/*'],
|
||||
testTimeout: process.env.TIMEOUT ? parseInt(process.env.TIMEOUT) : 10000,
|
||||
...(process.env.CI && { // https://github.com/vitest-dev/vitest/issues/1674
|
||||
minThreads: 1,
|
||||
maxThreads: 2
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user