rails-active-ui 0.3.8 → 0.4.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 +4 -4
- data/README.md +195 -6
- data/Rakefile +1 -1
- data/app/components/accordion_component.rb +41 -24
- data/app/components/accordion_item_component.rb +40 -0
- data/app/components/ad_component.rb +1 -1
- data/app/components/api_component.rb +1 -1
- data/app/components/breadcrumb_component.rb +1 -1
- data/app/components/button_group_component.rb +36 -0
- data/app/components/button_to_component.rb +1 -1
- data/app/components/calendar_component.rb +24 -20
- data/app/components/card_component.rb +5 -3
- data/app/components/comment_component.rb +5 -3
- data/app/components/comment_group_component.rb +27 -0
- data/app/components/comment_reply_component.rb +47 -0
- data/app/components/comment_reply_group_component.rb +25 -0
- data/app/components/dimmer_component.rb +1 -1
- data/app/components/divider_component.rb +1 -1
- data/app/components/dropdown_component.rb +6 -2
- data/app/components/embed_component.rb +1 -1
- data/app/components/emoji_component.rb +1 -1
- data/app/components/feed_component.rb +16 -4
- data/app/components/feed_item_component.rb +85 -0
- data/app/components/field_component.rb +42 -0
- data/app/components/flag_component.rb +1 -1
- data/app/components/flyout_component.rb +3 -2
- data/app/components/h_stack_component.rb +1 -1
- data/app/components/header_component.rb +2 -2
- data/app/components/image_component.rb +1 -1
- data/app/components/input_component.rb +22 -41
- data/app/components/item_component.rb +3 -2
- data/app/components/item_group_component.rb +1 -1
- data/app/components/list_component.rb +2 -2
- data/app/components/list_content_component.rb +27 -0
- data/app/components/list_description_component.rb +17 -0
- data/app/components/list_header_component.rb +28 -0
- data/app/components/list_item_component.rb +37 -0
- data/app/components/loader_component.rb +1 -1
- data/app/components/menu_component.rb +1 -1
- data/app/components/modal_component.rb +2 -1
- data/app/components/nag_component.rb +1 -1
- data/app/components/overlay_component.rb +1 -1
- data/app/components/placeholder_component.rb +37 -13
- data/app/components/popup_component.rb +1 -1
- data/app/components/progress_component.rb +1 -1
- data/app/components/pusher_component.rb +1 -1
- data/app/components/rail_component.rb +1 -1
- data/app/components/rating_component.rb +1 -1
- data/app/components/reveal_component.rb +3 -2
- data/app/components/row_component.rb +4 -0
- data/app/components/search_component.rb +1 -1
- data/app/components/segment_group_component.rb +1 -1
- data/app/components/shape_component.rb +1 -1
- data/app/components/sidebar_component.rb +1 -1
- data/app/components/site_component.rb +1 -1
- data/app/components/slider_component.rb +1 -1
- data/app/components/state_component.rb +1 -1
- data/app/components/statistic_component.rb +3 -2
- data/app/components/step_component.rb +2 -2
- data/app/components/step_group_component.rb +1 -1
- data/app/components/sticky_component.rb +1 -1
- data/app/components/style_component.rb +1 -1
- data/app/components/sub_accordion_component.rb +25 -0
- data/app/components/sub_header_component.rb +1 -1
- data/app/components/sub_menu_component.rb +1 -1
- data/app/components/table_cell_component.rb +2 -2
- data/app/components/table_component.rb +2 -2
- data/app/components/tag_component.rb +57 -0
- data/app/components/tag_group_component.rb +33 -0
- data/app/components/text_component.rb +1 -1
- data/app/components/toast_component.rb +1 -1
- data/app/components/transition_component.rb +2 -2
- data/app/components/v_stack_component.rb +1 -1
- data/app/components/visibility_component.rb +1 -1
- data/app/helpers/component_helper.rb +23 -6
- data/app/helpers/ui/fomantic_form_builder.rb +155 -201
- data/app/javascript/ui/controllers/fui_calendar_controller.js +18 -8
- data/lib/ui/version.rb +1 -1
- metadata +15 -3
- data/app/components/checkbox_component.rb +0 -41
- data/app/components/label_component.rb +0 -49
|
@@ -4,22 +4,25 @@
|
|
|
4
4
|
#
|
|
5
5
|
# A Rails FormBuilder wrapping every helper in Fomantic-UI markup.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
7
|
+
# All text-like input helpers (text_field, email_field, password_field, etc.)
|
|
8
|
+
# render a bare <input> element by default. Pass `field: true` to wrap the
|
|
9
|
+
# input in a Fomantic <div class="field"> with optional label, error, hint.
|
|
8
10
|
#
|
|
9
|
-
#
|
|
10
|
-
# <%= f.text_field :name %>
|
|
11
|
-
# <%= f.email_field :email, required: true %>
|
|
12
|
-
# <%= f.select :role, [['Admin', 'admin'], ['User', 'user']], dropdown: true %>
|
|
13
|
-
# <%= f.check_box :terms, label: 'I agree to the Terms and Conditions' %>
|
|
14
|
-
# <%= f.fields_group(equal_width: true) do %>
|
|
15
|
-
# <%= f.text_field :first_name %>
|
|
16
|
-
# <%= f.text_field :last_name %>
|
|
17
|
-
# <% end %>
|
|
18
|
-
# <%= f.submit 'Save', color: 'green' %>
|
|
19
|
-
# <% end %>
|
|
11
|
+
# Usage:
|
|
20
12
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
13
|
+
# # Bare input (no wrapper):
|
|
14
|
+
# TextField(:email, placeholder: "E-mail address")
|
|
15
|
+
#
|
|
16
|
+
# # Wrapped in <div class="field"> with auto-label:
|
|
17
|
+
# TextField(:email, field: true)
|
|
18
|
+
#
|
|
19
|
+
# # Inside an Input wrapper for icon styling:
|
|
20
|
+
# Input(icon: "user", icon_position: "left") {
|
|
21
|
+
# TextField(:email, placeholder: "E-mail address")
|
|
22
|
+
# }
|
|
23
|
+
#
|
|
24
|
+
# Field options (only used when field: true):
|
|
25
|
+
# label: String – override label text (false to suppress label)
|
|
23
26
|
# required: Boolean – adds "required" class and asterisk
|
|
24
27
|
# disabled: Boolean – adds "disabled" class
|
|
25
28
|
# readonly: Boolean – adds "read-only" class
|
|
@@ -29,7 +32,6 @@
|
|
|
29
32
|
# warning: String – warning message; adds "warning" class + inline message
|
|
30
33
|
# hint: String – rendered as a small grey note beneath the input
|
|
31
34
|
# field_class: String – extra classes on the wrapping .field div
|
|
32
|
-
# input_class: String – extra classes on the input element itself
|
|
33
35
|
#
|
|
34
36
|
module Ui
|
|
35
37
|
class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
@@ -45,14 +47,46 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
45
47
|
%i[
|
|
46
48
|
text_field email_field password_field
|
|
47
49
|
number_field url_field telephone_field phone_field
|
|
48
|
-
search_field color_field
|
|
49
|
-
month_field week_field time_field range_field
|
|
50
|
+
search_field color_field range_field
|
|
50
51
|
].each do |method_name|
|
|
51
52
|
define_method(method_name) do |attribute, options = {}|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
wrap_in_field = options.delete(:field)
|
|
54
|
+
|
|
55
|
+
input_html = super(attribute, options)
|
|
56
|
+
|
|
57
|
+
wrap_in_field ? fomantic_field(attribute, options, input_html) : input_html
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# ──────────────────────────────────────────────────────────────────────────
|
|
62
|
+
# Date/time inputs — wrapped in Fomantic calendar
|
|
63
|
+
# ──────────────────────────────────────────────────────────────────────────
|
|
64
|
+
|
|
65
|
+
CALENDAR_TYPE_MAP = {
|
|
66
|
+
date_field: "date",
|
|
67
|
+
datetime_local_field: "datetime",
|
|
68
|
+
time_field: "time",
|
|
69
|
+
month_field: "month",
|
|
70
|
+
week_field: "date"
|
|
71
|
+
}.freeze
|
|
72
|
+
|
|
73
|
+
%i[date_field datetime_local_field time_field month_field week_field].each do |method_name|
|
|
74
|
+
define_method(method_name) do |attribute, options = {}|
|
|
75
|
+
wrap_in_field = options.delete(:field)
|
|
76
|
+
cal_type = options.delete(:calendar_type) || CALENDAR_TYPE_MAP[method_name]
|
|
77
|
+
cal_format = options.delete(:calendar_format)
|
|
78
|
+
cal_icon = options.delete(:icon) || "calendar"
|
|
79
|
+
min_date = options.delete(:min_date)
|
|
80
|
+
max_date = options.delete(:max_date)
|
|
81
|
+
cal_inverted = options.delete(:inverted)
|
|
82
|
+
cal_size = options.delete(:calendar_size)
|
|
83
|
+
|
|
84
|
+
input_html = super(attribute, options)
|
|
85
|
+
result = calendar_wrap(input_html, cal_type,
|
|
86
|
+
format: cal_format, icon: cal_icon, min_date: min_date,
|
|
87
|
+
max_date: max_date, inverted: cal_inverted, size: cal_size)
|
|
88
|
+
|
|
89
|
+
wrap_in_field ? fomantic_field(attribute, options, result) : result
|
|
56
90
|
end
|
|
57
91
|
end
|
|
58
92
|
|
|
@@ -61,12 +95,13 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
61
95
|
# ──────────────────────────────────────────────────────────────────────────
|
|
62
96
|
|
|
63
97
|
def text_area(attribute, options = {})
|
|
98
|
+
wrap_in_field = options.delete(:field)
|
|
64
99
|
transparent = options.delete(:transparent)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
100
|
+
|
|
101
|
+
options[:class] = class_names(("transparent" if transparent), options[:class])
|
|
102
|
+
input_html = super(attribute, options)
|
|
103
|
+
|
|
104
|
+
wrap_in_field ? fomantic_field(attribute, options, input_html) : input_html
|
|
70
105
|
end
|
|
71
106
|
|
|
72
107
|
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -74,25 +109,27 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
74
109
|
# ──────────────────────────────────────────────────────────────────────────
|
|
75
110
|
|
|
76
111
|
def emoji_field(attribute, options = {})
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
112
|
+
wrap_in_field = options.delete(:field)
|
|
113
|
+
|
|
114
|
+
current = object&.public_send(attribute) rescue nil
|
|
115
|
+
name = object_name ? "#{object_name}[#{attribute}]" : attribute.to_s
|
|
116
|
+
|
|
117
|
+
result = @template.tag.div(data: { controller: "fui-emoji-picker" }) {
|
|
118
|
+
@template.safe_join([
|
|
119
|
+
@template.hidden_field_tag(name, current, data: { fui_emoji_picker_target: "input" }),
|
|
120
|
+
@template.tag.button(
|
|
121
|
+
type: "button",
|
|
122
|
+
class: "ui basic button",
|
|
123
|
+
data: { fui_emoji_picker_target: "preview", action: "click->fui-emoji-picker#toggle" }
|
|
124
|
+
) { (current.presence || "Pick emoji").html_safe },
|
|
125
|
+
@template.tag.div(
|
|
126
|
+
style: "display:none; position:absolute; z-index:1000;",
|
|
127
|
+
data: { fui_emoji_picker_target: "dropdown" }
|
|
128
|
+
)
|
|
129
|
+
])
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
wrap_in_field ? fomantic_field(attribute, options, result) : result
|
|
96
133
|
end
|
|
97
134
|
|
|
98
135
|
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -100,13 +137,13 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
100
137
|
# ──────────────────────────────────────────────────────────────────────────
|
|
101
138
|
|
|
102
139
|
def select(attribute, choices = nil, options = {}, html_options = {}, &block)
|
|
140
|
+
wrap_in_field = options.delete(:field)
|
|
103
141
|
use_dropdown = options.delete(:dropdown)
|
|
104
|
-
fomantic_field(attribute, options) do |attr, opts|
|
|
105
|
-
merged_html = html_options.merge(class: class_names(html_options[:class], opts.delete(:input_class)))
|
|
106
|
-
raw_select = super(attr, choices, opts, merged_html, &block)
|
|
107
142
|
|
|
108
|
-
|
|
109
|
-
|
|
143
|
+
raw_select = super(attribute, choices, options, html_options, &block)
|
|
144
|
+
result = use_dropdown ? dropdown_wrap(raw_select) : raw_select
|
|
145
|
+
|
|
146
|
+
wrap_in_field ? fomantic_field(attribute, options, result) : result
|
|
110
147
|
end
|
|
111
148
|
|
|
112
149
|
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -114,14 +151,19 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
114
151
|
# ──────────────────────────────────────────────────────────────────────────
|
|
115
152
|
|
|
116
153
|
def check_box(attribute, options = {}, checked_value = "1", unchecked_value = "0")
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
154
|
+
wrap_in_field = options.delete(:field)
|
|
155
|
+
label_text = options.delete(:label) { label_for(attribute) }
|
|
156
|
+
kind = options.delete(:kind) { :checkbox }
|
|
157
|
+
size = options.delete(:size)
|
|
158
|
+
inverted = options.delete(:inverted)
|
|
159
|
+
fitted = options.delete(:fitted)
|
|
160
|
+
right_aligned = options.delete(:right_aligned)
|
|
161
|
+
|
|
162
|
+
checkbox_html = super(attribute, options, checked_value, unchecked_value)
|
|
163
|
+
result = checkbox_ui(checkbox_html, label_text, kind,
|
|
164
|
+
size: size, inverted: inverted, fitted: fitted, right_aligned: right_aligned)
|
|
165
|
+
|
|
166
|
+
wrap_in_field ? fomantic_field(attribute, { suppress_label: true }, result) : result
|
|
125
167
|
end
|
|
126
168
|
|
|
127
169
|
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -129,13 +171,19 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
129
171
|
# ──────────────────────────────────────────────────────────────────────────
|
|
130
172
|
|
|
131
173
|
def radio_button(attribute, value, options = {})
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
174
|
+
wrap_in_field = options.delete(:field)
|
|
175
|
+
label_text = options.delete(:label) { value.to_s.humanize }
|
|
176
|
+
kind = options.delete(:kind) { :radio }
|
|
177
|
+
size = options.delete(:size)
|
|
178
|
+
inverted = options.delete(:inverted)
|
|
179
|
+
fitted = options.delete(:fitted)
|
|
180
|
+
right_aligned = options.delete(:right_aligned)
|
|
181
|
+
|
|
182
|
+
radio_html = super(attribute, value, options)
|
|
183
|
+
result = checkbox_ui(radio_html, label_text, kind,
|
|
184
|
+
size: size, inverted: inverted, fitted: fitted, right_aligned: right_aligned)
|
|
185
|
+
|
|
186
|
+
wrap_in_field ? fomantic_field(attribute, { suppress_label: true }, result) : result
|
|
139
187
|
end
|
|
140
188
|
|
|
141
189
|
# ──────────────────────────────────────────────────────────────────────────
|
|
@@ -143,14 +191,15 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
143
191
|
# ──────────────────────────────────────────────────────────────────────────
|
|
144
192
|
|
|
145
193
|
def file_field(attribute, options = {})
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
194
|
+
wrap_in_field = options.delete(:field)
|
|
195
|
+
|
|
196
|
+
input_html = super(attribute, options)
|
|
197
|
+
|
|
198
|
+
wrap_in_field ? fomantic_field(attribute, options, input_html) : input_html
|
|
150
199
|
end
|
|
151
200
|
|
|
152
201
|
# ──────────────────────────────────────────────────────────────────────────
|
|
153
|
-
# Hidden field (no wrapper)
|
|
202
|
+
# Hidden field (no wrapper ever)
|
|
154
203
|
# ──────────────────────────────────────────────────────────────────────────
|
|
155
204
|
|
|
156
205
|
def hidden_field(attribute, options = {})
|
|
@@ -183,7 +232,7 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
183
232
|
end
|
|
184
233
|
|
|
185
234
|
# ──────────────────────────────────────────────────────────────────────────
|
|
186
|
-
# Label override — produces a plain <label>
|
|
235
|
+
# Label override — produces a plain <label>
|
|
187
236
|
# ──────────────────────────────────────────────────────────────────────────
|
|
188
237
|
|
|
189
238
|
def label(attribute, text = nil, options = {}, &block)
|
|
@@ -192,11 +241,6 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
192
241
|
|
|
193
242
|
# ──────────────────────────────────────────────────────────────────────────
|
|
194
243
|
# fields_group — wraps children in <div class="fields ...">
|
|
195
|
-
#
|
|
196
|
-
# Options:
|
|
197
|
-
# equal_width: Boolean – adds "equal width"
|
|
198
|
-
# inline: Boolean – adds "inline"
|
|
199
|
-
# count: Integer – "N fields" (evenly divided)
|
|
200
244
|
# ──────────────────────────────────────────────────────────────────────────
|
|
201
245
|
|
|
202
246
|
def fields_group(options = {}, &block)
|
|
@@ -240,9 +284,9 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
240
284
|
|
|
241
285
|
private
|
|
242
286
|
|
|
243
|
-
# ──
|
|
287
|
+
# ── Field wrapper (opt-in via field: true) ─────────────────────────────────
|
|
244
288
|
|
|
245
|
-
def fomantic_field(attribute, options,
|
|
289
|
+
def fomantic_field(attribute, options, input_html)
|
|
246
290
|
required = options.delete(:required)
|
|
247
291
|
disabled = options.delete(:disabled)
|
|
248
292
|
readonly_opt = options.delete(:readonly)
|
|
@@ -275,8 +319,6 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
275
319
|
text ? label(attribute, text) : nil
|
|
276
320
|
end
|
|
277
321
|
|
|
278
|
-
input_html = block.call(attribute, options)
|
|
279
|
-
|
|
280
322
|
note_html = inline_note(error_msg || (has_error && first_error(attribute)), "red")
|
|
281
323
|
note_html = inline_note(warning_msg, "orange") if note_html.blank? && has_warning
|
|
282
324
|
note_html = inline_note(hint, "grey") if note_html.blank? && hint
|
|
@@ -288,15 +330,44 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
288
330
|
|
|
289
331
|
# ── Checkbox / Radio UI shell ──────────────────────────────────────────────
|
|
290
332
|
|
|
291
|
-
def checkbox_ui(input_html, label_text, kind)
|
|
333
|
+
def checkbox_ui(input_html, label_text, kind, size: nil, inverted: nil, fitted: nil, right_aligned: nil)
|
|
292
334
|
modifier = { radio: "radio", slider: "slider", toggle: "toggle" }[kind]
|
|
293
|
-
css
|
|
335
|
+
css = class_names(
|
|
336
|
+
"ui",
|
|
337
|
+
size,
|
|
338
|
+
modifier,
|
|
339
|
+
("inverted" if inverted),
|
|
340
|
+
("fitted" if fitted),
|
|
341
|
+
("right aligned" if right_aligned),
|
|
342
|
+
"checkbox"
|
|
343
|
+
)
|
|
294
344
|
|
|
295
|
-
@template.tag.div(class: css) do
|
|
345
|
+
@template.tag.div(class: css, data: { controller: "fui-checkbox" }) do
|
|
296
346
|
safe_join([ input_html, @template.tag.label(label_text.is_a?(String) ? label_text : nil) ])
|
|
297
347
|
end
|
|
298
348
|
end
|
|
299
349
|
|
|
350
|
+
# ── Calendar wrapper ─────────────────────────────────────────────────────
|
|
351
|
+
|
|
352
|
+
def calendar_wrap(input_html, cal_type, format: nil, icon: "calendar",
|
|
353
|
+
min_date: nil, max_date: nil, inverted: nil, size: nil)
|
|
354
|
+
data = { controller: "fui-calendar", fui_calendar_type_value: cal_type }
|
|
355
|
+
data[:fui_calendar_format_value] = format if format
|
|
356
|
+
data[:fui_calendar_min_date_value] = min_date if min_date
|
|
357
|
+
data[:fui_calendar_max_date_value] = max_date if max_date
|
|
358
|
+
|
|
359
|
+
cal_class = class_names("ui", size, ("inverted" if inverted), "calendar")
|
|
360
|
+
|
|
361
|
+
@template.tag.div(class: cal_class, data: data) {
|
|
362
|
+
@template.tag.div(class: "ui fluid input left icon") {
|
|
363
|
+
safe_join([
|
|
364
|
+
@template.tag.i(class: "#{icon} icon"),
|
|
365
|
+
input_html
|
|
366
|
+
])
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
end
|
|
370
|
+
|
|
300
371
|
# ── Dropdown wrapper ───────────────────────────────────────────────────────
|
|
301
372
|
|
|
302
373
|
def dropdown_wrap(select_html)
|
|
@@ -361,127 +432,10 @@ class FomanticFormBuilder < ActionView::Helpers::FormBuilder
|
|
|
361
432
|
@template.safe_join(parts)
|
|
362
433
|
end
|
|
363
434
|
|
|
364
|
-
# ── class_names helper
|
|
435
|
+
# ── class_names helper ────────────────────────────────────────────────────
|
|
365
436
|
|
|
366
437
|
def class_names(*args)
|
|
367
438
|
args.flatten.compact.reject { |v| v == false || v.to_s.strip.empty? }.join(" ")
|
|
368
439
|
end
|
|
369
440
|
end
|
|
370
|
-
|
|
371
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
372
|
-
# Usage examples (views)
|
|
373
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
374
|
-
|
|
375
|
-
# ── 1. Basic user registration form ──────────────────────────────────────────
|
|
376
|
-
#
|
|
377
|
-
# <%= form_with model: @user, builder: FomanticFormBuilder, class: "ui form" do |f| %>
|
|
378
|
-
#
|
|
379
|
-
# <%# grouped equal-width row %>
|
|
380
|
-
# <%= f.fields_group(equal_width: true) do %>
|
|
381
|
-
# <%= f.text_field :first_name, required: true %>
|
|
382
|
-
# <%= f.text_field :last_name, required: true %>
|
|
383
|
-
# <% end %>
|
|
384
|
-
#
|
|
385
|
-
# <%= f.email_field :email, required: true %>
|
|
386
|
-
# <%= f.password_field :password, required: true,
|
|
387
|
-
# hint: "Minimum 8 characters" %>
|
|
388
|
-
#
|
|
389
|
-
# <%# Native select styled by Fomantic %>
|
|
390
|
-
# <%= f.select :role, [["Admin", "admin"], ["Member", "member"]],
|
|
391
|
-
# { prompt: "Select a role" } %>
|
|
392
|
-
#
|
|
393
|
-
# <%# Fomantic dropdown widget (adds JS .dropdown() wrapper) %>
|
|
394
|
-
# <%= f.select :country, country_options,
|
|
395
|
-
# { dropdown: true, required: true } %>
|
|
396
|
-
#
|
|
397
|
-
# <%= f.check_box :terms,
|
|
398
|
-
# label: "I agree to the Terms and Conditions",
|
|
399
|
-
# required: true %>
|
|
400
|
-
#
|
|
401
|
-
# <%# Error/success messages from model %>
|
|
402
|
-
# <%= f.error_message "We had some issues",
|
|
403
|
-
# @user.errors.full_messages if @user.errors.any? %>
|
|
404
|
-
#
|
|
405
|
-
# <%= f.submit "Sign up", color: "green" %>
|
|
406
|
-
# <% end %>
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
# ── 2. Inline field (label beside input) ─────────────────────────────────────
|
|
410
|
-
#
|
|
411
|
-
# <%= f.text_field :phone, label: "Phone Number", inline: true,
|
|
412
|
-
# width: "eight" %>
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
# ── 3. Width-constrained fields ───────────────────────────────────────────────
|
|
416
|
-
#
|
|
417
|
-
# <%= f.fields_group do %>
|
|
418
|
-
# <%= f.text_field :first_name, width: "six" %>
|
|
419
|
-
# <%= f.text_field :middle, width: "three" %>
|
|
420
|
-
# <%= f.text_field :last_name, width: "seven" %>
|
|
421
|
-
# <% end %>
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
# ── 4. Checkbox kinds ─────────────────────────────────────────────────────────
|
|
425
|
-
#
|
|
426
|
-
# <%= f.check_box :notifications, label: "Enable notifications", kind: :toggle %>
|
|
427
|
-
# <%= f.check_box :public, label: "Publicly visible", kind: :slider %>
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
# ── 5. Radio group ────────────────────────────────────────────────────────────
|
|
431
|
-
#
|
|
432
|
-
# <%= f.fields_group do %>
|
|
433
|
-
# <%= f.radio_button :plan, "basic", label: "Basic" %>
|
|
434
|
-
# <%= f.radio_button :plan, "pro", label: "Pro" %>
|
|
435
|
-
# <%= f.radio_button :plan, "enterprise", label: "Enterprise" %>
|
|
436
|
-
# <% end %>
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
# ── 6. Textarea ───────────────────────────────────────────────────────────────
|
|
440
|
-
#
|
|
441
|
-
# <%= f.text_area :bio, rows: 4 %>
|
|
442
|
-
# <%= f.text_area :description, rows: 2, transparent: true %>
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
# ── 7. Form-level state messages ──────────────────────────────────────────────
|
|
446
|
-
#
|
|
447
|
-
# <%= f.error_message "Action Forbidden", ["Email already registered"] %>
|
|
448
|
-
# <%= f.success_message "All done!", "Your profile has been updated." %>
|
|
449
|
-
# <%= f.warning_message "Heads up", ["Please verify your email"] %>
|
|
450
|
-
# <%= f.info_message "Password rules", ["Must be at least 8 characters"] %>
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
# ── 8. Submit variations ──────────────────────────────────────────────────────
|
|
454
|
-
#
|
|
455
|
-
# <%= f.submit "Save", color: "blue" %>
|
|
456
|
-
# <%= f.submit "Delete", color: "red", basic: true %>
|
|
457
|
-
# <%= f.submit "Go", color: "green", size: "large", icon: "checkmark" %>
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
# ── 9. Opt-in per form (when default builder is not set) ──────────────────────
|
|
461
|
-
#
|
|
462
|
-
# <%= form_with model: @post, builder: FomanticFormBuilder, class: "ui form" do |f| %>
|
|
463
|
-
# ...
|
|
464
|
-
# <% end %>
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
468
|
-
# JavaScript initialisation (application.js or a Stimulus controller)
|
|
469
|
-
# ─────────────────────────────────────────────────────────────────────────────
|
|
470
|
-
#
|
|
471
|
-
# // Initialise all Fomantic dropdowns on the page
|
|
472
|
-
# document.addEventListener("DOMContentLoaded", () => {
|
|
473
|
-
# $(".ui.dropdown").dropdown();
|
|
474
|
-
# $(".ui.checkbox").checkbox();
|
|
475
|
-
# $(".ui.calendar").calendar({ type: "date" });
|
|
476
|
-
# });
|
|
477
|
-
#
|
|
478
|
-
# // Or with a Stimulus controller:
|
|
479
|
-
# //
|
|
480
|
-
# // import { Controller } from "@hotwired/stimulus"
|
|
481
|
-
# // export default class extends Controller {
|
|
482
|
-
# // connect() {
|
|
483
|
-
# // $(this.element).find(".ui.dropdown").dropdown()
|
|
484
|
-
# // $(this.element).find(".ui.checkbox").checkbox()
|
|
485
|
-
# // }
|
|
486
|
-
# // }
|
|
487
441
|
end
|
|
@@ -14,14 +14,15 @@ import { Controller } from "@hotwired/stimulus"
|
|
|
14
14
|
//
|
|
15
15
|
export default class extends Controller {
|
|
16
16
|
static values = {
|
|
17
|
-
type:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
type: { type: String, default: "date" },
|
|
18
|
+
format: { type: String, default: "" },
|
|
19
|
+
closable: { type: Boolean, default: true },
|
|
20
|
+
monthFirst: { type: Boolean, default: true },
|
|
21
|
+
firstDayOfWeek: { type: Number, default: 0 },
|
|
22
|
+
today: { type: Boolean, default: false },
|
|
23
|
+
formatInput: { type: Boolean, default: true },
|
|
24
|
+
minDate: { type: String, default: "" },
|
|
25
|
+
maxDate: { type: String, default: "" },
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
connect() {
|
|
@@ -58,6 +59,15 @@ export default class extends Controller {
|
|
|
58
59
|
onHide: () => { this.dispatch("hide") },
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
if (this.formatValue) {
|
|
63
|
+
opts.formatter = {
|
|
64
|
+
date: this.formatValue,
|
|
65
|
+
datetime: this.formatValue,
|
|
66
|
+
time: this.formatValue,
|
|
67
|
+
cellTime: this.formatValue,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
if (this.minDateValue) opts.minDate = new Date(this.minDateValue)
|
|
62
72
|
if (this.maxDateValue) opts.maxDate = new Date(this.maxDateValue)
|
|
63
73
|
|
data/lib/ui/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-active-ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- nathan
|
|
@@ -43,17 +43,21 @@ files:
|
|
|
43
43
|
- app/assets/stylesheets.css
|
|
44
44
|
- app/blocks/resource_list_block.rb
|
|
45
45
|
- app/components/accordion_component.rb
|
|
46
|
+
- app/components/accordion_item_component.rb
|
|
46
47
|
- app/components/ad_component.rb
|
|
47
48
|
- app/components/api_component.rb
|
|
48
49
|
- app/components/back_button_component.rb
|
|
49
50
|
- app/components/breadcrumb_component.rb
|
|
50
51
|
- app/components/button_component.rb
|
|
52
|
+
- app/components/button_group_component.rb
|
|
51
53
|
- app/components/button_to_component.rb
|
|
52
54
|
- app/components/calendar_component.rb
|
|
53
55
|
- app/components/card_component.rb
|
|
54
|
-
- app/components/checkbox_component.rb
|
|
55
56
|
- app/components/column_component.rb
|
|
56
57
|
- app/components/comment_component.rb
|
|
58
|
+
- app/components/comment_group_component.rb
|
|
59
|
+
- app/components/comment_reply_component.rb
|
|
60
|
+
- app/components/comment_reply_group_component.rb
|
|
57
61
|
- app/components/concerns/alignable.rb
|
|
58
62
|
- app/components/concerns/attachable.rb
|
|
59
63
|
- app/components/concerns/orientable.rb
|
|
@@ -66,6 +70,8 @@ files:
|
|
|
66
70
|
- app/components/embed_component.rb
|
|
67
71
|
- app/components/emoji_component.rb
|
|
68
72
|
- app/components/feed_component.rb
|
|
73
|
+
- app/components/feed_item_component.rb
|
|
74
|
+
- app/components/field_component.rb
|
|
69
75
|
- app/components/flag_component.rb
|
|
70
76
|
- app/components/flyout_component.rb
|
|
71
77
|
- app/components/form_component.rb
|
|
@@ -77,9 +83,12 @@ files:
|
|
|
77
83
|
- app/components/input_component.rb
|
|
78
84
|
- app/components/item_component.rb
|
|
79
85
|
- app/components/item_group_component.rb
|
|
80
|
-
- app/components/label_component.rb
|
|
81
86
|
- app/components/link_to_component.rb
|
|
82
87
|
- app/components/list_component.rb
|
|
88
|
+
- app/components/list_content_component.rb
|
|
89
|
+
- app/components/list_description_component.rb
|
|
90
|
+
- app/components/list_header_component.rb
|
|
91
|
+
- app/components/list_item_component.rb
|
|
83
92
|
- app/components/loader_component.rb
|
|
84
93
|
- app/components/menu_component.rb
|
|
85
94
|
- app/components/menu_item_component.rb
|
|
@@ -110,6 +119,7 @@ files:
|
|
|
110
119
|
- app/components/step_group_component.rb
|
|
111
120
|
- app/components/sticky_component.rb
|
|
112
121
|
- app/components/style_component.rb
|
|
122
|
+
- app/components/sub_accordion_component.rb
|
|
113
123
|
- app/components/sub_header_component.rb
|
|
114
124
|
- app/components/sub_menu_component.rb
|
|
115
125
|
- app/components/tab_component.rb
|
|
@@ -117,6 +127,8 @@ files:
|
|
|
117
127
|
- app/components/table_cell_component.rb
|
|
118
128
|
- app/components/table_component.rb
|
|
119
129
|
- app/components/table_row_component.rb
|
|
130
|
+
- app/components/tag_component.rb
|
|
131
|
+
- app/components/tag_group_component.rb
|
|
120
132
|
- app/components/template_component.rb
|
|
121
133
|
- app/components/text_component.rb
|
|
122
134
|
- app/components/toast_component.rb
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Checkbox — checkboxes, radios, toggles, sliders.
|
|
4
|
-
#
|
|
5
|
-
# Usage:
|
|
6
|
-
# Checkbox(label_text: "Accept terms", name: "terms")
|
|
7
|
-
# Checkbox(type: :toggle, label_text: "Dark mode", checked: true)
|
|
8
|
-
# Checkbox(type: :radio, label_text: "Option A", name: "choice", value: "a")
|
|
9
|
-
|
|
10
|
-
class CheckboxComponent < Component
|
|
11
|
-
attribute :type, :string, default: "checkbox"
|
|
12
|
-
attribute :label_text, :string, default: nil
|
|
13
|
-
attribute :name, :string, default: nil
|
|
14
|
-
attribute :value, :string, default: nil
|
|
15
|
-
attribute :checked, :boolean, default: false
|
|
16
|
-
attribute :disabled, :boolean, default: false
|
|
17
|
-
attribute :read_only, :boolean, default: false
|
|
18
|
-
attribute :fitted, :boolean, default: false
|
|
19
|
-
|
|
20
|
-
def to_s
|
|
21
|
-
classes = class_names(
|
|
22
|
-
"ui",
|
|
23
|
-
(type unless type == "checkbox"),
|
|
24
|
-
{ "fitted" => fitted, "read-only" => read_only, "disabled" => disabled },
|
|
25
|
-
"checkbox"
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
field_type = type == "radio" ? "radio" : "checkbox"
|
|
29
|
-
input_opts = { type: field_type }
|
|
30
|
-
input_opts[:name] = name if name
|
|
31
|
-
input_opts[:value] = value if value
|
|
32
|
-
input_opts[:checked] = "checked" if checked
|
|
33
|
-
input_opts[:disabled] = "disabled" if disabled
|
|
34
|
-
|
|
35
|
-
label_el = tag.label { label_text || "" }
|
|
36
|
-
|
|
37
|
-
tag.div(class: classes, data: { controller: "fui-checkbox" }) {
|
|
38
|
-
safe_join([ tag.input(**input_opts), label_el ])
|
|
39
|
-
}
|
|
40
|
-
end
|
|
41
|
-
end
|