From d4337bea1d59aa00213169e71cf5783a38f88d24 Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 26 Apr 2024 10:03:52 -0400 Subject: [PATCH 01/13] chore: Updating the comment style so that the comment shows up in LSP. --- packages/paste-core/components/button/src/Button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/paste-core/components/button/src/Button.tsx b/packages/paste-core/components/button/src/Button.tsx index bb92720f8f..391ff1b651 100644 --- a/packages/paste-core/components/button/src/Button.tsx +++ b/packages/paste-core/components/button/src/Button.tsx @@ -29,7 +29,7 @@ import type { const AnimatedBox = animated(Box); -/* +/** * If size isn't passed, come up with a smart default: * - 'reset' for variant 'link' * - 'icon' if there's 1 child that's an icon From 9f7500577e790aae97a282c5e426ccd6604391d5 Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 26 Apr 2024 10:36:34 -0400 Subject: [PATCH 02/13] feat: Adding JSDoc to make usage of the component more transparent. Including some information about accessibility concerns over variants. --- .../components/button/src/Button.tsx | 24 ++++++++++++++ .../paste-core/components/button/src/types.ts | 32 +++++++++++++++---- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/packages/paste-core/components/button/src/Button.tsx b/packages/paste-core/components/button/src/Button.tsx index 391ff1b651..3639c51441 100644 --- a/packages/paste-core/components/button/src/Button.tsx +++ b/packages/paste-core/components/button/src/Button.tsx @@ -57,6 +57,13 @@ const getButtonSize = (variant: ButtonVariants, children: React.ReactNode, size? return smartSize; }; +/** + * Determine the button state based on if it is disabled or loading. + * + * @param disabled - If the button is disabled. + * @param loading - If the button is loading. + * @returns The button state. + */ const getButtonState = (disabled?: boolean, loading?: boolean): ButtonStates => { if (disabled) { return "disabled"; @@ -129,6 +136,9 @@ const handlePropValidation = ({ const variantsWithoutBoundingBox = new Set(["link", "destructive_link", "inverse_link", "reset"]); +/** + * Display the inner content of the button. + */ const ButtonContents: React.FC> = ({ buttonState, children, @@ -173,6 +183,14 @@ const ButtonContents: React.FC> = ( ButtonContents.displayName = "ButtonContents"; +/** + * Determine which of the button components should be used based on variant. + * + * @description This is a button factory. + * + * @param variant - The variant of the button. + * @returns The button component. + */ const getButtonComponent = ( variant: ButtonVariants, ): React.ForwardRefExoticComponent> => { @@ -206,6 +224,12 @@ const getButtonComponent = ( }; // memo +/** + * Paste buttton component. + * + * @link https://paste.twilio.design/components/button + * @see https://paste.twilio.design/components/button#button-vs-anchor-link + */ const Button = React.forwardRef( ({ element = "BUTTON", i18nExternalLinkLabel = "(link takes you to an external page)", ...props }, ref) => { const { size, variant, children, disabled, loading, ...rest } = props; diff --git a/packages/paste-core/components/button/src/types.ts b/packages/paste-core/components/button/src/types.ts index 317cf3537d..f95cee458a 100644 --- a/packages/paste-core/components/button/src/types.ts +++ b/packages/paste-core/components/button/src/types.ts @@ -1,4 +1,4 @@ -import type { BoxProps, BoxStyleProps } from "@twilio-paste/box"; +import type { BoxProps } from "@twilio-paste/box"; import type { HTMLPasteProps } from "@twilio-paste/types"; type ButtonTypes = "submit" | "button" | "reset"; @@ -11,6 +11,11 @@ export type ButtonSizes = | "rounded_small" | "circle" | "circle_small"; +/** + * Base Button variants. [Avoid using link variants when possible.](https://paste.twilio.design/components/button#button-vs-anchor-link) + * + * @summary List of all of the differnt button appearances minus reset. + */ type ButtonBaseVariants = | "primary" | "primary_icon" @@ -24,13 +29,23 @@ type ButtonBaseVariants = | "inverse_link" | "inverse"; type ButtonResetVariant = "reset"; +/** + * All Button variants. Includes reset. [Avoid using link variants when possible.](https://paste.twilio.design/components/button#button-vs-anchor-link) + * + * @summary List of all of the differnt button appearances. + */ export type ButtonVariants = ButtonResetVariant | ButtonBaseVariants; +/** The various states of interactivity for the button. */ export type ButtonStates = "disabled" | "loading" | "default"; export type ButtonTabIndexes = 0 | -1; + export interface ButtonContentsProps { + /** The various states of interactivity for the button. */ buttonState: ButtonStates; + /** Is is the button in a loading state. */ showLoading: boolean; + /** Different kind of button variants */ variant?: ButtonVariants; } @@ -40,6 +55,7 @@ export interface DirectButtonProps extends HTMLPasteProps<"button"> { * @default 'button' */ as?: keyof JSX.IntrinsicElements; + /** The various states of interactivity for the button. */ buttonState: ButtonStates; children: React.ReactNode; /** @@ -82,16 +98,18 @@ export interface DirectButtonProps extends HTMLPasteProps<"button"> { */ type?: ButtonTypes; /** + * The different appearance variants for a button. [Avoid using link variants when possible.](https://paste.twilio.design/components/button#button-vs-anchor-link) + * * @default 'primary' */ variant: ButtonVariants; } -type BaseVariantsButtonProps = { - variant?: ButtonBaseVariants; -}; -type ResetVariantButtonProps = Omit & { - variant?: ButtonResetVariant; +type VariantsButtonProps = { + /** + * The different appearance variants for a button. [Avoid using link variants when possible.](https://paste.twilio.design/components/button#button-vs-anchor-link) + */ + variant?: ButtonBaseVariants | ButtonResetVariant; }; export type ButtonProps = Omit & { @@ -109,4 +127,4 @@ export type ButtonProps = Omit Date: Fri, 26 Apr 2024 10:46:44 -0400 Subject: [PATCH 03/13] fix: Removing deprecated defaultProps in favor of destructuring. --- .../components/button/src/Button.tsx | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/packages/paste-core/components/button/src/Button.tsx b/packages/paste-core/components/button/src/Button.tsx index 3639c51441..a67d7007aa 100644 --- a/packages/paste-core/components/button/src/Button.tsx +++ b/packages/paste-core/components/button/src/Button.tsx @@ -74,6 +74,11 @@ const getButtonState = (disabled?: boolean, loading?: boolean): ButtonStates => return "default"; }; +/** + * Validation ensuring the button is not being used in an inaccessible way. + * + * @throws Error if the button is being used in an inaccessible way. + */ const handlePropValidation = ({ as, href, @@ -227,12 +232,22 @@ const getButtonComponent = ( /** * Paste buttton component. * - * @link https://paste.twilio.design/components/button - * @see https://paste.twilio.design/components/button#button-vs-anchor-link + * @link [PasteButton](https://paste.twilio.design/components/button) + * @see [Accessiblity](https://paste.twilio.design/components/button#button-vs-anchor-link) */ const Button = React.forwardRef( - ({ element = "BUTTON", i18nExternalLinkLabel = "(link takes you to an external page)", ...props }, ref) => { - const { size, variant, children, disabled, loading, ...rest } = props; + ({ + element = "BUTTON", + i18nExternalLinkLabel = "(link takes you to an external page)", + as = 'button', + fullWidth = false, + disabled = false, + loading = false, + type = 'button', + variant = 'primary', + ...props + }, ref) => { + const { size, children, ...rest } = props; const [hovered, setHovered] = React.useState(false); const arrowIconStyles = useSpring({ translateX: hovered ? "4px" : "0px", @@ -247,7 +262,16 @@ const Button = React.forwardRef( return getButtonSize(variant, children, size); }, [size, variant, children]); - handlePropValidation({ ...props, size: smartDefaultSize }); + handlePropValidation({ + as, + fullWidth, + disabled, + loading, + type, + variant, + ...props, + size: smartDefaultSize + }); const buttonState = getButtonState(disabled, loading); const showLoading = buttonState === "loading"; @@ -257,7 +281,7 @@ const Button = React.forwardRef( // Automatically inject AnchorForwardIcon for link's dressed as buttons when possible let injectIconChildren = children; - if (props.as === "a" && props.href != null && typeof children === "string" && variant !== "reset") { + if (as === "a" && props.href != null && typeof children === "string" && variant !== "reset") { injectIconChildren = ( <> {children} @@ -304,15 +328,6 @@ const Button = React.forwardRef( }, ); -Button.defaultProps = { - as: "button", - fullWidth: false, - disabled: false, - loading: false, - type: "button", - variant: "primary", -}; - Button.displayName = "Button"; export type { ButtonProps }; From 91972408359d1e6b77adf1dd67ee2fb040a0565c Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Tue, 7 May 2024 15:58:06 -0400 Subject: [PATCH 04/13] feat: Adding changeset information. --- .changeset/gold-boats-explain.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/gold-boats-explain.md diff --git a/.changeset/gold-boats-explain.md b/.changeset/gold-boats-explain.md new file mode 100644 index 0000000000..270f4ebcd0 --- /dev/null +++ b/.changeset/gold-boats-explain.md @@ -0,0 +1,6 @@ +--- +"@twilio-paste/button": patch +"@twilio-paste/core": patch +--- + +Adding help text to the paste button component via JSDoc to ensure the design system guidance is accessible via the Language Server output. Minor updates to the syntax of the button component to modernize it. From da43c6091cc31708a6e7c566f5519b89b95fac7e Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 10:17:45 -0400 Subject: [PATCH 05/13] feat: Adding JSDoc to the AccountSwitcher components. --- .../components/account-switcher/src/AccountSwitcher.tsx | 5 +++++ .../components/account-switcher/src/AccountSwitcherBadge.tsx | 5 +++++ .../components/account-switcher/src/AccountSwitcherGroup.tsx | 5 +++++ .../components/account-switcher/src/AccountSwitcherItem.tsx | 5 +++++ .../account-switcher/src/AccountSwitcherItemRadio.tsx | 5 +++++ .../account-switcher/src/AccountSwitcherSeparator.tsx | 5 +++++ 6 files changed, 30 insertions(+) diff --git a/packages/paste-core/components/account-switcher/src/AccountSwitcher.tsx b/packages/paste-core/components/account-switcher/src/AccountSwitcher.tsx index d906c5efac..fdad9acfd3 100644 --- a/packages/paste-core/components/account-switcher/src/AccountSwitcher.tsx +++ b/packages/paste-core/components/account-switcher/src/AccountSwitcher.tsx @@ -15,6 +15,11 @@ export interface AccountSwitcherProps extends MenuProps { element?: BoxProps["element"]; } +/** + * An Account Switcher component is a stylized Menu Badge with a list of actions related to a user's accounts. + * + * @link [Account Switcher](https://paste.twilio.design/components/account-switcher) + */ const AccountSwitcher = React.forwardRef( ({ children, element = "ACCOUNT_SWITCHER", ...props }, ref) => { return ( diff --git a/packages/paste-core/components/account-switcher/src/AccountSwitcherBadge.tsx b/packages/paste-core/components/account-switcher/src/AccountSwitcherBadge.tsx index 2e8776cc82..1b46f9ae91 100644 --- a/packages/paste-core/components/account-switcher/src/AccountSwitcherBadge.tsx +++ b/packages/paste-core/components/account-switcher/src/AccountSwitcherBadge.tsx @@ -15,6 +15,11 @@ export interface AccountSwitcherBadgeProps extends Omit( ({ children, element = "ACCOUNT_SWITCHER_BADGE", ...props }, ref) => { return ( diff --git a/packages/paste-core/components/account-switcher/src/AccountSwitcherGroup.tsx b/packages/paste-core/components/account-switcher/src/AccountSwitcherGroup.tsx index b1aa43fc6b..ad5ca84b16 100644 --- a/packages/paste-core/components/account-switcher/src/AccountSwitcherGroup.tsx +++ b/packages/paste-core/components/account-switcher/src/AccountSwitcherGroup.tsx @@ -14,6 +14,11 @@ export interface AccountSwitcherGroupProps extends MenuGroupProps { element?: BoxProps["element"]; } +/** + * Used to group similar items together in the Account Switcher menu. An example of this might be a list of recent accounts. + * + * @link [Account Switcher Group](https://paste.twilio.design/components/account-switcher#account-switcher-group) + */ const AccountSwitcherGroup = React.forwardRef( ({ children, element = "ACCOUNT_SWITCHER_GROUP", label, ...props }, ref) => { return ( diff --git a/packages/paste-core/components/account-switcher/src/AccountSwitcherItem.tsx b/packages/paste-core/components/account-switcher/src/AccountSwitcherItem.tsx index a69383e4ae..e361c6468e 100644 --- a/packages/paste-core/components/account-switcher/src/AccountSwitcherItem.tsx +++ b/packages/paste-core/components/account-switcher/src/AccountSwitcherItem.tsx @@ -15,6 +15,11 @@ export interface AccountSwitcherItemProps extends MenuItemProps { element?: BoxProps["element"]; } +/** + * A menu item that can either perform an action or navigate to a new URL. + * + * @link [Account Switcher Item](https://paste.twilio.design/components/account-switcher#account-switcher-item) + */ const AccountSwitcherItem = React.forwardRef( ({ children, element = "ACCOUNT_SWITCHER_ITEM", ...props }, ref) => { return ( diff --git a/packages/paste-core/components/account-switcher/src/AccountSwitcherItemRadio.tsx b/packages/paste-core/components/account-switcher/src/AccountSwitcherItemRadio.tsx index 830e2b0d93..7801f23eea 100644 --- a/packages/paste-core/components/account-switcher/src/AccountSwitcherItemRadio.tsx +++ b/packages/paste-core/components/account-switcher/src/AccountSwitcherItemRadio.tsx @@ -15,6 +15,11 @@ export interface AccountSwitcherItemRadioProps extends MenuItemRadioProps { element?: BoxProps["element"]; } +/** + * A menu item that can perform a single selection of an item within a named group. Similar to a radio button group, only one item can be selected at a time. Each item in the group should have a name and value and must be contained in a Group. + * + * @link [Account Switcher Item Radio](https://paste.twilio.design/components/account-switcher#account-switcher-itemradio) + */ const AccountSwitcherItemRadio = React.forwardRef( ({ children, element = "ACCOUNT_SWITCHER_ITEM_RADIO", ...props }, ref) => { return ( diff --git a/packages/paste-core/components/account-switcher/src/AccountSwitcherSeparator.tsx b/packages/paste-core/components/account-switcher/src/AccountSwitcherSeparator.tsx index eacddc7a72..950e1061ee 100644 --- a/packages/paste-core/components/account-switcher/src/AccountSwitcherSeparator.tsx +++ b/packages/paste-core/components/account-switcher/src/AccountSwitcherSeparator.tsx @@ -14,6 +14,11 @@ export interface AccountSwitcherSeparatorProps extends MenuSeparatorProps { element?: BoxProps["element"]; } +/** + * Simple horizontal rule used to separate groups or individual items. + * + * @link [Account Switcher Separator](https://paste.twilio.design/components/account-switcher#account-switcher-separator) + */ const AccountSwitcherSeparator = React.forwardRef( ({ children, element = "ACCOUNT_SWITCHER_SEPARATOR", ...props }, ref) => { return ( From 917e9b335181f05b26ca59a9a8458b913119fbc7 Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 10:41:09 -0400 Subject: [PATCH 06/13] feat: Adding JSDoc to Alert component. Minor update to the syntax of the component. --- .../paste-core/components/alert/src/Alert.tsx | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/paste-core/components/alert/src/Alert.tsx b/packages/paste-core/components/alert/src/Alert.tsx index 5fe6f952ad..56f4de8547 100644 --- a/packages/paste-core/components/alert/src/Alert.tsx +++ b/packages/paste-core/components/alert/src/Alert.tsx @@ -10,23 +10,28 @@ import { ScreenReaderOnly } from "@twilio-paste/screen-reader-only"; import type { HTMLPasteProps, ValueOf } from "@twilio-paste/types"; import * as React from "react"; +/** Alert component variants keys. */ type AlertVariantKeys = "ERROR" | "NEUTRAL" | "WARNING"; +/** Alert component roles. */ export const AlertRoles = { ERROR: "alert", NEUTRAL: "status", WARNING: "alert", } as const; +/** Alert component variants. */ export const AlertVariants = { ERROR: "error", NEUTRAL: "neutral", WARNING: "warning", } as const; +/** Alert component background colors. */ export const AlertBackgroundColors = { ERROR: "colorBackgroundErrorWeakest", NEUTRAL: "colorBackgroundNeutralWeakest", WARNING: "colorBackgroundWarningWeakest", } as const; +/** Alert component text colors. */ export const AlertTextColors = { ERROR: "colorTextError", NEUTRAL: "colorTextNeutral", @@ -107,7 +112,20 @@ export interface AlertProps extends HTMLPasteProps<"div"> { element?: BoxProps["element"]; } -const renderAlertIcon = (variant: AlertVariants, element: string, title: string): React.ReactElement => { +interface AlertIconProps { + variant: AlertVariants; + element: string; + title: string; +} + +/** + * Component to display the appropriate alert icon. + */ +const AlertIcon: React.FC = ({ + variant, + element, + title, +}): React.ReactElement => { switch (variant) { case AlertVariants.ERROR: return ( @@ -142,7 +160,13 @@ const renderAlertIcon = (variant: AlertVariants, element: string, title: string) ); } }; +AlertIcon.displayName = "AlertIcon" +/** + * An Alert is a banner that notifies users to high-priority or time-sensitive information. + * + * @link [Alert](https://paste.twilio.design/components/alert) + */ const Alert = React.forwardRef( ( { @@ -180,7 +204,7 @@ const Alert = React.forwardRef( > - {renderAlertIcon(variant, element, i18nLabelVariantMap[variant])} + {children} From b24f17bf158c281c7699659c693ba9f9c1b3b20c Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 12:11:29 -0400 Subject: [PATCH 07/13] refactor: Adding JSDoc to the AlertDialog component. Fixing types in component. Removing bloated wrapper code in component. --- .../alert-dialog/src/AlertDialog.tsx | 123 +++++++++++------- 1 file changed, 79 insertions(+), 44 deletions(-) diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx index 741a93b25e..7636c608a8 100644 --- a/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx +++ b/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx @@ -1,8 +1,9 @@ -import { useTransition } from "@twilio-paste/animation-library"; -import { Box, safelySpreadBoxProps } from "@twilio-paste/box"; import type { BoxProps } from "@twilio-paste/box"; -import { ModalDialogOverlay } from "@twilio-paste/modal"; import type { HTMLPasteProps } from "@twilio-paste/types"; +import type { SpringValue } from "@react-spring/web"; +import { Box, safelySpreadBoxProps } from "@twilio-paste/box"; +import { ModalDialogOverlay } from "@twilio-paste/modal"; +import { useTransition } from "@twilio-paste/animation-library"; import { useUID } from "@twilio-paste/uid-library"; import * as React from "react"; @@ -11,8 +12,10 @@ import { AlertDialogContent } from "./AlertDialogContent"; import { AlertDialogFooter } from "./AlertDialogFooter"; import { AlertDialogHeader } from "./AlertDialogHeader"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const getAnimationStates = (): any => ({ +/** + * Animation states for the Alert Dialog. + */ +const AnimationStates = { from: { opacity: 0, transform: `scale(0.675)` }, enter: { opacity: 1, transform: `scale(1)` }, leave: { opacity: 0, transform: `scale(0.675)` }, @@ -22,7 +25,7 @@ const getAnimationStates = (): any => ({ tension: 370, friction: 26, }, -}); +}; export interface AlertDialogProps extends HTMLPasteProps<"div"> { children: NonNullable; @@ -92,6 +95,35 @@ export interface AlertDialogProps extends HTMLPasteProps<"div"> { element?: BoxProps["element"]; } +interface NormalizeStylesArg { + opacity: SpringValue; + transform: SpringValue; +} + +interface NormalizeStylesReturn { + opacity: number; + transform: string; +} + +/** + * Normalize ReactSpring styles to be used in the AlertDialog. + * + * @param {NormalizeStylesArg} styles - ReactSpring styles + * @returns {NormalizeStylesReturn} - Normalized styles + */ +const normalizeStyles = (styles: NormalizeStylesArg): NormalizeStylesReturn => { + return { + ...styles, + opacity: styles.opacity.get(), + transform: styles.transform.get() + }; +} + +/** + * An Alert Dialog is a page overlay that displays critical information, blocks interaction with the page, and only closes after an action is performed. + * + * @link [Alert Dialog](https://paste.twilio.design/components/alert-dialog) + */ export const AlertDialog = React.forwardRef( ( { @@ -109,47 +141,50 @@ export const AlertDialog = React.forwardRef( }, ref, ) => { - const transitions = useTransition(isOpen, getAnimationStates()); + const transitions = useTransition(isOpen, AnimationStates); const headingID = useUID(); const bodyID = useUID(); - return ( - <> - {transitions( - (styles, item) => - item && ( - - - - {heading} - - - {children} - - - - - ), - )} - + return transitions( + (rawStyles, item) => { + if (!item) { + return null; + } + // Normalizing ReactSpring styles. + const styles = normalizeStyles(rawStyles); + + return ( + + + + {heading} + + + {children} + + + + + ); + } ); }, ); From 2cab9adc5e5e9d2306ae001771f472c10cef65eb Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 13:04:42 -0400 Subject: [PATCH 08/13] feat: Adding JSDoc to all internal AlertDialog components. --- .../components/alert-dialog/src/AlertDialogBody.tsx | 5 +++++ .../alert-dialog/src/AlertDialogContent.tsx | 9 ++++++--- .../components/alert-dialog/src/AlertDialogFooter.tsx | 11 +++++++++++ .../components/alert-dialog/src/AlertDialogHeader.tsx | 6 ++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialogBody.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialogBody.tsx index 0153acd064..aa6dd48224 100644 --- a/packages/paste-core/components/alert-dialog/src/AlertDialogBody.tsx +++ b/packages/paste-core/components/alert-dialog/src/AlertDialogBody.tsx @@ -8,6 +8,11 @@ export interface AlertDialogBodyProps extends HTMLPasteProps<"div">, Pick; } +/** + * Internal body component for the AlertDialog component. + * + * @private + */ export const AlertDialogBody = React.forwardRef( ({ bodyID, children, element = "ALERT_DIALOG_BODY", ...props }, ref) => { return ( diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialogContent.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialogContent.tsx index 8c907ea3f4..525545716c 100644 --- a/packages/paste-core/components/alert-dialog/src/AlertDialogContent.tsx +++ b/packages/paste-core/components/alert-dialog/src/AlertDialogContent.tsx @@ -4,12 +4,15 @@ import { css, styled } from "@twilio-paste/styling-library"; export type AlertDialogContentProps = ModalDialogContentProps; -const AlertDialogContent = styled(ModalDialogContent)(() => +/** + * Content area for the AlertDialog component. + * + * @private + */ +export const AlertDialogContent = styled(ModalDialogContent)(() => css({ maxWidth: "size40", }), ); AlertDialogContent.displayName = "AlertDialogContent"; - -export { AlertDialogContent }; diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx index 253ba95bf6..1ed94cd80d 100644 --- a/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx +++ b/packages/paste-core/components/alert-dialog/src/AlertDialogFooter.tsx @@ -6,14 +6,25 @@ import type { HTMLPasteProps } from "@twilio-paste/types"; import * as React from "react"; export interface AlertDialogFooterProps extends HTMLPasteProps<"div">, Pick { + /** Determines if the Alert Dialog is destructive. _Only changes the button color of confirm button._ */ destructive?: boolean; + /** Function to run on confirmation of the Alert Dialog. */ onConfirm: () => void; + /** Text of the confirm button. */ onConfirmLabel: string; + /** Function to run on dismiss of the Alert Dialog. */ onDismiss: () => void; + /** Text of the dismiss button. */ onDismissLabel: string; + /** Property to disable the confirm button. _Has no effect if destructive is not true._ */ onConfirmDisabled?: boolean; } +/** + * Alert Dialog footer component for the AlertDialog component. + * + * @private + */ export const AlertDialogFooter = React.forwardRef( ( { diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialogHeader.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialogHeader.tsx index 9db23dd7cf..4a203db21f 100644 --- a/packages/paste-core/components/alert-dialog/src/AlertDialogHeader.tsx +++ b/packages/paste-core/components/alert-dialog/src/AlertDialogHeader.tsx @@ -6,9 +6,15 @@ import * as React from "react"; export interface AlertDialogHeaderProps extends HTMLPasteProps<"header">, Pick { children: string; + /** ID for the internal heading element. */ headingID: string; } +/** + * Internal alert dialog header component for the AlertDialog component. + * + * @private + */ export const AlertDialogHeader = React.forwardRef( ({ children, element = "ALERT_DIALOG_HEADER", headingID, ...props }, ref) => { return ( From 9e983923a5396f979a05e749d68e9dde7f44cacc Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 13:36:01 -0400 Subject: [PATCH 09/13] feat: Fixing type issue. --- packages/paste-core/components/button/src/types.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/paste-core/components/button/src/types.ts b/packages/paste-core/components/button/src/types.ts index 8ea7961782..995b79a17d 100644 --- a/packages/paste-core/components/button/src/types.ts +++ b/packages/paste-core/components/button/src/types.ts @@ -1,4 +1,4 @@ -import type { BoxProps } from "@twilio-paste/box"; +import type { BoxProps, BoxStyleProps } from "@twilio-paste/box"; import type { HTMLPasteProps } from "@twilio-paste/types"; type ButtonTypes = "submit" | "button" | "reset"; @@ -105,11 +105,17 @@ export interface DirectButtonProps extends HTMLPasteProps<"button"> { variant: ButtonVariants; } -type VariantsButtonProps = { +type BaseVariantsButtonProps = { /** * The different appearance variants for a button. [Avoid using link variants when possible.](https://paste.twilio.design/components/button#button-vs-anchor-link) */ - variant?: ButtonBaseVariants | ButtonResetVariant; + variant?: ButtonBaseVariants; +}; +type ResetVariantButtonProps = Omit & { + /** + * The different appearance variants for a button. [Avoid using link variants when possible.](https://paste.twilio.design/components/button#button-vs-anchor-link) + */ + variant?: ButtonResetVariant; }; export type ButtonProps = Omit & { @@ -127,4 +133,4 @@ export type ButtonProps = Omit Date: Fri, 10 May 2024 13:48:41 -0400 Subject: [PATCH 10/13] fix: Reverting button code change. --- packages/paste-core/components/button/src/types.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/paste-core/components/button/src/types.ts b/packages/paste-core/components/button/src/types.ts index 995b79a17d..5e73e8c2e3 100644 --- a/packages/paste-core/components/button/src/types.ts +++ b/packages/paste-core/components/button/src/types.ts @@ -39,7 +39,6 @@ export type ButtonVariants = ButtonResetVariant | ButtonBaseVariants; export type ButtonStates = "disabled" | "loading" | "default"; export type ButtonTabIndexes = 0 | -1; - export interface ButtonContentsProps { /** The various states of interactivity for the button. */ buttonState: ButtonStates; @@ -112,9 +111,6 @@ type BaseVariantsButtonProps = { variant?: ButtonBaseVariants; }; type ResetVariantButtonProps = Omit & { - /** - * The different appearance variants for a button. [Avoid using link variants when possible.](https://paste.twilio.design/components/button#button-vs-anchor-link) - */ variant?: ButtonResetVariant; }; From ba8d28603072cf57769302c2d9d2ba4f05d50948 Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 13:52:39 -0400 Subject: [PATCH 11/13] fix: Reverting button change. --- .../components/button/src/Button.tsx | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/packages/paste-core/components/button/src/Button.tsx b/packages/paste-core/components/button/src/Button.tsx index a67d7007aa..32dc9345b9 100644 --- a/packages/paste-core/components/button/src/Button.tsx +++ b/packages/paste-core/components/button/src/Button.tsx @@ -236,18 +236,8 @@ const getButtonComponent = ( * @see [Accessiblity](https://paste.twilio.design/components/button#button-vs-anchor-link) */ const Button = React.forwardRef( - ({ - element = "BUTTON", - i18nExternalLinkLabel = "(link takes you to an external page)", - as = 'button', - fullWidth = false, - disabled = false, - loading = false, - type = 'button', - variant = 'primary', - ...props - }, ref) => { - const { size, children, ...rest } = props; + ({ element = "BUTTON", i18nExternalLinkLabel = "(link takes you to an external page)", ...props }, ref) => { + const { size, variant, children, disabled, loading, ...rest } = props; const [hovered, setHovered] = React.useState(false); const arrowIconStyles = useSpring({ translateX: hovered ? "4px" : "0px", @@ -262,16 +252,7 @@ const Button = React.forwardRef( return getButtonSize(variant, children, size); }, [size, variant, children]); - handlePropValidation({ - as, - fullWidth, - disabled, - loading, - type, - variant, - ...props, - size: smartDefaultSize - }); + handlePropValidation({ ...props, size: smartDefaultSize }); const buttonState = getButtonState(disabled, loading); const showLoading = buttonState === "loading"; @@ -281,7 +262,7 @@ const Button = React.forwardRef( // Automatically inject AnchorForwardIcon for link's dressed as buttons when possible let injectIconChildren = children; - if (as === "a" && props.href != null && typeof children === "string" && variant !== "reset") { + if (props.as === "a" && props.href != null && typeof children === "string" && variant !== "reset") { injectIconChildren = ( <> {children} @@ -328,6 +309,15 @@ const Button = React.forwardRef( }, ); +Button.defaultProps = { + as: "button", + fullWidth: false, + disabled: false, + loading: false, + type: "button", + variant: "primary", +}; + Button.displayName = "Button"; export type { ButtonProps }; From fd40224d06043b53b2fd65508dad65e9de508d57 Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 14:23:47 -0400 Subject: [PATCH 12/13] chore: Formatting. --- .../alert-dialog/src/AlertDialog.tsx | 82 +++++++++---------- .../paste-core/components/alert/src/Alert.tsx | 8 +- 2 files changed, 42 insertions(+), 48 deletions(-) diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx index 7636c608a8..cd8830cd26 100644 --- a/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx +++ b/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx @@ -115,9 +115,9 @@ const normalizeStyles = (styles: NormalizeStylesArg): NormalizeStylesReturn => { return { ...styles, opacity: styles.opacity.get(), - transform: styles.transform.get() + transform: styles.transform.get(), }; -} +}; /** * An Alert Dialog is a page overlay that displays critical information, blocks interaction with the page, and only closes after an action is performed. @@ -145,47 +145,45 @@ export const AlertDialog = React.forwardRef( const headingID = useUID(); const bodyID = useUID(); - return transitions( - (rawStyles, item) => { - if (!item) { - return null; - } - // Normalizing ReactSpring styles. - const styles = normalizeStyles(rawStyles); - - return ( - - - - {heading} - - - {children} - - - - - ); + return transitions((rawStyles, item) => { + if (!item) { + return null; } - ); + // Normalizing ReactSpring styles. + const styles = normalizeStyles(rawStyles); + + return ( + + + + {heading} + + + {children} + + + + + ); + }); }, ); diff --git a/packages/paste-core/components/alert/src/Alert.tsx b/packages/paste-core/components/alert/src/Alert.tsx index 56f4de8547..409d22238d 100644 --- a/packages/paste-core/components/alert/src/Alert.tsx +++ b/packages/paste-core/components/alert/src/Alert.tsx @@ -121,11 +121,7 @@ interface AlertIconProps { /** * Component to display the appropriate alert icon. */ -const AlertIcon: React.FC = ({ - variant, - element, - title, -}): React.ReactElement => { +const AlertIcon: React.FC = ({ variant, element, title }): React.ReactElement => { switch (variant) { case AlertVariants.ERROR: return ( @@ -160,7 +156,7 @@ const AlertIcon: React.FC = ({ ); } }; -AlertIcon.displayName = "AlertIcon" +AlertIcon.displayName = "AlertIcon"; /** * An Alert is a banner that notifies users to high-priority or time-sensitive information. From d381439036a88db7476c4f27c56aa77894edf5f6 Mon Sep 17 00:00:00 2001 From: Joe Fehrman Date: Fri, 10 May 2024 15:19:39 -0400 Subject: [PATCH 13/13] chore: Fixing import order. --- .../paste-core/components/alert-dialog/src/AlertDialog.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx b/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx index cd8830cd26..c3bee3c3be 100644 --- a/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx +++ b/packages/paste-core/components/alert-dialog/src/AlertDialog.tsx @@ -1,9 +1,9 @@ -import type { BoxProps } from "@twilio-paste/box"; -import type { HTMLPasteProps } from "@twilio-paste/types"; import type { SpringValue } from "@react-spring/web"; +import { useTransition } from "@twilio-paste/animation-library"; +import type { BoxProps } from "@twilio-paste/box"; import { Box, safelySpreadBoxProps } from "@twilio-paste/box"; import { ModalDialogOverlay } from "@twilio-paste/modal"; -import { useTransition } from "@twilio-paste/animation-library"; +import type { HTMLPasteProps } from "@twilio-paste/types"; import { useUID } from "@twilio-paste/uid-library"; import * as React from "react";