diff --git a/.changeset/bright-buttons-port.md b/.changeset/bright-buttons-port.md
new file mode 100644
index 0000000000..3c9cdd1379
--- /dev/null
+++ b/.changeset/bright-buttons-port.md
@@ -0,0 +1,32 @@
+---
+"@patternfly/elements": major
+"@patternfly/pfe-core": patch
+---
+
+``: replaces `` with PatternFly v6 design specs and React Button parity.
+
+```html
+Secondary
+Save
+```
+
+**Breaking Changes from v5**
+
+- Renamed tag from `` to ``
+- CSS custom properties renamed from `--pf-v5-c-button--*` to `--pf-v6-c-button--*`
+- Boolean flags drop the `is-` prefix (`disabled`, `loading`, `block`, `danger`, β¦)
+- `label` renamed to `accessible-label`
+- `plain` boolean replaced by `variant="plain"`
+- `size="small"|"large"` replaced by `sm`/`lg`
+- Default `type` no longer submits forms (matches React); set `type="submit"` explicitly
+
+**New features**
+
+- Form-associated custom element (`formAssociated`) with ElementInternals ARIA
+- `loading` tri-state and `loading-label`
+- Slots: `icon`, `count`; parts: `button`, `icon`, `text`, `count`, `progress`
+- `icon-position` (`start`/`end`, with deprecated `left`/`right` aliases)
+- `disabled-focusable`, `favorite`/`favorited`, `hamburger`/`expanded`, `settings`, `no-padding`
+- Link rendering via `href`/`target` with `variant="link"`
+
+Also fixes `RovingTabindexController` so index updates do not steal focus after Tab leaves a widget.
diff --git a/core/pfe-core/controllers/internals-controller.ts b/core/pfe-core/controllers/internals-controller.ts
index 90eddcb560..d5923deeeb 100644
--- a/core/pfe-core/controllers/internals-controller.ts
+++ b/core/pfe-core/controllers/internals-controller.ts
@@ -74,14 +74,20 @@ type InternalsHost = ReactiveControllerHost & HTMLElement;
export class InternalsController implements ReactiveController, ARIAMixin {
private static instances = new WeakMap();
- declare readonly form: ElementInternals['form'];
- declare readonly shadowRoot: ElementInternals['shadowRoot'];
-
// https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states
declare readonly states: unknown;
declare readonly willValidate: ElementInternals['willValidate'];
declare readonly validationMessage: ElementInternals['validationMessage'];
+ /** Form associated with the host via ElementInternals (FACE). */
+ get form(): ElementInternals['form'] {
+ return this.attachOrRetrieveInternals().form;
+ }
+
+ get shadowRoot(): ElementInternals['shadowRoot'] {
+ return this.attachOrRetrieveInternals().shadowRoot;
+ }
+
public static getLabels(host: InternalsHost): Element[] {
return Array.from(this.instances.get(host)?.internals.labels ?? []) as Element[];
}
@@ -321,8 +327,25 @@ export class InternalsController implements ReactiveController, ARIAMixin {
return this.internals.reportValidity(...args);
}
- submit(): void {
- this.internals.form?.requestSubmit();
+ /**
+ * Submit the associated form.
+ * @param submitter - optional submitter; ignored when the UA rejects non-button submitters
+ * (common for form-associated custom elements today)
+ */
+ submit(submitter?: HTMLElement): void {
+ const { form } = this.internals;
+ if (!form) {
+ return;
+ }
+ if (submitter) {
+ try {
+ form.requestSubmit(submitter);
+ return;
+ } catch {
+ // FACE hosts are not yet accepted as submitters in all engines.
+ }
+ }
+ form.requestSubmit();
}
reset(): void {
diff --git a/core/pfe-core/controllers/roving-tabindex-controller.ts b/core/pfe-core/controllers/roving-tabindex-controller.ts
index 6189ac689b..dda994d035 100644
--- a/core/pfe-core/controllers/roving-tabindex-controller.ts
+++ b/core/pfe-core/controllers/roving-tabindex-controller.ts
@@ -42,12 +42,20 @@ export class RovingTabindexController<
for (const i of this.items) {
i.tabIndex = item === i ? 0 : -1;
}
- if (this.#gainedInitialFocus) {
+ // Only move DOM focus when focus is still inside the container.
+ // Otherwise Tab/Shift+Tab out of the widget gets stolen back by
+ // subsequent index updates (e.g. during Lit updateComplete).
+ if (this.#gainedInitialFocus && this.#isFocusWithin) {
item?.focus();
}
this.host.requestUpdate();
}
+ get #isFocusWithin(): boolean {
+ const container = this.itemsContainerElement;
+ return !!container?.matches(':focus-within');
+ }
+
get items() {
return this._items;
}
diff --git a/docs/_includes/_nav.njk b/docs/_includes/_nav.njk
index aeb39fa129..1f373dfcd1 100644
--- a/docs/_includes/_nav.njk
+++ b/docs/_includes/_nav.njk
@@ -16,10 +16,10 @@
- Versions
+ icon-set="fas">Versions
{% for version in versions %}
{%- if version.current -%}
diff --git a/docs/_plugins/pfe-assets.cjs b/docs/_plugins/pfe-assets.cjs
index 8b11e3003e..32f1e6b1ff 100644
--- a/docs/_plugins/pfe-assets.cjs
+++ b/docs/_plugins/pfe-assets.cjs
@@ -4,7 +4,7 @@ const path = require('path');
/**
* Generate a map of files per package which should be copied to the site dir
* @param {object} [options]
- * @param {string} [options.prefix='pf-v5'] element prefix e.g. 'pf-v5' for 'pf-v5-button'
+ * @param {string} [options.prefix='pf-v5'] element prefix e.g. 'pf-v5' for 'pf-v6-button'
*/
function getFilesToCopy(options) {
const cwd = process.cwd();
diff --git a/docs/docs/develop/setup.md b/docs/docs/develop/setup.md
index f16330be1a..b4e2073262 100644
--- a/docs/docs/develop/setup.md
+++ b/docs/docs/develop/setup.md
@@ -59,7 +59,7 @@ tags:
| --------------------- | ------------------------------------------ | --------------------------------------------------------------- |
| `--directory` | Output directory | string [default: "/path/to/patternfly-elements"] |
| `--silent` | Do not log anything to stdout | boolean [default: false] |
-| `-n`, `--tagName` | Custom element tag name. e.g. `pf-v5-button` | string |
+| `-n`, `--tagName` | Custom element tag name. e.g. `pf-v6-button` | string |
| `-p`, `--packageName` | NPM package scope. e.g. `@patternfly/elements`| string |
| `--overwrite` | Overwrite files without prompting | boolean [default: false] |
| `--help` | Show help | boolean |
@@ -123,7 +123,7 @@ npm run new -- --tagName pf-v5-cool-element
```bash
# Run a single test in watch mode.
- npm run test:watch --files "./elements/pf-v5-button/test/pf-v5-button.spec.ts"
+ npm run test:watch --files "./elements/pf-v6-button/test/pf-v6-button.spec.ts"
# Or multiple:
npm run test:watch --files "./elements/pf-v5-{avatar,card,tabs}/test/*.spec.ts"
diff --git a/docs/framework-integration/react.md b/docs/framework-integration/react.md
index 20f8185666..cbf2fa639d 100644
--- a/docs/framework-integration/react.md
+++ b/docs/framework-integration/react.md
@@ -128,7 +128,7 @@ tags:
```js
import { useState } from "react";
- import { Button } from "@patternfly/elements/react/pf-v5-button/pf-v5-button.js";
+ import { Button } from "@patternfly/elements/react/pf-v6-button/pf-v6-button.js";
import { Card } from "@patternfly/elements/react/pf-v5-card/pf-v5-card.js";
import { Switch } from "@patternfly/elements/react/pf-v6-switch/pf-v6-switch.js";
import { Popover } from "@patternfly/elements/react/pf-v5-popover/pf-v5-popover.js";
@@ -137,7 +137,7 @@ tags:
import "./App.css";
```
- Letβs use [`pf-v5-button`][pf-v5-button] and [`pf-v5-card`][pf-v5-card] component in the
+ Letβs use [`pf-v6-button`][pf-v6-button] and [`pf-v5-card`][pf-v5-card] component in the
`App` function in the `App.tsx` file to see that our Card and Button are
working. We are updating the local state and showing it in the UI after
clicking the button.
@@ -353,7 +353,7 @@ tags:
[ce-lifecycle]: https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks
[react-lifecycle]: https://legacy.reactjs.org/docs/state-and-lifecycle.html
[vite]: https://vitejs.dev/guide/#scaffolding-your-first-vite-project
-[pf-v5-button]: https://patternflyelements.org/components/button/
+[pf-v6-button]: https://patternflyelements.org/components/button/
[pf-v5-card]: https://patternflyelements.org/components/card/
[pf-v6-switch]: https://patternflyelements.org/components/switch/
[pf-v5-tooltip]: https://patternflyelements.org/components/tooltip/
diff --git a/docs/framework-integration/vue.md b/docs/framework-integration/vue.md
index 6f1008b623..4437e7dc16 100644
--- a/docs/framework-integration/vue.md
+++ b/docs/framework-integration/vue.md
@@ -93,7 +93,7 @@ tags:
Organically grow the holistic world view of disruptive
innovation via workplace diversity and empowerment.
- Learn more
+ Learn more
diff --git a/docs/get-started.md b/docs/get-started.md
index 238fc7b675..52bc0b2ef5 100644
--- a/docs/get-started.md
+++ b/docs/get-started.md
@@ -68,14 +68,14 @@ title: Get started
Card header
This is the pf-v5-card body.
- OK
+ OK
```
Card header
This is the pf-v5-card body.
- OK
+ OK
### Importmap and Markup
@@ -94,14 +94,14 @@ Altogether your import map code could look something like this [Lit Playground D
Card header
This is the pf-v5-card body.
- OK
+ OK
```
Card header
This is the pf-v5-card body.
- OK
+ OK
{% endband %}
@@ -122,7 +122,7 @@ Altogether your import map code could look something like this [Lit Playground D
Card header
This is the pf-v5-card body.
- OK
+ OK
{% endband %}
diff --git a/docs/main.mjs b/docs/main.mjs
index d56d42bf2d..3f15063a80 100644
--- a/docs/main.mjs
+++ b/docs/main.mjs
@@ -3,7 +3,7 @@ import { PfV5Icon } from '@patternfly/elements/pf-v5-icon/pf-v5-icon.js';
import '@patternfly/elements/pf-v5-accordion/pf-v5-accordion.js';
import '@patternfly/elements/pf-v5-alert/pf-v5-alert.js';
import '@patternfly/elements/pf-v5-back-to-top/pf-v5-back-to-top.js';
-import '@patternfly/elements/pf-v5-button/pf-v5-button.js';
+import '@patternfly/elements/pf-v6-button/pf-v6-button.js';
import '@patternfly/elements/pf-v5-card/pf-v5-card.js';
import '@patternfly/elements/pf-v5-chip/pf-v5-chip.js';
import '@patternfly/elements/pf-v5-clipboard-copy/pf-v5-clipboard-copy.js';
diff --git a/elements/pf-v5-accordion/demo/bordered.html b/elements/pf-v5-accordion/demo/bordered.html
index 47048286ea..bd6ec5f331 100644
--- a/elements/pf-v5-accordion/demo/bordered.html
+++ b/elements/pf-v5-accordion/demo/bordered.html
@@ -56,7 +56,7 @@ Item five
diff --git a/elements/pf-v5-button/demo/form-control.html b/elements/pf-v5-button/demo/form-control.html
deleted file mode 100644
index ff1a09f053..0000000000
--- a/elements/pf-v5-button/demo/form-control.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/elements/pf-v5-button/demo/index.html b/elements/pf-v5-button/demo/index.html
deleted file mode 100644
index f80de9ecef..0000000000
--- a/elements/pf-v5-button/demo/index.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
- Primary
- 0
-
-
-
-
-
diff --git a/elements/pf-v5-button/demo/sizes.html b/elements/pf-v5-button/demo/sizes.html
deleted file mode 100644
index 15e068d488..0000000000
--- a/elements/pf-v5-button/demo/sizes.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
- Primary small
- Secondary small
- Danger secondary small
- Tertiary small
- Danger small
- Warning small
-
- Primary large
- Secondary large
- Danger secondary large
- Tertiary large
- Danger large
- Warning large
-
-
-
-
diff --git a/elements/pf-v5-button/demo/stateful.html b/elements/pf-v5-button/demo/stateful.html
deleted file mode 100644
index c4d44c4683..0000000000
--- a/elements/pf-v5-button/demo/stateful.html
+++ /dev/null
@@ -1,50 +0,0 @@
-
- Stateful buttons have a loading indicator
- Resume loading logs
-
- Click to start loading
-
-
-
-
-
-
-
-
-
-
diff --git a/elements/pf-v5-button/demo/user-role.html b/elements/pf-v5-button/demo/user-role.html
deleted file mode 100644
index bc0d40bc20..0000000000
--- a/elements/pf-v5-button/demo/user-role.html
+++ /dev/null
@@ -1,70 +0,0 @@
-
- Button Role Example
-
-
-
- HTML is the foundational language of the web.
-
-
-
- CSS is used to add presentation, for advanced
- layouts, and for animations
-
-
-
- JavaScript should be used sparingly to add custom
- interactions and to improve accessibility
-
-
-
- Note: the purpose of this demo is to show how custom
- roles can be applied to <pf-v5-button>.
- However, we recommend always using <pf-v5-tabs>, and avoiding custom
- implementations of existing design system patterns
-
-
-
-
-
-
diff --git a/elements/pf-v5-button/demo/variants.html b/elements/pf-v5-button/demo/variants.html
deleted file mode 100644
index 51ccccf3ed..0000000000
--- a/elements/pf-v5-button/demo/variants.html
+++ /dev/null
@@ -1,99 +0,0 @@
-
- PatternFly supports several button styling variants to be used in different scenarios as needed. The following button variants can be assigned using the variant property.
-
- Primary
- Secondary
- Danger Secondary
- Tertiary
- Danger
- Warning
-
- Disabled
- Primary
- Secondary
- Danger Secondary
- Tertiary
- Danger
- Warning
-
-
-
- Link variant
- Link
- Link
- Inline Link
- Danger Link
-
- Disabled
- Link
- Link
- Inline Link
- Danger Link
-
-
-
- Plain button
-
-
-
-
-
-
- Disabled
-
-
-
-
-
-
-
-
- Control variant
- Control
-
-
-
-
-
-
- Disabled
- Control
-
-
-
-
-
-
-
- Note: when using <pf-v5-button> as an icon-button,
- <pf-v5-button> must have the label attribute.
-
-
-
-
-
-
diff --git a/elements/pf-v5-button/docs/CHANGELOG.old.md b/elements/pf-v5-button/docs/CHANGELOG.old.md
deleted file mode 100644
index 458458e91f..0000000000
--- a/elements/pf-v5-button/docs/CHANGELOG.old.md
+++ /dev/null
@@ -1,148 +0,0 @@
-# @patternfly/pfe-button
-
-## 2.0.0-next.9
-
-### Patch Changes
-
-- 0fe6c52db: Allowed button to be disabled by its form without sprouting a disabled attr
-- b841afe40: ``: fixed loading state
-- bbcfb687f: fixed icon layouts
-- Updated dependencies [b841afe40]
-- Updated dependencies [0fe6c52db]
-- Updated dependencies [0fe6c52db]
- - @patternfly/pfe-core@2.0.0-next.13
-
-## 2.0.0-next.8
-
-### Major Changes
-
-- 6b6e2617: Makes `` a form-associated custom element
-
- BREAKING CHANGE:
- users should no longer slot a native `` into the element
-
- Before:
-
- ```html
- Submit
- ```
-
- After:
-
- ```html
- Submit
- ```
-
-### Patch Changes
-
-- Updated dependencies [6b6e2617]
- - @patternfly/pfe-core@2.0.0-next.12
-
-## 2.0.0-next.7
-
-### Patch Changes
-
-- 07ad1d3d: Updates use of ``
-- Updated dependencies [ddf052bd]
-- Updated dependencies [07ad1d3d]
-- Updated dependencies [07ad1d3d]
- - @patternfly/pfe-spinner@2.0.0-next.6
- - @patternfly/pfe-icon@2.0.0-next.5
- - @patternfly/pfe-core@2.0.0-next.10
-
-## 2.0.0-next.6
-
-### Patch Changes
-
-- eeebb45d: Replace `` with ``
-- Updated dependencies [b7602c2c]
-- Updated dependencies [166ecee1]
- - @patternfly/pfe-spinner@2.0.0-next.5
- - @patternfly/pfe-core@2.0.0-next.9
-
-## 2.0.0-next.5
-
-### Patch Changes
-
-- bfad8b4b: Updates dependencies
-- bfad8b4b: Add missing dependencies
-- a423b010: fix typescript config and update dependencies
-- Updated dependencies [bfad8b4b]
-- Updated dependencies [a423b010]
- - @patternfly/pfe-core@2.0.0-next.8
- - @patternfly/pfe-icon@2.0.0-next.4
- - @patternfly/pfe-progress-indicator@2.0.0-next.4
-
-## 2.0.0-next.4
-
-### Major Changes
-
-- a730678c: Several changes align `` to [PatternFly v4](https://patternfly.org/components/button).
-
- NEW:
- `warning`, `link`, and `control` variants added.
- `icon` and `loading` attributes added.
- `plain`, `block`, `warning` and `loading` attributes added.
- `icon` slot added.
-
- BREAKING CHANGES:
- The `pfelement` attribute and `PFElement` class are **removed** from the `` element by default.
- The `danger` variant is **removed** in favour of a new `danger` variant.
- _All_ the `--pfe-*` css variables are **removed** in favour of their `--pf-*` equivalents.
-
- See the [docs](https://patternflyelements.org/components/button) for more info,
- and the [demo](https://patternflyelements.org/components/button/demo) for usage examples.
-
-### Patch Changes
-
-- Updated dependencies [34ecd410]
- - @patternfly/pfe-core@2.0.0-next.6
-
-## 2.0.0-next.3
-
-### Patch Changes
-
-- 6a2a0407: [View commit message here](https://gist.github.com/heyMP/200fc0b840690541475923facba393ab)
-- Updated dependencies [6a2a0407]
- - @patternfly/pfe-core@2.0.0-next.4
-
-## 2.0.0-next.2
-
-### Patch Changes
-
-- 447b2d75: Remove `esbuild` export condition, as this anyways was a runtime error
-- Updated dependencies [447b2d75]
- - @patternfly/pfe-core@2.0.0-next.3
-
-## 2.0.0-next.1
-
-### Patch Changes
-
-- a56aa80b: chore: update package.json
-
-## 2.0.0-next.0
-
-### Major Changes
-
-- af331f33: ## π₯ Migrate to Lit
-
- This release migrates `` to LitElement.
-
- ### NEW: CSS Shadow Parts!
-
- - Adds the `container` CSS part to ``
-
- ### Breaking Changes
-
- - Initial render is now [asynchronous](https://lit.dev/docs/components/lifecycle/#reactive-update-cycle).
- If your code assumes that shadow DOM is ready once the element is constructed, update it to `await element.updateComplete`
- - Deprecates `pfe-button:click` event - use `click`
- - Removes the internal shadow DOM button in favour of the slotted button
- - Makes all styles on the slotted button `!important`. Use CSS Custom Properties to override
-
- See [docs](https://patternflyelements.org/components/button/) for more info
-
-### Patch Changes
-
-- Updated dependencies [e8788c72]
- - @patternfly/pfe-core@2.0.0-next.0
diff --git a/elements/pf-v5-button/docs/pf-v5-button.md b/elements/pf-v5-button/docs/pf-v5-button.md
deleted file mode 100644
index c217081eaf..0000000000
--- a/elements/pf-v5-button/docs/pf-v5-button.md
+++ /dev/null
@@ -1,137 +0,0 @@
-
-
-
-
-{% renderInstallation %} {% endrenderInstallation %}
-
-{% renderOverview %}
-
-
-
-{% endrenderOverview %}
-
-{% band header="Usage" %}
- ### Link variant
- {% htmlexample %}
-
-
-
-
- Link
-
- Link
- Inline Link
- Danger Link
- Link
- Go to PatternFly
- {% endhtmlexample %}
-
- ### Plain button
- {% htmlexample %}
-
-
-
-
-
- {% endhtmlexample %}
-
- ### Control variant
- {% htmlexample %}
- Control
-
-
-
-
-
- {% endhtmlexample %}
-
- ### Size
- {% htmlexample %}
- Medium Button
- Large Button
- {% endhtmlexample %}
-
- ### Click listeners
-
-
- HTML
-
-
-```html
-
-Click me!
-```
-
-
- Lit
-
-
-```js
-import { html, render } from 'lit';
-import '@patternfly/elements/pf-v5-button/pf-v5-button.js';
-
-render(html`
- console.log('clicked!');}">
- Click me!
-
-`, document.getElementById('container'));
-```
-
-
- React
-
-
-```jsx
-import { Button } from '@patternfly/elements/react/pf-v5-button/pf-v5-button.js';
-export function Clicker() {
- return (
- console.log('clicked!');}>
- Click me!
-
- )
-}
-```
-
-
-
-
-{% endband %}
-
-{% renderSlots %}{% endrenderSlots %}
-
-{% renderAttributes %}{% endrenderAttributes %}
-
-{% renderMethods %}{% endrenderMethods %}
-
-{% renderEvents %}{% endrenderEvents %}
-
-{% renderCssCustomProperties %}{% endrenderCssCustomProperties %}
diff --git a/elements/pf-v5-button/docs/screenshot.png b/elements/pf-v5-button/docs/screenshot.png
deleted file mode 100644
index 6e1dfdd900..0000000000
Binary files a/elements/pf-v5-button/docs/screenshot.png and /dev/null differ
diff --git a/elements/pf-v5-button/pf-v5-button-icon.css b/elements/pf-v5-button/pf-v5-button-icon.css
deleted file mode 100644
index d6519719d7..0000000000
--- a/elements/pf-v5-button/pf-v5-button-icon.css
+++ /dev/null
@@ -1,11 +0,0 @@
-/******************************
- * *
- * ICON *
- * *
- ******************************/
-
-.hasIcon {
- gap: calc(2 * var(--pf-v5-c-button__icon--m-start--MarginLeft,
- var(--pf-global--spacer--xs, 0.25rem)));
-}
-
diff --git a/elements/pf-v5-button/pf-v5-button-tokens.css b/elements/pf-v5-button/pf-v5-button-tokens.css
deleted file mode 100644
index c3332d148a..0000000000
--- a/elements/pf-v5-button/pf-v5-button-tokens.css
+++ /dev/null
@@ -1,211 +0,0 @@
-:host {
- /** PaddingTop for the button */
- --pf-v5-c-button--PaddingTop: var(--pf-global--spacer--form-element, 0.375rem);
- /** PaddingRight for the button */
- --pf-v5-c-button--PaddingRight: var(--pf-global--spacer--md, 1rem);
- /** PaddingBottom for the button */
- --pf-v5-c-button--PaddingBottom: var(--pf-global--spacer--form-element, 0.375rem);
- /** PaddingLeft for the button */
- --pf-v5-c-button--PaddingLeft: var(--pf-global--spacer--md, 1rem);
- /** LineHeight for the button */
- --pf-v5-c-button--LineHeight: var(--pf-global--LineHeight--md, 1.5);
- /** FontWeight for the button */
- --pf-v5-c-button--FontWeight: var(--pf-global--FontWeight--normal, 400);
- /** FontSize for the button */
- --pf-v5-c-button--FontSize: var(--pf-global--FontSize--md, 1rem);
- /** BackgroundColor for the button */
- --pf-v5-c-button--BackgroundColor: transparent;
- /** BorderRadius for the button */
- --pf-v5-c-button--BorderRadius: var(--pf-global--BorderRadius--sm, 3px);
- /** BorderRadius for the button after element */
- --pf-v5-c-button--after--BorderRadius: var(--pf-global--BorderRadius--sm, 3px);
- /** BorderColor for the button after element */
- --pf-v5-c-button--after--BorderColor: transparent;
- /** BorderWidth for the button after element */
- --pf-v5-c-button--after--BorderWidth: var(--pf-global--BorderWidth--sm, 1px);
- /** BorderWidth for the button after element on hover */
- --pf-v5-c-button--hover--after--BorderWidth: var(--pf-global--BorderWidth--md, 2px);
- /** BorderWidth for the button after element on focus */
- --pf-v5-c-button--focus--after--BorderWidth: var(--pf-global--BorderWidth--md, 2px);
- /** BorderWidth for the button after element when active */
- --pf-v5-c-button--active--after--BorderWidth: var(--pf-global--BorderWidth--md, 2px);
- /** Color for the button when disabled */
- --pf-v5-c-button--disabled--Color: var(--pf-global--disabled-color--100, #6a6e73);
- /** BackgroundColor for the button when disabled */
- --pf-v5-c-button--disabled--BackgroundColor: var(--pf-global--disabled-color--200, #d2d2d2);
- /** BorderColor for the button after element when disabled */
- --pf-v5-c-button--disabled--after--BorderColor: transparent;
- /** BackgroundColor for the primary button variant */
- --pf-v5-c-button--m-primary--BackgroundColor: var(--pf-global--primary-color--100, #06c);
- /** Color for the primary button variant */
- --pf-v5-c-button--m-primary--Color: var(--pf-global--Color--light-100, #fff);
- /** BackgroundColor for the primary button variant on hover */
- --pf-v5-c-button--m-primary--hover--BackgroundColor: var(--pf-global--primary-color--200, #004080);
- /** Color for the primary button variant on hover */
- --pf-v5-c-button--m-primary--hover--Color: var(--pf-global--Color--light-100, #fff);
- /** BackgroundColor for the primary button variant on focus */
- --pf-v5-c-button--m-primary--focus--BackgroundColor: var(--pf-global--primary-color--200, #004080);
- /** Color for the primary button variant on focus */
- --pf-v5-c-button--m-primary--focus--Color: var(--pf-global--Color--light-100, #fff);
- /** BackgroundColor for the primary button variant when active */
- --pf-v5-c-button--m-primary--active--BackgroundColor: var(--pf-global--primary-color--200, #004080);
- /** Color for the primary button variant when active */
- --pf-v5-c-button--m-primary--active--Color: var(--pf-global--Color--light-100, #fff);
- /** BackgroundColor for the secondary button variant */
- --pf-v5-c-button--m-secondary--BackgroundColor: transparent;
- /** BorderColor for the secondary button variant after element */
- --pf-v5-c-button--m-secondary--after--BorderColor: var(--pf-global--primary-color--100, #06c);
- /** Color for the secondary button variant */
- --pf-v5-c-button--m-secondary--Color: var(--pf-global--primary-color--100, #06c);
- /** BackgroundColor for the secondary button variant on hover */
- --pf-v5-c-button--m-secondary--hover--BackgroundColor: transparent;
- /** BorderColor for the secondary button variant after element on hover */
- --pf-v5-c-button--m-secondary--hover--after--BorderColor: var(--pf-global--primary-color--100, #06c);
- /** Color for the secondary button variant on hover */
- --pf-v5-c-button--m-secondary--hover--Color: var(--pf-global--primary-color--100, #06c);
- /** BackgroundColor for the secondary button variant on focus */
- --pf-v5-c-button--m-secondary--focus--BackgroundColor: transparent;
- /** BorderColor for the secondary button variant after element on focus */
- --pf-v5-c-button--m-secondary--focus--after--BorderColor: var(--pf-global--primary-color--100, #06c);
- /** Color for the secondary button variant on focus */
- --pf-v5-c-button--m-secondary--focus--Color: var(--pf-global--primary-color--100, #06c);
- /** BackgroundColor for the secondary button variant when active */
- --pf-v5-c-button--m-secondary--active--BackgroundColor: transparent;
- --pf-v5-c-button--m-secondary--active--after--BorderColor: var(--pf-global--primary-color--100, #06c);
- --pf-v5-c-button--m-secondary--active--Color: var(--pf-global--primary-color--100, #06c);
- --pf-v5-c-button--m-secondary--m-danger--BackgroundColor: transparent;
- --pf-v5-c-button--m-secondary--m-danger--Color: var(--pf-global--danger-color--100, #c9190b);
- --pf-v5-c-button--m-secondary--m-danger--after--BorderColor: var(--pf-global--danger-color--100, #c9190b);
- --pf-v5-c-button--m-secondary--m-danger--hover--BackgroundColor: transparent;
- --pf-v5-c-button--m-secondary--m-danger--hover--Color: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-secondary--m-danger--hover--after--BorderColor: var(--pf-global--danger-color--100, #c9190b);
- --pf-v5-c-button--m-secondary--m-danger--focus--BackgroundColor: transparent;
- --pf-v5-c-button--m-secondary--m-danger--focus--Color: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-secondary--m-danger--focus--after--BorderColor: var(--pf-global--danger-color--100, #c9190b);
- --pf-v5-c-button--m-secondary--m-danger--active--BackgroundColor: transparent;
- --pf-v5-c-button--m-secondary--m-danger--active--Color: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-secondary--m-danger--active--after--BorderColor: var(--pf-global--danger-color--100, #c9190b);
- --pf-v5-c-button--m-tertiary--BackgroundColor: transparent;
- --pf-v5-c-button--m-tertiary--after--BorderColor: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-tertiary--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-tertiary--hover--BackgroundColor: transparent;
- --pf-v5-c-button--m-tertiary--hover--after--BorderColor: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-tertiary--hover--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-tertiary--focus--BackgroundColor: transparent;
- --pf-v5-c-button--m-tertiary--focus--after--BorderColor: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-tertiary--focus--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-tertiary--active--BackgroundColor: transparent;
- --pf-v5-c-button--m-tertiary--active--after--BorderColor: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-tertiary--active--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-warning--BackgroundColor: var(--pf-global--warning-color--100, #f0ab00);
- --pf-v5-c-button--m-warning--Color: var(--pf-global--Color--dark-100, #151515);
- --pf-v5-c-button--m-warning--hover--BackgroundColor: var(--pf-global--palette--gold-500, #c58c00);
- --pf-v5-c-button--m-warning--hover--Color: var(--pf-global--Color--dark-100, #151515);
- --pf-v5-c-button--m-warning--focus--BackgroundColor: var(--pf-global--palette--gold-500, #c58c00);
- --pf-v5-c-button--m-warning--focus--Color: var(--pf-global--Color--dark-100, #151515);
- --pf-v5-c-button--m-warning--active--BackgroundColor: var(--pf-global--palette--gold-500, #c58c00);
- --pf-v5-c-button--m-warning--active--Color: var(--pf-global--Color--dark-100, #151515);
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-global--danger-color--100, #c9190b);
- --pf-v5-c-button--m-danger--Color: var(--pf-global--Color--light-100, #fff);
- --pf-v5-c-button--m-danger--hover--BackgroundColor: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-danger--hover--Color: var(--pf-global--Color--light-100, #fff);
- --pf-v5-c-button--m-danger--focus--BackgroundColor: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-danger--focus--Color: var(--pf-global--Color--light-100, #fff);
- --pf-v5-c-button--m-danger--active--BackgroundColor: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-danger--active--Color: var(--pf-global--Color--light-100, #fff);
- --pf-v5-c-button--m-link--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--Color: var(--pf-global--link--Color, #06c);
- --pf-v5-c-button--m-link--hover--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--hover--Color: var(--pf-global--link--Color--hover, #004080);
- --pf-v5-c-button--m-link--focus--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--focus--Color: var(--pf-global--link--Color--hover, #004080);
- --pf-v5-c-button--m-link--active--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--active--Color: var(--pf-global--link--Color--hover, #004080);
- --pf-v5-c-button--m-link--disabled--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--m-inline--FontSize: inherit;
- --pf-v5-c-button--m-link--m-inline--hover--TextDecoration: var(--pf-global--link--TextDecoration--hover, underline);
- --pf-v5-c-button--m-link--m-inline--hover--Color: var(--pf-global--link--Color--hover, #004080);
- --pf-v5-c-button--m-link--m-inline--PaddingTop: 0;
- --pf-v5-c-button--m-link--m-inline--PaddingRight: 0;
- --pf-v5-c-button--m-link--m-inline--PaddingBottom: 0;
- --pf-v5-c-button--m-link--m-inline--PaddingLeft: 0;
- --pf-v5-c-button--m-link--m-inline__progress--Left: var(--pf-global--spacer--xs, 0.25rem);
- --pf-v5-c-button--m-link--m-inline--m-in-progress--PaddingLeft: calc(var(--pf-v5-c-button--m-link--m-inline__progress--Left) + 1rem + var(--pf-global--spacer--sm, 0.5rem));
- --pf-v5-c-button--m-link--m-danger--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--m-danger--Color: var(--pf-global--danger-color--100, #c9190b);
- --pf-v5-c-button--m-link--m-danger--hover--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--m-danger--hover--Color: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-link--m-danger--focus--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--m-danger--focus--Color: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-link--m-danger--active--BackgroundColor: transparent;
- --pf-v5-c-button--m-link--m-danger--active--Color: var(--pf-global--danger-color--200, #a30000);
- --pf-v5-c-button--m-plain--BackgroundColor: transparent;
- --pf-v5-c-button--m-plain--Color: var(--pf-global--Color--200, #6a6e73);
- --pf-v5-c-button--m-plain--hover--BackgroundColor: transparent;
- --pf-v5-c-button--m-plain--hover--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-plain--focus--BackgroundColor: transparent;
- --pf-v5-c-button--m-plain--focus--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-plain--active--BackgroundColor: transparent;
- --pf-v5-c-button--m-plain--active--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-plain--disabled--Color: var(--pf-global--disabled-color--200, #d2d2d2);
- --pf-v5-c-button--m-plain--disabled--BackgroundColor: transparent;
- --pf-v5-c-button--m-control--BackgroundColor: var(--pf-global--BackgroundColor--100, #fff);
- --pf-v5-c-button--m-control--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-control--BorderRadius: 0;
- --pf-v5-c-button--m-control--after--BorderWidth: var(--pf-global--BorderWidth--sm, 1px);
- --pf-v5-c-button--m-control--after--BorderTopColor: var(--pf-global--BorderColor--300, #f0f0f0);
- --pf-v5-c-button--m-control--after--BorderRightColor: var(--pf-global--BorderColor--300, #f0f0f0);
- --pf-v5-c-button--m-control--after--BorderBottomColor: var(--pf-global--BorderColor--200, #8a8d90);
- --pf-v5-c-button--m-control--after--BorderLeftColor: var(--pf-global--BorderColor--300, #f0f0f0);
- --pf-v5-c-button--m-control--disabled--BackgroundColor: var(--pf-global--disabled-color--300, #f0f0f0);
- --pf-v5-c-button--m-control--hover--BackgroundColor: var(--pf-global--BackgroundColor--100, #fff);
- --pf-v5-c-button--m-control--hover--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-control--hover--after--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px);
- --pf-v5-c-button--m-control--hover--after--BorderBottomColor: var(--pf-global--active-color--100, #06c);
- --pf-v5-c-button--m-control--active--BackgroundColor: var(--pf-global--BackgroundColor--100, #fff);
- --pf-v5-c-button--m-control--active--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-control--active--after--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px);
- --pf-v5-c-button--m-control--active--after--BorderBottomColor: var(--pf-global--active-color--100, #06c);
- --pf-v5-c-button--m-control--focus--BackgroundColor: var(--pf-global--BackgroundColor--100, #fff);
- --pf-v5-c-button--m-control--focus--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-control--focus--after--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px);
- --pf-v5-c-button--m-control--focus--after--BorderBottomColor: var(--pf-global--active-color--100, #06c);
- --pf-v5-c-button--m-control--m-expanded--BackgroundColor: var(--pf-global--BackgroundColor--100, #fff);
- --pf-v5-c-button--m-control--m-expanded--Color: var(--pf-global--Color--100, #151515);
- --pf-v5-c-button--m-control--m-expanded--after--BorderBottomWidth: var(--pf-global--BorderWidth--md, 2px);
- --pf-v5-c-button--m-control--m-expanded--after--BorderBottomColor: var(--pf-global--active-color--100, #06c);
- --pf-v5-c-button--m-small--FontSize: var(--pf-global--FontSize--sm, 0.875rem);
- --pf-v5-c-button--m-display-lg--PaddingTop: var(--pf-global--spacer--md, 1rem);
- --pf-v5-c-button--m-display-lg--PaddingRight: var(--pf-global--spacer--xl, 2rem);
- --pf-v5-c-button--m-display-lg--PaddingBottom: var(--pf-global--spacer--md, 1rem);
- --pf-v5-c-button--m-display-lg--PaddingLeft: var(--pf-global--spacer--xl, 2rem);
- --pf-v5-c-button--m-display-lg--FontWeight: var(--pf-global--FontWeight--bold, 700);
- --pf-v5-c-button--m-link--m-display-lg--FontSize: var(--pf-global--FontSize--lg, 1.125rem);
- --pf-v5-c-button__icon--m-start--MarginRight: var(--pf-global--spacer--xs, 0.25rem);
- --pf-v5-c-button__icon--m-end--MarginLeft: var(--pf-global--spacer--xs, 0.25rem);
- --pf-v5-c-button__progress--width: calc(var(--pf-global--icon--FontSize--md, 1.125rem) + var(--pf-global--spacer--sm, 0.5rem));
- --pf-v5-c-button__progress--Opacity: 0;
- --pf-v5-c-button__progress--TranslateY: -50%;
- --pf-v5-c-button__progress--TranslateX: 0;
- --pf-v5-c-button__progress--Top: 50%;
- --pf-v5-c-button__progress--Left: var(--pf-global--spacer--md, 1rem);
- --pf-v5-c-button--m-progress--TransitionProperty: padding;
- --pf-v5-c-button--m-progress--TransitionDuration: var(--pf-global--TransitionDuration, 250ms);
- --pf-v5-c-button--m-progress--PaddingRight: calc(var(--pf-global--spacer--md, 1rem) + var(--pf-v5-c-button__progress--width) / 2);
- --pf-v5-c-button--m-progress--PaddingLeft: calc(var(--pf-global--spacer--md, 1rem) + var(--pf-v5-c-button__progress--width) / 2);
- --pf-v5-c-button--m-in-progress--PaddingRight: var(--pf-global--spacer--md, 1rem);
- --pf-v5-c-button--m-in-progress--PaddingLeft: calc(var(--pf-global--spacer--md, 1rem) + var(--pf-v5-c-button__progress--width));
- --pf-v5-c-button--m-in-progress--m-plain--Color: var(--pf-global--primary-color--100, #06c);
- --pf-v5-c-button--m-in-progress--m-plain__progress--Left: 50%;
- --pf-v5-c-button--m-in-progress--m-plain__progress--TranslateX: -50%;
- --pf-v5-c-button__count--MarginLeft: var(--pf-global--spacer--sm, 0.5rem);
- --pf-v5-c-button--disabled__c-badge--Color: var(--pf-global--Color--dark-100, #151515);
- --pf-v5-c-button--disabled__c-badge--BackgroundColor: var(--pf-global--BackgroundColor--200, #f0f0f0);
- --pf-v5-c-button--m-primary__c-badge--BorderColor: var(--pf-global--BorderColor--300, #f0f0f0);
- --pf-v5-c-button--m-primary__c-badge--BorderWidth: var(--pf-global--BorderWidth--sm, 1px);
-
- /** Internal button color property */
- --_button-color: var(--pf-v5-c-button--m-primary--Color);
- /** Internal button background color property */
- --_button-background-color: var(--pf-v5-c-button--m-primary--BackgroundColor);
-}
diff --git a/elements/pf-v5-button/pf-v5-button.css b/elements/pf-v5-button/pf-v5-button.css
deleted file mode 100644
index d1fa059247..0000000000
--- a/elements/pf-v5-button/pf-v5-button.css
+++ /dev/null
@@ -1,611 +0,0 @@
-:host {
- font-size: var(--pf-v5-c-button--FontSize);
- font-weight: var(--pf-v5-c-button--FontWeight);
- line-height: var(--pf-v5-c-button--LineHeight);
- text-align: center;
- white-space: nowrap;
- font-size: var(--pf-v5-c-button--FontSize,
- var(--pf-global--FontSize--md, 1rem));
- font-weight: var(--pf-v5-c-button--FontWeight,
- var(--pf-global--FontWeight--normal, 400));
- line-height: var(--pf-v5-c-button--LineHeight,
- var(--pf-global--LineHeight--md, 1.5));
- display: inline-block;
- height: max-content;
- cursor: pointer;
- position: relative;
- font-family: inherit;
- border-width: 0;
- border-style: solid;
- border-radius: var(--pf-v5-c-button--BorderRadius,
- var(--pf-global--BorderRadius--sm, 3px));
-}
-
-:host([hidden]),
-[hidden] {
- display: none !important;
-}
-
-:host([inline]) {
- display: inline;
- --pf-v5-c-button--PaddingTop: 0;
- --pf-v5-c-button--PaddingLeft: 0;
- --pf-v5-c-button--PaddingBottom: 0;
- --pf-v5-c-button--PaddingRight: 0;
-}
-
-pf-v5-icon,
-::slotted(pf-v5-icon) {
- color: currentcolor;
- padding-inline-start: var(--_button-icon-padding-inline-start);
- padding-inline-end: var(--_button-icon-padding-inline-end);
- vertical-align: var(--_button-icon-vertical-align);
-}
-
-#icon {
- margin-inline-end: var(--pf-v5-c-button__icon--m-start--MarginRight,
- var(--pf-global--spacer--xs, 0.25rem));
-}
-
-#button {
- display: inline-block;
- color: var(--_button-color);
- padding:
- var(--pf-v5-c-button--PaddingTop,
- var(--pf-global--spacer--form-element, 0.375rem))
- var(--pf-v5-c-button--PaddingRight,
- var(--pf-global--spacer--md, 1rem))
- var(--pf-v5-c-button--PaddingBottom,
- var(--pf-global--spacer--form-element, 0.375rem))
- var(--pf-v5-c-button--PaddingLeft,
- var(--pf-global--spacer--md, 1rem));
- &::before,
- &::after {
- position: absolute;
- inset: 0;
- content: "";
- }
- &::before {
- background-color: var(--_button-background-color);
- border-radius: var(--pf-v5-c-button--BorderRadius,
- var(--pf-global--BorderRadius--sm, 3px));
- }
- &::after {
- pointer-events: none;
- border-style: solid;
- border-width: var(--pf-v5-c-button--after--BorderWidth);
- border-color: var(--pf-v5-c-button--after--BorderColor);
- border-radius: var(--pf-v5-c-button--after--BorderRadius);
- }
- &.anchor {
- text-decoration: none;
- &::after {
- pointer-events: all;
- }
- }
-}
-
-#text {
- display: inline;
- position: relative;
-}
-
-:host(:focus) {
- --pf-v5-c-button--m-primary--Color: var(--pf-v5-c-button--m-primary--focus--Color,
- var(--pf-global--Color--light-100, #fff));
- --pf-v5-c-button--m-primary--BackgroundColor: var(--pf-v5-c-button--m-primary--focus--BackgroundColor,
- var(--pf-global--primary-color--200, #004080));
- --pf-v5-c-button--after--BorderWidth: var(--pf-v5-c-button--focus--after--BorderWidth,
- var(--pf-global--BorderWidth--md, 2px));
- /* DANGER */
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-danger--focus--Color,
- var(--pf-global--Color--light-100, #fff));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-danger--focus--BackgroundColor,
- var(--pf-global--danger-color--200, #a30000));
- /* LINK */
- --pf-v5-c-button--m-link--Color: var(--pf-v5-c-button--m-link--focus--Color,
- var(--pf-global--link--Color--hover, #004080));
- --pf-v5-c-button--m-link--BackgroundColor: var(--pf-v5-c-button--m-link--hover--BackgroundColor, transparent);
- /* PLAIN */
- --pf-v5-c-button--m-plain--Color: var(--pf-v5-c-button--m-plain--focus--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-plain--BackgroundColor: var(--pf-v5-c-button--m-plain--focus--BackgroundColor,
- transparent);
-}
-
-:host(:hover) {
- --pf-v5-c-button--m-primary--Color: var(--pf-v5-c-button--m-primary--hover--Color,
- var(--pf-global--Color--light-100, #fff));
- --pf-v5-c-button--m-primary--BackgroundColor: var(--pf-v5-c-button--m-primary--hover--BackgroundColor,
- var(--pf-global--primary-color--200, #004080));
- --pf-v5-c-button--after--BorderWidth: var(--pf-v5-c-button--hover--after--BorderWidth,
- var(--pf-global--BorderWidth--md, 2px));
- /* DANGER */
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-danger--hover--Color,
- var(--pf-global--Color--light-100, #fff));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-danger--hover--BackgroundColor,
- var(--pf-global--danger-color--200, #a30000));
- /* LINK */
- --pf-v5-c-button--m-link--Color: var(--pf-v5-c-button--m-link--hover--Color,
- var(--pf-global--link--Color--hover, #004080));
- --pf-v5-c-button--m-link--BackgroundColor: var(--pf-v5-c-button--m-link--hover--BackgroundColor, transparent);
- /* PLAIN */
- --pf-v5-c-button--m-plain--Color: var(--pf-v5-c-button--m-plain--hover--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-plain--BackgroundColor: var(--pf-v5-c-button--m-plain--hover--BackgroundColor,
- transparent);
-}
-
-:host(:active) {
- --pf-v5-c-button--m-primary--Color: var(--pf-v5-c-button--m-primary--active--Color,
- var(--pf-global--Color--light-100, #fff));
- --pf-v5-c-button--m-primary--BackgroundColor: var(--pf-v5-c-button--m-primary--active--BackgroundColor,
- var(--pf-global--primary-color--200, #004080));
- --pf-v5-c-button--after--BorderWidth: var(--pf-v5-c-button--active--after--BorderWidth,
- var(--pf-global--BorderWidth--md, 2px));
- /* DANGER */
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-danger--active--Color,
- var(--pf-global--Color--light-100, #fff));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-danger--active--BackgroundColor,
- var(--pf-global--danger-color--200, #a30000));
- /* LINK */
- --pf-v5-c-button--m-link--Color: var(--pf-v5-c-button--m-link--active--Color,
- var(--pf-global--link--Color--hover, #004080));
- --pf-v5-c-button--m-link--BackgroundColor: var(--pf-v5-c-button--m-link--active--BackgroundColor, transparent);
-}
-
-.disabled,
-:host(:disabled),
-:host([danger]:disabled),
-:host([link]:disabled) .link {
- pointer-events: none;
- cursor: default;
-}
-
-[part=icon] {
- --pf-v5-icon--size: 16px;
- display: inline-flex;
- align-items: center;
- position: absolute;
- & ::slotted(*) {
- width: 16px;
- max-width: 16px;
- height: 16px;
- max-height: 16px;
- }
-}
-
-.hasIcon [part=icon] {
- cursor: pointer;
-}
-
-.hasIcon #button {
- position: absolute;
- inset: 0;
-}
-
-/******************************
- * *
- * PLAIN *
- * *
- ******************************/
-
-#button.plain {
- --pf-v5-c-button--disabled--BackgroundColor: var(--pf-v5-c-button--m-plain--disabled--BackgroundColor, transparent);
- --pf-v5-c-button--after--BorderWidth: 0 !important;
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-tertiary--after--BorderColor,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--disabled--Color: var(--pf-v5-c-button--m-plain--disabled--Color,
- var(--pf-global--disabled-color--200, #d2d2d2));
- --_button-color: var(--pf-v5-c-button--m-plain--Color,
- var(--pf-global--Color--200, #6a6e73));
- --_button-background-color: var(--pf-v5-c-button--m-plain--BackgroundColor,
- transparent);
- :host(:active) & {
- --pf-v5-c-button--m-plain--Color: var(--pf-v5-c-button--m-plain--active--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-plain--BackgroundColor: var(--pf-v5-c-button--m-plain--active--BackgroundColor,
- tranparent);
- }
- &:not(.hasIcon) [part=icon],
- &.loading [part=icon] {
- left: 16px;
- }
- & [part=icon] {
- display: contents;
- }
- &.disabled,
- &.link.disabled {
- --_button-color: var(--pf-v5-c-button--disabled--Color,
- var(--pf-v5-c-button--m-plain--disabled--Color,
- var(--pf-global--disabled--color--200, #d2d2d2)));
- }
-}
-
-.hasIcon:not(.plain) [part=icon] {
- position: relative;
-}
-
-/******************************
- * *
- * ICON POSITION RIGHT *
- * *
- ******************************/
-
-:host([icon-position=right]) .loading [part=icon] {
- order: 1;
-}
-
-:host([icon-position=right]) #button.hasIcon {
- padding-left: var(--pf-v5-c-button--PaddingLeft, var(--pf-global--spacer--md, 1rem));
- padding-right: calc(16px + 8px + var(--pf-v5-c-button--PaddingRight, var(--pf-global--spacer--md, 1rem)));
-}
-
-/******************************
- * *
- * WARNING *
- * *
- ******************************/
-
-#button.warning {
- --_button-color: var(--pf-v5-c-button--m-warning--Color,
- var(--pf-global--Color--dark-100, #151515));
- --_button-background-color: var(--pf-v5-c-button--m-warning--BackgroundColor,
- var(--pf-global--warning-color--100, #f0ab00));
- :host(:focus) & {
- --pf-v5-c-button--m-warning--Color: var(--pf-v5-c-button--m-warning--focus--Color,
- var(--pf-global--Color--dark-100, #151515));
- --pf-v5-c-button--m-warning--BackgroundColor: var(--pf-v5-c-button--m-warning--focus--BackgroundColor,
- var(--pf-global--palette--gold-500, #c58c00));
- }
- :host(:hover) & {
- --pf-v5-c-button--m-warning--Color: var(--pf-v5-c-button--m-warning--hover--Color,
- var(--pf-global--Color--dark-100, #151515));
- --pf-v5-c-button--m-warning--BackgroundColor: var(--pf-v5-c-button--m-warning--hover--BackgroundColor,
- var(--pf-global--palette--gold-500, #c58c00));
- }
- :host(:active) & {
- --pf-v5-c-button--m-warning--Color: var(--pf-v5-c-button--m-warning--active--Color,
- var(--pf-global--Color--dark-100, #151515));
- --pf-v5-c-button--m-warning--BackgroundColor: var(--pf-v5-c-button--m-warning--active--BackgroundColor,
- var(--pf-global--palette--gold-500, #c58c00));
- }
- &.disabled {
- --_button-color: var(--pf-v5-c-button--disabled--Color,
- var(--pf-global--disabled-color--100, #6a6e73));
- --_button-background-color: var(--pf-v5-c-button--disabled--BackgroundColor,
- var(--pf-global--disabled-color--200, #d2d2d2));
- }
-}
-
-/******************************
- * *
- * LOADING *
- * *
- ******************************/
-
-:host([loading]) #button {
- position: relative;
- display: flex;
- align-items: center;
-}
-
-#button.loading {
- & [part=icon] {
- display: inline-block;
- z-index: 1;
- position: absolute;
- cursor: pointer;
- top: var(--pf-v5-c-button__progress--Top, 50%);
- left: var(--pf-v5-c-button__progress--Left,
- var(--pf-global--spacer--md, 1rem));
- line-height: 1;
- transform: translate(
- var(--pf-v5-c-button__progress--TranslateX, 0),
- var(--pf-v5-c-button__progress--TranslateY, -50%));
- margin-inline-end: var(--pf-v5-c-button__icon--m-start--MarginRight,
- var(--pf-global--spacer--xs, 0.25rem));
- }
- &.primary:not(.plain),
- &.danger {
- --pf-v6-c-spinner--Color: white;
- }
- &:not(.plain) {
- padding-left: calc(12px + var(--pf-v5-c-button--PaddingLeft, var(--pf-global--spacer--md, 1rem)));
- --pf-v5-c-button--PaddingRight: var(--pf-v5-c-button--m-in-progress--PaddingRight,
- var(--pf-global--spacer--md, 1rem));
- --pf-v5-c-button--PaddingLeft: var(--pf-v5-c-button--m-in-progress--PaddingLeft,
- calc(
- var(--pf-global--spacer--md, 1rem) + var(--pf-v5-c-button__progress--width,
- calc(var(--pf-global--icon--FontSize--md, 1.125rem) + var(--pf-global--spacer--sm, 0.5rem))) / 2));
- }
-
-}
-
-/******************************
- * *
- * SECONDARY *
- * *
- ******************************/
-
-#button.secondary {
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-secondary--m-danger--Color,
- var(--pf-global--danger-color--100, #c9190b));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-secondary--m-danger--BackgroundColor, transparent);
- --_button-color: var(--pf-v5-c-button--m-secondary--Color,
- var(--pf-global--primary-color--100, #06c));
- --_button-background-color: var(--pf-v5-c-button--m-secondary--BackgroundColor, transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--after--BorderColor,
- var(--pf-global--primary-color--100, #06c));
- :host(:focus) & {
- --pf-v5-c-button--m-secondary--Color: var(--pf-v5-c-button--m-secondary--focus--Color,
- var(--pf-global--primary-color--100, #06c));
- --pf-v5-c-button--m-secondary--BackgroundColor: var(--pf-v5-c-button--m-secondary--focus--BackgroundColor, transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--focus--after--BorderColor,
- var(--pf-global--primary-color--100, #06c));
- /* DANGER */
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-secondary--m-danger--focus--Color,
- var(--pf-global--danger--color--200, #a30000));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-secondary--m-danger--focus--BackgroundColor, transparent);
- }
- :host(:hover) & {
- --pf-v5-c-button--m-secondary--Color: var(--pf-v5-c-button--m-secondary--hover--Color,
- var(--pf-global--primary-color--100, #06c));
- --pf-v5-c-button--m-secondary--BackgroundColor: var(--pf-v5-c-button--m-secondary--hover--BackgroundColor,
- transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--hover--after--BorderColor,
- var(--pf-global--primary-color--100, #06c));
- /* DANGER */
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-secondary--m-danger--hover--Color,
- var(--pf-global--danger--color--200, #a30000));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-secondary--m-danger--hover--BackgroundColor, transparent);
- }
- :host(:active) & {
- --pf-v5-c-button--m-secondary--Color: var(--pf-v5-c-button--m-secondary--active--Color,
- var(--pf-global--primary-color--100, #06c));
- --pf-v5-c-button--m-secondary--BackgroundColor: var(--pf-v5-c-button--m-secondary--active--BackgroundColor, transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--active--after--BorderColor,
- var(--pf-global--primary-color--100, #06c));
- /* DANGER */
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-secondary--m-danger--active--Color,
- var(--pf-global--danger--color--200, #a30000));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-secondary--m-danger--active--BackgroundColor, transparent);
- }
- &.danger {
- --_button-color: var(--pf-v5-c-button--m-secondary--m-danger--Color,
- var(--pf-global--danger--color--100, #c9190b));
- --_button-background-color: var(--pf-v5-c-button--m-secondary--m-danger--BackgroundColor, transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--m-danger--after--BorderColor,
- var(--pf-global--danger--color--100, #c9190b));
- :host(:focus) & {
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--m-danger--focus--after--BorderColor,
- var(--pf-global--danger--color--100, #c9190b));
- }
- :host(:hover) & {
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--m-danger--hover--after--BorderColor,
- var(--pf-global--danger--color--100, #c9190b));
- }
- :host(:active) & {
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-secondary--m-danger--active--after--BorderColor,
- var(--pf-global--danger--color--100, #c9190b));
- }
- }
-}
-
-/******************************
- * *
- * TERTIARY *
- * *
- ******************************/
-
-#button.tertiary {
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-tertiary--after--BorderColor,
- var(--pf-global--Color--100, #151515));
- --_button-color: var(--pf-v5-c-button--m-tertiary--Color,
- var(--pf-global--Color--100, #151515));
- --_button-background-color: var(--pf-v5-c-button--m-tertiary--BackgroundColor, transparent);
- :host(:focus) & {
- --pf-v5-c-button--m-tertiary--Color: var(--pf-v5-c-button--m-tertiary--focus--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-tertiary--BackgroundColor: var(--pf-v5-c-button--m-tertiary--focus--BackgroundColor,
- transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-tertiary--focus--after--BorderColor,
- var(--pf-global--Color--100, #151515));
- }
- :host(:hover) & {
- --pf-v5-c-button--m-tertiary--Color: var(--pf-v5-c-button--m-tertiary--hover--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-tertiary--BackgroundColor: var(--pf-v5-c-button--m-tertiary--hover--BackgroundColor, transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-tertiary--hover--after--BorderColor,
- var(--pf-global--Color--100, #151515));
- }
- :host(:active) & {
- --pf-v5-c-button--m-tertiary--Color: var(--pf-v5-c-button--m-tertiary--active--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-tertiary--BackgroundColor: var(--pf-v5-c-button--m-tertiary--active--BackgroundColor, transparent);
- --pf-v5-c-button--after--BorderColor: var(--pf-v5-c-button--m-tertiary--active--after--BorderColor,
- var(--pf-global--Color--100, #151515));
- }
-}
-
-/******************************
- * *
- * CONTROL *
- * *
- ******************************/
-
-#button.control {
- --pf-v5-c-button--BorderRadius: var(--pf-v5-c-button--m-control--BorderRadius, 0);
- --pf-v5-c-button--disabled--BackgroundColor: var(--pf-v5-c-button--m-control--disabled--BackgroundColor,
- var(--pf-global--disabled-color--300, #f0f0f0));
- --pf-v5-c-button--after--BorderRadius: 0;
- --pf-v5-c-button--after--BorderWidth: var(--pf-v5-c-button--m-control--after--BorderWidth,
- var(--pf-global--BorderWidth--sm, 1px));
- --pf-v5-c-button--after--BorderColor:
- var(--pf-v5-c-button--m-control--after--BorderTopColor,
- var(--pf-global--BorderColor--300, #f0f0f0))
- var(--pf-v5-c-button--m-control--after--BorderRightColor,
- var(--pf-global--BorderColor--300, #f0f0f0))
- var(--pf-v5-c-button--m-control--after--BorderBottomColor,
- var(--pf-global--BorderColor--200, #8a8d90))
- var(--pf-v5-c-button--m-control--after--BorderLeftColor,
- var(--pf-global--BorderColor--300, #f0f0f0));
- --_button-color: var(--pf-v5-c-button--m-control--Color,
- var(--pf-global--Color--100, #151515));
- --_button-background-color: var(--pf-v5-c-button--m-control--BackgroundColor,
- var(--pf-global--BackgroundColor--100, #fff));
- :host(:focus) & {
- --pf-v5-c-button--m-control--Color: var(--pf-v5-c-button--m-control--focus--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-control--BackgroundColor: var(--pf-v5-c-button--m-control--focus--BackgroundColor,
- var(--pf-global--BackgroundColor--100, #fff));
- --pf-v5-c-button--m-control--after--BorderBottomColor: var(--pf-v5-c-button--m-control--focus--after--BorderBottomColor,
- var(--pf-global--active-color--100, #06c));
- &::after {
- border-block-end-width: var(--pf-v5-c-button--m-control--focus--after--BorderBottomWidth,
- var(--pf-global--BorderWidth--md, 2px));
- }
- }
- :host(:hover) & {
- --pf-v5-c-button--m-control--Color: var(--pf-v5-c-button--m-control--hover--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-control--BackgroundColor: var(--pf-v5-c-button--m-control--hover--BackgroundColor,
- var(--pf-global--BackgroundColor--100, #fff));
- --pf-v5-c-button--m-control--after--BorderBottomColor: var(--pf-v5-c-button--m-control--hover--after--BorderBottomColor,
- var(--pf-global--active-color--100, #06c));
- &::after {
- border-block-end-width: var(--pf-v5-c-button--m-control--hover--after--BorderBottomWidth,
- var(--pf-global--BorderWidth--md, 2px));
- }
- }
- :host(:active) & {
- --pf-v5-c-button--m-control--Color: var(--pf-v5-c-button--m-control--active--Color,
- var(--pf-global--Color--100, #151515));
- --pf-v5-c-button--m-control--BackgroundColor: var(--pf-v5-c-button--m-control--active--BackgroundColor,
- var(--pf-global--BackgroundColor--100, #fff));
- --pf-v5-c-button--m-control--after--BorderBottomColor: var(--pf-v5-c-button--m-control--active--after--BorderBottomColor,
- var(--pf-global--active-color--100, #06c));
- &::after {
- border-block-end-width: var(--pf-v5-c-button--m-control--active--after--BorderBottomWidth,
- var(--pf-global--BorderWidth--md, 2px));
- }
- }
-}
-
-/******************************
- * *
- * LINK *
- * *
- ******************************/
-
-#button.link {
- --pf-v5-c-button--disabled--BackgroundColor: var(--pf-v5-c-button--m-link--disabled--BackgroundColor, transparent);
- --_button-color: var(--pf-v5-c-button--m-link--Color, var(--pf-global--link--Color, #06c));
- --_button-background-color: var(--pf-v5-c-button--m-link--BackgroundColor,
- var(--pf-v5-c-button--m-link--BackgroundColor, transparent));
- &.inline {
- :host(:hover) & {
- text-decoration: var(--pf-v5-c-button--m-link--m-inline--hover--TextDecoration,
- var(--pf-global--link--TextDecoration--hover, underline));
- }
- }
- &.danger {
- --pf-v5-c-button--m-danger--Color: var(--pf-v5-c-button--m-link--m-danger--Color,
- var(--pf-global--danger-color--100, #c9190b));
- --pf-v5-c-button--m-danger--BackgroundColor: var(--pf-v5-c-button--m-link--m-danger--BackgroundColor, transparent);
- :host(:hover) & {
- --pf-v5-c-button--m-link--m-danger--Color: var(--pf-v5-c-button--m-link--m-danger--hover--Color,
- var(--pf-global--danger-color--200, #a30000));
- --pf-v5-c-button--m-link--m-danger--BackgroundColor: var(--pf-v5-c-button--m-link--m-danger--hover--BackgroundColor, transparent);
- }
- :host(:focus) & {
- --pf-v5-c-button--m-link--m-danger--Color: var(--pf-v5-c-button--m-link--m-danger--focus--Color,
- var(--pf-global--danger-color--200, #a30000));
- --pf-v5-c-button--m-link--m-danger--BackgroundColor: var(--pf-v5-c-button--m-link--m-danger--focus--BackgroundColor, transparent);
- }
- :host(:active) & {
- --pf-v5-c-button--m-link--m-danger--Color: var(--pf-v5-c-button--m-link--m-danger--active--Color,
- var(--pf-global--danger-color--200, #a30000));
- --pf-v5-c-button--m-link--m-danger--BackgroundColor: var(--pf-v5-c-button--m-link--m-danger--active--BackgroundColor, transparent);
- }
- }
-}
-
-/******************************
- * *
- * DISABLED *
- * *
- ******************************/
-
-:host(:is(:disabled,[disabled])) {
- pointer-events: none;
- cursor: default;
-}
-
-#button.disabled {
- &:not(.plain) {
- --_button-color: var(--pf-v5-c-button--disabled--Color,
- var(--pf-global--disabled-color--100, #6a6e73));
- --_button-background-color: var(--pf-v5-c-button--disabled--BackgroundColor,
- var(--pf-global--disabled-color--200, #d2d2d2));
- }
- &::after {
- border-color: var(--pf-v5-c-button--disabled--after--BorderColor, transparent);
- }
-}
-
-/******************************
- * *
- * BLOCK *
- * *
- ******************************/
-
-:host([block]) {
- display: flex;
- width: 100%;
- justify-content: center;
-}
-
-/******************************
- * *
- * LARGE *
- * *
- ******************************/
-
-:host([size="large"]) {
- --pf-v5-c-button--PaddingTop: var(--pf-v5-c-button--m-display-lg--PaddingTop,
- var(--pf-global--spacer--md, 1rem));
- --pf-v5-c-button--PaddingRight: var(--pf-v5-c-button--m-display-lg--PaddingRight,
- var(--pf-global--spacer--xl, 2rem));
- --pf-v5-c-button--PaddingBottom: var(--pf-v5-c-button--m-display-lg--PaddingBottom,
- var(--pf-global--spacer--md, 1rem));
- --pf-v5-c-button--PaddingLeft: var(--pf-v5-c-button--m-display-lg--PaddingLeft,
- var(--pf-global--spacer--xl, 2rem));
- --pf-v5-c-button--FontWeight: var(--pf-v5-c-button--m-display-lg--FontWeight,
- var(--pf-global--FontWeight--bold, 700));
-}
-
-/******************************
- * *
- * SMALL *
- * *
- ******************************/
-
-:host([size="small"]) {
- --pf-v5-c-button--FontSize: var(--pf-v5-c-button--m-small--FontSize,
- var(--pf-global--FontSize--md, 1rem));
-}
-
-/******************************
- * *
- * DANGER *
- * *
- ******************************/
-
-#button.danger {
- --_button-color: var(--pf-v5-c-button--m-danger--Color,
- var(--pf-global--Color--light-100, #fff));
- --_button-background-color: var(--pf-v5-c-button--m-danger--BackgroundColor,
- var(--pf-global--danger-color--100, #c9190b));
-}
-
diff --git a/elements/pf-v5-button/pf-v5-button.ts b/elements/pf-v5-button/pf-v5-button.ts
deleted file mode 100644
index 3ebf87edb7..0000000000
--- a/elements/pf-v5-button/pf-v5-button.ts
+++ /dev/null
@@ -1,238 +0,0 @@
-import { LitElement, html, type TemplateResult } from 'lit';
-import { customElement } from 'lit/decorators/custom-element.js';
-import { property } from 'lit/decorators/property.js';
-import { ifDefined } from 'lit/directives/if-defined.js';
-import { classMap } from 'lit/directives/class-map.js';
-
-import { InternalsController } from '@patternfly/pfe-core/controllers/internals-controller.js';
-import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js';
-
-import '@patternfly/elements/pf-v5-icon/pf-v5-icon.js';
-import '@patternfly/elements/pf-v6-spinner/pf-v6-spinner.js';
-
-import tokensStyles from './pf-v5-button-tokens.css';
-import iconStyles from './pf-v5-button-icon.css';
-
-import styles from './pf-v5-button.css';
-
-export type ButtonVariant = (
- | 'primary'
- | 'secondary'
- | 'tertiary'
- | 'control'
- | 'link'
-);
-
-/**
- * A **button** is a box area or text that communicates and triggers user actions when
- * clicked or selected. Buttons can be used to communicate and immediately trigger
- * actions a user can take in an application, like submitting a form, canceling a
- * process, or creating a new object. Buttons can also be used to take a user to a
- * new location, like another page inside of a web application, or an external site
- * such as help or documentation..
- * @summary Allows users to perform an action when triggered
- * @alias Button
- * @attr {string} [loading-label='loading'] - ARIA label for the loading indicator
- */
-@customElement('pf-v5-button')
-export class PfV5Button extends LitElement {
- static readonly formAssociated = true;
-
- static readonly styles: CSSStyleSheet[] = [
- tokensStyles,
- iconStyles,
- styles,
- ];
-
- @property({ reflect: true }) type?: 'button' | 'submit' | 'reset';
-
- /** Accessible name for the button, use when the button does not have slotted text */
- @property() label?: string;
-
- /** Form value for the button */
- @property() value?: string;
-
- /** Form element name for the button */
- @property() name?: string;
-
- /** Disables the button */
- @property({ reflect: true, type: Boolean }) disabled = false;
-
- /** Represents the state of a stateful button */
- @property({ type: Boolean, reflect: true }) loading = false;
-
- /** Changes the size of the button. */
- @property({ reflect: true }) size?: 'small' | 'large';
-
- /** Not as urgent as danger */
- @property({ type: Boolean, reflect: true }) warning = false;
-
- /**
- * Use danger buttons for actions a user can take that are potentially
- * destructive or difficult/impossible to undo, like deleting or removing
- * user data.
- */
- @property({ type: Boolean, reflect: true }) danger = false;
-
- /** Applies plain styles */
- @property({ type: Boolean, reflect: true }) plain = false;
-
- /**
- * Changes the style of the button.
- * - Primary: Used for the most important call to action on a page. Try to
- * limit primary buttons to one per page.
- * - Secondary: Use secondary buttons for general actions on a page, that
- * donβt require as much emphasis as primary button actions. For example,
- * you can use secondary buttons where there are multiple actions, like in
- * toolbars or data lists.
- * - Tertiary: Tertiary buttons are flexible and can be used as needed.
- */
- @property({ reflect: true }) variant: ButtonVariant = 'primary';
-
- @property({ reflect: true, type: Boolean }) inline = false;
-
- @property({ reflect: true, type: Boolean }) block = false;
-
- /** Shorthand for the `icon` slot, the value is icon name */
- @property() icon?: string;
-
- /** Icon set for the `icon` property */
- @property({ attribute: 'icon-set' }) iconSet?: string;
-
- /** Store the URL Link */
- @property({ reflect: true }) href?: string;
-
- /** Redirecting the URL Link to new Tab */
- @property({ reflect: true }) target?: string;
-
- #internals = InternalsController.of(this, { role: this.variant === 'link' ? 'none' : 'button' });
-
- #slots = new SlotController(this, 'icon', null);
-
- get #disabled() {
- return this.disabled || this.#internals.formDisabled;
- }
-
- override connectedCallback(): void {
- super.connectedCallback();
- this.addEventListener('click', this.#onClick);
- this.addEventListener('keydown', this.#onKeydown);
- }
-
- protected override willUpdate(): void {
- this.#internals.ariaLabel = this.label || null;
- this.#internals.ariaDisabled = String(!!this.disabled);
- const isLink = this.variant === 'link' && this.href;
- if (isLink) {
- this.removeAttribute('tabindex');
- this.#internals.role = 'none';
- } else {
- this.tabIndex = 0;
- this.#internals.role = 'button';
- }
- }
-
- async formDisabledCallback(): Promise {
- await this.updateComplete;
- this.requestUpdate();
- }
-
- override render(): TemplateResult<1> {
- const hasIcon = !!this.icon || !!this.loading || this.#slots.hasSlotted('icon');
- const { warning, variant, danger, loading, plain, inline, block, size, href, target } = this;
-
- const disabled = this.#disabled;
-
- const content = html`
-
-
-
-
-
- `;
-
- if (variant === 'link' && href) {
- return html`
- ${content} `;
- } else {
- return html`
- ${content}
`;
- }
- }
-
- #onClick() {
- if (!this.#disabled) {
- switch (this.type) {
- case 'reset':
- return this.#internals.reset();
- default:
- return this.#internals.submit();
- }
- }
- }
-
- #onKeydown(event: KeyboardEvent) {
- switch (event.key) {
- case ' ':
- event.preventDefault();
- event.stopPropagation();
- if (this.dispatchEvent(new MouseEvent('click', {
- bubbles: true,
- cancelable: true,
- view: window,
- }))) {
- this.#onClick();
- }
- break;
- case 'Enter':
- if (this.dispatchEvent(new MouseEvent('click', {
- bubbles: true,
- cancelable: true,
- view: window,
- }))) {
- this.#onClick();
- }
- }
- }
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- 'pf-v5-button': PfV5Button;
- }
-}
diff --git a/elements/pf-v5-button/test/pf-button.e2e.ts b/elements/pf-v5-button/test/pf-button.e2e.ts
deleted file mode 100644
index f74a6ea00b..0000000000
--- a/elements/pf-v5-button/test/pf-button.e2e.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { test } from '@playwright/test';
-import { PfeDemoPage } from '@patternfly/pfe-tools/test/playwright/PfeDemoPage.js';
-import { SSRPage } from '@patternfly/pfe-tools/test/playwright/SSRPage.js';
-
-const tagName = 'pf-v5-button';
-
-test.describe(tagName, () => {
- test('snapshot', async ({ page }) => {
- const componentPage = new PfeDemoPage(page, tagName);
- await componentPage.navigate();
- await componentPage.snapshot();
- });
-
- test('ssr', async ({ browser }) => {
- const fixture = new SSRPage({
- tagName,
- browser,
- demoDir: new URL('../demo/', import.meta.url),
- importSpecifiers: [
- `@patternfly/elements/${tagName}/${tagName}.js`,
- ],
- });
- await fixture.snapshots();
- });
-});
diff --git a/elements/pf-v5-button/test/pf-button.spec.ts b/elements/pf-v5-button/test/pf-button.spec.ts
deleted file mode 100644
index e8648456f5..0000000000
--- a/elements/pf-v5-button/test/pf-button.spec.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import { expect, html } from '@open-wc/testing';
-import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js';
-import { sendKeys } from '@web/test-runner-commands';
-import { clickElementAtCenter } from '@patternfly/pfe-tools/test/utils.js';
-
-import { PfV5Button } from '@patternfly/elements/pf-v5-button/pf-v5-button.js';
-
-import '@patternfly/pfe-tools/test/stub-logger.js';
-
-function press(key: string) {
- return async function() {
- await sendKeys({ press: key });
- };
-}
-
-describe('', function() {
- it('imperatively instantiates', function() {
- expect(document.createElement('pf-v5-button')).to.be.an.instanceof(PfV5Button);
- });
-
- it('should upgrade', async function() {
- const el = await createFixture(html`Button `);
- expect(el, 'pf-v5-button should be an instance of PfV5Button')
- .to.be.an.instanceOf(customElements.get('pf-v5-button'))
- .and
- .to.be.an.instanceOf(PfV5Button);
- });
- describe('in a fieldset', function() {
- let element: PfV5Button;
- let fieldset: HTMLFieldSetElement;
- let form: HTMLFormElement;
- let submitEvent: SubmitEvent;
-
- beforeEach(async function() {
- form = await createFixture(html`
-
- `);
- fieldset = form.querySelector('fieldset')!;
- element = form.querySelector('pf-v5-button')!;
- form.querySelector('input')?.focus();
- form.addEventListener('submit', function(event) {
- event.preventDefault();
- submitEvent = event;
- });
- await element.updateComplete;
- });
-
- afterEach(function() {
- // @ts-expect-error: resetting fixture
- submitEvent = undefined;
- });
-
- describe('clicking the button', function() {
- beforeEach(() => clickElementAtCenter(element));
- it('submits the form', function() {
- expect(submitEvent).to.be.ok;
- });
- });
-
- describe('tabbing through', function() {
- beforeEach(press('Tab'));
- it('does focus the button', function() {
- expect(document.activeElement)
- .to
- .be.an.instanceof(PfV5Button);
- });
-
- describe('pressing Space', function() {
- beforeEach(press(' '));
- it('submits the form', function() {
- expect(submitEvent).to.be.ok;
- });
- });
-
- describe('pressing Enter', function() {
- beforeEach(press('Enter'));
- it('submits the form', function() {
- expect(submitEvent).to.be.ok;
- });
- });
- });
-
- describe('disabling the fieldset', function() {
- beforeEach(async function() {
- fieldset.disabled = true;
- await element.updateComplete;
- });
- it('disables the button', function() {
- expect(element.matches(':disabled'), 'matches :disabled').to.be.true;
- });
- describe('tabbing through', function() {
- beforeEach(press('Tab'));
- it('does not focus the button', function() {
- expect(document.activeElement)
- .to
- .not
- .be.an.instanceof(PfV5Button);
- });
- });
- // this was a regression spotted by @brianferry
- describe('then disabling the button', function() {
- beforeEach(async function() {
- element.disabled = true;
- await element.updateComplete;
- });
- describe('then enabling the button', function() {
- beforeEach(async function() {
- element.disabled = false;
- await element.updateComplete;
- });
- describe('then enabling the fieldset', function() {
- beforeEach(async function() {
- fieldset.disabled = false;
- await element.updateComplete;
- });
- describe('tabbing through', function() {
- beforeEach(press('Tab'));
- it('does focus the button', function() {
- expect(document.activeElement)
- .to
- .be.an.instanceof(PfV5Button);
- });
- });
- });
- });
- });
- });
- });
-});
diff --git a/elements/pf-v5-card/demo/header-images-and-actions.html b/elements/pf-v5-card/demo/header-images-and-actions.html
index edaeea341e..981da2b1fa 100644
--- a/elements/pf-v5-card/demo/header-images-and-actions.html
+++ b/elements/pf-v5-card/demo/header-images-and-actions.html
@@ -9,7 +9,7 @@
-
+
Action
Link
diff --git a/elements/pf-v5-card/demo/modifiers.html b/elements/pf-v5-card/demo/modifiers.html
index 85f9a21124..9c9f221f64 100644
--- a/elements/pf-v5-card/demo/modifiers.html
+++ b/elements/pf-v5-card/demo/modifiers.html
@@ -23,15 +23,15 @@
Lightest card
This is the lightest pf-v5-card and a link , and a visited link with border.
- Try
- Buy
+ Try
+ Buy
diff --git a/elements/pf-v5-tooltip/docs/pf-v5-tooltip.md b/elements/pf-v5-tooltip/docs/pf-v5-tooltip.md
index 2688f24a4b..de6dded0a4 100644
--- a/elements/pf-v5-tooltip/docs/pf-v5-tooltip.md
+++ b/elements/pf-v5-tooltip/docs/pf-v5-tooltip.md
@@ -3,7 +3,7 @@
{% renderOverview %}
### Default
- Tooltip
+ Tooltip
{% endrenderOverview %}
@@ -11,84 +11,84 @@
### Left Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Left-Start Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Left-End Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Right Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Right-Start Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Right-End Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Top Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Top-Start Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Top-End Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Bottom Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Bottom-Start Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
### Bottom-End Tooltip
{% htmlexample %}
- Tooltip
+ Tooltip
{% endhtmlexample %}
{% endband %}
diff --git a/elements/pf-v6-button/README.md b/elements/pf-v6-button/README.md
new file mode 100644
index 0000000000..8ad0a84f7d
--- /dev/null
+++ b/elements/pf-v6-button/README.md
@@ -0,0 +1,102 @@
+# Button
+
+A button communicates and triggers user actions when clicked or selected.
+
+## Usage
+
+### Basic button
+
+```html
+Primary
+Secondary
+```
+
+### Icon button
+
+```html
+
+
+
+```
+
+### Form submit
+
+```html
+
+```
+
+### Theming
+
+Override the same `--pf-v6-c-button--*` tokens as PatternFly CSS / React. For variant colors, prefer the `m-{variant}` tokens (variants assign those onto the shared surface tokens):
+
+```css
+pf-v6-button {
+ --pf-v6-c-button--BorderRadius: 0.25rem;
+ --pf-v6-c-button--m-primary--BackgroundColor: navy;
+ --pf-v6-c-button--m-primary--Color: white;
+}
+```
+
+Style shadow internals with parts:
+
+```css
+pf-v6-button::part(button) { /* surface */ }
+pf-v6-button::part(icon) { /* icon wrapper */ }
+pf-v6-button::part(text) { /* label wrapper */ }
+pf-v6-button::part(count) { /* count badge wrapper */ }
+pf-v6-button::part(progress) { /* spinner wrapper */ }
+```
+
+## Divergences from React `Button`
+
+### Not implemented
+
+| React prop | Notes |
+| ------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
+| `component` | Web components cannot change their host tag. Use `href` for anchors, or wrap the button in semantic HTML. |
+| `className` | Not needed with shadow DOM; style the host or `::part(button)`. |
+| `ouiaId` / `ouiaSafe` | OUIA helpers are React-specific. |
+| `inoperableEvents` | Aria-disabled blocks `click` activation; custom event lists are not exposed. |
+| `spinnerAriaLabelledBy` | Use `loading-label` or the spinner's `accessible-label`. |
+| `isCircle` / `isDocked` / `isTextExpanded` | Beta React APIs; omitted until design stabilizes. |
+| `innerRef` | Use a normal element reference to the host. |
+| `formaction` / `formenctype` / etc. | Not reliably supported on FACE submitters; use form-level attributes or a native submit control. |
+| `SubmitEvent.submitter` | Engines may reject FACE hosts as `requestSubmit(submitter)`; form still submits and `name`/`value` participate via `setFormValue`. |
+
+### Changed API
+
+| React prop | Web component | Difference |
+| ------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------ |
+| `isDisabled` | `disabled` | Dropped `is-` prefix. |
+| `isAriaDisabled` | `disabled-focusable` | Keeps the button focusable while blocking activation; sets `aria-disabled` via ElementInternals. |
+| `isLoading` | `loading` | Tri-state preserved: omit / `null` (off), `loading` / `true` (spinner), `loading="false"` (reserved progress padding). |
+| `isBlock` | `block` | Dropped `is-` prefix. |
+| `isInline` | `inline` | Dropped `is-` prefix. |
+| `isDanger` | `danger` | Dropped `is-` prefix. Applies to `secondary` and `link` variants. |
+| `isClicked` | `clicked` | Dropped `is-` prefix. (React renamed `isActive` β `isClicked`.) |
+| `isFavorite` / `isFavorited` | `favorite` / `favorited` | Dropped `is-` prefix. |
+| `isSettings` | `settings` | Dropped `is-` prefix. |
+| `isHamburger` / `isExpanded` | `hamburger` / `expanded` | Dropped `is-` prefix. |
+| `hasNoPadding` | `no-padding` | Dash-case boolean attribute. |
+| `aria-label` | `accessible-label` | Custom attribute; applied via ElementInternals. |
+| `icon` | `slot="icon"` or `icon` / `icon-set` | Prefer slotted icons. Optional shorthand renders ``. |
+| `iconPosition` | `icon-position` | `start` / `end`; accepts deprecated `left` / `right` aliases. |
+| `countOptions` | `slot="count"` | Slot a `` instead of an options object. |
+| `spinnerAriaLabel` / `spinnerAriaValueText` | `loading-label` | Reactive attribute/property for the spinner accessible name. |
+| `size="default"` | omit `size` | Default size is the absence of the attribute. |
+| `component="a"` + `href` | `href` / `target` | Renders an inner anchor when `variant="link"` and `href` are set. |
+| `type` default | omit / unset | Same as React: no form action until `type="submit"` or `type="reset"`. |
+
+### Added
+
+| Web component API | Notes |
+| ------------------------------------------------------ | -------------------------------------------------------------------------------------- |
+| Form association (`formAssociated`) | Host participates in forms like a native button; supports `type`, `name`, and `value`. |
+| `href` / `target` | Progressive-enhancement link rendering for `variant="link"`. |
+| `slot="icon"` / `slot="count"` | Composition slots for icons and count badges. |
+| `icon` / `icon-set` | Optional shorthand that renders `` in the icon slot. |
+| CSS parts `button`, `icon`, `text`, `count`, `progress` | Styling hooks for shadow internals. |
+| `--pf-v6-c-button--*` custom properties | Same component tokens as PatternFly CSS / React styles. |
diff --git a/elements/pf-v6-button/demo/block.html b/elements/pf-v6-button/demo/block.html
new file mode 100644
index 0000000000..939fa2b1e3
--- /dev/null
+++ b/elements/pf-v6-button/demo/block.html
@@ -0,0 +1,18 @@
+---
+name: Block level buttons
+description: Block level buttons span the full width of their parent when the block attribute is set.
+---
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/call-to-action.html b/elements/pf-v6-button/demo/call-to-action.html
new file mode 100644
index 0000000000..f0403b910e
--- /dev/null
+++ b/elements/pf-v6-button/demo/call-to-action.html
@@ -0,0 +1,38 @@
+---
+name: Call to action
+description: Primary, secondary, tertiary, and link buttons can use size="lg" for call-to-action styling.
+---
+
+
+ Call to action
+ Call to action
+ Call to action
+
+ Call to action
+
+
+
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/css-custom-properties.html b/elements/pf-v6-button/demo/css-custom-properties.html
new file mode 100644
index 0000000000..42810360a9
--- /dev/null
+++ b/elements/pf-v6-button/demo/css-custom-properties.html
@@ -0,0 +1,39 @@
+---
+name: CSS custom properties
+description: Theme the button with the same --pf-v6-c-button--* custom properties as PatternFly CSS, and target shadow parts.
+---
+
+
+ Themed primary
+ Themed secondary
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/disabled-focusable.html b/elements/pf-v6-button/demo/disabled-focusable.html
new file mode 100644
index 0000000000..bfbbf7f641
--- /dev/null
+++ b/elements/pf-v6-button/demo/disabled-focusable.html
@@ -0,0 +1,29 @@
+---
+name: Aria-disabled examples
+description: Disabled-focusable buttons stay focusable while blocking activation. Use them when a disabled control still needs a tooltip or other focus treatment.
+---
+
+
+ Primary
+ Secondary
+ Link
+ Link as anchor
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/disabled.html b/elements/pf-v6-button/demo/disabled.html
new file mode 100644
index 0000000000..2a99f559c7
--- /dev/null
+++ b/elements/pf-v6-button/demo/disabled.html
@@ -0,0 +1,63 @@
+---
+name: Disabled buttons
+description: Disable any button variant with the disabled attribute when the action is unavailable.
+---
+
+
+ Primary
+ Secondary
+ Danger secondary
+ Tertiary
+ Danger
+ Warning
+
+
+
+
+
+
+
+ Link
+
+ Inline link
+
+
+
+
+
+ Control
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/favorite.html b/elements/pf-v6-button/demo/favorite.html
new file mode 100644
index 0000000000..de3041b1b5
--- /dev/null
+++ b/elements/pf-v6-button/demo/favorite.html
@@ -0,0 +1,40 @@
+---
+name: Favorite
+description: Favorite buttons use the favorite attribute with variant="plain". Toggle favorited to update the filled star state.
+---
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/hamburger.html b/elements/pf-v6-button/demo/hamburger.html
new file mode 100644
index 0000000000..99469aea9c
--- /dev/null
+++ b/elements/pf-v6-button/demo/hamburger.html
@@ -0,0 +1,25 @@
+---
+name: Hamburger
+description: Hamburger buttons use the hamburger attribute. Set expanded and hamburger-variant to animate between expand and collapse.
+---
+
+
+
+
diff --git a/elements/pf-v6-button/demo/index.html b/elements/pf-v6-button/demo/index.html
new file mode 100644
index 0000000000..e73d3877f4
--- /dev/null
+++ b/elements/pf-v6-button/demo/index.html
@@ -0,0 +1,9 @@
+---
+name: Basic
+description: A button triggers an action when activated.
+---
+Primary
+
+
diff --git a/elements/pf-v6-button/demo/inline-span-link.html b/elements/pf-v6-button/demo/inline-span-link.html
new file mode 100644
index 0000000000..9b886eb6a6
--- /dev/null
+++ b/elements/pf-v6-button/demo/inline-span-link.html
@@ -0,0 +1,14 @@
+---
+name: Inline link
+description: Inline links use variant="link" with the inline attribute so they wrap with surrounding text.
+---
+
+
+ This is a
+ inline link button
+ in a sentence of text.
+
+
+
diff --git a/elements/pf-v6-button/demo/links.html b/elements/pf-v6-button/demo/links.html
new file mode 100644
index 0000000000..81ef63f3ed
--- /dev/null
+++ b/elements/pf-v6-button/demo/links.html
@@ -0,0 +1,55 @@
+---
+name: Links as buttons
+description: Buttons that navigate elsewhere can use href with primary, secondary, tertiary, or link variants.
+---
+
+
+ Primary link
+ Secondary link
+ Tertiary link
+
+ Link to PatternFly
+
+
+
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/plain-no-padding.html b/elements/pf-v6-button/demo/plain-no-padding.html
new file mode 100644
index 0000000000..34ce30fefb
--- /dev/null
+++ b/elements/pf-v6-button/demo/plain-no-padding.html
@@ -0,0 +1,26 @@
+---
+name: Plain with no padding
+description: Use no-padding with variant="plain" to place an icon button inline with text.
+---
+
+
+ Edit this value
+
+
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/progress.html b/elements/pf-v6-button/demo/progress.html
new file mode 100644
index 0000000000..3312e26b05
--- /dev/null
+++ b/elements/pf-v6-button/demo/progress.html
@@ -0,0 +1,61 @@
+---
+name: Progress indicators
+description: Set loading to show a progress spinner after the user starts an action. Use loading="false" to reserve progress padding without a spinner.
+---
+
+
+ Click to stop loading
+ Click to stop loading
+
+
+
+
+
+ Pause loading logs
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/settings.html b/elements/pf-v6-button/demo/settings.html
new file mode 100644
index 0000000000..ff0ed9c548
--- /dev/null
+++ b/elements/pf-v6-button/demo/settings.html
@@ -0,0 +1,30 @@
+---
+name: Settings
+description: Settings buttons use the settings attribute on plain or control variants and animate the gear icon on hover and focus.
+---
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/small.html b/elements/pf-v6-button/demo/small.html
new file mode 100644
index 0000000000..5ab9f8d17a
--- /dev/null
+++ b/elements/pf-v6-button/demo/small.html
@@ -0,0 +1,28 @@
+---
+name: Small buttons
+description: Primary, secondary, tertiary, danger, and warning buttons can use size="sm" to fit tight spaces.
+---
+
+
+ Primary
+ Secondary
+ Danger secondary
+ Tertiary
+ Danger
+ Warning
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/stateful.html b/elements/pf-v6-button/demo/stateful.html
new file mode 100644
index 0000000000..2ecccac755
--- /dev/null
+++ b/elements/pf-v6-button/demo/stateful.html
@@ -0,0 +1,65 @@
+---
+name: Stateful
+description: Stateful buttons communicate notification state with variant="stateful" and state set to read, unread, or attention.
+---
+
+
+
+
+
+
+ Read
+
+
+
+
+
+ Unread
+
+
+
+
+
+ Attention
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/types.html b/elements/pf-v6-button/demo/types.html
new file mode 100644
index 0000000000..31deadf578
--- /dev/null
+++ b/elements/pf-v6-button/demo/types.html
@@ -0,0 +1,38 @@
+---
+name: Button types
+description: Use type to control form behavior. Default is button (no form action). Use submit or reset for form actions.
+---
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/variant-examples.html b/elements/pf-v6-button/demo/variant-examples.html
new file mode 100644
index 0000000000..9ce55d487c
--- /dev/null
+++ b/elements/pf-v6-button/demo/variant-examples.html
@@ -0,0 +1,142 @@
+---
+name: Variant examples
+description: PatternFly supports several button styling variants for different scenarios. Assign a variant with the variant attribute.
+---
+
+
+ Primary
+ Secondary
+ Danger secondary
+ Tertiary
+ Danger
+ Warning
+
+
+
+
+
+
+
+ Link
+
+
+ Link
+
+
+
+
+ Inline link
+ Danger link
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Stateful read
+
+
+
+
+
+ Stateful unread
+
+
+
+
+
+ Stateful attention
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/demo/with-count.html b/elements/pf-v6-button/demo/with-count.html
new file mode 100644
index 0000000000..509b9a354e
--- /dev/null
+++ b/elements/pf-v6-button/demo/with-count.html
@@ -0,0 +1,33 @@
+---
+name: Button with count
+description: Slot a badge into count to show a numeric value beside the button label.
+---
+
+
+
+ Issues
+ 7
+
+
+ Issues
+ 7
+
+
+ Issues
+ 7
+
+
+
+
+
+
diff --git a/elements/pf-v6-button/docs/pf-v6-button.md b/elements/pf-v6-button/docs/pf-v6-button.md
new file mode 100644
index 0000000000..553e381e59
--- /dev/null
+++ b/elements/pf-v6-button/docs/pf-v6-button.md
@@ -0,0 +1,44 @@
+{% renderOverview %}
+ A button communicates and triggers user actions when clicked or selected.
+
+ Primary
+ Secondary
+{% endrenderOverview %}
+
+{% band header="Usage" %}
+ ### Variants
+ {% htmlexample %}
+ Primary
+ Secondary
+ Tertiary
+ Danger
+ Warning
+ Link
+ {% endhtmlexample %}
+
+ ### Disabled
+ {% htmlexample %}
+ Disabled
+ Disabled focusable
+ {% endhtmlexample %}
+
+ ### Form submit
+ {% htmlexample %}
+
+ {% endhtmlexample %}
+{% endband %}
+
+{% renderSlots %}{% endrenderSlots %}
+
+{% renderAttributes %}{% endrenderAttributes %}
+
+{% renderMethods %}{% endrenderMethods %}
+
+{% renderEvents %}{% endrenderEvents %}
+
+{% renderCssCustomProperties %}{% endrenderCssCustomProperties %}
+
+{% renderCssParts %}{% endrenderCssParts %}
diff --git a/elements/pf-v6-button/docs/screenshot.png b/elements/pf-v6-button/docs/screenshot.png
new file mode 100644
index 0000000000..9ac8d8fdb6
Binary files /dev/null and b/elements/pf-v6-button/docs/screenshot.png differ
diff --git a/elements/pf-v6-button/pf-v6-button.css b/elements/pf-v6-button/pf-v6-button.css
new file mode 100644
index 0000000000..d2de54df3a
--- /dev/null
+++ b/elements/pf-v6-button/pf-v6-button.css
@@ -0,0 +1,1038 @@
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+:where(button) {
+ margin: 0;
+ font-family: inherit;
+ font-size: 100%;
+ line-height: var(--pf-t--global--font--line-height--body, 1.5);
+ color: var(--pf-t--global--text--color--regular, #151515);
+ cursor: pointer;
+}
+
+:host {
+ color-scheme: light dark;
+
+
+ /* Base button variables */
+ --pf-v6-c-button--Display: inline-flex;
+ --pf-v6-c-button--AlignItems: baseline;
+ --pf-v6-c-button--JustifyContent: center;
+ --pf-v6-c-button--Gap: var(--pf-t--global--spacer--gap--text-to-element--default, 0.5rem);
+ --pf-v6-c-button--MinWidth: calc(1em * var(--pf-v6-c-button--LineHeight) + var(--pf-v6-c-button--PaddingBlockStart) + var(--pf-v6-c-button--PaddingBlockEnd));
+ --pf-v6-c-button--PaddingBlockStart: var(--pf-t--global--spacer--control--vertical--default, 0.5rem);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-t--global--spacer--action--horizontal--default, 1.5rem);
+ --pf-v6-c-button--PaddingBlockEnd: var(--pf-t--global--spacer--control--vertical--default, 0.5rem);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-t--global--spacer--action--horizontal--default, 1.5rem);
+ --pf-v6-c-button--Color: var(--pf-t--global--text--color--regular, #151515);
+ --pf-v6-c-button--LineHeight: var(--pf-t--global--font--line-height--body, 1.5);
+ --pf-v6-c-button--FontWeight: var(--pf-t--global--font--weight--body--default, 400);
+ --pf-v6-c-button--FontSize: var(--pf-t--global--font--size--body--default, 0.875rem);
+ --pf-v6-c-button--BackgroundColor: transparent;
+ --pf-v6-c-button--BorderColor: transparent;
+ --pf-v6-c-button--BorderWidth: var(--pf-t--global--border--width--action--default, 1px);
+ --pf-v6-c-button--BorderRadius: var(--pf-t--global--border--radius--pill, 999px);
+ --pf-v6-c-button--TextDecorationLine: none;
+ --pf-v6-c-button--TextDecorationStyle: none;
+ --pf-v6-c-button--TextDecorationColor: currentcolor;
+ --pf-v6-c-button--TransitionDelay: 0s;
+ --pf-v6-c-button--TransitionDuration: var(--pf-t--global--motion--duration--fade--default);
+ --pf-v6-c-button--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--accelerate);
+ --pf-v6-c-button--TransitionProperty: color, background, border-color;
+ --pf-v6-c-button--ScaleX: 1;
+ --pf-v6-c-button--ScaleY: 1;
+ --pf-v6-c-button--border--offset: 0;
+
+ /* Hover */
+ --pf-v6-c-button--hover--BackgroundColor: transparent;
+ --pf-v6-c-button--hover--BorderColor: transparent;
+ --pf-v6-c-button--hover--BorderWidth: var(--pf-t--global--border--width--action--hover);
+ --pf-v6-c-button--hover--TextDecorationLine: none;
+ --pf-v6-c-button--hover--TextDecorationStyle: none;
+ --pf-v6-c-button--hover--TextDecorationColor: currentcolor;
+ --pf-v6-c-button--hover--ScaleX: 1;
+ --pf-v6-c-button--hover--ScaleY: 1;
+
+ /* Clicked */
+ --pf-v6-c-button--m-clicked--BackgroundColor: transparent;
+ --pf-v6-c-button--m-clicked--BorderColor: transparent;
+ --pf-v6-c-button--m-clicked--BorderWidth: var(--pf-t--global--border--width--action--clicked);
+
+ /* Primary */
+ --pf-v6-c-button--m-primary--Color: var(--pf-t--global--text--color--on-brand--default, #ffffff);
+ --pf-v6-c-button--m-primary--BackgroundColor: var(--pf-t--global--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-primary__icon--Color: var(--pf-t--global--icon--color--on-brand--default, #ffffff);
+ --pf-v6-c-button--m-primary--hover--Color: var(--pf-t--global--text--color--on-brand--hover, #ffffff);
+ --pf-v6-c-button--m-primary--hover--BackgroundColor: var(--pf-t--global--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-primary--hover__icon--Color: var(--pf-t--global--icon--color--on-brand--hover, #ffffff);
+ --pf-v6-c-button--m-primary--m-clicked--Color: var(--pf-t--global--text--color--on-brand--clicked, #ffffff);
+ --pf-v6-c-button--m-primary--m-clicked--BackgroundColor: var(--pf-t--global--color--brand--clicked, #004d99);
+ --pf-v6-c-button--m-primary--m-clicked__icon--Color: var(--pf-t--global--icon--color--on-brand--clicked, #ffffff);
+
+ /* Secondary */
+ --pf-v6-c-button--m-secondary--Color: var(--pf-t--global--text--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-secondary--BorderColor: var(--pf-t--global--border--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-secondary--TransitionDuration: var(--pf-t--global--motion--duration--fade--short);
+ --pf-v6-c-button--m-secondary__icon--Color: var(--pf-t--global--icon--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-secondary--hover--Color: var(--pf-t--global--text--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-secondary--hover--BorderColor: var(--pf-t--global--border--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-secondary--hover__icon--Color: var(--pf-t--global--icon--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-secondary--m-clicked--Color: var(--pf-t--global--text--color--brand--clicked, #004d99);
+ --pf-v6-c-button--m-secondary--m-clicked--BorderColor: var(--pf-t--global--border--color--brand--clicked, #004d99);
+ --pf-v6-c-button--m-secondary--m-clicked__icon--Color: var(--pf-t--global--icon--color--brand--clicked, #004d99);
+ --pf-v6-c-button--m-secondary--m-danger--Color: var(--pf-t--global--text--color--status--danger--default, #b1380b);
+ --pf-v6-c-button--m-secondary--m-danger--BorderColor: var(--pf-t--global--border--color--status--danger--default, #b1380b);
+ --pf-v6-c-button--m-secondary--m-danger__icon--Color: var(--pf-t--global--icon--color--status--danger--default, #b1380b);
+ --pf-v6-c-button--m-secondary--m-danger--hover--Color: var(--pf-t--global--text--color--status--danger--hover, #731f00);
+ --pf-v6-c-button--m-secondary--m-danger--hover--BorderColor: var(--pf-t--global--border--color--status--danger--hover, #731f00);
+ --pf-v6-c-button--m-secondary--m-danger--hover__icon--Color: var(--pf-t--global--icon--color--status--danger--hover, #731f00);
+ --pf-v6-c-button--m-secondary--m-danger--m-clicked--Color: var(--pf-t--global--text--color--status--danger--clicked, #731f00);
+ --pf-v6-c-button--m-secondary--m-danger--m-clicked--BorderColor: var(--pf-t--global--border--color--status--danger--clicked, #731f00);
+ --pf-v6-c-button--m-secondary--m-danger--m-clicked__icon--Color: var(--pf-t--global--icon--color--status--danger--clicked, #731f00);
+
+ /* Tertiary */
+ --pf-v6-c-button--m-tertiary--Color: var(--pf-t--global--text--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-tertiary--BorderColor: var(--pf-t--global--border--color--default);
+ --pf-v6-c-button--m-tertiary--TransitionDuration: var(--pf-t--global--motion--duration--fade--short);
+ --pf-v6-c-button--m-tertiary__icon--Color: var(--pf-t--global--icon--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-tertiary--hover--Color: var(--pf-t--global--text--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-tertiary--hover--BorderColor: var(--pf-t--global--border--color--hover);
+ --pf-v6-c-button--m-tertiary--hover__icon--Color: var(--pf-t--global--icon--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-tertiary--m-clicked--Color: var(--pf-t--global--text--color--brand--clicked, #004d99);
+ --pf-v6-c-button--m-tertiary--m-clicked--BorderColor: var(--pf-t--global--border--color--clicked);
+ --pf-v6-c-button--m-tertiary--m-clicked__icon--Color: var(--pf-t--global--icon--color--brand--clicked, #004d99);
+
+ /* Link */
+ --pf-v6-c-button--m-link--BorderRadius: var(--pf-t--global--border--radius--small, 6px);
+ --pf-v6-c-button--m-link--PaddingInlineEnd: var(--pf-t--global--spacer--action--horizontal--plain--default, 0.5rem);
+ --pf-v6-c-button--m-link--PaddingInlineStart: var(--pf-t--global--spacer--action--horizontal--plain--default, 0.5rem);
+ --pf-v6-c-button--m-link--Color: var(--pf-t--global--text--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-link--BackgroundColor: var(--pf-t--global--background--color--action--plain--default, rgb(255 255 255 / 0%));
+ --pf-v6-c-button--m-link__icon--Color: var(--pf-t--global--icon--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-link--hover--Color: var(--pf-t--global--text--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-link--hover--BackgroundColor: var(--pf-t--global--background--color--action--plain--hover, rgb(0 0 0 / 8%));
+ --pf-v6-c-button--m-link--hover__icon--Color: var(--pf-t--global--text--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-link--m-clicked--Color: var(--pf-t--global--text--color--brand--clicked, #004d99);
+ --pf-v6-c-button--m-link--m-clicked--BackgroundColor: var(--pf-t--global--background--color--action--plain--clicked, rgb(0 0 0 / 16%));
+ --pf-v6-c-button--m-link--m-clicked__icon--Color: var(--pf-t--global--text--color--brand--clicked, #004d99);
+ --pf-v6-c-button--m-link--m-small--PaddingInlineEnd: var(--pf-t--global--spacer--action--horizontal--plain--compact, 0.25rem);
+ --pf-v6-c-button--m-link--m-small--PaddingInlineStart: var(--pf-t--global--spacer--action--horizontal--plain--compact, 0.25rem);
+ --pf-v6-c-button--m-link--BorderWidth: var(--pf-t--global--border--width--action--plain--default, 0px);
+ --pf-v6-c-button--m-link--m-clicked--BorderWidth: var(--pf-t--global--border--width--action--plain--clicked, 0px);
+ --pf-v6-c-button--m-link--hover--BorderWidth: var(--pf-t--global--border--width--action--plain--hover, 0px);
+ --pf-v6-c-button--m-link--BorderColor: var(--pf-t--global--border--color--high-contrast, rgb(255 255 255 / 0%));
+ --pf-v6-c-button--m-link--m-clicked--BorderColor: var(--pf-t--global--border--color--high-contrast, rgb(255 255 255 / 0%));
+ --pf-v6-c-button--m-link--hover--BorderColor: var(--pf-t--global--border--color--high-contrast, rgb(255 255 255 / 0%));
+
+ /* Link danger */
+ --pf-v6-c-button--m-link--m-danger--Color: var(--pf-t--global--text--color--status--danger--default, #b1380b);
+ --pf-v6-c-button--m-link--m-danger--BackgroundColor: var(--pf-t--global--background--color--action--plain--default, rgb(255 255 255 / 0%));
+ --pf-v6-c-button--m-link--m-danger__icon--Color: var(--pf-t--global--text--color--status--danger--default, #b1380b);
+ --pf-v6-c-button--m-link--m-danger--hover--Color: var(--pf-t--global--text--color--status--danger--hover, #731f00);
+ --pf-v6-c-button--m-link--m-danger--hover--BackgroundColor: var(--pf-t--global--background--color--action--plain--hover, rgb(0 0 0 / 8%));
+ --pf-v6-c-button--m-link--m-danger--hover__icon--Color: var(--pf-t--global--text--color--status--danger--hover, #731f00);
+ --pf-v6-c-button--m-link--m-danger--m-clicked--Color: var(--pf-t--global--text--color--status--danger--clicked, #731f00);
+ --pf-v6-c-button--m-link--m-danger--m-clicked--BackgroundColor: var(--pf-t--global--background--color--action--plain--clicked, rgb(0 0 0 / 16%));
+ --pf-v6-c-button--m-link--m-danger--m-clicked__icon--Color: var(--pf-t--global--text--color--status--danger--clicked, #731f00);
+
+ /* Link inline */
+ --pf-v6-c-button--m-link--m-inline--Display: inline-flex;
+ --pf-v6-c-button--m-link--m-inline--JustifyContent: flex-start;
+ --pf-v6-c-button--m-link--m-inline--FontSize: initial;
+ --pf-v6-c-button--m-link--m-inline--LineHeight: initial;
+ --pf-v6-c-button--m-link--m-inline--FontWeight: initial;
+ --pf-v6-c-button--m-link--m-inline--PaddingBlockStart: 0;
+ --pf-v6-c-button--m-link--m-inline--PaddingInlineEnd: 0;
+ --pf-v6-c-button--m-link--m-inline--PaddingBlockEnd: 0;
+ --pf-v6-c-button--m-link--m-inline--PaddingInlineStart: 0;
+ --pf-v6-c-button--m-link--m-inline--TextDecorationLine: var(--pf-t--global--text-decoration--link--line--default);
+ --pf-v6-c-button--m-link--m-inline--TextDecorationStyle: var(--pf-t--global--text-decoration--link--style--default);
+ --pf-v6-c-button--m-link--m-inline--hover--TextDecorationLine: var(--pf-t--global--text-decoration--link--line--hover);
+ --pf-v6-c-button--m-link--m-inline--hover--TextDecorationStyle: var(--pf-t--global--text-decoration--link--style--hover);
+ --pf-v6-c-button--m-link--m-inline__progress--InsetInlineStart: var(--pf-t--global--spacer--xs, 0.25rem);
+ --pf-v6-c-button--m-link--m-inline--m-in-progress--PaddingInlineStart: calc(var(--pf-v6-c-button--m-link--m-inline__progress--InsetInlineStart) + 1rem + var(--pf-t--global--spacer--sm, 0.5rem));
+ --pf-v6-c-button--m-link--m-inline--disabled--Color: var(--pf-t--global--text--color--disabled);
+ --pf-v6-c-button--m-link--m-inline--disabled__icon--Color: var(--pf-t--global--icon--color--disabled);
+ --pf-v6-c-button--span--m-link--m-inline--Display: inline;
+ --pf-v6-c-button--span--m-link--m-inline__icon--m-start--MarginInlineEnd: var(--pf-t--global--spacer--gap--text-to-element--default, 0.5rem);
+ --pf-v6-c-button--span--m-link--m-inline__icon--m-end--MarginInlineStart: var(--pf-t--global--spacer--gap--text-to-element--default, 0.5rem);
+ --pf-v6-c-button--m-link--m-inline--Color: var(--pf-t--global--text--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-link--m-inline__icon--Color: var(--pf-t--global--icon--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-link--m-inline--TextDecorationColor: currentcolor;
+ --pf-v6-c-button--m-link--m-inline--hover--Color: var(--pf-t--global--text--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-link--m-inline--hover__icon--Color: var(--pf-t--global--icon--color--brand--hover, #004d99);
+ --pf-v6-c-button--m-link--m-inline--hover--TextDecorationColor: currentcolor;
+
+ /* Plain */
+ --pf-v6-c-button--m-plain--BorderRadius: var(--pf-t--global--border--radius--small, 6px);
+ --pf-v6-c-button--m-plain--PaddingInlineEnd: var(--pf-t--global--spacer--action--horizontal--plain--default, 0.5rem);
+ --pf-v6-c-button--m-plain--PaddingInlineStart: var(--pf-t--global--spacer--action--horizontal--plain--default, 0.5rem);
+ --pf-v6-c-button--m-plain--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-plain__icon--Color: var(--pf-t--global--text--color--regular, #151515);
+ --pf-v6-c-button--m-plain--BackgroundColor: var(--pf-t--global--background--color--action--plain--default, rgb(255 255 255 / 0%));
+ --pf-v6-c-button--m-plain--hover--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-plain--hover--BackgroundColor: var(--pf-t--global--background--color--action--plain--hover, rgb(0 0 0 / 8%));
+ --pf-v6-c-button--m-plain--m-clicked--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-plain--m-clicked--BackgroundColor: var(--pf-t--global--background--color--action--plain--clicked, rgb(0 0 0 / 16%));
+ --pf-v6-c-button--m-plain--disabled--Color: var(--pf-t--global--text--color--disabled);
+ --pf-v6-c-button--m-plain--disabled__icon--Color: var(--pf-t--global--icon--color--disabled);
+ --pf-v6-c-button--m-plain--disabled--BackgroundColor: transparent;
+ --pf-v6-c-button--m-plain--m-small--PaddingInlineEnd: var(--pf-t--global--spacer--action--horizontal--plain--compact, 0.25rem);
+ --pf-v6-c-button--m-plain--m-small--PaddingInlineStart: var(--pf-t--global--spacer--action--horizontal--plain--compact, 0.25rem);
+ --pf-v6-c-button--m-plain--BorderWidth: var(--pf-t--global--border--width--action--plain--default, 0px);
+ --pf-v6-c-button--m-plain--m-clicked--BorderWidth: var(--pf-t--global--border--width--action--plain--clicked, 0px);
+ --pf-v6-c-button--m-plain--hover--BorderWidth: var(--pf-t--global--border--width--action--plain--hover, 0px);
+ --pf-v6-c-button--m-plain--BorderColor: transparent;
+ --pf-v6-c-button--m-plain--m-clicked--BorderColor: var(--pf-t--global--border--color--high-contrast, rgb(255 255 255 / 0%));
+ --pf-v6-c-button--m-plain--hover--BorderColor: var(--pf-t--global--border--color--high-contrast, rgb(255 255 255 / 0%));
+
+ /* Plain no padding */
+ --pf-v6-c-button--m-plain--m-no-padding--MinWidth: auto;
+ --pf-v6-c-button--m-plain--m-no-padding--PaddingBlockStart: 0;
+ --pf-v6-c-button--m-plain--m-no-padding--PaddingInlineEnd: 0;
+ --pf-v6-c-button--m-plain--m-no-padding--PaddingBlockEnd: 0;
+ --pf-v6-c-button--m-plain--m-no-padding--PaddingInlineStart: 0;
+ --pf-v6-c-button--m-plain--m-no-padding--m-small--PaddingInlineStart: 0;
+ --pf-v6-c-button--m-plain--m-no-padding--m-small--PaddingInlineEnd: 0;
+ --pf-v6-c-button--m-plain--m-no-padding__icon--Color: var(--pf-t--global--icon--color--subtle);
+ --pf-v6-c-button--m-plain--m-no-padding--BackgroundColor: transparent;
+ --pf-v6-c-button--m-plain--m-no-padding--hover__icon--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-plain--m-no-padding--hover--BackgroundColor: transparent;
+ --pf-v6-c-button--m-plain--m-no-padding--m-clicked--BackgroundColor: transparent;
+ --pf-v6-c-button--m-plain--m-no-padding--border--offset: -0.125rem;
+
+ /* Control */
+ --pf-v6-c-button--m-control--BorderRadius: var(--pf-t--global--border--radius--small, 6px);
+ --pf-v6-c-button--m-control--PaddingInlineStart: var(--pf-t--global--spacer--control--horizontal--default);
+ --pf-v6-c-button--m-control--PaddingInlineEnd: var(--pf-t--global--spacer--control--horizontal--default);
+ --pf-v6-c-button--m-control--Color: var(--pf-t--global--text--color--regular, #151515);
+ --pf-v6-c-button--m-control--BackgroundColor: var(--pf-t--global--background--color--control--default, #ffffff);
+ --pf-v6-c-button--m-control--BorderColor: var(--pf-t--global--border--color--default);
+ --pf-v6-c-button--m-control--BorderWidth: var(--pf-t--global--border--width--control--default, 1px);
+ --pf-v6-c-button--m-control__icon--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-control--hover--Color: var(--pf-t--global--text--color--regular, #151515);
+ --pf-v6-c-button--m-control--hover--BackgroundColor: var(--pf-t--global--background--color--control--default, #ffffff);
+ --pf-v6-c-button--m-control--hover--BorderColor: var(--pf-t--global--border--color--hover);
+ --pf-v6-c-button--m-control--hover--BorderWidth: var(--pf-t--global--border--width--control--hover, 2px);
+ --pf-v6-c-button--m-control--hover__icon--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-control--m-clicked--Color: var(--pf-t--global--text--color--regular, #151515);
+ --pf-v6-c-button--m-control--m-clicked--BackgroundColor: var(--pf-t--global--background--color--control--default, #ffffff);
+ --pf-v6-c-button--m-control--m-clicked--BorderColor: var(--pf-t--global--border--color--clicked);
+ --pf-v6-c-button--m-control--m-clicked--BorderWidth: var(--pf-t--global--border--width--control--clicked, 2px);
+ --pf-v6-c-button--m-control--m-clicked__icon--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-control--m-small--PaddingInlineEnd: var(--pf-t--global--spacer--control--horizontal--compact);
+ --pf-v6-c-button--m-control--m-small--PaddingInlineStart: var(--pf-t--global--spacer--control--horizontal--compact);
+
+ /* Stateful */
+ --pf-v6-c-button--m-stateful--BorderRadius: var(--pf-t--global--border--radius--small, 6px);
+ --pf-v6-c-button--m-stateful--PaddingInlineStart: var(--pf-t--global--spacer--control--horizontal--default);
+ --pf-v6-c-button--m-stateful--PaddingInlineEnd: var(--pf-t--global--spacer--control--horizontal--default);
+ --pf-v6-c-button--m-stateful--m-small--PaddingInlineEnd: var(--pf-t--global--spacer--control--horizontal--compact);
+ --pf-v6-c-button--m-stateful--m-small--PaddingInlineStart: var(--pf-t--global--spacer--control--horizontal--compact);
+
+ /* Read */
+ --pf-v6-c-button--m-read--BackgroundColor: var(--pf-t--global--background--color--control--default, #ffffff);
+ --pf-v6-c-button--m-read--BorderColor: var(--pf-t--global--border--color--default);
+ --pf-v6-c-button--m-read--hover--BackgroundColor: var(--pf-t--global--background--color--control--default, #ffffff);
+ --pf-v6-c-button--m-read--hover--BorderColor: var(--pf-t--global--border--color--hover);
+ --pf-v6-c-button--m-read--m-clicked--BackgroundColor: var(--pf-t--global--background--color--control--default, #ffffff);
+ --pf-v6-c-button--m-read--m-clicked--BorderColor: var(--pf-t--global--border--color--clicked);
+
+ /* Unread */
+ --pf-v6-c-button--m-unread--Color: var(--pf-t--global--text--color--status--unread--on-default--default);
+ --pf-v6-c-button--m-unread--BackgroundColor: var(--pf-t--global--color--status--unread--default, #0066cc);
+ --pf-v6-c-button--m-unread__icon--Color: var(--pf-t--global--icon--color--status--unread--on-default--default);
+ --pf-v6-c-button--m-unread--hover--Color: var(--pf-t--global--text--color--status--unread--on-default--hover);
+ --pf-v6-c-button--m-unread--hover--BackgroundColor: var(--pf-t--global--color--status--unread--hover, #004d99);
+ --pf-v6-c-button--m-unread--hover__icon--Color: var(--pf-t--global--icon--color--status--unread--on-default--hover);
+ --pf-v6-c-button--m-unread--m-clicked--Color: var(--pf-t--global--text--color--status--unread--on-default--clicked);
+ --pf-v6-c-button--m-unread--m-clicked--BackgroundColor: var(--pf-t--global--color--status--unread--clicked, #004d99);
+ --pf-v6-c-button--m-unread--m-clicked__icon--Color: var(--pf-t--global--icon--color--status--unread--on-default--clicked);
+
+ /* Attention */
+ --pf-v6-c-button--m-attention--Color: var(--pf-t--global--text--color--status--unread--on-attention--default);
+ --pf-v6-c-button--m-attention--BackgroundColor: var(--pf-t--global--color--status--unread--attention--default);
+ --pf-v6-c-button--m-attention__icon--Color: var(--pf-t--global--icon--color--status--unread--on-attention--default);
+ --pf-v6-c-button--m-attention--hover--Color: var(--pf-t--global--text--color--status--unread--on-attention--hover);
+ --pf-v6-c-button--m-attention--hover--BackgroundColor: var(--pf-t--global--color--status--unread--attention--hover);
+ --pf-v6-c-button--m-attention--hover__icon--Color: var(--pf-t--global--icon--color--status--unread--on-attention--hover);
+ --pf-v6-c-button--m-attention--m-clicked--Color: var(--pf-t--global--text--color--status--unread--on-attention--clicked);
+ --pf-v6-c-button--m-attention--m-clicked--BackgroundColor: var(--pf-t--global--color--status--unread--attention--clicked);
+ --pf-v6-c-button--m-attention--m-clicked__icon--Color: var(--pf-t--global--icon--color--status--unread--on-attention--clicked);
+
+ /* Warning */
+ --pf-v6-c-button--m-warning--Color: var(--pf-t--global--text--color--status--on-warning--default, #151515);
+ --pf-v6-c-button--m-warning--BackgroundColor: var(--pf-t--global--color--status--warning--default, #ffcc17);
+ --pf-v6-c-button--m-warning__icon--Color: var(--pf-t--global--icon--color--status--on-warning--default, #151515);
+ --pf-v6-c-button--m-warning--hover--Color: var(--pf-t--global--text--color--status--on-warning--hover, #151515);
+ --pf-v6-c-button--m-warning--hover--BackgroundColor: var(--pf-t--global--color--status--warning--hover, #dca614);
+ --pf-v6-c-button--m-warning--hover__icon--Color: var(--pf-t--global--icon--color--status--on-warning--hover, #151515);
+ --pf-v6-c-button--m-warning--m-clicked--Color: var(--pf-t--global--text--color--status--on-warning--clicked, #151515);
+ --pf-v6-c-button--m-warning--m-clicked--BackgroundColor: var(--pf-t--global--color--status--warning--clicked, #dca614);
+ --pf-v6-c-button--m-warning--m-clicked__icon--Color: var(--pf-t--global--icon--color--status--on-warning--clicked, #151515);
+
+ /* Danger */
+ --pf-v6-c-button--m-danger--Color: var(--pf-t--global--text--color--status--on-danger--default, #ffffff);
+ --pf-v6-c-button--m-danger--BackgroundColor: var(--pf-t--global--color--status--danger--default, #b1380b);
+ --pf-v6-c-button--m-danger__icon--Color: var(--pf-t--global--icon--color--status--on-danger--default, #ffffff);
+ --pf-v6-c-button--m-danger--hover--Color: var(--pf-t--global--text--color--status--on-danger--hover, #ffffff);
+ --pf-v6-c-button--m-danger--hover--BackgroundColor: var(--pf-t--global--color--status--danger--hover, #731f00);
+ --pf-v6-c-button--m-danger--hover__icon--Color: var(--pf-t--global--icon--color--status--on-danger--hover, #ffffff);
+ --pf-v6-c-button--m-danger--m-clicked--Color: var(--pf-t--global--text--color--status--on-danger--clicked, #ffffff);
+ --pf-v6-c-button--m-danger--m-clicked--BackgroundColor: var(--pf-t--global--color--status--danger--clicked, #731f00);
+ --pf-v6-c-button--m-danger--m-clicked__icon--Color: var(--pf-t--global--icon--color--status--on-danger--clicked, #ffffff);
+
+ /* Display lg (CTA) */
+ --pf-v6-c-button--m-display-lg--PaddingBlockStart: var(--pf-t--global--spacer--control--vertical--spacious);
+ --pf-v6-c-button--m-display-lg--PaddingInlineEnd: var(--pf-t--global--spacer--action--horizontal--spacious, 2rem);
+ --pf-v6-c-button--m-display-lg--PaddingBlockEnd: var(--pf-t--global--spacer--control--vertical--spacious);
+ --pf-v6-c-button--m-display-lg--PaddingInlineStart: var(--pf-t--global--spacer--action--horizontal--spacious, 2rem);
+ --pf-v6-c-button--m-display-lg--FontWeight: var(--pf-t--global--font--weight--body--bold);
+ --pf-v6-c-button--m-link--m-display-lg--FontSize: var(--pf-t--global--font--size--body--lg);
+
+ /* Small */
+ --pf-v6-c-button--m-small--PaddingBlockStart: var(--pf-t--global--spacer--control--vertical--compact);
+ --pf-v6-c-button--m-small--PaddingInlineEnd: var(--pf-t--global--spacer--action--horizontal--compact, 1rem);
+ --pf-v6-c-button--m-small--PaddingBlockEnd: var(--pf-t--global--spacer--control--vertical--compact);
+ --pf-v6-c-button--m-small--PaddingInlineStart: var(--pf-t--global--spacer--action--horizontal--compact, 1rem);
+
+ /* Disabled */
+ --pf-v6-c-button--disabled--Color: var(--pf-t--global--text--color--on-disabled, #6a6e73);
+ --pf-v6-c-button--disabled--BackgroundColor: var(--pf-t--global--background--color--disabled--default, #d2d2d2);
+ --pf-v6-c-button--disabled--TextDecorationColor: currentcolor;
+ --pf-v6-c-button--disabled--BorderColor: transparent;
+ --pf-v6-c-button--disabled__icon--Color: var(--pf-t--global--icon--color--on-disabled, #6a6e73);
+
+ /* Icon */
+ --pf-v6-c-button__icon--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-t--global--icon--color--regular, #151515);
+ --pf-v6-c-button__icon--MarginInlineStart: 0;
+ --pf-v6-c-button__icon--MarginInlineEnd: 0;
+ --pf-v6-c-button__icon--m-start--MarginInlineEnd: 0;
+ --pf-v6-c-button__icon--m-end--MarginInlineStart: 0;
+ --pf-v6-c-button--m-notify__icon--AnimationDuration--notify: var(--pf-t--global--motion--duration--3xl);
+ --pf-v6-c-button--m-notify__icon--AnimationTimingFunction--notify: var(--pf-t--global--motion--timing-function--default);
+ --pf-v6-c-button__icon--TransitionDelay: 0s;
+ --pf-v6-c-button__icon--TransitionTimingFunction: auto;
+ --pf-v6-c-button__icon--TransitionDuration: 0s;
+ --pf-v6-c-button__icon--TransitionProperty: none;
+ --pf-v6-c-button__icon--Rotate: 0deg;
+ --pf-v6-c-button--hover__icon--TransitionTimingFunction: auto;
+ --pf-v6-c-button--hover__icon--TransitionDuration: 0s;
+ --pf-v6-c-button--hover__icon--TransitionProperty: none;
+ --pf-v6-c-button--hover__icon--Rotate: 0deg;
+ --pf-v6-c-button__icon--ScaleX: 1;
+ --pf-v6-c-button__icon--ScaleY: 1;
+ --pf-v6-c-button--hover__icon--ScaleX: 1;
+ --pf-v6-c-button--hover__icon--ScaleY: 1;
+
+ /* Favorite button */
+ --pf-v6-c-button--m-favorite__icon--TransitionDuration: var(--pf-t--global--motion--duration--icon--default);
+ --pf-v6-c-button--m-favorite__icon--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--default);
+ --pf-v6-c-button--m-favorited__icon--Color: var(--pf-t--global--color--favorite--default);
+ --pf-v6-c-button--m-favorited--hover__icon--Color: var(--pf-t--global--color--favorite--hover);
+ --pf-v6-c-button--m-favorited__icon--AnimationDuration: var(--pf-t--global--motion--duration--icon--long);
+ --pf-v6-c-button--m-favorited__icon--AnimationTimingFunction: var(--pf-t--global--motion--timing-function--default);
+ --pf-v6-c-button__icon--favorite--Opacity: 1;
+ --pf-v6-c-button__icon--favorited--Opacity: 0;
+ --pf-v6-c-button--m-favorited__icon--favorite--Opacity: 0;
+ --pf-v6-c-button--m-favorited__icon--favorited--Opacity: 1;
+ --pf-v6-c-button__icon--favorite--TransitionDuration: var(--pf-t--global--motion--duration--icon--default);
+
+ /* Progress */
+ --pf-v6-c-button__progress--width: calc(var(--pf-t--global--icon--size--lg) + var(--pf-t--global--spacer--sm, 0.5rem));
+ --pf-v6-c-button__progress--Opacity: 0;
+ --pf-v6-c-button__progress--TranslateY: -50%;
+ --pf-v6-c-button__progress--TranslateX: 0;
+ --pf-v6-c-button__progress--InsetBlockStart: 50%;
+ --pf-v6-c-button__progress--InsetInlineStart: var(--pf-t--global--spacer--control--horizontal--default);
+ --pf-v6-c-button--m-progress--PaddingInlineEnd: calc(var(--pf-t--global--spacer--control--horizontal--default) + var(--pf-v6-c-button__progress--width) / 2);
+ --pf-v6-c-button--m-progress--PaddingInlineStart: calc(var(--pf-t--global--spacer--control--horizontal--default) + var(--pf-v6-c-button__progress--width) / 2);
+ --pf-v6-c-button--m-in-progress--PaddingInlineEnd: var(--pf-t--global--spacer--control--horizontal--default);
+ --pf-v6-c-button--m-in-progress--PaddingInlineStart: calc(var(--pf-t--global--spacer--control--horizontal--default) + var(--pf-v6-c-button__progress--width));
+ --pf-v6-c-button--m-in-progress--m-plain--Color: var(--pf-t--global--icon--color--brand--default, #0066cc);
+ --pf-v6-c-button--m-in-progress--m-plain__progress--InsetInlineStart: 50%;
+ --pf-v6-c-button--m-in-progress--m-plain__progress--TranslateX: -50%;
+
+ /* Settings */
+ --pf-v6-c-button--m-settings__icon--TransitionDuration: var(--pf-t--global--motion--duration--icon--long);
+ --pf-v6-c-button--m-settings__icon--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--accelerate);
+ --pf-v6-c-button--m-settings--hover__icon--TransitionDuration: var(--pf-t--global--motion--duration--icon--long);
+ --pf-v6-c-button--m-settings--hover__icon--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--decelerate);
+ --pf-v6-c-button--m-settings--hover__icon--Rotate: 60deg;
+
+ /* Count */
+ --pf-v6-c-button--m-primary__c-badge--BorderColor: var(--pf-t--global--border--color--alt);
+
+ /* Block */
+ --pf-v6-c-button--m-block--Display: flex;
+ --pf-v6-c-button--m-block--Width: 100%;
+
+ /* Hamburger */
+ --pf-v6-c-button--hamburger-icon--TransitionTimingFunction: var(--pf-t--global--motion--timing-function--decelerate);
+ --pf-v6-c-button--hamburger-icon--TransitionDuration: var(--pf-t--global--motion--duration--md);
+ --pf-v6-c-button--hamburger-icon--top--path--base: path("M1,1 L9,1");
+ --pf-v6-c-button--hamburger-icon--middle--path--base: path("M1,5 L9,5");
+ --pf-v6-c-button--hamburger-icon--arrow--path--base: path("M1,5 L1,5 L1,5");
+ --pf-v6-c-button--hamburger-icon--bottom--path--base: path("M9,9 L1,9");
+ --pf-v6-c-button--hamburger-icon--top--path: var(--pf-v6-c-button--hamburger-icon--top--path--base);
+ --pf-v6-c-button--hamburger-icon--middle--path: var(--pf-v6-c-button--hamburger-icon--middle--path--base);
+ --pf-v6-c-button--hamburger-icon--arrow--path: var(--pf-v6-c-button--hamburger-icon--arrow--path--base);
+ --pf-v6-c-button--hamburger-icon--bottom--path: var(--pf-v6-c-button--hamburger-icon--bottom--path--base);
+ --pf-v6-c-button--hamburger-icon--top--collapse--path: path("M5,1 L9,1");
+ --pf-v6-c-button--hamburger-icon--arrow--collapse--path: path("M3,7 L1,5 L3,3");
+ --pf-v6-c-button--hamburger-icon--bottom--collapse--path: path("M9,9 L5,9");
+ --pf-v6-c-button--m-hamburger__icon--m-expand--ScaleX: -1;
+
+ display: inline-block;
+ font-family: var(--pf-t--global--font--family--body, "Red Hat Text", RedHatText, Helvetica, Arial, sans-serif);
+ vertical-align: middle;
+ max-width: 100%;
+ cursor: pointer;
+ outline: none;
+}
+
+#button {
+ --pf-v6-c-button__progress--Color: var(--pf-v6-c-button__icon--Color);
+
+ position: relative;
+ inset: auto;
+ transform: none;
+ display: var(--pf-v6-c-button--Display, inline-flex);
+ gap: var(--pf-v6-c-button--Gap, var(--pf-t--global--spacer--gap--text-to-element--default, 0.5rem));
+ align-items: var(--pf-v6-c-button--AlignItems, baseline);
+ justify-content: var(--pf-v6-c-button--JustifyContent, center);
+ min-width: var(--pf-v6-c-button--MinWidth);
+ padding-block-start: var(--pf-v6-c-button--PaddingBlockStart, var(--pf-t--global--spacer--control--vertical--default, 0.5rem));
+ padding-block-end: var(--pf-v6-c-button--PaddingBlockEnd, var(--pf-t--global--spacer--control--vertical--default, 0.5rem));
+ padding-inline-start: var(--pf-v6-c-button--PaddingInlineStart, var(--pf-t--global--spacer--action--horizontal--default, 1.5rem));
+ padding-inline-end: var(--pf-v6-c-button--PaddingInlineEnd, var(--pf-t--global--spacer--action--horizontal--default, 1.5rem));
+ font-family: inherit;
+ font-size: var(--pf-v6-c-button--FontSize, inherit);
+ font-weight: var(--pf-v6-c-button--FontWeight, inherit);
+ line-height: var(--pf-v6-c-button--LineHeight, inherit);
+ color: var(--pf-v6-c-button--Color, var(--pf-t--global--text--color--regular, #151515));
+ text-align: center;
+ text-decoration-line: var(--pf-v6-c-button--TextDecorationLine);
+ text-decoration-style: var(--pf-v6-c-button--TextDecorationStyle);
+ text-decoration-color: var(--pf-v6-c-button--TextDecorationColor);
+ white-space: nowrap;
+ cursor: pointer;
+ user-select: none;
+ background-color: var(--pf-v6-c-button--BackgroundColor, transparent);
+ background-image: radial-gradient(circle, transparent 1%, color-mix(in srgb, currentcolor 15%, transparent) 2%);
+ background-position: center;
+ background-size: 15000% 15000%;
+ border: 0;
+ border-start-start-radius: var(--pf-v6-c-button--BorderStartStartRadius, var(--pf-v6-c-button--BorderRadius));
+ border-start-end-radius: var(--pf-v6-c-button--BorderStartEndRadius, var(--pf-v6-c-button--BorderRadius));
+ border-end-start-radius: var(--pf-v6-c-button--BorderEndStartRadius, var(--pf-v6-c-button--BorderRadius));
+ border-end-end-radius: var(--pf-v6-c-button--BorderEndEndRadius, var(--pf-v6-c-button--BorderRadius));
+ transition-delay: var(--pf-v6-c-button--TransitionDelay);
+ transition-timing-function: var(--pf-v6-c-button--TransitionTimingFunction);
+ transition-duration: var(--pf-v6-c-button--TransitionDuration);
+ transition-property: var(--pf-v6-c-button--TransitionProperty);
+ scale: var(--pf-v6-c-button--ScaleX) var(--pf-v6-c-button--ScaleY);
+
+ &::after {
+ position: absolute;
+ inset: var(--pf-v6-c-button--border--offset);
+ pointer-events: none;
+ content: "";
+ border: var(--pf-v6-c-button--BorderWidth) solid;
+ border-color: var(--pf-v6-c-button--BorderColor);
+ border-radius: inherit;
+ transition: inherit;
+ }
+
+ /* Primary variant */
+ &.primary {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-primary--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-primary--BackgroundColor);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-primary__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-primary--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-primary--hover--BackgroundColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-primary--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-primary--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-primary--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-primary--m-clicked__icon--Color);
+ }
+
+ /* Secondary variant */
+ &.secondary {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-secondary--Color);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--m-secondary--BorderColor);
+ --pf-v6-c-button--TransitionDuration: var(--pf-v6-c-button--m-secondary--TransitionDuration);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-secondary__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-secondary--hover--Color);
+ --pf-v6-c-button--hover--BorderColor: var(--pf-v6-c-button--m-secondary--hover--BorderColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-secondary--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-secondary--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BorderColor: var(--pf-v6-c-button--m-secondary--m-clicked--BorderColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-secondary--m-clicked__icon--Color);
+ --pf-v6-c-button--m-danger--Color: var(--pf-v6-c-button--m-secondary--m-danger--Color);
+ --pf-v6-c-button--m-danger__icon--Color: var(--pf-v6-c-button--m-secondary--m-danger__icon--Color);
+ --pf-v6-c-button--m-danger--hover--Color: var(--pf-v6-c-button--m-secondary--m-danger--hover--Color);
+ --pf-v6-c-button--m-danger--hover__icon--Color: var(--pf-v6-c-button--m-secondary--m-danger--hover__icon--Color);
+ --pf-v6-c-button--m-danger--m-clicked--Color: var(--pf-v6-c-button--m-secondary--m-danger--m-clicked--Color);
+ --pf-v6-c-button--m-danger--m-clicked__icon--Color: var(--pf-v6-c-button--m-secondary--m-danger--m-clicked__icon--Color);
+
+ &.danger {
+ --pf-v6-c-button--m-secondary--BorderColor: var(--pf-v6-c-button--m-secondary--m-danger--BorderColor);
+ --pf-v6-c-button--m-secondary--hover--BorderColor: var(--pf-v6-c-button--m-secondary--m-danger--hover--BorderColor);
+ --pf-v6-c-button--m-secondary--m-clicked--BorderColor: var(--pf-v6-c-button--m-secondary--m-danger--m-clicked--BorderColor);
+ --pf-v6-c-button--m-danger--BackgroundColor: transparent;
+ --pf-v6-c-button--m-danger--hover--BackgroundColor: transparent;
+ --pf-v6-c-button--m-danger--m-clicked--BackgroundColor: transparent;
+ }
+ }
+
+ /* Tertiary variant */
+ &.tertiary {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-tertiary--Color);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--m-tertiary--BorderColor);
+ --pf-v6-c-button--TransitionDuration: var(--pf-v6-c-button--m-tertiary--TransitionDuration);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-tertiary__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-tertiary--hover--Color);
+ --pf-v6-c-button--hover--BorderColor: var(--pf-v6-c-button--m-tertiary--hover--BorderColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-tertiary--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-tertiary--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BorderColor: var(--pf-v6-c-button--m-tertiary--m-clicked--BorderColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-tertiary--m-clicked__icon--Color);
+ }
+
+ /* Link variant */
+ &.link {
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-link--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-link--PaddingInlineStart);
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-link--Color);
+ --pf-v6-c-button--BorderWidth: var(--pf-v6-c-button--m-link--BorderWidth);
+ --pf-v6-c-button--hover--BorderColor: var(--pf-v6-c-button--m-link--hover--BorderColor);
+ --pf-v6-c-button--hover--BorderWidth: var(--pf-v6-c-button--m-link--hover--BorderWidth);
+ --pf-v6-c-button--m-clicked--BorderColor: var(--pf-v6-c-button--m-link--m-clicked--BorderColor);
+ --pf-v6-c-button--m-clicked--BorderWidth: var(--pf-v6-c-button--m-link--m-clicked--BorderWidth);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--m-link--BorderColor);
+ --pf-v6-c-button--BorderRadius: var(--pf-v6-c-button--m-link--BorderRadius);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-link--BackgroundColor);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-link__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-link--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-link--hover--BackgroundColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-link--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-link--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-link--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-link--m-clicked__icon--Color);
+ --pf-v6-c-button--m-small--PaddingInlineEnd: var(--pf-v6-c-button--m-link--m-small--PaddingInlineEnd);
+ --pf-v6-c-button--m-small--PaddingInlineStart: var(--pf-v6-c-button--m-link--m-small--PaddingInlineStart);
+
+ &.inline {
+ /* Override display and icon margins for span-like behavior */
+ --pf-v6-c-button--m-link--m-inline--Display: var(--pf-v6-c-button--span--m-link--m-inline--Display);
+ --pf-v6-c-button__icon--m-start--MarginInlineEnd: var(--pf-v6-c-button--span--m-link--m-inline__icon--m-start--MarginInlineEnd);
+ --pf-v6-c-button__icon--m-end--MarginInlineStart: var(--pf-v6-c-button--span--m-link--m-inline__icon--m-end--MarginInlineStart);
+ --pf-v6-c-button--Display: var(--pf-v6-c-button--m-link--m-inline--Display);
+ --pf-v6-c-button--JustifyContent: var(--pf-v6-c-button--m-link--m-inline--JustifyContent);
+ --pf-v6-c-button--FontSize: var(--pf-v6-c-button--m-link--m-inline--FontSize);
+ --pf-v6-c-button--LineHeight: var(--pf-v6-c-button--m-link--m-inline--LineHeight);
+ --pf-v6-c-button--FontWeight: var(--pf-v6-c-button--m-link--m-inline--FontWeight);
+ --pf-v6-c-button--PaddingBlockStart: var(--pf-v6-c-button--m-link--m-inline--PaddingBlockStart);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-link--m-inline--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingBlockEnd: var(--pf-v6-c-button--m-link--m-inline--PaddingBlockEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-link--m-inline--PaddingInlineStart);
+ --pf-v6-c-button--BackgroundColor: transparent;
+ --pf-v6-c-button__progress--InsetInlineStart: var(--pf-v6-c-button--m-link--m-inline__progress--InsetInlineStart);
+ --pf-v6-c-button--TextDecorationLine: var(--pf-v6-c-button--m-link--m-inline--TextDecorationLine);
+ --pf-v6-c-button--TextDecorationStyle: var(--pf-v6-c-button--m-link--m-inline--TextDecorationStyle);
+ --pf-v6-c-button--hover--TextDecorationLine: var(--pf-v6-c-button--m-link--m-inline--hover--TextDecorationLine);
+ --pf-v6-c-button--hover--TextDecorationStyle: var(--pf-v6-c-button--m-link--m-inline--hover--TextDecorationStyle);
+ --pf-v6-c-button--hover--BackgroundColor: transparent;
+ --pf-v6-c-button--m-clicked--BackgroundColor: transparent;
+ --pf-v6-c-button--disabled--BackgroundColor: transparent;
+ --pf-v6-c-button--disabled--Color: var(--pf-v6-c-button--m-link--m-inline--disabled--Color);
+ --pf-v6-c-button--disabled__icon--Color: var(--pf-v6-c-button--m-link--m-inline--disabled__icon--Color);
+ --pf-v6-c-button--m-link--Color: var(--pf-v6-c-button--m-link--m-inline--Color);
+ --pf-v6-c-button--m-link__icon--Color: var(--pf-v6-c-button--m-link--m-inline__icon--Color);
+ --pf-v6-c-button--TextDecorationColor: var(--pf-v6-c-button--m-link--m-inline--TextDecorationColor);
+ --pf-v6-c-button--hover--TextDecorationColor: var(--pf-v6-c-button--m-link--m-inline--hover--TextDecorationColor);
+ --pf-v6-c-button--m-link--hover--Color: var(--pf-v6-c-button--m-link--m-inline--hover--Color);
+ --pf-v6-c-button--m-link--hover__icon--Color: var(--pf-v6-c-button--m-link--m-inline--hover__icon--Color);
+ --pf-v6-c-button--BorderWidth: 0;
+ --pf-v6-c-button--hover--BorderWidth: 0;
+ --pf-v6-c-button--m-clicked--BorderWidth: 0;
+
+ text-align: start;
+ white-space: normal;
+ background: transparent;
+ outline-offset: var(--pf-t--global--focus-ring--position--offset, 0.125rem);
+ }
+
+ &.danger {
+ --pf-v6-c-button--m-danger--Color: var(--pf-v6-c-button--m-link--m-danger--Color);
+ --pf-v6-c-button--m-danger--BackgroundColor: var(--pf-v6-c-button--m-link--m-danger--BackgroundColor);
+ --pf-v6-c-button--m-danger__icon--Color: var(--pf-v6-c-button--m-link--m-danger__icon--Color);
+ --pf-v6-c-button--m-danger--hover--Color: var(--pf-v6-c-button--m-link--m-danger--hover--Color);
+ --pf-v6-c-button--m-danger--hover--BackgroundColor: var(--pf-v6-c-button--m-link--m-danger--hover--BackgroundColor);
+ --pf-v6-c-button--m-danger--hover__icon--Color: var(--pf-v6-c-button--m-link--m-danger--hover__icon--Color);
+ --pf-v6-c-button--m-danger--m-clicked--Color: var(--pf-v6-c-button--m-link--m-danger--m-clicked--Color);
+ --pf-v6-c-button--m-danger--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-link--m-danger--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-danger--m-clicked__icon--Color: var(--pf-v6-c-button--m-link--m-danger--m-clicked__icon--Color);
+ }
+
+ &.display-lg {
+ --pf-v6-c-button--FontSize: var(--pf-v6-c-button--m-link--m-display-lg--FontSize);
+ }
+ }
+
+ /* Warning variant */
+ &.warning {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-warning--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-warning--BackgroundColor);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-warning__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-warning--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-warning--hover--BackgroundColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-warning--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-warning--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-warning--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-warning--m-clicked__icon--Color);
+ }
+
+ /* Danger variant (note: also used as modifier for secondary/link) */
+ &.danger {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-danger--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-danger--BackgroundColor);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-danger__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-danger--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-danger--hover--BackgroundColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-danger--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-danger--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-danger--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-danger--m-clicked__icon--Color);
+ }
+
+ /* Control variant */
+ &.control {
+ --pf-v6-c-button--BorderRadius: var(--pf-v6-c-button--m-control--BorderRadius);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-control--PaddingInlineStart);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-control--PaddingInlineEnd);
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-control--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-control--BackgroundColor);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--m-control--BorderColor);
+ --pf-v6-c-button--BorderWidth: var(--pf-v6-c-button--m-control--BorderWidth);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-control__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-control--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-control--hover--BackgroundColor);
+ --pf-v6-c-button--hover--BorderColor: var(--pf-v6-c-button--m-control--hover--BorderColor);
+ --pf-v6-c-button--hover--BorderWidth: var(--pf-v6-c-button--m-control--hover--BorderWidth);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-control--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-control--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-control--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked--BorderColor: var(--pf-v6-c-button--m-control--m-clicked--BorderColor);
+ --pf-v6-c-button--m-clicked--BorderWidth: var(--pf-v6-c-button--m-control--m-clicked--BorderWidth);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-control--m-clicked__icon--Color);
+ --pf-v6-c-button--m-small--PaddingInlineEnd: var(--pf-v6-c-button--m-control--m-small--PaddingInlineEnd);
+ --pf-v6-c-button--m-small--PaddingInlineStart: var(--pf-v6-c-button--m-control--m-small--PaddingInlineStart);
+ }
+
+ /* Stateful variant */
+ &.stateful {
+ --pf-v6-c-button--BorderRadius: var(--pf-v6-c-button--m-stateful--BorderRadius);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-stateful--PaddingInlineStart);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-stateful--PaddingInlineEnd);
+ --pf-v6-c-button--m-small--PaddingInlineEnd: var(--pf-v6-c-button--m-stateful--m-small--PaddingInlineEnd);
+ --pf-v6-c-button--m-small--PaddingInlineStart: var(--pf-v6-c-button--m-stateful--m-small--PaddingInlineStart);
+ }
+
+ /* Read state */
+ &.read {
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-read--BackgroundColor);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--m-read--BorderColor);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-read--hover--BackgroundColor);
+ --pf-v6-c-button--hover--BorderColor: var(--pf-v6-c-button--m-read--hover--BorderColor);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-read--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked--BorderColor: var(--pf-v6-c-button--m-read--m-clicked--BorderColor);
+ }
+
+ /* Unread state */
+ &.unread {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-unread--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-unread--BackgroundColor);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-unread__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-unread--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-unread--hover--BackgroundColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-unread--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-unread--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-unread--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-unread--m-clicked__icon--Color);
+ }
+
+ /* Attention state */
+ &.attention {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-attention--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-attention--BackgroundColor);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-attention__icon--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-attention--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-attention--hover--BackgroundColor);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-attention--hover__icon--Color);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-attention--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-attention--m-clicked--BackgroundColor);
+ --pf-v6-c-button--m-clicked__icon--Color: var(--pf-v6-c-button--m-attention--m-clicked__icon--Color);
+ }
+
+ /* Plain variant */
+ &.plain {
+ --pf-v6-c-button--BorderWidth: var(--pf-v6-c-button--m-plain--BorderWidth);
+ --pf-v6-c-button--hover--BorderColor: var(--pf-v6-c-button--m-plain--hover--BorderColor);
+ --pf-v6-c-button--hover--BorderWidth: var(--pf-v6-c-button--m-plain--hover--BorderWidth);
+ --pf-v6-c-button--m-clicked--BorderColor: var(--pf-v6-c-button--m-plain--m-clicked--BorderColor);
+ --pf-v6-c-button--m-clicked--BorderWidth: var(--pf-v6-c-button--m-plain--m-clicked--BorderWidth);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--m-plain--BorderColor);
+ --pf-v6-c-button--BorderRadius: var(--pf-v6-c-button--m-plain--BorderRadius);
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-plain--Color);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-plain__icon--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-plain--BackgroundColor);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-plain--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-plain--PaddingInlineStart);
+ --pf-v6-c-button__progress--Color: var(--pf-v6-c-button--m-in-progress--m-plain--Color);
+ --pf-v6-c-button--hover--Color: var(--pf-v6-c-button--m-plain--hover--Color);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-plain--hover--BackgroundColor);
+ --pf-v6-c-button--m-clicked--Color: var(--pf-v6-c-button--m-plain--m-clicked--Color);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-plain--m-clicked--BackgroundColor);
+ --pf-v6-c-button--disabled--Color: var(--pf-v6-c-button--m-plain--disabled--Color);
+ --pf-v6-c-button--disabled__icon--Color: var(--pf-v6-c-button--m-plain--disabled__icon--Color);
+ --pf-v6-c-button--disabled--BackgroundColor: var(--pf-v6-c-button--m-plain--disabled--BackgroundColor);
+ --pf-v6-c-button--m-small--PaddingInlineEnd: var(--pf-v6-c-button--m-plain--m-small--PaddingInlineEnd);
+ --pf-v6-c-button--m-small--PaddingInlineStart: var(--pf-v6-c-button--m-plain--m-small--PaddingInlineStart);
+
+ &.no-padding {
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-plain--m-no-padding__icon--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-plain--m-no-padding--BackgroundColor);
+ --pf-v6-c-button--hover--BackgroundColor: var(--pf-v6-c-button--m-plain--m-no-padding--hover--BackgroundColor);
+ --pf-v6-c-button--m-clicked--BackgroundColor: var(--pf-v6-c-button--m-plain--m-no-padding--m-clicked--BackgroundColor);
+ --pf-v6-c-button--PaddingBlockStart: var(--pf-v6-c-button--m-plain--m-no-padding--PaddingBlockStart);
+ --pf-v6-c-button--PaddingBlockEnd: var(--pf-v6-c-button--m-plain--m-no-padding--PaddingBlockEnd);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-plain--m-no-padding--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-plain--m-no-padding--PaddingInlineStart);
+ --pf-v6-c-button--m-small--PaddingInlineEnd: var(--pf-v6-c-button--m-plain--m-no-padding--m-small--PaddingInlineEnd);
+ --pf-v6-c-button--m-small--PaddingInlineStart: var(--pf-v6-c-button--m-plain--m-no-padding--m-small--PaddingInlineStart);
+ --pf-v6-c-button--border--offset: var(--pf-v6-c-button--m-plain--m-no-padding--border--offset);
+
+ min-width: var(--pf-v6-c-button--m-plain--m-no-padding--MinWidth);
+ background: var(--pf-v6-c-button--BackgroundColor);
+ }
+ }
+
+ /* Block modifier */
+ &.block {
+ --pf-v6-c-button--Display: var(--pf-v6-c-button--m-block--Display);
+
+ width: var(--pf-v6-c-button--m-block--Width);
+ }
+
+ /* Small size */
+ &.small {
+ --pf-v6-c-button--PaddingBlockStart: var(--pf-v6-c-button--m-small--PaddingBlockStart);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-small--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingBlockEnd: var(--pf-v6-c-button--m-small--PaddingBlockEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-small--PaddingInlineStart);
+ }
+
+ /* Display lg size - padding only, font size set per-variant (e.g., .link.display-lg) */
+ &.display-lg {
+ --pf-v6-c-button--PaddingBlockStart: var(--pf-v6-c-button--m-display-lg--PaddingBlockStart);
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-display-lg--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingBlockEnd: var(--pf-v6-c-button--m-display-lg--PaddingBlockEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-display-lg--PaddingInlineStart);
+ }
+
+ /* Favorite button */
+ &.favorite .icon {
+ display: grid;
+ transition-timing-function: var(--pf-v6-c-button--m-favorite__icon--TransitionTimingFunction);
+ transition-duration: var(--pf-v6-c-button--m-favorite__icon--TransitionDuration);
+ transition-property: color;
+ }
+
+ /* Favorited state */
+ &.favorited {
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-favorited__icon--Color);
+ --pf-v6-c-button--m-plain--m-no-padding__icon--Color: var(--pf-v6-c-button--m-favorited__icon--Color);
+ --pf-v6-c-button--hover__icon--Color: var(--pf-v6-c-button--m-favorited--hover__icon--Color);
+ --pf-v6-c-button--m-plain--m-no-padding--hover__icon--Color: var(--pf-v6-c-button--m-favorited--hover__icon--Color);
+ --pf-v6-c-button__icon--favorite--Opacity: var(--pf-v6-c-button--m-favorited__icon--favorite--Opacity);
+ --pf-v6-c-button__icon--favorited--Opacity: var(--pf-v6-c-button--m-favorited__icon--favorited--Opacity);
+ }
+
+ /* Favorited animation */
+ &.favorited .icon {
+ animation-name: pf-v6-button-icon-favorited;
+ animation-duration: var(--pf-v6-c-button--m-favorited__icon--AnimationDuration);
+ animation-timing-function: var(--pf-v6-c-button--m-favorited__icon--AnimationTimingFunction);
+ }
+
+ /* Settings button */
+ &.settings {
+ --pf-v6-c-button__icon--TransitionProperty: rotate;
+ --pf-v6-c-button__icon--TransitionDuration: var(--pf-v6-c-button--m-settings__icon--TransitionDuration);
+ --pf-v6-c-button__icon--TransitionTimingFunction: var(--pf-v6-c-button--m-settings__icon--TransitionTimingFunction);
+ --pf-v6-c-button--hover__icon--TransitionProperty: rotate;
+ --pf-v6-c-button--hover__icon--TransitionDuration: var(--pf-v6-c-button--m-settings--hover__icon--TransitionDuration);
+ --pf-v6-c-button--hover__icon--TransitionTimingFunction: var(--pf-v6-c-button--m-settings--hover__icon--TransitionTimingFunction);
+ --pf-v6-c-button--hover__icon--Rotate: var(--pf-v6-c-button--m-settings--hover__icon--Rotate);
+ }
+
+ /* Hamburger button */
+ &.hamburger {
+ --pf-v6-c-button__icon--TransitionDelay: var(--pf-v6-c-button--hamburger-icon--TransitionDuration);
+ --pf-v6-c-button__icon--TransitionDuration: 0s;
+ --pf-v6-c-button__icon--TransitionProperty: scale;
+ --pf-v6-c-button--hover__icon--TransitionDelay: var(--pf-v6-c-button--hamburger-icon--TransitionDuration);
+ --pf-v6-c-button--hover__icon--TransitionDuration: 0s;
+ --pf-v6-c-button--hover__icon--TransitionProperty: scale;
+
+ &.expand {
+ --pf-v6-c-button--hamburger-icon--top--path: var(--pf-v6-c-button--hamburger-icon--top--collapse--path);
+ --pf-v6-c-button--hamburger-icon--arrow--path: var(--pf-v6-c-button--hamburger-icon--arrow--collapse--path);
+ --pf-v6-c-button--hamburger-icon--bottom--path: var(--pf-v6-c-button--hamburger-icon--bottom--collapse--path);
+ --pf-v6-c-button__icon--ScaleX: var(--pf-v6-c-button--m-hamburger__icon--m-expand--ScaleX);
+ --pf-v6-c-button--hover__icon--ScaleX: var(--pf-v6-c-button--m-hamburger__icon--m-expand--ScaleX);
+ }
+
+ &.collapse {
+ --pf-v6-c-button--hamburger-icon--top--path: var(--pf-v6-c-button--hamburger-icon--top--collapse--path);
+ --pf-v6-c-button--hamburger-icon--arrow--path: var(--pf-v6-c-button--hamburger-icon--arrow--collapse--path);
+ --pf-v6-c-button--hamburger-icon--bottom--path: var(--pf-v6-c-button--hamburger-icon--bottom--collapse--path);
+ --pf-v6-c-button__icon--ScaleX: 1;
+ --pf-v6-c-button--hover__icon--ScaleX: 1;
+ }
+ }
+
+ /* Hover states */
+ &:hover {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--hover--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--hover--BackgroundColor);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--hover--BorderColor);
+ --pf-v6-c-button--BorderWidth: var(--pf-v6-c-button--hover--BorderWidth);
+ --pf-v6-c-button--ScaleX: var(--pf-v6-c-button--hover--ScaleX);
+ --pf-v6-c-button--ScaleY: var(--pf-v6-c-button--hover--ScaleY);
+ --pf-v6-c-button--m-plain--m-no-padding__icon--Color: var(--pf-v6-c-button--m-plain--m-no-padding--hover__icon--Color);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--hover__icon--Color);
+ --pf-v6-c-button__icon--TransitionTimingFunction: var(--pf-v6-c-button--hover__icon--TransitionTimingFunction);
+ --pf-v6-c-button__icon--TransitionDuration: var(--pf-v6-c-button--hover__icon--TransitionDuration);
+ --pf-v6-c-button__icon--TransitionProperty: var(--pf-v6-c-button--hover__icon--TransitionProperty);
+ --pf-v6-c-button__icon--Rotate: var(--pf-v6-c-button--hover__icon--Rotate);
+ --pf-v6-c-button__icon--ScaleX: var(--pf-v6-c-button--hover__icon--ScaleX);
+ --pf-v6-c-button__icon--ScaleY: var(--pf-v6-c-button--hover__icon--ScaleY);
+
+ text-decoration-line: var(--pf-v6-c-button--hover--TextDecorationLine);
+ text-decoration-style: var(--pf-v6-c-button--hover--TextDecorationStyle);
+ text-decoration-color: var(--pf-v6-c-button--hover--TextDecorationColor);
+ outline-offset: var(--pf-t--global--focus-ring--position--offset, 0.125rem);
+ }
+
+ /* Active & clicked states */
+ &:active,
+ &.clicked {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--m-clicked--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--m-clicked--BackgroundColor);
+ --pf-v6-c-button--BorderWidth: var(--pf-v6-c-button--m-clicked--BorderWidth);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--m-clicked--BorderColor);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--m-clicked__icon--Color);
+ }
+
+ &:active {
+ background-size: 100% 100%;
+ transition-duration: 0s;
+ }
+
+ /* Disabled states */
+ &:disabled,
+ &.disabled {
+ pointer-events: none;
+ }
+
+ &:disabled,
+ &.disabled,
+ &.aria-disabled {
+ color: var(--pf-v6-c-button--disabled--Color);
+ text-decoration-color: var(--pf-v6-c-button--disabled--TextDecorationColor);
+ background: var(--pf-v6-c-button--disabled--BackgroundColor);
+
+ &::after {
+ border-color: transparent;
+ }
+
+ & .icon {
+ color: var(--pf-v6-c-button--disabled__icon--Color);
+ }
+ }
+
+ &.aria-disabled {
+ --pf-v6-c-button--m-link--m-inline--hover--TextDecorationLine: var(--pf-v6-c-button--TextDecorationLine);
+ --pf-v6-c-button--m-link--m-inline--hover--TextDecorationStyle: var(--pf-v6-c-button--TextDecorationStyle);
+
+ cursor: default;
+ }
+
+ /* Progress states */
+ &.progress {
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-progress--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-progress--PaddingInlineStart);
+ }
+
+ &.in-progress {
+ --pf-v6-c-button--m-link--m-inline--PaddingInlineStart: var(--pf-v6-c-button--m-link--m-inline--m-in-progress--PaddingInlineStart);
+
+ &:not(.plain) {
+ --pf-v6-c-button--PaddingInlineEnd: var(--pf-v6-c-button--m-in-progress--PaddingInlineEnd);
+ --pf-v6-c-button--PaddingInlineStart: var(--pf-v6-c-button--m-in-progress--PaddingInlineStart);
+ }
+
+ &.plain {
+ --pf-v6-c-button__progress--InsetInlineStart: var(--pf-v6-c-button--m-in-progress--m-plain__progress--InsetInlineStart);
+ --pf-v6-c-button__progress--TranslateX: var(--pf-v6-c-button--m-in-progress--m-plain__progress--TranslateX);
+
+ & > :not(.progress) {
+ opacity: 0;
+ }
+ }
+ }
+}
+
+.icon {
+ margin-inline-start: var(--pf-v6-c-button__icon--MarginInlineStart);
+ margin-inline-end: var(--pf-v6-c-button__icon--MarginInlineEnd);
+ color: var(--pf-v6-c-button__icon--Color);
+ transition-delay: var(--pf-v6-c-button__icon--TransitionDelay);
+ transition-timing-function: var(--pf-v6-c-button__icon--TransitionTimingFunction);
+ transition-duration: var(--pf-v6-c-button__icon--TransitionDuration);
+ transition-property: var(--pf-v6-c-button__icon--TransitionProperty);
+ rotate: var(--pf-v6-c-button__icon--Rotate);
+ scale: var(--pf-v6-c-button__icon--ScaleX) var(--pf-v6-c-button__icon--ScaleY);
+
+ &.icon-start {
+ --pf-v6-c-button__icon--MarginInlineEnd: var(--pf-v6-c-button__icon--m-start--MarginInlineEnd);
+ }
+
+ &.icon-end {
+ --pf-v6-c-button__icon--MarginInlineStart: var(--pf-v6-c-button__icon--m-end--MarginInlineStart);
+ }
+}
+
+.icon-favorite,
+.icon-favorited {
+ grid-area: 1 / 1 / 1 / 1;
+ transition-duration: var(--pf-v6-c-button__icon--favorite--TransitionDuration);
+ transition-property: opacity;
+}
+
+.icon-favorite {
+ opacity: var(--pf-v6-c-button__icon--favorite--Opacity);
+}
+
+.icon-favorited {
+ opacity: var(--pf-v6-c-button__icon--favorited--Opacity);
+}
+
+.progress {
+ position: absolute;
+ inset-block-start: var(--pf-v6-c-button__progress--InsetBlockStart);
+ inset-inline-start: var(--pf-v6-c-button__progress--InsetInlineStart);
+ line-height: 1;
+ color: var(--pf-v6-c-button__progress--Color);
+ transform: translate(var(--pf-v6-c-button__progress--TranslateX), var(--pf-v6-c-button__progress--TranslateY));
+}
+
+.text {
+ text-decoration: inherit;
+}
+
+.count {
+ display: inline-flex;
+ align-items: center;
+}
+
+.hamburger-icon {
+ path {
+ fill: none;
+ stroke: currentcolor;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ transition: d var(--pf-v6-c-button--hamburger-icon--TransitionDuration) var(--pf-v6-c-button--hamburger-icon--TransitionTimingFunction);
+ }
+}
+
+.hamburger-icon-top {
+ d: var(--pf-v6-c-button--hamburger-icon--top--path);
+}
+
+.hamburger-icon-middle {
+ d: var(--pf-v6-c-button--hamburger-icon--middle--path);
+}
+
+.hamburger-icon-arrow {
+ d: var(--pf-v6-c-button--hamburger-icon--arrow--path);
+}
+
+.hamburger-icon-bottom {
+ d: var(--pf-v6-c-button--hamburger-icon--bottom--path);
+}
+
+@keyframes pf-v6-button-icon-favorited {
+ 50% {
+ scale: 1.5;
+ }
+}
+
+/* Slotted badge styles - apply CSS variables to light DOM badges */
+#button.primary ::slotted(pf-v6-badge:not([state="read"])) {
+ --pf-v6-c-badge--BorderColor: var(--pf-v6-c-button--m-primary__c-badge--BorderColor);
+}
+
+:host(:focus) #button,
+:host(:focus-visible) #button {
+ --pf-v6-c-button--Color: var(--pf-v6-c-button--hover--Color);
+ --pf-v6-c-button--BackgroundColor: var(--pf-v6-c-button--hover--BackgroundColor);
+ --pf-v6-c-button--BorderColor: var(--pf-v6-c-button--hover--BorderColor);
+ --pf-v6-c-button--BorderWidth: var(--pf-v6-c-button--hover--BorderWidth);
+ --pf-v6-c-button--ScaleX: var(--pf-v6-c-button--hover--ScaleX);
+ --pf-v6-c-button--ScaleY: var(--pf-v6-c-button--hover--ScaleY);
+ --pf-v6-c-button--m-plain--m-no-padding__icon--Color: var(--pf-v6-c-button--m-plain--m-no-padding--hover__icon--Color);
+ --pf-v6-c-button__icon--Color: var(--pf-v6-c-button--hover__icon--Color);
+ --pf-v6-c-button__icon--TransitionTimingFunction: var(--pf-v6-c-button--hover__icon--TransitionTimingFunction);
+ --pf-v6-c-button__icon--TransitionDuration: var(--pf-v6-c-button--hover__icon--TransitionDuration);
+ --pf-v6-c-button__icon--TransitionProperty: var(--pf-v6-c-button--hover__icon--TransitionProperty);
+ --pf-v6-c-button__icon--Rotate: var(--pf-v6-c-button--hover__icon--Rotate);
+ --pf-v6-c-button__icon--ScaleX: var(--pf-v6-c-button--hover__icon--ScaleX);
+ --pf-v6-c-button__icon--ScaleY: var(--pf-v6-c-button--hover__icon--ScaleY);
+
+ text-decoration-line: var(--pf-v6-c-button--hover--TextDecorationLine);
+ text-decoration-style: var(--pf-v6-c-button--hover--TextDecorationStyle);
+ text-decoration-color: var(--pf-v6-c-button--hover--TextDecorationColor);
+ outline-offset: var(--pf-t--global--focus-ring--position--offset, 0.125rem);
+}
+
+:host([disabled]),
+:host([disabled-focusable]) {
+ cursor: not-allowed;
+}
+
+:host([disabled]) {
+ pointer-events: none;
+}
+
+:host([hidden]),
+[hidden] {
+ display: none !important;
+}
+
+:host([block]) {
+ display: flex;
+ width: 100%;
+}
+
+:host([inline]) {
+ display: inline;
+}
diff --git a/elements/pf-v6-button/pf-v6-button.ts b/elements/pf-v6-button/pf-v6-button.ts
new file mode 100644
index 0000000000..bf6eb5e3cd
--- /dev/null
+++ b/elements/pf-v6-button/pf-v6-button.ts
@@ -0,0 +1,588 @@
+import {
+ LitElement,
+ html,
+ isServer,
+ type ComplexAttributeConverter,
+ type PropertyValues,
+ type TemplateResult,
+} from 'lit';
+import { customElement } from 'lit/decorators/custom-element.js';
+import { property } from 'lit/decorators/property.js';
+import { classMap } from 'lit/directives/class-map.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+import { InternalsController } from '@patternfly/pfe-core/controllers/internals-controller.js';
+import { SlotController } from '@patternfly/pfe-core/controllers/slot-controller.js';
+
+import '@patternfly/elements/pf-v5-icon/pf-v5-icon.js';
+import '@patternfly/elements/pf-v6-spinner/pf-v6-spinner.js';
+
+import styles from './pf-v6-button.css';
+
+export type ButtonVariant =
+ | 'primary'
+ | 'secondary'
+ | 'tertiary'
+ | 'danger'
+ | 'warning'
+ | 'link'
+ | 'plain'
+ | 'control'
+ | 'stateful';
+
+export type ButtonSize = 'sm' | 'lg';
+
+export type ButtonState = 'read' | 'unread' | 'attention';
+
+export type ButtonType = 'button' | 'submit' | 'reset';
+
+/** `left` / `right` are deprecated aliases for `start` / `end` (React parity). */
+export type ButtonIconPosition = 'start' | 'end' | 'left' | 'right';
+
+export type ButtonHamburgerVariant = 'expand' | 'collapse';
+
+/**
+ * Tri-state loading converter matching React `isLoading`:
+ * - attribute absent β `null` (no progress layout)
+ * - `loading` / `loading=""` / `loading="true"` β `true` (spinner + in-progress)
+ * - `loading="false"` β `false` (reserved progress padding, no spinner)
+ */
+const loadingConverter: ComplexAttributeConverter = {
+ fromAttribute(value) {
+ if (value === null) {
+ return null;
+ }
+ if (value === 'false') {
+ return false;
+ }
+ return true;
+ },
+ toAttribute(value) {
+ if (value === null) {
+ return null;
+ }
+ if (value === false) {
+ return 'false';
+ }
+ return '';
+ },
+};
+
+/**
+ * A **button** communicates and triggers user actions when clicked or selected.
+ * Use buttons for actions such as submitting a form, canceling a process, or
+ * navigating to another page. Icon-only buttons MUST provide an `accessible-label`.
+ *
+ * This is a Form-Associated Custom Element (FACE). Form participation and ARIA
+ * (`role`, `aria-label`, `aria-disabled`, `aria-expanded`) are managed through
+ * `ElementInternals` via `InternalsController` β not a slotted native ``.
+ *
+ * @summary Triggers an action when activated
+ * @alias Button
+ *
+ * @slot - Button label text
+ * @slot icon - Icon displayed at the start or end of the button
+ * @slot count - Count badge displayed after the label
+ *
+ * @cssprop {} --pf-v6-c-button--BackgroundColor - Button background color
+ * @cssprop {} --pf-v6-c-button--Color - Button text color
+ * @cssprop {} --pf-v6-c-button--BorderColor - Button border color
+ * @cssprop {} --pf-v6-c-button--BorderWidth - Button border width
+ * @cssprop {} --pf-v6-c-button--BorderRadius - Button border radius
+ * @cssprop {} --pf-v6-c-button--FontSize - Button font size
+ * @cssprop {} --pf-v6-c-button--PaddingBlockStart - Block-start padding
+ * @cssprop {} --pf-v6-c-button--PaddingBlockEnd - Block-end padding
+ * @cssprop {} --pf-v6-c-button--PaddingInlineStart - Inline-start padding
+ * @cssprop {} --pf-v6-c-button--PaddingInlineEnd - Inline-end padding
+ * @cssprop {} --pf-v6-c-button__icon--Color - Icon color
+ * @cssprop {} --pf-v6-c-button--hover--BackgroundColor - Hover background
+ * @cssprop {} --pf-v6-c-button--m-clicked--BackgroundColor - Clicked background
+ *
+ * @csspart button - Main button surface (inner control chrome)
+ * @csspart icon - Container for the icon slot and built-in icons
+ * @csspart text - Container for the default slot label
+ * @csspart count - Container for the count slot
+ * @csspart progress - Container for the loading spinner
+ */
+@customElement('pf-v6-button')
+export class PfV6Button extends LitElement {
+ static readonly formAssociated = true;
+
+ static readonly styles: CSSStyleSheet[] = [styles];
+
+ /**
+ * Visual style of the button.
+ * - Primary: most important call to action; limit to one per page
+ * - Secondary: general actions that need less emphasis
+ * - Tertiary: classic button format with still less emphasis
+ * - Danger: potentially destructive or hard-to-undo actions
+ * - Warning: important setting changes that are not destructive
+ * - Link: low-emphasis actions or navigation
+ * - Plain: icon-labeled actions with no chrome
+ * - Control: for pairing with other controls in an input group
+ * - Stateful: notification state (`read`, `unread`, `attention`)
+ */
+ @property({ reflect: true }) variant: ButtonVariant = 'primary';
+
+ /** Size of the button. Omit for default size. */
+ @property({ reflect: true }) size?: ButtonSize;
+
+ /**
+ * Native form button type. Defaults to `button` (does not submit), matching
+ * React `Button`. Set `type="submit"` or `type="reset"` for form actions.
+ */
+ @property({ reflect: true }) type?: ButtonType;
+
+ /** State for the stateful variant. Defaults to unread when variant is stateful. */
+ @property({ reflect: true }) state?: ButtonState;
+
+ /** Form value for the button */
+ @property() value?: string;
+
+ /** Form element name for the button */
+ @property() name?: string;
+
+ /** Accessible name when the button has no visible text */
+ @property({ attribute: 'accessible-label' }) accessibleLabel?: string;
+
+ /** Disables the button and removes it from the tab order */
+ @property({ reflect: true, type: Boolean }) disabled = false;
+
+ /**
+ * Disables activation while keeping the button focusable.
+ * Use when a disabled button still needs a tooltip or other focus treatment.
+ */
+ @property({ reflect: true, type: Boolean, attribute: 'disabled-focusable' })
+ disabledFocusable = false;
+
+ /**
+ * Progress state (React `isLoading` tri-state):
+ * - omit / `null` β no progress layout
+ * - `true` / `loading` β show spinner and in-progress styling
+ * - `false` / `loading="false"` β reserve progress padding without a spinner
+ */
+ @property({ reflect: true, converter: loadingConverter })
+ loading: boolean | null = null;
+
+ /** Accessible label for the loading spinner */
+ @property({ attribute: 'loading-label' }) loadingLabel = 'Loading';
+
+ /** Spans the full width of the parent */
+ @property({ reflect: true, type: Boolean }) block = false;
+
+ /** Renders a link variant inline with surrounding text */
+ @property({ reflect: true, type: Boolean }) inline = false;
+
+ /** Applies danger styling to secondary or link variants */
+ @property({ reflect: true, type: Boolean }) danger = false;
+
+ /** Applies clicked styling */
+ @property({ reflect: true, type: Boolean }) clicked = false;
+
+ /** Renders as a favorite toggle; overrides the icon slot */
+ @property({ reflect: true, type: Boolean }) favorite = false;
+
+ /** Whether the favorite toggle is currently favorited */
+ @property({ reflect: true, type: Boolean }) favorited = false;
+
+ /** Renders as a settings button; overrides the icon slot */
+ @property({ reflect: true, type: Boolean }) settings = false;
+
+ /** Renders as a hamburger button; overrides the icon slot */
+ @property({ reflect: true, type: Boolean }) hamburger = false;
+
+ /** Required when `hamburger` is set; reflects expansion of controlled content */
+ @property({ reflect: true, type: Boolean }) expanded?: boolean;
+
+ /** Animates the hamburger icon toward expand or collapse */
+ @property({ reflect: true, attribute: 'hamburger-variant' })
+ hamburgerVariant?: ButtonHamburgerVariant;
+
+ /** Removes padding from a plain variant for inline icon placement */
+ @property({ reflect: true, type: Boolean, attribute: 'no-padding' })
+ noPadding = false;
+
+ /**
+ * Icon position relative to the label. Defaults to start.
+ * `left` / `right` are accepted as deprecated aliases for `start` / `end`.
+ */
+ @property({ reflect: true, attribute: 'icon-position' })
+ iconPosition?: ButtonIconPosition;
+
+ /** When set with `variant="link"`, renders as an anchor */
+ @property({ reflect: true }) href?: string;
+
+ /** Target for the link when `href` is set */
+ @property({ reflect: true }) target?: string;
+
+ /** Shorthand icon name for the icon slot */
+ @property() icon?: string;
+
+ /** Icon set for the `icon` property */
+ @property({ attribute: 'icon-set' }) iconSet?: string;
+
+ #internals = InternalsController.of(this);
+
+ #slots = new SlotController(this, 'icon', 'count', null);
+
+ /** Owning form via ElementInternals when `formAssociated` is true. */
+ get form(): HTMLFormElement | null {
+ return this.#internals.form;
+ }
+
+ get #disabled() {
+ return this.disabled || this.#internals.formDisabled;
+ }
+
+ get #operable() {
+ return !(this.#disabled || this.disabledFocusable);
+ }
+
+ override connectedCallback(): void {
+ super.connectedCallback();
+ if (!isServer) {
+ this.addEventListener('click', this.#onClick);
+ this.addEventListener('keydown', this.#onKeydown);
+ }
+ }
+
+ override disconnectedCallback(): void {
+ super.disconnectedCallback();
+ this.removeEventListener('click', this.#onClick);
+ this.removeEventListener('keydown', this.#onKeydown);
+ }
+
+ protected override willUpdate(): void {
+ const isLink = this.variant === 'link' && !!this.href;
+ this.#internals.ariaLabel = this.accessibleLabel || null;
+ this.#internals.ariaDisabled =
+ this.#disabled || this.disabledFocusable ? 'true' : null;
+ this.#internals.ariaExpanded =
+ this.expanded === undefined ? null : String(this.expanded);
+ this.#internals.setFormValue(
+ this.name == null ? null : (this.value ?? ''),
+ );
+
+ if (isLink) {
+ this.removeAttribute('tabindex');
+ this.#internals.role = 'none';
+ } else {
+ this.#internals.role = 'button';
+ if (this.#disabled) {
+ this.removeAttribute('tabindex');
+ } else {
+ this.tabIndex = 0;
+ }
+ }
+ }
+
+ protected override updated(changed: PropertyValues): void {
+ if (changed.has('hamburger') || changed.has('expanded')) {
+ if (this.hamburger && this.expanded === undefined) {
+ // eslint-disable-next-line no-console
+ console.error(
+ 'pf-v6-button: when hamburger is set, expanded must also be set. '
+ + 'A hamburger button is expected to control expansion of other content.'
+ );
+ }
+ }
+
+ if (
+ changed.has('settings')
+ || changed.has('hamburger')
+ || changed.has('favorite')
+ ) {
+ const iconOnly = this.settings || this.hamburger || this.favorite;
+ if (iconOnly && !this.accessibleLabel && !this.#hasTextContent()) {
+ // eslint-disable-next-line no-console
+ console.error(
+ 'pf-v6-button: provide visible text or accessible-label for settings, '
+ + 'hamburger, and favorite buttons.'
+ );
+ }
+ }
+
+ if (changed.has('disabled')) {
+ this.#syncCountBadgeDisabled();
+ }
+ }
+
+ override render(): TemplateResult<1> {
+ const disabled = this.#disabled;
+ const hasIcon = this.#hasIcon();
+ const hasCount = this.#slots.hasSlotted('count');
+ const hasText = this.#hasTextContent();
+ const iconAtEnd =
+ this.iconPosition === 'end' || this.iconPosition === 'right';
+ const isLoading = this.loading === true;
+ const showProgress = this.loading !== null && this.variant !== 'plain';
+ const showDanger =
+ this.variant === 'danger'
+ || (this.danger
+ && (this.variant === 'secondary' || this.variant === 'link'));
+
+ const classes = {
+ [this.variant]: true,
+ 'settings': this.settings,
+ 'hamburger': this.hamburger,
+ 'expand': this.hamburger && this.hamburgerVariant === 'expand',
+ 'collapse': this.hamburger && this.hamburgerVariant === 'collapse',
+ 'block': this.block,
+ disabled,
+ 'aria-disabled': this.disabledFocusable,
+ 'clicked': this.clicked,
+ 'inline': this.inline && this.variant === 'link',
+ 'favorite': this.favorite,
+ 'favorited': this.favorite && this.favorited,
+ 'danger': showDanger,
+ 'progress': showProgress,
+ 'in-progress': isLoading,
+ 'no-padding': this.noPadding && this.variant === 'plain',
+ 'small': this.size === 'sm',
+ 'display-lg': this.size === 'lg',
+ ...(this.variant === 'stateful' ?
+ { [this.state ?? 'unread']: true }
+ : {}),
+ hasIcon,
+ 'loading': isLoading,
+ 'anchor': !!(this.variant === 'link' && this.href),
+ };
+
+ const icon = this.#renderIcon(hasText);
+ const text = hasText ?
+ html`
+
+
+ `
+ : html` `;
+
+ const content = html`
+ ${isLoading ?
+ html`
+
+
+
+
+ `
+ : null}
+ ${iconAtEnd ? html`${text}${icon}` : html`${icon}${text}`}
+
+
+
+
+
+ `;
+
+ if (this.variant === 'link' && this.href) {
+ return html`
+ ${content}
+ `;
+ }
+
+ return html`
+ ${content}
+ `;
+ }
+
+ async formDisabledCallback(): Promise {
+ await this.updateComplete;
+ this.requestUpdate();
+ }
+
+ #hasIcon(): boolean {
+ return (
+ this.settings
+ || this.hamburger
+ || this.favorite
+ || this.loading === true
+ || !!this.icon
+ || this.#slots.hasSlotted('icon')
+ );
+ }
+
+ #hasTextContent(): boolean {
+ return this.#slots.hasSlotted();
+ }
+
+ #syncCountBadgeDisabled(): void {
+ if (isServer) {
+ return;
+ }
+ for (const badge of this.querySelectorAll('pf-v6-badge[slot="count"]')) {
+ if (this.disabled) {
+ badge.setAttribute('disabled', '');
+ } else {
+ badge.removeAttribute('disabled');
+ }
+ }
+ }
+
+ #renderIcon(hasText: boolean): TemplateResult {
+ const hasIcon = this.#hasIcon();
+ let iconContent: TemplateResult;
+
+ if (this.favorite) {
+ iconContent = this.#renderFavoriteIcons();
+ } else if (this.settings) {
+ iconContent = this.#renderSettingsIcon();
+ } else if (this.hamburger) {
+ iconContent = this.#renderHamburgerIcon();
+ } else {
+ // Always render the slot so SlotController can detect light-DOM icons.
+ iconContent = html`
+
+
+
+ `;
+ }
+
+ return html`
+
+ ${iconContent}
+ `;
+ }
+
+ #renderHamburgerIcon(): TemplateResult {
+ return html`
+
+
+
+
+
+
+ `;
+ }
+
+ #renderSettingsIcon(): TemplateResult {
+ return html`
+
+
+
+ `;
+ }
+
+ #renderFavoriteIcons(): TemplateResult {
+ return html`
+
+
+
+
+
+
+
+
+
+
+ `;
+ }
+
+ #onClick = (event: Event): void => {
+ if (!this.#operable) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ return;
+ }
+ if (this.variant === 'link' && this.href) {
+ return;
+ }
+ switch (this.type) {
+ case 'submit':
+ // Prefer this as submitter when the UA allows FACE submitters; otherwise
+ // falls back to requestSubmit(). name/value still come from setFormValue.
+ this.#internals.submit(this);
+ break;
+ case 'reset':
+ this.#internals.reset();
+ break;
+ case 'button':
+ default:
+ // Default matches React Button (`type="button"`): no form action.
+ break;
+ }
+ };
+
+ #onKeydown = (event: KeyboardEvent): void => {
+ if (this.variant === 'link' && this.href) {
+ return;
+ }
+ switch (event.key) {
+ case ' ':
+ event.preventDefault();
+ event.stopPropagation();
+ this.dispatchEvent(
+ new MouseEvent('click', {
+ bubbles: true,
+ cancelable: true,
+ view: window,
+ })
+ );
+ break;
+ case 'Enter':
+ this.dispatchEvent(
+ new MouseEvent('click', {
+ bubbles: true,
+ cancelable: true,
+ view: window,
+ })
+ );
+ break;
+ }
+ };
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'pf-v6-button': PfV6Button;
+ }
+}
diff --git a/elements/pf-v6-button/test/pf-v6-button.spec.ts b/elements/pf-v6-button/test/pf-v6-button.spec.ts
new file mode 100644
index 0000000000..3859e3cd0b
--- /dev/null
+++ b/elements/pf-v6-button/test/pf-v6-button.spec.ts
@@ -0,0 +1,435 @@
+import type { A11yTreeSnapshot } from '@patternfly/pfe-tools/test/a11y-snapshot.js';
+import { expect, html } from '@open-wc/testing';
+import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js';
+import { a11ySnapshot } from '@patternfly/pfe-tools/test/a11y-snapshot.js';
+import { sendKeys } from '@web/test-runner-commands';
+import { clickElementAtCenter } from '@patternfly/pfe-tools/test/utils.js';
+
+import { PfV6Button } from '@patternfly/elements/pf-v6-button/pf-v6-button.js';
+
+function press(key: string) {
+ return async function() {
+ await sendKeys({ press: key });
+ };
+}
+
+describe('', function() {
+ it('imperatively instantiates', function() {
+ expect(document.createElement('pf-v6-button')).to.be.an.instanceof(PfV6Button);
+ });
+
+ it('should upgrade', async function() {
+ const el = await createFixture(html`Button `);
+ expect(el, 'pf-v6-button should be an instance of PfV6Button')
+ .to.be.an.instanceof(customElements.get('pf-v6-button'))
+ .and
+ .to.be.an.instanceof(PfV6Button);
+ });
+
+ describe('simply instantiating', function() {
+ let element: PfV6Button;
+ let snapshot: A11yTreeSnapshot;
+
+ beforeEach(async function() {
+ element = await createFixture(html`
+ Save
+ `);
+ snapshot = await a11ySnapshot({ selector: 'pf-v6-button' });
+ });
+
+ it('has button role', function() {
+ expect(snapshot.role).to.equal('button');
+ });
+
+ it('exposes its label', function() {
+ expect(snapshot.name).to.equal('Save');
+ });
+
+ it('defaults to the primary variant', function() {
+ expect(element.variant).to.equal('primary');
+ });
+ });
+
+ describe('with accessible-label', function() {
+ let snapshot: A11yTreeSnapshot;
+
+ beforeEach(async function() {
+ await createFixture(html`
+
+ `);
+ snapshot = await a11ySnapshot({ selector: 'pf-v6-button' });
+ });
+
+ it('uses accessible-label as the accessible name', function() {
+ expect(snapshot.name).to.equal('Close');
+ });
+ });
+
+ describe('disabled', function() {
+ let element: PfV6Button;
+ let clicks: number;
+ let snapshot: A11yTreeSnapshot;
+
+ beforeEach(async function() {
+ clicks = 0;
+ element = await createFixture(html`
+ Disabled
+ `);
+ element.addEventListener('click', function() {
+ clicks += 1;
+ });
+ snapshot = await a11ySnapshot({ selector: 'pf-v6-button' });
+ });
+
+ it('matches :disabled', function() {
+ expect(element.matches(':disabled')).to.be.true;
+ });
+
+ it('reflects disabled in the accessibility tree', function() {
+ expect(snapshot.disabled).to.be.true;
+ });
+
+ it('does not fire click handlers when activated', async function() {
+ element.focus();
+ await sendKeys({ press: 'Enter' });
+ expect(clicks).to.equal(0);
+ });
+ });
+
+ describe('disabled-focusable', function() {
+ let element: PfV6Button;
+ let clicks: number;
+ let snapshot: A11yTreeSnapshot;
+
+ beforeEach(async function() {
+ clicks = 0;
+ element = await createFixture(html`
+ Disabled focusable
+ `);
+ element.addEventListener('click', function() {
+ clicks += 1;
+ });
+ snapshot = await a11ySnapshot({ selector: 'pf-v6-button' });
+ });
+
+ it('remains in the accessibility tree as a button', function() {
+ expect(snapshot.role).to.equal('button');
+ });
+
+ it('does not fire click handlers when activated', async function() {
+ element.focus();
+ await sendKeys({ press: 'Enter' });
+ expect(clicks).to.equal(0);
+ });
+ });
+
+ describe('variants', function() {
+ for (const variant of [
+ 'primary',
+ 'secondary',
+ 'tertiary',
+ 'danger',
+ 'warning',
+ 'link',
+ 'plain',
+ 'control',
+ 'stateful',
+ ] as const) {
+ it(`accepts the ${variant} variant`, async function() {
+ const element = await createFixture(html`
+
+ `);
+ expect(element.variant).to.equal(variant);
+ });
+ }
+ });
+
+ describe('loading', function() {
+ describe('when loading is set', function() {
+ let element: PfV6Button;
+
+ beforeEach(async function() {
+ element = await createFixture(html`
+ Loading
+ `);
+ });
+
+ it('reflects the loading attribute as true', function() {
+ expect(element.loading).to.be.true;
+ expect(element.hasAttribute('loading')).to.be.true;
+ });
+
+ it('exposes loading-label', function() {
+ expect(element.loadingLabel).to.equal('Saving');
+ });
+ });
+
+ describe('when loading is omitted', function() {
+ let element: PfV6Button;
+
+ beforeEach(async function() {
+ element = await createFixture(html`
+ Idle
+ `);
+ });
+
+ it('defaults to null (no progress layout)', function() {
+ expect(element.loading).to.be.null;
+ });
+ });
+
+ describe('when loading="false"', function() {
+ let element: PfV6Button;
+
+ beforeEach(async function() {
+ element = await createFixture(html`
+ Reserved
+ `);
+ });
+
+ it('parses as false for reserved progress padding', function() {
+ expect(element.loading).to.be.false;
+ expect(element.getAttribute('loading')).to.equal('false');
+ });
+ });
+ });
+
+ describe('icon-position', function() {
+ it('accepts deprecated right as an end alias', async function() {
+ const element = await createFixture(html`
+ Next
+ `);
+ expect(element.iconPosition).to.equal('right');
+ });
+ });
+
+ describe('link with href', function() {
+ let element: PfV6Button;
+
+ beforeEach(async function() {
+ element = await createFixture(html`
+ Docs
+ `);
+ });
+
+ it('exposes href for link buttons', function() {
+ expect(element.href).to.equal('#destination');
+ expect(element.variant).to.equal('link');
+ });
+ });
+
+ describe('form association', function() {
+ it('is a form-associated custom element', function() {
+ expect(PfV6Button.formAssociated).to.be.true;
+ });
+
+ describe('submit', function() {
+ let form: HTMLFormElement;
+ let element: PfV6Button;
+ let submitData: FormData | null;
+
+ beforeEach(async function() {
+ submitData = null;
+ form = await createFixture(html`
+
+ `);
+ element = form.querySelector('pf-v6-button')!;
+ form.addEventListener('submit', function(event) {
+ event.preventDefault();
+ submitData = new FormData(form);
+ });
+ await element.updateComplete;
+ });
+
+ it('associates with the owning form', function() {
+ expect(element.form).to.equal(form);
+ });
+
+ it('submits name and value via ElementInternals', async function() {
+ await clickElementAtCenter(element);
+ expect(submitData).to.be.ok;
+ expect(submitData!.get('save')).to.equal('yes');
+ });
+ });
+
+ describe('reset', function() {
+ let form: HTMLFormElement;
+ let element: PfV6Button;
+ let input: HTMLInputElement;
+
+ beforeEach(async function() {
+ form = await createFixture(html`
+
+ `);
+ element = form.querySelector('pf-v6-button')!;
+ input = form.querySelector('input')!;
+ input.value = 'changed';
+ await element.updateComplete;
+ });
+
+ it('resets the owning form via ElementInternals', async function() {
+ await clickElementAtCenter(element);
+ expect(input.value).to.equal('initial');
+ });
+ });
+
+ describe('type=button', function() {
+ let form: HTMLFormElement;
+ let element: PfV6Button;
+ let submitted: boolean;
+
+ beforeEach(async function() {
+ submitted = false;
+ form = await createFixture(html`
+
+ `);
+ element = form.querySelector('pf-v6-button')!;
+ form.addEventListener('submit', function(event) {
+ event.preventDefault();
+ submitted = true;
+ });
+ await element.updateComplete;
+ });
+
+ it('does not submit the form', async function() {
+ await clickElementAtCenter(element);
+ expect(submitted).to.be.false;
+ });
+ });
+
+ describe('default type', function() {
+ let form: HTMLFormElement;
+ let element: PfV6Button;
+ let submitted: boolean;
+
+ beforeEach(async function() {
+ submitted = false;
+ form = await createFixture(html`
+
+ `);
+ element = form.querySelector('pf-v6-button')!;
+ form.addEventListener('submit', function(event) {
+ event.preventDefault();
+ submitted = true;
+ });
+ await element.updateComplete;
+ });
+
+ it('does not submit the form (React type=button default)', async function() {
+ await clickElementAtCenter(element);
+ expect(submitted).to.be.false;
+ });
+ });
+ });
+
+ describe('in a fieldset', function() {
+ let element: PfV6Button;
+ let fieldset: HTMLFieldSetElement;
+ let form: HTMLFormElement;
+ let submitEvent: SubmitEvent;
+
+ beforeEach(async function() {
+ form = await createFixture(html`
+
+ `);
+ fieldset = form.querySelector('fieldset')!;
+ element = form.querySelector('pf-v6-button')!;
+ form.querySelector('input')?.focus();
+ form.addEventListener('submit', function(event) {
+ event.preventDefault();
+ submitEvent = event;
+ });
+ await element.updateComplete;
+ });
+
+ afterEach(function() {
+ // @ts-expect-error: resetting fixture
+ submitEvent = undefined;
+ });
+
+ describe('clicking the button', function() {
+ beforeEach(async function() {
+ await clickElementAtCenter(element);
+ });
+ it('submits the form', function() {
+ expect(submitEvent).to.be.ok;
+ });
+ });
+
+ describe('tabbing through', function() {
+ beforeEach(press('Tab'));
+ it('does focus the button', function() {
+ expect(document.activeElement).to.be.an.instanceof(PfV6Button);
+ });
+
+ describe('pressing Space', function() {
+ beforeEach(press(' '));
+ it('submits the form', function() {
+ expect(submitEvent).to.be.ok;
+ });
+ });
+
+ describe('pressing Enter', function() {
+ beforeEach(press('Enter'));
+ it('submits the form', function() {
+ expect(submitEvent).to.be.ok;
+ });
+ });
+ });
+
+ describe('disabling the fieldset', function() {
+ beforeEach(async function() {
+ fieldset.disabled = true;
+ await element.updateComplete;
+ });
+ it('disables the button', function() {
+ expect(element.matches(':disabled'), 'matches :disabled').to.be.true;
+ });
+ describe('tabbing through', function() {
+ beforeEach(press('Tab'));
+ it('does not focus the button', function() {
+ expect(document.activeElement).to.not.be.an.instanceof(PfV6Button);
+ });
+ });
+ describe('then disabling the button', function() {
+ beforeEach(async function() {
+ element.disabled = true;
+ await element.updateComplete;
+ });
+ describe('then enabling the button', function() {
+ beforeEach(async function() {
+ element.disabled = false;
+ await element.updateComplete;
+ });
+ describe('then enabling the fieldset', function() {
+ beforeEach(async function() {
+ fieldset.disabled = false;
+ await element.updateComplete;
+ });
+ describe('tabbing through', function() {
+ beforeEach(press('Tab'));
+ it('does focus the button', function() {
+ expect(document.activeElement).to.be.an.instanceof(PfV6Button);
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/elements/pf-v6-timestamp/test/pf-timestamp.spec.ts b/elements/pf-v6-timestamp/test/pf-timestamp.spec.ts
index 0674740815..7537aaa2cd 100644
--- a/elements/pf-v6-timestamp/test/pf-timestamp.spec.ts
+++ b/elements/pf-v6-timestamp/test/pf-timestamp.spec.ts
@@ -59,7 +59,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -74,7 +74,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -89,7 +89,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -111,7 +111,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -127,7 +127,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -142,7 +142,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -157,7 +157,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -295,7 +295,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -310,7 +310,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
@@ -325,7 +325,7 @@ describe('', function() {
beforeEach(async function() {
element = await createFixture(html`
-
+
`);
});
diff --git a/tools/pfe-tools/dev-server/plugins/templates/index.html b/tools/pfe-tools/dev-server/plugins/templates/index.html
index 52db3b0778..006a58bf87 100644
--- a/tools/pfe-tools/dev-server/plugins/templates/index.html
+++ b/tools/pfe-tools/dev-server/plugins/templates/index.html
@@ -35,7 +35,7 @@
{% endfor %}
@@ -44,12 +44,12 @@
-
+ accessible-label="Expand Main Navigation">
-
+
diff --git a/tools/pfe-tools/test/config.ts b/tools/pfe-tools/test/config.ts
index b9b66f1ecf..347d614d4b 100644
--- a/tools/pfe-tools/test/config.ts
+++ b/tools/pfe-tools/test/config.ts
@@ -28,9 +28,40 @@ const testRunnerHtml: TestRunnerConfig['testRunnerHtml'] = testFramework => /* h
}
}
+
+
+
+