> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cskn.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# System pickers and accent

> Open the OS date picker and dropdown menu, and follow the system accent color.

Some controls feel native only when the OS draws them. These calls ask the shell for the system's own date picker and dropdown menu, and tell you the accent color the user picked in their system settings. Each one tells you when there is nothing to show, so you can fall back to your own UI.

## Date picker

```tsx theme={null}
import { openDatePicker } from '@cskn/sdk';

async function pickDueDate() {
  const value = await openDatePicker({ mode: 'date', value: dueDate, title: 'Due date' });
  if (value === undefined) return openOwnPicker(); // no system picker here
  if (value === null) return;                      // the user cancelled
  setDueDate(value);                               // '2026-10-17'
}
```

On iOS the system calendar (or time wheels) opens in a sheet; on Android, Material 3's date and time dialogs.

**mode** `'date' | 'time' | 'datetime'` (default: 'date')

What to pick.

**value** `string`

The starting value, in the format an `<input>` uses: `2026-10-17`, `14:30` or `2026-10-17T14:30`.

**min** `string`

Earliest value, same format.

**max** `string`

Latest value, same format.

**title** `string`

Picker title.

**doneLabel** `string`

Text of the confirm button.

**cancelLabel** `string`

Text of the cancel button.

**result** `string | null | undefined`

The chosen value in the same format as `value`; `null` if the user cancelled; `undefined` where there is no system picker.

`isDatePickerAvailable()` resolves `true` when `openDatePicker` will show the OS picker.

> [!TIP]
>
> @cskn/ui's [`GroupedDateInput`](https://docs.cskn.dev/ui/stack/grouped-forms#groupeddateinput) uses the system picker when there is one and its own picker everywhere else.

## Dropdown menu

```tsx theme={null}
import { showNativeMenu } from '@cskn/sdk';

async function openMoreMenu(button: HTMLElement) {
  const r = button.getBoundingClientRect();
  const index = await showNativeMenu({
    rect: { x: r.x, y: r.y, width: r.width, height: r.height },
    items: [{ label: 'Rename' }, { label: 'Delete', destructive: true }],
  });
  if (index === null) return openOwnMenu(button); // no system menu here
  if (index === 0) rename();
  if (index === 1) remove();
  // -1: dismissed
}
```

**rect** `\{ x, y, width, height \}` *required*

The element the menu belongs to, in viewport CSS pixels, as `getBoundingClientRect()` returns it.

**items** `\{ label, destructive?, disabled? \}[]` *required*

Menu entries, in order.

**result** `number | null`

The index of the chosen item; `-1` if the menu was dismissed; `null` where there is no system menu.

Only the Android shell has one. iOS can't open its menus from code, so it resolves `null` there. `isNativeMenuAvailable()` tells you ahead of time. @cskn/ui's [`ContextMenu`](https://docs.cskn.dev/ui/components/overlays#contextmenu) uses this for you.

## Accent color

On macOS and Windows, the user picks an accent color in their system settings. `useSystemAccent()` returns it as `#rrggbb`, and updates live when the user changes it.

```tsx theme={null}
import { useSystemAccent } from '@cskn/sdk';

const accent = useSystemAccent(); // '#0a84ff', or null
```

It is `null` where there is no accent to follow (phones, TV, Linux, a browser) and until the shell answers. Pass `false` to stop asking and listening, for example when the user has picked their own color: `useSystemAccent(enabled)`.

Without React, `getSystemAccent()` returns the current value and `onSystemAccentChange(cb)` listens for changes; it returns an unsubscribe.

## Outside a shell

| Call | Off-shell result |
| - | - |
| `openDatePicker` | `undefined` |
| `showNativeMenu` | `null` |
| `isDatePickerAvailable`, `isNativeMenuAvailable` | `false` |
| `useSystemAccent`, `getSystemAccent` | `null` |

A shell that predates these calls doesn't answer the first availability check. After a 1.5 second wait the SDK treats them as unavailable, and every later call falls back immediately.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.