@simplybusiness/mobius-datepicker 4.0.0-beta.7 → 4.0.0-beta.9
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.
- package/dist/cjs/components/NewDatePicker/DatePickerIcon.d.ts +1 -0
- package/dist/cjs/components/NewDatePicker/DatePickerIcon.js +7 -0
- package/dist/cjs/components/NewDatePicker/DatePickerIcon.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/DatePickerModal.d.ts +7 -0
- package/dist/cjs/components/NewDatePicker/DatePickerModal.js +35 -0
- package/dist/cjs/components/NewDatePicker/DatePickerModal.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.d.ts +7 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.js +73 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.stories.d.ts +27 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.stories.js +32 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.stories.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.test.d.ts +1 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.test.js +80 -0
- package/dist/cjs/components/NewDatePicker/NewDatePicker.test.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/constants.d.ts +2 -0
- package/dist/cjs/components/NewDatePicker/constants.js +7 -0
- package/dist/cjs/components/NewDatePicker/constants.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/dateObjToString.d.ts +1 -0
- package/dist/cjs/components/NewDatePicker/dateObjToString.js +7 -0
- package/dist/cjs/components/NewDatePicker/dateObjToString.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/dateObjToString.test.d.ts +1 -0
- package/dist/cjs/components/NewDatePicker/dateObjToString.test.js +15 -0
- package/dist/cjs/components/NewDatePicker/dateObjToString.test.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/index.d.ts +1 -0
- package/dist/cjs/components/NewDatePicker/index.js +18 -0
- package/dist/cjs/components/NewDatePicker/index.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/weekdayAsOneLetter.d.ts +2 -0
- package/dist/cjs/components/NewDatePicker/weekdayAsOneLetter.js +14 -0
- package/dist/cjs/components/NewDatePicker/weekdayAsOneLetter.js.map +1 -0
- package/dist/cjs/components/NewDatePicker/weekdayAsOneLetter.test.d.ts +1 -0
- package/dist/cjs/components/NewDatePicker/weekdayAsOneLetter.test.js +23 -0
- package/dist/cjs/components/NewDatePicker/weekdayAsOneLetter.test.js.map +1 -0
- package/dist/cjs/hooks/useFocusTrap.d.ts +5 -0
- package/dist/cjs/hooks/useFocusTrap.js +41 -0
- package/dist/cjs/hooks/useFocusTrap.js.map +1 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils/excludeControls.d.ts +1 -0
- package/dist/cjs/utils/excludeControls.js +29 -0
- package/dist/cjs/utils/excludeControls.js.map +1 -0
- package/dist/cjs/utils/excludeControls.test.d.ts +1 -0
- package/dist/cjs/utils/excludeControls.test.js +25 -0
- package/dist/cjs/utils/excludeControls.test.js.map +1 -0
- package/dist/cjs/utils/isTouchDevice.d.ts +1 -0
- package/dist/cjs/utils/isTouchDevice.js +11 -0
- package/dist/cjs/utils/isTouchDevice.js.map +1 -0
- package/dist/esm/components/NewDatePicker/DatePickerIcon.js +3 -0
- package/dist/esm/components/NewDatePicker/DatePickerIcon.js.map +1 -0
- package/dist/esm/components/NewDatePicker/DatePickerModal.js +28 -0
- package/dist/esm/components/NewDatePicker/DatePickerModal.js.map +1 -0
- package/dist/esm/components/NewDatePicker/NewDatePicker.js +66 -0
- package/dist/esm/components/NewDatePicker/NewDatePicker.js.map +1 -0
- package/dist/esm/components/NewDatePicker/constants.js +4 -0
- package/dist/esm/components/NewDatePicker/constants.js.map +1 -0
- package/dist/esm/components/NewDatePicker/dateObjToString.js +3 -0
- package/dist/esm/components/NewDatePicker/dateObjToString.js.map +1 -0
- package/dist/esm/components/NewDatePicker/dateObjToString.test.js +13 -0
- package/dist/esm/components/NewDatePicker/dateObjToString.test.js.map +1 -0
- package/dist/esm/components/NewDatePicker/index.js +2 -0
- package/dist/esm/components/NewDatePicker/index.js.map +1 -0
- package/dist/esm/components/NewDatePicker/weekdayAsOneLetter.js +10 -0
- package/dist/esm/components/NewDatePicker/weekdayAsOneLetter.js.map +1 -0
- package/dist/esm/components/NewDatePicker/weekdayAsOneLetter.test.js +21 -0
- package/dist/esm/components/NewDatePicker/weekdayAsOneLetter.test.js.map +1 -0
- package/dist/esm/hooks/useFocusTrap.js +38 -0
- package/dist/esm/hooks/useFocusTrap.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/utils/excludeControls.js +25 -0
- package/dist/esm/utils/excludeControls.js.map +1 -0
- package/dist/esm/utils/excludeControls.test.js +23 -0
- package/dist/esm/utils/excludeControls.test.js.map +1 -0
- package/dist/esm/utils/isTouchDevice.js +7 -0
- package/dist/esm/utils/isTouchDevice.js.map +1 -0
- package/package.json +6 -4
- package/src/components/NewDatePicker/DatePickerIcon.tsx +1 -0
- package/src/components/NewDatePicker/DatePickerModal.tsx +69 -0
- package/src/components/NewDatePicker/NewDatePicker.mdx +521 -0
- package/src/components/NewDatePicker/NewDatePicker.stories.tsx +46 -0
- package/src/components/NewDatePicker/NewDatePicker.test.tsx +121 -0
- package/src/components/NewDatePicker/NewDatePicker.tsx +119 -0
- package/src/components/NewDatePicker/constants.ts +3 -0
- package/src/components/NewDatePicker/dateObjToString.test.ts +17 -0
- package/src/components/NewDatePicker/dateObjToString.ts +3 -0
- package/src/components/NewDatePicker/index.tsx +1 -0
- package/src/components/NewDatePicker/weekdayAsOneLetter.test.ts +28 -0
- package/src/components/NewDatePicker/weekdayAsOneLetter.ts +11 -0
- package/src/hooks/useFocusTrap.tsx +55 -0
- package/src/utils/excludeControls.test.ts +26 -0
- package/src/utils/excludeControls.ts +28 -0
- package/src/utils/isTouchDevice.ts +7 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { render, screen, fireEvent } from "@testing-library/react";
|
|
2
|
+
import { NewDatePicker } from ".";
|
|
3
|
+
|
|
4
|
+
const mockMatchMedia = (matches: boolean) => {
|
|
5
|
+
Object.defineProperty(window, "matchMedia", {
|
|
6
|
+
writable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
value: jest.fn().mockImplementation(query => ({
|
|
9
|
+
matches,
|
|
10
|
+
media: query,
|
|
11
|
+
onchange: null,
|
|
12
|
+
addListener: jest.fn(),
|
|
13
|
+
removeListener: jest.fn(),
|
|
14
|
+
addEventListener: jest.fn(),
|
|
15
|
+
removeEventListener: jest.fn(),
|
|
16
|
+
dispatchEvent: jest.fn(),
|
|
17
|
+
})),
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
describe("NewDatePicker", () => {
|
|
22
|
+
describe("given it is a touch device", () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
mockMatchMedia(true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("should render without errors", () => {
|
|
28
|
+
const exampleDate = "2023-11-13";
|
|
29
|
+
const labelText = "Start date";
|
|
30
|
+
const testId = "date-picker";
|
|
31
|
+
|
|
32
|
+
render(
|
|
33
|
+
<NewDatePicker
|
|
34
|
+
defaultValue={exampleDate}
|
|
35
|
+
label={labelText}
|
|
36
|
+
data-testid={testId}
|
|
37
|
+
/>,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const inputField = screen.getByTestId(testId);
|
|
41
|
+
const label = screen.getByLabelText(labelText);
|
|
42
|
+
|
|
43
|
+
expect(inputField).toHaveValue(exampleDate);
|
|
44
|
+
expect(label).toBeInTheDocument();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe("when value changes", () => {
|
|
48
|
+
it("triggers onChange", () => {
|
|
49
|
+
const labelText = "Start date";
|
|
50
|
+
const testId = "date-picker";
|
|
51
|
+
const onChange = jest.fn();
|
|
52
|
+
|
|
53
|
+
render(
|
|
54
|
+
<NewDatePicker
|
|
55
|
+
label={labelText}
|
|
56
|
+
data-testid={testId}
|
|
57
|
+
onChange={onChange}
|
|
58
|
+
/>,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
const inputField = screen.getByTestId(testId);
|
|
62
|
+
const newDate = "2015-06-01";
|
|
63
|
+
|
|
64
|
+
fireEvent.change(inputField, { target: { value: newDate } });
|
|
65
|
+
|
|
66
|
+
expect(inputField).toHaveValue(newDate);
|
|
67
|
+
expect(onChange).toHaveBeenCalledWith(newDate);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("given it is a non-touch device", () => {
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
mockMatchMedia(false);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("should render without errors", () => {
|
|
78
|
+
const exampleDate = "2023-11-13";
|
|
79
|
+
const labelText = "Start date";
|
|
80
|
+
const testId = "date-picker";
|
|
81
|
+
|
|
82
|
+
render(
|
|
83
|
+
<NewDatePicker
|
|
84
|
+
defaultValue={exampleDate}
|
|
85
|
+
label={labelText}
|
|
86
|
+
data-testid={testId}
|
|
87
|
+
/>,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const inputField = screen.getByTestId(testId);
|
|
91
|
+
const label = screen.getByLabelText(labelText);
|
|
92
|
+
|
|
93
|
+
expect(inputField).toHaveValue(exampleDate);
|
|
94
|
+
expect(label).toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe("when value changes", () => {
|
|
98
|
+
it("triggers onChange", () => {
|
|
99
|
+
const labelText = "Start date";
|
|
100
|
+
const testId = "date-picker";
|
|
101
|
+
const onChange = jest.fn();
|
|
102
|
+
|
|
103
|
+
render(
|
|
104
|
+
<NewDatePicker
|
|
105
|
+
label={labelText}
|
|
106
|
+
data-testid={testId}
|
|
107
|
+
onChange={onChange}
|
|
108
|
+
/>,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const inputField = screen.getByTestId(testId);
|
|
112
|
+
const newDate = "2015-06-01";
|
|
113
|
+
|
|
114
|
+
fireEvent.change(inputField, { target: { value: newDate } });
|
|
115
|
+
|
|
116
|
+
expect(inputField).toHaveValue(newDate);
|
|
117
|
+
expect(onChange).toHaveBeenCalledWith(newDate);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
TextField,
|
|
6
|
+
TextFieldElementType,
|
|
7
|
+
TextFieldProps,
|
|
8
|
+
VisuallyHidden,
|
|
9
|
+
} from "@simplybusiness/mobius";
|
|
10
|
+
import classNames from "classnames/dedupe";
|
|
11
|
+
import { ChangeEvent, useEffect, useRef, useState } from "react";
|
|
12
|
+
import { isTouchDevice } from "../../utils/isTouchDevice";
|
|
13
|
+
import { DatePickerModal } from "./DatePickerModal";
|
|
14
|
+
|
|
15
|
+
export interface NewDatePickerProps
|
|
16
|
+
extends Omit<TextFieldProps, "defaultValue" | "onChange"> {
|
|
17
|
+
onChange?: (date: string) => void;
|
|
18
|
+
defaultValue?: string;
|
|
19
|
+
id?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const NewDatePicker = (props: NewDatePickerProps) => {
|
|
23
|
+
const {
|
|
24
|
+
onChange,
|
|
25
|
+
defaultValue = "",
|
|
26
|
+
isDisabled,
|
|
27
|
+
validationState,
|
|
28
|
+
...otherProps
|
|
29
|
+
} = props;
|
|
30
|
+
const ref = useRef<TextFieldElementType | null>(null);
|
|
31
|
+
const [top, setTop] = useState<number>(0);
|
|
32
|
+
const [isOpen, setIsOpen] = useState<boolean>(false);
|
|
33
|
+
const [textFieldVal, setTextFieldVal] = useState<string>(defaultValue); // yyyy-MM-dd
|
|
34
|
+
const touchDevice = isTouchDevice();
|
|
35
|
+
|
|
36
|
+
const containerClasses = classNames("mobius/DatePickerContainer", {
|
|
37
|
+
"--is-disabled": isDisabled,
|
|
38
|
+
"--is-valid": validationState === "valid",
|
|
39
|
+
"--is-invalid": validationState === "invalid",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const popoverToggleClasses = classNames("mobius/DateFieldButton", {
|
|
43
|
+
"--is-valid": validationState === "valid",
|
|
44
|
+
"--is-invalid": validationState === "invalid",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const setPopoverPosition = () => {
|
|
48
|
+
if (!ref.current || isOpen) return;
|
|
49
|
+
|
|
50
|
+
const refHeight = ref.current.getBoundingClientRect().height;
|
|
51
|
+
|
|
52
|
+
setTop(refHeight);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const togglePopoverVisibility = () => {
|
|
56
|
+
setIsOpen(!isOpen);
|
|
57
|
+
setPopoverPosition();
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleTextFieldChange = (event: ChangeEvent<TextFieldElementType>) => {
|
|
61
|
+
setTextFieldVal(event.target.value);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const onDateSelected = (selectedDate: string) => {
|
|
65
|
+
setTextFieldVal(selectedDate);
|
|
66
|
+
setIsOpen(false);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// When user manually types in date,
|
|
70
|
+
// select date when popover becomes visible
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!textFieldVal) return;
|
|
73
|
+
if (onChange) {
|
|
74
|
+
onChange(textFieldVal);
|
|
75
|
+
}
|
|
76
|
+
}, [textFieldVal, onChange]);
|
|
77
|
+
|
|
78
|
+
if (touchDevice) {
|
|
79
|
+
return (
|
|
80
|
+
<TextField
|
|
81
|
+
type="date"
|
|
82
|
+
onChange={handleTextFieldChange}
|
|
83
|
+
value={textFieldVal}
|
|
84
|
+
isDisabled={isDisabled}
|
|
85
|
+
validationState={validationState}
|
|
86
|
+
{...otherProps}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div className={containerClasses} ref={ref}>
|
|
93
|
+
<TextField
|
|
94
|
+
type="date"
|
|
95
|
+
className="mobius/DatePicker"
|
|
96
|
+
onChange={handleTextFieldChange}
|
|
97
|
+
value={textFieldVal}
|
|
98
|
+
isDisabled={isDisabled}
|
|
99
|
+
validationState={validationState}
|
|
100
|
+
{...otherProps}
|
|
101
|
+
/>
|
|
102
|
+
<Button
|
|
103
|
+
className={popoverToggleClasses}
|
|
104
|
+
onClick={togglePopoverVisibility}
|
|
105
|
+
isDisabled={isDisabled}
|
|
106
|
+
>
|
|
107
|
+
<VisuallyHidden>Pick date</VisuallyHidden>
|
|
108
|
+
</Button>
|
|
109
|
+
{isOpen && (
|
|
110
|
+
<DatePickerModal
|
|
111
|
+
date={textFieldVal}
|
|
112
|
+
isOpen={isOpen}
|
|
113
|
+
top={top}
|
|
114
|
+
onSelected={onDateSelected}
|
|
115
|
+
/>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
);
|
|
119
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { dateObjToString } from "./dateObjToString";
|
|
2
|
+
|
|
3
|
+
describe("dateObjToString", () => {
|
|
4
|
+
describe("given a Date object", () => {
|
|
5
|
+
it("returns a formatted string as yyyy-mm-dd", () => {
|
|
6
|
+
const exampleDate = "2023-11-13";
|
|
7
|
+
|
|
8
|
+
const input = new Date(exampleDate);
|
|
9
|
+
|
|
10
|
+
const actual = dateObjToString(input);
|
|
11
|
+
|
|
12
|
+
const expected = exampleDate;
|
|
13
|
+
|
|
14
|
+
expect(actual).toEqual(expected);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./NewDatePicker";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { weekdayAsOneLetter } from "./weekdayAsOneLetter";
|
|
2
|
+
|
|
3
|
+
describe("weekdayAsOneLetter", () => {
|
|
4
|
+
describe("given a Date object and a locale", () => {
|
|
5
|
+
it("returns weekday as a single letter", () => {
|
|
6
|
+
const randomMonday = new Date("2023-11-13");
|
|
7
|
+
const locale = { locale: { code: "en-GB" } };
|
|
8
|
+
|
|
9
|
+
const actual = weekdayAsOneLetter(randomMonday, locale);
|
|
10
|
+
|
|
11
|
+
const expected = "M";
|
|
12
|
+
|
|
13
|
+
expect(actual).toEqual(expected);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe("given a Date object and no locale", () => {
|
|
18
|
+
it("returns weekday as a single letter, using en-GB as default locale", () => {
|
|
19
|
+
const randomMonday = new Date("2023-11-13");
|
|
20
|
+
|
|
21
|
+
const actual = weekdayAsOneLetter(randomMonday);
|
|
22
|
+
|
|
23
|
+
const expected = "M";
|
|
24
|
+
|
|
25
|
+
expect(actual).toEqual(expected);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DateFormatter } from "react-day-picker";
|
|
2
|
+
import { DEFAULT_LOCALE } from "./constants";
|
|
3
|
+
|
|
4
|
+
export const weekdayAsOneLetter: DateFormatter = (weekday, options) => {
|
|
5
|
+
const locale = options?.locale?.code || DEFAULT_LOCALE;
|
|
6
|
+
const oneLetter = weekday.toLocaleString(locale, {
|
|
7
|
+
weekday: "narrow",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
return oneLetter;
|
|
11
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ReactNode, useEffect, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
const useFocusTrap = () => {
|
|
4
|
+
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line consistent-return
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (containerRef.current) {
|
|
9
|
+
const element = containerRef.current;
|
|
10
|
+
const focusableElements =
|
|
11
|
+
containerRef.current.querySelectorAll<HTMLElement>(
|
|
12
|
+
'.rdp-nav_button, [tabindex]:not([tabindex="-1"])',
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const firstElement = focusableElements[0];
|
|
16
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
17
|
+
|
|
18
|
+
const handleTabKeyPress = (event: KeyboardEvent) => {
|
|
19
|
+
if (event.key === "Tab") {
|
|
20
|
+
if (event.shiftKey && document.activeElement === firstElement) {
|
|
21
|
+
event.preventDefault();
|
|
22
|
+
lastElement.focus();
|
|
23
|
+
} else if (
|
|
24
|
+
!event.shiftKey &&
|
|
25
|
+
document.activeElement === lastElement // TODO: handle for any day
|
|
26
|
+
) {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
firstElement.focus();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
element.addEventListener("keydown", handleTabKeyPress);
|
|
34
|
+
return () => {
|
|
35
|
+
element.removeEventListener("keydown", handleTabKeyPress);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
return containerRef;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type FocusTrapProps = {
|
|
44
|
+
children: ReactNode;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default function FocusTrap({ children }: FocusTrapProps) {
|
|
48
|
+
const focusRef = useFocusTrap();
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className="trap" ref={focusRef}>
|
|
52
|
+
{children}
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { excludeControls } from "./excludeControls";
|
|
2
|
+
|
|
3
|
+
describe("excludeControls", () => {
|
|
4
|
+
describe("given a list of props", () => {
|
|
5
|
+
it("returns an object where each prop has an entry with disabled params", () => {
|
|
6
|
+
const props = ["className", "elementType"];
|
|
7
|
+
|
|
8
|
+
const actual = excludeControls(...props);
|
|
9
|
+
|
|
10
|
+
const expected = {
|
|
11
|
+
elementType: {
|
|
12
|
+
table: {
|
|
13
|
+
disable: true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
className: {
|
|
17
|
+
table: {
|
|
18
|
+
disable: true,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
expect(actual).toEqual(expected);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// This function generates data structure required to hide specified
|
|
2
|
+
// prop from individual stories. Key 'table' is where specified key
|
|
3
|
+
// is disabled.
|
|
4
|
+
//
|
|
5
|
+
// The above is documented here:
|
|
6
|
+
// https://storybook.js.org/docs/react/essentials/controls#disable-controls-for-specific-properties
|
|
7
|
+
//
|
|
8
|
+
// The expected usage looks as follows:
|
|
9
|
+
//
|
|
10
|
+
// <Meta
|
|
11
|
+
// title="Components/MyComponent"
|
|
12
|
+
// component={MyComponent}
|
|
13
|
+
// argTypes={{
|
|
14
|
+
// label: {
|
|
15
|
+
// control: {
|
|
16
|
+
// type: "text",
|
|
17
|
+
// },
|
|
18
|
+
// table: {
|
|
19
|
+
// disable: true,
|
|
20
|
+
// },
|
|
21
|
+
// },
|
|
22
|
+
// }}
|
|
23
|
+
// />
|
|
24
|
+
export const excludeControls = (...args: string[]) =>
|
|
25
|
+
args.reduce(
|
|
26
|
+
(prev, acc) => ({ ...prev, [acc]: { table: { disable: true } } }),
|
|
27
|
+
{},
|
|
28
|
+
);
|