@eintrek/erp-shell 0.1.63 → 0.1.65
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/dist/guide/dom.d.ts +81 -1
- package/dist/guide/guide-styles.d.ts +1 -1
- package/dist/guide/guide-ui.d.ts +47 -6
- package/dist/guide/machine.d.ts +15 -3
- package/dist/guide/progress.d.ts +7 -0
- package/dist/guide/types.d.ts +35 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +598 -92
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +597 -91
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +5 -5
package/dist/guide/dom.d.ts
CHANGED
|
@@ -29,9 +29,89 @@ export declare function sameRect(a: Rect | null, b: Rect | null): boolean;
|
|
|
29
29
|
export declare const POPPER_SELECTOR = "[data-radix-popper-content-wrapper]";
|
|
30
30
|
/** Toasts stay usable above the tour. */
|
|
31
31
|
export declare const TOASTER_SELECTOR = "[data-sonner-toaster]";
|
|
32
|
+
/** Open dialogs (Radix dialog, alert dialog, sheet, popover content). */
|
|
33
|
+
export declare const OPEN_DIALOG_SELECTOR = "[role=\"dialog\"][data-state=\"open\"],[role=\"alertdialog\"][data-state=\"open\"]";
|
|
34
|
+
/**
|
|
35
|
+
* Whether an open dialog of the app's covers the target: the target is
|
|
36
|
+
* neither in it nor around it (a confirm opened by the step's own button).
|
|
37
|
+
* The ring and the hand would be drawn over the dialog, pointing at a button
|
|
38
|
+
* behind it.
|
|
39
|
+
*/
|
|
40
|
+
export declare function coveredByDialog(el: Element | null): boolean;
|
|
32
41
|
export declare function openPoppers(): HTMLElement[];
|
|
33
42
|
export declare function inGuideLayer(node: EventTarget | null): boolean;
|
|
34
43
|
export declare function prefersReducedMotion(): boolean;
|
|
35
44
|
export declare function isPhoneWidth(): boolean;
|
|
36
|
-
/**
|
|
45
|
+
/** The overlap of two rectangles, or null when they do not meet. */
|
|
46
|
+
export declare function intersectRect(a: Rect, b: Rect): Rect | null;
|
|
47
|
+
/** The part of `rect` inside every clip (scroll boxes, the viewport); null when none is. */
|
|
48
|
+
export declare function visibleRect(rect: Rect, clips: Rect[]): Rect | null;
|
|
49
|
+
/**
|
|
50
|
+
* The ancestors that cut the element off: anything with overflow other than
|
|
51
|
+
* visible on an axis. The body and the root scroll the page and are covered by
|
|
52
|
+
* the viewport. Read once per target; their rectangles are read every frame.
|
|
53
|
+
*/
|
|
54
|
+
export declare function clipAncestors(el: Element): Array<{
|
|
55
|
+
el: Element;
|
|
56
|
+
x: boolean;
|
|
57
|
+
y: boolean;
|
|
58
|
+
}>;
|
|
59
|
+
/** An ancestor's clip as a rectangle: unbounded on an axis it does not clip. */
|
|
60
|
+
export declare function clipRectOf(c: {
|
|
61
|
+
el: Element;
|
|
62
|
+
x: boolean;
|
|
63
|
+
y: boolean;
|
|
64
|
+
}): Rect;
|
|
65
|
+
export declare function viewportRect(): Rect;
|
|
66
|
+
/**
|
|
67
|
+
* The part of the element a person can see: its box cut by every scroll box
|
|
68
|
+
* around it and by the viewport. The spotlight, its hole, the ring and the
|
|
69
|
+
* hand use this, so a tab half out of a sideways-scrolling row of tabs is not
|
|
70
|
+
* spotlit where it cannot be pressed. Null when none of it is on screen.
|
|
71
|
+
*/
|
|
72
|
+
export declare function visibleRectOf(el: Element, ancestors?: {
|
|
73
|
+
el: Element;
|
|
74
|
+
x: boolean;
|
|
75
|
+
y: boolean;
|
|
76
|
+
}[]): Rect | null;
|
|
77
|
+
/** Inside a box that scrolls sideways (with somewhere to scroll) that is itself on screen. */
|
|
78
|
+
export declare function inSidewaysScroller(el: Element): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* How to bring a target into view, or null when it already is: to the middle
|
|
81
|
+
* when it is above or below the comfortable band (under the header, at the
|
|
82
|
+
* bottom edge), the nearest edge when only a side is cut off (a tab out of a
|
|
83
|
+
* sideways-scrolling row, on a phone).
|
|
84
|
+
*/
|
|
85
|
+
export declare function revealPlan(rect: Rect, visible: Rect | null, viewportHeight: number): {
|
|
86
|
+
block: "center" | "nearest";
|
|
87
|
+
inline: "nearest";
|
|
88
|
+
} | null;
|
|
89
|
+
/** Room left beside a target scrolled into a sideways scroll box. */
|
|
90
|
+
export declare const SIDEWAYS_MARGIN = 12;
|
|
91
|
+
/**
|
|
92
|
+
* How far to scroll a sideways scroll box so the target sits inside its
|
|
93
|
+
* visible part (`box`: the box cut by the viewport) with `margin` to spare on
|
|
94
|
+
* both sides; 0 when it already does. Clamped to what the box can scroll.
|
|
95
|
+
* A target wider than the room is aligned to its start.
|
|
96
|
+
*/
|
|
97
|
+
export declare function sidewaysDelta(target: Rect, box: Rect, scrollLeft: number, maxScrollLeft: number, margin?: number): number;
|
|
98
|
+
/**
|
|
99
|
+
* Scrolls the target into view (instant under reduced motion). In a box that
|
|
100
|
+
* scrolls sideways (a row of tabs on a phone) the box is scrolled first,
|
|
101
|
+
* leaving SIDEWAYS_MARGIN beside the target so its whole label shows; then
|
|
102
|
+
* the page, up or down only.
|
|
103
|
+
*/
|
|
37
104
|
export declare function revealTarget(el: Element): void;
|
|
105
|
+
/**
|
|
106
|
+
* The scrim's blocking area: the screen (with a 10 px margin) minus the union
|
|
107
|
+
* of the holes, as rectangles that do not overlap. Cutting each hole out with
|
|
108
|
+
* an even-odd fill made the place where two holes overlap (a field and the
|
|
109
|
+
* select list open over it) solid again, and the option there could not be
|
|
110
|
+
* pressed.
|
|
111
|
+
*
|
|
112
|
+
* Every hole edge splits the screen into a grid; a cell is blocked when no
|
|
113
|
+
* hole covers it. Cells in a row are joined, and identical rows stacked.
|
|
114
|
+
*/
|
|
115
|
+
export declare function blockedRects(holes: Rect[], width: number, height: number): Rect[];
|
|
116
|
+
/** Whether a point is in any of the rectangles (edges excluded). */
|
|
117
|
+
export declare function inRects(rects: Rect[], x: number, y: number): boolean;
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* brings its own sheet, namespaced `eg-`, drawn from the theme's tokens
|
|
5
5
|
* (--primary carries each app's brand accent; light and dark follow).
|
|
6
6
|
*/
|
|
7
|
-
export declare const GUIDE_CSS = "\n[data-erp-guide-layer]{position:fixed;inset:0;z-index:1000;pointer-events:none;font-family:inherit;color:var(--popover-foreground,#1c2634);\n --eg-scrim:rgba(12,20,34,.64);--eg-card:var(--popover,#fff);--eg-fg:var(--popover-foreground,#1c2634);\n --eg-muted:var(--muted-foreground,#6d7886);--eg-soft:var(--muted,#eef3f9);--eg-line:var(--border,#e8ecf1);\n --eg-primary:var(--primary,#3280dd);--eg-on-primary:var(--primary-foreground,#fff);\n --eg-tint:color-mix(in oklab,var(--eg-primary) 13%,var(--eg-card));--eg-strong:color-mix(in oklab,var(--eg-primary) 82%,#000);\n --eg-danger:var(--destructive,#d23b4b);--eg-ok:#1d9a5f;--eg-gold:#e6a417;\n --eg-shadow:0 18px 50px -12px rgba(16,32,64,.35),0 4px 12px rgba(16,32,64,.08);line-height:1.5;font-size:14px}\n[data-erp-guide-layer] *{box-sizing:border-box}\n[data-erp-guide-layer] button{font:inherit;color:inherit;cursor:pointer}\n.eg-i{pointer-events:auto}\n.eg-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n.eg-scrim-svg{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}\n.eg-scrim-svg path{fill:var(--eg-scrim);pointer-events:visiblePainted;fill-rule:evenodd}\n.eg-scrim{position:fixed;inset:0;background:var(--eg-scrim);pointer-events:auto}\n.eg-scrim.eg-light{background:rgba(12,20,34,.45)}\n.eg-scrim.eg-faint{background:rgba(12,20,34,.35)}\n.eg-ring{position:fixed;border-radius:12px;pointer-events:none;box-shadow:0 0 0 3px #fff,0 0 0 6px var(--eg-primary)}\n.eg-ring.eg-move{transition:left .26s ease,top .26s ease,width .26s ease,height .26s ease}\n.eg-ring::after{content:\"\";position:absolute;inset:-6px;border-radius:15px;border:3px solid var(--eg-primary);animation:eg-pulse 1.6s ease-out infinite}\n.eg-ring.eg-flash::after{animation:eg-flash .5s ease 1}\n@keyframes eg-pulse{0%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(1.12)}}\n@keyframes eg-flash{0%,100%{opacity:1;transform:none}50%{opacity:.2}}\n.eg-hand{position:fixed;width:46px;height:46px;pointer-events:none;filter:drop-shadow(0 4px 6px rgba(0,0,0,.35));animation:eg-tap 1.1s ease-in-out infinite}\n.eg-hand svg{width:46px;height:46px;fill:#fff;stroke:#1c2634;stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round}\n.eg-hand.eg-flip svg{transform:scaleY(-1)}\n@keyframes eg-tap{0%,100%{transform:translate(6px,8px)}50%{transform:translate(0,0)}}\n.eg-bubble{position:fixed;left:0;top:0;width:320px;background:var(--eg-card);color:var(--eg-fg);border-radius:14px;box-shadow:var(--eg-shadow);padding:14px 16px 12px;border-top:4px solid var(--eg-primary);outline:none;pointer-events:auto}\n.eg-bubble.eg-err{border-top-color:var(--eg-danger)}\n.eg-bubble.eg-nudge{animation:eg-nudge .38s ease}\n@keyframes eg-nudge{0%,100%{translate:0}20%{translate:-7px}40%{translate:6px}60%{translate:-4px}80%{translate:2px}}\n.eg-b-top{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:12px;color:var(--eg-muted)}\n.eg-b-top .eg-mis{font-weight:600;color:var(--eg-strong);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.eg-b-top .eg-cnt{white-space:nowrap;font-weight:600}\n.eg-pips{display:flex;gap:4px;margin:8px 0 10px}\n.eg-pips i{flex:1;height:4px;border-radius:2px;background:var(--eg-soft)}\n.eg-pips i.eg-d{background:var(--eg-primary)}\n.eg-pips i.eg-c{background:color-mix(in oklab,var(--eg-primary) 45%,var(--eg-card))}\n.eg-b-t{margin:0;font-size:16px;font-weight:600;line-height:1.45}\n.eg-b-w{margin:2px 0 0;font-size:13.5px;color:var(--eg-muted)}\n.eg-bubble.eg-err .eg-b-t{color:var(--eg-danger)}\n.eg-k{display:inline-block;background:var(--eg-tint);color:var(--eg-strong);border-radius:7px;padding:0 7px;font-weight:600}\n.eg-b-f{display:flex;align-items:center;justify-content:space-between;margin-top:12px;gap:8px}\n.eg-b-f .eg-btn{height:34px;padding:0 14px;font-size:13.5px}\n.eg-exit{border:0;background:none;color:var(--eg-muted);font-size:12.5px;padding:4px 0;text-decoration:underline;text-underline-offset:3px}\n.eg-exit:hover{color:var(--eg-fg)}\n.eg-arrow{position:absolute;width:14px;height:14px;background:var(--eg-card);transform:rotate(45deg);border-radius:2px}\n.eg-arrow.eg-top{background:var(--eg-primary)}\n.eg-bubble.eg-err .eg-arrow.eg-top{background:var(--eg-danger)}\n.eg-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:40px;padding:0 16px;border-radius:10px;border:1px solid transparent;font-size:14px;font-weight:600;white-space:nowrap}\n.eg-btn:focus-visible,.eg-exit:focus-visible,.eg-chip:focus-visible,.eg-x:focus-visible{outline:2px solid var(--eg-primary);outline-offset:2px}\n.eg-primary{background:var(--eg-primary);color:var(--eg-on-primary)!important}\n.eg-primary:hover{background:var(--eg-strong)}\n.eg-primary[disabled]{opacity:.55;cursor:default}\n.eg-ghost{background:var(--eg-card);border-color:var(--eg-line)}\n.eg-ghost:hover{background:var(--eg-soft)}\n.eg-ghost[disabled]{opacity:.55;cursor:default}\n.eg-link{background:none;border:0;color:var(--eg-muted);font-weight:500;padding:0 6px;height:32px}\n.eg-link:hover{color:var(--eg-fg);text-decoration:underline}\n.eg-modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:min(440px,calc(100vw - 32px));max-height:calc(100vh - 32px);overflow:auto;background:var(--eg-card);color:var(--eg-fg);border-radius:20px;box-shadow:var(--eg-shadow);padding:28px 28px 22px;text-align:center;outline:none;pointer-events:auto}\n.eg-modal.eg-pop{animation:eg-pop .32s cubic-bezier(.2,.9,.3,1.3)}\n@keyframes eg-pop{from{opacity:0;transform:translate(-50%,-46%) scale(.94)}}\n.eg-modal h2{margin:6px 0 4px;font-size:22px;font-weight:700;letter-spacing:-.2px;line-height:1.3}\n.eg-modal .eg-sub{margin:0;color:var(--eg-muted);font-size:14.5px}\n.eg-eyebrow{margin:0;font-size:12.5px;font-weight:600;letter-spacing:.3px;color:var(--eg-strong)}\n.eg-actions{display:grid;gap:6px;margin-top:20px}\n.eg-actions .eg-btn{height:44px}\n.eg-badge{width:64px;height:64px;border-radius:18px;margin:0 auto 12px;display:grid;place-items:center;background:var(--eg-tint);color:var(--eg-strong)}\n.eg-badge svg.eg-ic{width:30px;height:30px}\n.eg-quests{list-style:none;padding:0;margin:18px 0 0;text-align:left;display:grid;gap:6px}\n.eg-quests li{display:flex;align-items:center;gap:12px;padding:9px 12px;border-radius:11px;background:var(--eg-soft);font-size:14px}\n.eg-quests li .eg-n{width:26px;height:26px;border-radius:50%;background:var(--eg-card);border:1.5px solid var(--eg-line);display:grid;place-items:center;font-size:12px;font-weight:700;color:var(--eg-muted);flex:none}\n.eg-quests li.eg-first{background:var(--eg-tint)}\n.eg-quests li.eg-first .eg-n{border-color:var(--eg-primary);color:var(--eg-strong)}\n.eg-quests li.eg-ok .eg-n{background:var(--eg-ok);border-color:var(--eg-ok);color:#fff}\n.eg-quests li .eg-n svg.eg-ic{width:15px;height:15px;stroke-width:3}\n.eg-quests li .eg-t{flex:1}\n.eg-quests li small{color:var(--eg-muted);font-size:12px;white-space:nowrap}\n.eg-modal.eg-confirm{text-align:left;width:min(380px,calc(100vw - 32px));padding:22px}\n.eg-modal.eg-confirm h2{font-size:18px;margin-top:0}\n.eg-modal.eg-confirm .eg-actions{grid-template-columns:1fr 1fr}\n.eg-medal{width:84px;height:84px;border-radius:50%;margin:4px auto 10px;display:grid;place-items:center;color:#fff;background:radial-gradient(circle at 35% 30%,#ffd666,var(--eg-gold));box-shadow:0 0 0 8px #fff4d6;animation:eg-stamp .5s cubic-bezier(.2,.9,.3,1.4) .1s both}\n.eg-medal svg.eg-ic{width:42px;height:42px;stroke-width:2.6}\n@keyframes eg-stamp{from{transform:scale(.3) rotate(-25deg);opacity:0}}\n.eg-prog{display:flex;align-items:center;gap:10px;margin-top:16px;font-size:13px;color:var(--eg-muted);font-weight:600}\n.eg-prog .eg-bar{flex:1;height:8px;border-radius:4px;background:var(--eg-soft);overflow:hidden}\n.eg-prog .eg-bar i{display:block;height:100%;background:var(--eg-primary);border-radius:4px;transition:width .9s cubic-bezier(.2,.8,.2,1) .35s}\n.eg-burst{position:absolute;left:50%;top:70px;width:0;height:0;pointer-events:none}\n.eg-burst span{position:absolute;width:8px;height:12px;border-radius:2px;opacity:0;animation:eg-conf 1.1s cubic-bezier(.15,.7,.3,1) forwards}\n@keyframes eg-conf{0%{opacity:1;transform:translate(0,0) rotate(0)}100%{opacity:0;transform:translate(var(--x),var(--y)) rotate(var(--r))}}\n.eg-card{position:fixed;left:50%;bottom:28px;transform:translateX(-50%);width:min(360px,calc(100vw - 32px));background:var(--eg-card);color:var(--eg-fg);border-radius:14px;box-shadow:var(--eg-shadow);padding:14px 16px;border-top:4px solid var(--eg-primary);pointer-events:auto;outline:none}\n.eg-card .eg-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px}\n.eg-loading{display:flex;align-items:center;gap:10px;font-weight:600}\n.eg-spin{width:18px;height:18px;border-radius:50%;border:2.5px solid var(--eg-soft);border-top-color:var(--eg-primary);animation:eg-spin .8s linear infinite;flex:none}\n@keyframes eg-spin{to{transform:rotate(360deg)}}\n.eg-chip{position:fixed;right:22px;bottom:22px;display:flex;align-items:center;gap:10px;height:48px;padding:0 18px 0 8px;border-radius:24px;border:1px solid var(--eg-line);background:var(--eg-card);color:var(--eg-fg);box-shadow:0 8px 24px -8px rgba(16,32,64,.3);font-weight:600;font-size:14px;pointer-events:auto}\n.eg-chip svg{width:34px;height:34px}\n.eg-chip.eg-hi{animation:eg-hi 1.2s ease 2}\n@keyframes eg-hi{50%{box-shadow:0 0 0 6px color-mix(in oklab,var(--eg-primary) 35%,transparent),0 8px 24px -8px rgba(16,32,64,.3)}}\n.eg-panel{position:fixed;right:22px;bottom:82px;width:360px;max-height:calc(100vh - 110px);overflow:auto;background:var(--eg-card);color:var(--eg-fg);border:1px solid var(--eg-line);border-radius:16px;box-shadow:var(--eg-shadow);outline:none;pointer-events:auto}\n.eg-panel-bd{display:none}\n.eg-q-h{display:flex;align-items:center;gap:10px;padding:16px 12px 4px 18px}\n.eg-q-h h2{margin:0;font-size:16px;font-weight:700;flex:1}\n.eg-q-h .eg-n{font-size:13px;color:var(--eg-muted);font-weight:600}\n.eg-x{width:34px;height:34px;border-radius:10px;border:0;background:none;display:grid;place-items:center;color:var(--eg-muted)}\n.eg-x:hover{background:var(--eg-soft)}\n.eg-x svg.eg-ic{width:18px;height:18px}\n.eg-panel .eg-prog{margin:6px 18px 8px}\n.eg-q-list{list-style:none;margin:0;padding:4px 10px 6px;display:grid;gap:2px}\n.eg-q-item{display:flex;align-items:center;gap:12px;padding:10px 8px;border-radius:11px}\n.eg-q-item.eg-next{background:var(--eg-tint)}\n.eg-q-item .eg-n{width:30px;height:30px;border-radius:50%;border:1.5px solid var(--eg-line);display:grid;place-items:center;font-size:12.5px;font-weight:700;color:var(--eg-muted);flex:none;background:var(--eg-card)}\n.eg-q-item.eg-next .eg-n{border-color:var(--eg-primary);color:var(--eg-strong)}\n.eg-q-item.eg-done .eg-n{background:var(--eg-ok);border-color:var(--eg-ok);color:#fff}\n.eg-q-item.eg-done .eg-n svg.eg-ic{width:16px;height:16px;stroke-width:3}\n.eg-q-item.eg-dim .eg-n{opacity:.55}\n.eg-q-item.eg-just .eg-n{animation:eg-stamp .55s cubic-bezier(.2,.9,.3,1.4) .2s both}\n.eg-q-item .eg-t{flex:1;min-width:0}\n.eg-q-item .eg-t b{display:block;font-size:14px;font-weight:600}\n.eg-q-item.eg-done .eg-t b{color:var(--eg-muted)}\n.eg-q-item .eg-t small{display:block;font-size:12px;color:var(--eg-muted)}\n.eg-q-item .eg-t small.eg-sk{color:#b06a00}\n.eg-q-item .eg-btn{height:32px;padding:0 12px;font-size:13px}\n.eg-q-acts{display:flex;flex-direction:column;align-items:flex-end;gap:2px}\n.eg-q-acts .eg-link{height:22px;font-size:12px;padding:0 2px}\n.eg-q-f{border-top:1px solid var(--eg-line);padding:8px 12px;display:flex;justify-content:flex-end}\n.eg-toast{position:fixed;left:50%;bottom:84px;transform:translateX(-50%);background:#1c2634;color:#fff;padding:10px 16px;border-radius:10px;font-size:13.5px;box-shadow:var(--eg-shadow);max-width:calc(100vw - 32px);pointer-events:none}\nsvg.eg-ic{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}\n@media (max-width:767px){\n .eg-bubble{width:auto}\n .eg-arrow{display:none}\n .eg-modal{top:auto;bottom:12px;transform:translateX(-50%);width:calc(100vw - 24px);padding:24px 20px 18px}\n .eg-modal.eg-pop{animation:eg-up .3s cubic-bezier(.2,.9,.3,1.1)}\n .eg-modal .eg-actions .eg-btn{height:46px}\n .eg-chip{right:16px;bottom:calc(16px + env(safe-area-inset-bottom))}\n .eg-panel-bd{display:block;position:fixed;inset:0;background:rgba(15,23,42,.38);pointer-events:auto}\n .eg-panel{left:0;right:0;bottom:0;width:100%;max-height:85vh;border-radius:18px 18px 0 0;padding-bottom:env(safe-area-inset-bottom)}\n .eg-q-item{padding:12px 8px}\n .eg-card{bottom:calc(12px + env(safe-area-inset-bottom))}\n .eg-toast{bottom:calc(76px + env(safe-area-inset-bottom))}\n}\n@keyframes eg-up{from{opacity:0;transform:translate(-50%,30px)}}\n@media (prefers-reduced-motion:reduce){\n [data-erp-guide-layer] *,[data-erp-guide-layer] *::before,[data-erp-guide-layer] *::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}\n .eg-ring::after{animation:none!important;opacity:1;transform:none}\n .eg-ring.eg-flash::after{animation:eg-flash .5s ease 1!important;animation-duration:.5s!important}\n .eg-hand{animation:none!important;transform:translate(4px,6px)}\n .eg-burst{display:none}\n .eg-bubble.eg-nudge{animation:none!important;border-top-color:var(--eg-danger)}\n}\n";
|
|
7
|
+
export declare const GUIDE_CSS = "\n[data-erp-guide-layer]{position:fixed;inset:0;z-index:1000;pointer-events:none;font-family:inherit;color:var(--popover-foreground,#1c2634);\n --eg-scrim:rgba(12,20,34,.64);--eg-card:var(--popover,#fff);--eg-fg:var(--popover-foreground,#1c2634);\n --eg-muted:var(--muted-foreground,#6d7886);--eg-soft:var(--muted,#eef3f9);--eg-line:var(--border,#e8ecf1);\n --eg-primary:var(--primary,#3280dd);--eg-on-primary:var(--primary-foreground,#fff);\n --eg-tint:color-mix(in oklab,var(--eg-primary) 13%,var(--eg-card));--eg-strong:color-mix(in oklab,var(--eg-primary) 82%,#000);\n --eg-danger:var(--destructive,#d23b4b);--eg-ok:#1d9a5f;--eg-gold:#e6a417;\n --eg-shadow:0 18px 50px -12px rgba(16,32,64,.35),0 4px 12px rgba(16,32,64,.08);line-height:1.5;font-size:14px}\n[data-erp-guide-layer] *{box-sizing:border-box}\n[data-erp-guide-layer] button{font:inherit;color:inherit;cursor:pointer}\n.eg-i{pointer-events:auto}\n.eg-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\n.eg-scrim-svg{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}\n.eg-scrim-svg .eg-scrim-fill{fill:var(--eg-scrim);pointer-events:none}\n.eg-scrim-svg .eg-scrim-hit{fill:transparent;pointer-events:all}\n.eg-scrim{position:fixed;inset:0;background:var(--eg-scrim);pointer-events:auto}\n.eg-scrim.eg-light{background:rgba(12,20,34,.45)}\n.eg-scrim.eg-faint{background:rgba(12,20,34,.35)}\n.eg-ring{position:fixed;border-radius:12px;pointer-events:none;box-shadow:0 0 0 3px #fff,0 0 0 6px var(--eg-primary)}\n.eg-ring.eg-move{transition:left .26s ease,top .26s ease,width .26s ease,height .26s ease}\n.eg-ring::after{content:\"\";position:absolute;inset:-6px;border-radius:15px;border:3px solid var(--eg-primary);animation:eg-pulse 1.6s ease-out infinite}\n.eg-ring.eg-flash::after{animation:eg-flash .5s ease 1}\n@keyframes eg-pulse{0%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(1.12)}}\n@keyframes eg-flash{0%,100%{opacity:1;transform:none}50%{opacity:.2}}\n.eg-hand{position:fixed;width:46px;height:46px;pointer-events:none;filter:drop-shadow(0 4px 6px rgba(0,0,0,.35));animation:eg-tap 1.1s ease-in-out infinite}\n.eg-hand svg{width:46px;height:46px;fill:#fff;stroke:#1c2634;stroke-width:1.4;stroke-linejoin:round;stroke-linecap:round}\n.eg-hand.eg-flip svg{transform:scaleY(-1)}\n@keyframes eg-tap{0%,100%{transform:translate(6px,8px)}50%{transform:translate(0,0)}}\n.eg-bubble{position:fixed;left:0;top:0;width:320px;background:var(--eg-card);color:var(--eg-fg);border-radius:14px;box-shadow:var(--eg-shadow);padding:14px 16px 12px;border-top:4px solid var(--eg-primary);outline:none;pointer-events:auto}\n.eg-bubble.eg-err{border-top-color:var(--eg-danger)}\n.eg-bubble.eg-nudge{animation:eg-nudge .38s ease}\n@keyframes eg-nudge{0%,100%{translate:0}20%{translate:-7px}40%{translate:6px}60%{translate:-4px}80%{translate:2px}}\n.eg-b-top{display:flex;justify-content:space-between;align-items:center;gap:8px;font-size:12px;color:var(--eg-muted)}\n.eg-b-top .eg-mis{font-weight:600;color:var(--eg-strong);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.eg-b-top .eg-cnt{white-space:nowrap;font-weight:600}\n.eg-pips{display:flex;gap:4px;margin:8px 0 10px}\n.eg-pips i{flex:1;height:4px;border-radius:2px;background:var(--eg-soft)}\n.eg-pips i.eg-d{background:var(--eg-primary)}\n.eg-pips i.eg-c{background:color-mix(in oklab,var(--eg-primary) 45%,var(--eg-card))}\n.eg-b-t{margin:0;font-size:16px;font-weight:600;line-height:1.45}\n.eg-b-w{margin:2px 0 0;font-size:13.5px;color:var(--eg-muted)}\n.eg-bubble.eg-err .eg-b-t{color:var(--eg-danger)}\n.eg-k{display:inline-block;background:var(--eg-tint);color:var(--eg-strong);border-radius:7px;padding:0 7px;font-weight:600}\n.eg-b-f{display:flex;align-items:center;justify-content:space-between;margin-top:12px;gap:8px}\n.eg-b-f .eg-btn{height:34px;padding:0 14px;font-size:13.5px}\n.eg-exit{border:0;background:none;color:var(--eg-muted);font-size:12.5px;padding:4px 0;text-decoration:underline;text-underline-offset:3px}\n.eg-exit:hover{color:var(--eg-fg)}\n.eg-arrow{position:absolute;width:14px;height:14px;background:var(--eg-card);transform:rotate(45deg);border-radius:2px}\n.eg-arrow.eg-top{background:var(--eg-primary)}\n.eg-bubble.eg-err .eg-arrow.eg-top{background:var(--eg-danger)}\n.eg-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:40px;padding:0 16px;border-radius:10px;border:1px solid transparent;font-size:14px;font-weight:600;white-space:nowrap}\n.eg-btn:focus-visible,.eg-exit:focus-visible,.eg-chip:focus-visible,.eg-x:focus-visible{outline:2px solid var(--eg-primary);outline-offset:2px}\n.eg-primary{background:var(--eg-primary);color:var(--eg-on-primary)!important}\n.eg-primary:hover{background:var(--eg-strong)}\n.eg-primary[disabled]{opacity:.55;cursor:default}\n.eg-ghost{background:var(--eg-card);border-color:var(--eg-line)}\n.eg-ghost:hover{background:var(--eg-soft)}\n.eg-ghost[disabled]{opacity:.55;cursor:default}\n.eg-link{background:none;border:0;color:var(--eg-muted);font-weight:500;padding:0 6px;height:32px}\n.eg-link:hover{color:var(--eg-fg);text-decoration:underline}\n.eg-modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);width:min(440px,calc(100vw - 32px));max-height:calc(100vh - 32px);overflow:auto;background:var(--eg-card);color:var(--eg-fg);border-radius:20px;box-shadow:var(--eg-shadow);padding:28px 28px 22px;text-align:center;outline:none;pointer-events:auto}\n.eg-modal.eg-pop{animation:eg-pop .32s cubic-bezier(.2,.9,.3,1.3)}\n@keyframes eg-pop{from{opacity:0;transform:translate(-50%,-46%) scale(.94)}}\n.eg-modal h2{margin:6px 0 4px;font-size:22px;font-weight:700;letter-spacing:-.2px;line-height:1.3}\n.eg-modal .eg-sub{margin:0;color:var(--eg-muted);font-size:14.5px}\n.eg-eyebrow{margin:0;font-size:12.5px;font-weight:600;letter-spacing:.3px;color:var(--eg-strong)}\n.eg-actions{display:grid;gap:6px;margin-top:20px}\n.eg-actions .eg-btn{height:44px}\n.eg-badge{width:64px;height:64px;border-radius:18px;margin:0 auto 12px;display:grid;place-items:center;background:var(--eg-tint);color:var(--eg-strong)}\n.eg-badge svg.eg-ic{width:30px;height:30px}\n.eg-quests{list-style:none;padding:0;margin:18px 0 0;text-align:left;display:grid;gap:6px}\n.eg-quests li{display:flex;align-items:center;gap:12px;padding:9px 12px;border-radius:11px;background:var(--eg-soft);font-size:14px}\n.eg-quests li .eg-n{width:26px;height:26px;border-radius:50%;background:var(--eg-card);border:1.5px solid var(--eg-line);display:grid;place-items:center;font-size:12px;font-weight:700;color:var(--eg-muted);flex:none}\n.eg-quests li.eg-first{background:var(--eg-tint)}\n.eg-quests li.eg-first .eg-n{border-color:var(--eg-primary);color:var(--eg-strong)}\n.eg-quests li.eg-ok .eg-n{background:var(--eg-ok);border-color:var(--eg-ok);color:#fff}\n.eg-quests li .eg-n svg.eg-ic{width:15px;height:15px;stroke-width:3}\n.eg-quests li .eg-t{flex:1}\n.eg-quests li small{color:var(--eg-muted);font-size:12px;white-space:nowrap}\n.eg-modal.eg-confirm{text-align:left;width:min(380px,calc(100vw - 32px));padding:22px}\n.eg-modal.eg-confirm h2{font-size:18px;margin-top:0}\n.eg-modal.eg-confirm .eg-actions{grid-template-columns:1fr 1fr}\n.eg-medal{width:84px;height:84px;border-radius:50%;margin:4px auto 10px;display:grid;place-items:center;color:#fff;background:radial-gradient(circle at 35% 30%,#ffd666,var(--eg-gold));box-shadow:0 0 0 8px #fff4d6;animation:eg-stamp .5s cubic-bezier(.2,.9,.3,1.4) .1s both}\n.eg-medal svg.eg-ic{width:42px;height:42px;stroke-width:2.6}\n@keyframes eg-stamp{from{transform:scale(.3) rotate(-25deg);opacity:0}}\n.eg-prog{display:flex;align-items:center;gap:10px;margin-top:16px;font-size:13px;color:var(--eg-muted);font-weight:600}\n.eg-prog .eg-bar{flex:1;height:8px;border-radius:4px;background:var(--eg-soft);overflow:hidden}\n.eg-prog .eg-bar i{display:block;height:100%;background:var(--eg-primary);border-radius:4px;transition:width .9s cubic-bezier(.2,.8,.2,1) .35s}\n.eg-burst{position:absolute;left:50%;top:70px;width:0;height:0;pointer-events:none}\n.eg-burst span{position:absolute;width:8px;height:12px;border-radius:2px;opacity:0;animation:eg-conf 1.1s cubic-bezier(.15,.7,.3,1) forwards}\n@keyframes eg-conf{0%{opacity:1;transform:translate(0,0) rotate(0)}100%{opacity:0;transform:translate(var(--x),var(--y)) rotate(var(--r))}}\n.eg-card{position:fixed;left:50%;bottom:28px;transform:translateX(-50%);width:min(360px,calc(100vw - 32px));background:var(--eg-card);color:var(--eg-fg);border-radius:14px;box-shadow:var(--eg-shadow);padding:14px 16px;border-top:4px solid var(--eg-primary);pointer-events:auto;outline:none}\n.eg-card .eg-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px}\n.eg-loading{display:flex;align-items:center;gap:10px;font-weight:600}\n.eg-spin{width:18px;height:18px;border-radius:50%;border:2.5px solid var(--eg-soft);border-top-color:var(--eg-primary);animation:eg-spin .8s linear infinite;flex:none}\n@keyframes eg-spin{to{transform:rotate(360deg)}}\n.eg-chip{position:fixed;right:22px;bottom:22px;display:flex;align-items:center;gap:10px;height:48px;padding:0 18px 0 8px;border-radius:24px;border:1px solid var(--eg-line);background:var(--eg-card);color:var(--eg-fg);box-shadow:0 8px 24px -8px rgba(16,32,64,.3);font-weight:600;font-size:14px;pointer-events:auto}\n.eg-chip svg{width:34px;height:34px}\n.eg-chip.eg-hi{animation:eg-hi 1.2s ease 2}\n@keyframes eg-hi{50%{box-shadow:0 0 0 6px color-mix(in oklab,var(--eg-primary) 35%,transparent),0 8px 24px -8px rgba(16,32,64,.3)}}\n.eg-panel{position:fixed;right:22px;bottom:82px;width:360px;max-height:calc(100vh - 110px);overflow:auto;background:var(--eg-card);color:var(--eg-fg);border:1px solid var(--eg-line);border-radius:16px;box-shadow:var(--eg-shadow);outline:none;pointer-events:auto}\n.eg-panel-bd{display:none}\n.eg-q-h{display:flex;align-items:center;gap:10px;padding:16px 12px 4px 18px}\n.eg-q-h h2{margin:0;font-size:16px;font-weight:700;flex:1}\n.eg-q-h .eg-n{font-size:13px;color:var(--eg-muted);font-weight:600}\n.eg-x{width:34px;height:34px;border-radius:10px;border:0;background:none;display:grid;place-items:center;color:var(--eg-muted)}\n.eg-x:hover{background:var(--eg-soft)}\n.eg-x svg.eg-ic{width:18px;height:18px}\n.eg-panel .eg-prog{margin:6px 18px 8px}\n.eg-q-list{list-style:none;margin:0;padding:4px 10px 6px;display:grid;gap:2px}\n.eg-q-item{display:flex;align-items:center;gap:12px;padding:10px 8px;border-radius:11px}\n.eg-q-item.eg-next{background:var(--eg-tint)}\n.eg-q-item .eg-n{width:30px;height:30px;border-radius:50%;border:1.5px solid var(--eg-line);display:grid;place-items:center;font-size:12.5px;font-weight:700;color:var(--eg-muted);flex:none;background:var(--eg-card)}\n.eg-q-item.eg-next .eg-n{border-color:var(--eg-primary);color:var(--eg-strong)}\n.eg-q-item.eg-done .eg-n{background:var(--eg-ok);border-color:var(--eg-ok);color:#fff}\n.eg-q-item.eg-done .eg-n svg.eg-ic{width:16px;height:16px;stroke-width:3}\n.eg-q-item.eg-dim .eg-n{opacity:.55}\n.eg-q-item.eg-just .eg-n{animation:eg-stamp .55s cubic-bezier(.2,.9,.3,1.4) .2s both}\n.eg-q-item .eg-t{flex:1;min-width:0}\n.eg-q-item .eg-t b{display:block;font-size:14px;font-weight:600}\n.eg-q-item.eg-done .eg-t b{color:var(--eg-muted)}\n.eg-q-item .eg-t small{display:block;font-size:12px;color:var(--eg-muted)}\n.eg-q-item .eg-t small.eg-sk{color:#b06a00}\n.eg-q-item .eg-t small.eg-lock{color:var(--eg-fg);font-weight:500}\n.eg-q-item .eg-btn{height:32px;padding:0 12px;font-size:13px}\n.eg-q-acts{display:flex;flex-direction:column;align-items:flex-end;gap:2px}\n.eg-q-acts .eg-link{height:22px;font-size:12px;padding:0 2px}\n.eg-q-f{border-top:1px solid var(--eg-line);padding:8px 12px;display:flex;justify-content:flex-end}\n.eg-toast{position:fixed;left:50%;bottom:84px;transform:translateX(-50%);background:#1c2634;color:#fff;padding:10px 16px;border-radius:10px;font-size:13.5px;box-shadow:var(--eg-shadow);max-width:calc(100vw - 32px);pointer-events:none}\nsvg.eg-ic{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}\n@media (max-width:767px){\n .eg-bubble{width:auto}\n .eg-arrow{display:none}\n .eg-modal{top:auto;bottom:12px;transform:translateX(-50%);width:calc(100vw - 24px);padding:24px 20px 18px}\n .eg-modal.eg-pop{animation:eg-up .3s cubic-bezier(.2,.9,.3,1.1)}\n .eg-modal .eg-actions .eg-btn{height:46px}\n .eg-chip{right:16px;bottom:calc(16px + env(safe-area-inset-bottom))}\n .eg-panel-bd{display:block;position:fixed;inset:0;background:rgba(15,23,42,.38);pointer-events:auto}\n .eg-panel{left:0;right:0;bottom:0;width:100%;max-height:85vh;border-radius:18px 18px 0 0;padding-bottom:env(safe-area-inset-bottom)}\n .eg-q-item{padding:12px 8px}\n .eg-card{bottom:calc(12px + env(safe-area-inset-bottom))}\n .eg-toast{bottom:calc(76px + env(safe-area-inset-bottom))}\n}\n@keyframes eg-up{from{opacity:0;transform:translate(-50%,30px)}}\n@media (prefers-reduced-motion:reduce){\n [data-erp-guide-layer] *,[data-erp-guide-layer] *::before,[data-erp-guide-layer] *::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}\n .eg-ring::after{animation:none!important;opacity:1;transform:none}\n .eg-ring.eg-flash::after{animation:eg-flash .5s ease 1!important;animation-duration:.5s!important}\n .eg-hand{animation:none!important;transform:translate(4px,6px)}\n .eg-burst{display:none}\n .eg-bubble.eg-nudge{animation:none!important;border-top-color:var(--eg-danger)}\n}\n";
|
package/dist/guide/guide-ui.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Placement } from "@floating-ui/dom";
|
|
2
|
+
import { type Rect } from "./dom";
|
|
2
3
|
import type { MissionView, StepError } from "./machine";
|
|
3
4
|
/** "26 ต.ค. 2569 13:04" — day, month, Buddhist year, 24 h. */
|
|
4
5
|
export declare function formatThaiDateTime(iso: string | null | undefined): string;
|
|
@@ -11,15 +12,39 @@ export declare const IconX: () => import("react/jsx-runtime").JSX.Element;
|
|
|
11
12
|
export declare const IconFlag: () => import("react/jsx-runtime").JSX.Element;
|
|
12
13
|
export declare const IconTrophy: () => import("react/jsx-runtime").JSX.Element;
|
|
13
14
|
/**
|
|
14
|
-
* The dim layer that eats every press outside the holes.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* The dim layer that eats every press outside the holes. The holes are a
|
|
16
|
+
* union: where two overlap (a field and the select list open over it) the
|
|
17
|
+
* page stays open.
|
|
18
|
+
*
|
|
19
|
+
* - The look: one rectangle masked by the rounded holes (a mask adds holes
|
|
20
|
+
* up, so an overlap is not filled back in).
|
|
21
|
+
* - The presses: a transparent path made of the screen minus the holes, as
|
|
22
|
+
* rectangles that do not overlap (blockedRects). A press inside a hole
|
|
23
|
+
* reaches the page underneath; any other lands on the path (marked
|
|
24
|
+
* data-eg-block) and is cancelled.
|
|
25
|
+
* - `open`: the holes a press may go through, when not all of them (a "view"
|
|
26
|
+
* step's target is shown but not pressable). Default: every hole.
|
|
17
27
|
*/
|
|
18
|
-
export declare function Scrim({ holes, width, height }: {
|
|
28
|
+
export declare function Scrim({ holes, open, width, height }: {
|
|
19
29
|
holes: Rect[];
|
|
30
|
+
open?: Rect[];
|
|
20
31
|
width: number;
|
|
21
32
|
height: number;
|
|
22
33
|
}): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
/** The smallest rectangle around all of them. */
|
|
35
|
+
export declare function boundingRect(rs: Rect[]): Rect;
|
|
36
|
+
/** Where the bubble may go, in order of preference. */
|
|
37
|
+
export declare const BUBBLE_PLACEMENTS: Placement[];
|
|
38
|
+
/**
|
|
39
|
+
* The first placement (in BUBBLE_PLACEMENTS order) whose bubble is on screen,
|
|
40
|
+
* off the target (with its open list), and off everything to keep clear;
|
|
41
|
+
* failing that, the first that is only on screen and off the target; -1 when
|
|
42
|
+
* none is.
|
|
43
|
+
*/
|
|
44
|
+
export declare function pickPlacement(results: Array<{
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
}>, bw: number, bh: number, anchor: Rect, clear: Rect[], bounds: Rect): number;
|
|
23
48
|
export interface BubbleModel {
|
|
24
49
|
missionNo: number;
|
|
25
50
|
missionTitle: string;
|
|
@@ -35,10 +60,26 @@ export interface BubbleModel {
|
|
|
35
60
|
export interface StepLayerProps {
|
|
36
61
|
/** The spotlight (padded target), or null while there is none to show. */
|
|
37
62
|
spot: Rect | null;
|
|
38
|
-
/** Other holes:
|
|
63
|
+
/** Other holes: the anchors the step also allows. */
|
|
39
64
|
holes: Rect[];
|
|
65
|
+
/**
|
|
66
|
+
* Open popper lists (a select's options, a menu): holes too. While one is
|
|
67
|
+
* open the hand is not drawn (the choice is in the list now), and the ring
|
|
68
|
+
* is not drawn over a list that covers the target.
|
|
69
|
+
*/
|
|
70
|
+
popovers?: Rect[];
|
|
71
|
+
/**
|
|
72
|
+
* An open dialog of the app's covers the target (a confirm its button
|
|
73
|
+
* opened): no ring, no hand and no hole there; the bubble stays.
|
|
74
|
+
*/
|
|
75
|
+
covered?: boolean;
|
|
40
76
|
/** False for a "view" step with nothing to point at: the bubble is centred. */
|
|
41
77
|
hasTarget: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Presses on the target reach the page. False on a "view" step: the target
|
|
80
|
+
* is shown, read-only; ถัดไป is the way on. Default true.
|
|
81
|
+
*/
|
|
82
|
+
targetPressable?: boolean;
|
|
42
83
|
viewport: {
|
|
43
84
|
width: number;
|
|
44
85
|
height: number;
|
package/dist/guide/machine.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* No React, no DOM: the tests run it in Node (through the test loader).
|
|
8
8
|
*/
|
|
9
|
-
import type { GuideContext, GuideMission, GuideStep, GuideSuite, GuideText, GuideTrigger } from "./types";
|
|
9
|
+
import type { GuideAbortAction, GuideContext, GuideMission, GuideStep, GuideSuite, GuideText, GuideTrigger } from "./types";
|
|
10
10
|
import { type RouteParams } from "./patterns";
|
|
11
11
|
import type { GuideAudience, GuideProgress, MissionEntry } from "./progress";
|
|
12
12
|
export type StepPhase =
|
|
@@ -180,9 +180,13 @@ export type GuideEffect = {
|
|
|
180
180
|
type: "navigate";
|
|
181
181
|
href: string;
|
|
182
182
|
}
|
|
183
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Put the page back after a replay ended early: press the form's ยกเลิก,
|
|
185
|
+
* emit an app event, Escape to the open dialog (GuideAbortAction).
|
|
186
|
+
*/
|
|
184
187
|
| {
|
|
185
|
-
type: "
|
|
188
|
+
type: "abort";
|
|
189
|
+
actions: GuideAbortAction[];
|
|
186
190
|
};
|
|
187
191
|
export interface GuideResult {
|
|
188
192
|
state: GuideState;
|
|
@@ -216,6 +220,14 @@ export declare function spotlightTarget(step: GuideStep, ctx: GuideContext, brid
|
|
|
216
220
|
anchor: string;
|
|
217
221
|
id?: string;
|
|
218
222
|
} | null;
|
|
223
|
+
/**
|
|
224
|
+
* The page a step happens on: its own `route`, or else where the steps before
|
|
225
|
+
* it left the user (an earlier step's route trigger or route). Undefined when
|
|
226
|
+
* nothing says (a mission's first steps, which work from any page).
|
|
227
|
+
*/
|
|
228
|
+
export declare function stepHomeRoute(steps: GuideStep[], index: number): string | undefined;
|
|
229
|
+
/** What puts the page back when a replay ends at this step (see GuideStep.abort). */
|
|
230
|
+
export declare function abortActionsFor(mission: GuideMission, index: number): GuideAbortAction[];
|
|
219
231
|
/** Status of each mission as the panel shows it. */
|
|
220
232
|
export type MissionView = "todo" | "next" | "active" | "skipped" | "done" | "already" | "locked" | "waiting";
|
|
221
233
|
export declare function missionSettled(m: GuideMission, entry: MissionEntry | undefined, ctx: GuideContext): boolean;
|
package/dist/guide/progress.d.ts
CHANGED
|
@@ -60,6 +60,13 @@ export declare function parseGuidesAnswer(payload: unknown, suite: {
|
|
|
60
60
|
}): GuidesAnswer | null;
|
|
61
61
|
/** The PUT body for the client's state. Drops keys the server would refuse. */
|
|
62
62
|
export declare function putBody(p: GuideProgress, app: string): Record<string, unknown>;
|
|
63
|
+
/**
|
|
64
|
+
* What a PUT would store, without the rev it is checked against: two equal
|
|
65
|
+
* keys mean the save would change nothing, and it is not sent (a replay
|
|
66
|
+
* starting, a step entered again, never bump the row's rev). Key order does
|
|
67
|
+
* not matter.
|
|
68
|
+
*/
|
|
69
|
+
export declare function payloadKey(p: GuideProgress, app: string): string;
|
|
63
70
|
/**
|
|
64
71
|
* After a 409: this tab's state laid over the server's, keeping whatever is
|
|
65
72
|
* further along — a mission done anywhere stays done, the welcome once seen
|
package/dist/guide/types.d.ts
CHANGED
|
@@ -168,8 +168,18 @@ export interface GuideStep {
|
|
|
168
168
|
onMissing?: GuideOnMissing;
|
|
169
169
|
/** How long to wait for the target, while nothing is loading. 8000 ms. */
|
|
170
170
|
timeoutMs?: number;
|
|
171
|
-
/**
|
|
171
|
+
/**
|
|
172
|
+
* More anchors the user may use during this step. A "view" step's own
|
|
173
|
+
* target is read-only (presses on it are blocked, like the rest of the
|
|
174
|
+
* page; ถัดไป is the only way on) unless it is listed here too.
|
|
175
|
+
*/
|
|
172
176
|
allow?: GuideAnchorKey[];
|
|
177
|
+
/**
|
|
178
|
+
* How to put the page back when a replay ends at this step without saving
|
|
179
|
+
* (จบโดยไม่บันทึก, จบการทบทวน): press the form's ยกเลิก, emit an app event,
|
|
180
|
+
* or Escape to the open dialog. Overrides the mission's `abort`.
|
|
181
|
+
*/
|
|
182
|
+
abort?: GuideAbortAction | GuideAbortAction[];
|
|
173
183
|
/**
|
|
174
184
|
* "commit" steps: what a refused save means. Return the key of the step to
|
|
175
185
|
* go back to (a field) and/or the line to show. Default: stay, show the
|
|
@@ -180,6 +190,24 @@ export interface GuideStep {
|
|
|
180
190
|
message?: string;
|
|
181
191
|
} | void;
|
|
182
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* One thing the engine does to put the page back when a replay ends early.
|
|
195
|
+
* Run in order, after the tour has let go of the page; an anchor that is not
|
|
196
|
+
* on the page is passed over.
|
|
197
|
+
*/
|
|
198
|
+
export type GuideAbortAction =
|
|
199
|
+
/** Press this anchor (the form's ยกเลิก, a dialog's close). */
|
|
200
|
+
{
|
|
201
|
+
click: GuideAnchorKey;
|
|
202
|
+
}
|
|
203
|
+
/** `emitGuideEvent(name)`: the page cancels its own editing. */
|
|
204
|
+
| {
|
|
205
|
+
event: string;
|
|
206
|
+
}
|
|
207
|
+
/** Escape to the open dialog (Radix closes on it). */
|
|
208
|
+
| {
|
|
209
|
+
escape: true;
|
|
210
|
+
};
|
|
183
211
|
/** What `capture` sees: the trigger that advanced the step. */
|
|
184
212
|
export interface GuideCaptureEvent {
|
|
185
213
|
route?: {
|
|
@@ -219,6 +247,12 @@ export interface GuideMission {
|
|
|
219
247
|
title?: GuideText;
|
|
220
248
|
subtitle?: GuideText;
|
|
221
249
|
};
|
|
250
|
+
/**
|
|
251
|
+
* How to put the page back when a replay of this mission ends without
|
|
252
|
+
* saving (a step's own `abort` wins). Default: Escape, and only from a step
|
|
253
|
+
* that is not a checkpoint (inside the dialog or form the tour opened).
|
|
254
|
+
*/
|
|
255
|
+
abort?: GuideAbortAction | GuideAbortAction[];
|
|
222
256
|
steps: GuideStep[];
|
|
223
257
|
}
|
|
224
258
|
/** Shown in place of the welcome while the org is not ready for the tour. */
|
package/dist/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export { HelpDialogHost, type HelpDialogHostProps } from "./help/help-dialog";
|
|
|
33
33
|
export { openHelp, closeHelp, type HelpAppId } from "./help/help-store";
|
|
34
34
|
export { describeBrowser, describeAttached, detectHelpApp, type HelpContext, } from "./help/help-context";
|
|
35
35
|
export { SHELL_VERSION } from "./version";
|
|
36
|
-
export type { GuideAnchorKey, GuideApiFailure, GuideApiMatch, GuideAppId, GuideCaptureEvent, GuideConfig, GuideContext, GuideFacts, GuideGate, GuideMission, GuideOnMissing, GuideStep, GuideStepKind, GuideSuite, GuideText, GuideTrigger, } from "./guide/types";
|
|
36
|
+
export type { GuideAbortAction, GuideAnchorKey, GuideApiFailure, GuideApiMatch, GuideAppId, GuideCaptureEvent, GuideConfig, GuideContext, GuideFacts, GuideGate, GuideMission, GuideOnMissing, GuideStep, GuideStepKind, GuideSuite, GuideText, GuideTrigger, } from "./guide/types";
|
|
37
37
|
export { API_EVENT as GUIDE_API_EVENT, GUIDE_EVENT_PREFIX, GUIDE_LAYER_ATTRIBUTE, emitGuideEvent, guideAnchor, reportApiEvent, type ApiEventDetail, type GuideAnchorProps, } from "./guide/events";
|
|
38
38
|
export { openGuidePanel, useGuideEntry, type GuideEntry } from "./guide/guide-store";
|
|
39
39
|
export { GuideHost, type GuideHostProps } from "./guide/guide-host";
|