@teambit/react.ui.component-highlighter 0.0.0-4d64e75088ad738b699f1df7db0bcd7201d589d0

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 +103 -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 +13 -0
  34. package/dist/frame/frame.js +126 -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 +73 -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 +79 -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 +61 -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 +12 -0
  84. package/dist/label/label-container.js +75 -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 +60 -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-1751963029152.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 +139 -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 +136 -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 +72 -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 +61 -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,103 @@
1
+ import React from 'react';
2
+ // import { EnterpriseOffering } from '@teambit/evangelist.pages.enterprise-offering';
3
+ import { MockedComponentWithMeta } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
4
+ import { ExcludeHighlighter } from '../ignore-highlighter';
5
+ import { ChildrenHighlighter } from './children-highlighter';
6
+ import { MockTarget } from '../mock-component';
7
+
8
+ export const ChildrenHighlighterPreview = () => {
9
+ return (
10
+ // highlighter runs in compositions, therefor should not have our font
11
+ <ChildrenHighlighter style={{ padding: 40, minWidth: 200, fontFamily: 'sans-serif' }}>
12
+ <MockedComponentWithMeta>target #1</MockedComponentWithMeta>
13
+ <br />
14
+ <br />
15
+ <br />
16
+ <br />
17
+ <MockedComponentWithMeta>target #2</MockedComponentWithMeta>
18
+ </ChildrenHighlighter>
19
+ );
20
+ };
21
+
22
+ export const ChildrenHighlighterWithCustomColors = () => {
23
+ return (
24
+ <ChildrenHighlighter
25
+ style={{ padding: 40, minWidth: 200, color: 'yellow', fontFamily: 'sans-serif' }}
26
+ bgColor="cornflowerblue"
27
+ bgColorHover="blue"
28
+ bgColorActive="DarkSlateBlue"
29
+ >
30
+ <MockedComponentWithMeta>hover here</MockedComponentWithMeta>
31
+ <br />
32
+ <br />
33
+ <br />
34
+ <MockedComponentWithMeta>also here</MockedComponentWithMeta>
35
+ </ChildrenHighlighter>
36
+ );
37
+ };
38
+
39
+ export const ChildrenHighlighterInsideIgnore = () => {
40
+ return (
41
+ <ExcludeHighlighter>
42
+ <ChildrenHighlighter style={{ fontFamily: 'sans-serif' }}>
43
+ Multi Highlighter should still work when inside <code>{'<ExcludeHighlighter>'}</code>
44
+ <br />
45
+ It should only skip exclusion zones inside of it.
46
+ <br />
47
+ <br />
48
+ <br />
49
+ <MockedComponentWithMeta>hover here</MockedComponentWithMeta>
50
+ <br />
51
+ <br />
52
+ <br />
53
+ <MockedComponentWithMeta>also here</MockedComponentWithMeta>
54
+ </ChildrenHighlighter>
55
+ </ExcludeHighlighter>
56
+ );
57
+ };
58
+
59
+ export const ChildrenHighlighterWithRule = () => {
60
+ const rule = '#someSubTree *';
61
+
62
+ return (
63
+ <ChildrenHighlighter rule={rule} style={{ minWidth: 300, fontFamily: 'sans-serif' }}>
64
+ <div>
65
+ element filter: <code>"{rule}"</code>
66
+ </div>
67
+ <br />
68
+ <MockedComponentWithMeta>no highlighter</MockedComponentWithMeta>
69
+ <br />
70
+ <br />
71
+ <br />
72
+ <div id="someSubTree">
73
+ <MockedComponentWithMeta>this will be highlighted</MockedComponentWithMeta>
74
+ </div>
75
+ </ChildrenHighlighter>
76
+ );
77
+ };
78
+
79
+ export const ChildrenHighlighterWithComponentRule = () => {
80
+ const filterTarget = 'teambit.design/ui/mock-target';
81
+
82
+ return (
83
+ <ChildrenHighlighter componentRule={filterTarget} style={{ minWidth: 300, fontFamily: 'sans-serif' }}>
84
+ <div>
85
+ component filter: <code>"{filterTarget}"</code>
86
+ </div>
87
+ <br />
88
+ <MockedComponentWithMeta>no highlighter</MockedComponentWithMeta>
89
+ <br />
90
+ <br />
91
+ <br />
92
+ <MockTarget style={{ display: 'inline-block', margin: '0 8px' }}>this will be highlighted</MockTarget>
93
+ </ChildrenHighlighter>
94
+ );
95
+ };
96
+
97
+ // export const HighlightingAllElementsInTheEnterprisePage = () => {
98
+ // return (
99
+ // <ChildrenHighlighter>
100
+ // <EnterpriseOffering style={{ height: 300 }} />
101
+ // </ChildrenHighlighter>
102
+ // );
103
+ // };
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import { ChildrenHighlighterPreview } from './children-highlighter.composition';
4
+
5
+ it('should not throw when rendering the children-highlighter', () => {
6
+ const { getByText } = render(<ChildrenHighlighterPreview />);
7
+
8
+ const rendered = getByText('target #1');
9
+
10
+ expect(rendered).toBeInstanceOf(HTMLElement);
11
+ });
12
+
13
+ // .querySelectorAll() is not working as expected during the test, ignoring for now :(
14
+ // it('should render highlighter for all children components', async () => {
15
+ // const { queryAllByText } = render(<Preview />);
16
+
17
+ // // allow useEffect to run
18
+ // await new Promise((res) => setTimeout(res, 200));
19
+
20
+ // const rendered = queryAllByText('input/button');
21
+ // expect(rendered).toHaveLength(2);
22
+ // });
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+
3
+ import { HybridHighlighter, HybridHighlighterProps } from '../hybrid-highlighter';
4
+
5
+ export type ChildrenHighlighterProps = Omit<HybridHighlighterProps, 'mode'>;
6
+
7
+ export function ChildrenHighlighter({ watchMotion = false, ...props }: ChildrenHighlighterProps) {
8
+ return <HybridHighlighter {...props} mode={'allChildren'} watchMotion={watchMotion} />;
9
+ }
@@ -0,0 +1,5 @@
1
+ export { useChildrenHighlighter } from './use-children-highlighter';
2
+ export type { ChildrenHighlighterOptions } from './use-children-highlighter';
3
+
4
+ export { ChildrenHighlighter } from './children-highlighter';
5
+ export type { ChildrenHighlighterProps } from './children-highlighter';
@@ -0,0 +1,79 @@
1
+ import { useEffect, RefObject, HtmlHTMLAttributes } from 'react';
2
+ import getXPath from 'get-xpath';
3
+ import { domToReacts, toRootElement } from '@teambit/react.modules.dom-to-react';
4
+ import {
5
+ componentMetaField,
6
+ ComponentMetaHolder,
7
+ hasComponentMeta,
8
+ ReactComponentMetaHolder,
9
+ } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
10
+ import { excludeHighlighterSelector, skipHighlighterSelector } from '../ignore-highlighter';
11
+ import { ruleMatcher, MatchRule, ComponentMatchRule, componentRuleMatcher } from '../rule-matcher';
12
+
13
+ type HighlighterTarget = Record<string, { element: HTMLElement; components: ComponentMetaHolder[] }>;
14
+
15
+ export type ChildrenHighlighterOptions = {
16
+ onChange: (highlighterTargets: HighlighterTarget) => void;
17
+ disabled?: boolean;
18
+ scopeRef: RefObject<HTMLElement>;
19
+ scopeClass?: string;
20
+ /** filter highlighter targets by this query selector. (May be a more complex object in the future) */
21
+ rule?: MatchRule;
22
+ componentRule?: ComponentMatchRule;
23
+
24
+ // /** automatically update when children update. Use with caution, might be slow */
25
+ // watchDom?: boolean;
26
+ };
27
+
28
+ export function useChildrenHighlighter({
29
+ onChange,
30
+ disabled,
31
+ scopeRef,
32
+ scopeClass: scopeSelector = '',
33
+ rule,
34
+ componentRule,
35
+ }: ChildrenHighlighterOptions) {
36
+ useEffect(() => {
37
+ const nextTargets: HighlighterTarget = {};
38
+ const scopeElement = scopeRef.current;
39
+ if (!scopeElement || disabled) return;
40
+
41
+ // select all elements (except excluded)
42
+ let allElements = Array.from(scopeElement.querySelectorAll<HTMLElement>(targetsSelector(`.${scopeSelector}`)));
43
+ // apply rule filtering
44
+ if (rule) allElements = allElements.filter((elem) => ruleMatcher(elem, rule));
45
+ // seek the root element:
46
+ const rootElements = allElements.map(toRootElement).filter((x) => !!x);
47
+ // deduplicate
48
+ const uniqueRoots = new Set(rootElements);
49
+
50
+ uniqueRoots.forEach((element) => {
51
+ if (!element) return;
52
+ const comps = domToReacts(element);
53
+ const componentsWithMeta = comps.filter(
54
+ (x) => hasComponentMeta(x) && componentRuleMatcher({ meta: x[componentMetaField] }, componentRule)
55
+ ) as ReactComponentMetaHolder[];
56
+
57
+ if (componentsWithMeta.length < 1) return;
58
+
59
+ const key = getXPath(element);
60
+
61
+ nextTargets[key] = { element, components: componentsWithMeta };
62
+ });
63
+
64
+ onChange(nextTargets);
65
+ }, [disabled, scopeSelector]);
66
+ }
67
+
68
+ function targetsSelector(
69
+ /**
70
+ * the scope in which to consider the exclude selector.
71
+ * The `:scope` modifier is appropriate, but is not supported in older browsers.
72
+ */
73
+ scopeSelector = ':scope'
74
+ ) {
75
+ const excludedSelector = `${scopeSelector} ${excludeHighlighterSelector}, ${scopeSelector} ${excludeHighlighterSelector} *`;
76
+ const skippedSelector = `${scopeSelector} ${skipHighlighterSelector}, ${scopeSelector} ${skipHighlighterSelector} *`;
77
+
78
+ return `:not(${excludedSelector}, ${skippedSelector})`;
79
+ }
@@ -0,0 +1,191 @@
1
+ ---
2
+ description: Highlights Bit Components and links to their Bit scope
3
+ labels: ['component', 'highlight', 'react']
4
+ ---
5
+
6
+ import { HighlightedElement } from './element-highlighter/element-highlighter.compositions';
7
+
8
+ The component highlighter allows you to visually inspect bit react components, and provides a link to its documentation page.
9
+ It is mostly used for compositions debugging.
10
+
11
+ <HighlightedElement />
12
+
13
+ ## How to use?
14
+
15
+ Simplest way to use the component is by wrapping your code with `ComponentHighlighter`.
16
+ It will automatically detect components from DOM elements, just by hovering on them.
17
+
18
+ ```tsx
19
+ import { ComponentHighlighter } from '@teambit/react.ui.component-highlighter';
20
+
21
+ function App() {
22
+ return (
23
+ <ComponentHighlighter>
24
+ <Header />
25
+ <Feed />
26
+ </ComponentHighlighter>
27
+ );
28
+ }
29
+ ```
30
+
31
+ You can also use it manually, to have more control:
32
+
33
+ ```tsx
34
+ import { ElementHighlighter } from '@teambit/react.ui.component-highlighter';
35
+
36
+ function ManualHighlight() {
37
+ const targetRef = createRef<HTMLElement | undefined>(null);
38
+
39
+ return (
40
+ <div>
41
+ <div ref={targetRef}>highlight target</div>
42
+ <ElementHighlighter targetRef={targetRef} components={['teambit.design/ui/icon-button']} />
43
+ </div>
44
+ );
45
+ }
46
+ ```
47
+
48
+ ## How does it work?
49
+
50
+ The manual highlighter works by positioning elements (a frame and a label) to a target element. It uses [PopperJS](https://popper.js.org/) to correctly align them to the element.
51
+
52
+ The automatic highlighter then adds an event listener for hover events, which automatically tracks mouse movements and finds the most relevant React component using [DOM-to-react](https://bit.dev/teambit/react/modules/dom-to-react). It bubbles up the DOM until it finds a component with bit metadata.
53
+
54
+ Where does the metadata come from? The highlighter assumes the code has been transpiled by Bit's [custom babel plugin](https://bit.dev/teambit/react/babel/bit-react-transformer). The plugin looks for React components (i.e. functions or classes), and attaches a metadata object to them.
55
+
56
+ > The `Bit React Transformer` babel plugin is already running in the Preview, during `bit start`.
57
+ > It only effects the browser bundle, and not the dists.
58
+
59
+ The result looks like this:
60
+
61
+ ```tsx
62
+ var __bit_component = {
63
+ id: 'teambit.base-ui/button@1.0.0',
64
+ homepage: 'https://bit.dev/teambit/base-ui/input/button',
65
+ exported: true,
66
+ };
67
+
68
+ export function Button() {
69
+ return <div>click me!</div>;
70
+ }
71
+
72
+ // attaches metadata:
73
+ Button.__bit_component = __bit_component;
74
+ ```
75
+
76
+ ### Modes
77
+
78
+ The Component Highlighter comes in a few different modes:
79
+
80
+ - `hover` - this will track your mouse movements, and show the highlighter for the element the user is currently hovering on.
81
+ - `allChildren` - this automatically detects all components nested inside the highlighter, and apply a highlighter to them. Currently, this detection only happens once on initial setup, so it does not detect changes.
82
+
83
+ In addition to changing the `mode` prop, you can also use convenience exports from the same package:
84
+
85
+ ```tsx
86
+ import { ChildrenHighlighter, HoverHighlighter } from '@teambit/react.ui.component-highlighter';
87
+
88
+ function example() {
89
+ return (
90
+ <div>
91
+ <HoverHighlighter>
92
+ <App />
93
+ </HoverHighlighter>
94
+
95
+ <ChildrenHighlighter>
96
+ <App />
97
+ </ChildrenHighlighter>
98
+ </div>
99
+ );
100
+ }
101
+ ```
102
+
103
+ ### Debounce
104
+
105
+ Normally, moving quickly between elements could produce a jitter effect, where the highlighter "jumps" between elements, making interaction difficult.
106
+ A debounce mitigates this by batching re-targets and smooths out the experience.
107
+ First time selection will always happen immediately, for a snappy experience.
108
+
109
+ You can control the debounce rate with the `debounceSelection` prop. (default - `80ms`)
110
+
111
+ ## Exclusions Zones
112
+
113
+ To disabled highlighting in a specific area of the DOM, you can use the `<ExcludeHighlighter />` component:
114
+
115
+ ```tsx
116
+ import { ExcludeHighlighter, excludeHighlighterAtt } from '@teambit/react.ui.component-highlighter';
117
+
118
+ // ...
119
+
120
+ return (
121
+ <div>
122
+ <ExcludeHighlighter>
123
+ <Card>this component will not be highlighted</Card>
124
+ </ExcludeHighlighter>
125
+
126
+ {/* you can also add the exclude attribute without making a new div */}
127
+ <Card {...excludeHighlighterAtt}>this component will also be skipped</Card>
128
+ </div>
129
+ );
130
+ ```
131
+
132
+ Another options would be use use the `rule` prop.
133
+ Inspired by Webpack rules, it provides a query selector or function that the highlighter target will have to match.
134
+ For example:
135
+
136
+ ```tsx
137
+ <ComponentHighlighter rule="#include *">
138
+ <Button>will not be highlighted</Button>
139
+ <div id="include">
140
+ <Button>this will be highlighted</Button>
141
+ </div>
142
+ </ComponentHighlighter>
143
+ ```
144
+
145
+ You can also filter by component id, using the `componentRule` prop:
146
+
147
+ ```tsx
148
+ <ComponentHighlighter componentRule="teambit.design/ui/icon-button">
149
+ <Paragraph>will not be highlighted</Paragraph>
150
+ <Button>this will be highlighted</Button>
151
+ </ComponentHighlighter>
152
+ ```
153
+
154
+ ## Customization
155
+
156
+ Use these CSS variables to edit the highlighter color
157
+
158
+ ```css
159
+ --bit-highlighter-color: #eebcc9;
160
+ --bit-highlighter-color-hover: #f6dae2;
161
+ --bit-highlighter-color-active: #e79db1;
162
+ --bit-highlighter-shadow: 0px 11px 29px 0px rgba(0, 0, 0, 0.23));
163
+ ```
164
+
165
+ While it is preferred to use the css variables, you can also set them using react props:
166
+
167
+ ```tsx
168
+ <ComponentHighlighter bgColor="#eebcc9" bgColorHover="#f6dae2" bgColorActive="#e79db1">
169
+ ...
170
+ </ComponentHighlighter>
171
+ ```
172
+
173
+ And for complete control, you can pass these classes:
174
+
175
+ ```tsx
176
+ const classes = {
177
+ /** containing div */
178
+ container?: string;
179
+ /** border */
180
+ frame?: string;
181
+ /** component id links */
182
+ label?: string;
183
+ };
184
+
185
+ <ComponentHighlighter classes={classes}>
186
+ ...
187
+ </ComponentHighlighter>
188
+ ```
189
+
190
+ You can control the size using regular `font-size`.
191
+ Keep in mind that the label can be either two elements (when using component id), and a single element (for other texts)
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ export declare const ChildrenHighlighterPreview: () => React.JSX.Element;
3
+ export declare const ChildrenHighlighterWithCustomColors: () => React.JSX.Element;
4
+ export declare const ChildrenHighlighterInsideIgnore: () => React.JSX.Element;
5
+ export declare const ChildrenHighlighterWithRule: () => React.JSX.Element;
6
+ export declare const ChildrenHighlighterWithComponentRule: () => React.JSX.Element;
@@ -0,0 +1,93 @@
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.ChildrenHighlighterWithComponentRule = exports.ChildrenHighlighterWithRule = exports.ChildrenHighlighterInsideIgnore = exports.ChildrenHighlighterWithCustomColors = exports.ChildrenHighlighterPreview = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ // import { EnterpriseOffering } from '@teambit/evangelist.pages.enterprise-offering';
9
+ const react_ui_highlighter_component_metadata_bit_component_meta_1 = require("@teambit/react.ui.highlighter.component-metadata.bit-component-meta");
10
+ const ignore_highlighter_1 = require("../ignore-highlighter");
11
+ const children_highlighter_1 = require("./children-highlighter");
12
+ const mock_component_1 = require("../mock-component");
13
+ const ChildrenHighlighterPreview = () => {
14
+ return (
15
+ // highlighter runs in compositions, therefor should not have our font
16
+ react_1.default.createElement(children_highlighter_1.ChildrenHighlighter, { style: { padding: 40, minWidth: 200, fontFamily: 'sans-serif' } },
17
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "target #1"),
18
+ react_1.default.createElement("br", null),
19
+ react_1.default.createElement("br", null),
20
+ react_1.default.createElement("br", null),
21
+ react_1.default.createElement("br", null),
22
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "target #2")));
23
+ };
24
+ exports.ChildrenHighlighterPreview = ChildrenHighlighterPreview;
25
+ const ChildrenHighlighterWithCustomColors = () => {
26
+ return (react_1.default.createElement(children_highlighter_1.ChildrenHighlighter, { style: { padding: 40, minWidth: 200, color: 'yellow', fontFamily: 'sans-serif' }, bgColor: "cornflowerblue", bgColorHover: "blue", bgColorActive: "DarkSlateBlue" },
27
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "hover here"),
28
+ react_1.default.createElement("br", null),
29
+ react_1.default.createElement("br", null),
30
+ react_1.default.createElement("br", null),
31
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "also here")));
32
+ };
33
+ exports.ChildrenHighlighterWithCustomColors = ChildrenHighlighterWithCustomColors;
34
+ const ChildrenHighlighterInsideIgnore = () => {
35
+ return (react_1.default.createElement(ignore_highlighter_1.ExcludeHighlighter, null,
36
+ react_1.default.createElement(children_highlighter_1.ChildrenHighlighter, { style: { fontFamily: 'sans-serif' } },
37
+ "Multi Highlighter should still work when inside ",
38
+ react_1.default.createElement("code", null, '<ExcludeHighlighter>'),
39
+ react_1.default.createElement("br", null),
40
+ "It should only skip exclusion zones inside of it.",
41
+ react_1.default.createElement("br", null),
42
+ react_1.default.createElement("br", null),
43
+ react_1.default.createElement("br", null),
44
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "hover here"),
45
+ react_1.default.createElement("br", null),
46
+ react_1.default.createElement("br", null),
47
+ react_1.default.createElement("br", null),
48
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "also here"))));
49
+ };
50
+ exports.ChildrenHighlighterInsideIgnore = ChildrenHighlighterInsideIgnore;
51
+ const ChildrenHighlighterWithRule = () => {
52
+ const rule = '#someSubTree *';
53
+ return (react_1.default.createElement(children_highlighter_1.ChildrenHighlighter, { rule: rule, style: { minWidth: 300, fontFamily: 'sans-serif' } },
54
+ react_1.default.createElement("div", null,
55
+ "element filter: ",
56
+ react_1.default.createElement("code", null,
57
+ "\"",
58
+ rule,
59
+ "\"")),
60
+ react_1.default.createElement("br", null),
61
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "no highlighter"),
62
+ react_1.default.createElement("br", null),
63
+ react_1.default.createElement("br", null),
64
+ react_1.default.createElement("br", null),
65
+ react_1.default.createElement("div", { id: "someSubTree" },
66
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "this will be highlighted"))));
67
+ };
68
+ exports.ChildrenHighlighterWithRule = ChildrenHighlighterWithRule;
69
+ const ChildrenHighlighterWithComponentRule = () => {
70
+ const filterTarget = 'teambit.design/ui/mock-target';
71
+ return (react_1.default.createElement(children_highlighter_1.ChildrenHighlighter, { componentRule: filterTarget, style: { minWidth: 300, fontFamily: 'sans-serif' } },
72
+ react_1.default.createElement("div", null,
73
+ "component filter: ",
74
+ react_1.default.createElement("code", null,
75
+ "\"",
76
+ filterTarget,
77
+ "\"")),
78
+ react_1.default.createElement("br", null),
79
+ react_1.default.createElement(react_ui_highlighter_component_metadata_bit_component_meta_1.MockedComponentWithMeta, null, "no highlighter"),
80
+ react_1.default.createElement("br", null),
81
+ react_1.default.createElement("br", null),
82
+ react_1.default.createElement("br", null),
83
+ react_1.default.createElement(mock_component_1.MockTarget, { style: { display: 'inline-block', margin: '0 8px' } }, "this will be highlighted")));
84
+ };
85
+ exports.ChildrenHighlighterWithComponentRule = ChildrenHighlighterWithComponentRule;
86
+ // export const HighlightingAllElementsInTheEnterprisePage = () => {
87
+ // return (
88
+ // <ChildrenHighlighter>
89
+ // <EnterpriseOffering style={{ height: 300 }} />
90
+ // </ChildrenHighlighter>
91
+ // );
92
+ // };
93
+ //# sourceMappingURL=children-highlighter.composition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"children-highlighter.composition.js","sourceRoot":"","sources":["../../children-highlighter/children-highlighter.composition.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,sFAAsF;AACtF,oJAA8G;AAC9G,8DAA2D;AAC3D,iEAA6D;AAC7D,sDAA+C;AAExC,MAAM,0BAA0B,GAAG,GAAG,EAAE;IAC7C,OAAO;IACL,sEAAsE;IACtE,8BAAC,0CAAmB,IAAC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE;QAClF,8BAAC,oFAAuB,oBAAoC;QAC5D,yCAAM;QACN,yCAAM;QACN,yCAAM;QACN,yCAAM;QACN,8BAAC,oFAAuB,oBAAoC,CACxC,CACvB,CAAC;AACJ,CAAC,CAAC;AAZW,QAAA,0BAA0B,8BAYrC;AAEK,MAAM,mCAAmC,GAAG,GAAG,EAAE;IACtD,OAAO,CACL,8BAAC,0CAAmB,IAClB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,EAChF,OAAO,EAAC,gBAAgB,EACxB,YAAY,EAAC,MAAM,EACnB,aAAa,EAAC,eAAe;QAE7B,8BAAC,oFAAuB,qBAAqC;QAC7D,yCAAM;QACN,yCAAM;QACN,yCAAM;QACN,8BAAC,oFAAuB,oBAAoC,CACxC,CACvB,CAAC;AACJ,CAAC,CAAC;AAfW,QAAA,mCAAmC,uCAe9C;AAEK,MAAM,+BAA+B,GAAG,GAAG,EAAE;IAClD,OAAO,CACL,8BAAC,uCAAkB;QACjB,8BAAC,0CAAmB,IAAC,KAAK,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE;;YACN,4CAAO,sBAAsB,CAAQ;YACrF,yCAAM;;YAEN,yCAAM;YACN,yCAAM;YACN,yCAAM;YACN,8BAAC,oFAAuB,qBAAqC;YAC7D,yCAAM;YACN,yCAAM;YACN,yCAAM;YACN,8BAAC,oFAAuB,oBAAoC,CACxC,CACH,CACtB,CAAC;AACJ,CAAC,CAAC;AAlBW,QAAA,+BAA+B,mCAkB1C;AAEK,MAAM,2BAA2B,GAAG,GAAG,EAAE;IAC9C,MAAM,IAAI,GAAG,gBAAgB,CAAC;IAE9B,OAAO,CACL,8BAAC,0CAAmB,IAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE;QACjF;;YACkB;;gBAAQ,IAAI;qBAAS,CACjC;QACN,yCAAM;QACN,8BAAC,oFAAuB,yBAAyC;QACjE,yCAAM;QACN,yCAAM;QACN,yCAAM;QACN,uCAAK,EAAE,EAAC,aAAa;YACnB,8BAAC,oFAAuB,mCAAmD,CACvE,CACc,CACvB,CAAC;AACJ,CAAC,CAAC;AAlBW,QAAA,2BAA2B,+BAkBtC;AAEK,MAAM,oCAAoC,GAAG,GAAG,EAAE;IACvD,MAAM,YAAY,GAAG,+BAA+B,CAAC;IAErD,OAAO,CACL,8BAAC,0CAAmB,IAAC,aAAa,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE;QAClG;;YACoB;;gBAAQ,YAAY;qBAAS,CAC3C;QACN,yCAAM;QACN,8BAAC,oFAAuB,yBAAyC;QACjE,yCAAM;QACN,yCAAM;QACN,yCAAM;QACN,8BAAC,2BAAU,IAAC,KAAK,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,+BAAuC,CAClF,CACvB,CAAC;AACJ,CAAC,CAAC;AAhBW,QAAA,oCAAoC,wCAgB/C;AAEF,oEAAoE;AACpE,aAAa;AACb,4BAA4B;AAC5B,uDAAuD;AACvD,6BAA6B;AAC7B,OAAO;AACP,KAAK"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { HybridHighlighterProps } from '../hybrid-highlighter';
3
+ export type ChildrenHighlighterProps = Omit<HybridHighlighterProps, 'mode'>;
4
+ export declare function ChildrenHighlighter({ watchMotion, ...props }: ChildrenHighlighterProps): React.JSX.Element;
@@ -0,0 +1,24 @@
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.ChildrenHighlighter = ChildrenHighlighter;
18
+ const react_1 = __importDefault(require("react"));
19
+ const hybrid_highlighter_1 = require("../hybrid-highlighter");
20
+ function ChildrenHighlighter(_a) {
21
+ var { watchMotion = false } = _a, props = __rest(_a, ["watchMotion"]);
22
+ return react_1.default.createElement(hybrid_highlighter_1.HybridHighlighter, Object.assign({}, props, { mode: 'allChildren', watchMotion: watchMotion }));
23
+ }
24
+ //# sourceMappingURL=children-highlighter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"children-highlighter.js","sourceRoot":"","sources":["../../children-highlighter/children-highlighter.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAMA,kDAEC;AARD,kDAA0B;AAE1B,8DAAkF;AAIlF,SAAgB,mBAAmB,CAAC,EAA2D;QAA3D,EAAE,WAAW,GAAG,KAAK,OAAsC,EAAjC,KAAK,cAA/B,eAAiC,CAAF;IACjE,OAAO,8BAAC,sCAAiB,oBAAK,KAAK,IAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,IAAI,CAAC;AACzF,CAAC"}
@@ -0,0 +1,22 @@
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
+ const react_1 = __importDefault(require("react"));
7
+ const react_2 = require("@testing-library/react");
8
+ const children_highlighter_composition_1 = require("./children-highlighter.composition");
9
+ it('should not throw when rendering the children-highlighter', () => {
10
+ const { getByText } = (0, react_2.render)(react_1.default.createElement(children_highlighter_composition_1.ChildrenHighlighterPreview, null));
11
+ const rendered = getByText('target #1');
12
+ expect(rendered).toBeInstanceOf(HTMLElement);
13
+ });
14
+ // .querySelectorAll() is not working as expected during the test, ignoring for now :(
15
+ // it('should render highlighter for all children components', async () => {
16
+ // const { queryAllByText } = render(<Preview />);
17
+ // // allow useEffect to run
18
+ // await new Promise((res) => setTimeout(res, 200));
19
+ // const rendered = queryAllByText('input/button');
20
+ // expect(rendered).toHaveLength(2);
21
+ // });
22
+ //# sourceMappingURL=children-highlighter.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"children-highlighter.spec.js","sourceRoot":"","sources":["../../children-highlighter/children-highlighter.spec.tsx"],"names":[],"mappings":";;;;;AAAA,kDAA0B;AAC1B,kDAAgD;AAChD,yFAAgF;AAEhF,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;IAClE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,cAAM,EAAC,8BAAC,6DAA0B,OAAG,CAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAExC,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEH,sFAAsF;AACtF,4EAA4E;AAC5E,oDAAoD;AAEpD,8BAA8B;AAC9B,sDAAsD;AAEtD,qDAAqD;AACrD,sCAAsC;AACtC,MAAM"}
@@ -0,0 +1,4 @@
1
+ export { useChildrenHighlighter } from './use-children-highlighter';
2
+ export type { ChildrenHighlighterOptions } from './use-children-highlighter';
3
+ export { ChildrenHighlighter } from './children-highlighter';
4
+ export type { ChildrenHighlighterProps } from './children-highlighter';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChildrenHighlighter = exports.useChildrenHighlighter = void 0;
4
+ var use_children_highlighter_1 = require("./use-children-highlighter");
5
+ Object.defineProperty(exports, "useChildrenHighlighter", { enumerable: true, get: function () { return use_children_highlighter_1.useChildrenHighlighter; } });
6
+ var children_highlighter_1 = require("./children-highlighter");
7
+ Object.defineProperty(exports, "ChildrenHighlighter", { enumerable: true, get: function () { return children_highlighter_1.ChildrenHighlighter; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../children-highlighter/index.ts"],"names":[],"mappings":";;;AAAA,uEAAoE;AAA3D,kIAAA,sBAAsB,OAAA;AAG/B,+DAA6D;AAApD,2HAAA,mBAAmB,OAAA"}
@@ -0,0 +1,18 @@
1
+ import { RefObject } from 'react';
2
+ import { ComponentMetaHolder } from '@teambit/react.ui.highlighter.component-metadata.bit-component-meta';
3
+ import { MatchRule, ComponentMatchRule } from '../rule-matcher';
4
+ type HighlighterTarget = Record<string, {
5
+ element: HTMLElement;
6
+ components: ComponentMetaHolder[];
7
+ }>;
8
+ export type ChildrenHighlighterOptions = {
9
+ onChange: (highlighterTargets: HighlighterTarget) => void;
10
+ disabled?: boolean;
11
+ scopeRef: RefObject<HTMLElement>;
12
+ scopeClass?: string;
13
+ /** filter highlighter targets by this query selector. (May be a more complex object in the future) */
14
+ rule?: MatchRule;
15
+ componentRule?: ComponentMatchRule;
16
+ };
17
+ export declare function useChildrenHighlighter({ onChange, disabled, scopeRef, scopeClass: scopeSelector, rule, componentRule, }: ChildrenHighlighterOptions): void;
18
+ export {};