@qw-ui/core 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.
- package/LICENSE +21 -0
- package/dist/dialog/index.d.ts +56 -0
- package/dist/dialog/index.js +34 -0
- package/dist/dialog/index.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/tabs/index.d.ts +36 -0
- package/dist/tabs/index.js +22 -0
- package/dist/tabs/index.js.map +1 -0
- package/package.json +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 qw-ui contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Props } from '@zag-js/dialog';
|
|
2
|
+
export { Api as QwDialogApi, connect, machine as dialogMachine } from '@zag-js/dialog';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* QwDialogProps — Dialog 的用户输入。
|
|
6
|
+
*
|
|
7
|
+
* 对 zag.js 输入做两件事 (§06):
|
|
8
|
+
* 1. 默认值收口:closeOnEsc / closeOnOutside / scrollLock 默认全 true;
|
|
9
|
+
* 2. 命名 rebrand:把 zag 的 closeOnInteractOutside / preventScroll 改成业务易懂命名;
|
|
10
|
+
* 3. 业务 props 透出:onOpenChange / initialFocus / returnFocus 在 React/Vue 同名。
|
|
11
|
+
*
|
|
12
|
+
* 业务方只需 import 本类型,不需要直接 import `@zag-js/*`。
|
|
13
|
+
*/
|
|
14
|
+
interface QwDialogProps {
|
|
15
|
+
/** 唯一 id 前缀;不传时由 zag 安全生成 (SSR/CSR 一致)。 */
|
|
16
|
+
id?: string;
|
|
17
|
+
/** 受控开关。 */
|
|
18
|
+
open?: boolean;
|
|
19
|
+
/** 非受控初值。 */
|
|
20
|
+
defaultOpen?: boolean;
|
|
21
|
+
/** ESC 关闭,默认 true (zag 原名 closeOnEscape)。 */
|
|
22
|
+
closeOnEsc?: boolean;
|
|
23
|
+
/** 点击 backdrop 关闭,默认 true (zag 原名 closeOnInteractOutside)。 */
|
|
24
|
+
closeOnOutside?: boolean;
|
|
25
|
+
/** 滚动锁,默认 true (zag 原名 preventScroll)。 */
|
|
26
|
+
scrollLock?: boolean;
|
|
27
|
+
/** 模态遮蔽,默认 true。 */
|
|
28
|
+
modal?: boolean;
|
|
29
|
+
/** 角色,默认 dialog。 */
|
|
30
|
+
role?: "dialog" | "alertdialog";
|
|
31
|
+
/** 初始焦点策略;对象形式提供 selector,由 core 翻译成 zag 的 initialFocusEl。 */
|
|
32
|
+
initialFocus?: "autofocus" | "first" | "none" | {
|
|
33
|
+
selector: string;
|
|
34
|
+
};
|
|
35
|
+
/** 关闭回焦策略;对应 zag 的 restoreFocus + finalFocusEl。 */
|
|
36
|
+
returnFocus?: "previous" | "none" | {
|
|
37
|
+
selector: string;
|
|
38
|
+
};
|
|
39
|
+
/** 状态变化回调;zag 原生 onOpenChange。 */
|
|
40
|
+
onOpenChange?: (e: {
|
|
41
|
+
open: boolean;
|
|
42
|
+
}) => void;
|
|
43
|
+
/**
|
|
44
|
+
* 禁用 trigger:禁用后点击/键盘都不打开。
|
|
45
|
+
* adapter 层声明式属性(落到原生 button[disabled])——zag dialog 无此 context,不进 machine。
|
|
46
|
+
*/
|
|
47
|
+
disabled?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 把 QwDialogProps 转成 zag dialog machine 的 context (默认值收口 + 命名 rebrand)。
|
|
52
|
+
* 用法:`useMachine(dialogMachine, createDialogProps(props))`。
|
|
53
|
+
*/
|
|
54
|
+
declare function createDialogProps(props?: QwDialogProps): Partial<Props>;
|
|
55
|
+
|
|
56
|
+
export { type QwDialogProps, createDialogProps };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export { connect, machine as dialogMachine } from '@zag-js/dialog';
|
|
2
|
+
|
|
3
|
+
// src/dialog/index.ts
|
|
4
|
+
function createDialogProps(props = {}) {
|
|
5
|
+
const ctx = {
|
|
6
|
+
id: props.id,
|
|
7
|
+
open: props.open,
|
|
8
|
+
defaultOpen: props.defaultOpen,
|
|
9
|
+
role: props.role,
|
|
10
|
+
closeOnEscape: props.closeOnEsc !== false,
|
|
11
|
+
closeOnInteractOutside: props.closeOnOutside !== false,
|
|
12
|
+
preventScroll: props.scrollLock !== false
|
|
13
|
+
};
|
|
14
|
+
if (props.modal !== void 0) ctx.modal = props.modal;
|
|
15
|
+
if (props.onOpenChange) {
|
|
16
|
+
const cb = props.onOpenChange;
|
|
17
|
+
ctx.onOpenChange = (d) => cb({ open: d.open });
|
|
18
|
+
}
|
|
19
|
+
if (typeof props.initialFocus === "object") {
|
|
20
|
+
const sel = props.initialFocus.selector;
|
|
21
|
+
ctx.initialFocusEl = () => document.querySelector(sel);
|
|
22
|
+
}
|
|
23
|
+
if (typeof props.returnFocus === "object") {
|
|
24
|
+
const sel = props.returnFocus.selector;
|
|
25
|
+
ctx.finalFocusEl = () => document.querySelector(sel);
|
|
26
|
+
} else if (props.returnFocus === "none") {
|
|
27
|
+
ctx.restoreFocus = false;
|
|
28
|
+
}
|
|
29
|
+
return ctx;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { createDialogProps };
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/dialog/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","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"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { QwDialogProps, createDialogProps } from './dialog/index.js';
|
|
2
|
+
export { QwTabsProps, createTabsProps } from './tabs/index.js';
|
|
3
|
+
export { Api as QwDialogApi, connect, machine as dialogMachine } from '@zag-js/dialog';
|
|
4
|
+
export { Api as QwTabsApi, machine as tabsMachine } from '@zag-js/tabs';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export { connect, machine as dialogMachine } from '@zag-js/dialog';
|
|
2
|
+
export { machine as tabsMachine } from '@zag-js/tabs';
|
|
3
|
+
|
|
4
|
+
// src/dialog/index.ts
|
|
5
|
+
function createDialogProps(props = {}) {
|
|
6
|
+
const ctx = {
|
|
7
|
+
id: props.id,
|
|
8
|
+
open: props.open,
|
|
9
|
+
defaultOpen: props.defaultOpen,
|
|
10
|
+
role: props.role,
|
|
11
|
+
closeOnEscape: props.closeOnEsc !== false,
|
|
12
|
+
closeOnInteractOutside: props.closeOnOutside !== false,
|
|
13
|
+
preventScroll: props.scrollLock !== false
|
|
14
|
+
};
|
|
15
|
+
if (props.modal !== void 0) ctx.modal = props.modal;
|
|
16
|
+
if (props.onOpenChange) {
|
|
17
|
+
const cb = props.onOpenChange;
|
|
18
|
+
ctx.onOpenChange = (d) => cb({ open: d.open });
|
|
19
|
+
}
|
|
20
|
+
if (typeof props.initialFocus === "object") {
|
|
21
|
+
const sel = props.initialFocus.selector;
|
|
22
|
+
ctx.initialFocusEl = () => document.querySelector(sel);
|
|
23
|
+
}
|
|
24
|
+
if (typeof props.returnFocus === "object") {
|
|
25
|
+
const sel = props.returnFocus.selector;
|
|
26
|
+
ctx.finalFocusEl = () => document.querySelector(sel);
|
|
27
|
+
} else if (props.returnFocus === "none") {
|
|
28
|
+
ctx.restoreFocus = false;
|
|
29
|
+
}
|
|
30
|
+
return ctx;
|
|
31
|
+
}
|
|
32
|
+
function createTabsProps(props = {}) {
|
|
33
|
+
const ctx = {
|
|
34
|
+
id: props.id,
|
|
35
|
+
value: props.value,
|
|
36
|
+
defaultValue: props.defaultValue,
|
|
37
|
+
orientation: props.orientation,
|
|
38
|
+
activationMode: props.activationMode,
|
|
39
|
+
loopFocus: props.loop !== false
|
|
40
|
+
};
|
|
41
|
+
if (props.onValueChange) {
|
|
42
|
+
const cb = props.onValueChange;
|
|
43
|
+
ctx.onValueChange = (d) => cb({ value: d.value });
|
|
44
|
+
}
|
|
45
|
+
return ctx;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { createDialogProps, createTabsProps };
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Props } from '@zag-js/tabs';
|
|
2
|
+
export { Api as QwTabsApi, connect, machine as tabsMachine } from '@zag-js/tabs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* QwTabsProps — Tabs 的用户输入。对 zag.js 输入做默认值收口 + 命名 rebrand:
|
|
6
|
+
* - loop(默认 true)→ zag loopFocus;
|
|
7
|
+
* - value / defaultValue / orientation / activationMode 透传;
|
|
8
|
+
* - onValueChange 适配 zag details。
|
|
9
|
+
* 业务方只 import 本类型,不直接 import `@zag-js/*`。
|
|
10
|
+
*/
|
|
11
|
+
interface QwTabsProps {
|
|
12
|
+
/** 唯一 id 前缀;不传由适配层生成 (SSR/CSR 一致)。 */
|
|
13
|
+
id?: string;
|
|
14
|
+
/** 受控当前项。 */
|
|
15
|
+
value?: string | null;
|
|
16
|
+
/** 非受控初值。 */
|
|
17
|
+
defaultValue?: string | null;
|
|
18
|
+
/** 方向,默认 horizontal。 */
|
|
19
|
+
orientation?: "horizontal" | "vertical";
|
|
20
|
+
/** 激活模式,默认 automatic(聚焦即激活)。 */
|
|
21
|
+
activationMode?: "manual" | "automatic";
|
|
22
|
+
/** 方向键首尾循环,默认 true (zag 原名 loopFocus)。 */
|
|
23
|
+
loop?: boolean;
|
|
24
|
+
/** 选中项变化回调;zag 原生 onValueChange。 */
|
|
25
|
+
onValueChange?: (e: {
|
|
26
|
+
value: string;
|
|
27
|
+
}) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 把 QwTabsProps 转成 zag tabs machine 的 props (默认值收口 + 命名 rebrand)。
|
|
32
|
+
* 用法:`useMachine(tabsMachine, createTabsProps(props))`。
|
|
33
|
+
*/
|
|
34
|
+
declare function createTabsProps(props?: QwTabsProps): Partial<Props>;
|
|
35
|
+
|
|
36
|
+
export { type QwTabsProps, createTabsProps };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { connect, machine as tabsMachine } from '@zag-js/tabs';
|
|
2
|
+
|
|
3
|
+
// src/tabs/index.ts
|
|
4
|
+
function createTabsProps(props = {}) {
|
|
5
|
+
const ctx = {
|
|
6
|
+
id: props.id,
|
|
7
|
+
value: props.value,
|
|
8
|
+
defaultValue: props.defaultValue,
|
|
9
|
+
orientation: props.orientation,
|
|
10
|
+
activationMode: props.activationMode,
|
|
11
|
+
loopFocus: props.loop !== false
|
|
12
|
+
};
|
|
13
|
+
if (props.onValueChange) {
|
|
14
|
+
const cb = props.onValueChange;
|
|
15
|
+
ctx.onValueChange = (d) => cb({ value: d.value });
|
|
16
|
+
}
|
|
17
|
+
return ctx;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { createTabsProps };
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/tabs/index.ts"],"names":[],"mappings":";;;AAuCO,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 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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qw-ui/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "L2 · Headless Core — zag.js machine 薄包装,纯 TS / SSR-safe,零样式。",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "qw-ui contributors",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"headless",
|
|
9
|
+
"components",
|
|
10
|
+
"zag",
|
|
11
|
+
"state-machine",
|
|
12
|
+
"ssr",
|
|
13
|
+
"qw-ui"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "http://gitlab.alibaba-inc.com/qianwen/qw-ui",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+http://gitlab.alibaba-inc.com/qianwen/qw-ui.git",
|
|
19
|
+
"directory": "packages/core"
|
|
20
|
+
},
|
|
21
|
+
"bugs": "http://gitlab.alibaba-inc.com/qianwen/qw-ui/issues",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./dialog": {
|
|
32
|
+
"types": "./dist/dialog/index.d.ts",
|
|
33
|
+
"import": "./dist/dialog/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./tabs": {
|
|
36
|
+
"types": "./dist/tabs/index.d.ts",
|
|
37
|
+
"import": "./dist/tabs/index.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"sideEffects": false,
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@zag-js/dialog": "^1.42.0",
|
|
43
|
+
"@zag-js/tabs": "^1.42.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@microsoft/api-extractor": "^7.58.9",
|
|
47
|
+
"@size-limit/preset-small-lib": "^12.1.0",
|
|
48
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
49
|
+
"@zag-js/types": "1.42.0",
|
|
50
|
+
"@zag-js/vanilla": "^1.42.0",
|
|
51
|
+
"jsdom": "^29.1.1",
|
|
52
|
+
"size-limit": "^12.1.0",
|
|
53
|
+
"tsup": "^8.5.1",
|
|
54
|
+
"typescript": "^6.0.3",
|
|
55
|
+
"vitest": "^4.1.9",
|
|
56
|
+
"@qw-ui/eslint-config": "0.0.0",
|
|
57
|
+
"@qw-ui/tsconfig": "0.0.0"
|
|
58
|
+
},
|
|
59
|
+
"size-limit": [
|
|
60
|
+
{
|
|
61
|
+
"path": "dist/dialog/index.js",
|
|
62
|
+
"limit": "6 kB",
|
|
63
|
+
"ignore": [
|
|
64
|
+
"@zag-js/dialog"
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"path": "dist/tabs/index.js",
|
|
69
|
+
"limit": "6 kB",
|
|
70
|
+
"ignore": [
|
|
71
|
+
"@zag-js/tabs"
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public",
|
|
77
|
+
"registry": "https://registry.npmjs.org/"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "tsup",
|
|
81
|
+
"test": "vitest run",
|
|
82
|
+
"lint": "eslint .",
|
|
83
|
+
"size": "size-limit",
|
|
84
|
+
"api": "api-extractor run --local",
|
|
85
|
+
"clean": "rm -rf dist .turbo etc/*.api.json temp"
|
|
86
|
+
}
|
|
87
|
+
}
|