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
| Name | Description | Property | Type | Default | Allowed values |
|---|---|---|---|---|---|
clearable | Allows None in the editor. An empty value shows a slashed swatch and emits the same input/change events with an empty string. | clearable | boolean | false | — |
disabled | Prevents opening and editing. | disabled | boolean | false | — |
label | Accessible name for the swatch button and editor. | label | string | Choose colour | — |
name | The form field name. Leave empty to omit the colour from form submission. A form reset restores value. | name | string | | — |
round | Makes the square swatch circular. | round | boolean | false | — |
size | Shared control height, matching Input and Button of the same size. | size | keyword | md | sm, md, lg |
value | An 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. | value | string | #000000 | — |
Framework props
| Name | Type | Default | Allowed values |
|---|---|---|---|
clearable | boolean | false | — |
disabled | boolean | false | — |
label | string | Choose colour | — |
name | string | | — |
round | boolean | false | — |
size | "sm" | "md" | "lg" | md | sm, md, lg |
value | string | #000000 | — |
Events
| Name | Detail | Description |
|---|---|---|
change | object
| Emitted when a toggleable control changes checked state. |
input | object
| 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
| Token | Fallback |
|---|---|
--ui-accent-solid | — |
--ui-border-strong | — |
--ui-border-width | — |
--ui-control-border | var(--ui-border-strong) |
--ui-control-inset | — |
--ui-control-inset-block-lg | var(--ui-space-3) |
--ui-control-inset-block-md | var(--ui-space-2) |
--ui-control-inset-block-sm | var(--ui-space-1) |
--ui-control-size-lg | — |
--ui-control-size-md | — |
--ui-control-size-sm | — |
--ui-control-surface | var(--ui-surface-elevated) |
--ui-field-radius | var(--ui-radius-md) |
--ui-focus-ring | var(--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-press | var(--ui-motion-fast) |
--ui-press-scale | 0.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 | — |