Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 186 additions & 9 deletions packages/color-handle/README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,222 @@
## Description
## Overview

The `<sp-color-handle>` is used to select a colour on an `<sp-color-area>`, `<sp-color-slider>`, or `<sp-color-wheel>`. It functions similarly to the handle on an `<sp-slider>`.
The `<sp-color-handle>` is used to select a color on an `<sp-color-area>`, `<sp-color-slider>`, or `<sp-color-wheel>`. It functions similarly to the handle on an `<sp-slider>`, providing a draggable control point for precise color selection within color components.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we highlight the functional difference between the color-handle and the handle in sp-slider? If there is no difference, I would remove the reference to sp-slider, as that causes confusion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we highlight that this is an atomic level component or maybe discuss the language we would like to use for internal/dumb components?

cc @nikkimk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!
I added a note
**Note**: is a primitive component designed to be used within other color selection components. It's not typically used directly in applications, but rather as part of higher-level color components like, , or .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend revering to them my name and not stag unless you are referring to the code that creates them.

Suggested change
The `<sp-color-handle>` is used to select a color on an `<sp-color-area>`, `<sp-color-slider>`, or `<sp-color-wheel>`. It functions similarly to the handle on an `<sp-slider>`, providing a draggable control point for precise color selection within color components.
The color handle is used to select a color on a [color area](../color-area/), [color slider](../color-slider/), or [color wheel](../color-wheel/). It provides a draggable control point for precise color selection within color components.


### Usage

[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/color-handle?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/color-handle)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/color-handle?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/color-handle)

```
```bash
yarn add @spectrum-web-components/color-handle
```

Import the side effectful registration of `<sp-color-handle>` via:

```
```javascript
import '@spectrum-web-components/color-handle/sp-color-handle.js';
```

When looking to leverage the `ColorHandle` base class as a type and/or for extension purposes, do so via:

```
```javascript
import { ColorHandle } from '@spectrum-web-components/color-handle';
```

## Standard
### Anatomy

The color handle consists of several key parts:

- A visual handle element that indicates the current position
- An optional color loupe that appears above the handle when active
- Touch-responsive interaction areas
- Color display showing the current selected color
- Opacity checkerboard pattern for transparent colors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- A visual handle element that indicates the current position
- An optional color loupe that appears above the handle when active
- Touch-responsive interaction areas
- Color display showing the current selected color
- Opacity checkerboard pattern for transparent colors
A visual handle element that indicates the current position
- Touch-responsive interaction areas
- Color display showing the current selected color
- Opacity checkerboard pattern for transparent colors
- An optional color loupe that appears above the handle when active


```html
<sp-color-handle></sp-color-handle>
```

## Disabled
**Internal Structure**: The component renders an inner div with the background color and an `<sp-color-loupe>` element that appears when the `open` property is true and the component is not disabled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this call out can be removed with the suggestion above, just added these details to the bullet points

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


### Options

#### Color

The `color` property sets the visual color displayed within the handle. This accepts any valid CSS color format. The default color is `rgba(255, 0, 0, 0.5)` (semi-transparent red).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a table of the colors accepted OR we should add a line about how color uses the color-controller and link to the color-controller docs with the table

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


```html
<div style="display: flex; gap: 16px; align-items: center; margin: 16px 0;">
<!-- Hex color -->
<div style="position: relative; height: 20px; margin: 20px;">
<sp-color-handle color="#ff0000"></sp-color-handle>
</div>

<!-- RGB format -->
<div style="position: relative; height: 20px; margin: 20px;">
<sp-color-handle color="rgb(255, 0, 0)"></sp-color-handle>
</div>

<!-- RGBA format with transparency -->
<div style="position: relative; height: 20px; margin: 20px;">
<sp-color-handle color="rgba(255, 0, 0, 0.5)"></sp-color-handle>
</div>

<!-- HSL format -->
<div style="position: relative; height: 20px; margin: 20px;">
<sp-color-handle color="hsl(0, 100%, 50%)"></sp-color-handle>
</div>

<!-- Named colors -->
<div style="position: relative; height: 20px; margin: 20px;">
<sp-color-handle color="red"></sp-color-handle>
</div>
</div>
```

**Transparency Support**: When using transparent colors, the handle displays an opacity checkerboard pattern background to clearly show the transparency level.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this above the example


### States

#### Standard
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think this is necessary...? @nikkimk are we showing default states in all components?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I include the default if I used tabs for a visual comparison, and typically for variants more than states, but it's not necessarily a hill to die on for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding a default let the users compare what is the difference b/w default and other states


The default state of the color handle, ready for interaction:

```html
<sp-color-handle></sp-color-handle>
```

#### Disabled

A disabled color handle shows that the control exists but is not available for interaction. This maintains layout continuity and communicates that the handle may become available later:

```html
<sp-color-handle disabled></sp-color-handle>
```

## Open
#### Open

When the `<sp-color-handle>` uses the `open` property, the `<sp-color-loupe>` component can be used above the handle to show the selected color that would otherwise be covered by a mouse, stylus, or finger on the down/touch state. This can be customized to appear only on finger-input, or always appear regardless of input type.
When the `open` property is set, the `<sp-color-loupe>` component appears above the handle to show the selected color that would otherwise be covered by a mouse, stylus, or finger on the down/touch state. The loupe automatically appears for touch input (`pointerType === 'touch'`) and can be manually controlled for other input types.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should show an example of how to set up the other input types


```html
<div style="height: 72px"></div>
<sp-color-handle open></sp-color-handle>
```

**Automatic Behavior**: The loupe automatically opens when touched and closes when the touch interaction ends. For mouse and stylus input, the loupe remains hidden by default unless explicitly set to `open="true"`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldnt be needed, all details should be covered in the first paragraph, make updates there if you feel the wording needs updating

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually looking in to how this is implemented in other components, this is not automatically configured. we should make sure the examples and docs throughout accurately explain how to use this in a parent component.

color-area implementation of color-handle:
Screenshot 2025-08-05 at 2 00 48 PM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not exposing this to users The streamingListener for internal use only

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but isnt the streamingListener how a consumer using handle to make a new component would set it up for the event handlers? there is not functional code in handle that sets them up


#### Focused

The color handle can receive keyboard focus when used within interactive color components. The focused state is managed automatically by the parent component and is indicated visually:

```html
<sp-color-handle focused></sp-color-handle>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is handled in the parent, should this example show more of the implementation pattern versus the output in the DOM?

cc @nikkimk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good to include to show what focused state looks like and how it works within the component.

```

### Behaviors

#### Pointer Interactions

The color handle automatically manages pointer events to provide the optimal user experience:

- **Touch Input**: When touched (`pointerType === 'touch'`), the color loupe automatically appears to prevent the finger from obscuring the selected color
- **Mouse/Stylus Input**: The loupe remains hidden by default for precision pointing devices
- **Pointer Capture**: The handle captures pointer events during interaction to ensure smooth dragging even when the pointer moves outside the handle area
- **Event Handling**: The component listens for `pointerdown`, `pointerup`, and `pointercancel` events to manage the interaction lifecycle

#### Color Display

The handle displays the current color with proper support for transparency:

- Transparent colors are shown with an opacity checkerboard pattern background
- The color updates in real-time as the user interacts with the parent color component
- Supports all standard CSS color formats

</br>
<sp-table>
<sp-table-head>
<sp-table-head-cell>Format</sp-table-head-cell>
<sp-table-head-cell>Example Values</sp-table-head-cell>
<sp-table-head-cell>Description</sp-table-head-cell>
</sp-table-head>
<sp-table-body>
<sp-table-row>
<sp-table-cell>Hex3</sp-table-cell>
<sp-table-cell><code>#f00</code>, <code>#0a5</code></sp-table-cell>
<sp-table-cell>3-digit hexadecimal</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>Hex4</sp-table-cell>
<sp-table-cell><code>#f00f</code>, <code>#0a58</code></sp-table-cell>
<sp-table-cell>3-digit hexadecimal + alpha</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>Hex6</sp-table-cell>
<sp-table-cell><code>#ff0000</code>, <code>#00aa55</code></sp-table-cell>
<sp-table-cell>6-digit hexadecimal</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>Hex8</sp-table-cell>
<sp-table-cell><code>#ff0000ff</code>, <code>#00aa5580</code></sp-table-cell>
<sp-table-cell>6-digit hexadecimal + alpha</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>RGB</sp-table-cell>
<sp-table-cell><code>rgb(255, 0, 0)</code>, <code>rgb(0, 170, 85)</code></sp-table-cell>
<sp-table-cell>Red, Green, Blue values (0-255)</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>RGBA</sp-table-cell>
<sp-table-cell><code>rgba(255, 0, 0, 1)</code>, <code>rgba(0, 170, 85, 0.5)</code></sp-table-cell>
<sp-table-cell>RGB + Alpha channel (0-1)</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>HSL</sp-table-cell>
<sp-table-cell><code>hsl(0, 100%, 50%)</code>, <code>hsl(150, 100%, 33%)</code></sp-table-cell>
<sp-table-cell>Hue (0-360°), Saturation, Lightness</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>HSLA</sp-table-cell>
<sp-table-cell><code>hsla(0, 100%, 50%, 1)</code>, <code>hsla(150, 100%, 33%, 0.5)</code></sp-table-cell>
<sp-table-cell>HSL + Alpha channel (0-1)</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>HSV</sp-table-cell>
<sp-table-cell><code>hsv(0, 100%, 100%)</code>, <code>hsv(150, 100%, 67%)</code></sp-table-cell>
<sp-table-cell>Hue (0-360°), Saturation, Value</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>HSVA</sp-table-cell>
<sp-table-cell><code>hsva(0, 100%, 100%, 1)</code>, <code>hsva(150, 100%, 67%, 0.5)</code></sp-table-cell>
<sp-table-cell>HSV + Alpha channel (0-1)</sp-table-cell>
</sp-table-row>
<sp-table-row>
<sp-table-cell>Named Colors</sp-table-cell>
<sp-table-cell><code>red</code>, <code>rebeccapurple</code>, <code>darkseagreen</code></sp-table-cell>
<sp-table-cell>CSS color keywords (<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/named-color">full list</a>)</sp-table-cell>
</sp-table-row>
</sp-table-body>
</sp-table>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2025-08-04 at 11 41 13 AM

The UI is a bit off. Also can you add a note what this table is suggesting. Not sure we need 3 columns. But please cross check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

</br>

### Accessibility

The `<sp-color-handle>` is designed to work as part of accessible color selection components:

#### Keyboard Support

While the color handle itself is not directly keyboard accessible, it works in conjunction with its parent components (`<sp-color-area>`, `<sp-color-slider>`, `<sp-color-wheel>`) which provide comprehensive keyboard navigation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a small example to surface this usage to our customers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of an example here bringing in another component, I would like to suggest that we link to the other components docs to see it in use

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


#### Screen Reader Support

The color handle is rendered as a visual indicator and does not directly interface with screen readers. Accessibility is provided through the parent color component's ARIA implementation.

#### Touch Accessibility

- **Color Loupe**: Automatically appears for touch input to ensure the selected color remains visible
- **Large Touch Target**: The handle provides an appropriately sized touch target for mobile interaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the size of the touch target?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The size of sp-color-loupe

- **Pointer Capture**: Ensures reliable dragging behavior across different touch devices

#### Focus Management

Focus is managed by the parent color component, with the handle reflecting the focused state visually when its parent component has keyboard focus.
Loading