@vanilla-bean/components 1.0.2 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/Component/Component.js +5 -5
  2. package/Component/Component.scenarios.js +2 -2
  3. package/Component/Component.test.js +2 -2
  4. package/Component/observeElementConnection.js +1 -1
  5. package/README.md +1 -1
  6. package/components/BottomSheet/README.md +1 -1
  7. package/components/Button/Button.lld.md +1 -1
  8. package/components/Code/Code.lld.md +1 -1
  9. package/components/ColorPicker/ColorPicker.js +1 -1
  10. package/components/Dialog/Dialog.js +1 -1
  11. package/components/Dialog/Dialog.lld.md +1 -1
  12. package/components/Dialog/README.md +10 -10
  13. package/components/Form/Form.js +9 -9
  14. package/components/Form/Form.lld.md +2 -2
  15. package/components/Form/README.md +3 -3
  16. package/components/Input/README.md +7 -7
  17. package/components/Keyboard/Keyboard.lld.md +1 -1
  18. package/components/Menu/Menu.js +3 -3
  19. package/components/Notify/Notify.lld.md +2 -2
  20. package/components/Page/Page.lld.md +1 -1
  21. package/components/RadioButton/RadioButton.lld.md +1 -1
  22. package/components/Router/README.md +12 -12
  23. package/components/Select/README.md +5 -5
  24. package/components/Select/Select.js +1 -1
  25. package/components/Table/README.md +4 -4
  26. package/components/Table/Table.lld.md +1 -1
  27. package/components/TagList/TagList.lld.md +1 -1
  28. package/components/TooltipWrapper/TooltipWrapper.lld.md +2 -2
  29. package/components/Whiteboard/Whiteboard.lld.md +1 -1
  30. package/index.d.ts +4 -3
  31. package/package.json +1 -1
  32. package/theme/.test.js +20 -4
  33. package/theme/README.md +15 -8
  34. package/theme/button.js +1 -1
  35. package/theme/colors.js +9 -2
  36. package/theme/input.js +3 -3
  37. package/theme/page.js +6 -0
  38. package/theme/scrollbar.js +7 -3
  39. package/theme/table.js +2 -2
  40. package/utils/browser.js +1 -1
  41. package/Component/README.md +0 -455
  42. package/Elem/README.md +0 -373
  43. package/styled/README.md +0 -329
@@ -139,7 +139,7 @@ class Component extends Elem {
139
139
  if (this.constructor !== Component && this.constructor.prototype.hasOwnProperty('render')) {
140
140
  // eslint-disable-next-line no-console
141
141
  console.warn(
142
- `[Component] ${this.constructor.name} overrides render(). Structure belongs in build() — render() is the lifecycle orchestrator.`,
142
+ `[Component] ${this.constructor.name} overrides render(). Structure belongs in build() - render() is the lifecycle orchestrator.`,
143
143
  );
144
144
  }
145
145
  }
@@ -154,7 +154,7 @@ class Component extends Elem {
154
154
  }
155
155
 
156
156
  /**
157
- * Subclass structural hook — override to create child elements and component structure.
157
+ * Subclass structural hook - override to create child elements and component structure.
158
158
  * Called by render() before options are processed, so all structure exists
159
159
  * before _setOption receives values.
160
160
  */
@@ -204,7 +204,7 @@ class Component extends Elem {
204
204
  * Routes option changes through the static handlers chain, then standard routing.
205
205
  *
206
206
  * Walks the constructor chain collecting all handlers for the given key (deepest class
207
- * first), then executes them in order. Each handler receives `next(value?)` — call it
207
+ * first), then executes them in order. Each handler receives `next(value?)` - call it
208
208
  * to continue to the next handler in the chain, or to standard routing when the chain
209
209
  * is exhausted. Handlers that do not call `next` fully own the key.
210
210
  * @param {string} key - Option property name being changed
@@ -235,7 +235,7 @@ class Component extends Elem {
235
235
  }
236
236
 
237
237
  /**
238
- * Standard option routing pipeline — event handlers, special keys, attributes, methods, properties.
238
+ * Standard option routing pipeline - event handlers, special keys, attributes, methods, properties.
239
239
  * Called by _setOption when no handler claims the key, or when a handler calls next() past
240
240
  * the end of its chain.
241
241
  * @param {string} key - Option property name
@@ -260,7 +260,7 @@ class Component extends Elem {
260
260
  }
261
261
  return;
262
262
  }
263
- // method route — e.g. onPointerPress, onHover
263
+ // method route - e.g. onPointerPress, onHover
264
264
  }
265
265
 
266
266
  if (key === 'uniqueId') this.elem.id = typeof value === 'string' ? value : this.uniqueId;
@@ -1,7 +1,7 @@
1
1
  import Component from './Component.js';
2
2
 
3
3
  export const __lld_api = `
4
- destructiveRender() -> boolean | renders a component twice; returns true if child count matches (1) — second render cleared the first
4
+ destructiveRender() -> boolean | renders a component twice; returns true if child count matches (1) - second render cleared the first
5
5
  optionReactionFires() -> number | assigns to option after render; returns how many times _setOption was called (1 = reactive)
6
6
  buildBeforeOptions() -> boolean | verifies build() DOM structure exists when _setOption runs (true = ordering is correct)
7
7
  priorityRunsFirst() -> boolean | textContent (priority option) runs before style (non-priority); returns true if correct order
@@ -84,5 +84,5 @@ export const replaceCleanupRunsOnce = () => {
84
84
  }); // runs previous = 2, stores latest
85
85
  const countBeforeCleanup = count;
86
86
  comp.processCleanup(); // runs only the latest = 3
87
- return count - countBeforeCleanup; // 1 — only latest ran at cleanup time
87
+ return count - countBeforeCleanup; // 1 - only latest ran at cleanup time
88
88
  };
@@ -621,7 +621,7 @@ describe('Component', () => {
621
621
  });
622
622
 
623
623
  describe('cleanup system', () => {
624
- test('addCleanup chains — both functions run on processCleanup', () => {
624
+ test('addCleanup chains - both functions run on processCleanup', () => {
625
625
  const comp = new Component({ autoRender: false });
626
626
  const calls = [];
627
627
 
@@ -695,7 +695,7 @@ describe('Component', () => {
695
695
  expect(handler).toHaveBeenCalled();
696
696
  });
697
697
 
698
- test('on* method route — onPointerPress calls the component method', () => {
698
+ test('on* method route - onPointerPress calls the component method', () => {
699
699
  const handler = mock();
700
700
  component = new Component({ tag: 'button', onPointerPress: handler, appendTo: document.body });
701
701
 
@@ -33,7 +33,7 @@ function ensureObserver() {
33
33
  * @param {Node} config.target - Target element to watch for add/remove
34
34
  * @param {Function} config.onConnected - Called when target is added to the document
35
35
  * @param {Function} config.onDisconnected - Called when target is removed from the document
36
- * @returns {{ disconnect: Function }} Handle — call disconnect() to deregister
36
+ * @returns {{ disconnect: Function }} Handle - call disconnect() to deregister
37
37
  */
38
38
  export const observeElementConnection = ({ target, onConnected, onDisconnected }) => {
39
39
  ensureObserver();
package/README.md CHANGED
@@ -379,7 +379,7 @@ vanilla-bean-components/
379
379
  ├── Component/ # Core Component class
380
380
  ├── styled/ # Scoped styling system
381
381
  ├── theme/ # Design tokens and helpers
382
- ├── demo/ # Component explorer — live option editor, API docs, example apps
382
+ ├── demo/ # Component explorer - live option editor, API docs, example apps
383
383
  └── docs/ # Additional documentation
384
384
  ```
385
385
 
@@ -20,7 +20,7 @@ sheet.show();
20
20
  | Option | Type | Default | Description |
21
21
  | ---------- | ---------- | --------------- | ----------------------------------------------------------------- |
22
22
  | `appendTo` | `Element` | `document.body` | Where to mount the sheet in the DOM |
23
- | `onClose` | `Function` | — | Called when the sheet is dismissed — by drag or explicit `hide()` |
23
+ | `onClose` | `Function` | - | Called when the sheet is dismissed - by drag or explicit `hide()` |
24
24
 
25
25
  All standard `Component` options are supported.
26
26
 
@@ -15,7 +15,7 @@ Activatable element that unifies pointer and keyboard interaction under one hand
15
15
  - a caller-provided `onKeyUp` runs alongside the built-in keyboard activation; registering both handlers does not suppress either
16
16
  - does providing a custom onKeyUp still trigger onPointerPress on Space/Enter?
17
17
 
18
- ## Tooltip is automatic — no setup beyond the tooltip option
18
+ ## Tooltip is automatic - no setup beyond the tooltip option
19
19
 
20
20
  - Button extends TooltipWrapper; a `tooltip` option produces tooltip behavior with no additional wiring
21
21
  - does a Button with a tooltip option show a tooltip on hover?
@@ -15,7 +15,7 @@ Code display that automatically promotes from inline to block when the content s
15
15
  - the `language` option adds a `language-{name}` class; highlighting libraries target this class by convention
16
16
  - does the language option add an identifiable class to the code element?
17
17
 
18
- ## Copy confirms success visually — clipboard writes can fail silently
18
+ ## Copy confirms success visually - clipboard writes can fail silently
19
19
 
20
20
  - the copy button shows a notification on success so the user knows the copy worked rather than discovering it failed on paste
21
21
  - does a successful copy show the user a confirmation?
@@ -283,7 +283,7 @@ class ColorPicker extends StyledInput {
283
283
 
284
284
  const clamp = (val, min, max) => Math.min(max, Math.max(min, val));
285
285
 
286
- // HSV: x = saturation, y = (1 - value) — matches the gradient exactly
286
+ // HSV: x = saturation, y = (1 - value) - matches the gradient exactly
287
287
  const pickerX = clamp((this.sv ?? 0) * pickerW, 0, pickerW);
288
288
  const pickerY = clamp((1 - (this.v ?? 1)) * pickerH, 0, pickerH);
289
289
  this.pickerIndicator.elem.style.transform = `translate3d(${pickerX}px, ${pickerY}px, 0)`;
@@ -232,7 +232,7 @@ class Dialog extends styled(
232
232
  }
233
233
 
234
234
  /**
235
- * Content container — primary injection point for subclass and consumer content.
235
+ * Content container - primary injection point for subclass and consumer content.
236
236
  * @returns {Component} The dialog body component
237
237
  */
238
238
  get body() {
@@ -14,7 +14,7 @@ Native `<dialog>` element wrapper. The decision to use the native element rather
14
14
  - an unrecognized size or variant throws at the point of assignment, not later when layout breaks
15
15
  - does an unrecognized size value throw?
16
16
 
17
- ## Header, body, and footer are stable references — options update them in place
17
+ ## Header, body, and footer are stable references - options update them in place
18
18
 
19
19
  - the structural elements are created once in `build()` and persist across option updates; assigning a new `header` value changes the header's content, not the dialog's structure
20
20
  - does updating the header option change the header's content without replacing the dialog structure?
@@ -22,25 +22,25 @@ const dialog = new Dialog({
22
22
 
23
23
  | Option | Type | Default | Description |
24
24
  | --- | --- | --- | --- |
25
- | `header` | `string` | — | Text rendered in the `<h2>` header |
26
- | `body` | `string\|Component\|Array` | — | Content for the scrollable body section. Reactive: updating `options.body` replaces content |
27
- | `buttons` | `Array<string\|object>` | — | Shorthand footer buttons. Each entry is a string label or `{ textContent, variant?, onPointerPress?, ...buttonOptions }` |
28
- | `footer` | `Array<Component>` | — | Fully custom footer components. Takes precedence over `buttons` |
29
- | `onButtonPress` | `Function` | — | Called when any `buttons` entry is pressed. Receives `{ button, closeDialog, event }` |
25
+ | `header` | `string` | - | Text rendered in the `<h2>` header |
26
+ | `body` | `string\|Component\|Array` | - | Content for the scrollable body section. Reactive: updating `options.body` replaces content |
27
+ | `buttons` | `Array<string\|object>` | - | Shorthand footer buttons. Each entry is a string label or `{ textContent, variant?, onPointerPress?, ...buttonOptions }` |
28
+ | `footer` | `Array<Component>` | - | Fully custom footer components. Takes precedence over `buttons` |
29
+ | `onButtonPress` | `Function` | - | Called when any `buttons` entry is pressed. Receives `{ button, closeDialog, event }` |
30
30
  | `openOnRender` | `number\|boolean` | `16` | Auto-open delay in ms after render. Set to `false` to disable auto-open |
31
31
  | `modal` | `boolean` | `true` | Open as a modal (with backdrop) vs. non-modal |
32
32
  | `size` | `string` | `'small'` | Dialog dimensions: `'small'` (420×210px), `'standard'` (840×420px), `'large'` (90vw×90vh) |
33
- | `variant` | `string` | — | Color theme: `'info'`, `'success'`, `'warning'`, `'error'` |
34
- | `closeDialog` | `Function` | — | Override the default close behavior used inside `onButtonPress` |
33
+ | `variant` | `string` | - | Color theme: `'info'`, `'success'`, `'warning'`, `'error'` |
34
+ | `closeDialog` | `Function` | - | Override the default close behavior used inside `onButtonPress` |
35
35
  | `appendTo` | `Element` | `document.body` | Where to append the dialog in the DOM |
36
36
 
37
37
  ### `onButtonPress` callback signature
38
38
 
39
39
  ```js
40
40
  onButtonPress: ({ button, closeDialog, event }) => { ... }
41
- // button — the original entry from the buttons array (string or object)
42
- // closeDialog — function that closes the dialog (calls dialog.close() by default)
43
- // event — the pointer event that triggered the press
41
+ // button - the original entry from the buttons array (string or object)
42
+ // closeDialog - function that closes the dialog (calls dialog.close() by default)
43
+ // event - the pointer event that triggered the press
44
44
  ```
45
45
 
46
46
  ## Methods
@@ -14,18 +14,18 @@ import { Label } from '../Label';
14
14
  * **Field definition:**
15
15
  * ```js
16
16
  * {
17
- * key: 'name', // required — data key
18
- * label: 'Full Name', // optional — defaults to formatted key
19
- * InputComponent: Select, // optional — defaults to Input
20
- * onChange: event => {}, // optional — called after data update
21
- * parse: value => value.trim(), // optional — transform before storing
22
- * condition: data => data.type === 'x', // optional — hide field when false
23
- * validate: value => value ? null : 'Required', // optional — field-level validator
17
+ * key: 'name', // required - data key
18
+ * label: 'Full Name', // optional - defaults to formatted key
19
+ * InputComponent: Select, // optional - defaults to Input
20
+ * onChange: event => {}, // optional - called after data update
21
+ * parse: value => value.trim(), // optional - transform before storing
22
+ * condition: data => data.type === 'x', // optional - hide field when false
23
+ * validate: value => value ? null : 'Required', // optional - field-level validator
24
24
  * // ...any other InputComponent options
25
25
  * }
26
26
  * ```
27
27
  *
28
- * **Group definition** — renders inputs side-by-side in a layout container:
28
+ * **Group definition** - renders inputs side-by-side in a layout container:
29
29
  * ```js
30
30
  * {
31
31
  * type: 'group',
@@ -91,7 +91,7 @@ export default class Form extends Component {
91
91
  if (!this._conditionals.length) return;
92
92
  const evaluate = () => this._evaluateConditions();
93
93
  this.options.data.addEventListener('set', evaluate);
94
- // replaceCleanup — safe to call multiple times (inputs handler re-wires on rebuild)
94
+ // replaceCleanup - safe to call multiple times (inputs handler re-wires on rebuild)
95
95
  this.replaceCleanup('conditions', () => this.options.data.removeEventListener('set', evaluate));
96
96
  }
97
97
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  Declarative form from an array of input configurations. The key design decision is that the form owns data binding. Each input's changes update a shared reactive `data` context, and `hasErrors()` validates the whole form in one call.
6
6
 
7
- ## Label text falls back to the field key — no separate label required for obvious fields
7
+ ## Label text falls back to the field key - no separate label required for obvious fields
8
8
 
9
9
  - if an input config omits `label`, the key name becomes the label
10
10
  - does an input with no label option display the key name as its label?
@@ -15,7 +15,7 @@ Declarative form from an array of input configurations. The key design decision
15
15
  - does hasErrors return false when all inputs are valid?
16
16
  - does hasErrors return true when an input's validation fails?
17
17
 
18
- ## Form data is live — changes are visible before any submit action
18
+ ## Form data is live - changes are visible before any submit action
19
19
 
20
20
  - each input's value feeds the shared `data` context as it changes
21
21
  - does typing in an input field update the form's data context before any submit?
@@ -20,7 +20,7 @@ const form = new Form({
20
20
 
21
21
  | Option | Type | Default | Description |
22
22
  | -------- | --------------- | ------- | ----------------------------------------------------------------------- |
23
- | `inputs` | `Array<object>` | — | Input configuration array; see shape below |
23
+ | `inputs` | `Array<object>` | - | Input configuration array; see shape below |
24
24
  | `data` | `object` | `{}` | Initial form data. Replaced with an `Oxject` instance on each `build()` |
25
25
 
26
26
  ### `inputs` entry shape
@@ -32,8 +32,8 @@ const form = new Form({
32
32
  | `InputComponent` | `Component class` | `Input` | Component class to instantiate. Can be `Select`, `ColorPicker`, or any component that accepts `value` and `onChange` |
33
33
  | `onChange` | `Function` | `() => {}` | Called after the data context is updated with the new value |
34
34
  | `parse` | `Function(value, input)` | `v => v` | Transforms the raw event value before storing it in `options.data` |
35
- | `validations` | `Array` | — | Passed directly to the `InputComponent` (see Input validation format) |
36
- | `...inputOptions` | `any` | — | Any additional options forwarded to the `InputComponent` constructor |
35
+ | `validations` | `Array` | - | Passed directly to the `InputComponent` (see Input validation format) |
36
+ | `...inputOptions` | `any` | - | Any additional options forwarded to the `InputComponent` constructor |
37
37
 
38
38
  ### `data` Oxject lifecycle
39
39
 
@@ -27,12 +27,12 @@ const input = new Input({
27
27
  | `autocapitalize` | `string` | `'off'` | Native autocapitalize attribute |
28
28
  | `autocorrect` | `string` | `'off'` | Native autocorrect attribute |
29
29
  | `height` | `string\|number` | `'auto'` | Height for textarea. `'auto'` dynamically sizes to content; a number sets `em` units |
30
- | `syntaxHighlighting` | `boolean` | — | Adds `syntaxHighlighting` class and Tab key indentation handling (textarea only) |
31
- | `language` | `string` | — | Adds `language-<value>` class for Prism-compatible highlighting (requires `syntaxHighlighting`) |
32
- | `validations` | `Array` | — | Validation rules; see Validation section below |
33
- | `onInput` | `Function` | — | Called on every keystroke with an enhanced event containing `.value` |
34
- | `onChange` | `Function` | — | Called on change with an enhanced event containing `.value` |
35
- | `onKeyUp` | `Function` | — | Called on keyup with an enhanced event containing `.value` |
30
+ | `syntaxHighlighting` | `boolean` | - | Adds `syntaxHighlighting` class and Tab key indentation handling (textarea only) |
31
+ | `language` | `string` | - | Adds `language-<value>` class for Prism-compatible highlighting (requires `syntaxHighlighting`) |
32
+ | `validations` | `Array` | - | Validation rules; see Validation section below |
33
+ | `onInput` | `Function` | - | Called on every keystroke with an enhanced event containing `.value` |
34
+ | `onChange` | `Function` | - | Called on change with an enhanced event containing `.value` |
35
+ | `onKeyUp` | `Function` | - | Called on keyup with an enhanced event containing `.value` |
36
36
 
37
37
  ### Supported `type` values
38
38
 
@@ -62,7 +62,7 @@ input.validate({ validations?, value? }): Array | undefined
62
62
  // Runs validation rules. Returns array of error messages if invalid, undefined if valid.
63
63
  // Calling with no args uses options.validations and options.value.
64
64
 
65
- input.isDirty: boolean // getter — true if current value differs from the initial value
65
+ input.isDirty: boolean // getter - true if current value differs from the initial value
66
66
  ```
67
67
 
68
68
  ## Events
@@ -4,7 +4,7 @@
4
4
 
5
5
  On-screen keyboard where layout switching rebuilds the key DOM rather than showing/hiding rows. The decision: a clean rebuild on layout change is safer than managing per-key visibility across layout transitions; no key from one layout can bleed into another.
6
6
 
7
- ## Layout switch produces only keys from the new layout — no residual keys remain
7
+ ## Layout switch produces only keys from the new layout - no residual keys remain
8
8
 
9
9
  - changing `layout` removes all existing keys and builds the new set from scratch; a key that exists in layout A but not layout B is definitively absent after the switch
10
10
  - does switching layout remove keys from the previous layout?
@@ -18,12 +18,12 @@ const StyledList = styled(
18
18
  }
19
19
 
20
20
  &:hover, &:focus, &:focus-visible, & a:hover, & a:focus, & a:focus-visible {
21
- color: ${colors.light(colors.blue)} !important;
22
- border-color: ${colors.light(colors.blue)};
21
+ color: ${colors.light(colors.selected)} !important;
22
+ border-color: ${colors.light(colors.selected)};
23
23
  }
24
24
 
25
25
  &:focus-visible, & a:focus-visible {
26
- outline: 2px solid ${colors.light(colors.blue)};
26
+ outline: 2px solid ${colors.light(colors.selected)};
27
27
  outline-offset: -2px;
28
28
  }
29
29
  }
@@ -9,12 +9,12 @@ Transient notification that self-destructs. The design choice is that click-to-d
9
9
  - callers pass `type: 'error'` and the component picks the matching icon; a custom `icon` option overrides this only when the standard mapping doesn't fit
10
10
  - does a success notification use a visually distinct icon from an error notification?
11
11
 
12
- ## Clicking anywhere on the notification dismisses it — the whole surface is the target
12
+ ## Clicking anywhere on the notification dismisses it - the whole surface is the target
13
13
 
14
14
  - notifications are temporary and should be easy to clear; there is no separate close button
15
15
  - does clicking the notification body remove it from the page?
16
16
 
17
- ## Manual dismiss cancels a pending timeout — no duplicate destroy fires
17
+ ## Manual dismiss cancels a pending timeout - no duplicate destroy fires
18
18
 
19
19
  - when a `timeout` is set and the user dismisses manually before it fires, the timer is cancelled so a second destroy call after the component is already gone cannot happen
20
20
  - does manually dismissing a notification before its timeout prevent a second dismiss?
@@ -4,7 +4,7 @@
4
4
 
5
5
  Top-level layout component that takes ownership of stylesheet loading. The design decision: Page loads FontAwesome and typography as part of mounting; application code does not import or configure these separately.
6
6
 
7
- ## Required stylesheets load once — remounting does not re-fetch
7
+ ## Required stylesheets load once - remounting does not re-fetch
8
8
 
9
9
  - Page checks whether each stylesheet is already present before injecting; remounting in a single-page app does not duplicate link elements or re-trigger network requests
10
10
  - does mounting a Page a second time leave the stylesheet count unchanged?
@@ -4,7 +4,7 @@
4
4
 
5
5
  Radio group from an array of options. The design decision: the HTML `name` coordination that makes radios mutually exclusive is handled automatically; callers pass values and get a working group without managing name attributes.
6
6
 
7
- ## All radios in the group share one name — mutual exclusivity is provided by the browser
7
+ ## All radios in the group share one name - mutual exclusivity is provided by the browser
8
8
 
9
9
  - the component generates a shared `name` attribute; the browser enforces that only one radio in the group can be checked at a time
10
10
  - does each radio input in the group share the same name attribute?
@@ -9,7 +9,7 @@ import { Router, View, Page } from '@vanilla-bean/components';
9
9
 
10
10
  class HomeView extends View {
11
11
  build() {
12
- // render view content here — no Page needed, the shell provides it
12
+ // render view content here - no Page needed, the shell provides it
13
13
  }
14
14
  }
15
15
 
@@ -43,20 +43,20 @@ new Router({
43
43
 
44
44
  | Option | Type | Default | Description |
45
45
  | --- | --- | --- | --- |
46
- | `views` | `object` | — | **Required.** Maps route patterns to component classes. Patterns may contain `:param` segments. |
46
+ | `views` | `object` | - | **Required.** Maps route patterns to component classes. Patterns may contain `:param` segments. |
47
47
  | `defaultPath` | `string` | First key of `views` | Route used when the hash is empty and for fallback on unmatched routes. |
48
- | `notFound` | `typeof Component` | — | Component class rendered when no route matches and `defaultPath` fallback also fails. Receives `{ route }` as an option. |
49
- | `onRenderView` | `Function` | — | Called with the matched route string whenever a new view is rendered. |
48
+ | `notFound` | `typeof Component` | - | Component class rendered when no route matches and `defaultPath` fallback also fails. Receives `{ route }` as an option. |
49
+ | `onRenderView` | `Function` | - | Called with the matched route string whenever a new view is rendered. |
50
50
  | `mode` | `'hash' \| 'history'` | `'hash'` | `'hash'` uses URL fragments (`#/path`). `'history'` uses `pushState` and real pathnames (`/path`). History mode requires the server to serve `index.html` for all routes. |
51
51
 
52
52
  ## Properties
53
53
 
54
54
  ```js
55
- router.path; // string — current URL hash, stripped of '#/', '/', and query strings
55
+ router.path; // string - current URL hash, stripped of '#/', '/', and query strings
56
56
  router.path = '/users/42'; // navigate; sets window.location.hash and re-renders
57
57
 
58
- router.route; // string — the matched route pattern for the current path (e.g. '/users/:id')
59
- router.currentRoute; // string — the last successfully rendered route pattern
58
+ router.route; // string - the matched route pattern for the current path (e.g. '/users/:id')
59
+ router.currentRoute; // string - the last successfully rendered route pattern
60
60
  ```
61
61
 
62
62
  ## Methods
@@ -77,9 +77,9 @@ Routes are matched using exact string equality first, then by replacing `:param`
77
77
 
78
78
  ```js
79
79
  views: {
80
- '/users/new': NewUserView, // exact match — always wins
81
- '/users/:id': UserView, // one param — tested before /:section/:id
82
- '/:section/:id': SectionView, // two params — tested last
80
+ '/users/new': NewUserView, // exact match - always wins
81
+ '/users/:id': UserView, // one param - tested before /:section/:id
82
+ '/:section/:id': SectionView, // two params - tested last
83
83
  }
84
84
  ```
85
85
 
@@ -121,7 +121,7 @@ class SettingsView extends View {
121
121
  }
122
122
  ```
123
123
 
124
- ## Example — full SPA shell
124
+ ## Example - full SPA shell
125
125
 
126
126
  ```js
127
127
  import { Router, View, Nav, NavItem, Page } from '@vanilla-bean/components';
@@ -138,7 +138,7 @@ class ArticleView extends View {
138
138
  }
139
139
  }
140
140
 
141
- // Page is the app shell — Router and Nav live inside it, not inside each view
141
+ // Page is the app shell - Router and Nav live inside it, not inside each view
142
142
  const page = new Page({ title: 'My App', appendTo: document.body });
143
143
 
144
144
  const router = new Router({
@@ -20,9 +20,9 @@ Select inherits all options from `Input`. Key additions:
20
20
 
21
21
  | Option | Type | Default | Description |
22
22
  | --- | --- | --- | --- |
23
- | `options` | `Array<string\|object>` | — | List of selectable options. See shape below. Reactive: reassigning `options.options` rebuilds the `<option>` elements |
24
- | `value` | `any` | — | Currently selected value. Matched against option `value` attributes |
25
- | `onChange` | `Function` | — | Called with an enhanced event containing `.value` (the selected value string) on change |
23
+ | `options` | `Array<string\|object>` | - | List of selectable options. See shape below. Reactive: reassigning `options.options` rebuilds the `<option>` elements |
24
+ | `value` | `any` | - | Currently selected value. Matched against option `value` attributes |
25
+ | `onChange` | `Function` | - | Called with an enhanced event containing `.value` (the selected value string) on change |
26
26
 
27
27
  All other `Input` options (`placeholder`, `validations`, `onInput`, etc.) are available but less commonly used with Select.
28
28
 
@@ -46,8 +46,8 @@ options: ['plain string', { label: 'Display Text', value: 42 }, { label: 'Unavai
46
46
  ## Methods
47
47
 
48
48
  ```js
49
- select.value // getter — returns value, label, or textContent of the selected <option>
50
- select.value = newVal // setter — sets elem.value directly
49
+ select.value // getter - returns value, label, or textContent of the selected <option>
50
+ select.value = newVal // setter - sets elem.value directly
51
51
 
52
52
  // Inherited from Input:
53
53
  select.validate({ validations?, value? }): Array | undefined
@@ -56,7 +56,7 @@ class Select extends Input {
56
56
  * @returns {*} Selected option value, label, or text content
57
57
  */
58
58
  get value() {
59
- // Use elem.options (HTMLOptionsCollection) — works across optgroups
59
+ // Use elem.options (HTMLOptionsCollection) - works across optgroups
60
60
  const selected = Array.from(this.elem.options).find(({ selected }) => selected);
61
61
 
62
62
  return selected?.value ?? selected?.label ?? selected?.textContent ?? this.elem.value;
@@ -20,11 +20,11 @@ const table = new Table({
20
20
 
21
21
  | Option | Type | Default | Description |
22
22
  | --- | --- | --- | --- |
23
- | `data` | `Array<object>` | — | Array of row data objects. Reactive: reassigning `options.data` rebuilds the tbody |
23
+ | `data` | `Array<object>` | - | Array of row data objects. Reactive: reassigning `options.data` rebuilds the tbody |
24
24
  | `columns` | `Array<string\|object>` | `[]` | Column definitions; see shape below |
25
- | `footer` | `Array<string\|object>` | — | Footer row cells, same shape as columns. Strings are capitalized automatically |
26
- | `sortProperty` | `string` | — | Key of the currently sorted column |
27
- | `sortDirection` | `string` | — | `'asc'` or `'desc'` |
25
+ | `footer` | `Array<string\|object>` | - | Footer row cells, same shape as columns. Strings are capitalized automatically |
26
+ | `sortProperty` | `string` | - | Key of the currently sorted column |
27
+ | `sortDirection` | `string` | - | `'asc'` or `'desc'` |
28
28
  | `onSort` | `Function` | built-in | Called with `(property, direction)` when a sortable column header is clicked. Default sorts `options.data` in place using `orderBy` |
29
29
 
30
30
  ### `columns` entry shape
@@ -4,7 +4,7 @@
4
4
 
5
5
  Sortable data table where sort state is explicit options. The design decision: `sortProperty` and `sortDirection` are readable and writable options; the sort state is in the component's options object, not hidden inside event handlers, so it's readable and settable from outside.
6
6
 
7
- ## Sort state lives in options — externally readable and settable
7
+ ## Sort state lives in options - externally readable and settable
8
8
 
9
9
  - clicking a column header updates `sortProperty` and `sortDirection` as regular options; external code can read or set sort state without querying the DOM
10
10
  - does clicking a sortable column update sortProperty to that column's key?
@@ -10,7 +10,7 @@ Editable tag collection. The key decision: read-only mode removes the editing in
10
10
  - does a readOnly TagList contain no input element?
11
11
  - does a non-readOnly TagList contain both an input and an add button?
12
12
 
13
- ## Duplicate tags are silently rejected — adding them does nothing
13
+ ## Duplicate tags are silently rejected - adding them does nothing
14
14
 
15
15
  **method:** `duplicateRejected`
16
16
 
@@ -9,13 +9,13 @@ Component that adds a tooltip to whatever it wraps. The Tooltip is created durin
9
9
  - the Tooltip component is created when the `tooltip` option is processed during render; after construction it exists as `this._tooltip`
10
10
  - does the Tooltip component exist after construction with a tooltip option?
11
11
 
12
- ## Hover shows after a delay — brief mouse-overs do not trigger the tooltip
12
+ ## Hover shows after a delay - brief mouse-overs do not trigger the tooltip
13
13
 
14
14
  - pointerover registers a 700ms timer; pointerout cancels it and hides immediately; hovering for longer than 700ms shows the tooltip
15
15
  - does hovering for longer than 700ms show the tooltip?
16
16
  - does leaving before 700ms prevent the tooltip from appearing?
17
17
 
18
- ## Cleanup removes the tooltip element — nothing outlives the component
18
+ ## Cleanup removes the tooltip element - nothing outlives the component
19
19
 
20
20
  - when the TooltipWrapper is destroyed, the Tooltip component is also destroyed and removed from the DOM
21
21
  - does destroying the wrapper also remove the tooltip from the DOM?
@@ -10,7 +10,7 @@ Multi-touch drawing canvas that tracks each pointer independently. The design de
10
10
  - the whiteboard tracks each active pointer by its ID
11
11
  - does a second finger touching the canvas start a separate line from the first?
12
12
 
13
- ## Draw throttle rate adapts to line width — no separate configuration needed
13
+ ## Draw throttle rate adapts to line width - no separate configuration needed
14
14
 
15
15
  - the throttle delay is derived from `lineWidth + 3` (clamped to a range); thicker lines are visually coarser and tolerate a longer delay
16
16
  - callers set `lineWidth` and the draw rate adjusts automatically; they do not configure throttle separately
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // Minimal type declarations for IDE option-name recognition.
2
- // These are a projection of the source — not a TypeScript implementation.
2
+ // These are a projection of the source - not a TypeScript implementation.
3
3
  // VBC is plain JavaScript. These declarations exist so your IDE can suggest
4
4
  // option names while you write. They do not constrain what the library can do.
5
5
 
@@ -25,6 +25,7 @@ export interface ThemeColors {
25
25
  teal: ThemeColor;
26
26
  white: ThemeColor;
27
27
  black: ThemeColor;
28
+ selected: ThemeColor;
28
29
  transparent: ThemeColor;
29
30
  superWhite: ThemeColor;
30
31
  vantablack: ThemeColor;
@@ -189,7 +190,7 @@ export declare function styled<T extends typeof Elem>(
189
190
  export declare function configured<T extends typeof Elem>(Base: T, options: Partial<ComponentOptions>): T;
190
191
 
191
192
  // ── GENERATED: Built-in components ────────────────────────────────────────────
192
- // This section is generated by devTools/buildTypes.js — do not edit manually.
193
+ // This section is generated by devTools/buildTypes.js - do not edit manually.
193
194
  // Run `bun run build:types` to regenerate from JSDoc annotations.
194
195
 
195
196
  export interface BottomSheetOptions extends ComponentOptions {
@@ -310,7 +311,7 @@ export interface DialogOptions extends ComponentOptions {
310
311
 
311
312
  export declare class Dialog extends Component {
312
313
  constructor(options?: DialogOptions, ...children: Array<Elem | HTMLElement | string>);
313
- /** Content container — primary injection point for subclass and consumer content. */
314
+ /** Content container - primary injection point for subclass and consumer content. */
314
315
  readonly body: Component;
315
316
  /** Opens the dialog, either as modal or non-modal */
316
317
  open(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanilla-bean/components",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "module": "./index.js",
6
6
  "types": "./index.d.ts",