feat(search): add keyboard hint to search card

This commit is contained in:
alistair3149 2024-09-26 17:47:19 -04:00
parent 60e96f7f47
commit a213f1d6a0
No known key found for this signature in database
13 changed files with 127 additions and 4 deletions

View file

@ -13,6 +13,9 @@
"citizen-drawer-toggle": "Toggle menu",
"citizen-usermenu-toggle": "Toggle personal menu",
"citizen-search-toggle": "Toggle search",
"citizen-search-keyhint-exit": "Exit search",
"citizen-search-keyhint-open": "Open search",
"citizen-search-keyhint-select": "Select item",
"citizen-languages-toggle": "More languages",
"citizen-actions-more-toggle": "More actions",
"citizen-sitestats-articles-label": "articles",

View file

@ -18,6 +18,9 @@
"citizen-drawer-toggle": "Tooltip of drawer menu toggle",
"citizen-usermenu-toggle": "Tooltip of personal menu toggle",
"citizen-search-toggle": "Tooltip of search box toggle",
"citizen-search-keyhint-exit": "Keyboard hint for the key to exit search",
"citizen-search-keyhint-open": "Keyboard hint for the key to open search",
"citizen-search-keyhint-select": "Keyboard hint for the key to select item",
"citizen-languages-toggle": "Tooltip of languages menu toggle",
"citizen-actions-more-toggle": "Tooltip of more page actions menu toggle",
"citizen-sitestats-articles-label": "Label for the article statistics\n\n{{Identical|Article}}",

View file

@ -0,0 +1,34 @@
<?php
declare( strict_types=1 );
namespace MediaWiki\Skins\Citizen\Components;
/**
* CitizenComponentKeyboardHint component
*/
class CitizenComponentKeyboardHint implements CitizenComponent {
/** @var string */
private $label;
/** @var string */
private $key;
/**
* @param string $label
* @param string $key
*/
public function __construct( string $label = '', string $key = '' ) {
$this->label = $label;
$this->key = $key;
}
/**
* @inheritDoc
*/
public function getTemplateData(): array {
return [
'label' => $this->label,
'key' => $this->key,
];
}
}

View file

@ -4,12 +4,16 @@ declare( strict_types=1 );
namespace MediaWiki\Skins\Citizen\Components;
use MessageLocalizer;
use Skin;
/**
* CitizenComponentSearchBox component
*/
class CitizenComponentSearchBox implements CitizenComponent {
/** @var MessageLocalizer */
private $localizer;
/** @var array */
private $searchBoxData;
@ -17,16 +21,39 @@ class CitizenComponentSearchBox implements CitizenComponent {
private $skin;
/**
* @param MessageLocalizer $localizer
* @param array $searchBoxData
*/
public function __construct(
MessageLocalizer $localizer,
array $searchBoxData,
Skin $skin
) {
$this->localizer = $localizer;
$this->searchBoxData = $searchBoxData;
$this->skin = $skin;
}
/**
* Get the keyboard hint data
* @return array
*/
private function getKeyboardHintData() {
$data = [];
// There is probably a cleaner way to handle this
$map = [
'↑ ↓' => $this->localizer->msg( "citizen-search-keyhint-select" )->text(),
'/' => $this->localizer->msg( "citizen-search-keyhint-open" )->text(),
'Esc' => $this->localizer->msg( "citizen-search-keyhint-exit" )->text()
];
foreach ( $map as $key => $label ) {
$keyhint = new CitizenComponentKeyboardHint( $label, $key );
$data[] = $keyhint->getTemplateData();
}
return $data;
}
/**
* @inheritDoc
*/
@ -34,6 +61,8 @@ class CitizenComponentSearchBox implements CitizenComponent {
$searchBoxData = $this->searchBoxData;
return $searchBoxData += [
'array-keyboard-hint' => $this->getKeyboardHintData(),
'msg-citizen-search-footer' => $this->localizer->msg( "citizen-search-footer" )->text(),
'msg-citizen-search-toggle-shortcut' => '[/]',
'html-random-href' => $this->skin->makeSpecialUrl( 'Randompage' ),
];

View file

@ -116,6 +116,7 @@ class SkinCitizen extends SkinMustache {
$user
),
'data-search-box' => new CitizenComponentSearchBox(
$localizer,
$parentData['data-search-box'],
$this
),

View file

@ -2,7 +2,10 @@
@import '../mixins.less';
.citizen-typeahead {
margin: 0; // Reset <ol> styles
display: flex;
flex-direction: column;
gap: var( --space-xs );
margin: var( --space-xs ) 0;
list-style: none;
border-bottom-right-radius: var( --border-radius-medium );
border-bottom-left-radius: var( --border-radius-medium );
@ -53,8 +56,6 @@
gap: var( --space-xxs );
padding-right: var( --space-sm );
padding-left: var( --space-sm );
margin-top: var( --space-xs );
margin-bottom: var( --space-xs );
overflow-x: auto;
}
}

View file

@ -316,7 +316,7 @@ const typeahead = {
'msg-citizen-search-empty-desc': mw.message( 'citizen-search-empty-desc' ).text()
};
this.element = template.render( data ).get()[ 1 ];
formEl.parentElement.appendChild( this.element );
formEl.after( this.element );
this.form.init( formEl );
this.input.init( inputEl );

View file

@ -0,0 +1,19 @@
.citizen-keyboard-hint {
display: none;
gap: var( --space-xs );
font-size: var( --font-size-x-small );
line-height: 1;
/* Should have a keyboard */
@media ( hover: hover ) and ( pointer: fine ) {
display: flex;
}
&-label {
color: var( --color-base );
}
&-key {
color: var( --color-subtle );
}
}

View file

@ -95,6 +95,7 @@
z-index: @z-index-stacking-1;
display: flex;
height: 100%;
overflow: hidden;
font-size: var( --font-size-small );
background-color: inherit;
@ -137,6 +138,26 @@
-webkit-appearance: none;
}
}
&__footer {
display: flex;
gap: var( --space-lg );
align-items: center;
justify-content: space-between;
min-height: 2.5rem;
padding: 0 var( --space-md );
overflow: hidden;
font-size: var( --font-size-x-small );
white-space: nowrap;
border-top: 1px solid var( --border-color-base );
&-start,
&-end {
display: flex;
gap: var( --space-md );
align-items: center;
}
}
}
@media ( max-width: @max-width-breakpoint-tablet ) {

View file

@ -46,6 +46,7 @@
@import 'components/OverflowElements.less';
@import 'components/UserInfo.less';
@import 'components/Wordmark.less';
@import 'components/KeyboardHint.less';
// Mediawiki.skinning
// This get loaded regardless so we don't have to use skinStyles to target them

View file

@ -0,0 +1,4 @@
<div class="citizen-keyboard-hint">
<div class="citizen-keyboard-hint-label">{{label}}</div>
<div class="citizen-keyboard-hint-key">{{key}}</div>
</div>

View file

@ -26,5 +26,6 @@
<span class="screen-reader-text">{{msg-random}}</span>
</a>
</form>
{{>SearchFooter}}
</div>
</div>

View file

@ -0,0 +1,6 @@
<div class="citizen-search__footer">
<div class="citizen-search__footer-start"></div>
<div class="citizen-search__footer-end">
{{#array-keyboard-hint}}{{>KeyboardHint}}{{/array-keyboard-hint}}
</div>
</div>