stimeo-ui 0.16.0 → 0.18.0

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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +136 -0
  3. data/README.md +27 -11
  4. data/dist/cable/index.js +384 -449
  5. data/dist/controllers/accordion_controller.js +174 -55
  6. data/dist/controllers/alert_dialog_controller.js +903 -235
  7. data/dist/controllers/announcer_controller.js +238 -205
  8. data/dist/controllers/aspect_ratio_controller.js +0 -10
  9. data/dist/controllers/auto_submit_controller.js +414 -145
  10. data/dist/controllers/avatar_controller.js +185 -107
  11. data/dist/controllers/breadcrumb_controller.js +0 -130
  12. data/dist/controllers/bulk_select_controller.js +282 -58
  13. data/dist/controllers/calendar_controller.js +228 -260
  14. data/dist/controllers/carousel_controller.js +536 -436
  15. data/dist/controllers/character_counter_controller.js +493 -207
  16. data/dist/controllers/checkbox_controller.js +38 -74
  17. data/dist/controllers/clipboard_controller.js +261 -149
  18. data/dist/controllers/collapsible_controller.js +304 -120
  19. data/dist/controllers/color_picker_controller.js +178 -146
  20. data/dist/controllers/combobox_controller.js +522 -156
  21. data/dist/controllers/command_palette_controller.js +1156 -395
  22. data/dist/controllers/conditional_fields_controller.js +300 -171
  23. data/dist/controllers/confirm_controller.js +980 -262
  24. data/dist/controllers/context_menu_controller.js +346 -153
  25. data/dist/controllers/count_up_controller.js +73 -21
  26. data/dist/controllers/countdown_controller.js +281 -158
  27. data/dist/controllers/currency_input_controller.js +575 -225
  28. data/dist/controllers/data_grid_controller.js +248 -214
  29. data/dist/controllers/date_range_picker_controller.js +338 -235
  30. data/dist/controllers/dialog_controller.js +899 -237
  31. data/dist/controllers/direct_upload_controller.js +97 -167
  32. data/dist/controllers/dirty_form_controller.js +72 -69
  33. data/dist/controllers/dismissible_controller.js +196 -24
  34. data/dist/controllers/drawer_controller.js +974 -355
  35. data/dist/controllers/dropdown_controller.js +339 -96
  36. data/dist/controllers/editable_controller.js +315 -88
  37. data/dist/controllers/empty_state_controller.js +79 -58
  38. data/dist/controllers/file_dropzone_controller.js +322 -211
  39. data/dist/controllers/filter_controller.js +77 -42
  40. data/dist/controllers/flash_controller.js +238 -347
  41. data/dist/controllers/focus_controller.js +679 -240
  42. data/dist/controllers/form_field_controller.js +156 -132
  43. data/dist/controllers/form_validation_controller.js +31 -97
  44. data/dist/controllers/frame_loading_controller.js +275 -217
  45. data/dist/controllers/highlight_controller.js +107 -75
  46. data/dist/controllers/hover_card_controller.js +327 -130
  47. data/dist/controllers/idle_controller.js +271 -101
  48. data/dist/controllers/input_mask_controller.js +483 -97
  49. data/dist/controllers/intersection_controller.js +150 -106
  50. data/dist/controllers/lazy_frame_controller.js +24 -68
  51. data/dist/controllers/listbox_controller.js +523 -240
  52. data/dist/controllers/local_time_controller.js +102 -77
  53. data/dist/controllers/masonry_controller.js +80 -96
  54. data/dist/controllers/menu_controller.js +302 -188
  55. data/dist/controllers/menubar_controller.js +232 -345
  56. data/dist/controllers/meter_controller.js +417 -87
  57. data/dist/controllers/multi_select_controller.js +785 -393
  58. data/dist/controllers/navigation_menu_controller.js +190 -250
  59. data/dist/controllers/nested_form_controller.js +396 -192
  60. data/dist/controllers/network_status_controller.js +268 -62
  61. data/dist/controllers/number_input_controller.js +610 -303
  62. data/dist/controllers/optimistic_controller.js +45 -87
  63. data/dist/controllers/otp_controller.js +658 -255
  64. data/dist/controllers/overflow_indicator_controller.js +122 -113
  65. data/dist/controllers/overflow_menu_controller.js +470 -295
  66. data/dist/controllers/pagination_controller.js +332 -123
  67. data/dist/controllers/password_reveal_controller.js +392 -121
  68. data/dist/controllers/password_strength_controller.js +111 -158
  69. data/dist/controllers/persist_controller.js +165 -111
  70. data/dist/controllers/pointer_drag_controller.js +434 -188
  71. data/dist/controllers/popover_controller.js +269 -113
  72. data/dist/controllers/portal_controller.js +215 -76
  73. data/dist/controllers/preview_guard_controller.js +243 -116
  74. data/dist/controllers/progress_controller.js +391 -78
  75. data/dist/controllers/radio_group_controller.js +278 -211
  76. data/dist/controllers/range_slider_controller.js +220 -113
  77. data/dist/controllers/rating_controller.js +458 -211
  78. data/dist/controllers/read_more_controller.js +138 -63
  79. data/dist/controllers/reading_progress_controller.js +166 -137
  80. data/dist/controllers/relative_time_controller.js +211 -112
  81. data/dist/controllers/{reset_before_cache_controller.js → reset_on_restore_controller.js} +103 -38
  82. data/dist/controllers/resizable_controller.js +299 -150
  83. data/dist/controllers/roving_controller.js +49 -88
  84. data/dist/controllers/scroll_area_controller.js +490 -246
  85. data/dist/controllers/scroll_restore_controller.js +14 -55
  86. data/dist/controllers/scroll_visibility_controller.js +432 -149
  87. data/dist/controllers/scrollspy_controller.js +193 -248
  88. data/dist/controllers/separator_controller.js +285 -142
  89. data/dist/controllers/sidebar_controller.js +1069 -404
  90. data/dist/controllers/skeleton_controller.js +259 -101
  91. data/dist/controllers/slider_controller.js +187 -86
  92. data/dist/controllers/smart_sticky_header_controller.js +173 -66
  93. data/dist/controllers/sortable_controller.js +26 -125
  94. data/dist/controllers/spinner_controller.js +288 -173
  95. data/dist/controllers/step_indicator_controller.js +105 -46
  96. data/dist/controllers/stepper_controller.js +120 -73
  97. data/dist/controllers/stick_to_bottom_controller.js +275 -140
  98. data/dist/controllers/sticky_observer_controller.js +220 -49
  99. data/dist/controllers/submit_once_controller.js +376 -227
  100. data/dist/controllers/switch_controller.js +201 -84
  101. data/dist/controllers/tabs_controller.js +41 -30
  102. data/dist/controllers/tags_input_controller.js +293 -173
  103. data/dist/controllers/textarea_autosize_controller.js +108 -74
  104. data/dist/controllers/theme_controller.js +140 -116
  105. data/dist/controllers/time_picker_controller.js +331 -127
  106. data/dist/controllers/toast_controller.js +244 -324
  107. data/dist/controllers/toggle_group_controller.js +252 -191
  108. data/dist/controllers/toolbar_controller.js +219 -120
  109. data/dist/controllers/tooltip_controller.js +158 -124
  110. data/dist/controllers/transition_controller.js +123 -119
  111. data/dist/controllers/tree_view_controller.js +283 -369
  112. data/dist/index.js +8573 -10410
  113. data/dist/positioning/index.js +154 -47
  114. data/lib/generators/stimeo/install/install_generator.rb +7 -2
  115. data/lib/generators/stimeo/install/templates/stimeo.js +19 -6
  116. data/lib/stimeo/ui/version.rb +1 -1
  117. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 725d3da54257b2c556c30de96e34c325ed04ccfd06a9c065484aab388f5f969c
4
- data.tar.gz: ea9c6e5c0c2fd7dea325e6769af6b51f51e74a179575cbb05695cf965a141357
3
+ metadata.gz: 05c2871de0e4c97223dfb10803e8c4fa84abc3a0cf5e9c946d6570d88c46f065
4
+ data.tar.gz: a772dc1b21e16d21ea37af8dbb2f6a56618fa94252fe43eebcbede4ab296c2a2
5
5
  SHA512:
6
- metadata.gz: b080427c85f5accf04f627e757046fac13eda2a48b0ea1e27c548fbd035cb8bc90ddfcbfdb79f3bd63c7899e16649d873efcbdc6a964c5a4e2682271ccf48749
7
- data.tar.gz: b0d2bcd93e2beb311c4fe4e9a09f843b89cdc87e43ad88f8fd5a13e5146e939b8b9abce3adda89922c486337a141d854cfe74778a04b6249780554761cb3d4d5
6
+ metadata.gz: a74a9a638fadb04fcec7c72ced80825fb75215051533508d2e58c40fc64ef4eb3aa41a0b76ee85ab9697004f9861d6b6a46b75ec62c39b013d274487f7986d42
7
+ data.tar.gz: 2b0ff0e66bc0f7062c241ee01032888206b300eb74c552561c3638638a9255a19ea69b1a9555fa5e72b50ab1e8bd8479f9b37f8e79743077df6da59ee65e2409
data/CHANGELOG.md CHANGED
@@ -7,6 +7,139 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
  While the version is `0.x`, the public API (the `stimeo--*` data attributes) may
8
8
  change between releases.
9
9
 
10
+ ## [Unreleased]
11
+
12
+ ## [0.18.0] - 2026-10-22
13
+
14
+ Minor release with no new components. IME composition, Turbo morphs, and form
15
+ submission now behave consistently across the input components, and several
16
+ contracts change, so read Changed before upgrading. The Inspector manifest moves
17
+ to schema v16; update `stimeo check` and the VS Code extension together and run
18
+ `stimeo check` before deploying.
19
+
20
+ ### Added
21
+
22
+ - time-picker: `amLabel` and `pmLabel` Values set the meridiem text and its
23
+ speech, and `hour12ZeroBased` shows and enters a twelve-hour clock's hours as
24
+ 0–11, as `午前` / `午後` time is written. The submitted value stays on the
25
+ 24-hour clock.
26
+
27
+ ### Changed
28
+
29
+ - **Breaking** input-mask: a synchronized hidden field carries a unique internal
30
+ DOM name; native FormData and native / Turbo submission restore the original
31
+ name, and removing the source submits an empty entry. Find managed fields by id
32
+ or the pairing attribute, use native FormData, and call
33
+ `prepareInputMaskForm(form)` before reading FormData from a new detached form.
34
+ input-mask clears only the raw value it wrote.
35
+ - **Breaking** otp: a pattern drop held for a composition is reported as
36
+ `reconcile` before the edit's own `change` / `complete` / `invalid`, and a
37
+ reconnect under another `pattern` drops what it rejects as `reconcile`. Use the
38
+ edit events for submission.
39
+ - **Breaking** number-input: a range or step change made during IME composition
40
+ applies when the user confirms, reported as `change`; a morph that changes
41
+ neither holds nothing.
42
+ - **Breaking** currency-input: actions and events act only on the first `display`
43
+ target, and a display already focused when the controller connects starts
44
+ formatting at its next ordinary edit or composition end. Render the initial
45
+ hidden and accessible values on the server. `stimeo check` warns about extra
46
+ displays.
47
+ - **Breaking** tabs, calendar, date-range-picker, slider, range-slider,
48
+ color-picker, multi-select, and tags-input read the writing direction from their
49
+ layout targets instead of the root; carousel gains a `pickerList` and
50
+ navigation-menu a `list` target.
51
+ - **Breaking** dirty-form and optimistic accept only the terminal event matching
52
+ the latest start's source and token, and only `success: true` succeeds. For a
53
+ custom save, call `markClean` or dispatch the paired events with `success`.
54
+ - **Breaking** local-time and relative-time read `datetime` strictly: a clock
55
+ without a zone is UTC (relative-time read it as local time), and an incomplete
56
+ or invalid value keeps the current display.
57
+ - **Breaking** presence and typing-indicator templates use `{count}`, `{name}`,
58
+ and `{names}` instead of `%{…}`.
59
+ - **Breaking** modified `Home` / `End` / `PageUp` / `PageDown` go to the browser
60
+ in widgets without a dedicated binding; pointer-drag cancels a keyboard grab
61
+ when focus leaves the handle; time-picker accepts digits typed with `Shift`.
62
+ - **Breaking** progress, meter, pointer-drag, countdown, overflow-menu, listbox,
63
+ submit-once, clipboard, announcer, and currency-input change their ownership
64
+ markers (pointer-drag: `data-stimeo--pointer-drag-tabindex-loan`, listbox:
65
+ `owns-label`); re-render persisted HTML from authored markup. progress and meter
66
+ restore the authored `aria-valuetext` when the template is cleared or the
67
+ controller disconnects.
68
+ - **Breaking** menubar, navigation-menu, menu, and context-menu treat an entry
69
+ inside an `aria-disabled="true"` ancestor as disabled (it stays reachable with
70
+ the arrow keys), and with nested entries refuse an action when any entry holding
71
+ its target is disabled. A click is judged when it reaches the component, so a
72
+ handler inside the component that disables its entry during the click keeps the
73
+ open or close it started; a menubar top it leaves natively `disabled` then has
74
+ its menu closed again, without a `close` event.
75
+ - **Breaking** pointer-drag: `reset()` returns the inline `translate` to the
76
+ origin only when `follow` is on; otherwise it cancels the gesture in flight and
77
+ leaves the author's `translate` alone.
78
+ - toggle-group writes `aria-pressed`, time-picker `aria-valuenow`, and radio-group
79
+ its arrival and release `tabindex` only when the value changes.
80
+ - context-menu: the region contract drops `aria-haspopup`; give the region a role
81
+ and name that fit its content and advertise the key with
82
+ `aria-keyshortcuts="Shift+F10"`.
83
+ - `stimeo check` reports `missing-announcer` for the `stimeo-ui/cable`
84
+ controllers (live-counter, presence, typing-indicator), and the
85
+ `stimeo:install` generator writes commented-out pins and registrations for the
86
+ opt-in `stimeo-ui/cable` and `stimeo-ui/positioning` entry points.
87
+
88
+ ### Removed
89
+
90
+ - character-counter: the `announceTextValueChanged()` callback is gone from the
91
+ shipped types; pending announcements still read the current `announceText`.
92
+
93
+ ### Fixed
94
+
95
+ - IME composition no longer sticks after a page write, a move, or a Turbo morph
96
+ in auto-submit, character-counter, combobox, command-palette, currency-input,
97
+ editable, input-mask, multi-select, number-input, otp, tags-input, and toolbar.
98
+ A morph leaves a field mid-composition alone, and a focused draft survives
99
+ morphs and reconnection.
100
+ - switch, otp, currency-input, and input-mask keep their hidden form values right
101
+ across Turbo morphs and removal.
102
+ - State events and reconciliation stay right when a `change` listener disconnects
103
+ the controller or the page edits state during a repair.
104
+ - Components release what an earlier connection registered when connected twice,
105
+ and keep authored text, ARIA, and tab stops through restores.
106
+ - relative-time follows live `datetime` changes; template substitution leaves
107
+ inherited names such as `{constructor}` unchanged.
108
+ - menubar, navigation-menu, menu, and context-menu refuse a `hidden`, natively
109
+ `disabled`, or `aria-disabled` entry on every route — an explicit element, any
110
+ event, or hover — as a click on it already was; `context-menu#activate` takes
111
+ the optional event.
112
+ - The MCP server accepts JSON-RPC batches in sessions that negotiated protocol
113
+ version 2025-03-26; other versions, and batches before `initialize`, are still
114
+ rejected.
115
+
116
+ ## [0.17.0] - 2026-10-04
117
+
118
+ ### Changed
119
+
120
+ - **Breaking** Replace `reset-before-cache` with `reset-on-restore` (class, export,
121
+ and subpath).
122
+ Reset runs on restoration; remove `dispatchReset` and `:request` bindings.
123
+ Restored drawers and command palettes start closed.
124
+ - **Breaking** Rename calendar, combobox, and command-palette `selectByClick`, and
125
+ tree-view `onClick`, to `select`; replace calendar `selectDayElement` with
126
+ `select(element)`.
127
+ Accordion `toggle`, theme `set`, and scrollspy `scrollTo` require owned targets.
128
+ - **Breaking** State events are silent for unchanged state and superseded pending
129
+ reports.
130
+ For child edits within partial checkbox groups, use the children's native `change`.
131
+ Number Values and action params enforce finite values and their declared domains.
132
+ Update Inspector integrations to schema v15 and run `stimeo check` before deploying.
133
+ - Target actions accept owned elements; user state reports include `detail.reason`.
134
+ Toast duration, persist debounce, and count-up duration changes apply to the next
135
+ operation. Portal destination changes update mounts; Cable params cannot replace
136
+ the declared channel.
137
+
138
+ ### Fixed
139
+
140
+ - Preserve live state across Turbo caching, repair derived state after retained
141
+ morphs, and restore focus reliably across nested layers and Shadow DOM.
142
+
10
143
  ## [0.16.0] - 2026-09-26
11
144
 
12
145
  Minor release with no new components. Widgets now report their own state
@@ -1278,6 +1411,9 @@ Initial public alpha: 101 behavior-only, accessible Stimulus controllers driven
1278
1411
  by `data-*` attributes, shipping no CSS. Published to npm (with provenance) and
1279
1412
  RubyGems.
1280
1413
 
1414
+ [Unreleased]: https://github.com/taiyaky/stimeo-ui/compare/v0.18.0...HEAD
1415
+ [0.18.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.18.0
1416
+ [0.17.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.17.0
1281
1417
  [0.16.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.16.0
1282
1418
  [0.15.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.15.0
1283
1419
  [0.14.0]: https://github.com/taiyaky/stimeo-ui/releases/tag/v0.14.0
data/README.md CHANGED
@@ -15,9 +15,9 @@
15
15
  owns the look entirely.
16
16
 
17
17
  - Lean by design: the **core** needs only `@hotwired/stimulus` at runtime (kept
18
- external in the build). The opt-in `stimeo-ui/positioning` module is the one
19
- exception — it uses `@floating-ui/dom` (an optional **peer dependency**; see the
20
- Peer dependencies note below).
18
+ external in the build). Two opt-in subpaths each add one optional **peer
19
+ dependency**: `stimeo-ui/positioning` (`@floating-ui/dom`) and `stimeo-ui/cable`
20
+ (`@rails/actioncable`); see the Peer dependencies note below.
21
21
  - Accessibility first: every controller follows the relevant WAI-ARIA APG pattern
22
22
  and the related WCAG 2.2 AA criteria.
23
23
  - Public controller identifiers use the `stimeo--` namespace (e.g.
@@ -36,8 +36,12 @@ bin/rails generate stimeo:install
36
36
  ```
37
37
 
38
38
  The generator vendors the prebuilt JS into `vendor/javascript/stimeo/`, pins
39
- `stimeo-ui` in `config/importmap.rb`, and registers all controllers with your
40
- Stimulus application. Then drive components from HTML alone:
39
+ `stimeo-ui` in `config/importmap.rb`, and registers the core controllers with your
40
+ Stimulus application (`app/javascript/controllers/stimeo.js`). It writes the opt-in
41
+ `stimeo-ui/positioning` and `stimeo-ui/cable` entry points into those two files
42
+ commented out; to enable one, uncomment its lines. The cable lines include the pin
43
+ for its `@rails/actioncable` peer; positioning also needs a pin for
44
+ `@floating-ui/dom`. Then drive components from HTML alone:
41
45
 
42
46
  ```erb
43
47
  <div data-controller="stimeo--dropdown">
@@ -58,15 +62,26 @@ import { Application } from "@hotwired/stimulus";
58
62
  import { registerStimeo } from "stimeo-ui";
59
63
 
60
64
  const application = Application.start();
61
- registerStimeo(application); // registers every stimeo--* controller
65
+ registerStimeo(application); // registers every controller of the core entry point
62
66
  ```
63
67
 
68
+ The opt-in `stimeo-ui/positioning` and `stimeo-ui/cable` entry points register
69
+ theirs with `registerPositioning` / `registerCable`.
70
+
64
71
  Need only a few controllers? Import them individually from
65
- `stimeo-ui/controllers/*` and register them under your own identifiers.
72
+ `stimeo-ui/controllers/*` and register them under your own identifiers. Each
73
+ file loads on its own, yet the coordination between components — which layer
74
+ Escape closes, a focus trap's `Tab` and background, the value two components
75
+ lend the same attribute — is kept once per page, whichever files the
76
+ controllers came from, `stimeo-ui` itself included.
77
+ Copies of the same controller also share dirty-form confirmations, highlight
78
+ deadlines and portal origins. Opt-in Cable copies share the consumer, subscriptions
79
+ and peer departure decisions; generated ARIA ids stay distinct across copies too.
66
80
 
67
81
  - **Peer dependencies:** `@hotwired/stimulus` (always), `@floating-ui/dom` (only
68
82
  if you use the opt-in `stimeo-ui/positioning` module — tooltips, popovers, etc.
69
- work without it via the default flow layout).
83
+ work without it via the default flow layout), and `@rails/actioncable` (only if
84
+ you use the opt-in `stimeo-ui/cable` module).
70
85
  - **No CSS is shipped.** Style the components yourself; controllers only toggle
71
86
  ARIA state and `data-*` hooks.
72
87
 
@@ -111,8 +126,9 @@ keep the rules on everywhere else. For Biome:
111
126
  The `eslint-plugin-jsx-a11y` equivalents are
112
127
  `no-noninteractive-element-to-interactive-role`, `no-redundant-roles`,
113
128
  `prefer-tag-over-role`, `interactive-supports-focus`, and
114
- `no-noninteractive-tabindex`. These components' real accessibility is exercised
115
- with axe-core and real screen readers in this project's own test suite.
129
+ `no-noninteractive-tabindex`. This repository's tests check these components
130
+ with axe-core and with a virtual screen reader for speech order; neither stands
131
+ in for a real screen reader on your own pages.
116
132
 
117
133
  ## Composing components
118
134
 
@@ -272,7 +288,7 @@ or in `.mcp.json` (Claude Code) / `.cursor/mcp.json` (Cursor):
272
288
  It exposes four read-only tools — `stimeo_check` (validate a source string),
273
289
  `stimeo_catalog`, `stimeo_controller` (one controller's full contract,
274
290
  accessibility requirements included), and `stimeo_example` (verified example
275
- markup: the official catalog demo under [`examples/`](examples/), bundled at
291
+ markup: the controller's demo under [`examples/`](examples/), bundled at
276
292
  build time and guaranteed to pass the checker) — plus MCP resources
277
293
  (`stimeo://manifest`, `stimeo://examples/<id>`) for preloading context without
278
294
  a tool round-trip. The server reads only its bundled manifest and example