@enact/limestone 1.9.3 → 1.10.1

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 (120) hide show
  1. package/.github/workflows/ci-reusable.yml +2 -2
  2. package/ActionGuide/ActionGuide.module.css +4 -0
  3. package/Alert/Alert.d.ts +9 -0
  4. package/Alert/Alert.js +35 -4
  5. package/Alert/Alert.module.css +12 -1
  6. package/Alert/tests/Alert-specs.js +91 -0
  7. package/BodyText/BodyText.module.css +21 -0
  8. package/Button/Button.module.css +72 -40
  9. package/Button/tests/Button-specs.js +26 -0
  10. package/CHANGELOG.md +74 -0
  11. package/Card/Card.d.ts +4 -4
  12. package/Card/Card.js +10 -8
  13. package/Card/Card.module.css +31 -7
  14. package/Card/tests/Card-specs.js +39 -5
  15. package/Checkbox/Checkbox.module.css +4 -0
  16. package/CheckboxItem/CheckboxItem.js +6 -4
  17. package/Chips/Chip.js +12 -6
  18. package/Chips/Chip.module.css +3 -0
  19. package/Chips/Chips.js +12 -6
  20. package/Chips/tests/Chip-specs.js +25 -5
  21. package/Chips/tests/Chips-specs.js +12 -2
  22. package/ColorPicker/ColorPicker.js +27 -25
  23. package/ContextualPopupDecorator/ContextualPopupDecorator.js +32 -22
  24. package/DayPicker/DaySelectorDecorator.js +12 -7
  25. package/Dropdown/Dropdown.module.css +4 -0
  26. package/Dropdown/DropdownList.js +74 -53
  27. package/FlexiblePopupPanels/useNavButtonFocus.js +7 -10
  28. package/Heading/Heading.d.ts +1 -1
  29. package/Heading/Heading.js +2 -2
  30. package/Heading/Heading.module.css +16 -0
  31. package/Icon/Icon.d.ts +1 -0
  32. package/Icon/Icon.js +1 -0
  33. package/Icon/Icon.module.css +12 -0
  34. package/Icon/IconList.js +2 -0
  35. package/IconItem/IconItem.module.css +19 -3
  36. package/IconItem/tests/IconItem-specs.js +30 -1
  37. package/Image/Image.js +6 -4
  38. package/ImageItem/ImageItem.module.css +17 -0
  39. package/Input/Input.js +12 -1
  40. package/Input/Input.module.css +25 -9
  41. package/Input/InputField.js +75 -24
  42. package/Input/InputField.module.css +280 -45
  43. package/Input/InputFieldDecoratorIcon.js +1 -0
  44. package/Input/InputFieldSpotlightDecorator.js +53 -8
  45. package/Input/index.d.ts +105 -93
  46. package/Input/tests/Input-specs.js +26 -0
  47. package/Input/tests/InputField-specs.js +149 -3
  48. package/Input/tests/InputPopup-specs.js +1 -1
  49. package/Item/Item.module.css +2 -1
  50. package/KeyGuide/KeyGuide.js +29 -27
  51. package/KeyGuide/KeyGuide.module.css +10 -0
  52. package/MediaOverlay/MediaOverlay.module.css +16 -4
  53. package/MediaOverlay/tests/MediaOverlay-specs.js +29 -0
  54. package/MediaPlayer/MediaControls.module.css +3 -0
  55. package/MediaPlayer/Times.module.css +4 -0
  56. package/MediaPlayer/tests/util-specs.js +4 -1
  57. package/PageViews/PageViews.js +134 -69
  58. package/PageViews/PageViews.module.css +7 -0
  59. package/PageViews/PageViewsRouter.js +91 -42
  60. package/PageViews/tests/PageViews-specs.js +87 -0
  61. package/Panels/Header.js +6 -4
  62. package/Panels/Header.module.css +37 -31
  63. package/Popup/Popup.js +5 -4
  64. package/PopupTabLayout/PopupTabLayout.js +11 -9
  65. package/PopupTabLayout/PopupTabLayout.module.css +18 -0
  66. package/RadioItem/RadioItem.js +7 -5
  67. package/RadioItem/RadioItem.module.css +5 -0
  68. package/Scroller/EditableWrapper.js +19 -15
  69. package/Scroller/Scroller.js +11 -10
  70. package/Scroller/Scroller.module.css +10 -0
  71. package/Scroller/tests/Scroller-specs.js +91 -2
  72. package/Scroller/useThemeScroller.js +6 -3
  73. package/Slider/Slider.d.ts +4 -0
  74. package/Slider/Slider.js +40 -16
  75. package/Slider/Slider.module.css +150 -3
  76. package/Slider/SliderBehaviorDecorator.js +16 -14
  77. package/Slider/tests/Slider-specs.js +51 -0
  78. package/Slider/utils.js +23 -7
  79. package/Spinner/Spinner.js +10 -8
  80. package/Steps/Steps.module.css +3 -0
  81. package/Switch/Switch.module.css +15 -1
  82. package/TabLayout/RefocusDecorator.js +14 -12
  83. package/TabLayout/TabGroup.module.css +1 -1
  84. package/TabLayout/tests/TabGroup-specs.js +1 -1
  85. package/ThemeDecorator/AccessibilityDecorator.js +12 -11
  86. package/ThemeDecorator/I18nFontDecorator.js +6 -4
  87. package/ThemeDecorator/ThemeDecorator.d.ts +7 -0
  88. package/ThemeDecorator/ThemeDecorator.js +24 -9
  89. package/TimePicker/TimePicker.module.css +3 -0
  90. package/TimePicker/TimePickerBase.js +5 -3
  91. package/TooltipDecorator/Tooltip.module.css +4 -0
  92. package/TooltipDecorator/TooltipDecorator.js +12 -7
  93. package/TooltipDecorator/tests/useTooltip-specs.js +5 -2
  94. package/VideoPlayer/Feedback.module.css +3 -0
  95. package/VideoPlayer/FeedbackTooltip.module.css +7 -0
  96. package/VideoPlayer/MediaTitle.module.css +8 -0
  97. package/VideoPlayer/VideoPlayer.js +25 -24
  98. package/VirtualList/VirtualList.js +20 -18
  99. package/VirtualList/useSpotlight.js +1 -1
  100. package/fonts/Limestone_Icons.ttf +0 -0
  101. package/internal/AsyncRenderChildren/AsyncRenderChildren.js +9 -5
  102. package/internal/AsyncRenderChildren/tests/AsyncRenderChildren-specs.js +4 -1
  103. package/internal/DateTime/DateTime.module.css +3 -0
  104. package/internal/DateTime/DateTimeDecorator.js +5 -4
  105. package/internal/Panels/PanelsRouter.js +35 -29
  106. package/internal/Panels/useAutoFocus.js +10 -6
  107. package/internal/Panels/useFocusOnTransition.js +4 -3
  108. package/internal/Picker/Picker.js +7 -5
  109. package/internal/Picker/Picker.module.css +22 -0
  110. package/internal/Picker/SpottablePicker.js +15 -13
  111. package/internal/SharedStateDecorator/SharedStateDecorator.js +6 -4
  112. package/package.json +15 -12
  113. package/styles/colors.less +1 -0
  114. package/styles/variables.less +118 -26
  115. package/useScroll/HoverToScroll.js +15 -12
  116. package/useScroll/Scrollbar.js +14 -10
  117. package/useScroll/ScrollbarPlaceholder.js +4 -1
  118. package/useScroll/ScrollbarTrack.js +7 -5
  119. package/useScroll/useEvent.js +7 -2
  120. package/useScroll/useScroll.js +10 -2
@@ -35,7 +35,7 @@ jobs:
35
35
 
36
36
  - name: Clone and setup Enact CLI
37
37
  run: |
38
- git clone --branch=7.2.1 --depth 1 https://github.com/enactjs/cli ../cli
38
+ git clone --branch=develop --depth 1 https://github.com/enactjs/cli ../cli
39
39
  pushd ../cli
40
40
  npm install
41
41
  npm link
@@ -43,7 +43,7 @@ jobs:
43
43
 
44
44
  - name: Clone and setup Enact framework
45
45
  run: |
46
- git clone --branch=release/5.4.x.develop --depth 1 https://github.com/enactjs/enact ../enact
46
+ git clone --branch=develop --depth 1 https://github.com/enactjs/enact ../enact
47
47
  pushd ../enact
48
48
  npm install
49
49
  npm run lerna exec -- --ignore enact-sampler --concurrency 1 -- npm --no-package-lock install
@@ -22,6 +22,10 @@
22
22
  font-family: "Limestone";
23
23
  font-size: var(--primitive-font-size-48);
24
24
  }
25
+ .actionGuide:global(.largeText) .label {
26
+ font-size: var(--primitive-font-size-60);
27
+ line-height: 1.45833rem;
28
+ }
25
29
  .actionGuide:global(.neutral) .icon .icon {
26
30
  color: var(--semantic-color-on-background-actionguide);
27
31
  }
package/Alert/Alert.d.ts CHANGED
@@ -32,6 +32,15 @@ export class AlertImage extends React.Component<
32
32
  > {}
33
33
 
34
34
  export interface AlertBaseProps {
35
+ /**
36
+ * Sets the buttons layout direction.
37
+ *
38
+ * In `auto` mode, button direction follows UX defaults:
39
+ * * `overlay` - horizontal when there are exactly 2 buttons
40
+ * * `fullscreen` - horizontal when there are less than 3 buttons
41
+ * * otherwise vertical
42
+ */
43
+ buttonDirection?: "auto" | "horizontal" | "vertical";
35
44
  /**
36
45
  * Buttons to be included under the component.
37
46
  *
package/Alert/Alert.js CHANGED
@@ -24,7 +24,7 @@ var _Popup = _interopRequireDefault(require("../Popup"));
24
24
  var _AlertImage = _interopRequireDefault(require("./AlertImage"));
25
25
  var _AlertModule = _interopRequireDefault(require("./Alert.module.css"));
26
26
  var _jsxRuntime = require("react/jsx-runtime");
27
- var _excluded = ["buttons", "contentComponent", "children", "css", "id", "image", "overlayPosition", "title", "type"];
27
+ var _excluded = ["buttonDirection", "buttons", "contentComponent", "children", "css", "id", "image", "overlayPosition", "title", "type", "style"];
28
28
  /**
29
29
  * Limestone styled modal Alert components.
30
30
  *
@@ -56,6 +56,19 @@ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t =
56
56
  var AlertBase = exports.AlertBase = (0, _kind["default"])({
57
57
  name: 'Alert',
58
58
  propTypes: /** @lends limestone/Alert.AlertBase.prototype */{
59
+ /**
60
+ * Sets the buttons layout direction.
61
+ *
62
+ * In `auto` mode, button direction follows UX defaults:
63
+ * * `overlay` - horizontal when there are exactly 2 buttons
64
+ * * `fullscreen` - horizontal when there are less than 3 buttons
65
+ * * otherwise vertical
66
+ *
67
+ * @type {('auto'|'horizontal'|'vertical')}
68
+ * @default 'auto'
69
+ * @public
70
+ */
71
+ buttonDirection: _propTypes["default"].oneOf(['auto', 'horizontal', 'vertical']),
59
72
  /**
60
73
  * Buttons to be included under the component.
61
74
  *
@@ -171,6 +184,7 @@ var AlertBase = exports.AlertBase = (0, _kind["default"])({
171
184
  type: _propTypes["default"].oneOf(['fullscreen', 'overlay'])
172
185
  },
173
186
  defaultProps: {
187
+ buttonDirection: 'auto',
174
188
  open: false,
175
189
  overlayPosition: 'center',
176
190
  type: 'fullscreen'
@@ -212,7 +226,8 @@ var AlertBase = exports.AlertBase = (0, _kind["default"])({
212
226
  }
213
227
  },
214
228
  render: function render(_ref4) {
215
- var buttons = _ref4.buttons,
229
+ var buttonDirection = _ref4.buttonDirection,
230
+ buttons = _ref4.buttons,
216
231
  contentComponent = _ref4.contentComponent,
217
232
  children = _ref4.children,
218
233
  css = _ref4.css,
@@ -221,10 +236,25 @@ var AlertBase = exports.AlertBase = (0, _kind["default"])({
221
236
  overlayPosition = _ref4.overlayPosition,
222
237
  title = _ref4.title,
223
238
  type = _ref4.type,
239
+ style = _ref4.style,
224
240
  rest = _objectWithoutProperties(_ref4, _excluded);
225
241
  var fullscreen = type === 'fullscreen';
226
242
  var position = type === 'overlay' ? overlayPosition : type;
227
243
  var showTitle = fullscreen && title;
244
+ var buttonCount = _react.Children.toArray(buttons).filter(Boolean).length;
245
+ var resolvedButtonDirection = buttonDirection;
246
+ if (buttonDirection === 'auto') {
247
+ var useHorizontal = type === 'overlay' && buttonCount === 2 || type === 'fullscreen' && buttonCount < 3;
248
+ resolvedButtonDirection = useHorizontal ? 'horizontal' : 'vertical';
249
+ }
250
+ var overlayHorizontalButtons = type === 'overlay' && resolvedButtonDirection === 'horizontal';
251
+ var popupStyle = style;
252
+ if (overlayHorizontalButtons) {
253
+ var overlayHorizontalButtonCount = Math.max(1, Math.min(buttonCount, 4));
254
+ popupStyle = _objectSpread(_objectSpread({}, style), {}, {
255
+ '--alert-overlay-horizontal-button-count': overlayHorizontalButtonCount
256
+ });
257
+ }
228
258
  var ariaLabelledBy = (showTitle ? "".concat(id, "_title ") : '') + "".concat(id, "_content ").concat(id, "_buttons");
229
259
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
230
260
  "aria-owns": id,
@@ -235,6 +265,7 @@ var AlertBase = exports.AlertBase = (0, _kind["default"])({
235
265
  "aria-labelledby": ariaLabelledBy,
236
266
  css: css,
237
267
  position: position,
268
+ style: popupStyle,
238
269
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Layout["default"], {
239
270
  align: "center center",
240
271
  orientation: "vertical",
@@ -262,8 +293,8 @@ var AlertBase = exports.AlertBase = (0, _kind["default"])({
262
293
  shrink: true,
263
294
  className: css.buttonContainer,
264
295
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout["default"], {
265
- align: "center",
266
- orientation: "vertical",
296
+ align: "center center",
297
+ orientation: resolvedButtonDirection,
267
298
  id: "".concat(id, "_buttons"),
268
299
  children: buttons
269
300
  })
@@ -40,6 +40,7 @@
40
40
  .alert.overlay .buttonContainer {
41
41
  box-sizing: border-box;
42
42
  margin-top: var(--primitive-spacing-36);
43
+ padding: 0 var(--primitive-spacing-84);
43
44
  }
44
45
  .alert.overlay .content {
45
46
  align-self: stretch;
@@ -52,6 +53,7 @@
52
53
  word-break: keep-all;
53
54
  padding: 0 var(--primitive-spacing-84);
54
55
  margin: 0;
56
+ max-width: var(--alert-overlay-content-max-width, 23.5rem);
55
57
  }
56
58
  :global(.enact-locale-non-latin) .alert.overlay .content {
57
59
  font-family: "Limestone";
@@ -77,7 +79,16 @@
77
79
  word-break: normal;
78
80
  }
79
81
  .popup.overlay {
80
- width: 23.5rem;
82
+ box-sizing: border-box;
83
+ --alert-overlay-horizontal-button-count: 1;
84
+ --alert-overlay-horizontal-button-width: NaNrem + (2 * var(--primitive-spacing-36)));
85
+ --alert-overlay-horizontal-buttons-total-width: calc(var(--alert-overlay-horizontal-button-width) * var(--alert-overlay-horizontal-button-count));
86
+ --alert-overlay-width: max(1128px, var(--alert-overlay-horizontal-buttons-total-width));
87
+ --alert-overlay-content-horizontal-padding: var(--primitive-spacing-84);
88
+ --alert-overlay-content-max-width: calc(var(--alert-overlay-width) - (2 * var(--alert-overlay-content-horizontal-padding)));
89
+ width: var(--alert-overlay-width);
90
+ min-width: 23.5rem;
91
+ max-width: calc(100vw - 2 * var(--primitive-spacing-60));
81
92
  margin-left: auto;
82
93
  margin-right: auto;
83
94
  }
@@ -102,6 +102,60 @@ describe('Alert', function () {
102
102
  var expectedClass = 'thumbnail';
103
103
  expect(image).toHaveClass(expectedClass);
104
104
  });
105
+ test('should align buttons horizontally by default in fullscreen when button count is less than 3', function () {
106
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
107
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.Alert, {
108
+ open: true,
109
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("buttons", {
110
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
111
+ children: "yes"
112
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
113
+ children: "no"
114
+ })]
115
+ })
116
+ })
117
+ }));
118
+ var alert = _react.screen.getByRole('alert');
119
+ var buttonsLayout = alert.querySelector('[id$="_buttons"]');
120
+ expect(buttonsLayout).toHaveClass('horizontal');
121
+ });
122
+ test('should align buttons vertically by default in fullscreen when button count is 3', function () {
123
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
124
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.Alert, {
125
+ open: true,
126
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("buttons", {
127
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
128
+ children: "yes"
129
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
130
+ children: "no"
131
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
132
+ children: "later"
133
+ })]
134
+ })
135
+ })
136
+ }));
137
+ var alert = _react.screen.getByRole('alert');
138
+ var buttonsLayout = alert.querySelector('[id$="_buttons"]');
139
+ expect(buttonsLayout).toHaveClass('vertical');
140
+ });
141
+ test('should allow overriding button direction to vertical', function () {
142
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
143
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.Alert, {
144
+ open: true,
145
+ buttonDirection: "vertical",
146
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("buttons", {
147
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
148
+ children: "yes"
149
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
150
+ children: "no"
151
+ })]
152
+ })
153
+ })
154
+ }));
155
+ var alert = _react.screen.getByRole('alert');
156
+ var buttonsLayout = alert.querySelector('[id$="_buttons"]');
157
+ expect(buttonsLayout).toHaveClass('vertical');
158
+ });
105
159
  });
106
160
  describe('AlertOverlay specs', function () {
107
161
  test('should be rendered opened if open is set to true', function () {
@@ -201,4 +255,41 @@ describe('AlertOverlay specs', function () {
201
255
  var expectedClass = 'thumbnail';
202
256
  expect(image).toHaveClass(expectedClass);
203
257
  });
258
+ test('should align buttons horizontally by default in overlay when button count is 2', function () {
259
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
260
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.Alert, {
261
+ open: true,
262
+ type: "overlay",
263
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("buttons", {
264
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
265
+ size: "small",
266
+ children: "yes"
267
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
268
+ size: "small",
269
+ children: "no"
270
+ })]
271
+ })
272
+ })
273
+ }));
274
+ var alert = _react.screen.getByRole('alert');
275
+ var buttonsLayout = alert.querySelector('[id$="_buttons"]');
276
+ expect(buttonsLayout).toHaveClass('horizontal');
277
+ });
278
+ test('should align buttons vertically by default in overlay when button count is not 2', function () {
279
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(FloatingLayerController, {
280
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Alert.Alert, {
281
+ open: true,
282
+ type: "overlay",
283
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("buttons", {
284
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {
285
+ size: "small",
286
+ children: "yes"
287
+ })
288
+ })
289
+ })
290
+ }));
291
+ var alert = _react.screen.getByRole('alert');
292
+ var buttonsLayout = alert.querySelector('[id$="_buttons"]');
293
+ expect(buttonsLayout).toHaveClass('vertical');
294
+ });
204
295
  });
@@ -93,3 +93,24 @@
93
93
  :global(.enact-locale-ja) .bodyText {
94
94
  line-break: strict;
95
95
  }
96
+ .bodyText:global(.largeText) {
97
+ font-size: var(--primitive-font-size-72);
98
+ }
99
+ .bodyText:global(.largeText).small {
100
+ font-size: var(--primitive-font-size-66);
101
+ }
102
+ :global(.enact-locale-km) .bodyText:global(.largeText).small {
103
+ font-size: var(--primitive-font-size-60);
104
+ }
105
+ :global(.enact-locale-si) .bodyText:global(.largeText).small {
106
+ font-size: var(--primitive-font-size-60);
107
+ }
108
+ :global(.enact-locale-th) .bodyText:global(.largeText).small {
109
+ font-size: var(--primitive-font-size-60);
110
+ }
111
+ :global(.enact-locale-vi) .bodyText:global(.largeText).small {
112
+ font-size: var(--primitive-font-size-60);
113
+ }
114
+ :global(.enact-locale-non-latin) .bodyText:global(.largeText).small {
115
+ font-size: var(--primitive-font-size-60);
116
+ }
@@ -107,11 +107,26 @@ Motion Mixins
107
107
  font-weight: var(--primitive-font-weight-bold);
108
108
  }
109
109
  .button:global(.largeText) {
110
- font-size: var(--primitive-font-size-96);
111
- height: 4rem;
112
- min-width: 4rem;
113
- line-height: 3.75rem;
114
- --button-height: 4rem;
110
+ font-size: var(--primitive-font-size-72);
111
+ height: 2.75rem;
112
+ min-width: 2.75rem;
113
+ line-height: 2.5rem;
114
+ --button-height: 2.75rem;
115
+ }
116
+ .button:global(.largeText).red .client::before,
117
+ .button:global(.largeText).green .client::before,
118
+ .button:global(.largeText).yellow .client::before,
119
+ .button:global(.largeText).blue .client::before {
120
+ bottom: var(--primitive-spacing-12);
121
+ width: 1.5rem;
122
+ height: 0.625rem;
123
+ }
124
+ .button:global(.largeText).red:not(.minWidth) .client::before,
125
+ .button:global(.largeText).green:not(.minWidth) .client::before,
126
+ .button:global(.largeText).yellow:not(.minWidth) .client::before,
127
+ .button:global(.largeText).blue:not(.minWidth) .client::before {
128
+ width: 0.625rem;
129
+ height: 0.25rem;
115
130
  }
116
131
  .button.focusStatic {
117
132
  /* Defined to prevent global export */
@@ -169,10 +184,24 @@ Motion Mixins
169
184
  bottom: var(--primitive-spacing-12);
170
185
  left: 50%;
171
186
  width: 1.25rem;
172
- height: 0.25rem;
187
+ height: 0.5rem;
173
188
  border-radius: var(--semantic-radius-full);
174
189
  transform: translate(-50%, 50%);
175
190
  }
191
+ .button.red:not(.minWidth) .client::before,
192
+ .button.green:not(.minWidth) .client::before,
193
+ .button.yellow:not(.minWidth) .client::before,
194
+ .button.blue:not(.minWidth) .client::before {
195
+ width: 0.625rem;
196
+ height: 0.25rem;
197
+ }
198
+ .button.red:not(.minWidth):global(.largeText) .client::before,
199
+ .button.green:not(.minWidth):global(.largeText) .client::before,
200
+ .button.yellow:not(.minWidth):global(.largeText) .client::before,
201
+ .button.blue:not(.minWidth):global(.largeText) .client::before {
202
+ width: 0.625rem;
203
+ height: 0.25rem;
204
+ }
176
205
  .button.red.minWidth .icon,
177
206
  .button.green.minWidth .icon,
178
207
  .button.yellow.minWidth .icon,
@@ -280,7 +309,21 @@ Motion Mixins
280
309
  .button.small.blue .client::before {
281
310
  bottom: var(--primitive-spacing-12);
282
311
  width: 1.0625rem;
283
- height: 0.1875rem;
312
+ height: 0.4375rem;
313
+ }
314
+ .button.small.red:not(.minWidth) .client::before,
315
+ .button.small.green:not(.minWidth) .client::before,
316
+ .button.small.yellow:not(.minWidth) .client::before,
317
+ .button.small.blue:not(.minWidth) .client::before {
318
+ width: 0.625rem;
319
+ height: 0.25rem;
320
+ }
321
+ .button.small.red:not(.minWidth):global(.largeText) .client::before,
322
+ .button.small.green:not(.minWidth):global(.largeText) .client::before,
323
+ .button.small.yellow:not(.minWidth):global(.largeText) .client::before,
324
+ .button.small.blue:not(.minWidth):global(.largeText) .client::before {
325
+ width: 0.625rem;
326
+ height: 0.25rem;
284
327
  }
285
328
  .button.small.red.minWidth .client,
286
329
  .button.small.green.minWidth .client,
@@ -316,20 +359,34 @@ Motion Mixins
316
359
  margin-inline-start: var(--primitive-spacing-24);
317
360
  }
318
361
  .button.small:global(.largeText) {
319
- font-size: var(--primitive-font-size-72);
320
- height: 3rem;
321
- min-width: 3rem;
322
- line-height: 2.75rem;
323
- --button-height: 3rem;
362
+ font-size: var(--primitive-font-size-66);
363
+ height: 2.25rem;
364
+ min-width: 2.25rem;
365
+ line-height: 2rem;
366
+ --button-height: 2.25rem;
324
367
  }
325
368
  .button.small:global(.largeText).minWidth {
326
369
  min-width: 15rem;
327
370
  }
371
+ .button.small:global(.largeText).red .client::before,
372
+ .button.small:global(.largeText).green .client::before,
373
+ .button.small:global(.largeText).yellow .client::before,
374
+ .button.small:global(.largeText).blue .client::before {
375
+ width: 1.25rem;
376
+ height: 0.5rem;
377
+ }
378
+ .button.small:global(.largeText).red:not(.minWidth) .client::before,
379
+ .button.small:global(.largeText).green:not(.minWidth) .client::before,
380
+ .button.small:global(.largeText).yellow:not(.minWidth) .client::before,
381
+ .button.small:global(.largeText).blue:not(.minWidth) .client::before {
382
+ width: 0.625rem;
383
+ height: 0.25rem;
384
+ }
328
385
  .button.iconOnly {
329
386
  min-width: 2.75rem;
330
387
  }
331
388
  .button.iconOnly:global(.largeText) {
332
- min-width: 4rem;
389
+ min-width: 2.75rem;
333
390
  }
334
391
  .button.iconOnly .client {
335
392
  padding: 0;
@@ -357,7 +414,7 @@ Motion Mixins
357
414
  padding-right: 0.375rem;
358
415
  }
359
416
  .button.iconOnly.small:global(.largeText) {
360
- min-width: 3rem;
417
+ min-width: 2.25rem;
361
418
  }
362
419
  .button.iconOnly.iconAfter .icon,
363
420
  .button.iconOnly.iconBefore .icon,
@@ -369,34 +426,9 @@ Motion Mixins
369
426
  .button.iconOnly.iconBefore .icon:global(.largeText),
370
427
  .button.iconOnly.large .icon:global(.largeText),
371
428
  .button.iconOnly.small .icon:global(.largeText) {
429
+ overflow: visible;
372
430
  width: 100%;
373
431
  }
374
- .button.iconOnly.iconAfter.red .client::before,
375
- .button.iconOnly.iconBefore.red .client::before,
376
- .button.iconOnly.large.red .client::before,
377
- .button.iconOnly.small.red .client::before,
378
- .button.iconOnly.iconAfter.green .client::before,
379
- .button.iconOnly.iconBefore.green .client::before,
380
- .button.iconOnly.large.green .client::before,
381
- .button.iconOnly.small.green .client::before,
382
- .button.iconOnly.iconAfter.yellow .client::before,
383
- .button.iconOnly.iconBefore.yellow .client::before,
384
- .button.iconOnly.large.yellow .client::before,
385
- .button.iconOnly.small.yellow .client::before,
386
- .button.iconOnly.iconAfter.blue .client::before,
387
- .button.iconOnly.iconBefore.blue .client::before,
388
- .button.iconOnly.large.blue .client::before,
389
- .button.iconOnly.small.blue .client::before {
390
- width: 1.375rem;
391
- height: 0.1875rem;
392
- }
393
- .button.iconOnly.red .client::before,
394
- .button.iconOnly.green .client::before,
395
- .button.iconOnly.yellow .client::before,
396
- .button.iconOnly.blue .client::before {
397
- width: 1.375rem;
398
- height: 0.1875rem;
399
- }
400
432
  .button.collapsable.hasIcon:not(.iconOnly) {
401
433
  padding-left: 0;
402
434
  padding-right: 0;
@@ -30,6 +30,32 @@ describe('Button', function () {
30
30
  var expected = 'focusExpand';
31
31
  expect(button).toHaveClass(expected);
32
32
  });
33
+ test('should be pressed when selected', function () {
34
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button["default"], {}));
35
+ var button = _react.screen.getByRole('button');
36
+
37
+ // Select by key
38
+ _react.fireEvent.keyDown(button, {
39
+ key: 'Enter',
40
+ code: 'Enter',
41
+ keyCode: 13,
42
+ which: 13
43
+ });
44
+ expect(button).toHaveClass('pressed');
45
+ _react.fireEvent.keyUp(button, {
46
+ key: 'Enter',
47
+ code: 'Enter',
48
+ keyCode: 13,
49
+ which: 13
50
+ });
51
+ expect(button).not.toHaveClass('pressed');
52
+
53
+ // Select by pointer
54
+ _react.fireEvent.mouseDown(button);
55
+ expect(button).toHaveClass('pressed');
56
+ _react.fireEvent.mouseUp(button);
57
+ expect(button).not.toHaveClass('pressed');
58
+ });
33
59
  test('should be able to disable the expand focus effect', function () {
34
60
  (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.ButtonBase, {
35
61
  focusEffect: "static"
package/CHANGELOG.md CHANGED
@@ -2,6 +2,80 @@
2
2
 
3
3
  The following is a curated list of changes in the Enact limestone module, newest changes on the top.
4
4
 
5
+ ## [1.10.1] - 2026-06-01
6
+
7
+ ### Changed
8
+
9
+ - `limestone/ActionGuide` styling to match the latest GUI
10
+ - `limestone/BodyText` styling to match the latest GUI
11
+ - `limestone/Button` styling to match the latest GUI
12
+ - `limestone/Card` styling to match the latest GUI
13
+ - `limestone/Checkbox` styling to match the latest GUI
14
+ - `limestone/Chips.Chip` styling to match the latest GUI
15
+ - `limestone/DatePicker` styling to match the latest GUI
16
+ - `limestone/Heading` styling to match the latest GUI
17
+ - `limestone/Icon` styling to match the latest GUI
18
+ - `limestone/IconItem` styling to match the latest GUI
19
+ - `limestone/ImageItem` styling to match the latest GUI
20
+ - `limestone/Input` styling to match the latest GUI
21
+ - `limestone/InputField` styling to match the latest GUI
22
+ - `limestone/Item` styling to match the latest GUI
23
+ - `limestone/KeyGuide` styling to match the latest GUI
24
+ - `limestone/MediaOverlay` styling to match the latest GUI
25
+ - `limestone/PageViews` styling to match the latest GUI
26
+ - `limestone/Panels.Header` styling to match the latest GUI
27
+ - `limestone/Picker` styling to match the latest GUI
28
+ - `limestone/PopupTabLayout` styling to match the latest GUI
29
+ - `limestone/RadioItem` styling to match the latest GUI
30
+ - `limestone/Scroller` focus area to be separated from the vertical and horizontal scrollbars when `focusableScrollbar` is `"byEnter"`
31
+ - `limestone/Slider` styling to match the latest GUI
32
+ - `limestone/Steps` styling to match the latest GUI
33
+ - `limestone/Switch` styling to match the latest GUI
34
+ - `limestone/TabLayout` styling to match the latest GUI
35
+ - `limestone/TimePicker` styling to match the latest GUI
36
+ - `limestone/TooltipDecorator` styling to match the latest GUI
37
+ - `limestone/VideoPlayer` styling to match the latest GUI
38
+
39
+ ### Fixed
40
+
41
+ - `limestone/Scroller` to set initial focus on the scrollbar thumb when navigating between panels with `focusableScrollbar`
42
+
43
+
44
+ ## [1.10.0] - 2026-05-08
45
+
46
+ ### Added
47
+
48
+ - `limestone/Alert` `buttonDirection` prop to control button layout direction (`auto`, `horizontal`, `vertical`)
49
+ - `limestone/Icon` supported icon list, adding new icon `f1`
50
+ - `limestone/Input` props `marqueeInputField` to marquee inputField text on focus
51
+ - `limestone/Inputfield` prop `caretToEndOnFocus` to move caret to the end of the input field on input activation via 5-way
52
+ - `limestone/Inputfield` prop `marqueeContent` to marquee text on focus
53
+ - `limestone/PageViews` `showFooterButtons` prop to show optional Close/Next buttons
54
+ - `limestone/PageViews` `footerCloseLabel` prop to custom the Close button label
55
+ - `limestone/PageViews` `onFooterCloseClick` prop to custom the Close button behavior when it is clicked
56
+ - `limestone/Slider` `colorPicker` prop to change slider functionality
57
+ - `limestone/ThemeDecorator` config `focusEffectClass` to support customization for spottable components
58
+
59
+ ### Changed
60
+
61
+ - `limestone/Slider` styling to match the latest GUI
62
+ - `@storybook/addon-docs` version to `^10.3.4`.
63
+ - `@storybook/react-webpack5` version to `^10.3.4`.
64
+ - `storybook` version to `^10.3.4`.
65
+
66
+ ### Fixed
67
+
68
+ - `limestone/Card` `captionOverlayOnFocus` prop to work in `focusRing` mode
69
+ - `limestone/Card` press motion to work with key press
70
+ - `limestone/Dropdown` button to match `DropdownList` items size when `size` is `small`
71
+ - `limestone/IconItem` press motion to work with key press
72
+ - `limestone/MediaOverlay` press motion to work with key press
73
+ - `limestone/Popup` to not flicker on transition
74
+ - `limestone/Popup` to not delay when closed with pointer
75
+ - `limestone/Scroller.EditableWrapper` to not stop the `Marquee` when editing is complete
76
+ - `limestone/Slider` press motion to work with key press
77
+ - `limestone/useScroll` to not scroll on hover right after scroll by wheel
78
+
5
79
  ## [1.9.3] - 2026-04-20
6
80
 
7
81
  ### Fixed
package/Card/Card.d.ts CHANGED
@@ -10,10 +10,6 @@ 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
12
  export interface CardBaseProps extends ui_Card_CardProps {
13
- /**
14
- * The primary caption displayed with the image.
15
- */
16
- children: string;
17
13
  /**
18
14
  * Source for the image.
19
15
  String value or Object of values used to determine which image will appear on
@@ -38,6 +34,10 @@ It only applies when `orientation` is `'vertical'` .
38
34
  * Centers the captions when `imageIconSrc` is not provided.
39
35
  */
40
36
  centered?: boolean;
37
+ /**
38
+ * The primary caption displayed with the image.
39
+ */
40
+ children?: string;
41
41
  /**
42
42
  * Customizes the component by mapping the supplied collection of CSS class names to the
43
43
  corresponding internal elements and states of this component.
package/Card/Card.js CHANGED
@@ -72,14 +72,6 @@ var getDefaultImageSize = function getDefaultImageSize(orientation) {
72
72
  var CardBase = exports.CardBase = (0, _kind["default"])({
73
73
  name: 'Card',
74
74
  propTypes: /** @lends limestone/Card.CardBase.prototype */{
75
- /**
76
- * The primary caption displayed with the image.
77
- *
78
- * @type {String}
79
- * @required
80
- * @public
81
- */
82
- children: _propTypes["default"].string.isRequired,
83
75
  /**
84
76
  * Source for the image.
85
77
  * String value or Object of values used to determine which image will appear on
@@ -120,6 +112,13 @@ var CardBase = exports.CardBase = (0, _kind["default"])({
120
112
  * @public
121
113
  */
122
114
  centered: _propTypes["default"].bool,
115
+ /**
116
+ * The primary caption displayed with the image.
117
+ *
118
+ * @type {String}
119
+ * @public
120
+ */
121
+ children: _propTypes["default"].string,
123
122
  /**
124
123
  * Customizes the component by mapping the supplied collection of CSS class names to the
125
124
  * corresponding internal elements and states of this component.
@@ -419,10 +418,12 @@ var CardBase = exports.CardBase = (0, _kind["default"])({
419
418
  var captionOverlay = _ref4.captionOverlay,
420
419
  captionOverlayOnFocus = _ref4.captionOverlayOnFocus,
421
420
  icon = _ref4.icon,
421
+ label = _ref4.label,
422
422
  pressed = _ref4.pressed,
423
423
  roundedImage = _ref4.roundedImage,
424
424
  hasContainer = _ref4.hasContainer,
425
425
  orientation = _ref4.orientation,
426
+ secondaryLabel = _ref4.secondaryLabel,
426
427
  styler = _ref4.styler;
427
428
  return styler.append({
428
429
  captionOverlay: captionOverlay && orientation === 'vertical',
@@ -430,6 +431,7 @@ var CardBase = exports.CardBase = (0, _kind["default"])({
430
431
  pressed: pressed,
431
432
  roundedImage: roundedImage,
432
433
  hasContainer: orientation === 'horizontal' || hasContainer && !captionOverlay,
434
+ hasLabel: orientation === 'vertical' && label && secondaryLabel,
433
435
  isCheckIcon: icon === 'check'
434
436
  });
435
437
  },