-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(samples preview): toggle preview modes
- Loading branch information
1 parent
a8495bd
commit 3e75a18
Showing
4 changed files
with
121 additions
and
15 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
src/components/samples-preview/__tests__/toggle-button.test.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,30 @@ | ||
import { describe, it } from "@jest/globals"; | ||
import { fireEvent, render } from "@testing-library/react"; | ||
|
||
import * as ToggleButton from "../toggle-button"; | ||
|
||
function Render() { | ||
return ( | ||
<ToggleButton.Root defaultValue="one"> | ||
<ToggleButton.Item value="one">one</ToggleButton.Item> | ||
<ToggleButton.Item value="two">two</ToggleButton.Item> | ||
</ToggleButton.Root> | ||
); | ||
} | ||
|
||
describe("Samples Preview / ToggleButton", () => { | ||
it("Correct rendering and unmount", () => { | ||
const screen = render(<Render />); | ||
|
||
expect(() => screen.unmount()).not.toThrow(); | ||
}); | ||
|
||
it("Should change active item", () => { | ||
const screen = render(<Render />); | ||
const btnTwo = screen.getByText("two"); | ||
|
||
fireEvent.click(btnTwo); | ||
|
||
expect(btnTwo.getAttribute("aria-pressed")).toBe("true"); | ||
}); | ||
}); |
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
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
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,73 @@ | ||
import type { Dispatch, SetStateAction, ReactNode } from "react"; | ||
|
||
import { createContext, useState, useContext } from "react"; | ||
import { css, cx } from "@root/styled-system/css"; | ||
|
||
import { Button } from "@/components/primitives/button"; | ||
|
||
const classes = { | ||
root: css({ | ||
p: "1", | ||
bgColor: "bg-primary", | ||
display: "inline-block", | ||
rounded: "xl", | ||
border: "1px solid", | ||
borderColor: "border-secondary", | ||
}), | ||
|
||
item: css({ border: "none" }), | ||
|
||
enabledItem: css({ bgColor: "bg-tertiary", color: "text-primary" }), | ||
|
||
disabledItem: css({ color: "text-secondary" }), | ||
}; | ||
|
||
interface ContextValue { | ||
value: string; | ||
setValue: Dispatch<SetStateAction<string>>; | ||
onChange?: (value: string) => void; | ||
} | ||
|
||
const Context = createContext<Pick<ContextValue, "value">>({ | ||
value: "", | ||
}); | ||
|
||
interface RootProps extends Pick<ContextValue, "onChange"> { | ||
children: ReactNode; | ||
defaultValue: string; | ||
} | ||
|
||
export function Root({ children, defaultValue, onChange }: RootProps) { | ||
const [value, setValue] = useState(defaultValue); | ||
const valueProvider: ContextValue = { value, setValue, onChange }; | ||
|
||
return ( | ||
<Context.Provider value={valueProvider}> | ||
<div className={classes.root}>{children}</div> | ||
</Context.Provider> | ||
); | ||
} | ||
|
||
interface ItemProps extends Pick<ContextValue, "value"> { | ||
children: ReactNode; | ||
} | ||
|
||
export function Item({ children, value }: ItemProps) { | ||
const { value: activeValue, setValue, onChange } = useContext(Context) as ContextValue; | ||
const isEnabled = value === activeValue; | ||
|
||
function onClick() { | ||
setValue(value); | ||
onChange?.(value); | ||
} | ||
|
||
return ( | ||
<Button | ||
aria-pressed={isEnabled ? "true" : "false"} | ||
className={cx(classes.item, isEnabled ? classes.enabledItem : classes.disabledItem)} | ||
onClick={onClick} | ||
> | ||
{children} | ||
</Button> | ||
); | ||
} |