Hey everyone,
We have developed a modal component for Flow, based on the design spec for
MediaWiki-UI modals/dialogs. Thus, we have named it *mw.Modal*.
A very basic and feature-incomplete version of this modal can be seen at:
http://en.wikipedia.beta.wmflabs.org/wiki/Talk:Flow (hover over ellipsis
icon in topic, click "hide")
This modal implements the design outlined here
<https://trello.com/c/OLnPx7M4/331-g-11-spike-build-modal-dialog-box-for-hid…>,
but automates a lot of the visual aspects of it based on the input you give
it.
Below is an almost-verbatim copy of the original email I sent to another
mailing list, (discussion seen here:
https://lists.wikimedia.org/mailman/private/e2/2014-September/002494.html
), detailing the general concepts and use:
*First, an example using event binding:*
> // Instantiate mw.Modal
> *var* modal = new mw.*Modal*();
> // Open up a modal with HTML
> modal.*open*( "<button>Bye!</button>" );
> // Bubble click to wrapper, use it to close the parent modal of the target
> $( modal.*getContentNode*() ).*bind*( 'click', 'button', function () {
> mw.Modal.*close*( this ); } );
*Visuals (markup and CSS):*
As it stands, you can see the current designs for modals here
<https://trello.com/c/OLnPx7M4/331-g-11-spike-build-modal-dialog-box-for-hid…>,
with a screenshot of a Flow use case. This is being done with some very
simple markup:
flow-ui-modal
flow-ui-modal-layout
flow-ui-modal-heading* (optional)*
content + quick navigators* (automatic)*
flow-ui-modal-content
content
The CSS for this works back to IE6. It automatically centers on the
viewport, and scales up to max the viewport width/height, at which point
the modal would start showing scrollbar(s). No JS is needed for any of this.
*Automatic enhancement:*
- Shows title at top if it exists.
- Shows X on left of title to close if title exists.
- Shows ✓ form submission shortcut if title exists, and form with a
single primary button exists in content.
Caveat: This does not support off-center placement of modals (eg. placing a
modal by a specific element). For those use cases, I imagine *mw-ui-tooltip*
would be the solution, and it was written with that in mind.
*Use (JavaScript):*
A constructor would be called (modal = new mw.Modal( [ String name, ] [
Object settings ] )), which would give you access to control the flow of
your modal.
name may be omitted, but is simply there so you can easily determine which
modal is currently active with mw.Modal.getModal.
settings can have the following keys: open (same as modal.open), and title.
1. modal.*open*( [ Array|Object|Element|jQuery|String contents ] ) - You
can visually render the modal using this method. Accepts Element/jQuery, or
HTML String. Returns mw.Modal instance.
- Multi-step modals with an Array. You can pass [ Element, Element ]
to have two steps.
- Multi-step modals with an Object to have *named step keys*. Pass {
*steps*: [ 'first', 'second', 'foobar' ], *first*: Element, *second*:
Element, *foobar*: Element } for three steps.
2. modal.*close*() - Closes and destroys the given instance of
mw.Modal.
- *(Global) *mw.Modal.close( [ Element node ] ) - Closes the
currently-open modal (no args), or the modal in which node belongs.
Returns false if none, true if successfully destroyed.
3. modal.*go*( int|String to ) - For a multi-step modal, goes to a
specific step by number or name. Returns false if invalid step, mw.Modal
instance otherwise.
modal.*next*() and
modal.*prev*() - For a multi-step modal, goes to the previous or next
step, if any are left. Returns false if none, mw.Modal instance
otherwise.
- *(Global) *mw.Modal.*go*( int|String to, [ Element node ] ) - Go to
step on the currently-open modal (no args), or the modal in which node
belongs. Returns false if none, mw.Modal instance otherwise.
- *(Global) *mw.Modal.*next*( [ Element node ] ) - Next/prev step on
the currently-open modal (no args), or the modal in which node
belongs. Returns false if none, mw.Modal instance otherwise.
4. modal.*setTitle*( String title ) - Changes the title of the modal.
5. modal.*addSteps*( Array|Object|Element|jQuery|String contents ) -
Adds one or more steps, using the same arguments as modal.open. May
overwrite steps if any exist with the same key in Object mode. Returns
mw.Modal instance.
6. modal.*setStep*( int|String to, Element|jQuery|String contents ) -
Changes a given step. If String to does not exist in the list of steps,
throws an exception; int to always succeeds. If the given step is the
currently-active one, rerenders the modal contents. Returns mw.Modal
instance.
*Theoretically, you could use setStep to keep changing step 1 to create
a pseudo-multi-step modal.*
7. modal.*getSteps*() - Returns an Object with steps, and their
contents, eg. { *steps*: [ 1, 'foo', 'bar', 4 ], *1*: Element, '*foo*':
Element, '*bar*': Element, *4*: Element }
- *(Global)* mw.Modal.*getSteps*( [ Element node ] ) - Get an Array
of steps on the currently-open modal (no args), or the modal in which
node belongs. False on failure.
8. modal.*getNode*() - Returns the modal's wrapper Element, which
contains the header node and content node.
modal.*getContentNode*() - Returns the wrapping Element on which you can
bind bubbling events for your content.
- *(Global)* mw.Modal.*getContentNode*( [ Element node ] ) - Returns the
wrapping content Element on the currently-open modal (no args), or the
modal in which node belongs. False on failure.
9. modal.*setInteractiveHandler*( String name, Function callback ) -
See "inline event handlers" below. Some helper handlers for modals are
predefined, including "modalClose", "modalNavigate" (with
*data-mwui-modal-to* attribute), "modalPrev", and "modalNext".
An additional attribute, *data-mwui-interactive-target* is a jQuery
selector which allows you to point that event to interact with another
element, without having to put this selector in your JS. It supports an
unorthodox selector, the "closest parent" selector: "<".
eg. *data-mwui-interactive-target="< .foo .bar"* will find the closest
parent .foo, and then any nodes within .bar.
10. *(Global) *mw.Modal.*getModal*() - Returns an mw.Modal instance if
one is active, false otherwise.
11. modal.*getName*() - Returns the modal's name, as defined in
initialization.
*mw.Modal events:*
mw.Modal also inherits *ooJS' EventEmitter*. So, you may bind to individual
instances of mw.Modal, or even the global mw.Modal class itself. See wiki
<http://www.mediawiki.org/wiki/OOjs/Events>. Current events list:
*open*(mw.Modal
instance), *close*(mw.Modal instance, Element target), *navigate*(mw.Modal
instance, String nextStepKey), *render*(mw.Modal instance) (only triggered
on the first render of a given piece of content, not subsequent ones).
Returning *false* from any of these event callbacks will cancel the event
from continuing.
*Inline event callers:*
You can use special *data-* attributes to trigger/listen for events without
having to specifically bind to those elements. This allows you to write
more dynamic HTML, without having to adjust JavaScript when you change
elements or selectors. Some predefined helper handlers already exist (see
#8 above).
*Example:*
<button *data-mwui-interactive-handler*="*modalClose*">Close</button>
>
These event handling techniques are borrowed from the way Flow currently
"binds" events via markup. We do this, because we found a significant
amount of code was dedicated to finding elements with selectors in JS. Any
changes to markup required a change to the JS as well. This method allows
us to change the markup without changing the JS in many cases, as the
selectors are localized to the HTML. In addition, cumbersome parent
selecting is handled with our own "closest" selector (<).
In addition, we've been experimenting with an event forwarding mechanism
which "forwards" mouse & keyboard events from within the modal, out to the
element which triggered the modal to begin with (or any other arbitrary
node). This allows us to capture events within the modal, without having to
bind directly to it.
--Shahyar
Thanks to Lego this conversation was brought to my attention.
Basically a mediawiki ui progressive button sneaked into the special
contributions page. Although not a big deal (in my opinion) this has
caused a tiny bit of a stir as might be expected (Facebookization) and
gives us a useful insight into how any form changes might be
perceived.
This button is no longer blue on mediawiki.org and will go back to
normal styling on next deploy. It seems silly to lightning deploy a
fix for this in my opinion.
Read more here:
https://en.wikipedia.org/wiki/Wikipedia:Village_pump_%28technical%29#Enormo…
I've replied, feel free to do so also.
What happened:
* https://gerrit.wikimedia.org/r/#/c/162121/ got deployed.
* This patch https://gerrit.wikimedia.org/r/#/c/163775/ did not.
Hi all,
I need to create some tooltips for the MediaViewer project which have a
more robust look and behavior than the usual tipsy tooltips. (See the
second mockup in this specification
<https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/719>.)
They would still be implemented via tipsy, but would need to be reskinned.
This seems to be the kind of functionality that should not reimplemented by
each team with a different look and feel and a duplication of effort, but
should be done once in some central location so it is usable by all. So I
am wondering if something like this exist already, and if it doesn't , what
rules should I follow to make sure my work is useful for other teams?
Pau pointed me at the Tipsy on mediawiki.ui
<https://trello.com/c/vr0Oai8G/18-tipsy> trello card, which is exactly what
I would need, but had no activity since April, and it's hard to figure out
the state of the project from it (I did not find any related code in
mediawiki.ui, at any rate). Are there any results of that which I could use?
According to the living style guide (
https://tools.wmflabs.org/styleguide/desktop/section-2.html) the current
styling for "quiet buttons" is dark grey bold text with a blue hover state,
and no outline, underline, or other indication it is clickable (or even
what area it encompasses). Since we don't have hover states on mobile,
there is no way to tell that a quiet button is actually a button (rather
then just grey text). And you can't always assume this just from the text
being a verb. For example, in the mobile login CTA we have "Help improve
this page", "Log in", "Sign up", and "Edit without logging in". "Help
improve this page" isn't clickable even though it's a verb in grey text.
What do you guys think about this problem?
Ryan Kaldari
We have been rehearsing with applying styles in Commons. While not keeping
up-to-date with the implementation of the styles across sites, I presume
they are not yet in use in Commons.
But if anyone feels like it, please tell us what our chances are to create
the kind of infobox on a Commons File page, as described here:
https://commons.wikimedia.org/wiki/Template_talk:Map/Proposal#Georeferencin…
Thanks!
Cheers,
Susanna
As you may know, there is a global to test out what MediaWiki UI will
look like when it is enabled site-wide. See
https://www.mediawiki.org/wiki/Manual:$wgUseMediaWikiUIEverywhere
Unfortunately, you can't test it right now due to
https://bugzilla.wikimedia.org/71595 , but the edit page currently looks
like:
https://i.imgur.com/h4GTzUB.png
(Thanks to Quiddity for the screenshot).
I think the main button bar is too busy. Save page is fine; that color
is semantically correct and it's the main action.
However, I suggest we consider making preview and/or show pages neutral
(basically, that looks like a button, but is not colored in the current
skin).
I'm interested in other suggestions. See
https://tools.wmflabs.org/styleguide/desktop/index.html for the features
MW UI currently has.
Matt Flaschen
I just love this Google I/O 2013 talk on human perception and
cognition, and its implications for interactive and visual design. It
is accessible, but with a lot of information and applies very well to
us I think.
I'm sure that many designers know all about this and some have
probably seen the clip before, but it is also very good for
developers, because many of these things we know subconsciously, but
it's not really part of our vocabulary.
https://www.youtube.com/watch?v=z2exxj4COhU
DJ
Since we had the luxury of having several people in the office,
Trevor, Juliusz, Rob Moen, Ed Sanders, Shahyar, May, Monte and I sat
down to talk about the problem we currently have of having no standard
way to create icons. Here is my write up of this meeting, again, if
you attended please add/correct me on anything and if you were not
please ask for clarification where needed.
Currently we have two modes of creating icons in MediaWiki
1) Using a font
2) Using SVGs with PNG fallbacks
and the markup varies depending on what extension you look at.
We discussed both approaches and advantages and disadvantages of each.
One of the major disadvantages of the WikiFont is the additional HTTP
request it creates to download the font and cannot be embedded in the
stylesheet using data uris like SVGs can (due to URL size
restrictions).
One of the major advantages of WikiFont is you can design a grayscale
icon, and style it using font colour. Shahyar was happy to move Flow
to using SVG based fonts if we could build grayscale SVGs and change
their colours using ResourceLoader. One concrete example is when you
have an icon used in a constructive anchor. The icon needs to be
green, but when hovered over a lighter green.
Another advantage brought up by May was that currently she finds it
much easier to build icons in this way, and that having to maintain
separate coloured versions of the SVGs is a pain point to her.
We decided that we should push towards using SVGs that can be built
into fonts for the purpose of the app.
As next steps
1) Monte to explore using SVGs in the Wikipedia apps. He will create
font from SVGs. He will work with May to ensure her workflow is as
easy as before.
2) Trevor is going to look into how we can automatically generate
different colour versions of SVGs and automatically create PNGs from
them.
3) I am going to aim to agree on a standard icon HTML markup for
mediawiki ui. We still have an issue with the fact that everyone is
using different HTML markup to create icons. After reviewing all our
current approaches [1] it was clear that we were relatively closely
aligned and that it simply is a case of agreeing on class names.
We aim to get all the above done by Sept 15th, 2014 so please poke us
on the mailing list if you haven't had a follow up then.
Full disorganised notes can be found here [2].
[1] https://www.mediawiki.org/wiki/Icon_standardisation
[2] http://etherpad.wikimedia.org/p/Icon_standardisation
In the profile page of mobile [1] we have a button at the bottom of the page.
Is there any reason for it having blue text?
When you take a look at the styleguide it seems like an
mw-ui-progressive or just a simple mw-ui-button [2]
We currently have a bug [3] associated with this button due to its
uniqueness, so I'm keen to work out how to make this button be
consistent with other buttons and opened a standardisation bug [4].
Can someone chip in on the bug report with how it should be styled in
the language of the styleguide and if needed, provide a new icon for
talk that isn't blue?
Thanks!
[1] https://en.m.wikipedia.org/wiki/Special:UserProfile/Jdlrobson
[2] http://tools.wmflabs.org/styleguide/desktop/section-2.html
[3] https://bugzilla.wikimedia.org/70947
[4] https://bugzilla.wikimedia.org/71071