Skip to content

Commit 7489b0b

Browse files
Merge release/v3.3.0 into main branch (#1262)
* noMargin prop for FormGroup (#1261) * Adds description to `Option` (#1258)
1 parent 13ff075 commit 7489b0b

File tree

8 files changed

+111
-7
lines changed

8 files changed

+111
-7
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@user-interviews/ui-design-system",
3-
"version": "3.2.3",
3+
"version": "3.3.0",
44
"dependencies": {
55
"@tiptap/core": "^2.4.0",
66
"@tiptap/extension-bold": "^2.4.0",

scss/forms/form_group.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
}
5555
}
5656

57+
&--no-margin {
58+
margin: 0;
59+
}
60+
5761
&__helper-text {
5862
@include synth-font-type-20;
5963
color: var(--ux-gray-900);

src/FormGroup/FormGroup.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ be beneficial to the user
4242

4343
<Canvas of={ComponentStories.Required} />
4444

45+
### No margin
46+
47+
- Remove the default margin on the FormGroup.
48+
49+
<Canvas of={ComponentStories.NoMargin} />
50+
4551
### With Label Tooltip
4652

4753
- Information users will typically only reference once (and then it's learned) or here and there.

src/FormGroup/FormGroup.stories.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useState } from 'react';
22
import { faSearch } from '@fortawesome/pro-solid-svg-icons';
33

4+
import { FlexContainer } from 'src/FlexContainer';
45
import FormGroup from '.';
56
import Input from '../Input';
67
import FormControlLabel from '../FormControlLabel';
@@ -56,6 +57,27 @@ export const Required = () => (
5657
</FormGroup>
5758
);
5859

60+
export const NoMargin = () => (
61+
<FlexContainer flexDirection="column" gap={4}>
62+
<FormGroup
63+
label="Label"
64+
labelHtmlFor="no-margin-1-input"
65+
noMargin
66+
required
67+
>
68+
<InputComponent id="no-margin-1-input" placeholder="This FormGroup has no default margin" />
69+
</FormGroup>
70+
<FormGroup
71+
label="Label"
72+
labelHtmlFor="no-margin-2-input"
73+
noMargin
74+
required
75+
>
76+
<InputComponent id="no-margin-2-input" placeholder="This FormGroup has no default margin" />
77+
</FormGroup>
78+
</FlexContainer>
79+
);
80+
5981
export const WithLabelTooltip = () => (
6082
<FormGroup
6183
id="with-label"

src/FormGroup/FormGroup.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export type FormGroupProps = {
5757
labelHelperText?: string;
5858
labelHtmlFor?: string;
5959
labelTooltip?: React.ReactNode;
60+
noMargin?: boolean;
6061
required?: boolean;
6162
};
6263

@@ -76,6 +77,7 @@ export default function FormGroup({
7677
labelHelperText,
7778
labelHtmlFor = '',
7879
labelTooltip,
80+
noMargin,
7981
required,
8082
}: FormGroupProps) {
8183
const errorMessage = buildErrorMessage(errors[inputKey || ''], label);
@@ -137,6 +139,7 @@ export default function FormGroup({
137139
'FormGroup--is-invalid': hasErrors,
138140
'FormGroup--bordered': bordered,
139141
'FormGroup--inline': inline,
142+
'FormGroup--no-margin': noMargin,
140143
},
141144
),
142145
id,

src/Select/Option.jsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { forwardRef } from 'react';
2+
import classNames from 'classnames';
23
import { components } from 'react-select';
34

45
import CheckboxButton from 'src/CheckboxButton';
@@ -24,10 +25,21 @@ const Option = forwardRef(({ indeterminate, ...props }, ref) => (
2425
ref={ref}
2526
onChange={() => null}
2627
/>
27-
<label>{props.label}</label>
28+
<div className="TitleDescriptionContainer">
29+
<label
30+
className={classNames({
31+
'Label--bold': props.description,
32+
})}
33+
>
34+
{props.label}
35+
</label>
36+
{ props.description && (
37+
<span className="Description">{ props.description }</span>
38+
)}
39+
</div>
2840
</div>
2941
</components.Option>
30-
));
42+
));
3143
/* eslint-enable react/prop-types */
3244

3345
export default Option;

src/Select/Option.scss

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,19 @@
55
.Checkbox {
66
margin-right: var(--synth-spacing-3);
77
}
8+
9+
.TitleDescriptionContainer {
10+
display: flex;
11+
flex-direction: column;
12+
13+
.Label {
14+
&--bold {
15+
font-weight: var(--synth-font-weight-bold);
16+
}
17+
}
18+
19+
.Description {
20+
color: var(--ux-gray-800);
21+
}
22+
}
823
}

src/Select/SingleSelect.stories.jsx

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,26 @@ export default {
2020
};
2121

2222
const options = [
23-
{ label: '1-on-1 interview', value: 1 },
24-
{ label: 'Focus group', value: 2 },
25-
{ label: 'Multi-day study', value: 3 },
26-
{ label: 'Unmoderated task', value: 4 },
23+
{
24+
label: '1-on-1 interview',
25+
value: 1,
26+
description: 'Interviews are typically a conversation between you and a researcher.',
27+
},
28+
{
29+
label: 'Focus group',
30+
value: 2,
31+
description: 'Focus groups involve interacting with a small group of your peers.',
32+
},
33+
{
34+
label: 'Multi-day study',
35+
value: 3,
36+
description: 'Diary and multiday studies are days or weeks long commitments.',
37+
},
38+
{
39+
label: 'Unmoderated task',
40+
value: 4,
41+
description: 'An unmoderated task is just that—an opportunity for a user to try out a product, app, website, etc and share feedback.',
42+
},
2743
];
2844

2945
const peopleOptions = [
@@ -168,6 +184,32 @@ export const GroupedOptions = () => {
168184
);
169185
};
170186

187+
export const CustomOptionWithDescriptionAndCheckbox = () => (
188+
<FormGroup
189+
label="Custom Option with Description And Checkbox"
190+
labelHtmlFor="custom-option-with-description-and-checkbox-select"
191+
>
192+
<SingleSelect
193+
components={{
194+
Option: ({ ...props }) => (
195+
<Option
196+
{...props}
197+
// eslint-disable-next-line react/prop-types
198+
description={props.data.description}
199+
/>
200+
),
201+
}}
202+
inputId="custom-option-with-description-select"
203+
options={options}
204+
onChange={onChange}
205+
/>
206+
</FormGroup>
207+
);
208+
209+
/**
210+
If you're adding a new code, prefer the use of `Option` with a `description` prop.
211+
`OptionWithDescription` is effectively deprecated and will be merged into `Option`.
212+
*/
171213
export const CustomOptionWithDescription = () => {
172214
const optionsWithDescriptions = [
173215
{

0 commit comments

Comments
 (0)