From 9d555aaa73315fdf4b7b1eb2973e717400baeeea Mon Sep 17 00:00:00 2001 From: Benjamin Kott <benjamin.kott@outlook.com> Date: Fri, 6 Sep 2024 13:41:16 +0200 Subject: [PATCH] [TASK] Make panels context aware The new panel element styling is context aware and adapts to light and dark color schemes. The markup was streamlined, workarounds dropped and now features improved focus and hover styles. Resolves: #104818 Resolves: #104798 Releases: main Change-Id: I9cf2b1c203b8a38c0c0675ff26a08131b0277923 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/85725 Tested-by: Andreas Nedbal <andy@pixelde.su> Tested-by: Benjamin Franzke <ben@bnf.dev> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Andreas Nedbal <andy@pixelde.su> Reviewed-by: Benjamin Franzke <ben@bnf.dev> --- Build/Sources/Sass/_legacy.scss | 11 - Build/Sources/Sass/_minimal.scss | 3 + Build/Sources/Sass/component/_buttons.scss | 1 + Build/Sources/Sass/component/_caret.scss | 26 + Build/Sources/Sass/component/_modal.scss | 16 - Build/Sources/Sass/component/_order.scss | 42 ++ Build/Sources/Sass/component/_panel.scss | 447 +++++++++-------- Build/Sources/Sass/component/_recordlist.scss | 36 +- Build/Sources/Sass/component/_root.scss | 1 + Build/Sources/Sass/component/_table.scss | 4 + Build/Sources/Sass/component/_tabs.scss | 15 + Build/Sources/Sass/component/_type.scss | 18 + Build/Sources/Sass/form.scss | 4 - Build/Sources/Sass/module/_install.scss | 72 +-- .../Sources/Sass/typo3/_element_cropper.scss | 88 +--- .../Sources/Sass/typo3/_element_tceforms.scss | 8 - Build/Sources/Sass/typo3/_login_screen.scss | 10 +- Build/Sources/Sass/typo3/_main_form.scss | 38 +- .../backend/element/collapsible-element.ts | 58 --- .../container/files-control-container.ts | 2 +- .../module/upgrade/extension-scanner.ts | 14 +- Build/Sources/TypeScript/install/router.ts | 15 +- .../Container/FlexFormSectionContainer.php | 40 +- .../Form/Element/SelectCheckBoxElement.php | 35 +- .../Form/Element/TablePermissionElement.php | 8 +- .../Resources/Private/Layouts/Login.html | 11 +- .../ContentElement/ElementInformation.html | 243 +++++---- .../Form/ImageManipulationWizard.html | 96 ++-- .../Templates/ModuleTemplate/Collapse.html | 49 -- .../Templates/ModuleTemplate/Tabs.html | 11 - .../Templates/PageTsConfig/Active.html | 101 ++-- .../Templates/PageTsConfig/Includes.html | 133 +++-- .../backend/Resources/Public/Css/backend.css | 198 ++++---- .../JavaScript/element/collapsible-element.js | 13 - .../container/files-control-container.js | 2 +- .../Private/Partials/Compare/Information.html | 256 +++++----- .../Templates/BackendUser/Compare.html | 5 +- .../Private/Templates/BackendUser/Show.html | 463 ++++++++---------- .../Templates/BackendUserGroup/Compare.html | 5 +- .../Application/InstallTool/UpgradeCest.php | 4 +- .../sysext/form/Resources/Public/Css/form.css | 1 - .../ExtensionConfiguration/ExtensionForm.html | 22 +- .../LocalConfiguration/SubSection.html | 23 +- .../Partials/Settings/Presets/Cache.html | 23 +- .../Partials/Settings/Presets/Context.html | 23 +- .../Partials/Settings/Presets/Image.html | 23 +- .../Partials/Settings/Presets/Mail.html | 23 +- .../Settings/Presets/PasswordHashing.html | 23 +- .../Upgrade/UpgradeDocs/PanelItem.html | 27 +- .../Templates/Upgrade/ExtensionScanner.html | 79 ++- .../Upgrade/UpgradeDocsGetContent.html | 69 ++- .../module/upgrade/extension-scanner.js | 2 +- .../Resources/Public/JavaScript/router.js | 2 +- .../Partials/RecordsTable/DeletedRecord.html | 11 +- .../Partials/MultiRecordSelectionActions.html | 4 +- .../Resources/Private/Partials/TaskList.html | 6 +- .../Controller/ComponentsController.php | 27 +- .../Resources/Private/Language/locallang.xlf | 58 ++- .../Backend/Components/Accordion.html | 116 ----- .../Templates/Backend/Components/Panels.html | 423 ++++++++++++++++ .../Templates/Backend/Components/Tab.html | 2 +- .../Private/Partials/ActiveConditions.html | 63 +-- .../Private/Partials/ActiveTreePanel.html | 48 +- .../Private/Partials/AnalyzerConditions.html | 63 +-- .../Partials/AnalyzerSyntaxErrors.html | 58 ++- .../Private/Partials/AnalyzerTreePanel.html | 31 +- 66 files changed, 2043 insertions(+), 1809 deletions(-) create mode 100644 Build/Sources/Sass/component/_caret.scss create mode 100644 Build/Sources/Sass/component/_order.scss create mode 100644 Build/Sources/Sass/component/_tabs.scss delete mode 100644 Build/Sources/TypeScript/backend/element/collapsible-element.ts delete mode 100644 typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Collapse.html delete mode 100644 typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Tabs.html delete mode 100644 typo3/sysext/backend/Resources/Public/JavaScript/element/collapsible-element.js delete mode 100644 typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Accordion.html create mode 100644 typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Panels.html diff --git a/Build/Sources/Sass/_legacy.scss b/Build/Sources/Sass/_legacy.scss index 4fb2ecac437f..f455ead7ef4b 100644 --- a/Build/Sources/Sass/_legacy.scss +++ b/Build/Sources/Sass/_legacy.scss @@ -52,17 +52,6 @@ $input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) ! display: none !important; } -.caret { - display: inline-block; - width: 0; - height: 0; - margin-left: .125rem; - vertical-align: middle; - border-top: .25rem dashed $gray-700; - border-right: .25rem solid transparent; - border-left: .25rem solid transparent; -} - // nav fallback // todo add ".nav-item" and ".nav-link" classes to markup .nav.nav-tabs { diff --git a/Build/Sources/Sass/_minimal.scss b/Build/Sources/Sass/_minimal.scss index 2aee736d2477..70a650ba5147 100644 --- a/Build/Sources/Sass/_minimal.scss +++ b/Build/Sources/Sass/_minimal.scss @@ -81,8 +81,10 @@ // @import "component/root"; @import "component/type"; +@import "component/order"; @import "component/nav"; @import "component/icon"; +@import "component/caret"; @import "component/spacer"; @import "component/alert"; @import "component/autocomplete"; @@ -100,3 +102,4 @@ @import "component/panel"; @import "component/table"; @import "component/simpletable"; +@import "component/tabs"; diff --git a/Build/Sources/Sass/component/_buttons.scss b/Build/Sources/Sass/component/_buttons.scss index 798b13ae68ce..eff1f60ea576 100644 --- a/Build/Sources/Sass/component/_buttons.scss +++ b/Build/Sources/Sass/component/_buttons.scss @@ -60,6 +60,7 @@ } .btn-check:focus-visible + &, + &:has(*:focus-visible), &:focus-visible { outline: .25rem solid color-mix(in srgb, var(--typo3-btn-focus-border-color), transparent 25%); } diff --git a/Build/Sources/Sass/component/_caret.scss b/Build/Sources/Sass/component/_caret.scss new file mode 100644 index 000000000000..919b80e65386 --- /dev/null +++ b/Build/Sources/Sass/component/_caret.scss @@ -0,0 +1,26 @@ +// +// Caret +// +:root { + --typo3-caret-color: var(--typo3-text-color-base); + --typo3-caret-rotation: 0deg; + --typo3-caret-size: 16px; + --typo3-caret-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cg fill='%23fff'%3e%3cpath d='m4.464 6.05-.707.707L8 11l4.243-4.243-.707-.707L8 9.586z'/%3e%3c/g%3e%3c/svg%3e"); +} + +.caret { + display: inline-block; + position: relative; + height: var(--typo3-caret-size); + width: var(--typo3-caret-size); + background-color: var(--typo3-caret-color); + mask-repeat: no-repeat; + mask-image: var(--typo3-caret-icon); + mask-position: center center; + mask-size: contain; + rotate: var(--typo3-caret-rotation); + line-height: 1; + vertical-align: -22%; + + @include transition(all .25s ease-in-out); +} diff --git a/Build/Sources/Sass/component/_modal.scss b/Build/Sources/Sass/component/_modal.scss index bb3fa772aa93..61a50f55e8c0 100644 --- a/Build/Sources/Sass/component/_modal.scss +++ b/Build/Sources/Sass/component/_modal.scss @@ -155,22 +155,6 @@ $modal-sidebar-button-space: $padding-small-vertical; width: $modal-sidebar-md; } } - - .panel-heading { - .is-active { - // Disable pointer events to make - // sure the active panel stays open - pointer-events: none; - } - } - - .panel { - margin-bottom: 0; - } - - .panel-body { - border-inline-start: 2px solid $color-orange; - } } // diff --git a/Build/Sources/Sass/component/_order.scss b/Build/Sources/Sass/component/_order.scss new file mode 100644 index 000000000000..0b869b15f2f3 --- /dev/null +++ b/Build/Sources/Sass/component/_order.scss @@ -0,0 +1,42 @@ +// +// Ordering Helper +// +.order-0 { + order: 0; +} + +.order-1 { + order: 1; +} + +.order-2 { + order: 2; +} + +.order-3 { + order: 3; +} + +.order-4 { + order: 4; +} + +.order-5 { + order: 5; +} + +.order-6 { + order: 6; +} + +.order-7 { + order: 7; +} + +.order-8 { + order: 8; +} + +.order-9 { + order: 9; +} diff --git a/Build/Sources/Sass/component/_panel.scss b/Build/Sources/Sass/component/_panel.scss index d2f52473185d..d2158c8c1173 100644 --- a/Build/Sources/Sass/component/_panel.scss +++ b/Build/Sources/Sass/component/_panel.scss @@ -23,113 +23,45 @@ // </div> // </div> // -// - -// -// Variables -// -$panel-border-scale: -60%; -$panel-heading-bg-scale: -85%; - -// Mixins -@mixin panel-create-variant($name, $value, $border-scale: $panel-border-scale, $heading-scale: $panel-heading-bg-scale, $panel-progress-bg: null) { - $panel-border: shift-color($value, $border-scale); - $panel-heading-bg: shift-color($value, $heading-scale); - $panel-heading-color: color-contrast($panel-heading-bg); - - @if $panel-progress-bg == null { - $panel-progress-bg: $value; - } - --panel-#{$name}-border-color: #{$panel-border}; - --panel-#{$name}-progress-bg: #{$panel-progress-bg}; - --panel-#{$name}-heading-color: #{$panel-heading-color}; - --panel-#{$name}-heading-bg: #{$panel-heading-bg}; -} - -@mixin panel-use-variant($name) { - --panel-border-color: var(--panel-#{$name}-border-color); - --panel-progress-bg: var(--panel-#{$name}-progress-bg); - --panel-heading-color: var(--panel-#{$name}-heading-color); - --panel-heading-bg: var(--panel-#{$name}-heading-bg); -} - -// Variables -:root { - --panel-bg: #fff; - --panel-border-color: #ccc; - --panel-border-radius: var(--typo3-component-border-radius); - --panel-border-width: var(--typo3-component-border-width); - --panel-padding: var(--typo3-component-padding-x); - --panel-header-padding-x: var(--typo3-component-padding-x); - --panel-header-padding-y: var(--typo3-component-padding-y); - --panel-spacing: var(--typo3-component-spacing); - --panel-box-shadow: var(--typo3-component-box-shadow); - - @each $name, $value in $theme-colors { - @if $name == light { - @include panel-create-variant($name, $value, 20%, 0%, darken($value, 10%)); - } - - @else if $name == default { - @include panel-create-variant($name, $value, 20%, 0%, darken($value, 10%)); - } - - @else { - @include panel-create-variant($name, $value); - } - } -} - -// -// Group -// -.panel-group { - display: flex; - flex-flow: column; - overflow: hidden; - margin-bottom: var(--typo3-spacing); - border-radius: var(--panel-border-radius); - box-shadow: var(--panel-box-shadow); - - > .panel { - border-radius: 0; - margin-bottom: 0; - box-shadow: none; - margin-top: calc(var(--panel-border-width) * -1); - - &:first-child { - margin-top: 0; - border-top-left-radius: var(--panel-border-radius); - border-top-right-radius: var(--panel-border-radius); - } - - &:last-child { - border-bottom-left-radius: var(--panel-border-radius); - border-bottom-right-radius: var(--panel-border-radius); - } - } -} - -// -// Component -// .panel { + --typo3-panel-color: var(--typo3-component-color); + --typo3-panel-bg: var(--typo3-component-bg); + --typo3-panel-border-color: color-mix(in srgb, var(--typo3-panel-bg), var(--typo3-panel-color) 15%); + --typo3-panel-border-width: var(--typo3-component-border-width); + --typo3-panel-border-radius: var(--typo3-component-border-radius); + --typo3-panel-border-radius-top: var(--typo3-panel-border-radius); + --typo3-panel-border-radius-bottom: var(--typo3-panel-border-radius); + --typo3-panel-border-radius-inner-top: max(0px, calc(var(--typo3-panel-border-radius-top) - var(--typo3-panel-border-width))); + --typo3-panel-border-radius-inner-bottom: max(0px, calc(var(--typo3-panel-border-radius-bottom) - var(--typo3-panel-border-width))); + --typo3-panel-padding-y: .75rem; + --typo3-panel-padding-x: 1rem; + --typo3-panel-sm-padding-y: .5rem; + --typo3-panel-sm-padding-x: .75rem; + --typo3-panel-header-bg: var(--typo3-surface-container-low); + --typo3-panel-header-color: var(--typo3-text-color-base); + --typo3-panel-box-shadow: var(--typo3-component-box-shadow); + --typo3-panel-progress-bg: var(--typo3-state-primary-bg); + + @each $state in $base-variants { + --typo3-panel-#{$state}-header-color: var(--typo3-surface-container-#{$state}-text); + --typo3-panel-#{$state}-header-bg: var(--typo3-surface-container-#{$state}); + --typo3-panel-#{$state}-border-color: color-mix(in srgb, var(--typo3-panel-#{$state}-header-bg), var(--typo3-panel-#{$state}-header-color) 15%); + } display: flex; flex-direction: column; - overflow: hidden; min-width: 0; word-wrap: break-word; background-clip: border-box; - background-color: var(--panel-bg); - border: var(--panel-border-width) solid var(--panel-border-color); - border-radius: var(--panel-border-radius); - box-shadow: var(--panel-box-shadow); + color: var(--typo3-panel-color); + background-color: var(--typo3-panel-bg); + border: var(--typo3-panel-border-width) solid var(--typo3-panel-border-color); + border-radius: var(--typo3-panel-border-radius-top) var(--typo3-panel-border-radius-top) var(--typo3-panel-border-radius-bottom) var(--typo3-panel-border-radius-bottom); + box-shadow: var(--typo3-panel-box-shadow); margin-block-end: var(--typo3-spacing); - transition: all .2s ease-in-out; - transition-property: box-shadow, border, transform; position: relative; - .table-fit { + > .table-fit, + .panel-collapse > .table-fit { box-shadow: none; border-radius: 0; border-left: 0; @@ -137,18 +69,41 @@ $panel-heading-bg-scale: -85%; border-bottom: 0; margin-bottom: 0; } + + > .table-fit:last-child { + border-end-start-radius: var(--typo3-panel-border-radius-inner-bottom); + border-end-end-radius: var(--typo3-panel-border-radius-inner-bottom); + } } // // Loader // +// <div class="panel panel-default"> +// <div class="panel-loader"> +// <typo3-backend-spinner size="small"></typo3-backend-spinner> +// </div> +// </div> +// .panel-loader { - padding: var(--panel-padding); + padding: var(--typo3-panel-padding-y) var(--typo3-panel-padding-x); } // // Progress // +// <div class="panel panel-default panel-has-progress"> +// <div class="panel-progress"> +// <div class="panel-progress-bar" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%;"> +// <span class="visually-hidden">50%</span> +// </div> +// </div> +// </div> +// +.panel:has(.panel-progress) { + min-height: 5px; +} + .panel-progress { display: none; position: absolute; @@ -158,11 +113,13 @@ $panel-heading-bg-scale: -85%; width: 100%; z-index: 1; background-color: transparent; + overflow: hidden; + border-radius: var(--typo3-panel-border-radius-inner-top) var(--typo3-panel-border-radius-inner-top) 0 0; .panel-progress-bar { display: block; height: 100%; - background-color: var(--panel-progress-bg, $primary); + background-color: var(--typo3-panel-progress-bg); } } @@ -172,89 +129,137 @@ $panel-heading-bg-scale: -85%; } } +// +// Button +// +.panel-button { + position: relative; + display: flex; + align-items: center; + text-align: start; + padding: 0; + gap: .25rem; + background: transparent; + border: none; + flex-grow: 1; + width: 100%; + + &:after { + position: absolute; + content: ''; + left: 0; + right: 0; + top: calc(var(--typo3-panel-padding-y) * -1); + bottom: calc(var(--typo3-panel-padding-y) * -1); + } +} + // // Heading // .panel-heading { + font-size: var(--typo3-font-size); + font-weight: normal; position: relative; - color: var(--panel-heading-color); - background-color: var(--panel-heading-bg); - font-weight: bold; - padding: var(--panel-header-padding-y) var(--panel-header-padding-x); + color: var(--typo3-panel-header-color); + background-color: var(--typo3-panel-header-bg); + padding: var(--typo3-panel-padding-y) var(--typo3-panel-padding-x); + border-radius: var(--typo3-panel-border-radius-inner-top) var(--typo3-panel-border-radius-inner-top) var(--typo3-panel-border-radius-inner-bottom) var(--typo3-panel-border-radius-inner-bottom); + outline-offset: 0; + margin: 0; + + &:not(:last-child):not(.collapsed):not(:has(.collapsed)) { + --typo3-panel-border-radius-inner-bottom: 0; + } + + [data-bs-toggle="collapse"] { + outline: none; + } + + &:has([data-bs-toggle="collapse"]:focus-visible) { + z-index: 1; + outline: .25rem solid color-mix(in srgb, var(--typo3-panel-border-color), transparent 25%); + } .caret { - @include transition(all .25s ease-in-out); - border-top-color: var(--panel-heading-color); + --typo3-caret-color: var(--typo3-panel-header-color); } - /* stylelint-disable */ - .panel-collapsed &, - .collapsed > , - .collapsed > .form-irre-header-icon { + &.collapsed, + &:has(.collapsed), + &:has(.form-irre-header-button[aria-expanded="false"]) { .caret { - transform: rotate(-90deg); + --typo3-caret-rotation: calc(-90deg * var(--typo3-position-modifier)); } } - /* stylelint-enable */ - - a:not(.btn), - a:not(.btn):hover, - a:not(.btn):focus, - a:not(.btn):active { - text-decoration: none; - color: inherit; - } &-row { flex-grow: 1; display: flex; align-items: center; - flex-wrap: wrap; - max-width: 100%; - gap: var(--panel-header-padding-y) var(--panel-header-padding-x); - } - - &-title { - font-weight: bold; - flex-grow: 1; - width: 250px; max-width: 100%; - } - - &-actions { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: .25rem; - } + gap: .5rem; - &-button { - display: flex; - text-align: start; - align-items: center; - align-self: stretch; - border: 0; - width: 100%; + .panel-button { + width: auto; + } } } // // Title // +// <div class="panel panel-default panel-has-progress"> +// <h2 class="panel-heading"> +// Panel Title +// </h2> +// </div> +// .panel-title { - font-size: $font-size-base; + font-size: var(--typo3-font-size); margin-top: 0; margin-bottom: 0; + flex-grow: 1; +} + +.panel-heading:has([data-bs-toggle="collapse"]:hover) { + .panel-title { + text-decoration: underline; + } +} + +// +// Elements +// +.panel-icon, +.panel-badge { + display: flex; + justify-content: center; + align-items: center; +} + +.panel-actions { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: .25rem; } // // Body // +// <div class="panel panel-default"> +// <div class="panel-body"> +// ... +// </div> +// </div> +// .panel-body { - padding: var(--panel-padding); + padding: var(--typo3-panel-padding-y) var(--typo3-panel-padding-x); - > p > a { - text-decoration: underline; + &:last-child { + border-end-start-radius: var(--typo3-panel-border-radius-inner-bottom); + border-end-end-radius: var(--typo3-panel-border-radius-inner-bottom); } > *:first-child { @@ -272,45 +277,69 @@ $panel-heading-bg-scale: -85%; } // -// Footer +// Collapse // -.panel-footer { - padding: var(--panel-padding); +.panel-collapse { + overflow: hidden; + + &:last-child { + border-end-start-radius: var(--typo3-panel-border-radius-inner-bottom); + border-end-end-radius: var(--typo3-panel-border-radius-inner-bottom); + } } // -// Table +// Footer // -.panel-table { - th:first-child, - td:first-child { - padding-inline-start: var(--panel-header-padding-x); - } - - th:last-child, - td:last-child { - padding-inline-end: var(--panel-header-padding-x); - } +// <div class="panel panel-default"> +// <div class="panel-body"> +// ... +// </div> +// <div class="panel-footer"> +// ... +// </div> +// </div> +// +.panel-footer { + padding: var(--typo3-panel-padding-y) var(--typo3-panel-padding-x); } // // List // +// <div class="panel panel-default"> +// <div class="panel-body"> +// <ul class="panel-list"> +// <li>Item 1</li> +// <li>Item 2</li> +// <li>Item 3</li> +// </ul> +// </div> +// </div> +// .panel-list { - padding-left: var(--panel-padding); + padding-left: var(--typo3-panel-padding-x); - li { - padding-bottom: .2rem; + > li + li { + margin-top: .2rem; } } // // Condensed // +// <div class="panel panel-default panel-condensed"> +// <div class="panel-body"> +// ... +// </div> +// <div class="panel-footer"> +// ... +// </div> +// </div> +// .panel-condensed { - --panel-padding: .5rem; - --panel-header-padding-x: .5rem; - --panel-header-padding-y: .5rem; + --typo3-panel-padding-y: var(--typo3-panel-sm-padding-y); + --typo3-panel-padding-x: var(--typo3-panel-sm-padding-x); } // @@ -323,49 +352,79 @@ $panel-heading-bg-scale: -85%; } } -// -// Panel Tab -// -.panel-tab { - --panel-border-radius: 0; - border: 1px solid $nav-tabs-active-link-hover-border-color; - background-color: $nav-tabs-active-link-bg; -} - -.tab-pane { - > h2 + .form-section, - > .panel-tab:first-child { - border-top: none; - } -} - // // Colors // -@each $state, $value in $theme-colors { - .panel-#{$state} { - @include panel-use-variant($state); +@each $variant in $base-variants { + .panel-#{$variant} { + --typo3-panel-header-color: var(--typo3-panel-#{$variant}-header-color); + --typo3-panel-header-bg: var(--typo3-panel-#{$variant}-header-bg); + --typo3-panel-border-color: var(--typo3-panel-#{$variant}-border-color); } } .panel-active { - @include panel-use-variant('primary'); + @extend .panel-primary; } .panel-feature { - @include panel-use-variant('success'); + @extend .panel-success; } .panel-important { - @include panel-use-variant('info'); + @extend .panel-info; } .panel-deprecation { - @include panel-use-variant('warning'); + @extend .panel-warning; } .panel-breaking { - @include panel-use-variant('danger'); + @extend .panel-danger; +} + +// +// Group +// +.panel-group { + --typo3-panel-group-border-radius: var(--typo3-component-border-radius); + --typo3-panel-group-border-radius-top: var(--typo3-panel-group-border-radius); + --typo3-panel-group-border-radius-bottom: var(--typo3-panel-group-border-radius); + --typo3-panel-group-box-shadow: var(--typo3-component-box-shadow); + display: flex; + flex-flow: column; + margin-bottom: var(--typo3-spacing); + border-radius: var(--typo3-panel-group-border-radius-top) var(--typo3-panel-group-border-radius-top) var(--typo3-panel-group-border-radius-bottom) var(--typo3-panel-group-border-radius-bottom); + box-shadow: var(--typo3-panel-group-box-shadow); + + > .panel { + // Disable stylelint to preserve units + /* stylelint-disable */ + --typo3-panel-border-radius-top: 0px; + --typo3-panel-border-radius-bottom: 0px; + /* stylelint-enable */ + margin-bottom: 0; + box-shadow: none; + margin-top: calc(var(--typo3-panel-border-width) * -1); + + &:first-child { + margin-top: 0; + --typo3-panel-border-radius-top: var(--typo3-panel-group-border-radius); + } + + &:last-child { + --typo3-panel-border-radius-bottom: var(--typo3-panel-group-border-radius); + } + } +} + +// +// Animation +// +.panel, +.panel-heading { + transition: all .2s ease-in-out; + transition-property: box-shadow, border, border-radius, transform; } // @@ -378,7 +437,7 @@ $panel-heading-bg-scale: -85%; > .alert { margin: 0; border: none; - border-top: var(--panel-border-width) solid var(--panel-border-color); + border-top: var(--typo3-panel-border-width) solid var(--typo3-panel-border-color); --typo3-alert-border-radius: 0; } @@ -394,7 +453,7 @@ $panel-heading-bg-scale: -85%; > [role="tabpanel"] > .nav-tabs, > .nav-tabs { - border-top: 1px solid $panel-default-border; + border-top: 1px solid var(--typo3-panel-border-color); padding-top: 8px; > li { diff --git a/Build/Sources/Sass/component/_recordlist.scss b/Build/Sources/Sass/component/_recordlist.scss index 644384633645..8b39382d9518 100644 --- a/Build/Sources/Sass/component/_recordlist.scss +++ b/Build/Sources/Sass/component/_recordlist.scss @@ -14,11 +14,27 @@ } .recordlist { + --typo3-recordlist-color: var(--typo3-component-color); + --typo3-recordlist-bg: var(--typo3-component-bg); + --typo3-recordlist-border-color: color-mix(in srgb, var(--typo3-recordlist-bg), var(--typo3-recordlist-color) 15%); + --typo3-recordlist-border-width: var(--typo3-component-border-width); + --typo3-recordlist-border-radius: var(--typo3-component-border-radius); + --typo3-recordlist-border-radius-top: var(--typo3-recordlist-border-radius); + --typo3-recordlist-border-radius-bottom: var(--typo3-recordlist-border-radius); + --typo3-recordlist-border-radius-inner-top: max(0px, calc(var(--typo3-recordlist-border-radius-top) - var(--typo3-recordlist-border-width))); + --typo3-recordlist-border-radius-inner-bottom: max(0px, calc(var(--typo3-recordlist-border-radius-bottom) - var(--typo3-recordlist-border-width))); + --typo3-recordlist-padding-y: .75rem; + --typo3-recordlist-padding-x: 1rem; + --typo3-recordlist-header-bg: var(--typo3-surface-container-low); + --typo3-recordlist-header-color: var(--typo3-text-color-base); + --typo3-recordlist-spacing: var(--typo3-component-spacing); + --typo3-recordlist-box-shadow: var(--typo3-component-box-shadow); + --typo3-recordlist-progress-bg: var(--typo3-state-primary-bg); overflow: hidden; - background: var(--panel-bg); - box-shadow: var(--panel-box-shadow); - border-radius: var(--panel-border-radius); - border: var(--panel-border-width) solid var(--panel-default-border-color); + background: var(--typo3-recordlist-bg); + box-shadow: var(--typo3-recordlist-box-shadow); + border-radius: var(--typo3-recordlist-border-radius); + border: var(--typo3-recordlist-border-width) solid var(--typo3-recordlist-border-color); margin-bottom: var(--typo3-spacing); table tr { @@ -38,7 +54,7 @@ } .alert { - padding: var(--panel-header-padding-y) var(--typo3-component-padding-x); + padding: var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x); } .pagination { @@ -67,10 +83,10 @@ display: flex; align-items: center; flex-wrap: wrap; - color: var(--panel-default-heading-color); - background: var(--panel-default-heading-bg); - padding: var(--panel-header-padding-y) var(--panel-header-padding-x); - gap: var(--panel-header-padding-y) var(--panel-header-padding-x); + color: var(--typo3-recordlist-header-color); + background: var(--typo3-recordlist-header-bg); + padding: var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x); + gap: var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x); &-row { flex-grow: 1; @@ -78,7 +94,7 @@ align-items: center; flex-wrap: wrap; max-width: 100%; - gap: var(--panel-header-padding-y) var(--panel-header-padding-x); + gap: var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x); } &-title { diff --git a/Build/Sources/Sass/component/_root.scss b/Build/Sources/Sass/component/_root.scss index a8de64231202..723f5f9d3401 100644 --- a/Build/Sources/Sass/component/_root.scss +++ b/Build/Sources/Sass/component/_root.scss @@ -40,6 +40,7 @@ // Colors --typo3-text-color-base: light-dark(var(--token-color-neutral-90), var(--token-color-neutral-10)); + --typo3-text-color-link: var(--typo3-text-color-base); --typo3-text-color-variant: light-dark(var(--token-color-neutral-60), var(--token-color-neutral-30)); --typo3-text-color-primary: light-dark(var(--token-color-blue-60), var(--token-color-blue-30)); --typo3-text-color-secondary: light-dark(var(--token-color-neutral-70), var(--token-color-neutral-35)); diff --git a/Build/Sources/Sass/component/_table.scss b/Build/Sources/Sass/component/_table.scss index 932c0ac2d0c9..ae0444ff1ded 100644 --- a/Build/Sources/Sass/component/_table.scss +++ b/Build/Sources/Sass/component/_table.scss @@ -34,6 +34,10 @@ border-bottom-width: var(--typo3-table-border-width); vertical-align: middle; + > *:last-child { + margin-bottom: 0; + } + &:is(th) { white-space: nowrap; } diff --git a/Build/Sources/Sass/component/_tabs.scss b/Build/Sources/Sass/component/_tabs.scss new file mode 100644 index 000000000000..141d1e88049b --- /dev/null +++ b/Build/Sources/Sass/component/_tabs.scss @@ -0,0 +1,15 @@ +// +// Tab Pane +// +.tab-pane { + > .panel { + --typo3-panel-bg: #{$nav-tabs-active-link-bg}; + --typo3-panel-border-color: #{$nav-tabs-active-link-hover-border-color}; + --typo3-panel-border-radius: 0; + } + + > .visually-hidden:first-child + .form-section, + > *:first-child { + border-top: none; + } +} diff --git a/Build/Sources/Sass/component/_type.scss b/Build/Sources/Sass/component/_type.scss index b635247e9a86..a02f71545533 100644 --- a/Build/Sources/Sass/component/_type.scss +++ b/Build/Sources/Sass/component/_type.scss @@ -25,6 +25,24 @@ h3 { font-family: inherit; } +// +// Links +// +a { + color: var(--typo3-text-color-link); + text-decoration: none; + + &:hover { + text-decoration: underline; + } + + &:not([href]):not([class]), + &:not([href]):not([class]):hover { + color: inherit; + text-decoration: none; + } +} + // // Colors // diff --git a/Build/Sources/Sass/form.scss b/Build/Sources/Sass/form.scss index a28f6e385ff9..930a16b8729b 100644 --- a/Build/Sources/Sass/form.scss +++ b/Build/Sources/Sass/form.scss @@ -762,10 +762,6 @@ $tree-line-height: 20px; inset-inline-end: -1px; } - .caret { - color: $primary; - } - .t3-form-dropdown-buttons { .icon { margin-inline-end: .5em; diff --git a/Build/Sources/Sass/module/_install.scss b/Build/Sources/Sass/module/_install.scss index 7a627b94a5ca..c8fedd8c7c1c 100644 --- a/Build/Sources/Sass/module/_install.scss +++ b/Build/Sources/Sass/module/_install.scss @@ -23,10 +23,6 @@ .panel-heading { position: relative; - button.link-action { - padding: 0; - } - strong { line-height: 1.5em; } @@ -36,11 +32,11 @@ position: absolute; display: flex; gap: .5rem; - top: calc(var(--panel-padding) / 2); - inset-inline-end: var(--panel-padding); + top: calc(var(--typo3-panel-padding-y) / 2); + inset-inline-end: var(--typo3-panel-padding-x); ~ .panel-body { - padding-top: calc(var(--panel-padding) * 2); + padding-top: calc(var(--typo3-panel-padding-y) * 2); } } @@ -48,11 +44,11 @@ position: absolute; display: flex; gap: .5rem; - bottom: calc(var(--panel-padding) / 2); - inset-inline-end: var(--panel-padding); + bottom: calc(var(--typo3-panel-padding-y) / 2); + inset-inline-end: var(--typo3-panel-padding-x); ~ .panel-body { - padding-bottom: calc(var(--panel-padding) * 2); + padding-bottom: calc(var(--typo3-panel-padding-y) * 2); } } } @@ -69,11 +65,6 @@ } } - // Collapsibles clickable on full length - a[data-bs-toggle="collapse"] { - display: block; - } - // Styles for specific modals: language pack handling .table .t3-languagePacks-inactive, .table .t3-languagePacks-inactive td { @@ -139,57 +130,6 @@ } } -// -// Panel Severity Variants -// - -// $panel-border-scale: -60%; -// $panel-heading-bg-scale: -85%; -$risk-high-border-scale: -20%; -$risk-high-bg-scale: -45%; -$risk-medium-border-scale: -40%; -$risk-medium-bg-scale: -65%; - -.panel-success.risk-high { - @include panel-create-variant('success-high', $success, $risk-high-border-scale, $risk-high-bg-scale); - @include panel-use-variant('success-high'); -} - -.panel-success.risk-medium { - @include panel-create-variant('success-medium', $success, $risk-medium-border-scale, $risk-medium-bg-scale); - @include panel-use-variant('success-medium'); -} - -.panel-warning.risk-high { - @include panel-create-variant('warning-high', $warning, $risk-high-border-scale, $risk-high-bg-scale); - @include panel-use-variant('warning-high'); -} - -.panel-warning.risk-medium { - @include panel-create-variant('warning-medium', $warning, $risk-medium-border-scale, $risk-medium-bg-scale); - @include panel-use-variant('warning-medium'); -} - -.panel-danger.risk-high { - @include panel-create-variant('danger-high', $danger, $risk-high-border-scale, $risk-high-bg-scale); - @include panel-use-variant('danger-high'); -} - -.panel-danger.risk-medium { - @include panel-create-variant('danger-medium', $danger, $risk-medium-border-scale, $risk-medium-bg-scale); - @include panel-use-variant('danger-medium'); -} - -.panel-info.risk-high { - @include panel-create-variant('info-high', $info, $risk-high-border-scale, $risk-high-bg-scale); - @include panel-use-variant('info-high'); -} - -.panel-info.risk-medium { - @include panel-create-variant('info-medium', $info, $risk-medium-border-scale, $risk-medium-bg-scale); - @include panel-use-variant('info-medium'); -} - // // Localconf Settings // diff --git a/Build/Sources/Sass/typo3/_element_cropper.scss b/Build/Sources/Sass/typo3/_element_cropper.scss index 5dce84f5a7e1..f0851a476039 100644 --- a/Build/Sources/Sass/typo3/_element_cropper.scss +++ b/Build/Sources/Sass/typo3/_element_cropper.scss @@ -1,14 +1,16 @@ .cropper { + color-scheme: only dark; + .cropper-line { background-color: transparent; } .cropper-dashed { - border: 1px dashed $color-orange; + border: 1px dashed var(--typo3-state-primary-bg); } .cropper-point { - background-color: $color-orange; + background-color: var(--typo3-state-primary-bg); &.point-nw { left: 0; /* 3 */ @@ -52,7 +54,7 @@ } .cropper-view-box { - outline: 1px dashed $color-orange; + outline: 1px dashed var(--typo3-state-primary-bg); } .cropper-bg { @@ -76,10 +78,6 @@ margin-bottom: 10px; .btn { - &.btn-default { - margin-bottom: 5px; - } - &:not(.active) .icon { display: none; } @@ -88,68 +86,25 @@ // Cropper style tweaks for Bootstrap .panel .panel-group { - [aria-expanded=true] { - border-inline-start: 2px solid $color-orange; - position: relative; - - &[data-bs-toggle=collapse] { - background-color: #333; - } - } - - [aria-expanded=false] { - border-inline-start: 2px solid #444; - position: relative; - } - - table, - label { - color: $color-white; - - &:has(input[type="radio"]:focus) { - color: var(--bs-btn-hover-color); - background-color: var(--bs-btn-hover-bg); - border-color: var(--bs-btn-hover-border-color); - } - } + --typo3-panel-border-radius: 0; position: relative; margin: -15px; - } - .panel-collapse.collapse { - background-color: #2c2c2c !important; - } - - .panel-heading { - padding: 0; + .panel { + border: 0; + border-inline-start: 3px solid var(--typo3-panel-border-color); + margin-bottom: 0; - .panel-title { - > [data-crop-variant] { - display: flex; - padding: 10px 15px; - justify-content: space-between; + &:has(.panel-heading):not(:has(.collapsed)) { + border-color: var(--typo3-state-primary-bg); } - > a { - text-decoration: none !important; - user-select: none; - font-size: 13px; + + .panel { + margin-top: 1px; } } } - .panel-default > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #333; - } - - .panel-group, - .panel-default .panel-heading, - .panel { - background: #222; - border: none; - color: $color-white; - } - /** * Style overrides for CropperJS CSS and additional styles to make cropper look like expected * @@ -165,19 +120,16 @@ overflow: hidden; /* 2 */ &:after { - background-color: $color-orange; + color: var(--typo3-state-primary-color); + background-color: var(--typo3-state-primary-bg); + font-size: var(--typo3-font-size-small); content: "Cropped area"; position: absolute; inset-inline-start: 0; top: 0; - font-size: 10px; - color: black; - height: 16px; - width: 100%; - max-width: 80px; text-overflow: ellipsis; white-space: nowrap; - padding: 0 4px; + padding: .5em .75em; pointer-events: none; overflow: hidden; } @@ -242,7 +194,7 @@ &.ui-resizable-ne, &.ui-resizable-nw { transform: none; - background-color: #ccc; + background-color: var(--typo3-state-primary-bg); height: 6px; width: 6px; } @@ -383,7 +335,7 @@ } .cropper-preview-thumbnail-crop-area { - border: 1px solid $color-orange; + border: 1px solid var(--typo3-state-primary-bg); position: absolute; z-index: 10; overflow: hidden; diff --git a/Build/Sources/Sass/typo3/_element_tceforms.scss b/Build/Sources/Sass/typo3/_element_tceforms.scss index 6c38b5aa5d86..e6e5ccba6553 100644 --- a/Build/Sources/Sass/typo3/_element_tceforms.scss +++ b/Build/Sources/Sass/typo3/_element_tceforms.scss @@ -10,14 +10,6 @@ cursor: move !important; } -// -// TCEforms Sections -// -.t3-form-field-add-flexsection { - border-top: 1px solid #cdcdcd; - padding: 10px 5px 5px 0; -} - // preview image in sys_file records img.t3-tceforms-sysfile-imagepreview { float: var(--typo3-position-start); diff --git a/Build/Sources/Sass/typo3/_login_screen.scss b/Build/Sources/Sass/typo3/_login_screen.scss index bada13d80626..6e3c0c1f0409 100644 --- a/Build/Sources/Sass/typo3/_login_screen.scss +++ b/Build/Sources/Sass/typo3/_login_screen.scss @@ -238,9 +238,17 @@ body[data-typo3-login-ready] { // Copyright // .typo3-login-copyright-link { + display: flex; + border: none; + padding: 0; + width: 100%; + background-color: transparent; + justify-content: space-between; font-weight: normal !important; - @extend .clearfix; + &:hover { + text-decoration: underline; + } > img { float: var(--typo3-position-end); diff --git a/Build/Sources/Sass/typo3/_main_form.scss b/Build/Sources/Sass/typo3/_main_form.scss index 6ebdc3090ee6..8d8c3af81a73 100644 --- a/Build/Sources/Sass/typo3/_main_form.scss +++ b/Build/Sources/Sass/typo3/_main_form.scss @@ -10,44 +10,19 @@ position: relative; } -.form-group { - .panel, - .panel-group { - overflow: visible; - } -} - -// -// Form group validation states -// -.form-group.has-error { - .btn-toolbar { - label:before { - font-family: inherit; - font-size: inherit; - margin-right: inherit; - text-align: inherit; - content: ''; - color: inherit; - display: block; - } - } -} - // // Form Irre // .form-irre-header { display: flex; align-items: center; - margin: -5px; user-select: none; + gap: .25rem; } .form-irre-header-cell { vertical-align: middle; white-space: nowrap; - padding: 5px; } .form-irre-header-button { @@ -58,15 +33,14 @@ background: transparent; border: 0; width: 100%; - margin-inline-start: -15px; - padding-inline-start: 20px; + padding: 0; + gap: .25rem; } .form-irre-header-body { width: 100%; font-weight: normal; white-space: normal; - padding-inline-start: 5px; dl, dd, @@ -80,11 +54,13 @@ } .form-irre-header-thumbnail { - padding-inline-end: 5px; + padding-inline-end: .25rem; } .form-irre-header-control { - cursor: auto; + display: flex; + align-items: center; + gap: .25rem; } // diff --git a/Build/Sources/TypeScript/backend/element/collapsible-element.ts b/Build/Sources/TypeScript/backend/element/collapsible-element.ts deleted file mode 100644 index 673d8347ef13..000000000000 --- a/Build/Sources/TypeScript/backend/element/collapsible-element.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -import RegularEvent from '@typo3/core/event/regular-event'; -import Icons from '@typo3/backend/icons'; - -enum IconIdentifier { - collapse = 'actions-view-list-collapse', - expand = 'actions-view-list-expand', -} - -/** - * Module: @typo3/backend/element/collapsible-element - * - * Functionality for collapsible elements like accordions and panels - * - * @example - * <typo3-backend-collapsible> - * ... - * </typo3-backend-collapsible> - * - * This is based on W3C custom elements ("web components") specification, see - * https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements - */ -class CollapsibleElement extends HTMLElement { - - public connectedCallback(): void { - this.registerEventHandler(); - } - - private registerEventHandler(): void { - new RegularEvent('click', this.toggleGroup).delegateTo(this, 'button[data-bs-toggle="collapse"]'); - } - - private toggleGroup(e: MouseEvent, targetEl: HTMLElement): void { - e.preventDefault(); - - const isExpanded = targetEl.ariaExpanded === 'true'; - const collapseIcon = targetEl.querySelector('.collapseIcon'); - const toggleIcon = isExpanded ? IconIdentifier.collapse : IconIdentifier.expand; - - Icons.getIcon(toggleIcon, Icons.sizes.small).then((icon: string): void => { - collapseIcon.innerHTML = icon; - }); - } -} - -window.customElements.define('typo3-backend-collapsible', CollapsibleElement); diff --git a/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts index 755e94841032..c6377ca496b7 100644 --- a/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts +++ b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts @@ -549,7 +549,7 @@ class FilesControlContainer extends HTMLElement { } new RegularEvent('transitionend', (): void => { - recordContainer.parentElement.removeChild(recordContainer); + recordContainer.remove(); FormEngineValidation.validate(this.container); }).bindTo(recordContainer); diff --git a/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts b/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts index 514890c8a93d..6cf341985521 100644 --- a/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts +++ b/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts @@ -272,19 +272,20 @@ class ExtensionScanner extends AbstractInteractableModule { fileData.matches.forEach((match: Match): void => { hitFound = true; const aMatch = modalContent.querySelector(hitTemplate + ' .panel').cloneNode(true) as HTMLElement; - aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head').setAttribute('href', '#collapse' + match.uniqueId); + aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head').setAttribute('data-bs-target', '#collapse' + match.uniqueId); + aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head').setAttribute('aria-controls', 'collapse' + match.uniqueId); aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-body').setAttribute('id', 'collapse' + match.uniqueId); aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-filename').innerText = file; aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-message').innerText = match.message; if (match.indicator === 'strong') { - aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head .badges') + aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head .t3js-extensionScanner-hit-badges') .innerHTML += '<span class="badge badge-danger" title="Reliable match, false positive unlikely">strong</span>'; } else { - aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head .badges') + aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head .t3js-extensionScanner-hit-badges') .innerHTML += '<span class="badge badge-warning" title="Probable match, but can be a false positive">weak</span>'; } if (match.silenced === true) { - aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head .badges') + aMatch.querySelector<HTMLElement>('.t3js-extensionScanner-hit-file-panel-head .t3js-extensionScanner-hit-badges') .innerHTML += '<span class="badge badge-info" title="Match has been annotated by extension author' + ' as false positive match">silenced</span>'; } @@ -293,8 +294,9 @@ class ExtensionScanner extends AbstractInteractableModule { if (Array.isArray(match.restFiles)) { match.restFiles.forEach((restFile: RestFile): void => { const aRest = modalContent.querySelector(restTemplate + ' .panel').cloneNode(true) as HTMLElement; - aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-panel-head').setAttribute('href', '#collapse' + restFile.uniqueId); - aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-panel-head .badge').innerText = restFile.version; + aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-panel-head').setAttribute('data-bs-target', '#collapse' + restFile.uniqueId); + aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-panel-head').setAttribute('aria-controls', 'collapse' + restFile.uniqueId); + aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-panel-head .t3js-extensionScanner-hit-rest-badge').innerText = restFile.version; aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-panel-body').setAttribute('id', 'collapse' + restFile.uniqueId); aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-headline').innerText = restFile.headline; aRest.querySelector<HTMLElement>('.t3js-extensionScanner-hit-rest-body').innerText = restFile.content; diff --git a/Build/Sources/TypeScript/install/router.ts b/Build/Sources/TypeScript/install/router.ts index 10a786bbafbd..5d7ef257e500 100644 --- a/Build/Sources/TypeScript/install/router.ts +++ b/Build/Sources/TypeScript/install/router.ts @@ -248,16 +248,15 @@ class Router { + '</div>' + '</div>' + '<div class="panel-group" role="tablist" aria-multiselectable="true">' - + '<div class="panel panel-default searchhit">' - + '<div class="panel-heading" role="tab" id="heading-error">' - + '<h3 class="panel-title">' - + '<a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapse-error" aria-expanded="true" ' - + 'aria-controls="collapse-error" class="collapsed">' + + '<div class="panel panel-default">' + + '<h3 class="panel-heading" role="tab" id="heading-error">' + + '<div class="panel-heading-row">' + + '<button type="button" data-bs-toggle="collapse" data-bs-parent="#accordion" data-bs-target="#collapse-error" aria-expanded="true" aria-controls="collapse-error" class="panel-button collapsed">' + + '<div class="panel-title"><strong>Ajax error</strong></div>' + '<span class="caret"></span>' - + '<strong>Ajax error</strong>' - + '</a>' - + '</h3>' + + '</button>' + '</div>' + + '</h3>' + '<div id="collapse-error" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-error">' + '<div class="panel-body">' + (await error.response.text()) diff --git a/typo3/sysext/backend/Classes/Form/Container/FlexFormSectionContainer.php b/typo3/sysext/backend/Classes/Form/Container/FlexFormSectionContainer.php index a5fc01b415af..2a81463236cf 100644 --- a/typo3/sysext/backend/Classes/Form/Container/FlexFormSectionContainer.php +++ b/typo3/sysext/backend/Classes/Form/Container/FlexFormSectionContainer.php @@ -122,28 +122,26 @@ class FlexFormSectionContainer extends AbstractContainer // Wrap child stuff $toggleAll = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.toggleall')); $html = []; - $html[] = '<div class="panel panel-tab">'; - $html[] = '<div class="panel-body">'; - $html[] = '<div class="t3-form-field-container t3-form-flex" id="' . htmlspecialchars($containerId) . '" data-section="#' . htmlspecialchars($hashedSectionContainerId) . '">'; - $html[] = '<div class="t3-form-field-label-flexsection">'; - $html[] = '<h4>'; - $html[] = htmlspecialchars($sectionTitle); - $html[] = '</h4>'; - $html[] = '</div>'; - $html[] = '<div class="form-group">'; - $html[] = '<button class="btn btn-default t3-form-flexsection-toggle" type="button" title="' . $toggleAll . '" data-expand-all="false">'; - $html[] = $this->iconFactory->getIcon('actions-move-right', IconSize::SMALL)->render() . $toggleAll; - $html[] = '</button>'; - $html[] = '</div>'; - $html[] = '<div'; - $html[] = 'id="' . htmlspecialchars($hashedSectionContainerId) . '"'; - $html[] = 'class="panel-group panel-hover t3-form-field-container-flexsection t3-flex-container"'; - $html[] = 'data-t3-flex-allow-restructure="' . ($userHasAccessToDefaultLanguage ? '1' : '0') . '"'; - $html[] = '>'; - $html[] = $resultArray['html']; - $html[] = '</div>'; - $html[] = implode(LF, $createElementsHtml); + $html[] = '<div class="form-section">'; + $html[] = '<div class="t3-form-field-container t3-form-flex" id="' . htmlspecialchars($containerId) . '" data-section="#' . htmlspecialchars($hashedSectionContainerId) . '">'; + $html[] = '<div class="t3-form-field-label-flexsection">'; + $html[] = '<h4>'; + $html[] = htmlspecialchars($sectionTitle); + $html[] = '</h4>'; $html[] = '</div>'; + $html[] = '<div class="form-group">'; + $html[] = '<button class="btn btn-default t3-form-flexsection-toggle" type="button" title="' . $toggleAll . '" data-expand-all="false">'; + $html[] = $this->iconFactory->getIcon('actions-move-right', IconSize::SMALL)->render() . $toggleAll; + $html[] = '</button>'; + $html[] = '</div>'; + $html[] = '<div'; + $html[] = 'id="' . htmlspecialchars($hashedSectionContainerId) . '"'; + $html[] = 'class="panel-group panel-hover t3-form-field-container-flexsection t3-flex-container"'; + $html[] = 'data-t3-flex-allow-restructure="' . ($userHasAccessToDefaultLanguage ? '1' : '0') . '"'; + $html[] = '>'; + $html[] = $resultArray['html']; + $html[] = '</div>'; + $html[] = implode(LF, $createElementsHtml); $html[] = '</div>'; $html[] = '</div>'; diff --git a/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php b/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php index f468c05f1493..9c32ba0767da 100644 --- a/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/SelectCheckBoxElement.php @@ -152,7 +152,7 @@ class SelectCheckBoxElement extends AbstractFormElement $fieldWizardHtml = $fieldWizardResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false); - $html[] = '<typo3-backend-collapsible class="formengine-field-item t3js-formengine-field-item" data-formengine-validation-rules="' . htmlspecialchars($this->getValidationDataAsJsonString($config)) . '">'; + $html[] = '<div class="formengine-field-item t3js-formengine-field-item" data-formengine-validation-rules="' . htmlspecialchars($this->getValidationDataAsJsonString($config)) . '">'; $html[] = $fieldInformationHtml; $html[] = '<div class="form-wizards-wrap">'; $html[] = '<div class="form-wizards-item-element">'; @@ -171,21 +171,21 @@ class SelectCheckBoxElement extends AbstractFormElement $html[] = '<div id="' . $groupId . '" class="panel panel-default" data-multi-record-selection-identifier="' . $groupId . '">'; if ($hasGroupHeader) { - $expanded = ($config['appearance']['expandAll'] ?? false) ? 'true' : 'false'; - $icon = '<span class="collapseIcon">' . $this->iconFactory->getIcon((($config['appearance']['expandAll'] ?? false) ? 'actions-view-list-collapse' : 'actions-view-list-expand'), IconSize::SMALL)->render() . '</span>'; - - $html[] = '<button type="button" class="panel-heading panel-heading-button" aria-expanded="' . $expanded . '"'; - $html[] = ' aria-controls="' . $groupCollapsibleId . '" data-bs-target="#' . $groupCollapsibleId . '" data-bs-toggle="collapse">'; - $html[] = '<span class="flex-grow-1 align-self-center">'; - $html[] = $group['header']['icon']; - $html[] = htmlspecialchars($group['header']['title']); - $html[] = '</span>'; - $html[] = '<div class="panel-actions ml-auto">'; - $html[] = '<span class="btn btn-sm btn-default">'; - $html[] = $icon; - $html[] = '</span>'; + $expanded = ($config['appearance']['expandAll'] ?? false); + $html[] = '<div class="panel-heading" role="tab">'; + $html[] = '<div class="panel-heading-row">'; + $html[] = '<button type="button" class="panel-button' . (!$expanded ? ' collapsed' : '') . '" aria-expanded="' . ($expanded ? 'true' : 'false') . '"'; + $html[] = ' aria-controls="' . $groupCollapsibleId . '" data-bs-target="#' . $groupCollapsibleId . '" data-bs-toggle="collapse">'; + $html[] = '<div class="panel-icon">'; + $html[] = $group['header']['icon']; + $html[] = '</div>'; + $html[] = '<div class="panel-title">'; + $html[] = htmlspecialchars($group['header']['title']); + $html[] = '</div>'; + $html[] = '<span class="caret"></span>'; + $html[] = '</button>'; + $html[] = '</div>'; $html[] = '</div>'; - $html[] = '</button>'; } if (!empty($group['items']) && is_array($group['items'])) { $tableRows = []; @@ -237,7 +237,7 @@ class SelectCheckBoxElement extends AbstractFormElement } $html[] = '<div class="table-fit">'; - $html[] = '<table class="table table-transparent table-hover">'; + $html[] = '<table class="table table-hover">'; if (!$readOnly) { // Add table header with actions, in case the element is not readOnly $html[] = '<thead>'; @@ -249,7 +249,6 @@ class SelectCheckBoxElement extends AbstractFormElement // Add JavaScript module. This is only needed, in case the element // is not readOnly, since otherwise no checkbox changes take place. - $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/element/collapsible-element.js'); $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/multi-record-selection.js'); } $html[] = '<tbody>' . implode(LF, $tableRows) . '</tbody>'; @@ -269,7 +268,7 @@ class SelectCheckBoxElement extends AbstractFormElement $html[] = '</div>'; } $html[] = '</div>'; - $html[] = '</typo3-backend-collapsible>'; + $html[] = '</div>'; $resultArray['html'] = $this->wrapWithFieldsetAndLegend(implode(LF, $html)); return $resultArray; diff --git a/typo3/sysext/backend/Classes/Form/Element/TablePermissionElement.php b/typo3/sysext/backend/Classes/Form/Element/TablePermissionElement.php index e1d16bed5cf7..11558a71f464 100644 --- a/typo3/sysext/backend/Classes/Form/Element/TablePermissionElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/TablePermissionElement.php @@ -136,8 +136,6 @@ final class TablePermissionElement extends AbstractFormElement $html[] = '<input type="hidden" name="' . $selectStateFieldName . '" value="' . implode(',', $currentValue['select']) . '">'; } - $html[] = '<div id="' . $elementId . '" class="panel panel-default">'; - $tableRows = []; foreach ($tablesConfiguration as $tableConfiguration) { $tableRows[] = '<tr role="radiogroup" aria-labelledby="' . $tableConfiguration['label']['id'] . '">'; @@ -158,8 +156,9 @@ final class TablePermissionElement extends AbstractFormElement $tableRows[] = '</tr>'; } + $html[] = '<div id="' . $elementId . '">'; $html[] = '<div class="table-fit">'; - $html[] = '<table class="table table-transparent table-hover">'; + $html[] = '<table class="table table-hover">'; $html[] = '<thead>'; $html[] = '<tr>'; foreach (self::Permissions as $permission) { @@ -175,12 +174,13 @@ final class TablePermissionElement extends AbstractFormElement $html[] = '</table>'; $html[] = '</div>'; $html[] = '</div>'; + $html[] = '</div>'; if (!$readOnly) { $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/form-engine/element/table-permission-element.js'); $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/multi-record-selection.js'); } - $html[] = '</div>'; + $html[] = '</typo3-formengine-element-tablepermission>'; $resultArray['html'] = $this->wrapWithFieldsetAndLegend(implode(LF, $html)); diff --git a/typo3/sysext/backend/Resources/Private/Layouts/Login.html b/typo3/sysext/backend/Resources/Private/Layouts/Login.html index c5c20de29b76..879562a37ff7 100644 --- a/typo3/sysext/backend/Resources/Private/Layouts/Login.html +++ b/typo3/sysext/backend/Resources/Private/Layouts/Login.html @@ -124,11 +124,18 @@ <f:render partial="Login/LoginNews" arguments="{_all}" /> <footer class="card-footer"> <div class="typo3-login-copyright-wrap"> - <a href="#loginCopyright" class="typo3-login-copyright-link t3js-login-copyright-link collapsed" data-bs-toggle="collapse" role="button" aria-expanded="false" aria-controls="loginCopyright"> + <button + type="button" + class="typo3-login-copyright-link t3js-login-copyright-link collapsed" + data-bs-target="#loginCopyright" + data-bs-toggle="collapse" + aria-expanded="false" + aria-controls="loginCopyright" + > <span><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang.xlf:login.copyrightLink" /></span> <f:comment>the image within the button is only decorative</f:comment> <img src="{images.typo3}" alt="" width="70" height="20" /> - </a> + </button> <div id="loginCopyright" class="collapse"> <div class="typo3-login-copyright-text"> <p> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html b/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html index 31b5567c29af..93ec7be25eaf 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html +++ b/typo3/sysext/backend/Resources/Private/Templates/ContentElement/ElementInformation.html @@ -11,8 +11,7 @@ <f:be.pageRenderer includeJavaScriptModules="{ 0: '@typo3/backend/element/immediate-action-element.js', - 1: '@typo3/backend/element/collapsible-element.js', - 2: '@typo3/backend/utility/collapse-state-persister.js', + 1: '@typo3/backend/utility/collapse-state-persister.js', }" /> <f:variable name="args" value="{0: 'web', 1: extraFields.uid.value}" /> @@ -118,43 +117,39 @@ </f:if> <h2><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.general" /></h2> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="fieldValues-panel" - data-bs-target="#fieldValues-panel" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.fieldValues" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="fieldValues-panel" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="table-fit table-fit-wrap"> - <table class="table table-striped table-hover"> - <tbody> - <f:for each="{fields}" as="field"> - <tr> - <th class="col-fieldname">{field.fieldLabel}</th> - <td class="col-word-break">{field.fieldValue}</td> - </tr> - </f:for> - </tbody> - </table> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#fieldValues-panel" + aria-controls="fieldValues-panel" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.fieldValues" /> + </div> + <span class="caret"></span> + </button> + </div> + </div> + <div id="fieldValues-panel" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="table-fit table-fit-wrap"> + <table class="table table-striped table-hover"> + <tbody> + <f:for each="{fields}" as="field"> + <tr> + <th class="col-fieldname">{field.fieldLabel}</th> + <td class="col-word-break">{field.fieldValue}</td> + </tr> + </f:for> + </tbody> + </table> </div> </div> - </typo3-backend-collapsible> + </div> <f:if condition="{returnUrl}"> <a class="btn btn-primary" href="{returnUrl}" title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:back')}"> @@ -168,104 +163,96 @@ </f:if> <f:if condition="{refLines}"> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="referencesToThisItem-panel" - data-bs-target="#referencesToThisItem-panel" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.referencesToThisItem" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="referencesToThisItem-panel" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="table-fit"> - <table class="table table-striped table-hover"> - <thead> - <tr> - <th class="col-icon"></th> - <th class="col-recordtitle"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.title" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.table" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.field" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.flexpointer" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.softrefKey" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.sorting" /></th> - <th class="col-control"></th> - </tr> - </thead> - <tbody> - <f:for each="{refLines}" as="refLine"> - <f:render section="refLineRow" arguments="{line: refLine, maxTitleLength: maxTitleLength}" /> - </f:for> - </tbody> - </table> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#referencesToThisItem-panel" + aria-controls="referencesToThisItem-panel" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.referencesToThisItem" /> + </div> + <span class="caret"></span> + </button> + </div> + </div> + <div id="referencesToThisItem-panel" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="table-fit"> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th class="col-icon"></th> + <th class="col-recordtitle"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.title" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.table" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.field" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.flexpointer" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.softrefKey" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.sorting" /></th> + <th class="col-control"></th> + </tr> + </thead> + <tbody> + <f:for each="{refLines}" as="refLine"> + <f:render section="refLineRow" arguments="{line: refLine, maxTitleLength: maxTitleLength}" /> + </f:for> + </tbody> + </table> </div> </div> - </typo3-backend-collapsible> + </div> </f:if> <f:if condition="{refFromLines}"> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="referencesFromThisItem-panel" - data-bs-target="#referencesFromThisItem-panel" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.referencesFromThisItem" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="referencesFromThisItem-panel" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="table-fit"> - <table class="table table-striped table-hover"> - <thead> - <tr> - <th class="col-icon"></th> - <th class="col-recordtitle"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.title" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.table" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.field" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.flexpointer" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.softrefKey" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.sorting" /></th> - <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.refString" /></th> - <th class="col-control"></th> - </tr> - </thead> - <tbody> - <f:for each="{refFromLines}" as="refFromLine"> - <f:render section="refFromLineRow" arguments="{line: refFromLine, maxTitleLength: maxTitleLength}" /> - </f:for> - </tbody> - </table> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#referencesFromThisItem-panel" + aria-controls="referencesFromThisItem-panel" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.referencesFromThisItem" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="referencesFromThisItem-panel" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="table-fit"> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th class="col-icon"></th> + <th class="col-recordtitle"><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.title" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.table" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.uid" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.field" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.flexpointer" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.softrefKey" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.sorting" /></th> + <th><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:show_item.php.refString" /></th> + <th class="col-control"></th> + </tr> + </thead> + <tbody> + <f:for each="{refFromLines}" as="refFromLine"> + <f:render section="refFromLineRow" arguments="{line: refFromLine, maxTitleLength: maxTitleLength}" /> + </f:for> + </tbody> + </table> + </div> + </div> + </div> </f:if> </f:section> diff --git a/typo3/sysext/backend/Resources/Private/Templates/Form/ImageManipulationWizard.html b/typo3/sysext/backend/Resources/Private/Templates/Form/ImageManipulationWizard.html index bd920ff2f3a5..2c8989efd2f7 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/Form/ImageManipulationWizard.html +++ b/typo3/sysext/backend/Resources/Private/Templates/Form/ImageManipulationWizard.html @@ -11,30 +11,30 @@ <div class="panel-group" id="accordion-cropper-variants" role="tablist" aria-multiselectable="false"> <f:for each="{cropVariants}" as="cropVariant" iteration="cropVariantIterator"> <div class="panel panel-default" data-crop-variant-container="{cropVariant.id}"> - <div class="panel-heading" role="tab" id="cropper-accordion-heading-{cropVariantIterator.cycle}"> - <h4 class="panel-title"> - <a - role="button" + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button t3js-crop-variant-trigger {f:if(condition:cropVariantIterator.isFirst, then:'is-active', else:'collapsed')}" + type="button" data-bs-toggle="collapse" - href="#cropper-collapse-{cropVariantIterator.cycle}" + data-bs-target="#cropper-collapse-{cropVariantIterator.cycle}" aria-expanded="{f:if(condition:cropVariantIterator.isFirst, then:'true', else:'false')}" aria-controls="cropper-collapse-{cropVariantIterator.cycle}" - class="t3js-crop-variant-trigger {f:if(condition:cropVariantIterator.isFirst, then:'is-active', else:'collapsed')}" data-crop-variant-id="{cropVariant.id}" data-crop-variant + id="cropper-accordion-heading-{cropVariantIterator.cycle}" > - <span><core:icon identifier="actions-chevron-{f:if(condition:cropVariantIterator.isFirst, then:'up', else:'down')}" size="small" /> {cropVariant.title -> f:translate(id: cropVariant.title)}</span> - <div - class="cropper-preview-thumbnail {f:if(condition:'{image.properties.width}>{image.properties.height}', then:'wide', else: 'tall')}" - > + <span class="caret"></span> + <div class="panel-title">{cropVariant.title -> f:translate(id: cropVariant.title)}</div> + <div class="cropper-preview-thumbnail {f:if(condition:'{image.properties.width}>{image.properties.height}', then:'wide', else: 'tall')}"> <img class="cropper-preview-thumbnail-image" src="{f:uri.image(image:image, maxWidth:'300', maxHeight: '300')}"> <div class="cropper-preview-thumbnail-crop-area t3js-cropper-preview-thumbnail-crop-area"> <img src="{f:uri.image(image:image, maxWidth:'300', maxHeight: '300')}" class="cropper-preview-thumbnail-crop-image t3js-cropper-preview-thumbnail-crop-image"> <div class="cropper-preview-thumbnail-focus-area t3js-cropper-preview-thumbnail-focus-area"></div> </div> </div> - </a> - </h4> + </button> + </div> </div> <div id="cropper-collapse-{cropVariantIterator.cycle}" @@ -45,43 +45,41 @@ > <div class="panel-body"> <form class="form"> - <div class="form-group"> - <f:if condition="{cropVariant.allowedAspectRatios}"> - <label class="form-label" for="ratio-{cropVariantIterator.cycle}"> - <f:translate id="LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.aspect-ratio"/> - </label> - <div id="ratio-{cropVariantIterator.cycle}" class="ratio-buttons t3js-ratio-buttons"> - <f:for each="{cropVariant.allowedAspectRatios}" as="ratio" iteration="ratioIterator"> - <label - class="btn btn-secondary" - data-method="setAspectRatio" - data-bs-option="{ratio.id}" - title="{f:translate(id:'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.set-aspect-ratio')}" - > - <input - class="visually-hidden" - id="aspectRatio-{cropVariantIterator.cycle}-{ratioIterator.cycle}" - name="aspectRatio-{cropVariantIterator.cycle}-{ratioIterator.cycle}" - value="{cropVariant.id}" - type="radio" - /> - <span class="t3-js-ratio-title" data-ratio-id="{cropVariant.id}{ratio.id}">{ratio.title -> f:translate(id: ratio.title)}</span> <core:icon identifier="actions-check" size="small" /> - </label> - </f:for> - </div> - </f:if> - <label><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.selection" /></label> - <div class="mb-3 t3js-cropper-info-crop"></div> - <button - class="btn btn-secondary" - name="reset" - data-crop-variant="{cropVariant -> f:format.json()}" - title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.reset')}" - > - <core:icon identifier="actions-refresh" size="small" /> - {f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.reset')} - </button> - </div> + <f:if condition="{cropVariant.allowedAspectRatios}"> + <label class="form-label" for="ratio-{cropVariantIterator.cycle}"> + <f:translate id="LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.aspect-ratio"/> + </label> + <div id="ratio-{cropVariantIterator.cycle}" class="ratio-buttons t3js-ratio-buttons"> + <f:for each="{cropVariant.allowedAspectRatios}" as="ratio" iteration="ratioIterator"> + <label + class="btn btn-default" + data-method="setAspectRatio" + data-bs-option="{ratio.id}" + title="{f:translate(id:'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.set-aspect-ratio')}" + > + <input + class="visually-hidden" + id="aspectRatio-{cropVariantIterator.cycle}-{ratioIterator.cycle}" + name="aspectRatio-{cropVariantIterator.cycle}-{ratioIterator.cycle}" + value="{cropVariant.id}" + type="radio" + /> + <span class="t3-js-ratio-title" data-ratio-id="{cropVariant.id}{ratio.id}">{ratio.title -> f:translate(id: ratio.title)}</span> <core:icon identifier="actions-check" size="small" /> + </label> + </f:for> + </div> + </f:if> + <label><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.selection" /></label> + <div class="mb-3 t3js-cropper-info-crop"></div> + <button + class="btn btn-default" + name="reset" + data-crop-variant="{cropVariant -> f:format.json()}" + title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.reset')}" + > + <core:icon identifier="actions-refresh" size="small" /> + {f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_wizards.xlf:imwizard.reset')} + </button> </form> </div> </div> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Collapse.html b/typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Collapse.html deleted file mode 100644 index 1d0061f5a384..000000000000 --- a/typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Collapse.html +++ /dev/null @@ -1,49 +0,0 @@ -<html - xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" - data-namespace-typo3-fluid="true" -> -<f:be.pageRenderer - includeJavaScriptModules="{ - 0: '@typo3/backend/tabs.js' - }" -/> -<div class="panel-group" id="{id}" role="tablist" aria-multiselectable="true"> - <f:for each="{items}" as="item" iteration="iteration"> - <f:if condition="{item.content}"> - <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="{id}-{iteration.cycle}-heading"> - <a data-bs-toggle="collapse" title="{item.linkTitle}" data-bs-parent="#{id}" href="#{id}-{iteration.cycle}" aria-expanded="true" aria-controls="{id}-{iteration.cycle}"> - <f:if condition="{item.icon}"> - <f:format.raw>{item.icon}</f:format.raw> - </f:if> - {item.label} - <f:if condition="{item.requiredIcon}"> - <f:format.raw>{item.requiredIcon}</f:format.raw> - </f:if> - <f:if condition="{item.stateIcon}"> - <f:render partial="ModuleTemplate/StateIcon" arguments="{item: item}" /> - </f:if> - </a> - </div> - <div id="{id}-{iteration.cycle}" class="panel-collapse collapse{f:if(condition: '{iteration.cycle} == {defaultTabIndex}', then: ' in')}" role="tabpanel" aria-labelledby="{id}-{iteration.cycle}-heading"> - <f:if condition="{item.description}"> - <div class="panel-body"> - <p><f:format.nl2br>{item.description}</f:format.nl2br></p> - </div> - </f:if> - <f:if condition="{wrapContent}"> - <f:then> - <div class="panel-body"> - <f:format.raw>{item.content}</f:format.raw> - </div> - </f:then> - <f:else> - <f:format.raw>{item.content}</f:format.raw> - </f:else> - </f:if> - </div> - </div> - </f:if> - </f:for> -</div> -</html> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Tabs.html b/typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Tabs.html deleted file mode 100644 index 5562df8490fb..000000000000 --- a/typo3/sysext/backend/Resources/Private/Templates/ModuleTemplate/Tabs.html +++ /dev/null @@ -1,11 +0,0 @@ -<html - xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" - data-namespace-typo3-fluid="true" -> -<f:be.pageRenderer - includeJavaScriptModules="{ - 0: '@typo3/backend/tabs.js' - }" -/> -<f:render partial="ModuleTemplate/Tabs" arguments="{_all}" /> -</html> diff --git a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html index e0fe055c3a27..9b113d069703 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html +++ b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Active.html @@ -190,26 +190,21 @@ <f:section name="Conditions"> <div class="panel panel-default"> - <div class="panel-heading" role="tab"> - <f:if condition="{conditionActiveCount}"> - <f:then> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="pagetsconfig-active-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#pagetsconfig-active-conditions-body" - aria-expanded="false" - aria-controls="pagetsconfig-active-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_active.panel.header.conditions"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> + <h3 class="panel-heading" role="tab" id="pagetsconfig-active-conditions-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#pagetsconfig-active-conditions-body" + aria-controls="pagetsconfig-active-conditions-body" + aria-expanded="false" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_active.panel.header.conditions"/></strong> + </div> + <f:if condition="{conditionActiveCount}"> + <div class="panel-badge"> <span class="badge badge-info"> <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_active.panel.info.conditionActiveCount.{f:if(condition: '{conditionActiveCount} > 1', then:'multiple', else: 'single')}" @@ -217,25 +212,11 @@ /> </span> </div> - </div> - </f:then> - <f:else> - <h3 class="panel-title" id="pagetsconfig-active-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#pagetsconfig-active-conditions-body" - aria-expanded="false" - aria-controls="pagetsconfig-active-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_active.panel.header.conditions"/></strong> - </a> - </h3> - </f:else> - </f:if> - </div> + </f:if> + <span class="caret"></span> + </button> + </div> + </h3> <div class="panel-collapse collapse" id="pagetsconfig-active-conditions-body" @@ -290,29 +271,27 @@ <f:section name="TreePanel"> <div class="panel panel-default"> - <div class="panel-heading"> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="pagetsconfig-active-{type}-ast-heading"> - <a - href="#" - class="collapsed" - id="panel-tree-heading-{type}" - data-bs-toggle="collapse" - data-bs-target="#pagetsconfig-active-{type}-ast-body" - aria-expanded="false" - aria-controls="pagetsconfig-active-{type}-ast-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_active.panel.header.configuration"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> - <span class="badge badge-success hidden t3js-collapse-states-search-numberOfSearchMatches"></span> - </div> + <h3 class="panel-heading" role="tab" id="pagetsconfig-active-{type}-ast-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#pagetsconfig-active-{type}-ast-body" + aria-controls="pagetsconfig-active-{type}-ast-body" + aria-expanded="false" + id="panel-tree-heading-{type}" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_active.panel.header.configuration"/></strong> + </div> + <div class="panel-heading-badge"> + <span class="badge badge-success hidden t3js-collapse-states-search-numberOfSearchMatches"></span> + </div> + <span class="caret"></span> + </button> </div> - </div> + </h3> <div id="pagetsconfig-active-{type}-ast-body" class="panel-collapse collapse" diff --git a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html index 0c7daf0c4f88..ca2635a5160d 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html +++ b/typo3/sysext/backend/Resources/Private/Templates/PageTsConfig/Includes.html @@ -83,14 +83,23 @@ <f:section name="TreePanel"> <div class="panel panel-default"> - <div class="panel-heading"> - <h3 class="panel-title" id="pagetsconfig-includes-{type}-tree-heading"> - <a href="#" class="collapsed" data-bs-toggle="collapse" data-bs-target="#pagetsconfig-includes-{type}-tree-body" aria-expanded="false" aria-controls="pagetsconfig-includes-{type}-tree-body"> + <h3 class="panel-heading" role="tab" id="pagetsconfig-includes-{type}-tree-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#pagetsconfig-includes-{type}-tree-body" + aria-controls="pagetsconfig-includes-{type}-tree-body" + aria-expanded="false" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.header.configuration"/></strong> + </div> <span class="caret"></span> - <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.header.configuration"/></strong> - </a> - </h3> - </div> + </button> + </div> + </h3> <div id="pagetsconfig-includes-{type}-tree-body" class="panel-collapse collapse" data-persist-collapse-state="true" aria-labelledby="pagetsconfig-includes-{type}-tree-heading"> <div class="panel-body panel-body-overflow"> <ul class="treelist"> @@ -224,33 +233,31 @@ <f:section name="SyntaxErrors"> <f:if condition="{errors}"> <div class="panel panel-default"> - <div class="panel-heading"> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="pagetsconfig-includes-errors-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#pagetsconfig-includes-errors-body" - aria-expanded="false" - aria-controls="pagetsconfig-includes-errors-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.header.syntaxErrors"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> - <span class="badge badge-warning"> - <f:translate - key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.info.syntaxErrorCount.{f:if(condition: '{errorCount} > 1', then:'multiple', else: 'single')}" - arguments="{0: errorCount}" - /> - </span> - </div> + <h3 class="panel-heading" role="tab" id="pagetsconfig-includes-errors-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#pagetsconfig-includes-errors-body" + aria-controls="pagetsconfig-includes-errors-body" + aria-expanded="false" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.header.syntaxErrors"/></strong> + </div> + <div class="panel-badge"> + <span class="badge badge-warning"> + <f:translate + key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.info.syntaxErrorCount.{f:if(condition: '{errorCount} > 1', then:'multiple', else: 'single')}" + arguments="{0: errorCount}" + /> + </span> + </div> + <span class="caret"></span> + </button> </div> - </div> + </h3> <div id="pagetsconfig-includes-errors-body" class="panel-collapse collapse" data-persist-collapse-state="true" aria-labelledby="pagetsconfig-includes-errors-heading"> <div class="panel-body"> <f:for each="{errors}" as="error"> @@ -285,26 +292,22 @@ <f:section name="Conditions"> <f:if condition="{conditions}"> <div class="panel panel-default"> - <div class="panel-heading" role="tab"> - <f:if condition="{conditionActiveCount}"> - <f:then> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="pagetsconfig-includes-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#pagetsconfig-includes-conditions-body" - aria-expanded="false" - aria-controls="pagetsconfig-includes-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.header.conditions"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> + <h3 class="panel-heading" role="tab" id="pagetsconfig-includes-conditions-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#pagetsconfig-includes-conditions-body" + aria-controls="pagetsconfig-includes-conditions-body" + aria-expanded="false" + id="panel-tree-heading-{type}" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.header.conditions"/></strong> + </div> + <f:if condition="{conditionActiveCount}"> + <div class="panel-badge"> <span class="badge badge-info"> <f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.info.conditionActiveCount.{f:if(condition: '{conditionActiveCount} > 1', then:'multiple', else: 'single')}" @@ -312,25 +315,11 @@ /> </span> </div> - </div> - </f:then> - <f:else> - <h3 class="panel-title" id="pagetsconfig-includes-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#pagetsconfig-includes-conditions-body" - aria-expanded="false" - aria-controls="pagetsconfig-includes-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf:module.pagetsconfig_includes.panel.header.conditions"/></strong> - </a> - </h3> - </f:else> - </f:if> - </div> + </f:if> + <span class="caret"></span> + </button> + </div> + </h3> <div class="panel-collapse collapse" id="pagetsconfig-includes-conditions-body" diff --git a/typo3/sysext/backend/Resources/Public/Css/backend.css b/typo3/sysext/backend/Resources/Public/Css/backend.css index 4ae780a84e79..f6f5e3254e8d 100644 --- a/typo3/sysext/backend/Resources/Public/Css/backend.css +++ b/typo3/sysext/backend/Resources/Public/Css/backend.css @@ -904,7 +904,7 @@ to{transform:rotate(360deg)} @media (prefers-reduced-motion:reduce){ .spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s} } -.clearfix::after,.typo3-login-copyright-link::after{display:block;clear:both;content:""} +.clearfix::after{display:block;clear:both;content:""} .text-bg-primary{color:#fff!important;background-color:RGBA(var(--bs-primary-rgb),var(--bs-bg-opacity,1))!important} .text-bg-secondary{color:#fff!important;background-color:RGBA(var(--bs-secondary-rgb),var(--bs-bg-opacity,1))!important} .text-bg-success{color:#fff!important;background-color:RGBA(var(--bs-success-rgb),var(--bs-bg-opacity,1))!important} @@ -2306,7 +2306,6 @@ to{transform:rotate(360deg)} .d-print-none{display:none!important} } .hidden,.hide{display:none!important} -.caret{display:inline-block;width:0;height:0;margin-left:.125rem;vertical-align:middle;border-top:.25rem dashed #5a5a5a;border-right:.25rem solid transparent;border-left:.25rem solid transparent} .page-header{padding:.625rem 1rem;margin:2rem 0 1rem;border-bottom:1px solid #5a5a5a} .modal-backdrop.in{opacity:.5} div.typo3-localizationLink,div.typo3-newRecordLink,div.typo3-synchronizationLink{display:inline} @@ -2468,7 +2467,7 @@ button[aria-expanded=true]:not(:disabled) .modulemenu-indicator:after{transform: .scaffold-modulemenu-expanded .modulemenu-indicator{display:block!important} .scaffold-modulemenu-expanded .modulemenu-name{position:static;margin:0;margin-inline-start:1em;width:auto;height:auto} :root{--token-color-neutral-base:#000;--token-color-neutral-0:white;--token-color-neutral-3:#f7f7f7;--token-color-neutral-4:whitesmoke;--token-color-neutral-5:#f2f2f2;--token-color-neutral-10:#e6e6e6;--token-color-neutral-15:#d9d9d9;--token-color-neutral-20:#cccccc;--token-color-neutral-25:#bfbfbf;--token-color-neutral-30:#b3b3b3;--token-color-neutral-35:#a6a6a6;--token-color-neutral-40:#999999;--token-color-neutral-45:#8c8c8c;--token-color-neutral-50:gray;--token-color-neutral-55:#737373;--token-color-neutral-60:#666666;--token-color-neutral-65:#595959;--token-color-neutral-70:#4d4d4d;--token-color-neutral-75:#404040;--token-color-neutral-80:#333333;--token-color-neutral-85:#262626;--token-color-neutral-90:#1a1a1a;--token-color-neutral-95:#0d0d0d;--token-color-neutral-96:#0a0a0a;--token-color-neutral-97:#080808;--token-color-neutral-100:black;--token-color-blue-base:#05c;--token-color-blue-3:#f0f6ff;--token-color-blue-4:#ebf3ff;--token-color-blue-5:#e6f0ff;--token-color-blue-10:#cce1ff;--token-color-blue-15:#b3d2ff;--token-color-blue-20:#99c4ff;--token-color-blue-25:#80b5ff;--token-color-blue-30:#66a6ff;--token-color-blue-35:#4d97ff;--token-color-blue-40:#3388ff;--token-color-blue-45:#1a79ff;--token-color-blue-50:#006aff;--token-color-blue-55:#0060e6;--token-color-blue-60:#0055cc;--token-color-blue-65:#004ab3;--token-color-blue-70:#004099;--token-color-blue-75:#003580;--token-color-blue-80:#002b66;--token-color-blue-85:#00204d;--token-color-blue-90:#001533;--token-color-blue-95:#000b1a;--token-color-blue-96:#000914;--token-color-blue-97:#00060f;--token-color-purple-base:#5e4db2;--token-color-purple-3:#f5f4fa;--token-color-purple-4:#f2f1f9;--token-color-purple-5:#efedf7;--token-color-purple-10:#dfdbf0;--token-color-purple-15:#cfcae8;--token-color-purple-20:#bfb8e0;--token-color-purple-25:#afa6d9;--token-color-purple-30:#9e94d1;--token-color-purple-35:#8e82c9;--token-color-purple-40:#7e71c1;--token-color-purple-45:#6e5fba;--token-color-purple-50:#5e4db2;--token-color-purple-55:#5545a0;--token-color-purple-60:#4b3e8e;--token-color-purple-65:#42367d;--token-color-purple-70:#382e6b;--token-color-purple-75:#2f2759;--token-color-purple-80:#261f47;--token-color-purple-85:#1c1735;--token-color-purple-90:#130f24;--token-color-purple-95:#090812;--token-color-purple-96:#08060e;--token-color-purple-97:#06050b;--token-color-teal-base:#abdced;--token-color-teal-3:#f2fafc;--token-color-teal-4:#eef8fb;--token-color-teal-5:#eaf6fb;--token-color-teal-10:#d5eef6;--token-color-teal-15:#c0e5f2;--token-color-teal-20:#abdced;--token-color-teal-25:#96d3e9;--token-color-teal-30:#81cbe4;--token-color-teal-35:#6cc2e0;--token-color-teal-40:#57b9db;--token-color-teal-45:#42b0d7;--token-color-teal-50:#2da8d2;--token-color-teal-55:#2997bd;--token-color-teal-60:#2486a8;--token-color-teal-65:#207593;--token-color-teal-70:#1b657e;--token-color-teal-75:#175469;--token-color-teal-80:#124354;--token-color-teal-85:#0e323f;--token-color-teal-90:#09222a;--token-color-teal-95:#051115;--token-color-teal-96:#040d11;--token-color-teal-97:#030a0d;--token-color-green-base:#247554;--token-color-green-3:#f3fbf8;--token-color-green-4:#effaf6;--token-color-green-5:#ecf9f4;--token-color-green-10:#d8f3e8;--token-color-green-15:#c5eddd;--token-color-green-20:#b1e7d1;--token-color-green-25:#9ee1c6;--token-color-green-30:#8adbba;--token-color-green-35:#77d5af;--token-color-green-40:#63cfa3;--token-color-green-45:#50c998;--token-color-green-50:#3cc38c;--token-color-green-55:#36b07e;--token-color-green-60:#309c70;--token-color-green-65:#2a8962;--token-color-green-70:#247554;--token-color-green-75:#1e6246;--token-color-green-80:#184e38;--token-color-green-85:#123b2a;--token-color-green-90:#0c271c;--token-color-green-95:#06140e;--token-color-green-96:#05100b;--token-color-green-97:#040c08;--token-color-magenta-base:#c6398f;--token-color-magenta-3:#fcf3f8;--token-color-magenta-4:#faeff6;--token-color-magenta-5:#f9ebf4;--token-color-magenta-10:#f4d7e9;--token-color-magenta-15:#eec4dd;--token-color-magenta-20:#e8b0d2;--token-color-magenta-25:#e39cc7;--token-color-magenta-30:#dd88bc;--token-color-magenta-35:#d774b1;--token-color-magenta-40:#d161a5;--token-color-magenta-45:#cc4d9a;--token-color-magenta-50:#c6398f;--token-color-magenta-55:#b23381;--token-color-magenta-60:#9e2e72;--token-color-magenta-65:#8b2864;--token-color-magenta-70:#772256;--token-color-magenta-75:#631d48;--token-color-magenta-80:#4f1739;--token-color-magenta-85:#3b112b;--token-color-magenta-90:#280b1d;--token-color-magenta-95:#14060e;--token-color-magenta-96:#10050b;--token-color-magenta-97:#0c0309;--token-color-yellow-base:#fc3;--token-color-yellow-3:#fffbf0;--token-color-yellow-4:#fffaeb;--token-color-yellow-5:#fff9e6;--token-color-yellow-10:#fff2cc;--token-color-yellow-15:#ffecb3;--token-color-yellow-20:#ffe699;--token-color-yellow-25:#ffdf80;--token-color-yellow-30:#ffd966;--token-color-yellow-35:#ffd24d;--token-color-yellow-40:#ffcc33;--token-color-yellow-45:#ffc61a;--token-color-yellow-50:#ffbf00;--token-color-yellow-55:#e6ac00;--token-color-yellow-60:#cc9900;--token-color-yellow-65:#b38600;--token-color-yellow-70:#997300;--token-color-yellow-75:#806000;--token-color-yellow-80:#664d00;--token-color-yellow-85:#4d3900;--token-color-yellow-90:#332600;--token-color-yellow-95:#1a1300;--token-color-yellow-96:#140f00;--token-color-yellow-97:#0f0b00;--token-color-orange-base:#ee6d11;--token-color-orange-3:#fef6f1;--token-color-orange-4:#fef3ec;--token-color-orange-5:#fdf0e7;--token-color-orange-10:#fce2cf;--token-color-orange-15:#fad3b8;--token-color-orange-20:#f8c5a0;--token-color-orange-25:#f7b688;--token-color-orange-30:#f5a770;--token-color-orange-35:#f39958;--token-color-orange-40:#f18a41;--token-color-orange-45:#f07c29;--token-color-orange-50:#ee6d11;--token-color-orange-55:#d6620f;--token-color-orange-60:#be570e;--token-color-orange-65:#a74c0c;--token-color-orange-70:#8f410a;--token-color-orange-75:#773709;--token-color-orange-80:#5f2c07;--token-color-orange-85:#472105;--token-color-orange-90:#301603;--token-color-orange-95:#180b02;--token-color-orange-96:#130901;--token-color-orange-97:#0e0701;--token-color-red-base:#d13a2e;--token-color-red-3:#fcf3f2;--token-color-red-4:#fbefee;--token-color-red-5:#faebea;--token-color-red-10:#f6d8d5;--token-color-red-15:#f1c4c0;--token-color-red-20:#edb0ab;--token-color-red-25:#e89d97;--token-color-red-30:#e38982;--token-color-red-35:#df756d;--token-color-red-40:#da6158;--token-color-red-45:#d64e43;--token-color-red-50:#d13a2e;--token-color-red-55:#bc3429;--token-color-red-60:#a72e25;--token-color-red-65:#922920;--token-color-red-70:#7d231c;--token-color-red-75:#691d17;--token-color-red-80:#541712;--token-color-red-85:#3f110e;--token-color-red-90:#2a0c09;--token-color-red-95:#150605;--token-color-red-96:#110504;--token-color-red-97:#0d0303} -:root{color-scheme:only light;scroll-behavior:smooth;--typo3-font-size:12px;--typo3-font-size-small:11px;--typo3-font-family-sans-serif:Verdana,Arial,Helvetica,sans-serif;--typo3-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;--typo3-font-family:var(--typo3-font-family-sans-serif);--typo3-font-family-code:var(--typo3-font-family-monospace);--typo3-spacing:1rem;--typo3-header-font-family:"Source Sans 3",sans-serif;--typo3-text-color-base:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-10));--typo3-text-color-variant:light-dark(var(--token-color-neutral-60), var(--token-color-neutral-30));--typo3-text-color-primary:light-dark(var(--token-color-blue-60), var(--token-color-blue-30));--typo3-text-color-secondary:light-dark(var(--token-color-neutral-70), var(--token-color-neutral-35));--typo3-text-color-info:light-dark(var(--token-color-teal-70), var(--token-color-teal-40));--typo3-text-color-success:light-dark(var(--token-color-green-70), var(--token-color-green-50));--typo3-text-color-warning:light-dark(var(--token-color-yellow-80), var(--token-color-yellow-40));--typo3-text-color-danger:light-dark(var(--token-color-red-60), var(--token-color-red-40));--typo3-text-color-code:light-dark(var(--token-color-magenta-60), var(--token-color-magenta-35));--typo3-text-color-notice:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-40));--typo3-text-color-default:var(--typo3-text-color-base);--typo3-surface-dim:light-dark(var(--token-color-neutral-15), var(--token-color-neutral-96));--typo3-surface-base:light-dark(var(--token-color-neutral-4), var(--token-color-neutral-96));--typo3-surface-bright:light-dark(var(--token-color-neutral-4), var(--token-color-neutral-85));--typo3-surface-container-lowest:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-100));--typo3-surface-container-low:light-dark(var(--token-color-neutral-3), var(--token-color-neutral-97));--typo3-surface-container-base:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-95));--typo3-surface-container-high:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-90));--typo3-surface-container-highest:light-dark(var(--token-color-neutral-15), var(--token-color-neutral-85));--typo3-surface-primary:light-dark(var(--token-color-blue-60), var(--token-color-blue-70));--typo3-surface-primary-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-primary:light-dark(var(--token-color-blue-10), var(--token-color-blue-90));--typo3-surface-container-primary-text:light-dark(var(--token-color-blue-90), var(--token-color-blue-10));--typo3-surface-secondary:light-dark(var(--token-color-neutral-70), var(--token-color-neutral-70));--typo3-surface-secondary-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-secondary:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-90));--typo3-surface-container-secondary-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-10));--typo3-surface-info:light-dark(var(--token-color-teal-20), var(--token-color-teal-70));--typo3-surface-info-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-surface-container-info:light-dark(var(--token-color-teal-10), var(--token-color-teal-90));--typo3-surface-container-info-text:light-dark(var(--token-color-teal-90), var(--token-color-teal-10));--typo3-surface-success:light-dark(var(--token-color-green-70), var(--token-color-green-80));--typo3-surface-success-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-success:light-dark(var(--token-color-green-10), var(--token-color-green-90));--typo3-surface-container-success-text:light-dark(var(--token-color-green-90), var(--token-color-green-10));--typo3-surface-warning:light-dark(var(--token-color-yellow-40), var(--token-color-yellow-80));--typo3-surface-warning-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-surface-container-warning:light-dark(var(--token-color-yellow-10), var(--token-color-yellow-90));--typo3-surface-container-warning-text:light-dark(var(--token-color-yellow-90), var(--token-color-yellow-10));--typo3-surface-danger:light-dark(var(--token-color-red-50), var(--token-color-red-70));--typo3-surface-danger-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-danger:light-dark(var(--token-color-red-10), var(--token-color-red-90));--typo3-surface-container-danger-text:light-dark(var(--token-color-red-90), var(--token-color-red-10));--typo3-surface-notice:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-85));--typo3-surface-notice-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-notice:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-90));--typo3-surface-container-notice-text:light-dark(var(--token-color-neutral-95), var(--token-color-neutral-0));--typo3-surface-default:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-95));--typo3-surface-default-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-surface-container-default:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-95));--typo3-surface-container-default-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-default-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-default-bg:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-90));--typo3-state-default-border-color:light-dark(var(--token-color-neutral-25), var(--token-color-neutral-80));--typo3-state-default-hover-color:var(--typo3-state-default-color);--typo3-state-default-hover-bg:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-85));--typo3-state-default-hover-border-color:light-dark(var(--token-color-neutral-35), var(--token-color-neutral-75));--typo3-state-default-focus-color:var(--typo3-state-default-color);--typo3-state-default-focus-bg:light-dark(var(--token-color-neutral-15), var(--token-color-neutral-80));--typo3-state-default-focus-border-color:light-dark(var(--token-color-neutral-40), var(--token-color-neutral-70));--typo3-state-default-disabled-color:var(--typo3-state-default-color);--typo3-state-default-disabled-bg:var(--typo3-state-default-bg);--typo3-state-default-disabled-border-color:var(--typo3-state-default-border-color);--typo3-state-primary-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-primary-bg:light-dark(var(--token-color-blue-60), var(--token-color-blue-70));--typo3-state-primary-border-color:light-dark(var(--token-color-blue-65), var(--token-color-blue-65));--typo3-state-primary-hover-color:var(--typo3-state-primary-color);--typo3-state-primary-hover-bg:light-dark(var(--token-color-blue-65), var(--token-color-blue-65));--typo3-state-primary-hover-border-color:light-dark(var(--token-color-blue-70), var(--token-color-blue-60));--typo3-state-primary-focus-color:var(--typo3-state-primary-color);--typo3-state-primary-focus-bg:light-dark(var(--token-color-blue-70), var(--token-color-blue-60));--typo3-state-primary-focus-border-color:light-dark(var(--token-color-blue-75), var(--token-color-blue-55));--typo3-state-primary-disabled-color:var(--typo3-state-primary-color);--typo3-state-primary-disabled-bg:var(--typo3-state-primary-bg);--typo3-state-primary-disabled-border-color:var(--typo3-state-default-primary-color);--typo3-state-secondary-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-secondary-bg:light-dark(var(--token-color-neutral-70), var(--token-color-neutral-70));--typo3-state-secondary-border-color:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-65));--typo3-state-secondary-hover-color:var(--typo3-state-secondary-color);--typo3-state-secondary-hover-bg:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-65));--typo3-state-secondary-hover-border-color:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-60));--typo3-state-secondary-focus-color:var(--typo3-state-secondary-color);--typo3-state-secondary-focus-bg:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-60));--typo3-state-secondary-focus-border-color:light-dark(var(--token-color-neutral-85), var(--token-color-neutral-55));--typo3-state-secondary-disabled-color:var(--typo3-state-secondary-color);--typo3-state-secondary-disabled-bg:var(--typo3-state-secondary-bg);--typo3-state-secondary-disabled-border-color:var(--typo3-state-default-secondary-color);--typo3-state-success-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-success-bg:light-dark(var(--token-color-green-70), var(--token-color-green-80));--typo3-state-success-border-color:light-dark(var(--token-color-green-75), var(--token-color-green-75));--typo3-state-success-hover-color:var(--typo3-state-success-color);--typo3-state-success-hover-bg:light-dark(var(--token-color-green-75), var(--token-color-green-75));--typo3-state-success-hover-border-color:light-dark(var(--token-color-green-80), var(--token-color-green-70));--typo3-state-success-focus-color:var(--typo3-state-success-color);--typo3-state-success-focus-bg:light-dark(var(--token-color-green-80), var(--token-color-green-70));--typo3-state-success-focus-border-color:light-dark(var(--token-color-green-85), var(--token-color-green-65));--typo3-state-success-disabled-color:var(--typo3-state-success-color);--typo3-state-success-disabled-bg:var(--typo3-state-success-bg);--typo3-state-success-disabled-border-color:var(--typo3-state-default-success-color);--typo3-state-warning-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-warning-bg:light-dark(var(--token-color-yellow-40), var(--token-color-yellow-80));--typo3-state-warning-border-color:light-dark(var(--token-color-yellow-45), var(--token-color-yellow-75));--typo3-state-warning-hover-color:var(--typo3-state-warning-color);--typo3-state-warning-hover-bg:light-dark(var(--token-color-yellow-45), var(--token-color-yellow-75));--typo3-state-warning-hover-border-color:light-dark(var(--token-color-yellow-50), var(--token-color-yellow-70));--typo3-state-warning-focus-color:var(--typo3-state-warning-color);--typo3-state-warning-focus-bg:light-dark(var(--token-color-yellow-50), var(--token-color-yellow-70));--typo3-state-warning-focus-border-color:light-dark(var(--token-color-yellow-55), var(--token-color-yellow-65));--typo3-state-warning-disabled-color:var(--typo3-state-warning-color);--typo3-state-warning-disabled-bg:var(--typo3-state-warning-bg);--typo3-state-warning-disabled-border-color:var(--typo3-state-warning-border-color);--typo3-state-danger-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-danger-bg:light-dark(var(--token-color-red-50), var(--token-color-red-70));--typo3-state-danger-border-color:light-dark(var(--token-color-red-55), var(--token-color-red-65));--typo3-state-danger-hover-color:var(--typo3-state-danger-color);--typo3-state-danger-hover-bg:light-dark(var(--token-color-red-55), var(--token-color-red-65));--typo3-state-danger-hover-border-color:light-dark(var(--token-color-red-60), var(--token-color-red-60));--typo3-state-danger-focus-color:var(--typo3-state-danger-color);--typo3-state-danger-focus-bg:light-dark(var(--token-color-red-60), var(--token-color-red-60));--typo3-state-danger-focus-border-color:light-dark(var(--token-color-red-65), var(--token-color-red-55));--typo3-state-danger-disabled-color:var(--typo3-state-danger-color);--typo3-state-danger-disabled-bg:var(--typo3-state-danger-bg);--typo3-state-danger-disabled-border-color:var(--typo3-state-danger-border-color);--typo3-state-info-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-info-bg:light-dark(var(--token-color-teal-20), var(--token-color-teal-70));--typo3-state-info-border-color:light-dark(var(--token-color-teal-25), var(--token-color-teal-65));--typo3-state-info-hover-color:var(--typo3-state-info-color);--typo3-state-info-hover-bg:light-dark(var(--token-color-teal-25), var(--token-color-teal-65));--typo3-state-info-hover-border-color:light-dark(var(--token-color-teal-30), var(--token-color-teal-60));--typo3-state-info-focus-color:var(--typo3-state-info-color);--typo3-state-info-focus-bg:light-dark(var(--token-color-teal-30), var(--token-color-teal-60));--typo3-state-info-focus-border-color:light-dark(var(--token-color-teal-35), var(--token-color-teal-55));--typo3-state-info-disabled-color:var(--typo3-state-info-color);--typo3-state-info-disabled-bg:var(--typo3-state-info-bg);--typo3-state-info-disabled-border-color:var(--typo3-state-info-border-color);--typo3-state-notice-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-notice-bg:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-85));--typo3-state-notice-border-color:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-80));--typo3-state-notice-hover-color:var(--typo3-state-notice-color);--typo3-state-notice-hover-bg:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-80));--typo3-state-notice-hover-border-color:light-dark(var(--token-color-neutral-85), var(--token-color-neutral-75));--typo3-state-notice-focus-color:var(--typo3-state-notice-color);--typo3-state-notice-focus-bg:light-dark(var(--token-color-neutral-85), var(--token-color-neutral-75));--typo3-state-notice-focus-border-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-70));--typo3-state-notice-disabled-color:var(--typo3-state-notice-color);--typo3-state-notice-disabled-bg:var(--typo3-state-notice-bg);--typo3-state-notice-disabled-border-color:var(--typo3-state-notice-border-color);--typo3-shadow-2:0 1px 2px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 1px 2px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-4:0 2px 4px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 2px 4px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-8:0 4px 8px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 4px 8px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-16:0 8px 16px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 8px 16px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-28:0 14px 28px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 14px 28px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-64:0 0 4px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 32px 64px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-component-color:var(--typo3-text-color-base);--typo3-component-variant-color:var(--typo3-text-color-variant);--typo3-component-primary-color:var(--typo3-text-color-primary);--typo3-component-secondary-color:var(--typo3-text-color-secondary);--typo3-component-match-highlight-color:inherit;--typo3-component-match-highlight-bg:rgba(234, 92, 0, .33);--typo3-component-bg:var(--typo3-surface-container-lowest);--typo3-component-link-color:light-dark(#05c, #6699e0);--typo3-component-link-hover-color:light-dark(#1a66d1, #80aae6);--typo3-component-font-size:12px;--typo3-component-line-height:1.5;--typo3-component-border-radius:4px;--typo3-component-border-width:1px;--typo3-component-border-color:light-dark(rgb(215, 215, 215), rgb(51, 51, 51));--typo3-component-padding-y:.75rem;--typo3-component-padding-x:1rem;--typo3-component-box-shadow:var(--typo3-shadow-2);--typo3-component-box-shadow-strong:var(--typo3-shadow-4);--typo3-component-box-shadow-tooltip:var(--typo3-shadow-8);--typo3-component-box-shadow-flyout:var(--typo3-shadow-16);--typo3-component-box-shadow-dialog:var(--typo3-shadow-28);--typo3-component-box-shadow-window:var(--typo3-shadow-64);--typo3-component-hover-color:var(--typo3-component-color);--typo3-component-hover-bg:light-dark(#f2f7fc, rgb(51, 51, 51));--typo3-component-hover-border-color:light-dark(#d9e6f7, rgb(90, 90, 90));--typo3-component-focus-color:var(--typo3-component-color);--typo3-component-focus-bg:light-dark(#f2f7fc, #002b66);--typo3-component-focus-border-color:light-dark(#3377d6, #00337a);--typo3-component-active-color:#fff;--typo3-component-active-bg:light-dark(#3377d6, #0048ad);--typo3-component-active-border-color:light-dark(#3377d6, #0044a3);--typo3-component-disabled-color:rgb(115, 115, 115);--typo3-component-disabled-bg:transparent;--typo3-component-disabled-border-color:transparent;--typo3-component-spacing:2rem;--typo3-list-item-padding-y:.5rem;--typo3-list-item-padding-x:.75rem;--typo3-list-item-hover-color:var(--typo3-component-hover-color);--typo3-list-item-hover-bg:var(--typo3-component-hover-bg);--typo3-list-item-hover-border-color:var(--typo3-component-hover-border-color);--typo3-list-item-focus-color:var(--typo3-component-focus-color);--typo3-list-item-focus-bg:var(--typo3-component-focus-bg);--typo3-list-item-focus-border-color:var(--typo3-component-focus-border-color);--typo3-list-item-active-color:var(--typo3-list-item-focus-color);--typo3-list-item-active-bg:var(--typo3-list-item-focus-bg);--typo3-list-item-active-border-color:var(--typo3-list-item-focus-border-color);--typo3-list-item-disabled-color:var(--typo3-component-disabled-color);--typo3-list-item-disabled-bg:var(--typo3-component-disabled-bg);--typo3-list-item-disabled-border-color:var(--typo3-component-disabled-border-color);--typo3-legend-font-weight:600;--typo3-input-font-size:.75rem;--typo3-input-line-height:1.5;--typo3-input-padding-y:.5rem;--typo3-input-padding-x:.75rem;--typo3-input-sm-padding-y:.3125rem;--typo3-input-sm-padding-x:.5rem;--typo3-input-sm-font-size:.6875rem;--typo3-input-border-width:1px;--typo3-input-border-radius:var(--typo3-component-border-radius);--typo3-input-color:var(--typo3-text-color-base);--typo3-input-placeholder-color:color-mix(in srgb, var(--typo3-input-color), transparent 30%);--typo3-input-bg:var(--typo3-surface-container-lowest);--typo3-input-group-addon-bg:color-mix(in srgb, var(--typo3-input-bg), var(--typo3-input-color) 10%);--typo3-input-border-color:var(--typo3-state-default-border-color);--typo3-input-hover-color:var(--typo3-input-color);--typo3-input-hover-bg:var(--typo3-input-bg);--typo3-input-hover-border-color:var(--typo3-state-default-hover-border-color);--typo3-input-focus-color:var(--typo3-input-color);--typo3-input-focus-bg:var(--typo3-input-bg);--typo3-input-focus-border-color:var(--typo3-state-primary-focus-border-color);--typo3-input-active-color:var(--typo3-state-primary-color);--typo3-input-active-bg:var(--typo3-state-primary-bg);--typo3-input-active-border-color:var(--typo3-state-primary-focus-border-color);--typo3-input-disabled-color:var(--typo3-state-default-disabled-color);--typo3-input-disabled-bg:var(--typo3-state-default-disabled-bg);--typo3-input-disabled-border-color:var(--typo3-state-default-disabled-border-color);--typo3-input-disabled-opacity:.65} +:root{color-scheme:only light;scroll-behavior:smooth;--typo3-font-size:12px;--typo3-font-size-small:11px;--typo3-font-family-sans-serif:Verdana,Arial,Helvetica,sans-serif;--typo3-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;--typo3-font-family:var(--typo3-font-family-sans-serif);--typo3-font-family-code:var(--typo3-font-family-monospace);--typo3-spacing:1rem;--typo3-header-font-family:"Source Sans 3",sans-serif;--typo3-text-color-base:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-10));--typo3-text-color-link:var(--typo3-text-color-base);--typo3-text-color-variant:light-dark(var(--token-color-neutral-60), var(--token-color-neutral-30));--typo3-text-color-primary:light-dark(var(--token-color-blue-60), var(--token-color-blue-30));--typo3-text-color-secondary:light-dark(var(--token-color-neutral-70), var(--token-color-neutral-35));--typo3-text-color-info:light-dark(var(--token-color-teal-70), var(--token-color-teal-40));--typo3-text-color-success:light-dark(var(--token-color-green-70), var(--token-color-green-50));--typo3-text-color-warning:light-dark(var(--token-color-yellow-80), var(--token-color-yellow-40));--typo3-text-color-danger:light-dark(var(--token-color-red-60), var(--token-color-red-40));--typo3-text-color-code:light-dark(var(--token-color-magenta-60), var(--token-color-magenta-35));--typo3-text-color-notice:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-40));--typo3-text-color-default:var(--typo3-text-color-base);--typo3-surface-dim:light-dark(var(--token-color-neutral-15), var(--token-color-neutral-96));--typo3-surface-base:light-dark(var(--token-color-neutral-4), var(--token-color-neutral-96));--typo3-surface-bright:light-dark(var(--token-color-neutral-4), var(--token-color-neutral-85));--typo3-surface-container-lowest:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-100));--typo3-surface-container-low:light-dark(var(--token-color-neutral-3), var(--token-color-neutral-97));--typo3-surface-container-base:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-95));--typo3-surface-container-high:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-90));--typo3-surface-container-highest:light-dark(var(--token-color-neutral-15), var(--token-color-neutral-85));--typo3-surface-primary:light-dark(var(--token-color-blue-60), var(--token-color-blue-70));--typo3-surface-primary-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-primary:light-dark(var(--token-color-blue-10), var(--token-color-blue-90));--typo3-surface-container-primary-text:light-dark(var(--token-color-blue-90), var(--token-color-blue-10));--typo3-surface-secondary:light-dark(var(--token-color-neutral-70), var(--token-color-neutral-70));--typo3-surface-secondary-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-secondary:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-90));--typo3-surface-container-secondary-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-10));--typo3-surface-info:light-dark(var(--token-color-teal-20), var(--token-color-teal-70));--typo3-surface-info-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-surface-container-info:light-dark(var(--token-color-teal-10), var(--token-color-teal-90));--typo3-surface-container-info-text:light-dark(var(--token-color-teal-90), var(--token-color-teal-10));--typo3-surface-success:light-dark(var(--token-color-green-70), var(--token-color-green-80));--typo3-surface-success-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-success:light-dark(var(--token-color-green-10), var(--token-color-green-90));--typo3-surface-container-success-text:light-dark(var(--token-color-green-90), var(--token-color-green-10));--typo3-surface-warning:light-dark(var(--token-color-yellow-40), var(--token-color-yellow-80));--typo3-surface-warning-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-surface-container-warning:light-dark(var(--token-color-yellow-10), var(--token-color-yellow-90));--typo3-surface-container-warning-text:light-dark(var(--token-color-yellow-90), var(--token-color-yellow-10));--typo3-surface-danger:light-dark(var(--token-color-red-50), var(--token-color-red-70));--typo3-surface-danger-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-danger:light-dark(var(--token-color-red-10), var(--token-color-red-90));--typo3-surface-container-danger-text:light-dark(var(--token-color-red-90), var(--token-color-red-10));--typo3-surface-notice:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-85));--typo3-surface-notice-text:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-surface-container-notice:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-90));--typo3-surface-container-notice-text:light-dark(var(--token-color-neutral-95), var(--token-color-neutral-0));--typo3-surface-default:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-95));--typo3-surface-default-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-surface-container-default:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-95));--typo3-surface-container-default-text:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-default-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-default-bg:light-dark(var(--token-color-neutral-5), var(--token-color-neutral-90));--typo3-state-default-border-color:light-dark(var(--token-color-neutral-25), var(--token-color-neutral-80));--typo3-state-default-hover-color:var(--typo3-state-default-color);--typo3-state-default-hover-bg:light-dark(var(--token-color-neutral-10), var(--token-color-neutral-85));--typo3-state-default-hover-border-color:light-dark(var(--token-color-neutral-35), var(--token-color-neutral-75));--typo3-state-default-focus-color:var(--typo3-state-default-color);--typo3-state-default-focus-bg:light-dark(var(--token-color-neutral-15), var(--token-color-neutral-80));--typo3-state-default-focus-border-color:light-dark(var(--token-color-neutral-40), var(--token-color-neutral-70));--typo3-state-default-disabled-color:var(--typo3-state-default-color);--typo3-state-default-disabled-bg:var(--typo3-state-default-bg);--typo3-state-default-disabled-border-color:var(--typo3-state-default-border-color);--typo3-state-primary-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-primary-bg:light-dark(var(--token-color-blue-60), var(--token-color-blue-70));--typo3-state-primary-border-color:light-dark(var(--token-color-blue-65), var(--token-color-blue-65));--typo3-state-primary-hover-color:var(--typo3-state-primary-color);--typo3-state-primary-hover-bg:light-dark(var(--token-color-blue-65), var(--token-color-blue-65));--typo3-state-primary-hover-border-color:light-dark(var(--token-color-blue-70), var(--token-color-blue-60));--typo3-state-primary-focus-color:var(--typo3-state-primary-color);--typo3-state-primary-focus-bg:light-dark(var(--token-color-blue-70), var(--token-color-blue-60));--typo3-state-primary-focus-border-color:light-dark(var(--token-color-blue-75), var(--token-color-blue-55));--typo3-state-primary-disabled-color:var(--typo3-state-primary-color);--typo3-state-primary-disabled-bg:var(--typo3-state-primary-bg);--typo3-state-primary-disabled-border-color:var(--typo3-state-default-primary-color);--typo3-state-secondary-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-secondary-bg:light-dark(var(--token-color-neutral-70), var(--token-color-neutral-70));--typo3-state-secondary-border-color:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-65));--typo3-state-secondary-hover-color:var(--typo3-state-secondary-color);--typo3-state-secondary-hover-bg:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-65));--typo3-state-secondary-hover-border-color:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-60));--typo3-state-secondary-focus-color:var(--typo3-state-secondary-color);--typo3-state-secondary-focus-bg:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-60));--typo3-state-secondary-focus-border-color:light-dark(var(--token-color-neutral-85), var(--token-color-neutral-55));--typo3-state-secondary-disabled-color:var(--typo3-state-secondary-color);--typo3-state-secondary-disabled-bg:var(--typo3-state-secondary-bg);--typo3-state-secondary-disabled-border-color:var(--typo3-state-default-secondary-color);--typo3-state-success-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-success-bg:light-dark(var(--token-color-green-70), var(--token-color-green-80));--typo3-state-success-border-color:light-dark(var(--token-color-green-75), var(--token-color-green-75));--typo3-state-success-hover-color:var(--typo3-state-success-color);--typo3-state-success-hover-bg:light-dark(var(--token-color-green-75), var(--token-color-green-75));--typo3-state-success-hover-border-color:light-dark(var(--token-color-green-80), var(--token-color-green-70));--typo3-state-success-focus-color:var(--typo3-state-success-color);--typo3-state-success-focus-bg:light-dark(var(--token-color-green-80), var(--token-color-green-70));--typo3-state-success-focus-border-color:light-dark(var(--token-color-green-85), var(--token-color-green-65));--typo3-state-success-disabled-color:var(--typo3-state-success-color);--typo3-state-success-disabled-bg:var(--typo3-state-success-bg);--typo3-state-success-disabled-border-color:var(--typo3-state-default-success-color);--typo3-state-warning-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-warning-bg:light-dark(var(--token-color-yellow-40), var(--token-color-yellow-80));--typo3-state-warning-border-color:light-dark(var(--token-color-yellow-45), var(--token-color-yellow-75));--typo3-state-warning-hover-color:var(--typo3-state-warning-color);--typo3-state-warning-hover-bg:light-dark(var(--token-color-yellow-45), var(--token-color-yellow-75));--typo3-state-warning-hover-border-color:light-dark(var(--token-color-yellow-50), var(--token-color-yellow-70));--typo3-state-warning-focus-color:var(--typo3-state-warning-color);--typo3-state-warning-focus-bg:light-dark(var(--token-color-yellow-50), var(--token-color-yellow-70));--typo3-state-warning-focus-border-color:light-dark(var(--token-color-yellow-55), var(--token-color-yellow-65));--typo3-state-warning-disabled-color:var(--typo3-state-warning-color);--typo3-state-warning-disabled-bg:var(--typo3-state-warning-bg);--typo3-state-warning-disabled-border-color:var(--typo3-state-warning-border-color);--typo3-state-danger-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-danger-bg:light-dark(var(--token-color-red-50), var(--token-color-red-70));--typo3-state-danger-border-color:light-dark(var(--token-color-red-55), var(--token-color-red-65));--typo3-state-danger-hover-color:var(--typo3-state-danger-color);--typo3-state-danger-hover-bg:light-dark(var(--token-color-red-55), var(--token-color-red-65));--typo3-state-danger-hover-border-color:light-dark(var(--token-color-red-60), var(--token-color-red-60));--typo3-state-danger-focus-color:var(--typo3-state-danger-color);--typo3-state-danger-focus-bg:light-dark(var(--token-color-red-60), var(--token-color-red-60));--typo3-state-danger-focus-border-color:light-dark(var(--token-color-red-65), var(--token-color-red-55));--typo3-state-danger-disabled-color:var(--typo3-state-danger-color);--typo3-state-danger-disabled-bg:var(--typo3-state-danger-bg);--typo3-state-danger-disabled-border-color:var(--typo3-state-danger-border-color);--typo3-state-info-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-0));--typo3-state-info-bg:light-dark(var(--token-color-teal-20), var(--token-color-teal-70));--typo3-state-info-border-color:light-dark(var(--token-color-teal-25), var(--token-color-teal-65));--typo3-state-info-hover-color:var(--typo3-state-info-color);--typo3-state-info-hover-bg:light-dark(var(--token-color-teal-25), var(--token-color-teal-65));--typo3-state-info-hover-border-color:light-dark(var(--token-color-teal-30), var(--token-color-teal-60));--typo3-state-info-focus-color:var(--typo3-state-info-color);--typo3-state-info-focus-bg:light-dark(var(--token-color-teal-30), var(--token-color-teal-60));--typo3-state-info-focus-border-color:light-dark(var(--token-color-teal-35), var(--token-color-teal-55));--typo3-state-info-disabled-color:var(--typo3-state-info-color);--typo3-state-info-disabled-bg:var(--typo3-state-info-bg);--typo3-state-info-disabled-border-color:var(--typo3-state-info-border-color);--typo3-state-notice-color:light-dark(var(--token-color-neutral-0), var(--token-color-neutral-0));--typo3-state-notice-bg:light-dark(var(--token-color-neutral-75), var(--token-color-neutral-85));--typo3-state-notice-border-color:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-80));--typo3-state-notice-hover-color:var(--typo3-state-notice-color);--typo3-state-notice-hover-bg:light-dark(var(--token-color-neutral-80), var(--token-color-neutral-80));--typo3-state-notice-hover-border-color:light-dark(var(--token-color-neutral-85), var(--token-color-neutral-75));--typo3-state-notice-focus-color:var(--typo3-state-notice-color);--typo3-state-notice-focus-bg:light-dark(var(--token-color-neutral-85), var(--token-color-neutral-75));--typo3-state-notice-focus-border-color:light-dark(var(--token-color-neutral-90), var(--token-color-neutral-70));--typo3-state-notice-disabled-color:var(--typo3-state-notice-color);--typo3-state-notice-disabled-bg:var(--typo3-state-notice-bg);--typo3-state-notice-disabled-border-color:var(--typo3-state-notice-border-color);--typo3-shadow-2:0 1px 2px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 1px 2px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-4:0 2px 4px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 2px 4px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-8:0 4px 8px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 4px 8px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-16:0 8px 16px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 8px 16px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-28:0 14px 28px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 14px 28px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-shadow-64:0 0 4px light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.2)),0 32px 64px light-dark(rgba(0, 0, 0, 0.14), rgba(0, 0, 0, 0.28));--typo3-component-color:var(--typo3-text-color-base);--typo3-component-variant-color:var(--typo3-text-color-variant);--typo3-component-primary-color:var(--typo3-text-color-primary);--typo3-component-secondary-color:var(--typo3-text-color-secondary);--typo3-component-match-highlight-color:inherit;--typo3-component-match-highlight-bg:rgba(234, 92, 0, .33);--typo3-component-bg:var(--typo3-surface-container-lowest);--typo3-component-link-color:light-dark(#05c, #6699e0);--typo3-component-link-hover-color:light-dark(#1a66d1, #80aae6);--typo3-component-font-size:12px;--typo3-component-line-height:1.5;--typo3-component-border-radius:4px;--typo3-component-border-width:1px;--typo3-component-border-color:light-dark(rgb(215, 215, 215), rgb(51, 51, 51));--typo3-component-padding-y:.75rem;--typo3-component-padding-x:1rem;--typo3-component-box-shadow:var(--typo3-shadow-2);--typo3-component-box-shadow-strong:var(--typo3-shadow-4);--typo3-component-box-shadow-tooltip:var(--typo3-shadow-8);--typo3-component-box-shadow-flyout:var(--typo3-shadow-16);--typo3-component-box-shadow-dialog:var(--typo3-shadow-28);--typo3-component-box-shadow-window:var(--typo3-shadow-64);--typo3-component-hover-color:var(--typo3-component-color);--typo3-component-hover-bg:light-dark(#f2f7fc, rgb(51, 51, 51));--typo3-component-hover-border-color:light-dark(#d9e6f7, rgb(90, 90, 90));--typo3-component-focus-color:var(--typo3-component-color);--typo3-component-focus-bg:light-dark(#f2f7fc, #002b66);--typo3-component-focus-border-color:light-dark(#3377d6, #00337a);--typo3-component-active-color:#fff;--typo3-component-active-bg:light-dark(#3377d6, #0048ad);--typo3-component-active-border-color:light-dark(#3377d6, #0044a3);--typo3-component-disabled-color:rgb(115, 115, 115);--typo3-component-disabled-bg:transparent;--typo3-component-disabled-border-color:transparent;--typo3-component-spacing:2rem;--typo3-list-item-padding-y:.5rem;--typo3-list-item-padding-x:.75rem;--typo3-list-item-hover-color:var(--typo3-component-hover-color);--typo3-list-item-hover-bg:var(--typo3-component-hover-bg);--typo3-list-item-hover-border-color:var(--typo3-component-hover-border-color);--typo3-list-item-focus-color:var(--typo3-component-focus-color);--typo3-list-item-focus-bg:var(--typo3-component-focus-bg);--typo3-list-item-focus-border-color:var(--typo3-component-focus-border-color);--typo3-list-item-active-color:var(--typo3-list-item-focus-color);--typo3-list-item-active-bg:var(--typo3-list-item-focus-bg);--typo3-list-item-active-border-color:var(--typo3-list-item-focus-border-color);--typo3-list-item-disabled-color:var(--typo3-component-disabled-color);--typo3-list-item-disabled-bg:var(--typo3-component-disabled-bg);--typo3-list-item-disabled-border-color:var(--typo3-component-disabled-border-color);--typo3-legend-font-weight:600;--typo3-input-font-size:.75rem;--typo3-input-line-height:1.5;--typo3-input-padding-y:.5rem;--typo3-input-padding-x:.75rem;--typo3-input-sm-padding-y:.3125rem;--typo3-input-sm-padding-x:.5rem;--typo3-input-sm-font-size:.6875rem;--typo3-input-border-width:1px;--typo3-input-border-radius:var(--typo3-component-border-radius);--typo3-input-color:var(--typo3-text-color-base);--typo3-input-placeholder-color:color-mix(in srgb, var(--typo3-input-color), transparent 30%);--typo3-input-bg:var(--typo3-surface-container-lowest);--typo3-input-group-addon-bg:color-mix(in srgb, var(--typo3-input-bg), var(--typo3-input-color) 10%);--typo3-input-border-color:var(--typo3-state-default-border-color);--typo3-input-hover-color:var(--typo3-input-color);--typo3-input-hover-bg:var(--typo3-input-bg);--typo3-input-hover-border-color:var(--typo3-state-default-hover-border-color);--typo3-input-focus-color:var(--typo3-input-color);--typo3-input-focus-bg:var(--typo3-input-bg);--typo3-input-focus-border-color:var(--typo3-state-primary-focus-border-color);--typo3-input-active-color:var(--typo3-state-primary-color);--typo3-input-active-bg:var(--typo3-state-primary-bg);--typo3-input-active-border-color:var(--typo3-state-primary-focus-border-color);--typo3-input-disabled-color:var(--typo3-state-default-disabled-color);--typo3-input-disabled-bg:var(--typo3-state-default-disabled-bg);--typo3-input-disabled-border-color:var(--typo3-state-default-disabled-border-color);--typo3-input-disabled-opacity:.65} [data-color-scheme=auto]{color-scheme:light dark} [data-color-scheme=dark]{color-scheme:only dark} [data-color-scheme=light]{color-scheme:only light} @@ -2478,6 +2477,9 @@ button[aria-expanded=true]:not(:disabled) .modulemenu-indicator:after{transform: .h1,h1,typo3-backend-editable-page-title{font-family:var(--typo3-header-font-family);font-variant:normal;font-weight:400} .h1:not(:first-child):not([class]),.h2:not(:first-child):not([class]),.h3:not(:first-child):not([class]),.headline-spaced.h1,.headline-spaced.h2,.headline-spaced.h3,h1.headline-spaced,h1:not(:first-child):not([class]),h2.headline-spaced,h2:not(:first-child):not([class]),h3.headline-spaced,h3:not(:first-child):not([class]),typo3-backend-editable-page-title.headline-spaced,typo3-backend-editable-page-title:not(:first-child):not([class]){margin-top:calc(var(--typo3-spacing) * 2)} .h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit} +a{color:var(--typo3-text-color-link);text-decoration:none} +a:hover{text-decoration:underline} +a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none} .text-base,.text-base-emphasis{color:var(--typo3-text-color-base)!important} .text-muted,.text-muted-emphasis,.text-variant,.text-variant-emphasis{color:var(--typo3-text-color-variant)!important} .text-primary,.text-primary-emphasis{color:var(--typo3-text-color-primary)!important} @@ -2490,6 +2492,16 @@ button[aria-expanded=true]:not(:disabled) .modulemenu-indicator:after{transform: .text-default,.text-default-emphasis{color:var(--typo3-text-color-default)!important} .text-code,.text-code-emphasis,code{color:var(--typo3-text-color-code)!important} .text-reset{color:inherit!important} +.order-0{order:0} +.order-1{order:1} +.order-2{order:2} +.order-3{order:3} +.order-4{order:4} +.order-5{order:5} +.order-6{order:6} +.order-7{order:7} +.order-8{order:8} +.order-9{order:9} .nav{padding-inline:0} :root{--icon-color-primary:currentColor;--icon-size-small:16px;--icon-size-medium:32px;--icon-size-large:48px;--icon-size-mega:64px;--icon-unify-modifier:0.86;--icon-opacity-disabled:0.5} .icon{position:relative;display:inline-flex;overflow:hidden;white-space:nowrap;color:var(--icon-color-primary);height:var(--icon-size,1em);width:var(--icon-size,1em);line-height:var(--icon-size,1em);flex-shrink:0} @@ -2525,6 +2537,11 @@ button[aria-expanded=true]:not(:disabled) .modulemenu-indicator:after{transform: .icon-emphasized{--icon-emphasized-color:var(--typo3-state-default-color);--icon-emphasized-bg:var(--typo3-state-default-bg);color:var(--icon-emphasized-color);background-color:var(--icon-emphasized-bg);display:flex;justify-content:center;align-items:center;width:2rem;height:2rem;border-radius:100%} .alert .icon-emphasized{--icon-emphasized-color:var(--typo3-alert-icon-color);--icon-emphasized-bg:var(--typo3-alert-icon-bg)} .callout .icon-emphasized{--icon-emphasized-color:var(--typo3-callout-icon-color);--icon-emphasized-bg:var(--typo3-callout-icon-bg)} +:root{--typo3-caret-color:var(--typo3-text-color-base);--typo3-caret-rotation:0deg;--typo3-caret-size:16px;--typo3-caret-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cg fill='%23fff'%3e%3cpath d='m4.464 6.05-.707.707L8 11l4.243-4.243-.707-.707L8 9.586z'/%3e%3c/g%3e%3c/svg%3e")} +.caret{display:inline-block;position:relative;height:var(--typo3-caret-size);width:var(--typo3-caret-size);background-color:var(--typo3-caret-color);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-image:var(--typo3-caret-icon);mask-image:var(--typo3-caret-icon);-webkit-mask-position:center center;mask-position:center center;-webkit-mask-size:contain;mask-size:contain;rotate:var(--typo3-caret-rotation);line-height:1;vertical-align:-22%;transition:all .25s ease-in-out} +@media (prefers-reduced-motion:reduce){ +.caret{transition:none} +} hr.spacer{border-top:none;margin-top:var(--typo3-spacing);margin-bottom:var(--typo3-spacing)} .alert{--typo3-alert-color:inherit;--typo3-alert-bg:transparent;--typo3-alert-icon-color:inherit;--typo3-alert-icon-bg:transparent;--typo3-alert-padding-x:1rem;--typo3-alert-padding-y:1rem;--typo3-alert-padding-dismissable-end:3rem;--typo3-alert-margin-bottom:var(--typo3-spacing);--typo3-alert-border-color:color-mix(in srgb, var(--typo3-alert-bg), var(--typo3-alert-color) 15%);--typo3-alert-border-width:1px;--typo3-alert-border-radius:var(--typo3-component-border-radius);--typo3-alert-link-color:inherit;position:relative;padding:var(--typo3-alert-padding-y) var(--typo3-alert-padding-x);margin-bottom:var(--typo3-alert-margin-bottom);color:var(--typo3-alert-color);background-color:var(--typo3-alert-bg);border:var(--typo3-alert-border-width) solid var(--typo3-alert-border-color);border-radius:var(--typo3-alert-border-radius)} .alert a{color:inherit;text-decoration:underline} @@ -2758,7 +2775,7 @@ typo3-backend-formengine-suggest-result-item .formengine-suggest-result-item-lab .btn{--typo3-btn-padding-y:var(--typo3-input-padding-y);--typo3-btn-padding-x:var(--typo3-input-padding-x);--typo3-btn-font-size:var(--typo3-input-font-size);--typo3-btn-line-height:var(--typo3-input-line-height);--typo3-btn-border-width:var(--typo3-input-border-width);--typo3-btn-border-radius:var(--typo3-input-border-radius);--typo3-btn-disabled-opacity:.65;--typo3-btn-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;--typo3-btn-color:inherit;--typo3-btn-bg:transparent;--typo3-btn-border-color:transparent;--typo3-btn-hover-color:inherit;--typo3-btn-hover-bg:transparent;--typo3-btn-hover-border-color:transparent;--typo3-btn-focus-color:inherit;--typo3-btn-focus-bg:transparent;--typo3-btn-focus-border-color:transparent;--typo3-btn-disabled-color:inherit;--typo3-btn-disabled-bg:transparent;--typo3-btn-disabled-border-color:transparent;--typo3-btn-min-height:calc(var(--typo3-btn-padding-y) * 2 + var(--typo3-btn-font-size) * var(--typo3-btn-line-height) + var(--typo3-btn-border-width) * 2);display:inline-flex;align-items:center;justify-content:center;gap:.35em;color:var(--typo3-btn-color);background-color:var(--typo3-btn-bg);padding:var(--typo3-btn-padding-y) var(--typo3-btn-padding-x);font-size:var(--typo3-btn-font-size);font-weight:400;line-height:var(--typo3-btn-line-height);text-decoration:none;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--typo3-btn-border-width) solid var(--typo3-btn-border-color);border-radius:var(--typo3-btn-border-radius);transition:var(--typo3-btn-transition);outline-offset:0;min-height:var(--typo3-btn-min-height);cursor:pointer} .btn:hover{--typo3-btn-color:var(--typo3-btn-hover-color);--typo3-btn-bg:var(--typo3-btn-hover-bg);--typo3-btn-border-color:var(--typo3-btn-hover-border-color);text-decoration:inherit;z-index:2!important} .btn:focus{--typo3-btn-color:var(--typo3-btn-focus-color);--typo3-btn-bg:var(--typo3-btn-focus-bg);--typo3-btn-border-color:var(--typo3-btn-focus-border-color);z-index:3!important} -.btn-check:focus-visible+.btn,.btn:focus-visible{outline:.25rem solid color-mix(in srgb,var(--typo3-btn-focus-border-color),transparent 25%)} +.btn-check:focus-visible+.btn,.btn:focus-visible,.btn:has(:focus-visible){outline:.25rem solid color-mix(in srgb,var(--typo3-btn-focus-border-color),transparent 25%)} .btn-check:checked+.btn,.btn.active,.btn[aria-pressed=true],:not(.btn-check)+.btn:active{box-shadow:inset 0 0 1000px 0 color-mix(in srgb,var(--typo3-btn-color),transparent 90%)} .btn.disabled,.btn:disabled,fieldset:disabled .btn{--typo3-btn-color:var(--typo3-btn-disabled-color);--typo3-btn-bg:var(--typo3-btn-disabled-bg);--typo3-btn-border-color:var(--typo3-btn-disabled-border-color);opacity:var(--typo3-btn-disabled-opacity);pointer-events:none;cursor:not-allowed} .btn-group-sm>.btn,.btn-sm{--typo3-btn-padding-y:var(--typo3-input-sm-padding-y);--typo3-btn-padding-x:var(--typo3-input-sm-padding-x);--typo3-btn-font-size:var(--typo3-input-sm-font-size)} @@ -2909,64 +2926,60 @@ a.dropdown-toggle{text-decoration:none} .module-body>.container{padding-left:0;padding-right:0} .module-body .container-small{max-width:768px;margin:0 auto} .module-body>:last-child{margin-bottom:0} -:root{--panel-bg:#fff;--panel-border-color:#ccc;--panel-border-radius:var(--typo3-component-border-radius);--panel-border-width:var(--typo3-component-border-width);--panel-padding:var(--typo3-component-padding-x);--panel-header-padding-x:var(--typo3-component-padding-x);--panel-header-padding-y:var(--typo3-component-padding-y);--panel-spacing:var(--typo3-component-spacing);--panel-box-shadow:var(--typo3-component-box-shadow);--panel-primary-border-color:#99bbeb;--panel-primary-progress-bg:#05c;--panel-primary-heading-color:#000;--panel-primary-heading-bg:#d9e6f7;--panel-secondary-border-color:#c7c7c7;--panel-secondary-progress-bg:rgb(115, 115, 115);--panel-secondary-heading-color:#000;--panel-secondary-heading-bg:#eaeaea;--panel-success-border-color:#a7c8bb;--panel-success-progress-bg:#247554;--panel-success-heading-color:#000;--panel-success-heading-bg:#deeae5;--panel-info-border-color:#ddf1f8;--panel-info-progress-bg:#abdced;--panel-info-heading-color:#000;--panel-info-heading-bg:#f2fafc;--panel-warning-border-color:#ffebad;--panel-warning-progress-bg:#fc3;--panel-warning-heading-color:#000;--panel-warning-heading-bg:#fff7e0;--panel-danger-border-color:#edb0ab;--panel-danger-progress-bg:#d13a2e;--panel-danger-heading-color:#000;--panel-danger-heading-bg:#f8e1e0;--panel-light-border-color:#c4c4c4;--panel-light-progress-bg:gainsboro;--panel-light-heading-color:#000;--panel-light-heading-bg:whitesmoke;--panel-default-border-color:#c4c4c4;--panel-default-progress-bg:gainsboro;--panel-default-heading-color:#000;--panel-default-heading-bg:whitesmoke;--panel-notice-border-color:#adadad;--panel-notice-progress-bg:rgb(51, 51, 51);--panel-notice-heading-color:#000;--panel-notice-heading-bg:#e0e0e0;--panel-dark-border-color:#a5a5a5;--panel-dark-progress-bg:rgb(30, 30, 30);--panel-dark-heading-color:#000;--panel-dark-heading-bg:#dddddd} -.panel-group{display:flex;flex-flow:column;overflow:hidden;margin-bottom:var(--typo3-spacing);border-radius:var(--panel-border-radius);box-shadow:var(--panel-box-shadow)} -.panel-group>.panel{border-radius:0;margin-bottom:0;box-shadow:none;margin-top:calc(var(--panel-border-width) * -1)} -.panel-group>.panel:first-child{margin-top:0;border-top-left-radius:var(--panel-border-radius);border-top-right-radius:var(--panel-border-radius)} -.panel-group>.panel:last-child{border-bottom-left-radius:var(--panel-border-radius);border-bottom-right-radius:var(--panel-border-radius)} -.panel{display:flex;flex-direction:column;overflow:hidden;min-width:0;word-wrap:break-word;background-clip:border-box;background-color:var(--panel-bg);border:var(--panel-border-width) solid var(--panel-border-color);border-radius:var(--panel-border-radius);box-shadow:var(--panel-box-shadow);margin-block-end:var(--typo3-spacing);transition:all .2s ease-in-out;transition-property:box-shadow,border,transform;position:relative} -.panel .table-fit{box-shadow:none;border-radius:0;border-left:0;border-right:0;border-bottom:0;margin-bottom:0} -.panel-loader{padding:var(--panel-padding)} -.panel-progress{display:none;position:absolute;top:0;inset-inline-start:0;height:3px;width:100%;z-index:1;background-color:transparent} -.panel-progress .panel-progress-bar{display:block;height:100%;background-color:var(--panel-progress-bg,#05c)} +.panel{--typo3-panel-color:var(--typo3-component-color);--typo3-panel-bg:var(--typo3-component-bg);--typo3-panel-border-color:color-mix(in srgb, var(--typo3-panel-bg), var(--typo3-panel-color) 15%);--typo3-panel-border-width:var(--typo3-component-border-width);--typo3-panel-border-radius:var(--typo3-component-border-radius);--typo3-panel-border-radius-top:var(--typo3-panel-border-radius);--typo3-panel-border-radius-bottom:var(--typo3-panel-border-radius);--typo3-panel-border-radius-inner-top:max(0px, calc(var(--typo3-panel-border-radius-top) - var(--typo3-panel-border-width)));--typo3-panel-border-radius-inner-bottom:max(0px, calc(var(--typo3-panel-border-radius-bottom) - var(--typo3-panel-border-width)));--typo3-panel-padding-y:.75rem;--typo3-panel-padding-x:1rem;--typo3-panel-sm-padding-y:.5rem;--typo3-panel-sm-padding-x:.75rem;--typo3-panel-header-bg:var(--typo3-surface-container-low);--typo3-panel-header-color:var(--typo3-text-color-base);--typo3-panel-box-shadow:var(--typo3-component-box-shadow);--typo3-panel-progress-bg:var(--typo3-state-primary-bg);--typo3-panel-primary-header-color:var(--typo3-surface-container-primary-text);--typo3-panel-primary-header-bg:var(--typo3-surface-container-primary);--typo3-panel-primary-border-color:color-mix(in srgb, var(--typo3-panel-primary-header-bg), var(--typo3-panel-primary-header-color) 15%);--typo3-panel-secondary-header-color:var(--typo3-surface-container-secondary-text);--typo3-panel-secondary-header-bg:var(--typo3-surface-container-secondary);--typo3-panel-secondary-border-color:color-mix(in srgb, var(--typo3-panel-secondary-header-bg), var(--typo3-panel-secondary-header-color) 15%);--typo3-panel-info-header-color:var(--typo3-surface-container-info-text);--typo3-panel-info-header-bg:var(--typo3-surface-container-info);--typo3-panel-info-border-color:color-mix(in srgb, var(--typo3-panel-info-header-bg), var(--typo3-panel-info-header-color) 15%);--typo3-panel-success-header-color:var(--typo3-surface-container-success-text);--typo3-panel-success-header-bg:var(--typo3-surface-container-success);--typo3-panel-success-border-color:color-mix(in srgb, var(--typo3-panel-success-header-bg), var(--typo3-panel-success-header-color) 15%);--typo3-panel-warning-header-color:var(--typo3-surface-container-warning-text);--typo3-panel-warning-header-bg:var(--typo3-surface-container-warning);--typo3-panel-warning-border-color:color-mix(in srgb, var(--typo3-panel-warning-header-bg), var(--typo3-panel-warning-header-color) 15%);--typo3-panel-danger-header-color:var(--typo3-surface-container-danger-text);--typo3-panel-danger-header-bg:var(--typo3-surface-container-danger);--typo3-panel-danger-border-color:color-mix(in srgb, var(--typo3-panel-danger-header-bg), var(--typo3-panel-danger-header-color) 15%);--typo3-panel-notice-header-color:var(--typo3-surface-container-notice-text);--typo3-panel-notice-header-bg:var(--typo3-surface-container-notice);--typo3-panel-notice-border-color:color-mix(in srgb, var(--typo3-panel-notice-header-bg), var(--typo3-panel-notice-header-color) 15%);--typo3-panel-default-header-color:var(--typo3-surface-container-default-text);--typo3-panel-default-header-bg:var(--typo3-surface-container-default);--typo3-panel-default-border-color:color-mix(in srgb, var(--typo3-panel-default-header-bg), var(--typo3-panel-default-header-color) 15%);display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-clip:border-box;color:var(--typo3-panel-color);background-color:var(--typo3-panel-bg);border:var(--typo3-panel-border-width) solid var(--typo3-panel-border-color);border-radius:var(--typo3-panel-border-radius-top) var(--typo3-panel-border-radius-top) var(--typo3-panel-border-radius-bottom) var(--typo3-panel-border-radius-bottom);box-shadow:var(--typo3-panel-box-shadow);margin-block-end:var(--typo3-spacing);position:relative} +.panel .panel-collapse>.table-fit,.panel>.table-fit{box-shadow:none;border-radius:0;border-left:0;border-right:0;border-bottom:0;margin-bottom:0} +.panel>.table-fit:last-child{border-end-start-radius:var(--typo3-panel-border-radius-inner-bottom);border-end-end-radius:var(--typo3-panel-border-radius-inner-bottom)} +.panel-loader{padding:var(--typo3-panel-padding-y) var(--typo3-panel-padding-x)} +.panel:has(.panel-progress){min-height:5px} +.panel-progress{display:none;position:absolute;top:0;inset-inline-start:0;height:3px;width:100%;z-index:1;background-color:transparent;overflow:hidden;border-radius:var(--typo3-panel-border-radius-inner-top) var(--typo3-panel-border-radius-inner-top) 0 0} +.panel-progress .panel-progress-bar{display:block;height:100%;background-color:var(--typo3-panel-progress-bg)} .panel-has-progress>.panel-progress{display:block} -.panel-heading{position:relative;color:var(--panel-heading-color);background-color:var(--panel-heading-bg);font-weight:700;padding:var(--panel-header-padding-y) var(--panel-header-padding-x)} -.panel-heading .caret{transition:all .25s ease-in-out;border-top-color:var(--panel-heading-color)} -@media (prefers-reduced-motion:reduce){ -.panel-heading .caret{transition:none} -} -.panel-collapsed .panel-heading .caret,.panel-heading .collapsed>.caret,.panel-heading .collapsed>.form-irre-header-icon .caret{transform:rotate(-90deg)} -.panel-heading a:not(.btn),.panel-heading a:not(.btn):active,.panel-heading a:not(.btn):focus,.panel-heading a:not(.btn):hover{text-decoration:none;color:inherit} -.panel-heading-row{flex-grow:1;display:flex;align-items:center;flex-wrap:wrap;max-width:100%;gap:var(--panel-header-padding-y) var(--panel-header-padding-x)} -.panel-heading-title{font-weight:700;flex-grow:1;width:250px;max-width:100%} -.panel-heading-actions{display:flex;align-items:center;flex-wrap:wrap;gap:.25rem} -.panel-heading-button{display:flex;text-align:start;align-items:center;align-self:stretch;border:0;width:100%} -.panel-title{font-size:12px;margin-top:0;margin-bottom:0} -.panel-body{padding:var(--panel-padding)} -.panel-body>p>a{text-decoration:underline} +.panel-button{position:relative;display:flex;align-items:center;text-align:start;padding:0;gap:.25rem;background:0 0;border:none;flex-grow:1;width:100%} +.panel-button:after{position:absolute;content:"";left:0;right:0;top:calc(var(--typo3-panel-padding-y) * -1);bottom:calc(var(--typo3-panel-padding-y) * -1)} +.panel-heading{font-size:var(--typo3-font-size);font-weight:400;position:relative;color:var(--typo3-panel-header-color);background-color:var(--typo3-panel-header-bg);padding:var(--typo3-panel-padding-y) var(--typo3-panel-padding-x);border-radius:var(--typo3-panel-border-radius-inner-top) var(--typo3-panel-border-radius-inner-top) var(--typo3-panel-border-radius-inner-bottom) var(--typo3-panel-border-radius-inner-bottom);outline-offset:0;margin:0} +.panel-heading:not(:last-child):not(.collapsed):not(:has(.collapsed)){--typo3-panel-border-radius-inner-bottom:0} +.panel-heading [data-bs-toggle=collapse]{outline:0} +.panel-heading:has([data-bs-toggle=collapse]:focus-visible){z-index:1;outline:.25rem solid color-mix(in srgb,var(--typo3-panel-border-color),transparent 25%)} +.panel-heading .caret{--typo3-caret-color:var(--typo3-panel-header-color)} +.panel-heading.collapsed .caret,.panel-heading:has(.collapsed) .caret,.panel-heading:has(.form-irre-header-button[aria-expanded=false]) .caret{--typo3-caret-rotation:calc(-90deg * var(--typo3-position-modifier))} +.panel-heading-row{flex-grow:1;display:flex;align-items:center;max-width:100%;gap:.5rem} +.panel-heading-row .panel-button{width:auto} +.panel-title{font-size:var(--typo3-font-size);margin-top:0;margin-bottom:0;flex-grow:1} +.panel-heading:has([data-bs-toggle=collapse]:hover) .panel-title{text-decoration:underline} +.panel-badge,.panel-icon{display:flex;justify-content:center;align-items:center} +.panel-actions{display:flex;align-items:center;flex-wrap:wrap;gap:.25rem} +.panel-body{padding:var(--typo3-panel-padding-y) var(--typo3-panel-padding-x)} +.panel-body:last-child{border-end-start-radius:var(--typo3-panel-border-radius-inner-bottom);border-end-end-radius:var(--typo3-panel-border-radius-inner-bottom)} .panel-body>:first-child{margin-top:0} .panel-body>:last-child{margin-bottom:0} .panel-body-overflow{overflow:auto;max-width:100%} -.panel-footer{padding:var(--panel-padding)} -.panel-table td:first-child,.panel-table th:first-child{padding-inline-start:var(--panel-header-padding-x)} -.panel-table td:last-child,.panel-table th:last-child{padding-inline-end:var(--panel-header-padding-x)} -.panel-list{padding-left:var(--panel-padding)} -.panel-list li{padding-bottom:.2rem} -.panel-condensed{--panel-padding:.5rem;--panel-header-padding-x:.5rem;--panel-header-padding-y:.5rem} +.panel-collapse{overflow:hidden} +.panel-collapse:last-child{border-end-start-radius:var(--typo3-panel-border-radius-inner-bottom);border-end-end-radius:var(--typo3-panel-border-radius-inner-bottom)} +.panel-footer{padding:var(--typo3-panel-padding-y) var(--typo3-panel-padding-x)} +.panel-list{padding-left:var(--typo3-panel-padding-x)} +.panel-list>li+li{margin-top:.2rem} +.panel-condensed{--typo3-panel-padding-y:var(--typo3-panel-sm-padding-y);--typo3-panel-padding-x:var(--typo3-panel-sm-padding-x)} .panel-collapsed .panel-collapse{display:none;visibility:hidden} -.panel-tab{--panel-border-radius:0;border:1px solid #ccc;background-color:#fafafa} -.tab-pane>.h2+.form-section,.tab-pane>.panel-tab:first-child,.tab-pane>h2+.form-section{border-top:none} -.panel-primary{--panel-border-color:var(--panel-primary-border-color);--panel-progress-bg:var(--panel-primary-progress-bg);--panel-heading-color:var(--panel-primary-heading-color);--panel-heading-bg:var(--panel-primary-heading-bg)} -.panel-secondary{--panel-border-color:var(--panel-secondary-border-color);--panel-progress-bg:var(--panel-secondary-progress-bg);--panel-heading-color:var(--panel-secondary-heading-color);--panel-heading-bg:var(--panel-secondary-heading-bg)} -.panel-success{--panel-border-color:var(--panel-success-border-color);--panel-progress-bg:var(--panel-success-progress-bg);--panel-heading-color:var(--panel-success-heading-color);--panel-heading-bg:var(--panel-success-heading-bg)} -.panel-info{--panel-border-color:var(--panel-info-border-color);--panel-progress-bg:var(--panel-info-progress-bg);--panel-heading-color:var(--panel-info-heading-color);--panel-heading-bg:var(--panel-info-heading-bg)} -.panel-warning{--panel-border-color:var(--panel-warning-border-color);--panel-progress-bg:var(--panel-warning-progress-bg);--panel-heading-color:var(--panel-warning-heading-color);--panel-heading-bg:var(--panel-warning-heading-bg)} -.panel-danger{--panel-border-color:var(--panel-danger-border-color);--panel-progress-bg:var(--panel-danger-progress-bg);--panel-heading-color:var(--panel-danger-heading-color);--panel-heading-bg:var(--panel-danger-heading-bg)} -.panel-light{--panel-border-color:var(--panel-light-border-color);--panel-progress-bg:var(--panel-light-progress-bg);--panel-heading-color:var(--panel-light-heading-color);--panel-heading-bg:var(--panel-light-heading-bg)} -.panel-default{--panel-border-color:var(--panel-default-border-color);--panel-progress-bg:var(--panel-default-progress-bg);--panel-heading-color:var(--panel-default-heading-color);--panel-heading-bg:var(--panel-default-heading-bg)} -.panel-notice{--panel-border-color:var(--panel-notice-border-color);--panel-progress-bg:var(--panel-notice-progress-bg);--panel-heading-color:var(--panel-notice-heading-color);--panel-heading-bg:var(--panel-notice-heading-bg)} -.panel-dark{--panel-border-color:var(--panel-dark-border-color);--panel-progress-bg:var(--panel-dark-progress-bg);--panel-heading-color:var(--panel-dark-heading-color);--panel-heading-bg:var(--panel-dark-heading-bg)} -.panel-active{--panel-border-color:var(--panel-primary-border-color);--panel-progress-bg:var(--panel-primary-progress-bg);--panel-heading-color:var(--panel-primary-heading-color);--panel-heading-bg:var(--panel-primary-heading-bg)} -.panel-feature{--panel-border-color:var(--panel-success-border-color);--panel-progress-bg:var(--panel-success-progress-bg);--panel-heading-color:var(--panel-success-heading-color);--panel-heading-bg:var(--panel-success-heading-bg)} -.panel-important{--panel-border-color:var(--panel-info-border-color);--panel-progress-bg:var(--panel-info-progress-bg);--panel-heading-color:var(--panel-info-heading-color);--panel-heading-bg:var(--panel-info-heading-bg)} -.panel-deprecation{--panel-border-color:var(--panel-warning-border-color);--panel-progress-bg:var(--panel-warning-progress-bg);--panel-heading-color:var(--panel-warning-heading-color);--panel-heading-bg:var(--panel-warning-heading-bg)} -.panel-breaking{--panel-border-color:var(--panel-danger-border-color);--panel-progress-bg:var(--panel-danger-progress-bg);--panel-heading-color:var(--panel-danger-heading-color);--panel-heading-bg:var(--panel-danger-heading-bg)} -.panel-collapse>.alert,.panel>.alert{margin:0;border:none;border-top:var(--panel-border-width) solid var(--panel-border-color);--typo3-alert-border-radius:0} +.panel-active,.panel-primary{--typo3-panel-header-color:var(--typo3-panel-primary-header-color);--typo3-panel-header-bg:var(--typo3-panel-primary-header-bg);--typo3-panel-border-color:var(--typo3-panel-primary-border-color)} +.panel-secondary{--typo3-panel-header-color:var(--typo3-panel-secondary-header-color);--typo3-panel-header-bg:var(--typo3-panel-secondary-header-bg);--typo3-panel-border-color:var(--typo3-panel-secondary-border-color)} +.panel-important,.panel-info{--typo3-panel-header-color:var(--typo3-panel-info-header-color);--typo3-panel-header-bg:var(--typo3-panel-info-header-bg);--typo3-panel-border-color:var(--typo3-panel-info-border-color)} +.panel-feature,.panel-success{--typo3-panel-header-color:var(--typo3-panel-success-header-color);--typo3-panel-header-bg:var(--typo3-panel-success-header-bg);--typo3-panel-border-color:var(--typo3-panel-success-border-color)} +.panel-deprecation,.panel-warning{--typo3-panel-header-color:var(--typo3-panel-warning-header-color);--typo3-panel-header-bg:var(--typo3-panel-warning-header-bg);--typo3-panel-border-color:var(--typo3-panel-warning-border-color)} +.panel-breaking,.panel-danger{--typo3-panel-header-color:var(--typo3-panel-danger-header-color);--typo3-panel-header-bg:var(--typo3-panel-danger-header-bg);--typo3-panel-border-color:var(--typo3-panel-danger-border-color)} +.panel-notice{--typo3-panel-header-color:var(--typo3-panel-notice-header-color);--typo3-panel-header-bg:var(--typo3-panel-notice-header-bg);--typo3-panel-border-color:var(--typo3-panel-notice-border-color)} +.panel-default{--typo3-panel-header-color:var(--typo3-panel-default-header-color);--typo3-panel-header-bg:var(--typo3-panel-default-header-bg);--typo3-panel-border-color:var(--typo3-panel-default-border-color)} +.panel-group{--typo3-panel-group-border-radius:var(--typo3-component-border-radius);--typo3-panel-group-border-radius-top:var(--typo3-panel-group-border-radius);--typo3-panel-group-border-radius-bottom:var(--typo3-panel-group-border-radius);--typo3-panel-group-box-shadow:var(--typo3-component-box-shadow);display:flex;flex-flow:column;margin-bottom:var(--typo3-spacing);border-radius:var(--typo3-panel-group-border-radius-top) var(--typo3-panel-group-border-radius-top) var(--typo3-panel-group-border-radius-bottom) var(--typo3-panel-group-border-radius-bottom);box-shadow:var(--typo3-panel-group-box-shadow)} +.panel-group>.panel{--typo3-panel-border-radius-top:0px;--typo3-panel-border-radius-bottom:0px;margin-bottom:0;box-shadow:none;margin-top:calc(var(--typo3-panel-border-width) * -1)} +.panel-group>.panel:first-child{margin-top:0;--typo3-panel-border-radius-top:var(--typo3-panel-group-border-radius)} +.panel-group>.panel:last-child{--typo3-panel-border-radius-bottom:var(--typo3-panel-group-border-radius)} +.panel,.panel-heading{transition:all .2s ease-in-out;transition-property:box-shadow,border,border-radius,transform} +.panel-collapse>.alert,.panel>.alert{margin:0;border:none;border-top:var(--typo3-panel-border-width) solid var(--typo3-panel-border-color);--typo3-alert-border-radius:0} .panel-collapse>.form-section,.panel-collapse>.tab-content>.form-section,.panel-collapse>.tab-content>.tab-pane>.form-section,.panel-collapse>[role=tabpanel]>.tab-content>.form-section,.panel-collapse>[role=tabpanel]>.tab-content>.tab-pane>.form-section,.panel>.form-section,.panel>.tab-content>.form-section,.panel>.tab-content>.tab-pane>.form-section,.panel>[role=tabpanel]>.tab-content>.form-section,.panel>[role=tabpanel]>.tab-content>.tab-pane>.form-section{border-inline-start:0;border-inline-end:0;border-bottom:0} -.panel-collapse>.nav-tabs,.panel-collapse>[role=tabpanel]>.nav-tabs,.panel>.nav-tabs,.panel>[role=tabpanel]>.nav-tabs{border-top:1px solid #ccc;padding-top:8px} +.panel-collapse>.nav-tabs,.panel-collapse>[role=tabpanel]>.nav-tabs,.panel>.nav-tabs,.panel>[role=tabpanel]>.nav-tabs{border-top:1px solid var(--typo3-panel-border-color);padding-top:8px} .panel-collapse>.nav-tabs>li,.panel-collapse>[role=tabpanel]>.nav-tabs>li,.panel>.nav-tabs>li,.panel>[role=tabpanel]>.nav-tabs>li{margin-inline-start:-1px} .table{--typo3-table-font-size:var(--typo3-font-size);--typo3-table-color:var(--typo3-component-color);--typo3-table-bg:var(--typo3-component-bg);--typo3-table-bg-type:initial;--typo3-table-bg-state:initial;--typo3-table-border-style:none;--typo3-table-border-width:var(--typo3-component-border-width);--typo3-table-border-color:var(--typo3-component-border-color);--typo3-table-padding-y:.75rem;--typo3-table-padding-x:1rem;--typo3-table-sm-font-size:var(--typo3-font-size-small);--typo3-table-sm-padding-y:.5rem;--typo3-table-sm-padding-x:.75rem;--typo3-table-primary-color:var(--typo3-surface-container-primary-text);--typo3-table-primary-bg:var(--typo3-surface-container-primary);--typo3-table-primary-border-color:var(--typo3-state-primary-border-color);--typo3-table-secondary-color:var(--typo3-surface-container-secondary-text);--typo3-table-secondary-bg:var(--typo3-surface-container-secondary);--typo3-table-secondary-border-color:var(--typo3-state-secondary-border-color);--typo3-table-info-color:var(--typo3-surface-container-info-text);--typo3-table-info-bg:var(--typo3-surface-container-info);--typo3-table-info-border-color:var(--typo3-state-info-border-color);--typo3-table-success-color:var(--typo3-surface-container-success-text);--typo3-table-success-bg:var(--typo3-surface-container-success);--typo3-table-success-border-color:var(--typo3-state-success-border-color);--typo3-table-warning-color:var(--typo3-surface-container-warning-text);--typo3-table-warning-bg:var(--typo3-surface-container-warning);--typo3-table-warning-border-color:var(--typo3-state-warning-border-color);--typo3-table-danger-color:var(--typo3-surface-container-danger-text);--typo3-table-danger-bg:var(--typo3-surface-container-danger);--typo3-table-danger-border-color:var(--typo3-state-danger-border-color);--typo3-table-notice-color:var(--typo3-surface-container-notice-text);--typo3-table-notice-bg:var(--typo3-surface-container-notice);--typo3-table-notice-border-color:var(--typo3-state-notice-border-color);--typo3-table-default-color:var(--typo3-surface-container-default-text);--typo3-table-default-bg:var(--typo3-surface-container-default);--typo3-table-default-border-color:var(--typo3-state-default-border-color);font-size:var(--typo3-table-font-size);width:100%;border-color:var(--typo3-table-border-color);margin-bottom:var(--typo3-spacing)} .table>:not(caption)>*>*{padding:var(--typo3-table-padding-y) calc(var(--typo3-table-padding-x)/ 2);color:var(--typo3-table-color);background-color:var(--typo3-table-bg-state,var(--typo3-table-bg-type,var(--typo3-table-bg)));border-color:var(--typo3-table-border-color);border-bottom-width:var(--typo3-table-border-width);vertical-align:middle} +.table>:not(caption)>*>*>:last-child{margin-bottom:0} .table>:not(caption)>*>:is(th){white-space:nowrap} .table>:not(caption)>*>:first-child{padding-inline-start:var(--typo3-table-padding-x)} .table>:not(caption)>*>:last-child{padding-inline-end:var(--typo3-table-padding-x)} @@ -3037,6 +3050,8 @@ td .table-fit{margin-bottom:0} .simpletable td,.simpletable th{padding:.25em 1em} .simpletable td:first-child,.simpletable th:first-child{padding-inline-start:0} .simpletable td:last-child,.simpletable th:last-child{padding-inline-end:0} +.tab-pane>.panel{--typo3-panel-bg:#fafafa;--typo3-panel-border-color:#ccc;--typo3-panel-border-radius:0} +.tab-pane>.visually-hidden:first-child+.form-section,.tab-pane>:first-child{border-top:none} select-pure{--typo3-form-selectpure-border-radius:var(--typo3-input-border-radius);--typo3-form-selectpure-border-width:var(--typo3-input-border-width);--typo3-form-selectpure-border-color:var(--typo3-input-border-color);--typo3-form-selectpure-padding-x:var(--typo3-input-padding-x);--typo3-form-selectpure-padding-y:var(--typo3-input-padding-y);--typo3-form-selectpure-font-size:var(--typo3-input-font-size);--typo3-form-selectpure-line-height:var(--typo3-input-line-height);--typo3-form-selectpure-color:var(--typo3-input-color);--typo3-form-selectpure-bg:var(--typo3-input-bg);--typo3-form-selectpure-hover-color:var(--typo3-input-hover-color);--typo3-form-selectpure-hover-bg:var(--typo3-input-hover-bg);--typo3-form-selectpure-focus-border-color:var(--typo3-input-focus-border-color);--typo3-form-selectpure-disabled-color:var(--typo3-input-disabled-color);--typo3-form-selectpure-disabled-bg:var(--typo3-input-disabled-bg);--font-size:var(--typo3-form-selectpure-font-size);--font-family:inherit;--font-weight:400;--border-radius:var(--typo3-form-selectpure-border-radius);--border-width:var(--typo3-form-selectpure-border-width);--border-color:var(--typo3-form-selectpure-border-color);--padding:calc(var(--typo3-form-selectpure-padding-y) - 4px) var(--typo3-form-selectpure-padding-x);--select-height:calc(var(--typo3-form-selectpure-padding-y) * 2 + var(--typo3-form-selectpure-font-size) * var(--typo3-form-selectpure-line-height) + var(--typo3-form-selectpure-border-width) * 2);--select-width:100%;--color:var(--typo3-form-selectpure-color);--background-color:var(--typo3-form-selectpure-bg);--hover-color:var(--typo3-form-selectpure-hover-color);--hover-background-color:var(--typo3-form-selectpure-hover-bg);--disabled-color:var(--typo3-form-selectpure-disabled-color);--disabled-background-color:var(--typo3-form-selectpure-disabled-bg);--select-outline:.25rem solid color-mix(in srgb, var(--typo3-form-selectpure-focus-border-color), transparent 25%);--selected-background-color:var(--typo3-component-active-bg);--selected-color:var(--typo3-component-active-color);--dropdown-gap:calc(var(--typo3-spacing) * .5);--dropdown-items:5;--dropdown-z-index:2} .input-group>select-pure{position:relative;flex:1 1 auto} .cropper-container{position:relative;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none} @@ -3396,9 +3411,6 @@ typo3-backend-form-selecttree-toolbar{display:block} @media (min-width:992px){ .modal-image-manipulation .modal-panel-sidebar{width:300px} } -.modal-image-manipulation .panel-heading .is-active{pointer-events:none} -.modal-image-manipulation .panel{margin-bottom:0} -.modal-image-manipulation .panel-body{border-inline-start:2px solid #ff8700} .modal-type-iframe{padding:0} .modal-type-iframe .modal-body{padding:0} .modal-iframe{display:block;border:0;height:100%;width:100%;position:absolute;top:0;inset-inline-start:0} @@ -3538,17 +3550,17 @@ typo3-backend-live-search-result-item-action>* .livesearch-result-item-title .sm 0%,100%{opacity:1} 50%{opacity:.4} } -.recordlist{overflow:hidden;background:var(--panel-bg);box-shadow:var(--panel-box-shadow);border-radius:var(--panel-border-radius);border:var(--panel-border-width) solid var(--panel-default-border-color);margin-bottom:var(--typo3-spacing)} +.recordlist{--typo3-recordlist-color:var(--typo3-component-color);--typo3-recordlist-bg:var(--typo3-component-bg);--typo3-recordlist-border-color:color-mix(in srgb, var(--typo3-recordlist-bg), var(--typo3-recordlist-color) 15%);--typo3-recordlist-border-width:var(--typo3-component-border-width);--typo3-recordlist-border-radius:var(--typo3-component-border-radius);--typo3-recordlist-border-radius-top:var(--typo3-recordlist-border-radius);--typo3-recordlist-border-radius-bottom:var(--typo3-recordlist-border-radius);--typo3-recordlist-border-radius-inner-top:max(0px, calc(var(--typo3-recordlist-border-radius-top) - var(--typo3-recordlist-border-width)));--typo3-recordlist-border-radius-inner-bottom:max(0px, calc(var(--typo3-recordlist-border-radius-bottom) - var(--typo3-recordlist-border-width)));--typo3-recordlist-padding-y:.75rem;--typo3-recordlist-padding-x:1rem;--typo3-recordlist-header-bg:var(--typo3-surface-container-low);--typo3-recordlist-header-color:var(--typo3-text-color-base);--typo3-recordlist-spacing:var(--typo3-component-spacing);--typo3-recordlist-box-shadow:var(--typo3-component-box-shadow);--typo3-recordlist-progress-bg:var(--typo3-state-primary-bg);overflow:hidden;background:var(--typo3-recordlist-bg);box-shadow:var(--typo3-recordlist-box-shadow);border-radius:var(--typo3-recordlist-border-radius);border:var(--typo3-recordlist-border-width) solid var(--typo3-recordlist-border-color);margin-bottom:var(--typo3-spacing)} .recordlist table tr td.deletePlaceholder{text-decoration:line-through} .recordlist .alert,.recordlist .table-fit{box-shadow:none;border-radius:0;border-left:0;border-right:0;border-bottom:0;margin-bottom:0} -.recordlist .alert{padding:var(--panel-header-padding-y) var(--typo3-component-padding-x)} +.recordlist .alert{padding:var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x)} .recordlist .pagination{display:inline-flex} .recordlist+.recordlist{margin-top:calc(var(--typo3-spacing) * 1.5)} .recordlist tr{transition:opacity .5s;opacity:1} .recordlist tr.record-pulse{animation:record-pulse 1s ease-out 0s 1 normal none} .recordlist tr.record-deleted{opacity:0!important} -.recordlist-heading{display:flex;align-items:center;flex-wrap:wrap;color:var(--panel-default-heading-color);background:var(--panel-default-heading-bg);padding:var(--panel-header-padding-y) var(--panel-header-padding-x);gap:var(--panel-header-padding-y) var(--panel-header-padding-x)} -.recordlist-heading-row{flex-grow:1;display:flex;align-items:center;flex-wrap:wrap;max-width:100%;gap:var(--panel-header-padding-y) var(--panel-header-padding-x)} +.recordlist-heading{display:flex;align-items:center;flex-wrap:wrap;color:var(--typo3-recordlist-header-color);background:var(--typo3-recordlist-header-bg);padding:var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x);gap:var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x)} +.recordlist-heading-row{flex-grow:1;display:flex;align-items:center;flex-wrap:wrap;max-width:100%;gap:var(--typo3-recordlist-padding-y) var(--typo3-recordlist-padding-x)} .recordlist-heading-title{font-weight:700;flex-grow:1;width:250px;max-width:100%} .recordlist-heading-actions,.recordlist-heading-selection{display:flex;align-items:center;flex-wrap:wrap;gap:.25rem} .recordlist-heading-actions [data-recordlist-action=new]{order:1} @@ -3710,9 +3722,10 @@ typo3-rte-ckeditor-ckeditor5 .ck.ck-style-panel .ck-style-grid .ck-style-grid__b .collapse-horizontal{height:auto;width:0;vertical-align:middle;overflow:hidden} .collapse-horizontal.show{display:inline-block;width:auto} .collapse-horizontal.collapsing{display:inline-block;transition-property:width,visibility;width:0} +.cropper{color-scheme:only dark} .cropper .cropper-line{background-color:transparent} -.cropper .cropper-dashed{border:1px dashed #ff8700} -.cropper .cropper-point{background-color:#ff8700} +.cropper .cropper-dashed{border:1px dashed var(--typo3-state-primary-bg)} +.cropper .cropper-point{background-color:var(--typo3-state-primary-bg)} .cropper .cropper-point.point-nw{left:0;top:0} .cropper .cropper-point.point-w{left:0} .cropper .cropper-point.point-sw{left:0;bottom:0} @@ -3722,30 +3735,21 @@ typo3-rte-ckeditor-ckeditor5 .ck.ck-style-panel .ck-style-grid .ck-style-grid__b .cropper .cropper-point.point-se:before{background-color:#fff} .cropper .cropper-point.point-n{top:0} .cropper .cropper-point.point-s{bottom:0} -.cropper .cropper-view-box{outline:1px dashed #ff8700} +.cropper .cropper-view-box{outline:1px dashed var(--typo3-state-primary-bg)} .cropper .cropper-bg{background-image:url(../Images/cropper-background.png)} .cropper .cropper-image-container{direction:ltr;display:block;width:100%;max-width:1000px;max-height:calc(100vh - 250px)} @media (min-width:992px){ .cropper .cropper-image-container{max-height:100%} } .cropper .ratio-buttons{margin-bottom:10px} -.cropper .ratio-buttons .btn.btn-default{margin-bottom:5px} .cropper .ratio-buttons .btn:not(.active) .icon{display:none} -.cropper .panel-group{position:relative;margin:-15px} -.cropper .panel-group [aria-expanded=true]{border-inline-start:2px solid #ff8700;position:relative} -.cropper .panel-group [aria-expanded=true][data-bs-toggle=collapse]{background-color:#333} -.cropper .panel-group [aria-expanded=false]{border-inline-start:2px solid #444;position:relative} -.cropper .panel-group label,.cropper .panel-group table{color:#fff} -.cropper .panel-group label:has(input[type=radio]:focus),.cropper .panel-group table:has(input[type=radio]:focus){color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)} -.cropper .panel-collapse.collapse{background-color:#2c2c2c!important} -.cropper .panel-heading{padding:0} -.cropper .panel-heading .panel-title>[data-crop-variant]{display:flex;padding:10px 15px;justify-content:space-between} -.cropper .panel-heading .panel-title>a{text-decoration:none!important;-webkit-user-select:none;-moz-user-select:none;user-select:none;font-size:13px} -.cropper .panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#333} -.cropper .panel,.cropper .panel-default .panel-heading,.cropper .panel-group{background:#222;border:none;color:#fff} +.cropper .panel-group{--typo3-panel-border-radius:0;position:relative;margin:-15px} +.cropper .panel-group .panel{border:0;border-inline-start:3px solid var(--typo3-panel-border-color);margin-bottom:0} +.cropper .panel-group .panel:has(.panel-heading):not(:has(.collapsed)){border-color:var(--typo3-state-primary-bg)} +.cropper .panel-group .panel+.panel{margin-top:1px} .cropper .cropper-container.cropper-bg{overflow:visible} .cropper .cropper-crop-box{overflow:hidden} -.cropper .cropper-crop-box:after{background-color:#ff8700;content:"Cropped area";position:absolute;inset-inline-start:0;top:0;font-size:10px;color:#000;height:16px;width:100%;max-width:80px;text-overflow:ellipsis;white-space:nowrap;padding:0 4px;pointer-events:none;overflow:hidden} +.cropper .cropper-crop-box:after{color:var(--typo3-state-primary-color);background-color:var(--typo3-state-primary-bg);font-size:var(--typo3-font-size-small);content:"Cropped area";position:absolute;inset-inline-start:0;top:0;text-overflow:ellipsis;white-space:nowrap;padding:.5em .75em;pointer-events:none;overflow:hidden} .cropper .cropper-line.line-w{left:0} .cropper .cropper-line.line-e{right:0} .cropper .cropper-line.line-n{top:0} @@ -3757,7 +3761,7 @@ typo3-rte-ckeditor-ckeditor5 .ck.ck-style-panel .ck-style-grid .ck-style-grid__b .cropper .ui-resizable-handle.ui-resizable-w{left:0} .cropper .ui-resizable-handle.ui-resizable-n{top:0} .cropper .ui-resizable-handle.ui-resizable-s{bottom:0} -.cropper .ui-resizable-handle.ui-resizable-ne,.cropper .ui-resizable-handle.ui-resizable-nw,.cropper .ui-resizable-handle.ui-resizable-se,.cropper .ui-resizable-handle.ui-resizable-sw{transform:none;background-color:#ccc;height:6px;width:6px} +.cropper .ui-resizable-handle.ui-resizable-ne,.cropper .ui-resizable-handle.ui-resizable-nw,.cropper .ui-resizable-handle.ui-resizable-se,.cropper .ui-resizable-handle.ui-resizable-sw{transform:none;background-color:var(--typo3-state-primary-bg);height:6px;width:6px} .cropper .ui-resizable-handle.ui-resizable-nw{top:0;left:0} .cropper .ui-resizable-handle.ui-resizable-ne{top:0;right:0} .cropper .ui-resizable-handle.ui-resizable-se{bottom:0;right:0} @@ -3775,7 +3779,7 @@ typo3-rte-ckeditor-ckeditor5 .ck.ck-style-panel .ck-style-grid .ck-style-grid__b .cropper .cropper-preview-thumbnail-image{inset-inline-start:0;top:0} .cropper .wide .cropper-preview-thumbnail-image{width:100%;height:auto} .cropper .tall .cropper-preview-thumbnail-image{width:auto;height:100%} -.cropper .cropper-preview-thumbnail-crop-area{border:1px solid #ff8700;position:absolute;z-index:10;overflow:hidden} +.cropper .cropper-preview-thumbnail-crop-area{border:1px solid var(--typo3-state-primary-bg);position:absolute;z-index:10;overflow:hidden} .cropper .cropper-preview-thumbnail-focus-area{background-color:rgba(215,187,0,.7);position:absolute;z-index:11} :root .cropper-preview-thumbnail-crop-image{image-orientation:0deg;display:block;height:100%;width:100%;min-width:0;max-width:none;min-height:0;max-height:none} .cropper-preview-container{overflow:hidden;position:relative} @@ -3848,7 +3852,6 @@ input[type=range].slider[disabled]::-ms-track{cursor:not-allowed} .nav-tabs>li.has-validation-error>a.nav-link.active:before,.nav.nav-tabs>li.has-validation-error:not(.nav-item)>a.active:not(.nav-link):before{background-color:#d13a2e;color:#fff} .typo3-TCEforms{width:100%} .sortableHandle{cursor:move!important} -.t3-form-field-add-flexsection{border-top:1px solid #cdcdcd;padding:10px 5px 5px 0} img.t3-tceforms-sysfile-imagepreview{float:var(--typo3-position-start);margin-inline-end:10px;margin-bottom:10px} .typo3-TCEforms span.typo3-TCEforms-newToken{color:#900;font-weight:700} .t3-form-original-language{color:var(--typo3-state-default-color);background-color:var(--typo3-state-default-bg);border:var(--typo3-input-border-width) solid var(--typo3-state-default-border-color);padding:calc(var(--typo3-input-padding-y)/ 2) var(--typo3-input-padding-x);border-radius:var(--typo3-input-border-radius);font-size:.625rem;word-break:break-all} @@ -3974,7 +3977,8 @@ body[data-typo3-login-ready]{overflow-y:auto} .typo3-login-carousel-control:hover{opacity:1} .typo3-login-carousel-control.left{inset-inline-start:-20px;border:1px solid var(--typo3-card-border-color);border-inline-end:0;border-radius:var(--typo3-card-border-radius) 0 0 var(--typo3-card-border-radius)} .typo3-login-carousel-control.right{inset-inline-end:-20px;border:1px solid var(--typo3-card-border-color);border-inline-start:0;border-radius:0 var(--typo3-card-border-radius) var(--typo3-card-border-radius) 0} -.typo3-login-copyright-link{font-weight:400!important} +.typo3-login-copyright-link{display:flex;border:none;padding:0;width:100%;background-color:transparent;justify-content:space-between;font-weight:400!important} +.typo3-login-copyright-link:hover{text-decoration:underline} .typo3-login-copyright-link>img{float:var(--typo3-position-end);margin-top:-4px} .typo3-login-copyright-text{font-size:.95em;padding-top:1em;color:var(--typo3-login-copyright-color)} .typo3-login-copyright-text>:first-child{margin-top:0} @@ -4009,16 +4013,14 @@ video{background-color:#000} .grideditor-action-shrink-left{inset-inline-start:calc(50% - var(--grideditor-action-size) - var(--grideditor-action-spacing))} .form-control-holder{position:relative} .formengine-field-item{display:block;position:relative} -.form-group .panel,.form-group .panel-group{overflow:visible} -.form-group.has-error .btn-toolbar label:before{font-family:inherit;font-size:inherit;margin-right:inherit;text-align:inherit;content:"";color:inherit;display:block} -.form-irre-header{display:flex;align-items:center;margin:-5px;-webkit-user-select:none;-moz-user-select:none;user-select:none} -.form-irre-header-cell{vertical-align:middle;white-space:nowrap;padding:5px} -.form-irre-header-button{display:flex;text-align:start;align-items:center;align-self:stretch;background:0 0;border:0;width:100%;margin-inline-start:-15px;padding-inline-start:20px} -.form-irre-header-body{width:100%;font-weight:400;white-space:normal;padding-inline-start:5px} +.form-irre-header{display:flex;align-items:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;gap:.25rem} +.form-irre-header-cell{vertical-align:middle;white-space:nowrap} +.form-irre-header-button{display:flex;text-align:start;align-items:center;align-self:stretch;background:0 0;border:0;width:100%;padding:0;gap:.25rem} +.form-irre-header-body{width:100%;font-weight:400;white-space:normal} .form-irre-header-body dd,.form-irre-header-body dl,.form-irre-header-body dt{margin-bottom:0} .form-irre-header-icon{padding-inline-end:0} -.form-irre-header-thumbnail{padding-inline-end:5px} -.form-irre-header-control{cursor:auto} +.form-irre-header-thumbnail{padding-inline-end:.25rem} +.form-irre-header-control{display:flex;align-items:center;gap:.25rem} textarea.formengine-textarea{resize:none} .sticky-form-actions{position:sticky;top:0;z-index:2;padding:calc(1rem / 2) 1rem;background:#fff} .modal-body .sticky-form-actions{margin-inline:calc(var(--bs-modal-padding) * -1);margin-bottom:var(--bs-modal-padding);padding:calc(var(--bs-modal-padding)/ 2) var(--bs-modal-padding);border-bottom:var(--bs-modal-border-width) solid var(--bs-modal-border-color)} @@ -4105,15 +4107,13 @@ td.permission-column-group{padding-inline-start:0;width:200px;white-space:nowrap .install-tool-installer{overflow-y:auto} .install-tool-modal .panel-rst .panel-collapse,.install-tool-modal .panel-version .panel-collapse{position:relative;overflow:auto} .install-tool-modal .panel-rst .panel-heading,.install-tool-modal .panel-version .panel-heading{position:relative} -.install-tool-modal .panel-rst .panel-heading button.link-action,.install-tool-modal .panel-version .panel-heading button.link-action{padding:0} .install-tool-modal .panel-rst .panel-heading strong,.install-tool-modal .panel-version .panel-heading strong{line-height:1.5em} -.install-tool-modal .panel-rst .rst-tags,.install-tool-modal .panel-version .rst-tags{position:absolute;display:flex;gap:.5rem;top:calc(var(--panel-padding)/ 2);inset-inline-end:var(--panel-padding)} -.install-tool-modal .panel-rst .rst-tags~.panel-body,.install-tool-modal .panel-version .rst-tags~.panel-body{padding-top:calc(var(--panel-padding) * 2)} -.install-tool-modal .panel-rst .rst-links,.install-tool-modal .panel-version .rst-links{position:absolute;display:flex;gap:.5rem;bottom:calc(var(--panel-padding)/ 2);inset-inline-end:var(--panel-padding)} -.install-tool-modal .panel-rst .rst-links~.panel-body,.install-tool-modal .panel-version .rst-links~.panel-body{padding-bottom:calc(var(--panel-padding) * 2)} +.install-tool-modal .panel-rst .rst-tags,.install-tool-modal .panel-version .rst-tags{position:absolute;display:flex;gap:.5rem;top:calc(var(--typo3-panel-padding-y)/ 2);inset-inline-end:var(--typo3-panel-padding-x)} +.install-tool-modal .panel-rst .rst-tags~.panel-body,.install-tool-modal .panel-version .rst-tags~.panel-body{padding-top:calc(var(--typo3-panel-padding-y) * 2)} +.install-tool-modal .panel-rst .rst-links,.install-tool-modal .panel-version .rst-links{position:absolute;display:flex;gap:.5rem;bottom:calc(var(--typo3-panel-padding-y)/ 2);inset-inline-end:var(--typo3-panel-padding-x)} +.install-tool-modal .panel-rst .rst-links~.panel-body,.install-tool-modal .panel-version .rst-links~.panel-body{padding-bottom:calc(var(--typo3-panel-padding-y) * 2)} .install-tool-modal .list-group-item a{display:block} .install-tool-modal .list-group-item.active a{color:#fff} -.install-tool-modal a[data-bs-toggle=collapse]{display:block} .install-tool-modal .table .t3-languagePacks-inactive,.install-tool-modal .table .t3-languagePacks-inactive td{color:#aaa} .install-tool-modal .t3-install-displaytwinimageimages{border:1px solid #ccc;border-radius:4px;padding:10px;margin-bottom:var(--typo3-spacing)} .install-tool-modal .t3-install-displaytwinimagetextarea pre{border-top:0} @@ -4125,14 +4125,6 @@ td.permission-column-group{padding-inline-start:0;width:200px;white-space:nowrap .install-tool-modal ul{word-wrap:anywhere} .install-tool-modal .module-action-list{display:flex;align-items:center;gap:var(--typo3-spacing)} .install-tool-modal .module-action-list .module-action-list-description{flex-grow:1} -.panel-success.risk-high{--panel-success-high-border-color:#509176;--panel-success-high-progress-bg:#247554;--panel-success-high-heading-color:#000;--panel-success-high-heading-bg:#87b3a1;--panel-border-color:var(--panel-success-high-border-color);--panel-progress-bg:var(--panel-success-high-progress-bg);--panel-heading-color:var(--panel-success-high-heading-color);--panel-heading-bg:var(--panel-success-high-heading-bg)} -.panel-success.risk-medium{--panel-success-medium-border-color:#7cac98;--panel-success-medium-progress-bg:#247554;--panel-success-medium-heading-color:#000;--panel-success-medium-heading-bg:#b2cfc3;--panel-border-color:var(--panel-success-medium-border-color);--panel-progress-bg:var(--panel-success-medium-progress-bg);--panel-heading-color:var(--panel-success-medium-heading-color);--panel-heading-bg:var(--panel-success-medium-heading-bg)} -.panel-warning.risk-high{--panel-warning-high-border-color:#ffd65c;--panel-warning-high-progress-bg:#fc3;--panel-warning-high-heading-color:#000;--panel-warning-high-heading-bg:#ffe38f;--panel-border-color:var(--panel-warning-high-border-color);--panel-progress-bg:var(--panel-warning-high-progress-bg);--panel-heading-color:var(--panel-warning-high-heading-color);--panel-heading-bg:var(--panel-warning-high-heading-bg)} -.panel-warning.risk-medium{--panel-warning-medium-border-color:#ffe085;--panel-warning-medium-progress-bg:#fc3;--panel-warning-medium-heading-color:#000;--panel-warning-medium-heading-bg:#ffedb8;--panel-border-color:var(--panel-warning-medium-border-color);--panel-progress-bg:var(--panel-warning-medium-progress-bg);--panel-heading-color:var(--panel-warning-medium-heading-color);--panel-heading-bg:var(--panel-warning-medium-heading-bg)} -.panel-danger.risk-high{--panel-danger-high-border-color:#da6158;--panel-danger-high-progress-bg:#d13a2e;--panel-danger-high-heading-color:#000;--panel-danger-high-heading-bg:#e6938c;--panel-border-color:var(--panel-danger-high-border-color);--panel-progress-bg:var(--panel-danger-high-progress-bg);--panel-heading-color:var(--panel-danger-high-heading-color);--panel-heading-bg:var(--panel-danger-high-heading-bg)} -.panel-danger.risk-medium{--panel-danger-medium-border-color:#e38982;--panel-danger-medium-progress-bg:#d13a2e;--panel-danger-medium-heading-color:#000;--panel-danger-medium-heading-bg:#efbab6;--panel-border-color:var(--panel-danger-medium-border-color);--panel-progress-bg:var(--panel-danger-medium-progress-bg);--panel-heading-color:var(--panel-danger-medium-heading-color);--panel-heading-bg:var(--panel-danger-medium-heading-bg)} -.panel-info.risk-high{--panel-info-high-border-color:#bce3f1;--panel-info-high-progress-bg:#abdced;--panel-info-high-heading-color:#000;--panel-info-high-heading-bg:#d1ecf5;--panel-border-color:var(--panel-info-high-border-color);--panel-progress-bg:var(--panel-info-high-progress-bg);--panel-heading-color:var(--panel-info-high-heading-color);--panel-heading-bg:var(--panel-info-high-heading-bg)} -.panel-info.risk-medium{--panel-info-medium-border-color:#cdeaf4;--panel-info-medium-progress-bg:#abdced;--panel-info-medium-heading-color:#000;--panel-info-medium-heading-bg:#e2f3f9;--panel-border-color:var(--panel-info-medium-border-color);--panel-progress-bg:var(--panel-info-medium-progress-bg);--panel-heading-color:var(--panel-info-medium-heading-color);--panel-heading-bg:var(--panel-info-medium-heading-bg)} .localconf-list{display:flex;flex-direction:column;gap:1rem} .localconf-item{width:100%;border:1px solid #bebebe} .localconf-item.searchhit~.alert{display:none} diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/element/collapsible-element.js b/typo3/sysext/backend/Resources/Public/JavaScript/element/collapsible-element.js deleted file mode 100644 index 560539a39d01..000000000000 --- a/typo3/sysext/backend/Resources/Public/JavaScript/element/collapsible-element.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ -import RegularEvent from"@typo3/core/event/regular-event.js";import Icons from"@typo3/backend/icons.js";var IconIdentifier;!function(e){e.collapse="actions-view-list-collapse",e.expand="actions-view-list-expand"}(IconIdentifier||(IconIdentifier={}));class CollapsibleElement extends HTMLElement{connectedCallback(){this.registerEventHandler()}registerEventHandler(){new RegularEvent("click",this.toggleGroup).delegateTo(this,'button[data-bs-toggle="collapse"]')}toggleGroup(e,n){e.preventDefault();const t="true"===n.ariaExpanded,l=n.querySelector(".collapseIcon"),o=t?IconIdentifier.collapse:IconIdentifier.expand;Icons.getIcon(o,Icons.sizes.small).then((e=>{l.innerHTML=e}))}}window.customElements.define("typo3-backend-collapsible",CollapsibleElement); \ No newline at end of file diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js index be70739bf5bf..029d7dbd19b8 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import{AjaxDispatcher}from"@typo3/backend/form-engine/inline-relation/ajax-dispatcher.js";import NProgress from"nprogress";import Sortable from"sortablejs";import FormEngine from"@typo3/backend/form-engine.js";import FormEngineValidation from"@typo3/backend/form-engine-validation.js";import Icons from"@typo3/backend/icons.js";import InfoWindow from"@typo3/backend/info-window.js";import Modal from"@typo3/backend/modal.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Severity from"@typo3/backend/severity.js";import Utility from"@typo3/backend/utility.js";import{selector}from"@typo3/core/literals.js";var Selectors,States,Separators,SortDirections;!function(e){e.toggleSelector='[data-bs-toggle="formengine-file"]',e.controlSectionSelector=".t3js-formengine-file-header-control",e.deleteRecordButtonSelector=".t3js-editform-delete-file-reference",e.enableDisableRecordButtonSelector=".t3js-toggle-visibility-button",e.infoWindowButton='[data-action="infowindow"]',e.synchronizeLocalizeRecordButtonSelector=".t3js-synchronizelocalize-button",e.controlContainer=".t3js-file-controls"}(Selectors||(Selectors={})),function(e){e.new="isNewFileReference",e.visible="panel-visible",e.collapsed="panel-collapsed",e.notLoaded="t3js-not-loaded"}(States||(States={})),function(e){e.structureSeparator="-"}(Separators||(Separators={})),function(e){e.DOWN="down",e.UP="up"}(SortDirections||(SortDirections={}));class FilesControlContainer extends HTMLElement{constructor(){super(...arguments),this.container=null,this.recordsContainer=null,this.ajaxDispatcher=null,this.appearance=null,this.requestQueue={},this.progressQueue={},this.handlePostMessage=e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:foreignRelation:insert"===e.data.actionName){if(void 0===e.data.objectGroup)throw"No object group defined for message";if(e.data.objectGroup!==this.container.dataset.objectGroup)return;this.importRecord([e.data.objectGroup,e.data.uid]).then((()=>{if(e.source){const t={actionName:"typo3:foreignRelation:inserted",objectGroup:e.data.objectId,table:e.data.table,uid:e.data.uid};MessageUtility.send(t,e.source)}}))}if("typo3:foreignRelation:delete"===e.data.actionName){if(e.data.objectGroup!==this.container.dataset.objectGroup)return;const t=e.data.directRemoval||!1,o=[e.data.objectGroup,e.data.uid].join("-");this.deleteRecord(o,t)}}}connectedCallback(){const e=this.getAttribute("identifier")||"";this.container=this.querySelector(selector`[id="${e}"]`),null!==this.container&&(this.recordsContainer=this.container.querySelector(selector`[id="${this.container.getAttribute("id")}_records"]`),this.ajaxDispatcher=new AjaxDispatcher(this.container.dataset.objectGroup),this.registerEvents())}registerEvents(){this.registerInfoButton(),this.registerSort(),this.registerEnableDisableButton(),this.registerDeleteButton(),this.registerSynchronizeLocalize(),this.registerToggle(),new RegularEvent("message",this.handlePostMessage).bindTo(window),this.getAppearance().useSortable&&new Sortable(this.recordsContainer,{group:this.recordsContainer.getAttribute("id"),handle:".sortableHandle",onSort:()=>{this.updateSorting()}})}getFileReferenceContainer(e){return this.container.querySelector(selector`[data-object-id="${e}"]`)}getCollapseButton(e){return this.container.querySelector(selector`[aria-controls="${e}_fields"]`)}collapseElement(e,t){const o=this.getCollapseButton(t);e.classList.remove(States.visible),e.classList.add(States.collapsed),o.setAttribute("aria-expanded","false")}expandElement(e,t){const o=this.getCollapseButton(t);e.classList.remove(States.collapsed),e.classList.add(States.visible),o.setAttribute("aria-expanded","true")}isNewRecord(e){return this.getFileReferenceContainer(e).classList.contains(States.new)}updateExpandedCollapsedStateLocally(e,t){const o=this.getFileReferenceContainer(e),i=this.container.querySelectorAll('[name="uc[inlineView]['+o.dataset.topmostParentTable+"]["+o.dataset.topmostParentUid+"]"+o.dataset.fieldName+'"]');i.length&&(i[0].value=t?"1":"0")}registerToggle(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.loadRecordDetails(t.closest(Selectors.toggleSelector).parentElement.dataset.objectId)})).delegateTo(this.container,`${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`)}registerSort(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.changeSortingByButton(t.closest("[data-object-id]").dataset.objectId,t.dataset.direction)})).delegateTo(this.container,Selectors.controlSectionSelector+' [data-action="sort"]')}createRecord(e,t,o=null){let i=this.container.dataset.objectGroup;null!==o&&(i+=Separators.structureSeparator+o),null!==o?(this.getFileReferenceContainer(i).insertAdjacentHTML("afterend",t),this.memorizeAddRecord(e,o)):(this.recordsContainer.insertAdjacentHTML("beforeend",t),this.memorizeAddRecord(e,null))}async importRecord(e,t){return this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_create")),e).then((async e=>{this.isBelowMax()&&this.createRecord(e.compilerInput.uid,e.data,void 0!==t?t:null)}))}registerEnableDisableButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=t.closest("[data-object-id]").dataset.objectId,i=this.getFileReferenceContainer(o),n=selector`data${i.dataset.fieldName}[${t.dataset.hiddenField}]`,r=this.recordsContainer.querySelector('[data-formengine-input-name="'+n+'"'),a=this.recordsContainer.querySelector('[name="'+n+'"');null!==r&&null!==a&&(r.checked=!r.checked,a.value=r.checked?"1":"0",FormEngineValidation.markFieldAsChanged(r));const s="t3-form-field-container-inline-hidden";let l;i.classList.contains(s)?(l="actions-edit-hide",i.classList.remove(s)):(l="actions-edit-unhide",i.classList.add(s)),Icons.getIcon(l,Icons.sizes.small).then((e=>{t.replaceChild(document.createRange().createContextualFragment(e),t.querySelector(".t3js-icon"))}))})).delegateTo(this.container,Selectors.enableDisableRecordButtonSelector)}registerInfoButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),InfoWindow.showItem(t.dataset.infoTable,t.dataset.infoUid)})).delegateTo(this.container,Selectors.infoWindowButton)}registerDeleteButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=TYPO3.lang["label.confirm.delete_record.title"]||"Delete this record?",i=(TYPO3.lang["label.confirm.delete_record.content"]||"Are you sure you want to delete the record '%s'?").replace("%s",t.dataset.recordInfo);Modal.confirm(o,i,Severity.warning,[{text:TYPO3.lang["buttons.confirm.delete_record.no"]||"Cancel",active:!0,btnClass:"btn-default",name:"no",trigger:(e,t)=>t.hideModal()},{text:TYPO3.lang["buttons.confirm.delete_record.yes"]||"Yes, delete this record",btnClass:"btn-warning",name:"yes",trigger:(e,o)=>{this.deleteRecord(t.closest("[data-object-id]").dataset.objectId),o.hideModal()}}])})).delegateTo(this.container,Selectors.deleteRecordButtonSelector)}registerSynchronizeLocalize(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_synchronizelocalize")),[this.container.dataset.objectGroup,t.dataset.type]).then((async e=>{this.recordsContainer.insertAdjacentHTML("beforeend",e.data);const t=this.container.dataset.objectGroup+Separators.structureSeparator;for(const o of e.compilerInput.delete)this.deleteRecord(t+o,!0);for(const o of Object.values(e.compilerInput.localize)){if(void 0!==o.remove){const e=this.getFileReferenceContainer(t+o.remove);e.parentElement.removeChild(e)}this.memorizeAddRecord(o.uid,null)}}))})).delegateTo(this.container,Selectors.synchronizeLocalizeRecordButtonSelector)}loadRecordDetails(e){const t=this.recordsContainer.querySelector(selector`[id="${e}_fields"]`),o=this.getFileReferenceContainer(e),i=void 0!==this.requestQueue[e];if(null!==t&&!o.classList.contains(States.notLoaded))this.collapseExpandRecord(e);else{const n=this.getProgress(e,o.dataset.objectIdHash);if(i)this.requestQueue[e].abort(),delete this.requestQueue[e],delete this.progressQueue[e],n.done();else{const i=this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_details"));this.ajaxDispatcher.send(i,[e]).then((async i=>{delete this.requestQueue[e],delete this.progressQueue[e],o.classList.remove(States.notLoaded),t.innerHTML=i.data,this.collapseExpandRecord(e),n.done(),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)})),this.requestQueue[e]=i,n.start()}}}collapseExpandRecord(e){const t=this.getFileReferenceContainer(e),o=!0===this.getAppearance().expandSingle,i=t.classList.contains(States.collapsed);let n=[];const r=[];o&&i&&(n=this.collapseAllRecords(t.dataset.objectUid)),t.classList.contains(States.collapsed)?this.expandElement(t,e):this.collapseElement(t,e),this.isNewRecord(e)?this.updateExpandedCollapsedStateLocally(e,i):i?r.push(t.dataset.objectUid):i||n.push(t.dataset.objectUid),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_expandcollapse")),[e,r.join(","),n.join(",")])}memorizeAddRecord(e,t=null){const o=this.getFormFieldForElements();if(null===o)return;let i=Utility.trimExplode(",",o.value);if(t){const o=[];for(let n=0;n<i.length;n++)i[n].length&&o.push(i[n]),t===i[n]&&o.push(e);i=o}else i.push(e);o.value=i.join(","),o.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,i),this.isBelowMax()||this.toggleContainerControls(!1),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)}memorizeRemoveRecord(e){const t=this.getFormFieldForElements();if(null===t)return[];const o=Utility.trimExplode(",",t.value),i=o.indexOf(e);return i>-1&&(o.splice(i,1),t.value=o.join(","),t.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,o)),o}changeSortingByButton(e,t){const o=this.getFileReferenceContainer(e),i=o.dataset.objectUid,n=Array.from(this.recordsContainer.children).map((e=>e.dataset.objectUid)),r=n.indexOf(i);let a=!1;if(t===SortDirections.UP&&r>0?(n[r]=n[r-1],n[r-1]=i,a=!0):t===SortDirections.DOWN&&r<n.length-1&&(n[r]=n[r+1],n[r+1]=i,a=!0),a){const e=this.container.dataset.objectGroup+Separators.structureSeparator,i=t===SortDirections.UP?1:0;o.parentElement.insertBefore(this.getFileReferenceContainer(e+n[r-i]),this.getFileReferenceContainer(e+n[r+1-i])),this.updateSorting()}}updateSorting(){const e=this.getFormFieldForElements();if(null===e)return;const t=Array.from(this.recordsContainer.querySelectorAll(selector`[data-object-parent-group="${this.container.dataset.objectGroup}"][data-placeholder-record="0"]`)).map((e=>e.dataset.objectUid));e.value=t.join(","),e.classList.add("has-change"),document.dispatchEvent(new Event("formengine:files:sorting-changed")),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,t)}deleteRecord(e,t=!1){const o=this.getFileReferenceContainer(e),i=o.dataset.objectUid;if(o.classList.add("t3js-file-reference-deleted"),!this.isNewRecord(e)&&!t){const e=this.container.querySelector(selector`[name="cmd${o.dataset.fieldName}[delete]"]`);e.removeAttribute("disabled"),o.parentElement.insertAdjacentElement("afterbegin",e)}new RegularEvent("transitionend",(()=>{o.parentElement.removeChild(o),FormEngineValidation.validate(this.container)})).bindTo(o),this.memorizeRemoveRecord(i),o.classList.add("form-irre-object--deleted"),this.isBelowMax()&&this.toggleContainerControls(!0)}toggleContainerControls(e){const t=this.container.querySelector(Selectors.controlContainer);if(null===t)return;t.querySelectorAll("button, a").forEach((t=>{t.style.display=e?null:"none"}))}getProgress(e,t){const o="#"+t+"_header";let i;return void 0!==this.progressQueue[e]?i=this.progressQueue[e]:(i=NProgress,i.configure({parent:o,showSpinner:!1}),this.progressQueue[e]=i),i}collapseAllRecords(e){const t=this.getFormFieldForElements(),o=[];if(null!==t){const i=Utility.trimExplode(",",t.value);for(const t of i){if(t===e)continue;const i=this.container.dataset.objectGroup+Separators.structureSeparator+t,n=this.getFileReferenceContainer(i);n.classList.contains(States.visible)&&(this.collapseElement(n,i),this.isNewRecord(i)?this.updateExpandedCollapsedStateLocally(i,!1):o.push(t))}}return o}getFormFieldForElements(){const e=this.container.querySelectorAll(selector`[name="${this.container.dataset.formField}"]`);return e.length>0?e[0]:null}redrawSortingButtons(e,t=[]){if(0===t.length){const e=this.getFormFieldForElements();null!==e&&(t=Utility.trimExplode(",",e.value))}0!==t.length&&t.forEach(((o,i)=>{const n=this.getFileReferenceContainer(e+Separators.structureSeparator+o),r=this.container.querySelector('[id="'+n.dataset.objectIdHash+'_header"]'),a=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.UP+'"]');if(null!==a){let e="actions-move-up";0===i?(a.classList.add("disabled"),e="empty-empty"):a.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{a.replaceChild(document.createRange().createContextualFragment(e),a.querySelector(".t3js-icon"))}))}const s=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.DOWN+'"]');if(null!==s){let e="actions-move-down";i===t.length-1?(s.classList.add("disabled"),e="empty-empty"):s.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{s.replaceChild(document.createRange().createContextualFragment(e),s.querySelector(".t3js-icon"))}))}}))}isBelowMax(){const e=this.getFormFieldForElements();if(null===e)return!0;if(void 0!==TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup]){if(Utility.trimExplode(",",e.value).length>=TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max)return!1}return!0}getAppearance(){if(null===this.appearance&&(this.appearance={},"string"==typeof this.container.dataset.appearance))try{this.appearance=JSON.parse(this.container.dataset.appearance)}catch(e){console.error(e)}return this.appearance}}window.customElements.define("typo3-formengine-container-files",FilesControlContainer); \ No newline at end of file +import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import{AjaxDispatcher}from"@typo3/backend/form-engine/inline-relation/ajax-dispatcher.js";import NProgress from"nprogress";import Sortable from"sortablejs";import FormEngine from"@typo3/backend/form-engine.js";import FormEngineValidation from"@typo3/backend/form-engine-validation.js";import Icons from"@typo3/backend/icons.js";import InfoWindow from"@typo3/backend/info-window.js";import Modal from"@typo3/backend/modal.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Severity from"@typo3/backend/severity.js";import Utility from"@typo3/backend/utility.js";import{selector}from"@typo3/core/literals.js";var Selectors,States,Separators,SortDirections;!function(e){e.toggleSelector='[data-bs-toggle="formengine-file"]',e.controlSectionSelector=".t3js-formengine-file-header-control",e.deleteRecordButtonSelector=".t3js-editform-delete-file-reference",e.enableDisableRecordButtonSelector=".t3js-toggle-visibility-button",e.infoWindowButton='[data-action="infowindow"]',e.synchronizeLocalizeRecordButtonSelector=".t3js-synchronizelocalize-button",e.controlContainer=".t3js-file-controls"}(Selectors||(Selectors={})),function(e){e.new="isNewFileReference",e.visible="panel-visible",e.collapsed="panel-collapsed",e.notLoaded="t3js-not-loaded"}(States||(States={})),function(e){e.structureSeparator="-"}(Separators||(Separators={})),function(e){e.DOWN="down",e.UP="up"}(SortDirections||(SortDirections={}));class FilesControlContainer extends HTMLElement{constructor(){super(...arguments),this.container=null,this.recordsContainer=null,this.ajaxDispatcher=null,this.appearance=null,this.requestQueue={},this.progressQueue={},this.handlePostMessage=e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:foreignRelation:insert"===e.data.actionName){if(void 0===e.data.objectGroup)throw"No object group defined for message";if(e.data.objectGroup!==this.container.dataset.objectGroup)return;this.importRecord([e.data.objectGroup,e.data.uid]).then((()=>{if(e.source){const t={actionName:"typo3:foreignRelation:inserted",objectGroup:e.data.objectId,table:e.data.table,uid:e.data.uid};MessageUtility.send(t,e.source)}}))}if("typo3:foreignRelation:delete"===e.data.actionName){if(e.data.objectGroup!==this.container.dataset.objectGroup)return;const t=e.data.directRemoval||!1,o=[e.data.objectGroup,e.data.uid].join("-");this.deleteRecord(o,t)}}}connectedCallback(){const e=this.getAttribute("identifier")||"";this.container=this.querySelector(selector`[id="${e}"]`),null!==this.container&&(this.recordsContainer=this.container.querySelector(selector`[id="${this.container.getAttribute("id")}_records"]`),this.ajaxDispatcher=new AjaxDispatcher(this.container.dataset.objectGroup),this.registerEvents())}registerEvents(){this.registerInfoButton(),this.registerSort(),this.registerEnableDisableButton(),this.registerDeleteButton(),this.registerSynchronizeLocalize(),this.registerToggle(),new RegularEvent("message",this.handlePostMessage).bindTo(window),this.getAppearance().useSortable&&new Sortable(this.recordsContainer,{group:this.recordsContainer.getAttribute("id"),handle:".sortableHandle",onSort:()=>{this.updateSorting()}})}getFileReferenceContainer(e){return this.container.querySelector(selector`[data-object-id="${e}"]`)}getCollapseButton(e){return this.container.querySelector(selector`[aria-controls="${e}_fields"]`)}collapseElement(e,t){const o=this.getCollapseButton(t);e.classList.remove(States.visible),e.classList.add(States.collapsed),o.setAttribute("aria-expanded","false")}expandElement(e,t){const o=this.getCollapseButton(t);e.classList.remove(States.collapsed),e.classList.add(States.visible),o.setAttribute("aria-expanded","true")}isNewRecord(e){return this.getFileReferenceContainer(e).classList.contains(States.new)}updateExpandedCollapsedStateLocally(e,t){const o=this.getFileReferenceContainer(e),i=this.container.querySelectorAll('[name="uc[inlineView]['+o.dataset.topmostParentTable+"]["+o.dataset.topmostParentUid+"]"+o.dataset.fieldName+'"]');i.length&&(i[0].value=t?"1":"0")}registerToggle(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.loadRecordDetails(t.closest(Selectors.toggleSelector).parentElement.dataset.objectId)})).delegateTo(this.container,`${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`)}registerSort(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.changeSortingByButton(t.closest("[data-object-id]").dataset.objectId,t.dataset.direction)})).delegateTo(this.container,Selectors.controlSectionSelector+' [data-action="sort"]')}createRecord(e,t,o=null){let i=this.container.dataset.objectGroup;null!==o&&(i+=Separators.structureSeparator+o),null!==o?(this.getFileReferenceContainer(i).insertAdjacentHTML("afterend",t),this.memorizeAddRecord(e,o)):(this.recordsContainer.insertAdjacentHTML("beforeend",t),this.memorizeAddRecord(e,null))}async importRecord(e,t){return this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_create")),e).then((async e=>{this.isBelowMax()&&this.createRecord(e.compilerInput.uid,e.data,void 0!==t?t:null)}))}registerEnableDisableButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=t.closest("[data-object-id]").dataset.objectId,i=this.getFileReferenceContainer(o),n=selector`data${i.dataset.fieldName}[${t.dataset.hiddenField}]`,r=this.recordsContainer.querySelector('[data-formengine-input-name="'+n+'"'),a=this.recordsContainer.querySelector('[name="'+n+'"');null!==r&&null!==a&&(r.checked=!r.checked,a.value=r.checked?"1":"0",FormEngineValidation.markFieldAsChanged(r));const s="t3-form-field-container-inline-hidden";let l;i.classList.contains(s)?(l="actions-edit-hide",i.classList.remove(s)):(l="actions-edit-unhide",i.classList.add(s)),Icons.getIcon(l,Icons.sizes.small).then((e=>{t.replaceChild(document.createRange().createContextualFragment(e),t.querySelector(".t3js-icon"))}))})).delegateTo(this.container,Selectors.enableDisableRecordButtonSelector)}registerInfoButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),InfoWindow.showItem(t.dataset.infoTable,t.dataset.infoUid)})).delegateTo(this.container,Selectors.infoWindowButton)}registerDeleteButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=TYPO3.lang["label.confirm.delete_record.title"]||"Delete this record?",i=(TYPO3.lang["label.confirm.delete_record.content"]||"Are you sure you want to delete the record '%s'?").replace("%s",t.dataset.recordInfo);Modal.confirm(o,i,Severity.warning,[{text:TYPO3.lang["buttons.confirm.delete_record.no"]||"Cancel",active:!0,btnClass:"btn-default",name:"no",trigger:(e,t)=>t.hideModal()},{text:TYPO3.lang["buttons.confirm.delete_record.yes"]||"Yes, delete this record",btnClass:"btn-warning",name:"yes",trigger:(e,o)=>{this.deleteRecord(t.closest("[data-object-id]").dataset.objectId),o.hideModal()}}])})).delegateTo(this.container,Selectors.deleteRecordButtonSelector)}registerSynchronizeLocalize(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_synchronizelocalize")),[this.container.dataset.objectGroup,t.dataset.type]).then((async e=>{this.recordsContainer.insertAdjacentHTML("beforeend",e.data);const t=this.container.dataset.objectGroup+Separators.structureSeparator;for(const o of e.compilerInput.delete)this.deleteRecord(t+o,!0);for(const o of Object.values(e.compilerInput.localize)){if(void 0!==o.remove){const e=this.getFileReferenceContainer(t+o.remove);e.parentElement.removeChild(e)}this.memorizeAddRecord(o.uid,null)}}))})).delegateTo(this.container,Selectors.synchronizeLocalizeRecordButtonSelector)}loadRecordDetails(e){const t=this.recordsContainer.querySelector(selector`[id="${e}_fields"]`),o=this.getFileReferenceContainer(e),i=void 0!==this.requestQueue[e];if(null!==t&&!o.classList.contains(States.notLoaded))this.collapseExpandRecord(e);else{const n=this.getProgress(e,o.dataset.objectIdHash);if(i)this.requestQueue[e].abort(),delete this.requestQueue[e],delete this.progressQueue[e],n.done();else{const i=this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_details"));this.ajaxDispatcher.send(i,[e]).then((async i=>{delete this.requestQueue[e],delete this.progressQueue[e],o.classList.remove(States.notLoaded),t.innerHTML=i.data,this.collapseExpandRecord(e),n.done(),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)})),this.requestQueue[e]=i,n.start()}}}collapseExpandRecord(e){const t=this.getFileReferenceContainer(e),o=!0===this.getAppearance().expandSingle,i=t.classList.contains(States.collapsed);let n=[];const r=[];o&&i&&(n=this.collapseAllRecords(t.dataset.objectUid)),t.classList.contains(States.collapsed)?this.expandElement(t,e):this.collapseElement(t,e),this.isNewRecord(e)?this.updateExpandedCollapsedStateLocally(e,i):i?r.push(t.dataset.objectUid):i||n.push(t.dataset.objectUid),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_expandcollapse")),[e,r.join(","),n.join(",")])}memorizeAddRecord(e,t=null){const o=this.getFormFieldForElements();if(null===o)return;let i=Utility.trimExplode(",",o.value);if(t){const o=[];for(let n=0;n<i.length;n++)i[n].length&&o.push(i[n]),t===i[n]&&o.push(e);i=o}else i.push(e);o.value=i.join(","),o.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,i),this.isBelowMax()||this.toggleContainerControls(!1),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)}memorizeRemoveRecord(e){const t=this.getFormFieldForElements();if(null===t)return[];const o=Utility.trimExplode(",",t.value),i=o.indexOf(e);return i>-1&&(o.splice(i,1),t.value=o.join(","),t.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,o)),o}changeSortingByButton(e,t){const o=this.getFileReferenceContainer(e),i=o.dataset.objectUid,n=Array.from(this.recordsContainer.children).map((e=>e.dataset.objectUid)),r=n.indexOf(i);let a=!1;if(t===SortDirections.UP&&r>0?(n[r]=n[r-1],n[r-1]=i,a=!0):t===SortDirections.DOWN&&r<n.length-1&&(n[r]=n[r+1],n[r+1]=i,a=!0),a){const e=this.container.dataset.objectGroup+Separators.structureSeparator,i=t===SortDirections.UP?1:0;o.parentElement.insertBefore(this.getFileReferenceContainer(e+n[r-i]),this.getFileReferenceContainer(e+n[r+1-i])),this.updateSorting()}}updateSorting(){const e=this.getFormFieldForElements();if(null===e)return;const t=Array.from(this.recordsContainer.querySelectorAll(selector`[data-object-parent-group="${this.container.dataset.objectGroup}"][data-placeholder-record="0"]`)).map((e=>e.dataset.objectUid));e.value=t.join(","),e.classList.add("has-change"),document.dispatchEvent(new Event("formengine:files:sorting-changed")),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,t)}deleteRecord(e,t=!1){const o=this.getFileReferenceContainer(e),i=o.dataset.objectUid;if(o.classList.add("t3js-file-reference-deleted"),!this.isNewRecord(e)&&!t){const e=this.container.querySelector(selector`[name="cmd${o.dataset.fieldName}[delete]"]`);e.removeAttribute("disabled"),o.parentElement.insertAdjacentElement("afterbegin",e)}new RegularEvent("transitionend",(()=>{o.remove(),FormEngineValidation.validate(this.container)})).bindTo(o),this.memorizeRemoveRecord(i),o.classList.add("form-irre-object--deleted"),this.isBelowMax()&&this.toggleContainerControls(!0)}toggleContainerControls(e){const t=this.container.querySelector(Selectors.controlContainer);if(null===t)return;t.querySelectorAll("button, a").forEach((t=>{t.style.display=e?null:"none"}))}getProgress(e,t){const o="#"+t+"_header";let i;return void 0!==this.progressQueue[e]?i=this.progressQueue[e]:(i=NProgress,i.configure({parent:o,showSpinner:!1}),this.progressQueue[e]=i),i}collapseAllRecords(e){const t=this.getFormFieldForElements(),o=[];if(null!==t){const i=Utility.trimExplode(",",t.value);for(const t of i){if(t===e)continue;const i=this.container.dataset.objectGroup+Separators.structureSeparator+t,n=this.getFileReferenceContainer(i);n.classList.contains(States.visible)&&(this.collapseElement(n,i),this.isNewRecord(i)?this.updateExpandedCollapsedStateLocally(i,!1):o.push(t))}}return o}getFormFieldForElements(){const e=this.container.querySelectorAll(selector`[name="${this.container.dataset.formField}"]`);return e.length>0?e[0]:null}redrawSortingButtons(e,t=[]){if(0===t.length){const e=this.getFormFieldForElements();null!==e&&(t=Utility.trimExplode(",",e.value))}0!==t.length&&t.forEach(((o,i)=>{const n=this.getFileReferenceContainer(e+Separators.structureSeparator+o),r=this.container.querySelector('[id="'+n.dataset.objectIdHash+'_header"]'),a=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.UP+'"]');if(null!==a){let e="actions-move-up";0===i?(a.classList.add("disabled"),e="empty-empty"):a.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{a.replaceChild(document.createRange().createContextualFragment(e),a.querySelector(".t3js-icon"))}))}const s=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.DOWN+'"]');if(null!==s){let e="actions-move-down";i===t.length-1?(s.classList.add("disabled"),e="empty-empty"):s.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{s.replaceChild(document.createRange().createContextualFragment(e),s.querySelector(".t3js-icon"))}))}}))}isBelowMax(){const e=this.getFormFieldForElements();if(null===e)return!0;if(void 0!==TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup]){if(Utility.trimExplode(",",e.value).length>=TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max)return!1}return!0}getAppearance(){if(null===this.appearance&&(this.appearance={},"string"==typeof this.container.dataset.appearance))try{this.appearance=JSON.parse(this.container.dataset.appearance)}catch(e){console.error(e)}return this.appearance}}window.customElements.define("typo3-formengine-container-files",FilesControlContainer); \ No newline at end of file diff --git a/typo3/sysext/beuser/Resources/Private/Partials/Compare/Information.html b/typo3/sysext/beuser/Resources/Private/Partials/Compare/Information.html index c182adcdc832..262578f31a01 100644 --- a/typo3/sysext/beuser/Resources/Private/Partials/Compare/Information.html +++ b/typo3/sysext/beuser/Resources/Private/Partials/Compare/Information.html @@ -292,91 +292,83 @@ </f:if> </f:for> <f:if condition="{tableReadConfigured}"> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-read-table-{id}-collapse" - data-bs-target="#permission-group-read-table-{id}-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:tableModes.read" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline" /> - </span> - </span> - </div> - </button> - <div id="permission-group-read-table-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="table-fit"> - <table class="table"> - <f:for each="{tables.all}" key="table" as="label"> - <f:if condition="{tables.tables_select.{table}} && !{tables.tables_modify.{table}}"> - <tr> - <td class="col-icon"> - <core:iconForRecord table="{table}" row="{id: '0'}" /> - </td> - <td class="col-title"> - <f:if condition="{label}">{f:translate(key:label, default:label)}</f:if><f:if condition="{showUid}"> <code>[{table}]</code></f:if> - </td> - </tr> - </f:if> - </f:for> - </table> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-read-table-{id}-collapse" + aria-controls="permission-group-read-table-{id}-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:tableModes.read" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-read-table-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="table-fit"> + <table class="table"> + <f:for each="{tables.all}" key="table" as="label"> + <f:if condition="{tables.tables_select.{table}} && !{tables.tables_modify.{table}}"> + <tr> + <td class="col-icon"> + <core:iconForRecord table="{table}" row="{id: '0'}" /> + </td> + <td class="col-title"> + <f:if condition="{label}">{f:translate(key:label, default:label)}</f:if><f:if condition="{showUid}"> <code>[{table}]</code></f:if> + </td> + </tr> + </f:if> + </f:for> + </table> + </div> + </div> + </div> </f:if> <f:if condition="{tableReadWriteConfigured}"> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-read-write-table-{id}-collapse" - data-bs-target="#permission-group-read-write-table-{id}-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:tableModes.write" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline" /> - </span> - </span> - </div> - </button> - <div id="permission-group-read-write-table-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="table-fit"> - <table class="table"> - <f:for each="{tables.all}" key="table" as="label"> - <f:if condition="{tables.tables_modify.{table}}"> - <tr> - <td class="col-icon"> - <core:iconForRecord table="{table}" row="{id: '0'}" /> - </td> - <td class="col-title"> - <f:if condition="{label}">{f:translate(key:label, default:label)}</f:if><f:if condition="{showUid}"> <code>[{table}]</code></f:if> - </td> - </tr> - </f:if> - </f:for> - </table> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-read-write-table-{id}-collapse" + aria-controls="permission-group-read-write-table-{id}-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:tableModes.write" /> + </div> + <span class="caret"></span> + </button> + </div> + </div> + <div id="permission-group-read-write-table-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="table-fit"> + <table class="table"> + <f:for each="{tables.all}" key="table" as="label"> + <f:if condition="{tables.tables_modify.{table}}"> + <tr> + <td class="col-icon"> + <core:iconForRecord table="{table}" row="{id: '0'}" /> + </td> + <td class="col-title"> + <f:if condition="{label}">{f:translate(key:label, default:label)}</f:if><f:if condition="{showUid}"> <code>[{table}]</code></f:if> + </td> + </tr> + </f:if> + </f:for> + </table> </div> </div> - </typo3-backend-collapsible> + </div> </f:if> </f:if> </f:section> @@ -384,72 +376,66 @@ <f:section name="nonExcludeFields"> <f:if condition="{nonExcludeFields}"> <f:for each="{nonExcludeFields}" key="tableName" as="table"> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-{tableName}-{id}-collapse" - data-bs-target="#permission-group-{tableName}-{id}-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <core:iconForRecord table="{tableName}" row="{id: '0'}" /> - <f:if condition="{table.label}">{f:translate(key:table.label,default:table.label)}</f:if><f:if condition="{showUid}"> <code>[{tableName}]</code></f:if> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline" /> - </span> - </span> - </div> - </button> - <div id="permission-group-{tableName}-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="panel-body"> - <ul class="panel-list"> - <f:for each="{table.fields}" as="label" key="field"> - <li><f:if condition="{label}">{f:translate(key:label,default:label)} </f:if><code>[{field}]</code></li> - </f:for> - </ul> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-{tableName}-{id}-collapse" + aria-controls="permission-group-{tableName}-{id}-collapse" + aria-expanded="false" + > + <div class="panel-icon"> + <core:iconForRecord table="{tableName}" row="{id: '0'}" /> + </div> + <div class="panel-title"> + <f:if condition="{table.label}">{f:translate(key:table.label,default:table.label)}</f:if><f:if condition="{showUid}"> <code>[{tableName}]</code></f:if> + </div> + <span class="caret"></span> + </button> + </div> + </div> + <div id="permission-group-{tableName}-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="panel-body"> + <ul class="panel-list"> + <f:for each="{table.fields}" as="label" key="field"> + <li><f:if condition="{label}">{f:translate(key:label,default:label)} </f:if><code>[{field}]</code></li> + </f:for> + </ul> </div> </div> - </typo3-backend-collapsible> + </div> </f:for> </f:if> </f:section> <f:section name="tsconfig"> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-tsconfig-{id}-collapse" - data-bs-target="#permission-group-tsconfig-{id}-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:TSconfig" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline" /> - </span> - </span> - </div> - </button> - <div id="permission-group-tsconfig-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="panel-body"> - <f:render section="userTsConfigTree" arguments="{treeArray: tsconfig}" /> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-tsconfig-{id}-collapse" + aria-controls="permission-group-tsconfig-{id}-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:TSconfig" /> + </div> + <span class="caret"></span> + </button> + </div> + </div> + <div id="permission-group-tsconfig-{id}-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="panel-body"> + <f:render section="userTsConfigTree" arguments="{treeArray: tsconfig}" /> </div> </div> - </typo3-backend-collapsible> + </div> </f:section> <f:section name="userTsConfigTree"> diff --git a/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Compare.html b/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Compare.html index 953ed0d02ff2..d58cfe9b983e 100644 --- a/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Compare.html +++ b/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Compare.html @@ -10,9 +10,8 @@ <f:section name="Before"> <f:be.pageRenderer includeJavaScriptModules="{ - 0: '@typo3/backend/element/collapsible-element.js', - 1: '@typo3/backend/element/immediate-action-element.js', - 2: '@typo3/backend/utility/collapse-state-persister.js', + 0: '@typo3/backend/element/immediate-action-element.js', + 1: '@typo3/backend/utility/collapse-state-persister.js', }" /> <f:variable name="args" value="{0: 'system', 1: '0'}" /> diff --git a/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Show.html b/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Show.html index 49b9a4fd6912..aeffa3f1a959 100644 --- a/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Show.html +++ b/typo3/sysext/beuser/Resources/Private/Templates/BackendUser/Show.html @@ -10,9 +10,8 @@ <f:section name="Before"> <f:be.pageRenderer includeJavaScriptModules="{ - 0: '@typo3/backend/element/collapsible-element.js', - 1: '@typo3/backend/element/immediate-action-element.js', - 2: '@typo3/backend/utility/collapse-state-persister.js', + 0: '@typo3/backend/element/immediate-action-element.js', + 1: '@typo3/backend/utility/collapse-state-persister.js', }" /> <f:variable name="args" value="{0: 'system', 1: data.user.uid}" /> @@ -133,39 +132,35 @@ <div class="col-md-10 col-lg-8"> <f:if condition="{data.groups.all}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-groups-collapse" - data-bs-target="#permission-group-groups-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.subgroup" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-groups-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render - partial="Compare/Information" - section="groups" - arguments="{ - groups: data.groups, - hasColumnClasses: 1 - }" - /> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-groups-collapse" + aria-controls="permission-group-groups-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.subgroup" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-groups-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render + partial="Compare/Information" + section="groups" + arguments="{ + groups: data.groups, + hasColumnClasses: 1 + }" + /> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -186,32 +181,28 @@ <div class="col-md-10 col-lg-8"> <f:if condition="{data.languages}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-languages-collapse" - data-bs-target="#permission-group-languages-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:allowedLanguages" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-languages-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="languages" arguments="{languages: data.languages}"/> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-languages-collapse" + aria-controls="permission-group-languages-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:allowedLanguages" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-languages-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="languages" arguments="{languages: data.languages}"/> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -233,32 +224,28 @@ <h3><f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:generalPermissions" /></h3> <f:if condition="{data.modules}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-modules-collapse" - data-bs-target="#permission-group-modules-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:userMods" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-modules-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="modules" arguments="{modules: data.modules}"/> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-modules-collapse" + aria-controls="permission-group-modules-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:userMods" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-modules-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="modules" arguments="{modules: data.modules}"/> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -274,32 +261,28 @@ <f:if condition="{data.pageTypes}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-pageType-collapse" - data-bs-target="#permission-group-pageType-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.pagetypes_select" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-pageType-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="pageTypes" arguments="{pageTypes: data.pageTypes}" /> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-pageType-collapse" + aria-controls="permission-group-pageType-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.pagetypes_select" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-pageType-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="pageTypes" arguments="{pageTypes: data.pageTypes}" /> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -315,34 +298,30 @@ <f:if condition="{data.pageContentTypes}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-pageContentTypes-collapse" - data-bs-target="#permission-group-pageContentTypes-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:allowedPageContentTypes" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-pageContentTypes-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <div class="panel-body"> - <f:render partial="Compare/Information" section="pageContentTypes" arguments="{pageContentTypes: data.pageContentTypes}" /> - </div> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-pageContentTypes-collapse" + aria-controls="permission-group-pageContentTypes-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:allowedPageContentTypes" /> + </div> + <span class="caret"></span> + </button> + </div> + </div> + <div id="permission-group-pageContentTypes-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <div class="panel-body"> + <f:render partial="Compare/Information" section="pageContentTypes" arguments="{pageContentTypes: data.pageContentTypes}" /> </div> </div> - </typo3-backend-collapsible> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -404,32 +383,28 @@ <div class="col-md-10 col-lg-8"> <f:if condition="{data.workspaces} && {data.workspaces.record.uid}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-workspaces-collapse" - data-bs-target="#permission-group-workspaces-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:workspace_perms" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-workspaces-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="workspaces" arguments="{workspaces: data.workspaces}" /> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-workspaces-collapse" + aria-controls="permission-group-workspaces-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:workspace_perms" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-workspaces-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="workspaces" arguments="{workspaces: data.workspaces}" /> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -445,32 +420,28 @@ <f:if condition="{data.dbMounts}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-dbMounts-collapse" - data-bs-target="#permission-group-dbMounts-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:dbMountPoints" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-dbMounts-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="dbMounts" arguments="{dbMounts: data.dbMounts}" /> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-dbMounts-collapse" + aria-controls="permission-group-dbMounts-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:dbMountPoints" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-dbMounts-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="dbMounts" arguments="{dbMounts: data.dbMounts}" /> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -486,32 +457,28 @@ <f:if condition="{data.fileMounts}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-fileMounts-collapse" - data-bs-target="#permission-group-fileMounts-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:fileMounts" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-fileMounts-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="fileMounts" arguments="{fileMounts: data.fileMounts}"/> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-fileMounts-collapse" + aria-controls="permission-group-fileMounts-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:beuser/Resources/Private/Language/locallang.xlf:fileMounts" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-fileMounts-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="fileMounts" arguments="{fileMounts: data.fileMounts}"/> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -527,32 +494,28 @@ <f:if condition="{data.fileFolderPermissions}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-fileFolderPermissions-collapse" - data-bs-target="#permission-group-fileFolderPermissions-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.fileoper_perms" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-fileFolderPermissions-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="fileFolderPermissions" arguments="{fileFolderPermissions: data.fileFolderPermissions}" /> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-fileFolderPermissions-collapse" + aria-controls="permission-group-fileFolderPermissions-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_groups.fileoper_perms" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-fileFolderPermissions-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="fileFolderPermissions" arguments="{fileFolderPermissions: data.fileFolderPermissions}" /> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> @@ -568,32 +531,28 @@ <f:if condition="{data.categories}"> <f:then> - <typo3-backend-collapsible> - <div class="panel panel-default"> - <button - type="button" - class="panel-heading panel-heading-button" - aria-expanded="false" - aria-controls="permission-group-categories-collapse" - data-bs-target="#permission-group-categories-collapse" - data-bs-toggle="collapse" - > - <span class="flex-grow-1 align-self-center"> - <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:category_perms" /> - </span> - <div class="panel-actions ml-auto"> - <span class="btn btn-sm btn-default"> - <span class="collapseIcon"> - <core:icon identifier="actions-view-list-expand" alternativeMarkupIdentifier="inline"/> - </span> - </span> - </div> - </button> - <div id="permission-group-categories-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> - <f:render partial="Compare/Information" section="categories" arguments="{categories: data.categories}"/> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#permission-group-categories-collapse" + aria-controls="permission-group-categories-collapse" + aria-expanded="false" + > + <div class="panel-title"> + <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:category_perms" /> + </div> + <span class="caret"></span> + </button> </div> </div> - </typo3-backend-collapsible> + <div id="permission-group-categories-collapse" class="panel-collapse collapse" data-persist-collapse-state="true" role="tabpanel"> + <f:render partial="Compare/Information" section="categories" arguments="{categories: data.categories}"/> + </div> + </div> </f:then> <f:else> <div class="panel panel-default"> diff --git a/typo3/sysext/beuser/Resources/Private/Templates/BackendUserGroup/Compare.html b/typo3/sysext/beuser/Resources/Private/Templates/BackendUserGroup/Compare.html index 83d61f509ebc..7183399abd08 100644 --- a/typo3/sysext/beuser/Resources/Private/Templates/BackendUserGroup/Compare.html +++ b/typo3/sysext/beuser/Resources/Private/Templates/BackendUserGroup/Compare.html @@ -10,9 +10,8 @@ <f:section name="Before"> <f:be.pageRenderer includeJavaScriptModules="{ - 0: '@typo3/backend/element/collapsible-element.js', - 1: '@typo3/backend/element/immediate-action-element.js', - 2: '@typo3/backend/utility/collapse-state-persister.js', + 0: '@typo3/backend/element/immediate-action-element.js', + 1: '@typo3/backend/utility/collapse-state-persister.js', }" /> <f:variable name="args" value="{0: 'system', 1: '0'}" /> diff --git a/typo3/sysext/core/Tests/Acceptance/Application/InstallTool/UpgradeCest.php b/typo3/sysext/core/Tests/Acceptance/Application/InstallTool/UpgradeCest.php index 816a05b9a223..b96e419711de 100644 --- a/typo3/sysext/core/Tests/Acceptance/Application/InstallTool/UpgradeCest.php +++ b/typo3/sysext/core/Tests/Acceptance/Application/InstallTool/UpgradeCest.php @@ -54,12 +54,12 @@ final class UpgradeCest extends AbstractCest $I->amGoingTo('mark an item as read'); // pick 2nd named version (e.g. `12.4`), current dev versions might be empty (e.g. `13.0` and `12.4.x`) - $I->click('#heading-2 > h2:nth-child(1) > a:nth-child(1) > strong:nth-child(2)'); + $I->click('#heading-2'); $I->waitForElement('#version-2', 5, ModalDialog::$openedModalSelector); $textCurrentFirstPanelHeading = $I->grabTextFrom($versionPanel . ' .panel-heading'); - $I->click($versionPanel . ' a[data-bs-toggle="collapse"]'); + $I->click($versionPanel . ' button[data-bs-toggle="collapse"]'); $I->click($versionPanel . ' .t3js-upgradeDocs-markRead'); $I->dontSee($textCurrentFirstPanelHeading, '#version-2'); diff --git a/typo3/sysext/form/Resources/Public/Css/form.css b/typo3/sysext/form/Resources/Public/Css/form.css index 400c9344a3c7..17af97698961 100644 --- a/typo3/sysext/form/Resources/Public/Css/form.css +++ b/typo3/sysext/form/Resources/Public/Css/form.css @@ -134,7 +134,6 @@ #t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .btn-toolbar-container:after,#t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .btn-toolbar-container:before{position:absolute;top:0;display:block;width:1px;height:100%;content:" ";background-color:#05c} #t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .btn-toolbar-container:before{inset-inline-start:-1px} #t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .btn-toolbar-container:after{inset-inline-end:-1px} -#t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .btn-toolbar-container .caret{color:#05c} #t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .btn-toolbar-container .t3-form-dropdown-buttons .icon{margin-inline-end:.5em} #t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .btn-toolbar-container .btn-toolbar{float:var(--typo3-position-end)} #t3-form-stage-container.t3-form-stage-viewmode-abstract #t3-form-stage .t3-form-form-element-selected .meta-label{display:inline-block;top:1em;inset-inline-start:5em;bottom:auto;font-size:.9em;color:#fff} diff --git a/typo3/sysext/install/Resources/Private/Partials/Settings/ExtensionConfiguration/ExtensionForm.html b/typo3/sysext/install/Resources/Private/Partials/Settings/ExtensionConfiguration/ExtensionForm.html index 404cb49c6144..b3ec8c79c9ad 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Settings/ExtensionConfiguration/ExtensionForm.html +++ b/typo3/sysext/install/Resources/Private/Partials/Settings/ExtensionConfiguration/ExtensionForm.html @@ -5,13 +5,23 @@ > <div class="panel panel-default searchhit"> - <div class="panel-heading" role="tab" id="heading-{extensionKey}"> - <h3 class="panel-title"> - <a role="button" data-bs-toggle="collapse" href="#collapse-{extensionKey}" aria-expanded="false" aria-controls="collapse-{extensionKey}" class="collapsed"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#collapse-{extensionKey}" + aria-controls="collapse-{extensionKey}" + aria-expanded="false" + id="heading-{extensionKey}" + > + <div class="panel-title"> + <strong>{extensionKey}</strong> + </div> <span class="caret"></span> - <strong>{extensionKey}</strong> - </a> - </h3> + </button> + </div> </div> <div id="collapse-{extensionKey}" class="panel-collapse collapse search-item" role="tabpanel" aria-labelledby="heading-{extensionKey}"> <div class="panel-body"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Settings/LocalConfiguration/SubSection.html b/typo3/sysext/install/Resources/Private/Partials/Settings/LocalConfiguration/SubSection.html index 07266cc5e38e..4e31922b27b4 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Settings/LocalConfiguration/SubSection.html +++ b/typo3/sysext/install/Resources/Private/Partials/Settings/LocalConfiguration/SubSection.html @@ -1,13 +1,24 @@ <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:i="http://typo3.org/ns/TYPO3/CMS/Install/ViewHelpers" data-namespace-typo3-fluid="true"> <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="heading-{sectionName}"> - <h3 class="panel-title"> - <a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapse-{sectionName}" aria-expanded="true" aria-controls="collapse-{sectionName}" class="collapsed"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-parent="#accordion" + data-bs-target="#collapse-{sectionName}" + aria-controls="collapse-{sectionName}" + aria-expanded="false" + id="heading-{sectionName}" + > + <div class="panel-title"> + <strong>{sectionData.description}</strong> [{sectionName}] + </div> <span class="caret"></span> - <strong>{sectionData.description}</strong> [{sectionName}] - </a> - </h3> + </button> + </div> </div> <div id="collapse-{sectionName}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-{sectionName}"> <div class="panel-body"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Cache.html b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Cache.html index fa5679391e13..258cf1e20cda 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Cache.html +++ b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Cache.html @@ -1,13 +1,24 @@ <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true"> <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingSeven"> - <h4 class="panel-title"> - <a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapseSeven" aria-expanded="true" aria-controls="collapseSeven" class="collapsed"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-parent="#accordion" + data-bs-target="#collapseSeven" + aria-controls="collapseSeven" + aria-expanded="false" + id="headingSeven" + > + <div class="panel-title"> + <strong>Cache settings</strong> + </div> <span class="caret"></span> - <strong>Cache settings</strong> - </a> - </h4> + </button> + </div> </div> <div id="collapseSeven" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingSeven"> <div class="panel-body"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Context.html b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Context.html index 63030aa5add5..1c83f2ed9030 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Context.html +++ b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Context.html @@ -1,13 +1,24 @@ <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true"> <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingTwo"> - <h4 class="panel-title"> - <a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapseTwo" aria-expanded="true" aria-controls="collapseTwo" class="collapsed"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-parent="#accordion" + data-bs-target="#collapseTwo" + aria-controls="collapseTwo" + aria-expanded="false" + id="headingTwo" + > + <div class="panel-title"> + <strong>Debug settings</strong> + </div> <span class="caret"></span> - <strong>Debug settings</strong> - </a> - </h4> + </button> + </div> </div> <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo"> <div class="panel-body"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Image.html b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Image.html index f9335914487b..f2f86ae3e7c1 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Image.html +++ b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Image.html @@ -1,13 +1,24 @@ <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true"> <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingFour"> - <h4 class="panel-title"> - <a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapseFour" aria-expanded="true" aria-controls="collapseFour" class="collapsed"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-parent="#accordion" + data-bs-target="#collapseFour" + aria-controls="collapseFour" + aria-expanded="false" + id="headingFour" + > + <div class="panel-title"> + <strong>Image handling settings</strong> + </div> <span class="caret"></span> - <strong>Image handling settings</strong> - </a> - </h4> + </button> + </div> </div> <div id="collapseFour" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingFour"> <div class="panel-body"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Mail.html b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Mail.html index cd0b12de7ac2..a6f382328ec5 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Mail.html +++ b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/Mail.html @@ -1,13 +1,24 @@ <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true"> <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingFive"> - <h4 class="panel-title"> - <a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapseFive" aria-expanded="true" aria-controls="collapseFive" class="collapsed"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-parent="#accordion" + data-bs-target="#collapseFive" + aria-controls="collapseFive" + aria-expanded="false" + id="headingFive" + > + <div class="panel-title"> + <strong>Mail handling settings</strong> + </div> <span class="caret"></span> - <strong>Mail handling settings</strong> - </a> - </h4> + </button> + </div> </div> <div id="collapseFive" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingFive"> <div class="panel-body"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/PasswordHashing.html b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/PasswordHashing.html index 0001731242ba..f5efcd99c59e 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/PasswordHashing.html +++ b/typo3/sysext/install/Resources/Private/Partials/Settings/Presets/PasswordHashing.html @@ -1,13 +1,24 @@ <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true"> <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="headingSix"> - <h4 class="panel-title"> - <a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapseSix" aria-expanded="true" aria-controls="collapseSix" class="collapsed"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-parent="#accordion" + data-bs-target="#collapseSix" + aria-controls="collapseSix" + aria-expanded="false" + id="headingSix" + > + <div class="panel-title"> + <strong>Password hashing settings</strong> + </div> <span class="caret"></span> - <strong>Password hashing settings</strong> - </a> - </h4> + </button> + </div> </div> <div id="collapseSix" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingSix"> <div class="panel-body"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Upgrade/UpgradeDocs/PanelItem.html b/typo3/sysext/install/Resources/Private/Partials/Upgrade/UpgradeDocs/PanelItem.html index a101763ded72..1c8e58c5b762 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Upgrade/UpgradeDocs/PanelItem.html +++ b/typo3/sysext/install/Resources/Private/Partials/Upgrade/UpgradeDocs/PanelItem.html @@ -4,28 +4,35 @@ data-namespace-typo3-fluid="true"> <div class="t3js-upgrade-doc panel panel-rst panel-{fileArray.class} risk-medium" data-item-tags="{fileArray.tagList}" data-item-version="{fileArray.version}" data-item-state="{state}" id="heading{id}"> - <div class="panel-heading" role="tab"> - <h3 class="panel-title"> + <h3 class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button order-2 collapsed" + type="button" + data-bs-target="#collapse{id}" + data-bs-toggle="collapse" + aria-expanded="false" + aria-controls="collapse{id}" + > + <div class="panel-title"><strong>{fileArray.headline}</strong></div> + <span class="caret"></span> + </button> <f:if condition="{read}"> <f:then> - <button type="button" class="btn btn-link link-action t3js-upgradeDocs-unmarkRead float-end" data-filepath="{fileArray.filepath}" title="Mark as not read"> + <button type="button" class="btn btn-link t3js-upgradeDocs-unmarkRead" data-filepath="{fileArray.filepath}" title="Mark as not read"> <core:icon identifier="actions-ban" size="small" /> <span class="visually-hidden">restore this document</span> </button> </f:then> <f:else> - <button type="button" class="btn btn-link link-action t3js-upgradeDocs-markRead float-end" data-filepath="{fileArray.filepath}" title="Mark as read"> + <button type="button" class="btn btn-link t3js-upgradeDocs-markRead" data-filepath="{fileArray.filepath}" title="Mark as read"> <core:icon identifier="actions-check" size="small" /> <span class="visually-hidden">ignore this document</span> </button> </f:else> </f:if> - <a role="button" data-bs-toggle="collapse" href="#collapse{id}" aria-expanded="true" aria-controls="collapse{id}" class="collapsed"> - <span class="caret"></span> - <strong>{fileArray.headline}</strong> - </a> - </h3> - </div> + </div> + </h3> <div id="collapse{id}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{id}"> <div class="rst-tags"> <f:for each="{fileArray.tags}" as="tag"> diff --git a/typo3/sysext/install/Resources/Private/Templates/Upgrade/ExtensionScanner.html b/typo3/sysext/install/Resources/Private/Templates/Upgrade/ExtensionScanner.html index c5dd613bc81d..15591e6679b1 100644 --- a/typo3/sysext/install/Resources/Private/Templates/Upgrade/ExtensionScanner.html +++ b/typo3/sysext/install/Resources/Private/Templates/Upgrade/ExtensionScanner.html @@ -14,15 +14,26 @@ <div style="display: none"> <div id="t3js-extensionScanner-file-hit-template"> <div class="panel t3js-extensionScanner-hit-panel risk-medium"> - <div class="panel-heading"> - <h3 class="panel-title"> - <a href="#collapse" class="collapsed t3js-extensionScanner-hit-file-panel-head" data-bs-toggle="collapse"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed t3js-extensionScanner-hit-file-panel-head" + type="button" + data-bs-toggle="collapse" + data-bs-target="#collapse" + aria-controls="collapse" + aria-expanded="false" + id="heading-not-affected" + > + <div class="panel-title"> + <div><strong class="t3js-extensionScanner-hit-filename">aFile</strong></div> + <div class="t3js-extensionScanner-hit-message">aMessage</div> + </div> + <div class="panel-badge t3js-extensionScanner-hit-badges"> + </div> <span class="caret"></span> - <span class="float-end badges"></span> - <span class="t3js-extensionScanner-hit-filename file">aFile</span> - <span class="t3js-extensionScanner-hit-message message">aMessage</span> - </a> - </h3> + </button> + </div> </div> <div id="collapse" class="panel-collapse collapse t3js-extensionScanner-hit-file-panel-body"> <div class="panel-body"> @@ -34,17 +45,25 @@ </div> <div id="t3js-extensionScanner-file-hit-rest-template"> <div class="panel t3js-extensionScanner-hit-rest-panel risk-medium"> - <div class="panel-heading"> - <h3 class="panel-title"> - <a href="#collapse-rest" - class="collapsed t3js-extensionScanner-hit-rest-panel-head" + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed t3js-extensionScanner-hit-rest-panel-head" + type="button" data-bs-toggle="collapse" + data-bs-target="#collapse-rest" + aria-controls="collapse-rest" + aria-expanded="false" > - <span class="badge float-end">aBadge</span> + <div class="panel-title"> + <strong class="t3js-extensionScanner-hit-rest-headline">restFileHeadline</strong> + </div> + <div class="panel-badge"> + <span class="badge badge-default t3js-extensionScanner-hit-rest-badge">aBadge</span> + </div> <span class="caret"></span> - <strong class="t3js-extensionScanner-hit-rest-headline">restFileHeadline</strong> - </a> - </h3> + </button> + </div> </div> <div id="collapse-rest" class="panel-collapse collapse t3js-extensionScanner-hit-rest-panel-body"> <pre class="panel-body t3js-extensionScanner-hit-rest-body">restFileContent</pre> @@ -69,16 +88,28 @@ class="panel panel-default t3js-extensionScanner-extension t3js-extensionScanner-extension-{extension}" data-extension="{extension}"> <div class="panel-progress"> - <div class="panel-progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0;"><span class="visually-hidden"></span></div> + <div class="panel-progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0;"> + <span class="visually-hidden">0%</span> + </div> </div> - <div class="panel-heading"> - <h2 class="panel-title"> - <a href="#extension-{iterator.index}" class="collapsed" data-bs-toggle="collapse"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#extension-{iterator.index}" + aria-controls="extension-{iterator.index}" + aria-expanded="false" + > + <div class="panel-title"> + Extension: <strong>{extension}</strong> + </div> + <div class="panel-heading-text t3js-extensionScanner-number-of-files"> + </div> <span class="caret"></span> - Extension: <strong>{extension}</strong> - <span class="float-end t3js-extensionScanner-number-of-files"></span> - </a> - </h2> + </button> + </div> </div> <div class="panel-collapse collapse" id="extension-{iterator.index}"> <div class="panel-body hide t3js-extensionScanner-extension-body"></div> diff --git a/typo3/sysext/install/Resources/Private/Templates/Upgrade/UpgradeDocsGetContent.html b/typo3/sysext/install/Resources/Private/Templates/Upgrade/UpgradeDocsGetContent.html index 3604254d882d..5c8556bad247 100644 --- a/typo3/sysext/install/Resources/Private/Templates/Upgrade/UpgradeDocsGetContent.html +++ b/typo3/sysext/install/Resources/Private/Templates/Upgrade/UpgradeDocsGetContent.html @@ -36,18 +36,24 @@ <div class="panel-group" role="tablist" aria-multiselectable="true"> <f:for each="{upgradeDocsVersions}" as="version" iteration="iterator"> <div class="panel panel-default panel-version t3js-version-changes" data-version="{version}"> - <div class="panel-heading" role="tab" id="heading-{iterator.index}"> - <h2 class="panel-title"> - <a href="#version-{iterator.index}" - class="collapsed" data-bs-toggle="collapse" + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#version-{iterator.index}" + aria-controls="version-{iterator.index}" aria-expanded="false" - aria-controls="#version-{iterator.index}" + id="heading-{iterator.index}" > + <div class="panel-title"> + Version: <strong>{version}</strong> + <span class="t3js-panel-loading"><core:icon identifier="spinner-circle" size="small" /></span> + </div> <span class="caret"></span> - Version: <strong>{version}</strong> - <span class="float-end t3js-panel-loading"><core:icon identifier="spinner-circle" size="small" /></span> - </a> - </h2> + </button> + </div> </div> <div class="panel-collapse collapse" id="version-{iterator.index}" role="tabpanel" data-group-version="{version}"> @@ -57,14 +63,23 @@ </f:for> <div class="panel panel-default panel-version"> - <div class="panel-heading" role="tab" id="heading-read"> - <h2 class="panel-title"> - <a href="#collapseRead" class="collapsed" data-bs-toggle="collapse" aria-expanded="false" - aria-controls="collapseRead"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#collapseRead" + aria-controls="collapseRead" + aria-expanded="false" + id="heading-read" + > + <div class="panel-title"> + Files marked as read + </div> <span class="caret"></span> - Files marked as read - </a> - </h2> + </button> + </div> </div> <div class="panel-collapse collapse" id="collapseRead" role="tabpanel" data-group-version="read"> <div class="panel-body panel-body-read t3js-changelog-list" role="tablist" aria-multiselectable="false"></div> @@ -72,13 +87,23 @@ </div> <div class="panel panel-default panel-version"> - <div class="panel-heading" role="tab" id="heading-not-affected"> - <h2 class="panel-title"> - <a href="#collapseNotAffected" class="collapsed" data-bs-toggle="collapse"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#collapseNotAffected" + aria-controls="collapseNotAffected" + aria-expanded="false" + id="heading-not-affected" + > + <div class="panel-title"> + Files marked as not affected by extension scanner + </div> <span class="caret"></span> - Files marked as not affected by extension scanner - </a> - </h2> + </button> + </div> </div> <div class="panel-collapse collapse" id="collapseNotAffected" role="tabpanel" data-group-version="notAffected"> <div class="panel-body panel-body-not-affected t3js-changelog-list" role="tablist" aria-multiselectable="false"></div> diff --git a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js index 47926246411e..bab6f1577826 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/module/upgrade/extension-scanner.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import"bootstrap";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxQueue from"@typo3/install/ajax/ajax-queue.js";import Router from"@typo3/install/router.js";import RegularEvent from"@typo3/core/event/regular-event.js";var Identifiers;!function(e){e.extensionContainer=".t3js-extensionScanner-extension",e.numberOfFiles=".t3js-extensionScanner-number-of-files",e.scanSingleTrigger=".t3js-extensionScanner-scan-single",e.extensionScanButton=".t3js-extensionScanner-scan-all"}(Identifiers||(Identifiers={}));class ExtensionScanner extends AbstractInteractableModule{constructor(){super(...arguments),this.listOfAffectedRestFileHashes=[]}initialize(e){super.initialize(e),Promise.all([this.loadModuleFrameAgnostic("@typo3/backend/element/progress-bar-element.js")]).then((()=>{this.getData()})),new RegularEvent("typo3-modal-hide",(()=>{AjaxQueue.flush()})).bindTo(e),new RegularEvent("click",((e,n)=>{e.preventDefault();const t=n.closest(Identifiers.extensionContainer).dataset.extension;this.scanSingleExtension(t)})).delegateTo(e,Identifiers.scanSingleTrigger),new RegularEvent("click",(n=>{n.preventDefault(),this.setModalButtonsState(!1);const t=e.querySelectorAll(Identifiers.extensionContainer);this.scanAll(t)})).delegateTo(e,Identifiers.extensionScanButton)}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("extensionScannerGetData")).get().then((async n=>{const t=await n.resolve();!0===t.success?(e.innerHTML=t.html,Modal.setButtons(t.buttons),this.setupEventListeners()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(n=>{Router.handleAjaxError(n,e)}))}setupEventListeners(){this.currentModal.querySelectorAll(Identifiers.extensionContainer).forEach((e=>{new RegularEvent("show.bs.collapse",(e=>{const n=e.currentTarget;if(void 0===n.dataset.scanned){const e=n.dataset.extension;this.scanSingleExtension(e),n.dataset.scanned=String(!0)}})).bindTo(e)}))}getExtensionSelector(e){return Identifiers.extensionContainer+"-"+e}async scanAll(e){e.forEach((e=>{e.classList.remove("panel-danger","panel-warning","panel-success");const n=e.querySelector(".panel-progress-bar");n.style.width=String(0),n.setAttribute("aria-valuenow",String(0)),n.querySelector("span").innerText="0%"})),this.setProgressForAll();const n=[...e].map((async e=>{const n=e.dataset.extension;try{await this.scanSingleExtension(n)}finally{e.dataset.scanned=String(!0)}}));try{await Promise.allSettled(n)}finally{this.setModalButtonsState(!0),Notification.success("Scan finished","All extensions have been scanned.");try{const e=await new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerMarkFullyScannedRestFiles",token:this.getModuleContent().dataset.extensionScannerMarkFullyScannedRestFilesToken,hashes:Array.from(new Set(this.listOfAffectedRestFileHashes))}}),n=await e.resolve();!0===n.success&&Notification.success("Marked not affected files","Marked "+n.markedAsNotAffected+" ReST files as not affected.")}catch(e){Router.handleAjaxError(e,this.getModalBody())}}}setStatusMessageForScan(e,n,t){this.findInModal(this.getExtensionSelector(e)).querySelector(Identifiers.numberOfFiles).innerText="Checked "+n+" of "+t+" files"}setProgressForScan(e,n,t){const s=n/t*100,i=this.findInModal(this.getExtensionSelector(e)).querySelector(".panel-progress-bar");i.style.width=s+"%",i.setAttribute("aria-valuenow",String(s)),i.querySelector("span").innerText=s+"%"}setProgressForAll(){const e=this.currentModal.querySelectorAll(Identifiers.extensionContainer).length,n=this.currentModal.querySelectorAll(Identifiers.extensionContainer+".t3js-extensionscan-finished").length,t=`Scanning extensions (${n} of ${e} done)…`,s=this.findInModal(".t3js-extensionScanner-progress-all-extension");s.removeAttribute("hidden"),s.max=e,s.value=n,s.label=t}async scanSingleExtension(e){const n=this.getModuleContent().dataset.extensionScannerFilesToken,t=this.getModalBody(),s=this.findInModal(this.getExtensionSelector(e));let i=!1;s.classList.add("panel-default"),s.classList.remove("panel-danger","panel-warning","panel-success","t3js-extensionscan-finished"),s.dataset.hasRun=String("true");const a=s.querySelector(".t3js-extensionScanner-scan-single");a.innerText="Scanning...",a.disabled=!0,s.querySelector(".t3js-extensionScanner-extension-body-loc").innerText="0",s.querySelector(".t3js-extensionScanner-extension-body-ignored-files").innerText="0",s.querySelector(".t3js-extensionScanner-extension-body-ignored-lines").innerText="0",this.setProgressForAll();try{const a=await new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerFiles",token:n,extension:e}}),r=await a.resolve();if(!0===r.success&&Array.isArray(r.files)){const n=r.files.length;if(n<=0)return void Notification.warning("No files found","The extension "+e+" contains no scannable files");this.setStatusMessageForScan(e,0,n),s.querySelector(".t3js-extensionScanner-extension-body").innerText="",s.classList.add("panel-has-progress");let a=0;const o=r.files.map((r=>new Promise(((o,l)=>{AjaxQueue.add({method:"POST",data:{install:{action:"extensionScannerScanFile",token:this.getModuleContent().dataset.extensionScannerScanFileToken,extension:e,file:r}},url:Router.getUrl(),onfulfilled:async l=>{const c=await l.resolve();if(a++,this.setStatusMessageForScan(e,a,n),this.setProgressForScan(e,a,n),c.success&&Array.isArray(c.matches)&&c.matches.forEach((e=>{i=!0;const n=t.querySelector("#t3js-extensionScanner-file-hit-template .panel").cloneNode(!0);n.querySelector(".t3js-extensionScanner-hit-file-panel-head").setAttribute("href","#collapse"+e.uniqueId),n.querySelector(".t3js-extensionScanner-hit-file-panel-body").setAttribute("id","collapse"+e.uniqueId),n.querySelector(".t3js-extensionScanner-hit-filename").innerText=r,n.querySelector(".t3js-extensionScanner-hit-message").innerText=e.message,"strong"===e.indicator?n.querySelector(".t3js-extensionScanner-hit-file-panel-head .badges").innerHTML+='<span class="badge badge-danger" title="Reliable match, false positive unlikely">strong</span>':n.querySelector(".t3js-extensionScanner-hit-file-panel-head .badges").innerHTML+='<span class="badge badge-warning" title="Probable match, but can be a false positive">weak</span>',!0===e.silenced&&(n.querySelector(".t3js-extensionScanner-hit-file-panel-head .badges").innerHTML+='<span class="badge badge-info" title="Match has been annotated by extension author as false positive match">silenced</span>'),n.querySelector(".t3js-extensionScanner-hit-file-lineContent").innerText=e.lineContent,n.querySelector(".t3js-extensionScanner-hit-file-line").innerText=e.line+": ",Array.isArray(e.restFiles)&&e.restFiles.forEach((e=>{const s=t.querySelector("#t3js-extensionScanner-file-hit-rest-template .panel").cloneNode(!0);s.querySelector(".t3js-extensionScanner-hit-rest-panel-head").setAttribute("href","#collapse"+e.uniqueId),s.querySelector(".t3js-extensionScanner-hit-rest-panel-head .badge").innerText=e.version,s.querySelector(".t3js-extensionScanner-hit-rest-panel-body").setAttribute("id","collapse"+e.uniqueId),s.querySelector(".t3js-extensionScanner-hit-rest-headline").innerText=e.headline,s.querySelector(".t3js-extensionScanner-hit-rest-body").innerText=e.content,s.classList.add("panel-"+e.class),n.querySelector(".t3js-extensionScanner-hit-file-rest-container").append(s),this.listOfAffectedRestFileHashes.push(e.file_hash)}));const a=n.querySelectorAll(".panel-breaking, .t3js-extensionScanner-hit-file-rest-container").length>0?"panel-danger":"panel-warning";n.classList.add(a),n.classList.remove("panel-default");const o=s.querySelector(".t3js-extensionScanner-extension-body");o.classList.remove("hide"),o.append(n),s.classList.remove("panel-default"),"panel-danger"===a&&(s.classList.remove("panel-warning"),s.classList.add(a)),"panel-warning"!==a||s.classList.contains("panel-danger")||s.classList.add(a)})),c.success){const e=parseInt(s.querySelector(".t3js-extensionScanner-extension-body-loc").innerText,10);if(s.querySelector(".t3js-extensionScanner-extension-body-loc").innerText=String(e+c.effectiveCodeLines),c.isFileIgnored){const e=parseInt(s.querySelector(".t3js-extensionScanner-extension-body-ignored-files").innerText,10);s.querySelector(".t3js-extensionScanner-extension-body-ignored-files").innerText=String(e+1)}const n=parseInt(s.querySelector(".t3js-extensionScanner-extension-body-ignored-lines").innerText,10);s.querySelector(".t3js-extensionScanner-extension-body-ignored-lines").innerText=String(n+c.ignoredLines)}o()},onrejected:t=>{l(),a+=1,this.setStatusMessageForScan(e,a,n),this.setProgressForScan(e,a,n),s.classList.remove("panel-has-progress"),this.setProgressForAll(),console.error(t)}})}))));await Promise.allSettled(o),i||(s.classList.remove("panel-default"),s.classList.add("panel-success")),s.classList.add("t3js-extensionscan-finished"),s.classList.remove("panel-has-progress"),this.setProgressForAll();const l=s.querySelector(".t3js-extensionScanner-scan-single");l.innerText="Rescan",l.disabled=!1}else Notification.error("Oops, an error occurred","Please look at the browser console output for details"),console.error(r)}catch(e){Router.handleAjaxError(e,t)}}}export default new ExtensionScanner; \ No newline at end of file +import"bootstrap";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{AbstractInteractableModule}from"@typo3/install/module/abstract-interactable-module.js";import Modal from"@typo3/backend/modal.js";import Notification from"@typo3/backend/notification.js";import AjaxQueue from"@typo3/install/ajax/ajax-queue.js";import Router from"@typo3/install/router.js";import RegularEvent from"@typo3/core/event/regular-event.js";var Identifiers;!function(e){e.extensionContainer=".t3js-extensionScanner-extension",e.numberOfFiles=".t3js-extensionScanner-number-of-files",e.scanSingleTrigger=".t3js-extensionScanner-scan-single",e.extensionScanButton=".t3js-extensionScanner-scan-all"}(Identifiers||(Identifiers={}));class ExtensionScanner extends AbstractInteractableModule{constructor(){super(...arguments),this.listOfAffectedRestFileHashes=[]}initialize(e){super.initialize(e),Promise.all([this.loadModuleFrameAgnostic("@typo3/backend/element/progress-bar-element.js")]).then((()=>{this.getData()})),new RegularEvent("typo3-modal-hide",(()=>{AjaxQueue.flush()})).bindTo(e),new RegularEvent("click",((e,n)=>{e.preventDefault();const t=n.closest(Identifiers.extensionContainer).dataset.extension;this.scanSingleExtension(t)})).delegateTo(e,Identifiers.scanSingleTrigger),new RegularEvent("click",(n=>{n.preventDefault(),this.setModalButtonsState(!1);const t=e.querySelectorAll(Identifiers.extensionContainer);this.scanAll(t)})).delegateTo(e,Identifiers.extensionScanButton)}getData(){const e=this.getModalBody();new AjaxRequest(Router.getUrl("extensionScannerGetData")).get().then((async n=>{const t=await n.resolve();!0===t.success?(e.innerHTML=t.html,Modal.setButtons(t.buttons),this.setupEventListeners()):Notification.error("Something went wrong","The request was not processed successfully. Please check the browser's console and TYPO3's log.")}),(n=>{Router.handleAjaxError(n,e)}))}setupEventListeners(){this.currentModal.querySelectorAll(Identifiers.extensionContainer).forEach((e=>{new RegularEvent("show.bs.collapse",(e=>{const n=e.currentTarget;if(void 0===n.dataset.scanned){const e=n.dataset.extension;this.scanSingleExtension(e),n.dataset.scanned=String(!0)}})).bindTo(e)}))}getExtensionSelector(e){return Identifiers.extensionContainer+"-"+e}async scanAll(e){e.forEach((e=>{e.classList.remove("panel-danger","panel-warning","panel-success");const n=e.querySelector(".panel-progress-bar");n.style.width=String(0),n.setAttribute("aria-valuenow",String(0)),n.querySelector("span").innerText="0%"})),this.setProgressForAll();const n=[...e].map((async e=>{const n=e.dataset.extension;try{await this.scanSingleExtension(n)}finally{e.dataset.scanned=String(!0)}}));try{await Promise.allSettled(n)}finally{this.setModalButtonsState(!0),Notification.success("Scan finished","All extensions have been scanned.");try{const e=await new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerMarkFullyScannedRestFiles",token:this.getModuleContent().dataset.extensionScannerMarkFullyScannedRestFilesToken,hashes:Array.from(new Set(this.listOfAffectedRestFileHashes))}}),n=await e.resolve();!0===n.success&&Notification.success("Marked not affected files","Marked "+n.markedAsNotAffected+" ReST files as not affected.")}catch(e){Router.handleAjaxError(e,this.getModalBody())}}}setStatusMessageForScan(e,n,t){this.findInModal(this.getExtensionSelector(e)).querySelector(Identifiers.numberOfFiles).innerText="Checked "+n+" of "+t+" files"}setProgressForScan(e,n,t){const s=n/t*100,a=this.findInModal(this.getExtensionSelector(e)).querySelector(".panel-progress-bar");a.style.width=s+"%",a.setAttribute("aria-valuenow",String(s)),a.querySelector("span").innerText=s+"%"}setProgressForAll(){const e=this.currentModal.querySelectorAll(Identifiers.extensionContainer).length,n=this.currentModal.querySelectorAll(Identifiers.extensionContainer+".t3js-extensionscan-finished").length,t=`Scanning extensions (${n} of ${e} done)…`,s=this.findInModal(".t3js-extensionScanner-progress-all-extension");s.removeAttribute("hidden"),s.max=e,s.value=n,s.label=t}async scanSingleExtension(e){const n=this.getModuleContent().dataset.extensionScannerFilesToken,t=this.getModalBody(),s=this.findInModal(this.getExtensionSelector(e));let a=!1;s.classList.add("panel-default"),s.classList.remove("panel-danger","panel-warning","panel-success","t3js-extensionscan-finished"),s.dataset.hasRun=String("true");const i=s.querySelector(".t3js-extensionScanner-scan-single");i.innerText="Scanning...",i.disabled=!0,s.querySelector(".t3js-extensionScanner-extension-body-loc").innerText="0",s.querySelector(".t3js-extensionScanner-extension-body-ignored-files").innerText="0",s.querySelector(".t3js-extensionScanner-extension-body-ignored-lines").innerText="0",this.setProgressForAll();try{const i=await new AjaxRequest(Router.getUrl()).post({install:{action:"extensionScannerFiles",token:n,extension:e}}),r=await i.resolve();if(!0===r.success&&Array.isArray(r.files)){const n=r.files.length;if(n<=0)return void Notification.warning("No files found","The extension "+e+" contains no scannable files");this.setStatusMessageForScan(e,0,n),s.querySelector(".t3js-extensionScanner-extension-body").innerText="",s.classList.add("panel-has-progress");let i=0;const o=r.files.map((r=>new Promise(((o,l)=>{AjaxQueue.add({method:"POST",data:{install:{action:"extensionScannerScanFile",token:this.getModuleContent().dataset.extensionScannerScanFileToken,extension:e,file:r}},url:Router.getUrl(),onfulfilled:async l=>{const c=await l.resolve();if(i++,this.setStatusMessageForScan(e,i,n),this.setProgressForScan(e,i,n),c.success&&Array.isArray(c.matches)&&c.matches.forEach((e=>{a=!0;const n=t.querySelector("#t3js-extensionScanner-file-hit-template .panel").cloneNode(!0);n.querySelector(".t3js-extensionScanner-hit-file-panel-head").setAttribute("data-bs-target","#collapse"+e.uniqueId),n.querySelector(".t3js-extensionScanner-hit-file-panel-head").setAttribute("aria-controls","collapse"+e.uniqueId),n.querySelector(".t3js-extensionScanner-hit-file-panel-body").setAttribute("id","collapse"+e.uniqueId),n.querySelector(".t3js-extensionScanner-hit-filename").innerText=r,n.querySelector(".t3js-extensionScanner-hit-message").innerText=e.message,"strong"===e.indicator?n.querySelector(".t3js-extensionScanner-hit-file-panel-head .t3js-extensionScanner-hit-badges").innerHTML+='<span class="badge badge-danger" title="Reliable match, false positive unlikely">strong</span>':n.querySelector(".t3js-extensionScanner-hit-file-panel-head .t3js-extensionScanner-hit-badges").innerHTML+='<span class="badge badge-warning" title="Probable match, but can be a false positive">weak</span>',!0===e.silenced&&(n.querySelector(".t3js-extensionScanner-hit-file-panel-head .t3js-extensionScanner-hit-badges").innerHTML+='<span class="badge badge-info" title="Match has been annotated by extension author as false positive match">silenced</span>'),n.querySelector(".t3js-extensionScanner-hit-file-lineContent").innerText=e.lineContent,n.querySelector(".t3js-extensionScanner-hit-file-line").innerText=e.line+": ",Array.isArray(e.restFiles)&&e.restFiles.forEach((e=>{const s=t.querySelector("#t3js-extensionScanner-file-hit-rest-template .panel").cloneNode(!0);s.querySelector(".t3js-extensionScanner-hit-rest-panel-head").setAttribute("data-bs-target","#collapse"+e.uniqueId),s.querySelector(".t3js-extensionScanner-hit-rest-panel-head").setAttribute("aria-controls","collapse"+e.uniqueId),s.querySelector(".t3js-extensionScanner-hit-rest-panel-head .t3js-extensionScanner-hit-rest-badge").innerText=e.version,s.querySelector(".t3js-extensionScanner-hit-rest-panel-body").setAttribute("id","collapse"+e.uniqueId),s.querySelector(".t3js-extensionScanner-hit-rest-headline").innerText=e.headline,s.querySelector(".t3js-extensionScanner-hit-rest-body").innerText=e.content,s.classList.add("panel-"+e.class),n.querySelector(".t3js-extensionScanner-hit-file-rest-container").append(s),this.listOfAffectedRestFileHashes.push(e.file_hash)}));const i=n.querySelectorAll(".panel-breaking, .t3js-extensionScanner-hit-file-rest-container").length>0?"panel-danger":"panel-warning";n.classList.add(i),n.classList.remove("panel-default");const o=s.querySelector(".t3js-extensionScanner-extension-body");o.classList.remove("hide"),o.append(n),s.classList.remove("panel-default"),"panel-danger"===i&&(s.classList.remove("panel-warning"),s.classList.add(i)),"panel-warning"!==i||s.classList.contains("panel-danger")||s.classList.add(i)})),c.success){const e=parseInt(s.querySelector(".t3js-extensionScanner-extension-body-loc").innerText,10);if(s.querySelector(".t3js-extensionScanner-extension-body-loc").innerText=String(e+c.effectiveCodeLines),c.isFileIgnored){const e=parseInt(s.querySelector(".t3js-extensionScanner-extension-body-ignored-files").innerText,10);s.querySelector(".t3js-extensionScanner-extension-body-ignored-files").innerText=String(e+1)}const n=parseInt(s.querySelector(".t3js-extensionScanner-extension-body-ignored-lines").innerText,10);s.querySelector(".t3js-extensionScanner-extension-body-ignored-lines").innerText=String(n+c.ignoredLines)}o()},onrejected:t=>{l(),i+=1,this.setStatusMessageForScan(e,i,n),this.setProgressForScan(e,i,n),s.classList.remove("panel-has-progress"),this.setProgressForAll(),console.error(t)}})}))));await Promise.allSettled(o),a||(s.classList.remove("panel-default"),s.classList.add("panel-success")),s.classList.add("t3js-extensionscan-finished"),s.classList.remove("panel-has-progress"),this.setProgressForAll();const l=s.querySelector(".t3js-extensionScanner-scan-single");l.innerText="Rescan",l.disabled=!1}else Notification.error("Oops, an error occurred","Please look at the browser console output for details"),console.error(r)}catch(e){Router.handleAjaxError(e,t)}}}export default new ExtensionScanner; \ No newline at end of file diff --git a/typo3/sysext/install/Resources/Public/JavaScript/router.js b/typo3/sysext/install/Resources/Public/JavaScript/router.js index 99b53e4feda7..25b89e7daac7 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/router.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/router.js @@ -10,4 +10,4 @@ * * The TYPO3 project - inspiring people to share! */ -import{html}from"lit";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{default as Modal}from"@typo3/backend/modal.js";import{InfoBox}from"@typo3/install/renderable/info-box.js";import Severity from"@typo3/install/renderable/severity.js";import"@typo3/backend/element/spinner-element.js";import RegularEvent from"@typo3/core/event/regular-event.js";import"@typo3/backend/element/progress-bar-element.js";class Router{constructor(){this.rootSelector=".t3js-body",this.contentSelector=".t3js-module-body",this.scaffoldSelector=".t3js-scaffold",this.scaffoldContentOverlaySelector=".t3js-scaffold-content-overlay",this.scaffoldMenuToggleSelector=".t3js-topbar-button-modulemenu"}setContent(e){const t=this.rootContainer.querySelector(this.contentSelector);"string"==typeof e&&(e=document.createRange().createContextualFragment(e)),t.replaceChildren(e)}initialize(){this.rootContainer=document.querySelector(this.rootSelector),this.context=this.rootContainer.dataset.context??"",this.controller=this.rootContainer.dataset.controller??"",this.registerInstallToolRoutes(),new RegularEvent("click",(e=>{e.preventDefault(),this.logout()})).delegateTo(document,".t3js-login-lockInstallTool"),new RegularEvent("click",(e=>{e.preventDefault(),this.login()})).delegateTo(document,".t3js-login-login"),new RegularEvent("keydown",(e=>{"Enter"===e.key&&(e.preventDefault(),this.login())})).delegateTo(document,"#t3-install-form-password"),new RegularEvent("click",((e,t)=>{e.preventDefault();const o=t.dataset.import,n=t.dataset.inline;if(void 0!==n&&1===parseInt(n,10))import(o).then((({default:e})=>{e.initialize(t)}));else{const e=t.closest(".card").querySelector(".card-title").innerHTML,n=t.dataset.modalSize||Modal.sizes.large;Modal.advanced({type:Modal.types.default,title:e,size:n,content:html`<div class="modal-loading"><typo3-backend-spinner size="large"></typo3-backend-spinner></div>`,additionalCssClasses:["install-tool-modal"],staticBackdrop:!0,callback:e=>{import(o).then((({default:t})=>{t.initialize(e)}))}})}})).delegateTo(document,".card .btn"),"backend"===this.context?this.executeSilentConfigurationUpdate():this.preAccessCheck()}registerInstallToolRoutes(){void 0===TYPO3.settings&&(TYPO3.settings={ajaxUrls:{icons:window.location.origin+window.location.pathname+"?install[controller]=icon&install[action]=getIcon",icons_cache:window.location.origin+window.location.pathname+"?install[controller]=icon&install[action]=getCacheIdentifier"}})}getUrl(e,t,o){const n=new URL(location.href,window.origin);if(n.searchParams.set("install[controller]",t??this.controller),n.searchParams.set("install[context]",this.context),void 0!==e&&n.searchParams.set("install[action]",e),void 0!==o)for(const[e,t]of Object.entries(o))n.searchParams.set(e,t);return n.toString()}executeSilentConfigurationUpdate(){this.updateLoadingInfo("Checking session and executing silent configuration update"),new AjaxRequest(this.getUrl("executeSilentConfigurationUpdate","layout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.executeSilentTemplateFileUpdate():this.executeSilentConfigurationUpdate()}),(e=>{this.handleAjaxError(e)}))}executeSilentTemplateFileUpdate(){this.updateLoadingInfo("Checking session and executing silent template file update"),new AjaxRequest(this.getUrl("executeSilentTemplateFileUpdate","layout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.executeSilentExtensionConfigurationSynchronization():this.executeSilentTemplateFileUpdate()}),(e=>{this.handleAjaxError(e)}))}executeSilentExtensionConfigurationSynchronization(){this.updateLoadingInfo("Executing silent extension configuration synchronization"),new AjaxRequest(this.getUrl("executeSilentExtensionConfigurationSynchronization","layout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.loadMainLayout():this.setContent(InfoBox.create(Severity.error,"Something went wrong"))}),(e=>{this.handleAjaxError(e)}))}loadMainLayout(){this.updateLoadingInfo("Loading main layout"),new AjaxRequest(this.getUrl("mainLayout","layout",{"install[module]":this.controller})).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&"undefined"!==t.html&&t.html.length>0?(this.rootContainer.innerHTML=t.html,"backend"!==this.context&&(this.rootContainer.querySelector('[data-installroute-controller="'+this.controller+'"]').classList.add("modulemenu-action-active"),this.registerScaffoldEvents()),this.loadCards()):this.rootContainer.replaceChildren(InfoBox.create(Severity.error,"Something went wrong"))}),(e=>{this.handleAjaxError(e)}))}async handleAjaxError(e,t){if(403===e.response.status)"backend"===this.context?this.rootContainer.replaceChildren(InfoBox.create(Severity.error,"The Install Tool session expired. Please reload the backend and try again.")):this.checkEnableInstallToolFile();else{const o='<div class="t3js-infobox callout callout-sm callout-danger"><div class="callout-content"><div class="callout-title">Something went wrong</div><div class="callout-body"><p>Please use <b><a href="'+this.getUrl(void 0,"upgrade")+'">Check for broken extensions</a></b> to see if a loaded extension breaks this part of the Install Tool and unload it.</p><p>The box below may additionally reveal further details on what went wrong depending on your debug settings. It may help to temporarily switch to debug mode using <b>Settings > Configuration Presets > Debug settings.</b></p><p>If this error happens at an early state and no full exception back trace is shown, it may also help to manually increase debugging output in <strong>%config-dir%/system/settings.php</strong>:<code>[\'BE\'][\'debug\'] => true</code>, <code>[\'SYS\'][\'devIPmask\'] => \'*\'</code>, <code>[\'SYS\'][\'displayErrors\'] => 1</code>,<code>[\'SYS\'][\'exceptionalErrors\'] => 12290</code></p></div></div></div><div class="panel-group" role="tablist" aria-multiselectable="true"><div class="panel panel-default searchhit"><div class="panel-heading" role="tab" id="heading-error"><h3 class="panel-title"><a role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" href="#collapse-error" aria-expanded="true" aria-controls="collapse-error" class="collapsed"><span class="caret"></span><strong>Ajax error</strong></a></h3></div><div id="collapse-error" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-error"><div class="panel-body">'+await e.response.text()+"</div></div></div></div>";void 0!==t?t.innerHTML=o:this.rootContainer.innerHTML=o}}checkEnableInstallToolFile(){new AjaxRequest(this.getUrl("checkEnableInstallToolFile")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.checkLogin():this.showEnableInstallTool()}),(e=>{this.handleAjaxError(e)}))}showEnableInstallTool(){new AjaxRequest(this.getUrl("showEnableInstallToolFile")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&(this.rootContainer.innerHTML=t.html)}),(e=>{this.handleAjaxError(e)}))}checkLogin(){new AjaxRequest(this.getUrl("checkLogin")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.loadMainLayout():this.showLogin()}),(e=>{this.handleAjaxError(e)}))}showLogin(){new AjaxRequest(this.getUrl("showLogin")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&(this.rootContainer.innerHTML=t.html)}),(e=>{this.handleAjaxError(e)}))}login(){const e=document.querySelector(".t3js-login-output"),t=document.createElement("typo3-backend-progress-bar");e.replaceChildren(t),new AjaxRequest(this.getUrl()).post({install:{action:"login",token:document.querySelector("[data-login-token]").dataset.loginToken,password:document.querySelector(".t3-install-form-input-text").value}}).then((async t=>{const o=await t.resolve();!0===o.success?this.executeSilentConfigurationUpdate():o.status.forEach((t=>{e.replaceChildren(InfoBox.create(t.severity,t.title,t.message))}))}),(e=>{this.handleAjaxError(e)}))}logout(){new AjaxRequest(this.getUrl("logout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success&&this.showEnableInstallTool()}),(e=>{this.handleAjaxError(e)}))}loadCards(){new AjaxRequest(this.getUrl("cards")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&"undefined"!==t.html&&t.html.length>0?this.setContent(t.html):this.setContent(InfoBox.create(Severity.error,"Something went wrong"))}),(e=>{this.handleAjaxError(e)}))}registerScaffoldEvents(){localStorage.getItem("typo3-install-modulesCollapsed")||localStorage.setItem("typo3-install-modulesCollapsed","false"),this.toggleMenu("true"===localStorage.getItem("typo3-install-modulesCollapsed")),document.querySelector(this.scaffoldMenuToggleSelector).addEventListener("click",(e=>{e.preventDefault(),this.toggleMenu()})),document.querySelector(this.scaffoldContentOverlaySelector).addEventListener("click",(e=>{e.preventDefault(),this.toggleMenu(!0)})),document.querySelectorAll("[data-installroute-controller]").forEach((e=>{e.addEventListener("click",(()=>{window.innerWidth<768&&localStorage.setItem("typo3-install-modulesCollapsed","true")}))}))}toggleMenu(e){const t=document.querySelector(this.scaffoldSelector),o="scaffold-modulemenu-expanded";void 0===e&&(e=t.classList.contains(o)),t.classList.toggle(o,!e),localStorage.setItem("typo3-install-modulesCollapsed",e?"true":"false")}updateLoadingInfo(e){const t=this.rootContainer.querySelector("#t3js-ui-block-detail");void 0!==t&&t instanceof HTMLElement&&(t.innerText=e)}preAccessCheck(){this.updateLoadingInfo("Execute pre access check"),new AjaxRequest(this.getUrl("preAccessCheck","layout")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();t.installToolLocked?this.checkEnableInstallToolFile():t.isAuthorized?this.executeSilentConfigurationUpdate():this.showLogin()}),(e=>{this.handleAjaxError(e)}))}}export default new Router; \ No newline at end of file +import{html}from"lit";import AjaxRequest from"@typo3/core/ajax/ajax-request.js";import{default as Modal}from"@typo3/backend/modal.js";import{InfoBox}from"@typo3/install/renderable/info-box.js";import Severity from"@typo3/install/renderable/severity.js";import"@typo3/backend/element/spinner-element.js";import RegularEvent from"@typo3/core/event/regular-event.js";import"@typo3/backend/element/progress-bar-element.js";class Router{constructor(){this.rootSelector=".t3js-body",this.contentSelector=".t3js-module-body",this.scaffoldSelector=".t3js-scaffold",this.scaffoldContentOverlaySelector=".t3js-scaffold-content-overlay",this.scaffoldMenuToggleSelector=".t3js-topbar-button-modulemenu"}setContent(e){const t=this.rootContainer.querySelector(this.contentSelector);"string"==typeof e&&(e=document.createRange().createContextualFragment(e)),t.replaceChildren(e)}initialize(){this.rootContainer=document.querySelector(this.rootSelector),this.context=this.rootContainer.dataset.context??"",this.controller=this.rootContainer.dataset.controller??"",this.registerInstallToolRoutes(),new RegularEvent("click",(e=>{e.preventDefault(),this.logout()})).delegateTo(document,".t3js-login-lockInstallTool"),new RegularEvent("click",(e=>{e.preventDefault(),this.login()})).delegateTo(document,".t3js-login-login"),new RegularEvent("keydown",(e=>{"Enter"===e.key&&(e.preventDefault(),this.login())})).delegateTo(document,"#t3-install-form-password"),new RegularEvent("click",((e,t)=>{e.preventDefault();const o=t.dataset.import,n=t.dataset.inline;if(void 0!==n&&1===parseInt(n,10))import(o).then((({default:e})=>{e.initialize(t)}));else{const e=t.closest(".card").querySelector(".card-title").innerHTML,n=t.dataset.modalSize||Modal.sizes.large;Modal.advanced({type:Modal.types.default,title:e,size:n,content:html`<div class="modal-loading"><typo3-backend-spinner size="large"></typo3-backend-spinner></div>`,additionalCssClasses:["install-tool-modal"],staticBackdrop:!0,callback:e=>{import(o).then((({default:t})=>{t.initialize(e)}))}})}})).delegateTo(document,".card .btn"),"backend"===this.context?this.executeSilentConfigurationUpdate():this.preAccessCheck()}registerInstallToolRoutes(){void 0===TYPO3.settings&&(TYPO3.settings={ajaxUrls:{icons:window.location.origin+window.location.pathname+"?install[controller]=icon&install[action]=getIcon",icons_cache:window.location.origin+window.location.pathname+"?install[controller]=icon&install[action]=getCacheIdentifier"}})}getUrl(e,t,o){const n=new URL(location.href,window.origin);if(n.searchParams.set("install[controller]",t??this.controller),n.searchParams.set("install[context]",this.context),void 0!==e&&n.searchParams.set("install[action]",e),void 0!==o)for(const[e,t]of Object.entries(o))n.searchParams.set(e,t);return n.toString()}executeSilentConfigurationUpdate(){this.updateLoadingInfo("Checking session and executing silent configuration update"),new AjaxRequest(this.getUrl("executeSilentConfigurationUpdate","layout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.executeSilentTemplateFileUpdate():this.executeSilentConfigurationUpdate()}),(e=>{this.handleAjaxError(e)}))}executeSilentTemplateFileUpdate(){this.updateLoadingInfo("Checking session and executing silent template file update"),new AjaxRequest(this.getUrl("executeSilentTemplateFileUpdate","layout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.executeSilentExtensionConfigurationSynchronization():this.executeSilentTemplateFileUpdate()}),(e=>{this.handleAjaxError(e)}))}executeSilentExtensionConfigurationSynchronization(){this.updateLoadingInfo("Executing silent extension configuration synchronization"),new AjaxRequest(this.getUrl("executeSilentExtensionConfigurationSynchronization","layout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.loadMainLayout():this.setContent(InfoBox.create(Severity.error,"Something went wrong"))}),(e=>{this.handleAjaxError(e)}))}loadMainLayout(){this.updateLoadingInfo("Loading main layout"),new AjaxRequest(this.getUrl("mainLayout","layout",{"install[module]":this.controller})).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&"undefined"!==t.html&&t.html.length>0?(this.rootContainer.innerHTML=t.html,"backend"!==this.context&&(this.rootContainer.querySelector('[data-installroute-controller="'+this.controller+'"]').classList.add("modulemenu-action-active"),this.registerScaffoldEvents()),this.loadCards()):this.rootContainer.replaceChildren(InfoBox.create(Severity.error,"Something went wrong"))}),(e=>{this.handleAjaxError(e)}))}async handleAjaxError(e,t){if(403===e.response.status)"backend"===this.context?this.rootContainer.replaceChildren(InfoBox.create(Severity.error,"The Install Tool session expired. Please reload the backend and try again.")):this.checkEnableInstallToolFile();else{const o='<div class="t3js-infobox callout callout-sm callout-danger"><div class="callout-content"><div class="callout-title">Something went wrong</div><div class="callout-body"><p>Please use <b><a href="'+this.getUrl(void 0,"upgrade")+'">Check for broken extensions</a></b> to see if a loaded extension breaks this part of the Install Tool and unload it.</p><p>The box below may additionally reveal further details on what went wrong depending on your debug settings. It may help to temporarily switch to debug mode using <b>Settings > Configuration Presets > Debug settings.</b></p><p>If this error happens at an early state and no full exception back trace is shown, it may also help to manually increase debugging output in <strong>%config-dir%/system/settings.php</strong>:<code>[\'BE\'][\'debug\'] => true</code>, <code>[\'SYS\'][\'devIPmask\'] => \'*\'</code>, <code>[\'SYS\'][\'displayErrors\'] => 1</code>,<code>[\'SYS\'][\'exceptionalErrors\'] => 12290</code></p></div></div></div><div class="panel-group" role="tablist" aria-multiselectable="true"><div class="panel panel-default"><h3 class="panel-heading" role="tab" id="heading-error"><div class="panel-heading-row"><button type="button" data-bs-toggle="collapse" data-bs-parent="#accordion" data-bs-target="#collapse-error" aria-expanded="true" aria-controls="collapse-error" class="panel-button collapsed"><div class="panel-title"><strong>Ajax error</strong></div><span class="caret"></span></button></div></h3><div id="collapse-error" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-error"><div class="panel-body">'+await e.response.text()+"</div></div></div></div>";void 0!==t?t.innerHTML=o:this.rootContainer.innerHTML=o}}checkEnableInstallToolFile(){new AjaxRequest(this.getUrl("checkEnableInstallToolFile")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.checkLogin():this.showEnableInstallTool()}),(e=>{this.handleAjaxError(e)}))}showEnableInstallTool(){new AjaxRequest(this.getUrl("showEnableInstallToolFile")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&(this.rootContainer.innerHTML=t.html)}),(e=>{this.handleAjaxError(e)}))}checkLogin(){new AjaxRequest(this.getUrl("checkLogin")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success?this.loadMainLayout():this.showLogin()}),(e=>{this.handleAjaxError(e)}))}showLogin(){new AjaxRequest(this.getUrl("showLogin")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&(this.rootContainer.innerHTML=t.html)}),(e=>{this.handleAjaxError(e)}))}login(){const e=document.querySelector(".t3js-login-output"),t=document.createElement("typo3-backend-progress-bar");e.replaceChildren(t),new AjaxRequest(this.getUrl()).post({install:{action:"login",token:document.querySelector("[data-login-token]").dataset.loginToken,password:document.querySelector(".t3-install-form-input-text").value}}).then((async t=>{const o=await t.resolve();!0===o.success?this.executeSilentConfigurationUpdate():o.status.forEach((t=>{e.replaceChildren(InfoBox.create(t.severity,t.title,t.message))}))}),(e=>{this.handleAjaxError(e)}))}logout(){new AjaxRequest(this.getUrl("logout")).get({cache:"no-cache"}).then((async e=>{!0===(await e.resolve()).success&&this.showEnableInstallTool()}),(e=>{this.handleAjaxError(e)}))}loadCards(){new AjaxRequest(this.getUrl("cards")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();!0===t.success&&"undefined"!==t.html&&t.html.length>0?this.setContent(t.html):this.setContent(InfoBox.create(Severity.error,"Something went wrong"))}),(e=>{this.handleAjaxError(e)}))}registerScaffoldEvents(){localStorage.getItem("typo3-install-modulesCollapsed")||localStorage.setItem("typo3-install-modulesCollapsed","false"),this.toggleMenu("true"===localStorage.getItem("typo3-install-modulesCollapsed")),document.querySelector(this.scaffoldMenuToggleSelector).addEventListener("click",(e=>{e.preventDefault(),this.toggleMenu()})),document.querySelector(this.scaffoldContentOverlaySelector).addEventListener("click",(e=>{e.preventDefault(),this.toggleMenu(!0)})),document.querySelectorAll("[data-installroute-controller]").forEach((e=>{e.addEventListener("click",(()=>{window.innerWidth<768&&localStorage.setItem("typo3-install-modulesCollapsed","true")}))}))}toggleMenu(e){const t=document.querySelector(this.scaffoldSelector),o="scaffold-modulemenu-expanded";void 0===e&&(e=t.classList.contains(o)),t.classList.toggle(o,!e),localStorage.setItem("typo3-install-modulesCollapsed",e?"true":"false")}updateLoadingInfo(e){const t=this.rootContainer.querySelector("#t3js-ui-block-detail");void 0!==t&&t instanceof HTMLElement&&(t.innerText=e)}preAccessCheck(){this.updateLoadingInfo("Execute pre access check"),new AjaxRequest(this.getUrl("preAccessCheck","layout")).get({cache:"no-cache"}).then((async e=>{const t=await e.resolve();t.installToolLocked?this.checkEnableInstallToolFile():t.isAuthorized?this.executeSilentConfigurationUpdate():this.showLogin()}),(e=>{this.handleAjaxError(e)}))}}export default new Router; \ No newline at end of file diff --git a/typo3/sysext/recycler/Resources/Private/Partials/RecordsTable/DeletedRecord.html b/typo3/sysext/recycler/Resources/Private/Partials/RecordsTable/DeletedRecord.html index 08a4580b758c..3b74878b05c9 100644 --- a/typo3/sysext/recycler/Resources/Private/Partials/RecordsTable/DeletedRecord.html +++ b/typo3/sysext/recycler/Resources/Private/Partials/RecordsTable/DeletedRecord.html @@ -43,22 +43,23 @@ </f:if> </div> <div class="btn-group"> - <a + <button class="btn btn-default" + type="button" data-action="expand" data-bs-toggle="collapse" data-bs-target="#{record.table}_{record.uid}" title="{f:translate(key: 'LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:button.expand')}" - role="button" > <core:icon identifier="actions-document-info" /> - </a> + </button> </div> </td> </tr> <tr class="collapse table-active" id="{record.table}_{record.uid}"> - <td colspan="7"> - <table class="table table-transparent table-borderless"> + <td></td> + <td colspan="6" class="p-0"> + <table class="table table-active table-hover"> <tbody> <tr> <th scope="row" class="col-recordtitle"><f:translate key="LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:table.header.crdate" /></th> diff --git a/typo3/sysext/scheduler/Resources/Private/Partials/MultiRecordSelectionActions.html b/typo3/sysext/scheduler/Resources/Private/Partials/MultiRecordSelectionActions.html index 501368501f36..22c642ffa8e9 100644 --- a/typo3/sysext/scheduler/Resources/Private/Partials/MultiRecordSelectionActions.html +++ b/typo3/sysext/scheduler/Resources/Private/Partials/MultiRecordSelectionActions.html @@ -5,10 +5,10 @@ > <div class="panel-heading-row t3js-multi-record-selection-actions hidden"> - <div class="panel-heading-title"> + <div class="panel-title"> <strong><f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.selection"/></strong> </div> - <div class="panel-heading-actions"> + <div class="panel-actions"> <button type="button" class="btn btn-default btn-sm" data-multi-record-selection-action="go_cron" data-multi-record-selection-action-config='{"idField": "taskId"}'> <span title="{f:translate(key: 'LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.cronjobSelected')}"> <core:icon identifier="actions-clock" /> <f:translate key="LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.cronjobSelected" /> diff --git a/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html b/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html index fb301c28ed66..b5c9720a1b14 100644 --- a/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html +++ b/typo3/sysext/scheduler/Resources/Private/Partials/TaskList.html @@ -111,11 +111,11 @@ <div class="panel-heading multi-record-selection-panel"> <div class="panel-heading-row"> <f:if condition="{group.hidden}"> - <div class="panel-heading-badge"> + <div class="panel-badge"> <span class="badge badge-secondary"><f:translate key="LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.group.isDisabled" /></span> </div> </f:if> - <div class="panel-heading-title"> + <div class="panel-title"> <f:if condition="!{group.uid}"> <f:then> {f:translate(key: 'LLL:EXT:scheduler/Resources/Private/Language/locallang.xlf:label.noGroup')} @@ -131,7 +131,7 @@ </f:else> </f:if> </div> - <div class="panel-heading-actions"> + <div class="panel-actions"> <form name="tx_scheduler_form_group_toggle_hidden" id="tx_scheduler_form_group_toggle_hidden" method="post"> <input name="action[group][uid]" type="hidden" value="{group.uid}"> <a diff --git a/typo3/sysext/styleguide/Classes/Controller/ComponentsController.php b/typo3/sysext/styleguide/Classes/Controller/ComponentsController.php index b281af908eb0..822495d04c00 100644 --- a/typo3/sysext/styleguide/Classes/Controller/ComponentsController.php +++ b/typo3/sysext/styleguide/Classes/Controller/ComponentsController.php @@ -44,7 +44,6 @@ final class ComponentsController */ private array $allowedActions = [ 'componentsOverview', - 'accordion', 'avatar', 'badges', 'buttons', @@ -57,6 +56,7 @@ final class ComponentsController 'modal', 'notifications', 'pagination', + 'panels', 'progressIndicators', 'progressTrackers', 'select', @@ -81,7 +81,6 @@ final class ComponentsController // Actions from components navigation return match ($queryAction) { - 'accordion' => $this->renderAccordionView($request), 'avatar' => $this->renderAvatarView($request), 'badges' => $this->renderBadgesView($request), 'buttons' => $this->renderButtonsView($request), @@ -94,6 +93,7 @@ final class ComponentsController 'modal' => $this->renderModalView($request), 'notifications' => $this->renderNotificationsView($request), 'pagination' => $this->renderPaginationView($request), + 'panels' => $this->renderPanelsView($request), 'progressIndicators' => $this->renderProgressIndicatorsView($request), 'progressTrackers' => $this->renderProgressTrackersView($request), 'select' => $this->renderSelectView($request), @@ -117,17 +117,6 @@ final class ComponentsController return $view->renderResponse('Backend/ComponentsOverview'); } - private function renderAccordionView(ServerRequestInterface $request): ResponseInterface - { - $view = $this->createModuleTemplate($request, 'accordion'); - $view->assignMultiple([ - 'actions' => $this->allowedActions, - 'currentAction' => 'accordion', - 'routeIdentifier' => 'styleguide_components', - ]); - return $view->renderResponse('Backend/Components/Accordion'); - } - private function renderAvatarView(ServerRequestInterface $request): ResponseInterface { $view = $this->createModuleTemplate($request, 'avatar'); @@ -329,6 +318,18 @@ final class ComponentsController return $view->renderResponse('Backend/Components/Pagination'); } + private function renderPanelsView(ServerRequestInterface $request): ResponseInterface + { + $view = $this->createModuleTemplate($request, 'panels'); + $view->assignMultiple([ + 'actions' => $this->allowedActions, + 'currentAction' => 'panels', + 'routeIdentifier' => 'styleguide_components', + 'variants' => ['primary', 'secondary', 'info', 'success', 'warning', 'danger', 'notice', 'default'], + ]); + return $view->renderResponse('Backend/Components/Panels'); + } + private function renderProgressIndicatorsView(ServerRequestInterface $request): ResponseInterface { $view = $this->createModuleTemplate($request, 'progressIndicators'); diff --git a/typo3/sysext/styleguide/Resources/Private/Language/locallang.xlf b/typo3/sysext/styleguide/Resources/Private/Language/locallang.xlf index 72e919e4001e..fd3704b87f62 100644 --- a/typo3/sysext/styleguide/Resources/Private/Language/locallang.xlf +++ b/typo3/sysext/styleguide/Resources/Private/Language/locallang.xlf @@ -94,6 +94,9 @@ <trans-unit id="action.pagination" resname="action.pagination"> <source>Pagination</source> </trans-unit> + <trans-unit id="action.panels" resname="action.panels"> + <source>Panels</source> + </trans-unit> <trans-unit id="action.progressIndicators" resname="action.progressIndicators"> <source>Progress indicators</source> </trans-unit> @@ -237,23 +240,6 @@ <source>If set, the backend user type (normal user or admin user) and its status (disabled or not) will be displayed next to the avatar. </source> </trans-unit> - <!-- Component: Accordion --> - <trans-unit id="component.accordion.headline" resname="component.accordion.headline"> - <source>Accordion</source> - </trans-unit> - <trans-unit id="component.accordion.section.default.headline" resname="component.accordion.section.default.headline"> - <source>Default</source> - </trans-unit> - <trans-unit id="component.accordion.section.default.text" resname="component.accordion.section.default.text"> - <source>By default, accordion elements are closed.</source> - </trans-unit> - <trans-unit id="component.accordion.section.firstPanelOpened.headline" resname="component.accordion.section.firstPanelOpened.headline"> - <source>Open an accordion element by default</source> - </trans-unit> - <trans-unit id="component.accordion.section.firstPanelOpened.text" resname="component.accordion.section.firstPanelOpened.text"> - <source><![CDATA[If necessary, you can specify that an accordion element should be open by default. To achieve this, add an additional class "show" to <code>.panel-collapse</code> and set "aria-expanded" of <code>.panel-title a</code> to "true".]]></source> - </trans-unit> - <!-- Component: Badge --> <trans-unit id="component.badge.headline" resname="component.badge.headline"> <source>Badges</source> @@ -519,6 +505,44 @@ <source>Default</source> </trans-unit> + <!-- Component: Panels --> + <trans-unit id="component.panels.headline" resname="component.panels.headline"> + <source>Panels</source> + </trans-unit> + <trans-unit id="component.panels.collapsible.headline" resname="component.panels.collapsible.headline"> + <source>Collapsible</source> + </trans-unit> + <trans-unit id="component.panels.nesting.headline" resname="component.panels.nesting.headline"> + <source>Nesting</source> + </trans-unit> + <trans-unit id="component.panels.variants.headline" resname="component.panels.variants.headline"> + <source>Variants</source> + </trans-unit> + <trans-unit id="component.panels.loader.headline" resname="component.panels.loader.headline"> + <source>Loader</source> + </trans-unit> + <trans-unit id="component.panels.size.headline" resname="component.panels.size.headline"> + <source>Size</source> + </trans-unit> + <trans-unit id="component.panels.progress.headline" resname="component.panels.progress.headline"> + <source>Progress</source> + </trans-unit> + <trans-unit id="component.panels.header.headline" resname="component.panels.header.headline"> + <source>Header</source> + </trans-unit> + <trans-unit id="component.panels.body.headline" resname="component.panels.body.headline"> + <source>Body</source> + </trans-unit> + <trans-unit id="component.panels.footer.headline" resname="component.panels.footer.headline"> + <source>Footer</source> + </trans-unit> + <trans-unit id="component.panels.list.headline" resname="component.panels.list.headline"> + <source>List</source> + </trans-unit> + <trans-unit id="component.panels.table.headline" resname="component.panels.table.headline"> + <source>Table</source> + </trans-unit> + <!-- Component: Progress indicator --> <trans-unit id="component.progressIndicator.headline" resname="component.progressIndicator.headline"> <source>Progress indicators</source> diff --git a/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Accordion.html b/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Accordion.html deleted file mode 100644 index 433dd1fecec6..000000000000 --- a/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Accordion.html +++ /dev/null @@ -1,116 +0,0 @@ -<html - xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" - xmlns:sg="http://typo3.org/ns/TYPO3/CMS/Styleguide/ViewHelpers" - data-namespace-typo3-fluid="true" -> - -<f:layout name="Module" /> - -<f:section name="Content"> - - <f:render - partial="Backend/Navigation" - arguments="{ - currentAction: currentAction, - actions: actions, - route: routeIdentifier - }" - /> - - <div class="styleguide-content"> - <h1><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.accordion.headline" /></h1> - - <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.accordion.section.default.headline" /></h2> - <p><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.accordion.section.default.text" /></p> - - <f:variable name="codeSnippetDefault"> - <f:render section="accordion" arguments="{identifier: 'simple-panel'}" /> - </f:variable> - <sg:example codePreview="true" codeLanguage="html" customCode="{codeSnippetDefault}"> - <f:render - section="accordion" - arguments="{ - identifier: 'simple-panel', - panelBodyValue: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores.' - }" - /> - </sg:example> - - <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.accordion.section.firstPanelOpened.headline" /></h2> - <p> - <f:sanitize.html><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.accordion.section.firstPanelOpened.text" /></f:sanitize.html> - </p> - <sg:example> - <f:render - section="accordion" - arguments="{ - identifier: 'first-opened-panel', - panelBodyValue: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores.', - firstPanelIsOpened: 1 - }" - /> - </sg:example> - - <hr> - - <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:section.frontend.headline" /></h2> - - <h3><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:section.colorScheme.headline" /></h3> - <sg:colorScheme> - <f:render - section="accordion" - arguments="{ - identifier: 'color-panel', - panelBodyValue: 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores.' - }" - /> - </sg:colorScheme> - </div> - -</f:section> - -<f:section name="accordion"> -<div class="panel-group" id="{identifier}" role="tablist"> - <f:render - section="accordionItem" - arguments="{ - identifier: identifier, - iterator: '1', - panelTitleValue: 'Panel element', - panelBodyValue: panelBodyValue, - firstPanelIsOpened: firstPanelIsOpened - }" - /> - <f:render - section="accordionItem" - arguments="{ - identifier: identifier, - iterator: '2', - panelTitleValue: 'Panel element', - panelBodyValue: panelBodyValue, - firstPanelIsOpened: firstPanelIsOpened - }" - /> -</div> -</f:section> - -<f:section name="accordionItem"> - <f:if condition="{firstPanelIsOpened} && ({iterator} == '1')"> - <f:variable name="isOpened" value="1" /> - </f:if> - <div class="panel panel-default"> - <div class="panel-heading" role="tab" id="{identifier}-{iterator}-heading"> - <h3 class="panel-title"> - <a href="#{identifier}-{iterator}" class="collapsed" role="button" data-bs-toggle="collapse" aria-expanded="{f:if(condition: isOpened, then: 'true', else: 'false')}" aria-controls="{identifier}-{iterator}"> - <span class="caret"></span> - <strong>{panelTitleValue} {iterator}</strong> - </a> - </h3> - </div> - <div id="{identifier}-{iterator}" class="panel-collapse collapse{f:if(condition: isOpened, then: ' show')}" role="tabpanel" data-bs-parent="#{identifier}" aria-labelledby="{identifier}-{iterator}-heading"> - <div class="panel-body">{f:if(condition: panelBodyValue, then: panelBodyValue, else: '...')}</div> - </div> - </div> -</f:section> - -</html> diff --git a/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Panels.html b/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Panels.html new file mode 100644 index 000000000000..04b851f2ad8f --- /dev/null +++ b/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Panels.html @@ -0,0 +1,423 @@ +<html + xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" + xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers" + xmlns:sg="http://typo3.org/ns/TYPO3/CMS/Styleguide/ViewHelpers" + data-namespace-typo3-fluid="true" +> + +<f:layout name="Module" /> + +<f:section name="Content"> + + <f:render + partial="Backend/Navigation" + arguments="{ + currentAction: currentAction, + actions: actions, + route: routeIdentifier + }" + /> + + <div class="styleguide-content"> + + <h1><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.headline" /></h1> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.collapsible.headline" /></h2> + <sg:colorScheme> + <div class="panel-group" id="panel-group-<UNIQUEID>"> + <f:for each="{0:1, 1:2, 2:3, 3:4}" as="element"> + <div class="panel panel-default"> + <h3 class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#panel-{element}-<UNIQUEID>" + aria-expanded="true" + > + <div class="panel-title">Label {element}</div> + <span class="caret"></span> + </button> + </div> + </h3> + <div class="panel-collapse collapse" id="panel-{element}-<UNIQUEID>" aria-expanded="true"> + <div class="panel-body"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + </div> + </f:for> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.header.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default"> + <h3 class="panel-heading">Simple</h3> + <div class="panel-body"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + <div class="panel panel-default"> + <h3 class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button class="panel-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapsible-panel-header-button-expanded-<UNIQUEID>" aria-expanded="false"> + <div class="panel-title">Collapsible</div> + <span class="caret"></span> + </button> + </div> + </h3> + <div class="panel-collapse collapse" id="collapsible-panel-header-button-expanded-<UNIQUEID>"> + <div class="panel-body"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + </div> + <div class="panel panel-default"> + <h3 class="panel-heading"> + <div class="panel-heading-row"> + <button class="panel-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapsible-panel-complex-<UNIQUEID>" aria-expanded="false"> + <span class="caret"></span> + <div class="panel-title"> + Complex Row + </div> + </button> + <div class="panel-badge"> + <span class="badge badge-danger">Error</span> + </div> + <div class="panel-actions"> + <button type="button" class="btn btn-default btn-sm"> + <core:icon identifier="actions-clock" /> + Button label + </button> + <button type="button" class="btn btn-default btn-sm"> + <core:icon identifier="actions-play" /> + Button Label + </button> + </div> + </div> + </h3> + <div class="panel-collapse collapse" id="collapsible-panel-complex-<UNIQUEID>" aria-expanded="false"> + <div class="panel-body"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.variants.headline" /></h2> + <sg:colorScheme> + <f:for each="{variants}" as="variant"> + <div class="panel panel-{variant}"> + <h3 class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#collapsible-panel-{variant}-<UNIQUEID>" + aria-expanded="false" + > + <div class="panel-title">Collapsible Panel [<code>.panel-{variant}</code>]</div> + <span class="caret"></span> + </button> + </div> + </h3> + <div class="panel-collapse collapse" id="collapsible-panel-{variant}-<UNIQUEID>" aria-expanded="true"> + <div class="panel-body"> + <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vitae eros congue, viverra ante vel, tempus lacus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p> + </div> + </div> + </div> + </f:for> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.loader.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default"> + <div class="panel-loader"> + <typo3-backend-spinner size="small"></typo3-backend-spinner> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.size.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default"> + <div class="panel-heading"> + <h2 class="panel-title">Panel normal</h2> + </div> + <div class="panel-body"> + <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vitae eros congue, viverra ante vel, tempus lacus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p> + </div> + </div> + <div class="panel panel-default panel-condensed"> + <div class="panel-heading"> + <h2 class="panel-title">Panel condensed</h2> + </div> + <div class="panel-body"> + <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vitae eros congue, viverra ante vel, tempus lacus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.progress.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default panel-has-progress"> + <div class="panel-progress"> + <div class="panel-progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0;"><span class="visually-hidden">0%</span></div> + </div> + <div class="panel-heading"> + <h2 class="panel-title">Panel Title</h2> + </div> + </div> + <div class="panel panel-default panel-has-progress"> + <div class="panel-progress"> + <div class="panel-progress-bar" role="progressbar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" style="width: 25%;"><span class="visually-hidden">25%</span></div> + </div> + <div class="panel-heading"> + <h2 class="panel-title">Panel Title</h2> + </div> + </div> + <div class="panel panel-default panel-has-progress"> + <div class="panel-progress"> + <div class="panel-progress-bar" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%;"><span class="visually-hidden">50%</span></div> + </div> + <div class="panel-heading"> + <h2 class="panel-title">Panel Title</h2> + </div> + </div> + <div class="panel panel-default panel-has-progress"> + <div class="panel-progress"> + <div class="panel-progress-bar" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 75%;"><span class="visually-hidden">75%</span></div> + </div> + <div class="panel-heading"> + <h2 class="panel-title">Panel Title</h2> + </div> + </div> + <div class="panel panel-default panel-has-progress"> + <div class="panel-progress"> + <div class="panel-progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%;"><span class="visually-hidden">100%</span></div> + </div> + <div class="panel-heading"> + <h2 class="panel-title">Panel Title</h2> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.body.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default"> + <div class="panel-body"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + <div class="panel panel-default"> + <div class="panel-body panel-body-overflow"> + <p style="white-space: nowrap;"> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.footer.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default"> + <div class="panel-body"> + <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam vitae eros congue, viverra ante vel, tempus lacus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p> + </div> + <div class="panel-footer"> + <span class="badge badge-success"> + Success + </span> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.list.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default"> + <div class="panel-body"> + <ul class="panel-list"> + <li>Item 1</li> + <li>Item 2</li> + <li>Item 3</li> + </ul> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.table.headline" /></h2> + <sg:colorScheme> + <div class="panel panel-default"> + <div class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button class="panel-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapsible-panel-table-<UNIQUEID>" aria-controls="collapsible-panel-table-<UNIQUEID>" aria-expanded="true"> + <div class="panel-title"> + Panel Header + </div> + <span class="caret"></span> + </button> + </div> + </div> + <div id="collapsible-panel-table-<UNIQUEID>" class="panel-collapse collapse show" data-persist-collapse-state="true" role="tabpanel"> + <div class="table-fit table-fit-wrap"> + <table class="table table-striped table-hover"> + <tbody> + <tr> + <th class="col-fieldname">Field 1</th> + <td class="col-word-break">Value 1</td> + </tr> + <tr> + <th class="col-fieldname">Field 2</th> + <td class="col-word-break">Value 2</td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + </sg:colorScheme> + + <h2><f:translate key="LLL:EXT:styleguide/Resources/Private/Language/locallang.xlf:component.panels.nesting.headline" /></h2> + <sg:colorScheme> + <div class="panel-group" id="panel-group-<UNIQUEID>"> + <f:for each="{0:1, 1:2, 2:3, 3:4}" as="element"> + <div class="panel panel-default"> + <h3 class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#panel-nesting-{element}-<UNIQUEID>" + aria-expanded="true" + > + <div class="panel-title">Parent {element}</div> + <span class="caret"></span> + </button> + </div> + </h3> + <div class="panel-collapse collapse" id="panel-nesting-{element}-<UNIQUEID>" aria-expanded="true"> + <div class="panel-body"> + <div class="panel panel-default"> + <h3 class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#panel-nesting-child-{element}-<UNIQUEID>" + aria-expanded="true" + > + <div class="panel-title">Child {element}</div> + <span class="caret"></span> + </button> + </div> + </h3> + <div class="panel-collapse collapse" id="panel-nesting-child-{element}-<UNIQUEID>" aria-expanded="true"> + <div class="panel-body"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + </div> + <div class="panel-group" id="panel-group-child-{element}-<UNIQUEID>"> + <f:for each="{0:1, 1:2, 2:3, 3:4}" as="element"> + <div class="panel panel-default"> + <h3 class="panel-heading" role="tab"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#panel-nesting-group-{element}-<UNIQUEID>" + aria-expanded="true" + > + <div class="panel-title">Child in Group {element}</div> + <span class="caret"></span> + </button> + </div> + </h3> + <div class="panel-collapse collapse" id="panel-nesting-group-{element}-<UNIQUEID>" aria-expanded="true"> + <div class="panel-body"> + <p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum + efficitur nulla in tristique. Nunc mattis, sapien accumsan finibus vestibulum, + turpis enim hendrerit urna, eu sodales felis lectus quis metus. Donec vel mi + scelerisque, euismod orci et, facilisis arcu. Phasellus elit lorem, tempor at + ipsum pharetra, iaculis euismod tortor. Donec sagittis tincidunt mattis. Donec + semper, odio quis pulvinar maximus, augue tortor lacinia leo, ac bibendum felis + risus vestibulum nulla. + </p> + </div> + </div> + </div> + </f:for> + </div> + + </div> + </div> + </div> + </f:for> + </div> + </sg:colorScheme> + + </div> + +</f:section> diff --git a/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Tab.html b/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Tab.html index b3b56666ab0f..3390f9c8c7da 100644 --- a/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Tab.html +++ b/typo3/sysext/styleguide/Resources/Private/Templates/Backend/Components/Tab.html @@ -123,7 +123,7 @@ <f:section name="tabItem"> <div role="tabpanel" class="tab-pane{f:if(condition: '{iterator} == 1', then: ' active')}" id="{identifier}-{iterator}"> - <div class="panel panel-tab"> + <div class="panel"> <div class="panel-body">{f:if(condition: panelBodyValue, then: panelBodyValue, else: '...')}</div> </div> </div> diff --git a/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveConditions.html b/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveConditions.html index 58350abd4985..8eb1ede3550f 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveConditions.html +++ b/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveConditions.html @@ -6,26 +6,21 @@ <f:if condition="{conditions}"> <div class="panel panel-default"> - <div class="panel-heading" role="tab"> - <f:if condition="{conditionActiveCount}"> - <f:then> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="typoscript-active-{type}-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#typoscript-active-{type}-conditions-body" - aria-expanded="false" - aria-controls="typoscript-active-{type}-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.conditions"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> + <h3 class="panel-heading" role="tab" id="typoscript-active-{type}-conditions-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#typoscript-active-{type}-conditions-body" + aria-controls="typoscript-active-{type}-conditions-body" + aria-expanded="false" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.conditions"/></strong> + </div> + <f:if condition="{conditionActiveCount}"> + <div class="panel-badge"> <span class="badge badge-info"> <f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_active.xlf:panel.info.conditionActiveCount.{f:if(condition: '{conditionActiveCount} > 1', then:'multiple', else: 'single')}" @@ -33,31 +28,17 @@ /> </span> </div> - </div> - </f:then> - <f:else> - <h3 class="panel-title" id="typoscript-active-{type}-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#typoscript-active-{type}-conditions-body" - aria-expanded="false" - aria-controls="typoscript-active-{type}-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.conditions"/></strong> - </a> - </h3> - </f:else> - </f:if> - </div> + </f:if> + <span class="caret"></span> + </button> + </div> + </h3> <div class="panel-collapse collapse" id="typoscript-active-{type}-conditions-body" - data-persist-collapse-state="true" - role="tabpanel" aria-labelledby="typoscript-active-{type}-conditions-heading" + role="tabpanel" + data-persist-collapse-state="true" > <div class="panel-body"> <form action="{f:be.uri(route: 'typoscript_active', parameters: '{id: pageUid}')}" method="post"> diff --git a/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTreePanel.html b/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTreePanel.html index 9bf7ad519189..aba78b0d75db 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTreePanel.html +++ b/typo3/sysext/tstemplate/Resources/Private/Partials/ActiveTreePanel.html @@ -4,36 +4,34 @@ > <div class="panel panel-default"> - <div class="panel-heading"> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="typoscript-active-{type}-ast-heading"> - <a - href="#" - class="collapsed" - id="panel-tree-heading-{type}" - data-bs-toggle="collapse" - data-bs-target="#typoscript-active-{type}-ast-body" - aria-expanded="false" - aria-controls="typoscript-active-{type}-ast-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_active.xlf:panel.header.configuration"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> - <span class="badge badge-success hidden t3js-collapse-states-search-numberOfSearchMatches"></span> - </div> + <h3 class="panel-heading" role="tab" id="typoscript-active-{type}-ast-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#typoscript-active-{type}-ast-body" + aria-controls="typoscript-active-{type}-ast-body" + aria-expanded="false" + id="panel-tree-heading-{type}" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_active.xlf:panel.header.configuration"/></strong> + </div> + <div class="panel-badge"> + <span class="badge badge-success hidden t3js-collapse-states-search-numberOfSearchMatches"></span> + </div> + <span class="caret"></span> + </button> </div> - </div> + </h3> <div - id="typoscript-active-{type}-ast-body" class="panel-collapse collapse" - data-persist-collapse-state="true" - data-persist-collapse-state-if-state="shown" + id="typoscript-active-{type}-ast-body" aria-labelledby="typoscript-active-{type}-ast-heading" role="tabpanel" + data-persist-collapse-state="true" + data-persist-collapse-state-if-state="shown" > <div class="panel-body t3js-collapse-states-search-tree"> <form action="{f:be.uri(route: 'typoscript_active', parameters: '{id: pageUid}')}" method="post"> diff --git a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerConditions.html b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerConditions.html index b2d86b9ea9fe..25ae09e3a2ad 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerConditions.html +++ b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerConditions.html @@ -6,26 +6,21 @@ <f:if condition="{conditions}"> <div class="panel panel-default"> - <div class="panel-heading" role="tab"> - <f:if condition="{conditionActiveCount}"> - <f:then> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="template-analyzer-{type}-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#template-analyzer-{type}-conditions-body" - aria-expanded="false" - aria-controls="template-analyzer-{type}-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.conditions"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> + <h3 class="panel-heading" role="tab" id="template-analyzer-{type}-conditions-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#template-analyzer-{type}-conditions-body" + aria-controls="template-analyzer-{type}-conditions-body" + aria-expanded="false" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.conditions"/></strong> + </div> + <f:if condition="{conditionActiveCount}"> + <div class="panel-badge"> <span class="badge badge-info"> <f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.info.conditionActiveCount.{f:if(condition: '{conditionActiveCount} > 1', then:'multiple', else: 'single')}" @@ -33,31 +28,17 @@ /> </span> </div> - </div> - </f:then> - <f:else> - <h3 class="panel-title" id="template-analyzer-{type}-conditions-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#template-analyzer-{type}-conditions-body" - aria-expanded="false" - aria-controls="template-analyzer-{type}-conditions-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.conditions"/></strong> - </a> - </h3> - </f:else> - </f:if> - </div> + </f:if> + <span class="caret"></span> + </button> + </div> + </h3> <div class="panel-collapse collapse" id="template-analyzer-{type}-conditions-body" - data-persist-collapse-state="true" - role="tabpanel" aria-labelledby="template-analyzer-{type}-conditions-heading" + role="tabpanel" + data-persist-collapse-state="true" > <div class="panel-body"> <form action="{f:be.uri(route: 'web_typoscript_analyzer', parameters: '{id: pageUid}')}" method="post"> diff --git a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerSyntaxErrors.html b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerSyntaxErrors.html index 53fd527e7956..e77fa4138446 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerSyntaxErrors.html +++ b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerSyntaxErrors.html @@ -6,34 +6,38 @@ <f:if condition="{errors}"> <div class="panel panel-default"> - <div class="panel-heading"> - <div class="row align-items-center justify-content-between"> - <div class="col align-middle"> - <h3 class="panel-title" id="template-analyzer-{type}-errors-heading"> - <a - href="#" - class="collapsed" - data-bs-toggle="collapse" - data-bs-target="#template-analyzer-{type}-errors-body" - aria-expanded="false" - aria-controls="template-analyzer-{type}-errors-body" - > - <span class="caret"></span> - <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.syntaxErrors"/></strong> - </a> - </h3> - </div> - <div class="col text-end"> - <span class="badge badge-warning"> - <f:translate - key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.info.syntaxErrorCount.{f:if(condition: '{errorCount} > 1', then:'multiple', else: 'single')}" - arguments="{0: errorCount}" - /> - </span> - </div> + <h3 class="panel-heading" role="tab" id="template-analyzer-{type}-errors-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#template-analyzer-{type}-errors-body" + aria-controls="template-analyzer-{type}-errors-body" + aria-expanded="false" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.syntaxErrors"/></strong> + </div> + <div class="panel-badge"> + <span class="badge badge-warning"> + <f:translate + key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.info.syntaxErrorCount.{f:if(condition: '{errorCount} > 1', then:'multiple', else: 'single')}" + arguments="{0: errorCount}" + /> + </span> + </div> + <span class="caret"></span> + </button> </div> - </div> - <div id="template-analyzer-{type}-errors-body" class="panel-collapse collapse" data-persist-collapse-state="true" aria-labelledby="template-analyzer-{type}-errors-heading"> + </h3> + <div + class="panel-collapse collapse" + id="template-analyzer-{type}-errors-body" + aria-labelledby="template-analyzer-{type}-errors-heading" + role="tabpanel" + data-persist-collapse-state="true" + > <div class="panel-body"> <f:for each="{errors}" as="error"> <div class="row justify-content-between"> diff --git a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTreePanel.html b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTreePanel.html index 7c99291dc96c..619b0f7a0106 100644 --- a/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTreePanel.html +++ b/typo3/sysext/tstemplate/Resources/Private/Partials/AnalyzerTreePanel.html @@ -4,15 +4,30 @@ > <div class="panel panel-default"> - <div class="panel-heading"> - <h3 class="panel-title" id="template-analyzer-{type}-tree-heading"> - <a href="#" class="collapsed" data-bs-toggle="collapse" data-bs-target="#template-analyzer-{type}-tree-body" aria-expanded="false" aria-controls="template-analyzer-{type}-tree-body"> + <h3 class="panel-heading" role="tab" id="template-analyzer-{type}-tree-heading"> + <div class="panel-heading-row"> + <button + class="panel-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#template-analyzer-{type}-tree-body" + aria-controls="template-analyzer-{type}-tree-body" + aria-expanded="false" + > + <div class="panel-title"> + <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.configuration"/></strong> + </div> <span class="caret"></span> - <strong><f:translate key="LLL:EXT:tstemplate/Resources/Private/Language/locallang_analyzer.xlf:panel.header.configuration"/></strong> - </a> - </h3> - </div> - <div id="template-analyzer-{type}-tree-body" class="panel-collapse collapse" data-persist-collapse-state="true" aria-labelledby="template-analyzer-{type}-tree-heading"> + </button> + </div> + </h3> + <div + class="panel-collapse collapse" + id="template-analyzer-{type}-tree-body" + data-persist-collapse-state="true" + role="tabpanel" + aria-labelledby="template-analyzer-{type}-tree-heading" + > <div class="panel-body panel-body-overflow"> <ul class="treelist"> <f:render -- GitLab