Skip to content

Commit 94acd9a

Browse files
committed
feat: update button component to support icon-only variants and enhance icon handling in filters and view toggle
1 parent 8c9c82d commit 94acd9a

23 files changed

+220
-69
lines changed

assets/icons/filter-outline.svg

Lines changed: 1 addition & 3 deletions
Loading

assets/icons/filter-solid.svg

Lines changed: 1 addition & 4 deletions
Loading

assets/icons/horizontal-layout.svg

Lines changed: 1 addition & 0 deletions
Loading

assets/icons/sort-down-solid.svg

Lines changed: 1 addition & 5 deletions
Loading

assets/icons/sort-up-solid.svg

Lines changed: 1 addition & 5 deletions
Loading

assets/icons/vertical-layout.svg

Lines changed: 1 addition & 0 deletions
Loading

src/Components/Button/Button.stories.tsx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,83 @@ export const ErrorOutlinedWithIcon: Story = {
194194
}
195195
}
196196
};
197+
198+
export const IconOnly: Story = {
199+
args: {
200+
icon: {
201+
iconName: "IconBomb",
202+
iconPosition: "center"
203+
}
204+
}
205+
};
206+
207+
export const IconOnlyDisabled: Story = {
208+
args: {
209+
icon: {
210+
iconName: "IconBomb",
211+
iconPosition: "center"
212+
},
213+
disabled: true
214+
}
215+
};
216+
217+
export const IconOnlyLoading: Story = {
218+
args: {
219+
icon: {
220+
iconName: "IconBomb",
221+
iconPosition: "center"
222+
},
223+
isLoading: true
224+
}
225+
};
226+
227+
export const IconOnlyOutlined: Story = {
228+
args: {
229+
icon: {
230+
iconName: "IconBomb",
231+
iconPosition: "center"
232+
},
233+
outlined: true
234+
}
235+
};
236+
237+
export const IconOnlyPrimary: Story = {
238+
args: {
239+
icon: {
240+
iconName: "IconAddCircle",
241+
iconPosition: "center"
242+
},
243+
variant: ButtonVariantEnum.PRIMARY
244+
}
245+
};
246+
247+
export const IconOnlySecondary: Story = {
248+
args: {
249+
icon: {
250+
iconName: "IconAddCircle",
251+
iconPosition: "center"
252+
},
253+
variant: ButtonVariantEnum.SECONDARY
254+
}
255+
};
256+
257+
export const IconOnlyError: Story = {
258+
args: {
259+
icon: {
260+
iconName: "IconDeleteBin",
261+
iconPosition: "center"
262+
},
263+
variant: ButtonVariantEnum.ERROR
264+
}
265+
};
266+
267+
export const IconOnlyErrorOutlined: Story = {
268+
args: {
269+
icon: {
270+
iconName: "IconDeleteBin",
271+
iconPosition: "center"
272+
},
273+
variant: ButtonVariantEnum.ERROR,
274+
outlined: true
275+
}
276+
};

src/Components/Button/Button.tsx

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const Button: React.FC<IButtonProps> = (
2626
variant: ButtonVariantEnum.PRIMARY
2727
}
2828
) => {
29+
const isIconOnly = !children && !!icon?.iconName;
30+
2931
return (
3032
<button
3133
disabled={disabled}
@@ -36,33 +38,53 @@ const Button: React.FC<IButtonProps> = (
3638
disabled,
3739
outlined,
3840
className,
39-
isLoading
41+
isLoading,
42+
isIconOnly
4043
})}
4144
>
4245
<div className='yl:relative yl:flex yl:items-center yl:justify-center'>
4346
<span
4447
className={classNames({
45-
"yl:flex yl:items-center yl:gap-1": icon?.iconName,
48+
"yl:flex yl:items-center yl:gap-1": icon?.iconName && !isIconOnly,
4649
invisible: isLoading
4750
})}
4851
>
49-
{!isLoading && icon?.iconName && icon.iconPosition === "left" && (
50-
<Icon
51-
className={classNames(
52-
{
53-
"yl:w-5": !icon?.iconClassName
54-
},
55-
icon?.iconClassName
56-
)}
57-
iconName={icon.iconName}
58-
/>
59-
)}
52+
{!isLoading &&
53+
icon?.iconName &&
54+
(isIconOnly || icon.iconPosition === "left") && (
55+
<Icon
56+
className={classNames(
57+
{
58+
"yl:w-5": !icon?.iconClassName
59+
},
60+
icon?.iconClassName
61+
)}
62+
iconName={icon.iconName}
63+
/>
64+
)}
6065
<span className={classNames({ "yl:invisible": isLoading })}>
6166
{children}
6267
</span>
63-
{isLoading && icon?.iconName && icon.iconPosition === "right" && (
64-
<Spinner className={classNames("yl:w-4")} />
65-
)}
68+
{!isLoading &&
69+
!isIconOnly &&
70+
icon?.iconName &&
71+
icon.iconPosition === "right" && (
72+
<Icon
73+
className={classNames(
74+
{
75+
"yl:w-5": !icon?.iconClassName
76+
},
77+
icon?.iconClassName
78+
)}
79+
iconName={icon.iconName}
80+
/>
81+
)}
82+
{!isIconOnly &&
83+
isLoading &&
84+
icon?.iconName &&
85+
icon.iconPosition === "right" && (
86+
<Spinner className={classNames("yl:w-4")} />
87+
)}
6688
</span>
6789
<span className='yl:absolute'>
6890
{isLoading && <Spinner className={classNames("yl:w-6")} />}

src/Components/Button/Button.utils.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,16 @@ import classNames from "classnames";
22

33
import { ButtonVariantEnum, IGetButtonClassesArgs } from "./types";
44

5-
export const getStyles = (isLoading: boolean) => {
5+
export const getStyles = (isLoading: boolean, isIconOnly?: boolean) => {
6+
const padding = isIconOnly
7+
? "yl:p-2.5 yl:min-w-[2.5rem] yl:min-h-[2.5rem]"
8+
: "yl:px-3 yl:py-2";
9+
610
return {
7-
base: "yl:select-none yl:px-3 yl:py-2 yl:font-semibold yl:tracking-tight yl:rounded-md yl:border-2 yl:transition-all yl:duration-200 yl:transform yl:hover:scale-105",
11+
base: classNames(
12+
"yl:select-none yl:font-semibold yl:tracking-tight yl:rounded-md yl:border-2 yl:transition-all yl:duration-200 yl:transform yl:hover:scale-105",
13+
padding
14+
),
815
disabled: "yl:cursor-not-allowed yl:opacity-70",
916
enabled: classNames({
1017
"yl:cursor-pointer": !isLoading
@@ -68,9 +75,10 @@ export const getVariantClasses = (
6875
};
6976

7077
export const getButtonClasses = (args: IGetButtonClassesArgs) => {
71-
const { variant, disabled, outlined, isLoading, className } = args;
78+
const { variant, disabled, outlined, isLoading, className, isIconOnly } =
79+
args;
7280

73-
const styles = getStyles(isLoading);
81+
const styles = getStyles(isLoading, isIconOnly);
7482

7583
return classNames(
7684
styles.base,

src/Components/Button/__snapshots__/Button.test.tsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exports[`Button component > renders correctly - snapshot test 1`] = `
44
<DocumentFragment>
55
<button
6-
class="yl:select-none yl:px-3 yl:py-2 yl:font-semibold yl:tracking-tight yl:rounded-md yl:border-2 yl:transition-all yl:duration-200 yl:transform yl:hover:scale-105 yl:cursor-pointer yl:border-primary yl:bg-primary yl:text-background yl:hover:bg-transparent yl:hover:text-primary"
6+
class="yl:select-none yl:font-semibold yl:tracking-tight yl:rounded-md yl:border-2 yl:transition-all yl:duration-200 yl:transform yl:hover:scale-105 yl:px-3 yl:py-2 yl:cursor-pointer yl:border-primary yl:bg-primary yl:text-background yl:hover:bg-transparent yl:hover:text-primary"
77
type="button"
88
>
99
<div

0 commit comments

Comments
 (0)