maquina-components 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0f4bc77b94379658acd2eb8a4861dd9e93c70ae5030553892eae3e8ec8ce660
4
- data.tar.gz: 84502d8a40444a30ec4d3d113c53cb495dbed92e683c62b855877b73097f6fbf
3
+ metadata.gz: 61b5b2a30e1774c16e25bc87743e5b29e1e8ede10e55f76fbd0ab953108921f4
4
+ data.tar.gz: 7d932af15e3e997b0e369e54e5189c18f7ebb6ce407150957323444f70199aa5
5
5
  SHA512:
6
- metadata.gz: 54af9ab2d08c6f8e74a0722377573aaa8434f28d8c592daff680ad660d14f666b78fc8c16aebfcaac13b1a715e7e1c7f3376368802cc956aba533b1b5915d0f2
7
- data.tar.gz: a4044c1f428042c543f940bc601ccb02eb9f88250fd84226cdb6f9b73a04817ecadc23bf93c8ee7951a9ab54afdb6c728490b3a85ddb1190dc35eea74008fc50
6
+ metadata.gz: 4476d4fa6fa5cd882706e2a64a25ae8a5537b1f8d5d214f7d0960a7fc2b294f1d3f034b283be0979cd9e8f23290b4e7b46c2baf81c011727fa0b33551dea0a60
7
+ data.tar.gz: 53cd0563b8e6ce33ab34fd38ba19cec938514a1d0be558b4c6e95a36fffcd2068b25f9f7e07e2fde12f61c9a30e62f6e16f5b41bb56233b1b9fe5bd77a5adeee
data/README.md CHANGED
@@ -1,28 +1,214 @@
1
- # MaquinaComponents
2
- Short description and motivation.
1
+ # Maquina Components
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ Modern UI components for Ruby on Rails, powered by TailwindCSS and Stimulus
4
+
5
+ ![Dashboard Example](/imgs/home.png)
6
+
7
+ ![Form Example](/imgs/new.png)
8
+
9
+ ## Overview
10
+
11
+ Maquina Components provides a collection of ready-to-use UI components for Ruby on Rails applications. Built with ERB,
12
+ TailwindCSS 4.0, and Stimulus, it offers a modern and maintainable approach to building beautiful user interfaces
13
+ without the complexity of JavaScript frameworks.
14
+
15
+ ### Key Features
16
+
17
+ - 🎨 Pre-built UI components based on shadcn/ui design system
18
+ - ⚡️ Powered by TailwindCSS 4.0
19
+ - 🧩 Seamless Rails integration with ERB partials
20
+ - 📱 Fully responsive components
21
+ - 🎯 Interactive behaviors with Stimulus controllers
22
+ - 🌙 Dark mode support out of the box
23
+ - ♿️ Accessibility-first components
6
24
 
7
25
  ## Installation
26
+
8
27
  Add this line to your application's Gemfile:
9
28
 
10
29
  ```ruby
11
- gem "maquina_components"
30
+ gem 'maquina-components'
12
31
  ```
13
32
 
14
- And then execute:
33
+ Then execute:
34
+
15
35
  ```bash
16
- $ bundle
36
+ bundle install
17
37
  ```
18
38
 
19
- Or install it yourself as:
20
- ```bash
21
- $ gem install maquina_components
39
+ ### Setup
40
+
41
+ 1. Install TailwindCSS 4.0 in your Rails application
42
+ 2. Add the required Stimulus controllers to your application
43
+ 3. Use Shadcn/UI standard color variables:
44
+
45
+ ```css
46
+ /* app/assets/stylesheets/application.css */
47
+
48
+ @theme {
49
+ /* Default background color of <body />...etc */
50
+ --color-background: var(--background);
51
+ --color-foreground: var(--foreground);
52
+
53
+ /* Primary colors for Button */
54
+ --color-primary: var(--primary-color);
55
+ --color-primary-foreground: var(--primary-foreground-color);
56
+
57
+ /* Muted colors */
58
+ --color-muted: var(--muted);
59
+ --color-muted-foreground: var(--muted-foreground);
60
+
61
+ /* Secondary colors */
62
+ --color-secondary: var(--secondary);
63
+ --color-secondary-foreground: var(--secondary-foreground);
64
+
65
+ /* Accent colors */
66
+ --color-accent: var(--accent);
67
+ --color-accent-foreground: var(--accent-foreground);
68
+
69
+ /* Destructive colors */
70
+ --color-destructive: var(--destructive);
71
+ --color-destructive-foreground: var(--destructive-foreground);
72
+
73
+ /* Default input color */
74
+ --color-input: var(--input);
75
+
76
+ /* Default border color */
77
+ --color-border: var(--border);
78
+
79
+ /* Default ring color */
80
+ --color-ring: var(--ring);
81
+ --color-ring-destructive: var(--destructive);
82
+
83
+ /* Background color for Card */
84
+ --color-card: var(--card);
85
+ --color-card-foreground: var(--card-foreground);
86
+
87
+ /* Sidebar colors */
88
+ --color-sidebar: var(--sidebar-background);
89
+ --color-sidebar-foreground: var(--sidebar-foreground);
90
+
91
+ --color-sidebar-primary: var(--sidebar-primary);
92
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
93
+
94
+ --color-sidebar-accent: var(--sidebar-accent);
95
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
96
+
97
+ --color-sidebar-ring: var(--sidebar-ring);
98
+ --color-sidebar-border: var(--sidebar-border);
99
+ }
100
+ ```
101
+
102
+ ## Usage
103
+
104
+ ### Basic Layout Example
105
+
106
+ ```erb
107
+ <%# app/views/layouts/application.html.erb %>
108
+ <body class="bg-background text-primary font-display antialiased">
109
+ <div class="flex min-h-screen">
110
+ <%= render "components/sidebar" do %>
111
+ <%= render "components/sidebar_header" do %>
112
+ <%= render "shared/ui/menu_button",
113
+ title: "My App",
114
+ subtitle: "Dashboard",
115
+ text_icon: "MA" %>
116
+ <% end %>
117
+
118
+ <%= render "components/sidebar_content" do %>
119
+ <!-- Sidebar content here -->
120
+ <% end %>
121
+ <% end %>
122
+
123
+ <main class="flex-1 pl-(--sidebar-width)">
124
+ <%= yield %>
125
+ </main>
126
+ </div>
127
+ </body>
128
+ ```
129
+
130
+ ### Components
131
+
132
+ #### Cards
133
+
134
+ ```erb
135
+ <%= render "components/card" do %>
136
+ <%= render "components/card_header",
137
+ title: "Account Balance",
138
+ icon: :dollar %>
139
+
140
+ <%= render "components/card_content" do %>
141
+ <p class="text-2xl font-bold">
142
+ <%= number_to_currency(@balance) %>
143
+ </p>
144
+ <p class="text-xs text-muted-foreground">
145
+ Current balance
146
+ </p>
147
+ <% end %>
148
+ <% end %>
149
+ ```
150
+
151
+ #### Buttons
152
+
153
+ ```erb
154
+ <%= link_to new_transaction_path, class: "button-primary" do %>
155
+ New Transaction
156
+ <%= icon_for(:money) %>
157
+ <% end %>
158
+ ```
159
+
160
+ ## Available Components
161
+
162
+ Work in progress...
163
+
164
+ - Layout
165
+ - Sidebar
166
+ - Card
167
+ - Navigation
168
+ - Menu Button
169
+ - Navigation Menu
170
+ - Elements
171
+ - Button
172
+ - Alert
173
+ - Badge
174
+ - Forms
175
+ - Input
176
+ - Select
177
+ - Checkbox
178
+ - Radio
179
+
180
+ ## Customization
181
+
182
+ ### Theme Configuration
183
+
184
+ Customize the look and feel of your components by modifying the theme variables:
185
+
186
+ ```css
187
+ @theme {
188
+ /* Colors */
189
+ --color-primary: oklch(21.34% 0 0);
190
+ --color-primary-foreground: oklch(98.48% 0 0);
191
+
192
+ /* Typography */
193
+ --font-display: "Inter var", "sans-serif";
194
+
195
+ /* Spacing */
196
+ --sidebar-width: 16rem;
197
+
198
+ /* ... other customizations ... */
199
+ }
22
200
  ```
23
201
 
24
202
  ## Contributing
25
- Contribution directions go here.
203
+
204
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/maquina-app/maquina_components>.
26
205
 
27
206
  ## License
207
+
28
208
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
209
+
210
+ ## Acknowledgments
211
+
212
+ - Design system inspired by [shadcn/ui](https://ui.shadcn.com/)
213
+ - Built with [TailwindCSS](https://tailwindcss.com/)
214
+ - Powered by [Ruby on Rails](https://rubyonrails.org/)
@@ -0,0 +1,99 @@
1
+ @utility button-base {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ gap: 0.5rem;
6
+ /* gap-2 */
7
+ white-space: nowrap;
8
+ border-radius: 0.375rem;
9
+ /* rounded-md */
10
+ font-size: 0.875rem;
11
+ /* text-sm */
12
+ font-weight: 500;
13
+ /* font-medium */
14
+ height: 2.25rem;
15
+ /* h-9 */
16
+ padding: 0.5rem 1rem;
17
+ /* px-4 py-2 */
18
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
19
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
20
+ transition-duration: 150ms;
21
+
22
+ &:focus-visible {
23
+ outline: none;
24
+ ring-width: 1px;
25
+ ring-color: var(--color-ring);
26
+ }
27
+
28
+ &:disabled {
29
+ pointer-events: none;
30
+ opacity: 0.5;
31
+ }
32
+
33
+ & svg {
34
+ pointer-events: none;
35
+ width: 1rem;
36
+ /* size-4 */
37
+ height: 1rem;
38
+ /* size-4 */
39
+ flex-shrink: 0;
40
+ }
41
+ }
42
+
43
+ /* Form */
44
+ .form-base {
45
+ @apply flex flex-col w-full gap-6;
46
+ }
47
+
48
+ .form-group {
49
+ @apply flex flex-col gap-2;
50
+ }
51
+
52
+ .form-label {
53
+ @apply text-foreground text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70;
54
+ }
55
+
56
+ .form-input {
57
+ @apply flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm;
58
+ }
59
+
60
+ .form-select {
61
+ @apply col-start-1 row-start-1 w-full appearance-none rounded-md bg-transparent py-1.5 pl-3 pr-8 text-base text-foreground border border-input shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm/6;
62
+ }
63
+
64
+ .form-select-group {
65
+ @apply grid grid-cols-1;
66
+
67
+ & svg {
68
+ @apply pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-muted-foreground sm:size-4;
69
+ }
70
+ }
71
+
72
+ .form-help-text {
73
+ @apply text-sm text-muted-foreground;
74
+ }
75
+
76
+ .form-error-text {
77
+ @apply text-sm text-destructive;
78
+ }
79
+
80
+ /* Buttons */
81
+ .button-primary {
82
+ @apply button-base bg-primary text-primary-foreground hover:bg-primary/90;
83
+ }
84
+
85
+ .button-secondary {
86
+ @apply button-base bg-secondary text-secondary-foreground hover:bg-secondary/80;
87
+ }
88
+
89
+ .button-ghost {
90
+ @apply button-base hover:bg-secondary hover:text-secondary-foreground;
91
+ }
92
+
93
+ .button-outline {
94
+ @apply button-base border border-border bg-background shadow-sm hover:bg-secondary/40 hover:text-secondary-foreground;
95
+ }
96
+
97
+ .button-destructive {
98
+ @apply button-base bg-destructive text-destructive shadow-sm hover:bg-destructive/90;
99
+ }
@@ -0,0 +1,124 @@
1
+ module Components
2
+ module IconsHelper
3
+ def icon_for(name, options = {})
4
+ return nil unless name
5
+
6
+ svg = icon_svg_for(name.to_sym)
7
+ return nil unless svg
8
+
9
+ css_classes = options[:class]
10
+ svg = svg.gsub('class="', "class=\"#{css_classes} ")
11
+
12
+ if options[:stroke_width]
13
+ svg = svg.gsub('stroke-width="2"', "stroke-width=\"#{options[:stroke_width]}\"")
14
+ end
15
+
16
+ svg.html_safe
17
+ end
18
+
19
+ private
20
+
21
+ def icon_svg_for(name)
22
+ case name
23
+ when :dollar
24
+ <<~SVG.freeze
25
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
26
+ <line x1="12" y1="2" x2="12" y2="22"></line>
27
+ <path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path>
28
+ </svg>
29
+ SVG
30
+ when :users
31
+ <<~SVG.freeze
32
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
33
+ <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path>
34
+ <circle cx="9" cy="7" r="4"></circle>
35
+ <path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"></path>
36
+ </svg>
37
+ SVG
38
+ when :credit_card
39
+ <<~SVG.freeze
40
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
41
+ <rect width="20" height="14" x="2" y="5" rx="2"></rect>
42
+ <line x1="2" y1="10" x2="22" y2="10"></line>
43
+ </svg>
44
+ SVG
45
+ when :activity
46
+ <<~SVG.freeze
47
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
48
+ <path d="M22 12h-4l-3 9L9 3l-3 9H2"></path>
49
+ </svg>
50
+ SVG
51
+ when :trend_up
52
+ <<~SVG.freeze
53
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
54
+ <polyline points="22 7 13.5 15.5 8.5 10.5 2 17"></polyline>
55
+ <polyline points="16 7 22 7 22 13"></polyline>
56
+ </svg>
57
+ SVG
58
+ when :trend_down
59
+ <<~SVG.freeze
60
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
61
+ <polyline points="22 17 13.5 8.5 8.5 13.5 2 7"></polyline>
62
+ <polyline points="16 17 22 17 22 11"></polyline>
63
+ </svg>
64
+ SVG
65
+ when :clock
66
+ <<~SVG.freeze
67
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
68
+ <circle cx="12" cy="12" r="10"></circle>
69
+ <polyline points="12 6 12 12 16 14"></polyline>
70
+ </svg>
71
+ SVG
72
+ when :money
73
+ <<~SVG.freeze
74
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
75
+ <rect width="20" height="12" x="2" y="6" rx="2"></rect>
76
+ <circle cx="12" cy="12" r="2"></circle>
77
+ <path d="M6 12h.01M18 12h.01"></path>
78
+ </svg>
79
+ SVG
80
+ when :line_chart
81
+ <<~SVG.freeze
82
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
83
+ <path d="M3 3v18h18"/><path d="m19 9-5 5-4-4-3 3"/>
84
+ </svg>
85
+ SVG
86
+ when :piggy_bank
87
+ <<~SVG.freeze
88
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
89
+ <path d="M19 5c-1.5 0-2.8 1.4-3 2-3.5-1.5-11-.3-11 5 0 1.8 0 3 2 4.5V20h4v-2h3v2h4v-4c1-.5 1.7-1 2-2h2v-4h-2c0-1-.5-1.5-1-2h0V5z"/>
90
+ <path d="M2 9v1c0 1.1.9 2 2 2h1"/>
91
+ <path d="M16 11h0"/>
92
+ </svg>
93
+ SVG
94
+ when :arrow_left
95
+ <<~SVG.freeze
96
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
97
+ <line x1="19" y1="12" x2="5" y2="12"></line>
98
+ <polyline points="12 19 5 12 12 5"></polyline>
99
+ </svg>
100
+ SVG
101
+ when :select_chevron
102
+ <<~SVG.freeze
103
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="" aria-hidden="true">
104
+ <path d="m6 9 6 6 6-6"></path>
105
+ </svg>
106
+ SVG
107
+ when :check
108
+ <<~SVG.freeze
109
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
110
+ <path d="M20 6 9 17l-5-5"/>
111
+ </svg>
112
+ SVG
113
+ when :circle_alert
114
+ <<~SVG.freeze
115
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="">
116
+ <circle cx="12" cy="12" r="10"/>
117
+ <line x1="12" x2="12" y1="8" y2="12"/>
118
+ <line x1="12" x2="12.01" y1="16" y2="16"/>
119
+ </svg>
120
+ SVG
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,15 @@
1
+ module Components
2
+ module PaginationHelper
3
+ def paginated_page_param(pagy, page)
4
+ @page_param ||= pagy.vars[:page_param] || Pagy::VARS[:page_param]
5
+ @query_parameters ||= request.query_parameters
6
+
7
+ @query_parameters.merge(@page_param => page)
8
+ end
9
+
10
+ def paginated_path(path_helper, pagy, page, param)
11
+ page_query = paginated_page_param(pagy, page)
12
+ send(path_helper, param, page_query)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ <%# locals: (title: nil) %>
2
+ <% if notice || alert %>
3
+ <div
4
+ role="alert"
5
+ class="<%= class_names('relative w-full rounded-lg border px-4 py-3 text-sm mx-auto mb-4 [&>svg]:size-4 [&>svg+div]:translate-y-(-3px) [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg~*]:pl-7 max-w-lg', '[&>svg]:text-foreground bg-background text-foreground': notice.present?, 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive': alert.present?) %>"
6
+ >
7
+ <%= icon_for(notice.present? ? :check : :circle_alert) %>
8
+ <h5 class="mb-1 font-medium leading-none tracking-tight"><%= title || (notice.present? ? "Éxito" : "Error") %></h5>
9
+ <div class="text-sm [&_p]:leading-relaxed"><%= notice %></div>
10
+ </div>
11
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <%# locals: (custom_classes: "") -%>
2
+
3
+ <div
4
+ class="<%= class_names(
5
+ "rounded-xl border border-border bg-card text-card-foreground shadow",
6
+ custom_classes
7
+ ) %>"
8
+ >
9
+ <%= yield %>
10
+ </div>
@@ -0,0 +1,5 @@
1
+ <%# locals: (custom_classes: "") -%>
2
+
3
+ <div class="<%= class_names("p-6 pt-0", custom_classes) %>">
4
+ <%= yield %>
5
+ </div>
@@ -0,0 +1,8 @@
1
+ <%# locals: (title:, custom_classes: "", icon: nil, icon_classes: "h-4 w-4 text-muted-foreground") -%>
2
+
3
+ <div
4
+ class="<%= class_names("p-6 flex flex-row items-center justify-between space-y-0 pb-2", custom_classes) %>"
5
+ >
6
+ <h3 class="tracking-tight text-sm font-medium"><%= title %></h3>
7
+ <%= icon_for(icon, class: icon_classes) if icon.present? %>
8
+ </div>
@@ -0,0 +1,34 @@
1
+ <%# locals: (pagy:, route_helper:, param: nil, data: {turbo_action: :replace}) %>
2
+ <nav class="mx-auto flex w-full justify-center mt-4">
3
+ <ul class="flex flex-row items-center gap-1">
4
+ <li>
5
+ <% if pagy.prev.present? %>
6
+ <%= link_to "Previo",
7
+ paginated_path(route_helper, pagy, pagy.prev, param),
8
+ class: "button-ghost",
9
+ data: data %>
10
+ <% else %>
11
+ <button class="button-ghost" disabled>Previo</button>
12
+ <% end %>
13
+ </li>
14
+ <% pagy.series.each do |page| %>
15
+ <li>
16
+ <%= link_to page,
17
+ paginated_path(route_helper, pagy, page, param),
18
+ class: class_names("button-ghost", "button-outline": page.is_a?(String)),
19
+ data: data %>
20
+ </li>
21
+ <% end %>
22
+
23
+ <li>
24
+ <% if pagy.next.present? %>
25
+ <%= link_to "Siguiente",
26
+ paginated_path(route_helper, pagy, pagy.next, param),
27
+ class: "button-ghost",
28
+ data: data %>
29
+ <% else %>
30
+ <button class="button-ghost" disabled>Siguiente</button>
31
+ <% end %>
32
+ </li>
33
+ </ul>
34
+ </nav>
@@ -0,0 +1,30 @@
1
+ <aside
2
+ class="group peer hidden md:block text-sidebar-foreground"
3
+ data-controller="sidebars"
4
+ data-state="expanded"
5
+ data-collapsible=""
6
+ id="sidebar"
7
+ >
8
+ <!-- Mobile overlay -->
9
+ <div
10
+ class="
11
+ inset-0 bg-black/80 lg:hidden transition-opacity duration-300 hidden
12
+ "
13
+ data-sidebar-target="overlay"
14
+ data-action="click->sidebar#toggleMobile"
15
+ >
16
+ </div>
17
+ <!-- Sidebar container -->
18
+ <div
19
+ class="
20
+ duration-200 fixed inset-y-0 z-10 h-svh w-(--sidebar-width)
21
+ transition-[left,right,width] ease-linear md:flex left-0 border-r
22
+ border-sidebar-border group-data-[collapsible=icon]:w-[--sidebar-width-icon]
23
+ "
24
+ data-sidebar-target="container"
25
+ >
26
+ <div class=" flex h-full w-full flex-col bg-sidebar">
27
+ <%= yield %>
28
+ </div>
29
+ </div>
30
+ </aside>
@@ -0,0 +1,8 @@
1
+ <div
2
+ class="
3
+ flex min-h-0 flex-1 flex-col gap-2 overflow-auto
4
+ group-data-[collapsible=icon]:overflow-hidden
5
+ "
6
+ >
7
+ <%= yield %>
8
+ </div>
@@ -0,0 +1,42 @@
1
+ <%# locals: (title: nil, title_action: {}, menu: []) -%>
2
+ <%- title ||= nil -%>
3
+ <%- title_action ||= {} -%>
4
+ <%- menu ||= [] -%>
5
+
6
+ <div class="relative flex w-full min-w-0 flex-col p-2">
7
+ <% if title.present? %>
8
+ <div
9
+ class="
10
+ duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium
11
+ text-sidebar-foreground/70 outline-none ring-sidebar-ring
12
+ transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4
13
+ [&>svg]:shrink-0 group-data-[collapsible=icon]:-mt-8
14
+ group-data-[collapsible=icon]:opacity-0
15
+ "
16
+ >
17
+ <%= title %>
18
+
19
+ <% if title_action.any? %>
20
+ <%= link_to title_action[:url], class: "flex aspect-square w-5 items-center justify-center rounded-md p-0 ml-auto text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0 after:absolute after:-inset-2 after:md:hidden" do %>
21
+ <%= render_icon(title_action[:icon]) %>
22
+ <span class="sr-only"><%= title_action[:title] %></span>
23
+ <% end %>
24
+ <% end %>
25
+ </div>
26
+ <% end %>
27
+
28
+ <% if menu.any? %>
29
+ <ul class="flex w-full min-w-0 flex-col gap-1">
30
+ <% menu.each do |item| %>
31
+ <li class="group/menu-item relative">
32
+ <%= sidebar_menu_item(
33
+ title: item[:title],
34
+ url: item[:url],
35
+ icon: item[:icon],
36
+ current: item[:active],
37
+ ) %>
38
+ </li>
39
+ <% end %>
40
+ </ul>
41
+ <% end %>
42
+ </div>
@@ -0,0 +1,3 @@
1
+ <div class="flex flex-col gap-2 p-2">
2
+ <%= yield %>
3
+ </div>
@@ -1,3 +1,3 @@
1
1
  module MaquinaComponents
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maquina-components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Alberto Chávez
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-01-15 00:00:00.000000000 Z
10
+ date: 2025-01-17 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -33,6 +33,18 @@ files:
33
33
  - MIT-LICENSE
34
34
  - README.md
35
35
  - Rakefile
36
+ - app/assets/stylesheets/maquina_components.css
37
+ - app/helpers/components/icons_helper.rb
38
+ - app/helpers/components/pagination_helper.rb
39
+ - app/views/components/_alert.html.erb
40
+ - app/views/components/_card.html.erb
41
+ - app/views/components/_card_content.html.erb
42
+ - app/views/components/_card_header.html.erb
43
+ - app/views/components/_pagination.html.erb
44
+ - app/views/components/_sidebar.html.erb
45
+ - app/views/components/_sidebar_content.html.erb
46
+ - app/views/components/_sidebar_group.html.erb
47
+ - app/views/components/_sidebar_header.html.erb
36
48
  - lib/maquina-components.rb
37
49
  - lib/maquina_components/engine.rb
38
50
  - lib/maquina_components/version.rb