maglevcms 2.1.0 → 3.0.0.beta2

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 (673) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +53 -13
  3. data/Rakefile +0 -4
  4. data/app/assets/builds/maglev/tailwind.css +14393 -0
  5. data/app/assets/config/maglev_manifest.js +7 -0
  6. data/app/assets/javascripts/maglev/client/dom-operations.js +282 -0
  7. data/app/{frontend/live-preview-client → assets/javascripts/maglev/client}/iframe-decorator.js +81 -15
  8. data/app/{frontend/live-preview-client/message.js → assets/javascripts/maglev/client/incoming-messages.js} +14 -12
  9. data/app/assets/javascripts/maglev/client/index.js +26 -0
  10. data/app/{frontend/live-preview-client → assets/javascripts/maglev/client}/utils.js +4 -0
  11. data/app/assets/javascripts/maglev/editor/controllers/app/forms/section_form_controller.js +46 -0
  12. data/app/assets/javascripts/maglev/editor/controllers/app/forms/style_form_controller.js +19 -0
  13. data/app/assets/javascripts/maglev/editor/controllers/app/index.js +15 -0
  14. data/app/assets/javascripts/maglev/editor/controllers/app/page_preview_controller.js +163 -0
  15. data/app/assets/javascripts/maglev/editor/controllers/app/preview_notification_center_controller.js +151 -0
  16. data/app/assets/javascripts/maglev/editor/controllers/app/setting_controller.js +42 -0
  17. data/app/assets/javascripts/maglev/editor/controllers/application.js +9 -0
  18. data/app/assets/javascripts/maglev/editor/controllers/index.js +3 -0
  19. data/app/assets/javascripts/maglev/editor/controllers/shared/auto_save_controller.js +16 -0
  20. data/app/assets/javascripts/maglev/editor/controllers/shared/broken_image_controller.js +16 -0
  21. data/app/assets/javascripts/maglev/editor/controllers/shared/copy_to_clipboard_controller.js +36 -0
  22. data/app/assets/javascripts/maglev/editor/controllers/shared/disappearance_controller.js +21 -0
  23. data/app/assets/javascripts/maglev/editor/controllers/shared/dispatcher_controller.js +12 -0
  24. data/app/assets/javascripts/maglev/editor/controllers/shared/form_refresh_controller.js +15 -0
  25. data/app/assets/javascripts/maglev/editor/controllers/shared/index.js +27 -0
  26. data/app/assets/javascripts/maglev/editor/controllers/shared/max_length_controller.js +30 -0
  27. data/app/assets/javascripts/maglev/editor/controllers/shared/prevent_same_path.js +20 -0
  28. data/app/assets/javascripts/maglev/editor/controllers/shared/reload_page_controller.js +7 -0
  29. data/app/assets/javascripts/maglev/editor/controllers/shared/sortable_controller.js +64 -0
  30. data/app/assets/javascripts/maglev/editor/controllers/shared/submit_button_controller.js +45 -0
  31. data/app/assets/javascripts/maglev/editor/controllers/shared/transition_controller.js +14 -0
  32. data/app/assets/javascripts/maglev/editor/controllers/uikit.js +39 -0
  33. data/app/assets/javascripts/maglev/editor/controllers/utils.js +10 -0
  34. data/app/assets/javascripts/maglev/editor/index.js +66 -0
  35. data/app/assets/stylesheets/maglev/application.css +88 -0
  36. data/app/{frontend/editor/design/components/rich-text-editor.scss → assets/stylesheets/maglev/tailwind.css.erb} +30 -15
  37. data/app/components/maglev/editor/setting_registry.rb +59 -0
  38. data/app/components/maglev/editor/settings/base_component.rb +55 -0
  39. data/app/components/maglev/editor/settings/checkbox/checkbox_component.html.erb +16 -0
  40. data/app/components/maglev/editor/settings/checkbox/checkbox_component.rb +12 -0
  41. data/app/components/maglev/editor/settings/collection_item/collection_item_component.html.erb +25 -0
  42. data/app/components/maglev/editor/settings/collection_item/collection_item_component.rb +19 -0
  43. data/app/components/maglev/editor/settings/color/color_component.html.erb +17 -0
  44. data/app/components/maglev/editor/settings/color/color_component.rb +12 -0
  45. data/app/components/maglev/editor/settings/divider/divider_component.html.erb +12 -0
  46. data/app/components/maglev/editor/settings/divider/divider_component.rb +15 -0
  47. data/app/components/maglev/editor/settings/hint/hint_component.html.erb +3 -0
  48. data/app/components/maglev/editor/settings/hint/hint_component.rb +12 -0
  49. data/app/components/maglev/editor/settings/icon/icon_component.html.erb +21 -0
  50. data/app/components/maglev/editor/settings/icon/icon_component.rb +15 -0
  51. data/app/components/maglev/editor/settings/image/image_component.html.erb +26 -0
  52. data/app/components/maglev/editor/settings/image/image_component.rb +23 -0
  53. data/app/components/maglev/editor/settings/link/link_component.html.erb +22 -0
  54. data/app/components/maglev/editor/settings/link/link_component.rb +19 -0
  55. data/app/components/maglev/editor/settings/select/select_component.html.erb +20 -0
  56. data/app/components/maglev/editor/settings/select/select_component.rb +27 -0
  57. data/app/components/maglev/editor/settings/text/richtext_component.html.erb +22 -0
  58. data/app/components/maglev/editor/settings/text/richtext_component.rb +12 -0
  59. data/app/components/maglev/editor/settings/text/text_component.html.erb +18 -0
  60. data/app/components/maglev/editor/settings/text/text_component.rb +12 -0
  61. data/app/components/maglev/editor/settings/text/textarea_component.html.erb +21 -0
  62. data/app/components/maglev/editor/settings/text/textarea_component.rb +12 -0
  63. data/app/components/maglev/editor/settings_group_component.html.erb +5 -0
  64. data/app/components/maglev/editor/settings_group_component.rb +30 -0
  65. data/app/components/maglev/section_component.rb +10 -7
  66. data/app/components/maglev/uikit/app_layout/layout_component.html.erb +15 -0
  67. data/app/components/maglev/uikit/app_layout/layout_component.rb +19 -0
  68. data/app/components/maglev/uikit/app_layout/sidebar/link_component.html.erb +5 -0
  69. data/app/components/maglev/uikit/app_layout/sidebar/link_component.rb +40 -0
  70. data/app/components/maglev/uikit/app_layout/sidebar_component.html.erb +19 -0
  71. data/app/components/maglev/uikit/app_layout/sidebar_component.rb +11 -0
  72. data/app/components/maglev/uikit/app_layout/topbar/logo_component.html.erb +3 -0
  73. data/app/components/maglev/uikit/app_layout/topbar/logo_component.rb +18 -0
  74. data/app/components/maglev/uikit/app_layout/topbar/page_info_component.html.erb +26 -0
  75. data/app/components/maglev/uikit/app_layout/topbar/page_info_component.rb +28 -0
  76. data/app/components/maglev/uikit/app_layout/topbar_component.html.erb +15 -0
  77. data/app/components/maglev/uikit/app_layout/topbar_component.rb +21 -0
  78. data/app/components/maglev/uikit/badge_component.rb +40 -0
  79. data/app/components/maglev/uikit/base_component.rb +15 -0
  80. data/app/components/maglev/uikit/breadcrumbs/breadcrumbs_component.html.erb +10 -0
  81. data/app/components/maglev/uikit/breadcrumbs/breadcrumbs_component.rb +11 -0
  82. data/app/components/maglev/uikit/breadcrumbs/link_component.html.erb +12 -0
  83. data/app/components/maglev/uikit/breadcrumbs/link_component.rb +25 -0
  84. data/app/components/maglev/uikit/collapsible/collapsible_component.html.erb +5 -0
  85. data/app/components/maglev/uikit/collapsible/collapsible_component.rb +11 -0
  86. data/app/components/maglev/uikit/collapsible/collapsible_controller.js +9 -0
  87. data/app/components/maglev/uikit/collapsible/item_component.html.erb +17 -0
  88. data/app/components/maglev/uikit/collapsible/item_component.rb +11 -0
  89. data/app/components/maglev/uikit/device_toggler_component/device_toggler_component.html.erb +16 -0
  90. data/app/components/maglev/uikit/device_toggler_component/device_toggler_controller.js +25 -0
  91. data/app/components/maglev/uikit/device_toggler_component.rb +28 -0
  92. data/app/components/maglev/uikit/dropdown_component/dropdown_component.html.erb +18 -0
  93. data/app/components/maglev/uikit/dropdown_component/dropdown_controller.js +69 -0
  94. data/app/components/maglev/uikit/dropdown_component.rb +15 -0
  95. data/app/components/maglev/uikit/form/checkbox_component.html.erb +17 -0
  96. data/app/components/maglev/uikit/form/checkbox_component.rb +26 -0
  97. data/app/components/maglev/uikit/form/checkbox_controller.js +7 -0
  98. data/app/components/maglev/uikit/form/color_field_component.html.erb +76 -0
  99. data/app/components/maglev/uikit/form/color_field_component.rb +57 -0
  100. data/app/components/maglev/uikit/form/color_field_controller.js +25 -0
  101. data/app/components/maglev/uikit/form/combobox/list_component.html.erb +14 -0
  102. data/app/components/maglev/uikit/form/combobox/list_component.rb +13 -0
  103. data/app/components/maglev/uikit/form/combobox/option_component.html.erb +16 -0
  104. data/app/components/maglev/uikit/form/combobox/option_component.rb +22 -0
  105. data/app/components/maglev/uikit/form/combobox_component.html.erb +75 -0
  106. data/app/components/maglev/uikit/form/combobox_component.rb +64 -0
  107. data/app/components/maglev/uikit/form/combobox_controller.js +385 -0
  108. data/app/components/maglev/uikit/form/icon_field_component.html.erb +76 -0
  109. data/app/components/maglev/uikit/form/icon_field_component.rb +35 -0
  110. data/app/components/maglev/uikit/form/icon_field_controller.js +38 -0
  111. data/app/components/maglev/uikit/form/image_field_component.html.erb +101 -0
  112. data/app/components/maglev/uikit/form/image_field_component.rb +52 -0
  113. data/app/components/maglev/uikit/form/image_field_controller.js +74 -0
  114. data/app/components/maglev/uikit/form/link/base_component.rb +19 -0
  115. data/app/components/maglev/uikit/form/link/email_link_component.html.erb +16 -0
  116. data/app/components/maglev/uikit/form/link/email_link_component.rb +12 -0
  117. data/app/components/maglev/uikit/form/link/page_link_component.html.erb +17 -0
  118. data/app/components/maglev/uikit/form/link/page_link_component.rb +12 -0
  119. data/app/components/maglev/uikit/form/link/static_page_link_component.html.erb +16 -0
  120. data/app/components/maglev/uikit/form/link/static_page_link_component.rb +12 -0
  121. data/app/components/maglev/uikit/form/link/url_link_component.html.erb +16 -0
  122. data/app/components/maglev/uikit/form/link/url_link_component.rb +19 -0
  123. data/app/components/maglev/uikit/form/link_component.html.erb +55 -0
  124. data/app/components/maglev/uikit/form/link_component.rb +80 -0
  125. data/app/components/maglev/uikit/form/link_controller.js +36 -0
  126. data/app/components/maglev/uikit/form/richtext/block_button_component.html.erb +38 -0
  127. data/app/components/maglev/uikit/form/richtext/block_button_component.rb +22 -0
  128. data/app/components/maglev/uikit/form/richtext/button_component.html.erb +16 -0
  129. data/app/components/maglev/uikit/form/richtext/button_component.rb +19 -0
  130. data/app/components/maglev/uikit/form/richtext/button_group_component.html.erb +7 -0
  131. data/app/components/maglev/uikit/form/richtext/button_group_component.rb +13 -0
  132. data/app/components/maglev/uikit/form/richtext/toolbar_component.html.erb +23 -0
  133. data/app/components/maglev/uikit/form/richtext/toolbar_component.rb +19 -0
  134. data/app/components/maglev/uikit/form/richtext_component.html.erb +28 -0
  135. data/app/components/maglev/uikit/form/richtext_component.rb +54 -0
  136. data/app/components/maglev/uikit/form/richtext_controller.js +248 -0
  137. data/app/components/maglev/uikit/form/search_form_component.html.erb +24 -0
  138. data/app/components/maglev/uikit/form/search_form_component.rb +42 -0
  139. data/app/components/maglev/uikit/form/search_form_controller.js +31 -0
  140. data/app/components/maglev/uikit/form/select_component.html.erb +19 -0
  141. data/app/components/maglev/uikit/form/select_component.rb +52 -0
  142. data/app/components/maglev/uikit/form/select_controller.js +7 -0
  143. data/app/components/maglev/uikit/form/text_field_component.html.erb +26 -0
  144. data/app/components/maglev/uikit/form/text_field_component.rb +42 -0
  145. data/app/components/maglev/uikit/form/text_field_controller.js +18 -0
  146. data/app/components/maglev/uikit/form/textarea_component.html.erb +43 -0
  147. data/app/components/maglev/uikit/form/textarea_component.rb +53 -0
  148. data/app/components/maglev/uikit/icon_button_component/icon_button_component.html.erb +3 -0
  149. data/app/components/maglev/uikit/icon_button_component.rb +18 -0
  150. data/app/components/maglev/uikit/icon_component.rb +140 -0
  151. data/app/components/maglev/uikit/image_library/card_component.html.erb +41 -0
  152. data/app/components/maglev/uikit/image_library/card_component.rb +52 -0
  153. data/app/components/maglev/uikit/image_library/list_component.html.erb +7 -0
  154. data/app/components/maglev/uikit/image_library/list_component.rb +11 -0
  155. data/app/components/maglev/uikit/image_library/uploader_component.html.erb +30 -0
  156. data/app/components/maglev/uikit/image_library/uploader_component.rb +29 -0
  157. data/app/components/maglev/uikit/image_library/uploader_controller.js +74 -0
  158. data/app/components/maglev/uikit/list/insert_button_component.html.erb +7 -0
  159. data/app/components/maglev/uikit/list/insert_button_component.rb +40 -0
  160. data/app/components/maglev/uikit/list/list_component.html.erb +17 -0
  161. data/app/components/maglev/uikit/list/list_component.rb +34 -0
  162. data/app/components/maglev/uikit/list/list_item_component.html.erb +47 -0
  163. data/app/components/maglev/uikit/list/list_item_component.rb +85 -0
  164. data/app/components/maglev/uikit/locale_switcher_component/locale_switcher_component.html.erb +22 -0
  165. data/app/components/maglev/uikit/locale_switcher_component.rb +18 -0
  166. data/app/components/maglev/uikit/menu_dropdown_component/menu_dropdown_component.html.erb +15 -0
  167. data/app/components/maglev/uikit/menu_dropdown_component.rb +32 -0
  168. data/app/components/maglev/uikit/modal_component/modal_component.html.erb +63 -0
  169. data/app/components/maglev/uikit/modal_component/modal_controller.js +47 -0
  170. data/app/components/maglev/uikit/modal_component.rb +33 -0
  171. data/app/components/maglev/uikit/page_actions_dropdown_component/page_actions_dropdown_component.html.erb +56 -0
  172. data/app/components/maglev/uikit/page_actions_dropdown_component.rb +24 -0
  173. data/app/components/maglev/uikit/page_layout_component/back_link_component.html.erb +4 -0
  174. data/app/components/maglev/uikit/page_layout_component/page_layout_component.html.erb +58 -0
  175. data/app/components/maglev/uikit/page_layout_component/page_layout_controller.js +34 -0
  176. data/app/components/maglev/uikit/page_layout_component.rb +42 -0
  177. data/app/components/maglev/uikit/pagination_component/pagination_component.html.erb +70 -0
  178. data/app/components/maglev/uikit/pagination_component.rb +25 -0
  179. data/app/components/maglev/uikit/section_toolbar/bottom_component.html.erb +13 -0
  180. data/app/components/maglev/uikit/section_toolbar/bottom_component.rb +27 -0
  181. data/app/components/maglev/uikit/section_toolbar/section_toolbar_component.html.erb +17 -0
  182. data/app/components/maglev/uikit/section_toolbar/section_toolbar_component.rb +18 -0
  183. data/app/components/maglev/uikit/section_toolbar/section_toolbar_controller.js +90 -0
  184. data/app/components/maglev/uikit/section_toolbar/top_left_corner_component.html.erb +16 -0
  185. data/app/components/maglev/uikit/section_toolbar/top_left_corner_component.rb +15 -0
  186. data/app/components/maglev/uikit/section_toolbar/top_right_corner_component.html.erb +28 -0
  187. data/app/components/maglev/uikit/section_toolbar/top_right_corner_component.rb +28 -0
  188. data/app/components/maglev/uikit/tabs_component/tabs_component.html.erb +35 -0
  189. data/app/components/maglev/uikit/tabs_component/tabs_controller.js +57 -0
  190. data/app/components/maglev/uikit/tabs_component.rb +71 -0
  191. data/app/controllers/concerns/maglev/content_locale_concern.rb +5 -1
  192. data/app/controllers/concerns/maglev/editor/errors_concern.rb +45 -0
  193. data/app/controllers/concerns/maglev/fetchers_concern.rb +3 -6
  194. data/app/controllers/concerns/maglev/flash_i18n_concern.rb +11 -0
  195. data/app/controllers/maglev/application_controller.rb +1 -7
  196. data/app/controllers/maglev/editor/assets_controller.rb +59 -0
  197. data/app/controllers/maglev/editor/base_controller.rb +111 -0
  198. data/app/controllers/maglev/editor/combobox/collection_items_controller.rb +17 -0
  199. data/app/controllers/maglev/editor/combobox/pages_controller.rb +20 -0
  200. data/app/controllers/maglev/editor/home_controller.rb +25 -0
  201. data/app/controllers/maglev/editor/icons_controller.rb +24 -0
  202. data/app/controllers/maglev/editor/links_controller.rb +52 -0
  203. data/app/controllers/maglev/editor/page_clone_controller.rb +20 -0
  204. data/app/controllers/maglev/editor/pages_controller.rb +77 -0
  205. data/app/controllers/maglev/editor/publication_controller.rb +14 -0
  206. data/app/controllers/maglev/editor/section_blocks_controller.rb +101 -0
  207. data/app/controllers/maglev/editor/sections_controller.rb +96 -0
  208. data/app/controllers/maglev/editor/style_controller.rb +31 -0
  209. data/app/controllers/maglev/page_preview_controller.rb +1 -5
  210. data/app/controllers/maglev/published_page_preview_controller.rb +50 -0
  211. data/app/controllers/maglev/sitemap_controller.rb +1 -1
  212. data/app/helpers/maglev/application_helper.rb +148 -18
  213. data/app/helpers/maglev/editor/pages_helper.rb +23 -0
  214. data/app/helpers/maglev/editor/section_blocks_helper.rb +124 -0
  215. data/app/helpers/maglev/editor/settings_helper.rb +52 -0
  216. data/app/helpers/maglev/page_preview_helper.rb +1 -1
  217. data/app/lib/maglev/form/form_builder.rb +38 -0
  218. data/app/lib/maglev/form/inputs/check_box.rb +20 -0
  219. data/app/lib/maglev/form/inputs/combobox.rb +33 -0
  220. data/app/lib/maglev/form/inputs/image_field.rb +39 -0
  221. data/app/lib/maglev/form/inputs/richtext.rb +34 -0
  222. data/app/lib/maglev/form/inputs/select.rb +34 -0
  223. data/app/lib/maglev/form/inputs/text_field.rb +32 -0
  224. data/app/lib/maglev/form/inputs/textarea.rb +30 -0
  225. data/app/lib/maglev/turbo/streams/tag_builder.rb +17 -0
  226. data/app/models/concerns/maglev/content/enhanced_value_concern.rb +40 -0
  227. data/app/models/concerns/maglev/sections_concern.rb +30 -1
  228. data/app/models/concerns/maglev/translatable.rb +1 -2
  229. data/app/models/maglev/asset.rb +1 -3
  230. data/app/models/maglev/content/block_content.rb +96 -0
  231. data/app/models/maglev/content/editor_link.rb +49 -0
  232. data/app/models/maglev/content/section_content.rb +85 -0
  233. data/app/models/maglev/content/setting_content.rb +33 -0
  234. data/app/models/maglev/page/path_concern.rb +7 -0
  235. data/app/models/maglev/page/search_concern.rb +23 -4
  236. data/app/models/maglev/page.rb +3 -0
  237. data/app/models/maglev/section/block.rb +43 -6
  238. data/app/models/maglev/section/content_concern.rb +15 -1
  239. data/app/models/maglev/section/setting.rb +12 -0
  240. data/app/models/maglev/section.rb +52 -4
  241. data/app/models/maglev/sections_content_store.rb +36 -0
  242. data/app/models/maglev/setting_types/base.rb +8 -0
  243. data/app/models/maglev/setting_types/collection_item.rb +5 -1
  244. data/app/models/maglev/setting_types/image.rb +4 -0
  245. data/app/models/maglev/setting_types/link.rb +4 -0
  246. data/app/models/maglev/setting_types/text.rb +5 -0
  247. data/app/models/maglev/site/locales_concern.rb +4 -0
  248. data/app/models/maglev/site/style_value.rb +19 -13
  249. data/app/models/maglev/site.rb +4 -0
  250. data/app/models/maglev/theme/section_category.rb +6 -1
  251. data/app/models/maglev/theme/style_setting.rb +1 -1
  252. data/app/models/maglev/theme.rb +13 -0
  253. data/app/services/concerns/maglev/content/helpers_concern.rb +100 -0
  254. data/app/services/concerns/maglev/get_page_sections/transform_section_concern.rb +97 -0
  255. data/app/services/maglev/app_container.rb +27 -2
  256. data/app/services/maglev/content/add_section_block_service.rb +53 -0
  257. data/app/services/maglev/content/add_section_service.rb +99 -0
  258. data/app/services/maglev/content/delete_section_block_service.rb +45 -0
  259. data/app/services/maglev/content/delete_section_service.rb +34 -0
  260. data/app/services/maglev/content/sort_section_blocks_service.rb +47 -0
  261. data/app/services/maglev/content/update_section_block_service.rb +52 -0
  262. data/app/services/maglev/content/update_section_service.rb +50 -0
  263. data/app/services/maglev/create_page_service.rb +39 -0
  264. data/app/services/maglev/fetch_style.rb +22 -12
  265. data/app/services/maglev/get_base_url.rb +3 -1
  266. data/app/services/maglev/get_page_section_names.rb +1 -1
  267. data/app/services/maglev/get_page_sections.rb +11 -82
  268. data/app/services/maglev/get_published_page_sections_service.rb +48 -0
  269. data/app/services/maglev/persist_section_screenshot.rb +1 -1
  270. data/app/services/maglev/persist_style_service.rb +36 -0
  271. data/app/services/maglev/publish_service.rb +30 -0
  272. data/app/services/maglev/search_pages.rb +6 -2
  273. data/app/services/maglev/setup_pages.rb +44 -33
  274. data/app/views/layouts/maglev/editor/_head.html.erb +0 -0
  275. data/app/views/layouts/maglev/editor/_sidebar.html.erb +39 -0
  276. data/app/views/layouts/maglev/editor/_topbar.html.erb +45 -0
  277. data/app/views/layouts/maglev/editor/application.html.erb +67 -0
  278. data/app/views/maglev/editor/assets/_list.html.erb +33 -0
  279. data/app/views/maglev/editor/assets/index.html.erb +29 -0
  280. data/app/views/maglev/editor/combobox/collection_items/index.turbo_stream.erb +18 -0
  281. data/app/views/maglev/editor/combobox/pages/index.turbo_stream.erb +7 -0
  282. data/app/views/maglev/editor/home/index.html.erb +1 -0
  283. data/app/views/maglev/editor/icons/_list.html.erb +27 -0
  284. data/app/views/maglev/editor/icons/index.html.erb +23 -0
  285. data/app/views/maglev/editor/links/edit/_email.html.erb +5 -0
  286. data/app/views/maglev/editor/links/edit/_page.html.erb +29 -0
  287. data/app/views/maglev/editor/links/edit/_tabs.html.erb +11 -0
  288. data/app/views/maglev/editor/links/edit/_url.html.erb +7 -0
  289. data/app/views/maglev/editor/links/edit.html.erb +31 -0
  290. data/app/views/maglev/editor/links/update.turbo_stream.erb +9 -0
  291. data/app/views/maglev/editor/pages/_list.html.erb +28 -0
  292. data/app/views/maglev/editor/pages/_preview.html.erb +35 -0
  293. data/app/views/maglev/editor/pages/_preview_empty_message.html.erb +14 -0
  294. data/app/views/maglev/editor/pages/edit.html.erb +32 -0
  295. data/app/views/maglev/editor/pages/form/_main.html.erb +7 -0
  296. data/app/views/maglev/editor/pages/form/_seo.html.erb +11 -0
  297. data/app/views/maglev/editor/pages/form/_tabs.html.erb +8 -0
  298. data/app/views/maglev/editor/pages/index.html.erb +23 -0
  299. data/app/views/maglev/editor/pages/new.html.erb +28 -0
  300. data/app/views/maglev/editor/publication/create.turbo_stream.erb +1 -0
  301. data/app/views/maglev/editor/section_blocks/_form.html.erb +15 -0
  302. data/app/views/maglev/editor/section_blocks/_new.html.erb +21 -0
  303. data/app/views/maglev/editor/section_blocks/edit.html.erb +28 -0
  304. data/app/views/maglev/editor/section_blocks/index/_list.html.erb +41 -0
  305. data/app/views/maglev/editor/section_blocks/index/_tree.html.erb +56 -0
  306. data/app/views/maglev/editor/section_blocks/index.html.erb +20 -0
  307. data/app/views/maglev/editor/section_blocks/update.turbo_stream.erb +5 -0
  308. data/app/views/maglev/editor/sections/_form.html.erb +21 -0
  309. data/app/views/maglev/editor/sections/_list.html.erb +50 -0
  310. data/app/views/maglev/editor/sections/_theme_list.html.erb +32 -0
  311. data/app/views/maglev/editor/sections/_toolbar_list.html.erb +17 -0
  312. data/app/views/maglev/editor/sections/edit.html.erb +24 -0
  313. data/app/views/maglev/editor/sections/index.html.erb +11 -0
  314. data/app/views/maglev/editor/sections/new.html.erb +20 -0
  315. data/app/views/maglev/editor/sections/update.turbo_stream.erb +5 -0
  316. data/app/views/maglev/editor/shared/_button_label.html.erb +18 -0
  317. data/app/views/maglev/editor/shared/errors/not_authorized_error.turbo_stream.erb +17 -0
  318. data/app/views/maglev/editor/shared/errors/stale_object_error.turbo_stream.erb +21 -0
  319. data/app/views/maglev/editor/shared/errors/standard_error.turbo_stream.erb +17 -0
  320. data/app/views/maglev/editor/style/edit.html.erb +24 -0
  321. data/app/views/maglev/sitemap/index.xml.builder +1 -1
  322. data/config/client_importmap.rb +4 -0
  323. data/config/editor_importmap.rb +26 -0
  324. data/config/initializers/pagy.rb +3 -0
  325. data/config/locales/activerecord.ar.yml +20 -2
  326. data/config/locales/activerecord.en.yml +20 -2
  327. data/config/locales/activerecord.es.yml +15 -14
  328. data/config/locales/activerecord.fr.yml +15 -14
  329. data/config/locales/activerecord.pt-BR.yml +22 -4
  330. data/config/locales/editor.ar.yml +268 -0
  331. data/config/locales/editor.en.yml +268 -0
  332. data/config/locales/editor.es.yml +268 -0
  333. data/config/locales/editor.fr.yml +268 -0
  334. data/config/locales/editor.pt-BR.yml +268 -0
  335. data/config/locales/uikit.ar.yml +14 -0
  336. data/config/locales/uikit.en.yml +14 -0
  337. data/config/locales/uikit.es.yml +14 -0
  338. data/config/locales/uikit.fr.yml +14 -0
  339. data/config/locales/uikit.pt-BR.yml +14 -0
  340. data/config/routes.rb +34 -35
  341. data/db/migrate/20250929203214_create_maglev_sections_content_stores.rb +21 -0
  342. data/exe/tailwind-cli +29 -0
  343. data/lib/commands/maglev/publish_site_command.rb +46 -0
  344. data/lib/generators/maglev/install_generator.rb +1 -6
  345. data/lib/generators/maglev/templates/install/config/initializers/maglev.rb +6 -2
  346. data/lib/generators/maglev/templates/theme/app/views/theme/layout.html.erb.tt +2 -2
  347. data/lib/maglev/config.rb +2 -1
  348. data/lib/maglev/engine.rb +34 -42
  349. data/lib/maglev/errors.rb +3 -0
  350. data/lib/maglev/version.rb +1 -1
  351. data/lib/maglev.rb +3 -1
  352. data/lib/tasks/maglev/tailwindcss.rake +38 -0
  353. data/lib/tasks/maglev_tasks.rake +4 -23
  354. data/vendor/javascript/@floating-ui--core.js +4 -0
  355. data/vendor/javascript/@floating-ui--dom.js +12 -0
  356. data/vendor/javascript/@floating-ui--utils--dom.js +4 -0
  357. data/vendor/javascript/@floating-ui--utils.js +4 -0
  358. data/vendor/javascript/@hotwired--stimulus.js +4 -0
  359. data/vendor/javascript/@hotwired--turbo-rails.js +4 -0
  360. data/vendor/javascript/@hotwired--turbo.js +458 -0
  361. data/vendor/javascript/@rails--actioncable--src.js +4 -0
  362. data/vendor/javascript/@rails--request.js.js +4 -0
  363. data/vendor/javascript/@shopify--draggable.js +4 -0
  364. data/vendor/javascript/el-transition.js +4 -0
  365. data/vendor/javascript/stimulus-use.js +4 -0
  366. data/vendor/javascript/tiptap.bundle.js +1 -0
  367. metadata +363 -342
  368. data/.babelrc +0 -9
  369. data/.yarn/install-state.gz +0 -0
  370. data/.yarn/releases/yarn-4.4.0.cjs +0 -925
  371. data/.yarnrc.yml +0 -3
  372. data/app/controllers/maglev/admin/base_controller.rb +0 -20
  373. data/app/controllers/maglev/admin/dashboard_controller.rb +0 -11
  374. data/app/controllers/maglev/admin/sections/previews_controller.rb +0 -52
  375. data/app/controllers/maglev/admin/sections/screenshots_controller.rb +0 -17
  376. data/app/controllers/maglev/admin/themes_controller.rb +0 -19
  377. data/app/controllers/maglev/api/assets_controller.rb +0 -44
  378. data/app/controllers/maglev/api/collection_items_controller.rb +0 -21
  379. data/app/controllers/maglev/api/page_clones_controller.rb +0 -21
  380. data/app/controllers/maglev/api/pages_controller.rb +0 -65
  381. data/app/controllers/maglev/api/publications_controller.rb +0 -15
  382. data/app/controllers/maglev/api/sites_controller.rb +0 -21
  383. data/app/controllers/maglev/api_controller.rb +0 -61
  384. data/app/controllers/maglev/editor_controller.rb +0 -59
  385. data/app/frontend/admin/controllers/dropdown_controller.js +0 -9
  386. data/app/frontend/admin/controllers/iframe_controller.js +0 -16
  387. data/app/frontend/admin/controllers/screenshot_controller.js +0 -69
  388. data/app/frontend/admin/index.js +0 -10
  389. data/app/frontend/admin/utils/axios.js +0 -16
  390. data/app/frontend/editor/App.vue +0 -43
  391. data/app/frontend/editor/assets/remixicons/add-box-line.svg +0 -1
  392. data/app/frontend/editor/assets/remixicons/arrow-down-s-line.svg +0 -1
  393. data/app/frontend/editor/assets/remixicons/arrow-drop-left.svg +0 -1
  394. data/app/frontend/editor/assets/remixicons/arrow-drop-right.svg +0 -1
  395. data/app/frontend/editor/assets/remixicons/arrow-up-s-line.svg +0 -1
  396. data/app/frontend/editor/assets/remixicons/camera-line.svg +0 -1
  397. data/app/frontend/editor/assets/remixicons/clipboard-line.svg +0 -1
  398. data/app/frontend/editor/assets/remixicons/close-line.svg +0 -1
  399. data/app/frontend/editor/assets/remixicons/computer-line.svg +0 -1
  400. data/app/frontend/editor/assets/remixicons/delete-bin-line.svg +0 -1
  401. data/app/frontend/editor/assets/remixicons/file-line.svg +0 -1
  402. data/app/frontend/editor/assets/remixicons/format-blockquote.svg +0 -1
  403. data/app/frontend/editor/assets/remixicons/format-bold.svg +0 -1
  404. data/app/frontend/editor/assets/remixicons/format-code.svg +0 -1
  405. data/app/frontend/editor/assets/remixicons/format-heading-2.svg +0 -1
  406. data/app/frontend/editor/assets/remixicons/format-heading-3.svg +0 -1
  407. data/app/frontend/editor/assets/remixicons/format-heading-4.svg +0 -1
  408. data/app/frontend/editor/assets/remixicons/format-italic.svg +0 -1
  409. data/app/frontend/editor/assets/remixicons/format-link-unlink.svg +0 -1
  410. data/app/frontend/editor/assets/remixicons/format-link.svg +0 -1
  411. data/app/frontend/editor/assets/remixicons/format-list-ordered.svg +0 -1
  412. data/app/frontend/editor/assets/remixicons/format-list-unordered.svg +0 -1
  413. data/app/frontend/editor/assets/remixicons/format-paragraph.svg +0 -1
  414. data/app/frontend/editor/assets/remixicons/format-strikethrough.svg +0 -1
  415. data/app/frontend/editor/assets/remixicons/format-superscript.svg +0 -1
  416. data/app/frontend/editor/assets/remixicons/format-underline.svg +0 -1
  417. data/app/frontend/editor/assets/remixicons/home-4-line.svg +0 -1
  418. data/app/frontend/editor/assets/remixicons/image-line.svg +0 -1
  419. data/app/frontend/editor/assets/remixicons/logout-box-r-line.svg +0 -1
  420. data/app/frontend/editor/assets/remixicons/ri-add-line.svg +0 -1
  421. data/app/frontend/editor/assets/remixicons/ri-alert-line.svg +0 -1
  422. data/app/frontend/editor/assets/remixicons/ri-book-line.svg +0 -1
  423. data/app/frontend/editor/assets/remixicons/ri-bug-line.svg +0 -1
  424. data/app/frontend/editor/assets/remixicons/ri-check-line.svg +0 -1
  425. data/app/frontend/editor/assets/remixicons/ri-close-circle-line.svg +0 -1
  426. data/app/frontend/editor/assets/remixicons/ri-close-line.svg +0 -1
  427. data/app/frontend/editor/assets/remixicons/ri-delete-column.svg +0 -1
  428. data/app/frontend/editor/assets/remixicons/ri-delete-row.svg +0 -1
  429. data/app/frontend/editor/assets/remixicons/ri-draggable.svg +0 -1
  430. data/app/frontend/editor/assets/remixicons/ri-drop-line.svg +0 -1
  431. data/app/frontend/editor/assets/remixicons/ri-external-link-line.svg +0 -1
  432. data/app/frontend/editor/assets/remixicons/ri-eye-line.svg +0 -1
  433. data/app/frontend/editor/assets/remixicons/ri-eye-off-line.svg +0 -1
  434. data/app/frontend/editor/assets/remixicons/ri-file-copy-line.svg +0 -1
  435. data/app/frontend/editor/assets/remixicons/ri-file-line.svg +0 -1
  436. data/app/frontend/editor/assets/remixicons/ri-folders-line.svg +0 -1
  437. data/app/frontend/editor/assets/remixicons/ri-global-line.svg +0 -1
  438. data/app/frontend/editor/assets/remixicons/ri-insert-column-left.svg +0 -1
  439. data/app/frontend/editor/assets/remixicons/ri-insert-column-right.svg +0 -1
  440. data/app/frontend/editor/assets/remixicons/ri-insert-row-bottom.svg +0 -1
  441. data/app/frontend/editor/assets/remixicons/ri-insert-row-top.svg +0 -1
  442. data/app/frontend/editor/assets/remixicons/ri-loader-4-line.svg +0 -1
  443. data/app/frontend/editor/assets/remixicons/ri-mail-line.svg +0 -1
  444. data/app/frontend/editor/assets/remixicons/ri-more-2-fill.svg +0 -1
  445. data/app/frontend/editor/assets/remixicons/ri-more-fill.svg +0 -1
  446. data/app/frontend/editor/assets/remixicons/ri-palette-line.svg +0 -1
  447. data/app/frontend/editor/assets/remixicons/ri-pencil-line.svg +0 -1
  448. data/app/frontend/editor/assets/remixicons/ri-play-list-add-line.svg +0 -1
  449. data/app/frontend/editor/assets/remixicons/ri-settings-5-line.svg +0 -1
  450. data/app/frontend/editor/assets/remixicons/ri-shadow-line.svg +0 -1
  451. data/app/frontend/editor/assets/remixicons/ri-stack-line.svg +0 -1
  452. data/app/frontend/editor/assets/remixicons/ri-table-2.svg +0 -1
  453. data/app/frontend/editor/assets/remixicons/ri-table-line.svg +0 -1
  454. data/app/frontend/editor/assets/remixicons/search-line.svg +0 -1
  455. data/app/frontend/editor/assets/remixicons/settings-4-line.svg +0 -1
  456. data/app/frontend/editor/assets/remixicons/smartphone-line.svg +0 -1
  457. data/app/frontend/editor/assets/remixicons/tablet-line.svg +0 -1
  458. data/app/frontend/editor/components/dynamic-form/dynamic-input.vue +0 -142
  459. data/app/frontend/editor/components/dynamic-form/index.vue +0 -36
  460. data/app/frontend/editor/components/errors/forbidden.vue +0 -24
  461. data/app/frontend/editor/components/errors/stale-record.vue +0 -24
  462. data/app/frontend/editor/components/header-nav/device-toggler.vue +0 -40
  463. data/app/frontend/editor/components/header-nav/index.vue +0 -77
  464. data/app/frontend/editor/components/header-nav/locale-toggler/index.vue +0 -51
  465. data/app/frontend/editor/components/header-nav/locale-toggler/locale-link.vue +0 -32
  466. data/app/frontend/editor/components/header-nav/page-info.vue +0 -41
  467. data/app/frontend/editor/components/header-nav/preview-button.vue +0 -20
  468. data/app/frontend/editor/components/header-nav/preview-toggler.vue +0 -40
  469. data/app/frontend/editor/components/header-nav/publish-button.vue +0 -77
  470. data/app/frontend/editor/components/header-nav/save-button.vue +0 -33
  471. data/app/frontend/editor/components/header-nav/separator.vue +0 -11
  472. data/app/frontend/editor/components/icon-library/index.vue +0 -39
  473. data/app/frontend/editor/components/image-library/index.vue +0 -107
  474. data/app/frontend/editor/components/image-library/list-item.vue +0 -93
  475. data/app/frontend/editor/components/image-library/list.vue +0 -26
  476. data/app/frontend/editor/components/image-library/uploader.vue +0 -76
  477. data/app/frontend/editor/components/kit/accordion.vue +0 -68
  478. data/app/frontend/editor/components/kit/checkbox-input.vue +0 -59
  479. data/app/frontend/editor/components/kit/collection-item-input.vue +0 -79
  480. data/app/frontend/editor/components/kit/color-input/core-input.vue +0 -92
  481. data/app/frontend/editor/components/kit/color-input/preset-button.vue +0 -61
  482. data/app/frontend/editor/components/kit/color-input/preset-dropdown.vue +0 -47
  483. data/app/frontend/editor/components/kit/color-input.vue +0 -41
  484. data/app/frontend/editor/components/kit/confirmation-button.vue +0 -65
  485. data/app/frontend/editor/components/kit/copy-paste-button.vue +0 -26
  486. data/app/frontend/editor/components/kit/divider.vue +0 -22
  487. data/app/frontend/editor/components/kit/dropdown.vue +0 -66
  488. data/app/frontend/editor/components/kit/hint.vue +0 -12
  489. data/app/frontend/editor/components/kit/icon-button.vue +0 -24
  490. data/app/frontend/editor/components/kit/icon-input.vue +0 -96
  491. data/app/frontend/editor/components/kit/icon.vue +0 -36
  492. data/app/frontend/editor/components/kit/image-input.vue +0 -124
  493. data/app/frontend/editor/components/kit/index.js +0 -56
  494. data/app/frontend/editor/components/kit/link-input.vue +0 -121
  495. data/app/frontend/editor/components/kit/modal-root.vue +0 -85
  496. data/app/frontend/editor/components/kit/modal.vue +0 -39
  497. data/app/frontend/editor/components/kit/page-icon.vue +0 -21
  498. data/app/frontend/editor/components/kit/pagination/button.vue +0 -35
  499. data/app/frontend/editor/components/kit/pagination/index.vue +0 -116
  500. data/app/frontend/editor/components/kit/rich-text-input/block-button.vue +0 -75
  501. data/app/frontend/editor/components/kit/rich-text-input/extensions/Doc.js +0 -12
  502. data/app/frontend/editor/components/kit/rich-text-input/extensions/LineBreak.js +0 -38
  503. data/app/frontend/editor/components/kit/rich-text-input/extensions/marks/Link.js +0 -57
  504. data/app/frontend/editor/components/kit/rich-text-input/extensions/marks/Superscript.js +0 -43
  505. data/app/frontend/editor/components/kit/rich-text-input/format-buttons.vue +0 -47
  506. data/app/frontend/editor/components/kit/rich-text-input/link-buttons.vue +0 -91
  507. data/app/frontend/editor/components/kit/rich-text-input/list-buttons.vue +0 -29
  508. data/app/frontend/editor/components/kit/rich-text-input/menu-button.vue +0 -22
  509. data/app/frontend/editor/components/kit/rich-text-input/table-button.vue +0 -112
  510. data/app/frontend/editor/components/kit/rich-text-input.vue +0 -187
  511. data/app/frontend/editor/components/kit/search-input.vue +0 -54
  512. data/app/frontend/editor/components/kit/select-input.vue +0 -200
  513. data/app/frontend/editor/components/kit/simple-select.vue +0 -63
  514. data/app/frontend/editor/components/kit/submit-button.vue +0 -117
  515. data/app/frontend/editor/components/kit/tabs.vue +0 -99
  516. data/app/frontend/editor/components/kit/text-input.vue +0 -63
  517. data/app/frontend/editor/components/kit/textarea-input.vue +0 -61
  518. data/app/frontend/editor/components/link-picker/actions.vue +0 -32
  519. data/app/frontend/editor/components/link-picker/email.vue +0 -32
  520. data/app/frontend/editor/components/link-picker/index.vue +0 -97
  521. data/app/frontend/editor/components/link-picker/page.vue +0 -126
  522. data/app/frontend/editor/components/link-picker/url.vue +0 -43
  523. data/app/frontend/editor/components/page/edit.vue +0 -99
  524. data/app/frontend/editor/components/page/form/main.vue +0 -64
  525. data/app/frontend/editor/components/page/form/seo.vue +0 -94
  526. data/app/frontend/editor/components/page/list/actions-button.vue +0 -159
  527. data/app/frontend/editor/components/page/list/index.vue +0 -58
  528. data/app/frontend/editor/components/page/list/list-item.vue +0 -96
  529. data/app/frontend/editor/components/page/new.vue +0 -79
  530. data/app/frontend/editor/components/section-block-pane/index.vue +0 -69
  531. data/app/frontend/editor/components/section-block-pane/setting-list.vue +0 -53
  532. data/app/frontend/editor/components/section-highlighter/bottom-actions.vue +0 -60
  533. data/app/frontend/editor/components/section-highlighter/index.vue +0 -125
  534. data/app/frontend/editor/components/section-highlighter/top-left-actions.vue +0 -78
  535. data/app/frontend/editor/components/section-highlighter/top-right-actions.vue +0 -130
  536. data/app/frontend/editor/components/section-list/add-button.vue +0 -39
  537. data/app/frontend/editor/components/section-list/index.vue +0 -79
  538. data/app/frontend/editor/components/section-list/list-item.vue +0 -60
  539. data/app/frontend/editor/components/section-pane/block-list/index.vue +0 -68
  540. data/app/frontend/editor/components/section-pane/block-list/list-item.vue +0 -74
  541. data/app/frontend/editor/components/section-pane/block-list/new-block-button.vue +0 -80
  542. data/app/frontend/editor/components/section-pane/block-tree/index.vue +0 -63
  543. data/app/frontend/editor/components/section-pane/block-tree/new-nested-block-button.vue +0 -73
  544. data/app/frontend/editor/components/section-pane/block-tree/tree-node.vue +0 -109
  545. data/app/frontend/editor/components/section-pane/index.vue +0 -94
  546. data/app/frontend/editor/components/section-pane/setting-list.vue +0 -50
  547. data/app/frontend/editor/components/sidebar-nav/index.vue +0 -102
  548. data/app/frontend/editor/components/sidebar-nav/link.vue +0 -60
  549. data/app/frontend/editor/components/style-pane/index.vue +0 -48
  550. data/app/frontend/editor/components/theme-section-list/category.vue +0 -47
  551. data/app/frontend/editor/components/theme-section-list/index.vue +0 -27
  552. data/app/frontend/editor/components/theme-section-list/list-item.vue +0 -95
  553. data/app/frontend/editor/design/application.scss +0 -17
  554. data/app/frontend/editor/design/components/buttons.scss +0 -25
  555. data/app/frontend/editor/design/components/modal.scss +0 -49
  556. data/app/frontend/editor/design/components/tooltip.scss +0 -123
  557. data/app/frontend/editor/design/components/tree.scss +0 -6
  558. data/app/frontend/editor/design/helpers.scss +0 -9
  559. data/app/frontend/editor/design/transitions.scss +0 -121
  560. data/app/frontend/editor/layouts/app.vue +0 -42
  561. data/app/frontend/editor/layouts/default.vue +0 -57
  562. data/app/frontend/editor/layouts/slide-pane.vue +0 -87
  563. data/app/frontend/editor/locales/editor.ar.json +0 -265
  564. data/app/frontend/editor/locales/editor.en.json +0 -265
  565. data/app/frontend/editor/locales/editor.es.json +0 -265
  566. data/app/frontend/editor/locales/editor.fr.json +0 -265
  567. data/app/frontend/editor/locales/editor.pt-BR.json +0 -265
  568. data/app/frontend/editor/locales/index.js +0 -23
  569. data/app/frontend/editor/main.js +0 -21
  570. data/app/frontend/editor/misc/__tests__/utils.spec.js +0 -43
  571. data/app/frontend/editor/misc/utils.js +0 -177
  572. data/app/frontend/editor/mixins/error-modal.js +0 -28
  573. data/app/frontend/editor/mixins/focused-input.js +0 -20
  574. data/app/frontend/editor/mixins/global.js +0 -140
  575. data/app/frontend/editor/mixins/grouped-dropdowns.js +0 -17
  576. data/app/frontend/editor/mixins/index.js +0 -1
  577. data/app/frontend/editor/mixins/preview-transformation.js +0 -59
  578. data/app/frontend/editor/plugins/event-bus.js +0 -3
  579. data/app/frontend/editor/plugins/filters.js +0 -7
  580. data/app/frontend/editor/plugins/i18n.js +0 -13
  581. data/app/frontend/editor/plugins/index.js +0 -3
  582. data/app/frontend/editor/plugins/tooltip.js +0 -4
  583. data/app/frontend/editor/router/index.js +0 -41
  584. data/app/frontend/editor/router/routes/base.js +0 -59
  585. data/app/frontend/editor/router/routes/index.js +0 -3
  586. data/app/frontend/editor/router/routes/page.js +0 -30
  587. data/app/frontend/editor/router/routes/section-block.js +0 -29
  588. data/app/frontend/editor/router/routes/section.js +0 -67
  589. data/app/frontend/editor/router/routes/style.js +0 -17
  590. data/app/frontend/editor/services/__tests__/page.spec.js +0 -38
  591. data/app/frontend/editor/services/__tests__/section.spec.js +0 -39
  592. data/app/frontend/editor/services/api.js +0 -40
  593. data/app/frontend/editor/services/block.js +0 -26
  594. data/app/frontend/editor/services/collection-item.js +0 -20
  595. data/app/frontend/editor/services/image.js +0 -26
  596. data/app/frontend/editor/services/index.js +0 -21
  597. data/app/frontend/editor/services/live-preview.js +0 -131
  598. data/app/frontend/editor/services/page.js +0 -107
  599. data/app/frontend/editor/services/section.js +0 -214
  600. data/app/frontend/editor/services/site.js +0 -21
  601. data/app/frontend/editor/services/theme.js +0 -9
  602. data/app/frontend/editor/spec/__mocks__/page.js +0 -434
  603. data/app/frontend/editor/spec/__mocks__/section.js +0 -232
  604. data/app/frontend/editor/spec/__mocks__/services.js +0 -84
  605. data/app/frontend/editor/spec/__mocks__/site.js +0 -95
  606. data/app/frontend/editor/spec/__mocks__/theme.js +0 -518
  607. data/app/frontend/editor/store/__tests__/getters.spec.js +0 -158
  608. data/app/frontend/editor/store/actions/__tests__/page.spec.js +0 -97
  609. data/app/frontend/editor/store/actions/__tests__/section-block.spec.js +0 -105
  610. data/app/frontend/editor/store/actions/__tests__/section.spec.js +0 -62
  611. data/app/frontend/editor/store/actions/index.js +0 -35
  612. data/app/frontend/editor/store/actions/page.js +0 -66
  613. data/app/frontend/editor/store/actions/section-block.js +0 -57
  614. data/app/frontend/editor/store/actions/section.js +0 -75
  615. data/app/frontend/editor/store/actions/site.js +0 -32
  616. data/app/frontend/editor/store/default-state.js +0 -27
  617. data/app/frontend/editor/store/getters.js +0 -113
  618. data/app/frontend/editor/store/index.js +0 -29
  619. data/app/frontend/editor/store/mutations.js +0 -187
  620. data/app/frontend/editor/views/content-pane.vue +0 -109
  621. data/app/frontend/editor/views/page-preview.vue +0 -160
  622. data/app/frontend/editor/views/pages/edit.vue +0 -26
  623. data/app/frontend/editor/views/pages/index.vue +0 -65
  624. data/app/frontend/editor/views/sections/add-pane.vue +0 -23
  625. data/app/frontend/editor/views/sections/list-pane.vue +0 -20
  626. data/app/frontend/editor/views/slide-pane.vue +0 -14
  627. data/app/frontend/editor/views/slide-pane2.vue +0 -14
  628. data/app/frontend/editor/views/style/edit-pane.vue +0 -22
  629. data/app/frontend/entrypoints/admin.js +0 -3
  630. data/app/frontend/entrypoints/admin.scss +0 -5
  631. data/app/frontend/entrypoints/editor.js +0 -8
  632. data/app/frontend/entrypoints/live-preview-client.js +0 -6
  633. data/app/frontend/entrypoints/live-preview-rails-client.js +0 -9
  634. data/app/frontend/live-preview-client/index.js +0 -11
  635. data/app/frontend/live-preview-client/rails.js +0 -217
  636. data/app/helpers/maglev/editor_helper.rb +0 -95
  637. data/app/services/maglev/persist_page.rb +0 -97
  638. data/app/views/layouts/maglev/admin/_header_actions.html.erb +0 -5
  639. data/app/views/layouts/maglev/admin/application.html.erb +0 -26
  640. data/app/views/maglev/admin/sections/previews/show.html.erb +0 -47
  641. data/app/views/maglev/admin/themes/_empty.html.erb +0 -20
  642. data/app/views/maglev/admin/themes/_section_categories.html.erb +0 -9
  643. data/app/views/maglev/admin/themes/_sections.html.erb +0 -54
  644. data/app/views/maglev/admin/themes/show.html.erb +0 -21
  645. data/app/views/maglev/api/_pagination.json.jbuilder +0 -6
  646. data/app/views/maglev/api/assets/_show.json.jbuilder +0 -8
  647. data/app/views/maglev/api/assets/index.json.jbuilder +0 -9
  648. data/app/views/maglev/api/assets/show.json.jbuilder +0 -3
  649. data/app/views/maglev/api/collection_items/_show.json.jbuilder +0 -5
  650. data/app/views/maglev/api/collection_items/index.json.jbuilder +0 -5
  651. data/app/views/maglev/api/collection_items/show.json.jbuilder +0 -7
  652. data/app/views/maglev/api/page_clones/create.json.jbuilder +0 -3
  653. data/app/views/maglev/api/pages/_show.json.jbuilder +0 -23
  654. data/app/views/maglev/api/pages/index.json.jbuilder +0 -18
  655. data/app/views/maglev/api/pages/show.json.jbuilder +0 -3
  656. data/app/views/maglev/api/sites/_show.json.jbuilder +0 -15
  657. data/app/views/maglev/api/sites/show.json.jbuilder +0 -3
  658. data/app/views/maglev/api/themes/_show.json.jbuilder +0 -17
  659. data/app/views/maglev/editor/_header.html.erb +0 -1
  660. data/app/views/maglev/editor/show.html.erb +0 -41
  661. data/app/views/maglev/settings/index.html.erb +0 -11
  662. data/bin/vite +0 -29
  663. data/config/initializers/kaminari.rb +0 -16
  664. data/config/vite.json +0 -17
  665. data/lib/tasks/maglev/vite.rake +0 -70
  666. data/package.json +0 -58
  667. data/postcss.config.cjs +0 -6
  668. data/tailwind.config.js +0 -68
  669. data/vite.config.ts +0 -18
  670. data/yarn.lock +0 -4749
  671. /data/app/{frontend/images → assets/images/maglev}/favicon.svg +0 -0
  672. /data/app/{frontend/images → assets/images/maglev}/logo.svg +0 -0
  673. /data/app/{frontend/live-preview-client → assets/javascripts/maglev/client}/run-scripts.js +0 -0
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ module Uikit
5
+ class IconComponent < ViewComponent::Base
6
+ attr_reader :name, :size, :class_names
7
+
8
+ def initialize(name:, size: '1.25rem', class_names: nil)
9
+ @name = name
10
+ @size = size
11
+ @class_names = class_names
12
+ end
13
+
14
+ def call
15
+ icon_svg = ICONS[name] || raise("Icon '#{name}' not found")
16
+
17
+ # Apply styling and classes to the SVG
18
+ styled_svg = icon_svg.gsub(
19
+ '<svg xmlns="http://www.w3.org/2000/svg" ',
20
+ "<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"#{style}\" class=\"#{final_class_names}\""
21
+ )
22
+
23
+ # rubocop:disable Rails/OutputSafety
24
+ styled_svg.html_safe
25
+ # rubocop:enable Rails/OutputSafety
26
+ end
27
+
28
+ private
29
+
30
+ def style
31
+ "width: #{size}; height: #{size};"
32
+ end
33
+
34
+ def final_class_names
35
+ helpers.class_names(*class_names, 'fill-current')
36
+ end
37
+
38
+ # Centralized icon definitions
39
+ # rubocop:disable Layout/LineLength, Naming/VariableNumber
40
+ ICONS = {
41
+ # Remix Icons
42
+ error_warning: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>',
43
+
44
+ stack: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M20.083 15.2l1.202.721a.5.5 0 0 1 0 .858l-8.77 5.262a1 1 0 0 1-1.03 0l-8.77-5.262a.5.5 0 0 1 0-.858l1.202-.721L12 20.05l8.083-4.85zm0-4.7l1.202.721a.5.5 0 0 1 0 .858L12 17.65l-9.285-5.571a.5.5 0 0 1 0-.858l1.202-.721L12 15.35l8.083-4.85zm-7.569-9.191l8.771 5.262a.5.5 0 0 1 0 .858L12 13L2.715 7.43a.5.5 0 0 1 0-.858l8.771-5.262a1 1 0 0 1 1.03 0zM12 3.332L5.887 7 12 10.668 18.113 7 12 3.332z"/></svg>',
45
+
46
+ checkbox_circle: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-.997-6l7.07-7.071-1.414-1.414-5.656 5.657-2.829-2.829-1.414 1.414L11.003 16z"/></svg>',
47
+
48
+ settings: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M2.213 14.06a9.945 9.945 0 0 1 0-4.12c1.11.13 2.08-.237 2.396-1.001.317-.765-.108-1.71-.986-2.403a9.945 9.945 0 0 1 2.913-2.913c.692.877 1.638 1.303 2.403.986.765-.317 1.132-1.286 1.001-2.396a9.945 9.945 0 0 1 4.12 0c-.13 1.11.237 2.08 1.001 2.396.765.317 1.71-.108 2.403-.986a9.945 9.945 0 0 1 2.913 2.913c-.877.692-1.303 1.638-.986 2.403.317.765 1.286 1.132 2.396 1.001a9.945 9.945 0 0 1 0 4.12c-1.11-.13-2.08.237-2.396 1.001-.317.765.108 1.71.986 2.403a9.945 9.945 0 0 1-2.913 2.913c-.692-.877-1.638-1.303-2.403-.986-.765.317-1.132 1.286-1.001 2.396a9.945 9.945 0 0 1-4.12 0c.13-1.11-.237-2.08-1.001-2.396-.765-.317-1.71.108-2.403.986a9.945 9.945 0 0 1-2.913-2.913c.877-.692 1.303-1.638.986-2.403-.317-.765-1.286-1.132-2.396-1.001zM4 12.21c1.1.305 2.007 1.002 2.457 2.086.449 1.085.3 2.22-.262 3.212.096.102.195.201.297.297.993-.562 2.127-.71 3.212-.262 1.084.45 1.781 1.357 2.086 2.457.14.004.28.004.42 0 .305-1.1 1.002-2.007 2.086-2.457 1.085-.449 2.22-.3 3.212.262.102-.096.201-.195.297-.297-.562-.993-.71-2.127-.262-3.212.45-1.084 1.357-1.781 2.457-2.086.004-.14.004-.28 0-.42-1.1-.305-2.007-1.002-2.457-2.086-.449-1.085-.3-2.22.262-3.212a7.935 7.935 0 0 0-.297-.297c-.993.562-2.127.71-3.212.262C13.212 6.007 12.515 5.1 12.21 4a7.935 7.935 0 0 0-.42 0c-.305 1.1-1.002 2.007-2.086 2.457-1.085.449-2.22.3-3.212-.262-.102.096-.201.195-.297.297.562.993.71 2.127.262 3.212C6.007 10.788 5.1 11.485 4 11.79c-.004.14-.004.28 0 .42zM12 15a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg>',
49
+
50
+ close: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-current"><path fill="none" d="M0 0h24v24H0z"></path><path d="m12 10.586 4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"></path></svg>',
51
+
52
+ clone: '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" class="fill-current"><path d="M3 2a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h3v3a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1h-3V3a1 1 0 0 0-1-1zm15 9.56 2 2v2.88l-2-2zm0-2.12V8h2v3.44zM18 17v-.44l2 2V20h-1.44l-2-2H17a1 1 0 0 0 1-1m-3.56 1 2 2h-2.88l-2-2zm-5 0 2 2H8v-2zM4 16V4h12v12z"></path></svg>',
53
+
54
+ add: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></svg>',
55
+
56
+ more: '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" class="fill-current"><path d="M5 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m14 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m-7 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2"></path></svg>',
57
+
58
+ more_2: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 3c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 14c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-7c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>',
59
+
60
+ file: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8l6-5.997zM5.83 8H9V4.83L5.83 8zM11 4v5a1 1 0 0 1-1 1H5v10h14V4h-8z"/></svg>',
61
+
62
+ file_copy: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8L5 20h10V8H5.003zM9 6h8v10h2V4H9v2z"/></svg>',
63
+
64
+ clipboard: '<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" class="fill-current"><path d="M7 4V2h10v2h3.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.993.993 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4zm0 2H5v14h14V6h-2v2H7zm2-2v2h6V4z"></path></svg>',
65
+
66
+ global: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10m-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.01 8.01 0 0 0 5.648 6.667M10.03 13c.151 2.439.848 4.73 1.97 6.752A15.9 15.9 0 0 0 13.97 13zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.01 8.01 0 0 0 19.938 13M4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.01 8.01 0 0 0 4.062 11m5.969 0h3.938A15.9 15.9 0 0 0 12 4.248 15.9 15.9 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.01 8.01 0 0 0-5.648-6.667"></path></svg>',
67
+
68
+ arrow_down: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="fill-current"><path fill="none" d="M0 0h24v24H0z"></path><path d="m12 13.172 4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z"></path></svg>',
69
+ arrow_left: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M10.8284 12.0007L15.7782 16.9504L14.364 18.3646L8 12.0007L14.364 5.63672L15.7782 7.05093L10.8284 12.0007Z"></path></svg>',
70
+ arrow_right: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M13.1717 12.0007L8.22192 7.05093L9.63614 5.63672L16.0001 12.0007L9.63614 18.3646L8.22192 16.9504L13.1717 12.0007Z"></path></svg>',
71
+
72
+ image: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M4.828 21l-.02.02-.021-.02H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H4.828zM20 15V5H4v14L14 9l6 6zm0 2.828l-6-6L6.828 19H20v-1.172zM8 11a2 2 0 1 1 0-4 2 2 0 0 1 0 4z" fill="#000"/></svg>',
73
+
74
+ delete_bin: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M17 6h5v2h-2v13a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V8H2V6h5V3a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v3zm1 2H6v12h12V8zm-9 3h2v6H9v-6zm4 0h2v6h-2v-6zM9 4v2h6V4H9z"/></svg>',
75
+
76
+ search: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.031 16.617l4.283 4.282-1.415 1.415-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9 9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617zm-2.006-.742A6.977 6.977 0 0 0 18 11c0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7a6.977 6.977 0 0 0 4.875-1.975l.15-.15z"/></svg>',
77
+
78
+ camera: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M9.828 5l-2 2H4v12h16V7h-3.828l-2-2H9.828zM9 3h6l2 2h4a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h4l2-2zm3 15a5.5 5.5 0 1 1 0-11 5.5 5.5 0 0 1 0 11zm0-2a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z"/></svg>',
79
+
80
+ draggable: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8.5 7C9.32843 7 10 6.32843 10 5.5C10 4.67157 9.32843 4 8.5 4C7.67157 4 7 4.67157 7 5.5C7 6.32843 7.67157 7 8.5 7ZM8.5 13.5C9.32843 13.5 10 12.8284 10 12C10 11.1716 9.32843 10.5 8.5 10.5C7.67157 10.5 7 11.1716 7 12C7 12.8284 7.67157 13.5 8.5 13.5ZM10 18.5C10 19.3284 9.32843 20 8.5 20C7.67157 20 7 19.3284 7 18.5C7 17.6716 7.67157 17 8.5 17C9.32843 17 10 17.6716 10 18.5ZM15.5 7C16.3284 7 17 6.32843 17 5.5C17 4.67157 16.3284 4 15.5 4C14.6716 4 14 4.67157 14 5.5C14 6.32843 14.6716 7 15.5 7ZM17 12C17 12.8284 16.3284 13.5 15.5 13.5C14.6716 13.5 14 12.8284 14 12C14 11.1716 14.6716 10.5 15.5 10.5C16.3284 10.5 17 11.1716 17 12ZM15.5 20C16.3284 20 17 19.3284 17 18.5C17 17.6716 16.3284 17 15.5 17C14.6716 17 14 17.6716 14 18.5C14 19.3284 14.6716 20 15.5 20Z"></path></svg>',
81
+
82
+ pencil: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414-1.414-1.414-1.414-1.414 1.414 1.414 1.414zM7.242 21H3v-4.243L16.435 3.322a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414L7.243 21z"/></svg>',
83
+
84
+ archive_stack: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 5H20V3H4V5ZM20 9H4V7H20V9ZM3 11H10V13H14V11H21V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V11ZM16 13V15H8V13H5V19H19V13H16Z"></path></svg>',
85
+
86
+ eraser: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8.58564 8.85449L3.63589 13.8042L8.83021 18.9985L9.99985 18.9978V18.9966H11.1714L14.9496 15.2184L8.58564 8.85449ZM9.99985 7.44027L16.3638 13.8042L19.1922 10.9758L12.8283 4.61185L9.99985 7.44027ZM13.9999 18.9966H20.9999V20.9966H11.9999L8.00229 20.9991L1.51457 14.5113C1.12405 14.1208 1.12405 13.4877 1.51457 13.0971L12.1212 2.49053C12.5117 2.1 13.1449 2.1 13.5354 2.49053L21.3136 10.2687C21.7041 10.6592 21.7041 11.2924 21.3136 11.6829L13.9999 18.9966Z"></path></svg>',
87
+
88
+ external_link: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M10 6V8H5V19H16V14H18V20C18 20.5523 17.5523 21 17 21H4C3.44772 21 3 20.5523 3 20V7C3 6.44772 3.44772 6 4 6H10ZM21 3V11H19L18.9999 6.413L11.2071 14.2071L9.79289 12.7929L17.5849 5H13V3H21Z"></path></svg>',
89
+
90
+ mail: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3ZM20 7.23792L12.0718 14.338L4 7.21594V19H20V7.23792ZM4.51146 5L12.0619 11.662L19.501 5H4.51146Z"></path></svg>',
91
+
92
+ palette: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C17.5222 2 22 5.97778 22 10.8889C22 13.9556 19.5111 16.4444 16.4444 16.4444H14.4778C13.5556 16.4444 12.8111 17.1889 12.8111 18.1111C12.8111 18.5333 12.9778 18.9222 13.2333 19.2111C13.5 19.5111 13.6667 19.9 13.6667 20.3333C13.6667 21.2556 12.9 22 12 22C6.47778 22 2 17.5222 2 12C2 6.47778 6.47778 2 12 2ZM10.8111 18.1111C10.8111 16.0843 12.451 14.4444 14.4778 14.4444H16.4444C18.4065 14.4444 20 12.851 20 10.8889C20 7.1392 16.4677 4 12 4C7.58235 4 4 7.58235 4 12C4 16.19 7.2226 19.6285 11.324 19.9718C10.9948 19.4168 10.8111 18.7761 10.8111 18.1111ZM7.5 12C6.67157 12 6 11.3284 6 10.5C6 9.67157 6.67157 9 7.5 9C8.32843 9 9 9.67157 9 10.5C9 11.3284 8.32843 12 7.5 12ZM16.5 12C15.6716 12 15 11.3284 15 10.5C15 9.67157 15.6716 9 16.5 9C17.3284 9 18 9.67157 18 10.5C18 11.3284 17.3284 12 16.5 12ZM12 9C11.1716 9 10.5 8.32843 10.5 7.5C10.5 6.67157 11.1716 6 12 6C12.8284 6 13.5 6.67157 13.5 7.5C13.5 8.32843 12.8284 9 12 9Z"></path></svg>',
93
+
94
+ check: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M9.9997 15.1709L19.1921 5.97852L20.6063 7.39273L9.9997 17.9993L3.63574 11.6354L5.04996 10.2212L9.9997 15.1709Z"></path></svg>',
95
+
96
+ drop: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3.09723L7.05025 8.04697C4.31658 10.7806 4.31658 15.2128 7.05025 17.9465C9.78392 20.6801 14.2161 20.6801 16.9497 17.9465C19.6834 15.2128 19.6834 10.7806 16.9497 8.04697L12 3.09723ZM12 0.268799L18.364 6.63276C21.8787 10.1475 21.8787 15.846 18.364 19.3607C14.8492 22.8754 9.15076 22.8754 5.63604 19.3607C2.12132 15.846 2.12132 10.1475 5.63604 6.63276L12 0.268799Z"></path></svg>',
97
+
98
+ book: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 18.5V5C3 3.34315 4.34315 2 6 2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22H6.5C4.567 22 3 20.433 3 18.5ZM19 20V17H6.5C5.67157 17 5 17.6716 5 18.5C5 19.3284 5.67157 20 6.5 20H19ZM5 15.3368C5.45463 15.1208 5.9632 15 6.5 15H19V4H6C5.44772 4 5 4.44772 5 5V15.3368Z"></path></svg>',
99
+
100
+ preview: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12.0003 3C17.3924 3 21.8784 6.87976 22.8189 12C21.8784 17.1202 17.3924 21 12.0003 21C6.60812 21 2.12215 17.1202 1.18164 12C2.12215 6.87976 6.60812 3 12.0003 3ZM12.0003 19C16.2359 19 19.8603 16.052 20.7777 12C19.8603 7.94803 16.2359 5 12.0003 5C7.7646 5 4.14022 7.94803 3.22278 12C4.14022 16.052 7.7646 19 12.0003 19ZM12.0003 16.5C9.51498 16.5 7.50026 14.4853 7.50026 12C7.50026 9.51472 9.51498 7.5 12.0003 7.5C14.4855 7.5 16.5003 9.51472 16.5003 12C16.5003 14.4853 14.4855 16.5 12.0003 16.5ZM12.0003 14.5C13.381 14.5 14.5003 13.3807 14.5003 12C14.5003 10.6193 13.381 9.5 12.0003 9.5C10.6196 9.5 9.50026 10.6193 9.50026 12C9.50026 13.3807 10.6196 14.5 12.0003 14.5Z"></path></svg>',
101
+
102
+ # Richtext
103
+
104
+ text_bold: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8 11H12.5C13.8807 11 15 9.88071 15 8.5C15 7.11929 13.8807 6 12.5 6H8V11ZM18 15.5C18 17.9853 15.9853 20 13.5 20H6V4H12.5C14.9853 4 17 6.01472 17 8.5C17 9.70431 16.5269 10.7981 15.7564 11.6058C17.0979 12.3847 18 13.837 18 15.5ZM8 13V18H13.5C14.8807 18 16 16.8807 16 15.5C16 14.1193 14.8807 13 13.5 13H8Z"></path></svg>',
105
+ text_italic: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M15 20H7V18H9.92661L12.0425 6H9V4H17V6H14.0734L11.9575 18H15V20Z"></path></svg>',
106
+ text_underline: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8 3V12C8 14.2091 9.79086 16 12 16C14.2091 16 16 14.2091 16 12V3H18V12C18 15.3137 15.3137 18 12 18C8.68629 18 6 15.3137 6 12V3H8ZM4 20H20V22H4V20Z"></path></svg>',
107
+ text_strikethrough: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M17.1538 14C17.3846 14.5161 17.5 15.0893 17.5 15.7196C17.5 17.0625 16.9762 18.1116 15.9286 18.867C14.8809 19.6223 13.4335 20 11.5862 20C9.94674 20 8.32335 19.6185 6.71592 18.8555V16.6009C8.23538 17.4783 9.7908 17.917 11.3822 17.917C13.9333 17.917 15.2128 17.1846 15.2208 15.7196C15.2208 15.0939 15.0049 14.5598 14.5731 14.1173C14.5339 14.0772 14.4939 14.0381 14.4531 14H3V12H21V14H17.1538ZM13.076 11H7.62908C7.4566 10.8433 7.29616 10.6692 7.14776 10.4778C6.71592 9.92084 6.5 9.24559 6.5 8.45207C6.5 7.21602 6.96583 6.165 7.89749 5.299C8.82916 4.43299 10.2706 4 12.2219 4C13.6934 4 15.1009 4.32808 16.4444 4.98426V7.13591C15.2448 6.44921 13.9293 6.10587 12.4978 6.10587C10.0187 6.10587 8.77917 6.88793 8.77917 8.45207C8.77917 8.87172 8.99709 9.23796 9.43293 9.55079C9.86878 9.86362 10.4066 10.1135 11.0463 10.3004C11.6665 10.4816 12.3431 10.7148 13.076 11H13.076Z"></path></svg>',
108
+ text_superscript: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5.59567 5L10.5 10.9283L15.4043 5H18L11.7978 12.4971L18 19.9943V20H15.4091L10.5 14.0659L5.59092 20H3V19.9943L9.20216 12.4971L3 5H5.59567ZM21.5507 6.5803C21.7042 6.43453 21.8 6.22845 21.8 6C21.8 5.55817 21.4418 5.2 21 5.2C20.5582 5.2 20.2 5.55817 20.2 6C20.2 6.07624 20.2107 6.14999 20.2306 6.21983L19.0765 6.54958C19.0267 6.37497 19 6.1906 19 6C19 4.89543 19.8954 4 21 4C22.1046 4 23 4.89543 23 6C23 6.57273 22.7593 7.08923 22.3735 7.45384L20.7441 9H23V10H19V9L21.5507 6.5803V6.5803Z"></path></svg>',
109
+
110
+ text_unorderd_list: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8 4H21V6H8V4ZM4.5 6.5C3.67157 6.5 3 5.82843 3 5C3 4.17157 3.67157 3.5 4.5 3.5C5.32843 3.5 6 4.17157 6 5C6 5.82843 5.32843 6.5 4.5 6.5ZM4.5 13.5C3.67157 13.5 3 12.8284 3 12C3 11.1716 3.67157 10.5 4.5 10.5C5.32843 10.5 6 11.1716 6 12C6 12.8284 5.32843 13.5 4.5 13.5ZM4.5 20.4C3.67157 20.4 3 19.7284 3 18.9C3 18.0716 3.67157 17.4 4.5 17.4C5.32843 17.4 6 18.0716 6 18.9C6 19.7284 5.32843 20.4 4.5 20.4ZM8 11H21V13H8V11ZM8 18H21V20H8V18Z"></path></svg>',
111
+ text_ordered_list: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M8 4H21V6H8V4ZM5 3V6H6V7H3V6H4V4H3V3H5ZM3 14V11.5H5V11H3V10H6V12.5H4V13H6V14H3ZM5 19.5H3V18.5H5V18H3V17H6V21H3V20H5V19.5ZM8 11H21V13H8V11ZM8 18H21V20H8V18Z"></path></svg>',
112
+
113
+ text_paragraph: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 6V21H10V16C6.68629 16 4 13.3137 4 10C4 6.68629 6.68629 4 10 4H20V6H17V21H15V6H12ZM10 6C7.79086 6 6 7.79086 6 10C6 12.2091 7.79086 14 10 14V6Z"></path></svg>',
114
+ text_heading_2: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4V11H11V4H13V20H11V13H4V20H2V4H4ZM18.5 8C20.5711 8 22.25 9.67893 22.25 11.75C22.25 12.6074 21.9623 13.3976 21.4781 14.0292L21.3302 14.2102L18.0343 18H22V20H15L14.9993 18.444L19.8207 12.8981C20.0881 12.5908 20.25 12.1893 20.25 11.75C20.25 10.7835 19.4665 10 18.5 10C17.5818 10 16.8288 10.7071 16.7558 11.6065L16.75 11.75H14.75C14.75 9.67893 16.4289 8 18.5 8Z"></path></svg>',
115
+ text_heading_3: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M22 8L21.9984 10L19.4934 12.883C21.0823 13.3184 22.25 14.7728 22.25 16.5C22.25 18.5711 20.5711 20.25 18.5 20.25C16.674 20.25 15.1528 18.9449 14.8184 17.2166L16.7821 16.8352C16.9384 17.6413 17.6481 18.25 18.5 18.25C19.4665 18.25 20.25 17.4665 20.25 16.5C20.25 15.5335 19.4665 14.75 18.5 14.75C18.214 14.75 17.944 14.8186 17.7056 14.9403L16.3992 13.3932L19.3484 10H15V8H22ZM4 4V11H11V4H13V20H11V13H4V20H2V4H4Z"></path></svg>',
116
+ text_heading_4: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M13 20H11V13H4V20H2V4H4V11H11V4H13V20ZM22 8V16H23.5V18H22V20H20V18H14.5V16.66L19.5 8H22ZM20 11.133L17.19 16H20V11.133Z"></path></svg>',
117
+ text_code: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3.41436 5.99995L5.70726 3.70706L4.29304 2.29285L0.585938 5.99995L4.29304 9.70706L5.70726 8.29285L3.41436 5.99995ZM9.58594 5.99995L7.29304 3.70706L8.70726 2.29285L12.4144 5.99995L8.70726 9.70706L7.29304 8.29285L9.58594 5.99995ZM14.0002 2.99995H21.0002C21.5524 2.99995 22.0002 3.44767 22.0002 3.99995V20C22.0002 20.5522 21.5524 21 21.0002 21H3.00015C2.44787 21 2.00015 20.5522 2.00015 20V12H4.00015V19H20.0002V4.99995H14.0002V2.99995Z"></path></svg>',
118
+ text_quote: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19.4167 6.67891C20.4469 7.77257 21.0001 9 21.0001 10.9897C21.0001 14.4891 18.5436 17.6263 14.9695 19.1768L14.0768 17.7992C17.4121 15.9946 18.0639 13.6539 18.3245 12.178C17.7875 12.4557 17.0845 12.5533 16.3954 12.4895C14.591 12.3222 13.1689 10.8409 13.1689 9C13.1689 7.067 14.7359 5.5 16.6689 5.5C17.742 5.5 18.7681 5.99045 19.4167 6.67891ZM9.41669 6.67891C10.4469 7.77257 11.0001 9 11.0001 10.9897C11.0001 14.4891 8.54359 17.6263 4.96951 19.1768L4.07682 17.7992C7.41206 15.9946 8.06392 13.6539 8.32447 12.178C7.78747 12.4557 7.08452 12.5533 6.39539 12.4895C4.59102 12.3222 3.16895 10.8409 3.16895 9C3.16895 7.067 4.73595 5.5 6.66895 5.5C7.742 5.5 8.76814 5.99045 9.41669 6.67891Z"></path></svg>',
119
+
120
+ text_link: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M18.3638 15.5355L16.9496 14.1213L18.3638 12.7071C20.3164 10.7545 20.3164 7.58866 18.3638 5.63604C16.4112 3.68341 13.2453 3.68341 11.2927 5.63604L9.87849 7.05025L8.46428 5.63604L9.87849 4.22182C12.6122 1.48815 17.0443 1.48815 19.778 4.22182C22.5117 6.95549 22.5117 11.3876 19.778 14.1213L18.3638 15.5355ZM15.5353 18.364L14.1211 19.7782C11.3875 22.5118 6.95531 22.5118 4.22164 19.7782C1.48797 17.0445 1.48797 12.6123 4.22164 9.87868L5.63585 8.46446L7.05007 9.87868L5.63585 11.2929C3.68323 13.2455 3.68323 16.4113 5.63585 18.364C7.58847 20.3166 10.7543 20.3166 12.7069 18.364L14.1211 16.9497L15.5353 18.364ZM14.8282 7.75736L16.2425 9.17157L9.17139 16.2426L7.75717 14.8284L14.8282 7.75736Z"></path></svg>',
121
+ text_unlink: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M17 17H22V19H19V22H17V17ZM7 7H2V5H5V2H7V7ZM18.364 15.5355L16.9497 14.1213L18.364 12.7071C20.3166 10.7545 20.3166 7.58866 18.364 5.63604C16.4113 3.68342 13.2455 3.68342 11.2929 5.63604L9.87868 7.05025L8.46447 5.63604L9.87868 4.22183C12.6123 1.48816 17.0445 1.48816 19.7782 4.22183C22.5118 6.9555 22.5118 11.3877 19.7782 14.1213L18.364 15.5355ZM15.5355 18.364L14.1213 19.7782C11.3877 22.5118 6.9555 22.5118 4.22183 19.7782C1.48816 17.0445 1.48816 12.6123 4.22183 9.87868L5.63604 8.46447L7.05025 9.87868L5.63604 11.2929C3.68342 13.2455 3.68342 16.4113 5.63604 18.364C7.58866 20.3166 10.7545 20.3166 12.7071 18.364L14.1213 16.9497L15.5355 18.364ZM14.8284 7.75736L16.2426 9.17157L9.17157 16.2426L7.75736 14.8284L14.8284 7.75736Z"></path></svg>',
122
+
123
+ # Devices
124
+
125
+ computer: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M4 16h16V5H4v11zm9 2v2h4v2H7v-2h4v-2H2.992A.998.998 0 0 1 2 16.993V4.007C2 3.451 2.455 3 2.992 3h18.016c.548 0 .992.449.992 1.007v12.986c0 .556-.455 1.007-.992 1.007H13z" fill="#000"/></svg>',
126
+ tablet: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"></path><path d="M6 4v16h12V4zM5 2h14a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1m7 15a1 1 0 1 1 0 2 1 1 0 0 1 0-2"></path></svg>',
127
+ smartphone: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M7 4v16h10V4H7zM6 2h12a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zm6 15a1 1 0 1 1 0 2 1 1 0 0 1 0-2z" fill="#000"/></svg>',
128
+
129
+ # Other icons
130
+ home: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1m-6-2h5V9.157l-6-5.454-6 5.454V19h5v-6h2z"/></svg>',
131
+
132
+ logout: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 22a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v3h-2V4H6v16h12v-2h2v3a1 1 0 0 1-1 1H5zm13-6v-3h-7v-2h7V8l5 4-5 4z"/></svg>',
133
+
134
+ # Spinners
135
+ spinner: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M18.364 5.63604L16.9497 7.05025C15.683 5.7835 13.933 5 12 5C8.13401 5 5 8.13401 5 12C5 15.866 8.13401 19 12 19C15.866 19 19 15.866 19 12H21C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C14.4853 3 16.7353 4.00736 18.364 5.63604Z"></path></svg>'
136
+ }.with_indifferent_access.freeze
137
+ # rubocop:enable Layout/LineLength, Naming/VariableNumber
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,41 @@
1
+ <div class="flex h-full flex-col" data-controller="transition">
2
+ <div class="bg-checkerboard pb-full relative overflow-hidden rounded flex-1" data-action="mouseenter->transition#enter mouseleave->transition#leave">
3
+ <div class="absolute inset-0 h-full w-full rounded">
4
+ <img
5
+ src="<%= image_url %>"
6
+ class="h-full w-full object-contain <%= 'cursor-pointer' if picker_mode? %>"
7
+ <% if picker_mode? %>
8
+ data-controller="dispatcher"
9
+ data-action="click->dispatcher#trigger click->uikit-modal#close:self"
10
+ data-dispatcher-event-name-value="<%= picker_event_name %>"
11
+ data-dispatcher-payload-value="<%= picker_event_payload %>"
12
+ <% end %>
13
+ />
14
+
15
+ <div
16
+ class="flex items-center px-2 absolute bg-black/75 bottom-0 h-12 w-full text-white text-xs cursor-default rounded-b hidden"
17
+ data-transition-target="revealable"
18
+ data-transition-enter="ease-out duration-100"
19
+ data-transition-enter-start="translate-y-4 opacity-0"
20
+ data-transition-enter-end="translate-y-0 opacity-100"
21
+ data-transition-leave="ease-in duration-100"
22
+ data-transition-leave-start="translate-y-0 opacity-100"
23
+ data-transition-leave-end="translate-y-4 opacity-0"
24
+ >
25
+ <%= button_to delete_path,
26
+ method: :delete,
27
+ form_class: 'ml-auto flex items-center',
28
+ class: 'px-1 py-1 bg-white rounded-full flex items-center justify-center text-gray-900 cursor-pointer',
29
+ data: { turbo_confirm: t('maglev.editor.image_library.confirm_destroy'), turbo_frame: 'modal-dialog' } do
30
+ %>
31
+ <%= render Maglev::Uikit::IconComponent.new(name: 'delete_bin', size: '1rem') %>
32
+ <% end %>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ <div class="mt-1 text-xs font-bold text-gray-900 truncate" title="<%= filename %>"><%= filename %></div>
37
+ <div class="mb-1 flex items-center text-xs justify-between text-gray-700">
38
+ <span><% if width_and_height? %><%= width %>x<%= height %><% end %></span>
39
+ <span><% if byte_size.present? %><%= number_to_human_size(byte_size) %><% end %></span>
40
+ </div>
41
+ </div>
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ module Uikit
5
+ module ImageLibrary
6
+ class CardComponent < Maglev::Uikit::BaseComponent
7
+ attr_reader :id, :image_url, :filename, :width, :height, :byte_size, :delete_path, :picker_attributes
8
+
9
+ def initialize(image:, delete_path:, picker_attributes: nil)
10
+ @id = image[:id]
11
+ @image_url = image[:image_url]
12
+ @filename = image[:filename]
13
+ @width = image[:width]
14
+ @height = image[:height]
15
+ @byte_size = image[:byte_size]
16
+ @delete_path = delete_path
17
+ @picker_attributes = picker_attributes
18
+ end
19
+
20
+ def picker_mode?
21
+ picker_attributes.present? && picker_attributes[:picker].present?
22
+ end
23
+
24
+ def picker_event_payload
25
+ {
26
+ source: picker_attributes[:source],
27
+ image: picker_event_image_payload
28
+ }.to_json
29
+ end
30
+
31
+ def picker_event_image_payload
32
+ {
33
+ id: id,
34
+ filename: filename,
35
+ url: image_url,
36
+ width: width,
37
+ height: height,
38
+ byte_size: byte_size
39
+ }
40
+ end
41
+
42
+ def picker_event_name
43
+ "image-selected-#{picker_attributes[:source]}"
44
+ end
45
+
46
+ def width_and_height?
47
+ width.present? && height.present?
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ <div class="grid grid-cols-4 gap-4">
2
+ <% images.each do |image| %>
3
+ <div class="col-span-1 h-58">
4
+ <%= image %>
5
+ </div>
6
+ <% end %>
7
+ </div>
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ module Uikit
5
+ module ImageLibrary
6
+ class ListComponent < Maglev::Uikit::BaseComponent
7
+ renders_many :images, 'Maglev::Uikit::ImageLibrary::CardComponent'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ <div
2
+ class="flex items-center gap-4"
3
+ data-controller="uikit-image-library-uploader"
4
+ data-uikit-image-library-uploader-maxsize-value="<%= maxsize %>"
5
+ data-uikit-image-library-uploader-create-path-value="<%= create_path %>"
6
+ data-uikit-image-library-uploader-refresh-path-value="<%= refresh_path %>"
7
+ data-uikit-image-library-uploader-too-big-error-message-value="<%= too_big_error_message %>"
8
+ >
9
+ <button
10
+ class="<%= button_class_names(color: :primary, size: :medium, class: 'group/button') %>"
11
+ data-action="click->uikit-image-library-uploader#openFileDialog"
12
+ data-uikit-image-library-uploader-target="button"
13
+ >
14
+ <span class="group-disabled/button:hidden">
15
+ <%= t('maglev.editor.image_library.uploader.upload_button.default') %>
16
+ </span>
17
+ <span class="group-disabled/button:block hidden">
18
+ <%= t('maglev.editor.image_library.uploader.upload_button.in_progress') %>
19
+ </span>
20
+ </button>
21
+
22
+ <input
23
+ type="file"
24
+ accept="image/*"
25
+ multiple
26
+ class="hidden"
27
+ data-uikit-image-library-uploader-target="fileInput"
28
+ data-action="change->uikit-image-library-uploader#onFilesSelected"
29
+ />
30
+ </div>
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ module Uikit
5
+ module ImageLibrary
6
+ class UploaderComponent < Maglev::Uikit::BaseComponent
7
+ attr_reader :create_path, :refresh_path, :maxsize
8
+
9
+ def initialize(create_path:, refresh_path:, maxsize: 2_048_144)
10
+ @create_path = create_path
11
+ @refresh_path = refresh_path
12
+ @maxsize = maxsize
13
+ end
14
+
15
+ def success_message
16
+ t('maglev.editor.image_library.uploader.upload_button.success')
17
+ end
18
+
19
+ def error_message
20
+ t('maglev.editor.image_library.uploader.upload_button.fail')
21
+ end
22
+
23
+ def too_big_error_message
24
+ t('maglev.editor.image_library.uploader.wrong_files', limit: number_to_human_size(maxsize))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,74 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+ import { FetchRequest } from '@rails/request.js'
3
+
4
+ export default class extends Controller {
5
+ static targets = ['button', 'fileInput']
6
+ static values = {
7
+ createPath: String,
8
+ refreshPath: String,
9
+ maxsize: Number,
10
+ tooBigErrorMessage: String,
11
+ }
12
+
13
+ connect() {
14
+ console.log('UploaderController connected')
15
+ }
16
+
17
+ openFileDialog() {
18
+ this.fileInputTarget.click()
19
+ }
20
+
21
+ onFilesSelected() {
22
+ const allowedFiles = this.allowedFiles()
23
+ if (allowedFiles) {
24
+ this.buttonTarget.disabled = true
25
+ this.uploadFiles(allowedFiles).then(() => {
26
+ this.reloadFrameTag()
27
+ })
28
+ .catch((error) => {
29
+ console.error(error)
30
+ alert('Network/Server connection error')
31
+ }).finally(() => {
32
+ this.buttonTarget.disabled = false
33
+ })
34
+ } else {
35
+ alert(this.tooBigErrorMessageValue)
36
+ }
37
+ }
38
+
39
+ uploadFiles(allowedFiles) {
40
+ return Promise.all(allowedFiles.map((file) => this.uploadSingleFile({ file }, allowedFiles.length)))
41
+ }
42
+
43
+ uploadSingleFile(attributes, numberOfAssets) {
44
+ const formData = new FormData()
45
+ formData.append('number_of_assets', numberOfAssets)
46
+ Object.entries(attributes).forEach(([key, value]) =>
47
+ formData.append(`asset[${key}]`, value)
48
+ )
49
+
50
+ const request = new FetchRequest('post', this.createPathValue, { body: formData })
51
+ return request.perform()
52
+ }
53
+
54
+ allowedFiles() {
55
+ const allowedFiles = []
56
+ const files = this.fileInputTarget.files
57
+ for (var i = 0; i < files.length; i++) {
58
+ const file = files[i]
59
+ if (file && file.size < this.maxsizeValue) {
60
+ allowedFiles.push(file)
61
+ } else return false
62
+ }
63
+ return allowedFiles
64
+ }
65
+
66
+ reloadFrameTag() {
67
+ console.log('reloadFrameTag', this.refreshPathValue)
68
+ const frame = document.querySelector(`turbo-frame#modal-dialog`)
69
+ if (frame) {
70
+ frame.src = this.refreshPathValue
71
+ frame.reload()
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,7 @@
1
+ <div <%= tag.attributes(class: wrapper_classes) %>>
2
+ <div class="absolute top-0 left-0 w-full justify-center flex opacity-0 group-hover/button:opacity-100 transition-opacity duration-200">
3
+ <%= link_to link_url, data: link_data, class: "h-7 w-7 flex items-center justify-center rounded-full focus:outline-none transition-colors duration-200 border-4 border-white bg-gray-500 text-gray-200 hover:bg-gray-900 hover:text-gray-100" do %>
4
+ <%= render Maglev::Uikit::IconComponent.new(name: "add", size: "1.15rem") %>
5
+ <% end %>
6
+ </div>
7
+ </div>
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ module Uikit
5
+ module List
6
+ class InsertButtonComponent < Maglev::Uikit::BaseComponent
7
+ attr_reader :link, :index
8
+
9
+ def initialize(link:, index: nil)
10
+ @link = link
11
+ @index = index
12
+ end
13
+
14
+ def link_url
15
+ link[:url]
16
+ end
17
+
18
+ def link_data
19
+ link[:data] || {}
20
+ end
21
+
22
+ def color_class
23
+ [
24
+ 'bg-gray-500/20',
25
+ 'bg-red-500/20',
26
+ 'bg-blue-500/20',
27
+ 'bg-green-500/20',
28
+ 'bg-yellow-500/20'
29
+ ][index]
30
+ end
31
+
32
+ def wrapper_classes(...)
33
+ class_variants(
34
+ base: 'relative w-full h-7 group/button z-10 -mb-5 -mt-5 group-[.is-dragging]:hidden'
35
+ ).render(...)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ <%= tag.div(
2
+ class: 'flex flex-col gap-3 group',
3
+ data: {
4
+ controller: sortable? ? 'sortable' : nil,
5
+ 'sortable-scope-value': sortable? ? sortable_scope : nil,
6
+ **(html_options[:data] || {})
7
+ }.compact,
8
+ ) do %>
9
+ <% items.each do |item| %>
10
+ <%= item %>
11
+ <% end %>
12
+
13
+ <%= form_with url: sort_form_path, method: :put, data: sort_form_data, class: 'invisible' do %>
14
+ <!-- Empty form -->
15
+ <%= hidden_field_tag :scope, sortable_scope if sortable_scope.present? %>
16
+ <% end if sortable? %>
17
+ <% end %>
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ module Uikit
5
+ module List
6
+ class ListComponent < Maglev::Uikit::BaseComponent
7
+ renders_many :items, types: {
8
+ content: Maglev::Uikit::List::ListItemComponent,
9
+ insert_button: Maglev::Uikit::List::InsertButtonComponent
10
+ }
11
+
12
+ attr_reader :sort_form, :sortable_scope, :html_options
13
+
14
+ def initialize(sort_form: nil, sortable_scope: nil, html_options: {})
15
+ @sort_form = sort_form
16
+ @sortable_scope = sortable_scope
17
+ @html_options = html_options
18
+ end
19
+
20
+ def sort_form_path
21
+ sort_form&.fetch(:path)
22
+ end
23
+
24
+ def sort_form_data
25
+ { sortable_target: 'sortableForm' }.merge(sort_form[:data] || {})
26
+ end
27
+
28
+ def sortable?
29
+ sort_form_path.present?
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,47 @@
1
+ <%= tag.div(data: { sortable_target: sortable_target, item_id: id, item_index: index }) do %>
2
+ <%= tag.div(class: wrapper_classes) do %>
3
+
4
+ <%= tag.div(class: 'flex items-center cursor-move', data: { sortable_target: sortable_handle }) do %>
5
+ <%= render Maglev::Uikit::IconComponent.new(name: "draggable") %>
6
+ <% end if handle? %>
7
+
8
+ <% item_body = capture do %>
9
+ <% if image? %>
10
+ <div class="h-8 w-8 bg-gray-400">
11
+ <%= image %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <% if big_image? %>
16
+ <%= big_image %>
17
+ <% end %>
18
+
19
+ <div class="flex flex-col overflow-hidden">
20
+ <% if pre_title? %>
21
+ <div class="text-gray-500 text-xs"><%= pre_title %></div>
22
+ <div class="text-gray-800 truncate"><%= title %></div>
23
+ <% else %>
24
+ <div class="truncate"><%= title %></div>
25
+ <% end %>
26
+ </div>
27
+ <% end %>
28
+
29
+ <% if link? %>
30
+ <%= link_to link_url, data: link_data, class: content_classes do %>
31
+ <%= item_body %>
32
+ <% end %>
33
+ <% else %>
34
+ <div class="<%= content_classes %>">
35
+ <%= item_body %>
36
+ </div>
37
+ <% end %>
38
+
39
+ <% if action? %>
40
+ <div class="relative ml-auto flex items-center shrink-0 min-h-full gap-2">
41
+ <%= action %>
42
+ </div>
43
+ <% end %>
44
+ <% end %>
45
+
46
+ <%= content if content? %>
47
+ <% end %>