wilday_ui 0.8.0 → 0.9.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 +3 -2
- data/app/assets/builds/wilday_ui/index.js +78 -27
- data/app/assets/builds/wilday_ui/index.js.map +3 -3
- data/app/assets/stylesheets/wilday_ui/components/button/base.css +12 -0
- data/app/assets/stylesheets/wilday_ui/components/button/features/animation.css +284 -0
- data/app/assets/stylesheets/wilday_ui/components/button/features/sizes.css +36 -0
- data/app/assets/stylesheets/wilday_ui/components/button/index.css +1 -0
- data/app/helpers/wilday_ui/application_helper.rb +1 -1
- data/app/helpers/wilday_ui/components/button/button_helper.rb +348 -0
- data/app/helpers/wilday_ui/components/button/feature_engine.rb +74 -0
- data/app/helpers/wilday_ui/components/button/features/animation.rb +97 -0
- data/app/helpers/wilday_ui/components/button/features/confirm_dialog.rb +70 -0
- data/app/helpers/wilday_ui/components/button/features/copy_to_clipboard.rb +56 -0
- data/app/helpers/wilday_ui/components/button/features/dropdown.rb +74 -0
- data/app/helpers/wilday_ui/components/button/features/loading.rb +32 -0
- data/app/helpers/wilday_ui/components/button/features/tooltip.rb +138 -0
- data/app/javascript/wilday_ui/controllers/animation_controller.js +97 -0
- data/app/javascript/wilday_ui/controllers/index.js +2 -0
- data/app/javascript/wilday_ui/controllers/tooltip_controller.js +0 -33
- data/lib/wilday_ui/version.rb +1 -1
- metadata +12 -3
- data/app/helpers/wilday_ui/components/button_helper.rb +0 -672
@@ -1,672 +0,0 @@
|
|
1
|
-
module WildayUi
|
2
|
-
module Components
|
3
|
-
module ButtonHelper
|
4
|
-
BUTTON_FEATURES = {
|
5
|
-
dropdown: {
|
6
|
-
wrapper_required: true,
|
7
|
-
stimulus_controller: "dropdown",
|
8
|
-
default_stimulus_action: "click->dropdown#toggle"
|
9
|
-
},
|
10
|
-
loading: {
|
11
|
-
wrapper_required: false,
|
12
|
-
stimulus_controller: "button",
|
13
|
-
default_stimulus_action: "click->button#toggleLoading"
|
14
|
-
},
|
15
|
-
copy_to_clipboard: {
|
16
|
-
wrapper_required: true,
|
17
|
-
stimulus_controller: "clipboard button",
|
18
|
-
default_stimulus_action: "click->clipboard#copy click->button#toggleLoading"
|
19
|
-
},
|
20
|
-
confirm: {
|
21
|
-
wrapper_required: true,
|
22
|
-
stimulus_controller: "confirmation",
|
23
|
-
default_stimulus_action: "click->confirmation#showDialog"
|
24
|
-
},
|
25
|
-
tooltip: {
|
26
|
-
wrapper_required: true,
|
27
|
-
stimulus_controller: "tooltip",
|
28
|
-
default_stimulus_action: {
|
29
|
-
hover: "mouseenter->tooltip#show mouseleave->tooltip#hide focusin->tooltip#show focusout->tooltip#hide",
|
30
|
-
click: "click->tooltip#toggle"
|
31
|
-
}
|
32
|
-
}
|
33
|
-
# Add more features here as needed
|
34
|
-
# tooltip: {
|
35
|
-
# wrapper_required: true,
|
36
|
-
# stimulus_controller: "tooltip",
|
37
|
-
# default_stimulus_action: "mouseenter->tooltip#show mouseleave->tooltip#hide"
|
38
|
-
# }
|
39
|
-
}.freeze
|
40
|
-
|
41
|
-
def w_button(
|
42
|
-
content,
|
43
|
-
variant: :solid,
|
44
|
-
size: :medium,
|
45
|
-
radius: :rounded,
|
46
|
-
gradient: nil,
|
47
|
-
icon: nil,
|
48
|
-
icon_position: :left,
|
49
|
-
icon_only: false,
|
50
|
-
loading: false,
|
51
|
-
loading_text: nil,
|
52
|
-
disabled: false,
|
53
|
-
additional_classes: "",
|
54
|
-
use_default_controller: true,
|
55
|
-
href: nil,
|
56
|
-
method: :get,
|
57
|
-
target: nil,
|
58
|
-
underline: true,
|
59
|
-
dropdown: false,
|
60
|
-
dropdown_items: nil,
|
61
|
-
dropdown_icon: nil,
|
62
|
-
theme: nil,
|
63
|
-
copy_to_clipboard: nil,
|
64
|
-
confirm: nil,
|
65
|
-
tooltip: nil,
|
66
|
-
**options
|
67
|
-
)
|
68
|
-
content_for(:head) { stylesheet_link_tag "wilday_ui/components/button/index", media: "all" }
|
69
|
-
|
70
|
-
options[:data] ||= {}
|
71
|
-
wrapper_data = {}
|
72
|
-
wrapper_options = nil
|
73
|
-
|
74
|
-
# Process gradient styles if present
|
75
|
-
if gradient.present?
|
76
|
-
gradient_styles = process_gradient(gradient)
|
77
|
-
options[:style] = [ options[:style], gradient_styles ].compact.join(";") if gradient_styles.present?
|
78
|
-
end
|
79
|
-
|
80
|
-
# Process theme styles
|
81
|
-
if theme.present?
|
82
|
-
theme_styles = process_theme(variant, theme)
|
83
|
-
options[:style] = theme_styles if theme_styles.present?
|
84
|
-
end
|
85
|
-
|
86
|
-
variant_class = get_variant_class(variant)
|
87
|
-
size_class = get_size_class(size)
|
88
|
-
radius_class = get_radius_class(radius)
|
89
|
-
gradient_class = get_gradient_class(gradient)
|
90
|
-
|
91
|
-
# Setup features that require Stimulus controllers
|
92
|
-
active_features = determine_active_features(loading, dropdown, loading_text, copy_to_clipboard, confirm, tooltip, use_default_controller)
|
93
|
-
|
94
|
-
setup_features(active_features, options, use_default_controller, loading_text)
|
95
|
-
|
96
|
-
setup_link_options(options, href, target, method)
|
97
|
-
|
98
|
-
if dropdown
|
99
|
-
setup_dropdown_options(
|
100
|
-
options,
|
101
|
-
additional_classes,
|
102
|
-
dropdown,
|
103
|
-
dropdown_items,
|
104
|
-
wrapper_data
|
105
|
-
)
|
106
|
-
end
|
107
|
-
|
108
|
-
if copy_to_clipboard
|
109
|
-
setup_clipboard_options(
|
110
|
-
options,
|
111
|
-
additional_classes,
|
112
|
-
copy_to_clipboard,
|
113
|
-
wrapper_data
|
114
|
-
)
|
115
|
-
end
|
116
|
-
|
117
|
-
if confirm
|
118
|
-
setup_confirmation_options(
|
119
|
-
options,
|
120
|
-
additional_classes,
|
121
|
-
confirm,
|
122
|
-
wrapper_data
|
123
|
-
)
|
124
|
-
end
|
125
|
-
|
126
|
-
if tooltip
|
127
|
-
setup_tooltip_options(
|
128
|
-
options,
|
129
|
-
additional_classes,
|
130
|
-
tooltip,
|
131
|
-
wrapper_data
|
132
|
-
)
|
133
|
-
end
|
134
|
-
|
135
|
-
# Setup wrapper options if any feature requires it
|
136
|
-
wrapper_options = setup_wrapper_options(
|
137
|
-
active_features,
|
138
|
-
additional_classes,
|
139
|
-
wrapper_data
|
140
|
-
)
|
141
|
-
|
142
|
-
render_button(
|
143
|
-
content,
|
144
|
-
variant_class,
|
145
|
-
size_class,
|
146
|
-
radius_class,
|
147
|
-
gradient_class,
|
148
|
-
icon,
|
149
|
-
icon_position,
|
150
|
-
icon_only,
|
151
|
-
loading,
|
152
|
-
loading_text,
|
153
|
-
additional_classes,
|
154
|
-
disabled,
|
155
|
-
options,
|
156
|
-
href,
|
157
|
-
underline,
|
158
|
-
dropdown,
|
159
|
-
dropdown_items,
|
160
|
-
dropdown_icon,
|
161
|
-
wrapper_options
|
162
|
-
)
|
163
|
-
end
|
164
|
-
|
165
|
-
private
|
166
|
-
|
167
|
-
# def get_variant_class(variant)
|
168
|
-
# {
|
169
|
-
# primary: "w-button-primary",
|
170
|
-
# secondary: "w-button-secondary",
|
171
|
-
# outline: "w-button-outline"
|
172
|
-
# }[variant] || "w-button-primary"
|
173
|
-
# end
|
174
|
-
|
175
|
-
def get_variant_class(variant)
|
176
|
-
{
|
177
|
-
solid: "w-button-solid",
|
178
|
-
subtle: "w-button-subtle",
|
179
|
-
surface: "w-button-surface",
|
180
|
-
outline: "w-button-outline",
|
181
|
-
ghost: "w-button-ghost",
|
182
|
-
plain: "w-button-plain"
|
183
|
-
}[variant] || "w-button-solid"
|
184
|
-
end
|
185
|
-
|
186
|
-
def get_size_class(size)
|
187
|
-
{
|
188
|
-
small: "w-button-small",
|
189
|
-
medium: "w-button-medium",
|
190
|
-
large: "w-button-large"
|
191
|
-
}[size] || "w-button-medium"
|
192
|
-
end
|
193
|
-
|
194
|
-
def get_radius_class(radius)
|
195
|
-
{
|
196
|
-
rounded: "w-button-rounded",
|
197
|
-
pill: "w-button-pill",
|
198
|
-
square: "w-button-square"
|
199
|
-
}[radius] || "w-button-rounded"
|
200
|
-
end
|
201
|
-
|
202
|
-
def get_gradient_class(gradient)
|
203
|
-
return nil unless gradient
|
204
|
-
|
205
|
-
if gradient.is_a?(Hash) && gradient[:from] && gradient[:to]
|
206
|
-
"w-button-gradient-custom"
|
207
|
-
else
|
208
|
-
"w-button-gradient-#{gradient}"
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def process_gradient(gradient)
|
213
|
-
return nil unless gradient.is_a?(Hash) && gradient[:from] && gradient[:to]
|
214
|
-
|
215
|
-
if gradient[:via]
|
216
|
-
"background: linear-gradient(135deg, #{gradient[:from]}, #{gradient[:via]}, #{gradient[:to]})"
|
217
|
-
else
|
218
|
-
"background: linear-gradient(135deg, #{gradient[:from]}, #{gradient[:to]})"
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
def process_theme(variant, theme)
|
223
|
-
return nil unless theme[:name] || theme[:custom]
|
224
|
-
|
225
|
-
Rails.logger.debug "[Wilday UI] Processing theme for variant: #{variant}"
|
226
|
-
Rails.logger.debug "[Wilday UI] Theme config: #{theme.inspect}"
|
227
|
-
|
228
|
-
styles = {}
|
229
|
-
|
230
|
-
if theme[:name]
|
231
|
-
theme_colors = get_theme_colors(variant, theme[:name])
|
232
|
-
styles.merge!(theme_colors)
|
233
|
-
end
|
234
|
-
|
235
|
-
if theme[:custom]
|
236
|
-
custom_styles = process_custom_theme(theme[:custom])
|
237
|
-
styles.merge!(custom_styles)
|
238
|
-
end
|
239
|
-
|
240
|
-
generate_styles(styles)
|
241
|
-
end
|
242
|
-
|
243
|
-
def get_theme_colors(variant, theme_name)
|
244
|
-
config = WildayUi::Config::Theme.configuration
|
245
|
-
# Convert theme_name to string
|
246
|
-
return {} unless config&.colors&.[](theme_name.to_s)
|
247
|
-
|
248
|
-
colors = config.colors[theme_name.to_s]
|
249
|
-
|
250
|
-
case variant
|
251
|
-
when :solid
|
252
|
-
{
|
253
|
-
"--w-button-color": "#FFFFFF",
|
254
|
-
"--w-button-bg": colors["500"],
|
255
|
-
"--w-button-hover-bg": colors["600"],
|
256
|
-
"--w-button-active-bg": colors["700"]
|
257
|
-
}
|
258
|
-
when :subtle
|
259
|
-
{
|
260
|
-
"--w-button-color": colors["700"],
|
261
|
-
"--w-button-bg": colors["50"],
|
262
|
-
"--w-button-hover-bg": colors["100"],
|
263
|
-
"--w-button-hover-color": colors["800"]
|
264
|
-
}
|
265
|
-
when :surface
|
266
|
-
{
|
267
|
-
"--w-button-color": colors["700"],
|
268
|
-
"--w-button-bg": colors["50"],
|
269
|
-
"--w-button-hover-bg": colors["100"],
|
270
|
-
"--w-button-border": colors["200"],
|
271
|
-
"--w-button-hover-border": colors["300"]
|
272
|
-
}
|
273
|
-
when :outline
|
274
|
-
{
|
275
|
-
"--w-button-color": colors["600"],
|
276
|
-
"--w-button-border": colors["300"],
|
277
|
-
"--w-button-hover-bg": colors["50"],
|
278
|
-
"--w-button-hover-border": colors["400"],
|
279
|
-
"--w-button-hover-color": colors["700"]
|
280
|
-
}
|
281
|
-
when :ghost
|
282
|
-
{
|
283
|
-
"--w-button-color": colors["600"],
|
284
|
-
"--w-button-hover-bg": colors["50"],
|
285
|
-
"--w-button-hover-color": colors["700"]
|
286
|
-
}
|
287
|
-
when :plain
|
288
|
-
{
|
289
|
-
"--w-button-color": colors["600"],
|
290
|
-
"--w-button-hover-color": colors["700"],
|
291
|
-
"--w-button-active-color": colors["800"]
|
292
|
-
}
|
293
|
-
else
|
294
|
-
{}
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
def process_custom_theme(custom)
|
299
|
-
return {} unless custom
|
300
|
-
|
301
|
-
{
|
302
|
-
"--w-button-color": custom[:color],
|
303
|
-
"--w-button-bg": custom[:background],
|
304
|
-
"--w-button-border": custom[:border],
|
305
|
-
"--w-button-hover-color": custom.dig(:hover, :color),
|
306
|
-
"--w-button-hover-bg": custom.dig(:hover, :background),
|
307
|
-
"--w-button-hover-border": custom.dig(:hover, :border),
|
308
|
-
"--w-button-active-color": custom.dig(:active, :color),
|
309
|
-
"--w-button-active-bg": custom.dig(:active, :background),
|
310
|
-
"--w-button-active-border": custom.dig(:active, :border)
|
311
|
-
}.compact
|
312
|
-
end
|
313
|
-
|
314
|
-
def generate_styles(styles)
|
315
|
-
styles.map { |k, v| "#{k}: #{v}" }.join(";")
|
316
|
-
end
|
317
|
-
|
318
|
-
def determine_active_features(loading, dropdown, loading_text = nil, copy_to_clipboard = nil, confirm = nil, tooltip = nil, use_default_controller = true)
|
319
|
-
features = {}
|
320
|
-
features[:loading] = true if (loading || loading_text.present?) && use_default_controller
|
321
|
-
features[:dropdown] = true if dropdown && use_default_controller
|
322
|
-
features[:copy_to_clipboard] = true if copy_to_clipboard.present? && use_default_controller
|
323
|
-
features[:confirm] = true if confirm.present? && use_default_controller
|
324
|
-
features[:tooltip] = true if tooltip.present? && use_default_controller
|
325
|
-
features
|
326
|
-
end
|
327
|
-
|
328
|
-
def setup_features(active_features, options, use_default_controller, loading_text)
|
329
|
-
return unless use_default_controller && active_features.any?
|
330
|
-
|
331
|
-
active_features.each do |feature, _value|
|
332
|
-
feature_config = BUTTON_FEATURES[feature]
|
333
|
-
next unless feature_config
|
334
|
-
|
335
|
-
# Skip adding controller for dropdown feature since it's handled by wrapper
|
336
|
-
if feature_config[:wrapper_required]
|
337
|
-
# For dropdown, only set the action, not the controller
|
338
|
-
options[:data][:action] = feature_config[:default_stimulus_action]
|
339
|
-
else
|
340
|
-
setup_feature_controller(options, feature_config, loading_text)
|
341
|
-
end
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
def setup_feature_controller(options, feature_config, loading_text)
|
346
|
-
options[:data] ||= {}
|
347
|
-
|
348
|
-
existing_controller = options.dig(:data, :controller)
|
349
|
-
existing_action = options.dig(:data, :action)
|
350
|
-
|
351
|
-
options[:data][:controller] = [
|
352
|
-
existing_controller,
|
353
|
-
feature_config[:stimulus_controller]
|
354
|
-
].compact.join(" ")
|
355
|
-
|
356
|
-
options[:data][:action] = [
|
357
|
-
existing_action,
|
358
|
-
feature_config[:default_stimulus_action]
|
359
|
-
].compact.join(" ")
|
360
|
-
|
361
|
-
# Add feature-specific data attributes
|
362
|
-
if feature_config[:stimulus_controller] == "button" && loading_text.present?
|
363
|
-
options[:data][:button_loading_text] = loading_text
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
def setup_link_options(options, href, target, method)
|
368
|
-
return unless href.present?
|
369
|
-
|
370
|
-
options[:href] = href
|
371
|
-
options[:target] = target if target
|
372
|
-
options[:data][:method] = method if method != :get
|
373
|
-
options[:rel] = "noopener noreferrer" if target == "_blank"
|
374
|
-
end
|
375
|
-
|
376
|
-
def setup_dropdown_options(options, additional_classes, dropdown, dropdown_items, wrapper_data)
|
377
|
-
additional_classes = "#{additional_classes} w-button-dropdown"
|
378
|
-
|
379
|
-
options[:data][:dropdown_target] = "button"
|
380
|
-
|
381
|
-
wrapper_data.merge!(
|
382
|
-
controller: "dropdown",
|
383
|
-
dropdown_id: "dropdown-#{SecureRandom.hex(4)}"
|
384
|
-
)
|
385
|
-
|
386
|
-
if dropdown.is_a?(Hash)
|
387
|
-
wrapper_data.merge!(
|
388
|
-
dropdown_position_value: dropdown[:position]&.to_s || "bottom",
|
389
|
-
dropdown_align_value: dropdown[:align]&.to_s || "start",
|
390
|
-
dropdown_trigger_value: dropdown[:trigger]&.to_s || "click"
|
391
|
-
)
|
392
|
-
else
|
393
|
-
wrapper_data.merge!(
|
394
|
-
dropdown_position_value: "bottom",
|
395
|
-
dropdown_align_value: "start",
|
396
|
-
dropdown_trigger_value: "click"
|
397
|
-
)
|
398
|
-
end
|
399
|
-
|
400
|
-
normalize_dropdown_items(dropdown_items)
|
401
|
-
end
|
402
|
-
|
403
|
-
def setup_wrapper_options(active_features, additional_classes, wrapper_data)
|
404
|
-
return nil unless needs_wrapper?(active_features)
|
405
|
-
|
406
|
-
{
|
407
|
-
class: [ "w-button-wrapper", additional_classes ].compact.join(" "),
|
408
|
-
data: wrapper_data,
|
409
|
-
role: active_features[:dropdown] ? "menu" : nil
|
410
|
-
}.compact
|
411
|
-
end
|
412
|
-
|
413
|
-
def needs_wrapper?(active_features)
|
414
|
-
active_features.any? { |feature, _| BUTTON_FEATURES[feature][:wrapper_required] }
|
415
|
-
end
|
416
|
-
|
417
|
-
def normalize_dropdown_items(items, parent_id = nil)
|
418
|
-
return [] unless items
|
419
|
-
|
420
|
-
items.map.with_index do |item, index|
|
421
|
-
item_id = generate_item_id(parent_id, index)
|
422
|
-
|
423
|
-
normalized_item = {
|
424
|
-
id: item_id,
|
425
|
-
text: item[:text],
|
426
|
-
href: item[:href],
|
427
|
-
divider: item[:divider]
|
428
|
-
}
|
429
|
-
|
430
|
-
if item[:children].present?
|
431
|
-
normalized_item[:children] = normalize_dropdown_items(item[:children], item_id)
|
432
|
-
end
|
433
|
-
|
434
|
-
normalized_item.compact
|
435
|
-
end
|
436
|
-
end
|
437
|
-
|
438
|
-
def generate_item_id(parent_id, index)
|
439
|
-
base = parent_id ? "#{parent_id}-" : "dropdown-item-"
|
440
|
-
"#{base}#{index}"
|
441
|
-
end
|
442
|
-
|
443
|
-
def setup_clipboard_options(options, additional_classes, copy_to_clipboard, wrapper_data)
|
444
|
-
return unless copy_to_clipboard.present?
|
445
|
-
|
446
|
-
clipboard_config = normalize_clipboard_options(copy_to_clipboard)
|
447
|
-
|
448
|
-
wrapper_data.merge!(
|
449
|
-
controller: "clipboard button",
|
450
|
-
clipboard_text_value: clipboard_config[:text],
|
451
|
-
clipboard_feedback_text_value: clipboard_config[:feedback_text],
|
452
|
-
clipboard_feedback_position_value: clipboard_config[:position],
|
453
|
-
clipboard_feedback_duration_value: clipboard_config[:duration]
|
454
|
-
)
|
455
|
-
|
456
|
-
options[:data][:clipboard_target] = "button"
|
457
|
-
options[:data][:button_target] = "button"
|
458
|
-
end
|
459
|
-
|
460
|
-
def normalize_clipboard_options(options)
|
461
|
-
if options.is_a?(Hash)
|
462
|
-
{
|
463
|
-
text: options[:text],
|
464
|
-
feedback_text: options[:feedback_text] || "Copied!",
|
465
|
-
position: options[:position] || "top",
|
466
|
-
duration: options[:duration] || 2000
|
467
|
-
}
|
468
|
-
else
|
469
|
-
{
|
470
|
-
text: options.to_s,
|
471
|
-
feedback_text: "Copied!",
|
472
|
-
position: "top",
|
473
|
-
duration: 2000
|
474
|
-
}
|
475
|
-
end
|
476
|
-
end
|
477
|
-
|
478
|
-
def setup_confirmation_options(options, additional_classes, confirm, wrapper_data)
|
479
|
-
return unless confirm.present?
|
480
|
-
|
481
|
-
confirm_config = normalize_confirmation_options(confirm)
|
482
|
-
|
483
|
-
# Use the same theme processing as regular buttons
|
484
|
-
confirm_theme_styles = process_theme(:solid, { name: confirm_config[:variant] })
|
485
|
-
cancel_theme_styles = process_theme(:subtle, { name: :secondary })
|
486
|
-
|
487
|
-
wrapper_data.merge!(
|
488
|
-
controller: "confirmation",
|
489
|
-
confirmation_title_value: confirm_config[:title],
|
490
|
-
confirmation_message_value: confirm_config[:message],
|
491
|
-
confirmation_icon_color_value: confirm_config[:variant],
|
492
|
-
confirmation_confirm_text_value: confirm_config[:confirm_text],
|
493
|
-
confirmation_cancel_text_value: confirm_config[:cancel_text],
|
494
|
-
confirmation_confirm_styles_value: confirm_theme_styles,
|
495
|
-
confirmation_cancel_styles_value: cancel_theme_styles
|
496
|
-
)
|
497
|
-
|
498
|
-
# Only add loading state if enabled
|
499
|
-
if confirm_config[:loading]
|
500
|
-
wrapper_data.merge!(
|
501
|
-
confirmation_loading_value: "true",
|
502
|
-
confirmation_loading_text_value: confirm_config[:loading_text]
|
503
|
-
)
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
def normalize_confirmation_options(options)
|
508
|
-
if options.is_a?(String)
|
509
|
-
{
|
510
|
-
title: "Confirm Action",
|
511
|
-
message: options,
|
512
|
-
variant: :info,
|
513
|
-
confirm_text: "Confirm",
|
514
|
-
cancel_text: "Cancel"
|
515
|
-
}
|
516
|
-
else
|
517
|
-
{
|
518
|
-
title: options[:title] || "Confirm Action",
|
519
|
-
message: options[:message],
|
520
|
-
variant: options[:variant] || :info,
|
521
|
-
confirm_text: options[:confirm_text] || "Confirm",
|
522
|
-
cancel_text: options[:cancel_text] || "Cancel",
|
523
|
-
loading: options[:loading] || false,
|
524
|
-
loading_text: options[:loading_text] || "Processing..."
|
525
|
-
}
|
526
|
-
end
|
527
|
-
end
|
528
|
-
|
529
|
-
def setup_tooltip_options(options, additional_classes, tooltip, wrapper_data)
|
530
|
-
tooltip_config = normalize_tooltip_options(tooltip)
|
531
|
-
|
532
|
-
# Check if dropdown is present
|
533
|
-
has_dropdown = wrapper_data[:controller]&.include?("dropdown")
|
534
|
-
has_clipboard = wrapper_data[:controller]&.include?("clipboard")
|
535
|
-
|
536
|
-
# Get the appropriate action based on trigger type
|
537
|
-
# Force hover behavior if dropdown is present
|
538
|
-
trigger_type = (has_dropdown || has_clipboard) ? :hover : tooltip_config[:trigger].to_sym
|
539
|
-
tooltip_action = BUTTON_FEATURES[:tooltip][:default_stimulus_action][trigger_type]
|
540
|
-
|
541
|
-
# Merge controllers
|
542
|
-
existing_controller = wrapper_data[:controller]
|
543
|
-
wrapper_data[:controller] = [
|
544
|
-
existing_controller,
|
545
|
-
"tooltip"
|
546
|
-
].compact.join(" ")
|
547
|
-
|
548
|
-
# Merge actions
|
549
|
-
existing_action = wrapper_data[:action]
|
550
|
-
if has_dropdown
|
551
|
-
# Keep the dropdown toggle action and add tooltip hover actions
|
552
|
-
wrapper_data[:action] = [
|
553
|
-
"click->dropdown#toggle", # Ensure dropdown action comes first
|
554
|
-
tooltip_action
|
555
|
-
].compact.join(" ")
|
556
|
-
elsif has_clipboard
|
557
|
-
# Keep the clipboard copy action and add tooltip hover actions
|
558
|
-
wrapper_data[:action] = [
|
559
|
-
"click->clipboard#copy click->button#toggleLoading",
|
560
|
-
tooltip_action
|
561
|
-
].compact.join(" ")
|
562
|
-
else
|
563
|
-
wrapper_data[:action] = [
|
564
|
-
existing_action,
|
565
|
-
tooltip_action
|
566
|
-
].compact.join(" ")
|
567
|
-
end
|
568
|
-
|
569
|
-
# Handle theme data
|
570
|
-
theme = tooltip_config[:theme]
|
571
|
-
theme_name = theme.is_a?(Hash) ? theme[:name] : theme
|
572
|
-
|
573
|
-
wrapper_data.merge!(
|
574
|
-
tooltip_content_value: tooltip_config[:content],
|
575
|
-
tooltip_position_value: tooltip_config[:position],
|
576
|
-
tooltip_align_value: tooltip_config[:align],
|
577
|
-
tooltip_trigger_value: trigger_type,
|
578
|
-
tooltip_show_delay_value: tooltip_config[:delay][:show],
|
579
|
-
tooltip_hide_delay_value: tooltip_config[:delay][:hide],
|
580
|
-
tooltip_offset_value: tooltip_config[:offset],
|
581
|
-
tooltip_theme_value: theme_name,
|
582
|
-
tooltip_size_value: tooltip_config[:size],
|
583
|
-
tooltip_arrow_value: tooltip_config[:arrow]
|
584
|
-
)
|
585
|
-
|
586
|
-
# Add custom theme styles if present
|
587
|
-
if theme.is_a?(Hash) && theme[:custom]
|
588
|
-
custom_styles = []
|
589
|
-
custom_styles << "--tooltip-text-color: #{theme[:custom][:color]}" if theme[:custom][:color]
|
590
|
-
custom_styles << "--tooltip-bg-color: #{theme[:custom][:background]}" if theme[:custom][:background]
|
591
|
-
wrapper_data[:tooltip_custom_style_value] = custom_styles.join(";")
|
592
|
-
end
|
593
|
-
|
594
|
-
options[:data][:tooltip_target] = "trigger"
|
595
|
-
options[:aria] ||= {}
|
596
|
-
options[:aria][:describedby] = "tooltip-#{SecureRandom.hex(4)}"
|
597
|
-
end
|
598
|
-
|
599
|
-
def normalize_tooltip_options(options)
|
600
|
-
if options.is_a?(String)
|
601
|
-
{
|
602
|
-
content: options,
|
603
|
-
position: "top",
|
604
|
-
align: "center",
|
605
|
-
trigger: "hover",
|
606
|
-
delay: { show: 0, hide: 0 },
|
607
|
-
offset: 8,
|
608
|
-
theme: "light",
|
609
|
-
size: "md",
|
610
|
-
arrow: false
|
611
|
-
}
|
612
|
-
else
|
613
|
-
theme = options[:theme]
|
614
|
-
theme_data = if theme.is_a?(Hash) && theme[:custom]
|
615
|
-
{
|
616
|
-
name: "custom",
|
617
|
-
custom: {
|
618
|
-
color: theme.dig(:custom, :color),
|
619
|
-
background: theme.dig(:custom, :background)
|
620
|
-
}
|
621
|
-
}
|
622
|
-
else
|
623
|
-
{ name: theme || "light" }
|
624
|
-
end
|
625
|
-
|
626
|
-
{
|
627
|
-
content: options[:content],
|
628
|
-
position: options[:position] || "top",
|
629
|
-
align: options[:align] || "center",
|
630
|
-
trigger: options[:trigger] || "hover",
|
631
|
-
delay: {
|
632
|
-
show: options.dig(:delay, :show) || 0,
|
633
|
-
hide: options.dig(:delay, :hide) || 0
|
634
|
-
},
|
635
|
-
offset: options[:offset] || 8,
|
636
|
-
theme: theme_data,
|
637
|
-
size: options[:size] || "md",
|
638
|
-
arrow: options[:arrow] || false
|
639
|
-
}
|
640
|
-
end
|
641
|
-
end
|
642
|
-
|
643
|
-
def render_button(content, variant_class, size_class, radius_class, gradient_class, icon, icon_position, icon_only,
|
644
|
-
loading, loading_text, additional_classes, disabled, options, href, underline,
|
645
|
-
dropdown, dropdown_items, dropdown_icon, wrapper_options)
|
646
|
-
|
647
|
-
render partial: "wilday_ui/button",
|
648
|
-
locals: {
|
649
|
-
content: content,
|
650
|
-
variant_class: variant_class,
|
651
|
-
size_class: size_class,
|
652
|
-
radius_class: radius_class,
|
653
|
-
gradient_class: gradient_class,
|
654
|
-
icon: icon,
|
655
|
-
icon_position: icon_position,
|
656
|
-
icon_only: icon_only,
|
657
|
-
loading: loading,
|
658
|
-
loading_text: loading_text,
|
659
|
-
additional_classes: additional_classes,
|
660
|
-
disabled: disabled,
|
661
|
-
html_options: options,
|
662
|
-
href: href,
|
663
|
-
underline: underline,
|
664
|
-
dropdown: dropdown,
|
665
|
-
dropdown_items: dropdown_items,
|
666
|
-
dropdown_icon: dropdown_icon,
|
667
|
-
wrapper_options: wrapper_options
|
668
|
-
}
|
669
|
-
end
|
670
|
-
end
|
671
|
-
end
|
672
|
-
end
|