plutonium 0.54.0 → 0.55.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 +4 -4
- data/.claude/skills/plutonium-behavior/SKILL.md +22 -0
- data/.claude/skills/plutonium-resource/SKILL.md +55 -0
- data/.claude/skills/plutonium-ui/SKILL.md +2 -1
- data/CHANGELOG.md +14 -0
- data/app/assets/plutonium.css +1 -1
- data/app/assets/plutonium.js +18 -0
- data/app/assets/plutonium.js.map +4 -4
- data/app/assets/plutonium.min.js +30 -30
- data/app/assets/plutonium.min.js.map +4 -4
- data/docs/public/images/reference/structured-inputs-removed.png +0 -0
- data/docs/public/images/reference/structured-inputs.png +0 -0
- data/docs/reference/resource/definition.md +110 -0
- data/docs/superpowers/plans/2026-06-02-structured-inputs.md +1061 -0
- data/docs/superpowers/plans/2026-06-02-structured-inputs.md.tasks.json +60 -0
- data/docs/superpowers/specs/2026-06-01-structured-inputs-design.md +191 -0
- data/gemfiles/rails_8.1.gemfile.lock +1 -1
- data/lib/plutonium/definition/base.rb +1 -0
- data/lib/plutonium/definition/structured_inputs.rb +67 -0
- data/lib/plutonium/interaction/README.md +24 -78
- data/lib/plutonium/interaction/base.rb +10 -2
- data/lib/plutonium/resource/controller.rb +6 -1
- data/lib/plutonium/resource/controllers/interactive_actions.rb +10 -6
- data/lib/plutonium/structured_inputs/param_cleaner.rb +36 -0
- data/lib/plutonium/structured_inputs/params_concern.rb +36 -0
- data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +3 -3
- data/lib/plutonium/ui/form/concerns/renders_structured_inputs.rb +178 -0
- data/lib/plutonium/ui/form/concerns/repeater_field_styles.rb +24 -0
- data/lib/plutonium/ui/form/resource.rb +4 -1
- data/lib/plutonium/ui/modal/slideover.rb +9 -3
- data/lib/plutonium/version.rb +1 -1
- data/package.json +1 -1
- data/src/css/components.css +10 -5
- data/src/js/controllers/register_controllers.js +2 -0
- data/src/js/controllers/structured_input_row_controller.js +26 -0
- metadata +14 -5
- data/docs/superpowers/specs/2026-06-01-interaction-repeater-inputs-design.md +0 -178
- data/lib/plutonium/interaction/nested_attributes.rb +0 -93
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Plutonium
|
|
4
|
-
module Interaction
|
|
5
|
-
module NestedAttributes
|
|
6
|
-
extend ActiveSupport::Concern
|
|
7
|
-
|
|
8
|
-
class_methods do
|
|
9
|
-
# Dynamically defines writer and reader methods for handling nested
|
|
10
|
-
# attributes in form objects or interaction classes, mimicking the
|
|
11
|
-
# behavior of ActiveRecord's `accepts_nested_attributes_for`.
|
|
12
|
-
#
|
|
13
|
-
# This method allows you to pass in nested data (e.g. from a form) and
|
|
14
|
-
# automatically build or destroy associated records based on that input.
|
|
15
|
-
#
|
|
16
|
-
# === Example 1: Basic usage with default naming
|
|
17
|
-
# # If `Contact` is the associated model inferred from the
|
|
18
|
-
# `:contacts` association:
|
|
19
|
-
#
|
|
20
|
-
# `accepts_nested_attributes_for :contacts`
|
|
21
|
-
#
|
|
22
|
-
# === Example 2: When association name and model name differ
|
|
23
|
-
# Suppose the `User` model has a `has_many :contacts` association
|
|
24
|
-
# pointing to a `UserContactInfo` model. You need to specify the
|
|
25
|
-
# model name.
|
|
26
|
-
#
|
|
27
|
-
# `accepts_nested_attributes_for :contacts, class_name: "UserAddress"`
|
|
28
|
-
#
|
|
29
|
-
# This macro defines:
|
|
30
|
-
# - `contacts_attributes=` — used to assign nested attributes,
|
|
31
|
-
# including support for `_destroy`
|
|
32
|
-
# - `contacts_attributes` — returns the current attributes of
|
|
33
|
-
# associated records
|
|
34
|
-
#
|
|
35
|
-
# @param association [Symbol] The association name. (e.g., `:contacts`).
|
|
36
|
-
# @param class_name [String, nil] Required if association reflection
|
|
37
|
-
# is needed to determine the associated model class (e.g. when the
|
|
38
|
-
# association name doesn't match the class name).
|
|
39
|
-
# @param reject_if [Proc, Symbol, nil] Used to skip building association
|
|
40
|
-
# records when the condition returns true.
|
|
41
|
-
def accepts_nested_attributes_for(
|
|
42
|
-
association,
|
|
43
|
-
class_name: nil,
|
|
44
|
-
reject_if: nil
|
|
45
|
-
)
|
|
46
|
-
destroy_values = [1, "1", "true", true]
|
|
47
|
-
|
|
48
|
-
should_destroy = ->(value) { destroy_values.include?(value) }
|
|
49
|
-
|
|
50
|
-
should_reject =
|
|
51
|
-
lambda do |attrs|
|
|
52
|
-
case reject_if
|
|
53
|
-
when Symbol
|
|
54
|
-
send(reject_if, attrs)
|
|
55
|
-
when Proc
|
|
56
|
-
reject_if.call(attrs)
|
|
57
|
-
else
|
|
58
|
-
false
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
assoc_class =
|
|
63
|
-
class_name&.constantize || association.to_s.classify.constantize
|
|
64
|
-
|
|
65
|
-
define_method(:"#{association}_attributes=") do |attributes|
|
|
66
|
-
result =
|
|
67
|
-
case attributes
|
|
68
|
-
when Hash
|
|
69
|
-
attrs = attributes.except(:_destroy)
|
|
70
|
-
unless should_destroy.call(attributes[:_destroy]) ||
|
|
71
|
-
should_reject.call(attrs)
|
|
72
|
-
assoc_class.new(attrs)
|
|
73
|
-
end
|
|
74
|
-
when Array
|
|
75
|
-
attributes.filter_map do |attrs|
|
|
76
|
-
unless should_destroy.call(attrs[:_destroy]) ||
|
|
77
|
-
should_reject.call(attrs)
|
|
78
|
-
assoc_class.new(attrs.except(:_destroy))
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
send(:"#{association}=", result)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
define_method(:"#{association}_attributes") do
|
|
87
|
-
Array(send(association)).map(&:attributes)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|