Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1,445 changes: 748 additions & 697 deletions src/App.js

Large diffs are not rendered by default.

52 changes: 47 additions & 5 deletions src/components/filter/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
transform-origin: top;
transform: scaleY(0);
transition: transform 0.26s ease;
z-index: 1;
/* Raise stacking context so the filter and its controls can appear above page content */
z-index: 1000;
}

.filter-wrapper.full-width {
Expand All @@ -35,7 +36,7 @@
}

.filter-wrapper.open {
box-shadow: 0px 5px 15px 5px rgb( from var(--color-black) r g b / 0.70);
box-shadow: 0px 5px 15px 5px rgb(from var(--color-black) r g b / 0.7);
overflow: visible;
transform: scaleY(1);
}
Expand All @@ -50,7 +51,26 @@
position: fixed;
right: 20px;
width: 6vh;
z-index: 1;
/* Make sure the toggle button sits above the filter when needed */
z-index: 1001;
}

/* Ensure react-select controls and menus in the filter stack above other elements.
Some react-select menus are rendered into a portal (body); adding global rules
here ensures consistent stacking regardless of portal usage. */
.basic-multi-select .select__control {
z-index: 1002;
}

.basic-multi-select .select__menu,
.basic-multi-select .select__menu-list {
z-index: 9999; /* match inline portal z-index used in SelectFilter */
}

/* Also cover portal-mounted menus which are rendered as siblings under <body> */
.select__menu,
.select__menu-list {
z-index: 9999 !important;
}

.filter-toggle-icon-wrapper svg {
Expand All @@ -66,6 +86,20 @@
width: 400px;
}

/* Page-specific tweak: add spacing to filter labels on the barrel attachments page */
.barrel-attachments-filter .single-filter-label {
padding-right: 12px;
}

/* Narrow the inner filter content on the Barrel Attachments page so the
page headline can fit on a single line next to the filter controls. */
.barrel-attachments-filter .filter-content-wrapper {
max-width: 820px; /* reduce from full width to keep headline on one line */
padding-left: 12px;
padding-right: 12px;
justify-content: flex-end;
}

.single-filter-wrapper-wide .basic-multi-select {
flex-grow: 1;
}
Expand Down Expand Up @@ -98,7 +132,15 @@

.basic-multi-select {
min-width: 110px;
color: var(--color-gunmetal-dark);
/* Ensure the select's visible text is light on the dark control background */
color: var(--color-white);
}

/* Make sure the react-select input, single value and placeholder text are readable */
.basic-multi-select .select__input,
.basic-multi-select .select__single-value,
.basic-multi-select .select__placeholder {
color: var(--color-white) !important;
}

.filter-slider-wrapper .MuiSlider-root {
Expand Down Expand Up @@ -140,7 +182,7 @@

.button-group-button:hover img,
.button-group-button.selected img {
opacity: 1.0;
opacity: 1;
}

.button-group-button:first-child {
Expand Down
72 changes: 28 additions & 44 deletions src/components/filter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,7 @@ const ConditionalWrapper = ({ condition, wrapper, children }) => {
return condition ? wrapper(children) : children;
};

function ButtonGroupFilterButton({
tooltipContent,
onClick,
content,
selected,
type = 'image',
}) {
function ButtonGroupFilterButton({ tooltipContent, onClick, content, selected, type = 'image' }) {
return (
<Tooltip placement="top" title={tooltipContent} arrow>
<button
Expand Down Expand Up @@ -53,7 +47,7 @@ function SliderFilter({
valueLabelDisplay = 'auto',
}) {
if (!!marks && !Array.isArray(marks)) {
marks = Object.keys(marks).map(val => {
marks = Object.keys(marks).map((val) => {
return {
label: String(marks[val]),
value: parseInt(val),
Expand Down Expand Up @@ -99,7 +93,7 @@ function RangeFilter({
valueLabelDisplay,
}) {
if (!!marks && !Array.isArray(marks)) {
marks = Object.keys(marks).map(val => {
marks = Object.keys(marks).map((val) => {
return {
label: String(marks[val]),
value: val,
Expand Down Expand Up @@ -166,7 +160,7 @@ const selectFilterStyle = {
multiValueLabel: (provided) => ({
...provided,
color: 'var(--color-yellow-light)',
padding: '0.1rem'
padding: '0.1rem',
}),
menu: (provided) => ({
...provided,
Expand Down Expand Up @@ -208,6 +202,9 @@ const selectFilterStyle = {
}),
};

// Export the style object so pages can reuse the same react-select styles
export { selectFilterStyle };

function SelectFilter({
placeholder,
defaultValue,
Expand All @@ -231,11 +228,7 @@ function SelectFilter({
condition={tooltip}
wrapper={(children) => {
return (
<Tooltip
placement="bottom"
title={tooltip}
arrow
>
<Tooltip placement="bottom" title={tooltip} arrow>
{children}
</Tooltip>
);
Expand All @@ -253,7 +246,7 @@ function SelectFilter({
<span className={'single-filter-label'}>{label}</span>
{labelChildren}
</label>
)
);
}}
>
<Select
Expand All @@ -270,7 +263,9 @@ function SelectFilter({
options={options}
ref={parentRef}
styles={selectFilterStyle}
noOptionsMessage={() => { return t('All options already selected');}}
noOptionsMessage={() => {
return t('All options already selected');
}}
/>
</ConditionalWrapper>
</ConditionalWrapper>
Expand Down Expand Up @@ -299,28 +294,24 @@ function SelectItemFilter({
const selectInputRef = useRef(null);
const { t } = useTranslation();

const elements = [(
const elements = [
<SelectFilter
key={'select-item-filter'}
placeholder={placeholder}
label={label}
options={items.map((item) => {
return {
label: shortNames? item.shortName : item.name,
label: shortNames ? item.shortName : item.name,
value: item[valueField],
selected: selection && selection.id === item.id
selected: selection && selection.id === item.id,
};
})}
onChange={(event) => {
if (!event) {
return true;
}

setSelectedItem(
items.find(
(item) => item.id === event.value,
),
);
setSelectedItem(items.find((item) => item.id === event.value));
if (onChange) {
onChange(event);
}
Expand All @@ -334,31 +325,28 @@ function SelectItemFilter({
tooltipDisabled={tooltipDisabled}
onMenuOpen={onMenuOpen}
onMenuClose={onMenuClose}
/>
)];
/>,
];

if (selectedItem && showImage) {
elements.push((
<Tooltip
title={t('Clear selection')}
arrow
>
elements.push(
<Tooltip title={t('Clear selection')} arrow>
<img
key={'select-item-filter-selected-icon'}
alt={`${selectedItem.name}-icon`}
onClick={() => {
selectInputRef.current?.clearValue();
setSelectedItem(false);
if (onChange) {
onChange({label: '', value: false});
onChange({ label: '', value: false });
}
}}
loading="lazy"
src={selectedItem.iconLink}
style={{cursor: 'pointer'}}
style={{ cursor: 'pointer' }}
/>
</Tooltip>
))
</Tooltip>,
);
}
return elements;
}
Expand All @@ -381,11 +369,7 @@ function InputFilter({
condition={tooltip}
wrapper={(children) => {
return (
<Tooltip
placement="bottom"
title={tooltip}
arrow
>
<Tooltip placement="bottom" title={tooltip} arrow>
{children}
</Tooltip>
);
Expand All @@ -410,14 +394,14 @@ function InputFilter({
);
}

function Filter({ center, children, fullWidth }) {
function Filter({ center, children, fullWidth, className }) {
const [showFilter, setShowFilter] = useState(false);
const toggleButton = useRef();
useEffect(() => {
if (!toggleButton.current) {
return;
}
const intersectionObserver = new IntersectionObserver(entries => {
const intersectionObserver = new IntersectionObserver((entries) => {
if (!toggleButton.current) {
return;
}
Expand Down Expand Up @@ -447,7 +431,7 @@ function Filter({ center, children, fullWidth }) {
<div
className={`filter-wrapper${showFilter ? ' open' : ''}${
center ? ' filter-wrapper-center' : ''
}${fullWidth ? ' full-width' : ''}`}
}${fullWidth ? ' full-width' : ''} ${className || ''}`}
key="page-filter"
>
<div className={'filter-content-wrapper'}>
Expand Down
Loading