snail.view 1.0.3 → 1.0.5

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.
@@ -1,44 +1,290 @@
1
1
  import { IScope, IVersionManager } from 'snail.core';
2
2
 
3
+ /**
4
+ * CSS管理器
5
+ */
6
+ interface ICSSManager {
7
+ /**
8
+ * 转换CSS对象为描述符
9
+ * @param op
10
+ */
11
+ parse(css: CSS): CSSDescriptor;
12
+ /**
13
+ * 进行css操作
14
+ * - 删除操作时,从css.style中分析key做清理
15
+ * @param el 目标元素
16
+ * @param type 操作类型:添加、清楚
17
+ * @param css css对象
18
+ */
19
+ operate(el: HTMLElement, type: "add" | "clear", css: CSSDescriptor): any;
20
+ /**
21
+ * 构建样式
22
+ * @param options 样式配置
23
+ * @param isFlex 是否是flex布局
24
+ * @returns 计算出来的组件样式信息
25
+ */
26
+ buildStyle(options: AllStyle | undefined, isFlex?: boolean): Partial<CSSStyleDeclaration>;
27
+ }
28
+ /**
29
+ * css 样式
30
+ * - string、string[] 时为 class 类样式名称
31
+ * - Object时为 style 样式对象:key为样式名称(height、width、scale),value为样式值
32
+ * - - { height:"100px" }
33
+ */
34
+ type CSS = string | string[] | Partial<CSSStyleDeclaration>;
35
+ /**
36
+ * css 信息 描述器
37
+ */
38
+ type CSSDescriptor = {
39
+ /**
40
+ * class样式名称数组
41
+ */
42
+ class?: string[];
43
+ /**
44
+ * 内联样式信息
45
+ */
46
+ style?: Partial<CSSStyleDeclaration>;
47
+ };
48
+ /**
49
+ * 所有的样式属性
50
+ * - 高度、宽度、对齐、边框、内边距等合集
51
+ * - 对齐方式、、、
52
+ */
53
+ type AllStyle = AlignStyle & FlexStyle & HeightStyle & WidthStyle & MarginStyle & BorderStyle & PaddingStyle & TransitionStyle;
54
+ /**
55
+ * 组件对齐样式
56
+ * - flex布局时约束 align-items和 justify-content
57
+ * - 非flex布局时约束 text-align和 vertical-align
58
+ */
59
+ type AlignStyle = {
60
+ /**
61
+ * 对齐方式
62
+ * - left: 左对齐
63
+ * - center: 居中对齐
64
+ * - right: 右对齐
65
+ */
66
+ align?: "left" | "center" | "right";
67
+ /**
68
+ * 垂直对齐方式
69
+ * - top: 顶部对齐
70
+ * - middle: 居中对齐
71
+ * - bottom: 底部对齐
72
+ */
73
+ valign?: "top" | "middle" | "bottom";
74
+ };
75
+ /**
76
+ * 主轴弹性样式
77
+ */
78
+ type FlexStyle = {
79
+ /**
80
+ * 弹性置
81
+ * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex
82
+ */
83
+ flex?: string;
84
+ /**
85
+ * 主轴初始大小
86
+ * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-basis
87
+ */
88
+ flexBasis?: string;
89
+ /**
90
+ * 主轴放大系数
91
+ * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-grow
92
+ */
93
+ flexGrow?: number | "inherit" | "initial" | "revert" | "unset";
94
+ /**
95
+ * 主轴收缩规则
96
+ * @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex-shrink
97
+ */
98
+ flexShrink?: number | "inherit" | "initial" | "unset";
99
+ };
100
+ /**
101
+ * 宽度样式
102
+ */
103
+ type WidthStyle = {
104
+ /**
105
+ * 宽度
106
+ */
107
+ width?: string;
108
+ /**
109
+ * 最小宽度
110
+ */
111
+ minWidth?: string;
112
+ /**
113
+ * 最大宽度
114
+ */
115
+ maxWidth?: string;
116
+ };
117
+ /**
118
+ * 高度样式
119
+ */
120
+ type HeightStyle = {
121
+ /**
122
+ * 高度
123
+ */
124
+ height?: string;
125
+ /**
126
+ * 最小高度
127
+ */
128
+ minHeight?: string;
129
+ /**
130
+ * 最大高度
131
+ */
132
+ maxHeight?: string;
133
+ };
134
+ /**
135
+ * 组件外边距样式
136
+ * - margin < marginXXX
137
+ */
138
+ type MarginStyle = {
139
+ /**
140
+ * 外边距样式
141
+ */
142
+ margin?: string;
143
+ /**
144
+ * 上外边距样式
145
+ */
146
+ marginTop?: string;
147
+ /**
148
+ * 右外边距样式
149
+ */
150
+ marginRight?: string;
151
+ /**
152
+ * 下外边距样式
153
+ */
154
+ marginBottom?: string;
155
+ /**
156
+ * 左外边距样式
157
+ */
158
+ marginLeft?: string;
159
+ };
160
+ /**
161
+ * 组件边框样式
162
+ * - border < borderXXX
163
+ */
164
+ type BorderStyle = {
165
+ /**
166
+ * 边框圆角
167
+ */
168
+ borderRadius?: string;
169
+ /**
170
+ * 边框样式
171
+ */
172
+ border?: string;
173
+ /**
174
+ * 上边框样式
175
+ */
176
+ borderTop?: string;
177
+ /**
178
+ * 右边框样式
179
+ */
180
+ borderRight?: string;
181
+ /**
182
+ * 下边框样式
183
+ */
184
+ borderBottom?: string;
185
+ /**
186
+ * 左边框样式
187
+ */
188
+ borderLeft?: string;
189
+ };
190
+ /**
191
+ * 内边距样式
192
+ * - 优先级:padding < paddingXXX
193
+ */
194
+ type PaddingStyle = {
195
+ /**
196
+ * 内边距
197
+ */
198
+ padding?: string;
199
+ /**
200
+ * 上内边距
201
+ */
202
+ paddingTop?: string;
203
+ /**
204
+ * 右内边距
205
+ */
206
+ paddingRight?: string;
207
+ /**
208
+ * 下内边距
209
+ */
210
+ paddingBottom?: string;
211
+ /**
212
+ * 左内边距
213
+ */
214
+ paddingLeft?: string;
215
+ };
216
+ /**
217
+ * 过渡效果 样式
218
+ */
219
+ type TransitionStyle = {
220
+ /**
221
+ * 过渡效果
222
+ */
223
+ transition?: string;
224
+ /**
225
+ * 过渡效果属性
226
+ * - 如height、width、left、、、
227
+ */
228
+ transitionProperty?: string;
229
+ /**
230
+ * 过渡效果持续时间
231
+ */
232
+ transitionDuration?: string;
233
+ /**
234
+ * 过渡效果延迟时间
235
+ */
236
+ transitionDelay?: string;
237
+ /**
238
+ * 过渡效果函数
239
+ * - 暂时固定效果,后期支持自定义
240
+ */
241
+ transitionTimingFunction?: ("ease" | "ease-in" | "ease-out" | "ease-in-out" | "linear" | "step-start" | "step-end");
242
+ };
243
+
3
244
  /**
4
245
  * 动画管理器
5
246
  */
6
247
  interface IAnimationManager {
7
248
  /**
8
- * 【卷起】动画
9
- * - 水平方向 卷动 时,设置target的宽度
10
- * - 垂直方向 卷动 时,设置target的高度
11
- * @param target 要执行动画的目标元素
12
- * @param direction 卷起方法:水平、垂直
13
- * @param options 动画效果配置
249
+ * 过渡动画:从初始样式变为目标样式
250
+ * - 执行顺序 from - to - end
251
+ * - 开始动画时,清理 to end 操作样式,设置 from 再设异步置 to 样式
252
+ * - 动画结束后,清理 from to 操作样式,保留 end 样式
253
+ * @param el 执行动画的元素
254
+ * @param effect 动画效果配置,约束 from to end 样式
255
+ * @param time 动画持续时长,单位ms,默认200ms;动画结束后销毁作用域
14
256
  * @returns 动画作用域
15
- */
16
- roll(target: HTMLElement, direction: "horizontal" | "vertical", options: TransitionEffectOptions): IScope;
257
+ * @example 将div的高度在1s内从100px变为200px。动画结束后保持200px高度,则可以使用如下代码:
258
+ * transition(el,{
259
+ * from: { transition: "height 1s ease", "overflow": "hidden", height: "100px" },
260
+ * to: { height: "200px" },
261
+ * end: { height: "200px" }
262
+ * }, 1000);
263
+ */
264
+ transition(el: HTMLElement, effect: TransitionEffectOptions, time?: number): IScope;
17
265
  }
18
266
  /**
19
- * 过渡动画效果配置选项
20
- * - 约束动画过程中样式值:样式名随着动画类型自动适配,如roll动画则为 height
267
+ * 过渡动画效果配置信息
268
+ * - 执行顺序 from - to - end
21
269
  */
22
270
  type TransitionEffectOptions = {
23
271
  /**
24
- * 样式过渡的初始值
25
- * - roll 动画时,设置过渡动画的初始高度值
26
- */
27
- start: string;
28
- /**
29
- * 样式过渡到的目标值
30
- * - 如 roll 动画时,设置过渡动画的最终高度值
272
+ * 过渡动画开始样式
273
+ * - 支持 class 、style 样式属性
274
+ * - 如 高度 从 100 到 200;100 则为动画开始样式
31
275
  */
32
- target: string;
276
+ from: CSS;
33
277
  /**
34
- * 动画时间,单位ms
35
- * - 默认 200ms
278
+ * 过渡动画目标样式
279
+ * - 支持 class 、style 样式属性
280
+ * - 如 高度 从 100 到 200;200 则为动画目标样式
36
281
  */
37
- time?: number;
282
+ to: CSS;
38
283
  /**
39
- * 动画结束后,是否清理过渡动画的target值
284
+ * 动画结束样式
285
+ * - 支持 class 、style 样式属性
40
286
  */
41
- clear?: boolean;
287
+ end?: CSS;
42
288
  };
43
289
 
44
290
  /**
@@ -56,6 +302,11 @@ type TransitionEffectOptions = {
56
302
  */
57
303
  declare function useAnimation(): IAnimationManager & IScope;
58
304
 
305
+ /**
306
+ * 全局的【CSS管理器】
307
+ */
308
+ declare const css: ICSSManager;
309
+
59
310
  /**
60
311
  * 接口:link标签管理器
61
312
  */
@@ -216,225 +467,5 @@ type ElementSize = {
216
467
  */
217
468
  declare function useObserver(): IObserver & IScope;
218
469
 
219
- /**
220
- * css样式数据结构
221
- * 1、高度、宽度、边框、内外边距样式
222
- * 2、文本、布局对齐方式
223
- */
224
- /**
225
- * 样式管理器
226
- */
227
- interface IStyleManager {
228
- /**
229
- * 构建样式
230
- * @param options 样式配置
231
- * @param isFlex 是否是flex布局
232
- * @returns 计算出来的组件样式信息
233
- */
234
- build(options: AllStyle | undefined, isFlex?: boolean): Partial<CSSStyleDeclaration>;
235
- /**
236
- * 获取元素样式
237
- * - 仅限style属性中获取
238
- * @param target 目标元素
239
- * @param keys 需要获取样式信息
240
- * @returns 样式信息
241
- */
242
- getStyle(target: HTMLElement, ...keys: Extract<keyof CSSStyleDeclaration, string>[]): Record<string, string>;
243
- /**
244
- * 为元素设置样式
245
- * @param target 目标元素
246
- * @param options 样式配置
247
- */
248
- setStyle(target: HTMLElement, options: AllStyle): void;
249
- }
250
- /**
251
- * 所有的样式属性
252
- * - 尺寸、对齐、边框、内边距等合集
253
- * - 对齐方式、、、
254
- */
255
- type AllStyle = AlignStyle & SizeStyle & MarginStyle & BorderStyle & PaddingStyle & TransitionStyle;
256
- /**
257
- * 组件对齐样式
258
- * - flex布局时约束 align-items和 justify-content
259
- * - 非flex布局时约束 text-align和 vertical-align
260
- */
261
- type AlignStyle = {
262
- /**
263
- * 对齐方式
264
- * - left: 左对齐
265
- * - center: 居中对齐
266
- * - right: 右对齐
267
- */
268
- align?: "left" | "center" | "right";
269
- /**
270
- * 垂直对齐方式
271
- * - top: 顶部对齐
272
- * - middle: 居中对齐
273
- * - bottom: 底部对齐
274
- */
275
- valign?: "top" | "middle" | "bottom";
276
- };
277
- /**
278
- * 尺寸配置选项
279
- */
280
- type SizeOptions = {
281
- /**
282
- * 弹性尺寸
283
- * - 在flex布局时生效
284
- * - 存在时,size属性无效
285
- */
286
- flex?: number;
287
- /**
288
- * 固定尺寸大小
289
- * -对应 width 或者 height 属性
290
- */
291
- size?: string;
292
- /**
293
- * 最小值
294
- * - 对应 min-width 或者 min-height 属性
295
- * - size 属性未指定、或者无效时生效;
296
- */
297
- min?: string;
298
- /**
299
- * 最大值
300
- * - 对应 max-width 或者 max-height 属性
301
- * - size 属性未指定、或者无效时生效;
302
- */
303
- max?: string;
304
- };
305
- /**
306
- * 尺寸样式:宽度+高度
307
- */
308
- type SizeStyle = {
309
- /**
310
- * 宽度样式
311
- */
312
- width?: SizeOptions;
313
- /**
314
- * 高度样式
315
- */
316
- height?: SizeOptions;
317
- };
318
- /**
319
- * 组件外边距样式
320
- * - margin < marginXXX
321
- */
322
- type MarginStyle = {
323
- /**
324
- * 外边距样式
325
- */
326
- margin?: string;
327
- /**
328
- * 上外边距样式
329
- */
330
- marginTop?: string;
331
- /**
332
- * 右外边距样式
333
- */
334
- marginRight?: string;
335
- /**
336
- * 下外边距样式
337
- */
338
- marginBottom?: string;
339
- /**
340
- * 左外边距样式
341
- */
342
- marginLeft?: string;
343
- };
344
- /**
345
- * 组件边框样式
346
- * - border < borderXXX
347
- */
348
- type BorderStyle = {
349
- /**
350
- * 边框圆角
351
- */
352
- borderRadius?: string;
353
- /**
354
- * 边框样式
355
- */
356
- border?: string;
357
- /**
358
- * 上边框样式
359
- */
360
- borderTop?: string;
361
- /**
362
- * 右边框样式
363
- */
364
- borderRight?: string;
365
- /**
366
- * 下边框样式
367
- */
368
- borderBottom?: string;
369
- /**
370
- * 左边框样式
371
- */
372
- borderLeft?: string;
373
- };
374
- /**
375
- * 内边距样式
376
- * - 优先级:padding < paddingXXX
377
- */
378
- type PaddingStyle = {
379
- /**
380
- * 内边距
381
- */
382
- padding?: string;
383
- /**
384
- * 上内边距
385
- */
386
- paddingTop?: string;
387
- /**
388
- * 右内边距
389
- */
390
- paddingRight?: string;
391
- /**
392
- * 下内边距
393
- */
394
- paddingBottom?: string;
395
- /**
396
- * 左内边距
397
- */
398
- paddingLeft?: string;
399
- };
400
- /**
401
- * 过渡效果 样式
402
- */
403
- type TransitionStyle = {
404
- /**
405
- * 过渡效果
406
- */
407
- transition?: string;
408
- /**
409
- * 过渡效果属性
410
- * - 如height、width、left、、、
411
- */
412
- transitionProperty?: string;
413
- /**
414
- * 过渡效果持续时间
415
- */
416
- transitionDuration?: string;
417
- /**
418
- * 过渡效果延迟时间
419
- */
420
- transitionDelay?: string;
421
- /**
422
- * 过渡效果函数
423
- * - 暂时固定效果,后期支持自定义
424
- */
425
- transitionTimingFunction?: ("ease" | "ease-in" | "ease-out" | "ease-in-out" | "linear" | "step-start" | "step-end");
426
- };
427
-
428
- /**
429
- * 样式管理模块
430
- * 1、基于配置构建css样式数据
431
- * 2、【后续支持】构建style标签,并生成css样式插入到页面
432
- */
433
-
434
- /**
435
- * 全局的【样式管理器】
436
- */
437
- declare const style: IStyleManager;
438
-
439
- export { configLink, link, linkMap, style, useAnimation, useLink, useObserver };
440
- export type { AlignStyle, AllStyle, BorderStyle, ElementSize, IAnimationManager, ILinkManager, IObserver, IStyleManager, LinkElement, LinkFile, LinkOptions, MarginStyle, PaddingStyle, SizeOptions, SizeStyle, TransitionEffectOptions, TransitionStyle };
470
+ export { configLink, css, link, linkMap, useAnimation, useLink, useObserver };
471
+ export type { ElementSize, IAnimationManager, ILinkManager, IObserver, LinkElement, LinkFile, LinkOptions, TransitionEffectOptions };
@@ -1,5 +1,11 @@
1
1
  //@ sourceURL=/snail.view.js
2
- import { throwIfFalse, checkScope, throwIfNullOrUndefined, throwIfTrue, useScope, useScopes, mountScope, extract, hasOwnProperty, tidyString, event, mustString, isArrayNotEmpty, isStringNotEmpty, version, run, mustFunction } from 'snail.core';
2
+ import { checkScope, throwIfFalse, useKeyScope, isArrayNotEmpty, isStringNotEmpty, isObject, useScopes, mountScope, extract, hasOwnProperty, tidyString, event, mustString, version, useScope, run, mustFunction } from 'snail.core';
3
+
4
+ function getAnimationScope(manager, el) {
5
+ checkScope(manager, "getAnimationScope: manager destroyed.");
6
+ throwIfFalse(el instanceof HTMLElement, "getAnimationScope: el must be an HTMLElement.");
7
+ return useKeyScope(el, false).scope;
8
+ }
3
9
 
4
10
  function buildAlign(style, align, isFlex) {
5
11
  if (isFlex == true) {
@@ -20,19 +26,26 @@ function buildAlign(style, align, isFlex) {
20
26
  align.valign && (style.verticalAlign = align.valign);
21
27
  }
22
28
  }
23
- function buildSize(style, size, styleName, isFlex) {
24
- if (size) {
25
- var fixed = size.size;
26
- if (isFlex && size.flex != void 0) {
27
- fixed = void 0;
28
- style.flex = String(size.flex);
29
- }
30
- if (fixed != void 0) {
31
- style[styleName] = fixed;
32
- } else {
33
- size.min != void 0 && (style[`min-${styleName}`] = size.min);
34
- size.max != void 0 && (style[`max-${styleName}`] = size.max);
35
- }
29
+ function buildFlex(style, flex) {
30
+ if (flex) {
31
+ flex.flex && (style.flex = flex.flex);
32
+ flex.flexBasis && (style.flexBasis = flex.flexBasis);
33
+ flex.flexGrow && (style.flexGrow = String(flex.flexGrow));
34
+ flex.flexShrink && (style.flexShrink = String(flex.flexShrink));
35
+ }
36
+ }
37
+ function buildWidth(style, width) {
38
+ if (width) {
39
+ width.width && (style.width = width.width);
40
+ width.minWidth && (style.minWidth = width.minWidth);
41
+ width.maxWidth && (style.maxWidth = width.maxWidth);
42
+ }
43
+ }
44
+ function buildHeight(style, height) {
45
+ if (height) {
46
+ height.height && (style.height = height.height);
47
+ height.minHeight && (style.minHeight = height.minHeight);
48
+ height.maxHeight && (style.maxHeight = height.maxHeight);
36
49
  }
37
50
  }
38
51
  function buildMargin(style, margin) {
@@ -73,80 +86,73 @@ function buildTransition(style, transition) {
73
86
  }
74
87
  }
75
88
 
76
- function useStyle() {
77
- function build(options, isFlex) {
78
- const style2 = Object.create(null);
79
- if (options) {
80
- buildAlign(style2, options, isFlex);
81
- buildSize(style2, options.width, "width", isFlex);
82
- buildSize(style2, options.height, "height", isFlex);
83
- buildMargin(style2, options);
84
- buildBorder(style2, options);
85
- buildPadding(style2, options);
86
- buildTransition(style2, options);
89
+ function useCSS() {
90
+ function parse(css2) {
91
+ if (isStringNotEmpty(css2) == true) {
92
+ return {
93
+ class: [css2]
94
+ };
87
95
  }
88
- return style2;
89
- }
90
- function getStyle(target) {
91
- throwIfFalse(target instanceof HTMLElement, "getStyle: target must be an HTMLElement.");
92
- const ret = Object.create(null);
93
- for (var _len = arguments.length, keys = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
94
- keys[_key - 1] = arguments[_key];
96
+ if (isArrayNotEmpty(css2) == true) {
97
+ const strs = css2.filter(name => isStringNotEmpty(name));
98
+ return strs.length > 0 ? {
99
+ class: strs
100
+ } : {};
95
101
  }
96
- keys.forEach(key => ret[key] = target.style[key]);
97
- return Object.freeze(ret);
102
+ if (css2 instanceof CSSStyleDeclaration || isObject(css2) == true) {
103
+ return {
104
+ style: Object.assign(Object.create(null), css2)
105
+ };
106
+ }
107
+ return Object.create(null);
98
108
  }
99
- function setStyle(target, options) {
100
- throwIfFalse(target instanceof HTMLElement, "setStyle: target must be an HTMLElement.");
101
- const style2 = build(options);
102
- Object.assign(target.style, style2);
109
+ function operate(el, type, css2) {
110
+ css2 && isArrayNotEmpty(css2.class) && css2.class.forEach(name => type == "add" ? el.classList.add(name) : el.classList.remove(name));
111
+ css2 && css2.style && Object.keys(css2.style).forEach(key => type == "add" ? el.style.setProperty(key, css2.style[key]) : el.style.removeProperty(key));
112
+ }
113
+ function buildStyle(options, isFlex) {
114
+ const style = Object.create(null);
115
+ if (options) {
116
+ buildAlign(style, options, isFlex);
117
+ isFlex && buildFlex(style, options);
118
+ buildWidth(style, options);
119
+ buildHeight(style, options);
120
+ buildMargin(style, options);
121
+ buildBorder(style, options);
122
+ buildPadding(style, options);
123
+ buildTransition(style, options);
124
+ }
125
+ return style;
103
126
  }
104
127
  return Object.freeze({
105
- build,
106
- getStyle,
107
- setStyle
108
- });
109
- }
110
- const style = useStyle();
111
-
112
- const ERROR_SAMEVALUE = "value cannot be the same";
113
- function checkTransition(scope, target, options) {
114
- checkScope(scope, "checkTransition: scope destroyed.");
115
- throwIfFalse(target instanceof HTMLElement, "checkTransition: target must be an HTMLElement.");
116
- throwIfNullOrUndefined(options, "checkTransition: options must be an Object.");
117
- throwIfTrue(options.start == options.target, `checkTransition: options.start and end ${ERROR_SAMEVALUE}. value: ${options.start}`);
118
- options.time = options.time > 0 ? options.time : 200;
119
- options.start = options.start || "";
120
- options.target = options.target || "";
121
- }
122
- function startTransition(target, init, styleName, options) {
123
- const backStyle = style.getStyle(target, ...Object.keys(init), styleName);
124
- const scope = useScope();
125
- const setTarget = () => target.style[styleName] = options.target;
126
- Object.assign(target.style, init, {
127
- [styleName]: options.start
128
- });
129
- setTimeout(setTarget, 1);
130
- setTimeout(scope.destroy, options.time);
131
- return scope.onDestroy(() => {
132
- Object.assign(target.style, backStyle);
133
- options.clear != true && setTarget();
128
+ parse,
129
+ operate,
130
+ buildStyle
134
131
  });
135
132
  }
133
+ const css = useCSS();
136
134
 
137
135
  function useAnimation() {
138
136
  const scopes = useScopes();
139
- function roll(target, direction, options) {
140
- checkTransition(manager, target, options);
141
- const styleName = direction === "horizontal" ? "width" : "height";
142
- const scope = startTransition(target, {
143
- overflow: "hidden !important",
144
- transition: `${styleName} ${options.time || 200}ms ease !important`
145
- }, styleName, options);
146
- return scopes.add(scope);
137
+ function transition(el, effect, time) {
138
+ throwIfFalse(isObject(effect), "transition: effect must be an object.");
139
+ const scope = scopes.add(getAnimationScope(manager, el));
140
+ const fromCss = css.parse(effect.from);
141
+ const toCss = css.parse(effect.to);
142
+ const endCss = css.parse(effect.end);
143
+ css.operate(el, "clear", toCss);
144
+ css.operate(el, "clear", endCss);
145
+ css.operate(el, "add", fromCss);
146
+ setTimeout(css.operate, 1, el, "add", toCss);
147
+ setTimeout(scope.destroy, time > 0 ? time : 200);
148
+ return scope.onDestroy(function () {
149
+ css.operate(el, "clear", fromCss);
150
+ css.operate(el, "clear", toCss);
151
+ css.operate(el, "add", endCss);
152
+ });
147
153
  }
148
154
  const manager = mountScope({
149
- roll
155
+ transition
150
156
  });
151
157
  manager.onDestroy(scopes.destroy);
152
158
  return Object.freeze(manager);
@@ -340,4 +346,4 @@ function useObserver() {
340
346
  return Object.freeze(manager);
341
347
  }
342
348
 
343
- export { configLink, link, linkMap, style, useAnimation, useLink, useObserver };
349
+ export { configLink, css, link, linkMap, useAnimation, useLink, useObserver };
@@ -5,6 +5,12 @@
5
5
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SnailView = global.SnailView || {}, global.Snail));
6
6
  })(this, (function (exports, snail_core) { 'use strict';
7
7
 
8
+ function getAnimationScope(manager, el) {
9
+ snail_core.checkScope(manager, "getAnimationScope: manager destroyed.");
10
+ snail_core.throwIfFalse(el instanceof HTMLElement, "getAnimationScope: el must be an HTMLElement.");
11
+ return snail_core.useKeyScope(el, false).scope;
12
+ }
13
+
8
14
  function buildAlign(style, align, isFlex) {
9
15
  if (isFlex == true) {
10
16
  const map = {
@@ -24,19 +30,26 @@
24
30
  align.valign && (style.verticalAlign = align.valign);
25
31
  }
26
32
  }
27
- function buildSize(style, size, styleName, isFlex) {
28
- if (size) {
29
- var fixed = size.size;
30
- if (isFlex && size.flex != void 0) {
31
- fixed = void 0;
32
- style.flex = String(size.flex);
33
- }
34
- if (fixed != void 0) {
35
- style[styleName] = fixed;
36
- } else {
37
- size.min != void 0 && (style[`min-${styleName}`] = size.min);
38
- size.max != void 0 && (style[`max-${styleName}`] = size.max);
39
- }
33
+ function buildFlex(style, flex) {
34
+ if (flex) {
35
+ flex.flex && (style.flex = flex.flex);
36
+ flex.flexBasis && (style.flexBasis = flex.flexBasis);
37
+ flex.flexGrow && (style.flexGrow = String(flex.flexGrow));
38
+ flex.flexShrink && (style.flexShrink = String(flex.flexShrink));
39
+ }
40
+ }
41
+ function buildWidth(style, width) {
42
+ if (width) {
43
+ width.width && (style.width = width.width);
44
+ width.minWidth && (style.minWidth = width.minWidth);
45
+ width.maxWidth && (style.maxWidth = width.maxWidth);
46
+ }
47
+ }
48
+ function buildHeight(style, height) {
49
+ if (height) {
50
+ height.height && (style.height = height.height);
51
+ height.minHeight && (style.minHeight = height.minHeight);
52
+ height.maxHeight && (style.maxHeight = height.maxHeight);
40
53
  }
41
54
  }
42
55
  function buildMargin(style, margin) {
@@ -77,80 +90,73 @@
77
90
  }
78
91
  }
79
92
 
80
- function useStyle() {
81
- function build(options, isFlex) {
82
- const style2 = Object.create(null);
83
- if (options) {
84
- buildAlign(style2, options, isFlex);
85
- buildSize(style2, options.width, "width", isFlex);
86
- buildSize(style2, options.height, "height", isFlex);
87
- buildMargin(style2, options);
88
- buildBorder(style2, options);
89
- buildPadding(style2, options);
90
- buildTransition(style2, options);
93
+ function useCSS() {
94
+ function parse(css2) {
95
+ if (snail_core.isStringNotEmpty(css2) == true) {
96
+ return {
97
+ class: [css2]
98
+ };
91
99
  }
92
- return style2;
93
- }
94
- function getStyle(target) {
95
- snail_core.throwIfFalse(target instanceof HTMLElement, "getStyle: target must be an HTMLElement.");
96
- const ret = Object.create(null);
97
- for (var _len = arguments.length, keys = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
98
- keys[_key - 1] = arguments[_key];
100
+ if (snail_core.isArrayNotEmpty(css2) == true) {
101
+ const strs = css2.filter(name => snail_core.isStringNotEmpty(name));
102
+ return strs.length > 0 ? {
103
+ class: strs
104
+ } : {};
99
105
  }
100
- keys.forEach(key => ret[key] = target.style[key]);
101
- return Object.freeze(ret);
106
+ if (css2 instanceof CSSStyleDeclaration || snail_core.isObject(css2) == true) {
107
+ return {
108
+ style: Object.assign(Object.create(null), css2)
109
+ };
110
+ }
111
+ return Object.create(null);
102
112
  }
103
- function setStyle(target, options) {
104
- snail_core.throwIfFalse(target instanceof HTMLElement, "setStyle: target must be an HTMLElement.");
105
- const style2 = build(options);
106
- Object.assign(target.style, style2);
113
+ function operate(el, type, css2) {
114
+ css2 && snail_core.isArrayNotEmpty(css2.class) && css2.class.forEach(name => type == "add" ? el.classList.add(name) : el.classList.remove(name));
115
+ css2 && css2.style && Object.keys(css2.style).forEach(key => type == "add" ? el.style.setProperty(key, css2.style[key]) : el.style.removeProperty(key));
116
+ }
117
+ function buildStyle(options, isFlex) {
118
+ const style = Object.create(null);
119
+ if (options) {
120
+ buildAlign(style, options, isFlex);
121
+ isFlex && buildFlex(style, options);
122
+ buildWidth(style, options);
123
+ buildHeight(style, options);
124
+ buildMargin(style, options);
125
+ buildBorder(style, options);
126
+ buildPadding(style, options);
127
+ buildTransition(style, options);
128
+ }
129
+ return style;
107
130
  }
108
131
  return Object.freeze({
109
- build,
110
- getStyle,
111
- setStyle
112
- });
113
- }
114
- const style = useStyle();
115
-
116
- const ERROR_SAMEVALUE = "value cannot be the same";
117
- function checkTransition(scope, target, options) {
118
- snail_core.checkScope(scope, "checkTransition: scope destroyed.");
119
- snail_core.throwIfFalse(target instanceof HTMLElement, "checkTransition: target must be an HTMLElement.");
120
- snail_core.throwIfNullOrUndefined(options, "checkTransition: options must be an Object.");
121
- snail_core.throwIfTrue(options.start == options.target, `checkTransition: options.start and end ${ERROR_SAMEVALUE}. value: ${options.start}`);
122
- options.time = options.time > 0 ? options.time : 200;
123
- options.start = options.start || "";
124
- options.target = options.target || "";
125
- }
126
- function startTransition(target, init, styleName, options) {
127
- const backStyle = style.getStyle(target, ...Object.keys(init), styleName);
128
- const scope = snail_core.useScope();
129
- const setTarget = () => target.style[styleName] = options.target;
130
- Object.assign(target.style, init, {
131
- [styleName]: options.start
132
- });
133
- setTimeout(setTarget, 1);
134
- setTimeout(scope.destroy, options.time);
135
- return scope.onDestroy(() => {
136
- Object.assign(target.style, backStyle);
137
- options.clear != true && setTarget();
132
+ parse,
133
+ operate,
134
+ buildStyle
138
135
  });
139
136
  }
137
+ const css = useCSS();
140
138
 
141
139
  function useAnimation() {
142
140
  const scopes = snail_core.useScopes();
143
- function roll(target, direction, options) {
144
- checkTransition(manager, target, options);
145
- const styleName = direction === "horizontal" ? "width" : "height";
146
- const scope = startTransition(target, {
147
- overflow: "hidden !important",
148
- transition: `${styleName} ${options.time || 200}ms ease !important`
149
- }, styleName, options);
150
- return scopes.add(scope);
141
+ function transition(el, effect, time) {
142
+ snail_core.throwIfFalse(snail_core.isObject(effect), "transition: effect must be an object.");
143
+ const scope = scopes.add(getAnimationScope(manager, el));
144
+ const fromCss = css.parse(effect.from);
145
+ const toCss = css.parse(effect.to);
146
+ const endCss = css.parse(effect.end);
147
+ css.operate(el, "clear", toCss);
148
+ css.operate(el, "clear", endCss);
149
+ css.operate(el, "add", fromCss);
150
+ setTimeout(css.operate, 1, el, "add", toCss);
151
+ setTimeout(scope.destroy, time > 0 ? time : 200);
152
+ return scope.onDestroy(function () {
153
+ css.operate(el, "clear", fromCss);
154
+ css.operate(el, "clear", toCss);
155
+ css.operate(el, "add", endCss);
156
+ });
151
157
  }
152
158
  const manager = snail_core.mountScope({
153
- roll
159
+ transition
154
160
  });
155
161
  manager.onDestroy(scopes.destroy);
156
162
  return Object.freeze(manager);
@@ -345,9 +351,9 @@
345
351
  }
346
352
 
347
353
  exports.configLink = configLink;
354
+ exports.css = css;
348
355
  exports.link = link;
349
356
  exports.linkMap = linkMap;
350
- exports.style = style;
351
357
  exports.useAnimation = useAnimation;
352
358
  exports.useLink = useLink;
353
359
  exports.useObserver = useObserver;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "对视图界面做的一些封装。如样式计算助手方法,常用样式less混入、变量等;dom相关助手类",
4
4
  "author": "snail_dev@163.com",
5
5
  "license": "MIT",
6
- "version": "1.0.3",
6
+ "version": "1.0.5",
7
7
  "type": "module",
8
8
  "main": "dist/snail.view.js",
9
9
  "module": "dist/snail.view.js",
@@ -14,7 +14,7 @@
14
14
  "types": "tsc -p ./tsconfig.dts.json --declarationDir ./dist/_types"
15
15
  },
16
16
  "dependencies": {
17
- "snail.core": ">=2.0.3"
17
+ "snail.core": ">=2.0.5"
18
18
  },
19
19
  "devDependencies": {
20
20
  "rollup": ">=4.39.0",