ph-utils 0.12.8 → 0.13.0

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/lib/dom.d.ts CHANGED
@@ -196,26 +196,33 @@ export declare function formatClass(classObj: (boolean | string | undefined | nu
196
196
  */
197
197
  export declare function formatStyle(styleObj: FormatStyleParam): string;
198
198
  /**
199
- * 对指定的 HTML 元素应用显示过渡效果。
200
- * @param target - 要应用过渡效果的 HTML 元素。
201
- * @param properties - 包含要改变的 CSS 属性及其目标值的数组。eg. [['opacity', '0.5']]
202
- * @param duration - 过渡效果的持续时间,如果不传, 则不会应用 transition-style, 可以自己在 css 中进行定义。
203
- * 该方法首先将元素的 display 属性设置为 "none",然后设置过渡属性,
204
- * 在下一个 DOM 更新周期后显示元素并移除设置的属性,从而实现过渡效果。
199
+ * 执行元素的过渡动画。
205
200
  *
206
- * ```
207
- * startTransition($msg, [
208
- ["opacity", "0"],
209
- ["transform", "translate3d(-50%, -100%, 0)"],
210
- ]);
211
- * ```
212
- */
213
- export declare function startTransition(target: HTMLElement, properties: [string, string][], duration?: string): void;
214
- /**
215
- * 结束元素的过渡效果,并在过渡结束后隐藏元素。
216
- * @param target - 要操作的 HTML 元素。
217
- * @param properties - 包含要设置的 CSS 属性和值的数组。
218
- * @param finish - 过渡结束后可选的回调函数。
201
+ * 如果是名称类似于 Vue.js 的过渡动画,通过添加 `*-active`、`*-from|to` class 类名。
202
+ *
203
+ * @param el - 需要执行过渡动画的 HTML 元素。
204
+ * @param nameOrProperties - 过渡动画的名称或属性数组。可以是字符串表示的动画名称,或者是包含属性名称、初始值或目标值、持续时间。eg. [['opacity', '0.5']] | 'nt-opacity'
205
+ * @param dir - 过渡动画的方向,"leave" 表示离开,"enter" 表示进入。默认值为 "enter"。
206
+ * @param finish - 过渡动画结束时的回调函数。
207
+ *
208
+ * @example <caption>执行 `nt-opacity` 名称动画</caption>
209
+ * // css
210
+ * .nt-opacity-enter-active,
211
+ * .nt-opacity-leave-active {
212
+ * transition: opacity 0.3s ease;
213
+ * }
214
+ * .nt-opacity-enter-from,
215
+ * .nt-opacity-leave-to {
216
+ * opacity: 0;
217
+ * }
218
+ * // js
219
+ * transition($el, "nt-opacity", "enter");
220
+ *
221
+ * @example <caption>执行 `style` 属性动画</caption>
222
+ * transition($el, [["opacity", "0", "0.3s"]], "enter");
223
+ *
224
+ * @example <caption>动画结束后移除节点</caption>
225
+ * transition($el, [["opacity", "0", "0.3s"]], "leave", () => { $el.remove(); });
219
226
  */
220
- export declare function endTransition(target: HTMLElement, properties: [string, string][], finish?: () => void): void;
227
+ export declare function transition(el: HTMLElement, nameOrProperties: string | [string, string, string][], dir?: "leave" | "enter", finish?: () => void): void;
221
228
  export {};
package/lib/dom.js CHANGED
@@ -396,58 +396,115 @@ export function formatStyle(styleObj) {
396
396
  }
397
397
  return styleStr;
398
398
  }
399
+ function toggleCssProperty(el, properties, method = "set") {
400
+ for (let i = 0, len = properties.length; i < len; i++) {
401
+ const rec = properties[i];
402
+ if (method === "set") {
403
+ el.style.setProperty(rec[0], rec[1]);
404
+ }
405
+ else {
406
+ el.style.removeProperty(rec[0]);
407
+ }
408
+ }
409
+ }
399
410
  /**
400
- * 对指定的 HTML 元素应用显示过渡效果。
401
- * @param target - 要应用过渡效果的 HTML 元素。
402
- * @param properties - 包含要改变的 CSS 属性及其目标值的数组。eg. [['opacity', '0.5']]
403
- * @param duration - 过渡效果的持续时间,如果不传, 则不会应用 transition-style, 可以自己在 css 中进行定义。
404
- * 该方法首先将元素的 display 属性设置为 "none",然后设置过渡属性,
405
- * 在下一个 DOM 更新周期后显示元素并移除设置的属性,从而实现过渡效果。
411
+ * 执行元素的过渡动画。
412
+ *
413
+ * 如果是名称类似于 Vue.js 的过渡动画,通过添加 `*-active`、`*-from|to` class 类名。
414
+ *
415
+ * @param el - 需要执行过渡动画的 HTML 元素。
416
+ * @param nameOrProperties - 过渡动画的名称或属性数组。可以是字符串表示的动画名称,或者是包含属性名称、初始值或目标值、持续时间。eg. [['opacity', '0.5']] | 'nt-opacity'
417
+ * @param dir - 过渡动画的方向,"leave" 表示离开,"enter" 表示进入。默认值为 "enter"。
418
+ * @param finish - 过渡动画结束时的回调函数。
406
419
  *
407
- * ```
408
- * startTransition($msg, [
409
- ["opacity", "0"],
410
- ["transform", "translate3d(-50%, -100%, 0)"],
411
- ]);
412
- * ```
420
+ * @example <caption>执行 `nt-opacity` 名称动画</caption>
421
+ * // css
422
+ * .nt-opacity-enter-active,
423
+ * .nt-opacity-leave-active {
424
+ * transition: opacity 0.3s ease;
425
+ * }
426
+ * .nt-opacity-enter-from,
427
+ * .nt-opacity-leave-to {
428
+ * opacity: 0;
429
+ * }
430
+ * // js
431
+ * transition($el, "nt-opacity", "enter");
432
+ *
433
+ * @example <caption>执行 `style` 属性动画</caption>
434
+ * transition($el, [["opacity", "0", "0.3s"]], "enter");
435
+ *
436
+ * @example <caption>动画结束后移除节点</caption>
437
+ * transition($el, [["opacity", "0", "0.3s"]], "leave", () => { $el.remove(); });
413
438
  */
414
- export function startTransition(target, properties, duration) {
415
- target.style.setProperty("display", "none");
439
+ export function transition(el, nameOrProperties, dir = "enter", finish) {
440
+ const p = dir === "enter" ? "from" : "to";
441
+ let nameClass = "", activeClass = "";
416
442
  const trans = [];
417
- for (let i = 0, len = properties.length; i < len; i++) {
418
- const rec = properties[i];
419
- target.style.setProperty(rec[0], rec[1]);
420
- trans.push(`${rec[0]} ${duration}`);
443
+ if (typeof nameOrProperties === "string") {
444
+ nameClass = `${nameOrProperties}-${dir}-${p}`;
445
+ activeClass = `${nameOrProperties}-${dir}-active`;
421
446
  }
422
- if (duration) {
423
- target.style.setProperty("transition", trans.join(", "));
447
+ else {
448
+ for (let i = 0, len = nameOrProperties.length; i < len; i++) {
449
+ const rec = nameOrProperties[i];
450
+ if (rec.length >= 3) {
451
+ trans.push(`${rec[0]} ${rec[2]}`);
452
+ }
453
+ }
424
454
  }
425
- target.style.removeProperty("display");
426
- requestAnimationFrame(() => {
427
- for (let i = 0, len = properties.length; i < len; i++) {
428
- const rec = properties[i];
429
- target.style.removeProperty(rec[0]);
455
+ if (dir === "enter") {
456
+ if (nameClass) {
457
+ el.classList.add(nameClass, activeClass);
430
458
  }
431
- });
432
- }
433
- /**
434
- * 结束元素的过渡效果,并在过渡结束后隐藏元素。
435
- * @param target - 要操作的 HTML 元素。
436
- * @param properties - 包含要设置的 CSS 属性和值的数组。
437
- * @param finish - 过渡结束后可选的回调函数。
438
- */
439
- export function endTransition(target, properties, finish) {
440
- for (let i = 0, len = properties.length; i < len; i++) {
441
- const rec = properties[i];
442
- target.style.setProperty(rec[0], rec[1]);
459
+ else {
460
+ toggleCssProperty(el, nameOrProperties, "set");
461
+ if (trans.length > 0) {
462
+ el.style.setProperty("transition", trans.join(", "));
463
+ }
464
+ }
465
+ requestAnimationFrame(() => {
466
+ if (nameClass) {
467
+ el.classList.remove(nameClass);
468
+ }
469
+ else {
470
+ toggleCssProperty(el, nameOrProperties, "remove");
471
+ }
472
+ });
443
473
  }
444
- target.addEventListener("transitionend", () => {
445
- target.style.display = "none";
446
- for (let i = 0, len = properties.length; i < len; i++) {
447
- const rec = properties[i];
448
- target.style.removeProperty(rec[0]);
474
+ else {
475
+ if (nameClass) {
476
+ el.classList.add(activeClass);
477
+ requestAnimationFrame(() => {
478
+ el.classList.add(nameClass);
479
+ });
480
+ }
481
+ else {
482
+ if (trans.length > 0) {
483
+ el.style.setProperty("transition", trans.join(", "));
484
+ }
485
+ requestAnimationFrame(() => {
486
+ toggleCssProperty(el, nameOrProperties, "set");
487
+ });
488
+ }
489
+ }
490
+ el.addEventListener("transitionend", () => {
491
+ if (nameClass) {
492
+ el.classList.remove(activeClass);
493
+ requestAnimationFrame(() => {
494
+ el.classList.remove(nameClass);
495
+ });
496
+ }
497
+ else {
498
+ if (trans) {
499
+ el.style.removeProperty("transition");
500
+ }
501
+ requestAnimationFrame(() => {
502
+ requestAnimationFrame(() => {
503
+ toggleCssProperty(el, nameOrProperties, "remove");
504
+ });
505
+ });
449
506
  }
450
- if (finish != null) {
507
+ if (finish) {
451
508
  finish();
452
509
  }
453
510
  }, { once: true });
package/lib/theme.d.ts CHANGED
@@ -18,9 +18,10 @@ export declare function getTheme(): string;
18
18
  * 应用主题
19
19
  * @param theme 待应用的主题
20
20
  * @param cache 是否缓存应用的主题, 让应用下一次启动的时候, 可以应用主题, 默认: true
21
+ * @param transition 是否使用过渡动画, 注意浏览器必须支持 document.startViewTransition, 默认: true
21
22
  * @returns 应用的主题
22
23
  */
23
- export declare function applyTheme(theme?: "light" | "dark" | "auto", cache?: boolean): Promise<unknown>;
24
+ export declare function applyTheme(theme?: "light" | "dark" | "auto", cache?: boolean, transition?: boolean): Promise<unknown>;
24
25
  /** 获取当前主题色 */
25
26
  export declare function getColorTheme(defaultValue?: string): string | undefined;
26
27
  /**
package/lib/theme.js CHANGED
@@ -88,13 +88,14 @@ export function getTheme() {
88
88
  * 应用主题
89
89
  * @param theme 待应用的主题
90
90
  * @param cache 是否缓存应用的主题, 让应用下一次启动的时候, 可以应用主题, 默认: true
91
+ * @param transition 是否使用过渡动画, 注意浏览器必须支持 document.startViewTransition, 默认: true
91
92
  * @returns 应用的主题
92
93
  */
93
- export async function applyTheme(theme, cache = true) {
94
+ export async function applyTheme(theme, cache = true, transition = true) {
94
95
  if (cache === true) {
95
96
  localStorage.setItem("web-theme-appearance", theme == null ? "auto" : theme);
96
97
  }
97
- return toggleTheme(theme);
98
+ return toggleTheme(theme, transition);
98
99
  }
99
100
  /** 获取当前主题色 */
100
101
  export function getColorTheme(defaultValue) {
package/package.json CHANGED
@@ -68,7 +68,7 @@
68
68
  },
69
69
  "./*": "./lib/*"
70
70
  },
71
- "version": "0.12.8",
71
+ "version": "0.13.0",
72
72
  "type": "module",
73
73
  "repository": {
74
74
  "type": "git",