Skip to content

Commit 358d3c2

Browse files
committed
Replace hand-rolled dropdown on the dashboard and menu-related UI fixes (#5037)
* Try popover * Pass targetRef instead of target, stop Escape clearing filters * Stop Escape clearing filters when popover menus active * Attempt get rid of hand-rolled dropdown * Fix issue with comparison calendar * Almost works * Unify styles * Focus modals on mount * Refactor date picker logic * Replace navigate keybinds with straightforward keybinds * Remove extraneous Calendar component, better props * Attempt optimise menu re-renders * Memoise QueryPeriodsMenu, refactor getDatePeriodGroups * Refactor ComparisonMenu to Popover * Refactor QueryPeriodMenu to Popover * Pull calendar out of components * Refactor calendar to receive position from JS * Simpler calendar API * Add click outside listener for Calendar, fix FiltersBar measurements * Give back top bar room * Update tests * Apply unified button text style * Close calendar on keyboard nav to othe menus as well * Kinda works * Works even better * Working well * Sometimes menu stays active * WIP * Adapter * Works with error * Fixed the error * Remove handrolled isOpen * Introduce shared adapter * Share adapter
1 parent 0e83628 commit 358d3c2

28 files changed

+1328
-1171
lines changed

assets/css/app.css

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
@import './modal.css';
66
@import './loader.css';
77
@import './tooltip.css';
8-
@import './flatpickr.css';
8+
@import './flatpickr-colors.css';
99
@import './chartjs.css';
1010
@import 'tailwindcss/components';
1111
@import 'tailwindcss/utilities';
@@ -246,11 +246,6 @@ blockquote {
246246
transition: opacity 100ms ease-in;
247247
}
248248

249-
.flatpickr-calendar.static.open {
250-
right: 2px;
251-
top: 12px;
252-
}
253-
254249
.datamaps-subunit {
255250
cursor: pointer;
256251
}
Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,6 @@
11
/* @format */
22
/* stylelint-disable media-feature-range-notation */
33
/* stylelint-disable selector-class-pattern */
4-
.flatpickr-calendar::before,
5-
.flatpickr-calendar::after {
6-
right: 22px !important;
7-
}
8-
9-
.flatpickr-wrapper {
10-
right: 35% !important;
11-
}
12-
13-
@media (max-width: 768px) {
14-
.flatpickr-wrapper {
15-
right: 50% !important;
16-
}
17-
}
18-
19-
@media (max-width: 768px) {
20-
.flatpickr-wrapper {
21-
position: absolute !important;
22-
right: 0 !important;
23-
left: 0 !important;
24-
}
25-
}
264

275
/* Because Flatpickr offers zero support for dynamic theming on its own (outside of third-party plugins) */
286
.dark .flatpickr-calendar {

assets/js/dashboard/components/dropdown.tsx

Lines changed: 0 additions & 175 deletions
This file was deleted.

assets/js/dashboard/components/filter-operator-selector.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** @format */
22

3-
import React, { Fragment } from 'react'
3+
import React, { Fragment, useRef } from 'react'
44

55
import {
66
FILTER_OPERATIONS,
@@ -12,9 +12,11 @@ import {
1212
import { Menu, Transition } from '@headlessui/react'
1313
import { ChevronDownIcon } from '@heroicons/react/20/solid'
1414
import classNames from 'classnames'
15+
import { BlurMenuButtonOnEscape } from '../keybinding'
1516

1617
export default function FilterOperatorSelector(props) {
1718
const filterName = props.forFilter
19+
const buttonRef = useRef()
1820

1921
function renderTypeItem(operation, shouldDisplay) {
2022
return (
@@ -46,8 +48,12 @@ export default function FilterOperatorSelector(props) {
4648
<Menu as="div" className="relative inline-block text-left w-full">
4749
{({ open }) => (
4850
<>
51+
<BlurMenuButtonOnEscape targetRef={buttonRef} />
4952
<div className="w-full">
50-
<Menu.Button className="inline-flex justify-between items-center w-full rounded-md border border-gray-300 dark:border-gray-500 shadow-sm px-4 py-2 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-850 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 text-left">
53+
<Menu.Button
54+
ref={buttonRef}
55+
className="inline-flex justify-between items-center w-full rounded-md border border-gray-300 dark:border-gray-500 shadow-sm px-4 py-2 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-850 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 text-left"
56+
>
5157
{FILTER_OPERATIONS_DISPLAY_NAMES[props.selectedType]}
5258
<ChevronDownIcon
5359
className="-mr-2 ml-2 h-4 w-4 text-gray-500 dark:text-gray-400"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/** @format */
2+
import { TransitionClasses } from '@headlessui/react'
3+
import classNames from 'classnames'
4+
5+
const TRANSITION_CONFIG: TransitionClasses = {
6+
enter: 'transition ease-out duration-100',
7+
enterFrom: 'opacity-0 scale-95',
8+
enterTo: 'opacity-100 scale-100',
9+
leave: 'transition ease-in duration-75',
10+
leaveFrom: 'opacity-100 scale-100',
11+
leaveTo: 'opacity-0 scale-95'
12+
}
13+
14+
const transition = {
15+
props: TRANSITION_CONFIG,
16+
classNames: { fullwidth: 'z-10 absolute left-0 right-0' }
17+
}
18+
19+
const panel = {
20+
classNames: {
21+
roundedSheet:
22+
'focus:outline-none rounded-md shadow-lg bg-white dark:bg-gray-800 ring-1 ring-black ring-opacity-5 font-medium text-gray-800 dark:text-gray-200'
23+
}
24+
}
25+
26+
const toggleButton = {
27+
classNames: {
28+
rounded: 'flex items-center rounded text-sm leading-tight h-9',
29+
shadow:
30+
'bg-white dark:bg-gray-800 shadow text-gray-800 dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-900',
31+
ghost:
32+
'text-gray-500 hover:text-gray-800 hover:bg-gray-200 dark:hover:text-gray-200 dark:hover:bg-gray-900',
33+
truncatedText: 'truncate block font-medium'
34+
}
35+
}
36+
37+
const items = {
38+
classNames: {
39+
navigationLink: classNames(
40+
'flex items-center justify-between',
41+
'px-4 py-2 text-sm leading-tight'
42+
),
43+
selectedOption: classNames('data-[selected=true]:font-bold'),
44+
hoverLink: classNames(
45+
'hover:bg-gray-100',
46+
'hover:text-gray-900',
47+
'dark:hover:bg-gray-900',
48+
'dark:hover:text-gray-100',
49+
50+
'focus-within:bg-gray-100',
51+
'focus-within:text-gray-900',
52+
'dark:focus-within:bg-gray-900',
53+
'dark:focus-within:text-gray-100'
54+
),
55+
roundedStartEnd: classNames(
56+
'first-of-type:rounded-t-md',
57+
'last-of-type:rounded-b-md'
58+
)
59+
}
60+
}
61+
62+
export const popover = {
63+
toggleButton,
64+
panel,
65+
transition,
66+
items
67+
}

assets/js/dashboard/components/search-input.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ export const SearchInput = ({
4343
type="keyup"
4444
handler={blurSearchBox}
4545
shouldIgnoreWhen={[isModifierPressed, () => !isFocused]}
46-
target={searchBoxRef.current}
46+
targetRef={searchBoxRef}
4747
/>
4848
<Keybind
4949
keyboardKey="/"
5050
type="keyup"
5151
handler={focusSearchBox}
5252
shouldIgnoreWhen={[isModifierPressed, () => isFocused]}
53-
target={document}
53+
targetRef="document"
5454
/>
5555
<input
5656
onBlur={() => setIsFocused(false)}

0 commit comments

Comments
 (0)