mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-12 09:21:11 +00:00
Merge "[storybook] Document button usage and update broken stories"
This commit is contained in:
commit
084aec1e38
|
@ -18,6 +18,22 @@
|
|||
url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2220%22 height=%2220%22 viewBox=%220 0 20 20%22%3E%3Ctitle%3Etray%3C/title%3E%3Cpath d=%22M3 1a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm14 12h-4l-1 2H8l-1-2H3V3h14z%22/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.mw-ui-icon-add:before {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Ctitle%3Elanguage%3C/title%3E%3Cg fill='%2354595d'%3E%3Cpath d='M11 9V4H9v5H4v2h5v5h2v-5h5V9z'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.mw-ui-icon-add-invert:before {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Ctitle%3Elanguage%3C/title%3E%3Cg fill='white'%3E%3Cpath d='M11 9V4H9v5H4v2h5v5h2v-5h5V9z'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.mw-ui-icon-add-progressive:before {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Ctitle%3Elanguage%3C/title%3E%3Cg fill='%23447ff5'%3E%3Cpath d='M11 9V4H9v5H4v2h5v5h2v-5h5V9z'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.mw-ui-icon-add-destructive:before {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Ctitle%3Elanguage%3C/title%3E%3Cg fill='%23ff4242'%3E%3Cpath d='M11 9V4H9v5H4v2h5v5h2v-5h5V9z'/%3E%3C/g%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.uls-trigger {
|
||||
background-image: linear-gradient(transparent,transparent),
|
||||
url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2220%22 height=%2220%22 viewBox=%220 0 20 20%22%3E %3Ctitle%3E language %3C/title%3E %3Cpath d=%22M20 18h-1.44a.61.61 0 0 1-.4-.12.81.81 0 0 1-.23-.31L17 15h-5l-1 2.54a.77.77 0 0 1-.22.3.59.59 0 0 1-.4.14H9l4.55-11.47h1.89zm-3.53-4.31L14.89 9.5a11.62 11.62 0 0 1-.39-1.24q-.09.37-.19.69l-.19.56-1.58 4.19zm-6.3-1.58a13.43 13.43 0 0 1-2.91-1.41 11.46 11.46 0 0 0 2.81-5.37H12V4H7.31a4 4 0 0 0-.2-.56C6.87 2.79 6.6 2 6.6 2l-1.47.5s.4.89.6 1.5H0v1.33h2.15A11.23 11.23 0 0 0 5 10.7a17.19 17.19 0 0 1-5 2.1q.56.82.87 1.38a23.28 23.28 0 0 0 5.22-2.51 15.64 15.64 0 0 0 3.56 1.77zM3.63 5.33h4.91a8.11 8.11 0 0 1-2.45 4.45 9.11 9.11 0 0 1-2.46-4.45z%22/%3E %3C/svg%3E") !important;
|
||||
|
|
|
@ -227,7 +227,7 @@ class Hooks {
|
|||
* @param string $name
|
||||
* @return string of HTML
|
||||
*/
|
||||
public static function makeButtonIcon( $name ) {
|
||||
public static function makeIcon( $name ) {
|
||||
// Html::makeLink will pass this through rawElement
|
||||
return '<span class="mw-ui-icon mw-ui-icon-' . $name . '"></span>';
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ class Hooks {
|
|||
if ( $hideText ) {
|
||||
$item['link-class'][] = 'mw-ui-icon mw-ui-icon-element mw-ui-icon-' . $icon;
|
||||
} else {
|
||||
$item['link-html'] = self::makeButtonIcon( $icon );
|
||||
$item['link-html'] = self::makeIcon( $icon );
|
||||
}
|
||||
}
|
||||
$content_navigation[$menu][$key] = $item;
|
||||
|
|
|
@ -516,7 +516,7 @@ class SkinVector extends SkinMustache {
|
|||
'label' => $label,
|
||||
// ext.uls.interface attaches click handler to this selector.
|
||||
'checkbox-class' => ' mw-interlanguage-selector ',
|
||||
'html-vector-heading-icon' => Hooks::makeButtonIcon( 'wikimedia-language' ),
|
||||
'html-vector-heading-icon' => Hooks::makeIcon( 'wikimedia-language' ),
|
||||
'heading-class' =>
|
||||
' vector-menu-heading ' .
|
||||
' mw-ui-button mw-ui-quiet'
|
||||
|
|
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -2329,6 +2329,12 @@
|
|||
"integrity": "sha512-H2MbvBt7DTROqm6kCRNdK6nUZuBvSYjq/7k01ZI5/uR9mj8FzxsMQcH4joh8kFVQ2LpDPXNsaPq/P5hqIDtSAw==",
|
||||
"dev": true
|
||||
},
|
||||
"@wikimedia/wvui": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/wvui/-/wvui-0.3.0.tgz",
|
||||
"integrity": "sha512-RiVvKReEn7KtvPzYghLr+e5FOYh71BWzaT1/uG/A2d8D6QM+0U5arF0MKJnB6drNvkQZPM/YcWu/IbV3zItcOA==",
|
||||
"dev": true
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"@types/mustache": "4.0.1",
|
||||
"@types/node-fetch": "2.5.7",
|
||||
"@wikimedia/types-wikimedia": "0.2.0",
|
||||
"@wikimedia/wvui": "0.3.0",
|
||||
"babel-loader": "8.0.6",
|
||||
"bundlesize": "0.18.1",
|
||||
"eslint-config-wikimedia": "0.20.0",
|
||||
|
|
145
stories/ButtonsAndIcons.stories.js
Normal file
145
stories/ButtonsAndIcons.stories.js
Normal file
|
@ -0,0 +1,145 @@
|
|||
import wvui from '@wikimedia/wvui';
|
||||
import Vue from 'vue';
|
||||
import '@wikimedia/wvui/dist/wvui.css';
|
||||
const wvuiIconAdd = 'M11 9V4H9v5H4v2h5v5h2v-5h5V9z';
|
||||
|
||||
export default {
|
||||
title: 'Icon and Buttons'
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @typedef {Object} ButtonProps
|
||||
* @property {string} type
|
||||
* @property {string} action
|
||||
*/
|
||||
/**
|
||||
* @param {ButtonProps} props
|
||||
* @param {string} text
|
||||
* @return {string}
|
||||
*/
|
||||
function makeButtonLegacy( props, text ) {
|
||||
let typeClass = '';
|
||||
let iconClass = 'mw-ui-icon-add';
|
||||
switch ( props.type ) {
|
||||
case 'quiet':
|
||||
typeClass += ' mw-ui-quiet';
|
||||
break;
|
||||
}
|
||||
switch ( props.action ) {
|
||||
case 'progressive':
|
||||
typeClass += ' mw-ui-progressive';
|
||||
iconClass += '-progressive';
|
||||
break;
|
||||
case 'destructive':
|
||||
typeClass += ' mw-ui-destructive';
|
||||
iconClass += '-destructive';
|
||||
break;
|
||||
}
|
||||
if ( props.type === 'primary' ) {
|
||||
iconClass = 'mw-ui-icon-add-invert';
|
||||
}
|
||||
return `<button class="mw-ui-button ${typeClass}">
|
||||
<span class="mw-ui-icon ${iconClass}"
|
||||
></span>${text}
|
||||
</button>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ButtonProps} props
|
||||
* @param {string} text
|
||||
* @param {string} icon
|
||||
* @return {string}
|
||||
*/
|
||||
function makeButton( props, text, icon ) {
|
||||
const el = document.createElement( 'div' );
|
||||
const vm = new Vue( {
|
||||
el,
|
||||
render: function ( createElement ) {
|
||||
return createElement( wvui.WvuiButton, {
|
||||
props
|
||||
}, [
|
||||
createElement( wvui.WvuiIcon, {
|
||||
props: {
|
||||
icon
|
||||
}
|
||||
} ),
|
||||
text
|
||||
] );
|
||||
}
|
||||
} );
|
||||
return `
|
||||
<tr>
|
||||
<td>${makeButtonLegacy( props, text )}</td>
|
||||
<td>${vm.$el.outerHTML}</td>
|
||||
</tr>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
function makeIcon() {
|
||||
return `
|
||||
<tr>
|
||||
<td>
|
||||
<button class="mw-ui-icon mw-ui-icon-element mw-ui-icon-add
|
||||
mw-ui-button">Normal Icon</button>
|
||||
</td>
|
||||
<td>N/A</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button class="mw-ui-icon mw-ui-icon-element mw-ui-icon-add
|
||||
mw-ui-button mw-ui-quiet">Quiet Icon</button>
|
||||
</td>
|
||||
<td>N/A</td>
|
||||
</tr>`;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string[]} btns
|
||||
* @return {string}
|
||||
*/
|
||||
function makeButtons( btns ) {
|
||||
return `<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Legacy</th>
|
||||
<th>WVUI</th>
|
||||
</tr>
|
||||
${btns.join( '\n' )}
|
||||
</tbody>
|
||||
</table>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
export const Button = () => makeButtons( [
|
||||
makeButton( {
|
||||
action: 'default',
|
||||
type: 'quiet'
|
||||
}, 'Quiet button', wvuiIconAdd ),
|
||||
makeButton( {
|
||||
action: 'progressive',
|
||||
type: 'quiet'
|
||||
}, 'Quiet progressive', wvuiIconAdd ),
|
||||
makeButton( {
|
||||
action: 'destructive',
|
||||
type: 'quiet'
|
||||
}, 'Quiet destructive', wvuiIconAdd ),
|
||||
makeButton( {
|
||||
action: 'default',
|
||||
type: 'normal'
|
||||
}, 'Normal', wvuiIconAdd ),
|
||||
makeButton( {
|
||||
type: 'primary',
|
||||
action: 'progressive'
|
||||
}, 'Progressive primary', wvuiIconAdd ),
|
||||
makeButton( {
|
||||
type: 'primary',
|
||||
action: 'destructive'
|
||||
}, 'Destructive primary', wvuiIconAdd ),
|
||||
makeIcon()
|
||||
] );
|
|
@ -1,7 +1,8 @@
|
|||
/**
|
||||
* @external MenuDefinition
|
||||
*/
|
||||
import { placeholder, htmlUserLanguageAttributes, portletAfter } from './utils';
|
||||
import { placeholder, htmlUserLanguageAttributes,
|
||||
makeIcon, portletAfter } from './utils';
|
||||
|
||||
/**
|
||||
* @type {MenuDefinition}
|
||||
|
@ -12,8 +13,9 @@ export const languageData = {
|
|||
class: 'mw-portlet-lang vector-menu-dropdown',
|
||||
// mw-interlanguage-selector must be present to operate in ULS mode.
|
||||
// icon classes and button classes
|
||||
'heading-class': 'vector-menu-heading mw-interlanguage-selector ' +
|
||||
'mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-language ' +
|
||||
'checkbox-class': 'mw-interlanguage-selector',
|
||||
'html-vector-heading-icon': makeIcon( 'wikimedia-language' ),
|
||||
'heading-class': 'vector-menu-heading ' +
|
||||
'mw-ui-button mw-ui-quiet',
|
||||
'html-tooltip': 'A message tooltip-p-lang must exist for this to appear',
|
||||
label: '10 languages',
|
||||
|
|
|
@ -7,38 +7,4 @@ export default {
|
|||
title: 'LanguageButton'
|
||||
};
|
||||
|
||||
// mw-page-container is needed to enable the 20x20 icon
|
||||
// mw-body-header can be removed when VectorLanguageInHeader is true and
|
||||
// old language inside portal in modern Vector is no longer supported.
|
||||
const CONTAINER_CLASS_MODERN_VECTOR = 'mw-body-header mw-page-container';
|
||||
|
||||
/**
|
||||
* It allows us to support old and new renderings.
|
||||
*
|
||||
* @param {string|HTMLElement} htmlOrElement
|
||||
* @param {string} className of containing element
|
||||
* @return {HTMLElement}
|
||||
*/
|
||||
const wrapLanguageButton = ( htmlOrElement, className ) => {
|
||||
const node = document.createElement( 'div' );
|
||||
node.setAttribute( 'class', className );
|
||||
if ( typeof htmlOrElement === 'string' ) {
|
||||
node.innerHTML = htmlOrElement;
|
||||
} else {
|
||||
node.appendChild( htmlOrElement );
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
export const languageButton = () => mustache.render( vectorMenuTemplate, languageData );
|
||||
|
||||
export const languageButtonWhenULSEnabled = () => wrapLanguageButton(
|
||||
wrapLanguageButton(
|
||||
wrapLanguageButton(
|
||||
mustache.render( vectorMenuTemplate, languageData ),
|
||||
'vector-menu-hide-dropdown'
|
||||
),
|
||||
CONTAINER_CLASS_MODERN_VECTOR
|
||||
),
|
||||
'client-js'
|
||||
);
|
||||
|
|
|
@ -12,7 +12,7 @@ export { vectorMenuTemplate };
|
|||
*/
|
||||
export const moreData = {
|
||||
'is-dropdown': true,
|
||||
class: 'vector-menu-dropdown',
|
||||
class: 'vector-menu-dropdown vector-menu-dropdown-noicon',
|
||||
label: 'More',
|
||||
id: 'p-cactions',
|
||||
'html-user-language-attributes': htmlUserLanguageAttributes,
|
||||
|
@ -35,7 +35,7 @@ export const moreData = {
|
|||
*/
|
||||
export const variantsData = {
|
||||
'is-dropdown': true,
|
||||
class: 'vector-menu-dropdown',
|
||||
class: 'vector-menu-dropdown vector-menu-dropdown-noicon',
|
||||
label: '新加坡简体',
|
||||
id: 'p-variants',
|
||||
'html-user-language-attributes': htmlUserLanguageAttributes,
|
||||
|
|
|
@ -83,6 +83,7 @@ const additionalUserMoreData = {
|
|||
|
||||
const userMoreHtmlItems = ( isAnon = true ) => mustache.render( userLinksMoreTemplate, {
|
||||
'is-anon': isAnon,
|
||||
'is-create-account-allowed': isAnon,
|
||||
'html-create-account': `<a href="/w/index.php?title=Special:CreateAccount&returnto=Main+Page" class="mw-ui-button mw-ui-quiet" title="You are encouraged to create an account and log in; however, it is not mandatory">Create account</a>`,
|
||||
'data-user-page': helperMakeMenuData( 'user-page', `
|
||||
<li id="pt-userpage-2" class="user-links-collapsible-item">
|
||||
|
@ -95,7 +96,7 @@ const userMoreHtmlItems = ( isAnon = true ) => mustache.render( userLinksMoreTem
|
|||
const loggedInData = {
|
||||
class: 'vector-user-menu vector-menu-dropdown vector-user-menu-logged-in',
|
||||
'is-dropdown': true,
|
||||
'heading-class': 'mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-userAvatar',
|
||||
'heading-class': 'mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-userAvatar',
|
||||
'is-anon': false,
|
||||
'html-after-portal': mustache.render( userLinksLogoutTemplate, {
|
||||
htmlLogout: `<a class="vector-menu-content-item vector-menu-content-item-logout mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-logOut" data-mw="interface" href="/w/index.php?title=Special:UserLogout&returnto=Main+Page"><span>Log out</span></a>`
|
||||
|
@ -105,7 +106,7 @@ const loggedInData = {
|
|||
const loggedOutData = {
|
||||
class: 'vector-user-menu vector-menu-dropdown vector-user-menu-logged-out',
|
||||
'is-dropdown': true,
|
||||
'heading-class': 'mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-ellipsis',
|
||||
'heading-class': 'mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-ellipsis',
|
||||
'is-anon': true,
|
||||
'html-before-portal': mustache.render( userLinksLoginTemplate, {
|
||||
htmlCreateAccount: `<a href="/w/index.php?title=Special:CreateAccount&returnto=Special%3AUserLogout" icon="userAvatar" class="user-links-collapsible-item vector-menu-content-item mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-userAvatar" title="You are encouraged to create an account and log in; however, it is not mandatory"><span>Create account</span></a>`,
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
* @property {string} id
|
||||
* @property {string} label
|
||||
* @property {string} html-items
|
||||
* @property {string} [checkbox-class]
|
||||
* @property {string} [html-vector-heading-icon]
|
||||
* @property {string} [heading-class]
|
||||
* @property {string} [html-tooltip]
|
||||
* @property {string} [class] of menu
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
* @external MenuDefinition
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @return {string}
|
||||
*/
|
||||
function makeIcon( name ) {
|
||||
return `<span class="mw-ui-icon mw-ui-icon-${name}"></span>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} msg
|
||||
* @param {number} [height=200]
|
||||
|
@ -64,6 +72,7 @@ function helperMakeMenuData( name, htmlItems, additionalData = {} ) {
|
|||
}
|
||||
|
||||
export {
|
||||
makeIcon,
|
||||
placeholder,
|
||||
htmlUserLanguageAttributes,
|
||||
portletAfter,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"noImplicitReturns": true,
|
||||
"newLine": "lf",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true,
|
||||
"pretty": true,
|
||||
"target": "es5",
|
||||
"lib": [ "dom" ],
|
||||
|
|
Loading…
Reference in a new issue