Skip to content

Commit

Permalink
Add CodeSandbox examples
Browse files Browse the repository at this point in the history
  • Loading branch information
petecorreia committed Feb 19, 2019
1 parent 1542528 commit 15ec90f
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 83 deletions.
28 changes: 8 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,13 @@ React components for easily composing a circular range input
[github-release]: https://flat.badgen.net/github/release/petecorreia/react-circular-input

```sh
npm i react-circular-input
npm i react-circular-input
```

<a href="https://react-circular-input.now.sh/"><img width="300" src="https://react-circular-input.now.sh/static/screenshot.png" alt="Screenshot"></a>

## Example

You can use the default circular input:

```tsx
import { CircularInput } from 'react-circular-input'

export default () => {
const [value, setValue] = useState(0.25)

return (
<CircularInput value={value} onChange={setValue} />
)
}
```

Or **compose it**:

```tsx
import {
CircularInput,
Expand All @@ -60,15 +44,19 @@ export default () => {

There's a lot more you can do with the library. From a simple gauge to a fully custom and animated circular input range.

Play around with **[examples at CodeSandbox](https://codesandbox.io/s/ypwq61rnxz?hidenavigation=1)**:

[![Edit react-circular-input](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/ypwq61rnxz?hidenavigation=1)

A declarative and composable approach means we have a lot of flexibility, check out the documentation for how to go further!

## Documentation

Full documentation at **[react-circular-input.now.sh](https://react-circular-input.now.sh)**.

* [Examples](https://react-circular-input.now.sh/examples)
* [Components](https://react-circular-input.now.sh/components)
* [Hooks](https://react-circular-input.now.sh/hooks)
- [Examples](https://react-circular-input.now.sh/examples)
- [Components](https://react-circular-input.now.sh/components)
- [Hooks](https://react-circular-input.now.sh/hooks)

Enjoy! 🎉

Expand Down
138 changes: 122 additions & 16 deletions docs/pages/examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
CircularTrack,
CircularProgress,
CircularThumb,
useCircularInputContext,
} from '../../src'
import styled from 'styled-components'
import { animated } from 'react-spring/renderprops-universal'

const FullFeaturedExample = () => {
const [value, setValue] = useState(0.25)
Expand All @@ -33,11 +33,11 @@ const ProgressExample = () => {
}, [])

return (
<Spring to={{ value }}>
<Spring to={{ value }} config={config.slow}>
{props => (
<CircularInput value={props.value}>
<CircularTrack />
<CircularProgress />
<CircularTrack strokeWidth={5} stroke="#eee" />
<CircularProgress stroke={`hsl(${props.value * 100}, 100%, 50%)`} />
</CircularInput>
)}
</Spring>
Expand Down Expand Up @@ -83,13 +83,74 @@ const AnimatedExample = () => {
)
}

const CustomComponent = () => {
const { getPointFromValue, value } = useCircularInputContext()
const { x, y } = getPointFromValue()

return (
<text
x={x}
y={y}
textAnchor="middle"
dy="0.35em"
fill="rgb(61, 153, 255)"
style={{ pointerEvents: 'none', fontWeight: 'bold' }}
>
{Math.round(value * 100)}
</text>
)
}

const CustomExample = () => {
const [value, setValue] = useState(0.25)

return (
<Spring to={{ value }} config={config.stiff}>
{props => (
<CircularInput value={props.value} onChange={setValue}>
<CircularProgress
strokeWidth={45}
stroke={`rgba(61, 153, 255, ${props.value})`}
/>
<CircularThumb
fill="white"
stroke="rgb(61, 153, 255)"
strokeWidth="5"
/>
<CustomComponent />
</CircularInput>
)}
</Spring>
)
}

export default () => (
<>
<Lead>
A declarative and composable approach means we have a lot of flexibility,
here are a few examples that showcase it.
</Lead>

<p>
Play around with the{' '}
<a
href="https://codesandbox.io/s/ypwq61rnxz?hidenavigation=1&view=preview"
target="_blank"
>
<strong>examples at CodeSandbox</strong>
</a>
</p>

<a
href="https://codesandbox.io/s/ypwq61rnxz?hidenavigation=1&view=preview"
target="_blank"
>
<img
alt="Edit react-circular-input"
src="https://codesandbox.io/static/img/play-codesandbox.svg"
/>
</a>

<h2 id="full-featured">Full featured</h2>

<p>
Expand Down Expand Up @@ -163,6 +224,7 @@ export default () => (
<CodeHighlight
code={`
const [value, setValue] = useState(0.25)
return (
<StyledCircularInput value={value} onChange={setValue}>
{/* CSS-in-JS */}
Expand All @@ -178,27 +240,49 @@ export default () => (
`}
/>

<h2 id="readonly">Readonly</h2>
<h2 id="custom">Custom Component</h2>

<p>
⚠️ Omitting the <code>onChange</code> prop makes it readonly.
Using the provided{' '}
<strong>
<Link href="/hooks">
<a>Hooks</a>
</Link>
</strong>{' '}
you can create your own components! 🤩
</p>

<BoxCenteredOnMobile py={[3, 3, 4]} mt={4}>
<CircularInput value={0.25}>
<CircularTrack />
<CircularProgress />
<CircularThumb />
</CircularInput>
<CustomExample />
</BoxCenteredOnMobile>

<CodeHighlight
code={`
<CircularInput value={0.25}>
<CircularTrack />
<CircularProgress />
<CircularThumb />
</CircularInput>
const CustomComponent = () => {
const { getPointFromValue, value } = useCircularInputContext()
const { x, y } = getPointFromValue()
return (
<text x={x} y={y} style={{ pointerEvents: 'none' }}>
{Math.round(value * 100)}
</text>
)
}
const CustomComponentExample = () => {
const [value, setValue] = useState(0.25)
return (
<CircularInput value={value} onChange={setValue}>
<CircularProgress />
<CircularThumb />
{/* Add any component and use the provided hooks! */}
<CustomComponent />
</CircularInput>
)
}
`}
/>

Expand All @@ -210,6 +294,28 @@ export default () => (
<ProgressExample />
</BoxCenteredOnMobile>

<CodeHighlight
code={`
<CircularInput value={Math.random()}>
<CircularTrack strokeWidth={5} stroke="#eee" />
<CircularProgress stroke={\`hsl(\${props.value * 100}, 100%, 50%)\`} />
</CircularInput>
`}
/>

<h2 id="readonly">Readonly</h2>

<p>
Omitting the <code>onChange</code> prop makes it readonly.
</p>

<BoxCenteredOnMobile py={[3, 3, 4]} mt={4}>
<CircularInput value={0.25}>
<CircularTrack />
<CircularProgress />
</CircularInput>
</BoxCenteredOnMobile>

<CodeHighlight
code={`
<CircularInput value={0.25}>
Expand Down
80 changes: 53 additions & 27 deletions docs/pages/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,60 +13,86 @@ export default () => (
<code>CircularInput</code>.
</p>

<h2>useCircularDrag</h2>
<h2>useCircularInputContext</h2>

<p>
Makes a component "draggable" and fires the <code>CircularThumb</code>{' '}
<code>onChange</code> on click and drag with the nearest value.
Gives you access to the same context used by the components so you can
create custom ones. 🙂
</p>

<p>
Adds/removes event listeners as needed so you don't have to worry about
that complexity.
You get access to key computed values and utility functions that should be
enough to build any custom component.
</p>

<CodeHighlight
code={`
const ref = useRef(null) // your element ref
const {
value, // current value
radius, // radius in px
center, // {x,y} of center
onChange, // onChange handler
getPointFromValue, // util: returns {x,y} of current value
getValueFromPointerEvent, // util: returns the nearest value to the given pointer event
} = useCircularInputContext()
useCircularDrag(ref)
// ...on click/drag it's going to update value
// to the nearest point in the value circumference
// Example of a custom component to display text on top of the thumb
const CustomComponent = () => {
const { getPointFromValue, value } = useCircularInputContext()
const { x, y } = getPointFromValue()
return (
<text x={x} y={y} style={{ pointerEvents: 'none' }}>
{Math.round(value * 100)}
</text>
)
}
`}
/>

<h2>useCircularDrag</h2>

<p>
<code>CircularThumb</code> uses this hook:{' '}
<a href="https://github.com/petecorreia/react-circular-input/blob/master/src/CircularThumb.tsx#L10">
View source
</a>
Adds event listeners to an element ref to fire the{' '}
<code>CircularThumb</code> <code>onChange</code> on click and drag with
the nearest value.
</p>

<h2>useCircularInputContext</h2>

<p>
Gives you access to the same context used by the components so you can
create custom ones. 🙂
Adds/removes listeners as needed so you don't have to worry about that
complexity.
</p>

<p>
You get access to key computed values and utility functions that should be
enough to build any custom component.
<code>CircularThumb</code> uses this hook:{' '}
<a href="https://github.com/petecorreia/react-circular-input/blob/master/src/CircularThumb.tsx#L10">
View source
</a>
</p>

<CodeHighlight
code={`
const {
const ref = useRef(null) // your element ref
value, // current value
radius, // radius in px
center, // {x,y} of center
onChange, // onChange handler
getPointFromValue, // util: returns {x,y} when given a value [0-1]
getValueFromPointerEvent, // util: returns the nearest value to the given pointer event
useCircularDrag(ref)
} = useCircularInputContext()
// ...on click/drag it's going to update value
// to the nearest point in the value circumference
// Example of a custom thumb component
const CustomThumb = () => {
const { getPointFromValue } = useCircularInputContext()
const { x, y } = getPointFromValue()
const ref = useRef(null)
useCircularDrag(ref)
return <circle ref={ref} cx={x} cy={y} r={20} />
}
`}
/>
</>
Expand Down
Loading

0 comments on commit 15ec90f

Please sign in to comment.