mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-26 02:06:49 +00:00
feat(settings): add comfortable/compact density toggle (#683)
Adds a per-device appearance preference that compresses row, cell, and tile padding across dashboard, settings, audit log, and every shared table without changing typography or layout structure. Density is stored in localStorage and applied to the document body as a class that swaps a set of CSS variables. Components opt in by consuming the tokens, so the global table primitive scales all seven consumers at once. A new Appearance section in the Identity group lets users pick between Comfortable and Compact via a Combobox, with a helper line that reflects the current choice.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Combobox } from '@/components/ui/combobox';
|
||||
import { useDensity } from '@/hooks/use-density';
|
||||
import type { Density } from '@/hooks/use-density';
|
||||
|
||||
const DENSITY_OPTIONS: { value: Density; label: string }[] = [
|
||||
{ value: 'comfortable', label: 'Comfortable' },
|
||||
{ value: 'compact', label: 'Compact' },
|
||||
];
|
||||
|
||||
const DENSITY_DESCRIPTIONS: Record<Density, string> = {
|
||||
comfortable: 'Default spacing. Roomy rows for review and orientation.',
|
||||
compact: 'Tighter rows and tiles. Fits more on screen for dense dashboards.',
|
||||
};
|
||||
|
||||
export function AppearanceSection() {
|
||||
const [density, setDensity] = useDensity();
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-4 bg-glass border border-glass-border p-4 rounded-lg">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="density-select">Density</Label>
|
||||
<Combobox
|
||||
options={DENSITY_OPTIONS}
|
||||
value={density}
|
||||
onValueChange={(v) => {
|
||||
if (v === 'comfortable' || v === 'compact') setDensity(v);
|
||||
}}
|
||||
placeholder="Select density"
|
||||
/>
|
||||
<p className="text-xs text-stat-subtitle">
|
||||
{DENSITY_DESCRIPTIONS[density]}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-xs text-stat-subtitle">
|
||||
Preference is saved to this browser only. Each device you use remembers its own choice.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
export { AccountSection } from './AccountSection';
|
||||
export { AppearanceSection } from './AppearanceSection';
|
||||
export { LicenseSection } from './LicenseSection';
|
||||
export { UsersSection } from './UsersSection';
|
||||
export { SystemSection } from './SystemSection';
|
||||
|
||||
@@ -42,6 +42,15 @@ export const SETTINGS_ITEMS: readonly SettingsItemMeta[] = [
|
||||
scope: 'global',
|
||||
hiddenOnRemote: true,
|
||||
},
|
||||
{
|
||||
id: 'appearance',
|
||||
group: 'identity',
|
||||
label: 'Appearance',
|
||||
description: 'Density and display preferences saved to this browser.',
|
||||
keywords: ['density', 'comfortable', 'compact', 'spacing', 'display', 'theme'],
|
||||
tier: null,
|
||||
scope: 'global',
|
||||
},
|
||||
{
|
||||
id: 'license',
|
||||
group: 'identity',
|
||||
|
||||
@@ -28,6 +28,7 @@ export const DEFAULT_SETTINGS: PatchableSettings = {
|
||||
|
||||
export type SectionId =
|
||||
| 'account'
|
||||
| 'appearance'
|
||||
| 'license'
|
||||
| 'users'
|
||||
| 'sso'
|
||||
|
||||
Reference in New Issue
Block a user