From 84174ad689b17b75cb1f0df4d5a77ba9f1f4152d Mon Sep 17 00:00:00 2001 From: Sascha Karnatz <122262394+sascha-karnatz@users.noreply.github.com> Date: Wed, 25 Oct 2023 15:26:35 +0200 Subject: [PATCH 1/3] Update select styling Use the same styling for selects as for Select2 - components. This will be a graceful fallback, if the Select2 component can't be rendered. --- app/assets/stylesheets/alchemy/elements.scss | 33 +++----------------- app/assets/stylesheets/alchemy/forms.scss | 17 +++------- app/assets/stylesheets/alchemy/selects.scss | 29 +++++++++++++---- app/assets/stylesheets/alchemy/tables.scss | 4 --- 4 files changed, 33 insertions(+), 50 deletions(-) diff --git a/app/assets/stylesheets/alchemy/elements.scss b/app/assets/stylesheets/alchemy/elements.scss index 61a7cf2dba..b3de6d8031 100644 --- a/app/assets/stylesheets/alchemy/elements.scss +++ b/app/assets/stylesheets/alchemy/elements.scss @@ -827,40 +827,17 @@ select.long { margin-bottom: 2 * $default-margin; } + select, .select2-container { width: 100%; } - &.display_inline .select2-container { - width: 170px; - } - } - - select.ingredient-editor-select { - border-radius: $default-border-radius; - background: white; - border: 1px solid $button-border-color; - font-size: $default-font-size; - height: 21px; - line-height: 21px; - padding: 2px; - - optgroup { - color: gray; - font-style: normal; - font-weight: bold; - text-indent: 8px; - - option { - text-indent: 24px; + &.display_inline { + select, + .select2-container { + width: 170px; } } - - option { - padding-top: 2px; - padding-bottom: 2px; - color: black; - } } &.picture { diff --git a/app/assets/stylesheets/alchemy/forms.scss b/app/assets/stylesheets/alchemy/forms.scss index 962210b8d9..3feb0c5b7b 100644 --- a/app/assets/stylesheets/alchemy/forms.scss +++ b/app/assets/stylesheets/alchemy/forms.scss @@ -29,6 +29,7 @@ form { > input[type="email"], > input[type="password"], > textarea, + > select, > .select2-container, > .autocomplete_tag_list, > .tinymce_container, @@ -38,6 +39,7 @@ form { float: right; } + .input > select, .input > .select2-container { width: 100%; } @@ -53,6 +55,7 @@ form { line-height: 16px; } + select, .select2-container { margin: 4px 0; } @@ -128,10 +131,11 @@ form { width: $form-field-addon-width; position: absolute; bottom: 2 * $default-padding; + --select-background-image: none; select { width: 100%; - padding: 0 2px; + padding: 0 6px; text-align: center; } @@ -250,17 +254,6 @@ form { } } -// styles for link overlay selects -.window_form { - td.checkbox { - text-align: left; - } - - .select2-container { - width: 100%; - } -} - .input-column > label { display: block; margin-top: $default-margin + 1; diff --git a/app/assets/stylesheets/alchemy/selects.scss b/app/assets/stylesheets/alchemy/selects.scss index eb54c6da5c..3ebfe69e1d 100644 --- a/app/assets/stylesheets/alchemy/selects.scss +++ b/app/assets/stylesheets/alchemy/selects.scss @@ -5,22 +5,37 @@ select { $background-color: $form-field-background-color, $hover-color: $form-field-background-color, $hover-border-color: darken($default-border-color, 10%), - $padding: 0 2 * $default-padding, + $padding: 0.4em 26px 0.4em 0.6em, $border: 1px solid $default-border-color, $box-shadow: none, $color: $text-color, $margin: 0 ); height: $form-field-height; - padding: 0.4em 0.6em; max-width: 100%; width: auto; font-weight: normal; vertical-align: middle; - &.alchemy_selectbox.medium { + background-image: var( + --select-background-image, + url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{$icon-color}' style='opacity: #{$addon-icon-opacity}' viewBox='0 0 320 512'%3E%3Cpath d='M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z'/%3E%3C/svg%3E") + ); + background-position: right 0.75rem center; + background-repeat: no-repeat; + background-size: 0.75rem; + + &.tiny { + padding-right: 0.6em; + } + + &.medium { width: $medium-select-box-width; } + + &.large { + width: $large-select-box-width; + } } .select2-container { @@ -53,12 +68,14 @@ select { @extend .fas; background-image: none; opacity: $addon-icon-opacity; + font-size: 14px; + line-height: 1; &:before { content: fa-content($fa-var-caret-down); position: absolute; - top: 50%; - left: 50%; + top: calc(50% - 2px); + left: calc(50% + 2px); transform: translate(-50%, -50%); } } @@ -242,8 +259,8 @@ select { } } -.window_form, #filter_bar { + select, .select2-container { width: 100%; } diff --git a/app/assets/stylesheets/alchemy/tables.scss b/app/assets/stylesheets/alchemy/tables.scss index a5965d0e73..3f54c69eac 100644 --- a/app/assets/stylesheets/alchemy/tables.scss +++ b/app/assets/stylesheets/alchemy/tables.scss @@ -174,10 +174,6 @@ td.count { padding-right: 16px; } -table.window_form { - width: 100%; -} - .list .login_status { width: 16px; } From 61409fd6fb6607bf991586607ef16efe7343a2c5 Mon Sep 17 00:00:00 2001 From: Sascha Karnatz <122262394+sascha-karnatz@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:09:00 +0200 Subject: [PATCH 2/3] Add Select web component Bind the Select2 configuration with a web component to prevent initialization problems. The current solution does not work on Safari, but it will fallback to the default browser behavior. --- app/javascript/alchemy_admin.js | 3 +- .../alchemy_admin/components/select.js | 12 ++++++ app/javascript/alchemy_admin/gui.js | 1 - app/javascript/alchemy_admin/select_box.js | 11 ------ .../admin/attachments/archive_overlay.js.erb | 1 - .../alchemy/admin/elements/_form.html.erb | 2 +- app/views/alchemy/admin/elements/new.html.erb | 2 +- .../admin/ingredients/_file_fields.html.erb | 4 +- .../ingredients/_picture_fields.html.erb | 6 +-- .../admin/ingredients/_video_fields.html.erb | 2 +- .../alchemy/admin/languages/_form.html.erb | 4 +- app/views/alchemy/admin/nodes/_form.html.erb | 2 +- .../alchemy/admin/pages/_anchor_link.html.erb | 2 +- .../pages/_create_language_form.html.erb | 4 +- .../admin/pages/_external_link.html.erb | 2 +- .../alchemy/admin/pages/_file_link.html.erb | 4 +- .../admin/pages/_internal_link.html.erb | 2 +- .../admin/pages/_new_page_form.html.erb | 2 +- .../admin/pages/_page_layout_filter.html.erb | 3 +- app/views/alchemy/admin/pages/edit.html.erb | 5 +-- app/views/alchemy/admin/pages/new.html.erb | 2 +- .../partials/_language_tree_select.html.erb | 3 +- .../admin/partials/_site_select.html.erb | 2 +- .../admin/pictures/archive_overlay.js.erb | 2 +- .../alchemy/admin/resources/_filter.html.erb | 2 +- .../alchemy/admin/resources/_form.html.erb | 4 +- .../alchemy/admin/styleguide/index.html.erb | 2 +- .../ingredients/_select_editor.html.erb | 3 +- app/views/layouts/alchemy/admin.html.erb | 2 +- .../alchemy_admin/components/select.spec.js | 38 +++++++++++++++++++ .../alchemy/ingredients/select_editor_spec.rb | 2 +- 31 files changed, 87 insertions(+), 49 deletions(-) create mode 100644 app/javascript/alchemy_admin/components/select.js delete mode 100644 app/javascript/alchemy_admin/select_box.js create mode 100644 spec/javascript/alchemy_admin/components/select.spec.js diff --git a/app/javascript/alchemy_admin.js b/app/javascript/alchemy_admin.js index 59750c4166..8161f6bbea 100644 --- a/app/javascript/alchemy_admin.js +++ b/app/javascript/alchemy_admin.js @@ -13,7 +13,6 @@ import Initializer from "alchemy_admin/initializer" import pictureSelector from "alchemy_admin/picture_selector" import pleaseWaitOverlay from "alchemy_admin/please_wait_overlay" import Sitemap from "alchemy_admin/sitemap" -import SelectBox from "alchemy_admin/select_box" import Spinner from "alchemy_admin/spinner" import PagePublicationFields from "alchemy_admin/page_publication_fields" @@ -25,6 +24,7 @@ import "alchemy_admin/components/char_counter" import "alchemy_admin/components/datepicker" import "alchemy_admin/components/overlay" import "alchemy_admin/components/page_select" +import "alchemy_admin/components/select" import "alchemy_admin/components/spinner" import "alchemy_admin/components/tinymce" import "alchemy_admin/components/tooltip" @@ -51,7 +51,6 @@ Object.assign(Alchemy, { IngredientAnchorLink, pictureSelector, pleaseWaitOverlay, - SelectBox, Sitemap, Spinner, PagePublicationFields diff --git a/app/javascript/alchemy_admin/components/select.js b/app/javascript/alchemy_admin/components/select.js new file mode 100644 index 0000000000..d9db935b55 --- /dev/null +++ b/app/javascript/alchemy_admin/components/select.js @@ -0,0 +1,12 @@ +class Select extends HTMLSelectElement { + connectedCallback() { + this.classList.add("alchemy_selectbox") + + $(this).select2({ + minimumResultsForSearch: 7, + dropdownAutoWidth: true + }) + } +} + +customElements.define("alchemy-select", Select, { extends: "select" }) diff --git a/app/javascript/alchemy_admin/gui.js b/app/javascript/alchemy_admin/gui.js index 7566298e49..64c2504f9b 100644 --- a/app/javascript/alchemy_admin/gui.js +++ b/app/javascript/alchemy_admin/gui.js @@ -1,7 +1,6 @@ import TagsAutocomplete from "alchemy_admin/tags_autocomplete" function init(scope) { - Alchemy.SelectBox(scope) Alchemy.Buttons.observe(scope) if (!scope) { Alchemy.watchForDialogs() diff --git a/app/javascript/alchemy_admin/select_box.js b/app/javascript/alchemy_admin/select_box.js deleted file mode 100644 index 021000e8cc..0000000000 --- a/app/javascript/alchemy_admin/select_box.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Initializes all select tag with .alchemy_selectbox class as select2 instance - * Pass a jQuery scope to only init a subset of selectboxes. - * @param scope - */ -export default function SelectBox(scope) { - $("select.alchemy_selectbox", scope).select2({ - minimumResultsForSearch: 7, - dropdownAutoWidth: true - }) -} diff --git a/app/views/alchemy/admin/attachments/archive_overlay.js.erb b/app/views/alchemy/admin/attachments/archive_overlay.js.erb index 0890e636cb..22a0e85f32 100644 --- a/app/views/alchemy/admin/attachments/archive_overlay.js.erb +++ b/app/views/alchemy/admin/attachments/archive_overlay.js.erb @@ -1,6 +1,5 @@ (function() { var dialog = Alchemy.currentDialog(); dialog.dialog_body.html('<%= j render("archive_overlay") %>'); - Alchemy.SelectBox('#filter_bar'); Alchemy.ListFilter(dialog.dialog_body); })(); diff --git a/app/views/alchemy/admin/elements/_form.html.erb b/app/views/alchemy/admin/elements/_form.html.erb index 3579183734..5fc2e26d9c 100644 --- a/app/views/alchemy/admin/elements/_form.html.erb +++ b/app/views/alchemy/admin/elements/_form.html.erb @@ -10,7 +10,7 @@ collection: elements_for_select(@elements), prompt: Alchemy.t(:select_element), selected: (@elements.first if @elements.count == 1), - input_html: {class: 'alchemy_selectbox', autofocus: true, disabled: @elements.count == 1} %> + input_html: {is: 'alchemy-select', autofocus: true, disabled: @elements.count == 1} %> <% if @elements.count == 1 %> <%= form.hidden_field :name, value: @elements.first[:name] %> <% end %> diff --git a/app/views/alchemy/admin/elements/new.html.erb b/app/views/alchemy/admin/elements/new.html.erb index 3ca385ba05..c17875722f 100644 --- a/app/views/alchemy/admin/elements/new.html.erb +++ b/app/views/alchemy/admin/elements/new.html.erb @@ -15,7 +15,7 @@ <%= select_tag 'paste_from_clipboard', clipboard_select_tag_options(@clipboard_items), - class: 'alchemy_selectbox' %> + is: 'alchemy-select' %> <%= f.submit Alchemy.t(:paste) %> <% end %> diff --git a/app/views/alchemy/admin/ingredients/_file_fields.html.erb b/app/views/alchemy/admin/ingredients/_file_fields.html.erb index ab4a675bfa..58b2bfae26 100644 --- a/app/views/alchemy/admin/ingredients/_file_fields.html.erb +++ b/app/views/alchemy/admin/ingredients/_file_fields.html.erb @@ -6,7 +6,7 @@ <%= f.input :css_class, collection: css_classes, include_blank: Alchemy.t('None'), - input_html: {class: 'alchemy_selectbox'} %> + input_html: {is: 'alchemy-select'} %> <%- else -%> <%= f.input :css_class, label: Alchemy.t(:position_in_text), @@ -14,5 +14,5 @@ [Alchemy.t(:above), "no_float"], [Alchemy.t(:left), "left"], [Alchemy.t(:right), "right"] - ], include_blank: Alchemy.t('Layout default'), input_html: {class: 'alchemy_selectbox'} %> + ], include_blank: Alchemy.t('Layout default'), input_html: {is: 'alchemy-select'} %> <%- end -%> diff --git a/app/views/alchemy/admin/ingredients/_picture_fields.html.erb b/app/views/alchemy/admin/ingredients/_picture_fields.html.erb index f0d826e4a1..7823ad75fe 100644 --- a/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +++ b/app/views/alchemy/admin/ingredients/_picture_fields.html.erb @@ -7,13 +7,13 @@ [Alchemy.t('Layout default'), ""] ] + ingredient.settings[:sizes].to_a, include_blank: false, - input_html: {class: 'alchemy_selectbox'} %> + input_html: {is: 'alchemy-select'} %> <%- end -%> <%- if ingredient.settings[:css_classes].present? -%> <%= f.input :css_class, collection: ingredient.settings[:css_classes], include_blank: Alchemy.t('None'), - input_html: {class: 'alchemy_selectbox'} %> + input_html: {is: 'alchemy-select'} %> <%- else -%> <%= f.input :css_class, label: Alchemy.t(:position_in_text), @@ -21,5 +21,5 @@ [Alchemy.t(:above), "no_float"], [Alchemy.t(:left), "left"], [Alchemy.t(:right), "right"] - ], include_blank: Alchemy.t("Layout default"), input_html: {class: 'alchemy_selectbox'} %> + ], include_blank: Alchemy.t("Layout default"), input_html: {is: 'alchemy-select'} %> <%- end -%> diff --git a/app/views/alchemy/admin/ingredients/_video_fields.html.erb b/app/views/alchemy/admin/ingredients/_video_fields.html.erb index dfa598c7b8..45d0d883b7 100644 --- a/app/views/alchemy/admin/ingredients/_video_fields.html.erb +++ b/app/views/alchemy/admin/ingredients/_video_fields.html.erb @@ -6,4 +6,4 @@ <%= f.input :muted, as: :boolean %> <%= f.input :playsinline, as: :boolean %> <%= f.input :preload, collection: %w(auto none metadata), - include_blank: false, input_html: {class: 'alchemy_selectbox'} %> + include_blank: false, input_html: {is: 'alchemy-select'} %> diff --git a/app/views/alchemy/admin/languages/_form.html.erb b/app/views/alchemy/admin/languages/_form.html.erb index 8ee463d007..dbdf933440 100644 --- a/app/views/alchemy/admin/languages/_form.html.erb +++ b/app/views/alchemy/admin/languages/_form.html.erb @@ -9,14 +9,14 @@ <%= f.input :locale, collection: language.matching_locales.presence || ::I18n.available_locales, selected: language.locale || language.language_code || ::I18n.default_locale.to_s, - input_html: {class: 'alchemy_selectbox'} %> + input_html: {is: 'alchemy-select'} %> <% end %> <%= f.input :frontpage_name %> <%= f.input :page_layout, collection: Alchemy::PageLayout.all, label_method: ->(p) { Alchemy::Page.human_layout_name(p['name']) }, value_method: ->(p) { p['name'] }, - input_html: {class: 'alchemy_selectbox'} %> + input_html: {is: 'alchemy-select'} %> <%= f.input :public %> <%= f.input :default %> <%= f.hidden_field :site_id %> diff --git a/app/views/alchemy/admin/nodes/_form.html.erb b/app/views/alchemy/admin/nodes/_form.html.erb index 4175f37b2e..201cd43956 100644 --- a/app/views/alchemy/admin/nodes/_form.html.erb +++ b/app/views/alchemy/admin/nodes/_form.html.erb @@ -3,7 +3,7 @@ <%= f.input :menu_type, collection: Alchemy::Language.current.available_menu_names.map { |n| [I18n.t(n, scope: [:alchemy, :menu_names]), n] }, include_blank: false, - input_html: { class: 'alchemy_selectbox' } %> + input_html: { is: 'alchemy-select' } %> <% else %> <% if node.root? %> <%= f.input :name %> diff --git a/app/views/alchemy/admin/pages/_anchor_link.html.erb b/app/views/alchemy/admin/pages/_anchor_link.html.erb index a952d7aad6..75cfaebc2b 100644 --- a/app/views/alchemy/admin/pages/_anchor_link.html.erb +++ b/app/views/alchemy/admin/pages/_anchor_link.html.erb @@ -8,7 +8,7 @@ <%= select_tag(:anchor_link, options_for_select([[Alchemy.t('Please choose'), '']]), - class: 'alchemy_selectbox') %> + is: 'alchemy-select') %>