@enact/limestone 1.3.0 → 1.10.0

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 (200) 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 +13 -2
  7. package/Alert/Alert.js +39 -5
  8. package/Alert/Alert.module.css +48 -1
  9. package/Alert/tests/Alert-specs.js +91 -0
  10. package/BodyText/BodyText.d.ts +5 -4
  11. package/BodyText/BodyText.module.css +7 -7
  12. package/Button/Button.d.ts +17 -12
  13. package/Button/Button.js +1 -1
  14. package/Button/Button.module.css +195 -268
  15. package/Button/tests/Button-specs.js +26 -0
  16. package/CHANGELOG.md +254 -0
  17. package/Card/Card.d.ts +40 -12
  18. package/Card/Card.js +164 -28
  19. package/Card/Card.module.css +277 -58
  20. package/Card/tests/Card-specs.js +67 -3
  21. package/Checkbox/Checkbox.d.ts +8 -7
  22. package/Checkbox/Checkbox.js +3 -1
  23. package/Checkbox/Checkbox.module.css +213 -120
  24. package/Checkbox/tests/Checkbox-specs.js +1 -1
  25. package/CheckboxItem/CheckboxItem.d.ts +22 -7
  26. package/CheckboxItem/CheckboxItem.js +71 -4
  27. package/Chips/Chip.js +72 -13
  28. package/Chips/Chip.module.css +3 -3
  29. package/Chips/Chips.js +37 -17
  30. package/Chips/Chips.module.css +1 -1
  31. package/Chips/tests/Chip-specs.js +43 -13
  32. package/Chips/tests/Chips-specs.js +31 -21
  33. package/ColorPicker/ColorPicker.js +27 -25
  34. package/ContextualMenuDecorator/ContextualMenuDecorator.d.ts +4 -5
  35. package/ContextualPopupDecorator/ContextualPopup.module.css +34 -34
  36. package/ContextualPopupDecorator/ContextualPopupDecorator.js +567 -549
  37. package/DatePicker/DatePicker.d.ts +4 -5
  38. package/DayPicker/DayPicker.d.ts +8 -7
  39. package/DayPicker/DaySelectorDecorator.js +12 -7
  40. package/Dropdown/Dropdown.d.ts +11 -13
  41. package/Dropdown/Dropdown.module.css +13 -9
  42. package/Dropdown/DropdownList.js +80 -54
  43. package/FixedPopupPanels/FixedPopupPanels.d.ts +4 -2
  44. package/FixedPopupPanels/FixedPopupPanels.module.css +18 -18
  45. package/FlexiblePopupPanels/FlexiblePopupPanels.module.css +23 -23
  46. package/FlexiblePopupPanels/useNavButtonFocus.js +7 -10
  47. package/FormCheckboxItem/FormCheckboxItem.d.ts +5 -4
  48. package/Heading/Heading.d.ts +9 -8
  49. package/Heading/Heading.js +2 -2
  50. package/Heading/Heading.module.css +5 -5
  51. package/Icon/Icon.d.ts +15 -4
  52. package/Icon/Icon.js +49 -2
  53. package/Icon/Icon.module.css +1 -1
  54. package/Icon/IconList.js +27 -1
  55. package/IconItem/IconItem.d.ts +13 -12
  56. package/IconItem/IconItem.js +15 -0
  57. package/IconItem/IconItem.module.css +107 -1
  58. package/IconItem/tests/IconItem-specs.js +30 -1
  59. package/Image/Image.d.ts +5 -4
  60. package/Image/Image.js +6 -4
  61. package/ImageItem/ImageItem.d.ts +11 -10
  62. package/ImageItem/ImageItem.js +37 -31
  63. package/ImageItem/ImageItem.module.css +30 -30
  64. package/ImageItem/tests/ImageItem-specs.js +3 -10
  65. package/Input/Input.js +21 -3
  66. package/Input/Input.module.css +37 -8
  67. package/Input/InputField.js +79 -24
  68. package/Input/InputField.module.css +273 -41
  69. package/Input/InputFieldDecoratorIcon.js +1 -0
  70. package/Input/InputFieldSpotlightDecorator.js +257 -228
  71. package/Input/index.d.ts +120 -111
  72. package/Input/tests/Input-specs.js +26 -0
  73. package/Input/tests/InputField-specs.js +170 -3
  74. package/Input/tests/InputPopup-specs.js +1 -1
  75. package/Item/Item.d.ts +16 -9
  76. package/Item/Item.js +20 -2
  77. package/Item/Item.module.css +1 -1
  78. package/KeyGuide/KeyGuide.d.ts +8 -7
  79. package/KeyGuide/KeyGuide.js +29 -27
  80. package/KeyGuide/KeyGuide.module.css +25 -1
  81. package/Marquee/Marquee.d.ts +2 -4
  82. package/MediaOverlay/MediaOverlay.d.ts +12 -11
  83. package/MediaOverlay/MediaOverlay.js +43 -21
  84. package/MediaOverlay/MediaOverlay.module.css +114 -15
  85. package/MediaOverlay/tests/MediaOverlay-specs.js +29 -0
  86. package/MediaPlayer/MediaControls.js +195 -13
  87. package/MediaPlayer/MediaControls.module.css +3 -2
  88. package/MediaPlayer/MediaSlider.module.css +7 -20
  89. package/MediaPlayer/index.d.ts +59 -7
  90. package/MediaPlayer/tests/util-specs.js +4 -1
  91. package/PageViews/PageViews.js +232 -82
  92. package/PageViews/PageViews.module.css +3 -0
  93. package/PageViews/PageViewsRouter.js +100 -42
  94. package/PageViews/tests/PageViews-specs.js +171 -0
  95. package/Panels/Header.js +54 -34
  96. package/Panels/Header.module.css +83 -31
  97. package/Panels/Panel.module.css +1 -1
  98. package/Panels/index.d.ts +7 -8
  99. package/Picker/Picker.d.ts +4 -5
  100. package/Picker/Picker.module.css +2 -2
  101. package/Popup/Popup.js +245 -242
  102. package/Popup/Popup.module.css +24 -24
  103. package/PopupTabLayout/PopupTabLayout.d.ts +5 -7
  104. package/PopupTabLayout/PopupTabLayout.js +26 -18
  105. package/PopupTabLayout/PopupTabLayout.module.css +53 -16
  106. package/PopupTabLayout/PopupTabLayoutStateContext.js +8 -0
  107. package/ProgressBar/ProgressBar.d.ts +5 -4
  108. package/ProgressBar/ProgressBarTooltip.module.css +12 -12
  109. package/ProgressButton/ProgressButton.d.ts +4 -5
  110. package/QuickGuidePanels/QuickGuidePanels.module.css +2 -2
  111. package/RadioItem/RadioItem.d.ts +18 -5
  112. package/RadioItem/RadioItem.js +69 -2
  113. package/RadioItem/RadioItem.module.css +36 -36
  114. package/RangePicker/RangePicker.module.css +2 -2
  115. package/Scroller/EditableWrapper.js +28 -18
  116. package/Scroller/Scroller.d.ts +20 -16
  117. package/Scroller/Scroller.js +20 -13
  118. package/Scroller/Scroller.module.css +4 -4
  119. package/Scroller/useThemeScroller.js +3 -3
  120. package/Slider/Slider.d.ts +20 -14
  121. package/Slider/Slider.js +71 -14
  122. package/Slider/Slider.module.css +464 -91
  123. package/Slider/SliderBehaviorDecorator.js +16 -14
  124. package/Slider/tests/Slider-specs.js +53 -1
  125. package/Slider/utils.js +23 -7
  126. package/Spinner/Spinner.d.ts +5 -4
  127. package/Spinner/Spinner.js +10 -8
  128. package/Spinner/Spinner.module.css +9 -9
  129. package/Steps/Steps.d.ts +5 -4
  130. package/Steps/Steps.js +9 -5
  131. package/Switch/Switch.d.ts +8 -7
  132. package/Switch/Switch.module.css +100 -13
  133. package/SwitchItem/SwitchItem.d.ts +9 -6
  134. package/TabLayout/RefocusDecorator.js +26 -18
  135. package/TabLayout/TabGroup.js +3 -2
  136. package/TabLayout/TabGroup.module.css +2 -2
  137. package/TabLayout/TabLayout.d.ts +6 -0
  138. package/TabLayout/TabLayout.js +11 -1
  139. package/TabLayout/TabLayout.module.css +18 -0
  140. package/TabLayout/tests/TabGroup-specs.js +1 -1
  141. package/TabLayout/tests/TabLayout-specs.js +52 -0
  142. package/ThemeDecorator/AccessibilityDecorator.js +12 -11
  143. package/ThemeDecorator/I18nFontDecorator.js +6 -4
  144. package/ThemeDecorator/ThemeDecorator.d.ts +16 -10
  145. package/ThemeDecorator/ThemeDecorator.js +24 -9
  146. package/ThemeDecorator/fontGenerator.js +1 -1
  147. package/ThemeDecorator/screenTypes.json +1 -0
  148. package/TimePicker/TimePicker.module.css +1 -1
  149. package/TimePicker/TimePickerBase.js +5 -3
  150. package/TooltipDecorator/Tooltip.module.css +1 -2
  151. package/TooltipDecorator/TooltipDecorator.js +12 -7
  152. package/TooltipDecorator/tests/useTooltip-specs.js +5 -2
  153. package/TooltipDecorator/tests/util-specs.js +12 -0
  154. package/TooltipDecorator/useTooltip.js +1 -1
  155. package/TooltipDecorator/util.js +18 -11
  156. package/VideoPlayer/Feedback.js +3 -0
  157. package/VideoPlayer/Feedback.module.css +5 -9
  158. package/VideoPlayer/FeedbackIcons.js +1 -1
  159. package/VideoPlayer/FeedbackTooltip.module.css +55 -11
  160. package/VideoPlayer/VideoPlayer.d.ts +44 -18
  161. package/VideoPlayer/VideoPlayer.js +153 -47
  162. package/VideoPlayer/VideoPlayer.module.css +28 -11
  163. package/VirtualList/VirtualList.d.ts +9 -2
  164. package/VirtualList/VirtualList.js +51 -24
  165. package/VirtualList/tests/VirtualGridList-translate-specs.js +3 -0
  166. package/VirtualList/tests/VirtualList-specs.js +28 -1
  167. package/VirtualList/tests/VirtualList-translate-specs.js +4 -1
  168. package/VirtualList/useSpotlight.js +1 -1
  169. package/WizardPanels/WizardPanels.module.css +2 -2
  170. package/WizardPanels/index.d.ts +4 -2
  171. package/fonts/Limestone_Icons.ttf +0 -0
  172. package/internal/$L/$L.js +3 -3
  173. package/internal/AsyncRenderChildren/AsyncRenderChildren.js +9 -5
  174. package/internal/AsyncRenderChildren/tests/AsyncRenderChildren-specs.js +4 -1
  175. package/internal/DateComponentPicker/DateComponentPicker.module.css +2 -2
  176. package/internal/DateTime/DateTime.module.css +1 -0
  177. package/internal/DateTime/DateTimeDecorator.js +5 -4
  178. package/internal/Panels/PanelsRouter.js +48 -31
  179. package/internal/Panels/useAutoFocus.js +10 -6
  180. package/internal/Panels/useFocusOnTransition.js +4 -3
  181. package/internal/Picker/Picker.js +7 -5
  182. package/internal/Picker/Picker.module.css +2 -2
  183. package/internal/Picker/SpottablePicker.js +15 -13
  184. package/internal/SharedStateDecorator/SharedStateDecorator.js +78 -99
  185. package/internal/validators/validators.js +21 -2
  186. package/package.json +18 -15
  187. package/styles/colors-highcontrast.less +9 -1
  188. package/styles/colors.less +12 -7
  189. package/styles/motion-mixins.less +66 -0
  190. package/styles/motions.less +78 -0
  191. package/styles/variables.less +176 -150
  192. package/useScroll/HoverToScroll.js +23 -17
  193. package/useScroll/Scrollbar.js +14 -10
  194. package/useScroll/ScrollbarPlaceholder.js +3 -5
  195. package/useScroll/ScrollbarTrack.js +7 -5
  196. package/useScroll/ScrollbarTrack.module.css +8 -8
  197. package/useScroll/useEvent.js +14 -3
  198. package/useScroll/useScroll.js +12 -2
  199. package/useScroll/useScroll.module.css +6 -6
  200. package/.travis.yml +0 -40
package/Input/index.d.ts CHANGED
@@ -9,99 +9,6 @@ import { SpottableProps as spotlight_Spottable_SpottableProps } from "@enact/spo
9
9
  type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
10
10
  type Merge<M, N> = Omit<M, Extract<keyof M, keyof N>> & N;
11
11
 
12
- export interface InputFieldBaseProps {
13
- /**
14
- * Passed by AnnounceDecorator for accessibility.
15
- */
16
- announce?: Function;
17
- /**
18
- * Disables InputField and becomes non-interactive.
19
- */
20
- disabled?: boolean;
21
- /**
22
- * Blurs the input when the "enter" key is pressed.
23
- */
24
- dismissOnEnter?: boolean;
25
- /**
26
- * The icon to be placed at the end of the input.
27
- */
28
- iconAfter?: string;
29
- /**
30
- * The icon to be placed at the beginning of the input.
31
- */
32
- iconBefore?: string;
33
- /**
34
- * Indicates is invalid and shows
35
- , if set.
36
- */
37
- invalid?: boolean;
38
- /**
39
- * The tooltip text to be displayed when the input is
40
- .
41
- *
42
- * If this value is _falsy_ , the tooltip will be shown with the default message.
43
- */
44
- invalidMessage?: string;
45
- /**
46
- * Called before the input value is changed.
47
- *
48
- * The change can be prevented by calling `preventDefault` on the event.
49
- */
50
- onBeforeChange?: Function;
51
- /**
52
- * Called when blurred.
53
- */
54
- onBlur?: Function;
55
- /**
56
- * Called when the input value is changed.
57
- *
58
- * The event payload includes the current `value` as well as a `stopPropagation()` method
59
- which may be called to stop the original `onChange` event from the `<input>` from
60
- bubbling.
61
- */
62
- onChange?: Function;
63
- /**
64
- * Called when clicked.
65
- */
66
- onClick?: Function;
67
- /**
68
- * Called when focused.
69
- */
70
- onFocus?: Function;
71
- /**
72
- * Called when a key is pressed down.
73
- */
74
- onKeyDown?: Function;
75
- /**
76
- * Text to display when is not set.
77
- */
78
- placeholder?: string;
79
- /**
80
- * The size of the input field.
81
- */
82
- size?: "large" | "small";
83
- /**
84
- * The type of input.
85
- *
86
- * Accepted values correspond to the standard HTML5 input types.
87
- */
88
- type?: string;
89
- /**
90
- * The value of the input.
91
- */
92
- value?: string | number;
93
- }
94
- /**
95
- * A Limestone styled input component.
96
- *
97
- * It supports start and end icons, but it does not support Spotlight. Apps should use
98
- .
99
- */
100
-
101
- export class InputFieldBase extends React.Component<
102
- Merge<React.HTMLProps<HTMLElement>, InputFieldBaseProps>
103
- > {}
104
-
105
12
  export interface InputPopupBaseProps {
106
13
  /**
107
14
  * Passed by AnnounceDecorator for accessibility.
@@ -158,6 +65,10 @@ and when `numberInputField` is `'auto'` .
158
65
  * This value will override `minLength` and `maxLength` .
159
66
  */
160
67
  length?: number;
68
+ /**
69
+ * Wraps the `InputField` 's value display in a marquee.
70
+ */
71
+ marqueeInputField?: boolean;
161
72
  /**
162
73
  * The maximum length of number input fields.
163
74
  *
@@ -260,23 +171,122 @@ export class InputPopupBase extends React.Component<
260
171
  Merge<React.HTMLProps<HTMLElement>, InputPopupBaseProps>
261
172
  > {}
262
173
 
263
- export interface InputFieldDecoratorProps
264
- extends Merge<
265
- ui_Changeable_ChangeableProps,
266
- limestone_Skinnable_SkinnableProps
267
- > {}
174
+ export interface InputFieldBaseProps {
175
+ /**
176
+ * Passed by AnnounceDecorator for accessibility.
177
+ */
178
+ announce?: Function;
179
+ /**
180
+ * Moves the caret to the end of the text when the input receives focus.
181
+ */
182
+ caretToEndOnFocus?: boolean;
183
+ /**
184
+ * Disables InputField and becomes non-interactive.
185
+ */
186
+ disabled?: boolean;
187
+ /**
188
+ * Blurs the input when the "enter" key is pressed.
189
+ */
190
+ dismissOnEnter?: boolean;
191
+ /**
192
+ * The icon to be placed at the end of the input.
193
+ */
194
+ iconAfter?: string;
195
+ /**
196
+ * The icon to be placed at the beginning of the input.
197
+ */
198
+ iconBefore?: string;
199
+ /**
200
+ * Indicates is invalid and shows
201
+ , if set.
202
+ */
203
+ invalid?: boolean;
204
+ /**
205
+ * The tooltip text to be displayed when the input is
206
+ .
207
+ *
208
+ * If this value is _falsy_ , the tooltip will be shown with the default message.
209
+ */
210
+ invalidMessage?: string;
211
+ /**
212
+ * Wraps the input's value/placeholder display in a marquee.
213
+ */
214
+ marqueeContent?: boolean;
215
+ /**
216
+ * Called before the input value is changed.
217
+ *
218
+ * The change can be prevented by calling `preventDefault` on the event.
219
+ */
220
+ onBeforeChange?: Function;
221
+ /**
222
+ * Called when blurred.
223
+ */
224
+ onBlur?: Function;
225
+ /**
226
+ * Called when the input value is changed.
227
+ *
228
+ * The event payload includes the current `value` as well as a `stopPropagation()` method
229
+ which may be called to stop the original `onChange` event from the `<input>` from
230
+ bubbling.
231
+ */
232
+ onChange?: Function;
233
+ /**
234
+ * Called when clicked.
235
+ */
236
+ onClick?: Function;
237
+ /**
238
+ * Called when focused.
239
+ */
240
+ onFocus?: Function;
241
+ /**
242
+ * Called when a key is pressed down.
243
+ */
244
+ onKeyDown?: Function;
245
+ /**
246
+ * Text to display when is not set.
247
+ */
248
+ placeholder?: string;
249
+ /**
250
+ * The size of the input field.
251
+ */
252
+ size?: "large" | "small";
253
+ /**
254
+ * The type of input.
255
+ *
256
+ * Accepted values correspond to the standard HTML5 input types.
257
+ */
258
+ type?: string;
259
+ /**
260
+ * The value of the input.
261
+ */
262
+ value?: string | number;
263
+ }
264
+ /**
265
+ * A Limestone styled input component.
266
+ *
267
+ * It supports start and end icons, but it does not support Spotlight. Apps should use
268
+ .
269
+ */
270
+
271
+ export class InputFieldBase extends React.Component<
272
+ Merge<React.HTMLProps<HTMLElement>, InputFieldBaseProps>
273
+ > {}
274
+
275
+ export interface InputFieldDecoratorProps extends Merge<
276
+ ui_Changeable_ChangeableProps,
277
+ limestone_Skinnable_SkinnableProps
278
+ > {}
268
279
  export function InputFieldDecorator<P>(
269
280
  Component: React.ComponentType<P> | string,
270
281
  ): React.ComponentType<P & InputFieldDecoratorProps>;
271
282
 
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
- > {
283
+ export interface InputFieldProps extends Merge<
284
+ Merge<
285
+ Merge<InputFieldBaseProps, ui_Changeable_ChangeableProps>,
286
+ spotlight_Spottable_SpottableProps
287
+ >,
288
+ limestone_Skinnable_SkinnableProps
289
+ > {
280
290
  /**
281
291
  * Focuses the internal input when the component gains 5-way focus.
282
292
  *
@@ -362,11 +372,10 @@ export class InputBase extends React.Component<
362
372
  Merge<React.HTMLProps<HTMLElement>, InputBaseProps>
363
373
  > {}
364
374
 
365
- export interface InputDecoratorProps
366
- extends Merge<
367
- Merge<ui_Toggleable_ToggleableProps, ui_Changeable_ChangeableProps>,
368
- limestone_Skinnable_SkinnableProps
369
- > {}
375
+ export interface InputDecoratorProps extends Merge<
376
+ Merge<ui_Toggleable_ToggleableProps, ui_Changeable_ChangeableProps>,
377
+ limestone_Skinnable_SkinnableProps
378
+ > {}
370
379
  export function InputDecorator<P>(
371
380
  Component: React.ComponentType<P> | string,
372
381
  ): React.ComponentType<P & InputDecoratorProps>;
@@ -534,4 +534,30 @@ describe('Input specs', function () {
534
534
  expect(buttonSubmit).toBeNull();
535
535
  });
536
536
  });
537
+ describe('marqueeInputField', function () {
538
+ test('should not render a marquee node in the InputField by default', function () {
539
+ var _render = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
540
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
541
+ open: true,
542
+ value: "hello"
543
+ })
544
+ })),
545
+ baseElement = _render.baseElement;
546
+ var marqueeText = baseElement.querySelector('.marqueeText');
547
+ expect(marqueeText).toBeNull();
548
+ });
549
+ test('should render a marquee node in the InputField when marqueeInputField is true', function () {
550
+ var _render2 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
551
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input["default"], {
552
+ open: true,
553
+ marqueeInputField: true,
554
+ value: "hello"
555
+ })
556
+ })),
557
+ baseElement = _render2.baseElement;
558
+ var marqueeText = baseElement.querySelector('.marqueeText');
559
+ expect(marqueeText).not.toBeNull();
560
+ expect(marqueeText.querySelector('.marquee')).not.toBeNull();
561
+ });
562
+ });
537
563
  });
@@ -25,7 +25,7 @@ describe('InputField Specs', function () {
25
25
  var inputField = _react.screen.getByLabelText('hello Input field');
26
26
  var expected = 'hello';
27
27
  var actual = inputField.textContent;
28
- expect(actual).toBe(expected);
28
+ expect(actual).toContain(expected);
29
29
  });
30
30
  test('should callback onChange with `onChange` type when the text changes', /*#__PURE__*/_asyncToGenerator(function* () {
31
31
  var handleChange = jest.fn();
@@ -175,13 +175,13 @@ describe('InputField Specs', function () {
175
175
  var inputField = _react.screen.getByLabelText('hello Input field');
176
176
  var actual = inputField.textContent;
177
177
  var expected = 'hello';
178
- expect(actual).toBe(expected);
178
+ expect(actual).toContain(expected);
179
179
  });
180
180
  test('should have dir equal to rtl when there is rtl text', function () {
181
181
  (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
182
182
  value: "\u05E9\u05D5\u05E2\u05DC \u05D4\u05D7\u05D5\u05DD \u05D4\u05D6\u05E8\u05D9\u05D6 \u05E7\u05E4\u05E5 \u05DE\u05E2\u05DC \u05D4\u05DB\u05DC\u05D1 \u05D4\u05E2\u05E6\u05DC\u05DF.\u05E6\u05D9\u05E4\u05D5\u05E8 \u05E2\u05E4\u05D4 \u05D4\u05E9\u05E2\u05D5\u05E2\u05D9\u05EA \u05E2\u05DD \u05E9\u05E7\u05D9"
183
183
  }));
184
- var inputField = _react.screen.getByLabelText('שועל החום הזריז קפץ מעל הכלב העצלן.ציפור עפה השעועית עם שקי' + ' Input field').children.item(2);
184
+ var inputField = _react.screen.getByPlaceholderText('');
185
185
  var expectedAttribute = 'dir';
186
186
  var expectedValue = 'rtl';
187
187
  expect(inputField).toHaveAttribute(expectedAttribute, expectedValue);
@@ -289,4 +289,171 @@ 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
+ }));
313
+ describe('marqueeContent', function () {
314
+ test('should not render a marquee node by default', function () {
315
+ var _render2 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
316
+ value: "hello"
317
+ })),
318
+ baseElement = _render2.baseElement;
319
+ var marqueeText = baseElement.querySelector('.marqueeText');
320
+ expect(marqueeText).toBeNull();
321
+ });
322
+ test('should render a marquee node when marqueeContent is true', function () {
323
+ var _render3 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
324
+ marqueeContent: true,
325
+ value: "hello"
326
+ })),
327
+ baseElement = _render3.baseElement;
328
+ var marqueeText = baseElement.querySelector('.marqueeText');
329
+ expect(marqueeText).not.toBeNull();
330
+ expect(marqueeText.querySelector('.marquee')).not.toBeNull();
331
+ });
332
+ });
333
+ describe('moveCaretToEnd', function () {
334
+ test('should move caret to end of value on mouse focus when caretToEndOnFocus is true', function () {
335
+ jest.useFakeTimers();
336
+ var value = 'hello';
337
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
338
+ caretToEndOnFocus: true,
339
+ value: value
340
+ }));
341
+ var inputField = _react.screen.getByPlaceholderText('');
342
+ var setSelectionRange = jest.spyOn(inputField, 'setSelectionRange');
343
+ _react.fireEvent.mouseDown(inputField);
344
+ (0, _react.act)(function () {
345
+ return jest.runOnlyPendingTimers();
346
+ });
347
+ expect(setSelectionRange).toHaveBeenCalledWith(value.length, value.length);
348
+ jest.useRealTimers();
349
+ });
350
+ test('should set scrollLeft to scrollWidth for LTR input when caretToEndOnFocus is true', function () {
351
+ jest.useFakeTimers();
352
+ var value = 'hello';
353
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
354
+ caretToEndOnFocus: true,
355
+ value: value
356
+ }));
357
+ var inputField = _react.screen.getByPlaceholderText('');
358
+ var scrollLeft = 0;
359
+ Object.defineProperty(inputField, 'scrollLeft', {
360
+ get: function get() {
361
+ return scrollLeft;
362
+ },
363
+ set: function set(v) {
364
+ scrollLeft = v;
365
+ },
366
+ configurable: true
367
+ });
368
+ Object.defineProperty(inputField, 'scrollWidth', {
369
+ get: function get() {
370
+ return 200;
371
+ },
372
+ configurable: true
373
+ });
374
+ _react.fireEvent.mouseDown(inputField);
375
+ (0, _react.act)(function () {
376
+ return jest.runOnlyPendingTimers();
377
+ });
378
+ expect(scrollLeft).toBe(200);
379
+ jest.useRealTimers();
380
+ });
381
+ test('should set scrollLeft to 0 for RTL input when caretToEndOnFocus is true', function () {
382
+ jest.useFakeTimers();
383
+ var rtlValue = 'שועל החום הזריז';
384
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
385
+ caretToEndOnFocus: true,
386
+ value: rtlValue
387
+ }));
388
+ var inputField = _react.screen.getByPlaceholderText('');
389
+ var scrollLeft = 999;
390
+ Object.defineProperty(inputField, 'scrollLeft', {
391
+ get: function get() {
392
+ return scrollLeft;
393
+ },
394
+ set: function set(v) {
395
+ scrollLeft = v;
396
+ },
397
+ configurable: true
398
+ });
399
+ Object.defineProperty(inputField, 'scrollWidth', {
400
+ get: function get() {
401
+ return 200;
402
+ },
403
+ configurable: true
404
+ });
405
+ _react.fireEvent.mouseDown(inputField);
406
+ (0, _react.act)(function () {
407
+ return jest.runOnlyPendingTimers();
408
+ });
409
+ expect(scrollLeft).toBe(0);
410
+ jest.useRealTimers();
411
+ });
412
+ test('should not move caret when caretToEndOnFocus is not set', function () {
413
+ jest.useFakeTimers();
414
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
415
+ value: "hello"
416
+ }));
417
+ var inputField = _react.screen.getByPlaceholderText('');
418
+ var setSelectionRange = jest.spyOn(inputField, 'setSelectionRange');
419
+ _react.fireEvent.mouseDown(inputField);
420
+ (0, _react.act)(function () {
421
+ return jest.runOnlyPendingTimers();
422
+ });
423
+ expect(setSelectionRange).not.toHaveBeenCalled();
424
+ jest.useRealTimers();
425
+ });
426
+ });
427
+ describe('decorator icons', function () {
428
+ test('should render iconBefore and iconAfter with data-input-icon attribute', function () {
429
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
430
+ iconBefore: "plus",
431
+ iconAfter: "minus"
432
+ }));
433
+ var icons = document.querySelectorAll('[data-input-icon]');
434
+ expect(icons).toHaveLength(2);
435
+ });
436
+ test('should not activate the input when iconBefore is clicked', function () {
437
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
438
+ iconBefore: "plus",
439
+ value: "hello"
440
+ }));
441
+ var inputField = _react.screen.getByPlaceholderText('');
442
+ var icon = document.querySelector('[data-input-icon]');
443
+ var focusSpy = jest.spyOn(inputField, 'focus');
444
+ _react.fireEvent.mouseDown(icon);
445
+ expect(focusSpy).not.toHaveBeenCalled();
446
+ });
447
+ test('should not activate the input when iconAfter is clicked', function () {
448
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_.InputField, {
449
+ iconAfter: "minus",
450
+ value: "hello"
451
+ }));
452
+ var inputField = _react.screen.getByPlaceholderText('');
453
+ var icon = document.querySelector('[data-input-icon]');
454
+ var focusSpy = jest.spyOn(inputField, 'focus');
455
+ _react.fireEvent.mouseDown(icon);
456
+ expect(focusSpy).not.toHaveBeenCalled();
457
+ });
458
+ });
292
459
  });
@@ -47,7 +47,7 @@ describe('InputPopup Specs', function () {
47
47
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Input.InputPopup, {
48
48
  defaultValue: strDefaultValue,
49
49
  open: true,
50
- value: strValue
50
+ value: strValue || strDefaultValue
51
51
  })
52
52
  }));
53
53
  var actual = _react.screen.getByDisplayValue(strValue);
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>;
package/Item/Item.js CHANGED
@@ -20,7 +20,7 @@ var _Skinnable = _interopRequireDefault(require("../Skinnable"));
20
20
  var _ItemModule = _interopRequireDefault(require("./Item.module.css"));
21
21
  var _jsxRuntime = require("react/jsx-runtime");
22
22
  var _excluded = ["componentRef", "content", "contentSize", "css", "label", "labelPosition", "marqueeOn"],
23
- _excluded2 = ["centered", "children", "componentRef", "contentRef", "contentSize", "css", "inline", "label", "labelPosition", "marqueeOn", "slotAfter", "slotBefore"];
23
+ _excluded2 = ["centered", "children", "componentRef", "contentRef", "contentSize", "css", "inline", "label", "labelPosition", "marqueeOn", "slotAfter", "slotAfterAria", "slotBefore", "slotBeforeAria"];
24
24
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
25
25
  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; }
26
26
  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; }
@@ -217,6 +217,13 @@ var ItemBase = exports.ItemBase = (0, _kind["default"])({
217
217
  * @public
218
218
  */
219
219
  slotAfter: _propTypes2["default"].node,
220
+ /**
221
+ * Aria-label for slotAfter icon.
222
+ *
223
+ * @type {String}
224
+ * @public
225
+ */
226
+ slotAfterAria: _propTypes2["default"].string,
220
227
  /**
221
228
  * Nodes to be inserted before `children` and `label`.
222
229
  *
@@ -227,7 +234,14 @@ var ItemBase = exports.ItemBase = (0, _kind["default"])({
227
234
  * @type {Node}
228
235
  * @public
229
236
  */
230
- slotBefore: _propTypes2["default"].node
237
+ slotBefore: _propTypes2["default"].node,
238
+ /**
239
+ * Aria-label for slotBefore icon.
240
+ *
241
+ * @type {String}
242
+ * @public
243
+ */
244
+ slotBeforeAria: _propTypes2["default"].string
231
245
  },
232
246
  defaultProps: {
233
247
  labelPosition: 'below',
@@ -267,7 +281,9 @@ var ItemBase = exports.ItemBase = (0, _kind["default"])({
267
281
  labelPosition = _ref5.labelPosition,
268
282
  marqueeOn = _ref5.marqueeOn,
269
283
  slotAfter = _ref5.slotAfter,
284
+ slotAfterAria = _ref5.slotAfterAria,
270
285
  slotBefore = _ref5.slotBefore,
286
+ slotBeforeAria = _ref5.slotBeforeAria,
271
287
  rest = _objectWithoutProperties(_ref5, _excluded2);
272
288
  delete rest.size;
273
289
  var keys = Object.keys(rest);
@@ -286,6 +302,7 @@ var ItemBase = exports.ItemBase = (0, _kind["default"])({
286
302
  className: css.bg
287
303
  }), slotBefore ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
288
304
  className: css.slotBefore,
305
+ "aria-label": slotBeforeAria,
289
306
  shrink: true,
290
307
  children: slotBefore
291
308
  }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(ItemContent, {
@@ -299,6 +316,7 @@ var ItemBase = exports.ItemBase = (0, _kind["default"])({
299
316
  shrink: inline
300
317
  }), slotAfter ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
301
318
  className: css.slotAfter,
319
+ "aria-label": slotAfterAria,
302
320
  shrink: true,
303
321
  children: slotAfter
304
322
  }) : null]
@@ -7,7 +7,7 @@
7
7
  display: flex;
8
8
  position: relative;
9
9
  color: inherit;
10
- margin: 0 0.75rem 0.625rem 0.75rem;
10
+ margin: 0 var(--primitive-spacing-36) var(--primitive-spacing-30) var(--primitive-spacing-36);
11
11
  }
12
12
  .item.selected {
13
13
  /* Available for customization */
@@ -66,17 +66,18 @@ export class KeyGuideBase extends React.Component<
66
66
  Merge<React.HTMLProps<HTMLElement>, KeyGuideBaseProps>
67
67
  > {}
68
68
 
69
- export interface KeyGuideDecoratorProps
70
- extends Merge<
71
- limestone_Marquee_MarqueeControllerProps,
72
- limestone_Skinnable_SkinnableProps
73
- > {}
69
+ export interface KeyGuideDecoratorProps extends Merge<
70
+ limestone_Marquee_MarqueeControllerProps,
71
+ limestone_Skinnable_SkinnableProps
72
+ > {}
74
73
  export function KeyGuideDecorator<P>(
75
74
  Component: React.ComponentType<P> | string,
76
75
  ): React.ComponentType<P & KeyGuideDecoratorProps>;
77
76
 
78
- export interface KeyGuideProps
79
- extends Merge<KeyGuideBaseProps, KeyGuideDecoratorProps> {}
77
+ export interface KeyGuideProps extends Merge<
78
+ KeyGuideBaseProps,
79
+ KeyGuideDecoratorProps
80
+ > {}
80
81
  /**
81
82
  * A Key Guide component, ready to use in Limestone applications.
82
83
  *