Skip to content

Commit

Permalink
feat(directives): make arg and modifiers reactive
Browse files Browse the repository at this point in the history
- ref 5a1e4d6
  • Loading branch information
pdanpdan committed Mar 2, 2023
1 parent dc2bfcc commit 96e9454
Show file tree
Hide file tree
Showing 19 changed files with 453 additions and 275 deletions.
16 changes: 9 additions & 7 deletions ui/src/components/menu/ClickOutside.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function globalHandler (evt) {
export default {
name: 'click-outside',

bind (el, { value, arg }, vnode) {
bind (el, { arg, value }, vnode) {
const vmEl = vnode.componentInstance || vnode.context

const ctx = {
Expand Down Expand Up @@ -106,14 +106,16 @@ export default {
}, 500)
},

update (el, { value, oldValue, arg }) {
update (el, { arg, value, oldValue }) {
const ctx = el.__qclickoutside

if (value !== oldValue) {
ctx.trigger = value
}
if (arg !== ctx.arg) {
ctx.toggleEl = arg
if (ctx !== void 0) {
if (ctx.toggleEl !== arg) {
ctx.toggleEl = arg
}
if (oldValue !== value) {
ctx.trigger = value
}
}
},

Expand Down
2 changes: 1 addition & 1 deletion ui/src/directives/ClosePopup.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default {
},

update (el, { value, oldValue }) {
if (el.__qclosepopup !== void 0 && value !== oldValue) {
if (el.__qclosepopup !== void 0 && oldValue !== value) {
el.__qclosepopup.depth = getDepth(value)
}
},
Expand Down
13 changes: 9 additions & 4 deletions ui/src/directives/GoBack.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function destroy (el) {
export default {
name: 'go-back',

bind (el, { value, modifiers }, vnode) {
bind (el, { modifiers, value }, vnode) {
if (el.__qgoback !== void 0) {
destroy(el)
el.__qgoback_destroyed = true
Expand Down Expand Up @@ -51,11 +51,16 @@ export default {
el.addEventListener('keyup', ctx.goBackKey)
},

update (el, { value, oldValue }) {
update (el, { modifiers, value, oldValue }) {
const ctx = el.__qgoback

if (ctx !== void 0 && value !== oldValue) {
ctx.value = value
if (ctx !== void 0) {
if (ctx.single !== modifiers.single) {
ctx.single = modifiers.single
}
if (oldValue !== value) {
ctx.value = value
}
}
},

Expand Down
1 change: 1 addition & 0 deletions ui/src/directives/GoBack.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"single": {
"type": "Boolean",
"desc": "Go back to previous route instead of the whole way to before directive was initialized",
"reactive": true,
"examples": [ "v-go-back.single" ]
}
}
Expand Down
4 changes: 1 addition & 3 deletions ui/src/directives/Intersection.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,7 @@
"once": {
"type": "Boolean",
"desc": "Call handler only once, when the conditions are first met",
"examples": [
"v-intersection.once"
]
"examples": [ "v-intersection.once" ]
}
}
}
118 changes: 63 additions & 55 deletions ui/src/directives/Morph.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import morph from '../utils/morph.js'

const morphGroups = {}
const mods = [
'resize', 'useCSS', 'hideFromClone', 'keepToClone', 'tween'
]
const props = [
'duration', 'delay', 'easing', 'fill',
'classes', 'style', 'duration', 'resize',
'useCSS', 'hideFromClone', 'keepToClone', 'tween',
'classes', 'style', 'duration',
'tweenFromOpacity', 'tweenToOpacity',
'waitFor', 'onEnd'
]
const mods = [
'resize', 'useCSS', 'hideFromClone', 'keepToClone', 'tween'
]

function changeClass (ctx, action) {
if (ctx.clsAction !== action) {
Expand Down Expand Up @@ -65,47 +64,7 @@ function trigger (group) {
}
}

function updateModifiers (mod, ctx) {
const opts = ctx.opts

mods.forEach(name => {
opts[name] = mod[name] === true
})
}

function insertArgs (arg, ctx) {
const opts = typeof arg === 'string' && arg.length > 0
? arg.split(':') : []

ctx.name = opts[0]
ctx.group = opts[1]

Object.assign(ctx.opts, {
duration: isNaN(opts[2]) === true
? 300
: parseFloat(opts[2]),
waitFor: opts[3]
})
}

function updateArgs (arg, ctx) {
if (arg.group !== void 0) {
ctx.group = arg.group
}
if (arg.name !== void 0) {
ctx.name = arg.name
}

const opts = ctx.opts

props.forEach(name => {
if (arg[name] !== void 0) {
opts[name] = arg[name]
}
})
}

function updateModel (name, ctx) {
function changeModel (ctx, name) {
if (ctx.name === name) {
const group = morphGroups[ctx.group]

Expand Down Expand Up @@ -138,21 +97,61 @@ function updateModel (name, ctx) {
}
}

function setOptsFromValue (ctx, value) {
if (value.group !== void 0) {
ctx.group = value.group
}
if (value.name !== void 0) {
ctx.name = value.name
}

const opts = ctx.opts

props.forEach(name => {
if (value[name] !== void 0) {
opts[name] = value[name]
}
})
}

function updateArg (ctx, arg) {
const opts = typeof arg === 'string' && arg.length > 0
? arg.split(':') : []

ctx.name = opts[0]
ctx.group = opts[1]

Object.assign(ctx.opts, {
duration: isNaN(opts[2]) === true
? 300
: parseFloat(opts[2]),
waitFor: opts[3]
})
}

function updateModifiers (ctx, modifiers) {
const opts = ctx.opts

mods.forEach(name => {
opts[name] = modifiers[name] === true
})
}

function updateValue (ctx, value) {
let model

if (Object(value) === value) {
model = '' + value.model
updateArgs(value, ctx)
updateModifiers(value, ctx)
setOptsFromValue(ctx, value)
updateModifiers(ctx, value)
}
else {
model = '' + value
}

if (model !== ctx.model) {
ctx.model = model
updateModel(model, ctx)
changeModel(ctx, model)
}
else if (ctx.animating === false && ctx.clsAction !== void 0) {
// ensure HMR
Expand Down Expand Up @@ -190,28 +189,37 @@ function destroy (el) {
export default {
name: 'morph',

inserted (el, binding) {
inserted (el, { modifiers, arg, value }) {
if (el.__qmorph !== void 0) {
destroy(el)
el.__qmorph_destroyed = true
}

const ctx = {
el,

arg,

animating: false,
opts: {}
}

updateModifiers(binding.modifiers, ctx)
insertArgs(binding.arg, ctx)
updateValue(ctx, binding.value)
updateModifiers(ctx, modifiers)
updateArg(ctx, arg)
updateValue(ctx, value)

el.__qmorph = ctx
},

update (el, binding) {
update (el, { modifiers, arg, value }) {
const ctx = el.__qmorph
ctx !== void 0 && updateValue(ctx, binding.value)
if (ctx !== void 0) {
updateModifiers(ctx, modifiers)
if (ctx.arg !== arg) {
updateArg(ctx, arg)
}
updateValue(ctx, value)
}
},

unbind (el) {
Expand Down
16 changes: 11 additions & 5 deletions ui/src/directives/Morph.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@
"arg": {
"type": "String",
"desc": "x:x2:y:z, where x is the morph element name, x2 is the morph group, y is the animation duration (in milliseconds) and z is the amount of time to wait (in milliseconds) or the 'transitionend' string",
"reactive": true,
"examples": [
"v-morph:name=\"options\"",
"v-morph:name:groupName=\"options\"",
Expand All @@ -153,27 +154,32 @@
"modifiers": {
"resize": {
"type": "Boolean",
"desc": "Use resize instead of scale transform for morph (forceResize option of the morph function)"
"desc": "Use resize instead of scale transform for morph (forceResize option of the morph function)",
"reactive": true
},

"useCSS": {
"type": "Boolean",
"desc": "Use CSS animations for morph (forceCssAnimation option of the morph function)"
"desc": "Use CSS animations for morph (forceCssAnimation option of the morph function)",
"reactive": true
},

"hideFromClone": {
"type": "Boolean",
"desc": "Hide the spacer for the initial element (hideFromClone option of the morph function)"
"desc": "Hide the spacer for the initial element (hideFromClone option of the morph function)",
"reactive": true
},

"keepToClone": {
"type": "Boolean",
"desc": "Keep the final element visible while morphing (keepToClone option of the morph function)"
"desc": "Keep the final element visible while morphing (keepToClone option of the morph function)",
"reactive": true
},

"tween": {
"type": "Boolean",
"desc": "Use opacity tween morphing between initial and final elements (tween option of the morph function)"
"desc": "Use opacity tween morphing between initial and final elements (tween option of the morph function)",
"reactive": true
}
}
}
27 changes: 19 additions & 8 deletions ui/src/directives/Mutation.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isDeepEqual } from '../utils/is.js'

const defaultCfg = {
childList: true,
subtree: true,
Expand Down Expand Up @@ -35,28 +37,37 @@ function destroy (el) {
export default {
name: 'mutation',

inserted (el, { modifiers: { once, ...mod }, value }) {
inserted (el, { modifiers: { once, ...opts }, value }) {
if (el.__qmutation !== void 0) {
destroy(el)
el.__qmutation_destroyed = true
}

const ctx = {
once,
opts: Object.keys(mod).length === 0
? defaultCfg
: mod
once
}

ctx.opts = Object.keys(opts).length === 0
? defaultCfg
: opts
update(el, ctx, value)

el.__qmutation = ctx
},

update (el, { oldValue, value }) {
update (el, { modifiers: { once, ...opts }, value, oldValue }) {
const ctx = el.__qmutation
if (ctx !== void 0 && oldValue !== value) {
update(el, ctx, value)
if (ctx !== void 0) {
const newOpts = Object.keys(opts).length === 0
? defaultCfg
: opts
if (
oldValue !== value ||
isDeepEqual(ctx.opts, newOpts) !== true
) {
ctx.opts = newOpts
update(el, ctx, value)
}
}
},

Expand Down
Loading

0 comments on commit 96e9454

Please sign in to comment.