Skip to content

Commit d873273

Browse files
nicoback2nicoback
andcommitted
[Harmony] Add SelectablePill to Harmony PAY-1654 (#3803)
Co-authored-by: Nikki Kang <[email protected]>
1 parent 977ecd9 commit d873273

File tree

8 files changed

+169
-3
lines changed

8 files changed

+169
-3
lines changed

apps/audius-client/packages/stems/src/components/HarmonyButton/types.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { ComponentPropsWithoutRef, ReactNode } from 'react'
1+
import { ReactNode } from 'react'
22

33
import { IconComponent } from 'components/Icons/types'
44
import { ColorValue } from 'styles/colors'
5+
import { BaseButtonProps } from 'utils/types'
56

67
export enum HarmonyButtonType {
78
PRIMARY = 'primary',
@@ -17,8 +18,6 @@ export enum HarmonyButtonSize {
1718
LARGE = 'large'
1819
}
1920

20-
type BaseButtonProps = Omit<ComponentPropsWithoutRef<'button'>, 'children'>
21-
2221
export type HarmonyButtonProps = {
2322
/**
2423
* Override the color of the button, only valid for the `PRIMARY` variant
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
.pill {
2+
cursor: pointer;
3+
display: inline-flex;
4+
align-items: center;
5+
justify-content: center;
6+
color: var(--text-subdued);
7+
user-select: none;
8+
height: var(--unit-6);
9+
padding-left: var(--unit-3);
10+
padding-right: var(--unit-3);
11+
gap: var(--unit-1);
12+
13+
border-radius: 100px;
14+
border: 1px solid var(--border-strong);
15+
background-color: var(--white);
16+
font-size: var(--font-m);
17+
font-weight: var(--font-medium);
18+
line-height: 125%;
19+
transition: all 0.12s ease-out;
20+
}
21+
22+
.large {
23+
height: var(--unit-8);
24+
box-shadow: var(--shadow-near);
25+
color: var(--text-default);
26+
padding-left: var(--unit-4);
27+
padding-right: var(--unit-4);
28+
gap: var(--unit-2);
29+
}
30+
31+
.selected,
32+
.pill:active {
33+
background-color: var(--secondary-dark-1);
34+
border: 1px solid var(--secondary-dark-1);
35+
color: var(--static-white);
36+
}
37+
38+
.pill:hover {
39+
border: 1px solid var(--secondary);
40+
background-color: var(--secondary-light-1);
41+
color: var(--static-white);
42+
}
43+
44+
.large:hover {
45+
border: 1px solid var(--secondary-light-1);
46+
background-color: var(--secondary-light-2);
47+
box-shadow: none;
48+
}
49+
50+
.large:active,
51+
.large.selected {
52+
box-shadow: none;
53+
}
54+
55+
.icon path {
56+
fill: currentColor;
57+
}
58+
59+
.icon {
60+
margin-right: var(--unit-1);
61+
width: var(--unit-4);
62+
height: var(--unit-4);
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { useState } from 'react'
2+
3+
import { Story } from '@storybook/react'
4+
5+
import { IconHeart } from 'components/Icons'
6+
7+
import { HarmonySelectablePill } from './HarmonySelectablePill'
8+
import { HarmonySelectablePillProps } from './types'
9+
10+
export default {
11+
component: HarmonySelectablePill,
12+
title: 'Components/HarmonySelectablePill'
13+
}
14+
15+
const Template: Story<HarmonySelectablePillProps> = ({ ...args }) => {
16+
const [isSelected, setIsSelected] = useState(false)
17+
return (
18+
<HarmonySelectablePill
19+
onClick={() => setIsSelected(!isSelected)}
20+
{...args}
21+
isSelected={args.isSelected === undefined ? isSelected : args.isSelected}
22+
/>
23+
)
24+
}
25+
26+
const baseProps: Partial<HarmonySelectablePillProps> = {
27+
size: 'default',
28+
label: 'Label'
29+
}
30+
31+
// Default
32+
export const Primary = Template.bind({})
33+
Primary.args = { ...baseProps }
34+
35+
// Large
36+
export const Large = Template.bind({})
37+
Large.args = { size: 'large', ...baseProps }
38+
39+
// Icon
40+
export const WithIcon = Template.bind({})
41+
WithIcon.args = { ...baseProps, icon: IconHeart }
42+
43+
// Icon - large
44+
export const LargeWithIcon = Template.bind({})
45+
LargeWithIcon.args = { ...baseProps, size: 'large', icon: IconHeart }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { forwardRef } from 'react'
2+
3+
import cn from 'classnames'
4+
5+
import styles from './HarmonySelectablePill.module.css'
6+
import { HarmonySelectablePillProps } from './types'
7+
8+
export const HarmonySelectablePill = forwardRef<
9+
HTMLButtonElement,
10+
HarmonySelectablePillProps
11+
>((props, ref) => {
12+
const {
13+
size,
14+
isSelected,
15+
label,
16+
icon: IconComponent,
17+
className,
18+
...restProps
19+
} = props
20+
return (
21+
<button
22+
className={cn(
23+
styles.pill,
24+
{
25+
[styles.large]: size === 'large',
26+
[styles.selected]: isSelected
27+
},
28+
className
29+
)}
30+
ref={ref}
31+
{...restProps}
32+
>
33+
{IconComponent ? <IconComponent className={styles.icon} /> : null}
34+
<span>{label}</span>
35+
</button>
36+
)
37+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { HarmonySelectablePill } from './HarmonySelectablePill'
2+
export { HarmonySelectablePillProps } from './types'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { IconComponent } from 'components/Icons/types'
2+
import { BaseButtonProps } from 'utils/types'
3+
4+
export type HarmonySelectablePillProps = {
5+
size?: 'default' | 'large'
6+
isSelected: boolean
7+
label: string
8+
icon?: IconComponent
9+
onClick?: () => void
10+
} & BaseButtonProps

apps/audius-client/packages/stems/src/index.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,7 @@ export {
103103
MarkdownViewer,
104104
MarkdownViewerProps
105105
} from './components/MarkdownViewer'
106+
export {
107+
HarmonySelectablePill,
108+
HarmonySelectablePillProps
109+
} from './components/SelectablePill'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { ComponentPropsWithoutRef } from 'react'
2+
3+
export type BaseButtonProps = Omit<
4+
ComponentPropsWithoutRef<'button'>,
5+
'children'
6+
>

0 commit comments

Comments
 (0)