better_ui 0.9.0 → 0.9.1

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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/lib/better_ui/version.rb +1 -1
  3. data/spec/components/previews/better_ui/action_messages_component_preview/all_styles.html.erb +17 -0
  4. data/spec/components/previews/better_ui/action_messages_component_preview/all_variants.html.erb +19 -0
  5. data/spec/components/previews/better_ui/action_messages_component_preview/auto_dismiss.html.erb +51 -0
  6. data/spec/components/previews/better_ui/action_messages_component_preview/dismissible.html.erb +19 -0
  7. data/spec/components/previews/better_ui/action_messages_component_preview/with_title.html.erb +17 -0
  8. data/spec/components/previews/better_ui/action_messages_component_preview.rb +224 -0
  9. data/spec/components/previews/better_ui/avatar_component_preview/all_shapes.html.erb +26 -0
  10. data/spec/components/previews/better_ui/avatar_component_preview/all_sizes.html.erb +24 -0
  11. data/spec/components/previews/better_ui/avatar_component_preview/all_variants.html.erb +12 -0
  12. data/spec/components/previews/better_ui/avatar_component_preview/with_initials.html.erb +22 -0
  13. data/spec/components/previews/better_ui/avatar_component_preview/with_status.html.erb +26 -0
  14. data/spec/components/previews/better_ui/avatar_component_preview.rb +73 -0
  15. data/spec/components/previews/better_ui/badge_component_preview/all_sizes.html.erb +29 -0
  16. data/spec/components/previews/better_ui/badge_component_preview/all_styles.html.erb +26 -0
  17. data/spec/components/previews/better_ui/badge_component_preview/all_variants.html.erb +14 -0
  18. data/spec/components/previews/better_ui/badge_component_preview/counter_badges.html.erb +39 -0
  19. data/spec/components/previews/better_ui/badge_component_preview/dot_badges.html.erb +28 -0
  20. data/spec/components/previews/better_ui/badge_component_preview.rb +69 -0
  21. data/spec/components/previews/better_ui/breadcrumb/breadcrumb_component_preview/all_separators.html.erb +47 -0
  22. data/spec/components/previews/better_ui/breadcrumb/breadcrumb_component_preview/default.html.erb +23 -0
  23. data/spec/components/previews/better_ui/breadcrumb/breadcrumb_component_preview/with_icons.html.erb +43 -0
  24. data/spec/components/previews/better_ui/breadcrumb/breadcrumb_component_preview.rb +38 -0
  25. data/spec/components/previews/better_ui/button_component_preview/all_sizes.html.erb +25 -0
  26. data/spec/components/previews/better_ui/button_component_preview/all_variants.html.erb +14 -0
  27. data/spec/components/previews/better_ui/button_component_preview/as_links.html.erb +18 -0
  28. data/spec/components/previews/better_ui/button_component_preview/auto_loading_submit.html.erb +112 -0
  29. data/spec/components/previews/better_ui/button_component_preview/external_links.html.erb +61 -0
  30. data/spec/components/previews/better_ui/button_component_preview/form_integration.html.erb +102 -0
  31. data/spec/components/previews/better_ui/button_component_preview/interactive.html.erb +149 -0
  32. data/spec/components/previews/better_ui/button_component_preview/link_states.html.erb +36 -0
  33. data/spec/components/previews/better_ui/button_component_preview/loading_states.html.erb +62 -0
  34. data/spec/components/previews/better_ui/button_component_preview/turbo_method_links.html.erb +98 -0
  35. data/spec/components/previews/better_ui/button_component_preview/with_icons.html.erb +123 -0
  36. data/spec/components/previews/better_ui/button_component_preview.rb +155 -0
  37. data/spec/components/previews/better_ui/card_component_preview/all_sizes.html.erb +10 -0
  38. data/spec/components/previews/better_ui/card_component_preview/all_styles.html.erb +22 -0
  39. data/spec/components/previews/better_ui/card_component_preview/all_variants.html.erb +10 -0
  40. data/spec/components/previews/better_ui/card_component_preview.rb +269 -0
  41. data/spec/components/previews/better_ui/container_component_preview/all_sizes.html.erb +13 -0
  42. data/spec/components/previews/better_ui/container_component_preview.rb +59 -0
  43. data/spec/components/previews/better_ui/dialog/alert_component_preview/all_variants.html.erb +17 -0
  44. data/spec/components/previews/better_ui/dialog/alert_component_preview/custom_button_label.html.erb +14 -0
  45. data/spec/components/previews/better_ui/dialog/alert_component_preview/default.html.erb +13 -0
  46. data/spec/components/previews/better_ui/dialog/alert_component_preview/playground.html.erb +16 -0
  47. data/spec/components/previews/better_ui/dialog/alert_component_preview/without_icon.html.erb +14 -0
  48. data/spec/components/previews/better_ui/dialog/alert_component_preview.rb +57 -0
  49. data/spec/components/previews/better_ui/dialog/confirm_component_preview/all_variants.html.erb +17 -0
  50. data/spec/components/previews/better_ui/dialog/confirm_component_preview/custom_labels.html.erb +15 -0
  51. data/spec/components/previews/better_ui/dialog/confirm_component_preview/danger_confirm.html.erb +15 -0
  52. data/spec/components/previews/better_ui/dialog/confirm_component_preview/default.html.erb +13 -0
  53. data/spec/components/previews/better_ui/dialog/confirm_component_preview/playground.html.erb +17 -0
  54. data/spec/components/previews/better_ui/dialog/confirm_component_preview.rb +60 -0
  55. data/spec/components/previews/better_ui/dialog/dialog_component_preview/all_sizes.html.erb +32 -0
  56. data/spec/components/previews/better_ui/dialog/dialog_component_preview/default.html.erb +34 -0
  57. data/spec/components/previews/better_ui/dialog/dialog_component_preview/no_close_button.html.erb +28 -0
  58. data/spec/components/previews/better_ui/dialog/dialog_component_preview/playground.html.erb +39 -0
  59. data/spec/components/previews/better_ui/dialog/dialog_component_preview/with_all_slots.html.erb +52 -0
  60. data/spec/components/previews/better_ui/dialog/dialog_component_preview.rb +51 -0
  61. data/spec/components/previews/better_ui/divider_component_preview/all_styles.html.erb +58 -0
  62. data/spec/components/previews/better_ui/divider_component_preview/with_labels.html.erb +67 -0
  63. data/spec/components/previews/better_ui/divider_component_preview.rb +62 -0
  64. data/spec/components/previews/better_ui/drawer/header_component_preview.rb +169 -0
  65. data/spec/components/previews/better_ui/drawer/layout_component_preview/complete_layout.html.erb +87 -0
  66. data/spec/components/previews/better_ui/drawer/layout_component_preview/dark_theme.html.erb +36 -0
  67. data/spec/components/previews/better_ui/drawer/layout_component_preview/dashboard_example.html.erb +188 -0
  68. data/spec/components/previews/better_ui/drawer/layout_component_preview/default.html.erb +22 -0
  69. data/spec/components/previews/better_ui/drawer/layout_component_preview/primary_theme.html.erb +36 -0
  70. data/spec/components/previews/better_ui/drawer/layout_component_preview/right_sidebar.html.erb +44 -0
  71. data/spec/components/previews/better_ui/drawer/layout_component_preview/with_header_only.html.erb +20 -0
  72. data/spec/components/previews/better_ui/drawer/layout_component_preview/with_sidebar_only.html.erb +21 -0
  73. data/spec/components/previews/better_ui/drawer/layout_component_preview.rb +91 -0
  74. data/spec/components/previews/better_ui/drawer/nav_group_component_preview/complete_navigation.html.erb +55 -0
  75. data/spec/components/previews/better_ui/drawer/nav_group_component_preview.rb +163 -0
  76. data/spec/components/previews/better_ui/drawer/nav_item_component_preview.rb +104 -0
  77. data/spec/components/previews/better_ui/drawer/sidebar_component_preview.rb +212 -0
  78. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview/all_sizes.html.erb +19 -0
  79. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview/default.html.erb +12 -0
  80. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview/disabled_items.html.erb +14 -0
  81. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview/placement_options.html.erb +16 -0
  82. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview/playground.html.erb +35 -0
  83. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview/with_dividers_and_headers.html.erb +18 -0
  84. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview/with_icons.html.erb +34 -0
  85. data/spec/components/previews/better_ui/dropdown/dropdown_component_preview.rb +59 -0
  86. data/spec/components/previews/better_ui/fa_icon_component_preview/all_sizes.html.erb +17 -0
  87. data/spec/components/previews/better_ui/fa_icon_component_preview/all_styles.html.erb +19 -0
  88. data/spec/components/previews/better_ui/fa_icon_component_preview/all_variants.html.erb +26 -0
  89. data/spec/components/previews/better_ui/fa_icon_component_preview/animations.html.erb +26 -0
  90. data/spec/components/previews/better_ui/fa_icon_component_preview/transformations.html.erb +88 -0
  91. data/spec/components/previews/better_ui/fa_icon_component_preview.rb +85 -0
  92. data/spec/components/previews/better_ui/forms/checkbox_component_preview/all_sizes.html.erb +12 -0
  93. data/spec/components/previews/better_ui/forms/checkbox_component_preview/all_variants.html.erb +12 -0
  94. data/spec/components/previews/better_ui/forms/checkbox_component_preview/form_integration.html.erb +32 -0
  95. data/spec/components/previews/better_ui/forms/checkbox_component_preview.rb +143 -0
  96. data/spec/components/previews/better_ui/forms/checkbox_group_component_preview/all_variants.html.erb +14 -0
  97. data/spec/components/previews/better_ui/forms/checkbox_group_component_preview/form_integration.html.erb +47 -0
  98. data/spec/components/previews/better_ui/forms/checkbox_group_component_preview/orientations.html.erb +34 -0
  99. data/spec/components/previews/better_ui/forms/checkbox_group_component_preview.rb +150 -0
  100. data/spec/components/previews/better_ui/forms/number_input_component_preview/all_sizes.html.erb +14 -0
  101. data/spec/components/previews/better_ui/forms/number_input_component_preview/form_integration.html.erb +45 -0
  102. data/spec/components/previews/better_ui/forms/number_input_component_preview.rb +211 -0
  103. data/spec/components/previews/better_ui/forms/password_input_component_preview/all_sizes.html.erb +12 -0
  104. data/spec/components/previews/better_ui/forms/password_input_component_preview/confirm_password_example.html.erb +29 -0
  105. data/spec/components/previews/better_ui/forms/password_input_component_preview/form_integration.html.erb +34 -0
  106. data/spec/components/previews/better_ui/forms/password_input_component_preview.rb +181 -0
  107. data/spec/components/previews/better_ui/forms/select_component_preview/all_sizes.html.erb +13 -0
  108. data/spec/components/previews/better_ui/forms/select_component_preview/all_states.html.erb +64 -0
  109. data/spec/components/previews/better_ui/forms/select_component_preview.rb +167 -0
  110. data/spec/components/previews/better_ui/forms/text_input_component_preview/all_sizes.html.erb +12 -0
  111. data/spec/components/previews/better_ui/forms/text_input_component_preview/all_types.html.erb +12 -0
  112. data/spec/components/previews/better_ui/forms/text_input_component_preview/form_integration.html.erb +33 -0
  113. data/spec/components/previews/better_ui/forms/text_input_component_preview.rb +247 -0
  114. data/spec/components/previews/better_ui/forms/textarea_component_preview/all_resize_variants.html.erb +13 -0
  115. data/spec/components/previews/better_ui/forms/textarea_component_preview/all_sizes.html.erb +12 -0
  116. data/spec/components/previews/better_ui/forms/textarea_component_preview/form_integration.html.erb +36 -0
  117. data/spec/components/previews/better_ui/forms/textarea_component_preview.rb +239 -0
  118. data/spec/components/previews/better_ui/heading_component_preview/all_alignments.html.erb +12 -0
  119. data/spec/components/previews/better_ui/heading_component_preview/all_levels.html.erb +7 -0
  120. data/spec/components/previews/better_ui/heading_component_preview/all_variants.html.erb +14 -0
  121. data/spec/components/previews/better_ui/heading_component_preview.rb +113 -0
  122. data/spec/components/previews/better_ui/link_component_preview/all_sizes.html.erb +25 -0
  123. data/spec/components/previews/better_ui/link_component_preview/all_styles.html.erb +14 -0
  124. data/spec/components/previews/better_ui/link_component_preview/all_variants.html.erb +14 -0
  125. data/spec/components/previews/better_ui/link_component_preview/with_icons.html.erb +66 -0
  126. data/spec/components/previews/better_ui/link_component_preview.rb +66 -0
  127. data/spec/components/previews/better_ui/progress_component_preview/all_sizes.html.erb +15 -0
  128. data/spec/components/previews/better_ui/progress_component_preview/all_variants.html.erb +11 -0
  129. data/spec/components/previews/better_ui/progress_component_preview.rb +64 -0
  130. data/spec/components/previews/better_ui/spinner_component_preview/all_sizes.html.erb +17 -0
  131. data/spec/components/previews/better_ui/spinner_component_preview/all_variants.html.erb +11 -0
  132. data/spec/components/previews/better_ui/spinner_component_preview.rb +44 -0
  133. data/spec/components/previews/better_ui/table/table_component_preview/all_sizes.html.erb +28 -0
  134. data/spec/components/previews/better_ui/table/table_component_preview/all_variants.html.erb +34 -0
  135. data/spec/components/previews/better_ui/table/table_component_preview/bordered.html.erb +33 -0
  136. data/spec/components/previews/better_ui/table/table_component_preview/collection_mode.html.erb +31 -0
  137. data/spec/components/previews/better_ui/table/table_component_preview/default.html.erb +33 -0
  138. data/spec/components/previews/better_ui/table/table_component_preview/empty_state.html.erb +36 -0
  139. data/spec/components/previews/better_ui/table/table_component_preview/highlighted.html.erb +64 -0
  140. data/spec/components/previews/better_ui/table/table_component_preview/hoverable.html.erb +27 -0
  141. data/spec/components/previews/better_ui/table/table_component_preview/inside_card.html.erb +173 -0
  142. data/spec/components/previews/better_ui/table/table_component_preview/sortable.html.erb +44 -0
  143. data/spec/components/previews/better_ui/table/table_component_preview/striped.html.erb +31 -0
  144. data/spec/components/previews/better_ui/table/table_component_preview/with_footer.html.erb +40 -0
  145. data/spec/components/previews/better_ui/table/table_component_preview.rb +79 -0
  146. data/spec/components/previews/better_ui/tabs/container_component_preview/alignments.html.erb +24 -0
  147. data/spec/components/previews/better_ui/tabs/container_component_preview/all_sizes.html.erb +24 -0
  148. data/spec/components/previews/better_ui/tabs/container_component_preview/all_variants.html.erb +24 -0
  149. data/spec/components/previews/better_ui/tabs/container_component_preview/bordered_style.html.erb +30 -0
  150. data/spec/components/previews/better_ui/tabs/container_component_preview/default.html.erb +30 -0
  151. data/spec/components/previews/better_ui/tabs/container_component_preview/disabled_tab.html.erb +65 -0
  152. data/spec/components/previews/better_ui/tabs/container_component_preview/pills_style.html.erb +34 -0
  153. data/spec/components/previews/better_ui/tabs/container_component_preview/turbo_mode.html.erb +40 -0
  154. data/spec/components/previews/better_ui/tabs/container_component_preview/vertical_left.html.erb +38 -0
  155. data/spec/components/previews/better_ui/tabs/container_component_preview/vertical_right.html.erb +30 -0
  156. data/spec/components/previews/better_ui/tabs/container_component_preview/with_icons_and_badges.html.erb +71 -0
  157. data/spec/components/previews/better_ui/tabs/container_component_preview.rb +130 -0
  158. data/spec/components/previews/better_ui/tag_component_preview/all_styles.html.erb +14 -0
  159. data/spec/components/previews/better_ui/tag_component_preview/all_variants.html.erb +14 -0
  160. data/spec/components/previews/better_ui/tag_component_preview/as_links.html.erb +14 -0
  161. data/spec/components/previews/better_ui/tag_component_preview/dismissible.html.erb +34 -0
  162. data/spec/components/previews/better_ui/tag_component_preview.rb +56 -0
  163. data/spec/components/previews/better_ui/tooltip_component_preview/all_positions.html.erb +25 -0
  164. data/spec/components/previews/better_ui/tooltip_component_preview/variants.html.erb +37 -0
  165. data/spec/components/previews/better_ui/tooltip_component_preview.rb +40 -0
  166. metadata +164 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c218661dc93efb93042ba9a4a5277091a7dac3de216acc162d50c8d36077bc8
4
- data.tar.gz: b06ea500b4d3c547249664dcee953910457263029549d77af2a3314cef45ef58
3
+ metadata.gz: bfebd7a7f2bdd44a6d4e0bde15d4608c970ddab81a6d4cdd2454fead24711239
4
+ data.tar.gz: '09f376342d514046ba25b525f35d499be58493aadccca8b40ad71bbf2c3b2912'
5
5
  SHA512:
6
- metadata.gz: 238ed43c059619f7f8ab17ffcc28aa6e6d461b1de72a7bfe57a9a188da44e4f810381ad2c0aac5118b79013855f985635f4bbc01355558640a7f3cb377695fd9
7
- data.tar.gz: 5a8971012b178358d34198642446a423da9ccee69f6418f6d2cc3bc77529bb96a4185e5f281d14b0a6d83fd5195cc20255e61664c7fa4899ef2c06758b63b04e
6
+ metadata.gz: 48fcb5c0cfcea7748056c19b5f36791498e98dce7bd2a4af0d0e43d7f7f5374495b42bc73b4fd2ee1dbec6fa9dd219185206422580cbf07b32514f1fd58def54
7
+ data.tar.gz: 155edcbbfbbea18cfb4b4b7c4b26fb5b9fd4ae040818f94e00f82410e10d129a968b4d5b575c392a8b0ac708f45bbc1e441d29159d89fd1952cb9a5836cc9467
@@ -1,3 +1,3 @@
1
1
  module BetterUi
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.1"
3
3
  end
@@ -0,0 +1,17 @@
1
+ <div class="p-8 space-y-8">
2
+ <h2 class="text-2xl font-bold mb-6">All Styles (Primary Variant)</h2>
3
+
4
+ <% (@styles || [:solid, :soft, :outline, :ghost]).each do |style| %>
5
+ <div class="space-y-2">
6
+ <h3 class="text-sm font-medium text-grayscale-600 capitalize"><%= style %> Style</h3>
7
+ <%= render BetterUi::ActionMessagesComponent.new(
8
+ variant: (@variant || :primary),
9
+ style: style,
10
+ messages: [
11
+ "This is a #{style} style message.",
12
+ "Each style has different visual appearance."
13
+ ]
14
+ ) %>
15
+ </div>
16
+ <% end %>
17
+ </div>
@@ -0,0 +1,19 @@
1
+ <div class="p-8 space-y-6">
2
+ <h2 class="text-2xl font-bold mb-6">All Variants (Soft Style)</h2>
3
+
4
+ <div class="space-y-4">
5
+ <% (@variants || BetterUi::ApplicationComponent::VARIANTS.keys).each do |variant| %>
6
+ <div>
7
+ <h3 class="text-sm font-medium text-grayscale-600 mb-2 capitalize"><%= variant %></h3>
8
+ <%= render BetterUi::ActionMessagesComponent.new(
9
+ variant: variant,
10
+ style: :soft,
11
+ messages: [
12
+ "This is a #{variant} message.",
13
+ "You can display multiple lines in the message list."
14
+ ]
15
+ ) %>
16
+ </div>
17
+ <% end %>
18
+ </div>
19
+ </div>
@@ -0,0 +1,51 @@
1
+ <div class="p-8 space-y-6">
2
+ <h2 class="text-2xl font-bold mb-6">Auto-Dismiss Messages</h2>
3
+ <p class="text-grayscale-600 mb-4">These messages will automatically disappear after the specified duration. Refresh the page to see them again.</p>
4
+
5
+ <div class="space-y-4">
6
+ <%= render BetterUi::ActionMessagesComponent.new(
7
+ variant: :success,
8
+ style: :soft,
9
+ auto_dismiss: 3,
10
+ title: "Quick Notice (3 seconds)",
11
+ messages: [
12
+ "This message will disappear in 3 seconds.",
13
+ "No user action required."
14
+ ]
15
+ ) %>
16
+
17
+ <%= render BetterUi::ActionMessagesComponent.new(
18
+ variant: :info,
19
+ style: :soft,
20
+ auto_dismiss: 5,
21
+ title: "Standard Notice (5 seconds)",
22
+ messages: [
23
+ "This message will disappear in 5 seconds.",
24
+ "Typical duration for informational messages."
25
+ ]
26
+ ) %>
27
+
28
+ <%= render BetterUi::ActionMessagesComponent.new(
29
+ variant: :warning,
30
+ style: :soft,
31
+ auto_dismiss: 10,
32
+ title: "Important Notice (10 seconds)",
33
+ messages: [
34
+ "This message will disappear in 10 seconds.",
35
+ "Longer duration for important information."
36
+ ]
37
+ ) %>
38
+
39
+ <%= render BetterUi::ActionMessagesComponent.new(
40
+ variant: :danger,
41
+ style: :soft,
42
+ dismissible: true,
43
+ auto_dismiss: 8,
44
+ title: "Combined (8 seconds + Manual Dismiss)",
45
+ messages: [
46
+ "This message auto-dismisses in 8 seconds.",
47
+ "But you can also dismiss it manually with the X button."
48
+ ]
49
+ ) %>
50
+ </div>
51
+ </div>
@@ -0,0 +1,19 @@
1
+ <div class="p-8 space-y-6">
2
+ <h2 class="text-2xl font-bold mb-6">Dismissible Messages</h2>
3
+ <p class="text-grayscale-600 mb-4">Click the X button to dismiss each message.</p>
4
+
5
+ <div class="space-y-4">
6
+ <% (@variants || [:info, :warning, :danger]).each do |variant| %>
7
+ <%= render BetterUi::ActionMessagesComponent.new(
8
+ variant: variant,
9
+ style: :soft,
10
+ dismissible: true,
11
+ title: "#{variant.to_s.capitalize} Message",
12
+ messages: [
13
+ "This is a dismissible #{variant} message.",
14
+ "Click the X button to close it and see the fade-out animation."
15
+ ]
16
+ ) %>
17
+ <% end %>
18
+ </div>
19
+ </div>
@@ -0,0 +1,17 @@
1
+ <div class="p-8 space-y-6">
2
+ <h2 class="text-2xl font-bold mb-6">With Title</h2>
3
+
4
+ <div class="space-y-4">
5
+ <% (@variants || [:info, :success, :warning, :danger]).each do |variant| %>
6
+ <%= render BetterUi::ActionMessagesComponent.new(
7
+ variant: variant,
8
+ style: :soft,
9
+ title: variant.to_s.capitalize,
10
+ messages: [
11
+ "This is a #{variant} message with a title.",
12
+ "The title appears above the message list."
13
+ ]
14
+ ) %>
15
+ <% end %>
16
+ </div>
17
+ </div>
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ # Lookbook previews for ActionMessagesComponent
5
+ #
6
+ # Provides interactive examples of the component with different configurations:
7
+ # - All variants showcase (9 color variants)
8
+ # - All styles showcase (4 visual styles)
9
+ # - Real-world examples (form errors, success messages)
10
+ # - Feature demonstrations (dismissible, auto-dismiss, icons, titles)
11
+ # - Interactive playground with configurable parameters
12
+ #
13
+ # View at: http://localhost:3000/lookbook
14
+ #
15
+ # @label Action Messages
16
+ class ActionMessagesComponentPreview < ViewComponent::Preview
17
+ # Basic component with default settings (info variant, soft style)
18
+ # @label Default
19
+ def default
20
+ render BetterUi::ActionMessagesComponent.new(
21
+ messages: [ "This is an informational message." ]
22
+ )
23
+ end
24
+
25
+ # Showcase all 9 color variants using soft style
26
+ # Demonstrates the full color palette available for messages
27
+ # @label All Variants
28
+ # @display bg_color #f5f5f5
29
+ def all_variants
30
+ @variants = ApplicationComponent::VARIANTS.keys
31
+ render_with_template
32
+ end
33
+
34
+ # Showcase all 4 visual styles using primary variant
35
+ # Demonstrates solid, soft, outline, and ghost appearances
36
+ # @label All Styles
37
+ # @display bg_color #f5f5f5
38
+ def all_styles
39
+ @styles = [ :solid, :soft, :outline, :ghost ]
40
+ @variant = :primary
41
+ render_with_template
42
+ end
43
+
44
+ # Real-world example: Form validation errors
45
+ # Common use case showing danger variant with multiple error messages
46
+ # @label Form Errors
47
+ def form_errors
48
+ render BetterUi::ActionMessagesComponent.new(
49
+ variant: :danger,
50
+ style: :soft,
51
+ title: "Please correct the following errors:",
52
+ messages: [
53
+ "Email can't be blank",
54
+ "Password is too short (minimum is 8 characters)",
55
+ "Password confirmation doesn't match Password"
56
+ ]
57
+ )
58
+ end
59
+
60
+ # Real-world example: Success notification
61
+ # Common use case showing success variant with confirmation message
62
+ # @label Success Message
63
+ def success_message
64
+ render BetterUi::ActionMessagesComponent.new(
65
+ variant: :success,
66
+ style: :soft,
67
+ title: "Success!",
68
+ messages: [ "Your changes have been saved successfully." ]
69
+ )
70
+ end
71
+
72
+ # Demonstrates title feature with common message types
73
+ # Shows how titles provide context for message lists
74
+ # @label With Title
75
+ # @display bg_color #f5f5f5
76
+ def with_title
77
+ @variants = [ :info, :success, :warning, :danger ]
78
+ render_with_template
79
+ end
80
+
81
+ # Demonstrates icon slot with custom SVG icon
82
+ # Icons are passed as block content to the component
83
+ # @label With Icon
84
+ def with_icon
85
+ render BetterUi::ActionMessagesComponent.new(
86
+ variant: :success,
87
+ style: :soft,
88
+ title: "Payment Successful",
89
+ messages: [
90
+ "Your payment has been processed.",
91
+ "You will receive a confirmation email shortly."
92
+ ]
93
+ ) do
94
+ tag.svg(
95
+ class: "w-6 h-6 text-success-600 mt-1",
96
+ fill: "none",
97
+ stroke: "currentColor",
98
+ viewBox: "0 0 24 24",
99
+ xmlns: "http://www.w3.org/2000/svg"
100
+ ) do
101
+ tag.path(
102
+ stroke_linecap: "round",
103
+ stroke_linejoin: "round",
104
+ stroke_width: "2",
105
+ d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
106
+ )
107
+ end
108
+ end
109
+ end
110
+
111
+ # Demonstrates manual dismiss functionality
112
+ # Click X button to see smooth fade-out animation
113
+ # @label Dismissible
114
+ # @display bg_color #f5f5f5
115
+ def dismissible
116
+ @variants = [ :info, :warning, :danger ]
117
+ render_with_template
118
+ end
119
+
120
+ # Demonstrates auto-dismiss feature with different durations
121
+ # Messages automatically disappear after configured seconds
122
+ # Refresh page to see the messages again
123
+ # @label Auto Dismiss
124
+ # @display bg_color #f5f5f5
125
+ def auto_dismiss
126
+ render_with_template
127
+ end
128
+
129
+ # Demonstrates multiple features working together
130
+ # Shows icon, title, dismissible button, and auto-dismiss all at once
131
+ # @label Combined Features
132
+ def combined
133
+ render BetterUi::ActionMessagesComponent.new(
134
+ variant: :warning,
135
+ style: :soft,
136
+ title: "Session Expiring",
137
+ dismissible: true,
138
+ auto_dismiss: 10,
139
+ messages: [
140
+ "Your session will expire in 10 seconds.",
141
+ "Please save your work to avoid losing data."
142
+ ]
143
+ ) do
144
+ tag.svg(
145
+ class: "w-6 h-6 text-warning-600 mt-1",
146
+ fill: "none",
147
+ stroke: "currentColor",
148
+ viewBox: "0 0 24 24",
149
+ xmlns: "http://www.w3.org/2000/svg"
150
+ ) do
151
+ tag.path(
152
+ stroke_linecap: "round",
153
+ stroke_linejoin: "round",
154
+ stroke_width: "2",
155
+ d: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
156
+ )
157
+ end
158
+ end
159
+ end
160
+
161
+ # Demonstrates component with many messages
162
+ # Shows how the component handles longer lists of items
163
+ # @label Multiple Messages
164
+ def multiple_messages
165
+ render BetterUi::ActionMessagesComponent.new(
166
+ variant: :info,
167
+ style: :soft,
168
+ title: "System Updates",
169
+ messages: [
170
+ "Database backup completed successfully",
171
+ "Cache cleared for all users",
172
+ "Email queue processed (142 emails sent)",
173
+ "Security scan completed - no issues found",
174
+ "Server maintenance scheduled for tonight at 2 AM"
175
+ ]
176
+ )
177
+ end
178
+
179
+ # Edge case: Component with empty messages array
180
+ # Shows that component handles empty state gracefully
181
+ # @label Empty Messages
182
+ def empty_messages
183
+ render BetterUi::ActionMessagesComponent.new(
184
+ variant: :info,
185
+ style: :soft,
186
+ title: "No new notifications",
187
+ messages: []
188
+ )
189
+ end
190
+
191
+ # Interactive playground with configurable parameters
192
+ # Experiment with different variants, styles, and features in real-time
193
+ # @label Playground
194
+ # @param variant select { choices: [primary, secondary, accent, success, danger, warning, info, light, dark] }
195
+ # @param style select { choices: [solid, soft, outline, ghost] }
196
+ # @param dismissible toggle
197
+ # @param auto_dismiss number
198
+ # @param title text
199
+ # @param message_1 text
200
+ # @param message_2 text
201
+ # @param message_3 text
202
+ def playground(
203
+ variant: :info,
204
+ style: :soft,
205
+ dismissible: false,
206
+ auto_dismiss: nil,
207
+ title: "Notification",
208
+ message_1: "This is the first message.",
209
+ message_2: "This is the second message.",
210
+ message_3: ""
211
+ )
212
+ messages = [ message_1, message_2, message_3 ].reject(&:blank?)
213
+
214
+ render BetterUi::ActionMessagesComponent.new(
215
+ variant: variant.to_sym,
216
+ style: style.to_sym,
217
+ dismissible: dismissible,
218
+ auto_dismiss: auto_dismiss&.to_f&.positive? ? auto_dismiss.to_f : nil,
219
+ title: title.present? ? title : nil,
220
+ messages: messages
221
+ )
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,26 @@
1
+ <div class="flex flex-wrap items-center gap-6 p-4">
2
+ <% [:circle, :square, :rounded].each do |shape| %>
3
+ <div class="flex flex-col items-center gap-2">
4
+ <%= render BetterUi::AvatarComponent.new(
5
+ src: "https://i.pravatar.cc/150?u=#{shape}",
6
+ alt: "Avatar #{shape}",
7
+ size: :lg,
8
+ shape: shape
9
+ ) %>
10
+ <span class="text-sm text-grayscale-600"><%= shape %></span>
11
+ </div>
12
+ <% end %>
13
+ </div>
14
+ <div class="flex flex-wrap items-center gap-6 p-4 mt-4">
15
+ <% [:circle, :square, :rounded].each do |shape| %>
16
+ <div class="flex flex-col items-center gap-2">
17
+ <%= render BetterUi::AvatarComponent.new(
18
+ name: "John Doe",
19
+ variant: :primary,
20
+ size: :lg,
21
+ shape: shape
22
+ ) %>
23
+ <span class="text-sm text-grayscale-600"><%= shape %></span>
24
+ </div>
25
+ <% end %>
26
+ </div>
@@ -0,0 +1,24 @@
1
+ <div class="flex flex-wrap items-end gap-6 p-4">
2
+ <% [:xs, :sm, :md, :lg, :xl].each do |size| %>
3
+ <div class="flex flex-col items-center gap-2">
4
+ <%= render BetterUi::AvatarComponent.new(
5
+ name: "John Doe",
6
+ variant: :primary,
7
+ size: size
8
+ ) %>
9
+ <span class="text-sm text-grayscale-600"><%= size %></span>
10
+ </div>
11
+ <% end %>
12
+ </div>
13
+ <div class="flex flex-wrap items-end gap-6 p-4 mt-4">
14
+ <% [:xs, :sm, :md, :lg, :xl].each do |size| %>
15
+ <div class="flex flex-col items-center gap-2">
16
+ <%= render BetterUi::AvatarComponent.new(
17
+ src: "https://i.pravatar.cc/150?u=#{size}",
18
+ alt: "Avatar #{size}",
19
+ size: size
20
+ ) %>
21
+ <span class="text-sm text-grayscale-600"><%= size %></span>
22
+ </div>
23
+ <% end %>
24
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="flex flex-wrap items-center gap-6 p-4">
2
+ <% BetterUi::ApplicationComponent::VARIANTS.keys.each do |variant| %>
3
+ <div class="flex flex-col items-center gap-2">
4
+ <%= render BetterUi::AvatarComponent.new(
5
+ name: variant.to_s.capitalize,
6
+ variant: variant,
7
+ size: :lg
8
+ ) %>
9
+ <span class="text-sm text-grayscale-600"><%= variant %></span>
10
+ </div>
11
+ <% end %>
12
+ </div>
@@ -0,0 +1,22 @@
1
+ <div class="flex flex-wrap items-center gap-6 p-4">
2
+ <% [
3
+ ["Alice", :primary],
4
+ ["Bob Smith", :secondary],
5
+ ["Charlie Brown", :accent],
6
+ ["Diana", :success],
7
+ ["Edward Norton", :danger],
8
+ ["Fiona Apple", :warning],
9
+ ["George", :info],
10
+ ["Helen Troy", :light],
11
+ ["Ivan Drago", :dark]
12
+ ].each do |name, variant| %>
13
+ <div class="flex flex-col items-center gap-2">
14
+ <%= render BetterUi::AvatarComponent.new(
15
+ name: name,
16
+ variant: variant,
17
+ size: :lg
18
+ ) %>
19
+ <span class="text-sm text-grayscale-600"><%= name %></span>
20
+ </div>
21
+ <% end %>
22
+ </div>
@@ -0,0 +1,26 @@
1
+ <div class="flex flex-wrap items-center gap-6 p-4">
2
+ <% [:online, :offline, :busy, :away].each do |status| %>
3
+ <div class="flex flex-col items-center gap-2">
4
+ <%= render BetterUi::AvatarComponent.new(
5
+ src: "https://i.pravatar.cc/150?u=#{status}",
6
+ alt: "User #{status}",
7
+ size: :lg,
8
+ status: status
9
+ ) %>
10
+ <span class="text-sm text-grayscale-600"><%= status %></span>
11
+ </div>
12
+ <% end %>
13
+ </div>
14
+ <div class="flex flex-wrap items-center gap-6 p-4 mt-4">
15
+ <% [:online, :offline, :busy, :away].each do |status| %>
16
+ <div class="flex flex-col items-center gap-2">
17
+ <%= render BetterUi::AvatarComponent.new(
18
+ name: "Jane Smith",
19
+ variant: :secondary,
20
+ size: :lg,
21
+ status: status
22
+ ) %>
23
+ <span class="text-sm text-grayscale-600"><%= status %></span>
24
+ </div>
25
+ <% end %>
26
+ </div>
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ # @label Avatar
5
+ class AvatarComponentPreview < ViewComponent::Preview
6
+ # @label Default
7
+ # @display bg_color #f5f5f5
8
+ def default
9
+ render BetterUi::AvatarComponent.new(
10
+ src: "https://i.pravatar.cc/150?u=default",
11
+ alt: "Default avatar"
12
+ )
13
+ end
14
+
15
+ # @label All Variants
16
+ # @display bg_color #f5f5f5
17
+ def all_variants
18
+ render_with_template
19
+ end
20
+
21
+ # @label All Sizes
22
+ # @display bg_color #f5f5f5
23
+ def all_sizes
24
+ render_with_template
25
+ end
26
+
27
+ # @label All Shapes
28
+ # @display bg_color #f5f5f5
29
+ def all_shapes
30
+ render_with_template
31
+ end
32
+
33
+ # @label With Status
34
+ # @display bg_color #f5f5f5
35
+ def with_status
36
+ render_with_template
37
+ end
38
+
39
+ # @label With Initials
40
+ # @display bg_color #f5f5f5
41
+ def with_initials
42
+ render_with_template
43
+ end
44
+
45
+ # @label Playground
46
+ # @param src text
47
+ # @param name text
48
+ # @param variant select { choices: [primary, secondary, accent, success, danger, warning, info, light, dark] }
49
+ # @param size select { choices: [xs, sm, md, lg, xl] }
50
+ # @param shape select { choices: [circle, square, rounded] }
51
+ # @param status select { choices: [~, online, offline, busy, away] }
52
+ def playground(
53
+ src: "",
54
+ name: "John Doe",
55
+ variant: :primary,
56
+ size: :md,
57
+ shape: :circle,
58
+ status: nil
59
+ )
60
+ resolved_src = src.present? ? src : nil
61
+ resolved_status = status.present? ? status.to_sym : nil
62
+
63
+ render BetterUi::AvatarComponent.new(
64
+ src: resolved_src,
65
+ name: name,
66
+ variant: variant.to_sym,
67
+ size: size.to_sym,
68
+ shape: shape.to_sym,
69
+ status: resolved_status
70
+ )
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,29 @@
1
+ <div class="p-8">
2
+ <h3 class="text-lg font-semibold mb-6">Badge Sizes</h3>
3
+
4
+ <div class="space-y-6">
5
+ <% (@sizes || [:xs, :sm, :md, :lg]).each do |size| %>
6
+ <div class="flex items-center gap-4">
7
+ <span class="w-20 text-sm font-medium text-gray-600 uppercase"><%= size %></span>
8
+
9
+ <div class="flex flex-wrap gap-3 items-center">
10
+ <%= render BetterUi::BadgeComponent.new(size: size, variant: :primary) do %>
11
+ Solid <%= size.to_s.upcase %>
12
+ <% end %>
13
+
14
+ <%= render BetterUi::BadgeComponent.new(size: size, variant: :secondary, style: :outline) do %>
15
+ Outline <%= size.to_s.upcase %>
16
+ <% end %>
17
+
18
+ <%= render BetterUi::BadgeComponent.new(size: size, variant: :success, style: :soft) do %>
19
+ Soft <%= size.to_s.upcase %>
20
+ <% end %>
21
+
22
+ <%= render BetterUi::BadgeComponent.new(size: size, variant: :danger, style: :ghost) do %>
23
+ Ghost <%= size.to_s.upcase %>
24
+ <% end %>
25
+ </div>
26
+ </div>
27
+ <% end %>
28
+ </div>
29
+ </div>
@@ -0,0 +1,26 @@
1
+ <div class="p-8 space-y-8">
2
+ <% (@styles || [:solid, :outline, :soft, :ghost]).each do |style| %>
3
+ <div>
4
+ <h3 class="text-lg font-semibold mb-4 capitalize"><%= style %> Style</h3>
5
+ <div class="flex flex-wrap gap-3 items-center">
6
+ <% BetterUi::ApplicationComponent::VARIANTS.each do |variant, _| %>
7
+ <%= render BetterUi::BadgeComponent.new(variant: variant, style: style) do %>
8
+ <%= variant.to_s.capitalize %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+ <% end %>
14
+
15
+ <h3 class="text-lg font-semibold mb-4 mt-8">Pill vs Rounded</h3>
16
+ <div class="flex flex-wrap gap-3 items-center">
17
+ <% (@styles || [:solid, :outline, :soft, :ghost]).each do |style| %>
18
+ <%= render BetterUi::BadgeComponent.new(style: style, pill: true) do %>
19
+ Pill (<%= style %>)
20
+ <% end %>
21
+ <%= render BetterUi::BadgeComponent.new(style: style, pill: false) do %>
22
+ Rounded (<%= style %>)
23
+ <% end %>
24
+ <% end %>
25
+ </div>
26
+ </div>
@@ -0,0 +1,14 @@
1
+ <div class="p-8 space-y-8">
2
+ <% (@styles || [:solid, :outline, :soft, :ghost]).each do |style| %>
3
+ <div>
4
+ <h3 class="text-lg font-semibold mb-4 capitalize"><%= style %> Badges</h3>
5
+ <div class="flex flex-wrap gap-3 items-center">
6
+ <% (@variants || BetterUi::ApplicationComponent::VARIANTS.keys).each do |variant| %>
7
+ <%= render BetterUi::BadgeComponent.new(variant: variant, style: style) do %>
8
+ <%= variant.to_s.capitalize %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,39 @@
1
+ <div class="p-8 space-y-8">
2
+ <div>
3
+ <h3 class="text-lg font-semibold mb-4">Counter Badges (Solid)</h3>
4
+ <div class="flex flex-wrap gap-3 items-center">
5
+ <% BetterUi::ApplicationComponent::VARIANTS.each do |variant, _| %>
6
+ <%= render BetterUi::BadgeComponent.new(variant: variant, counter: rand(1..99)) %>
7
+ <% end %>
8
+ </div>
9
+ </div>
10
+
11
+ <div>
12
+ <h3 class="text-lg font-semibold mb-4">Counter Badges (Outline)</h3>
13
+ <div class="flex flex-wrap gap-3 items-center">
14
+ <% BetterUi::ApplicationComponent::VARIANTS.each do |variant, _| %>
15
+ <%= render BetterUi::BadgeComponent.new(variant: variant, style: :outline, counter: rand(1..99)) %>
16
+ <% end %>
17
+ </div>
18
+ </div>
19
+
20
+ <div>
21
+ <h3 class="text-lg font-semibold mb-4">Counter Sizes</h3>
22
+ <div class="flex flex-wrap gap-3 items-center">
23
+ <%= render BetterUi::BadgeComponent.new(size: :xs, variant: :danger, counter: 3) %>
24
+ <%= render BetterUi::BadgeComponent.new(size: :sm, variant: :danger, counter: 12) %>
25
+ <%= render BetterUi::BadgeComponent.new(size: :md, variant: :danger, counter: 42) %>
26
+ <%= render BetterUi::BadgeComponent.new(size: :lg, variant: :danger, counter: 99) %>
27
+ </div>
28
+ </div>
29
+
30
+ <div>
31
+ <h3 class="text-lg font-semibold mb-4">Pill vs Rounded Counters</h3>
32
+ <div class="flex flex-wrap gap-3 items-center">
33
+ <%= render BetterUi::BadgeComponent.new(variant: :primary, counter: 7, pill: true) %>
34
+ <%= render BetterUi::BadgeComponent.new(variant: :primary, counter: 7, pill: false) %>
35
+ <%= render BetterUi::BadgeComponent.new(variant: :danger, counter: 99, pill: true) %>
36
+ <%= render BetterUi::BadgeComponent.new(variant: :danger, counter: 99, pill: false) %>
37
+ </div>
38
+ </div>
39
+ </div>