@douyinfe/semi-foundation 2.14.0-beta.2 → 2.15.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 (91) hide show
  1. package/cascader/cascader.scss +20 -0
  2. package/cascader/foundation.ts +21 -0
  3. package/cascader/variables.scss +2 -0
  4. package/checkbox/checkbox.scss +9 -9
  5. package/checkbox/checkboxFoundation.ts +1 -0
  6. package/datePicker/foundation.ts +32 -8
  7. package/datePicker/monthsGridFoundation.ts +1 -2
  8. package/dropdown/dropdown.scss +4 -0
  9. package/dropdown/foundation.ts +38 -1
  10. package/dropdown/menuFoundation.ts +77 -0
  11. package/lib/cjs/cascader/cascader.css +15 -0
  12. package/lib/cjs/cascader/cascader.scss +20 -0
  13. package/lib/cjs/cascader/foundation.d.ts +6 -0
  14. package/lib/cjs/cascader/foundation.js +23 -0
  15. package/lib/cjs/cascader/variables.scss +2 -0
  16. package/lib/cjs/checkbox/checkbox.css +5 -5
  17. package/lib/cjs/checkbox/checkbox.scss +9 -9
  18. package/lib/cjs/checkbox/checkboxFoundation.d.ts +1 -0
  19. package/lib/cjs/datePicker/foundation.d.ts +7 -0
  20. package/lib/cjs/datePicker/foundation.js +38 -7
  21. package/lib/cjs/datePicker/monthsGridFoundation.js +1 -4
  22. package/lib/cjs/dropdown/dropdown.css +4 -0
  23. package/lib/cjs/dropdown/dropdown.scss +4 -0
  24. package/lib/cjs/dropdown/foundation.d.ts +4 -0
  25. package/lib/cjs/dropdown/foundation.js +48 -0
  26. package/lib/cjs/dropdown/menuFoundation.d.ts +9 -0
  27. package/lib/cjs/dropdown/menuFoundation.js +119 -0
  28. package/lib/cjs/list/list.css +1 -1
  29. package/lib/cjs/list/list.scss +1 -1
  30. package/lib/cjs/list/variables.scss +2 -1
  31. package/lib/cjs/modal/modalFoundation.d.ts +1 -0
  32. package/lib/cjs/rating/foundation.d.ts +13 -0
  33. package/lib/cjs/rating/foundation.js +123 -35
  34. package/lib/cjs/rating/rating.css +14 -5
  35. package/lib/cjs/rating/rating.scss +21 -8
  36. package/lib/cjs/rating/variables.scss +4 -0
  37. package/lib/cjs/tabs/foundation.js +28 -6
  38. package/lib/cjs/tooltip/foundation.js +39 -9
  39. package/lib/cjs/tree/foundation.d.ts +1 -0
  40. package/lib/cjs/treeSelect/foundation.js +9 -1
  41. package/lib/cjs/utils/FocusHandle.d.ts +1 -0
  42. package/lib/cjs/utils/FocusHandle.js +6 -1
  43. package/lib/cjs/utils/a11y.d.ts +9 -0
  44. package/lib/cjs/utils/a11y.js +123 -0
  45. package/lib/es/cascader/cascader.css +15 -0
  46. package/lib/es/cascader/cascader.scss +20 -0
  47. package/lib/es/cascader/foundation.d.ts +6 -0
  48. package/lib/es/cascader/foundation.js +23 -0
  49. package/lib/es/cascader/variables.scss +2 -0
  50. package/lib/es/checkbox/checkbox.css +5 -5
  51. package/lib/es/checkbox/checkbox.scss +9 -9
  52. package/lib/es/checkbox/checkboxFoundation.d.ts +1 -0
  53. package/lib/es/datePicker/foundation.d.ts +7 -0
  54. package/lib/es/datePicker/foundation.js +37 -7
  55. package/lib/es/datePicker/monthsGridFoundation.js +1 -3
  56. package/lib/es/dropdown/dropdown.css +4 -0
  57. package/lib/es/dropdown/dropdown.scss +4 -0
  58. package/lib/es/dropdown/foundation.d.ts +4 -0
  59. package/lib/es/dropdown/foundation.js +45 -0
  60. package/lib/es/dropdown/menuFoundation.d.ts +9 -0
  61. package/lib/es/dropdown/menuFoundation.js +99 -0
  62. package/lib/es/list/list.css +1 -1
  63. package/lib/es/list/list.scss +1 -1
  64. package/lib/es/list/variables.scss +2 -1
  65. package/lib/es/modal/modalFoundation.d.ts +1 -0
  66. package/lib/es/rating/foundation.d.ts +13 -0
  67. package/lib/es/rating/foundation.js +116 -32
  68. package/lib/es/rating/rating.css +14 -5
  69. package/lib/es/rating/rating.scss +21 -8
  70. package/lib/es/rating/variables.scss +4 -0
  71. package/lib/es/tabs/foundation.js +30 -6
  72. package/lib/es/tooltip/foundation.js +38 -9
  73. package/lib/es/tree/foundation.d.ts +1 -0
  74. package/lib/es/treeSelect/foundation.js +9 -1
  75. package/lib/es/utils/FocusHandle.d.ts +1 -0
  76. package/lib/es/utils/FocusHandle.js +6 -1
  77. package/lib/es/utils/a11y.d.ts +9 -0
  78. package/lib/es/utils/a11y.js +101 -0
  79. package/list/list.scss +1 -1
  80. package/list/variables.scss +2 -1
  81. package/modal/modalFoundation.ts +1 -0
  82. package/package.json +2 -2
  83. package/rating/foundation.ts +90 -31
  84. package/rating/rating.scss +21 -8
  85. package/rating/variables.scss +4 -0
  86. package/tabs/foundation.ts +9 -6
  87. package/tooltip/foundation.ts +16 -8
  88. package/tree/foundation.ts +1 -0
  89. package/treeSelect/foundation.ts +5 -1
  90. package/utils/FocusHandle.ts +3 -1
  91. package/utils/a11y.ts +105 -0
@@ -1,3 +1,4 @@
1
+ import _isFunction from "lodash/isFunction";
1
2
  import _isEqual from "lodash/isEqual";
2
3
  import _isString from "lodash/isString";
3
4
  import _isObject from "lodash/isObject";
@@ -135,6 +136,27 @@ export default class DatePickerFoundation extends BaseFoundation {
135
136
  this._adapter.updateValue(result);
136
137
 
137
138
  this.resetCachedSelectedValue(result);
139
+ this.initRangeInputFocus(result);
140
+
141
+ if (this._adapter.needConfirm()) {
142
+ this._adapter.updateCachedSelectedValue(result);
143
+ }
144
+ }
145
+ /**
146
+ * 如果用户传了一个空的 value,需要把 range input focus 设置为 rangeStart,这样用户可以清除完之后继续从开始选择
147
+ *
148
+ * If the user passes an empty value, you need to set the range input focus to rangeStart, so that the user can continue to select from the beginning after clearing
149
+ */
150
+
151
+
152
+ initRangeInputFocus(result) {
153
+ const {
154
+ triggerRender
155
+ } = this.getProps();
156
+
157
+ if (this._isRangeType() && _isFunction(triggerRender) && result.length === 0) {
158
+ this._adapter.setRangeInputFocus('rangeStart');
159
+ }
138
160
  }
139
161
 
140
162
  parseWithTimezone(value, timeZone, prevTimeZone) {
@@ -1392,7 +1414,8 @@ export default class DatePickerFoundation extends BaseFoundation {
1392
1414
 
1393
1415
  handleTriggerWrapperClick(e) {
1394
1416
  const {
1395
- disabled
1417
+ disabled,
1418
+ triggerRender
1396
1419
  } = this._adapter.getProps();
1397
1420
 
1398
1421
  const {
@@ -1411,12 +1434,19 @@ export default class DatePickerFoundation extends BaseFoundation {
1411
1434
  */
1412
1435
 
1413
1436
 
1414
- if (this._isRangeType() && !rangeInputFocus && this._adapter.isEventTarget(e)) {
1415
- _setTimeout(() => {
1416
- // using setTimeout get correct state value 'rangeInputFocus'
1417
- this.handleInputFocus(e, 'rangeStart');
1418
- this.openPanel();
1419
- }, 0);
1437
+ if (this._isRangeType() && !rangeInputFocus) {
1438
+ if (this._adapter.isEventTarget(e)) {
1439
+ _setTimeout(() => {
1440
+ // using setTimeout get correct state value 'rangeInputFocus'
1441
+ this.handleInputFocus(e, 'rangeStart');
1442
+ }, 0);
1443
+ } else if (_isFunction(triggerRender)) {
1444
+ // 如果是 triggerRender 场景,因为没有 input,因此打开面板时默认 focus 在 rangeStart
1445
+ // If it is a triggerRender scene, because there is no input, the default focus is rangeStart when the panel is opened
1446
+ this._adapter.setRangeInputFocus('rangeStart');
1447
+ }
1448
+
1449
+ this.openPanel();
1420
1450
  } else {
1421
1451
  this.openPanel();
1422
1452
  }
@@ -1,4 +1,3 @@
1
- import _isFunction from "lodash/isFunction";
2
1
  import _isEqual from "lodash/isEqual";
3
2
  import _isSet from "lodash/isSet";
4
3
  import _includes from "lodash/includes";
@@ -800,11 +799,10 @@ export default class MonthsGridFoundation extends BaseFoundation {
800
799
  /**
801
800
  * no need to check focus then
802
801
  * - dateRange and isDateRangeAndHasOffset
803
- * - dateRange and triggerRender
804
802
  */
805
803
 
806
804
 
807
- const needCheckFocusRecord = !(type === 'dateRange' && (isDateRangeAndHasOffset || _isFunction(triggerRender)));
805
+ const needCheckFocusRecord = !(type === 'dateRange' && isDateRangeAndHasOffset);
808
806
 
809
807
  this._adapter.notifySelectedChange(date, {
810
808
  needCheckFocusRecord
@@ -53,6 +53,10 @@
53
53
  .semi-dropdown-item:not(.semi-dropdown-item-active):active {
54
54
  background-color: var(--semi-color-fill-1);
55
55
  }
56
+ .semi-dropdown-item:focus-visible {
57
+ background-color: var(--semi-color-fill-0);
58
+ outline: 0;
59
+ }
56
60
  .semi-dropdown-item-icon {
57
61
  display: inline-flex;
58
62
  align-items: center;
@@ -50,6 +50,10 @@ $module: #{$prefix}-dropdown;
50
50
  &:not(.#{$module}-item-active):active {
51
51
  background-color: $color-dropdown_item-bg-active;
52
52
  }
53
+ &:focus-visible {
54
+ background-color: $color-dropdown_item-bg-hover;
55
+ outline: 0;
56
+ }
53
57
  &-icon {
54
58
  display: inline-flex;
55
59
  align-items: center;
@@ -5,4 +5,8 @@ export interface DropdownAdapter extends Partial<DefaultAdapter> {
5
5
  }
6
6
  export default class DropdownFoundation extends BaseFoundation<DropdownAdapter> {
7
7
  handleVisibleChange(visible: boolean): void;
8
+ getMenuItemNodes(target: any): HTMLElement[];
9
+ setFocusToFirstMenuItem(target: any): void;
10
+ setFocusToLastMenuItem(target: any): void;
11
+ handleKeyDown(event: any): void;
8
12
  }
@@ -1,4 +1,7 @@
1
+ import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
2
+ import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
1
3
  import BaseFoundation from '../base/foundation';
4
+ import { handlePrevent, setFocusToFirstItem, setFocusToLastItem } from '../utils/a11y';
2
5
  export default class DropdownFoundation extends BaseFoundation {
3
6
  handleVisibleChange(visible) {
4
7
  this._adapter.setPopVisible(visible);
@@ -6,4 +9,46 @@ export default class DropdownFoundation extends BaseFoundation {
6
9
  this._adapter.notifyVisibleChange(visible);
7
10
  }
8
11
 
12
+ getMenuItemNodes(target) {
13
+ var _context;
14
+
15
+ const id = target.attributes['data-popupId'].value;
16
+ const menuWrapper = document.getElementById(id); // if has dropdown item, the item must wrapped by li
17
+
18
+ return menuWrapper ? _filterInstanceProperty(_context = _Array$from(menuWrapper.getElementsByTagName('li'))).call(_context, item => item.ariaDisabled === "false") : null;
19
+ }
20
+
21
+ setFocusToFirstMenuItem(target) {
22
+ const menuItemNodes = this.getMenuItemNodes(target);
23
+ menuItemNodes && setFocusToFirstItem(menuItemNodes);
24
+ }
25
+
26
+ setFocusToLastMenuItem(target) {
27
+ const menuItemNodes = this.getMenuItemNodes(target);
28
+ menuItemNodes && setFocusToLastItem(menuItemNodes);
29
+ }
30
+
31
+ handleKeyDown(event) {
32
+ switch (event.key) {
33
+ case ' ':
34
+ case 'Enter':
35
+ event.target.click();
36
+ handlePrevent(event);
37
+ break;
38
+
39
+ case 'ArrowDown':
40
+ this.setFocusToFirstMenuItem(event.target);
41
+ handlePrevent(event);
42
+ break;
43
+
44
+ case 'ArrowUp':
45
+ this.setFocusToLastMenuItem(event.target);
46
+ handlePrevent(event);
47
+ break;
48
+
49
+ default:
50
+ break;
51
+ }
52
+ }
53
+
9
54
  }
@@ -0,0 +1,9 @@
1
+ import BaseFoundation, { DefaultAdapter } from '../base/foundation';
2
+ export default class DropdownMenuFoundation extends BaseFoundation<Partial<DefaultAdapter>> {
3
+ menuItemNodes: HTMLElement[];
4
+ firstChars: string[];
5
+ autoFocus(ulElement: any): void;
6
+ handleEscape(menu: Element): void;
7
+ setFocusByFirstCharacter(curItem: any, char: string): void;
8
+ onMenuKeydown(event: any): void;
9
+ }
@@ -0,0 +1,99 @@
1
+ import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
2
+ import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
3
+ import _trimInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/trim";
4
+ import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find";
5
+ import BaseFoundation from '../base/foundation';
6
+ import { handlePrevent, isPrintableCharacter, findIndexByCharacter, getAncestorNodeByRole, getMenuButton, setFocusToFirstItem, setFocusToItem, setFocusToNextMenuitem, setFocusToPreviousMenuItem } from '../utils/a11y';
7
+ export default class DropdownMenuFoundation extends BaseFoundation {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.menuItemNodes = null;
11
+ this.firstChars = [];
12
+ } // if trigger is click, auto focus to the first menu item
13
+
14
+
15
+ autoFocus(ulElement) {
16
+ const trigger = this._adapter.getContext('trigger');
17
+
18
+ if (trigger === 'click') {
19
+ var _context;
20
+
21
+ // find all non-disabled li under this menu and set focus to the first menu
22
+ this.menuItemNodes = _filterInstanceProperty(_context = [...ulElement.getElementsByTagName('li')]).call(_context, item => item.ariaDisabled !== "true");
23
+ setFocusToFirstItem(this.menuItemNodes);
24
+ }
25
+ }
26
+
27
+ handleEscape(menu) {
28
+ const trigger = this._adapter.getContext('trigger');
29
+
30
+ if (trigger === 'custom') {
31
+ const menuButton = menu && getMenuButton(document.querySelectorAll("[data-popupId]"), menu.id);
32
+ menuButton.focus();
33
+ }
34
+ }
35
+
36
+ setFocusByFirstCharacter(curItem, char) {
37
+ const index = findIndexByCharacter(this.menuItemNodes, curItem, this.firstChars, char);
38
+
39
+ if (index >= 0) {
40
+ setFocusToItem(this.menuItemNodes, this.menuItemNodes[index]);
41
+ }
42
+ }
43
+
44
+ onMenuKeydown(event) {
45
+ var _context5;
46
+
47
+ const menu = getAncestorNodeByRole(event.target, 'tooltip');
48
+
49
+ if (!this.menuItemNodes) {
50
+ var _context2;
51
+
52
+ this.menuItemNodes = _filterInstanceProperty(_context2 = [...event.target.parentNode.getElementsByTagName('li')]).call(_context2, item => item.ariaDisabled !== "true");
53
+ }
54
+
55
+ if (this.firstChars.length === 0) {
56
+ var _context3;
57
+
58
+ _forEachInstanceProperty(_context3 = this.menuItemNodes).call(_context3, item => {
59
+ var _context4;
60
+
61
+ this.firstChars.push(_trimInstanceProperty(_context4 = item.textContent).call(_context4)[0].toLowerCase());
62
+ });
63
+ } // get the currently focused menu item
64
+
65
+
66
+ const curItem = _findInstanceProperty(_context5 = this.menuItemNodes).call(_context5, item => item.tabIndex === 0);
67
+
68
+ switch (event.key) {
69
+ case ' ':
70
+ case 'Enter':
71
+ event.target.click();
72
+ handlePrevent(event);
73
+ break;
74
+
75
+ case 'Escape':
76
+ this.handleEscape(menu);
77
+ break;
78
+
79
+ case 'ArrowUp':
80
+ setFocusToPreviousMenuItem(this.menuItemNodes, curItem);
81
+ handlePrevent(event);
82
+ break;
83
+
84
+ case 'ArrowDown':
85
+ setFocusToNextMenuitem(this.menuItemNodes, curItem);
86
+ handlePrevent(event);
87
+ break;
88
+
89
+ default:
90
+ if (isPrintableCharacter(event.key)) {
91
+ this.setFocusByFirstCharacter(curItem, event.key);
92
+ handlePrevent(event);
93
+ }
94
+
95
+ break;
96
+ }
97
+ }
98
+
99
+ }
@@ -15,7 +15,7 @@
15
15
  padding: 12px 24px;
16
16
  }
17
17
  .semi-list-empty {
18
- padding: 12px;
18
+ padding: 12px 0px;
19
19
  color: var(--semi-color-text-2);
20
20
  width: 100%;
21
21
  text-align: center;
@@ -17,7 +17,7 @@ $module: #{$prefix}-list;
17
17
  }
18
18
 
19
19
  &-empty {
20
- padding: $spacing-list_empty-padding;
20
+ padding: $spacing-list_empty-paddingY $spacing-list_empty-paddingX;
21
21
  color: $color-list_empty-text-default;
22
22
  width: 100%;
23
23
  text-align: center;
@@ -1,7 +1,8 @@
1
1
  $color-list_default-border-default: var(--semi-color-border); // 列表描边颜色
2
2
  $color-list_empty-text-default: var(--semi-color-text-2); // 空状态下列表文字颜色
3
3
 
4
- $spacing-list_empty-padding: $spacing-base-tight; // 空状态列表内边距
4
+ $spacing-list_empty-paddingX: 0px; // 空状态列表水平内边距
5
+ $spacing-list_empty-paddingY: $spacing-base-tight; // 空状态列表垂直内边距
5
6
  $spacing-list_footer-paddingX: $spacing-base-tight; // 列表 footer 水平内边距
6
7
  $spacing-list_footer-paddingY: $spacing-loose; // 列表 footer 垂直内边距
7
8
  $spacing-list_item-paddingX: $spacing-base-tight; // 列表 item 水平内边距 - 默认尺寸
@@ -51,6 +51,7 @@ export interface ModalProps {
51
51
  keepDOM?: boolean;
52
52
  direction?: any;
53
53
  fullScreen?: boolean;
54
+ preventScroll?: boolean;
54
55
  }
55
56
  export interface ModalState {
56
57
  hidden: boolean;
@@ -8,6 +8,7 @@ export interface RatingAdapter<P = Record<string, any>, S = Record<string, any>>
8
8
  notifyFocus: (e: any) => void;
9
9
  notifyBlur: (e: any) => void;
10
10
  notifyKeyDown: (e: any) => void;
11
+ setEmptyStarFocusVisible: (focusVisible: boolean) => void;
11
12
  }
12
13
  export default class RatingFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<RatingAdapter<P, S>, P, S> {
13
14
  constructor(adapter: RatingAdapter<P, S>);
@@ -25,4 +26,16 @@ export default class RatingFoundation<P = Record<string, any>, S = Record<string
25
26
  handleFocus(e: any): void;
26
27
  handleBlur(e: any): void;
27
28
  handleKeyDown(event: any, value: number): void;
29
+ changeFocusStar(value: number, event: any): void;
30
+ handleStarFocusVisible: (event: any) => void;
31
+ handleStarBlur: (event: React.FocusEvent) => void;
32
+ }
33
+ export interface RatingItemAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
34
+ setFirstStarFocus: (value: boolean) => void;
35
+ setSecondStarFocus: (value: boolean) => void;
36
+ }
37
+ export declare class RatingItemFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<RatingItemAdapter<P, S>, P, S> {
38
+ constructor(adapter: RatingItemAdapter<P, S>);
39
+ handleFocusVisible: (event: any, star: string) => void;
40
+ handleBlur: (event: React.FocusEvent, star: string) => void;
28
41
  }
@@ -1,14 +1,40 @@
1
1
  import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign";
2
+ import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
3
+ import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
2
4
 
3
5
  /* eslint-disable no-param-reassign */
4
6
  import BaseFoundation from '../base/foundation';
5
- const KeyCode = {
6
- LEFT: 37,
7
- RIGHT: 39
8
- };
7
+ import warning from '../utils/warning';
9
8
  export default class RatingFoundation extends BaseFoundation {
10
9
  constructor(adapter) {
11
10
  super(_Object$assign(_Object$assign({}, RatingFoundation.defaultAdapter), adapter));
11
+
12
+ this.handleStarFocusVisible = event => {
13
+ const {
14
+ target
15
+ } = event;
16
+ const {
17
+ count
18
+ } = this.getProps(); // when rating 0 is focus visible
19
+
20
+ try {
21
+ if (target.matches(':focus-visible')) {
22
+ this._adapter.setEmptyStarFocusVisible(true);
23
+ }
24
+ } catch (error) {
25
+ warning(true, 'Warning: [Semi Rating] The current browser does not support the focus-visible');
26
+ }
27
+ };
28
+
29
+ this.handleStarBlur = event => {
30
+ const {
31
+ emptyStarFocusVisible
32
+ } = this.getStates();
33
+
34
+ if (emptyStarFocusVisible) {
35
+ this._adapter.setEmptyStarFocusVisible(false);
36
+ }
37
+ };
12
38
  }
13
39
 
14
40
  init() {
@@ -138,8 +164,10 @@ export default class RatingFoundation extends BaseFoundation {
138
164
  }
139
165
 
140
166
  handleKeyDown(event, value) {
167
+ var _context;
168
+
141
169
  const {
142
- keyCode
170
+ key
143
171
  } = event;
144
172
  const {
145
173
  count,
@@ -149,38 +177,94 @@ export default class RatingFoundation extends BaseFoundation {
149
177
  const direction = this._adapter.getContext('direction');
150
178
 
151
179
  const reverse = direction === 'rtl';
180
+ const step = allowHalf ? 0.5 : 1;
181
+ let tempValue;
182
+ let newValue;
183
+
184
+ if (key === 'ArrowRight' || key === 'ArrowUp') {
185
+ tempValue = value + (reverse ? -step : step);
186
+ } else if (key === 'ArrowLeft' || key === 'ArrowDown') {
187
+ tempValue = value + (reverse ? step : -step);
188
+ }
152
189
 
153
- if (keyCode === KeyCode.RIGHT && value < count && !reverse) {
154
- if (allowHalf) {
155
- value += 0.5;
156
- } else {
157
- value += 1;
158
- }
159
- } else if (keyCode === KeyCode.LEFT && value > 0 && !reverse) {
160
- if (allowHalf) {
161
- value -= 0.5;
162
- } else {
163
- value -= 1;
164
- }
165
- } else if (keyCode === KeyCode.RIGHT && value > 0 && reverse) {
166
- if (allowHalf) {
167
- value -= 0.5;
168
- } else {
169
- value -= 1;
170
- }
171
- } else if (keyCode === KeyCode.LEFT && value < count && reverse) {
172
- if (allowHalf) {
173
- value += 0.5;
174
- } else {
175
- value += 1;
176
- }
190
+ if (tempValue > count) {
191
+ newValue = 0;
192
+ } else if (tempValue < 0) {
193
+ newValue = count;
194
+ } else {
195
+ newValue = tempValue;
196
+ }
197
+
198
+ if (_includesInstanceProperty(_context = ['ArrowRight', 'ArrowUp', 'ArrowLeft', 'ArrowDown']).call(_context, key)) {
199
+ this._adapter.notifyKeyDown(event);
200
+
201
+ this._adapter.updateValue(newValue);
202
+
203
+ this.changeFocusStar(newValue, event);
204
+ event.preventDefault();
205
+
206
+ this._adapter.notifyHoverChange(undefined, null);
177
207
  }
208
+ }
178
209
 
179
- this._adapter.updateValue(value);
210
+ changeFocusStar(value, event) {
211
+ var _context2;
180
212
 
181
- event.preventDefault();
213
+ const {
214
+ count,
215
+ allowHalf,
216
+ preventScroll
217
+ } = this.getProps();
218
+ const index = Math.ceil(value) - 1;
219
+
220
+ const starElement = _mapInstanceProperty(_context2 = [...event.currentTarget.childNodes]).call(_context2, item => item.childNodes[0].childNodes);
182
221
 
183
- this._adapter.notifyKeyDown(event);
222
+ if (index < 0) {
223
+ starElement[count][0].focus({
224
+ preventScroll
225
+ });
226
+ } else {
227
+ starElement[index][allowHalf ? value * 10 % 10 === 5 ? 0 : 1 : 0].focus({
228
+ preventScroll
229
+ });
230
+ }
231
+ }
232
+
233
+ }
234
+ export class RatingItemFoundation extends BaseFoundation {
235
+ constructor(adapter) {
236
+ super(_Object$assign(_Object$assign({}, RatingItemFoundation.defaultAdapter), adapter));
237
+
238
+ this.handleFocusVisible = (event, star) => {
239
+ const {
240
+ target
241
+ } = event; // when rating 0 is focus visible
242
+
243
+ try {
244
+ if (target.matches(':focus-visible')) {
245
+ if (star === 'first') {
246
+ this._adapter.setFirstStarFocus(true);
247
+ } else {
248
+ this._adapter.setSecondStarFocus(true);
249
+ }
250
+ }
251
+ } catch (error) {
252
+ warning(true, 'Warning: [Semi Rating] The current browser does not support the focus-visible');
253
+ }
254
+ };
255
+
256
+ this.handleBlur = (event, star) => {
257
+ const {
258
+ firstStarFocus,
259
+ secondStarFocus
260
+ } = this.getStates();
261
+
262
+ if (star === 'first') {
263
+ firstStarFocus && this._adapter.setFirstStarFocus(false);
264
+ } else {
265
+ secondStarFocus && this._adapter.setSecondStarFocus(false);
266
+ }
267
+ };
184
268
  }
185
269
 
186
270
  }
@@ -6,10 +6,15 @@
6
6
  margin: 0px;
7
7
  padding: 0px;
8
8
  color: rgba(var(--semi-yellow-5), 1);
9
- font-size: 20px;
10
- line-height: unset;
11
9
  list-style: none;
12
10
  outline: none;
11
+ border-radius: 3px;
12
+ }
13
+ .semi-rating-focus {
14
+ outline: 2px solid var(--semi-color-primary-light-active);
15
+ }
16
+ .semi-rating-no-focus {
17
+ outline: none;
13
18
  }
14
19
  .semi-rating-disabled .semi-rating-star {
15
20
  cursor: default;
@@ -29,12 +34,12 @@
29
34
  .semi-rating-star:not(:last-child) {
30
35
  margin-right: 6px;
31
36
  }
32
- .semi-rating-star > div:focus {
33
- outline: 0;
34
- }
35
37
  .semi-rating-star > div:hover, .semi-rating-star > div:focus {
36
38
  transform: scale(1.1);
37
39
  }
40
+ .semi-rating-star > div.semi-rating-star-disabled {
41
+ transform: none;
42
+ }
38
43
  .semi-rating-star-small {
39
44
  width: 16px;
40
45
  height: 16px;
@@ -47,6 +52,10 @@
47
52
  }
48
53
  .semi-rating-star-wrapper {
49
54
  position: relative;
55
+ overflow: hidden;
56
+ border-radius: 3px;
57
+ width: 100%;
58
+ height: 100%;
50
59
  }
51
60
  .semi-rating-star-first, .semi-rating-star-second {
52
61
  color: var(--semi-color-fill-0);
@@ -1,4 +1,4 @@
1
- @import "./variables.scss";
1
+ @import './variables.scss';
2
2
 
3
3
  $module: #{$prefix}-rating;
4
4
 
@@ -7,10 +7,19 @@ $module: #{$prefix}-rating;
7
7
  margin: $spacing-rating-margin;
8
8
  padding: $spacing-rating-padding;
9
9
  color: $color-rating-icon-default;
10
- font-size: $font-rating-fontSize;
11
- line-height: unset;
10
+ // font-size: $font-rating-fontSize;
11
+ // line-height: unset;
12
12
  list-style: none;
13
13
  outline: none;
14
+ border-radius: 3px;
15
+
16
+ &-focus {
17
+ outline: $width-rating-outline-focus solid $color-rating-outline-focus;
18
+ }
19
+
20
+ &-no-focus {
21
+ outline: none;
22
+ }
14
23
 
15
24
  &-disabled &-star {
16
25
  cursor: default;
@@ -34,14 +43,14 @@ $module: #{$prefix}-rating;
34
43
  }
35
44
 
36
45
  & > div {
37
- &:focus {
38
- outline: 0;
39
- }
40
-
41
46
  &:hover,
42
47
  &:focus {
43
48
  transform: scale(1.1);
44
49
  }
50
+
51
+ &.#{$module}-star-disabled {
52
+ transform: none;
53
+ }
45
54
  }
46
55
 
47
56
  &-small {
@@ -58,6 +67,10 @@ $module: #{$prefix}-rating;
58
67
 
59
68
  &-wrapper {
60
69
  position: relative;
70
+ overflow: hidden;
71
+ border-radius: 3px;
72
+ width: 100%;
73
+ height: 100%;
61
74
  }
62
75
 
63
76
  &-first,
@@ -88,4 +101,4 @@ $module: #{$prefix}-rating;
88
101
  }
89
102
  }
90
103
 
91
- @import "./rtl.scss";
104
+ @import './rtl.scss';
@@ -1,6 +1,8 @@
1
1
  $color-rating-icon-default: rgba(var(--semi-yellow-5), 1); // 评分图标按钮颜色 - 已填
2
2
  $color-rating-bg-default: var(--semi-color-fill-0); // 评分图标按钮颜色 - 未填
3
3
 
4
+ $color-rating-outline-focus: var(--semi-color-primary-light-active); // 聚焦轮廓颜色
5
+
4
6
  $font-rating-fontSize: 20px; // 评分文本字体大小
5
7
 
6
8
  $spacing-rating-margin: 0px; // 整体外边距
@@ -12,3 +14,5 @@ $font-rating_item_small-fontSize: $width-rating_item_small; // 小尺寸评分
12
14
 
13
15
  $width-rating_item_default: 24px; // 评分项宽度
14
16
  $font-rating_item_default-fontSize: $width-rating_item_default; // 评分项文本字体大小
17
+
18
+ $width-rating-outline-focus: 2px; // 聚焦轮廓宽度