Skip to content

Commit

Permalink
improved date handling
Browse files Browse the repository at this point in the history
  • Loading branch information
heswell committed Aug 16, 2024
1 parent 79625a3 commit 2c3d725
Show file tree
Hide file tree
Showing 18 changed files with 516 additions and 877 deletions.
1,120 changes: 311 additions & 809 deletions vuu-ui/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions vuu-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"cypress": "13.6.1",
"cypress-axe": "1.5.0",
"cypress-real-events": "1.11.0",
"esbuild": "0.20.1",
"esbuild": "0.23.0",
"esbuild-visualizer": "0.6.0",
"eslint": "8.36.0",
"eslint-config-prettier": "8.7.0",
Expand All @@ -88,7 +88,7 @@
"eslint-plugin-react-hooks": "4.6.0",
"happy-dom": "^12.10.3",
"open": "^10.0.0",
"prettier": "2.8.4",
"prettier": "3.3.3",
"rollup": "^4.14.1",
"rollup-plugin-esbuild": "^6.1.1",
"rollup-plugin-import-css": "^3.5.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
NewFilterClause,
PartialFilterClauseColumnAndOperator,
} from "../../../../../showcase/src/examples/Filters/FilterBar/FilterClause.examples";
} from "../../../../../showcase/src/examples/Filters/FilterClause/FilterClause.examples";

describe("FilterClause", () => {
describe("WHEN new filter clause is rendered", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ const getDate = (t: "start-today" | "start-tomorrow" | "end-today") => {
}
};

describe("WHEN a user applies a date filter", () => {
describe.only("WHEN a user applies a date filter", () => {
const DATE_COLUMN = "lastUpdated";
const startOfToday = getDate("start-today").getTime();
const endOfToday = getDate("end-today").getTime();
Expand Down Expand Up @@ -550,7 +550,10 @@ describe("WHEN a user applies a date filter", () => {
// Add date filter
findAddButton().realClick();
clickListItems(DATE_COLUMN, op);
cy.get(".vuuDatePopup .vuuIconButton").realClick();
cy.findByRole("textbox", { name: "Start date" }).should("be.focused");
cy.realPress("ArrowDown")

// cy.get(".vuuDatePopup .vuuIconButton").realClick();
cy.get(`${VISIBLE_MONTH} .saltCalendarDay-today`).realClick();
cy.realPress("ArrowRight");
clickButton("Save");
Expand Down
12 changes: 11 additions & 1 deletion vuu-ui/packages/vuu-filters/src/filter-bar/FilterBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
);
--vuuFilterEditor-height: var(--filterbar-height);
--flexbar-gap: var(--salt-spacing-100);
--icon-marginTop: 0;

align-items: center;
background-color: var(--salt-container-secondary-background);
Expand All @@ -23,10 +24,10 @@
height: calc(var(--salt-spacing-100) + var(--filterbar-height));
overflow: hidden;
padding: var(--salt-spacing-100) var(--salt-spacing-200);
/* transition: height 0.3s ease-in; */
}

.vuuFilterBar-quick-filter {
--icon-marginTop: 20px;
--filterbar-height: var(
--vuuFilterBar-height,
calc(2 * var(--salt-size-base))
Expand All @@ -40,6 +41,15 @@
height: calc(1px + var(--flexbar-gap) + (2 * var(--filterbar-height)));
}

.vuuFilterBar-iconContainer {
height: 100%;

.saltToggleButtonGroup {
margin-top: var(--icon-marginTop);
transition: margin-top 0.1s ease-in;
}
}

.vuuFilterbar-icon {
display: inline-block;
height: 16px;
Expand Down
6 changes: 2 additions & 4 deletions vuu-ui/packages/vuu-filters/src/filter-bar/FilterBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export const FilterBar = ({
{...htmlAttributes}
className={cx(className, `${classBase}-${filterMode}`)}
>
{startAdornment}
<div className={`${classBase}-iconContainer`}>{startAdornment}</div>
{filterMode === "custom-filter" ? (
<CustomFilters
columnDescriptors={columnDescriptors}
Expand All @@ -144,16 +144,14 @@ export const FilterBar = ({
suggestionProvider={suggestionProvider}
tableSchema={tableSchema}
/>
) : QuickFilterProps ? (
) : (
<QuickFilters
{...QuickFilterProps}
availableColumns={columnDescriptors}
onApplyFilter={onApplyFilter}
suggestionProvider={suggestionProvider}
tableSchema={tableSchema}
/>
) : (
"Missing QuickFilterProps"
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
padding: 0;
height: 16px;
}

.saltDateInput {
width: auto;
}
}

.salt-density-high .vuuFilterClause {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,28 @@ const getFilterClauseDetails = ({ classList }: HTMLElement) => {
return "value";
} else {
throw Error(
"getFilterClauseField, filterClauseElemnent is missing required class name"
"getFilterClauseField, filterClauseElemnent is missing required class name",
);
}
};

export const getFocusedFieldDetails = (): [number, string] | [] => {
const el = document.activeElement as HTMLElement;
const field = queryClosest(el, ".vuuFilterClauseField");
const filterClause = queryClosest(field, ".vuuFilterClause");
if (filterClause && field) {
return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];
} else {
return [];
const field = queryClosest(el, ".vuuFilterClauseField,.saltCalendar");
if (field?.matches(".vuuFilterClauseField")) {
const filterClause = queryClosest(field, ".vuuFilterClause");
if (filterClause && field) {
return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];
}
} else if (field?.matches(".saltCalendar")) {
console.log("muthafucker is ins a calendar");
}
// const filterClause = queryClosest(field, ".vuuFilterClause");
// if (filterClause && field) {
// return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];
// } else {
return [];
// }
};

// Focus the input control within field. If clause passed, will
Expand All @@ -52,24 +60,24 @@ const focusField = (fieldOrClause: HTMLElement | null) => {
};

export const elementIsFilterCombinator = (
element: Element | null
element: Element | null,
): element is HTMLElement =>
element !== null && element.classList.contains("vuuFilterClauseCombinator");

export const elementIsFilterClause = (
element: Element | null
element: Element | null,
): element is HTMLElement =>
element !== null && element.classList.contains("vuuFilterClause");

export const focusFilterClauseField = (
filterEditor: HTMLElement,
filterClauseIndex: number,
fieldName: FilterClauseFieldName = "value"
fieldName: FilterClauseFieldName = "value",
) => {
if (filterEditor) {
const fieldClassName = mapFilterFieldToClassName[fieldName];
const field = filterEditor.querySelector(
`.vuuFilterClause[data-index="${filterClauseIndex}"] .${fieldClassName}`
`.vuuFilterClause[data-index="${filterClauseIndex}"] .${fieldClassName}`,
) as HTMLElement;
focusField(field);
}
Expand All @@ -78,7 +86,7 @@ export const focusFilterClauseField = (
export const focusLastClauseValue = (filterEditor: HTMLElement) => {
console.log("focusLastClauseValue");
const field = Array.from(
filterEditor?.querySelectorAll(".vuuFilterClauseField")
filterEditor?.querySelectorAll(".vuuFilterClauseField"),
).at(-1) as HTMLElement;
focusField(field);
};
Expand Down Expand Up @@ -115,7 +123,7 @@ export const focusNextElement = () => {
if (filterClause && filterClauseField) {
if (filterClauseField.classList.contains("vuuFilterClauseValue")) {
const clearButton = filterClause.querySelector(
".vuuFilterClause-clearButton"
".vuuFilterClause-clearButton",
) as HTMLButtonElement;
clearButton?.focus();
} else {
Expand All @@ -134,8 +142,8 @@ const getFieldName = (field: HTMLElement) =>
field?.classList.contains("vuuFilterClauseColumn")
? "column"
: field?.classList.contains("vuuFilterClauseOperator")
? "operator"
: "value";
? "operator"
: "value";

export const clauseIsNotFirst = (el: HTMLElement) => {
const clause = getFilterClauseElement(el);
Expand All @@ -160,14 +168,14 @@ export const tabToPreviousFilterCombinator = (currentElement: HTMLElement) => {

export const navigateToNextFilterClause = (
currentElement: HTMLElement,
direction: "bwd" | "fwd" = "fwd"
direction: "bwd" | "fwd" = "fwd",
) => {
if (direction === "bwd") {
if (elementIsFilterCombinator(currentElement)) {
const nextClause = currentElement.previousElementSibling;
if (elementIsFilterClause(nextClause)) {
const nextField = nextClause.querySelector(
".vuuFilterClauseValue"
".vuuFilterClauseValue",
) as HTMLElement;
console.log(`focus field Value ${nextField?.classList}`);
focusField(nextField);
Expand All @@ -176,7 +184,7 @@ export const navigateToNextFilterClause = (
const filterClause = getFilterClauseElement(currentElement);
const nextClause = filterClause.previousSibling as HTMLElement;
const nextField = nextClause.querySelector(
".vuuFilterClauseValue"
".vuuFilterClauseValue",
) as HTMLElement;
focusField(nextField);
}
Expand All @@ -189,7 +197,7 @@ export const navigateToNextFilterClause = (
// The logic around preventDefault/stopPropagation is important
// in this function
export const navigateToNextItemIfAtBoundary = (
evt: KeyboardEvent<HTMLInputElement>
evt: KeyboardEvent<HTMLInputElement>,
) => {
const input = evt.target as HTMLInputElement;
const field = getFilterClauseFieldElement(input);
Expand Down Expand Up @@ -231,10 +239,10 @@ export const navigateToNextItemIfAtBoundary = (
};

export const focusFirstClauseIfAllClausesValid = (
filterEditor: HTMLElement
filterEditor: HTMLElement,
) => {
const columInput = Array.from(
filterEditor.querySelectorAll(".vuuFilterClauseColumn input")
filterEditor.querySelectorAll(".vuuFilterClauseColumn input"),
) as HTMLInputElement[];
if (columInput.every((input) => input.value.length > 0)) {
setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export const FilterClauseValueEditor = forwardRef(
<FilterClauseValueEditorDate
inputProps={inputProps}
className={cx(`${classBase}Field`, `${classBase}Value`)}
data-field="value"
// ref={forwardedRef}
value={value as number}
operator={operator as NumericFilterClauseOp}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import React, {
useCallback,
useState,
} from "react";
import cx from "clsx";
import React, { useCallback, useState } from "react";
import { getLocalTimeZone, DateValue } from "@internationalized/date";
import { CommitHandler, toCalendarDate } from "@finos/vuu-utils";
import { NumericFilterClauseOp } from "@finos/vuu-filter-types";
Expand Down Expand Up @@ -46,8 +42,9 @@ export const FilterClauseValueEditorDate = (

return (
<VuuDatePicker
data-field="value"
inputProps={inputProps}
className={cx("vuuFilterClause-DatePicker", className)}
className={className}
onBlur={onBlur}
onCommit={handleCommit}
selectedDate={date}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface QuickFilterProps
allowFind?: boolean;
availableColumns: ColumnDescriptor[];
onChangeQuickFilterColumns?: (columns: string[]) => void;
quickFilterColumns: string[];
quickFilterColumns?: string[];
/**
* Render a general 'search' control.
* if true, all columns of type 'string' will be included in the search. Otherwise
Expand Down
2 changes: 1 addition & 1 deletion vuu-ui/packages/vuu-ui-controls/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@finos/vuu-popups": "0.0.26",
"@finos/vuu-table": "0.0.26",
"@finos/vuu-utils": "0.0.26",
"@floating-ui/react": "0.26.5",
"@floating-ui/react": "^0.26.5",
"@salt-ds/core": "1.34.0",
"@salt-ds/icons": "1.12.1",
"@salt-ds/styles": "0.2.1",
Expand Down
3 changes: 3 additions & 0 deletions vuu-ui/packages/vuu-ui-controls/src/calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { getCurrentLocale } from "./internal/utils";

export type CalendarProps = useCalendarProps & {
className?: string;
id?: string;
renderDayContents?: CalendarCarouselProps["renderDayContents"];
hideYearDropdown?: CalendarNavigationProps["hideYearDropdown"];
borderedDropdown?: CalendarNavigationProps["borderedDropdown"];
Expand All @@ -35,6 +36,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarProps>(
function Calendar(props, ref) {
const {
className,
id,
renderDayContents,
hideYearDropdown,
TooltipProps,
Expand Down Expand Up @@ -77,6 +79,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarProps>(
>
<div
className={clsx(withBaseName(), className)}
id={id}
role="application"
aria-label={calendarLabel}
ref={ref}
Expand Down
14 changes: 13 additions & 1 deletion vuu-ui/packages/vuu-ui-controls/src/date-picker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
useFloatingUI,
useForkRef,
useFormFieldProps,
useId,
} from "@salt-ds/core";
import { CalendarIcon } from "@salt-ds/icons";
import {
Expand Down Expand Up @@ -130,6 +131,7 @@ export const DatePicker = forwardRef<
dateFormatter,
CalendarProps,
className,
id: idProp,
open: openProp,
defaultOpen,
onOpenChange: onOpenChangeProp,
Expand Down Expand Up @@ -158,6 +160,8 @@ export const DatePicker = forwardRef<
state: "selectedDate",
});

const id = useId(idProp);

const [startVisibleMonth, setStartVisibleMonth] = useState<
DateValue | undefined
>(
Expand Down Expand Up @@ -248,12 +252,16 @@ export const DatePicker = forwardRef<
getPanelPosition,
};

const calendarId = `${id}-calendar`;

return (
<DatePickerContext.Provider value={datePickerContextValue}>
<DateInput
aria-owns={calendarId}
validationStatus={validationStatus}
bordered={bordered}
className={clsx(withBaseName(), className)}
id={id}
ref={inputRef}
{...getReferenceProps()}
startInputRef={startInputRef}
Expand All @@ -279,7 +287,11 @@ export const DatePicker = forwardRef<
ref={floatingRef}
{...getFloatingProps()}
onSelect={handleSelect}
CalendarProps={{ ...CalendarProps, borderedDropdown: bordered }}
CalendarProps={{
...CalendarProps,
borderedDropdown: bordered,
id: calendarId,
}}
helperText={helperText}
visibleMonths={visibleMonths}
/>
Expand Down
Loading

0 comments on commit 2c3d725

Please sign in to comment.