-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
20d2498
commit 8b2caf3
Showing
5 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
162 changes: 162 additions & 0 deletions
162
packages/components/src/__actions__/Link/v3/LinkButton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
import React from "react" | ||
import { Link as RACLink } from "react-aria-components" | ||
import { LoadingSpinner } from "~components/Loading" | ||
import { useReversedColors } from "~components/__utilities__/v3" | ||
import { mergeClassNames } from "~components/utils/mergeClassNames" | ||
import styles from "./Button.module.scss" | ||
|
||
export type ButtonVariants = "primary" | "secondary" | "tertiary" | ||
export type ButtonSizes = "small" | "medium" | "large" | ||
|
||
// type ButtonPendingProps = { | ||
// isPending?: false | ||
// /** Rendered as the child while `pendingLabel` is `true` */ | ||
// pendingLabel?: string | ||
// /** Hides the `pendingLabel` and renders only the loading spinner if `isPending` is `true`. This will still be used as the accessible label. | ||
// * @default false | ||
// */ | ||
// isPendingLabelVisible?: boolean | ||
// } | ||
|
||
// type ButtonContentProps = { | ||
// /** The visual label of Button. */ | ||
// label?: string | ||
// icon?: JSX.Element | ||
// /** `iconPosition` will only control icons passed in as a prop | ||
// * @default "start" | ||
// */ | ||
// iconPosition?: "start" | "end" | ||
// /** The visual size of the button. `medium` was formerly `regular` | ||
// * @default "primary" | ||
// */ | ||
// children?: never | ||
// } & ButtonPendingProps | ||
|
||
// type ButtonContentWithChildrenProps = { | ||
// children: RACButtonProps["children"] | ||
// label?: never | ||
// icon?: never | ||
// iconPosition?: never | ||
// } & ButtonPendingProps | ||
|
||
export type ButtonBaseProps = { | ||
/** The visual label of Button. */ | ||
label?: string | ||
icon?: JSX.Element | ||
/** `iconPosition` will only control icons passed in as a prop | ||
* @default "start" | ||
*/ | ||
iconPosition?: "start" | "end" | ||
/** The visual size of the button. `medium` was formerly `regular` | ||
* @default "primary" | ||
*/ | ||
variant?: ButtonVariants | ||
/** The visual size of the button. `medium` was formerly `regular` | ||
* @default "medium" | ||
*/ | ||
size?: ButtonSizes | ||
/** Determines if the button should fill the width of its container | ||
* @default false | ||
*/ | ||
isFullWidth?: boolean | ||
/** Triggers a pending state and stops additional press events while waiting for a server response | ||
* @default false | ||
*/ | ||
isPending?: false | ||
/** Rendered as the child while `pendingLabel` is `true` */ | ||
pendingLabel?: string | ||
/** Hides the `pendingLabel` and renders only the loading spinner if `isPending` is `true`. This will still be used as the accessible label. | ||
* @default false | ||
*/ | ||
isPendingLabelVisible?: boolean | ||
} & Omit<RACButtonProps, "children"> | ||
|
||
export type ButtonWithoutChildren = ButtonBaseProps & { | ||
label: string | ||
children?: never | ||
} | ||
|
||
export type ButtonWithChildren = ButtonBaseProps & { | ||
label?: never | ||
children: RACButtonProps["children"] | ||
} | ||
|
||
export type ButtonProps = ButtonWithoutChildren | ButtonWithChildren | ||
|
||
export type PendingButtonProps = Omit< | ||
ButtonProps, | ||
"isPending" | "pendingLabel" | ||
> & { | ||
/** Triggers a pending state and stops additional press events while waiting for a server response */ | ||
isPending: true | ||
/** Rendered as the child of the button during pending state */ | ||
pendingLabel: string | ||
/** Hides the `pendingLabel` and renders only the loading spinner if `isPending` is `true`. This will still be used as the accessible label. | ||
* @default false | ||
*/ | ||
isPendingLabelVisible?: boolean | ||
} | ||
|
||
// TODO: the content width based on the total size of the button content | ||
const PendingContent = ({ | ||
pendingLabel, | ||
isPendingLabelVisible, | ||
}: PendingButtonProps): JSX.Element => { | ||
if (isPendingLabelVisible) { | ||
return ( | ||
<> | ||
{pendingLabel} | ||
<LoadingSpinner size="md" accessibilityLabel="" /> | ||
</> | ||
) | ||
} | ||
|
||
return ( | ||
<> | ||
{/* TODO: the loading spinner will need to take size */} | ||
<LoadingSpinner size="md" accessibilityLabel={pendingLabel} /> | ||
</> | ||
) | ||
} | ||
|
||
const ButtonContent = (props: ButtonProps): JSX.Element => { | ||
const hasChildren = "children" in props | ||
|
||
return hasChildren ? ( | ||
<>{props.children}</> | ||
) : ( | ||
<> | ||
{props.iconPosition !== "end" && props.icon} | ||
{props.label} | ||
{props.iconPosition === "end" && props.icon} | ||
</> | ||
) | ||
} | ||
|
||
export const Button = ({ | ||
variant = "primary", | ||
className, | ||
size = "medium", | ||
isFullWidth, | ||
// isPending, | ||
...otherProps | ||
}: ButtonProps): JSX.Element => { | ||
const isReversed = useReversedColors() | ||
|
||
return ( | ||
<RACLink | ||
aria-live={"pendingLabel" in otherProps ? "polite" : undefined} | ||
className={mergeClassNames( | ||
styles.button, | ||
styles[variant], | ||
styles[size], | ||
isFullWidth && styles.fullWidth, | ||
isReversed && styles.reversed, | ||
className | ||
)} | ||
{...otherProps} | ||
> | ||
<ButtonContent {...otherProps} /> | ||
</RACLink> | ||
) | ||
} |
24 changes: 24 additions & 0 deletions
24
packages/components/src/__actions__/Link/v3/_docs/LinkButton.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React from "react" | ||
import { action } from "@storybook/addon-actions" | ||
import { Meta, StoryObj } from "@storybook/react" | ||
import { validate } from "uuid" | ||
import { AddIcon, TrashIcon, ChevronUpIcon } from "~components/Icon" | ||
Check failure on line 5 in packages/components/src/__actions__/Link/v3/_docs/LinkButton.stories.tsx
|
||
import { VisuallyHidden } from "~components/VisuallyHidden" | ||
import { LinkButton } from "../index" | ||
|
||
const meta = { | ||
title: "Actions/Button/Button (v3)", | ||
component: LinkButton, | ||
args: { | ||
label: "Label", | ||
onPress: action("Button onPress event"), | ||
}, | ||
} satisfies Meta<typeof LinkButton> | ||
|
||
export default meta | ||
|
||
type Story = StoryObj<typeof meta> | ||
|
||
export const Playground: Story = { | ||
render: args => <LinkButton {...args}></LinkButton>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./LinkButton" |