Skip to content

Commit

Permalink
[DS-432] Added description prop to Switch (#521)
Browse files Browse the repository at this point in the history
  • Loading branch information
vicky-comeau authored Nov 4, 2024
2 parents 091d308 + 4eacf7b commit e1996cf
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 86 deletions.
5 changes: 5 additions & 0 deletions .changeset/pink-weeks-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hopper-ui/components": patch
---

Added a `description` prop to SwitchField and removed the description slot.
9 changes: 3 additions & 6 deletions packages/components/src/switch/docs/SwitchField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,10 @@ export const Default: Story = {
*/
export const Description: Story = {
render: props => (
<SwitchField {...props}>
<SwitchField {...props} description="Description">
<Switch>
<Text>Option 1</Text>
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
)
};
Expand All @@ -71,17 +70,15 @@ export const Disabled: Story = {
export const Sizes: Story = {
render: props => (
<Stack>
<SwitchField {...props} size="sm">
<SwitchField {...props} size="sm" description="Description">
<Switch>
<Text>Option 1</Text>
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
<SwitchField {...props} size="md">
<SwitchField {...props} size="md" description="Description">
<Switch>
<Text>Option 1</Text>
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
</Stack>
)
Expand Down
5 changes: 2 additions & 3 deletions packages/components/src/switch/docs/switchfield/disabled.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Switch, SwitchField, Text } from "@hopper-ui/components";
import { Switch, SwitchField } from "@hopper-ui/components";

export default function Example() {
return (
<SwitchField isDisabled>
<SwitchField isDisabled description="This will override your changes">
<Switch>Save</Switch>
<Text>This will override your changes.</Text>
</SwitchField>
);
}
8 changes: 3 additions & 5 deletions packages/components/src/switch/docs/switchfield/sizes.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { Inline, Switch, SwitchField, Text } from "@hopper-ui/components";
import { Inline, Switch, SwitchField } from "@hopper-ui/components";

export default function Example() {
return (
<Inline>
<SwitchField size="sm">
<SwitchField size="sm" description="This will override your changes.">
<Switch>Save</Switch>
<Text>This will override your changes.</Text>
</SwitchField>
<SwitchField size="md">
<SwitchField size="md" description="This will override your changes.">
<Switch>Save</Switch>
<Text>This will override your changes.</Text>
</SwitchField>
</Inline>
);
Expand Down
37 changes: 24 additions & 13 deletions packages/components/src/switch/src/SwitchField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import {
type ResponsiveProp,
type StyledSystemProps
} from "@hopper-ui/styled-system";
import { forwardRef, type ForwardedRef } from "react";
import { mergeProps, useId } from "react-aria";
import { useSlotId } from "@react-aria/utils";
import { forwardRef, type ForwardedRef, type ReactNode } from "react";
import { mergeProps } from "react-aria";
import { composeRenderProps, useContextProps } from "react-aria-components";

import { TextContext, type TextSize } from "../../typography/Text/index.ts";
import { Text, type TextSize } from "../../typography/Text/index.ts";
import { composeClassnameRenderProps, cssModule, SlotProvider, useRenderProps, type AccessibleSlotProps, type FieldSize, type RenderProps, type SizeAdapter } from "../../utils/index.ts";

import { SwitchContext } from "./SwitchContext.ts";
Expand All @@ -32,14 +33,18 @@ interface SwitchFieldRenderProps {

export interface SwitchFieldProps extends RenderProps<SwitchFieldRenderProps>, StyledSystemProps, AccessibleSlotProps {
/**
* A switch field can vary in size.
* @default "md"
* The description of the switch field.
*/
size?: ResponsiveProp<FieldSize>;
description?: ReactNode;
/**
* Whether the switch field is disabled.
*/
isDisabled?: boolean;
/**
* A switch field can vary in size.
* @default "md"
*/
size?: ResponsiveProp<FieldSize>;
}

function SwitchField(props: SwitchFieldProps, ref: ForwardedRef<HTMLDivElement>) {
Expand All @@ -49,16 +54,17 @@ function SwitchField(props: SwitchFieldProps, ref: ForwardedRef<HTMLDivElement>)

const {
className,
style,
description,
isDisabled,
size: sizeProp = "md",
slot,
style,
...otherProps
} = ownProps;

const size = useResponsiveValue(sizeProp) ?? "md";

const descriptionId = useId();
const descriptionId = useSlotId([Boolean(description)]);

const classNames = composeClassnameRenderProps(
className,
Expand Down Expand Up @@ -90,11 +96,6 @@ function SwitchField(props: SwitchFieldProps, ref: ForwardedRef<HTMLDivElement>)
return (
<SlotProvider
values={[
[TextContext, {
id: descriptionId,
className: styles["hop-SwitchField__description"],
size: SwitchToDescriptionSizeAdapter[size]
}],
[SwitchContext, {
className: styles["hop-SwitchField__switch"],
size: size,
Expand All @@ -110,6 +111,16 @@ function SwitchField(props: SwitchFieldProps, ref: ForwardedRef<HTMLDivElement>)
{...mergeProps(renderProps, otherProps)}
>
{renderProps.children}
{description && (
<Text
id={descriptionId}
className={styles["hop-SwitchField__description"]}
size={SwitchToDescriptionSizeAdapter[size]}
slot="description"
>
{description}
</Text>
)}
</div>
</SlotProvider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react";

import { Inline, Stack } from "../../../layout/index.ts";
import { Text } from "../../../typography/Text/index.ts";
import { Switch } from "../../src/Switch.tsx";
import { SwitchField } from "../../src/SwitchField.tsx";

Expand All @@ -17,17 +16,15 @@ type Story = StoryObj<typeof meta>;
export const Default: Story = {
render: props => (
<Inline alignY="end">
<SwitchField {...props} size="sm">
<SwitchField {...props} size="sm" description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
<SwitchField {...props} size="md">
<SwitchField {...props} size="md" description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
</Inline>
)
Expand All @@ -36,17 +33,15 @@ export const Default: Story = {
export const Disabled: Story = {
render: props => (
<Inline alignY="end">
<SwitchField {...props} size="sm" isDisabled>
<SwitchField {...props} size="sm" isDisabled description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
<SwitchField {...props} size="md" isDisabled>
<SwitchField {...props} size="md" isDisabled description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
</Inline>
)
Expand All @@ -56,31 +51,27 @@ export const Zoom: Story = {
render: props => (
<Stack>
<Inline alignY="end">
<SwitchField {...props} size="sm" className="zoom-in">
<SwitchField {...props} size="sm" className="zoom-in" description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
<SwitchField {...props} size="md" className="zoom-in">
<SwitchField {...props} size="md" className="zoom-in" description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
</Inline>
<Inline alignY="end">
<SwitchField {...props} size="sm" className="zoom-out">
<SwitchField {...props} size="sm" className="zoom-out" description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
<SwitchField {...props} size="md" className="zoom-out">
<SwitchField {...props} size="md" className="zoom-out" description="Description">
<Switch>
<Text>Option 1</Text>
Option 1
</Switch>
<Text slot="description">Description</Text>
</SwitchField>
</Inline>
</Stack>
Expand All @@ -90,26 +81,23 @@ export const Zoom: Story = {
export const AccessToDisabledState: Story = {
render: props => (
<Inline alignY="end">
<SwitchField {...props} size="sm" isDisabled>
<SwitchField {...props} size="sm" isDisabled description="Value should be true">
{({ isDisabled }) => (
<>
<Switch>
<Text>Should be true</Text>
</Switch>
<Text slot="description">Is disabled: {String(isDisabled)}</Text>
</>
<Switch>
Is disabled: {String(isDisabled)}
</Switch>
)}
</SwitchField>
<SwitchField
{...props}
size="sm"
isDisabled
style={({ isDisabled }) => isDisabled ? { border: "1px solid red" } : {}}
description="Border should be red"
>
<Switch>
<Text>Disable and red border</Text>
Disable and red border
</Switch>
<Text slot="description">Border should be red</Text>
</SwitchField>
</Inline>
)
Expand Down
Loading

0 comments on commit e1996cf

Please sign in to comment.