Skip to content

Commit e421ee4

Browse files
add tests
1 parent af31b75 commit e421ee4

4 files changed

Lines changed: 104 additions & 19 deletions

File tree

packages/ui-components/src/components/SortButton/SortButton.component.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55

66
import React from "react"
7-
87
import { ToggleButton } from "../ToggleButton/ToggleButton.component"
98
import { Icon, KnownIcons } from "../Icon/Icon.component"
109

@@ -13,11 +12,8 @@ interface SortButtonProps {
1312
onOrderChange?: (_order: string) => void
1413
}
1514

16-
export const SortButton: React.FC<SortButtonProps> = ({ order = "asc", onOrderChange, ...props }) => {
17-
const options: { value: string; icon: KnownIcons }[] = [
18-
{ value: "sortShortWideArrowUp", icon: "sortShortWideArrowUp" },
19-
{ value: "sortShortWideArrowDown", icon: "sortShortWideArrowDown" },
20-
]
15+
export const SortButton: React.FC<SortButtonProps> = ({ order = "desc", onOrderChange, ...props }) => {
16+
const options: { value: string }[] = [{ value: "sortShortWideArrowUp" }, { value: "sortShortWideArrowDown" }]
2117

2218
const handleChange = (value: string) => {
2319
if (onOrderChange) {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import React from "react"
7+
import { render, screen } from "@testing-library/react"
8+
import userEvent from "@testing-library/user-event"
9+
import { describe, expect, it, vi } from "vitest"
10+
11+
import { ToggleButton } from "./ToggleButton.component"
12+
13+
describe("ToggleButton Component", () => {
14+
it("renders plain values as labels", async () => {
15+
const options = ["state1", "state2"]
16+
const handleChange = vi.fn()
17+
18+
render(<ToggleButton options={options} onChange={handleChange} />)
19+
const button = screen.getByRole("button")
20+
21+
expect(button).toHaveTextContent("state1")
22+
23+
await userEvent.click(button)
24+
expect(button).toHaveTextContent("state2")
25+
expect(handleChange).toHaveBeenCalledWith("state2")
26+
27+
await userEvent.click(button)
28+
expect(button).toHaveTextContent("state1")
29+
expect(handleChange).toHaveBeenCalledWith("state1")
30+
})
31+
32+
it("renders labels from array of objects with value and label", async () => {
33+
const options = [
34+
{ value: "state1", label: "Label 1" },
35+
{ value: "state2", label: "Label 2" },
36+
]
37+
const handleChange = vi.fn()
38+
39+
render(<ToggleButton options={options} onChange={handleChange} />)
40+
const button = screen.getByRole("button")
41+
42+
expect(button).toHaveTextContent("Label 1")
43+
44+
await userEvent.click(button)
45+
expect(button).toHaveTextContent("Label 2")
46+
expect(handleChange).toHaveBeenCalledWith("state2")
47+
48+
await userEvent.click(button)
49+
expect(button).toHaveTextContent("Label 1")
50+
expect(handleChange).toHaveBeenCalledWith("state1")
51+
})
52+
53+
it("uses renderLabel function for custom label rendering", async () => {
54+
const options = ["state1", "state2"]
55+
const customRenderLabel = vi.fn((value) => `Custom ${value}`)
56+
57+
render(<ToggleButton options={options} renderLabel={customRenderLabel} />)
58+
const button = screen.getByRole("button")
59+
60+
expect(button).toHaveTextContent("Custom state1")
61+
62+
await userEvent.click(button)
63+
expect(button).toHaveTextContent("Custom state2")
64+
})
65+
})

packages/ui-components/src/components/ToggleButton/ToggleButton.component.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
*/
55

66
import React, { useState, useEffect } from "react"
7-
import { Button } from "../Button"
7+
import { Button, ButtonProps } from "../Button"
8+
import { KnownIcons } from "../Icon/Icon.component"
89

910
type Option<T> = T | { value: T; label?: React.ReactNode; icon?: KnownIcons }
1011

11-
export interface ToggleButtonProps<T> {
12+
export interface ToggleButtonProps<T> extends Omit<ButtonProps, "onChange" | "value"> {
1213
options: Option<T>[]
1314
value?: T
1415
onChange?: (_value: T) => void
@@ -20,7 +21,7 @@ export const ToggleButton = <T extends string | number>({
2021
value: controlledValue,
2122
onChange,
2223
renderLabel,
23-
...buttonProps
24+
...props
2425
}: ToggleButtonProps<T>) => {
2526
const getValue = (option: Option<T>): T => (typeof option === "object" ? option.value : option)
2627
const initialValue = controlledValue !== undefined ? controlledValue : getValue(options[0])
@@ -51,5 +52,5 @@ export const ToggleButton = <T extends string | number>({
5152
return typeof currentOption === "object" ? currentOption.label : currentOption
5253
}
5354

54-
return <Button {...buttonProps} label={getLabel()} onClick={onButtonClick} />
55+
return <Button {...props} label={getLabel()} onClick={onButtonClick} />
5556
}

packages/ui-components/src/components/ToggleButton/ToggleButton.stories.tsx

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ const meta: Meta<typeof ToggleButton> = {
3434
action: "toggleChanged",
3535
description: "Callback for whenever the toggle changes.",
3636
},
37+
variant: {
38+
control: {
39+
type: "select",
40+
options: ["primary", "default", "primary-danger", "subdued"],
41+
},
42+
description: "Variant styling for the button.",
43+
},
3744
},
3845
}
3946

@@ -55,6 +62,25 @@ export const Default: Story = {
5562
},
5663
}
5764

65+
export const WithObjectOptions: Story = {
66+
args: {
67+
options: [
68+
{ value: "Theme 1", label: "Light Theme" },
69+
{ value: "Theme 2", label: "Dark Theme" },
70+
{ value: "Theme 3", label: "Colorful Theme" },
71+
],
72+
value: "Theme 1",
73+
onChange: (value) => console.log("Theme changed to:", value),
74+
},
75+
parameters: {
76+
docs: {
77+
description: {
78+
story: "ToggleButton using options with value-label objects.",
79+
},
80+
},
81+
},
82+
}
83+
5884
export const Disabled: Story = {
5985
args: {
6086
options: ["Option 1", "Option 2", "Option 3"],
@@ -71,20 +97,17 @@ export const Disabled: Story = {
7197
},
7298
}
7399

74-
export const WithObjectOptions: Story = {
100+
export const PrimaryVariant: Story = {
75101
args: {
76-
options: [
77-
{ value: "Theme 1", label: "Light Theme" },
78-
{ value: "Theme 2", label: "Dark Theme" },
79-
{ value: "Theme 3", label: "Colorful Theme" },
80-
],
81-
value: "Theme 1",
82-
onChange: (value) => console.log("Theme changed to:", value),
102+
options: ["Option A", "Option B", "Option C"],
103+
value: "Option A",
104+
variant: "primary",
105+
onChange: (value) => console.log("Changed to:", value),
83106
},
84107
parameters: {
85108
docs: {
86109
description: {
87-
story: "ToggleButton using options with value-label objects.",
110+
story: "ToggleButton rendered with primary variant styling.",
88111
},
89112
},
90113
},

0 commit comments

Comments
 (0)