Skip to content

Commit

Permalink
feat(panel): new Side Panel component
Browse files Browse the repository at this point in the history
  • Loading branch information
nolimits4web committed Sep 6, 2021
1 parent 7c11178 commit b9ca8ba
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
99 changes: 99 additions & 0 deletions src/react/components/Panel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React, { useRef, forwardRef, useImperativeHandle } from 'react';
import { cls } from '../shared/cls.js';
import { positionClass } from '../shared/position-class.js';
import { useDarkClasses } from '../shared/use-dark-classes.js';
import { useThemeClasses } from '../shared/use-theme-classes.js';

const Panel = forwardRef((props, ref) => {
const {
component = 'div',
className,
colors: colorsProp,

size = 'w-72 h-screen',
side = 'left',
opened,
backdrop = true,
onBackdropClick,

ios,
material,

// Children
children,

// Rest
...rest
} = props;

const elRef = useRef(null);

useImperativeHandle(ref, () => ({
el: elRef.current,
}));

const state = opened ? 'opened' : 'closed';

const Component = component;

const attrs = {
...rest,
};

const themeClasses = useThemeClasses({ ios, material });
const dark = useDarkClasses();

const colors = {
bg: cls('bg-white', dark('dark:bg-black')),
...colorsProp,
};

const c = themeClasses(
{
base: {
common: cls(
'top-0 transition-transform transform duration-400 z-40 max-w-full max-h-full overflow-hidden',
colors.bg,
positionClass('fixed', className),
size
),
ios: '',
material: 'shadow-2xl',
},
left: {
common: cls('no-safe-areas-right left-0'),
opened: 'translate-x-0',
closed: '-translate-x-full',
},
right: {
common: cls('no-safe-areas-left left-full'),
opened: '-translate-x-full',
closed: 'translate-x-0',
},
backdrop: {
common:
'fixed z-40 w-full h-full left-0 top-0 bg-black bg-opacity-50 duration-400',
opened: '',
closed: 'opacity-0 pointer-events-none',
},
},
className
);

const classes = cls(c.base, c[side][state]);

return (
<>
{backdrop && (
<div className={c.backdrop[state]} onClick={onBackdropClick} />
)}
<Component ref={elRef} className={classes} {...attrs}>
{children}
</Component>
</>
);
});

Panel.displayName = 'Panel';

export default Panel;
2 changes: 2 additions & 0 deletions src/react/tailwind-mobile-react.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import MenuListItem from './components/MenuListItem.jsx';
import Navbar from './components/Navbar.jsx';
import NavbarBackLink from './components/NavbarBackLink.jsx';
import Page from './components/Page.jsx';
import Panel from './components/Panel.jsx';
import Popover from './components/Popover.jsx';
import Popup from './components/Popup.jsx';
import Preloader from './components/Preloader.jsx';
Expand Down Expand Up @@ -70,6 +71,7 @@ export {
Navbar,
NavbarBackLink,
Page,
Panel,
Popover,
Popup,
Preloader,
Expand Down
48 changes: 48 additions & 0 deletions src/types/Panel.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
interface Props {
/**
* Component's HTML Element
*
* @default 'div'
*/
component?: string;
/**
* Object with Tailwind CSS colors classes
* */
colors?: {
/**
* Panel bg color
*
* @default 'bg-white dark:bg-black'
*/
bg?: string;
};
/**
* Tailwind CSS size classes
*
* @default 'w-72 h-screen'
* */
size?: string;

/**
* Panel side
*
* @default 'left'
*/
side?: 'left' | 'right';
/**
* Allows to open/close Panel and set its initial state
*
* @default false
*/
opened?: boolean;
/**
* Enables Panel backdrop (dark semi transparent layer behind)
*
* @default true
*/
backdrop?: boolean;
/**
* Click handler on backdrop element
*/
onBackdropClick?: (e: any) => void;
}

0 comments on commit b9ca8ba

Please sign in to comment.