atomic_view 0.1.17 → 0.1.18

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60e24ea14905c39463895bf65986134967d2d43ca813e0bf2694ac2624675bb7
4
- data.tar.gz: 4776e9b26a08dcc0ef789bc94e1a1ee7067226bce0a02674516b1bfb9f3e8a73
3
+ metadata.gz: bf51382f0171a3bef2e79ae3229c2de7838e4b69d01fa8ea7ec8cc3ba0d0cde6
4
+ data.tar.gz: 0a990c04df1c8cfc688b66c0c4d2805c54e5af984ca4e81942f1225952c15841
5
5
  SHA512:
6
- metadata.gz: a8c0c0b283c93b31c668e5c5354940031caf143e017486cb4634b4d7dc458dfec76cd3721ecf1ba8dd389f3dbad7dde6f8c557acd5f879b5a254bfc130f8bf06
7
- data.tar.gz: dfefa8a1cda45ae904771d27c02cb9d106323cdd5a9db8aab3876e8d4fd684d070f473fe39a27a2aa9c9238cd663298cf46af2bbe47d23b23b41c028e1e78331
6
+ metadata.gz: d5f777b44351f97e414c6f157389fd3fc00e360e08dbb40dff71e3f4251d60341e4ed0c6ad5479d38a207bc861261572ba0e53460239393ce707b238e5f762a2
7
+ data.tar.gz: 791368e6d9ee177cd2ee840697158a876062af1e44881ae505606c51c0b09286b04e627c980c5b7ef047ed9f76af7226c6b5636cc86c7c41a5358af08a608b23
@@ -0,0 +1,32 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // A key (or chord) bound elsewhere via Stimulus's keyboard event filters,
4
+ // e.g. `data-action="keydown.n@window->hotkey#click"`, activates this
5
+ // element instead of every shortcut needing its own handler. Ignored while
6
+ // the user is typing (an input/textarea/Trix editor has focus) or when the
7
+ // element itself isn't interactable right now (hidden, disabled via
8
+ // pointer-events: none, ...).
9
+ export default class extends Controller {
10
+ click(event) {
11
+ if (this.isClickable && !this.shouldIgnore(event)) {
12
+ event.preventDefault()
13
+ this.element.click()
14
+ }
15
+ }
16
+
17
+ focus(event) {
18
+ if (this.isClickable && !this.shouldIgnore(event)) {
19
+ event.preventDefault()
20
+ this.element.focus()
21
+ }
22
+ }
23
+
24
+ shouldIgnore(event) {
25
+ const target = event.target
26
+ return event.defaultPrevented || !!target?.closest("input, textarea, trix-editor, [contenteditable]")
27
+ }
28
+
29
+ get isClickable() {
30
+ return getComputedStyle(this.element).pointerEvents !== "none"
31
+ }
32
+ }
@@ -9,14 +9,27 @@ module AtomicView
9
9
  # the same ButtonVariants concern, so a navigational action (e.g. "New
10
10
  # record") can sit next to real buttons without looking out of place.
11
11
  #
12
- # `keybinds:`, when given (a single key, or an array for a chord --
13
- # same convention as `CommandPaletteComponent::RowComponent#hint`),
14
- # renders a KbdComponent per key after the content, as a visual hint.
15
- # Wiring the actual keydown-to-click behavior is left to the host app
16
- # (e.g. a Stimulus controller on the anchor).
12
+ # `keybinds:`, when given (a single key, or an array for a simultaneous
13
+ # chord, e.g. `["⌘", "K"]` -- same `Array(...)`-of-keys convention as
14
+ # `CommandPaletteComponent::RowComponent#hint`), renders a KbdComponent
15
+ # per key after the content as a visual hint, and wires the anchor to
16
+ # `atomic-view--hotkey` (see
17
+ # `app/assets/javascripts/atomic_view/controllers/hotkey_controller.js`)
18
+ # so pressing the combo anywhere on the page actually clicks it.
19
+ # Modifier symbols/names (⌘/cmd/command, ⇧, ⌃/control, ⌥/option) are
20
+ # normalized to Stimulus's own modifier names (meta/shift/ctrl/alt) for
21
+ # the underlying `keydown.<filter>@window->atomic-view--hotkey#click`
22
+ # action; any other key is lowercased as-is (e.g. "N" -> "n").
17
23
  class LinkComponent < AtomicView::Component
18
24
  include AtomicView::Components::Concerns::ButtonVariants
19
25
 
26
+ MODIFIER_ALIASES = {
27
+ "⌘" => "meta", "cmd" => "meta", "command" => "meta",
28
+ "⇧" => "shift",
29
+ "⌃" => "ctrl", "control" => "ctrl",
30
+ "⌥" => "alt", "option" => "alt"
31
+ }.freeze
32
+
20
33
  attr_reader :href, :variant, :keybinds
21
34
 
22
35
  def initialize(href, variant: :primary, keybinds: nil, **options)
@@ -28,12 +41,27 @@ module AtomicView
28
41
  end
29
42
 
30
43
  def html_options
31
- @options.except(:class).merge(class: html_class)
44
+ @options.except(:class, :data).merge(class: html_class, data: data_attributes)
32
45
  end
33
46
 
34
47
  def html_class
35
48
  class_names(base_classes, variant_classes, @options[:class])
36
49
  end
50
+
51
+ def data_attributes
52
+ attributes = (@options[:data] || {}).dup
53
+ return attributes unless keybinds.present?
54
+
55
+ attributes[:controller] = [attributes[:controller], "atomic-view--hotkey"].compact.join(" ")
56
+ attributes[:action] = [attributes[:action], "keydown.#{keydown_filter}@window->atomic-view--hotkey#click"].compact.join(" ")
57
+ attributes
58
+ end
59
+
60
+ private
61
+
62
+ def keydown_filter
63
+ keybinds.map { |key| MODIFIER_ALIASES[key.to_s.downcase] || key.to_s.downcase }.join("+")
64
+ end
37
65
  end
38
66
  end
39
67
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AtomicView
4
- VERSION = "0.1.17"
4
+ VERSION = "0.1.18"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atomic_view
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.17
4
+ version: 0.1.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Warrington
@@ -143,6 +143,7 @@ files:
143
143
  - app/assets/javascripts/atomic_view/controllers/chip_controller.js
144
144
  - app/assets/javascripts/atomic_view/controllers/command_palette_controller.js
145
145
  - app/assets/javascripts/atomic_view/controllers/dropdown_controller.js
146
+ - app/assets/javascripts/atomic_view/controllers/hotkey_controller.js
146
147
  - app/assets/javascripts/atomic_view/controllers/modal_controller.js
147
148
  - app/assets/javascripts/atomic_view/controllers/theme_toggle_controller.js
148
149
  - app/assets/javascripts/atomic_view/controllers/toast_controller.js