-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ld-accordion): implement accordion component
Resolves #127
- Loading branch information
1 parent
916d465
commit 709ed6b
Showing
37 changed files
with
2,707 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions
49
src/liquid/components/ld-accordion/ld-accordion-panel/ld-accordion-panel.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
:host { | ||
/* Not using 0s here because we rely on the transition end event. */ | ||
--ld-accordion-panel-transition-duration: 0.001s; | ||
|
||
position: relative; | ||
display: block; | ||
box-sizing: border-box; | ||
max-height: var(--ld-accordion-panel-max-height, auto); | ||
overflow: hidden; | ||
background-color: var(--ld-accordion-bg-col); | ||
border-radius: var(--ld-accordion-border-radius); | ||
border-top-left-radius: inherit; | ||
border-top-right-radius: inherit; | ||
will-change: max-height; | ||
|
||
&(.ld-accordion-panel--initialized) { | ||
/* stylelint-disable-next-line plugin/no-low-performance-animation-properties */ | ||
transition: max-height var(--ld-accordion-panel-transition-duration) ease; | ||
|
||
@media (prefers-reduced-motion: no-preference) { | ||
--ld-accordion-panel-transition-duration: 0.2s; | ||
} | ||
} | ||
|
||
&(.ld-accordion-panel--expanded) { | ||
&::before { | ||
content: ''; | ||
height: var(--ld-sp-1); | ||
background-color: var(--ld-accordion-panel-border-top-color); | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
} | ||
|
||
.ld-accordion-panel__content { | ||
opacity: 1; | ||
visibility: inherit; | ||
transition: opacity var(--ld-accordion-panel-transition-duration) linear; | ||
} | ||
} | ||
} | ||
|
||
.ld-accordion-panel__content { | ||
opacity: 0; | ||
visibility: hidden; | ||
transition: opacity var(--ld-accordion-panel-transition-duration) linear, | ||
visibility 0s var(--ld-accordion-panel-transition-duration) linear; | ||
} |
111 changes: 111 additions & 0 deletions
111
src/liquid/components/ld-accordion/ld-accordion-panel/ld-accordion-panel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import '../../../components' // type definitions for type checks and intelliSense | ||
import { Component, Element, h, Host, Method, State } from '@stencil/core' | ||
import { getClassNames } from '../../../utils/getClassNames' | ||
import { closest } from '../../../utils/closest' | ||
|
||
/** | ||
* @virtualProp ref - reference to component | ||
* @virtualProp {string | number} key - for tracking the node's identity when working with lists | ||
*/ | ||
@Component({ | ||
tag: 'ld-accordion-panel', | ||
styleUrl: 'ld-accordion-panel.css', | ||
shadow: true, | ||
}) | ||
export class LdAccordionPanel { | ||
@Element() el: HTMLElement | ||
|
||
// Container to be observed for size changes. | ||
// Note that we can not observe size changes on the element itself, | ||
// As with the max-height prop applied to it changes to the content | ||
// will not trigger a resize event. Hence, we use a container element. | ||
private contentRef: HTMLDivElement | ||
|
||
@State() expanded: boolean | ||
@State() initialized = false | ||
@State() transitionEnabled = false | ||
@State() maxHeight: number | ||
@State() resizeObserver: ResizeObserver | ||
@State() innerPanelExpanding = false | ||
|
||
/** | ||
* @internal | ||
* Updates expanded state. | ||
*/ | ||
@Method() | ||
async applyMaxHeight(additionalHeightFromInnerPanel = 0) { | ||
if (additionalHeightFromInnerPanel) { | ||
this.innerPanelExpanding = true | ||
} | ||
|
||
// Apply max height on outer panel inside nested accordion. | ||
if (this.expanded) { | ||
const closestPanel = closest('ld-accordion-panel', this.el.parentElement) | ||
closestPanel?.applyMaxHeight(this.el.scrollHeight) | ||
} | ||
|
||
this.maxHeight = this.expanded | ||
? this.el.scrollHeight + additionalHeightFromInnerPanel | ||
: 0 | ||
} | ||
|
||
/** | ||
* @internal | ||
* Updates expanded state. | ||
*/ | ||
@Method() | ||
async setExpanded(expanded: boolean) { | ||
this.expanded = expanded | ||
|
||
this.applyMaxHeight() | ||
} | ||
|
||
private onTransitionEnd = (ev: TransitionEvent) => { | ||
if (ev.target === this.el) { | ||
this.innerPanelExpanding = false | ||
} | ||
} | ||
|
||
componentDidLoad() { | ||
setTimeout(() => { | ||
this.resizeObserver = new ResizeObserver(() => { | ||
// When a panel is expanding inside a nested accordion, the nested panel | ||
// takes over the responsibility for updating the max-height on the outer | ||
// panel. In other words: We disable the observer callback function in | ||
// order to instantly update the max-height for a better performance. | ||
if (!this.innerPanelExpanding) { | ||
this.applyMaxHeight() | ||
} | ||
}) | ||
this.resizeObserver.observe(this.contentRef) | ||
this.initialized = true | ||
}) | ||
} | ||
|
||
disconnectedCallback() { | ||
this.resizeObserver.unobserve(this.contentRef) | ||
} | ||
|
||
render() { | ||
const cl = getClassNames([ | ||
'ld-accordion-panel', | ||
this.expanded && 'ld-accordion-panel--expanded', | ||
this.initialized && 'ld-accordion-panel--initialized', | ||
]) | ||
|
||
return ( | ||
<Host | ||
style={{ '--ld-accordion-panel-max-height': this.maxHeight + 'px' }} | ||
class={cl} | ||
onTransitionEnd={this.onTransitionEnd} | ||
> | ||
<div | ||
ref={(ref) => (this.contentRef = ref)} | ||
class="ld-accordion-panel__content" | ||
> | ||
<slot></slot> | ||
</div> | ||
</Host> | ||
) | ||
} | ||
} |
Oops, something went wrong.