Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { ComponentProps, ComponentType, useCallback, useState } from 'react';
- import { Interactive } from 'react-interactive';
- import classNames from 'classnames';
- export type onSelectionCallback = (value: string) => void;
- export type SelectProps = ComponentProps<typeof Interactive> & {
- variant?: 'primary' | 'secondary';
- values: string[];
- placeholder?: string;
- onSelection?: onSelectionCallback;
- };
- const border = `border border-1 border-white
- `;
- const CLASSES = {
- base: 'py-5 px-8 font-bold text-white hover:no-underline text-center',
- variant: {
- primary: `bg-red ${border}`,
- secondary: `bg-black`,
- },
- };
- const DROPDOWN_CLASSES = {
- base: 'z-10 absolute top-[64px] mt-1 py-2 px-8 text-white list-none',
- variant: {
- primary: 'bg-red border border-white border-1',
- secondary: 'bg-black',
- }
- };
- const DROPDOWN_ITEM_CLASSES = 'block font-bold text-white py-2 hover:text-white';
- export const Select: ComponentType<SelectProps> = ({
- as = 'button',
- variant = 'primary',
- className,
- onSelection,
- placeholder,
- values,
- ...props
- }) => {
- const [active, setActive] = useState(false)
- const [activeSelection, setActiveSelection] = useState(values[0])
- const handleDropdown = useCallback(
- ({state, prevState}) => {
- if (state.active) {
- setActive(true)
- }
- if (state.focus === false) {
- setActive(false)
- }
- },
- [active]
- )
- return (
- <div className="inline-block relative">
- <Interactive
- className={classNames(
- CLASSES.base,
- CLASSES.variant[variant],
- className
- )}
- as={as}
- onStateChange={handleDropdown}
- {...props}
- ><div className="flex items-center">{placeholder ? placeholder : activeSelection} <ArrowDown rotate={active} /></div></Interactive>
- <div className={classNames(DROPDOWN_CLASSES.base, { hidden: !active }, CLASSES.variant[variant])}>
- <ul className="py-1" aria-labelledby="dropdownButton">
- {
- values.map((item, key) => {
- return (
- <li key={key}>
- <Interactive className={DROPDOWN_ITEM_CLASSES} onStateChange={({ state, prevState }) => { if (state.focus !== false && prevState.focus === false) { setActiveSelection(item); if (onSelection) onSelection(item) } }}>{item}</Interactive>
- </li>
- )
- })
- }
- </ul>
- </div>
- </div>
- );
- }
- const ArrowDown: React.FC<{rotate: boolean}> = ({ rotate }) => {
- return (
- <div className="ml-4">
- <svg width="13" height="9" viewBox="0 0 13 9" fill="none" xmlns="http://www.w3.org/2000/svg" className={`transition .3s ease ${rotate ? '-rotate-90' : ''}`}>
- <path fillRule="evenodd" clipRule="evenodd" d="M3.09159 1.99951L7.00159 6.82151L10.9866 1.99951H3.09159ZM6.99959 8.99951C6.49359 8.99951 6.00959 8.76651 5.67359 8.35751L1.46059 3.25951C0.956594 2.64851 0.856594 1.78151 1.20159 1.04851C1.50659 0.401512 2.11359 -0.000488281 2.78659 -0.000488281H11.2126C11.8856 -0.000488281 12.4926 0.401512 12.7976 1.04851C13.1436 1.78151 13.0426 2.64851 12.5396 3.25851L8.32559 8.35751C7.98959 8.76651 7.50559 8.99951 6.99959 8.99951Z" fill="white"/>
- </svg>
- </div>
- )
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement