vident 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95a2b00a3176fdc3fbd06569b20665b3e1d1bc8032758b0945d2dc58990d2fa5
4
- data.tar.gz: e946108732b2abd5af47e5437b13e72983838cad032fb6b5c4c460504dc4cf8c
3
+ metadata.gz: ea398d33c180c2198ac689bd70d6f830dc625f9e70fd17bd94cb1acbaa7ec690
4
+ data.tar.gz: 86b1e7379929fbbe3e5b83b9356debfa18490a9cca60599a1a7ecbd9537d97f7
5
5
  SHA512:
6
- metadata.gz: 3fd4da39749c72675965bf507287db253b305a2203c29a323a6342fa593709c06480ce1a3671e6044b562503853b78c56ca9a698e5962217a4a1becf23a29722
7
- data.tar.gz: 11e8f9e658bb2ff4459719a205ae13bcecb7f2c65b1e4d89edb718879d5a54fe947922c0328cf5c15b19f066d46695250a935599fa37fcfd8de0fbfb9e2975af
6
+ metadata.gz: 3e36f069043b62f9d300993e7be4d2cc8666aac6f782ee4ba04fd5efeaffe9ebd28ace5dbfd1022f90f515b253b9778d1123e516606fc20255b0d1bcb5a7bfe5
7
+ data.tar.gz: abf930b3b049e617544a8fe274b0c7deac1ad4f8226642d88fe120246fa0935b90cbcd3206480604290e2f2b9ff540dbf234ab72df8fb4051d8b6838cbecbc11
data/CHANGELOG.md CHANGED
@@ -14,6 +14,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
14
14
 
15
15
  ### Fixed
16
16
 
17
+
18
+ ## [0.11.0] - 2024-02-21
19
+
20
+ ### Added
21
+
22
+ - `outlet_host` DSL method to support components hooking themselves into a host component's outlets
23
+
24
+
25
+
26
+ ## [0.10.1] - 2024-02-21
27
+
28
+ ### Added
29
+
30
+ - `outlets` option now accepts either a string stimulus controller identifier, a component instance, or a tuple of
31
+ identifier and CSS selector for the outlet.
32
+
33
+
17
34
  ## [0.10.0] - 2024-02-21
18
35
 
19
36
  ### Added
data/lib/vident/base.rb CHANGED
@@ -80,6 +80,11 @@ module Vident
80
80
  @id.presence || random_id
81
81
  end
82
82
 
83
+ # If connecting an outlet to this specific component instance, use this ID
84
+ def outlet_id
85
+ @outlet_id ||= [stimulus_identifier, "##{id}"]
86
+ end
87
+
83
88
  # Methods to use in component views
84
89
  # ---------------------------------
85
90
 
@@ -146,6 +151,7 @@ module Vident
146
151
  actions: attribute(:actions) + Array.wrap(options[:actions]),
147
152
  targets: attribute(:targets) + Array.wrap(options[:targets]),
148
153
  outlets: attribute(:outlets) + Array.wrap(options[:outlets]),
154
+ outlet_host: attribute(:outlet_host),
149
155
  named_classes: merge_stimulus_option(options, :named_classes),
150
156
  data_maps: prepare_stimulus_option(options, :data_maps)
151
157
  }
@@ -185,7 +191,7 @@ module Vident
185
191
  end
186
192
 
187
193
  def random_id
188
- @random_id ||= "#{self.class.component_name}-#{StableId.next_id_in_sequence}"
194
+ @random_id ||= "#{component_class_name}-#{StableId.next_id_in_sequence}"
189
195
  end
190
196
 
191
197
  CLASSNAME_SEPARATOR = " "
@@ -17,6 +17,7 @@ module Vident
17
17
  attribute :actions, default: [], delegates: false
18
18
  attribute :targets, default: [], delegates: false
19
19
  attribute :outlets, default: [], delegates: false
20
+ attribute :outlet_host, delegates: false
20
21
  attribute :data_maps, default: [], delegates: false
21
22
  attribute :named_classes, delegates: false
22
23
  end
@@ -7,6 +7,7 @@ module Vident
7
7
  actions: nil,
8
8
  targets: nil,
9
9
  outlets: nil,
10
+ outlet_host: nil,
10
11
  named_classes: nil, # https://stimulus.hotwired.dev/reference/css-classes
11
12
  data_maps: nil,
12
13
  element_tag: nil,
@@ -23,6 +24,13 @@ module Vident
23
24
  @named_classes = named_classes
24
25
  @data_map_kvs = {}
25
26
  @data_maps = data_maps
27
+
28
+ outlet_host.connect_outlet(self) if outlet_host.respond_to?(:connect_outlet)
29
+ end
30
+
31
+ def connect_outlet(outlet)
32
+ @outlets ||= []
33
+ @outlets << outlet
26
34
  end
27
35
 
28
36
  # The view component's helpers for setting stimulus data-* attributes on this component.
@@ -61,6 +69,15 @@ module Vident
61
69
  build_target_data_attributes([target(name)])
62
70
  end
63
71
 
72
+ def outlet(css_selector: nil)
73
+ controller = implied_controller_name
74
+ if css_selector.nil?
75
+ [controller, "[data-controller~=#{controller}]"]
76
+ else
77
+ [controller, css_selector]
78
+ end
79
+ end
80
+
64
81
  # Getter for a named classes list so can be used in view to set initial state on SSR
65
82
  # Returns a String of classes that can be used in a `class` attribute.
66
83
  def named_classes(*names)
@@ -133,7 +150,21 @@ module Vident
133
150
 
134
151
  def outlet_list
135
152
  return {} unless @outlets&.size&.positive?
136
- @outlets.each_with_object({}) { |o, obj| obj["#{implied_controller_name}-#{o.stimulus_identifier}-outlet"] = "[data-controller~=#{o.stimulus_identifier}]" }
153
+
154
+ @outlets.each_with_object({}) do |outlet_config, obj|
155
+ identifier, css_selector = if outlet_config.is_a?(String)
156
+ [outlet_config, "[data-controller~=#{outlet_config}]"]
157
+ elsif outlet_config.is_a?(Array)
158
+ outlet_config[..1]
159
+ elsif outlet_config.respond_to?(:stimulus_identifier) # Is a Component
160
+ [outlet_config.stimulus_identifier, "[data-controller~=#{outlet_config.stimulus_identifier}]"]
161
+ elsif outlet_config.send(:implied_controller_name) # Is a RootComponent ?
162
+ [outlet_config.send(:implied_controller_name), "[data-controller~=#{outlet_config.send(:implied_controller_name)}]"]
163
+ else
164
+ raise ArgumentError, "Invalid outlet config: #{outlet_config}"
165
+ end
166
+ obj[:"#{implied_controller_name}-#{identifier}-outlet"] = css_selector
167
+ end
137
168
  end
138
169
 
139
170
  # Actions can be specified as a symbol, in which case they imply an action on the primary
@@ -189,7 +220,7 @@ module Vident
189
220
  end
190
221
 
191
222
  def parse_attributes(attrs, controller = nil)
192
- attrs.transform_keys { |k| "#{controller || implied_controller_name}-#{k}" }
223
+ attrs.transform_keys { |k| :"#{controller || implied_controller_name}-#{k}" }
193
224
  end
194
225
 
195
226
  def data_map_attributes
@@ -219,7 +250,7 @@ module Vident
219
250
 
220
251
  def build_named_classes_data_attributes(named_classes)
221
252
  parse_named_classes_hash(named_classes)
222
- .map { |c| ["#{c[:controller]}-#{c[:name]}-class", c[:classes]] }
253
+ .map { |c| [:"#{c[:controller]}-#{c[:name]}-class", c[:classes]] }
223
254
  .to_h
224
255
  end
225
256
 
@@ -1,23 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "random/formatter"
4
+
3
5
  module Vident
4
6
  class StableId
5
7
  class << self
6
8
  def set_current_sequence_generator
7
9
  ::Thread.current[:vident_number_sequence_generator] = id_sequence_generator
8
10
  end
11
+ alias_method :new_current_sequence_generator, :set_current_sequence_generator
12
+
13
+ def clear_current_sequence_generator
14
+ ::Thread.current[:vident_number_sequence_generator] = nil
15
+ end
9
16
 
10
17
  def next_id_in_sequence
11
18
  generator = ::Thread.current[:vident_number_sequence_generator]
12
- return "?" unless generator
19
+ # When no generator exists, use a random value. This means we loose the stability of the ID sequence but
20
+ # at least generate unique IDs for the current render.
21
+ return Random.hex(16) unless generator
13
22
  generator.next.join("-")
14
23
  end
15
24
 
16
25
  private
17
26
 
18
27
  def id_sequence_generator
19
- number_generator = Random.new(296_865_628_524)
20
- Enumerator.produce { number_generator.rand(10_000_000) }.with_index
28
+ number_generator = Random.new(42)
29
+ Enumerator.produce { number_generator.hex(16) }.with_index
21
30
  end
22
31
  end
23
32
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Vident
4
- VERSION = "0.10.0"
4
+ VERSION = "0.11.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vident
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Ierodiaconou