Skip to content

Commit 7635db9

Browse files
committed
feat(react): port over remaining features
BREAKING CHANGE: react version implemented natively to support server-side rendering, minor interface or implementation differences are possible
1 parent 98f2db1 commit 7635db9

File tree

6 files changed

+112
-30
lines changed

6 files changed

+112
-30
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ demo/.gitignore
66
cypress/fixtures
77
cypress/screenshots
88
cypress/support
9-
.next
9+
.next

demo-ssr/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
"indicate": "file:.."
2323
},
2424
"devDependencies": {
25-
"@types/node": "18.8.5",
25+
"@types/node": "18.11.3",
2626
"@types/react": "18.0.21",
2727
"@types/react-dom": "18.0.6",
28-
"eslint": "8.25.0",
28+
"eslint": "8.26.0",
2929
"eslint-config-next": "12.3.1",
3030
"typescript": "4.8.4"
3131
}

demo-ssr/pages/index.tsx

+58
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useRef, Fragment } from 'react'
12
import type { NextPage } from 'next'
23
import Head from 'next/head'
34
import { Indicate } from 'indicate'
@@ -79,6 +80,9 @@ const Table = () => (
7980
)
8081

8182
const Home: NextPage = () => {
83+
const childRef = useRef<HTMLElement>(null)
84+
const tableRef = useRef<HTMLTableElement>(null)
85+
8286
return (
8387
<>
8488
<Head>
@@ -239,6 +243,60 @@ const Home: NextPage = () => {
239243
>
240244
<Boxes />
241245
</Indicate>
246+
<pre>{`<Indicate childAsElement>`}</pre>
247+
<Indicate childAsElement ref={childRef}>
248+
<section style={{ display: 'inline-flex' }} ref={childRef}>
249+
<Box />
250+
<Box />
251+
<Box />
252+
<Box />
253+
<Box />
254+
<Box />
255+
<Box />
256+
<Box />
257+
<Box />
258+
<Box />
259+
<Box />
260+
<Box />
261+
<Box />
262+
<Box />
263+
<Box />
264+
<Box />
265+
<Box />
266+
<Box />
267+
<Box />
268+
<Box />
269+
</section>
270+
</Indicate>
271+
{/* <Indicate childAsElement ref={tableRef}>
272+
<table ref={tableRef}>
273+
<tr>
274+
<th>Company</th>
275+
<th>Contact</th>
276+
<th>Country</th>
277+
</tr>
278+
<tr>
279+
<td style={{ whiteSpace: 'nowrap' }}>Alfreds Futterkiste</td>
280+
<td style={{ whiteSpace: 'nowrap' }}>Maria Anders and Much More Text</td>
281+
<td style={{ whiteSpace: 'nowrap' }}>Germany and Some More Text</td>
282+
</tr>
283+
<tr>
284+
<td style={{ whiteSpace: 'nowrap' }}>Centro comercial Moctezuma</td>
285+
<td style={{ whiteSpace: 'nowrap' }}>Francisco Chang</td>
286+
<td style={{ whiteSpace: 'nowrap' }}>Mexico and Some More Text</td>
287+
</tr>
288+
<tr>
289+
<td style={{ whiteSpace: 'nowrap' }}>Centro comercial Moctezuma</td>
290+
<td style={{ whiteSpace: 'nowrap' }}>Francisco Chang</td>
291+
<td style={{ whiteSpace: 'nowrap' }}>Mexico and Some More Text</td>
292+
</tr>
293+
<tr>
294+
<td style={{ whiteSpace: 'nowrap' }}>Centro comercial Moctezuma</td>
295+
<td style={{ whiteSpace: 'nowrap' }}>Francisco Chang</td>
296+
<td style={{ whiteSpace: 'nowrap' }}>Mexico and Some More Text</td>
297+
</tr>
298+
</table>
299+
</Indicate> */}
242300
</main>
243301
</>
244302
)

demo/test.tsx

+9-10
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,24 @@ const ServerSideRendering = () => {
107107
<Indicate className="react-server-regular">
108108
<Tiles />
109109
</Indicate>
110+
<h4>Horizontal</h4>
111+
<Indicate horizontal className="react-server-horizontal">
112+
<Tiles />
113+
</Indicate>
110114
<h4>Table</h4>
111115
<Indicate className="react-server-table">
112116
<Table />
113117
</Indicate>
114118
<h4>childAsElement</h4>
115-
<Indicate
116-
ref={reactRef}
117-
childAsElement
118-
style={{ display: 'inline-flex' }}
119-
className="react-server-child"
120-
>
119+
<Indicate ref={reactRef} childAsElement className="react-server-child">
121120
<div ref={reactRef}>
122121
<Tiles />
123122
</div>
124123
</Indicate>
125-
<h4>Table as Element</h4>
124+
{/* <h4>Table as Element</h4>
126125
<Indicate ref={reactTableRef} childAsElement className="react-server-child-table">
127126
<Table ref={reactTableRef} />
128-
</Indicate>
127+
</Indicate> */}
129128
<h4>inlineStyles</h4>
130129
<Indicate
131130
outerStyle={{
@@ -379,10 +378,10 @@ export const TestCases = () => {
379378
<Tiles />
380379
</div>
381380
</Indicate>
382-
<h3>Table as Element</h3>
381+
{/* <h3>Table as Element</h3>
383382
<Indicate ref={reactTableRef} childAsElement className="react-child-table">
384383
<Table ref={reactTableRef} />
385-
</Indicate>
384+
</Indicate> */}
386385
<h3>Server-Side Rendering</h3>
387386
<ServerSideRendering />
388387
</>

helper.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const log = (messageKey: string, objects = null) => {
1313
'When using React with childAsElement option there can only be a single child node at the top, falling back to adding a wrapper element',
1414
ReactMissingRef:
1515
'When using React with childAsElement option a ref to the child node is required, falling back to adding a wrapper element',
16+
ReactFragmentRef: 'Cannot use a Fragment in conjunction with childAsElement',
1617
}
1718

1819
const prefixedMessage = `indicate: ${Messages[messageKey]}.`

react.tsx

+41-17
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ const childrenValid = (children: ReactNode, childRef: ForwardedRef<HTMLElement>)
3737
valid = false
3838
}
3939

40+
if (
41+
valid &&
42+
(Children.toArray(children)[0] as any).type.toString() === Symbol('react.fragment').toString()
43+
) {
44+
log('ReactFragmentRef', { children })
45+
valid = false
46+
}
47+
4048
if (!childRef) {
4149
log('ReactMissingRef')
4250
valid = false
@@ -324,9 +332,9 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
324332
},
325333
childRef
326334
) => {
327-
const outerWrapperRef = useRef<HTMLDivElement>(null)
328-
const elementRef = useRef<HTMLElement>(null)
329-
const innerWrapperRef = useRef<HTMLDivElement & HTMLTableElement>(null)
335+
const outerWrapperRef = useRef<HTMLDivElement>()
336+
const elementRef = useRef<HTMLElement & HTMLDivElement>()
337+
const innerWrapperRef = useRef<HTMLDivElement & HTMLTableElement>()
330338
const indicatorsRef = useRef<HTMLSpanElement[]>([])
331339
const isInline = getInline(as, style && style.display)
332340

@@ -398,7 +406,6 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
398406

399407
const observe = useCallback((element: HTMLElement) => {
400408
const observer = new IntersectionObserver(handleObservation, {
401-
// TODO innerWrapper if table
402409
root: element,
403410
// Only parts of element inside the root element are counted.
404411
rootMargin: '0px',
@@ -415,36 +422,54 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
415422
}, [])
416423

417424
useEffect(() => {
418-
// const outerWrapper = outerWrapperRef.current
419425
const element = elementRef?.current ?? (childRef as MutableRefObject<HTMLElement>)?.current
420-
// const innerWrapper = innerWrapperRef?.current
421-
422426
const disconnectObserver = observe(element)
423-
424427
return disconnectObserver
425428
}, [])
426429

427430
if (childAsElement && childrenValid(children, childRef)) {
428-
// cloneElement necessary to add styles, React elements immutable.
431+
const innerChildrenModifiable = Children.toArray((children as any).props.children)
432+
433+
innerChildrenModifiable.push(
434+
<Observers key="observers" observersRef={observersRef} theme={theme} />
435+
)
436+
437+
// cloneElement necessary to add styles and observers, React elements immutable.
429438
content = cloneElement(children as ReactElement, {
430439
...props,
440+
className,
441+
children: createElement(
442+
'div',
443+
{
444+
style: {
445+
// Transferring styles from child to inner wrapper.
446+
...(children as any).props.style,
447+
display: 'inline-flex',
448+
position: 'relative',
449+
verticalAlign: 'top',
450+
...innerStyle,
451+
...theme.innerWrapper,
452+
},
453+
ref: innerWrapperRef,
454+
...innerWrapperProps,
455+
},
456+
innerChildrenModifiable
457+
),
431458
style: {
459+
position: 'relative',
432460
overflow: 'auto',
461+
verticalAlign: 'top',
433462
...(hideScrollbar && {
434463
msOverflowStyle: 'none',
435464
scrollbarWidth: 'none',
436465
}),
437466
...style,
438467
...theme.element,
439-
// ...options?.inlineStyles?.element,
440-
// ...elementProps?.style,
441-
// ...(!(childRef as MutableRefObject<HTMLElement>)?.current && options?.inlineStyles?.innerWrapper),
442468
},
443469
})
444470
} else if (as === 'table') {
445471
content = (
446472
<div
447-
// @ts-ignore
448473
ref={elementRef}
449474
style={{
450475
position: 'relative',
@@ -454,13 +479,13 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
454479
...theme.element,
455480
}}
456481
>
457-
{/* @ts-ignore */}
458482
<table
459483
ref={innerWrapperRef}
460484
style={{
461485
display: 'inline-block',
462486
position: 'relative',
463487
verticalAlign: 'top',
488+
...innerStyle,
464489
...theme.innerWrapper,
465490
}}
466491
>
@@ -472,7 +497,6 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
472497
} else if (isInline) {
473498
content = (
474499
<div
475-
// @ts-ignore
476500
ref={elementRef}
477501
style={{
478502
...style,
@@ -490,6 +514,7 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
490514
position: 'relative',
491515
verticalAlign: 'top',
492516
display: 'inline-flex',
517+
...innerStyle,
493518
...theme.innerWrapper,
494519
},
495520
},
@@ -523,10 +548,10 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
523548
},
524549
<div
525550
style={{
526-
...innerStyle,
527551
position: 'relative',
528552
display: 'inline-flex',
529553
verticalAlign: 'top',
554+
...innerStyle,
530555
...theme.innerWrapper,
531556
}}
532557
ref={innerWrapperRef}
@@ -543,7 +568,6 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
543568
style={{
544569
...outerStyle,
545570
position: 'relative',
546-
...(childAsElement && { overflow: 'auto' }),
547571
...(isInline && { display: 'inline-block' }),
548572
...theme.outerWrapper,
549573
}}

0 commit comments

Comments
 (0)