Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,6 @@ E.g:
<Box is={Link} to="/login">Login</Box>
```

##### 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`
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -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)",
Expand All @@ -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": {
Expand All @@ -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"
},
Expand Down Expand Up @@ -150,7 +150,7 @@
"size-limit": [
{
"webpack": false,
"path": "dist/index.js",
"path": "dist/src/index.js",
"limit": "5 KB",
"running": false,
"gzip": false
Expand Down
26 changes: 12 additions & 14 deletions src/box.tsx
Original file line number Diff line number Diff line change
@@ -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
}

/**
Expand All @@ -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
10 changes: 8 additions & 2 deletions src/types/box-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type RefType<T> = T extends keyof DomNodes
* Remove box props from object `T` if they're present
* @template T Object
*/
type WithoutBoxProps<T> = Without<T, "is" | "innerRef">
type WithoutBoxProps<T> = Without<T, "is">

/**
* Grab components passed to the `is` prop and return their props
Expand All @@ -53,14 +53,20 @@ export type BoxProps<T extends Is> = InheritedProps<T> &
* 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<RefType<T>>
ref?: React.Ref<RefType<T>>

/**
* Allows the high level value of safeHref to be overwritten on an individual component basis
*/
allowUnsafeHref?: boolean
}

export interface ForwardRefBoxComponent {
<T extends Is>(props: BoxProps<T>, ref?: React.Ref<RefType<T>>): React.ReactElement | null
propTypes?: React.FunctionComponent['propTypes']
displayName?: React.FunctionComponent['displayName']
}

export interface BoxComponent {
<T extends Is>(props: BoxProps<T>): React.ReactElement | null
propTypes?: React.FunctionComponent['propTypes']
Expand Down
10 changes: 5 additions & 5 deletions test/box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(<Box innerRef={innerRef} />, {
const ref = sinon.spy()
render.create(<Box ref={ref} />, {
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 => {
Expand Down
8 changes: 4 additions & 4 deletions tools/story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,14 @@ storiesOf('Box', module)
<Box boxSizing="border-box">boxSizing: border-box</Box>
</Box>
))
.add('innerRef', () => (
.add('ref', () => (
<Box>
<Box innerRef={logRef}>innerRef</Box>
<Box ref={logRef}>ref</Box>
</Box>
))
.add('innerRef as React ref', () => (
.add('ref as React ref', () => (
<Box>
<Box innerRef={reactRef}>React ref</Box>
<Box ref={reactRef}>React ref</Box>
</Box>
))
.add('props pass through', () => (
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"esModuleInterop": true
},
"include": [
"src"
"src",
"tools"
]
}