diff --git a/app/components/_index.sass b/app/components/_index.sass index 802d5ae8e6b..b943ce7ea8b 100644 --- a/app/components/_index.sass +++ b/app/components/_index.sass @@ -1,3 +1,4 @@ +@import "admin_settings_form_component" @import "work_packages/activities_tab/index_component" @import "work_packages/activities_tab/journals/new_component" @import "work_packages/activities_tab/journals/index_component" diff --git a/app/components/admin_settings_form_component.rb b/app/components/admin_settings_form_component.rb new file mode 100644 index 00000000000..cd77878032c --- /dev/null +++ b/app/components/admin_settings_form_component.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +class AdminSettingsFormComponent < ApplicationComponent + def render_in(view_context, &) + tag.div(class: "op-admin-settings-form-wrapper") do + super + end + end +end diff --git a/app/components/admin_settings_form_component.sass b/app/components/admin_settings_form_component.sass new file mode 100644 index 00000000000..fb707af7830 --- /dev/null +++ b/app/components/admin_settings_form_component.sass @@ -0,0 +1,3 @@ +.op-admin-settings-form-wrapper + max-width: 680px + margin: 0 auto 0 0 diff --git a/app/components/work_packages/types/settings_component.rb b/app/components/work_packages/types/settings_component.rb index 97699f45cf6..039f1fc5be8 100644 --- a/app/components/work_packages/types/settings_component.rb +++ b/app/components/work_packages/types/settings_component.rb @@ -30,7 +30,7 @@ module WorkPackages module Types - class SettingsComponent < ApplicationComponent + class SettingsComponent < AdminSettingsFormComponent include OpPrimer::ComponentHelpers include OpTurbo::Streamable diff --git a/app/components/work_packages/types/subject_configuration_component.rb b/app/components/work_packages/types/subject_configuration_component.rb index 4df87d4e9b7..142b8877240 100644 --- a/app/components/work_packages/types/subject_configuration_component.rb +++ b/app/components/work_packages/types/subject_configuration_component.rb @@ -30,7 +30,7 @@ module WorkPackages module Types - class SubjectConfigurationComponent < ApplicationComponent + class SubjectConfigurationComponent < AdminSettingsFormComponent include OpPrimer::ComponentHelpers include OpTurbo::Streamable diff --git a/app/forms/work_packages/types/settings_form.rb b/app/forms/work_packages/types/settings_form.rb index dca2d61dce3..c7ab04ee73f 100644 --- a/app/forms/work_packages/types/settings_form.rb +++ b/app/forms/work_packages/types/settings_form.rb @@ -36,7 +36,6 @@ module WorkPackages name: :name, label: label(:name), placeholder: I18n.t(:label_name), - input_width: :large, required: true, disabled: model.is_standard? ) @@ -44,16 +43,16 @@ module WorkPackages settings_form.color_select_list( name: :color_id, label: Color.model_name.human, - caption: I18n.t("types.edit.settings.type_color_text"), - input_width: :large + input_width: :medium, + caption: I18n.t("types.edit.settings.type_color_text") ) if show_work_flow_copy? settings_form.select_list( name: :copy_workflow_from, + input_width: :medium, label: I18n.t(:label_copy_workflow_from), - include_blank: true, - input_width: :large + include_blank: true ) do |other_types| work_package_types.each do |type| other_types.option( @@ -68,7 +67,6 @@ module WorkPackages settings_form.rich_text_area( name: :description, label: label(:description), - input_width: :large, rich_text_options: { showAttachments: false } ) diff --git a/app/forms/work_packages/types/subject_configuration_form.rb b/app/forms/work_packages/types/subject_configuration_form.rb index 6e1f5c4f6d2..7f6b1697552 100644 --- a/app/forms/work_packages/types/subject_configuration_form.rb +++ b/app/forms/work_packages/types/subject_configuration_form.rb @@ -54,7 +54,6 @@ module WorkPackages toggleable_group.pattern_input( name: :pattern, value: model.pattern, - input_width: :large, suggestions: model.suggestions, label: I18n.t("types.edit.subject_configuration.pattern.label"), caption: I18n.t("types.edit.subject_configuration.pattern.caption"), diff --git a/lookbook/docs/patterns/02-forms.md.erb b/lookbook/docs/patterns/02-forms.md.erb index 7635efc710a..c68a1982d8b 100644 --- a/lookbook/docs/patterns/02-forms.md.erb +++ b/lookbook/docs/patterns/02-forms.md.erb @@ -30,9 +30,16 @@ If a form does not use Subhead sections, then there should be a single 'Save' (u ## Form width -In Primer, form elements automatically take the width of the container. In certain cases (especially Settings pages), full-width input fields will look strange. In this case, form inputs will need to have a smaller width. A good rule of thumb is to fit the size of the fields to the expected length of the user input. Date fields can for example be rather small, as they are limited in length. The name of an object on the other hand can be quite long, so the field is expected to be larger. +In Primer, form elements automatically take the width of the container. In certain cases (especially Settings pages), +full-width input fields will look strange. For these wide settings pages, we introduced [a pattern](./settings_pages) +that wraps the form inside container that limits the width of the form. -In OpenProject, each form element has its own container. It is thus possible to define the container width for each input with the `:input_width` parameter. This width will define both the visual width of the field but also the max width of the caption field (where the line breaks). +Individual form elements can however be sized to be smaller than the width the container. A good rule of thumb is to choose a width for a +field based on the expected length of the user input: date fields can for example be rather short but a name field has the potential to be quite long. While the +input field can be limited in width, the caption and validation messages will always extend to the full width of the form (or the container, if one is used). + +In OpenProject, each form element also has its own container. It is thus possible to define the container width for each +input with the `:input_width` parameter. The options are: diff --git a/lookbook/docs/patterns/17-settings-pages.md.erb b/lookbook/docs/patterns/17-settings-pages.md.erb index f975a73b902..806c0691528 100644 --- a/lookbook/docs/patterns/17-settings-pages.md.erb +++ b/lookbook/docs/patterns/17-settings-pages.md.erb @@ -1 +1,27 @@ -When working on Settings pages, please refer to the Forms pattern for information on how to implement form elements. \ No newline at end of file +Settings pages usually stretch to the full width of the viewport as they tend not to have addition horizontally-positioned elements. + +## Settings page base component + +As specified in the documentation for [forms](./forms), we prefer limiting the width of a form for legibility. Because the default +behaviour of form elements to fill the full width of the container, we wrap forms in a container that limits its available width. + +Any view component rendering a form should inherit from `AdminSettingsFormComponent`. The template stays unchanged. This +way, the rendered form is wrapped into a container with `680px` max-width. + +```ruby +module WorkPackages + module Types + class SettingsComponent < AdminSettingsFormComponent + # component logic goes here + end + end +end +``` + +```erb +<%%= + primer_form_with(**form_options) do |f| + render(WorkPackages::Types::SettingsForm.new(f)) + end +%> +``` diff --git a/lookbook/previews/patterns/forms_preview/default.html.erb b/lookbook/previews/patterns/forms_preview/default.html.erb index a521a87a5c2..0d4cfaaa27f 100644 --- a/lookbook/previews/patterns/forms_preview/default.html.erb +++ b/lookbook/previews/patterns/forms_preview/default.html.erb @@ -13,6 +13,7 @@ name: :ultimate_answer, label: "Small", required: true, + caption: "Small fields cannot contain a much longer caption. It will overflow until it reaches the form width.", input_width: :small )