@teambit/react.ui.component-highlighter 0.0.0-2240a868c0f88bba4f62719e6d10d31987cae1f9

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 (134) hide show
  1. package/children-highlighter/children-highlighter.composition.tsx +103 -0
  2. package/children-highlighter/children-highlighter.spec.tsx +22 -0
  3. package/children-highlighter/children-highlighter.tsx +9 -0
  4. package/children-highlighter/index.ts +5 -0
  5. package/children-highlighter/use-children-highlighter.tsx +79 -0
  6. package/component-highlighter.docs.md +191 -0
  7. package/dist/children-highlighter/children-highlighter.composition.d.ts +6 -0
  8. package/dist/children-highlighter/children-highlighter.composition.js +93 -0
  9. package/dist/children-highlighter/children-highlighter.composition.js.map +1 -0
  10. package/dist/children-highlighter/children-highlighter.d.ts +4 -0
  11. package/dist/children-highlighter/children-highlighter.js +24 -0
  12. package/dist/children-highlighter/children-highlighter.js.map +1 -0
  13. package/dist/children-highlighter/children-highlighter.spec.d.ts +1 -0
  14. package/dist/children-highlighter/children-highlighter.spec.js +22 -0
  15. package/dist/children-highlighter/children-highlighter.spec.js.map +1 -0
  16. package/dist/children-highlighter/index.d.ts +4 -0
  17. package/dist/children-highlighter/index.js +8 -0
  18. package/dist/children-highlighter/index.js.map +1 -0
  19. package/dist/children-highlighter/use-children-highlighter.d.ts +18 -0
  20. package/dist/children-highlighter/use-children-highlighter.js +51 -0
  21. package/dist/children-highlighter/use-children-highlighter.js.map +1 -0
  22. package/dist/component-highlighter.docs.md +191 -0
  23. package/dist/element-highlighter/element-highlighter.compositions.d.ts +14 -0
  24. package/dist/element-highlighter/element-highlighter.compositions.js +113 -0
  25. package/dist/element-highlighter/element-highlighter.compositions.js.map +1 -0
  26. package/dist/element-highlighter/element-highlighter.d.ts +22 -0
  27. package/dist/element-highlighter/element-highlighter.js +31 -0
  28. package/dist/element-highlighter/element-highlighter.js.map +1 -0
  29. package/dist/element-highlighter/element-highlighter.module.scss +10 -0
  30. package/dist/element-highlighter/index.d.ts +2 -0
  31. package/dist/element-highlighter/index.js +6 -0
  32. package/dist/element-highlighter/index.js.map +1 -0
  33. package/dist/frame/frame.d.ts +14 -0
  34. package/dist/frame/frame.js +138 -0
  35. package/dist/frame/frame.js.map +1 -0
  36. package/dist/frame/frame.module.scss +23 -0
  37. package/dist/frame/index.d.ts +2 -0
  38. package/dist/frame/index.js +6 -0
  39. package/dist/frame/index.js.map +1 -0
  40. package/dist/hover-highlighter/bubble-to-component.d.ts +24 -0
  41. package/dist/hover-highlighter/bubble-to-component.js +55 -0
  42. package/dist/hover-highlighter/bubble-to-component.js.map +1 -0
  43. package/dist/hover-highlighter/bubble-to-component.spec.d.ts +1 -0
  44. package/dist/hover-highlighter/bubble-to-component.spec.js +38 -0
  45. package/dist/hover-highlighter/bubble-to-component.spec.js.map +1 -0
  46. package/dist/hover-highlighter/hover-highlighter.compositions.d.ts +4 -0
  47. package/dist/hover-highlighter/hover-highlighter.compositions.js +83 -0
  48. package/dist/hover-highlighter/hover-highlighter.compositions.js.map +1 -0
  49. package/dist/hover-highlighter/hover-highlighter.d.ts +4 -0
  50. package/dist/hover-highlighter/hover-highlighter.js +24 -0
  51. package/dist/hover-highlighter/hover-highlighter.js.map +1 -0
  52. package/dist/hover-highlighter/hover-highlighter.spec.d.ts +1 -0
  53. package/dist/hover-highlighter/hover-highlighter.spec.js +95 -0
  54. package/dist/hover-highlighter/hover-highlighter.spec.js.map +1 -0
  55. package/dist/hover-highlighter/index.d.ts +4 -0
  56. package/dist/hover-highlighter/index.js +8 -0
  57. package/dist/hover-highlighter/index.js.map +1 -0
  58. package/dist/hover-highlighter/use-hover-highlighter.d.ts +25 -0
  59. package/dist/hover-highlighter/use-hover-highlighter.js +47 -0
  60. package/dist/hover-highlighter/use-hover-highlighter.js.map +1 -0
  61. package/dist/hybrid-highlighter/hybrid-highlighter.d.ts +36 -0
  62. package/dist/hybrid-highlighter/hybrid-highlighter.js +93 -0
  63. package/dist/hybrid-highlighter/hybrid-highlighter.js.map +1 -0
  64. package/dist/hybrid-highlighter/index.d.ts +2 -0
  65. package/dist/hybrid-highlighter/index.js +6 -0
  66. package/dist/hybrid-highlighter/index.js.map +1 -0
  67. package/dist/ignore-highlighter.d.ts +19 -0
  68. package/dist/ignore-highlighter.js +25 -0
  69. package/dist/ignore-highlighter.js.map +1 -0
  70. package/dist/index.d.ts +10 -0
  71. package/dist/index.js +18 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/label/component-strip.compositions.d.ts +2 -0
  74. package/dist/label/component-strip.compositions.js +17 -0
  75. package/dist/label/component-strip.compositions.js.map +1 -0
  76. package/dist/label/component-strip.d.ts +7 -0
  77. package/dist/label/component-strip.js +71 -0
  78. package/dist/label/component-strip.js.map +1 -0
  79. package/dist/label/component-strip.module.scss +68 -0
  80. package/dist/label/index.d.ts +4 -0
  81. package/dist/label/index.js +8 -0
  82. package/dist/label/index.js.map +1 -0
  83. package/dist/label/label-container.d.ts +13 -0
  84. package/dist/label/label-container.js +87 -0
  85. package/dist/label/label-container.js.map +1 -0
  86. package/dist/label/label.d.ts +6 -0
  87. package/dist/label/label.js +70 -0
  88. package/dist/label/label.js.map +1 -0
  89. package/dist/label/label.module.scss +32 -0
  90. package/dist/label/links.d.ts +2 -0
  91. package/dist/label/links.js +16 -0
  92. package/dist/label/links.js.map +1 -0
  93. package/dist/label/other-components.d.ts +9 -0
  94. package/dist/label/other-components.js +34 -0
  95. package/dist/label/other-components.js.map +1 -0
  96. package/dist/mock-component.d.ts +14 -0
  97. package/dist/mock-component.js +43 -0
  98. package/dist/mock-component.js.map +1 -0
  99. package/dist/preview-1768840768294.js +10 -0
  100. package/dist/rule-matcher.d.ts +8 -0
  101. package/dist/rule-matcher.js +32 -0
  102. package/dist/rule-matcher.js.map +1 -0
  103. package/element-highlighter/element-highlighter.compositions.tsx +130 -0
  104. package/element-highlighter/element-highlighter.module.scss +10 -0
  105. package/element-highlighter/element-highlighter.tsx +51 -0
  106. package/element-highlighter/index.ts +2 -0
  107. package/frame/frame.module.scss +23 -0
  108. package/frame/frame.tsx +142 -0
  109. package/frame/index.ts +2 -0
  110. package/hover-highlighter/bubble-to-component.spec.tsx +57 -0
  111. package/hover-highlighter/bubble-to-component.tsx +82 -0
  112. package/hover-highlighter/hover-highlighter.compositions.tsx +65 -0
  113. package/hover-highlighter/hover-highlighter.spec.tsx +115 -0
  114. package/hover-highlighter/hover-highlighter.tsx +8 -0
  115. package/hover-highlighter/index.ts +5 -0
  116. package/hover-highlighter/use-hover-highlighter.tsx +85 -0
  117. package/hybrid-highlighter/hybrid-highlighter.tsx +142 -0
  118. package/hybrid-highlighter/index.ts +2 -0
  119. package/ignore-highlighter.tsx +22 -0
  120. package/index.ts +21 -0
  121. package/label/component-strip.compositions.tsx +13 -0
  122. package/label/component-strip.module.scss +68 -0
  123. package/label/component-strip.tsx +57 -0
  124. package/label/index.ts +5 -0
  125. package/label/label-container.tsx +74 -0
  126. package/label/label.module.scss +32 -0
  127. package/label/label.tsx +37 -0
  128. package/label/links.tsx +9 -0
  129. package/label/other-components.tsx +51 -0
  130. package/mock-component.tsx +23 -0
  131. package/package.json +60 -0
  132. package/rule-matcher.tsx +42 -0
  133. package/types/asset.d.ts +29 -0
  134. package/types/style.d.ts +42 -0
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.calcComponentLink = calcComponentLink;
7
+ const url_join_1 = __importDefault(require("url-join"));
8
+ const component_modules_component_url_1 = require("@teambit/component.modules.component-url");
9
+ function calcComponentLink(id, exported) {
10
+ if (!id)
11
+ return undefined;
12
+ if (exported)
13
+ return component_modules_component_url_1.ComponentUrl.toUrl(id);
14
+ return (0, url_join_1.default)('/', id.fullName);
15
+ }
16
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../label/links.tsx"],"names":[],"mappings":";;;;;AAIA,8CAIC;AARD,wDAA+B;AAE/B,8FAAwE;AAExE,SAAgB,iBAAiB,CAAC,EAA2B,EAAE,QAA6B;IAC1F,IAAI,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IAC1B,IAAI,QAAQ;QAAE,OAAO,8CAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5C,OAAO,IAAA,kBAAO,EAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { TippyProps } from '@tippyjs/react/headless';
3
+ import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
4
+ export type OtherComponentsProps = {
5
+ components: (ComponentMetaHolder | string)[];
6
+ start?: number;
7
+ end?: number;
8
+ } & TippyProps;
9
+ export declare function OtherComponentsPopper({ components, children, start, end, placement, interactive, ...tippyProps }: OtherComponentsProps): React.JSX.Element;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.OtherComponentsPopper = OtherComponentsPopper;
18
+ const react_1 = __importDefault(require("react"));
19
+ const headless_1 = __importDefault(require("@tippyjs/react/headless"));
20
+ const component_strip_1 = require("./component-strip");
21
+ const label_module_scss_1 = __importDefault(require("./label.module.scss"));
22
+ // a popper ("tooltip") that shows the additional React Components related to this dom element
23
+ function OtherComponentsPopper(_a) {
24
+ var { components, children, start, end = -1, placement = 'bottom', interactive = true } = _a, tippyProps = __rest(_a, ["components", "children", "start", "end", "placement", "interactive"]);
25
+ const content = (react_1.default.createElement(react_1.default.Fragment, null, components
26
+ .slice(start, end)
27
+ .reverse()
28
+ .map((comp, idx) => (react_1.default.createElement(component_strip_1.ComponentStrip, { key: idx, component: comp })))));
29
+ return (react_1.default.createElement(headless_1.default, Object.assign({ placement: placement, interactive: interactive }, tippyProps, {
30
+ // second parameter "content" is always undefined, use content inline
31
+ // https://github.com/atomiks/tippyjs-react/issues/341
32
+ render: (attrs) => (react_1.default.createElement("div", Object.assign({}, attrs, { className: label_module_scss_1.default.othersContainer }), content)) }), children));
33
+ }
34
+ //# sourceMappingURL=other-components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"other-components.js","sourceRoot":"","sources":["../../label/other-components.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAcA,sDAoCC;AAlDD,kDAA0B;AAC1B,uEAA4D;AAG5D,uDAAmD;AACnD,4EAAyC;AAQzC,8FAA8F;AAC9F,SAAgB,qBAAqB,CAAC,EAQf;QARe,EACpC,UAAU,EACV,QAAQ,EACR,KAAK,EACL,GAAG,GAAG,CAAC,CAAC,EACR,SAAS,GAAG,QAAQ,EACpB,WAAW,GAAG,IAAI,OAEG,EADlB,UAAU,cAPuB,sEAQrC,CADc;IAEb,MAAM,OAAO,GAAG,CACd,8DACG,UAAU;SACR,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;SACjB,OAAO,EAAE;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAClB,8BAAC,gCAAc,IAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,GAAI,CAC9C,CAAC,CACH,CACJ,CAAC;IAEF,OAAO,CACL,8BAAC,kBAAK,kBACJ,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,IACpB,UAAU;QACd,qEAAqE;QACrE,sDAAsD;QACtD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CACjB,uDAAS,KAAK,IAAE,SAAS,EAAE,2BAAM,CAAC,eAAe,KAC9C,OAAO,CACJ,CACP,KAEA,QAAQ,CACH,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import React, { ButtonHTMLAttributes, HTMLAttributes } from 'react';
2
+ import { ComponentMeta } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
3
+ export declare function MockTarget({ children, ...rest }: HTMLAttributes<HTMLDivElement>): React.JSX.Element;
4
+ export declare namespace MockTarget {
5
+ var __bit_component: ComponentMeta;
6
+ }
7
+ export declare function MockButton({ children, ...rest }: ButtonHTMLAttributes<HTMLButtonElement>): React.JSX.Element;
8
+ export declare namespace MockButton {
9
+ var __bit_component: ComponentMeta;
10
+ }
11
+ export declare function MockSnap({ children, ...rest }: ButtonHTMLAttributes<HTMLButtonElement>): React.JSX.Element;
12
+ export declare namespace MockSnap {
13
+ var __bit_component: ComponentMeta;
14
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MockTarget = MockTarget;
18
+ exports.MockButton = MockButton;
19
+ exports.MockSnap = MockSnap;
20
+ const react_1 = __importDefault(require("react"));
21
+ const react_ui_highlighter_component_metadata_bit_component_meta_1 = require("@teambit/react.ui.highlighter.component-metadata.bit-component-meta");
22
+ function MockTarget(_a) {
23
+ var { children } = _a, rest = __rest(_a, ["children"]);
24
+ return react_1.default.createElement("div", Object.assign({}, rest), children);
25
+ }
26
+ MockTarget[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField] = {
27
+ id: 'teambit.design/ui/mock-target@1.6.2',
28
+ };
29
+ function MockButton(_a) {
30
+ var { children } = _a, rest = __rest(_a, ["children"]);
31
+ return react_1.default.createElement("button", Object.assign({}, rest), children);
32
+ }
33
+ MockButton[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField] = {
34
+ id: 'teambit.design/ui/icon-button@1.6.2',
35
+ };
36
+ function MockSnap(_a) {
37
+ var { children } = _a, rest = __rest(_a, ["children"]);
38
+ return react_1.default.createElement("button", Object.assign({}, rest), children);
39
+ }
40
+ MockSnap[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField] = {
41
+ id: 'teambit.design/ui/icon-button@a21594d5cc63fd24d2b4763fa7d817b131f0edbb',
42
+ };
43
+ //# sourceMappingURL=mock-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-component.js","sourceRoot":"","sources":["../mock-component.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAGA,gCAEC;AAKD,gCAEC;AAKD,4BAEC;AAnBD,kDAAoE;AACpE,oJAAwH;AAExH,SAAgB,UAAU,CAAC,EAAqD;QAArD,EAAE,QAAQ,OAA2C,EAAtC,IAAI,cAAnB,YAAqB,CAAF;IAC5C,OAAO,uDAAS,IAAI,GAAG,QAAQ,CAAO,CAAC;AACzC,CAAC;AACD,UAAU,CAAC,+EAAkB,CAAC,GAAG;IAC/B,EAAE,EAAE,qCAAqC;CACzB,CAAC;AAEnB,SAAgB,UAAU,CAAC,EAA8D;QAA9D,EAAE,QAAQ,OAAoD,EAA/C,IAAI,cAAnB,YAAqB,CAAF;IAC5C,OAAO,0DAAY,IAAI,GAAG,QAAQ,CAAU,CAAC;AAC/C,CAAC;AACD,UAAU,CAAC,+EAAkB,CAAC,GAAG;IAC/B,EAAE,EAAE,qCAAqC;CACzB,CAAC;AAEnB,SAAgB,QAAQ,CAAC,EAA8D;QAA9D,EAAE,QAAQ,OAAoD,EAA/C,IAAI,cAAnB,YAAqB,CAAF;IAC1C,OAAO,0DAAY,IAAI,GAAG,QAAQ,CAAU,CAAC;AAC/C,CAAC;AACD,QAAQ,CAAC,+EAAkB,CAAC,GAAG;IAC7B,EAAE,EAAE,wEAAwE;CAC5D,CAAC"}
@@ -0,0 +1,10 @@
1
+ import * as compositions_0 from '/tmp/capsules-root/sign-capsules/2026-0-19/z4rgtj/teambit.react_ui_component-highlighter@2240a868c0f88bba4f62719e6d10d31987cae1f9/dist/children-highlighter/children-highlighter.composition.js';
2
+ import * as compositions_1 from '/tmp/capsules-root/sign-capsules/2026-0-19/z4rgtj/teambit.react_ui_component-highlighter@2240a868c0f88bba4f62719e6d10d31987cae1f9/dist/element-highlighter/element-highlighter.compositions.js';
3
+ import * as compositions_2 from '/tmp/capsules-root/sign-capsules/2026-0-19/z4rgtj/teambit.react_ui_component-highlighter@2240a868c0f88bba4f62719e6d10d31987cae1f9/dist/hover-highlighter/hover-highlighter.compositions.js';
4
+ import * as compositions_3 from '/tmp/capsules-root/sign-capsules/2026-0-19/z4rgtj/teambit.react_ui_component-highlighter@2240a868c0f88bba4f62719e6d10d31987cae1f9/dist/label/component-strip.compositions.js';
5
+ import * as overview_0 from '/tmp/capsules-root/sign-capsules/2026-0-19/z4rgtj/teambit.react_ui_component-highlighter@2240a868c0f88bba4f62719e6d10d31987cae1f9/dist/component-highlighter.docs.md';
6
+
7
+ export const compositions = [compositions_0, compositions_1, compositions_2, compositions_3];
8
+ export const overview = [overview_0];
9
+
10
+ export const compositions_metadata = {"compositions":[{"displayName":"Children highlighter preview","identifier":"ChildrenHighlighterPreview"},{"displayName":"Children highlighter with custom colors","identifier":"ChildrenHighlighterWithCustomColors"},{"displayName":"Children highlighter inside ignore","identifier":"ChildrenHighlighterInsideIgnore"},{"displayName":"Children highlighter with rule","identifier":"ChildrenHighlighterWithRule"},{"displayName":"Children highlighter with component rule","identifier":"ChildrenHighlighterWithComponentRule"},{"displayName":"Highlighted element","identifier":"HighlightedElement"},{"displayName":"Customized","identifier":"Customized"},{"displayName":"Sizes","identifier":"Sizes"},{"displayName":"Moving element","identifier":"MovingElement"},{"displayName":"Fullscreen element","identifier":"FullscreenElement"},{"displayName":"Offscreen elements","identifier":"OffscreenElements"},{"displayName":"Show when hovering","identifier":"ShowWhenHovering"},{"displayName":"Unmounting element","identifier":"UnmountingElement"},{"displayName":"Hover exclusion zones","identifier":"HoverExclusionZones"},{"displayName":"Component strip preview","identifier":"ComponentStripPreview"}]};
@@ -0,0 +1,8 @@
1
+ import { ComponentMeta } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
2
+ export type MatchRule = undefined | string | ((element: HTMLElement) => boolean);
3
+ export type ComponentMatchRule = undefined | string | string[] | ((target: ComponentMatchTarget) => boolean);
4
+ export declare function ruleMatcher(element: HTMLElement, rule: MatchRule): boolean;
5
+ export type ComponentMatchTarget = {
6
+ meta: ComponentMeta;
7
+ };
8
+ export declare function componentRuleMatcher(target: ComponentMatchTarget, rule: ComponentMatchRule): boolean;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ruleMatcher = ruleMatcher;
4
+ exports.componentRuleMatcher = componentRuleMatcher;
5
+ // in the future, we will add more options here, like include / exclude objects.
6
+ const component_id_1 = require("@teambit/component-id");
7
+ function ruleMatcher(element, rule) {
8
+ if (typeof rule === 'string') {
9
+ return element.matches(rule);
10
+ }
11
+ if (typeof rule === 'function') {
12
+ return rule(element);
13
+ }
14
+ return true;
15
+ }
16
+ function componentRuleMatcher(target, rule) {
17
+ if (typeof rule === 'string') {
18
+ const targetCmpId = component_id_1.ComponentID.tryFromString(target.meta.id);
19
+ const ruleCmpId = component_id_1.ComponentID.tryFromString(rule);
20
+ return component_id_1.ComponentID.isEqual(ruleCmpId, targetCmpId, { ignoreVersion: true });
21
+ }
22
+ if (Array.isArray(rule)) {
23
+ const targetCmpId = component_id_1.ComponentID.tryFromString(target.meta.id);
24
+ const ruleCmpIds = rule.map((x) => component_id_1.ComponentID.tryFromString(x));
25
+ return ruleCmpIds.some((cmdId) => component_id_1.ComponentID.isEqual(targetCmpId, cmdId, { ignoreVersion: true }));
26
+ }
27
+ if (typeof rule === 'function') {
28
+ return rule(target);
29
+ }
30
+ return true;
31
+ }
32
+ //# sourceMappingURL=rule-matcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-matcher.js","sourceRoot":"","sources":["../rule-matcher.tsx"],"names":[],"mappings":";;AAOA,kCAUC;AAID,oDAoBC;AAzCD,gFAAgF;AAChF,wDAAoD;AAMpD,SAAgB,WAAW,CAAC,OAAoB,EAAE,IAAe;IAC/D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAID,SAAgB,oBAAoB,CAAC,MAA4B,EAAE,IAAwB;IACzF,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,0BAAW,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9D,MAAM,SAAS,GAAG,0BAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAElD,OAAO,0BAAW,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,0BAAW,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0BAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjE,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,0BAAW,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtG,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,130 @@
1
+ import React, { useState, createRef, useEffect, CSSProperties } from 'react';
2
+ import { ElementHighlighter } from './element-highlighter';
3
+ import { MockTarget } from '../mock-component';
4
+
5
+ type HighlightedElementProps = {
6
+ style?: CSSProperties;
7
+ targetStyle?: CSSProperties;
8
+ className?: string;
9
+ watchMotion?: boolean;
10
+ };
11
+
12
+ export const HighlightedElement = ({ style, targetStyle, watchMotion, className }: HighlightedElementProps) => {
13
+ const targetRef = createRef<HTMLDivElement>();
14
+
15
+ return (
16
+ <div className={className} style={{ padding: '16px 16px 40px 16px', width: 300, fontFamily: 'sans-serif' }}>
17
+ <div ref={targetRef} style={{ width: 100, ...targetStyle }}>
18
+ highlight target
19
+ </div>
20
+
21
+ <ElementHighlighter
22
+ targetRef={targetRef}
23
+ components={[MockTarget]}
24
+ style={style}
25
+ watchMotion={watchMotion}
26
+ placement="bottom"
27
+ />
28
+ </div>
29
+ );
30
+ };
31
+
32
+ export const Customized = () => {
33
+ return (
34
+ <HighlightedElement
35
+ style={
36
+ {
37
+ '--bit-highlighter-color': '#94deb4',
38
+ '--bit-highlighter-color-hover': '#d0f1de',
39
+ '--bit-highlighter-color-active': '#37b26c',
40
+ } as CSSProperties
41
+ }
42
+ />
43
+ );
44
+ };
45
+
46
+ export const Sizes = () => {
47
+ return (
48
+ <div>
49
+ <HighlightedElement style={{ fontSize: 10 }} />
50
+ <HighlightedElement style={{ fontSize: 14 }} />
51
+ <HighlightedElement style={{ fontSize: 18 }} />
52
+ </div>
53
+ );
54
+ };
55
+
56
+ const fps = 30;
57
+ const frameInterval = 1000 / fps;
58
+
59
+ export const MovingElement = () => {
60
+ const [margin, setMargin] = useState(0);
61
+
62
+ useEffect(() => {
63
+ const intervalId = setInterval(() => setMargin((x) => (x + 1) % 100), frameInterval);
64
+ return () => clearInterval(intervalId);
65
+ }, []);
66
+
67
+ return <HighlightedElement targetStyle={{ marginLeft: margin }} watchMotion />;
68
+ };
69
+
70
+ export const FullscreenElement = () => {
71
+ const targetRef = createRef<HTMLDivElement>();
72
+
73
+ return (
74
+ <div style={{ fontFamily: 'sans-serif' }}>
75
+ <div
76
+ ref={targetRef}
77
+ style={{
78
+ height: '100vh',
79
+ width: '100%',
80
+ background: '#bceed4',
81
+ }}
82
+ >
83
+ This element will cover the entire document,
84
+ <br />
85
+ pushing the highlighter to the edge of the window.
86
+ <br />
87
+ The highlighter should remain inside and expand no further than the document.
88
+ </div>
89
+ <ElementHighlighter targetRef={targetRef} components={[MockTarget]} watchMotion />
90
+ </div>
91
+ );
92
+ };
93
+
94
+ const edgeStyles = { position: 'absolute', background: 'cyan', padding: 30 } as const;
95
+ const centerStyles = {
96
+ top: { top: -30, left: '50%', transform: 'translate(-50%,0)' },
97
+ right: { right: -30, top: '50%', transform: 'translate(0, -50%)' },
98
+ bottom: { bottom: -30, left: '50%', transform: 'translate(-50%,0)' },
99
+ left: { left: -30, top: '50%', transform: 'translate(0, -50%)' },
100
+ };
101
+
102
+ export function OffscreenElements() {
103
+ const target01 = createRef<HTMLDivElement>();
104
+ const target02 = createRef<HTMLDivElement>();
105
+ const target03 = createRef<HTMLDivElement>();
106
+ const target04 = createRef<HTMLDivElement>();
107
+
108
+ return (
109
+ <div style={{ fontFamily: 'sans-serif', height: '100%' }}>
110
+ <div style={{ position: 'relative', width: '100%', height: '100%', overflow: 'hidden' }}>
111
+ <div ref={target01} style={{ ...edgeStyles, ...centerStyles.top }}>
112
+ top
113
+ </div>
114
+ <div ref={target02} style={{ ...edgeStyles, ...centerStyles.right }}>
115
+ right
116
+ </div>
117
+ <div ref={target03} style={{ ...edgeStyles, ...centerStyles.bottom }}>
118
+ bottom
119
+ </div>
120
+ <div ref={target04} style={{ ...edgeStyles, ...centerStyles.left }}>
121
+ left
122
+ </div>
123
+ <ElementHighlighter targetRef={target01} components={[MockTarget]} watchMotion />
124
+ <ElementHighlighter targetRef={target02} components={[MockTarget]} watchMotion />
125
+ <ElementHighlighter targetRef={target03} components={[MockTarget]} watchMotion />
126
+ <ElementHighlighter targetRef={target04} components={[MockTarget]} watchMotion />
127
+ </div>
128
+ </div>
129
+ );
130
+ }
@@ -0,0 +1,10 @@
1
+ .label {
2
+ // space between the label and the target
3
+ // keep this space so users can move their cursor in this space.
4
+ padding: 8px;
5
+ }
6
+
7
+ .frame,
8
+ .label {
9
+ z-index: 15500 // $highlighter-z-index;
10
+ }
@@ -0,0 +1,51 @@
1
+ import React, { RefObject } from 'react';
2
+ import classnames from 'classnames';
3
+ import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
4
+ import { Frame } from '../frame';
5
+ import { Label, LabelContainer, Placement } from '../label';
6
+ import { skipHighlighterAttr } from '../ignore-highlighter';
7
+ import styles from './element-highlighter.module.scss';
8
+
9
+ export interface ElementHighlighterProps extends React.HTMLAttributes<HTMLDivElement> {
10
+ /** highlight this element */
11
+ targetRef: RefObject<HTMLElement | null>;
12
+ /** components with metadata to show in the label */
13
+ components?: (ComponentMetaHolder | string)[];
14
+
15
+ /** default location of the label */
16
+ placement?: Placement;
17
+ /** customize styles */
18
+ classes?: HighlightClasses;
19
+ /** continually update highlighter to match moving elements */
20
+ watchMotion?: boolean;
21
+ }
22
+
23
+ export { Placement };
24
+
25
+ export type HighlightClasses = {
26
+ container?: string;
27
+ frame?: string;
28
+ label?: string;
29
+ };
30
+
31
+ export function ElementHighlighter({
32
+ targetRef,
33
+ components,
34
+ placement = 'top',
35
+ watchMotion,
36
+ className,
37
+ classes,
38
+ ...props
39
+ }: ElementHighlighterProps) {
40
+ return (
41
+ <div {...props} {...skipHighlighterAttr} className={classnames(classes?.container, styles.container, className)}>
42
+ <Frame targetRef={targetRef} className={classnames(styles.frame, classes?.frame)} watchMotion={watchMotion} />
43
+
44
+ {components && (
45
+ <LabelContainer targetRef={targetRef} className={styles.label} placement={placement} watchMotion={watchMotion}>
46
+ <Label components={components} className={classes?.label} />
47
+ </LabelContainer>
48
+ )}
49
+ </div>
50
+ );
51
+ }
@@ -0,0 +1,2 @@
1
+ export { ElementHighlighter } from './element-highlighter';
2
+ export type { ElementHighlighterProps, Placement, HighlightClasses } from './element-highlighter';
@@ -0,0 +1,23 @@
1
+ $border: 2;
2
+ $padding: 4;
3
+
4
+ .overlayBorder {
5
+ box-sizing: border-box;
6
+ border: $border * 1px solid var(--bit-highlighter-color, #eebcc9);
7
+
8
+ border-radius: 11px;
9
+ padding: $padding * 1px;
10
+
11
+ pointer-events: none;
12
+ user-select: none;
13
+ }
14
+
15
+ .hidden {
16
+ // the frame's size is ignored anyways,
17
+ // and so we can use 'display: none' and not 'visibility: hidden'
18
+ display: none;
19
+ }
20
+
21
+ :export {
22
+ offset: $border + $padding;
23
+ }
@@ -0,0 +1,142 @@
1
+ import React, { useEffect, useLayoutEffect, useRef, RefObject, CSSProperties } from 'react';
2
+ import classnames from 'classnames';
3
+ import { useFloating, autoUpdate, offset, size, detectOverflow, hide } from '@floating-ui/react-dom';
4
+ import type { Coords } from '@floating-ui/react-dom';
5
+
6
+ import styles from './frame.module.scss';
7
+
8
+ export const useIsomorphicLayoutEffect =
9
+ typeof window !== 'undefined' ? useLayoutEffect : useEffect
10
+
11
+ /** frame padding around the target */
12
+ const MARGIN_FROM_TARGET = +styles.offset || 6; // setting fallback 6, for tests
13
+ /** min. distance from the edge of the screen. */
14
+ const MARGIN_FROM_DOC_EDGE = 0;
15
+
16
+ const overflowParameters = { rootBoundary: 'document', padding: MARGIN_FROM_DOC_EDGE } as const;
17
+ const SHIFT_POSITIVE = 'shiftPositive';
18
+
19
+ const HAS_RESIZE_OBSERVER = typeof window !== 'undefined' && !!window.ResizeObserver;
20
+
21
+ export interface FrameProps extends React.HTMLAttributes<HTMLDivElement> {
22
+ /** apply the frame to this element */
23
+ targetRef: RefObject<HTMLElement | null>;
24
+ /**
25
+ * the specific flavor of the frame.
26
+ * @default "redBorderClass"
27
+ */
28
+ stylesClass?: string;
29
+ /** continually update frame position to match moving elements */
30
+ watchMotion?: boolean;
31
+ }
32
+
33
+ // position - bottom start (bottom left corner)
34
+ // x - width - horizontal (cross axis)
35
+ // y - height - vertical (main axis)
36
+
37
+ type DimensionsStyle = Pick<CSSProperties, 'width' | 'height' | 'maxWidth' | 'maxHeight'>;
38
+
39
+ export function Frame({ targetRef, watchMotion, className, stylesClass = styles.overlayBorder, style }: FrameProps) {
40
+ const dimensionRef = useRef<DimensionsStyle>({ width: 0, height: 0 });
41
+
42
+ const { x, y, strategy, reference, floating, update, refs, middlewareData } = useFloating({
43
+ placement: 'bottom-start',
44
+ middleware: [
45
+ // replace dimensions from previous iterations with the target's size
46
+ // this is only the measured size, not yet the applied size
47
+ {
48
+ name: 'align-to-target',
49
+ fn({ rects }) {
50
+ rects.floating = {
51
+ ...rects.floating,
52
+ width: rects.reference.width + 2 * MARGIN_FROM_TARGET,
53
+ height: rects.reference.height + 2 * MARGIN_FROM_TARGET,
54
+ };
55
+
56
+ return {};
57
+ },
58
+ },
59
+ // reposition x,y, to the top of the reference
60
+ offset(({ rects }) => -rects.reference.height),
61
+ // offset the frame by its extra padding
62
+ offset(() => ({ mainAxis: -MARGIN_FROM_TARGET, crossAxis: -MARGIN_FROM_TARGET })),
63
+ // pushes the frame into the document. Similar to shift(), but only pushes when coods are negative
64
+ {
65
+ name: 'shiftPositive',
66
+ fn: async (args) => {
67
+ const overflow = await detectOverflow(args, overflowParameters);
68
+
69
+ const nextCoords = {
70
+ x: overflow.left > 0 ? args.x + overflow.left : args.x,
71
+ y: overflow.top > 0 ? args.y + overflow.top : args.y,
72
+ };
73
+ const shiftAmount = {
74
+ x: nextCoords.x - args.x,
75
+ y: nextCoords.y - args.y,
76
+ };
77
+
78
+ return {
79
+ ...nextCoords,
80
+ data: shiftAmount,
81
+ };
82
+ },
83
+ },
84
+ // size also applies overflow detection via width and height
85
+ size({
86
+ // apply overflow detection in reference to the document
87
+ rootBoundary: 'document',
88
+ padding: MARGIN_FROM_DOC_EDGE,
89
+ apply({ elements, rects, availableHeight, availableWidth, middlewareData }) {
90
+ const shift: Coords = middlewareData[SHIFT_POSITIVE] || { x: 0, y: 0 };
91
+ const paddingX = 2 * MARGIN_FROM_TARGET - shift.x;
92
+ const paddingY = 2 * MARGIN_FROM_TARGET - shift.y;
93
+
94
+ const dimensions: DimensionsStyle = {
95
+ width: rects.reference.width + paddingX,
96
+ height: rects.reference.height + paddingY,
97
+ maxWidth: availableWidth,
98
+ maxHeight: availableHeight,
99
+ };
100
+
101
+ // per floating-ui docs, apply styles directly during apply()
102
+ Object.assign(elements.floating.style, dimensions);
103
+
104
+ // also store in reference, so react renders will have the same value
105
+ dimensionRef.current = dimensions;
106
+ },
107
+ }),
108
+ hide({ strategy: 'referenceHidden' }),
109
+ ],
110
+ });
111
+
112
+ // set target as floating reference
113
+ useIsomorphicLayoutEffect(() => {
114
+ reference(targetRef.current);
115
+ }, [targetRef.current]);
116
+
117
+ // automatically update on scroll, resize, etc.
118
+ // `watchMotion` will trigger continuous updates using animation frame
119
+ useEffect(() => {
120
+ if (!refs.reference.current || !refs.floating.current || !HAS_RESIZE_OBSERVER) return () => {};
121
+
122
+ return autoUpdate(refs.reference.current, refs.floating.current, update, { animationFrame: watchMotion });
123
+ }, [refs.reference.current, refs.floating.current, update, watchMotion]);
124
+
125
+ // could check if x !== null
126
+ const isReady = !middlewareData.hide?.referenceHidden;
127
+
128
+ return (
129
+ <div
130
+ ref={floating}
131
+ className={classnames(className, stylesClass, !isReady && styles.hidden)}
132
+ style={{
133
+ ...style,
134
+ ...dimensionRef.current,
135
+ position: strategy,
136
+ // starting at pos [0,0] will ensure the label doesn't increase the document size.
137
+ top: y ?? 0,
138
+ left: x ?? 0,
139
+ }}
140
+ />
141
+ );
142
+ }
package/frame/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { Frame } from './frame';
2
+ export type { FrameProps } from './frame';
@@ -0,0 +1,57 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import { MockTarget } from '../mock-component';
4
+ import { bubbleToComponent } from './bubble-to-component';
5
+
6
+ it('should find component when starting from a div', () => {
7
+ const { getByText, getByTestId } = render(
8
+ <MockTarget data-testid="expected-result">
9
+ <div>hello world</div>
10
+ </MockTarget>
11
+ );
12
+
13
+ const rendered = getByText('hello world');
14
+
15
+ const result = bubbleToComponent(rendered);
16
+
17
+ expect(result?.element).toBe(getByTestId('expected-result'));
18
+ expect(result?.components).toEqual([MockTarget]);
19
+ });
20
+
21
+ it('should bubble to root component when it renders itself recursively', () => {
22
+ const { getByText, getByTestId } = render(
23
+ <MockTarget data-testid="expected-result">
24
+ <MockTarget>
25
+ <MockTarget>
26
+ <div>hello world</div>
27
+ </MockTarget>
28
+ </MockTarget>
29
+ </MockTarget>
30
+ );
31
+
32
+ const rendered = getByText('hello world');
33
+
34
+ const result = bubbleToComponent(rendered);
35
+
36
+ expect(result?.element).toBe(getByTestId('expected-result'));
37
+ expect(result?.components).toEqual([MockTarget]);
38
+ });
39
+
40
+ it('should find first component, when parent propagation is disabled', () => {
41
+ const { getByText, getByTestId } = render(
42
+ <MockTarget>
43
+ <MockTarget>
44
+ <MockTarget data-testid="expected-result">
45
+ <div>hello world</div>
46
+ </MockTarget>
47
+ </MockTarget>
48
+ </MockTarget>
49
+ );
50
+
51
+ const rendered = getByText('hello world');
52
+
53
+ const result = bubbleToComponent(rendered, { propagateSameParents: false });
54
+
55
+ expect(result?.element).toBe(getByTestId('expected-result'));
56
+ expect(result?.components).toEqual([MockTarget]);
57
+ });