atomic_view 0.1.16 → 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: 815b41e5c66fe63cac96239f8d90cfdfa137da236e27f0d8577bdee068e35ce7
4
- data.tar.gz: f4e735119fefc770222c595c49dd4031b43a64b2dcec004417bae2a610b9524e
3
+ metadata.gz: bf51382f0171a3bef2e79ae3229c2de7838e4b69d01fa8ea7ec8cc3ba0d0cde6
4
+ data.tar.gz: 0a990c04df1c8cfc688b66c0c4d2805c54e5af984ca4e81942f1225952c15841
5
5
  SHA512:
6
- metadata.gz: d013eb53df0f79b51f6be0d0fcb167f52f2621a5dde41bad2385df742d426e44d68f7422bc4b697ff43db623797fe350c4cdf3f8549872492804c488c9cdcf3e
7
- data.tar.gz: 0efc941867d3a932de3de2f98ef8318260a5c9df7b100406e5e4074dff38da2fe6cdbb55360a82b89b89ea350c205e52761bffd8f6483f280970a11c045491be
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
+ }
@@ -0,0 +1,10 @@
1
+ <%= link_to(href, html_options) do %>
2
+ <%= content %>
3
+ <% if keybinds.present? %>
4
+ <span class="inline-flex items-center gap-0.5">
5
+ <% keybinds.each do |key| %>
6
+ <%= render(AtomicView::Components::KbdComponent.new) { key } %>
7
+ <% end %>
8
+ </span>
9
+ <% end %>
10
+ <% end %>
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AtomicView
4
+ module Components
5
+ # Link
6
+ #
7
+ # A button-styled anchor tag -- shares ButtonComponent's variants
8
+ # (`primary`, `secondary`, `destructive`, `muted`, `link`, `outline`) via
9
+ # the same ButtonVariants concern, so a navigational action (e.g. "New
10
+ # record") can sit next to real buttons without looking out of place.
11
+ #
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").
23
+ class LinkComponent < AtomicView::Component
24
+ include AtomicView::Components::Concerns::ButtonVariants
25
+
26
+ MODIFIER_ALIASES = {
27
+ "⌘" => "meta", "cmd" => "meta", "command" => "meta",
28
+ "⇧" => "shift",
29
+ "⌃" => "ctrl", "control" => "ctrl",
30
+ "⌥" => "alt", "option" => "alt"
31
+ }.freeze
32
+
33
+ attr_reader :href, :variant, :keybinds
34
+
35
+ def initialize(href, variant: :primary, keybinds: nil, **options)
36
+ super()
37
+ @href = href
38
+ @variant = variant
39
+ @keybinds = Array(keybinds)
40
+ @options = options
41
+ end
42
+
43
+ def html_options
44
+ @options.except(:class, :data).merge(class: html_class, data: data_attributes)
45
+ end
46
+
47
+ def html_class
48
+ class_names(base_classes, variant_classes, @options[:class])
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
65
+ end
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AtomicView
4
- VERSION = "0.1.16"
4
+ VERSION = "0.1.18"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atomic_view
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.16
4
+ version: 0.1.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Warrington
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-08 00:00:00.000000000 Z
11
+ date: 2026-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -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
@@ -202,6 +203,8 @@ files:
202
203
  - lib/atomic_view/components/grouped_collection_select_component.rb
203
204
  - lib/atomic_view/components/kbd_component.rb
204
205
  - lib/atomic_view/components/label_component.rb
206
+ - lib/atomic_view/components/link_component.html.erb
207
+ - lib/atomic_view/components/link_component.rb
205
208
  - lib/atomic_view/components/modal_component.html.erb
206
209
  - lib/atomic_view/components/modal_component.rb
207
210
  - lib/atomic_view/components/month_field_component.rb