Skip to content

Commit 83eb5f8

Browse files
authored
Merge 238aafd into ccd5bab
2 parents ccd5bab + 238aafd commit 83eb5f8

File tree

6 files changed

+73
-80
lines changed

6 files changed

+73
-80
lines changed

packages/react/jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ module.exports = {
6969
'<rootDir>/src/__tests__/theme.test.ts',
7070
'<rootDir>/src/__tests__/themeGet.test.ts',
7171
'<rootDir>/src/__tests__/useSafeTimeout.test.ts',
72+
'<rootDir>/src/experimental/IssueLabel',
7273
'<rootDir>/src/experimental/Skeleton',
7374
'<rootDir>/src/hooks/',
7475
'<rootDir>/src/internal/utils/',

packages/react/src/experimental/IssueLabel/IssueLabel.features.stories.tsx

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,54 @@ const meta = {
99

1010
export default meta
1111

12-
export const VariantPink = () => <IssueLabel variant="pink" text="Issue label" />
12+
export const VariantPink = () => <IssueLabel variant="pink">Issue label</IssueLabel>
1313

14-
export const VariantPlum = () => <IssueLabel variant="plum" text="Issue label" />
14+
export const VariantPlum = () => <IssueLabel variant="plum">Issue label</IssueLabel>
1515

16-
export const VariantPurple = () => <IssueLabel variant="purple" text="Issue label" />
16+
export const VariantPurple = () => <IssueLabel variant="purple">Issue label</IssueLabel>
1717

18-
export const VariantIndigo = () => <IssueLabel variant="indigo" text="Issue label" />
18+
export const VariantIndigo = () => <IssueLabel variant="indigo">Issue label</IssueLabel>
1919

20-
export const VariantBlue = () => <IssueLabel variant="blue" text="Issue label" />
20+
export const VariantBlue = () => <IssueLabel variant="blue">Issue label</IssueLabel>
2121

22-
export const VariantCyan = () => <IssueLabel variant="cyan" text="Issue label" />
22+
export const VariantCyan = () => <IssueLabel variant="cyan">Issue label</IssueLabel>
2323

24-
export const VariantTeal = () => <IssueLabel variant="teal" text="Issue label" />
24+
export const VariantTeal = () => <IssueLabel variant="teal">Issue label</IssueLabel>
2525

26-
export const VariantPine = () => <IssueLabel variant="pine" text="Issue label" />
26+
export const VariantPine = () => <IssueLabel variant="pine">Issue label</IssueLabel>
2727

28-
export const VariantGreen = () => <IssueLabel variant="green" text="Issue label" />
28+
export const VariantGreen = () => <IssueLabel variant="green">Issue label</IssueLabel>
2929

30-
export const VariantLime = () => <IssueLabel variant="lime" text="Issue label" />
30+
export const VariantLime = () => <IssueLabel variant="lime">Issue label</IssueLabel>
3131

32-
export const VariantOlive = () => <IssueLabel variant="olive" text="Issue label" />
32+
export const VariantOlive = () => <IssueLabel variant="olive">Issue label</IssueLabel>
3333

34-
export const VariantLemon = () => <IssueLabel variant="lemon" text="Issue label" />
34+
export const VariantLemon = () => <IssueLabel variant="lemon">Issue label</IssueLabel>
3535

36-
export const VariantYellow = () => <IssueLabel variant="yellow" text="Issue label" />
36+
export const VariantYellow = () => <IssueLabel variant="yellow">Issue label</IssueLabel>
3737

38-
export const VariantOrange = () => <IssueLabel variant="orange" text="Issue label" />
38+
export const VariantOrange = () => <IssueLabel variant="orange">Issue label</IssueLabel>
3939

40-
export const VariantRed = () => <IssueLabel variant="red" text="Issue label" />
40+
export const VariantRed = () => <IssueLabel variant="red">Issue label</IssueLabel>
4141

42-
export const VariantCoral = () => <IssueLabel variant="coral" text="Issue label" />
42+
export const VariantCoral = () => <IssueLabel variant="coral">Issue label</IssueLabel>
4343

44-
export const VariantGray = () => <IssueLabel variant="gray" text="Issue label" />
44+
export const VariantGray = () => <IssueLabel variant="gray">Issue label</IssueLabel>
4545

46-
export const VariantBrown = () => <IssueLabel variant="brown" text="Issue label" />
46+
export const VariantBrown = () => <IssueLabel variant="brown">Issue label</IssueLabel>
4747

48-
export const VariantAuburn = () => <IssueLabel variant="auburn" text="Issue label" />
48+
export const VariantAuburn = () => <IssueLabel variant="auburn">Issue label</IssueLabel>
4949

5050
export const HexColor = (args: {fillColor: `#${string}`}) => (
51-
<IssueLabel text="Issue label" fillColor={args.fillColor} />
51+
<IssueLabel fillColor={args.fillColor}>Issue label</IssueLabel>
5252
)
5353
HexColor.args = {
5454
fillColor: '#59B200',
5555
}
5656
HexColor.argTypes = {
5757
fillColor: {control: {type: 'color'}},
5858
variant: {table: {disable: true}},
59-
text: {table: {disable: true}},
59+
children: {table: {disable: true}},
6060
id: {table: {disable: true}},
6161
className: {table: {disable: true}},
6262
onClick: {table: {disable: true}},
@@ -65,19 +65,19 @@ HexColor.argTypes = {
6565
href: {table: {disable: true}},
6666
}
6767

68-
export const AsLink = () => <IssueLabel href="/" text="Issue label" />
68+
export const AsLink = () => <IssueLabel href="/">Issue label</IssueLabel>
6969

70-
export const AsButton = () => <IssueLabel text="Issue label" as="button" />
70+
export const AsButton = () => <IssueLabel as="button">Issue label</IssueLabel>
7171

72-
export const OnClick = () => <IssueLabel text="Issue label" onClick={() => alert('clicked')} />
72+
export const OnClick = () => <IssueLabel onClick={() => alert('clicked')}>Issue label</IssueLabel>
7373

7474
export const GroupOfLabels = () => (
7575
<Stack direction="horizontal" gap="condensed" wrap="wrap">
76-
<IssueLabel variant="blue" text="Issue label" />
77-
<IssueLabel variant="purple" text="Another label" />
78-
<IssueLabel variant="green" text="A third label" />
79-
<IssueLabel variant="orange" text="Issue label" />
80-
<IssueLabel variant="yellow" text="Another label" />
81-
<IssueLabel variant="brown" text="A third label" />
76+
<IssueLabel variant="blue">Issue label</IssueLabel>
77+
<IssueLabel variant="purple">Another label</IssueLabel>
78+
<IssueLabel variant="green">A third label</IssueLabel>
79+
<IssueLabel variant="orange">Issue label</IssueLabel>
80+
<IssueLabel variant="yellow">Another label</IssueLabel>
81+
<IssueLabel variant="brown">A third label</IssueLabel>
8282
</Stack>
8383
)

packages/react/src/experimental/IssueLabel/IssueLabel.stories.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ const meta = {
88

99
export default meta
1010

11-
export const Default = () => <IssueLabel text="Issue label" />
11+
export const Default = () => <IssueLabel>Issue label</IssueLabel>
1212

1313
export const Playground: StoryObj<typeof IssueLabel> = {
1414
render: args => <IssueLabel {...args} />,
1515
args: {
16-
text: 'Issue label',
16+
children: 'Issue label',
1717
as: 'span',
1818
},
1919
argTypes: {
@@ -45,9 +45,6 @@ export const Playground: StoryObj<typeof IssueLabel> = {
4545
'auburn',
4646
],
4747
},
48-
text: {
49-
control: 'text',
50-
},
5148
as: {
5249
control: 'inline-radio',
5350
options: ['span', 'button', 'a'],
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {describe, expect, it, vi} from 'vitest'
2+
import {render, screen} from '@testing-library/react'
3+
import userEvent from '@testing-library/user-event'
4+
import {IssueLabel} from '../IssueLabel'
5+
6+
describe('IssueLabel', () => {
7+
it('should support `className` on outermost element', () => {
8+
const {container} = render(<IssueLabel className="custom-class">Label</IssueLabel>)
9+
expect(container.firstChild).toHaveClass('custom-class')
10+
})
11+
12+
it('should support merging `style` on outermost element', () => {
13+
const {container} = render(<IssueLabel style={{color: 'red', backgroundColor: 'blue'}}>Label</IssueLabel>)
14+
expect(container.firstChild).toHaveStyle({
15+
color: 'red',
16+
backgroundColor: 'blue',
17+
})
18+
})
19+
})

packages/react/src/experimental/IssueLabel/IssueLabel.tsx

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {getColorsFromHex} from './getColorFromHex'
33
import {useTheme} from '../../ThemeProvider'
44
import {clsx} from 'clsx'
55
import classes from './IssueLabel.module.css'
6-
export type Hex = `#${string}`
6+
7+
type Hex = `#${string}`
78

89
type LabelColorVariant =
910
| 'pink'
@@ -26,35 +27,15 @@ type LabelColorVariant =
2627
| 'brown'
2728
| 'auburn'
2829

29-
export interface IssueLabelProps {
30+
type IssueLabelProps<As extends React.ElementType> = {
31+
as?: As
3032
fillColor?: Hex
3133
variant?: LabelColorVariant
32-
href?: string
33-
as?: 'button' | 'a' | 'span'
34-
text: React.ReactNode
35-
id?: number | string
3634
className?: string
37-
onClick?: React.MouseEventHandler<HTMLSpanElement | HTMLButtonElement | HTMLAnchorElement>
38-
onFocus?: React.FocusEventHandler<HTMLSpanElement | HTMLButtonElement | HTMLAnchorElement>
39-
}
40-
41-
export function IssueLabel({
42-
className,
43-
fillColor,
44-
variant = 'gray',
45-
href,
46-
onClick,
47-
onFocus,
48-
text,
49-
as,
50-
id,
51-
...rest
52-
}: IssueLabelProps) {
53-
// Error handling: `href` and `onClick` should not be set simultaneously
54-
if (href && onClick) {
55-
throw new Error('`href` and `onClick` cannot both be set. Choose either a link (`<a>`) or a button (`<button>`).')
56-
}
35+
} & React.ComponentPropsWithoutRef<React.ElementType extends As ? 'span' : As>
5736

37+
function IssueLabel<As extends React.ElementType>(props: IssueLabelProps<As>) {
38+
const {as, children, className, fillColor, onClick, style, variant = 'gray', ...rest} = props
5839
const {resolvedColorScheme} = useTheme()
5940
const mode = resolvedColorScheme?.startsWith('dark') ? 'dark' : 'light'
6041
// TODO: get the bgColor, getting it from theme.colorScheme seems a bit sketchy
@@ -63,31 +44,25 @@ export function IssueLabel({
6344
dark: '#0d1117',
6445
}
6546

66-
// Determine the component type: Prioritize `as`, then fallback to `href` or `onClick` logic
67-
let Component: 'a' | 'button' | 'span' = 'span' // Default to <span>
68-
69-
if (as) {
70-
Component = as // use 'as' prop if provided
71-
} else if (href) {
72-
Component = 'a' // render as <a> if `href` is provided
47+
let BaseComponent = 'span'
48+
if ('href' in rest) {
49+
BaseComponent = 'a'
7350
} else if (onClick) {
74-
Component = 'button' // render as <button> if `onClick` is provided
51+
BaseComponent = 'button'
7552
}
7653

77-
const anchorProps = href ? {href} : {}
78-
7954
return (
80-
<Component
55+
<BaseComponent
8156
{...rest}
82-
{...anchorProps}
83-
onClick={onClick}
84-
onFocus={onFocus}
85-
id={id?.toString()}
86-
className={clsx(classes.IssueLabel, className)}
57+
className={clsx(className, classes.IssueLabel)}
8758
data-variant={fillColor ? undefined : variant}
88-
style={fillColor ? getColorsFromHex(fillColor, resolvedColorScheme, bgColors[mode]) : undefined}
59+
onClick={onClick}
60+
style={fillColor ? {...style, ...getColorsFromHex(fillColor, resolvedColorScheme, bgColors[mode])} : style}
8961
>
90-
{text}
91-
</Component>
62+
{children}
63+
</BaseComponent>
9264
)
9365
}
66+
67+
export {IssueLabel}
68+
export type {Hex, IssueLabelProps}

packages/react/vitest.config.browser.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export default defineConfig({
7979
'src/__tests__/filterObject.test.ts',
8080
'src/__tests__/theme.test.ts',
8181
'src/__tests__/themeGet.test.ts',
82+
'src/experimental/IssueLabel/**/*.test.?(c|m)[jt]s?(x)',
8283
'src/experimental/Skeleton/**/*.test.?(c|m)[jt]s?(x)',
8384
'src/hooks/**/*.test.?(c|m)[jt]s?(x)',
8485
'src/internal/utils/**/*.test.?(c|m)[jt]s?(x)',

0 commit comments

Comments
 (0)