@teambit/react.ui.component-highlighter 0.0.513 → 0.2.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 (59) hide show
  1. package/children-highlighter/children-highlighter.composition.tsx +13 -11
  2. package/children-highlighter/children-highlighter.spec.tsx +1 -1
  3. package/children-highlighter/use-children-highlighter.tsx +6 -3
  4. package/dist/children-highlighter/children-highlighter.composition.js +17 -8
  5. package/dist/children-highlighter/children-highlighter.composition.js.map +1 -1
  6. package/dist/children-highlighter/children-highlighter.spec.js +1 -1
  7. package/dist/children-highlighter/children-highlighter.spec.js.map +1 -1
  8. package/dist/children-highlighter/use-children-highlighter.js +3 -1
  9. package/dist/children-highlighter/use-children-highlighter.js.map +1 -1
  10. package/dist/element-highlighter/element-highlighter.compositions.d.ts +2 -1
  11. package/dist/element-highlighter/element-highlighter.compositions.js +36 -6
  12. package/dist/element-highlighter/element-highlighter.compositions.js.map +1 -1
  13. package/dist/element-highlighter/element-highlighter.js +1 -1
  14. package/dist/element-highlighter/element-highlighter.js.map +1 -1
  15. package/dist/frame/frame.js +49 -25
  16. package/dist/frame/frame.js.map +1 -1
  17. package/dist/hover-highlighter/hover-highlighter.compositions.d.ts +2 -0
  18. package/dist/hover-highlighter/hover-highlighter.compositions.js +32 -3
  19. package/dist/hover-highlighter/hover-highlighter.compositions.js.map +1 -1
  20. package/dist/hover-highlighter/use-hover-highlighter.js +7 -2
  21. package/dist/hover-highlighter/use-hover-highlighter.js.map +1 -1
  22. package/dist/ignore-highlighter.d.ts +12 -3
  23. package/dist/ignore-highlighter.js +11 -4
  24. package/dist/ignore-highlighter.js.map +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +3 -2
  27. package/dist/index.js.map +1 -1
  28. package/dist/label/component-strip.compositions.d.ts +2 -0
  29. package/dist/label/component-strip.compositions.js +17 -0
  30. package/dist/label/component-strip.compositions.js.map +1 -0
  31. package/dist/label/component-strip.js +7 -5
  32. package/dist/label/component-strip.js.map +1 -1
  33. package/dist/label/component-strip.module.scss +19 -0
  34. package/dist/label/label-container.js +11 -5
  35. package/dist/label/label-container.js.map +1 -1
  36. package/dist/label/label.module.scss +2 -0
  37. package/dist/mock-component.d.ts +4 -2
  38. package/dist/mock-component.js +18 -4
  39. package/dist/mock-component.js.map +1 -1
  40. package/dist/tsconfig.json +32 -0
  41. package/element-highlighter/element-highlighter.compositions.tsx +52 -4
  42. package/element-highlighter/element-highlighter.tsx +2 -2
  43. package/frame/frame.tsx +52 -24
  44. package/hover-highlighter/hover-highlighter.compositions.tsx +45 -3
  45. package/hover-highlighter/use-hover-highlighter.tsx +9 -3
  46. package/ignore-highlighter.tsx +11 -3
  47. package/index.ts +2 -1
  48. package/label/component-strip.compositions.tsx +13 -0
  49. package/label/component-strip.module.scss +19 -0
  50. package/label/component-strip.tsx +7 -5
  51. package/label/label-container.tsx +11 -5
  52. package/label/label.module.scss +2 -0
  53. package/mock-component.tsx +19 -5
  54. package/package-tar/teambit-react.ui.component-highlighter-0.2.0.tgz +0 -0
  55. package/package.json +18 -55
  56. package/preview-1657547073447.js +8 -0
  57. package/tsconfig.json +8 -2
  58. package/package-tar/teambit-react.ui.component-highlighter-0.0.513.tgz +0 -0
  59. package/preview-1649042627943.js +0 -2
@@ -3,16 +3,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ExcludeHighlighter = exports.excludeHighlighterAtt = exports.excludeHighlighterSelector = exports.excludeHighlighterAttrName = void 0;
6
+ exports.skipHighlighterSelector = exports.skipHighlighterAttr = exports.skipHighlighterAttrName = exports.ExcludeHighlighter = exports.excludeHighlighterAtt = exports.excludeHighlighterSelector = exports.excludeHighlighterAttrName = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
+ /** name of ignore attribute */
8
9
  exports.excludeHighlighterAttrName = 'data-ignore-component-highlight';
9
- /** select elements matching the exclusion pattern */
10
+ /** selector for elements with the ignore attribute */
10
11
  exports.excludeHighlighterSelector = `[${exports.excludeHighlighterAttrName}]`;
11
- /** elements with these attributes will be ignored by the automatic highlighter */
12
+ /** highlighter will exclude elements with this attribute */
12
13
  exports.excludeHighlighterAtt = { [exports.excludeHighlighterAttrName]: true };
13
- /** elements under this element will be ignored by the automatic highlighter */
14
+ /** children of this element will be excluded by the automatic highlighter */
14
15
  function ExcludeHighlighter(props) {
15
16
  return react_1.default.createElement("div", Object.assign({}, props, exports.excludeHighlighterAtt));
16
17
  }
17
18
  exports.ExcludeHighlighter = ExcludeHighlighter;
19
+ /** name of skip attribute */
20
+ exports.skipHighlighterAttrName = 'data-skip-component-highlight';
21
+ /** highlighter will skip (ignore) elements with these attributes */
22
+ exports.skipHighlighterAttr = { [exports.skipHighlighterAttrName]: true };
23
+ /** selector for elements with the skip attribute */
24
+ exports.skipHighlighterSelector = `[${exports.skipHighlighterAttrName}]`;
18
25
  //# sourceMappingURL=ignore-highlighter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ignore-highlighter.js","sourceRoot":"","sources":["../ignore-highlighter.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAEb,QAAA,0BAA0B,GAAG,iCAAiC,CAAC;AAE5E,qDAAqD;AACxC,QAAA,0BAA0B,GAAG,IAAI,kCAA0B,GAAG,CAAC;AAE5E,kFAAkF;AACrE,QAAA,qBAAqB,GAAG,EAAE,CAAC,kCAA0B,CAAC,EAAE,IAAI,EAAE,CAAC;AAE5E,+EAA+E;AAC/E,SAAgB,kBAAkB,CAAC,KAA2C;IAC5E,OAAO,uDAAS,KAAK,EAAM,6BAAqB,EAAI,CAAC;AACvD,CAAC;AAFD,gDAEC"}
1
+ {"version":3,"file":"ignore-highlighter.js","sourceRoot":"","sources":["../ignore-highlighter.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,+BAA+B;AAClB,QAAA,0BAA0B,GAAG,iCAAiC,CAAC;AAE5E,sDAAsD;AACzC,QAAA,0BAA0B,GAAG,IAAI,kCAA0B,GAAG,CAAC;AAE5E,4DAA4D;AAC/C,QAAA,qBAAqB,GAAG,EAAE,CAAC,kCAA0B,CAAC,EAAE,IAAI,EAAE,CAAC;AAE5E,6EAA6E;AAC7E,SAAgB,kBAAkB,CAAC,KAA2C;IAC5E,OAAO,uDAAS,KAAK,EAAM,6BAAqB,EAAI,CAAC;AACvD,CAAC;AAFD,gDAEC;AAED,6BAA6B;AAChB,QAAA,uBAAuB,GAAG,+BAA+B,CAAC;AACvE,oEAAoE;AACvD,QAAA,mBAAmB,GAAG,EAAE,CAAC,+BAAuB,CAAC,EAAE,IAAI,EAAE,CAAC;AACvE,oDAAoD;AACvC,QAAA,uBAAuB,GAAG,IAAI,+BAAuB,GAAG,CAAC"}
package/dist/index.d.ts CHANGED
@@ -6,5 +6,5 @@ export { ChildrenHighlighter } from './children-highlighter';
6
6
  export type { ChildrenHighlighterProps } from './children-highlighter';
7
7
  export { ElementHighlighter } from './element-highlighter';
8
8
  export type { ElementHighlighterProps, Placement, HighlightClasses } from './element-highlighter';
9
- export { ExcludeHighlighter, excludeHighlighterAtt, excludeHighlighterSelector, excludeHighlighterAttrName, } from './ignore-highlighter';
9
+ export { ExcludeHighlighter, excludeHighlighterAtt, excludeHighlighterAttrName, skipHighlighterAttr, skipHighlighterAttrName, } from './ignore-highlighter';
10
10
  export type { MatchRule } from './rule-matcher';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.excludeHighlighterAttrName = exports.excludeHighlighterSelector = exports.excludeHighlighterAtt = exports.ExcludeHighlighter = exports.ElementHighlighter = exports.ChildrenHighlighter = exports.HoverHighlighter = exports.ComponentHighlighter = void 0;
3
+ exports.skipHighlighterAttrName = exports.skipHighlighterAttr = exports.excludeHighlighterAttrName = exports.excludeHighlighterAtt = exports.ExcludeHighlighter = exports.ElementHighlighter = exports.ChildrenHighlighter = exports.HoverHighlighter = exports.ComponentHighlighter = void 0;
4
4
  var hybrid_highlighter_1 = require("./hybrid-highlighter");
5
5
  Object.defineProperty(exports, "ComponentHighlighter", { enumerable: true, get: function () { return hybrid_highlighter_1.HybridHighlighter; } });
6
6
  var hover_highlighter_1 = require("./hover-highlighter");
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "ElementHighlighter", { enumerable: true, get: fu
12
12
  var ignore_highlighter_1 = require("./ignore-highlighter");
13
13
  Object.defineProperty(exports, "ExcludeHighlighter", { enumerable: true, get: function () { return ignore_highlighter_1.ExcludeHighlighter; } });
14
14
  Object.defineProperty(exports, "excludeHighlighterAtt", { enumerable: true, get: function () { return ignore_highlighter_1.excludeHighlighterAtt; } });
15
- Object.defineProperty(exports, "excludeHighlighterSelector", { enumerable: true, get: function () { return ignore_highlighter_1.excludeHighlighterSelector; } });
16
15
  Object.defineProperty(exports, "excludeHighlighterAttrName", { enumerable: true, get: function () { return ignore_highlighter_1.excludeHighlighterAttrName; } });
16
+ Object.defineProperty(exports, "skipHighlighterAttr", { enumerable: true, get: function () { return ignore_highlighter_1.skipHighlighterAttr; } });
17
+ Object.defineProperty(exports, "skipHighlighterAttrName", { enumerable: true, get: function () { return ignore_highlighter_1.skipHighlighterAttrName; } });
17
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,2DAAiF;AAAxE,0HAAA,iBAAiB,OAAwB;AAGlD,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AAGzB,+DAA6D;AAApD,2HAAA,mBAAmB,OAAA;AAG5B,6DAA2D;AAAlD,yHAAA,kBAAkB,OAAA;AAG3B,2DAK8B;AAJ5B,wHAAA,kBAAkB,OAAA;AAClB,2HAAA,qBAAqB,OAAA;AACrB,gIAAA,0BAA0B,OAAA;AAC1B,gIAAA,0BAA0B,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,2DAAiF;AAAxE,0HAAA,iBAAiB,OAAwB;AAGlD,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AAGzB,+DAA6D;AAApD,2HAAA,mBAAmB,OAAA;AAG5B,6DAA2D;AAAlD,yHAAA,kBAAkB,OAAA;AAG3B,2DAM8B;AAL5B,wHAAA,kBAAkB,OAAA;AAClB,2HAAA,qBAAqB,OAAA;AACrB,gIAAA,0BAA0B,OAAA;AAC1B,yHAAA,mBAAmB,OAAA;AACnB,6HAAA,uBAAuB,OAAA"}
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const ComponentStripPreview: () => JSX.Element;
@@ -0,0 +1,17 @@
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.ComponentStripPreview = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const component_strip_1 = require("./component-strip");
9
+ const mock_component_1 = require("../mock-component");
10
+ const ComponentStripPreview = () => {
11
+ return (react_1.default.createElement("div", { style: { fontFamily: 'sans-serif', padding: 8 } },
12
+ react_1.default.createElement(component_strip_1.ComponentStrip, { component: mock_component_1.MockSnap }),
13
+ react_1.default.createElement("br", null),
14
+ react_1.default.createElement(component_strip_1.ComponentStrip, { component: mock_component_1.MockButton })));
15
+ };
16
+ exports.ComponentStripPreview = ComponentStripPreview;
17
+ //# sourceMappingURL=component-strip.compositions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-strip.compositions.js","sourceRoot":"","sources":["../../label/component-strip.compositions.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,uDAAmD;AACnD,sDAAyD;AAElD,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,OAAO,CACL,uCAAK,KAAK,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,EAAE;QAClD,8BAAC,gCAAc,IAAC,SAAS,EAAE,yBAAQ,GAAI;QACvC,yCAAM;QACN,8BAAC,gCAAc,IAAC,SAAS,EAAE,2BAAU,GAAI,CACrC,CACP,CAAC;AACJ,CAAC,CAAC;AARW,QAAA,qBAAqB,yBAQhC"}
@@ -37,14 +37,16 @@ exports.ComponentStrip = (0, react_1.forwardRef)(function ComponentStrip({ compo
37
37
  return (react_1.default.createElement("div", { className: component_strip_module_scss_1.default.componentStrip, ref: ref },
38
38
  !parsedId && react_1.default.createElement(LabelBlock, { link: homepage }, id),
39
39
  parsedId && react_1.default.createElement(LabelBlock, { link: component_modules_component_url_1.ScopeUrl.toUrl(parsedId.scope) }, parsedId.scope),
40
- parsedId && (react_1.default.createElement(LabelBlock, { link: componentLink },
41
- parsedId.fullName,
42
- parsedId.version && parsedId.version !== 'latest' && `@${parsedId.version}`)),
40
+ parsedId && (react_1.default.createElement(LabelBlock, { link: componentLink, className: component_strip_module_scss_1.default.nameBlock },
41
+ react_1.default.createElement("span", null, parsedId.fullName),
42
+ parsedId.version && parsedId.version !== 'latest' && (react_1.default.createElement("span", { className: component_strip_module_scss_1.default.version },
43
+ "@",
44
+ parsedId.version)))),
43
45
  children));
44
46
  });
45
- function LabelBlock({ link, children }) {
47
+ function LabelBlock({ link, children, className }) {
46
48
  const Comp = link ? base_ui_routing_native_link_1.NativeLink : 'span';
47
- return (react_1.default.createElement(Comp, { href: link, external: !!link }, children));
49
+ return (react_1.default.createElement(Comp, { href: link, external: !!link, className: className }, children));
48
50
  }
49
51
  function extractMetadata(metadata) {
50
52
  if (typeof metadata === 'string') {
@@ -1 +1 @@
1
- {"version":3,"file":"component-strip.js","sourceRoot":"","sources":["../../label/component-strip.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAA4E;AAC5E,sFAAkE;AAClE,wDAAoD;AACpD,8FAAoE;AACpE,oJAI6E;AAC7E,gGAAmD;AACnD,mCAA4C;AAK/B,QAAA,cAAc,GAAG,IAAA,kBAAU,EAAC,SAAS,cAAc,CAC9D,EAAE,SAAS,EAAE,QAAQ,EAAuB,EAC5C,GAAiC;IAEjC,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAE9D,MAAM,QAAQ,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,0BAAW,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,QAAQ,IAAI,IAAA,yBAAiB,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAExE,OAAO,CACL,uCAAK,SAAS,EAAE,qCAAM,CAAC,cAAc,EAAE,GAAG,EAAE,GAAG;QAC5C,CAAC,QAAQ,IAAI,8BAAC,UAAU,IAAC,IAAI,EAAE,QAAQ,IAAG,EAAE,CAAc;QAC1D,QAAQ,IAAI,8BAAC,UAAU,IAAC,IAAI,EAAE,0CAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAG,QAAQ,CAAC,KAAK,CAAc;QAC3F,QAAQ,IAAI,CACX,8BAAC,UAAU,IAAC,IAAI,EAAE,aAAa;YAC5B,QAAQ,CAAC,QAAQ;YACjB,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,QAAQ,CAAC,OAAO,EAAE,CACjE,CACd;QACA,QAAQ,CACL,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAA0C;IAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,wCAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,CACL,8BAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,IAC/B,QAAQ,CACJ,CACR,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,QAAsC;IAC7D,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;QAChC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KACzC;IAED,OAAO,QAAQ,CAAC,+EAAkB,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"component-strip.js","sourceRoot":"","sources":["../../label/component-strip.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAA4E;AAC5E,sFAAkE;AAClE,wDAAoD;AACpD,8FAAoE;AACpE,oJAI6E;AAC7E,gGAAmD;AACnD,mCAA4C;AAK/B,QAAA,cAAc,GAAG,IAAA,kBAAU,EAAC,SAAS,cAAc,CAC9D,EAAE,SAAS,EAAE,QAAQ,EAAuB,EAC5C,GAAiC;IAEjC,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAE9D,MAAM,QAAQ,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,0BAAW,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,QAAQ,IAAI,IAAA,yBAAiB,EAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAExE,OAAO,CACL,uCAAK,SAAS,EAAE,qCAAM,CAAC,cAAc,EAAE,GAAG,EAAE,GAAG;QAC5C,CAAC,QAAQ,IAAI,8BAAC,UAAU,IAAC,IAAI,EAAE,QAAQ,IAAG,EAAE,CAAc;QAC1D,QAAQ,IAAI,8BAAC,UAAU,IAAC,IAAI,EAAE,0CAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAG,QAAQ,CAAC,KAAK,CAAc;QAC3F,QAAQ,IAAI,CACX,8BAAC,UAAU,IAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,qCAAM,CAAC,SAAS;YAC1D,4CAAO,QAAQ,CAAC,QAAQ,CAAQ;YAC/B,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,CACpD,wCAAM,SAAS,EAAE,qCAAM,CAAC,OAAO;;gBAAI,QAAQ,CAAC,OAAO,CAAQ,CAC5D,CACU,CACd;QACA,QAAQ,CACL,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAA8D;IAC3G,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,wCAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IACxC,OAAO,CACL,8BAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,IACrD,QAAQ,CACJ,CACR,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,QAAsC;IAC7D,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;QAChC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KACzC;IAED,OAAO,QAAQ,CAAC,+EAAkB,CAAC,CAAC;AACtC,CAAC"}
@@ -7,6 +7,7 @@ $gap: 0.125em;
7
7
 
8
8
  border-radius: $borderRadius;
9
9
  box-shadow: var(--bit-highlighter-shadow);
10
+ white-space: nowrap;
10
11
 
11
12
  > * {
12
13
  padding: 0 0.5em;
@@ -47,3 +48,21 @@ $gap: 0.125em;
47
48
  }
48
49
  }
49
50
  }
51
+
52
+ .nameBlock {
53
+ display: flex;
54
+
55
+ .version {
56
+ // leave room for 9 digits + 3 "."
57
+ max-width: 13ch;
58
+ overflow: hidden;
59
+ text-overflow: ellipsis;
60
+ white-space: nowrap;
61
+
62
+ transition: max-width 480ms;
63
+
64
+ &:hover {
65
+ max-width: 61ch;
66
+ }
67
+ }
68
+ }
@@ -39,14 +39,18 @@ const classnames_1 = __importDefault(require("classnames"));
39
39
  const lodash_compact_1 = __importDefault(require("lodash.compact"));
40
40
  const react_dom_1 = require("@floating-ui/react-dom");
41
41
  const label_module_scss_1 = __importDefault(require("./label.module.scss"));
42
+ const HAS_RESIZE_OBSERVER = typeof window !== 'undefined' && !!window.ResizeObserver;
42
43
  function LabelContainer(_a) {
44
+ var _b;
43
45
  var { targetRef, offset, placement, flip = true, watchMotion, className, style } = _a, rest = __rest(_a, ["targetRef", "offset", "placement", "flip", "watchMotion", "className", "style"]);
44
- const { x, y, strategy, floating, reference, refs, update } = (0, react_dom_1.useFloating)({
46
+ const { x, y, strategy, floating, reference, refs, update, middlewareData } = (0, react_dom_1.useFloating)({
45
47
  placement,
46
48
  middleware: (0, lodash_compact_1.default)([
47
49
  offset && (0, react_dom_1.offset)({ mainAxis: offset[0], crossAxis: offset[1] }),
48
50
  flip && (0, react_dom_1.flip)(),
49
- (0, react_dom_1.shift)({ rootBoundary: 'viewport' }),
51
+ // enabling 'shift' for 'crossAxis' will make floating-ui push the label _inside_, when it has nowhere to go
52
+ (0, react_dom_1.shift)({ rootBoundary: 'document', mainAxis: true, crossAxis: true }),
53
+ (0, react_dom_1.hide)({ strategy: 'referenceHidden' }),
50
54
  ]),
51
55
  });
52
56
  (0, react_1.useLayoutEffect)(() => {
@@ -55,12 +59,14 @@ function LabelContainer(_a) {
55
59
  // automatically update on scroll, resize, etc.
56
60
  // `watchMotion` will trigger continuous updates using animation frame
57
61
  (0, react_1.useEffect)(() => {
58
- if (!refs.reference.current || !refs.floating.current)
62
+ if (!refs.reference.current || !refs.floating.current || !HAS_RESIZE_OBSERVER)
59
63
  return () => { };
60
64
  return (0, react_dom_1.autoUpdate)(refs.reference.current, refs.floating.current, update, { animationFrame: !!watchMotion });
61
65
  }, [refs.reference.current, refs.floating.current, update, watchMotion]);
62
- const isReady = x !== null;
63
- return (react_1.default.createElement("div", Object.assign({}, rest, { ref: floating, className: (0, classnames_1.default)(className, !isReady && label_module_scss_1.default.hidden), style: Object.assign(Object.assign({}, style), { position: strategy, top: y !== null && y !== void 0 ? y : '', left: x !== null && x !== void 0 ? x : '' }) })));
66
+ const isReady = !((_b = middlewareData.hide) === null || _b === void 0 ? void 0 : _b.referenceHidden);
67
+ return (react_1.default.createElement("div", Object.assign({}, rest, { ref: floating, className: (0, classnames_1.default)(className, !isReady && label_module_scss_1.default.hidden),
68
+ // starting at pos [0,0] will ensure the label doesn't increase the document size.
69
+ style: Object.assign(Object.assign({}, style), { position: strategy, top: y !== null && y !== void 0 ? y : 0, left: x !== null && x !== void 0 ? x : 0 }) })));
64
70
  }
65
71
  exports.LabelContainer = LabelContainer;
66
72
  //# sourceMappingURL=label-container.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"label-container.js","sourceRoot":"","sources":["../../label/label-container.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAqE;AACrE,4DAAoC;AACpC,oEAAqC;AACrC,sDAMgC;AAEhC,4EAAyC;AAazC,SAAgB,cAAc,CAAC,EAST;QATS,EAC7B,SAAS,EACT,MAAM,EACN,SAAS,EACT,IAAI,GAAG,IAAI,EACX,WAAW,EACX,SAAS,EACT,KAAK,OAEe,EADjB,IAAI,cARsB,iFAS9B,CADQ;IAEP,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAA,uBAAW,EAAC;QACxE,SAAS;QACT,UAAU,EAAE,IAAA,wBAAO,EAAC;YAClB,MAAM,IAAI,IAAA,kBAAgB,EAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,IAAI,IAAI,IAAA,gBAAc,GAAE;YACxB,IAAA,iBAAK,EAAC,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;SACpC,CAAC;KACH,CAAC,CAAC;IAEH,IAAA,uBAAe,EAAC,GAAG,EAAE;QACnB,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAEnC,+CAA+C;IAC/C,sEAAsE;IACtE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAEvE,OAAO,IAAA,sBAAU,EAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9G,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAEzE,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,CAAC;IAE3B,OAAO,CACL,uDACM,IAAI,IACR,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,IAAA,oBAAU,EAAC,SAAS,EAAE,CAAC,OAAO,IAAI,2BAAM,CAAC,MAAM,CAAC,EAC3D,KAAK,kCAAO,KAAK,KAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,EAAE,EAAE,IAAI,EAAE,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,EAAE,OAClE,CACH,CAAC;AACJ,CAAC;AAzCD,wCAyCC"}
1
+ {"version":3,"file":"label-container.js","sourceRoot":"","sources":["../../label/label-container.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAqE;AACrE,4DAAoC;AACpC,oEAAqC;AACrC,sDAOgC;AAEhC,4EAAyC;AAEzC,MAAM,mBAAmB,GAAG,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC;AAarF,SAAgB,cAAc,CAAC,EAST;;QATS,EAC7B,SAAS,EACT,MAAM,EACN,SAAS,EACT,IAAI,GAAG,IAAI,EACX,WAAW,EACX,SAAS,EACT,KAAK,OAEe,EADjB,IAAI,cARsB,iFAS9B,CADQ;IAEP,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,IAAA,uBAAW,EAAC;QACxF,SAAS;QACT,UAAU,EAAE,IAAA,wBAAO,EAAC;YAClB,MAAM,IAAI,IAAA,kBAAgB,EAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,IAAI,IAAI,IAAA,gBAAc,GAAE;YACxB,4GAA4G;YAC5G,IAAA,iBAAK,EAAC,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;YACpE,IAAA,gBAAI,EAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;SACtC,CAAC;KACH,CAAC,CAAC;IAEH,IAAA,uBAAe,EAAC,GAAG,EAAE;QACnB,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAEnC,+CAA+C;IAC/C,sEAAsE;IACtE,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,mBAAmB;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAE/F,OAAO,IAAA,sBAAU,EAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9G,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAEzE,MAAM,OAAO,GAAG,CAAC,CAAA,MAAA,cAAc,CAAC,IAAI,0CAAE,eAAe,CAAA,CAAC;IAEtD,OAAO,CACL,uDACM,IAAI,IACR,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,IAAA,oBAAU,EAAC,SAAS,EAAE,CAAC,OAAO,IAAI,2BAAM,CAAC,MAAM,CAAC;QAC3D,kFAAkF;QAClF,KAAK,kCAAO,KAAK,KAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,CAAC,EAAE,IAAI,EAAE,CAAC,aAAD,CAAC,cAAD,CAAC,GAAI,CAAC,OAChE,CACH,CAAC;AACJ,CAAC;AA5CD,wCA4CC"}
@@ -24,6 +24,8 @@
24
24
  }
25
25
 
26
26
  .hidden {
27
+ // label size is needed for position calculations,
28
+ // so it can't be removed by `display: none`
27
29
  visibility: hidden;
28
30
  pointer-events: none;
29
31
  user-select: none;
@@ -1,2 +1,4 @@
1
- import { PropsWithChildren } from 'react';
2
- export declare function MockTarget({ children, ...rest }: PropsWithChildren<{}>): JSX.Element;
1
+ import { ButtonHTMLAttributes, HTMLAttributes } from 'react';
2
+ export declare function MockTarget({ children, ...rest }: HTMLAttributes<HTMLDivElement>): JSX.Element;
3
+ export declare function MockButton({ children, ...rest }: ButtonHTMLAttributes<HTMLButtonElement>): JSX.Element;
4
+ export declare function MockSnap({ children, ...rest }: ButtonHTMLAttributes<HTMLButtonElement>): JSX.Element;
@@ -14,17 +14,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.MockTarget = void 0;
17
+ exports.MockSnap = exports.MockButton = exports.MockTarget = void 0;
18
18
  const react_1 = __importDefault(require("react"));
19
19
  const react_ui_highlighter_component_metadata_bit_component_meta_1 = require("@teambit/react.ui.highlighter.component-metadata.bit-component-meta");
20
20
  function MockTarget(_a) {
21
21
  var { children } = _a, rest = __rest(_a, ["children"]);
22
- return react_1.default.createElement("div", Object.assign({}, rest),
23
- "mocked ",
24
- children);
22
+ return react_1.default.createElement("div", Object.assign({}, rest), children);
25
23
  }
26
24
  exports.MockTarget = MockTarget;
27
25
  MockTarget[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField] = {
26
+ id: 'teambit.design/ui/mock-target@1.6.2',
27
+ };
28
+ function MockButton(_a) {
29
+ var { children } = _a, rest = __rest(_a, ["children"]);
30
+ return react_1.default.createElement("button", Object.assign({}, rest), children);
31
+ }
32
+ exports.MockButton = MockButton;
33
+ MockButton[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField] = {
28
34
  id: 'teambit.design/ui/icon-button@1.6.2',
29
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
+ exports.MockSnap = MockSnap;
41
+ MockSnap[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField] = {
42
+ id: 'teambit.design/ui/icon-button@a21594d5cc63fd24d2b4763fa7d817b131f0edbb',
43
+ };
30
44
  //# sourceMappingURL=mock-component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mock-component.js","sourceRoot":"","sources":["../mock-component.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAAiD;AACjD,oJAAyG;AAEzG,SAAgB,UAAU,CAAC,EAA4C;QAA5C,EAAE,QAAQ,OAAkC,EAA7B,IAAI,cAAnB,YAAqB,CAAF;IAC5C,OAAO,uDAAS,IAAI;;QAAU,QAAQ,CAAO,CAAC;AAChD,CAAC;AAFD,gCAEC;AACD,UAAU,CAAC,+EAAkB,CAAC,GAAG;IAC/B,EAAE,EAAE,qCAAqC;CAC1C,CAAC"}
1
+ {"version":3,"file":"mock-component.js","sourceRoot":"","sources":["../mock-component.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,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;AAFD,gCAEC;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;AAFD,gCAEC;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;AAFD,4BAEC;AACD,QAAQ,CAAC,+EAAkB,CAAC,GAAG;IAC7B,EAAE,EAAE,wEAAwE;CAC5D,CAAC"}
@@ -0,0 +1,32 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": [
4
+ "es2019",
5
+ "DOM",
6
+ "ES6",
7
+ "DOM.Iterable"
8
+ ],
9
+ "target": "es2015",
10
+ "module": "CommonJS",
11
+ "jsx": "react",
12
+ "allowJs": true,
13
+ "composite": true,
14
+ "declaration": true,
15
+ "sourceMap": true,
16
+ "skipLibCheck": true,
17
+ "experimentalDecorators": true,
18
+ "outDir": "dist",
19
+ "moduleResolution": "node",
20
+ "esModuleInterop": true,
21
+ "rootDir": ".",
22
+ "resolveJsonModule": true
23
+ },
24
+ "exclude": [
25
+ "dist",
26
+ "package.json"
27
+ ],
28
+ "include": [
29
+ "**/*",
30
+ "**/*.json"
31
+ ]
32
+ }
@@ -67,16 +67,64 @@ export const MovingElement = () => {
67
67
  return <HighlightedElement targetStyle={{ marginLeft: margin }} watchMotion />;
68
68
  };
69
69
 
70
- export const ElementOnTheEdge = () => {
70
+ export const FullscreenElement = () => {
71
71
  const targetRef = createRef<HTMLDivElement>();
72
72
 
73
73
  return (
74
74
  <div style={{ fontFamily: 'sans-serif' }}>
75
- <div ref={targetRef} style={{ width: '100%', border: '1px solid black', boxSizing: 'border-box' }}>
76
- This element is on the edge of the document, making the highlighter overflow. <br />
77
- It should instead shrink to fit inside the document.
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.
78
88
  </div>
79
89
  <ElementHighlighter targetRef={targetRef} components={[MockTarget]} watchMotion />
80
90
  </div>
81
91
  );
82
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
+ }
@@ -3,7 +3,7 @@ import classnames from 'classnames';
3
3
  import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
4
4
  import { Frame } from '../frame';
5
5
  import { Label, LabelContainer, Placement } from '../label';
6
- import { excludeHighlighterAtt } from '../ignore-highlighter';
6
+ import { skipHighlighterAttr } from '../ignore-highlighter';
7
7
  import styles from './element-highlighter.module.scss';
8
8
 
9
9
  export interface ElementHighlighterProps extends React.HTMLAttributes<HTMLDivElement> {
@@ -38,7 +38,7 @@ export function ElementHighlighter({
38
38
  ...props
39
39
  }: ElementHighlighterProps) {
40
40
  return (
41
- <div {...props} {...excludeHighlighterAtt} className={classnames(classes?.container, styles.container, className)}>
41
+ <div {...props} {...skipHighlighterAttr} className={classnames(classes?.container, styles.container, className)}>
42
42
  <Frame targetRef={targetRef} className={classnames(styles.frame, classes?.frame)} watchMotion={watchMotion} />
43
43
 
44
44
  {components && (
package/frame/frame.tsx CHANGED
@@ -1,6 +1,6 @@
1
- import React, { useEffect, useLayoutEffect, useRef, RefObject } from 'react';
1
+ import React, { useEffect, useLayoutEffect, useRef, RefObject, CSSProperties } from 'react';
2
2
  import classnames from 'classnames';
3
- import { useFloating, autoUpdate, offset, size, shift } from '@floating-ui/react-dom';
3
+ import { useFloating, autoUpdate, offset, size, detectOverflow, hide } from '@floating-ui/react-dom';
4
4
  import type { Coords } from '@floating-ui/react-dom';
5
5
 
6
6
  import styles from './frame.module.scss';
@@ -10,6 +10,11 @@ const MARGIN_FROM_TARGET = +styles.offset || 6; // setting fallback 6, for tests
10
10
  /** min. distance from the edge of the screen. */
11
11
  const MARGIN_FROM_DOC_EDGE = 0;
12
12
 
13
+ const overflowParameters = { rootBoundary: 'document', padding: MARGIN_FROM_DOC_EDGE } as const;
14
+ const SHIFT_POSITIVE = 'shiftPositive';
15
+
16
+ const HAS_RESIZE_OBSERVER = typeof window !== 'undefined' && !!window.ResizeObserver;
17
+
13
18
  export interface FrameProps extends React.HTMLAttributes<HTMLDivElement> {
14
19
  /** apply the frame to this element */
15
20
  targetRef: RefObject<HTMLElement | null>;
@@ -26,11 +31,12 @@ export interface FrameProps extends React.HTMLAttributes<HTMLDivElement> {
26
31
  // x - width - horizontal (cross axis)
27
32
  // y - height - vertical (main axis)
28
33
 
34
+ type DimensionsStyle = Pick<CSSProperties, 'width' | 'height' | 'maxWidth' | 'maxHeight'>;
35
+
29
36
  export function Frame({ targetRef, watchMotion, className, stylesClass = styles.overlayBorder, style }: FrameProps) {
30
- const dimensionRef = useRef({ width: 0, height: 0 });
31
- const shiftRef = useRef<Coords | undefined>();
37
+ const dimensionRef = useRef<DimensionsStyle>({ width: 0, height: 0 });
32
38
 
33
- const { x, y, strategy, reference, floating, update, refs } = useFloating({
39
+ const { x, y, strategy, reference, floating, update, refs, middlewareData } = useFloating({
34
40
  placement: 'bottom-start',
35
41
  middleware: [
36
42
  // replace dimensions from previous iterations with the target's size
@@ -48,17 +54,28 @@ export function Frame({ targetRef, watchMotion, className, stylesClass = styles.
48
54
  },
49
55
  },
50
56
  // reposition x,y, to the top of the reference
51
- offset((options) => -options.reference.height),
57
+ offset(({ rects }) => -rects.reference.height),
52
58
  // offset the frame by its extra padding
53
59
  offset(() => ({ mainAxis: -MARGIN_FROM_TARGET, crossAxis: -MARGIN_FROM_TARGET })),
54
- // push the frame inside the screen
55
- shift({ rootBoundary: 'document', padding: MARGIN_FROM_DOC_EDGE, mainAxis: true, crossAxis: true }),
56
- // read "shift" for the size-apply() method (because it doesn't forward middlewareData)
60
+ // pushes the frame into the document. Similar to shift(), but only pushes when coods are negative
57
61
  {
58
- name: 'read-shift',
59
- fn({ middlewareData }) {
60
- shiftRef.current = middlewareData.shift;
61
- return {};
62
+ name: 'shiftPositive',
63
+ fn: async (args) => {
64
+ const overflow = await detectOverflow(args, overflowParameters);
65
+
66
+ const nextCoords = {
67
+ x: overflow.left > 0 ? args.x + overflow.left : args.x,
68
+ y: overflow.top > 0 ? args.y + overflow.top : args.y,
69
+ };
70
+ const shiftAmount = {
71
+ x: nextCoords.x - args.x,
72
+ y: nextCoords.y - args.y,
73
+ };
74
+
75
+ return {
76
+ ...nextCoords,
77
+ data: shiftAmount,
78
+ };
62
79
  },
63
80
  },
64
81
  // size also applies overflow detection via width and height
@@ -66,17 +83,26 @@ export function Frame({ targetRef, watchMotion, className, stylesClass = styles.
66
83
  // apply overflow detection in reference to the document
67
84
  rootBoundary: 'document',
68
85
  padding: MARGIN_FROM_DOC_EDGE,
69
- apply({ reference: referenceRect, height, width }) {
70
- const paddingX = 2 * MARGIN_FROM_TARGET - (shiftRef.current?.x || 0);
71
- const paddingY = 2 * MARGIN_FROM_TARGET - (shiftRef.current?.y || 0);
86
+ apply({ elements, rects, availableHeight, availableWidth, middlewareData }) {
87
+ const shift: Coords = middlewareData[SHIFT_POSITIVE] || { x: 0, y: 0 };
88
+ const paddingX = 2 * MARGIN_FROM_TARGET - shift.x;
89
+ const paddingY = 2 * MARGIN_FROM_TARGET - shift.y;
72
90
 
73
- dimensionRef.current = {
74
- width: Math.min(referenceRect.width + paddingX, width),
75
- height: Math.min(referenceRect.height + paddingY, height),
91
+ const dimensions: DimensionsStyle = {
92
+ width: rects.reference.width + paddingX,
93
+ height: rects.reference.height + paddingY,
94
+ maxWidth: availableWidth,
95
+ maxHeight: availableHeight,
76
96
  };
77
- Object.assign(refs.floating.current?.style, dimensionRef.current);
97
+
98
+ // per floating-ui docs, apply styles directly during apply()
99
+ Object.assign(elements.floating.style, dimensions);
100
+
101
+ // also store in reference, so react renders will have the same value
102
+ dimensionRef.current = dimensions;
78
103
  },
79
104
  }),
105
+ hide({ strategy: 'referenceHidden' }),
80
106
  ],
81
107
  });
82
108
 
@@ -88,12 +114,13 @@ export function Frame({ targetRef, watchMotion, className, stylesClass = styles.
88
114
  // automatically update on scroll, resize, etc.
89
115
  // `watchMotion` will trigger continuous updates using animation frame
90
116
  useEffect(() => {
91
- if (!refs.reference.current || !refs.floating.current) return () => {};
117
+ if (!refs.reference.current || !refs.floating.current || !HAS_RESIZE_OBSERVER) return () => {};
92
118
 
93
119
  return autoUpdate(refs.reference.current, refs.floating.current, update, { animationFrame: watchMotion });
94
120
  }, [refs.reference.current, refs.floating.current, update, watchMotion]);
95
121
 
96
- const isReady = x !== null;
122
+ // could check if x !== null
123
+ const isReady = !middlewareData.hide?.referenceHidden;
97
124
 
98
125
  return (
99
126
  <div
@@ -103,8 +130,9 @@ export function Frame({ targetRef, watchMotion, className, stylesClass = styles.
103
130
  ...style,
104
131
  ...dimensionRef.current,
105
132
  position: strategy,
106
- top: y ?? '',
107
- left: x ?? '',
133
+ // starting at pos [0,0] will ensure the label doesn't increase the document size.
134
+ top: y ?? 0,
135
+ left: x ?? 0,
108
136
  }}
109
137
  />
110
138
  );
@@ -1,6 +1,7 @@
1
- import React, { useState } from 'react';
2
- import { IconButton } from '@teambit/design.ui.icon-button';
1
+ import React, { useEffect, useState } from 'react';
3
2
  import { HoverHighlighter } from './hover-highlighter';
3
+ import { MockButton, MockTarget } from '../mock-component';
4
+ import { excludeHighlighterAtt } from '../ignore-highlighter';
4
5
 
5
6
  export const ShowWhenHovering = () => {
6
7
  const [disabled, setDisabled] = useState<boolean>(false);
@@ -11,7 +12,7 @@ export const ShowWhenHovering = () => {
11
12
  <div>
12
13
  <br />
13
14
  <div>
14
- <IconButton onClick={() => setDisabled((x) => !x)}>Hover here</IconButton>
15
+ <MockButton onClick={() => setDisabled((x) => !x)}>Hover here</MockButton>
15
16
  </div>
16
17
  <div>
17
18
  {disabled ? 'X' : '✓'} highlighter is {disabled ? 'disabled' : 'enabled'}
@@ -21,3 +22,44 @@ export const ShowWhenHovering = () => {
21
22
  </div>
22
23
  );
23
24
  };
25
+
26
+ export const UnmountingElement = () => {
27
+ const [shown, setShown] = useState(true);
28
+ useEffect(() => {
29
+ const tid = setInterval(() => setShown((x) => !x), 1500);
30
+ return () => clearInterval(tid);
31
+ }, []);
32
+
33
+ return (
34
+ <div style={{ padding: '16px 50px 32px 16px', minWidth: 300, fontFamily: 'sans-serif' }}>
35
+ <HoverHighlighter>
36
+ <div>{!shown && '(hidden)'}</div>
37
+
38
+ <div>{shown && <MockButton>Hover here</MockButton>}</div>
39
+ <br />
40
+ <MockTarget>
41
+ <div>{shown && <MockButton>Hover here</MockButton>}</div>
42
+ <div>same with a container</div>
43
+ </MockTarget>
44
+ </HoverHighlighter>
45
+ </div>
46
+ );
47
+ };
48
+
49
+ export const HoverExclusionZones = () => {
50
+ return (
51
+ <div style={{ padding: '16px 50px 32px 16px', minWidth: 300, fontFamily: 'sans-serif' }}>
52
+ <HoverHighlighter>
53
+ <MockTarget>
54
+ container (target-able)
55
+ <div>{<MockButton>will be highlighted</MockButton>}</div>
56
+ </MockTarget>
57
+ <br />
58
+ <MockTarget>
59
+ container (target-able)
60
+ <div {...excludeHighlighterAtt}>{<MockButton>will be ignored</MockButton>}</div>
61
+ </MockTarget>
62
+ </HoverHighlighter>
63
+ </div>
64
+ );
65
+ };
@@ -3,7 +3,7 @@ import { useDebouncedCallback } from 'use-debounce';
3
3
  import { useHoverSelection } from '@teambit/react.ui.hover-selector';
4
4
  import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
5
5
 
6
- import { excludeHighlighterSelector } from '../ignore-highlighter';
6
+ import { excludeHighlighterSelector, skipHighlighterSelector } from '../ignore-highlighter';
7
7
  import { MatchRule, ComponentMatchRule } from '../rule-matcher';
8
8
  import { bubbleToComponent } from './bubble-to-component';
9
9
 
@@ -56,8 +56,14 @@ function useHoverHandler({
56
56
  return;
57
57
  }
58
58
 
59
- // skip DOM trees having 'data-ignore-component-highlight'
60
- if (element.closest(`.${scopeClass} ${excludeHighlighterSelector}`)) return;
59
+ // clear when ancestor has 'data-ignore-component-highlight'
60
+ if (element.closest(`.${scopeClass} ${excludeHighlighterSelector}`)) {
61
+ onChange(undefined);
62
+ return;
63
+ }
64
+
65
+ // skip DOM trees having 'data-skip-component-highlight'
66
+ if (element.closest(`.${scopeClass} ${skipHighlighterSelector}`)) return;
61
67
 
62
68
  const result = bubbleToComponent(element, { elementRule: rule, componentRule });
63
69
  if (!result) return;