diff --git a/docs/src/components/card.tsx b/docs/src/components/card.tsx index 980265c..bc54341 100644 --- a/docs/src/components/card.tsx +++ b/docs/src/components/card.tsx @@ -3,12 +3,14 @@ import React from 'react' export default ({ children, title, + last, }: { children: [React.ReactNode, React.ReactNode, React.ReactNode] title: string + last?: boolean }) => (

Hamburger type: diff --git a/docs/src/components/cards.tsx b/docs/src/components/cards.tsx index 6d0df1a..35c3733 100644 --- a/docs/src/components/cards.tsx +++ b/docs/src/components/cards.tsx @@ -1,9 +1,15 @@ +import { Cross } from '../../../src' import { Fade } from '../../../src' +import { Pivot } from '../../../src' +import { Rotate } from '../../../src' +import { Slant } from '../../../src' import { Sling } from '../../../src' import { Spin } from '../../../src' +import { Spiral } from '../../../src' +import { Squash } from '../../../src' +import { Squeeze } from '../../../src' import { Turn } from '../../../src' import { Twirl } from '../../../src' -import { Squash } from '../../../src' import Hamburger from '../../../src' import Card from './card' import NewCard from './new-card' @@ -34,6 +40,18 @@ export default () => ( + + +
+ import {'{'} + Cross + as + Hamburger + {'}'} from 'hamburger-react' +
+ +
+
@@ -58,6 +76,42 @@ export default () => ( + + +
+ import {'{'} + Slant + as + Hamburger + {'}'} from 'hamburger-react' +
+ +
+ + + +
+ import {'{'} + Pivot + as + Hamburger + {'}'} from 'hamburger-react' +
+ +
+ + + +
+ import {'{'} + Spiral + as + Hamburger + {'}'} from 'hamburger-react' +
+ +
+
@@ -82,6 +136,18 @@ export default () => ( + + +
+ import {'{'} + Rotate + as + Hamburger + {'}'} from 'hamburger-react' +
+ +
+
@@ -92,6 +158,17 @@ export default () => ( {'}'} from 'hamburger-react'
+ + + +
+ import {'{'} + Squeeze + as + Hamburger + {'}'} from 'hamburger-react' +
+
) diff --git a/docs/src/components/footer.tsx b/docs/src/components/footer.tsx index b58b4dd..feb9979 100644 --- a/docs/src/components/footer.tsx +++ b/docs/src/components/footer.tsx @@ -7,7 +7,7 @@ export default () => ( Luuk @@ -16,7 +16,7 @@ export default () => ( Stutpak @@ -27,7 +27,7 @@ export default () => ( NPM @@ -35,7 +35,7 @@ export default () => ( GitHub @@ -43,7 +43,7 @@ export default () => ( Contact diff --git a/docs/src/components/information.tsx b/docs/src/components/information.tsx index 07efdc5..0fdf6d0 100644 --- a/docs/src/components/information.tsx +++ b/docs/src/components/information.tsx @@ -9,7 +9,7 @@ export default () => ( GitHub repository diff --git a/docs/src/components/new-card.tsx b/docs/src/components/new-card.tsx index 38af913..c88a88a 100644 --- a/docs/src/components/new-card.tsx +++ b/docs/src/components/new-card.tsx @@ -3,12 +3,14 @@ import React from 'react' export default ({ children, title, + last, }: { children: [React.ReactNode, React.ReactNode] title: string + last?: boolean }) => (

Hamburger type: diff --git a/docs/src/components/properties.tsx b/docs/src/components/properties.tsx index 8755d8c..b3cd5c1 100644 --- a/docs/src/components/properties.tsx +++ b/docs/src/components/properties.tsx @@ -28,7 +28,7 @@ export default () => { - + The animation direction of the icon, left or right.
{'<'} @@ -40,6 +40,21 @@ export default () => {
+ + + + The vertical distance between the lines. Small (sm), medium (md) or + large (lg). +
+ {'<'} + Hamburger +   + distance=" + lg + {'" />'} +
+
+ (
- v2.0.0 (1.5 KB) + v2.1.0 (1.5 KB) ) diff --git a/src/Burger.tsx b/src/Burger.tsx index 77148e7..94b20fc 100644 --- a/src/Burger.tsx +++ b/src/Burger.tsx @@ -3,11 +3,11 @@ import { BurgerProps } from './' const area = 48 const timing = 'cubic-bezier(0, 0, 0, 1)' -const translate = 4.6325 export const Burger = (({ color = 'currentColor', direction = 'left', + distance = 'md', duration = 0.4, hideOutline = true, label, @@ -17,6 +17,7 @@ export const Burger = (({ size = 32, toggle, toggled, + _lines = 3, }) => { const [toggledInternal, toggleInternal] = useState(false) @@ -25,13 +26,18 @@ export const Burger = (({ const barHeightRaw = width / 12 const barHeight = Math.round(barHeightRaw) - const marginRaw = width / 4.5 + + const space = distance === 'lg' ? 0.25 : distance === 'sm' ? 0.75 : 0.5 + const marginRaw = width / (_lines * (space + (_lines === 3 ? 1 : 1.25))) const margin = Math.round(marginRaw) - const height = barHeight * 3 + margin * 2 + const height = (barHeight * _lines) + margin * (_lines - 1) const topOffset = Math.round((area - height) / 2) - const deviation = (barHeightRaw - barHeight) + (marginRaw - margin) + const translate = _lines === 3 + ? distance === 'lg' ? 4.0425 : distance === 'sm' ? 5.1625 : 4.6325 + : distance === 'lg' ? 6.7875 : distance === 'sm' ? 8.4875 : 7.6675 + const deviation = ((barHeightRaw - barHeight) + (marginRaw - margin)) / (_lines === 3 ? 1 : 2) const move = parseFloat(((width / translate) - (deviation / (4 / 3))).toFixed(2)) const time = Math.max(0, duration) diff --git a/src/Cross.tsx b/src/Cross.tsx new file mode 100644 index 0000000..6e789e5 --- /dev/null +++ b/src/Cross.tsx @@ -0,0 +1,38 @@ +import { Burger } from './Burger' +import React, { FunctionComponent } from 'react' +import { CommonBurgerProps } from './' + +export const Cross = ((props) => ( + ( +
(e.key === 'Enter' || e.keyCode === 13) && o.handler()} + role="button" + style={o.burgerStyles} + tabIndex={0} + > +
+ +
+
+ )} /> +)) as FunctionComponent diff --git a/src/Pivot.tsx b/src/Pivot.tsx new file mode 100644 index 0000000..308896b --- /dev/null +++ b/src/Pivot.tsx @@ -0,0 +1,72 @@ +import { Burger } from './Burger' +import React, { FunctionComponent } from 'react' +import { CommonBurgerProps } from './' + +export const Pivot = ((props) => ( + ( +
(e.key === 'Enter' || e.keyCode === 13) && o.handler()} + role="button" + style={{ + ...o.burgerStyles, + transform: `${o.isToggled + ? `rotate(${90 * (o.isLeft ? -1 : 1)}deg)` + : 'none' + }`, + }} + tabIndex={0} + > +
+
+
+ +
+
+
+
+ )} /> +)) as FunctionComponent diff --git a/src/Rotate.tsx b/src/Rotate.tsx new file mode 100644 index 0000000..daced4d --- /dev/null +++ b/src/Rotate.tsx @@ -0,0 +1,44 @@ +import { Burger } from './Burger' +import React, { FunctionComponent } from 'react' +import { CommonBurgerProps } from './' + +export const Rotate = ((props) => ( + ( +
(e.key === 'Enter' || e.keyCode === 13) && o.handler()} + role="button" + style={{ + ...o.burgerStyles, + transform: `${o.isToggled + ? `rotateY(${180 * (o.isLeft ? -1 : 1)}deg)` + : 'none' + }`, + }} + tabIndex={0} + > +
+ +
+
+ )} /> +)) as FunctionComponent diff --git a/src/Slant.tsx b/src/Slant.tsx new file mode 100644 index 0000000..ce63b9f --- /dev/null +++ b/src/Slant.tsx @@ -0,0 +1,44 @@ +import { Burger } from './Burger' +import React, { FunctionComponent } from 'react' +import { CommonBurgerProps } from './' + +export const Slant = ((props) => ( + ( +
(e.key === 'Enter' || e.keyCode === 13) && o.handler()} + role="button" + style={{ + ...o.burgerStyles, + transform: `${o.isToggled + ? `rotate(${90 * (o.isLeft ? -1 : 1)}deg)` + : 'none' + }`, + }} + tabIndex={0} + > +
+ +
+
+ )} /> +)) as FunctionComponent diff --git a/src/Spin.tsx b/src/Spin.tsx index 554832f..52795c3 100644 --- a/src/Spin.tsx +++ b/src/Spin.tsx @@ -14,7 +14,7 @@ export const Spin = ((props) => ( style={{ ...o.burgerStyles, transform: `${o.isToggled - ? `rotate(${360 * (o.isLeft ? -1 : 1)}deg)` + ? `rotate(${180 * (o.isLeft ? -1 : 1)}deg)` : 'none' }`, }} diff --git a/src/Spiral.tsx b/src/Spiral.tsx new file mode 100644 index 0000000..891f850 --- /dev/null +++ b/src/Spiral.tsx @@ -0,0 +1,44 @@ +import { Burger } from './Burger' +import React, { FunctionComponent } from 'react' +import { CommonBurgerProps } from './' + +export const Spiral = ((props) => ( + ( +
(e.key === 'Enter' || e.keyCode === 13) && o.handler()} + role="button" + style={{ + ...o.burgerStyles, + transform: `${o.isToggled + ? `rotate(${180 * (o.isLeft ? -1 : 1)}deg)` + : 'none' + }`, + }} + tabIndex={0} + > +
+ +
+
+ )} /> +)) as FunctionComponent diff --git a/src/Squeeze.tsx b/src/Squeeze.tsx new file mode 100644 index 0000000..749b7df --- /dev/null +++ b/src/Squeeze.tsx @@ -0,0 +1,66 @@ +import { Burger } from './Burger' +import React, { FunctionComponent } from 'react' +import { CommonBurgerProps } from './' + +export const Squeeze = ((props) => ( + ( +
(e.key === 'Enter' || e.keyCode === 13) && o.handler()} + role="button" + style={o.burgerStyles} + tabIndex={0} + > +
+
+
+ +
+
+
+
+ )} /> +)) as FunctionComponent diff --git a/src/index.ts b/src/index.ts index bf23563..8a6142a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,22 +1,30 @@ import React, { CSSProperties, Dispatch, SetStateAction } from 'react' import { Tilt as Hamburger } from './Tilt' +import { Cross } from './Cross' import { Fade } from './Fade' +import { Pivot } from './Pivot' +import { Rotate } from './Rotate' +import { Slant } from './Slant' import { Sling } from './Sling' import { Spin } from './Spin' +import { Spiral } from './Spiral' import { Squash } from './Squash' +import { Squeeze } from './Squeeze' import { Turn } from './Turn' import { Twirl } from './Twirl' export default Hamburger -export { Fade, Sling, Spin, Squash, Turn, Twirl } +export { Cross, Fade, Pivot, Rotate, Slant, Sling, Spin, Spiral, Squash, Squeeze, Turn, Twirl } export interface CommonBurgerProps { /** The color of the icon bars, accepts any CSS-parsable argument. */ color?: string; /** The animation direction of the icon, left or right. */ direction?: 'left' | 'right'; + /** The vertical distance between the lines. Small (sm), medium (md) or large (lg). */ + distance?: 'sm' | 'md' | 'lg'; /** The duration of the animation. Can be set to zero if no animation is desired. */ duration?: number; /** Hides the default browser focus style. */ @@ -33,6 +41,8 @@ export interface CommonBurgerProps { toggle?: Dispatch> /** A way to provide your own state value. Can be used together with a state action (the `toggle` prop). */ toggled?: boolean; + /** Only for internal use. */ + _lines?: number; } export interface RenderOptions { diff --git a/tests/distance.test.tsx b/tests/distance.test.tsx new file mode 100644 index 0000000..944ba0a --- /dev/null +++ b/tests/distance.test.tsx @@ -0,0 +1,45 @@ +import React from 'react' +import { Cross } from '../src' +import { render } from '@testing-library/react' + +it(`can be set to small`, () => { + const { getByTestId: get } = render() + + expect(get('bar-one')).toHaveStyle({ top: '17px' }) + expect(get('bar-two')).toHaveStyle({ top: '28px' }) +}) + +it(`can be set to large`, () => { + const { getByTestId: get } = render() + + expect(get('bar-one')).toHaveStyle({ top: '16px' }) + expect(get('bar-two')).toHaveStyle({ top: '30px' }) +}) + +it(`is medium by default`, () => { + const { getByTestId: get } = render() + + expect(get('bar-one')).toHaveStyle({ top: '17px' }) + expect(get('bar-two')).toHaveStyle({ top: '29px' }) +}) + +it(`is medium when an invalid value is passed`, () => { + const { getByTestId: get } = render() + + expect(get('bar-one')).toHaveStyle({ top: '17px' }) + expect(get('bar-two')).toHaveStyle({ top: '29px' }) +}) + +it(`works in combination with a custom tiny size`, () => { + const { getByTestId: get } = render() + + expect(get('bar-one')).toHaveStyle({ top: '18px' }) + expect(get('bar-two')).toHaveStyle({ top: '28px' }) +}) + +it(`works in combination with a custom big size`, () => { + const { getByTestId: get } = render() + + expect(get('bar-one')).toHaveStyle({ top: '15px' }) + expect(get('bar-two')).toHaveStyle({ top: '31px' }) +}) diff --git a/tests/general.test.tsx b/tests/general.test.tsx index 6ab12c5..2f06352 100644 --- a/tests/general.test.tsx +++ b/tests/general.test.tsx @@ -1,15 +1,34 @@ import React from 'react' -import Hamburger, { Fade, Sling, Spin, Squash, Turn, Twirl } from '../src' import { render, fireEvent } from '@testing-library/react' +import Hamburger, { + Fade, + Slant, + Sling, + Spin, + Squash, + Turn, + Twirl, + Squeeze, + Cross, + Rotate, + Pivot, + Spiral, +} from '../src' it(`renders all versions`, () => { const { getByTestId: get } = render( <> - + + + + + + + @@ -24,6 +43,13 @@ it(`renders all versions`, () => { expect(get('twirl')).toBeInTheDocument() }) +it(`renders two bars in a simple burger`, () => { + const { getByTestId: get } = render() + + expect(get('bar-one')).toBeInTheDocument() + expect(get('bar-two')).toBeInTheDocument() +}) + it(`renders three bars in a simple burger`, () => { const { getByTestId: get } = render() @@ -32,6 +58,15 @@ it(`renders three bars in a simple burger`, () => { expect(get('bar-three')).toBeInTheDocument() }) +it(`renders two bars in a complex burger`, () => { + const { getByTestId: get } = render() + + expect(get('bar-wrap-one')).toBeInTheDocument() + expect(get('bar-one')).toBeInTheDocument() + expect(get('bar-wrap-two')).toBeInTheDocument() + expect(get('bar-two')).toBeInTheDocument() +}) + it(`renders three bars in a complex burger`, () => { const { getByTestId: get } = render() diff --git a/tests/hideOutline.test.tsx b/tests/hideOutline.test.tsx new file mode 100644 index 0000000..1ea35b2 --- /dev/null +++ b/tests/hideOutline.test.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import Hamburger from '../src' +import { render } from '@testing-library/react' + +it('is hidden by default', () => { + const { getByTestId: get } = render() + + expect(get('tilt')).toHaveStyle({ outline: 'none' }) +}) + +it(`can be set to visible`, () => { + const { getByTestId: get } = render() + + expect(get('tilt')).not.toHaveStyle({ outline: 'none' }) +})