Improve props
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import { CodeBlock } from '@/components/CodeBlock';
|
||||
import { PropsTable } from '@/components/PropsTable';
|
||||
import { spacePropsList } from '@/utils/spaceProps';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { BoxPreview } from '@/snippets/box';
|
||||
import { boxPropDefs } from './props';
|
||||
import { spacingPropDefs } from '../../../../utils/propDefs';
|
||||
|
||||
# Box
|
||||
|
||||
@@ -36,60 +37,13 @@ Box is the lowest-level component in Canon. It provides a consistent API for sty
|
||||
This is the Box component, our lowest-level component. Here are all the
|
||||
available properties.
|
||||
|
||||
<PropsTable
|
||||
data={{
|
||||
alignItems: {
|
||||
type: ['stretch', 'start', 'center', 'end'],
|
||||
responsive: true,
|
||||
},
|
||||
border: {
|
||||
type: ['none', 'base', 'error', 'warning', 'selected'],
|
||||
responsive: true,
|
||||
},
|
||||
borderRadius: {
|
||||
type: ['none', '2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl'],
|
||||
responsive: true,
|
||||
},
|
||||
children: {
|
||||
type: 'ReactNode',
|
||||
responsive: false,
|
||||
},
|
||||
className: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
display: {
|
||||
type: ['none', 'flex', 'block', 'inline'],
|
||||
responsive: true,
|
||||
},
|
||||
flexDirection: {
|
||||
type: ['row', 'column'],
|
||||
responsive: true,
|
||||
},
|
||||
flexWrap: {
|
||||
type: ['wrap', 'nowrap', 'wrap-reverse'],
|
||||
responsive: true,
|
||||
},
|
||||
gap: {
|
||||
type: ['2xs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl'],
|
||||
responsive: true,
|
||||
},
|
||||
justifyContent: {
|
||||
type: ['stretch', 'start', 'center', 'end', 'around', 'between'],
|
||||
responsive: true,
|
||||
},
|
||||
style: {
|
||||
type: 'CSSProperties',
|
||||
responsive: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<PropsTable data={boxPropDefs} />
|
||||
|
||||
Padding and margin are used to create space around your component using our
|
||||
predefined spacing tokens. We would recommend to use padding over margin to
|
||||
avoid collapsing margins but both are available.
|
||||
|
||||
<PropsTable data={spacePropsList} />
|
||||
<PropsTable data={spacingPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import {
|
||||
classNamePropDefs,
|
||||
displayPropDefs,
|
||||
heightPropDefs,
|
||||
positionPropDefs,
|
||||
stylePropDefs,
|
||||
widthPropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const boxPropDefs: Record<string, PropDef> = {
|
||||
as: {
|
||||
type: 'enum',
|
||||
values: ['div', 'span'],
|
||||
default: 'div',
|
||||
responsive: true,
|
||||
},
|
||||
...widthPropDefs,
|
||||
...heightPropDefs,
|
||||
...positionPropDefs,
|
||||
...displayPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -4,6 +4,7 @@ import { spacePropsList } from '@/utils/spaceProps';
|
||||
import { Tabs } from '@/components/Tabs';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { ContainerPreview } from '@/snippets/container';
|
||||
import { containerPropDefs } from './props';
|
||||
|
||||
# Container
|
||||
|
||||
@@ -32,46 +33,7 @@ content on the page.
|
||||
|
||||
## API reference
|
||||
|
||||
<PropsTable
|
||||
data={{
|
||||
children: {
|
||||
type: 'ReactNode',
|
||||
responsive: false,
|
||||
},
|
||||
className: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
marginY: {
|
||||
type: spacePropsList.marginY.type,
|
||||
responsive: spacePropsList.marginY.responsive,
|
||||
},
|
||||
marginBottom: {
|
||||
type: spacePropsList.marginBottom.type,
|
||||
responsive: spacePropsList.marginBottom.responsive,
|
||||
},
|
||||
marginTop: {
|
||||
type: spacePropsList.marginTop.type,
|
||||
responsive: spacePropsList.marginTop.responsive,
|
||||
},
|
||||
paddingY: {
|
||||
type: spacePropsList.paddingY.type,
|
||||
responsive: spacePropsList.paddingY.responsive,
|
||||
},
|
||||
paddingBottom: {
|
||||
type: spacePropsList.paddingBottom.type,
|
||||
responsive: spacePropsList.paddingBottom.responsive,
|
||||
},
|
||||
paddingTop: {
|
||||
type: spacePropsList.paddingTop.type,
|
||||
responsive: spacePropsList.paddingTop.responsive,
|
||||
},
|
||||
style: {
|
||||
type: 'CSSProperties',
|
||||
responsive: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<PropsTable data={containerPropDefs} />
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import {
|
||||
classNamePropDefs,
|
||||
stylePropDefs,
|
||||
gapPropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
import type { PropDef } from '../../../../utils/propDefs';
|
||||
|
||||
export const containerPropDefs: Record<string, PropDef> = {
|
||||
...gapPropDefs,
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -5,6 +5,8 @@ import { Tabs } from '@/components/Tabs';
|
||||
import { grid } from '@/snippets/_snippets';
|
||||
import { Snippet } from '@/components/Snippet';
|
||||
import { GridPreview } from '@/snippets/grid';
|
||||
import { spacingPropDefs } from '../../../../utils/propDefs';
|
||||
import { gridPropDefs } from './props';
|
||||
|
||||
# Grid
|
||||
|
||||
@@ -38,34 +40,11 @@ This is the grid container component. It will help to define the number of
|
||||
columns that will be used in the grid. You can also define the gap between the
|
||||
columns. All values are responsive.
|
||||
|
||||
<PropsTable
|
||||
data={{
|
||||
columns: {
|
||||
type: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 'auto'],
|
||||
responsive: true,
|
||||
},
|
||||
gap: {
|
||||
type: ['xs', 'sm', 'md', 'lg', 'xl'],
|
||||
responsive: true,
|
||||
},
|
||||
children: {
|
||||
type: 'ReactNode',
|
||||
required: false,
|
||||
},
|
||||
className: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
},
|
||||
style: {
|
||||
type: 'CSSProperties',
|
||||
required: false,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<PropsTable data={gridPropDefs} />
|
||||
|
||||
The grid component also accepts all the spacing props from the Box component.
|
||||
|
||||
<PropsTable data={spacePropsList} />
|
||||
<PropsTable data={spacingPropDefs} />
|
||||
|
||||
### Grid.Item
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
PropDef,
|
||||
classNamePropDefs,
|
||||
displayPropDefs,
|
||||
stylePropDefs,
|
||||
} from '../../../../utils/propDefs';
|
||||
|
||||
export const gridPropDefs: Record<string, PropDef> = {
|
||||
columns: {
|
||||
type: 'enum | string',
|
||||
values: [
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'10',
|
||||
'11',
|
||||
'12',
|
||||
'auto',
|
||||
],
|
||||
responsive: true,
|
||||
default: 'auto',
|
||||
},
|
||||
children: {
|
||||
type: 'enum',
|
||||
values: ['ReactNode'],
|
||||
required: true,
|
||||
},
|
||||
...classNamePropDefs,
|
||||
...stylePropDefs,
|
||||
};
|
||||
@@ -9,6 +9,7 @@ type PropData = {
|
||||
values?: string | string[];
|
||||
responsive?: boolean;
|
||||
default?: string;
|
||||
type?: string;
|
||||
};
|
||||
|
||||
// Modify the PropsTable component to use the new type
|
||||
@@ -17,57 +18,56 @@ export const PropsTable = <T extends Record<string, PropData>>({
|
||||
}: {
|
||||
data: T;
|
||||
}) => {
|
||||
const completeData = {
|
||||
...data,
|
||||
className: {
|
||||
values: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
style: {
|
||||
values: 'CSSProperties',
|
||||
responsive: false,
|
||||
},
|
||||
};
|
||||
if (!data) return null;
|
||||
|
||||
return (
|
||||
<Table.Root>
|
||||
<Table.Header>
|
||||
<Table.HeaderRow>
|
||||
<Table.HeaderCell>Prop</Table.HeaderCell>
|
||||
<Table.HeaderCell>Type</Table.HeaderCell>
|
||||
<Table.HeaderCell>Default</Table.HeaderCell>
|
||||
<Table.HeaderCell>Responsive</Table.HeaderCell>
|
||||
<Table.HeaderCell style={{ width: '16%' }}>Prop</Table.HeaderCell>
|
||||
<Table.HeaderCell style={{ width: '56%' }}>Type</Table.HeaderCell>
|
||||
<Table.HeaderCell style={{ width: '14%' }}>Default</Table.HeaderCell>
|
||||
<Table.HeaderCell style={{ width: '14%' }}>
|
||||
Responsive
|
||||
</Table.HeaderCell>
|
||||
</Table.HeaderRow>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{Object.keys(completeData).map(n => (
|
||||
<Table.Row key={n}>
|
||||
<Table.Cell>
|
||||
<Chip head>{n}</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<div
|
||||
style={{ display: 'flex', flexWrap: 'wrap', gap: '0.375rem' }}
|
||||
>
|
||||
{completeData[n].values === 'icon' ? (
|
||||
Object.keys(icons).map(icon => <Chip key={icon}>{icon}</Chip>)
|
||||
) : Array.isArray(completeData[n].values) ? (
|
||||
completeData[n].values.map(t => <Chip key={t}>{t}</Chip>)
|
||||
) : (
|
||||
<Chip>{completeData[n].values}</Chip>
|
||||
)}
|
||||
</div>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Chip>
|
||||
{completeData[n].default ? completeData[n].default : '-'}
|
||||
</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Chip>{completeData[n].responsive ? 'Yes' : 'No'}</Chip>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
{Object.keys(data).map(n => {
|
||||
const enumValues =
|
||||
data[n].values === 'icon'
|
||||
? Object.keys(icons).map(icon => <Chip key={icon}>{icon}</Chip>)
|
||||
: Array.isArray(data[n].values) &&
|
||||
data[n].values.map(t => <Chip key={t}>{t}</Chip>);
|
||||
|
||||
return (
|
||||
<Table.Row key={n}>
|
||||
<Table.Cell style={{ width: '16%' }}>
|
||||
<Chip head>{n}</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell style={{ width: '56%' }}>
|
||||
<div
|
||||
style={{ display: 'flex', flexWrap: 'wrap', gap: '0.375rem' }}
|
||||
>
|
||||
{data[n].type === 'string' && <Chip>string</Chip>}
|
||||
{data[n].type === 'enum' && enumValues}
|
||||
{data[n].type === 'enum | string' && (
|
||||
<>
|
||||
{enumValues}
|
||||
<Chip>string</Chip>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Table.Cell>
|
||||
<Table.Cell style={{ width: '14%' }}>
|
||||
<Chip>{data[n].default ? data[n].default : '-'}</Chip>
|
||||
</Table.Cell>
|
||||
<Table.Cell style={{ width: '14%' }}>
|
||||
<Chip>{data[n].responsive ? 'Yes' : 'No'}</Chip>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
);
|
||||
})}
|
||||
</Table.Body>
|
||||
</Table.Root>
|
||||
);
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* 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 React from 'react';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
@@ -37,9 +21,18 @@ export const HeaderRow = ({ children }: { children: React.ReactNode }) => {
|
||||
return <tr>{children}</tr>;
|
||||
};
|
||||
|
||||
export const HeaderCell = ({ children }: { children: React.ReactNode }) => {
|
||||
export const HeaderCell = ({
|
||||
children,
|
||||
style,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
}) => {
|
||||
return (
|
||||
<th className={`${styles.tableCell} ${styles.tableHeaderCell}`}>
|
||||
<th
|
||||
className={`${styles.tableCell} ${styles.tableHeaderCell}`}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
</th>
|
||||
);
|
||||
@@ -49,6 +42,16 @@ export const Row = ({ children }: { children: React.ReactNode }) => {
|
||||
return <tr className={styles.tableRow}>{children}</tr>;
|
||||
};
|
||||
|
||||
export const Cell = ({ children }: { children: React.ReactNode }) => {
|
||||
return <td className={styles.tableCell}>{children}</td>;
|
||||
export const Cell = ({
|
||||
children,
|
||||
style,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
}) => {
|
||||
return (
|
||||
<td className={styles.tableCell} style={style}>
|
||||
{children}
|
||||
</td>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.wrapper {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
import type { Breakpoint } from '@backstage/canon/src/types';
|
||||
|
||||
const breakpoints = ['initial', 'xs', 'sm', 'md', 'lg', 'xl'] as Breakpoint[];
|
||||
|
||||
export type PropDef = {
|
||||
type: 'string' | 'enum' | 'enum | string';
|
||||
values?: string | string[];
|
||||
default?: string;
|
||||
required?: boolean;
|
||||
responsive?: boolean;
|
||||
};
|
||||
|
||||
export { breakpoints };
|
||||
export type { Breakpoint };
|
||||
|
||||
export const spacingValues = [
|
||||
'0.5',
|
||||
'1',
|
||||
'1.5',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'10',
|
||||
'11',
|
||||
'12',
|
||||
'13',
|
||||
'14',
|
||||
];
|
||||
|
||||
export const paddingPropDefs = (
|
||||
spacingValues: string[],
|
||||
): Record<string, PropDef> => ({
|
||||
p: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
px: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
py: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
pt: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
pr: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
pb: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
pl: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
});
|
||||
|
||||
export const marginPropDefs = (
|
||||
spacingValues: string[],
|
||||
): Record<string, PropDef> => ({
|
||||
m: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
mx: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
my: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
mt: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
mr: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
mb: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
ml: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
},
|
||||
});
|
||||
|
||||
export const spacingPropDefs = {
|
||||
...paddingPropDefs(spacingValues),
|
||||
...marginPropDefs(spacingValues),
|
||||
};
|
||||
|
||||
export const displayPropDefs: Record<string, PropDef> = {
|
||||
display: {
|
||||
type: 'enum',
|
||||
values: ['none', 'inline', 'inline-block', 'block'],
|
||||
default: 'block',
|
||||
responsive: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const gapPropDefs: Record<string, PropDef> = {
|
||||
gap: {
|
||||
type: 'enum | string',
|
||||
values: spacingValues,
|
||||
responsive: true,
|
||||
default: '4',
|
||||
},
|
||||
};
|
||||
|
||||
export const widthPropDefs: Record<string, PropDef> = {
|
||||
width: {
|
||||
type: 'string',
|
||||
default: '0',
|
||||
responsive: true,
|
||||
},
|
||||
minWidth: {
|
||||
type: 'string',
|
||||
default: '0',
|
||||
responsive: true,
|
||||
},
|
||||
maxWidth: {
|
||||
type: 'string',
|
||||
default: '0',
|
||||
responsive: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const heightPropDefs: Record<string, PropDef> = {
|
||||
height: {
|
||||
type: 'string',
|
||||
default: '0',
|
||||
responsive: true,
|
||||
},
|
||||
minHeight: {
|
||||
type: 'string',
|
||||
default: '0',
|
||||
responsive: true,
|
||||
},
|
||||
maxHeight: {
|
||||
type: 'string',
|
||||
default: '0',
|
||||
responsive: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const positionPropDefs: Record<string, PropDef> = {
|
||||
position: {
|
||||
type: 'enum',
|
||||
values: ['static', 'relative', 'absolute', 'fixed', 'sticky'],
|
||||
default: 'static',
|
||||
responsive: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const classNamePropDefs: Record<string, PropDef> = {
|
||||
className: {
|
||||
type: 'string',
|
||||
responsive: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const stylePropDefs: Record<string, PropDef> = {
|
||||
style: {
|
||||
type: 'enum',
|
||||
values: ['CSSProperties'],
|
||||
responsive: false,
|
||||
},
|
||||
};
|
||||
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const spacePropsList = [
|
||||
'margin',
|
||||
'marginBottom',
|
||||
|
||||
Reference in New Issue
Block a user