Skip to content

Commit a7d3ada

Browse files
thatblindgeyetlabajTitanipatternfly-buildmcoker
authored andcommitted
fix(DatePicker): resolved page scrolling bug (patternfly#9401)
* Rebase postv5 (patternfly#9393) * chore(deps): bump docs framework (patternfly#9370) * chore(docs): Updated screenshots (patternfly#9337) * chore(docs): Updated screenshots * updated screenshots after logo update --------- Co-authored-by: Titani <tlabaj@redaht.com> * chore(release): releasing packages [ci skip] - @patternfly/react-docs@6.0.0-prerelease.26 * chore(deps): bump to latest chore version (patternfly#9389) * chore(deps): bump to latest chore version * bump to 16 * chore(release): releasing packages [ci skip] - @patternfly/react-charts@7.0.0-prerelease.12 - @patternfly/react-code-editor@5.0.0-prerelease.24 - @patternfly/react-core@5.0.0-prerelease.24 - @patternfly/react-docs@6.0.0-prerelease.27 - @patternfly/react-icons@5.0.0-prerelease.9 - demo-app-ts@5.0.0-prerelease.22 - @patternfly/react-styles@5.0.0-prerelease.7 - @patternfly/react-table@5.0.0-prerelease.24 - @patternfly/react-tokens@5.0.0-prerelease.9 * fix(fileupload): use default readonly text input instead of plain (patternfly#9387) * fix(fileupload): use default readonly text input instead of plain * chore(build): snaps * fix(CodeEditor): prevent clicks in textarea from opening fileupload (patternfly#9385) * fix(toolbar): added chip container class to toolbar content (patternfly#9379) * feat(Menu): added support for tooltips to menu (patternfly#9382) * fix(whitespace): Update readme to trigger release * chore(release): releasing packages [ci skip] - @patternfly/react-code-editor@5.0.0-prerelease.25 - @patternfly/react-core@5.0.0-prerelease.25 - @patternfly/react-docs@6.0.0-prerelease.28 - demo-app-ts@5.0.0-prerelease.23 - @patternfly/react-table@5.0.0-prerelease.25 * fix(Toolbar): resolved typeerror on full page demo (patternfly#9355) * chore(TreeView): converted examples to TS (patternfly#9286) * fix(ExpandableSection): added ARIA attributes (patternfly#9303) * fix(ExpandableSection): added ARIA attributes * Updated failing snapshots due to mismatching generated ID * chore(Tooltip): updated unit tests (patternfly#9295) * chore(Tooltip): updated unit tests * Updated mock and tests * Updated based on Austin feedback * Updated integration tests * Removed unused imports * Updated remaining tests using Popper mock * Removed extraenous snapshot test * Removed test * Split out onTooltipHidden test * chore(Card): added tests for new clickable/selectable (patternfly#9262) * chore(Card): added tests for new clickable/selectable * Added tests for clickable cards * Updated card with actions test * fix(Slider): reverted taborder (patternfly#9293) * fix(chore): Fix deprecated wizard integration tests (patternfly#9312) * fix(chore): Fix deprecated wizard integration tests * updated non deprecated test as well --------- Co-authored-by: Titani <tlabaj@redaht.com> --------- Co-authored-by: Titani <tlabaj@redaht.com> Co-authored-by: patternfly-build <patternfly-build@redhat.com> Co-authored-by: Michael Coker <35148959+mcoker@users.noreply.github.com> Co-authored-by: Dallas <dallas.nicol@gmail.com> Co-authored-by: Dana Gutride <dgutride@gmail.com> Co-authored-by: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com> * fix(DatePicker): resolved page scrolling bug * Updated snapshots after rebase * Fixed wrong date being focused after selection * Fixed linting errors --------- Co-authored-by: Titani Labaj <39532947+tlabaj@users.noreply.github.com> Co-authored-by: Titani <tlabaj@redaht.com> Co-authored-by: patternfly-build <patternfly-build@redhat.com> Co-authored-by: Michael Coker <35148959+mcoker@users.noreply.github.com> Co-authored-by: Dallas <dallas.nicol@gmail.com> Co-authored-by: Dana Gutride <dgutride@gmail.com>
1 parent f0c5c9a commit a7d3ada

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,8 @@ export const CalendarMonth = ({
180180

181181
useEffect(() => {
182182
// Calendar month should not be focused on page load
183-
// Datepicker should place focus in calendar month when opened
184183
if ((shouldFocus || isDateFocused) && focusedDateValidated && focusRef.current) {
185184
focusRef.current.focus();
186-
} else {
187-
setShouldFocus(true);
188185
}
189186
}, [focusedDate, isDateFocused, focusedDateValidated, focusRef]);
190187

packages/react-core/src/components/DatePicker/DatePicker.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as React from 'react';
22
import { css } from '@patternfly/react-styles';
33
import styles from '@patternfly/react-styles/css/components/DatePicker/date-picker';
44
import buttonStyles from '@patternfly/react-styles/css/components/Button/button';
5+
import calendarMonthStyles from '@patternfly/react-styles/css/components/CalendarMonth/calendar-month';
56
import { TextInput, TextInputProps } from '../TextInput/TextInput';
67
import { Popover, PopoverProps } from '../Popover/Popover';
78
import { InputGroup, InputGroupItem } from '../InputGroup';
@@ -214,9 +215,15 @@ const DatePickerBase = (
214215
[setPopoverOpen, popoverOpen, selectOpen]
215216
);
216217

218+
const createFocusSelectorString = (modifierClass: string) =>
219+
`.${calendarMonthStyles.calendarMonthDatesCell}.${modifierClass} .${calendarMonthStyles.calendarMonthDate}`;
220+
const focusSelectorForSelectedDate = createFocusSelectorString(calendarMonthStyles.modifiers.selected);
221+
const focusSelectorForUnselectedDate = createFocusSelectorString(calendarMonthStyles.modifiers.current);
222+
217223
return (
218224
<div className={css(styles.datePicker, className)} ref={datePickerWrapperRef} style={style} {...props}>
219225
<Popover
226+
elementToFocus={valueDate ? focusSelectorForSelectedDate : focusSelectorForUnselectedDate}
220227
position="bottom"
221228
bodyContent={
222229
<CalendarMonth
@@ -232,7 +239,6 @@ const DatePickerBase = (
232239
dayFormat={dayFormat}
233240
weekStart={weekStart}
234241
rangeStart={rangeStart}
235-
isDateFocused
236242
/>
237243
}
238244
showClose={false}

packages/react-core/src/components/Popover/Popover.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ export interface PopoverProps {
7878
closeBtnAriaLabel?: string;
7979
/** Distance of the popover to its target. Defaults to 25. */
8080
distance?: number;
81+
/** The element to focus when the popover becomes visible. By default the first
82+
* focusable element will receive focus.
83+
*/
84+
elementToFocus?: HTMLElement | SVGElement | string;
8185
/**
8286
* If true, tries to keep the popover in view by flipping it if necessary.
8387
* If the position is set to 'auto', this prop is ignored.
@@ -269,6 +273,7 @@ export const Popover: React.FunctionComponent<PopoverProps> = ({
269273
triggerRef,
270274
hasNoPadding = false,
271275
hasAutoWidth = false,
276+
elementToFocus,
272277
...rest
273278
}: PopoverProps) => {
274279
// could make this a prop in the future (true | false | 'toggle')
@@ -285,7 +290,7 @@ export const Popover: React.FunctionComponent<PopoverProps> = ({
285290
React.useEffect(() => {
286291
if (triggerManually) {
287292
if (isVisible) {
288-
show();
293+
show(undefined, true);
289294
} else {
290295
hide();
291296
}
@@ -404,13 +409,26 @@ export const Popover: React.FunctionComponent<PopoverProps> = ({
404409
hide(event);
405410
}
406411
};
412+
407413
const content = (
408414
<FocusTrap
409415
ref={popoverRef}
410416
active={focusTrapActive}
411417
focusTrapOptions={{
412418
returnFocusOnDeactivate: true,
413419
clickOutsideDeactivates: true,
420+
// FocusTrap's initialFocus can accept false as a value to prevent initial focus.
421+
// We want to prevent this in case false is ever passed in.
422+
initialFocus: elementToFocus || undefined,
423+
checkCanFocusTrap: (containers) =>
424+
new Promise((resolve) => {
425+
const interval = setInterval(() => {
426+
if (containers.every((container) => getComputedStyle(container).visibility !== 'hidden')) {
427+
resolve();
428+
clearInterval(interval);
429+
}
430+
}, 10);
431+
}),
414432
tabbableOptions: { displayCheck: 'none' },
415433

416434
fallbackFocus: () => {

packages/react-core/src/components/Popover/examples/Popover.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,11 @@ Here the popover goes over the navigation, so the prop `appendTo` is set to the
8989
```ts file="./PopoverAlert.tsx"
9090

9191
```
92+
93+
### Custom focus
94+
95+
Use the `elementToFocus` property to customize which element inside the Popover receives focus when opened.
96+
97+
```ts file="./PopoverCustomFocus.tsx"
98+
99+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react';
2+
import { Popover, Button } from '@patternfly/react-core';
3+
4+
export const PopoverCustomFocus: React.FunctionComponent = () => (
5+
<Popover
6+
elementToFocus="#popover-cancel-button"
7+
showClose={false}
8+
aria-label="Popover with custom focus"
9+
headerContent={<div>Popover header</div>}
10+
bodyContent={
11+
<div>
12+
Lorem ipsum dolor sit amet, consectetur adipisicing elit.{' '}
13+
<Button
14+
// Preventing default click behavior for example purposes only
15+
onClick={(event: React.MouseEvent) => event.preventDefault()}
16+
component="a"
17+
isInline
18+
variant="link"
19+
href="#basic"
20+
>
21+
View the basic example
22+
</Button>
23+
</div>
24+
}
25+
footerContent={(hide) => (
26+
<Button onClick={hide} variant="secondary" id="popover-cancel-button">
27+
Cancel
28+
</Button>
29+
)}
30+
>
31+
<Button>Toggle popover with custom focus</Button>
32+
</Popover>
33+
);

0 commit comments

Comments
 (0)