stimeo-ui 0.10.0 → 0.11.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.
@@ -271,7 +271,7 @@
271
271
  },
272
272
  "stimeo--pointer-drag": {
273
273
  "file": "examples/pointer_drag/_demo.html.erb",
274
- "source": "<%# pointer-drag: the primitive normalizes the drag lifecycle (threshold, axis\n lock, pointer capture, touch-action, cancel) and adds a keyboard alternative.\n With the opt-in follow value it also moves the card itself — translate on\n move, committed on drop, restored on cancel — so the consumer JS below only\n mirrors the signal into the status line. %>\n<div class=\"pointer-drag-demo\">\n <p class=\"pointer-drag-demo__hint\"><%= t(\"components.pointer_drag.demo.hint\") %></p>\n <div class=\"pointer-drag-demo__area\">\n <button type=\"button\" class=\"pointer-drag-demo__card\" id=\"pointer-drag-card\"\n data-controller=\"stimeo--pointer-drag\"\n data-stimeo--pointer-drag-follow-value=\"true\">\n <svg class=\"demo-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\"\n aria-hidden=\"true\">\n <circle cx=\"9\" cy=\"6\" r=\"1.5\"></circle><circle cx=\"15\" cy=\"6\" r=\"1.5\"></circle>\n <circle cx=\"9\" cy=\"12\" r=\"1.5\"></circle><circle cx=\"15\" cy=\"12\" r=\"1.5\"></circle>\n <circle cx=\"9\" cy=\"18\" r=\"1.5\"></circle><circle cx=\"15\" cy=\"18\" r=\"1.5\"></circle>\n </svg>\n <%= t(\"components.pointer_drag.demo.card_label\") %>\n </button>\n </div>\n <p class=\"pointer-drag-demo__status\" data-pointer-drag-status aria-live=\"polite\"\n data-moved-template=\"<%= t(\"components.pointer_drag.demo.moved_template\") %>\"\n data-idle-text=\"<%= t(\"components.pointer_drag.demo.idle_text\") %>\"></p>\n</div>\n"
274
+ "source": "<%# pointer-drag: the primitive normalizes the drag lifecycle (threshold, axis\n lock, pointer capture, touch-action, cancel) and adds a keyboard alternative.\n With the opt-in follow value it also moves the card itself — translate on\n move, committed on drop, restored on cancel — so the consumer JS below only\n mirrors the signal into the status line. The card can travel out of the\n dashed area, which the area clips; the reset action brings it back, since\n follow's committed offset is internal state a consumer cannot clear. The\n button sits outside the controller element, so its click reaches the action\n as a custom event the element's own data-action maps. %>\n<div class=\"pointer-drag-demo\">\n <p class=\"pointer-drag-demo__hint\"><%= t(\"components.pointer_drag.demo.hint\") %></p>\n <div class=\"pointer-drag-demo__area\">\n <button type=\"button\" class=\"pointer-drag-demo__card\" id=\"pointer-drag-card\"\n data-controller=\"stimeo--pointer-drag\"\n data-stimeo--pointer-drag-follow-value=\"true\"\n data-action=\"demo:reset->stimeo--pointer-drag#reset\">\n <svg class=\"demo-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\"\n aria-hidden=\"true\">\n <circle cx=\"9\" cy=\"6\" r=\"1.5\"></circle><circle cx=\"15\" cy=\"6\" r=\"1.5\"></circle>\n <circle cx=\"9\" cy=\"12\" r=\"1.5\"></circle><circle cx=\"15\" cy=\"12\" r=\"1.5\"></circle>\n <circle cx=\"9\" cy=\"18\" r=\"1.5\"></circle><circle cx=\"15\" cy=\"18\" r=\"1.5\"></circle>\n </svg>\n <%= t(\"components.pointer_drag.demo.card_label\") %>\n </button>\n </div>\n <p class=\"pointer-drag-demo__actions\">\n <button type=\"button\" class=\"demo-trigger\" data-pointer-drag-reset>\n <%= t(\"components.pointer_drag.demo.reset_label\") %>\n </button>\n </p>\n <p class=\"pointer-drag-demo__status\" data-pointer-drag-status aria-live=\"polite\"\n data-moved-template=\"<%= t(\"components.pointer_drag.demo.moved_template\") %>\"\n data-idle-text=\"<%= t(\"components.pointer_drag.demo.idle_text\") %>\"></p>\n</div>\n"
275
275
  },
276
276
  "stimeo--popover": {
277
277
  "file": "examples/popover/_demo.html.erb",
@@ -287,7 +287,7 @@
287
287
  },
288
288
  "stimeo--preview-guard": {
289
289
  "file": "examples/preview_guard/_demo.html.erb",
290
- "source": "<%# Preview-guard demo: data-turbo-preview is a Turbo-internal attribute, so this catalog\n has no real preview to show. demo.js toggles it on <html> for ~1.5s to reproduce a\n preview window — exactly what Turbo does on a back/restore visit. The balance guards in\n placeholder mode (swaps to —) and the timestamp in hide mode (becomes invisible, box\n kept). The library only watches the attribute and reflects data-preview-hidden. %>\n<div class=\"preview-guard-demo\">\n <button type=\"button\" class=\"demo-trigger\" data-preview-guard-demo-toggle>\n <%= t(\"components.preview_guard.demo.toggle\") %>\n </button>\n\n <dl class=\"preview-guard-demo__list\">\n <div class=\"preview-guard-demo__row\">\n <dt><%= t(\"components.preview_guard.demo.balance_label\") %></dt>\n <dd>\n <span\n class=\"preview-guard-demo__value\"\n data-controller=\"stimeo--preview-guard\"\n data-stimeo--preview-guard-mode-value=\"placeholder\"\n data-stimeo--preview-guard-placeholder-value=\"—\"\n ><%= t(\"components.preview_guard.demo.balance\") %></span>\n </dd>\n </div>\n <div class=\"preview-guard-demo__row\">\n <dt><%= t(\"components.preview_guard.demo.updated_label\") %></dt>\n <dd>\n <span\n class=\"preview-guard-demo__value\"\n data-controller=\"stimeo--preview-guard\"\n ><%= t(\"components.preview_guard.demo.updated\") %></span>\n </dd>\n </div>\n </dl>\n\n <p class=\"preview-guard-demo__note\"><%= t(\"components.preview_guard.demo.note\") %></p>\n</div>\n"
290
+ "source": "<%# Preview-guard demo: data-turbo-preview is a Turbo-internal attribute, so this catalog\n has no real preview to show. demo.js toggles it on <html> for ~1.5s to reproduce a\n preview window — exactly what Turbo does on a back/restore visit. The balance declares a\n placeholder, so it swaps to —; the timestamp declares none, so it goes invisible with its\n box kept. The library only watches the attribute and reflects data-preview-hidden. %>\n<div class=\"preview-guard-demo\">\n <button type=\"button\" class=\"demo-trigger\" data-preview-guard-demo-toggle>\n <%= t(\"components.preview_guard.demo.toggle\") %>\n </button>\n\n <dl class=\"preview-guard-demo__list\">\n <div class=\"preview-guard-demo__row\">\n <dt><%= t(\"components.preview_guard.demo.balance_label\") %></dt>\n <dd>\n <span\n class=\"preview-guard-demo__value\"\n data-controller=\"stimeo--preview-guard\"\n data-stimeo--preview-guard-placeholder-value=\"—\"\n ><%= t(\"components.preview_guard.demo.balance\") %></span>\n </dd>\n </div>\n <div class=\"preview-guard-demo__row\">\n <dt><%= t(\"components.preview_guard.demo.updated_label\") %></dt>\n <dd>\n <span\n class=\"preview-guard-demo__value\"\n data-controller=\"stimeo--preview-guard\"\n ><%= t(\"components.preview_guard.demo.updated\") %></span>\n </dd>\n </div>\n </dl>\n\n <p class=\"preview-guard-demo__note\"><%= t(\"components.preview_guard.demo.note\") %></p>\n</div>\n"
291
291
  },
292
292
  "stimeo--progress": {
293
293
  "file": "examples/progress/_demo.html.erb",
@@ -443,7 +443,7 @@
443
443
  },
444
444
  "stimeo--typing-indicator": {
445
445
  "file": "examples/typing_indicator/_demo.html.erb",
446
- "source": "<%# typing-indicator: the state lives on the server stream, not in client memory.\n Typing in the composer broadcasts a throttled signal through TypingChannel;\n every OTHER client shows \"X is typing…\" in the status live region and clears\n it automatically after silence. Own echoes are suppressed by design, so open\n this page in a second tab to see the indicator. The guest name is randomized\n per render so each tab is a distinct \"user\" (a real app passes\n current_user.name). The data-one/data-many templates keep the announcement\n localizable; %{name}/%{names} are substituted by the controller. %>\n<% guest = t(\"components.typing_indicator.demo.guest_name\", token: SecureRandom.hex(2)) %>\n<div class=\"typing-demo\"\n data-controller=\"stimeo--typing-indicator\"\n data-stimeo--typing-indicator-channel-value=\"TypingChannel\"\n data-stimeo--typing-indicator-params-value='{\"room\":\"<%= TypingChannel::ROOM %>\"}'\n data-stimeo--typing-indicator-name-value=\"<%= guest %>\"\n data-stimeo--typing-indicator-timeout-value=\"3000\"\n data-stimeo--typing-indicator-throttle-value=\"1000\">\n <p class=\"typing-demo__hint\"><%= t(\"components.typing_indicator.demo.hint\") %></p>\n <p class=\"typing-demo__you\"><%= t(\"components.typing_indicator.demo.you_are\", name: guest) %></p>\n <label class=\"typing-demo__label\" for=\"typing-demo-input\">\n <%= t(\"components.typing_indicator.demo.input_label\") %>\n </label>\n <textarea id=\"typing-demo-input\" class=\"demo-input typing-demo__input\" rows=\"3\"\n data-stimeo--typing-indicator-target=\"input\"></textarea>\n <p class=\"typing-demo__status\" role=\"status\"\n data-stimeo--typing-indicator-target=\"status\"\n data-one=\"<%= t(\"components.typing_indicator.demo.one\") %>\"\n data-many=\"<%= t(\"components.typing_indicator.demo.many\") %>\"></p>\n</div>\n"
446
+ "source": "<%# typing-indicator: the state lives on the server stream, not in client memory.\n Typing in the composer broadcasts a throttled signal through TypingChannel;\n every OTHER client shows \"X is typing…\" in the visible status slot and clears\n it automatically after silence. Own echoes are suppressed by design, so open\n this page in a second tab to see the indicator. The guest name is randomized\n per render so each tab is a distinct \"user\" (a real app passes\n current_user.name). The data-one/data-many templates keep the announcement\n localizable; %{name}/%{names} are substituted by the controller. The status slot is\n plain visible copy — assistive tech is reached through the page's shared announcer\n instead, so the announce-one/announce-many values carry the spoken wording ({name}\n syntax, not %{}). Leaving them off shows the indicator without announcing it. %>\n<% guest = t(\"components.typing_indicator.demo.guest_name\", token: SecureRandom.hex(2)) %>\n<% announce_one = t(\"components.typing_indicator.demo.announce_one\") %>\n<% announce_many = t(\"components.typing_indicator.demo.announce_many\") %>\n<div class=\"typing-demo\"\n data-controller=\"stimeo--typing-indicator\"\n data-stimeo--typing-indicator-channel-value=\"TypingChannel\"\n data-stimeo--typing-indicator-params-value='{\"room\":\"<%= TypingChannel::ROOM %>\"}'\n data-stimeo--typing-indicator-name-value=\"<%= guest %>\"\n data-stimeo--typing-indicator-timeout-value=\"3000\"\n data-stimeo--typing-indicator-throttle-value=\"1000\"\n data-stimeo--typing-indicator-announce-one-text-value=\"<%= announce_one %>\"\n data-stimeo--typing-indicator-announce-many-text-value=\"<%= announce_many %>\">\n <p class=\"typing-demo__hint\"><%= t(\"components.typing_indicator.demo.hint\") %></p>\n <p class=\"typing-demo__you\"><%= t(\"components.typing_indicator.demo.you_are\", name: guest) %></p>\n <label class=\"typing-demo__label\" for=\"typing-demo-input\">\n <%= t(\"components.typing_indicator.demo.input_label\") %>\n </label>\n <textarea id=\"typing-demo-input\" class=\"demo-input typing-demo__input\" rows=\"3\"\n data-stimeo--typing-indicator-target=\"input\"></textarea>\n <p class=\"typing-demo__status\"\n data-stimeo--typing-indicator-target=\"status\"\n data-one=\"<%= t(\"components.typing_indicator.demo.one\") %>\"\n data-many=\"<%= t(\"components.typing_indicator.demo.many\") %>\"></p>\n</div>\n"
447
447
  }
448
448
  }
449
449
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 12,
3
- "packageVersion": "0.10.0",
3
+ "packageVersion": "0.11.0",
4
4
  "controllers": {
5
5
  "stimeo--accordion": {
6
6
  "targets": [
@@ -3369,7 +3369,9 @@
3369
3369
  ],
3370
3370
  "valueConstraints": [],
3371
3371
  "valueRelations": [],
3372
- "actions": [],
3372
+ "actions": [
3373
+ "reset"
3374
+ ],
3373
3375
  "events": [
3374
3376
  "start",
3375
3377
  "move",
@@ -3475,8 +3477,7 @@
3475
3477
  "stimeo--preview-guard": {
3476
3478
  "targets": [],
3477
3479
  "values": [
3478
- "placeholder",
3479
- "mode"
3480
+ "placeholder"
3480
3481
  ],
3481
3482
  "valueConstraints": [],
3482
3483
  "valueRelations": [],
@@ -5647,7 +5648,9 @@
5647
5648
  "params",
5648
5649
  "name",
5649
5650
  "timeout",
5650
- "throttle"
5651
+ "throttle",
5652
+ "announceOneText",
5653
+ "announceManyText"
5651
5654
  ],
5652
5655
  "valueConstraints": [],
5653
5656
  "valueRelations": [],
@@ -5659,30 +5662,7 @@
5659
5662
  "conditionalTargets": [],
5660
5663
  "requiredActions": [],
5661
5664
  "actionCompletion": [],
5662
- "a11y": [
5663
- {
5664
- "target": "status",
5665
- "attrs": [
5666
- "role"
5667
- ],
5668
- "values": [
5669
- "status",
5670
- "alert"
5671
- ],
5672
- "or": [
5673
- {
5674
- "attrs": [
5675
- "aria-live"
5676
- ],
5677
- "values": [
5678
- "polite",
5679
- "assertive"
5680
- ]
5681
- }
5682
- ],
5683
- "suggestion": "Add role=\"status\" (or aria-live=\"polite\") to the status target."
5684
- }
5685
- ],
5665
+ "a11y": [],
5686
5666
  "keyboard": [],
5687
5667
  "hosts": [],
5688
5668
  "managedAria": [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stimeo-ui",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Headless Stimulus UI framework for Ruby on Rails — behavior-only, accessible components driven by HTML attributes.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -84,7 +84,7 @@
84
84
  }
85
85
  },
86
86
  "devDependencies": {
87
- "@biomejs/biome": "2.5.10",
87
+ "@biomejs/biome": "2.5.12",
88
88
  "@floating-ui/dom": "1.8.0",
89
89
  "@rails/actioncable": "8.1.301",
90
90
  "@types/rails__actioncable": "8.0.3",
@@ -94,7 +94,7 @@
94
94
  "@types/node": "24.13.3",
95
95
  "@vitest/coverage-istanbul": "4.1.11",
96
96
  "axe-core": "4.13.0",
97
- "happy-dom": "20.11.15",
97
+ "happy-dom": "20.14.0",
98
98
  "tsup": "8.5.1",
99
99
  "typescript": "6.0.3",
100
100
  "vitest": "4.1.11",