Skip to content
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-12261-fixed-1747862074450.md

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

πŸŽ—οΈ Reminder to self: get UX approval before merging

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

bumping this!

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Fixed
---

Radio buttons too large on plans table ([#12261](https://github.com/linode/manager/pull/12261))
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export const PlanSelection = (props: PlanSelectionProps) => {
}
id={plan.id}
onChange={() => onSelect(plan.id)}
size="small"
/>
}
label={plan.heading}
Expand All @@ -162,6 +163,7 @@ export const PlanSelection = (props: PlanSelectionProps) => {
<TableCell
className={rowIsDisabled ? 'hasTooltip' : ''}
data-qa-plan-name
sx={{ paddingLeft: 0.5 }}
>
{plan.heading} &nbsp;
{showDisabledTooltip && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export const PlanSelectionTable = (props: PlanSelectionTableProps) => {
isPlanCell={isPlanCell}
key={testId}
noWrap={noWrap}
sx={isPlanCell ? { paddingLeft: 0.5 } : undefined}
>
{isPlanCell && filterOptions?.header
? filterOptions?.header
Expand Down
256 changes: 238 additions & 18 deletions packages/ui/src/components/Radio/Radio.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @todo: modularization - Import from 'ui' package once FormControlLabel is migrated.
import { FormControlLabel } from '@mui/material';
import React from 'react';
import React, { useState } from 'react';

import { Box } from '../Box';
import { RadioGroup } from '../RadioGroup';
Expand All @@ -9,19 +9,86 @@ import { Radio } from './Radio';
import type { RadioProps } from './Radio';
import type { Meta, StoryObj } from '@storybook/react';

const meta: Meta<RadioProps> = {
interface CustomArgs {
checkedState?: 'checked' | 'unchecked';
state?: 'active' | 'default' | 'disabled' | 'hover' | 'readonly';
}

type RadioStoryProps = RadioProps & CustomArgs;

const meta: Meta<RadioStoryProps> = {
args: {
defaultChecked: false,
disableFocusRipple: false,
disableRipple: false,
disableTouchRipple: false,
disabled: false,
name: 'radio',
readOnly: false,
checkedState: 'unchecked',
size: 'medium',
state: 'default',
},
argTypes: {
state: {
options: ['default', 'disabled', 'readonly', 'hover', 'active'],
control: { type: 'radio' },
description: 'The state to render',
table: {
type: { summary: 'string' },
defaultValue: { summary: '"default"' },
},
},
checkedState: {
options: ['unchecked', 'checked'],
control: { type: 'radio' },
description: 'The checked state of the radio button',
table: {
type: { summary: 'string' },
defaultValue: { summary: '"unchecked"' },
},
},
size: {
control: {
type: 'radio',
},
options: ['small', 'medium'],
description: 'The size of the component',
table: {
type: { summary: 'string' },
defaultValue: { summary: '"medium"' },
},
},
disableRipple: {
control: 'boolean',
description: 'If true, the ripple effect is disabled',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
disableFocusRipple: {
control: 'boolean',
description: 'If true, the focus ripple effect is disabled',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
disableTouchRipple: {
control: 'boolean',
description: 'If true, the touch ripple effect is disabled',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
name: { table: { disable: true } },
slots: { table: { disable: true } },
slotProps: { table: { disable: true } },
component: { table: { disable: true } },
ref: { table: { disable: true } },
defaultChecked: { table: { disable: true } },
disabled: { table: { disable: true } },
readOnly: { table: { disable: true } },
checked: { table: { disable: true } },
},
component: Radio,
decorators: [
(Story) => (
(Story: React.ComponentType) => (
<Box sx={{ padding: 4 }}>
<Story />
</Box>
Expand All @@ -30,23 +97,176 @@ const meta: Meta<RadioProps> = {
title: 'Foundations/Radio',
};

type Story = StoryObj<RadioProps>;
type Story = StoryObj<RadioStoryProps>;

export const Default: Story = {
render: (args: RadioProps) => <Radio {...args} />,
render: (args) => {
const {
state = 'default',
checkedState = 'unchecked',
...radioProps
} = args;

let stateProps: Partial<RadioProps> = {};
if (state === 'disabled') {
stateProps = { disabled: true };
} else if (state === 'readonly') {
stateProps = { readOnly: true };
}

let stateStyle = {};
if (state === 'hover') {
stateStyle = { backgroundColor: 'rgba(0, 0, 0, 0.04)' };
} else if (state === 'active') {
stateStyle = { backgroundColor: 'rgba(0, 0, 0, 0.08)' };
}

const isChecked = checkedState === 'checked';

return (
<Box sx={{ '& .MuiRadio-root': stateStyle }}>
<Radio {...radioProps} {...stateProps} checked={isChecked} />
</Box>
);
},
};

export const Groups: Story = {
name: 'Controlled Radio Groups',
export const Unchecked: Story = {
parameters: {
controls: { disable: true },
},
render: () => <Radio />,
};

export const UncheckedDisabled: Story = {
name: 'Unchecked Disabled',
parameters: {
controls: { disable: true },
},
render: () => <Radio disabled />,
};

export const UncheckedReadOnly: Story = {
name: 'Unchecked Read Only',
parameters: {
controls: { disable: true },
},
render: () => <Radio readOnly />,
};

export const Checked: Story = {
parameters: {
controls: { disable: true },
},
render: () => <Radio checked />,
};

export const CheckedDisabled: Story = {
name: 'Checked Disabled',
parameters: {
controls: { disable: true },
},
render: () => <Radio checked disabled />,
};

export const CheckedReadOnly: Story = {
name: 'Checked Read Only',
parameters: {
controls: { disable: true },
},
render: () => <Radio checked readOnly />,
};

export const SmallSize: Story = {
name: 'Small Size',
parameters: {
controls: { disable: true },
},
render: () => (
<RadioGroup>
<Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
<Radio size="small" />
<Radio checked size="small" />
</Box>
),
};

const RadioGroupsDemo = (props: { size: 'medium' | 'small' }) => {
const { size } = props;
const [selectedValue, setSelectedValue] = useState('Option 1');

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSelectedValue(event.target.value);
};

return (
<RadioGroup onChange={handleChange} value={selectedValue}>
<FormControlLabel
control={<Radio checked={false} disabled />}
control={<Radio disabled size={size} />}
label="Disabled"
value="Disabled"
/>
<FormControlLabel
control={<Radio size={size} />}
label="Option 1"
value="Option 1"
/>
<FormControlLabel
control={<Radio size={size} />}
label="Option 2"
value="Option 2"
/>
<FormControlLabel control={<Radio />} label="Option 1" value="Option 1" />
<FormControlLabel control={<Radio />} label="Option 2" value="Option 2" />
</RadioGroup>
);
};

interface GroupsArgs {
size: 'medium' | 'small';
}

export const Groups: StoryObj<GroupsArgs> = {
name: 'Controlled Radio Groups',
args: {
size: 'medium',
},
argTypes: {
size: {
control: {
type: 'radio',
},
options: ['small', 'medium'],
description: 'The size of the component',
table: {
type: { summary: 'string' },
defaultValue: { summary: '"medium"' },
},
},
},
render: (args) => {
return <RadioGroupsDemo size={args.size} />;
},
};

export const WithLabel: Story = {
name: 'With Label',
parameters: {
controls: { disable: true },
},
render: () => (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<FormControlLabel control={<Radio />} label="Unchecked with label" />
<FormControlLabel
control={<Radio checked />}
label="Checked with label"
/>
<FormControlLabel
control={<Radio disabled />}
label="Disabled with label"
/>
<FormControlLabel
control={<Radio checked disabled />}
label="Checked disabled with label"
/>
</Box>
),
};

Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/foundations/themes/dark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,11 @@ export const darkTheme: ThemeOptions = {
color: theme.palette.primary.main,
},
padding: '10px 10px',
'&.MuiRadio-sizeSmall': {
'.MuiSvgIcon-fontSizeSmall': {
fontSize: '16px',
},
},
}),
},
},
Expand Down