brutalist_rails_ui 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 926531173316cb0b387b1797fbdd6c0d6dab22ef199c62fb72ec3dd888cb1c63
4
+ data.tar.gz: 8d53b13cda298e3b3a2b883f65085a7c32c267a86033461169fd03faf79414b7
5
+ SHA512:
6
+ metadata.gz: 3140365ce4b09dc1bf643f5783c6ebec46fa2cf8da2de1e896d9be59b58d79e1f7c062814dab893dbb5079ab67c91b26f282ee2e7f2c49c0c3431db544ed98f7
7
+ data.tar.gz: c7a80dd90bf304791176303e660cc6b6106e79668f1bfbc2e852c46af3b192018d745c390213b8b00ad20325a8d6da13fcba73b561ea4d9a45f6b55a25c211e3
data/README.md ADDED
@@ -0,0 +1,240 @@
1
+ # brutalist_rails_ui
2
+
3
+ Neobrutalist UI component library for Rails. Thick black borders, yellow accents, uppercase type, no rounded corners.
4
+
5
+ Built with Tailwind CSS v4 + Hotwire.
6
+
7
+ ## Installation
8
+
9
+ Add to your Gemfile:
10
+
11
+ ```ruby
12
+ gem "brutalist_rails_ui", path: "path/to/brutalist_rails_ui"
13
+ ```
14
+
15
+ Run the installer:
16
+
17
+ ```bash
18
+ bundle install
19
+ rails g brutalist_rails_ui:install
20
+ bin/rails tailwindcss:build
21
+ ```
22
+
23
+ Add to `app/helpers/application_helper.rb`:
24
+
25
+ ```ruby
26
+ module ApplicationHelper
27
+ include BrutalistRailsUi::Helpers
28
+ end
29
+ ```
30
+
31
+ The generator:
32
+ - Copies `brutalist_rails_ui.css` → `app/assets/tailwind/`
33
+ - Injects `@import "./brutalist_rails_ui"` into `application.css`
34
+ - Copies `modal_controller.js` → `app/javascript/controllers/`
35
+
36
+ Add `modal_controller` to your importmap in `application.html.erb`:
37
+
38
+ ```erb
39
+ "controllers/modal_controller": "<%= asset_path('controllers/modal_controller.js') %>"
40
+ ```
41
+
42
+ ## CSS Directives
43
+
44
+ | Class | Use |
45
+ |-------|-----|
46
+ | `.btn-primary` | Black button, yellow on hover |
47
+ | `.btn-secondary` | White button, yellow on hover |
48
+ | `.btn-danger` | Red button |
49
+ | `.input` | Form input field |
50
+ | `.label` | Form label |
51
+ | `.card` | White box with black border |
52
+ | `.card-header` | Black bar with white text (inside `.card`) |
53
+ | `.table-brutal` | Table with black header and dividers |
54
+ | `.badge` | Inline status pill |
55
+ | `.money-input` | Wrapper for `$`-prefixed number inputs |
56
+ | `.progress-bar` | Gray track with `.progress-bar-fill` inside |
57
+
58
+ ## View Helpers
59
+
60
+ ### `page_header`
61
+
62
+ ```erb
63
+ <%= page_header "Transactions" do %>
64
+ <%= link_to "+ Add", new_transaction_path, class: "btn-primary text-sm" %>
65
+ <% end %>
66
+
67
+ <%# With subtitle %>
68
+ <%= page_header "Unassigned", subtitle: "42 transactions need a category" %>
69
+ ```
70
+
71
+ ### `card`
72
+
73
+ ```erb
74
+ <%= card "Recent Activity" do %>
75
+ <p class="p-6">Content here</p>
76
+ <% end %>
77
+
78
+ <%# No header %>
79
+ <%= card do %>
80
+ <p class="p-6">Content</p>
81
+ <% end %>
82
+ ```
83
+
84
+ ### `card_header`
85
+
86
+ ```erb
87
+ <div class="card">
88
+ <%= card_header "Accounts", action_text: "View all", action_path: accounts_path %>
89
+ ...
90
+ </div>
91
+ ```
92
+
93
+ ### `empty_state`
94
+
95
+ ```erb
96
+ <%= empty_state icon: "✓", message: "All transactions assigned" %>
97
+
98
+ <%= empty_state icon: "📭", message: "No accounts yet" do %>
99
+ <%= link_to "Connect a bank", banks_link_path, class: "btn-primary mt-4" %>
100
+ <% end %>
101
+ ```
102
+
103
+ ### `kpi_box`
104
+
105
+ ```erb
106
+ <div class="grid grid-cols-2 gap-4">
107
+ <%= kpi_box label: "Total Spent", value: "$12.40" %>
108
+ <%= kpi_box label: "Total Calls", value: "42", dark: true %>
109
+ </div>
110
+ ```
111
+
112
+ ### `cta_banner`
113
+
114
+ ```erb
115
+ <%= cta_banner headline: "Connect a bank",
116
+ subtext: "Sync transactions automatically",
117
+ link_text: "Get Started",
118
+ path: banks_link_path %>
119
+ ```
120
+
121
+ ### `status_badge`
122
+
123
+ ```erb
124
+ <%= status_badge "pending" %>
125
+ <%= status_badge "over", "over" => "bg-red-600 text-white" %>
126
+ ```
127
+
128
+ ### `nav_link`
129
+
130
+ ```erb
131
+ <%= nav_link "Dashboard", root_path %>
132
+ <%= nav_link "Transactions", transactions_path %>
133
+ ```
134
+
135
+ ### `money` / `money_class`
136
+
137
+ ```erb
138
+ <span class="<%= money_class(transaction.amount) %>">
139
+ <%= money(transaction.amount) %>
140
+ </span>
141
+ ```
142
+
143
+ ## Partials
144
+
145
+ ### Modal
146
+
147
+ Wraps content in a Turbo Frame modal overlay with backdrop-click-to-close.
148
+
149
+ ```erb
150
+ <%# In your view (e.g. transactions/new.html.erb) %>
151
+ <%= render "brutalist_rails_ui/modal", title: "Add Transaction", width: "max-w-md" do %>
152
+ <%= render "form", transaction: @transaction %>
153
+ <% end %>
154
+ ```
155
+
156
+ Options:
157
+ - `title` — header text (required)
158
+ - `width` — Tailwind max-width class (default: `max-w-sm`)
159
+ - `frame_id` — turbo-frame id (default: `modal`)
160
+ - `body_class` — padding class for body wrapper (default: `p-6`)
161
+
162
+ Add `<turbo-frame id="modal"></turbo-frame>` to your layout.
163
+
164
+ ### Flash
165
+
166
+ ```erb
167
+ <%= render "brutalist_rails_ui/flash" %>
168
+ ```
169
+
170
+ ### Pagination
171
+
172
+ Requires [Pagy](https://github.com/ddnexus/pagy).
173
+
174
+ ```erb
175
+ <%= render "brutalist_rails_ui/pagination", pagy: @pagy %>
176
+ ```
177
+
178
+ ### Form buttons
179
+
180
+ ```erb
181
+ <%= render "brutalist_rails_ui/form_buttons",
182
+ f: f,
183
+ cancel_path: transactions_path,
184
+ submit_text: "Add Transaction" %>
185
+ ```
186
+
187
+ Options:
188
+ - `f` — form builder (required)
189
+ - `cancel_path` — cancel link href (required)
190
+ - `submit_text` — submit button label (default: `Save`)
191
+ - `cancel_text` — cancel button label (default: `Cancel`)
192
+ - `cancel_frame` — turbo frame for cancel link (default: `_top`)
193
+
194
+ ## Usage with WASM (wasm-rails)
195
+
196
+ When running inside [wasm-rails](https://github.com/emerson-argueta/wasm-rails), three extra steps are required because Bundler auto-require and engine view path registration don't work in the WASM environment.
197
+
198
+ ### 1. Explicit require in `config/application.rb`
199
+
200
+ `Bundler.require` is skipped in WASM, so add an explicit require alongside your other gems:
201
+
202
+ ```ruby
203
+ require "wasm_rails"
204
+ require "brutalist_rails_ui"
205
+ require "turbo-rails"
206
+ ```
207
+
208
+ ### 2. Include helpers in `ApplicationHelper`
209
+
210
+ Rails hooks like `ActiveSupport.on_load` and `config.to_prepare` don't fire reliably in WASM. Include helpers directly instead:
211
+
212
+ ```ruby
213
+ module ApplicationHelper
214
+ include BrutalistRailsUi::Helpers
215
+ end
216
+ ```
217
+
218
+ ### 3. Bundle the gem's ERB partials
219
+
220
+ Add `brutalist_rails_ui` to `GEM_EXTRA_PATHS` in `bin/build_app_bundle.mjs` so the gem's `app/views` are included in the WASM bundle:
221
+
222
+ ```js
223
+ const GEM_EXTRA_PATHS = {
224
+ 'turbo-rails': ['app/controllers', 'app/controllers/concerns', 'app/helpers', 'app/models', 'app/models/concerns', 'app/views'],
225
+ 'brutalist_rails_ui': ['app/views'],
226
+ };
227
+ ```
228
+
229
+ Then rebuild:
230
+
231
+ ```bash
232
+ npm run build:app
233
+ ```
234
+
235
+ ## Requirements
236
+
237
+ - Ruby 3.1+
238
+ - Rails 7.1+
239
+ - Tailwind CSS v4 (via tailwindcss-rails)
240
+ - Hotwire / Stimulus (for modal controller)
@@ -0,0 +1,7 @@
1
+ <% if notice.present? %>
2
+ <div id="flash" class="border-2 border-black bg-yellow-400 p-3 text-sm font-bold mb-4"><%= notice %></div>
3
+ <% elsif alert.present? %>
4
+ <div id="flash" class="border-2 border-black bg-red-500 text-white p-3 text-sm font-bold mb-4"><%= alert %></div>
5
+ <% else %>
6
+ <div id="flash"></div>
7
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <div class="flex justify-end gap-2 pt-2">
2
+ <%= link_to local_assigns.fetch(:cancel_text, "Cancel"), cancel_path,
3
+ class: "btn-secondary",
4
+ data: { turbo_frame: local_assigns.fetch(:cancel_frame, "_top") } %>
5
+ <%= f.submit local_assigns.fetch(:submit_text, "Save"), class: "btn-primary" %>
6
+ </div>
@@ -0,0 +1,15 @@
1
+ <turbo-frame id="<%= local_assigns.fetch(:frame_id, "modal") %>">
2
+ <div class="fixed inset-0 bg-black/60 flex items-center justify-content z-50"
3
+ data-controller="modal"
4
+ data-action="click->modal#closeOnBackdrop">
5
+ <div class="bg-white border-2 border-black w-full <%= local_assigns.fetch(:width, "max-w-sm") %> overflow-hidden mx-auto"
6
+ data-modal-target="panel">
7
+ <div class="px-6 py-3 bg-black">
8
+ <h2 class="text-sm font-black text-white uppercase tracking-wider"><%= title %></h2>
9
+ </div>
10
+ <div class="<%= local_assigns.fetch(:body_class, "p-6") %>">
11
+ <%= yield %>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </turbo-frame>
@@ -0,0 +1,13 @@
1
+ <% if pagy.last > 1 %>
2
+ <div class="flex items-center justify-between mt-4 text-sm font-bold border-2 border-black px-4 py-3 bg-white">
3
+ <span class="text-xs uppercase tracking-wide">Showing <%= pagy.from %>–<%= pagy.to %> of <%= pagy.count %></span>
4
+ <div class="flex gap-0">
5
+ <% if pagy.previous %>
6
+ <%= link_to "← Prev", url_for(page: pagy.previous), class: "px-3 py-1 border-2 border-black hover:bg-yellow-400 font-bold text-xs" %>
7
+ <% end %>
8
+ <% if pagy.next %>
9
+ <%= link_to "Next →", url_for(page: pagy.next), class: "px-3 py-1 border-2 border-black hover:bg-yellow-400 font-bold text-xs" %>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+ <% end %>
@@ -0,0 +1,4 @@
1
+ module BrutalistRailsUi
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,138 @@
1
+ module BrutalistRailsUi
2
+ module Helpers
3
+ # Nav link that highlights when active.
4
+ # Pass mobile: true for the vertical mobile menu variant.
5
+ def nav_link(label, path, mobile: false, **options)
6
+ base = path.split("?").first
7
+ active = current_page?(path) || (base != "/" && request.path.start_with?(base))
8
+ if mobile
9
+ classes = active \
10
+ ? "block bg-yellow-400 text-black px-4 py-3 text-sm font-bold border-b border-gray-700" \
11
+ : "block text-white hover:bg-gray-800 px-4 py-3 text-sm font-bold border-b border-gray-700"
12
+ else
13
+ classes = active \
14
+ ? "bg-yellow-400 text-black px-3 py-4 text-sm font-bold border-r border-l border-yellow-400" \
15
+ : "text-white hover:bg-white hover:text-black px-3 py-4 text-sm font-bold border-r border-gray-700 last:border-r-0"
16
+ end
17
+ link_to label, path, class: classes, **options
18
+ end
19
+
20
+ # Page header row: h1 title + optional action buttons block.
21
+ #
22
+ # <%= page_header "Transactions" do %>
23
+ # <%= link_to "+ Add", new_transaction_path, class: "btn-primary" %>
24
+ # <% end %>
25
+ def page_header(title, subtitle: nil, &block)
26
+ content_tag :div, class: "flex flex-wrap items-center justify-between gap-3 mb-6" do
27
+ concat content_tag(:div) {
28
+ concat content_tag(:h1, title, class: "text-2xl font-black text-black uppercase tracking-tight")
29
+ concat content_tag(:p, subtitle, class: "text-sm font-bold text-gray-500 mt-1 uppercase tracking-wide") if subtitle
30
+ }
31
+ concat content_tag(:div, capture(&block), class: "flex flex-wrap items-center gap-2") if block
32
+ end
33
+ end
34
+
35
+ # White card with optional black header bar.
36
+ #
37
+ # <%= card "Recent Transactions" do %>
38
+ # <p class="p-6">Content here</p>
39
+ # <% end %>
40
+ def card(title = nil, &block)
41
+ content_tag :div, class: "bg-white border-2 border-black overflow-hidden" do
42
+ if title
43
+ concat content_tag(:div, class: "px-6 py-3 bg-black") {
44
+ content_tag(:h2, title, class: "text-xs font-bold text-white uppercase tracking-wider")
45
+ }
46
+ end
47
+ concat capture(&block)
48
+ end
49
+ end
50
+
51
+ # Card header bar with optional right-side action.
52
+ #
53
+ # <%= card_header "Accounts", action_text: "View all", action_path: accounts_path %>
54
+ def card_header(title, action_text: nil, action_path: nil)
55
+ content_tag :div, class: "px-6 py-3 bg-black flex items-center justify-between" do
56
+ concat content_tag(:h2, title, class: "text-xs font-bold text-white uppercase tracking-wider")
57
+ if action_text && action_path
58
+ concat link_to(action_text, action_path, class: "text-xs text-yellow-400 hover:text-white font-bold")
59
+ end
60
+ end
61
+ end
62
+
63
+ # Centered empty state with icon and message.
64
+ #
65
+ # <%= empty_state icon: "✓", message: "All transactions assigned" %>
66
+ # <%= empty_state icon: "📭", message: "No accounts yet" do %>
67
+ # <%= link_to "Connect a bank", banks_link_path, class: "btn-primary mt-4" %>
68
+ # <% end %>
69
+ def empty_state(icon: nil, message:, &block)
70
+ content_tag :div, class: "px-6 py-12 text-center" do
71
+ concat content_tag(:p, icon, class: "text-3xl mb-3") if icon
72
+ concat content_tag(:p, message, class: "font-black text-black uppercase tracking-wide")
73
+ concat capture(&block) if block
74
+ end
75
+ end
76
+
77
+ # KPI stat box for summary grids.
78
+ #
79
+ # <div class="grid grid-cols-2 gap-4">
80
+ # <%= kpi_box label: "Total Spent", value: "$12.40" %>
81
+ # <%= kpi_box label: "Total Calls", value: "42", dark: true %>
82
+ # </div>
83
+ def kpi_box(label:, value:, dark: false)
84
+ bg = dark ? "bg-black text-white" : "bg-white border-2 border-black text-black"
85
+ label_class = dark ? "text-xs font-bold uppercase tracking-widest text-gray-400 mb-1" \
86
+ : "text-xs font-bold uppercase tracking-widest text-gray-500 mb-1"
87
+ content_tag :div, class: "#{bg} p-5" do
88
+ concat content_tag(:p, label, class: label_class)
89
+ concat content_tag(:p, value, class: "text-2xl font-black")
90
+ end
91
+ end
92
+
93
+ # Yellow CTA banner with headline and action link.
94
+ #
95
+ # <%= cta_banner headline: "Connect a bank",
96
+ # subtext: "Sync transactions automatically",
97
+ # link_text: "Get Started",
98
+ # path: banks_link_path %>
99
+ def cta_banner(headline:, subtext: nil, link_text:, path:, **link_options)
100
+ content_tag :div, class: "border-2 border-black bg-yellow-400 p-6 flex items-center justify-between gap-4" do
101
+ concat content_tag(:div) {
102
+ concat content_tag(:p, headline, class: "font-black text-black uppercase")
103
+ concat content_tag(:p, subtext, class: "text-sm text-black mt-1 font-bold") if subtext
104
+ }
105
+ concat link_to(link_text, path, class: "btn-primary flex-shrink-0", **link_options)
106
+ end
107
+ end
108
+
109
+ # Status badge pill.
110
+ #
111
+ # <%= status_badge "pending" %>
112
+ # <%= status_badge "funded", "funded" => "bg-green-600 text-white" %>
113
+ def status_badge(status, color_map = {})
114
+ defaults = {
115
+ "active" => "bg-black text-white",
116
+ "funded" => "bg-black text-white",
117
+ "over" => "bg-red-600 text-white",
118
+ "pending" => "bg-yellow-400 text-black",
119
+ "income" => "bg-black text-white",
120
+ "transfer" => "bg-white text-black",
121
+ "untracked" => "bg-white text-black"
122
+ }.merge(color_map)
123
+ color = defaults[status.to_s] || "bg-white text-black"
124
+ tag.span status.to_s.humanize,
125
+ class: "inline-flex items-center border-2 border-black px-2 py-0.5 text-xs font-bold uppercase tracking-wide #{color}"
126
+ end
127
+
128
+ # Format a number as currency.
129
+ def money(amount)
130
+ number_to_currency(amount, unit: "$", precision: 2)
131
+ end
132
+
133
+ # CSS class for positive/negative amounts.
134
+ def money_class(amount)
135
+ amount.to_f.negative? ? "text-red-600" : "text-black"
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,3 @@
1
+ module BrutalistRailsUi
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ require "brutalist_rails_ui/version"
2
+ require "brutalist_rails_ui/helpers"
3
+ require "brutalist_rails_ui/engine" if defined?(Rails)
@@ -0,0 +1,34 @@
1
+ require "rails/generators"
2
+
3
+ module BrutalistRailsUi
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ desc "Installs BrutalistRailsUi CSS and Stimulus modal controller"
9
+
10
+ def copy_css
11
+ copy_file "brutalist_rails_ui.css", "app/assets/tailwind/brutalist_rails_ui.css"
12
+ inject_into_file "app/assets/tailwind/application.css",
13
+ %(@import "./brutalist_rails_ui";\n),
14
+ after: %(@import "tailwindcss";\n)
15
+ rescue Thor::Error
16
+ say_status :skip, "Could not inject import — add '@import \"./brutalist_rails_ui\";' to app/assets/tailwind/application.css manually", :yellow
17
+ end
18
+
19
+ def copy_modal_controller
20
+ copy_file "modal_controller.js", "app/javascript/controllers/modal_controller.js"
21
+ end
22
+
23
+ def done
24
+ say ""
25
+ say "BrutalistRailsUi installed!", :green
26
+ say ""
27
+ say " 1. Rebuild Tailwind: bin/rails tailwindcss:build"
28
+ say " 2. Add modal to your layout's importmap (if using importmap-rails):"
29
+ say " \"controllers/modal_controller\": asset_path('controllers/modal_controller.js')"
30
+ say ""
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,88 @@
1
+ @layer components {
2
+ /* Buttons */
3
+ .btn-primary {
4
+ @apply inline-flex items-center px-4 py-2 text-sm font-bold bg-black text-white hover:bg-yellow-400 hover:text-black border-2 border-black cursor-pointer;
5
+ }
6
+
7
+ .btn-secondary {
8
+ @apply inline-flex items-center px-4 py-2 text-sm font-bold bg-white text-black hover:bg-yellow-400 border-2 border-black cursor-pointer;
9
+ }
10
+
11
+ .btn-danger {
12
+ @apply inline-flex items-center px-4 py-2 text-sm font-bold bg-red-600 text-white hover:bg-red-700 border-2 border-black cursor-pointer;
13
+ }
14
+
15
+ /* Form controls */
16
+ .input {
17
+ @apply w-full border-2 border-black px-3 py-2 text-sm font-mono focus:outline-none focus:border-black bg-white;
18
+ }
19
+
20
+ .label {
21
+ @apply block text-xs font-bold uppercase tracking-wide mb-1;
22
+ }
23
+
24
+ /* Layout */
25
+ .card {
26
+ @apply bg-white border-2 border-black overflow-hidden;
27
+ }
28
+
29
+ .card-header {
30
+ @apply px-6 py-3 bg-black;
31
+ }
32
+
33
+ /* Table */
34
+ .table-brutal {
35
+ @apply w-full;
36
+ }
37
+
38
+ .table-brutal thead {
39
+ @apply bg-black;
40
+ }
41
+
42
+ .table-brutal thead th {
43
+ @apply px-6 py-3 text-left text-xs font-bold text-gray-400 uppercase tracking-wider;
44
+ }
45
+
46
+ .table-brutal tbody {
47
+ @apply divide-y-2 divide-black bg-white;
48
+ }
49
+
50
+ .table-brutal tbody tr {
51
+ @apply hover:bg-gray-50;
52
+ }
53
+
54
+ .table-brutal tbody td {
55
+ @apply px-6 py-3 text-sm;
56
+ }
57
+
58
+ /* Badge */
59
+ .badge {
60
+ @apply inline-flex items-center border-2 border-black px-2 py-0.5 text-xs font-bold uppercase tracking-wide;
61
+ }
62
+
63
+ /* Money input wrapper */
64
+ .money-input {
65
+ @apply relative;
66
+ }
67
+
68
+ .money-input .money-prefix {
69
+ @apply absolute left-3 top-1/2 -translate-y-1/2 text-gray-500 text-sm font-bold pointer-events-none;
70
+ }
71
+
72
+ .money-input .input {
73
+ @apply pl-7;
74
+ }
75
+
76
+ /* Progress bar */
77
+ .progress-bar {
78
+ @apply h-2 bg-gray-200 overflow-hidden;
79
+ }
80
+
81
+ .progress-bar-fill {
82
+ @apply h-full bg-black transition-all;
83
+ }
84
+
85
+ .progress-bar-fill.over {
86
+ @apply bg-red-600;
87
+ }
88
+ }
@@ -0,0 +1,16 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static targets = ["panel"]
5
+
6
+ closeOnBackdrop(event) {
7
+ if (this.hasPanelTarget && !this.panelTarget.contains(event.target)) {
8
+ this.close()
9
+ }
10
+ }
11
+
12
+ close() {
13
+ const frame = this.element.closest("turbo-frame")
14
+ if (frame) frame.innerHTML = ""
15
+ }
16
+ }
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: brutalist_rails_ui
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Emerson Argueta
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-05-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: railties
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '7.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionview
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '7.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '7.1'
41
+ description:
42
+ email:
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - README.md
48
+ - app/views/brutalist_rails_ui/_flash.html.erb
49
+ - app/views/brutalist_rails_ui/_form_buttons.html.erb
50
+ - app/views/brutalist_rails_ui/_modal.html.erb
51
+ - app/views/brutalist_rails_ui/_pagination.html.erb
52
+ - lib/brutalist_rails_ui.rb
53
+ - lib/brutalist_rails_ui/engine.rb
54
+ - lib/brutalist_rails_ui/helpers.rb
55
+ - lib/brutalist_rails_ui/version.rb
56
+ - lib/generators/brutalist_rails_ui/install/install_generator.rb
57
+ - lib/generators/brutalist_rails_ui/install/templates/brutalist_rails_ui.css
58
+ - lib/generators/brutalist_rails_ui/install/templates/modal_controller.js
59
+ homepage:
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.5.9
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Neobrutalist UI components for Rails — Tailwind directives, view helpers,
82
+ and partials.
83
+ test_files: []