@enact/limestone 1.3.0 → 1.9.3

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.
Files changed (163) hide show
  1. package/.github/workflows/ci-branch.yml +21 -0
  2. package/.github/workflows/ci-pull-request.yml +16 -0
  3. package/.github/workflows/ci-reusable.yml +73 -0
  4. package/ActionGuide/ActionGuide.d.ts +5 -4
  5. package/ActionGuide/ActionGuide.module.css +1 -1
  6. package/Alert/Alert.d.ts +4 -2
  7. package/Alert/Alert.js +4 -1
  8. package/Alert/Alert.module.css +36 -0
  9. package/BodyText/BodyText.d.ts +5 -4
  10. package/BodyText/BodyText.module.css +7 -7
  11. package/Button/Button.d.ts +17 -12
  12. package/Button/Button.js +1 -1
  13. package/Button/Button.module.css +195 -268
  14. package/CHANGELOG.md +220 -0
  15. package/Card/Card.d.ts +36 -8
  16. package/Card/Card.js +157 -20
  17. package/Card/Card.module.css +277 -58
  18. package/Card/tests/Card-specs.js +30 -0
  19. package/Checkbox/Checkbox.d.ts +8 -7
  20. package/Checkbox/Checkbox.js +3 -1
  21. package/Checkbox/Checkbox.module.css +213 -120
  22. package/Checkbox/tests/Checkbox-specs.js +1 -1
  23. package/CheckboxItem/CheckboxItem.d.ts +22 -7
  24. package/CheckboxItem/CheckboxItem.js +69 -4
  25. package/Chips/Chip.js +60 -7
  26. package/Chips/Chip.module.css +3 -3
  27. package/Chips/Chips.js +26 -12
  28. package/Chips/Chips.module.css +1 -1
  29. package/Chips/tests/Chip-specs.js +19 -9
  30. package/Chips/tests/Chips-specs.js +19 -19
  31. package/ContextualMenuDecorator/ContextualMenuDecorator.d.ts +4 -5
  32. package/ContextualPopupDecorator/ContextualPopup.module.css +34 -34
  33. package/ContextualPopupDecorator/ContextualPopupDecorator.js +557 -549
  34. package/DatePicker/DatePicker.d.ts +4 -5
  35. package/DayPicker/DayPicker.d.ts +8 -7
  36. package/Dropdown/Dropdown.d.ts +11 -13
  37. package/Dropdown/Dropdown.module.css +9 -9
  38. package/Dropdown/DropdownList.js +16 -11
  39. package/FixedPopupPanels/FixedPopupPanels.d.ts +4 -2
  40. package/FixedPopupPanels/FixedPopupPanels.module.css +18 -18
  41. package/FlexiblePopupPanels/FlexiblePopupPanels.module.css +23 -23
  42. package/FormCheckboxItem/FormCheckboxItem.d.ts +5 -4
  43. package/Heading/Heading.d.ts +8 -7
  44. package/Heading/Heading.module.css +5 -5
  45. package/Icon/Icon.d.ts +14 -4
  46. package/Icon/Icon.js +48 -2
  47. package/Icon/Icon.module.css +1 -1
  48. package/Icon/IconList.js +25 -1
  49. package/IconItem/IconItem.d.ts +13 -12
  50. package/IconItem/IconItem.js +15 -0
  51. package/IconItem/IconItem.module.css +107 -1
  52. package/Image/Image.d.ts +5 -4
  53. package/ImageItem/ImageItem.d.ts +11 -10
  54. package/ImageItem/ImageItem.js +37 -31
  55. package/ImageItem/ImageItem.module.css +30 -30
  56. package/ImageItem/tests/ImageItem-specs.js +3 -10
  57. package/Input/Input.js +9 -2
  58. package/Input/Input.module.css +37 -8
  59. package/Input/InputField.js +5 -1
  60. package/Input/InputField.module.css +17 -2
  61. package/Input/InputFieldSpotlightDecorator.js +213 -229
  62. package/Input/index.d.ts +15 -18
  63. package/Input/tests/InputField-specs.js +21 -0
  64. package/Item/Item.d.ts +16 -9
  65. package/Item/Item.js +20 -2
  66. package/Item/Item.module.css +1 -1
  67. package/KeyGuide/KeyGuide.d.ts +8 -7
  68. package/KeyGuide/KeyGuide.module.css +25 -1
  69. package/Marquee/Marquee.d.ts +2 -4
  70. package/MediaOverlay/MediaOverlay.d.ts +12 -11
  71. package/MediaOverlay/MediaOverlay.js +43 -21
  72. package/MediaOverlay/MediaOverlay.module.css +114 -15
  73. package/MediaPlayer/MediaControls.js +195 -13
  74. package/MediaPlayer/MediaControls.module.css +3 -2
  75. package/MediaPlayer/MediaSlider.module.css +7 -20
  76. package/MediaPlayer/index.d.ts +59 -7
  77. package/PageViews/PageViews.js +165 -80
  78. package/PageViews/PageViewsRouter.js +9 -0
  79. package/PageViews/tests/PageViews-specs.js +84 -0
  80. package/Panels/Header.js +48 -30
  81. package/Panels/Header.module.css +83 -31
  82. package/Panels/Panel.module.css +1 -1
  83. package/Panels/index.d.ts +7 -8
  84. package/Picker/Picker.d.ts +4 -5
  85. package/Picker/Picker.module.css +2 -2
  86. package/Popup/Popup.js +242 -240
  87. package/Popup/Popup.module.css +24 -24
  88. package/PopupTabLayout/PopupTabLayout.d.ts +5 -7
  89. package/PopupTabLayout/PopupTabLayout.js +15 -9
  90. package/PopupTabLayout/PopupTabLayout.module.css +53 -16
  91. package/PopupTabLayout/PopupTabLayoutStateContext.js +8 -0
  92. package/ProgressBar/ProgressBar.d.ts +5 -4
  93. package/ProgressBar/ProgressBarTooltip.module.css +12 -12
  94. package/ProgressButton/ProgressButton.d.ts +4 -5
  95. package/QuickGuidePanels/QuickGuidePanels.module.css +2 -2
  96. package/RadioItem/RadioItem.d.ts +18 -5
  97. package/RadioItem/RadioItem.js +67 -2
  98. package/RadioItem/RadioItem.module.css +36 -36
  99. package/RangePicker/RangePicker.module.css +2 -2
  100. package/Scroller/EditableWrapper.js +11 -4
  101. package/Scroller/Scroller.d.ts +20 -16
  102. package/Scroller/Scroller.js +9 -3
  103. package/Scroller/Scroller.module.css +4 -4
  104. package/Slider/Slider.d.ts +16 -14
  105. package/Slider/Slider.js +37 -4
  106. package/Slider/Slider.module.css +314 -91
  107. package/Slider/tests/Slider-specs.js +2 -1
  108. package/Spinner/Spinner.d.ts +5 -4
  109. package/Spinner/Spinner.module.css +9 -9
  110. package/Steps/Steps.d.ts +5 -4
  111. package/Steps/Steps.js +9 -5
  112. package/Switch/Switch.d.ts +8 -7
  113. package/Switch/Switch.module.css +100 -13
  114. package/SwitchItem/SwitchItem.d.ts +9 -6
  115. package/TabLayout/RefocusDecorator.js +15 -9
  116. package/TabLayout/TabGroup.js +3 -2
  117. package/TabLayout/TabGroup.module.css +2 -2
  118. package/TabLayout/TabLayout.d.ts +6 -0
  119. package/TabLayout/TabLayout.js +11 -1
  120. package/TabLayout/TabLayout.module.css +18 -0
  121. package/TabLayout/tests/TabLayout-specs.js +52 -0
  122. package/ThemeDecorator/ThemeDecorator.d.ts +9 -10
  123. package/ThemeDecorator/fontGenerator.js +1 -1
  124. package/ThemeDecorator/screenTypes.json +1 -0
  125. package/TimePicker/TimePicker.module.css +1 -1
  126. package/TooltipDecorator/Tooltip.module.css +1 -2
  127. package/TooltipDecorator/tests/util-specs.js +12 -0
  128. package/TooltipDecorator/useTooltip.js +1 -1
  129. package/TooltipDecorator/util.js +18 -11
  130. package/VideoPlayer/Feedback.js +3 -0
  131. package/VideoPlayer/Feedback.module.css +5 -9
  132. package/VideoPlayer/FeedbackIcons.js +1 -1
  133. package/VideoPlayer/FeedbackTooltip.module.css +55 -11
  134. package/VideoPlayer/VideoPlayer.d.ts +44 -18
  135. package/VideoPlayer/VideoPlayer.js +128 -23
  136. package/VideoPlayer/VideoPlayer.module.css +28 -11
  137. package/VirtualList/VirtualList.d.ts +9 -2
  138. package/VirtualList/VirtualList.js +31 -6
  139. package/VirtualList/tests/VirtualGridList-translate-specs.js +3 -0
  140. package/VirtualList/tests/VirtualList-specs.js +28 -1
  141. package/VirtualList/tests/VirtualList-translate-specs.js +4 -1
  142. package/WizardPanels/WizardPanels.module.css +2 -2
  143. package/WizardPanels/index.d.ts +4 -2
  144. package/fonts/Limestone_Icons.ttf +0 -0
  145. package/internal/$L/$L.js +3 -3
  146. package/internal/DateComponentPicker/DateComponentPicker.module.css +2 -2
  147. package/internal/DateTime/DateTime.module.css +1 -0
  148. package/internal/Panels/PanelsRouter.js +16 -5
  149. package/internal/Picker/Picker.module.css +2 -2
  150. package/internal/SharedStateDecorator/SharedStateDecorator.js +76 -99
  151. package/internal/validators/validators.js +21 -2
  152. package/package.json +14 -14
  153. package/styles/colors-highcontrast.less +9 -1
  154. package/styles/colors.less +11 -7
  155. package/styles/motion-mixins.less +66 -0
  156. package/styles/motions.less +78 -0
  157. package/styles/variables.less +176 -150
  158. package/useScroll/HoverToScroll.js +8 -5
  159. package/useScroll/ScrollbarTrack.module.css +8 -8
  160. package/useScroll/useEvent.js +7 -1
  161. package/useScroll/useScroll.js +2 -0
  162. package/useScroll/useScroll.module.css +6 -6
  163. package/.travis.yml +0 -40
@@ -18,18 +18,9 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default":
18
18
  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; }
19
19
  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; }
20
20
  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; }
21
- function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
22
- function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
23
- function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
24
21
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
25
22
  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); }
26
- function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
27
- function _possibleConstructorReturn(t, e) { if (e && ("object" == typeof e || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
28
- function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
29
- function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
30
- function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
31
- function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
32
- function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
23
+ function _objectDestructuringEmpty(t) { if (null == t) throw new TypeError("Cannot destructure " + t); }
33
24
  var isBubbling = function isBubbling(ev) {
34
25
  return ev.currentTarget !== ev.target;
35
26
  };
@@ -43,7 +34,6 @@ var isSelectionAtLocation = function isSelectionAtLocation(target, location) {
43
34
  return true;
44
35
  }
45
36
  };
46
- var handleKeyDown = (0, _handle.handle)((0, _handle.forwardWithPrevent)('onKeyDown'), (0, _handle.call)('onKeyDown'));
47
37
 
48
38
  /**
49
39
  * Default config for {@link limestone/Input.InputSpotlightDecorator|InputSpotlightDecorator}
@@ -72,7 +62,6 @@ var defaultConfig = {
72
62
  * @private
73
63
  */
74
64
  var InputSpotlightDecorator = exports.InputSpotlightDecorator = (0, _hoc["default"])(defaultConfig, function (config, Wrapped) {
75
- var _Class;
76
65
  var noLockPointer = config.noLockPointer;
77
66
  var Component = (0, _Spottable["default"])({
78
67
  emulateMouse: false
@@ -80,245 +69,239 @@ var InputSpotlightDecorator = exports.InputSpotlightDecorator = (0, _hoc["defaul
80
69
  var forwardBlur = (0, _handle.forward)('onBlur');
81
70
  var forwardMouseDown = (0, _handle.forward)('onMouseDown');
82
71
  var forwardFocus = (0, _handle.forward)('onFocus');
72
+ var forwardKeyDown = (0, _handle.forwardWithPrevent)('onKeyDown');
83
73
  var forwardKeyUp = (0, _handle.forward)('onKeyUp');
84
- return _Class = /*#__PURE__*/function (_ReactComponent) {
85
- function _Class(props) {
86
- var _this;
87
- _classCallCheck(this, _Class);
88
- _this = _callSuper(this, _Class, [props]);
89
- _this.updateFocus = function () {
90
- // focus node if `InputSpotlightDecorator` is pausing Spotlight or if Spotlight is paused
91
- if (_this.node && _spotlight.Spotlight.getCurrent() !== _this.node && (_this.paused.isPaused() || !_spotlight.Spotlight.isPaused())) {
92
- if (_this.fromMouse) {
93
- _this.node.focus({
94
- preventScroll: true
95
- });
96
- } else {
97
- _this.node.focus();
98
- }
99
- }
100
- var focusChanged = _this.focused !== _this.prevStatus.focused;
101
- if (focusChanged) {
102
- if (_this.focused === 'input') {
103
- (0, _handle.forwardCustom)('onActivate')(null, _this.props);
104
- if (!noLockPointer) {
105
- (0, _pointer.lockPointer)(_this.node);
106
- }
107
- _this.paused.pause();
108
- } else if (_this.prevStatus.focused === 'input') {
109
- (0, _handle.forwardCustom)('onDeactivate')(null, _this.props);
110
- if (!noLockPointer) {
111
- (0, _pointer.releasePointer)(_this.prevStatus.node);
112
- }
113
- _this.paused.resume();
114
- }
115
- }
116
- _this.prevStatus.focused = _this.focused;
117
- _this.prevStatus.node = _this.node;
118
- };
119
- _this.focus = function (focused, node, fromMouse) {
120
- _this.focused = focused;
121
- _this.node = node;
122
- _this.fromMouse = fromMouse;
123
- _this.updateFocus();
124
- };
125
- _this.blur = function () {
126
- if (_this.focused || _this.node) {
127
- _this.focused = null;
128
- _this.node = null;
129
- _this.updateFocus();
74
+
75
+ // eslint-disable-next-line no-shadow
76
+ var InputSpotlightDecorator = function InputSpotlightDecorator(_ref) {
77
+ var props = Object.assign({}, (_objectDestructuringEmpty(_ref), _ref));
78
+ var downTarget = (0, _react.useRef)(null);
79
+ var focused = (0, _react.useRef)(null);
80
+ var node = (0, _react.useRef)(null);
81
+ var fromMouse = (0, _react.useRef)(false);
82
+ var prevStatus = (0, _react.useRef)({
83
+ focused: null,
84
+ node: null
85
+ });
86
+ var paused = (0, _react.useMemo)(function () {
87
+ return new _Pause["default"]('InputSpotlightDecorator');
88
+ }, []);
89
+ var setDownTarget = (0, _react.useCallback)(function (ev) {
90
+ var repeat = ev.repeat,
91
+ target = ev.target;
92
+ if (!repeat) {
93
+ downTarget.current = target;
94
+ }
95
+ }, []);
96
+ var updateFocus = (0, _react.useCallback)(function () {
97
+ // focus node if `InputSpotlightDecorator` is pausing Spotlight or if Spotlight is paused
98
+ if (node.current && _spotlight.Spotlight.getCurrent() !== node.current && (paused.isPaused() || !_spotlight.Spotlight.isPaused())) {
99
+ if (fromMouse.current) {
100
+ node.current.focus({
101
+ preventScroll: true
102
+ });
103
+ } else {
104
+ node.current.focus();
130
105
  }
131
- };
132
- _this.focusDecorator = function (decorator) {
133
- _this.focus('decorator', decorator, false);
134
- };
135
- _this.focusInput = function (decorator, fromMouse) {
136
- _this.focus('input', decorator.querySelector('input'), fromMouse);
137
- };
138
- _this.onBlur = function (ev) {
139
- if (!_this.props.autoFocus) {
140
- if (isBubbling(ev)) {
141
- if (_spotlight.Spotlight.getPointerMode()) {
142
- _this.blur();
143
- forwardBlur(ev, _this.props);
144
- } else {
145
- _this.focused = 'decorator';
146
- _this.node = ev.currentTarget;
147
- _this.fromMouse = false;
148
- ev.stopPropagation();
149
- }
150
- } else if (!ev.currentTarget.contains(ev.relatedTarget)) {
151
- // Blurring decorator but not focusing input
152
- forwardBlur(ev, _this.props);
153
- _this.blur();
106
+ }
107
+ var focusChanged = focused.current !== prevStatus.current.focused;
108
+ if (focusChanged) {
109
+ if (focused.current === 'input') {
110
+ (0, _handle.forwardCustom)('onActivate')(null, props);
111
+ if (!noLockPointer) {
112
+ (0, _pointer.lockPointer)(node.current);
154
113
  }
155
- } else if (isBubbling(ev)) {
156
- if (_this.focused === 'input' && _this.node === ev.target && ev.currentTarget !== ev.relatedTarget) {
157
- _this.blur();
158
- forwardBlur(ev, _this.props);
159
- } else {
160
- _this.focusDecorator(ev.currentTarget);
161
- ev.stopPropagation();
162
- _this.blur();
114
+ paused.pause();
115
+ } else if (prevStatus.current.focused === 'input') {
116
+ (0, _handle.forwardCustom)('onDeactivate')(null, props);
117
+ if (!noLockPointer) {
118
+ (0, _pointer.releasePointer)(prevStatus.current.node);
163
119
  }
120
+ paused.resume();
164
121
  }
122
+ }
123
+ prevStatus.current = {
124
+ focused: focused.current,
125
+ node: node.current
165
126
  };
166
- _this.onMouseDown = function (ev) {
167
- var _this$props = _this.props,
168
- disabled = _this$props.disabled,
169
- spotlightDisabled = _this$props.spotlightDisabled;
170
- _this.setDownTarget(ev);
171
- // focus the <input> whenever clicking on any part of the component to ensure both that
172
- // the <input> has focus and Spotlight is paused.
173
- if (!disabled && !spotlightDisabled) {
174
- _this.focusInput(ev.currentTarget, true);
175
- }
176
- forwardMouseDown(ev, _this.props);
177
- };
178
- _this.onFocus = function (ev) {
179
- forwardFocus(ev, _this.props);
127
+ }, [paused, props]);
128
+ var blur = (0, _react.useCallback)(function () {
129
+ if (focused.current || node.current) {
130
+ focused.current = null;
131
+ node.current = null;
132
+ updateFocus();
133
+ }
134
+ }, [updateFocus]);
135
+ var focus = (0, _react.useCallback)(function (focusedProp, nodeProp, fromMouseProp) {
136
+ focused.current = focusedProp;
137
+ node.current = nodeProp;
138
+ fromMouse.current = fromMouseProp;
139
+ updateFocus();
140
+ }, [updateFocus]);
141
+ var focusDecorator = (0, _react.useCallback)(function (decorator) {
142
+ focus('decorator', decorator, false);
143
+ }, [focus]);
144
+ var onKeyDown = (0, _react.useCallback)(function (ev) {
145
+ forwardKeyDown(ev, props);
146
+ var currentTarget = ev.currentTarget,
147
+ keyCode = ev.keyCode,
148
+ target = ev.target;
180
149
 
181
- // when in autoFocus mode, focusing the decorator directly will cause it to
182
- // forward the focus onto the <input>
183
- if (!isBubbling(ev) && _this.props.autoFocus && _this.focused === null && !_spotlight.Spotlight.getPointerMode()) {
184
- _this.focusInput(ev.currentTarget, false);
185
- ev.stopPropagation();
150
+ // cache the target if this is the first keyDown event to ensure the component had focus
151
+ // when the key interaction started
152
+ setDownTarget(ev);
153
+ if (focused.current === 'input') {
154
+ var isDown = (0, _keymap.is)('down', keyCode);
155
+ var isLeft = (0, _keymap.is)('left', keyCode);
156
+ var isRight = (0, _keymap.is)('right', keyCode);
157
+ var isUp = (0, _keymap.is)('up', keyCode);
158
+
159
+ // move spotlight
160
+ var shouldSpotlightMove =
161
+ // No value exists! (Can happen when disabled)
162
+ target.value == null ||
163
+ // on left + at beginning of selection
164
+ isLeft && isSelectionAtLocation(target, 0) ||
165
+ // on right + at end of selection (note: fails on non-selectable types usually)
166
+ isRight && isSelectionAtLocation(target, target.value.length) ||
167
+ // on up
168
+ isUp ||
169
+ // on down
170
+ isDown;
171
+
172
+ // prevent modifying the value via 5-way for numeric fields
173
+ if ((isUp || isDown) && target.type === 'number') {
174
+ ev.preventDefault();
186
175
  }
187
- };
188
- _this.onKeyUp = function (ev) {
189
- var dismissOnEnter = _this.props.dismissOnEnter;
190
- var currentTarget = ev.currentTarget,
191
- keyCode = ev.keyCode,
192
- target = ev.target;
176
+ if (shouldSpotlightMove) {
177
+ var direction = (0, _spotlight.getDirection)(keyCode);
178
+ var getPointerMode = _spotlight.Spotlight.getPointerMode,
179
+ move = _spotlight.Spotlight.move,
180
+ resetKeyHoldState = _spotlight.Spotlight.resetKeyHoldState,
181
+ setPointerMode = _spotlight.Spotlight.setPointerMode;
182
+ if (getPointerMode()) {
183
+ setPointerMode(false);
184
+ }
185
+ (0, _handle.stopImmediate)(ev);
186
+ paused.resume();
193
187
 
194
- // verify that we have a matching pair of key down/up events to avoid adjusting focus
195
- // when the component received focus mid-press
196
- if (target === _this.downTarget) {
197
- _this.downTarget = null;
198
- if (!_this.props.disabled) {
199
- if (_this.focused === 'input' && dismissOnEnter && (0, _keymap.is)('enter', keyCode)) {
200
- _this.focusDecorator(currentTarget);
201
- // prevent Enter onKeyPress which triggers an onMouseDown via Spotlight
202
- ev.preventDefault();
203
- } else if (_this.focused !== 'input' && (0, _keymap.is)('enter', keyCode)) {
204
- _this.focusInput(currentTarget, false);
205
- }
188
+ // Move spotlight in the keypress direction
189
+ if (move(direction)) {
190
+ // if successful, reset the internal state
191
+ blur();
192
+ resetKeyHoldState();
193
+ } else {
194
+ // if there is no other spottable elements, focus `InputDecorator` instead
195
+ focusDecorator(currentTarget);
206
196
  }
197
+ } else if (isLeft || isRight) {
198
+ // prevent 5-way nav for left/right keys within the <input>
199
+ (0, _handle.stopImmediate)(ev);
207
200
  }
208
- forwardKeyUp(ev, _this.props);
209
- };
210
- _this.focused = null;
211
- _this.node = null;
212
- _this.fromMouse = false;
213
- _this.paused = new _Pause["default"]('InputSpotlightDecorator');
214
- _this.handleKeyDown = handleKeyDown.bind(_this);
215
- _this.prevStatus = {
216
- focused: null,
217
- node: null
218
- };
219
- return _this;
220
- }
221
- _inherits(_Class, _ReactComponent);
222
- return _createClass(_Class, [{
223
- key: "componentWillUnmount",
224
- value: function componentWillUnmount() {
225
- this.paused.resume();
226
- if (this.focused === 'input') {
227
- var onSpotlightDisappear = this.props.onSpotlightDisappear;
201
+ }
202
+ }, [blur, focusDecorator, paused, props, setDownTarget]);
203
+ (0, _react.useEffect)(function () {
204
+ return function () {
205
+ paused.resume();
206
+ if (focused.current === 'input') {
207
+ var onSpotlightDisappear = props.onSpotlightDisappear;
228
208
  if (onSpotlightDisappear) {
229
209
  onSpotlightDisappear();
230
210
  }
231
211
  if (!noLockPointer) {
232
- (0, _pointer.releasePointer)(this.node);
212
+ (0, _pointer.releasePointer)(node.current);
233
213
  }
234
214
  }
235
- }
236
- }, {
237
- key: "onKeyDown",
238
- value: function onKeyDown(ev) {
239
- var currentTarget = ev.currentTarget,
240
- keyCode = ev.keyCode,
241
- target = ev.target;
242
-
243
- // cache the target if this is the first keyDown event to ensure the component had focus
244
- // when the key interaction started
245
- this.setDownTarget(ev);
246
- if (this.focused === 'input') {
247
- var isDown = (0, _keymap.is)('down', keyCode);
248
- var isLeft = (0, _keymap.is)('left', keyCode);
249
- var isRight = (0, _keymap.is)('right', keyCode);
250
- var isUp = (0, _keymap.is)('up', keyCode);
251
-
252
- // move spotlight
253
- var shouldSpotlightMove =
254
- // No value exists! (Can happen when disabled)
255
- target.value == null ||
256
- // on left + at beginning of selection
257
- isLeft && isSelectionAtLocation(target, 0) ||
258
- // on right + at end of selection (note: fails on non-selectable types usually)
259
- isRight && isSelectionAtLocation(target, target.value.length) ||
260
- // on up
261
- isUp ||
262
- // on down
263
- isDown;
264
-
265
- // prevent modifying the value via 5-way for numeric fields
266
- if ((isUp || isDown) && target.type === 'number') {
267
- ev.preventDefault();
268
- }
269
- if (shouldSpotlightMove) {
270
- var direction = (0, _spotlight.getDirection)(keyCode);
271
- var getPointerMode = _spotlight.Spotlight.getPointerMode,
272
- move = _spotlight.Spotlight.move,
273
- resetKeyHoldState = _spotlight.Spotlight.resetKeyHoldState,
274
- setPointerMode = _spotlight.Spotlight.setPointerMode;
275
- if (getPointerMode()) {
276
- setPointerMode(false);
277
- }
278
- (0, _handle.stopImmediate)(ev);
279
- this.paused.resume();
215
+ };
216
+ }, []); // eslint-disable-line react-hooks/exhaustive-deps
280
217
 
281
- // Move spotlight in the keypress direction
282
- if (move(direction)) {
283
- // if successful, reset the internal state
284
- this.blur();
285
- resetKeyHoldState();
286
- } else {
287
- // if there is no other spottable elements, focus `InputDecorator` instead
288
- this.focusDecorator(currentTarget);
289
- }
290
- } else if (isLeft || isRight) {
291
- // prevent 5-way nav for left/right keys within the <input>
292
- (0, _handle.stopImmediate)(ev);
218
+ var focusInput = (0, _react.useCallback)(function (decorator, fromMouseProp) {
219
+ focus('input', decorator.querySelector('input'), fromMouseProp);
220
+ }, [focus]);
221
+ var onBlur = (0, _react.useCallback)(function (ev) {
222
+ if (!props.autoFocus) {
223
+ if (isBubbling(ev)) {
224
+ if (_spotlight.Spotlight.getPointerMode()) {
225
+ blur();
226
+ forwardBlur(ev, props);
227
+ } else {
228
+ focused.current = 'decorator';
229
+ node.current = ev.currentTarget;
230
+ fromMouse.current = false;
231
+ ev.stopPropagation();
293
232
  }
233
+ } else if (!ev.currentTarget.contains(ev.relatedTarget)) {
234
+ // Blurring decorator but not focusing input
235
+ forwardBlur(ev, props);
236
+ blur();
294
237
  }
295
- }
296
- }, {
297
- key: "setDownTarget",
298
- value: function setDownTarget(ev) {
299
- var repeat = ev.repeat,
300
- target = ev.target;
301
- if (!repeat) {
302
- this.downTarget = target;
238
+ } else if (isBubbling(ev)) {
239
+ if (focused.current === 'input' && node.current === ev.target && ev.currentTarget !== ev.relatedTarget) {
240
+ blur();
241
+ forwardBlur(ev, props);
242
+ } else {
243
+ focusDecorator(ev.currentTarget);
244
+ ev.stopPropagation();
245
+ blur();
303
246
  }
304
247
  }
305
- }, {
306
- key: "render",
307
- value: function render() {
308
- var props = Object.assign({}, this.props);
309
- delete props.autoFocus;
310
- delete props.onActivate;
311
- delete props.onDeactivate;
312
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component, _objectSpread(_objectSpread({}, props), {}, {
313
- onBlur: this.onBlur,
314
- onMouseDown: this.onMouseDown,
315
- onFocus: this.onFocus,
316
- onKeyDown: this.handleKeyDown,
317
- onKeyUp: this.onKeyUp
318
- }));
248
+ }, [blur, focusDecorator, props]);
249
+ var onMouseDown = (0, _react.useCallback)(function (ev) {
250
+ var disabled = props.disabled,
251
+ spotlightDisabled = props.spotlightDisabled;
252
+ setDownTarget(ev);
253
+ // focus the <input> whenever clicking on any part of the component to ensure both that
254
+ // the <input> has focus and Spotlight is paused.
255
+ if (!disabled && !spotlightDisabled) {
256
+ focusInput(ev.currentTarget, true);
257
+ }
258
+ forwardMouseDown(ev, props);
259
+ }, [focusInput, props, setDownTarget]);
260
+ var onFocus = (0, _react.useCallback)(function (ev) {
261
+ forwardFocus(ev, props);
262
+ // when in autoFocus mode, focusing the decorator directly will cause it to
263
+ // forward the focus onto the <input>
264
+ if (!isBubbling(ev) && props.autoFocus && focused.current === null && !_spotlight.Spotlight.getPointerMode()) {
265
+ focusInput(ev.currentTarget, false);
266
+ ev.stopPropagation();
267
+ }
268
+ }, [focusInput, props]);
269
+ var onKeyUp = (0, _react.useCallback)(function (ev) {
270
+ var dismissOnEnter = props.dismissOnEnter;
271
+ var currentTarget = ev.currentTarget,
272
+ keyCode = ev.keyCode,
273
+ target = ev.target;
274
+
275
+ // verify that we have a matching pair of key down/up events to avoid adjusting focus
276
+ // when the component received focus mid-press
277
+ if (target === downTarget.current) {
278
+ downTarget.current = null;
279
+ if (!props.disabled) {
280
+ if (focused.current === 'input' && dismissOnEnter && (0, _keymap.is)('enter', keyCode)) {
281
+ focusDecorator(currentTarget);
282
+ // prevent Enter onKeyPress which triggers an onMouseDown via Spotlight
283
+ ev.preventDefault();
284
+ } else if (focused.current !== 'input' && (0, _keymap.is)('enter', keyCode)) {
285
+ focusInput(currentTarget, false);
286
+ }
287
+ }
319
288
  }
320
- }]);
321
- }(_react.Component), _Class.displayName = 'InputSpotlightDecorator', _Class.propTypes = /** @lends limestone/Input/InputSpotlightDecorator.InputSpotlightDecorator.prototype */{
289
+ forwardKeyUp(ev, props);
290
+ }, [focusDecorator, focusInput, props]);
291
+ var componentProps = Object.assign({}, props);
292
+ delete componentProps.autoFocus;
293
+ delete componentProps.onActivate;
294
+ delete componentProps.onDeactivate;
295
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component, _objectSpread(_objectSpread({}, componentProps), {}, {
296
+ onBlur: onBlur,
297
+ onFocus: onFocus,
298
+ onKeyDown: onKeyDown,
299
+ onKeyUp: onKeyUp,
300
+ onMouseDown: onMouseDown
301
+ }));
302
+ };
303
+ InputSpotlightDecorator.displayName = 'InputSpotlightDecorator';
304
+ InputSpotlightDecorator.propTypes = /** @lends limestone/Input/InputSpotlightDecorator.InputSpotlightDecorator.prototype */{
322
305
  /**
323
306
  * Focuses the <input> when the decorator is focused via 5-way.
324
307
  *
@@ -375,6 +358,7 @@ var InputSpotlightDecorator = exports.InputSpotlightDecorator = (0, _hoc["defaul
375
358
  * @public
376
359
  */
377
360
  spotlightDisabled: _propTypes["default"].bool
378
- }, _Class;
361
+ };
362
+ return InputSpotlightDecorator;
379
363
  });
380
364
  var _default = exports["default"] = InputSpotlightDecorator;
package/Input/index.d.ts CHANGED
@@ -260,23 +260,21 @@ export class InputPopupBase extends React.Component<
260
260
  Merge<React.HTMLProps<HTMLElement>, InputPopupBaseProps>
261
261
  > {}
262
262
 
263
- export interface InputFieldDecoratorProps
264
- extends Merge<
265
- ui_Changeable_ChangeableProps,
266
- limestone_Skinnable_SkinnableProps
267
- > {}
263
+ export interface InputFieldDecoratorProps extends Merge<
264
+ ui_Changeable_ChangeableProps,
265
+ limestone_Skinnable_SkinnableProps
266
+ > {}
268
267
  export function InputFieldDecorator<P>(
269
268
  Component: React.ComponentType<P> | string,
270
269
  ): React.ComponentType<P & InputFieldDecoratorProps>;
271
270
 
272
- export interface InputFieldProps
273
- extends Merge<
274
- Merge<
275
- Merge<InputFieldBaseProps, ui_Changeable_ChangeableProps>,
276
- spotlight_Spottable_SpottableProps
277
- >,
278
- limestone_Skinnable_SkinnableProps
279
- > {
271
+ export interface InputFieldProps extends Merge<
272
+ Merge<
273
+ Merge<InputFieldBaseProps, ui_Changeable_ChangeableProps>,
274
+ spotlight_Spottable_SpottableProps
275
+ >,
276
+ limestone_Skinnable_SkinnableProps
277
+ > {
280
278
  /**
281
279
  * Focuses the internal input when the component gains 5-way focus.
282
280
  *
@@ -362,11 +360,10 @@ export class InputBase extends React.Component<
362
360
  Merge<React.HTMLProps<HTMLElement>, InputBaseProps>
363
361
  > {}
364
362
 
365
- export interface InputDecoratorProps
366
- extends Merge<
367
- Merge<ui_Toggleable_ToggleableProps, ui_Changeable_ChangeableProps>,
368
- limestone_Skinnable_SkinnableProps
369
- > {}
363
+ export interface InputDecoratorProps extends Merge<
364
+ Merge<ui_Toggleable_ToggleableProps, ui_Changeable_ChangeableProps>,
365
+ limestone_Skinnable_SkinnableProps
366
+ > {}
370
367
  export function InputDecorator<P>(
371
368
  Component: React.ComponentType<P> | string,
372
369
  ): React.ComponentType<P & InputDecoratorProps>;
@@ -289,4 +289,25 @@ describe('InputField Specs', function () {
289
289
  var expectedAttribute = 'data-webos-voice-label';
290
290
  expect(inputField).toHaveAttribute(expectedAttribute, customLabel);
291
291
  });
292
+ test('should callback onKeyDown with `keydown` type when key is pressed', /*#__PURE__*/_asyncToGenerator(function* () {
293
+ var handleKeyDown = jest.fn();
294
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
295
+ onKeyDown: handleKeyDown
296
+ }));
297
+ var inputField = _react.screen.getByPlaceholderText('');
298
+ _react.fireEvent.mouseDown(inputField);
299
+ _react.fireEvent.keyDown(inputField, {
300
+ which: 37,
301
+ keyCode: 37,
302
+ code: 37
303
+ });
304
+ var key = handleKeyDown.mock.calls[0][0].key;
305
+ var expected = {
306
+ type: 'keydown'
307
+ };
308
+ var actual = handleKeyDown.mock.calls.length && handleKeyDown.mock.calls[0][0];
309
+ expect(handleKeyDown).toHaveBeenCalled();
310
+ expect(key).toBe('ArrowLeft');
311
+ expect(actual).toMatchObject(expected);
312
+ }));
292
313
  });
package/Item/Item.d.ts CHANGED
@@ -59,6 +59,10 @@ locales, the nodes are inserted to the left. If nothing is specified, nothing, n
59
59
  an empty container, is rendered in this place.
60
60
  */
61
61
  slotAfter?: React.ReactNode;
62
+ /**
63
+ * Aria-label for slotAfter icon.
64
+ */
65
+ slotAfterAria?: string;
62
66
  /**
63
67
  * Nodes to be inserted before `children` and `label` .
64
68
  *
@@ -67,6 +71,10 @@ locales, the nodes are inserted to the right. If nothing is specified, nothing,
67
71
  an empty container, is rendered in this place.
68
72
  */
69
73
  slotBefore?: React.ReactNode;
74
+ /**
75
+ * Aria-label for slotBefore icon.
76
+ */
77
+ slotBeforeAria?: string;
70
78
  }
71
79
  /**
72
80
  * A Limestone styled item without any behavior.
@@ -76,17 +84,16 @@ export class ItemBase extends React.Component<
76
84
  Merge<React.HTMLProps<HTMLElement>, ItemBaseProps>
77
85
  > {}
78
86
 
79
- export interface ItemDecoratorProps
80
- extends Merge<
87
+ export interface ItemDecoratorProps extends Merge<
88
+ Merge<
81
89
  Merge<
82
- Merge<
83
- Merge<ui_Item_ItemDecoratorProps, ui_Slottable_SlottableProps>,
84
- spotlight_Spottable_SpottableProps
85
- >,
86
- limestone_Marquee_MarqueeControllerProps
90
+ Merge<ui_Item_ItemDecoratorProps, ui_Slottable_SlottableProps>,
91
+ spotlight_Spottable_SpottableProps
87
92
  >,
88
- limestone_Skinnable_SkinnableProps
89
- > {}
93
+ limestone_Marquee_MarqueeControllerProps
94
+ >,
95
+ limestone_Skinnable_SkinnableProps
96
+ > {}
90
97
  export function ItemDecorator<P>(
91
98
  Component: React.ComponentType<P> | string,
92
99
  ): React.ComponentType<P & ItemDecoratorProps>;