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
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ module Table
5
+ class TableComponentPreview < ViewComponent::Preview
6
+ # @label Default
7
+ # @display bg_color "#f5f5f5"
8
+ def default
9
+ render_with_template
10
+ end
11
+
12
+ # @label Bordered
13
+ # @display bg_color "#f5f5f5"
14
+ def bordered
15
+ render_with_template
16
+ end
17
+
18
+ # @label Striped
19
+ # @display bg_color "#f5f5f5"
20
+ def striped
21
+ render_with_template
22
+ end
23
+
24
+ # @label Hoverable
25
+ # @display bg_color "#f5f5f5"
26
+ def hoverable
27
+ render_with_template
28
+ end
29
+
30
+ # @label All Variants
31
+ # @display bg_color "#f5f5f5"
32
+ def all_variants
33
+ render_with_template
34
+ end
35
+
36
+ # @label All Sizes
37
+ # @display bg_color "#f5f5f5"
38
+ def all_sizes
39
+ render_with_template
40
+ end
41
+
42
+ # @label Collection Mode
43
+ # @display bg_color "#f5f5f5"
44
+ def collection_mode
45
+ render_with_template
46
+ end
47
+
48
+ # @label Empty State
49
+ # @display bg_color "#f5f5f5"
50
+ def empty_state
51
+ render_with_template
52
+ end
53
+
54
+ # @label With Footer
55
+ # @display bg_color "#f5f5f5"
56
+ def with_footer
57
+ render_with_template
58
+ end
59
+
60
+ # @label Inside Card
61
+ # @display bg_color "#f5f5f5"
62
+ def inside_card
63
+ render_with_template
64
+ end
65
+
66
+ # @label Highlighted Rows
67
+ # @display bg_color "#f5f5f5"
68
+ def highlighted
69
+ render_with_template
70
+ end
71
+
72
+ # @label Sortable Headers
73
+ # @display bg_color "#f5f5f5"
74
+ def sortable
75
+ render_with_template
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,24 @@
1
+ <div class="p-4 space-y-8">
2
+ <h3 class="text-lg font-semibold mb-4">Tab Alignments</h3>
3
+
4
+ <% %i[start center end].each do |alignment| %>
5
+ <div class="mb-6">
6
+ <p class="text-sm font-medium text-grayscale-500 mb-2 capitalize"><%= alignment %></p>
7
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :pills, alignment: alignment) do |tabs| %>
8
+ <% tabs.with_tab(id: "#{alignment}-tab1", label: "First", active: true) %>
9
+ <% tabs.with_tab(id: "#{alignment}-tab2", label: "Second") %>
10
+ <% tabs.with_tab(id: "#{alignment}-tab3", label: "Third") %>
11
+
12
+ <% tabs.with_panel(id: "#{alignment}-tab1", active: true) do %>
13
+ <div class="p-3 text-sm text-grayscale-600">Alignment: <%= alignment %></div>
14
+ <% end %>
15
+ <% tabs.with_panel(id: "#{alignment}-tab2") do %>
16
+ <div class="p-3 text-sm text-grayscale-600">Tab Two content</div>
17
+ <% end %>
18
+ <% tabs.with_panel(id: "#{alignment}-tab3") do %>
19
+ <div class="p-3 text-sm text-grayscale-600">Tab Three content</div>
20
+ <% end %>
21
+ <% end %>
22
+ </div>
23
+ <% end %>
24
+ </div>
@@ -0,0 +1,24 @@
1
+ <div class="p-4 space-y-8">
2
+ <h3 class="text-lg font-semibold mb-4">All Sizes</h3>
3
+
4
+ <% %i[xs sm md lg xl].each do |size| %>
5
+ <div class="mb-6">
6
+ <p class="text-sm font-medium text-grayscale-500 mb-2 uppercase"><%= size %></p>
7
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :underline, size: size) do |tabs| %>
8
+ <% tabs.with_tab(id: "#{size}-tab1", label: "Tab One", active: true) %>
9
+ <% tabs.with_tab(id: "#{size}-tab2", label: "Tab Two") %>
10
+ <% tabs.with_tab(id: "#{size}-tab3", label: "Tab Three") %>
11
+
12
+ <% tabs.with_panel(id: "#{size}-tab1", active: true) do %>
13
+ <div class="p-3 text-sm text-grayscale-600">Content for size <%= size %></div>
14
+ <% end %>
15
+ <% tabs.with_panel(id: "#{size}-tab2") do %>
16
+ <div class="p-3 text-sm text-grayscale-600">Tab Two content</div>
17
+ <% end %>
18
+ <% tabs.with_panel(id: "#{size}-tab3") do %>
19
+ <div class="p-3 text-sm text-grayscale-600">Tab Three content</div>
20
+ <% end %>
21
+ <% end %>
22
+ </div>
23
+ <% end %>
24
+ </div>
@@ -0,0 +1,24 @@
1
+ <div class="p-4 space-y-8">
2
+ <h3 class="text-lg font-semibold mb-4">All Color Variants (Underline Style)</h3>
3
+
4
+ <% BetterUi::ApplicationComponent::VARIANTS.keys.each do |variant| %>
5
+ <div class="mb-6">
6
+ <p class="text-sm font-medium text-grayscale-500 mb-2 capitalize"><%= variant %></p>
7
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :underline, variant: variant) do |tabs| %>
8
+ <% tabs.with_tab(id: "#{variant}-tab1", label: "Tab One", active: true) %>
9
+ <% tabs.with_tab(id: "#{variant}-tab2", label: "Tab Two") %>
10
+ <% tabs.with_tab(id: "#{variant}-tab3", label: "Tab Three") %>
11
+
12
+ <% tabs.with_panel(id: "#{variant}-tab1", active: true) do %>
13
+ <div class="p-3 text-sm text-grayscale-600">Content for <%= variant %> variant, Tab One</div>
14
+ <% end %>
15
+ <% tabs.with_panel(id: "#{variant}-tab2") do %>
16
+ <div class="p-3 text-sm text-grayscale-600">Content for <%= variant %> variant, Tab Two</div>
17
+ <% end %>
18
+ <% tabs.with_panel(id: "#{variant}-tab3") do %>
19
+ <div class="p-3 text-sm text-grayscale-600">Content for <%= variant %> variant, Tab Three</div>
20
+ <% end %>
21
+ <% end %>
22
+ </div>
23
+ <% end %>
24
+ </div>
@@ -0,0 +1,30 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Bordered Style</h3>
3
+
4
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :bordered) do |tabs| %>
5
+ <% tabs.with_tab(id: "details", label: "Details", active: true) %>
6
+ <% tabs.with_tab(id: "reviews", label: "Reviews") %>
7
+ <% tabs.with_tab(id: "shipping", label: "Shipping") %>
8
+
9
+ <% tabs.with_panel(id: "details", active: true) do %>
10
+ <div class="p-4 border border-t-0 border-grayscale-200 rounded-b-lg">
11
+ <h4 class="font-medium mb-2">Product Details</h4>
12
+ <p class="text-grayscale-600">High-quality product with premium materials and craftsmanship.</p>
13
+ </div>
14
+ <% end %>
15
+
16
+ <% tabs.with_panel(id: "reviews") do %>
17
+ <div class="p-4 border border-t-0 border-grayscale-200 rounded-b-lg">
18
+ <h4 class="font-medium mb-2">Customer Reviews</h4>
19
+ <p class="text-grayscale-600">4.8 out of 5 stars (128 reviews)</p>
20
+ </div>
21
+ <% end %>
22
+
23
+ <% tabs.with_panel(id: "shipping") do %>
24
+ <div class="p-4 border border-t-0 border-grayscale-200 rounded-b-lg">
25
+ <h4 class="font-medium mb-2">Shipping Information</h4>
26
+ <p class="text-grayscale-600">Free shipping on orders over $50. Delivery in 3-5 business days.</p>
27
+ </div>
28
+ <% end %>
29
+ <% end %>
30
+ </div>
@@ -0,0 +1,30 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Underline Style (Default)</h3>
3
+
4
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :underline) do |tabs| %>
5
+ <% tabs.with_tab(id: "profile", label: "Profile", active: true) %>
6
+ <% tabs.with_tab(id: "account", label: "Account") %>
7
+ <% tabs.with_tab(id: "notifications", label: "Notifications") %>
8
+
9
+ <% tabs.with_panel(id: "profile", active: true) do %>
10
+ <div class="p-4">
11
+ <h4 class="font-medium mb-2">Profile Settings</h4>
12
+ <p class="text-grayscale-600">Manage your profile information and preferences.</p>
13
+ </div>
14
+ <% end %>
15
+
16
+ <% tabs.with_panel(id: "account") do %>
17
+ <div class="p-4">
18
+ <h4 class="font-medium mb-2">Account Settings</h4>
19
+ <p class="text-grayscale-600">Update your account details and security settings.</p>
20
+ </div>
21
+ <% end %>
22
+
23
+ <% tabs.with_panel(id: "notifications") do %>
24
+ <div class="p-4">
25
+ <h4 class="font-medium mb-2">Notification Preferences</h4>
26
+ <p class="text-grayscale-600">Choose how you want to receive notifications.</p>
27
+ </div>
28
+ <% end %>
29
+ <% end %>
30
+ </div>
@@ -0,0 +1,65 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Tabs with Disabled State</h3>
3
+
4
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :underline) do |tabs| %>
5
+ <% tabs.with_tab(id: "active", label: "Active Tab", active: true) %>
6
+ <% tabs.with_tab(id: "enabled", label: "Enabled Tab") %>
7
+ <% tabs.with_tab(id: "disabled", label: "Disabled Tab", disabled: true) %>
8
+ <% tabs.with_tab(id: "another", label: "Another Tab") %>
9
+
10
+ <% tabs.with_panel(id: "active", active: true) do %>
11
+ <div class="p-4">
12
+ <h4 class="font-medium mb-2">Active Tab Content</h4>
13
+ <p class="text-grayscale-600">This is the currently active tab.</p>
14
+ </div>
15
+ <% end %>
16
+
17
+ <% tabs.with_panel(id: "enabled") do %>
18
+ <div class="p-4">
19
+ <h4 class="font-medium mb-2">Enabled Tab Content</h4>
20
+ <p class="text-grayscale-600">This tab can be selected.</p>
21
+ </div>
22
+ <% end %>
23
+
24
+ <% tabs.with_panel(id: "disabled") do %>
25
+ <div class="p-4">
26
+ <h4 class="font-medium mb-2">Disabled Tab Content</h4>
27
+ <p class="text-grayscale-600">This content cannot be accessed because the tab is disabled.</p>
28
+ </div>
29
+ <% end %>
30
+
31
+ <% tabs.with_panel(id: "another") do %>
32
+ <div class="p-4">
33
+ <h4 class="font-medium mb-2">Another Tab Content</h4>
34
+ <p class="text-grayscale-600">This is another selectable tab.</p>
35
+ </div>
36
+ <% end %>
37
+ <% end %>
38
+
39
+ <div class="mt-8">
40
+ <h4 class="text-md font-semibold mb-4">Pills Style with Disabled</h4>
41
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :pills, variant: :success) do |tabs| %>
42
+ <% tabs.with_tab(id: "pills-active", label: "Active", active: true) %>
43
+ <% tabs.with_tab(id: "pills-disabled", label: "Coming Soon", disabled: true) %>
44
+ <% tabs.with_tab(id: "pills-enabled", label: "Enabled") %>
45
+
46
+ <% tabs.with_panel(id: "pills-active", active: true) do %>
47
+ <div class="p-4">
48
+ <p class="text-grayscale-600">The "Coming Soon" tab is disabled.</p>
49
+ </div>
50
+ <% end %>
51
+
52
+ <% tabs.with_panel(id: "pills-disabled") do %>
53
+ <div class="p-4">
54
+ <p class="text-grayscale-600">Disabled content.</p>
55
+ </div>
56
+ <% end %>
57
+
58
+ <% tabs.with_panel(id: "pills-enabled") do %>
59
+ <div class="p-4">
60
+ <p class="text-grayscale-600">Enabled tab content.</p>
61
+ </div>
62
+ <% end %>
63
+ <% end %>
64
+ </div>
65
+ </div>
@@ -0,0 +1,34 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Pills Style</h3>
3
+
4
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :pills) do |tabs| %>
5
+ <% tabs.with_tab(id: "all", label: "All", active: true) %>
6
+ <% tabs.with_tab(id: "active", label: "Active") %>
7
+ <% tabs.with_tab(id: "draft", label: "Draft") %>
8
+ <% tabs.with_tab(id: "archived", label: "Archived") %>
9
+
10
+ <% tabs.with_panel(id: "all", active: true) do %>
11
+ <div class="p-4">
12
+ <p class="text-grayscale-600">Showing all items (15 total)</p>
13
+ </div>
14
+ <% end %>
15
+
16
+ <% tabs.with_panel(id: "active") do %>
17
+ <div class="p-4">
18
+ <p class="text-grayscale-600">Showing active items (8 total)</p>
19
+ </div>
20
+ <% end %>
21
+
22
+ <% tabs.with_panel(id: "draft") do %>
23
+ <div class="p-4">
24
+ <p class="text-grayscale-600">Showing draft items (4 total)</p>
25
+ </div>
26
+ <% end %>
27
+
28
+ <% tabs.with_panel(id: "archived") do %>
29
+ <div class="p-4">
30
+ <p class="text-grayscale-600">Showing archived items (3 total)</p>
31
+ </div>
32
+ <% end %>
33
+ <% end %>
34
+ </div>
@@ -0,0 +1,40 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Turbo Mode Example</h3>
3
+
4
+ <div class="mb-4 p-4 bg-info-50 border border-info-200 rounded-lg">
5
+ <p class="text-sm text-info-800">
6
+ <strong>Note:</strong> Turbo mode tabs use anchor tags that navigate via Turbo Frames.
7
+ This example shows the HTML structure. In a real application, clicking tabs would
8
+ load content from the server into the turbo-frame.
9
+ </p>
10
+ </div>
11
+
12
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :turbo, frame_id: "tab-content", style: :underline) do |tabs| %>
13
+ <% tabs.with_tab(id: "dashboard", label: "Dashboard", href: "#dashboard", active: true) %>
14
+ <% tabs.with_tab(id: "users", label: "Users", href: "#users") %>
15
+ <% tabs.with_tab(id: "settings", label: "Settings", href: "#settings") %>
16
+ <% end %>
17
+
18
+ <turbo-frame id="tab-content" class="block p-4 border border-grayscale-200 rounded-b-lg mt-0">
19
+ <div class="text-grayscale-600">
20
+ <p>This is a <code class="bg-grayscale-100 px-1 rounded">turbo-frame</code> element.</p>
21
+ <p class="mt-2">In Turbo mode, clicking a tab navigates to the href and the response is rendered inside this frame.</p>
22
+ </div>
23
+ </turbo-frame>
24
+
25
+ <div class="mt-8">
26
+ <h4 class="text-md font-semibold mb-4">Pills Style Turbo Mode</h4>
27
+
28
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :turbo, frame_id: "pills-content", style: :pills, variant: :accent) do |tabs| %>
29
+ <% tabs.with_tab(id: "overview", label: "Overview", href: "#overview", active: true) %>
30
+ <% tabs.with_tab(id: "analytics", label: "Analytics", href: "#analytics") %>
31
+ <% tabs.with_tab(id: "reports", label: "Reports", href: "#reports") %>
32
+ <% end %>
33
+
34
+ <turbo-frame id="pills-content" class="block p-4 mt-4">
35
+ <div class="text-grayscale-600">
36
+ <p>Content loaded via Turbo Frame.</p>
37
+ </div>
38
+ </turbo-frame>
39
+ </div>
40
+ </div>
@@ -0,0 +1,38 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Vertical Tabs (Left Position)</h3>
3
+
4
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :underline, position: :left) do |tabs| %>
5
+ <% tabs.with_tab(id: "general", label: "General", active: true) %>
6
+ <% tabs.with_tab(id: "security", label: "Security") %>
7
+ <% tabs.with_tab(id: "billing", label: "Billing") %>
8
+ <% tabs.with_tab(id: "team", label: "Team") %>
9
+
10
+ <% tabs.with_panel(id: "general", active: true) do %>
11
+ <div class="p-4">
12
+ <h4 class="font-medium mb-2">General Settings</h4>
13
+ <p class="text-grayscale-600">Configure your general application settings and preferences.</p>
14
+ </div>
15
+ <% end %>
16
+
17
+ <% tabs.with_panel(id: "security") do %>
18
+ <div class="p-4">
19
+ <h4 class="font-medium mb-2">Security Settings</h4>
20
+ <p class="text-grayscale-600">Manage your security preferences and two-factor authentication.</p>
21
+ </div>
22
+ <% end %>
23
+
24
+ <% tabs.with_panel(id: "billing") do %>
25
+ <div class="p-4">
26
+ <h4 class="font-medium mb-2">Billing Information</h4>
27
+ <p class="text-grayscale-600">View and update your billing details and payment methods.</p>
28
+ </div>
29
+ <% end %>
30
+
31
+ <% tabs.with_panel(id: "team") do %>
32
+ <div class="p-4">
33
+ <h4 class="font-medium mb-2">Team Management</h4>
34
+ <p class="text-grayscale-600">Invite team members and manage their permissions.</p>
35
+ </div>
36
+ <% end %>
37
+ <% end %>
38
+ </div>
@@ -0,0 +1,30 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Vertical Tabs (Right Position)</h3>
3
+
4
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :pills, position: :right, variant: :accent) do |tabs| %>
5
+ <% tabs.with_tab(id: "overview", label: "Overview", active: true) %>
6
+ <% tabs.with_tab(id: "analytics", label: "Analytics") %>
7
+ <% tabs.with_tab(id: "reports", label: "Reports") %>
8
+
9
+ <% tabs.with_panel(id: "overview", active: true) do %>
10
+ <div class="p-4">
11
+ <h4 class="font-medium mb-2">Dashboard Overview</h4>
12
+ <p class="text-grayscale-600">View your dashboard metrics and key performance indicators.</p>
13
+ </div>
14
+ <% end %>
15
+
16
+ <% tabs.with_panel(id: "analytics") do %>
17
+ <div class="p-4">
18
+ <h4 class="font-medium mb-2">Analytics Dashboard</h4>
19
+ <p class="text-grayscale-600">Dive deep into your analytics data and trends.</p>
20
+ </div>
21
+ <% end %>
22
+
23
+ <% tabs.with_panel(id: "reports") do %>
24
+ <div class="p-4">
25
+ <h4 class="font-medium mb-2">Reports</h4>
26
+ <p class="text-grayscale-600">Generate and download custom reports.</p>
27
+ </div>
28
+ <% end %>
29
+ <% end %>
30
+ </div>
@@ -0,0 +1,71 @@
1
+ <div class="p-4">
2
+ <h3 class="text-lg font-semibold mb-4">Tabs with Icons and Badges</h3>
3
+
4
+ <%= render BetterUi::Tabs::ContainerComponent.new(mode: :js, style: :underline) do |tabs| %>
5
+ <% tabs.with_tab(id: "inbox", label: "Inbox", active: true) do |tab| %>
6
+ <% tab.with_icon do %>
7
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
8
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
9
+ </svg>
10
+ <% end %>
11
+ <% tab.with_badge do %>
12
+ <span class="inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium bg-primary-100 text-primary-800 rounded-full">12</span>
13
+ <% end %>
14
+ <% end %>
15
+
16
+ <% tabs.with_tab(id: "sent", label: "Sent") do |tab| %>
17
+ <% tab.with_icon do %>
18
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
19
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path>
20
+ </svg>
21
+ <% end %>
22
+ <% end %>
23
+
24
+ <% tabs.with_tab(id: "drafts", label: "Drafts") do |tab| %>
25
+ <% tab.with_icon do %>
26
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
27
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
28
+ </svg>
29
+ <% end %>
30
+ <% tab.with_badge do %>
31
+ <span class="inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium bg-warning-100 text-warning-800 rounded-full">3</span>
32
+ <% end %>
33
+ <% end %>
34
+
35
+ <% tabs.with_tab(id: "trash", label: "Trash") do |tab| %>
36
+ <% tab.with_icon do %>
37
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
38
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
39
+ </svg>
40
+ <% end %>
41
+ <% end %>
42
+
43
+ <% tabs.with_panel(id: "inbox", active: true) do %>
44
+ <div class="p-4">
45
+ <h4 class="font-medium mb-2">Inbox</h4>
46
+ <p class="text-grayscale-600">You have 12 unread messages.</p>
47
+ </div>
48
+ <% end %>
49
+
50
+ <% tabs.with_panel(id: "sent") do %>
51
+ <div class="p-4">
52
+ <h4 class="font-medium mb-2">Sent Messages</h4>
53
+ <p class="text-grayscale-600">View your sent messages.</p>
54
+ </div>
55
+ <% end %>
56
+
57
+ <% tabs.with_panel(id: "drafts") do %>
58
+ <div class="p-4">
59
+ <h4 class="font-medium mb-2">Drafts</h4>
60
+ <p class="text-grayscale-600">You have 3 draft messages.</p>
61
+ </div>
62
+ <% end %>
63
+
64
+ <% tabs.with_panel(id: "trash") do %>
65
+ <div class="p-4">
66
+ <h4 class="font-medium mb-2">Trash</h4>
67
+ <p class="text-grayscale-600">Deleted messages appear here.</p>
68
+ </div>
69
+ <% end %>
70
+ <% end %>
71
+ </div>
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BetterUi
4
+ module Tabs
5
+ # @label Tabs Container
6
+ class ContainerComponentPreview < ViewComponent::Preview
7
+ # @label Default (Underline)
8
+ # @display max_height 400px
9
+ def default
10
+ render_with_template
11
+ end
12
+
13
+ # @label Pills Style
14
+ # @display max_height 400px
15
+ def pills_style
16
+ render_with_template
17
+ end
18
+
19
+ # @label Bordered Style
20
+ # @display max_height 400px
21
+ def bordered_style
22
+ render_with_template
23
+ end
24
+
25
+ # @label All Variants (Underline)
26
+ # @display max_height 600px
27
+ def all_variants
28
+ render_with_template
29
+ end
30
+
31
+ # @label All Sizes
32
+ # @display max_height 800px
33
+ def all_sizes
34
+ render_with_template
35
+ end
36
+
37
+ # @label Alignments
38
+ # @display max_height 600px
39
+ def alignments
40
+ render_with_template
41
+ end
42
+
43
+ # @label Vertical Tabs (Left)
44
+ # @display max_height 400px
45
+ def vertical_left
46
+ render_with_template
47
+ end
48
+
49
+ # @label Vertical Tabs (Right)
50
+ # @display max_height 400px
51
+ def vertical_right
52
+ render_with_template
53
+ end
54
+
55
+ # @label With Icons and Badges
56
+ # @display max_height 400px
57
+ def with_icons_and_badges
58
+ render_with_template
59
+ end
60
+
61
+ # @label Disabled Tab
62
+ # @display max_height 400px
63
+ def disabled_tab
64
+ render_with_template
65
+ end
66
+
67
+ # @label Turbo Mode Example
68
+ # @display max_height 400px
69
+ def turbo_mode
70
+ render_with_template
71
+ end
72
+
73
+ # @label Playground
74
+ # @display max_height 500px
75
+ # @param mode select { choices: [js, turbo] }
76
+ # @param style select { choices: [underline, pills, bordered] }
77
+ # @param variant select { choices: [primary, secondary, accent, success, danger, warning, info, light, dark] }
78
+ # @param size select { choices: [xs, sm, md, lg, xl] }
79
+ # @param alignment select { choices: [start, center, end, stretch] }
80
+ # @param position select { choices: [top, bottom, left, right] }
81
+ def playground(
82
+ mode: :js,
83
+ style: :underline,
84
+ variant: :primary,
85
+ size: :md,
86
+ alignment: :start,
87
+ position: :top
88
+ )
89
+ render BetterUi::Tabs::ContainerComponent.new(
90
+ mode: mode.to_sym,
91
+ style: style.to_sym,
92
+ variant: variant.to_sym,
93
+ size: size.to_sym,
94
+ alignment: alignment.to_sym,
95
+ position: position.to_sym
96
+ ) do |tabs|
97
+ tabs.with_tab(id: "overview", label: "Overview", active: true)
98
+ tabs.with_tab(id: "features", label: "Features")
99
+ tabs.with_tab(id: "pricing", label: "Pricing")
100
+
101
+ tabs.with_panel(id: "overview", active: true) do
102
+ "<div class='p-4'>
103
+ <h3 class='text-lg font-semibold mb-2'>Overview</h3>
104
+ <p class='text-grayscale-600'>This is the overview panel content. Customize the tabs using the controls above.</p>
105
+ </div>".html_safe
106
+ end
107
+
108
+ tabs.with_panel(id: "features") do
109
+ "<div class='p-4'>
110
+ <h3 class='text-lg font-semibold mb-2'>Features</h3>
111
+ <ul class='list-disc list-inside text-grayscale-600'>
112
+ <li>Multiple styles: underline, pills, bordered</li>
113
+ <li>9 color variants</li>
114
+ <li>5 size options</li>
115
+ <li>Vertical and horizontal layouts</li>
116
+ </ul>
117
+ </div>".html_safe
118
+ end
119
+
120
+ tabs.with_panel(id: "pricing") do
121
+ "<div class='p-4'>
122
+ <h3 class='text-lg font-semibold mb-2'>Pricing</h3>
123
+ <p class='text-grayscale-600'>Contact us for pricing information.</p>
124
+ </div>".html_safe
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,14 @@
1
+ <div class="p-8 space-y-8">
2
+ <% [:xs, :sm, :md, :lg].each do |size| %>
3
+ <div>
4
+ <h3 class="text-lg font-semibold mb-4 capitalize">Size: <%= size %></h3>
5
+ <div class="flex flex-wrap gap-3">
6
+ <% [:solid, :outline, :soft].each do |style| %>
7
+ <%= render BetterUi::TagComponent.new(style: style, size: size) do %>
8
+ <%= style.to_s.capitalize %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+ <% end %>
14
+ </div>
@@ -0,0 +1,14 @@
1
+ <div class="p-8 space-y-8">
2
+ <% [:solid, :outline, :soft].each do |style| %>
3
+ <div>
4
+ <h3 class="text-lg font-semibold mb-4 capitalize"><%= style %> Tags</h3>
5
+ <div class="flex flex-wrap gap-3">
6
+ <% BetterUi::ApplicationComponent::VARIANTS.keys.each do |variant| %>
7
+ <%= render BetterUi::TagComponent.new(variant: variant, style: style) do %>
8
+ <%= variant.to_s.capitalize %>
9
+ <% end %>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+ <% end %>
14
+ </div>