vident 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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