shadcn.io is not affiliated with official shadcn/ui
Compact Dense Density Form Block for Vue
A new-task form with a density switch: Comfortable, Compact and Dense change the control height, the gaps and the type through CSS variables, with the numbers printed, and a phone keeps 40 pixel controls.
Installation
Overview
Let people choose how much form fits on the screen with this density form for Vue with Ark UI. A compact header holds a Toggle Group of Comfortable, Compact and Dense over a hairline frame with a plus mark on each corner. The form is a new task for a household to-do app: a name (Input), an assignee and a priority (Selects), a due date (Date Input), tags and a "Notify the assignee" Checkbox. The density sets three CSS variables on the panel, the control height (40, 32 or 28 px), the gap between fields and the type size, so one form is restyled without rebuilding it, and a line in the first band prints the numbers ("32 px controls, 16 px gaps"). Dense stays above the 24 px touch-target floor. On a phone the controls keep 40 px whatever is chosen and Dense is not offered. Add task checks the name, the assignee and the due date, names the first problem in the foot and focuses it. The Shine Button is the only colored control. It's built from Toggle Group, Input, Select, Date Input, Checkbox, Shine Button and Guides, with a CSS entrance only. For admin tools, data entry, internal apps and any form that people fill in all day.
FAQ
How does the density switch work?
lookOf returns one string of three variables for the chosen density: --ctl (control height), --gap (space between fields) and --fs (type size). The panel carries that string, and every control reads the variables (sm:h-(--ctl), sm:gap-(--gap)), so nothing is re-rendered with a different component. To add a density, add a branch to lookOf, its numbers to heightOf and gapOf, and an entry to DENSITIES.
Is Dense too small to use?
At 28 px it is above the 24 px minimum target size, and each control has space around it from the gap. It is meant for a pointer. Below the small breakpoint the height variable is ignored: every control is 40 px, the Dense choice is hidden and the line prints "40 px controls on a phone".
When are problems shown?
On Add task, for the name, the assignee and the due date at once. The first one is worded in the status line and its control is focused; the fields have no line of their own, so the form can stay as tight as the density asks. After that the status follows what is still wrong, and a field marked invalid gets the destructive border.
How does the density group work with a keyboard?
The three choices are one group that is named "Density", always with exactly one pressed; Tab enters it and the arrow keys move between them, and choosing one changes the form but never moves focus. The header and the first band do not move when the form tightens, only the panel below them.
What stays local, and how do I connect it for real?
Nothing is created: Add task says Added "Take out the recycling" in this demo. Nothing was sent. To make it real, post the draft from the submit handler, validate it again on the server and keep the person's chosen density in a setting of your own (a cookie or their profile), reading it into the initial state.