web: Enhance accordion header interactions for better UX (#12813)
web: Refine accordion headers for pressability. - Allows user to click or tap anywhere on a accordion header to expand or collapse. - Adds transition to collapse.
This commit is contained in:
@ -125,6 +125,11 @@ html > form > input {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.pf-m-pressable {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Flow-card adjustments for static pages */
|
||||
.pf-c-brand {
|
||||
padding-top: calc(
|
||||
|
@ -3,6 +3,7 @@ import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { createRef, ref } from "lit/directives/ref.js";
|
||||
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
@ -14,13 +15,9 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
*
|
||||
* Mostly visual effects, with a single interaction for opening/closing the view.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO: Listen for custom events from its children about 'invalidation' events, and
|
||||
* @todo Listen for custom events from its children about 'invalidation' events, and
|
||||
* trigger the `expanded` property as needed.
|
||||
*/
|
||||
|
||||
@customElement("ak-form-group")
|
||||
export class FormGroup extends AKElement {
|
||||
@property({ type: Boolean, reflect: true })
|
||||
@ -36,15 +33,68 @@ export class FormGroup extends AKElement {
|
||||
PFButton,
|
||||
PFFormControl,
|
||||
css`
|
||||
/**
|
||||
* Workaround to trigger the hover effect on the button when the header is hovered.
|
||||
*
|
||||
* Alternatively, we group the expander button and header, but the grid would have to be
|
||||
* restructured to allow for this.
|
||||
*/
|
||||
.pf-c-form__field-group:has(.pf-c-form__field-group-header:hover) .pf-c-button {
|
||||
color: var(--pf-global--Color--100) !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transition ensuring a smooth animation when the body is expanded/collapsed.
|
||||
*/
|
||||
slot[name="body"] {
|
||||
transition-behavior: allow-discrete;
|
||||
transition-property: opacity, display, transform;
|
||||
transition-duration: var(--pf-global--TransitionDuration);
|
||||
transition-timing-function: var(--pf-global--TimingFunction);
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transform: scaleY(1);
|
||||
transform-origin: top left;
|
||||
will-change: opacity, display, transform;
|
||||
}
|
||||
|
||||
slot[name="body"][hidden] {
|
||||
opacity: 0 !important;
|
||||
display: none !important;
|
||||
transform: scaleY(0) !important;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
slot[name="body"] {
|
||||
transition-duration: 0s;
|
||||
}
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
formRef = createRef<HTMLFormElement>();
|
||||
|
||||
scrollAnimationFrame = -1;
|
||||
|
||||
scrollIntoView = (): void => {
|
||||
this.formRef.value?.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
});
|
||||
};
|
||||
|
||||
toggleExpanded = (): void => {
|
||||
cancelAnimationFrame(this.scrollAnimationFrame);
|
||||
|
||||
this.expanded = !this.expanded;
|
||||
|
||||
if (this.expanded) {
|
||||
this.scrollAnimationFrame = requestAnimationFrame(this.scrollIntoView);
|
||||
}
|
||||
};
|
||||
|
||||
render(): TemplateResult {
|
||||
return html` <div class="pf-c-form">
|
||||
return html`<div class="pf-c-form" ${ref(this.formRef)}>
|
||||
<div class="pf-c-form__field-group ${this.expanded ? "pf-m-expanded" : ""}">
|
||||
<div class="pf-c-form__field-group-toggle">
|
||||
<div class="pf-c-form__field-group-toggle-button">
|
||||
@ -53,9 +103,7 @@ export class FormGroup extends AKElement {
|
||||
type="button"
|
||||
aria-expanded="${this.expanded}"
|
||||
aria-label=${this.ariaLabel}
|
||||
@click=${() => {
|
||||
this.expanded = !this.expanded;
|
||||
}}
|
||||
@click=${this.toggleExpanded}
|
||||
>
|
||||
<span class="pf-c-form__field-group-toggle-icon">
|
||||
<i class="fas fa-angle-right" aria-hidden="true"></i>
|
||||
@ -63,7 +111,12 @@ export class FormGroup extends AKElement {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-c-form__field-group-header">
|
||||
<div
|
||||
class="pf-c-form__field-group-header pf-m-pressable"
|
||||
@click=${this.toggleExpanded}
|
||||
aria-expanded=${this.expanded}
|
||||
aria-role="button"
|
||||
>
|
||||
<div class="pf-c-form__field-group-header-main">
|
||||
<div class="pf-c-form__field-group-header-title">
|
||||
<div class="pf-c-form__field-group-header-title-text">
|
||||
|
Reference in New Issue
Block a user