@qw-ui/core 0.3.0-next.3 → 0.3.0-next.31
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/README.md +1 -1
- package/dist/badge/badge.d.ts +76 -0
- package/dist/badge/index.d.ts +1 -0
- package/dist/badge/index.js +75 -0
- package/dist/badge/index.js.map +1 -0
- package/dist/dialog/dialog.d.ts +31 -42
- package/dist/dialog/index.js +18 -19
- package/dist/dialog/index.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.js +7 -1
- package/dist/overlay-panel/index.d.ts +2 -0
- package/dist/overlay-panel/index.js +2 -0
- package/dist/overlay-panel/overlay-panel.d.ts +20 -0
- package/dist/overlay-panel-Z_qdKeBj.js +26 -0
- package/dist/overlay-panel-Z_qdKeBj.js.map +1 -0
- package/dist/search-bar/index.js +1 -1
- package/dist/search-bar/index.js.map +1 -1
- package/dist/search-bar/search-bar.d.ts +2 -0
- package/dist/side-nav/index.d.ts +1 -0
- package/dist/side-nav/index.js +99 -0
- package/dist/side-nav/index.js.map +1 -0
- package/dist/side-nav/side-nav.d.ts +94 -0
- package/dist/stepper/index.d.ts +1 -0
- package/dist/stepper/index.js +113 -0
- package/dist/stepper/index.js.map +1 -0
- package/dist/stepper/stepper.d.ts +121 -0
- package/dist/switch/index.d.ts +1 -0
- package/dist/switch/index.js +43 -0
- package/dist/switch/index.js.map +1 -0
- package/dist/switch/switch.d.ts +55 -0
- package/dist/tabbar/index.d.ts +1 -0
- package/dist/tabbar/index.js +50 -0
- package/dist/tabbar/index.js.map +1 -0
- package/dist/tabbar/tabbar.d.ts +69 -0
- package/dist/textarea/index.js +2 -2
- package/dist/textarea/index.js.map +1 -1
- package/dist/textarea/textarea.d.ts +4 -0
- package/dist/visual-manifest.d.ts +4 -0
- package/package.json +26 -2
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//#region src/side-nav/side-nav.ts
|
|
2
|
+
/**
|
|
3
|
+
* SideNav 的跨框架行为契约。
|
|
4
|
+
*
|
|
5
|
+
* SideNav 是受控单选的 Prototype A 侧导航列:纵向堆叠的导航项(可选分组
|
|
6
|
+
* 标题),多用于 H5 浮层分类切换。选中项白底加粗,组内直接相邻项获得
|
|
7
|
+
* 16px 邻接圆角。这里仅归一化公开 props、推导选中/邻接视觉态并收口
|
|
8
|
+
* data/aria 属性,React/Vue 适配器不得复制归一化、可见性或推导规则。
|
|
9
|
+
*/
|
|
10
|
+
const SIDENAV_PARTS = [
|
|
11
|
+
"root",
|
|
12
|
+
"group-label",
|
|
13
|
+
"item"
|
|
14
|
+
];
|
|
15
|
+
function resolveItem(item, selectedValue) {
|
|
16
|
+
return {
|
|
17
|
+
value: item.value,
|
|
18
|
+
label: item.label,
|
|
19
|
+
disabled: item.disabled ?? false,
|
|
20
|
+
selected: selectedValue !== void 0 && item.value === selectedValue
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** 组内邻接推导:仅与选中项索引差 1 的项获得 adjacent;分组标题为边界。 */
|
|
24
|
+
function attachAdjacency(items) {
|
|
25
|
+
const selectedIndex = items.findIndex((item) => item.selected);
|
|
26
|
+
if (selectedIndex < 0) return;
|
|
27
|
+
for (const item of items) item.adjacent = null;
|
|
28
|
+
if (selectedIndex > 0) {
|
|
29
|
+
const prev = items[selectedIndex - 1];
|
|
30
|
+
if (prev) prev.adjacent = "prev";
|
|
31
|
+
}
|
|
32
|
+
if (selectedIndex < items.length - 1) {
|
|
33
|
+
const next = items[selectedIndex + 1];
|
|
34
|
+
if (next) next.adjacent = "next";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 将公开输入归一化为唯一的跨框架状态。
|
|
39
|
+
* items 非空时作为最前的无标题隐式组;空组(无项)不产生渲染;
|
|
40
|
+
* 全部为空 → visible=false。
|
|
41
|
+
*/
|
|
42
|
+
function resolveSideNavState(props = {}) {
|
|
43
|
+
const selectedValue = props.value;
|
|
44
|
+
const rawGroups = [];
|
|
45
|
+
if ((props.items ?? []).length > 0) rawGroups.push({ items: props.items ?? [] });
|
|
46
|
+
for (const group of props.groups ?? []) rawGroups.push(group);
|
|
47
|
+
const groups = [];
|
|
48
|
+
let count = 0;
|
|
49
|
+
for (const raw of rawGroups) {
|
|
50
|
+
if (raw.items.length === 0) continue;
|
|
51
|
+
const items = raw.items.map((item) => ({
|
|
52
|
+
...resolveItem(item, selectedValue),
|
|
53
|
+
adjacent: null
|
|
54
|
+
}));
|
|
55
|
+
attachAdjacency(items);
|
|
56
|
+
groups.push({
|
|
57
|
+
...raw.title !== void 0 ? { title: raw.title } : {},
|
|
58
|
+
items
|
|
59
|
+
});
|
|
60
|
+
count += items.length;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
visible: count > 0,
|
|
64
|
+
count,
|
|
65
|
+
...selectedValue !== void 0 ? { selectedValue } : {},
|
|
66
|
+
groups
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** 将归一化结果转成 root 属性。 */
|
|
70
|
+
function getSideNavRootProps(state) {
|
|
71
|
+
return {
|
|
72
|
+
"data-scope": "side-nav",
|
|
73
|
+
"data-part": "root",
|
|
74
|
+
"data-count": String(state.count)
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** 分组标题元素属性(无状态入参,纯收口)。 */
|
|
78
|
+
function getSideNavGroupLabelProps() {
|
|
79
|
+
return {
|
|
80
|
+
"data-scope": "side-nav",
|
|
81
|
+
"data-part": "group-label"
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** 将单个归一化导航项转成 button 属性(选中/邻接/禁用收口,适配器不得覆盖)。 */
|
|
85
|
+
function getSideNavItemProps(item) {
|
|
86
|
+
return {
|
|
87
|
+
type: "button",
|
|
88
|
+
"data-scope": "side-nav",
|
|
89
|
+
"data-part": "item",
|
|
90
|
+
"data-state": item.selected ? "selected" : "default",
|
|
91
|
+
...item.selected ? { "aria-current": "true" } : {},
|
|
92
|
+
...item.adjacent !== null ? { "data-adjacent": item.adjacent } : {},
|
|
93
|
+
disabled: item.disabled
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
export { SIDENAV_PARTS, getSideNavGroupLabelProps, getSideNavItemProps, getSideNavRootProps, resolveSideNavState };
|
|
98
|
+
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/side-nav/side-nav.ts"],"sourcesContent":["/**\n * SideNav 的跨框架行为契约。\n *\n * SideNav 是受控单选的 Prototype A 侧导航列:纵向堆叠的导航项(可选分组\n * 标题),多用于 H5 浮层分类切换。选中项白底加粗,组内直接相邻项获得\n * 16px 邻接圆角。这里仅归一化公开 props、推导选中/邻接视觉态并收口\n * data/aria 属性,React/Vue 适配器不得复制归一化、可见性或推导规则。\n */\n\nexport const SIDENAV_PARTS = [\"root\", \"group-label\", \"item\"] as const;\n\nexport type SideNavPart = (typeof SIDENAV_PARTS)[number];\n\n/** 与选中项直接相邻的方位:prev=上邻项(右下角圆角)、next=下邻项(右上角圆角)。 */\nexport type SideNavItemAdjacent = \"prev\" | \"next\";\n\n/** 单个导航项声明;双栈共享,框架特有的事件通道不进入 Core。 */\nexport interface QwSideNavItemProps {\n /** 唯一标识;受控选中值与 onChange 回传值均用它比对。 */\n value: string;\n /** 纯文本标签,同时作为按钮可访问名。 */\n label: string;\n /** 禁用标记:保留灰底、文字降为 placeholder 语义色,不可激活。 */\n disabled?: boolean;\n}\n\n/** 分组声明;分组标题仅作视觉区隔,不参与选中语义。 */\nexport interface QwSideNavGroupProps {\n /** 分组标题;缺省时该组无标题行。 */\n title?: string;\n /** 该组导航项。 */\n items: readonly QwSideNavItemProps[];\n}\n\n/** 双栈共享的标量 props。 */\nexport interface QwSideNavProps {\n /** 扁平声明;归一化为最前的无标题隐式组。 */\n items?: readonly QwSideNavItemProps[];\n /** 分组声明;追加在隐式组之后。 */\n groups?: readonly QwSideNavGroupProps[];\n /** 受控选中项 value;缺省时全部为默认态。 */\n value?: string;\n /** 项被激活(点击/回车/空格)时回传该项 value;点击已选中项同样触发。 */\n onChange?: (value: string) => void;\n}\n\n/** 逐项归一化结果。 */\nexport interface ResolvedSideNavItemState {\n value: string;\n label: string;\n disabled: boolean;\n /** value 与受控选中值全等。 */\n selected: boolean;\n /** 组内与选中项直接相邻:prev=上邻、next=下邻;否则 null。 */\n adjacent: SideNavItemAdjacent | null;\n}\n\n/** 归一化分组结果。 */\nexport interface ResolvedSideNavGroupState {\n title?: string;\n items: ResolvedSideNavItemState[];\n}\n\n/** 适配器唯一可消费的归一化结果。 */\nexport interface ResolvedSideNavState {\n visible: boolean;\n count: number;\n selectedValue?: string;\n groups: ResolvedSideNavGroupState[];\n}\n\n/** Core 生成、由适配器摊到根元素(原生 nav)的属性。 */\nexport interface SideNavRootProps {\n \"data-scope\": \"side-nav\";\n \"data-part\": \"root\";\n \"data-count\": string;\n}\n\n/** Core 生成、由适配器摊到分组标题元素的属性。 */\nexport interface SideNavGroupLabelProps {\n \"data-scope\": \"side-nav\";\n \"data-part\": \"group-label\";\n}\n\n/** Core 生成、由适配器摊到导航项(原生 button)的属性。 */\nexport interface SideNavItemProps {\n type: \"button\";\n \"data-scope\": \"side-nav\";\n \"data-part\": \"item\";\n \"data-state\": \"selected\" | \"default\";\n \"aria-current\"?: \"true\";\n \"data-adjacent\"?: SideNavItemAdjacent;\n disabled: boolean;\n}\n\nfunction resolveItem(\n item: QwSideNavItemProps,\n selectedValue: string | undefined,\n): Omit<ResolvedSideNavItemState, \"adjacent\"> {\n return {\n value: item.value,\n label: item.label,\n disabled: item.disabled ?? false,\n selected: selectedValue !== undefined && item.value === selectedValue,\n };\n}\n\n/** 组内邻接推导:仅与选中项索引差 1 的项获得 adjacent;分组标题为边界。 */\nfunction attachAdjacency(items: ResolvedSideNavItemState[]): void {\n const selectedIndex = items.findIndex((item) => item.selected);\n if (selectedIndex < 0) return;\n for (const item of items) item.adjacent = null;\n if (selectedIndex > 0) {\n const prev = items[selectedIndex - 1];\n if (prev) prev.adjacent = \"prev\";\n }\n if (selectedIndex < items.length - 1) {\n const next = items[selectedIndex + 1];\n if (next) next.adjacent = \"next\";\n }\n}\n\n/**\n * 将公开输入归一化为唯一的跨框架状态。\n * items 非空时作为最前的无标题隐式组;空组(无项)不产生渲染;\n * 全部为空 → visible=false。\n */\nexport function resolveSideNavState(props: QwSideNavProps = {}): ResolvedSideNavState {\n const selectedValue = props.value;\n const rawGroups: QwSideNavGroupProps[] = [];\n if ((props.items ?? []).length > 0) rawGroups.push({ items: props.items ?? [] });\n for (const group of props.groups ?? []) rawGroups.push(group);\n\n const groups: ResolvedSideNavGroupState[] = [];\n let count = 0;\n for (const raw of rawGroups) {\n if (raw.items.length === 0) continue;\n const items = raw.items.map((item) => ({\n ...resolveItem(item, selectedValue),\n adjacent: null as SideNavItemAdjacent | null,\n }));\n attachAdjacency(items);\n groups.push({ ...(raw.title !== undefined ? { title: raw.title } : {}), items });\n count += items.length;\n }\n\n return {\n visible: count > 0,\n count,\n ...(selectedValue !== undefined ? { selectedValue } : {}),\n groups,\n };\n}\n\n/** 将归一化结果转成 root 属性。 */\nexport function getSideNavRootProps(state: ResolvedSideNavState): SideNavRootProps {\n return {\n \"data-scope\": \"side-nav\",\n \"data-part\": \"root\",\n \"data-count\": String(state.count),\n };\n}\n\n/** 分组标题元素属性(无状态入参,纯收口)。 */\nexport function getSideNavGroupLabelProps(): SideNavGroupLabelProps {\n return {\n \"data-scope\": \"side-nav\",\n \"data-part\": \"group-label\",\n };\n}\n\n/** 将单个归一化导航项转成 button 属性(选中/邻接/禁用收口,适配器不得覆盖)。 */\nexport function getSideNavItemProps(item: ResolvedSideNavItemState): SideNavItemProps {\n return {\n type: \"button\",\n \"data-scope\": \"side-nav\",\n \"data-part\": \"item\",\n \"data-state\": item.selected ? \"selected\" : \"default\",\n ...(item.selected ? { \"aria-current\": \"true\" as const } : {}),\n ...(item.adjacent !== null ? { \"data-adjacent\": item.adjacent } : {}),\n disabled: item.disabled,\n };\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,gBAAgB;CAAC;CAAQ;CAAe;AAAM;AAsF3D,SAAS,YACP,MACA,eAC4C;CAC5C,OAAO;EACL,OAAO,KAAK;EACZ,OAAO,KAAK;EACZ,UAAU,KAAK,YAAY;EAC3B,UAAU,kBAAkB,KAAA,KAAa,KAAK,UAAU;CAC1D;AACF;;AAGA,SAAS,gBAAgB,OAAyC;CAChE,MAAM,gBAAgB,MAAM,WAAW,SAAS,KAAK,QAAQ;CAC7D,IAAI,gBAAgB,GAAG;CACvB,KAAK,MAAM,QAAQ,OAAO,KAAK,WAAW;CAC1C,IAAI,gBAAgB,GAAG;EACrB,MAAM,OAAO,MAAM,gBAAgB;EACnC,IAAI,MAAM,KAAK,WAAW;CAC5B;CACA,IAAI,gBAAgB,MAAM,SAAS,GAAG;EACpC,MAAM,OAAO,MAAM,gBAAgB;EACnC,IAAI,MAAM,KAAK,WAAW;CAC5B;AACF;;;;;;AAOA,SAAgB,oBAAoB,QAAwB,CAAC,GAAyB;CACpF,MAAM,gBAAgB,MAAM;CAC5B,MAAM,YAAmC,CAAC;CAC1C,KAAK,MAAM,SAAS,CAAC,EAAA,CAAG,SAAS,GAAG,UAAU,KAAK,EAAE,OAAO,MAAM,SAAS,CAAC,EAAE,CAAC;CAC/E,KAAK,MAAM,SAAS,MAAM,UAAU,CAAC,GAAG,UAAU,KAAK,KAAK;CAE5D,MAAM,SAAsC,CAAC;CAC7C,IAAI,QAAQ;CACZ,KAAK,MAAM,OAAO,WAAW;EAC3B,IAAI,IAAI,MAAM,WAAW,GAAG;EAC5B,MAAM,QAAQ,IAAI,MAAM,KAAK,UAAU;GACrC,GAAG,YAAY,MAAM,aAAa;GAClC,UAAU;EACZ,EAAE;EACF,gBAAgB,KAAK;EACrB,OAAO,KAAK;GAAE,GAAI,IAAI,UAAU,KAAA,IAAY,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;GAAI;EAAM,CAAC;EAC/E,SAAS,MAAM;CACjB;CAEA,OAAO;EACL,SAAS,QAAQ;EACjB;EACA,GAAI,kBAAkB,KAAA,IAAY,EAAE,cAAc,IAAI,CAAC;EACvD;CACF;AACF;;AAGA,SAAgB,oBAAoB,OAA+C;CACjF,OAAO;EACL,cAAc;EACd,aAAa;EACb,cAAc,OAAO,MAAM,KAAK;CAClC;AACF;;AAGA,SAAgB,4BAAoD;CAClE,OAAO;EACL,cAAc;EACd,aAAa;CACf;AACF;;AAGA,SAAgB,oBAAoB,MAAkD;CACpF,OAAO;EACL,MAAM;EACN,cAAc;EACd,aAAa;EACb,cAAc,KAAK,WAAW,aAAa;EAC3C,GAAI,KAAK,WAAW,EAAE,gBAAgB,OAAgB,IAAI,CAAC;EAC3D,GAAI,KAAK,aAAa,OAAO,EAAE,iBAAiB,KAAK,SAAS,IAAI,CAAC;EACnE,UAAU,KAAK;CACjB;AACF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SideNav 的跨框架行为契约。
|
|
3
|
+
*
|
|
4
|
+
* SideNav 是受控单选的 Prototype A 侧导航列:纵向堆叠的导航项(可选分组
|
|
5
|
+
* 标题),多用于 H5 浮层分类切换。选中项白底加粗,组内直接相邻项获得
|
|
6
|
+
* 16px 邻接圆角。这里仅归一化公开 props、推导选中/邻接视觉态并收口
|
|
7
|
+
* data/aria 属性,React/Vue 适配器不得复制归一化、可见性或推导规则。
|
|
8
|
+
*/
|
|
9
|
+
export declare const SIDENAV_PARTS: readonly ["root", "group-label", "item"];
|
|
10
|
+
export type SideNavPart = (typeof SIDENAV_PARTS)[number];
|
|
11
|
+
/** 与选中项直接相邻的方位:prev=上邻项(右下角圆角)、next=下邻项(右上角圆角)。 */
|
|
12
|
+
export type SideNavItemAdjacent = "prev" | "next";
|
|
13
|
+
/** 单个导航项声明;双栈共享,框架特有的事件通道不进入 Core。 */
|
|
14
|
+
export interface QwSideNavItemProps {
|
|
15
|
+
/** 唯一标识;受控选中值与 onChange 回传值均用它比对。 */
|
|
16
|
+
value: string;
|
|
17
|
+
/** 纯文本标签,同时作为按钮可访问名。 */
|
|
18
|
+
label: string;
|
|
19
|
+
/** 禁用标记:保留灰底、文字降为 placeholder 语义色,不可激活。 */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** 分组声明;分组标题仅作视觉区隔,不参与选中语义。 */
|
|
23
|
+
export interface QwSideNavGroupProps {
|
|
24
|
+
/** 分组标题;缺省时该组无标题行。 */
|
|
25
|
+
title?: string;
|
|
26
|
+
/** 该组导航项。 */
|
|
27
|
+
items: readonly QwSideNavItemProps[];
|
|
28
|
+
}
|
|
29
|
+
/** 双栈共享的标量 props。 */
|
|
30
|
+
export interface QwSideNavProps {
|
|
31
|
+
/** 扁平声明;归一化为最前的无标题隐式组。 */
|
|
32
|
+
items?: readonly QwSideNavItemProps[];
|
|
33
|
+
/** 分组声明;追加在隐式组之后。 */
|
|
34
|
+
groups?: readonly QwSideNavGroupProps[];
|
|
35
|
+
/** 受控选中项 value;缺省时全部为默认态。 */
|
|
36
|
+
value?: string;
|
|
37
|
+
/** 项被激活(点击/回车/空格)时回传该项 value;点击已选中项同样触发。 */
|
|
38
|
+
onChange?: (value: string) => void;
|
|
39
|
+
}
|
|
40
|
+
/** 逐项归一化结果。 */
|
|
41
|
+
export interface ResolvedSideNavItemState {
|
|
42
|
+
value: string;
|
|
43
|
+
label: string;
|
|
44
|
+
disabled: boolean;
|
|
45
|
+
/** value 与受控选中值全等。 */
|
|
46
|
+
selected: boolean;
|
|
47
|
+
/** 组内与选中项直接相邻:prev=上邻、next=下邻;否则 null。 */
|
|
48
|
+
adjacent: SideNavItemAdjacent | null;
|
|
49
|
+
}
|
|
50
|
+
/** 归一化分组结果。 */
|
|
51
|
+
export interface ResolvedSideNavGroupState {
|
|
52
|
+
title?: string;
|
|
53
|
+
items: ResolvedSideNavItemState[];
|
|
54
|
+
}
|
|
55
|
+
/** 适配器唯一可消费的归一化结果。 */
|
|
56
|
+
export interface ResolvedSideNavState {
|
|
57
|
+
visible: boolean;
|
|
58
|
+
count: number;
|
|
59
|
+
selectedValue?: string;
|
|
60
|
+
groups: ResolvedSideNavGroupState[];
|
|
61
|
+
}
|
|
62
|
+
/** Core 生成、由适配器摊到根元素(原生 nav)的属性。 */
|
|
63
|
+
export interface SideNavRootProps {
|
|
64
|
+
"data-scope": "side-nav";
|
|
65
|
+
"data-part": "root";
|
|
66
|
+
"data-count": string;
|
|
67
|
+
}
|
|
68
|
+
/** Core 生成、由适配器摊到分组标题元素的属性。 */
|
|
69
|
+
export interface SideNavGroupLabelProps {
|
|
70
|
+
"data-scope": "side-nav";
|
|
71
|
+
"data-part": "group-label";
|
|
72
|
+
}
|
|
73
|
+
/** Core 生成、由适配器摊到导航项(原生 button)的属性。 */
|
|
74
|
+
export interface SideNavItemProps {
|
|
75
|
+
type: "button";
|
|
76
|
+
"data-scope": "side-nav";
|
|
77
|
+
"data-part": "item";
|
|
78
|
+
"data-state": "selected" | "default";
|
|
79
|
+
"aria-current"?: "true";
|
|
80
|
+
"data-adjacent"?: SideNavItemAdjacent;
|
|
81
|
+
disabled: boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 将公开输入归一化为唯一的跨框架状态。
|
|
85
|
+
* items 非空时作为最前的无标题隐式组;空组(无项)不产生渲染;
|
|
86
|
+
* 全部为空 → visible=false。
|
|
87
|
+
*/
|
|
88
|
+
export declare function resolveSideNavState(props?: QwSideNavProps): ResolvedSideNavState;
|
|
89
|
+
/** 将归一化结果转成 root 属性。 */
|
|
90
|
+
export declare function getSideNavRootProps(state: ResolvedSideNavState): SideNavRootProps;
|
|
91
|
+
/** 分组标题元素属性(无状态入参,纯收口)。 */
|
|
92
|
+
export declare function getSideNavGroupLabelProps(): SideNavGroupLabelProps;
|
|
93
|
+
/** 将单个归一化导航项转成 button 属性(选中/邻接/禁用收口,适配器不得覆盖)。 */
|
|
94
|
+
export declare function getSideNavItemProps(item: ResolvedSideNavItemState): SideNavItemProps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./stepper.js";
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
//#region src/stepper/stepper.ts
|
|
2
|
+
/**
|
|
3
|
+
* Stepper 加减(数量步进器)的跨框架行为契约。
|
|
4
|
+
*
|
|
5
|
+
* Stepper 是原型 A(无状态 Core 状态机):交互由原生 `<button>` 承担,
|
|
6
|
+
* core 只负责数值归一化、边界 clamp、按钮可用性计算与 prop-getter 生成。
|
|
7
|
+
*/
|
|
8
|
+
/** 尺寸全集:s = 15×15px,m = 18×18px。 */
|
|
9
|
+
const STEPPER_SIZES = ["s", "m"];
|
|
10
|
+
/** 形态变体全集:default = 裸按钮组合,bordered = 带边框卡片形态。 */
|
|
11
|
+
const STEPPER_VARIANTS = ["default", "bordered"];
|
|
12
|
+
/** 渲染部位全集(data-part 取值)。 */
|
|
13
|
+
const STEPPER_PARTS = [
|
|
14
|
+
"root",
|
|
15
|
+
"decrement",
|
|
16
|
+
"value",
|
|
17
|
+
"increment"
|
|
18
|
+
];
|
|
19
|
+
/** 将数值约束在 [min, max] 范围内;边界未定义时跳过对应侧。 */
|
|
20
|
+
function clampStepperValue(value, min, max) {
|
|
21
|
+
let result = value;
|
|
22
|
+
if (typeof min === "number" && !Number.isNaN(min)) result = Math.max(result, min);
|
|
23
|
+
if (typeof max === "number" && !Number.isNaN(max)) result = Math.min(result, max);
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
/** 规范化 step:仅接受正数,否则回退到 1。 */
|
|
27
|
+
function normalizeStepperStep(step) {
|
|
28
|
+
return typeof step === "number" && step > 0 && !Number.isNaN(step) ? step : 1;
|
|
29
|
+
}
|
|
30
|
+
/** 规范化 min:未指定时按规格默认 0(不做负数默认值)。 */
|
|
31
|
+
function normalizeStepperMin(min) {
|
|
32
|
+
return typeof min === "number" && !Number.isNaN(min) ? min : 0;
|
|
33
|
+
}
|
|
34
|
+
/** 将公开输入归一化为唯一的跨框架状态。 */
|
|
35
|
+
function resolveStepperState(props = {}) {
|
|
36
|
+
const min = normalizeStepperMin(props.min);
|
|
37
|
+
const max = props.max;
|
|
38
|
+
const step = normalizeStepperStep(props.step);
|
|
39
|
+
const disabled = props.disabled ?? false;
|
|
40
|
+
const variant = props.variant ?? "default";
|
|
41
|
+
const value = clampStepperValue(props.value !== void 0 ? props.value : props.defaultValue ?? min, min, max);
|
|
42
|
+
return {
|
|
43
|
+
value,
|
|
44
|
+
min,
|
|
45
|
+
max,
|
|
46
|
+
step,
|
|
47
|
+
disabled,
|
|
48
|
+
size: props.size ?? "m",
|
|
49
|
+
variant,
|
|
50
|
+
selected: value > min,
|
|
51
|
+
canDecrement: !disabled && value > min,
|
|
52
|
+
canIncrement: !disabled && (typeof max !== "number" || value < max),
|
|
53
|
+
decrementLabel: props.decrementLabel ?? "减少",
|
|
54
|
+
incrementLabel: props.incrementLabel ?? "增加"
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/** 计算减量后的目标值(已 clamp)。 */
|
|
58
|
+
function getStepperDecrementValue(state) {
|
|
59
|
+
return clampStepperValue(state.value - state.step, state.min, state.max);
|
|
60
|
+
}
|
|
61
|
+
/** 计算增量后的目标值(已 clamp)。 */
|
|
62
|
+
function getStepperIncrementValue(state) {
|
|
63
|
+
return clampStepperValue(state.value + state.step, state.min, state.max);
|
|
64
|
+
}
|
|
65
|
+
/** 生成根容器属性。 */
|
|
66
|
+
function getStepperRootProps(state) {
|
|
67
|
+
return {
|
|
68
|
+
role: "group",
|
|
69
|
+
"data-scope": "stepper",
|
|
70
|
+
"data-part": "root",
|
|
71
|
+
"data-size": state.size,
|
|
72
|
+
"data-variant": state.variant,
|
|
73
|
+
...state.selected ? { "data-selected": "true" } : {},
|
|
74
|
+
...state.disabled ? { "data-disabled": "true" } : {}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** 生成减量按钮属性。 */
|
|
78
|
+
function getStepperDecrementProps(state) {
|
|
79
|
+
const disabled = !state.canDecrement;
|
|
80
|
+
return {
|
|
81
|
+
type: "button",
|
|
82
|
+
disabled,
|
|
83
|
+
"data-scope": "stepper",
|
|
84
|
+
"data-part": "decrement",
|
|
85
|
+
"aria-label": state.decrementLabel,
|
|
86
|
+
...disabled ? { "data-disabled": "true" } : {}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** 生成增量按钮属性。 */
|
|
90
|
+
function getStepperIncrementProps(state) {
|
|
91
|
+
const disabled = !state.canIncrement;
|
|
92
|
+
return {
|
|
93
|
+
type: "button",
|
|
94
|
+
disabled,
|
|
95
|
+
"data-scope": "stepper",
|
|
96
|
+
"data-part": "increment",
|
|
97
|
+
"aria-label": state.incrementLabel,
|
|
98
|
+
...disabled ? { "data-disabled": "true" } : {}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** 生成数值展示属性。 */
|
|
102
|
+
function getStepperValueProps() {
|
|
103
|
+
return {
|
|
104
|
+
"data-scope": "stepper",
|
|
105
|
+
"data-part": "value",
|
|
106
|
+
"aria-live": "polite",
|
|
107
|
+
"aria-atomic": "true"
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
export { STEPPER_PARTS, STEPPER_SIZES, STEPPER_VARIANTS, clampStepperValue, getStepperDecrementProps, getStepperDecrementValue, getStepperIncrementProps, getStepperIncrementValue, getStepperRootProps, getStepperValueProps, resolveStepperState };
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/stepper/stepper.ts"],"sourcesContent":["/**\n * Stepper 加减(数量步进器)的跨框架行为契约。\n *\n * Stepper 是原型 A(无状态 Core 状态机):交互由原生 `<button>` 承担,\n * core 只负责数值归一化、边界 clamp、按钮可用性计算与 prop-getter 生成。\n */\n\n/** 尺寸全集:s = 15×15px,m = 18×18px。 */\nexport const STEPPER_SIZES = [\"s\", \"m\"] as const;\n\n/** 形态变体全集:default = 裸按钮组合,bordered = 带边框卡片形态。 */\nexport const STEPPER_VARIANTS = [\"default\", \"bordered\"] as const;\n\n/** 渲染部位全集(data-part 取值)。 */\nexport const STEPPER_PARTS = [\"root\", \"decrement\", \"value\", \"increment\"] as const;\n\nexport type StepperSize = (typeof STEPPER_SIZES)[number];\nexport type StepperVariant = (typeof STEPPER_VARIANTS)[number];\nexport type StepperPart = (typeof STEPPER_PARTS)[number];\n\n/**\n * QwStepperProps — 双栈共享的行为契约(全字段可选)。\n * `value` 未传时走非受控模式,由适配层管理内部数值。\n */\nexport interface QwStepperProps {\n /** 受控值。未传时走非受控模式。 */\n value?: number;\n /** 非受控初始值,默认 `0`(若 `min > 0` 则取 `min`)。仅在 `value` 未传时生效。 */\n defaultValue?: number;\n /** 数值变化回调,参数为新的 value。 */\n onChange?: (value: number) => void;\n /** 最小值。 */\n min?: number;\n /** 最大值。 */\n max?: number;\n /** 步长,默认 1;非法值(非正数)回退到 1。 */\n step?: number;\n /** 禁用状态。 */\n disabled?: boolean;\n /** 按钮尺寸,默认 m。 */\n size?: StepperSize;\n /** 形态变体,默认 default;bordered 为带边框卡片形态。 */\n variant?: StepperVariant;\n /** 减量按钮 aria-label,默认「减少」(适配层可注入语言包取值)。 */\n decrementLabel?: string;\n /** 增量按钮 aria-label,默认「增加」(适配层可注入语言包取值)。 */\n incrementLabel?: string;\n}\n\n/** 适配器唯一可消费的归一化结果。 */\nexport interface ResolvedStepperState {\n /** 当前数值(已按 min/max clamp)。 */\n value: number;\n /** 最小值。 */\n min: number | undefined;\n /** 最大值。 */\n max: number | undefined;\n /** 实际生效的步长。 */\n step: number;\n /** 是否整体禁用。 */\n disabled: boolean;\n /** 按钮尺寸。 */\n size: StepperSize;\n /** 形态变体。 */\n variant: StepperVariant;\n /** 选中态:value > min 派生,仅影响 bordered 视觉。 */\n selected: boolean;\n /** 减量按钮是否可用。 */\n canDecrement: boolean;\n /** 增量按钮是否可用。 */\n canIncrement: boolean;\n /** 减量按钮 aria-label(per-prop > 适配层注入 > 内置「减少」)。 */\n decrementLabel: string;\n /** 增量按钮 aria-label(per-prop > 适配层注入 > 内置「增加」)。 */\n incrementLabel: string;\n}\n\n/** 将数值约束在 [min, max] 范围内;边界未定义时跳过对应侧。 */\nexport function clampStepperValue(\n value: number,\n min: number | undefined,\n max: number | undefined,\n): number {\n let result = value;\n if (typeof min === \"number\" && !Number.isNaN(min)) {\n result = Math.max(result, min);\n }\n if (typeof max === \"number\" && !Number.isNaN(max)) {\n result = Math.min(result, max);\n }\n return result;\n}\n\n/** 规范化 step:仅接受正数,否则回退到 1。 */\nfunction normalizeStepperStep(step: number | undefined): number {\n return typeof step === \"number\" && step > 0 && !Number.isNaN(step) ? step : 1;\n}\n\n/** 规范化 min:未指定时按规格默认 0(不做负数默认值)。 */\nfunction normalizeStepperMin(min: number | undefined): number {\n return typeof min === \"number\" && !Number.isNaN(min) ? min : 0;\n}\n\n/** 将公开输入归一化为唯一的跨框架状态。 */\nexport function resolveStepperState(props: QwStepperProps = {}): ResolvedStepperState {\n const min = normalizeStepperMin(props.min);\n const max = props.max;\n const step = normalizeStepperStep(props.step);\n const disabled = props.disabled ?? false;\n const variant = props.variant ?? \"default\";\n\n const isControlled = props.value !== undefined;\n const rawValue = isControlled\n ? props.value!\n : (props.defaultValue ?? min);\n\n const value = clampStepperValue(rawValue, min, max);\n\n const size = props.size ?? \"m\";\n\n const selected = value > min;\n\n const canDecrement = !disabled && value > min;\n const canIncrement = !disabled && (typeof max !== \"number\" || value < max);\n\n return {\n value,\n min,\n max,\n step,\n disabled,\n size,\n variant,\n selected,\n canDecrement,\n canIncrement,\n decrementLabel: props.decrementLabel ?? \"减少\",\n incrementLabel: props.incrementLabel ?? \"增加\",\n };\n}\n\n/** 计算减量后的目标值(已 clamp)。 */\nexport function getStepperDecrementValue(state: ResolvedStepperState): number {\n return clampStepperValue(state.value - state.step, state.min, state.max);\n}\n\n/** 计算增量后的目标值(已 clamp)。 */\nexport function getStepperIncrementValue(state: ResolvedStepperState): number {\n return clampStepperValue(state.value + state.step, state.min, state.max);\n}\n\n/** Core 生成、由适配器最后覆盖到根元素的属性。 */\nexport interface StepperRootProps {\n role: \"group\";\n \"data-scope\": \"stepper\";\n \"data-part\": \"root\";\n \"data-size\": StepperSize;\n \"data-variant\": StepperVariant;\n \"data-selected\"?: \"true\";\n \"data-disabled\"?: \"true\";\n}\n\n/** 生成根容器属性。 */\nexport function getStepperRootProps(state: ResolvedStepperState): StepperRootProps {\n return {\n role: \"group\",\n \"data-scope\": \"stepper\",\n \"data-part\": \"root\",\n \"data-size\": state.size,\n \"data-variant\": state.variant,\n ...(state.selected ? { \"data-selected\": \"true\" as const } : {}),\n ...(state.disabled ? { \"data-disabled\": \"true\" as const } : {}),\n };\n}\n\n/** 减量按钮属性。 */\nexport interface StepperDecrementProps {\n type: \"button\";\n disabled: boolean;\n \"data-scope\": \"stepper\";\n \"data-part\": \"decrement\";\n \"aria-label\": string;\n \"data-disabled\"?: \"true\";\n}\n\n/** 生成减量按钮属性。 */\nexport function getStepperDecrementProps(state: ResolvedStepperState): StepperDecrementProps {\n const disabled = !state.canDecrement;\n return {\n type: \"button\",\n disabled,\n \"data-scope\": \"stepper\",\n \"data-part\": \"decrement\",\n \"aria-label\": state.decrementLabel,\n ...(disabled ? { \"data-disabled\": \"true\" as const } : {}),\n };\n}\n\n/** 增量按钮属性。 */\nexport interface StepperIncrementProps {\n type: \"button\";\n disabled: boolean;\n \"data-scope\": \"stepper\";\n \"data-part\": \"increment\";\n \"aria-label\": string;\n \"data-disabled\"?: \"true\";\n}\n\n/** 生成增量按钮属性。 */\nexport function getStepperIncrementProps(state: ResolvedStepperState): StepperIncrementProps {\n const disabled = !state.canIncrement;\n return {\n type: \"button\",\n disabled,\n \"data-scope\": \"stepper\",\n \"data-part\": \"increment\",\n \"aria-label\": state.incrementLabel,\n ...(disabled ? { \"data-disabled\": \"true\" as const } : {}),\n };\n}\n\n/** 数值展示属性。 */\nexport interface StepperValueProps {\n \"data-scope\": \"stepper\";\n \"data-part\": \"value\";\n \"aria-live\": \"polite\";\n \"aria-atomic\": \"true\";\n}\n\n/** 生成数值展示属性。 */\nexport function getStepperValueProps(): StepperValueProps {\n return {\n \"data-scope\": \"stepper\",\n \"data-part\": \"value\",\n \"aria-live\": \"polite\",\n \"aria-atomic\": \"true\",\n };\n}\n"],"mappings":";;;;;;;;AAQA,MAAa,gBAAgB,CAAC,KAAK,GAAG;;AAGtC,MAAa,mBAAmB,CAAC,WAAW,UAAU;;AAGtD,MAAa,gBAAgB;CAAC;CAAQ;CAAa;CAAS;AAAW;;AAgEvE,SAAgB,kBACd,OACA,KACA,KACQ;CACR,IAAI,SAAS;CACb,IAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,MAAM,GAAG,GAC9C,SAAS,KAAK,IAAI,QAAQ,GAAG;CAE/B,IAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,MAAM,GAAG,GAC9C,SAAS,KAAK,IAAI,QAAQ,GAAG;CAE/B,OAAO;AACT;;AAGA,SAAS,qBAAqB,MAAkC;CAC9D,OAAO,OAAO,SAAS,YAAY,OAAO,KAAK,CAAC,OAAO,MAAM,IAAI,IAAI,OAAO;AAC9E;;AAGA,SAAS,oBAAoB,KAAiC;CAC5D,OAAO,OAAO,QAAQ,YAAY,CAAC,OAAO,MAAM,GAAG,IAAI,MAAM;AAC/D;;AAGA,SAAgB,oBAAoB,QAAwB,CAAC,GAAyB;CACpF,MAAM,MAAM,oBAAoB,MAAM,GAAG;CACzC,MAAM,MAAM,MAAM;CAClB,MAAM,OAAO,qBAAqB,MAAM,IAAI;CAC5C,MAAM,WAAW,MAAM,YAAY;CACnC,MAAM,UAAU,MAAM,WAAW;CAOjC,MAAM,QAAQ,kBALO,MAAM,UAAU,KAAA,IAEjC,MAAM,QACL,MAAM,gBAAgB,KAEe,KAAK,GAAG;CASlD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA,MAbW,MAAM,QAAQ;EAczB;EACA,UAbe,QAAQ;EAcvB,cAZmB,CAAC,YAAY,QAAQ;EAaxC,cAZmB,CAAC,aAAa,OAAO,QAAQ,YAAY,QAAQ;EAapE,gBAAgB,MAAM,kBAAkB;EACxC,gBAAgB,MAAM,kBAAkB;CAC1C;AACF;;AAGA,SAAgB,yBAAyB,OAAqC;CAC5E,OAAO,kBAAkB,MAAM,QAAQ,MAAM,MAAM,MAAM,KAAK,MAAM,GAAG;AACzE;;AAGA,SAAgB,yBAAyB,OAAqC;CAC5E,OAAO,kBAAkB,MAAM,QAAQ,MAAM,MAAM,MAAM,KAAK,MAAM,GAAG;AACzE;;AAcA,SAAgB,oBAAoB,OAA+C;CACjF,OAAO;EACL,MAAM;EACN,cAAc;EACd,aAAa;EACb,aAAa,MAAM;EACnB,gBAAgB,MAAM;EACtB,GAAI,MAAM,WAAW,EAAE,iBAAiB,OAAgB,IAAI,CAAC;EAC7D,GAAI,MAAM,WAAW,EAAE,iBAAiB,OAAgB,IAAI,CAAC;CAC/D;AACF;;AAaA,SAAgB,yBAAyB,OAAoD;CAC3F,MAAM,WAAW,CAAC,MAAM;CACxB,OAAO;EACL,MAAM;EACN;EACA,cAAc;EACd,aAAa;EACb,cAAc,MAAM;EACpB,GAAI,WAAW,EAAE,iBAAiB,OAAgB,IAAI,CAAC;CACzD;AACF;;AAaA,SAAgB,yBAAyB,OAAoD;CAC3F,MAAM,WAAW,CAAC,MAAM;CACxB,OAAO;EACL,MAAM;EACN;EACA,cAAc;EACd,aAAa;EACb,cAAc,MAAM;EACpB,GAAI,WAAW,EAAE,iBAAiB,OAAgB,IAAI,CAAC;CACzD;AACF;;AAWA,SAAgB,uBAA0C;CACxD,OAAO;EACL,cAAc;EACd,aAAa;EACb,aAAa;EACb,eAAe;CACjB;AACF"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stepper 加减(数量步进器)的跨框架行为契约。
|
|
3
|
+
*
|
|
4
|
+
* Stepper 是原型 A(无状态 Core 状态机):交互由原生 `<button>` 承担,
|
|
5
|
+
* core 只负责数值归一化、边界 clamp、按钮可用性计算与 prop-getter 生成。
|
|
6
|
+
*/
|
|
7
|
+
/** 尺寸全集:s = 15×15px,m = 18×18px。 */
|
|
8
|
+
export declare const STEPPER_SIZES: readonly ["s", "m"];
|
|
9
|
+
/** 形态变体全集:default = 裸按钮组合,bordered = 带边框卡片形态。 */
|
|
10
|
+
export declare const STEPPER_VARIANTS: readonly ["default", "bordered"];
|
|
11
|
+
/** 渲染部位全集(data-part 取值)。 */
|
|
12
|
+
export declare const STEPPER_PARTS: readonly ["root", "decrement", "value", "increment"];
|
|
13
|
+
export type StepperSize = (typeof STEPPER_SIZES)[number];
|
|
14
|
+
export type StepperVariant = (typeof STEPPER_VARIANTS)[number];
|
|
15
|
+
export type StepperPart = (typeof STEPPER_PARTS)[number];
|
|
16
|
+
/**
|
|
17
|
+
* QwStepperProps — 双栈共享的行为契约(全字段可选)。
|
|
18
|
+
* `value` 未传时走非受控模式,由适配层管理内部数值。
|
|
19
|
+
*/
|
|
20
|
+
export interface QwStepperProps {
|
|
21
|
+
/** 受控值。未传时走非受控模式。 */
|
|
22
|
+
value?: number;
|
|
23
|
+
/** 非受控初始值,默认 `0`(若 `min > 0` 则取 `min`)。仅在 `value` 未传时生效。 */
|
|
24
|
+
defaultValue?: number;
|
|
25
|
+
/** 数值变化回调,参数为新的 value。 */
|
|
26
|
+
onChange?: (value: number) => void;
|
|
27
|
+
/** 最小值。 */
|
|
28
|
+
min?: number;
|
|
29
|
+
/** 最大值。 */
|
|
30
|
+
max?: number;
|
|
31
|
+
/** 步长,默认 1;非法值(非正数)回退到 1。 */
|
|
32
|
+
step?: number;
|
|
33
|
+
/** 禁用状态。 */
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
/** 按钮尺寸,默认 m。 */
|
|
36
|
+
size?: StepperSize;
|
|
37
|
+
/** 形态变体,默认 default;bordered 为带边框卡片形态。 */
|
|
38
|
+
variant?: StepperVariant;
|
|
39
|
+
/** 减量按钮 aria-label,默认「减少」(适配层可注入语言包取值)。 */
|
|
40
|
+
decrementLabel?: string;
|
|
41
|
+
/** 增量按钮 aria-label,默认「增加」(适配层可注入语言包取值)。 */
|
|
42
|
+
incrementLabel?: string;
|
|
43
|
+
}
|
|
44
|
+
/** 适配器唯一可消费的归一化结果。 */
|
|
45
|
+
export interface ResolvedStepperState {
|
|
46
|
+
/** 当前数值(已按 min/max clamp)。 */
|
|
47
|
+
value: number;
|
|
48
|
+
/** 最小值。 */
|
|
49
|
+
min: number | undefined;
|
|
50
|
+
/** 最大值。 */
|
|
51
|
+
max: number | undefined;
|
|
52
|
+
/** 实际生效的步长。 */
|
|
53
|
+
step: number;
|
|
54
|
+
/** 是否整体禁用。 */
|
|
55
|
+
disabled: boolean;
|
|
56
|
+
/** 按钮尺寸。 */
|
|
57
|
+
size: StepperSize;
|
|
58
|
+
/** 形态变体。 */
|
|
59
|
+
variant: StepperVariant;
|
|
60
|
+
/** 选中态:value > min 派生,仅影响 bordered 视觉。 */
|
|
61
|
+
selected: boolean;
|
|
62
|
+
/** 减量按钮是否可用。 */
|
|
63
|
+
canDecrement: boolean;
|
|
64
|
+
/** 增量按钮是否可用。 */
|
|
65
|
+
canIncrement: boolean;
|
|
66
|
+
/** 减量按钮 aria-label(per-prop > 适配层注入 > 内置「减少」)。 */
|
|
67
|
+
decrementLabel: string;
|
|
68
|
+
/** 增量按钮 aria-label(per-prop > 适配层注入 > 内置「增加」)。 */
|
|
69
|
+
incrementLabel: string;
|
|
70
|
+
}
|
|
71
|
+
/** 将数值约束在 [min, max] 范围内;边界未定义时跳过对应侧。 */
|
|
72
|
+
export declare function clampStepperValue(value: number, min: number | undefined, max: number | undefined): number;
|
|
73
|
+
/** 将公开输入归一化为唯一的跨框架状态。 */
|
|
74
|
+
export declare function resolveStepperState(props?: QwStepperProps): ResolvedStepperState;
|
|
75
|
+
/** 计算减量后的目标值(已 clamp)。 */
|
|
76
|
+
export declare function getStepperDecrementValue(state: ResolvedStepperState): number;
|
|
77
|
+
/** 计算增量后的目标值(已 clamp)。 */
|
|
78
|
+
export declare function getStepperIncrementValue(state: ResolvedStepperState): number;
|
|
79
|
+
/** Core 生成、由适配器最后覆盖到根元素的属性。 */
|
|
80
|
+
export interface StepperRootProps {
|
|
81
|
+
role: "group";
|
|
82
|
+
"data-scope": "stepper";
|
|
83
|
+
"data-part": "root";
|
|
84
|
+
"data-size": StepperSize;
|
|
85
|
+
"data-variant": StepperVariant;
|
|
86
|
+
"data-selected"?: "true";
|
|
87
|
+
"data-disabled"?: "true";
|
|
88
|
+
}
|
|
89
|
+
/** 生成根容器属性。 */
|
|
90
|
+
export declare function getStepperRootProps(state: ResolvedStepperState): StepperRootProps;
|
|
91
|
+
/** 减量按钮属性。 */
|
|
92
|
+
export interface StepperDecrementProps {
|
|
93
|
+
type: "button";
|
|
94
|
+
disabled: boolean;
|
|
95
|
+
"data-scope": "stepper";
|
|
96
|
+
"data-part": "decrement";
|
|
97
|
+
"aria-label": string;
|
|
98
|
+
"data-disabled"?: "true";
|
|
99
|
+
}
|
|
100
|
+
/** 生成减量按钮属性。 */
|
|
101
|
+
export declare function getStepperDecrementProps(state: ResolvedStepperState): StepperDecrementProps;
|
|
102
|
+
/** 增量按钮属性。 */
|
|
103
|
+
export interface StepperIncrementProps {
|
|
104
|
+
type: "button";
|
|
105
|
+
disabled: boolean;
|
|
106
|
+
"data-scope": "stepper";
|
|
107
|
+
"data-part": "increment";
|
|
108
|
+
"aria-label": string;
|
|
109
|
+
"data-disabled"?: "true";
|
|
110
|
+
}
|
|
111
|
+
/** 生成增量按钮属性。 */
|
|
112
|
+
export declare function getStepperIncrementProps(state: ResolvedStepperState): StepperIncrementProps;
|
|
113
|
+
/** 数值展示属性。 */
|
|
114
|
+
export interface StepperValueProps {
|
|
115
|
+
"data-scope": "stepper";
|
|
116
|
+
"data-part": "value";
|
|
117
|
+
"aria-live": "polite";
|
|
118
|
+
"aria-atomic": "true";
|
|
119
|
+
}
|
|
120
|
+
/** 生成数值展示属性。 */
|
|
121
|
+
export declare function getStepperValueProps(): StepperValueProps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./switch.js";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region src/switch/switch.ts
|
|
2
|
+
/**
|
|
3
|
+
* Switch 的跨框架行为契约。
|
|
4
|
+
*
|
|
5
|
+
* Switch 是无状态的 Prototype A:交互由原生 button 承担,
|
|
6
|
+
* 这里仅归一化公开 props(checked / defaultChecked / disabled)。
|
|
7
|
+
* React/Vue 适配器不得复制 disabled 或 checked 的组合规则。
|
|
8
|
+
*/
|
|
9
|
+
/** Switch 各渲染部位全集(data-part 取值)。 */
|
|
10
|
+
const SWITCH_PARTS = ["root", "thumb"];
|
|
11
|
+
/** 将公开输入归一化为唯一的跨框架状态。 */
|
|
12
|
+
function resolveSwitchState(props = {}) {
|
|
13
|
+
return {
|
|
14
|
+
checked: props.checked ?? props.defaultChecked ?? false,
|
|
15
|
+
disabled: props.disabled ?? false,
|
|
16
|
+
type: props.type ?? "button"
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** 将归一化结果转成 root 属性。 */
|
|
20
|
+
function getSwitchRootProps(state) {
|
|
21
|
+
return {
|
|
22
|
+
type: state.type,
|
|
23
|
+
role: "switch",
|
|
24
|
+
disabled: state.disabled,
|
|
25
|
+
"aria-checked": state.checked ? "true" : "false",
|
|
26
|
+
"data-scope": "switch",
|
|
27
|
+
"data-part": "root",
|
|
28
|
+
"data-checked": state.checked ? "true" : "false",
|
|
29
|
+
...state.disabled ? { "data-disabled": "true" } : {}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** 生成旋钮属性。 */
|
|
33
|
+
function getSwitchThumbProps() {
|
|
34
|
+
return {
|
|
35
|
+
"data-scope": "switch",
|
|
36
|
+
"data-part": "thumb",
|
|
37
|
+
"aria-hidden": "true"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { SWITCH_PARTS, getSwitchRootProps, getSwitchThumbProps, resolveSwitchState };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/switch/switch.ts"],"sourcesContent":["/**\n * Switch 的跨框架行为契约。\n *\n * Switch 是无状态的 Prototype A:交互由原生 button 承担,\n * 这里仅归一化公开 props(checked / defaultChecked / disabled)。\n * React/Vue 适配器不得复制 disabled 或 checked 的组合规则。\n */\n\n/** Switch 各渲染部位全集(data-part 取值)。 */\nexport const SWITCH_PARTS = [\"root\", \"thumb\"] as const;\n\nexport type SwitchPart = (typeof SWITCH_PARTS)[number];\n\n/**\n * QwSwitchProps — 双栈共享的行为契约(全字段可选)。\n * checked 未传时走非受控模式,由适配层管理内部状态。\n */\nexport interface QwSwitchProps {\n /** 受控值。未传时走非受控模式。 */\n checked?: boolean;\n /** 非受控初始值,默认 false。仅在 checked 未传时生效。 */\n defaultChecked?: boolean;\n /** 状态变化回调,参数为新的 checked 值。 */\n onToggle?: (checked: boolean) => void;\n /** 禁用状态。 */\n disabled?: boolean;\n /** 原生 button 类型,默认 `button`。 */\n type?: \"button\" | \"submit\" | \"reset\";\n}\n\n/** 适配器唯一可消费的归一化结果。 */\nexport interface ResolvedSwitchState {\n checked: boolean;\n disabled: boolean;\n type: \"button\" | \"submit\" | \"reset\";\n}\n\n/** Core 生成、由适配器最后覆盖到根元素的属性。 */\nexport interface SwitchRootProps {\n type: \"button\" | \"submit\" | \"reset\";\n role: \"switch\";\n disabled: boolean;\n \"aria-checked\": \"true\" | \"false\";\n \"data-scope\": \"switch\";\n \"data-part\": \"root\";\n \"data-checked\": \"true\" | \"false\";\n \"data-disabled\"?: \"true\";\n}\n\n/** 旋钮属性(纯视觉元素)。 */\nexport interface SwitchThumbProps {\n \"data-scope\": \"switch\";\n \"data-part\": \"thumb\";\n \"aria-hidden\": \"true\";\n}\n\n/** 将公开输入归一化为唯一的跨框架状态。 */\nexport function resolveSwitchState(props: QwSwitchProps = {}): ResolvedSwitchState {\n return {\n checked: props.checked ?? props.defaultChecked ?? false,\n disabled: props.disabled ?? false,\n type: props.type ?? \"button\",\n };\n}\n\n/** 将归一化结果转成 root 属性。 */\nexport function getSwitchRootProps(state: ResolvedSwitchState): SwitchRootProps {\n return {\n type: state.type,\n role: \"switch\",\n disabled: state.disabled,\n \"aria-checked\": state.checked ? \"true\" : \"false\",\n \"data-scope\": \"switch\",\n \"data-part\": \"root\",\n \"data-checked\": state.checked ? \"true\" : \"false\",\n ...(state.disabled ? { \"data-disabled\": \"true\" as const } : {}),\n };\n}\n\n/** 生成旋钮属性。 */\nexport function getSwitchThumbProps(): SwitchThumbProps {\n return {\n \"data-scope\": \"switch\",\n \"data-part\": \"thumb\",\n \"aria-hidden\": \"true\",\n };\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,eAAe,CAAC,QAAQ,OAAO;;AAgD5C,SAAgB,mBAAmB,QAAuB,CAAC,GAAwB;CACjF,OAAO;EACL,SAAS,MAAM,WAAW,MAAM,kBAAkB;EAClD,UAAU,MAAM,YAAY;EAC5B,MAAM,MAAM,QAAQ;CACtB;AACF;;AAGA,SAAgB,mBAAmB,OAA6C;CAC9E,OAAO;EACL,MAAM,MAAM;EACZ,MAAM;EACN,UAAU,MAAM;EAChB,gBAAgB,MAAM,UAAU,SAAS;EACzC,cAAc;EACd,aAAa;EACb,gBAAgB,MAAM,UAAU,SAAS;EACzC,GAAI,MAAM,WAAW,EAAE,iBAAiB,OAAgB,IAAI,CAAC;CAC/D;AACF;;AAGA,SAAgB,sBAAwC;CACtD,OAAO;EACL,cAAc;EACd,aAAa;EACb,eAAe;CACjB;AACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Switch 的跨框架行为契约。
|
|
3
|
+
*
|
|
4
|
+
* Switch 是无状态的 Prototype A:交互由原生 button 承担,
|
|
5
|
+
* 这里仅归一化公开 props(checked / defaultChecked / disabled)。
|
|
6
|
+
* React/Vue 适配器不得复制 disabled 或 checked 的组合规则。
|
|
7
|
+
*/
|
|
8
|
+
/** Switch 各渲染部位全集(data-part 取值)。 */
|
|
9
|
+
export declare const SWITCH_PARTS: readonly ["root", "thumb"];
|
|
10
|
+
export type SwitchPart = (typeof SWITCH_PARTS)[number];
|
|
11
|
+
/**
|
|
12
|
+
* QwSwitchProps — 双栈共享的行为契约(全字段可选)。
|
|
13
|
+
* checked 未传时走非受控模式,由适配层管理内部状态。
|
|
14
|
+
*/
|
|
15
|
+
export interface QwSwitchProps {
|
|
16
|
+
/** 受控值。未传时走非受控模式。 */
|
|
17
|
+
checked?: boolean;
|
|
18
|
+
/** 非受控初始值,默认 false。仅在 checked 未传时生效。 */
|
|
19
|
+
defaultChecked?: boolean;
|
|
20
|
+
/** 状态变化回调,参数为新的 checked 值。 */
|
|
21
|
+
onToggle?: (checked: boolean) => void;
|
|
22
|
+
/** 禁用状态。 */
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
/** 原生 button 类型,默认 `button`。 */
|
|
25
|
+
type?: "button" | "submit" | "reset";
|
|
26
|
+
}
|
|
27
|
+
/** 适配器唯一可消费的归一化结果。 */
|
|
28
|
+
export interface ResolvedSwitchState {
|
|
29
|
+
checked: boolean;
|
|
30
|
+
disabled: boolean;
|
|
31
|
+
type: "button" | "submit" | "reset";
|
|
32
|
+
}
|
|
33
|
+
/** Core 生成、由适配器最后覆盖到根元素的属性。 */
|
|
34
|
+
export interface SwitchRootProps {
|
|
35
|
+
type: "button" | "submit" | "reset";
|
|
36
|
+
role: "switch";
|
|
37
|
+
disabled: boolean;
|
|
38
|
+
"aria-checked": "true" | "false";
|
|
39
|
+
"data-scope": "switch";
|
|
40
|
+
"data-part": "root";
|
|
41
|
+
"data-checked": "true" | "false";
|
|
42
|
+
"data-disabled"?: "true";
|
|
43
|
+
}
|
|
44
|
+
/** 旋钮属性(纯视觉元素)。 */
|
|
45
|
+
export interface SwitchThumbProps {
|
|
46
|
+
"data-scope": "switch";
|
|
47
|
+
"data-part": "thumb";
|
|
48
|
+
"aria-hidden": "true";
|
|
49
|
+
}
|
|
50
|
+
/** 将公开输入归一化为唯一的跨框架状态。 */
|
|
51
|
+
export declare function resolveSwitchState(props?: QwSwitchProps): ResolvedSwitchState;
|
|
52
|
+
/** 将归一化结果转成 root 属性。 */
|
|
53
|
+
export declare function getSwitchRootProps(state: ResolvedSwitchState): SwitchRootProps;
|
|
54
|
+
/** 生成旋钮属性。 */
|
|
55
|
+
export declare function getSwitchThumbProps(): SwitchThumbProps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./tabbar.js";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region src/tabbar/tabbar.ts
|
|
2
|
+
/**
|
|
3
|
+
* TabBar 的跨框架行为契约。
|
|
4
|
+
*
|
|
5
|
+
* TabBar 是无状态的 Prototype A 底部操作栏:白底容器 + 顶部 1px 分割线 +
|
|
6
|
+
* 1–N 个等宽 L 号按钮(组合已交付的 Button)。这里仅归一化公开 props 与
|
|
7
|
+
* item → Button 的档位映射,React/Vue 适配器不得复制可见性、默认档位或
|
|
8
|
+
* 映射规则。
|
|
9
|
+
*/
|
|
10
|
+
const TABBAR_ITEM_VARIANTS = ["primary", "secondary"];
|
|
11
|
+
const TABBAR_ITEM_TONES = ["brand", "neutral"];
|
|
12
|
+
const TABBAR_PARTS = ["root"];
|
|
13
|
+
/** 将公开输入归一化为唯一的跨框架状态;items 缺省/空 → 不可见。 */
|
|
14
|
+
function resolveTabBarState(props = {}) {
|
|
15
|
+
const items = (props.items ?? []).map((item) => ({
|
|
16
|
+
text: item.text,
|
|
17
|
+
variant: item.variant ?? "primary",
|
|
18
|
+
tone: item.tone ?? "brand",
|
|
19
|
+
disabled: item.disabled ?? false,
|
|
20
|
+
loading: item.loading ?? false,
|
|
21
|
+
...item.onClick ? { onClick: item.onClick } : {}
|
|
22
|
+
}));
|
|
23
|
+
return {
|
|
24
|
+
visible: items.length > 0,
|
|
25
|
+
count: items.length,
|
|
26
|
+
items
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** 将归一化结果转成 root 属性。 */
|
|
30
|
+
function getTabBarRootProps(state) {
|
|
31
|
+
return {
|
|
32
|
+
"data-scope": "tabbar",
|
|
33
|
+
"data-part": "root",
|
|
34
|
+
"data-count": String(state.count)
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** 将单个操作项映射为 Button props(档位收口,适配器不得覆盖)。 */
|
|
38
|
+
function getTabBarItemButtonProps(item) {
|
|
39
|
+
return {
|
|
40
|
+
variant: item.variant === "primary" ? "solid" : "soft",
|
|
41
|
+
tone: item.tone,
|
|
42
|
+
size: "l",
|
|
43
|
+
disabled: item.disabled,
|
|
44
|
+
loading: item.loading
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { TABBAR_ITEM_TONES, TABBAR_ITEM_VARIANTS, TABBAR_PARTS, getTabBarItemButtonProps, getTabBarRootProps, resolveTabBarState };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/tabbar/tabbar.ts"],"sourcesContent":["/**\n * TabBar 的跨框架行为契约。\n *\n * TabBar 是无状态的 Prototype A 底部操作栏:白底容器 + 顶部 1px 分割线 +\n * 1–N 个等宽 L 号按钮(组合已交付的 Button)。这里仅归一化公开 props 与\n * item → Button 的档位映射,React/Vue 适配器不得复制可见性、默认档位或\n * 映射规则。\n */\n\nexport const TABBAR_ITEM_VARIANTS = [\"primary\", \"secondary\"] as const;\nexport const TABBAR_ITEM_TONES = [\"brand\", \"neutral\"] as const;\nexport const TABBAR_PARTS = [\"root\"] as const;\n\nexport type TabBarItemVariant = (typeof TABBAR_ITEM_VARIANTS)[number];\nexport type TabBarItemTone = (typeof TABBAR_ITEM_TONES)[number];\nexport type TabBarPart = (typeof TABBAR_PARTS)[number];\n\n/** 单个操作项声明;双栈共享,框架特有的事件通道不进入 Core。 */\nexport interface QwTabBarItemProps {\n /** 按钮文案,同时作为可访问名。 */\n text: string;\n /** 视觉档位,默认 `primary`。primary→Button solid;secondary→Button soft。 */\n variant?: TabBarItemVariant;\n /** 语气,默认 `brand`。 */\n tone?: TabBarItemTone;\n /** 原生禁用状态。 */\n disabled?: boolean;\n /** 忙碌态,沿用 Button loading 契约。 */\n loading?: boolean;\n /** 点击(含键盘激活)回调。 */\n onClick?: () => void;\n}\n\n/** 双栈共享的标量 props。 */\nexport interface QwTabBarProps {\n /** 操作项列表;缺省或空数组时组件不渲染。 */\n items?: readonly QwTabBarItemProps[];\n}\n\n/** 逐项归一化结果。 */\nexport interface ResolvedTabBarItemState {\n text: string;\n variant: TabBarItemVariant;\n tone: TabBarItemTone;\n disabled: boolean;\n loading: boolean;\n onClick?: () => void;\n}\n\n/** 适配器唯一可消费的归一化结果。 */\nexport interface ResolvedTabBarState {\n visible: boolean;\n count: number;\n items: ResolvedTabBarItemState[];\n}\n\n/** Core 生成、由适配器摊到根元素的属性。 */\nexport interface TabBarRootProps {\n \"data-scope\": \"tabbar\";\n \"data-part\": \"root\";\n \"data-count\": string;\n}\n\n/** item → Button 的档位映射结果(size 固定 l)。 */\nexport interface TabBarItemButtonProps {\n variant: \"solid\" | \"soft\";\n tone: \"brand\" | \"neutral\";\n size: \"l\";\n disabled: boolean;\n loading: boolean;\n}\n\n/** 将公开输入归一化为唯一的跨框架状态;items 缺省/空 → 不可见。 */\nexport function resolveTabBarState(props: QwTabBarProps = {}): ResolvedTabBarState {\n const items = (props.items ?? []).map((item) => ({\n text: item.text,\n variant: item.variant ?? \"primary\",\n tone: item.tone ?? \"brand\",\n disabled: item.disabled ?? false,\n loading: item.loading ?? false,\n ...(item.onClick ? { onClick: item.onClick } : {}),\n }));\n return {\n visible: items.length > 0,\n count: items.length,\n items,\n };\n}\n\n/** 将归一化结果转成 root 属性。 */\nexport function getTabBarRootProps(state: ResolvedTabBarState): TabBarRootProps {\n return {\n \"data-scope\": \"tabbar\",\n \"data-part\": \"root\",\n \"data-count\": String(state.count),\n };\n}\n\n/** 将单个操作项映射为 Button props(档位收口,适配器不得覆盖)。 */\nexport function getTabBarItemButtonProps(item: ResolvedTabBarItemState): TabBarItemButtonProps {\n return {\n variant: item.variant === \"primary\" ? \"solid\" : \"soft\",\n tone: item.tone,\n size: \"l\",\n disabled: item.disabled,\n loading: item.loading,\n };\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,uBAAuB,CAAC,WAAW,WAAW;AAC3D,MAAa,oBAAoB,CAAC,SAAS,SAAS;AACpD,MAAa,eAAe,CAAC,MAAM;;AA8DnC,SAAgB,mBAAmB,QAAuB,CAAC,GAAwB;CACjF,MAAM,SAAS,MAAM,SAAS,CAAC,EAAA,CAAG,KAAK,UAAU;EAC/C,MAAM,KAAK;EACX,SAAS,KAAK,WAAW;EACzB,MAAM,KAAK,QAAQ;EACnB,UAAU,KAAK,YAAY;EAC3B,SAAS,KAAK,WAAW;EACzB,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;CAClD,EAAE;CACF,OAAO;EACL,SAAS,MAAM,SAAS;EACxB,OAAO,MAAM;EACb;CACF;AACF;;AAGA,SAAgB,mBAAmB,OAA6C;CAC9E,OAAO;EACL,cAAc;EACd,aAAa;EACb,cAAc,OAAO,MAAM,KAAK;CAClC;AACF;;AAGA,SAAgB,yBAAyB,MAAsD;CAC7F,OAAO;EACL,SAAS,KAAK,YAAY,YAAY,UAAU;EAChD,MAAM,KAAK;EACX,MAAM;EACN,UAAU,KAAK;EACf,SAAS,KAAK;CAChB;AACF"}
|