From cc69840fcd7722430675e04540da319f1bbf1ad7 Mon Sep 17 00:00:00 2001 From: Teffen Ellis Date: Sat, 25 Jan 2025 04:09:13 -0500 Subject: [PATCH] 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. --- web/src/common/styles/authentik.css | 5 +++ web/src/elements/forms/FormGroup.ts | 67 ++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/web/src/common/styles/authentik.css b/web/src/common/styles/authentik.css index 9804d343f3f8..a1da71a7608c 100644 --- a/web/src/common/styles/authentik.css +++ b/web/src/common/styles/authentik.css @@ -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( diff --git a/web/src/elements/forms/FormGroup.ts b/web/src/elements/forms/FormGroup.ts index 92986eaecf4a..f782ef026650 100644 --- a/web/src/elements/forms/FormGroup.ts +++ b/web/src/elements/forms/FormGroup.ts @@ -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,62 @@ 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; } `, ]; } + formRef = createRef(); + + 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`
+ return html`
@@ -53,9 +97,7 @@ export class FormGroup extends AKElement { type="button" aria-expanded="${this.expanded}" aria-label=${this.ariaLabel} - @click=${() => { - this.expanded = !this.expanded; - }} + @click=${this.toggleExpanded} > @@ -63,7 +105,12 @@ export class FormGroup extends AKElement {
-
+