# SunSwitch

> A theme switch drawn as a pixel sun. Hover it for a lens on its true colours; click it and the new theme spreads from the sun in a dithered, grid-aligned wave.

- Package: `fancy-ui-vue` (Vue 3.5+ + Tailwind CSS v4)
- Category: Buttons
- Tags: switch, theme, dark mode, pixel, dither, view transition, canvas
- Types: `SunSwitchProps`, `SunPalette`, `PixelWaveOptions`, `PixelWaveMode`
- Docs: https://fancy-ui.rama.app/docs/components/sun-switch
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/vue/src/components/sun-switch

## Import

```vue
<script setup lang="ts">
import { SunSwitch } from 'fancy-ui-vue';
</script>
```

Setup (once per project): `npm install fancy-ui-vue`, then put these lines in your main CSS file (the stylesheet imports go right after `@import "tailwindcss";`):

```css
@import "tailwindcss";
@import "fancy-ui-vue/tailwind.css";
@import "fancy-ui-vue/styles.css";
```

Full guide: https://fancy-ui.rama.app/llms.txt

The names below are the ones to write in a Vue template; when one differs from the Svelte name, the Svelte name follows in parentheses. Snippets become named slots (`#default` is the default snippet), a prop the Vue port declares as a model is a `v-model:<name>` (except `ref`, exposed via `defineExpose({ ref })`: put a template ref on the component and read `.ref`) and callbacks are listeners (`onclick` is `@click`). Every component sets `inheritAttrs: false`: `class` is a declared prop, merged where the Svelte component applies it (not always the root element), and only when the props table below lists it; other attributes do not fall through unless the package README lists the component as forwarding native attributes. Divergences: https://github.com/RamaHerbin/fancy-ui/tree/main/vue#divergences-from-the-svelte-api

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `v-model:checked` (Svelte `checked`) | `boolean` | `true` | Day (true) or night (false). Bindable. |
| `@checked-change` (Svelte `onCheckedChange`) | `(checked: boolean) => void` | — | Called with the new value from inside the view transition's update callback. Flip your theme here; the component never changes classes on the document. Flip the theme synchronously: the new snapshot is taken as soon as it returns. |
| `radius` | `number` | `10` | Sun radius in cells. The canvas is 2 × radius + 1 cells square. |
| `cell` | `number` | `5` | Grid pitch in CSS pixels, shared by the sun, the wave front and its halo. |
| `dot` | `number` | `4` | Size of each square dot in CSS pixels (at most `cell`). |
| `palette` | `[string, string, string, string]` | `SUN_PALETTE` | Four colours from the top of the sun to the bottom. The halo reuses them: densest rim in the last colour, sparse fringe in the first. |
| `ink` | `string` | `"currentColor"` | Monochrome colour of the night sun and the horizon outside the lens. Resolved from the computed colour of the button, so it follows the theme. |
| `nightAlpha` | `number` | `0.42` | Opacity of the ink sun at night. |
| `horizon` | `boolean` | `true` | Draws a few sparse rows of dots under the sun for the lens to reveal. |
| `lens` | `boolean` | `true` | On hover, a soft circular lens follows the pointer and shows the true colours under it. |
| `lensRadius` | `number` | `7` | Lens radius in cells; about two thirds of the sun reads best. |
| `mode` | `"document" \| "contained"` | `"document"` | `document` runs the wave as a view transition over the whole page. `contained` paints it over `scope` only, with a sheet of the old colour that the wave cuts away. |
| `scope` | `HTMLElement \| null` | — | The element the wave covers in contained mode. It needs `position: relative` and `overflow: hidden`. |
| `fill` | `string` | — | Colour of the old-state sheet in contained mode and browsers without view transitions. Defaults to the first opaque background found from `scope` (or the body) upwards. |
| `duration` | `number` | `1300` | Duration of the wave in milliseconds (ease in-out cubic). |
| `haloCells` | `number` | `9` | Thickness of the dithered halo that leads the wave front, in cells. |
| `hdr` | `boolean` | `true` | On HDR displays with WebGPU, redraws the sun and the wave halo as hard squares brighter than SDR white. Elsewhere nothing is created. |
| `sound` | `boolean` | `false` | Plays the toggle cue (on for day, off for night) through the sound controller, once the user has enabled sound. |
| `label` | `string` | `"Day mode"` | Accessible name of the switch. Its checked state is announced as on or off. |
| `disabled` | `boolean` | `false` | Blocks interaction. |
| `class` | `string` | — | Additional CSS classes on the button. |

## Example

No Vue example is published for this component yet: start from the import above and the props table. The full examples are Svelte-only, on https://fancy-ui.rama.app/docs/components/sun-switch.md.
