Skip to content

Commit

Permalink
feat(react): port over remaining features
Browse files Browse the repository at this point in the history
BREAKING CHANGE: react version implemented natively to support server-side rendering, minor interface or implementation differences are possible
  • Loading branch information
tobua committed Oct 24, 2022
1 parent 98f2db1 commit 7635db9
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ demo/.gitignore
cypress/fixtures
cypress/screenshots
cypress/support
.next
.next
4 changes: 2 additions & 2 deletions demo-ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
"indicate": "file:.."
},
"devDependencies": {
"@types/node": "18.8.5",
"@types/node": "18.11.3",
"@types/react": "18.0.21",
"@types/react-dom": "18.0.6",
"eslint": "8.25.0",
"eslint": "8.26.0",
"eslint-config-next": "12.3.1",
"typescript": "4.8.4"
}
Expand Down
58 changes: 58 additions & 0 deletions demo-ssr/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useRef, Fragment } from 'react'
import type { NextPage } from 'next'
import Head from 'next/head'
import { Indicate } from 'indicate'
Expand Down Expand Up @@ -79,6 +80,9 @@ const Table = () => (
)

const Home: NextPage = () => {
const childRef = useRef<HTMLElement>(null)
const tableRef = useRef<HTMLTableElement>(null)

return (
<>
<Head>
Expand Down Expand Up @@ -239,6 +243,60 @@ const Home: NextPage = () => {
>
<Boxes />
</Indicate>
<pre>{`<Indicate childAsElement>`}</pre>
<Indicate childAsElement ref={childRef}>
<section style={{ display: 'inline-flex' }} ref={childRef}>
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
<Box />
</section>
</Indicate>
{/* <Indicate childAsElement ref={tableRef}>
<table ref={tableRef}>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td style={{ whiteSpace: 'nowrap' }}>Alfreds Futterkiste</td>
<td style={{ whiteSpace: 'nowrap' }}>Maria Anders and Much More Text</td>
<td style={{ whiteSpace: 'nowrap' }}>Germany and Some More Text</td>
</tr>
<tr>
<td style={{ whiteSpace: 'nowrap' }}>Centro comercial Moctezuma</td>
<td style={{ whiteSpace: 'nowrap' }}>Francisco Chang</td>
<td style={{ whiteSpace: 'nowrap' }}>Mexico and Some More Text</td>
</tr>
<tr>
<td style={{ whiteSpace: 'nowrap' }}>Centro comercial Moctezuma</td>
<td style={{ whiteSpace: 'nowrap' }}>Francisco Chang</td>
<td style={{ whiteSpace: 'nowrap' }}>Mexico and Some More Text</td>
</tr>
<tr>
<td style={{ whiteSpace: 'nowrap' }}>Centro comercial Moctezuma</td>
<td style={{ whiteSpace: 'nowrap' }}>Francisco Chang</td>
<td style={{ whiteSpace: 'nowrap' }}>Mexico and Some More Text</td>
</tr>
</table>
</Indicate> */}
</main>
</>
)
Expand Down
19 changes: 9 additions & 10 deletions demo/test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,25 +107,24 @@ const ServerSideRendering = () => {
<Indicate className="react-server-regular">
<Tiles />
</Indicate>
<h4>Horizontal</h4>
<Indicate horizontal className="react-server-horizontal">
<Tiles />
</Indicate>
<h4>Table</h4>
<Indicate className="react-server-table">
<Table />
</Indicate>
<h4>childAsElement</h4>
<Indicate
ref={reactRef}
childAsElement
style={{ display: 'inline-flex' }}
className="react-server-child"
>
<Indicate ref={reactRef} childAsElement className="react-server-child">
<div ref={reactRef}>
<Tiles />
</div>
</Indicate>
<h4>Table as Element</h4>
{/* <h4>Table as Element</h4>
<Indicate ref={reactTableRef} childAsElement className="react-server-child-table">
<Table ref={reactTableRef} />
</Indicate>
</Indicate> */}
<h4>inlineStyles</h4>
<Indicate
outerStyle={{
Expand Down Expand Up @@ -379,10 +378,10 @@ export const TestCases = () => {
<Tiles />
</div>
</Indicate>
<h3>Table as Element</h3>
{/* <h3>Table as Element</h3>
<Indicate ref={reactTableRef} childAsElement className="react-child-table">
<Table ref={reactTableRef} />
</Indicate>
</Indicate> */}
<h3>Server-Side Rendering</h3>
<ServerSideRendering />
</>
Expand Down
1 change: 1 addition & 0 deletions helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const log = (messageKey: string, objects = null) => {
'When using React with childAsElement option there can only be a single child node at the top, falling back to adding a wrapper element',
ReactMissingRef:
'When using React with childAsElement option a ref to the child node is required, falling back to adding a wrapper element',
ReactFragmentRef: 'Cannot use a Fragment in conjunction with childAsElement',
}

const prefixedMessage = `indicate: ${Messages[messageKey]}.`
Expand Down
58 changes: 41 additions & 17 deletions react.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ const childrenValid = (children: ReactNode, childRef: ForwardedRef<HTMLElement>)
valid = false
}

if (
valid &&
(Children.toArray(children)[0] as any).type.toString() === Symbol('react.fragment').toString()
) {
log('ReactFragmentRef', { children })
valid = false
}

if (!childRef) {
log('ReactMissingRef')
valid = false
Expand Down Expand Up @@ -324,9 +332,9 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
},
childRef
) => {
const outerWrapperRef = useRef<HTMLDivElement>(null)
const elementRef = useRef<HTMLElement>(null)
const innerWrapperRef = useRef<HTMLDivElement & HTMLTableElement>(null)
const outerWrapperRef = useRef<HTMLDivElement>()
const elementRef = useRef<HTMLElement & HTMLDivElement>()
const innerWrapperRef = useRef<HTMLDivElement & HTMLTableElement>()
const indicatorsRef = useRef<HTMLSpanElement[]>([])
const isInline = getInline(as, style && style.display)

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

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

useEffect(() => {
// const outerWrapper = outerWrapperRef.current
const element = elementRef?.current ?? (childRef as MutableRefObject<HTMLElement>)?.current
// const innerWrapper = innerWrapperRef?.current

const disconnectObserver = observe(element)

return disconnectObserver
}, [])

if (childAsElement && childrenValid(children, childRef)) {
// cloneElement necessary to add styles, React elements immutable.
const innerChildrenModifiable = Children.toArray((children as any).props.children)

innerChildrenModifiable.push(
<Observers key="observers" observersRef={observersRef} theme={theme} />
)

// cloneElement necessary to add styles and observers, React elements immutable.
content = cloneElement(children as ReactElement, {
...props,
className,
children: createElement(
'div',
{
style: {
// Transferring styles from child to inner wrapper.
...(children as any).props.style,
display: 'inline-flex',
position: 'relative',
verticalAlign: 'top',
...innerStyle,
...theme.innerWrapper,
},
ref: innerWrapperRef,
...innerWrapperProps,
},
innerChildrenModifiable
),
style: {
position: 'relative',
overflow: 'auto',
verticalAlign: 'top',
...(hideScrollbar && {
msOverflowStyle: 'none',
scrollbarWidth: 'none',
}),
...style,
...theme.element,
// ...options?.inlineStyles?.element,
// ...elementProps?.style,
// ...(!(childRef as MutableRefObject<HTMLElement>)?.current && options?.inlineStyles?.innerWrapper),
},
})
} else if (as === 'table') {
content = (
<div
// @ts-ignore
ref={elementRef}
style={{
position: 'relative',
Expand All @@ -454,13 +479,13 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
...theme.element,
}}
>
{/* @ts-ignore */}
<table
ref={innerWrapperRef}
style={{
display: 'inline-block',
position: 'relative',
verticalAlign: 'top',
...innerStyle,
...theme.innerWrapper,
}}
>
Expand All @@ -472,7 +497,6 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
} else if (isInline) {
content = (
<div
// @ts-ignore
ref={elementRef}
style={{
...style,
Expand All @@ -490,6 +514,7 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
position: 'relative',
verticalAlign: 'top',
display: 'inline-flex',
...innerStyle,
...theme.innerWrapper,
},
},
Expand Down Expand Up @@ -523,10 +548,10 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
},
<div
style={{
...innerStyle,
position: 'relative',
display: 'inline-flex',
verticalAlign: 'top',
...innerStyle,
...theme.innerWrapper,
}}
ref={innerWrapperRef}
Expand All @@ -543,7 +568,6 @@ export const Indicate = forwardRef<HTMLElement, Props & ReactHTMLElementProperti
style={{
...outerStyle,
position: 'relative',
...(childAsElement && { overflow: 'auto' }),
...(isInline && { display: 'inline-block' }),
...theme.outerWrapper,
}}
Expand Down

0 comments on commit 7635db9

Please sign in to comment.