carbon-react 107.1.3 → 107.1.6
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/esm/__internal__/input/input.component.js +3 -0
- package/esm/__internal__/label/icon-wrapper.style.d.ts +2 -0
- package/esm/__internal__/label/icon-wrapper.style.js +4 -4
- package/esm/__internal__/label/index.d.ts +2 -1
- package/esm/__internal__/label/label.component.d.ts +27 -0
- package/esm/__internal__/label/label.component.js +42 -80
- package/esm/__internal__/label/label.style.d.ts +23 -3
- package/esm/__internal__/label/label.style.js +4 -19
- package/esm/__internal__/utils/helpers/events/events.d.ts +0 -58
- package/esm/__internal__/utils/helpers/events/events.js +12 -128
- package/esm/__spec_helper__/test-utils.d.ts +4 -25
- package/esm/__spec_helper__/test-utils.js +12 -25
- package/esm/components/action-popover/action-popover-menu/action-popover-menu.component.js +2 -2
- package/esm/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.component.d.ts +19 -0
- package/esm/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.component.js +14 -21
- package/esm/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.style.d.ts +5 -0
- package/esm/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.style.js +0 -4
- package/esm/components/anchor-navigation/anchor-navigation.component.d.ts +14 -0
- package/esm/components/anchor-navigation/anchor-navigation.component.js +55 -72
- package/esm/components/anchor-navigation/anchor-navigation.style.d.ts +4 -0
- package/esm/components/anchor-navigation/anchor-section-divider.component.d.ts +4 -0
- package/esm/components/anchor-navigation/{anchor-section-divider/anchor-section-divider.style.js → anchor-section-divider.component.js} +3 -2
- package/esm/components/anchor-navigation/index.d.ts +5 -3
- package/esm/components/anchor-navigation/index.js +1 -1
- package/esm/components/date/__internal__/date-picker/date-picker.component.js +10 -1
- package/esm/components/flat-table/flat-table-cell/flat-table-cell.component.js +1 -0
- package/esm/components/flat-table/flat-table-checkbox/flat-table-checkbox.component.js +1 -0
- package/esm/components/flat-table/flat-table-header/flat-table-header.component.js +1 -0
- package/esm/components/flat-table/flat-table-row/flat-table-row.component.js +3 -3
- package/esm/components/flat-table/flat-table-row-header/flat-table-row-header.component.js +1 -0
- package/esm/components/help/help.style.d.ts +2 -0
- package/esm/components/menu/__internal__/spec-helper/index.js +1 -2
- package/esm/components/menu/__internal__/submenu/submenu.component.js +1 -1
- package/esm/components/multi-action-button/multi-action-button.component.js +3 -0
- package/esm/components/numeral-date/numeral-date.component.js +1 -1
- package/esm/components/search/search.component.js +1 -2
- package/esm/components/tabs/tabs.component.js +28 -20
- package/lib/__internal__/input/input.component.js +3 -0
- package/lib/__internal__/label/icon-wrapper.style.d.ts +2 -0
- package/lib/__internal__/label/icon-wrapper.style.js +2 -2
- package/lib/__internal__/label/index.d.ts +2 -1
- package/lib/__internal__/label/label.component.d.ts +27 -0
- package/lib/__internal__/label/label.component.js +40 -78
- package/lib/__internal__/label/label.style.d.ts +23 -3
- package/lib/__internal__/label/label.style.js +4 -22
- package/lib/__internal__/utils/helpers/events/events.d.ts +0 -58
- package/lib/__internal__/utils/helpers/events/events.js +12 -128
- package/lib/__spec_helper__/test-utils.d.ts +4 -25
- package/lib/__spec_helper__/test-utils.js +12 -25
- package/lib/components/action-popover/action-popover-menu/action-popover-menu.component.js +2 -2
- package/lib/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.component.d.ts +19 -0
- package/lib/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.component.js +14 -21
- package/lib/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.style.d.ts +5 -0
- package/lib/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.style.js +0 -7
- package/lib/components/anchor-navigation/anchor-navigation.component.d.ts +14 -0
- package/lib/components/anchor-navigation/anchor-navigation.component.js +57 -73
- package/lib/components/anchor-navigation/anchor-navigation.style.d.ts +4 -0
- package/lib/components/anchor-navigation/anchor-section-divider.component.d.ts +4 -0
- package/lib/components/anchor-navigation/{anchor-section-divider/anchor-section-divider.style.js → anchor-section-divider.component.js} +3 -2
- package/lib/components/anchor-navigation/index.d.ts +5 -3
- package/lib/components/anchor-navigation/index.js +1 -1
- package/lib/components/date/__internal__/date-picker/date-picker.component.js +10 -1
- package/lib/components/flat-table/flat-table-cell/flat-table-cell.component.js +1 -0
- package/lib/components/flat-table/flat-table-checkbox/flat-table-checkbox.component.js +1 -0
- package/lib/components/flat-table/flat-table-header/flat-table-header.component.js +1 -0
- package/lib/components/flat-table/flat-table-row/flat-table-row.component.js +2 -4
- package/lib/components/flat-table/flat-table-row-header/flat-table-row-header.component.js +1 -0
- package/lib/components/help/help.style.d.ts +2 -0
- package/lib/components/menu/__internal__/spec-helper/index.js +1 -2
- package/lib/components/menu/__internal__/submenu/submenu.component.js +1 -1
- package/lib/components/multi-action-button/multi-action-button.component.js +3 -0
- package/lib/components/numeral-date/numeral-date.component.js +1 -1
- package/lib/components/search/search.component.js +1 -3
- package/lib/components/tabs/tabs.component.js +28 -20
- package/package.json +4 -4
- package/esm/__internal__/label/label.d.ts +0 -43
- package/esm/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.d.ts +0 -23
- package/esm/components/anchor-navigation/anchor-navigation.d.ts +0 -11
- package/esm/components/anchor-navigation/anchor-section-divider/anchor-section-divider.d.ts +0 -12
- package/lib/__internal__/label/label.d.ts +0 -43
- package/lib/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.d.ts +0 -23
- package/lib/components/anchor-navigation/anchor-navigation.d.ts +0 -11
- package/lib/components/anchor-navigation/anchor-section-divider/anchor-section-divider.d.ts +0 -12
|
@@ -27,43 +27,6 @@ const Events = {
|
|
|
27
27
|
return ev.type === type;
|
|
28
28
|
},
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
* A method to determine whether a key down event was an arrow key
|
|
32
|
-
* */
|
|
33
|
-
isNavigationKeyup: ev => {
|
|
34
|
-
if (!Events.isEventType(ev, "keyup")) {
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return Events.isNavigationKey(ev);
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* A method to determine whether a key down event was an enter key
|
|
43
|
-
* */
|
|
44
|
-
isEnterKeyup: ev => {
|
|
45
|
-
if (!Events.isEventType(ev, "keyup")) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return Events.isEnterKey(ev);
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* A method to determine whether a key up event is allowed or not.
|
|
54
|
-
* */
|
|
55
|
-
isValidKeypress: ev => {
|
|
56
|
-
if (!Events.isEventType(ev, "keyup")) {
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (Events.isNumberKey(ev) || Events.isAlphabetKey(ev) || Events.isNumpadKey(ev) || Events.isSymbolKey(ev) || Events.isSpaceKey(ev) || Events.isDeletingKey(ev) || Events.isBackspaceKey(ev)) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return false;
|
|
65
|
-
},
|
|
66
|
-
|
|
67
30
|
/**
|
|
68
31
|
* Determines if a number key along the top of the keyboard or a number key on the
|
|
69
32
|
* keypad is pressed
|
|
@@ -75,167 +38,88 @@ const Events = {
|
|
|
75
38
|
return charCode !== undefined && charCode >= 48 && charCode <= 57;
|
|
76
39
|
},
|
|
77
40
|
|
|
78
|
-
/**
|
|
79
|
-
* Determines if the key pressed is part of the numpad
|
|
80
|
-
* includes symbols
|
|
81
|
-
* */
|
|
82
|
-
isNumpadKey: ev => {
|
|
83
|
-
return ev.which !== undefined && ev.which >= 96 && ev.which <= 111;
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Determines if the key pressed is a alphabet key
|
|
88
|
-
* Case insensitive
|
|
89
|
-
* */
|
|
90
|
-
isAlphabetKey: ev => {
|
|
91
|
-
return ev.which !== undefined && ev.which >= 65 && ev.which <= 90;
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Determines if the key pressed is a valid symbol
|
|
96
|
-
* */
|
|
97
|
-
isSymbolKey: ev => {
|
|
98
|
-
return ev.which !== undefined && (ev.which >= 58 && ev.which <= 64 || ev.which >= 106 && ev.which <= 107 || ev.which >= 186 && ev.which <= 192 || ev.which >= 219 && ev.which <= 222);
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Determines if the key pressed is a navigation key
|
|
103
|
-
* */
|
|
104
|
-
isNavigationKey: ev => {
|
|
105
|
-
return ev.which !== undefined && ev.which >= 37 && ev.which <= 40;
|
|
106
|
-
},
|
|
107
|
-
|
|
108
41
|
/**
|
|
109
42
|
* Determines if the key pressed is a navigation left key
|
|
110
43
|
* */
|
|
111
44
|
isLeftKey: ev => {
|
|
112
|
-
return ev.
|
|
45
|
+
return ev.key === "ArrowLeft";
|
|
113
46
|
},
|
|
114
47
|
|
|
115
48
|
/**
|
|
116
49
|
* Determines if the key pressed is a navigation up key
|
|
117
50
|
* */
|
|
118
51
|
isUpKey: ev => {
|
|
119
|
-
return ev.
|
|
52
|
+
return ev.key === "ArrowUp";
|
|
120
53
|
},
|
|
121
54
|
|
|
122
55
|
/**
|
|
123
56
|
* Determines if the key pressed is a navigation right key
|
|
124
57
|
* */
|
|
125
58
|
isRightKey: ev => {
|
|
126
|
-
return ev.
|
|
59
|
+
return ev.key === "ArrowRight";
|
|
127
60
|
},
|
|
128
61
|
|
|
129
62
|
/**
|
|
130
63
|
* Determines if the key pressed is a navigation down key
|
|
131
64
|
* */
|
|
132
65
|
isDownKey: ev => {
|
|
133
|
-
return ev.
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Determines if the key pressed is a meta key
|
|
138
|
-
* */
|
|
139
|
-
isMetaKey: ev => {
|
|
140
|
-
return !!ev.metaKey;
|
|
66
|
+
return ev.key === "ArrowDown";
|
|
141
67
|
},
|
|
142
68
|
|
|
143
69
|
/**
|
|
144
70
|
* Determines if the key pressed is the escape key
|
|
145
71
|
* */
|
|
146
72
|
isEscKey: ev => {
|
|
147
|
-
return ev.
|
|
73
|
+
return ev.key === "Escape";
|
|
148
74
|
},
|
|
149
75
|
|
|
150
76
|
/**
|
|
151
77
|
* Determines if the key pressed is the enter key
|
|
152
78
|
* */
|
|
153
79
|
isEnterKey: ev => {
|
|
154
|
-
return ev.
|
|
80
|
+
return ev.key === "Enter";
|
|
155
81
|
},
|
|
156
82
|
|
|
157
83
|
/**
|
|
158
84
|
* Determines if the key pressed is the tab key
|
|
159
85
|
* */
|
|
160
86
|
isTabKey: ev => {
|
|
161
|
-
return ev.
|
|
162
|
-
},
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Determines if the key pressed is the backspace key
|
|
166
|
-
* */
|
|
167
|
-
isBackspaceKey: ev => {
|
|
168
|
-
return ev.key === "Backspace";
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Determines if the key pressed is the delete key
|
|
173
|
-
* */
|
|
174
|
-
isDeleteKey: ev => {
|
|
175
|
-
return ev.key === "Delete";
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Determines if the key pressed is the backspace or delete key
|
|
180
|
-
* */
|
|
181
|
-
isDeletingKey: ev => {
|
|
182
|
-
return Events.isDeleteKey(ev) || Events.isBackspaceKey(ev);
|
|
87
|
+
return ev.key === "Tab";
|
|
183
88
|
},
|
|
184
89
|
|
|
185
90
|
/**
|
|
186
91
|
* Determines if the key pressed is the shift key
|
|
187
92
|
* */
|
|
188
93
|
isShiftKey: ev => {
|
|
189
|
-
return ev.shiftKey
|
|
94
|
+
return ev.shiftKey;
|
|
190
95
|
},
|
|
191
96
|
|
|
192
97
|
/**
|
|
193
98
|
* Determines if the key pressed is the space key
|
|
194
99
|
* */
|
|
195
100
|
isSpaceKey: ev => {
|
|
196
|
-
return ev.
|
|
101
|
+
return ev.key === " ";
|
|
197
102
|
},
|
|
198
103
|
|
|
199
104
|
/**
|
|
200
105
|
* Determines if the key pressed is the space key or enter key
|
|
201
106
|
* */
|
|
202
107
|
isEnterOrSpaceKey: ev => {
|
|
203
|
-
return ev.
|
|
204
|
-
},
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Determines if the key pressed is the period key
|
|
208
|
-
* */
|
|
209
|
-
isPeriodKey: ev => {
|
|
210
|
-
return ev.which === 190;
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Determines if the key pressed is the comma key
|
|
215
|
-
* */
|
|
216
|
-
isCommaKey: ev => {
|
|
217
|
-
return ev.which === 188;
|
|
218
|
-
},
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Determines if the key pressed is the minus key
|
|
222
|
-
* */
|
|
223
|
-
isMinusKey: ev => {
|
|
224
|
-
return ev.key === "-" || ev.key === "Subtract";
|
|
108
|
+
return ev.key === "Enter" || ev.key === " ";
|
|
225
109
|
},
|
|
226
110
|
|
|
227
111
|
/**
|
|
228
112
|
* Determines if the key pressed is the home key
|
|
229
113
|
* */
|
|
230
114
|
isHomeKey: ev => {
|
|
231
|
-
return ev.
|
|
115
|
+
return ev.key === "Home";
|
|
232
116
|
},
|
|
233
117
|
|
|
234
118
|
/**
|
|
235
119
|
* Determines if the key pressed is the end key
|
|
236
120
|
* */
|
|
237
121
|
isEndKey: ev => {
|
|
238
|
-
return ev.
|
|
122
|
+
return ev.key === "End";
|
|
239
123
|
},
|
|
240
124
|
|
|
241
125
|
/**
|
|
@@ -8,32 +8,11 @@ declare const assertStyleMatch: <Props>(styleSpec: {
|
|
|
8
8
|
[key: string]: string | number | undefined;
|
|
9
9
|
}, component: ReactWrapper<Props, {}, import("react").Component<{}, {}, any>> | ShallowWrapper<Props, {}, import("react").Component<{}, {}, any>> | ReactTestRendererJSON | ReactTestRendererJSON[] | null, opts?: jest.Options | undefined) => void;
|
|
10
10
|
declare const makeArrayKeys: (n: number) => number[];
|
|
11
|
-
declare const
|
|
12
|
-
readonly UpArrow: 38;
|
|
13
|
-
readonly DownArrow: 40;
|
|
14
|
-
readonly RightArrow: 39;
|
|
15
|
-
readonly LeftArrow: 37;
|
|
16
|
-
readonly Enter: 13;
|
|
17
|
-
readonly Tab: 9;
|
|
18
|
-
readonly Space: 32;
|
|
19
|
-
readonly Escape: 27;
|
|
20
|
-
readonly End: 35;
|
|
21
|
-
readonly Home: 36;
|
|
22
|
-
readonly D: 68;
|
|
23
|
-
readonly E: 69;
|
|
24
|
-
readonly P: 80;
|
|
25
|
-
readonly Z: 90;
|
|
26
|
-
readonly 1: 49;
|
|
27
|
-
};
|
|
28
|
-
declare type Keys = keyof typeof keyMap;
|
|
29
|
-
declare type MappedKeys = `press${Keys}`;
|
|
30
|
-
declare type KeyboardAccumulatorType = Record<MappedKeys, () => void>;
|
|
31
|
-
declare const keyboard: KeyboardAccumulatorType;
|
|
32
|
-
declare type KeydownAccumulatorType = Record<MappedKeys, (wrapper: ReactWrapper<any>, options?: {
|
|
33
|
-
shiftKey: boolean;
|
|
34
|
-
}) => void>;
|
|
11
|
+
declare const keyboard: Record<string, () => void>;
|
|
35
12
|
declare const simulate: {
|
|
36
|
-
keydown:
|
|
13
|
+
keydown: Record<string, (target: ReactWrapper<any>, { shiftKey }?: {
|
|
14
|
+
shiftKey: boolean;
|
|
15
|
+
} | undefined) => void>;
|
|
37
16
|
};
|
|
38
17
|
declare const listFrom: (wrapper: ReactWrapper) => ReactWrapper<import("enzyme").HTMLAttributes, any, import("react").Component<{}, {}, any>>;
|
|
39
18
|
declare const childrenFrom: (node: ReactWrapper) => ReactWrapper<any, any, import("react").Component<{}, {}, any>>;
|
|
@@ -50,30 +50,16 @@ exports.makeArrayKeys = makeArrayKeys;
|
|
|
50
50
|
|
|
51
51
|
const dispatchKeyPress = code => {
|
|
52
52
|
const ev = new KeyboardEvent("keydown", {
|
|
53
|
-
|
|
53
|
+
key: code
|
|
54
54
|
});
|
|
55
55
|
document.dispatchEvent(ev);
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Enter: 13,
|
|
64
|
-
Tab: 9,
|
|
65
|
-
Space: 32,
|
|
66
|
-
Escape: 27,
|
|
67
|
-
End: 35,
|
|
68
|
-
Home: 36,
|
|
69
|
-
D: 68,
|
|
70
|
-
E: 69,
|
|
71
|
-
P: 80,
|
|
72
|
-
Z: 90,
|
|
73
|
-
1: 49
|
|
74
|
-
};
|
|
75
|
-
const keyboard = Object.keys(keyMap).reduce((acc, key) => {
|
|
76
|
-
acc[`press${key}`] = () => dispatchKeyPress(keyMap[key]);
|
|
58
|
+
const keys = ["ArrowUp", "ArrowDown", "ArrowRight", "ArrowLeft", "Enter", "Tab", " ", "Escape", "End", "Home", "D", "E", "P", "Z", "1"];
|
|
59
|
+
const keyboard = keys.reduce((acc, key) => {
|
|
60
|
+
const methodName = `press${key === " " ? "Space" : key}`;
|
|
61
|
+
|
|
62
|
+
acc[methodName] = () => dispatchKeyPress(key);
|
|
77
63
|
|
|
78
64
|
return acc;
|
|
79
65
|
}, {}); // Build an object of Enzyme simulate helpers
|
|
@@ -81,16 +67,17 @@ const keyboard = Object.keys(keyMap).reduce((acc, key) => {
|
|
|
81
67
|
// e.g. simulate.keydown.pressEscape(target)
|
|
82
68
|
|
|
83
69
|
exports.keyboard = keyboard;
|
|
84
|
-
const keydown =
|
|
85
|
-
|
|
70
|
+
const keydown = keys.reduce((acc, key) => {
|
|
71
|
+
const methodName = `press${key === " " ? "Space" : key}`;
|
|
72
|
+
|
|
73
|
+
acc[methodName] = (target, {
|
|
86
74
|
shiftKey
|
|
87
75
|
} = {
|
|
88
76
|
shiftKey: false
|
|
89
77
|
}) => {
|
|
90
78
|
target.simulate("keydown", {
|
|
91
79
|
shiftKey,
|
|
92
|
-
key
|
|
93
|
-
which: keyMap[key]
|
|
80
|
+
key
|
|
94
81
|
});
|
|
95
82
|
};
|
|
96
83
|
|
|
@@ -146,7 +133,7 @@ const assertCorrectTraversal = method => expect => ({
|
|
|
146
133
|
expect(arraysEqual(validIndexes, indexesThatWereSelected)).toBeTruthy();
|
|
147
134
|
};
|
|
148
135
|
|
|
149
|
-
const assertKeyboardTraversal = assertCorrectTraversal(() => keyboard.
|
|
136
|
+
const assertKeyboardTraversal = assertCorrectTraversal(() => keyboard.pressArrowDown)(expect);
|
|
150
137
|
exports.assertKeyboardTraversal = assertKeyboardTraversal;
|
|
151
138
|
const assertHoverTraversal = assertCorrectTraversal(wrapper => hoverList(wrapper))(expect);
|
|
152
139
|
exports.assertHoverTraversal = assertHoverTraversal;
|
|
@@ -92,8 +92,8 @@ const ActionPopoverMenu = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
92
92
|
e.preventDefault();
|
|
93
93
|
e.stopPropagation();
|
|
94
94
|
setFocusIndex(items.length - 1);
|
|
95
|
-
} else if (
|
|
96
|
-
//
|
|
95
|
+
} else if (e.key.length === 1) {
|
|
96
|
+
// any printable character: focus the next item on the list that starts with that character
|
|
97
97
|
// selection should wrap to the start of the list
|
|
98
98
|
e.stopPropagation();
|
|
99
99
|
let firstMatch;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface AnchorNavigationItemProps {
|
|
3
|
+
/** Reference to the section html element meant to be shown */
|
|
4
|
+
target?: React.RefObject<HTMLElement>;
|
|
5
|
+
/** href to be passed to the anchor element, can be linked with id passed to the scrollable section */
|
|
6
|
+
href?: string;
|
|
7
|
+
/** Indicates if component is selected */
|
|
8
|
+
isSelected?: boolean;
|
|
9
|
+
/** onClick handler */
|
|
10
|
+
onClick?: (ev: React.MouseEvent<HTMLAnchorElement>) => void;
|
|
11
|
+
/** OnKeyDown handler */
|
|
12
|
+
onKeyDown?: (ev: React.KeyboardEvent<HTMLAnchorElement>) => void;
|
|
13
|
+
/** tabIndex passed to the anchor element */
|
|
14
|
+
tabIndex?: number;
|
|
15
|
+
/** Children elements */
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
declare const AnchorNavigationItem: React.ForwardRefExoticComponent<AnchorNavigationItemProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
19
|
+
export default AnchorNavigationItem;
|
package/lib/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.component.js
CHANGED
|
@@ -13,7 +13,6 @@ var _anchorNavigationItem = _interopRequireDefault(require("./anchor-navigation-
|
|
|
13
13
|
|
|
14
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
15
|
|
|
16
|
-
/* eslint-disable react/no-unused-prop-types */
|
|
17
16
|
const AnchorNavigationItem = /*#__PURE__*/_react.default.forwardRef(({
|
|
18
17
|
children,
|
|
19
18
|
onKeyDown,
|
|
@@ -33,26 +32,20 @@ const AnchorNavigationItem = /*#__PURE__*/_react.default.forwardRef(({
|
|
|
33
32
|
}, children)));
|
|
34
33
|
|
|
35
34
|
AnchorNavigationItem.propTypes = {
|
|
36
|
-
children: _propTypes.default.node,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
/** Indicates if component is selected */
|
|
51
|
-
isSelected: _propTypes.default.bool,
|
|
52
|
-
|
|
53
|
-
/** Reference to the section html element meant to be shown */
|
|
54
|
-
target: _propTypes.default.shape({
|
|
55
|
-
current: _propTypes.default.instanceOf(Element)
|
|
35
|
+
"children": _propTypes.default.node,
|
|
36
|
+
"href": _propTypes.default.string,
|
|
37
|
+
"isSelected": _propTypes.default.bool,
|
|
38
|
+
"onClick": _propTypes.default.func,
|
|
39
|
+
"onKeyDown": _propTypes.default.func,
|
|
40
|
+
"tabIndex": _propTypes.default.number,
|
|
41
|
+
"target": _propTypes.default.shape({
|
|
42
|
+
"current": _propTypes.default.oneOfType([_propTypes.default.oneOf([null]), function (props, propName) {
|
|
43
|
+
if (props[propName] == null) {
|
|
44
|
+
return new Error("Prop '" + propName + "' is required but wasn't specified");
|
|
45
|
+
} else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) {
|
|
46
|
+
return new Error("Expected prop '" + propName + "' to be of type Element");
|
|
47
|
+
}
|
|
48
|
+
}]).isRequired
|
|
56
49
|
})
|
|
57
50
|
};
|
|
58
51
|
AnchorNavigationItem.displayName = "AnchorNavigationItem";
|
package/lib/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.style.js
CHANGED
|
@@ -5,16 +5,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
|
-
|
|
10
8
|
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
|
11
9
|
|
|
12
10
|
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
13
11
|
|
|
14
12
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
13
|
|
|
16
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
14
|
const StyledNavigationItem = _styledComponents.default.li`
|
|
19
15
|
width: 100%;
|
|
20
16
|
|
|
@@ -46,8 +42,5 @@ const StyledNavigationItem = _styledComponents.default.li`
|
|
|
46
42
|
`}
|
|
47
43
|
}
|
|
48
44
|
`;
|
|
49
|
-
StyledNavigationItem.propTypes = {
|
|
50
|
-
isSelected: _propTypes.default.bool
|
|
51
|
-
};
|
|
52
45
|
var _default = StyledNavigationItem;
|
|
53
46
|
exports.default = _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface AnchorNavigationProps {
|
|
3
|
+
/** Child elements */
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
/** The AnchorNavigationItems components to be rendered in the sticky navigation.
|
|
6
|
+
It is important to maintain proper structure.
|
|
7
|
+
List of AnchorNavigationItems has to be wrapped in React.Fragment */
|
|
8
|
+
stickyNavigation?: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
declare const AnchorNavigation: {
|
|
11
|
+
({ children, stickyNavigation, }: AnchorNavigationProps): JSX.Element;
|
|
12
|
+
displayName: string;
|
|
13
|
+
};
|
|
14
|
+
export default AnchorNavigation;
|
|
@@ -9,10 +9,12 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
9
9
|
|
|
10
10
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
11
|
|
|
12
|
-
var _throttle = _interopRequireDefault(require("lodash/throttle"));
|
|
13
|
-
|
|
14
12
|
var _reactIs = require("react-is");
|
|
15
13
|
|
|
14
|
+
var _invariant = _interopRequireDefault(require("invariant"));
|
|
15
|
+
|
|
16
|
+
var _throttle = _interopRequireDefault(require("lodash/throttle"));
|
|
17
|
+
|
|
16
18
|
var _events = _interopRequireDefault(require("../../__internal__/utils/helpers/events"));
|
|
17
19
|
|
|
18
20
|
var _anchorNavigation = require("./anchor-navigation.style");
|
|
@@ -32,45 +34,57 @@ const AnchorNavigation = ({
|
|
|
32
34
|
children,
|
|
33
35
|
stickyNavigation
|
|
34
36
|
}) => {
|
|
37
|
+
(0, _invariant.default)((0, _reactIs.isFragment)(stickyNavigation), "`stickyNavigation` prop in `AnchorNavigation` should be a React Fragment.");
|
|
38
|
+
const hasCorrectItemStructure = (0, _react.useMemo)(() => {
|
|
39
|
+
const incorrectChild = _react.default.Children.toArray(stickyNavigation.props.children).find(child => {
|
|
40
|
+
return ! /*#__PURE__*/_react.default.isValidElement(child) || child.type.displayName !== _anchorNavigationItem.default.displayName;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return !incorrectChild;
|
|
44
|
+
}, [stickyNavigation]);
|
|
45
|
+
(0, _invariant.default)(hasCorrectItemStructure, `\`stickyNavigation\` prop in \`AnchorNavigation\` should be a React Fragment that only contains children of type \`${_anchorNavigationItem.default.displayName}\``);
|
|
35
46
|
const [selectedIndex, setSelectedIndex] = (0, _react.useState)(0);
|
|
36
47
|
const sectionRefs = (0, _react.useRef)(_react.default.Children.map(stickyNavigation.props.children, child => child.props.target));
|
|
37
48
|
const anchorRefs = (0, _react.useRef)(Array.from({
|
|
38
49
|
length: _react.default.Children.count(stickyNavigation.props.children)
|
|
39
|
-
}, () => /*#__PURE__*/_react.
|
|
40
|
-
const contentRef = (0, _react.useRef)();
|
|
41
|
-
const navigationRef = (0, _react.useRef)();
|
|
50
|
+
}, () => /*#__PURE__*/(0, _react.createRef)()));
|
|
51
|
+
const contentRef = (0, _react.useRef)(null);
|
|
52
|
+
const navigationRef = (0, _react.useRef)(null);
|
|
42
53
|
const isUserScroll = (0, _react.useRef)(true);
|
|
43
54
|
const isUserScrollTimer = (0, _react.useRef)();
|
|
44
55
|
const setSelectedAnchorBasedOnScroll = (0, _react.useCallback)(() => {
|
|
45
|
-
|
|
56
|
+
// istanbul ignore if
|
|
57
|
+
// function is called only after component is rendered, so ref cannot hold a null value
|
|
58
|
+
if (navigationRef.current === null) return;
|
|
59
|
+
const offsetsWithIndexes = sectionRefs.current.map(({
|
|
46
60
|
current
|
|
47
|
-
}) => current.getBoundingClientRect().top);
|
|
61
|
+
}, index) => [index, current === null || current === void 0 ? void 0 : current.getBoundingClientRect().top]).filter(offsetWithIndex => offsetWithIndex[1] !== undefined);
|
|
48
62
|
const {
|
|
49
63
|
top: navTopOffset
|
|
50
64
|
} = navigationRef.current.getBoundingClientRect();
|
|
51
|
-
const indexOfSmallestNegativeTopOffset =
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
const indexOfSmallestNegativeTopOffset = offsetsWithIndexes.reduce((currentTopIndex, offsetWithIndex) => {
|
|
66
|
+
const [index, offset] = offsetWithIndex;
|
|
67
|
+
if (offset - SECTION_VISIBILITY_OFFSET > navTopOffset) return currentTopIndex;
|
|
68
|
+
return offset > offsetsWithIndexes[currentTopIndex][1] ? index : currentTopIndex;
|
|
69
|
+
}, offsetsWithIndexes[0][0]);
|
|
55
70
|
setSelectedIndex(indexOfSmallestNegativeTopOffset);
|
|
56
71
|
}, []);
|
|
57
|
-
const scrollHandler = (0, _react.
|
|
72
|
+
const scrollHandler = (0, _react.useMemo)(() => (0, _throttle.default)(() => {
|
|
58
73
|
if (isUserScroll.current) {
|
|
59
74
|
setSelectedAnchorBasedOnScroll();
|
|
60
75
|
} else {
|
|
61
|
-
window.clearTimeout(isUserScrollTimer.current);
|
|
76
|
+
if (isUserScrollTimer.current !== undefined) window.clearTimeout(isUserScrollTimer.current);
|
|
62
77
|
isUserScrollTimer.current = setTimeout(() => {
|
|
63
78
|
isUserScroll.current = true;
|
|
64
79
|
}, SCROLL_THROTTLE + 50);
|
|
65
80
|
}
|
|
66
|
-
}, SCROLL_THROTTLE), []);
|
|
81
|
+
}, SCROLL_THROTTLE), [setSelectedAnchorBasedOnScroll]);
|
|
67
82
|
(0, _react.useEffect)(() => {
|
|
68
83
|
window.addEventListener("scroll", scrollHandler, true);
|
|
69
84
|
return () => window.removeEventListener("scroll", scrollHandler, true);
|
|
70
85
|
}, [scrollHandler]);
|
|
71
86
|
|
|
72
87
|
const focusFirstFocusableChild = section => {
|
|
73
|
-
// eslint-disable-next-line max-len
|
|
74
88
|
const defaultFocusableSelectors = 'button, [href], input:not([type="hidden"]), select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
75
89
|
const firstFocusableElement = section.querySelector(defaultFocusableSelectors);
|
|
76
90
|
|
|
@@ -81,46 +95,45 @@ const AnchorNavigation = ({
|
|
|
81
95
|
}
|
|
82
96
|
};
|
|
83
97
|
|
|
84
|
-
const scrollToSection =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
block: "start",
|
|
88
|
-
inline: "nearest",
|
|
89
|
-
behavior: "smooth"
|
|
90
|
-
});
|
|
91
|
-
};
|
|
98
|
+
const scrollToSection = index => {
|
|
99
|
+
const sectionToScroll = sectionRefs.current[index].current; // istanbul ignore if
|
|
100
|
+
// function is called only after component is rendered, so ref cannot hold a null value
|
|
92
101
|
|
|
93
|
-
|
|
94
|
-
event.preventDefault();
|
|
95
|
-
const sectionToScroll = sectionRefs.current[index].current;
|
|
102
|
+
if (sectionToScroll === null) return;
|
|
96
103
|
focusFirstFocusableChild(sectionToScroll); // workaround due to preventScroll focus method option on firefox not working consistently
|
|
97
104
|
|
|
98
105
|
window.setTimeout(() => {
|
|
99
|
-
|
|
106
|
+
isUserScroll.current = false;
|
|
107
|
+
sectionToScroll.scrollIntoView({
|
|
108
|
+
block: "start",
|
|
109
|
+
inline: "nearest",
|
|
110
|
+
behavior: "smooth"
|
|
111
|
+
});
|
|
100
112
|
setSelectedIndex(index);
|
|
101
113
|
}, 10);
|
|
102
114
|
};
|
|
103
115
|
|
|
104
|
-
const focusNavItem =
|
|
105
|
-
|
|
106
|
-
let newIndex = index;
|
|
116
|
+
const focusNavItem = index => {
|
|
117
|
+
var _anchorRefs$current$c;
|
|
107
118
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
newIndex = 0;
|
|
112
|
-
}
|
|
119
|
+
const noOfRefs = anchorRefs.current.length;
|
|
120
|
+
(_anchorRefs$current$c = anchorRefs.current[(index % noOfRefs + noOfRefs) % noOfRefs].current) === null || _anchorRefs$current$c === void 0 ? void 0 : _anchorRefs$current$c.focus();
|
|
121
|
+
};
|
|
113
122
|
|
|
114
|
-
|
|
123
|
+
const handleClick = (event, index) => {
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
scrollToSection(index);
|
|
115
126
|
};
|
|
116
127
|
|
|
117
128
|
const handleKeyDown = (event, index) => {
|
|
129
|
+
event.preventDefault();
|
|
130
|
+
|
|
118
131
|
if (_events.default.isUpKey(event)) {
|
|
119
|
-
focusNavItem(
|
|
132
|
+
focusNavItem(index - 1);
|
|
120
133
|
} else if (_events.default.isDownKey(event)) {
|
|
121
|
-
focusNavItem(
|
|
134
|
+
focusNavItem(index + 1);
|
|
122
135
|
} else if (_events.default.isEnterKey(event) || _events.default.isSpaceKey(event)) {
|
|
123
|
-
|
|
136
|
+
scrollToSection(index);
|
|
124
137
|
}
|
|
125
138
|
};
|
|
126
139
|
|
|
@@ -133,45 +146,16 @@ const AnchorNavigation = ({
|
|
|
133
146
|
}, _react.default.Children.map(stickyNavigation.props.children, (child, index) => /*#__PURE__*/_react.default.cloneElement(child, {
|
|
134
147
|
isSelected: index === selectedIndex,
|
|
135
148
|
tabIndex: index === selectedIndex ? 0 : -1,
|
|
136
|
-
onClick:
|
|
137
|
-
onKeyDown:
|
|
149
|
+
onClick: event => handleClick(event, index),
|
|
150
|
+
onKeyDown: event => handleKeyDown(event, index),
|
|
138
151
|
ref: anchorRefs.current[index]
|
|
139
152
|
}))), /*#__PURE__*/_react.default.createElement(_anchorNavigation.StyledContent, null, children));
|
|
140
153
|
};
|
|
141
154
|
|
|
142
155
|
AnchorNavigation.propTypes = {
|
|
143
|
-
children: _propTypes.default.node,
|
|
144
|
-
|
|
145
|
-
/** The AnchorNavigationItems components to be rendered in the sticky navigation.
|
|
146
|
-
It is important to maintain proper structure.
|
|
147
|
-
List of AnchorNavigationItems has to be wrapped in React.Fragment */
|
|
148
|
-
stickyNavigation: (props, propName, componentName) => {
|
|
149
|
-
let error;
|
|
150
|
-
const prop = props[propName];
|
|
151
|
-
const errorsList = [];
|
|
152
|
-
|
|
153
|
-
if (!(0, _reactIs.isFragment)(prop)) {
|
|
154
|
-
errorsList.push(`Prop ${propName} container supplied to ${componentName} should be a React.Fragment.`);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
let isAnyChildIncorrect = false;
|
|
158
|
-
|
|
159
|
-
_react.default.Children.forEach(prop.props.children, child => {
|
|
160
|
-
if (_anchorNavigationItem.default.displayName !== child.type.displayName) {
|
|
161
|
-
isAnyChildIncorrect = true;
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
if (isAnyChildIncorrect) {
|
|
166
|
-
errorsList.push(`Prop ${propName} container supplied to ${componentName} only accepts children of type ${_anchorNavigationItem.default.displayName}.`);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (errorsList.length) {
|
|
170
|
-
error = new Error(errorsList.join(" "));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return error;
|
|
174
|
-
}
|
|
156
|
+
"children": _propTypes.default.node,
|
|
157
|
+
"stickyNavigation": _propTypes.default.node
|
|
175
158
|
};
|
|
159
|
+
AnchorNavigation.displayName = "AnchorNavigation";
|
|
176
160
|
var _default = AnchorNavigation;
|
|
177
161
|
exports.default = _default;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const StyledAnchorNavigation: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
2
|
+
declare const StyledNavigation: import("styled-components").StyledComponent<"ul", any, {}, never>;
|
|
3
|
+
declare const StyledContent: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
4
|
+
export { StyledAnchorNavigation, StyledNavigation, StyledContent };
|