@qw-ui/core 0.1.0 → 0.2.0-next.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 (57) hide show
  1. package/dist/avatar/avatar.d.ts +145 -0
  2. package/dist/avatar/index.d.ts +1 -0
  3. package/dist/avatar/index.js +150 -0
  4. package/dist/avatar/index.js.map +1 -0
  5. package/dist/button/button.d.ts +84 -0
  6. package/dist/button/index.d.ts +1 -0
  7. package/dist/button/index.js +104 -0
  8. package/dist/button/index.js.map +1 -0
  9. package/dist/dialog/dialog.d.ts +59 -0
  10. package/dist/dialog/index.d.ts +1 -56
  11. package/dist/dialog/index.js +31 -30
  12. package/dist/dialog/index.js.map +1 -1
  13. package/dist/divider/divider.d.ts +23 -0
  14. package/dist/divider/index.d.ts +1 -0
  15. package/dist/divider/index.js +18 -0
  16. package/dist/divider/index.js.map +1 -0
  17. package/dist/empty/empty.d.ts +12 -0
  18. package/dist/empty/index.d.ts +1 -0
  19. package/dist/empty/index.js +21 -0
  20. package/dist/empty/index.js.map +1 -0
  21. package/dist/icon/icon.d.ts +11 -0
  22. package/dist/icon/index.d.ts +1 -0
  23. package/dist/icon/index.js +20 -0
  24. package/dist/icon/index.js.map +1 -0
  25. package/dist/image/image.d.ts +88 -0
  26. package/dist/image/index.d.ts +1 -0
  27. package/dist/image/index.js +84 -0
  28. package/dist/image/index.js.map +1 -0
  29. package/dist/index.d.ts +22 -4
  30. package/dist/index.js +12 -50
  31. package/dist/loading/index.d.ts +1 -0
  32. package/dist/loading/index.js +19 -0
  33. package/dist/loading/index.js.map +1 -0
  34. package/dist/loading/loading.d.ts +26 -0
  35. package/dist/search-bar/index.d.ts +1 -0
  36. package/dist/search-bar/index.js +252 -0
  37. package/dist/search-bar/index.js.map +1 -0
  38. package/dist/search-bar/search-bar.d.ts +146 -0
  39. package/dist/skeleton/index.d.ts +1 -0
  40. package/dist/skeleton/index.js +28 -0
  41. package/dist/skeleton/index.js.map +1 -0
  42. package/dist/skeleton/skeleton.d.ts +38 -0
  43. package/dist/tabs/index.d.ts +1 -36
  44. package/dist/tabs/index.js +34 -18
  45. package/dist/tabs/index.js.map +1 -1
  46. package/dist/tabs/tabs.d.ts +61 -0
  47. package/dist/toast/index.d.ts +1 -0
  48. package/dist/toast/index.js +44 -0
  49. package/dist/toast/index.js.map +1 -0
  50. package/dist/toast/toast.d.ts +52 -0
  51. package/dist/top-bar/index.d.ts +1 -0
  52. package/dist/top-bar/index.js +43 -0
  53. package/dist/top-bar/index.js.map +1 -0
  54. package/dist/top-bar/top-bar.d.ts +86 -0
  55. package/dist/visual-manifest.d.ts +142 -0
  56. package/package.json +61 -4
  57. package/dist/index.js.map +0 -1
@@ -0,0 +1,61 @@
1
+ import type { Props as ZagTabsProps } from "@zag-js/tabs";
2
+ /**
3
+ * Tabs 契约 — 原型 B(有状态),core 包裹 zag.js tabs machine。
4
+ * 行为 props 进 createTabsProps → zag context;视觉 props(level/variant/size)
5
+ * 不进 machine,由适配层挂 data-* 属性驱动 CSS。
6
+ *
7
+ * 枚举以运行时常量数组为唯一事实源(类型从常量推导),__test__ 直接锁死词表。
8
+ */
9
+ /** 导航层级全集:primary 一级导航(默认)/ secondary 二级导航。 */
10
+ export declare const TABS_LEVELS: readonly ["primary", "secondary"];
11
+ export type TabsLevel = (typeof TABS_LEVELS)[number];
12
+ /** 视觉形态全集:text 纯文本(默认)/ button 按钮。button 仅 secondary 支持。 */
13
+ export declare const TABS_VARIANTS: readonly ["text", "button"];
14
+ export type TabsVariant = (typeof TABS_VARIANTS)[number];
15
+ /** 字号全集:仅 primary 生效,"14" / "16"(默认)。 */
16
+ export declare const TABS_SIZES: readonly ["14", "16"];
17
+ export type TabsSize = (typeof TABS_SIZES)[number];
18
+ /**
19
+ * QwTabsProps — 双栈共享的行为 + 视觉契约。
20
+ * 行为 props(进 createTabsProps → zag machine):
21
+ * - loop(默认 true)→ zag loopFocus;
22
+ * - value / defaultValue / activationMode 透传;
23
+ * - onValueChange 适配 zag details。
24
+ * 视觉 props(不进 machine,适配层挂 data-*):
25
+ * - level / variant / size。
26
+ */
27
+ export interface QwTabsProps {
28
+ /** 唯一 id 前缀;不传由适配层生成 (SSR/CSR 一致)。 */
29
+ id?: string;
30
+ /** 受控当前项。 */
31
+ value?: string | null;
32
+ /** 非受控初值。 */
33
+ defaultValue?: string | null;
34
+ /** 激活模式,默认 automatic(聚焦即激活)。 */
35
+ activationMode?: "manual" | "automatic";
36
+ /** 方向键首尾循环,默认 true (zag 原名 loopFocus)。 */
37
+ loop?: boolean;
38
+ /** 选中项变化回调;zag 原生 onValueChange。 */
39
+ onValueChange?: (e: {
40
+ value: string;
41
+ }) => void;
42
+ /** 导航层级,默认 primary。 */
43
+ level?: TabsLevel;
44
+ /** 视觉形态,默认 text。level=primary 时强制 text。 */
45
+ variant?: TabsVariant;
46
+ /** 字号,默认 "16"。仅 level=primary 生效。 */
47
+ size?: TabsSize;
48
+ }
49
+ /**
50
+ * 直接 re-export zag tabs 的 machine 与 connect —— 不包一层。
51
+ * 用 re-export 保留原始可移植类型 (避免 TS2742)。
52
+ */
53
+ export { machine as tabsMachine, connect } from "@zag-js/tabs";
54
+ /** rebrand zag 的 TabsApi 类型对外。 */
55
+ export type { Api as QwTabsApi } from "@zag-js/tabs";
56
+ /**
57
+ * 把 QwTabsProps 的行为 props 转成 zag tabs machine 的 props (默认值收口 + 命名 rebrand)。
58
+ * 视觉 props(level/variant/size)不出现在返回值中——它们是适配层 data-* 属性。
59
+ * 用法:`useMachine(tabsMachine, createTabsProps(props))`。
60
+ */
61
+ export declare function createTabsProps(props?: QwTabsProps): Partial<ZagTabsProps>;
@@ -0,0 +1 @@
1
+ export * from "./toast.js";
@@ -0,0 +1,44 @@
1
+ //#region src/toast/toast.ts
2
+ /**
3
+ * @qw-ui/core · Toast 契约(原型 D · 自研命令式单例)
4
+ * ─────────────────────────────────────────────────────────────
5
+ * 纯 TS / SSR-safe,零框架依赖。只收口「框架无关的选项契约 + 纯函数」:
6
+ * 交互(命令式挂载 / 计时 / 渲染)落在各框架适配层,节点类型(icon/content)
7
+ * 由适配层用 `ReactNode` / `VNode` 具体化 `QwToastOptions<Node>`。
8
+ */
9
+ /** 垂直显示位置。 */
10
+ const TOAST_POSITIONS = [
11
+ "top",
12
+ "bottom",
13
+ "center"
14
+ ];
15
+ /** 内建状态图标类型。 */
16
+ const TOAST_ICON_TYPES = [
17
+ "success",
18
+ "fail",
19
+ "loading"
20
+ ];
21
+ /** 逻辑部件(承载 data-part 样式与 parity 指纹)。 */
22
+ const TOAST_PARTS = [
23
+ "mask",
24
+ "wrap",
25
+ "body",
26
+ "icon",
27
+ "content"
28
+ ];
29
+ /** 默认展示时长(ms)。 */
30
+ const DEFAULT_TOAST_DURATION = 3e3;
31
+ /** 默认垂直位置(对齐设计稿:默认顶部)。 */
32
+ const DEFAULT_TOAST_POSITION = "top";
33
+ /** 判断 icon 是否为内建状态图标类型。 */
34
+ function isToastIconType(icon) {
35
+ return typeof icon === "string" && TOAST_ICON_TYPES.includes(icon);
36
+ }
37
+ /** 解析持续时间:未传用默认 3000;显式 0 透传(不自动关闭)。 */
38
+ function resolveToastDuration(duration) {
39
+ return duration == null ? DEFAULT_TOAST_DURATION : duration;
40
+ }
41
+ //#endregion
42
+ export { DEFAULT_TOAST_DURATION, DEFAULT_TOAST_POSITION, TOAST_ICON_TYPES, TOAST_PARTS, TOAST_POSITIONS, isToastIconType, resolveToastDuration };
43
+
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/toast/toast.ts"],"sourcesContent":["/**\n * @qw-ui/core · Toast 契约(原型 D · 自研命令式单例)\n * ─────────────────────────────────────────────────────────────\n * 纯 TS / SSR-safe,零框架依赖。只收口「框架无关的选项契约 + 纯函数」:\n * 交互(命令式挂载 / 计时 / 渲染)落在各框架适配层,节点类型(icon/content)\n * 由适配层用 `ReactNode` / `VNode` 具体化 `QwToastOptions<Node>`。\n */\n\n/** 垂直显示位置。 */\nexport const TOAST_POSITIONS = [\"top\", \"bottom\", \"center\"] as const;\nexport type QwToastPosition = (typeof TOAST_POSITIONS)[number];\n\n/** 内建状态图标类型。 */\nexport const TOAST_ICON_TYPES = [\"success\", \"fail\", \"loading\"] as const;\nexport type QwToastIconType = (typeof TOAST_ICON_TYPES)[number];\n\n/** 逻辑部件(承载 data-part 样式与 parity 指纹)。 */\nexport const TOAST_PARTS = [\"mask\", \"wrap\", \"body\", \"icon\", \"content\"] as const;\nexport type QwToastPart = (typeof TOAST_PARTS)[number];\n\n/** 默认展示时长(ms)。 */\nexport const DEFAULT_TOAST_DURATION = 3000;\n\n/** 默认垂直位置(对齐设计稿:默认顶部)。 */\nexport const DEFAULT_TOAST_POSITION: QwToastPosition = \"top\";\n\n/**\n * Toast 选项契约。`Node` / `Style` 由适配层具体化\n * (React `ReactNode` / `CSSProperties`;Vue `VNode` / `StyleValue`)。\n * 与 antd-mobile 风格对齐:命令式 `Toast.show(options)`。\n */\nexport interface QwToastOptions<Node = unknown, Style = unknown> {\n /** 提示主文案。可空(纯图标提示)。 */\n content?: Node;\n /** 前置图标:内建类型 `success | fail | loading`,或任意自定义节点;不传则不展示图标。 */\n icon?: QwToastIconType | Node;\n /** 持续时间(ms),默认 3000;为 0 时不自动关闭。 */\n duration?: number;\n /** 垂直显示位置,默认 top。 */\n position?: QwToastPosition;\n /** 自定义遮罩层内联样式。 */\n maskStyle?: Style;\n /** 自定义遮罩层 class。 */\n maskClassName?: string;\n /** 关闭后回调(自动消失或手动 clear 均触发)。 */\n afterClose?: () => void;\n}\n\n/** 命令式 Toast 单例接口(各框架适配层实现同名同义)。 */\nexport interface QwToast<Node = unknown, Style = unknown> {\n /** 展示一条提示(替换上一条)。 */\n show: (options?: QwToastOptions<Node, Style>) => void;\n /** 立即收起当前提示。 */\n clear: () => void;\n}\n\n/** 判断 icon 是否为内建状态图标类型。 */\nexport function isToastIconType(icon: unknown): icon is QwToastIconType {\n return typeof icon === \"string\" && (TOAST_ICON_TYPES as readonly string[]).includes(icon);\n}\n\n/** 解析持续时间:未传用默认 3000;显式 0 透传(不自动关闭)。 */\nexport function resolveToastDuration(duration?: number): number {\n return duration == null ? DEFAULT_TOAST_DURATION : duration;\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,kBAAkB;CAAC;CAAO;CAAU;AAAQ;;AAIzD,MAAa,mBAAmB;CAAC;CAAW;CAAQ;AAAS;;AAI7D,MAAa,cAAc;CAAC;CAAQ;CAAQ;CAAQ;CAAQ;AAAS;;AAIrE,MAAa,yBAAyB;;AAGtC,MAAa,yBAA0C;;AAiCvD,SAAgB,gBAAgB,MAAwC;CACtE,OAAO,OAAO,SAAS,YAAa,iBAAuC,SAAS,IAAI;AAC1F;;AAGA,SAAgB,qBAAqB,UAA2B;CAC9D,OAAO,YAAY,OAAO,yBAAyB;AACrD"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @qw-ui/core · Toast 契约(原型 D · 自研命令式单例)
3
+ * ─────────────────────────────────────────────────────────────
4
+ * 纯 TS / SSR-safe,零框架依赖。只收口「框架无关的选项契约 + 纯函数」:
5
+ * 交互(命令式挂载 / 计时 / 渲染)落在各框架适配层,节点类型(icon/content)
6
+ * 由适配层用 `ReactNode` / `VNode` 具体化 `QwToastOptions<Node>`。
7
+ */
8
+ /** 垂直显示位置。 */
9
+ export declare const TOAST_POSITIONS: readonly ["top", "bottom", "center"];
10
+ export type QwToastPosition = (typeof TOAST_POSITIONS)[number];
11
+ /** 内建状态图标类型。 */
12
+ export declare const TOAST_ICON_TYPES: readonly ["success", "fail", "loading"];
13
+ export type QwToastIconType = (typeof TOAST_ICON_TYPES)[number];
14
+ /** 逻辑部件(承载 data-part 样式与 parity 指纹)。 */
15
+ export declare const TOAST_PARTS: readonly ["mask", "wrap", "body", "icon", "content"];
16
+ export type QwToastPart = (typeof TOAST_PARTS)[number];
17
+ /** 默认展示时长(ms)。 */
18
+ export declare const DEFAULT_TOAST_DURATION = 3000;
19
+ /** 默认垂直位置(对齐设计稿:默认顶部)。 */
20
+ export declare const DEFAULT_TOAST_POSITION: QwToastPosition;
21
+ /**
22
+ * Toast 选项契约。`Node` / `Style` 由适配层具体化
23
+ * (React `ReactNode` / `CSSProperties`;Vue `VNode` / `StyleValue`)。
24
+ * 与 antd-mobile 风格对齐:命令式 `Toast.show(options)`。
25
+ */
26
+ export interface QwToastOptions<Node = unknown, Style = unknown> {
27
+ /** 提示主文案。可空(纯图标提示)。 */
28
+ content?: Node;
29
+ /** 前置图标:内建类型 `success | fail | loading`,或任意自定义节点;不传则不展示图标。 */
30
+ icon?: QwToastIconType | Node;
31
+ /** 持续时间(ms),默认 3000;为 0 时不自动关闭。 */
32
+ duration?: number;
33
+ /** 垂直显示位置,默认 top。 */
34
+ position?: QwToastPosition;
35
+ /** 自定义遮罩层内联样式。 */
36
+ maskStyle?: Style;
37
+ /** 自定义遮罩层 class。 */
38
+ maskClassName?: string;
39
+ /** 关闭后回调(自动消失或手动 clear 均触发)。 */
40
+ afterClose?: () => void;
41
+ }
42
+ /** 命令式 Toast 单例接口(各框架适配层实现同名同义)。 */
43
+ export interface QwToast<Node = unknown, Style = unknown> {
44
+ /** 展示一条提示(替换上一条)。 */
45
+ show: (options?: QwToastOptions<Node, Style>) => void;
46
+ /** 立即收起当前提示。 */
47
+ clear: () => void;
48
+ }
49
+ /** 判断 icon 是否为内建状态图标类型。 */
50
+ export declare function isToastIconType(icon: unknown): icon is QwToastIconType;
51
+ /** 解析持续时间:未传用默认 3000;显式 0 透传(不自动关闭)。 */
52
+ export declare function resolveToastDuration(duration?: number): number;
@@ -0,0 +1 @@
1
+ export * from "./top-bar.js";
@@ -0,0 +1,43 @@
1
+ //#region src/top-bar/top-bar.ts
2
+ /**
3
+ * Top Bar 契约 — 原型 A(无状态),core 无 machine,只承载双栈共享的类型契约。
4
+ * React/Vue 适配层从这里 import 类型与 createTopBarProps,不允许各自再定义一份。
5
+ *
6
+ * Top Bar 是内容面板的头部组件,通过 `variant` prop 选择三种互斥结构形式:
7
+ * basic(标题 + 收起 icon)、tab(tablist + 收起 icon)、extended(返回箭头 + 自定义中间 + 关闭 icon)。
8
+ * Tab 切换复用 @qw-ui/core/tabs。
9
+ *
10
+ * 枚举以运行时常量数组为唯一事实源(类型从常量推导),__test__ 直接锁死词表。
11
+ */
12
+ /** variant 全集:basic 基础 / tab 标签页 / extended 拓展。 */
13
+ const TOPBAR_VARIANTS = [
14
+ "basic",
15
+ "tab",
16
+ "extended"
17
+ ];
18
+ /**
19
+ * 把 QwTopBarProps 收口默认值,返回适配层配置对象。
20
+ * 不进 machine(原型 A)。纯函数,SSR-safe。
21
+ */
22
+ function createTopBarProps(props) {
23
+ const items = props.items;
24
+ return {
25
+ variant: props.variant,
26
+ title: props.title,
27
+ items,
28
+ defaultValue: props.defaultValue ?? null,
29
+ value: props.value ?? null,
30
+ onValueChange: props.onValueChange,
31
+ onCollapse: props.onCollapse,
32
+ collapseLabel: props.collapseLabel ?? "收起",
33
+ onBack: props.onBack,
34
+ backLabel: props.backLabel ?? "返回",
35
+ onClose: props.onClose,
36
+ closeLabel: props.closeLabel ?? "关闭",
37
+ hasTabs: items !== void 0 && items.length > 0
38
+ };
39
+ }
40
+ //#endregion
41
+ export { TOPBAR_VARIANTS, createTopBarProps };
42
+
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/top-bar/top-bar.ts"],"sourcesContent":["/**\n * Top Bar 契约 — 原型 A(无状态),core 无 machine,只承载双栈共享的类型契约。\n * React/Vue 适配层从这里 import 类型与 createTopBarProps,不允许各自再定义一份。\n *\n * Top Bar 是内容面板的头部组件,通过 `variant` prop 选择三种互斥结构形式:\n * basic(标题 + 收起 icon)、tab(tablist + 收起 icon)、extended(返回箭头 + 自定义中间 + 关闭 icon)。\n * Tab 切换复用 @qw-ui/core/tabs。\n *\n * 枚举以运行时常量数组为唯一事实源(类型从常量推导),__test__ 直接锁死词表。\n */\n\n/** variant 全集:basic 基础 / tab 标签页 / extended 拓展。 */\nexport const TOPBAR_VARIANTS = [\"basic\", \"tab\", \"extended\"] as const;\n\n/** 结构形式。 */\nexport type TopBarVariant = (typeof TOPBAR_VARIANTS)[number];\n\n/**\n * TopBarItem — Tab 项契约,与 @qw-ui/react/tabs 和 @qw-ui/vue/tabs 的 TabItem 同构。\n * core 定义最小形状(label/content 为 string),适配层各自扩展为 ReactNode / slot。\n */\nexport interface TopBarItem {\n /** 选项唯一值。 */\n value: string;\n /** 选项标签文本。 */\n label: string;\n /** 选项内容(简单文本)。 */\n content?: string;\n /** 禁用该选项:跳过键盘漫游、不可点击。 */\n disabled?: boolean;\n}\n\n/**\n * QwTopBarProps — 双栈共享的行为 + 视觉契约。\n * Tab 相关 props(items/value/defaultValue/onValueChange)透传给 @qw-ui/core/tabs。\n * variant 为必填,其余 props 按 variant 条件可选(flat interface,非 discriminated union)。\n */\nexport interface QwTopBarProps {\n /** 结构形式(必填)。 */\n variant: TopBarVariant;\n\n // ── basic 专用 ──\n /** 标题名称(basic 专用)。 */\n title?: string;\n\n // ── tab 专用 ──\n /** Tab 切换模式的数据项。 */\n items?: TopBarItem[];\n /** Tab 非受控初值。 */\n defaultValue?: string | null;\n /** Tab 受控当前项。 */\n value?: string | null;\n /** Tab 选中项变化回调。 */\n onValueChange?: (e: { value: string }) => void;\n\n // ── basic + tab 共用 ──\n /** 收起 icon 点击回调(关闭内容面板)。 */\n onCollapse?: () => void;\n /** 收起 icon 的 aria-label,默认「收起」。 */\n collapseLabel?: string;\n\n // ── extended 专用 ──\n /** 返回箭头点击回调(面板内导航回退)。 */\n onBack?: () => void;\n /** 返回箭头的 aria-label,默认「返回」。 */\n backLabel?: string;\n /** 关闭 icon 点击回调(关闭面板)。 */\n onClose?: () => void;\n /** 关闭 icon 的 aria-label,默认「关闭」。 */\n closeLabel?: string;\n}\n\n/**\n * ResolvedTopBarProps — createTopBarProps 返回值,适配层消费此对象渲染。\n */\nexport interface ResolvedTopBarProps {\n variant: TopBarVariant;\n title: string | undefined;\n items: TopBarItem[] | undefined;\n defaultValue: string | null;\n value: string | null;\n onValueChange: ((e: { value: string }) => void) | undefined;\n onCollapse: (() => void) | undefined;\n collapseLabel: string;\n onBack: (() => void) | undefined;\n backLabel: string;\n onClose: (() => void) | undefined;\n closeLabel: string;\n hasTabs: boolean;\n}\n\n/**\n * 把 QwTopBarProps 收口默认值,返回适配层配置对象。\n * 不进 machine(原型 A)。纯函数,SSR-safe。\n */\nexport function createTopBarProps(props: QwTopBarProps): ResolvedTopBarProps {\n const items = props.items;\n\n return {\n variant: props.variant,\n title: props.title,\n items,\n defaultValue: props.defaultValue ?? null,\n value: props.value ?? null,\n onValueChange: props.onValueChange,\n onCollapse: props.onCollapse,\n collapseLabel: props.collapseLabel ?? \"收起\",\n onBack: props.onBack,\n backLabel: props.backLabel ?? \"返回\",\n onClose: props.onClose,\n closeLabel: props.closeLabel ?? \"关闭\",\n hasTabs: items !== undefined && items.length > 0,\n };\n}\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,kBAAkB;CAAC;CAAS;CAAO;AAAU;;;;;AAmF1D,SAAgB,kBAAkB,OAA2C;CAC3E,MAAM,QAAQ,MAAM;CAEpB,OAAO;EACL,SAAS,MAAM;EACf,OAAO,MAAM;EACb;EACA,cAAc,MAAM,gBAAgB;EACpC,OAAO,MAAM,SAAS;EACtB,eAAe,MAAM;EACrB,YAAY,MAAM;EAClB,eAAe,MAAM,iBAAiB;EACtC,QAAQ,MAAM;EACd,WAAW,MAAM,aAAa;EAC9B,SAAS,MAAM;EACf,YAAY,MAAM,cAAc;EAChC,SAAS,UAAU,KAAA,KAAa,MAAM,SAAS;CACjD;AACF"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Top Bar 契约 — 原型 A(无状态),core 无 machine,只承载双栈共享的类型契约。
3
+ * React/Vue 适配层从这里 import 类型与 createTopBarProps,不允许各自再定义一份。
4
+ *
5
+ * Top Bar 是内容面板的头部组件,通过 `variant` prop 选择三种互斥结构形式:
6
+ * basic(标题 + 收起 icon)、tab(tablist + 收起 icon)、extended(返回箭头 + 自定义中间 + 关闭 icon)。
7
+ * Tab 切换复用 @qw-ui/core/tabs。
8
+ *
9
+ * 枚举以运行时常量数组为唯一事实源(类型从常量推导),__test__ 直接锁死词表。
10
+ */
11
+ /** variant 全集:basic 基础 / tab 标签页 / extended 拓展。 */
12
+ export declare const TOPBAR_VARIANTS: readonly ["basic", "tab", "extended"];
13
+ /** 结构形式。 */
14
+ export type TopBarVariant = (typeof TOPBAR_VARIANTS)[number];
15
+ /**
16
+ * TopBarItem — Tab 项契约,与 @qw-ui/react/tabs 和 @qw-ui/vue/tabs 的 TabItem 同构。
17
+ * core 定义最小形状(label/content 为 string),适配层各自扩展为 ReactNode / slot。
18
+ */
19
+ export interface TopBarItem {
20
+ /** 选项唯一值。 */
21
+ value: string;
22
+ /** 选项标签文本。 */
23
+ label: string;
24
+ /** 选项内容(简单文本)。 */
25
+ content?: string;
26
+ /** 禁用该选项:跳过键盘漫游、不可点击。 */
27
+ disabled?: boolean;
28
+ }
29
+ /**
30
+ * QwTopBarProps — 双栈共享的行为 + 视觉契约。
31
+ * Tab 相关 props(items/value/defaultValue/onValueChange)透传给 @qw-ui/core/tabs。
32
+ * variant 为必填,其余 props 按 variant 条件可选(flat interface,非 discriminated union)。
33
+ */
34
+ export interface QwTopBarProps {
35
+ /** 结构形式(必填)。 */
36
+ variant: TopBarVariant;
37
+ /** 标题名称(basic 专用)。 */
38
+ title?: string;
39
+ /** Tab 切换模式的数据项。 */
40
+ items?: TopBarItem[];
41
+ /** Tab 非受控初值。 */
42
+ defaultValue?: string | null;
43
+ /** Tab 受控当前项。 */
44
+ value?: string | null;
45
+ /** Tab 选中项变化回调。 */
46
+ onValueChange?: (e: {
47
+ value: string;
48
+ }) => void;
49
+ /** 收起 icon 点击回调(关闭内容面板)。 */
50
+ onCollapse?: () => void;
51
+ /** 收起 icon 的 aria-label,默认「收起」。 */
52
+ collapseLabel?: string;
53
+ /** 返回箭头点击回调(面板内导航回退)。 */
54
+ onBack?: () => void;
55
+ /** 返回箭头的 aria-label,默认「返回」。 */
56
+ backLabel?: string;
57
+ /** 关闭 icon 点击回调(关闭面板)。 */
58
+ onClose?: () => void;
59
+ /** 关闭 icon 的 aria-label,默认「关闭」。 */
60
+ closeLabel?: string;
61
+ }
62
+ /**
63
+ * ResolvedTopBarProps — createTopBarProps 返回值,适配层消费此对象渲染。
64
+ */
65
+ export interface ResolvedTopBarProps {
66
+ variant: TopBarVariant;
67
+ title: string | undefined;
68
+ items: TopBarItem[] | undefined;
69
+ defaultValue: string | null;
70
+ value: string | null;
71
+ onValueChange: ((e: {
72
+ value: string;
73
+ }) => void) | undefined;
74
+ onCollapse: (() => void) | undefined;
75
+ collapseLabel: string;
76
+ onBack: (() => void) | undefined;
77
+ backLabel: string;
78
+ onClose: (() => void) | undefined;
79
+ closeLabel: string;
80
+ hasTabs: boolean;
81
+ }
82
+ /**
83
+ * 把 QwTopBarProps 收口默认值,返回适配层配置对象。
84
+ * 不进 machine(原型 A)。纯函数,SSR-safe。
85
+ */
86
+ export declare function createTopBarProps(props: QwTopBarProps): ResolvedTopBarProps;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * 组件视觉契约清单类型 — workspace 内部使用(不进 npm 产物、不进 core 公开 API)。
3
+ *
4
+ * 每个组件在 `src/<slug>/docs/visual.ts` 维护一份 `QwComponentVisualMeta`,
5
+ * 它是确定性视觉契约的唯一事实源:React/Vue 共用同一份场景声明,
6
+ * `tools/visual-check` 按清单展开矩阵并在真实浏览器内做运行时自比较
7
+ *(状态差异 / token 绑定 / 主题切换 / 双栈样式 parity / 几何关系)。
8
+ *
9
+ * Demo 层通过 `data-visual-target="<target>"` 标记契约锚点(不进组件公共 API)。
10
+ *
11
+ * 非目标:禁止落盘任何截图或 computed-style 指纹制品作为跨运行基线。
12
+ */
13
+ /** 受支持的视觉状态词表(封闭集合;新增状态须改此类型并更新共享 driver)。 */
14
+ export type QwVisualState = "default" | "hover" | "active" | "focus-visible" | "disabled" | "loading" | "open" | "closed" | "selected" | "checked" | "expanded";
15
+ /** 主题轴。 */
16
+ export type QwVisualTheme = "light" | "dark";
17
+ /** 框架轴。 */
18
+ export type QwVisualFramework = "react" | "vue";
19
+ /** 视口配置(预留扩展;默认 mobile = 390×844 @2x,与 G3 一致)。 */
20
+ export type QwVisualViewport = "mobile";
21
+ /**
22
+ * 语义视觉通道——状态变化的抽象分组,不是 CSS 属性字面量。
23
+ * 状态差异断言要求 delta 至少命中该状态通道词表中的一项。
24
+ */
25
+ export type QwVisualChannel = "fill" | "content" | "edge" | "opacity" | "transform" | "cursor" | "presence";
26
+ /** 声明式前置动作(进入 open/selected 等状态)。 */
27
+ export type QwVisualAction = {
28
+ action: "click";
29
+ target: string;
30
+ } | {
31
+ action: "press";
32
+ target: string;
33
+ keys: string;
34
+ } | {
35
+ action: "tab-to";
36
+ target: string;
37
+ } | {
38
+ action: "click-role";
39
+ role: string;
40
+ name?: string;
41
+ index?: number;
42
+ };
43
+ /**
44
+ * 几何关系谓词——只表达相对关系,不写死绝对像素。
45
+ * 封闭小词表;按需求增长,不预设。
46
+ */
47
+ export type QwGeometryRelation = {
48
+ rel: "contains";
49
+ outer: string;
50
+ inner: string;
51
+ } | {
52
+ rel: "centered";
53
+ item: string;
54
+ within: string;
55
+ axis?: "block" | "inline";
56
+ } | {
57
+ rel: "monotonic";
58
+ axis: "block-size" | "inline-size";
59
+ targets: string[];
60
+ } | {
61
+ rel: "equal";
62
+ axis: "block-size" | "inline-size";
63
+ targets: string[];
64
+ tolerancePx?: number;
65
+ } | {
66
+ rel: "token-size";
67
+ target: string;
68
+ axis: "block-size" | "inline-size";
69
+ /** T3 token 短名,如 "size-control-height-m";运行时从 tokens.json 解析 */
70
+ token: string;
71
+ };
72
+ /** 场景级可选强契约;省略时仍享有零声明基础保障。 */
73
+ export interface QwVisualExpect {
74
+ /** 覆盖库级默认通道(极少用,如某状态刻意不改 fill)。 */
75
+ channels?: Partial<Record<QwVisualState, QwVisualChannel[]>>;
76
+ /**
77
+ * 强契约:状态下某属性必须解析为指定 T3 token 的值。
78
+ * key = "state.property"(state 可省略,默认 default),value = token 短名(如 "border-focus")。
79
+ */
80
+ tokens?: Record<string, string>;
81
+ /** 几何关系谓词。 */
82
+ geometry?: QwGeometryRelation[];
83
+ /** 该场景颜色随主题不变,显式豁免主题 delta 检查。 */
84
+ themeInvariant?: boolean;
85
+ /** 动画契约。 */
86
+ motion?: {
87
+ /** data-visual-target 或 data-part 选择器别名;解析为动画宿主 */
88
+ animatedPart: string;
89
+ respectsReducedMotion?: boolean;
90
+ };
91
+ /** Icon 等:双栈 SVG 结构归一化哈希一致。 */
92
+ svgParity?: boolean;
93
+ /** target 允许溢出 demo 画布(Dialog backdrop / Toast overlay 等)。 */
94
+ allowOverflow?: boolean;
95
+ }
96
+ /** 单个视觉场景。 */
97
+ export interface QwVisualScenario {
98
+ /** kebab-case 场景名,进入 case id。 */
99
+ name: string;
100
+ /** 引用 demos.ts 中的 demo id。 */
101
+ demo: string;
102
+ /** 对应 demo 中 `data-visual-target` 的值。 */
103
+ target: string;
104
+ /** 本场景要验证的视觉状态列表。 */
105
+ states: QwVisualState[];
106
+ /** 主题列表,默认 light + dark(主题 delta 使用;parity 仍跑双主题)。 */
107
+ themes?: QwVisualTheme[];
108
+ /** 框架列表,默认 react + vue。 */
109
+ frameworks?: QwVisualFramework[];
110
+ /** 进入特定状态前的动作序列。 */
111
+ setup?: QwVisualAction[];
112
+ /** 视口配置,默认 mobile。 */
113
+ viewport?: QwVisualViewport;
114
+ /** 可选强契约;零声明场景仍有基础保障。 */
115
+ expect?: QwVisualExpect;
116
+ }
117
+ /** 组件视觉契约元数据。 */
118
+ export interface QwComponentVisualMeta {
119
+ slug: string;
120
+ scenarios: QwVisualScenario[];
121
+ /** 软预算提示阈值(契约 case 数);超出时 verify 警告但不阻塞。 */
122
+ budget?: number;
123
+ }
124
+ /** 默认主题轴。 */
125
+ export declare const QW_VISUAL_DEFAULT_THEMES: readonly QwVisualTheme[];
126
+ /** 默认框架轴。 */
127
+ export declare const QW_VISUAL_DEFAULT_FRAMEWORKS: readonly QwVisualFramework[];
128
+ /** 软预算默认值(契约 case 数)。 */
129
+ export declare const QW_VISUAL_DEFAULT_BUDGET = 120;
130
+ /**
131
+ * 库级默认:状态 → 期望变化的视觉通道。
132
+ * 通道命中即可(OR),不要求全部命中。
133
+ */
134
+ export declare const QW_STATE_CHANNELS: Readonly<Record<Exclude<QwVisualState, "default" | "closed">, readonly QwVisualChannel[]>>;
135
+ /** Case id:`{slug}-{scenario}--{state}--{theme}-{framework}` */
136
+ export declare function qwVisualCaseId(slug: string, scenario: string, state: QwVisualState, theme: QwVisualTheme, framework: QwVisualFramework): string;
137
+ /** @deprecated 使用 qwVisualCaseId;保留别名以兼容过渡期引用。 */
138
+ export declare const qwVisualSnapshotName: typeof qwVisualCaseId;
139
+ /** 展开场景为契约 case id 列表。 */
140
+ export declare function expandVisualCases(meta: QwComponentVisualMeta): string[];
141
+ /** @deprecated 使用 expandVisualCases。 */
142
+ export declare const expandVisualSnapshots: typeof expandVisualCases;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qw-ui/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0-next.0",
4
4
  "description": "L2 · Headless Core — zag.js machine 薄包装,纯 TS / SSR-safe,零样式。",
5
5
  "license": "MIT",
6
6
  "author": "qw-ui contributors",
@@ -35,12 +35,59 @@
35
35
  "./tabs": {
36
36
  "types": "./dist/tabs/index.d.ts",
37
37
  "import": "./dist/tabs/index.js"
38
+ },
39
+ "./toast": {
40
+ "types": "./dist/toast/index.d.ts",
41
+ "import": "./dist/toast/index.js"
42
+ },
43
+ "./button": {
44
+ "types": "./dist/button/index.d.ts",
45
+ "import": "./dist/button/index.js"
46
+ },
47
+ "./empty": {
48
+ "types": "./dist/empty/index.d.ts",
49
+ "import": "./dist/empty/index.js"
50
+ },
51
+ "./divider": {
52
+ "types": "./dist/divider/index.d.ts",
53
+ "import": "./dist/divider/index.js"
54
+ },
55
+ "./loading": {
56
+ "types": "./dist/loading/index.d.ts",
57
+ "import": "./dist/loading/index.js"
58
+ },
59
+ "./skeleton": {
60
+ "types": "./dist/skeleton/index.d.ts",
61
+ "import": "./dist/skeleton/index.js"
62
+ },
63
+ "./top-bar": {
64
+ "types": "./dist/top-bar/index.d.ts",
65
+ "import": "./dist/top-bar/index.js"
66
+ },
67
+ "./icon": {
68
+ "types": "./dist/icon/index.d.ts",
69
+ "import": "./dist/icon/index.js"
70
+ },
71
+ "./search-bar": {
72
+ "types": "./dist/search-bar/index.d.ts",
73
+ "import": "./dist/search-bar/index.js"
74
+ },
75
+ "./avatar": {
76
+ "types": "./dist/avatar/index.d.ts",
77
+ "import": "./dist/avatar/index.js"
78
+ },
79
+ "./image": {
80
+ "types": "./dist/image/index.d.ts",
81
+ "import": "./dist/image/index.js"
38
82
  }
39
83
  },
40
84
  "sideEffects": false,
41
85
  "dependencies": {
86
+ "@zag-js/core": "1.42.0",
42
87
  "@zag-js/dialog": "^1.42.0",
43
- "@zag-js/tabs": "^1.42.0"
88
+ "@zag-js/tabs": "^1.42.0",
89
+ "@zag-js/utils": "1.42.0",
90
+ "@qw-ui/icons": "^0.2.0-next.0"
44
91
  },
45
92
  "devDependencies": {
46
93
  "@microsoft/api-extractor": "^7.58.9",
@@ -50,8 +97,9 @@
50
97
  "@zag-js/vanilla": "^1.42.0",
51
98
  "jsdom": "^29.1.1",
52
99
  "size-limit": "^12.1.0",
53
- "tsup": "^8.5.1",
100
+ "tsdown": "^0.22.4",
54
101
  "typescript": "^6.0.3",
102
+ "unrun": "^0.3.1",
55
103
  "vitest": "^4.1.9",
56
104
  "@qw-ui/eslint-config": "0.0.0",
57
105
  "@qw-ui/tsconfig": "0.0.0"
@@ -70,6 +118,14 @@
70
118
  "ignore": [
71
119
  "@zag-js/tabs"
72
120
  ]
121
+ },
122
+ {
123
+ "path": "dist/top-bar/index.js",
124
+ "limit": "4 kB"
125
+ },
126
+ {
127
+ "path": "dist/toast/index.js",
128
+ "limit": "2 kB"
73
129
  }
74
130
  ],
75
131
  "publishConfig": {
@@ -77,9 +133,10 @@
77
133
  "registry": "https://registry.npmjs.org/"
78
134
  },
79
135
  "scripts": {
80
- "build": "tsup",
136
+ "build": "tsdown && tsgo -p tsconfig.build.json",
81
137
  "test": "vitest run",
82
138
  "lint": "eslint .",
139
+ "typecheck": "tsgo --noEmit -p tsconfig.build.json",
83
140
  "size": "size-limit",
84
141
  "api": "api-extractor run --local",
85
142
  "clean": "rm -rf dist .turbo etc/*.api.json temp"
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/dialog/index.ts","../src/tabs/index.ts"],"names":[],"mappings":";;;;AAwDO,SAAS,iBAAA,CAAkB,KAAA,GAAuB,EAAC,EAA4B;AACpF,EAAA,MAAM,GAAA,GAA+B;AAAA,IACnC,IAAI,KAAA,CAAM,EAAA;AAAA,IACV,MAAM,KAAA,CAAM,IAAA;AAAA,IACZ,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,MAAM,KAAA,CAAM,IAAA;AAAA,IACZ,aAAA,EAAe,MAAM,UAAA,KAAe,KAAA;AAAA,IACpC,sBAAA,EAAwB,MAAM,cAAA,KAAmB,KAAA;AAAA,IACjD,aAAA,EAAe,MAAM,UAAA,KAAe;AAAA,GACtC;AAEA,EAAA,IAAI,KAAA,CAAM,KAAA,KAAU,MAAA,EAAW,GAAA,CAAI,QAAQ,KAAA,CAAM,KAAA;AAEjD,EAAA,IAAI,MAAM,YAAA,EAAc;AACtB,IAAA,MAAM,KAAK,KAAA,CAAM,YAAA;AACjB,IAAA,GAAA,CAAI,YAAA,GAAe,CAAC,CAAA,KAAyB,EAAA,CAAG,EAAE,IAAA,EAAM,CAAA,CAAE,MAAM,CAAA;AAAA,EAClE;AAGA,EAAA,IAAI,OAAO,KAAA,CAAM,YAAA,KAAiB,QAAA,EAAU;AAC1C,IAAA,MAAM,GAAA,GAAM,MAAM,YAAA,CAAa,QAAA;AAC/B,IAAA,GAAA,CAAI,cAAA,GAAiB,MAAM,QAAA,CAAS,aAAA,CAA2B,GAAG,CAAA;AAAA,EACpE;AAGA,EAAA,IAAI,OAAO,KAAA,CAAM,WAAA,KAAgB,QAAA,EAAU;AACzC,IAAA,MAAM,GAAA,GAAM,MAAM,WAAA,CAAY,QAAA;AAC9B,IAAA,GAAA,CAAI,YAAA,GAAe,MAAM,QAAA,CAAS,aAAA,CAA2B,GAAG,CAAA;AAAA,EAClE,CAAA,MAAA,IAAW,KAAA,CAAM,WAAA,KAAgB,MAAA,EAAQ;AACvC,IAAA,GAAA,CAAI,YAAA,GAAe,KAAA;AAAA,EACrB;AAEA,EAAA,OAAO,GAAA;AACT;AClDO,SAAS,eAAA,CAAgB,KAAA,GAAqB,EAAC,EAA0B;AAC9E,EAAA,MAAM,GAAA,GAA6B;AAAA,IACjC,IAAI,KAAA,CAAM,EAAA;AAAA,IACV,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,cAAc,KAAA,CAAM,YAAA;AAAA,IACpB,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,gBAAgB,KAAA,CAAM,cAAA;AAAA,IACtB,SAAA,EAAW,MAAM,IAAA,KAAS;AAAA,GAC5B;AAEA,EAAA,IAAI,MAAM,aAAA,EAAe;AACvB,IAAA,MAAM,KAAK,KAAA,CAAM,aAAA;AACjB,IAAA,GAAA,CAAI,aAAA,GAAgB,CAAC,CAAA,KAA0B,EAAA,CAAG,EAAE,KAAA,EAAO,CAAA,CAAE,OAAO,CAAA;AAAA,EACtE;AAEA,EAAA,OAAO,GAAA;AACT","file":"index.js","sourcesContent":["import type { Props as ZagDialogProps, OpenChangeDetails } from \"@zag-js/dialog\";\n\n/**\n * QwDialogProps — Dialog 的用户输入。\n *\n * 对 zag.js 输入做两件事 (§06):\n * 1. 默认值收口:closeOnEsc / closeOnOutside / scrollLock 默认全 true;\n * 2. 命名 rebrand:把 zag 的 closeOnInteractOutside / preventScroll 改成业务易懂命名;\n * 3. 业务 props 透出:onOpenChange / initialFocus / returnFocus 在 React/Vue 同名。\n *\n * 业务方只需 import 本类型,不需要直接 import `@zag-js/*`。\n */\nexport interface QwDialogProps {\n /** 唯一 id 前缀;不传时由 zag 安全生成 (SSR/CSR 一致)。 */\n id?: string;\n /** 受控开关。 */\n open?: boolean;\n /** 非受控初值。 */\n defaultOpen?: boolean;\n /** ESC 关闭,默认 true (zag 原名 closeOnEscape)。 */\n closeOnEsc?: boolean;\n /** 点击 backdrop 关闭,默认 true (zag 原名 closeOnInteractOutside)。 */\n closeOnOutside?: boolean;\n /** 滚动锁,默认 true (zag 原名 preventScroll)。 */\n scrollLock?: boolean;\n /** 模态遮蔽,默认 true。 */\n modal?: boolean;\n /** 角色,默认 dialog。 */\n role?: \"dialog\" | \"alertdialog\";\n /** 初始焦点策略;对象形式提供 selector,由 core 翻译成 zag 的 initialFocusEl。 */\n initialFocus?: \"autofocus\" | \"first\" | \"none\" | { selector: string };\n /** 关闭回焦策略;对应 zag 的 restoreFocus + finalFocusEl。 */\n returnFocus?: \"previous\" | \"none\" | { selector: string };\n /** 状态变化回调;zag 原生 onOpenChange。 */\n onOpenChange?: (e: { open: boolean }) => void;\n /**\n * 禁用 trigger:禁用后点击/键盘都不打开。\n * adapter 层声明式属性(落到原生 button[disabled])——zag dialog 无此 context,不进 machine。\n */\n disabled?: boolean;\n}\n\n/**\n * 直接 re-export zag 的 dialog machine 与 connect —— 不再包一层。\n * machine 由各框架 useMachine 消费;connect 把 service 接成 prop-getter。\n * 用 re-export 而非 `const x = dialog.x` 以保留原始可移植类型 (避免 TS2742)。\n */\nexport { machine as dialogMachine, connect } from \"@zag-js/dialog\";\n\n/** rebrand zag 的 DialogApi 类型对外。 */\nexport type { Api as QwDialogApi } from \"@zag-js/dialog\";\n\n/**\n * 把 QwDialogProps 转成 zag dialog machine 的 context (默认值收口 + 命名 rebrand)。\n * 用法:`useMachine(dialogMachine, createDialogProps(props))`。\n */\nexport function createDialogProps(props: QwDialogProps = {}): Partial<ZagDialogProps> {\n const ctx: Partial<ZagDialogProps> = {\n id: props.id,\n open: props.open,\n defaultOpen: props.defaultOpen,\n role: props.role,\n closeOnEscape: props.closeOnEsc !== false,\n closeOnInteractOutside: props.closeOnOutside !== false,\n preventScroll: props.scrollLock !== false,\n };\n\n if (props.modal !== undefined) ctx.modal = props.modal;\n\n if (props.onOpenChange) {\n const cb = props.onOpenChange;\n ctx.onOpenChange = (d: OpenChangeDetails) => cb({ open: d.open });\n }\n\n // initialFocus: { selector } → initialFocusEl 回调;'none' 关闭自动聚焦\n if (typeof props.initialFocus === \"object\") {\n const sel = props.initialFocus.selector;\n ctx.initialFocusEl = () => document.querySelector<HTMLElement>(sel);\n }\n\n // returnFocus: { selector } → finalFocusEl;'none' → restoreFocus=false\n if (typeof props.returnFocus === \"object\") {\n const sel = props.returnFocus.selector;\n ctx.finalFocusEl = () => document.querySelector<HTMLElement>(sel);\n } else if (props.returnFocus === \"none\") {\n ctx.restoreFocus = false;\n }\n\n return ctx;\n}\n","import type { Props as ZagTabsProps, ValueChangeDetails } from \"@zag-js/tabs\";\n\n/**\n * QwTabsProps — Tabs 的用户输入。对 zag.js 输入做默认值收口 + 命名 rebrand:\n * - loop(默认 true)→ zag loopFocus;\n * - value / defaultValue / orientation / activationMode 透传;\n * - onValueChange 适配 zag details。\n * 业务方只 import 本类型,不直接 import `@zag-js/*`。\n */\nexport interface QwTabsProps {\n /** 唯一 id 前缀;不传由适配层生成 (SSR/CSR 一致)。 */\n id?: string;\n /** 受控当前项。 */\n value?: string | null;\n /** 非受控初值。 */\n defaultValue?: string | null;\n /** 方向,默认 horizontal。 */\n orientation?: \"horizontal\" | \"vertical\";\n /** 激活模式,默认 automatic(聚焦即激活)。 */\n activationMode?: \"manual\" | \"automatic\";\n /** 方向键首尾循环,默认 true (zag 原名 loopFocus)。 */\n loop?: boolean;\n /** 选中项变化回调;zag 原生 onValueChange。 */\n onValueChange?: (e: { value: string }) => void;\n}\n\n/**\n * 直接 re-export zag tabs 的 machine 与 connect —— 不包一层。\n * 用 re-export 保留原始可移植类型 (避免 TS2742)。\n */\nexport { machine as tabsMachine, connect } from \"@zag-js/tabs\";\n\n/** rebrand zag 的 TabsApi 类型对外。 */\nexport type { Api as QwTabsApi } from \"@zag-js/tabs\";\n\n/**\n * 把 QwTabsProps 转成 zag tabs machine 的 props (默认值收口 + 命名 rebrand)。\n * 用法:`useMachine(tabsMachine, createTabsProps(props))`。\n */\nexport function createTabsProps(props: QwTabsProps = {}): Partial<ZagTabsProps> {\n const ctx: Partial<ZagTabsProps> = {\n id: props.id,\n value: props.value,\n defaultValue: props.defaultValue,\n orientation: props.orientation,\n activationMode: props.activationMode,\n loopFocus: props.loop !== false,\n };\n\n if (props.onValueChange) {\n const cb = props.onValueChange;\n ctx.onValueChange = (d: ValueChangeDetails) => cb({ value: d.value });\n }\n\n return ctx;\n}\n"]}