@simhub2/justflipit 4.0.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +243 -99
- package/dist/justFlipIt-combined.js +60 -28
- package/dist/justFlipIt-combined.min.js +12 -10
- package/dist/justFlipIt-modern.js +60 -28
- package/dist/justFlipIt-modern.min.js +12 -10
- package/dist/justFlipIt-vanilla.js +60 -28
- package/dist/justFlipIt-vanilla.min.js +12 -10
- package/dist/justFlipIt.cjs +60 -28
- package/dist/justFlipIt.cjs.map +2 -2
- package/dist/justFlipIt.js +60 -28
- package/dist/justFlipIt.js.map +2 -2
- package/dist/justFlipIt.min.js +12 -10
- package/dist/justFlipIt.min.js.map +3 -3
- package/dist/justFlipIt.mjs +60 -28
- package/dist/justFlipIt.mjs.map +2 -2
- package/package.json +1 -1
package/dist/justFlipIt.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/core.js"],
|
|
4
|
-
"sourcesContent": ["const instances = new WeakMap();\nconst defaults = { Click: false, FlipX: false, Duration: 400, Easing: 'cubic-bezier(.22,.61,.36,1)', Tilt: false, Effect: 'flip', ReducedMotion: true, preserveClasses: true, preserveStyles: true, Style: [] };\nconst css = `\n._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}\n._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}\n._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}\n._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}\n._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}\n._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}\n._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}\n._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{transform:scale(.94)}\n._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}\n._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}\n@media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}\n`;\nfunction styles(doc) {\n if (doc.querySelector('style[data-justflipitstyle=\"v4\"]')) return;\n const style = doc.createElement('style');\n style.dataset.justflipitstyle = 'v4'; style.textContent = css; doc.head.append(style);\n}\nfunction validate(options) {\n if (options.Duration !== undefined && (!Number.isFinite(options.Duration) || options.Duration < 0)) throw new TypeError('Duration must be a non-negative finite number');\n if (options.Effect !== undefined && !['flip', 'fade', 'scale'].includes(options.Effect)) throw new TypeError('Unknown Effect');\n if (options.Tilt && typeof options.Tilt === 'object') {\n for (const key of ['max', 'perspective', 'scale']) {\n if (options.Tilt[key] !== undefined && (!Number.isFinite(options.Tilt[key]) || options.Tilt[key] < 0)) throw new TypeError(`Invalid Tilt.${key}`);\n }\n }\n}\nexport class FlipController {\n constructor(element, options = {}) {\n validate(options);\n if (!element || element.nodeType !== 1) throw new TypeError('Expected an HTML element');\n this.element = element; this.settings = { ...defaults, ...options }; this.flipped = false; this.destroyed = false;\n this.cleanups = []; this.restores = []; this.win = element.ownerDocument.defaultView;\n const doc = element.ownerDocument; styles(doc);\n this.managed = !!options.Faces;\n if (this.managed) {\n this.hoverPanel = element;\n this.frontWrapper = element.querySelector(options.Faces.front);\n this.backWrapper = element.querySelector(options.Faces.back);\n if (!this.frontWrapper || !this.backWrapper || this.frontWrapper === this.backWrapper || this.frontWrapper.parentNode !== element || this.backWrapper.parentNode !== element) throw new TypeError('Faces must select two distinct direct children');\n } else {\n if (!element.parentNode) throw new TypeError('Element must have a parent');\n this.hoverPanel = doc.createElement('div');\n this.frontWrapper = doc.createElement('div'); this.backWrapper = doc.createElement('div');\n if (this.settings.preserveClasses) this.hoverPanel.className = element.className;\n if (this.settings.preserveStyles) this.hoverPanel.style.cssText = element.style.cssText;\n element.before(this.hoverPanel); this.hoverPanel.append(this.frontWrapper, this.backWrapper);\n this.frontWrapper.append(element);\n if (options.Template !== undefined) this.backWrapper.innerHTML = options.Template;\n else {\n const clone = element.cloneNode(true);\n clone.removeAttribute('id'); clone.querySelectorAll('[id]').forEach(node => node.removeAttribute('id'));\n this.backWrapper.append(clone);\n }\n }\n const panel = this.hoverPanel;\n for (const node of [panel, this.frontWrapper, this.backWrapper]) {\n const owned = node === panel ? ['class', 'style', 'tabindex', 'data-jfi-axis', 'data-jfi-effect', 'data-jfi-motion', 'data-jfi-flipped', 'data-jfi-reduced'] : ['style', 'data-jfi-face', 'aria-hidden', 'inert'];\n const attrs = owned.map(name => [name, node.getAttribute(name)]);\n const inert = node.inert || false;\n this.restores.push(() => { node.inert = inert; for (const [name, value] of attrs) { if (value === null) node.removeAttribute(name); else node.setAttribute(name, value); } });\n }\n panel.classList.add('_justFlipIt_panel');\n this.frontWrapper.dataset.jfiFace = 'front'; this.backWrapper.dataset.jfiFace = 'back';\n this.motion = this.win.matchMedia?.('(prefers-reduced-motion: reduce)');\n const motionChange = () => { this.resetTilt(); this.render(); };\n this.motion?.addEventListener('change', motionChange);\n this.cleanups.push(() => this.motion?.removeEventListener('change', motionChange));\n this.configure(); this.events(); this.render();\n instances.set(element, this); instances.set(panel, this);\n }\n listen(type, handler, options) { this.hoverPanel.addEventListener(type, handler, options); this.cleanups.push(() => this.hoverPanel.removeEventListener(type, handler, options)); }\n get reduced() { return this.settings.ReducedMotion !== false && !!this.motion?.matches; }\n configure() {\n const s = this.settings, p = this.hoverPanel;\n p.style.setProperty('--jfi-duration', `${s.Duration}ms`); p.style.setProperty('--jfi-easing', s.Easing);\n p.dataset.jfiAxis = s.FlipX ? 'x' : 'y'; p.dataset.jfiEffect = s.Effect;\n p.dataset.jfiMotion = s.ReducedMotion === false ? 'allow' : 'respect';\n for (const item of s.Style || []) {\n const targets = item.el === 'self' ? [p] : p.querySelectorAll(item.el);\n targets.forEach(node => Object.assign(node.style, item.style));\n }\n // A generic keyboard focus target avoids button roles around interactive children.\n if (s.Tilt !== 'only' && !p.hasAttribute('tabindex')) p.tabIndex = 0;\n }\n events() {\n this.listen('click', event => {\n if (this.settings.Tilt === 'only') return;\n const trigger = this.settings.Click;\n if (trigger === true || (trigger && [].concat(trigger).some(selector => event.target.closest?.(selector) && this.hoverPanel.contains(event.target.closest(selector))))) this.toggle();\n });\n this.listen('keydown', event => {\n if (event.target !== this.hoverPanel || this.settings.Tilt === 'only') return;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); this.toggle(); }\n if (event.key === 'Escape') this.flip(false);\n });\n this.listen('pointerenter', event => { if (!this.settings.Click && this.settings.Tilt !== 'only' && event.pointerType !== 'touch') this.flip(true); });\n this.listen('pointerleave', () => { this.resetTilt(); if (!this.settings.Click && this.settings.Tilt !== 'only') this.flip(false); });\n this.listen('pointercancel', () => this.resetTilt());\n this.listen('pointerup', event => { if (event.pointerType === 'touch') { this.resetTilt(); if (!this.settings.Click && this.settings.Tilt !== 'only') this.toggle(); } });\n this.listen('pointermove', event => {\n if (!this.settings.Tilt || this.reduced || event.pointerType === 'touch') return;\n this.point = [event.clientX, event.clientY];\n if (this.frame) return;\n this.frame = this.win.requestAnimationFrame(() => {\n this.frame = 0;\n const rect = this.hoverPanel.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const t = { max: 10, perspective: 1000, scale: 1.03, ...(typeof this.settings.Tilt === 'object' ? this.settings.Tilt : {}) };\n const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));\n const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));\n this.hoverPanel.style.transform = `perspective(${t.perspective}px) rotateX(${-y * t.max}deg) rotateY(${x * t.max}deg) scale(${t.scale})`;\n });\n }, { passive: true });\n this.baseTransform = this.hoverPanel.style.transform;\n }\n resetTilt() { if (this.frame) this.win.cancelAnimationFrame(this.frame); this.frame = 0; this.hoverPanel.style.transform = this.baseTransform || ''; }\n render() {\n this.hoverPanel.dataset.jfiFlipped = String(this.flipped); this.hoverPanel.dataset.jfiReduced = String(this.reduced);\n for (const [node, hidden] of [[this.frontWrapper, this.flipped], [this.backWrapper, !this.flipped]]) { node.setAttribute('aria-hidden', String(hidden)); node.inert = hidden; }\n }\n flip(value = true) {\n if (this.destroyed || this.flipped === !!value) return this;\n const active = this.element.ownerDocument.activeElement;\n if ((value ? this.frontWrapper : this.backWrapper).contains(active)) this.hoverPanel.focus({ preventScroll: true });\n this.flipped = !!value; this.render();\n this.hoverPanel.dispatchEvent(new this.win.CustomEvent('justflipit:change', { bubbles: true, detail: this.getState() }));\n return this;\n }\n toggle() { return this.flip(!this.flipped); }\n update(options = {}) {\n if (this.destroyed) return this;\n if ('Faces' in options) throw new TypeError('Faces cannot change after initialization');\n validate(options);\n if (this.managed && 'Template' in options) throw new TypeError('Render framework face content with the framework');\n this.settings = { ...this.settings, ...options };\n if ('Template' in options) {\n if (this.managed) throw new TypeError('Render framework face content with the framework');\n this.backWrapper.innerHTML = options.Template;\n }\n this.resetTilt(); this.configure(); this.render(); return this;\n }\n getState() { return { flipped: this.flipped, destroyed: this.destroyed, effect: this.settings.Effect }; }\n destroy() {\n if (this.destroyed) return;\n this.resetTilt(); this.cleanups.forEach(fn => fn());\n this.restores.forEach(fn => fn());\n if (!this.managed) { this.hoverPanel.replaceWith(this.element); }\n instances.delete(this.element); instances.delete(this.hoverPanel); this.destroyed = true;\n }\n}\nfunction elements(target) {\n if (typeof target === 'string') return typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(target));\n if (target?.nodeType === 1) return [target];\n return target ? Array.from(target) : [];\n}\nexport default function justFlipIt(target, options) {\n const result = elements(target).map(element => instances.get(element) || new FlipController(element, options));\n return target?.nodeType === 1 ? result[0] : result;\n}\njustFlipIt.destroy = target => elements(target).forEach(element => instances.get(element)?.destroy());\njustFlipIt.get = element => instances.get(element);\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAM,YAAY,oBAAI,QAAQ;AAC9B,IAAM,WAAW,EAAE,OAAO,OAAO,OAAO,OAAO,UAAU,KAAK,QAAQ,+BAA+B,MAAM,OAAO,QAAQ,QAAQ,eAAe,MAAM,iBAAiB,MAAM,gBAAgB,MAAM,OAAO,CAAC,EAAE;AAC9M,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["const instances = new WeakMap();\nconst defaults = { Click: false, FlipX: false, Duration: 400, Easing: 'cubic-bezier(.22,.61,.36,1)', Tilt: false, Effect: 'flip', ReducedMotion: true, preserveClasses: true, preserveStyles: true, Style: [] };\nconst css = `\n._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}\n._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}\n._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}\n._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}\n._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{transform:scale(.94)}\n._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}\n._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}\n@media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}\n`;\nfunction styles(doc) {\n if (doc.querySelector('style[data-justflipitstyle=\"v4\"]')) return;\n const style = doc.createElement('style');\n style.dataset.justflipitstyle = 'v4'; style.textContent = css; doc.head.append(style);\n}\nfunction validate(options) {\n if (options.Duration !== undefined && (!Number.isFinite(options.Duration) || options.Duration < 0)) throw new TypeError('Duration must be a non-negative finite number');\n if (options.Effect !== undefined && !['flip', 'fade', 'scale'].includes(options.Effect)) throw new TypeError('Unknown Effect');\n if (options.Tilt && typeof options.Tilt === 'object') {\n for (const key of ['max', 'perspective', 'scale']) {\n if (options.Tilt[key] !== undefined && (!Number.isFinite(options.Tilt[key]) || options.Tilt[key] < 0)) throw new TypeError(`Invalid Tilt.${key}`);\n }\n }\n}\nexport class FlipController {\n constructor(element, options = {}) {\n validate(options);\n if (!element || element.nodeType !== 1) throw new TypeError('Expected an HTML element');\n this.element = element; this.settings = { ...defaults, ...options }; this.flipped = false; this.destroyed = false;\n this.cleanups = []; this.restores = []; this.win = element.ownerDocument.defaultView;\n const doc = element.ownerDocument; styles(doc);\n this.managed = !!options.Faces;\n if (this.managed) {\n this.hoverPanel = element;\n this.frontWrapper = element.querySelector(options.Faces.front);\n this.backWrapper = element.querySelector(options.Faces.back);\n if (!this.frontWrapper || !this.backWrapper || this.frontWrapper === this.backWrapper || this.frontWrapper.parentNode !== element || this.backWrapper.parentNode !== element) throw new TypeError('Faces must select two distinct direct children');\n } else {\n if (!element.parentNode) throw new TypeError('Element must have a parent');\n this.hoverPanel = doc.createElement('div');\n this.frontWrapper = doc.createElement('div'); this.backWrapper = doc.createElement('div');\n if (this.settings.preserveClasses) this.hoverPanel.className = element.className;\n if (this.settings.preserveStyles) this.hoverPanel.style.cssText = element.style.cssText;\n element.before(this.hoverPanel); this.hoverPanel.append(this.frontWrapper, this.backWrapper);\n this.frontWrapper.append(element);\n if (options.Template !== undefined) this.backWrapper.innerHTML = options.Template;\n else {\n const clone = element.cloneNode(true);\n clone.removeAttribute('id'); clone.querySelectorAll('[id]').forEach(node => node.removeAttribute('id'));\n this.backWrapper.append(clone);\n }\n }\n const panel = this.hoverPanel;\n for (const node of [panel, this.frontWrapper, this.backWrapper]) {\n const owned = node === panel ? ['class', 'style', 'tabindex', 'data-jfi-axis', 'data-jfi-effect', 'data-jfi-motion', 'data-jfi-flipped', 'data-jfi-reduced'] : ['style', 'data-jfi-face', 'aria-hidden', 'inert'];\n const attrs = owned.map(name => [name, node.getAttribute(name)]);\n const inert = node.inert || false;\n this.restores.push(() => { node.inert = inert; for (const [name, value] of attrs) { if (value === null) node.removeAttribute(name); else node.setAttribute(name, value); } });\n }\n panel.classList.add('_justFlipIt_panel');\n this.frontWrapper.dataset.jfiFace = 'front'; this.backWrapper.dataset.jfiFace = 'back';\n this.motion = this.win.matchMedia?.('(prefers-reduced-motion: reduce)');\n const motionChange = () => { this.resetTilt(); this.render(); };\n this.motion?.addEventListener('change', motionChange);\n this.cleanups.push(() => this.motion?.removeEventListener('change', motionChange));\n this.configure(); this.events(); this.render();\n instances.set(element, this); instances.set(panel, this);\n }\n listen(type, handler, options) { this.hoverPanel.addEventListener(type, handler, options); this.cleanups.push(() => this.hoverPanel.removeEventListener(type, handler, options)); }\n get reduced() { return this.settings.ReducedMotion !== false && !!this.motion?.matches; }\n configure() {\n const s = this.settings, p = this.hoverPanel;\n p.style.setProperty('--jfi-duration', `${s.Duration}ms`); p.style.setProperty('--jfi-easing', s.Easing);\n p.dataset.jfiAxis = s.FlipX ? 'x' : 'y'; p.dataset.jfiEffect = s.Effect;\n p.dataset.jfiMotion = s.ReducedMotion === false ? 'allow' : 'respect';\n for (const item of s.Style || []) {\n const targets = item.el === 'self' ? [p] : p.querySelectorAll(item.el);\n targets.forEach(node => Object.assign(node.style, item.style));\n }\n // A generic keyboard focus target avoids button roles around interactive children.\n if (s.Tilt !== 'only' && !p.hasAttribute('tabindex')) p.tabIndex = 0;\n }\n events() {\n this.listen('click', event => {\n if (this.settings.Tilt === 'only') return;\n const trigger = this.settings.Click;\n if (trigger === true || (trigger && [].concat(trigger).some(selector => event.target.closest?.(selector) && this.hoverPanel.contains(event.target.closest(selector))))) this.toggle();\n });\n this.listen('keydown', event => {\n if (event.target !== this.hoverPanel || this.settings.Tilt === 'only') return;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); this.toggle(); }\n if (event.key === 'Escape') this.flip(false);\n });\n this.listen('pointerenter', event => { if (!this.settings.Click && this.settings.Tilt !== 'only' && event.pointerType !== 'touch') this.flip(true); });\n this.listen('pointerleave', event => {\n // Touch release also emits pointerleave. The tap must survive it.\n if (event.pointerType === 'touch') return;\n this.resetTilt();\n if (!this.settings.Click && this.settings.Tilt !== 'only') this.flip(false);\n });\n this.listen('pointerdown', event => {\n if (event.pointerType !== 'touch' || event.isPrimary === false || this.touch) return;\n this.resetTilt();\n this.touch = { id: event.pointerId, x: event.clientX, y: event.clientY, moved: false };\n this.queueTilt(event, this.touch);\n }, { passive: true });\n this.listen('pointermove', event => {\n if (event.pointerType !== 'touch') {\n if (!this.touch) this.queueTilt(event);\n return;\n }\n const touch = this.touch;\n if (!touch || touch.id !== event.pointerId) return;\n touch.moved ||= this.touchMoved(event, touch);\n this.queueTilt(event, touch);\n }, { passive: true });\n this.listen('pointerup', event => {\n const touch = this.finishTouch(event);\n if (!touch || touch.moved || this.touchMoved(event, touch)) return;\n // Explicit click triggers continue to use the browser's click event.\n if (!this.settings.Click && this.settings.Tilt !== 'only') this.toggle();\n });\n this.listen('pointercancel', event => {\n if (event.pointerType === 'touch') this.finishTouch(event);\n else this.resetTilt();\n });\n this.listen('lostpointercapture', event => this.finishTouch(event));\n this.baseTransform = this.hoverPanel.style.transform;\n }\n touchMoved(event, touch) {\n return Math.hypot(event.clientX - touch.x, event.clientY - touch.y) > 10;\n }\n finishTouch(event) {\n const touch = this.touch;\n if (event.pointerType !== 'touch' || !touch || touch.id !== event.pointerId) return;\n this.touch = null;\n this.resetTilt();\n return touch;\n }\n queueTilt(event, touch) {\n if (!this.settings.Tilt || this.reduced) return;\n this.point = [event.clientX, event.clientY];\n if (this.frame) return;\n this.frame = this.win.requestAnimationFrame(() => {\n this.frame = 0;\n // Keep the touch reference box stable as the panel rotates.\n const rect = touch\n ? (touch.rect ??= this.hoverPanel.getBoundingClientRect())\n : this.hoverPanel.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const { max = 10, perspective = 1000, scale = 1.03 } = this.settings.Tilt;\n const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));\n const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));\n this.hoverPanel.style.transform = `perspective(${perspective}px) rotateX(${-y * max}deg) rotateY(${x * max}deg) scale(${scale})`;\n });\n }\n resetTilt() { if (this.frame) this.win.cancelAnimationFrame(this.frame); this.frame = 0; this.hoverPanel.style.transform = this.baseTransform || ''; }\n render() {\n this.hoverPanel.dataset.jfiFlipped = String(this.flipped); this.hoverPanel.dataset.jfiReduced = String(this.reduced);\n for (const [node, hidden] of [[this.frontWrapper, this.flipped], [this.backWrapper, !this.flipped]]) { node.setAttribute('aria-hidden', String(hidden)); node.inert = hidden; }\n }\n flip(value = true) {\n if (this.destroyed || this.flipped === !!value) return this;\n const active = this.element.ownerDocument.activeElement;\n if ((value ? this.frontWrapper : this.backWrapper).contains(active)) this.hoverPanel.focus({ preventScroll: true });\n this.flipped = !!value; this.render();\n this.hoverPanel.dispatchEvent(new this.win.CustomEvent('justflipit:change', { bubbles: true, detail: this.getState() }));\n return this;\n }\n toggle() { return this.flip(!this.flipped); }\n update(options = {}) {\n if (this.destroyed) return this;\n if ('Faces' in options) throw new TypeError('Faces cannot change after initialization');\n validate(options);\n if (this.managed && 'Template' in options) throw new TypeError('Render framework face content with the framework');\n this.settings = { ...this.settings, ...options };\n if ('Template' in options) {\n if (this.managed) throw new TypeError('Render framework face content with the framework');\n this.backWrapper.innerHTML = options.Template;\n }\n this.resetTilt(); this.configure(); this.render(); return this;\n }\n getState() { return { flipped: this.flipped, destroyed: this.destroyed, effect: this.settings.Effect }; }\n destroy() {\n if (this.destroyed) return;\n this.resetTilt(); this.cleanups.forEach(fn => fn());\n this.restores.forEach(fn => fn());\n if (!this.managed) { this.hoverPanel.replaceWith(this.element); }\n instances.delete(this.element); instances.delete(this.hoverPanel); this.destroyed = true;\n }\n}\nfunction elements(target) {\n if (typeof target === 'string') return typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(target));\n if (target?.nodeType === 1) return [target];\n return target ? Array.from(target) : [];\n}\nexport default function justFlipIt(target, options) {\n const result = elements(target).map(element => instances.get(element) || new FlipController(element, options));\n return target?.nodeType === 1 ? result[0] : result;\n}\njustFlipIt.destroy = target => elements(target).forEach(element => instances.get(element)?.destroy());\njustFlipIt.get = element => instances.get(element);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/justFlipIt.js
CHANGED
|
@@ -28,14 +28,16 @@ var JustFlipItModule = (() => {
|
|
|
28
28
|
var css = `
|
|
29
29
|
._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}
|
|
30
30
|
._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}
|
|
31
|
-
._justFlipIt_panel>[data-jfi-face=front]{
|
|
32
|
-
._justFlipIt_panel>[data-jfi-face=back]{
|
|
33
|
-
._justFlipIt_panel[data-jfi-
|
|
34
|
-
._justFlipIt_panel[data-jfi-
|
|
35
|
-
._justFlipIt_panel[data-jfi-
|
|
36
|
-
._justFlipIt_panel[data-jfi-
|
|
37
|
-
._justFlipIt_panel[data-jfi-
|
|
38
|
-
._justFlipIt_panel[data-jfi-effect=
|
|
31
|
+
._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}
|
|
32
|
+
._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}
|
|
33
|
+
._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}
|
|
34
|
+
._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}
|
|
35
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}
|
|
36
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}
|
|
37
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}
|
|
38
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
|
|
39
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
|
|
40
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
|
|
39
41
|
._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}
|
|
40
42
|
._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}
|
|
41
43
|
._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}
|
|
@@ -163,33 +165,63 @@ var JustFlipItModule = (() => {
|
|
|
163
165
|
this.listen("pointerenter", (event) => {
|
|
164
166
|
if (!this.settings.Click && this.settings.Tilt !== "only" && event.pointerType !== "touch") this.flip(true);
|
|
165
167
|
});
|
|
166
|
-
this.listen("pointerleave", () => {
|
|
168
|
+
this.listen("pointerleave", (event) => {
|
|
169
|
+
if (event.pointerType === "touch") return;
|
|
167
170
|
this.resetTilt();
|
|
168
171
|
if (!this.settings.Click && this.settings.Tilt !== "only") this.flip(false);
|
|
169
172
|
});
|
|
170
|
-
this.listen("
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
});
|
|
173
|
+
this.listen("pointerdown", (event) => {
|
|
174
|
+
if (event.pointerType !== "touch" || event.isPrimary === false || this.touch) return;
|
|
175
|
+
this.resetTilt();
|
|
176
|
+
this.touch = { id: event.pointerId, x: event.clientX, y: event.clientY, moved: false };
|
|
177
|
+
this.queueTilt(event, this.touch);
|
|
178
|
+
}, { passive: true });
|
|
177
179
|
this.listen("pointermove", (event) => {
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
|
|
187
|
-
const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
|
|
188
|
-
this.hoverPanel.style.transform = `perspective(${t.perspective}px) rotateX(${-y * t.max}deg) rotateY(${x * t.max}deg) scale(${t.scale})`;
|
|
189
|
-
});
|
|
180
|
+
if (event.pointerType !== "touch") {
|
|
181
|
+
if (!this.touch) this.queueTilt(event);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const touch = this.touch;
|
|
185
|
+
if (!touch || touch.id !== event.pointerId) return;
|
|
186
|
+
touch.moved || (touch.moved = this.touchMoved(event, touch));
|
|
187
|
+
this.queueTilt(event, touch);
|
|
190
188
|
}, { passive: true });
|
|
189
|
+
this.listen("pointerup", (event) => {
|
|
190
|
+
const touch = this.finishTouch(event);
|
|
191
|
+
if (!touch || touch.moved || this.touchMoved(event, touch)) return;
|
|
192
|
+
if (!this.settings.Click && this.settings.Tilt !== "only") this.toggle();
|
|
193
|
+
});
|
|
194
|
+
this.listen("pointercancel", (event) => {
|
|
195
|
+
if (event.pointerType === "touch") this.finishTouch(event);
|
|
196
|
+
else this.resetTilt();
|
|
197
|
+
});
|
|
198
|
+
this.listen("lostpointercapture", (event) => this.finishTouch(event));
|
|
191
199
|
this.baseTransform = this.hoverPanel.style.transform;
|
|
192
200
|
}
|
|
201
|
+
touchMoved(event, touch) {
|
|
202
|
+
return Math.hypot(event.clientX - touch.x, event.clientY - touch.y) > 10;
|
|
203
|
+
}
|
|
204
|
+
finishTouch(event) {
|
|
205
|
+
const touch = this.touch;
|
|
206
|
+
if (event.pointerType !== "touch" || !touch || touch.id !== event.pointerId) return;
|
|
207
|
+
this.touch = null;
|
|
208
|
+
this.resetTilt();
|
|
209
|
+
return touch;
|
|
210
|
+
}
|
|
211
|
+
queueTilt(event, touch) {
|
|
212
|
+
if (!this.settings.Tilt || this.reduced) return;
|
|
213
|
+
this.point = [event.clientX, event.clientY];
|
|
214
|
+
if (this.frame) return;
|
|
215
|
+
this.frame = this.win.requestAnimationFrame(() => {
|
|
216
|
+
this.frame = 0;
|
|
217
|
+
const rect = touch ? touch.rect ?? (touch.rect = this.hoverPanel.getBoundingClientRect()) : this.hoverPanel.getBoundingClientRect();
|
|
218
|
+
if (!rect.width || !rect.height) return;
|
|
219
|
+
const { max = 10, perspective = 1e3, scale = 1.03 } = this.settings.Tilt;
|
|
220
|
+
const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
|
|
221
|
+
const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
|
|
222
|
+
this.hoverPanel.style.transform = `perspective(${perspective}px) rotateX(${-y * max}deg) rotateY(${x * max}deg) scale(${scale})`;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
193
225
|
resetTilt() {
|
|
194
226
|
if (this.frame) this.win.cancelAnimationFrame(this.frame);
|
|
195
227
|
this.frame = 0;
|
package/dist/justFlipIt.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/core.js"],
|
|
4
|
-
"sourcesContent": ["const instances = new WeakMap();\nconst defaults = { Click: false, FlipX: false, Duration: 400, Easing: 'cubic-bezier(.22,.61,.36,1)', Tilt: false, Effect: 'flip', ReducedMotion: true, preserveClasses: true, preserveStyles: true, Style: [] };\nconst css = `\n._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}\n._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}\n._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}\n._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}\n._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}\n._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}\n._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}\n._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{transform:scale(.94)}\n._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}\n._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}\n@media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}\n`;\nfunction styles(doc) {\n if (doc.querySelector('style[data-justflipitstyle=\"v4\"]')) return;\n const style = doc.createElement('style');\n style.dataset.justflipitstyle = 'v4'; style.textContent = css; doc.head.append(style);\n}\nfunction validate(options) {\n if (options.Duration !== undefined && (!Number.isFinite(options.Duration) || options.Duration < 0)) throw new TypeError('Duration must be a non-negative finite number');\n if (options.Effect !== undefined && !['flip', 'fade', 'scale'].includes(options.Effect)) throw new TypeError('Unknown Effect');\n if (options.Tilt && typeof options.Tilt === 'object') {\n for (const key of ['max', 'perspective', 'scale']) {\n if (options.Tilt[key] !== undefined && (!Number.isFinite(options.Tilt[key]) || options.Tilt[key] < 0)) throw new TypeError(`Invalid Tilt.${key}`);\n }\n }\n}\nexport class FlipController {\n constructor(element, options = {}) {\n validate(options);\n if (!element || element.nodeType !== 1) throw new TypeError('Expected an HTML element');\n this.element = element; this.settings = { ...defaults, ...options }; this.flipped = false; this.destroyed = false;\n this.cleanups = []; this.restores = []; this.win = element.ownerDocument.defaultView;\n const doc = element.ownerDocument; styles(doc);\n this.managed = !!options.Faces;\n if (this.managed) {\n this.hoverPanel = element;\n this.frontWrapper = element.querySelector(options.Faces.front);\n this.backWrapper = element.querySelector(options.Faces.back);\n if (!this.frontWrapper || !this.backWrapper || this.frontWrapper === this.backWrapper || this.frontWrapper.parentNode !== element || this.backWrapper.parentNode !== element) throw new TypeError('Faces must select two distinct direct children');\n } else {\n if (!element.parentNode) throw new TypeError('Element must have a parent');\n this.hoverPanel = doc.createElement('div');\n this.frontWrapper = doc.createElement('div'); this.backWrapper = doc.createElement('div');\n if (this.settings.preserveClasses) this.hoverPanel.className = element.className;\n if (this.settings.preserveStyles) this.hoverPanel.style.cssText = element.style.cssText;\n element.before(this.hoverPanel); this.hoverPanel.append(this.frontWrapper, this.backWrapper);\n this.frontWrapper.append(element);\n if (options.Template !== undefined) this.backWrapper.innerHTML = options.Template;\n else {\n const clone = element.cloneNode(true);\n clone.removeAttribute('id'); clone.querySelectorAll('[id]').forEach(node => node.removeAttribute('id'));\n this.backWrapper.append(clone);\n }\n }\n const panel = this.hoverPanel;\n for (const node of [panel, this.frontWrapper, this.backWrapper]) {\n const owned = node === panel ? ['class', 'style', 'tabindex', 'data-jfi-axis', 'data-jfi-effect', 'data-jfi-motion', 'data-jfi-flipped', 'data-jfi-reduced'] : ['style', 'data-jfi-face', 'aria-hidden', 'inert'];\n const attrs = owned.map(name => [name, node.getAttribute(name)]);\n const inert = node.inert || false;\n this.restores.push(() => { node.inert = inert; for (const [name, value] of attrs) { if (value === null) node.removeAttribute(name); else node.setAttribute(name, value); } });\n }\n panel.classList.add('_justFlipIt_panel');\n this.frontWrapper.dataset.jfiFace = 'front'; this.backWrapper.dataset.jfiFace = 'back';\n this.motion = this.win.matchMedia?.('(prefers-reduced-motion: reduce)');\n const motionChange = () => { this.resetTilt(); this.render(); };\n this.motion?.addEventListener('change', motionChange);\n this.cleanups.push(() => this.motion?.removeEventListener('change', motionChange));\n this.configure(); this.events(); this.render();\n instances.set(element, this); instances.set(panel, this);\n }\n listen(type, handler, options) { this.hoverPanel.addEventListener(type, handler, options); this.cleanups.push(() => this.hoverPanel.removeEventListener(type, handler, options)); }\n get reduced() { return this.settings.ReducedMotion !== false && !!this.motion?.matches; }\n configure() {\n const s = this.settings, p = this.hoverPanel;\n p.style.setProperty('--jfi-duration', `${s.Duration}ms`); p.style.setProperty('--jfi-easing', s.Easing);\n p.dataset.jfiAxis = s.FlipX ? 'x' : 'y'; p.dataset.jfiEffect = s.Effect;\n p.dataset.jfiMotion = s.ReducedMotion === false ? 'allow' : 'respect';\n for (const item of s.Style || []) {\n const targets = item.el === 'self' ? [p] : p.querySelectorAll(item.el);\n targets.forEach(node => Object.assign(node.style, item.style));\n }\n // A generic keyboard focus target avoids button roles around interactive children.\n if (s.Tilt !== 'only' && !p.hasAttribute('tabindex')) p.tabIndex = 0;\n }\n events() {\n this.listen('click', event => {\n if (this.settings.Tilt === 'only') return;\n const trigger = this.settings.Click;\n if (trigger === true || (trigger && [].concat(trigger).some(selector => event.target.closest?.(selector) && this.hoverPanel.contains(event.target.closest(selector))))) this.toggle();\n });\n this.listen('keydown', event => {\n if (event.target !== this.hoverPanel || this.settings.Tilt === 'only') return;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); this.toggle(); }\n if (event.key === 'Escape') this.flip(false);\n });\n this.listen('pointerenter', event => { if (!this.settings.Click && this.settings.Tilt !== 'only' && event.pointerType !== 'touch') this.flip(true); });\n this.listen('pointerleave', () => { this.resetTilt(); if (!this.settings.Click && this.settings.Tilt !== 'only') this.flip(false); });\n this.listen('pointercancel', () => this.resetTilt());\n this.listen('pointerup', event => { if (event.pointerType === 'touch') { this.resetTilt(); if (!this.settings.Click && this.settings.Tilt !== 'only') this.toggle(); } });\n this.listen('pointermove', event => {\n if (!this.settings.Tilt || this.reduced || event.pointerType === 'touch') return;\n this.point = [event.clientX, event.clientY];\n if (this.frame) return;\n this.frame = this.win.requestAnimationFrame(() => {\n this.frame = 0;\n const rect = this.hoverPanel.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const t = { max: 10, perspective: 1000, scale: 1.03, ...(typeof this.settings.Tilt === 'object' ? this.settings.Tilt : {}) };\n const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));\n const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));\n this.hoverPanel.style.transform = `perspective(${t.perspective}px) rotateX(${-y * t.max}deg) rotateY(${x * t.max}deg) scale(${t.scale})`;\n });\n }, { passive: true });\n this.baseTransform = this.hoverPanel.style.transform;\n }\n resetTilt() { if (this.frame) this.win.cancelAnimationFrame(this.frame); this.frame = 0; this.hoverPanel.style.transform = this.baseTransform || ''; }\n render() {\n this.hoverPanel.dataset.jfiFlipped = String(this.flipped); this.hoverPanel.dataset.jfiReduced = String(this.reduced);\n for (const [node, hidden] of [[this.frontWrapper, this.flipped], [this.backWrapper, !this.flipped]]) { node.setAttribute('aria-hidden', String(hidden)); node.inert = hidden; }\n }\n flip(value = true) {\n if (this.destroyed || this.flipped === !!value) return this;\n const active = this.element.ownerDocument.activeElement;\n if ((value ? this.frontWrapper : this.backWrapper).contains(active)) this.hoverPanel.focus({ preventScroll: true });\n this.flipped = !!value; this.render();\n this.hoverPanel.dispatchEvent(new this.win.CustomEvent('justflipit:change', { bubbles: true, detail: this.getState() }));\n return this;\n }\n toggle() { return this.flip(!this.flipped); }\n update(options = {}) {\n if (this.destroyed) return this;\n if ('Faces' in options) throw new TypeError('Faces cannot change after initialization');\n validate(options);\n if (this.managed && 'Template' in options) throw new TypeError('Render framework face content with the framework');\n this.settings = { ...this.settings, ...options };\n if ('Template' in options) {\n if (this.managed) throw new TypeError('Render framework face content with the framework');\n this.backWrapper.innerHTML = options.Template;\n }\n this.resetTilt(); this.configure(); this.render(); return this;\n }\n getState() { return { flipped: this.flipped, destroyed: this.destroyed, effect: this.settings.Effect }; }\n destroy() {\n if (this.destroyed) return;\n this.resetTilt(); this.cleanups.forEach(fn => fn());\n this.restores.forEach(fn => fn());\n if (!this.managed) { this.hoverPanel.replaceWith(this.element); }\n instances.delete(this.element); instances.delete(this.hoverPanel); this.destroyed = true;\n }\n}\nfunction elements(target) {\n if (typeof target === 'string') return typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(target));\n if (target?.nodeType === 1) return [target];\n return target ? Array.from(target) : [];\n}\nexport default function justFlipIt(target, options) {\n const result = elements(target).map(element => instances.get(element) || new FlipController(element, options));\n return target?.nodeType === 1 ? result[0] : result;\n}\njustFlipIt.destroy = target => elements(target).forEach(element => instances.get(element)?.destroy());\njustFlipIt.get = element => instances.get(element);\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAM,YAAY,oBAAI,QAAQ;AAC9B,MAAM,WAAW,EAAE,OAAO,OAAO,OAAO,OAAO,UAAU,KAAK,QAAQ,+BAA+B,MAAM,OAAO,QAAQ,QAAQ,eAAe,MAAM,iBAAiB,MAAM,gBAAgB,MAAM,OAAO,CAAC,EAAE;AAC9M,MAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["const instances = new WeakMap();\nconst defaults = { Click: false, FlipX: false, Duration: 400, Easing: 'cubic-bezier(.22,.61,.36,1)', Tilt: false, Effect: 'flip', ReducedMotion: true, preserveClasses: true, preserveStyles: true, Style: [] };\nconst css = `\n._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}\n._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}\n._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}\n._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}\n._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{transform:scale(.94)}\n._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}\n._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}\n@media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}\n`;\nfunction styles(doc) {\n if (doc.querySelector('style[data-justflipitstyle=\"v4\"]')) return;\n const style = doc.createElement('style');\n style.dataset.justflipitstyle = 'v4'; style.textContent = css; doc.head.append(style);\n}\nfunction validate(options) {\n if (options.Duration !== undefined && (!Number.isFinite(options.Duration) || options.Duration < 0)) throw new TypeError('Duration must be a non-negative finite number');\n if (options.Effect !== undefined && !['flip', 'fade', 'scale'].includes(options.Effect)) throw new TypeError('Unknown Effect');\n if (options.Tilt && typeof options.Tilt === 'object') {\n for (const key of ['max', 'perspective', 'scale']) {\n if (options.Tilt[key] !== undefined && (!Number.isFinite(options.Tilt[key]) || options.Tilt[key] < 0)) throw new TypeError(`Invalid Tilt.${key}`);\n }\n }\n}\nexport class FlipController {\n constructor(element, options = {}) {\n validate(options);\n if (!element || element.nodeType !== 1) throw new TypeError('Expected an HTML element');\n this.element = element; this.settings = { ...defaults, ...options }; this.flipped = false; this.destroyed = false;\n this.cleanups = []; this.restores = []; this.win = element.ownerDocument.defaultView;\n const doc = element.ownerDocument; styles(doc);\n this.managed = !!options.Faces;\n if (this.managed) {\n this.hoverPanel = element;\n this.frontWrapper = element.querySelector(options.Faces.front);\n this.backWrapper = element.querySelector(options.Faces.back);\n if (!this.frontWrapper || !this.backWrapper || this.frontWrapper === this.backWrapper || this.frontWrapper.parentNode !== element || this.backWrapper.parentNode !== element) throw new TypeError('Faces must select two distinct direct children');\n } else {\n if (!element.parentNode) throw new TypeError('Element must have a parent');\n this.hoverPanel = doc.createElement('div');\n this.frontWrapper = doc.createElement('div'); this.backWrapper = doc.createElement('div');\n if (this.settings.preserveClasses) this.hoverPanel.className = element.className;\n if (this.settings.preserveStyles) this.hoverPanel.style.cssText = element.style.cssText;\n element.before(this.hoverPanel); this.hoverPanel.append(this.frontWrapper, this.backWrapper);\n this.frontWrapper.append(element);\n if (options.Template !== undefined) this.backWrapper.innerHTML = options.Template;\n else {\n const clone = element.cloneNode(true);\n clone.removeAttribute('id'); clone.querySelectorAll('[id]').forEach(node => node.removeAttribute('id'));\n this.backWrapper.append(clone);\n }\n }\n const panel = this.hoverPanel;\n for (const node of [panel, this.frontWrapper, this.backWrapper]) {\n const owned = node === panel ? ['class', 'style', 'tabindex', 'data-jfi-axis', 'data-jfi-effect', 'data-jfi-motion', 'data-jfi-flipped', 'data-jfi-reduced'] : ['style', 'data-jfi-face', 'aria-hidden', 'inert'];\n const attrs = owned.map(name => [name, node.getAttribute(name)]);\n const inert = node.inert || false;\n this.restores.push(() => { node.inert = inert; for (const [name, value] of attrs) { if (value === null) node.removeAttribute(name); else node.setAttribute(name, value); } });\n }\n panel.classList.add('_justFlipIt_panel');\n this.frontWrapper.dataset.jfiFace = 'front'; this.backWrapper.dataset.jfiFace = 'back';\n this.motion = this.win.matchMedia?.('(prefers-reduced-motion: reduce)');\n const motionChange = () => { this.resetTilt(); this.render(); };\n this.motion?.addEventListener('change', motionChange);\n this.cleanups.push(() => this.motion?.removeEventListener('change', motionChange));\n this.configure(); this.events(); this.render();\n instances.set(element, this); instances.set(panel, this);\n }\n listen(type, handler, options) { this.hoverPanel.addEventListener(type, handler, options); this.cleanups.push(() => this.hoverPanel.removeEventListener(type, handler, options)); }\n get reduced() { return this.settings.ReducedMotion !== false && !!this.motion?.matches; }\n configure() {\n const s = this.settings, p = this.hoverPanel;\n p.style.setProperty('--jfi-duration', `${s.Duration}ms`); p.style.setProperty('--jfi-easing', s.Easing);\n p.dataset.jfiAxis = s.FlipX ? 'x' : 'y'; p.dataset.jfiEffect = s.Effect;\n p.dataset.jfiMotion = s.ReducedMotion === false ? 'allow' : 'respect';\n for (const item of s.Style || []) {\n const targets = item.el === 'self' ? [p] : p.querySelectorAll(item.el);\n targets.forEach(node => Object.assign(node.style, item.style));\n }\n // A generic keyboard focus target avoids button roles around interactive children.\n if (s.Tilt !== 'only' && !p.hasAttribute('tabindex')) p.tabIndex = 0;\n }\n events() {\n this.listen('click', event => {\n if (this.settings.Tilt === 'only') return;\n const trigger = this.settings.Click;\n if (trigger === true || (trigger && [].concat(trigger).some(selector => event.target.closest?.(selector) && this.hoverPanel.contains(event.target.closest(selector))))) this.toggle();\n });\n this.listen('keydown', event => {\n if (event.target !== this.hoverPanel || this.settings.Tilt === 'only') return;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); this.toggle(); }\n if (event.key === 'Escape') this.flip(false);\n });\n this.listen('pointerenter', event => { if (!this.settings.Click && this.settings.Tilt !== 'only' && event.pointerType !== 'touch') this.flip(true); });\n this.listen('pointerleave', event => {\n // Touch release also emits pointerleave. The tap must survive it.\n if (event.pointerType === 'touch') return;\n this.resetTilt();\n if (!this.settings.Click && this.settings.Tilt !== 'only') this.flip(false);\n });\n this.listen('pointerdown', event => {\n if (event.pointerType !== 'touch' || event.isPrimary === false || this.touch) return;\n this.resetTilt();\n this.touch = { id: event.pointerId, x: event.clientX, y: event.clientY, moved: false };\n this.queueTilt(event, this.touch);\n }, { passive: true });\n this.listen('pointermove', event => {\n if (event.pointerType !== 'touch') {\n if (!this.touch) this.queueTilt(event);\n return;\n }\n const touch = this.touch;\n if (!touch || touch.id !== event.pointerId) return;\n touch.moved ||= this.touchMoved(event, touch);\n this.queueTilt(event, touch);\n }, { passive: true });\n this.listen('pointerup', event => {\n const touch = this.finishTouch(event);\n if (!touch || touch.moved || this.touchMoved(event, touch)) return;\n // Explicit click triggers continue to use the browser's click event.\n if (!this.settings.Click && this.settings.Tilt !== 'only') this.toggle();\n });\n this.listen('pointercancel', event => {\n if (event.pointerType === 'touch') this.finishTouch(event);\n else this.resetTilt();\n });\n this.listen('lostpointercapture', event => this.finishTouch(event));\n this.baseTransform = this.hoverPanel.style.transform;\n }\n touchMoved(event, touch) {\n return Math.hypot(event.clientX - touch.x, event.clientY - touch.y) > 10;\n }\n finishTouch(event) {\n const touch = this.touch;\n if (event.pointerType !== 'touch' || !touch || touch.id !== event.pointerId) return;\n this.touch = null;\n this.resetTilt();\n return touch;\n }\n queueTilt(event, touch) {\n if (!this.settings.Tilt || this.reduced) return;\n this.point = [event.clientX, event.clientY];\n if (this.frame) return;\n this.frame = this.win.requestAnimationFrame(() => {\n this.frame = 0;\n // Keep the touch reference box stable as the panel rotates.\n const rect = touch\n ? (touch.rect ??= this.hoverPanel.getBoundingClientRect())\n : this.hoverPanel.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const { max = 10, perspective = 1000, scale = 1.03 } = this.settings.Tilt;\n const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));\n const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));\n this.hoverPanel.style.transform = `perspective(${perspective}px) rotateX(${-y * max}deg) rotateY(${x * max}deg) scale(${scale})`;\n });\n }\n resetTilt() { if (this.frame) this.win.cancelAnimationFrame(this.frame); this.frame = 0; this.hoverPanel.style.transform = this.baseTransform || ''; }\n render() {\n this.hoverPanel.dataset.jfiFlipped = String(this.flipped); this.hoverPanel.dataset.jfiReduced = String(this.reduced);\n for (const [node, hidden] of [[this.frontWrapper, this.flipped], [this.backWrapper, !this.flipped]]) { node.setAttribute('aria-hidden', String(hidden)); node.inert = hidden; }\n }\n flip(value = true) {\n if (this.destroyed || this.flipped === !!value) return this;\n const active = this.element.ownerDocument.activeElement;\n if ((value ? this.frontWrapper : this.backWrapper).contains(active)) this.hoverPanel.focus({ preventScroll: true });\n this.flipped = !!value; this.render();\n this.hoverPanel.dispatchEvent(new this.win.CustomEvent('justflipit:change', { bubbles: true, detail: this.getState() }));\n return this;\n }\n toggle() { return this.flip(!this.flipped); }\n update(options = {}) {\n if (this.destroyed) return this;\n if ('Faces' in options) throw new TypeError('Faces cannot change after initialization');\n validate(options);\n if (this.managed && 'Template' in options) throw new TypeError('Render framework face content with the framework');\n this.settings = { ...this.settings, ...options };\n if ('Template' in options) {\n if (this.managed) throw new TypeError('Render framework face content with the framework');\n this.backWrapper.innerHTML = options.Template;\n }\n this.resetTilt(); this.configure(); this.render(); return this;\n }\n getState() { return { flipped: this.flipped, destroyed: this.destroyed, effect: this.settings.Effect }; }\n destroy() {\n if (this.destroyed) return;\n this.resetTilt(); this.cleanups.forEach(fn => fn());\n this.restores.forEach(fn => fn());\n if (!this.managed) { this.hoverPanel.replaceWith(this.element); }\n instances.delete(this.element); instances.delete(this.hoverPanel); this.destroyed = true;\n }\n}\nfunction elements(target) {\n if (typeof target === 'string') return typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(target));\n if (target?.nodeType === 1) return [target];\n return target ? Array.from(target) : [];\n}\nexport default function justFlipIt(target, options) {\n const result = elements(target).map(element => instances.get(element) || new FlipController(element, options));\n return target?.nodeType === 1 ? result[0] : result;\n}\njustFlipIt.destroy = target => elements(target).forEach(element => instances.get(element)?.destroy());\njustFlipIt.get = element => instances.get(element);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/justFlipIt.min.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
var JustFlipItModule=(()=>{var
|
|
1
|
+
var JustFlipItModule=(()=>{var d=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var b=(i,t)=>{for(var e in t)d(i,e,{get:t[e],enumerable:!0})},_=(i,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of T(t))!v.call(i,s)&&s!==e&&d(i,s,{get:()=>t[s],enumerable:!(a=g(t,s))||a.enumerable});return i};var w=i=>_(d({},"__esModule",{value:!0}),i);var I={};b(I,{FlipController:()=>c,default:()=>h});var n=new WeakMap,k={Click:!1,FlipX:!1,Duration:400,Easing:"cubic-bezier(.22,.61,.36,1)",Tilt:!1,Effect:"flip",ReducedMotion:!0,preserveClasses:!0,preserveStyles:!0,Style:[]},F=`
|
|
2
2
|
._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}
|
|
3
3
|
._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}
|
|
4
|
-
._justFlipIt_panel>[data-jfi-face=front]{
|
|
5
|
-
._justFlipIt_panel>[data-jfi-face=back]{
|
|
6
|
-
._justFlipIt_panel[data-jfi-
|
|
7
|
-
._justFlipIt_panel[data-jfi-
|
|
8
|
-
._justFlipIt_panel[data-jfi-
|
|
9
|
-
._justFlipIt_panel[data-jfi-
|
|
10
|
-
._justFlipIt_panel[data-jfi-
|
|
11
|
-
._justFlipIt_panel[data-jfi-effect=
|
|
4
|
+
._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}
|
|
5
|
+
._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}
|
|
6
|
+
._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}
|
|
7
|
+
._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}
|
|
8
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}
|
|
9
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}
|
|
10
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}
|
|
11
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
|
|
12
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
|
|
13
|
+
._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
|
|
12
14
|
._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}
|
|
13
15
|
._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}
|
|
14
16
|
._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}
|
|
@@ -16,6 +18,6 @@ var JustFlipItModule=(()=>{var p=Object.defineProperty;var g=Object.getOwnProper
|
|
|
16
18
|
._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}
|
|
17
19
|
._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}
|
|
18
20
|
@media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}
|
|
19
|
-
`;function
|
|
21
|
+
`;function E(i){if(i.querySelector('style[data-justflipitstyle="v4"]'))return;let t=i.createElement("style");t.dataset.justflipitstyle="v4",t.textContent=F,i.head.append(t)}function j(i){if(i.Duration!==void 0&&(!Number.isFinite(i.Duration)||i.Duration<0))throw new TypeError("Duration must be a non-negative finite number");if(i.Effect!==void 0&&!["flip","fade","scale"].includes(i.Effect))throw new TypeError("Unknown Effect");if(i.Tilt&&typeof i.Tilt=="object"){for(let t of["max","perspective","scale"])if(i.Tilt[t]!==void 0&&(!Number.isFinite(i.Tilt[t])||i.Tilt[t]<0))throw new TypeError(`Invalid Tilt.${t}`)}}var c=class{constructor(t,e={}){if(j(e),!t||t.nodeType!==1)throw new TypeError("Expected an HTML element");this.element=t,this.settings={...k,...e},this.flipped=!1,this.destroyed=!1,this.cleanups=[],this.restores=[],this.win=t.ownerDocument.defaultView;let a=t.ownerDocument;if(E(a),this.managed=!!e.Faces,this.managed){if(this.hoverPanel=t,this.frontWrapper=t.querySelector(e.Faces.front),this.backWrapper=t.querySelector(e.Faces.back),!this.frontWrapper||!this.backWrapper||this.frontWrapper===this.backWrapper||this.frontWrapper.parentNode!==t||this.backWrapper.parentNode!==t)throw new TypeError("Faces must select two distinct direct children")}else{if(!t.parentNode)throw new TypeError("Element must have a parent");if(this.hoverPanel=a.createElement("div"),this.frontWrapper=a.createElement("div"),this.backWrapper=a.createElement("div"),this.settings.preserveClasses&&(this.hoverPanel.className=t.className),this.settings.preserveStyles&&(this.hoverPanel.style.cssText=t.style.cssText),t.before(this.hoverPanel),this.hoverPanel.append(this.frontWrapper,this.backWrapper),this.frontWrapper.append(t),e.Template!==void 0)this.backWrapper.innerHTML=e.Template;else{let r=t.cloneNode(!0);r.removeAttribute("id"),r.querySelectorAll("[id]").forEach(l=>l.removeAttribute("id")),this.backWrapper.append(r)}}let s=this.hoverPanel;for(let r of[s,this.frontWrapper,this.backWrapper]){let p=(r===s?["class","style","tabindex","data-jfi-axis","data-jfi-effect","data-jfi-motion","data-jfi-flipped","data-jfi-reduced"]:["style","data-jfi-face","aria-hidden","inert"]).map(o=>[o,r.getAttribute(o)]),y=r.inert||!1;this.restores.push(()=>{r.inert=y;for(let[o,u]of p)u===null?r.removeAttribute(o):r.setAttribute(o,u)})}s.classList.add("_justFlipIt_panel"),this.frontWrapper.dataset.jfiFace="front",this.backWrapper.dataset.jfiFace="back",this.motion=this.win.matchMedia?.("(prefers-reduced-motion: reduce)");let f=()=>{this.resetTilt(),this.render()};this.motion?.addEventListener("change",f),this.cleanups.push(()=>this.motion?.removeEventListener("change",f)),this.configure(),this.events(),this.render(),n.set(t,this),n.set(s,this)}listen(t,e,a){this.hoverPanel.addEventListener(t,e,a),this.cleanups.push(()=>this.hoverPanel.removeEventListener(t,e,a))}get reduced(){return this.settings.ReducedMotion!==!1&&!!this.motion?.matches}configure(){let t=this.settings,e=this.hoverPanel;e.style.setProperty("--jfi-duration",`${t.Duration}ms`),e.style.setProperty("--jfi-easing",t.Easing),e.dataset.jfiAxis=t.FlipX?"x":"y",e.dataset.jfiEffect=t.Effect,e.dataset.jfiMotion=t.ReducedMotion===!1?"allow":"respect";for(let a of t.Style||[])(a.el==="self"?[e]:e.querySelectorAll(a.el)).forEach(f=>Object.assign(f.style,a.style));t.Tilt!=="only"&&!e.hasAttribute("tabindex")&&(e.tabIndex=0)}events(){this.listen("click",t=>{if(this.settings.Tilt==="only")return;let e=this.settings.Click;(e===!0||e&&[].concat(e).some(a=>t.target.closest?.(a)&&this.hoverPanel.contains(t.target.closest(a))))&&this.toggle()}),this.listen("keydown",t=>{t.target!==this.hoverPanel||this.settings.Tilt==="only"||((t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.toggle()),t.key==="Escape"&&this.flip(!1))}),this.listen("pointerenter",t=>{!this.settings.Click&&this.settings.Tilt!=="only"&&t.pointerType!=="touch"&&this.flip(!0)}),this.listen("pointerleave",t=>{t.pointerType!=="touch"&&(this.resetTilt(),!this.settings.Click&&this.settings.Tilt!=="only"&&this.flip(!1))}),this.listen("pointerdown",t=>{t.pointerType!=="touch"||t.isPrimary===!1||this.touch||(this.resetTilt(),this.touch={id:t.pointerId,x:t.clientX,y:t.clientY,moved:!1},this.queueTilt(t,this.touch))},{passive:!0}),this.listen("pointermove",t=>{if(t.pointerType!=="touch"){this.touch||this.queueTilt(t);return}let e=this.touch;!e||e.id!==t.pointerId||(e.moved||(e.moved=this.touchMoved(t,e)),this.queueTilt(t,e))},{passive:!0}),this.listen("pointerup",t=>{let e=this.finishTouch(t);!e||e.moved||this.touchMoved(t,e)||!this.settings.Click&&this.settings.Tilt!=="only"&&this.toggle()}),this.listen("pointercancel",t=>{t.pointerType==="touch"?this.finishTouch(t):this.resetTilt()}),this.listen("lostpointercapture",t=>this.finishTouch(t)),this.baseTransform=this.hoverPanel.style.transform}touchMoved(t,e){return Math.hypot(t.clientX-e.x,t.clientY-e.y)>10}finishTouch(t){let e=this.touch;if(!(t.pointerType!=="touch"||!e||e.id!==t.pointerId))return this.touch=null,this.resetTilt(),e}queueTilt(t,e){!this.settings.Tilt||this.reduced||(this.point=[t.clientX,t.clientY],!this.frame&&(this.frame=this.win.requestAnimationFrame(()=>{this.frame=0;let a=e?e.rect??(e.rect=this.hoverPanel.getBoundingClientRect()):this.hoverPanel.getBoundingClientRect();if(!a.width||!a.height)return;let{max:s=10,perspective:f=1e3,scale:r=1.03}=this.settings.Tilt,l=Math.max(-1,Math.min(1,(this.point[0]-a.left)/a.width*2-1)),p=Math.max(-1,Math.min(1,(this.point[1]-a.top)/a.height*2-1));this.hoverPanel.style.transform=`perspective(${f}px) rotateX(${-p*s}deg) rotateY(${l*s}deg) scale(${r})`})))}resetTilt(){this.frame&&this.win.cancelAnimationFrame(this.frame),this.frame=0,this.hoverPanel.style.transform=this.baseTransform||""}render(){this.hoverPanel.dataset.jfiFlipped=String(this.flipped),this.hoverPanel.dataset.jfiReduced=String(this.reduced);for(let[t,e]of[[this.frontWrapper,this.flipped],[this.backWrapper,!this.flipped]])t.setAttribute("aria-hidden",String(e)),t.inert=e}flip(t=!0){if(this.destroyed||this.flipped===!!t)return this;let e=this.element.ownerDocument.activeElement;return(t?this.frontWrapper:this.backWrapper).contains(e)&&this.hoverPanel.focus({preventScroll:!0}),this.flipped=!!t,this.render(),this.hoverPanel.dispatchEvent(new this.win.CustomEvent("justflipit:change",{bubbles:!0,detail:this.getState()})),this}toggle(){return this.flip(!this.flipped)}update(t={}){if(this.destroyed)return this;if("Faces"in t)throw new TypeError("Faces cannot change after initialization");if(j(t),this.managed&&"Template"in t)throw new TypeError("Render framework face content with the framework");if(this.settings={...this.settings,...t},"Template"in t){if(this.managed)throw new TypeError("Render framework face content with the framework");this.backWrapper.innerHTML=t.Template}return this.resetTilt(),this.configure(),this.render(),this}getState(){return{flipped:this.flipped,destroyed:this.destroyed,effect:this.settings.Effect}}destroy(){this.destroyed||(this.resetTilt(),this.cleanups.forEach(t=>t()),this.restores.forEach(t=>t()),this.managed||this.hoverPanel.replaceWith(this.element),n.delete(this.element),n.delete(this.hoverPanel),this.destroyed=!0)}};function m(i){return typeof i=="string"?typeof document>"u"?[]:Array.from(document.querySelectorAll(i)):i?.nodeType===1?[i]:i?Array.from(i):[]}function h(i,t){let e=m(i).map(a=>n.get(a)||new c(a,t));return i?.nodeType===1?e[0]:e}h.destroy=i=>m(i).forEach(t=>n.get(t)?.destroy());h.get=i=>n.get(i);return w(I);})();
|
|
20
22
|
globalThis.justFlipIt = JustFlipItModule.default;
|
|
21
23
|
//# sourceMappingURL=justFlipIt.min.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/core.js"],
|
|
4
|
-
"sourcesContent": ["const instances = new WeakMap();\nconst defaults = { Click: false, FlipX: false, Duration: 400, Easing: 'cubic-bezier(.22,.61,.36,1)', Tilt: false, Effect: 'flip', ReducedMotion: true, preserveClasses: true, preserveStyles: true, Style: [] };\nconst css = `\n._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}\n._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}\n._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}\n._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}\n._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}\n._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}\n._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}\n._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{transform:scale(.94)}\n._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}\n._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}\n@media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}\n`;\nfunction styles(doc) {\n if (doc.querySelector('style[data-justflipitstyle=\"v4\"]')) return;\n const style = doc.createElement('style');\n style.dataset.justflipitstyle = 'v4'; style.textContent = css; doc.head.append(style);\n}\nfunction validate(options) {\n if (options.Duration !== undefined && (!Number.isFinite(options.Duration) || options.Duration < 0)) throw new TypeError('Duration must be a non-negative finite number');\n if (options.Effect !== undefined && !['flip', 'fade', 'scale'].includes(options.Effect)) throw new TypeError('Unknown Effect');\n if (options.Tilt && typeof options.Tilt === 'object') {\n for (const key of ['max', 'perspective', 'scale']) {\n if (options.Tilt[key] !== undefined && (!Number.isFinite(options.Tilt[key]) || options.Tilt[key] < 0)) throw new TypeError(`Invalid Tilt.${key}`);\n }\n }\n}\nexport class FlipController {\n constructor(element, options = {}) {\n validate(options);\n if (!element || element.nodeType !== 1) throw new TypeError('Expected an HTML element');\n this.element = element; this.settings = { ...defaults, ...options }; this.flipped = false; this.destroyed = false;\n this.cleanups = []; this.restores = []; this.win = element.ownerDocument.defaultView;\n const doc = element.ownerDocument; styles(doc);\n this.managed = !!options.Faces;\n if (this.managed) {\n this.hoverPanel = element;\n this.frontWrapper = element.querySelector(options.Faces.front);\n this.backWrapper = element.querySelector(options.Faces.back);\n if (!this.frontWrapper || !this.backWrapper || this.frontWrapper === this.backWrapper || this.frontWrapper.parentNode !== element || this.backWrapper.parentNode !== element) throw new TypeError('Faces must select two distinct direct children');\n } else {\n if (!element.parentNode) throw new TypeError('Element must have a parent');\n this.hoverPanel = doc.createElement('div');\n this.frontWrapper = doc.createElement('div'); this.backWrapper = doc.createElement('div');\n if (this.settings.preserveClasses) this.hoverPanel.className = element.className;\n if (this.settings.preserveStyles) this.hoverPanel.style.cssText = element.style.cssText;\n element.before(this.hoverPanel); this.hoverPanel.append(this.frontWrapper, this.backWrapper);\n this.frontWrapper.append(element);\n if (options.Template !== undefined) this.backWrapper.innerHTML = options.Template;\n else {\n const clone = element.cloneNode(true);\n clone.removeAttribute('id'); clone.querySelectorAll('[id]').forEach(node => node.removeAttribute('id'));\n this.backWrapper.append(clone);\n }\n }\n const panel = this.hoverPanel;\n for (const node of [panel, this.frontWrapper, this.backWrapper]) {\n const owned = node === panel ? ['class', 'style', 'tabindex', 'data-jfi-axis', 'data-jfi-effect', 'data-jfi-motion', 'data-jfi-flipped', 'data-jfi-reduced'] : ['style', 'data-jfi-face', 'aria-hidden', 'inert'];\n const attrs = owned.map(name => [name, node.getAttribute(name)]);\n const inert = node.inert || false;\n this.restores.push(() => { node.inert = inert; for (const [name, value] of attrs) { if (value === null) node.removeAttribute(name); else node.setAttribute(name, value); } });\n }\n panel.classList.add('_justFlipIt_panel');\n this.frontWrapper.dataset.jfiFace = 'front'; this.backWrapper.dataset.jfiFace = 'back';\n this.motion = this.win.matchMedia?.('(prefers-reduced-motion: reduce)');\n const motionChange = () => { this.resetTilt(); this.render(); };\n this.motion?.addEventListener('change', motionChange);\n this.cleanups.push(() => this.motion?.removeEventListener('change', motionChange));\n this.configure(); this.events(); this.render();\n instances.set(element, this); instances.set(panel, this);\n }\n listen(type, handler, options) { this.hoverPanel.addEventListener(type, handler, options); this.cleanups.push(() => this.hoverPanel.removeEventListener(type, handler, options)); }\n get reduced() { return this.settings.ReducedMotion !== false && !!this.motion?.matches; }\n configure() {\n const s = this.settings, p = this.hoverPanel;\n p.style.setProperty('--jfi-duration', `${s.Duration}ms`); p.style.setProperty('--jfi-easing', s.Easing);\n p.dataset.jfiAxis = s.FlipX ? 'x' : 'y'; p.dataset.jfiEffect = s.Effect;\n p.dataset.jfiMotion = s.ReducedMotion === false ? 'allow' : 'respect';\n for (const item of s.Style || []) {\n const targets = item.el === 'self' ? [p] : p.querySelectorAll(item.el);\n targets.forEach(node => Object.assign(node.style, item.style));\n }\n // A generic keyboard focus target avoids button roles around interactive children.\n if (s.Tilt !== 'only' && !p.hasAttribute('tabindex')) p.tabIndex = 0;\n }\n events() {\n this.listen('click', event => {\n if (this.settings.Tilt === 'only') return;\n const trigger = this.settings.Click;\n if (trigger === true || (trigger && [].concat(trigger).some(selector => event.target.closest?.(selector) && this.hoverPanel.contains(event.target.closest(selector))))) this.toggle();\n });\n this.listen('keydown', event => {\n if (event.target !== this.hoverPanel || this.settings.Tilt === 'only') return;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); this.toggle(); }\n if (event.key === 'Escape') this.flip(false);\n });\n this.listen('pointerenter', event => { if (!this.settings.Click && this.settings.Tilt !== 'only' && event.pointerType !== 'touch') this.flip(true); });\n this.listen('pointerleave', () => { this.resetTilt(); if (!this.settings.Click && this.settings.Tilt !== 'only') this.flip(false); });\n this.listen('pointercancel', () => this.resetTilt());\n this.listen('pointerup', event => { if (event.pointerType === 'touch') { this.resetTilt(); if (!this.settings.Click && this.settings.Tilt !== 'only') this.toggle(); } });\n this.listen('pointermove', event => {\n if (!this.settings.Tilt || this.reduced || event.pointerType === 'touch') return;\n this.point = [event.clientX, event.clientY];\n if (this.frame) return;\n this.frame = this.win.requestAnimationFrame(() => {\n this.frame = 0;\n const rect = this.hoverPanel.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const t = { max: 10, perspective: 1000, scale: 1.03, ...(typeof this.settings.Tilt === 'object' ? this.settings.Tilt : {}) };\n const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));\n const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));\n this.hoverPanel.style.transform = `perspective(${t.perspective}px) rotateX(${-y * t.max}deg) rotateY(${x * t.max}deg) scale(${t.scale})`;\n });\n }, { passive: true });\n this.baseTransform = this.hoverPanel.style.transform;\n }\n resetTilt() { if (this.frame) this.win.cancelAnimationFrame(this.frame); this.frame = 0; this.hoverPanel.style.transform = this.baseTransform || ''; }\n render() {\n this.hoverPanel.dataset.jfiFlipped = String(this.flipped); this.hoverPanel.dataset.jfiReduced = String(this.reduced);\n for (const [node, hidden] of [[this.frontWrapper, this.flipped], [this.backWrapper, !this.flipped]]) { node.setAttribute('aria-hidden', String(hidden)); node.inert = hidden; }\n }\n flip(value = true) {\n if (this.destroyed || this.flipped === !!value) return this;\n const active = this.element.ownerDocument.activeElement;\n if ((value ? this.frontWrapper : this.backWrapper).contains(active)) this.hoverPanel.focus({ preventScroll: true });\n this.flipped = !!value; this.render();\n this.hoverPanel.dispatchEvent(new this.win.CustomEvent('justflipit:change', { bubbles: true, detail: this.getState() }));\n return this;\n }\n toggle() { return this.flip(!this.flipped); }\n update(options = {}) {\n if (this.destroyed) return this;\n if ('Faces' in options) throw new TypeError('Faces cannot change after initialization');\n validate(options);\n if (this.managed && 'Template' in options) throw new TypeError('Render framework face content with the framework');\n this.settings = { ...this.settings, ...options };\n if ('Template' in options) {\n if (this.managed) throw new TypeError('Render framework face content with the framework');\n this.backWrapper.innerHTML = options.Template;\n }\n this.resetTilt(); this.configure(); this.render(); return this;\n }\n getState() { return { flipped: this.flipped, destroyed: this.destroyed, effect: this.settings.Effect }; }\n destroy() {\n if (this.destroyed) return;\n this.resetTilt(); this.cleanups.forEach(fn => fn());\n this.restores.forEach(fn => fn());\n if (!this.managed) { this.hoverPanel.replaceWith(this.element); }\n instances.delete(this.element); instances.delete(this.hoverPanel); this.destroyed = true;\n }\n}\nfunction elements(target) {\n if (typeof target === 'string') return typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(target));\n if (target?.nodeType === 1) return [target];\n return target ? Array.from(target) : [];\n}\nexport default function justFlipIt(target, options) {\n const result = elements(target).map(element => instances.get(element) || new FlipController(element, options));\n return target?.nodeType === 1 ? result[0] : result;\n}\njustFlipIt.destroy = target => elements(target).forEach(element => instances.get(element)?.destroy());\njustFlipIt.get = element => instances.get(element);\n"],
|
|
5
|
-
"mappings": "ubAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oBAAAE,EAAA,YAAAC,IAAA,IAAMC,EAAY,IAAI,QAChBC,EAAW,CAAE,MAAO,GAAO,MAAO,GAAO,SAAU,IAAK,OAAQ,8BAA+B,KAAM,GAAO,OAAQ,OAAQ,cAAe,GAAM,gBAAiB,GAAM,eAAgB,GAAM,MAAO,CAAC,CAAE,EACxMC,EAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,
|
|
6
|
-
"names": ["core_exports", "__export", "FlipController", "justFlipIt", "instances", "defaults", "css", "styles", "doc", "style", "validate", "options", "key", "element", "clone", "node", "panel", "attrs", "name", "inert", "value", "motionChange", "type", "handler", "s", "p", "item", "event", "trigger", "selector", "rect", "
|
|
4
|
+
"sourcesContent": ["const instances = new WeakMap();\nconst defaults = { Click: false, FlipX: false, Duration: 400, Easing: 'cubic-bezier(.22,.61,.36,1)', Tilt: false, Effect: 'flip', ReducedMotion: true, preserveClasses: true, preserveStyles: true, Style: [] };\nconst css = `\n._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}\n._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}\n._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}\n._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}\n._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}\n._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}\n._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}\n._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}\n._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{transform:scale(.94)}\n._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}\n._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}\n@media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}\n`;\nfunction styles(doc) {\n if (doc.querySelector('style[data-justflipitstyle=\"v4\"]')) return;\n const style = doc.createElement('style');\n style.dataset.justflipitstyle = 'v4'; style.textContent = css; doc.head.append(style);\n}\nfunction validate(options) {\n if (options.Duration !== undefined && (!Number.isFinite(options.Duration) || options.Duration < 0)) throw new TypeError('Duration must be a non-negative finite number');\n if (options.Effect !== undefined && !['flip', 'fade', 'scale'].includes(options.Effect)) throw new TypeError('Unknown Effect');\n if (options.Tilt && typeof options.Tilt === 'object') {\n for (const key of ['max', 'perspective', 'scale']) {\n if (options.Tilt[key] !== undefined && (!Number.isFinite(options.Tilt[key]) || options.Tilt[key] < 0)) throw new TypeError(`Invalid Tilt.${key}`);\n }\n }\n}\nexport class FlipController {\n constructor(element, options = {}) {\n validate(options);\n if (!element || element.nodeType !== 1) throw new TypeError('Expected an HTML element');\n this.element = element; this.settings = { ...defaults, ...options }; this.flipped = false; this.destroyed = false;\n this.cleanups = []; this.restores = []; this.win = element.ownerDocument.defaultView;\n const doc = element.ownerDocument; styles(doc);\n this.managed = !!options.Faces;\n if (this.managed) {\n this.hoverPanel = element;\n this.frontWrapper = element.querySelector(options.Faces.front);\n this.backWrapper = element.querySelector(options.Faces.back);\n if (!this.frontWrapper || !this.backWrapper || this.frontWrapper === this.backWrapper || this.frontWrapper.parentNode !== element || this.backWrapper.parentNode !== element) throw new TypeError('Faces must select two distinct direct children');\n } else {\n if (!element.parentNode) throw new TypeError('Element must have a parent');\n this.hoverPanel = doc.createElement('div');\n this.frontWrapper = doc.createElement('div'); this.backWrapper = doc.createElement('div');\n if (this.settings.preserveClasses) this.hoverPanel.className = element.className;\n if (this.settings.preserveStyles) this.hoverPanel.style.cssText = element.style.cssText;\n element.before(this.hoverPanel); this.hoverPanel.append(this.frontWrapper, this.backWrapper);\n this.frontWrapper.append(element);\n if (options.Template !== undefined) this.backWrapper.innerHTML = options.Template;\n else {\n const clone = element.cloneNode(true);\n clone.removeAttribute('id'); clone.querySelectorAll('[id]').forEach(node => node.removeAttribute('id'));\n this.backWrapper.append(clone);\n }\n }\n const panel = this.hoverPanel;\n for (const node of [panel, this.frontWrapper, this.backWrapper]) {\n const owned = node === panel ? ['class', 'style', 'tabindex', 'data-jfi-axis', 'data-jfi-effect', 'data-jfi-motion', 'data-jfi-flipped', 'data-jfi-reduced'] : ['style', 'data-jfi-face', 'aria-hidden', 'inert'];\n const attrs = owned.map(name => [name, node.getAttribute(name)]);\n const inert = node.inert || false;\n this.restores.push(() => { node.inert = inert; for (const [name, value] of attrs) { if (value === null) node.removeAttribute(name); else node.setAttribute(name, value); } });\n }\n panel.classList.add('_justFlipIt_panel');\n this.frontWrapper.dataset.jfiFace = 'front'; this.backWrapper.dataset.jfiFace = 'back';\n this.motion = this.win.matchMedia?.('(prefers-reduced-motion: reduce)');\n const motionChange = () => { this.resetTilt(); this.render(); };\n this.motion?.addEventListener('change', motionChange);\n this.cleanups.push(() => this.motion?.removeEventListener('change', motionChange));\n this.configure(); this.events(); this.render();\n instances.set(element, this); instances.set(panel, this);\n }\n listen(type, handler, options) { this.hoverPanel.addEventListener(type, handler, options); this.cleanups.push(() => this.hoverPanel.removeEventListener(type, handler, options)); }\n get reduced() { return this.settings.ReducedMotion !== false && !!this.motion?.matches; }\n configure() {\n const s = this.settings, p = this.hoverPanel;\n p.style.setProperty('--jfi-duration', `${s.Duration}ms`); p.style.setProperty('--jfi-easing', s.Easing);\n p.dataset.jfiAxis = s.FlipX ? 'x' : 'y'; p.dataset.jfiEffect = s.Effect;\n p.dataset.jfiMotion = s.ReducedMotion === false ? 'allow' : 'respect';\n for (const item of s.Style || []) {\n const targets = item.el === 'self' ? [p] : p.querySelectorAll(item.el);\n targets.forEach(node => Object.assign(node.style, item.style));\n }\n // A generic keyboard focus target avoids button roles around interactive children.\n if (s.Tilt !== 'only' && !p.hasAttribute('tabindex')) p.tabIndex = 0;\n }\n events() {\n this.listen('click', event => {\n if (this.settings.Tilt === 'only') return;\n const trigger = this.settings.Click;\n if (trigger === true || (trigger && [].concat(trigger).some(selector => event.target.closest?.(selector) && this.hoverPanel.contains(event.target.closest(selector))))) this.toggle();\n });\n this.listen('keydown', event => {\n if (event.target !== this.hoverPanel || this.settings.Tilt === 'only') return;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); this.toggle(); }\n if (event.key === 'Escape') this.flip(false);\n });\n this.listen('pointerenter', event => { if (!this.settings.Click && this.settings.Tilt !== 'only' && event.pointerType !== 'touch') this.flip(true); });\n this.listen('pointerleave', event => {\n // Touch release also emits pointerleave. The tap must survive it.\n if (event.pointerType === 'touch') return;\n this.resetTilt();\n if (!this.settings.Click && this.settings.Tilt !== 'only') this.flip(false);\n });\n this.listen('pointerdown', event => {\n if (event.pointerType !== 'touch' || event.isPrimary === false || this.touch) return;\n this.resetTilt();\n this.touch = { id: event.pointerId, x: event.clientX, y: event.clientY, moved: false };\n this.queueTilt(event, this.touch);\n }, { passive: true });\n this.listen('pointermove', event => {\n if (event.pointerType !== 'touch') {\n if (!this.touch) this.queueTilt(event);\n return;\n }\n const touch = this.touch;\n if (!touch || touch.id !== event.pointerId) return;\n touch.moved ||= this.touchMoved(event, touch);\n this.queueTilt(event, touch);\n }, { passive: true });\n this.listen('pointerup', event => {\n const touch = this.finishTouch(event);\n if (!touch || touch.moved || this.touchMoved(event, touch)) return;\n // Explicit click triggers continue to use the browser's click event.\n if (!this.settings.Click && this.settings.Tilt !== 'only') this.toggle();\n });\n this.listen('pointercancel', event => {\n if (event.pointerType === 'touch') this.finishTouch(event);\n else this.resetTilt();\n });\n this.listen('lostpointercapture', event => this.finishTouch(event));\n this.baseTransform = this.hoverPanel.style.transform;\n }\n touchMoved(event, touch) {\n return Math.hypot(event.clientX - touch.x, event.clientY - touch.y) > 10;\n }\n finishTouch(event) {\n const touch = this.touch;\n if (event.pointerType !== 'touch' || !touch || touch.id !== event.pointerId) return;\n this.touch = null;\n this.resetTilt();\n return touch;\n }\n queueTilt(event, touch) {\n if (!this.settings.Tilt || this.reduced) return;\n this.point = [event.clientX, event.clientY];\n if (this.frame) return;\n this.frame = this.win.requestAnimationFrame(() => {\n this.frame = 0;\n // Keep the touch reference box stable as the panel rotates.\n const rect = touch\n ? (touch.rect ??= this.hoverPanel.getBoundingClientRect())\n : this.hoverPanel.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n const { max = 10, perspective = 1000, scale = 1.03 } = this.settings.Tilt;\n const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));\n const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));\n this.hoverPanel.style.transform = `perspective(${perspective}px) rotateX(${-y * max}deg) rotateY(${x * max}deg) scale(${scale})`;\n });\n }\n resetTilt() { if (this.frame) this.win.cancelAnimationFrame(this.frame); this.frame = 0; this.hoverPanel.style.transform = this.baseTransform || ''; }\n render() {\n this.hoverPanel.dataset.jfiFlipped = String(this.flipped); this.hoverPanel.dataset.jfiReduced = String(this.reduced);\n for (const [node, hidden] of [[this.frontWrapper, this.flipped], [this.backWrapper, !this.flipped]]) { node.setAttribute('aria-hidden', String(hidden)); node.inert = hidden; }\n }\n flip(value = true) {\n if (this.destroyed || this.flipped === !!value) return this;\n const active = this.element.ownerDocument.activeElement;\n if ((value ? this.frontWrapper : this.backWrapper).contains(active)) this.hoverPanel.focus({ preventScroll: true });\n this.flipped = !!value; this.render();\n this.hoverPanel.dispatchEvent(new this.win.CustomEvent('justflipit:change', { bubbles: true, detail: this.getState() }));\n return this;\n }\n toggle() { return this.flip(!this.flipped); }\n update(options = {}) {\n if (this.destroyed) return this;\n if ('Faces' in options) throw new TypeError('Faces cannot change after initialization');\n validate(options);\n if (this.managed && 'Template' in options) throw new TypeError('Render framework face content with the framework');\n this.settings = { ...this.settings, ...options };\n if ('Template' in options) {\n if (this.managed) throw new TypeError('Render framework face content with the framework');\n this.backWrapper.innerHTML = options.Template;\n }\n this.resetTilt(); this.configure(); this.render(); return this;\n }\n getState() { return { flipped: this.flipped, destroyed: this.destroyed, effect: this.settings.Effect }; }\n destroy() {\n if (this.destroyed) return;\n this.resetTilt(); this.cleanups.forEach(fn => fn());\n this.restores.forEach(fn => fn());\n if (!this.managed) { this.hoverPanel.replaceWith(this.element); }\n instances.delete(this.element); instances.delete(this.hoverPanel); this.destroyed = true;\n }\n}\nfunction elements(target) {\n if (typeof target === 'string') return typeof document === 'undefined' ? [] : Array.from(document.querySelectorAll(target));\n if (target?.nodeType === 1) return [target];\n return target ? Array.from(target) : [];\n}\nexport default function justFlipIt(target, options) {\n const result = elements(target).map(element => instances.get(element) || new FlipController(element, options));\n return target?.nodeType === 1 ? result[0] : result;\n}\njustFlipIt.destroy = target => elements(target).forEach(element => instances.get(element)?.destroy());\njustFlipIt.get = element => instances.get(element);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["core_exports", "__export", "FlipController", "justFlipIt", "instances", "defaults", "css", "styles", "doc", "style", "validate", "options", "key", "element", "clone", "node", "panel", "attrs", "name", "inert", "value", "motionChange", "type", "handler", "s", "p", "item", "event", "trigger", "selector", "touch", "rect", "max", "perspective", "scale", "x", "y", "hidden", "active", "fn", "elements", "target", "result"]
|
|
7
7
|
}
|