Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

docs(Ref): restore docs for a component #4039

Merged
merged 3 commits into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions docs/src/components/ComponentDoc/ComponentDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,14 @@ class ComponentDoc extends Component {
subheader={_.join(componentInfo.docblock.description, ' ')}
/>
<ComponentDocSee seeTags={seeTags} />
<ComponentDocLinks
displayName={displayName}
parentDisplayName={componentInfo.parentDisplayName}
repoPath={componentInfo.repoPath}
type={componentInfo.type}
/>
{componentInfo.repoPath && (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hides this block as code is not hosted in this repo:

image

<ComponentDocLinks
displayName={displayName}
parentDisplayName={componentInfo.parentDisplayName}
repoPath={componentInfo.repoPath}
type={componentInfo.type}
/>
)}
<ComponentProps componentsInfo={componentsInfo} displayName={displayName} />
</Grid.Column>
</Grid.Row>
Expand Down
67 changes: 67 additions & 0 deletions docs/src/examples/addons/Ref/Types/RefExampleRef.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react'
import { Grid, Table, Ref, Segment } from 'semantic-ui-react'

function RefExampleRef() {
const objectRef = React.useRef(null)
const [functionalRef, setFunctionalRef] = React.useState(null)
const [isMounted, setIsMounted] = React.useState(false)

React.useEffect(() => {
setIsMounted(true)
return () => setIsMounted(false)
}, [])

return (
<Grid>
<Grid.Column width={6}>
<Segment.Group>
<Ref innerRef={setFunctionalRef}>
<Segment>An example node with functional ref</Segment>
</Ref>
<Ref innerRef={objectRef}>
<Segment>
An example node with ref via <code>React.useRef()</code>
</Segment>
</Ref>
</Segment.Group>
</Grid.Column>
<Grid.Column width={10}>
{isMounted && (
<Table>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Type</Table.HeaderCell>
<Table.HeaderCell>
<code>nodeName</code>
</Table.HeaderCell>
<Table.HeaderCell>
<code>textContent</code>
</Table.HeaderCell>
</Table.Row>
</Table.Header>

<Table.Body>
<Table.Row>
<Table.Cell singleLine>
Functional ref via <code>React.useState()</code> hook
</Table.Cell>
<Table.Cell>{functionalRef.nodeName}</Table.Cell>
<Table.Cell>{functionalRef.textContent}</Table.Cell>
</Table.Row>

<Table.Row>
<Table.Cell singleLine>
From <code>React.useRef()</code> hook
</Table.Cell>
<Table.Cell>{objectRef.current.nodeName}</Table.Cell>
<Table.Cell>{objectRef.current.textContent}</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
)}
</Grid.Column>
</Grid>
)
}

export default RefExampleRef
54 changes: 54 additions & 0 deletions docs/src/examples/addons/Ref/Types/RefForwardingExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react'
import { Grid, Ref, Segment } from 'semantic-ui-react'

const ExampleButton = React.forwardRef((props, ref) => (
<div>
<button {...props} ref={ref} />
</div>
))

function RefForwardingExample() {
const forwardedRef = React.useRef(null)
const [isMounted, setIsMounted] = React.useState(false)

React.useEffect(() => {
setIsMounted(true)
return () => setIsMounted(false)
}, [])

return (
<Grid columns={2}>
<Grid.Column>
<Segment>
<p>
A button below uses <code>React.forwardRef()</code> API.
</p>

<Ref innerRef={forwardedRef}>
<ExampleButton>A button</ExampleButton>
</Ref>
</Segment>
</Grid.Column>

<Grid.Column>
{isMounted && (
<Segment secondary>
<pre>
{JSON.stringify(
{
nodeName: forwardedRef.current.nodeName,
nodeType: forwardedRef.current.nodeType,
textContent: forwardedRef.current.textContent,
},
null,
2,
)}
</pre>
</Segment>
)}
</Grid.Column>
</Grid>
)
}

export default RefForwardingExample
30 changes: 30 additions & 0 deletions docs/src/examples/addons/Ref/Types/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const RefTypesExamples = () => (
<ExampleSection title='Types'>
<ComponentExample
title='Ref'
description={
<span>
A component exposes the <code>innerRef</code> prop that always returns
the DOM node of both functional and class component children.
</span>
}
examplePath='addons/Ref/Types/RefExampleRef'
/>
<ComponentExample
title='Forward Ref'
description={
<span>
<code>React.forwardRef()</code> API is also handled by this component.
</span>
}
examplePath='addons/Ref/Types/RefForwardingExample'
/>
</ExampleSection>
)

export default RefTypesExamples
28 changes: 28 additions & 0 deletions docs/src/examples/addons/Ref/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { Message } from 'semantic-ui-react'

import Types from './Types'

const RefExamples = () => (
<>
<Message info>
<p>
Currently, it's recommended to use <code>Ref</code> component to get
refs to HTML elements from Semantic UI React components as not all
components support native ref forwarding via{' '}
<code>React.forwardRef()</code>.
</p>
<p>
As it uses deprecated <code>ReactDOM.findDOMNode()</code> you may
receive warnings in React's StrictMode. We are working on it in{' '}
<a href='https://github.com/Semantic-Org/Semantic-UI-React/issues/3819'>
Semantic-Org/Semantic-UI-React#3819
</a>
.
</p>
</Message>
<Types />
</>
)

export default RefExamples
14 changes: 13 additions & 1 deletion docs/static/utils/getComponentMenu.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import _ from 'lodash'
import componentMenu from '../../src/componentMenu'

const getComponentMenu = () => componentMenu
const getComponentMenu = () =>
_.sortBy(
[
...componentMenu,
{
displayName: 'Ref',
type: 'addon',
external: true,
},
],
'displayName',
)

export default getComponentMenu
4 changes: 2 additions & 2 deletions src/modules/Popup/lib/createReferenceProxy.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isRefObject, toRefObject } from '@fluentui/react-component-ref'
import { isRefObject } from '@fluentui/react-component-ref'
import _ from 'lodash'

class ReferenceProxy {
Expand Down Expand Up @@ -31,7 +31,7 @@ class ReferenceProxy {
* @see https://popper.js.org/popper-documentation.html#referenceObject
*/
const createReferenceProxy = _.memoize(
(reference) => new ReferenceProxy(isRefObject(reference) ? reference : toRefObject(reference)),
(reference) => new ReferenceProxy(isRefObject(reference) ? reference : { current: reference }),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A small follow up fix for #4023.

)

export default createReferenceProxy
77 changes: 66 additions & 11 deletions static.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,82 @@ export default async () => {
})),

// Routes for components, i.e. /element/button
..._.map(getComponentMenu(), (baseInfo) => ({
path: getComponentPathname(baseInfo),
..._.map(
_.filter(getComponentMenu(), (baseInfo) => !baseInfo.external),
(baseInfo) => ({
path: getComponentPathname(baseInfo),
component: 'docs/src/components/ComponentDoc',
priority: 0.8,
getData: async () => {
const componentsInfo = getComponentGroupInfo(baseInfo.displayName)
const sidebarSections = getSidebarSections(baseInfo.displayName)

return {
componentsInfo,
exampleSources,
sidebarSections,
displayName: baseInfo.displayName,
deprecated: !!_.find(
_.get(componentsInfo[baseInfo.displayName], 'docblock.tags'),
(tag) => tag.title === 'deprecated',
),
seeTags: getInfoForSeeTags(componentsInfo[baseInfo.displayName]),
}
},
}),
),

{
path: `/addons/ref/`,
component: 'docs/src/components/ComponentDoc',
priority: 0.8,
getData: async () => {
const componentsInfo = getComponentGroupInfo(baseInfo.displayName)
const sidebarSections = getSidebarSections(baseInfo.displayName)
const componentsInfo = {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's annoying to do this manually, but in any case this is not a long term solution

Ref: {
displayName: 'Ref',
props: [
{
description: ['Called when a child component will be mounted or updated.'],
name: 'innerRef',
type: 'func',
required: true,
tags: [
{
title: 'param',
description: 'Referred node.',
type: {
type: 'NameExpression',
name: 'HTMLElement',
},
name: 'node',
},
],
},
],
type: 'addon',
isParent: true,
subcomponents: [],
docblock: {
tags: [],
description: [
'This component exposes the `innerRef` prop that supports functional and createRef() API and returns the DOM node of both functional and class component children.',
],
},
examplesExist: true,
},
}
const sidebarSections = getSidebarSections('Ref')

return {
componentsInfo,
exampleSources,
sidebarSections,
displayName: baseInfo.displayName,
deprecated: !!_.find(
_.get(componentsInfo[baseInfo.displayName], 'docblock.tags'),
(tag) => tag.title === 'deprecated',
),
seeTags: getInfoForSeeTags(componentsInfo[baseInfo.displayName]),
displayName: 'Ref',
deprecated: false,
seeTags: [],
}
},
})),
},

// Routes for layouts, i.e. /layouts/theming
..._.map(await getLayoutPaths(), ({ routeName, componentFilename }) => ({
Expand Down