All files / web/src/components/studio StudioColor.tsx

100% Statements 77/77
100% Branches 2/2
100% Functions 2/2
100% Lines 77/77

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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 781x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x  
'use client'
 
// StudioColor — a labelled colour well for the dark studio rails (Gitea #43).
// Same props as the toy debug panel's `DebugColor`, styled from theme.ts.
//
// Two changes from the borrowed control. The label goes ABOVE, so a column of
// colours lines up with the selects and sliders beside them instead of being the
// one control whose label is inline. And the swatch + hex live together inside a
// CONTROL-shaped well that is itself the click target (the whole thing is one
// <label>), because a 22 px square is a small thing to ask someone to hit when
// the row it sits in is full-width anyway.
 
import { CONTROL, STUDIO } from './theme'
 
export interface StudioColorProps {
  label: string
  /** `#rrggbb` — a native color input accepts nothing else. */
  value: string
  onChange: (hex: string) => void
  dataElement?: string
  dataAction?: string
}
 
export function StudioColor({
  label,
  value,
  onChange,
  dataElement = 'debug-color',
  dataAction,
}: StudioColorProps) {
  return (
    <label
      data-component="studio-color"
      data-element={dataElement}
      style={{
        display: 'flex',
        flexDirection: 'column',
        gap: STUDIO.space.field,
        cursor: 'pointer',
      }}
    >
      <span style={STUDIO.type.label}>{label}</span>
      <span
        style={{
          ...CONTROL,
          // a 22 px swatch on CONTROL's own 8 px padding would make this the one
          // 40 px control in a column of 32 px ones; trim the block padding so
          // the well still lands on the control height rule 6 asks for
          padding: '5px 8px',
          display: 'flex',
          alignItems: 'center',
          gap: 8,
          width: '100%',
          boxSizing: 'border-box',
        }}
      >
        <input
          type="color"
          value={value}
          aria-label={label}
          data-action={dataAction}
          onChange={(e) => onChange(e.target.value)}
          style={{
            width: 22,
            height: 22,
            padding: 0,
            border: `1px solid ${STUDIO.color.buttonBorder}`,
            borderRadius: STUDIO.radius.swatch,
            background: 'none',
            cursor: 'pointer',
          }}
        />
        <span style={STUDIO.type.value}>{value}</span>
      </span>
    </label>
  )
}