vident 0.7.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +103 -418
- data/Rakefile +1 -12
- data/lib/tasks/vident_tasks.rake +4 -0
- data/lib/vident/attributes/not_typed.rb +3 -0
- data/lib/vident/base.rb +8 -29
- data/lib/vident/caching.rb +120 -0
- data/lib/vident/component.rb +0 -2
- data/lib/vident/engine.rb +15 -0
- data/lib/vident/root_component.rb +235 -0
- data/lib/vident/version.rb +1 -1
- data/lib/vident.rb +3 -36
- metadata +12 -30
- data/.standard.yml +0 -3
- data/CHANGELOG.md +0 -79
- data/CODE_OF_CONDUCT.md +0 -84
- data/Gemfile +0 -35
- data/LICENSE.txt +0 -21
- data/examples/avatar.png +0 -0
- data/examples/ex1.gif +0 -0
- data/lib/tasks/vident.rake +0 -37
- data/lib/vident/attributes/typed.rb +0 -229
- data/lib/vident/attributes/typed_niling_struct.rb +0 -27
- data/lib/vident/attributes/types.rb +0 -16
- data/lib/vident/caching/cache_key.rb +0 -144
- data/lib/vident/railtie.rb +0 -10
- data/lib/vident/root_component/base.rb +0 -237
- data/lib/vident/root_component/using_better_html.rb +0 -41
- data/lib/vident/root_component/using_phlex_html.rb +0 -50
- data/lib/vident/root_component/using_view_component.rb +0 -51
- data/lib/vident/tailwind.rb +0 -12
- data/lib/vident/test_case.rb +0 -8
- data/lib/vident/testing/attributes_tester.rb +0 -176
- data/lib/vident/testing/auto_test.rb +0 -70
- data/lib/vident/typed_component.rb +0 -48
- data/sig/vident.rbs +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9144ee8a1b3361914b568d5dfbdcc22df506818813573e91ede2302e3a6775aa
|
4
|
+
data.tar.gz: 6476408b4f5acf6e4dd40d96539df7fb5588bb225200d3fbd05d35310a7c1c2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3098fa53c35329dc0ab5bbae9c4d2ca368ce8d9486fa5cfad29fddf8b006bed162dd8eb89cc1b76d42be91daecb0f0b41f979c866734f5a05f99580936444728
|
7
|
+
data.tar.gz: 47dff0e200721e7b48498e13cb27cf58fd7b0da9be6b428be201bb4f73593ffc233a459dc2e0b16f2c925097c65956a274a41c3707c1bfb45be1eccc7b2edbc7
|
data/README.md
CHANGED
@@ -1,59 +1,46 @@
|
|
1
1
|
# Vident
|
2
2
|
|
3
|
-
Vident
|
3
|
+
**Vident** is a collection of gems that help you create **flexible** & **maintainable** component libraries for your Rails application.
|
4
4
|
|
5
|
-
|
5
|
+
<a href="https://github.com/stevegeek/vident"><img alt="Vident logo" src="https://raw.githubusercontent.com/stevegeek/vident/main/logo-by-sd-256-colors.png" width="180" /></a>
|
6
|
+
|
7
|
+
Vident also provides a neat Ruby DSL to make wiring up **Stimulus easier & less error prone** in your view components.
|
8
|
+
|
9
|
+
[`ViewComponent`](https://viewcomponent.org/) and [`Phlex`](https://phlex.fun) supported.
|
6
10
|
|
7
11
|
# Motivation
|
8
12
|
|
9
13
|
I love working with Stimulus, but I find manually crafting the data attributes for
|
10
|
-
targets and actions error
|
11
|
-
and keep me thinking in Ruby.
|
14
|
+
targets and actions error-prone and tedious. Vident aims to make this process easier
|
15
|
+
and keep me thinking in Ruby.
|
12
16
|
|
13
|
-
I have been using Vident with `ViewComponent` in production apps for a while now and
|
14
|
-
evolving.
|
17
|
+
I have been using Vident with `ViewComponent` in production apps for a while now (and recently `Phlex`!)
|
18
|
+
and it has been constantly evolving.
|
15
19
|
|
16
20
|
This gem is a work in progress and I would love to get your feedback and contributions!
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
- `Vident::Component`: A mixin for your `ViewComponent` components or `Phlex` components that provides the a helper to create the
|
21
|
-
root element component (in templated or template-less components).
|
22
|
+
# Vident is a collection of gems
|
22
23
|
|
23
|
-
|
24
|
+
The core gems are:
|
24
25
|
|
25
|
-
|
26
|
+
- [`vident`](https://github.com/stevegeek/vident) to get the base functionality
|
27
|
+
- [`vident-typed`](https://github.com/stevegeek/vident-typed) to optionally define typed attributes for your view components
|
26
28
|
|
27
|
-
|
28
|
-
so you can easily override classes when rendering a component.
|
29
|
+
Gems that provide support for `ViewComponent` and `Phlex`:
|
29
30
|
|
30
|
-
- `
|
31
|
-
|
31
|
+
- [`vident-view_component`](https://github.com/stevegeek/vident-view_component) for using with `ViewComponent` and untyped attributes
|
32
|
+
- [`vident-typed-view_component`](https://github.com/stevegeek/vident-typed-view_component) for using with `ViewComponent` and typed attributes
|
33
|
+
- [`vident-phlex`](https://github.com/stevegeek/vident-phlex) for using with `Phlex` and untyped attributes
|
34
|
+
- [`vident-typed-phlex`](https://github.com/stevegeek/vident-typed-phlex) for using with `Phlex` and typed attributes
|
32
35
|
|
33
|
-
|
34
|
-
exposes a simple API for configuring and adding Stimulus controllers, targets and actions. Normally you create these
|
35
|
-
using the `root` helper method on `Vident::Component`/`Vident::TypedComponent`.
|
36
|
+
There is also:
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
-
|
40
|
-
- Component arguments are defined using the `attribute` method which allows you to define default values, (optionally) types and
|
41
|
-
if blank or nil values should be allowed.
|
42
|
-
- You can use the same component in multiple contexts and configure the root element differently in each context by passing
|
43
|
-
options to the component when instantiating it.
|
44
|
-
- Stimulus support is built in and sets a default controller name based on the component name.
|
45
|
-
- Stimulus actions, targets and classes can be setup using a simple DSL to avoid hand crafting the data attributes.
|
46
|
-
- Since data attribute names are generated from the component class name, you can rename easily refactor and move components without
|
47
|
-
having to update the data attributes in your views.
|
48
|
-
- Components are rendered with useful class names and IDs to make debugging easier (autogenerated IDs are 'random' but deterministic so they
|
49
|
-
are the same each time a given view is rendered to avoid content changing/Etag changing).
|
50
|
-
- (experimental) Support for fragment caching of components (only with ViewComponent and with caveats)
|
51
|
-
- (experimental) A test helper to make testing components easier by utilising type information from the component arguments to render
|
52
|
-
automatically configured good and bad examples of the component.
|
53
|
-
- (experimental) support for `better_html`
|
38
|
+
- [`vident-typed-minitest`](https://github.com/stevegeek/vident-typed-minitest) to get some test helpers for typed attributes (auto generates inputs to test attributes)
|
39
|
+
- [`vident-better_html`](https://github.com/stevegeek/vident-better_html) to support `better_html` if you use it in your Rails app
|
40
|
+
- [`vident-tailwind`](https://github.com/stevegeek/vident-tailwind) to get all the benefits of the amazing [`tailwind_merge`](https://github.com/gjtorikian/tailwind_merge/).
|
54
41
|
|
55
42
|
|
56
|
-
|
43
|
+
# Things still to do...
|
57
44
|
|
58
45
|
This is a work in progress. Here's what's left to do for first release:
|
59
46
|
|
@@ -63,445 +50,145 @@ This is a work in progress. Here's what's left to do for first release:
|
|
63
50
|
- Create an example library of a few components for some design system
|
64
51
|
- Create a demo app with `lookbook` and those components
|
65
52
|
- Add more documentation
|
66
|
-
- split `vident` into `vident` + `vident-rails` gems (and maybe `vident-rspec`) (Phlex can be used outside of Rails)
|
67
|
-
- possibly also split into `vident-phlex` and `vident-view_component` gems ?
|
68
|
-
|
69
|
-
|
70
53
|
|
71
|
-
#
|
54
|
+
# About Vident
|
72
55
|
|
73
|
-
|
74
|
-
both ViewComponent and Phlex (with and without Vident) in the `test/dummy`.
|
75
|
-
- https://github.com/stevegeek/vident/tree/main/test/dummy/app/components
|
76
|
-
- https://github.com/stevegeek/vident/tree/main/test/dummy/app/views
|
77
|
-
|
78
|
-
Start Rails:
|
79
|
-
|
80
|
-
```bash
|
81
|
-
cd test/dummy
|
82
|
-
bundle install
|
83
|
-
rails assets:precompile
|
84
|
-
rails s
|
85
|
-
```
|
86
|
-
|
87
|
-
and visit http://localhost:3000
|
56
|
+
## What does Vident provide?
|
88
57
|
|
58
|
+
- Base classes for your `ViewComponent` components or `Phlex` components that provides a helper to create the
|
59
|
+
all important 'root' element component (can be used with templated or template-less components).
|
89
60
|
|
90
|
-
|
61
|
+
- implementations of these root components for creating the 'root' element in your view components. Similar to `Primer::BaseComponent` but
|
62
|
+
exposes a simple API for configuring and adding Stimulus controllers, targets and actions. The root component also handles deduplication
|
63
|
+
of classes, creating a unique ID, setting the element tag type, handling possible overrides set at the render site, and determining stimulus controller identifiers etc
|
91
64
|
|
92
|
-
|
65
|
+
- a way to define attributes for your components, either typed or untyped, with default values and optional validation.
|
93
66
|
|
94
|
-
|
67
|
+
### Various utilities
|
95
68
|
|
96
|
-
|
69
|
+
Such as...
|
97
70
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
no_stimulus_controller
|
105
|
-
with_cache_key :attributes
|
106
|
-
|
107
|
-
attribute :url, String, allow_nil: true, allow_blank: false
|
108
|
-
attribute :initials, String, allow_blank: false
|
109
|
-
|
110
|
-
attribute :shape, Symbol, in: %i[circle square], default: :circle
|
111
|
-
|
112
|
-
attribute :border, :boolean, default: false
|
113
|
-
|
114
|
-
attribute :size, Symbol, in: %i[tiny small normal medium large x_large xx_large], default: :normal
|
115
|
-
|
116
|
-
private
|
117
|
-
|
118
|
-
def html_options
|
119
|
-
if image_avatar?
|
120
|
-
{ class: "inline-block object-contain", src: url, alt: t(".image") }
|
121
|
-
else
|
122
|
-
{ class: "inline-flex items-center justify-center bg-gray-500" }
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def element_classes
|
127
|
-
[size_classes, shape_class, border? ? "border" : ""]
|
128
|
-
end
|
129
|
-
|
130
|
-
alias_method :image_avatar?, :url?
|
131
|
-
|
132
|
-
def shape_class
|
133
|
-
(shape == :circle) ? "rounded-full" : "rounded-md"
|
134
|
-
end
|
135
|
-
|
136
|
-
def size_classes
|
137
|
-
case size
|
138
|
-
when :tiny
|
139
|
-
"w-6 h-6"
|
140
|
-
when :small
|
141
|
-
"w-8 h-8"
|
142
|
-
when :medium
|
143
|
-
"w-12 h-12"
|
144
|
-
when :large
|
145
|
-
"w-14 h-14"
|
146
|
-
when :x_large
|
147
|
-
"sm:w-24 sm:h-24 w-16 h-16"
|
148
|
-
when :xx_large
|
149
|
-
"sm:w-32 sm:h-32 w-24 h-24"
|
150
|
-
else
|
151
|
-
"w-10 h-10"
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def text_size_class
|
156
|
-
case size
|
157
|
-
when :tiny
|
158
|
-
"text-xs"
|
159
|
-
when :small
|
160
|
-
"text-xs"
|
161
|
-
when :medium
|
162
|
-
"text-lg"
|
163
|
-
when :large
|
164
|
-
"sm:text-xl text-lg"
|
165
|
-
when :extra_large
|
166
|
-
"sm:text-2xl text-xl"
|
167
|
-
else
|
168
|
-
"text-medium"
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
```
|
71
|
+
- for Taiwind users, a mixin for your vident component which uses [tailwind_merge](https://github.com/gjtorikian/tailwind_merge) to merge TailwindCSS classes
|
72
|
+
so you can easily override classes when rendering a component.
|
73
|
+
- a mixin for your Vident Components which provides a `#cache_key` method that can be used to generate a cache key for
|
74
|
+
fragment caching or etag generation.
|
75
|
+
- a test helper for your typed Vident ViewComponents which can be used to generate good and bad attribute/params/inputs
|
173
76
|
|
174
|
-
|
175
|
-
<%= render root(
|
176
|
-
element_tag: image_avatar? ? :img : :div,
|
177
|
-
html_options: html_options
|
178
|
-
) do %>
|
179
|
-
<% unless image_avatar? %>
|
180
|
-
<span class="<%= text_size_class %> font-medium leading-none text-white"><%= initials %></span>
|
181
|
-
<% end %>
|
182
|
-
<% end %>
|
77
|
+
## All the Features...
|
183
78
|
|
184
|
-
|
79
|
+
- use Vident with `ViewComponent` or `Phlex` or your own view component system
|
80
|
+
- A helper to create the root HTML element for your component, which then handles creation of attributes.
|
81
|
+
- Component arguments are defined using the `attribute` method which allows you to define default values, (optionally) types and
|
82
|
+
if blank or nil values should be allowed.
|
83
|
+
- You can use the same component in multiple contexts and configure the root element differently in each context by passing
|
84
|
+
options to the component when instantiating it.
|
85
|
+
- Stimulus support is built in and sets a default controller name based on the component name.
|
86
|
+
- Stimulus actions, targets and classes can be setup using a simple DSL to avoid hand crafting the data attributes.
|
87
|
+
- Since data attribute names are generated from the component class name, you can rename easily refactor and move components without
|
88
|
+
having to update the data attributes in your views.
|
89
|
+
- Components are rendered with useful class names and IDs to make debugging easier (autogenerated IDs are 'random' but deterministic so they
|
90
|
+
are the same each time a given view is rendered to avoid content changing/Etag changing).
|
91
|
+
- (experimental) Support for fragment caching of components (`Vident::Caching` and `Vident::<ViewComponent | Phlex>::Caching`... implementation has caveats)
|
92
|
+
- (experimental) A test helper to make testing components easier by utilising type information from the component arguments to render
|
93
|
+
automatically configured good and bad examples of the component.
|
94
|
+
- (experimental) support for `better_html`
|
185
95
|
|
186
|
-
Example usages:
|
187
|
-
|
188
|
-
```erb
|
189
|
-
<!-- These will render -->
|
190
|
-
<%= render AvatarComponent.new(url: "https://someurl.com/avatar.jpg", initials: "AB" size: :large) %>
|
191
|
-
<%= render AvatarComponent.new(url: "https://someurl.com/avatar.jpg", html_options: {alt: "My alt text", class: "object-scale-down"}) %>
|
192
|
-
<%= render AvatarComponent.new(initials: "SG", size: :small) %>
|
193
|
-
<%= render AvatarComponent.new(initials: "SG", size: :large, html_options: {class: "border-2 border-red-600"}) %>
|
194
|
-
|
195
|
-
<!-- These will raise an error -->
|
196
|
-
<!-- missing initals -->
|
197
|
-
<%= render AvatarComponent.new(url: "https://someurl.com/avatar.jpg", size: :large) %>
|
198
|
-
<!-- initials blank -->
|
199
|
-
<%= render AvatarComponent.new(initials: "", size: :large) %>
|
200
|
-
<!-- invalid size -->
|
201
|
-
<%= render AvatarComponent.new(initials: "SG", size: :foo_bar) %>
|
202
|
-
```
|
203
96
|
|
97
|
+
## Installation
|
204
98
|
|
205
|
-
|
99
|
+
This gem (`vident`) provides only base functionality but there are a number of gems that provide additional functionality
|
100
|
+
or an "out of the box" experience.
|
206
101
|
|
207
|
-
|
208
|
-
|
209
|
-
<span class="text-xs font-medium leading-none text-white">SG</span>
|
210
|
-
</div>
|
211
|
-
```
|
102
|
+
It's a "pick your own adventure" approach. You decide what frameworks and features you want to use
|
103
|
+
and add the gems as needed.
|
212
104
|
|
213
|
-
|
105
|
+
First, add this line to your application's Gemfile:
|
214
106
|
|
215
|
-
```
|
216
|
-
|
107
|
+
```ruby
|
108
|
+
gem 'vident'
|
217
109
|
```
|
218
110
|
|
219
|
-
|
220
|
-
|
221
|
-
![Example](examples/avatar.png)
|
111
|
+
Then go on to choose the gems you want to use:
|
222
112
|
|
223
|
-
|
113
|
+
#### Q1. Do you want to use [`ViewComponent`](https://viewcomponent.org/) or [`Phlex`](https://www.phlex.fun/) for your view components?
|
224
114
|
|
225
|
-
|
115
|
+
For ViewComponent use:
|
226
116
|
|
227
|
-
|
228
|
-
used to greet the user. At the same time the button changes to be a 'reset' button, which resets the greeting when clicked again.
|
117
|
+
- [`vident-view_component`](https://github.com/stevegeek/vident-view_component)
|
229
118
|
|
230
|
-
|
119
|
+
For Phlex use:
|
231
120
|
|
232
|
-
|
233
|
-
<%# app/views/home/index.html.erb %>
|
121
|
+
- [`vident-phlex`](https://github.com/stevegeek/vident-phlex)
|
234
122
|
|
235
|
-
<!-- ... -->
|
236
|
-
|
237
|
-
<!-- render the Greeter ViewComponent (that uses Vident) -->
|
238
|
-
<%= render ::GreeterComponent.new(cta: "Hey!", html_options: {class: "my-4"}) do |greeter| %>
|
239
|
-
<%# this component has a slot called `trigger` that renders a `ButtonComponent` (which also uses Vident) %>
|
240
|
-
<% greeter.trigger(
|
241
|
-
|
242
|
-
# The button component has attributes that are typed
|
243
|
-
before_clicked: "Greet",
|
244
|
-
after_clicked: "Greeted! Reset?",
|
245
|
-
|
246
|
-
# A stimulus action is added to the button that triggers the `greet` action on the greeter stimulus controller.
|
247
|
-
# This action will be added to any defined on the button component itself
|
248
|
-
actions: [
|
249
|
-
greeter.action(:click, :greet),
|
250
|
-
],
|
251
|
-
|
252
|
-
# We can also override the default button classes of our component, or set other HTML attributes
|
253
|
-
html_options: {
|
254
|
-
class: "bg-red-500 hover:bg-red-700"
|
255
|
-
}
|
256
|
-
) %>
|
257
|
-
<% end %>
|
258
|
-
|
259
|
-
<!-- ... -->
|
260
|
-
```
|
261
|
-
|
262
|
-
The output HTML of the above, using Vident, is:
|
263
|
-
|
264
|
-
```html
|
265
|
-
<div class="greeter-component py-2 my-4"
|
266
|
-
data-controller="greeter-component"
|
267
|
-
data-greeter-component-pre-click-class="text-md text-gray-500"
|
268
|
-
data-greeter-component-post-click-class="text-xl text-blue-700"
|
269
|
-
id="greeter-component-1599855-6">
|
270
|
-
<input type="text"
|
271
|
-
data-greeter-component-target="name"
|
272
|
-
class="shadow appearance-none border rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
|
273
|
-
<button class="button-component ml-4 whitespace-no-wrap bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded bg-red-500 hover:bg-red-700"
|
274
|
-
data-controller="button-component"
|
275
|
-
data-action="click->greeter-component#greet button-component#changeMessage"
|
276
|
-
data-button-component-after-clicked-message="Greeted! Reset?"
|
277
|
-
data-button-component-before-clicked-message="Greet"
|
278
|
-
id="button-component-7799479-7">Hey!</button>
|
279
|
-
<!-- you can also use the `target_tag` helper to render targets -->
|
280
|
-
<span class="ml-4 text-md text-gray-500"
|
281
|
-
data-greeter-component-target="output">
|
282
|
-
...
|
283
|
-
</span>
|
284
|
-
</div>
|
285
|
-
```
|
286
123
|
|
287
|
-
|
124
|
+
Note: you can also use both in the same app.
|
288
125
|
|
289
|
-
|
126
|
+
For example, if you want to use ViewComponent and Phlex in the same app, you might end up with:
|
290
127
|
|
291
128
|
```ruby
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
include Vident::Component
|
296
|
-
|
297
|
-
renders_one :trigger, ButtonComponent
|
298
|
-
end
|
129
|
+
gem 'vident'
|
130
|
+
gem 'vident-view_component'
|
131
|
+
gem 'vident-phlex'
|
299
132
|
```
|
300
133
|
|
301
|
-
|
302
|
-
<%# app/components/greeter_component.html.erb %>
|
303
|
-
|
304
|
-
<%# Rendering the `root` element creates a tag which has stimulus `data-*`s, a unique id & other attributes set. %>
|
305
|
-
<%# The stimulus controller name (identifier) is derived from the component name, and then used to generate the relavent data attribute names. %>
|
306
|
-
|
307
|
-
<%= render root named_classes: {
|
308
|
-
pre_click: "text-md text-gray-500", # named classes are exposed to Stimulus as `data-<controller>-<name>-class` attributes
|
309
|
-
post_click: "text-xl text-blue-700",
|
310
|
-
html_options: {class: "py-2"}
|
311
|
-
} do |greeter| %>
|
312
|
-
|
313
|
-
<%# `greeter` is the root element and exposes methods to generate stimulus targets and actions %>
|
314
|
-
<input type="text"
|
315
|
-
<%= greeter.as_target(:name) %>
|
316
|
-
class="shadow appearance-none border rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline">
|
317
|
-
|
318
|
-
<%# Render the slot %>
|
319
|
-
<%= trigger %>
|
320
|
-
|
321
|
-
<%# you can also use the `target_tag` helper to render targets %>
|
322
|
-
<%= greeter.target_tag(
|
323
|
-
:span,
|
324
|
-
:output,
|
325
|
-
# Stimulus named classes can be referenced to set class attributes at render time
|
326
|
-
class: "ml-4 #{greeter.named_classes(:pre_click)}"
|
327
|
-
) do %>
|
328
|
-
...
|
329
|
-
<% end %>
|
330
|
-
<% end %>
|
134
|
+
#### Q2. Do you want to build components where the attributes have runtime type checking (powered by [`dry-types`](https://github.com/dry-rb/dry-types))?
|
331
135
|
|
332
|
-
|
333
|
-
|
334
|
-
```js
|
335
|
-
// app/components/greeter_component_controller.js
|
336
|
-
|
337
|
-
import { Controller } from "@hotwired/stimulus"
|
338
|
-
|
339
|
-
// This is a Stimulus controller that is automatically registered for the `GreeterComponent`
|
340
|
-
// and is 'sidecar' to the component. You can see that while in the ERB we use Ruby naming conventions
|
341
|
-
// with snake_case Symbols, here they are converted to camelCase names. We can also just use camelCase
|
342
|
-
// in the ERB if we want.
|
343
|
-
export default class extends Controller {
|
344
|
-
static targets = [ "name", "output" ]
|
345
|
-
static classes = [ "preClick", "postClick" ]
|
346
|
-
|
347
|
-
greet() {
|
348
|
-
this.clicked = !this.clicked;
|
349
|
-
this.outputTarget.classList.toggle(this.preClickClasses, !this.clicked);
|
350
|
-
this.outputTarget.classList.toggle(this.postClickClasses, this.clicked);
|
351
|
-
|
352
|
-
if (this.clicked)
|
353
|
-
this.outputTarget.textContent = `Hello, ${this.nameTarget.value}!`
|
354
|
-
else
|
355
|
-
this.clear();
|
356
|
-
}
|
357
|
-
|
358
|
-
clear() {
|
359
|
-
this.outputTarget.textContent = '...';
|
360
|
-
this.nameTarget.value = '';
|
361
|
-
}
|
362
|
-
}
|
363
|
-
```
|
364
|
-
|
365
|
-
The slot renders a `ButtonComponent` component:
|
136
|
+
If yes, then add `vident-typed` to your Gemfile:
|
366
137
|
|
367
138
|
```ruby
|
368
|
-
|
369
|
-
|
370
|
-
class ButtonComponent < ViewComponent::Base
|
371
|
-
# This component uses Vident::TypedComponent which uses dry-types to define typed attributes.
|
372
|
-
include Vident::TypedComponent
|
373
|
-
|
374
|
-
# The attributes can specify an expected type, a default value and if nil is allowed.
|
375
|
-
attribute :after_clicked, String, default: "Greeted!"
|
376
|
-
attribute :before_clicked, String, allow_nil: false
|
377
|
-
|
378
|
-
# This example is a templateless ViewComponent.
|
379
|
-
def call
|
380
|
-
# The button is rendered as a <button> tag with an click action on its own controller.
|
381
|
-
render root(
|
382
|
-
element_tag: :button,
|
383
|
-
|
384
|
-
# We can define actions as arrays of Symbols, or pass manually manually crafted strings.
|
385
|
-
# Here we specify the action name only, implying an action on the current components controller
|
386
|
-
# and the default event type of `click`.
|
387
|
-
actions: [:change_message],
|
388
|
-
# Alternatively: [:click, :change_message] or ["click", "changeMessage"] or even "click->button-component#changeMessage"
|
389
|
-
|
390
|
-
# A couple of data values are also set which will be available to the controller
|
391
|
-
data_maps: [{after_clicked_message: after_clicked, before_clicked_message: before_clicked}],
|
392
|
-
|
393
|
-
# The <button> tag has a default styling set directly on it. Note that
|
394
|
-
# if not using utility classes, you can style the component using its
|
395
|
-
# canonical class name (which is equal to the component's stimulus identifier),
|
396
|
-
# in this case `button-component`.
|
397
|
-
html_options: {class: "ml-4 whitespace-no-wrap bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"}
|
398
|
-
) do
|
399
|
-
@before_clicked
|
400
|
-
end
|
401
|
-
end
|
402
|
-
end
|
139
|
+
gem 'vident-typed'
|
403
140
|
```
|
404
141
|
|
405
|
-
|
406
|
-
// app/components/button_component_controller.js
|
407
|
-
|
408
|
-
import { Controller } from "@hotwired/stimulus"
|
142
|
+
and then use the relavent `*-typed-*` gems for your chosen view component system:
|
409
143
|
|
410
|
-
|
411
|
-
|
412
|
-
changeMessage() {
|
413
|
-
this.clicked = !this.clicked;
|
414
|
-
// The data attributes have their naming convention converted to camelCase.
|
415
|
-
this.element.textContent = this.clicked ? this.data.get("afterClickedMessage") : this.data.get("beforeClickedMessage");
|
416
|
-
}
|
417
|
-
}
|
144
|
+
- use [`vident-typed-view_component`](https://github.com/stevegeek/vident-typed-view_component)
|
145
|
+
- and/or [`vident-typed-phlex`](https://github.com/stevegeek/vident-typed-phlex)
|
418
146
|
|
419
|
-
|
420
|
-
|
421
|
-
## Installation
|
147
|
+
Note you must also include the gem for the view component system you are using.
|
422
148
|
|
423
|
-
|
149
|
+
For example, for ViewComponent, you might end up with:
|
424
150
|
|
425
151
|
```ruby
|
426
152
|
gem 'vident'
|
153
|
+
gem 'vident-view_component'
|
154
|
+
gem 'vident-typed'
|
155
|
+
gem 'vident-typed-view_component'
|
427
156
|
```
|
428
157
|
|
429
|
-
|
158
|
+
#### Q3. Do you use or want to use [BetterHTML](https://github.com/Shopify/better-html) in your Rails project?
|
430
159
|
|
431
|
-
|
432
|
-
gem 'view_component'
|
433
|
-
```
|
434
|
-
|
435
|
-
or
|
436
|
-
|
437
|
-
```ruby
|
438
|
-
gem 'phlex' # Must be version 0.5 or higher
|
439
|
-
```
|
440
|
-
|
441
|
-
or **both**!
|
442
|
-
|
443
|
-
If you want to use typed attributes you must also include `dry-struct`
|
444
|
-
|
445
|
-
```ruby
|
446
|
-
gem 'dry-struct'
|
447
|
-
```
|
448
|
-
|
449
|
-
And then execute:
|
450
|
-
|
451
|
-
$ bundle install
|
452
|
-
|
453
|
-
## Making 'sidecar' Stimulus Controllers work
|
454
|
-
|
455
|
-
### When using `stimulus-rails`, `sprockets-rails` & `importmap-rails`
|
456
|
-
|
457
|
-
Pin any JS modules from under `app/views` and `app/components` which are sidecar with their respective components.
|
458
|
-
|
459
|
-
Add to `config/importmap.rb`:
|
160
|
+
If yes, then include [`vident-better_html`](https://github.com/stevegeek/vident-better_html) in your Gemfile alongside `better_html` and your vident gems of choice.
|
460
161
|
|
461
162
|
```ruby
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
components_path.glob("**/*_controller.js").each do |controller|
|
466
|
-
name = controller.relative_path_from(components_path).to_s.remove(/\.js$/)
|
467
|
-
pin "#{prefix}/#{name}", to: name
|
468
|
-
end
|
469
|
-
end
|
163
|
+
...
|
164
|
+
gem 'better_html'
|
165
|
+
gem 'vident-better_html'
|
470
166
|
```
|
471
167
|
|
472
|
-
Note
|
473
|
-
See this for more: https://stackoverflow.com/a/73228193/268602
|
168
|
+
Note that `vident-better_html` automatically enables `better_html` support in Vident root components.
|
474
169
|
|
475
|
-
|
476
|
-
to the `app/assets/config/manifest.js`:
|
170
|
+
### Q4. Do you use or want to use [TailwindCSS](https://tailwindcss.com/)?
|
477
171
|
|
478
|
-
|
479
|
-
//= link_tree ../../components .js
|
480
|
-
//= link_tree ../../views .js
|
481
|
-
```
|
482
|
-
|
483
|
-
We also need to add to `assets.paths`. Add to your to `config/application.rb`
|
172
|
+
If yes, then consider adding [`vident-tailwind`](https://github.com/stevegeek/vident-tailwind) to your Gemfile alongside your vident gems of choice.
|
484
173
|
|
485
174
|
```ruby
|
486
|
-
|
487
|
-
|
175
|
+
...
|
176
|
+
gem 'vident-tailwind'
|
488
177
|
```
|
489
178
|
|
490
|
-
|
491
|
-
|
492
|
-
TODO
|
179
|
+
When creating your components you can then include `Vident::Tailwind` to get all the benefits of the amazing [`tailwind_merge`](https://github.com/gjtorikian/tailwind_merge/).
|
493
180
|
|
494
|
-
###
|
181
|
+
### Q5. Did none of the above gems suit your needs?
|
495
182
|
|
496
|
-
|
183
|
+
You can always just use base `vident` gems and then roll your own solutions:
|
497
184
|
|
498
|
-
|
185
|
+
- [`vident`](https://github.com/stevegeek/vident) to get the base functionality to mix with your own view component system
|
186
|
+
- [`vident-typed`](https://github.com/stevegeek/vident-typed) to define typed attributes for your own view component system
|
499
187
|
|
500
|
-
TODO
|
501
188
|
|
502
|
-
##
|
189
|
+
## Documentation
|
503
190
|
|
504
|
-
|
191
|
+
See the [docs](docs/) directory and visit the individual gem pages for more information.
|
505
192
|
|
506
193
|
## Development
|
507
194
|
|
@@ -509,8 +196,6 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
509
196
|
|
510
197
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
511
198
|
|
512
|
-
|
513
|
-
|
514
199
|
## Contributing
|
515
200
|
|
516
201
|
Bug reports and pull requests are welcome on GitHub at https://github.com/stevegeek/vident. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/vident/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -1,14 +1,3 @@
|
|
1
|
-
|
1
|
+
require "bundler/setup"
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
|
-
require "rake/testtask"
|
5
|
-
|
6
|
-
Rake::TestTask.new(:test) do |t|
|
7
|
-
t.libs << "test"
|
8
|
-
t.libs << "lib"
|
9
|
-
t.test_files = FileList["test/**/*_test.rb"]
|
10
|
-
end
|
11
|
-
|
12
|
-
require "standard/rake"
|
13
|
-
|
14
|
-
task default: %i[test standard]
|