@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.
Files changed (52) hide show
  1. package/dist/KeakToolbarShadow.d.ts +21 -0
  2. package/dist/KeakToolbarShadow.d.ts.map +1 -0
  3. package/dist/components/ui/card.d.ts +9 -0
  4. package/dist/components/ui/card.d.ts.map +1 -0
  5. package/dist/components/ui/html-preview.d.ts +9 -0
  6. package/dist/components/ui/html-preview.d.ts.map +1 -0
  7. package/dist/components/ui/simple-tabs.d.ts +26 -0
  8. package/dist/components/ui/simple-tabs.d.ts.map +1 -0
  9. package/dist/components/ui/spinner.d.ts +6 -0
  10. package/dist/components/ui/spinner.d.ts.map +1 -0
  11. package/dist/components/ui/tabs.d.ts +13 -0
  12. package/dist/components/ui/tabs.d.ts.map +1 -0
  13. package/dist/components/ui/textarea.d.ts +6 -0
  14. package/dist/components/ui/textarea.d.ts.map +1 -0
  15. package/dist/index.cjs.js +2 -198
  16. package/dist/index.cjs.js.map +1 -1
  17. package/dist/index.js +2 -198
  18. package/dist/index.js.map +1 -1
  19. package/dist/services/telemetry/index.d.ts +20 -0
  20. package/dist/services/telemetry/index.d.ts.map +1 -0
  21. package/dist/services/telemetry/telemetryService.d.ts +66 -0
  22. package/dist/services/telemetry/telemetryService.d.ts.map +1 -0
  23. package/dist/services/telemetry/types.d.ts +64 -0
  24. package/dist/services/telemetry/types.d.ts.map +1 -0
  25. package/dist/toolbar/AIPromptPanel.d.ts +9 -0
  26. package/dist/toolbar/AIPromptPanel.d.ts.map +1 -0
  27. package/dist/toolbar/ElementSelector.d.ts.map +1 -1
  28. package/dist/toolbar/ExperimentPanel.d.ts +9 -0
  29. package/dist/toolbar/ExperimentPanel.d.ts.map +1 -0
  30. package/dist/toolbar/KeakToolbar.d.ts.map +1 -1
  31. package/dist/toolbar/MetricsPanel.d.ts +7 -0
  32. package/dist/toolbar/MetricsPanel.d.ts.map +1 -0
  33. package/dist/toolbar/PageScanPanel.d.ts +15 -0
  34. package/dist/toolbar/PageScanPanel.d.ts.map +1 -0
  35. package/dist/toolbar/components/PrimaryButton.d.ts +12 -0
  36. package/dist/toolbar/components/PrimaryButton.d.ts.map +1 -0
  37. package/dist/toolbar/components/WarningButton.d.ts +12 -0
  38. package/dist/toolbar/components/WarningButton.d.ts.map +1 -0
  39. package/dist/toolbar/components/ui/Badge.d.ts +10 -0
  40. package/dist/toolbar/components/ui/Badge.d.ts.map +1 -0
  41. package/dist/toolbar/components/ui/Button.d.ts +12 -0
  42. package/dist/toolbar/components/ui/Button.d.ts.map +1 -0
  43. package/dist/toolbar/components/ui/Progress.d.ts +5 -0
  44. package/dist/toolbar/components/ui/Progress.d.ts.map +1 -0
  45. package/dist/toolbar/components/ui/Tabs.d.ts +44 -0
  46. package/dist/toolbar/components/ui/Tabs.d.ts.map +1 -0
  47. package/dist/toolbar/components/ui/dropdown-menu.d.ts +28 -0
  48. package/dist/toolbar/components/ui/dropdown-menu.d.ts.map +1 -0
  49. package/dist/toolbar.js +2 -198
  50. package/dist/toolbar.js.map +1 -1
  51. package/package.json +1 -1
  52. 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,9 @@
1
+ import React from 'react';
2
+ interface HTMLPreviewProps {
3
+ html: string;
4
+ className?: string;
5
+ title?: string;
6
+ }
7
+ export declare const HTMLPreview: React.FC<HTMLPreviewProps>;
8
+ export {};
9
+ //# sourceMappingURL=html-preview.d.ts.map
@@ -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" }), mapWarning.show && (jsxRuntime.jsx("div", { className: "keak-map-warning", style: {
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);