Skip to content

Themed controls

j3w1 edited this page Sep 9, 2026 · 1 revision

Themed controls and native form behavior

Version 1.1.0 renders single/multiple choices and date/time editors with j3w1 surfaces, rose text and red interaction states. The portal and Vue demo use the same supported runtime that consumers receive.

Choose the right component

Interaction Start with
Choose one fixed option, or a native multiple choice select and its declared variants
Type to filter suggestions combobox
A dedicated multiple-selection widget multiselect
Date entry and calendar date-picker
Time entry and stepping time-picker
Number entry with explicit step buttons number-field

Read each component page for its specific contract. The similarly named controls have distinct APIs and behavior; do not treat their names as interchangeable.

Enhance an existing application's controls

import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/controls.css';
import { enhanceControls } from '@j3w1/ui/enhance/choice';

const root = document.querySelector('#settings-form');
const controls = enhanceControls(root);
// When the owning application view is removed:
// controls.destroy();

Call it with a real mounted element. It observes inserted and removed controls within that explicit root. The root stylesheet also themes ordinary buttons, inputs, checkboxes, radios, range controls and file-button chrome; it removes native number spinners. Use the Number field's explicit step controls when stepping is needed.

In Vue, call after mount and destroy in onBeforeUnmount; see the complete Vue example. Official component instances manage their own enhancement. Do not duplicate dropdown implementations in each app or manually manipulate the generated proxy markup.

Why there is still a native input underneath

The original control keeps its name, value, defaults, form relationship, disabled state and validation. The visible themed control is its presentation. FormData should receive one successful value, not an extra hidden duplicate added by the application.

Keep framework bindings on native controls when the framework owns state. Use the documented API for component-owned behavior. Property assignment changes state; do not assume it fabricates a user input event. Cleanup restores the native fallback.

No-JavaScript fallbacks and explicit static reference specimens retain native controls. Browser-owned file/system dialogs remain host UI. The file input selects files; it does not upload them.

Keyboard reference

Control Keys
Single choice Enter/Space or arrows open; arrows and Home/End move; typing finds an option; Enter/Space commits; Escape/Tab closes
Multiple choices Arrows move; Space or click toggles; Shift with arrows selects a range; Ctrl/Command+A selects or clears enabled choices
Date calendar Arrows move; Home/End within a week; PageUp/Down changes month; Enter/Space chooses; Escape closes
Time Explicit text entry and step buttons; step="any" disables stepping

Dates use YYYY-MM-DD; time entry uses HH:MM or HH:MM:SS. Min/max/step and read-only/disabled behavior remain connected to the original input. Engines exposing date/time as text receive explicit parsing and constraint support from the enhancement.

Test the visible behavior

After enhancement, use the visible combobox/listbox and options in browser tests. Calling Playwright selectOption() on a hidden native select does not exercise the themed popup. Verify label propagation, focus, real keyboard selection, disabled options, validation, reset and form ownership.

Sources: D-025, enhancement API, consumption guide.

Clone this wiki locally