composable-view 0.0.13 → 0.0.14
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 +4 -0
- data/README.md +96 -22
- data/lib/composable/view/gem_version.rb +1 -1
- data/lib/composable/view/version.rb +2 -0
- metadata +7 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 386177726dbe2cd300932e8051cd8a80c911aec78f7ba728e14a0129eb9263c5
|
|
4
|
+
data.tar.gz: 85255d4a6ca25d891a67a05c4e61ef5575382e1705b5038a619130826d71f2c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8f11cb4d150421aac5c4f4096dcd2f5dab66b772472934b8b5d81c93973e6b1711e75a7b987947f046298a7056e6654295513d2f3fa75b9fd06dee623b7e62b
|
|
7
|
+
data.tar.gz: 309255d139074ee6a6fa48e21e423586b6bc45e30bd519aa3b8eb0698664ea0b752619ff1afa84a847a3895cca711c11973d0033cf7ef180a5e6b01e4aa404d1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
- Fix gem-version loading and component test discovery.
|
|
4
|
+
- Document validated inputs, safe rendering and inherited ViewComponent capabilities.
|
|
5
|
+
- Add complete coverage and rendering regression tests.
|
|
6
|
+
|
|
3
7
|
## [0.0.1] - 2022-01-31
|
|
4
8
|
|
|
5
9
|
- Initial release
|
data/README.md
CHANGED
|
@@ -1,43 +1,117 @@
|
|
|
1
|
-
#
|
|
1
|
+
# composable-view
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ViewComponent components with declared, typed inputs and validation at
|
|
4
|
+
construction. Requires Ruby 3.2+, ActiveModel/ActiveSupport 7.2+ and ViewComponent
|
|
5
|
+
3.21+. Install `gem "composable-view"`; require `composable/view` in Rails.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
```ruby
|
|
8
|
+
require "composable/view"
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
class BadgeComponent < Composable::View::Component
|
|
11
|
+
attribute :label, type: :string
|
|
12
|
+
validates :label, presence: true
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
def call
|
|
15
|
+
content_tag(:span, label, **rest)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
gem 'composable-view'
|
|
19
|
+
# render BadgeComponent.new(label: "Ready", class: "badge")
|
|
13
20
|
```
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
Inputs use the [core attribute DSL](../composable-core/README.md), including types,
|
|
23
|
+
independent defaults, predicates and inheritance. Unknown keys remain in `rest`,
|
|
24
|
+
allowing application components to choose which HTML attributes to forward.
|
|
25
|
+
Construction calls `validate!`: invalid inputs raise `ActiveModel::ValidationError`
|
|
26
|
+
before rendering.
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
The base inherits ViewComponent slots, rendering and template behavior; declare
|
|
29
|
+
slots using ViewComponent's normal API. It does not provide an application form
|
|
30
|
+
builder or application-specific layout helpers.
|
|
18
31
|
|
|
19
|
-
|
|
32
|
+
Use Rails HTML helpers for escaping. Do not apply `html_safe` to user input or
|
|
33
|
+
blindly forward untrusted HTML attributes; allow-list them at the application
|
|
34
|
+
boundary. Input validation is not output sanitization or authorization.
|
|
20
35
|
|
|
21
|
-
$ gem install composable-view
|
|
22
36
|
|
|
23
|
-
##
|
|
37
|
+
## Declare inputs and forward selected HTML attributes
|
|
24
38
|
|
|
25
|
-
|
|
39
|
+
Use `rest` deliberately rather than forwarding every caller-supplied key. This
|
|
40
|
+
component accepts a typed option and allow-lists the remaining HTML attributes:
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
class StatusBadgeComponent < Composable::View::Component
|
|
44
|
+
attribute :label, type: :string
|
|
45
|
+
attribute :compact, type: :boolean, default: false
|
|
46
|
+
validates :label, presence: true
|
|
47
|
+
|
|
48
|
+
def call
|
|
49
|
+
html_attributes = rest.symbolize_keys.slice(:id, :class, :title)
|
|
50
|
+
classes = ["status-badge", ("status-badge--compact" if compact?), html_attributes[:class]]
|
|
51
|
+
html_attributes[:class] = classes.compact.join(" ")
|
|
52
|
+
content_tag(:span, label, **html_attributes)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
```
|
|
26
56
|
|
|
27
|
-
|
|
57
|
+
Render it in a Rails template:
|
|
28
58
|
|
|
29
|
-
|
|
59
|
+
```erb
|
|
60
|
+
<%= render StatusBadgeComponent.new(
|
|
61
|
+
label: "Ready", compact: true, class: "text-success", title: "Current status"
|
|
62
|
+
) %>
|
|
63
|
+
```
|
|
30
64
|
|
|
31
|
-
|
|
65
|
+
`compact` is a declared input and is not forwarded to the HTML helper. The label
|
|
66
|
+
is escaped by `content_tag`. The allow-list does not include event-handler
|
|
67
|
+
attributes such as `onclick`.
|
|
32
68
|
|
|
33
|
-
##
|
|
69
|
+
## Handle invalid component input
|
|
34
70
|
|
|
35
|
-
|
|
71
|
+
```ruby
|
|
72
|
+
begin
|
|
73
|
+
StatusBadgeComponent.new(label: "")
|
|
74
|
+
rescue ActiveModel::ValidationError => error
|
|
75
|
+
error.model.errors.full_messages # => ["Label can't be blank"]
|
|
76
|
+
end
|
|
77
|
+
```
|
|
36
78
|
|
|
37
|
-
|
|
79
|
+
Validation happens during construction, so there is no service-style `.call`,
|
|
80
|
+
`success?` or `result` API for components. The component's instance `call` produces
|
|
81
|
+
rendered content through ViewComponent.
|
|
38
82
|
|
|
39
|
-
|
|
83
|
+
## Use an ERB template and a slot
|
|
40
84
|
|
|
41
|
-
|
|
85
|
+
For a template-backed component, omit `call`. Place the template next to the
|
|
86
|
+
component using ViewComponent's normal naming convention:
|
|
87
|
+
|
|
88
|
+
```ruby
|
|
89
|
+
# app/components/panel_component.rb
|
|
90
|
+
class PanelComponent < Composable::View::Component
|
|
91
|
+
attribute :title, type: :string
|
|
92
|
+
validates :title, presence: true
|
|
93
|
+
renders_one :footer
|
|
94
|
+
end
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```erb
|
|
98
|
+
<%# app/components/panel_component.html.erb %>
|
|
99
|
+
<section>
|
|
100
|
+
<h2><%= title %></h2>
|
|
101
|
+
<div><%= content %></div>
|
|
102
|
+
<% if footer? %>
|
|
103
|
+
<footer><%= footer %></footer>
|
|
104
|
+
<% end %>
|
|
105
|
+
</section>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```erb
|
|
109
|
+
<%= render PanelComponent.new(title: "Example panel") do |panel| %>
|
|
110
|
+
<% panel.with_footer do %>
|
|
111
|
+
Updated recently
|
|
112
|
+
<% end %>
|
|
113
|
+
<p>Panel content</p>
|
|
114
|
+
<% end %>
|
|
115
|
+
```
|
|
42
116
|
|
|
43
|
-
|
|
117
|
+
See [testing](../docs/testing.md) for rendering tests and coverage gates.
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: composable-view
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.14
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jairo Vazquez
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-10-07 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: composable-core
|
|
@@ -15,28 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.0.
|
|
18
|
+
version: 0.0.14
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.0.
|
|
25
|
+
version: 0.0.14
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: view_component
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
32
|
+
version: '3.21'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
39
|
+
version: '3.21'
|
|
40
40
|
description: View composable object to work with Rails ActionView forms
|
|
41
41
|
email:
|
|
42
42
|
- jairovm20@gmail.com
|
|
@@ -65,7 +65,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
65
65
|
requirements:
|
|
66
66
|
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 2.
|
|
68
|
+
version: 3.2.0
|
|
69
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
70
|
requirements:
|
|
71
71
|
- - ">="
|