feat(form): add select size variants
This commit is contained in:
parent
56f642aadd
commit
934a612df3
5 changed files with 59 additions and 4 deletions
|
|
@ -73,6 +73,7 @@
|
|||
.select {
|
||||
width: auto;
|
||||
min-width: 130px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
background:
|
||||
|
|
@ -95,7 +96,6 @@
|
|||
font: inherit;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
padding: 8px 32px 8px 12px;
|
||||
transition:
|
||||
border-color 0.18s ease,
|
||||
background 0.18s ease,
|
||||
|
|
@ -107,6 +107,24 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selectSizeSm {
|
||||
min-height: 32px;
|
||||
padding: 6px 30px 6px 10px;
|
||||
background-position:
|
||||
0 0,
|
||||
0 0,
|
||||
right 10px center;
|
||||
}
|
||||
|
||||
.selectSizeMd {
|
||||
min-height: 36px;
|
||||
padding: 8px 32px 8px 12px;
|
||||
background-position:
|
||||
0 0,
|
||||
0 0,
|
||||
right 12px center;
|
||||
}
|
||||
|
||||
.select:hover {
|
||||
border-color: rgba(255, 255, 255, 0.16);
|
||||
background:
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ describe('form primitives', () => {
|
|||
expect(screen.getByText('Short summary')).toBeInTheDocument();
|
||||
expect(screen.getByRole('alert')).toHaveTextContent('Validation failed');
|
||||
expect(screen.getByLabelText('Status')).toHaveValue('open');
|
||||
expect(screen.getByLabelText('Status')).toHaveAttribute('data-size', 'md');
|
||||
fireEvent.change(screen.getByLabelText('Status'), { target: { value: 'resolved' } });
|
||||
expect(screen.getByLabelText('Status')).toHaveValue('resolved');
|
||||
|
||||
|
|
@ -176,4 +177,15 @@ describe('form primitives', () => {
|
|||
'primary',
|
||||
);
|
||||
});
|
||||
|
||||
it('supports compact select sizing', () => {
|
||||
render(
|
||||
<Select aria-label="Compact" defaultValue="one" size="sm">
|
||||
<option value="one">One</option>
|
||||
<option value="two">Two</option>
|
||||
</Select>,
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText('Compact')).toHaveAttribute('data-size', 'sm');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -77,13 +77,32 @@ export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(function
|
|||
return <textarea ref={ref} className={clsx(styles.textArea, className)} {...props} />;
|
||||
});
|
||||
|
||||
export type SelectProps = SelectHTMLAttributes<HTMLSelectElement>;
|
||||
export type SelectSize = 'sm' | 'md';
|
||||
|
||||
export type SelectProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, 'className' | 'size'> & {
|
||||
className?: string;
|
||||
size?: SelectSize;
|
||||
};
|
||||
|
||||
export const Select = forwardRef<HTMLSelectElement, SelectProps>(function Select(
|
||||
{ className, ...props },
|
||||
{ className, size = 'md', ...props },
|
||||
ref,
|
||||
) {
|
||||
return <select ref={ref} className={clsx(styles.select, className)} {...props} />;
|
||||
return (
|
||||
<select
|
||||
ref={ref}
|
||||
className={clsx(
|
||||
styles.select,
|
||||
{
|
||||
[styles.selectSizeSm]: size === 'sm',
|
||||
[styles.selectSizeMd]: size === 'md',
|
||||
},
|
||||
className,
|
||||
)}
|
||||
data-size={size}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
type BaseCheckboxProps = ComponentPropsWithoutRef<typeof BaseCheckbox.Root>;
|
||||
|
|
|
|||
|
|
@ -303,6 +303,11 @@ describe('import route', () => {
|
|||
|
||||
expect(await screen.findByRole('button', { name: /^Needs Review\s*1$/ })).toBeInTheDocument();
|
||||
expect(screen.getAllByText('Album A').length).toBeGreaterThan(0);
|
||||
const intervalSelect = document.getElementById('auto-import-interval');
|
||||
if (!(intervalSelect instanceof HTMLElement)) {
|
||||
throw new Error('auto-import interval select missing');
|
||||
}
|
||||
expect(intervalSelect).toHaveAttribute('data-size', 'sm');
|
||||
expect(getFetchUrls().some((url) => url.includes('/api/import/staging/groups'))).toBe(false);
|
||||
expect(getFetchUrls().some((url) => url.includes('/api/import/staging/suggestions'))).toBe(
|
||||
false,
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ export function AutoImportPanel({
|
|||
<span>Interval:</span>
|
||||
<Select
|
||||
id="auto-import-interval"
|
||||
size="sm"
|
||||
value={interval}
|
||||
onChange={(event) => setInterval(Number(event.target.value))}
|
||||
>
|
||||
|
|
|
|||
Loading…
Reference in a new issue