diff --git a/packages/fuselage/src/.storybook/PropsVariation.tsx b/packages/fuselage/src/.storybook/PropsVariation.tsx index 0e80022d89..090feafe4e 100644 --- a/packages/fuselage/src/.storybook/PropsVariation.tsx +++ b/packages/fuselage/src/.storybook/PropsVariation.tsx @@ -1,5 +1,5 @@ import React, { ComponentType } from 'react'; -import { Box } from '../components/Box'; +import Box from '../components/Box'; function PropsVariation({ component: Component, diff --git a/packages/fuselage/src/components/Accordion/Accordion.tsx b/packages/fuselage/src/components/Accordion/Accordion.tsx index 5860a7c959..7a80e54fd8 100644 --- a/packages/fuselage/src/components/Accordion/Accordion.tsx +++ b/packages/fuselage/src/components/Accordion/Accordion.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactElement, ReactNode } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { AccordionItem } from './AccordionItem'; type AccordionProps = ComponentProps & { diff --git a/packages/fuselage/src/components/Accordion/AccordionItem.tsx b/packages/fuselage/src/components/Accordion/AccordionItem.tsx index 2830f6385e..fbf72361d1 100644 --- a/packages/fuselage/src/components/Accordion/AccordionItem.tsx +++ b/packages/fuselage/src/components/Accordion/AccordionItem.tsx @@ -2,7 +2,7 @@ import { useToggle, useUniqueId } from '@rocket.chat/fuselage-hooks'; import type { FormEvent, KeyboardEvent, MouseEvent, ReactNode } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Chevron } from '../Chevron'; import { ToggleSwitch } from '../ToggleSwitch'; diff --git a/packages/fuselage/src/components/AutoComplete/AutoComplete.js b/packages/fuselage/src/components/AutoComplete/AutoComplete.js index cb8c3c54df..6fb6120219 100644 --- a/packages/fuselage/src/components/AutoComplete/AutoComplete.js +++ b/packages/fuselage/src/components/AutoComplete/AutoComplete.js @@ -5,7 +5,7 @@ import { import React, { useEffect, useRef, useMemo, useState } from 'react'; import AnimatedVisibility from '../AnimatedVisibility'; -import { Box } from '../Box'; +import Box from '../Box'; import Chip from '../Chip'; import { Icon } from '../Icon'; import { InputBox } from '../InputBox'; diff --git a/packages/fuselage/src/components/Box/Box.spec.tsx b/packages/fuselage/src/components/Box/Box.spec.tsx index 5953263897..503b6a64cf 100644 --- a/packages/fuselage/src/components/Box/Box.spec.tsx +++ b/packages/fuselage/src/components/Box/Box.spec.tsx @@ -2,7 +2,7 @@ import { css } from '@rocket.chat/css-in-js'; import { render } from '@testing-library/react'; import React from 'react'; -import { Box } from '../..'; +import Box from '.'; it('renders without crashing', () => { render(); diff --git a/packages/fuselage/src/components/Box/Box.tsx b/packages/fuselage/src/components/Box/Box.tsx new file mode 100644 index 0000000000..113249d146 --- /dev/null +++ b/packages/fuselage/src/components/Box/Box.tsx @@ -0,0 +1,66 @@ +import type { cssFn } from '@rocket.chat/css-in-js'; +import React, { createElement, forwardRef, memo } from 'react'; +import type { + AllHTMLAttributes, + ElementType, + RefAttributes, + SVGAttributes, + Ref, +} from 'react'; + +import { useArrayLikeClassNameProp } from '../../hooks/useArrayLikeClassNameProp'; +import { useBoxOnlyProps } from '../../hooks/useBoxOnlyProps'; +import { useStyleSheet } from '../../hooks/useStyleSheet'; +import type { Falsy } from '../../types/Falsy'; +import { useBoxTransform, BoxTransforms } from './BoxTransforms'; +import type { StylingProps } from './stylingProps'; +import { useStylingProps } from './useStylingProps'; + +type BoxProps = { + is?: ElementType; + className?: string | cssFn | (string | cssFn | Falsy)[]; + animated?: boolean; + withRichContent?: boolean | 'inlineWithoutBreaks'; + htmlSize?: AllHTMLAttributes['size']; +} & Partial & + Omit< + AllHTMLAttributes, + 'ref' | 'is' | 'className' | 'size' | 'elevation' + > & + Omit< + SVGAttributes, + keyof AllHTMLAttributes | 'elevation' + >; + +export const Box = forwardRef(function Box( + { is = 'div', children, ...props }: BoxProps, + ref: Ref +) { + useStyleSheet(); + + const propsWithRef: BoxProps & RefAttributes = props; + + if (ref) { + propsWithRef.ref = ref; + } + + let propsWithStringClassName = useArrayLikeClassNameProp(propsWithRef); + + const transformFn = useBoxTransform(); + if (transformFn) { + propsWithStringClassName = transformFn(propsWithStringClassName); + } + + const propsWithoutStylingProps = useStylingProps(propsWithStringClassName); + const propsWithoutBoxOnlyProps = useBoxOnlyProps(propsWithoutStylingProps); + + const element = createElement(is, propsWithoutBoxOnlyProps, children); + + if (transformFn) { + return ; + } + + return element; +}); + +export default memo(Box); diff --git a/packages/fuselage/src/components/Box/index.d.ts b/packages/fuselage/src/components/Box/index.d.ts deleted file mode 100644 index 1ed1d1b1ad..0000000000 --- a/packages/fuselage/src/components/Box/index.d.ts +++ /dev/null @@ -1,188 +0,0 @@ -import type { cssFn } from '@rocket.chat/css-in-js'; -import type { - AllHTMLAttributes, - ComponentProps, - CSSProperties, - ElementType, - ReactElement, - RefAttributes, - SVGAttributes, -} from 'react'; - -type Size = '1' | '2' | '4' | '8' | '12' | '16' | '20' | '24' | '32' | '40'; - -type FontScale = - | 'hero' - | 'h1' - | 'h2' - | 'h3' - | 'h4' - | 'h5' - | 'p1' - | 'p1m' - | 'p1b' - | 'p2' - | 'p2m' - | 'p2b' - | 'c1' - | 'c2' - | 'micro'; - -type Falsy = false | 0 | '' | null | undefined; - -type BoxStylingProps = { - border?: CSSProperties['border']; - borderBlock?: CSSProperties['borderBlock']; - borderBlockStart?: CSSProperties['borderBlockStart']; - borderBlockEnd?: CSSProperties['borderBlockEnd']; - borderInline?: CSSProperties['borderInline']; - borderInlineStart?: CSSProperties['borderInlineStart']; - borderInlineEnd?: CSSProperties['borderInlineEnd']; - borderWidth?: CSSProperties['borderWidth']; - borderBlockWidth?: CSSProperties['borderBlockWidth']; - borderBlockStartWidth?: CSSProperties['borderBlockStartWidth']; - borderBlockEndWidth?: CSSProperties['borderBlockEndWidth']; - borderInlineWidth?: CSSProperties['borderInlineWidth']; - borderInlineStartWidth?: CSSProperties['borderInlineStartWidth']; - borderInlineEndWidth?: CSSProperties['borderInlineEndWidth']; - borderStyle?: CSSProperties['borderStyle']; - borderBlockStyle?: CSSProperties['borderBlockStyle']; - borderBlockStartStyle?: CSSProperties['borderBlockStartStyle']; - borderBlockEndStyle?: CSSProperties['borderBlockEndStyle']; - borderInlineStyle?: CSSProperties['borderInlineStyle']; - borderInlineStartStyle?: CSSProperties['borderInlineStartStyle']; - borderInlineEndStyle?: CSSProperties['borderInlineEndStyle']; - borderColor?: CSSProperties['borderColor']; - borderBlockColor?: CSSProperties['borderBlockColor']; - borderBlockStartColor?: CSSProperties['borderBlockStartColor']; - borderBlockEndColor?: CSSProperties['borderBlockEndColor']; - borderInlineColor?: CSSProperties['borderInlineColor']; - borderInlineStartColor?: CSSProperties['borderInlineStartColor']; - borderInlineEndColor?: CSSProperties['borderInlineEndColor']; - borderRadius?: CSSProperties['borderRadius']; - borderStartStartRadius?: CSSProperties['borderStartStartRadius']; - borderStartEndRadius?: CSSProperties['borderStartEndRadius']; - borderEndStartRadius?: CSSProperties['borderEndStartRadius']; - borderEndEndRadius?: CSSProperties['borderEndEndRadius']; - - color?: CSSProperties['color']; - backgroundColor?: CSSProperties['backgroundColor']; - bg?: CSSProperties['backgroundColor']; - opacity?: CSSProperties['opacity']; - - alignItems?: CSSProperties['alignItems']; - alignContent?: CSSProperties['alignContent']; - justifyItems?: CSSProperties['justifyItems']; - justifyContent?: CSSProperties['justifyContent']; - flexWrap?: CSSProperties['flexWrap']; - flexDirection?: CSSProperties['flexDirection']; - flexGrow?: CSSProperties['flexGrow']; - flexShrink?: CSSProperties['flexShrink']; - flexBasis?: CSSProperties['flexBasis']; - justifySelf?: CSSProperties['justifySelf']; - alignSelf?: CSSProperties['alignSelf']; - order?: CSSProperties['order']; - - w?: CSSProperties['width']; - width?: CSSProperties['width']; - minWidth?: CSSProperties['minWidth']; - maxWidth?: CSSProperties['maxWidth']; - h?: CSSProperties['height']; - height?: CSSProperties['height']; - minHeight?: CSSProperties['minHeight']; - maxHeight?: CSSProperties['maxHeight']; - display?: CSSProperties['display']; - verticalAlign?: CSSProperties['verticalAlign']; - overflow?: CSSProperties['overflow']; - overflowX?: CSSProperties['overflowX']; - overflowY?: CSSProperties['overflowY']; - - position?: CSSProperties['position']; - zIndex?: CSSProperties['zIndex']; - inset?: CSSProperties['inset']; - insetBlock?: CSSProperties['insetBlock']; - insetBlockStart?: CSSProperties['insetBlockStart']; - insetBlockEnd?: CSSProperties['insetBlockEnd']; - insetInline?: CSSProperties['insetInline']; - insetInlineStart?: CSSProperties['insetInlineStart']; - insetInlineEnd?: CSSProperties['insetInlineEnd']; - - m?: CSSProperties['margin']; - margin?: CSSProperties['margin']; - mb?: CSSProperties['marginBlock']; - marginBlock?: CSSProperties['marginBlock']; - mbs?: CSSProperties['marginBlockStart']; - marginBlockStart?: CSSProperties['marginBlockStart']; - mbe?: CSSProperties['marginBlockEnd']; - marginBlockEnd?: CSSProperties['marginBlockEnd']; - mi?: CSSProperties['marginInline']; - marginInline?: CSSProperties['marginInline']; - mis?: CSSProperties['marginInlineStart']; - marginInlineStart?: CSSProperties['marginInlineStart']; - mie?: CSSProperties['marginInlineEnd']; - marginInlineEnd?: CSSProperties['marginInlineEnd']; - p?: CSSProperties['padding']; - padding?: CSSProperties['padding']; - pb?: CSSProperties['paddingBlock']; - paddingBlock?: CSSProperties['paddingBlock']; - pbs?: CSSProperties['paddingBlockStart']; - paddingBlockStart?: CSSProperties['paddingBlockStart']; - pbe?: CSSProperties['paddingBlockEnd']; - paddingBlockEnd?: CSSProperties['paddingBlockEnd']; - pi?: CSSProperties['paddingInline']; - paddingInline?: CSSProperties['paddingInline']; - pis?: CSSProperties['paddingInlineStart']; - paddingInlineStart?: CSSProperties['paddingInlineStart']; - pie?: CSSProperties['paddingInlineEnd']; - paddingInlineEnd?: CSSProperties['paddingInlineEnd']; - - fontFamily?: CSSProperties['fontFamily'] | FontScale; - fontSize?: CSSProperties['fontSize'] | FontScale; - fontStyle?: CSSProperties['fontStyle']; - fontWeight?: CSSProperties['fontWeight'] | FontScale; - letterSpacing?: CSSProperties['letterSpacing'] | FontScale; - lineHeight?: CSSProperties['lineHeight'] | FontScale; - textAlign?: CSSProperties['textAlign']; - textTransform?: CSSProperties['textTransform']; - textDecorationLine?: CSSProperties['textDecorationLine']; - - animated?: boolean; - elevation?: '0' | '1' | '2'; - invisible?: boolean; - withRichContent?: boolean | string; - withTruncatedText?: boolean; - size?: `x${Size}` | `neg-x${Size}` | CSSProperties['blockSize']; - minSize?: CSSProperties['blockSize']; - maxSize?: CSSProperties['blockSize']; - fontScale?: FontScale; - - className?: string | cssFn | (string | cssFn | Falsy)[]; -}; - -export type BoxProps = { - is?: TElementType; - htmlSize?: 'size' extends keyof ComponentProps - ? ComponentProps['size'] - : never; -} & BoxStylingProps & - Omit, 'is' | 'className' | 'size'>; - -type UnsafeBoxProps = { - is?: ElementType; - htmlSize?: AllHTMLAttributes['size']; -} & BoxStylingProps & - Omit, 'ref' | 'is' | 'className' | 'size'> & - Omit, keyof AllHTMLAttributes> & - RefAttributes; - -export const Box: { - // `Box` unfortunately cannot be a generic component because of the abuse of `ComponentProps` - // ( - // props: BoxProps - // ): ReactElement | null; - (props: UnsafeBoxProps): ReactElement | null; - defaultProps?: undefined; - propTypes?: undefined; - displayName?: string | undefined; - readonly $$typeof: symbol; -}; diff --git a/packages/fuselage/src/components/Box/index.js b/packages/fuselage/src/components/Box/index.js deleted file mode 100644 index a2b32111c2..0000000000 --- a/packages/fuselage/src/components/Box/index.js +++ /dev/null @@ -1,37 +0,0 @@ -import React, { createElement, forwardRef, memo } from 'react'; - -import { useArrayLikeClassNameProp } from '../../hooks/useArrayLikeClassNameProp'; -import { useBoxOnlyProps } from '../../hooks/useBoxOnlyProps'; -import { useStyleSheet } from '../../hooks/useStyleSheet'; -import { useBoxTransform, BoxTransforms } from './BoxTransforms'; -import { useStylingProps } from './stylingProps'; - -export const Box = memo( - forwardRef(function Box({ is = 'div', children, ...props }, ref) { - useStyleSheet(); - - if (ref) { - props.ref = ref; - } - - props = useArrayLikeClassNameProp(props); - - const transformFn = useBoxTransform(); - if (transformFn) { - props = transformFn(props); - } - - props = useBoxOnlyProps(props); - props = useStylingProps(props); - - const element = createElement(is, props, children); - - if (transformFn) { - return ; - } - - return element; - }) -); - -Box.displayName = 'Box'; diff --git a/packages/fuselage/src/components/Box/index.tsx b/packages/fuselage/src/components/Box/index.tsx new file mode 100644 index 0000000000..a3e93ac535 --- /dev/null +++ b/packages/fuselage/src/components/Box/index.tsx @@ -0,0 +1 @@ +export { default } from './Box'; diff --git a/packages/fuselage/src/components/Box/stylingProps.js b/packages/fuselage/src/components/Box/stylingProps.js deleted file mode 100644 index 8aff0f9ba4..0000000000 --- a/packages/fuselage/src/components/Box/stylingProps.js +++ /dev/null @@ -1,352 +0,0 @@ -import { css } from '@rocket.chat/css-in-js'; - -import { appendClassName } from '../../helpers/appendClassName'; -import { fromCamelToKebab } from '../../helpers/fromCamelToKebab'; -import { useStyle } from '../../hooks/useStyle'; -import { - borderWidth, - borderRadius, - color, - size, - inset, - margin, - padding, - fontFamily, - fontScale, -} from '../../styleTokens'; - -const stringProp = { - toCSSValue: (value) => (typeof value === 'string' ? value : undefined), -}; - -const numberOrStringProp = { - toCSSValue: (value) => { - if (typeof value === 'number' || typeof value === 'string') { - return String(value); - } - }, -}; - -const borderWidthProp = { - toCSSValue: borderWidth, -}; - -const borderRadiusProp = { - toCSSValue: borderRadius, -}; - -const colorProp = { - toCSSValue: color, -}; - -const sizeProp = { - toCSSValue: size, -}; - -const insetProp = { - toCSSValue: inset, -}; - -const marginProp = { - toCSSValue: margin, -}; - -const paddingProp = { - toCSSValue: padding, -}; - -const fontFamilyProp = { - toCSSValue: fontFamily, -}; - -const fontSizeProp = { - toCSSValue: (value) => fontScale(value)?.fontSize || size(value), -}; - -const fontWeightProp = { - toCSSValue: (value) => fontScale(value)?.fontWeight || value, -}; - -const lineHeightProp = { - toCSSValue: (value) => fontScale(value)?.lineHeight || size(value), -}; - -const letterSpacingProp = { - toCSSValue: (value) => fontScale(value)?.letterSpacing || value, -}; - -const aliasOf = (propName) => ({ - aliasOf: propName, -}); - -const propDefs = { - border: stringProp, - borderBlock: stringProp, - borderBlockStart: stringProp, - borderBlockEnd: stringProp, - borderInline: stringProp, - borderInlineStart: stringProp, - borderInlineEnd: stringProp, - borderWidth: borderWidthProp, - borderBlockWidth: borderWidthProp, - borderBlockStartWidth: borderWidthProp, - borderBlockEndWidth: borderWidthProp, - borderInlineWidth: borderWidthProp, - borderInlineStartWidth: borderWidthProp, - borderInlineEndWidth: borderWidthProp, - borderStyle: stringProp, - borderBlockStyle: stringProp, - borderBlockStartStyle: stringProp, - borderBlockEndStyle: stringProp, - borderInlineStyle: stringProp, - borderInlineStartStyle: stringProp, - borderInlineEndStyle: stringProp, - borderColor: colorProp, - borderBlockColor: colorProp, - borderBlockStartColor: colorProp, - borderBlockEndColor: colorProp, - borderInlineColor: colorProp, - borderInlineStartColor: colorProp, - borderInlineEndColor: colorProp, - borderRadius: borderRadiusProp, - borderStartStartRadius: borderRadiusProp, - borderStartEndRadius: borderRadiusProp, - borderEndStartRadius: borderRadiusProp, - borderEndEndRadius: borderRadiusProp, - - color: colorProp, - backgroundColor: colorProp, - bg: aliasOf('backgroundColor'), - opacity: numberOrStringProp, - - alignItems: stringProp, - alignContent: stringProp, - justifyItems: stringProp, - justifyContent: stringProp, - flexWrap: stringProp, - flexDirection: stringProp, - flexGrow: numberOrStringProp, - flexShrink: numberOrStringProp, - flexBasis: stringProp, - justifySelf: stringProp, - alignSelf: stringProp, - order: numberOrStringProp, - - w: aliasOf('width'), - width: sizeProp, - minWidth: sizeProp, - maxWidth: sizeProp, - h: aliasOf('height'), - height: sizeProp, - minHeight: sizeProp, - maxHeight: sizeProp, - display: stringProp, - verticalAlign: stringProp, - overflow: stringProp, - overflowX: stringProp, - overflowY: stringProp, - - position: stringProp, - zIndex: numberOrStringProp, - inset: insetProp, - insetBlock: insetProp, - insetBlockStart: insetProp, - insetBlockEnd: insetProp, - insetInline: insetProp, - insetInlineStart: insetProp, - insetInlineEnd: insetProp, - - m: aliasOf('margin'), - margin: marginProp, - mb: aliasOf('marginBlock'), - marginBlock: marginProp, - mbs: aliasOf('marginBlockStart'), - marginBlockStart: marginProp, - mbe: aliasOf('marginBlockEnd'), - marginBlockEnd: marginProp, - mi: aliasOf('marginInline'), - marginInline: marginProp, - mis: aliasOf('marginInlineStart'), - marginInlineStart: marginProp, - mie: aliasOf('marginInlineEnd'), - marginInlineEnd: marginProp, - p: aliasOf('padding'), - padding: paddingProp, - pb: aliasOf('paddingBlock'), - paddingBlock: paddingProp, - pbs: aliasOf('paddingBlockStart'), - paddingBlockStart: paddingProp, - pbe: aliasOf('paddingBlockEnd'), - paddingBlockEnd: paddingProp, - pi: aliasOf('paddingInline'), - paddingInline: paddingProp, - pis: aliasOf('paddingInlineStart'), - paddingInlineStart: paddingProp, - pie: aliasOf('paddingInlineEnd'), - paddingInlineEnd: paddingProp, - - fontFamily: fontFamilyProp, - fontSize: fontSizeProp, - fontStyle: stringProp, - fontWeight: fontWeightProp, - letterSpacing: letterSpacingProp, - lineHeight: lineHeightProp, - textAlign: stringProp, - textTransform: stringProp, - textDecorationLine: stringProp, - - elevation: { - toStyle: (value) => { - if (value === '0') { - return css` - box-shadow: none; - `; - } - - if (value === '1') { - return css` - box-shadow: 0px 0px 12px 0px ${color('neutral-800-10')}; - `; - } - - if (value === '2') { - return css` - box-shadow: 0px 0px 2px 0px ${color('neutral-800-8')}, - 0px 0px 12px 0px ${color('neutral-800-12')}; - `; - } - }, - }, - invisible: { - toStyle: (value) => - value - ? css` - visibility: hidden; - opacity: 0; - ` - : undefined, - }, - withTruncatedText: { - toStyle: (value) => - value - ? css` - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - ` - : undefined, - }, - size: { - toStyle: (value) => - size(value) - ? css` - width: ${size(value)} !important; - height: ${size(value)} !important; - ` - : undefined, - }, - minSize: { - toStyle: (value) => - size(value) - ? css` - min-width: ${size(value)} !important; - min-height: ${size(value)} !important; - ` - : undefined, - }, - maxSize: { - toStyle: (value) => - size(value) - ? css` - max-width: ${size(value)} !important; - max-height: ${size(value)} !important; - ` - : undefined, - }, - fontScale: { - toStyle: (value) => css` - font-size: ${fontScale(value)?.fontSize} !important; - font-weight: ${fontScale(value)?.fontWeight} !important; - letter-spacing: ${fontScale(value)?.letterSpacing} !important; - line-height: ${fontScale(value)?.lineHeight} !important; - `, - }, -}; - -export const useStylingProps = (originalProps) => { - const { htmlSize, ...props } = originalProps; - - const stylingProps = new Map(); - - for (const entry of Object.entries(props)) { - const [propName, propValue] = entry; - const propDef = propDefs[propName]; - - if (!propDef) { - continue; - } - - delete props[propName]; - - if (propValue === undefined) { - continue; - } - - let effectivePropName = propName; - let effectivePropDef = propDef; - - if (effectivePropDef.aliasOf) { - if (stylingProps.has(effectivePropDef.aliasOf)) { - continue; - } - - effectivePropName = effectivePropDef.aliasOf; - effectivePropDef = propDefs[effectivePropName]; - } - - let { toStyle } = effectivePropDef; - - if (effectivePropDef.toCSSValue) { - const cssProperty = fromCamelToKebab(effectivePropName); - const { toCSSValue } = effectivePropDef; - toStyle = (value) => { - const cssValue = toCSSValue(value); - if (cssValue === undefined) { - return; - } - - return css` - ${cssProperty}: ${cssValue} !important; - `; - }; - } - - const style = toStyle(propValue); - - if (style === undefined) { - continue; - } - - stylingProps.set(effectivePropName, style); - } - - const styles = stylingProps.size - ? Array.from(stylingProps.values()) - : undefined; - - const newClassName = useStyle( - css` - ${styles} - ` - ); - - if (newClassName) { - props.className = appendClassName(props.className, newClassName); - } - - if (htmlSize) { - props.size = htmlSize; - } - - return props; -}; diff --git a/packages/fuselage/src/components/Box/stylingProps.ts b/packages/fuselage/src/components/Box/stylingProps.ts new file mode 100644 index 0000000000..33a520cdba --- /dev/null +++ b/packages/fuselage/src/components/Box/stylingProps.ts @@ -0,0 +1,525 @@ +import type { cssFn } from '@rocket.chat/css-in-js'; +import { css } from '@rocket.chat/css-in-js'; +import type { CSSProperties } from 'react'; + +import { fromCamelToKebab } from '../../helpers/fromCamelToKebab'; +import { + borderRadius, + borderWidth, + color, + fontFamily, + fontScale, + inset, + margin, + padding, + size, +} from '../../styleTokens'; + +type FontScale = + | 'hero' + | 'h1' + | 'h2' + | 'h3' + | 'h4' + | 'h5' + | 'p1' + | 'p1m' + | 'p1b' + | 'p2' + | 'p2m' + | 'p2b' + | 'c1' + | 'c2' + | 'micro'; + +export type StylingProps = { + border: CSSProperties['border']; + borderBlock: CSSProperties['borderBlock']; + borderBlockStart: CSSProperties['borderBlockStart']; + borderBlockEnd: CSSProperties['borderBlockEnd']; + borderInline: CSSProperties['borderInline']; + borderInlineStart: CSSProperties['borderInlineStart']; + borderInlineEnd: CSSProperties['borderInlineEnd']; + borderWidth: CSSProperties['borderWidth']; + borderBlockWidth: CSSProperties['borderBlockWidth']; + borderBlockStartWidth: CSSProperties['borderBlockStartWidth']; + borderBlockEndWidth: CSSProperties['borderBlockEndWidth']; + borderInlineWidth: CSSProperties['borderInlineWidth']; + borderInlineStartWidth: CSSProperties['borderInlineStartWidth']; + borderInlineEndWidth: CSSProperties['borderInlineEndWidth']; + borderStyle: CSSProperties['borderStyle']; + borderBlockStyle: CSSProperties['borderBlockStyle']; + borderBlockStartStyle: CSSProperties['borderBlockStartStyle']; + borderBlockEndStyle: CSSProperties['borderBlockEndStyle']; + borderInlineStyle: CSSProperties['borderInlineStyle']; + borderInlineStartStyle: CSSProperties['borderInlineStartStyle']; + borderInlineEndStyle: CSSProperties['borderInlineEndStyle']; + borderColor: CSSProperties['borderColor']; + borderBlockColor: CSSProperties['borderBlockColor']; + borderBlockStartColor: CSSProperties['borderBlockStartColor']; + borderBlockEndColor: CSSProperties['borderBlockEndColor']; + borderInlineColor: CSSProperties['borderInlineColor']; + borderInlineStartColor: CSSProperties['borderInlineStartColor']; + borderInlineEndColor: CSSProperties['borderInlineEndColor']; + borderRadius: CSSProperties['borderRadius']; + borderStartStartRadius: CSSProperties['borderStartStartRadius']; + borderStartEndRadius: CSSProperties['borderStartEndRadius']; + borderEndStartRadius: CSSProperties['borderEndStartRadius']; + borderEndEndRadius: CSSProperties['borderEndEndRadius']; + + color: CSSProperties['color']; + backgroundColor: CSSProperties['backgroundColor']; + bg: CSSProperties['backgroundColor']; + opacity: CSSProperties['opacity']; + + alignItems: CSSProperties['alignItems']; + alignContent: CSSProperties['alignContent']; + justifyItems: CSSProperties['justifyItems']; + justifyContent: CSSProperties['justifyContent']; + flexWrap: CSSProperties['flexWrap']; + flexDirection: CSSProperties['flexDirection']; + flexGrow: CSSProperties['flexGrow']; + flexShrink: CSSProperties['flexShrink']; + flexBasis: CSSProperties['flexBasis']; + justifySelf: CSSProperties['justifySelf']; + alignSelf: CSSProperties['alignSelf']; + order: CSSProperties['order']; + + w: CSSProperties['width']; + width: CSSProperties['width']; + minWidth: CSSProperties['minWidth']; + maxWidth: CSSProperties['maxWidth']; + h: CSSProperties['height']; + height: CSSProperties['height']; + minHeight: CSSProperties['minHeight']; + maxHeight: CSSProperties['maxHeight']; + display: CSSProperties['display']; + verticalAlign: CSSProperties['verticalAlign']; + overflow: CSSProperties['overflow']; + overflowX: CSSProperties['overflowX']; + overflowY: CSSProperties['overflowY']; + + position: CSSProperties['position']; + zIndex: CSSProperties['zIndex']; + inset: CSSProperties['inset']; + insetBlock: CSSProperties['insetBlock']; + insetBlockStart: CSSProperties['insetBlockStart']; + insetBlockEnd: CSSProperties['insetBlockEnd']; + insetInline: CSSProperties['insetInline']; + insetInlineStart: CSSProperties['insetInlineStart']; + insetInlineEnd: CSSProperties['insetInlineEnd']; + + m: CSSProperties['margin']; + margin: CSSProperties['margin']; + mb: CSSProperties['marginBlock']; + marginBlock: CSSProperties['marginBlock']; + mbs: CSSProperties['marginBlockStart']; + marginBlockStart: CSSProperties['marginBlockStart']; + mbe: CSSProperties['marginBlockEnd']; + marginBlockEnd: CSSProperties['marginBlockEnd']; + mi: CSSProperties['marginInline']; + marginInline: CSSProperties['marginInline']; + mis: CSSProperties['marginInlineStart']; + marginInlineStart: CSSProperties['marginInlineStart']; + mie: CSSProperties['marginInlineEnd']; + marginInlineEnd: CSSProperties['marginInlineEnd']; + p: CSSProperties['padding']; + padding: CSSProperties['padding']; + pb: CSSProperties['paddingBlock']; + paddingBlock: CSSProperties['paddingBlock']; + pbs: CSSProperties['paddingBlockStart']; + paddingBlockStart: CSSProperties['paddingBlockStart']; + pbe: CSSProperties['paddingBlockEnd']; + paddingBlockEnd: CSSProperties['paddingBlockEnd']; + pi: CSSProperties['paddingInline']; + paddingInline: CSSProperties['paddingInline']; + pis: CSSProperties['paddingInlineStart']; + paddingInlineStart: CSSProperties['paddingInlineStart']; + pie: CSSProperties['paddingInlineEnd']; + paddingInlineEnd: CSSProperties['paddingInlineEnd']; + + fontFamily: CSSProperties['fontFamily'] | FontScale; + fontSize: CSSProperties['fontSize'] | FontScale; + fontStyle: CSSProperties['fontStyle']; + fontWeight: CSSProperties['fontWeight'] | FontScale; + letterSpacing: CSSProperties['letterSpacing'] | FontScale; + lineHeight: CSSProperties['lineHeight'] | FontScale; + textAlign: CSSProperties['textAlign']; + textTransform: CSSProperties['textTransform']; + textDecorationLine: CSSProperties['textDecorationLine']; + + elevation: '0' | '1' | '2'; + invisible: boolean; + withTruncatedText: boolean; + size: CSSProperties['blockSize']; + minSize: CSSProperties['blockSize']; + maxSize: CSSProperties['blockSize']; + fontScale: FontScale; +}; + +type PropDefinition = + | { + toCSSValue: (value: unknown) => string | undefined; + } + | { aliasOf: keyof StylingProps } + | { + toStyle: (value: unknown) => cssFn | undefined; + }; + +const stringProp: PropDefinition = { + toCSSValue: (value) => (typeof value === 'string' ? value : undefined), +}; + +const numberOrStringProp: PropDefinition = { + toCSSValue: (value) => { + if (typeof value === 'number' || typeof value === 'string') { + return String(value); + } + + return undefined; + }, +}; + +const borderWidthProp: PropDefinition = { + toCSSValue: borderWidth, +}; + +const borderRadiusProp: PropDefinition = { + toCSSValue: borderRadius, +}; + +const colorProp: PropDefinition = { + toCSSValue: color, +}; + +const sizeProp: PropDefinition = { + toCSSValue: size, +}; + +const insetProp: PropDefinition = { + toCSSValue: inset, +}; + +const marginProp: PropDefinition = { + toCSSValue: margin, +}; + +const paddingProp: PropDefinition = { + toCSSValue: padding, +}; + +const fontFamilyProp: PropDefinition = { + toCSSValue: fontFamily, +}; + +const fontSizeProp: PropDefinition = { + toCSSValue: (value) => fontScale(value)?.fontSize || size(value), +}; + +const fontWeightProp: PropDefinition = { + toCSSValue: (value) => + value ? String(fontScale(value)?.fontWeight || value) : undefined, +}; + +const lineHeightProp: PropDefinition = { + toCSSValue: (value) => fontScale(value)?.lineHeight || size(value), +}; + +const letterSpacingProp: PropDefinition = { + toCSSValue: (value) => + value ? String(fontScale(value)?.letterSpacing || value) : undefined, +}; + +const aliasOf = (propName: keyof StylingProps): PropDefinition => ({ + aliasOf: propName, +}); + +export const propDefs: Record = { + border: stringProp, + borderBlock: stringProp, + borderBlockStart: stringProp, + borderBlockEnd: stringProp, + borderInline: stringProp, + borderInlineStart: stringProp, + borderInlineEnd: stringProp, + borderWidth: borderWidthProp, + borderBlockWidth: borderWidthProp, + borderBlockStartWidth: borderWidthProp, + borderBlockEndWidth: borderWidthProp, + borderInlineWidth: borderWidthProp, + borderInlineStartWidth: borderWidthProp, + borderInlineEndWidth: borderWidthProp, + borderStyle: stringProp, + borderBlockStyle: stringProp, + borderBlockStartStyle: stringProp, + borderBlockEndStyle: stringProp, + borderInlineStyle: stringProp, + borderInlineStartStyle: stringProp, + borderInlineEndStyle: stringProp, + borderColor: colorProp, + borderBlockColor: colorProp, + borderBlockStartColor: colorProp, + borderBlockEndColor: colorProp, + borderInlineColor: colorProp, + borderInlineStartColor: colorProp, + borderInlineEndColor: colorProp, + borderRadius: borderRadiusProp, + borderStartStartRadius: borderRadiusProp, + borderStartEndRadius: borderRadiusProp, + borderEndStartRadius: borderRadiusProp, + borderEndEndRadius: borderRadiusProp, + + color: colorProp, + backgroundColor: colorProp, + bg: aliasOf('backgroundColor'), + opacity: numberOrStringProp, + + alignItems: stringProp, + alignContent: stringProp, + justifyItems: stringProp, + justifyContent: stringProp, + flexWrap: stringProp, + flexDirection: stringProp, + flexGrow: numberOrStringProp, + flexShrink: numberOrStringProp, + flexBasis: stringProp, + justifySelf: stringProp, + alignSelf: stringProp, + order: numberOrStringProp, + + w: aliasOf('width'), + width: sizeProp, + minWidth: sizeProp, + maxWidth: sizeProp, + h: aliasOf('height'), + height: sizeProp, + minHeight: sizeProp, + maxHeight: sizeProp, + display: stringProp, + verticalAlign: stringProp, + overflow: stringProp, + overflowX: stringProp, + overflowY: stringProp, + + position: stringProp, + zIndex: numberOrStringProp, + inset: insetProp, + insetBlock: insetProp, + insetBlockStart: insetProp, + insetBlockEnd: insetProp, + insetInline: insetProp, + insetInlineStart: insetProp, + insetInlineEnd: insetProp, + + m: aliasOf('margin'), + margin: marginProp, + mb: aliasOf('marginBlock'), + marginBlock: marginProp, + mbs: aliasOf('marginBlockStart'), + marginBlockStart: marginProp, + mbe: aliasOf('marginBlockEnd'), + marginBlockEnd: marginProp, + mi: aliasOf('marginInline'), + marginInline: marginProp, + mis: aliasOf('marginInlineStart'), + marginInlineStart: marginProp, + mie: aliasOf('marginInlineEnd'), + marginInlineEnd: marginProp, + p: aliasOf('padding'), + padding: paddingProp, + pb: aliasOf('paddingBlock'), + paddingBlock: paddingProp, + pbs: aliasOf('paddingBlockStart'), + paddingBlockStart: paddingProp, + pbe: aliasOf('paddingBlockEnd'), + paddingBlockEnd: paddingProp, + pi: aliasOf('paddingInline'), + paddingInline: paddingProp, + pis: aliasOf('paddingInlineStart'), + paddingInlineStart: paddingProp, + pie: aliasOf('paddingInlineEnd'), + paddingInlineEnd: paddingProp, + + fontFamily: fontFamilyProp, + fontSize: fontSizeProp, + fontStyle: stringProp, + fontWeight: fontWeightProp, + letterSpacing: letterSpacingProp, + lineHeight: lineHeightProp, + textAlign: stringProp, + textTransform: stringProp, + textDecorationLine: stringProp, + + elevation: { + toStyle: (value) => { + if (value === '0') { + return css` + box-shadow: none; + `; + } + + if (value === '1') { + return css` + box-shadow: 0px 0px 12px 0px ${color('neutral-800-10')}; + `; + } + + if (value === '2') { + return css` + box-shadow: 0px 0px 2px 0px ${color('neutral-800-8')}, + 0px 0px 12px 0px ${color('neutral-800-12')}; + `; + } + }, + }, + invisible: { + toStyle: (value) => + value + ? css` + visibility: hidden; + opacity: 0; + ` + : undefined, + }, + withTruncatedText: { + toStyle: (value) => + value + ? css` + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + ` + : undefined, + }, + size: { + toStyle: (value) => + size(value) + ? css` + width: ${size(value)} !important; + height: ${size(value)} !important; + ` + : undefined, + }, + minSize: { + toStyle: (value) => + size(value) + ? css` + min-width: ${size(value)} !important; + min-height: ${size(value)} !important; + ` + : undefined, + }, + maxSize: { + toStyle: (value) => + size(value) + ? css` + max-width: ${size(value)} !important; + max-height: ${size(value)} !important; + ` + : undefined, + }, + fontScale: { + toStyle: (value) => css` + font-size: ${fontScale(value)?.fontSize} !important; + font-weight: ${fontScale(value)?.fontWeight} !important; + letter-spacing: ${fontScale(value)?.letterSpacing} !important; + line-height: ${fontScale(value)?.lineHeight} !important; + `, + }, +}; + +const compiledPropDefs = new Map( + (Object.entries(propDefs) as [keyof StylingProps, PropDefinition][]).map( + ([propName, propDef]): [ + propName: string, + inject: ( + value: unknown, + stylingProps: Map + ) => void + ] => { + if ('aliasOf' in propDef) { + const { aliasOf: effectivePropName } = propDef; + + return [ + propName, + (value, stylingProps) => { + if (stylingProps.has(effectivePropName)) { + return; + } + + const inject = compiledPropDefs.get(effectivePropName); + + inject?.(value, stylingProps); + }, + ]; + } + + if ('toCSSValue' in propDef) { + const cssProperty = fromCamelToKebab(propName); + const { toCSSValue } = propDef; + return [ + propName, + (value, stylingProps) => { + const cssValue = toCSSValue(value); + + if (cssValue === undefined) { + return; + } + + stylingProps.set( + propName, + css` + ${cssProperty}: ${cssValue} !important; + ` + ); + }, + ]; + } + + const { toStyle } = propDef; + + return [ + propName, + (value, stylingProps) => { + const style = toStyle(value); + + if (style === undefined) { + return; + } + + stylingProps.set(propName, style); + }, + ]; + } + ) +); + +export const extractStylingProps = >( + props: TProps & Partial +): [props: TProps, styles: cssFn | undefined] => { + const stylingProps = new Map(); + const newProps: Record = {}; + + for (const [propName, value] of Object.entries(props)) { + const inject = compiledPropDefs.get(propName); + + if (!inject) { + newProps[propName] = value; + continue; + } + + if (value === undefined) { + continue; + } + + inject(value, stylingProps); + } + + const styles = stylingProps.size + ? css` + ${Array.from(stylingProps.values())} + ` + : undefined; + + return [newProps as TProps, styles]; +}; diff --git a/packages/fuselage/src/components/Box/useStylingProps.ts b/packages/fuselage/src/components/Box/useStylingProps.ts new file mode 100644 index 0000000000..e2d7d397e1 --- /dev/null +++ b/packages/fuselage/src/components/Box/useStylingProps.ts @@ -0,0 +1,20 @@ +import { appendClassName } from '../../helpers/appendClassName'; +import { useStyle } from '../../hooks/useStyle'; +import type { StylingProps } from './stylingProps'; +import { extractStylingProps } from './stylingProps'; + +export const useStylingProps = ( + originalProps: TProps & Partial +): TProps => { + const [props, styles] = extractStylingProps(originalProps); + + const newClassName = useStyle(styles, undefined); + + if (newClassName) { + props.className = props.className + ? appendClassName(props.className, newClassName) + : newClassName; + } + + return props; +}; diff --git a/packages/fuselage/src/components/Box/withBoxStyling.js b/packages/fuselage/src/components/Box/withBoxStyling.js deleted file mode 100644 index b10d2d23c9..0000000000 --- a/packages/fuselage/src/components/Box/withBoxStyling.js +++ /dev/null @@ -1,26 +0,0 @@ -import { createElement } from 'react'; - -import { useStyleSheet } from '../../hooks/useStyleSheet'; -import { useStylingProps } from './stylingProps'; - -export const withBoxStyling = (component) => { - const render = (props) => { - if (typeof component === 'function') { - return component(props); - } - - return createElement(component, props); - }; - - const WithBoxStyling = (props) => { - useStyleSheet(); - props = useStylingProps(props); - return render(props); - }; - - WithBoxStyling.displayName = `WithBoxStyling(${ - component.displayName || component.name || 'Component' - })`; - - return WithBoxStyling; -}; diff --git a/packages/fuselage/src/components/Box/withBoxStyling.ts b/packages/fuselage/src/components/Box/withBoxStyling.ts new file mode 100644 index 0000000000..77314d2b6e --- /dev/null +++ b/packages/fuselage/src/components/Box/withBoxStyling.ts @@ -0,0 +1,22 @@ +import type { ComponentType } from 'react'; +import { createElement } from 'react'; + +import { useStyleSheet } from '../../hooks/useStyleSheet'; +import type { StylingProps } from './stylingProps'; +import { useStylingProps } from './useStylingProps'; + +export const withBoxStyling = ( + component: ComponentType +): ComponentType => { + const WithBoxStyling = (props: TProps & Partial) => { + useStyleSheet(); + const propsWithoutStylingProps = useStylingProps(props); + return createElement(component, propsWithoutStylingProps); + }; + + WithBoxStyling.displayName = `WithBoxStyling(${ + component.displayName || component.name || 'Component' + })`; + + return WithBoxStyling; +}; diff --git a/packages/fuselage/src/components/Button/Button.tsx b/packages/fuselage/src/components/Button/Button.tsx index 07a6ec1714..ad183a19de 100644 --- a/packages/fuselage/src/components/Button/Button.tsx +++ b/packages/fuselage/src/components/Button/Button.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef, useMemo } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; export type ButtonProps = ComponentProps & { info?: boolean; diff --git a/packages/fuselage/src/components/ButtonGroup/ButtonGroup.tsx b/packages/fuselage/src/components/ButtonGroup/ButtonGroup.tsx index f53d612423..723ff11095 100644 --- a/packages/fuselage/src/components/ButtonGroup/ButtonGroup.tsx +++ b/packages/fuselage/src/components/ButtonGroup/ButtonGroup.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { appendClassName } from '../../helpers/appendClassName'; import { patchChildren } from '../../helpers/patchChildren'; -import { Box } from '../Box'; +import Box from '../Box'; type ButtonGroupProps = Omit, 'wrap'> & { align?: 'start' | 'center' | 'end'; diff --git a/packages/fuselage/src/components/Callout/Callout.tsx b/packages/fuselage/src/components/Callout/Callout.tsx index 927b57c4b0..dcdfb470dc 100644 --- a/packages/fuselage/src/components/Callout/Callout.tsx +++ b/packages/fuselage/src/components/Callout/Callout.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactNode } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Icon } from '../Icon'; type CalloutProps = Omit, 'type' | 'name'> & { diff --git a/packages/fuselage/src/components/CheckBox/CheckBox.tsx b/packages/fuselage/src/components/CheckBox/CheckBox.tsx index 12d681de39..acaed86e4a 100644 --- a/packages/fuselage/src/components/CheckBox/CheckBox.tsx +++ b/packages/fuselage/src/components/CheckBox/CheckBox.tsx @@ -2,7 +2,7 @@ import { useMergedRefs } from '@rocket.chat/fuselage-hooks'; import type { ComponentProps, Ref, FormEvent } from 'react'; import React, { forwardRef, useLayoutEffect, useRef, useCallback } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Label } from '../Label'; type CheckBoxProps = ComponentProps & { diff --git a/packages/fuselage/src/components/Chevron/Chevron.tsx b/packages/fuselage/src/components/Chevron/Chevron.tsx index 29c2619168..a709707c72 100644 --- a/packages/fuselage/src/components/Chevron/Chevron.tsx +++ b/packages/fuselage/src/components/Chevron/Chevron.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactElement } from 'react'; import React, { useMemo } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Icon } from '../Icon'; type ChevronProps = Omit, 'size'> & { diff --git a/packages/fuselage/src/components/Chip/Chip.tsx b/packages/fuselage/src/components/Chip/Chip.tsx index 08b6473e50..91dba7a41a 100644 --- a/packages/fuselage/src/components/Chip/Chip.tsx +++ b/packages/fuselage/src/components/Chip/Chip.tsx @@ -7,7 +7,7 @@ import { Icon } from '../Icon'; import Margins from '../Margins'; type ChipProps = Omit, 'type'> & { - thumbUrl: string; + thumbUrl?: string; renderThumb?: (props: { url: string }) => React.ReactNode; renderDismissSymbol?: () => React.ReactNode; }; diff --git a/packages/fuselage/src/components/CodeSnippet/CodeSnippet.tsx b/packages/fuselage/src/components/CodeSnippet/CodeSnippet.tsx index 5b78535168..5873a2ca09 100644 --- a/packages/fuselage/src/components/CodeSnippet/CodeSnippet.tsx +++ b/packages/fuselage/src/components/CodeSnippet/CodeSnippet.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactElement } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Button } from '../Button'; import { Skeleton } from '../Skeleton'; diff --git a/packages/fuselage/src/components/Divider/Divider.tsx b/packages/fuselage/src/components/Divider/Divider.tsx index e7069e03da..216f3bdffb 100644 --- a/packages/fuselage/src/components/Divider/Divider.tsx +++ b/packages/fuselage/src/components/Divider/Divider.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type DividerProps = ComponentProps; diff --git a/packages/fuselage/src/components/Field/Field.tsx b/packages/fuselage/src/components/Field/Field.tsx index aeec47ec1b..da8b416797 100644 --- a/packages/fuselage/src/components/Field/Field.tsx +++ b/packages/fuselage/src/components/Field/Field.tsx @@ -1,7 +1,7 @@ import type { ComponentPropsWithoutRef } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type FieldProps = ComponentPropsWithoutRef; diff --git a/packages/fuselage/src/components/Field/FieldDescription.tsx b/packages/fuselage/src/components/Field/FieldDescription.tsx index ab40c81ed2..d92a652f38 100644 --- a/packages/fuselage/src/components/Field/FieldDescription.tsx +++ b/packages/fuselage/src/components/Field/FieldDescription.tsx @@ -1,7 +1,7 @@ import type { ComponentPropsWithoutRef } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type FieldDescriptionProps = ComponentPropsWithoutRef; diff --git a/packages/fuselage/src/components/Field/FieldError.tsx b/packages/fuselage/src/components/Field/FieldError.tsx index a129533437..f17b4e2542 100644 --- a/packages/fuselage/src/components/Field/FieldError.tsx +++ b/packages/fuselage/src/components/Field/FieldError.tsx @@ -1,7 +1,7 @@ import type { ComponentPropsWithoutRef } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type FieldErrorProps = ComponentPropsWithoutRef; diff --git a/packages/fuselage/src/components/Field/FieldHint.tsx b/packages/fuselage/src/components/Field/FieldHint.tsx index 63bc901528..ff78ebc355 100644 --- a/packages/fuselage/src/components/Field/FieldHint.tsx +++ b/packages/fuselage/src/components/Field/FieldHint.tsx @@ -1,7 +1,7 @@ import type { ComponentPropsWithoutRef } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type FieldHintProps = ComponentPropsWithoutRef; diff --git a/packages/fuselage/src/components/Field/FieldLabel.tsx b/packages/fuselage/src/components/Field/FieldLabel.tsx index 2ce55f26b9..88e7ec46b2 100644 --- a/packages/fuselage/src/components/Field/FieldLabel.tsx +++ b/packages/fuselage/src/components/Field/FieldLabel.tsx @@ -1,7 +1,7 @@ import type { ComponentPropsWithoutRef } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Label } from '../Label'; type FieldLabelProps = ComponentPropsWithoutRef; diff --git a/packages/fuselage/src/components/Field/FieldLink.tsx b/packages/fuselage/src/components/Field/FieldLink.tsx index 7b6468b98d..cc7f985cae 100644 --- a/packages/fuselage/src/components/Field/FieldLink.tsx +++ b/packages/fuselage/src/components/Field/FieldLink.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactElement } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type FieldLinkProps = ComponentProps; diff --git a/packages/fuselage/src/components/Field/FieldRow.tsx b/packages/fuselage/src/components/Field/FieldRow.tsx index 14c66b088d..972a4741f0 100644 --- a/packages/fuselage/src/components/Field/FieldRow.tsx +++ b/packages/fuselage/src/components/Field/FieldRow.tsx @@ -1,7 +1,7 @@ import type { ComponentPropsWithoutRef } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type FieldRowProps = ComponentPropsWithoutRef; diff --git a/packages/fuselage/src/components/FieldGroup/FieldGroup.tsx b/packages/fuselage/src/components/FieldGroup/FieldGroup.tsx index 24143bbde8..e35fe33e6a 100644 --- a/packages/fuselage/src/components/FieldGroup/FieldGroup.tsx +++ b/packages/fuselage/src/components/FieldGroup/FieldGroup.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { appendClassName } from '../../helpers/appendClassName'; import { patchChildren } from '../../helpers/patchChildren'; -import { Box } from '../Box'; +import Box from '../Box'; type FieldGroupProps = ComponentProps; diff --git a/packages/fuselage/src/components/Grid/Grid.tsx b/packages/fuselage/src/components/Grid/Grid.tsx index 194e478264..05f8b0430a 100644 --- a/packages/fuselage/src/components/Grid/Grid.tsx +++ b/packages/fuselage/src/components/Grid/Grid.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { GridItem } from './GridItem'; type GridProps = ComponentProps & { diff --git a/packages/fuselage/src/components/Grid/GridItem.tsx b/packages/fuselage/src/components/Grid/GridItem.tsx index 29cce18876..e9272e059e 100644 --- a/packages/fuselage/src/components/Grid/GridItem.tsx +++ b/packages/fuselage/src/components/Grid/GridItem.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type GridItemProps = ComponentProps & { xs?: 1 | 2 | 3 | 4; diff --git a/packages/fuselage/src/components/Icon/Icon.tsx b/packages/fuselage/src/components/Icon/Icon.tsx index f5480beb8e..1cb0098678 100644 --- a/packages/fuselage/src/components/Icon/Icon.tsx +++ b/packages/fuselage/src/components/Icon/Icon.tsx @@ -3,7 +3,7 @@ import nameToCharacterMapping from '@rocket.chat/icons'; import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; export type IconProps = Omit, 'name' | 'size'> & { name: Keys; diff --git a/packages/fuselage/src/components/InputBox/Addon.tsx b/packages/fuselage/src/components/InputBox/Addon.tsx index 5ff10ce6aa..74e3f0fa25 100644 --- a/packages/fuselage/src/components/InputBox/Addon.tsx +++ b/packages/fuselage/src/components/InputBox/Addon.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type AddonProps = ComponentProps; diff --git a/packages/fuselage/src/components/InputBox/Input.tsx b/packages/fuselage/src/components/InputBox/Input.tsx index 2477e04071..d884c5f327 100644 --- a/packages/fuselage/src/components/InputBox/Input.tsx +++ b/packages/fuselage/src/components/InputBox/Input.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type InputProps = ComponentProps; diff --git a/packages/fuselage/src/components/InputBox/InputBox.tsx b/packages/fuselage/src/components/InputBox/InputBox.tsx index ff6568b578..7b5989a877 100644 --- a/packages/fuselage/src/components/InputBox/InputBox.tsx +++ b/packages/fuselage/src/components/InputBox/InputBox.tsx @@ -10,7 +10,7 @@ import React, { forwardRef, useCallback, useLayoutEffect, useRef } from 'react'; import type { InputBoxSkeleton } from '.'; import { Input, Wrapper } from '.'; -import type { Box } from '../Box'; +import type Box from '../Box'; import { Addon } from './Addon'; import type { Option } from './Option'; import type { Placeholder } from './Placeholder'; diff --git a/packages/fuselage/src/components/InputBox/InputBoxSkeleton.tsx b/packages/fuselage/src/components/InputBox/InputBoxSkeleton.tsx index 33c2e0b96f..f62fc6863d 100644 --- a/packages/fuselage/src/components/InputBox/InputBoxSkeleton.tsx +++ b/packages/fuselage/src/components/InputBox/InputBoxSkeleton.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Skeleton } from '../Skeleton'; type InputBoxSkeletonProps = ComponentProps; diff --git a/packages/fuselage/src/components/InputBox/Option.tsx b/packages/fuselage/src/components/InputBox/Option.tsx index b16547b54b..444006b217 100644 --- a/packages/fuselage/src/components/InputBox/Option.tsx +++ b/packages/fuselage/src/components/InputBox/Option.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type OptionProps = ComponentProps; diff --git a/packages/fuselage/src/components/InputBox/Placeholder.tsx b/packages/fuselage/src/components/InputBox/Placeholder.tsx index 20244fa617..dec7df56a4 100644 --- a/packages/fuselage/src/components/InputBox/Placeholder.tsx +++ b/packages/fuselage/src/components/InputBox/Placeholder.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type PlaceholderProps = ComponentProps; diff --git a/packages/fuselage/src/components/InputBox/Wrapper.tsx b/packages/fuselage/src/components/InputBox/Wrapper.tsx index c3473a5cac..6ba0e08848 100644 --- a/packages/fuselage/src/components/InputBox/Wrapper.tsx +++ b/packages/fuselage/src/components/InputBox/Wrapper.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Label } from '../Label'; export const Wrapper = (props: ComponentProps) => ( diff --git a/packages/fuselage/src/components/Label/Label.tsx b/packages/fuselage/src/components/Label/Label.tsx index bbe5b23294..e621db104f 100644 --- a/packages/fuselage/src/components/Label/Label.tsx +++ b/packages/fuselage/src/components/Label/Label.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactElement, ElementType } from 'react'; import React, { createContext, useContext } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; const LabelContext = createContext(false); diff --git a/packages/fuselage/src/components/Margins/Margins.tsx b/packages/fuselage/src/components/Margins/Margins.tsx index 1db8e7055d..59eb58425d 100644 --- a/packages/fuselage/src/components/Margins/Margins.tsx +++ b/packages/fuselage/src/components/Margins/Margins.tsx @@ -2,11 +2,11 @@ import { css } from '@rocket.chat/css-in-js'; import type { ComponentProps, PropsWithChildren } from 'react'; import React, { useCallback } from 'react'; -import type { Box } from '..'; import { appendClassName } from '../../helpers/appendClassName'; import { patchChildren } from '../../helpers/patchChildren'; import { useStyle } from '../../hooks/useStyle'; import { margin } from '../../styleTokens'; +import type Box from '../Box'; import { BoxTransforms, useComposedBoxTransform } from '../Box/BoxTransforms'; type MarginsProps = PropsWithChildren<{ diff --git a/packages/fuselage/src/components/Menu/Menu.tsx b/packages/fuselage/src/components/Menu/Menu.tsx index 7892a1b24e..8a6a556543 100644 --- a/packages/fuselage/src/components/Menu/Menu.tsx +++ b/packages/fuselage/src/components/Menu/Menu.tsx @@ -2,8 +2,8 @@ import type { Placements } from '@rocket.chat/fuselage-hooks'; import type { ComponentProps, ElementType, ReactNode } from 'react'; import React, { useRef, useCallback } from 'react'; -import type { Box } from '..'; import { ActionButton, PositionAnimated, Options, useCursor } from '..'; +import type Box from '../Box'; import type { OptionType } from '../Options'; type MenuProps = Omit, 'icon'> & { diff --git a/packages/fuselage/src/components/Message/MessageBlock.tsx b/packages/fuselage/src/components/Message/MessageBlock.tsx index 55b9eb1338..1b779d0f53 100644 --- a/packages/fuselage/src/components/Message/MessageBlock.tsx +++ b/packages/fuselage/src/components/Message/MessageBlock.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type MessageBlockProps = ComponentProps; diff --git a/packages/fuselage/src/components/Message/MessageDivider/MessageDivider.stories.tsx b/packages/fuselage/src/components/Message/MessageDivider/MessageDivider.stories.tsx index d70721bbe4..e15b0751b2 100644 --- a/packages/fuselage/src/components/Message/MessageDivider/MessageDivider.stories.tsx +++ b/packages/fuselage/src/components/Message/MessageDivider/MessageDivider.stories.tsx @@ -2,7 +2,7 @@ import type { ComponentStory, ComponentMeta } from '@storybook/react'; import React from 'react'; import { MessageDivider } from '.'; -import { Box } from '../..'; +import Box from '../../Box'; export default { title: 'Message/MessageDivider', diff --git a/packages/fuselage/src/components/Modal/Modal.tsx b/packages/fuselage/src/components/Modal/Modal.tsx index 665576a0c1..7c1d348dd3 100644 --- a/packages/fuselage/src/components/Modal/Modal.tsx +++ b/packages/fuselage/src/components/Modal/Modal.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type ModalProps = ComponentProps; diff --git a/packages/fuselage/src/components/Modal/ModalBackdrop.tsx b/packages/fuselage/src/components/Modal/ModalBackdrop.tsx index 67104f82fd..95eb462de5 100644 --- a/packages/fuselage/src/components/Modal/ModalBackdrop.tsx +++ b/packages/fuselage/src/components/Modal/ModalBackdrop.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; export type ModalBackdropProps = ComponentProps; diff --git a/packages/fuselage/src/components/Modal/ModalClose.tsx b/packages/fuselage/src/components/Modal/ModalClose.tsx index a3050618f4..bf5ee982f2 100644 --- a/packages/fuselage/src/components/Modal/ModalClose.tsx +++ b/packages/fuselage/src/components/Modal/ModalClose.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import type { Box } from '..'; +import type Box from '../Box'; import { ActionButton } from '../Button'; export type ModalCloseProps = ComponentProps; diff --git a/packages/fuselage/src/components/Modal/ModalContent.tsx b/packages/fuselage/src/components/Modal/ModalContent.tsx index 04180acb84..adde197233 100644 --- a/packages/fuselage/src/components/Modal/ModalContent.tsx +++ b/packages/fuselage/src/components/Modal/ModalContent.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import Scrollable from '../Scrollable'; export type ModalContentProps = ComponentProps & { diff --git a/packages/fuselage/src/components/Modal/ModalFooter.tsx b/packages/fuselage/src/components/Modal/ModalFooter.tsx index c2a90daee2..ad70bec234 100644 --- a/packages/fuselage/src/components/Modal/ModalFooter.tsx +++ b/packages/fuselage/src/components/Modal/ModalFooter.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; export type ModalFooterProps = ComponentProps; diff --git a/packages/fuselage/src/components/Modal/ModalHeader.tsx b/packages/fuselage/src/components/Modal/ModalHeader.tsx index ff4d64630c..9fa21d47c3 100644 --- a/packages/fuselage/src/components/Modal/ModalHeader.tsx +++ b/packages/fuselage/src/components/Modal/ModalHeader.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import Margins from '../Margins'; export type ModalHeaderProps = ComponentProps; diff --git a/packages/fuselage/src/components/Modal/ModalThumb.tsx b/packages/fuselage/src/components/Modal/ModalThumb.tsx index abb3f5c1ad..1f24cfdd53 100644 --- a/packages/fuselage/src/components/Modal/ModalThumb.tsx +++ b/packages/fuselage/src/components/Modal/ModalThumb.tsx @@ -2,7 +2,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; import { Avatar } from '../Avatar'; -import { Box } from '../Box'; +import Box from '../Box'; export type ModalThumbProps = ComponentProps; diff --git a/packages/fuselage/src/components/Modal/ModalTitle.tsx b/packages/fuselage/src/components/Modal/ModalTitle.tsx index cdc910e41b..6e948d15e7 100644 --- a/packages/fuselage/src/components/Modal/ModalTitle.tsx +++ b/packages/fuselage/src/components/Modal/ModalTitle.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; export type ModalTitleProps = ComponentProps; diff --git a/packages/fuselage/src/components/MultiSelect/MultiSelect.tsx b/packages/fuselage/src/components/MultiSelect/MultiSelect.tsx index c20d2c1f7f..021a97ac21 100644 --- a/packages/fuselage/src/components/MultiSelect/MultiSelect.tsx +++ b/packages/fuselage/src/components/MultiSelect/MultiSelect.tsx @@ -15,7 +15,7 @@ import React, { useState, useRef, useEffect, forwardRef } from 'react'; import type { SelectOption } from '..'; import { isForwardRefType } from '../../helpers/isForwardRefType'; import AnimatedVisibility from '../AnimatedVisibility'; -import { Box } from '../Box'; +import Box from '../Box'; import Flex from '../Flex'; import { Icon } from '../Icon'; import Margins from '../Margins'; diff --git a/packages/fuselage/src/components/MultiSelect/SelectedOptions.tsx b/packages/fuselage/src/components/MultiSelect/SelectedOptions.tsx index b9a9623e83..ec43cdc2a7 100644 --- a/packages/fuselage/src/components/MultiSelect/SelectedOptions.tsx +++ b/packages/fuselage/src/components/MultiSelect/SelectedOptions.tsx @@ -1,16 +1,18 @@ -import type { NamedExoticComponent, SyntheticEvent } from 'react'; +import type { ReactNode, SyntheticEvent } from 'react'; import React, { memo } from 'react'; import Chip from '../Chip'; type SelectedOptionsProps = { + children: ReactNode; tabIndex: number; role: string; key: string; onMouseDown: (e: SyntheticEvent) => void; - children: string | void; }; -export const SelectedOptions: NamedExoticComponent = memo( - (props) => -); +export const SelectedOptions = memo(function SelectedOptions( + props: SelectedOptionsProps +) { + return ; +}); diff --git a/packages/fuselage/src/components/Options/Option/Option.tsx b/packages/fuselage/src/components/Options/Option/Option.tsx index 43ff713d4a..f1fb606350 100644 --- a/packages/fuselage/src/components/Options/Option/Option.tsx +++ b/packages/fuselage/src/components/Options/Option/Option.tsx @@ -2,7 +2,7 @@ import type { Ref, ComponentProps, ReactNode, MouseEvent } from 'react'; import React, { memo } from 'react'; import type { Icon } from '../..'; -import type { Box } from '../../Box'; +import type Box from '../../Box'; import OptionAvatar from './OptionAvatar'; import OptionContent from './OptionContent'; import OptionIcon from './OptionIcon'; diff --git a/packages/fuselage/src/components/Options/Options.tsx b/packages/fuselage/src/components/Options/Options.tsx index 9f4f362688..170dc83bff 100644 --- a/packages/fuselage/src/components/Options/Options.tsx +++ b/packages/fuselage/src/components/Options/Options.tsx @@ -13,7 +13,7 @@ import React, { useRef, } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import Scrollable from '../Scrollable'; import Tile from '../Tile'; import Option, { OptionHeader, OptionDivider } from './Option'; diff --git a/packages/fuselage/src/components/OptionsPaginated/OptionsPaginated.tsx b/packages/fuselage/src/components/OptionsPaginated/OptionsPaginated.tsx index 35834a8fbc..d5ea2d4960 100644 --- a/packages/fuselage/src/components/OptionsPaginated/OptionsPaginated.tsx +++ b/packages/fuselage/src/components/OptionsPaginated/OptionsPaginated.tsx @@ -7,7 +7,7 @@ import React, { forwardRef, memo } from 'react'; import { Virtuoso } from 'react-virtuoso'; import AnimatedVisibility from '../AnimatedVisibility'; -import { Box } from '../Box'; +import Box from '../Box'; import { CheckBox } from '../CheckBox'; import Option from '../Options/Option'; import Tile from '../Tile'; diff --git a/packages/fuselage/src/components/PaginatedSelect/PaginatedMultiSelect.tsx b/packages/fuselage/src/components/PaginatedSelect/PaginatedMultiSelect.tsx index 45a48b1ebe..26d6c9e59f 100644 --- a/packages/fuselage/src/components/PaginatedSelect/PaginatedMultiSelect.tsx +++ b/packages/fuselage/src/components/PaginatedSelect/PaginatedMultiSelect.tsx @@ -7,7 +7,7 @@ import type { SyntheticEvent, ComponentProps, Ref } from 'react'; import React, { useState, useRef, useCallback, forwardRef, memo } from 'react'; import AnimatedVisibility from '../AnimatedVisibility'; -import { Box } from '../Box'; +import Box from '../Box'; import Chip from '../Chip'; import Flex from '../Flex'; import { Icon } from '../Icon'; diff --git a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx index 9038f1f56e..becd489b8d 100644 --- a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx +++ b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelect.tsx @@ -8,7 +8,7 @@ import React, { useState, useRef, useMemo, useEffect } from 'react'; import type { SelectProps } from '..'; import AnimatedVisibility from '../AnimatedVisibility'; -import { Box } from '../Box'; +import Box from '../Box'; import { Icon } from '../Icon'; import { useVisible } from '../Options/useVisible'; import { OptionsPaginated } from '../OptionsPaginated'; @@ -25,7 +25,7 @@ export type PaginatedSelectProps = Omit & { anchor?: ElementType; options: PaginatedOptionType[]; withTitle?: boolean; - endReached: (index: number) => void; + endReached?: (index: number) => void; setFilter?: (value: string | undefined | number) => void; }; diff --git a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectAddon.tsx b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectAddon.tsx index 99c7548c9b..0331283c2e 100644 --- a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectAddon.tsx +++ b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectAddon.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type PaginatedSelectAddonProps = ComponentProps; diff --git a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectFocus.tsx b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectFocus.tsx index 05d496265c..7e12691b6c 100644 --- a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectFocus.tsx +++ b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectFocus.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type PaginatedSelectFocusProps = ComponentProps; diff --git a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectWrapper.tsx b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectWrapper.tsx index 0322f0fe37..779acb2fa9 100644 --- a/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectWrapper.tsx +++ b/packages/fuselage/src/components/PaginatedSelect/PaginatedSelectWrapper.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type PaginatedSelectWrapperProps = ComponentProps; diff --git a/packages/fuselage/src/components/Pagination/Pagination.tsx b/packages/fuselage/src/components/Pagination/Pagination.tsx index 911df552d7..807a1b4dcb 100644 --- a/packages/fuselage/src/components/Pagination/Pagination.tsx +++ b/packages/fuselage/src/components/Pagination/Pagination.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Dispatch, SetStateAction } from 'react'; import React, { useMemo } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Chevron } from '../Chevron'; type ItemsPerPage = 25 | 50 | 100; diff --git a/packages/fuselage/src/components/Position/Position.tsx b/packages/fuselage/src/components/Position/Position.tsx index c99295fe8c..676eba78e4 100644 --- a/packages/fuselage/src/components/Position/Position.tsx +++ b/packages/fuselage/src/components/Position/Position.tsx @@ -9,7 +9,7 @@ import type { import { useRef, useMemo, useEffect, cloneElement } from 'react'; import { createPortal } from 'react-dom'; -import type { Box } from '../Box'; +import type Box from '../Box'; type PositionProps = { anchor: RefObject; diff --git a/packages/fuselage/src/components/ProgressBar/ProgressBar.tsx b/packages/fuselage/src/components/ProgressBar/ProgressBar.tsx index d047f3db8e..3dc52b269c 100644 --- a/packages/fuselage/src/components/ProgressBar/ProgressBar.tsx +++ b/packages/fuselage/src/components/ProgressBar/ProgressBar.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; const getWidth = (percentage: number): string => `${Math.min(Math.max(0, percentage), 100).toFixed(1)}%`; diff --git a/packages/fuselage/src/components/RadioButton/RadioButton.tsx b/packages/fuselage/src/components/RadioButton/RadioButton.tsx index adf152e22b..8a8e81a91e 100644 --- a/packages/fuselage/src/components/RadioButton/RadioButton.tsx +++ b/packages/fuselage/src/components/RadioButton/RadioButton.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Label } from '../Label'; type RadioButtonProps = ComponentProps & { diff --git a/packages/fuselage/src/components/Select/Select.tsx b/packages/fuselage/src/components/Select/Select.tsx index 1efaa7cd60..fd38b8908a 100644 --- a/packages/fuselage/src/components/Select/Select.tsx +++ b/packages/fuselage/src/components/Select/Select.tsx @@ -14,7 +14,7 @@ import React, { useState, useRef, useEffect, forwardRef, useMemo } from 'react'; import { isForwardRefType } from '../../helpers/isForwardRefType'; import AnimatedVisibility from '../AnimatedVisibility'; -import { Box } from '../Box'; +import Box from '../Box'; import { Icon } from '../Icon'; import Margins from '../Margins'; import type { OptionType } from '../Options'; diff --git a/packages/fuselage/src/components/Select/SelectAddon.tsx b/packages/fuselage/src/components/Select/SelectAddon.tsx index 6767ec3478..65c36a7980 100644 --- a/packages/fuselage/src/components/Select/SelectAddon.tsx +++ b/packages/fuselage/src/components/Select/SelectAddon.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; export type SelectOptions = readonly [value: string, label: string][]; diff --git a/packages/fuselage/src/components/Select/SelectFocus.tsx b/packages/fuselage/src/components/Select/SelectFocus.tsx index a81a0d20f9..09dd70ab96 100644 --- a/packages/fuselage/src/components/Select/SelectFocus.tsx +++ b/packages/fuselage/src/components/Select/SelectFocus.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; export type SelectOptions = readonly [value: string, label: string][]; diff --git a/packages/fuselage/src/components/Sidebar/Item.tsx b/packages/fuselage/src/components/Sidebar/Item.tsx index 0fe2ce532a..40f3071be4 100644 --- a/packages/fuselage/src/components/Sidebar/Item.tsx +++ b/packages/fuselage/src/components/Sidebar/Item.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactNode } from 'react'; import React from 'react'; -import type { Box } from '..'; +import type Box from '../Box'; import { Icon as FuselageIcon } from '../Icon'; import { SidebarAction, SidebarActions } from './SidebarActions'; diff --git a/packages/fuselage/src/components/Sidebar/TopBar.tsx b/packages/fuselage/src/components/Sidebar/TopBar.tsx index cdf660454a..f822265350 100644 --- a/packages/fuselage/src/components/Sidebar/TopBar.tsx +++ b/packages/fuselage/src/components/Sidebar/TopBar.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, ReactNode } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Divider } from '../Divider'; import { SidebarAction, SidebarActions } from './SidebarActions'; diff --git a/packages/fuselage/src/components/Sidebar/index.tsx b/packages/fuselage/src/components/Sidebar/index.tsx index 8fa358ac7e..57ce1f5740 100644 --- a/packages/fuselage/src/components/Sidebar/index.tsx +++ b/packages/fuselage/src/components/Sidebar/index.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '..'; +import Box from '../Box'; import SidebarItem from './Item'; import SidebarSection from './Section'; import SidebarTopBar from './TopBar'; diff --git a/packages/fuselage/src/components/Skeleton/Skeleton.tsx b/packages/fuselage/src/components/Skeleton/Skeleton.tsx index 8fb765ff7c..7d30ebc869 100644 --- a/packages/fuselage/src/components/Skeleton/Skeleton.tsx +++ b/packages/fuselage/src/components/Skeleton/Skeleton.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type SkeletonProps = ComponentProps & { variant?: 'text' | 'rect'; diff --git a/packages/fuselage/src/components/Table/Table.tsx b/packages/fuselage/src/components/Table/Table.tsx index 88c85ef886..39a9d99c1b 100644 --- a/packages/fuselage/src/components/Table/Table.tsx +++ b/packages/fuselage/src/components/Table/Table.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, CSSProperties } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { TableSelection } from './TableSelection'; import { TableSelectionButton } from './TableSelectionButton'; diff --git a/packages/fuselage/src/components/Table/TableBody.tsx b/packages/fuselage/src/components/Table/TableBody.tsx index 04fd2bd809..b36df6085d 100644 --- a/packages/fuselage/src/components/Table/TableBody.tsx +++ b/packages/fuselage/src/components/Table/TableBody.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import type { TableProps } from './Table'; type TableBodyProps = TableProps; diff --git a/packages/fuselage/src/components/Table/TableCell.tsx b/packages/fuselage/src/components/Table/TableCell.tsx index 845dcd3254..4be5296372 100644 --- a/packages/fuselage/src/components/Table/TableCell.tsx +++ b/packages/fuselage/src/components/Table/TableCell.tsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import type { TableProps } from './Table'; import { TableHeadContext } from './TableHead'; diff --git a/packages/fuselage/src/components/Table/TableFoot.tsx b/packages/fuselage/src/components/Table/TableFoot.tsx index 6f046b5b93..e2966f6736 100644 --- a/packages/fuselage/src/components/Table/TableFoot.tsx +++ b/packages/fuselage/src/components/Table/TableFoot.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import type { TableProps } from './Table'; type TableFootProps = TableProps; diff --git a/packages/fuselage/src/components/Table/TableHead.tsx b/packages/fuselage/src/components/Table/TableHead.tsx index 1fd296b2e5..32ce3a73d3 100644 --- a/packages/fuselage/src/components/Table/TableHead.tsx +++ b/packages/fuselage/src/components/Table/TableHead.tsx @@ -1,6 +1,6 @@ import React, { createContext } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import type { TableProps } from './Table'; export const TableHeadContext = createContext(false); diff --git a/packages/fuselage/src/components/Table/TableRow.tsx b/packages/fuselage/src/components/Table/TableRow.tsx index 4902395d0b..662a6be354 100644 --- a/packages/fuselage/src/components/Table/TableRow.tsx +++ b/packages/fuselage/src/components/Table/TableRow.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type TableRowProps = Omit, 'action'> & { action?: boolean; diff --git a/packages/fuselage/src/components/Table/TableSelection.tsx b/packages/fuselage/src/components/Table/TableSelection.tsx index aba444f85c..99c4b00cb9 100644 --- a/packages/fuselage/src/components/Table/TableSelection.tsx +++ b/packages/fuselage/src/components/Table/TableSelection.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import Margins from '../Margins'; import { style } from './Table'; diff --git a/packages/fuselage/src/components/Table/TableSelectionButton.tsx b/packages/fuselage/src/components/Table/TableSelectionButton.tsx index fa98fd9ea6..15183e8138 100644 --- a/packages/fuselage/src/components/Table/TableSelectionButton.tsx +++ b/packages/fuselage/src/components/Table/TableSelectionButton.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import type { Box } from '../Box'; +import type Box from '../Box'; import { Button } from '../Button'; type TableSelectionButtonProps = ComponentProps; diff --git a/packages/fuselage/src/components/Tabs/Tabs.tsx b/packages/fuselage/src/components/Tabs/Tabs.tsx index 2a7be5d28d..e597122cfd 100644 --- a/packages/fuselage/src/components/Tabs/Tabs.tsx +++ b/packages/fuselage/src/components/Tabs/Tabs.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { TabsItem } from './TabsItem'; type TabsProps = ComponentProps; diff --git a/packages/fuselage/src/components/Tabs/TabsItem.tsx b/packages/fuselage/src/components/Tabs/TabsItem.tsx index ddcaf3f69c..fde98a9b82 100644 --- a/packages/fuselage/src/components/Tabs/TabsItem.tsx +++ b/packages/fuselage/src/components/Tabs/TabsItem.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type TabsItemProps = ComponentProps & { selected?: boolean; diff --git a/packages/fuselage/src/components/Tag/Tag.tsx b/packages/fuselage/src/components/Tag/Tag.tsx index ffa6c211ac..3c2ce55821 100644 --- a/packages/fuselage/src/components/Tag/Tag.tsx +++ b/packages/fuselage/src/components/Tag/Tag.tsx @@ -1,8 +1,8 @@ import type { ComponentProps } from 'react'; import React from 'react'; -import type { Box } from '..'; import { prependClassName } from '../../helpers/prependClassName'; +import type Box from '../Box'; type TagProps = ComponentProps & { small?: boolean; diff --git a/packages/fuselage/src/components/Throbber/Throbber.tsx b/packages/fuselage/src/components/Throbber/Throbber.tsx index 7aa9f9aab1..2c1d661275 100644 --- a/packages/fuselage/src/components/Throbber/Throbber.tsx +++ b/packages/fuselage/src/components/Throbber/Throbber.tsx @@ -2,7 +2,7 @@ import { css } from '@rocket.chat/css-in-js'; import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; type ThrobberProps = Omit, 'disabled'> & { circleCount?: number; diff --git a/packages/fuselage/src/components/Tile/Tile.tsx b/packages/fuselage/src/components/Tile/Tile.tsx index b717057608..4ed51bded3 100644 --- a/packages/fuselage/src/components/Tile/Tile.tsx +++ b/packages/fuselage/src/components/Tile/Tile.tsx @@ -2,7 +2,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; import { useStyleSheet } from '../../hooks/useStyleSheet'; -import { Box } from '../Box'; +import Box from '../Box'; import tileStyleSheet from './Tile.styles.scss'; type TileProps = ComponentProps & { diff --git a/packages/fuselage/src/components/ToggleSwitch/ToggleSwitch.tsx b/packages/fuselage/src/components/ToggleSwitch/ToggleSwitch.tsx index 7770188310..281c9c8e94 100644 --- a/packages/fuselage/src/components/ToggleSwitch/ToggleSwitch.tsx +++ b/packages/fuselage/src/components/ToggleSwitch/ToggleSwitch.tsx @@ -1,7 +1,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; -import { Box } from '../Box'; +import Box from '../Box'; import { Label } from '../Label'; type ToggleSwitchProps = ComponentProps & { diff --git a/packages/fuselage/src/components/Tooltip/Tooltip.tsx b/packages/fuselage/src/components/Tooltip/Tooltip.tsx index c7a0f0595e..4e6945f141 100644 --- a/packages/fuselage/src/components/Tooltip/Tooltip.tsx +++ b/packages/fuselage/src/components/Tooltip/Tooltip.tsx @@ -2,7 +2,7 @@ import type { ComponentProps, Ref } from 'react'; import React, { forwardRef } from 'react'; import { useStyleSheet } from '../../hooks/useStyleSheet'; -import { Box } from '../Box'; +import Box from '../Box'; import tooltipStyleSheet from './Tooltip.styles.scss'; const parsePlacement = (placement: string | null | undefined) => { diff --git a/packages/fuselage/src/components/index.ts b/packages/fuselage/src/components/index.ts index 7d22b8e48d..88a16e05ba 100644 --- a/packages/fuselage/src/components/index.ts +++ b/packages/fuselage/src/components/index.ts @@ -4,7 +4,7 @@ export * from './AutoComplete'; export * from './Avatar'; export * from './Badge'; export { default as Banner } from './Banner'; -export { Box } from './Box'; +export { default as Box } from './Box'; export { useArrayLikeClassNameProp } from '../hooks/useArrayLikeClassNameProp'; export { default as Button, ActionButton } from './Button'; export * from './ButtonGroup'; diff --git a/packages/fuselage/src/hooks/useArrayLikeClassNameProp.ts b/packages/fuselage/src/hooks/useArrayLikeClassNameProp.ts index a7d5dad712..5b31d040e4 100644 --- a/packages/fuselage/src/hooks/useArrayLikeClassNameProp.ts +++ b/packages/fuselage/src/hooks/useArrayLikeClassNameProp.ts @@ -2,17 +2,18 @@ import type { cssFn } from '@rocket.chat/css-in-js'; import { css } from '@rocket.chat/css-in-js'; import { appendClassName } from '../helpers/appendClassName'; +import type { Falsy } from '../types/Falsy'; import { useStyle } from './useStyle'; export const useArrayLikeClassNameProp = < T extends { - className?: string | cssFn | (string | cssFn)[]; + className?: string | cssFn | (string | cssFn | Falsy)[]; } >( props: T ): T & { className: string } => { const classNames = props.className - ? ([] as (string | cssFn)[]).concat(props.className) + ? ([] as (string | cssFn | Falsy)[]).concat(props.className) : []; const cssFns = classNames.filter( diff --git a/packages/fuselage/src/hooks/useBoxOnlyProps.ts b/packages/fuselage/src/hooks/useBoxOnlyProps.ts index 46fb72669b..0383026f8b 100644 --- a/packages/fuselage/src/hooks/useBoxOnlyProps.ts +++ b/packages/fuselage/src/hooks/useBoxOnlyProps.ts @@ -1,10 +1,16 @@ +import type { AllHTMLAttributes } from 'react'; + import { prependClassName } from '../helpers/prependClassName'; -export const useBoxOnlyProps = ( +export const useBoxOnlyProps = < + T extends { className: string; size?: AllHTMLAttributes['size'] } +>( props: T & { animated?: boolean; withRichContent?: boolean | 'inlineWithoutBreaks'; elevation?: '0' | '1' | '2'; + htmlSize?: AllHTMLAttributes['size']; + size?: AllHTMLAttributes['size']; } & Record<`rcx-${string}`, unknown> ): T => { Object.entries(props).forEach(([key, value]) => { @@ -46,6 +52,11 @@ export const useBoxOnlyProps = ( } } + if (props.htmlSize) { + props.size = props.htmlSize; + delete props.htmlSize; + } + delete props.withRichContent; props.className = prependClassName(props.className, 'rcx-box rcx-box--full'); diff --git a/packages/fuselage/src/hooks/useStyle.ts b/packages/fuselage/src/hooks/useStyle.ts index 86beee2cd4..cbf25000ed 100644 --- a/packages/fuselage/src/hooks/useStyle.ts +++ b/packages/fuselage/src/hooks/useStyle.ts @@ -7,7 +7,7 @@ import { } from '@rocket.chat/css-in-js'; import { useDebugValue, useLayoutEffect, useMemo } from 'react'; -export const useStyle = (cssFn: cssFn, arg: unknown) => { +export const useStyle = (cssFn: cssFn | undefined, arg: unknown) => { const content = useMemo(() => (cssFn ? cssFn(arg) : undefined), [arg, cssFn]); const className = useMemo(() => { diff --git a/packages/fuselage/src/types/Falsy.ts b/packages/fuselage/src/types/Falsy.ts new file mode 100644 index 0000000000..03ec62d6b3 --- /dev/null +++ b/packages/fuselage/src/types/Falsy.ts @@ -0,0 +1 @@ +export type Falsy = false | 0 | '' | null | undefined;