All files / views/ui toggle.ts

100% Statements 5/5
100% Branches 0/0
100% Functions 3/3
100% Lines 5/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60                          3x                           3x       1408x       2816x     1408x                                          
import type { Html, HtmlBuilder } from 'foldkit/html'
 
import { Switch } from '@foldkit/ui'
 
export type Config<Message> = Readonly<{
  id: string
  label: string
  description: string
  isOn: boolean
  onToggle: Message
  swatch: Html
}>
 
const CHIP_CLASS = [
  'flex shrink-0 cursor-pointer select-none items-center gap-1.5 whitespace-nowrap rounded-md border px-2 py-1 text-xs outline-hidden',
  'transition-colors duration-100 motion-reduce:transition-none',
  'border-transparent text-faint hover:border-line/40 hover:bg-ink/5 hover:text-ink',
  'data-[checked]:border-line data-[checked]:bg-ink/10 data-[checked]:text-ink data-[checked]:hover:bg-ink/20',
  'active:bg-ink/25 data-[checked]:active:bg-ink/25',
  'focus-visible:ring-2 focus-visible:ring-focus',
  '[@media(hover:none)]:py-1.5',
].join(' ')
 
/**
 * An on/off chip for the toolbar, built on Switch: screen readers announce "MGRS, switch, on".
 * The whole chip is the switch button, so the swatch, the label and the padding all toggle it.
 */
export const view = <Message>(
  { id, label, description, isOn, onToggle, swatch }: Config<Message>,
  h: HtmlBuilder<Message>,
): Html =>
  Switch.view(
    {
      id,
      isChecked: isOn,
      onToggle: () => onToggle,
      hasDescription: true,
      toView: attributes =>
        h.span(
          [h.Class('flex shrink-0')],
          [
            h.button(
              [...attributes.button, h.Title(description), h.Class(CHIP_CLASS)],
              [
                swatch,
                // NOTE: the label carries only Switch's id, not its click handler. Inside the
                // button, that handler would toggle a second time on each click.
                h.span([h.Id(Switch.labelId(id))], [label]),
              ],
            ),
            h.span(
              [...attributes.description, h.Class('sr-only')],
              [description],
            ),
          ],
        ),
    },
    h,
  )