@leafer-in/state 1.0.1 → 1.0.3

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/src/index.ts CHANGED
@@ -1,29 +1,83 @@
1
- import { ILeaf, IStateStyleType } from '@leafer-ui/interface'
2
- import { State, UI } from '@leafer-ui/core'
1
+ export { stateType, stateStyleType } from './decorator'
3
2
 
4
- import { setStateStyle } from './set'
5
- import { unsetStateStyle } from './unset'
3
+ import { IUI, IStateStyleType, IStateName } from '@leafer-ui/interface'
4
+ import { State, UI, dataType } from '@leafer-ui/core'
5
+
6
+ import { setPointerState, setState } from './set'
7
+ import { unsetPointerState, unsetState } from './unset'
6
8
  import { updateEventStyle } from './event'
9
+ import { checkPointerState, checkFixedState, checkState } from './check'
10
+ import { getStyle, updateStyle } from './style'
11
+ import { stateType, stateStyleType } from './decorator'
12
+
13
+
14
+ State.animateExcludes = {
15
+ animation: 1,
16
+ animationOut: 1,
17
+
18
+ transition: 1,
19
+ transitionOut: 1,
20
+
21
+ states: 1,
22
+ state: 1,
23
+
24
+ normalStyle: 1,
25
+ hoverStyle: 1,
26
+ pressStyle: 1,
27
+ focusStyle: 1,
28
+ selectedStyle: 1,
29
+ disabledStyle: 1
30
+ }
31
+
32
+
33
+ State.isState = function (state: IStateName, leaf: IUI, button?: IUI | boolean): boolean { return checkState(state, leaf, button) }
34
+ State.isSelected = function (leaf: IUI, button?: IUI | boolean): boolean { return checkFixedState('selected', leaf, button) }
35
+ State.isDisabled = function (leaf: IUI, button?: IUI | boolean): boolean { return checkFixedState('disabled', leaf, button) }
7
36
 
37
+ State.isFocus = function (leaf: IUI, button?: IUI | boolean): boolean { return checkPointerState('isFocus', leaf, button) }
38
+ State.isHover = function (leaf: IUI, button?: IUI | boolean): boolean { return checkPointerState('isHover', leaf, button) }
39
+ State.isPress = function (leaf: IUI, button?: IUI | boolean): boolean { return checkPointerState('isPress', leaf, button) }
8
40
 
9
- State.isHover = function (leaf: ILeaf): boolean { return leaf.leafer && leaf.leafer.interaction.isHover(leaf) }
10
- State.isPress = function (leaf: ILeaf): boolean { return leaf.leafer && leaf.leafer.interaction.isPress(leaf) }
11
- State.isFocus = function (leaf: ILeaf): boolean { return leaf.leafer && leaf.leafer.interaction.isFocus(leaf) }
12
- State.isDrag = function (leaf: ILeaf): boolean { return leaf.leafer && leaf.leafer.interaction.isDrag(leaf) }
13
- State.setStyle = function (leaf: ILeaf, stateType: IStateStyleType, value: boolean): void { value ? setStateStyle(leaf, stateType) : unsetStateStyle(leaf, stateType) }
41
+ State.isDrag = function (leaf: IUI, button?: IUI | boolean): boolean { return checkPointerState('isDrag', leaf, button) }
42
+
43
+ State.setStyleName = function (leaf: IUI, stateType: IStateStyleType, value: boolean): void { value ? setState(leaf, stateType, leaf[stateType]) : unsetState(leaf, stateType, leaf[stateType]) }
44
+ State.set = function (leaf: IUI, stateName: string): void { const style = leaf.states[stateName]; style ? setState(leaf, stateName, style) : unsetState(leaf, stateName, style) }
45
+
46
+ State.getStyle = getStyle
47
+ State.updateStyle = updateStyle
14
48
  State.updateEventStyle = updateEventStyle
15
49
 
16
50
 
17
- UI.prototype.focus = function (value: boolean = true): void {
51
+ const ui = UI.prototype
52
+
53
+ // addAttr
54
+ stateType(false, 'selectedStyle')(ui, 'selected')
55
+ stateType(false, 'disabledStyle')(ui, 'disabled')
56
+
57
+ stateStyleType({})(ui, 'states')
58
+ stateType('')(ui, 'state')
59
+
60
+ dataType()(ui, 'normalStyle')
61
+ stateStyleType()(ui, 'hoverStyle')
62
+ stateStyleType()(ui, 'pressStyle')
63
+ stateStyleType()(ui, 'focusStyle')
64
+ stateStyleType()(ui, 'selectedStyle')
65
+ stateStyleType()(ui, 'disabledStyle')
66
+
67
+ dataType(false)(ui, 'button')
68
+
69
+ ui.focus = function (value: boolean = true): void {
18
70
  this.waitLeafer(() => {
19
71
  let { focusData } = this.app.interaction
20
72
  if (value) {
21
73
  if (focusData) focusData.focus(false)
22
74
  focusData = this
23
- } else {
24
- focusData = null
25
- }
75
+ } else focusData = null
26
76
  this.app.interaction.focusData = focusData
27
- State.setStyle(this, 'focusStyle', value)
77
+ value ? setPointerState(this, 'focusStyle') : unsetPointerState(this, 'focusStyle')
28
78
  })
79
+ }
80
+
81
+ ui.updateState = function (): void {
82
+ State.updateStyle(this, undefined, 'in')
29
83
  }
package/src/set.ts CHANGED
@@ -1,40 +1,45 @@
1
- import { ILeaf, IObject, IStateStyleType } from '@leafer-ui/interface'
1
+ import { IUI, IStateStyle, IStateStyleType, IStateName } from '@leafer-ui/interface'
2
2
  import { State } from '@leafer-ui/core'
3
3
 
4
- import { hasFixedState, restoreStyle } from './helper'
4
+ import { setStyle } from './style'
5
5
 
6
6
 
7
- export function setStateStyle(leaf: ILeaf, stateType: IStateStyleType, pointerState?: boolean): void {
7
+ export function setPointerState(leaf: IUI, stateName: IStateStyleType): void {
8
+ const style = leaf[stateName]
9
+ if (style) setStyle(leaf, style)
10
+ if (leaf.button) setChildrenState(leaf.children, stateName)
11
+ }
8
12
 
9
- let style: IObject
10
- const data = leaf.__ as IObject
13
+ export function setState(leaf: IUI, stateName: string, stateStyle?: IStateStyle): void {
14
+ if (!stateStyle) stateStyle = leaf.states[stateName]
15
+ setStyle(leaf, stateStyle)
16
+ if (leaf.button) setChildrenState(leaf.children, null, stateName)
17
+ }
11
18
 
12
- if (pointerState) {
13
19
 
14
- // hover / press
15
- style = !hasFixedState(leaf) && data[stateType]
20
+ function setChildrenState(children: IUI[], stateType: IStateStyleType, state?: IStateName): void {
21
+ if (!children) return
16
22
 
17
- } else {
23
+ let leaf: IUI, update: boolean
24
+ for (let i = 0, len = children.length; i < len; i++) {
25
+ leaf = children[i]
26
+ if (stateType) {
18
27
 
19
- // disabled > focus > selected
20
- switch (stateType) {
21
- case 'disabledStyle':
22
- style = data[stateType]
23
- break
24
- case 'focusStyle':
25
- style = !leaf.disabled && data[stateType]
26
- break
27
- case 'selectedStyle':
28
- style = !leaf.disabled && !State.isFocus(leaf) && data[stateType]
29
- break
30
- }
28
+ update = true
29
+ switch (stateType) {
30
+ case 'hoverStyle':
31
+ if (State.isHover(leaf)) update = false
32
+ break
33
+ case 'pressStyle':
34
+ if (State.isPress(leaf)) update = false
35
+ break
36
+ case 'focusStyle':
37
+ if (State.isFocus(leaf)) update = false
38
+ }
39
+ if (update) setPointerState(leaf, stateType)
31
40
 
32
- }
41
+ } else if (state) setState(leaf, state)
33
42
 
34
- if (style) {
35
- restoreStyle(leaf) // 先回到正常状态
36
- leaf.__.normalStyle = leaf.get(style) as IObject
37
- leaf.set(style)
43
+ if (leaf.isBranch) setChildrenState(leaf.children, stateType, state)
38
44
  }
39
-
40
45
  }
package/src/style.ts ADDED
@@ -0,0 +1,136 @@
1
+ import { IUI, IObject, IUIInputData, IStateStyle, IScaleData, ITransition } from '@leafer-ui/interface'
2
+ import { State, MathHelper, isNull } from '@leafer-ui/core'
3
+
4
+ import { findParentButton } from './helper'
5
+
6
+
7
+ export function setStyle(leaf: IUI, style: IStateStyle): void {
8
+ if (typeof style !== 'object') style = undefined
9
+ updateStyle(leaf, style, 'in')
10
+ }
11
+
12
+ export function unsetStyle(leaf: IUI, style?: IStateStyle): void {
13
+ const { normalStyle } = leaf
14
+ if (typeof style !== 'object') style = undefined
15
+ if (normalStyle) {
16
+ if (!style) style = normalStyle
17
+ updateStyle(leaf, style, 'out')
18
+ }
19
+ }
20
+
21
+ const emprtyStyle = {}
22
+
23
+ export function updateStyle(leaf: IUI, style?: IStateStyle, type?: 'in' | 'out'): void {
24
+ const { normalStyle } = leaf
25
+
26
+ if (!style) style = emprtyStyle
27
+
28
+ if (style.scale) {
29
+ MathHelper.assignScale(style as IScaleData, style.scale)
30
+ delete style.scale
31
+ }
32
+
33
+ if (style === emprtyStyle || !State.canAnimate) type = null
34
+ let transition = type ? getTransition(type, style, leaf) : false
35
+ const fromStyle = transition ? getFromStyle(leaf, style) : undefined
36
+
37
+ // 回到正常状态
38
+ leaf.killAnimate('transition')
39
+ if (normalStyle) leaf.set(normalStyle, true)
40
+
41
+
42
+ const statesStyle = getStyle(leaf) // 必须在回到正常状态之后获取
43
+ if (statesStyle) {
44
+
45
+ const { animation } = statesStyle
46
+ if (animation) {
47
+ const animate = leaf.animate(animation, undefined, 'animation', true)
48
+ Object.assign(statesStyle, animate.endingStyle) // 加上最终的动画样式
49
+
50
+ if (type !== 'in' || style.animation !== animation) animate.kill()
51
+ else transition = false
52
+
53
+ delete statesStyle.animation
54
+ }
55
+
56
+
57
+ leaf.normalStyle = filterStyle(statesStyle, leaf)
58
+ leaf.set(statesStyle, true)
59
+ } else {
60
+ leaf.normalStyle = undefined
61
+ }
62
+
63
+ if (transition) {
64
+ const toStyle = filterStyle(fromStyle, leaf)
65
+ leaf.set(fromStyle, true)
66
+ leaf.animate([fromStyle, toStyle], transition, 'transition', true)
67
+ }
68
+
69
+ leaf.__layout.stateStyleChanged = false
70
+ }
71
+
72
+ export function getStyle(leaf: IUI): IStateStyle {
73
+
74
+ // 从低到高依次覆盖: states < selected < focus < hover < press < disabled
75
+
76
+ let exist: boolean
77
+ const style: IUIInputData = {}, { state } = leaf, button = findParentButton(leaf)
78
+
79
+ const stateStyle = state && leaf.states[state]
80
+ if (stateStyle && State.isState(state, leaf, button)) exist = assign(style, stateStyle)
81
+
82
+ const selectedStyle = style.selectedStyle || leaf.selectedStyle
83
+ if (selectedStyle && State.isSelected(leaf, button)) exist = assign(style, selectedStyle)
84
+
85
+ if (State.isDisabled(leaf, button)) {
86
+
87
+ const disabledStyle = style.disabledStyle || leaf.disabledStyle
88
+ if (disabledStyle) exist = assign(style, disabledStyle)
89
+
90
+ } else {
91
+
92
+ const focusStyle = style.focusStyle || leaf.focusStyle
93
+ if (focusStyle && State.isFocus(leaf, button)) exist = assign(style, focusStyle)
94
+
95
+ const hoverStyle = style.hoverStyle || leaf.hoverStyle
96
+ if (hoverStyle && State.isHover(leaf, button)) exist = assign(style, hoverStyle)
97
+
98
+ const pressStyle = style.pressStyle || leaf.pressStyle
99
+ if (pressStyle && State.isPress(leaf, button)) exist = assign(style, pressStyle)
100
+
101
+ }
102
+
103
+ return exist ? style : undefined
104
+ }
105
+
106
+
107
+ function filterStyle(style: IObject, data: IObject, addStyle?: IObject, useAnimateExcludes?: boolean): IObject {
108
+ const to: IObject = addStyle ? style : {}, forStyle = addStyle || style
109
+ for (let key in forStyle) {
110
+ if (useAnimateExcludes) {
111
+ if (!State.animateExcludes[key]) to[key] = data[key]
112
+ } else to[key] = data[key]
113
+ }
114
+ return to
115
+ }
116
+
117
+ function filterAnimateStyle(style: IObject, data: IObject, addStyle?: IObject): IObject {
118
+ return filterStyle(style, data, addStyle, true)
119
+ }
120
+
121
+ function getFromStyle(leaf: IUI, style: IObject): IObject {
122
+ const fromStyle = filterAnimateStyle(style, leaf), animate = leaf.animate()
123
+ if (animate) filterAnimateStyle(fromStyle, leaf, animate.fromStyle)
124
+ return fromStyle
125
+ }
126
+
127
+ function getTransition(type: 'in' | 'out', style: IStateStyle, data: IUI): ITransition {
128
+ let name: 'transition' | 'transitionOut' = type === 'in' ? 'transition' : 'transitionOut'
129
+ if (type === 'out' && isNull(data[name]) && isNull(style[name])) name = 'transition'
130
+ return isNull(style[name]) ? data[name] : style[name]
131
+ }
132
+
133
+ function assign(style: IStateStyle, stateStyle: IStateStyle): boolean {
134
+ Object.assign(style, stateStyle)
135
+ return true
136
+ }
package/src/unset.ts CHANGED
@@ -1,40 +1,29 @@
1
- import { ILeaf, IStateStyleType } from '@leafer/interface'
2
- import { State } from '@leafer-ui/core'
1
+ import { IUI, IStateStyleType, IStateStyle, IStateName } from '@leafer-ui/interface'
3
2
 
4
- import { setStateStyle } from './set'
5
- import { hasFixedState, restoreStyle } from './helper'
3
+ import { unsetStyle } from './style'
6
4
 
7
5
 
8
- export function unsetStateStyle(leaf: ILeaf, _stateType: IStateStyleType, pointerState?: boolean): void {
6
+ export function unsetPointerState(leaf: IUI, stateName: IStateStyleType): void {
7
+ const style = leaf[stateName]
8
+ if (style) unsetStyle(leaf, style)
9
+ if (leaf.button) unsetChildrenState(leaf.children, stateName)
10
+ }
9
11
 
10
- if (pointerState) {
12
+ export function unsetState(leaf: IUI, stateName: string, stateStyle?: IStateStyle): void {
13
+ unsetStyle(leaf, stateStyle)
14
+ if (leaf.button) unsetChildrenState(leaf.children, null, stateName)
15
+ }
11
16
 
12
- if (!hasFixedState(leaf)) {
13
17
 
14
- restoreStyle(leaf)
18
+ function unsetChildrenState(children: IUI[], stateType: IStateStyleType, state?: IStateName): void {
19
+ if (!children) return
15
20
 
16
- // press > hover
17
- if (State.isPress(leaf) && leaf.pressStyle) {
18
- setStateStyle(leaf, 'pressStyle', true)
19
- } else if (State.isHover(leaf) && leaf.hoverStyle) {
20
- setStateStyle(leaf, 'hoverStyle', true)
21
- }
22
-
23
- }
24
-
25
- } else {
26
-
27
- // disabled > focus > selected
28
- restoreStyle(leaf)
29
-
30
- if (leaf.disabledStyle && leaf.disabled) {
31
- setStateStyle(leaf, 'disabledStyle')
32
- } else if (leaf.focusStyle && State.isFocus(leaf)) {
33
- setStateStyle(leaf, 'focusStyle')
34
- } else if (leaf.selectedStyle && leaf.selected) {
35
- setStateStyle(leaf, 'selectedStyle')
36
- }
21
+ let leaf: IUI
22
+ for (let i = 0, len = children.length; i < len; i++) {
23
+ leaf = children[i]
24
+ if (stateType) unsetPointerState(leaf, stateType)
25
+ else if (state) unsetState(leaf, state)
37
26
 
27
+ if (leaf.isBranch) unsetChildrenState(leaf.children, stateType, state)
38
28
  }
39
-
40
29
  }
package/types/index.d.ts CHANGED
@@ -1,2 +1,7 @@
1
+ import * as _leafer_ui_interface from '@leafer-ui/interface';
2
+ import { IValue } from '@leafer-ui/interface';
1
3
 
2
- export { }
4
+ declare function stateType(defaultValue?: IValue, styleName?: string): (target: _leafer_ui_interface.ILeaf, key: string) => void;
5
+ declare function stateStyleType(defaultValue?: IValue): (target: _leafer_ui_interface.ILeaf, key: string) => void;
6
+
7
+ export { stateStyleType, stateType };