Page MenuHomePhabricator

Define and document shared component library guiding principles
Closed, ResolvedPublic

Description

Summary

Shared libraries often document guiding principles to describe the paradigms followed when designing, building, collaborating on, and sharing the library. These can include many different things depending on the purpose of the library and the priorities of the maintainers: visual design paradigms, code design patterns, collaboration principles, etc.

Some examples:

Defining and documenting guiding principles for the future Vue component library could help us in the following ways:

  • Communicate to our end users who the library is for: which users we intend to prioritize and what we intend to provide them
  • Communicate to our collaborators how we intend to work with them
  • Be a resource for resolving issues or conflicts when they come up
  • Document high-level principles of the kind of code we want to write

Proposal

The Wikimedia Design Style Guide captures design-specific principles. In the shared component library, we could cover the following (note: these are some initial ideas and the wording will need work):

Who we're serving

  • Prioritize end-user developer experience: we want the library to make building user interfaces straightforward and fast. We aim to serve users of varying levels of experience and to stick to existing patterns as much as possible so the library to facilitate developer onboarding.
  • Accessibility and internationalization: Wikimedia intends to serve every human being, eventually. We will follow Wikimedia's accessibility principles and aim to support many languages.
  • Designed and built for the wider MediaWiki ecosystem: we intend to serve developers working both within MediaWiki (core, skins, and extensions) and in the larger ecosystem, including web-based tools, static web applications, Jamstack applications, and some of our mobile apps. Platform-agnosticism will enable us to use this library as we continue expanding this ecosystem.
    • To keep our code as flexible as possible, we will aim to avoid entirely MediaWiki-specific components. When they can't be avoided, we will clearly label them as such and abstract out as much of the MediaWiki-specific code as possible in order to sequester it and aim to make it optional or configurable.
    • Components should be thoughtfully designed and developed to work across device widths

Collaboration principles [1]

  • Transparency: We work in the open and aim to provide consumers as much information as possible about what we're working on and how we're prioritizing that work.
  • Enable rather than enforce: The library maintainers welcome contributions from others and wish to collaboratively build resources to enable others to easily contribute to the library.
  • Knowledge sharing rather than knowledge silos: Contributors should have support and access to resources that allow them to understand and influence the system's workflows, methodologies, standards, and infrastructure.

Code design patterns

  • Composition over complexity: Smaller components are easier to understand and more reusable.
  • Clarity over brevity: It's better for code to be easily understandable than to be as short or as clever as possible.
  • Use existing patterns: Sticking to patterns established in the greater front-end community enables more people to contribute. Following consistent patterns within the library makes the code easier to write, review, and maintain.
  • Keep the template simple: The template within single file Vue components can be a tool to clearly illustrate what a component is and does. Consider moving everything but the most basic JavaScript code to the script tag.

Please feel free to comment on these principles or suggest additional ones in the comments!

[1] Notes on collaboration principles:


Acceptance criteria

  • Propose an initial list of guiding principles at the Vue.js Developer Summit, or shortly afterward if there isn't time at the summit
  • Solicit feedback on additional principles to include
  • Discuss principles within this task
  • Document them in the shared library, ideally in a way that's visible in Storybook

Event Timeline

I've updated this task with some feedback from the summit, especially relating to 2 of the "who we're serving" principles. We also decided to talk to the Inclusive Product Development Working Group to see if they have any feedback on how we can use these principles to build a more inclusive product

One decision that I think we should make here is where we put shared components that are MediaWiki-specific. For example, we'll have a generic typeahead search component, but MediaWiki developers should have an easy to reuse component for a typeahead search for page titles or user names on the wiki (so a MediaWiki-specific specialization of a generic component). We'll also have MediaWiki-specific components that will be reused in many places, like UniversalLanguageSelector, a wrapper for VisualEditor, and various components for interacting with Wikidata entities.

We could put these in the library, but then the library would contain MediaWiki-specific things, and some of these components can't function outside a MediaWiki context (e.g. typeahead search for titles). Alternatively, we could put them in MediaWiki core, or in the extensions they belong to (VisualEditor for the VE wrapper, Wikibase for the Wikidata things, etc), but then we wouldn't have all of our reusable components in one place. Neither of these is great, but we have to make a choice.

@Catrope thanks for raising this point. I'm trying to figure out how to reconcile the following:

  • The library is being built primarily for use in MediaWiki
  • It'd be nice if we could share what we build, which includes deep accessibility/language/browser/device support, outside of MediaWiki
  • We want to converge on a single design system and not have things in multiple locations (I worked here for at least a year before I knew that there were some widgets living in MediaWiki core)

One way I think we could achieve this is by including everything in the shared library, but separating them within Storybook to clearly indicate what is MediaWiki-specific, similar to how WiKit visually separates Wikibase components in the sidebar menu. We could have a set of agnostic components (likely the more basic ones), then a set of MediaWiki-specific components, and perhaps a set of Wikibase-specific components (although we can debate whether those should be separate later). We could consider naming the MediaWiki-specific ones with a special prefix to make it even clearer.

We could also aim to keep components MediaWiki-agnostic as much as possible. We could do this by forcing the end user to pass in a MediaWiki-specific thing as a prop, or defaulting to that MediaWiki-specific thing but allowing the prop to be customized to anything. We could also pull out the MediaWiki-specific parts into composables or mixins (like how all the API calls and response handling for MediaSearch's AutocompleteSearchInput is actually done outside the component in an app-specific mixin).

Naturally, we will need to figure out some details:

  • How can we avoid "penalizing" MediaWiki users by making them do more work in the name of generalizing? Where do we draw that line?
  • How much extra work is it to generalize, and do we have the resourcing for that?

@Catrope , @AnneT, If it helps, we can also try to identify out target audience that MUST be served. The following set comes to mind:

  1. Mediawiki Core usecases
  2. Mediawiki extensions and skins usecases, developed by WMF and volunteers
  3. Products developed by Wikimedia foundation but not based on Mediawiki - Example: Mobile centric apps like KaiOS-Wikipedia-app, Various portals for our audience that are static web applications, JAM stack applications, various analytics/stats/performance/admin tools.
  4. Non-WMF Mediawiki users
  5. web based tools developed by WMF/Volunteers. Example: Web applications deployed in wmflabs.org , toolforge.org etc

I might be missing some more, but just wanted to give an idea that this is already a wide audience with various technologies. So when we say mediawiki-specific or mediawiki-agnostic, I wanted to make sure we are not talking about MediaWiki as in Mediawiki wiki software, but the ecosystem of all of above and beyond. So we may need a better framing of this. We also need to keep in mind that this system we are developing is going to be the key tooling to enable our 2030 vision of " Wikimedia will become the essential infrastructure of the ecosystem of free knowledge, and anyone who shares our vision will be able to join us ". This means we need to account for a non-mediawiki, non-wikimedia usecases.

For the new UI library, is there an actual example of UI component that is mediawiki specific? I can think of article search and username search and such examples, but I would say they are second layer components on top of basic autocompletion based components with custom APIs and UI customization. IMHO, they should be part of the extension/skin/core that intergrates the new UI library to mediawiki.

A consideration that @Prtksxna asked about during the regular design meeting was to make it more MediaWiki agnostic so that it could be used by developers for example on WMF Tool labs, as well by designers and developers creating prototypes for Wikimedia projects that are not yet on MW.
I would also strongly support MW-agnostic library as this would serve the principle of making this accessible to more people and to enable more people to start participating who are not yet using MW. It speaks a little as well to the Movement Strategy UX recommendations around being more inclusive of designers, who are again not necessarily utilising the MW library yet but wish to prototype and build tools using the design system.

Thanks for the perspectives, @santhosh and @RHo . I've been saying "MediaWiki adjacent" to refer to items 3 and 5 on Santhosh's list, but perhaps "the wider MediaWiki ecosystem" is a better way to represent everything. Either way, I appreciate having these specifics you both spelled out, and agree that this is already a large user base to serve.

I also agree with Santhosh that we should consider what is a truly shared component that should be included in the library and what qualifies as more of a MediaWiki-specific feature, which shouldn't be included. That could get us into gray area fast, though—for example, TypeaheadSearch seems like a one-off feature upon first glance, but TypeaheadSuggestion is being reused in the Vue port of RelatedArticles as a sort of card component. I think this is where we'll need to consider how to make these types of components as generic as possible, including pulling out clearly agnostic bits into standalones (like generic autocomplete functionality). This goes back to the "composition over complexity" principle.

Finally, Rita makes a great point that being more MediaWiki-agnostic would open the library to a wider user and contributor base (I would love for it to be more accessible to designers, and it would also welcome non-MediaWiki developers more readily).

My proposal would be that we state our intention to design and build for the wider MediaWiki ecosystem (and spell out what that means), while striving for MediaWiki-agnosticism (with examples of how we can do that, and what we'll do when we can't achieve it). I'll update the task description to reflect this and feedback is welcome.

...That could get us into gray area fast, though—for example, TypeaheadSearch seems like a one-off feature upon first glance, but TypeaheadSuggestion is being reused in the Vue port of RelatedArticles as a sort of card component. I think this is where we'll need to consider how to make these types of components as generic as possible, including pulling out clearly agnostic bits into standalones (like generic autocomplete functionality). This goes back to the "composition over complexity" principle.

-> T286973: Consider renaming TypeaheadSuggestion component
The current name implies its just for typeahead suggestions, but the component itself is essentially just a card that can be used elsewhere, and I think its just the name that causes the confusion - TypeaheadSearch is probably a one-off feature, but the card that it uses to render results is more basic and reusable

-> T286973: Consider renaming TypeaheadSuggestion component
The current name implies its just for typeahead suggestions, but the component itself is essentially just a card that can be used elsewhere, and I think its just the name that causes the confusion - TypeaheadSearch is probably a one-off feature, but the card that it uses to render results is more basic and reusable

Right, the specific case of TypeaheadSearch and its subcomponents might get more complicated than "is this whole thing reusable or not." I'm hoping when we move those components into the new library we can reevaluate each one's reusability (and tackle that task you mentioned)

STH triaged this task as Low priority.
AnneT claimed this task.
AnneT updated the task description. (Show Details)

I think we can close this, since all acceptance criteria have been met