Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add portfolio filter info alert on overview map #744

Merged
merged 29 commits into from
Apr 12, 2023
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f97e3b9
add react-select package
austensen Apr 5, 2023
5665f10
add react-relect (wip)
austensen Apr 6, 2023
623bb31
add back placeholder styles
austensen Apr 6, 2023
819cef2
separated selected values working
austensen Apr 6, 2023
62a5ae5
add more/less selections
austensen Apr 7, 2023
d6f2549
custom close icon for selected values
austensen Apr 7, 2023
01c44c4
replace old multiselect, new functional, styled for desktop
austensen Apr 7, 2023
e5ad5f2
fix multiselect error placement and input border
austensen Apr 7, 2023
d864725
fix info-alert styles
austensen Apr 7, 2023
f6ce0fa
multiselect mobile styles, start refactoring filter styles
austensen Apr 8, 2023
3608053
separate out MinMaxSelect component
austensen Apr 8, 2023
e160550
separate out MinMaxSelect styles
austensen Apr 8, 2023
909a533
fix up alert styles for no-close, align apply buttons
austensen Apr 8, 2023
c59cf10
finish styles refactor, fix multiselect apply move
austensen Apr 8, 2023
05cee1a
fix primary button letter spacing (from #738)
austensen Apr 8, 2023
ff20821
Merge 'filters' into multiselect-screen-reader
austensen Apr 8, 2023
b4a563f
reduce font weight for table body (except firefox)
austensen Apr 9, 2023
04c10c2
remove old styles mistakenly adding in 'filters' merge
austensen Apr 9, 2023
0176fdb
fix min-max label font styles & "to" -> "and"
austensen Apr 9, 2023
752f464
delete old multiselect styles file
austensen Apr 9, 2023
5afdd2c
"Zip Code" (fix capitalization)
austensen Apr 9, 2023
f2db0b4
add portfolio filter info alert on overview map, update big portfolio…
austensen Apr 9, 2023
57bf5ca
adjust down firefox font-weight in minmax- & multi-select components
austensen Apr 9, 2023
623503d
fix multiselect filename
austensen Apr 9, 2023
cfc797f
adjust desktop filter dropdowns for scrollbars on windows
austensen Apr 10, 2023
6715daa
add aria labels for multiselect buttons & description on input
austensen Apr 10, 2023
fa6a0dd
Merge in 'multiselect-rewrite' changes
austensen Apr 10, 2023
0497012
keep portfolio alerts closed for session
austensen Apr 10, 2023
10b2563
Merge branch 'filters' into overview-filter-alert
austensen Apr 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add aria labels for multiselect buttons & description on input
austensen committed Apr 10, 2023
commit 6715daa8e90ee2be52eafd31878ad915f6d51f0a
37 changes: 33 additions & 4 deletions client/src/components/Multiselect.tsx
Original file line number Diff line number Diff line change
@@ -6,14 +6,15 @@ import Select, {
GroupBase,
MultiValueRemoveProps,
OptionProps,
InputProps,
} from "react-select";
import { I18n } from "@lingui/core";
import { I18n, i18n } from "@lingui/core";
import { t, Trans } from "@lingui/macro";
import { Alert } from "./Alert";
import { CloseIcon, CheckIcon } from "./Icons";
import classnames from "classnames";

// Example of separating out selected values (sadly with many typescript errors, which I've tried to address)
// Example of separating out selected values
// https://github.com/JedWatson/react-select/discussions/4850

export type Option = {
@@ -38,6 +39,11 @@ interface CustomSelectProps {
setShowAllSelections: (x: any) => void;
}

const ariaLiveGuidanceGeneral = `Type to refine list of options. Use Up and Down to choose options,
press Enter to select the currently focused option, press Escape to exit the menu.
Use Left and Right to toggle between selected values,
press Backspace to remove the currently focused value`;

function CustomSelect<
Option,
IsMulti extends boolean = true,
@@ -132,6 +138,7 @@ function MultiSelect<
ClearIndicator: () => null,
SelectContainer: SelectContainer,
Option: CustomOption,
Input: CustomInput,
}}
// Custom props passed through SelectProps to composable components
removeValue={removeValue}
@@ -147,6 +154,7 @@ function MultiSelect<

<button
className="button is-primary"
aria-label={i18n._(t`Apply selections and get results`)}
onClick={handleApply}
// By default, when multiselect option list is open mouseDown outside
// closes the list, so because the Apply button is below, if you try to
@@ -210,17 +218,20 @@ function SelectedValuesContainer<
);
};

const numSelections = getValue().length;

return (
<div className={`${classNamePrefix}__selected-value-container`}>
{getValue()
.map(toMultiValue)
.filter((_value, i) => showAllSelections || i < previewSelectedNum)}
{!showAllSelections && getValue().length > previewSelectedNum && (
{!showAllSelections && numSelections > previewSelectedNum && (
<button
className={`${classNamePrefix}__show-more-button`}
aria-label={i18n._(t`Show all ${numSelections} selections`)}
onClick={() => setShowAllSelections((prev: boolean) => !prev)}
>
+{getValue().length - previewSelectedNum}
+{numSelections - previewSelectedNum}
</button>
)}
</div>
@@ -263,13 +274,15 @@ function SelectContainer<
<button
className={`${classNamePrefix}__show-less-button button is-text`}
onClick={() => setShowAllSelections((prev: boolean) => !prev)}
aria-label={i18n._(t`Show only ${previewSelectedNum} selections`)}
>
<Trans>Show less</Trans>
</button>
)}
{getValue().length > 0 && (
<button
className={`${classNamePrefix}__clear-value-button button is-text`}
aria-label={i18n._(t`Clear all selections`)}
onClick={() => {
setSelections([]);
onApply([]);
@@ -296,6 +309,22 @@ function CustomMultiValueRemove<
);
}

function CustomInput<
Option,
IsMulti extends boolean = true,
GroupType extends GroupBase<Option> = GroupBase<Option>
>(props: InputProps<Option, IsMulti, GroupType>) {
const id = "test-123456789";
return (
<>
<components.Input {...props} aria-describedby={id}></components.Input>
<span hidden id={id}>
{ariaLiveGuidanceGeneral}
</span>
</>
);
}

function CustomOption<
Option,
IsMulti extends boolean = true,
11 changes: 9 additions & 2 deletions client/src/components/PortfolioFilters.tsx
Original file line number Diff line number Diff line change
@@ -137,6 +137,7 @@ export const PortfolioFilters = React.memo(
aria-pressed={rsunitslatestActive}
onClick={updateRsunitslatest}
className="filter filter-toggle"
aria-label={i18n._(t`Rent Stabilized Units filter`)}
>
<div className="checkbox">{rsunitslatestActive && <CheckIcon />}</div>
<span>
@@ -154,14 +155,15 @@ export const PortfolioFilters = React.memo(
initialFocus={isMobile ? undefined : "#filter-ownernames-multiselect input"}
selectionsCount={filterContext.filterSelections.ownernames.length}
className="ownernames-accordion"
i18n={i18n}
>
<MultiSelect
id="filter-ownernames-multiselect"
options={ownernamesOptionsSelect}
onApply={onOwnernamesApply}
i18n={i18n}
infoAlert={OwnernamesInfoAlert}
noOptionsMessage={() => i18n._(t`Zip code is not applicable`)}
aria-label={i18n._(t`Landlord filter`)}
/>
</FilterAccordion>
<FilterAccordion
@@ -173,6 +175,7 @@ export const PortfolioFilters = React.memo(
initialFocus={isMobile ? undefined : "#filter-unitsres-minmax_min-input"}
setIsOpen={setUnitsresIsOpen}
className="unitsres-accordion"
i18n={i18n}
>
<MinMaxSelect
options={filterContext.filterOptions.unitsres}
@@ -190,13 +193,15 @@ export const PortfolioFilters = React.memo(
initialFocus={isMobile ? undefined : "#filter-zip-multiselect input"}
selectionsCount={filterContext.filterSelections.zip.length}
className="zip-accordion"
i18n={i18n}
>
<MultiSelect
id="filter-zip-multiselect"
options={zipOptionsSelect}
onApply={onZipApply}
i18n={i18n}
noOptionsMessage={() => i18n._(t`ZIP code is not applicable`)}
aria-label={i18n._(t`Zip code filter`)}
onKeyDown={helpers.preventNonNumericalInput}
/>
</FilterAccordion>
@@ -431,6 +436,7 @@ function FilterAccordion(props: {
initialFocus?: FocusTarget;
selectionsCount?: number;
className?: string;
i18n: I18n;
}) {
const {
title,
@@ -444,6 +450,7 @@ function FilterAccordion(props: {
initialFocus,
selectionsCount,
className,
i18n,
} = props;

return (
@@ -454,7 +461,6 @@ function FilterAccordion(props: {
returnFocusOnDeactivate: false,
onDeactivate: () => setIsOpen(false),
initialFocus: initialFocus,
// escapeDeactivates: false,
}}
>
<details
@@ -467,6 +473,7 @@ function FilterAccordion(props: {
setIsOpen(!isOpen);
}}
data-selections={selectionsCount}
aria-label={i18n._(t`Filter`)}
>
{title}
{isActive && selectionsCount && (!isOpen || isMobile) && (
48 changes: 40 additions & 8 deletions client/src/locales/en/messages.po
Original file line number Diff line number Diff line change
@@ -142,10 +142,14 @@ msgstr "An “eviction filing” is a legal case for eviction commenced by a lan
#~ msgstr "An “eviction filing” is a legal case for eviction commenced by a landlord against a tenant in Housing Court. Such a case can be commenced for nonpayment of rent (most commonly) or for a violation of the lease (such as a nuisance). The eviction filings number only represents cases filed in Housing Court (data from the New York State Office of Court Administration<0>via the Housing Data Coalition</0> in collaboration with the <1>Right to Counsel Coalition</1>) and not evictions carried out by NYC Marshals.<2/>If you or someone you know is facing eviction and want to learn more about your rights, head over to <3>Housing Court Answers for more information</3>.<4/>Due to privacy restrictions on the use of these data, eviction filings cannot be shown for buildings with fewer than 11 units."

#: src/components/MinMaxSelect.tsx:50
#: src/components/MultiSelect.tsx:77
#: src/components/Multiselect.tsx:83
msgid "Apply"
msgstr "Apply"

#: src/components/Multiselect.tsx:78
msgid "Apply selections and get results"
msgstr "Apply selections and get results"

#: src/components/DetailView.tsx:261
msgid "Are you having issues in this building?"
msgstr "Are you having issues in this building?"
@@ -247,7 +251,7 @@ msgstr "Class C"
msgid "Class I"
msgstr "Class I"

#: src/components/MultiSelect.tsx:132
#: src/components/Multiselect.tsx:139
msgid "Clear"
msgstr "Clear"

@@ -259,6 +263,10 @@ msgstr "Clear Filters"
#~ msgid "Clear all"
#~ msgstr "Clear all"

#: src/components/Multiselect.tsx:135
msgid "Clear all selections"
msgstr "Clear all selections"

#: src/components/FeatureCalloutContent.ts:13
msgid "Clearer Landlord Contact Info"
msgstr "Clearer Landlord Contact Info"
@@ -453,6 +461,10 @@ msgstr "Filed"
#~ msgid "Filied"
#~ msgstr "Filied"

#: src/components/PortfolioFilters.tsx:236
msgid "Filter"
msgstr "Filter"

#: src/components/PortfolioFilters.tsx:175
msgid "Filters"
msgstr "Filters"
@@ -601,6 +613,10 @@ msgstr "LOCKS"
msgid "Landlord"
msgstr "Landlord"

#: src/components/PortfolioFilters.tsx:90
msgid "Landlord filter"
msgstr "Landlord filter"

#: src/containers/HomePage.tsx:108
msgid "Landlord name"
msgstr "Landlord name"
@@ -694,7 +710,7 @@ msgstr "Made with NYC ♥ by the team at <0>JustFix.org</0>"
msgid "Maintenance code violations"
msgstr "Maintenance code violations"

#: src/components/MultiSelect.tsx:57
#: src/components/Multiselect.tsx:62
msgid "Make a selection from the list or clear search text"
msgstr "Make a selection from the list or clear search text"

@@ -966,6 +982,10 @@ msgstr "Registration expired:"
msgid "Rent Stabilized Units"
msgstr "Rent Stabilized Units"

#: src/components/PortfolioFilters.tsx:83
msgid "Rent Stabilized Units filter"
msgstr "Rent Stabilized Units filter"

#: src/components/PropertiesSummary.tsx:125
msgid "Rent stabilization"
msgstr "Rent stabilization"
@@ -994,7 +1014,7 @@ msgstr "SIGNAGE MISSING"
msgid "STAIRS"
msgstr "STAIRS"

#: src/components/MultiSelect.tsx:59
#: src/components/Multiselect.tsx:64
#: src/containers/App.tsx:87
msgid "Search"
msgstr "Search"
@@ -1041,10 +1061,18 @@ msgstr "Share this page with your neighbors"
msgid "Shareholder"
msgstr "Shareholder"

#: src/components/MultiSelect.tsx:126
#: src/components/Multiselect.tsx:118
msgid "Show all {numSelections} selections"
msgstr "Show all {numSelections} selections"

#: src/components/Multiselect.tsx:133
msgid "Show less"
msgstr "Show less"

#: src/components/Multiselect.tsx:132
msgid "Show only {previewSelectedNum} selections"
msgstr "Show only {previewSelectedNum} selections"

#: src/components/PortfolioFilters.tsx:103
msgid "Showing {0} {1, plural, one {result} other {results}}"
msgstr "Showing {0} {1, plural, one {result} other {results}}"
@@ -1444,7 +1472,7 @@ msgstr "What happens if the landlord has failed to register?"
msgid "What's New"
msgstr "What's New"

#: src/components/PortfolioFilters.tsx:246
#: src/components/PortfolioFilters.tsx:245
msgid "What's this?"
msgstr "What's this?"

@@ -1526,9 +1554,13 @@ msgstr "ZIP code is not applicable"
msgid "Zip Code"
msgstr "Zip Code"

#: src/components/PortfolioFilters.tsx:96
msgid "Zip code filter"
msgstr "Zip code filter"

#: src/components/PortfolioFilters.tsx:90
msgid "Zip code is not applicable"
msgstr "Zip code is not applicable"
#~ msgid "Zip code is not applicable"
#~ msgstr "Zip code is not applicable"

#: src/components/PortfolioGraph.tsx:133
msgid "Zoom in"
Loading