Color Picker

Square or circular swatch button with shared control sizing and a dismissible RGB/hex colour editor.

Accent color

One editable color with its accessible label.

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-color-picker/ui-color-picker.html"
>

<ui-color-picker
  value="#7658d6"
  label="Accent color"
></ui-color-picker>
<script setup>
  import { UiColorPicker } from "@threadlabs/looma";
</script>

<template>
  <UiColorPicker
    value="#7658d6"
    label="Accent color"
  />
</template>
import { UiColorPicker } from "@threadlabs/looma";

export default function Example() {
  return <UiColorPicker
    value="#7658d6"
    label="Accent color"
  />;
}
/** @jsxImportSource preact */
import { UiColorPicker } from "@threadlabs/looma";

export default function Example() {
  return <UiColorPicker
    value="#7658d6"
    label="Accent color"
  />;
}
<script>
  import { UiColorPicker } from "@threadlabs/looma";
</script>

<UiColorPicker
  value="#7658d6"
  label="Accent color"
/>
import { Component } from "@angular/core";
import { UiColorPicker } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiColorPicker],
  template: `
    <span
      ui-color-picker
      [value]="'#7658d6'"
      [label]="'Accent color'"
    ></span>
  `,
})
export default class Example {}

Shapes and shared sizes

Square by default, circular with round. Each swatch matches the adjacent field. Click again or press Escape to close.

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-stack/ui-stack.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-color-picker/ui-color-picker.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-input/ui-input.html"
>

<ui-stack>
  <ui-cluster
    wrap="nowrap"
  >
    <ui-color-picker
      size="sm"
      value="#7c3aed"
      label="Frodo’s calendar colour"
    ></ui-color-picker>
    <ui-input
      size="sm"
      value="#7c3aed"
      aria-label="Frodo’s calendar hex"
    ></ui-input>
  </ui-cluster>
  <ui-cluster
    wrap="nowrap"
  >
    <ui-color-picker
      value="#16a34a"
      label="Sam’s desk colour"
    ></ui-color-picker>
    <ui-input
      value="#16a34a"
      aria-label="Sam’s desk hex"
    ></ui-input>
  </ui-cluster>
  <ui-cluster
    wrap="nowrap"
  >
    <ui-color-picker
      size="lg"
      round
      value="#2563eb"
      label="Sméagol’s badge colour"
    ></ui-color-picker>
    <ui-input
      size="lg"
      value="#2563eb"
      aria-label="Sméagol’s badge hex"
    ></ui-input>
  </ui-cluster>
</ui-stack>
<script setup>
  import { UiCluster, UiColorPicker, UiInput, UiStack } from "@threadlabs/looma";
</script>

<template>
  <UiStack>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        size="sm"
        value="#7c3aed"
        label="Frodo’s calendar colour"
      />
      <UiInput
        size="sm"
        value="#7c3aed"
        aria-label="Frodo’s calendar hex"
      />
    </UiCluster>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        value="#16a34a"
        label="Sam’s desk colour"
      />
      <UiInput
        value="#16a34a"
        aria-label="Sam’s desk hex"
      />
    </UiCluster>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        size="lg"
        :round="true"
        value="#2563eb"
        label="Sméagol’s badge colour"
      />
      <UiInput
        size="lg"
        value="#2563eb"
        aria-label="Sméagol’s badge hex"
      />
    </UiCluster>
  </UiStack>
</template>
import { UiCluster, UiColorPicker, UiInput, UiStack } from "@threadlabs/looma";

export default function Example() {
  return <UiStack>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        size="sm"
        value="#7c3aed"
        label="Frodo’s calendar colour"
      />
      <UiInput
        size="sm"
        value="#7c3aed"
        aria-label="Frodo’s calendar hex"
      />
    </UiCluster>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        value="#16a34a"
        label="Sam’s desk colour"
      />
      <UiInput
        value="#16a34a"
        aria-label="Sam’s desk hex"
      />
    </UiCluster>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        size="lg"
        round
        value="#2563eb"
        label="Sméagol’s badge colour"
      />
      <UiInput
        size="lg"
        value="#2563eb"
        aria-label="Sméagol’s badge hex"
      />
    </UiCluster>
  </UiStack>;
}
/** @jsxImportSource preact */
import { UiCluster, UiColorPicker, UiInput, UiStack } from "@threadlabs/looma";

export default function Example() {
  return <UiStack>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        size="sm"
        value="#7c3aed"
        label="Frodo’s calendar colour"
      />
      <UiInput
        size="sm"
        value="#7c3aed"
        aria-label="Frodo’s calendar hex"
      />
    </UiCluster>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        value="#16a34a"
        label="Sam’s desk colour"
      />
      <UiInput
        value="#16a34a"
        aria-label="Sam’s desk hex"
      />
    </UiCluster>
    <UiCluster
      wrap="nowrap"
    >
      <UiColorPicker
        size="lg"
        round
        value="#2563eb"
        label="Sméagol’s badge colour"
      />
      <UiInput
        size="lg"
        value="#2563eb"
        aria-label="Sméagol’s badge hex"
      />
    </UiCluster>
  </UiStack>;
}
<script>
  import { UiCluster, UiColorPicker, UiInput, UiStack } from "@threadlabs/looma";
</script>

<UiStack>
  <UiCluster
    wrap="nowrap"
  >
    <UiColorPicker
      size="sm"
      value="#7c3aed"
      label="Frodo’s calendar colour"
    />
    <UiInput
      size="sm"
      value="#7c3aed"
      aria-label="Frodo’s calendar hex"
    />
  </UiCluster>
  <UiCluster
    wrap="nowrap"
  >
    <UiColorPicker
      value="#16a34a"
      label="Sam’s desk colour"
    />
    <UiInput
      value="#16a34a"
      aria-label="Sam’s desk hex"
    />
  </UiCluster>
  <UiCluster
    wrap="nowrap"
  >
    <UiColorPicker
      size="lg"
      round
      value="#2563eb"
      label="Sméagol’s badge colour"
    />
    <UiInput
      size="lg"
      value="#2563eb"
      aria-label="Sméagol’s badge hex"
    />
  </UiCluster>
</UiStack>
import { Component } from "@angular/core";
import { UiCluster, UiColorPicker, UiInput, UiStack } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiStack, UiCluster, UiColorPicker, UiInput],
  template: `
    <div
      ui-stack
    >
      <div
        ui-cluster
        [wrap]="'nowrap'"
      >
        <span
          ui-color-picker
          [size]="'sm'"
          [value]="'#7c3aed'"
          [label]="'Frodo’s calendar colour'"
        ></span>
        <input
          ui-input
          [size]="'sm'"
          [value]="'#7c3aed'"
          aria-label="Frodo’s calendar hex"
        >
      </div>
      <div
        ui-cluster
        [wrap]="'nowrap'"
      >
        <span
          ui-color-picker
          [value]="'#16a34a'"
          [label]="'Sam’s desk colour'"
        ></span>
        <input
          ui-input
          [value]="'#16a34a'"
          aria-label="Sam’s desk hex"
        >
      </div>
      <div
        ui-cluster
        [wrap]="'nowrap'"
      >
        <span
          ui-color-picker
          [size]="'lg'"
          [round]="true"
          [value]="'#2563eb'"
          [label]="'Sméagol’s badge colour'"
        ></span>
        <input
          ui-input
          [size]="'lg'"
          [value]="'#2563eb'"
          aria-label="Sméagol’s badge hex"
        >
      </div>
    </div>
  `,
})
export default class Example {}

Optional colors

Allow None inside each picker without a separate mode control. An empty value shows a slashed swatch.

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-cluster/ui-cluster.html"
>
<link
  rel="component"
  href="@threadlabs/looma/components/ui-color-picker/ui-color-picker.html"
>

<ui-cluster>
  <ui-color-picker
    clearable
    value
    label="Optional secondary accent"
  ></ui-color-picker>
  <ui-color-picker
    clearable
    value="#fc5b69"
    label="Optional supporting accent"
  ></ui-color-picker>
</ui-cluster>
<script setup>
  import { UiCluster, UiColorPicker } from "@threadlabs/looma";
</script>

<template>
  <UiCluster>
    <UiColorPicker
      :clearable="true"
      value=""
      label="Optional secondary accent"
    />
    <UiColorPicker
      :clearable="true"
      value="#fc5b69"
      label="Optional supporting accent"
    />
  </UiCluster>
</template>
import { UiCluster, UiColorPicker } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster>
    <UiColorPicker
      clearable
      value=""
      label="Optional secondary accent"
    />
    <UiColorPicker
      clearable
      value="#fc5b69"
      label="Optional supporting accent"
    />
  </UiCluster>;
}
/** @jsxImportSource preact */
import { UiCluster, UiColorPicker } from "@threadlabs/looma";

export default function Example() {
  return <UiCluster>
    <UiColorPicker
      clearable
      value=""
      label="Optional secondary accent"
    />
    <UiColorPicker
      clearable
      value="#fc5b69"
      label="Optional supporting accent"
    />
  </UiCluster>;
}
<script>
  import { UiCluster, UiColorPicker } from "@threadlabs/looma";
</script>

<UiCluster>
  <UiColorPicker
    clearable
    value=""
    label="Optional secondary accent"
  />
  <UiColorPicker
    clearable
    value="#fc5b69"
    label="Optional supporting accent"
  />
</UiCluster>
import { Component } from "@angular/core";
import { UiCluster, UiColorPicker } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiCluster, UiColorPicker],
  template: `
    <div
      ui-cluster
    >
      <span
        ui-color-picker
        [clearable]="true"
        [value]="''"
        [label]="'Optional secondary accent'"
      ></span>
      <span
        ui-color-picker
        [clearable]="true"
        [value]="'#fc5b69'"
        [label]="'Optional supporting accent'"
      ></span>
    </div>
  `,
})
export default class Example {}

API

Package: @threadlabs/looma · Native root: span

Attributes

NameDescriptionPropertyTypeDefaultAllowed values
clearableAllows None in the editor. An empty value shows a slashed swatch and emits the same input/change events with an empty string.clearablebooleanfalse—
disabledPrevents opening and editing.disabledbooleanfalse—
labelAccessible name for the swatch button and editor.labelstringChoose colour—
nameThe form field name. Leave empty to omit the colour from form submission. A form reset restores value.namestring—
roundMakes the square swatch circular.roundbooleanfalse—
sizeShared control height, matching Input and Button of the same size.sizekeywordmdsm, md, lg
valueAn opaque sRGB colour as six hexadecimal digits prefixed with #, or an empty string for None when clearable. User edits emit input and change with detail.value. Invalid values are ignored. Set name to include the value in form submission.valuestring#000000—

Framework props

NameTypeDefaultAllowed values
clearablebooleanfalse—
disabledbooleanfalse—
labelstringChoose colour—
namestring—
roundbooleanfalse—
size"sm" | "md" | "lg"mdsm, md, lg
valuestring#000000—

Events

NameDetailDescription
changeobject
  • value: string (required)
Emitted when a toggleable control changes checked state.
inputobject
  • value: string (required)
Emitted with the declared detail payload.

Slots

No slots.

Design tokens

Set shared theme properties on a theme boundary. Component hooks apply only to their owning component.

Component tokens

No component tokens.

Shared tokens

TokenFallback
--ui-accent-solid—
--ui-border-strong—
--ui-border-width—
--ui-control-bordervar(--ui-border-strong)
--ui-control-inset—
--ui-control-inset-block-lgvar(--ui-space-3)
--ui-control-inset-block-mdvar(--ui-space-2)
--ui-control-inset-block-smvar(--ui-space-1)
--ui-control-size-lg—
--ui-control-size-md—
--ui-control-size-sm—
--ui-control-surfacevar(--ui-surface-elevated)
--ui-field-radiusvar(--ui-radius-md)
--ui-focus-ringvar(--ui-accent-solid)
--ui-focus-width—
--ui-font-size-md—
--ui-font-size-sm—
--ui-line-height-tight—
--ui-motion-ease—
--ui-motion-fast—
--ui-motion-pressvar(--ui-motion-fast)
--ui-press-scale0.96
--ui-radius-md—
--ui-shadow-lg—
--ui-space-1—
--ui-space-2—
--ui-space-3—
--ui-space-4—
--ui-surface-elevated—
--ui-surface-subtle—
--ui-text-primary—
--ui-text-secondary—