import React, { useState, useRef } from 'react'; import { Link } from 'react-router-dom'; import { makeStyles } from '@material-ui/styles'; import Menu from '@material-ui/core/Menu'; import MenuItem from '@material-ui/core/MenuItem'; import ArrowDropDown from '@material-ui/icons/ArrowDropDown'; function parse(query) { // TODO: extract the rest of the query? const params = {}; // TODO: support escaping without quotes const re = /(\w+):([A-Za-z0-9-]+|(["'])(([^\3]|\\.)*)\3)+/g; let matches; while ((matches = re.exec(query)) !== null) { if (!params[matches[1]]) { params[matches[1]] = []; } let value; if (matches[4]) { value = matches[4]; } else { value = matches[2]; } value = value.replace(/\\(.)/g, '$1'); params[matches[1]].push(value); } return params; } function quote(value) { const hasSingle = value.includes("'"); const hasDouble = value.includes('"'); const hasSpaces = value.includes(' '); if (!hasSingle && !hasDouble && !hasSpaces) { return value; } if (!hasDouble) { return `"${value}"`; } if (!hasSingle) { return `'${value}'`; } value = value.replace(/"/g, '\\"'); return `"${value}"`; } function stringify(params) { const parts = Object.entries(params).map(([key, values]) => { return values.map(value => `${key}:${quote(value)}`); }); return [].concat(...parts).join(' '); } const useStyles = makeStyles(theme => ({ element: { ...theme.typography.body2, color: ({ active }) => (active ? '#333' : '#444'), padding: theme.spacing(0, 1), fontWeight: ({ active }) => (active ? 600 : 400), textDecoration: 'none', display: 'flex', background: 'none', border: 'none', }, itemActive: { fontWeight: 600, }, icon: { paddingRight: theme.spacing(0.5), }, })); function Dropdown({ children, dropdown, itemActive, to, ...props }) { const [open, setOpen] = useState(false); const buttonRef = useRef(); const classes = useStyles(); return ( <> setOpen(false)} anchorEl={buttonRef.current} > {dropdown.map(([key, value]) => ( setOpen(false)} key={key} > {value} ))} ); } function Filter({ active, to, children, icon: Icon, dropdown, ...props }) { const classes = useStyles({ active }); const content = ( <> {Icon && }
{children}
); if (dropdown) { return ( {content} ); } if (to) { return ( {content} ); } return
{content}
; } export default Filter; export { parse, stringify, quote };