tramway 3.1.1.3 → 3.1.2
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 +59 -2
- data/app/components/tramway/form/builder.rb +19 -0
- data/app/components/tramway/form/rich_text_area_component.html.haml +14 -0
- data/app/components/tramway/form/rich_text_area_component.rb +42 -0
- data/app/components/tramway/table/row_component.html.haml +2 -2
- data/app/views/tramway/layouts/application.html.haml +2 -4
- data/config/tailwind.config.js +6 -1
- data/lib/generators/tramway/install/install_generator.rb +50 -0
- data/lib/tramway/utils/field.rb +1 -1
- data/lib/tramway/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b60bf123066d7c59336dba45b1dae5ab6a90b36fd54063c73f04d4fcac17ba21
|
|
4
|
+
data.tar.gz: d1512dee19a6f92b27791ad9b6b40582e0b0e90b7ef2a6304e7d1846d7d05930
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fbe4b415c8fc353f3be1453064072dc34864181f795f92c631ff2776af7fa060f0c0ab893149b8e3fb1702365b9f56c286b038424bff034b6ec3a1a6c13156b8
|
|
7
|
+
data.tar.gz: 4a403cd5695f25bf309feceed280afdf9cc489eff25dd1d37bf766b2714aff4fd22cf6d0fbf460659b115258bd9b89f6b10bb5c419c228a077d97272921222c8
|
data/README.md
CHANGED
|
@@ -53,7 +53,8 @@ bin/rails g tramway:install
|
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
The install generator adds the required gems (`haml-rails`, `kaminari`, `view_component`, `dry-initializer`, and `dry-monads`) to your
|
|
56
|
-
application's Gemfile—if they are not present—
|
|
56
|
+
application's Gemfile—if they are not present—appends the Tailwind safelist configuration Tramway ships with, and injects the
|
|
57
|
+
Trix stylesheet and JavaScript tags into your application layout (required for `rich_text_area`).
|
|
57
58
|
|
|
58
59
|
## Getting Started
|
|
59
60
|
|
|
@@ -1203,6 +1204,7 @@ Checkboxes render dark while unchecked and use the light primary checked state.
|
|
|
1203
1204
|
<%= f.select :role, [:admin, :user] %>
|
|
1204
1205
|
<%= f.date_field :birth_date %>
|
|
1205
1206
|
<%= f.datetime_field :confirmed_at %>
|
|
1207
|
+
<%= f.rich_text_area :bio %>
|
|
1206
1208
|
<%= f.tramway_select :permissions, [['Create User', 'create_user'], ['Update user', 'update_user']] %>
|
|
1207
1209
|
<%= f.file_field :file %>
|
|
1208
1210
|
<%= f.submit 'Create User' %>
|
|
@@ -1238,10 +1240,12 @@ Available form helpers:
|
|
|
1238
1240
|
* password_field
|
|
1239
1241
|
* file_field
|
|
1240
1242
|
* check_box
|
|
1243
|
+
* checkbox (alias for check_box)
|
|
1241
1244
|
* select
|
|
1242
1245
|
* date_field
|
|
1243
1246
|
* datetime_field
|
|
1244
1247
|
* time_field
|
|
1248
|
+
* rich_text_area (Action Text/Trix editor with Tramway dark form classes)
|
|
1245
1249
|
* tramway_select ([Stimulus-based](https://github.com/Purple-Magic/tramway#stimulus-based-inputs))
|
|
1246
1250
|
* submit
|
|
1247
1251
|
|
|
@@ -1283,6 +1287,60 @@ same select field.
|
|
|
1283
1287
|
<% end %>
|
|
1284
1288
|
```
|
|
1285
1289
|
|
|
1290
|
+
#### Rich text area
|
|
1291
|
+
|
|
1292
|
+
`rich_text_area` (and its alias `rich_textarea`) renders a [Trix](https://trix-editor.org/) rich text editor
|
|
1293
|
+
with Tramway's dark-theme Tailwind styling. Trix is bundled with Rails and does not require an additional gem.
|
|
1294
|
+
|
|
1295
|
+
Before using `rich_text_area`, the Trix stylesheet and JavaScript must be present in your application layout.
|
|
1296
|
+
The `tramway:install` generator adds them automatically. To add them manually:
|
|
1297
|
+
|
|
1298
|
+
```haml
|
|
1299
|
+
-# app/views/layouts/application.html.haml
|
|
1300
|
+
= stylesheet_link_tag "trix", "data-turbo-track": "reload"
|
|
1301
|
+
= javascript_include_tag "trix", "data-turbo-track": "reload", defer: true
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
```erb
|
|
1305
|
+
<%# app/views/layouts/application.html.erb %>
|
|
1306
|
+
<%= stylesheet_link_tag "trix", "data-turbo-track": "reload" %>
|
|
1307
|
+
<%= javascript_include_tag "trix", "data-turbo-track": "reload", defer: true %>
|
|
1308
|
+
```
|
|
1309
|
+
|
|
1310
|
+
Basic usage:
|
|
1311
|
+
|
|
1312
|
+
```erb
|
|
1313
|
+
<%= tramway_form_for @post do |f| %>
|
|
1314
|
+
<%= f.rich_text_area :body %>
|
|
1315
|
+
<% end %>
|
|
1316
|
+
```
|
|
1317
|
+
|
|
1318
|
+
Custom label and extra CSS class:
|
|
1319
|
+
|
|
1320
|
+
```erb
|
|
1321
|
+
<%= tramway_form_for @post do |f| %>
|
|
1322
|
+
<%= f.rich_text_area :body, label: 'Post body', class: 'min-h-60' %>
|
|
1323
|
+
<% end %>
|
|
1324
|
+
```
|
|
1325
|
+
|
|
1326
|
+
Suppress the label:
|
|
1327
|
+
|
|
1328
|
+
```erb
|
|
1329
|
+
<%= tramway_form_for @post do |f| %>
|
|
1330
|
+
<%= f.rich_text_area :body, label: false %>
|
|
1331
|
+
<% end %>
|
|
1332
|
+
```
|
|
1333
|
+
|
|
1334
|
+
Pass `data` attributes for Stimulus controllers:
|
|
1335
|
+
|
|
1336
|
+
```erb
|
|
1337
|
+
<%= tramway_form_for @post do |f| %>
|
|
1338
|
+
<%= f.rich_text_area :body, data: { controller: 'mentions' } %>
|
|
1339
|
+
<% end %>
|
|
1340
|
+
```
|
|
1341
|
+
|
|
1342
|
+
`size:` is a Tramway-level option and is not forwarded to the `<trix-editor>` element.
|
|
1343
|
+
|
|
1286
1344
|
#### Stimulus-based inputs
|
|
1287
1345
|
|
|
1288
1346
|
`tramway_form_for` provides Tailwind-styled Stimulus-based custom inputs.
|
|
@@ -1339,7 +1397,6 @@ With `remote: true`, Tramway submits the form on each input `change` via inline
|
|
|
1339
1397
|
### Tailwind-styled pagination for Kaminari
|
|
1340
1398
|
|
|
1341
1399
|
Tramway uses [Tailwind](https://tailwindcss.com/) by default. It has tailwind-styled pagination for [kaminari](https://github.com/kaminari/kaminari).
|
|
1342
|
-
Pagination components use hardcoded dark shadcn-style classes and do not render a separate light theme.
|
|
1343
1400
|
|
|
1344
1401
|
#### How to use
|
|
1345
1402
|
|
|
@@ -56,6 +56,14 @@ module Tramway
|
|
|
56
56
|
common_field(:text_area, :text_area, attribute, **, &)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
+
def rich_text_area(attribute, **, &)
|
|
60
|
+
rich_text_area_field(:rich_text_area, attribute, **, &)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def rich_textarea(attribute, **, &)
|
|
64
|
+
rich_text_area_field(:rich_textarea, attribute, **, &)
|
|
65
|
+
end
|
|
66
|
+
|
|
59
67
|
def password_field(attribute, **options, &)
|
|
60
68
|
sanitized_options = sanitize_options(options)
|
|
61
69
|
|
|
@@ -88,6 +96,8 @@ module Tramway
|
|
|
88
96
|
common_field(:checkbox, :check_box, attribute, **, &)
|
|
89
97
|
end
|
|
90
98
|
|
|
99
|
+
alias checkbox check_box
|
|
100
|
+
|
|
91
101
|
def select(attribute, collection, **options, &)
|
|
92
102
|
if options[:multiple] || options[:autocomplete]
|
|
93
103
|
tramway_select(attribute, collection, **options, &)
|
|
@@ -138,6 +148,15 @@ module Tramway
|
|
|
138
148
|
), &)
|
|
139
149
|
end
|
|
140
150
|
|
|
151
|
+
def rich_text_area_field(input_method, attribute, **options, &)
|
|
152
|
+
sanitized_options = sanitize_options(options)
|
|
153
|
+
|
|
154
|
+
render(Tramway::Form::RichTextAreaComponent.new(
|
|
155
|
+
input: input(input_method),
|
|
156
|
+
**default_options(attribute, sanitized_options)
|
|
157
|
+
), &)
|
|
158
|
+
end
|
|
159
|
+
|
|
141
160
|
def input(method_name)
|
|
142
161
|
unbound_method = self.class.superclass.instance_method(method_name)
|
|
143
162
|
unbound_method.bind(self)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
%div{ class: default_container_classes }
|
|
2
|
+
:css
|
|
3
|
+
trix-toolbar .trix-button-group {
|
|
4
|
+
border-color: #52525b;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
trix-toolbar .trix-button:not(.trix-active)::before {
|
|
8
|
+
filter: invert(1);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
- if @label
|
|
12
|
+
= component('tramway/form/label', for: @for, class: 'mb-0') do
|
|
13
|
+
= @label
|
|
14
|
+
= @input.call @attribute, **rich_text_area_options
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tramway
|
|
4
|
+
module Form
|
|
5
|
+
# Tailwind-styled rich text area
|
|
6
|
+
class RichTextAreaComponent < TailwindComponent
|
|
7
|
+
RICH_TEXT_AREA_CLASSES = [
|
|
8
|
+
'trix-content',
|
|
9
|
+
'prose',
|
|
10
|
+
'prose-invert',
|
|
11
|
+
'max-w-none',
|
|
12
|
+
'w-full',
|
|
13
|
+
'min-h-40',
|
|
14
|
+
'rounded-md',
|
|
15
|
+
'border',
|
|
16
|
+
'border-zinc-800',
|
|
17
|
+
'bg-zinc-950',
|
|
18
|
+
'!bg-zinc-950',
|
|
19
|
+
'text-zinc-50',
|
|
20
|
+
'!text-zinc-50',
|
|
21
|
+
'shadow-sm',
|
|
22
|
+
'transition-colors',
|
|
23
|
+
'focus-visible:outline-none',
|
|
24
|
+
'focus-visible:ring-2',
|
|
25
|
+
'focus-visible:ring-zinc-300',
|
|
26
|
+
'focus-visible:ring-offset-2',
|
|
27
|
+
'focus-visible:ring-offset-zinc-950',
|
|
28
|
+
'disabled:cursor-not-allowed',
|
|
29
|
+
'disabled:opacity-50'
|
|
30
|
+
].freeze
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def rich_text_area_options
|
|
35
|
+
options.dup.tap do |rich_text_options|
|
|
36
|
+
custom_class = rich_text_options.delete(:class) || rich_text_options.delete('class')
|
|
37
|
+
rich_text_options[:class] = [RICH_TEXT_AREA_CLASSES, custom_class].compact.join(' ')
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- cells = visible_cells_from(content)
|
|
9
9
|
|
|
10
10
|
- if href.present?
|
|
11
|
-
= tag.a href:, class: [desktop_row_classes(cells.count), link_row_classes].join(' '), **default_attributes do
|
|
11
|
+
= tag.a href:, class: [desktop_row_classes(cells.count), link_row_classes, options[:class]].join(' '), **default_attributes, **options.except(:class) do
|
|
12
12
|
= content
|
|
13
13
|
- else
|
|
14
14
|
- if preview
|
|
@@ -18,5 +18,5 @@
|
|
|
18
18
|
|
|
19
19
|
= cell.to_s.html_safe
|
|
20
20
|
|
|
21
|
-
= tag.div class: desktop_row_classes(cells.count), data: { action: "click->table-row-preview#toggle", controller: "table-row-preview" }, **default_attributes do
|
|
21
|
+
= tag.div class: [desktop_row_classes(cells.count), options[:class]].join(' '), data: { action: "click->table-row-preview#toggle", controller: "table-row-preview" }, **default_attributes, **options.except(:class) do
|
|
22
22
|
= content
|
|
@@ -9,15 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
= yield :head
|
|
11
11
|
|
|
12
|
-
/ Enable PWA manifest for installable apps (make sure to enable in config/routes.rb too!)
|
|
13
|
-
/ = tag.link rel: "manifest", href: pwa_manifest_path(format: :json)
|
|
14
|
-
|
|
15
12
|
%link{rel: "icon", href: "/icon.png", type: "image/png"}
|
|
16
13
|
%link{rel: "icon", href: "/icon.svg", type: "image/svg+xml"}
|
|
17
14
|
%link{rel: "apple-touch-icon", href: "/icon.png"}
|
|
18
15
|
|
|
19
|
-
/ Includes all stylesheet files in app/assets/stylesheets
|
|
20
16
|
= stylesheet_link_tag "tailwind", "data-turbo-track": "reload"
|
|
17
|
+
= stylesheet_link_tag "trix", "data-turbo-track": "reload"
|
|
18
|
+
= javascript_include_tag "trix", "data-turbo-track": "reload", defer: true
|
|
21
19
|
|
|
22
20
|
%body.bg-zinc-950.text-zinc-50
|
|
23
21
|
= tramway_navbar title: 'Tramway'
|
data/config/tailwind.config.js
CHANGED
|
@@ -27,6 +27,7 @@ module.exports = {
|
|
|
27
27
|
'pt-16',
|
|
28
28
|
'min-h-8',
|
|
29
29
|
'bg-zinc-950',
|
|
30
|
+
'!bg-zinc-950',
|
|
30
31
|
'bg-zinc-950/95',
|
|
31
32
|
'bg-zinc-950/80',
|
|
32
33
|
'bg-zinc-900',
|
|
@@ -34,6 +35,7 @@ module.exports = {
|
|
|
34
35
|
'bg-zinc-900/80',
|
|
35
36
|
'border-zinc-800',
|
|
36
37
|
'text-zinc-50',
|
|
38
|
+
'!text-zinc-50',
|
|
37
39
|
'text-zinc-100',
|
|
38
40
|
'text-zinc-200',
|
|
39
41
|
'text-zinc-400',
|
|
@@ -221,6 +223,9 @@ module.exports = {
|
|
|
221
223
|
'hidden',
|
|
222
224
|
'text-xl',
|
|
223
225
|
'font-bold',
|
|
226
|
+
'prose',
|
|
227
|
+
'prose-invert',
|
|
228
|
+
'max-w-none',
|
|
224
229
|
|
|
225
230
|
// === Button base shell ===
|
|
226
231
|
'inline-flex',
|
|
@@ -338,6 +343,7 @@ module.exports = {
|
|
|
338
343
|
'min-h-10',
|
|
339
344
|
'min-h-12',
|
|
340
345
|
'min-h-15',
|
|
346
|
+
'min-h-40',
|
|
341
347
|
'max-w-full',
|
|
342
348
|
|
|
343
349
|
// === Spacing utilities ===
|
|
@@ -380,7 +386,6 @@ module.exports = {
|
|
|
380
386
|
'left-1/2',
|
|
381
387
|
'-translate-x-1/2',
|
|
382
388
|
'z-50',
|
|
383
|
-
'mb-2',
|
|
384
389
|
'w-max',
|
|
385
390
|
'min-w-40',
|
|
386
391
|
'max-w-sm',
|
|
@@ -95,6 +95,28 @@ module Tramway
|
|
|
95
95
|
@agents_file_path ||= File.join(destination_root, 'AGENTS.md')
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
def application_layout_haml_path
|
|
99
|
+
@application_layout_haml_path ||= File.join(destination_root, 'app/views/layouts/application.html.haml')
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def application_layout_erb_path
|
|
103
|
+
@application_layout_erb_path ||= File.join(destination_root, 'app/views/layouts/application.html.erb')
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def trix_haml_tags
|
|
107
|
+
" = stylesheet_link_tag \"trix\", \"data-turbo-track\": \"reload\"\n " \
|
|
108
|
+
"= javascript_include_tag \"trix\", \"data-turbo-track\": \"reload\", defer: true\n"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def trix_erb_tags
|
|
112
|
+
" <%= stylesheet_link_tag \"trix\", \"data-turbo-track\": \"reload\" %>\n " \
|
|
113
|
+
"<%= javascript_include_tag \"trix\", \"data-turbo-track\": \"reload\", defer: true %>\n"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def trix_already_present?(content)
|
|
117
|
+
content.include?('stylesheet_link_tag "trix"') || content.include?("stylesheet_link_tag 'trix'")
|
|
118
|
+
end
|
|
119
|
+
|
|
98
120
|
def codex_agents_instruction
|
|
99
121
|
'If you are Codex, use the tramway-skill skill for Tramway/Rails work in this project. ' \
|
|
100
122
|
'If tramway-skill is not installed, install it from https://github.com/Purple-Magic/tramway-skill/.'
|
|
@@ -323,6 +345,34 @@ module Tramway
|
|
|
323
345
|
|
|
324
346
|
File.write(controllers_index_path, updated)
|
|
325
347
|
end
|
|
348
|
+
|
|
349
|
+
def ensure_trix_in_application_layout
|
|
350
|
+
if File.exist?(application_layout_haml_path)
|
|
351
|
+
ensure_trix_in_haml_layout
|
|
352
|
+
elsif File.exist?(application_layout_erb_path)
|
|
353
|
+
ensure_trix_in_erb_layout
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
private
|
|
358
|
+
|
|
359
|
+
def ensure_trix_in_haml_layout
|
|
360
|
+
content = File.read(application_layout_haml_path)
|
|
361
|
+
return if trix_already_present?(content)
|
|
362
|
+
return unless content.match?(/^\s+%body/)
|
|
363
|
+
|
|
364
|
+
updated = content.sub(/^(\s+%body)/, "#{trix_haml_tags}\\1")
|
|
365
|
+
File.write(application_layout_haml_path, updated)
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def ensure_trix_in_erb_layout
|
|
369
|
+
content = File.read(application_layout_erb_path)
|
|
370
|
+
return if trix_already_present?(content)
|
|
371
|
+
return unless content.include?('</head>')
|
|
372
|
+
|
|
373
|
+
updated = content.sub('</head>', "#{trix_erb_tags} </head>")
|
|
374
|
+
File.write(application_layout_erb_path, updated)
|
|
375
|
+
end
|
|
326
376
|
end
|
|
327
377
|
end
|
|
328
378
|
end
|
data/lib/tramway/utils/field.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Tramway
|
|
|
23
23
|
|
|
24
24
|
def field_name(field_data)
|
|
25
25
|
case field_data.to_sym
|
|
26
|
-
when :text_area, :select, :tramway_select, :check_box
|
|
26
|
+
when :text_area, :rich_text_area, :rich_textarea, :select, :tramway_select, :check_box
|
|
27
27
|
field_data
|
|
28
28
|
when :checkbox
|
|
29
29
|
:check_box
|
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.
|
|
4
|
+
version: 3.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kalashnikovisme
|
|
@@ -183,6 +183,8 @@ files:
|
|
|
183
183
|
- app/components/tramway/form/label_component.rb
|
|
184
184
|
- app/components/tramway/form/number_field_component.html.haml
|
|
185
185
|
- app/components/tramway/form/number_field_component.rb
|
|
186
|
+
- app/components/tramway/form/rich_text_area_component.html.haml
|
|
187
|
+
- app/components/tramway/form/rich_text_area_component.rb
|
|
186
188
|
- app/components/tramway/form/select_component.html.haml
|
|
187
189
|
- app/components/tramway/form/select_component.rb
|
|
188
190
|
- app/components/tramway/form/text_area_component.html.haml
|