diff --git a/packages/lib/src/accordion/Accordion.tsx b/packages/lib/src/accordion/Accordion.tsx index 1e7466c2e7..9cc4e2e631 100644 --- a/packages/lib/src/accordion/Accordion.tsx +++ b/packages/lib/src/accordion/Accordion.tsx @@ -2,15 +2,15 @@ import { JSX, Children, useCallback, useMemo, useState } from "react"; import styled from "@emotion/styled"; import { getMargin } from "../common/utils"; import { spaces } from "../common/variables"; -import AccordionPropsType, { AccordionContextProps } from "./types"; +import { AccordionProps, AccordionContextProps } from "./types"; import AccordionContext from "./AccordionContext"; import AccordionItem from "./AccordionItem"; -const calculateWidth = (margin: AccordionPropsType["margin"]) => +const calculateWidth = (margin: AccordionProps["margin"]) => `calc(100% - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})`; const AccordionContainer = styled.div<{ - margin: AccordionPropsType["margin"]; + margin: AccordionProps["margin"]; }>` width: ${(props) => calculateWidth(props.margin)}; margin: ${({ margin }) => (margin && typeof margin !== "object" ? spaces[margin] : "var(--spacing-padding-none)")}; @@ -74,7 +74,7 @@ const AccordionItemWithProvider = ({ return {child}; }; -const DxcAccordion = (props: AccordionPropsType): JSX.Element => { +const DxcAccordion = (props: AccordionProps): JSX.Element => { const { children, defaultIndexActive, independent, indexActive, margin, onActiveChange } = props; const [innerIndexActive, setInnerIndexActive] = useState( diff --git a/packages/lib/src/accordion/types.ts b/packages/lib/src/accordion/types.ts index 8f44b489ad..0277ac928f 100644 --- a/packages/lib/src/accordion/types.ts +++ b/packages/lib/src/accordion/types.ts @@ -1,5 +1,5 @@ import { ReactNode, ReactElement } from "react"; -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, PrettifyTypes, SVG, Space } from "../common/types"; export type AccordionItemProps = { /** @@ -103,7 +103,7 @@ type NonIndependentProps = CommonProps & { onActiveChange?: (index: number[]) => void; }; -type Props = IndependentProps | NonIndependentProps; +export type AccordionProps = PrettifyTypes; export type AccordionContextProps = { index: number; @@ -112,4 +112,4 @@ export type AccordionContextProps = { independent?: boolean; }; -export default Props; +export type { AccordionProps as default }; \ No newline at end of file diff --git a/packages/lib/src/action-icon/ActionIcon.stories.tsx b/packages/lib/src/action-icon/ActionIcon.stories.tsx index 86a96bfc76..b44b03b0f0 100644 --- a/packages/lib/src/action-icon/ActionIcon.stories.tsx +++ b/packages/lib/src/action-icon/ActionIcon.stories.tsx @@ -5,7 +5,7 @@ import DxcActionIcon from "./ActionIcon"; import DxcFlex from "../flex/Flex"; import Title from "../../.storybook/components/Title"; import ExampleContainer, { PseudoState } from "../../.storybook/components/ExampleContainer"; -import { ActionIconPropTypes, Status } from "./types"; +import { ActionIconProps, Status } from "./types"; export default { title: "ActionIcon", @@ -17,10 +17,10 @@ type Story = StoryObj; type GroupingKey = "size" | "shape" | "color" | "statusPosition" | "statusMode" | "pseudoState"; type ActionIconRowProps = { - sizes?: ActionIconPropTypes["size"][]; - shapes?: ActionIconPropTypes["shape"][]; - colors?: ActionIconPropTypes["color"][]; - icon?: ActionIconPropTypes["icon"]; + sizes?: ActionIconProps["size"][]; + shapes?: ActionIconProps["shape"][]; + colors?: ActionIconProps["color"][]; + icon?: ActionIconProps["icon"]; statusModes?: Status["mode"][]; statusPositions?: (Status["position"] | undefined)[]; pseudoStates?: (PseudoState | "disabled" | undefined)[]; @@ -30,7 +30,7 @@ type ActionIconRowProps = { const ActionIconRow = ({ sizes = ["medium"], shapes = ["circle"], - colors = ["neutral"], + colors = [undefined], statusModes, statusPositions = [], pseudoStates = [], @@ -58,9 +58,9 @@ const ActionIconRow = ({ const renderGroup = ( level: number, filters: { - size?: ActionIconPropTypes["size"]; - shape?: ActionIconPropTypes["shape"]; - color?: ActionIconPropTypes["color"]; + size?: ActionIconProps["size"]; + shape?: ActionIconProps["shape"]; + color?: ActionIconProps["color"]; statusMode?: Status["mode"]; statusPosition?: Status["position"]; pseudoState?: PseudoState | "disabled"; @@ -117,9 +117,9 @@ const ActionIconRow = ({ return values.map((value) => { const newFilters = { ...filters }; - if (key === "size") newFilters.size = value as ActionIconPropTypes["size"]; - else if (key === "shape") newFilters.shape = value as ActionIconPropTypes["shape"]; - else if (key === "color") newFilters.color = value as ActionIconPropTypes["color"]; + if (key === "size") newFilters.size = value as ActionIconProps["size"]; + else if (key === "shape") newFilters.shape = value as ActionIconProps["shape"]; + else if (key === "color") newFilters.color = value as ActionIconProps["color"]; else if (key === "statusPosition") newFilters.statusPosition = value as Status["position"]; else if (key === "statusMode") newFilters.statusMode = value as Status["mode"]; else if (key === "pseudoState") newFilters.pseudoState = value as PseudoState | "disabled"; @@ -144,6 +144,7 @@ export const Shapes: Story = { sizes={["xsmall", "small", "medium", "large", "xlarge", "xxlarge"]} shapes={["circle", "square"]} groupBy={["shape", "size"]} + colors={["neutral"]} /> ), @@ -156,9 +157,10 @@ export const Colors: Story = { + ), }; @@ -167,10 +169,10 @@ export const PseudoStates: Story = { render: () => ( <> - <DxcActionIcon color="transparent" icon="settings" onClick={() => console.log("hello")} /> + <DxcActionIcon icon="settings" onClick={() => console.log("hello")} /> <ActionIconRow - colors={["transparent"]} + colors={undefined} sizes={["xsmall", "small", "medium", "large", "xlarge", "xxlarge"]} shapes={["square"]} statusModes={["success"]} @@ -182,24 +184,26 @@ export const PseudoStates: Story = { ), }; -export const Types: Story = { - render: () => ( - <> - <Title title="Icon (custom)" theme="light" level={2} /> - <ActionIconRow - sizes={["xsmall", "small", "medium", "large", "xlarge", "xxlarge"]} - shapes={["circle"]} - groupBy={["size"]} - /> - <Title title="Icon (default)" theme="light" level={2} /> - <ActionIconRow - sizes={["xsmall", "small", "medium", "large", "xlarge", "xxlarge"]} - shapes={["circle"]} - groupBy={["size"]} - /> - </> - ), -}; +// export const Types: Story = { +// render: () => ( +// <> +// <Title title="Icon (custom)" theme="light" level={2} /> +// <ActionIconRow +// sizes={["xsmall", "small", "medium", "large", "xlarge", "xxlarge"]} +// shapes={["circle"]} +// groupBy={["size"]} +// colors={["neutral"]} +// /> +// <Title title="Icon (default)" theme="light" level={2} /> +// <ActionIconRow +// sizes={["xsmall", "small", "medium", "large", "xlarge", "xxlarge"]} +// shapes={["circle"]} +// groupBy={["size"]} +// colors={["neutral"]} +// /> +// </> +// ), +// }; const Tooltip = () => ( <> diff --git a/packages/lib/src/action-icon/ActionIcon.tsx b/packages/lib/src/action-icon/ActionIcon.tsx index 1442ed9c62..b2341f272c 100644 --- a/packages/lib/src/action-icon/ActionIcon.tsx +++ b/packages/lib/src/action-icon/ActionIcon.tsx @@ -1,6 +1,6 @@ import styled from "@emotion/styled"; import { css } from "@emotion/react"; -import { ActionIconPropTypes } from "./types"; +import { ActionIconProps } from "./types"; import { getBackgroundColor, getBorderRadius, getColor, getIconSize, getOutlineWidth, getSize } from "./utils"; import DxcIcon from "../icon/Icon"; import { Tooltip } from "../tooltip/Tooltip"; @@ -8,10 +8,10 @@ import { Tooltip } from "../tooltip/Tooltip"; const ActionIconContainer = styled.div< { hasAction?: boolean; - shape: ActionIconPropTypes["shape"]; - size: ActionIconPropTypes["size"]; - disabled?: ActionIconPropTypes["disabled"]; - color: ActionIconPropTypes["color"]; + shape: ActionIconProps["shape"]; + size: ActionIconProps["size"]; + disabled?: ActionIconProps["disabled"]; + color?: ActionIconProps["color"]; } & React.AnchorHTMLAttributes<HTMLAnchorElement> >` /* Reset button default styles when rendered as button */ @@ -62,7 +62,7 @@ const ActionIconContainer = styled.div< const IconContainerWrapper = styled.div<{ hasAction?: boolean; - disabled: ActionIconPropTypes["disabled"]; + disabled: ActionIconProps["disabled"]; }>` height: 100%; width: 100%; @@ -82,7 +82,7 @@ const IconContainerWrapper = styled.div<{ `} `; -export const IconContainer = styled.div<{ size: ActionIconPropTypes["size"] }>` +export const IconContainer = styled.div<{ size: ActionIconProps["size"] }>` display: flex; justify-content: center; align-items: center; @@ -100,7 +100,7 @@ export const IconContainer = styled.div<{ size: ActionIconPropTypes["size"] }>` const ForwardedActionIcon = ({ ariaLabel, content, - color = "transparent", + color = undefined, disabled = false, icon, linkHref, @@ -110,7 +110,7 @@ const ForwardedActionIcon = ({ size = "medium", tabIndex = 0, title, -}: ActionIconPropTypes) => { +}: ActionIconProps) => { return ( <Tooltip label={title}> <ActionIconContainer diff --git a/packages/lib/src/action-icon/types.ts b/packages/lib/src/action-icon/types.ts index ea46592a7d..9430e25b51 100644 --- a/packages/lib/src/action-icon/types.ts +++ b/packages/lib/src/action-icon/types.ts @@ -1,21 +1,12 @@ import { MouseEvent, ReactNode, Ref } from "react"; -import { SVG } from "../common/utils"; +import { SVG, Color, Shape, Size } from "../common/types"; export type RefType = HTMLDivElement; - -type Size = "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge"; -type Shape = "circle" | "square"; -type Color = - "primary" | "secondary" | "tertiary" | "success" | "info" | "neutral" | "warning" | "error" | "transparent"; export interface Status { mode: "default" | "info" | "success" | "warning" | "error"; position: "top" | "bottom"; } -export type ActionIconPropTypes = - | (CommonProps & { content: ReactNode; icon?: string | SVG }) - | (CommonProps & { content?: ReactNode; icon: string | SVG }); - type CommonProps = { /** * Text to be used as aria-label for the Action Icon. It is recommended to provide this prop when using the onClick or linkHref properties and no title is provided. @@ -58,3 +49,9 @@ type CommonProps = { */ title?: string; }; + +export type ActionIconProps = + | (CommonProps & { content: ReactNode; icon?: string | SVG }) + | (CommonProps & { content?: ReactNode; icon: string | SVG }); + +export type { ActionIconProps as default }; \ No newline at end of file diff --git a/packages/lib/src/action-icon/utils.ts b/packages/lib/src/action-icon/utils.ts index 73d6287c80..d43f0487f3 100644 --- a/packages/lib/src/action-icon/utils.ts +++ b/packages/lib/src/action-icon/utils.ts @@ -1,4 +1,4 @@ -import { ActionIconPropTypes } from "./types"; +import { ActionIconProps } from "./types"; const contextualColorMap = { primary: { @@ -75,13 +75,13 @@ const outlineWidthMap = { xxlarge: "var(--border-width-l)", }; -export const getColor = (color: ActionIconPropTypes["color"]) => +export const getColor = (color: ActionIconProps["color"]) => color && contextualColorMap[color] ? contextualColorMap[color].text : contextualColorMap.transparent.text; -export const getBackgroundColor = (color: ActionIconPropTypes["color"]) => +export const getBackgroundColor = (color: ActionIconProps["color"]) => color && contextualColorMap[color] ? contextualColorMap[color].background : contextualColorMap.transparent.background; -export const getBorderRadius = (shape: ActionIconPropTypes["shape"], size: ActionIconPropTypes["size"]) => { +export const getBorderRadius = (shape: ActionIconProps["shape"], size: ActionIconProps["size"]) => { if (shape === "circle") { return "100%"; } @@ -91,10 +91,10 @@ export const getBorderRadius = (shape: ActionIconPropTypes["shape"], size: Actio return "100%"; }; -export const getSize = (size: ActionIconPropTypes["size"]) => (size && sizeMap[size] ? sizeMap[size] : "40px"); +export const getSize = (size: ActionIconProps["size"]) => (size && sizeMap[size] ? sizeMap[size] : "40px"); -export const getIconSize = (size: ActionIconPropTypes["size"]) => +export const getIconSize = (size: ActionIconProps["size"]) => size && iconSizeMap[size] ? iconSizeMap[size] : "var(--height-s)"; -export const getOutlineWidth = (size: ActionIconPropTypes["size"]) => +export const getOutlineWidth = (size: ActionIconProps["size"]) => size && outlineWidthMap[size] ? outlineWidthMap[size] : "var(--border-width-m)"; diff --git a/packages/lib/src/alert/Actions.tsx b/packages/lib/src/alert/Actions.tsx index 65ef62cfb8..80eb04af0b 100644 --- a/packages/lib/src/alert/Actions.tsx +++ b/packages/lib/src/alert/Actions.tsx @@ -1,7 +1,7 @@ import { memo } from "react"; import DxcButton from "../button/Button"; import DxcFlex from "../flex/Flex"; -import AlertPropsType from "./types"; +import { AlertProps } from "./types"; const Actions = memo( ({ @@ -9,7 +9,7 @@ const Actions = memo( primaryAction, secondaryAction, semantic, - }: Pick<AlertPropsType, "mode" | "primaryAction" | "secondaryAction" | "semantic">) => + }: Pick<AlertProps, "mode" | "primaryAction" | "secondaryAction" | "semantic">) => (primaryAction != null || secondaryAction != null) && ( <DxcFlex gap="var(--spacing-gap-s)" alignSelf={mode === "inline" || mode === "modal" ? "flex-end" : undefined}> {secondaryAction?.onClick && ( diff --git a/packages/lib/src/alert/Alert.tsx b/packages/lib/src/alert/Alert.tsx index 4c5f0d997e..2ce9104a91 100644 --- a/packages/lib/src/alert/Alert.tsx +++ b/packages/lib/src/alert/Alert.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; import { css } from "@emotion/react"; import { useState, useId, useEffect, useCallback, use, useMemo } from "react"; -import AlertPropsType from "./types"; +import { AlertProps } from "./types"; import DxcIcon from "../icon/Icon"; import DxcDivider from "../divider/Divider"; import DxcActionIcon from "../action-icon/ActionIcon"; @@ -11,8 +11,8 @@ import ModalAlertWrapper from "./ModalAlertWrapper"; import { HalstackLanguageContext } from "../HalstackContext"; const AlertContainer = styled.div<{ - semantic: AlertPropsType["semantic"]; - mode: AlertPropsType["mode"]; + semantic: AlertProps["semantic"]; + mode: AlertProps["mode"]; }>` box-sizing: border-box; display: flex; @@ -35,7 +35,7 @@ const AlertContainer = styled.div<{ overflow: hidden; `; -const TitleContainer = styled.div<{ mode: AlertPropsType["mode"]; semantic: AlertPropsType["semantic"] }>` +const TitleContainer = styled.div<{ mode: AlertProps["mode"]; semantic: AlertProps["semantic"] }>` flex-grow: 1; display: flex; align-items: center; @@ -55,13 +55,13 @@ const typographyStyles = css` font-weight: var(--typography-helper-text-regular); `; -const Title = styled.span<{ mode: AlertPropsType["mode"] }>` +const Title = styled.span<{ mode: AlertProps["mode"] }>` ${typographyStyles} font-size: ${(props) => (props.mode === "modal" ? "var(--typography-title-xl)" : "var(--typography-title-s)")}; font-weight: var(--typography-title-bold); `; -const Message = styled.div<{ mode: AlertPropsType["mode"] }>` +const Message = styled.div<{ mode: AlertProps["mode"] }>` ${typographyStyles} white-space: ${(props) => props.mode === "banner" && "nowrap"}; text-overflow: ${(props) => props.mode === "banner" && "ellipsis"}; @@ -79,7 +79,7 @@ const NavigationText = styled.span` font-size: var(--typography-helper-text-s); `; -const getIcon = (semantic: AlertPropsType["semantic"]) => { +const getIcon = (semantic: AlertProps["semantic"]) => { switch (semantic) { case "info": return <DxcIcon icon="filled_info" />; @@ -100,7 +100,7 @@ const DxcAlert = ({ secondaryAction, semantic = "info", title = "", -}: AlertPropsType) => { +}: AlertProps) => { const messages = useMemo(() => (Array.isArray(message) ? message : [message]), [message]); const [currentIndex, setCurrentIndex] = useState(0); diff --git a/packages/lib/src/alert/types.ts b/packages/lib/src/alert/types.ts index b348298997..581898af17 100644 --- a/packages/lib/src/alert/types.ts +++ b/packages/lib/src/alert/types.ts @@ -1,7 +1,7 @@ import { ReactNode } from "react"; -import { SVG } from "../common/utils"; +import { PrettifyTypes, SVG } from "../common/types"; -type Action = { +export type AlertAction = { /** * The icon of the action. It can be a string with the name of the icon or an SVG component. */ @@ -16,7 +16,7 @@ type Action = { onClick: () => void; }; -type Message = { +export type AlertMessage = { /** * The function that will be executed when the user clicks on the close action button. */ @@ -39,11 +39,11 @@ type CommonProps = { /** * Primary action of the alert. */ - primaryAction?: Action; + primaryAction?: AlertAction; /** * Secondary action of the alert. */ - secondaryAction?: Action; + secondaryAction?: AlertAction; /** * Specifies the semantic meaning of the alert. */ @@ -56,37 +56,37 @@ type CommonProps = { type ModeSpecificProps = | { - /** - * List of messages to be displayed. Each message has a close action that will, - * apart from remove from the alert the current message, call the onClose if it is defined. - * If the message is an array, the alert will show a navigation bar to move between the messages. - * The modal mode only allows one message per alert. In this case, the message must be an object - * and the presence of the onClose attribute is mandatory, since the management of the closing - * of the alert relies completely on the user. - */ - message?: Message | Message[]; - /** - * The mode of the alert. - */ - mode?: "inline" | "banner"; - } + /** + * List of messages to be displayed. Each message has a close action that will, + * apart from remove from the alert the current message, call the onClose if it is defined. + * If the message is an array, the alert will show a navigation bar to move between the messages. + * The modal mode only allows one message per alert. In this case, the message must be an object + * and the presence of the onClose attribute is mandatory, since the management of the closing + * of the alert relies completely on the user. + */ + message?: AlertMessage | AlertMessage[]; + /** + * The mode of the alert. + */ + mode?: "inline" | "banner"; + } | { - /** - * List of messages to be displayed. Each message has a close action that will, - * apart from remove from the alert the current message, call the onClose if it is defined. - * If the message is an array, the alert will show a navigation bar to move between the messages. - * The modal mode only allows one message per alert. In this case, the message must be an object - * and the presence of the onClose attribute is mandatory, since the management of the closing - * of the alert relies completely on the user. - */ - message: Required<Message>; - /** - * The mode of the alert. - */ - mode: "modal"; - }; + /** + * List of messages to be displayed. Each message has a close action that will, + * apart from remove from the alert the current message, call the onClose if it is defined. + * If the message is an array, the alert will show a navigation bar to move between the messages. + * The modal mode only allows one message per alert. In this case, the message must be an object + * and the presence of the onClose attribute is mandatory, since the management of the closing + * of the alert relies completely on the user. + */ + message: Required<AlertMessage>; + /** + * The mode of the alert. + */ + mode: "modal"; + }; -type Props = CommonProps & ModeSpecificProps; +export type AlertProps = PrettifyTypes<CommonProps & ModeSpecificProps>; export type ModalAlertWrapperProps = { condition: boolean; @@ -94,4 +94,4 @@ export type ModalAlertWrapperProps = { children: ReactNode; }; -export default Props; +export type { AlertProps as default }; \ No newline at end of file diff --git a/packages/lib/src/avatar/types.ts b/packages/lib/src/avatar/types.ts index 1f415bb4bf..1c7d9692d2 100644 --- a/packages/lib/src/avatar/types.ts +++ b/packages/lib/src/avatar/types.ts @@ -1,15 +1,12 @@ import { Ref } from "react"; -import { SVG } from "../common/utils"; +import { SVG, Color, Size, Shape } from "../common/types"; -type Size = "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge"; -type Shape = "circle" | "square"; -type Color = "primary" | "secondary" | "tertiary" | "success" | "info" | "neutral" | "warning" | "error"; -export interface Status { +export type AvatarStatus = { mode: "default" | "info" | "success" | "warning" | "error"; position: "top" | "bottom"; -} +}; -type Props = { +export type AvatarProps = { /** * Affects the visual style of the avatar. It can be used following semantic purposes or not. */ @@ -63,7 +60,7 @@ type Props = { * Defines the color of the status indicator displayed on the avatar and where it will be placed. * If not provided, no indicator will be rendered. */ - status?: Status; + status?: AvatarStatus; /** * Value of the tabindex attribute. It will only apply when the onClick property is passed. */ @@ -95,7 +92,7 @@ export type ContentType = { initials: string; icon?: string | SVG; color: Color; - status?: Status; + status?: AvatarStatus; }; -export default Props; +export type { AvatarProps as default }; \ No newline at end of file diff --git a/packages/lib/src/badge/Badge.tsx b/packages/lib/src/badge/Badge.tsx index 1b99d52519..03f5dbecfd 100644 --- a/packages/lib/src/badge/Badge.tsx +++ b/packages/lib/src/badge/Badge.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import BadgePropsType from "./types"; +import { BadgeProps } from "./types"; import DxcIcon from "../icon/Icon"; import { Tooltip } from "../tooltip/Tooltip"; @@ -82,13 +82,13 @@ const sizeMap = { }, }; -const getColor = (mode: BadgePropsType["mode"], color: BadgePropsType["color"]) => +const getColor = (mode: BadgeProps["mode"], color: BadgeProps["color"]) => mode === "contextual" && color ? contextualColorMap[color].text : notificationColor.text; -const getBackgroundColor = (mode: BadgePropsType["mode"], color: BadgePropsType["color"]) => +const getBackgroundColor = (mode: BadgeProps["mode"], color: BadgeProps["color"]) => mode === "contextual" && color ? contextualColorMap[color].background : notificationColor.background; -const getPadding = (mode: BadgePropsType["mode"], size: BadgePropsType["size"], label: BadgePropsType["label"]) => +const getPadding = (mode: BadgeProps["mode"], size: BadgeProps["size"], label: BadgeProps["label"]) => size && (mode === "contextual" ? sizeMap[size].padding.contextual @@ -97,10 +97,10 @@ const getPadding = (mode: BadgePropsType["mode"], size: BadgePropsType["size"], : sizeMap[size].padding.notification); const BadgeContainer = styled.div<{ - label: BadgePropsType["label"]; - mode: BadgePropsType["mode"]; - color: BadgePropsType["color"]; - size: BadgePropsType["size"]; + label: BadgeProps["label"]; + mode: BadgeProps["mode"]; + color: BadgeProps["color"]; + size: BadgeProps["size"]; }>` box-sizing: border-box; border-radius: ${(props) => props.size && sizeMap[props.size].borderRadius}; @@ -117,7 +117,7 @@ const BadgeContainer = styled.div<{ color: ${(props) => getColor(props.mode, props.color)}; `; -const IconContainer = styled.div<{ size: BadgePropsType["size"] }>` +const IconContainer = styled.div<{ size: BadgeProps["size"] }>` display: flex; font-size: ${(props) => props.size && sizeMap[props.size].iconSize}; @@ -127,7 +127,7 @@ const IconContainer = styled.div<{ size: BadgePropsType["size"] }>` } `; -const Label = styled.span<{ size: BadgePropsType["size"] }>` +const Label = styled.span<{ size: BadgeProps["size"] }>` font-family: var(--typography-font-family); font-size: ${(props) => props.size && sizeMap[props.size].fontSize}; font-style: normal; @@ -145,7 +145,7 @@ const DxcBadge = ({ notificationLimit = 99, ref, size = "medium", -}: BadgePropsType) => ( +}: BadgeProps) => ( <Tooltip label={title}> <BadgeContainer label={label} diff --git a/packages/lib/src/badge/types.ts b/packages/lib/src/badge/types.ts index c77c5029f1..2370b66828 100644 --- a/packages/lib/src/badge/types.ts +++ b/packages/lib/src/badge/types.ts @@ -1,6 +1,25 @@ -import { SVG } from "../common/utils"; +import { Color, PrettifyTypes, SVG } from "../common/types"; -export type ContextualProps = { +export type CommonProps = { + /** + * Text representing advisory information related to the badge. Under the hood, this prop also serves as an accessible label for the component. + */ + title?: string; + /** + * Material Symbol name or SVG element used as the icon that will be placed next to the badge label in contextual mode. + */ + icon?: string | SVG; + /** + * Ref to be forwarded to the badge container element. + */ + ref?: React.Ref<HTMLDivElement>; + /** + * Size of the component. + */ + size?: "small" | "medium" | "large"; +}; + +export type ContextualBadgeProps = CommonProps & { /** * Text to be placed in the badge. */ @@ -16,10 +35,10 @@ export type ContextualProps = { /** * Affects the visual style of the badge. It can be used following semantic purposes or not. */ - color?: "primary" | "secondary" | "tertiary" | "success" | "info" | "neutral" | "warning" | "error"; + color?: Color; }; -export type NotificationProps = { +export type NotificationBadgeProps = CommonProps & { /** * Text to be placed in the badge. */ @@ -38,25 +57,6 @@ export type NotificationProps = { color?: never; }; -export type CommonProps = { - /** - * Text representing advisory information related to the badge. Under the hood, this prop also serves as an accessible label for the component. - */ - title?: string; - /** - * Material Symbol name or SVG element used as the icon that will be placed next to the badge label in contextual mode. - */ - icon?: string | SVG; - /** - * Ref to be forwarded to the badge container element. - */ - ref?: React.Ref<HTMLDivElement>; - /** - * Size of the component. - */ - size?: "small" | "medium" | "large"; -}; - -type Props = (ContextualProps | NotificationProps) & CommonProps; +export type BadgeProps = PrettifyTypes<ContextualBadgeProps> | PrettifyTypes<NotificationBadgeProps>; -export default Props; +export type { BadgeProps as default }; \ No newline at end of file diff --git a/packages/lib/src/base-menu/GroupItem.tsx b/packages/lib/src/base-menu/GroupItem.tsx index 8b6cdf8642..cabbeb58e7 100644 --- a/packages/lib/src/base-menu/GroupItem.tsx +++ b/packages/lib/src/base-menu/GroupItem.tsx @@ -3,12 +3,12 @@ import DxcIcon from "../icon/Icon"; import SubMenu from "./SubMenu"; import ItemAction from "./ItemAction"; import MenuItem from "./MenuItem"; -import { GroupItemProps } from "./types"; +import { BaseGroupItemProps } from "./types"; import { useGroupItem } from "./useGroupItem"; import BaseMenuContext from "./BaseMenuContext"; import DxcPopover from "../popover/Popover"; -const GroupItem = ({ items, ...props }: GroupItemProps) => { +const GroupItem = ({ items, ...props }: BaseGroupItemProps) => { const groupMenuId = `group-menu-${useId()}`; const contextValue = use(BaseMenuContext) ?? {}; const { groupSelected, isOpen, toggleOpen, hasPopOver, isHorizontal } = useGroupItem( diff --git a/packages/lib/src/base-menu/ItemAction.tsx b/packages/lib/src/base-menu/ItemAction.tsx index df7d2a0480..a6f39bcfa0 100644 --- a/packages/lib/src/base-menu/ItemAction.tsx +++ b/packages/lib/src/base-menu/ItemAction.tsx @@ -1,13 +1,13 @@ import { memo } from "react"; import styled from "@emotion/styled"; -import { ItemActionProps } from "./types"; +import { BaseItemActionProps } from "./types"; import DxcIcon from "../icon/Icon"; import { TooltipWrapper } from "../tooltip/Tooltip"; import { useItemAction } from "./useItemAction"; const Action = styled.a<{ - depthLevel: ItemActionProps["depthLevel"]; - selected: ItemActionProps["selected"]; + depthLevel: BaseItemActionProps["depthLevel"]; + selected: BaseItemActionProps["selected"]; displayGroupLines: boolean; hasPopOver?: boolean; isHorizontal?: boolean; @@ -60,7 +60,7 @@ const Icon = styled.span` } `; -const Text = styled.span<{ selected: ItemActionProps["selected"] }>` +const Text = styled.span<{ selected: BaseItemActionProps["selected"] }>` color: var(--color-fg-neutral-dark); font-family: var(--typography-font-family); font-size: var(--typography-label-m); @@ -79,7 +79,7 @@ const Control = styled.span` gap: var(--spacing-gap-s); `; -const ItemAction = memo(({ ...props }: ItemActionProps) => { +const ItemAction = memo(({ ...props }: BaseItemActionProps) => { const { hasTooltip, modifiedBadge, diff --git a/packages/lib/src/base-menu/MenuItem.tsx b/packages/lib/src/base-menu/MenuItem.tsx index b70663a489..6fad9c6975 100644 --- a/packages/lib/src/base-menu/MenuItem.tsx +++ b/packages/lib/src/base-menu/MenuItem.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; import GroupItem from "./GroupItem"; import SingleItem from "./SingleItem"; -import { MenuItemProps } from "./types"; +import { BaseMenuItemProps } from "./types"; import { isGroupItem } from "./utils"; const MenuItemContainer = styled.li` @@ -9,7 +9,7 @@ const MenuItemContainer = styled.li` gap: var(--spacing-gap-xs); `; -export default function MenuItem({ item, depthLevel = 0 }: MenuItemProps) { +export default function MenuItem({ item, depthLevel = 0 }: BaseMenuItemProps) { return ( <MenuItemContainer role="menuitem"> {isGroupItem(item) ? ( diff --git a/packages/lib/src/base-menu/Section.tsx b/packages/lib/src/base-menu/Section.tsx index 7cb5a1f14f..5a730afe41 100644 --- a/packages/lib/src/base-menu/Section.tsx +++ b/packages/lib/src/base-menu/Section.tsx @@ -2,7 +2,7 @@ import { use, useId } from "react"; import styled from "@emotion/styled"; import SubMenu from "./SubMenu"; import MenuItem from "./MenuItem"; -import { SectionProps } from "./types"; +import { BaseSectionProps } from "./types"; import BaseMenuContext from "./BaseMenuContext"; import DxcInset from "../inset/Inset"; import DxcDivider from "../divider/Divider"; @@ -21,7 +21,7 @@ const Title = styled.h2` padding: var(--spacing-padding-xxs); `; -export default function Section({ index, length, section }: SectionProps) { +export default function Section({ index, length, section }: BaseSectionProps) { const id = `section-${useId()}`; const { hasPopOver } = use(BaseMenuContext) ?? {}; return ( diff --git a/packages/lib/src/base-menu/SingleItem.tsx b/packages/lib/src/base-menu/SingleItem.tsx index c0482e574f..8699712bf4 100644 --- a/packages/lib/src/base-menu/SingleItem.tsx +++ b/packages/lib/src/base-menu/SingleItem.tsx @@ -1,9 +1,9 @@ import { use, useEffect } from "react"; import ItemAction from "./ItemAction"; -import { SingleItemProps } from "./types"; +import { BaseSingleItemProps } from "./types"; import BaseMenuContext from "./BaseMenuContext"; -export default function SingleItem({ id, onSelect, selected = false, ...props }: SingleItemProps) { +export default function SingleItem({ id, onSelect, selected = false, ...props }: BaseSingleItemProps) { const { selectedItemId, setSelectedItemId, hasPopOver, closePopOver, onSelectItem } = use(BaseMenuContext) ?? {}; const handleClick = () => { diff --git a/packages/lib/src/base-menu/SubMenu.tsx b/packages/lib/src/base-menu/SubMenu.tsx index 3874bd8859..902a7148c2 100644 --- a/packages/lib/src/base-menu/SubMenu.tsx +++ b/packages/lib/src/base-menu/SubMenu.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import { SubMenuProps } from "./types"; +import { BaseSubMenuProps } from "./types"; import BaseMenuContext from "./BaseMenuContext"; import { use } from "react"; @@ -35,7 +35,7 @@ export default function SubMenu({ depthLevel = 0, isHorizontal = false, isPopOver = false, -}: SubMenuProps) { +}: BaseSubMenuProps) { const { displayGroupLines } = use(BaseMenuContext) ?? {}; return ( <SubMenuContainer diff --git a/packages/lib/src/base-menu/types.ts b/packages/lib/src/base-menu/types.ts index e86c87e0ed..c8da76d92a 100644 --- a/packages/lib/src/base-menu/types.ts +++ b/packages/lib/src/base-menu/types.ts @@ -1,30 +1,30 @@ import { ButtonHTMLAttributes, Dispatch, ReactElement, ReactNode, SetStateAction } from "react"; -import { SVG } from "../common/utils"; +import { SVG } from "../common/types"; -type CommonItemProps = { +type BaseCommonItemProps = { badge?: ReactElement; icon?: string | SVG; label: string; }; -type Item = CommonItemProps & { +type BaseItem = BaseCommonItemProps & { onSelect?: () => void; selected?: boolean; href?: string; renderItem?: (props: { children: ReactNode }) => ReactNode; }; -type GroupItem = CommonItemProps & { - items: (Item | GroupItem)[]; +type BaseGroupItem = BaseCommonItemProps & { + items: (BaseItem | BaseGroupItem)[]; defaultOpen?: boolean; }; -type Section = { items: (Item | GroupItem)[]; title?: string }; -type Props = { +type BaseSection = { items: (BaseItem | BaseGroupItem)[]; title?: string }; +type BaseMenuProps = { /** * Array of items to be displayed in the menu. * Each item can be a single/simple item, a group item or a section. */ - items: (Item | GroupItem)[] | Section[]; + items: (BaseItem | BaseGroupItem)[] | BaseSection[]; /** * If true the menu will be displayed with a border. */ @@ -52,41 +52,41 @@ type Props = { onSelectItem?: () => void; }; -type ItemWithId = Item & { id: number }; +type BaseItemWithId = BaseItem & { id: number }; -type GroupItemWithId = Omit<GroupItem, "items"> & { - items: (ItemWithId | GroupItemWithId)[]; +type BaseGroupItemWithId = Omit<BaseGroupItem, "items"> & { + items: (BaseItemWithId | BaseGroupItemWithId)[]; }; -type SectionWithId = { items: (ItemWithId | GroupItemWithId)[]; title?: string }; +type BaseSectionWithId = { items: (BaseItemWithId | BaseGroupItemWithId)[]; title?: string }; -type SingleItemProps = ItemWithId & { +type BaseSingleItemProps = BaseItemWithId & { depthLevel: number; }; -type GroupItemProps = GroupItemWithId & { +type BaseGroupItemProps = BaseGroupItemWithId & { depthLevel: number; }; -type MenuItemProps = { - item: ItemWithId | GroupItemWithId; +type BaseMenuItemProps = { + item: BaseItemWithId | BaseGroupItemWithId; depthLevel?: number; }; -type ItemActionProps = ButtonHTMLAttributes<HTMLAnchorElement> & { - badge?: Item["badge"]; +type BaseItemActionProps = ButtonHTMLAttributes<HTMLAnchorElement> & { + badge?: BaseItem["badge"]; collapseIcon?: ReactNode; depthLevel: number; - icon?: Item["icon"]; - label: Item["label"]; + icon?: BaseItem["icon"]; + label: BaseItem["label"]; ref?: React.Ref<HTMLAnchorElement> | undefined; - selected: Item["selected"]; - href?: Item["href"]; - renderItem?: Item["renderItem"]; + selected: BaseItem["selected"]; + href?: BaseItem["href"]; + renderItem?: BaseItem["renderItem"]; }; -type SectionProps = { - section: SectionWithId; +type BaseSectionProps = { + section: BaseSectionWithId; index: number; length: number; }; -type SubMenuProps = { +type BaseSubMenuProps = { children: ReactNode; id?: string; depthLevel?: number; @@ -105,20 +105,20 @@ type BaseMenuContextProps = { }; export type { - CommonItemProps, + BaseCommonItemProps, BaseMenuContextProps, - GroupItem, - GroupItemProps, - GroupItemWithId, - Item, - ItemActionProps, - ItemWithId, - SubMenuProps, - MenuItemProps, - Section, - SectionWithId, - SectionProps, - SingleItemProps, + BaseGroupItem, + BaseGroupItemProps, + BaseGroupItemWithId, + BaseItem, + BaseItemActionProps, + BaseItemWithId, + BaseSubMenuProps, + BaseMenuItemProps, + BaseSection, + BaseSectionWithId, + BaseSectionProps, + BaseSingleItemProps, + BaseMenuProps, + BaseMenuProps as default, }; - -export default Props; diff --git a/packages/lib/src/base-menu/useGroupItem.ts b/packages/lib/src/base-menu/useGroupItem.ts index 96f11608bd..e349e4cd0e 100644 --- a/packages/lib/src/base-menu/useGroupItem.ts +++ b/packages/lib/src/base-menu/useGroupItem.ts @@ -1,14 +1,18 @@ import { useId, useMemo, useState } from "react"; -import { BaseMenuContextProps, GroupItemProps } from "./types"; +import { BaseMenuContextProps, BaseGroupItemProps } from "./types"; -const isGroupSelected = (items: GroupItemProps["items"], selectedItemId?: number): boolean => +const isGroupSelected = (items: BaseGroupItemProps["items"], selectedItemId?: number): boolean => items.some((item) => { if ("items" in item) return isGroupSelected(item.items, selectedItemId); else if (selectedItemId !== -1) return item.id === selectedItemId; else return !!item.selected; }); -export const useGroupItem = (items: GroupItemProps["items"], context: BaseMenuContextProps, defaultOpen?: boolean) => { +export const useGroupItem = ( + items: BaseGroupItemProps["items"], + context: BaseMenuContextProps, + defaultOpen?: boolean +) => { const groupMenuId = `group-menu-${useId()}`; const { selectedItemId, hasPopOver } = context ?? {}; const groupSelected = useMemo(() => isGroupSelected(items, selectedItemId), [items, selectedItemId]); diff --git a/packages/lib/src/base-menu/useItemAction.ts b/packages/lib/src/base-menu/useItemAction.ts index 46ac53d040..a394986ca5 100644 --- a/packages/lib/src/base-menu/useItemAction.ts +++ b/packages/lib/src/base-menu/useItemAction.ts @@ -1,8 +1,8 @@ import { useState, use, cloneElement, ReactNode, ReactElement } from "react"; import BaseMenuContext from "./BaseMenuContext"; -import { ItemActionProps } from "./types"; +import { BaseItemActionProps } from "./types"; -export function useItemAction({ badge, renderItem }: ItemActionProps) { +export function useItemAction({ badge, renderItem }: BaseItemActionProps) { const [hasTooltip, setHasTooltip] = useState(false); const modifiedBadge = badge && cloneElement(badge as ReactElement<{ size?: string }>, { size: "small" }); const { displayControlsAfter, hasPopOver, displayGroupLines, isHorizontal } = use(BaseMenuContext) ?? {}; diff --git a/packages/lib/src/base-menu/utils.ts b/packages/lib/src/base-menu/utils.ts index 77db32b032..37182c3684 100644 --- a/packages/lib/src/base-menu/utils.ts +++ b/packages/lib/src/base-menu/utils.ts @@ -1,36 +1,36 @@ import ContextualMenuPropsType, { - GroupItem, - GroupItemProps, - GroupItemWithId, - Item, - ItemWithId, - Section as SectionType, - SectionWithId, + BaseGroupItem, + BaseGroupItemProps, + BaseGroupItemWithId, + BaseItem, + BaseItemWithId, + BaseSection, + BaseSectionWithId, } from "./types"; -export const isGroupItem = (item: Item | GroupItem): item is GroupItem => "items" in item; +export const isGroupItem = (item: BaseItem | BaseGroupItem): item is BaseGroupItem => "items" in item; -export const isSection = (item: SectionType | Item | GroupItem): item is SectionType => +export const isSection = (item: BaseSection | BaseItem | BaseGroupItem): item is BaseSection => "items" in item && !("label" in item); export const addIdToItems = ( items: ContextualMenuPropsType["items"] -): (ItemWithId | GroupItemWithId | SectionWithId)[] => { +): (BaseItemWithId | BaseGroupItemWithId | BaseSectionWithId)[] => { let accId = 0; const innerAddIdToItems = ( items: ContextualMenuPropsType["items"] - ): (ItemWithId | GroupItemWithId | SectionWithId)[] => - items.map((item: Item | GroupItem | SectionType) => + ): (BaseItemWithId | BaseGroupItemWithId | BaseSectionWithId)[] => + items.map((item: BaseItem | BaseGroupItem | BaseSection) => isSection(item) - ? ({ ...item, items: innerAddIdToItems(item.items) } as SectionWithId) + ? ({ ...item, items: innerAddIdToItems(item.items) } as BaseSectionWithId) : isGroupItem(item) - ? ({ ...item, items: innerAddIdToItems(item.items) } as GroupItemWithId) + ? ({ ...item, items: innerAddIdToItems(item.items) } as BaseGroupItemWithId) : { ...item, id: accId++ } ); return innerAddIdToItems(items); }; -export const isGroupSelected = (items: GroupItemProps["items"], selectedItemId?: number): boolean => +export const isGroupSelected = (items: BaseGroupItemProps["items"], selectedItemId?: number): boolean => items.some((item) => { if ("items" in item) return isGroupSelected(item.items, selectedItemId); else if (selectedItemId !== -1) return item.id === selectedItemId; diff --git a/packages/lib/src/bleed/Bleed.tsx b/packages/lib/src/bleed/Bleed.tsx index c4a9af9f6d..2f40334875 100644 --- a/packages/lib/src/bleed/Bleed.tsx +++ b/packages/lib/src/bleed/Bleed.tsx @@ -1,9 +1,9 @@ -import BleedPropsType from "./types"; +import { BleedProps } from "./types"; import DxcContainer from "../container/Container"; const getNegativeValue = (value?: string) => (value ? `calc(${value} * -1)` : null); -const DxcBleed = ({ space, horizontal, vertical, top, right, bottom, left, children }: BleedPropsType) => ( +const DxcBleed = ({ space, horizontal, vertical, top, right, bottom, left, children }: BleedProps) => ( <DxcContainer margin={{ top: getNegativeValue(top) ?? getNegativeValue(vertical) ?? getNegativeValue(space) ?? "0rem", diff --git a/packages/lib/src/bleed/types.ts b/packages/lib/src/bleed/types.ts index c008340530..19652b5a0a 100644 --- a/packages/lib/src/bleed/types.ts +++ b/packages/lib/src/bleed/types.ts @@ -1,6 +1,6 @@ import { ReactNode } from "react"; -type Props = { +export type BleedProps = { /** * Applies the spacing scale to all sides. */ @@ -35,4 +35,4 @@ type Props = { children: ReactNode; }; -export default Props; +export type { BleedProps as default }; diff --git a/packages/lib/src/breadcrumbs/Breadcrumbs.tsx b/packages/lib/src/breadcrumbs/Breadcrumbs.tsx index 774df0240a..d1ba3c12e7 100644 --- a/packages/lib/src/breadcrumbs/Breadcrumbs.tsx +++ b/packages/lib/src/breadcrumbs/Breadcrumbs.tsx @@ -1,6 +1,6 @@ import { useCallback } from "react"; import styled from "@emotion/styled"; -import BreadcrumbsProps from "./types"; +import { BreadcrumbsProps } from "./types"; import DxcDropdown from "../dropdown/Dropdown"; import DxcIcon from "../icon/Icon"; import Item from "./Item"; diff --git a/packages/lib/src/breadcrumbs/Item.tsx b/packages/lib/src/breadcrumbs/Item.tsx index 59b7707e02..b0f8836fdc 100644 --- a/packages/lib/src/breadcrumbs/Item.tsx +++ b/packages/lib/src/breadcrumbs/Item.tsx @@ -1,8 +1,8 @@ import { useRef, MouseEvent } from "react"; import styled from "@emotion/styled"; -import { ItemPropsType } from "./types"; +import { BreadcrumbsItemProps } from "./types"; -const ListItem = styled.li<{ isCurrentPage?: ItemPropsType["isCurrentPage"] }>` +const ListItem = styled.li<{ isCurrentPage?: BreadcrumbsItemProps["isCurrentPage"] }>` display: flex; align-items: center; color: var(--color-fg-neutral-dark); @@ -44,7 +44,7 @@ const Text = styled.span` } `; -const Item = ({ isCurrentPage = false, href, label, onClick }: ItemPropsType) => { +const Item = ({ isCurrentPage = false, href, label, onClick }: BreadcrumbsItemProps) => { const currentItemRef = useRef<HTMLSpanElement | null>(null); const handleOnClick = (event: MouseEvent<HTMLAnchorElement>) => { diff --git a/packages/lib/src/breadcrumbs/types.ts b/packages/lib/src/breadcrumbs/types.ts index 2912e649d9..195857b5e2 100644 --- a/packages/lib/src/breadcrumbs/types.ts +++ b/packages/lib/src/breadcrumbs/types.ts @@ -1,8 +1,10 @@ -type Item = { +import { PrettifyTypes } from "../common/types"; + +export type BreadcrumbsItem = { href?: string; label: string; }; -type Props = { +export type BreadcrumbsProps = { /** * Provides a label that describes the type of navigation enabled by * the component. @@ -11,7 +13,7 @@ type Props = { /** * Array of objects representing the items of the breadcrumbs. */ - items: Item[]; + items: BreadcrumbsItem[]; /** * Number of items before showing a collapsed version of the * breadcrumbs. It can't be lower than two (root/collapsed action and @@ -34,9 +36,11 @@ type Props = { showRoot?: boolean; }; -export type ItemPropsType = Item & { - isCurrentPage?: boolean; - onClick?: (href: string) => void; -}; +export type BreadcrumbsItemProps = PrettifyTypes< + BreadcrumbsItem & { + isCurrentPage?: boolean; + onClick?: (href: string) => void; + } +>; -export default Props; +export type { BreadcrumbsProps as default }; \ No newline at end of file diff --git a/packages/lib/src/bulleted-list/BulletedList.tsx b/packages/lib/src/bulleted-list/BulletedList.tsx index 5bae88571d..9ebfc89abe 100644 --- a/packages/lib/src/bulleted-list/BulletedList.tsx +++ b/packages/lib/src/bulleted-list/BulletedList.tsx @@ -2,7 +2,7 @@ import { JSX, Children } from "react"; import styled from "@emotion/styled"; import DxcFlex from "../flex/Flex"; import DxcTypography from "../typography/Typography"; -import BulletedListPropsType, { BulletedListItemPropsType } from "./types"; +import { BulletedListProps, BulletedListItemProps } from "./types"; import DxcIcon from "../icon/Icon"; const ListContainer = styled.div` @@ -79,9 +79,9 @@ const ListItem = styled.li` padding: var(--spacing-padding-none); `; -const BulletedListItem = ({ children }: BulletedListItemPropsType): JSX.Element => <>{children}</>; +const BulletedListItem = ({ children }: BulletedListItemProps): JSX.Element => <>{children}</>; -const DxcBulletedList = ({ children, type = "disc", icon = "" }: BulletedListPropsType): JSX.Element => ( +const DxcBulletedList = ({ children, type = "disc", icon = "" }: BulletedListProps): JSX.Element => ( <ListContainer> <DxcFlex direction="column" as={type === "number" ? "ol" : "ul"} gap="0.125rem"> {Children.map(children, (child, index) => ( diff --git a/packages/lib/src/bulleted-list/types.ts b/packages/lib/src/bulleted-list/types.ts index 24ae1f1125..2a4c8aee13 100644 --- a/packages/lib/src/bulleted-list/types.ts +++ b/packages/lib/src/bulleted-list/types.ts @@ -1,7 +1,7 @@ import { ReactNode } from "react"; -import { SVG } from "../common/utils"; +import { PrettifyTypes, SVG } from "../common/types"; -type IconProps = { +type BulletedListIconProps = { /** * Defines the style of the bullet point in the list. */ @@ -16,7 +16,7 @@ type IconProps = { children: ReactNode; }; -type OtherProps = { +type BulletedListWithoutIconProps = { /** * Defines the style of the bullet point in the list. */ @@ -31,13 +31,13 @@ type OtherProps = { children: ReactNode; }; -type Props = IconProps | OtherProps; +export type BulletedListProps = PrettifyTypes<BulletedListIconProps | BulletedListWithoutIconProps>; -export type BulletedListItemPropsType = { +export type BulletedListItemProps = { /** * Text to be shown in the list. */ children?: ReactNode; }; -export default Props; +export type { BulletedListProps as default }; \ No newline at end of file diff --git a/packages/lib/src/button/Button.tsx b/packages/lib/src/button/Button.tsx index e7b9d09d8c..5784d59e22 100644 --- a/packages/lib/src/button/Button.tsx +++ b/packages/lib/src/button/Button.tsx @@ -1,17 +1,17 @@ import styled from "@emotion/styled"; import { spaces } from "../common/variables"; -import ButtonPropsType, { Mode, Semantic, Size } from "./types"; +import { ButtonMode, ButtonSemantic, ButtonSize, ButtonProps } from "./types"; import DxcIcon from "../icon/Icon"; import { Tooltip } from "../tooltip/Tooltip"; import { calculateWidth, getButtonStyles, getHeight } from "./utils"; const Button = styled.button<{ iconOnly: boolean; - iconPosition: ButtonPropsType["iconPosition"]; - margin: ButtonPropsType["margin"]; - semantic: Semantic; - size: Size; - $mode: Mode; + iconPosition: ButtonProps["iconPosition"]; + margin: ButtonProps["margin"]; + semantic: ButtonSemantic; + size: ButtonSize; + $mode: ButtonMode; }>` display: inline-flex; align-items: center; @@ -54,7 +54,7 @@ const LabelContainer = styled.span` `; const IconContainer = styled.div<{ - size: Size; + size: ButtonSize; }>` display: flex; font-size: ${({ size }) => @@ -80,7 +80,7 @@ const DxcButton = ({ tabIndex = 0, title, type = "button", -}: ButtonPropsType) => { +}: ButtonProps) => { return ( <Tooltip label={title}> <Button diff --git a/packages/lib/src/button/types.ts b/packages/lib/src/button/types.ts index 7f60a651fc..0167cfe64f 100644 --- a/packages/lib/src/button/types.ts +++ b/packages/lib/src/button/types.ts @@ -1,8 +1,8 @@ -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; -export type Semantic = "default" | "error" | "warning" | "success" | "info"; -export type Mode = "primary" | "secondary" | "tertiary"; -export type Size = { +export type ButtonSemantic = "default" | "error" | "warning" | "success" | "info"; +export type ButtonMode = "primary" | "secondary" | "tertiary"; +export type ButtonSize = { /** * Height of the button. */ @@ -13,7 +13,7 @@ export type Size = { width?: "small" | "medium" | "large" | "fillParent" | "fitContent"; }; -type Props = { +export type ButtonProps = { /** * If true, the component will be disabled. */ @@ -38,7 +38,7 @@ type Props = { /** * The available button modes. */ - mode?: Mode; + mode?: ButtonMode; /** * This function will be called when the user clicks the button. */ @@ -50,11 +50,11 @@ type Props = { /** * Specifies the semantic meaning of the buttons, which determines its color. */ - semantic?: Semantic; + semantic?: ButtonSemantic; /** * Size of the component. */ - size?: Size; + size?: ButtonSize; /** * Value of the tabindex attribute. */ @@ -69,4 +69,4 @@ type Props = { type?: "button" | "reset" | "submit"; }; -export default Props; +export type { ButtonProps as default }; diff --git a/packages/lib/src/button/utils.ts b/packages/lib/src/button/utils.ts index 9bd0f81cbe..080a0ac532 100644 --- a/packages/lib/src/button/utils.ts +++ b/packages/lib/src/button/utils.ts @@ -1,7 +1,11 @@ import { getMargin } from "../common/utils"; -import ButtonPropsType, { Mode, Semantic, Size } from "./types"; +import { ButtonProps, ButtonMode, ButtonSemantic, ButtonSize } from "./types"; -export const getButtonStyles = (mode: Mode, semantic: Semantic | "unselected" | "selected", size: Size) => { +export const getButtonStyles = ( + mode: ButtonMode, + semantic: ButtonSemantic | "unselected" | "selected", + size: ButtonSize +) => { let enabled = ""; let hover = ""; let active = ""; @@ -207,12 +211,12 @@ const widths = { fitContent: "fit-content", }; -export const calculateWidth = (margin: ButtonPropsType["margin"], size: ButtonPropsType["size"]) => +export const calculateWidth = (margin: ButtonProps["margin"], size: ButtonProps["size"]) => size?.width === "fillParent" ? `calc(${widths[size?.width]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` : size?.width && widths[size?.width]; -export const getHeight = (height: Size["height"]) => { +export const getHeight = (height: ButtonSize["height"]) => { switch (height) { case "small": return "var(--height-s)"; diff --git a/packages/lib/src/card/Card.tsx b/packages/lib/src/card/Card.tsx index 2653f30c6f..eec25a033b 100644 --- a/packages/lib/src/card/Card.tsx +++ b/packages/lib/src/card/Card.tsx @@ -1,6 +1,6 @@ import { Ref, use, useEffect, useState } from "react"; import styled from "@emotion/styled"; -import CardPropsType from "./types"; +import { CardProps } from "./types"; import DxcImage from "../image/Image"; import { getCardStyles, emptyIconSizes, handleEvent, getSelectableWrapperStyles } from "./utils"; import DxcFlex from "../flex/Flex"; @@ -9,13 +9,13 @@ import DxcTypography from "../typography/Typography"; import { HalstackLanguageContext } from "../HalstackContext"; const Card = styled.div<{ - mode: CardPropsType["mode"]; - direction?: CardPropsType["direction"]; - imagePosition?: CardPropsType["imagePosition"]; + mode: CardProps["mode"]; + direction?: CardProps["direction"]; + imagePosition?: CardProps["imagePosition"]; selectable?: boolean; interactive?: boolean; selected?: boolean; - size?: CardPropsType["size"]; + size?: CardProps["size"]; }>` display: flex; flex-direction: ${({ direction, imagePosition }) => @@ -38,7 +38,7 @@ const SelectableWrapper = styled.div<{ selected: boolean }>` overflow: hidden; `; -const EmptyCard = styled(Card)<{ emptySize?: CardPropsType["emptySize"] }>` +const EmptyCard = styled(Card)<{ emptySize?: CardProps["emptySize"] }>` display: flex; align-items: center; justify-content: center; @@ -47,7 +47,7 @@ const EmptyCard = styled(Card)<{ emptySize?: CardPropsType["emptySize"] }>` background: var(--color-bg-neutral-lighter); `; -const LoadingCard = styled(Card)<{ loadingSize?: CardPropsType["loadingSize"] }>` +const LoadingCard = styled(Card)<{ loadingSize?: CardProps["loadingSize"] }>` display: flex; align-items: center; justify-content: center; @@ -60,7 +60,7 @@ const CardLink = styled(Card.withComponent("a"))` text-decoration: none; `; -const ImageContainer = styled.div<{ image: CardPropsType["image"]; isLoading?: CardPropsType["isLoading"] }>` +const ImageContainer = styled.div<{ image: CardProps["image"]; isLoading?: CardProps["isLoading"] }>` display: flex; align-items: center; justify-content: center; @@ -114,7 +114,7 @@ const DxcCard = ({ selected, size = { width: "fitContent", height: "fitContent" }, tabIndex = 0, -}: CardPropsType) => { +}: CardProps) => { const isInteractive = !!(onClick || onSelectionChange) || selectable; const [internalSelected, setInternalSelected] = useState( selected !== undefined ? selected : defaultSelected || false diff --git a/packages/lib/src/card/types.ts b/packages/lib/src/card/types.ts index 4766177dda..21977162c0 100644 --- a/packages/lib/src/card/types.ts +++ b/packages/lib/src/card/types.ts @@ -6,7 +6,7 @@ type Size = { height?: "fillParent" | "fitContent"; }; -type Props = { +export type CardProps = { /** * Custom content that will be placed inside the component. */ @@ -98,4 +98,4 @@ type Props = { tabIndex?: number; }; -export default Props; +export type { CardProps as default }; diff --git a/packages/lib/src/card/utils.ts b/packages/lib/src/card/utils.ts index 20c84aa68f..868c3f1a58 100644 --- a/packages/lib/src/card/utils.ts +++ b/packages/lib/src/card/utils.ts @@ -1,14 +1,14 @@ -import CardPropsType from "./types"; +import { CardProps } from "./types"; -const calculateSize = (size?: CardPropsType["size"]) => { +const calculateSize = (size?: CardProps["size"]) => { return `width: ${size?.width === "fillParent" ? "100%" : "fit-content"}; height: ${size?.height === "fillParent" ? "100%" : "fit-content"};`; }; export const getCardStyles = ( - mode: CardPropsType["mode"], + mode: CardProps["mode"], interactive: boolean, selected?: boolean, - size?: CardPropsType["size"] + size?: CardProps["size"] ) => { let hover = ""; let focus = ""; @@ -81,8 +81,8 @@ export const getSelectableWrapperStyles = (selected: boolean) => { export const handleEvent = ( event: React.KeyboardEvent | React.MouseEvent, - onClick?: CardPropsType["onClick"], - onSelectionChange?: CardPropsType["onSelectionChange"], + onClick?: CardProps["onClick"], + onSelectionChange?: CardProps["onSelectionChange"], internalSelected?: boolean, setInternalSelected?: React.Dispatch<React.SetStateAction<boolean>>, selected?: boolean, diff --git a/packages/lib/src/checkbox/Checkbox.tsx b/packages/lib/src/checkbox/Checkbox.tsx index 4a0cfc3f50..5031b964aa 100644 --- a/packages/lib/src/checkbox/Checkbox.tsx +++ b/packages/lib/src/checkbox/Checkbox.tsx @@ -1,12 +1,12 @@ import { use, useState, useRef, useId, KeyboardEvent } from "react"; import styled from "@emotion/styled"; import { HalstackLanguageContext } from "../HalstackContext"; -import CheckboxPropsType from "./types"; +import { CheckboxProps } from "./types"; import { calculateWidth, icons, spaces } from "./utils"; import CheckboxContext from "./CheckboxContext"; const Label = styled.span<{ - disabled: CheckboxPropsType["disabled"]; + disabled: CheckboxProps["disabled"]; }>` color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-dark)")}; font-family: var(--typography-font-family); @@ -18,8 +18,8 @@ const Label = styled.span<{ `; const Checkbox = styled.span<{ - disabled: CheckboxPropsType["disabled"]; - readOnly: CheckboxPropsType["readOnly"]; + disabled: CheckboxProps["disabled"]; + readOnly: CheckboxProps["readOnly"]; }>` display: flex; border-radius: var(--border-radius-s); @@ -38,11 +38,11 @@ const Checkbox = styled.span<{ `; const CheckboxContainer = styled.div<{ - disabled: CheckboxPropsType["disabled"]; - labelPosition: CheckboxPropsType["labelPosition"]; - margin: CheckboxPropsType["margin"]; - readOnly: CheckboxPropsType["readOnly"]; - size: CheckboxPropsType["size"]; + disabled: CheckboxProps["disabled"]; + labelPosition: CheckboxProps["labelPosition"]; + margin: CheckboxProps["margin"]; + readOnly: CheckboxProps["readOnly"]; + size: CheckboxProps["size"]; }>` display: flex; align-items: center; @@ -86,7 +86,7 @@ const DxcCheckbox = ({ size = "fitContent", tabIndex = 0, value, -}: CheckboxPropsType) => { +}: CheckboxProps) => { const labelId = `label-checkbox-${useId()}`; const [innerChecked, setInnerChecked] = useState(defaultChecked); const checkboxRef = useRef<HTMLSpanElement | null>(null); diff --git a/packages/lib/src/checkbox/types.ts b/packages/lib/src/checkbox/types.ts index dbcaa461a0..fb3f1808aa 100644 --- a/packages/lib/src/checkbox/types.ts +++ b/packages/lib/src/checkbox/types.ts @@ -1,11 +1,11 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; /** * Reference to the component. */ export type RefType = HTMLDivElement; -type Props = { +export type CheckboxProps = { /** * Specifies a string to be used as the name for the checkbox element when no `label` is provided. */ @@ -78,4 +78,4 @@ export type CheckboxContextProps = { partial: boolean; }; -export default Props; +export type { CheckboxProps as default }; diff --git a/packages/lib/src/chip/Chip.tsx b/packages/lib/src/chip/Chip.tsx index ded48e62f8..27684c1198 100644 --- a/packages/lib/src/chip/Chip.tsx +++ b/packages/lib/src/chip/Chip.tsx @@ -1,16 +1,16 @@ import styled from "@emotion/styled"; import DxcIcon from "../icon/Icon"; -import ChipPropsType, { ChipAvatarType } from "./types"; +import { ChipProps, ChipAvatarType } from "./types"; import DxcActionIcon from "../action-icon/ActionIcon"; import DxcAvatar from "../avatar/Avatar"; import { isValidElement, ReactNode, useState } from "react"; -import { SVG } from "../common/utils"; +import { SVG } from "../common/types"; import { getChipStyles } from "./utils"; const Chip = styled.div<{ - disabled: ChipPropsType["disabled"]; - mode: ChipPropsType["mode"]; - selected: ChipPropsType["selected"]; + disabled: ChipProps["disabled"]; + mode: ChipProps["mode"]; + selected: ChipProps["selected"]; isAvatar?: boolean; type?: string; }>` @@ -32,7 +32,7 @@ const Chip = styled.div<{ ${({ mode, selected }) => getChipStyles(mode, selected)} `; -const ContentWrapper = styled.div<{ mode: ChipPropsType["mode"] }>` +const ContentWrapper = styled.div<{ mode: ChipProps["mode"] }>` max-width: ${({ mode }) => (mode === "dismissible" ? "calc(100% - var(--spacing-gap-xxs) - 24px)" : "100%")}; display: inline-flex; align-items: center; @@ -96,7 +96,7 @@ const DxcChip = ({ selected, tabIndex = 0, ref, -}: ChipPropsType) => { +}: ChipProps) => { const [innerSelected, setInnerSelected] = useState(false); if (mode === "selectable" && isAvatarType(prefix) && !label) { diff --git a/packages/lib/src/chip/types.ts b/packages/lib/src/chip/types.ts index 4cdf0c9a0b..e70ade4de2 100644 --- a/packages/lib/src/chip/types.ts +++ b/packages/lib/src/chip/types.ts @@ -1,4 +1,4 @@ -import { SVG } from "../common/utils"; +import { PrettifyTypes, SVG } from "../common/types"; import AvatarProps from "../avatar/types"; export type ChipAvatarType = { @@ -23,67 +23,71 @@ type CommonProps = { tabIndex?: number; }; -type SelectableChipProps = CommonProps & { - /** - * If true, the component will be disabled. - */ - disabled?: boolean; - /** - * The whole chip is an interactive element that allows users to activate or clear options directly within the interface. - */ - mode?: "selectable"; - /** - * If true, the component will be selected. This property is only applicable when the mode is "selectable". - * If undefined, the component manages its own internal state (uncontrolled mode). - */ - selected?: boolean; -} & ( - | { - /** - * Element, path or avatar used as icon to be placed before the chip label. - */ - prefix: ChipAvatarType; - /** - * Text to be placed on the chip. Required when using an avatar prefix. - */ - label: string; - } - | { - /** - * Element or path used as icon to be placed before the chip label. - */ - prefix: string | SVG; - /** - * Text to be placed on the chip. Optional when using an icon prefix. - */ - label?: string; - } - | { - prefix?: undefined; - /** - * Text to be placed on the chip. - */ - label: string; - } - ); +type SelectableChipProps = PrettifyTypes< + CommonProps & { + /** + * If true, the component will be disabled. + */ + disabled?: boolean; + /** + * The whole chip is an interactive element that allows users to activate or clear options directly within the interface. + */ + mode?: "selectable"; + /** + * If true, the component will be selected. This property is only applicable when the mode is "selectable". + * If undefined, the component manages its own internal state (uncontrolled mode). + */ + selected?: boolean; + } & ( + | { + /** + * Element, path or avatar used as icon to be placed before the chip label. + */ + prefix: ChipAvatarType; + /** + * Text to be placed on the chip. Required when using an avatar prefix. + */ + label: string; + } + | { + /** + * Element or path used as icon to be placed before the chip label. + */ + prefix: string | SVG; + /** + * Text to be placed on the chip. Optional when using an icon prefix. + */ + label?: string; + } + | { + prefix?: undefined; + /** + * Text to be placed on the chip. + */ + label: string; + } + ) +>; -type DismissibleChipProps = CommonProps & { - /** - * Dismissible chip is used to represent information generated by user input within an interface. - */ - mode: "dismissible"; - /** - * Text to be placed on the chip. - */ - label: string; - /** - * Element, path or avatar used as icon to be placed before the chip label. - */ - prefix?: string | SVG | ChipAvatarType; - selected?: never; - disabled?: never; -}; +type DismissibleChipProps = PrettifyTypes< + CommonProps & { + /** + * Dismissible chip is used to represent information generated by user input within an interface. + */ + mode: "dismissible"; + /** + * Text to be placed on the chip. + */ + label: string; + /** + * Element, path or avatar used as icon to be placed before the chip label. + */ + prefix?: string | SVG | ChipAvatarType; + selected?: never; + disabled?: never; + } +>; -type Props = SelectableChipProps | DismissibleChipProps; +export type ChipProps = PrettifyTypes<SelectableChipProps | DismissibleChipProps>; -export default Props; +export type { ChipProps as default }; diff --git a/packages/lib/src/common/types.ts b/packages/lib/src/common/types.ts new file mode 100644 index 0000000000..4b56377f5b --- /dev/null +++ b/packages/lib/src/common/types.ts @@ -0,0 +1,22 @@ +import React from "react"; + +export type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge"; +export type Margin = { + top?: Space; + bottom?: Space; + left?: Space; + right?: Space; +}; +export type SVG = React.ReactNode & React.SVGProps<SVGSVGElement>; +export type Side = keyof Margin; + +export type Size = "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge"; +export type Shape = "circle" | "square"; +export type Color = "primary" | "secondary" | "tertiary" | "success" | "info" | "neutral" | "warning" | "error"; + +/** + * Utility type to make complex types more readable in TypeScript. + */ +export type PrettifyTypes<T> = { + [K in keyof T]: T[K]; +} & {}; diff --git a/packages/lib/src/common/utils.ts b/packages/lib/src/common/utils.ts index 13ececd8f1..04230e5c67 100644 --- a/packages/lib/src/common/utils.ts +++ b/packages/lib/src/common/utils.ts @@ -1,15 +1,5 @@ -import { ReactNode, SVGProps } from "react"; import { spaces } from "./variables"; - -export type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge"; -export type Margin = { - top?: Space; - bottom?: Space; - left?: Space; - right?: Space; -}; -export type SVG = ReactNode & SVGProps<SVGSVGElement>; -export type Side = keyof Margin; +import { Space, Margin, Side } from "./types"; export const getMargin = (marginProp: Space | Margin | undefined, side: Side) => marginProp && typeof marginProp === "object" diff --git a/packages/lib/src/container/Container.tsx b/packages/lib/src/container/Container.tsx index 52ff9cf1b1..0fb1103a41 100644 --- a/packages/lib/src/container/Container.tsx +++ b/packages/lib/src/container/Container.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import ContainerPropsType, { BorderProperties, StyledProps } from "./types"; +import { BorderProperties, StyledProps, ContainerProps } from "./types"; const getBorderStyles = (direction: "top" | "bottom" | "left" | "right", borderProperties: BorderProperties) => `border-${direction}: ${borderProperties.width ?? ""} ${borderProperties.style ?? ""} ${ @@ -82,7 +82,7 @@ const Container = styled.div<StyledProps>` padding-left: ${({ padding }) => (typeof padding === "object" && padding.left ? padding.left : "")}; `; -const DxcContainer = ({ display, width, height, overflow, ref, ...props }: ContainerPropsType) => ( +const DxcContainer = ({ display, width, height, overflow, ref, ...props }: ContainerProps) => ( <Container ref={ref} $display={display} $width={width} $height={height} $overflow={overflow} {...props} /> ); diff --git a/packages/lib/src/container/types.ts b/packages/lib/src/container/types.ts index 36457c0450..847e906620 100644 --- a/packages/lib/src/container/types.ts +++ b/packages/lib/src/container/types.ts @@ -1,20 +1,14 @@ import { ReactNode, Ref } from "react"; +import { PrettifyTypes } from "../common/types"; -type Space = { +export type Spacing = { top?: string; right?: string; bottom?: string; left?: string; }; -type Inset = { - top?: string; - right?: string; - bottom?: string; - left?: string; -}; - -type Background = { +export type Background = { attachment?: string; clip?: string; color?: string; @@ -30,23 +24,26 @@ export type BorderProperties = { style?: string; color?: string; }; -type Border = +export type Border = PrettifyTypes< | BorderProperties | { top?: BorderProperties; right?: BorderProperties; bottom?: BorderProperties; left?: BorderProperties; - }; + } +>; -type Outline = BorderProperties & { - offset?: string; -}; +export type Outline = PrettifyTypes< + BorderProperties & { + offset?: string; + } +>; -type OverflowValues = "visible" | "hidden" | "clip" | "scroll" | "auto"; -type Overflow = OverflowValues | { x?: OverflowValues; y?: OverflowValues }; +export type OverflowValues = "visible" | "hidden" | "clip" | "scroll" | "auto"; +export type Overflow = PrettifyTypes<OverflowValues | { x?: OverflowValues; y?: OverflowValues }>; -type Props = { +export type ContainerProps = { /** * Based on the CSS property background allows configuring all properties related to the background of a container. * @@ -108,11 +105,11 @@ type Props = { * Based on the CSS property inset this prop is a shorthand that corresponds * to the top, right, bottom, and/or left properties. */ - inset?: Inset; + inset?: Spacing; /** * Size of the margin to be applied to the container. */ - margin?: string | Space; + margin?: string | Spacing; /** * Sets the max-width CSS property. * @@ -151,7 +148,7 @@ type Props = { /** * Size of the padding to be applied to the container. */ - padding?: string | Space; + padding?: string | Spacing; /** * Sets the position CSS property. * @@ -172,11 +169,11 @@ type Props = { zIndex?: "auto" | number; }; -export type StyledProps = Omit<Props, "display" | "width" | "height" | "opacity" | "overflow"> & { +export type StyledProps = Omit<ContainerProps, "display" | "width" | "height" | "opacity" | "overflow"> & { $display?: "block" | "inline-block" | "inline" | "none"; $height?: string; $overflow?: Overflow; $width?: string; }; -export default Props; +export type { ContainerProps as default }; diff --git a/packages/lib/src/contextual-menu/ContextualMenu.tsx b/packages/lib/src/contextual-menu/ContextualMenu.tsx index 0ce3a683de..c34e8eef23 100644 --- a/packages/lib/src/contextual-menu/ContextualMenu.tsx +++ b/packages/lib/src/contextual-menu/ContextualMenu.tsx @@ -3,10 +3,11 @@ import styled from "@emotion/styled"; import MenuItem from "../base-menu/MenuItem"; import Section from "../base-menu/Section"; import SubMenu from "../base-menu/SubMenu"; -import ContextualMenuContext from "../base-menu/BaseMenuContext"; -import ContextualMenuPropsType, { GroupItemWithId, ItemWithId, SectionWithId } from "./types"; +import ContextualMenuContext from "./ContextualMenuContext"; +import { ContextualMenuProps } from "./types"; import scrollbarStyles from "../styles/scroll"; import { addIdToItems, isSection } from "../base-menu/utils"; +import { BaseGroupItemWithId, BaseItemWithId, BaseSectionWithId } from "../base-menu/types"; const ContextualMenu = styled.div` box-sizing: border-box; @@ -24,7 +25,7 @@ const ContextualMenu = styled.div` ${scrollbarStyles} `; -export default function DxcContextualMenu({ items }: ContextualMenuPropsType) { +export default function DxcContextualMenu({ items }: ContextualMenuProps) { const [firstUpdate, setFirstUpdate] = useState(true); const [selectedItemId, setSelectedItemId] = useState(-1); const contextualMenuRef = useRef<HTMLDivElement | null>(null); @@ -48,12 +49,12 @@ export default function DxcContextualMenu({ items }: ContextualMenuPropsType) { <ContextualMenu ref={contextualMenuRef}> <ContextualMenuContext value={contextValue}> {itemsWithId[0] && isSection(itemsWithId[0]) ? ( - (itemsWithId as SectionWithId[]).map((item, index) => ( + (itemsWithId as BaseSectionWithId[]).map((item, index) => ( <Section key={`section-${index}`} section={item} index={index} length={itemsWithId.length} /> )) ) : ( <SubMenu> - {(itemsWithId as (GroupItemWithId | ItemWithId)[]).map((item, index) => ( + {(itemsWithId as (BaseGroupItemWithId | BaseItemWithId)[]).map((item, index) => ( <MenuItem item={item} key={`${item.label}-${index}`} /> ))} </SubMenu> diff --git a/packages/lib/src/contextual-menu/types.ts b/packages/lib/src/contextual-menu/types.ts index 194c79aaed..2bd21d1dcc 100644 --- a/packages/lib/src/contextual-menu/types.ts +++ b/packages/lib/src/contextual-menu/types.ts @@ -1,37 +1,9 @@ -import BaseProps, { - BaseMenuContextProps, - GroupItem, - GroupItemProps, - GroupItemWithId, - Item as BaseItem, - ItemActionProps as BaseItemActionProps, - ItemWithId, - SubMenuProps, - MenuItemProps, - Section, - SectionWithId, - SectionProps, - SingleItemProps, -} from "../base-menu/types"; +import BaseProps, { BaseMenuContextProps } from "../base-menu/types"; -type Item = Omit<BaseItem, "href" | "renderItem" | "selected">; -type Props = Omit<BaseProps, "displayBorder" | "displayGroupLines" | "displayControlsAfter" | "hasPopOver">; -type ItemActionProps = Omit<BaseItemActionProps, "href" | "renderItem">; +type ContextualMenuProps = Omit< + BaseProps, + "displayBorder" | "displayGroupLines" | "displayControlsAfter" | "hasPopOver" +>; type ContextualMenuContextProps = Omit<BaseMenuContextProps, "hasPopOver">; -export type { - ContextualMenuContextProps, - GroupItem, - GroupItemProps, - GroupItemWithId, - Item, - ItemActionProps, - ItemWithId, - SubMenuProps, - MenuItemProps, - Section, - SectionWithId, - SectionProps, - SingleItemProps, - Props as default, -}; +export type { ContextualMenuProps, ContextualMenuContextProps, ContextualMenuProps as default }; diff --git a/packages/lib/src/data-grid/DataGrid.tsx b/packages/lib/src/data-grid/DataGrid.tsx index fb8e747f76..74c5244921 100644 --- a/packages/lib/src/data-grid/DataGrid.tsx +++ b/packages/lib/src/data-grid/DataGrid.tsx @@ -1,7 +1,7 @@ import { JSX, useEffect, useMemo, useState } from "react"; import { DataGrid, SortColumn } from "react-data-grid"; import styled from "@emotion/styled"; -import DataGridPropsType, { HierarchyGridRow, GridRow, ExpandableGridRow } from "./types"; +import type { DataGridProps, DataGridHierarchyRow, DataGridRow, DataGridExpandableRow } from "./types"; import "react-data-grid/lib/styles.css"; import { convertToRDGColumns, @@ -177,8 +177,10 @@ const DxcDataGrid = ({ onPageChange, totalItems, defaultPage = 1, -}: DataGridPropsType): JSX.Element => { - const [rowsToRender, setRowsToRender] = useState<GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]>([...rows]); +}: DataGridProps): JSX.Element => { + const [rowsToRender, setRowsToRender] = useState<DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]>([ + ...rows, + ]); const [page, changePage] = useState(defaultPage); const [colHeight, setColHeight] = useState(36); const [loadingChildren, setLoadingChildren] = useState<(string | number)[]>([]); @@ -232,11 +234,8 @@ const DxcDataGrid = ({ ...expectedColumns, ]; } - const rowHasHierarchy = (row: GridRow | HierarchyGridRow): row is HierarchyGridRow => { - return ( - (Array.isArray(row.childRows) && row.childRows?.length > 0) || - typeof (row as HierarchyGridRow)?.childrenTrigger === "function" - ); + const rowHasHierarchy = (row: DataGridRow | DataGridHierarchyRow): row is DataGridHierarchyRow => { + return (Array.isArray(row.childRows) && row.childRows?.length > 0) || typeof row?.childrenTrigger === "function"; }; if (!expandable && rows.some((row) => rowHasHierarchy(row)) && uniqueRowId) { // only the first column will be clickable and will expand the rows @@ -366,14 +365,14 @@ const DxcDataGrid = ({ }); }; - const onRowsChange = (newRows: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]) => { + const onRowsChange = (newRows: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]) => { // call function to change rows, like when they have been edited if (typeof onGridRowsChange === "function") { onGridRowsChange(newRows); } }; - const sortedRows = useMemo((): readonly GridRow[] | HierarchyGridRow[] | ExpandableGridRow[] => { + const sortedRows = useMemo((): readonly DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[] => { const sortFunctions = getCustomSortFn(columns); if (!onSort) { if (sortColumns.length > 0 && uniqueRowId) { diff --git a/packages/lib/src/data-grid/types.ts b/packages/lib/src/data-grid/types.ts index 1a750971a9..013e8d3be9 100644 --- a/packages/lib/src/data-grid/types.ts +++ b/packages/lib/src/data-grid/types.ts @@ -1,7 +1,8 @@ import { ReactNode } from "react"; import { SortColumn } from "react-data-grid"; +import { PrettifyTypes } from "../common/types"; -export type GridColumn = { +type DataGridColumn = { /** * Key that will be rendered from each row in rows. */ @@ -40,67 +41,71 @@ export type GridColumn = { alignment?: "left" | "right" | "center"; }; -export type GridRow = { +type DataGridRow = { /** * List of rows that will be rendered in each cell based on the key in each column. */ [key: string]: ReactNode | undefined; }; -export type HierarchyGridRow = GridRow & { - /** - * Array of child rows nested under this row, enabling hierarchical (tree-like) structures. - * These child rows will be displayed when the parent row is expanded. - */ - childRows?: HierarchyGridRow[] | GridRow[]; - /** - * Function called when a row with children is expanded or collapsed (based on the value of `open`). - * Returns (or resolves to) the array of child rows nested under this row to display when expanded. - */ - childrenTrigger?: ( - open?: boolean, - triggerRow?: HierarchyGridRow - ) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]>; - /** - * Indicates whether child rows are currently being loaded. - */ - loadingChildren?: boolean; - /** - * Indicates the level of nesting for this row in the hierarchy. - */ - rowLevel?: number; - /** - * Reference to the parent row's unique identifier. - */ - parentKey?: string | number; - /** - * Indicates whether child rows are currently visible. - */ - visibleChildren?: boolean; -}; +type DataGridHierarchyRow = PrettifyTypes< + DataGridRow & { + /** + * Array of child rows nested under this row, enabling hierarchical (tree-like) structures. + * These child rows will be displayed when the parent row is expanded. + */ + childRows?: DataGridHierarchyRow[] | DataGridRow[]; + /** + * Function called when a row with children is expanded or collapsed (based on the value of `open`). + * Returns (or resolves to) the array of child rows nested under this row to display when expanded. + */ + childrenTrigger?: ( + open?: boolean, + triggerRow?: DataGridHierarchyRow + ) => (DataGridHierarchyRow[] | DataGridRow[]) | Promise<DataGridHierarchyRow[] | DataGridRow[]>; + /** + * Indicates whether child rows are currently being loaded. + */ + loadingChildren?: boolean; + /** + * Indicates the level of nesting for this row in the hierarchy. + */ + rowLevel?: number; + /** + * Reference to the parent row's unique identifier. + */ + parentKey?: string | number; + /** + * Indicates whether child rows are currently visible. + */ + visibleChildren?: boolean; + } +>; -export type ExpandableGridRow = GridRow & { - expandedContent?: ReactNode; - expandedContentHeight?: number; - contentIsExpanded?: boolean; -}; +type DataGridExpandableRow = PrettifyTypes< + DataGridRow & { + expandedContent?: ReactNode; + expandedContentHeight?: number; + contentIsExpanded?: boolean; + } +>; -export type ExpandableRows = { - rows: ExpandableGridRow[]; +type DataGridExpandableRows = { + rows: DataGridExpandableRow[]; /** * Whether the rows can expand or not. */ expandable: true; /** - * This prop indicates the unique key that can be used to identify each row. This prop is mandatory if selectable is set to true, expandable is set to true or rows is of type HierarchyGridRow[]. + * This prop indicates the unique key that can be used to identify each row. This prop is mandatory if selectable is set to true, expandable is set to true or rows is of type DataGridHierarchyRow[]. */ uniqueRowId: string; }; -export type HierarchyRows = { - rows: HierarchyGridRow[]; +type DataGridHierarchyRows = { + rows: DataGridHierarchyRow[]; /** - * This prop indicates the unique key that can be used to identify each row. This prop is mandatory if selectable is set to true, expandable is set to true or rows is of type HierarchyGridRow[]. + * This prop indicates the unique key that can be used to identify each row. This prop is mandatory if selectable is set to true, expandable is set to true or rows is of type DataGridHierarchyRow[]. */ uniqueRowId: string; /** @@ -109,7 +114,7 @@ export type HierarchyRows = { expandable?: false; }; -export type SelectableGridProps = +type DataGridSelectableProps = | { /** * Whether the rows are selectable or not. @@ -124,7 +129,7 @@ export type SelectableGridProps = */ onSelectRows: (selectedRows: Set<number | string>) => void; /** - * This prop indicates the unique key that can be used to identify each row. This prop is mandatory if selectable is set to true, expandable is set to true or rows is of type HierarchyGridRow[]. + * This prop indicates the unique key that can be used to identify each row. This prop is mandatory if selectable is set to true, expandable is set to true or rows is of type DataGridHierarchyRow[]. */ uniqueRowId: string; } @@ -135,7 +140,7 @@ export type SelectableGridProps = uniqueRowId?: string; }; -type PaginatedProps = { +type DataGridPaginatedProps = { /** * If true, paginator will be displayed. */ @@ -171,7 +176,7 @@ type PaginatedProps = { defaultPage?: number; }; -type NonPaginatedProps = { +type DataGridNonPaginatedProps = { /** * If true, paginator will be displayed. */ @@ -207,16 +212,16 @@ type NonPaginatedProps = { defaultPage?: never; }; -export type CommonProps = { - columns: GridColumn[]; +type CommonProps = { + columns: DataGridColumn[]; /** * Extra row that will be always visible. */ - summaryRow?: GridRow; + summaryRow?: DataGridRow; /** * Function called whenever a cell is edited. */ - onGridRowsChange?: (_rows: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]) => void; + onGridRowsChange?: (_rows: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]) => void; /** * Function called whenever a column is sorted. Receives the sorted * column and direction, or `undefined` if no sorting is applied. @@ -224,20 +229,33 @@ export type CommonProps = { onSort?: (_sortColumn?: SortColumn) => void; }; -export type BasicGridProps = { - rows: GridRow[]; +type DataGridBasicProps = { + rows: DataGridRow[]; /** * Whether the rows can expand or not. */ expandable?: false; }; -type Props = CommonProps & - (PaginatedProps | NonPaginatedProps) & - ( - | (BasicGridProps & SelectableGridProps) - | (ExpandableRows & SelectableGridProps) - | (HierarchyRows & SelectableGridProps) - ); +type DataGridProps = PrettifyTypes< + CommonProps & + (DataGridPaginatedProps | DataGridNonPaginatedProps) & + ( + | (DataGridBasicProps & DataGridSelectableProps) + | (DataGridExpandableRows & DataGridSelectableProps) + | (DataGridHierarchyRows & DataGridSelectableProps) + ) +>; -export default Props; +export type { + DataGridColumn, + DataGridRow, + DataGridHierarchyRow, + DataGridExpandableRow, + DataGridExpandableRows, + DataGridHierarchyRows, + DataGridSelectableProps, + DataGridBasicProps, + DataGridProps, + DataGridProps as default, +}; diff --git a/packages/lib/src/data-grid/utils.tsx b/packages/lib/src/data-grid/utils.tsx index be9e1958b8..ff49ab15e5 100644 --- a/packages/lib/src/data-grid/utils.tsx +++ b/packages/lib/src/data-grid/utils.tsx @@ -3,19 +3,22 @@ import { Column, RenderSortStatusProps, SortColumn, renderTextEditor } from "rea import DxcActionIcon from "../action-icon/ActionIcon"; import DxcCheckbox from "../checkbox/Checkbox"; import DxcIcon from "../icon/Icon"; -import { GridColumn, HierarchyGridRow, GridRow, ExpandableGridRow } from "./types"; +import { DataGridColumn, DataGridHierarchyRow, DataGridRow, DataGridExpandableRow } from "./types"; import DxcSpinner from "../spinner/Spinner"; /** * Converts grid columns into react-data-grid column format. - * @param {GridColumn} gridColumn - Object representing the properties of a grid column. - * @param {GridRow} [summaryRow] - Optional summary row to render at the end. - * @returns {Column<GridRow | HierarchyGridRow | ExpandableGridRow, GridRow | HierarchyGridRow | ExpandableGridRow>} Formatted column object for react-data-grid. + * @param {DataGridColumn} gridColumn - Object representing the properties of a grid column. + * @param {DataGridRow} [summaryRow] - Optional summary row to render at the end. + * @returns {Column<DataGridRow | DataGridHierarchyRow | DataGridExpandableRow, DataGridRow | DataGridHierarchyRow | DataGridExpandableRow>} Formatted column object for react-data-grid. */ export const convertToRDGColumns = ( - gridColumn: GridColumn, - summaryRow?: GridRow -): Column<GridRow | HierarchyGridRow | ExpandableGridRow, GridRow | HierarchyGridRow | ExpandableGridRow> => ({ + gridColumn: DataGridColumn, + summaryRow?: DataGridRow +): Column< + DataGridRow | DataGridHierarchyRow | DataGridExpandableRow, + DataGridRow | DataGridHierarchyRow | DataGridExpandableRow +> => ({ key: gridColumn.key, name: gridColumn.label, resizable: gridColumn.resizable, @@ -58,11 +61,11 @@ export const renderSortStatus = ({ sortDirection }: RenderSortStatusProps) => ( /** * Expands a given row by inserting a new child row with the expanded content. - * @param {ExpandableGridRow} row - The row object to expand. - * @param {ExpandableGridRow[]} rows - The current list of all rows (as rendered). + * @param {DataGridExpandableRow} row - The row object to expand. + * @param {DataGridExpandableRow[]} rows - The current list of all rows (as rendered). * @param {string} uniqueRowId - Unique identifier key used for each row. */ -export const expandRow = (row: ExpandableGridRow, rows: ExpandableGridRow[], uniqueRowId: string) => { +export const expandRow = (row: DataGridExpandableRow, rows: DataGridExpandableRow[], uniqueRowId: string) => { const rowIndex = rows.findIndex((r) => r === row); addRow(rows, rowIndex + 1, { isExpandedChildContent: true, @@ -75,10 +78,10 @@ export const expandRow = (row: ExpandableGridRow, rows: ExpandableGridRow[], uni /** * Collapses a given row by removing its expanded child row. - * @param {ExpandableGridRow} row - The row object to collapse. - * @param {ExpandableGridRow[]} rows - The current list of all rows (as rendered). + * @param {DataGridExpandableRow} row - The row object to collapse. + * @param {DataGridExpandableRow[]} rows - The current list of all rows (as rendered). */ -export const collapseRow = (row: ExpandableGridRow, rows: ExpandableGridRow[]) => { +export const collapseRow = (row: DataGridExpandableRow, rows: DataGridExpandableRow[]) => { const rowIndex = rows.findIndex((r) => r === row); const newRows = [...rows]; deleteRow(newRows, rowIndex + 1); @@ -87,17 +90,17 @@ export const collapseRow = (row: ExpandableGridRow, rows: ExpandableGridRow[]) = /** * Renders an expandable trigger icon that toggles row expansion. - * @param {ExpandableGridRow} row - Row object that can be expanded or collapsed. - * @param {ExpandableGridRow[]} rows - List of all rows. + * @param {DataGridExpandableRow} row - Row object that can be expanded or collapsed. + * @param {DataGridExpandableRow[]} rows - List of all rows. * @param {string} uniqueRowId - Unique identifier for each row. * @param {Function} setRowsToRender - Function to update the rows being rendered. * @returns {JSX.Element} Icon with functionality to toggle the expanded content of the row. */ export const renderExpandableTrigger = ( - row: ExpandableGridRow, - rows: ExpandableGridRow[], + row: DataGridExpandableRow, + rows: DataGridExpandableRow[], uniqueRowId: string, - setRowsToRender: (_value: SetStateAction<GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]>) => void + setRowsToRender: (_value: SetStateAction<DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]>) => void ) => ( <DxcActionIcon size="xsmall" @@ -121,22 +124,24 @@ export const renderExpandableTrigger = ( ); /** - * Determines if the given row is a `HierarchyGridRow`. + * Determines if the given row is a `DataGridHierarchyRow`. * - * A `HierarchyGridRow` is identified by having a `childRows` property + * A `DataGridHierarchyRow` is identified by having a `childRows` property * that is an array with at least one element. * - * @param {GridRow} row - The row to check. - * @returns {row is HierarchyGridRow & { childRows: HierarchyGridRow[] | GridRow[] }} - * Returns `true` if the row is a `HierarchyGridRow` with `childRows` defined, otherwise `false`. + * @param {DataGridRow} row - The row to check. + * @returns {row is DataGridHierarchyRow & { childRows: DataGridHierarchyRow[] | DataGridRow[] }} + * Returns `true` if the row is a `DataGridHierarchyRow` with `childRows` defined, otherwise `false`. */ -const isHierarchyGridRow = (row: GridRow): row is HierarchyGridRow & { childRows: HierarchyGridRow[] | GridRow[] } => +const isDataGridHierarchyRow = ( + row: DataGridRow +): row is DataGridHierarchyRow & { childRows: DataGridHierarchyRow[] | DataGridRow[] } => Array.isArray(row.childRows) && row.childRows.length > 0; /** * Renders a trigger for hierarchical row expansion in the grid. - * @param {HierarchyGridRow[]} rows - List of all hierarchy grid rows. - * @param {HierarchyGridRow} triggerRow - Row object with children that can be expanded or collapsed. + * @param {DataGridHierarchyRow[]} rows - List of all hierarchy grid rows. + * @param {DataGridHierarchyRow} triggerRow - Row object with children that can be expanded or collapsed. * @param {string} uniqueRowId - Unique identifier for each row. * @param {string} columnKey - Key of the column that displays the hierarchy trigger. * @param {Function} setRowsToRender - Function to update the rows being rendered. @@ -144,17 +149,17 @@ const isHierarchyGridRow = (row: GridRow): row is HierarchyGridRow & { childRows * @returns {JSX.Element} Button that toggles visibility of child rows. */ export const renderHierarchyTrigger = ( - rows: HierarchyGridRow[], - triggerRow: HierarchyGridRow, + rows: DataGridHierarchyRow[], + triggerRow: DataGridHierarchyRow, uniqueRowId: string, columnKey: string, - setRowsToRender: (_value: SetStateAction<GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]>) => void, + setRowsToRender: (_value: SetStateAction<DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]>) => void, loadingChildren?: (string | number)[], setLoadingChildren?: (_value: SetStateAction<(string | number)[]>) => void, childrenTrigger?: ( _open: boolean, - _selectedRow: HierarchyGridRow - ) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]> + _selectedRow: DataGridHierarchyRow + ) => (DataGridHierarchyRow[] | DataGridRow[]) | Promise<DataGridHierarchyRow[] | DataGridRow[]> ) => { const isLoading = !!loadingChildren?.includes(rowKeyGetter(triggerRow, uniqueRowId)); const expandChildren = async () => { @@ -172,7 +177,7 @@ export const renderHierarchyTrigger = ( const newRowsToRender = [...currentRows]; if (newRowsToRender.some((row) => rowKeyGetter(row, uniqueRowId) === triggerRow[uniqueRowId])) { const rowIndex = currentRows.findIndex((row) => triggerRow === row); - dynamicChildren.forEach((childRow: HierarchyGridRow, index: number) => { + dynamicChildren.forEach((childRow: DataGridHierarchyRow, index: number) => { childRow.rowLevel = triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1; childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId); @@ -193,7 +198,7 @@ export const renderHierarchyTrigger = ( const newRowsToRender = [...currentRows]; const rowIndex = currentRows.findIndex((row) => triggerRow === row); - triggerRow.childRows?.forEach((childRow: HierarchyGridRow, index: number) => { + triggerRow.childRows?.forEach((childRow: DataGridHierarchyRow, index: number) => { childRow.rowLevel = triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1; childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId); @@ -222,7 +227,7 @@ export const renderHierarchyTrigger = ( } else { setRowsToRender((currentRows) => { // The children of the row that is being collapsed are added to an array - const rowsToRemove: HierarchyGridRow[] = rows.filter( + const rowsToRemove: DataGridHierarchyRow[] = rows.filter( (rowToRender) => rowToRender.parentKey && rowToRender.parentKey === rowKeyGetter(triggerRow, uniqueRowId) ); // The children are checked if any of them has any other children of their own @@ -268,16 +273,16 @@ export const renderHierarchyTrigger = ( /** * Renders a checkbox for row selection. - * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rows - Array of rows that are currently displayed. - * @param {GridRow | HierarchyGridRow | ExpandableGridRow} row - Row object to render the checkbox for. + * @param {DataGridRow | DataGridHierarchyRow | DataGridExpandableRow} row - Row object to render the checkbox for. + * @param {GridRow | DataGridHierarchyRow | DataGridExpandableRow} row - Row object to render the checkbox for. * @param {string} uniqueRowId - The key used to uniquely identify each row. * @param {Set<string | number>} selectedRows - Set of selected rows. * @param {Function} onSelectRows - Callback function that triggers when rows are selected/deselected. * @returns {JSX.Element} Checkbox for selecting the row. */ export const renderCheckbox = ( - rows: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[], - row: GridRow | HierarchyGridRow | ExpandableGridRow, + rows: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[], + row: DataGridRow | DataGridHierarchyRow | DataGridExpandableRow, uniqueRowId: string, selectedRows: Set<string | number>, onSelectRows: (_selected: Set<string | number>) => void @@ -301,14 +306,14 @@ export const renderCheckbox = ( /** * Renders a header checkbox that controls the selection of all rows. - * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rows - Array of rows that are currently displayed. + * @param {DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]} rows - Array of rows that are currently displayed. * @param {string} uniqueRowId - The key used to uniquely identify each row. * @param {Set<string | number>} selectedRows - Set of selected rows. * @param {Function} onSelectRows - Callback function that triggers when rows are selected/deselected. * @returns {JSX.Element} Checkbox for the header checkbox. */ export const renderHeaderCheckbox = ( - rows: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[], + rows: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[], uniqueRowId: string, selectedRows: Set<string | number>, onSelectRows: (_selected: Set<string | number>) => void @@ -321,14 +326,14 @@ export const renderHeaderCheckbox = ( if (checked) { rows.forEach((row) => { updatedSelection.add(rowKeyGetter(row, uniqueRowId)); - if (isHierarchyGridRow(row)) { + if (isDataGridHierarchyRow(row)) { getChildrenSelection(row.childRows, uniqueRowId, updatedSelection, checked); } }); } else { rows.forEach((row) => { updatedSelection.delete(rowKeyGetter(row, uniqueRowId)); - if (isHierarchyGridRow(row)) { + if (isDataGridHierarchyRow(row)) { getChildrenSelection(row.childRows, uniqueRowId, updatedSelection, checked); } }); @@ -342,21 +347,21 @@ export const renderHeaderCheckbox = ( /** * Retrieves the unique key for a row based on the given uniqueRowId. - * @param {GridRow | HierarchyGridRow | ExpandableGridRow} row - The row object from which to retrieve the key. + * @param {DataGridRow | DataGridHierarchyRow | DataGridExpandableRow} row - The row object from which to retrieve the key. * @param {string} uniqueRowId - The unique key used to identify the row. * @returns {string | number} The unique key of the row. */ -export const rowKeyGetter = (row: GridRow | HierarchyGridRow | ExpandableGridRow, uniqueRowId: string) => { +export const rowKeyGetter = (row: DataGridRow | DataGridHierarchyRow | DataGridExpandableRow, uniqueRowId: string) => { const keyValue = row[uniqueRowId]; return typeof keyValue === "string" || typeof keyValue === "number" ? keyValue : ""; }; /** * Extracts and returns custom sorting functions from the given columns. - * @param {GridColumn[]} columns - Array of column definitions. + * @param {DataGridColumn[]} columns - Array of column definitions. * @returns {object[]} Array of objects, each containing a column key and its custom sort function. */ -export const getCustomSortFn = (columns: GridColumn[]) => { +export const getCustomSortFn = (columns: DataGridColumn[]) => { const customSortFunctions = [...columns] .filter((column) => column.sortFn) .map((column) => ({ column: column.key, sortFn: column.sortFn! })); @@ -383,14 +388,14 @@ export const compareRows = (rowA: ReactNode, rowB: ReactNode, sortFn?: (_a: Reac /** * Sorts an array of rows based on the specified sort columns and custom sort functions. - * @param {GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]} rows - Array of rows to be sorted. + * @param {DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]} rows - Array of rows to be sorted. * @param {SortColumn[]} sortColumns - Array of sort column definitions. * @param {Function[]} sortFunctions - Array of objects, each containing a column and its custom sort function. * @param {boolean} reversed - Boolean indicating whether the sort order should be reversed. - * @returns {GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]} The sorted array of rows. + * @returns {DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]} The sorted array of rows. */ export const sortRows = ( - rows: GridRow[] | ExpandableGridRow[] | HierarchyGridRow[], + rows: DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[], sortColumns: readonly SortColumn[], sortFunctions?: { column: string; sortFn: (_a: ReactNode, _b: ReactNode) => number }[], reversed?: boolean @@ -425,14 +430,14 @@ export const sortRows = ( /** * Sorts an array of rows, ensuring child rows are placed under their parents. - * @param {HierarchyGridRow[]} rows - Array of rows to be sorted. + * @param {DataGridHierarchyRow[]} rows - Array of rows to be sorted. * @param {SortColumn[]} sortColumns - Array of sort column definitions. * @param {object[]} sortFunctions - Array of custom sort functions for specific columns. * @param {string} uniqueRowId - Unique key used to identify rows. - * @returns {GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]} The sorted array of rows, with children positioned under their parents. + * @returns {DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]} The sorted array of rows, with children positioned under their parents. */ export const sortHierarchyRows = ( - rows: HierarchyGridRow[], + rows: DataGridHierarchyRow[], sortColumns: readonly SortColumn[], sortFunctions: { column: string; sortFn: (_a: ReactNode, _b: ReactNode) => number }[], uniqueRowId: string @@ -457,8 +462,8 @@ export const sortHierarchyRows = ( if (uniqueRowId && sortedChildren.some((row) => uniqueRowId in row)) { sortedChildren = sortedChildren.reduce( ( - remainingChilds: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[], - child: GridRow | HierarchyGridRow | ExpandableGridRow + remainingChilds: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[], + child: DataGridRow | DataGridHierarchyRow | DataGridExpandableRow ) => { const parentIndex = parentsSorted.findIndex( (parent) => rowKeyGetter(parent, uniqueRowId) === child.parentKey @@ -479,39 +484,39 @@ export const sortHierarchyRows = ( /** * Inserts a new row into the row list at the specified index. - * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rowList - Array of rows to insert the new row into. + * @param {DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]} rowList - Array of rows to insert the new row into. * @param {number} index - Index where the new row should be added. - * @param {GridRow | HierarchyGridRow | ExpandableGridRow} row - The row to be added. + * @param {GridRow | DataGridHierarchyRow | DataGridExpandableRow} row - The row to be added. */ export const addRow = ( - rowList: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[], + rowList: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[], index: number, - row: GridRow | HierarchyGridRow | ExpandableGridRow + row: DataGridRow | DataGridHierarchyRow | DataGridExpandableRow ) => { rowList.splice(index, 0, row); }; /** * Deletes a row from the specified index of a list of rows. - * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rowList - Array rows from which to delete a row. + * @param {DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]} rowList - Array rows from which to delete a row. * @param {number} index - Index where the row should be deleted. */ -export const deleteRow = (rowList: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[], index: number) => { +export const deleteRow = (rowList: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[], index: number) => { rowList.splice(index, 1); }; /** - * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rowList List of rows in which to look for the row, it will also look for the row in the childRows + * @param {DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]} rowList List of rows in which to look for the row, it will also look for the row in the childRows * @param {string} uniqueRowId The key that contains the unique value of the row * @param {ReactNode} uniqueRowIdValue Unique value to identify the row - * @returns {GridRow | HierarchyGridRow | ExpandableGridRow | undefined} A copy of the Row or undefined if not found + * @returns {GridRow | DataGridHierarchyRow | DataGridExpandableRow | undefined} A copy of the Row or undefined if not found */ export const rowFinderBasedOnId = ( - rowList: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[], + rowList: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[], uniqueRowId: string, uniqueRowIdValue: ReactNode -): GridRow | HierarchyGridRow | ExpandableGridRow | undefined => { - let foundRow: GridRow | HierarchyGridRow | ExpandableGridRow | undefined; +): DataGridRow | DataGridHierarchyRow | DataGridExpandableRow | undefined => { + let foundRow: DataGridRow | DataGridHierarchyRow | DataGridExpandableRow | undefined; rowList.forEach((row) => { if (rowKeyGetter(row, uniqueRowId) === uniqueRowIdValue) { foundRow = { ...row }; @@ -527,21 +532,21 @@ export const rowFinderBasedOnId = ( /** * Recursively selects or deselects children rows based on the checked state. - * @param {GridRow[] | HierarchyGridRow[]} rowList - List of child rows that need to be checked/unchecked. + * @param {DataGridRow[] | DataGridHierarchyRow[]} rowList - List of child rows that need to be checked/unchecked. * @param {string} uniqueRowId - Key used to uniquely identify each row. * @param {Set<string | number>} selectedRows - Set of selected rows. * @param {boolean} checked - Boolean indicating whether the rows should be selected (true) or deselected (false). * @param {boolean} expandingChildren - Defines children are being expanded or not, used to avoid removing children that were previously set when expanding an unset parent */ const getChildrenSelection = ( - rowList: GridRow[] | HierarchyGridRow[], + rowList: DataGridRow[] | DataGridHierarchyRow[], uniqueRowId: string, selectedRows: Set<string | number>, checked: boolean, hierarchyValidation?: boolean ) => { rowList.forEach((row) => { - if (isHierarchyGridRow(row)) { + if (isDataGridHierarchyRow(row)) { // Recursively select/deselect child rows getChildrenSelection(row.childRows, uniqueRowId, selectedRows, checked, hierarchyValidation); } @@ -557,7 +562,7 @@ const getChildrenSelection = ( /** * Check if the parent and its parent should be selected/unselected - * @param {HierarchyGridRow[]} rowList + * @param {DataGridHierarchyRow[]} rowList * @param {ReactNode} uniqueRowKeyValue Unique value of the selected row * @param {ReactNode} parentKeyValue Unique value of the parent Row * @param {string} uniqueRowId Key where the unique value is located @@ -565,7 +570,7 @@ const getChildrenSelection = ( * @param {boolean} checkedStateToMatch */ const getParentSelectedState = ( - rowList: HierarchyGridRow[], + rowList: DataGridHierarchyRow[], parentKeyValue: ReactNode, uniqueRowId: string, selectedRows: Set<string | number>, @@ -574,9 +579,9 @@ const getParentSelectedState = ( if (!rowList.some((row) => uniqueRowId in row)) { return; } - const parentRow = rowFinderBasedOnId(rowList, uniqueRowId, parentKeyValue) as HierarchyGridRow; + const parentRow = rowFinderBasedOnId(rowList, uniqueRowId, parentKeyValue) as DataGridHierarchyRow; - if (!parentRow || !isHierarchyGridRow(parentRow)) { + if (!parentRow || !isDataGridHierarchyRow(parentRow)) { return; } @@ -601,8 +606,8 @@ const getParentSelectedState = ( /** * Updates the rows when the checkbox state changes - * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rows - Array of rows that are currently displayed. - * @param {GridRow | HierarchyGridRow | ExpandableGridRow} row - Row object to render the checkbox for. + * @param {DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[]} rows - Array of rows that are currently displayed. + * @param {GridRow | DataGridHierarchyRow | DataGridExpandableRow} row - Row object to render the checkbox for. * @param {string} uniqueRowId - Unique identifier for each row. * @param {string} columnKey - Key of the column that displays the hierarchy trigger. * @param {Set<string | number>} selectedRows - Set of selected rows. @@ -611,8 +616,8 @@ const getParentSelectedState = ( * @returns {JSX.Element} Button that toggles visibility of child rows. */ const handleCheckboxUpdate = ( - rows: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[], - row: GridRow | HierarchyGridRow | ExpandableGridRow, + rows: DataGridRow[] | DataGridHierarchyRow[] | DataGridExpandableRow[], + row: DataGridRow | DataGridHierarchyRow | DataGridExpandableRow, uniqueRowId: string, selectedRows: Set<string | number>, checked: boolean, @@ -648,35 +653,35 @@ export const getMinItemsPerPageIndex = (currentPageInternal: number, itemsPerPag * Returns the ending index for paginated items on a specific page. * @param {number} minItemsPerPageIndex - The starting index of items for the current page. * @param {number} itemsPerPage - Number of items per page. - * @param {GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]} rows - List of all rows to paginate. + * @param {DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]} rows - List of all rows to paginate. * @param {number} page - Target page number. * @returns {number} The ending index of items for the given page. */ export const getMaxItemsPerPageIndex = ( minItemsPerPageIndex: number, itemsPerPage: number, - rows: GridRow[] | ExpandableGridRow[] | HierarchyGridRow[], + rows: DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[], page: number ) => (minItemsPerPageIndex + itemsPerPage > rows.length ? rows.length : itemsPerPage * page - 1); /** * Filters and returns paginated rows along with their children rows if applicable. - * @param {GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]} rows - All rows from which to select the paginated ones. + * @param {DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]} rows - All rows from which to select the paginated ones. * @param {string} uniqueRowId - The key used to uniquely identify each row. * @param {number} start - The starting index for pagination. * @param {number} end - The ending index for pagination. - * @returns {GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]} List of rows that should be rendered in the current pagination view, including child rows. + * @returns {DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[]} List of rows that should be rendered in the current pagination view, including child rows. */ export const getPaginatedNodes = ( - rows: readonly GridRow[] | ExpandableGridRow[] | HierarchyGridRow[], + rows: readonly DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[], uniqueRowId?: string, start?: number, end?: number -): readonly GridRow[] | ExpandableGridRow[] | HierarchyGridRow[] => { +): readonly DataGridRow[] | DataGridExpandableRow[] | DataGridHierarchyRow[] => { if (!uniqueRowId) { return rows.slice(start, end); } - const rowsToPaginate: HierarchyGridRow[] = + const rowsToPaginate: DataGridHierarchyRow[] = start != null && end != null ? rows .filter(({ parentKey, isExpandedChildContent }) => parentKey == null && isExpandedChildContent == null) @@ -684,7 +689,7 @@ export const getPaginatedNodes = ( : [...rows]; // Recursive function to check childRows at any depth - const isRowInHierarchy = (row: HierarchyGridRow, targetId: ReactNode): boolean => { + const isRowInHierarchy = (row: DataGridHierarchyRow, targetId: ReactNode): boolean => { if (row[uniqueRowId] === targetId) { return true; } @@ -696,10 +701,10 @@ export const getPaginatedNodes = ( rowsToPaginate.some( (rowToPaginate) => rowToPaginate[uniqueRowId] === row[uniqueRowId] || - (rowToPaginate.contentIsExpanded && + (rowToPaginate.contentIsExpanded === true && row?.triggerRowKey === rowToPaginate[uniqueRowId] && - row?.isExpandedChildContent) || - rowToPaginate?.childRows?.some((child) => isRowInHierarchy(child, row[uniqueRowId])) + row?.isExpandedChildContent === true) || + rowToPaginate.childRows?.some((child) => isRowInHierarchy(child, row[uniqueRowId])) ) ); }; @@ -714,4 +719,4 @@ export const getPaginatedNodes = ( * @returns {boolean} - Returns `true` if `key` is a valid key of `obj`, otherwise `false`. * */ -export const isKeyOfRow = <T extends GridRow>(key: string, obj: T): key is Extract<keyof T, string> => key in obj; +export const isKeyOfRow = <T extends DataGridRow>(key: string, obj: T): key is Extract<keyof T, string> => key in obj; diff --git a/packages/lib/src/date-input/DateInput.tsx b/packages/lib/src/date-input/DateInput.tsx index f471256993..b5bd0ca020 100644 --- a/packages/lib/src/date-input/DateInput.tsx +++ b/packages/lib/src/date-input/DateInput.tsx @@ -3,7 +3,7 @@ import dayjs, { Dayjs } from "dayjs"; import styled from "@emotion/styled"; import customParseFormat from "dayjs/plugin/customParseFormat"; import { HalstackLanguageContext } from "../HalstackContext"; -import DateInputPropsType from "./types"; +import { DateInputProps } from "./types"; import DatePicker from "./DatePicker"; import { getMargin } from "../common/utils"; import { spaces } from "../common/variables"; @@ -22,12 +22,12 @@ const sizes = { fillParent: "100%", }; -const calculateWidth = (margin: DateInputPropsType["margin"], size: DateInputPropsType["size"]) => +const calculateWidth = (margin: DateInputProps["margin"], size: DateInputProps["size"]) => size === "fillParent" ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` : size && sizes[size]; -const DateInputContainer = styled.div<{ margin: DateInputPropsType["margin"]; size: DateInputPropsType["size"] }>` +const DateInputContainer = styled.div<{ margin: DateInputProps["margin"]; size: DateInputProps["size"] }>` ${(props) => props.size === "fillParent" && "width: 100%;"} display: flex; flex-direction: column; @@ -46,7 +46,7 @@ const DateInputContainer = styled.div<{ margin: DateInputPropsType["margin"]; si `; const Label = styled.label<{ - disabled: DateInputPropsType["disabled"]; + disabled: DateInputProps["disabled"]; hasHelperText: boolean; }>` color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium);" : "var(--color-fg-neutral-dark);")}; @@ -56,13 +56,13 @@ const Label = styled.label<{ `; const OptionalLabel = styled.span<{ - disabled: DateInputPropsType["disabled"]; + disabled: DateInputProps["disabled"]; }>` color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium);" : "var(--color-fg-neutral-stronger);")}; font-weight: var(--typography-label-regular); `; -const HelperText = styled.span<{ disabled: DateInputPropsType["disabled"] }>` +const HelperText = styled.span<{ disabled: DateInputProps["disabled"] }>` color: ${(props) => (props.disabled ? "var(--color-fg-neutral-medium);" : "var(--color-fg-neutral-stronger);")}; font-size: var(--typography-helper-text-s); font-weight: var(--typography-helper-text-regular); @@ -96,7 +96,7 @@ const DxcDateInput = ({ tabIndex, ariaLabel = "Date input", ref, -}: DateInputPropsType) => { +}: DateInputProps) => { const [innerValue, setInnerValue] = useState(defaultValue); const [isOpen, setIsOpen] = useState(false); const calendarId = `date-picker-${useId()}`; diff --git a/packages/lib/src/date-input/types.ts b/packages/lib/src/date-input/types.ts index d34f89f94e..ae8fcce98f 100644 --- a/packages/lib/src/date-input/types.ts +++ b/packages/lib/src/date-input/types.ts @@ -1,9 +1,9 @@ import { Dayjs } from "dayjs"; -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; export type RefType = React.Ref<HTMLDivElement>; -type Props = { +export type DateInputProps = { /** * Initial value of the input element, only when it is uncontrolled. */ @@ -184,4 +184,4 @@ export type DateUnitPickerPropsType = { unit?: "month" | "year"; }; -export default Props; +export type { DateInputProps as default }; diff --git a/packages/lib/src/dialog/types.ts b/packages/lib/src/dialog/types.ts index 558068c6e3..0fe1c784fd 100644 --- a/packages/lib/src/dialog/types.ts +++ b/packages/lib/src/dialog/types.ts @@ -1,6 +1,6 @@ import { ReactNode } from "react"; -type Props = { +export type DialogProps = { /** * If true, the close button will be visible. */ @@ -40,4 +40,4 @@ type Props = { disableFocusLock?: boolean; }; -export default Props; +export type { DialogProps as default }; diff --git a/packages/lib/src/divider/Divider.tsx b/packages/lib/src/divider/Divider.tsx index 17ee8757e9..88ab06edcf 100644 --- a/packages/lib/src/divider/Divider.tsx +++ b/packages/lib/src/divider/Divider.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; -import DividerPropsType from "./types"; +import { DividerProps } from "./types"; -const StyledDivider = styled.hr<DividerPropsType>` +const StyledDivider = styled.hr<DividerProps>` ${({ orientation, weight, color }) => ` border-color: ${ color === "lightGrey" @@ -26,7 +26,7 @@ export default function DxcDivider({ decorative = true, orientation = "horizontal", weight = "regular", -}: DividerPropsType) { +}: DividerProps) { return ( <StyledDivider aria-hidden={decorative} diff --git a/packages/lib/src/divider/types.ts b/packages/lib/src/divider/types.ts index 6c2bce91b6..64a0ccf5a2 100644 --- a/packages/lib/src/divider/types.ts +++ b/packages/lib/src/divider/types.ts @@ -1,4 +1,4 @@ -type Props = { +export type DividerProps = { /** * The divider can be shown in horizontal or vertical. */ @@ -19,4 +19,4 @@ type Props = { decorative?: boolean; }; -export default Props; +export type { DividerProps as default }; diff --git a/packages/lib/src/dropdown/Dropdown.tsx b/packages/lib/src/dropdown/Dropdown.tsx index 5537d2945e..afb9f68c91 100644 --- a/packages/lib/src/dropdown/Dropdown.tsx +++ b/packages/lib/src/dropdown/Dropdown.tsx @@ -5,7 +5,7 @@ import { spaces } from "../common/variables"; import DxcIcon from "../icon/Icon"; import useWidth from "../utils/useWidth"; import DropdownMenu from "./DropdownMenu"; -import DropdownPropsType from "./types"; +import { DropdownProps } from "./types"; import DxcPopover from "../popover/Popover"; import { Tooltip } from "../tooltip/Tooltip"; @@ -17,15 +17,15 @@ const sizes = { fitContent: "fit-content", }; -const calculateWidth = (margin: DropdownPropsType["margin"], size: DropdownPropsType["size"]) => +const calculateWidth = (margin: DropdownProps["margin"], size: DropdownProps["size"]) => size != null && (size === "fillParent" ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` : sizes[size]); const DropdownContainer = styled.div<{ - margin: DropdownPropsType["margin"]; - size: DropdownPropsType["size"]; + margin: DropdownProps["margin"]; + size: DropdownProps["size"]; }>` width: ${(props) => calculateWidth(props.margin, props.size)}; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; @@ -40,9 +40,9 @@ const DropdownContainer = styled.div<{ `; const DropdownTrigger = styled.button<{ - label: DropdownPropsType["label"]; - margin: DropdownPropsType["margin"]; - size: DropdownPropsType["size"]; + label: DropdownProps["label"]; + margin: DropdownProps["margin"]; + size: DropdownProps["size"]; }>` display: flex; justify-content: space-between; @@ -71,7 +71,7 @@ const DropdownTrigger = styled.button<{ `}; `; -const DropdownTriggerContent = styled.span<{ iconPosition: DropdownPropsType["iconPosition"] }>` +const DropdownTriggerContent = styled.span<{ iconPosition: DropdownProps["iconPosition"] }>` display: flex; ${({ iconPosition }) => (iconPosition === "after" ? "flex-direction: row-reverse;" : "flex-direction: row;")} align-items: center; @@ -90,7 +90,7 @@ const DropdownTriggerLabel = styled.span` `; const DropdownTriggerIcon = styled.span<{ - disabled: DropdownPropsType["disabled"]; + disabled: DropdownProps["disabled"]; }>` display: flex; font-size: var(--height-xs); @@ -101,7 +101,7 @@ const DropdownTriggerIcon = styled.span<{ } `; -const CaretIcon = styled.span<{ disabled: DropdownPropsType["disabled"] }>` +const CaretIcon = styled.span<{ disabled: DropdownProps["disabled"] }>` display: flex; font-size: var(--typography-label-l); @@ -134,7 +134,7 @@ const DxcDropdown = ({ size = "fitContent", tabIndex = 0, title, -}: DropdownPropsType) => { +}: DropdownProps) => { const id = useId(); const triggerId = `trigger-${id}`; const menuId = `menu-${id}`; diff --git a/packages/lib/src/dropdown/types.ts b/packages/lib/src/dropdown/types.ts index 03d3bc44e9..889eed06a0 100644 --- a/packages/lib/src/dropdown/types.ts +++ b/packages/lib/src/dropdown/types.ts @@ -1,9 +1,7 @@ import { CSSProperties, KeyboardEvent } from "react"; -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; -type Size = "small" | "medium" | "large" | "fillParent" | "fitContent"; - -export type Option = { +export type DropdownOption = { /** * Option display value. */ @@ -22,11 +20,11 @@ export type Option = { hasDivider?: boolean; }; -type Props = { +export type DropdownProps = { /** * An array of objects representing the options. */ - options: Option[]; + options: DropdownOption[]; /** * In case options include icons, whether the icon should appear * after or before the label. @@ -70,7 +68,7 @@ type Props = { /** * Size of the component. */ - size?: Size; + size?: "small" | "medium" | "large" | "fillParent" | "fitContent"; /** * Value of the tabindex attribute. */ @@ -89,7 +87,7 @@ export type DropdownMenuProps = { visualFocusIndex: number; menuItemOnClick: (value: string) => void; onKeyDown: (event: KeyboardEvent<HTMLUListElement>) => void; - options: Option[]; + options: DropdownOption[]; ref: React.Ref<HTMLUListElement>; styles: CSSProperties; }; @@ -99,7 +97,7 @@ export type DropdownMenuItemProps = { visuallyFocused: boolean; iconPosition: "before" | "after"; onClick: (value: string) => void; - option: Option; + option: DropdownOption; }; -export default Props; +export type { DropdownProps as default }; diff --git a/packages/lib/src/file-input/FileInput.tsx b/packages/lib/src/file-input/FileInput.tsx index 92ed214386..50ac1caaf4 100644 --- a/packages/lib/src/file-input/FileInput.tsx +++ b/packages/lib/src/file-input/FileInput.tsx @@ -3,16 +3,16 @@ import styled from "@emotion/styled"; import DxcButton from "../button/Button"; import { spaces } from "../common/variables"; import FileItem from "./FileItem"; -import FileInputPropsType, { FileData } from "./types"; +import { FileInputProps, FileData } from "./types"; import { HalstackLanguageContext } from "../HalstackContext"; import { getFilePreview, isFileIncluded } from "./utils"; import HelperText from "../styles/forms/HelperText"; import Label from "../styles/forms/Label"; const FileInputContainer = styled.div<{ - margin: FileInputPropsType["margin"]; - mode: FileInputPropsType["mode"]; - size: FileInputPropsType["size"]; + margin: FileInputProps["margin"]; + mode: FileInputProps["mode"]; + size: FileInputProps["size"]; }>` display: flex; flex-direction: column; @@ -56,10 +56,10 @@ const Container = styled.div` `; const DragDropArea = styled.div<{ - mode: FileInputPropsType["mode"]; - disabled: FileInputPropsType["disabled"]; + mode: FileInputProps["mode"]; + disabled: FileInputProps["disabled"]; isDragging: boolean; - size: FileInputPropsType["size"]; + size: FileInputProps["size"]; }>` box-sizing: border-box; display: flex; @@ -84,7 +84,7 @@ const DragDropArea = styled.div<{ cursor: ${(props) => props.disabled && "not-allowed"}; `; -const DropzoneLabel = styled.div<{ disabled: FileInputPropsType["disabled"] }>` +const DropzoneLabel = styled.div<{ disabled: FileInputProps["disabled"] }>` display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; @@ -97,7 +97,7 @@ const DropzoneLabel = styled.div<{ disabled: FileInputPropsType["disabled"] }>` font-weight: var(--typography-helper-text-regular); `; -const FiledropLabel = styled.span<{ disabled: FileInputPropsType["disabled"] }>` +const FiledropLabel = styled.span<{ disabled: FileInputProps["disabled"] }>` overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -126,7 +126,7 @@ const DxcFileInput = ({ tabIndex = 0, optional = false, ref, -}: FileInputPropsType) => { +}: FileInputProps) => { const [isDragging, setIsDragging] = useState(false); const [files, setFiles] = useState<FileData[]>([]); const fileInputId = `file-input-${useId()}`; diff --git a/packages/lib/src/file-input/types.ts b/packages/lib/src/file-input/types.ts index 189b76e245..82697635f2 100644 --- a/packages/lib/src/file-input/types.ts +++ b/packages/lib/src/file-input/types.ts @@ -1,4 +1,4 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, PrettifyTypes, Space } from "../common/types"; /** * Reference to the component. @@ -119,7 +119,7 @@ type FileModeProps = CommonProps & { mode?: "file"; }; -type Props = DropModeProps | FileModeProps; +export type FileInputProps = PrettifyTypes<DropModeProps | FileModeProps>; /** * Single file item preview. @@ -136,4 +136,4 @@ export type FileItemProps = { size: "medium" | "fillParent"; }; -export default Props; +export type { FileInputProps as default }; diff --git a/packages/lib/src/flex/Flex.tsx b/packages/lib/src/flex/Flex.tsx index ca57aa486a..42cf3dcb70 100644 --- a/packages/lib/src/flex/Flex.tsx +++ b/packages/lib/src/flex/Flex.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import FlexPropsType, { StyledProps } from "./types"; +import type { FlexProps, StyledProps } from "./types"; const Flex = styled.div<StyledProps>` display: flex; @@ -20,7 +20,7 @@ const Flex = styled.div<StyledProps>` `} `; -const DxcFlex = ({ basis, direction, fullHeight = false, gap, grow, order, shrink, wrap, ...props }: FlexPropsType) => ( +const DxcFlex = ({ basis, direction, fullHeight = false, gap, grow, order, shrink, wrap, ...props }: FlexProps) => ( <Flex $basis={basis} $direction={direction} diff --git a/packages/lib/src/flex/types.ts b/packages/lib/src/flex/types.ts index b610975302..4b1a628d81 100644 --- a/packages/lib/src/flex/types.ts +++ b/packages/lib/src/flex/types.ts @@ -1,6 +1,7 @@ import { ReactNode } from "react"; +import { PrettifyTypes } from "../common/types"; -type Gap = { rowGap: string; columnGap?: string } | { rowGap?: string; columnGap: string } | string; +export type FlexGap = { rowGap: string; columnGap?: string } | { rowGap?: string; columnGap: string } | string; type CommonProps = { /** @@ -60,72 +61,76 @@ type CommonProps = { alignSelf?: "auto" | "flex-start" | "flex-end" | "center" | "baseline" | "stretch"; }; -type Props = CommonProps & { - /** - * Sets the flex-direction CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction - */ - direction?: "row" | "row-reverse" | "column" | "column-reverse"; - /** - * Sets the flex-wrap CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap - */ - wrap?: "nowrap" | "wrap" | "wrap-reverse"; - /** - * Sets the gap CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/gap - */ - gap?: Gap; - /** - * Sets the order CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/order - */ - order?: number; - /** - * If true, the flex container will take the full height of its parent. - */ - fullHeight?: boolean; - /** - * Sets the flex-grow CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow - */ - grow?: number; - /** - * Sets the flex-shrink CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-shrink - */ - shrink?: number; - /** - * Sets the flex-basis CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis - */ - basis?: string; - /** - * Sets a custom HTML tag. - */ - as?: keyof HTMLElementTagNameMap; - /** - * Custom content inside the flex container. - */ - children: ReactNode; -}; +export type FlexProps = PrettifyTypes< + CommonProps & { + /** + * Sets the flex-direction CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction + */ + direction?: "row" | "row-reverse" | "column" | "column-reverse"; + /** + * Sets the flex-wrap CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap + */ + wrap?: "nowrap" | "wrap" | "wrap-reverse"; + /** + * Sets the gap CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/gap + */ + gap?: FlexGap; + /** + * Sets the order CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/order + */ + order?: number; + /** + * If true, the flex container will take the full height of its parent. + */ + fullHeight?: boolean; + /** + * Sets the flex-grow CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-grow + */ + grow?: number; + /** + * Sets the flex-shrink CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-shrink + */ + shrink?: number; + /** + * Sets the flex-basis CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis + */ + basis?: string; + /** + * Sets a custom HTML tag. + */ + as?: keyof HTMLElementTagNameMap; + /** + * Custom content inside the flex container. + */ + children: ReactNode; + } +>; -export type StyledProps = CommonProps & { - $direction?: "row" | "row-reverse" | "column" | "column-reverse"; - $wrap?: "nowrap" | "wrap" | "wrap-reverse"; - $gap?: Gap; - $fullHeight?: boolean; - $order?: number; - $grow?: number; - $shrink?: number; - $basis?: string; -}; +export type StyledProps = PrettifyTypes< + CommonProps & { + $direction?: "row" | "row-reverse" | "column" | "column-reverse"; + $wrap?: "nowrap" | "wrap" | "wrap-reverse"; + $gap?: FlexGap; + $fullHeight?: boolean; + $order?: number; + $grow?: number; + $shrink?: number; + $basis?: string; + } +>; -export default Props; +export type { FlexProps as default }; diff --git a/packages/lib/src/footer/Footer.tsx b/packages/lib/src/footer/Footer.tsx index 0edd31c5bc..a23f8f963a 100644 --- a/packages/lib/src/footer/Footer.tsx +++ b/packages/lib/src/footer/Footer.tsx @@ -3,7 +3,7 @@ import styled from "@emotion/styled"; import DxcIcon from "../icon/Icon"; import { Tooltip } from "../tooltip/Tooltip"; import { dxcLogo, dxcSmallLogo } from "./Icons"; -import FooterPropsType from "./types"; +import { FooterProps } from "./types"; import { HalstackLanguageContext, HalstackLogosContext } from "../HalstackContext"; import { getContrastColor, getResponsiveStyles } from "./utils"; import DxcLink from "../link/Link"; @@ -11,7 +11,7 @@ import useWidth from "../utils/useWidth"; import { css } from "@emotion/react"; const FooterContainer = styled.footer<{ - mode?: FooterPropsType["mode"]; + mode?: FooterProps["mode"]; }>` box-sizing: border-box; display: flex; @@ -53,7 +53,7 @@ const LeftContainer = styled.div<{ width: number }>` `} `; -const LogoContainer = styled.span<{ mode?: FooterPropsType["mode"] }>` +const LogoContainer = styled.span<{ mode?: FooterProps["mode"] }>` max-height: ${(props) => (props?.mode === "default" ? "var(--height-xl)" : "var(--height-xxs)")}; width: fit-content; text-align: center; @@ -72,7 +72,7 @@ const LogoContainer = styled.span<{ mode?: FooterPropsType["mode"] }>` } `; -const LogoImg = styled.img<{ mode: FooterPropsType["mode"] }>` +const LogoImg = styled.img<{ mode: FooterProps["mode"] }>` max-height: ${(props) => (props.mode === "default" ? "var(--height-m)" : "var(--height-xxs)")}; width: auto; `; @@ -127,7 +127,7 @@ const SocialIconContainer = styled.div` } `; -const BottomContainer = styled.div<{ textColor: string; width: number; variant: FooterPropsType["variant"] }>` +const BottomContainer = styled.div<{ textColor: string; width: number; variant: FooterProps["variant"] }>` width: 100%; min-height: var(--height-xl); display: grid; @@ -216,7 +216,7 @@ const DxcFooter = ({ socialLinks, variant = "branded", tabIndex = 0, -}: FooterPropsType): JSX.Element => { +}: FooterProps): JSX.Element => { const translatedLabels = use(HalstackLanguageContext).labels; const themedLogos = use(HalstackLogosContext); diff --git a/packages/lib/src/footer/types.ts b/packages/lib/src/footer/types.ts index 99aa3a3cd9..603a119349 100644 --- a/packages/lib/src/footer/types.ts +++ b/packages/lib/src/footer/types.ts @@ -1,7 +1,7 @@ import { ReactNode } from "react"; -import { SVG } from "../common/utils"; +import { SVG } from "../common/types"; -type SocialLink = { +type FooterSocialLink = { /** * URL of the page the link goes to. */ @@ -16,7 +16,7 @@ type SocialLink = { title: string; }; -type BottomLink = { +type FooterBottomLink = { /** * URL of the page the link goes to. */ @@ -27,7 +27,7 @@ type BottomLink = { text: string; }; -type Logo = { +type FooterLogo = { /** * Source of the logo image. */ @@ -38,12 +38,12 @@ type Logo = { alt: string; }; -type FooterPropsType = { +type FooterProps = { /** * An array of objects representing the links that will be rendered at * the bottom part of the footer. */ - bottomLinks?: BottomLink[]; + bottomLinks?: FooterBottomLink[]; /** * The text that will be displayed as copyright disclaimer. */ @@ -55,7 +55,7 @@ type FooterPropsType = { /** * Logo to be displayed inside the footer */ - logo?: Logo; + logo?: FooterLogo; /** * Determines the visual style and layout * - "default": The default mode with full content and styling. @@ -70,7 +70,7 @@ type FooterPropsType = { * An array of objects representing the links that will be rendered as * icons at the top-right side of the footer. */ - socialLinks?: SocialLink[]; + socialLinks?: FooterSocialLink[]; /** * Value of the tabindex for all interactive elements, except those * inside the leftContent and rightContent. @@ -82,4 +82,4 @@ type FooterPropsType = { variant?: "branded" | "neutral"; }; -export default FooterPropsType; +export type { FooterProps as default, FooterProps, FooterBottomLink, FooterLogo, FooterSocialLink }; diff --git a/packages/lib/src/global.d.ts b/packages/lib/src/global.d.ts index 645ab52174..5a60fc8359 100644 --- a/packages/lib/src/global.d.ts +++ b/packages/lib/src/global.d.ts @@ -7,3 +7,5 @@ declare module "*.woff" { const content: string; export default content; } + +declare module "*.css" {} diff --git a/packages/lib/src/grid/Grid.tsx b/packages/lib/src/grid/Grid.tsx index 7e1797a76b..63ab25a42a 100644 --- a/packages/lib/src/grid/Grid.tsx +++ b/packages/lib/src/grid/Grid.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; -import GridPropsType, { GridItemProps } from "./types"; +import { GridProps, GridItemProps } from "./types"; -const Grid = styled.div<GridPropsType>` +const Grid = styled.div<GridProps>` display: grid; ${(props) => ` ${props.templateColumns ? `grid-template-columns: ${props.templateColumns.join(" ")};` : ""} @@ -91,7 +91,7 @@ const GridItem = styled.div<GridItemProps>` `} `; -const DxcGrid = (props: GridPropsType) => <Grid {...props} />; +const DxcGrid = (props: GridProps) => <Grid {...props} />; DxcGrid.Item = GridItem; export default DxcGrid; diff --git a/packages/lib/src/grid/types.ts b/packages/lib/src/grid/types.ts index 3bf02a22c0..c692c16e7c 100644 --- a/packages/lib/src/grid/types.ts +++ b/packages/lib/src/grid/types.ts @@ -1,19 +1,12 @@ import { ReactNode } from "react"; +import { PrettifyTypes } from "../common/types"; -type Gap = string | { columnGap?: string; rowGap: string } | { columnGap: string; rowGap?: string }; +type GridGap = string | { columnGap?: string; rowGap: string } | { columnGap: string; rowGap?: string }; type GridCell = { end: number | string; start: number | string }; -type PlaceSelfValues = "auto" | "baseline" | "center" | "end" | "start" | "stretch"; -type PlaceContentValues = - | "baseline" - | "center" - | "end" - | "normal" - | "space-around" - | "space-between" - | "space-evenly" - | "start" - | "stretch"; -type PlaceItemsValues = "baseline" | "center" | "end" | "normal" | "start" | "stretch"; +type GridPlaceSelfValues = "auto" | "baseline" | "center" | "end" | "start" | "stretch"; +type GridPlaceContentValues = + "baseline" | "center" | "end" | "normal" | "space-around" | "space-between" | "space-evenly" | "start" | "stretch"; +type GridPlaceItemsValues = "baseline" | "center" | "end" | "normal" | "start" | "stretch"; type PlaceObject<Type, Suffix extends string> = { [Property in Extract<keyof Type, string> as `${Property}${Capitalize<Suffix>}`]: Type[Property]; }; @@ -22,7 +15,7 @@ type PlaceGeneric<PlaceValues, Element extends string> = | PlaceObject<{ align?: PlaceValues; justify: PlaceValues }, Element> | PlaceValues; -export type GridItemProps = { +type GridItemProps = { /** * Sets the name of an item so that it can be referenced by a template created with the grid-template-areas property. */ @@ -46,7 +39,7 @@ export type GridItemProps = { * * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/place-self */ - placeSelf?: PlaceGeneric<PlaceSelfValues, "self">; + placeSelf?: PlaceGeneric<GridPlaceSelfValues, "self">; /** * Sets the grid-row CSS property. * @@ -55,61 +48,72 @@ export type GridItemProps = { row?: number | string | GridCell; }; -type Props = GridItemProps & { - /** - * Sets the grid-auto-columns CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-columns - */ - autoColumns?: string; - /** - * Sets the grid-auto-flow CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow - */ - autoFlow?: "row" | "column" | "row dense" | "column dense"; - /** - * Sets the grid-auto-rows CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-rows - */ - autoRows?: string; - /** - * Sets the gap CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/gap - */ - gap?: Gap; - /** - * Sets the place-content CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/place-content - */ - placeContent?: PlaceGeneric<PlaceContentValues, "content">; - /** - * Sets the place-items CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/place-items - */ - placeItems?: PlaceGeneric<PlaceItemsValues, "items">; - /** - * Sets the grid-template-areas CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas - */ - templateAreas?: string[]; - /** - * Sets the grid-template-columns CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns - */ - templateColumns?: string[]; - /** - * Sets the grid-template-rows CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-rows - */ - templateRows?: string[]; -}; +type GridProps = PrettifyTypes< + GridItemProps & { + /** + * Sets the grid-auto-columns CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-columns + */ + autoColumns?: string; + /** + * Sets the grid-auto-flow CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow + */ + autoFlow?: "row" | "column" | "row dense" | "column dense"; + /** + * Sets the grid-auto-rows CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-rows + */ + autoRows?: string; + /** + * Sets the gap CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/gap + */ + gap?: GridGap; + /** + * Sets the place-content CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/place-content + */ + placeContent?: PlaceGeneric<GridPlaceContentValues, "content">; + /** + * Sets the place-items CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/place-items + */ + placeItems?: PlaceGeneric<GridPlaceItemsValues, "items">; + /** + * Sets the grid-template-areas CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-areas + */ + templateAreas?: string[]; + /** + * Sets the grid-template-columns CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns + */ + templateColumns?: string[]; + /** + * Sets the grid-template-rows CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-rows + */ + templateRows?: string[]; + } +>; -export default Props; +export type { + GridProps as default, + GridProps, + GridCell, + GridItemProps, + GridGap, + GridPlaceSelfValues, + GridPlaceContentValues, + GridPlaceItemsValues, +}; diff --git a/packages/lib/src/header/Header.tsx b/packages/lib/src/header/Header.tsx index 1f452a8471..2898633d7b 100644 --- a/packages/lib/src/header/Header.tsx +++ b/packages/lib/src/header/Header.tsx @@ -1,11 +1,11 @@ import styled from "@emotion/styled"; import DxcGrid from "../grid/Grid"; -import HeaderProps from "./types"; +import { HeaderProps } from "./types"; import DxcImage from "../image/Image"; import DxcDivider from "../divider/Divider"; import DxcHeading from "../heading/Heading"; import { isGroupItem } from "../base-menu/utils"; -import { GroupItem, Item } from "../base-menu/types"; +import { BaseGroupItem, BaseItem } from "../base-menu/types"; import { JSX, use, useEffect, useMemo, useState } from "react"; import DxcNavigationTree from "../navigation-tree/NavigationTree"; import { responsiveSizes } from "../common/variables"; @@ -114,13 +114,13 @@ const Overlay = styled.div` * @param level current level of recursion. * @return Processed navigation items with limited levels. */ -const sanitizeNavItems = (navItems: HeaderProps["navItems"], level?: number): (GroupItem | Item)[] => { +const sanitizeNavItems = (navItems: HeaderProps["navItems"], level?: number): (BaseGroupItem | BaseItem)[] => { if (!navItems) return []; if (!level) level = 0; - const sanitizedItems = navItems.reduce<(GroupItem | Item)[]>((acc, item) => { + const sanitizedItems = navItems.reduce<(BaseGroupItem | BaseItem)[]>((acc, item) => { if (isGroupItem(item)) { if (level < LEVEL_LIMIT) { - const processedGroup: GroupItem = { + const processedGroup: BaseGroupItem = { ...item, items: sanitizeNavItems(item.items, level + 1), }; diff --git a/packages/lib/src/header/types.ts b/packages/lib/src/header/types.ts index b8ba097537..64e46f9bff 100644 --- a/packages/lib/src/header/types.ts +++ b/packages/lib/src/header/types.ts @@ -1,21 +1,24 @@ import { ReactNode } from "react"; -import { CommonItemProps, Item } from "../base-menu/types"; +import { BaseCommonItemProps, BaseItem } from "../base-menu/types"; import { SearchBarProps } from "../search-bar/types"; +import { PrettifyTypes } from "../common/types"; -type GroupItem = CommonItemProps & { - items: Item[]; -}; +export type HeaderGroupItem = PrettifyTypes< + BaseCommonItemProps & { + items: BaseItem[]; + } +>; -type MainNavPropsType = (GroupItem | Item)[]; +export type HeaderMainNavPropsType = (HeaderGroupItem | PrettifyTypes<BaseItem>)[]; -type SearchBarHeaderProps = Omit<SearchBarProps, "autoFocus" | "disabled">; +export type HeaderSearchBarProps = Omit<SearchBarProps, "autoFocus" | "disabled">; -type Props = { +export type HeaderProps = { appTitle?: string; - navItems?: MainNavPropsType; + navItems?: HeaderMainNavPropsType; responsiveBottomContent?: ReactNode; - searchBar?: SearchBarHeaderProps; + searchBar?: HeaderSearchBarProps; sideContent?: ReactNode | ((isResponsive: boolean) => ReactNode); }; -export default Props; +export type { HeaderProps as default }; diff --git a/packages/lib/src/heading/types.ts b/packages/lib/src/heading/types.ts index 0b37579636..b8a42fc1df 100644 --- a/packages/lib/src/heading/types.ts +++ b/packages/lib/src/heading/types.ts @@ -1,6 +1,6 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; -type Props = { +type HeadingProps = { /** * Defines the heading level from 1 to 5. The styles of the heading are applied according to the level. * The html tag of the heading will be the one specified in the 'as' prop. @@ -26,4 +26,4 @@ type Props = { margin?: Space | Margin; }; -export default Props; +export type { HeadingProps, HeadingProps as default }; diff --git a/packages/lib/src/heading/utils.ts b/packages/lib/src/heading/utils.ts index 02771a9e70..dd90a3429a 100644 --- a/packages/lib/src/heading/utils.ts +++ b/packages/lib/src/heading/utils.ts @@ -1,6 +1,6 @@ -import HeadingPropsType from "./types"; +import { HeadingProps } from "./types"; -export const getHeadingSize = (level: HeadingPropsType["level"]) => { +export const getHeadingSize = (level: HeadingProps["level"]) => { switch (level) { case 1: return "var(--typography-heading-xxl)"; @@ -17,7 +17,7 @@ export const getHeadingSize = (level: HeadingPropsType["level"]) => { } }; -export const getHeadingWeight = (weight: HeadingPropsType["weight"]) => { +export const getHeadingWeight = (weight: HeadingProps["weight"]) => { switch (weight) { case "default": return "var(--typography-heading-semibold)"; diff --git a/packages/lib/src/image/Image.tsx b/packages/lib/src/image/Image.tsx index 7ed3d15ac8..ca1b97f69c 100644 --- a/packages/lib/src/image/Image.tsx +++ b/packages/lib/src/image/Image.tsx @@ -1,6 +1,6 @@ import styled from "@emotion/styled"; import { ReactNode } from "react"; -import ImagePropsType from "./types"; +import { ImageProps } from "./types"; const Figure = styled.figure` display: flex; @@ -18,7 +18,7 @@ const CaptionContainer = styled.figcaption` font-weight: var(--typography-label-regular); `; -const CaptionWrapper = ({ caption, children }: { caption: ImagePropsType["caption"]; children: ReactNode }) => +const CaptionWrapper = ({ caption, children }: { caption: ImageProps["caption"]; children: ReactNode }) => caption != null ? ( <Figure> {children} @@ -41,7 +41,7 @@ export default function DxcImage({ src, srcSet, width, -}: ImagePropsType) { +}: ImageProps) { return ( <CaptionWrapper caption={caption}> <img diff --git a/packages/lib/src/image/types.ts b/packages/lib/src/image/types.ts index 15d741890f..9956ce6ab8 100644 --- a/packages/lib/src/image/types.ts +++ b/packages/lib/src/image/types.ts @@ -1,6 +1,6 @@ import { ReactEventHandler } from "react"; -type Props = { +type ImageProps = { /** * Alternative text description displayed when the specified image is not loaded. * @@ -66,4 +66,4 @@ type Props = { width?: string; }; -export default Props; +export type { ImageProps, ImageProps as default }; diff --git a/packages/lib/src/index.ts b/packages/lib/src/index.ts index e776fe13c3..ac103aaba4 100644 --- a/packages/lib/src/index.ts +++ b/packages/lib/src/index.ts @@ -55,3 +55,104 @@ export { default as DxcTypography } from "./typography/Typography"; export { default as DxcWizard } from "./wizard/Wizard"; export { HalstackProvider, HalstackLanguageContext } from "./HalstackContext"; export { default as useToast } from "./toast/useToast"; + +// types exports +export type { + Space as DxcSpace, + Margin as DxcMargin, + SVG as DxcSVG, + Size as DxcSize, + Shape as DxcShape, + Color as DxcColor, +} from "./common/types"; +export type { + AccordionProps as DxcAccordionProps, + AccordionItemProps as DxcAccordionItemProps, +} from "./accordion/types"; +export type { + AlertProps as DxcAlertProps, + AlertAction as DxcAlertAction, + AlertMessage as DxcAlertMessage, +} from "./alert/types"; +export type { + ApplicationLayoutProps as DxcAppLayoutProps, + AppLayoutMainProps as DxcAppLayoutMainProps, + AppLayoutSidenavProps as DxcAppLayoutSidenavProps, + AppLayoutLogo as DxcAppLayoutLogo, +} from "./layout/types"; +export type { AvatarProps as DxcAvatarProps, AvatarStatus as DxcAvatarStatus } from "./avatar/types"; +export type { BadgeProps as DxcBadgeProps } from "./badge/types"; +export type { + BaseItem as DxcBaseItem, + BaseGroupItem as DxcBaseGroupItem, + BaseSection as DxcBaseSection, +} from "./base-menu/types"; +export type { + BreadcrumbsProps as DxcBreadcrumbsProps, + BreadcrumbsItemProps as DxcBreadcrumbsItemProps, +} from "./breadcrumbs/types"; +export type { + BulletedListProps as DxcBulletedListProps, + BulletedListItemProps as DxcBulletedListItemProps, +} from "./bulleted-list/types"; +export type { + ButtonProps as DxcButtonProps, + ButtonMode as DxcButtonMode, + ButtonSemantic as DxcButtonSemantic, + ButtonSize as DxcButtonSize, +} from "./button/types"; +export type { CardProps as DxcCardProps } from "./card/types"; +export type { CheckboxProps as DxcCheckboxProps } from "./checkbox/types"; +export type { ChipProps as DxcChipProps } from "./chip/types"; +export type { ContextualMenuProps as DxcContextualMenuProps } from "./contextual-menu/types"; +export type { + DataGridProps as DxcDataGridProps, + DataGridRow as DxcDataGridRow, + DataGridHierarchyRow as DxcDataGridHierarchyRow, + DataGridExpandableRow as DxcDataGridExpandableRow, + DataGridExpandableRows as DxcDataGridExpandableRows, + DataGridHierarchyRows as DxcDataGridHierarchyRows, + DataGridSelectableProps as DxcDataGridSelectableProps, + DataGridBasicProps as DxcDataGridBasicProps, + DataGridColumn as DxcDataGridColumn, +} from "./data-grid/types"; +export type { DateInputProps as DxcDateInputProps } from "./date-input/types"; +export type { DialogProps as DxcDialogProps } from "./dialog/types"; +export type { DropdownProps as DxcDropdownProps, DropdownOption as DxcDropdownOption } from "./dropdown/types"; +export type { FileInputProps as DxcFileInputProps, FileData as DxcFileData } from "./file-input/types"; +export type { FlexProps as DxcFlexProps } from "./flex/types"; +export type { + FooterProps as DxcFooterProps, + FooterBottomLink as DxcFooterBottomLink, + FooterSocialLink as DxcFooterSocialLink, + FooterLogo as DxcFooterLogo, +} from "./footer/types"; +export type { + GridProps as DxcGridProps, + GridGap as DxcGridGap, + GridCell as DxcGridCell, + GridItemProps as DxcGridItemProps, + GridPlaceSelfValues as DxcGridPlaceSelfValues, + GridPlaceContentValues as DxcGridPlaceContentValues, + GridPlaceItemsValues as DxcGridPlaceItemsValues, +} from "./grid/types"; +export type { + HeaderProps as DxcHeaderProps, + HeaderMainNavPropsType as DxcHeaderMainNavPropsType, + HeaderSearchBarProps as DxcHeaderSearchBarProps, + HeaderGroupItem as DxcHeaderGroupItem, +} from "./header/types"; +export type { HeadingProps as DxcHeadingProps } from "./heading/types"; +export type { ImageProps as DxcImageProps } from "./image/types"; +export type { InsetProps as DxcInsetProps } from "./inset/types"; +export type { LinkProps as DxcLinkProps } from "./link/types"; +export type { MessageInputProps as DxcMessageInputProps } from "./message-input/types"; +export type { NavTabsProps as DxcNavTabsProps, NavTabsTabProps as DxcNavTabsTabProps } from "./nav-tabs/types"; +export type { NumberInputProps as DxcNumberInputProps } from "./number-input/types"; +export type { PaginatorProps as DxcPaginatorProps } from "./paginator/types"; +export type { PasswordProps as DxcPasswordInputProps } from "./password-input/types"; +export type { + SidenavProps as DxcSidenavProps, + SidenavSection as DxcSidenavSection, + SidenavSearchbarProps as DxcSidenavSearchbarProps, +} from "./sidenav/types"; diff --git a/packages/lib/src/inset/Inset.tsx b/packages/lib/src/inset/Inset.tsx index 9eb421db01..ad0ca0f9ea 100644 --- a/packages/lib/src/inset/Inset.tsx +++ b/packages/lib/src/inset/Inset.tsx @@ -1,7 +1,7 @@ -import InsetPropsType from "./types"; +import { InsetProps } from "./types"; import DxcContainer from "../container/Container"; -export default function DxcInset({ bottom, children, horizontal, left, right, space, top, vertical }: InsetPropsType) { +export default function DxcInset({ bottom, children, horizontal, left, right, space, top, vertical }: InsetProps) { return ( <DxcContainer padding={{ diff --git a/packages/lib/src/inset/types.ts b/packages/lib/src/inset/types.ts index af9833ef26..80075695c2 100644 --- a/packages/lib/src/inset/types.ts +++ b/packages/lib/src/inset/types.ts @@ -1,6 +1,6 @@ import { ReactNode } from "react"; -type Props = { +type InsetProps = { /** * Applies the spacing scale to the bottom side. */ @@ -35,4 +35,4 @@ type Props = { vertical?: string; }; -export default Props; +export type { InsetProps, InsetProps as default }; diff --git a/packages/lib/src/layout/ApplicationLayout.tsx b/packages/lib/src/layout/ApplicationLayout.tsx index 546b396091..2132451cfe 100644 --- a/packages/lib/src/layout/ApplicationLayout.tsx +++ b/packages/lib/src/layout/ApplicationLayout.tsx @@ -3,7 +3,7 @@ import styled from "@emotion/styled"; import DxcFooter from "../footer/Footer"; import DxcHeader from "../header/Header"; import DxcSidenav from "../sidenav/Sidenav"; -import ApplicationLayoutPropsType, { AppLayoutMainPropsType } from "./types"; +import { ApplicationLayoutProps, AppLayoutMainProps } from "./types"; import { bottomLinks, findChildType, socialLinks, year } from "./utils"; import ApplicationLayoutContext from "./ApplicationLayoutContext"; import { responsiveSizes } from "../common/variables"; @@ -62,9 +62,9 @@ const FooterContainer = styled.div` width: 100%; `; -const Main = ({ children }: AppLayoutMainPropsType): JSX.Element => <div>{children}</div>; +const Main = ({ children }: AppLayoutMainProps): JSX.Element => <div>{children}</div>; -const DxcApplicationLayout = ({ logo, header, sidenav, footer, children }: ApplicationLayoutPropsType): JSX.Element => { +const DxcApplicationLayout = ({ logo, header, sidenav, footer, children }: ApplicationLayoutProps): JSX.Element => { const [headerHeight, setHeaderHeight] = useState("0px"); const [hideMainContent, setHideMainContent] = useState(false); const themedLogos = use(HalstackLogosContext); @@ -80,7 +80,7 @@ const DxcApplicationLayout = ({ logo, header, sidenav, footer, children }: Appli ); const contextValue = useMemo(() => { - const logoToUse: ApplicationLayoutPropsType["logo"] = { + const logoToUse: ApplicationLayoutProps["logo"] = { src: logo?.src || themedLogos?.mainLogo || "", alt: logo?.alt || "", }; diff --git a/packages/lib/src/layout/ApplicationLayoutContext.tsx b/packages/lib/src/layout/ApplicationLayoutContext.tsx index 2da55fbd92..31d051932f 100644 --- a/packages/lib/src/layout/ApplicationLayoutContext.tsx +++ b/packages/lib/src/layout/ApplicationLayoutContext.tsx @@ -1,7 +1,7 @@ import { createContext } from "react"; -import { ApplicationLayoutContextType } from "./types"; +import { ApplicationLayoutContext } from "./types"; -export default createContext<ApplicationLayoutContextType>({ +export default createContext<ApplicationLayoutContext>({ logo: undefined, headerExists: false, setHideMainContent: () => {}, diff --git a/packages/lib/src/layout/types.ts b/packages/lib/src/layout/types.ts index f8b1e667ac..cc9523a464 100644 --- a/packages/lib/src/layout/types.ts +++ b/packages/lib/src/layout/types.ts @@ -1,14 +1,14 @@ import { ReactElement, ReactNode } from "react"; -import { SVG } from "../common/utils"; +import { SVG } from "../common/types"; -export type AppLayoutMainPropsType = { +export type AppLayoutMainProps = { /** * Everything between the tags will be displayed as the content of the main part of the application. */ children: ReactNode; }; -type LogoPropsType = { +export type AppLayoutLogo = { /** * Alternative text for the logo image. */ @@ -27,7 +27,7 @@ type LogoPropsType = { src: string | SVG; }; -export type AppLayoutSidenavPropsType = { +export type AppLayoutSidenavProps = { /** * The area inside the sidenav. This area can be used to render the content inside the sidenav. */ @@ -38,11 +38,11 @@ export type AppLayoutSidenavPropsType = { title?: ReactNode; }; -export type ApplicationLayoutContextType = { +export type ApplicationLayoutContext = { /** * Logo properties. */ - logo?: LogoPropsType; + logo?: AppLayoutLogo; /** * Indicates if the header exists. */ @@ -53,11 +53,11 @@ export type ApplicationLayoutContextType = { setHideMainContent: (hide: boolean) => void; }; -type ApplicationLayoutPropsType = { +export type ApplicationLayoutProps = { /** * Logo properties. */ - logo?: LogoPropsType; + logo?: AppLayoutLogo; /** * Header content. */ @@ -73,7 +73,7 @@ type ApplicationLayoutPropsType = { /** * Use the DxcApplicationLayout.Main provided to render main content. */ - children: ReactElement<AppLayoutMainPropsType>; + children: ReactElement<AppLayoutMainProps>; }; -export default ApplicationLayoutPropsType; +export type { ApplicationLayoutProps as default }; diff --git a/packages/lib/src/layout/utils.tsx b/packages/lib/src/layout/utils.tsx index 7f785f7c26..0ff8a87bf4 100644 --- a/packages/lib/src/layout/utils.tsx +++ b/packages/lib/src/layout/utils.tsx @@ -1,6 +1,6 @@ import { Children, isValidElement, useState, useEffect, ElementType } from "react"; import layoutIcons from "./Icons"; -import ApplicationLayoutPropsType from "./types"; +import { ApplicationLayoutProps } from "./types"; export const year = new Date().getFullYear(); @@ -37,7 +37,7 @@ export const socialLinks = [ }, ]; -export const findChildType = (children: ApplicationLayoutPropsType["children"], childType: ElementType) => +export const findChildType = (children: ApplicationLayoutProps["children"], childType: ElementType) => Children.toArray(children).find((child) => isValidElement(child) && child.type === childType); export const useResponsive = (breakpoint: string) => { diff --git a/packages/lib/src/link/types.ts b/packages/lib/src/link/types.ts index 08c3b0e13c..8ba8046241 100644 --- a/packages/lib/src/link/types.ts +++ b/packages/lib/src/link/types.ts @@ -1,4 +1,4 @@ -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; export type LinkProps = { /** @@ -48,3 +48,5 @@ export type LinkProps = { */ tabIndex?: number; }; + +export type { LinkProps as default }; diff --git a/packages/lib/src/message-input/MessageInput.tsx b/packages/lib/src/message-input/MessageInput.tsx index 4439d1c291..6d91494c31 100644 --- a/packages/lib/src/message-input/MessageInput.tsx +++ b/packages/lib/src/message-input/MessageInput.tsx @@ -1,7 +1,7 @@ import { ChangeEvent, FocusEvent, KeyboardEvent, MouseEvent, use, useEffect, useId, useRef, useState } from "react"; import styled from "@emotion/styled"; import scrollbarStyles from "../styles/scroll"; -import PromptInputPropsType from "./types"; +import { MessageInputProps } from "./types"; import { getFilePreview, getSelectedOption, inputStylesByStatePromptInput } from "./utils"; import DxcButton from "../button/Button"; import DxcChip from "../chip/Chip"; @@ -23,7 +23,7 @@ const sizes = { } as const; const MessageInput = styled.div<{ - disabled: Required<PromptInputPropsType>["disabled"]; + disabled: Required<MessageInputProps>["disabled"]; error: boolean; focus: boolean; hasFiles?: boolean; @@ -132,7 +132,7 @@ const DxcMessageInput = ({ size = "medium", tabIndex, value, -}: PromptInputPropsType) => { +}: MessageInputProps) => { const languageContext = use(HalstackLanguageContext); const translatedLabels = languageContext.labels; const locale = languageContext.locale ?? "en-US"; diff --git a/packages/lib/src/message-input/types.ts b/packages/lib/src/message-input/types.ts index a6a49969bf..7ae9db1d01 100644 --- a/packages/lib/src/message-input/types.ts +++ b/packages/lib/src/message-input/types.ts @@ -5,7 +5,7 @@ export type SelectOption = { selected?: boolean; }; -type Props = { +export type MessageInputProps = { /** * If true, the voice recording button will be shown. */ @@ -106,4 +106,4 @@ type Props = { value?: string; }; -export default Props; +export type { MessageInputProps as default }; diff --git a/packages/lib/src/nav-tabs/NavTabs.tsx b/packages/lib/src/nav-tabs/NavTabs.tsx index 00a823c740..227b6b1112 100644 --- a/packages/lib/src/nav-tabs/NavTabs.tsx +++ b/packages/lib/src/nav-tabs/NavTabs.tsx @@ -1,6 +1,6 @@ import { JSX, Children, KeyboardEvent, useMemo, useState } from "react"; import styled from "@emotion/styled"; -import NavTabsPropsType from "./types"; +import { NavTabsProps } from "./types"; import Tab from "./Tab"; import NavTabsContext from "./NavTabsContext"; import { getLabelFromTab, getPropInChild, getPreviousTabIndex, getNextTabIndex } from "./utils"; @@ -20,7 +20,7 @@ const Underline = styled.div` width: 100%; `; -const DxcNavTabs = ({ iconPosition = "left", tabIndex = 0, children }: NavTabsPropsType): JSX.Element => { +const DxcNavTabs = ({ iconPosition = "left", tabIndex = 0, children }: NavTabsProps): JSX.Element => { const [innerFocusIndex, setInnerFocusIndex] = useState<number | null>(null); const childArray = Children.toArray(children).filter((child) => typeof child === "object" && "props" in child); diff --git a/packages/lib/src/nav-tabs/Tab.tsx b/packages/lib/src/nav-tabs/Tab.tsx index ac4f76b96e..b33fb1261c 100644 --- a/packages/lib/src/nav-tabs/Tab.tsx +++ b/packages/lib/src/nav-tabs/Tab.tsx @@ -2,7 +2,7 @@ import { useEffect, use, useRef, useImperativeHandle, KeyboardEvent } from "reac import styled from "@emotion/styled"; import DxcBadge from "../badge/Badge"; import DxcFlex from "../flex/Flex"; -import NavTabsPropsType, { TabProps } from "./types"; +import { NavTabsProps, NavTabsTabProps } from "./types"; import NavTabsContext from "./NavTabsContext"; import DxcIcon from "../icon/Icon"; import DxcInset from "../inset/Inset"; @@ -15,8 +15,8 @@ const TabContainer = styled.div` const TabLink = styled.div< { - disabled: TabProps["disabled"]; - iconPosition: NavTabsPropsType["iconPosition"]; + disabled: NavTabsTabProps["disabled"]; + iconPosition: NavTabsProps["iconPosition"]; } & React.AnchorHTMLAttributes<HTMLAnchorElement> >` box-sizing: border-box; @@ -51,7 +51,7 @@ const TabLink = styled.div< `; const Label = styled.span<{ - disabled: TabProps["disabled"]; + disabled: NavTabsTabProps["disabled"]; }>` display: inline; color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; @@ -65,7 +65,7 @@ const Label = styled.span<{ `; const IconContainer = styled.div<{ - disabled: TabProps["disabled"]; + disabled: NavTabsTabProps["disabled"]; }>` display: flex; color: ${({ disabled }) => (disabled ? "var(--color-fg-neutral-medium)" : "var(--color-fg-neutral-stronger)")}; @@ -76,7 +76,7 @@ const IconContainer = styled.div<{ } `; -const Underline = styled.span<{ active: TabProps["active"] }>` +const Underline = styled.span<{ active: NavTabsTabProps["active"] }>` position: absolute; left: 0; bottom: 0; @@ -96,7 +96,7 @@ const Tab = ({ onClick, ref, ...otherProps -}: TabProps) => { +}: NavTabsTabProps) => { const { iconPosition, tabIndex, focusedLabel } = use(NavTabsContext) ?? {}; const tabRef = useRef<HTMLAnchorElement | HTMLDivElement | null>(null); const innerRef = useRef<HTMLAnchorElement | HTMLDivElement | null>(null); diff --git a/packages/lib/src/nav-tabs/types.ts b/packages/lib/src/nav-tabs/types.ts index 583624fa46..a80a305f9d 100644 --- a/packages/lib/src/nav-tabs/types.ts +++ b/packages/lib/src/nav-tabs/types.ts @@ -1,5 +1,5 @@ import { ReactNode } from "react"; -import { SVG } from "../common/utils"; +import { SVG } from "../common/types"; export type NavTabsContextProps = { focusedLabel: string | undefined; @@ -7,7 +7,7 @@ export type NavTabsContextProps = { tabIndex: number; }; -export type TabProps = { +type NavTabsTabProps = { /** * Whether the tab is active or not. */ @@ -46,7 +46,7 @@ export type TabProps = { ref?: React.Ref<HTMLAnchorElement | HTMLDivElement>; }; -type Props = { +type NavTabsProps = { /** * Contains one or more DxcNavTabs.Tab. */ @@ -61,4 +61,4 @@ type Props = { tabIndex?: number; }; -export default Props; +export type { NavTabsProps as default, NavTabsProps, NavTabsTabProps }; diff --git a/packages/lib/src/navigation-tree/NavigationTree.tsx b/packages/lib/src/navigation-tree/NavigationTree.tsx index 9af732ae3d..b04be61180 100644 --- a/packages/lib/src/navigation-tree/NavigationTree.tsx +++ b/packages/lib/src/navigation-tree/NavigationTree.tsx @@ -1,7 +1,7 @@ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import styled from "@emotion/styled"; import MenuItem from "../base-menu/MenuItem"; -import NavigationTreePropsType, { GroupItemWithId, ItemWithId, SectionWithId } from "./types"; +import NavigationTreeProps, { BaseGroupItemWithId, BaseItemWithId, BaseSectionWithId } from "./types"; import Section from "../base-menu/Section"; import NavigationTreeContext from "../base-menu/BaseMenuContext"; import scrollbarStyles from "../styles/scroll"; @@ -35,7 +35,7 @@ export default function DxcNavigationTree({ hasPopOver = false, isHorizontal = false, onSelectItem, -}: NavigationTreePropsType) { +}: NavigationTreeProps) { const [firstUpdate, setFirstUpdate] = useState(true); const [selectedItemId, setSelectedItemId] = useState(-1); const NavigationTreeRef = useRef<HTMLDivElement | null>(null); @@ -78,12 +78,12 @@ export default function DxcNavigationTree({ <NavigationTreeContainer displayBorder={displayBorder} ref={NavigationTreeRef}> <NavigationTreeContext value={contextValue}> {itemsWithId[0] && isSection(itemsWithId[0]) ? ( - (itemsWithId as SectionWithId[]).map((item, index) => ( + (itemsWithId as BaseSectionWithId[]).map((item, index) => ( <Section key={`section-${index}`} section={item} index={index} length={itemsWithId.length} /> )) ) : ( <SubMenu isHorizontal={isHorizontal}> - {(itemsWithId as (GroupItemWithId | ItemWithId)[]).map((item, index) => ( + {(itemsWithId as (BaseGroupItemWithId | BaseItemWithId)[]).map((item, index) => ( <MenuItem item={item} key={`${item.label}-${index}`} /> ))} </SubMenu> diff --git a/packages/lib/src/navigation-tree/types.ts b/packages/lib/src/navigation-tree/types.ts index 9afb437531..495723f820 100644 --- a/packages/lib/src/navigation-tree/types.ts +++ b/packages/lib/src/navigation-tree/types.ts @@ -1,32 +1,33 @@ -import Props, { +import { + BaseMenuProps, BaseMenuContextProps as NavigationTreeContextProps, - GroupItem, - GroupItemProps, - GroupItemWithId, - Item, - ItemActionProps, - ItemWithId, - SubMenuProps, - MenuItemProps, - Section, - SectionWithId, - SectionProps, - SingleItemProps, + BaseGroupItem, + BaseGroupItemProps, + BaseGroupItemWithId, + BaseItem, + BaseItemActionProps, + BaseItemWithId, + BaseSubMenuProps, + BaseMenuItemProps, + BaseSection, + BaseSectionWithId, + BaseSectionProps, + BaseSingleItemProps, } from "../base-menu/types"; export type { - GroupItem, - GroupItemProps, - GroupItemWithId, - Item, - ItemActionProps, - ItemWithId, - SubMenuProps, - MenuItemProps, + BaseGroupItem, + BaseGroupItemProps, + BaseGroupItemWithId, + BaseItem, + BaseItemActionProps, + BaseItemWithId, + BaseSubMenuProps, + BaseMenuItemProps, NavigationTreeContextProps, - Section, - SectionWithId, - SectionProps, - SingleItemProps, - Props as default, + BaseSection, + BaseSectionWithId, + BaseSectionProps, + BaseSingleItemProps, + BaseMenuProps as default, }; diff --git a/packages/lib/src/number-input/NumberInput.tsx b/packages/lib/src/number-input/NumberInput.tsx index 1ee3d71990..d636e4f551 100644 --- a/packages/lib/src/number-input/NumberInput.tsx +++ b/packages/lib/src/number-input/NumberInput.tsx @@ -1,10 +1,10 @@ import { useEffect, useMemo, useRef } from "react"; import styled from "@emotion/styled"; import DxcTextInput from "../text-input/TextInput"; -import NumberInputPropsType from "./types"; +import { NumberInputProps } from "./types"; import NumberInputContext from "./NumberInputContext"; -const NumberInputContainer = styled.div<{ size: NumberInputPropsType["size"] }>` +const NumberInputContainer = styled.div<{ size: NumberInputProps["size"] }>` ${({ size }) => size === "fillParent" && "width: 100%;"} // Chrome, Safari, Edge, Opera @@ -45,7 +45,7 @@ const DxcNumberInput = ({ suffix, tabIndex, value, -}: NumberInputPropsType) => { +}: NumberInputProps) => { const numberInputRef = useRef<HTMLInputElement | null>(null); const contextValue = useMemo( diff --git a/packages/lib/src/number-input/types.ts b/packages/lib/src/number-input/types.ts index 916aba19cd..8aad68e49d 100644 --- a/packages/lib/src/number-input/types.ts +++ b/packages/lib/src/number-input/types.ts @@ -1,11 +1,11 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; /** * Reference to the component. */ export type RefType = React.Ref<HTMLInputElement>; -type Props = { +export type NumberInputProps = { /** * Text to be placed above the number. */ @@ -131,11 +131,11 @@ type Props = { }; export type NumberInputContextProps = { - maxNumber: Props["max"]; - minNumber: Props["min"]; - showControls: Props["showControls"]; - stepNumber: Props["step"]; + maxNumber: NumberInputProps["max"]; + minNumber: NumberInputProps["min"]; + showControls: NumberInputProps["showControls"]; + stepNumber: NumberInputProps["step"]; typeNumber?: string; }; -export default Props; +export type { NumberInputProps as default }; diff --git a/packages/lib/src/paginator/types.ts b/packages/lib/src/paginator/types.ts index d213d66c44..3f64b3b6e5 100644 --- a/packages/lib/src/paginator/types.ts +++ b/packages/lib/src/paginator/types.ts @@ -1,4 +1,4 @@ -type Props = { +export type PaginatorProps = { /** * Number of the current selected page. */ @@ -36,4 +36,4 @@ type Props = { tabIndex?: number; }; -export default Props; +export type { PaginatorProps as default }; diff --git a/packages/lib/src/password-input/PasswordInput.tsx b/packages/lib/src/password-input/PasswordInput.tsx index d3d156d38e..e2becd2f04 100644 --- a/packages/lib/src/password-input/PasswordInput.tsx +++ b/packages/lib/src/password-input/PasswordInput.tsx @@ -1,11 +1,11 @@ import { use, useLayoutEffect, useRef, useState } from "react"; import styled from "@emotion/styled"; import DxcTextInput from "../text-input/TextInput"; -import PasswordInputPropsType from "./types"; +import { PasswordInputProps } from "./types"; import { HalstackLanguageContext } from "../HalstackContext"; const PasswordInput = styled.div<{ - size: PasswordInputPropsType["size"]; + size: PasswordInputProps["size"]; isPasswordVisible: boolean; }>` ${(props) => props.size === "fillParent" && "width: 100%;"} @@ -35,7 +35,7 @@ const DxcPasswordInput = ({ tabIndex = 0, ariaLabel = "Password input", ref, -}: PasswordInputPropsType) => { +}: PasswordInputProps) => { const [isPasswordVisible, setIsPasswordVisible] = useState(false); const containerRef = useRef<HTMLInputElement | null>(null); const { passwordInput } = use(HalstackLanguageContext).labels; diff --git a/packages/lib/src/password-input/types.ts b/packages/lib/src/password-input/types.ts index 910fb44c06..edb97ad309 100644 --- a/packages/lib/src/password-input/types.ts +++ b/packages/lib/src/password-input/types.ts @@ -1,11 +1,11 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; /** * Reference to the component. */ export type RefType = React.Ref<HTMLDivElement>; -type Props = { +export type PasswordInputProps = { /** * Specifies a string to be used as the name for the password input element when no `label` is provided. */ @@ -107,4 +107,4 @@ type Props = { value?: string; }; -export default Props; +export type { PasswordInputProps as default }; diff --git a/packages/lib/src/popover/Popover.tsx b/packages/lib/src/popover/Popover.tsx index 464c7537b5..ec97dae980 100644 --- a/packages/lib/src/popover/Popover.tsx +++ b/packages/lib/src/popover/Popover.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; import { JSX, useEffect, useId, useRef, useState } from "react"; import * as Popover from "@radix-ui/react-popover"; -import { PopoverPropsType } from "./types"; +import { PopoverProps } from "./types"; const PopoverWrapper = styled.div` width: fit-content; @@ -44,7 +44,7 @@ const DxcPopover = ({ onCloseAutoFocus, popoverContent, side = "bottom", -}: PopoverPropsType): JSX.Element => { +}: PopoverProps): JSX.Element => { const popOverId = `popover-${useId()}`; const isControlled = useRef(isOpen !== undefined); diff --git a/packages/lib/src/popover/types.ts b/packages/lib/src/popover/types.ts index 999ae1ed85..20a2385cdc 100644 --- a/packages/lib/src/popover/types.ts +++ b/packages/lib/src/popover/types.ts @@ -1,4 +1,4 @@ -export type PopoverPropsType = { +export type PopoverProps = { /** Action that triggers the popover to open. */ actionToOpen?: "click" | "hover"; /** Alignment of the popover relative to the trigger element. */ @@ -29,3 +29,5 @@ export type PopoverPropsType = { /** Side of the trigger where the popover will appear. */ side?: "top" | "bottom" | "left" | "right"; }; + +export type { PopoverProps as default }; diff --git a/packages/lib/src/progress-bar/ProgressBar.tsx b/packages/lib/src/progress-bar/ProgressBar.tsx index 0af5b55c31..8b987dec74 100644 --- a/packages/lib/src/progress-bar/ProgressBar.tsx +++ b/packages/lib/src/progress-bar/ProgressBar.tsx @@ -1,12 +1,12 @@ import { JSX, useEffect, useId, useState } from "react"; import styled from "@emotion/styled"; import { spaces } from "../common/variables"; -import ProgressBarPropsType from "./types"; +import { ProgressBarProps } from "./types"; import DxcFlex from "../flex/Flex"; import { auxTextStyles, labelTextStyles, textColorStyles } from "./utils"; const ProgressBarContainer = styled.div<{ - overlay: ProgressBarPropsType["overlay"]; + overlay: ProgressBarProps["overlay"]; }>` display: flex; flex-wrap: wrap; @@ -33,8 +33,8 @@ const Overlay = styled.div` `; const MainContainer = styled.div<{ - overlay: ProgressBarPropsType["overlay"]; - margin: ProgressBarPropsType["margin"]; + overlay: ProgressBarProps["overlay"]; + margin: ProgressBarProps["margin"]; }>` width: ${(props) => (props.overlay ? "80%" : "100%")}; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; @@ -53,7 +53,7 @@ const MainContainer = styled.div<{ `; const ProgressBarLabel = styled.div<{ - overlay: ProgressBarPropsType["overlay"]; + overlay: ProgressBarProps["overlay"]; }>` ${labelTextStyles}; ${(props) => textColorStyles(props.overlay)}; @@ -64,21 +64,21 @@ const ProgressBarLabel = styled.div<{ `; const ProgressBarProgress = styled.div<{ - overlay: ProgressBarPropsType["overlay"]; + overlay: ProgressBarProps["overlay"]; }>` ${auxTextStyles}; ${(props) => textColorStyles(props.overlay)}; flex-shrink: 0; `; -const HelperText = styled.span<{ overlay: ProgressBarPropsType["overlay"] }>` +const HelperText = styled.span<{ overlay: ProgressBarProps["overlay"] }>` ${(props) => textColorStyles(props.overlay)}; ${auxTextStyles}; `; const LinearProgress = styled.div<{ - helperText: ProgressBarPropsType["helperText"]; - overlay: ProgressBarPropsType["overlay"]; + helperText: ProgressBarProps["helperText"]; + overlay: ProgressBarProps["overlay"]; }>` position: relative; border-radius: var(--border-radius-m); @@ -88,9 +88,9 @@ const LinearProgress = styled.div<{ `; const LinearProgressBar = styled.span<{ - overlay: ProgressBarPropsType["overlay"]; + overlay: ProgressBarProps["overlay"]; variant: "determinate" | "indeterminate"; - value: ProgressBarPropsType["value"]; + value: ProgressBarProps["value"]; }>` position: absolute; top: 0; @@ -145,7 +145,7 @@ const DxcProgressBar = ({ showValue, margin, ariaLabel = "Progress bar", -}: ProgressBarPropsType): JSX.Element => { +}: ProgressBarProps): JSX.Element => { const labelId = `label-${useId()}`; const [innerValue, setInnerValue] = useState<number | undefined>(); diff --git a/packages/lib/src/progress-bar/types.ts b/packages/lib/src/progress-bar/types.ts index daa4a988d2..0faea7c855 100644 --- a/packages/lib/src/progress-bar/types.ts +++ b/packages/lib/src/progress-bar/types.ts @@ -1,13 +1,6 @@ -import { Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; -type Size = { - top?: Space; - bottom?: Space; - left?: Space; - right?: Space; -}; - -type Props = { +export type ProgressBarProps = { /** * Text to be placed above the progress bar. */ @@ -34,11 +27,11 @@ type Props = { * an object with 'top', 'bottom', 'left' and 'right' properties * in order to specify different margin sizes. */ - margin?: Space | Size; + margin?: Space | Margin; /** * Specifies a string to be used as the name for the progress bar element when no `label` is provided. */ ariaLabel?: string; }; -export default Props; +export type { ProgressBarProps as default }; diff --git a/packages/lib/src/quick-nav/QuickNav.tsx b/packages/lib/src/quick-nav/QuickNav.tsx index 5e322e1cad..3184c1f0b2 100644 --- a/packages/lib/src/quick-nav/QuickNav.tsx +++ b/packages/lib/src/quick-nav/QuickNav.tsx @@ -3,7 +3,7 @@ import slugify from "slugify"; import styled from "@emotion/styled"; import DxcHeading from "../heading/Heading"; import { HalstackLanguageContext } from "../HalstackContext"; -import QuickNavTypes from "./types"; +import { QuickNavProps } from "./types"; const QuickNavContainer = styled.div` display: flex; @@ -59,7 +59,7 @@ const Link = styled.a` } `; -export default function DxcQuickNav({ links, title }: QuickNavTypes) { +export default function DxcQuickNav({ links, title }: QuickNavProps) { const translatedLabels = use(HalstackLanguageContext).labels; const isHashRouter = (): boolean => { if (typeof window === "undefined") return false; diff --git a/packages/lib/src/quick-nav/types.ts b/packages/lib/src/quick-nav/types.ts index a6c061dc46..5dec437cbf 100644 --- a/packages/lib/src/quick-nav/types.ts +++ b/packages/lib/src/quick-nav/types.ts @@ -1,4 +1,4 @@ -type Link = { +export type QuickNavLink = { /** * Label to be shown in the link. */ @@ -6,10 +6,10 @@ type Link = { /** * Sublinks of the link. */ - links?: Link[]; + links?: QuickNavLink[]; }; -type Props = { +export type QuickNavProps = { /** * Title of the quick nav component. */ @@ -17,7 +17,7 @@ type Props = { /** * Links to be shown inside the quick nav component. */ - links: Link[]; + links: QuickNavLink[]; }; -export default Props; +export type { QuickNavProps as default }; diff --git a/packages/lib/src/radio-group/RadioGroup.tsx b/packages/lib/src/radio-group/RadioGroup.tsx index 5be76345bd..671cb0a712 100644 --- a/packages/lib/src/radio-group/RadioGroup.tsx +++ b/packages/lib/src/radio-group/RadioGroup.tsx @@ -2,7 +2,7 @@ import { FocusEvent, KeyboardEvent, useCallback, use, useId, useMemo, useState } import styled from "@emotion/styled"; import { HalstackLanguageContext } from "../HalstackContext"; import RadioInput from "./RadioInput"; -import RadioGroupPropsType from "./types"; +import { RadioGroupProps } from "./types"; import Label from "../styles/forms/Label"; import HelperText from "../styles/forms/HelperText"; import ErrorMessage from "../styles/forms/ErrorMessage"; @@ -13,7 +13,7 @@ const RadioGroupContainer = styled.div` flex-direction: column; `; -const RadioGroup = styled.div<{ stacking: RadioGroupPropsType["stacking"] }>` +const RadioGroup = styled.div<{ stacking: RadioGroupProps["stacking"] }>` display: flex; flex-wrap: wrap; flex-direction: ${({ stacking }) => stacking}; @@ -39,7 +39,7 @@ const DxcRadioGroup = ({ stacking = "column", tabIndex = 0, value, -}: RadioGroupPropsType) => { +}: RadioGroupProps) => { const id = `radio-group-${useId()}`; const labelId = `label-${id}`; const errorId = `error-${id}`; diff --git a/packages/lib/src/radio-group/types.ts b/packages/lib/src/radio-group/types.ts index 4a262d9262..894c5e319e 100644 --- a/packages/lib/src/radio-group/types.ts +++ b/packages/lib/src/radio-group/types.ts @@ -3,7 +3,7 @@ */ export type RefType = React.Ref<HTMLDivElement>; -type Option = { +type RadioGroupOption = { /** * Label of the option placed next to the radio input. */ @@ -20,7 +20,7 @@ type Option = { disabled?: boolean; }; -type RadioGroupProps = { +export type RadioGroupProps = { /** * Specifies a string to be used as the name for the radio group when no `label` is provided. */ @@ -70,7 +70,7 @@ type RadioGroupProps = { /** * An array of objects representing the selectable options. */ - options: Option[]; + options: RadioGroupOption[]; /** * This function will be called when the radio group loses the focus. An * object including the value and the error will be passed to this @@ -120,4 +120,4 @@ export type RadioInputProps = { tabIndex: number; }; -export default RadioGroupProps; +export type { RadioGroupProps as default }; diff --git a/packages/lib/src/resultset-table/types.ts b/packages/lib/src/resultset-table/types.ts index 766092b967..0f02252b97 100644 --- a/packages/lib/src/resultset-table/types.ts +++ b/packages/lib/src/resultset-table/types.ts @@ -1,5 +1,5 @@ import { ReactNode } from "react"; -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; export type Column = { /** diff --git a/packages/lib/src/select/types.ts b/packages/lib/src/select/types.ts index ae2759a700..3157898de0 100644 --- a/packages/lib/src/select/types.ts +++ b/packages/lib/src/select/types.ts @@ -1,5 +1,5 @@ import { CSSProperties } from "react"; -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; /** * Reference to the select component. diff --git a/packages/lib/src/sidenav/Sidenav.tsx b/packages/lib/src/sidenav/Sidenav.tsx index 6d6bf12069..3ee2bc87bf 100644 --- a/packages/lib/src/sidenav/Sidenav.tsx +++ b/packages/lib/src/sidenav/Sidenav.tsx @@ -1,6 +1,6 @@ import styled from "@emotion/styled"; import DxcFlex from "../flex/Flex"; -import SidenavPropsType from "./types"; +import { SidenavProps } from "./types"; import DxcDivider from "../divider/Divider"; import DxcButton from "../button/Button"; import DxcImage from "../image/Image"; @@ -102,7 +102,7 @@ const DxcSidenav = ({ defaultExpanded, onExpandedChange, searchBar, -}: SidenavPropsType): JSX.Element => { +}: SidenavProps): JSX.Element => { const isBelowLarge = useBreakpoint("large"); const isBelowMedium = useBreakpoint("medium"); const { logo, headerExists, setHideMainContent } = use(ApplicationLayoutContext); diff --git a/packages/lib/src/sidenav/types.ts b/packages/lib/src/sidenav/types.ts index 460ee830a5..7a762220f1 100644 --- a/packages/lib/src/sidenav/types.ts +++ b/packages/lib/src/sidenav/types.ts @@ -1,12 +1,12 @@ import { ReactNode } from "react"; import { SearchBarProps } from "../search-bar/types"; -import { GroupItem, Item } from "../base-menu/types"; +import { BaseGroupItem, BaseItem } from "../base-menu/types"; -type Section = { items: (Item | GroupItem)[]; title?: string }; +export type SidenavSection = { items: (BaseItem | BaseGroupItem)[]; title?: string }; -type SearchbarSidenavProps = Omit<SearchBarProps, "autoFocus" | "disabled" | "onCancel">; +export type SidenavSearchbarProps = Omit<SearchBarProps, "autoFocus" | "disabled" | "onCancel">; -type Props = { +export type SidenavProps = { /** * The content rendered in the bottom part of the sidenav, under the navigation menu. */ @@ -32,7 +32,7 @@ type Props = { * Array of items to be displayed in the navigation menu. * Each item can be a single/simple item, a group item or a section. */ - navItems?: (Item | GroupItem)[] | Section[]; + navItems?: (BaseItem | BaseGroupItem)[] | SidenavSection[]; /** * Function called when the expansion state of the sidenav changes. */ @@ -40,11 +40,11 @@ type Props = { /** * When provided, a search bar will be rendered at the top of the sidenav. */ - searchBar?: SearchbarSidenavProps; + searchBar?: SidenavSearchbarProps; /** * The additional content rendered in the upper part of the sidenav, under the branding. */ topContent?: ReactNode; }; -export default Props; +export type { SidenavProps as default }; diff --git a/packages/lib/src/slider/types.ts b/packages/lib/src/slider/types.ts index 16f93d42d2..5cd03af39d 100644 --- a/packages/lib/src/slider/types.ts +++ b/packages/lib/src/slider/types.ts @@ -1,4 +1,4 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; /** * Reference to the component. diff --git a/packages/lib/src/spinner/types.ts b/packages/lib/src/spinner/types.ts index 129d70d81c..37f66f8aa8 100644 --- a/packages/lib/src/spinner/types.ts +++ b/packages/lib/src/spinner/types.ts @@ -1,4 +1,4 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; type Props = { /** diff --git a/packages/lib/src/switch/types.ts b/packages/lib/src/switch/types.ts index a731e8853d..babff51519 100644 --- a/packages/lib/src/switch/types.ts +++ b/packages/lib/src/switch/types.ts @@ -1,4 +1,4 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; /** * Reference to the component. diff --git a/packages/lib/src/table/types.ts b/packages/lib/src/table/types.ts index 4152ab4963..af2a478784 100644 --- a/packages/lib/src/table/types.ts +++ b/packages/lib/src/table/types.ts @@ -1,5 +1,5 @@ import { ReactNode } from "react"; -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; import { Option } from "../dropdown/types"; type BaseActionCell = { diff --git a/packages/lib/src/tabs/types.ts b/packages/lib/src/tabs/types.ts index 9322e5844a..ba6fd7decc 100644 --- a/packages/lib/src/tabs/types.ts +++ b/packages/lib/src/tabs/types.ts @@ -1,6 +1,6 @@ import { ReactNode } from "react"; -import type { Space, Margin, SVG } from "../common/utils"; +import type { Space, Margin, SVG } from "../common/types"; export type TabsContextProps = { activeTabId?: string; diff --git a/packages/lib/src/text-input/types.ts b/packages/lib/src/text-input/types.ts index 0670261b6f..e83a29a0c7 100644 --- a/packages/lib/src/text-input/types.ts +++ b/packages/lib/src/text-input/types.ts @@ -1,5 +1,5 @@ import { JSX, CSSProperties, ReactNode } from "react"; -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; type Action = { /** diff --git a/packages/lib/src/textarea/types.ts b/packages/lib/src/textarea/types.ts index db5d747c34..102fe716d5 100644 --- a/packages/lib/src/textarea/types.ts +++ b/packages/lib/src/textarea/types.ts @@ -1,4 +1,4 @@ -import { Margin, Space } from "../common/utils"; +import { Margin, Space } from "../common/types"; /** * Reference to the component. diff --git a/packages/lib/src/toast/types.ts b/packages/lib/src/toast/types.ts index c38c156070..5fdb7363db 100644 --- a/packages/lib/src/toast/types.ts +++ b/packages/lib/src/toast/types.ts @@ -1,5 +1,5 @@ import { ReactNode } from "react"; -import { SVG } from "../common/utils"; +import { SVG } from "../common/types"; type Action = { /** diff --git a/packages/lib/src/toggle-group/types.ts b/packages/lib/src/toggle-group/types.ts index fe055c35f4..f8ddf92056 100644 --- a/packages/lib/src/toggle-group/types.ts +++ b/packages/lib/src/toggle-group/types.ts @@ -1,4 +1,4 @@ -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; type OptionIcon = { /** diff --git a/packages/lib/src/wizard/types.ts b/packages/lib/src/wizard/types.ts index 074edb1d3e..97621ea1f2 100644 --- a/packages/lib/src/wizard/types.ts +++ b/packages/lib/src/wizard/types.ts @@ -1,4 +1,4 @@ -import { Margin, SVG, Space } from "../common/utils"; +import { Margin, SVG, Space } from "../common/types"; export type StepProps = { /**