From 63f975ccc4ee26093ffd1dde62d7189ac2004e51 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Mon, 25 Nov 2024 17:14:01 +0000 Subject: [PATCH] Improve layout components Signed-off-by: Charles de Dreuille --- packages/canon/.storybook/main.ts | 2 +- packages/canon/{src => }/docs/Home.mdx | 4 +- packages/canon/docs/Layout.mdx | 47 +++++ packages/canon/{src => }/docs/Theme.mdx | 93 +++++++-- .../components}/chip/chip.css.ts | 0 .../components}/chip/index.tsx | 0 .../components}/columns/columns.css.ts | 0 .../components}/columns/index.tsx | 0 .../component-status/component-status.css.ts | 0 .../components}/component-status/index.tsx | 0 packages/canon/docs/components/index.ts | 7 + .../components/layout-components/index.tsx | 93 +++++++++ .../layout-components.css.ts | 197 ++++++++++++++++++ .../components}/table/index.tsx | 0 .../components}/table/table.css.ts | 7 +- .../components}/text/index.tsx | 0 .../components}/text/text.css.ts | 0 .../components}/title/index.tsx | 0 .../components}/title/title.css.ts | 0 packages/canon/src/components/box/box.mdx | 6 +- .../canon/src/components/box/box.stories.tsx | 2 +- .../src/components/box/docs/props-table.tsx | 4 +- .../canon/src/components/box/properties.ts | 14 +- .../src/components/inline/inline.stories.tsx | 2 +- .../src/components/stack/stack.stories.tsx | 2 +- packages/canon/src/storybook/index.ts | 4 - packages/canon/src/theme/theme.css | 16 +- packages/canon/tsconfig.json | 2 +- 28 files changed, 457 insertions(+), 45 deletions(-) rename packages/canon/{src => }/docs/Home.mdx (90%) create mode 100644 packages/canon/docs/Layout.mdx rename packages/canon/{src => }/docs/Theme.mdx (62%) rename packages/canon/{src/storybook => docs/components}/chip/chip.css.ts (100%) rename packages/canon/{src/storybook => docs/components}/chip/index.tsx (100%) rename packages/canon/{src/storybook => docs/components}/columns/columns.css.ts (100%) rename packages/canon/{src/storybook => docs/components}/columns/index.tsx (100%) rename packages/canon/{src/storybook => docs/components}/component-status/component-status.css.ts (100%) rename packages/canon/{src/storybook => docs/components}/component-status/index.tsx (100%) create mode 100644 packages/canon/docs/components/index.ts create mode 100644 packages/canon/docs/components/layout-components/index.tsx create mode 100644 packages/canon/docs/components/layout-components/layout-components.css.ts rename packages/canon/{src/storybook => docs/components}/table/index.tsx (100%) rename packages/canon/{src/storybook => docs/components}/table/table.css.ts (91%) rename packages/canon/{src/storybook => docs/components}/text/index.tsx (100%) rename packages/canon/{src/storybook => docs/components}/text/text.css.ts (100%) rename packages/canon/{src/storybook => docs/components}/title/index.tsx (100%) rename packages/canon/{src/storybook => docs/components}/title/title.css.ts (100%) delete mode 100644 packages/canon/src/storybook/index.ts diff --git a/packages/canon/.storybook/main.ts b/packages/canon/.storybook/main.ts index 86dc3ec87f..41df32404b 100644 --- a/packages/canon/.storybook/main.ts +++ b/packages/canon/.storybook/main.ts @@ -13,7 +13,7 @@ function getAbsolutePath(value: string): any { } const config: StorybookConfig = { stories: [ - '../src/docs/**/*.mdx', + '../docs/**/*.mdx', '../src/components/**/*.mdx', '../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)', ], diff --git a/packages/canon/src/docs/Home.mdx b/packages/canon/docs/Home.mdx similarity index 90% rename from packages/canon/src/docs/Home.mdx rename to packages/canon/docs/Home.mdx index 7e3bd45858..e1199604a8 100644 --- a/packages/canon/src/docs/Home.mdx +++ b/packages/canon/docs/Home.mdx @@ -1,7 +1,5 @@ import { Unstyled } from '@storybook/blocks'; -import { Text } from '../storybook/text'; -import { ComponentStatus } from '../storybook/component-status'; -import { Columns } from '../storybook/columns'; +import { Columns, Text, ComponentStatus } from './components'; diff --git a/packages/canon/docs/Layout.mdx b/packages/canon/docs/Layout.mdx new file mode 100644 index 0000000000..3dc36ed0d1 --- /dev/null +++ b/packages/canon/docs/Layout.mdx @@ -0,0 +1,47 @@ +import { Unstyled, Source } from '@storybook/blocks'; +import { Title, Text, LayoutComponents } from './components'; +import * as Table from './components/table'; + + + +Layout + + Canon is made for extensibility. We built this library to make it easy for any + Backstage plugin creator to be able to build their ideas at speed ensuring + consistency across the rest of your ecosystem. Each component is designed to + be editable to match your need but sometimes you want to have more control + over the layout of your page. To help you with that, we created a set of + layout components that you can use to build your own layouts. All of these + components are built to extend on our theming system, making it easy for you + to build your own layouts. Sometimes these components are not enough so we + created a set of helpers to be used with any CSS-in-JS library. + + +Layout Components + + + We built a couple of layout components to help you build responsive elements + that will be consistent with the rest of your Bacvkstage instance. These + components are opinionated and use typescript to ensure that the props you + provide are the ones coming from the theme. + + + + Hello World + + Project 1 + Project 2 + +`} + language="tsx" + dark +/> + + + +Layout Helpers + +TBD + + diff --git a/packages/canon/src/docs/Theme.mdx b/packages/canon/docs/Theme.mdx similarity index 62% rename from packages/canon/src/docs/Theme.mdx rename to packages/canon/docs/Theme.mdx index 6ce036aa71..7df8545c63 100644 --- a/packages/canon/src/docs/Theme.mdx +++ b/packages/canon/docs/Theme.mdx @@ -1,6 +1,6 @@ import { Unstyled, Source } from '@storybook/blocks'; -import { Title, Text, Chip } from '../storybook'; -import * as Table from '../storybook/table'; +import { Title, Text, Chip } from './components'; +import * as Table from './components/table'; @@ -79,49 +79,49 @@ import * as Table from '../storybook/table'; - --canon-accent + --canon-accent The accent color for the theme. - --canon-bg + --canon-bg The background color for the theme. - --canon-surface-1 + --canon-surface-1 The first surface color for the theme. - --canon-surface-2 + --canon-surface-2 The second surface color for the theme. - --canon-outline + --canon-outline The outline color for the theme. - --canon-outline-focus + --canon-outline-focus The outline focus color for the theme. - --canon-text-primary + --canon-text-primary The primary text color for the theme. - --canon-text-secondary + --canon-text-secondary The secondary text color for the theme. @@ -145,17 +145,86 @@ import * as Table from '../storybook/table'; - --canon-font-sans + --canon-font-sans The sans-serif font for the theme. - --canon-font-mono + --canon-font-mono The monospace font for the theme. +Spacing + + Our default spacing system is made to made to work in most scenarios. We have + 7 scale values from `xxs` to `xxl`. We use the values on padding and margin in + our layout components mostly. If you prefer to use a different spacing system, + you can do that by changing the values below. + + + + + + Prop + Description + + + + + + --canon-space-unit + + + The base unit for the spacing system. Default value is `1em` + + + + + --canon-space-xxs + + Default value is `0.25 x space unit` + + + + --canon-space-xs + + Default value is `0.5 x space unit` + + + + --canon-space-sm + + Default value is `0.75 x space unit` + + + + --canon-space-md + + Default value is `1.25 x space unit` + + + + --canon-space-lg + + Default value is `2 x space unit` + + + + --canon-space-xl + + Default value is `3.25 x space unit` + + + + --canon-space-xxl + + Default value is `5.25 x space unit` + + + + diff --git a/packages/canon/src/storybook/chip/chip.css.ts b/packages/canon/docs/components/chip/chip.css.ts similarity index 100% rename from packages/canon/src/storybook/chip/chip.css.ts rename to packages/canon/docs/components/chip/chip.css.ts diff --git a/packages/canon/src/storybook/chip/index.tsx b/packages/canon/docs/components/chip/index.tsx similarity index 100% rename from packages/canon/src/storybook/chip/index.tsx rename to packages/canon/docs/components/chip/index.tsx diff --git a/packages/canon/src/storybook/columns/columns.css.ts b/packages/canon/docs/components/columns/columns.css.ts similarity index 100% rename from packages/canon/src/storybook/columns/columns.css.ts rename to packages/canon/docs/components/columns/columns.css.ts diff --git a/packages/canon/src/storybook/columns/index.tsx b/packages/canon/docs/components/columns/index.tsx similarity index 100% rename from packages/canon/src/storybook/columns/index.tsx rename to packages/canon/docs/components/columns/index.tsx diff --git a/packages/canon/src/storybook/component-status/component-status.css.ts b/packages/canon/docs/components/component-status/component-status.css.ts similarity index 100% rename from packages/canon/src/storybook/component-status/component-status.css.ts rename to packages/canon/docs/components/component-status/component-status.css.ts diff --git a/packages/canon/src/storybook/component-status/index.tsx b/packages/canon/docs/components/component-status/index.tsx similarity index 100% rename from packages/canon/src/storybook/component-status/index.tsx rename to packages/canon/docs/components/component-status/index.tsx diff --git a/packages/canon/docs/components/index.ts b/packages/canon/docs/components/index.ts new file mode 100644 index 0000000000..f4c3ec3001 --- /dev/null +++ b/packages/canon/docs/components/index.ts @@ -0,0 +1,7 @@ +export * from './chip'; +export * from './table'; +export * from './title'; +export * from './text'; +export * from './columns'; +export * from './component-status'; +export * from './layout-components'; diff --git a/packages/canon/docs/components/layout-components/index.tsx b/packages/canon/docs/components/layout-components/index.tsx new file mode 100644 index 0000000000..b819955d76 --- /dev/null +++ b/packages/canon/docs/components/layout-components/index.tsx @@ -0,0 +1,93 @@ +import React from 'react'; +import { + container, + box, + content, + title, + description, + whiteBox, + whiteBoxStack, + stack, + verticalDivider, + horizontalDivider, + columns, + inline, + tiles, + whiteBoxColumns, + whiteBoxInline, + whiteBoxTiles, +} from './layout-components.css'; + +export const LayoutComponents = () => { + return ( +
+
+ +
+ +
Box
+
The most basic layout component.
+
+
+ +
+
+
+ +
Stack
+
Arrange your components vertically.
+
+
+ +
+
+
+ +
Columns
+
Arrange your components horizontally.
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
Inline
+
Arrange your components in a row.
+
+
+ +
+
+
+
+
+
+ + ); +}; diff --git a/packages/canon/docs/components/layout-components/layout-components.css.ts b/packages/canon/docs/components/layout-components/layout-components.css.ts new file mode 100644 index 0000000000..7b56964eac --- /dev/null +++ b/packages/canon/docs/components/layout-components/layout-components.css.ts @@ -0,0 +1,197 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { style } from '@vanilla-extract/css'; + +export const container = style({ + display: 'flex', + justifyContent: 'flex-start', + gap: '1rem', + flexWrap: 'wrap', +}); + +export const box = style({ + display: 'flex', + flexDirection: 'column', + width: 'calc(33.33% - 0.67rem)', + marginBottom: '1rem', + alignItems: 'flex-start', +}); + +export const content = style({ + flex: 'none', + background: '#f2f2f2', + borderRadius: '4px', + width: '100%', + height: '180px', + border: '1px solid #e0e0e0', + transition: 'border-color 0.2s ease-in-out', + marginBottom: '0.75rem', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + selectors: { + [`${box}:hover &`]: { + borderColor: '#1f47ff', + }, + }, +}); + +export const title = style({ + fontSize: '16px', + fontFamily: 'var(--canon-font-sans)', + transition: 'color 0.2s ease-in-out', + marginBottom: '0.25rem', + selectors: { + [`${box}:hover &`]: { + color: '#1f47ff', + }, + }, +}); + +export const description = style({ + fontSize: '16px', + fontFamily: 'var(--canon-font-sans)', + color: '#9e9e9e', +}); + +export const whiteBox = style({ + background: '#fff', + width: '40px', + height: '40px', + borderRadius: '4px', + boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)', +}); + +export const whiteBoxStack = style([ + whiteBox, + { + width: '40%', + height: '28px', + }, +]); + +export const whiteBoxColumns = style([ + whiteBox, + { + width: '30%', + height: '32px', + }, +]); + +export const whiteBoxInline = style([ + whiteBox, + { + width: '32px', + height: '32px', + }, +]); + +export const whiteBoxTiles = style([ + whiteBox, + { + width: '100%', + height: '32px', + }, +]); + +export const stack = style({ + display: 'flex', + flexDirection: 'column', +}); + +export const columns = style({ + display: 'flex', + flexDirection: 'row', +}); + +export const inline = style({ + display: 'flex', + flexWrap: 'wrap', + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'flex-start', + gap: '0.5rem', + paddingLeft: '1rem', +}); + +export const tiles = style({ + display: 'grid', + gridTemplateColumns: 'repeat(4, 1fr)', + gap: '0.5rem', + paddingLeft: '1rem', + paddingRight: '1rem', + width: '100%', +}); + +export const verticalDivider = style({ + display: 'flex', + flexShrink: 0, + flexDirection: 'column', + position: 'relative', + height: '20px', + width: '2px', + backgroundColor: '#1f47ff', + selectors: { + '&::before': { + content: '""', + position: 'absolute', + top: 0, + left: '-9px', + width: '20px', + height: '2px', + backgroundColor: '#1f47ff', + }, + '&::after': { + content: '""', + position: 'absolute', + bottom: 0, + left: '-9px', + width: '20px', + height: '2px', + backgroundColor: '#1f47ff', + }, + }, +}); + +export const horizontalDivider = style({ + flexShrink: 0, + display: 'flex', + flexDirection: 'row', + position: 'relative', + height: '2px', + width: '20px', + backgroundColor: '#1f47ff', + selectors: { + '&::before': { + content: '""', + position: 'absolute', + left: 0, + top: '-9px', + width: '2px', + height: '20px', + backgroundColor: '#1f47ff', + }, + '&::after': { + content: '""', + position: 'absolute', + right: 0, + top: '-9px', + width: '2px', + height: '20px', + backgroundColor: '#1f47ff', + }, + }, +}); diff --git a/packages/canon/src/storybook/table/index.tsx b/packages/canon/docs/components/table/index.tsx similarity index 100% rename from packages/canon/src/storybook/table/index.tsx rename to packages/canon/docs/components/table/index.tsx diff --git a/packages/canon/src/storybook/table/table.css.ts b/packages/canon/docs/components/table/table.css.ts similarity index 91% rename from packages/canon/src/storybook/table/table.css.ts rename to packages/canon/docs/components/table/table.css.ts index 6f4b2404c4..cc30cf135a 100644 --- a/packages/canon/src/storybook/table/table.css.ts +++ b/packages/canon/docs/components/table/table.css.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { style } from '@vanilla-extract/css'; +import { style, globalStyle } from '@vanilla-extract/css'; export const wrapperStyles = style({ border: '1px solid #e7e7e7', @@ -39,6 +39,11 @@ export const cellStyles = style({ fontWeight: '300', }); +// Apply global styles to

elements inside cellStyles +globalStyle(`${cellStyles} p`, { + margin: '0', +}); + export const headerRowStyles = style({ borderBottom: '1px solid #e7e7e7', }); diff --git a/packages/canon/src/storybook/text/index.tsx b/packages/canon/docs/components/text/index.tsx similarity index 100% rename from packages/canon/src/storybook/text/index.tsx rename to packages/canon/docs/components/text/index.tsx diff --git a/packages/canon/src/storybook/text/text.css.ts b/packages/canon/docs/components/text/text.css.ts similarity index 100% rename from packages/canon/src/storybook/text/text.css.ts rename to packages/canon/docs/components/text/text.css.ts diff --git a/packages/canon/src/storybook/title/index.tsx b/packages/canon/docs/components/title/index.tsx similarity index 100% rename from packages/canon/src/storybook/title/index.tsx rename to packages/canon/docs/components/title/index.tsx diff --git a/packages/canon/src/storybook/title/title.css.ts b/packages/canon/docs/components/title/title.css.ts similarity index 100% rename from packages/canon/src/storybook/title/title.css.ts rename to packages/canon/docs/components/title/title.css.ts diff --git a/packages/canon/src/components/box/box.mdx b/packages/canon/src/components/box/box.mdx index f8cadc316b..57d7eabb3a 100644 --- a/packages/canon/src/components/box/box.mdx +++ b/packages/canon/src/components/box/box.mdx @@ -1,10 +1,10 @@ import { Canvas, Meta, Unstyled } from '@storybook/blocks'; import * as BoxStories from './box.stories'; -import { Chip } from '../../storybook/chip'; -import * as Table from '../../storybook/table'; +import { Chip } from '../../../docs/components/chip'; +import * as Table from '../../../docs/components/table'; import { Box } from './box'; import { Stack } from '../stack/stack'; -import { Title, Text } from '../../storybook'; +import { Title, Text } from '../../../docs/components'; import { Padding } from './docs/padding'; import { listResponsiveValues, listColorValues } from '../../utils/list-values'; import { responsiveProperties } from './sprinkles.css'; diff --git a/packages/canon/src/components/box/box.stories.tsx b/packages/canon/src/components/box/box.stories.tsx index 65d83c35d6..1ba9f590a8 100644 --- a/packages/canon/src/components/box/box.stories.tsx +++ b/packages/canon/src/components/box/box.stories.tsx @@ -110,7 +110,7 @@ sortedArgTypes['children'] = { }; const meta = { - title: 'Layout/Box', + title: 'Components/Box', component: Box, parameters: { layout: 'centered', diff --git a/packages/canon/src/components/box/docs/props-table.tsx b/packages/canon/src/components/box/docs/props-table.tsx index de4de09bfe..13382c83d0 100644 --- a/packages/canon/src/components/box/docs/props-table.tsx +++ b/packages/canon/src/components/box/docs/props-table.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import * as Table from '../../../storybook'; -import { Chip } from '../../../storybook'; +import * as Table from '../../../../docs/components'; +import { Chip } from '../../../../docs/components'; import { listResponsiveValues } from '../../../utils/list-values'; import { responsiveProperties } from '../sprinkles.css'; diff --git a/packages/canon/src/components/box/properties.ts b/packages/canon/src/components/box/properties.ts index 9063aa24d6..96d75e4ef8 100644 --- a/packages/canon/src/components/box/properties.ts +++ b/packages/canon/src/components/box/properties.ts @@ -9,11 +9,11 @@ export const breakpoints = { export const space = { none: 0, - xxs: 'var(--space-xxs)', - xs: 'var(--space-xs)', - sm: 'var(--space-sm)', - md: 'var(--space-md)', - lg: 'var(--space-lg)', - xl: 'var(--space-xl)', - xxl: 'var(--space-xxl)', + xxs: 'var(--canon-space-xxs)', + xs: 'var(--canon-space-xs)', + sm: 'var(--canon-space-sm)', + md: 'var(--canon-space-md)', + lg: 'var(--canon-space-lg)', + xl: 'var(--canon-space-xl)', + xxl: 'var(--canon-space-xxl)', }; diff --git a/packages/canon/src/components/inline/inline.stories.tsx b/packages/canon/src/components/inline/inline.stories.tsx index 9562a0b914..863e6ce3f0 100644 --- a/packages/canon/src/components/inline/inline.stories.tsx +++ b/packages/canon/src/components/inline/inline.stories.tsx @@ -19,7 +19,7 @@ import { Inline } from './inline'; import { Box } from '../box/box'; const meta = { - title: 'Layout/Inline', + title: 'Components/Inline', component: Inline, } satisfies Meta; diff --git a/packages/canon/src/components/stack/stack.stories.tsx b/packages/canon/src/components/stack/stack.stories.tsx index 209811880a..7595f5020a 100644 --- a/packages/canon/src/components/stack/stack.stories.tsx +++ b/packages/canon/src/components/stack/stack.stories.tsx @@ -19,7 +19,7 @@ import { Stack } from './stack'; import { Box } from '../box/box'; const meta = { - title: 'Layout/Stack', + title: 'Components/Stack', component: Stack, } satisfies Meta; diff --git a/packages/canon/src/storybook/index.ts b/packages/canon/src/storybook/index.ts deleted file mode 100644 index d2a20bec92..0000000000 --- a/packages/canon/src/storybook/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './chip'; -export * from './table'; -export * from './title'; -export * from './text'; diff --git a/packages/canon/src/theme/theme.css b/packages/canon/src/theme/theme.css index 90e91510a5..e435a53091 100644 --- a/packages/canon/src/theme/theme.css +++ b/packages/canon/src/theme/theme.css @@ -18,14 +18,14 @@ --canon-font-emoji: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; - --space-unit: 1em; - --space-xxs: calc(0.25 * var(--space-unit)); - --space-xs: calc(0.5 * var(--space-unit)); - --space-sm: calc(0.75 * var(--space-unit)); - --space-md: calc(1.25 * var(--space-unit)); - --space-lg: calc(2 * var(--space-unit)); - --space-xl: calc(3.25 * var(--space-unit)); - --space-xxl: calc(5.25 * var(--space-unit)); + --canon-space-unit: 1em; + --canon-space-xxs: calc(0.25 * var(--canon-space-unit)); + --canon-space-xs: calc(0.5 * var(--canon-space-unit)); + --canon-space-sm: calc(0.75 * var(--canon-space-unit)); + --canon-space-md: calc(1.25 * var(--canon-space-unit)); + --canon-space-lg: calc(2 * var(--canon-space-unit)); + --canon-space-xl: calc(3.25 * var(--canon-space-unit)); + --canon-space-xxl: calc(5.25 * var(--canon-space-unit)); } /* Dark theme */ diff --git a/packages/canon/tsconfig.json b/packages/canon/tsconfig.json index 5ae9aeb62d..72ad802d80 100644 --- a/packages/canon/tsconfig.json +++ b/packages/canon/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], + "include": ["src", "docs/components"], "exclude": ["node_modules"], "compilerOptions": { "outDir": "dist-types",