Skip to content

Commit

Permalink
Checkbox and Radio Button Icon Alignment (#2694)
Browse files Browse the repository at this point in the history
Co-authored-by: Josh Wooding <[email protected]>
  • Loading branch information
lilyvc and joshwooding authored Nov 14, 2023
1 parent 3b57518 commit bb41157
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 6 deletions.
6 changes: 6 additions & 0 deletions .changeset/ten-mayflies-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@salt-ds/core": patch
---

Fixed alignment for Checkbox and Radio Button. They are now correctly aligned to their labels.
Fixed alignment for Checkbox Group and Radio Button Group when in a Form Field with label left. The Form Field label is now inline with the groups.
7 changes: 5 additions & 2 deletions packages/core/src/checkbox/Checkbox.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
cursor: var(--salt-selectable-cursor-readonly);
}

.saltCheckbox-input,
.saltCheckboxIcon {
margin-top: calc((var(--salt-text-lineHeight) - var(--salt-size-selectable)) / 2);
}

.saltCheckboxIcon > svg {
/* ensures svg is centered in all browsers */
transform: translate(0px, 0px);
Expand Down Expand Up @@ -55,11 +60,9 @@
/* Styles applied to input element */
.saltCheckbox-input {
cursor: inherit;
left: 0;
margin: 0;
opacity: 0;
padding: 0;
position: absolute;
top: 0;
z-index: var(--salt-zIndex-default);
}
6 changes: 6 additions & 0 deletions packages/core/src/checkbox/CheckboxGroup.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@
.saltCheckboxGroup-noWrap .saltCheckbox {
white-space: break-spaces;
}

/* Styles applied when checkbox button group is inside a form field with label left or right */
.saltFormField-labelLeft .saltCheckboxGroup,
.saltFormField-labelRight .saltCheckboxGroup {
padding-top: var(--salt-spacing-100);
}
10 changes: 7 additions & 3 deletions packages/core/src/radio-button/RadioButton.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
line-height: var(--salt-text-lineHeight);
font-family: var(--salt-text-fontFamily);
font-weight: var(--salt-text-fontWeight);

--radioButton-icon-marginTop: calc((var(--salt-text-lineHeight) - var(--salt-size-selectable)) / 2);
}

/* Styles applied when RadioButton is disabled */
Expand All @@ -29,14 +31,16 @@
position: absolute;
height: var(--salt-size-selectable);
opacity: 0;
top: 0;
left: 0;
margin: 0;
margin: var(--radioButton-icon-marginTop) 0 0 0;
padding: 0;
width: var(--salt-size-selectable);
z-index: var(--salt-zIndex-default);
}

.saltRadioButtonIcon {
margin-top: var(--radioButton-icon-marginTop);
}

.saltRadioButtonIcon > svg {
/* ensures svg is centered in all browsers */
transform: translate(0px, 0px);
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/radio-button/RadioButtonGroup.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,9 @@
.saltRadioButtonGroup-noWrap .saltRadioButton {
white-space: break-spaces;
}

/* Styles applied when radio button group is inside a form field with label left or right */
.saltFormField-labelLeft .saltRadioButtonGroup,
.saltFormField-labelRight .saltRadioButtonGroup {
padding-top: var(--salt-spacing-100);
}
26 changes: 25 additions & 1 deletion packages/core/stories/checkbox/checkbox.qa.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { Meta, StoryFn } from "@storybook/react";
import { Checkbox, CheckboxGroup, CheckboxGroupProps } from "@salt-ds/core";
import {
Checkbox,
CheckboxGroup,
CheckboxGroupProps,
FormField,
FormFieldLabel,
FormFieldHelperText,
} from "@salt-ds/core";
import { QAContainer, QAContainerProps } from "docs/components";

export default {
Expand Down Expand Up @@ -38,11 +45,28 @@ const CheckboxGroupExample = ({
);
};

const CheckboxInFormFieldExample = () => {
return (
<FormField labelPlacement="left">
<FormFieldLabel>Assignment</FormFieldLabel>
<CheckboxGroup>
<Checkbox label="Private placement of equity or debt securities" />
<Checkbox defaultChecked label="Syndicated credit facility or loan" />
<Checkbox label="Interest rate, foreign exchange or commodity hedging or equity derivative" />
<Checkbox label="Escrow arrangement" />
<Checkbox label="Restructuring of debt securities of the Counterparty or the Company" />
</CheckboxGroup>
<FormFieldHelperText>Select all appropriate</FormFieldHelperText>
</FormField>
);
};

export const AllExamplesGrid: StoryFn<QAContainerProps> = (props) => {
return (
<QAContainer cols={1} itemPadding={8} {...props}>
<CheckboxGroupExample direction="vertical" />
<CheckboxGroupExample direction="horizontal" />
<CheckboxInFormFieldExample />
</QAContainer>
);
};
Expand Down
97 changes: 97 additions & 0 deletions packages/core/stories/form-field/form-field.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,103 @@ export const LabelLeft: StoryFn<typeof FormField> = (props) => {
);
};

export const LabelLeftWithControls: StoryFn<typeof FormField> = (props) => {
const [isRadioError, setIsRadioError] = useState(true);

const [radioGroupValue, setRadioGroupValue] = useState("");
const [checkboxGroupValue, setCheckboxGroupValue] = useState<string[]>([]);

const handleRadioChange: ChangeEventHandler<HTMLInputElement> = (event) => {
const { value } = event.target;
setRadioGroupValue(value);
props.onChange?.(event);
isRadioError && setIsRadioError(false);
};

const handleCheckboxChange: ChangeEventHandler<HTMLInputElement> = (
event
) => {
const { value } = event.target;
if (checkboxGroupValue.indexOf(value) === -1) {
setCheckboxGroupValue((prevControlledValues) => [
...prevControlledValues,
value,
]);
} else {
setCheckboxGroupValue((prevControlledValues) =>
prevControlledValues.filter(
(controlledValue) => controlledValue !== value
)
);
}
props.onChange?.(event);
};

const isCheckboxError = checkboxGroupValue.length === 0;

return (
<FlowLayout style={{ width: "466px" }}>
<FormField labelPlacement="left" {...props}>
<FormLabel>Client directed request</FormLabel>
<RadioButtonGroup direction="horizontal">
<RadioButton key="option1" label="Yes" value="yes" />
<RadioButton key="option2" label="No" value="no" />
</RadioButtonGroup>
</FormField>
<FormField labelPlacement="left" {...props}>
<FormLabel>Assignment</FormLabel>
<CheckboxGroup>
<Checkbox label="Private placement of equity or debt securities" />
<Checkbox defaultChecked label="Syndicated credit facility or loan" />
<Checkbox label="Interest rate, foreign exchange or commodity hedging or equity derivative" />
<Checkbox label="Escrow arrangement" />
<Checkbox label="Restructuring of debt securities of the Counterparty or the Company" />
</CheckboxGroup>
<FormHelperText>Select all appropriate</FormHelperText>
</FormField>
<FormField
labelPlacement="left"
validationStatus={isRadioError ? "error" : undefined}
{...props}
>
<FormLabel>Deal owner</FormLabel>
<RadioButtonGroup onChange={handleRadioChange} value={radioGroupValue}>
{radioData.map((radio) => {
return (
<RadioButton
key={radio.label}
label={radio.label}
value={radio.value}
/>
);
})}
</RadioButtonGroup>
<FormHelperText>{`${
isRadioError ? "Must select one option. " : ""
}Is this deal for the ultimate parent or a subsidiary?`}</FormHelperText>
</FormField>
<FormField
labelPlacement="left"
validationStatus={isCheckboxError ? "error" : undefined}
{...props}
>
<FormLabel>Fee type</FormLabel>
<CheckboxGroup
checkedValues={checkboxGroupValue}
onChange={handleCheckboxChange}
>
{checkboxesData.map((data) => (
<Checkbox key={data.value} {...data} />
))}
</CheckboxGroup>
<FormHelperText>{`${
isCheckboxError ? "Must select at least one option. " : ""
}`}</FormHelperText>
</FormField>
</FlowLayout>
);
};

export const LabelQuestion: StoryFn<typeof FormField> = (props) => {
return (
<FormField {...props}>
Expand Down
18 changes: 18 additions & 0 deletions packages/core/stories/radio-button/radio-button.qa.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
FormField,
FormFieldLabel,
RadioButton,
RadioButtonGroup,
RadioButtonGroupProps,
Expand Down Expand Up @@ -38,11 +40,27 @@ const RadioButtonGroupExample = ({
);
};

const RadioButtonInFormFieldExample = () => {
return (
<FormField labelPlacement="left">
<FormFieldLabel>Assignment</FormFieldLabel>
<RadioButtonGroup>
<RadioButton label="Private placement of equity or debt securities" />
<RadioButton label="Syndicated credit facility or loan" />
<RadioButton label="Interest rate, foreign exchange or commodity hedging or equity derivative" />
<RadioButton label="Escrow arrangement" />
<RadioButton label="Restructuring of debt securities of the Counterparty or the Company" />
</RadioButtonGroup>
</FormField>
);
};

export const AllExamplesGrid: StoryFn<QAContainerProps> = (props) => {
return (
<QAContainer cols={1} itemPadding={8} {...props}>
<RadioButtonGroupExample direction="vertical" />
<RadioButtonGroupExample direction="horizontal" />
<RadioButtonInFormFieldExample />
</QAContainer>
);
};
Expand Down

1 comment on commit bb41157

@vercel
Copy link

@vercel vercel bot commented on bb41157 Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.