Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DS-432] Added description prop to Switch #521

Merged
merged 1 commit into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
vicky-comeau marked this conversation as resolved.
Show resolved Hide resolved
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