plutonium 0.10.3 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -2
  3. data/app/assets/application.js.bk +31419 -0
  4. data/app/assets/plutonium-logo-original.png +0 -0
  5. data/app/assets/plutonium-logo-white.png +0 -0
  6. data/app/assets/plutonium-logo.png +0 -0
  7. data/app/assets/plutonium.css +1 -0
  8. data/app/assets/plutonium.ico +0 -0
  9. data/app/assets/plutonium.js +12416 -0
  10. data/app/assets/plutonium.js.map +7 -0
  11. data/app/assets/plutonium.min.js +39 -0
  12. data/app/assets/plutonium.min.js.map +7 -0
  13. data/app/views/application/_flash_alerts.html.erb +2 -2
  14. data/app/views/application/_resource_header.html.erb +263 -697
  15. data/app/views/application/_resource_sidebar.html.erb +14 -12
  16. data/app/views/components/action_button/action_button_component.rb +3 -3
  17. data/app/views/components/attributes.rb +184 -0
  18. data/app/views/components/base.rb +19 -40
  19. data/app/views/components/block/block_component.html.erb +1 -1
  20. data/app/views/components/block/block_component.rb +11 -7
  21. data/app/views/components/breadcrumbs/breadcrumbs_component.rb +3 -3
  22. data/app/views/components/button/button_component.html.erb +2 -2
  23. data/app/views/components/button/button_component.rb +10 -5
  24. data/app/views/components/dyna_frame_content/dyna_frame_content_component.html.erb +1 -0
  25. data/app/views/components/dyna_frame_content/dyna_frame_content_component.rb +3 -3
  26. data/app/views/components/dyna_frame_host/dyna_frame_host_component.html.erb +1 -2
  27. data/app/views/components/dyna_frame_host/dyna_frame_host_component.rb +12 -5
  28. data/app/views/components/empty_card/empty_card_component.rb +3 -3
  29. data/app/views/components/form/form_builder.rb +1 -1
  30. data/app/views/components/form/form_component.rb +3 -3
  31. data/app/views/components/has_many_panel/has_many_panel_component.html.erb +25 -0
  32. data/app/views/components/has_many_panel/has_many_panel_component.rb +16 -0
  33. data/app/views/components/header/header_component.rb +3 -3
  34. data/app/views/components/interactive_action_form/interactive_action_form_component.rb +3 -3
  35. data/app/views/components/nav_grid_menu/nav_grid_menu_component.html.erb +24 -0
  36. data/app/views/components/nav_grid_menu/nav_grid_menu_component.rb +23 -0
  37. data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.html.erb +4 -0
  38. data/app/views/components/nav_grid_menu_item/nav_grid_menu_item_component.rb +20 -0
  39. data/app/views/components/nav_user/nav_user_component.html.erb +50 -0
  40. data/app/views/components/nav_user/nav_user_component.rb +32 -0
  41. data/app/views/components/nav_user_link/nav_user_link_component.html.erb +7 -0
  42. data/app/views/components/nav_user_link/nav_user_link_component.rb +23 -0
  43. data/app/views/components/nav_user_section/nav_user_section_component.html.erb +7 -0
  44. data/app/views/components/nav_user_section/nav_user_section_component.rb +18 -0
  45. data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.html.erb +1 -3
  46. data/app/views/components/nested_resource_form_fields/nested_resource_form_fields_component.rb +11 -5
  47. data/app/views/components/pagination/pagination_component.html.erb +1 -1
  48. data/app/views/components/pagination/pagination_component.rb +10 -7
  49. data/app/views/components/panel/panel_component.html.erb +13 -6
  50. data/app/views/components/panel/panel_component.rb +11 -5
  51. data/app/views/components/resource_header/resource_header_component.html.erb +81 -0
  52. data/app/views/components/resource_header/resource_header_component.rb +20 -0
  53. data/app/views/components/resource_layout/resource_layout_component.html.erb +32 -0
  54. data/app/views/components/resource_layout/resource_layout_component.rb +39 -0
  55. data/app/views/components/sidebar/sidebar_component.html.erb +3 -33
  56. data/app/views/components/sidebar/sidebar_component.rb +3 -3
  57. data/app/views/components/sidebar_menu/sidebar_menu_component.html.erb +4 -2
  58. data/app/views/components/sidebar_menu/sidebar_menu_component.rb +10 -6
  59. data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.html.erb +63 -71
  60. data/app/views/components/sidebar_menu_item/sidebar_menu_item_component.rb +27 -8
  61. data/app/views/components/skeleton/table/table_component.html.erb +1 -1
  62. data/app/views/components/skeleton/table/table_component.rb +3 -3
  63. data/app/views/components/table/table_component.html.erb +40 -89
  64. data/app/views/components/table/table_component.rb +124 -28
  65. data/app/views/components/table_search_input/table_search_input_component.html.erb +1 -1
  66. data/app/views/components/table_search_input/table_search_input_component.rb +11 -6
  67. data/app/views/components/table_toolbar/table_toolbar_component.html.erb +1 -1
  68. data/app/views/components/table_toolbar/table_toolbar_component.rb +11 -3
  69. data/app/views/components/toolbar/toolbar_component.html.erb +2 -2
  70. data/app/views/components/toolbar/toolbar_component.rb +16 -8
  71. data/app/views/layouts/resource.html.erb +21 -37
  72. data/app/views/layouts/rodauth.html.erb +32 -30
  73. data/app/views/resource/_interactive_resource_action_form.html.erb +1 -1
  74. data/app/views/resource/_resource_details.html.erb +8 -5
  75. data/app/views/resource/_resource_table.html.erb +70 -1
  76. data/app/views/resource/interactive_resource_collection_action.html.erb +1 -0
  77. data/app/views/resource/interactive_resource_record_action.html.erb +1 -0
  78. data/app/views/resource/interactive_resource_recordless_action.html.erb +1 -0
  79. data/app/views/resource/new.html.erb +1 -0
  80. data/config/initializers/simple_form.rb +22 -2
  81. data/esbuild.config.js +35 -31
  82. data/lib/generators/pu/core/assets/assets_generator.rb +41 -0
  83. data/lib/generators/pu/core/assets/templates/tailwind.config.js +18 -0
  84. data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +3 -0
  85. data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +6 -0
  86. data/lib/generators/pu/gen/component/component_generator.rb +13 -10
  87. data/lib/generators/pu/gen/component/templates/component.html.erb.tt +1 -1
  88. data/lib/generators/pu/gen/component/templates/component.rb.tt +10 -4
  89. data/lib/generators/pu/pkg/app/app_generator.rb +4 -4
  90. data/lib/generators/pu/pkg/app/templates/app/controllers/concerns/controller.rb.tt +28 -0
  91. data/lib/generators/pu/pkg/app/templates/app/controllers/controller.rb.tt +5 -0
  92. data/lib/generators/pu/pkg/app/templates/app/controllers/dashboard_controller.rb.tt +1 -1
  93. data/lib/generators/pu/res/conn/conn_generator.rb +4 -4
  94. data/lib/generators/pu/res/conn/templates/app/controllers/resource_controller.rb.tt +1 -1
  95. data/lib/generators/pu/res/model/model_generator.rb +3 -3
  96. data/lib/generators/pu/res/scaffold/templates/policy.rb.tt +6 -0
  97. data/lib/generators/pu/service/sidekiq/sidekiq_generator.rb +0 -5
  98. data/lib/generators/pu/service/sidekiq/templates/app/sidekiq/sidekiq_job.rb +0 -2
  99. data/lib/plutonium/config.rb +2 -14
  100. data/lib/plutonium/core/associations/renderers/basic_renderer.rb +28 -0
  101. data/lib/plutonium/core/associations/renderers/factory.rb +36 -0
  102. data/lib/plutonium/core/associations/renderers/has_many_renderer.rb +16 -0
  103. data/lib/plutonium/core/autodiscovery/association_renderer_discoverer.rb +31 -0
  104. data/lib/plutonium/core/controllers/authorizable.rb +13 -17
  105. data/lib/plutonium/core/controllers/base.rb +3 -7
  106. data/lib/plutonium/core/controllers/presentable.rb +6 -1
  107. data/lib/plutonium/core/definers/association_renderer_definer.rb +33 -0
  108. data/lib/plutonium/core/fields/inputs/checkbox_input.rb +13 -0
  109. data/lib/plutonium/core/fields/inputs/factory.rb +1 -0
  110. data/lib/plutonium/core/fields/inputs/polymorphic_belongs_to_association_input.rb +1 -1
  111. data/lib/plutonium/core/ui/detail.rb +1 -0
  112. data/lib/plutonium/helpers/application_helper.rb +8 -9
  113. data/lib/plutonium/helpers/assets_helper.rb +33 -0
  114. data/lib/plutonium/helpers/display_helper.rb +13 -0
  115. data/lib/plutonium/helpers/form_helper.rb +1 -1
  116. data/lib/plutonium/helpers.rb +1 -0
  117. data/lib/plutonium/icons.rb +12 -5
  118. data/lib/plutonium/pkg/app.rb +10 -0
  119. data/lib/plutonium/pundit/context.rb +18 -0
  120. data/lib/plutonium/pundit/policy_finder.rb +25 -0
  121. data/lib/plutonium/railtie.rb +20 -8
  122. data/lib/plutonium/reloader.rb +18 -7
  123. data/lib/plutonium/resource/controller.rb +4 -0
  124. data/lib/plutonium/resource/policy.rb +69 -47
  125. data/lib/plutonium/resource/presenter.rb +1 -0
  126. data/lib/plutonium/resource/query_object.rb +139 -130
  127. data/lib/plutonium/rodauth/controller_methods.rb +7 -3
  128. data/lib/plutonium/version.rb +1 -1
  129. data/lib/plutonium.rb +9 -57
  130. data/package-lock.json +782 -17
  131. data/package.json +31 -8
  132. data/postcss.config.js +17 -7
  133. data/src/.npmignore +2 -0
  134. data/src/js/controllers/color_mode_controller.js +41 -0
  135. data/src/js/controllers/frame_navigator_controller.js +99 -0
  136. data/src/js/controllers/has_many_panel_controller.js +8 -0
  137. data/src/js/controllers/nav_grid_menu_controller.js +8 -0
  138. data/src/js/controllers/nav_grid_menu_item_controller.js +8 -0
  139. data/{app/views/components/tab_bar/tab_bar_controller.js → src/js/controllers/nav_user_controller.js} +2 -2
  140. data/src/js/controllers/nav_user_link_controller.js +8 -0
  141. data/src/js/controllers/nav_user_section_controller.js +8 -0
  142. data/src/js/controllers/register_controllers.js +45 -0
  143. data/{app/assets/javascripts → src/js}/controllers/resource_dismiss_controller.js +2 -0
  144. data/{app/assets/javascripts → src/js}/controllers/resource_drop_down_controller.js +2 -0
  145. data/src/js/controllers/resource_header_controller.js +8 -0
  146. data/src/js/controllers/resource_layout_controller.js +8 -0
  147. data/src/js/controllers/sidebar_menu_controller.js +8 -0
  148. data/src/js/controllers/sidebar_menu_item_controller.js +8 -0
  149. data/src/js/core.js +4 -0
  150. data/{app/assets/javascripts/plutonium-app.js → src/js/plutonium.js} +1 -1
  151. data/{app/assets/javascripts → src/js}/turbo/turbo_debug.js +2 -4
  152. data/tailwind.config.js +85 -84
  153. metadata +73 -39
  154. data/app/assets/build/plutonium.js +0 -5122
  155. data/app/assets/javascripts/controllers/index.js +0 -34
  156. data/app/assets/javascripts/plutonium.js +0 -1
  157. data/app/views/application/_color_modes.html.erb +0 -57
  158. data/app/views/components/tab_bar/tab_bar_component.html.erb +0 -11
  159. data/app/views/components/tab_bar/tab_bar_component.rb +0 -9
  160. data/app/views/resource/_nav_user.html.erb +0 -4
  161. data/app/views/resource/_tab_menu.html.erb +0 -13
  162. data/css.manifest +0 -3
  163. data/js.manifest +0 -4
  164. data/lib/generators/pu/pkg/app/templates/app/controllers/app_controller.rb.tt +0 -5
  165. data/lib/generators/pu/pkg/app/templates/app/controllers/package_controller.rb.tt +0 -26
  166. data/public/plutonium-assets/application.css +0 -25086
  167. data/public/plutonium-assets/plutonium-app-36KN5FVJ.js +0 -6
  168. data/public/plutonium-assets/plutonium-app-36KN5FVJ.js.map +0 -7
  169. data/public/plutonium-assets/plutonium-app-6WILQCTT.js +0 -39
  170. data/public/plutonium-assets/plutonium-app-6WILQCTT.js.map +0 -7
  171. data/public/plutonium-assets/plutonium.2d4f0c333cd000051d3b.css +0 -3424
  172. data/public/plutonium-assets/plutonium.50232e35b5495f5ad90d.css +0 -3415
  173. data/public/plutonium-assets/plutonium.8bee7a8482988b0360e3.css +0 -3420
  174. /data/{app/assets/build → lib/generators/pu/core/assets/templates}/.keep +0 -0
  175. /data/{app/assets/stylesheets → src/css}/plutonium.css +0 -0
  176. /data/{app/views/components/form → src/js/controllers}/form_controller.js +0 -0
  177. /data/{app/views/components/interactive_action_form → src/js/controllers}/interactive_action_form_controller.js +0 -0
  178. /data/{app/views/components/nested_resource_form_fields → src/js/controllers}/nested_resource_form_fields_controller.js +0 -0
  179. /data/{app/views/components/table → src/js/controllers}/table_controller.js +0 -0
  180. /data/{app/views/components/table_search_input → src/js/controllers}/table_search_input_controller.js +0 -0
  181. /data/{app/views/components/table_toolbar → src/js/controllers}/table_toolbar_controller.js +0 -0
  182. /data/{app/views/components/toolbar → src/js/controllers}/toolbar_controller.js +0 -0
  183. /data/{app/assets/javascripts → src/js}/turbo/index.js +0 -0
  184. /data/{app/assets/javascripts → src/js}/turbo/turbo_actions.js +0 -0
  185. /data/{app/assets/javascripts → src/js}/turbo/turbo_frame_monkey_patch.js +0 -0
@@ -0,0 +1,50 @@
1
+ <div <%= attributes_html %>>
2
+ <% if avatar_url.present? %>
3
+ <button
4
+ type="button"
5
+ class="flex mx-3 text-sm bg-gray-800 rounded-full md:mr-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
6
+ aria-expanded="false"
7
+ id="user-nav-dropdown-toggle"
8
+ data-resource-drop-down-target="trigger">
9
+ <span class="sr-only">Open user menu</span>
10
+ <img
11
+ class="w-8 h-8 rounded-full"
12
+ src="<%= avatar_url %>"
13
+ alt="avatar" />
14
+ </button>
15
+ <% else %>
16
+ <button
17
+ type="button"
18
+ class="flex mx-3 text-sm border border-gray-600 text-gray-500 hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-white dark:hover:bg-gray-700 rounded-full md:mr-0 focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600"
19
+ aria-expanded="false"
20
+ id="user-nav-dropdown-toggle"
21
+ data-resource-drop-down-target="trigger">
22
+ <span class="sr-only">Open user menu</span>
23
+ <svg class="w-8 h-8" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
24
+ <path fill-rule="evenodd" d="M12 4a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm-2 9a4 4 0 0 0-4 4v1a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-1a4 4 0 0 0-4-4h-4Z" clip-rule="evenodd"/>
25
+ </svg>
26
+ </button>
27
+ <% end %>
28
+ <!-- Dropdown menu -->
29
+ <div
30
+ class="hidden z-50 my-4 w-56 text-base list-none bg-white divide-y divide-gray-100 shadow dark:bg-gray-700 dark:divide-gray-600 rounded-xl"
31
+ data-resource-drop-down-target="menu">
32
+ <div class="py-3 px-4">
33
+ <% if name.present? %>
34
+ <span
35
+ class="block text-sm font-semibold text-gray-900 dark:text-white">
36
+ <%= name %>
37
+ </span>
38
+ <% end %>
39
+ <span
40
+ class="block text-sm text-gray-900 truncate dark:text-white">
41
+ <%= email %>
42
+ </span>
43
+ </div>
44
+
45
+ <% sections.each do |section| %>
46
+ <%= section %>
47
+ <% end %>
48
+
49
+ </div>
50
+ </div>
@@ -0,0 +1,32 @@
1
+ module PlutoniumUi
2
+ class NavUserComponent < PlutoniumUi::Base
3
+ renders_many :sections, "PlutoniumUi::NavUserSectionComponent"
4
+
5
+ option :email
6
+ option :name, optional: true
7
+ option :avatar_url, optional: true
8
+ option :logout_url, optional: true
9
+
10
+ private
11
+
12
+ def base_attributes
13
+ # base attributes go here
14
+ {
15
+ classname: "nav-user",
16
+ controller: "nav-user resource-drop-down"
17
+ }
18
+ end
19
+
20
+ def before_render
21
+ return unless logout_url.present?
22
+
23
+ content # get block to execute so our link gets added at the very end
24
+
25
+ with_section do |section|
26
+ section.with_link url: logout_url, label: "Sign out", data: {turbo: false}, classname: "rounded-b-lg"
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ Plutonium::ComponentRegistry.register :nav_user, to: PlutoniumUi::NavUserComponent
@@ -0,0 +1,7 @@
1
+ <a <%= attributes_html %>>
2
+ <span class="flex items-center">
3
+ <%= leading if leading.present? %>
4
+ <%= label %>
5
+ </span>
6
+ <%= trailing if trailing.present? %>
7
+ </a>
@@ -0,0 +1,23 @@
1
+ module PlutoniumUi
2
+ class NavUserLinkComponent < PlutoniumUi::Base
3
+ renders_one :leading
4
+ renders_one :trailing
5
+
6
+ option :label
7
+ option :url, as: :href
8
+
9
+ private
10
+
11
+ def base_attributes
12
+ # base attributes go here
13
+ {
14
+ id: "nav-user-link-#{label.parameterize}",
15
+ classname: "nav-user-link flex justify-between items-center py-2 px-4 text-sm hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white",
16
+ controller: "nav-user-link",
17
+ href:
18
+ }
19
+ end
20
+ end
21
+ end
22
+
23
+ Plutonium::ComponentRegistry.register :nav_user_link, to: PlutoniumUi::NavUserLinkComponent
@@ -0,0 +1,7 @@
1
+ <ul <%= attributes_html %>>
2
+ <% links.each do |link| %>
3
+ <li>
4
+ <%= link %>
5
+ </li>
6
+ <% end %>
7
+ </ul>
@@ -0,0 +1,18 @@
1
+ module PlutoniumUi
2
+ class NavUserSectionComponent < PlutoniumUi::Base
3
+ renders_many :links, "PlutoniumUi::NavUserLinkComponent"
4
+
5
+ private
6
+
7
+ def base_attributes
8
+ # base attributes go here
9
+ {
10
+ classname: "nav-user-section text-gray-700 dark:text-gray-300",
11
+ controller: "nav-user-section",
12
+ aria: {labelledby: "user-nav-dropdown-toggle"}
13
+ }
14
+ end
15
+ end
16
+ end
17
+
18
+ Plutonium::ComponentRegistry.register :nav_user_section, to: PlutoniumUi::NavUserSectionComponent
@@ -1,6 +1,4 @@
1
- <div data-controller="nested-resource-form-fields"
2
- data-nested-resource-form-fields-limit-value="<%= limit %>"
3
- <%= render_component_attributes %>>
1
+ <div <%= attributes_html %>>
4
2
  <h2 class="text-lg font-bold dark:text-white ">
5
3
  <%= label %>
6
4
  </h2>
@@ -1,5 +1,5 @@
1
- module Plutonium::Ui
2
- class NestedResourceFormFieldsComponent < Plutonium::Ui::Base
1
+ module PlutoniumUi
2
+ class NestedResourceFormFieldsComponent < PlutoniumUi::Base
3
3
  option :name
4
4
  option :resource_class
5
5
  option :form
@@ -10,8 +10,14 @@ module Plutonium::Ui
10
10
  option :update_only, optional: true
11
11
  option :limit, optional: true
12
12
 
13
- def base_classname
14
- "mt-6 mb-4"
13
+ def base_attributes
14
+ {
15
+ classname: "mt-6 mb-4",
16
+ controller: "nested-resource-form-fields",
17
+ data: {
18
+ "nested-resource-form-fields-limit-value": limit
19
+ }
20
+ }
15
21
  end
16
22
 
17
23
  def label
@@ -20,4 +26,4 @@ module Plutonium::Ui
20
26
  end
21
27
  end
22
28
 
23
- Plutonium::ComponentRegistry.register :nested_resource_form_fields, to: Plutonium::Ui::NestedResourceFormFieldsComponent
29
+ Plutonium::ComponentRegistry.register :nested_resource_form_fields, to: PlutoniumUi::NestedResourceFormFieldsComponent
@@ -1,4 +1,4 @@
1
- <div data-controller="pagination" <%= render_component_attributes %>>
1
+ <div <%= attributes_html %>>
2
2
  <%== pagy_info(pager) %>
3
3
  <% if pager.pages > 1 %>
4
4
  <%== pagy_nav(pager) %>
@@ -1,7 +1,7 @@
1
1
  require "pagy"
2
2
 
3
- module Plutonium::Ui
4
- class PaginationComponent < Plutonium::Ui::Base
3
+ module PlutoniumUi
4
+ class PaginationComponent < PlutoniumUi::Base
5
5
  include Pagy::Frontend
6
6
 
7
7
  option :pager
@@ -9,10 +9,6 @@ module Plutonium::Ui
9
9
  option :nav_aria_label, optional: true
10
10
  option :nav_i18n_key, optional: true
11
11
 
12
- def classname
13
- "flex flex-col items-center space-y-2 p-6 #{super}"
14
- end
15
-
16
12
  def pagy_nav(pagy, **vars)
17
13
  p_id = %( id="#{pagy_id}") if pagy_id
18
14
  link = pagy_link_proc(pagy, link_extra: "class=\"#{default_link_classes} #{page_link_classes}\"")
@@ -52,6 +48,13 @@ module Plutonium::Ui
52
48
 
53
49
  private
54
50
 
51
+ def base_attributes
52
+ {
53
+ classname: "flex flex-col items-center space-y-2 p-6",
54
+ controller: "pagination"
55
+ }
56
+ end
57
+
55
58
  def prev_html(pagy, text: pagy_t("pagy.prev"))
56
59
  link = pagy_link_proc(pagy, link_extra: "class=\"#{default_link_classes} #{page_link_classes} rounded-s-lg\"")
57
60
 
@@ -88,4 +91,4 @@ module Plutonium::Ui
88
91
  end
89
92
  end
90
93
 
91
- Plutonium::ComponentRegistry.register :pagination, to: Plutonium::Ui::PaginationComponent
94
+ Plutonium::ComponentRegistry.register :pagination, to: PlutoniumUi::PaginationComponent
@@ -1,10 +1,17 @@
1
1
  <%= render_component :block, rounded: :all do %>
2
- <div <%= render_component_attributes %>>
3
- <% if title.present? %>
4
- <h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
5
- <%= title %>
6
- </h5>
7
- <% end %>
2
+ <div <%= attributes_html %>>
3
+ <div class="flex justify-between items-center mb-4">
4
+ <% if title.present? %>
5
+ <h5 class="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
6
+ <%= title %>
7
+ </h5>
8
+ <% end %>
9
+ <div class="flex">
10
+ <% actions.each do |action| %>
11
+ <%= action %>
12
+ <% end %>
13
+ </div>
14
+ </div>
8
15
  <%= content %>
9
16
  </div>
10
17
  <% end %>
@@ -1,11 +1,17 @@
1
- module Plutonium::Ui
2
- class PanelComponent < Plutonium::Ui::Base
1
+ module PlutoniumUi
2
+ class PanelComponent < PlutoniumUi::Base
3
+ renders_many :actions
4
+
3
5
  option :title, optional: true
4
6
 
5
- def classname
6
- "p-4 #{super}"
7
+ private
8
+
9
+ def base_attributes
10
+ {
11
+ classname: "p-4"
12
+ }
7
13
  end
8
14
  end
9
15
  end
10
16
 
11
- Plutonium::ComponentRegistry.register :panel, to: Plutonium::Ui::PanelComponent
17
+ Plutonium::ComponentRegistry.register :panel, to: PlutoniumUi::PanelComponent
@@ -0,0 +1,81 @@
1
+ <nav <%= attributes_html %>>
2
+ <div class="flex flex-wrap justify-between items-center">
3
+ <div class="flex justify-start items-center">
4
+ <button
5
+ data-drawer-target="drawer-navigation"
6
+ data-drawer-toggle="drawer-navigation"
7
+ aria-controls="drawer-navigation"
8
+ class="p-2 mr-2 text-gray-600 rounded-lg cursor-pointer lg:hidden hover:text-gray-900 hover:bg-gray-100 focus:bg-gray-100 dark:focus:bg-gray-700 focus:ring-2 focus:ring-gray-100 dark:focus:ring-gray-700 dark:text-gray-200 dark:hover:bg-gray-700 dark:hover:text-white">
9
+ <svg
10
+ aria-hidden="true"
11
+ class="w-6 h-6"
12
+ fill="currentColor"
13
+ viewBox="0 0 20 20"
14
+ xmlns="http://www.w3.org/2000/svg">
15
+ <path
16
+ fill-rule="evenodd"
17
+ d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h6a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
18
+ clip-rule="evenodd"
19
+ ></path>
20
+ </svg>
21
+ <svg
22
+ aria-hidden="true"
23
+ class="hidden w-6 h-6"
24
+ fill="currentColor"
25
+ viewBox="0 0 20 20"
26
+ xmlns="http://www.w3.org/2000/svg">
27
+ <path
28
+ fill-rule="evenodd"
29
+ d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
30
+ clip-rule="evenodd"></path>
31
+ </svg>
32
+ <span class="sr-only">Toggle sidebar</span>
33
+ </button>
34
+ <% if brand_name.present? || brand_logo.present? %>
35
+ <a href="<%= root_path %>" class="flex items-center justify-between md:min-w-60">
36
+ <%= brand_logo if brand_logo.present? %>
37
+ <% if brand_name.present? %>
38
+ <span class="self-center text-2xl font-semibold whitespace-nowrap dark:text-white hidden xs:block">
39
+ <%= brand_name %>
40
+ </span>
41
+ <% end %>
42
+ </a>
43
+ <% end %>
44
+
45
+ <%= content %>
46
+ <%#
47
+ <form action="#" method="GET" class="hidden md:block md:pl-2">
48
+ <label for="topbar-search" class="sr-only">Search</label>
49
+ <div class="relative md:w-64">
50
+ <div
51
+ class="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none">
52
+ <svg
53
+ class="w-5 h-5 text-gray-500 dark:text-gray-200"
54
+ fill="currentColor"
55
+ viewBox="0 0 20 20"
56
+ xmlns="http://www.w3.org/2000/svg">
57
+ <path
58
+ fill-rule="evenodd"
59
+ clip-rule="evenodd"
60
+ d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"></path>
61
+ </svg>
62
+ </div>
63
+ <input
64
+ type="text"
65
+ name="email"
66
+ id="topbar-search"
67
+ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full pl-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500"
68
+ placeholder="Search" />
69
+ </div>
70
+ </form>
71
+ %>
72
+ </div>
73
+ <% if actions.present? %>
74
+ <div class="flex items-center lg:order-2">
75
+ <% actions.each do |action| %>
76
+ <%= action %>
77
+ <% end %>
78
+ </div>
79
+ <% end %>
80
+ </div>
81
+ </nav>
@@ -0,0 +1,20 @@
1
+ module PlutoniumUi
2
+ class ResourceHeaderComponent < PlutoniumUi::Base
3
+ renders_one :brand_logo
4
+ renders_many :actions
5
+
6
+ option :brand_name
7
+
8
+ private
9
+
10
+ def base_attributes
11
+ # base attributes go here
12
+ {
13
+ classname: "resource-header bg-white border-b border-gray-200 px-4 py-2.5 dark:bg-gray-800 dark:border-gray-700 fixed left-0 right-0 top-0 z-50",
14
+ controller: "resource-header"
15
+ }
16
+ end
17
+ end
18
+ end
19
+
20
+ Plutonium::ComponentRegistry.register :resource_header, to: PlutoniumUi::ResourceHeaderComponent
@@ -0,0 +1,32 @@
1
+ <!DOCTYPE html>
2
+ <html <%= attributes_html %>>
3
+ <head>
4
+ <title><%= page_title %></title>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width,initial-scale=1">
7
+ <%= csrf_meta_tags %>
8
+ <%= csp_meta_tag %>
9
+
10
+ <%= meta %>
11
+ <%= favicon %>
12
+ <%= fonts %>
13
+ <%= assets %>
14
+ <%= after_head %>
15
+ <%# <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.snow.min.css" integrity="sha512-/FHUK/LsH78K9XTqsR9hbzr21J8B8RwHR/r8Jv9fzry6NVAOVIGFKQCNINsbhK7a1xubVu2r5QZcz2T9cKpubw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
16
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.min.js" integrity="sha512-P2W2rr8ikUPfa31PLBo5bcBQrsa+TNj8jiKadtaIrHQGMo6hQM6RdPjQYxlNguwHz8AwSQ28VkBK6kHBLgd/8g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
17
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.css" integrity="sha512-GvqWM4KWH8mbgWIyvwdH8HgjUbyZTXrCq0sjGij9fDNiXz3vJoy3jCcAaWNekH2rJe4hXVWCJKN+bEW8V7AAEQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
18
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/slim-select/2.6.0/slimselect.min.js" integrity="sha512-0E8oaoA2v32h26IycsmRDShtQ8kMgD91zWVBxdIvUCjU3xBw81PV61QBsBqNQpWkp/zYJZip8Ag3ifmzz1wCKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> %>
19
+ </head>
20
+ <body class="<%= body_classname %>">
21
+ <%= header %>
22
+ <%= sidebar %>
23
+ <main class="<%= build_main_classname %>">
24
+ <%= render "flash" %>
25
+ <%= content %>
26
+ </main>
27
+ </body>
28
+ </html>
29
+
30
+ <%#= modal_frame_tag do %>
31
+ <%#= yield(:modal) %>
32
+ <%# end %>
@@ -0,0 +1,39 @@
1
+ module PlutoniumUi
2
+ class ResourceLayoutComponent < PlutoniumUi::Base
3
+ renders_one :meta
4
+ renders_one :favicon
5
+ renders_one :fonts
6
+ renders_one :assets
7
+ renders_one :after_head
8
+ renders_one :header
9
+ renders_one :sidebar
10
+
11
+ option :page_title
12
+ option :lang
13
+ option :body_classname, default: -> { "antialiased bg-gray-50 dark:bg-gray-900" }
14
+ option :main_classname, default: -> { "p-4 h-auto" }
15
+ option :header_adjustment, default: -> { "pt-20" }
16
+ option :sidebar_adjustment, default: -> { "lg:ml-64" }
17
+
18
+ private
19
+
20
+ def base_attributes
21
+ # base attributes go here
22
+ {
23
+ classname: "resource-layout",
24
+ controller: "resource-layout color-mode",
25
+ lang:
26
+ }
27
+ end
28
+
29
+ def build_main_classname
30
+ classname = Array(main_classname)
31
+ classname += Array(header_adjustment) if header.present?
32
+ classname += Array(sidebar_adjustment) if sidebar.present?
33
+
34
+ classname.join " "
35
+ end
36
+ end
37
+ end
38
+
39
+ Plutonium::ComponentRegistry.register :resource_layout, to: PlutoniumUi::ResourceLayoutComponent
@@ -55,36 +55,6 @@
55
55
  </div>
56
56
  -->
57
57
 
58
- <script>
59
- function updateColorMode() {
60
- // On page load or when changing themes, best to add inline in `head` to avoid FOUC
61
- if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
62
- document.documentElement.classList.add('dark')
63
- } else {
64
- document.documentElement.classList.remove('dark')
65
- }
66
- }
67
-
68
- function setLightColorMode() {
69
- // Whenever the user explicitly chooses light mode
70
- localStorage.theme = 'light'
71
- updateColorMode()
72
- }
73
-
74
- function setDarkColorMode() {
75
- // Whenever the user explicitly chooses dark mode
76
- localStorage.theme = 'dark'
77
- updateColorMode()
78
- }
79
-
80
- function setSystemColorMode() {
81
- // Whenever the user explicitly chooses to respect the OS preference
82
- localStorage.removeItem('theme')
83
- updateColorMode()
84
- }
85
-
86
- updateColorMode()
87
- </script>
88
58
 
89
59
  <!-- Color Modes -->
90
60
  <div data-controller="resource-drop-down">
@@ -105,7 +75,7 @@
105
75
  type="button"
106
76
  class="w-full block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600"
107
77
  role="menuitem"
108
- onclick="setLightColorMode()"
78
+ data-action="click->color-mode#setLightColorMode"
109
79
  >
110
80
  <div class="flex justify-start">
111
81
  <svg class="w-6 h-6 me-2 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
@@ -120,7 +90,7 @@
120
90
  type="button"
121
91
  class="w-full block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600"
122
92
  role="menuitem"
123
- onclick="setDarkColorMode()"
93
+ data-action="click->color-mode#setDarkColorMode"
124
94
  >
125
95
  <div class="flex justify-start">
126
96
  <svg class="w-6 h-6 me-2 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
@@ -135,7 +105,7 @@
135
105
  type="button"
136
106
  class="w-full block py-2 px-4 text-sm text-gray-700 hover:bg-gray-100 dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600"
137
107
  role="menuitem"
138
- onclick="setSystemColorMode()"
108
+ data-action="click->color-mode#setSystemColorMode"
139
109
  >
140
110
  <div class="flex justify-start">
141
111
  <svg class="w-6 h-6 me-2 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
@@ -1,5 +1,5 @@
1
- module Plutonium::Ui
2
- class SidebarComponent < Plutonium::Ui::Base
1
+ module PlutoniumUi
2
+ class SidebarComponent < PlutoniumUi::Base
3
3
  private
4
4
 
5
5
  def sidebar_class
@@ -12,4 +12,4 @@ module Plutonium::Ui
12
12
  end
13
13
  end
14
14
 
15
- Plutonium::ComponentRegistry.register :sidebar, to: Plutonium::Ui::SidebarComponent
15
+ Plutonium::ComponentRegistry.register :sidebar, to: PlutoniumUi::SidebarComponent
@@ -1,3 +1,5 @@
1
- <ul class="<%= menu_class %>">
2
- <%= content %>
1
+ <ul <%= attributes_html %>>
2
+ <% items.each do |item| %>
3
+ <%= item %>
4
+ <% end %>
3
5
  </ul>
@@ -1,13 +1,17 @@
1
- module Plutonium::Ui
2
- class SidebarMenuComponent < Plutonium::Ui::Base
3
- option :separated, optional: true
1
+ module PlutoniumUi
2
+ class SidebarMenuComponent < PlutoniumUi::Base
3
+ renders_many :items, "::PlutoniumUi::SidebarMenuItemComponent"
4
4
 
5
5
  private
6
6
 
7
- def menu_class
8
- "space-y-2 #{separated ? "pt-5 mt-5 border-t border-gray-200 dark:border-gray-700" : nil}"
7
+ def base_attributes
8
+ # base attributes go here
9
+ {
10
+ classname: "sidebar-menu space-y-2",
11
+ controller: "sidebar-menu"
12
+ }
9
13
  end
10
14
  end
11
15
  end
12
16
 
13
- Plutonium::ComponentRegistry.register :sidebar_menu, to: Plutonium::Ui::SidebarMenuComponent
17
+ Plutonium::ComponentRegistry.register :sidebar_menu, to: PlutoniumUi::SidebarMenuComponent