Skip to content

Commit

Permalink
Allow limiting the allowed breakpoints when calling getBreakpoint()
Browse files Browse the repository at this point in the history
Also:
* Limit allowed breakpoints to those provided by the `responsive` prop of Oui*Breadcrumbs

Signed-off-by: Miki <miki@amazon.com>
  • Loading branch information
AMoo-Miki committed Sep 18, 2024
1 parent f2117cb commit e9486e3
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 21 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- Remove scaling of heading elements ([#1389](https://github.com/opensearch-project/oui/pull/1389))
- Make the space between search bar and table rows match the compressed state of the search box ([#1391](https://github.com/opensearch-project/oui/pull/1391))
- Add CSS breakpoints to OuiBreakpointSize ([#1401](https://github.com/opensearch-project/oui/pull/1401))
- Allow limiting the allowed breakpoints when calling `getBreakpoint()` ([#1401](https://github.com/opensearch-project/oui/pull/1401))

### 🐛 Bug Fixes

Expand All @@ -30,6 +31,7 @@
- Remove the unwanted OuiBreadcrumbs focus rectangle ([#1401](https://github.com/opensearch-project/oui/pull/1401))
- Correctly color the OuiBreadcrumbs when focused ([#1401](https://github.com/opensearch-project/oui/pull/1401))
- Display the last breadcrumb in a nested breadcrumb as a normal breadcrumb ([#1401](https://github.com/opensearch-project/oui/pull/1401))
- Limit allowed breakpoints to those provided by the `responsive` prop of Oui*Breadcrumbs ([#1401](https://github.com/opensearch-project/oui/pull/1401))

### 🚞 Infrastructure

Expand Down
31 changes: 21 additions & 10 deletions src/components/breadcrumbs/breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,12 +196,28 @@ export const OuiBreadcrumbs: FunctionComponent<OuiBreadcrumbsProps> = ({
max = 5,
...rest
}) => {
// Use the default object if they simply passed `true` for responsive
const responsiveObject =
typeof responsive === 'object' ? responsive : responsiveDefault;

const allowedBreakpoints = responsive
? (Object.keys(responsiveObject) as OuiBreakpointSize[])
: undefined;

const [currentBreakpoint, setCurrentBreakpoint] = useState(
getBreakpoint(typeof window === 'undefined' ? -Infinity : window.innerWidth)
getBreakpoint(
typeof window === 'undefined' ? -Infinity : window.innerWidth,
undefined,
allowedBreakpoints
)
);

const functionToCallOnWindowResize = throttle(() => {
const newBreakpoint = getBreakpoint(window.innerWidth);
const newBreakpoint = getBreakpoint(
window.innerWidth,
undefined,
allowedBreakpoints
);
if (newBreakpoint !== currentBreakpoint) {
setCurrentBreakpoint(newBreakpoint);
}
Expand All @@ -215,7 +231,7 @@ export const OuiBreadcrumbs: FunctionComponent<OuiBreadcrumbsProps> = ({
return () => {
window.removeEventListener('resize', functionToCallOnWindowResize);
};
}, [responsive, functionToCallOnWindowResize]);
}, [responsive, responsiveObject, functionToCallOnWindowResize]);

const isInPopover = className === 'ouiBreadcrumbs__inPopover';

Expand Down Expand Up @@ -288,19 +304,14 @@ export const OuiBreadcrumbs: FunctionComponent<OuiBreadcrumbsProps> = ({
return <Fragment key={index}>{wall}</Fragment>;
});

// Use the default object if they simply passed `true` for responsive
const responsiveObject =
typeof responsive === 'object' ? responsive : responsiveDefault;

// The max property collapses any breadcrumbs past the max quantity.
// This is the same behavior we want for responsiveness.
// So calculate the max value based on the combination of `max` and `responsive`

// First, calculate the responsive max value
const responsiveMax =
responsive && responsiveObject[currentBreakpoint as OuiBreakpointSize]
? responsiveObject[currentBreakpoint as OuiBreakpointSize]
: null;
(responsive && responsiveObject[currentBreakpoint as OuiBreakpointSize]) ||
null;

// Second, if both max and responsiveMax are set, use the smaller of the two. Otherwise, use the one that is set.
const calculatedMax: OuiBreadcrumbsProps['max'] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@
* GitHub history for details.
*/

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import React, {
Fragment,
FunctionComponent,
Expand Down Expand Up @@ -155,12 +174,28 @@ export const OuiSimplifiedBreadcrumbs: FunctionComponent<OuiSimplifiedBreadcrumb
hideLastBreadCrumb,
...rest
}) => {
// Use the default object if they simply passed `true` for responsive
const responsiveObject =
typeof responsive === 'object' ? responsive : responsiveDefault;

const allowedBreakpoints = responsive
? (Object.keys(responsiveObject) as OuiBreakpointSize[])
: undefined;

const [currentBreakpoint, setCurrentBreakpoint] = useState(
getBreakpoint(typeof window === 'undefined' ? -Infinity : window.innerWidth)
getBreakpoint(
typeof window === 'undefined' ? -Infinity : window.innerWidth,
undefined,
allowedBreakpoints
)
);

const functionToCallOnWindowResize = throttle(() => {
const newBreakpoint = getBreakpoint(window.innerWidth);
const newBreakpoint = getBreakpoint(
window.innerWidth,
undefined,
allowedBreakpoints
);
if (newBreakpoint !== currentBreakpoint) {
setCurrentBreakpoint(newBreakpoint);
}
Expand All @@ -174,7 +209,9 @@ export const OuiSimplifiedBreadcrumbs: FunctionComponent<OuiSimplifiedBreadcrumb
return () => {
window.removeEventListener('resize', functionToCallOnWindowResize);
};
}, [responsive, functionToCallOnWindowResize]);
}, [responsive, responsiveObject, functionToCallOnWindowResize]);

const isInPopover = className === 'ouiSimplifiedBreadcrumbs__inPopover';

const breadcrumbElements = breadcrumbs.map((breadcrumb, index) => {
const {
Expand Down Expand Up @@ -213,7 +250,7 @@ export const OuiSimplifiedBreadcrumbs: FunctionComponent<OuiSimplifiedBreadcrumb
ref={ref}
className={breadcrumbClasses}
title={innerText}
aria-current={isLastBreadcrumb ? 'page' : 'false'}
aria-current={isLastBreadcrumb && !isInPopover ? 'page' : 'false'}
{...breadcrumbRest}>
{text}
</span>
Expand Down Expand Up @@ -260,10 +297,6 @@ export const OuiSimplifiedBreadcrumbs: FunctionComponent<OuiSimplifiedBreadcrumb
);
});

// Use the default object if they simply passed `true` for responsive
const responsiveObject =
typeof responsive === 'object' ? responsive : responsiveDefault;

// The max property collapses any breadcrumbs past the max quantity.
// This is the same behavior we want for responsiveness.
// So calculate the max value based on the combination of `max` and `responsive`
Expand Down
10 changes: 7 additions & 3 deletions src/services/breakpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,18 @@ export const BREAKPOINT_KEYS = keysOf(BREAKPOINTS);
*
* @param {number} width Can either be the full window width or any width
* @param {OuiBreakpoints} breakpoints An object with keys for sizing and values for minimum width
* @param {OuiBreakpointSize[] | undefined} allowedBreakpoints An array of allowed breakpoints
* @returns {string | undefined} Name of the breakpoint key or `undefined` if a key doesn't exist
*/
export function getBreakpoint(
width: number,
breakpoints: OuiBreakpoints = BREAKPOINTS
breakpoints: OuiBreakpoints = BREAKPOINTS,
allowedBreakpoints: OuiBreakpointSize[] = keysOf(BREAKPOINTS)
): OuiBreakpointSize | undefined {
// Find the breakpoint (key) whose value is <= windowWidth starting with largest first
return keysOf(BREAKPOINTS).find((key) => breakpoints[key] <= width);
// Find the breakpoint (key) whose value is <= windowWidth starting with the largest first
return keysOf(BREAKPOINTS).find(
(key) => allowedBreakpoints.includes(key) && breakpoints[key] <= width
);
}

/**
Expand Down

0 comments on commit e9486e3

Please sign in to comment.