Skip to content

Commit af31b75

Browse files
rough sort button
1 parent 25b17c6 commit af31b75

3 files changed

Lines changed: 102 additions & 17 deletions

File tree

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
8+
import { ToggleButton } from "../ToggleButton/ToggleButton.component"
9+
import { Icon, KnownIcons } from "../Icon/Icon.component"
10+
11+
interface SortButtonProps {
12+
order?: string
13+
onOrderChange?: (_order: string) => void
14+
}
15+
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+
]
21+
22+
const handleChange = (value: string) => {
23+
if (onOrderChange) {
24+
onOrderChange(value)
25+
}
26+
}
27+
28+
return (
29+
<ToggleButton options={options} onChange={handleChange} renderLabel={(value) => <Icon icon={value} />} {...props} />
30+
)
31+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 type { Meta, StoryObj } from "@storybook/react-vite"
7+
import { SortButton } from "./SortButton.component"
8+
9+
const meta: Meta<typeof SortButton> = {
10+
title: "Components/SortButton",
11+
component: SortButton,
12+
argTypes: {
13+
order: {
14+
control: {
15+
type: "radio",
16+
options: ["asc", "desc"],
17+
},
18+
description: "Initial sort order state, either ascending ('asc') or descending ('desc').",
19+
},
20+
disabled: {
21+
control: "boolean",
22+
description: "Whether the sort button is disabled.",
23+
},
24+
onOrderChange: {
25+
action: "orderChanged",
26+
description: "Callback triggered when the sort order changes.",
27+
},
28+
},
29+
}
30+
31+
export default meta
32+
type Story = StoryObj<typeof meta>
33+
34+
export const Default: Story = {
35+
args: {
36+
order: "desc",
37+
onOrderChange: (order) => console.log("Sort order changed to:", order),
38+
},
39+
parameters: {
40+
docs: {
41+
description: {
42+
story: "Default SortButton toggling between ascending and descending order.",
43+
},
44+
},
45+
},
46+
}
47+
48+
export const Disabled: Story = {
49+
args: {
50+
order: "asc",
51+
disabled: true,
52+
onOrderChange: (order) => console.log("Attempted to change sort order to:", order),
53+
},
54+
parameters: {
55+
docs: {
56+
description: {
57+
story: "SortButton in a disabled state, showing the initial sorting direction.",
58+
},
59+
},
60+
},
61+
}

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

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

66
import React, { useState, useEffect } from "react"
7-
import { Button, ButtonProps } from "../Button"
7+
import { Button } from "../Button"
88

9-
type Option<T> = T | { value: T; label?: React.ReactNode }
9+
type Option<T> = T | { value: T; label?: React.ReactNode; icon?: KnownIcons }
1010

11-
interface ToggleButtonProps<T extends string | number> extends Omit<ButtonProps, "onClick" | "onChange" | "value"> {
11+
export interface ToggleButtonProps<T> {
1212
options: Option<T>[]
1313
value?: T
1414
onChange?: (_value: T) => void
@@ -38,25 +38,18 @@ export const ToggleButton = <T extends string | number>({
3838
const nextValue = getValue(options[nextIndex])
3939

4040
setCurrentValue(nextValue)
41-
if (onChange) onChange(nextValue)
41+
if (onChange) {
42+
onChange(nextValue)
43+
}
4244
}
4345

44-
const getLabel = (): string | undefined => {
46+
const getLabel = (): React.ReactNode => {
4547
if (renderLabel) {
46-
const renderedLabel = renderLabel(currentValue)
47-
if (typeof renderedLabel === "string") {
48-
return renderedLabel
49-
}
48+
return renderLabel(currentValue)
5049
}
51-
5250
const currentOption = options.find((opt) => getValue(opt) === currentValue)
53-
54-
if (currentOption && typeof currentOption === "object" && typeof currentOption.label === "string") {
55-
return currentOption.label
56-
}
57-
58-
return currentValue?.toString()
51+
return typeof currentOption === "object" ? currentOption.label : currentOption
5952
}
6053

61-
return <Button {...buttonProps} label={getLabel()} onClick={onButtonClick} variant="primary" />
54+
return <Button {...buttonProps} label={getLabel()} onClick={onButtonClick} />
6255
}

0 commit comments

Comments
 (0)