website refactor
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { ReactNode, ElementType } from 'react';
|
||||
import React, { ReactNode, ElementType, forwardRef, ForwardedRef } from 'react';
|
||||
import { Box, BoxProps, ResponsiveValue } from './Box';
|
||||
|
||||
/**
|
||||
@@ -13,8 +13,6 @@ import { Box, BoxProps, ResponsiveValue } from './Box';
|
||||
* If you need a more specific layout, create a new component in apps/website/components.
|
||||
*/
|
||||
|
||||
type Spacing = 0 | 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 3.5 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 52 | 56 | 60 | 64 | 72 | 80 | 96;
|
||||
|
||||
interface ResponsiveGap {
|
||||
base?: number;
|
||||
sm?: number;
|
||||
@@ -23,73 +21,31 @@ interface ResponsiveGap {
|
||||
xl?: number;
|
||||
}
|
||||
|
||||
interface ResponsiveSpacing {
|
||||
base?: Spacing;
|
||||
sm?: Spacing;
|
||||
md?: Spacing;
|
||||
lg?: Spacing;
|
||||
xl?: Spacing;
|
||||
'2xl'?: Spacing;
|
||||
}
|
||||
|
||||
export interface StackProps<T extends ElementType> {
|
||||
export interface StackProps<T extends ElementType> extends Omit<BoxProps<T>, 'children'> {
|
||||
as?: T;
|
||||
children: ReactNode;
|
||||
children?: ReactNode;
|
||||
className?: string;
|
||||
direction?: 'row' | 'col' | { base?: 'row' | 'col'; md?: 'row' | 'col'; lg?: 'row' | 'col' };
|
||||
gap?: number | ResponsiveGap;
|
||||
gap?: number | string | ResponsiveGap;
|
||||
align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline' | ResponsiveValue<'start' | 'center' | 'end' | 'stretch' | 'baseline'>;
|
||||
justify?: 'start' | 'center' | 'end' | 'between' | 'around' | ResponsiveValue<'start' | 'center' | 'end' | 'between' | 'around'>;
|
||||
wrap?: boolean;
|
||||
// Spacing (allowed for layout)
|
||||
m?: Spacing | ResponsiveSpacing;
|
||||
mt?: Spacing | ResponsiveSpacing;
|
||||
mb?: Spacing | ResponsiveSpacing;
|
||||
ml?: Spacing | ResponsiveSpacing;
|
||||
mr?: Spacing | ResponsiveSpacing;
|
||||
p?: Spacing | ResponsiveSpacing;
|
||||
pt?: Spacing | ResponsiveSpacing;
|
||||
pb?: Spacing | ResponsiveSpacing;
|
||||
pl?: Spacing | ResponsiveSpacing;
|
||||
pr?: Spacing | ResponsiveSpacing;
|
||||
px?: Spacing | ResponsiveSpacing;
|
||||
py?: Spacing | ResponsiveSpacing;
|
||||
// Sizing (allowed for layout)
|
||||
w?: string | ResponsiveValue<string>;
|
||||
h?: string | ResponsiveValue<string>;
|
||||
minWidth?: string | ResponsiveValue<string>;
|
||||
maxWidth?: string | ResponsiveValue<string>;
|
||||
minHeight?: string | ResponsiveValue<string>;
|
||||
maxHeight?: string | ResponsiveValue<string>;
|
||||
// Basic styling (sometimes needed for containers)
|
||||
rounded?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
|
||||
// Flex item props
|
||||
flex?: number | string;
|
||||
flexGrow?: number;
|
||||
flexShrink?: number;
|
||||
alignSelf?: 'auto' | 'start' | 'end' | 'center' | 'stretch' | 'baseline';
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export function Stack<T extends ElementType = 'div'>({
|
||||
children,
|
||||
className = '',
|
||||
direction = 'col',
|
||||
gap = 4,
|
||||
align,
|
||||
justify,
|
||||
wrap = false,
|
||||
m, mt, mb, ml, mr,
|
||||
p, pt, pb, pl, pr, px, py,
|
||||
w, h, minWidth, maxWidth, minHeight, maxHeight,
|
||||
rounded,
|
||||
flex,
|
||||
flexGrow,
|
||||
flexShrink,
|
||||
alignSelf,
|
||||
as,
|
||||
...props
|
||||
}: StackProps<T>) {
|
||||
export const Stack = forwardRef(<T extends ElementType = 'div'>(
|
||||
{
|
||||
children,
|
||||
className = '',
|
||||
direction = 'col',
|
||||
gap = 4,
|
||||
align,
|
||||
justify,
|
||||
wrap = false,
|
||||
as,
|
||||
...props
|
||||
}: StackProps<T>,
|
||||
ref: ForwardedRef<HTMLElement>
|
||||
) => {
|
||||
const gapClasses: Record<number, string> = {
|
||||
0: 'gap-0',
|
||||
1: 'gap-1',
|
||||
@@ -104,50 +60,19 @@ export function Stack<T extends ElementType = 'div'>({
|
||||
16: 'gap-16'
|
||||
};
|
||||
|
||||
const getGapClasses = (value: number | ResponsiveGap | undefined) => {
|
||||
const getGapClasses = (value: number | string | ResponsiveGap | undefined) => {
|
||||
if (value === undefined) return '';
|
||||
if (typeof value === 'object') {
|
||||
const classes = [];
|
||||
if (value.base !== undefined) classes.push(gapClasses[value.base]);
|
||||
if (value.sm !== undefined) classes.push(`sm:${gapClasses[value.sm]}`);
|
||||
if (value.md !== undefined) classes.push(`md:${gapClasses[value.md]}`);
|
||||
if (value.lg !== undefined) classes.push(`lg:${gapClasses[value.lg]}`);
|
||||
if (value.xl !== undefined) classes.push(`xl:${gapClasses[value.xl]}`);
|
||||
if (value.base !== undefined) classes.push(typeof value.base === 'number' ? gapClasses[value.base] : `gap-${value.base}`);
|
||||
if (value.sm !== undefined) classes.push(typeof value.sm === 'number' ? `sm:${gapClasses[value.sm]}` : `sm:gap-${value.sm}`);
|
||||
if (value.md !== undefined) classes.push(typeof value.md === 'number' ? `md:${gapClasses[value.md]}` : `md:gap-${value.md}`);
|
||||
if (value.lg !== undefined) classes.push(typeof value.lg === 'number' ? `lg:${gapClasses[value.lg]}` : `lg:gap-${value.lg}`);
|
||||
if (value.xl !== undefined) classes.push(typeof value.xl === 'number' ? `xl:${gapClasses[value.xl]}` : `xl:gap-${value.xl}`);
|
||||
return classes.join(' ');
|
||||
}
|
||||
return gapClasses[value];
|
||||
};
|
||||
|
||||
const spacingMap: Record<number, string> = {
|
||||
0: '0', 0.5: '0.5', 1: '1', 1.5: '1.5', 2: '2', 2.5: '2.5', 3: '3', 3.5: '3.5', 4: '4',
|
||||
5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12', 14: '14',
|
||||
16: '16', 20: '20', 24: '24', 28: '28', 32: '32', 36: '36', 40: '40', 44: '44',
|
||||
48: '48', 52: '52', 56: '56', 60: '60', 64: '64', 72: '72', 80: '80', 96: '96'
|
||||
};
|
||||
|
||||
const roundedClasses = {
|
||||
none: 'rounded-none',
|
||||
sm: 'rounded-sm',
|
||||
md: 'rounded-md',
|
||||
lg: 'rounded-lg',
|
||||
xl: 'rounded-xl',
|
||||
'2xl': 'rounded-2xl',
|
||||
full: 'rounded-full'
|
||||
};
|
||||
|
||||
const getSpacingClass = (prefix: string, value: Spacing | ResponsiveSpacing | undefined) => {
|
||||
if (value === undefined) return '';
|
||||
if (typeof value === 'object') {
|
||||
const classes = [];
|
||||
if (value.base !== undefined) classes.push(`${prefix}-${spacingMap[value.base]}`);
|
||||
if (value.sm !== undefined) classes.push(`sm:${prefix}-${spacingMap[value.sm]}`);
|
||||
if (value.md !== undefined) classes.push(`md:${prefix}-${spacingMap[value.md]}`);
|
||||
if (value.lg !== undefined) classes.push(`lg:${prefix}-${spacingMap[value.lg]}`);
|
||||
if (value.xl !== undefined) classes.push(`xl:${prefix}-${spacingMap[value.xl]}`);
|
||||
if (value['2xl'] !== undefined) classes.push(`2xl:${prefix}-${spacingMap[value['2xl']]}`);
|
||||
return classes.join(' ');
|
||||
}
|
||||
return `${prefix}-${spacingMap[value]}`;
|
||||
if (typeof value === 'number') return gapClasses[value];
|
||||
return `gap-${value}`;
|
||||
};
|
||||
|
||||
const classes = [
|
||||
@@ -161,19 +86,6 @@ export function Stack<T extends ElementType = 'div'>({
|
||||
].filter(Boolean).join(' '),
|
||||
getGapClasses(gap) || 'gap-4',
|
||||
wrap ? 'flex-wrap' : '',
|
||||
getSpacingClass('m', m),
|
||||
getSpacingClass('mt', mt),
|
||||
getSpacingClass('mb', mb),
|
||||
getSpacingClass('ml', ml),
|
||||
getSpacingClass('mr', mr),
|
||||
getSpacingClass('p', p),
|
||||
getSpacingClass('pt', pt),
|
||||
getSpacingClass('pb', pb),
|
||||
getSpacingClass('pl', pl),
|
||||
getSpacingClass('pr', pr),
|
||||
getSpacingClass('px', px),
|
||||
getSpacingClass('py', py),
|
||||
rounded ? roundedClasses[rounded] : '',
|
||||
className
|
||||
].filter(Boolean).join(' ');
|
||||
|
||||
@@ -217,20 +129,13 @@ export function Stack<T extends ElementType = 'div'>({
|
||||
return (
|
||||
<Box
|
||||
as={as}
|
||||
ref={ref}
|
||||
className={`${classes} ${layoutClasses}`}
|
||||
w={w}
|
||||
h={h}
|
||||
minWidth={minWidth}
|
||||
maxWidth={maxWidth}
|
||||
minHeight={minHeight}
|
||||
maxHeight={maxHeight}
|
||||
flex={flex}
|
||||
flexGrow={flexGrow}
|
||||
flexShrink={flexShrink}
|
||||
alignSelf={alignSelf}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Stack.displayName = 'Stack';
|
||||
|
||||
Reference in New Issue
Block a user