one padding value, for the device on the toggle
The three columns became one select. Which breakpoint it writes comes from the device control above it, so the value you see is the value for the view you are looking at.
This commit is contained in:
+13
-38
@@ -1,3 +1,4 @@
|
||||
import { useDevice } from '../DeviceToggle';
|
||||
/**
|
||||
* The site's horizontal gutter: how far the content sits from the edge of the window.
|
||||
*
|
||||
@@ -23,17 +24,8 @@
|
||||
|
||||
export type Gutter = Partial<Record<'base' | 'md' | 'lg', number>>;
|
||||
|
||||
/**
|
||||
* The three widths, smallest first, with the name the admin uses for each.
|
||||
*
|
||||
* Smallest first because that is the direction they cascade: `md` inherits from `base`, `lg` from `md`.
|
||||
* Read left to right, the row is the progression.
|
||||
*/
|
||||
const WIDTHS = [
|
||||
{ key: 'base' as const, label: 'Mobile', hint: 'every width' },
|
||||
{ key: 'md' as const, label: 'Tablet', hint: '768 and up' },
|
||||
{ key: 'lg' as const, label: 'Desktop', hint: '1024 and up' },
|
||||
];
|
||||
/** The device toggle's names, and the breakpoint each one writes. */
|
||||
const BREAKPOINT = { desktop: 'lg', tablet: 'md', mobile: 'base' } as const;
|
||||
|
||||
/** What a width falls back to: the nearest smaller one that has a value. */
|
||||
const inherited = (gutter: Gutter, key: 'base' | 'md' | 'lg'): number | null => {
|
||||
@@ -55,53 +47,36 @@ export const GutterTab = ({
|
||||
steps: number[];
|
||||
onChange: (gutter: Gutter) => void;
|
||||
}) => {
|
||||
const set = (key: 'base' | 'md' | 'lg', value: string) => {
|
||||
const [device] = useDevice();
|
||||
const key = BREAKPOINT[device];
|
||||
|
||||
const set = (value: string) => {
|
||||
const next = { ...gutter };
|
||||
// Removed rather than stored as null: an absence is what "inherit" means, and a marker for it would
|
||||
// leave two ways to say the same thing.
|
||||
// Removed rather than stored as null: an absence is what "inherit" means.
|
||||
if (value === '') delete next[key];
|
||||
else next[key] = Number(value);
|
||||
onChange(next);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex flex-wrap items-baseline gap-2">
|
||||
<h4 className="text-xs font-medium">Horizontal padding</h4>
|
||||
<span className="text-[10px] text-muted-foreground">
|
||||
The space between the content and the edge of the window — the header, the page and the footer
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-3 gap-3 sm:grid-cols-4">
|
||||
{WIDTHS.map(({ key, label, hint }) => {
|
||||
const own = gutter[key];
|
||||
const from = inherited(gutter, key);
|
||||
|
||||
return (
|
||||
<div key={key} className="flex flex-col gap-1">
|
||||
<label className="text-xs">{label}</label>
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs">Horizontal padding</label>
|
||||
<select
|
||||
value={own === undefined ? '' : String(own)}
|
||||
onChange={(event) => set(key, event.currentTarget.value)}
|
||||
onChange={(event) => set(event.currentTarget.value)}
|
||||
className="h-8 rounded-md border border-input bg-transparent px-2 text-xs"
|
||||
>
|
||||
{/* Mobile is the smallest, so there is nothing below it to inherit from and the empty
|
||||
option means what it actually does there: none. */}
|
||||
<option value="">
|
||||
{key === 'base' ? 'None' : from === null ? 'Inherit (none)' : `Inherit (${from})`}
|
||||
</option>
|
||||
{/* Mobile is the smallest, so there is nothing below it to inherit from. */}
|
||||
<option value="">{key === 'base' ? 'None' : from === null ? 'Inherit (none)' : `Inherit (${from})`}</option>
|
||||
{steps.map((step) => (
|
||||
<option key={step} value={String(step)}>
|
||||
{step}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<span className="truncate text-[10px] text-muted-foreground">{hint}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user