Skip to content

Commit

Permalink
fix: header-sticky script converted to a component
Browse files Browse the repository at this point in the history
  • Loading branch information
marsanwedoo committed Nov 25, 2022
1 parent 4456c53 commit 1a23929
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 30 deletions.
2 changes: 2 additions & 0 deletions src/js/bootstrap-italia.entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
UploadDragDrop,
BackToTop,
Sticky,
HeaderSticky,
HistoryBack,
Forward,
Masonry,
Expand Down Expand Up @@ -74,6 +75,7 @@ window.bootstrap = {
ProgressDonut,
SelectAutocomplete,
Sticky,
HeaderSticky,
TrackFocus,
Transfer,
UploadDragDrop,
Expand Down
1 change: 1 addition & 0 deletions src/js/bootstrap-italia.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { default as NavBarCollapsible } from './plugins/navbar-collapsible'
export { default as Accordion } from './plugins/accordion'
export { default as NavScroll } from './plugins/navscroll'
export { default as Sticky } from './plugins/sticky'
export { default as HeaderSticky } from './plugins/header-sticky'
export { default as TrackFocus } from './plugins/track-focus'
export { FormValidate, ValidatorSelectAutocomplete } from './plugins/form-validate'
export { default as Input } from './plugins/input'
Expand Down
104 changes: 74 additions & 30 deletions src/js/plugins/header-sticky.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import SelectorEngine from 'bootstrap/js/src/dom/selector-engine'
import { isVisible } from 'bootstrap/js/src/util'

import Sticky from './sticky'

import onDocumentScroll from './util/on-document-scroll'

const CLASS_NAME_CLONED_HEADER = 'cloned-element'
const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_ISTICKY = 'is-sticky'

const SELECTOR_HEADER = '.it-header-sticky'
const SELECTOR_TOGGLER = '.custom-navbar-toggler'
Expand All @@ -12,35 +17,68 @@ const SELECTOR_SEARCH_WRAPPER = '.it-search-wrapper'
const SELECTOR_USER_WRAPPER = '.it-user-wrapper'
const SELECTOR_CLONED = `.${CLASS_NAME_CLONED_HEADER}`

const toggleClonedElement = (targetHeader, toAdd = true) => {
const isDesktop = !isVisible(SelectorEngine.findOne(SELECTOR_TOGGLER, targetHeader))
const dataSet = new Map()

if (isDesktop) {
const target = SelectorEngine.findOne(SELECTOR_MENU_WRAPPER, targetHeader)
class HeaderSticky {
//HeaderSticky uses Sticky so it can't be a Bootstrap BaseComponent
constructor(element) {
if (dataSet.get(element)) {
return null
}

if (toAdd) {
const elBrand = SelectorEngine.findOne(SELECTOR_BRAND_WRAPPER, targetHeader)
const elSearch = SelectorEngine.findOne(SELECTOR_SEARCH_WRAPPER, targetHeader)
const elUser = SelectorEngine.findOne(SELECTOR_USER_WRAPPER, targetHeader)
this._element = element
this._elementObj = Sticky.getOrCreateInstance(element)

const clonedBrand = elBrand ? elBrand.cloneNode(true) : null
const clonedSearch = elSearch ? elSearch.cloneNode(true) : null
const clonedUser = elUser ? elUser.cloneNode(true) : null
dataSet.set(element, this._elementObj)

if (clonedBrand) {
target.insertBefore(clonedBrand, target.childNodes[0]).classList.add(CLASS_NAME_CLONED_HEADER)
}
if (clonedSearch) {
target.appendChild(clonedSearch).classList.add(CLASS_NAME_CLONED_HEADER)
}
if (clonedUser) {
target.appendChild(clonedUser).classList.add(CLASS_NAME_CLONED_HEADER)
target.appendChild(clonedUser).classList.remove(CLASS_NAME_SHOW)
this._bindEvents()

this._toggleClonedElement(this._element.classList.contains(CLASS_NAME_ISTICKY))
}

//Static

static getOrCreateInstance(element) {
return dataSet.get(element) || new this(element)
}

//Private

_bindEvents() {
this._element.addEventListener('on.bs.sticky', () => this._toggleClonedElement(true))
this._element.addEventListener('off.bs.sticky', () => this._toggleClonedElement(false))
}

_toggleClonedElement(toAdd = true) {
const isDesktop = !isVisible(SelectorEngine.findOne(SELECTOR_TOGGLER, this._element))

if (isDesktop) {
const target = SelectorEngine.findOne(SELECTOR_MENU_WRAPPER, this._element)

if (toAdd) {
const elBrand = SelectorEngine.findOne(SELECTOR_BRAND_WRAPPER, this._element)
const elSearch = SelectorEngine.findOne(SELECTOR_SEARCH_WRAPPER, this._element)
const elUser = SelectorEngine.findOne(SELECTOR_USER_WRAPPER, this._element)

const clonedBrand = elBrand ? elBrand.cloneNode(true) : null
const clonedSearch = elSearch ? elSearch.cloneNode(true) : null
const clonedUser = elUser ? elUser.cloneNode(true) : null

if (clonedBrand) {
target.insertBefore(clonedBrand, target.childNodes[0]).classList.add(CLASS_NAME_CLONED_HEADER)
}
if (clonedSearch) {
target.appendChild(clonedSearch).classList.add(CLASS_NAME_CLONED_HEADER)
}
if (clonedUser) {
target.appendChild(clonedUser).classList.add(CLASS_NAME_CLONED_HEADER)
target.appendChild(clonedUser).classList.remove(CLASS_NAME_SHOW)
}
} else {
SelectorEngine.find(SELECTOR_CLONED, this._element).forEach((item) => {
item.parentElement.removeChild(item)
})
}
} else {
SelectorEngine.find(SELECTOR_CLONED, targetHeader).forEach((item) => {
item.parentElement.removeChild(item)
})
}
}

Expand All @@ -51,11 +89,17 @@ const toggleClonedElement = (targetHeader, toAdd = true) => {
}*/
}

const init = (targetHeader) => {
targetHeader.addEventListener('on.bs.sticky', () => toggleClonedElement(targetHeader, true))
targetHeader.addEventListener('off.bs.sticky', () => toggleClonedElement(targetHeader, false))
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/

SelectorEngine.find(SELECTOR_HEADER).forEach((header) => {
init(header)
onDocumentScroll(() => {
const stickies = SelectorEngine.find(SELECTOR_HEADER)
stickies.map((sticky) => {
HeaderSticky.getOrCreateInstance(sticky)
})
})

export default HeaderSticky

0 comments on commit 1a23929

Please sign in to comment.