@octohirono/stitch-design-system 0.1.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 (184) hide show
  1. package/README.md +7 -0
  2. package/dist/components/Accordion/Accordion.d.ts +45 -0
  3. package/dist/components/Accordion/Accordion.js +26 -0
  4. package/dist/components/Accordion/accordion.module.js +4 -0
  5. package/dist/components/Accordion/index.d.ts +2 -0
  6. package/dist/components/AlertDialog/AlertDialog.d.ts +45 -0
  7. package/dist/components/AlertDialog/AlertDialog.js +32 -0
  8. package/dist/components/AlertDialog/alert-dialog.module.js +4 -0
  9. package/dist/components/AlertDialog/index.d.ts +2 -0
  10. package/dist/components/AspectRatio/AspectRatio.d.ts +29 -0
  11. package/dist/components/AspectRatio/AspectRatio.js +15 -0
  12. package/dist/components/AspectRatio/aspect-ratio.module.js +4 -0
  13. package/dist/components/AspectRatio/index.d.ts +2 -0
  14. package/dist/components/Avatar/Avatar.d.ts +42 -0
  15. package/dist/components/Avatar/Avatar.js +21 -0
  16. package/dist/components/Avatar/avatar.module.js +13 -0
  17. package/dist/components/Avatar/index.d.ts +2 -0
  18. package/dist/components/Button/Button.d.ts +60 -0
  19. package/dist/components/Button/Button.js +22 -0
  20. package/dist/components/Button/button.module.js +19 -0
  21. package/dist/components/Button/index.d.ts +2 -0
  22. package/dist/components/Card/Card.d.ts +50 -0
  23. package/dist/components/Card/Card.js +21 -0
  24. package/dist/components/Card/card.module.js +22 -0
  25. package/dist/components/Card/index.d.ts +2 -0
  26. package/dist/components/Checkbox/Checkbox.d.ts +45 -0
  27. package/dist/components/Checkbox/Checkbox.js +56 -0
  28. package/dist/components/Checkbox/checkbox.module.js +17 -0
  29. package/dist/components/Checkbox/index.d.ts +2 -0
  30. package/dist/components/CodeBlock/CodeBlock.d.ts +10 -0
  31. package/dist/components/CodeBlock/CodeBlock.js +50 -0
  32. package/dist/components/CodeBlock/codeblock.module.js +17 -0
  33. package/dist/components/CodeBlock/index.d.ts +2 -0
  34. package/dist/components/Collapse/Collapse.d.ts +38 -0
  35. package/dist/components/Collapse/Collapse.js +50 -0
  36. package/dist/components/Collapse/collapse.module.js +13 -0
  37. package/dist/components/Collapse/index.d.ts +2 -0
  38. package/dist/components/ContextMenu/ContextMenu.d.ts +47 -0
  39. package/dist/components/ContextMenu/ContextMenu.js +50 -0
  40. package/dist/components/ContextMenu/context-menu.module.js +13 -0
  41. package/dist/components/ContextMenu/index.d.ts +2 -0
  42. package/dist/components/Divider/Divider.d.ts +50 -0
  43. package/dist/components/Divider/Divider.js +23 -0
  44. package/dist/components/Divider/divider.module.js +14 -0
  45. package/dist/components/Divider/index.d.ts +2 -0
  46. package/dist/components/Drawer/Drawer.d.ts +36 -0
  47. package/dist/components/Drawer/Drawer.js +76 -0
  48. package/dist/components/Drawer/drawer.module.js +21 -0
  49. package/dist/components/Drawer/index.d.ts +2 -0
  50. package/dist/components/DropdownMenu/DropdownMenu.d.ts +55 -0
  51. package/dist/components/DropdownMenu/DropdownMenu.js +54 -0
  52. package/dist/components/DropdownMenu/dropdown-menu.module.js +13 -0
  53. package/dist/components/DropdownMenu/index.d.ts +2 -0
  54. package/dist/components/Form/Form.d.ts +20 -0
  55. package/dist/components/Form/Form.js +105 -0
  56. package/dist/components/Form/FormItem.d.ts +3 -0
  57. package/dist/components/Form/FormItem.js +96 -0
  58. package/dist/components/Form/context.d.ts +22 -0
  59. package/dist/components/Form/context.js +5 -0
  60. package/dist/components/Form/form.module.js +25 -0
  61. package/dist/components/Form/index.d.ts +7 -0
  62. package/dist/components/Form/types.d.ts +164 -0
  63. package/dist/components/Form/types.js +6 -0
  64. package/dist/components/Form/useForm.d.ts +15 -0
  65. package/dist/components/Form/useForm.js +188 -0
  66. package/dist/components/Form/validators.d.ts +3 -0
  67. package/dist/components/Form/validators.js +73 -0
  68. package/dist/components/HoverCard/HoverCard.d.ts +47 -0
  69. package/dist/components/HoverCard/HoverCard.js +26 -0
  70. package/dist/components/HoverCard/hover-card.module.js +9 -0
  71. package/dist/components/HoverCard/index.d.ts +2 -0
  72. package/dist/components/Icon/Icon.d.ts +100 -0
  73. package/dist/components/Icon/Icon.js +150 -0
  74. package/dist/components/Icon/icon.module.js +7 -0
  75. package/dist/components/Icon/index.d.ts +2 -0
  76. package/dist/components/Image/Image.d.ts +50 -0
  77. package/dist/components/Image/Image.js +95 -0
  78. package/dist/components/Image/image.module.js +27 -0
  79. package/dist/components/Image/index.d.ts +2 -0
  80. package/dist/components/Input/Input.d.ts +41 -0
  81. package/dist/components/Input/Input.js +62 -0
  82. package/dist/components/Input/index.d.ts +2 -0
  83. package/dist/components/Input/input.module.js +17 -0
  84. package/dist/components/Label/Label.d.ts +28 -0
  85. package/dist/components/Label/Label.js +15 -0
  86. package/dist/components/Label/index.d.ts +2 -0
  87. package/dist/components/Label/label.module.js +4 -0
  88. package/dist/components/Loading/Loading.d.ts +22 -0
  89. package/dist/components/Loading/Loading.js +32 -0
  90. package/dist/components/Loading/index.d.ts +2 -0
  91. package/dist/components/Loading/loading.module.js +14 -0
  92. package/dist/components/Menubar/Menubar.d.ts +64 -0
  93. package/dist/components/Menubar/Menubar.js +70 -0
  94. package/dist/components/Menubar/index.d.ts +2 -0
  95. package/dist/components/Menubar/menubar.module.js +15 -0
  96. package/dist/components/Modal/Modal.d.ts +38 -0
  97. package/dist/components/Modal/Modal.js +68 -0
  98. package/dist/components/Modal/index.d.ts +2 -0
  99. package/dist/components/Modal/modal.module.js +13 -0
  100. package/dist/components/NavigationMenu/NavigationMenu.d.ts +47 -0
  101. package/dist/components/NavigationMenu/NavigationMenu.js +47 -0
  102. package/dist/components/NavigationMenu/index.d.ts +2 -0
  103. package/dist/components/NavigationMenu/navigation-menu.module.js +16 -0
  104. package/dist/components/Notification/Notification.d.ts +14 -0
  105. package/dist/components/Notification/Notification.js +87 -0
  106. package/dist/components/Notification/NotificationPortal.d.ts +29 -0
  107. package/dist/components/Notification/NotificationPortal.js +90 -0
  108. package/dist/components/Notification/index.d.ts +4 -0
  109. package/dist/components/Notification/notification.module.js +31 -0
  110. package/dist/components/Notification/types.d.ts +44 -0
  111. package/dist/components/OtpField/OtpField.d.ts +40 -0
  112. package/dist/components/OtpField/OtpField.js +20 -0
  113. package/dist/components/OtpField/index.d.ts +2 -0
  114. package/dist/components/OtpField/otp-field.module.js +7 -0
  115. package/dist/components/PasswordInput/PasswordInput.d.ts +36 -0
  116. package/dist/components/PasswordInput/PasswordInput.js +28 -0
  117. package/dist/components/PasswordInput/index.d.ts +2 -0
  118. package/dist/components/PasswordInput/password-input.module.js +4 -0
  119. package/dist/components/Popover/Popover.d.ts +42 -0
  120. package/dist/components/Popover/Popover.js +24 -0
  121. package/dist/components/Popover/index.d.ts +2 -0
  122. package/dist/components/Popover/popover.module.js +9 -0
  123. package/dist/components/Progress/Progress.d.ts +44 -0
  124. package/dist/components/Progress/Progress.js +55 -0
  125. package/dist/components/Progress/index.d.ts +2 -0
  126. package/dist/components/Progress/progress.module.js +21 -0
  127. package/dist/components/Radio/Radio.d.ts +47 -0
  128. package/dist/components/Radio/Radio.js +102 -0
  129. package/dist/components/Radio/index.d.ts +2 -0
  130. package/dist/components/Radio/radio.module.js +17 -0
  131. package/dist/components/ScrollArea/ScrollArea.d.ts +34 -0
  132. package/dist/components/ScrollArea/ScrollArea.js +34 -0
  133. package/dist/components/ScrollArea/index.d.ts +2 -0
  134. package/dist/components/ScrollArea/scroll-area.module.js +10 -0
  135. package/dist/components/Select/Select.d.ts +54 -0
  136. package/dist/components/Select/Select.js +118 -0
  137. package/dist/components/Select/index.d.ts +2 -0
  138. package/dist/components/Select/select.module.js +24 -0
  139. package/dist/components/Skeleton/Skeleton.d.ts +71 -0
  140. package/dist/components/Skeleton/Skeleton.js +147 -0
  141. package/dist/components/Skeleton/index.d.ts +2 -0
  142. package/dist/components/Skeleton/skeleton.module.js +16 -0
  143. package/dist/components/Slider/Slider.d.ts +58 -0
  144. package/dist/components/Slider/Slider.js +33 -0
  145. package/dist/components/Slider/index.d.ts +2 -0
  146. package/dist/components/Slider/slider.module.js +9 -0
  147. package/dist/components/Switch/Switch.d.ts +50 -0
  148. package/dist/components/Switch/Switch.js +43 -0
  149. package/dist/components/Switch/index.d.ts +2 -0
  150. package/dist/components/Switch/switch.module.js +15 -0
  151. package/dist/components/Table/Table.d.ts +65 -0
  152. package/dist/components/Table/Table.js +75 -0
  153. package/dist/components/Table/index.d.ts +2 -0
  154. package/dist/components/Table/table.module.js +21 -0
  155. package/dist/components/Tabs/Tabs.d.ts +37 -0
  156. package/dist/components/Tabs/Tabs.js +68 -0
  157. package/dist/components/Tabs/index.d.ts +2 -0
  158. package/dist/components/Tabs/tabs.module.js +13 -0
  159. package/dist/components/Tag/Tag.d.ts +67 -0
  160. package/dist/components/Tag/Tag.js +54 -0
  161. package/dist/components/Tag/index.d.ts +2 -0
  162. package/dist/components/Tag/tag.module.js +28 -0
  163. package/dist/components/Toggle/Toggle.d.ts +39 -0
  164. package/dist/components/Toggle/Toggle.js +29 -0
  165. package/dist/components/Toggle/index.d.ts +2 -0
  166. package/dist/components/Toggle/toggle.module.js +7 -0
  167. package/dist/components/ToggleGroup/ToggleGroup.d.ts +88 -0
  168. package/dist/components/ToggleGroup/ToggleGroup.js +42 -0
  169. package/dist/components/ToggleGroup/index.d.ts +2 -0
  170. package/dist/components/ToggleGroup/toggle-group.module.js +8 -0
  171. package/dist/components/Toolbar/Toolbar.d.ts +116 -0
  172. package/dist/components/Toolbar/Toolbar.js +72 -0
  173. package/dist/components/Toolbar/index.d.ts +2 -0
  174. package/dist/components/Toolbar/toolbar.module.js +14 -0
  175. package/dist/components/Tooltip/Tooltip.d.ts +41 -0
  176. package/dist/components/Tooltip/Tooltip.js +38 -0
  177. package/dist/components/Tooltip/index.d.ts +2 -0
  178. package/dist/components/Tooltip/tooltip.module.js +21 -0
  179. package/dist/components/_internal/useOverlay.d.ts +15 -0
  180. package/dist/components/_internal/useOverlay.js +55 -0
  181. package/dist/index.d.ts +82 -0
  182. package/dist/index.js +43 -0
  183. package/dist/style.css +3693 -0
  184. package/package.json +36 -0
@@ -0,0 +1,95 @@
1
+ import { Icon as e } from "../Icon/Icon.js";
2
+ import t from "./image.module.js";
3
+ import { useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
4
+ import o from "clsx";
5
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
6
+ import { createPortal as u } from "react-dom";
7
+ //#region packages/react/src/components/Image/Image.tsx
8
+ var d = (e) => e === "default" ? "" : t[`image-${e}`], f = ({ src: f, alt: p = "", width: m, height: h, color: g = "default", lazy: _ = !1, preview: v = !0, className: y, style: b, onLoad: x, onError: S, ...C }) => {
9
+ let [w, T] = a(!1), [E, D] = a(!1), [O, k] = a(!1), A = i(null), j = i(null), [M, N] = a(f);
10
+ f !== M && (N(f), T(!1), D(!1));
11
+ let P = n((e) => {
12
+ D(!0), x?.(e);
13
+ }, [x]), F = n((e) => {
14
+ T(!0), D(!0), S?.(e);
15
+ }, [S]);
16
+ r(() => {
17
+ if (!O) return;
18
+ A.current?.focus();
19
+ let e = (e) => {
20
+ e.key === "Escape" ? k(!1) : e.key === "Tab" && (e.preventDefault(), A.current?.focus());
21
+ };
22
+ return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
23
+ }, [O]), r(() => {
24
+ O || (j.current?.focus(), j.current = null);
25
+ }, [O]);
26
+ let I = () => {
27
+ j.current = document.activeElement, k(!0);
28
+ };
29
+ if (w) return /* @__PURE__ */ l("span", {
30
+ className: o(t.image, d(g), t.error, y),
31
+ style: {
32
+ width: m,
33
+ height: h,
34
+ ...b
35
+ },
36
+ role: "img",
37
+ "aria-label": p || "图片加载失败",
38
+ children: [/* @__PURE__ */ c(e, {
39
+ name: "error",
40
+ size: 32
41
+ }), /* @__PURE__ */ c("span", { children: "图片加载失败" })]
42
+ });
43
+ let L = o(t.image, d(g), E && t.loaded, v && t.preview, y), R = {
44
+ width: m,
45
+ height: h,
46
+ ...b
47
+ }, z = /* @__PURE__ */ c("img", {
48
+ src: f,
49
+ alt: p,
50
+ loading: _ ? "lazy" : void 0,
51
+ className: t.img,
52
+ onLoad: P,
53
+ onError: F,
54
+ ...C
55
+ });
56
+ return v ? /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("button", {
57
+ type: "button",
58
+ className: L,
59
+ style: R,
60
+ onClick: I,
61
+ children: z
62
+ }), u(O ? /* @__PURE__ */ c("div", {
63
+ className: t.mask,
64
+ onClick: () => k(!1),
65
+ children: /* @__PURE__ */ l("div", {
66
+ className: t.dialog,
67
+ role: "dialog",
68
+ "aria-modal": "true",
69
+ "aria-label": p ? `查看图片:${p}` : "图片预览",
70
+ onClick: (e) => e.stopPropagation(),
71
+ children: [/* @__PURE__ */ c("button", {
72
+ type: "button",
73
+ ref: A,
74
+ className: t.closeBtn,
75
+ "aria-label": "关闭预览",
76
+ onClick: () => k(!1),
77
+ children: /* @__PURE__ */ c(e, {
78
+ name: "close",
79
+ size: 16
80
+ })
81
+ }), /* @__PURE__ */ c("img", {
82
+ src: f,
83
+ alt: p,
84
+ className: t.previewImg
85
+ })]
86
+ })
87
+ }) : null, document.body)] }) : /* @__PURE__ */ c("span", {
88
+ className: L,
89
+ style: R,
90
+ children: z
91
+ });
92
+ };
93
+ f.displayName = "Image";
94
+ //#endregion
95
+ export { f as Image };
@@ -0,0 +1,27 @@
1
+ //#region packages/react/src/components/Image/image.module.less
2
+ var e = "_image_15m2u_1", t = "_img_15m2u_19", n = "_loaded_15m2u_26", r = "_error_15m2u_29", i = "_preview_15m2u_71", a = "_mask_15m2u_82", o = "_dialog_15m2u_92", s = "_previewImg_15m2u_97", c = "_closeBtn_15m2u_105", l = {
3
+ image: e,
4
+ img: t,
5
+ loaded: n,
6
+ error: r,
7
+ "image-accent": "_image-accent_15m2u_38",
8
+ "image-danger": "_image-danger_15m2u_41",
9
+ "image-success": "_image-success_15m2u_44",
10
+ "image-warning": "_image-warning_15m2u_47",
11
+ "image-info": "_image-info_15m2u_50",
12
+ "image-cat-1": "_image-cat-1_15m2u_53",
13
+ "image-cat-2": "_image-cat-2_15m2u_56",
14
+ "image-cat-3": "_image-cat-3_15m2u_59",
15
+ "image-cat-4": "_image-cat-4_15m2u_62",
16
+ "image-cat-5": "_image-cat-5_15m2u_65",
17
+ "image-cat-6": "_image-cat-6_15m2u_68",
18
+ preview: i,
19
+ mask: a,
20
+ "stitch-image-fade-in": "_stitch-image-fade-in_15m2u_1",
21
+ dialog: o,
22
+ previewImg: s,
23
+ "stitch-image-zoom-in": "_stitch-image-zoom-in_15m2u_1",
24
+ closeBtn: c
25
+ };
26
+ //#endregion
27
+ export { c as closeBtn, l as default, o as dialog, r as error, e as image, t as img, n as loaded, a as mask, i as preview, s as previewImg };
@@ -0,0 +1,2 @@
1
+ export { Image } from './Image';
2
+ export type { ImageProps, ImageColor } from './Image';
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ export type InputSize = 'small' | 'middle' | 'large';
3
+ /**
4
+ * 文本输入框:结构靠 1px 边框(`--stitch-border`)而非 3D 影;圆角由 `--stitch-radius-input`
5
+ * 决定(随主题变)。只做插槽包裹,不发明取值逻辑。
6
+ *
7
+ * 跨-prop 注意事项:
8
+ * - **受控/非受控双模式**:给 `value` 由父管,只给 `defaultValue` 组件自管;`allowClear` 的
9
+ * 清除经 native setter + `dispatchEvent` 派发真实 `change`(`onChange` 收到的是完整
10
+ * SyntheticEvent,与用户键入一致)。
11
+ * - **`prefix` / `suffix` 传你自己的 `<Icon>` 或文本**——**Do NOT** 传 emoji / Unicode 符号 /
12
+ * 裸 `<svg>`。`allowClear` 的清除按钮内部走 `<Icon name="close">`(非 Unicode `×`),是原生
13
+ * `<button>`:可 Tab 聚焦、Enter/Space 触发,`clearAriaLabel` 定其可访问名。
14
+ * - **`status="error"` 同时置 `aria-invalid="true"`**;聚焦环走 `:focus-within` +
15
+ * `--stitch-focus-ring`(含 prefix/suffix 整框)。
16
+ */
17
+ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix'> {
18
+ /** 输入框尺寸 */
19
+ size?: InputSize;
20
+ /** 前缀节点(传你自己的 `<Icon>` 或文本) */
21
+ prefix?: React.ReactNode;
22
+ /** 后缀节点(传你自己的 `<Icon>` 或文本) */
23
+ suffix?: React.ReactNode;
24
+ /**
25
+ * 允许一键清除(有值且非禁用时显示清除按钮)
26
+ * @default false
27
+ */
28
+ allowClear?: boolean;
29
+ /** 校验态(error 同时置 `aria-invalid`) */
30
+ status?: 'error' | 'warning';
31
+ /** 值变化回调 */
32
+ onChange?: React.ChangeEventHandler<HTMLInputElement>;
33
+ /** 清除回调 */
34
+ onClear?: () => void;
35
+ /**
36
+ * 清除按钮的无障碍标签
37
+ * @default '清除'
38
+ */
39
+ clearAriaLabel?: string;
40
+ }
41
+ export declare const Input: React.FC<InputProps>;
@@ -0,0 +1,62 @@
1
+ import { Icon as e } from "../Icon/Icon.js";
2
+ import t from "./input.module.js";
3
+ import { useCallback as n, useRef as r, useState as i } from "react";
4
+ import a from "clsx";
5
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
6
+ //#region packages/react/src/components/Input/Input.tsx
7
+ var c = ({ size: c = "middle", prefix: l, suffix: u, allowClear: d = !1, status: f, disabled: p = !1, className: m, value: h, defaultValue: g, onChange: _, onClear: v, clearAriaLabel: y = "清除", ...b }) => {
8
+ let [x, S] = i(g ?? ""), C = h !== void 0, w = C ? h : x, T = r(null), E = n((e) => {
9
+ C || S(e.target.value), _?.(e);
10
+ }, [C, _]), D = n((e) => {
11
+ if (e.animationName !== "stitch-onautofillstart") return;
12
+ let t = e.currentTarget;
13
+ t.value !== w && E({
14
+ target: t,
15
+ currentTarget: t
16
+ });
17
+ }, [w, E]), O = n(() => {
18
+ C || S(""), v?.();
19
+ let e = T.current;
20
+ if (e) {
21
+ (Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set)?.call(e, "");
22
+ let t = new Event("input", { bubbles: !0 });
23
+ e.dispatchEvent(t);
24
+ }
25
+ }, [C, v]), k = a(t.wrapper, t[`wrapper-${c}`], f && t[`wrapper-${f}`], p && t["wrapper-disabled"], m);
26
+ return /* @__PURE__ */ s("span", {
27
+ className: k,
28
+ children: [
29
+ l && /* @__PURE__ */ o("span", {
30
+ className: t.prefix,
31
+ children: l
32
+ }),
33
+ /* @__PURE__ */ o("input", {
34
+ ref: T,
35
+ className: t.input,
36
+ disabled: p,
37
+ value: w,
38
+ onChange: E,
39
+ onAnimationStart: D,
40
+ "aria-invalid": f === "error" ? "true" : void 0,
41
+ ...b
42
+ }),
43
+ d && w && !p && /* @__PURE__ */ o("button", {
44
+ type: "button",
45
+ className: t.clear,
46
+ onClick: O,
47
+ "aria-label": y,
48
+ children: /* @__PURE__ */ o(e, {
49
+ name: "close",
50
+ size: 14
51
+ })
52
+ }),
53
+ u && /* @__PURE__ */ o("span", {
54
+ className: t.suffix,
55
+ children: u
56
+ })
57
+ ]
58
+ });
59
+ };
60
+ c.displayName = "Input";
61
+ //#endregion
62
+ export { c as Input };
@@ -0,0 +1,2 @@
1
+ export { Input } from './Input';
2
+ export type { InputProps, InputSize } from './Input';
@@ -0,0 +1,17 @@
1
+ //#region packages/react/src/components/Input/input.module.less
2
+ var e = "_wrapper_srps2_1", t = "_input_srps2_51", n = "_prefix_srps2_90", r = "_suffix_srps2_91", i = "_clear_srps2_104", a = {
3
+ wrapper: e,
4
+ "wrapper-disabled": "_wrapper-disabled_srps2_10",
5
+ "wrapper-error": "_wrapper-error_srps2_10",
6
+ "wrapper-warning": "_wrapper-warning_srps2_10",
7
+ "wrapper-small": "_wrapper-small_srps2_17",
8
+ "wrapper-middle": "_wrapper-middle_srps2_22",
9
+ "wrapper-large": "_wrapper-large_srps2_27",
10
+ input: t,
11
+ "stitch-onautofillstart": "_stitch-onautofillstart_srps2_1",
12
+ prefix: n,
13
+ suffix: r,
14
+ clear: i
15
+ };
16
+ //#endregion
17
+ export { i as clear, a as default, t as input, n as prefix, r as suffix, e as wrapper };
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ /**
3
+ * 表单标签:为一个表单控件(Input / Switch / Checkbox…)提供文字标签,点标签即
4
+ * 聚焦 / 激活该控件。基于原生 `<label>`,通过 `htmlFor` 关联控件 id。组合 Radix
5
+ * `Label.Root`(单 part)。
6
+ *
7
+ * 跨-prop 注意事项:
8
+ * - **vs Form(表单容器)**:Form 会为它的每个 field **自动渲染** label(含必填星号 /
9
+ * 冒号 / 对齐),无需手挂本组件;独立 `Label` 用于 **Form 之外**的零散控件关联——
10
+ * 如手搭一个 `Input` 配文字标签时,用 `htmlFor` 指向控件 id。**不是**替代 Form 的
11
+ * label 体系。
12
+ * - **`htmlFor` = 关联控件 id**:透传成原生 `<label for>`,浏览器据此把标签绑到同 id 的
13
+ * 控件;点标签聚焦 / 激活控件由原生保证(无需自写点击逻辑)。控件用 `id`、标签用同值
14
+ * `htmlFor`。
15
+ * - **极简无状态**:文字走 `--stitch-text-primary` + `--stitch-font-body`,无
16
+ * hover / disabled 等状态色(禁用语义由被关联的控件承载,非标签)。
17
+ */
18
+ export interface LabelProps {
19
+ /** 关联控件的 id:透传成原生 `<label for>`,点标签即聚焦 / 激活该控件 */
20
+ htmlFor?: string;
21
+ /** 标签文字内容 */
22
+ children?: React.ReactNode;
23
+ /** 自定义类名(挂到 `<label>` 上) */
24
+ className?: string;
25
+ /** 行内样式(挂到 `<label>` 上) */
26
+ style?: React.CSSProperties;
27
+ }
28
+ export declare const Label: React.FC<LabelProps>;
@@ -0,0 +1,15 @@
1
+ import e from "./label.module.js";
2
+ import "react";
3
+ import t from "clsx";
4
+ import { jsx as n } from "react/jsx-runtime";
5
+ import { Label as r } from "radix-ui";
6
+ //#region packages/react/src/components/Label/Label.tsx
7
+ var i = ({ htmlFor: i, children: a, className: o, style: s }) => /* @__PURE__ */ n(r.Root, {
8
+ htmlFor: i,
9
+ className: t(e.root, o),
10
+ style: s,
11
+ children: a
12
+ });
13
+ i.displayName = "Label";
14
+ //#endregion
15
+ export { i as Label };
@@ -0,0 +1,2 @@
1
+ export { Label } from './Label';
2
+ export type { LabelProps } from './Label';
@@ -0,0 +1,4 @@
1
+ //#region packages/react/src/components/Label/label.module.less
2
+ var e = "_root_1kq6y_1", t = { root: e };
3
+ //#endregion
4
+ export { t as default, e as root };
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ export type LoadingSize = 'small' | 'middle' | 'large';
3
+ export interface LoadingProps {
4
+ /**
5
+ * 是否处于加载中:`true` 显示遮罩 + 转圈,`false` 淡出后隐藏
6
+ * (对齐 Ant v5 `Spin.spinning`)
7
+ * @default true
8
+ */
9
+ spinning?: boolean;
10
+ /**
11
+ * 转圈尺寸
12
+ * @default 'middle'
13
+ */
14
+ size?: LoadingSize;
15
+ /** 转圈下方的提示文案;字符串时兼作无障碍名 */
16
+ tip?: React.ReactNode;
17
+ /** 透传到遮罩根元素 */
18
+ className?: string;
19
+ /** 透传到遮罩根元素 */
20
+ style?: React.CSSProperties;
21
+ }
22
+ export declare const Loading: React.FC<LoadingProps>;
@@ -0,0 +1,32 @@
1
+ import e from "./loading.module.js";
2
+ import { useEffect as t, useState as n } from "react";
3
+ import r from "clsx";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ //#region packages/react/src/components/Loading/Loading.tsx
6
+ var o = 350, s = ({ spinning: s = !0, size: c = "middle", tip: l, className: u, style: d }) => {
7
+ let [f, p] = n(!s), [m, h] = n(s);
8
+ s !== m && (h(s), s && p(!1)), t(() => {
9
+ if (s) return;
10
+ let e = setTimeout(() => p(!0), o);
11
+ return () => clearTimeout(e);
12
+ }, [s]);
13
+ let g = typeof l == "string" && l ? l : l ? void 0 : "加载中";
14
+ return /* @__PURE__ */ a("div", {
15
+ className: r(e.overlay, !s && e.closing, f && e.hidden, u),
16
+ style: d,
17
+ role: "status",
18
+ "aria-live": "polite",
19
+ "aria-busy": s || void 0,
20
+ "aria-label": g,
21
+ children: [/* @__PURE__ */ i("span", {
22
+ className: r(e.spinner, e[`spinner-${c}`]),
23
+ "aria-hidden": "true"
24
+ }), l ? /* @__PURE__ */ i("span", {
25
+ className: e.tip,
26
+ children: l
27
+ }) : null]
28
+ });
29
+ };
30
+ s.displayName = "Loading";
31
+ //#endregion
32
+ export { s as Loading };
@@ -0,0 +1,2 @@
1
+ export { Loading } from './Loading';
2
+ export type { LoadingProps, LoadingSize } from './Loading';
@@ -0,0 +1,14 @@
1
+ //#region packages/react/src/components/Loading/loading.module.less
2
+ var e = "_overlay_jixc4_1", t = "_closing_jixc4_14", n = "_hidden_jixc4_17", r = "_spinner_jixc4_20", i = "_tip_jixc4_46", a = {
3
+ overlay: e,
4
+ closing: t,
5
+ hidden: n,
6
+ spinner: r,
7
+ "stitch-loading-spin": "_stitch-loading-spin_jixc4_1",
8
+ "spinner-small": "_spinner-small_jixc4_31",
9
+ "spinner-middle": "_spinner-middle_jixc4_36",
10
+ "spinner-large": "_spinner-large_jixc4_41",
11
+ tip: i
12
+ };
13
+ //#endregion
14
+ export { t as closing, a as default, n as hidden, e as overlay, r as spinner, i as tip };
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { type IconName } from '../Icon';
3
+ /**
4
+ * 菜单栏某个菜单里的一项。结构与 `DropdownMenuItem` / `ContextMenuItem` 完全一致
5
+ * (同族,同一心智)。
6
+ */
7
+ export interface MenubarMenuItem {
8
+ /** 菜单项文字 */
9
+ label: React.ReactNode;
10
+ /** 选中该项时触发(底层 `onSelect` → 我们的 `onClick`);有 `children` 的父项忽略此项 */
11
+ onClick?: () => void;
12
+ /** 危险操作(如删除):文字走 `--stitch-danger`、高亮态软底 `--stitch-danger-bg` */
13
+ danger?: boolean;
14
+ /** 禁用该项(不可选、灰显;键盘导航跳过——由底层保证) */
15
+ disabled?: boolean;
16
+ /** 项前图标(必须是 `<Icon>` 支持的名,图标经 `<Icon>` 渲染、不接受裸 svg) */
17
+ icon?: IconName;
18
+ /** 子菜单项:非空 → 该项渲染为可展开的子菜单入口(底层 `Sub/SubTrigger/SubContent`) */
19
+ children?: MenubarMenuItem[];
20
+ }
21
+ /**
22
+ * 菜单栏里的一个顶层菜单:`label` 是栏上的按钮文字,`items` 是点开后的一列动作项。
23
+ */
24
+ export interface MenubarMenu {
25
+ /** 顶层菜单按钮文字(如「文件」「编辑」「视图」) */
26
+ label: React.ReactNode;
27
+ /** 该菜单点开后的动作项数组(与 DropdownMenu 同结构) */
28
+ items: MenubarMenuItem[];
29
+ }
30
+ /**
31
+ * 菜单栏(桌面应用式命令栏):横排**一组**互相协调的顶层菜单(文件 / 编辑 / 视图…),
32
+ * 打开一个后横向方向键即切到相邻菜单;每个菜单点开是一列动作项,点项**触发动作、无选中态**。
33
+ * 对外 **两层 `items` 数组**(`MenubarMenu[]`,每个 menu 再含一层 `MenubarMenuItem[]`)。
34
+ *
35
+ * 跨-prop 注意事项:
36
+ * - **vs NavigationMenu**:那是**站点导航**(链接为主、`role="navigation"`、跳页面);Menubar 是
37
+ * **应用命令栏**(一排动作菜单、`role="menubar"`、触发命令)。
38
+ * - **vs DropdownMenu**:那是**单个**触发按钮弹出的一列动作;Menubar 是**一排互相协调**的菜单——
39
+ * 横向键在菜单间移动、打开态跟随鼠标切换相邻菜单(命令栏心智),并非多个独立 DropdownMenu 并排。
40
+ * - **两层 items API**:外层 `MenubarMenu = { label, items }`(栏上一个菜单);内层 `MenubarMenuItem`
41
+ * 与 DropdownMenu / ContextMenu 项**同结构**(`{ label, onClick?, danger?, disabled?, icon?, children? }`)。
42
+ * 底层 `onSelect` 归一成 `onClick`;`icon` 走 `<Icon>`(禁裸 svg);某项 `children` 非空即渲染成可展开子菜单。
43
+ * - **面 = 浮起层**(复用 DropdownMenu 族皮):菜单面走 `--stitch-bg-elevated` + `--stitch-text-primary`,
44
+ * 边 `--stitch-border`、圆角 `--stitch-radius-card`、阴影 `--stitch-shadow-base`;顶层 Trigger 是菜单栏按钮样式。
45
+ * 开合态 / 高亮态 / 禁用态由底层挂的 `data-state` / `data-highlighted` / `data-disabled` 描,组件不自持显隐 state。
46
+ * - **键盘 / 焦点 / ARIA**(横向键切菜单、纵向键走项、Enter 选中、Esc 关、焦点归还、`role="menubar"`)
47
+ * 由底层保证,组件不重复实现。
48
+ * - **悬停打开(hover 即开)**:鼠标停在某个顶层菜单约 `openDelay` 毫秒即自动展开(含首个、无需点击);
49
+ * 一旦有菜单开着,移到相邻菜单即切换。Radix 默认要先 click/键盘开首个(之后才 hover 切换),本组件只补
50
+ * 「首个」这一环:保持 Radix **非受控**(切换/关闭全走 Radix 原生,无双主竞态),静息悬停满 `openDelay`
51
+ * 且此刻无菜单开着时,程序化在该 Trigger 派发 `pointerdown` 把首个开出来,之后交给 Radix。短延时防止鼠标
52
+ * 只是扫过工具栏就误弹。点击仍即时打开(延时只作用于悬停)。
53
+ */
54
+ export interface MenubarProps {
55
+ /** 两层菜单数据:栏上一排菜单,每个菜单再含一列动作项 */
56
+ items: MenubarMenu[];
57
+ /** 悬停多久(ms)自动展开首个菜单(防误触的意图延时;菜单已开时切换相邻不受此限、即时切换) @default 150 */
58
+ openDelay?: number;
59
+ /** 自定义类名(挂到菜单栏根容器上) */
60
+ className?: string;
61
+ /** 给菜单栏(`role="menubar"`)的无障碍标签 */
62
+ 'aria-label'?: string;
63
+ }
64
+ export declare const Menubar: React.FC<MenubarProps>;
@@ -0,0 +1,70 @@
1
+ import { Icon as e } from "../Icon/Icon.js";
2
+ import t from "./menubar.module.js";
3
+ import n from "react";
4
+ import r from "clsx";
5
+ import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
6
+ import { Menubar as s } from "radix-ui";
7
+ //#region packages/react/src/components/Menubar/Menubar.tsx
8
+ function c(n, l = "") {
9
+ return n.map((n, u) => {
10
+ let d = `${l}${u}`, f = /* @__PURE__ */ o(i, { children: [n.icon && /* @__PURE__ */ a(e, {
11
+ name: n.icon,
12
+ size: "1em",
13
+ className: t.itemIcon
14
+ }), /* @__PURE__ */ a("span", {
15
+ className: t.itemLabel,
16
+ children: n.label
17
+ })] });
18
+ return n.children && n.children.length > 0 ? /* @__PURE__ */ o(s.Sub, { children: [/* @__PURE__ */ o(s.SubTrigger, {
19
+ className: r(t.item, n.danger && t.danger),
20
+ disabled: n.disabled,
21
+ children: [f, /* @__PURE__ */ a(e, {
22
+ name: "chevron-right",
23
+ size: "1em",
24
+ className: t.subArrow
25
+ })]
26
+ }), /* @__PURE__ */ a(s.Portal, { children: /* @__PURE__ */ a(s.SubContent, {
27
+ className: t.content,
28
+ sideOffset: 8,
29
+ children: c(n.children, `${d}-`)
30
+ }) })] }, d) : /* @__PURE__ */ a(s.Item, {
31
+ className: r(t.item, n.danger && t.danger),
32
+ disabled: n.disabled,
33
+ onSelect: n.onClick,
34
+ children: f
35
+ }, d);
36
+ });
37
+ }
38
+ var l = ({ items: e, openDelay: i = 150, className: l, "aria-label": u }) => {
39
+ let d = n.useRef(null), f = n.useRef(void 0), p = () => {
40
+ f.current !== void 0 && (clearTimeout(f.current), f.current = void 0);
41
+ };
42
+ n.useEffect(() => p, []);
43
+ let m = (e) => {
44
+ p(), f.current = setTimeout(() => {
45
+ d.current?.querySelector("[data-state=\"open\"]") || e.dispatchEvent(new MouseEvent("pointerdown", {
46
+ bubbles: !0,
47
+ button: 0
48
+ }));
49
+ }, i);
50
+ };
51
+ return /* @__PURE__ */ a(s.Root, {
52
+ ref: d,
53
+ className: r(t.root, l),
54
+ "aria-label": u,
55
+ onPointerLeave: p,
56
+ children: e.map((e, n) => /* @__PURE__ */ o(s.Menu, { children: [/* @__PURE__ */ a(s.Trigger, {
57
+ className: t.trigger,
58
+ onPointerEnter: (e) => m(e.currentTarget),
59
+ children: e.label
60
+ }), /* @__PURE__ */ a(s.Portal, { children: /* @__PURE__ */ a(s.Content, {
61
+ className: t.content,
62
+ align: "start",
63
+ sideOffset: 4,
64
+ children: c(e.items)
65
+ }) })] }, n))
66
+ });
67
+ };
68
+ l.displayName = "Menubar";
69
+ //#endregion
70
+ export { l as Menubar };
@@ -0,0 +1,2 @@
1
+ export { Menubar } from './Menubar';
2
+ export type { MenubarProps, MenubarMenu, MenubarMenuItem } from './Menubar';
@@ -0,0 +1,15 @@
1
+ //#region packages/react/src/components/Menubar/menubar.module.less
2
+ var e = "_root_907u3_1", t = "_trigger_907u3_8", n = "_content_907u3_40", r = "_item_907u3_60", i = "_danger_907u3_80", a = "_itemIcon_907u3_87", o = "_itemLabel_907u3_91", s = "_subArrow_907u3_94", c = {
3
+ root: e,
4
+ trigger: t,
5
+ content: n,
6
+ "stitch-menubar-in": "_stitch-menubar-in_907u3_1",
7
+ "stitch-menubar-out": "_stitch-menubar-out_907u3_1",
8
+ item: r,
9
+ danger: i,
10
+ itemIcon: a,
11
+ itemLabel: o,
12
+ subArrow: s
13
+ };
14
+ //#endregion
15
+ export { n as content, i as danger, c as default, r as item, a as itemIcon, o as itemLabel, e as root, s as subArrow, t as trigger };
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ export interface ModalProps {
3
+ /** 是否可见 */
4
+ open: boolean;
5
+ /** 标题 */
6
+ title?: React.ReactNode;
7
+ /** 宽度 @default 520 */
8
+ width?: number | string;
9
+ /**
10
+ * 点击遮罩是否关闭
11
+ * @default true
12
+ */
13
+ maskClosable?: boolean;
14
+ /** 底部按钮区域;`null` 隐藏页脚,`undefined` 用默认「取消/确定」 */
15
+ footer?: React.ReactNode | null;
16
+ /** 确认回调(默认页脚「确定」按钮) */
17
+ onOk?: () => void;
18
+ /** 关闭回调(遮罩 / Esc / 默认页脚「取消」触发;Ant v5 Modal 约定名 `onCancel`) */
19
+ onCancel?: () => void;
20
+ /** 对话框内容 */
21
+ children?: React.ReactNode;
22
+ /** 自定义类名 */
23
+ className?: string;
24
+ /** 遮罩层自定义样式 */
25
+ maskStyle?: React.CSSProperties;
26
+ /**
27
+ * 对话框语义角色:普通对话框用 `dialog`;必须做决策的确认框用 `alertdialog`
28
+ * (由 `AlertDialog` 复用本件时传入,读屏据此提示不可忽略)
29
+ * @default 'dialog'
30
+ */
31
+ role?: 'dialog' | 'alertdialog';
32
+ }
33
+ /**
34
+ * 对话框浮层:Portal 挂到 body,遮罩 + 居中面板。
35
+ * 打开时把焦点送进对话框并做 Tab 焦点陷阱,Esc / 点遮罩关闭,关闭时焦点归还触发元素(共享自 `useOverlay`)。
36
+ * `role`(默认 `dialog`,确认框变体传 `alertdialog`)+ `aria-modal` + `aria-labelledby`/`aria-describedby` 关联标题与正文。
37
+ */
38
+ export declare const Modal: React.FC<ModalProps>;
@@ -0,0 +1,68 @@
1
+ import { Button as e } from "../Button/Button.js";
2
+ import { useOverlay as t } from "../_internal/useOverlay.js";
3
+ import n from "./modal.module.js";
4
+ import { useCallback as r, useId as i, useRef as a } from "react";
5
+ import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
6
+ import { createPortal as l } from "react-dom";
7
+ //#region packages/react/src/components/Modal/Modal.tsx
8
+ var u = ({ open: u, title: d, width: f = 520, maskClosable: p = !0, footer: m, onOk: h, onCancel: g, children: _, className: v, maskStyle: y, role: b = "dialog" }) => {
9
+ let x = a(null);
10
+ t({
11
+ open: u,
12
+ containerRef: x,
13
+ onEscape: g
14
+ });
15
+ let S = r(() => {
16
+ p && g?.();
17
+ }, [p, g]), C = r((e) => {
18
+ e.stopPropagation();
19
+ }, []), w = `stitch-modal-${i().replace(/:/g, "")}`, T = `${w}-title`, E = `${w}-body`;
20
+ if (!u) return null;
21
+ let D = /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(e, {
22
+ type: "default",
23
+ onClick: g,
24
+ children: "取消"
25
+ }), /* @__PURE__ */ s(e, {
26
+ type: "primary",
27
+ onClick: h,
28
+ children: "确定"
29
+ })] }), O = /* @__PURE__ */ s("div", {
30
+ className: n.mask,
31
+ style: y,
32
+ onClick: S,
33
+ children: /* @__PURE__ */ c("div", {
34
+ ref: x,
35
+ className: [n.modal, v].filter(Boolean).join(" "),
36
+ style: { width: f },
37
+ onClick: C,
38
+ role: b,
39
+ "aria-modal": "true",
40
+ "aria-labelledby": d ? T : void 0,
41
+ "aria-describedby": E,
42
+ tabIndex: -1,
43
+ children: [
44
+ d && /* @__PURE__ */ s("div", {
45
+ className: n.header,
46
+ children: /* @__PURE__ */ s("div", {
47
+ className: n.title,
48
+ id: T,
49
+ children: d
50
+ })
51
+ }),
52
+ /* @__PURE__ */ s("div", {
53
+ className: n.body,
54
+ id: E,
55
+ children: _
56
+ }),
57
+ m !== null && /* @__PURE__ */ s("div", {
58
+ className: n.footer,
59
+ children: m === void 0 ? D : m
60
+ })
61
+ ]
62
+ })
63
+ });
64
+ return l(O, document.body);
65
+ };
66
+ u.displayName = "Modal";
67
+ //#endregion
68
+ export { u as Modal };
@@ -0,0 +1,2 @@
1
+ export { Modal } from './Modal';
2
+ export type { ModalProps } from './Modal';