diff --git a/README.md b/README.md
index 6574765..e72fb49 100644
--- a/README.md
+++ b/README.md
@@ -62,12 +62,6 @@ E.g:
Login
```
-##### innerRef
-
-Type: `function`
-
-Callback that gets passed a ref to inner DOM node (or component if the `is` prop is set to a React component type).
-
##### clearfix
Type: `boolean`
diff --git a/package.json b/package.json
index 863e57f..34f5cfa 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ui-box",
- "version": "3.3.0",
+ "version": "4.0.0-0",
"description": "Blazing Fast React UI Primitive",
"contributors": [
"Jeroen Ransijn (https://twitter.com/jeroen_ransijn)",
@@ -14,10 +14,10 @@
],
"repository": "segmentio/ui-box",
"license": "MIT",
- "main": "dist/index.js",
- "typings": "dist/index.d.ts",
+ "main": "dist/src/index.js",
+ "typings": "dist/src/index.d.ts",
"files": [
- "dist"
+ "dist/src"
],
"sideEffects": false,
"scripts": {
@@ -27,7 +27,7 @@
"build": "tsc",
"build-storybook": "build-storybook -s .storybook/static -o .out",
"release": "np",
- "benchmark": "echo ui-box && react-benchmark tools/benchmarks/box.js",
+ "benchmark": "echo ui-box && react-benchmark dist/tools/benchmarks/box.js",
"size": "size-limit",
"coverage": "nyc report --reporter=html"
},
@@ -150,7 +150,7 @@
"size-limit": [
{
"webpack": false,
- "path": "dist/index.js",
+ "path": "dist/src/index.js",
"limit": "5 KB",
"running": false,
"gzip": false
diff --git a/src/box.tsx b/src/box.tsx
index 3e4d331..f201931 100644
--- a/src/box.tsx
+++ b/src/box.tsx
@@ -1,18 +1,18 @@
-import React from 'react'
+import React, { forwardRef } from 'react'
import PropTypes from 'prop-types'
-import {BoxComponent} from './types/box-types'
+import {BoxComponent, ForwardRefBoxComponent} from './types/box-types'
import {propTypes} from './enhancers'
import enhanceProps from './enhance-props'
import {extractAnchorProps, getUseSafeHref} from './utils/safeHref'
-const Box: BoxComponent = ({ is = 'div', innerRef, children, allowUnsafeHref, ...props }) => {
+const Box: ForwardRefBoxComponent = ({ is = 'div', children, allowUnsafeHref, ...props }, ref) => {
// Convert the CSS props to class names (and inject the styles)
const {className, enhancedProps: parsedProps} = enhanceProps(props)
parsedProps.className = className
- if (innerRef) {
- parsedProps.ref = innerRef
+ if (ref) {
+ parsedProps.ref = ref
}
/**
@@ -32,19 +32,17 @@ const Box: BoxComponent = ({ is = 'div', innerRef, children, allowUnsafeHref, ..
Box.displayName = 'Box'
-Box.propTypes = {
+const BoxWithRef = forwardRef(Box) as BoxComponent
+
+BoxWithRef.propTypes = {
...propTypes,
- innerRef: PropTypes.oneOfType([
- PropTypes.func,
- PropTypes.shape({ current: PropTypes.element })
- ]),
- is: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.elementType])
+ is: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.elementType]),
+ allowUnsafeHref: PropTypes.bool
}
-Box.defaultProps = {
- innerRef: null,
+BoxWithRef.defaultProps = {
is: 'div',
boxSizing: 'border-box'
}
-export default Box
+export default BoxWithRef
diff --git a/src/types/box-types.ts b/src/types/box-types.ts
index ed7cf67..5eb2eb8 100644
--- a/src/types/box-types.ts
+++ b/src/types/box-types.ts
@@ -29,7 +29,7 @@ export type RefType = T extends keyof DomNodes
* Remove box props from object `T` if they're present
* @template T Object
*/
-type WithoutBoxProps = Without
+type WithoutBoxProps = Without
/**
* Grab components passed to the `is` prop and return their props
@@ -53,7 +53,7 @@ export type BoxProps = InheritedProps &
* Callback that gets passed a ref to inner DOM node (or component if the
* `is` prop is set to a React component type).
*/
- innerRef?: React.Ref>
+ ref?: React.Ref>
/**
* Allows the high level value of safeHref to be overwritten on an individual component basis
@@ -61,6 +61,12 @@ export type BoxProps = InheritedProps &
allowUnsafeHref?: boolean
}
+export interface ForwardRefBoxComponent {
+ (props: BoxProps, ref?: React.Ref>): React.ReactElement | null
+ propTypes?: React.FunctionComponent['propTypes']
+ displayName?: React.FunctionComponent['displayName']
+}
+
export interface BoxComponent {
(props: BoxProps): React.ReactElement | null
propTypes?: React.FunctionComponent['propTypes']
diff --git a/test/box.tsx b/test/box.tsx
index 122666a..17eeff8 100644
--- a/test/box.tsx
+++ b/test/box.tsx
@@ -57,16 +57,16 @@ test('is prop allows changing the component type', t => {
t.true(component.is(TestComponent))
})
-test('innerRef prop gets passed the ref', t => {
+test('ref gets forwarded', t => {
const node = {domNode: true}
- const innerRef = sinon.spy()
- render.create(, {
+ const ref = sinon.spy()
+ render.create(, {
createNodeMock() {
return node
}
})
- t.true(innerRef.calledOnce)
- t.is(innerRef.args[0][0], node)
+ t.true(ref.calledOnce)
+ t.is(ref.args[0][0], node)
})
test('renders children', t => {
diff --git a/tools/story.tsx b/tools/story.tsx
index 06abee0..059cf98 100644
--- a/tools/story.tsx
+++ b/tools/story.tsx
@@ -180,14 +180,14 @@ storiesOf('Box', module)
boxSizing: border-box
))
- .add('innerRef', () => (
+ .add('ref', () => (
- innerRef
+ ref
))
- .add('innerRef as React ref', () => (
+ .add('ref as React ref', () => (
- React ref
+ React ref
))
.add('props pass through', () => (
diff --git a/tsconfig.json b/tsconfig.json
index ec28fd3..5ba8e22 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -27,6 +27,7 @@
"esModuleInterop": true
},
"include": [
- "src"
+ "src",
+ "tools"
]
}