tramway 2.1.3.2 → 2.2.1
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/README.md +105 -1
- data/app/components/tailwind_component.rb +45 -5
- data/app/components/tailwinds/back_button_component.html.haml +1 -1
- data/app/components/tailwinds/back_button_component.rb +6 -0
- data/app/components/tailwinds/badge_component.rb +7 -4
- data/app/components/tailwinds/button_component.rb +13 -10
- data/app/components/tailwinds/containers/main_component.html.haml +2 -0
- data/app/components/tailwinds/containers/main_component.rb +14 -0
- data/app/components/tailwinds/containers/narrow_component.html.haml +1 -1
- data/app/components/tailwinds/containers/narrow_component.rb +7 -0
- data/app/components/tailwinds/flash_component.html.haml +3 -3
- data/app/components/tailwinds/flash_component.rb +19 -0
- data/app/components/tailwinds/form/date_field_component.html.haml +2 -3
- data/app/components/tailwinds/form/file_field_component.html.haml +2 -2
- data/app/components/tailwinds/form/label_component.html.haml +1 -1
- data/app/components/tailwinds/form/label_component.rb +6 -0
- data/app/components/tailwinds/form/multiselect/dropdown_container.html.haml +1 -1
- data/app/components/tailwinds/form/multiselect/dropdown_container.rb +7 -1
- data/app/components/tailwinds/form/multiselect/item_container.html.haml +3 -3
- data/app/components/tailwinds/form/multiselect/item_container.rb +21 -1
- data/app/components/tailwinds/form/multiselect/select_as_input.html.haml +2 -3
- data/app/components/tailwinds/form/multiselect/select_as_input.rb +8 -3
- data/app/components/tailwinds/form/multiselect/selected_item_template.html.haml +1 -1
- data/app/components/tailwinds/form/multiselect/selected_item_template.rb +8 -1
- data/app/components/tailwinds/form/multiselect_component.html.haml +3 -3
- data/app/components/tailwinds/form/multiselect_component.rb +20 -0
- data/app/components/tailwinds/form/number_field_component.html.haml +1 -3
- data/app/components/tailwinds/form/select_component.html.haml +1 -4
- data/app/components/tailwinds/form/submit_button_component.html.haml +2 -3
- data/app/components/tailwinds/form/submit_button_component.rb +1 -1
- data/app/components/tailwinds/form/text_area_component.html.haml +1 -3
- data/app/components/tailwinds/form/text_field_component.html.haml +1 -3
- data/app/components/tailwinds/nav/item_component.rb +4 -1
- data/app/components/tailwinds/navbar_component.html.haml +4 -4
- data/app/components/tailwinds/navbar_component.rb +25 -0
- data/app/components/tailwinds/pagination/base.rb +6 -4
- data/app/components/tailwinds/pagination/gap_component.html.haml +1 -1
- data/app/components/tailwinds/pagination/gap_component.rb +5 -0
- data/app/components/tailwinds/pagination/page_component.html.haml +1 -1
- data/app/components/tailwinds/pagination/page_component.rb +7 -0
- data/app/components/tailwinds/table/cell_component.html.haml +1 -1
- data/app/components/tailwinds/table/cell_component.rb +7 -0
- data/app/components/tailwinds/table/header_component.html.haml +2 -2
- data/app/components/tailwinds/table/header_component.rb +11 -0
- data/app/components/tailwinds/table/row/preview_component.html.haml +2 -2
- data/app/components/tailwinds/table/row/preview_component.rb +11 -0
- data/app/components/tailwinds/table/row_component.html.haml +3 -3
- data/app/components/tailwinds/table/row_component.rb +21 -7
- data/app/components/tailwinds/table_component.html.haml +1 -1
- data/app/components/tailwinds/table_component.rb +6 -0
- data/app/components/tailwinds/title_component.html.haml +1 -1
- data/app/components/tailwinds/title_component.rb +6 -0
- data/app/components/tramway/actions_buttons_container_component.html.haml +2 -0
- data/app/components/tramway/actions_buttons_container_component.rb +6 -0
- data/app/components/tramway/base_component.rb +13 -0
- data/app/components/tramway/entity_component.html.haml +19 -1
- data/app/controllers/tramway/entities_controller.rb +24 -1
- data/app/views/tramway/entities/_form.html.haml +4 -1
- data/app/views/tramway/entities/_list.html.haml +2 -2
- data/app/views/tramway/entities/edit.html.haml +5 -0
- data/app/views/tramway/entities/show.html.haml +13 -2
- data/config/locales/en.yml +10 -0
- data/config/routes.rb +4 -25
- data/config/tailwind.config.js +87 -76
- data/docs/AGENTS.md +1 -1
- data/lib/tramway/base_decorator.rb +10 -6
- data/lib/tramway/base_form.rb +1 -0
- data/lib/tramway/config.rb +2 -1
- data/lib/tramway/configs/entity.rb +24 -13
- data/lib/tramway/helpers/views_helper.rb +13 -1
- data/lib/tramway/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 88472147f728346a8406400f46ce9b0c3aeda279944f7c3df64c793addf2f37e
|
|
4
|
+
data.tar.gz: 65a3a58d859f7c88f960547f78aaa3ba55fb061af5b0abbd0b6b4671c5dee252
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 73ad5c1dab62c549c296a15ba556e7df759ea5613c2afe9894fd794e89d1d6b1b16020c51516ef12559ac3d499b280b3c9cdbb026145705f8c3232737232375d
|
|
7
|
+
data.tar.gz: 74cd74e6f6c57495ac2ea2178c52e33f94b57ee48ce0c5c746a84895c54af1dff33a491b757e597f863c5630beacd825c66269136054886c7eec2360ff61318b
|
data/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Tramway
|
|
2
2
|
Unite Ruby on Rails brilliance. Streamline development with Tramway.
|
|
3
3
|
|
|
4
|
+
Tramway ships with full CRUD (index, show, create, update, destroy) out of the box, and it includes a great AGENTS.md guide
|
|
5
|
+
that helps you generate good, Tramway-native code with all the framework features.
|
|
6
|
+
|
|
4
7
|
[](https://rubygems.org/gems/tramway)
|
|
5
8
|
[](https://github.com/Purple-Magic/tramway/actions/workflows/test.yml)
|
|
6
9
|
[](https://github.com/Purple-Magic/tramway/actions/workflows/lint.yml)
|
|
@@ -60,7 +63,13 @@ Tramway.configure do |config|
|
|
|
60
63
|
config.entities = [
|
|
61
64
|
{
|
|
62
65
|
name: :user,
|
|
63
|
-
pages: [
|
|
66
|
+
pages: [
|
|
67
|
+
{ action: :index },
|
|
68
|
+
{ action: :show },
|
|
69
|
+
{ action: :create },
|
|
70
|
+
{ action: :update },
|
|
71
|
+
{ action: :destroy }
|
|
72
|
+
],
|
|
64
73
|
}
|
|
65
74
|
]
|
|
66
75
|
end
|
|
@@ -215,6 +224,91 @@ end
|
|
|
215
224
|
With this configuration in place, visiting the show page displays a two-column table where the left column contains the
|
|
216
225
|
localized attribute names and the right column renders their values.
|
|
217
226
|
|
|
227
|
+
**create page**
|
|
228
|
+
|
|
229
|
+
To render a create page for an entity, declare a `:create` action inside the `pages` array in
|
|
230
|
+
`config/initializers/tramway.rb`. Tramway will generate the route and render the form fields based on your form object.
|
|
231
|
+
See the [form_fields method](#form_fields-method) for details on configuring fields.
|
|
232
|
+
|
|
233
|
+
```ruby
|
|
234
|
+
Tramway.configure do |config|
|
|
235
|
+
config.entities = [
|
|
236
|
+
{
|
|
237
|
+
name: :campaign,
|
|
238
|
+
pages: [
|
|
239
|
+
{ action: :index },
|
|
240
|
+
{ action: :create }
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
end
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**update page**
|
|
248
|
+
|
|
249
|
+
To render an update page, declare an `:update` action inside the `pages` array in `config/initializers/tramway.rb`.
|
|
250
|
+
Tramway will generate the edit route and reuse the same form partial as create. See the
|
|
251
|
+
[form_fields method](#form_fields-method) for details on configuring fields.
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
Tramway.configure do |config|
|
|
255
|
+
config.entities = [
|
|
256
|
+
{
|
|
257
|
+
name: :campaign,
|
|
258
|
+
pages: [
|
|
259
|
+
{ action: :index },
|
|
260
|
+
{ action: :update }
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
end
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**form_fields method**
|
|
268
|
+
|
|
269
|
+
Use `form_fields` in your form class to customize which form helpers get rendered and which options are passed to them.
|
|
270
|
+
Each field must map to a form helper method name. When you need to pass options, use a hash where `:type` is the helper
|
|
271
|
+
method name and the remaining keys are passed as named arguments.
|
|
272
|
+
|
|
273
|
+
```ruby
|
|
274
|
+
class UserForm < Tramway::BaseForm
|
|
275
|
+
properties :email, :about_me
|
|
276
|
+
|
|
277
|
+
fields email: :email,
|
|
278
|
+
about_me: {
|
|
279
|
+
type: :text_area,
|
|
280
|
+
rows: 5
|
|
281
|
+
}
|
|
282
|
+
end
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
The configuration above renders:
|
|
286
|
+
|
|
287
|
+
```erb
|
|
288
|
+
<%= tramway_form_for .... do |f| %>
|
|
289
|
+
<%= f.email_field :email %>
|
|
290
|
+
<%= f.text_area :about_me, rows: 5 %>
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**destroy page**
|
|
294
|
+
|
|
295
|
+
To render a destroy action, declare a `:destroy` action inside the `pages` array in `config/initializers/tramway.rb`.
|
|
296
|
+
Tramway will generate the destroy route and render the delete action button.
|
|
297
|
+
|
|
298
|
+
```ruby
|
|
299
|
+
Tramway.configure do |config|
|
|
300
|
+
config.entities = [
|
|
301
|
+
{
|
|
302
|
+
name: :campaign,
|
|
303
|
+
pages: [
|
|
304
|
+
{ action: :index },
|
|
305
|
+
{ action: :destroy }
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
end
|
|
310
|
+
```
|
|
311
|
+
|
|
218
312
|
**route_helper**
|
|
219
313
|
|
|
220
314
|
To get routes Tramway generated just Tramway::Engine.
|
|
@@ -891,6 +985,16 @@ Tramway provides `tramway_form_for` helper that renders Tailwind-styled forms by
|
|
|
891
985
|
|
|
892
986
|
will render [this](https://play.tailwindcss.com/xho3LfjKkK)
|
|
893
987
|
|
|
988
|
+
Use `size:` to control the form sizing (`:small`, `:middle`, or `:large`). The default is `:middle`, and all fields rendered
|
|
989
|
+
within the form will use the same size value.
|
|
990
|
+
|
|
991
|
+
```erb
|
|
992
|
+
<%= tramway_form_for @user, size: :large do |f| %>
|
|
993
|
+
<%= f.text_field :text %>
|
|
994
|
+
<%= f.submit 'Create User' %>
|
|
995
|
+
<% end %>
|
|
996
|
+
```
|
|
997
|
+
|
|
894
998
|
Available form helpers:
|
|
895
999
|
* text_field
|
|
896
1000
|
* email_field
|
|
@@ -28,16 +28,56 @@ class TailwindComponent < Tramway::BaseComponent
|
|
|
28
28
|
multiselect_input: 'text-base px-3 py-2'
|
|
29
29
|
},
|
|
30
30
|
large: {
|
|
31
|
-
text_input: 'text-
|
|
32
|
-
select_input: 'text-
|
|
33
|
-
file_button: 'text-
|
|
34
|
-
submit_button: 'text-
|
|
35
|
-
multiselect_input: 'text-
|
|
31
|
+
text_input: 'text-xl px-4 py-3',
|
|
32
|
+
select_input: 'text-xl px-4 py-3',
|
|
33
|
+
file_button: 'text-xl px-5 py-3',
|
|
34
|
+
submit_button: 'text-xl px-5 py-3',
|
|
35
|
+
multiselect_input: 'text-xl px-4 py-3'
|
|
36
36
|
}
|
|
37
37
|
}.freeze
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
+
def text_input_base_classes
|
|
42
|
+
theme_classes(
|
|
43
|
+
classic: 'w-full rounded-xl border border-gray-200 bg-gray-100 text-gray-700 shadow-inner ' \
|
|
44
|
+
'focus:outline-none focus:ring-2 focus:ring-gray-300 placeholder-gray-400 ' \
|
|
45
|
+
'dark:bg-gray-900 dark:border-gray-700 dark:text-gray-100 dark:placeholder-gray-500 ' \
|
|
46
|
+
'dark:focus:ring-gray-600'
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def select_base_classes
|
|
51
|
+
theme_classes(
|
|
52
|
+
classic: 'w-full rounded-xl border border-gray-200 bg-gray-100 text-gray-700 shadow-inner ' \
|
|
53
|
+
'focus:outline-none focus:ring-2 focus:ring-gray-300 disabled:cursor-not-allowed ' \
|
|
54
|
+
'disabled:bg-gray-200 disabled:text-gray-400 dark:bg-gray-900 dark:border-gray-700 ' \
|
|
55
|
+
'dark:text-gray-100 dark:focus:ring-gray-600 dark:disabled:bg-gray-800 ' \
|
|
56
|
+
'dark:disabled:text-gray-500'
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def file_button_base_classes
|
|
61
|
+
theme_classes(
|
|
62
|
+
classic: 'inline-block text-blue-800 font-semibold rounded-xl cursor-pointer mt-4 bg-blue-100 ' \
|
|
63
|
+
'hover:bg-blue-200 shadow-md dark:bg-blue-900 dark:text-blue-100 dark:hover:bg-blue-800'
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def submit_button_base_classes
|
|
68
|
+
theme_classes(
|
|
69
|
+
classic: 'font-semibold rounded-xl focus:outline-none focus:ring-2 focus:ring-red-200 cursor-pointer ' \
|
|
70
|
+
'bg-green-100 hover:bg-green-200 shadow-md dark:bg-green-900 ' \
|
|
71
|
+
'dark:hover:bg-green-800 dark:focus:ring-red-700'
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def form_label_classes
|
|
76
|
+
theme_classes(
|
|
77
|
+
classic: 'block text-sm font-semibold mb-2 text-gray-700 dark:text-gray-200'
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
41
81
|
def size_class(key)
|
|
42
82
|
size_classes = SIZE_CLASSES.fetch(size) { SIZE_CLASSES[:middle] }
|
|
43
83
|
size_classes.fetch(key) { SIZE_CLASSES[:middle].fetch(key) }
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
%a
|
|
1
|
+
%a{ class: back_button_classes, onclick: "window.history.back(); return false;", href: '#' }
|
|
2
2
|
= t('actions.back')
|
|
@@ -3,5 +3,11 @@
|
|
|
3
3
|
module Tailwinds
|
|
4
4
|
# Backbutton component
|
|
5
5
|
class BackButtonComponent < BaseComponent
|
|
6
|
+
def back_button_classes
|
|
7
|
+
theme_classes(
|
|
8
|
+
classic: 'btn btn-delete bg-orange-100 hover:bg-orange-200 text-orange-800 font-semibold py-2 px-4 ' \
|
|
9
|
+
'rounded-xl ml-2 shadow-md dark:bg-orange-800 dark:text-orange-100 dark:hover:bg-orange-700'
|
|
10
|
+
)
|
|
11
|
+
end
|
|
6
12
|
end
|
|
7
13
|
end
|
|
@@ -9,10 +9,13 @@ module Tailwinds
|
|
|
9
9
|
option :color, optional: true
|
|
10
10
|
|
|
11
11
|
def classes
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
theme_classes(
|
|
13
|
+
classic: [
|
|
14
|
+
'flex', 'px-3', 'py-1', 'text-sm', 'font-semibold', 'rounded-full', 'w-fit', 'h-fit',
|
|
15
|
+
"bg-#{resolved_color}-200", "text-#{resolved_color}-800", 'shadow-md',
|
|
16
|
+
"dark:bg-#{resolved_color}-700", "dark:text-#{resolved_color}-100"
|
|
17
|
+
]
|
|
18
|
+
)
|
|
16
19
|
end
|
|
17
20
|
end
|
|
18
21
|
end
|
|
@@ -18,7 +18,7 @@ module Tailwinds
|
|
|
18
18
|
{
|
|
19
19
|
small: 'text-sm py-1 px-2 rounded',
|
|
20
20
|
middle: 'py-2 px-4 h-10',
|
|
21
|
-
large: 'text-
|
|
21
|
+
large: 'text-xl px-5 py-3 h-12'
|
|
22
22
|
}[size]
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -29,22 +29,25 @@ module Tailwinds
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def default_classes
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
base_classes = theme_classes(
|
|
33
|
+
classic: %w[btn btn-primary flex flex-row font-semibold rounded-xl whitespace-nowrap items-center gap-1
|
|
34
|
+
shadow-md]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
base_classes + [size_classes.to_s, options[:class].to_s]
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
def color_classes
|
|
39
41
|
if disabled?
|
|
40
|
-
%w[bg-gray-400 text-gray-
|
|
42
|
+
%w[bg-gray-200 text-gray-400 shadow-inner dark:bg-gray-800 dark:text-gray-500]
|
|
41
43
|
else
|
|
42
44
|
[
|
|
43
|
-
"bg-#{resolved_color}-
|
|
44
|
-
"hover:bg-#{resolved_color}-
|
|
45
|
-
'text-gray-300'
|
|
45
|
+
"bg-#{resolved_color}-200", "hover:bg-#{resolved_color}-300", "text-#{resolved_color}-800",
|
|
46
|
+
"dark:bg-#{resolved_color}-700", "dark:hover:bg-#{resolved_color}-600", "dark:text-#{resolved_color}-100"
|
|
46
47
|
]
|
|
47
|
-
end
|
|
48
|
+
end => classes_collection
|
|
49
|
+
|
|
50
|
+
theme_classes classic: classes_collection
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def disabled?
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tailwinds
|
|
4
|
+
module Containers
|
|
5
|
+
# Main container for tailwind-styled layout
|
|
6
|
+
class MainComponent < Tramway::BaseComponent
|
|
7
|
+
def container_classes
|
|
8
|
+
theme_classes(
|
|
9
|
+
classic: 'bg-gray-100 text-gray-700 shadow-inner dark:bg-gray-900 dark:text-gray-100'
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -6,6 +6,13 @@ module Tailwinds
|
|
|
6
6
|
class NarrowComponent < Tramway::BaseComponent
|
|
7
7
|
option :id, optional: true, default: proc { SecureRandom.uuid }
|
|
8
8
|
option :options, optional: true, default: proc { {} }
|
|
9
|
+
|
|
10
|
+
def container_classes
|
|
11
|
+
theme_classes(
|
|
12
|
+
classic: 'container p-4 flex align-center justify-center w-full mx-auto bg-gray-100 text-gray-700 ' \
|
|
13
|
+
'shadow-inner rounded-xl dark:bg-gray-900 dark:text-gray-100'
|
|
14
|
+
)
|
|
15
|
+
end
|
|
9
16
|
end
|
|
10
17
|
end
|
|
11
18
|
end
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
animation: fadeout 2.7s ease-out forwards;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
%div{ class: container_classes, **options }
|
|
21
|
+
%div{ class: flash_classes }
|
|
22
|
+
%div{ class: title_classes }
|
|
23
23
|
= text
|
|
@@ -7,5 +7,24 @@ module Tailwinds
|
|
|
7
7
|
option :type, optional: true, default: -> {}
|
|
8
8
|
option :color, optional: true, default: -> {}
|
|
9
9
|
option :options, optional: true, default: -> { {} }
|
|
10
|
+
|
|
11
|
+
def container_classes
|
|
12
|
+
theme_classes(
|
|
13
|
+
classic: 'fixed top-4 right-4 z-50 space-y-2'
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def flash_classes
|
|
18
|
+
theme_classes(
|
|
19
|
+
classic: "flash opacity-100 px-4 py-2 rounded-xl shadow-md bg-#{resolved_color}-100 " \
|
|
20
|
+
"text-#{resolved_color}-800"
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def title_classes
|
|
25
|
+
theme_classes(
|
|
26
|
+
classic: 'text-xl font-semibold'
|
|
27
|
+
)
|
|
28
|
+
end
|
|
10
29
|
end
|
|
11
30
|
end
|
|
@@ -2,6 +2,5 @@
|
|
|
2
2
|
- if @label
|
|
3
3
|
= component('tailwinds/form/label', for: @for) do
|
|
4
4
|
= @label
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
= @input.call @attribute, **@options.merge(class: classes), value: @value
|
|
5
|
+
- classes = "#{size_class(:text_input)} #{text_input_base_classes}"
|
|
6
|
+
= @input.call @attribute, **@options.merge(class: classes), value: @value
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.mb-4
|
|
2
2
|
- if @label
|
|
3
|
-
-
|
|
4
|
-
|
|
3
|
+
- classes = "#{size_class(:file_button)} #{file_button_base_classes}"
|
|
4
|
+
|
|
5
5
|
%label{ for: @for, class: classes }
|
|
6
6
|
= @label
|
|
7
7
|
= @input
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
%label
|
|
1
|
+
%label{ for: @for, class: form_label_classes }
|
|
2
2
|
= content
|
|
@@ -5,6 +5,12 @@ module Tailwinds
|
|
|
5
5
|
# Form label for all tailwind-styled forms
|
|
6
6
|
class LabelComponent < Tramway::BaseComponent
|
|
7
7
|
option :for
|
|
8
|
+
|
|
9
|
+
def form_label_classes
|
|
10
|
+
theme_classes(
|
|
11
|
+
classic: 'block text-sm font-semibold mb-2 text-white'
|
|
12
|
+
)
|
|
13
|
+
end
|
|
8
14
|
end
|
|
9
15
|
end
|
|
10
16
|
end
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
#dropdown
|
|
1
|
+
#dropdown{ class: dropdown_classes, data: { action: "click@window->multiselect#closeOnClickOutside" } }
|
|
2
2
|
.flex.flex-col.w-full
|
|
3
3
|
{{content}}
|
|
@@ -4,7 +4,13 @@ module Tailwinds
|
|
|
4
4
|
module Form
|
|
5
5
|
module Multiselect
|
|
6
6
|
# Container for dropdown component
|
|
7
|
-
class DropdownContainer <
|
|
7
|
+
class DropdownContainer < Tramway::BaseComponent
|
|
8
|
+
def dropdown_classes
|
|
9
|
+
theme_classes(
|
|
10
|
+
classic: 'absolute shadow top-11 z-40 w-full lef-0 rounded-xl max-h-select overflow-y-auto ' \
|
|
11
|
+
'bg-gray-100 shadow-md ring-1 ring-gray-200 dark:bg-gray-900 dark:ring-gray-700'
|
|
12
|
+
)
|
|
13
|
+
end
|
|
8
14
|
end
|
|
9
15
|
end
|
|
10
16
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
%div{ class: item_classes, data: { action: "click->multiselect#toggleItem", text: "{{text}}", value: "{{value}}" } }
|
|
2
|
+
%div{ class: item_inner_classes }
|
|
3
|
+
%div{ class: item_text_classes }
|
|
4
4
|
.mx-2.leading-6
|
|
5
5
|
{{text}}
|
|
@@ -4,7 +4,27 @@ module Tailwinds
|
|
|
4
4
|
module Form
|
|
5
5
|
module Multiselect
|
|
6
6
|
# Container for item in dropdown component
|
|
7
|
-
class ItemContainer <
|
|
7
|
+
class ItemContainer < Tramway::BaseComponent
|
|
8
|
+
def item_classes
|
|
9
|
+
theme_classes(
|
|
10
|
+
classic: 'cursor-pointer w-full rounded-xl border-b border-gray-200 bg-gray-100 ' \
|
|
11
|
+
'hover:bg-gray-200 shadow-inner dark:bg-gray-900 dark:border-gray-700 ' \
|
|
12
|
+
'dark:hover:bg-gray-800'
|
|
13
|
+
)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def item_inner_classes
|
|
17
|
+
theme_classes(
|
|
18
|
+
classic: 'flex w-full items-center p-2 pl-2 border-transparent border-l-2 relative ' \
|
|
19
|
+
'hover:border-gray-300 dark:hover:border-gray-600'
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def item_text_classes
|
|
24
|
+
theme_classes(
|
|
25
|
+
classic: 'w-full items-center flex text-gray-700 dark:text-gray-100'
|
|
26
|
+
)
|
|
27
|
+
end
|
|
8
28
|
end
|
|
9
29
|
end
|
|
10
30
|
end
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
.flex-1
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
= @input.call(@attribute, @options.merge(placeholder: "{{placeholder}}", class: classes, data: { 'multiselect-target' => 'hiddenInput' }))
|
|
2
|
+
- classes = "#{@size_class} #{base_classes}"
|
|
3
|
+
= @input.call(@attribute, @options.merge(placeholder: "{{placeholder}}", class: classes, data: { 'multiselect-target' => 'hiddenInput' }))
|
|
@@ -4,13 +4,18 @@ module Tailwinds
|
|
|
4
4
|
module Form
|
|
5
5
|
module Multiselect
|
|
6
6
|
# Renders input as select
|
|
7
|
-
class SelectAsInput <
|
|
8
|
-
extend Dry::Initializer[undefined: false]
|
|
9
|
-
|
|
7
|
+
class SelectAsInput < Tramway::BaseComponent
|
|
10
8
|
option :options
|
|
11
9
|
option :attribute
|
|
12
10
|
option :input
|
|
13
11
|
option :size_class
|
|
12
|
+
|
|
13
|
+
def base_classes
|
|
14
|
+
theme_classes(
|
|
15
|
+
classic: 'bg-transparent appearance-none outline-none h-full w-full hidden text-gray-700 ' \
|
|
16
|
+
'placeholder-gray-400 dark:text-gray-100 dark:placeholder-gray-500'
|
|
17
|
+
)
|
|
18
|
+
end
|
|
14
19
|
end
|
|
15
20
|
end
|
|
16
21
|
end
|
|
@@ -4,7 +4,14 @@ module Tailwinds
|
|
|
4
4
|
module Form
|
|
5
5
|
module Multiselect
|
|
6
6
|
# Tailwind-styled multi-select field
|
|
7
|
-
class SelectedItemTemplate <
|
|
7
|
+
class SelectedItemTemplate < Tramway::BaseComponent
|
|
8
|
+
def selected_item_classes
|
|
9
|
+
theme_classes(
|
|
10
|
+
classic: 'flex justify-center items-center m-1 font-medium py-1 px-2 rounded-full border ' \
|
|
11
|
+
'bg-teal-100 text-teal-800 border-teal-200 shadow-md dark:bg-teal-900 ' \
|
|
12
|
+
'dark:text-teal-100 dark:border-teal-700'
|
|
13
|
+
)
|
|
14
|
+
end
|
|
8
15
|
end
|
|
9
16
|
end
|
|
10
17
|
end
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
- if @label
|
|
3
3
|
= component('tailwinds/form/label', for: @for) do
|
|
4
4
|
= @label
|
|
5
|
-
|
|
5
|
+
%div{ class: wrapper_classes, data: multiselect_hash, id: "#{@for}_multiselect" }
|
|
6
6
|
.min-w-96.w-fit
|
|
7
|
-
|
|
7
|
+
%div{ class: dropdown_classes, data: { "multiselect-target" => "dropdown" } }
|
|
8
8
|
.flex.flex-auto.flex-wrap{ data: { "multiselect-target" => "showSelectedArea" } }
|
|
9
|
-
|
|
9
|
+
%div{ class: dropdown_indicator_classes }
|
|
10
10
|
^
|
|
@@ -26,6 +26,26 @@ module Tailwinds
|
|
|
26
26
|
controllers.join(' ')
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
def wrapper_classes
|
|
30
|
+
theme_classes(
|
|
31
|
+
classic: 'flex flex-col relative text-gray-700 dark:text-gray-200'
|
|
32
|
+
)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def dropdown_classes
|
|
36
|
+
theme_classes(
|
|
37
|
+
classic: 'p-1 flex border rounded-xl border-gray-200 bg-gray-100 shadow-inner ' \
|
|
38
|
+
'dark:bg-gray-900 dark:border-gray-700'
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def dropdown_indicator_classes
|
|
43
|
+
theme_classes(
|
|
44
|
+
classic: 'w-8 py-1 pl-2 pr-1 border-l flex items-center text-gray-400 border-gray-200 ' \
|
|
45
|
+
'dark:text-gray-500 dark:border-gray-700'
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
|
|
29
49
|
private
|
|
30
50
|
|
|
31
51
|
def action
|
|
@@ -2,7 +2,5 @@
|
|
|
2
2
|
- if @label
|
|
3
3
|
= component('tailwinds/form/label', for: @for) do
|
|
4
4
|
= @label
|
|
5
|
-
-
|
|
6
|
-
- base_classes += 'bg-gray-800 border-gray-600 text-white focus:border-red-400 placeholder-white'
|
|
7
|
-
- classes = "#{size_class(:text_input)} #{base_classes}"
|
|
5
|
+
- classes = "#{size_class(:text_input)} #{text_input_base_classes}"
|
|
8
6
|
= @input.call @attribute, **@options.merge(class: classes), value: @value
|
|
@@ -2,8 +2,5 @@
|
|
|
2
2
|
- if @label
|
|
3
3
|
= component('tailwinds/form/label', for: @for) do
|
|
4
4
|
= @label
|
|
5
|
-
-
|
|
6
|
-
- base_classes += 'focus:border-transparent disabled:cursor-not-allowed '
|
|
7
|
-
- base_classes += 'bg-gray-800 border-gray-600 text-gray-100 focus:ring-red-400 disabled:bg-gray-800 disabled:text-gray-500'
|
|
8
|
-
- classes = "#{size_class(:select_input)} #{base_classes}"
|
|
5
|
+
- classes = "#{size_class(:select_input)} #{select_base_classes}"
|
|
9
6
|
= @input.call(@attribute, @collection, { selected: @value }, @options.merge(class: classes))
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
.flex.items-center.justify-between
|
|
2
|
-
-
|
|
3
|
-
- base_classes += 'text-white bg-red-600 hover:bg-red-500 focus:ring-2 focus:ring-red-400'
|
|
4
|
-
- classes = "#{size_class(:submit_button)} #{base_classes}"
|
|
2
|
+
- classes = "#{size_class(:submit_button)} #{submit_button_base_classes}"
|
|
5
3
|
|
|
6
4
|
= helpers.tramway_button text: @text,
|
|
7
5
|
type: :submit,
|
|
8
6
|
name: :commit,
|
|
9
7
|
size:,
|
|
8
|
+
class: classes,
|
|
10
9
|
**@options
|
|
11
10
|
|
|
12
11
|
= @content
|
|
@@ -2,7 +2,5 @@
|
|
|
2
2
|
- if @label
|
|
3
3
|
= component('tailwinds/form/label', for: @for) do
|
|
4
4
|
= @label
|
|
5
|
-
-
|
|
6
|
-
- base_classes += 'bg-gray-800 border-gray-600 text-white focus:border-red-400 placeholder-white'
|
|
7
|
-
- classes = "#{size_class(:text_input)} #{base_classes}"
|
|
5
|
+
- classes = "#{size_class(:text_input)} #{text_input_base_classes}"
|
|
8
6
|
= @input.call @attribute, **@options.merge(class: classes), value: @value
|
|
@@ -2,7 +2,5 @@
|
|
|
2
2
|
- if @label
|
|
3
3
|
= component('tailwinds/form/label', for: @for) do
|
|
4
4
|
= @label
|
|
5
|
-
-
|
|
6
|
-
- base_classes += 'bg-gray-800 border-gray-600 text-white focus:border-red-400 placeholder-white'
|
|
7
|
-
- classes = "#{size_class(:text_input)} #{base_classes}"
|
|
5
|
+
- classes = "#{size_class(:text_input)} #{text_input_base_classes}"
|
|
8
6
|
= @input.call @attribute, **@options.merge(class: classes), value: @value
|
|
@@ -7,7 +7,10 @@ module Tailwinds
|
|
|
7
7
|
class ItemComponent < TailwindComponent
|
|
8
8
|
def style
|
|
9
9
|
@style ||= [
|
|
10
|
-
|
|
10
|
+
theme_classes(
|
|
11
|
+
classic: 'px-4 py-2 rounded-xl whitespace-nowrap hover:bg-gray-200 hover:text-gray-600 text-gray-700 ' \
|
|
12
|
+
'dark:text-gray-200 dark:hover:bg-gray-800 dark:hover:text-gray-300'
|
|
13
|
+
)
|
|
11
14
|
].join(' ')
|
|
12
15
|
end
|
|
13
16
|
end
|