Skip to content

Commit 68674c5

Browse files
authoredNov 8, 2023
feat(fuselage): create LabelInfo component (#1214)
1 parent 51e16ef commit 68674c5

File tree

10 files changed

+298
-1
lines changed

10 files changed

+298
-1
lines changed
 

‎.changeset/tame-bikes-reflect.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@rocket.chat/fuselage": minor
3+
---
4+
5+
feat(fuselage): create `LabelInfo` component

‎packages/fuselage/src/components/Field/Field.stories.tsx

+33
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
ToggleSwitch,
1515
FieldLink,
1616
} from '../..';
17+
import { FieldLabelInfo } from './FieldLabelInfo';
1718

1819
export default {
1920
title: 'Inputs/Field',
@@ -47,6 +48,38 @@ export const Default: ComponentStory<typeof Field> = () => (
4748
<FieldHint>Hint</FieldHint>
4849
</Field>
4950
);
51+
export const WithLabelInfo: ComponentStory<typeof Field> = () => (
52+
<Field>
53+
<FieldLabel htmlFor='label-info-id'>
54+
Label
55+
<FieldLabelInfo id='info-id' title='this is a info label' />
56+
</FieldLabel>
57+
<FieldDescription>Description</FieldDescription>
58+
<FieldRow>
59+
<InputBox id='label-info-id' type='text' aria-describedby='info-id' />
60+
</FieldRow>
61+
<FieldError>Error</FieldError>
62+
<FieldHint>Hint</FieldHint>
63+
</Field>
64+
);
65+
export const RequiredWithLabelInfo: ComponentStory<typeof Field> = () => (
66+
<Field>
67+
<FieldLabel required htmlFor='label-required-id'>
68+
Label
69+
<FieldLabelInfo id='required-info-id' title='this is a info label' />
70+
</FieldLabel>
71+
<FieldDescription>Description</FieldDescription>
72+
<FieldRow>
73+
<InputBox
74+
id='label-required-id'
75+
type='text'
76+
aria-describedby='required-info-id'
77+
/>
78+
</FieldRow>
79+
<FieldError>Error</FieldError>
80+
<FieldHint>Hint</FieldHint>
81+
</Field>
82+
);
5083

5184
export const WithCheckBox: ComponentStory<typeof Field> = () => (
5285
<Field>

‎packages/fuselage/src/components/Field/FieldLabel.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Box from '../Box';
66
import { Label } from '../Label';
77
import { FieldContext } from './Field';
88

9-
type FieldLabelProps = ComponentPropsWithoutRef<typeof Box>;
9+
type FieldLabelProps = ComponentPropsWithoutRef<typeof Label>;
1010

1111
export const FieldLabel = (props: FieldLabelProps) => {
1212
const component = <Box is={Label} rcx-field__label {...props} />;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { ComponentProps } from 'react';
2+
import React from 'react';
3+
4+
import WithErrorWrapper from '../../helpers/WithErrorWrapper';
5+
import { LabelInfo } from '../Label/LabelInfo';
6+
import { FieldContext } from './Field';
7+
8+
type FieldLabelInfoProps = ComponentProps<typeof LabelInfo>;
9+
10+
export const FieldLabelInfo = (props: FieldLabelInfoProps) => {
11+
const component = <LabelInfo {...props} />;
12+
13+
if (process.env.NODE_ENV === 'development') {
14+
return (
15+
<WithErrorWrapper
16+
context={FieldContext}
17+
parentComponent='Field'
18+
componentName={FieldLabelInfo.name}
19+
>
20+
{component}
21+
</WithErrorWrapper>
22+
);
23+
}
24+
25+
return component;
26+
};

‎packages/fuselage/src/components/Field/__snapshots__/Field.spec.tsx.snap

+126
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,72 @@ exports[`[Field Component] renders Default without crashing 1`] = `
4242
</body>
4343
`;
4444

45+
exports[`[Field Component] renders RequiredWithLabelInfo without crashing 1`] = `
46+
<body>
47+
<div>
48+
<div
49+
class="rcx-box rcx-box--full rcx-field"
50+
>
51+
<label
52+
class="rcx-box rcx-box--full rcx-label rcx-box rcx-box--full rcx-field__label"
53+
for="label-required-id"
54+
>
55+
Label
56+
<span
57+
class="rcx-box rcx-box--full rcx-label__info rcx-css-wcp0mp"
58+
>
59+
<span
60+
hidden=""
61+
id="required-info-id"
62+
>
63+
this is a info label
64+
</span>
65+
<i
66+
aria-hidden="true"
67+
class="rcx-box rcx-box--full rcx-icon--name-info-circled rcx-icon"
68+
title="this is a info label"
69+
>
70+
71+
</i>
72+
</span>
73+
<span
74+
aria-hidden="true"
75+
class="rcx-box rcx-box--full rcx-label__required rcx-css-b7g1a9"
76+
>
77+
*
78+
</span>
79+
</label>
80+
<span
81+
class="rcx-box rcx-box--full rcx-field__description"
82+
>
83+
Description
84+
</span>
85+
<span
86+
class="rcx-box rcx-box--full rcx-field__row"
87+
>
88+
<input
89+
aria-describedby="required-info-id"
90+
class="rcx-box rcx-box--full rcx-box--animated rcx-input-box--type-text rcx-input-box"
91+
id="label-required-id"
92+
size="1"
93+
type="text"
94+
/>
95+
</span>
96+
<span
97+
class="rcx-box rcx-box--full rcx-field__error"
98+
>
99+
Error
100+
</span>
101+
<span
102+
class="rcx-box rcx-box--full rcx-field__hint"
103+
>
104+
Hint
105+
</span>
106+
</div>
107+
</div>
108+
</body>
109+
`;
110+
45111
exports[`[Field Component] renders WithCheckBox without crashing 1`] = `
46112
<body>
47113
<div>
@@ -252,6 +318,66 @@ exports[`[Field Component] renders WithHintAndLink without crashing 1`] = `
252318
</body>
253319
`;
254320

321+
exports[`[Field Component] renders WithLabelInfo without crashing 1`] = `
322+
<body>
323+
<div>
324+
<div
325+
class="rcx-box rcx-box--full rcx-field"
326+
>
327+
<label
328+
class="rcx-box rcx-box--full rcx-label rcx-box rcx-box--full rcx-field__label"
329+
for="label-info-id"
330+
>
331+
Label
332+
<span
333+
class="rcx-box rcx-box--full rcx-label__info rcx-css-wcp0mp"
334+
>
335+
<span
336+
hidden=""
337+
id="info-id"
338+
>
339+
this is a info label
340+
</span>
341+
<i
342+
aria-hidden="true"
343+
class="rcx-box rcx-box--full rcx-icon--name-info-circled rcx-icon"
344+
title="this is a info label"
345+
>
346+
347+
</i>
348+
</span>
349+
</label>
350+
<span
351+
class="rcx-box rcx-box--full rcx-field__description"
352+
>
353+
Description
354+
</span>
355+
<span
356+
class="rcx-box rcx-box--full rcx-field__row"
357+
>
358+
<input
359+
aria-describedby="info-id"
360+
class="rcx-box rcx-box--full rcx-box--animated rcx-input-box--type-text rcx-input-box"
361+
id="label-info-id"
362+
size="1"
363+
type="text"
364+
/>
365+
</span>
366+
<span
367+
class="rcx-box rcx-box--full rcx-field__error"
368+
>
369+
Error
370+
</span>
371+
<span
372+
class="rcx-box rcx-box--full rcx-field__hint"
373+
>
374+
Hint
375+
</span>
376+
</div>
377+
</div>
378+
</body>
379+
`;
380+
255381
exports[`[Field Component] renders WithLink without crashing 1`] = `
256382
<body>
257383
<div>

‎packages/fuselage/src/components/Field/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { FieldDescription } from './FieldDescription';
33
import { FieldError } from './FieldError';
44
import { FieldHint } from './FieldHint';
55
import { FieldLabel } from './FieldLabel';
6+
import { FieldLabelInfo } from './FieldLabelInfo';
67
import { FieldLink } from './FieldLink';
78
import { FieldRow } from './FieldRow';
89

@@ -12,6 +13,7 @@ export {
1213
FieldError,
1314
FieldHint,
1415
FieldLabel,
16+
FieldLabelInfo,
1517
FieldLink,
1618
FieldRow,
1719
};

‎packages/fuselage/src/components/Label/Label.stories.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { ComponentStory, ComponentMeta } from '@storybook/react';
99
import React from 'react';
1010

1111
import { Label } from '../..';
12+
import { LabelInfo } from './LabelInfo';
1213

1314
export default {
1415
title: 'Inputs/Label',
@@ -42,6 +43,20 @@ Required.args = {
4243
required: true,
4344
};
4445

46+
export const Info: ComponentStory<typeof Label> = (args) => (
47+
<Label {...args}>
48+
Label
49+
<LabelInfo title='this is a label info' />
50+
</Label>
51+
);
52+
53+
export const InfoRequired: ComponentStory<typeof Label> = (args) => (
54+
<Label required {...args}>
55+
Label
56+
<LabelInfo title='this is a label info' />
57+
</Label>
58+
);
59+
4560
export const Disabled: ComponentStory<typeof Label> = Template.bind({});
4661
Disabled.args = {
4762
disabled: true,

‎packages/fuselage/src/components/Label/Label.styles.scss

+9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
@use '../../styles/colors.scss';
22
@use '../../styles/typography.scss';
3+
@use '../../styles/lengths.scss';
34

45
.rcx-label {
56
@include typography.use-font-scale(p2m);
7+
display: flex;
8+
69
color: colors.font(default);
710

811
&--disabled {
@@ -11,6 +14,12 @@
1114
color: colors.font(secondary-info);
1215
}
1316

17+
&__info {
18+
display: flex;
19+
align-items: center;
20+
order: 1;
21+
}
22+
1423
&__required {
1524
color: colors.font(danger);
1625
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { ComponentProps } from 'react';
2+
import React from 'react';
3+
4+
import Box from '../Box/Box';
5+
import { Icon } from '../Icon';
6+
7+
type LabelInfoProps = {
8+
title: string;
9+
id?: string;
10+
} & Omit<ComponentProps<typeof Icon>, 'name'>;
11+
12+
export const LabelInfo = ({ title, id, ...props }: LabelInfoProps) => (
13+
<Box is='span' mi={2} rcx-label__info>
14+
<span hidden id={id}>
15+
{title}
16+
</span>
17+
<Icon {...props} name='info-circled' title={title} />
18+
</Box>
19+
);

‎packages/fuselage/src/components/Label/__snapshots__/Label.spec.tsx.snap

+62
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,68 @@ exports[`[Label Component] renders Disabled without crashing 1`] = `
2424
</body>
2525
`;
2626

27+
exports[`[Label Component] renders Info without crashing 1`] = `
28+
<body>
29+
<div>
30+
<label
31+
class="rcx-box rcx-box--full rcx-label"
32+
>
33+
Label
34+
<span
35+
class="rcx-box rcx-box--full rcx-label__info rcx-css-wcp0mp"
36+
>
37+
<span
38+
hidden=""
39+
>
40+
this is a label info
41+
</span>
42+
<i
43+
aria-hidden="true"
44+
class="rcx-box rcx-box--full rcx-icon--name-info-circled rcx-icon"
45+
title="this is a label info"
46+
>
47+
48+
</i>
49+
</span>
50+
</label>
51+
</div>
52+
</body>
53+
`;
54+
55+
exports[`[Label Component] renders InfoRequired without crashing 1`] = `
56+
<body>
57+
<div>
58+
<label
59+
class="rcx-box rcx-box--full rcx-label"
60+
>
61+
Label
62+
<span
63+
class="rcx-box rcx-box--full rcx-label__info rcx-css-wcp0mp"
64+
>
65+
<span
66+
hidden=""
67+
>
68+
this is a label info
69+
</span>
70+
<i
71+
aria-hidden="true"
72+
class="rcx-box rcx-box--full rcx-icon--name-info-circled rcx-icon"
73+
title="this is a label info"
74+
>
75+
76+
</i>
77+
</span>
78+
<span
79+
aria-hidden="true"
80+
class="rcx-box rcx-box--full rcx-label__required rcx-css-b7g1a9"
81+
>
82+
*
83+
</span>
84+
</label>
85+
</div>
86+
</body>
87+
`;
88+
2789
exports[`[Label Component] renders Required without crashing 1`] = `
2890
<body>
2991
<div>

0 commit comments

Comments
 (0)
Please sign in to comment.