Currently, the follow## Existing implementations of a buttoncomponents
**MediaWiki component exist:munity:**
- [[https://github.com/wikimedia/wvui/blob/master/src/components/button/Button.vue|WVUI]] (used in Vector search, NearbyPages, GlobalWatchlist)
- [[https://github.com/wikimedia/mediawiki-extensions-WikibaseMediaInfo/blob/master/resources/mediasearch-vue/components/base/Button.vue|WikibaseMediaInfo]] ([[https://github.com/wikimedia/mediawiki-extensions-WikibaseMediaInfo/blob/master/resources/mediasearch-vueMediaSearch/blob/master/resources/components/base/Button.vue|MediaSearch]] ([[https://github.com/wikimedia/mediawiki-extensions-MediaSearch/blob/master/resources/components/base/Button.less|styles]]; copy used in WikiLambda)
- [[https://github.com/wikimedia/mediawiki-extensions-ContentTranslation/blob/master/app/src/lib/mediawiki.ui/components/MWButton/MWButton.vue|ContentTranslation]]
- [[https://github.com/wmde/wikit/blob/master/vue-components/src/components/Button.vue|Wikit]]
- [[https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/extensions/Wikibase/+/refs/heads/master/client/data-bridge/src/presentation/components/EventEmittingButton.vue|Wikidata bridge]]
Some of the differences between these implementations are:**External libraries:**
- Vuetify: [[ https://github.com/vuetifyjs/vuetify/tree/master/packages/vuetify/src/components/VBtn | VBtn ]]
- Buefy: [[ https://github.com/buefy/buefy/blob/dev/src/components/button/Button.vue | Button ]]
1. **Primary style**: The WBMI button allows progressive/destructive buttons to be primary (white text on blue/red background) or non-primary (blue/red text on white background). The WVUI button is always non-primary. The CX button is primary by default, but it supports the non-primary style through `type="text"`. The Wikit button styles primary buttons exactly as prescribed in the**Wikimedia Design Style Guide links:**
- [[https://design.wikimedia.org/style-guide/components/buttons.html|design style guide]], but it ignores `type="progressive"` or `type="destructive"` if the button doesn't also have `variant="primary"` or `variant="quiet"`. The Wikidata Bridge button is always primary when it is progressive. | Buttons ]]
- [[ https://www.figma.com/file/2Jb1lVkhEMDFxO20I5xwyA/WikimediaUI-%E2%80%93-Components-library?node-id=217%3A159 | Figma specification ]]
2. **Setting the action type and quietness**: The Wikit button takes a `type` prop that can be set to `neutral`, `progressive` or `destructive`, and a variant prop that can be set to `normal`, `primary` or `quiet`. Even though Wikit is written in TypeScript, it doesn't use TypeScript types for these, they just take a string and use a validator. The WVUI button takes an `action` prop that can be set to `default`, `progressive` or `destructive`, and [[https://github.com/wikimedia/wvui/blob/master/src/actions/PrimaryAction.ts|defines a TypeScript enum]] for this; `quiet` is a boolean prop, and there is no way to make a button primary. The CX button takes `progressive` and `destructive` as boolean props; it doesn't have quiet buttons as such,### Implementation decisions
#### Primary style
- WVUI: Primary is one of three possible values for the `type` param (the others are "normal" and "quiet"). but buttons with `type="text"` or `type="icon"` look similar (there is also an `outlined` prop but I'm not sure what it does). Similarly, WBMI takes `progressive`, `destructive`These types are captured in a `ButtonType` enum.
- Wikit: styles primary buttons exactly as prescribed in the [[https://design.wikimedia.org/style-guide/components/buttons.html|design style guide]], and `primary` as boolean props, as well as a boolean `frameless` prop (which appears to be the same concept as "quiet"). Wikidata Bridge takes `type="primaryProgressive"`but it ignores `type="progressive"` or `type="destructive"` if the button doesn't also have `variant="primary"` or `variant="quiet"`
- MediaSearch: allows progressive/destructive buttons to be primary (white text on blue/red background) or non-primary (blue/red text on white background).
- CX: primary by default, and does not support destructive (or non-primary progressive); it supports something similar to quiet buttons with `type="link"` (and `type="close" and `type="back"` are icon-only quiet buttons)but it supports the non-primary style through `type="text"`
- Wikidata Bridge: button is always primary when it is progressive.
3. **Other display modes**: The CX button takes `type="icon"` to make a button quiet and icon-only, `type="text"` to make it quiet and text-only, `type="toggle"` (which doesn't seem to do anything); it also takes a boolean prop `large` to make it bigger, and boolean `outlined` and `depressed` props whose behavior is unclear to me. The Wikit button takes an `icon-only` prop. Wikidata Bridge takes a `size` prop (set to M, L or XL) and a `squary` prop (unclear what that does). WVUI and WBMI don't have additional display modes.#### Setting the action type and quietness
4.- WVUI: the button takes an `action` prop that can be set to `default`, `progressive` or `destructive`, and [[https://github.com/wikimedia/wvui/blob/master/src/actions/PrimaryAction.ts|defines a TypeScript enum]] for this. As mentioned above, `quiet` is one of the three `ButtonTypes` that can be set via the `type` prop.
- Wikit: the button takes a `type` prop that can be set to `neutral`, `progressive` or `destructive`, and a variant prop that can be set to `normal`, `primary` or `quiet`. Even though Wikit is written in TypeScript, it doesn't use TypeScript types for these, they just take a string and use a validator.
- MediaSearch: similar to CX, the button takes `progressive`, `destructive`, **Which HTML tag to use / link support**: WVUIand `primary` as boolean props, WBMI and Wikit always use `<button>`.as well as a boolean `frameless` prop (which appears to be the same concept as "quiet").
- CX: the button takes `progressive` and `destructive` as boolean props; CX uses an `<a>` if the `href` prop is setit doesn't have quiet buttons as such, and a `<span>` otherwise.but buttons with `type="text"` or `type="icon"` look similar (there is also an `outlined` prop but I'm not sure what it does).
- Wikidata Bridge: the button takes `type="primaryProgressive"`, Wikidata Bridge always uses an `<a>` with a `<span>` inside it,and does not support destructive (or non-primary progressive); and takes an `href` prop and and props to make the link open in a new tab (`opens-in-new-tab`) or prevent the href from being followed (`prevent-default`it supports something similar to quiet buttons with `type="link"` (and `type="close" and `type="back"` are icon-only quiet buttons).
5. **Setting the disabled state**: The CX, and Wikidata Bridge implementations have a `disabled` prop, and set a CSS class on the button when it's disabled, in order to style it differently. The WVUI and Wikit implementations don't have a `disabled` prop, so setting them to `disabled` sets the native attribute on the `<button>`, which they then style through the `:disabled` selector. WBMI does have a `disabled` prop, but it's superfluous since it's only used to set the native attribute.#### Other display modes
6. **How content is injected**: WVUI allows any content to be injected through a slot, and does not have explicit support for icons; a button with an icon can be made by manually passing in an icon as part of the slot content. Wikit works the same way, but it also takes an `icon-only` prop that styles the button differently. WBMI accepts arbitrary content via a slot, but also takes an `icon` prop that adds the specified icon before the slot content. Wikidata Bridge only accepts text, through the `message` prop;- Wikit: the button takes an `icon-only` prop.
- CX: the button takes `type="icon"` to make a button quiet and icon-only, it does not support arbitrary content`type="text"` to make it quiet and text-only, and support for icons is limited (`type="back"` and `type="close"` make the button icon-only with a pre-set icon).`type="toggle"` (which doesn't seem to do anything); CX renders an iconit also takes a boolean prop `large` to make it bigger, a plain text label and an indicator (smaller secondary icon) by default, but allows arbitrary content to be injected through a slotnd boolean `outlined` and `depressed` props whose behavior is unclear to me.
- Wikidata Bridge: the button takes a `size` prop (set to M, which overrides all ofL or XL) and a `squary` prop (unclear what that does).
7. **How the icon color is controlled**: CX's Icon component uses inline SVG with `fill="currentColor"`, so setting the text color (to blue for progressive, red for destructive, or white for primary) also changes the icon color. Wikit and WBMI do the same thing. WVUI's Icon component doesn't do this, and its button doesn't manage icons explicitly, so color-coordinating the icons is left up to the caller. WDB's button doesn't support changing the color of the icon.#### Which HTML tag to use / link support
8. **Invisible label text**: WBMI takes an `invisibleLabel` prop that causes the label to be rendered but hidden (this is desirable for icon-only buttons- WVUI, for accessibility reasons).Wikit, WDB does this automatically when `type="back"` or `type="close"` are used (both result in an icon-only button). WVUI and Wikit don't put in their own icons or labelsand MediaSearch: always use `<button>`
- CX: uses an `<a>` if the `href` prop is set, so this feature isn't relevant for them. CX doesn't have this featureand a `<span>` otherwise
- Wikidata Bridge: always uses an `<a>` with a `<span>` inside it, the label isn't rendered at all for icon-only buttonsand takes an `href` prop and and props to make the link open in a new tab (`opens-in-new-tab`) or prevent the href from being followed (`prevent-default`).
#### Setting the disabled state
- WVUI and Wikit: these implementations don't have a `disabled` prop, so setting them to `disabled` sets the native attribute on the `<button>`, which they then style through the `:disabled` selector.
- MediaSearch: has a `disabled` prop, but it's superfluous since it's only used to set the native attribute.
- CX and Wikidata Bridge: these implementations have a `disabled` prop, and set a CSS class on the button when it's disabled, in order to style it differently.
#### How content is injected
- WVUI: allows any content to be injected through a slot, and does not have explicit support for icons; a button with an icon can be made by manually passing in an icon as part of the slot content.
- Wikit: works the same way, but it also takes an `icon-only` prop that styles the button differently.
- MediaSearch: accepts arbitrary content via a slot, but also takes an `icon` prop that adds the specified icon before the slot content.
- CX: renders an icon, a plain text label and an indicator (smaller secondary icon) by default, but allows arbitrary content to be injected through a slot, which overrides all of that.
- Wikidata Bridge: only accepts text, through the `message` prop; it does not support arbitrary content, and support for icons is limited (`type="back"` and `type="close"` make the button icon-only with a pre-set icon).
#### How the icon color is controlled
- WVUI: button doesn't manage icons explicitly, so color-coordinating the icons is left up to the caller
- WiKit, MediaSearch, and CX: icon component uses inline SVG with `fill="currentColor"`, so setting the text color (to blue for progressive, red for destructive, or white for primary) also changes the icon color.
- Wikidata Bridge: doesn't support changing the color of the icon.
#### Invisible label text
- WVUI and Wikit: don't put in their own icons or labels, so this feature isn't relevant for them.
- MediaSearch: takes an `invisibleLabel` prop that causes the label to be rendered but hidden (this is desirable for icon-only buttons, for accessibility reasons).
- CX: doesn't have this feature, the label isn't rendered at all for icon-only buttons.
- Wikidata Bridge: does this automatically when `type="back"` or `type="close"` are used (both result in an icon-only button).