@teambit/react.ui.component-highlighter 0.0.510 → 0.0.513
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/children-highlighter/use-children-highlighter.tsx +5 -3
- package/component-highlighter.docs.md +3 -14
- package/dist/children-highlighter/use-children-highlighter.d.ts +7 -2
- package/dist/children-highlighter/use-children-highlighter.js.map +1 -1
- package/dist/component-highlighter.docs.md +3 -14
- package/dist/element-highlighter/element-highlighter.compositions.d.ts +1 -0
- package/dist/element-highlighter/element-highlighter.compositions.js +17 -17
- package/dist/element-highlighter/element-highlighter.compositions.js.map +1 -1
- package/dist/element-highlighter/element-highlighter.d.ts +6 -10
- package/dist/element-highlighter/element-highlighter.js +4 -4
- package/dist/element-highlighter/element-highlighter.js.map +1 -1
- package/dist/element-highlighter/index.d.ts +1 -1
- package/dist/frame/frame.d.ts +8 -4
- package/dist/frame/frame.js +67 -31
- package/dist/frame/frame.js.map +1 -1
- package/dist/frame/frame.module.scss +8 -1
- package/dist/hover-highlighter/bubble-to-component.d.ts +19 -0
- package/dist/hover-highlighter/bubble-to-component.js +43 -0
- package/dist/hover-highlighter/bubble-to-component.js.map +1 -0
- package/dist/hover-highlighter/bubble-to-component.spec.d.ts +1 -0
- package/dist/hover-highlighter/bubble-to-component.spec.js +38 -0
- package/dist/hover-highlighter/bubble-to-component.spec.js.map +1 -0
- package/dist/hover-highlighter/use-hover-highlighter.d.ts +6 -1
- package/dist/hover-highlighter/use-hover-highlighter.js +2 -23
- package/dist/hover-highlighter/use-hover-highlighter.js.map +1 -1
- package/dist/hybrid-highlighter/hybrid-highlighter.js +1 -1
- package/dist/hybrid-highlighter/hybrid-highlighter.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/label/component-strip.d.ts +1 -1
- package/dist/label/component-strip.js +7 -1
- package/dist/label/component-strip.js.map +1 -1
- package/dist/label/label-container.d.ts +4 -5
- package/dist/label/label-container.js +26 -13
- package/dist/label/label-container.js.map +1 -1
- package/dist/label/label.d.ts +1 -1
- package/dist/label/label.module.scss +6 -0
- package/dist/label/other-components.d.ts +1 -1
- package/dist/mock-component.d.ts +2 -0
- package/dist/mock-component.js +30 -0
- package/dist/mock-component.js.map +1 -0
- package/element-highlighter/element-highlighter.compositions.tsx +29 -19
- package/element-highlighter/element-highlighter.tsx +13 -25
- package/element-highlighter/index.ts +1 -1
- package/frame/frame.module.scss +8 -1
- package/frame/frame.tsx +91 -44
- package/hover-highlighter/bubble-to-component.spec.tsx +57 -0
- package/hover-highlighter/bubble-to-component.tsx +69 -0
- package/hover-highlighter/use-hover-highlighter.tsx +5 -36
- package/hybrid-highlighter/hybrid-highlighter.tsx +7 -2
- package/index.ts +1 -1
- package/label/component-strip.tsx +11 -2
- package/label/label-container.tsx +40 -20
- package/label/label.module.scss +6 -0
- package/label/label.tsx +1 -1
- package/label/other-components.tsx +1 -1
- package/mock-component.tsx +9 -0
- package/package-tar/teambit-react.ui.component-highlighter-0.0.513.tgz +0 -0
- package/package.json +8 -9
- package/{__preview-1645365357220.js → preview-1649042627943.js} +2 -2
- package/dist/use-animation-frame.d.ts +0 -1
- package/dist/use-animation-frame.js +0 -23
- package/dist/use-animation-frame.js.map +0 -1
- package/package-tar/teambit-react.ui.component-highlighter-0.0.510.tgz +0 -0
- package/use-animation-frame.tsx +0 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hover-highlighter.js","sourceRoot":"","sources":["../../hover-highlighter/use-hover-highlighter.tsx"],"names":[],"mappings":";;;AAAA,iCAAyC;AACzC,+CAAoD;AACpD,
|
|
1
|
+
{"version":3,"file":"use-hover-highlighter.js","sourceRoot":"","sources":["../../hover-highlighter/use-hover-highlighter.tsx"],"names":[],"mappings":";;;AAAA,iCAAyC;AACzC,+CAAoD;AACpD,8EAAqE;AAGrE,8DAAmE;AAEnE,+DAA0D;AAa1D,oDAAoD;AACpD,SAAgB,mBAAmB,CACjC,QAA4C,EAC5C,QAAiC,EAAE,EACnC,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAA8B;IAE3F,MAAM,EAAE,aAAa,EAAE,GAAG,eAAe,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;IAErH,MAAM,QAAQ,GAAG,IAAA,2CAAiB,EAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAEhF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAVD,kDAUC;AAWD,SAAS,eAAe,CAAC,EACvB,QAAQ,EACR,UAAU,GAAG,EAAE,EACf,gBAAgB,EAChB,QAAQ,EACR,IAAI,EACJ,aAAa,GACY;IACzB,yDAAyD;IACzD,MAAM,cAAc,GAAG,CAAC,OAA2B,EAAE,EAAE;QACrD,kCAAkC;QAClC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC,kCAAkC,CAAC,EAAE;YACxE,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpB,OAAO;SACR;QAED,0DAA0D;QAC1D,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,UAAU,IAAI,+CAA0B,EAAE,CAAC;YAAE,OAAO;QAE5E,MAAM,MAAM,GAAG,IAAA,uCAAiB,EAAC,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QAChF,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,QAAQ,CAAC;YACP,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,IAAA,mCAAoB,EAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAE7E,uBAAuB;IACvB,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,QAAQ;YAAE,aAAa,CAAC,MAAM,EAAE,CAAC;IACvC,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;IAE9B,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -70,7 +70,7 @@ function HybridHighlighter(_a) {
|
|
|
70
70
|
const _styles = (0, react_1.useMemo)(() => (Object.assign({ '--bit-highlighter-color': bgColor, '--bit-highlighter-color-hover': bgColorHover, '--bit-highlighter-color-active': bgColorActive }, style)), [bgColor, bgColorHover, bgColorActive, style]);
|
|
71
71
|
return (react_1.default.createElement("div", Object.assign({ ref: ref }, rest, handlers, { style: _styles, className: (0, classnames_1.default)(className, scopeClass), "data-nullify-component-highlight": true }),
|
|
72
72
|
children,
|
|
73
|
-
Object.entries(targets).map(([key, target]) => (react_1.default.createElement(element_highlighter_1.ElementHighlighter, { key: key, target: target, classes: classes, style: highlightStyle, placement: placement, watchMotion: watchMotion })))));
|
|
73
|
+
Object.entries(targets).map(([key, target]) => (react_1.default.createElement(element_highlighter_1.ElementHighlighter, { key: key, targetRef: { current: target.element }, components: target.components, classes: classes, style: highlightStyle, placement: placement, watchMotion: watchMotion })))));
|
|
74
74
|
}
|
|
75
75
|
exports.HybridHighlighter = HybridHighlighter;
|
|
76
76
|
//# sourceMappingURL=hybrid-highlighter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid-highlighter.js","sourceRoot":"","sources":["../../hybrid-highlighter/hybrid-highlighter.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAA8F;AAC9F,4DAAoC;AACpC,+BAA0B;
|
|
1
|
+
{"version":3,"file":"hybrid-highlighter.js","sourceRoot":"","sources":["../../hybrid-highlighter/hybrid-highlighter.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAA8F;AAC9F,4DAAoC;AACpC,+BAA0B;AAI1B,4DAA2D;AAC3D,gEAAyF;AACzF,kEAAiE;AAuCjE,kDAAkD;AAClD,SAAgB,iBAAiB,CAAC,EAkBT;QAlBS,EAChC,QAAQ,EACR,IAAI,GAAG,OAAO,EACd,iBAAiB,GAAG,EAAE,EACtB,WAAW,GAAG,IAAI,EAClB,SAAS,EACT,IAAI,EACJ,aAAa,EAEb,OAAO,EACP,cAAc,EACd,SAAS,EACT,KAAK,EACL,OAAO,EACP,YAAY,EACZ,aAAa,EACb,QAAQ,OAEe,EADpB,IAAI,cAjByB,yMAkBjC,CADQ;IAEP,MAAM,GAAG,GAAG,IAAA,iBAAS,GAAkB,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAAkC,EAAE,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,IAAA,cAAM,EAAC,YAAY,IAAA,SAAE,GAAE,EAAE,CAAC,CAAC,OAAO,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAEtD,8BAA8B;IAC9B,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,QAAQ;YAAE,SAAS,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,MAAM,QAAQ,GAAG,IAAA,uCAAmB,EAClC,CAAC,UAAU,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAC3E,IAAI,EACJ;QACE,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;QACpD,UAAU;QACV,QAAQ,EAAE,QAAQ,IAAI,IAAI,KAAK,OAAO;QACtC,IAAI;QACJ,aAAa;KACd,CACF,CAAC;IAEF,IAAA,6CAAsB,EAAC;QACrB,QAAQ,EAAE,SAAS;QACnB,QAAQ,EAAE,GAAG;QACb,UAAU;QACV,QAAQ,EAAE,QAAQ,IAAI,IAAI,KAAK,aAAa;QAC5C,IAAI;QACJ,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAA,eAAO,EACrB,GAAG,EAAE,CAAC,iBACJ,yBAAyB,EAAE,OAAO,EAClC,+BAA+B,EAAE,YAAY,EAC7C,gCAAgC,EAAE,aAAa,IAC5C,KAAK,EACR,EACF,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,CAAC,CAC9C,CAAC;IAEF,OAAO,CACL,qDACE,GAAG,EAAE,GAAG,IACJ,IAAI,EACJ,QAAQ,IACZ,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,IAAA,oBAAU,EAAC,SAAS,EAAE,UAAU,CAAC;QAG3C,QAAQ;QAKR,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAC9C,8BAAC,wCAAkB,IACjB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,EACtC,UAAU,EAAE,MAAM,CAAC,UAAU,EAC7B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,GACxB,CACH,CAAC,CACE,CACP,CAAC;AACJ,CAAC;AAvFD,8CAuFC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ export type { HoverHighlighterProps } from './hover-highlighter';
|
|
|
5
5
|
export { ChildrenHighlighter } from './children-highlighter';
|
|
6
6
|
export type { ChildrenHighlighterProps } from './children-highlighter';
|
|
7
7
|
export { ElementHighlighter } from './element-highlighter';
|
|
8
|
-
export type { ElementHighlighterProps,
|
|
8
|
+
export type { ElementHighlighterProps, Placement, HighlightClasses } from './element-highlighter';
|
|
9
9
|
export { ExcludeHighlighter, excludeHighlighterAtt, excludeHighlighterSelector, excludeHighlighterAttrName, } from './ignore-highlighter';
|
|
10
10
|
export type { MatchRule } from './rule-matcher';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
|
|
3
3
|
interface ComponentStripProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
-
component: ComponentMetaHolder;
|
|
4
|
+
component: ComponentMetaHolder | string;
|
|
5
5
|
}
|
|
6
6
|
export declare const ComponentStrip: React.ForwardRefExoticComponent<ComponentStripProps & React.RefAttributes<HTMLDivElement>>;
|
|
7
7
|
export {};
|
|
@@ -31,7 +31,7 @@ const react_ui_highlighter_component_metadata_bit_component_meta_1 = require("@t
|
|
|
31
31
|
const component_strip_module_scss_1 = __importDefault(require("./component-strip.module.scss"));
|
|
32
32
|
const links_1 = require("./links");
|
|
33
33
|
exports.ComponentStrip = (0, react_1.forwardRef)(function ComponentStrip({ component, children }, ref) {
|
|
34
|
-
const { id, homepage, exported } = component
|
|
34
|
+
const { id, homepage, exported } = extractMetadata(component);
|
|
35
35
|
const parsedId = (0, react_1.useMemo)(() => component_id_1.ComponentID.tryFromString(id), [id]);
|
|
36
36
|
const componentLink = homepage || (0, links_1.calcComponentLink)(parsedId, exported);
|
|
37
37
|
return (react_1.default.createElement("div", { className: component_strip_module_scss_1.default.componentStrip, ref: ref },
|
|
@@ -46,4 +46,10 @@ function LabelBlock({ link, children }) {
|
|
|
46
46
|
const Comp = link ? base_ui_routing_native_link_1.NativeLink : 'span';
|
|
47
47
|
return (react_1.default.createElement(Comp, { href: link, external: !!link }, children));
|
|
48
48
|
}
|
|
49
|
+
function extractMetadata(metadata) {
|
|
50
|
+
if (typeof metadata === 'string') {
|
|
51
|
+
return { id: metadata, exported: true };
|
|
52
|
+
}
|
|
53
|
+
return metadata[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField];
|
|
54
|
+
}
|
|
49
55
|
//# sourceMappingURL=component-strip.js.map
|
|
@@ -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,
|
|
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,8 +1,7 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { Placement } from '@
|
|
3
|
-
import '@popperjs/core';
|
|
1
|
+
import React, { RefObject } from 'react';
|
|
2
|
+
import type { Placement } from '@floating-ui/react-dom';
|
|
4
3
|
export interface LabelContainerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
-
targetRef: HTMLElement | null
|
|
4
|
+
targetRef: RefObject<HTMLElement | null>;
|
|
6
5
|
offset?: [number, number];
|
|
7
6
|
placement?: Placement;
|
|
8
7
|
flip?: boolean;
|
|
@@ -10,4 +9,4 @@ export interface LabelContainerProps extends React.HTMLAttributes<HTMLDivElement
|
|
|
10
9
|
watchMotion?: boolean;
|
|
11
10
|
}
|
|
12
11
|
export type { Placement };
|
|
13
|
-
export declare function LabelContainer({ targetRef, offset, placement, flip, watchMotion, className, ...rest }: LabelContainerProps): JSX.Element;
|
|
12
|
+
export declare function LabelContainer({ targetRef, offset, placement, flip, watchMotion, className, style, ...rest }: LabelContainerProps): JSX.Element;
|
|
@@ -29,25 +29,38 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
29
29
|
}
|
|
30
30
|
return t;
|
|
31
31
|
};
|
|
32
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34
|
+
};
|
|
32
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
36
|
exports.LabelContainer = void 0;
|
|
34
37
|
const react_1 = __importStar(require("react"));
|
|
35
|
-
const
|
|
36
|
-
require("
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
39
|
+
const lodash_compact_1 = __importDefault(require("lodash.compact"));
|
|
40
|
+
const react_dom_1 = require("@floating-ui/react-dom");
|
|
41
|
+
const label_module_scss_1 = __importDefault(require("./label.module.scss"));
|
|
39
42
|
function LabelContainer(_a) {
|
|
40
|
-
var { targetRef, offset, placement, flip = true, watchMotion, className } = _a, rest = __rest(_a, ["targetRef", "offset", "placement", "flip", "watchMotion", "className"]);
|
|
41
|
-
const
|
|
42
|
-
const modifiers = (0, react_1.useMemo)(() => [{ name: 'offset', options: { offset } }], [flip, offset]);
|
|
43
|
-
const { styles, attributes, update } = (0, react_popper_1.usePopper)(targetRef, sourceRef, {
|
|
44
|
-
modifiers,
|
|
43
|
+
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)({
|
|
45
45
|
placement,
|
|
46
|
+
middleware: (0, lodash_compact_1.default)([
|
|
47
|
+
offset && (0, react_dom_1.offset)({ mainAxis: offset[0], crossAxis: offset[1] }),
|
|
48
|
+
flip && (0, react_dom_1.flip)(),
|
|
49
|
+
(0, react_dom_1.shift)({ rootBoundary: 'viewport' }),
|
|
50
|
+
]),
|
|
46
51
|
});
|
|
47
|
-
(0,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
53
|
+
reference(targetRef.current);
|
|
54
|
+
}, [targetRef.current, reference]);
|
|
55
|
+
// automatically update on scroll, resize, etc.
|
|
56
|
+
// `watchMotion` will trigger continuous updates using animation frame
|
|
57
|
+
(0, react_1.useEffect)(() => {
|
|
58
|
+
if (!refs.reference.current || !refs.floating.current)
|
|
59
|
+
return () => { };
|
|
60
|
+
return (0, react_dom_1.autoUpdate)(refs.reference.current, refs.floating.current, update, { animationFrame: !!watchMotion });
|
|
61
|
+
}, [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 : '' }) })));
|
|
51
64
|
}
|
|
52
65
|
exports.LabelContainer = LabelContainer;
|
|
53
66
|
//# sourceMappingURL=label-container.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label-container.js","sourceRoot":"","sources":["../../label/label-container.tsx"],"names":[],"mappings":"
|
|
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"}
|
package/dist/label/label.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
|
|
3
3
|
export interface LabelProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
-
components: ComponentMetaHolder[];
|
|
4
|
+
components: (ComponentMetaHolder | string)[];
|
|
5
5
|
}
|
|
6
6
|
export declare function Label({ components, ...props }: LabelProps): JSX.Element;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { TippyProps } from '@tippyjs/react/headless';
|
|
3
3
|
import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
|
|
4
4
|
export declare type OtherComponentsProps = {
|
|
5
|
-
components: ComponentMetaHolder[];
|
|
5
|
+
components: (ComponentMetaHolder | string)[];
|
|
6
6
|
start?: number;
|
|
7
7
|
end?: number;
|
|
8
8
|
} & TippyProps;
|
|
@@ -0,0 +1,30 @@
|
|
|
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 = void 0;
|
|
18
|
+
const react_1 = __importDefault(require("react"));
|
|
19
|
+
const react_ui_highlighter_component_metadata_bit_component_meta_1 = require("@teambit/react.ui.highlighter.component-metadata.bit-component-meta");
|
|
20
|
+
function MockTarget(_a) {
|
|
21
|
+
var { children } = _a, rest = __rest(_a, ["children"]);
|
|
22
|
+
return react_1.default.createElement("div", Object.assign({}, rest),
|
|
23
|
+
"mocked ",
|
|
24
|
+
children);
|
|
25
|
+
}
|
|
26
|
+
exports.MockTarget = MockTarget;
|
|
27
|
+
MockTarget[react_ui_highlighter_component_metadata_bit_component_meta_1.componentMetaField] = {
|
|
28
|
+
id: 'teambit.design/ui/icon-button@1.6.2',
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=mock-component.js.map
|
|
@@ -0,0 +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,16 +1,6 @@
|
|
|
1
|
-
import { componentMetaField } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
|
|
2
1
|
import React, { useState, createRef, useEffect, CSSProperties } from 'react';
|
|
3
|
-
import { ElementHighlighter
|
|
4
|
-
|
|
5
|
-
const mockTarget: Partial<HighlightTarget> = {
|
|
6
|
-
components: [
|
|
7
|
-
{
|
|
8
|
-
[componentMetaField]: {
|
|
9
|
-
id: 'teambit.design/ui/icon-button@1.6.2',
|
|
10
|
-
},
|
|
11
|
-
},
|
|
12
|
-
],
|
|
13
|
-
};
|
|
2
|
+
import { ElementHighlighter } from './element-highlighter';
|
|
3
|
+
import { MockTarget } from '../mock-component';
|
|
14
4
|
|
|
15
5
|
type HighlightedElementProps = {
|
|
16
6
|
style?: CSSProperties;
|
|
@@ -20,18 +10,21 @@ type HighlightedElementProps = {
|
|
|
20
10
|
};
|
|
21
11
|
|
|
22
12
|
export const HighlightedElement = ({ style, targetStyle, watchMotion, className }: HighlightedElementProps) => {
|
|
23
|
-
const [targetElement, setTargetElement] = useState<HTMLElement | undefined>(undefined);
|
|
24
13
|
const targetRef = createRef<HTMLDivElement>();
|
|
25
14
|
|
|
26
|
-
useEffect(() => setTargetElement(targetRef.current || undefined), [targetRef.current]);
|
|
27
|
-
const target = targetElement && { ...mockTarget, element: targetElement };
|
|
28
|
-
|
|
29
15
|
return (
|
|
30
16
|
<div className={className} style={{ padding: '16px 16px 40px 16px', width: 300, fontFamily: 'sans-serif' }}>
|
|
31
17
|
<div ref={targetRef} style={{ width: 100, ...targetStyle }}>
|
|
32
18
|
highlight target
|
|
33
19
|
</div>
|
|
34
|
-
|
|
20
|
+
|
|
21
|
+
<ElementHighlighter
|
|
22
|
+
targetRef={targetRef}
|
|
23
|
+
components={[MockTarget]}
|
|
24
|
+
style={style}
|
|
25
|
+
watchMotion={watchMotion}
|
|
26
|
+
placement="bottom"
|
|
27
|
+
/>
|
|
35
28
|
</div>
|
|
36
29
|
);
|
|
37
30
|
};
|
|
@@ -60,13 +53,30 @@ export const Sizes = () => {
|
|
|
60
53
|
);
|
|
61
54
|
};
|
|
62
55
|
|
|
56
|
+
const fps = 30;
|
|
57
|
+
const frameInterval = 1000 / fps;
|
|
58
|
+
|
|
63
59
|
export const MovingElement = () => {
|
|
64
60
|
const [margin, setMargin] = useState(0);
|
|
65
61
|
|
|
66
62
|
useEffect(() => {
|
|
67
|
-
const intervalId = setInterval(() => setMargin((x) => (x + 1) % 100),
|
|
63
|
+
const intervalId = setInterval(() => setMargin((x) => (x + 1) % 100), frameInterval);
|
|
68
64
|
return () => clearInterval(intervalId);
|
|
69
65
|
}, []);
|
|
70
66
|
|
|
71
|
-
return <HighlightedElement targetStyle={{ marginLeft: margin }} />;
|
|
67
|
+
return <HighlightedElement targetStyle={{ marginLeft: margin }} watchMotion />;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const ElementOnTheEdge = () => {
|
|
71
|
+
const targetRef = createRef<HTMLDivElement>();
|
|
72
|
+
|
|
73
|
+
return (
|
|
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.
|
|
78
|
+
</div>
|
|
79
|
+
<ElementHighlighter targetRef={targetRef} components={[MockTarget]} watchMotion />
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
72
82
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { RefObject } from 'react';
|
|
2
2
|
import classnames from 'classnames';
|
|
3
3
|
import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
|
|
4
4
|
import { Frame } from '../frame';
|
|
@@ -7,8 +7,11 @@ import { excludeHighlighterAtt } from '../ignore-highlighter';
|
|
|
7
7
|
import styles from './element-highlighter.module.scss';
|
|
8
8
|
|
|
9
9
|
export interface ElementHighlighterProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/** highlight this element */
|
|
11
|
+
targetRef: RefObject<HTMLElement | null>;
|
|
12
|
+
/** components with metadata to show in the label */
|
|
13
|
+
components?: (ComponentMetaHolder | string)[];
|
|
14
|
+
|
|
12
15
|
/** default location of the label */
|
|
13
16
|
placement?: Placement;
|
|
14
17
|
/** customize styles */
|
|
@@ -19,13 +22,6 @@ export interface ElementHighlighterProps extends React.HTMLAttributes<HTMLDivEle
|
|
|
19
22
|
|
|
20
23
|
export { Placement };
|
|
21
24
|
|
|
22
|
-
export type HighlightTarget = {
|
|
23
|
-
/** element to show the highlight at */
|
|
24
|
-
element: HTMLElement;
|
|
25
|
-
/** components with metadata to show in the label */
|
|
26
|
-
components?: ComponentMetaHolder[];
|
|
27
|
-
};
|
|
28
|
-
|
|
29
25
|
export type HighlightClasses = {
|
|
30
26
|
container?: string;
|
|
31
27
|
frame?: string;
|
|
@@ -33,29 +29,21 @@ export type HighlightClasses = {
|
|
|
33
29
|
};
|
|
34
30
|
|
|
35
31
|
export function ElementHighlighter({
|
|
36
|
-
|
|
32
|
+
targetRef,
|
|
33
|
+
components,
|
|
37
34
|
placement = 'top',
|
|
38
|
-
watchMotion
|
|
35
|
+
watchMotion,
|
|
39
36
|
className,
|
|
40
37
|
classes,
|
|
41
38
|
...props
|
|
42
39
|
}: ElementHighlighterProps) {
|
|
43
40
|
return (
|
|
44
41
|
<div {...props} {...excludeHighlighterAtt} className={classnames(classes?.container, styles.container, className)}>
|
|
45
|
-
<Frame
|
|
46
|
-
targetRef={target.element}
|
|
47
|
-
className={classnames(styles.frame, classes?.frame)}
|
|
48
|
-
watchMotion={watchMotion}
|
|
49
|
-
/>
|
|
42
|
+
<Frame targetRef={targetRef} className={classnames(styles.frame, classes?.frame)} watchMotion={watchMotion} />
|
|
50
43
|
|
|
51
|
-
{
|
|
52
|
-
<LabelContainer
|
|
53
|
-
className={
|
|
54
|
-
targetRef={target.element}
|
|
55
|
-
placement={placement}
|
|
56
|
-
watchMotion={watchMotion}
|
|
57
|
-
>
|
|
58
|
-
<Label components={target.components} className={classes?.label} />
|
|
44
|
+
{components && (
|
|
45
|
+
<LabelContainer targetRef={targetRef} className={styles.label} placement={placement} watchMotion={watchMotion}>
|
|
46
|
+
<Label components={components} className={classes?.label} />
|
|
59
47
|
</LabelContainer>
|
|
60
48
|
)}
|
|
61
49
|
</div>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { ElementHighlighter } from './element-highlighter';
|
|
2
|
-
export type { ElementHighlighterProps,
|
|
2
|
+
export type { ElementHighlighterProps, Placement, HighlightClasses } from './element-highlighter';
|
package/frame/frame.module.scss
CHANGED
|
@@ -2,6 +2,7 @@ $border: 2;
|
|
|
2
2
|
$padding: 4;
|
|
3
3
|
|
|
4
4
|
.overlayBorder {
|
|
5
|
+
box-sizing: border-box;
|
|
5
6
|
border: $border * 1px solid var(--bit-highlighter-color, #eebcc9);
|
|
6
7
|
|
|
7
8
|
border-radius: 11px;
|
|
@@ -11,6 +12,12 @@ $padding: 4;
|
|
|
11
12
|
user-select: none;
|
|
12
13
|
}
|
|
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
|
+
|
|
14
21
|
:export {
|
|
15
|
-
offset:
|
|
22
|
+
offset: $border + $padding;
|
|
16
23
|
}
|
package/frame/frame.tsx
CHANGED
|
@@ -1,64 +1,111 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
import { usePopper, Modifier } from 'react-popper';
|
|
1
|
+
import React, { useEffect, useLayoutEffect, useRef, RefObject } from 'react';
|
|
3
2
|
import classnames from 'classnames';
|
|
4
|
-
import '@
|
|
3
|
+
import { useFloating, autoUpdate, offset, size, shift } from '@floating-ui/react-dom';
|
|
4
|
+
import type { Coords } from '@floating-ui/react-dom';
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import { resizeToMatchReference } from '@teambit/base-ui.utils.popper-js.resize-to-match-reference';
|
|
6
|
+
import styles from './frame.module.scss';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
const popperModifiers: Modifier<any>[] = [
|
|
15
|
-
ignorePopperSize,
|
|
16
|
-
resizeToMatchReference,
|
|
17
|
-
{
|
|
18
|
-
name: 'flip',
|
|
19
|
-
enabled: false,
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: 'offset',
|
|
23
|
-
options: {
|
|
24
|
-
// move box from above the target ('top-start')
|
|
25
|
-
// to directly cover the target.
|
|
26
|
-
offset: ({ reference }: any) => [BASE_OFFSET, BASE_OFFSET - reference.height],
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
];
|
|
8
|
+
/** frame padding around the target */
|
|
9
|
+
const MARGIN_FROM_TARGET = +styles.offset || 6; // setting fallback 6, for tests
|
|
10
|
+
/** min. distance from the edge of the screen. */
|
|
11
|
+
const MARGIN_FROM_DOC_EDGE = 0;
|
|
30
12
|
|
|
31
13
|
export interface FrameProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
32
|
-
|
|
14
|
+
/** apply the frame to this element */
|
|
15
|
+
targetRef: RefObject<HTMLElement | null>;
|
|
16
|
+
/**
|
|
17
|
+
* the specific flavor of the frame.
|
|
18
|
+
* @default "redBorderClass"
|
|
19
|
+
*/
|
|
33
20
|
stylesClass?: string;
|
|
34
21
|
/** continually update frame position to match moving elements */
|
|
35
22
|
watchMotion?: boolean;
|
|
36
23
|
}
|
|
37
24
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
25
|
+
// position - bottom start (bottom left corner)
|
|
26
|
+
// x - width - horizontal (cross axis)
|
|
27
|
+
// y - height - vertical (main axis)
|
|
28
|
+
|
|
29
|
+
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>();
|
|
32
|
+
|
|
33
|
+
const { x, y, strategy, reference, floating, update, refs } = useFloating({
|
|
34
|
+
placement: 'bottom-start',
|
|
35
|
+
middleware: [
|
|
36
|
+
// replace dimensions from previous iterations with the target's size
|
|
37
|
+
// this is only the measured size, not yet the applied size
|
|
38
|
+
{
|
|
39
|
+
name: 'align-to-target',
|
|
40
|
+
fn({ rects }) {
|
|
41
|
+
rects.floating = {
|
|
42
|
+
...rects.floating,
|
|
43
|
+
width: rects.reference.width + 2 * MARGIN_FROM_TARGET,
|
|
44
|
+
height: rects.reference.height + 2 * MARGIN_FROM_TARGET,
|
|
45
|
+
};
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
return {};
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
// reposition x,y, to the top of the reference
|
|
51
|
+
offset((options) => -options.reference.height),
|
|
52
|
+
// offset the frame by its extra padding
|
|
53
|
+
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)
|
|
57
|
+
{
|
|
58
|
+
name: 'read-shift',
|
|
59
|
+
fn({ middlewareData }) {
|
|
60
|
+
shiftRef.current = middlewareData.shift;
|
|
61
|
+
return {};
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
// size also applies overflow detection via width and height
|
|
65
|
+
size({
|
|
66
|
+
// apply overflow detection in reference to the document
|
|
67
|
+
rootBoundary: 'document',
|
|
68
|
+
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);
|
|
72
|
+
|
|
73
|
+
dimensionRef.current = {
|
|
74
|
+
width: Math.min(referenceRect.width + paddingX, width),
|
|
75
|
+
height: Math.min(referenceRect.height + paddingY, height),
|
|
76
|
+
};
|
|
77
|
+
Object.assign(refs.floating.current?.style, dimensionRef.current);
|
|
78
|
+
},
|
|
79
|
+
}),
|
|
80
|
+
],
|
|
50
81
|
});
|
|
51
82
|
|
|
52
|
-
|
|
83
|
+
// set target as floating reference
|
|
84
|
+
useLayoutEffect(() => {
|
|
85
|
+
reference(targetRef.current);
|
|
86
|
+
}, [targetRef.current]);
|
|
87
|
+
|
|
88
|
+
// automatically update on scroll, resize, etc.
|
|
89
|
+
// `watchMotion` will trigger continuous updates using animation frame
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (!refs.reference.current || !refs.floating.current) return () => {};
|
|
92
|
+
|
|
93
|
+
return autoUpdate(refs.reference.current, refs.floating.current, update, { animationFrame: watchMotion });
|
|
94
|
+
}, [refs.reference.current, refs.floating.current, update, watchMotion]);
|
|
53
95
|
|
|
54
|
-
|
|
96
|
+
const isReady = x !== null;
|
|
55
97
|
|
|
56
98
|
return (
|
|
57
99
|
<div
|
|
58
|
-
ref={
|
|
59
|
-
className={classnames(className, stylesClass)}
|
|
60
|
-
style={{
|
|
61
|
-
|
|
100
|
+
ref={floating}
|
|
101
|
+
className={classnames(className, stylesClass, !isReady && styles.hidden)}
|
|
102
|
+
style={{
|
|
103
|
+
...style,
|
|
104
|
+
...dimensionRef.current,
|
|
105
|
+
position: strategy,
|
|
106
|
+
top: y ?? '',
|
|
107
|
+
left: x ?? '',
|
|
108
|
+
}}
|
|
62
109
|
/>
|
|
63
110
|
);
|
|
64
111
|
}
|
|
@@ -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
|
+
});
|