# ViewOptions

> The "Display" popover beside a list: layout, grouping, ordering, density and the visible properties, each a field of one GET form, so the URL holds the view and a link shares it.

```ts
import { ViewOptions } from "@sdxc/ui/app";
```

Renders the trigger and its popover. Every field reads its value from `url`, falling back to
the field's default, and Apply submits them with every other parameter carried as hidden
fields, so the filters and tab the page shows survive a view change.

## Examples

```tsx
<ViewOptions
	id="monitors-view"
	url={request.url}
	layout={{ defaultValue: "table", options: [{ value: "table", label: "Table", icon: <TableIcon /> }, { value: "grid", label: "Grid", icon: <LayoutGridIcon /> }] }}
	density={{ defaultValue: "compact", options: [{ value: "compact", label: "Compact" }, { value: "comfortable", label: "Comfortable" }] }}
	setDefault={{ action: "/settings/views/monitors" }}
	labels={labels}
/>
```

## Props

| Prop | Type | Description |
| --- | --- | --- |
| `id` | `string` | Prefix for the popover and form ids; unique on the page. |
| `url?` | `URL \| string` | The page's current URL, where every applied value is read from. |
| `action?` | `string` | Where Apply submits. Defaults to the current path. |
| `layout?` | `Field` |  |
| `grouping?` | `Field` |  |
| `ordering?` | `Field` |  |
| `density?` | `Field` |  |
| `properties?` | `Properties` |  |
| `setDefault?` | `{ action: string }` | Where "Set as default" posts the fields; omitted hides the button. |
| `inline?` | `boolean` | Draws the form in place, without its own trigger and popover, for a menu that holds it among other view controls, such as a filter bar's `options`. |
| `labels` | `Labels` |  |

Also accepts everything in `Omit<TagProps<"div">, "children" | "id">`.

