@leavepulse/ui 0.95.0 → 0.95.2

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,7 +1,10 @@
1
1
  import { ref, onScopeDispose, readonly } from "vue";
2
+ import { prefersReducedMotion } from "./easing.js";
2
3
  const OVERLAY = '[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [data-state="open"][data-side]';
3
4
  const INPUT_EVENTS = ["pointerdown", "keydown", "wheel", "touchstart", "input"];
4
5
  const CARRY_MS = 6e4;
6
+ const FADE_OUT_MS = 220;
7
+ const FADE_IN_MS = 320;
5
8
  function editableFocused() {
6
9
  const el = document.activeElement;
7
10
  if (!(el instanceof HTMLElement)) return false;
@@ -34,6 +37,9 @@ function useAppUpdate(options) {
34
37
  const carried = readCarried(key);
35
38
  if (carried && carried.href === location.href && Date.now() - carried.at < CARRY_MS) {
36
39
  restored.value = true;
40
+ if (!prefersReducedMotion()) {
41
+ document.documentElement.animate([{ opacity: 0 }, { opacity: 1 }], { duration: FADE_IN_MS, easing: "cubic-bezier(0.2, 0, 0, 1)" });
42
+ }
37
43
  const top = carried.top;
38
44
  const restore = () => window.scrollTo({ top, behavior: "instant" });
39
45
  requestAnimationFrame(() => requestAnimationFrame(restore));
@@ -44,7 +50,12 @@ function useAppUpdate(options) {
44
50
  sessionStorage.setItem(key, JSON.stringify({ href: location.href, top: window.scrollY, at: Date.now() }));
45
51
  } catch {
46
52
  }
47
- location.reload();
53
+ if (document.hidden || prefersReducedMotion()) {
54
+ location.reload();
55
+ return;
56
+ }
57
+ const fade = document.documentElement.animate([{ opacity: 1 }, { opacity: 0 }], { duration: FADE_OUT_MS, easing: "ease-in", fill: "forwards" });
58
+ fade.finished.then(() => location.reload(), () => location.reload());
48
59
  }
49
60
  function safe() {
50
61
  if (document.hidden) return true;
package/dist/index.d.ts CHANGED
@@ -196,6 +196,8 @@ export type { SortState, TableColumn, TableListMode, TablePage, TableQuery } fro
196
196
  export type { TableLabels } from "./components/LpTable.vue";
197
197
  export type { TableCellEdit, TableExportOptions, TableSelectionToken } from "./components/LpTable.vue";
198
198
  export type { ColumnPin, ColumnPreset, TableLayout } from "./components/tableFeatures";
199
+ export { rowWindow } from "./components/tableFeatures";
200
+ export type { RowWindow } from "./components/tableFeatures";
199
201
  export { compareValues } from "./components/tableSort";
200
202
  export { filterRows, showOnly, shownValues } from "./components/tableFilter";
201
203
  export type { TableFilters } from "./components/tableFilter";
package/dist/index.js CHANGED
@@ -112,6 +112,7 @@ import { _ as _76 } from "./chunks/LpStat-SyVb5JXm.js";
112
112
  import { _ as _77 } from "./chunks/LpStepper-DBNRA6Q2.js";
113
113
  import { _ as _78 } from "./chunks/LpSwitch-D-mcaA6C.js";
114
114
  import { default as default13 } from "./components/LpTable.vue.js";
115
+ import { rowWindow } from "./components/tableFeatures.js";
115
116
  import { compareValues } from "./components/tableSort.js";
116
117
  import { filterRows, showOnly, shownValues } from "./components/tableFilter.js";
117
118
  import { useTableFilterChoice } from "./composables/useTableFilterChoice.js";
@@ -1245,6 +1246,7 @@ export {
1245
1246
  rgbToHsv,
1246
1247
  ringWindow,
1247
1248
  rose,
1249
+ rowWindow,
1248
1250
  rubberBand,
1249
1251
  rubberClamp,
1250
1252
  runningHintSystem,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.95.0",
3
+ "version": "0.95.2",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -1,4 +1,5 @@
1
1
  import { onScopeDispose, readonly, ref, type Ref } from "vue"
2
+ import { prefersReducedMotion } from "./easing"
2
3
 
3
4
  /*
4
5
  * A new build is out and every open tab should run it, without anyone losing
@@ -20,6 +21,10 @@ import { onScopeDispose, readonly, ref, type Ref } from "vue"
20
21
  * window scroll position, and anything the app already keeps in storage, such
21
22
  * as form drafts. After the reload `restored` is true for the app to say
22
23
  * "updated" if it wants to.
24
+ *
25
+ * A visible reload does not blink: the page fades out before it and fades back
26
+ * in after it, so the swap reads as one change rather than a flash of blank.
27
+ * Under reduced motion, and in a hidden tab, it simply reloads.
23
28
  */
24
29
 
25
30
  export interface AppUpdateOptions {
@@ -51,6 +56,8 @@ export interface AppUpdate {
51
56
  const OVERLAY = '[role="dialog"], [role="alertdialog"], [role="menu"], [role="listbox"], [data-state="open"][data-side]'
52
57
  const INPUT_EVENTS = ["pointerdown", "keydown", "wheel", "touchstart", "input"] as const
53
58
  const CARRY_MS = 60_000
59
+ const FADE_OUT_MS = 220
60
+ const FADE_IN_MS = 320
54
61
 
55
62
  interface Carried {
56
63
  href: string
@@ -94,6 +101,9 @@ export function useAppUpdate(options: AppUpdateOptions): AppUpdate {
94
101
  const carried = readCarried(key)
95
102
  if (carried && carried.href === location.href && Date.now() - carried.at < CARRY_MS) {
96
103
  restored.value = true
104
+ if (!prefersReducedMotion()) {
105
+ document.documentElement.animate([{ opacity: 0 }, { opacity: 1 }], { duration: FADE_IN_MS, easing: "cubic-bezier(0.2, 0, 0, 1)" })
106
+ }
97
107
  const top = carried.top
98
108
  const restore = () => window.scrollTo({ top, behavior: "instant" })
99
109
  requestAnimationFrame(() => requestAnimationFrame(restore))
@@ -106,7 +116,12 @@ export function useAppUpdate(options: AppUpdateOptions): AppUpdate {
106
116
  } catch {
107
117
  // Storage off: the reload still happens, only the scroll is lost.
108
118
  }
109
- location.reload()
119
+ if (document.hidden || prefersReducedMotion()) {
120
+ location.reload()
121
+ return
122
+ }
123
+ const fade = document.documentElement.animate([{ opacity: 1 }, { opacity: 0 }], { duration: FADE_OUT_MS, easing: "ease-in", fill: "forwards" })
124
+ fade.finished.then(() => location.reload(), () => location.reload())
110
125
  }
111
126
 
112
127
  function safe(): boolean {
package/src/index.ts CHANGED
@@ -272,6 +272,8 @@ export type { SortState, TableColumn, TableListMode, TablePage, TableQuery } fro
272
272
  export type { TableLabels } from "./components/LpTable.vue"
273
273
  export type { TableCellEdit, TableExportOptions, TableSelectionToken } from "./components/LpTable.vue"
274
274
  export type { ColumnPin, ColumnPreset, TableLayout } from "./components/tableFeatures"
275
+ export { rowWindow } from "./components/tableFeatures"
276
+ export type { RowWindow } from "./components/tableFeatures"
275
277
  export { compareValues } from "./components/tableSort"
276
278
  export { filterRows, showOnly, shownValues } from "./components/tableFilter"
277
279
  export type { TableFilters } from "./components/tableFilter"