Skip to content

Commit

Permalink
add optional mutation observer on marquee
Browse files Browse the repository at this point in the history
  • Loading branch information
Applelo committed Feb 13, 2024
1 parent 66e8821 commit d2d52e4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 8 deletions.
3 changes: 2 additions & 1 deletion docs/demo/dropdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

onMounted(() => {
const dropdown = new Dropdown('#dropdown', {
openOn: 'hover'
openOn: 'hover',
setWidth: true
})
const dropdownMenu = new Dropdown('#dropdown-menu')
})
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/components/dropdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export interface DropdownOptions extends ParentOptions {
* @default undefined
*/
enforceType?: 'default' | 'menu'
/**
* Use ResizeObserver to get and set the width on the trigger and the container
* @default false
*/
setWidth?: boolean
/**
* Use MutationObserver to update component on changes
* @default true
Expand All @@ -37,6 +42,8 @@ export default class Dropdown extends Parent {
private opened: boolean = false

private mutationObserver?: MutationObserver
private resizeObserver?: ResizeObserver
private widthCssVar = '--c-dropdown-width'

constructor(el: HTMLElement | string, options: DropdownOptions = {}) {
super(el, options)
Expand Down Expand Up @@ -68,10 +75,16 @@ export default class Dropdown extends Parent {
: new MutationObserver(() => {
this.update()
})
this.resizeObserver = this.opts.setWidth === true
? new ResizeObserver(() => {
this.setWidth()
})
: undefined
this.mutationObserver?.observe(this.el, {
childList: true,
subtree: true,
})
this.resizeObserver?.observe(this.el)
this.opened = this.triggerEl.getAttribute('aria-expanded') === 'true'

super.init()
Expand Down Expand Up @@ -252,6 +265,19 @@ export default class Dropdown extends Parent {
: 'default'
}

private setWidth() {
this.el.classList.remove('c-dropdown--setwidth')
this.el.style.removeProperty(this.widthCssVar)
if (!this.triggerEl || !this.menuEl)
return
const triggerWidth = this.triggerEl.clientWidth
const containerWidth = this.menuEl.clientWidth
console.log(triggerWidth, containerWidth)

Check failure on line 275 in packages/core/src/components/dropdown.ts

View workflow job for this annotation

GitHub Actions / Lint: node-18, ubuntu-latest

Unexpected console statement
const maxWidth = Math.max(triggerWidth, containerWidth)
this.el.style.setProperty(this.widthCssVar, `${Math.ceil(maxWidth)}px`)
this.el.classList.add('c-dropdown--setwidth')
}

/**
* Close the dropdown
*/
Expand Down Expand Up @@ -281,6 +307,7 @@ export default class Dropdown extends Parent {
}

public destroy() {
this.resizeObserver?.disconnect()
this.mutationObserver?.disconnect()
if (this.triggerEl) {
if (this.triggerEl.tagName !== 'BUTTON')
Expand Down
21 changes: 14 additions & 7 deletions packages/core/src/components/marquee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ export interface MarqueeOptions extends ParentOptions {
* @default 1
*/
duration?: number | string
/**
* Use MutationObserver to update component on changes
* @default true
*/
mutationObserver?: boolean
}

export default class Marquee extends Parent {
Expand Down Expand Up @@ -68,19 +73,21 @@ export default class Marquee extends Parent {
this.update()
this.containerEl = this.el.querySelector('.c-marquee-container')

this.mutationObserver = new MutationObserver(([el]) => {
const addedEls = Array.from(el.addedNodes) as HTMLElement[]
const isFilling = addedEls.findIndex(item => item.classList.contains('c-marquee-clone')) === -1
if (!isFilling)
this.update(this.opts.fill)
})
this.mutationObserver = this.opts.mutationObserver === false
? undefined
: new MutationObserver(([el]) => {
const addedEls = Array.from(el.addedNodes) as HTMLElement[]
const isFilling = addedEls.findIndex(item => item.classList.contains('c-marquee-clone')) === -1
if (!isFilling)
this.update(this.opts.fill)
})
this.resizeObserver = new ResizeObserver(() => {
// fix wrong calculation from Firefox
setTimeout(() => this.update(), 1)
})

this.resizeObserver.observe(this.el)
this.mutationObserver.observe(this.el, {
this.mutationObserver?.observe(this.el, {
childList: true,
subtree: true,
})
Expand Down

0 comments on commit d2d52e4

Please sign in to comment.