Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4718466
docs: updated documentation of reactive-controllers
Oct 13, 2025
d703c09
Merge branch 'main' into rajdeep/swc-429
Rajdeepc Oct 15, 2025
fb835a8
docs: updated main readme to align with doc standard
Oct 16, 2025
442dfd6
Merge branch 'rajdeep/swc-429' of https://github.com/adobe/spectrum-w…
Oct 16, 2025
fdc8571
docs: updated color controller readme to align with doc standard
Oct 16, 2025
60df8b0
docs: updated dependency controller readme to align with doc standard
Oct 16, 2025
aa88fc4
docs: updated element resolution controller readme to align with doc …
Oct 16, 2025
cc621ec
docs: updated match media controller readme to align with doc standard
Oct 16, 2025
2584cab
docs: updated pending state controller readme to align with doc standard
Oct 16, 2025
a0eb897
docs: updated pending roving tab index controller readme to align wit…
Oct 17, 2025
3dc61ac
Merge branch 'main' into rajdeep/swc-429
Rajdeepc Oct 17, 2025
5ff113f
Merge branch 'main' of https://github.com/adobe/spectrum-web-componen…
Oct 20, 2025
b1e1e41
docs: updated the element resolution example with form field logic
Oct 20, 2025
f31137d
docs: updated element resolution modal overlay example to show the us…
Oct 20, 2025
63ab40f
docs: added new language resolution controller readme
Oct 20, 2025
b3b3459
docs: removed commented code in main readme
Oct 20, 2025
22a5a1c
docs: update docs for the disabled items in robing tab index controller
Oct 20, 2025
7a6c840
docs: removed screen reader section in roving tab index
Oct 20, 2025
38c4ad4
Merge branch 'rajdeep/swc-429' of https://github.com/adobe/spectrum-w…
Oct 20, 2025
746a320
chore: fix up review comments on verbs and script tags
Oct 24, 2025
5bd78cb
chore: added system context controller readme
Oct 24, 2025
6b98e9e
chore: main readme formatting fix
Oct 24, 2025
1811ade
Merge branch 'main' into rajdeep/swc-429
Rajdeepc Oct 26, 2025
9e6283a
Merge branch 'main' into rajdeep/swc-429
Rajdeepc Oct 27, 2025
126a961
chore: resolved merge conflicts from barebones
Nov 6, 2025
92a9241
Merge branch 'main' into rajdeep/swc-429
Rajdeepc Nov 6, 2025
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
18 changes: 11 additions & 7 deletions tools/reactive-controllers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,20 +247,24 @@ Implements the W3C ARIA roving tabindex pattern for keyboard navigation in compo

---

#### SystemContextResolutionController
### [SystemContextResolutionController](./system-context-resolution.md)

Resolves and tracks system-level context like color scheme and scale preferences from Spectrum theme providers.

**Use cases:**

- Theme integration
- Scale-aware components
- System preference detection
- Spectrum theme consumption
- Design system variant detection (Spectrum Classic, Express, Spectrum 2)
- System-specific asset loading
- Adaptive UI rendering

**Key features:**

- Automatic theme context resolution
- Color scheme tracking
- Scale preference tracking
- Works with Spectrum theme providers
- Reactive system variant updates
- Event-based communication with `<sp-theme>`
- Automatic cleanup on disconnect

**Note:** Private Beta API - subject to changes.

[Learn more →](../system-context-resolution)
8 changes: 4 additions & 4 deletions tools/reactive-controllers/color-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The `ColorController` is a comprehensive [reactive controller](https://lit.dev/d
- **Validation**: Validate color strings and ensure they conform to expected formats
- **Conversion**: Convert colors between different color spaces for versatile applications
- **State management**: Maintain current color state and save/restore previous color values
- **Format preservation**: Automatically preserves the format of the original color input when returning values
- **Format preservation**: Automatically preserve the format of the original color input when returning values

### Properties

Expand Down Expand Up @@ -48,14 +48,14 @@ The `ColorController` is a comprehensive [reactive controller](https://lit.dev/d
[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/reactive-controllers?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/reactive-controllers)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/reactive-controllers?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/reactive-controllers)

```
```bash
yarn add @spectrum-web-components/reactive-controllers
```

Import the `ColorController` via:

```
import {ColorController,} from '@spectrum-web-components/reactive-controllers/src/ColorController.js';
```typescript
import { ColorController } from '@spectrum-web-components/reactive-controllers/src/ColorController.js';
```

### Examples
Expand Down
69 changes: 4 additions & 65 deletions tools/reactive-controllers/dependency-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ The `DependencyManagerController` is a [reactive controller](https://lit.dev/doc

### Features

- **Lazy loading support**: Delay functionality until required custom elements are registered
- **Multiple dependency tracking**: Manage any number of custom element dependencies
- **Lazy loading support**: Delays functionality until required custom elements are registered
- **Multiple dependency tracking**: Manages any number of custom element dependencies
- **Reactive loading state**: Automatically updates the host when all dependencies are loaded
- **Async registration handling**: Works seamlessly with dynamic imports and lazy loading

Expand All @@ -14,13 +14,13 @@ The `DependencyManagerController` is a [reactive controller](https://lit.dev/doc
[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/reactive-controllers?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/reactive-controllers)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/reactive-controllers?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/reactive-controllers)

```
```bash
yarn add @spectrum-web-components/reactive-controllers
```

Import the `DependencyManagerController` via:

```
```typescript
import { DependencyManagerController } from '@spectrum-web-components/reactive-controllers/src/DependencyManger.js';
```

Expand Down Expand Up @@ -219,67 +219,6 @@ class FeatureLoader extends LitElement {
customElements.define('feature-loader', FeatureLoader);
```

Load components based on routing:

```typescript
import { html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { DependencyManagerController } from '@spectrum-web-components/reactive-controllers/src/DependencyManger.js';

class AppRouter extends LitElement {
dependencyManager = new DependencyManagerController(this);

@property({ type: String })
currentRoute = 'home';

private routeComponents = new Map([
['home', 'home-page'],
['dashboard', 'dashboard-page'],
['settings', 'settings-page'],
]);

updated(changedProperties: Map<string, any>) {
if (changedProperties.has('currentRoute')) {
const component = this.routeComponents.get(this.currentRoute);

if (component) {
this.dependencyManager.add(component);
import(`./pages/${component}.js`).catch((error) => {
console.error(`Failed to load ${component}:`, error);
});
}
}
}

renderRoute() {
if (!this.dependencyManager.loaded) {
return html`
<div
role="progressbar"
aria-label="Loading page"
aria-busy="true"
>
Loading page...
</div>
`;
}

const component = this.routeComponents.get(this.currentRoute);
return html`
${component ? html`<${component}></${component}>` : html``}
`;
}

render() {
return html`
<main role="main">${this.renderRoute()}</main>
`;
}
}

customElements.define('app-router', AppRouter);
```

#### Tracking load state changes

Use the `dependencyManagerLoadedSymbol` to react to loading state changes:
Expand Down
89 changes: 12 additions & 77 deletions tools/reactive-controllers/element-resolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,22 @@ The `ElementResolutionController` is a [reactive controller](https://lit.dev/doc
- **Reactive updates**: Automatically triggers host updates when the resolved element changes
- **Scope awareness**: Works within Shadow DOM and regular DOM contexts

<!-- ### Usage

```typescript
import { elementResolverUpdatedSymbol } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';

protected override willUpdate(changes: PropertyValues): void {
if (changes.has(elementResolverUpdatedSymbol)) {
// React to element resolution changes
}
}
``` -->

### Usage

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

```
```bash
yarn add @spectrum-web-components/reactive-controllers
```

Import the `ElementResolutionController` and/or `elementResolverUpdatedSymbol` via:

```
import { ElementResolutionController, elementResolverUpdatedSymbol } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';
```typescript
import {
ElementResolutionController,
elementResolverUpdatedSymbol,
} from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';
```

### Examples
Expand Down Expand Up @@ -70,14 +61,14 @@ customElements.define('root-el', RootEl);

In this example, the selector `'.other-element'` is supplied to the resolver, which means in the following example, `this.resolvedElement.element` will maintain a reference to the sibling `<div>` element:

```html
```html-no-demo
<root-el></root-el>
<div class="other-element"></div>
```

The resolved reference will always be the first element matching the selector applied, so in the following example the element with content "First!" will be the reference:

```html
```html-no-demo
<root-el></root-el>
<div class="other-element">First!</div>
<div class="other-element">Last.</div>
Expand Down Expand Up @@ -201,9 +192,9 @@ class CustomInput extends LitElement {
customElements.define('custom-input', CustomInput);
```

**Usage:**
Usage:

```html
```html-no-demo
<span class="input-label" id="name-label">Enter your name</span>
<custom-input></custom-input>
```
Expand Down Expand Up @@ -307,9 +298,9 @@ class ModalManager extends LitElement {
customElements.define('modal-manager', ModalManager);
```

**Usage:**
Usage:

```html
```html-no-demo
<!-- Elements with data-first-focus/data-last-focus can be inside shadow root -->
<modal-manager></modal-manager>

Expand All @@ -321,61 +312,6 @@ customElements.define('modal-manager', ModalManager);
</modal-manager>
```

The `ElementResolutionController` automatically finds the marked elements whether they're in the shadow DOM or slotted from the light DOM, which is essential for managing focus traps in reusable overlay components.

#### Form validation integration

Resolve and connect to error message elements:

```typescript
import { html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { ElementResolutionController } from '@spectrum-web-components/reactive-controllers/src/ElementResolution.js';

class ValidatedInput extends LitElement {
errorElement = new ElementResolutionController(this, {
selector: '.error-message',
});

@property({ type: Boolean })
invalid = false;

updated() {
const input = this.shadowRoot?.querySelector('input');

if (input && this.errorElement.element) {
input.setAttribute('aria-invalid', String(this.invalid));

if (this.invalid) {
input.setAttribute(
'aria-describedby',
this.errorElement.element.id
);
} else {
input.removeAttribute('aria-describedby');
}
}
}

render() {
return html`
<input type="text" aria-label="Validated input" />
`;
}
}

customElements.define('validated-input', ValidatedInput);
```

**Usage:**

```html
<validated-input invalid></validated-input>
<span class="error-message" id="error-1" role="alert">
This field is required
</span>
```

### Accessibility

When using `ElementResolutionController` for accessibility-related functionality, consider these best practices:
Expand Down Expand Up @@ -421,4 +357,3 @@ When using `ElementResolutionController` for accessibility-related functionality
- [WCAG 2.1 - Name, Role, Value](https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html)
- [ARIA: aria-labelledby attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-labelledby)
- [ARIA: aria-describedby attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby)
- [Adobe Accessibility Guidelines](https://www.adobe.com/accessibility/products/spectrum.html)
16 changes: 13 additions & 3 deletions tools/reactive-controllers/language-resolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ The `LanguageResolutionController` is a Lit reactive controller that automatical
[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/reactive-controllers?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/reactive-controllers)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/reactive-controllers?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/reactive-controllers)

```
```bash
yarn add @spectrum-web-components/reactive-controllers
```

Import the `LanguageResolutionController` via:

```
```typescript
import { LanguageResolutionController } from '@spectrum-web-components/reactive-controllers/src/LanguageResolution.js';
```

Expand Down Expand Up @@ -73,6 +73,16 @@ class LocalizedGreeting extends LitElement {
customElements.define('localized-greeting', LocalizedGreeting);
```

Usage:

```html-no-demo
<!-- Spanish context -->
<div lang="es-ES">
<localized-greeting></localized-greeting>
<!-- Renders: Hola, World! (es-ES) -->
</div>
```

#### Locale change tracking

The controller automatically re-renders components when the language context changes:
Expand Down Expand Up @@ -145,7 +155,7 @@ customElements.define('localized-card', LocalizedCard);

The controller searches up through parent elements to find language context:

```html
```html-no-demo
<!-- Finds lang attribute several levels up -->
<article lang="ja-JP">
<section>
Expand Down
Loading