@enact/limestone 1.10.0 → 1.10.2
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/.github/PULL_REQUEST_TEMPLATE.md +1 -0
- package/ActionGuide/ActionGuide.d.ts +1 -1
- package/ActionGuide/ActionGuide.module.css +7 -0
- package/Alert/Alert.d.ts +9 -0
- package/Alert/Alert.js +63 -21
- package/Alert/Alert.module.css +41 -9
- package/Alert/AlertImage.module.css +5 -1
- package/Alert/tests/Alert-specs.js +6 -2
- package/BodyText/BodyText.d.ts +1 -1
- package/BodyText/BodyText.js +14 -9
- package/BodyText/BodyText.module.css +22 -1
- package/Button/Button.d.ts +3 -3
- package/Button/Button.module.css +81 -63
- package/CHANGELOG.md +87 -0
- package/Card/Card.d.ts +81 -9
- package/Card/Card.js +324 -84
- package/Card/Card.module.css +200 -25
- package/Card/tests/Card-specs.js +100 -0
- package/Checkbox/Checkbox.d.ts +2 -2
- package/Checkbox/Checkbox.module.css +2 -5
- package/CheckboxItem/CheckboxItem.d.ts +8 -1
- package/CheckboxItem/CheckboxItem.js +39 -12
- package/CheckboxItem/CheckboxItem.module.css +228 -4
- package/Chips/Chip.module.css +5 -2
- package/ContextualMenuDecorator/ContextualMenuDecorator.d.ts +2 -2
- package/ContextualPopupDecorator/ContextualPopup.module.css +1 -1
- package/ContextualPopupDecorator/ContextualPopupDecorator.js +2 -4
- package/ContextualPopupDecorator/tests/ContextualPopupDecorator-specs.js +39 -2
- package/Dropdown/Dropdown.d.ts +2 -2
- package/Dropdown/Dropdown.module.css +7 -7
- package/FixedPopupPanels/FixedPopupPanels.d.ts +2 -2
- package/FlexiblePopupPanels/FlexiblePopupPanels.module.css +15 -3
- package/FlexiblePopupPanels/index.d.ts +2 -2
- package/FormCheckboxItem/FormCheckboxItem.d.ts +1 -1
- package/FormCheckboxItem/FormCheckboxItem.js +1 -0
- package/FormCheckboxItem/FormCheckboxItem.module.css +1 -1
- package/Heading/Heading.d.ts +2 -2
- package/Heading/Heading.module.css +16 -0
- package/Icon/Icon.d.ts +22 -1
- package/Icon/Icon.js +21 -0
- package/Icon/Icon.module.css +12 -0
- package/Icon/IconList.js +43 -1
- package/IconItem/IconItem.d.ts +2 -2
- package/IconItem/IconItem.module.css +27 -14
- package/Image/Image.d.ts +1 -1
- package/Image/Image.module.css +1 -1
- package/ImageItem/ImageItem.d.ts +2 -2
- package/ImageItem/ImageItem.js +3 -16
- package/ImageItem/ImageItem.module.css +122 -97
- package/ImageItem/tests/ImageItem-specs.js +6 -5
- package/Input/Input.module.css +33 -16
- package/Input/InputField.module.css +22 -4
- package/Input/index.d.ts +1 -1
- package/Input/tests/Input-specs.js +2 -2
- package/Input/tests/InputField-specs.js +1 -1
- package/Item/Item.d.ts +2 -2
- package/Item/Item.module.css +29 -16
- package/KeyGuide/KeyGuide.d.ts +2 -2
- package/KeyGuide/KeyGuide.module.css +10 -0
- package/MediaOverlay/MediaOverlay.d.ts +2 -2
- package/MediaOverlay/MediaOverlay.module.css +18 -9
- package/MediaPlayer/MediaControls.module.css +3 -0
- package/MediaPlayer/MediaSlider.module.css +1 -0
- package/MediaPlayer/Times.module.css +5 -1
- package/MediaPlayer/index.d.ts +2 -2
- package/PageViews/PageViews.module.css +6 -1
- package/Panels/Header.module.css +74 -56
- package/Panels/Panel.module.css +1 -1
- package/Panels/index.d.ts +1 -1
- package/Picker/Picker.d.ts +1 -1
- package/Popup/Popup.module.css +4 -1
- package/PopupTabLayout/PopupTabLayout.d.ts +6 -6
- package/PopupTabLayout/PopupTabLayout.module.css +24 -6
- package/ProgressBar/ProgressBar.d.ts +1 -1
- package/ProgressBar/ProgressBar.module.css +12 -12
- package/ProgressBar/ProgressBarTooltip.module.css +7 -7
- package/ProgressButton/ProgressButton.d.ts +2 -2
- package/QuickGuidePanels/QuickGuidePanels.module.css +1 -1
- package/RadioItem/RadioItem.d.ts +1 -1
- package/RadioItem/RadioItem.module.css +21 -18
- package/Scroller/EditableWrapper.js +2 -1
- package/Scroller/Scroller.d.ts +12 -0
- package/Scroller/Scroller.js +15 -0
- package/Scroller/Scroller.module.css +10 -0
- package/Scroller/tests/Scroller-specs.js +120 -2
- package/Scroller/useThemeScroller.js +25 -2
- package/Slider/Slider.d.ts +1 -1
- package/Slider/Slider.module.css +539 -303
- package/Spinner/Spinner.d.ts +1 -1
- package/Spinner/Spinner.module.css +2 -2
- package/Steps/Steps.d.ts +1 -1
- package/Steps/Steps.js +12 -6
- package/Steps/Steps.module.css +19 -2
- package/Switch/Switch.module.css +17 -6
- package/SwitchItem/SwitchItem.d.ts +1 -1
- package/TabLayout/RefocusDecorator.js +1 -1
- package/TabLayout/TabGroup.module.css +13 -7
- package/TabLayout/TabLayout.js +4 -0
- package/ThemeDecorator/ThemeDecorator.d.ts +1 -1
- package/ThemeDecorator/ThemeDecorator.module.css +22 -1
- package/TimePicker/TimePicker.module.css +3 -0
- package/TooltipDecorator/Tooltip.js +68 -7
- package/TooltipDecorator/Tooltip.module.css +44 -23
- package/TooltipDecorator/TooltipDecorator.d.ts +52 -0
- package/TooltipDecorator/TooltipDecorator.js +42 -0
- package/TooltipDecorator/TooltipLabel.js +67 -14
- package/TooltipDecorator/tests/TooltipDecorator-specs.js +46 -0
- package/TooltipDecorator/useTooltip.js +14 -2
- package/VideoPlayer/Feedback.module.css +3 -0
- package/VideoPlayer/FeedbackTooltip.module.css +7 -0
- package/VideoPlayer/MediaTitle.module.css +9 -1
- package/VirtualList/VirtualList.d.ts +24 -0
- package/VirtualList/VirtualList.js +30 -0
- package/VirtualList/tests/stickTo-specs.js +115 -0
- package/VirtualList/tests/useEvent-specs.js +39 -0
- package/VirtualList/useEvent.js +45 -10
- package/VirtualList/useThemeVirtualList.js +20 -2
- package/WizardPanels/WizardPanels.module.css +1 -1
- package/fonts/Limestone_Icons.ttf +0 -0
- package/internal/DateComponentPicker/DateComponentPicker.module.css +3 -3
- package/internal/DateTime/DateTime.module.css +3 -0
- package/internal/Picker/Picker.js +8 -10
- package/internal/Picker/Picker.module.css +92 -137
- package/package.json +14 -17
- package/styles/color-mixins.less +4 -60
- package/styles/colors-game.less +5 -5
- package/styles/colors.less +9 -10
- package/styles/mixins.less +0 -46
- package/styles/motion-mixins.less +16 -7
- package/styles/motions.less +2 -2
- package/styles/variables.less +186 -69
- package/useScroll/ScrollbarPlaceholder.js +8 -3
- package/useScroll/useScroll.js +3 -1
|
@@ -456,6 +456,21 @@ _VirtualList.propTypes = /** @lends limestone/VirtualList.VirtualList.prototype
|
|
|
456
456
|
* @public
|
|
457
457
|
*/
|
|
458
458
|
spotlightId: _propTypes["default"].string,
|
|
459
|
+
/**
|
|
460
|
+
* Anchors the focused item to a fixed "focus position" at the start edge while the list scrolls
|
|
461
|
+
* beneath it.
|
|
462
|
+
*
|
|
463
|
+
* When set to `'start'`, moving focus with 5-way keys keeps the focus indicator at a fixed slot
|
|
464
|
+
* at the start of the list (top for vertical, leading edge for horizontal) and scrolls so the
|
|
465
|
+
* newly focused item lands in that slot. At the end of the list, the list scrolls only to its
|
|
466
|
+
* last position so the focused item stays visible.
|
|
467
|
+
*
|
|
468
|
+
* This is ignored when `snapToCenter` is set.
|
|
469
|
+
*
|
|
470
|
+
* @type {('start')}
|
|
471
|
+
* @public
|
|
472
|
+
*/
|
|
473
|
+
stickTo: _propTypes["default"].oneOf(['start']),
|
|
459
474
|
/**
|
|
460
475
|
* Specifies how to show vertical scrollbar.
|
|
461
476
|
*
|
|
@@ -908,6 +923,21 @@ _VirtualGridList.propTypes = /** @lends limestone/VirtualList.VirtualGridList.pr
|
|
|
908
923
|
* @public
|
|
909
924
|
*/
|
|
910
925
|
spotlightId: _propTypes["default"].string,
|
|
926
|
+
/**
|
|
927
|
+
* Anchors the focused item to a fixed "focus position" at the start edge while the list scrolls
|
|
928
|
+
* beneath it.
|
|
929
|
+
*
|
|
930
|
+
* When set to `'start'`, moving focus with 5-way keys keeps the focus indicator at a fixed slot
|
|
931
|
+
* at the start of the list (top for vertical, leading edge for horizontal) and scrolls so the
|
|
932
|
+
* newly focused item lands in that slot. At the end of the list, the list scrolls only to its
|
|
933
|
+
* last position so the focused item stays visible.
|
|
934
|
+
*
|
|
935
|
+
* This is ignored when `snapToCenter` is set.
|
|
936
|
+
*
|
|
937
|
+
* @type {('start')}
|
|
938
|
+
* @public
|
|
939
|
+
*/
|
|
940
|
+
stickTo: _propTypes["default"].oneOf(['start']),
|
|
911
941
|
/**
|
|
912
942
|
* Specifies how to show vertical scrollbar.
|
|
913
943
|
*
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("@testing-library/jest-dom");
|
|
4
|
+
var _spotlight = _interopRequireDefault(require("@enact/spotlight"));
|
|
5
|
+
var _react = require("@testing-library/react");
|
|
6
|
+
var _Item = _interopRequireDefault(require("../../Item"));
|
|
7
|
+
var _VirtualList = _interopRequireDefault(require("../VirtualList"));
|
|
8
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
9
|
+
var _excluded = ["index"]; // These tests exercise the `stickTo="start"` scroll behavior added to `useThemeVirtualList`. They
|
|
10
|
+
// live in their own file because they depend on a clean Spotlight instance.
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
12
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
13
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
14
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
15
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
16
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
17
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
18
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
19
|
+
var focus = function focus(elm) {
|
|
20
|
+
return _react.fireEvent.focus(elm);
|
|
21
|
+
};
|
|
22
|
+
var keyDownUp = function keyDownUp(keyCode) {
|
|
23
|
+
return function (elm) {
|
|
24
|
+
_react.fireEvent.keyDown(elm, {
|
|
25
|
+
keyCode: keyCode
|
|
26
|
+
});
|
|
27
|
+
return _react.fireEvent.keyUp(elm, {
|
|
28
|
+
keyCode: keyCode
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
var pressDownKey = keyDownUp(40);
|
|
33
|
+
describe('VirtualList stickTo="start"', function () {
|
|
34
|
+
var clientSize, currentFocusIndex, dataSize, handlerOnFocus, items, itemSize, renderItem;
|
|
35
|
+
beforeEach(function () {
|
|
36
|
+
clientSize = {
|
|
37
|
+
clientWidth: 1280,
|
|
38
|
+
clientHeight: 720
|
|
39
|
+
};
|
|
40
|
+
currentFocusIndex = -1;
|
|
41
|
+
dataSize = 200;
|
|
42
|
+
items = [];
|
|
43
|
+
itemSize = 60;
|
|
44
|
+
handlerOnFocus = function handlerOnFocus(index) {
|
|
45
|
+
return function () {
|
|
46
|
+
currentFocusIndex = index;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
renderItem = function renderItem(_ref) {
|
|
50
|
+
var index = _ref.index,
|
|
51
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
52
|
+
// eslint-disable-line enact/display-name
|
|
53
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Item["default"], _objectSpread(_objectSpread({}, rest), {}, {
|
|
54
|
+
onFocus: handlerOnFocus(index),
|
|
55
|
+
children: items[index].name
|
|
56
|
+
}));
|
|
57
|
+
};
|
|
58
|
+
for (var i = 0; i < dataSize; i++) {
|
|
59
|
+
items.push({
|
|
60
|
+
name: 'Account ' + i
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
afterEach(function () {
|
|
65
|
+
clientSize = null;
|
|
66
|
+
dataSize = null;
|
|
67
|
+
handlerOnFocus = null;
|
|
68
|
+
items = null;
|
|
69
|
+
itemSize = null;
|
|
70
|
+
renderItem = null;
|
|
71
|
+
});
|
|
72
|
+
test('should scroll to anchor the focused item at the start slot on 5-way navigation', function () {
|
|
73
|
+
var spy = jest.fn(function () {});
|
|
74
|
+
var scrollToFn = global.Element.prototype.scrollTo;
|
|
75
|
+
global.Element.prototype.scrollTo = spy;
|
|
76
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualList["default"], {
|
|
77
|
+
clientSize: clientSize,
|
|
78
|
+
dataSize: dataSize,
|
|
79
|
+
itemRenderer: renderItem,
|
|
80
|
+
itemSize: itemSize,
|
|
81
|
+
stickTo: "start"
|
|
82
|
+
}));
|
|
83
|
+
var list = _react.screen.getByRole('list');
|
|
84
|
+
var item13 = list.children.item(13).children.item(0);
|
|
85
|
+
focus(item13);
|
|
86
|
+
expect(currentFocusIndex).toBe(13);
|
|
87
|
+
pressDownKey(item13);
|
|
88
|
+
expect(currentFocusIndex).toBe(14);
|
|
89
|
+
expect(spy).toHaveBeenCalled();
|
|
90
|
+
global.Element.prototype.scrollTo = scrollToFn;
|
|
91
|
+
});
|
|
92
|
+
test('should scroll a focused item to the start slot', function () {
|
|
93
|
+
var spy = jest.fn(function () {});
|
|
94
|
+
var scrollToFn = global.Element.prototype.scrollTo;
|
|
95
|
+
global.Element.prototype.scrollTo = spy;
|
|
96
|
+
var pointerSpy = jest.spyOn(_spotlight["default"], 'getPointerMode').mockReturnValue(false);
|
|
97
|
+
var currentSpy = jest.spyOn(_spotlight["default"], 'getCurrent');
|
|
98
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualList["default"], {
|
|
99
|
+
clientSize: clientSize,
|
|
100
|
+
dataSize: dataSize,
|
|
101
|
+
direction: "horizontal",
|
|
102
|
+
itemRenderer: renderItem,
|
|
103
|
+
itemSize: itemSize,
|
|
104
|
+
stickTo: "start"
|
|
105
|
+
}));
|
|
106
|
+
var list = _react.screen.getByRole('list');
|
|
107
|
+
var node = list.querySelector('[data-index="13"]');
|
|
108
|
+
currentSpy.mockReturnValue(node);
|
|
109
|
+
_react.fireEvent.focusIn(node);
|
|
110
|
+
expect(spy).toHaveBeenCalled();
|
|
111
|
+
currentSpy.mockRestore();
|
|
112
|
+
pointerSpy.mockRestore();
|
|
113
|
+
global.Element.prototype.scrollTo = scrollToFn;
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -27,6 +27,14 @@ var keyDownUp = function keyDownUp(keyCode) {
|
|
|
27
27
|
});
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
|
+
var keyDownRepeat = function keyDownRepeat(keyCode) {
|
|
31
|
+
return function (elm) {
|
|
32
|
+
return _react.fireEvent.keyDown(elm, {
|
|
33
|
+
keyCode: keyCode,
|
|
34
|
+
repeat: true
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
};
|
|
30
38
|
var pressLeftKey = keyDownUp(37);
|
|
31
39
|
var pressRightKey = keyDownUp(39);
|
|
32
40
|
var pressUpKey = keyDownUp(38);
|
|
@@ -148,6 +156,37 @@ describe('VirtualList useEvent', function () {
|
|
|
148
156
|
expect(spy).toHaveBeenCalled();
|
|
149
157
|
global.Element.prototype.scrollTo = scrollToFn;
|
|
150
158
|
});
|
|
159
|
+
test('should handle repeat keydown on first VirtualList entry without error', function () {
|
|
160
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualList["default"], {
|
|
161
|
+
clientSize: clientSize,
|
|
162
|
+
dataSize: dataSize,
|
|
163
|
+
itemRenderer: renderItem,
|
|
164
|
+
itemSize: itemSize
|
|
165
|
+
}));
|
|
166
|
+
var list = _react.screen.getByRole('list');
|
|
167
|
+
var item0 = list.children.item(0).children.item(0);
|
|
168
|
+
focus(item0);
|
|
169
|
+
expect(currentFocusIndex).toBe(0);
|
|
170
|
+
keyDownRepeat(40)(item0);
|
|
171
|
+
expect(currentFocusIndex).toBe(0);
|
|
172
|
+
});
|
|
173
|
+
test('should handle repeat keydown when data-index jumps unexpectedly without error', function () {
|
|
174
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_VirtualList["default"], {
|
|
175
|
+
clientSize: clientSize,
|
|
176
|
+
dataSize: dataSize,
|
|
177
|
+
itemRenderer: renderItem,
|
|
178
|
+
itemSize: itemSize
|
|
179
|
+
}));
|
|
180
|
+
var list = _react.screen.getByRole('list');
|
|
181
|
+
var item0 = list.children.item(0).children.item(0);
|
|
182
|
+
var item1 = list.children.item(1).children.item(0);
|
|
183
|
+
focus(item0);
|
|
184
|
+
pressDownKey(item0);
|
|
185
|
+
expect(currentFocusIndex).toBe(1);
|
|
186
|
+
item1.dataset.index = '20';
|
|
187
|
+
keyDownRepeat(40)(item1);
|
|
188
|
+
expect(currentFocusIndex).toBe(1);
|
|
189
|
+
});
|
|
151
190
|
test('should scroll by page-down key', function () {
|
|
152
191
|
var spy = jest.fn(function () {});
|
|
153
192
|
var scrollToFn = global.Element.prototype.scrollTo;
|
package/VirtualList/useEvent.js
CHANGED
|
@@ -28,13 +28,14 @@ var isDown = (0, _keymap.is)('down'),
|
|
|
28
28
|
// should return -1 if index is not a number or a negative value
|
|
29
29
|
return number >= 0 ? number : -1;
|
|
30
30
|
};
|
|
31
|
-
var prevKeyDownIndex = -1;
|
|
32
31
|
var useEventKey = exports.useEventKey = function useEventKey(props, instances, context) {
|
|
33
32
|
// Mutable value
|
|
34
33
|
|
|
35
34
|
var mutableRef = (0, _react.useRef)({
|
|
36
35
|
fn: null
|
|
37
36
|
});
|
|
37
|
+
var prevKeyDownIndexRef = (0, _react.useRef)(-1);
|
|
38
|
+
var hasProcessedKeyDownRef = (0, _react.useRef)(false);
|
|
38
39
|
|
|
39
40
|
// Functions
|
|
40
41
|
|
|
@@ -121,6 +122,7 @@ var useEventKey = exports.useEventKey = function useEventKey(props, instances, c
|
|
|
121
122
|
var handle5WayKeyUp = context.handle5WayKeyUp,
|
|
122
123
|
handleDirectionKeyDown = context.handleDirectionKeyDown,
|
|
123
124
|
handlePageUpDownKeyDown = context.handlePageUpDownKeyDown,
|
|
125
|
+
resetAccelerator = context.resetAccelerator,
|
|
124
126
|
spotlightAcceleratorProcessKey = context.spotlightAcceleratorProcessKey;
|
|
125
127
|
function handleKeyDown(ev) {
|
|
126
128
|
var keyCode = ev.keyCode,
|
|
@@ -163,15 +165,50 @@ var useEventKey = exports.useEventKey = function useEventKey(props, instances, c
|
|
|
163
165
|
isRightMovement = _getNextIndex.isRightMovement,
|
|
164
166
|
isWrapped = _getNextIndex.isWrapped,
|
|
165
167
|
nextIndex = _getNextIndex.nextIndex;
|
|
168
|
+
var _scrollContentHandle$2 = scrollContentHandle.current,
|
|
169
|
+
dimensionToExtent = _scrollContentHandle$2.dimensionToExtent,
|
|
170
|
+
isPrimaryDirectionVertical = _scrollContentHandle$2.isPrimaryDirectionVertical;
|
|
171
|
+
|
|
172
|
+
// VirtualList recycles DOM nodes during scroll. If a node gets reused for a different index
|
|
173
|
+
// while browser focus stays on it, target.dataset.index reflects the new (wrong) index.
|
|
174
|
+
// Detect this by checking if the index jumped unnaturally during key repeat.
|
|
175
|
+
var isForwardKey = isPrimaryDirectionVertical ? isDownKey : isRightMovement;
|
|
176
|
+
var isBackwardKey = isPrimaryDirectionVertical ? isUpKey : isLeftMovement;
|
|
177
|
+
var isOutdatedIndex = repeat && prevKeyDownIndexRef.current !== -1 && (isForwardKey && (prevKeyDownIndexRef.current > index || index > prevKeyDownIndexRef.current + dimensionToExtent) || isBackwardKey && (prevKeyDownIndexRef.current < index || index < prevKeyDownIndexRef.current - dimensionToExtent));
|
|
178
|
+
|
|
179
|
+
// Block the first repeat event when entering VirtualList from outside with acceleration.
|
|
180
|
+
// prevKeyDownIndexRef is -1 only on first entry; a repeat here means key was held before entering.
|
|
181
|
+
var isFirstEntryRepeat = repeat && !hasProcessedKeyDownRef.current;
|
|
182
|
+
if (isFirstEntryRepeat) {
|
|
183
|
+
ev.preventDefault();
|
|
184
|
+
ev.stopPropagation();
|
|
185
|
+
resetAccelerator();
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (isOutdatedIndex) {
|
|
189
|
+
ev.preventDefault();
|
|
190
|
+
ev.stopPropagation();
|
|
191
|
+
resetAccelerator();
|
|
192
|
+
var correctedNextIndex = isForwardKey ? prevKeyDownIndexRef.current + dimensionToExtent : prevKeyDownIndexRef.current - dimensionToExtent;
|
|
193
|
+
if (correctedNextIndex >= 0 && correctedNextIndex < props.dataSize) {
|
|
194
|
+
var currentItemNode = instances.itemRefs.current[prevKeyDownIndexRef.current % scrollContentHandle.current.state.numOfItems];
|
|
195
|
+
var correctedTarget = currentItemNode && parseInt(currentItemNode.dataset.index) === prevKeyDownIndexRef.current ? currentItemNode : target;
|
|
196
|
+
handleDirectionKeyDown(ev, 'acceleratedKeyDown', {
|
|
197
|
+
isWrapped: false,
|
|
198
|
+
keyCode: keyCode,
|
|
199
|
+
nextIndex: correctedNextIndex,
|
|
200
|
+
repeat: repeat,
|
|
201
|
+
target: correctedTarget
|
|
202
|
+
});
|
|
203
|
+
prevKeyDownIndexRef.current = correctedNextIndex;
|
|
204
|
+
}
|
|
205
|
+
// At list boundary: keep prevKeyDownIndexRef.current unchanged so next event stays recoverable
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
166
208
|
if (nextIndex >= 0) {
|
|
167
209
|
// if the candidate is another item
|
|
168
210
|
ev.preventDefault();
|
|
169
211
|
ev.stopPropagation();
|
|
170
|
-
if (repeat && prevKeyDownIndex !== -1 && (isDownKey && prevKeyDownIndex > index || isUpKey && prevKeyDownIndex < index)) {
|
|
171
|
-
// Ignore keyEvent from item with wrong data-index (Workaround for data-index bug)
|
|
172
|
-
// Sometimes keyDown event occurs before the data-index updated, it causes reverse focus change
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
212
|
if (props.scrollContainerHandle && props.scrollContainerHandle.current) {
|
|
176
213
|
props.scrollContainerHandle.current.lastInputType = 'arrowKey';
|
|
177
214
|
}
|
|
@@ -188,9 +225,6 @@ var useEventKey = exports.useEventKey = function useEventKey(props, instances, c
|
|
|
188
225
|
focusableScrollbar = props.focusableScrollbar,
|
|
189
226
|
isHorizontalScrollbarVisible = props.isHorizontalScrollbarVisible,
|
|
190
227
|
isVerticalScrollbarVisible = props.isVerticalScrollbarVisible;
|
|
191
|
-
var _scrollContentHandle$2 = scrollContentHandle.current,
|
|
192
|
-
dimensionToExtent = _scrollContentHandle$2.dimensionToExtent,
|
|
193
|
-
isPrimaryDirectionVertical = _scrollContentHandle$2.isPrimaryDirectionVertical;
|
|
194
228
|
var column = index % dimensionToExtent;
|
|
195
229
|
var row = (index - column) % dataSize / dimensionToExtent;
|
|
196
230
|
var directions = {};
|
|
@@ -236,7 +270,8 @@ var useEventKey = exports.useEventKey = function useEventKey(props, instances, c
|
|
|
236
270
|
}
|
|
237
271
|
}
|
|
238
272
|
}
|
|
239
|
-
|
|
273
|
+
prevKeyDownIndexRef.current = index;
|
|
274
|
+
hasProcessedKeyDownRef.current = true;
|
|
240
275
|
if (isLeaving) {
|
|
241
276
|
handleDirectionKeyDown(ev, 'keyLeave');
|
|
242
277
|
}
|
|
@@ -99,6 +99,9 @@ var useSpottable = function useSpottable(props, instances) {
|
|
|
99
99
|
handle5WayKeyUp: function handle5WayKeyUp() {
|
|
100
100
|
SpotlightAccelerator.reset();
|
|
101
101
|
},
|
|
102
|
+
resetAccelerator: function resetAccelerator() {
|
|
103
|
+
SpotlightAccelerator.reset();
|
|
104
|
+
},
|
|
102
105
|
spotlightAcceleratorProcessKey: function spotlightAcceleratorProcessKey(ev) {
|
|
103
106
|
return SpotlightAccelerator.processKey(ev, nop);
|
|
104
107
|
}
|
|
@@ -192,6 +195,10 @@ var useSpottable = function useSpottable(props, instances) {
|
|
|
192
195
|
var index = getNumberValue(target.dataset.index);
|
|
193
196
|
var direction = (0, _spotlight.getDirection)(keyCode);
|
|
194
197
|
var allowAffordance = !(noAffordance || orientation === 'horizontal');
|
|
198
|
+
// When anchoring focus to the start slot, always scroll the newly focused item to that slot
|
|
199
|
+
// rather than leaving it in place when it happens to be already visible. `snapToCenter` is a
|
|
200
|
+
// more specific mode and keeps precedence.
|
|
201
|
+
var stickToStart = props.stickTo === 'start' && !snapToCenter;
|
|
195
202
|
var shouldMove = snapToCenter ? nextIndex > 0 && nextIndex < dataSize - 1 && index > 0 : nextIndex >= 0 && index >= 0;
|
|
196
203
|
mutableRef.current.isScrolledBy5way = false;
|
|
197
204
|
mutableRef.current.isScrolledByJump = false;
|
|
@@ -203,7 +210,7 @@ var useSpottable = function useSpottable(props, instances) {
|
|
|
203
210
|
startBoundary = scrollMode === 'native' ? scrollPosition : scrollPositionTarget,
|
|
204
211
|
endBoundary = startBoundary + clientSize - (!allowAffordance ? 0 : _resolution["default"].scale(_useScroll.affordanceSize));
|
|
205
212
|
mutableRef.current.lastFocusedIndex = nextIndex;
|
|
206
|
-
if (start >= startBoundary && end <= endBoundary) {
|
|
213
|
+
if (!stickToStart && start >= startBoundary && end <= endBoundary) {
|
|
207
214
|
// The next item could be still out of viewport. So we need to prevent scrolling into view with `isScrolledBy5way` flag.
|
|
208
215
|
mutableRef.current.isScrolledBy5way = true;
|
|
209
216
|
focusByIndex(nextIndex, direction);
|
|
@@ -213,6 +220,9 @@ var useSpottable = function useSpottable(props, instances) {
|
|
|
213
220
|
} else if (!snapToCenter || !mutableRef.current.isScrollingBySnapToCenter) {
|
|
214
221
|
var itemNode = getItemNode(nextIndex);
|
|
215
222
|
var stickTo = Math.abs(endBoundary - end) < Math.abs(startBoundary - start) ? 'end' : 'start';
|
|
223
|
+
if (stickToStart) {
|
|
224
|
+
stickTo = 'start';
|
|
225
|
+
}
|
|
216
226
|
stickTo = snapToCenter ? 'center' : stickTo;
|
|
217
227
|
mutableRef.current.isScrolledBy5way = true;
|
|
218
228
|
mutableRef.current.isWrappedBy5way = isWrapped;
|
|
@@ -286,6 +296,7 @@ var useSpottable = function useSpottable(props, instances) {
|
|
|
286
296
|
var offsetToClientEnd = Math.max(0, primary.clientSize - (snapToCenter ? primary.gridSize : primary.itemSize) - (!allowAffordance ? 0 : _resolution["default"].scale(_useScroll.affordanceSize)));
|
|
287
297
|
var focusedIndex = getNumberValue(item.getAttribute(_useScroll.dataIndexAttribute));
|
|
288
298
|
var offsetToCenter = snapToCenter ? primary.clientSize / 2 - primary.gridSize / 2 : 0;
|
|
299
|
+
var stickToStart = props.stickTo === 'start' && !snapToCenter;
|
|
289
300
|
if (focusedIndex >= 0) {
|
|
290
301
|
var gridPosition = scrollContentHandle.current.getGridPosition(focusedIndex);
|
|
291
302
|
if (numOfItems > 0 && focusedIndex % numOfItems !== mutableRef.current.lastFocusedIndex % numOfItems) {
|
|
@@ -296,7 +307,13 @@ var useSpottable = function useSpottable(props, instances) {
|
|
|
296
307
|
}
|
|
297
308
|
mutableRef.current.lastFocusedIndex = focusedIndex;
|
|
298
309
|
if (primary.clientSize >= primary.itemSize) {
|
|
299
|
-
if (
|
|
310
|
+
if (stickToStart) {
|
|
311
|
+
// anchor to the start slot
|
|
312
|
+
// Clamp to the scroll bounds so that at the end of the list, the list stops at its
|
|
313
|
+
// last position while keeping the focused item visible.
|
|
314
|
+
var maxPos = scrollContentHandle.current.isPrimaryDirectionVertical ? scrollContentHandle.current.scrollBounds.maxTop : scrollContentHandle.current.scrollBounds.maxLeft;
|
|
315
|
+
gridPosition.primaryPosition = Math.max(0, Math.min(gridPosition.primaryPosition, maxPos));
|
|
316
|
+
} else if (gridPosition.primaryPosition > scrollPosition + offsetToClientEnd) {
|
|
300
317
|
// forward over
|
|
301
318
|
gridPosition.primaryPosition -= pageScroll ? 0 : offsetToClientEnd - offsetToCenter;
|
|
302
319
|
} else if (gridPosition.primaryPosition >= scrollPosition) {
|
|
@@ -431,6 +448,7 @@ var useThemeVirtualList = exports.useThemeVirtualList = function useThemeVirtual
|
|
|
431
448
|
delete rest.scrollContentHandle;
|
|
432
449
|
delete rest.snapToCenter;
|
|
433
450
|
delete rest.spotlightId;
|
|
451
|
+
delete rest.stickTo;
|
|
434
452
|
delete rest.wrap;
|
|
435
453
|
return _objectSpread(_objectSpread({}, rest), {}, {
|
|
436
454
|
containerProps: {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
margin-top: calc(var(--primitive-spacing-84) * -1);
|
|
8
8
|
}
|
|
9
9
|
.wizardPanels .content {
|
|
10
|
-
margin: var(--primitive-spacing-60)
|
|
10
|
+
margin: var(--primitive-spacing-60) calc(324px - calc(132px - var(--primitive-spacing-36)));
|
|
11
11
|
}
|
|
12
12
|
.wizardPanels .footer {
|
|
13
13
|
text-align: center;
|
|
Binary file
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
vertical-align: inherit;
|
|
6
6
|
}
|
|
7
7
|
.dateComponentPicker .label {
|
|
8
|
+
text-align: center;
|
|
9
|
+
white-space: nowrap;
|
|
8
10
|
font-weight: var(--primitive-font-weight-regular);
|
|
9
11
|
font-size: var(--primitive-font-size-60);
|
|
10
12
|
font-style: normal;
|
|
11
13
|
font-family: "Limestone";
|
|
12
|
-
line-height: 1.
|
|
13
|
-
text-align: center;
|
|
14
|
+
line-height: 1.34em;
|
|
14
15
|
padding: 0.75rem 1rem;
|
|
15
|
-
white-space: nowrap;
|
|
16
16
|
}
|
|
17
17
|
:global(.enact-locale-non-latin) .dateComponentPicker .label {
|
|
18
18
|
font-family: "Limestone";
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
.dateTime .pickers > *:nth-last-child(2) {
|
|
20
20
|
margin-inline-end: 0;
|
|
21
21
|
}
|
|
22
|
+
.dateTime:global(.largeText) .heading {
|
|
23
|
+
font-size: var(--primitive-font-size-80);
|
|
24
|
+
}
|
|
22
25
|
.dateTime:global(.neutral) .heading {
|
|
23
26
|
color: var(--semantic-color-on-background-main);
|
|
24
27
|
}
|
|
@@ -11,7 +11,7 @@ Object.defineProperty(exports, "PickerItem", {
|
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
13
|
exports["default"] = void 0;
|
|
14
|
-
var
|
|
14
|
+
var _classnames2 = _interopRequireDefault(require("classnames"));
|
|
15
15
|
var _handle = require("@enact/core/handle");
|
|
16
16
|
var _propTypes = _interopRequireDefault(require("@enact/core/internal/prop-types"));
|
|
17
17
|
var _keymap = require("@enact/core/keymap");
|
|
@@ -27,6 +27,7 @@ var _spotlight = _interopRequireWildcard(require("@enact/spotlight"));
|
|
|
27
27
|
var _propTypes2 = _interopRequireDefault(require("prop-types"));
|
|
28
28
|
var _react = require("react");
|
|
29
29
|
var _Skinnable = _interopRequireDefault(require("../../Skinnable"));
|
|
30
|
+
var _Steps = _interopRequireDefault(require("../../Steps"));
|
|
30
31
|
var _$L = _interopRequireDefault(require("../$L"));
|
|
31
32
|
var _validators = require("../validators");
|
|
32
33
|
var _util2 = require("../util");
|
|
@@ -418,7 +419,7 @@ var _PickerBase = function PickerBase(props) {
|
|
|
418
419
|
}, [hasReachedBound, orientation, props, step]);
|
|
419
420
|
var determineClasses = (0, _react.useCallback)(function (cssProps, decrementerDisabledProp, incrementerDisabledProp) {
|
|
420
421
|
var classNameVariable = props.className;
|
|
421
|
-
return (0,
|
|
422
|
+
return (0, _classnames2["default"])(cssProps.picker, cssProps[changedBy], cssProps[orientation], cssProps[width], _defineProperty(_defineProperty(_defineProperty({}, cssProps.joined, joined), cssProps.decrementing, !decrementerDisabledProp && pressed === -1), cssProps.incrementing, !incrementerDisabledProp && pressed === 1), classNameVariable);
|
|
422
423
|
}, [changedBy, joined, orientation, pressed, props, width]);
|
|
423
424
|
var calcValueText = (0, _react.useCallback)(function () {
|
|
424
425
|
var _props$accessibilityH = props.accessibilityHint,
|
|
@@ -580,14 +581,11 @@ var _PickerBase = function PickerBase(props) {
|
|
|
580
581
|
noAnimation: noAnimation,
|
|
581
582
|
reverseTransition: reverseTransition.current,
|
|
582
583
|
children: children
|
|
583
|
-
}), showIndicators && /*#__PURE__*/(0, _jsxRuntime.jsx)("
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
className: (0, _classnames3["default"])(css.indicator, _defineProperty({}, css.active, index === indicator))
|
|
589
|
-
}, "indicator".concat(indicator));
|
|
590
|
-
})
|
|
584
|
+
}), showIndicators && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Steps["default"], _objectSpread(_objectSpread({}, voiceProps), {}, {
|
|
585
|
+
css: css,
|
|
586
|
+
highlightCurrentOnly: true,
|
|
587
|
+
current: index + 1,
|
|
588
|
+
total: children.length
|
|
591
589
|
}))]
|
|
592
590
|
}), isHorizontalJoinedEnter ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({}, voiceProps), {}, {
|
|
593
591
|
align: joined ? 'stretch' : null,
|