vident 0.13.0 → 1.0.0.alpha1
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 +4 -4
- data/CHANGELOG.md +31 -1
- data/README.md +522 -681
- data/lib/vident/caching.rb +3 -3
- data/lib/vident/class_list_builder.rb +101 -0
- data/lib/vident/component.rb +76 -22
- data/lib/vident/component_attribute_resolver.rb +77 -0
- data/lib/vident/component_class_lists.rb +28 -0
- data/lib/vident/stimulus_action.rb +98 -0
- data/lib/vident/stimulus_action_collection.rb +11 -0
- data/lib/vident/stimulus_attribute_base.rb +63 -0
- data/lib/vident/stimulus_attributes.rb +257 -0
- data/lib/vident/stimulus_builder.rb +116 -0
- data/lib/vident/stimulus_class.rb +65 -0
- data/lib/vident/stimulus_class_collection.rb +15 -0
- data/lib/vident/stimulus_collection_base.rb +59 -0
- data/lib/vident/stimulus_component.rb +74 -0
- data/lib/vident/stimulus_controller.rb +44 -0
- data/lib/vident/stimulus_controller_collection.rb +14 -0
- data/lib/vident/stimulus_data_attribute_builder.rb +91 -0
- data/lib/vident/stimulus_dsl.rb +74 -0
- data/lib/vident/stimulus_outlet.rb +97 -0
- data/lib/vident/stimulus_outlet_collection.rb +15 -0
- data/lib/vident/stimulus_target.rb +57 -0
- data/lib/vident/stimulus_target_collection.rb +22 -0
- data/lib/vident/stimulus_value.rb +69 -0
- data/lib/vident/stimulus_value_collection.rb +15 -0
- data/lib/vident/tag_helper.rb +64 -0
- data/lib/vident/tailwind.rb +23 -0
- data/lib/vident/version.rb +1 -1
- data/lib/vident.rb +44 -3
- metadata +47 -6
- data/lib/vident/attributes/not_typed.rb +0 -81
- data/lib/vident/base.rb +0 -247
- data/lib/vident/root_component.rb +0 -309
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
# Builds a hash of Stimulus data attributes from collections of stimulus objects
|
5
|
+
# Handles merging multiple actions, targets, outlets, values, and classes
|
6
|
+
# into the final data-* attributes needed for HTML elements
|
7
|
+
class StimulusDataAttributeBuilder
|
8
|
+
def initialize(controllers: [], actions: [], targets: [], outlets: [], values: [], classes: [])
|
9
|
+
@controllers = Array(controllers)
|
10
|
+
@actions = Array(actions)
|
11
|
+
@targets = Array(targets)
|
12
|
+
@outlets = Array(outlets)
|
13
|
+
@values = Array(values)
|
14
|
+
@classes = Array(classes)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Build the final data attributes hash
|
18
|
+
def build
|
19
|
+
{
|
20
|
+
**merged_controllers,
|
21
|
+
**merged_actions,
|
22
|
+
**merged_targets,
|
23
|
+
**merged_outlets,
|
24
|
+
**merged_values,
|
25
|
+
**merged_classes
|
26
|
+
}.transform_keys(&:to_s).compact
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def merged_controllers
|
32
|
+
return {} if @controllers.empty?
|
33
|
+
|
34
|
+
if @controllers.first.is_a?(StimulusControllerCollection)
|
35
|
+
StimulusControllerCollection.merge(*@controllers).to_h
|
36
|
+
else
|
37
|
+
StimulusControllerCollection.new(@controllers).to_h
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def merged_actions
|
42
|
+
return {} if @actions.empty?
|
43
|
+
|
44
|
+
if @actions.first.is_a?(StimulusActionCollection)
|
45
|
+
StimulusActionCollection.merge(*@actions).to_h
|
46
|
+
else
|
47
|
+
StimulusActionCollection.new(@actions).to_h
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def merged_targets
|
52
|
+
return {} if @targets.empty?
|
53
|
+
|
54
|
+
if @targets.first.is_a?(StimulusTargetCollection)
|
55
|
+
StimulusTargetCollection.merge(*@targets).to_h
|
56
|
+
else
|
57
|
+
StimulusTargetCollection.new(@targets).to_h
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def merged_outlets
|
62
|
+
return {} if @outlets.empty?
|
63
|
+
|
64
|
+
if @outlets.first.is_a?(StimulusOutletCollection)
|
65
|
+
StimulusOutletCollection.merge(*@outlets).to_h
|
66
|
+
else
|
67
|
+
StimulusOutletCollection.new(@outlets).to_h
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def merged_values
|
72
|
+
return {} if @values.empty?
|
73
|
+
|
74
|
+
if @values.first.is_a?(StimulusValueCollection)
|
75
|
+
StimulusValueCollection.merge(*@values).to_h
|
76
|
+
else
|
77
|
+
StimulusValueCollection.new(@values).to_h
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def merged_classes
|
82
|
+
return {} if @classes.empty?
|
83
|
+
|
84
|
+
if @classes.first.is_a?(StimulusClassCollection)
|
85
|
+
StimulusClassCollection.merge(*@classes).to_h
|
86
|
+
else
|
87
|
+
StimulusClassCollection.new(@classes).to_h
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
module StimulusDSL
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
class_methods do
|
8
|
+
def stimulus(&block)
|
9
|
+
# Initialize stimulus builder if not already present
|
10
|
+
if @stimulus_builder.nil?
|
11
|
+
@stimulus_builder = StimulusBuilder.new
|
12
|
+
@inheritance_merged = false
|
13
|
+
end
|
14
|
+
|
15
|
+
# Ensure inheritance is applied
|
16
|
+
ensure_inheritance_merged
|
17
|
+
|
18
|
+
# Execute the new block to add/merge new attributes
|
19
|
+
@stimulus_builder.instance_eval(&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def stimulus_dsl_attributes(component_instance)
|
23
|
+
# If no stimulus blocks have been defined on this class, check parent
|
24
|
+
if @stimulus_builder.nil? && superclass.respond_to?(:stimulus_dsl_attributes)
|
25
|
+
return superclass.stimulus_dsl_attributes(component_instance)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Ensure inheritance is applied at access time
|
29
|
+
ensure_inheritance_merged
|
30
|
+
|
31
|
+
@stimulus_builder&.to_attributes(component_instance) || {}
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def ensure_inheritance_merged
|
37
|
+
return if @inheritance_merged || @stimulus_builder.nil?
|
38
|
+
|
39
|
+
if superclass.respond_to?(:stimulus_dsl_builder, true)
|
40
|
+
parent_builder = superclass.send(:stimulus_dsl_builder)
|
41
|
+
if parent_builder
|
42
|
+
@stimulus_builder.merge_with(parent_builder)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
@inheritance_merged = true
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def stimulus_dsl_builder
|
51
|
+
@stimulus_builder
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Instance method to get DSL attributes for this component instance
|
56
|
+
def stimulus_dsl_attributes
|
57
|
+
self.class.stimulus_dsl_attributes(self)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Instance method to resolve prop-mapped values at runtime
|
61
|
+
def resolve_values_from_props(prop_names)
|
62
|
+
return {} if prop_names.empty?
|
63
|
+
|
64
|
+
resolved = {}
|
65
|
+
prop_names.each do |name|
|
66
|
+
# Map from instance variable if it exists
|
67
|
+
if instance_variable_defined?("@#{name}")
|
68
|
+
resolved[name] = instance_variable_get("@#{name}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
resolved
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
class StimulusOutlet < StimulusAttributeBase
|
5
|
+
attr_reader :controller, :outlet_name, :selector
|
6
|
+
|
7
|
+
def initialize(*args, implied_controller:, component_id: nil)
|
8
|
+
@component_id = component_id
|
9
|
+
super(*args, implied_controller: implied_controller)
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
@selector
|
14
|
+
end
|
15
|
+
|
16
|
+
def data_attribute_name
|
17
|
+
"#{@controller}-#{@outlet_name}-outlet"
|
18
|
+
end
|
19
|
+
|
20
|
+
def data_attribute_value
|
21
|
+
@selector
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parse_arguments(*args)
|
27
|
+
case args.size
|
28
|
+
when 1
|
29
|
+
parse_single_argument(args[0])
|
30
|
+
when 2
|
31
|
+
parse_two_arguments(args[0], args[1])
|
32
|
+
when 3
|
33
|
+
parse_three_arguments(args[0], args[1], args[2])
|
34
|
+
else
|
35
|
+
raise ArgumentError, "Invalid number of arguments: #{args.size}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_single_argument(arg)
|
40
|
+
@controller = implied_controller_name
|
41
|
+
if arg.is_a?(Symbol)
|
42
|
+
# Single symbol: outlet name on implied controller with auto-generated selector
|
43
|
+
outlet_identifier = arg.to_s.dasherize
|
44
|
+
@outlet_name = outlet_identifier
|
45
|
+
@selector = build_outlet_selector(outlet_identifier)
|
46
|
+
elsif arg.is_a?(String)
|
47
|
+
# Single string: outlet identifier with auto-generated selector
|
48
|
+
@outlet_name = arg.dasherize
|
49
|
+
@selector = build_outlet_selector(arg)
|
50
|
+
elsif arg.is_a?(Array) && arg.size == 2
|
51
|
+
# Array format: [outlet_identifier, css_selector]
|
52
|
+
@outlet_name = arg[0].to_s.dasherize
|
53
|
+
@selector = arg[1]
|
54
|
+
elsif arg.respond_to?(:stimulus_identifier)
|
55
|
+
# Component with stimulus_identifier
|
56
|
+
identifier = arg.stimulus_identifier
|
57
|
+
@outlet_name = identifier
|
58
|
+
@selector = build_outlet_selector(identifier)
|
59
|
+
elsif arg.respond_to?(:implied_controller_name)
|
60
|
+
# RootComponent with implied_controller_name
|
61
|
+
identifier = arg.implied_controller_name
|
62
|
+
@outlet_name = identifier
|
63
|
+
@selector = build_outlet_selector(identifier)
|
64
|
+
else
|
65
|
+
raise ArgumentError, "Invalid argument type: #{arg.class}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_two_arguments(arg1, arg2)
|
70
|
+
if arg1.is_a?(Symbol) && arg2.is_a?(String)
|
71
|
+
# outlet name on implied controller + custom selector
|
72
|
+
@controller = implied_controller_name
|
73
|
+
@outlet_name = arg1.to_s.dasherize
|
74
|
+
@selector = arg2
|
75
|
+
else
|
76
|
+
raise ArgumentError, "Invalid argument types: #{arg1.class}, #{arg2.class}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse_three_arguments(controller, outlet_name, selector)
|
81
|
+
if controller.is_a?(String) && outlet_name.is_a?(Symbol) && selector.is_a?(String)
|
82
|
+
# controller path + outlet name + selector
|
83
|
+
@controller = stimulize_path(controller)
|
84
|
+
@outlet_name = outlet_name.to_s.dasherize
|
85
|
+
@selector = selector
|
86
|
+
else
|
87
|
+
raise ArgumentError, "Invalid argument types: #{controller.class}, #{outlet_name.class}, #{selector.class}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Build outlet selector following the same pattern as RootComponent
|
92
|
+
def build_outlet_selector(outlet_selector)
|
93
|
+
prefix = @component_id ? "##{@component_id} " : ""
|
94
|
+
"#{prefix}[data-controller~=#{outlet_selector}]"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
class StimulusOutletCollection < StimulusCollectionBase
|
5
|
+
def to_h
|
6
|
+
return {} if items.empty?
|
7
|
+
|
8
|
+
merged = {}
|
9
|
+
items.each do |outlet|
|
10
|
+
merged.merge!(outlet.to_h)
|
11
|
+
end
|
12
|
+
merged
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
class StimulusTarget < StimulusAttributeBase
|
5
|
+
attr_reader :controller, :name
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
@name
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the data attribute name for this target
|
12
|
+
def data_attribute_name
|
13
|
+
"#{@controller}-target"
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the target name value for the data attribute
|
17
|
+
def data_attribute_value
|
18
|
+
@name
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def parse_arguments(*args)
|
24
|
+
case args.size
|
25
|
+
when 1
|
26
|
+
parse_single_argument(args[0])
|
27
|
+
when 2
|
28
|
+
parse_two_arguments(args[0], args[1])
|
29
|
+
else
|
30
|
+
raise ArgumentError, "Invalid number of arguments: #{args.size}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_single_argument(arg)
|
35
|
+
@controller = implied_controller_name
|
36
|
+
if arg.is_a?(Symbol)
|
37
|
+
# 1 symbol arg, name of target on implied controller
|
38
|
+
@name = js_name(arg)
|
39
|
+
elsif arg.is_a?(String)
|
40
|
+
# 1 string arg, assume it's a target name on implied controller
|
41
|
+
@name = arg
|
42
|
+
else
|
43
|
+
raise ArgumentError, "Invalid argument type: #{arg.class}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_two_arguments(part1, part2)
|
48
|
+
if part1.is_a?(String) && part2.is_a?(Symbol)
|
49
|
+
# 1 string arg, 1 symbol = controller + target
|
50
|
+
@controller = stimulize_path(part1)
|
51
|
+
@name = js_name(part2)
|
52
|
+
else
|
53
|
+
raise ArgumentError, "Invalid argument types: #{part1.class}, #{part2.class}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
class StimulusTargetCollection < StimulusCollectionBase
|
5
|
+
def to_h
|
6
|
+
return {} if items.empty?
|
7
|
+
|
8
|
+
merged = {}
|
9
|
+
items.each do |target|
|
10
|
+
target.to_h.each do |key, value|
|
11
|
+
merged[key] = if merged.key?(key)
|
12
|
+
# Merge space-separated values for same target attribute
|
13
|
+
"#{merged[key]} #{value}"
|
14
|
+
else
|
15
|
+
value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
merged
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module Vident
|
6
|
+
class StimulusValue < StimulusAttributeBase
|
7
|
+
attr_reader :controller, :value_name, :value
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
@value.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def data_attribute_name
|
14
|
+
"#{@controller}-#{@value_name}-value"
|
15
|
+
end
|
16
|
+
|
17
|
+
def data_attribute_value
|
18
|
+
@value
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def parse_arguments(*args)
|
24
|
+
case args.size
|
25
|
+
when 2
|
26
|
+
parse_two_arguments(args[0], args[1])
|
27
|
+
when 3
|
28
|
+
parse_three_arguments(args[0], args[1], args[2])
|
29
|
+
else
|
30
|
+
raise ArgumentError, "Invalid number of arguments: #{args.size} (#{args.inspect}). Did you pass an array of hashes?"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_two_arguments(value_name, value)
|
35
|
+
if value_name.is_a?(Symbol)
|
36
|
+
# value name on implied controller + value
|
37
|
+
@controller = implied_controller_name
|
38
|
+
@value_name = value_name.to_s.dasherize
|
39
|
+
@value = serialize_value(value)
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Invalid argument types: #{value_name.class}, #{value.class}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_three_arguments(controller, value_name, value)
|
46
|
+
if controller.is_a?(String) && value_name.is_a?(Symbol)
|
47
|
+
# controller + value name + value
|
48
|
+
@controller = stimulize_path(controller)
|
49
|
+
@value_name = value_name.to_s.dasherize
|
50
|
+
@value = serialize_value(value)
|
51
|
+
else
|
52
|
+
raise ArgumentError, "Invalid argument types: #{controller.class}, #{value_name.class}, #{value.class}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def serialize_value(value)
|
57
|
+
case value
|
58
|
+
when Array, Hash
|
59
|
+
value.to_json
|
60
|
+
when TrueClass, FalseClass
|
61
|
+
value.to_s
|
62
|
+
when Numeric
|
63
|
+
value.to_s
|
64
|
+
else
|
65
|
+
value.to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
module TagHelper
|
5
|
+
# Generate a tag with the given name and options, including stimulus data attributes
|
6
|
+
def tag(
|
7
|
+
tag_name,
|
8
|
+
stimulus_controllers: nil,
|
9
|
+
stimulus_targets: nil,
|
10
|
+
stimulus_actions: nil,
|
11
|
+
stimulus_outlets: nil,
|
12
|
+
stimulus_values: nil,
|
13
|
+
stimulus_classes: nil,
|
14
|
+
stimulus_controller: nil,
|
15
|
+
stimulus_target: nil,
|
16
|
+
stimulus_action: nil,
|
17
|
+
stimulus_outlet: nil,
|
18
|
+
stimulus_value: nil,
|
19
|
+
stimulus_class: nil,
|
20
|
+
**options,
|
21
|
+
&block
|
22
|
+
)
|
23
|
+
# Ensure the plural attributes are actually enumerables
|
24
|
+
tag_attribute_must_be_collection!(stimulus_controllers, "stimulus_controllers")
|
25
|
+
tag_attribute_must_be_collection!(stimulus_targets, "stimulus_targets")
|
26
|
+
tag_attribute_must_be_collection!(stimulus_actions, "stimulus_actions")
|
27
|
+
tag_attribute_must_be_collection!(stimulus_outlets, "stimulus_outlets")
|
28
|
+
tag_attribute_must_be_collection!(stimulus_values, "stimulus_values")
|
29
|
+
tag_attribute_must_be_collection!(stimulus_classes, "stimulus_classes")
|
30
|
+
|
31
|
+
stimulus_controllers_collection = send(:stimulus_controllers, *tag_wrap_single_stimulus_attribute(stimulus_controllers, stimulus_controller))
|
32
|
+
stimulus_targets_collection = send(:stimulus_targets, *tag_wrap_single_stimulus_attribute(stimulus_targets, stimulus_target))
|
33
|
+
stimulus_actions_collection = send(:stimulus_actions, *tag_wrap_single_stimulus_attribute(stimulus_actions, stimulus_action))
|
34
|
+
stimulus_outlets_collection = send(:stimulus_outlets, *tag_wrap_single_stimulus_attribute(stimulus_outlets, stimulus_outlet))
|
35
|
+
stimulus_values_collection = send(:stimulus_values, stimulus_values || stimulus_value)
|
36
|
+
stimulus_classes_collection = send(:stimulus_classes, stimulus_classes || stimulus_class)
|
37
|
+
|
38
|
+
stimulus_data_attributes = StimulusDataAttributeBuilder.new(
|
39
|
+
controllers: stimulus_controllers_collection,
|
40
|
+
actions: stimulus_actions_collection,
|
41
|
+
targets: stimulus_targets_collection,
|
42
|
+
outlets: stimulus_outlets_collection,
|
43
|
+
values: stimulus_values_collection,
|
44
|
+
classes: stimulus_classes_collection
|
45
|
+
).build
|
46
|
+
generate_tag(tag_name, stimulus_data_attributes, options, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def tag_attribute_must_be_collection!(collection, name)
|
52
|
+
return unless collection
|
53
|
+
raise ArgumentError, "'#{name}:' must be an enumerable. Did you mean '#{name.to_s.singularize}:'?" unless collection.is_a?(Enumerable)
|
54
|
+
end
|
55
|
+
|
56
|
+
def tag_wrap_single_stimulus_attribute(plural, singular)
|
57
|
+
plural || (singular ? Array.wrap(singular) : nil)
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_tag(tag_name, stimulus_data_attributes, options, &block)
|
61
|
+
raise NoMethodError, "Not implemented"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Vident
|
4
|
+
# Adds Tailwind CSS class merging functionality to components
|
5
|
+
# This module provides methods to create and manage TailwindMerge::Merger instances
|
6
|
+
module Tailwind
|
7
|
+
# Get or create a thread-safe Tailwind merger instance
|
8
|
+
def tailwind_merger
|
9
|
+
return unless tailwind_merge_available?
|
10
|
+
|
11
|
+
return @tailwind_merger if defined?(@tailwind_merger)
|
12
|
+
|
13
|
+
@tailwind_merger = Thread.current[:vident_tailwind_merger] ||= ::TailwindMerge::Merger.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# Check if TailwindMerge gem is available
|
17
|
+
def tailwind_merge_available?
|
18
|
+
defined?(::TailwindMerge::Merger) && ::TailwindMerge::Merger.respond_to?(:new)
|
19
|
+
rescue NameError
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/vident/version.rb
CHANGED
data/lib/vident.rb
CHANGED
@@ -1,12 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
if ENV["COVERAGE"]
|
4
|
+
require "simplecov"
|
5
|
+
SimpleCov.command_name "Vident"
|
6
|
+
SimpleCov.root File.expand_path("..", __dir__)
|
7
|
+
SimpleCov.start do
|
8
|
+
add_filter "/test/"
|
9
|
+
add_filter "/tmp/"
|
10
|
+
add_filter "/bin/"
|
11
|
+
add_filter "/lib/vident/engine.rb"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
3
15
|
require "active_support"
|
4
16
|
require "active_support/concern"
|
17
|
+
require "literal"
|
18
|
+
|
5
19
|
require "vident/version"
|
6
|
-
require "vident/
|
20
|
+
require "vident/tailwind"
|
21
|
+
|
22
|
+
require "vident/stimulus_attribute_base"
|
23
|
+
require "vident/stimulus_controller"
|
24
|
+
require "vident/stimulus_action"
|
25
|
+
require "vident/stimulus_target"
|
26
|
+
require "vident/stimulus_outlet"
|
27
|
+
require "vident/stimulus_value"
|
28
|
+
require "vident/stimulus_class"
|
29
|
+
|
30
|
+
require "vident/stimulus_collection_base"
|
31
|
+
require "vident/stimulus_controller_collection"
|
32
|
+
require "vident/stimulus_action_collection"
|
33
|
+
require "vident/stimulus_target_collection"
|
34
|
+
require "vident/stimulus_outlet_collection"
|
35
|
+
require "vident/stimulus_value_collection"
|
36
|
+
require "vident/stimulus_class_collection"
|
37
|
+
|
38
|
+
require "vident/stimulus_attributes"
|
39
|
+
require "vident/stimulus_data_attribute_builder"
|
40
|
+
|
41
|
+
require "vident/tag_helper"
|
7
42
|
require "vident/stable_id"
|
8
|
-
require "vident/
|
9
|
-
|
43
|
+
require "vident/class_list_builder"
|
44
|
+
|
45
|
+
require "vident/stimulus_component"
|
46
|
+
require "vident/component_class_lists"
|
47
|
+
require "vident/component_attribute_resolver"
|
48
|
+
require "vident/stimulus_builder"
|
49
|
+
require "vident/stimulus_dsl"
|
50
|
+
|
10
51
|
require "vident/component"
|
11
52
|
|
12
53
|
require "vident/engine" if defined?(Rails)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vident
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Ierodiaconou
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-07-08 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: railties
|
@@ -49,6 +49,26 @@ dependencies:
|
|
49
49
|
- - "<"
|
50
50
|
- !ruby/object:Gem::Version
|
51
51
|
version: '9'
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: literal
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '1.0'
|
59
|
+
- - "<"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- - "<"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '2'
|
52
72
|
description: Vident makes using Stimulus with your `ViewComponent` or `Phlex` view
|
53
73
|
components as easy as writing Ruby. Vident is the base of your design system implementation,
|
54
74
|
which provides helpers for working with Stimulus. For component libraries with ViewComponent
|
@@ -63,13 +83,34 @@ files:
|
|
63
83
|
- LICENSE.txt
|
64
84
|
- README.md
|
65
85
|
- lib/vident.rb
|
66
|
-
- lib/vident/attributes/not_typed.rb
|
67
|
-
- lib/vident/base.rb
|
68
86
|
- lib/vident/caching.rb
|
87
|
+
- lib/vident/class_list_builder.rb
|
69
88
|
- lib/vident/component.rb
|
89
|
+
- lib/vident/component_attribute_resolver.rb
|
90
|
+
- lib/vident/component_class_lists.rb
|
70
91
|
- lib/vident/engine.rb
|
71
|
-
- lib/vident/root_component.rb
|
72
92
|
- lib/vident/stable_id.rb
|
93
|
+
- lib/vident/stimulus_action.rb
|
94
|
+
- lib/vident/stimulus_action_collection.rb
|
95
|
+
- lib/vident/stimulus_attribute_base.rb
|
96
|
+
- lib/vident/stimulus_attributes.rb
|
97
|
+
- lib/vident/stimulus_builder.rb
|
98
|
+
- lib/vident/stimulus_class.rb
|
99
|
+
- lib/vident/stimulus_class_collection.rb
|
100
|
+
- lib/vident/stimulus_collection_base.rb
|
101
|
+
- lib/vident/stimulus_component.rb
|
102
|
+
- lib/vident/stimulus_controller.rb
|
103
|
+
- lib/vident/stimulus_controller_collection.rb
|
104
|
+
- lib/vident/stimulus_data_attribute_builder.rb
|
105
|
+
- lib/vident/stimulus_dsl.rb
|
106
|
+
- lib/vident/stimulus_outlet.rb
|
107
|
+
- lib/vident/stimulus_outlet_collection.rb
|
108
|
+
- lib/vident/stimulus_target.rb
|
109
|
+
- lib/vident/stimulus_target_collection.rb
|
110
|
+
- lib/vident/stimulus_value.rb
|
111
|
+
- lib/vident/stimulus_value_collection.rb
|
112
|
+
- lib/vident/tag_helper.rb
|
113
|
+
- lib/vident/tailwind.rb
|
73
114
|
- lib/vident/version.rb
|
74
115
|
homepage: https://github.com/stevegeek/vident
|
75
116
|
licenses:
|
@@ -85,7 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
85
126
|
requirements:
|
86
127
|
- - ">="
|
87
128
|
- !ruby/object:Gem::Version
|
88
|
-
version: 3.
|
129
|
+
version: 3.2.0
|
89
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
131
|
requirements:
|
91
132
|
- - ">="
|