Tabs y Accordion animados
This commit is contained in:
@@ -34,6 +34,10 @@ const onUnmount = fn => {
|
||||
if (activeOwner) (activeOwner._cleanups ||= new Set()).add(fn)
|
||||
}
|
||||
|
||||
const onMount = fn => {
|
||||
if (activeOwner) (activeOwner._mounts ||= []).push(fn)
|
||||
}
|
||||
|
||||
const createEffect = (fn, isComputed = false) => {
|
||||
const effect = () => {
|
||||
if (effect._disposed) return
|
||||
@@ -99,20 +103,16 @@ const untrack = fn => {
|
||||
try { return fn() } finally { activeEffect = prev }
|
||||
}
|
||||
|
||||
const onMount = fn => {
|
||||
if (activeOwner) (activeOwner._mounts ||= []).push(fn)
|
||||
}
|
||||
|
||||
const $ = (value, storageKey = null) => {
|
||||
const $ = (initialValue, storageKey = null) => {
|
||||
const subs = new Set()
|
||||
if (isFunc(value)) {
|
||||
if (isFunc(initialValue)) {
|
||||
let cache, dirty = true
|
||||
const computed = () => {
|
||||
if (dirty) {
|
||||
const prev = activeEffect
|
||||
activeEffect = computed
|
||||
try {
|
||||
const next = value()
|
||||
const next = initialValue()
|
||||
if (!Object.is(cache, next)) {
|
||||
cache = next
|
||||
dirty = false
|
||||
@@ -140,18 +140,18 @@ const $ = (value, storageKey = null) => {
|
||||
if (activeOwner) onUnmount(computed.stop)
|
||||
return computed
|
||||
}
|
||||
if (storageKey) try { value = JSON.parse(localStorage.getItem(storageKey)) ?? value } catch (e) {}
|
||||
if (storageKey) try { initialValue = JSON.parse(localStorage.getItem(storageKey)) ?? initialValue } catch (e) {}
|
||||
return (...args) => {
|
||||
if (args.length) {
|
||||
const next = isFunc(args[0]) ? args[0](value) : args[0]
|
||||
if (!Object.is(value, next)) {
|
||||
value = next
|
||||
if (storageKey) localStorage.setItem(storageKey, JSON.stringify(value))
|
||||
const next = isFunc(args[0]) ? args[0](initialValue) : args[0]
|
||||
if (!Object.is(initialValue, next)) {
|
||||
initialValue = next
|
||||
if (storageKey) localStorage.setItem(storageKey, JSON.stringify(initialValue))
|
||||
trackUpdate(subs, true)
|
||||
}
|
||||
}
|
||||
trackUpdate(subs)
|
||||
return value
|
||||
return initialValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,33 +181,29 @@ const cleanupNode = node => {
|
||||
const DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i
|
||||
const isDangerousAttr = key => key === 'src' || key === 'href' || key.startsWith('on')
|
||||
|
||||
const validateAttr = (key, val) => {
|
||||
if (val == null || val === false) return null
|
||||
if (isDangerousAttr(key) && DANGEROUS_PROTOCOL.test(String(val))) return '#'
|
||||
return val
|
||||
}
|
||||
|
||||
const setProperty = (elem, key, val, isSVG) => {
|
||||
val = validateAttr(key, val)
|
||||
if (key === 'class' || key === 'className') elem.className = val || ''
|
||||
else if (key === 'style' && typeof val === 'object') Object.assign(elem.style, val)
|
||||
else if (key in elem && !isSVG) elem[key] = val
|
||||
else if (isSVG) {
|
||||
const applyProp = (elem, key, value, isSVG) => {
|
||||
if (value == null || value === false) {
|
||||
if (key === 'class' || key === 'className') elem.className = ''
|
||||
else if (key in elem && !isSVG) elem[key] = ''
|
||||
else elem.removeAttribute(key)
|
||||
return
|
||||
}
|
||||
if (key === 'class' || key === 'className') {
|
||||
elem.className = value
|
||||
} else if (key === 'style' && typeof value === 'object') {
|
||||
Object.assign(elem.style, value)
|
||||
} else if (key in elem && !isSVG) {
|
||||
elem[key] = value
|
||||
} else if (isSVG) {
|
||||
if (key.startsWith('xlink:')) {
|
||||
if (val == null || val === false) elem.removeAttributeNS('http://www.w3.org/1999/xlink', key.slice(6))
|
||||
else elem.setAttributeNS('http://www.w3.org/1999/xlink', key, val)
|
||||
elem.setAttributeNS('http://www.w3.org/1999/xlink', key, value)
|
||||
} else if (key === 'xmlns' || key.startsWith('xmlns:')) {
|
||||
if (val == null || val === false) elem.removeAttributeNS('http://www.w3.org/2000/xmlns/', key)
|
||||
else elem.setAttributeNS('http://www.w3.org/2000/xmlns/', key, val)
|
||||
elem.setAttributeNS('http://www.w3.org/2000/xmlns/', key, value)
|
||||
} else {
|
||||
if (val == null || val === false) elem.removeAttribute(key)
|
||||
else if (val === true) elem.setAttribute(key, '')
|
||||
else elem.setAttribute(key, val)
|
||||
elem.setAttribute(key, value === true ? '' : value)
|
||||
}
|
||||
} else {
|
||||
if (val == null || val === false) elem.removeAttribute(key)
|
||||
else if (val === true) elem.setAttribute(key, '')
|
||||
else elem.setAttribute(key, val)
|
||||
elem.setAttribute(key, value === true ? '' : value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,14 +226,14 @@ const Tag = (tag, props = {}, children = []) => {
|
||||
ctx._mounts = effect._mounts || []
|
||||
ctx._cleanups = effect._cleanups || new Set()
|
||||
const result = effect._result
|
||||
const attachLifecycle = node => {
|
||||
const attach = node => {
|
||||
if (node && typeof node === 'object' && !node._isRuntime) {
|
||||
node._mounts = ctx._mounts
|
||||
node._cleanups = ctx._cleanups
|
||||
node._ownerEffect = effect
|
||||
}
|
||||
}
|
||||
isArr(result) ? result.forEach(attachLifecycle) : attachLifecycle(result)
|
||||
isArr(result) ? result.forEach(attach) : attach(result)
|
||||
if (result == null) return null
|
||||
if (result instanceof Node || (isArr(result) && result.every(n => n instanceof Node))) return result
|
||||
return doc.createTextNode(String(result))
|
||||
@@ -262,11 +258,9 @@ const Tag = (tag, props = {}, children = []) => {
|
||||
onUnmount(off)
|
||||
} else if (isFunc(value)) {
|
||||
const effect = createEffect(() => {
|
||||
const val = validateAttr(key, value())
|
||||
if (key === "class") elem.className = val || ""
|
||||
else if (val == null) elem.removeAttribute(key)
|
||||
else if (key in elem && !isSVG) elem[key] = val
|
||||
else elem.setAttribute(key, val === true ? "" : val)
|
||||
let val = value()
|
||||
if (isDangerousAttr(key) && DANGEROUS_PROTOCOL.test(String(val))) val = '#'
|
||||
applyProp(elem, key, val, isSVG)
|
||||
})
|
||||
effect()
|
||||
elem._cleanups.add(() => dispose(effect))
|
||||
@@ -276,16 +270,14 @@ const Tag = (tag, props = {}, children = []) => {
|
||||
elem.addEventListener(eventType, ev => value(ev.target[key]))
|
||||
}
|
||||
} else {
|
||||
const val = validateAttr(key, value)
|
||||
if (val != null) {
|
||||
if (key in elem && !isSVG) elem[key] = val
|
||||
else elem.setAttribute(key, val === true ? "" : val)
|
||||
}
|
||||
let val = value
|
||||
if (isDangerousAttr(key) && DANGEROUS_PROTOCOL.test(String(val))) val = '#'
|
||||
if (val != null) applyProp(elem, key, val, isSVG)
|
||||
}
|
||||
}
|
||||
|
||||
const append = child => {
|
||||
if (isArr(child)) return child.forEach(append)
|
||||
const mountChild = child => {
|
||||
if (isArr(child)) return child.forEach(mountChild)
|
||||
if (isFunc(child)) {
|
||||
const anchor = doc.createTextNode("")
|
||||
elem.appendChild(anchor)
|
||||
@@ -316,7 +308,7 @@ const Tag = (tag, props = {}, children = []) => {
|
||||
if (node._mounts) node._mounts.forEach(fn => fn())
|
||||
}
|
||||
}
|
||||
append(children)
|
||||
mountChild(children)
|
||||
return elem
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user