Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .changeset/bright-buttons-port.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
"@patternfly/elements": major
"@patternfly/pfe-core": patch
---

`<pf-v6-button>`: replaces `<pf-v5-button>` with PatternFly v6 design specs and React Button parity.

```html
<pf-v6-button variant="secondary">Secondary</pf-v6-button>
<pf-v6-button type="submit">Save</pf-v6-button>
```

**Breaking Changes from v5**

- Renamed tag from `<pf-v5-button>` to `<pf-v6-button>`
- 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.
33 changes: 28 additions & 5 deletions core/pfe-core/controllers/internals-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,20 @@ type InternalsHost = ReactiveControllerHost & HTMLElement;
export class InternalsController implements ReactiveController, ARIAMixin {
private static instances = new WeakMap<HTMLElement, InternalsController>();

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[];
}
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 9 additions & 1 deletion core/pfe-core/controllers/roving-tabindex-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions docs/_includes/_nav.njk
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
</a>
</div>
<pf-v5-dropdown id="docs-versions-dropdown">
<pf-v5-button slot="toggle"
<pf-v6-button slot="toggle"
variant="control"
icon="caret-down"
icon-set="fas">Versions</pf-v5-button>
icon-set="fas">Versions</pf-v6-button>
<pf-v5-dropdown-menu slot="menu">
{% for version in versions %}
{%- if version.current -%}
Expand Down
2 changes: 1 addition & 1 deletion docs/_plugins/pfe-assets.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/develop/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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"
Expand Down
6 changes: 3 additions & 3 deletions docs/framework-integration/react.md
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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.
Expand Down Expand Up @@ -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/
Expand Down
2 changes: 1 addition & 1 deletion docs/framework-integration/vue.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ tags:
Organically grow the holistic world view of disruptive
innovation via workplace diversity and empowerment.
</p>
<pf-v5-button slot="footer" variant="link" href="#">Learn more</pf-v5-button>
<pf-v6-button slot="footer" variant="link" href="#">Learn more</pf-v6-button>
</pf-v5-card>
</div>
</template>
Expand Down
10 changes: 5 additions & 5 deletions docs/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ title: Get started
<pf-v5-card>
<h3 slot="header">Card header</h3>
<p>This is the pf-v5-card body.</p>
<pf-v5-button slot="footer">OK</pf-v5-button>
<pf-v6-button slot="footer">OK</pf-v6-button>
</pf-v5-card>
```

<pf-v5-card>
<h3 slot="header">Card header</h3>
<p>This is the pf-v5-card body.</p>
<pf-v5-button slot="footer">OK</pf-v5-button>
<pf-v6-button slot="footer">OK</pf-v6-button>
</pf-v5-card>

### Importmap and Markup
Expand All @@ -94,14 +94,14 @@ Altogether your import map code could look something like this [Lit Playground D
<pf-v5-card rounded>
<h3 slot="header">Card header</h3>
<p>This is the pf-v5-card body.</p>
<pf-v5-button slot="footer">OK</pf-v5-button>
<pf-v6-button slot="footer">OK</pf-v6-button>
</pf-v5-card>
```

<pf-v5-card rounded>
<h3 slot="header">Card header</h3>
<p>This is the pf-v5-card body.</p>
<pf-v5-button slot="footer">OK</pf-v5-button>
<pf-v6-button slot="footer">OK</pf-v6-button>
</pf-v5-card>
{% endband %}

Expand All @@ -122,7 +122,7 @@ Altogether your import map code could look something like this [Lit Playground D
<pf-v5-card flat rounded style="--pf-v5-c-card--BackgroundColor: var(--pf-global--active-color--200, #bee1f4);">
<h3 slot="header">Card header</h3>
<p>This is the pf-v5-card body.</p>
<pf-v5-button slot="footer">OK</pf-v5-button>
<pf-v6-button slot="footer">OK</pf-v6-button>
</pf-v5-card>
{% endband %}

Expand Down
2 changes: 1 addition & 1 deletion docs/main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
2 changes: 1 addition & 1 deletion elements/pf-v5-accordion/demo/bordered.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ <h3>Item five</h3>

<script type="module">
import '@patternfly/elements/pf-v5-accordion/pf-v5-accordion.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-v6-switch/pf-v6-switch.js';

const bordered = document.getElementById('bordered-example');
Expand Down
4 changes: 2 additions & 2 deletions elements/pf-v5-accordion/demo/fixed-panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ <h3>Item three</h3>
</pf-v5-accordion-header>
<pf-v5-accordion-panel>
<p>Morbi vitae urna quis nunc convallis hendrerit. Aliquam congue orci quis ultricies tempus.</p>
<pf-v5-button>Focus on me!</pf-v5-button>
<pf-v6-button>Focus on me!</pf-v6-button>
</pf-v5-accordion-panel>
<pf-v5-accordion-header>
<h3>Item four</h3>
Expand Down Expand Up @@ -85,7 +85,7 @@ <h3>Item five</h3>

<script type="module">
import '@patternfly/elements/pf-v5-accordion/pf-v5-accordion.js';
import '@patternfly/elements/pf-v5-button/pf-v5-button.js';
import '@patternfly/elements/pf-v6-button/pf-v6-button.js';
</script>

<style>
Expand Down
5 changes: 2 additions & 3 deletions elements/pf-v5-accordion/test/pf-accordion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -675,8 +675,7 @@ describe('<pf-v5-accordion>', function() {
describe('Shift+Tab', function() {
beforeEach(press('Shift+Tab'));
it('moves focus to the body', async function() {
const snapshot = await a11ySnapshot();
expect(querySnapshot(snapshot, { focused: true })).to.not.be.ok;
expect(await a11ySnapshot()).to.not.axContainQuery({ role: 'button', focused: true });
});
});

Expand Down Expand Up @@ -1166,7 +1165,7 @@ describe('<pf-v5-accordion>', function() {
describe('Tab', function() {
beforeEach(press('Tab'));
it('moves focus to the body', async function() {
expect(await a11ySnapshot()).to.have.axTreeFocusOn(document.body);
expect(await a11ySnapshot()).to.not.axContainQuery({ role: 'button', focused: true });
});
});
});
Expand Down
4 changes: 2 additions & 2 deletions elements/pf-v5-alert/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ Inline alert example:
A new system update is available.

<div slot="actionLinks">
<pf-v5-button plain>Update Now</pf-v5-button>
<pf-v5-button plain>Later</pf-v5-button>
<pf-v6-button variant="plain">Update Now</pf-v6-button>
<pf-v6-button variant="plain">Later</pf-v6-button>
</div>
</pf-v5-alert>
```
Expand Down
2 changes: 1 addition & 1 deletion elements/pf-v5-alert/demo/expandable.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<script type="module">
import '@patternfly/elements/pf-v5-alert/pf-v5-alert.js';
import '@patternfly/elements/pf-v5-button/pf-v5-button.js';
import '@patternfly/elements/pf-v6-button/pf-v6-button.js';
</script>

<style>
Expand Down
10 changes: 5 additions & 5 deletions elements/pf-v5-alert/demo/timeout.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<pf-v5-button id="addAlertButton"
variant="secondary">Add alert</pf-v5-button>
<pf-v5-button id="removeAllAlertsButton"
variant="secondary">Remove all alerts</pf-v5-button>
<pf-v6-button id="addAlertButton"
variant="secondary">Add alert</pf-v6-button>
<pf-v6-button id="removeAllAlertsButton"
variant="secondary">Remove all alerts</pf-v6-button>

<div id="alert-container">
</div>

<script type="module">
import '@patternfly/elements/pf-v5-alert/pf-v5-alert.js';
import '@patternfly/elements/pf-v5-button/pf-v5-button.js';
import '@patternfly/elements/pf-v6-button/pf-v6-button.js';

const addAlertButton = document.getElementById('addAlertButton');
const removeAllAlertsButton = document.getElementById('removeAllAlertsButton');
Expand Down
2 changes: 1 addition & 1 deletion elements/pf-v5-alert/demo/variations.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

<script type="module">
import '@patternfly/elements/pf-v5-alert/pf-v5-alert.js';
import '@patternfly/elements/pf-v5-button/pf-v5-button.js';
import '@patternfly/elements/pf-v6-button/pf-v6-button.js';
</script>

<style>
Expand Down
16 changes: 8 additions & 8 deletions elements/pf-v5-alert/pf-v5-alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { observes } from '@patternfly/pfe-core/decorators.js';

import '@patternfly/elements/pf-v5-icon/pf-v5-icon.js';
import '@patternfly/elements/pf-v5-button/pf-v5-button.js';
import '@patternfly/elements/pf-v6-button/pf-v6-button.js';

import styles from './pf-v5-alert.css';

Expand Down Expand Up @@ -133,16 +133,16 @@ export class PfV5Alert extends LitElement {
const { expandable, expanded, variant } = this;
const icon = this.icon ?? VariantIconMap.get(variant);
return html`
<pf-v5-button id="toggle"
plain
<pf-v6-button id="toggle"
variant="plain"
?hidden="${!expandable}"
icon="${expandable ? 'angle-down' : 'angle-right'}"
icon-set="fas"
@click="${this.#onToggleClick}"
aria-controls="${ifDefined(expandable ? 'description' : undefined)}"
aria-expanded="${ifDefined(expandable ? String(expanded) : undefined)}"
aria-label="${expanded ? 'Collapse Alert' : 'Expand Alert'}">
</pf-v5-button>
accessible-label="${expanded ? 'Collapse Alert' : 'Expand Alert'}">
</pf-v6-button>

<div id="icon">
<slot name="icon">
Expand All @@ -163,13 +163,13 @@ export class PfV5Alert extends LitElement {
<slot name="actions"></slot>
</div>

<pf-v5-button id="close"
plain
<pf-v6-button id="close"
variant="plain"
icon="close"
icon-set="patternfly"
?hidden="${!this.dismissable}"
@click="${this.#onCloseClick}">
</pf-v5-button>
</pf-v6-button>
`;
}

Expand Down
Loading
Loading