@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,13 @@
1
+ //#region packages/react/src/components/Modal/modal.module.less
2
+ var e = "_mask_10ord_1", t = "_modal_10ord_11", n = "_header_10ord_32", r = "_title_10ord_38", i = "_body_10ord_45", a = "_footer_10ord_56", o = {
3
+ mask: e,
4
+ "stitch-modal-fade-in": "_stitch-modal-fade-in_10ord_1",
5
+ modal: t,
6
+ "stitch-modal-zoom-in": "_stitch-modal-zoom-in_10ord_1",
7
+ header: n,
8
+ title: r,
9
+ body: i,
10
+ footer: a
11
+ };
12
+ //#endregion
13
+ export { i as body, o as default, a as footer, n as header, e as mask, t as modal, r as title };
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ /**
3
+ * 站点导航里的一项。两种形态由字段组合决定:
4
+ * - **纯链接项**:给 `href`、不给 `content` → 渲染成 `<a>`(`NavigationMenu.Link`),点击跳转。
5
+ * - **带面板项**:给 `content` → 渲染成触发按钮 + 展开面板(`Trigger` + `Content`),
6
+ * `content` 是自由 `ReactNode`(可放链接列、图文卡片等导航内容)。
7
+ */
8
+ export interface NavItem {
9
+ /** 导航项文字(链接文本 / 触发按钮文本 = 可访问名来源) */
10
+ label: React.ReactNode;
11
+ /** 目标地址:给了即渲染为链接(无 `content` 时为纯链接项,透传到底层 `<a>` 的 `href`) */
12
+ href?: string;
13
+ /** 展开面板内容:给了即渲染为可展开项(`Trigger` + `Content`),内容自由 ReactNode */
14
+ content?: React.ReactNode;
15
+ /** 标记为当前项:底层挂 `data-active` + `aria-current="page"`,皮上走激活态(`--stitch-accent`) */
16
+ active?: boolean;
17
+ }
18
+ /**
19
+ * 站点导航菜单(顶栏一排导航项,部分项 hover/focus 展开一块面板):对外 `items` 数组,
20
+ * 每项按字段渲染成纯链接(`href`)或带展开面板(`content`)。组合底层
21
+ * `Root/List/Item/Trigger/Content/Link/Viewport`;根渲染 `<nav>` landmark。
22
+ *
23
+ * 跨-prop 注意事项:
24
+ * - **items 分支(= 核心 API)**:`href` 无 `content` → `NavigationMenu.Link`(纯链接、可跳转、
25
+ * 可标 `active`);有 `content` → `NavigationMenu.Trigger` + `NavigationMenu.Content`(展开面板,
26
+ * 面板内容自由 ReactNode)。与库里 Tabs / Select / DropdownMenu 一致走 `items` 数组心智。
27
+ * - **vs Tabs**:Tabs 是**页内切换面板内容**(tablist/tab、同页多视图、无跳转);NavigationMenu 是
28
+ * **站点导航**(链接为主,点击跳转 / 展开导航面板),别混用。
29
+ * - **vs Menubar**:Menubar 是应用式菜单栏,项触发**动作命令**;NavigationMenu 是**导航链接**,
30
+ * 项跳转或展开导航内容。
31
+ * - **面 = 浮起层**:展开面板走 `--stitch-bg-elevated` + `--stitch-text-primary`、边 `--stitch-border`、
32
+ * 圆角 `--stitch-radius-card`、阴影 `--stitch-shadow-base`;开合态 / 当前项由底层挂的
33
+ * `data-state`(`open`|`closed`)/ `data-active` 描,组件不自持显隐 state。
34
+ * - **键盘 / 焦点 / ARIA**(方向键走项、Enter 触发、Esc 关面板、焦点归还、`<nav>` + `data-active`
35
+ * → `aria-current`)由底层保证,组件不重复实现。
36
+ */
37
+ export interface NavigationMenuProps {
38
+ /** 导航项数组(纯链接 / 带展开面板混排) */
39
+ items: NavItem[];
40
+ /** 显隐变化回调(任一面板开合时触发,回当前展开项的 value;全关时为空串) */
41
+ onValueChange?: (value: string) => void;
42
+ /** 自定义类名(挂到根 `<nav>` 上) */
43
+ className?: string;
44
+ /** 根导航的可访问名(挂到 `<nav>` landmark) */
45
+ 'aria-label'?: string;
46
+ }
47
+ export declare const NavigationMenu: React.FC<NavigationMenuProps>;
@@ -0,0 +1,47 @@
1
+ import { Icon as e } from "../Icon/Icon.js";
2
+ import t from "./navigation-menu.module.js";
3
+ import "react";
4
+ import n from "clsx";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ import { NavigationMenu as a } from "radix-ui";
7
+ //#region packages/react/src/components/NavigationMenu/NavigationMenu.tsx
8
+ var o = ({ items: o, onValueChange: s, className: c, "aria-label": l }) => /* @__PURE__ */ i(a.Root, {
9
+ className: n(t.root, c),
10
+ "aria-label": l,
11
+ onValueChange: s,
12
+ children: [/* @__PURE__ */ r(a.List, {
13
+ className: t.list,
14
+ children: o.map((n, o) => {
15
+ let s = `${o}`;
16
+ return n.content === void 0 ? /* @__PURE__ */ r(a.Item, {
17
+ className: t.item,
18
+ children: /* @__PURE__ */ r(a.Link, {
19
+ className: t.link,
20
+ href: n.href,
21
+ active: n.active,
22
+ children: n.label
23
+ })
24
+ }, s) : /* @__PURE__ */ i(a.Item, {
25
+ className: t.item,
26
+ children: [/* @__PURE__ */ i(a.Trigger, {
27
+ className: t.trigger,
28
+ children: [n.label, /* @__PURE__ */ r(e, {
29
+ name: "chevron-down",
30
+ size: "1em",
31
+ className: t.caret,
32
+ "aria-hidden": !0
33
+ })]
34
+ }), /* @__PURE__ */ r(a.Content, {
35
+ className: t.content,
36
+ children: n.content
37
+ })]
38
+ }, s);
39
+ })
40
+ }), /* @__PURE__ */ r("div", {
41
+ className: t.viewportWrapper,
42
+ children: /* @__PURE__ */ r(a.Viewport, { className: t.viewport })
43
+ })]
44
+ });
45
+ o.displayName = "NavigationMenu";
46
+ //#endregion
47
+ export { o as NavigationMenu };
@@ -0,0 +1,2 @@
1
+ export { NavigationMenu } from './NavigationMenu';
2
+ export type { NavigationMenuProps, NavItem } from './NavigationMenu';
@@ -0,0 +1,16 @@
1
+ //#region packages/react/src/components/NavigationMenu/navigation-menu.module.less
2
+ var e = "_root_phcem_1", t = "_list_phcem_8", n = "_item_phcem_16", r = "_link_phcem_19", i = "_trigger_phcem_20", a = "_caret_phcem_52", o = "_viewportWrapper_phcem_60", s = "_viewport_phcem_60", c = "_content_phcem_85", l = {
3
+ root: e,
4
+ list: t,
5
+ item: n,
6
+ link: r,
7
+ trigger: i,
8
+ caret: a,
9
+ viewportWrapper: o,
10
+ viewport: s,
11
+ "stitch-navigation-menu-in": "_stitch-navigation-menu-in_phcem_1",
12
+ "stitch-navigation-menu-out": "_stitch-navigation-menu-out_phcem_1",
13
+ content: c
14
+ };
15
+ //#endregion
16
+ export { a as caret, c as content, l as default, n as item, r as link, t as list, e as root, i as trigger, s as viewport, o as viewportWrapper };
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import type { NotificationItem } from './types';
3
+ /**
4
+ * 内部单条通知视图,非公开命令式面。使用方走 `Notification.*` 静态方法而不直接渲染它,
5
+ * 故 `@internal` 标注、不进 skill 参考。
6
+ * @internal
7
+ */
8
+ export interface NotificationViewProps {
9
+ item: NotificationItem;
10
+ onRemove: (key: string) => void;
11
+ }
12
+ export declare const NotificationView: React.FC<NotificationViewProps>;
13
+ export declare const NOTIFICATION_ENTER_MS = 250;
14
+ export declare const NOTIFICATION_LEAVE_MS = 250;
@@ -0,0 +1,87 @@
1
+ import { Icon as e } from "../Icon/Icon.js";
2
+ import t from "./notification.module.js";
3
+ import n, { useEffect as r, useRef as i, useState as a } from "react";
4
+ import o from "clsx";
5
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
6
+ //#region packages/react/src/components/Notification/Notification.tsx
7
+ var l = 250, u = {
8
+ success: "success",
9
+ info: "info",
10
+ warning: "warning",
11
+ error: "error"
12
+ }, d = ({ item: d, onRemove: f }) => {
13
+ let [p, m] = a(!1), h = i(null), g = i(null), _ = n.useCallback(() => {
14
+ p || m(!0);
15
+ }, [p]);
16
+ r(() => {
17
+ if (!(!d.duration || d.duration <= 0)) return h.current = window.setTimeout(() => {
18
+ _();
19
+ }, d.duration * 1e3), () => {
20
+ h.current !== null && (window.clearTimeout(h.current), h.current = null);
21
+ };
22
+ }, [d.duration, _]), r(() => {
23
+ if (p) return g.current = window.setTimeout(() => {
24
+ f(d.key), d.onClose?.();
25
+ }, l), () => {
26
+ g.current !== null && (window.clearTimeout(g.current), g.current = null);
27
+ };
28
+ }, [
29
+ p,
30
+ d.key,
31
+ d.onClose,
32
+ f
33
+ ]);
34
+ let v = (e) => {
35
+ e.stopPropagation(), _();
36
+ }, y = () => {
37
+ d.onClick && d.onClick();
38
+ }, b = o(t.notification, t[`type-${d.type}`], t[`placement-${d.placement}`], p && t.leaving, !!d.onClick && t.clickable, d.className), x = d.icon ?? /* @__PURE__ */ s(e, {
39
+ name: u[d.type],
40
+ size: "1em",
41
+ style: { color: "var(--stitch-text-on-dark)" }
42
+ });
43
+ return /* @__PURE__ */ c("div", {
44
+ className: b,
45
+ style: d.style,
46
+ onClick: y,
47
+ role: d.onClick ? "button" : void 0,
48
+ tabIndex: d.onClick ? 0 : void 0,
49
+ onKeyDown: (e) => {
50
+ d.onClick && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), d.onClick());
51
+ },
52
+ "data-notification-key": d.key,
53
+ children: [
54
+ /* @__PURE__ */ s("div", {
55
+ className: t.iconWrap,
56
+ "aria-hidden": !0,
57
+ children: x
58
+ }),
59
+ /* @__PURE__ */ c("div", {
60
+ className: t.body,
61
+ children: [/* @__PURE__ */ s("div", {
62
+ className: t.title,
63
+ children: d.message
64
+ }), d.description !== void 0 && d.description !== null && /* @__PURE__ */ s("div", {
65
+ className: t.description,
66
+ children: d.description
67
+ })]
68
+ }),
69
+ d.btn && /* @__PURE__ */ s("div", {
70
+ className: t.btnSlot,
71
+ children: d.btn
72
+ }),
73
+ /* @__PURE__ */ s("button", {
74
+ type: "button",
75
+ className: t.close,
76
+ "aria-label": "关闭",
77
+ onClick: v,
78
+ children: d.closeIcon ?? /* @__PURE__ */ s(e, {
79
+ name: "close",
80
+ size: "1em"
81
+ })
82
+ })
83
+ ]
84
+ });
85
+ };
86
+ //#endregion
87
+ export { d as NotificationView };
@@ -0,0 +1,29 @@
1
+ import type { NotificationConfig, NotificationType } from './types';
2
+ declare const open: (config: NotificationConfig | string, type?: NotificationType) => void;
3
+ declare const destroy: (key?: string) => void;
4
+ /**
5
+ * **命令式 API,不是 JSX 组件** —— 导出的 `Notification` 是一组 antd 风格静态方法;
6
+ * 你调用它们弹通知,而不是渲染 `<Notification />`。调用本身不返回节点、不挂载到你的树里
7
+ * (首次调用会自挂一个 Portal 到 `document.body`,每个 position 栈是 `aria-live="polite"`
8
+ * 区域,新通知会被读屏播报)。`NotificationViewProps` 是内部单条视图、非公开面。
9
+ *
10
+ * - `Notification.success(config | string)` / `.info` / `.warning` / `.error`
11
+ * - `Notification.open(config | string)` —— 等价 `.info`
12
+ * - `Notification.destroy()` 关闭全部;`Notification.destroy(key)` 关闭指定 key
13
+ * - `config` 可传字符串(仅 `message`)或完整 `NotificationConfig` 对象
14
+ * - 默认位置 `top`(顶部居中);默认 `duration: 4.5` 秒,传 `0` 不自动关闭
15
+ * - 显式指定 `key` 后再次 `open` 同 key 会更新现有通知而不是新增一条
16
+ * - 4 类型默认图标与关闭图标都走内置具名 `<Icon>`(品牌中立、随 currentColor 换肤,无 emoji / 裸 SVG / Unicode 符号)
17
+ */
18
+ export interface NotificationStatic {
19
+ (config: NotificationConfig | string): void;
20
+ open: (config: NotificationConfig | string) => void;
21
+ success: (config: NotificationConfig | string) => void;
22
+ info: (config: NotificationConfig | string) => void;
23
+ warning: (config: NotificationConfig | string) => void;
24
+ error: (config: NotificationConfig | string) => void;
25
+ destroy: (key?: string) => void;
26
+ }
27
+ export declare const Notification: NotificationStatic;
28
+ export { open as notificationOpen, destroy as notificationDestroy };
29
+ export declare const NOTIFICATION_DEFAULT_DURATION = 4.5;
@@ -0,0 +1,90 @@
1
+ import e from "./notification.module.js";
2
+ import { NotificationView as t } from "./Notification.js";
3
+ import { useCallback as n, useSyncExternalStore as r } from "react";
4
+ import i from "clsx";
5
+ import { Fragment as a, jsx as o } from "react/jsx-runtime";
6
+ import { createRoot as s } from "react-dom/client";
7
+ //#region packages/react/src/components/Notification/NotificationPortal.tsx
8
+ var c = 4.5, l = {
9
+ top: "top",
10
+ topLeft: "top",
11
+ topRight: "top",
12
+ bottom: "bottom",
13
+ bottomLeft: "bottom",
14
+ bottomRight: "bottom"
15
+ }, u = [
16
+ "top",
17
+ "topLeft",
18
+ "topRight",
19
+ "bottom",
20
+ "bottomLeft",
21
+ "bottomRight"
22
+ ], d = [], f = 0, p = /* @__PURE__ */ new Set(), m = null, h = null, g = (e) => (p.add(e), () => {
23
+ p.delete(e);
24
+ }), _ = () => d, v = () => [], y = () => {
25
+ if (h || typeof document > "u") return;
26
+ let t = document.createElement("div");
27
+ t.setAttribute("data-stitch-notification-root", ""), t.className = e.notificationRoot, document.body.appendChild(t), m = t, h = s(m), h.render(/* @__PURE__ */ o(x, {}));
28
+ }, b = () => {
29
+ h || typeof document > "u" || y();
30
+ }, x = () => {
31
+ let e = r(g, _, v);
32
+ return /* @__PURE__ */ o(S, { items: e });
33
+ }, S = ({ items: r }) => {
34
+ let s = n((e) => {
35
+ let t = d.filter((t) => t.key !== e);
36
+ t.length !== d.length && (d = t, p.forEach((e) => e()));
37
+ }, []);
38
+ return /* @__PURE__ */ o(a, { children: u.map((n) => {
39
+ let a = r.filter((e) => e.position === n);
40
+ return a.length === 0 ? null : /* @__PURE__ */ o("div", {
41
+ className: i(e[`position-${n}`]),
42
+ "data-position": n,
43
+ role: "region",
44
+ "aria-label": `通知(${n})`,
45
+ "aria-live": "polite",
46
+ "aria-relevant": "additions",
47
+ children: a.map((e) => /* @__PURE__ */ o(t, {
48
+ item: e,
49
+ onRemove: s
50
+ }, e.key))
51
+ }, n);
52
+ }) });
53
+ }, C = (e, t) => {
54
+ let n = typeof e == "string" ? { message: e } : { ...e }, r = n.position ?? "top";
55
+ return f += 1, {
56
+ ...n,
57
+ type: t,
58
+ key: n.key ?? `stitch-notification-${Date.now()}-${f}`,
59
+ position: r,
60
+ placement: l[r],
61
+ duration: n.duration ?? c,
62
+ createdAt: Date.now()
63
+ };
64
+ }, w = (e, t = "info") => {
65
+ if (typeof document > "u") return;
66
+ let n = C(e, t);
67
+ if (n.key) {
68
+ let e = d.findIndex((e) => e.key === n.key);
69
+ if (e !== -1) {
70
+ let t = d.slice();
71
+ t[e] = n, d = t, p.forEach((e) => e());
72
+ return;
73
+ }
74
+ }
75
+ d = [...d, n], p.forEach((e) => e()), b();
76
+ }, T = (e) => {
77
+ let t = [];
78
+ if (e) {
79
+ t = d.filter((t) => t.key === e);
80
+ let n = d.filter((t) => t.key !== e);
81
+ if (n.length === d.length) return;
82
+ d = n;
83
+ } else if (d.length === 0) return;
84
+ else t = d.slice(), d = [];
85
+ p.forEach((e) => e()), t.forEach((e) => e.onClose?.());
86
+ }, E = ((e) => w(e, "info"));
87
+ E.open = (e) => w(e, "info"), E.success = (e) => w(e, "success"), E.info = (e) => w(e, "info"), E.warning = (e) => w(e, "warning"), E.error = (e) => w(e, "error"), E.destroy = T;
88
+ var D = E;
89
+ //#endregion
90
+ export { D as Notification, T as notificationDestroy, w as notificationOpen };
@@ -0,0 +1,4 @@
1
+ export { Notification, notificationOpen, notificationDestroy, NOTIFICATION_DEFAULT_DURATION, } from './NotificationPortal';
2
+ export type { NotificationStatic } from './NotificationPortal';
3
+ export type { NotificationViewProps } from './Notification';
4
+ export type { NotificationConfig, NotificationType, NotificationPosition, NotificationPlacement, NotificationItem, } from './types';
@@ -0,0 +1,31 @@
1
+ //#region packages/react/src/components/Notification/notification.module.less
2
+ var e = "_notificationRoot_1yy4u_1", t = "_notification_1yy4u_1", n = "_clickable_1yy4u_74", r = "_iconWrap_1yy4u_88", i = "_body_1yy4u_125", a = "_title_1yy4u_132", o = "_description_1yy4u_140", s = "_btnSlot_1yy4u_147", c = "_close_1yy4u_153", l = "_leaving_1yy4u_182", u = {
3
+ notificationRoot: e,
4
+ "position-top": "_position-top_1yy4u_8",
5
+ "position-topLeft": "_position-topLeft_1yy4u_9",
6
+ "position-topRight": "_position-topRight_1yy4u_10",
7
+ "position-bottom": "_position-bottom_1yy4u_11",
8
+ "position-bottomLeft": "_position-bottomLeft_1yy4u_12",
9
+ "position-bottomRight": "_position-bottomRight_1yy4u_13",
10
+ notification: t,
11
+ clickable: n,
12
+ "type-success": "_type-success_1yy4u_85",
13
+ iconWrap: r,
14
+ "type-info": "_type-info_1yy4u_92",
15
+ "type-warning": "_type-warning_1yy4u_99",
16
+ "type-error": "_type-error_1yy4u_106",
17
+ body: i,
18
+ title: a,
19
+ description: o,
20
+ btnSlot: s,
21
+ close: c,
22
+ "placement-top": "_placement-top_1yy4u_179",
23
+ "stitch-notification-slide-from-top": "_stitch-notification-slide-from-top_1yy4u_1",
24
+ leaving: l,
25
+ "stitch-notification-slide-out-top": "_stitch-notification-slide-out-top_1yy4u_1",
26
+ "placement-bottom": "_placement-bottom_1yy4u_185",
27
+ "stitch-notification-rise-from-bottom": "_stitch-notification-rise-from-bottom_1yy4u_1",
28
+ "stitch-notification-sink-out-bottom": "_stitch-notification-sink-out-bottom_1yy4u_1"
29
+ };
30
+ //#endregion
31
+ export { i as body, s as btnSlot, n as clickable, c as close, u as default, o as description, r as iconWrap, l as leaving, t as notification, e as notificationRoot, a as title };
@@ -0,0 +1,44 @@
1
+ import type { ReactNode } from 'react';
2
+ export type NotificationType = 'success' | 'info' | 'warning' | 'error';
3
+ export type NotificationPosition = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight';
4
+ export type NotificationPlacement = 'top' | 'bottom';
5
+ export interface NotificationConfig {
6
+ /** 通知标题(必填) */
7
+ message: ReactNode;
8
+ /** 通知描述/正文,支持 ReactNode */
9
+ description?: ReactNode;
10
+ /** 自动关闭延时(秒),默认 4.5;传 0 不自动关闭 */
11
+ duration?: number;
12
+ /** 出现位置,默认 'top'(顶部居中) */
13
+ position?: NotificationPosition;
14
+ /** 类型 */
15
+ type?: NotificationType;
16
+ /** 自定义图标(优先级高于 type 默认图标) */
17
+ icon?: ReactNode;
18
+ /** 自定义操作按钮,渲染在关闭按钮左侧 */
19
+ btn?: ReactNode;
20
+ /** 唯一 key,显式指定后再次调用 open 同 key 会更新现有通知而不是新增 */
21
+ key?: string;
22
+ /** 关闭回调 */
23
+ onClose?: () => void;
24
+ /** 点击通知本体回调 */
25
+ onClick?: () => void;
26
+ /** 自定义关闭图标 */
27
+ closeIcon?: ReactNode;
28
+ /** 自定义类名 */
29
+ className?: string;
30
+ /** 自定义样式 */
31
+ style?: React.CSSProperties;
32
+ }
33
+ export interface NotificationItem extends NotificationConfig {
34
+ /** 运行时唯一 key */
35
+ key: string;
36
+ /** 实际类型(已 fallback) */
37
+ type: NotificationType;
38
+ /** 实际 position(已 fallback) */
39
+ position: NotificationPosition;
40
+ /** placement 由 position 推导(用于出场动画方向) */
41
+ placement: NotificationPlacement;
42
+ /** 创建时间戳 */
43
+ createdAt: number;
44
+ }
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ /**
3
+ * 一次性验证码分格输入(OTP):定长的一排单字符输入格,自动跳格、支持整段粘贴分发。
4
+ * 按 `length` 渲染 `length` 个分格(外加隐藏聚合 input 供表单提交),取整串值:
5
+ * `value`/`defaultValue`/`onChange`(整串)+ `disabled` + `autoFocus`。
6
+ *
7
+ * 跨-prop 注意事项:
8
+ * - **length → 格数**:内部按 `length` 渲染 `length` 个分格(底层每个 `Input` = 一个字符位);
9
+ * `length` 是渲染数量的唯一来源,不由 children 传入。
10
+ * - **值聚合 → onChange(string)**:每格一字符,底层把各格拼成整串;值变更回调回**整串**
11
+ * (底层 `onValueChange(string)` → 我们的 `onChange(string)`)。
12
+ * - **受控/非受控双模式**:给 `value` 由父管(配 `onChange`),只给 `defaultValue` 组件自管;
13
+ * 两者均为整串、直接透传底层(不自持 state)。
14
+ * - **vs Input**:Input 是单框自由文本;OtpField 是定长分格验证码(每格一字符、自动跳格)。
15
+ * - **vs PasswordInput**:那是可明暗切换的密码框;OtpField 是分格验证码,二者别混。
16
+ * - **Less 皮**:每格走 `--stitch-radius-input` + `--stitch-border`(focus → `--stitch-accent`
17
+ * + focus 环 `--stitch-focus-ring`),与表单控件族对齐;禁用态由底层给每格挂 `disabled`。
18
+ * - **键盘 / 焦点 / 跳格 / 粘贴分发 / ARIA** 由底层保证,组件不重复实现。
19
+ */
20
+ export interface OtpFieldProps {
21
+ /** 格数(验证码位数);内部按此渲染 length 个分格 */
22
+ length: number;
23
+ /** 受控值(整串) */
24
+ value?: string;
25
+ /** 非受控初始值(整串) */
26
+ defaultValue?: string;
27
+ /** 值变化回调;回聚合后的整串 */
28
+ onChange?: (value: string) => void;
29
+ /** 禁用 */
30
+ disabled?: boolean;
31
+ /** 挂载即聚焦第一格 */
32
+ autoFocus?: boolean;
33
+ /** 自定义类名(挂到根分格容器) */
34
+ className?: string;
35
+ /** 无障碍标签(给分格组一个可及名) */
36
+ 'aria-label'?: string;
37
+ /** 关联外部可见 label 的 id */
38
+ 'aria-labelledby'?: string;
39
+ }
40
+ export declare const OtpField: React.FC<OtpFieldProps>;
@@ -0,0 +1,20 @@
1
+ import e from "./otp-field.module.js";
2
+ import "react";
3
+ import t from "clsx";
4
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
+ import { unstable_OneTimePasswordField as i } from "radix-ui";
6
+ //#region packages/react/src/components/OtpField/OtpField.tsx
7
+ var a = ({ length: a, value: o, defaultValue: s, onChange: c, disabled: l = !1, autoFocus: u, className: d, "aria-label": f, "aria-labelledby": p }) => /* @__PURE__ */ r(i.Root, {
8
+ className: t(e.root, d),
9
+ value: o,
10
+ defaultValue: s,
11
+ onValueChange: c,
12
+ disabled: l,
13
+ autoFocus: u,
14
+ "aria-label": f,
15
+ "aria-labelledby": p,
16
+ children: [Array.from({ length: a }, (t, r) => /* @__PURE__ */ n(i.Input, { className: e.input }, r)), /* @__PURE__ */ n(i.HiddenInput, {})]
17
+ });
18
+ a.displayName = "OtpField";
19
+ //#endregion
20
+ export { a as OtpField };
@@ -0,0 +1,2 @@
1
+ export { OtpField } from './OtpField';
2
+ export type { OtpFieldProps } from './OtpField';
@@ -0,0 +1,7 @@
1
+ //#region packages/react/src/components/OtpField/otp-field.module.less
2
+ var e = "_root_iee8a_1", t = "_input_iee8a_7", n = {
3
+ root: e,
4
+ input: t
5
+ };
6
+ //#endregion
7
+ export { n as default, t as input, e as root };
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import { type InputProps } from '../Input';
3
+ /**
4
+ * 密码框:在底件 `Input` 之上只加「明暗切换」那一层——`suffix` 槽 / `type` 透传 / 受控·非受控
5
+ * 值范式 / 边框 / 校验态全复用 `Input`(不重写)。相对普通 `Input` 补一点:
6
+ *
7
+ * - 内部持 `visible` 态,`type = visible ? 'text' : 'password'` 透给底件(对外不暴露 `type`);
8
+ * `suffix` 塞一个眼睛按钮,点击翻 `visible`,按钮的 `aria-label` 与 `<Icon>`(eye ↔ eye-off)
9
+ * 随态切换。切换钮是原生 `<button type="button">`:可 Tab 聚焦、Enter/Space 触发。
10
+ *
11
+ * 跨-prop 注意事项:
12
+ * - **省去 `type` / `suffix`**——由本件内部管;`type` 恒为 password/text 二态,`suffix` 恒为切换钮。
13
+ * - **值仍走底件的受控/非受控双模式**:给 `value` 由父管,只给 `defaultValue` 组件自管
14
+ * (`onChange` 收到的与底件一致)。可见态只影响遮蔽显示,不改值。
15
+ * - **切换钮图标走 `<Icon name="eye"/"eye-off">`**(描边、随 `--stitch-*` 换肤)——**Do NOT** 传
16
+ * emoji / Unicode / 裸 `<svg>`。可访问名由 `showAriaLabel` / `hideAriaLabel` 定。
17
+ * - `visibilityToggle={false}` 时不渲染切换钮、恒遮蔽(`suffix` 留空,值仍可键入)。
18
+ */
19
+ export interface PasswordInputProps extends Omit<InputProps, 'type' | 'suffix'> {
20
+ /**
21
+ * 是否显示明暗切换按钮(关掉则恒遮蔽)
22
+ * @default true
23
+ */
24
+ visibilityToggle?: boolean;
25
+ /**
26
+ * 遮蔽态下切换钮的可访问名(点击将显示密码)
27
+ * @default '显示密码'
28
+ */
29
+ showAriaLabel?: string;
30
+ /**
31
+ * 可见态下切换钮的可访问名(点击将隐藏密码)
32
+ * @default '隐藏密码'
33
+ */
34
+ hideAriaLabel?: string;
35
+ }
36
+ export declare const PasswordInput: React.FC<PasswordInputProps>;
@@ -0,0 +1,28 @@
1
+ import { Icon as e } from "../Icon/Icon.js";
2
+ import { Input as t } from "../Input/Input.js";
3
+ import n from "./password-input.module.js";
4
+ import { useCallback as r, useState as i } from "react";
5
+ import { jsx as a } from "react/jsx-runtime";
6
+ //#region packages/react/src/components/PasswordInput/PasswordInput.tsx
7
+ var o = ({ visibilityToggle: o = !0, showAriaLabel: s = "显示密码", hideAriaLabel: c = "隐藏密码", disabled: l = !1, ...u }) => {
8
+ let [d, f] = i(!1), p = r(() => f((e) => !e), []), m = o && !l ? /* @__PURE__ */ a("button", {
9
+ type: "button",
10
+ className: n.toggle,
11
+ onClick: p,
12
+ "aria-label": d ? c : s,
13
+ "aria-pressed": d,
14
+ children: /* @__PURE__ */ a(e, {
15
+ name: d ? "eye-off" : "eye",
16
+ size: 16
17
+ })
18
+ }) : void 0;
19
+ return /* @__PURE__ */ a(t, {
20
+ ...u,
21
+ type: d ? "text" : "password",
22
+ disabled: l,
23
+ suffix: m
24
+ });
25
+ };
26
+ o.displayName = "PasswordInput";
27
+ //#endregion
28
+ export { o as PasswordInput };
@@ -0,0 +1,2 @@
1
+ export { PasswordInput } from './PasswordInput';
2
+ export type { PasswordInputProps } from './PasswordInput';
@@ -0,0 +1,4 @@
1
+ //#region packages/react/src/components/PasswordInput/password-input.module.less
2
+ var e = "_toggle_ksvhb_1", t = { toggle: e };
3
+ //#endregion
4
+ export { t as default, e as toggle };
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ /**
3
+ * 可交互浮层(Ant `Popover` 语义):`trigger` 触发器 + `children` 浮层内容(可放按钮 / 表单 /
4
+ * 链接)+ 受控 `open` / 非受控 `defaultOpen` / `onOpenChange`。click 触发,点外部或 Esc 关闭。
5
+ *
6
+ * 跨-prop 注意事项:
7
+ * - **vs Tooltip**:Tooltip 是短文字提示、hover 触发、`role="tooltip"`、不含交互;Popover 是
8
+ * **click 触发的可交互浮层**,内容可获得焦点、可交互,别混用。
9
+ * - **受控/非受控双模式**:给 `open` 由父管(配 `onOpenChange`),只给 `defaultOpen` 组件自管;
10
+ * 两者与底层同名,直接透传。
11
+ * - **面 = 浮起层**:浮层走 `--stitch-bg-elevated`(浮起面)+ `--stitch-text-primary`,
12
+ * 边框 `--stitch-border`、圆角 `--stitch-radius-card`、阴影 `--stitch-shadow-base`;开合态由
13
+ * 底层挂的 `data-state` 描(`open` 时淡入),组件不自持显隐 state。
14
+ * - **键盘 / 焦点 / ARIA**(Esc 关、焦点陷阱与归还、`aria-expanded`)由底层保证,组件不重复实现;
15
+ * 但浮层是 `role="dialog"`,**须有可及名**——用 `aria-label` 或 `aria-labelledby` 指定(内容相关,
16
+ * 由使用者给)。
17
+ */
18
+ export interface PopoverProps {
19
+ /** 触发器:任意可承载 click 与焦点的元素(如 `<button>`),浮层锚定其上 */
20
+ trigger: React.ReactNode;
21
+ /** 浮层内容,可含按钮 / 表单 / 链接等可交互元素 */
22
+ children?: React.ReactNode;
23
+ /** 浮层(`role="dialog"`)的可及名——无可见标题时用它 */
24
+ 'aria-label'?: string;
25
+ /** 浮层的可及名来源:指向浮层内标题元素的 id */
26
+ 'aria-labelledby'?: string;
27
+ /** 受控显隐(气泡浮层约定:Ant v5 `open`) */
28
+ open?: boolean;
29
+ /** 非受控初始显隐 @default false */
30
+ defaultOpen?: boolean;
31
+ /** 显隐变化回调(气泡浮层约定:Ant v5 `onOpenChange`) */
32
+ onOpenChange?: (open: boolean) => void;
33
+ /** 触发器与浮层的间距(px) @default 8 */
34
+ sideOffset?: number;
35
+ /** 自定义类名(挂到浮层面上) */
36
+ className?: string;
37
+ }
38
+ /**
39
+ * 可交互浮层:click 触发,点外部 / Esc 关闭,焦点管理与 ARIA 由底层保证;
40
+ * 受控(`open`/`onOpenChange`)与非受控双模式。
41
+ */
42
+ export declare const Popover: React.FC<PopoverProps>;