tramway 3.1.2.4 → 3.1.2.5
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 +36 -1
- data/app/assets/javascripts/tramway/tramway.js +30 -3
- data/app/components/tailwind_component.rb +6 -3
- data/app/components/tramway/form/checkbox_component.html.haml +5 -5
- data/app/components/tramway/form/checkbox_component.rb +52 -6
- data/app/components/tramway/table/cell_component.html.haml +1 -1
- data/app/components/tramway/table/cell_component.rb +2 -0
- data/app/components/tramway/table/header_component.html.haml +1 -1
- data/app/components/tramway/table/header_component.rb +1 -0
- data/config/locales/en.yml +2 -0
- data/config/tailwind.config.js +5 -0
- data/lib/tramway/base_decorator.rb +3 -1
- data/lib/tramway/helpers/views_helper.rb +4 -3
- data/lib/tramway/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 564610d50165b34a4446cdc570c377a12f9c49587b366c994141a3e2702e289f
|
|
4
|
+
data.tar.gz: beed0c0e6d742dbec6caeaed2fff43c0b6ff62248b804d723dc7b0ce98883b4b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 98bfc099a4338a4e114a7591d9721b209077e3a419b83669b5c5fbe5ce21a4c004515a97af9d4a32bf3c5219c426198176c5e413b3633569b68935f623eb9f3f
|
|
7
|
+
data.tar.gz: f7d43d03755310fa2ae39e8d0a89c2c87ff90791843ce7ee899eae5ef518dd06b7830c45a0a861159dcf7378862c3e008ef7411b21b465a19ade3863085880a1
|
data/README.md
CHANGED
|
@@ -548,6 +548,24 @@ UserDecorator.decorate user # => nil
|
|
|
548
548
|
|
|
549
549
|
Read [behave_as_ar](https://github.com/Purple-Magic/tramway#behave_as_ar) section
|
|
550
550
|
|
|
551
|
+
#### Actions column on index tables
|
|
552
|
+
|
|
553
|
+
When an entity has `update` or `destroy` pages configured, Tramway automatically
|
|
554
|
+
appends an `Actions` column to the end of the entity's index table headers,
|
|
555
|
+
holding the edit/destroy controls for each row.
|
|
556
|
+
|
|
557
|
+
This label is looked up through `I18n` (`tramway.table.actions_header`), so you
|
|
558
|
+
can rename it to your own language by overriding the key in your app's locale
|
|
559
|
+
file:
|
|
560
|
+
|
|
561
|
+
*config/locales/en.yml*
|
|
562
|
+
```yaml
|
|
563
|
+
en:
|
|
564
|
+
tramway:
|
|
565
|
+
table:
|
|
566
|
+
actions_header: "Actions"
|
|
567
|
+
```
|
|
568
|
+
|
|
551
569
|
### Tramway Form
|
|
552
570
|
|
|
553
571
|
Tramway provides **convenient** form objects for Rails applications. List properties you want to change and the rules in Form classes. No controllers overloading.
|
|
@@ -1073,6 +1091,22 @@ details panel. Pass `preview: false` when you want a row without the preview pan
|
|
|
1073
1091
|
<% end %>
|
|
1074
1092
|
```
|
|
1075
1093
|
|
|
1094
|
+
`tramway_cell` also forwards any HTML options to the underlying cell wrapper. Use this when you need per-cell classes,
|
|
1095
|
+
data attributes, ids, or other attributes:
|
|
1096
|
+
|
|
1097
|
+
```erb
|
|
1098
|
+
<%= tramway_cell class: 'whitespace-nowrap', data: { turbo: false } do %>
|
|
1099
|
+
<%= user.name %>
|
|
1100
|
+
<% end %>
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
`tramway_header` forwards HTML options to the header wrapper as well. That makes it easy to add ids, classes, or data
|
|
1104
|
+
attributes to the header row:
|
|
1105
|
+
|
|
1106
|
+
```erb
|
|
1107
|
+
<%= tramway_header headers: ['Name', 'Email'], class: 'sticky top-0', data: { controller: 'table-header' } %>
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1076
1110
|
When you render a header you can either pass the `headers:` array, as in the examples above, or render custom header content in
|
|
1077
1111
|
the block. `tramway_header` uses the length of the `headers` array to build the grid if the array is present.
|
|
1078
1112
|
If you omit the array and provide custom content, pass the `columns:` argument so the component knows how many grid columns to
|
|
@@ -1196,7 +1230,8 @@ Tramway uses [Tailwind](https://tailwindcss.com/) by default. All UI helpers are
|
|
|
1196
1230
|
|
|
1197
1231
|
Tramway provides `tramway_form_for` helper that renders Tailwind-styled forms by default. Form inputs use hardcoded
|
|
1198
1232
|
dark shadcn-style classes; Tramway does not render a separate light form theme.
|
|
1199
|
-
Checkboxes render dark
|
|
1233
|
+
Checkboxes render with a visible, fixed-size dark unchecked surface and use the light primary checked state.
|
|
1234
|
+
Checkbox controls, checkmarks, and vertically centered label line heights scale together with the form-level `size:` option.
|
|
1200
1235
|
|
|
1201
1236
|
```erb
|
|
1202
1237
|
<%= tramway_form_for @user do |f| %>
|
|
@@ -388,15 +388,42 @@ class UiCheckbox extends Controller {
|
|
|
388
388
|
|
|
389
389
|
this.buttonTarget.setAttribute("aria-checked", checked.toString())
|
|
390
390
|
this.buttonTarget.dataset.state = state
|
|
391
|
-
this.
|
|
391
|
+
this.syncBoxStyle(checked)
|
|
392
|
+
this.buttonTarget.classList.add("border-zinc-50")
|
|
392
393
|
this.buttonTarget.classList.toggle("bg-zinc-50", checked)
|
|
393
394
|
this.buttonTarget.classList.toggle("text-zinc-950", checked)
|
|
394
|
-
this.buttonTarget.classList.toggle("
|
|
395
|
-
this.buttonTarget.classList.toggle("bg-zinc-950", !checked)
|
|
395
|
+
this.buttonTarget.classList.toggle("bg-zinc-900", !checked)
|
|
396
396
|
this.buttonTarget.classList.toggle("text-zinc-50", !checked)
|
|
397
|
+
this.buttonTarget.classList.remove("border-zinc-800", "bg-zinc-950")
|
|
397
398
|
this.indicatorTarget.classList.toggle("hidden", !checked)
|
|
398
399
|
this.buttonTarget.toggleAttribute("disabled", this.inputTarget.disabled)
|
|
399
400
|
}
|
|
401
|
+
|
|
402
|
+
syncBoxStyle(checked) {
|
|
403
|
+
const size = this.checkboxSize()
|
|
404
|
+
|
|
405
|
+
this.buttonTarget.style.width = size
|
|
406
|
+
this.buttonTarget.style.height = size
|
|
407
|
+
this.buttonTarget.style.minWidth = size
|
|
408
|
+
this.buttonTarget.style.minHeight = size
|
|
409
|
+
this.buttonTarget.style.display = "inline-flex"
|
|
410
|
+
this.buttonTarget.style.alignItems = "center"
|
|
411
|
+
this.buttonTarget.style.justifyContent = "center"
|
|
412
|
+
this.buttonTarget.style.padding = "0"
|
|
413
|
+
this.buttonTarget.style.lineHeight = "1"
|
|
414
|
+
this.buttonTarget.style.boxSizing = "border-box"
|
|
415
|
+
this.buttonTarget.style.border = "1px solid #fafafa"
|
|
416
|
+
this.buttonTarget.style.backgroundColor = checked ? "#fafafa" : "#18181b"
|
|
417
|
+
this.buttonTarget.style.color = checked ? "#09090b" : "#fafafa"
|
|
418
|
+
this.buttonTarget.style.boxShadow = "0 0 0 1px #fafafa"
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
checkboxSize() {
|
|
422
|
+
if (this.buttonTarget.classList.contains("h-4")) return "1rem"
|
|
423
|
+
if (this.buttonTarget.classList.contains("h-6")) return "1.5rem"
|
|
424
|
+
|
|
425
|
+
return "1.25rem"
|
|
426
|
+
}
|
|
400
427
|
}
|
|
401
428
|
|
|
402
429
|
class Tooltip extends Controller {
|
|
@@ -19,7 +19,8 @@ class TailwindComponent < Tramway::BaseComponent
|
|
|
19
19
|
file_button: 'text-sm px-3 py-1',
|
|
20
20
|
submit_button: 'text-sm px-3 py-1',
|
|
21
21
|
tramway_select_input: 'text-sm px-2 py-1 h-10',
|
|
22
|
-
checkbox_input: '
|
|
22
|
+
checkbox_input: 'h-4 w-4',
|
|
23
|
+
checkbox_indicator: 'h-3 w-3'
|
|
23
24
|
},
|
|
24
25
|
medium: {
|
|
25
26
|
text_input: 'text-base px-3 py-2',
|
|
@@ -27,7 +28,8 @@ class TailwindComponent < Tramway::BaseComponent
|
|
|
27
28
|
file_button: 'text-base px-4 py-2',
|
|
28
29
|
submit_button: 'text-base px-4 py-2',
|
|
29
30
|
tramway_select_input: 'text-base px-2 py-1 h-12',
|
|
30
|
-
checkbox_input: '
|
|
31
|
+
checkbox_input: 'h-5 w-5',
|
|
32
|
+
checkbox_indicator: 'h-4 w-4'
|
|
31
33
|
},
|
|
32
34
|
large: {
|
|
33
35
|
text_input: 'text-xl px-4 py-3',
|
|
@@ -35,7 +37,8 @@ class TailwindComponent < Tramway::BaseComponent
|
|
|
35
37
|
file_button: 'text-xl px-5 py-3',
|
|
36
38
|
submit_button: 'text-xl px-5 py-3',
|
|
37
39
|
tramway_select_input: 'text-xl px-3 py-2 h-15',
|
|
38
|
-
checkbox_input: '
|
|
40
|
+
checkbox_input: 'h-6 w-6',
|
|
41
|
+
checkbox_indicator: 'h-5 w-5'
|
|
39
42
|
}
|
|
40
43
|
}.freeze
|
|
41
44
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.flex.items-center.
|
|
1
|
+
.flex.items-center.gap-2{ class: default_container_classes, data: { controller: 'ui--checkbox' } }
|
|
2
2
|
- checkbox_checked = checked?
|
|
3
3
|
= @input.call @attribute, **hidden_checkbox_options
|
|
4
4
|
%button{ type: 'button',
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
'data-ui--checkbox-target' => 'button',
|
|
10
10
|
value: 'on',
|
|
11
11
|
class: checkbox_button_classes,
|
|
12
|
+
style: checkbox_button_style,
|
|
12
13
|
for: @for,
|
|
13
14
|
id: @for }
|
|
14
15
|
%span{ class: checkbox_indicator_classes, style: 'pointer-events: none', data: { 'ui--checkbox-target' => 'indicator' } }
|
|
@@ -21,9 +22,8 @@
|
|
|
21
22
|
'stroke-width' => '2',
|
|
22
23
|
'stroke-linecap' => 'round',
|
|
23
24
|
'stroke-linejoin' => 'round',
|
|
24
|
-
class:
|
|
25
|
+
class: size_class(:checkbox_indicator) }
|
|
25
26
|
%polyline{ points: '20 6 9 17 4 12' }
|
|
26
27
|
- if @label
|
|
27
|
-
|
|
28
|
-
=
|
|
29
|
-
= @label
|
|
28
|
+
= component('tramway/form/label', for: @for, options: { class: label_classes, style: label_style, data: { action: 'click->ui--checkbox#toggle' } }) do
|
|
29
|
+
= @label
|
|
@@ -4,8 +4,25 @@ module Tramway
|
|
|
4
4
|
module Form
|
|
5
5
|
# Tailwind-styled checkbox field
|
|
6
6
|
class CheckboxComponent < TailwindComponent
|
|
7
|
+
CHECKBOX_BUTTON_BASE_STYLES = {
|
|
8
|
+
display: 'inline-flex',
|
|
9
|
+
'align-items': 'center',
|
|
10
|
+
'justify-content': 'center',
|
|
11
|
+
padding: '0',
|
|
12
|
+
'line-height': '1',
|
|
13
|
+
'box-sizing': 'border-box',
|
|
14
|
+
border: '1px solid #fafafa',
|
|
15
|
+
'box-shadow': '0 0 0 1px #fafafa'
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
CHECKBOX_BUTTON_SIZES = {
|
|
19
|
+
small: '1rem',
|
|
20
|
+
medium: '1.25rem',
|
|
21
|
+
large: '1.5rem'
|
|
22
|
+
}.freeze
|
|
23
|
+
|
|
7
24
|
def checkbox_button_classes
|
|
8
|
-
|
|
25
|
+
"peer #{size_class(:checkbox_input)} shrink-0 rounded-sm border border-zinc-50 bg-zinc-900 text-zinc-50 " \
|
|
9
26
|
'ring-offset-zinc-950 ' \
|
|
10
27
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-300 ' \
|
|
11
28
|
'focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ' \
|
|
@@ -14,7 +31,11 @@ module Tramway
|
|
|
14
31
|
end
|
|
15
32
|
|
|
16
33
|
def checkbox_indicator_classes
|
|
17
|
-
|
|
34
|
+
"flex hidden #{size_class(:checkbox_indicator)} items-center justify-center text-current"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def checkbox_button_style
|
|
38
|
+
checkbox_button_style_attributes.map { |key, value| "#{key}: #{value}" }.join('; ')
|
|
18
39
|
end
|
|
19
40
|
|
|
20
41
|
def checked?
|
|
@@ -36,19 +57,44 @@ module Tramway
|
|
|
36
57
|
end
|
|
37
58
|
|
|
38
59
|
def label_classes
|
|
39
|
-
default_classes = 'cursor-pointer mb-0
|
|
60
|
+
default_classes = 'cursor-pointer mb-0'
|
|
40
61
|
|
|
41
62
|
case size
|
|
42
63
|
when :small
|
|
43
|
-
default_classes += ' text-sm'
|
|
64
|
+
default_classes += ' text-sm leading-5'
|
|
44
65
|
when :medium
|
|
45
|
-
default_classes += ' text-base'
|
|
66
|
+
default_classes += ' text-base leading-6'
|
|
46
67
|
when :large
|
|
47
|
-
default_classes += ' text-lg'
|
|
68
|
+
default_classes += ' text-lg leading-7'
|
|
48
69
|
end
|
|
49
70
|
|
|
50
71
|
default_classes
|
|
51
72
|
end
|
|
73
|
+
|
|
74
|
+
def label_style
|
|
75
|
+
{
|
|
76
|
+
'align-self': 'center',
|
|
77
|
+
'line-height': checkbox_button_size,
|
|
78
|
+
'margin-bottom': '0'
|
|
79
|
+
}.map { |key, value| "#{key}: #{value}" }.join('; ')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def checkbox_button_style_attributes
|
|
85
|
+
CHECKBOX_BUTTON_BASE_STYLES.merge(
|
|
86
|
+
width: checkbox_button_size,
|
|
87
|
+
height: checkbox_button_size,
|
|
88
|
+
'min-width': checkbox_button_size,
|
|
89
|
+
'min-height': checkbox_button_size,
|
|
90
|
+
'background-color': checked? ? '#fafafa' : '#18181b',
|
|
91
|
+
color: checked? ? '#09090b' : '#fafafa'
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def checkbox_button_size
|
|
96
|
+
CHECKBOX_BUTTON_SIZES.fetch(size, CHECKBOX_BUTTON_SIZES.fetch(:medium))
|
|
97
|
+
end
|
|
52
98
|
end
|
|
53
99
|
end
|
|
54
100
|
end
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
%div{ class: cell_classes }
|
|
1
|
+
%div{ class: [options[:class], cell_classes].compact.join(' '), **options.except(:class) }
|
|
2
2
|
= content
|
|
@@ -4,6 +4,8 @@ module Tramway
|
|
|
4
4
|
module Table
|
|
5
5
|
# Component for rendering a cell in a table
|
|
6
6
|
class CellComponent < Tramway::BaseComponent
|
|
7
|
+
option :options, optional: true, default: -> { {} }
|
|
8
|
+
|
|
7
9
|
def cell_classes
|
|
8
10
|
'div-table-cell hidden px-6 py-4 text-base font-medium text-zinc-100 first:block md:block'
|
|
9
11
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
- parsed_cells = headers.any? ? nil : visible_cells_from(content)
|
|
2
|
-
%div{ class: "#{header_row_classes} md:grid-cols-#{columns_count(parsed_cells: parsed_cells)}", aria: { label: "Table Header" }, role: "row" }
|
|
2
|
+
%div{ class: [options[:class], "#{header_row_classes} md:grid-cols-#{columns_count(parsed_cells: parsed_cells)}"].compact.join(' '), aria: { label: "Table Header" }, role: "row", **options.except(:class) }
|
|
3
3
|
- if headers.any?
|
|
4
4
|
- headers.each do |header|
|
|
5
5
|
.div-table-cell.border-b.border-zinc-800{ class: header_cell_classes }
|
|
@@ -8,6 +8,7 @@ module Tramway
|
|
|
8
8
|
|
|
9
9
|
option :headers, optional: true, default: -> { [] }
|
|
10
10
|
option :columns, optional: true, default: -> { 3 }
|
|
11
|
+
option :options, optional: true, default: -> { {} }
|
|
11
12
|
|
|
12
13
|
def columns_count(content = nil, parsed_cells: nil)
|
|
13
14
|
return headers.size if headers.present?
|
data/config/locales/en.yml
CHANGED
data/config/tailwind.config.js
CHANGED
|
@@ -516,8 +516,12 @@ module.exports = {
|
|
|
516
516
|
'leading-none',
|
|
517
517
|
'appearance-none',
|
|
518
518
|
'peer',
|
|
519
|
+
'h-3',
|
|
520
|
+
'w-3',
|
|
519
521
|
'h-4',
|
|
520
522
|
'w-4',
|
|
523
|
+
'h-6',
|
|
524
|
+
'w-6',
|
|
521
525
|
'text-current',
|
|
522
526
|
'ring-offset-zinc-950',
|
|
523
527
|
'data-[state=checked]:border-zinc-50',
|
|
@@ -578,6 +582,7 @@ module.exports = {
|
|
|
578
582
|
'text-sm',
|
|
579
583
|
'font-medium',
|
|
580
584
|
'leading-6',
|
|
585
|
+
'leading-7',
|
|
581
586
|
'text-zinc-50',
|
|
582
587
|
'text-green-400',
|
|
583
588
|
'text-blue-400',
|
|
@@ -68,7 +68,9 @@ module Tramway
|
|
|
68
68
|
(model_class || entity.model_class).human_attribute_name(attribute)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
if entity&.page(:update).present? || entity&.page(:destroy).present?
|
|
72
|
+
headers += [I18n.t('tramway.table.actions_header')]
|
|
73
|
+
end
|
|
72
74
|
|
|
73
75
|
headers
|
|
74
76
|
end
|
|
@@ -23,10 +23,11 @@ module Tramway
|
|
|
23
23
|
component 'tramway/table', options:, &
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
def tramway_header(headers: nil, columns: nil, &)
|
|
26
|
+
def tramway_header(headers: nil, columns: nil, **options, &)
|
|
27
27
|
component 'tramway/table/header',
|
|
28
28
|
headers:,
|
|
29
29
|
columns:,
|
|
30
|
+
options:,
|
|
30
31
|
&
|
|
31
32
|
end
|
|
32
33
|
|
|
@@ -39,8 +40,8 @@ module Tramway
|
|
|
39
40
|
&
|
|
40
41
|
end
|
|
41
42
|
|
|
42
|
-
def tramway_cell(&)
|
|
43
|
-
component 'tramway/table/cell', &
|
|
43
|
+
def tramway_cell(**options, &)
|
|
44
|
+
component 'tramway/table/cell', options:, &
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
def tramway_button(path: nil, text: nil, method: :get, form_options: {}, **options, &)
|
data/lib/tramway/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tramway
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.2.
|
|
4
|
+
version: 3.1.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kalashnikovisme
|
|
@@ -325,7 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
325
325
|
- !ruby/object:Gem::Version
|
|
326
326
|
version: '0'
|
|
327
327
|
requirements: []
|
|
328
|
-
rubygems_version: 4.0.
|
|
328
|
+
rubygems_version: 4.0.16
|
|
329
329
|
specification_version: 4
|
|
330
330
|
summary: Tramway Rails Engine
|
|
331
331
|
test_files: []
|