sdr_view_components 0.1.14 → 0.2.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 (174) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +55 -38
  3. data/app/assets/sdr_view_components.css +110 -0
  4. data/app/components/sdr_view_components/elements/heading_component.rb +3 -1
  5. data/app/components/sdr_view_components/elements/icon_button_component.rb +10 -0
  6. data/app/components/sdr_view_components/elements/spinner_component.html.erb +2 -2
  7. data/app/components/sdr_view_components/elements/spinner_component.rb +5 -4
  8. data/app/components/sdr_view_components/elements/tabs/pane_component.html.erb +3 -0
  9. data/app/components/sdr_view_components/elements/tabs/pane_component.rb +27 -0
  10. data/app/components/sdr_view_components/elements/tabs/tab_component.html.erb +3 -0
  11. data/app/components/sdr_view_components/elements/tabs/tab_component.rb +42 -0
  12. data/app/components/sdr_view_components/elements/tabs/tab_list_component.html.erb +9 -0
  13. data/app/components/sdr_view_components/elements/tabs/tab_list_component.rb +33 -0
  14. data/app/components/sdr_view_components/elements/toast_component.rb +1 -1
  15. data/app/components/sdr_view_components/tables/base_table_component.html.erb +32 -0
  16. data/app/components/sdr_view_components/tables/base_table_component.rb +69 -0
  17. data/app/components/sdr_view_components/tables/cell_component.html.erb +3 -0
  18. data/app/components/sdr_view_components/tables/cell_component.rb +21 -0
  19. data/app/components/sdr_view_components/tables/header_component.html.erb +4 -0
  20. data/app/components/sdr_view_components/tables/header_component.rb +22 -0
  21. data/app/components/sdr_view_components/tables/list_cell_component.html.erb +5 -0
  22. data/app/components/sdr_view_components/tables/list_cell_component.rb +22 -0
  23. data/app/components/sdr_view_components/tables/raw_table_component.rb +10 -0
  24. data/app/components/sdr_view_components/tables/row_component.html.erb +24 -0
  25. data/app/components/sdr_view_components/tables/row_component.rb +32 -0
  26. data/app/components/sdr_view_components/tables/table_component.rb +10 -0
  27. data/app/views/layouts/lookbook.html.erb +46 -0
  28. data/lib/sdr_view_components/configuration.rb +22 -0
  29. data/lib/sdr_view_components/engine.rb +17 -7
  30. data/lib/sdr_view_components/error.rb +7 -0
  31. data/lib/sdr_view_components/version.rb +1 -1
  32. data/lib/sdr_view_components.rb +2 -0
  33. data/spec/components/previews/sdr_view_components/elements/alert_component_preview.rb +71 -0
  34. data/spec/components/previews/sdr_view_components/elements/banner_component_preview.rb +58 -0
  35. data/spec/components/previews/sdr_view_components/elements/breadcrumb_nav_component_preview.rb +52 -0
  36. data/spec/components/previews/sdr_view_components/elements/button_component_preview.rb +71 -0
  37. data/spec/components/previews/sdr_view_components/elements/button_form_component_preview.rb +97 -0
  38. data/spec/components/previews/sdr_view_components/elements/button_link_component_preview.rb +81 -0
  39. data/spec/components/previews/sdr_view_components/elements/card_component_preview.rb +41 -0
  40. data/spec/components/previews/sdr_view_components/elements/heading_component_preview.rb +51 -0
  41. data/spec/components/previews/sdr_view_components/elements/horizontal_rule_component_preview/default.html.erb +5 -0
  42. data/spec/components/previews/sdr_view_components/elements/horizontal_rule_component_preview.rb +9 -0
  43. data/spec/components/previews/sdr_view_components/elements/icon_button_component_preview.rb +17 -0
  44. data/spec/components/previews/sdr_view_components/elements/icon_button_link_component_preview.rb +15 -0
  45. data/spec/components/previews/sdr_view_components/elements/modal_component_preview/default.html.erb +9 -0
  46. data/spec/components/previews/sdr_view_components/elements/modal_component_preview/with_header_and_footer.html.erb +19 -0
  47. data/spec/components/previews/sdr_view_components/elements/modal_component_preview/without_size.html.erb +9 -0
  48. data/spec/components/previews/sdr_view_components/elements/modal_component_preview.rb +15 -0
  49. data/spec/components/previews/sdr_view_components/elements/progress_bar_component_preview.rb +97 -0
  50. data/spec/components/previews/sdr_view_components/elements/spinner_component_preview.rb +83 -0
  51. data/spec/components/previews/sdr_view_components/elements/tabs/tab_list_component_preview/default_variant.html.erb +12 -0
  52. data/spec/components/previews/sdr_view_components/elements/tabs/tab_list_component_preview/underline_variant.html.erb +12 -0
  53. data/spec/components/previews/sdr_view_components/elements/tabs/tab_list_component_preview/with_header.html.erb +16 -0
  54. data/spec/components/previews/sdr_view_components/elements/tabs/tab_list_component_preview.rb +16 -0
  55. data/spec/components/previews/sdr_view_components/elements/toast_component_preview.rb +29 -0
  56. data/spec/components/previews/sdr_view_components/elements/tooltip_component_preview/default.html.erb +13 -0
  57. data/spec/components/previews/sdr_view_components/elements/tooltip_component_preview.rb +9 -0
  58. data/spec/components/previews/sdr_view_components/forms/basic/basic_checkbox_component_preview/checked.html.erb +7 -0
  59. data/spec/components/previews/sdr_view_components/forms/basic/basic_checkbox_component_preview/default.html.erb +6 -0
  60. data/spec/components/previews/sdr_view_components/forms/basic/basic_checkbox_component_preview/disabled.html.erb +7 -0
  61. data/spec/components/previews/sdr_view_components/forms/basic/basic_checkbox_component_preview.rb +17 -0
  62. data/spec/components/previews/sdr_view_components/forms/basic/basic_file_component_preview/default.html.erb +6 -0
  63. data/spec/components/previews/sdr_view_components/forms/basic/basic_file_component_preview/with_accept.html.erb +7 -0
  64. data/spec/components/previews/sdr_view_components/forms/basic/basic_file_component_preview/with_multiple.html.erb +7 -0
  65. data/spec/components/previews/sdr_view_components/forms/basic/basic_file_component_preview/with_required.html.erb +7 -0
  66. data/spec/components/previews/sdr_view_components/forms/basic/basic_file_component_preview.rb +25 -0
  67. data/spec/components/previews/sdr_view_components/forms/basic/basic_radio_button_component_preview/checked.html.erb +8 -0
  68. data/spec/components/previews/sdr_view_components/forms/basic/basic_radio_button_component_preview/default.html.erb +7 -0
  69. data/spec/components/previews/sdr_view_components/forms/basic/basic_radio_button_component_preview/disabled.html.erb +8 -0
  70. data/spec/components/previews/sdr_view_components/forms/basic/basic_radio_button_component_preview.rb +17 -0
  71. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_area_component_preview/default.html.erb +6 -0
  72. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_area_component_preview/with_placeholder.html.erb +7 -0
  73. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_area_component_preview/with_required.html.erb +7 -0
  74. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_area_component_preview/with_rows.html.erb +7 -0
  75. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_area_component_preview.rb +19 -0
  76. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_field_component_preview/default.html.erb +6 -0
  77. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_field_component_preview/disabled.html.erb +8 -0
  78. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_field_component_preview/required.html.erb +7 -0
  79. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_field_component_preview/with_placeholder.html.erb +7 -0
  80. data/spec/components/previews/sdr_view_components/forms/basic/basic_text_field_component_preview.rb +19 -0
  81. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview/checked.html.erb +9 -0
  82. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview/default.html.erb +8 -0
  83. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview/disabled.html.erb +9 -0
  84. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview/with_additional_container_content.html.erb +12 -0
  85. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview/with_help_text.html.erb +10 -0
  86. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview/with_label.html.erb +9 -0
  87. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview/with_validation_error.html.erb +9 -0
  88. data/spec/components/previews/sdr_view_components/forms/checkbox_component_preview.rb +33 -0
  89. data/spec/components/previews/sdr_view_components/forms/file_component_preview/default.html.erb +8 -0
  90. data/spec/components/previews/sdr_view_components/forms/file_component_preview/with_additional_container_content.html.erb +14 -0
  91. data/spec/components/previews/sdr_view_components/forms/file_component_preview/with_help_text.html.erb +9 -0
  92. data/spec/components/previews/sdr_view_components/forms/file_component_preview/with_help_text_below.html.erb +10 -0
  93. data/spec/components/previews/sdr_view_components/forms/file_component_preview/with_label.html.erb +9 -0
  94. data/spec/components/previews/sdr_view_components/forms/file_component_preview/with_multiple.html.erb +9 -0
  95. data/spec/components/previews/sdr_view_components/forms/file_component_preview/with_validation_error.html.erb +9 -0
  96. data/spec/components/previews/sdr_view_components/forms/file_component_preview.rb +32 -0
  97. data/spec/components/previews/sdr_view_components/forms/help_text_component_preview/with_block_content.html.erb +3 -0
  98. data/spec/components/previews/sdr_view_components/forms/help_text_component_preview/with_text.html.erb +4 -0
  99. data/spec/components/previews/sdr_view_components/forms/help_text_component_preview.rb +13 -0
  100. data/spec/components/previews/sdr_view_components/forms/label_component_preview/default.html.erb +7 -0
  101. data/spec/components/previews/sdr_view_components/forms/label_component_preview/hidden_label.html.erb +8 -0
  102. data/spec/components/previews/sdr_view_components/forms/label_component_preview/with_caption.html.erb +8 -0
  103. data/spec/components/previews/sdr_view_components/forms/label_component_preview/with_tooltip.html.erb +17 -0
  104. data/spec/components/previews/sdr_view_components/forms/label_component_preview.rb +17 -0
  105. data/spec/components/previews/sdr_view_components/forms/radio_button_component_preview/default.html.erb +9 -0
  106. data/spec/components/previews/sdr_view_components/forms/radio_button_component_preview/with_additional_container_content.html.erb +14 -0
  107. data/spec/components/previews/sdr_view_components/forms/radio_button_component_preview/with_help_text.html.erb +10 -0
  108. data/spec/components/previews/sdr_view_components/forms/radio_button_component_preview/with_help_text_below.html.erb +11 -0
  109. data/spec/components/previews/sdr_view_components/forms/radio_button_component_preview/with_label.html.erb +10 -0
  110. data/spec/components/previews/sdr_view_components/forms/radio_button_component_preview/with_validation_error.html.erb +11 -0
  111. data/spec/components/previews/sdr_view_components/forms/radio_button_component_preview.rb +30 -0
  112. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/danger.html.erb +6 -0
  113. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/default.html.erb +5 -0
  114. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/info.html.erb +6 -0
  115. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/primary.html.erb +6 -0
  116. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/secondary.html.erb +6 -0
  117. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/success.html.erb +6 -0
  118. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/warning.html.erb +6 -0
  119. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/with_block_content_and_value.html.erb +7 -0
  120. data/spec/components/previews/sdr_view_components/forms/submit_component_preview/with_form_id.html.erb +8 -0
  121. data/spec/components/previews/sdr_view_components/forms/submit_component_preview.rb +29 -0
  122. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview/default.html.erb +8 -0
  123. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview/with_additional_container_content.html.erb +12 -0
  124. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview/with_help_text.html.erb +9 -0
  125. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview/with_help_text_below.html.erb +10 -0
  126. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview/with_hidden_label.html.erb +9 -0
  127. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview/with_mark_required.html.erb +9 -0
  128. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview/with_validation_error.html.erb +9 -0
  129. data/spec/components/previews/sdr_view_components/forms/text_area_component_preview.rb +32 -0
  130. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/default.html.erb +8 -0
  131. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/disabled.html.erb +9 -0
  132. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/label_hidden.html.erb +9 -0
  133. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/marked_required.html.erb +9 -0
  134. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/required.html.erb +9 -0
  135. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/with_additional_container_content.html.erb +12 -0
  136. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/with_help_text.html.erb +9 -0
  137. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/with_help_text_below.html.erb +10 -0
  138. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/with_placeholder.html.erb +9 -0
  139. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview/with_validation_error.html.erb +9 -0
  140. data/spec/components/previews/sdr_view_components/forms/text_field_component_preview.rb +40 -0
  141. data/spec/components/previews/sdr_view_components/forms/toggle_component_preview/default.html.erb +11 -0
  142. data/spec/components/previews/sdr_view_components/forms/toggle_component_preview/with_validation_error.html.erb +12 -0
  143. data/spec/components/previews/sdr_view_components/forms/toggle_component_preview.rb +20 -0
  144. data/spec/components/previews/sdr_view_components/structure/footer_component_preview.rb +11 -0
  145. data/spec/components/previews/sdr_view_components/structure/header_component_preview/dark_variant.html.erb +15 -0
  146. data/spec/components/previews/sdr_view_components/structure/header_component_preview/dark_variant_with_background_color.html.erb +15 -0
  147. data/spec/components/previews/sdr_view_components/structure/header_component_preview/light_variant.html.erb +15 -0
  148. data/spec/components/previews/sdr_view_components/structure/header_component_preview/no_rosette.html.erb +15 -0
  149. data/spec/components/previews/sdr_view_components/structure/header_component_preview/white_variant.html.erb +15 -0
  150. data/spec/components/previews/sdr_view_components/structure/header_component_preview.rb +16 -0
  151. data/spec/components/previews/sdr_view_components/tables/cell_component_preview/default.html.erb +9 -0
  152. data/spec/components/previews/sdr_view_components/tables/cell_component_preview/with_colspan.html.erb +17 -0
  153. data/spec/components/previews/sdr_view_components/tables/cell_component_preview.rb +11 -0
  154. data/spec/components/previews/sdr_view_components/tables/header_component_preview/default.html.erb +7 -0
  155. data/spec/components/previews/sdr_view_components/tables/header_component_preview/with_tooltip.html.erb +19 -0
  156. data/spec/components/previews/sdr_view_components/tables/header_component_preview.rb +11 -0
  157. data/spec/components/previews/sdr_view_components/tables/list_cell_component_preview/with_item_values.html.erb +7 -0
  158. data/spec/components/previews/sdr_view_components/tables/list_cell_component_preview/with_items.html.erb +11 -0
  159. data/spec/components/previews/sdr_view_components/tables/list_cell_component_preview.rb +27 -0
  160. data/spec/components/previews/sdr_view_components/tables/raw_table_component_preview/default.html.erb +26 -0
  161. data/spec/components/previews/sdr_view_components/tables/raw_table_component_preview.rb +9 -0
  162. data/spec/components/previews/sdr_view_components/tables/row_component_preview/label_only.html.erb +5 -0
  163. data/spec/components/previews/sdr_view_components/tables/row_component_preview/with_cells.html.erb +13 -0
  164. data/spec/components/previews/sdr_view_components/tables/row_component_preview/with_first_value_and_values.html.erb +8 -0
  165. data/spec/components/previews/sdr_view_components/tables/row_component_preview/with_label_content.html.erb +11 -0
  166. data/spec/components/previews/sdr_view_components/tables/row_component_preview/with_tooltip.html.erb +18 -0
  167. data/spec/components/previews/sdr_view_components/tables/row_component_preview/with_value.html.erb +8 -0
  168. data/spec/components/previews/sdr_view_components/tables/row_component_preview/with_values.html.erb +8 -0
  169. data/spec/components/previews/sdr_view_components/tables/row_component_preview.rb +21 -0
  170. data/spec/components/previews/sdr_view_components/tables/table_component_preview.rb +81 -0
  171. metadata +163 -6
  172. data/app/assets/stylesheets/styles.scss +0 -118
  173. data/app/components/component_support/file_hierarchy.rb +0 -22
  174. data/app/components/sdr_view_components/forms/button_component.rb +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e89b11e845efdc4fa1bea907cac71a0e4165853da5233d4007e15c829709a3e
4
- data.tar.gz: 486b3bf6dbf1b657cd76d93327892feec81600502c1f75e3aa9578d108478660
3
+ metadata.gz: b973a9d37ca8cbaf8923757222f1e73ae754a72ca99731008c68d22c7be41f28
4
+ data.tar.gz: 6014055eb861360362ee8527f5f7d2afba60665428720df0e095982af8aa9c46
5
5
  SHA512:
6
- metadata.gz: 9723c013dfb1a1ba6d6cc4af4c1170aec972539dbff1e6ae78065006b32233c812a66cb1b3b04b8d7a0909acd886783dc1f33d92af62ea3c290760e08be15f96
7
- data.tar.gz: 4130c0034e46554ccc3e1e5fff29869a0aca37c7c718e75067fc5d1ab0763cb96ed1dd8a7cf96fd756f2641ca6e4857bdf2ff96d10093a91fbdfef0a91b614db
6
+ metadata.gz: ec8945789ecbc351308b32e6f7df8600e8b43d9bfe92ef9bd4013279b69a20a0eeebf5f4ea6cf6fb36946690a5564020e57e268826a145c1a0911d9cd1aad796
7
+ data.tar.gz: d5fe578fc6d4c376408b315536cf97d538dd19c466785e73472266d402663d95150f2ae5e7fe9095989e1c39bac616c88582067282863d893a3eebbfa35e2c1a
data/README.md CHANGED
@@ -4,8 +4,7 @@
4
4
 
5
5
  # SdrViewComponents
6
6
 
7
- A rails gem to provide reusable view components used throughout the SDR applications and implement
8
- component library assets.
7
+ A rails gem to provide reusable view components used throughout the SDR applications and implement component library assets.
9
8
 
10
9
  # Installation
11
10
 
@@ -21,48 +20,13 @@ This set of components relies on the component library stylesheets, add:
21
20
 
22
21
  ```
23
22
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/sul-dlss/component-library@v2025-09-11/styles/sul.css">
23
+ <%= stylesheet_link_tag "sdr_view_components", "data-turbo-track": "reload" %>
24
24
  ```
25
25
 
26
26
  with the most recent date tagged release to your `application.html.erb` layout file.
27
27
 
28
28
  ## Usage
29
29
 
30
- ### Add the SUL Header to your application
31
-
32
- Supported header variations are `:dark`, `:light`, and `:white` (default is `:light`)
33
-
34
- ```
35
- <%= render SdrViewComponents::Structure::HeaderComponent.new(title: 'Test Header', subtitle: 'Test Subtitle', variant: :dark) do |header| %>
36
- <% header.with_primary_navigation_link do %>
37
- <%= render SdrViewComponents::Elements::Navigation::NavItemComponent.new(text: 'Home', path: '#') %>
38
- <% end %>
39
- <% header.with_primary_navigation_link do %>
40
- <%= render SdrViewComponents::Elements::Navigation::DropdownMenuComponent.new(text: 'Logged in: amcollie-preview-dropdown') do |dropdown| %>
41
- <% dropdown.with_item do %>
42
- <%= link_to 'Logout', '/Shibboleth.sso/Logout', class: 'dropdown-item' %>
43
- <% end %>
44
- <% end %>
45
- <%# ... all primary nav links %>
46
- <% end %>
47
- <% header.with_secondary_navigation_link do %>
48
- <%= render SdrViewComponents::Elements::Navigation::NavItemComponent.new(text: 'Option', path: '/item1') %>
49
- <%# ... all secondary nav links>
50
- <% end %>
51
- <% end %>
52
- ```
53
-
54
- The `:dark` variation supports providing an rgb value via the `background_color` param in order to override the default dark background, for example:
55
-
56
- ```
57
- <%= render SdrViewComponents::Structure::HeaderComponent.new(title: 'Test Header', subtitle: 'Test Subtitle', variant: :dark, rgb_color_str: '1, 104, 149') do |header| %>
58
-
59
- ...
60
-
61
- <% end %>
62
- ```
63
-
64
- By default, the SUL Rosette is included in the header, this can be disabled by setting `rosette: false` in the parameter list when instantiating the header.
65
-
66
30
  ### Form components
67
31
 
68
32
  SdrViewComponents provides a wrapper for several [ActionView::Helper::Tags](https://api.rubyonrails.org/v8.1.1/classes/ActionView/Helpers/Tags.html).
@@ -113,3 +77,56 @@ At a minimum, each of these components must be provided wih the `form:` and `fie
113
77
  ```
114
78
  <% render SdrViewComponent::....>
115
79
  ```
80
+
81
+ ## Component library version
82
+ The [component-library](https://github.com/sul-dlss/component-library/) version is set in `lib/sdr_view_components/configuration.rb`.
83
+
84
+ ```
85
+ def initialize
86
+ # Default URL for the component library assets
87
+ @component_library_url = 'https://cdn.jsdelivr.net/gh/sul-dlss/component-library@v2026-01-27'
88
+ end
89
+ ```
90
+
91
+ ## Lookbook
92
+
93
+ [Lookbook](https://lookbook.build/) provides a component browser for the components.
94
+
95
+ ### Creating previews
96
+ For a component to appear in Lookbook, it must have a preview. See `spec/components/previews/sdr_view_components`
97
+
98
+ Previews can easily be created with the `viewComponentPreview` prompt. For example: `/viewComponentPreview SpinnerComponent`.
99
+
100
+ ### Running locally
101
+
102
+ `bin/rails s`
103
+
104
+ Lookbook will then be available at: http://localhost:3000/lookbook
105
+
106
+ ### Adding to another app
107
+
108
+ When performing development in an app that is using SdrViewComponents, it may be helpful to be running Lookbook in that app (instead of having to run a separate local instance of it).
109
+
110
+ To run Lookbook in that app:
111
+ 1. Add Lookbook to `Gemfile.rb`:
112
+ ```
113
+ group :development do
114
+ gem 'lookbook'
115
+ end
116
+ ```
117
+ 2. Add routes to `routes.rb`:
118
+ ```
119
+ if Rails.env.development?
120
+ mount SdrViewComponents::Engine => '/sdr_view_components'
121
+ mount Lookbook::Engine, at: '/lookbook'
122
+ end
123
+ ```
124
+ 3. Add `config/initializers/sdr_view_components.rb`:
125
+ ```
126
+ SdrViewComponents.configure do |config|
127
+ config.component_library_url = Settings.component_library.url
128
+ end
129
+ ```
130
+ It is recommended to change the component library URL to a configuration in the app instead of hardcoding in layouts.
131
+
132
+ When your app is running locally, Lookbook will be available at: http://localhost:3000/lookbook
@@ -0,0 +1,110 @@
1
+ /* Header */
2
+ .masthead {
3
+ color: white;
4
+ }
5
+
6
+ .masthead h1,
7
+ .masthead .h1 {
8
+ font-size: 2.25rem;
9
+ }
10
+
11
+ /* Toggle */
12
+ .btn-group-toggle label.btn {
13
+ --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgb(var(--bs-btn-focus-shadow-rgb), .5);
14
+ }
15
+
16
+ .btn-group-toggle input:checked + label {
17
+ background-color: var(--bs-primary);
18
+ border-color: var(--bs-primary);
19
+ color: #fff;
20
+ }
21
+
22
+ .btn-group-toggle input:not(:checked) + label {
23
+ background-color: transparent;
24
+ border-color: var(--bs-primary);
25
+ color: var(--bs-primary);
26
+ }
27
+
28
+ .btn-group-toggle .btn-check:checked + .btn {
29
+ background-color: var(--stanford-digital-blue);
30
+ border-color: var(--stanford-digital-blue);
31
+ color: #fff;
32
+ }
33
+
34
+ .btn-group-toggle :not(.btn-check:checked) + .btn {
35
+ color: var(--stanford-digital-blue);
36
+ border-color: var(--stanford-digital-blue);
37
+ }
38
+
39
+ .btn-group-toggle input:checked + label::before {
40
+ display: inline-block;
41
+ margin-right: 3px;
42
+ font-family: bootstrap-icons;
43
+ vertical-align: -15%;
44
+ content: "\F633";
45
+ }
46
+
47
+ /* Banner */
48
+ .banner.alert a.btn-primary {
49
+ color: white;
50
+ }
51
+
52
+ /* Forms */
53
+ .form-control,
54
+ .form-select,
55
+ .form-check-input {
56
+ border-color: var(--stanford-60-black);
57
+ }
58
+
59
+ /* Tabs */
60
+ .nav-underline {
61
+ border-bottom: 1px solid black;
62
+ margin-bottom: 10px;
63
+ }
64
+
65
+ .nav-underline .nav-link {
66
+ width: 10.5rem;
67
+ }
68
+
69
+ .nav-underline .nav-link:not(.active) {
70
+ color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
71
+ }
72
+
73
+ .nav-underline .nav-link.active {
74
+ border-bottom: 3px solid #B1040E;
75
+ color: #B1040E;
76
+ font-weight: bold;
77
+ }
78
+
79
+ /* Tables */
80
+ table.table-h3 caption {
81
+ padding: .25rem;
82
+ font-size: 1.5rem;
83
+ font-weight: 600;
84
+ line-height: 1.5;
85
+ color: var(--stanford-black);
86
+ caption-side: top;
87
+ border-bottom: 1px solid var(--stanford-black);
88
+ }
89
+
90
+ table.table-h3 th {
91
+ font-size: 1.0rem;
92
+ font-weight: 600;
93
+ color: var(--stanford-black);
94
+ }
95
+
96
+ table.table-h3 tr {
97
+ border-color: var(--stanford-30-black);
98
+ }
99
+
100
+ /* Item lists */
101
+ table.table-h3 .list-unstyled {
102
+ list-style: none;
103
+ margin-left: 0;
104
+ padding-left: 0;
105
+ }
106
+
107
+ table.table-data th {
108
+ width: fit-content;
109
+ white-space: nowrap;
110
+ }
@@ -20,7 +20,9 @@ module SdrViewComponents
20
20
 
21
21
  # Renders the component without the need for a .erb partial.
22
22
  def call
23
- content_tag(@level, class: classes) do
23
+ return unless tag.respond_to?(@level)
24
+
25
+ tag.public_send(@level, class: classes) do
24
26
  @text || content
25
27
  end
26
28
  end
@@ -12,6 +12,10 @@ module SdrViewComponents
12
12
  super()
13
13
  end
14
14
 
15
+ def before_render
16
+ raise SdrViewComponents::Error::UnknownComponentIcon, "Unknown icon type: #{@icon}" unless button_icon?
17
+ end
18
+
15
19
  attr_reader :label, :options
16
20
 
17
21
  def classes
@@ -21,6 +25,12 @@ module SdrViewComponents
21
25
  def button_icon
22
26
  helpers.public_send(:"#{@icon}_icon")
23
27
  end
28
+
29
+ private
30
+
31
+ def button_icon?
32
+ helpers.respond_to?(:"#{@icon}_icon")
33
+ end
24
34
  end
25
35
  end
26
36
  end
@@ -1,8 +1,8 @@
1
1
  <%= tag.div class: classes do %>
2
2
  <% if image_path %>
3
- <%= tag.img src: image_path, alt: 'Spinner', class: spinner_classes, role: 'status', style: spinner_style, **options %>
3
+ <%= tag.img src: image_path, alt: 'Spinner', class: spinner_classes, role: 'status', style: spinner_style, **spinner_options %>
4
4
  <% else %>
5
- <%= tag.div class: spinner_classes, role: 'status', style: spinner_style, **options %>
5
+ <%= tag.div class: spinner_classes, role: 'status', style: spinner_style, **spinner_options %>
6
6
  <% end %>
7
7
  <%= tag.div class: message_classes do %><%= message %><% end %>
8
8
  <% end %>
@@ -6,7 +6,7 @@ module SdrViewComponents
6
6
  class SpinnerComponent < BaseComponent
7
7
  def initialize(message: 'Loading...', message_classes: [], message_position: :right, hide_message: false, # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
8
8
  image_path: nil, variant: nil, classes: [],
9
- height: nil, width: nil, speed: 0.75, **options)
9
+ height: nil, width: nil, speed: 0.75, spinner_classes: ['mx-2'], **spinner_options)
10
10
  @message = message
11
11
  @variant = variant
12
12
  @hide_message = hide_message
@@ -16,15 +16,16 @@ module SdrViewComponents
16
16
  @width = width
17
17
  @message_classes = message_classes
18
18
  @speed = speed # In seconds, so a larger number is slower. The default (0.75) is the same as Bootstrap's default.
19
- @options = options
19
+ @spinner_classes = spinner_classes
20
+ @spinner_options = spinner_options
20
21
  @message_position = message_position # :bottom or :right
21
22
  super()
22
23
  end
23
24
 
24
- attr_reader :message, :image_path, :options
25
+ attr_reader :message, :image_path, :spinner_options
25
26
 
26
27
  def spinner_classes
27
- merge_classes('spinner-border', variant_class, border_class, 'mx-2')
28
+ merge_classes('spinner-border', variant_class, border_class, @spinner_classes)
28
29
  end
29
30
 
30
31
  def message_classes
@@ -0,0 +1,3 @@
1
+ <%= tag.div class: classes, id:, role: 'tabpanel', 'aria-labelledby': tab_id, tabindex: '0' do %>
2
+ <%= content %>
3
+ <% end %>
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Elements
5
+ module Tabs
6
+ # Component for rendering a tab pane in a tabbed interface.
7
+ class PaneComponent < BaseComponent
8
+ def initialize(id:, tab_id:, active: false)
9
+ @id = id
10
+ @tab_id = tab_id
11
+ @active = active
12
+ super()
13
+ end
14
+
15
+ attr_reader :id, :tab_id
16
+
17
+ def active?
18
+ @active
19
+ end
20
+
21
+ def classes
22
+ merge_classes(%w[tab-pane fade], active? ? %w[show active] : nil)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ <li class="nav-item" role="presentation">
2
+ <%= tag.button class: button_classes, id:, data: { bs_toggle: 'tab', bs_target: "##{pane_id}" }, type: 'button', role: 'tab', 'aria-controls': 'details-pane', 'aria-selected': active? do %><%= label %><% end %>
3
+ </li>
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Elements
5
+ module Tabs
6
+ # Component for rendering a tab in a tabbed interface.
7
+ class TabComponent < BaseComponent
8
+ def initialize(label:, id:, pane_id:, active: false, variant: :underline)
9
+ @label = label
10
+ @id = id
11
+ @pane_id = pane_id
12
+ @active = active
13
+ @variant = variant
14
+
15
+ raise ArgumentError, "Invalid variant: #{variant}" unless %i[underline default].include?(variant)
16
+
17
+ super()
18
+ end
19
+
20
+ attr_reader :label, :id, :pane_id, :variant
21
+
22
+ def active?
23
+ @active
24
+ end
25
+
26
+ def classes
27
+ merge_classes('nav', variant_classes)
28
+ end
29
+
30
+ def button_classes
31
+ merge_classes('nav-link', active? ? 'active' : nil)
32
+ end
33
+
34
+ private
35
+
36
+ def variant_classes
37
+ 'nav-underline' if variant == :underline
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ <%= tag.ul class: classes, role: 'tablist' do %>
2
+ <% tabs.each do |tab| %><%= tab %><% end %>
3
+ <% end %>
4
+
5
+ <%= header %>
6
+
7
+ <div class="tab-content">
8
+ <% panes.each do |pane| %><%= pane %><% end %>
9
+ </div>
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Elements
5
+ module Tabs
6
+ # Component for rendering a list of tabs in a tabbed interface.
7
+ class TabListComponent < BaseComponent
8
+ renders_one :header # optional
9
+ renders_many :tabs, Elements::Tabs::TabComponent
10
+ renders_many :panes, Elements::Tabs::PaneComponent
11
+
12
+ def initialize(classes: [], variant: :default)
13
+ @classes = classes
14
+ @variant = variant
15
+
16
+ raise ArgumentError, "Invalid variant: #{variant}" unless %i[underline default].include?(variant)
17
+
18
+ super()
19
+ end
20
+
21
+ def classes
22
+ merge_classes('nav', @classes, variant_classes)
23
+ end
24
+
25
+ private
26
+
27
+ def variant_classes
28
+ 'nav-underline' if @variant == :underline
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -21,7 +21,7 @@ module SdrViewComponents
21
21
  def background_color
22
22
  case variant
23
23
  when :red
24
- 'bg-stanford-cardinal'
24
+ 'bg-stanford-digital-red'
25
25
  when :green
26
26
  'bg-stanford-digital-green'
27
27
  when :poppy
@@ -0,0 +1,32 @@
1
+ <% @table_content = capture do %>
2
+ <%= tag.table class: classes, 'aria-label': label, **@table_options do %>
3
+ <% if show_label? %>
4
+ <caption><%= label || caption %></caption>
5
+ <% end %>
6
+ <% if headers? %>
7
+ <%= tag.thead class: head_classes do %>
8
+ <tr>
9
+ <% headers.each do |header| %>
10
+ <%= header %>
11
+ <% end %>
12
+ </tr>
13
+ <% end %>
14
+ <% end %>
15
+ <%= tag.tbody class: body_classes do %>
16
+ <% rows.each do |row| %>
17
+ <%= row %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
21
+ <% if empty_message && !rows? %>
22
+ <p class="fst-italic"><%= empty_message %></p>
23
+ <% end %>
24
+ <% end %>
25
+
26
+ <% if responsive? %>
27
+ <%= tag.div class: 'table-responsive' do %>
28
+ <%= @table_content %>
29
+ <% end %>
30
+ <% else %>
31
+ <%= @table_content %>
32
+ <% end %>
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Tables
5
+ # Base component for rendering a table.
6
+ class BaseTableComponent < BaseComponent
7
+ renders_many :headers, SdrViewComponents::Tables::HeaderComponent
8
+ renders_one :caption
9
+ # Subclasses should provide rows, e.g., renders_many :rows
10
+
11
+ def initialize(label: nil, classes: [], head_classes: [], body_classes: [], show_label: true, # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
12
+ empty_message: nil, responsive: false, variant: :h3, **table_options)
13
+ @classes = classes
14
+ @body_classes = body_classes
15
+ @label = label
16
+ @show_label = show_label
17
+ @empty_message = empty_message
18
+ @head_classes = head_classes
19
+ @responsive = responsive
20
+ @table_options = table_options
21
+ @variant = variant
22
+ raise ArgumentError, 'Unknown variant' unless %i[h3 data].include?(@variant)
23
+
24
+ raise ArgumentError, 'Subclasses must provide rows' unless respond_to?(:rows)
25
+
26
+ super()
27
+ end
28
+
29
+ attr_reader :label, :empty_message, :table_options, :variant
30
+
31
+ def before_render
32
+ raise ArgumentError, 'Must provide label or caption' unless label.present? || caption?
33
+ end
34
+
35
+ def classes
36
+ merge_classes(%w[table caption-top], variant_classes, @classes)
37
+ end
38
+
39
+ def head_classes
40
+ merge_classes(@head_classes)
41
+ end
42
+
43
+ def body_classes
44
+ merge_classes(@body_classes)
45
+ end
46
+
47
+ def show_label?
48
+ @show_label
49
+ end
50
+
51
+ def render?
52
+ rows? || empty_message.present?
53
+ end
54
+
55
+ def responsive?
56
+ @responsive
57
+ end
58
+
59
+ def variant_classes
60
+ case variant
61
+ when :h3
62
+ 'table-h3'
63
+ when :data
64
+ 'table-data table-striped table-hover table-bordered'
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ <%= tag.td(colspan:, class: classes, **cell_options) do %>
2
+ <%= content %>
3
+ <% end %>
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Tables
5
+ # Component for rendering a table cell.
6
+ class CellComponent < BaseComponent
7
+ def initialize(colspan: nil, classes: [], **cell_options)
8
+ @colspan = colspan
9
+ @classes = classes
10
+ @cell_options = cell_options
11
+ super()
12
+ end
13
+
14
+ attr_reader :colspan, :cell_options
15
+
16
+ def classes
17
+ merge_classes(@classes)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ <%= tag.th scope: 'col', class: classes, **header_options do %>
2
+ <%= label %>
3
+ <%= render SdrViewComponents::Elements::TooltipComponent.new(target_label: label, tooltip:) %>
4
+ <% end %>
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Tables
5
+ # Component for rendering a table header.
6
+ class HeaderComponent < BaseComponent
7
+ def initialize(label:, classes: [], tooltip: nil, **header_options)
8
+ @label = label
9
+ @classes = classes
10
+ @tooltip = tooltip
11
+ @header_options = header_options
12
+ super()
13
+ end
14
+
15
+ attr_reader :label, :tooltip, :header_options
16
+
17
+ def classes
18
+ merge_classes(@classes)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ <ul class="list-unstyled mb-0">
2
+ <% list_items.each do |item| %>
3
+ <li><%= item %></li>
4
+ <% end %>
5
+ </ul>
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Tables
5
+ # Component for rendering a list in a table cell.
6
+ class ListCellComponent < BaseComponent
7
+ renders_many :items
8
+
9
+ def initialize(item_values: [])
10
+ # Provide items or item_values
11
+ @item_values = item_values
12
+ super()
13
+ end
14
+
15
+ attr_reader :item_values
16
+
17
+ def list_items
18
+ items? ? items : item_values
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrViewComponents
4
+ module Tables
5
+ # Component for rendering a table in which rows must be provided.
6
+ class RawTableComponent < BaseTableComponent
7
+ renders_many :rows
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ <%= tag.tr **row_options do %>
2
+ <% if label.present? || label_content.present? %>
3
+ <th class="col-3" scope="row">
4
+ <%= label || label_content %>
5
+ <%= render SdrViewComponents::Elements::TooltipComponent.new(target_label: label, tooltip:) %>
6
+ </th>
7
+ <% end %>
8
+
9
+ <% if first_value.present? %>
10
+ <td class="col-3" scope="row"><%= first_value %></td>
11
+ <% end %>
12
+
13
+ <% values.each do |value| %>
14
+ <td><%= value %></td>
15
+ <% end %>
16
+
17
+ <% cells.each do |cell| %>
18
+ <%= cell %>
19
+ <% end %>
20
+
21
+ <% if empty_cell? %>
22
+ <td></td>
23
+ <% end %>
24
+ <% end %>