-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Harley Alexander
authored and
Harley Alexander
committed
Apr 8, 2020
1 parent
e9d0bdf
commit 80087ca
Showing
5 changed files
with
173 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,49 @@ | ||
# `bottom-sheet` | ||
# `mui-bottom-sheet` | ||
|
||
Features: | ||
> 👆 A delightful bottom sheet component for react up to material design spec | ||
- peek heights - make drawer stop at specific heights on the way up to full screen | ||
- clamp to max height - if the contents are smaller than full screen, clamp it | ||
- hide completely with hidden prop | ||
- backdrop fades in and out as you swipe up | ||
The bottom sheet in the Google Maps app for a location is _really_ nice. I set out to recreate that level of UX detail with a modern `BottomSheet` for React. [Try it in the storybook](). | ||
|
||
![Bottom Sheet Demo](https://user-images.githubusercontent.com/43975092/78733881-0f751300-798a-11ea-8c9c-62cda96fc35b.gif) | ||
|
||
Under the hood it uses `react-spring` for delightful animations and `react-use-gesture` to handle dragging. This is still a work in progress - let me know features you'd like and I'll add them in. | ||
|
||
## Installation | ||
|
||
```bash | ||
yarn add mui-bottom-sheet | ||
``` | ||
|
||
## Usage | ||
|
||
```js | ||
import React from 'react'; | ||
import { BottomSheet } from 'mui-bottom-sheet'; | ||
|
||
export const App = () => { | ||
return <BottomSheet>Add your content here</BottomSheet>; | ||
}; | ||
``` | ||
|
||
## Props (options) | ||
|
||
| prop | type | description | default | | ||
| --------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | | ||
| `backdrop` | `boolean?` | Whether to show the transparent backdrop that fades in as you pull up. | `true` | | ||
| `background` | `React.ReactElement?` | Background element that slides up behind the main bottom sheet. | `null` | | ||
| `defaultHeight` | `number?` | Default height when the sheet is closed. | `100` | | ||
| `hidden` | `boolean?` | When true, the sheet will completely hide at the bottom of the screen. | `false` | | ||
| `fullHeight` | `boolean?` | Whether to allow the sheet to go 100% of the screen height. If false, the highest it can go is the maximum of `peekHeights`. Otherwise it'll stick to `defaultHeight`. | `true` | | ||
| `peekHeights` | `number[]?` | Progressive peek heights for the bottom sheet to stop at. Use this to reveal more detailed information as the sheet is pulled up. | `[]` | | ||
| `styles` | `{ root: {}, backdrop: {}, background: {} }` | Pass additional styles to either the sheet, the backdrop or the background components | `{ root: {}, backdrop: {}, background: {} }` | | ||
| `threshold` | `number?` | The threshold for over-dragging the sheet above its maximum height before it snaps to the highest position. | `70` | | ||
|
||
## Upcoming | ||
|
||
- [ ] Cypress tests - Jest doesn't play nicely with dragging and dropping. Help appreciated. | ||
- [ ] Hooks API for binding custom components instead of a prescribed `animated.div` | ||
- [ ] Programatically set stop height | ||
- [ ] Access to current stop index | ||
- [ ] `open()` and `close()` for programatic interaction | ||
- [ ] passing custom `react-spring` config | ||
- [ ] anything else? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,130 @@ | ||
import React, { PropsWithChildren } from 'react'; | ||
import { BottomSheet, BottomSheetProps } from '../src/BottomSheet'; | ||
import { boolean, number, object } from '@storybook/addon-knobs'; | ||
import backgroundImage from './static/buildings.jpg'; | ||
|
||
export default { | ||
title: 'A BottomSheet', | ||
component: BottomSheet, | ||
decorators: [ | ||
StoryFn => ( | ||
<div style={{ fontFamily: 'sans-serif', padding: 24 }}> | ||
<StoryFn /> | ||
</div> | ||
), | ||
], | ||
}; | ||
|
||
// By passing optional props to this story, you can control the props of the component when | ||
// you consume the story in a test. | ||
|
||
export const Default = ( | ||
props?: Partial<PropsWithChildren<BottomSheetProps>> | ||
) => ( | ||
<div style={{ fontFamily: 'sans-serif', padding: 24 }}> | ||
Map will go here | ||
<BottomSheet | ||
children={<div style={{ height: 900, padding: 24 }}>Sheet content</div>} | ||
{...props} | ||
/> | ||
); | ||
|
||
export const AllPropsAsKnobs = () => ( | ||
<BottomSheet | ||
backdrop={boolean('backdrop', true)} | ||
defaultHeight={number('defaultHeight', 100)} | ||
hidden={boolean('hidden', false)} | ||
fullHeight={boolean('fullHeight', true)} | ||
peekHeights={object('peekHeights', [250, 400])} | ||
threshold={number('threshold', 70)} | ||
> | ||
<div style={{ height: 900, padding: 24 }}>Content</div> | ||
</BottomSheet> | ||
); | ||
export const CustomStyles = () => ( | ||
<div style={{ background: '#1E2128', color: '#F3EFF5' }}> | ||
Regular page content | ||
<BottomSheet | ||
peekHeights={[100, 300]} | ||
fullHeight={false} | ||
background={ | ||
<div style={{ padding: 24 }}> | ||
Add images, carousels, or anything in here! | ||
</div> | ||
} | ||
styles={object('styles', { | ||
root: { | ||
borderRadius: '10px 10px 0 0', | ||
backgroundColor: '#313642', | ||
color: '#F3EFF5', | ||
}, | ||
backdrop: { | ||
backgroundColor: 'rgba(255,255,255,0.8)', | ||
}, | ||
background: { | ||
backgroundImage: `url(${backgroundImage})`, | ||
backgroundPosition: 'center center', | ||
backgroundSize: 'cover', | ||
paddingBottom: 24, | ||
display: 'flex', | ||
alignItems: 'flex-end', | ||
color: '#fff', | ||
fontSize: 24, | ||
fontWeight: 'bold', | ||
}, | ||
})} | ||
> | ||
<div style={{ height: 900, padding: 24 }}> | ||
Pull me up for a pretty image. | ||
</div> | ||
</BottomSheet> | ||
</div> | ||
); | ||
|
||
CustomStyles.story = { | ||
decorators: [ | ||
StoryFn => ( | ||
<div | ||
style={{ | ||
fontFamily: 'sans-serif', | ||
padding: 24, | ||
background: '#1E2128', | ||
color: '#F3EFF5', | ||
}} | ||
> | ||
<StoryFn /> | ||
</div> | ||
), | ||
], | ||
}; | ||
|
||
export const WithLongContentAndBackground = () => ( | ||
<> | ||
Your regular page here. | ||
<BottomSheet | ||
background={ | ||
<div style={{ backgroundColor: '#eee', height: '100%', padding: 24 }}> | ||
Location image sliders can go here | ||
Add images, carousels, or anything in here! | ||
</div> | ||
} | ||
peekHeights={[250, 400]} | ||
{...props} | ||
styles={{ | ||
root: { | ||
borderRadius: '10px 10px 0 0', | ||
}, | ||
}} | ||
> | ||
<div style={{ height: 900, width: '100%', padding: 24 }}> | ||
Waypoint information carousel here | ||
<div style={{ height: 250, width: '100%', padding: 24 }}> | ||
Main bottom sheet content can go here. | ||
</div> | ||
<div | ||
style={{ height: 250, width: '100%', padding: 24, background: '#eee' }} | ||
> | ||
Peek heights reveal more information progressively. | ||
</div> | ||
<div | ||
style={{ height: 250, width: '100%', padding: 24, background: '#ccc' }} | ||
> | ||
Only scroll when you're at full height. | ||
</div> | ||
</BottomSheet> | ||
</div> | ||
</> | ||
); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.