Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(button): custom roles #2806

Merged
merged 8 commits into from
Jul 9, 2024
Merged
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
10 changes: 6 additions & 4 deletions core/pfe-core/controllers/internals-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ function aria(
configurable: false,
get(this: InternalsController) {
// @ts-expect-error: because i'm bad, i'm bad
return this.attach()[key];
const internals = this.attachOrRetrieveInternals();
return internals[key];
},
set(this: InternalsController, value: string | null) {
// @ts-expect-error: shamone!
this.attach()[key] = value;
const internals = this.attachOrRetrieveInternals();
internals[key] = value;
this.host.requestUpdate();
},
});
Expand Down Expand Up @@ -206,7 +208,7 @@ export class InternalsController implements ReactiveController, ARIAMixin {
`InternalsController must be instantiated with an HTMLElement or a \`getHTMLElement\` function`,
);
}
this.attach();
this.attachOrRetrieveInternals();
this.initializeOptions(options);
InternalsController.instances.set(host, this);
this.#polyfillDisabledPseudo();
Expand Down Expand Up @@ -237,7 +239,7 @@ export class InternalsController implements ReactiveController, ARIAMixin {
* Because of that, `this.internals` may not be available in the decorator setter
* so we cheat here with nullish coalescing assignment operator `??=`;
*/
private attach() {
private attachOrRetrieveInternals() {
this.internals ??= this.element!.attachInternals();
return this.internals;
}
Expand Down
70 changes: 70 additions & 0 deletions elements/pf-button/demo/user-role.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<pf-card id="custom-tabs-card">
<h2 id="title" slot="header">Button Role Example</h2>
<div id="custom-tab-group"
slot="header"
role="tablist"
aria-labelledby="title">
<pf-button id="tab-html"
role="tab"
size="small"
aria-controls="panel-html"
aria-selected="true">HTML</pf-button>
<pf-button id="tab-css"
role="tab"
size="small"
aria-controls="panel-css"
aria-selected="false">CSS</pf-button>
<pf-button id="tab-js"
role="tab"
size="small"
aria-controls="panel-js"
aria-selected="false">JS</pf-button>
</div>

<div id="panel-html" role="tabpanel" aria-labelledby="tab-html">
<strong>HTML</strong> is the foundational language of the web.
</div>

<div id="panel-css" role="tabpanel" aria-labelledby="tab-css" hidden>
<strong>CSS</strong> is used to add presentation, for advanced
layouts, and for animations
</div>

<div id="panel-js" role="tabpanel" aria-labelledby="tab-js" hidden>
<strong>JavaScript</strong> should be used sparingly to add custom
interactions and to improve accessibility
</div>

<small slot="footer">
<strong>Note:</strong> the purpose of this demo is to show how custom
roles can be applied to <code>&lt;pf-button&gt;</code>.
However, we recommend always using <code>&lt;pf-tabs&gt;</code>, and avoiding custom
implementations of existing design system patterns
</small>
</pf-card>

<style>
#custom-tabs-card {
margin: 1em;
max-width: 500px;
& h2 {
margin-inline-end: auto;
}
}
</style>

<script type="module">
import '@patternfly/elements/pf-button/pf-button.js';
const tabs = document.getElementById('custom-tab-group');
const panels = document.querySelectorAll('[role=tabpanel]');
tabs.addEventListener('click', function(event) {
const ariaControls = event.target.getAttribute('aria-controls');
if (ariaControls) {
for (const panel of panels) {
const isSelected = ariaControls === panel.id
event.target.setAttribute('aria-selected', String(isSelected));
panel.hidden = !isSelected;
}
}
})
</script>
Loading