From 97eab7f35b0801cda02c96f65bdb87313ebd43ac Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bartosz=20Dziewo=C5=84ski?= Date: Wed, 29 May 2019 00:22:18 +0200 Subject: [PATCH] Improve collapsible HTMLForm styling (and accessibility, slightly) Previously the form was only collapsible/expandable using the small link-button on the far right. Now you can click on the entire header to do it, and it has an appropriate pretty icon. We add appropriate ARIA `role` and textual labels. Together with recently added `toggleARIA` option of jquery.makeCollapsible in Ic457bda58e56f we feature a screen reader workable output. Bug: T222904 Change-Id: I6964296bc6870550478de662d21f12a1fc084c15 --- autoload.php | 1 + .../htmlform/CollapsibleFieldsetLayout.php | 29 ++++++++++++ includes/htmlform/OOUIHTMLForm.php | 13 ++---- .../jquery/jquery.makeCollapsible.styles.less | 6 --- .../src/mediawiki.htmlform.ooui.styles.less | 46 ++++++++++++++++++- 5 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 includes/htmlform/CollapsibleFieldsetLayout.php diff --git a/autoload.php b/autoload.php index 7ff29ce803..55e5a7f089 100644 --- a/autoload.php +++ b/autoload.php @@ -285,6 +285,7 @@ $wgAutoloadLocalClasses = [ 'CloneDatabase' => __DIR__ . '/includes/db/CloneDatabase.php', 'CodeCleanerGlobalsPass' => __DIR__ . '/maintenance/CodeCleanerGlobalsPass.inc', 'CodeContentHandler' => __DIR__ . '/includes/content/CodeContentHandler.php', + 'CollapsibleFieldsetLayout' => __DIR__ . '/includes/htmlform/CollapsibleFieldsetLayout.php', 'Collation' => __DIR__ . '/includes/collation/Collation.php', 'CollationCkb' => __DIR__ . '/includes/collation/CollationCkb.php', 'CommandLineInc' => __DIR__ . '/maintenance/commandLine.inc', diff --git a/includes/htmlform/CollapsibleFieldsetLayout.php b/includes/htmlform/CollapsibleFieldsetLayout.php new file mode 100644 index 0000000000..804f1b9bdb --- /dev/null +++ b/includes/htmlform/CollapsibleFieldsetLayout.php @@ -0,0 +1,29 @@ +addClasses( [ 'mw-collapsible' ] ); + if ( isset( $config[ 'collapsed' ] ) && $config[ 'collapsed' ] ) { + $this->addClasses( [ 'mw-collapsed' ] ); + } + $this->header->addClasses( [ 'mw-collapsible-toggle' ] ); + $this->group->addClasses( [ 'mw-collapsible-content' ] ); + + $this->header->appendContent( + new OOUI\IconWidget( [ + 'icon' => 'expand', + 'label' => wfMessage( 'collapsible-expand' )->text(), + ] ), + new OOUI\IconWidget( [ + 'icon' => 'collapse', + 'label' => wfMessage( 'collapsible-collapse' )->text(), + ] ) + ); + + $this->header->setAttributes( [ + 'role' => 'button', + ] ); + } +} diff --git a/includes/htmlform/OOUIHTMLForm.php b/includes/htmlform/OOUIHTMLForm.php index baafa5e721..94ba75eb0f 100644 --- a/includes/htmlform/OOUIHTMLForm.php +++ b/includes/htmlform/OOUIHTMLForm.php @@ -281,17 +281,10 @@ class OOUIHTMLForm extends HTMLForm { public function wrapForm( $html ) { if ( is_string( $this->mWrapperLegend ) ) { - $classes = $this->mCollapsible ? [ 'mw-collapsible' ] : []; - if ( $this->mCollapsed ) { - $classes[] = 'mw-collapsed'; - } - $content = new OOUI\FieldsetLayout( [ + $phpClass = $this->mCollapsible ? CollapsibleFieldsetLayout::class : OOUI\FieldsetLayout::class; + $content = new $phpClass( [ 'label' => $this->mWrapperLegend, - 'classes' => $classes, - 'group' => new OOUI\StackLayout( [ - 'expanded' => false, - 'classes' => [ 'mw-collapsible-content' ], - ] ), + 'collapsed' => $this->mCollapsed, 'items' => [ new OOUI\Widget( [ 'content' => new OOUI\HtmlSnippet( $html ) diff --git a/resources/src/jquery/jquery.makeCollapsible.styles.less b/resources/src/jquery/jquery.makeCollapsible.styles.less index ac896160a5..23e86f7c78 100644 --- a/resources/src/jquery/jquery.makeCollapsible.styles.less +++ b/resources/src/jquery/jquery.makeCollapsible.styles.less @@ -125,12 +125,6 @@ li, } } -fieldset.mw-collapsible .mw-collapsible-toggle { - position: absolute; - right: 0; - z-index: 1; -} - // special treatment for list items to match above // !important necessary to override overly-specific float left and right above. ol.mw-collapsible:not( @{exclude} ):before, diff --git a/resources/src/mediawiki.htmlform.ooui.styles.less b/resources/src/mediawiki.htmlform.ooui.styles.less index 470d826446..e345d412fa 100644 --- a/resources/src/mediawiki.htmlform.ooui.styles.less +++ b/resources/src/mediawiki.htmlform.ooui.styles.less @@ -6,6 +6,7 @@ @ooui-font-size-browser: 16; // assumed browser default of `16px` @ooui-font-size-base: 0.875em; // equals `14px` at browser default of `16px` +@ooui-spacing-small: 8 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.57142857em`≈`8px` @ooui-spacing-medium: 12 / @ooui-font-size-browser / @ooui-font-size-base; // equals `0.8571429em`≈`12px` @ooui-spacing-large: 16 / @ooui-font-size-browser / @ooui-font-size-base; // equals `1.1428571em`≈`16px` @ooui-padding-horizontal: 12 / @ooui-font-size-browser / @ooui-font-size-base; @@ -15,10 +16,21 @@ // Reducing `padding-top`, as the heading's `line-height` provides similar distance. padding: @ooui-spacing-medium @ooui-spacing-large @ooui-spacing-large; + .client-js & .oo-ui-fieldsetLayout.mw-collapsible .oo-ui-fieldsetLayout-header { + // Push legend up when JS is on, to increase clickable area. + margin-top: -@ooui-spacing-small; + margin-bottom: @ooui-spacing-small; + // Add `padding-top` to make up for negative `margin` above. + padding: @ooui-spacing-small; + // Make space for toggle icon defined below. + padding-left: 24 / @ooui-font-size-browser / @ooui-font-size-base; + } + // Trigger only when collapsible & JS is available via `.mw-collapsed`. .client-js & .oo-ui-fieldsetLayout.mw-collapsed .oo-ui-fieldsetLayout-header { + min-height: 30px; // Negative margin to match the reduced distance on the top caused by the previous rule. - margin-bottom: -( @ooui-spacing-large - @ooui-spacing-medium ); + margin-bottom: -@ooui-spacing-medium; .oo-ui-labelElement-label { margin-bottom: 0; @@ -113,3 +125,35 @@ .mw-htmlform-ooui .mw-htmlform-submit-buttons { margin-top: @ooui-spacing-medium; } + +.oo-ui-fieldsetLayout.mw-collapsible { + .oo-ui-fieldsetLayout-header { + max-width: none; + } + + .mw-collapsible-toggle .oo-ui-iconElement-icon { + position: absolute; + top: 0; + left: 0; + // Special case: Reduce to `16px` icon size here. + min-width: 16px; + width: 16 / @ooui-font-size-browser / @ooui-font-size-base; + margin-right: 0.5em; + } + + // When expanded: only 'collapse' icon visible + .mw-collapsible-toggle .oo-ui-icon-expand { + display: none; + } + + // When collapsed: only 'expand' icon visible + &.mw-collapsed { + .mw-collapsible-toggle .oo-ui-icon-expand { + display: inline-block; + } + + .mw-collapsible-toggle .oo-ui-icon-collapse { + display: none; + } + } +} -- 2.20.1