@keak/sdk 2.0.9 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/KeakToolbarShadow.d.ts +21 -0
- package/dist/KeakToolbarShadow.d.ts.map +1 -0
- package/dist/components/ui/card.d.ts +9 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/html-preview.d.ts +9 -0
- package/dist/components/ui/html-preview.d.ts.map +1 -0
- package/dist/components/ui/simple-tabs.d.ts +26 -0
- package/dist/components/ui/simple-tabs.d.ts.map +1 -0
- package/dist/components/ui/spinner.d.ts +6 -0
- package/dist/components/ui/spinner.d.ts.map +1 -0
- package/dist/components/ui/tabs.d.ts +13 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/index.cjs.js +2 -198
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +2 -198
- package/dist/index.js.map +1 -1
- package/dist/services/telemetry/index.d.ts +20 -0
- package/dist/services/telemetry/index.d.ts.map +1 -0
- package/dist/services/telemetry/telemetryService.d.ts +66 -0
- package/dist/services/telemetry/telemetryService.d.ts.map +1 -0
- package/dist/services/telemetry/types.d.ts +64 -0
- package/dist/services/telemetry/types.d.ts.map +1 -0
- package/dist/toolbar/AIPromptPanel.d.ts +9 -0
- package/dist/toolbar/AIPromptPanel.d.ts.map +1 -0
- package/dist/toolbar/ElementSelector.d.ts.map +1 -1
- package/dist/toolbar/ExperimentPanel.d.ts +9 -0
- package/dist/toolbar/ExperimentPanel.d.ts.map +1 -0
- package/dist/toolbar/KeakToolbar.d.ts.map +1 -1
- package/dist/toolbar/MetricsPanel.d.ts +7 -0
- package/dist/toolbar/MetricsPanel.d.ts.map +1 -0
- package/dist/toolbar/PageScanPanel.d.ts +15 -0
- package/dist/toolbar/PageScanPanel.d.ts.map +1 -0
- package/dist/toolbar/components/PrimaryButton.d.ts +12 -0
- package/dist/toolbar/components/PrimaryButton.d.ts.map +1 -0
- package/dist/toolbar/components/WarningButton.d.ts +12 -0
- package/dist/toolbar/components/WarningButton.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Badge.d.ts +10 -0
- package/dist/toolbar/components/ui/Badge.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Button.d.ts +12 -0
- package/dist/toolbar/components/ui/Button.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Progress.d.ts +5 -0
- package/dist/toolbar/components/ui/Progress.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Tabs.d.ts +44 -0
- package/dist/toolbar/components/ui/Tabs.d.ts.map +1 -0
- package/dist/toolbar/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/toolbar/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/toolbar.js +2 -198
- package/dist/toolbar.js.map +1 -1
- package/package.json +1 -1
- package/src/plugins/webpack-loader-babel/index.js +1 -6
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface KeakToolbarShadowProps {
|
|
3
|
+
/** Initial position of the toolbar */
|
|
4
|
+
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
5
|
+
/** Theme variant */
|
|
6
|
+
theme?: "light" | "dark" | "auto" | "high-contrast" | "cluely";
|
|
7
|
+
/** API key for Keak services */
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
/** Custom z-index for the toolbar */
|
|
10
|
+
zIndex?: number;
|
|
11
|
+
/** Callback when toolbar is mounted */
|
|
12
|
+
onMount?: (shadowRoot: ShadowRoot) => void;
|
|
13
|
+
/** Callback when toolbar is unmounted */
|
|
14
|
+
onUnmount?: () => void;
|
|
15
|
+
/** Custom CSS variables to override theme */
|
|
16
|
+
customTheme?: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
export declare function KeakToolbarShadow({ position, theme, apiKey, zIndex, // max practical z-index
|
|
19
|
+
onMount, onUnmount, customTheme }: KeakToolbarShadowProps): React.ReactPortal | null;
|
|
20
|
+
export { KeakToolbarShadow as KeakToolbar };
|
|
21
|
+
//# sourceMappingURL=KeakToolbarShadow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeakToolbarShadow.d.ts","sourceRoot":"","sources":["../src/KeakToolbarShadow.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAK9B,MAAM,WAAW,sBAAsB;IACrC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAA;IACpE,oBAAoB;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,eAAe,GAAG,QAAQ,CAAA;IAC9D,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAA;IAC1C,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,QAAyB,EACzB,KAAc,EACd,MAAM,EACN,MAAmB,EAAE,wBAAwB;AAC7C,OAAO,EACP,SAAS,EACT,WAAW,EACZ,EAAE,sBAAsB,4BAmKxB;AAGD,OAAO,EAAE,iBAAiB,IAAI,WAAW,EAAE,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
3
|
+
declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
4
|
+
declare const CardTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
5
|
+
declare const CardDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
6
|
+
declare const CardContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
declare const CardFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
|
|
9
|
+
//# sourceMappingURL=card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../src/components/ui/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,IAAI,6GAYR,CAAC;AAGH,QAAA,MAAM,UAAU,6GASd,CAAC;AAGH,QAAA,MAAM,SAAS,uHAYb,CAAC;AAGH,QAAA,MAAM,eAAe,yHASnB,CAAC;AAGH,QAAA,MAAM,WAAW,6GAKf,CAAC;AAGH,QAAA,MAAM,UAAU,6GASd,CAAC;AAGH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-preview.d.ts","sourceRoot":"","sources":["../../../src/components/ui/html-preview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA2GlD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface TabsProps {
|
|
3
|
+
defaultValue: string;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const Tabs: React.FC<TabsProps>;
|
|
8
|
+
interface TabsListProps {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const TabsList: React.FC<TabsListProps>;
|
|
13
|
+
interface TabsTriggerProps {
|
|
14
|
+
value: string;
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const TabsTrigger: React.FC<TabsTriggerProps>;
|
|
19
|
+
interface TabsContentProps {
|
|
20
|
+
value: string;
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const TabsContent: React.FC<TabsContentProps>;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=simple-tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-tabs.d.ts","sourceRoot":"","sources":["../../../src/components/ui/simple-tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8C,MAAM,OAAO,CAAC;AAUnE,UAAU,SAAS;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAUpC,CAAC;AAEF,UAAU,aAAa;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAM5C,CAAC;AAEF,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAqBlD,CAAC;AAEF,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAalD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type LucideProps } from 'lucide-react';
|
|
2
|
+
export type SpinnerProps = LucideProps & {
|
|
3
|
+
variant?: 'default' | 'circle' | 'pinwheel' | 'circle-filled' | 'ellipsis' | 'ring';
|
|
4
|
+
};
|
|
5
|
+
export declare const Spinner: ({ variant, ...props }: SpinnerProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../../src/components/ui/spinner.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,cAAc,CAAC;AA+ItB,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IACvC,OAAO,CAAC,EACJ,SAAS,GACT,QAAQ,GACR,UAAU,GACV,eAAe,GACf,UAAU,GACV,MAAM,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,OAAO,GAAI,uBAAuB,YAAY,4CAe1D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare const Tabs: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
3
|
+
declare const TabsList: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
4
|
+
declare const TabsTrigger: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
5
|
+
value: string;
|
|
6
|
+
active?: boolean;
|
|
7
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
8
|
+
declare const TabsContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
|
|
9
|
+
value: string;
|
|
10
|
+
active?: boolean;
|
|
11
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
|
13
|
+
//# sourceMappingURL=tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../../src/components/ui/tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,QAAA,MAAM,IAAI,6GASR,CAAC;AAGH,QAAA,MAAM,QAAQ,6GAYZ,CAAC;AAGH,QAAA,MAAM,WAAW;WAGN,MAAM;aACJ,OAAO;2CAclB,CAAC;AAGH,QAAA,MAAM,WAAW;WAGN,MAAM;aACJ,OAAO;wCAYlB,CAAC;AAGH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
3
|
+
}
|
|
4
|
+
declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
5
|
+
export { Textarea };
|
|
6
|
+
//# sourceMappingURL=textarea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../../src/components/ui/textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,WAAW,aACf,SAAQ,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC;CAAG;AAE9D,QAAA,MAAM,QAAQ,2FAab,CAAC;AAGF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -501,116 +501,9 @@ function getSourceConfidence(sourceInfo) {
|
|
|
501
501
|
}
|
|
502
502
|
return 'low';
|
|
503
503
|
}
|
|
504
|
-
/**
|
|
505
|
-
* Check if an element is part of a dynamically generated list (.map(), .forEach(), etc.)
|
|
506
|
-
*
|
|
507
|
-
* Detection strategy:
|
|
508
|
-
* 1. Check if multiple siblings share the same source location (primary method)
|
|
509
|
-
* 2. This indicates they're generated from the same template (likely a map)
|
|
510
|
-
* 3. Also check if the element is a descendant of an element that's in a map
|
|
511
|
-
*
|
|
512
|
-
* @param element The DOM element to check
|
|
513
|
-
* @returns Object with isInMap (boolean) and reason (string) if detected
|
|
514
|
-
*/
|
|
515
|
-
function isElementInDynamicList(element) {
|
|
516
|
-
// First, check if the element itself is in a map
|
|
517
|
-
const directCheck = checkElementForMapPattern(element);
|
|
518
|
-
if (directCheck.isInMap) {
|
|
519
|
-
return directCheck;
|
|
520
|
-
}
|
|
521
|
-
// If not, check if any ancestor is in a map
|
|
522
|
-
let current = element.parentElement;
|
|
523
|
-
let depth = 0;
|
|
524
|
-
const maxDepth = 10; // Limit traversal depth to avoid performance issues
|
|
525
|
-
while (current && depth < maxDepth) {
|
|
526
|
-
const ancestorCheck = checkElementForMapPattern(current);
|
|
527
|
-
if (ancestorCheck.isInMap) {
|
|
528
|
-
return {
|
|
529
|
-
isInMap: true,
|
|
530
|
-
reason: `This element is a child of a dynamically generated list item. ${ancestorCheck.reason}`,
|
|
531
|
-
siblingCount: ancestorCheck.siblingCount
|
|
532
|
-
};
|
|
533
|
-
}
|
|
534
|
-
current = current.parentElement;
|
|
535
|
-
depth++;
|
|
536
|
-
}
|
|
537
|
-
return { isInMap: false };
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* Helper function to check if a specific element is part of a map pattern
|
|
541
|
-
*/
|
|
542
|
-
function checkElementForMapPattern(element) {
|
|
543
|
-
const parent = element.parentElement;
|
|
544
|
-
if (!parent) {
|
|
545
|
-
return { isInMap: false };
|
|
546
|
-
}
|
|
547
|
-
// Get all sibling elements (including the element itself)
|
|
548
|
-
const siblings = Array.from(parent.children).filter((sibling) => sibling instanceof HTMLElement);
|
|
549
|
-
// Need at least 2 siblings to detect a pattern
|
|
550
|
-
if (siblings.length < 2) {
|
|
551
|
-
return { isInMap: false };
|
|
552
|
-
}
|
|
553
|
-
// Get source location for the target element
|
|
554
|
-
const elementSource = getReactFiberSource(element);
|
|
555
|
-
// If we can't get source for the element, try data-keak-src attribute
|
|
556
|
-
let elementSourceKey = null;
|
|
557
|
-
if (elementSource) {
|
|
558
|
-
elementSourceKey = `${elementSource.fileName}:${elementSource.lineNumber}`;
|
|
559
|
-
}
|
|
560
|
-
else {
|
|
561
|
-
const keakSrc = element.getAttribute('data-keak-src');
|
|
562
|
-
if (keakSrc) {
|
|
563
|
-
// Format is "file:line:column", we use file:line as key
|
|
564
|
-
const parts = keakSrc.split(':');
|
|
565
|
-
if (parts.length >= 2) {
|
|
566
|
-
const fileName = parts.slice(0, -2).join(':'); // Handle Windows paths
|
|
567
|
-
const lineNumber = parts[parts.length - 2];
|
|
568
|
-
elementSourceKey = `${fileName}:${lineNumber}`;
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
// If we don't have source info, we can't detect map patterns reliably
|
|
573
|
-
if (!elementSourceKey) {
|
|
574
|
-
return { isInMap: false };
|
|
575
|
-
}
|
|
576
|
-
// Check how many siblings share the same source location
|
|
577
|
-
let matchingSiblings = 0;
|
|
578
|
-
for (const sibling of siblings) {
|
|
579
|
-
const siblingSource = getReactFiberSource(sibling);
|
|
580
|
-
let siblingSourceKey = null;
|
|
581
|
-
if (siblingSource) {
|
|
582
|
-
siblingSourceKey = `${siblingSource.fileName}:${siblingSource.lineNumber}`;
|
|
583
|
-
}
|
|
584
|
-
else {
|
|
585
|
-
const keakSrc = sibling.getAttribute('data-keak-src');
|
|
586
|
-
if (keakSrc) {
|
|
587
|
-
const parts = keakSrc.split(':');
|
|
588
|
-
if (parts.length >= 2) {
|
|
589
|
-
const fileName = parts.slice(0, -2).join(':');
|
|
590
|
-
const lineNumber = parts[parts.length - 2];
|
|
591
|
-
siblingSourceKey = `${fileName}:${lineNumber}`;
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
if (siblingSourceKey === elementSourceKey) {
|
|
596
|
-
matchingSiblings++;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
// If 2+ siblings share the same source location, it's likely a map/forEach
|
|
600
|
-
// We use >= 2 because the element itself counts as one
|
|
601
|
-
if (matchingSiblings >= 2) {
|
|
602
|
-
return {
|
|
603
|
-
isInMap: true,
|
|
604
|
-
reason: `Multiple elements (${matchingSiblings}) share the same source location, indicating they're generated from a .map() or similar dynamic list pattern`,
|
|
605
|
-
siblingCount: matchingSiblings
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
return { isInMap: false };
|
|
609
|
-
}
|
|
610
504
|
|
|
611
505
|
const ElementSelector = ({ onElementSelected, onCancel, }) => {
|
|
612
506
|
const [hoveredElement, setHoveredElement] = React.useState(null);
|
|
613
|
-
const [mapWarning, setMapWarning] = React.useState({ show: false, message: "" });
|
|
614
507
|
const highlightRef = React.useRef(null);
|
|
615
508
|
React.useEffect(() => {
|
|
616
509
|
const handleMouseMove = (e) => {
|
|
@@ -635,27 +528,9 @@ const ElementSelector = ({ onElementSelected, onCancel, }) => {
|
|
|
635
528
|
target.closest(".keak-toolbar") ||
|
|
636
529
|
target.closest(".keak-selector-highlight") ||
|
|
637
530
|
target.closest(".keak-selector-tooltip") ||
|
|
638
|
-
target.closest(".keak-selector-instructions")
|
|
639
|
-
target.closest(".keak-map-warning")) {
|
|
531
|
+
target.closest(".keak-selector-instructions")) {
|
|
640
532
|
return;
|
|
641
533
|
}
|
|
642
|
-
// Check if element is inside a dynamic list (.map(), .forEach(), etc.)
|
|
643
|
-
const mapCheck = isElementInDynamicList(target);
|
|
644
|
-
if (mapCheck.isInMap) {
|
|
645
|
-
// Show warning and prevent selection
|
|
646
|
-
setMapWarning({
|
|
647
|
-
show: true,
|
|
648
|
-
message: mapCheck.reason || "Element is part of a dynamically generated list",
|
|
649
|
-
siblingCount: mapCheck.siblingCount
|
|
650
|
-
});
|
|
651
|
-
// Auto-hide warning after 5 seconds
|
|
652
|
-
setTimeout(() => {
|
|
653
|
-
setMapWarning({ show: false, message: "" });
|
|
654
|
-
}, 5000);
|
|
655
|
-
return; // Prevent selection
|
|
656
|
-
}
|
|
657
|
-
// Clear any existing warning
|
|
658
|
-
setMapWarning({ show: false, message: "" });
|
|
659
534
|
onElementSelected(target);
|
|
660
535
|
};
|
|
661
536
|
const handleKeyDown = (e) => {
|
|
@@ -818,65 +693,7 @@ const ElementSelector = ({ onElementSelected, onCancel, }) => {
|
|
|
818
693
|
return { selector, text, source, impact };
|
|
819
694
|
};
|
|
820
695
|
const elementInfo = hoveredElement ? getElementInfo(hoveredElement) : null;
|
|
821
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { ref: highlightRef, className: "keak-selector-highlight" }),
|
|
822
|
-
position: "fixed",
|
|
823
|
-
top: "140px",
|
|
824
|
-
left: "50%",
|
|
825
|
-
transform: "translateX(-50%)",
|
|
826
|
-
maxWidth: "500px",
|
|
827
|
-
background: "hsl(0 84.2% 60.2%)",
|
|
828
|
-
border: "1px solid hsl(0 72.2% 50.6%)",
|
|
829
|
-
borderRadius: "8px",
|
|
830
|
-
padding: "16px 20px",
|
|
831
|
-
boxShadow: "0 10px 30px 0 rgba(0, 0, 0, 0.3)",
|
|
832
|
-
fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
833
|
-
zIndex: 1000000,
|
|
834
|
-
color: "white",
|
|
835
|
-
animation: "slideDown 0.3s ease-out",
|
|
836
|
-
}, children: jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("div", { style: {
|
|
837
|
-
fontSize: "20px",
|
|
838
|
-
lineHeight: "1",
|
|
839
|
-
marginTop: "2px",
|
|
840
|
-
}, children: "\u26A0\uFE0F" }), jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("div", { style: {
|
|
841
|
-
fontSize: "15px",
|
|
842
|
-
fontWeight: 600,
|
|
843
|
-
marginBottom: "8px",
|
|
844
|
-
}, children: "Cannot select element from dynamic list" }), jsxRuntime.jsx("div", { style: {
|
|
845
|
-
fontSize: "13px",
|
|
846
|
-
lineHeight: "1.5",
|
|
847
|
-
opacity: 0.95,
|
|
848
|
-
marginBottom: "12px",
|
|
849
|
-
}, children: "This element is part of a dynamically generated list (.map(), .forEach(), etc.). Selecting individual items isn't supported because:" }), jsxRuntime.jsxs("ul", { style: {
|
|
850
|
-
fontSize: "13px",
|
|
851
|
-
lineHeight: "1.6",
|
|
852
|
-
margin: "0 0 12px 0",
|
|
853
|
-
paddingLeft: "20px",
|
|
854
|
-
opacity: 0.95,
|
|
855
|
-
listStyle: "none",
|
|
856
|
-
}, children: [jsxRuntime.jsxs("li", { style: { position: "relative", paddingLeft: "16px" }, children: [jsxRuntime.jsx("span", { style: { position: "absolute", left: 0 }, children: "-" }), "The data might come from props or a database"] }), jsxRuntime.jsxs("li", { style: { position: "relative", paddingLeft: "16px" }, children: [jsxRuntime.jsx("span", { style: { position: "absolute", left: 0 }, children: "-" }), "Variants would affect all items, not just one"] })] }), jsxRuntime.jsx("div", { style: {
|
|
857
|
-
fontSize: "13px",
|
|
858
|
-
fontWeight: 600,
|
|
859
|
-
marginTop: "12px",
|
|
860
|
-
paddingTop: "12px",
|
|
861
|
-
borderTop: "1px solid rgba(255, 255, 255, 0.2)",
|
|
862
|
-
}, children: "\uD83D\uDCA1 Alternatives:" }), jsxRuntime.jsxs("ul", { style: {
|
|
863
|
-
fontSize: "13px",
|
|
864
|
-
lineHeight: "1.6",
|
|
865
|
-
margin: "8px 0 0 0",
|
|
866
|
-
paddingLeft: "20px",
|
|
867
|
-
opacity: 0.95,
|
|
868
|
-
listStyle: "none",
|
|
869
|
-
}, children: [jsxRuntime.jsxs("li", { style: { position: "relative", paddingLeft: "16px" }, children: [jsxRuntime.jsx("span", { style: { position: "absolute", left: 0 }, children: "-" }), "Select the parent container to test the entire list"] }), jsxRuntime.jsxs("li", { style: { position: "relative", paddingLeft: "16px" }, children: [jsxRuntime.jsx("span", { style: { position: "absolute", left: 0 }, children: "-" }), "Extract list items into a separate component and wrap it in Experiment/Variant"] })] })] }), jsxRuntime.jsx("button", { onClick: () => setMapWarning({ show: false, message: "" }), style: {
|
|
870
|
-
background: "transparent",
|
|
871
|
-
border: "none",
|
|
872
|
-
color: "white",
|
|
873
|
-
cursor: "pointer",
|
|
874
|
-
fontSize: "18px",
|
|
875
|
-
lineHeight: "1",
|
|
876
|
-
padding: "0",
|
|
877
|
-
opacity: 0.8,
|
|
878
|
-
transition: "opacity 0.2s",
|
|
879
|
-
}, onMouseEnter: (e) => (e.currentTarget.style.opacity = "1"), onMouseLeave: (e) => (e.currentTarget.style.opacity = "0.8"), children: "\u00D7" })] }) })), hoveredElement && elementInfo && (jsxRuntime.jsxs("div", { className: "keak-selector-tooltip", style: {
|
|
696
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { ref: highlightRef, className: "keak-selector-highlight" }), hoveredElement && elementInfo && (jsxRuntime.jsxs("div", { className: "keak-selector-tooltip", style: {
|
|
880
697
|
position: "fixed",
|
|
881
698
|
bottom: `${window.innerHeight -
|
|
882
699
|
hoveredElement.getBoundingClientRect().top +
|
|
@@ -1496,19 +1313,6 @@ const KeakToolbar = ({ position = 'bottom-right', theme = 'auto' }) => {
|
|
|
1496
1313
|
console.log('[Keak Toolbar] Tag:', element.tagName);
|
|
1497
1314
|
console.log('[Keak Toolbar] HTML (first 300 chars):', element.outerHTML.substring(0, 300));
|
|
1498
1315
|
console.log('[Keak Toolbar] All attributes:', Array.from(element.attributes).map(a => `${a.name}="${a.value}"`).join(', '));
|
|
1499
|
-
// Check if element is inside a dynamic list (.map(), .forEach(), etc.)
|
|
1500
|
-
const mapCheck = isElementInDynamicList(element);
|
|
1501
|
-
if (mapCheck.isInMap) {
|
|
1502
|
-
console.log('[Keak Toolbar] ⚠️ Element is part of a dynamic list, preventing selection');
|
|
1503
|
-
console.log('[Keak Toolbar] Reason:', mapCheck.reason);
|
|
1504
|
-
// Show a brief visual feedback
|
|
1505
|
-
element.style.transition = 'all 0.3s';
|
|
1506
|
-
element.style.outline = '3px solid #ef4444';
|
|
1507
|
-
setTimeout(() => { element.style.outline = ''; }, 2000);
|
|
1508
|
-
// Don't proceed with selection
|
|
1509
|
-
setIsSelecting(false);
|
|
1510
|
-
return;
|
|
1511
|
-
}
|
|
1512
1316
|
setSelectedElement(element);
|
|
1513
1317
|
setIsSelecting(false);
|
|
1514
1318
|
updateSelectedHighlight(element);
|