@rainbow-oh/yee-c 0.8.0 → 0.8.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 (101) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +40 -25
  3. package/dist/cjs/Card/card.js +7 -3
  4. package/dist/cjs/Carousel/carousel-item.js +7 -2
  5. package/dist/cjs/Carousel/carousel.js +31 -4
  6. package/dist/cjs/Cascader/cascader.js +1 -1
  7. package/dist/cjs/Cascader/column.js +1 -1
  8. package/dist/cjs/Cascader/node.js +16 -4
  9. package/dist/cjs/Cascader/search-list.js +13 -4
  10. package/dist/cjs/Checkbox/checkbox-group.js +1 -1
  11. package/dist/cjs/Checkbox/checkbox.js +6 -3
  12. package/dist/cjs/Collapse/panel.js +10 -1
  13. package/dist/cjs/Dialog/dialog.js +22 -7
  14. package/dist/cjs/Drawer/drawer.js +14 -5
  15. package/dist/cjs/Menu/menu-item.js +14 -5
  16. package/dist/cjs/Menu/menu.js +10 -2
  17. package/dist/cjs/Pagination/items.js +10 -5
  18. package/dist/cjs/Pagination/pagination.js +9 -3
  19. package/dist/cjs/Radio/radio-group.js +6 -5
  20. package/dist/cjs/Radio/radio.js +39 -29
  21. package/dist/cjs/Rate/rate.js +6 -1
  22. package/dist/cjs/Rate/star.js +7 -3
  23. package/dist/cjs/Steps/step.js +7 -5
  24. package/dist/cjs/Steps/steps.js +1 -1
  25. package/dist/cjs/Tabs/tab-content.js +3 -1
  26. package/dist/cjs/Tabs/tab-header/index.js +3 -1
  27. package/dist/cjs/Tabs/tab-header/tab-header-title.js +3 -1
  28. package/dist/cjs/hooks/useDelayState.js +3 -2
  29. package/dist/cjs/hooks/useFocusManage.d.ts +1 -1
  30. package/dist/cjs/hooks/useFocusManage.js +27 -22
  31. package/dist/cjs/style/themes.css +1 -1
  32. package/dist/cjs/style/variables.css +1 -1
  33. package/dist/cjs/utils/focusStack.d.ts +6 -2
  34. package/dist/cjs/utils/focusStack.js +40 -11
  35. package/dist/cjs/version.d.ts +1 -1
  36. package/dist/cjs/version.js +1 -1
  37. package/dist/esm/Card/card.js +7 -3
  38. package/dist/esm/Carousel/carousel-item.js +7 -2
  39. package/dist/esm/Carousel/carousel.js +31 -4
  40. package/dist/esm/Cascader/cascader.js +3 -1
  41. package/dist/esm/Cascader/column.js +2 -1
  42. package/dist/esm/Cascader/node.js +18 -4
  43. package/dist/esm/Cascader/search-list.js +18 -4
  44. package/dist/esm/Checkbox/checkbox-group.js +3 -1
  45. package/dist/esm/Checkbox/checkbox.js +6 -3
  46. package/dist/esm/Collapse/panel.js +11 -2
  47. package/dist/esm/Dialog/dialog.js +26 -9
  48. package/dist/esm/Drawer/drawer.js +16 -7
  49. package/dist/esm/Menu/menu-item.js +16 -5
  50. package/dist/esm/Menu/menu.js +11 -5
  51. package/dist/esm/Pagination/items.js +14 -5
  52. package/dist/esm/Pagination/pagination.js +16 -4
  53. package/dist/esm/Radio/radio-group.js +5 -4
  54. package/dist/esm/Radio/radio.js +5 -4
  55. package/dist/esm/Rate/rate.js +6 -1
  56. package/dist/esm/Rate/star.js +12 -4
  57. package/dist/esm/Steps/step.js +12 -6
  58. package/dist/esm/Steps/steps.js +3 -1
  59. package/dist/esm/Tabs/tab-content.js +3 -1
  60. package/dist/esm/Tabs/tab-header/index.js +3 -1
  61. package/dist/esm/Tabs/tab-header/tab-header-title.js +3 -1
  62. package/dist/esm/hooks/useDelayState.js +5 -2
  63. package/dist/esm/hooks/useFocusManage.d.ts +1 -1
  64. package/dist/esm/hooks/useFocusManage.js +31 -13
  65. package/dist/esm/style/themes.css +1 -1
  66. package/dist/esm/style/variables.css +1 -1
  67. package/dist/esm/utils/focusStack.d.ts +6 -2
  68. package/dist/esm/utils/focusStack.js +37 -14
  69. package/dist/esm/version.d.ts +1 -1
  70. package/dist/esm/version.js +1 -1
  71. package/dist/umd/yee-c.min.js +1 -1
  72. package/package.json +10 -6
  73. package/src/Card/card.tsx +5 -1
  74. package/src/Carousel/carousel-item.tsx +7 -1
  75. package/src/Carousel/carousel.tsx +30 -3
  76. package/src/Cascader/cascader.tsx +1 -1
  77. package/src/Cascader/column.tsx +1 -1
  78. package/src/Cascader/node.tsx +14 -2
  79. package/src/Cascader/search-list.tsx +11 -2
  80. package/src/Checkbox/checkbox-group.tsx +1 -1
  81. package/src/Checkbox/checkbox.tsx +3 -0
  82. package/src/Collapse/panel.tsx +11 -1
  83. package/src/Dialog/dialog.tsx +31 -6
  84. package/src/Drawer/drawer.tsx +12 -3
  85. package/src/Menu/menu-item.tsx +12 -3
  86. package/src/Menu/menu.tsx +11 -5
  87. package/src/Pagination/items.tsx +9 -4
  88. package/src/Pagination/pagination.tsx +10 -4
  89. package/src/Radio/radio-group.tsx +2 -1
  90. package/src/Radio/radio.tsx +7 -2
  91. package/src/Rate/rate.tsx +5 -0
  92. package/src/Rate/star.tsx +8 -4
  93. package/src/Steps/step.tsx +15 -5
  94. package/src/Steps/steps.tsx +1 -1
  95. package/src/Tabs/tab-content.tsx +2 -0
  96. package/src/Tabs/tab-header/index.tsx +2 -0
  97. package/src/Tabs/tab-header/tab-header-title.tsx +3 -1
  98. package/src/hooks/useDelayState.ts +4 -2
  99. package/src/hooks/useFocusManage.ts +33 -17
  100. package/src/utils/focusStack.ts +55 -12
  101. package/src/version.ts +1 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 InsureMO
3
+ Copyright (c) 2026 insureMO
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@rainbow-oh/yee-c.svg)](https://www.npmjs.com/package/@rainbow-oh/yee-c) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
4
4
 
5
- 65+ foundational React UI components for building modern enterprise applications. Part of the [Yee](https://github.com/InsureMO/oh-yee) component library.
5
+ 65+ foundational React UI components for building modern enterprise applications. Part of the [Yee](https://github.com/insureMO/oh-yee) component library.
6
6
 
7
7
  ## Features
8
8
 
@@ -24,7 +24,16 @@ Requires `react >= 18` and `react-dom >= 18` as peer dependencies.
24
24
  ## Usage
25
25
 
26
26
  ```tsx
27
- import { Button, Form, Input, Table, Card, Select, Dialog, message } from '@rainbow-oh/yee-c';
27
+ import {
28
+ Button,
29
+ Form,
30
+ Input,
31
+ Table,
32
+ Card,
33
+ Select,
34
+ Dialog,
35
+ message,
36
+ } from '@rainbow-oh/yee-c';
28
37
  ```
29
38
 
30
39
  Import styles:
@@ -54,10 +63,16 @@ function UserForm() {
54
63
  <>
55
64
  {messageHolder}
56
65
  <Form form={form} onFinish={handleSubmit}>
57
- <Form.Field label="Name" name="name" rules={[{ required: true, message: 'Please enter name' }]}>
66
+ <Form.Field
67
+ label="Name"
68
+ name="name"
69
+ rules={[{ required: true, message: 'Please enter name' }]}
70
+ >
58
71
  <Input />
59
72
  </Form.Field>
60
- <Button type="primary" htmlType="submit">Submit</Button>
73
+ <Button type="primary" htmlType="submit">
74
+ Submit
75
+ </Button>
61
76
  </Form>
62
77
  </>
63
78
  );
@@ -98,31 +113,31 @@ ConfigProvider, Portal
98
113
 
99
114
  20+ utility hooks for common React patterns:
100
115
 
101
- | Hook | Description |
102
- |---|---|
103
- | `useDebounceFunction` | Debounced function execution |
104
- | `useDebounceValue` | Debounced state value |
105
- | `useDeepCompareEffect` | Effect with deep comparison |
106
- | `useDeepCompareMemo` | Memo with deep comparison |
107
- | `useMergedState` | Controlled/uncontrolled state |
108
- | `useLatest` | Always-current ref value |
109
- | `useMount` | Mount lifecycle hook |
110
- | `useUpdateEffect` | Skip-first-run effect |
111
- | `useResizeObserver` | Element resize observation |
112
- | `useElementSize` | Element dimensions tracking |
113
- | `useEvent` | Stable event handler |
114
- | `useFocusManage` | Focus management |
115
- | `useKeyControl` | Keyboard control |
116
- | `useVirtualForm` | Virtual scrolling for forms |
116
+ | Hook | Description |
117
+ | ---------------------- | ----------------------------- |
118
+ | `useDebounceFunction` | Debounced function execution |
119
+ | `useDebounceValue` | Debounced state value |
120
+ | `useDeepCompareEffect` | Effect with deep comparison |
121
+ | `useDeepCompareMemo` | Memo with deep comparison |
122
+ | `useMergedState` | Controlled/uncontrolled state |
123
+ | `useLatest` | Always-current ref value |
124
+ | `useMount` | Mount lifecycle hook |
125
+ | `useUpdateEffect` | Skip-first-run effect |
126
+ | `useResizeObserver` | Element resize observation |
127
+ | `useElementSize` | Element dimensions tracking |
128
+ | `useEvent` | Stable event handler |
129
+ | `useFocusManage` | Focus management |
130
+ | `useKeyControl` | Keyboard control |
131
+ | `useVirtualForm` | Virtual scrolling for forms |
117
132
 
118
133
  ## Theming
119
134
 
120
135
  Use built-in color themes by importing the corresponding CSS file:
121
136
 
122
137
  ```tsx
123
- import '@rainbow-oh/yee-c/variables.css'; // Base variables
124
- import '@rainbow-oh/yee-c/color.blue.css'; // Blue theme
125
- import '@rainbow-oh/yee-c/color.dark.css'; // Dark theme
138
+ import '@rainbow-oh/yee-c/variables.css'; // Base variables
139
+ import '@rainbow-oh/yee-c/color.blue.css'; // Blue theme
140
+ import '@rainbow-oh/yee-c/color.dark.css'; // Dark theme
126
141
  ```
127
142
 
128
143
  Available themes: `blue`, `crimson`, `dark`, `green`, `jam`, `navy`, `peach`, `pine`, `pitaya`, `pumpkin`, `ruby`.
@@ -145,8 +160,8 @@ pnpm lint
145
160
 
146
161
  ## Contributing
147
162
 
148
- See the root [Contributing Guide](https://github.com/InsureMO/oh-yee/blob/main/CONTRIBUTING.md).
163
+ See the root [Contributing Guide](https://github.com/insureMO/oh-yee/blob/main/CONTRIBUTING.md).
149
164
 
150
165
  ## License
151
166
 
152
- [MIT](./LICENSE) © [InsureMO](https://github.com/InsureMO)
167
+ [MIT](./LICENSE) © [insureMO](https://github.com/insureMO)
@@ -140,10 +140,10 @@ var Card = (baseprops) => {
140
140
  ),
141
141
  style: styles == null ? void 0 : styles.expandIcon,
142
142
  "aria-expanded": mergedExpanded,
143
+ "aria-label": mergedExpanded ? "Collapse content" : "Expand content",
143
144
  icon: icon ? icon : /* @__PURE__ */ import_react2.default.createElement(
144
145
  import_lucide_react.ChevronUp,
145
146
  {
146
- "aria-label": "expanded",
147
147
  strokeWidth: 1.5,
148
148
  size: 16,
149
149
  style: {
@@ -187,7 +187,8 @@ var Card = (baseprops) => {
187
187
  onClick: headerClickable ? handleExpand : void 0,
188
188
  onKeyDown: handleKeyDown,
189
189
  tabIndex: headerClickable ? 0 : void 0,
190
- role: headerClickable ? "button" : void 0
190
+ role: headerClickable ? "button" : void 0,
191
+ "aria-expanded": headerClickable ? mergedExpanded : void 0
191
192
  },
192
193
  iconPosition === "left" ? renderExpandIcon() : null,
193
194
  title ? /* @__PURE__ */ import_react2.default.createElement(
@@ -208,7 +209,10 @@ var Card = (baseprops) => {
208
209
  style: __spreadProps(__spreadValues({}, styles == null ? void 0 : styles.content), { overflow: "hidden" }),
209
210
  animate: mergedExpanded ? { height: "auto" } : { height: 0 },
210
211
  exit: { height: 0, display: "none" },
211
- transition: { duration: animationDuration }
212
+ transition: { duration: animationDuration },
213
+ role: "region",
214
+ "aria-labelledby": title ? headerId : void 0,
215
+ "aria-hidden": !mergedExpanded
212
216
  },
213
217
  children
214
218
  )
@@ -38,18 +38,23 @@ var import_carousel = require("./carousel");
38
38
  var CarouselItem = (props) => {
39
39
  const { style, className, children, index } = props;
40
40
  const { prefixCls, current } = import_react.default.useContext(import_carousel.CarouselCtx);
41
+ const isActive = index === current - 1;
41
42
  return /* @__PURE__ */ import_react.default.createElement(
42
43
  "div",
43
44
  {
44
45
  className: (0, import_clsx.default)(
45
46
  `${prefixCls}-item`,
46
47
  {
47
- [`${prefixCls}-item-active`]: index === current - 1
48
+ [`${prefixCls}-item-active`]: isActive
48
49
  },
49
50
  className
50
51
  ),
51
52
  "data-index": index,
52
- style
53
+ style,
54
+ role: "tabpanel",
55
+ "aria-roledescription": "slide",
56
+ "aria-label": `Slide ${(index != null ? index : 0) + 1}`,
57
+ "aria-hidden": !isActive
53
58
  },
54
59
  children
55
60
  );
@@ -211,6 +211,9 @@ var Carousel = import_react.default.forwardRef(
211
211
  { [`${prefixCls}-arrows-visible`]: showArrow },
212
212
  className
213
213
  ),
214
+ role: "region",
215
+ "aria-roledescription": "carousel",
216
+ "aria-live": autoplay ? "off" : "polite",
214
217
  onMouseEnter: handleMouseEnter,
215
218
  onMouseLeave: handleMouseLeave
216
219
  });
@@ -233,7 +236,16 @@ var Carousel = import_react.default.forwardRef(
233
236
  classNames == null ? void 0 : classNames.prev
234
237
  ),
235
238
  style: styles == null ? void 0 : styles.prev,
236
- onClick: prev
239
+ onClick: prev,
240
+ role: "button",
241
+ "aria-label": "Previous slide",
242
+ tabIndex: 0,
243
+ onKeyDown: (e) => {
244
+ if (e.key === "Enter" || e.key === " ") {
245
+ e.preventDefault();
246
+ prev();
247
+ }
248
+ }
237
249
  },
238
250
  direction === "vertical" ? /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronUp, null) : /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronLeft, null)
239
251
  ), /* @__PURE__ */ import_react.default.createElement(
@@ -247,7 +259,16 @@ var Carousel = import_react.default.forwardRef(
247
259
  classNames == null ? void 0 : classNames.next
248
260
  ),
249
261
  style: styles == null ? void 0 : styles.next,
250
- onClick: next
262
+ onClick: next,
263
+ role: "button",
264
+ "aria-label": "Next slide",
265
+ tabIndex: 0,
266
+ onKeyDown: (e) => {
267
+ if (e.key === "Enter" || e.key === " ") {
268
+ e.preventDefault();
269
+ next();
270
+ }
271
+ }
251
272
  },
252
273
  direction === "vertical" ? /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronDown, null) : /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronRight, null)
253
274
  ));
@@ -262,15 +283,21 @@ var Carousel = import_react.default.forwardRef(
262
283
  [`${prefixCls}-bar-${dotPosition}`],
263
284
  classNames == null ? void 0 : classNames.dot
264
285
  ),
265
- style: styles == null ? void 0 : styles.dot
286
+ style: styles == null ? void 0 : styles.dot,
287
+ role: "tablist",
288
+ "aria-label": "Slide controls"
266
289
  },
267
290
  new Array(import_react.default.Children.count(children)).fill(0).map((i, index) => {
291
+ const isActive = current === index + 1 || current === 0 && index === count - 1;
268
292
  return /* @__PURE__ */ import_react.default.createElement(
269
293
  "li",
270
294
  {
271
295
  className: (0, import_clsx.default)({
272
- active: current === index + 1 || current === 0 && index === count
296
+ active: isActive
273
297
  }),
298
+ role: "tab",
299
+ "aria-selected": isActive,
300
+ "aria-label": `Slide ${index + 1}`,
274
301
  tabIndex: 0,
275
302
  onClick: () => handleIndicator(index + 1, "click"),
276
303
  onKeyDown: (e) => {
@@ -409,7 +409,7 @@ var Cascader = (baseprops) => {
409
409
  );
410
410
  };
411
411
  const renderPopup = () => {
412
- return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_clsx.default)(prefixCls) }, isFilter ? /* @__PURE__ */ import_react.default.createElement(
412
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: (0, import_clsx.default)(prefixCls), role: "group", "aria-label": "Cascader options" }, isFilter ? /* @__PURE__ */ import_react.default.createElement(
413
413
  import_search_list.default,
414
414
  {
415
415
  prefixCls,
@@ -53,7 +53,7 @@ var import_react = __toESM(require("react"));
53
53
  var import_node = __toESM(require("./node"));
54
54
  var Column = (props) => {
55
55
  const { prefixCls, data, index } = props;
56
- return /* @__PURE__ */ import_react.default.createElement("ul", { className: `${prefixCls}-menu`, role: "menu" }, Array.isArray(data) && data.map((item, idx) => {
56
+ return /* @__PURE__ */ import_react.default.createElement("ul", { className: `${prefixCls}-menu`, role: "listbox", "aria-label": `Level ${index + 1} options` }, Array.isArray(data) && data.map((item, idx) => {
57
57
  return /* @__PURE__ */ import_react.default.createElement(
58
58
  import_node.default,
59
59
  __spreadProps(__spreadValues({}, item), {
@@ -41,7 +41,7 @@ var import_isEqual = __toESM(require("../utils/isEqual"));
41
41
  var import_cascader = require("./cascader");
42
42
  var import_utils = require("./utils");
43
43
  var Node = (props) => {
44
- var _a;
44
+ var _a, _b, _c;
45
45
  const { uid, value, disabled, label, $source, isLeaf, path, level } = props;
46
46
  const {
47
47
  prefixCls,
@@ -120,14 +120,26 @@ var Node = (props) => {
120
120
  {
121
121
  className: clsName,
122
122
  onMouseEnter: handleMouseEnter,
123
- onClick: (e) => handleClick(false, e)
123
+ onClick: (e) => handleClick(false, e),
124
+ role: "option",
125
+ "aria-disabled": disabled || void 0,
126
+ "aria-selected": checked || ((_b = expandedPath[level]) == null ? void 0 : _b.key) === uid,
127
+ "aria-expanded": isParent ? ((_c = expandedPath[level]) == null ? void 0 : _c.key) === uid : void 0,
128
+ tabIndex: disabled ? -1 : 0,
129
+ onKeyDown: (e) => {
130
+ if (e.key === "Enter" || e.key === " ") {
131
+ e.preventDefault();
132
+ handleClick(false, e);
133
+ }
134
+ }
124
135
  },
125
136
  multiple && /* @__PURE__ */ import_react.default.createElement(
126
137
  import_Checkbox.default,
127
138
  {
128
139
  checked: isParent ? checkedAll : checked,
129
140
  onChange: isParent ? () => handleClick(true) : void 0,
130
- indeterminate
141
+ indeterminate,
142
+ "aria-label": `Select ${typeof label === "string" ? label : String(label)}`
131
143
  }
132
144
  ),
133
145
  /* @__PURE__ */ import_react.default.createElement(
@@ -140,7 +152,7 @@ var Node = (props) => {
140
152
  },
141
153
  label
142
154
  ),
143
- load === 1 ? /* @__PURE__ */ import_react.default.createElement(import_Spin.default, { size: "small" }) : isLeaf === false ? /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronRight, { size: 20 }) : null
155
+ load === 1 ? /* @__PURE__ */ import_react.default.createElement(import_Spin.default, { size: "small", "aria-label": "Loading" }) : isLeaf === false ? /* @__PURE__ */ import_react.default.createElement(import_lucide_react.ChevronRight, { size: 20, "aria-hidden": "true" }) : null
144
156
  );
145
157
  };
146
158
  var node_default = (0, import_react.memo)(Node);
@@ -45,8 +45,8 @@ var renderHighlightText = (matches) => {
45
45
  };
46
46
  var SearchList = (props) => {
47
47
  const { prefixCls, items, onClick } = props;
48
- return /* @__PURE__ */ import_react.default.createElement("ul", { className: `${prefixCls}-filter-menu` }, items.length ? items.map((item) => {
49
- var _a;
48
+ return /* @__PURE__ */ import_react.default.createElement("ul", { className: `${prefixCls}-filter-menu`, role: "listbox", "aria-label": "Search results" }, items.length ? items.map((item) => {
49
+ var _a, _b;
50
50
  const title = ((_a = item.data.$source) == null ? void 0 : _a.title) || item.data.labelPath.join(" / ");
51
51
  return /* @__PURE__ */ import_react.default.createElement(
52
52
  "li",
@@ -54,10 +54,19 @@ var SearchList = (props) => {
54
54
  className: `${prefixCls}-filter-menu-item`,
55
55
  title: typeof title === "string" ? title : String(title),
56
56
  onClick: () => onClick(item.data),
57
- key: item.data.uid
57
+ key: item.data.uid,
58
+ role: "option",
59
+ "aria-disabled": ((_b = item.data.$source) == null ? void 0 : _b.disabled) || void 0,
60
+ tabIndex: 0,
61
+ onKeyDown: (e) => {
62
+ if (e.key === "Enter" || e.key === " ") {
63
+ e.preventDefault();
64
+ onClick(item.data);
65
+ }
66
+ }
58
67
  },
59
68
  renderHighlightText(item.matches)
60
69
  );
61
- }) : /* @__PURE__ */ import_react.default.createElement("p", null, "No result"));
70
+ }) : /* @__PURE__ */ import_react.default.createElement("li", { role: "option", "aria-disabled": "true" }, "No result"));
62
71
  };
63
72
  var search_list_default = import_react.default.memo(SearchList);
@@ -100,7 +100,7 @@ var CheckboxGroup = (baseprops) => {
100
100
  setMergedValue(newValue);
101
101
  onChange == null ? void 0 : onChange(newValue);
102
102
  };
103
- return /* @__PURE__ */ import_react.default.createElement("div", { className: cls, style }, /* @__PURE__ */ import_react.default.createElement(
103
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: cls, style, role: "group", "aria-disabled": disabled || void 0 }, /* @__PURE__ */ import_react.default.createElement(
104
104
  CheckboxGroupCtx.Provider,
105
105
  {
106
106
  value: { name, buttonStyle, onChange: handleChange }
@@ -119,7 +119,8 @@ var Checkbox = (baseprops) => {
119
119
  },
120
120
  className
121
121
  ),
122
- style
122
+ style,
123
+ "aria-disabled": disabled || void 0
123
124
  },
124
125
  /* @__PURE__ */ import_react.default.createElement(
125
126
  "span",
@@ -139,14 +140,16 @@ var Checkbox = (baseprops) => {
139
140
  value,
140
141
  disabled,
141
142
  checked: mergedChecked,
142
- onChange: handleChange
143
+ onChange: handleChange,
144
+ "aria-checked": indeterminate ? "mixed" : mergedChecked
143
145
  })
144
146
  ),
145
147
  /* @__PURE__ */ import_react.default.createElement(
146
148
  "span",
147
149
  {
148
150
  className: (0, import_clsx.default)(`${prefixCls}-inner`, classNames == null ? void 0 : classNames.inner),
149
- style: styles == null ? void 0 : styles.inner
151
+ style: styles == null ? void 0 : styles.inner,
152
+ "aria-hidden": "true"
150
153
  }
151
154
  )
152
155
  ),
@@ -41,6 +41,9 @@ var import_collapse = require("./collapse");
41
41
  var Panel = (props) => {
42
42
  const { children, title, id, className, style, extra, classNames, styles } = props;
43
43
  const { prefixCls, activeKey, onExpand } = (0, import_react2.useContext)(import_collapse.CollapseContext);
44
+ const panelId = (0, import_react2.useId)();
45
+ const headerId = `${panelId}-header`;
46
+ const contentId = `${panelId}-content`;
44
47
  const expanded = activeKey.includes(id);
45
48
  const itemClassName = (0, import_clsx.default)(
46
49
  `${prefixCls}-item`,
@@ -55,7 +58,9 @@ var Panel = (props) => {
55
58
  className: (0, import_clsx.default)(`${prefixCls}-header`, classNames == null ? void 0 : classNames.header),
56
59
  role: "button",
57
60
  style: styles == null ? void 0 : styles.header,
61
+ id: headerId,
58
62
  "aria-expanded": expanded,
63
+ "aria-controls": contentId,
59
64
  "aria-disabled": "false",
60
65
  tabIndex: 0,
61
66
  onClick: () => onExpand(id),
@@ -72,7 +77,8 @@ var Panel = (props) => {
72
77
  className: (0, import_clsx.default)(`${prefixCls}-expand-icon`, classNames == null ? void 0 : classNames.expandIcon),
73
78
  style: styles == null ? void 0 : styles.expandIcon,
74
79
  animate: { rotate: expanded ? 90 : 0 },
75
- transition: { duration: 0.15 }
80
+ transition: { duration: 0.15 },
81
+ "aria-hidden": "true"
76
82
  },
77
83
  /* @__PURE__ */ import_react2.default.createElement(import_Button.default, { icon: /* @__PURE__ */ import_react2.default.createElement(import_lucide_react.ChevronRight, { size: 16 }), type: "text" })
78
84
  ),
@@ -99,6 +105,9 @@ var Panel = (props) => {
99
105
  {
100
106
  className: (0, import_clsx.default)(`${prefixCls}-content`, classNames == null ? void 0 : classNames.content),
101
107
  style: styles == null ? void 0 : styles.content,
108
+ id: contentId,
109
+ role: "region",
110
+ "aria-labelledby": headerId,
102
111
  initial: { height: 0, opacity: 0 },
103
112
  animate: { height: "auto", opacity: 1 },
104
113
  exit: { height: 0, opacity: 0 },
@@ -80,7 +80,6 @@ var ANIMATION_DURATION = 0.2;
80
80
  var CLOSE_ICON_SIZE = 16;
81
81
  var CLOSE_ICON_STROKE_WIDTH = 1.5;
82
82
  var Dialog = (baseprops) => {
83
- var _b;
84
83
  const { dialog } = (0, import_react2.useContext)(import_Config_Provider.GlobalContext);
85
84
  const props = (0, import_mergeContextToProps.default)(baseprops, dialog);
86
85
  const { locale } = (0, import_locale.useLocale)();
@@ -137,7 +136,17 @@ var Dialog = (baseprops) => {
137
136
  "onConfirm"
138
137
  ]);
139
138
  const [delayOpen, setDelayOpen] = (0, import_react2.useState)(open);
139
+ const [contentElement, setContentElement] = (0, import_react2.useState)(
140
+ null
141
+ );
140
142
  const contentRef = (0, import_react2.useRef)(null);
143
+ const setContentRef = (0, import_react2.useCallback)((element) => {
144
+ contentRef.current = element;
145
+ setContentElement(element);
146
+ }, []);
147
+ const dialogId = (0, import_react2.useId)();
148
+ const titleId = `${dialogId}-title`;
149
+ const bodyId = `${dialogId}-body`;
141
150
  (0, import_react2.useEffect)(() => {
142
151
  var _a2;
143
152
  if (open && draggable && openResetLocation) {
@@ -149,14 +158,14 @@ var Dialog = (baseprops) => {
149
158
  element: contentRef,
150
159
  bounds: dragLimitInWindow ? () => document.body : void 0
151
160
  });
152
- (0, import_useLockFocus.default)((_b = contentRef == null ? void 0 : contentRef.current) != null ? _b : null, delayOpen);
161
+ (0, import_useLockFocus.default)(contentElement, delayOpen);
153
162
  (0, import_useEsc.default)({
154
163
  enabled: keyboard,
155
164
  onEsc: () => {
156
165
  onCancel == null ? void 0 : onCancel();
157
166
  }
158
167
  });
159
- (0, import_useFocusManage.default)(contentRef.current, delayOpen);
168
+ (0, import_useFocusManage.default)(contentElement, open);
160
169
  const cls = (0, import_clsx.default)(prefixCls, {
161
170
  [`${prefixCls}-open`]: delayOpen,
162
171
  [`${prefixCls}-fullscreen`]: fullscreen
@@ -208,7 +217,8 @@ var Dialog = (baseprops) => {
208
217
  "div",
209
218
  {
210
219
  className: (0, import_clsx.default)(`${prefixCls}-mask`, classNames == null ? void 0 : classNames.mask),
211
- style: styles == null ? void 0 : styles.mask
220
+ style: styles == null ? void 0 : styles.mask,
221
+ "aria-hidden": "true"
212
222
  }
213
223
  ),
214
224
  /* @__PURE__ */ import_react2.default.createElement(
@@ -224,7 +234,11 @@ var Dialog = (baseprops) => {
224
234
  style: __spreadValues({ width: fullscreen ? "100%" : width }, styles == null ? void 0 : styles.content),
225
235
  tabIndex: 0,
226
236
  onClick: (e) => e.stopPropagation(),
227
- ref: contentRef
237
+ ref: setContentRef,
238
+ role: "dialog",
239
+ "aria-modal": showMask ? true : void 0,
240
+ "aria-labelledby": title ? titleId : void 0,
241
+ "aria-describedby": bodyId
228
242
  },
229
243
  closable ? /* @__PURE__ */ import_react2.default.createElement(
230
244
  import_Button.default,
@@ -248,13 +262,14 @@ var Dialog = (baseprops) => {
248
262
  className: (0, import_clsx.default)(`${prefixCls}-header`, classNames == null ? void 0 : classNames.header),
249
263
  style: styles == null ? void 0 : styles.header
250
264
  },
251
- /* @__PURE__ */ import_react2.default.createElement("div", { className: `${prefixCls}-title` }, title)
265
+ /* @__PURE__ */ import_react2.default.createElement("div", { className: `${prefixCls}-title`, id: titleId }, title)
252
266
  ) : null,
253
267
  /* @__PURE__ */ import_react2.default.createElement(
254
268
  "div",
255
269
  {
256
270
  className: (0, import_clsx.default)(`${prefixCls}-body`, classNames == null ? void 0 : classNames.body),
257
- style: styles == null ? void 0 : styles.body
271
+ style: styles == null ? void 0 : styles.body,
272
+ id: bodyId
258
273
  },
259
274
  children
260
275
  ),
@@ -152,6 +152,9 @@ var Drawer = (baseprops) => {
152
152
  ]);
153
153
  const [delayOpen, setDelayOpen] = (0, import_react2.useState)(open);
154
154
  const contentRef = (0, import_react2.useRef)(null);
155
+ const drawerId = (0, import_react2.useId)();
156
+ const titleId = `${drawerId}-title`;
157
+ const bodyId = `${drawerId}-body`;
155
158
  (0, import_useLockFocus.default)(contentRef.current, delayOpen);
156
159
  (0, import_useEsc.default)({
157
160
  enabled: keyboard,
@@ -207,7 +210,7 @@ var Drawer = (baseprops) => {
207
210
  };
208
211
  const renderNode = () => {
209
212
  const { initial, animate, exit } = getAnimate(placement, open);
210
- return /* @__PURE__ */ import_react2.default.createElement("div", __spreadProps(__spreadValues({}, rest), { className: cls, style, role: "modal" }), showMask && delayOpen && /* @__PURE__ */ import_react2.default.createElement(
213
+ return /* @__PURE__ */ import_react2.default.createElement("div", __spreadProps(__spreadValues({}, rest), { className: cls, style }), showMask && delayOpen && /* @__PURE__ */ import_react2.default.createElement(
211
214
  import_react.motion.div,
212
215
  {
213
216
  className: (0, import_clsx.default)(`${prefixCls}-mask`, classNames == null ? void 0 : classNames.mask),
@@ -216,7 +219,8 @@ var Drawer = (baseprops) => {
216
219
  initial: { opacity: 0 },
217
220
  animate: open ? { opacity: 1 } : { opacity: 0 },
218
221
  exit: { opacity: 0 },
219
- transition: { duration: ANIMATION_DURATION }
222
+ transition: { duration: ANIMATION_DURATION },
223
+ "aria-hidden": "true"
220
224
  }
221
225
  ), /* @__PURE__ */ import_react2.default.createElement(
222
226
  import_react.motion.div,
@@ -247,7 +251,11 @@ var Drawer = (baseprops) => {
247
251
  className: (0, import_clsx.default)(`${prefixCls}-content`, classNames == null ? void 0 : classNames.content),
248
252
  tabIndex: 0,
249
253
  style: styles == null ? void 0 : styles.content,
250
- ref: contentRef
254
+ ref: contentRef,
255
+ role: "dialog",
256
+ "aria-modal": showMask ? true : void 0,
257
+ "aria-labelledby": title ? titleId : void 0,
258
+ "aria-describedby": bodyId
251
259
  },
252
260
  renderClose(),
253
261
  title ? /* @__PURE__ */ import_react2.default.createElement(
@@ -256,13 +264,14 @@ var Drawer = (baseprops) => {
256
264
  className: (0, import_clsx.default)(`${prefixCls}-header`, classNames == null ? void 0 : classNames.header),
257
265
  style: styles == null ? void 0 : styles.header
258
266
  },
259
- /* @__PURE__ */ import_react2.default.createElement("div", { className: (0, import_clsx.default)(`${prefixCls}-title`, classNames == null ? void 0 : classNames.title), style: styles == null ? void 0 : styles.title }, title)
267
+ /* @__PURE__ */ import_react2.default.createElement("div", { className: (0, import_clsx.default)(`${prefixCls}-title`, classNames == null ? void 0 : classNames.title), style: styles == null ? void 0 : styles.title, id: titleId }, title)
260
268
  ) : null,
261
269
  /* @__PURE__ */ import_react2.default.createElement(
262
270
  "div",
263
271
  {
264
272
  className: (0, import_clsx.default)(`${prefixCls}-body`, classNames == null ? void 0 : classNames.body),
265
- style: styles == null ? void 0 : styles.body
273
+ style: styles == null ? void 0 : styles.body,
274
+ id: bodyId
266
275
  },
267
276
  children
268
277
  ),
@@ -100,7 +100,11 @@ var MenuItem = (props) => {
100
100
  ),
101
101
  style: __spreadValues({ paddingLeft }, styles == null ? void 0 : styles.item),
102
102
  onClick: handleClick,
103
- title: isCollapsed && typeof label === "string" ? label : void 0
103
+ title: isCollapsed && typeof label === "string" ? label : void 0,
104
+ role: "menuitem",
105
+ "aria-disabled": disabled || void 0,
106
+ "aria-current": (selectedKeys == null ? void 0 : selectedKeys.includes(key)) ? "page" : void 0,
107
+ tabIndex: disabled ? -1 : 0
104
108
  },
105
109
  iconNode,
106
110
  !isCollapsed && /* @__PURE__ */ import_react2.default.createElement(
@@ -167,14 +171,15 @@ var MenuItem = (props) => {
167
171
  if (isCollapsed)
168
172
  return null;
169
173
  if (mode === "vertical" || mode === "horizontal") {
170
- return /* @__PURE__ */ import_react2.default.createElement("span", { className: `${prefixCls}-item-switch` }, /* @__PURE__ */ import_react2.default.createElement(import_lucide_react.ChevronRight, { strokeWidth: 2, size: 18 }));
174
+ return /* @__PURE__ */ import_react2.default.createElement("span", { className: `${prefixCls}-item-switch`, "aria-hidden": "true" }, /* @__PURE__ */ import_react2.default.createElement(import_lucide_react.ChevronRight, { strokeWidth: 2, size: 18 }));
171
175
  }
172
176
  return /* @__PURE__ */ import_react2.default.createElement(
173
177
  import_react.motion.span,
174
178
  {
175
179
  className: `${prefixCls}-item-switch`,
176
180
  animate: { rotateX: opened ? 180 : 0 },
177
- transition: { duration: 0.15 }
181
+ transition: { duration: 0.15 },
182
+ "aria-hidden": "true"
178
183
  },
179
184
  /* @__PURE__ */ import_react2.default.createElement(import_lucide_react.ChevronDown, { strokeWidth: 2, size: 18 })
180
185
  );
@@ -182,7 +187,10 @@ var MenuItem = (props) => {
182
187
  const triggerNode = /* @__PURE__ */ import_react2.default.createElement(
183
188
  "div",
184
189
  {
185
- role: "submenu",
190
+ role: "menuitem",
191
+ "aria-haspopup": "true",
192
+ "aria-expanded": opened,
193
+ "aria-disabled": disabled || void 0,
186
194
  className: (0, import_clsx.default)(`${prefixCls}-submenu-title`, {
187
195
  [`${prefixCls}-submenu-open`]: opened,
188
196
  [`${prefixCls}-submenu-selected`]: selectedKeys.includes(key) || selectedKeys.find(
@@ -191,6 +199,7 @@ var MenuItem = (props) => {
191
199
  }),
192
200
  style: { paddingLeft },
193
201
  onClick: handleExpand,
202
+ tabIndex: disabled ? -1 : 0,
194
203
  title: isCollapsed && typeof label === "string" ? label : void 0
195
204
  },
196
205
  iconNode,
@@ -207,7 +216,7 @@ var MenuItem = (props) => {
207
216
  );
208
217
  const usePopup = mode === "vertical" || mode === "horizontal" || isCollapsed;
209
218
  const placement = mode === "horizontal" && !isCollapsed ? "bottomLeft" : "rightTop";
210
- const childNode = /* @__PURE__ */ import_react2.default.createElement("li", { className: cls }, usePopup ? /* @__PURE__ */ import_react2.default.createElement(
219
+ const childNode = /* @__PURE__ */ import_react2.default.createElement("li", { className: cls, role: "none" }, usePopup ? /* @__PURE__ */ import_react2.default.createElement(
211
220
  import_Trigger.default,
212
221
  {
213
222
  open: openKeys.includes(key),
@@ -63,7 +63,15 @@ var MenuGroup = ({
63
63
  item,
64
64
  prefixCls,
65
65
  renderItems
66
- }) => /* @__PURE__ */ import_react.default.createElement("li", { className: `${prefixCls}-item-group` }, /* @__PURE__ */ import_react.default.createElement("div", { className: `${prefixCls}-item-group-title` }, item.label), /* @__PURE__ */ import_react.default.createElement("ul", { className: `${prefixCls}-item-group-list` }, renderItems(item.children)));
66
+ }) => /* @__PURE__ */ import_react.default.createElement("li", { className: `${prefixCls}-item-group`, role: "none" }, /* @__PURE__ */ import_react.default.createElement("div", { className: `${prefixCls}-item-group-title`, role: "presentation", id: `${prefixCls}-group-${String(item.label)}` }, item.label), /* @__PURE__ */ import_react.default.createElement(
67
+ "ul",
68
+ {
69
+ className: `${prefixCls}-item-group-list`,
70
+ role: "group",
71
+ "aria-labelledby": `${prefixCls}-group-${String(item.label)}`
72
+ },
73
+ renderItems(item.children)
74
+ ));
67
75
  var Menu = (props) => {
68
76
  const {
69
77
  items,
@@ -122,7 +130,7 @@ var Menu = (props) => {
122
130
  }
123
131
  );
124
132
  const rootStyle = root ? __spreadValues({}, style) : {};
125
- return /* @__PURE__ */ import_react.default.createElement("ul", __spreadProps(__spreadValues({}, dataAttrs), { className: cls, style: rootStyle, role: "menu" }), /* @__PURE__ */ import_react.default.createElement(MenuCtx.Provider, { value: { level, mode, classNames, styles } }, getChildFromItems(items), level === 0 && footer && /* @__PURE__ */ import_react.default.createElement("li", { className: `${prefixCls}-footer` }, footer)));
133
+ return /* @__PURE__ */ import_react.default.createElement("ul", __spreadProps(__spreadValues({}, dataAttrs), { className: cls, style: rootStyle, role: root && mode === "horizontal" ? "menubar" : "menu" }), /* @__PURE__ */ import_react.default.createElement(MenuCtx.Provider, { value: { level, mode, classNames, styles } }, getChildFromItems(items), level === 0 && footer && /* @__PURE__ */ import_react.default.createElement("li", { className: `${prefixCls}-footer`, role: "none" }, footer)));
126
134
  };
127
135
  Menu.displayName = "Menu";
128
136
  var menu_default = Menu;