Skip to content

Commit

Permalink
Merge branch 'master' into toast-jsdoc
Browse files Browse the repository at this point in the history
  • Loading branch information
anuraghazra committed Oct 21, 2020
2 parents d913356 + fb0a82b commit c5d453b
Show file tree
Hide file tree
Showing 35 changed files with 594 additions and 501 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ jobs:
with:
timezone: Asia/Kolkata

- name: install deps
- name: Install deps
run: yarn
- name: Check Types
run: yarn check-types
- name: Test
run: yarn test
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"build:cjs": "cross-env BABEL_ENV=cjs babel src --extensions .ts,.tsx --config-file ./babel-config.js -d dist/cjs --source-maps",
"build:esm": "cross-env BABEL_ENV=esm babel src --extensions .ts,.tsx --config-file ./babel-config.js -d dist/esm --source-maps",
"build:types": "tsc --emitDeclarationOnly",
"check-types": "tsc --noEmit",
"commit": "gacp",
"format": "prettier --write \"./**/*.{js,ts,css,less,json,md,html,yml,yaml,pcss,jsx,tsx}\"",
"keys": "node scripts/build/keys",
Expand Down
2 changes: 1 addition & 1 deletion src/accordion/AccordionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type AccordionState = CompositeState & {
* Whether the accodion selection should be manual.
* @default true
*/
manual: boolean;
manual?: boolean;
/**
* Allow to open multiple accordion items
* @default false
Expand Down
35 changes: 32 additions & 3 deletions src/accordion/AccordionTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ export const useAccordionTrigger = createHook<

useProps(
options,
{ onClick: htmlOnClick, onFocus: htmlOnFocus, ...htmlProps },
{
onClick: htmlOnClick,
onKeyDown: htmlOnKeyDown,
onFocus: htmlOnFocus,
...htmlProps
},
) {
const {
manual,
Expand All @@ -61,9 +66,30 @@ export const useAccordionTrigger = createHook<
} = options;
const selected = isAccordionSelected(options);
const accordionPanelId = useAccordionPanelId(options);
const onKeyDownRef = useLiveRef(htmlOnKeyDown);
const onClickRef = useLiveRef(htmlOnClick);
const onFocusRef = useLiveRef(htmlOnFocus);

const onKeyDown = React.useCallback(
(event: React.KeyboardEvent) => {
const first = options.first && (() => setTimeout(options.first));
const last = options.last && (() => setTimeout(options.last));
const keyMap = { Home: first, End: last };
const action = keyMap[event.key as keyof typeof keyMap];
if (action) {
event.preventDefault();
event.stopPropagation();
action();
return;
}

onKeyDownRef.current?.(event);
},

// eslint-disable-next-line react-hooks/exhaustive-deps
[options.first, options.last],
);

const handleSelection = React.useCallback(() => {
if (disabled) return;
if (!id) return;
Expand Down Expand Up @@ -91,7 +117,8 @@ export const useAccordionTrigger = createHook<
handleSelection();
},

[handleSelection, onClickRef],
// eslint-disable-next-line react-hooks/exhaustive-deps
[handleSelection],
);

const onFocus = React.useCallback(
Expand All @@ -103,7 +130,8 @@ export const useAccordionTrigger = createHook<
handleSelection();
},

[onFocusRef, manual, handleSelection],
// eslint-disable-next-line react-hooks/exhaustive-deps
[manual, handleSelection],
);

return {
Expand All @@ -112,6 +140,7 @@ export const useAccordionTrigger = createHook<
"aria-disabled": ariaAttr(!allowToggle && selected),
onClick,
onFocus,
onKeyDown,
...htmlProps,
};
},
Expand Down
2 changes: 1 addition & 1 deletion src/accordion/stories/Accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
AccordionComponent as Accordion,
AccordionComponentInitialState,
StyledAccordion,
} from "./Accordion";
} from "./AccordionComponent";

export default {
component: Accordion,
Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion src/calendar/CalendarCellButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type CalendarCellButtonOptions = ButtonOptions &
| "maxDate"
| "dateValue"
| "isFocused"
| "isRangeCalendar"
> &
Partial<Pick<RangeCalendarStateReturn, "anchorDate">> & {
date: Date;
Expand Down Expand Up @@ -132,7 +133,7 @@ export const useCalendarCellButton = createHook<

// When a cell is focused and this is a range calendar, add a prompt to help
// screenreader users know that they are in a range selection mode.
if (anchorDate && isFocused && !isDisabled) {
if (options.isRangeCalendar && isFocused && !isDisabled) {
let rangeSelectionPrompt = "";

// If selection has started add "click to finish selecting range"
Expand Down
12 changes: 7 additions & 5 deletions src/calendar/CalendarState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,15 @@ export function useCalendarState(props: CalendarInitialState = {}) {
setFocusedDate(date);
}

const announceSelectedDate = React.useCallback((value: Date) => {
if (!value) return;
announce(`Selected Date: ${format(value, "do MMM yyyy")}`);
}, []);

function setValue(value: Date) {
if (!isDisabled && !isReadOnly) {
setControllableValue(value);
announceSelectedDate(value);
}
}

Expand All @@ -129,11 +135,6 @@ export function useCalendarState(props: CalendarInitialState = {}) {
// rather than move focus, we announce the new month value
}, [currentMonth]);

useUpdateEffect(() => {
if (!value) return;
announce(`Selected Date: ${format(value, "do MMM yyyy")}`);
}, [value]);

return {
calendarId,
dateValue: value,
Expand Down Expand Up @@ -190,6 +191,7 @@ export function useCalendarState(props: CalendarInitialState = {}) {
selectDate(date: Date) {
setValue(date);
},
isRangeCalendar: false,
};
}

Expand Down
32 changes: 17 additions & 15 deletions src/calendar/RangeCalendarState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,7 @@ export function useRangeCalendarState(props: RangeCalendarInitialState = {}) {
? makeRange(anchorDate, calendar.focusedDate)
: value && dateRange && makeRange(dateRange.start, dateRange.end);

const selectDate = (date: Date) => {
if (props.isReadOnly) {
return;
}

if (!anchorDate) {
setAnchorDate(date);
} else {
setValue(makeRange(anchorDate, date));
setAnchorDate(null);
}
};

useUpdateEffect(() => {
if (anchorDate) return;
const announceRange = React.useCallback(() => {
if (!highlightedRange) return;
if (isSameDay(highlightedRange.start, highlightedRange.end)) {
announce(
Expand All @@ -96,6 +82,21 @@ export function useRangeCalendarState(props: RangeCalendarInitialState = {}) {
}
}, [highlightedRange]);

const selectDate = (date: Date) => {
if (props.isReadOnly) {
return;
}

if (!anchorDate) {
setAnchorDate(date);
announce(`Starting range from ${format(date, "do MMM yyyy")}`);
} else {
setValue(makeRange(anchorDate, date));
announceRange();
setAnchorDate(null);
}
};

return {
...calendar,
dateRangeValue: dateRange,
Expand All @@ -112,6 +113,7 @@ export function useRangeCalendarState(props: RangeCalendarInitialState = {}) {
calendar.setFocusedDate(date);
}
},
isRangeCalendar: true,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/calendar/__keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const CALENDAR_STATE_KEYS = [
"focusPreviousYear",
"selectFocusedDate",
"selectDate",
"isRangeCalendar",
] as const;
const RANGE_CALENDAR_STATE_KEYS = [
...CALENDAR_STATE_KEYS,
Expand Down
19 changes: 15 additions & 4 deletions src/calendar/__tests__/RangeCalendar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,11 @@ describe("RangeCalendar", () => {
press.Tab();
press.Tab();

expect(label("Wednesday, October 7, 2020 selected")).toHaveFocus();
expect(
label(
"Wednesday, October 7, 2020 selected (click to start selecting range)",
),
).toHaveFocus();
press.ArrowDown(); // go to down just for some variety

press.Enter(); // start the selection, currently the start and end should be the same date
Expand All @@ -145,9 +149,12 @@ describe("RangeCalendar", () => {
// check if the selection is actually finished or not
press.ArrowRight();
press.ArrowRight();
expect(label("Wednesday, November 4, 2020")).toHaveFocus();
expect(
label("Wednesday, November 4, 2020")?.parentElement,
label("Wednesday, November 4, 2020 (click to start selecting range)"),
).toHaveFocus();
expect(
label("Wednesday, November 4, 2020 (click to start selecting range)")
?.parentElement,
).not.toHaveAttribute("data-is-range-selection");

// Verify selection ranges
Expand All @@ -174,7 +181,11 @@ describe("RangeCalendar", () => {
press.Tab();
press.Tab();

expect(label("Monday, October 7, 2019 selected")).toHaveFocus();
expect(
label(
"Monday, October 7, 2019 selected (click to start selecting range)",
),
).toHaveFocus();
press.ArrowDown();
press.Enter(); // start the selection

Expand Down
5 changes: 1 addition & 4 deletions src/calendar/stories/RangeCalendar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,7 @@ const RangeCalendarComp: React.FC<RangeCalendarInitialState> = props => {
export const Default = () => <RangeCalendarComp />;
export const DefaultValue = () => (
<RangeCalendarComp
defaultValue={{
start: format(new Date(), "yyyy-MM-dd"),
end: format(addDays(new Date(), 4), "yyyy-MM-dd"),
}}
defaultValue={{ start: "2019-10-07", end: "2019-10-30" }}
/>
);

Expand Down
19 changes: 14 additions & 5 deletions src/datepicker/DatePickerSegment.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { DatePickerStateReturn } from ".";
import { unstable_useId as useId } from "reakit";
import { createComponent, createHook } from "reakit-system";

import { DATE_PICKER_SEGMENT_KEYS } from "./__keys";
import { DateRangePickerStateReturn } from "./DateRangePickerState";
import { useSegment, SegmentOptions, SegmentHTMLProps } from "../segment";

export type DatePickerSegmentOptions =
| SegmentOptions
| Partial<DatePickerStateReturn>
| Partial<DateRangePickerStateReturn>;
export type DatePickerSegmentOptions = SegmentOptions &
Partial<Pick<DatePickerStateReturn, "pickerId" | "isDateRangePicker">>;

export type DatePickerSegmentHTMLProps = SegmentHTMLProps;

Expand All @@ -22,6 +20,17 @@ export const useDatePickerSegment = createHook<
name: "DatePickerSegment",
compose: useSegment,
keys: DATE_PICKER_SEGMENT_KEYS,

useProps(options, htmlProps) {
const { id } = useId({ baseId: "datepicker-segment" });
return {
id,
...(options.isDateRangePicker
? { "aria-labelledby": `${options.pickerId} ${options.baseId} ${id}` }
: { "aria-labelledby": id }),
...htmlProps,
};
},
});

export const DatePickerSegment = createComponent({
Expand Down
1 change: 1 addition & 0 deletions src/datepicker/DatePickerState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export const useDatePickerState = (props: DatePickerInitialState = {}) => {
...popover,
...segmentState,
calendar,
isDateRangePicker: false,
};
};

Expand Down
11 changes: 7 additions & 4 deletions src/datepicker/DateRangePickerState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ import {
FocusableProps,
ValidationState,
} from "@react-types/shared";
import { v4 } from "uuid";
import * as React from "react";
import { useCompositeState } from "reakit";
import { useControllableState } from "@chakra-ui/hooks";
import { useCompositeState, unstable_useId as useId } from "reakit";

import {
parseDate,
Expand Down Expand Up @@ -159,6 +158,9 @@ export const useDateRangePickerState = (
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [autoFocus, segmentComposite.first]);

const { id: startId } = useId({ baseId: "startsegment" });
const { id: endId } = useId({ baseId: "endsegment" });

return {
dateValue: value,
setDateValue: setValue,
Expand All @@ -171,14 +173,15 @@ export const useDateRangePickerState = (
startSegmentState: {
...startSegmentState,
...segmentComposite,
baseId: v4(),
baseId: startId,
},
endSegmentState: {
...endSegmentState,
...segmentComposite,
baseId: v4(),
baseId: endId,
},
calendar,
isDateRangePicker: true,
};
};

Expand Down
2 changes: 2 additions & 0 deletions src/datepicker/__keys.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Automatically generated
const DATE_PICKER_STATE_KEYS = [
"calendar",
"isDateRangePicker",
"fieldValue",
"setFieldValue",
"segments",
Expand Down Expand Up @@ -83,6 +84,7 @@ const DATE_RANGE_PICKER_STATE_KEYS = [
"startSegmentState",
"endSegmentState",
"calendar",
"isDateRangePicker",
"baseId",
"unstable_idCountRef",
"visible",
Expand Down
12 changes: 8 additions & 4 deletions src/datepicker/__tests__/DateRangePicker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,12 +146,16 @@ describe("DateRangePicker", () => {

openDatePicker(text, testId);

expect(label("Sunday, November 15, 2020 selected")).toHaveFocus();
expect(
label(
"Sunday, November 15, 2020 selected (click to start selecting range)",
),
).toHaveFocus();

// check if current date is selected
isEndSelection(label, "Sunday, November 15, 2020 selected");
isStartSelection(label, "Sunday, November 15, 2020 selected");
isInSelectionRange(label, "Sunday, November 15, 2020 selected");
isEndSelection(label, /Sunday, November 15, 2020 selected/i);
isStartSelection(label, /Sunday, November 15, 2020 selected/i);
isInSelectionRange(label, /Sunday, November 15, 2020 selected/i);

// change date selection
press.Enter();
Expand Down
Loading

0 comments on commit c5d453b

Please sign in to comment.