maglevcms 3.0.0.beta3 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -53
- data/Rakefile +3 -1
- data/app/assets/builds/maglev/tailwind.css +424 -84
- data/app/assets/config/maglev_manifest.js +3 -2
- data/app/assets/javascripts/maglev/client/dom-operations.js +5 -5
- data/app/assets/javascripts/maglev/client/iframe-decorator.js +24 -0
- data/app/assets/javascripts/maglev/client/incoming-messages.js +13 -3
- data/app/assets/javascripts/maglev/client/index.js +3 -2
- data/app/assets/javascripts/maglev/client/utils.js +22 -0
- data/app/assets/javascripts/maglev/editor/controllers/app/forms/section_form_controller.js +4 -3
- data/app/assets/javascripts/maglev/editor/controllers/app/forms/style_form_controller.js +2 -1
- data/app/assets/javascripts/maglev/editor/controllers/app/page_preview_controller.js +96 -5
- data/app/assets/javascripts/maglev/editor/controllers/app/preview_notification_center_controller.js +105 -23
- data/app/assets/javascripts/maglev/editor/controllers/app/setting_controller.js +3 -2
- data/app/assets/javascripts/maglev/editor/controllers/shared/copy_to_clipboard_controller.js +2 -1
- data/app/assets/javascripts/maglev/editor/controllers/utils.js +22 -0
- data/app/assets/javascripts/maglev/editor/index.js +2 -1
- data/app/assets/javascripts/maglev/editor/patches/turbo_stream_patch.js +3 -3
- data/app/assets/stylesheets/maglev/tailwind.css.erb +8 -1
- data/app/components/maglev/content/link.rb +1 -1
- data/app/components/maglev/editor/settings/link/link_component.rb +7 -1
- data/app/components/maglev/section_component.rb +11 -1
- data/app/components/maglev/uikit/app_layout/sidebar/link_component.html.erb +1 -1
- data/app/components/maglev/uikit/app_layout/sidebar/link_component.rb +35 -5
- data/app/components/maglev/uikit/app_layout/sidebar_component.html.erb +3 -4
- data/app/components/maglev/uikit/app_layout/topbar_component.html.erb +1 -1
- data/app/components/maglev/uikit/app_layout/topbar_component.rb +1 -1
- data/app/components/maglev/uikit/button_group_component/button_group_component.html.erb +5 -0
- data/app/components/maglev/uikit/button_group_component.rb +70 -0
- data/app/components/maglev/uikit/device_toggler_component.rb +10 -1
- data/app/components/maglev/uikit/dropdown_component/dropdown_component.html.erb +2 -2
- data/app/components/maglev/uikit/dropdown_component.rb +6 -1
- data/app/components/maglev/uikit/form/color_field_component.html.erb +1 -1
- data/app/components/maglev/uikit/form/combobox_component.html.erb +1 -0
- data/app/components/maglev/uikit/form/link_component.rb +5 -1
- data/app/components/maglev/uikit/form/richtext_controller.js +5 -4
- data/app/components/maglev/uikit/form/search_form_component.html.erb +1 -0
- data/app/components/maglev/uikit/icon_component.rb +3 -0
- data/app/components/maglev/uikit/image_library/uploader_controller.js +3 -2
- data/app/components/maglev/uikit/list/list_item_component.html.erb +36 -19
- data/app/components/maglev/uikit/list/list_item_component.rb +19 -5
- data/app/components/maglev/uikit/locale_switcher_component/locale_switcher_component.html.erb +6 -10
- data/app/components/maglev/uikit/menu_dropdown_component/menu_dropdown_component.html.erb +6 -2
- data/app/components/maglev/uikit/menu_dropdown_component.rb +244 -7
- data/app/components/maglev/uikit/page_actions_dropdown_component/page_actions_dropdown_component.html.erb +39 -46
- data/app/components/maglev/uikit/pagination_component/pagination_component.html.erb +9 -12
- data/app/components/maglev/uikit/pagination_component.rb +6 -1
- data/app/components/maglev/uikit/section_toolbar/bottom_component.html.erb +1 -1
- data/app/components/maglev/uikit/tabs_component/tabs_component.html.erb +7 -4
- data/app/components/maglev/uikit/tabs_component.rb +23 -4
- data/app/components/maglev/uikit/well/simple_well_component.html.erb +15 -0
- data/app/components/maglev/uikit/well/simple_well_component.rb +13 -0
- data/app/controllers/concerns/maglev/editor/preview_urls_concern.rb +32 -0
- data/app/controllers/concerns/maglev/editor/turbo_concern.rb +29 -0
- data/app/controllers/concerns/maglev/flash_i18n_concern.rb +1 -0
- data/app/controllers/maglev/application_controller.rb +1 -1
- data/app/controllers/maglev/assets/active_storage_proxy_controller.rb +2 -1
- data/app/controllers/maglev/editor/assets_controller.rb +1 -1
- data/app/controllers/maglev/editor/base_controller.rb +6 -32
- data/app/controllers/maglev/editor/pages/clone_controller.rb +22 -0
- data/app/controllers/maglev/editor/pages/discard_draft_controller.rb +17 -0
- data/app/controllers/maglev/editor/pages_controller.rb +26 -7
- data/app/controllers/maglev/editor/section_blocks_controller.rb +13 -9
- data/app/controllers/maglev/editor/sections_controller.rb +26 -7
- data/app/controllers/maglev/published_page_preview_controller.rb +4 -0
- data/app/helpers/maglev/application_helper.rb +6 -6
- data/app/helpers/maglev/editor/section_blocks_helper.rb +2 -2
- data/app/models/maglev/page/publishable_concern.rb +69 -0
- data/app/models/maglev/page.rb +2 -13
- data/app/models/maglev/section/block.rb +4 -0
- data/app/models/maglev/section/content_concern.rb +3 -1
- data/app/models/maglev/section.rb +21 -1
- data/app/models/maglev/sections_content_store.rb +1 -3
- data/app/services/concerns/maglev/content/helpers_concern.rb +5 -8
- data/app/services/maglev/app_container.rb +4 -2
- data/app/services/maglev/discard_page_draft_service.rb +45 -0
- data/app/services/maglev/fetch_section_screenshot_url.rb +12 -1
- data/app/services/maglev/has_unpublished_changes.rb +21 -0
- data/app/services/maglev/publish_service.rb +15 -2
- data/app/views/layouts/maglev/editor/_sidebar.html.erb +6 -1
- data/app/views/layouts/maglev/editor/application.html.erb +5 -0
- data/app/views/layouts/maglev/editor/topbar/_page_info.html.erb +1 -1
- data/app/views/layouts/maglev/editor/topbar/_publish_button.html.erb +32 -10
- data/app/views/maglev/editor/assets/_list.html.erb +2 -1
- data/app/views/maglev/editor/assets/index.html.erb +1 -0
- data/app/views/maglev/editor/home/index.html.erb +1 -1
- data/app/views/maglev/editor/links/edit/_email.html.erb +1 -1
- data/app/views/maglev/editor/links/edit/_url.html.erb +1 -1
- data/app/views/maglev/editor/pages/_list.html.erb +25 -21
- data/app/views/maglev/editor/pages/_preview.html.erb +6 -6
- data/app/views/maglev/editor/pages/_preview_empty_message.html.erb +13 -10
- data/app/views/maglev/editor/pages/discard_draft/create.turbo_stream.erb +16 -0
- data/app/views/maglev/editor/pages/index.html.erb +8 -1
- data/app/views/maglev/editor/section_blocks/_form.html.erb +5 -13
- data/app/views/maglev/editor/section_blocks/_form_with_tabs.html.erb +15 -0
- data/app/views/maglev/editor/section_blocks/_new.html.erb +1 -1
- data/app/views/maglev/editor/section_blocks/edit.html.erb +2 -2
- data/app/views/maglev/editor/section_blocks/index/_list.html.erb +2 -2
- data/app/views/maglev/editor/section_blocks/index/_tree.html.erb +1 -1
- data/app/views/maglev/editor/section_blocks/update.turbo_stream.erb +1 -1
- data/app/views/maglev/editor/sections/_form.html.erb +6 -20
- data/app/views/maglev/editor/sections/_form_with_tabs.html.erb +21 -0
- data/app/views/maglev/editor/sections/_list.html.erb +3 -3
- data/app/views/maglev/editor/sections/edit.html.erb +4 -4
- data/app/views/maglev/editor/sections/index.html.erb +1 -1
- data/app/views/maglev/editor/sections/new.html.erb +19 -2
- data/app/views/maglev/editor/sections/theme/_empty_list.html.erb +3 -0
- data/app/views/maglev/editor/sections/theme/_list.html.erb +35 -0
- data/app/views/maglev/editor/sections/theme/_screenshot_placeholder.html.erb +6 -0
- data/app/views/maglev/editor/sections/theme/_search.html.erb +22 -0
- data/app/views/maglev/editor/sections/update.turbo_stream.erb +1 -1
- data/app/views/maglev/editor/shared/_button_label.html.erb +4 -4
- data/app/views/maglev/editor/style/edit.html.erb +1 -0
- data/config/editor_importmap.rb +13 -13
- data/config/locales/editor.ar.yml +12 -4
- data/config/locales/editor.en.yml +31 -23
- data/config/locales/editor.es.yml +12 -4
- data/config/locales/editor.fr.yml +12 -4
- data/config/locales/editor.pt-BR.yml +12 -4
- data/config/routes/maglev/assets.rb +4 -0
- data/config/routes/maglev/editor.rb +38 -0
- data/config/routes/maglev/preview.rb +8 -0
- data/config/routes/maglev/public_preview.rb +6 -0
- data/config/routes.rb +8 -47
- data/db/migrate/20211013210954_translate_section_content.rb +1 -0
- data/db/migrate/20260114112058_add_published_payload_to_pages.rb +14 -0
- data/exe/tailwind-cli +1 -1
- data/lib/generators/maglev/install_generator.rb +9 -7
- data/lib/generators/maglev/templates/install/config/initializers/maglev.rb +10 -3
- data/lib/maglev/active_storage/serving_blob.rb +29 -0
- data/lib/maglev/active_storage.rb +2 -0
- data/lib/maglev/config.rb +22 -3
- data/lib/maglev/engine.rb +14 -10
- data/lib/maglev/version.rb +1 -1
- data/lib/maglev.rb +18 -3
- data/lib/tasks/db_test_all.rake +290 -0
- metadata +46 -19
- data/app/controllers/maglev/editor/page_clone_controller.rb +0 -20
- data/app/views/maglev/editor/sections/_theme_list.html.erb +0 -32
- /data/vendor/javascript/{@floating-ui--core.js → maglev/@floating-ui--core.js} +0 -0
- /data/vendor/javascript/{@floating-ui--dom.js → maglev/@floating-ui--dom.js} +0 -0
- /data/vendor/javascript/{@floating-ui--utils--dom.js → maglev/@floating-ui--utils--dom.js} +0 -0
- /data/vendor/javascript/{@floating-ui--utils.js → maglev/@floating-ui--utils.js} +0 -0
- /data/vendor/javascript/{@hotwired--stimulus.js → maglev/@hotwired--stimulus.js} +0 -0
- /data/vendor/javascript/{@hotwired--turbo-rails.js → maglev/@hotwired--turbo-rails.js} +0 -0
- /data/vendor/javascript/{@hotwired--turbo.js → maglev/@hotwired--turbo.js} +0 -0
- /data/vendor/javascript/{@rails--actioncable--src.js → maglev/@rails--actioncable--src.js} +0 -0
- /data/vendor/javascript/{@rails--request.js.js → maglev/@rails--request.js.js} +0 -0
- /data/vendor/javascript/{@shopify--draggable.js → maglev/@shopify--draggable.js} +0 -0
- /data/vendor/javascript/{el-transition.js → maglev/el-transition.js} +0 -0
- /data/vendor/javascript/{stimulus-use.js → maglev/stimulus-use.js} +0 -0
- /data/vendor/javascript/{tiptap.bundle.js → maglev/tiptap.bundle.js} +0 -0
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
import { StreamActions } from '@hotwired/turbo'
|
|
3
3
|
import TurboDelayedStreams from 'maglev-patches/turbo_delayed_streams'
|
|
4
|
-
import { generateRequestId } from 'maglev-controllers/utils'
|
|
4
|
+
import { generateRequestId, log } from 'maglev-controllers/utils'
|
|
5
5
|
|
|
6
6
|
// Custom stream actions
|
|
7
7
|
StreamActions.console_log = function() {
|
|
8
8
|
const message = this.getAttribute("message")
|
|
9
|
-
|
|
9
|
+
log(message)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
StreamActions.dispatch_event = function() {
|
|
13
13
|
const type = this.getAttribute("type")
|
|
14
14
|
const payload = this.getAttribute("payload")
|
|
15
|
-
|
|
15
|
+
log('dispatchEvent', type, payload, `dispatcher:${type}`)
|
|
16
16
|
const event = new CustomEvent(`dispatcher:${type}`, { detail: JSON.parse(payload) })
|
|
17
17
|
window.dispatchEvent(event)
|
|
18
18
|
}
|
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
--color-editor-primary: var(--editor-color-primary);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/* Empty-state overlay in #root: visible when the preview Stimulus shell has .is-empty */
|
|
12
|
+
@custom-variant editor-preview-empty (body:has([data-controller~="editor-page-preview"].is-empty) &);
|
|
13
|
+
|
|
11
14
|
@source "<%= Maglev::Engine.root.join('app') %>";
|
|
12
15
|
@source "<%= Maglev::Engine.root.join('lib') %>";
|
|
16
|
+
@source "<%= Maglev::Engine.root.join('spec/components/previews/maglev/uikit') %>";
|
|
13
17
|
|
|
14
18
|
<% Maglev.config.tailwindcss_folders.each do |folder| %>
|
|
15
19
|
@source "<%= folder %>";
|
|
@@ -28,6 +32,10 @@
|
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
@layer base {
|
|
35
|
+
.turbo-progress-bar {
|
|
36
|
+
background-color: var(--editor-color-primary) !important;
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
/* Tiptap / ProseMirror */
|
|
32
40
|
.ProseMirror {
|
|
33
41
|
@apply block py-2 px-3 rounded bg-gray-100 text-gray-800 focus:outline-none focus:ring focus:ring-inset focus:ring-2 focus:ring-editor-primary/50 placeholder-gray-500;
|
|
@@ -143,7 +151,6 @@
|
|
|
143
151
|
td,
|
|
144
152
|
th {
|
|
145
153
|
min-width: 1em;
|
|
146
|
-
// border: 2px solid $color-grey;
|
|
147
154
|
@apply border-2;
|
|
148
155
|
@apply border-solid;
|
|
149
156
|
padding: 3px 5px;
|
|
@@ -6,12 +6,18 @@ module Maglev
|
|
|
6
6
|
module Link
|
|
7
7
|
class LinkComponent < Maglev::Editor::Settings::BaseComponent
|
|
8
8
|
def edit_link_path
|
|
9
|
-
fetch_path(:edit_link_path, { value: value, input_name: input_name })
|
|
9
|
+
fetch_path(:edit_link_path, { value: value || default_value, input_name: input_name })
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def after_initialize
|
|
13
13
|
@value = value&.with_indifferent_access
|
|
14
14
|
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def default_value
|
|
19
|
+
{ link_type: 'url' }
|
|
20
|
+
end
|
|
15
21
|
end
|
|
16
22
|
end
|
|
17
23
|
end
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# NOTE: this class is too long (but not too complex),
|
|
4
|
+
# we need to move it along with the PageComponent and BlockComponent
|
|
5
|
+
# to a separate folder (content?)
|
|
6
|
+
|
|
7
|
+
# rubocop:disable Metrics/ClassLength
|
|
3
8
|
module Maglev
|
|
4
9
|
class SectionComponent < BaseComponent
|
|
5
10
|
include TagHelper
|
|
@@ -31,7 +36,7 @@ module Maglev
|
|
|
31
36
|
end
|
|
32
37
|
|
|
33
38
|
def lock_version
|
|
34
|
-
@lock_version ||=
|
|
39
|
+
@lock_version ||= lock_source&.lock_version || '0'
|
|
35
40
|
end
|
|
36
41
|
|
|
37
42
|
def dom_data
|
|
@@ -63,6 +68,10 @@ module Maglev
|
|
|
63
68
|
|
|
64
69
|
private
|
|
65
70
|
|
|
71
|
+
def lock_source
|
|
72
|
+
definition&.site_scoped? ? site : page
|
|
73
|
+
end
|
|
74
|
+
|
|
66
75
|
def build_block_list
|
|
67
76
|
build_blocks(attributes[:blocks])
|
|
68
77
|
end
|
|
@@ -131,3 +140,4 @@ module Maglev
|
|
|
131
140
|
end
|
|
132
141
|
end
|
|
133
142
|
end
|
|
143
|
+
# rubocop:enable Metrics/ClassLength
|
|
@@ -5,12 +5,24 @@ module Maglev
|
|
|
5
5
|
module AppLayout
|
|
6
6
|
module Sidebar
|
|
7
7
|
class LinkComponent < Maglev::Uikit::BaseComponent
|
|
8
|
-
|
|
8
|
+
LINK_BASE_CLASSES = [
|
|
9
|
+
'relative flex w-full min-h-11 items-center justify-center rounded py-3',
|
|
10
|
+
'outline-none transition-colors duration-200',
|
|
11
|
+
'focus-visible:ring-2 focus-visible:ring-editor-primary/50',
|
|
12
|
+
'focus-visible:ring-offset-2 focus-visible:ring-offset-white'
|
|
13
|
+
].join(' ')
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
LINK_ACTIVE_CLASSES = 'bg-gray-100 text-editor-primary hover:bg-gray-100'
|
|
16
|
+
|
|
17
|
+
LINK_INACTIVE_CLASSES = 'text-black hover:bg-gray-100'
|
|
18
|
+
|
|
19
|
+
attr_reader :path, :icon, :icon_size, :active, :data, :label
|
|
20
|
+
|
|
21
|
+
def initialize(path:, icon:, active: false, label: nil, options: {})
|
|
11
22
|
@path = path
|
|
12
23
|
@active = active
|
|
13
24
|
@icon = icon
|
|
25
|
+
@label = label
|
|
14
26
|
@icon_size = options[:icon_size] || '1.5rem'
|
|
15
27
|
@position = options[:position] || :top
|
|
16
28
|
@data = options[:data]
|
|
@@ -24,15 +36,33 @@ module Maglev
|
|
|
24
36
|
@position == :top
|
|
25
37
|
end
|
|
26
38
|
|
|
39
|
+
def link_html_options
|
|
40
|
+
{
|
|
41
|
+
class: link_classes(active: active?),
|
|
42
|
+
data: data,
|
|
43
|
+
title: label.presence,
|
|
44
|
+
aria: link_aria_attributes
|
|
45
|
+
}.compact
|
|
46
|
+
end
|
|
47
|
+
|
|
27
48
|
def link_classes(...)
|
|
28
49
|
class_variants(
|
|
29
|
-
base:
|
|
50
|
+
base: LINK_BASE_CLASSES,
|
|
30
51
|
variants: {
|
|
31
|
-
active:
|
|
32
|
-
'!active':
|
|
52
|
+
active: LINK_ACTIVE_CLASSES,
|
|
53
|
+
'!active': LINK_INACTIVE_CLASSES
|
|
33
54
|
}
|
|
34
55
|
).render(...)
|
|
35
56
|
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def link_aria_attributes
|
|
61
|
+
aria = {}
|
|
62
|
+
aria[:label] = label.presence
|
|
63
|
+
aria[:current] = 'page' if active?
|
|
64
|
+
aria.compact.presence
|
|
65
|
+
end
|
|
36
66
|
end
|
|
37
67
|
end
|
|
38
68
|
end
|
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
id="app-layout-sidebar"
|
|
3
3
|
class="w-16 flex-shrink-0 flex content-center h-full border-r border-gray-200 relative z-20 bg-white"
|
|
4
4
|
>
|
|
5
|
-
<nav class="w-16 flex
|
|
6
|
-
<ol class="
|
|
5
|
+
<nav class="flex h-full w-16 flex-col justify-between py-2">
|
|
6
|
+
<ol class="flex flex-col gap-1 px-2">
|
|
7
7
|
<% links.each do |link| %>
|
|
8
8
|
<%= link if link.top? %>
|
|
9
9
|
<% end %>
|
|
10
10
|
</ol>
|
|
11
11
|
|
|
12
|
-
<ol class="
|
|
13
|
-
<li></li>
|
|
12
|
+
<ol class="flex flex-col gap-1 px-2">
|
|
14
13
|
<% links.each do |link| %>
|
|
15
14
|
<%= link unless link.top? %>
|
|
16
15
|
<% end %>
|
|
@@ -5,7 +5,7 @@ module Maglev
|
|
|
5
5
|
module AppLayout
|
|
6
6
|
class TopbarComponent < ViewComponent::Base
|
|
7
7
|
renders_one :logo, 'Maglev::Uikit::AppLayout::Topbar::LogoComponent'
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
renders_one :page_info
|
|
10
10
|
renders_one :actions
|
|
11
11
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Maglev
|
|
4
|
+
module Uikit
|
|
5
|
+
class ButtonGroupComponent < Maglev::Uikit::BaseComponent
|
|
6
|
+
renders_many :buttons
|
|
7
|
+
|
|
8
|
+
attr_reader :color, :size
|
|
9
|
+
|
|
10
|
+
def initialize(color: nil, size: nil)
|
|
11
|
+
@color = color || :primary
|
|
12
|
+
@size = size || :medium
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# rubocop:disable Metrics/MethodLength
|
|
16
|
+
def button_classes
|
|
17
|
+
class_variants(
|
|
18
|
+
base: %(
|
|
19
|
+
inline-flex items-center justify-center cursor-pointer
|
|
20
|
+
group-[.is-success]/form:bg-green-500/95 group-[.is-success]/form:hover:bg-green-500/100
|
|
21
|
+
group-[.is-success]/form:disabled:bg-green-500/75
|
|
22
|
+
group-[.is-error]/form:bg-red-500/95 group-[.is-error]/form:hover:bg-red-500/100
|
|
23
|
+
group-[.is-error]/form:disabled:bg-red-500/75
|
|
24
|
+
),
|
|
25
|
+
variants: {
|
|
26
|
+
size: {
|
|
27
|
+
medium: 'inline-flex items-center justify-center px-4 h-10'
|
|
28
|
+
},
|
|
29
|
+
color: {
|
|
30
|
+
primary: 'text-white bg-editor-primary hover:bg-editor-primary/90 disabled:bg-editor-primary/75',
|
|
31
|
+
secondary: 'text-gray-800 hover:bg-gray-100'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
).render(color: color, size: size)
|
|
35
|
+
end
|
|
36
|
+
# rubocop:enable Metrics/MethodLength
|
|
37
|
+
|
|
38
|
+
# rubocop:disable Metrics/MethodLength
|
|
39
|
+
def wrapper_classes(**args)
|
|
40
|
+
class_variants(
|
|
41
|
+
base: %(
|
|
42
|
+
inline-flex items-center transition-colors duration-200 h-full
|
|
43
|
+
[.is-success]:bg-green-500/95 [.is-success]:hover:bg-green-500/100
|
|
44
|
+
[.is-success]:disabled:bg-green-500/75
|
|
45
|
+
[.is-error]:bg-red-500/95 [.is-error]:hover:bg-red-500/100
|
|
46
|
+
[.is-error]:disabled:bg-red-500/75
|
|
47
|
+
),
|
|
48
|
+
variants: {
|
|
49
|
+
color: {
|
|
50
|
+
primary: 'text-white bg-editor-primary hover:bg-editor-primary/90 has-[:disabled]:bg-editor-primary/75',
|
|
51
|
+
secondary: 'text-gray-800 hover:bg-gray-100'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
).render(color: color, **args)
|
|
55
|
+
end
|
|
56
|
+
# rubocop:enable Metrics/MethodLength
|
|
57
|
+
|
|
58
|
+
def wrapped_button_classes(**args)
|
|
59
|
+
class_variants(
|
|
60
|
+
base: 'cursor-pointer',
|
|
61
|
+
variants: {
|
|
62
|
+
size: {
|
|
63
|
+
medium: 'inline-flex items-center justify-center px-4 h-10'
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
).render(size: size, **args)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -5,13 +5,22 @@ module Maglev
|
|
|
5
5
|
class DeviceTogglerComponent < Maglev::Uikit::BaseComponent
|
|
6
6
|
def toggler_classes(...)
|
|
7
7
|
class_variants(
|
|
8
|
-
base:
|
|
8
|
+
base: base_classes,
|
|
9
9
|
variants: {
|
|
10
10
|
active: active_classes
|
|
11
11
|
}
|
|
12
12
|
).render(...)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def base_classes
|
|
16
|
+
[
|
|
17
|
+
'cursor-pointer hover:bg-gray-100 h-10 w-10 flex items-center justify-center rounded',
|
|
18
|
+
'outline-none transition-colors duration-200',
|
|
19
|
+
'focus-visible:ring-2 focus-visible:ring-editor-primary/50',
|
|
20
|
+
'focus-visible:ring-offset-2 focus-visible:ring-offset-white'
|
|
21
|
+
].join(' ').freeze
|
|
22
|
+
end
|
|
23
|
+
|
|
15
24
|
def active_classes
|
|
16
25
|
'bg-gray-100'
|
|
17
26
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<%= tag.div(
|
|
2
|
-
class:
|
|
2
|
+
class: wrapper_classes,
|
|
3
3
|
data: {
|
|
4
4
|
controller: 'uikit-dropdown',
|
|
5
5
|
'uikit-dropdown-placement-value': placement
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<%= trigger %>
|
|
9
9
|
|
|
10
10
|
<div
|
|
11
|
-
class="hidden z-50 opacity-0 scale-95 shadow-lg rounded
|
|
11
|
+
class="hidden z-50 opacity-0 scale-95 shadow-lg rounded text-sm bg-white w-max fixed"
|
|
12
12
|
data-aria-orientation="vertical"
|
|
13
13
|
data-aria-labelledby="dropdown-button"
|
|
14
14
|
data-uikit-dropdown-target="content"
|
|
@@ -7,9 +7,14 @@ module Maglev
|
|
|
7
7
|
|
|
8
8
|
attr_reader :placement
|
|
9
9
|
|
|
10
|
-
def initialize(placement: 'bottom-start')
|
|
10
|
+
def initialize(placement: 'bottom-start', wrapper_classes: nil)
|
|
11
|
+
@wrapper_classes = wrapper_classes
|
|
11
12
|
@placement = placement
|
|
12
13
|
end
|
|
14
|
+
|
|
15
|
+
def wrapper_classes
|
|
16
|
+
helpers.class_names('relative', @wrapper_classes)
|
|
17
|
+
end
|
|
13
18
|
end
|
|
14
19
|
end
|
|
15
20
|
end
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
placeholder: placeholder || t('maglev.uikit.form.combobox.placeholder'),
|
|
34
34
|
value: selected_label,
|
|
35
35
|
aria: { controls: 'options', expanded: 'false' },
|
|
36
|
+
autocomplete: 'off',
|
|
36
37
|
data: {
|
|
37
38
|
'uikit-form-combobox-target' => 'input',
|
|
38
39
|
'uikit-dropdown-target' => 'button',
|
|
@@ -59,7 +59,7 @@ module Maglev
|
|
|
59
59
|
|
|
60
60
|
def self.link_type_component(input_name:, value:, path:)
|
|
61
61
|
# Default to url if the link type is not found (shouldn't happen)
|
|
62
|
-
klass = link_type_klasses_map.fetch(value[:link_type]
|
|
62
|
+
klass = link_type_klasses_map.fetch(value[:link_type]&.to_sym, default_link_type_klass)
|
|
63
63
|
|
|
64
64
|
return unless klass
|
|
65
65
|
|
|
@@ -74,6 +74,10 @@ module Maglev
|
|
|
74
74
|
static_page: Maglev::Uikit::Form::Link::StaticPageLinkComponent
|
|
75
75
|
}
|
|
76
76
|
end
|
|
77
|
+
|
|
78
|
+
def self.default_link_type_klass
|
|
79
|
+
Maglev::Uikit::Form::Link::UrlLinkComponent
|
|
80
|
+
end
|
|
77
81
|
end
|
|
78
82
|
end
|
|
79
83
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
|
2
2
|
import { Editor, Document, Text, Paragraph, Heading, Blockquote, CodeBlock, History, Bold, Italic, Underline, Strike, Superscript, HardBreak, Link, ListItem, BulletList, OrderedList } from 'tiptap'
|
|
3
|
+
import { log } from 'maglev-controllers/utils'
|
|
3
4
|
|
|
4
5
|
const MaglevLink = Link.extend({
|
|
5
6
|
addAttributes() {
|
|
@@ -205,11 +206,11 @@ export default class extends Controller {
|
|
|
205
206
|
}
|
|
206
207
|
|
|
207
208
|
openLinkModal(event) {
|
|
208
|
-
|
|
209
|
+
log('toggleLink', event)
|
|
209
210
|
const url = new URL(this.editLinkPathValue, window.location.origin)
|
|
210
211
|
const link = this.editor.getAttributes('link')
|
|
211
212
|
|
|
212
|
-
|
|
213
|
+
log('toggleLink,build link from', link)
|
|
213
214
|
|
|
214
215
|
url.searchParams.set('input_name', this.inputNameValue)
|
|
215
216
|
url.searchParams.set('link[href]', link.href ?? '')
|
|
@@ -230,8 +231,8 @@ export default class extends Controller {
|
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
setLink(event) {
|
|
233
|
-
const link = JSON.parse(event.detail)
|
|
234
|
-
|
|
234
|
+
const link = typeof event.detail === 'string' ? JSON.parse(event.detail) : event.detail
|
|
235
|
+
log('setLink, link=', link)
|
|
235
236
|
this.editor.commands.setLink({
|
|
236
237
|
href: link.href,
|
|
237
238
|
target: link.open_new_window ? '_blank' : '',
|
|
@@ -68,6 +68,7 @@ module Maglev
|
|
|
68
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
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
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
|
+
arrow_right_long: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M1.99974 13.0001L1.9996 11.0002L18.1715 11.0002L14.2218 7.05044L15.636 5.63623L22 12.0002L15.636 18.3642L14.2218 16.9499L18.1716 13.0002L1.99974 13.0001Z"></path></svg>',
|
|
71
72
|
|
|
72
73
|
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
|
|
|
@@ -131,6 +132,8 @@ module Maglev
|
|
|
131
132
|
|
|
132
133
|
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
|
|
|
135
|
+
history: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12H4C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C9.25022 4 6.82447 5.38734 5.38451 7.50024L8 7.5V9.5H2V3.5H4L3.99989 5.99918C5.82434 3.57075 8.72873 2 12 2ZM13 7L12.9998 11.585L16.2426 14.8284L14.8284 16.2426L10.9998 12.413L11 7H13Z"></path></svg>',
|
|
136
|
+
|
|
134
137
|
# Spinners
|
|
135
138
|
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
139
|
}.with_indifferent_access.freeze
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Controller } from '@hotwired/stimulus'
|
|
2
2
|
import { FetchRequest } from '@rails/request.js'
|
|
3
|
+
import { log } from 'maglev-controllers/utils'
|
|
3
4
|
|
|
4
5
|
export default class extends Controller {
|
|
5
6
|
static targets = ['button', 'fileInput']
|
|
@@ -11,7 +12,7 @@ export default class extends Controller {
|
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
connect() {
|
|
14
|
-
|
|
15
|
+
log('UploaderController connected')
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
openFileDialog() {
|
|
@@ -64,7 +65,7 @@ export default class extends Controller {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
reloadFrameTag() {
|
|
67
|
-
|
|
68
|
+
log('reloadFrameTag', this.refreshPathValue)
|
|
68
69
|
const frame = document.querySelector(`turbo-frame#modal-dialog`)
|
|
69
70
|
if (frame) {
|
|
70
71
|
frame.src = this.refreshPathValue
|
|
@@ -1,29 +1,48 @@
|
|
|
1
1
|
<%= tag.div(data: { sortable_target: sortable_target, item_id: id, item_index: index }) do %>
|
|
2
|
-
<%=
|
|
2
|
+
<%= content_tag(wrapper_tag_name.to_sym, class: wrapper_classes) do %>
|
|
3
|
+
<%= content if content? %>
|
|
3
4
|
|
|
4
5
|
<%= tag.div(class: 'flex items-center cursor-move', data: { sortable_target: sortable_handle }) do %>
|
|
5
6
|
<%= render Maglev::Uikit::IconComponent.new(name: "draggable") %>
|
|
6
7
|
<% end if handle? %>
|
|
7
8
|
|
|
8
9
|
<% item_body = capture do %>
|
|
9
|
-
<% if
|
|
10
|
-
<div class="
|
|
11
|
-
|
|
10
|
+
<% if icon? %>
|
|
11
|
+
<div class="grid grid-cols-[auto_1fr_auto] flex flex-1 items-center">
|
|
12
|
+
<div class="mr-2">
|
|
13
|
+
<%= icon %>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="text-gray-800 truncate"><%= title %></div>
|
|
16
|
+
<% if sub_title? %>
|
|
17
|
+
<div class="col-start-2 text-gray-500 text-xs"><%= sub_title %></div>
|
|
18
|
+
<% end %>
|
|
12
19
|
</div>
|
|
13
|
-
<%
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
<% else %>
|
|
21
|
+
<% if image? %>
|
|
22
|
+
<div class="h-8 w-8 bg-gray-400">
|
|
23
|
+
<%= image %>
|
|
24
|
+
</div>
|
|
25
|
+
<% end %>
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
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>
|
|
27
|
+
<% if big_image? %>
|
|
28
|
+
<%= big_image %>
|
|
25
29
|
<% end %>
|
|
26
|
-
|
|
30
|
+
|
|
31
|
+
<div class="flex flex-col overflow-hidden">
|
|
32
|
+
<% if pre_title? %>
|
|
33
|
+
<div class="text-gray-500 text-xs"><%= pre_title %></div>
|
|
34
|
+
<div class="text-gray-800 truncate"><%= title %></div>
|
|
35
|
+
<% if sub_title? %>
|
|
36
|
+
<div class="text-gray-500 text-xs"><%= sub_title %></div>
|
|
37
|
+
<% end %>
|
|
38
|
+
<% else %>
|
|
39
|
+
<div class="truncate"><%= title %></div>
|
|
40
|
+
<% if sub_title? %>
|
|
41
|
+
<div class="text-gray-500 text-xs"><%= sub_title %></div>
|
|
42
|
+
<% end %>
|
|
43
|
+
<% end %>
|
|
44
|
+
</div>
|
|
45
|
+
<% end %>
|
|
27
46
|
<% end %>
|
|
28
47
|
|
|
29
48
|
<% if link? %>
|
|
@@ -41,7 +60,5 @@
|
|
|
41
60
|
<%= action %>
|
|
42
61
|
</div>
|
|
43
62
|
<% end %>
|
|
44
|
-
<% end %>
|
|
45
|
-
|
|
46
|
-
<%= content if content? %>
|
|
63
|
+
<% end %>
|
|
47
64
|
<% end %>
|
|
@@ -7,16 +7,20 @@ module Maglev
|
|
|
7
7
|
renders_one :handle
|
|
8
8
|
renders_one :image
|
|
9
9
|
renders_one :big_image
|
|
10
|
+
renders_one :icon
|
|
10
11
|
renders_one :pre_title
|
|
12
|
+
renders_one :sub_title
|
|
11
13
|
renders_one :title
|
|
12
14
|
renders_one :action
|
|
13
15
|
|
|
14
|
-
attr_reader :link, :index, :options
|
|
16
|
+
attr_reader :link, :index, :options, :variant, :wrapper_tag_name
|
|
15
17
|
|
|
16
18
|
def initialize(id: nil, link: nil, options: {})
|
|
17
19
|
@id = id
|
|
18
20
|
@link = link
|
|
21
|
+
@variant = options.fetch(:variant, :filled).to_sym
|
|
19
22
|
@custom_wrapper_classes = options[:wrapper_classes]
|
|
23
|
+
@wrapper_tag_name = options[:wrapper_tag] || :div
|
|
20
24
|
@index = options[:index]
|
|
21
25
|
@options = options
|
|
22
26
|
end
|
|
@@ -37,18 +41,28 @@ module Maglev
|
|
|
37
41
|
link[:data] || {}
|
|
38
42
|
end
|
|
39
43
|
|
|
44
|
+
# rubocop:disable Metrics/MethodLength
|
|
40
45
|
def wrapper_classes
|
|
41
46
|
class_variants(
|
|
42
|
-
base: '
|
|
43
|
-
|
|
47
|
+
base: 'rounded-md flex text-gray-800',
|
|
48
|
+
variants: {
|
|
49
|
+
variant: {
|
|
50
|
+
filled: 'bg-gray-100',
|
|
51
|
+
ghost: 'hover:bg-gray-50 transition-colors duration-200'
|
|
52
|
+
},
|
|
53
|
+
padding: { default: 'p-2', medium: 'p-3' }
|
|
54
|
+
},
|
|
55
|
+
default: { variant: :filled, padding: :default }
|
|
56
|
+
).render(variant: variant, padding: big_image? ? :medium : :default, class: @custom_wrapper_classes)
|
|
44
57
|
end
|
|
58
|
+
# rubocop:enable Metrics/MethodLength
|
|
45
59
|
|
|
46
60
|
def content_classes
|
|
47
61
|
class_variants(
|
|
48
|
-
base: 'flex flex-1
|
|
62
|
+
base: 'flex flex-1 gap-3 overflow-hidden',
|
|
49
63
|
variants: {
|
|
50
64
|
disposition: {
|
|
51
|
-
row: 'flex-row items-center',
|
|
65
|
+
row: 'flex-row items-center px-2',
|
|
52
66
|
col: 'flex-col'
|
|
53
67
|
}
|
|
54
68
|
},
|
data/app/components/maglev/uikit/locale_switcher_component/locale_switcher_component.html.erb
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
<%= render(Maglev::Uikit::MenuDropdownComponent.new) do |dropdown| %>
|
|
2
2
|
<% dropdown.with_trigger do %>
|
|
3
|
-
|
|
4
|
-
class="flex-1 h-full w-full px-6 hover:bg-gray-100 transition-colors duration-200 flex items-center focus:outline-none focus:none cursor-pointer space-x-2"
|
|
5
|
-
data-action="click->uikit-dropdown#toggle"
|
|
6
|
-
data-uikit-dropdown-target="button">
|
|
3
|
+
<%= tag.button class: helpers.maglev_button_classes(color: :secondary, class: 'space-x-2'), data: { action: 'click->uikit-dropdown#toggle', 'uikit-dropdown-target': 'button' } do %>
|
|
7
4
|
<%= render Maglev::Uikit::IconComponent.new(name: 'global') %>
|
|
8
5
|
<span class="whitespace-nowrap">
|
|
9
6
|
<%= current_locale_label %>
|
|
10
7
|
</span>
|
|
11
8
|
<%= render Maglev::Uikit::IconComponent.new(name: 'arrow_down') %>
|
|
12
|
-
|
|
9
|
+
<% end %>
|
|
13
10
|
<% end %>
|
|
14
11
|
|
|
15
12
|
<% locales.each do |locale| %>
|
|
16
|
-
<% dropdown.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<% end %>
|
|
13
|
+
<% dropdown.with_item_link_to(locale[:path], data: locale[:data_attributes]) do |menu_item| %>
|
|
14
|
+
<% menu_item.with_label_content(locale[:label]) %>
|
|
15
|
+
<% menu_item.with_icon_content('check') if locale[:value] == current_locale %>
|
|
16
|
+
<% end %>
|
|
21
17
|
<% end %>
|
|
22
18
|
<% end %>
|