@neut/ui 0.0.13 → 0.0.15
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/dist/components/calendar/Calendar/Calendar.js +11 -8
- package/dist/components/calendar/Calendar/Calendar.js.map +1 -1
- package/dist/components/combobox/ComboboxInput/ComboboxInput.js +1 -1
- package/dist/components/combobox/ComboboxInput/ComboboxInput.js.map +1 -1
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.context.d.ts +41 -3
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.context.js +35 -7
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.context.js.map +1 -1
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.d.ts +23 -2
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.js +53 -33
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.js.map +1 -1
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.styles.d.ts +8 -0
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.styles.js +7 -0
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.styles.js.map +1 -0
- package/dist/components/toggle-group/ToggleGroup/ToggleGroup.types.d.ts +125 -19
- package/dist/components/toggle-group/ToggleGroup/create-change-event-details.d.ts +8 -0
- package/dist/components/toggle-group/ToggleGroup/create-change-event-details.js +25 -0
- package/dist/components/toggle-group/ToggleGroup/create-change-event-details.js.map +1 -0
- package/dist/components/toggle-group/ToggleGroup/index.d.ts +1 -1
- package/dist/components/toggle-group/ToggleGroup/useToggleGroupKeyboard.d.ts +17 -0
- package/dist/components/toggle-group/ToggleGroup/useToggleGroupKeyboard.js +47 -0
- package/dist/components/toggle-group/ToggleGroup/useToggleGroupKeyboard.js.map +1 -0
- package/dist/components/toggle-group/ToggleGroupItem/ToggleGroupItem.d.ts +9 -1
- package/dist/components/toggle-group/ToggleGroupItem/ToggleGroupItem.js +58 -42
- package/dist/components/toggle-group/ToggleGroupItem/ToggleGroupItem.js.map +1 -1
- package/dist/components/toggle-group/ToggleGroupItem/ToggleGroupItem.styles.d.ts +12 -0
- package/dist/components/toggle-group/ToggleGroupItem/ToggleGroupItem.styles.js +7 -0
- package/dist/components/toggle-group/ToggleGroupItem/ToggleGroupItem.styles.js.map +1 -0
- package/dist/components/toggle-group/ToggleGroupItem/ToggleGroupItem.types.d.ts +21 -7
- package/dist/components/toggle-group/call-event-handler.d.ts +5 -0
- package/dist/components/toggle-group/call-event-handler.js +9 -0
- package/dist/components/toggle-group/call-event-handler.js.map +1 -0
- package/dist/components/toggle-group/index.d.ts +1 -1
- package/dist/ui.css +1 -1
- package/package.json +1 -1
|
@@ -1,28 +1,134 @@
|
|
|
1
|
-
import { Accessor, ParentProps } from 'solid-js';
|
|
2
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { Accessor } from 'solid-js';
|
|
3
3
|
import { toggleVariants } from '../../toggle/Toggle/Toggle.styles';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
import { BaseProps, PolymorphicProps } from '../../../types';
|
|
5
|
+
/**
|
|
6
|
+
* ToggleGroup / ToggleGroupItem 的值类型(与 `TabsValue` 保持一致,支持 string 与 number)。
|
|
7
|
+
* 组件通过泛型参数收窄到具体字面量联合类型,例如 `"bold" | "italic"` 或 `1 | 2`。
|
|
8
|
+
*/
|
|
9
|
+
export type ToggleGroupValue = string | number;
|
|
10
|
+
/** item 的 variant / size 取值直接取自 toggleVariants,避免多处维护 */
|
|
11
|
+
export type ToggleGroupVariant = NonNullable<VariantProps<typeof toggleVariants>["variant"]>;
|
|
12
|
+
export type ToggleGroupSize = NonNullable<VariantProps<typeof toggleVariants>["size"]>;
|
|
13
|
+
export type ToggleGroupOrientation = "horizontal" | "vertical";
|
|
14
|
+
/** 对齐 base-ui:ToggleGroup 的 change reason 目前只有 "none" */
|
|
15
|
+
export type ToggleGroupChangeEventReason = "none";
|
|
16
|
+
/**
|
|
17
|
+
* onValueChange 的第二个参数,语义对齐 base-ui 的 `ToggleGroup.ChangeEventDetails`。
|
|
18
|
+
*
|
|
19
|
+
* - `cancel()`:阻止组件提交本次变更(受控模式下状态由外部决定,组件本就不提交)
|
|
20
|
+
* - `allowPropagation()`:API 对齐保留;本实现不主动阻止事件传播,因此是空操作
|
|
21
|
+
*/
|
|
22
|
+
export interface ToggleGroupChangeEventDetails {
|
|
23
|
+
reason: ToggleGroupChangeEventReason;
|
|
24
|
+
event: Event;
|
|
25
|
+
cancel: () => void;
|
|
26
|
+
allowPropagation: () => void;
|
|
27
|
+
readonly isCanceled: boolean;
|
|
28
|
+
readonly isPropagationAllowed: boolean;
|
|
29
|
+
trigger: Element | undefined;
|
|
30
|
+
}
|
|
31
|
+
/** 单选与多选共用的 props */
|
|
32
|
+
interface ToggleGroupCommonProps extends BaseProps {
|
|
33
|
+
/** 整组禁用,item 会继承该状态 */
|
|
12
34
|
disabled?: boolean;
|
|
13
|
-
|
|
14
|
-
|
|
35
|
+
/** 布局方向,默认 "horizontal";同时决定方向键映射与排列方向 */
|
|
36
|
+
orientation?: ToggleGroupOrientation;
|
|
37
|
+
/** 方向键到达边界时是否循环回另一端,默认 true */
|
|
38
|
+
loopFocus?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* item 之间的间距,通过根元素上的 `--gap` 变量实现,默认 2(对齐 shadcn)。
|
|
41
|
+
* 传 0 时相邻 item 拼接为一个整体(仅首尾保留圆角与边框)。
|
|
42
|
+
*/
|
|
15
43
|
spacing?: number;
|
|
16
|
-
|
|
17
|
-
|
|
44
|
+
/** 组级 variant,item 未单独指定时继承 */
|
|
45
|
+
variant?: ToggleGroupVariant;
|
|
46
|
+
/** 组级 size,item 未单独指定时继承 */
|
|
47
|
+
size?: ToggleGroupSize;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 单选模式(默认):`value` / `defaultValue` / `onValueChange` 都是**标量**。
|
|
51
|
+
*
|
|
52
|
+
* 这是本项目对 base-ui 的一处有意偏离 —— base-ui 单选时也要求传数组,用起来别扭。
|
|
53
|
+
* 取消选中时回调收到 `undefined`。
|
|
54
|
+
*
|
|
55
|
+
* 注意:`value === undefined` 视为非受控,所以受控的单选组请让信号有确定值
|
|
56
|
+
* (信号类型建议 `TValue | undefined`,并在传参前用 `??` 兜底,或改用多选数组模式)。
|
|
57
|
+
*/
|
|
58
|
+
export interface ToggleGroupSingleProps<TValue extends ToggleGroupValue = ToggleGroupValue> extends ToggleGroupCommonProps {
|
|
59
|
+
/** 单选模式标记(默认),不需要显式传 */
|
|
60
|
+
multiple?: false;
|
|
61
|
+
/** 受控选中值;不传则内部自管理 */
|
|
62
|
+
value?: TValue;
|
|
63
|
+
/** 非受控模式下的初始选中值 */
|
|
64
|
+
defaultValue?: TValue;
|
|
65
|
+
/** 选中值变化回调(受控与非受控都会触发) */
|
|
66
|
+
onValueChange?: (value: TValue | undefined, eventDetails: ToggleGroupChangeEventDetails) => void;
|
|
67
|
+
}
|
|
68
|
+
/** 多选模式(`multiple`):值是数组,未选中时为空数组 */
|
|
69
|
+
export interface ToggleGroupMultipleProps<TValue extends ToggleGroupValue = ToggleGroupValue> extends ToggleGroupCommonProps {
|
|
70
|
+
/** 多选模式标记 */
|
|
71
|
+
multiple: true;
|
|
72
|
+
/** 受控选中值;不传则内部自管理 */
|
|
73
|
+
value?: readonly TValue[];
|
|
74
|
+
/** 非受控模式下的初始选中值 */
|
|
75
|
+
defaultValue?: readonly TValue[];
|
|
76
|
+
/** 选中值变化回调(受控与非受控都会触发) */
|
|
77
|
+
onValueChange?: (value: TValue[], eventDetails: ToggleGroupChangeEventDetails) => void;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 值类型由泛型参数决定:
|
|
81
|
+
* - 不传时是宽类型 `ToggleGroupValue`(string | number)
|
|
82
|
+
* - `defaultValue` / `value` / `onValueChange` 中任意一处给出具体类型即可推导,
|
|
83
|
+
* 例如 `defaultValue={1}` 会推导出 `number`
|
|
84
|
+
* - 也可显式指定:`<ToggleGroup<"bold" | "italic"> />`
|
|
85
|
+
*
|
|
86
|
+
* `multiple` 决定值的形状:单选是标量,多选是数组(传错会被类型拦住)。
|
|
87
|
+
*/
|
|
88
|
+
export type ToggleGroupProps<TValue extends ToggleGroupValue = ToggleGroupValue> = PolymorphicProps<"div", ToggleGroupSingleProps<TValue> | ToggleGroupMultipleProps<TValue>, false>;
|
|
89
|
+
/** 两种模式下 onValueChange 的联合类型(供内部状态实现使用) */
|
|
90
|
+
export type ToggleGroupChangeHandler<TValue extends ToggleGroupValue> = NonNullable<ToggleGroupSingleProps<TValue>["onValueChange"]> | NonNullable<ToggleGroupMultipleProps<TValue>["onValueChange"]>;
|
|
91
|
+
/** 已注册的 item,供 roving focus 与键盘导航使用 */
|
|
92
|
+
export interface ToggleGroupItemEntry<TValue extends ToggleGroupValue = ToggleGroupValue> {
|
|
93
|
+
value: TValue;
|
|
94
|
+
element: HTMLElement;
|
|
95
|
+
/** accessor,支持运行时 disabled 翻转 */
|
|
96
|
+
disabled: () => boolean;
|
|
18
97
|
}
|
|
19
|
-
export interface ToggleGroupContextValue {
|
|
20
|
-
|
|
21
|
-
|
|
98
|
+
export interface ToggleGroupContextValue<TValue extends ToggleGroupValue = ToggleGroupValue> {
|
|
99
|
+
/**
|
|
100
|
+
* 当前选中值,**已规范化成数组**:单选模式是 0 或 1 个元素。
|
|
101
|
+
* 判断某个 item 是否选中请用 `isPressed`。
|
|
102
|
+
*/
|
|
103
|
+
value: Accessor<readonly TValue[]>;
|
|
22
104
|
multiple: Accessor<boolean>;
|
|
23
105
|
disabled: Accessor<boolean>;
|
|
24
|
-
orientation: Accessor<
|
|
106
|
+
orientation: Accessor<ToggleGroupOrientation>;
|
|
107
|
+
loopFocus: Accessor<boolean>;
|
|
108
|
+
dir: Accessor<"ltr" | "rtl" | "auto" | undefined>;
|
|
25
109
|
spacing: Accessor<number>;
|
|
26
|
-
variant
|
|
27
|
-
|
|
110
|
+
/** 组级 variant / size;未显式指定时为 undefined,便于 item 单独覆盖 */
|
|
111
|
+
variant: Accessor<ToggleGroupVariant | undefined>;
|
|
112
|
+
size: Accessor<ToggleGroupSize | undefined>;
|
|
113
|
+
/** 当前焦点高亮的 item(roving focus 的 tabindex 起点) */
|
|
114
|
+
highlightedValue: Accessor<TValue | undefined>;
|
|
115
|
+
/**
|
|
116
|
+
* 以下带值参数的方法用 method 简写声明:方法参数是双变的,
|
|
117
|
+
* 因此 `ToggleGroupContextValue<number>` 仍可赋给 `ToggleGroupContextValue<string | number>`
|
|
118
|
+
* (Provider 的 value 类型是宽类型,不能用函数属性写法,否则逆变会报错)。
|
|
119
|
+
*/
|
|
120
|
+
/** 该 value 当前是否处于按下状态 */
|
|
121
|
+
isPressed(value: TValue): boolean;
|
|
122
|
+
/** 切换某个 item 的按下状态,并按模式派发 onValueChange */
|
|
123
|
+
toggleItem(value: TValue, event: Event, trigger?: Element): void;
|
|
124
|
+
setHighlightedValue(value: TValue): void;
|
|
125
|
+
/** 按挂载顺序注册 item,返回注销函数 */
|
|
126
|
+
registerItem(entry: ToggleGroupItemEntry<TValue>): () => void;
|
|
127
|
+
/** 已注册的 item 列表(挂载顺序) */
|
|
128
|
+
getItems(): ToggleGroupItemEntry<TValue>[];
|
|
129
|
+
/** 高亮缺失时,该 value 是否为第一个可用 item(tabindex 起点) */
|
|
130
|
+
isFirstEnabled(value: TValue): boolean;
|
|
131
|
+
/** 该 value 对应的 item 当前是否可用(已注册且未 disabled) */
|
|
132
|
+
isUsable(value: TValue): boolean;
|
|
28
133
|
}
|
|
134
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ToggleGroupChangeEventDetails } from './ToggleGroup.types';
|
|
2
|
+
/**
|
|
3
|
+
* 构造 onValueChange 的事件详情(对齐 base-ui 的 `ChangeEventDetails`)。
|
|
4
|
+
*
|
|
5
|
+
* `isCanceled` / `isPropagationAllowed` 用 getter 暴露:回调内部可以即时读到
|
|
6
|
+
* `cancel()` / `allowPropagation()` 之后的最新值,而不是创建时的快照。
|
|
7
|
+
*/
|
|
8
|
+
export declare function createChangeEventDetails(event: Event, trigger?: Element): ToggleGroupChangeEventDetails;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/components/toggle-group/ToggleGroup/create-change-event-details.ts
|
|
2
|
+
function e(e, t) {
|
|
3
|
+
let n = !1, r = !1;
|
|
4
|
+
return {
|
|
5
|
+
reason: "none",
|
|
6
|
+
event: e,
|
|
7
|
+
trigger: t,
|
|
8
|
+
cancel: () => {
|
|
9
|
+
n = !0;
|
|
10
|
+
},
|
|
11
|
+
allowPropagation: () => {
|
|
12
|
+
r = !0;
|
|
13
|
+
},
|
|
14
|
+
get isCanceled() {
|
|
15
|
+
return n;
|
|
16
|
+
},
|
|
17
|
+
get isPropagationAllowed() {
|
|
18
|
+
return r;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { e as createChangeEventDetails };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=create-change-event-details.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-change-event-details.js","names":[],"sources":["../../../../src/components/toggle-group/ToggleGroup/create-change-event-details.ts"],"sourcesContent":["import type { ToggleGroupChangeEventDetails } from \"./ToggleGroup.types\";\n\n/**\n * 构造 onValueChange 的事件详情(对齐 base-ui 的 `ChangeEventDetails`)。\n *\n * `isCanceled` / `isPropagationAllowed` 用 getter 暴露:回调内部可以即时读到\n * `cancel()` / `allowPropagation()` 之后的最新值,而不是创建时的快照。\n */\nexport function createChangeEventDetails(\n event: Event,\n trigger?: Element,\n): ToggleGroupChangeEventDetails {\n let canceled = false;\n let propagationAllowed = false;\n\n return {\n reason: \"none\",\n event,\n trigger,\n cancel: () => {\n canceled = true;\n },\n allowPropagation: () => {\n propagationAllowed = true;\n },\n get isCanceled() {\n return canceled;\n },\n get isPropagationAllowed() {\n return propagationAllowed;\n },\n };\n}\n"],"mappings":";AAQA,SAAgB,EACd,GACA,GAC+B;CAC/B,IAAI,IAAW,IACX,IAAqB;CAEzB,OAAO;EACL,QAAQ;EACR;EACA;EACA,cAAc;GACZ,IAAW;EACb;EACA,wBAAwB;GACtB,IAAqB;EACvB;EACA,IAAI,aAAa;GACf,OAAO;EACT;EACA,IAAI,uBAAuB;GACzB,OAAO;EACT;CACF;AACF"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { ToggleGroup } from './ToggleGroup';
|
|
2
2
|
export { ToggleGroupContext, useToggleGroupContext, } from './ToggleGroup.context';
|
|
3
|
-
export type { ToggleGroupProps, ToggleGroupContextValue, } from './ToggleGroup.types';
|
|
3
|
+
export type { ToggleGroupProps, ToggleGroupSingleProps, ToggleGroupMultipleProps, ToggleGroupValue, ToggleGroupContextValue, ToggleGroupItemEntry, ToggleGroupOrientation, ToggleGroupVariant, ToggleGroupSize, ToggleGroupChangeEventDetails, ToggleGroupChangeEventReason, } from './ToggleGroup.types';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ToggleGroupContextValue, ToggleGroupValue } from './ToggleGroup.types';
|
|
2
|
+
/**
|
|
3
|
+
* ToggleGroup 的 roving focus 键盘导航(纯逻辑,可独立单测)。
|
|
4
|
+
*
|
|
5
|
+
* 方向映射:
|
|
6
|
+
* - horizontal + ltr: ArrowRight → next, ArrowLeft → prev
|
|
7
|
+
* - horizontal + rtl: 左右反转
|
|
8
|
+
* - vertical: ArrowDown → next, ArrowUp → prev
|
|
9
|
+
* - Home → 第一个,End → 最后一个
|
|
10
|
+
* - loopFocus=true 环绕,false 边界停止;跳过 disabled 的 item
|
|
11
|
+
*
|
|
12
|
+
* 只有焦点已经在某个 item 上时才接管按键,避免影响外部其它元素;
|
|
13
|
+
* 移动焦点后由 item 的 onFocus 更新高亮。
|
|
14
|
+
*/
|
|
15
|
+
export declare function useToggleGroupKeyboard<TValue extends ToggleGroupValue = ToggleGroupValue>(ctx: ToggleGroupContextValue<TValue>): {
|
|
16
|
+
handleKeyDown: (e: KeyboardEvent) => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region src/components/toggle-group/ToggleGroup/useToggleGroupKeyboard.ts
|
|
2
|
+
var e = /* @__PURE__ */ new Set([
|
|
3
|
+
"ArrowLeft",
|
|
4
|
+
"ArrowRight",
|
|
5
|
+
"ArrowUp",
|
|
6
|
+
"ArrowDown",
|
|
7
|
+
"Home",
|
|
8
|
+
"End"
|
|
9
|
+
]);
|
|
10
|
+
function t(t) {
|
|
11
|
+
return { handleKeyDown: (n) => {
|
|
12
|
+
if (t.disabled() || !e.has(n.key)) return;
|
|
13
|
+
let r = document.activeElement, i = t.getItems().filter((e) => !e.disabled());
|
|
14
|
+
if (i.length === 0) return;
|
|
15
|
+
let a = i.findIndex((e) => e.element === r);
|
|
16
|
+
if (a === -1) return;
|
|
17
|
+
let o = t.orientation() === "vertical", s = t.dir(), c = s === "rtl" || s !== "ltr" && typeof document < "u" && getComputedStyle(n.currentTarget).direction === "rtl", l;
|
|
18
|
+
switch (n.key) {
|
|
19
|
+
case "Home":
|
|
20
|
+
l = 0;
|
|
21
|
+
break;
|
|
22
|
+
case "End":
|
|
23
|
+
l = i.length - 1;
|
|
24
|
+
break;
|
|
25
|
+
case "ArrowLeft":
|
|
26
|
+
if (o) return;
|
|
27
|
+
l = a + (c ? 1 : -1);
|
|
28
|
+
break;
|
|
29
|
+
case "ArrowRight":
|
|
30
|
+
if (o) return;
|
|
31
|
+
l = a + (c ? -1 : 1);
|
|
32
|
+
break;
|
|
33
|
+
case "ArrowUp":
|
|
34
|
+
if (!o) return;
|
|
35
|
+
l = a - 1;
|
|
36
|
+
break;
|
|
37
|
+
case "ArrowDown":
|
|
38
|
+
if (!o) return;
|
|
39
|
+
l = a + 1;
|
|
40
|
+
}
|
|
41
|
+
l !== void 0 && (n.preventDefault(), l = t.loopFocus() ? (l + i.length) % i.length : Math.min(i.length - 1, Math.max(0, l)), i[l].element.focus(), t.setHighlightedValue(i[l].value));
|
|
42
|
+
} };
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { t as useToggleGroupKeyboard };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=useToggleGroupKeyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useToggleGroupKeyboard.js","names":[],"sources":["../../../../src/components/toggle-group/ToggleGroup/useToggleGroupKeyboard.ts"],"sourcesContent":["import type {\n ToggleGroupContextValue,\n ToggleGroupValue,\n} from \"./ToggleGroup.types\";\n\n/** 键盘导航按键:方向键 + Home/End(对齐 base-ui CompositeRoot 的 enableHomeAndEndKeys) */\nconst NAV_KEYS = new Set([\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"Home\",\n \"End\",\n]);\n\n/**\n * ToggleGroup 的 roving focus 键盘导航(纯逻辑,可独立单测)。\n *\n * 方向映射:\n * - horizontal + ltr: ArrowRight → next, ArrowLeft → prev\n * - horizontal + rtl: 左右反转\n * - vertical: ArrowDown → next, ArrowUp → prev\n * - Home → 第一个,End → 最后一个\n * - loopFocus=true 环绕,false 边界停止;跳过 disabled 的 item\n *\n * 只有焦点已经在某个 item 上时才接管按键,避免影响外部其它元素;\n * 移动焦点后由 item 的 onFocus 更新高亮。\n */\nexport function useToggleGroupKeyboard<\n TValue extends ToggleGroupValue = ToggleGroupValue,\n>(ctx: ToggleGroupContextValue<TValue>) {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (ctx.disabled()) return;\n if (!NAV_KEYS.has(e.key)) return;\n\n const activeEl = document.activeElement as HTMLElement | null;\n const items = ctx.getItems().filter((item) => !item.disabled());\n if (items.length === 0) return;\n\n const currentIndex = items.findIndex((item) => item.element === activeEl);\n if (currentIndex === -1) return;\n\n const isVertical = ctx.orientation() === \"vertical\";\n // dir 未指定/auto 时,按根元素的实际书写方向判断(兼容祖先节点上的 dir)\n const dir = ctx.dir();\n const isRTL =\n dir === \"rtl\" ||\n (dir !== \"ltr\" &&\n typeof document !== \"undefined\" &&\n getComputedStyle(e.currentTarget as Element).direction === \"rtl\");\n\n let nextIndex: number | undefined;\n switch (e.key) {\n case \"Home\":\n nextIndex = 0;\n break;\n case \"End\":\n nextIndex = items.length - 1;\n break;\n case \"ArrowLeft\":\n if (isVertical) return;\n nextIndex = currentIndex + (isRTL ? 1 : -1);\n break;\n case \"ArrowRight\":\n if (isVertical) return;\n nextIndex = currentIndex + (isRTL ? -1 : 1);\n break;\n case \"ArrowUp\":\n if (!isVertical) return;\n nextIndex = currentIndex - 1;\n break;\n case \"ArrowDown\":\n if (!isVertical) return;\n nextIndex = currentIndex + 1;\n break;\n }\n\n if (nextIndex === undefined) return;\n\n // 方向键与当前布局匹配,接管默认滚动行为\n e.preventDefault();\n\n if (ctx.loopFocus()) {\n nextIndex = (nextIndex + items.length) % items.length;\n } else {\n nextIndex = Math.min(items.length - 1, Math.max(0, nextIndex));\n }\n\n items[nextIndex].element.focus();\n ctx.setHighlightedValue(items[nextIndex].value);\n };\n\n return { handleKeyDown };\n}\n"],"mappings":";AAMA,IAAM,oBAAW,IAAI,IAAI;CACvB;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAeD,SAAgB,EAEd,GAAsC;CA8DtC,OAAO,EAAE,gBA7Dc,MAAqB;EAE1C,IADI,EAAI,SAAS,KACb,CAAC,EAAS,IAAI,EAAE,GAAG,GAAG;EAE1B,IAAM,IAAW,SAAS,eACpB,IAAQ,EAAI,SAAS,CAAC,CAAC,QAAQ,MAAS,CAAC,EAAK,SAAS,CAAC;EAC9D,IAAI,EAAM,WAAW,GAAG;EAExB,IAAM,IAAe,EAAM,WAAW,MAAS,EAAK,YAAY,CAAQ;EACxE,IAAI,MAAiB,IAAI;EAEzB,IAAM,IAAa,EAAI,YAAY,MAAM,YAEnC,IAAM,EAAI,IAAI,GACd,IACJ,MAAQ,SACP,MAAQ,SACP,OAAO,WAAa,OACpB,iBAAiB,EAAE,aAAwB,CAAC,CAAC,cAAc,OAE3D;EACJ,QAAQ,EAAE,KAAV;GACE,KAAK;IACH,IAAY;IACZ;GACF,KAAK;IACH,IAAY,EAAM,SAAS;IAC3B;GACF,KAAK;IACH,IAAI,GAAY;IAChB,IAAY,KAAgB,IAAQ,IAAI;IACxC;GACF,KAAK;IACH,IAAI,GAAY;IAChB,IAAY,KAAgB,IAAQ,KAAK;IACzC;GACF,KAAK;IACH,IAAI,CAAC,GAAY;IACjB,IAAY,IAAe;IAC3B;GACF,KAAK;IACH,IAAI,CAAC,GAAY;IACjB,IAAY,IAAe;EAE/B;EAEI,MAAc,KAAA,MAGlB,EAAE,eAAe,GAEjB,AAGE,IAHE,EAAI,UAAU,KACH,IAAY,EAAM,UAAU,EAAM,SAEnC,KAAK,IAAI,EAAM,SAAS,GAAG,KAAK,IAAI,GAAG,CAAS,CAAC,GAG/D,EAAM,EAAU,CAAC,QAAQ,MAAM,GAC/B,EAAI,oBAAoB,EAAM,EAAU,CAAC,KAAK;CAChD,EAEuB;AACzB"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import { JSX } from 'solid-js';
|
|
2
|
+
import { ToggleGroupValue } from '../ToggleGroup/ToggleGroup.types';
|
|
2
3
|
import { ToggleGroupItemProps } from './ToggleGroupItem.types';
|
|
3
|
-
|
|
4
|
+
/**
|
|
5
|
+
* ToggleGroupItem:ToggleGroup 内的两态按钮。
|
|
6
|
+
*
|
|
7
|
+
* - 选中值由 ToggleGroup 统一持有,点击通过 `ctx.toggleItem` 触发变更
|
|
8
|
+
* - disabled 继承整组状态,可在 item 上单独禁用
|
|
9
|
+
* - roving tabindex:整组只有一个 tab 停靠点,方向键在同组内移动焦点
|
|
10
|
+
*/
|
|
11
|
+
export declare function ToggleGroupItem<TValue extends ToggleGroupValue = ToggleGroupValue>(props: ToggleGroupItemProps<TValue>): JSX.Element;
|
|
@@ -1,72 +1,88 @@
|
|
|
1
1
|
import { clsx as e } from "../../../utils/clsx.js";
|
|
2
2
|
import { toggleVariants as t } from "../../toggle/Toggle/Toggle.styles.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { callEventHandler as n } from "../call-event-handler.js";
|
|
4
|
+
import { useToggleGroupContext as r } from "../ToggleGroup/ToggleGroup.context.js";
|
|
5
|
+
import { toggleGroupItemVariants as i } from "./ToggleGroupItem.styles.js";
|
|
6
|
+
import { delegateEvents as a, insert as o, mergeProps as s, spread as c, template as l, use as u } from "solid-js/web";
|
|
7
|
+
import { mergeProps as d, onCleanup as f, onMount as p, splitProps as m } from "solid-js";
|
|
6
8
|
//#region src/components/toggle-group/ToggleGroupItem/ToggleGroupItem.tsx
|
|
7
|
-
var
|
|
8
|
-
function
|
|
9
|
-
let
|
|
9
|
+
var h = /*#__PURE__*/ l("<button data-slot=toggle-group-item>");
|
|
10
|
+
function g(a) {
|
|
11
|
+
let l = r("ToggleGroupItem"), g = d({ type: "button" }, a), [_, v] = m(g, [
|
|
10
12
|
"value",
|
|
11
13
|
"variant",
|
|
12
14
|
"size",
|
|
13
15
|
"class",
|
|
16
|
+
"classList",
|
|
14
17
|
"disabled",
|
|
18
|
+
"type",
|
|
15
19
|
"onClick",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
]),
|
|
19
|
-
if (
|
|
20
|
-
let e =
|
|
21
|
-
|
|
22
|
-
}, v = (e) => {
|
|
23
|
-
if (d.onKeyDown?.(e), e.defaultPrevented || g() || ![
|
|
24
|
-
"ArrowDown",
|
|
25
|
-
"ArrowRight",
|
|
26
|
-
"ArrowUp",
|
|
27
|
-
"ArrowLeft"
|
|
28
|
-
].includes(e.key)) return;
|
|
29
|
-
e.preventDefault();
|
|
30
|
-
let t = e.currentTarget.closest("[data-slot=\"toggle-group\"]"), n = Array.from(t?.querySelectorAll("[data-slot=\"toggle-group-item\"]") ?? []);
|
|
31
|
-
n.length !== 0 && n[(n.indexOf(e.currentTarget) + (e.key === "ArrowDown" || e.key === "ArrowRight" ? 1 : -1) + n.length) % n.length].focus();
|
|
20
|
+
"onFocus",
|
|
21
|
+
"children"
|
|
22
|
+
]), y, b = () => l.variant() ?? _.variant ?? "default", x = () => l.size() ?? _.size ?? "default", S = () => l.isPressed(_.value), C = () => l.disabled() || !!_.disabled, w = () => {
|
|
23
|
+
if (C()) return -1;
|
|
24
|
+
let e = l.highlightedValue();
|
|
25
|
+
return e === _.value && l.isUsable(_.value) || (e === void 0 || !l.isUsable(e)) && l.isFirstEnabled(_.value) ? 0 : -1;
|
|
32
26
|
};
|
|
33
|
-
return (() => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
return p(() => {
|
|
28
|
+
f(l.registerItem({
|
|
29
|
+
value: _.value,
|
|
30
|
+
disabled: C,
|
|
31
|
+
element: y
|
|
32
|
+
}));
|
|
33
|
+
}), (() => {
|
|
34
|
+
var r = h();
|
|
35
|
+
return r.addEventListener("focus", (e) => {
|
|
36
|
+
C() || l.setHighlightedValue(_.value), n(_.onFocus, e);
|
|
37
|
+
}), r.$$click = (e) => {
|
|
38
|
+
n(_.onClick, e), !e.defaultPrevented && !C() && l.toggleItem(_.value, e, e.currentTarget);
|
|
39
|
+
}, u((e) => {
|
|
40
|
+
y = e;
|
|
41
|
+
}, r), c(r, s({
|
|
38
42
|
get type() {
|
|
39
|
-
return
|
|
43
|
+
return _.type;
|
|
40
44
|
},
|
|
41
45
|
get disabled() {
|
|
42
|
-
return
|
|
46
|
+
return C();
|
|
47
|
+
},
|
|
48
|
+
get tabindex() {
|
|
49
|
+
return w();
|
|
43
50
|
},
|
|
44
51
|
get "data-variant"() {
|
|
45
|
-
return
|
|
52
|
+
return b();
|
|
46
53
|
},
|
|
47
54
|
get "data-size"() {
|
|
48
|
-
return
|
|
55
|
+
return x();
|
|
49
56
|
},
|
|
50
57
|
get "data-spacing"() {
|
|
51
|
-
return
|
|
58
|
+
return l.spacing();
|
|
52
59
|
},
|
|
53
|
-
get "
|
|
54
|
-
return
|
|
60
|
+
get "data-pressed"() {
|
|
61
|
+
return S() ? "" : null;
|
|
62
|
+
},
|
|
63
|
+
get "data-disabled"() {
|
|
64
|
+
return C() ? "" : null;
|
|
55
65
|
},
|
|
56
66
|
get "data-state"() {
|
|
57
|
-
return
|
|
67
|
+
return S() ? "on" : "off";
|
|
68
|
+
},
|
|
69
|
+
get "aria-pressed"() {
|
|
70
|
+
return S();
|
|
58
71
|
},
|
|
59
72
|
get class() {
|
|
60
|
-
return e(
|
|
61
|
-
variant:
|
|
62
|
-
size:
|
|
63
|
-
}),
|
|
73
|
+
return e(t({
|
|
74
|
+
variant: b(),
|
|
75
|
+
size: x()
|
|
76
|
+
}), i(), _.class);
|
|
77
|
+
},
|
|
78
|
+
get classList() {
|
|
79
|
+
return _.classList;
|
|
64
80
|
}
|
|
65
|
-
},
|
|
81
|
+
}, v), !1, !0), o(r, () => _.children), r;
|
|
66
82
|
})();
|
|
67
83
|
}
|
|
68
|
-
|
|
84
|
+
a(["click"]);
|
|
69
85
|
//#endregion
|
|
70
|
-
export {
|
|
86
|
+
export { g as ToggleGroupItem };
|
|
71
87
|
|
|
72
88
|
//# sourceMappingURL=ToggleGroupItem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroupItem.js","names":["
|
|
1
|
+
{"version":3,"file":"ToggleGroupItem.js","names":["mergeProps","onCleanup","onMount","splitProps","JSX","clsx","toggleVariants","callEventHandler","useToggleGroupContext","ToggleGroupValue","toggleGroupItemVariants","ToggleGroupItemProps","ToggleGroupItem","props","TValue","Element","ctx","merged","type","const","local","rest","elementRef","HTMLButtonElement","variant","size","pressed","isPressed","value","disabled","tabIndex","highlighted","highlightedValue","isUsable","undefined","isFirstEnabled","registerItem","element","_el$","_tmpl$","addEventListener","e","setHighlightedValue","onFocus","$$click","onClick","defaultPrevented","toggleItem","currentTarget","_$use","el","_$spread","_$mergeProps","tabindex","data-variant","data-size","data-spacing","spacing","data-pressed","data-disabled","data-state","aria-pressed","class","classList","_$insert","children","_$delegateEvents"],"sources":["../../../../src/components/toggle-group/ToggleGroupItem/ToggleGroupItem.tsx"],"sourcesContent":["import { mergeProps, onCleanup, onMount, splitProps, type JSX } from \"solid-js\";\nimport { clsx } from \"~/utils\";\nimport { toggleVariants } from \"~/components/toggle/Toggle/Toggle.styles\";\nimport { callEventHandler } from \"../call-event-handler\";\nimport { useToggleGroupContext } from \"../ToggleGroup/ToggleGroup.context\";\nimport type { ToggleGroupValue } from \"../ToggleGroup/ToggleGroup.types\";\nimport { toggleGroupItemVariants } from \"./ToggleGroupItem.styles\";\nimport type { ToggleGroupItemProps } from \"./ToggleGroupItem.types\";\n\n/**\n * ToggleGroupItem:ToggleGroup 内的两态按钮。\n *\n * - 选中值由 ToggleGroup 统一持有,点击通过 `ctx.toggleItem` 触发变更\n * - disabled 继承整组状态,可在 item 上单独禁用\n * - roving tabindex:整组只有一个 tab 停靠点,方向键在同组内移动焦点\n */\nexport function ToggleGroupItem<\n TValue extends ToggleGroupValue = ToggleGroupValue,\n>(props: ToggleGroupItemProps<TValue>): JSX.Element {\n // context 用宽值类型读取:item 无法从父级推导 group 的值类型,\n // 自己的 TValue 始终可以传给宽类型参数\n const ctx = useToggleGroupContext(\"ToggleGroupItem\");\n const merged = mergeProps({ type: \"button\" as const }, props);\n\n const [local, rest] = splitProps(merged, [\n \"value\",\n \"variant\",\n \"size\",\n \"class\",\n \"classList\",\n \"disabled\",\n \"type\",\n \"onClick\",\n \"onFocus\",\n \"children\",\n ]);\n\n let elementRef: HTMLButtonElement | undefined;\n\n // 组级未显式指定 variant/size 时,item 可单独覆盖\n const variant = () => ctx.variant() ?? local.variant ?? \"default\";\n const size = () => ctx.size() ?? local.size ?? \"default\";\n const pressed = () => ctx.isPressed(local.value);\n const disabled = () => ctx.disabled() || !!local.disabled;\n\n // roving tabindex:高亮 item 持 0;高亮缺失或指向不可用 item(disabled/卸载)时,\n // 首个可用 item 持 0 作为键盘起点,避免整组键盘不可达\n const tabIndex = () => {\n if (disabled()) return -1;\n const highlighted = ctx.highlightedValue();\n if (highlighted === local.value && ctx.isUsable(local.value)) return 0;\n if (\n (highlighted === undefined || !ctx.isUsable(highlighted)) &&\n ctx.isFirstEnabled(local.value)\n ) {\n return 0;\n }\n return -1;\n };\n\n onMount(() => {\n onCleanup(\n ctx.registerItem({\n value: local.value,\n disabled,\n element: elementRef!,\n }),\n );\n });\n\n return (\n <button\n ref={(el) => {\n elementRef = el;\n }}\n type={local.type}\n disabled={disabled()}\n tabindex={tabIndex()}\n data-slot=\"toggle-group-item\"\n data-variant={variant()}\n data-size={size()}\n data-spacing={ctx.spacing()}\n data-pressed={pressed() ? \"\" : null}\n data-disabled={disabled() ? \"\" : null}\n data-state={pressed() ? \"on\" : \"off\"}\n aria-pressed={pressed()}\n class={clsx(\n toggleVariants({ variant: variant(), size: size() }),\n toggleGroupItemVariants(),\n local.class,\n )}\n classList={local.classList}\n onClick={(e) => {\n // 用户回调优先,可用 preventDefault() 阻止本次选中\n callEventHandler(local.onClick, e);\n if (!e.defaultPrevented && !disabled()) {\n ctx.toggleItem(local.value, e, e.currentTarget);\n }\n }}\n onFocus={(e) => {\n // 聚焦更新高亮(roving focus 起点)\n if (!disabled()) ctx.setHighlightedValue(local.value);\n callEventHandler(local.onFocus, e);\n }}\n {...rest}\n >\n {local.children}\n </button>\n );\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAgBY,EAEdC,GAAkD;CAGlD,IAAMG,IAAMR,EAAsB,iBAAiB,GAC7CS,IAASjB,EAAW,EAAEkB,MAAM,SAAkB,GAAGL,CAAK,GAEtD,CAACO,GAAOC,KAAQlB,EAAWc,GAAQ;EACvC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAAU,CACX,GAEGK,GAGEE,UAAgBR,EAAIQ,QAAQ,KAAKJ,EAAMI,WAAW,WAClDC,UAAaT,EAAIS,KAAK,KAAKL,EAAMK,QAAQ,WACzCC,UAAgBV,EAAIW,UAAUP,EAAMQ,KAAK,GACzCC,UAAiBb,EAAIa,SAAS,KAAK,CAAC,CAACT,EAAMS,UAI3CC,UAAiB;EACrB,IAAID,EAAS,GAAG,OAAO;EACvB,IAAME,IAAcf,EAAIgB,iBAAiB;EAQzC,OAPID,MAAgBX,EAAMQ,SAASZ,EAAIiB,SAASb,EAAMQ,KAAK,MAExDG,MAAgBG,KAAAA,KAAa,CAAClB,EAAIiB,SAASF,CAAW,MACvDf,EAAImB,eAAef,EAAMQ,KAAK,IAEvB,IAEF;CACT;CAYA,OAVA1B,QAAc;EACZD,EACEe,EAAIoB,aAAa;GACfR,OAAOR,EAAMQ;GACbC;GACAQ,SAASf;EACX,CAAC,CACH;CACF,CAAC,UAED;EAAA,IAAAgB,IAAAC,EAAA;EAoCmB,OApCnBD,EAAAE,iBAAA,UA6BcC,MAAM;GAGdlC,AADKsB,EAAS,KAAGb,EAAI0B,oBAAoBtB,EAAMQ,KAAK,GACpDrB,EAAiBa,EAAMuB,SAASF,CAAC;EACnC,CAAC,GAAAH,EAAAM,WAXSH,MAAM;GAGd,AADAlC,EAAiBa,EAAMyB,SAASJ,CAAC,GAC7B,CAACA,EAAEK,oBAAoB,CAACjB,EAAS,KACnCb,EAAI+B,WAAW3B,EAAMQ,OAAOa,GAAGA,EAAEO,aAAa;EAElD,GAACC,GA1BKC,MAAO;GACX5B,IAAa4B;EACf,GAACZ,CAAA,GAAAa,EAAAb,GAAAc,EAAA;GAAA,IACDlC,OAAI;IAAA,OAAEE,EAAMF;GAAI;GAAA,IAChBW,WAAQ;IAAA,OAAEA,EAAS;GAAC;GAAA,IACpBwB,WAAQ;IAAA,OAAEvB,EAAS;GAAC;GAAA,IAAA,iBAAA;IAAA,OAENN,EAAQ;GAAC;GAAA,IAAA,cAAA;IAAA,OACZC,EAAK;GAAC;GAAA,IAAA,iBAAA;IAAA,OACHT,EAAIyC,QAAQ;GAAC;GAAA,IAAA,iBAAA;IAAA,OACb/B,EAAQ,IAAI,KAAK;GAAI;GAAA,IAAA,kBAAA;IAAA,OACpBG,EAAS,IAAI,KAAK;GAAI;GAAA,IAAA,eAAA;IAAA,OACzBH,EAAQ,IAAI,OAAO;GAAK;GAAA,IAAA,iBAAA;IAAA,OACtBA,EAAQ;GAAC;GAAA,IAAA,QAAA;IAAA,OAChBrB,EACLC,EAAe;KAAEkB,SAASA,EAAQ;KAAGC,MAAMA,EAAK;IAAE,CAAC,GACnDf,EAAwB,GACxBU,EAAM0C,KACR;GAAC;GAAA,IACDC,YAAS;IAAA,OAAE3C,EAAM2C;GAAS;EAAA,GAatB1C,CAAI,GAAA,IAAA,EAAA,GAAA2C,EAAA1B,SAEPlB,EAAM6C,QAAQ,GAAA3B;CAAA,EAAA,CAAA;AAGrB;AAAC4B,EAAA,CAAA,OAAA,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ToggleGroupItem 位于 ToggleGroup 内时需要的“拼接态”样式。
|
|
3
|
+
*
|
|
4
|
+
* 依赖根元素上的钩子:
|
|
5
|
+
* - `group-data-[spacing=0]/toggle-group`:spacing 为 0 时相邻 item 拼接为整体
|
|
6
|
+
* - `data-[spacing=0]`:item 自身的 data-spacing(shadcn 同样在 item 上输出)
|
|
7
|
+
* - `group-data-horizontal|vertical/toggle-group`:按方向决定首尾圆角/边框
|
|
8
|
+
* - `data-[variant=outline]`:outline 拼接时只保留内侧边框
|
|
9
|
+
*
|
|
10
|
+
* variant / size 的基础样式仍由 `toggleVariants` 提供,这里只补“组合关系”。
|
|
11
|
+
*/
|
|
12
|
+
export declare const toggleGroupItemVariants: (props?: import('class-variance-authority/types').ClassProp | undefined) => string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { cva as e } from "class-variance-authority";
|
|
2
|
+
//#region src/components/toggle-group/ToggleGroupItem/ToggleGroupItem.styles.ts
|
|
3
|
+
var t = e("shrink-0 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t");
|
|
4
|
+
//#endregion
|
|
5
|
+
export { t as toggleGroupItemVariants };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=ToggleGroupItem.styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleGroupItem.styles.js","names":[],"sources":["../../../../src/components/toggle-group/ToggleGroupItem/ToggleGroupItem.styles.ts"],"sourcesContent":["import { cva } from \"class-variance-authority\";\n\n/**\n * ToggleGroupItem 位于 ToggleGroup 内时需要的“拼接态”样式。\n *\n * 依赖根元素上的钩子:\n * - `group-data-[spacing=0]/toggle-group`:spacing 为 0 时相邻 item 拼接为整体\n * - `data-[spacing=0]`:item 自身的 data-spacing(shadcn 同样在 item 上输出)\n * - `group-data-horizontal|vertical/toggle-group`:按方向决定首尾圆角/边框\n * - `data-[variant=outline]`:outline 拼接时只保留内侧边框\n *\n * variant / size 的基础样式仍由 `toggleVariants` 提供,这里只补“组合关系”。\n */\nexport const toggleGroupItemVariants = cva(\n \"shrink-0 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t\",\n);\n"],"mappings":";;AAaA,IAAa,IAA0B,EACrC,k4BACF"}
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import { ComponentProps } from 'solid-js';
|
|
3
3
|
import { toggleVariants } from '../../toggle/Toggle/Toggle.styles';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
import { HTMLAttributes, PolymorphicProps } from '../../../types';
|
|
5
|
+
import { ToggleGroupValue } from '../ToggleGroup/ToggleGroup.types';
|
|
6
|
+
/**
|
|
7
|
+
* 必须先从 button 属性里摘掉原生的 `value`(Solid 声明为 `string | undefined`),
|
|
8
|
+
* 否则会与下面的 `value: TValue` 求交叉:`number & string` 会塌缩成 `never`。
|
|
9
|
+
*/
|
|
10
|
+
type BaseToggleGroupItemProps<TValue extends ToggleGroupValue> = VariantProps<typeof toggleVariants> & Omit<HTMLAttributes<"button">, "value"> & {
|
|
11
|
+
/** 当前 item 的唯一值,类型由泛型参数决定(与所属 ToggleGroup 保持一致) */
|
|
12
|
+
value: TValue;
|
|
13
|
+
/** 组件内部会先处理选中,再调用用户回调(与 tabs 的 trigger 一致) */
|
|
14
|
+
onClick?: ComponentProps<"button">["onClick"];
|
|
15
|
+
/** 聚焦即更新 roving focus 高亮,用户回调会被一并调用 */
|
|
16
|
+
onFocus?: ComponentProps<"button">["onFocus"];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* 泛型参数约束 `value` 的类型(默认 `string | number`)。
|
|
20
|
+
* 子组件无法从父级 `ToggleGroup` 推导类型,因此这里由 `value` 自身推导,
|
|
21
|
+
* 或显式指定:`<ToggleGroupItem<"bold" | "italic"> value="bold" />`。
|
|
22
|
+
*/
|
|
23
|
+
export type ToggleGroupItemProps<TValue extends ToggleGroupValue = ToggleGroupValue> = PolymorphicProps<"button", BaseToggleGroupItemProps<TValue>, false>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/components/toggle-group/call-event-handler.ts
|
|
2
|
+
function e(e, t) {
|
|
3
|
+
let n = Array.isArray(e) ? e : [e];
|
|
4
|
+
for (let e of n) typeof e == "function" && e(t);
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
export { e as callEventHandler };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=call-event-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-event-handler.js","names":[],"sources":["../../../src/components/toggle-group/call-event-handler.ts"],"sourcesContent":["/**\n * 调用用户传入的事件处理器(兼容 Solid 的函数 / 函数数组 / bound 对象形式)。\n * splitProps 提取出的事件类型是 EventHandlerUnion,不能直接调用。\n */\nexport function callEventHandler<E extends Event>(\n handler: unknown,\n event: E,\n): void {\n const list = Array.isArray(handler) ? handler : [handler];\n for (const h of list) {\n if (typeof h === \"function\") (h as (e: E) => void)(event);\n }\n}\n"],"mappings":";AAIA,SAAgB,EACd,GACA,GACM;CACN,IAAM,IAAO,MAAM,QAAQ,CAAO,IAAI,IAAU,CAAC,CAAO;CACxD,KAAK,IAAM,KAAK,GACd,AAAI,OAAO,KAAM,cAAY,EAAsB,CAAK;AAE5D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { ToggleGroup } from './ToggleGroup';
|
|
2
|
-
export type { ToggleGroupProps, ToggleGroupContextValue } from './ToggleGroup';
|
|
2
|
+
export type { ToggleGroupProps, ToggleGroupSingleProps, ToggleGroupMultipleProps, ToggleGroupValue, ToggleGroupContextValue, ToggleGroupItemEntry, ToggleGroupOrientation, ToggleGroupVariant, ToggleGroupSize, ToggleGroupChangeEventDetails, ToggleGroupChangeEventReason, } from './ToggleGroup';
|
|
3
3
|
export { ToggleGroupItem } from './ToggleGroupItem';
|
|
4
4
|
export type { ToggleGroupItemProps } from './ToggleGroupItem';
|