AdminX storybook updates (#18503)
refs. https://github.com/TryGhost/Product/issues/3949
38
apps/admin-x-settings/.storybook/adminx-theme.tsx
Normal file
@ -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,
|
||||
});
|
6
apps/admin-x-settings/.storybook/manager.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import {addons} from '@storybook/manager-api';
|
||||
import adminxTheme from './adminx-theme';
|
||||
|
||||
addons.setConfig({
|
||||
theme: adminxTheme
|
||||
});
|
@ -4,6 +4,10 @@ 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 '../src/admin-x-ds/assets/styles/storybook.css';
|
||||
|
||||
const preview: Preview = {
|
||||
parameters: {
|
||||
@ -17,9 +21,12 @@ const preview: Preview = {
|
||||
options: {
|
||||
storySort: {
|
||||
mathod: 'alphabetical',
|
||||
order: ['Global', ['Chrome', 'Form', 'Modal', 'Layout', 'List', '*'], 'Settings', ['Setting Section', 'Setting Group', '*'], 'Experimental'],
|
||||
order: ['Welcome', 'Foundations', ['Style Guide', 'Colors', 'Icons', 'ErrorHandling'], 'Global', ['Form', 'Chrome', 'Modal', 'Layout', 'List', 'Table', '*'], 'Settings', ['Setting Section', 'Setting Group', '*'], 'Experimental'],
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
theme: adminxTheme,
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story, context) => {
|
||||
|
214
apps/admin-x-settings/src/admin-x-ds/assets/styles/storybook.css
Normal file
@ -0,0 +1,214 @@
|
||||
.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;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import { Meta } from '@storybook/blocks';
|
||||
|
||||
<Meta title="About" />
|
||||
|
||||
<style>
|
||||
{`
|
||||
.sb-doc {
|
||||
max-width: 720px;
|
||||
width: 100%;
|
||||
font-family: Inter, sans-serif !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.sb-highlight {
|
||||
background: yellow;
|
||||
border-radius: 7px;
|
||||
padding: 12px 24px;
|
||||
margin: 0;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
<div className="sb-doc">
|
||||
|
||||
# AdminX Design System
|
||||
|
||||
This is a documentation of the design system of Ghost AdminX.
|
||||
|
||||
## Why?
|
||||
|
||||
The purpose of any design system is to bring order to chaos and this is not any diffrent here either. Historically we maintained consistency in the Ghost Admin via using components and global CSS as much as possible. However due to the growth of the product and the loose system, more and more exotic patterns and styles emerged—which resulted in inconsistency.
|
||||
|
||||
The main goal of the design system (any design system) is to bring order into chaos by defining and documenting **reusable components**.
|
||||
|
||||
## Install
|
||||
|
||||
ATM the design system is part of the AdminX Settings project but soon it will be decoupled with the intention to be able to (re)use it in any future React based Admin projects. Eventually it should be an independent package that could be added to any React app.
|
||||
|
||||
`yarn add @tryghost/admin-x-ds`
|
||||
|
||||
</div>
|
56
apps/admin-x-settings/src/admin-x-ds/docs/Colors.mdx
Normal file
@ -0,0 +1,56 @@
|
||||
import { Meta, ColorPalette, ColorItem } from '@storybook/blocks';
|
||||
|
||||
|
||||
<Meta title="Foundations / Colors" />
|
||||
|
||||
<div className="sb-doc">
|
||||
# Colors
|
||||
|
||||
<p className='excerpt'>You'll find all the official Ghost colors and more in Tailwind, but here's a list of them in case you want to use them elsewhere.</p>
|
||||
|
||||
<ColorPalette>
|
||||
<ColorItem
|
||||
title="Primary colors"
|
||||
colors={{
|
||||
Green: '#30CF43',
|
||||
Black: '#15171A',
|
||||
White: '#FFFFFF'
|
||||
}}
|
||||
/>
|
||||
<ColorItem
|
||||
title="Secondary colors"
|
||||
colors={{
|
||||
Lime: '#B5FF18',
|
||||
Blue: '#14B8FF',
|
||||
Purple: '#8E42FF'
|
||||
}}
|
||||
/>
|
||||
<ColorItem
|
||||
colors={{
|
||||
Yellow: '#FFB41F',
|
||||
Red: '#F50B23',
|
||||
Pink: '#FB2D8D'
|
||||
}}
|
||||
/>
|
||||
<ColorItem
|
||||
title="Greys"
|
||||
colors={{
|
||||
50: '#FAFAFB',
|
||||
100: '#F4F5F6',
|
||||
200: '#EBEEF0',
|
||||
300: '#DDE1E5',
|
||||
400: '#CED4D9'
|
||||
}}
|
||||
/>
|
||||
<ColorItem
|
||||
colors={{
|
||||
500: '#AEB7C1',
|
||||
600: '#95A1AD',
|
||||
700: '#7C8B9A',
|
||||
800: '#626D79',
|
||||
900: '#394047',
|
||||
}}
|
||||
/>
|
||||
</ColorPalette>
|
||||
|
||||
</div>
|
@ -1,73 +0,0 @@
|
||||
import { Meta } from '@storybook/blocks';
|
||||
import SBStructure from './assets/ds-structure.png';
|
||||
|
||||
<Meta title="Development" />
|
||||
|
||||
<style>
|
||||
{`
|
||||
.sb-doc {
|
||||
max-width: 720px;
|
||||
width: 100%;
|
||||
font-family: Inter, sans-serif !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.sb-highlight {
|
||||
background: #E4D2FF;
|
||||
border-radius: 7px;
|
||||
padding: 12px 24px;
|
||||
margin: 0 0 24px;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
|
||||
<div className="sb-doc">
|
||||
|
||||
# Development
|
||||
|
||||
Here's a guideline of how new components should be developed to match the goal of the design system.
|
||||
|
||||
<br />
|
||||
|
||||
## Structure
|
||||
|
||||
The design system contains **reusable components**. These components live in one of the following groups:
|
||||
|
||||
### Global
|
||||
Contains common components that are used across all parts (in all apps) of the admin: buttons, checkboxes, lists, input fields etc—the usual suspects. You can check them in the "Global" group in the sidebar.
|
||||
|
||||
### App specific
|
||||
The Admin is broken down to multiple React apps, each with its own set custom of reusable components. **These components are also part of the design system** which allows potential reusability in the future, and forces designers and developers to think in terms of the design system.
|
||||
|
||||
### What about non-reusable components?
|
||||
|
||||
With all fairness, **most of the components should be part of the design system**. Of course there pages, containers etc. in each app which are obviously **non-reusable**, however these should be built up of _mostly_ reusable components.
|
||||
|
||||
<p className='sb-highlight'>If you can't decide whether a component is reusable or not, then default to adding it to the design system!</p>
|
||||
|
||||
<br />
|
||||
<img src={SBStructure} />
|
||||
<br /><br />
|
||||
|
||||
### Example: settings app
|
||||
|
||||
[TBD: Settings structure]
|
||||
|
||||
<br />
|
||||
|
||||
## How to develop new components?
|
||||
|
||||
If there's a single thing you should remember is this:
|
||||
|
||||
<p className='sb-highlight'>Storybook is **the central tool** of the design system, it is **not** an afterthought. It is the **starting point** of the development of any new component.</p>
|
||||
|
||||
### Steps to develop new components
|
||||
[TBD: expand]
|
||||
|
||||
1. Create the react component in the desgn system with a rudimentary interface
|
||||
2. Create a new story (you can use `Boilerplate.stories.tsx` to get started)
|
||||
3. Develop the details of the new react component
|
||||
4. Create stories for all interesting use cases. There should be a story for the most common parameter combinations.
|
||||
5. Test the new component in your app. If something is off, think about how you can solve it in the system—avoid visual hacking in the app.
|
||||
|
||||
</div>
|
@ -3,68 +3,43 @@ import SBLocalError from './assets/local-error-example.png';
|
||||
import SBPageError from './assets/page-error-example.png';
|
||||
import SBGlobalError from './assets/global-error-example.png';
|
||||
|
||||
<Meta title="Error handling" />
|
||||
|
||||
<style>
|
||||
{`
|
||||
.sb-doc {
|
||||
max-width: 720px;
|
||||
width: 100%;
|
||||
font-family: Inter, sans-serif !important;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.sb-highlight {
|
||||
background: #E4D2FF;
|
||||
border-radius: 7px;
|
||||
padding: 12px 24px;
|
||||
margin: 0 0 24px;
|
||||
}
|
||||
|
||||
.sb-wide {
|
||||
max-width: 1340px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<Meta title="Foundations / Error handling" />
|
||||
|
||||
<div className="sb-doc">
|
||||
|
||||
# Error handling in AdminX
|
||||
# Error handling
|
||||
|
||||
The three most common errors in Ghost Admin should fall into one of the following categories:
|
||||
<p className='excerpt'>Consistent error handling throughout the whole product is a key to great user experience.</p>
|
||||
|
||||
1. **Inline errors** — errors related typically to input fields in forms
|
||||
2. **Contextual errors** — errors which are related to a screen, page or a modal and the tasks the user is doing at that specific context.
|
||||
3. **System errors** — global errors which are relevant no matter what the actual screen is or the user's actual task
|
||||
Errors in Ghost Admin fall into one of three categories:
|
||||
|
||||
## Inline errors
|
||||
1. **Field errors** — errors related to various [input] fields in forms
|
||||
2. **Page errors** — errors which are related to a screen, page or a modal.
|
||||
3. **System errors** — product level, global errors
|
||||
|
||||
Inline errors are typically related to form validation and appear most commonly close to a form element. An example of an inline error is when the user doesn't fill a mandatory input field and an error message appears near the field.
|
||||
## Field errors
|
||||
|
||||
Example of a inline error:
|
||||
Field errors are shown during frontend form validation, and appear close to the related form field. The most typical example of it is when the user doesn't fill a mandatory input field and an error message appears like this:
|
||||
|
||||
<img src={SBLocalError} />
|
||||
<br /><br />
|
||||
<img src={SBLocalError} className='small' />
|
||||
|
||||
Frontend form validation usually happens without an API roundtrip, ideally right after the user finishes editing a field (`onFocusOut`):
|
||||
|
||||
1. User fills the form
|
||||
2. Clicks on the next form field (focus is out of the current input field)
|
||||
3. The system does form field validation and — in case of an error — shows the related inline field error
|
||||
|
||||
All the form fields in AdminX have a built in capability to show inline errors via the `error` prop set to `true` and using the `hint` prop to set the error message. Example: [Textfield](/story/global-form-textfield--error)
|
||||
This kind of error is usually used for inline frontend form validation, which mostly happens without an API roundtrip. The error is shown right after the user finishes editing the field and focuses out of it (`onBlur`).
|
||||
|
||||
Ideally, all validation should be inline: that is, as soon as the user has finished filling in a field, an indicator should appear nearby if the field contains an error. This type of error message is easily noticeable; moreover, fixing the error immediately after the field has been completed requires the least interaction cost for users: they don’t need to locate it or navigate to the field, nor do they have to switch context from a new field to return to an old field they thought they had completed successfully.
|
||||
|
||||
Of course, there will be situations where inline validation won’t be possible and data entered by the user will need to be sent to a server for verification. ([ref](https://www.nngroup.com/articles/errors-forms-design-guidelines/))
|
||||
Of course, there will be situations where inline validation won’t be possible and data entered by the user will need to be sent to a server for verification. ([ref](https://www.nngroup.com/articles/errors-forms-design-guidelines/)).
|
||||
|
||||
So the steps to show a field error are:
|
||||
|
||||
1. User fills a field in the form
|
||||
2. Clicks outside the field (`onBlur`)
|
||||
3. The system does frontend field validation and — in case of an error — shows the related error
|
||||
|
||||
All form elements (input fields, selects etc.) in AdminX have a built in capability to show form errors via the `error` prop set to `true` and using the `hint` prop to set the error message. (Example: [Textfield](/story/global-form-textfield--error))
|
||||
|
||||
## Page errors
|
||||
|
||||
Page errors are related to the actual page, modal or the task but unlike inline errors, they always appear on the top of the page. An important property of page errors is that they _disappear_ if the user navigates away from the page.
|
||||
|
||||
A common example of page errors is a summary of form validation errors or an API error or a summary of errors on submitting a form.
|
||||
Page errors are related to the actual page, modal or the task but unlike inline errors, they always appear on the top of the page. An important property of page errors is that they _disappear_ if the user navigates away from the page. A common example of page errors is a summary of form validation errors or an API error or a summary of errors on submitting a form.
|
||||
|
||||
A typical example when page errors would be used:
|
||||
|
||||
@ -77,7 +52,6 @@ A typical example when page errors would be used:
|
||||
|
||||
<div className="sb-wide">
|
||||
<img src={SBPageError} />
|
||||
<br /><br />
|
||||
</div>
|
||||
|
||||
<div className="sb-doc">
|
||||
@ -90,7 +64,6 @@ For example:
|
||||
|
||||
<div className="sb-wide">
|
||||
<img src={SBGlobalError} />
|
||||
<br /><br /><br />
|
||||
</div>
|
||||
|
||||
|
||||
|
45
apps/admin-x-settings/src/admin-x-ds/docs/Icons.mdx
Normal file
@ -0,0 +1,45 @@
|
||||
import { Meta } from '@storybook/blocks';
|
||||
import StreamlineSettings from './assets/streamline-settings.png';
|
||||
|
||||
<Meta title="Foundations / Icons" />
|
||||
|
||||
<div className="sb-doc">
|
||||
|
||||
# Icons
|
||||
|
||||
<p className='excerpt'>We use the [Streamline icon library](https://www.streamlinehq.com/) in Ghost Admin. Here are some iconography best practices.</p>
|
||||
|
||||
### Overview
|
||||
The icons are part of the AdminX design system so they can be reusable in any Ghost Admin app. Use the [Icon](/docs/global-icon--docs) component to display available icons in standard icon sizes.
|
||||
|
||||
### Adding new icons
|
||||
|
||||
There are some rules we have to follow in order to maintain consistent iconography:
|
||||
|
||||
<div className="streamline">
|
||||
<div>
|
||||
- All icons must be SVG format.
|
||||
- Icons must be exported using **strokes** as lines and **not** filled areas. The stroke width must be **1.5px**. This allows more flexibility but still maintains consistency (and less filesize).
|
||||
- All icon should be exported in a 24x24 pixel container.
|
||||
- All icons should use `currentColor` as their colors for strokes. This lets us color the icon easily in CSS.
|
||||
- Icons must be exported with transparent background.
|
||||
|
||||
<br /><br />
|
||||
|
||||
#### Exporting using the Streamline app
|
||||
|
||||
For the best result we recommend using the Streamline app to copy the SVG code of new icons with the following settings:
|
||||
|
||||
- Format: SVG
|
||||
- Size: 24px
|
||||
- Stroke: 1.5px
|
||||
- Responsive size: OFF
|
||||
- Outline stroke: **OFF**
|
||||
- Background: transparent
|
||||
- Asset currentcolor: **ON**
|
||||
- Background currentcolor: OFF
|
||||
</div>
|
||||
<img src={StreamlineSettings} />
|
||||
</div>
|
||||
|
||||
</div>
|
49
apps/admin-x-settings/src/admin-x-ds/docs/Welcome.mdx
Normal file
@ -0,0 +1,49 @@
|
||||
import { Meta } from '@storybook/blocks';
|
||||
import WelcomeImage from './assets/adminx-screenshot.png';
|
||||
import BlocksIcon from './assets/blocks.svg';
|
||||
import CircleMenu from './assets/circle-menu.svg';
|
||||
import AppsIcon from './assets/apps.svg';
|
||||
|
||||
<Meta title="Welcome" />
|
||||
|
||||
<div className="sb-doc">
|
||||
|
||||
<img src={WelcomeImage} className='main-image' />
|
||||
|
||||
# AdminX Design System
|
||||
|
||||
<p className='excerpt'>Here you can find our design guidelines, component documentation, and resources for building apps in Ghost Admin.</p>
|
||||
|
||||
<div className="highlight purple"><strong>This is a work in progress.</strong> As of today, the Storybook system is part of <a href="https://github.com/TryGhost/Ghost/tree/main/apps/admin-x-settings">AdminX Settings app</a> but it's about to be a separated into its own package.</div>
|
||||
|
||||
### What's inside
|
||||
|
||||
The AdminX Design System is a collection of React UI building blocks for designers and developers to create apps for Ghost Admin. Its main purpose is to provide a library of available components and maintain consistency across the whole product.
|
||||
|
||||
<section className="main-structure-container">
|
||||
<div>
|
||||
<img src={CircleMenu} className="icon green" />
|
||||
<h4>Foundations</h4>
|
||||
<p>Basic global design patterns like colors and icons</p>
|
||||
[Read more →](/docs/foundations-colors--docs)
|
||||
</div>
|
||||
<div>
|
||||
<img src={BlocksIcon} className="icon purple" />
|
||||
<h4>Global components</h4>
|
||||
<p>UI building blocks to be used across all apps in Ghost Admin</p>
|
||||
[Browse →](/docs/global-form-checkbox--docs)
|
||||
</div>
|
||||
<div>
|
||||
<img src={AppsIcon} className="icon pink" />
|
||||
<h4>App specific</h4>
|
||||
<p>Reusable components of individual React apps in Ghost Admin</p>
|
||||
[Example →](/docs/settings-setting-section--docs)
|
||||
</div>
|
||||
</section>
|
||||
|
||||
The system uses Storybook — if you're new to it, we recommend reading about what it is and how to use it, on [storybook.js.org](https://storybook.js.org).
|
||||
|
||||
<br/><br/>
|
||||
|
||||
|
||||
</div>
|
After Width: | Height: | Size: 611 KiB |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.75 -0.75 32 32" height="32" width="32"><defs></defs><title>app-window-multiple</title><path d="M2.872083333333333 2.8631875h17.15625s1.90625 0 1.90625 1.90625v13.34375s0 1.90625 -1.90625 1.90625H2.872083333333333s-1.90625 0 -1.90625 -1.90625v-13.34375s0 -1.90625 1.90625 -1.90625" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m0.9658333333333333 8.5819375 20.96875 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M25.747083333333332 8.5819375v13.34375a1.90625 1.90625 0 0 1 -1.90625 1.90625H6.684583333333332" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M29.559583333333332 12.394437499999999v13.34375a1.90625 1.90625 0 0 1 -1.90625 1.90625H10.497083333333332" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1 @@
|
||||
<svg viewBox="-0.75 -0.75 32 32" xmlns="http://www.w3.org/2000/svg" height="32" width="32"><path d="M13.34375 15.918458333333332a1.242875 1.242875 0 0 1 -1.2390625 1.2454166666666666h-9.9125a1.2416041666666666 1.2416041666666666 0 0 1 -1.2390625 -1.2454166666666666V2.2061666666666664a1.242875 1.242875 0 0 1 1.2403333333333333 -1.2454166666666666l9.9125 0.016520833333333332a1.242875 1.242875 0 0 1 1.2377916666666666 1.2454166666666666Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M29.541791666666665 8.316333333333333a1.2314375 1.2314375 0 0 1 -1.2390625 1.2225416666666666h-9.9125a1.2301666666666666 1.2301666666666666 0 0 1 -1.2390625 -1.2225416666666666V2.1998125a1.2301666666666666 1.2301666666666666 0 0 1 1.2365208333333333 -1.2225416666666666l9.9125 -0.016520833333333332a1.2327083333333333 1.2327083333333333 0 0 1 1.2416041666666666 1.2225416666666666Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M13.34375 28.32814583333333a1.2339791666666666 1.2339791666666666 0 0 1 -1.2416041666666666 1.2263541666666666l-9.9125 -0.016520833333333332a1.2314375 1.2314375 0 0 1 -1.2365208333333333 -1.2250833333333333V22.20145833333333a1.2314375 1.2314375 0 0 1 1.2390625 -1.2250833333333333h9.9125a1.2327083333333333 1.2327083333333333 0 0 1 1.2390625 1.2250833333333333Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="M18.391499999999997 29.554499999999997a1.242875 1.242875 0 0 1 -1.2403333333333333 -1.2466875V14.5980625a1.242875 1.242875 0 0 1 1.2390625 -1.2466875h9.9125a1.242875 1.242875 0 0 1 1.2390625 1.2466875v13.693229166666667a1.2441458333333333 1.2441458333333333 0 0 1 -1.2377916666666666 1.2466875Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1 @@
|
||||
<svg viewBox="-0.75 -0.75 32 32" xmlns="http://www.w3.org/2000/svg" height="32" width="32"><path d="M0.953125 15.253812499999999a14.296875 14.296875 0 1 0 28.59375 0 14.296875 14.296875 0 1 0 -28.59375 0Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m9.53125 10.488187499999999 11.4375 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m9.53125 15.253812499999999 11.4375 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path><path d="m9.53125 20.0194375 11.4375 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"></path></svg>
|
After Width: | Height: | Size: 776 B |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 139 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 2.2 MiB |
BIN
apps/admin-x-settings/src/admin-x-ds/docs/assets/style-guide.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
@ -0,0 +1 @@
|
||||
<svg viewBox="-1 -1 32 32" xmlns="http://www.w3.org/2000/svg" height="32" width="32"><path d="M24.375 0.9375a0.9375 0.9375 0 0 1 0.9375 0.9375v7.5a0.9375 0.9375 0 0 1 -0.9375 0.9375h-18.75a0.9375 0.9375 0 0 1 -0.9375 -0.9375v-7.5A0.9375 0.9375 0 0 1 5.625 0.9375h2.8125a0.9375 0.9375 0 0 1 0.9375 0.9375v0.9375a1.875 1.875 0 0 0 3.75 0V1.875a0.9375 0.9375 0 0 1 0.9375 -0.9375h1.875a0.9375 0.9375 0 0 1 0.9375 0.9375v0.9375a1.875 1.875 0 0 0 3.75 0V1.875a0.9375 0.9375 0 0 1 0.9375 -0.9375Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path><path d="m6.5625 10.3125 -1.875 18.75 20.625 0 -1.875 -18.75 -16.875 0z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path><path d="M17.8125 29.0625h-5.625V22.5a2.8125 2.8125 0 0 1 5.625 0Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path><path d="m0.9375 29.0625 28.125 0" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |