@ai11y/core 0.0.1
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/.turbo/turbo-build.log +87 -0
- package/CHANGELOG.md +29 -0
- package/README.md +37 -0
- package/dist/agent/agent-adapter.d.mts +17 -0
- package/dist/agent/agent-adapter.d.mts.map +1 -0
- package/dist/agent/agent-adapter.mjs +45 -0
- package/dist/agent/agent-adapter.mjs.map +1 -0
- package/dist/agent/llm-agent.d.mts +13 -0
- package/dist/agent/llm-agent.d.mts.map +1 -0
- package/dist/agent/llm-agent.mjs +41 -0
- package/dist/agent/llm-agent.mjs.map +1 -0
- package/dist/agent/plan.d.mts +27 -0
- package/dist/agent/plan.d.mts.map +1 -0
- package/dist/agent/plan.mjs +28 -0
- package/dist/agent/plan.mjs.map +1 -0
- package/dist/agent/rule-based-agent.d.mts +13 -0
- package/dist/agent/rule-based-agent.d.mts.map +1 -0
- package/dist/agent/rule-based-agent.mjs +152 -0
- package/dist/agent/rule-based-agent.mjs.map +1 -0
- package/dist/agent/tool-contract.d.mts +19 -0
- package/dist/agent/tool-contract.d.mts.map +1 -0
- package/dist/agent/types.d.mts +77 -0
- package/dist/agent/types.d.mts.map +1 -0
- package/dist/client-api.d.mts +49 -0
- package/dist/client-api.d.mts.map +1 -0
- package/dist/client-api.mjs +68 -0
- package/dist/client-api.mjs.map +1 -0
- package/dist/context.d.mts +29 -0
- package/dist/context.d.mts.map +1 -0
- package/dist/dom-actions/click.d.mts +15 -0
- package/dist/dom-actions/click.d.mts.map +1 -0
- package/dist/dom-actions/click.mjs +36 -0
- package/dist/dom-actions/click.mjs.map +1 -0
- package/dist/dom-actions/fill-input.d.mts +17 -0
- package/dist/dom-actions/fill-input.d.mts.map +1 -0
- package/dist/dom-actions/fill-input.mjs +69 -0
- package/dist/dom-actions/fill-input.mjs.map +1 -0
- package/dist/dom-actions/find-element.mjs +17 -0
- package/dist/dom-actions/find-element.mjs.map +1 -0
- package/dist/dom-actions/highlight.d.mts +34 -0
- package/dist/dom-actions/highlight.d.mts.map +1 -0
- package/dist/dom-actions/highlight.mjs +60 -0
- package/dist/dom-actions/highlight.mjs.map +1 -0
- package/dist/dom-actions/navigate.d.mts +16 -0
- package/dist/dom-actions/navigate.d.mts.map +1 -0
- package/dist/dom-actions/navigate.mjs +22 -0
- package/dist/dom-actions/navigate.mjs.map +1 -0
- package/dist/dom-actions/scroll.d.mts +16 -0
- package/dist/dom-actions/scroll.d.mts.map +1 -0
- package/dist/dom-actions/scroll.mjs +32 -0
- package/dist/dom-actions/scroll.mjs.map +1 -0
- package/dist/dom.d.mts +23 -0
- package/dist/dom.d.mts.map +1 -0
- package/dist/dom.mjs +60 -0
- package/dist/dom.mjs.map +1 -0
- package/dist/events.d.mts +35 -0
- package/dist/events.d.mts.map +1 -0
- package/dist/events.mjs +49 -0
- package/dist/events.mjs.map +1 -0
- package/dist/index.d.mts +21 -0
- package/dist/index.mjs +18 -0
- package/dist/instruction.d.mts +21 -0
- package/dist/instruction.d.mts.map +1 -0
- package/dist/marker.d.mts +35 -0
- package/dist/marker.d.mts.map +1 -0
- package/dist/marker.mjs +137 -0
- package/dist/marker.mjs.map +1 -0
- package/dist/store.d.mts +56 -0
- package/dist/store.d.mts.map +1 -0
- package/dist/store.mjs +114 -0
- package/dist/store.mjs.map +1 -0
- package/dist/util/attributes.d.mts +57 -0
- package/dist/util/attributes.d.mts.map +1 -0
- package/dist/util/attributes.mjs +68 -0
- package/dist/util/attributes.mjs.map +1 -0
- package/dist/util/format.d.mts +18 -0
- package/dist/util/format.d.mts.map +1 -0
- package/dist/util/format.mjs +21 -0
- package/dist/util/format.mjs.map +1 -0
- package/package.json +26 -0
- package/src/agent/agent-adapter.ts +75 -0
- package/src/agent/index.ts +21 -0
- package/src/agent/llm-agent.ts +64 -0
- package/src/agent/plan.ts +41 -0
- package/src/agent/rule-based-agent.ts +269 -0
- package/src/agent/tool-contract.ts +22 -0
- package/src/agent/types.ts +83 -0
- package/src/client-api.ts +107 -0
- package/src/context.ts +28 -0
- package/src/dom-actions/click.ts +39 -0
- package/src/dom-actions/fill-input.ts +113 -0
- package/src/dom-actions/find-element.ts +14 -0
- package/src/dom-actions/highlight.ts +93 -0
- package/src/dom-actions/index.ts +5 -0
- package/src/dom-actions/navigate.ts +17 -0
- package/src/dom-actions/scroll.ts +29 -0
- package/src/dom.ts +89 -0
- package/src/events.ts +55 -0
- package/src/index.ts +55 -0
- package/src/instruction.ts +6 -0
- package/src/marker.ts +237 -0
- package/src/store.ts +138 -0
- package/src/util/attributes.ts +68 -0
- package/src/util/format.ts +16 -0
- package/src/util/index.ts +2 -0
- package/tsconfig.json +18 -0
- package/tsdown.config.ts +10 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Ai11yContext } from "../context.mjs";
|
|
2
|
+
import { Instruction } from "../instruction.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/agent/types.d.ts
|
|
5
|
+
interface AgentResponse {
|
|
6
|
+
reply: string;
|
|
7
|
+
instructions?: Instruction[];
|
|
8
|
+
}
|
|
9
|
+
interface ConversationMessage {
|
|
10
|
+
role: "user" | "assistant";
|
|
11
|
+
content: string;
|
|
12
|
+
}
|
|
13
|
+
interface AgentRequest {
|
|
14
|
+
input: string;
|
|
15
|
+
context: Ai11yContext;
|
|
16
|
+
messages?: ConversationMessage[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Configuration for LLM-based agent
|
|
20
|
+
*/
|
|
21
|
+
interface LLMAgentConfig {
|
|
22
|
+
/**
|
|
23
|
+
* API endpoint URL for the agent server (e.g., "http://localhost:3000/ai11y/agent")
|
|
24
|
+
*/
|
|
25
|
+
apiEndpoint: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Agent mode selection
|
|
29
|
+
*/
|
|
30
|
+
type AgentMode = "llm" | "rule-based" | "auto";
|
|
31
|
+
/**
|
|
32
|
+
* Configuration for agent selection
|
|
33
|
+
*/
|
|
34
|
+
interface AgentAdapterConfig {
|
|
35
|
+
/**
|
|
36
|
+
* Agent mode selection strategy
|
|
37
|
+
* - "llm": Always use LLM agent (requires llmConfig)
|
|
38
|
+
* - "rule-based": Always use rule-based agent
|
|
39
|
+
* - "auto": Use LLM if configured, fallback to rule-based on error or when offline
|
|
40
|
+
* @default "auto"
|
|
41
|
+
*/
|
|
42
|
+
mode?: AgentMode;
|
|
43
|
+
/**
|
|
44
|
+
* LLM configuration (required for "llm" mode, optional for "auto")
|
|
45
|
+
*/
|
|
46
|
+
llmConfig?: LLMAgentConfig | null;
|
|
47
|
+
/**
|
|
48
|
+
* Force rule-based mode (skip LLM even if config is available)
|
|
49
|
+
* @default false
|
|
50
|
+
*/
|
|
51
|
+
forceRuleBased?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Unified agent configuration combining LLM settings with agent selection options
|
|
55
|
+
*/
|
|
56
|
+
interface AgentConfig {
|
|
57
|
+
/**
|
|
58
|
+
* API endpoint URL for the LLM agent server (required for "llm" mode)
|
|
59
|
+
*/
|
|
60
|
+
apiEndpoint?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Agent mode selection strategy
|
|
63
|
+
* - "llm": Always use LLM agent (requires apiEndpoint)
|
|
64
|
+
* - "rule-based": Always use rule-based agent
|
|
65
|
+
* - "auto": Use LLM if apiEndpoint is provided, fallback to rule-based on error or when offline
|
|
66
|
+
* @default "auto"
|
|
67
|
+
*/
|
|
68
|
+
mode?: AgentMode;
|
|
69
|
+
/**
|
|
70
|
+
* Force rule-based mode (skip LLM even if apiEndpoint is available)
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
forceRuleBased?: boolean;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { AgentAdapterConfig, AgentConfig, AgentMode, AgentRequest, AgentResponse, ConversationMessage, LLMAgentConfig };
|
|
77
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../src/agent/types.ts"],"sourcesContent":[],"mappings":";;;;UAGiB,aAAA;;EAAA,YAAA,CAAA,EAED,WAFc,EAEd;AAGhB;AAKiB,UALA,mBAAA,CAOP;EAOO,IAAA,EAAA,MAAA,GAAA,WAAc;EAUnB,OAAA,EAAA,MAAS;AAKrB;AAyBiB,UAjDA,YAAA,CA8DT;;WA5DE;aACE;;;;;UAMK,cAAA;;;;;;;;;KAUL,SAAA;;;;UAKK,kBAAA;;;;;;;;SAQT;;;;cAKK;;;;;;;;;;UAYI,WAAA;;;;;;;;;;;;SAaT"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Ai11yContext } from "./context.mjs";
|
|
2
|
+
import { Instruction } from "./instruction.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/client-api.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Client interface for interacting with the AI accessibility system
|
|
8
|
+
*/
|
|
9
|
+
interface Ai11yClient {
|
|
10
|
+
/**
|
|
11
|
+
* Describes the current UI context (markers, route, state, errors)
|
|
12
|
+
*/
|
|
13
|
+
describe(): Ai11yContext;
|
|
14
|
+
/**
|
|
15
|
+
* Executes an instruction on the UI
|
|
16
|
+
*/
|
|
17
|
+
act(instruction: Instruction): void;
|
|
18
|
+
/**
|
|
19
|
+
* Tracks a custom event
|
|
20
|
+
*/
|
|
21
|
+
track(event: string, payload?: unknown): void;
|
|
22
|
+
/**
|
|
23
|
+
* Reports an error to the system
|
|
24
|
+
*/
|
|
25
|
+
reportError(error: Error, meta?: {
|
|
26
|
+
surface?: string;
|
|
27
|
+
markerId?: string;
|
|
28
|
+
}): void;
|
|
29
|
+
}
|
|
30
|
+
interface CreateClientOptions {
|
|
31
|
+
onNavigate?: (route: string) => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new AI accessibility client instance
|
|
35
|
+
*
|
|
36
|
+
* @param options - Optional configuration
|
|
37
|
+
* @returns An Ai11yClient instance
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const ctx = createClient({ onNavigate: (route) => navigate(route) })
|
|
42
|
+
* const ui = ctx.describe()
|
|
43
|
+
* ctx.act({ action: "click", id: "save_button" })
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
declare function createClient(options?: CreateClientOptions): Ai11yClient;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Ai11yClient, createClient };
|
|
49
|
+
//# sourceMappingURL=client-api.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-api.d.mts","names":[],"sources":["../src/client-api.ts"],"sourcesContent":[],"mappings":";;;;;;;AAeA;AAIa,UAJI,WAAA,CAIJ;EAKK;;;EAgBR,QAAA,EAAA,EArBG,YAqBgB;EAiBb;;;mBAjCE;;;;;;;;qBAWT;;;;;UAKC,mBAAA;;;;;;;;;;;;;;;;iBAiBM,YAAA,WAAuB,sBAAsB"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { setError, track } from "./store.mjs";
|
|
2
|
+
import { getContext } from "./dom.mjs";
|
|
3
|
+
import { clickMarker } from "./dom-actions/click.mjs";
|
|
4
|
+
import { fillInputMarker } from "./dom-actions/fill-input.mjs";
|
|
5
|
+
import { highlightMarker } from "./dom-actions/highlight.mjs";
|
|
6
|
+
import { navigateToRoute } from "./dom-actions/navigate.mjs";
|
|
7
|
+
import { scrollToMarker } from "./dom-actions/scroll.mjs";
|
|
8
|
+
|
|
9
|
+
//#region src/client-api.ts
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new AI accessibility client instance
|
|
12
|
+
*
|
|
13
|
+
* @param options - Optional configuration
|
|
14
|
+
* @returns An Ai11yClient instance
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const ctx = createClient({ onNavigate: (route) => navigate(route) })
|
|
19
|
+
* const ui = ctx.describe()
|
|
20
|
+
* ctx.act({ action: "click", id: "save_button" })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
function createClient(options) {
|
|
24
|
+
const { onNavigate } = options || {};
|
|
25
|
+
return {
|
|
26
|
+
describe() {
|
|
27
|
+
return getContext();
|
|
28
|
+
},
|
|
29
|
+
act(instruction) {
|
|
30
|
+
switch (instruction.action) {
|
|
31
|
+
case "click":
|
|
32
|
+
clickMarker(instruction.id);
|
|
33
|
+
break;
|
|
34
|
+
case "navigate":
|
|
35
|
+
if (onNavigate) onNavigate(instruction.route);
|
|
36
|
+
else navigateToRoute(instruction.route);
|
|
37
|
+
break;
|
|
38
|
+
case "highlight":
|
|
39
|
+
highlightMarker(instruction.id);
|
|
40
|
+
break;
|
|
41
|
+
case "scroll":
|
|
42
|
+
scrollToMarker(instruction.id);
|
|
43
|
+
break;
|
|
44
|
+
case "fillInput":
|
|
45
|
+
fillInputMarker(instruction.id, instruction.value);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
track(event, payload) {
|
|
50
|
+
track(event, payload);
|
|
51
|
+
},
|
|
52
|
+
reportError(error, meta) {
|
|
53
|
+
setError({
|
|
54
|
+
error,
|
|
55
|
+
meta,
|
|
56
|
+
timestamp: Date.now()
|
|
57
|
+
});
|
|
58
|
+
track("error", {
|
|
59
|
+
error: error.message,
|
|
60
|
+
meta
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
export { createClient };
|
|
68
|
+
//# sourceMappingURL=client-api.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-api.mjs","names":[],"sources":["../src/client-api.ts"],"sourcesContent":["import type { Ai11yContext, Ai11yError } from \"./context.js\";\nimport { getContext } from \"./dom.js\";\nimport {\n\tclickMarker,\n\tfillInputMarker,\n\thighlightMarker,\n\tnavigateToRoute,\n\tscrollToMarker,\n} from \"./dom-actions/index.js\";\nimport type { Instruction } from \"./instruction.js\";\nimport { setError, track as trackToStore } from \"./store.js\";\n\n/**\n * Client interface for interacting with the AI accessibility system\n */\nexport interface Ai11yClient {\n\t/**\n\t * Describes the current UI context (markers, route, state, errors)\n\t */\n\tdescribe(): Ai11yContext;\n\n\t/**\n\t * Executes an instruction on the UI\n\t */\n\tact(instruction: Instruction): void;\n\n\t/**\n\t * Tracks a custom event\n\t */\n\ttrack(event: string, payload?: unknown): void;\n\n\t/**\n\t * Reports an error to the system\n\t */\n\treportError(\n\t\terror: Error,\n\t\tmeta?: { surface?: string; markerId?: string },\n\t): void;\n}\n\ninterface CreateClientOptions {\n\tonNavigate?: (route: string) => void;\n}\n\n/**\n * Creates a new AI accessibility client instance\n *\n * @param options - Optional configuration\n * @returns An Ai11yClient instance\n *\n * @example\n * ```ts\n * const ctx = createClient({ onNavigate: (route) => navigate(route) })\n * const ui = ctx.describe()\n * ctx.act({ action: \"click\", id: \"save_button\" })\n * ```\n */\nexport function createClient(options?: CreateClientOptions): Ai11yClient {\n\tconst { onNavigate } = options || {};\n\n\treturn {\n\t\tdescribe(): Ai11yContext {\n\t\t\treturn getContext();\n\t\t},\n\n\t\tact(instruction: Instruction): void {\n\t\t\tswitch (instruction.action) {\n\t\t\t\tcase \"click\":\n\t\t\t\t\tclickMarker(instruction.id);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"navigate\":\n\t\t\t\t\tif (onNavigate) {\n\t\t\t\t\t\tonNavigate(instruction.route);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnavigateToRoute(instruction.route);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"highlight\":\n\t\t\t\t\thighlightMarker(instruction.id);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"scroll\":\n\t\t\t\t\tscrollToMarker(instruction.id);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"fillInput\":\n\t\t\t\t\tfillInputMarker(instruction.id, instruction.value);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\n\t\ttrack(event: string, payload?: unknown): void {\n\t\t\ttrackToStore(event, payload);\n\t\t},\n\n\t\treportError(\n\t\t\terror: Error,\n\t\t\tmeta?: { surface?: string; markerId?: string },\n\t\t): void {\n\t\t\tconst assistError: Ai11yError = {\n\t\t\t\terror,\n\t\t\t\tmeta,\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t};\n\t\t\tsetError(assistError);\n\t\t\ttrackToStore(\"error\", { error: error.message, meta });\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyDA,SAAgB,aAAa,SAA4C;CACxE,MAAM,EAAE,eAAe,WAAW,EAAE;AAEpC,QAAO;EACN,WAAyB;AACxB,UAAO,YAAY;;EAGpB,IAAI,aAAgC;AACnC,WAAQ,YAAY,QAApB;IACC,KAAK;AACJ,iBAAY,YAAY,GAAG;AAC3B;IACD,KAAK;AACJ,SAAI,WACH,YAAW,YAAY,MAAM;SAE7B,iBAAgB,YAAY,MAAM;AAEnC;IACD,KAAK;AACJ,qBAAgB,YAAY,GAAG;AAC/B;IACD,KAAK;AACJ,oBAAe,YAAY,GAAG;AAC9B;IACD,KAAK;AACJ,qBAAgB,YAAY,IAAI,YAAY,MAAM;AAClD;;;EAIH,MAAM,OAAe,SAAyB;AAC7C,SAAa,OAAO,QAAQ;;EAG7B,YACC,OACA,MACO;AAMP,YALgC;IAC/B;IACA;IACA,WAAW,KAAK,KAAK;IACrB,CACoB;AACrB,SAAa,SAAS;IAAE,OAAO,MAAM;IAAS;IAAM,CAAC;;EAEtD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Marker } from "./marker.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/context.d.ts
|
|
4
|
+
interface Ai11yState {
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
interface Ai11yError {
|
|
8
|
+
error: Error;
|
|
9
|
+
meta?: {
|
|
10
|
+
surface?: string;
|
|
11
|
+
markerId?: string;
|
|
12
|
+
};
|
|
13
|
+
timestamp: number;
|
|
14
|
+
}
|
|
15
|
+
interface Ai11yEvent {
|
|
16
|
+
type: string;
|
|
17
|
+
payload?: unknown;
|
|
18
|
+
timestamp: number;
|
|
19
|
+
}
|
|
20
|
+
interface Ai11yContext {
|
|
21
|
+
markers: Marker[];
|
|
22
|
+
inViewMarkerIds?: string[];
|
|
23
|
+
route?: string;
|
|
24
|
+
state?: Ai11yState;
|
|
25
|
+
error?: Ai11yError | null;
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { Ai11yContext, Ai11yError, Ai11yEvent, Ai11yState };
|
|
29
|
+
//# sourceMappingURL=context.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.mts","names":[],"sources":["../src/context.ts"],"sourcesContent":[],"mappings":";;;UAEiB,UAAA;;AAAjB;AAIiB,UAAA,UAAA,CACT;EAQS,KAAA,EART,KAQS;EAMA,IAAA,CAAA,EAAA;IACP,OAAA,CAAA,EAAA,MAAA;IAGD,QAAA,CAAA,EAAA,MAAA;EACA,CAAA;EAAU,SAAA,EAAA,MAAA;;UAXF,UAAA;;;;;UAMA,YAAA;WACP;;;UAGD;UACA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/dom-actions/click.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Clicks a marker element by its ID
|
|
4
|
+
*
|
|
5
|
+
* @param markerId - The marker ID to click
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* clickMarker('connect_stripe');
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
declare function clickMarker(markerId: string): void;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { clickMarker };
|
|
15
|
+
//# sourceMappingURL=click.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.d.mts","names":[],"sources":["../../src/dom-actions/click.ts"],"sourcesContent":[],"mappings":";;AAaA;;;;;;;;;iBAAgB,WAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { track } from "../store.mjs";
|
|
2
|
+
import { findMarkerElement } from "./find-element.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/dom-actions/click.ts
|
|
5
|
+
/**
|
|
6
|
+
* Clicks a marker element by its ID
|
|
7
|
+
*
|
|
8
|
+
* @param markerId - The marker ID to click
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* clickMarker('connect_stripe');
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function clickMarker(markerId) {
|
|
16
|
+
const element = findMarkerElement(markerId);
|
|
17
|
+
if (!element) {
|
|
18
|
+
console.warn(`Marker ${markerId} not found`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if ("click" in element && typeof element.click === "function") element.click();
|
|
22
|
+
else {
|
|
23
|
+
const mouseEvent = new MouseEvent("click", {
|
|
24
|
+
view: window,
|
|
25
|
+
bubbles: true,
|
|
26
|
+
cancelable: true,
|
|
27
|
+
buttons: 1
|
|
28
|
+
});
|
|
29
|
+
element.dispatchEvent(mouseEvent);
|
|
30
|
+
}
|
|
31
|
+
track("click", { markerId });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { clickMarker };
|
|
36
|
+
//# sourceMappingURL=click.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"click.mjs","names":[],"sources":["../../src/dom-actions/click.ts"],"sourcesContent":["import { track } from \"../store.js\";\nimport { findMarkerElement } from \"./find-element.js\";\n\n/**\n * Clicks a marker element by its ID\n *\n * @param markerId - The marker ID to click\n *\n * @example\n * ```ts\n * clickMarker('connect_stripe');\n * ```\n */\nexport function clickMarker(markerId: string): void {\n\tconst element = findMarkerElement(markerId);\n\tif (!element) {\n\t\tconsole.warn(`Marker ${markerId} not found`);\n\t\treturn;\n\t}\n\n\t// Prefer native click to avoid double-firing handlers (important for toggles)\n\tif (\n\t\t\"click\" in element &&\n\t\ttypeof (element as HTMLElement).click === \"function\"\n\t) {\n\t\t(element as HTMLElement).click();\n\t} else {\n\t\t// Fallback: dispatch a synthetic mouse event\n\t\tconst mouseEvent = new MouseEvent(\"click\", {\n\t\t\tview: window,\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t\tbuttons: 1,\n\t\t});\n\t\telement.dispatchEvent(mouseEvent);\n\t}\n\n\ttrack(\"click\", { markerId });\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,YAAY,UAAwB;CACnD,MAAM,UAAU,kBAAkB,SAAS;AAC3C,KAAI,CAAC,SAAS;AACb,UAAQ,KAAK,UAAU,SAAS,YAAY;AAC5C;;AAID,KACC,WAAW,WACX,OAAQ,QAAwB,UAAU,WAE1C,CAAC,QAAwB,OAAO;MAC1B;EAEN,MAAM,aAAa,IAAI,WAAW,SAAS;GAC1C,MAAM;GACN,SAAS;GACT,YAAY;GACZ,SAAS;GACT,CAAC;AACF,UAAQ,cAAc,WAAW;;AAGlC,OAAM,SAAS,EAAE,UAAU,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/dom-actions/fill-input.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Fills an input, textarea, or select element by its marker ID with a value, emitting native browser events
|
|
4
|
+
*
|
|
5
|
+
* @param markerId - The marker ID of the input/textarea/select element to fill
|
|
6
|
+
* @param value - The value to fill into the element. For select elements, this must match one of the available option values.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* fillInputMarker('email_input', 'test@example.com');
|
|
11
|
+
* fillInputMarker('category_select', 'feedback');
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
declare function fillInputMarker(markerId: string, value: string): void;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { fillInputMarker };
|
|
17
|
+
//# sourceMappingURL=fill-input.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill-input.d.mts","names":[],"sources":["../../src/dom-actions/fill-input.ts"],"sourcesContent":[],"mappings":";;AAeA;;;;;;;;;;;iBAAgB,eAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { track } from "../store.mjs";
|
|
2
|
+
import { findMarkerElement } from "./find-element.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/dom-actions/fill-input.ts
|
|
5
|
+
/**
|
|
6
|
+
* Fills an input, textarea, or select element by its marker ID with a value, emitting native browser events
|
|
7
|
+
*
|
|
8
|
+
* @param markerId - The marker ID of the input/textarea/select element to fill
|
|
9
|
+
* @param value - The value to fill into the element. For select elements, this must match one of the available option values.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* fillInputMarker('email_input', 'test@example.com');
|
|
14
|
+
* fillInputMarker('category_select', 'feedback');
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function fillInputMarker(markerId, value) {
|
|
18
|
+
const element = findMarkerElement(markerId);
|
|
19
|
+
if (!element) {
|
|
20
|
+
console.warn(`Marker ${markerId} not found`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
let inputElement = null;
|
|
24
|
+
let selectElement = null;
|
|
25
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) inputElement = element;
|
|
26
|
+
else if (element instanceof HTMLSelectElement) selectElement = element;
|
|
27
|
+
else if (element instanceof HTMLElement) {
|
|
28
|
+
const nestedInput = element.querySelector("input, textarea");
|
|
29
|
+
if (nestedInput instanceof HTMLInputElement || nestedInput instanceof HTMLTextAreaElement) inputElement = nestedInput;
|
|
30
|
+
else {
|
|
31
|
+
const nestedSelect = element.querySelector("select");
|
|
32
|
+
if (nestedSelect instanceof HTMLSelectElement) selectElement = nestedSelect;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const isContentEditable = element instanceof HTMLElement && element.contentEditable === "true";
|
|
36
|
+
if (!inputElement && !selectElement && !isContentEditable) {
|
|
37
|
+
console.warn(`Marker ${markerId} does not contain an input, textarea, select, or contenteditable element`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (inputElement) {
|
|
41
|
+
const prototype = inputElement instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
|
|
42
|
+
const setter = Object.getOwnPropertyDescriptor(prototype, "value")?.set;
|
|
43
|
+
if (setter) setter.call(inputElement, value);
|
|
44
|
+
else inputElement.value = value;
|
|
45
|
+
inputElement.dispatchEvent(new Event("input", { bubbles: true }));
|
|
46
|
+
inputElement.dispatchEvent(new Event("change", { bubbles: true }));
|
|
47
|
+
inputElement.focus();
|
|
48
|
+
} else if (selectElement) {
|
|
49
|
+
selectElement.value = value;
|
|
50
|
+
selectElement.dispatchEvent(new Event("change", { bubbles: true }));
|
|
51
|
+
selectElement.focus();
|
|
52
|
+
} else if (isContentEditable) {
|
|
53
|
+
const editableElement = element;
|
|
54
|
+
editableElement.textContent = value;
|
|
55
|
+
const inputEvent = new InputEvent("input", {
|
|
56
|
+
bubbles: true,
|
|
57
|
+
cancelable: true
|
|
58
|
+
});
|
|
59
|
+
element.dispatchEvent(inputEvent);
|
|
60
|
+
}
|
|
61
|
+
track("fillInput", {
|
|
62
|
+
markerId,
|
|
63
|
+
value
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//#endregion
|
|
68
|
+
export { fillInputMarker };
|
|
69
|
+
//# sourceMappingURL=fill-input.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill-input.mjs","names":["inputElement: HTMLInputElement | HTMLTextAreaElement | null","selectElement: HTMLSelectElement | null"],"sources":["../../src/dom-actions/fill-input.ts"],"sourcesContent":["import { track } from \"../store.js\";\nimport { findMarkerElement } from \"./find-element.js\";\n\n/**\n * Fills an input, textarea, or select element by its marker ID with a value, emitting native browser events\n *\n * @param markerId - The marker ID of the input/textarea/select element to fill\n * @param value - The value to fill into the element. For select elements, this must match one of the available option values.\n *\n * @example\n * ```ts\n * fillInputMarker('email_input', 'test@example.com');\n * fillInputMarker('category_select', 'feedback');\n * ```\n */\nexport function fillInputMarker(markerId: string, value: string): void {\n\tconst element = findMarkerElement(markerId);\n\tif (!element) {\n\t\tconsole.warn(`Marker ${markerId} not found`);\n\t\treturn;\n\t}\n\n\t// If the marked element is not itself an input, try to find an input inside it\n\t// (in case Mark wraps the input in a container)\n\tlet inputElement: HTMLInputElement | HTMLTextAreaElement | null = null;\n\tlet selectElement: HTMLSelectElement | null = null;\n\n\tif (\n\t\telement instanceof HTMLInputElement ||\n\t\telement instanceof HTMLTextAreaElement\n\t) {\n\t\tinputElement = element;\n\t} else if (element instanceof HTMLSelectElement) {\n\t\tselectElement = element;\n\t} else if (element instanceof HTMLElement) {\n\t\t// Search for input, textarea, or select within the marked element\n\t\tconst nestedInput = element.querySelector(\"input, textarea\");\n\t\tif (\n\t\t\tnestedInput instanceof HTMLInputElement ||\n\t\t\tnestedInput instanceof HTMLTextAreaElement\n\t\t) {\n\t\t\tinputElement = nestedInput;\n\t\t} else {\n\t\t\tconst nestedSelect = element.querySelector(\"select\");\n\t\t\tif (nestedSelect instanceof HTMLSelectElement) {\n\t\t\t\tselectElement = nestedSelect;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst isContentEditable =\n\t\telement instanceof HTMLElement && element.contentEditable === \"true\";\n\n\tif (!inputElement && !selectElement && !isContentEditable) {\n\t\tconsole.warn(\n\t\t\t`Marker ${markerId} does not contain an input, textarea, select, or contenteditable element`,\n\t\t);\n\t\treturn;\n\t}\n\n\t// Set the value property (for React controlled components)\n\tif (inputElement) {\n\t\t// Step 1: Directly set the value\n\t\t// For React-controlled inputs, we must use the native setter to bypass React's value prop\n\t\tconst prototype =\n\t\t\tinputElement instanceof HTMLTextAreaElement\n\t\t\t\t? HTMLTextAreaElement.prototype\n\t\t\t\t: HTMLInputElement.prototype;\n\t\tconst setter = Object.getOwnPropertyDescriptor(prototype, \"value\")?.set;\n\n\t\tif (setter) {\n\t\t\t// Use native setter for React-controlled inputs\n\t\t\tsetter.call(inputElement, value);\n\t\t} else {\n\t\t\t// Fallback: direct assignment for native inputs\n\t\t\tinputElement.value = value;\n\t\t}\n\n\t\t// Step 2: Dispatch the right events with bubbles: true\n\t\t// This is crucial - bubbles: true allows React/Vue/Angular to catch the events\n\t\t// input event → updates live state\n\t\tinputElement.dispatchEvent(new Event(\"input\", { bubbles: true }));\n\n\t\t// change event → commits value (important for forms)\n\t\tinputElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\n\t\t// Step 3: Focus management (optional but useful)\n\t\t// Helps with validation, conditional UI, and accessibility expectations\n\t\tinputElement.focus();\n\t} else if (selectElement) {\n\t\t// For select elements, set the value property\n\t\tselectElement.value = value;\n\n\t\t// Dispatch change event to trigger React onChange handlers\n\t\tselectElement.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\n\t\t// Focus the select element\n\t\tselectElement.focus();\n\t} else if (isContentEditable) {\n\t\t// For contenteditable elements, set textContent and dispatch events\n\t\tconst editableElement = element as HTMLElement;\n\t\teditableElement.textContent = value;\n\n\t\t// Dispatch input event\n\t\tconst inputEvent = new InputEvent(\"input\", {\n\t\t\tbubbles: true,\n\t\t\tcancelable: true,\n\t\t});\n\t\telement.dispatchEvent(inputEvent);\n\t}\n\n\ttrack(\"fillInput\", { markerId, value });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,SAAgB,gBAAgB,UAAkB,OAAqB;CACtE,MAAM,UAAU,kBAAkB,SAAS;AAC3C,KAAI,CAAC,SAAS;AACb,UAAQ,KAAK,UAAU,SAAS,YAAY;AAC5C;;CAKD,IAAIA,eAA8D;CAClE,IAAIC,gBAA0C;AAE9C,KACC,mBAAmB,oBACnB,mBAAmB,oBAEnB,gBAAe;UACL,mBAAmB,kBAC7B,iBAAgB;UACN,mBAAmB,aAAa;EAE1C,MAAM,cAAc,QAAQ,cAAc,kBAAkB;AAC5D,MACC,uBAAuB,oBACvB,uBAAuB,oBAEvB,gBAAe;OACT;GACN,MAAM,eAAe,QAAQ,cAAc,SAAS;AACpD,OAAI,wBAAwB,kBAC3B,iBAAgB;;;CAKnB,MAAM,oBACL,mBAAmB,eAAe,QAAQ,oBAAoB;AAE/D,KAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,mBAAmB;AAC1D,UAAQ,KACP,UAAU,SAAS,0EACnB;AACD;;AAID,KAAI,cAAc;EAGjB,MAAM,YACL,wBAAwB,sBACrB,oBAAoB,YACpB,iBAAiB;EACrB,MAAM,SAAS,OAAO,yBAAyB,WAAW,QAAQ,EAAE;AAEpE,MAAI,OAEH,QAAO,KAAK,cAAc,MAAM;MAGhC,cAAa,QAAQ;AAMtB,eAAa,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,MAAM,CAAC,CAAC;AAGjE,eAAa,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,MAAM,CAAC,CAAC;AAIlE,eAAa,OAAO;YACV,eAAe;AAEzB,gBAAc,QAAQ;AAGtB,gBAAc,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,MAAM,CAAC,CAAC;AAGnE,gBAAc,OAAO;YACX,mBAAmB;EAE7B,MAAM,kBAAkB;AACxB,kBAAgB,cAAc;EAG9B,MAAM,aAAa,IAAI,WAAW,SAAS;GAC1C,SAAS;GACT,YAAY;GACZ,CAAC;AACF,UAAQ,cAAc,WAAW;;AAGlC,OAAM,aAAa;EAAE;EAAU;EAAO,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getMarkerSelector } from "../util/attributes.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/dom-actions/find-element.ts
|
|
4
|
+
/**
|
|
5
|
+
* Finds an element by its marker ID (data-ai-id attribute)
|
|
6
|
+
*
|
|
7
|
+
* @param markerId - The marker ID to find
|
|
8
|
+
* @returns The element if found, null otherwise
|
|
9
|
+
*/
|
|
10
|
+
function findMarkerElement(markerId) {
|
|
11
|
+
if (typeof document === "undefined") return null;
|
|
12
|
+
return document.querySelector(getMarkerSelector(markerId));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { findMarkerElement };
|
|
17
|
+
//# sourceMappingURL=find-element.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-element.mjs","names":[],"sources":["../../src/dom-actions/find-element.ts"],"sourcesContent":["import { getMarkerSelector } from \"../util/attributes.js\";\n\n/**\n * Finds an element by its marker ID (data-ai-id attribute)\n *\n * @param markerId - The marker ID to find\n * @returns The element if found, null otherwise\n */\nexport function findMarkerElement(markerId: string): Element | null {\n\tif (typeof document === \"undefined\") {\n\t\treturn null;\n\t}\n\treturn document.querySelector(getMarkerSelector(markerId));\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,kBAAkB,UAAkC;AACnE,KAAI,OAAO,aAAa,YACvB,QAAO;AAER,QAAO,SAAS,cAAc,kBAAkB,SAAS,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/dom-actions/highlight.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Options for highlighting a marker
|
|
4
|
+
*/
|
|
5
|
+
interface HighlightOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Callback function called when marker is highlighted
|
|
8
|
+
*/
|
|
9
|
+
onHighlight?: (markerId: string, element: Element) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Duration in milliseconds for the highlight (default: 2000)
|
|
12
|
+
* Set to 0 to skip visual highlighting (useful when using custom highlight wrapper)
|
|
13
|
+
*/
|
|
14
|
+
duration?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Highlights a marker element by its ID
|
|
18
|
+
* Scrolls the element into view (only if not already in view) and applies visual highlighting
|
|
19
|
+
*
|
|
20
|
+
* @param markerId - The marker ID to highlight
|
|
21
|
+
* @param options - Optional configuration for highlighting
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* highlightMarker('connect_stripe', {
|
|
26
|
+
* onHighlight: (id, el) => console.log('Highlighted:', id),
|
|
27
|
+
* duration: 3000
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
declare function highlightMarker(markerId: string, options?: HighlightOptions): void;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { HighlightOptions, highlightMarker };
|
|
34
|
+
//# sourceMappingURL=highlight.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight.d.mts","names":[],"sources":["../../src/dom-actions/highlight.ts"],"sourcesContent":[],"mappings":";;AAMA;AA6CA;UA7CiB,gBAAA;;;;4CAI0B;;;;;;;;;;;;;;;;;;;;;;iBAyC3B,eAAA,6BAEN"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { track } from "../store.mjs";
|
|
2
|
+
import { findMarkerElement } from "./find-element.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/dom-actions/highlight.ts
|
|
5
|
+
/**
|
|
6
|
+
* Checks if an element is currently visible in the viewport
|
|
7
|
+
*/
|
|
8
|
+
function isElementInView(element) {
|
|
9
|
+
const rect = element.getBoundingClientRect();
|
|
10
|
+
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
11
|
+
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
12
|
+
return rect.top < windowHeight && rect.bottom > 0 && rect.left < windowWidth && rect.right > 0;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Highlights a marker element by its ID
|
|
16
|
+
* Scrolls the element into view (only if not already in view) and applies visual highlighting
|
|
17
|
+
*
|
|
18
|
+
* @param markerId - The marker ID to highlight
|
|
19
|
+
* @param options - Optional configuration for highlighting
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* highlightMarker('connect_stripe', {
|
|
24
|
+
* onHighlight: (id, el) => console.log('Highlighted:', id),
|
|
25
|
+
* duration: 3000
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function highlightMarker(markerId, options = {}) {
|
|
30
|
+
const element = findMarkerElement(markerId);
|
|
31
|
+
if (!element) {
|
|
32
|
+
console.warn(`Marker ${markerId} not found`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const { onHighlight, duration = 2e3 } = options;
|
|
36
|
+
if (!isElementInView(element)) element.scrollIntoView({
|
|
37
|
+
behavior: "smooth",
|
|
38
|
+
block: "center",
|
|
39
|
+
inline: "nearest"
|
|
40
|
+
});
|
|
41
|
+
if (onHighlight) onHighlight(markerId, element);
|
|
42
|
+
if (duration > 0) {
|
|
43
|
+
const originalOutline = element.style.outline;
|
|
44
|
+
const originalOutlineOffset = element.style.outlineOffset;
|
|
45
|
+
const originalTransition = element.style.transition;
|
|
46
|
+
element.style.outline = "3px solid #3b82f6";
|
|
47
|
+
element.style.outlineOffset = "2px";
|
|
48
|
+
element.style.transition = "outline 0.2s ease";
|
|
49
|
+
window.setTimeout(() => {
|
|
50
|
+
element.style.outline = originalOutline;
|
|
51
|
+
element.style.outlineOffset = originalOutlineOffset;
|
|
52
|
+
element.style.transition = originalTransition;
|
|
53
|
+
}, duration);
|
|
54
|
+
}
|
|
55
|
+
track("highlight", { markerId });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { highlightMarker };
|
|
60
|
+
//# sourceMappingURL=highlight.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight.mjs","names":[],"sources":["../../src/dom-actions/highlight.ts"],"sourcesContent":["import { track } from \"../store.js\";\nimport { findMarkerElement } from \"./find-element.js\";\n\n/**\n * Options for highlighting a marker\n */\nexport interface HighlightOptions {\n\t/**\n\t * Callback function called when marker is highlighted\n\t */\n\tonHighlight?: (markerId: string, element: Element) => void;\n\t/**\n\t * Duration in milliseconds for the highlight (default: 2000)\n\t * Set to 0 to skip visual highlighting (useful when using custom highlight wrapper)\n\t */\n\tduration?: number;\n}\n\n/**\n * Checks if an element is currently visible in the viewport\n */\nfunction isElementInView(element: Element): boolean {\n\tconst rect = element.getBoundingClientRect();\n\tconst windowHeight =\n\t\twindow.innerHeight || document.documentElement.clientHeight;\n\tconst windowWidth = window.innerWidth || document.documentElement.clientWidth;\n\n\tconst isPartiallyVisible =\n\t\trect.top < windowHeight &&\n\t\trect.bottom > 0 &&\n\t\trect.left < windowWidth &&\n\t\trect.right > 0;\n\n\treturn isPartiallyVisible;\n}\n\n/**\n * Highlights a marker element by its ID\n * Scrolls the element into view (only if not already in view) and applies visual highlighting\n *\n * @param markerId - The marker ID to highlight\n * @param options - Optional configuration for highlighting\n *\n * @example\n * ```ts\n * highlightMarker('connect_stripe', {\n * onHighlight: (id, el) => console.log('Highlighted:', id),\n * duration: 3000\n * });\n * ```\n */\nexport function highlightMarker(\n\tmarkerId: string,\n\toptions: HighlightOptions = {},\n): void {\n\tconst element = findMarkerElement(markerId);\n\tif (!element) {\n\t\tconsole.warn(`Marker ${markerId} not found`);\n\t\treturn;\n\t}\n\n\tconst { onHighlight, duration = 2000 } = options;\n\n\tif (!isElementInView(element)) {\n\t\telement.scrollIntoView({\n\t\t\tbehavior: \"smooth\",\n\t\t\tblock: \"center\",\n\t\t\tinline: \"nearest\",\n\t\t});\n\t}\n\n\tif (onHighlight) {\n\t\tonHighlight(markerId, element);\n\t}\n\n\tif (duration > 0) {\n\t\tconst originalOutline = (element as HTMLElement).style.outline;\n\t\tconst originalOutlineOffset = (element as HTMLElement).style.outlineOffset;\n\t\tconst originalTransition = (element as HTMLElement).style.transition;\n\n\t\t(element as HTMLElement).style.outline = \"3px solid #3b82f6\";\n\t\t(element as HTMLElement).style.outlineOffset = \"2px\";\n\t\t(element as HTMLElement).style.transition = \"outline 0.2s ease\";\n\n\t\twindow.setTimeout(() => {\n\t\t\t(element as HTMLElement).style.outline = originalOutline;\n\t\t\t(element as HTMLElement).style.outlineOffset = originalOutlineOffset;\n\t\t\t(element as HTMLElement).style.transition = originalTransition;\n\t\t}, duration);\n\t}\n\n\ttrack(\"highlight\", { markerId });\n}\n"],"mappings":";;;;;;;AAqBA,SAAS,gBAAgB,SAA2B;CACnD,MAAM,OAAO,QAAQ,uBAAuB;CAC5C,MAAM,eACL,OAAO,eAAe,SAAS,gBAAgB;CAChD,MAAM,cAAc,OAAO,cAAc,SAAS,gBAAgB;AAQlE,QALC,KAAK,MAAM,gBACX,KAAK,SAAS,KACd,KAAK,OAAO,eACZ,KAAK,QAAQ;;;;;;;;;;;;;;;;;AAoBf,SAAgB,gBACf,UACA,UAA4B,EAAE,EACvB;CACP,MAAM,UAAU,kBAAkB,SAAS;AAC3C,KAAI,CAAC,SAAS;AACb,UAAQ,KAAK,UAAU,SAAS,YAAY;AAC5C;;CAGD,MAAM,EAAE,aAAa,WAAW,QAAS;AAEzC,KAAI,CAAC,gBAAgB,QAAQ,CAC5B,SAAQ,eAAe;EACtB,UAAU;EACV,OAAO;EACP,QAAQ;EACR,CAAC;AAGH,KAAI,YACH,aAAY,UAAU,QAAQ;AAG/B,KAAI,WAAW,GAAG;EACjB,MAAM,kBAAmB,QAAwB,MAAM;EACvD,MAAM,wBAAyB,QAAwB,MAAM;EAC7D,MAAM,qBAAsB,QAAwB,MAAM;AAE1D,EAAC,QAAwB,MAAM,UAAU;AACzC,EAAC,QAAwB,MAAM,gBAAgB;AAC/C,EAAC,QAAwB,MAAM,aAAa;AAE5C,SAAO,iBAAiB;AACvB,GAAC,QAAwB,MAAM,UAAU;AACzC,GAAC,QAAwB,MAAM,gBAAgB;AAC/C,GAAC,QAAwB,MAAM,aAAa;KAC1C,SAAS;;AAGb,OAAM,aAAa,EAAE,UAAU,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/dom-actions/navigate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Navigates to a route
|
|
4
|
+
* Updates the route in the store and tracks the navigation event
|
|
5
|
+
*
|
|
6
|
+
* @param route - The route to navigate to
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* navigateToRoute('/billing');
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
declare function navigateToRoute(route: string): void;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { navigateToRoute };
|
|
16
|
+
//# sourceMappingURL=navigate.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.d.mts","names":[],"sources":["../../src/dom-actions/navigate.ts"],"sourcesContent":[],"mappings":";;AAaA;;;;;;;;;;iBAAgB,eAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { setRoute, track } from "../store.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/dom-actions/navigate.ts
|
|
4
|
+
/**
|
|
5
|
+
* Navigates to a route
|
|
6
|
+
* Updates the route in the store and tracks the navigation event
|
|
7
|
+
*
|
|
8
|
+
* @param route - The route to navigate to
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* navigateToRoute('/billing');
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
function navigateToRoute(route) {
|
|
16
|
+
setRoute(route);
|
|
17
|
+
track("navigate", { route });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { navigateToRoute };
|
|
22
|
+
//# sourceMappingURL=navigate.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.mjs","names":[],"sources":["../../src/dom-actions/navigate.ts"],"sourcesContent":["import { setRoute, track } from \"../store.js\";\n\n/**\n * Navigates to a route\n * Updates the route in the store and tracks the navigation event\n *\n * @param route - The route to navigate to\n *\n * @example\n * ```ts\n * navigateToRoute('/billing');\n * ```\n */\nexport function navigateToRoute(route: string): void {\n\tsetRoute(route);\n\ttrack(\"navigate\", { route });\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,gBAAgB,OAAqB;AACpD,UAAS,MAAM;AACf,OAAM,YAAY,EAAE,OAAO,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/dom-actions/scroll.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Scrolls to a marker element by its ID
|
|
4
|
+
* Does not apply highlight animation - use highlightMarker() if you want both scroll and highlight
|
|
5
|
+
*
|
|
6
|
+
* @param markerId - The marker ID to scroll to
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* scrollToMarker('connect_stripe');
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
declare function scrollToMarker(markerId: string): void;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { scrollToMarker };
|
|
16
|
+
//# sourceMappingURL=scroll.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll.d.mts","names":[],"sources":["../../src/dom-actions/scroll.ts"],"sourcesContent":[],"mappings":";;AAcA;;;;;;;;;;iBAAgB,cAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { track } from "../store.mjs";
|
|
2
|
+
import { findMarkerElement } from "./find-element.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/dom-actions/scroll.ts
|
|
5
|
+
/**
|
|
6
|
+
* Scrolls to a marker element by its ID
|
|
7
|
+
* Does not apply highlight animation - use highlightMarker() if you want both scroll and highlight
|
|
8
|
+
*
|
|
9
|
+
* @param markerId - The marker ID to scroll to
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* scrollToMarker('connect_stripe');
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
function scrollToMarker(markerId) {
|
|
17
|
+
const element = findMarkerElement(markerId);
|
|
18
|
+
if (!element) {
|
|
19
|
+
console.warn(`Marker ${markerId} not found`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
element.scrollIntoView({
|
|
23
|
+
behavior: "smooth",
|
|
24
|
+
block: "center",
|
|
25
|
+
inline: "nearest"
|
|
26
|
+
});
|
|
27
|
+
track("scroll", { markerId });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { scrollToMarker };
|
|
32
|
+
//# sourceMappingURL=scroll.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scroll.mjs","names":[],"sources":["../../src/dom-actions/scroll.ts"],"sourcesContent":["import { track } from \"../store.js\";\nimport { findMarkerElement } from \"./find-element.js\";\n\n/**\n * Scrolls to a marker element by its ID\n * Does not apply highlight animation - use highlightMarker() if you want both scroll and highlight\n *\n * @param markerId - The marker ID to scroll to\n *\n * @example\n * ```ts\n * scrollToMarker('connect_stripe');\n * ```\n */\nexport function scrollToMarker(markerId: string): void {\n\tconst element = findMarkerElement(markerId);\n\tif (!element) {\n\t\tconsole.warn(`Marker ${markerId} not found`);\n\t\treturn;\n\t}\n\n\telement.scrollIntoView({\n\t\tbehavior: \"smooth\",\n\t\tblock: \"center\",\n\t\tinline: \"nearest\",\n\t});\n\n\ttrack(\"scroll\", { markerId });\n}\n"],"mappings":";;;;;;;;;;;;;;;AAcA,SAAgB,eAAe,UAAwB;CACtD,MAAM,UAAU,kBAAkB,SAAS;AAC3C,KAAI,CAAC,SAAS;AACb,UAAQ,KAAK,UAAU,SAAS,YAAY;AAC5C;;AAGD,SAAQ,eAAe;EACtB,UAAU;EACV,OAAO;EACP,QAAQ;EACR,CAAC;AAEF,OAAM,UAAU,EAAE,UAAU,CAAC"}
|