rails-active-ui 0.3.3 → 0.3.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/app/components/input_component.rb +1 -0
- data/app/controllers/ui/examples_controller.rb +7 -0
- data/app/views/ui/examples/_behaviors.html.ruby +65 -0
- data/app/views/ui/examples/_collections.html.ruby +303 -0
- data/app/views/ui/examples/_elements.html.ruby +587 -0
- data/app/views/ui/examples/_globals.html.ruby +36 -0
- data/app/views/ui/examples/_layout_primitives.html.ruby +180 -0
- data/app/views/ui/examples/_modules_components.html.ruby +666 -0
- data/app/views/ui/examples/_views_components.html.ruby +301 -0
- data/app/views/ui/examples/index.html.ruby +61 -0
- data/config/routes.rb +2 -1
- data/lib/ui/version.rb +1 -1
- data/lib/ui/version.rb.erb +3 -0
- metadata +11 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0058e3cc403ae342263ae7ed336067515a465e050c833071d582e2724fa0a451'
|
|
4
|
+
data.tar.gz: 94956bddda4efa13eaf12fbed9de95fed87a999d33b871d80ae1ce992aa9de55
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b5fda493b980890c6a882563b8b04cb01f7e5b7b6a0df9dc567d5ccf6f565cd8d80fd78ab686b45cf7ed7e4ad43b2877269095730991cfb7b39c8d12cbd1ce91
|
|
7
|
+
data.tar.gz: 937f9a991da1899949b425735a5926c7a2277c6769a77b39822c918e59afb0454f0f69fbebb9c4c85895ee058ee1e39948d5a8f6f29e0dcaf4d9760de10513f5
|
|
@@ -63,6 +63,7 @@ class InputComponent < Component
|
|
|
63
63
|
input_opts[:value] = value if value
|
|
64
64
|
input_opts[:disabled] = "disabled" if disabled
|
|
65
65
|
input_opts[:id] = id if id
|
|
66
|
+
input_opts[:aria] = @html_options[:aria] if @html_options&.dig(:aria)
|
|
66
67
|
|
|
67
68
|
icon_el = icon ? tag.i(class: "#{icon} icon") : nil
|
|
68
69
|
input_el = tag.input(**input_opts)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# ------------------------------------------------------------------
|
|
2
|
+
# Api
|
|
3
|
+
# ------------------------------------------------------------------
|
|
4
|
+
Header(size: :h3) { text "Api" }
|
|
5
|
+
text "Wraps content with the fui-api Stimulus controller for making AJAX requests."
|
|
6
|
+
|
|
7
|
+
Segment {
|
|
8
|
+
Api(url: "/up", method_val: "get") {
|
|
9
|
+
Button(color: :blue) { text "Check Health" }
|
|
10
|
+
concat tag.div(class: "ui response") { "" }
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
Segment(secondary: true) {
|
|
15
|
+
concat tag.pre { tag.code(
|
|
16
|
+
'Api(url: "/up", method_val: "get") {
|
|
17
|
+
Button(color: :blue) { text "Check Health" }
|
|
18
|
+
concat tag.div(class: "ui response") { "" }
|
|
19
|
+
}'
|
|
20
|
+
)}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Divider(hidden: true)
|
|
24
|
+
|
|
25
|
+
# ------------------------------------------------------------------
|
|
26
|
+
# State
|
|
27
|
+
# ------------------------------------------------------------------
|
|
28
|
+
Header(size: :h3) { text "State" }
|
|
29
|
+
text "Manages active/inactive states on an element, toggling text and CSS classes."
|
|
30
|
+
|
|
31
|
+
Segment {
|
|
32
|
+
State(text_active: "Following", text_inactive: "Follow", class_active: "green", class_inactive: "") {
|
|
33
|
+
Button(color: :blue) { text "Follow" }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Segment(secondary: true) {
|
|
38
|
+
concat tag.pre { tag.code(
|
|
39
|
+
'State(text_active: "Following", text_inactive: "Follow", class_active: "green", class_inactive: "") {
|
|
40
|
+
Button(color: :blue) { text "Follow" }
|
|
41
|
+
}'
|
|
42
|
+
)}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Divider(hidden: true)
|
|
46
|
+
|
|
47
|
+
# ------------------------------------------------------------------
|
|
48
|
+
# Visibility
|
|
49
|
+
# ------------------------------------------------------------------
|
|
50
|
+
Header(size: :h3) { text "Visibility" }
|
|
51
|
+
text "Tracks element visibility in the viewport and fires callbacks on scroll events."
|
|
52
|
+
|
|
53
|
+
Segment {
|
|
54
|
+
Visibility(once: true, offset: 50) {
|
|
55
|
+
Segment { text "This element tracks its visibility in the viewport." }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Segment(secondary: true) {
|
|
60
|
+
concat tag.pre { tag.code(
|
|
61
|
+
'Visibility(once: true, offset: 50) {
|
|
62
|
+
Segment { text "This element tracks its visibility in the viewport." }
|
|
63
|
+
}'
|
|
64
|
+
)}
|
|
65
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# ------------------------------------------------------------------
|
|
2
|
+
# Breadcrumb
|
|
3
|
+
# ------------------------------------------------------------------
|
|
4
|
+
Header(size: :h3) { text "Breadcrumb" }
|
|
5
|
+
text "A breadcrumb trail for navigation hierarchy."
|
|
6
|
+
|
|
7
|
+
Segment {
|
|
8
|
+
Breadcrumb(size: :large) {
|
|
9
|
+
concat tag.a("Home", class: "section", href: "#")
|
|
10
|
+
concat tag.div(class: "divider") { "/" }
|
|
11
|
+
concat tag.a("Store", class: "section", href: "#")
|
|
12
|
+
concat tag.div(class: "divider") { "/" }
|
|
13
|
+
concat tag.div(class: "active section") { "T-Shirt" }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
Segment(secondary: true) {
|
|
18
|
+
concat tag.pre { tag.code(
|
|
19
|
+
'Breadcrumb(size: :large) {
|
|
20
|
+
concat tag.a("Home", class: "section", href: "#")
|
|
21
|
+
concat tag.div(class: "divider") { "/" }
|
|
22
|
+
concat tag.a("Store", class: "section", href: "#")
|
|
23
|
+
concat tag.div(class: "divider") { "/" }
|
|
24
|
+
concat tag.div(class: "active section") { "T-Shirt" }
|
|
25
|
+
}'
|
|
26
|
+
)}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
Divider(hidden: true)
|
|
30
|
+
|
|
31
|
+
# ------------------------------------------------------------------
|
|
32
|
+
# Form
|
|
33
|
+
# ------------------------------------------------------------------
|
|
34
|
+
Header(size: :h3) { text "Form" }
|
|
35
|
+
text "A styled form with field layout and validation states."
|
|
36
|
+
|
|
37
|
+
Segment {
|
|
38
|
+
Form {
|
|
39
|
+
concat tag.div(class: "field") {
|
|
40
|
+
safe_join([
|
|
41
|
+
tag.label("Name"),
|
|
42
|
+
tag.input(type: "text", placeholder: "Full Name")
|
|
43
|
+
])
|
|
44
|
+
}
|
|
45
|
+
concat tag.div(class: "field") {
|
|
46
|
+
safe_join([
|
|
47
|
+
tag.label("Email"),
|
|
48
|
+
tag.input(type: "email", placeholder: "email@example.com")
|
|
49
|
+
])
|
|
50
|
+
}
|
|
51
|
+
concat tag.div(class: "fields") {
|
|
52
|
+
safe_join([
|
|
53
|
+
tag.div(class: "eight wide field") {
|
|
54
|
+
safe_join([tag.label("First Name"), tag.input(type: "text", placeholder: "First Name")])
|
|
55
|
+
},
|
|
56
|
+
tag.div(class: "eight wide field") {
|
|
57
|
+
safe_join([tag.label("Last Name"), tag.input(type: "text", placeholder: "Last Name")])
|
|
58
|
+
}
|
|
59
|
+
])
|
|
60
|
+
}
|
|
61
|
+
Button(color: :blue, type: :submit) { text "Submit" }
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Segment(secondary: true) {
|
|
66
|
+
concat tag.pre { tag.code(
|
|
67
|
+
'Form {
|
|
68
|
+
concat tag.div(class: "field") {
|
|
69
|
+
safe_join([
|
|
70
|
+
tag.label("Name"),
|
|
71
|
+
tag.input(type: "text", placeholder: "Full Name")
|
|
72
|
+
])
|
|
73
|
+
}
|
|
74
|
+
concat tag.div(class: "field") {
|
|
75
|
+
safe_join([
|
|
76
|
+
tag.label("Email"),
|
|
77
|
+
tag.input(type: "email", placeholder: "email@example.com")
|
|
78
|
+
])
|
|
79
|
+
}
|
|
80
|
+
Button(color: :blue, type: :submit) { text "Submit" }
|
|
81
|
+
}'
|
|
82
|
+
)}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Divider(hidden: true)
|
|
86
|
+
|
|
87
|
+
# ------------------------------------------------------------------
|
|
88
|
+
# Grid (more detailed, already shown in layout)
|
|
89
|
+
# ------------------------------------------------------------------
|
|
90
|
+
Header(size: :h3) { text "Grid" }
|
|
91
|
+
text "A responsive grid system with column width, stacking, and alignment controls."
|
|
92
|
+
|
|
93
|
+
Segment {
|
|
94
|
+
Grid(columns: 2, stackable: true, celled: "internally") {
|
|
95
|
+
Row(centered: true) {
|
|
96
|
+
Column(width: 6) {
|
|
97
|
+
Segment(basic: true) { text "6 wide centered" }
|
|
98
|
+
}
|
|
99
|
+
Column(width: 6) {
|
|
100
|
+
Segment(basic: true) { text "6 wide centered" }
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
Row {
|
|
104
|
+
Column(width: 4) {
|
|
105
|
+
Segment(basic: true) { text "4 wide" }
|
|
106
|
+
}
|
|
107
|
+
Column(width: 8) {
|
|
108
|
+
Segment(basic: true) { text "8 wide" }
|
|
109
|
+
}
|
|
110
|
+
Column(width: 4) {
|
|
111
|
+
Segment(basic: true) { text "4 wide" }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
Segment(secondary: true) {
|
|
118
|
+
concat tag.pre { tag.code(
|
|
119
|
+
'Grid(columns: 2, stackable: true, celled: "internally") {
|
|
120
|
+
Row(centered: true) {
|
|
121
|
+
Column(width: 6) { Segment(basic: true) { text "6 wide" } }
|
|
122
|
+
Column(width: 6) { Segment(basic: true) { text "6 wide" } }
|
|
123
|
+
}
|
|
124
|
+
}'
|
|
125
|
+
)}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
Divider(hidden: true)
|
|
129
|
+
|
|
130
|
+
# ------------------------------------------------------------------
|
|
131
|
+
# Menu / MenuItem / SubMenu
|
|
132
|
+
# ------------------------------------------------------------------
|
|
133
|
+
Header(size: :h3) { text "Menu / MenuItem / SubMenu" }
|
|
134
|
+
text "Navigation menus with items, submenus, and various styles."
|
|
135
|
+
|
|
136
|
+
Segment {
|
|
137
|
+
Menu {
|
|
138
|
+
MenuItem(active: true, href: "#") { text "Home" }
|
|
139
|
+
MenuItem(href: "#") { text "Messages" }
|
|
140
|
+
MenuItem(href: "#") { text "Friends" }
|
|
141
|
+
SubMenu(position: "right") {
|
|
142
|
+
MenuItem {
|
|
143
|
+
Input(placeholder: "Search...", icon: "search")
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
Divider(hidden: true)
|
|
149
|
+
|
|
150
|
+
Menu(secondary: true, pointing: true) {
|
|
151
|
+
MenuItem(active: true) { text "Active" }
|
|
152
|
+
MenuItem { text "Tab Two" }
|
|
153
|
+
MenuItem { text "Tab Three" }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Divider(hidden: true)
|
|
157
|
+
|
|
158
|
+
Menu(vertical: true, pointing: true) {
|
|
159
|
+
MenuItem(active: true) { text "Dashboard" }
|
|
160
|
+
MenuItem { text "Settings" }
|
|
161
|
+
MenuItem { text "Profile" }
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
Segment(secondary: true) {
|
|
166
|
+
concat tag.pre { tag.code(
|
|
167
|
+
'Menu {
|
|
168
|
+
MenuItem(active: true, href: "#") { text "Home" }
|
|
169
|
+
MenuItem(href: "#") { text "Messages" }
|
|
170
|
+
MenuItem(href: "#") { text "Friends" }
|
|
171
|
+
SubMenu(position: "right") {
|
|
172
|
+
MenuItem {
|
|
173
|
+
Input(placeholder: "Search...", icon: "search")
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Menu(secondary: true, pointing: true) {
|
|
179
|
+
MenuItem(active: true) { text "Active" }
|
|
180
|
+
MenuItem { text "Tab Two" }
|
|
181
|
+
MenuItem { text "Tab Three" }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
Menu(vertical: true, pointing: true) {
|
|
185
|
+
MenuItem(active: true) { text "Dashboard" }
|
|
186
|
+
MenuItem { text "Settings" }
|
|
187
|
+
MenuItem { text "Profile" }
|
|
188
|
+
}'
|
|
189
|
+
)}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
Divider(hidden: true)
|
|
193
|
+
|
|
194
|
+
# ------------------------------------------------------------------
|
|
195
|
+
# Message
|
|
196
|
+
# ------------------------------------------------------------------
|
|
197
|
+
Header(size: :h3) { text "Message" }
|
|
198
|
+
text "Informational messages with type, icon, and dismissible options."
|
|
199
|
+
|
|
200
|
+
Segment {
|
|
201
|
+
VStack(spacing: 12) {
|
|
202
|
+
Message { text "Default message content." }
|
|
203
|
+
Message(type: :positive) { |c|
|
|
204
|
+
c.header { text "Success!" }
|
|
205
|
+
text "Your action was completed successfully."
|
|
206
|
+
}
|
|
207
|
+
Message(type: :negative) { |c|
|
|
208
|
+
c.header { text "Error" }
|
|
209
|
+
text "Something went wrong. Please try again."
|
|
210
|
+
}
|
|
211
|
+
Message(type: :warning) { text "Warning: This action cannot be undone." }
|
|
212
|
+
Message(type: :info, icon: "inbox") { text "You have new notifications." }
|
|
213
|
+
Message(dismissible: true, color: :blue) { text "Dismissible blue message." }
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
Segment(secondary: true) {
|
|
218
|
+
concat tag.pre { tag.code(
|
|
219
|
+
'Message { text "Default message content." }
|
|
220
|
+
|
|
221
|
+
Message(type: :positive) { |c|
|
|
222
|
+
c.header { text "Success!" }
|
|
223
|
+
text "Your action was completed successfully."
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
Message(type: :negative) { |c|
|
|
227
|
+
c.header { text "Error" }
|
|
228
|
+
text "Something went wrong. Please try again."
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
Message(type: :warning) { text "Warning: This action cannot be undone." }
|
|
232
|
+
Message(type: :info, icon: "inbox") { text "You have new notifications." }
|
|
233
|
+
Message(dismissible: true, color: :blue) { text "Dismissible blue message." }'
|
|
234
|
+
)}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
Divider(hidden: true)
|
|
238
|
+
|
|
239
|
+
# ------------------------------------------------------------------
|
|
240
|
+
# Table / TableRow / TableCell
|
|
241
|
+
# ------------------------------------------------------------------
|
|
242
|
+
Header(size: :h3) { text "Table / TableRow / TableCell" }
|
|
243
|
+
text "Data tables with manual rows or column accumulator mode."
|
|
244
|
+
|
|
245
|
+
Segment {
|
|
246
|
+
Header(size: :h4) { text "Manual Row Mode" }
|
|
247
|
+
Table(celled: true, striped: true) {
|
|
248
|
+
concat tag.thead {
|
|
249
|
+
tag.tr {
|
|
250
|
+
safe_join([
|
|
251
|
+
tag.th("Name"),
|
|
252
|
+
tag.th("Status"),
|
|
253
|
+
tag.th("Notes")
|
|
254
|
+
])
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
concat tag.tbody {
|
|
258
|
+
capture {
|
|
259
|
+
TableRow(positive: true) {
|
|
260
|
+
TableCell { text "John" }
|
|
261
|
+
TableCell { Icon(name: "checkmark", color: :green); text "Approved" }
|
|
262
|
+
TableCell { text "All good" }
|
|
263
|
+
}
|
|
264
|
+
TableRow {
|
|
265
|
+
TableCell { text "Jane" }
|
|
266
|
+
TableCell { text "Pending" }
|
|
267
|
+
TableCell { text "Awaiting review" }
|
|
268
|
+
}
|
|
269
|
+
TableRow(warning: true) {
|
|
270
|
+
TableCell { text "Bob" }
|
|
271
|
+
TableCell { text "Warning" }
|
|
272
|
+
TableCell { text "Needs attention" }
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
Segment(secondary: true) {
|
|
280
|
+
concat tag.pre { tag.code(
|
|
281
|
+
'Table(celled: true, striped: true) {
|
|
282
|
+
concat tag.thead {
|
|
283
|
+
tag.tr {
|
|
284
|
+
safe_join([tag.th("Name"), tag.th("Status"), tag.th("Notes")])
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
concat tag.tbody {
|
|
288
|
+
capture {
|
|
289
|
+
TableRow(positive: true) {
|
|
290
|
+
TableCell { text "John" }
|
|
291
|
+
TableCell { Icon(name: "checkmark", color: :green); text "Approved" }
|
|
292
|
+
TableCell { text "All good" }
|
|
293
|
+
}
|
|
294
|
+
TableRow {
|
|
295
|
+
TableCell { text "Jane" }
|
|
296
|
+
TableCell { text "Pending" }
|
|
297
|
+
TableCell { text "Awaiting review" }
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}'
|
|
302
|
+
)}
|
|
303
|
+
}
|