tramway 2.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 +39 -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 +1 -1
- data/app/components/tailwinds/table/row_component.rb +17 -5
- 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/base_component.rb +13 -0
- data/config/tailwind.config.js +87 -76
- data/lib/tramway/config.rb +2 -1
- data/lib/tramway/helpers/views_helper.rb +13 -1
- data/lib/tramway/version.rb +1 -1
- metadata +4 -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
|
@@ -228,6 +228,7 @@ localized attribute names and the right column renders their values.
|
|
|
228
228
|
|
|
229
229
|
To render a create page for an entity, declare a `:create` action inside the `pages` array in
|
|
230
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.
|
|
231
232
|
|
|
232
233
|
```ruby
|
|
233
234
|
Tramway.configure do |config|
|
|
@@ -246,7 +247,8 @@ end
|
|
|
246
247
|
**update page**
|
|
247
248
|
|
|
248
249
|
To render an update page, declare an `:update` action inside the `pages` array in `config/initializers/tramway.rb`.
|
|
249
|
-
Tramway will generate the edit route and reuse the same form partial as create.
|
|
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.
|
|
250
252
|
|
|
251
253
|
```ruby
|
|
252
254
|
Tramway.configure do |config|
|
|
@@ -262,6 +264,32 @@ Tramway.configure do |config|
|
|
|
262
264
|
end
|
|
263
265
|
```
|
|
264
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
|
+
|
|
265
293
|
**destroy page**
|
|
266
294
|
|
|
267
295
|
To render a destroy action, declare a `:destroy` action inside the `pages` array in `config/initializers/tramway.rb`.
|
|
@@ -957,6 +985,16 @@ Tramway provides `tramway_form_for` helper that renders Tailwind-styled forms by
|
|
|
957
985
|
|
|
958
986
|
will render [this](https://play.tailwindcss.com/xho3LfjKkK)
|
|
959
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
|
+
|
|
960
998
|
Available form helpers:
|
|
961
999
|
* text_field
|
|
962
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
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
%nav
|
|
1
|
+
%nav{ class: navbar_classes }
|
|
2
2
|
.flex.justify-between.w-full
|
|
3
3
|
- if @title[:text].present? || @left_items.present?
|
|
4
4
|
.flex.items-center
|
|
5
5
|
- if @title[:text].present?
|
|
6
6
|
= link_to @title[:link] do
|
|
7
|
-
.text-xl
|
|
7
|
+
.text-xl{ class: title_classes }
|
|
8
8
|
= @title[:text]
|
|
9
9
|
- if @left_items.present?
|
|
10
10
|
%ul.flex-row.items-center.space-x-4.ml-4.hidden.md:flex
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
= item
|
|
13
13
|
|
|
14
14
|
.block.sm:hidden
|
|
15
|
-
%button#mobile-menu-button
|
|
15
|
+
%button#mobile-menu-button{ class: mobile_button_classes }
|
|
16
16
|
☰
|
|
17
17
|
|
|
18
18
|
- if @right_items.present?
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
- @right_items.each do |item|
|
|
21
21
|
= item
|
|
22
22
|
|
|
23
|
-
#mobile-menu
|
|
23
|
+
#mobile-menu{ class: mobile_menu_classes }
|
|
24
24
|
- if @left_items.present?
|
|
25
25
|
%ul.flex.flex-col.space-y-2
|
|
26
26
|
- @left_items.each do |item|
|
|
@@ -8,5 +8,30 @@ module Tailwinds
|
|
|
8
8
|
@left_items = options[:left_items]
|
|
9
9
|
@right_items = options[:right_items]
|
|
10
10
|
end
|
|
11
|
+
|
|
12
|
+
def navbar_classes
|
|
13
|
+
theme_classes(
|
|
14
|
+
classic: 'py-2 px-4 sm:px-8 flex justify-between items-center bg-gray-100 shadow-md ' \
|
|
15
|
+
'dark:bg-gray-900'
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def title_classes
|
|
20
|
+
theme_classes(
|
|
21
|
+
classic: 'text-xl font-semibold text-gray-800 dark:text-gray-100'
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def mobile_button_classes
|
|
26
|
+
theme_classes(
|
|
27
|
+
classic: 'text-gray-700 focus:outline-none dark:text-gray-200'
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def mobile_menu_classes
|
|
32
|
+
theme_classes(
|
|
33
|
+
classic: 'hidden flex-col sm:hidden bg-gray-100 shadow-inner dark:bg-gray-900'
|
|
34
|
+
)
|
|
35
|
+
end
|
|
11
36
|
end
|
|
12
37
|
end
|