react-day-picker 8.1.3 → 8.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,4 +4,4 @@ export declare type ButtonProps = React.HTMLProps<HTMLButtonElement>;
4
4
  /**
5
5
  * Render a button HTML element applying the reset class name.
6
6
  */
7
- export declare const Button: React.ForwardRefExoticComponent<Pick<ButtonProps, "multiple" | "default" | "className" | "style" | "disabled" | "hidden" | "selected" | "dir" | "onSelect" | "required" | "min" | "max" | "start" | "color" | "content" | "size" | "wrap" | "open" | "cite" | "data" | "form" | "label" | "slot" | "span" | "summary" | "title" | "pattern" | "children" | "value" | "id" | "aria-label" | "onChange" | "accept" | "acceptCharset" | "action" | "allowFullScreen" | "allowTransparency" | "alt" | "as" | "async" | "autoComplete" | "autoFocus" | "autoPlay" | "capture" | "cellPadding" | "cellSpacing" | "charSet" | "challenge" | "checked" | "classID" | "cols" | "colSpan" | "controls" | "coords" | "crossOrigin" | "dateTime" | "defer" | "download" | "encType" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "frameBorder" | "headers" | "height" | "high" | "href" | "hrefLang" | "htmlFor" | "httpEquiv" | "integrity" | "keyParams" | "keyType" | "kind" | "list" | "loop" | "low" | "manifest" | "marginHeight" | "marginWidth" | "maxLength" | "media" | "mediaGroup" | "method" | "minLength" | "muted" | "name" | "nonce" | "noValidate" | "optimum" | "placeholder" | "playsInline" | "poster" | "preload" | "readOnly" | "rel" | "reversed" | "rows" | "rowSpan" | "sandbox" | "scope" | "scoped" | "scrolling" | "seamless" | "shape" | "sizes" | "src" | "srcDoc" | "srcLang" | "srcSet" | "step" | "target" | "type" | "useMap" | "width" | "wmode" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "draggable" | "lang" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key"> & React.RefAttributes<HTMLButtonElement>>;
7
+ export declare const Button: React.ForwardRefExoticComponent<Pick<ButtonProps, "children" | "aria-label" | "onChange" | "value" | "className" | "style" | "cite" | "data" | "form" | "label" | "slot" | "span" | "summary" | "title" | "pattern" | "dir" | "accept" | "acceptCharset" | "action" | "allowFullScreen" | "allowTransparency" | "alt" | "as" | "async" | "autoComplete" | "autoFocus" | "autoPlay" | "capture" | "cellPadding" | "cellSpacing" | "charSet" | "challenge" | "checked" | "classID" | "cols" | "colSpan" | "content" | "controls" | "coords" | "crossOrigin" | "dateTime" | "default" | "defer" | "disabled" | "download" | "encType" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "frameBorder" | "headers" | "height" | "high" | "href" | "hrefLang" | "htmlFor" | "httpEquiv" | "integrity" | "keyParams" | "keyType" | "kind" | "list" | "loop" | "low" | "manifest" | "marginHeight" | "marginWidth" | "max" | "maxLength" | "media" | "mediaGroup" | "method" | "min" | "minLength" | "multiple" | "muted" | "name" | "nonce" | "noValidate" | "open" | "optimum" | "placeholder" | "playsInline" | "poster" | "preload" | "readOnly" | "rel" | "required" | "reversed" | "rows" | "rowSpan" | "sandbox" | "scope" | "scoped" | "scrolling" | "seamless" | "selected" | "shape" | "size" | "sizes" | "src" | "srcDoc" | "srcLang" | "srcSet" | "start" | "step" | "target" | "type" | "useMap" | "width" | "wmode" | "wrap" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "contentEditable" | "contextMenu" | "draggable" | "hidden" | "id" | "lang" | "spellCheck" | "tabIndex" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key"> & React.RefAttributes<HTMLButtonElement>>;
package/dist/style.css CHANGED
@@ -5,7 +5,7 @@
5
5
  --rdp-accent-color-dark: #3003e1;
6
6
  --rdp-background-color-dark: #180270;
7
7
  --rdp-outline: 2px solid var(--rdp-accent-color); /* Outline border for focused elements */
8
- --rdp-outline-selected: 2px solid rgba(0, 0, 0, 0.75); /* Outline border for focused _and_ selected elements */
8
+ --rdp-outline-selected: 3px solid var(--rdp-accent-color); /* Outline border for focused _and_ selected elements */
9
9
 
10
10
  margin: 1em;
11
11
  }
@@ -38,7 +38,6 @@
38
38
  padding: 0;
39
39
  cursor: default;
40
40
  color: inherit;
41
- outline: none;
42
41
  background: none;
43
42
  font: inherit;
44
43
 
@@ -46,6 +45,11 @@
46
45
  -webkit-appearance: none;
47
46
  }
48
47
 
48
+ .rdp-button_reset:focus-visible {
49
+ /* Make sure to reset outline only when :focus-visible is supported */
50
+ outline: none;
51
+ }
52
+
49
53
  .rdp-button {
50
54
  border: 2px solid transparent;
51
55
  }
@@ -58,11 +62,11 @@
58
62
  cursor: pointer;
59
63
  }
60
64
 
61
- .rdp-button:focus:not([disabled]),
65
+ .rdp-button:focus-visible:not([disabled]),
62
66
  .rdp-button:active:not([disabled]) {
63
67
  color: inherit;
64
- border: var(--rdp-outline);
65
68
  background-color: var(--rdp-background-color);
69
+ border: var(--rdp-outline);
66
70
  }
67
71
 
68
72
  .rdp-button:hover:not([disabled]) {
@@ -196,9 +200,12 @@
196
200
 
197
201
  .rdp-dropdown:focus:not([disabled]) + .rdp-caption_label,
198
202
  .rdp-dropdown:active:not([disabled]) + .rdp-caption_label {
203
+ background-color: var(--rdp-background-color);
204
+ }
205
+
206
+ .rdp-dropdown:focus-visible:not([disabled]) {
199
207
  border: var(--rdp-outline);
200
208
  border-radius: 6px;
201
- background-color: var(--rdp-background-color);
202
209
  }
203
210
 
204
211
  .rdp-dropdown_icon {
@@ -273,7 +280,9 @@
273
280
  }
274
281
 
275
282
  .rdp-day_selected:focus:not([disabled]) {
276
- border: var(--rdp-outline-selected);
283
+ /* Since the background is the same use again the outline */
284
+ outline: var(--rdp-outline);
285
+ outline-offset: 2px;
277
286
  }
278
287
 
279
288
  .rdp:not([dir='rtl']) .rdp-day_range_start:not(.rdp-day_range_end) {
@@ -5,7 +5,7 @@
5
5
  --rdp-accent-color-dark: #3003e1;
6
6
  --rdp-background-color-dark: #180270;
7
7
  --rdp-outline: 2px solid var(--rdp-accent-color); /* Outline border for focused elements */
8
- --rdp-outline-selected: 2px solid rgba(0, 0, 0, 0.75); /* Outline border for focused _and_ selected elements */
8
+ --rdp-outline-selected: 3px solid var(--rdp-accent-color); /* Outline border for focused _and_ selected elements */
9
9
 
10
10
  margin: 1em;
11
11
  }
@@ -38,7 +38,6 @@
38
38
  padding: 0;
39
39
  cursor: default;
40
40
  color: inherit;
41
- outline: none;
42
41
  background: none;
43
42
  font: inherit;
44
43
 
@@ -46,6 +45,11 @@
46
45
  -webkit-appearance: none;
47
46
  }
48
47
 
48
+ .button_reset:focus-visible {
49
+ /* Make sure to reset outline only when :focus-visible is supported */
50
+ outline: none;
51
+ }
52
+
49
53
  .button {
50
54
  border: 2px solid transparent;
51
55
  }
@@ -58,11 +62,11 @@
58
62
  cursor: pointer;
59
63
  }
60
64
 
61
- .button:focus:not([disabled]),
65
+ .button:focus-visible:not([disabled]),
62
66
  .button:active:not([disabled]) {
63
67
  color: inherit;
64
- border: var(--rdp-outline);
65
68
  background-color: var(--rdp-background-color);
69
+ border: var(--rdp-outline);
66
70
  }
67
71
 
68
72
  .button:hover:not([disabled]) {
@@ -196,9 +200,12 @@
196
200
 
197
201
  .dropdown:focus:not([disabled]) + .caption_label,
198
202
  .dropdown:active:not([disabled]) + .caption_label {
203
+ background-color: var(--rdp-background-color);
204
+ }
205
+
206
+ .dropdown:focus-visible:not([disabled]) {
199
207
  border: var(--rdp-outline);
200
208
  border-radius: 6px;
201
- background-color: var(--rdp-background-color);
202
209
  }
203
210
 
204
211
  .dropdown_icon {
@@ -273,7 +280,9 @@
273
280
  }
274
281
 
275
282
  .day_selected:focus:not([disabled]) {
276
- border: var(--rdp-outline-selected);
283
+ /* Since the background is the same use again the outline */
284
+ outline: var(--rdp-outline);
285
+ outline-offset: 2px;
277
286
  }
278
287
 
279
288
  .rdp:not([dir='rtl']) .day_range_start:not(.day_range_end) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-day-picker",
3
- "version": "8.1.3",
3
+ "version": "8.1.4",
4
4
  "description": "Customizable Date Picker for React",
5
5
  "author": "Giampaolo Bellavite <io@gpbl.dev>",
6
6
  "homepage": "http://react-day-picker.js.org",
@@ -54,8 +54,9 @@ describe('when a selection mode is set', () => {
54
54
  beforeEach(() => {
55
55
  setup(props, dayPickerProps);
56
56
  });
57
- test('should render a button', () => {
57
+ test('should render a button named "day"', () => {
58
58
  expect(container.firstChild?.nodeName).toBe('BUTTON');
59
+ expect(container.firstChild).toHaveAttribute('name', 'day');
59
60
  });
60
61
  });
61
62
 
@@ -26,5 +26,5 @@ export function Day(props: DayProps): JSX.Element {
26
26
  if (!dayRender.isButton) {
27
27
  return <div {...dayRender.divProps} />;
28
28
  }
29
- return <Button ref={buttonRef} {...dayRender.buttonProps} />;
29
+ return <Button name="day" ref={buttonRef} {...dayRender.buttonProps} />;
30
30
  }
@@ -19,6 +19,7 @@ function setup(props: DropdownProps, dayPickerProps?: DayPickerProps) {
19
19
  }
20
20
 
21
21
  const props: Required<DropdownProps> = {
22
+ name: 'dropdown',
22
23
  'aria-label': 'foo',
23
24
  onChange: jest.fn(),
24
25
  caption: 'Some caption',
@@ -5,6 +5,7 @@ import { useDayPicker } from 'contexts/DayPicker';
5
5
 
6
6
  /** The props for the {@link Dropdown} component. */
7
7
  export interface DropdownProps {
8
+ name?: string;
8
9
  caption?: React.ReactNode;
9
10
  children?: React.SelectHTMLAttributes<HTMLSelectElement>['children'];
10
11
  className?: string;
@@ -30,6 +31,7 @@ export function Dropdown(props: DropdownProps): JSX.Element {
30
31
  {props['aria-label']}
31
32
  </span>
32
33
  <select
34
+ name={props.name}
33
35
  aria-label={props['aria-label']}
34
36
  className={dayPicker.classNames.dropdown}
35
37
  style={dayPicker.styles.dropdown}
@@ -2,7 +2,7 @@ import React from 'react';
2
2
 
3
3
  import { screen } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
- import { differenceInMonths } from 'date-fns';
5
+ import { addMonths, differenceInMonths } from 'date-fns';
6
6
  import { DayPickerProps } from 'DayPicker';
7
7
 
8
8
  import { customRender } from 'test/render';
@@ -30,6 +30,16 @@ const props: MonthsDropdownProps = {
30
30
  onChange: jest.fn()
31
31
  };
32
32
 
33
+ describe('when fromDate and toDate are passed in', () => {
34
+ beforeEach(() => {
35
+ setup(props, { fromDate: new Date(), toDate: addMonths(new Date(), 1) });
36
+ });
37
+ test('should render the dropdown element', () => {
38
+ expect(root).toMatchSnapshot();
39
+ expect(select).toHaveAttribute('name', 'months');
40
+ });
41
+ });
42
+
33
43
  describe('when "fromDate" is not set', () => {
34
44
  beforeEach(() => {
35
45
  setup(props, { fromDate: undefined });
@@ -58,6 +58,7 @@ export function MonthsDropdown(props: MonthsDropdownProps): JSX.Element {
58
58
 
59
59
  return (
60
60
  <DropdownComponent
61
+ name="months"
61
62
  aria-label={labelMonthDropdown()}
62
63
  className={classNames.dropdown_month}
63
64
  style={styles.dropdown_month}
@@ -0,0 +1,48 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`when fromDate and toDate are passed in should render the dropdown element 1`] = `
4
+ <div
5
+ class="rdp-dropdown_month"
6
+ >
7
+ <span
8
+ class="rdp-vhidden"
9
+ >
10
+ Month:
11
+ </span>
12
+ <select
13
+ aria-label="Month: "
14
+ class="rdp-dropdown"
15
+ name="months"
16
+ >
17
+ <option
18
+ value="0"
19
+ >
20
+ January
21
+ </option>
22
+ <option
23
+ value="1"
24
+ >
25
+ February
26
+ </option>
27
+ </select>
28
+ <div
29
+ aria-hidden="true"
30
+ class="rdp-caption_label"
31
+ >
32
+ January
33
+ <svg
34
+ class="rdp-dropdown_icon"
35
+ data-testid="iconDropdown"
36
+ height="8px"
37
+ viewBox="0 0 120 120"
38
+ width="8px"
39
+ >
40
+ <path
41
+ d="M4.22182541,48.2218254 C8.44222828,44.0014225 15.2388494,43.9273804 19.5496459,47.9996989 L19.7781746,48.2218254 L60,88.443 L100.221825,48.2218254 C104.442228,44.0014225 111.238849,43.9273804 115.549646,47.9996989 L115.778175,48.2218254 C119.998577,52.4422283 120.07262,59.2388494 116.000301,63.5496459 L115.778175,63.7781746 L67.7781746,111.778175 C63.5577717,115.998577 56.7611506,116.07262 52.4503541,112.000301 L52.2218254,111.778175 L4.22182541,63.7781746 C-0.0739418023,59.4824074 -0.0739418023,52.5175926 4.22182541,48.2218254 Z"
42
+ fill="currentColor"
43
+ fill-rule="nonzero"
44
+ />
45
+ </svg>
46
+ </div>
47
+ </div>
48
+ `;
@@ -56,6 +56,12 @@ describe('when rendered', () => {
56
56
  const icons = root.getElementsByTagName('svg');
57
57
  expect(icons[1]).toHaveTextContent('IconRight');
58
58
  });
59
+ test('the previous button should be named "previous-month"', () => {
60
+ expect(getPrevButton()).toHaveAttribute('name', 'previous-month');
61
+ });
62
+ test('the next button should be named "next-month"', () => {
63
+ expect(getNextButton()).toHaveAttribute('name', 'next-month');
64
+ });
59
65
  beforeEach(() => {
60
66
  userEvent.click(getPrevButton());
61
67
  });
@@ -57,6 +57,7 @@ export function Navigation(props: NavigationProps): JSX.Element {
57
57
  <div className={classNames.nav} style={styles.nav}>
58
58
  {!props.hidePrevious && (
59
59
  <Button
60
+ name="previous-month"
60
61
  aria-label={previousLabel}
61
62
  className={previousClassName}
62
63
  style={styles.nav_button_previous}
@@ -78,6 +79,7 @@ export function Navigation(props: NavigationProps): JSX.Element {
78
79
  )}
79
80
  {!props.hideNext && (
80
81
  <Button
82
+ name="next-month"
81
83
  aria-label={nextLabel}
82
84
  className={nextClassName}
83
85
  style={styles.nav_button_next}
@@ -27,12 +27,19 @@ describe('without "onWeekNumberClick" prop', () => {
27
27
 
28
28
  describe('with "onWeekNumberClick" prop', () => {
29
29
  const dayPickerProps: DayPickerProps = { onWeekNumberClick: jest.fn() };
30
- const { container } = setup(props, dayPickerProps);
30
+ let container: HTMLElement;
31
+ beforeEach(() => {
32
+ container = setup(props, dayPickerProps).container;
33
+ });
31
34
  test('it should return a button element', () => {
35
+ expect(screen.getByRole('button')).toBeInTheDocument();
36
+ expect(container.firstChild).toHaveAttribute('name', 'week-number');
32
37
  expect(container.firstChild).toMatchSnapshot();
33
38
  });
34
39
  describe('when the button element is clicked', () => {
35
- userEvent.click(screen.getByRole('button'));
40
+ beforeEach(async () => {
41
+ await userEvent.click(screen.getByRole('button'));
42
+ });
36
43
  test('should call onWeekNumberClick', () => {
37
44
  expect(dayPickerProps.onWeekNumberClick).toHaveBeenCalledWith(
38
45
  props.number,
@@ -47,6 +47,7 @@ export function WeekNumber(props: WeekNumberProps): JSX.Element {
47
47
 
48
48
  return (
49
49
  <Button
50
+ name="week-number"
50
51
  aria-label={label}
51
52
  className={classNames.weeknumber}
52
53
  style={styles.weeknumber}
@@ -1,6 +1,15 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`with "onWeekNumberClick" prop it should return a button element 1`] = `null`;
3
+ exports[`with "onWeekNumberClick" prop it should return a button element 1`] = `
4
+ <button
5
+ aria-label="Week n. 10"
6
+ class="rdp-button_reset rdp-button rdp-weeknumber"
7
+ name="week-number"
8
+ type="button"
9
+ >
10
+ 10
11
+ </button>
12
+ `;
4
13
 
5
14
  exports[`without "onWeekNumberClick" prop it should return a span element 1`] = `
6
15
  <span
@@ -2,7 +2,7 @@ import React from 'react';
2
2
 
3
3
  import { screen } from '@testing-library/react';
4
4
  import userEvent from '@testing-library/user-event';
5
- import { differenceInYears } from 'date-fns';
5
+ import { addMonths, differenceInYears } from 'date-fns';
6
6
  import { DayPickerProps } from 'DayPicker';
7
7
 
8
8
  import { customRender } from 'test/render';
@@ -30,6 +30,16 @@ const props: YearsDropdownProps = {
30
30
  onChange: jest.fn()
31
31
  };
32
32
 
33
+ describe('when fromDate and toDate are passed in', () => {
34
+ beforeEach(() => {
35
+ setup(props, { fromDate: new Date(), toDate: addMonths(new Date(), 1) });
36
+ });
37
+ test('should render the dropdown element', () => {
38
+ expect(root).toMatchSnapshot();
39
+ expect(select).toHaveAttribute('name', 'years');
40
+ });
41
+ });
42
+
33
43
  describe('when "fromDate" is not set', () => {
34
44
  beforeEach(() => {
35
45
  setup(props, { fromDate: undefined });
@@ -59,6 +59,7 @@ export function YearsDropdown(props: YearsDropdownProps): JSX.Element {
59
59
 
60
60
  return (
61
61
  <DropdownComponent
62
+ name="years"
62
63
  aria-label={labelYearDropdown()}
63
64
  className={classNames.dropdown_year}
64
65
  style={styles.dropdown_year}
@@ -0,0 +1,43 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`when fromDate and toDate are passed in should render the dropdown element 1`] = `
4
+ <div
5
+ class="rdp-dropdown_year"
6
+ >
7
+ <span
8
+ class="rdp-vhidden"
9
+ >
10
+ Year:
11
+ </span>
12
+ <select
13
+ aria-label="Year: "
14
+ class="rdp-dropdown"
15
+ name="years"
16
+ >
17
+ <option
18
+ value="2021"
19
+ >
20
+ 2021
21
+ </option>
22
+ </select>
23
+ <div
24
+ aria-hidden="true"
25
+ class="rdp-caption_label"
26
+ >
27
+ 2021
28
+ <svg
29
+ class="rdp-dropdown_icon"
30
+ data-testid="iconDropdown"
31
+ height="8px"
32
+ viewBox="0 0 120 120"
33
+ width="8px"
34
+ >
35
+ <path
36
+ d="M4.22182541,48.2218254 C8.44222828,44.0014225 15.2388494,43.9273804 19.5496459,47.9996989 L19.7781746,48.2218254 L60,88.443 L100.221825,48.2218254 C104.442228,44.0014225 111.238849,43.9273804 115.549646,47.9996989 L115.778175,48.2218254 C119.998577,52.4422283 120.07262,59.2388494 116.000301,63.5496459 L115.778175,63.7781746 L67.7781746,111.778175 C63.5577717,115.998577 56.7611506,116.07262 52.4503541,112.000301 L52.2218254,111.778175 L4.22182541,63.7781746 C-0.0739418023,59.4824074 -0.0739418023,52.5175926 4.22182541,48.2218254 Z"
37
+ fill="currentColor"
38
+ fill-rule="nonzero"
39
+ />
40
+ </svg>
41
+ </div>
42
+ </div>
43
+ `;
@@ -158,8 +158,8 @@ export function useInput(options: UseInputOptions = {}): UseInputValue {
158
158
  onMonthChange: handleMonthChange,
159
159
  selected: selectedDay,
160
160
  locale,
161
- fromDate: options?.fromDate,
162
- toDate: options?.toDate,
161
+ fromDate,
162
+ toDate,
163
163
  today
164
164
  };
165
165
 
package/src/style.css CHANGED
@@ -5,7 +5,7 @@
5
5
  --rdp-accent-color-dark: #3003e1;
6
6
  --rdp-background-color-dark: #180270;
7
7
  --rdp-outline: 2px solid var(--rdp-accent-color); /* Outline border for focused elements */
8
- --rdp-outline-selected: 2px solid rgba(0, 0, 0, 0.75); /* Outline border for focused _and_ selected elements */
8
+ --rdp-outline-selected: 3px solid var(--rdp-accent-color); /* Outline border for focused _and_ selected elements */
9
9
 
10
10
  margin: 1em;
11
11
  }
@@ -38,7 +38,6 @@
38
38
  padding: 0;
39
39
  cursor: default;
40
40
  color: inherit;
41
- outline: none;
42
41
  background: none;
43
42
  font: inherit;
44
43
 
@@ -46,6 +45,11 @@
46
45
  -webkit-appearance: none;
47
46
  }
48
47
 
48
+ .rdp-button_reset:focus-visible {
49
+ /* Make sure to reset outline only when :focus-visible is supported */
50
+ outline: none;
51
+ }
52
+
49
53
  .rdp-button {
50
54
  border: 2px solid transparent;
51
55
  }
@@ -58,11 +62,11 @@
58
62
  cursor: pointer;
59
63
  }
60
64
 
61
- .rdp-button:focus:not([disabled]),
65
+ .rdp-button:focus-visible:not([disabled]),
62
66
  .rdp-button:active:not([disabled]) {
63
67
  color: inherit;
64
- border: var(--rdp-outline);
65
68
  background-color: var(--rdp-background-color);
69
+ border: var(--rdp-outline);
66
70
  }
67
71
 
68
72
  .rdp-button:hover:not([disabled]) {
@@ -196,9 +200,12 @@
196
200
 
197
201
  .rdp-dropdown:focus:not([disabled]) + .rdp-caption_label,
198
202
  .rdp-dropdown:active:not([disabled]) + .rdp-caption_label {
203
+ background-color: var(--rdp-background-color);
204
+ }
205
+
206
+ .rdp-dropdown:focus-visible:not([disabled]) {
199
207
  border: var(--rdp-outline);
200
208
  border-radius: 6px;
201
- background-color: var(--rdp-background-color);
202
209
  }
203
210
 
204
211
  .rdp-dropdown_icon {
@@ -273,7 +280,9 @@
273
280
  }
274
281
 
275
282
  .rdp-day_selected:focus:not([disabled]) {
276
- border: var(--rdp-outline-selected);
283
+ /* Since the background is the same use again the outline */
284
+ outline: var(--rdp-outline);
285
+ outline-offset: 2px;
277
286
  }
278
287
 
279
288
  .rdp:not([dir='rtl']) .rdp-day_range_start:not(.rdp-day_range_end) {