@neut/ui 0.0.10 → 0.0.12
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/label/index.d.ts +1 -0
- package/dist/components/select/Select/Select.context.d.ts +3 -0
- package/dist/components/select/Select/Select.context.js +12 -0
- package/dist/components/select/Select/Select.context.js.map +1 -0
- package/dist/components/select/Select/Select.d.ts +19 -0
- package/dist/components/select/Select/Select.js +48 -0
- package/dist/components/select/Select/Select.js.map +1 -0
- package/dist/components/select/Select/Select.types.d.ts +41 -0
- package/dist/components/select/Select/index.d.ts +3 -0
- package/dist/components/select/SelectContent/SelectContent.d.ts +2 -0
- package/dist/components/select/SelectContent/SelectContent.js +80 -0
- package/dist/components/select/SelectContent/SelectContent.js.map +1 -0
- package/dist/components/select/SelectContent/SelectContent.types.d.ts +22 -0
- package/dist/components/select/SelectContent/SelectContent.utils.d.ts +35 -0
- package/dist/components/select/SelectContent/SelectContent.utils.js +66 -0
- package/dist/components/select/SelectContent/SelectContent.utils.js.map +1 -0
- package/dist/components/select/SelectContent/index.d.ts +6 -0
- package/dist/components/select/SelectContent/useSelectContent.d.ts +28 -0
- package/dist/components/select/SelectContent/useSelectContent.js +46 -0
- package/dist/components/select/SelectContent/useSelectContent.js.map +1 -0
- package/dist/components/select/SelectGroup/SelectGroup.d.ts +2 -0
- package/dist/components/select/SelectGroup/SelectGroup.js +13 -0
- package/dist/components/select/SelectGroup/SelectGroup.js.map +1 -0
- package/dist/components/select/SelectGroup/index.d.ts +1 -0
- package/dist/components/select/SelectItem/SelectItem.d.ts +2 -0
- package/dist/components/select/SelectItem/SelectItem.js +52 -0
- package/dist/components/select/SelectItem/SelectItem.js.map +1 -0
- package/dist/components/select/SelectItem/SelectItem.types.d.ts +9 -0
- package/dist/components/select/SelectItem/index.d.ts +4 -0
- package/dist/components/select/SelectItem/useSelectItem.d.ts +11 -0
- package/dist/components/select/SelectItem/useSelectItem.js +32 -0
- package/dist/components/select/SelectItem/useSelectItem.js.map +1 -0
- package/dist/components/select/SelectLabel/SelectLabel.d.ts +2 -0
- package/dist/components/select/SelectLabel/SelectLabel.js +13 -0
- package/dist/components/select/SelectLabel/SelectLabel.js.map +1 -0
- package/dist/components/select/SelectLabel/index.d.ts +1 -0
- package/dist/components/select/SelectSeparator/SelectSeparator.d.ts +2 -0
- package/dist/components/select/SelectSeparator/SelectSeparator.js +13 -0
- package/dist/components/select/SelectSeparator/SelectSeparator.js.map +1 -0
- package/dist/components/select/SelectSeparator/index.d.ts +1 -0
- package/dist/components/select/SelectTrigger/SelectTrigger.d.ts +4 -0
- package/dist/components/select/SelectTrigger/SelectTrigger.js +50 -0
- package/dist/components/select/SelectTrigger/SelectTrigger.js.map +1 -0
- package/dist/components/select/SelectTrigger/SelectTrigger.types.d.ts +3 -0
- package/dist/components/select/SelectTrigger/index.d.ts +4 -0
- package/dist/components/select/SelectTrigger/useSelectTrigger.d.ts +15 -0
- package/dist/components/select/SelectTrigger/useSelectTrigger.js +37 -0
- package/dist/components/select/SelectTrigger/useSelectTrigger.js.map +1 -0
- package/dist/components/select/SelectValue/SelectValue.d.ts +2 -0
- package/dist/components/select/SelectValue/SelectValue.js +20 -0
- package/dist/components/select/SelectValue/SelectValue.js.map +1 -0
- package/dist/components/select/SelectValue/SelectValue.types.d.ts +4 -0
- package/dist/components/select/SelectValue/index.d.ts +2 -0
- package/dist/components/select/index.d.ts +13 -0
- package/dist/components/select/index.js +9 -0
- package/dist/components/switch/Switch.styles.js +1 -1
- package/dist/components/switch/Switch.styles.js.map +1 -1
- package/dist/components/tabs/Tabs/Tabs.context.d.ts +47 -0
- package/dist/components/tabs/Tabs/Tabs.context.js +54 -0
- package/dist/components/tabs/Tabs/Tabs.context.js.map +1 -0
- package/dist/components/tabs/Tabs/Tabs.d.ts +2 -0
- package/dist/components/tabs/Tabs/Tabs.js +71 -0
- package/dist/components/tabs/Tabs/Tabs.js.map +1 -0
- package/dist/components/tabs/Tabs/Tabs.types.d.ts +16 -0
- package/dist/components/tabs/Tabs/call-event-handler.d.ts +5 -0
- package/dist/components/tabs/Tabs/call-event-handler.js +9 -0
- package/dist/components/tabs/Tabs/call-event-handler.js.map +1 -0
- package/dist/components/tabs/Tabs/index.d.ts +2 -0
- package/dist/components/tabs/Tabs/useTabsKeyboard.d.ts +18 -0
- package/dist/components/tabs/Tabs/useTabsKeyboard.js +49 -0
- package/dist/components/tabs/Tabs/useTabsKeyboard.js.map +1 -0
- package/dist/components/tabs/TabsContent/TabsContent.d.ts +3 -0
- package/dist/components/tabs/TabsContent/TabsContent.js +52 -0
- package/dist/components/tabs/TabsContent/TabsContent.js.map +1 -0
- package/dist/components/tabs/TabsContent/TabsContent.types.d.ts +6 -0
- package/dist/components/tabs/TabsContent/index.d.ts +2 -0
- package/dist/components/tabs/TabsList/TabsList.context.d.ts +7 -0
- package/dist/components/tabs/TabsList/TabsList.context.js +11 -0
- package/dist/components/tabs/TabsList/TabsList.context.js.map +1 -0
- package/dist/components/tabs/TabsList/TabsList.d.ts +2 -0
- package/dist/components/tabs/TabsList/TabsList.js +48 -0
- package/dist/components/tabs/TabsList/TabsList.js.map +1 -0
- package/dist/components/tabs/TabsList/TabsList.styles.d.ts +3 -0
- package/dist/components/tabs/TabsList/TabsList.styles.js +13 -0
- package/dist/components/tabs/TabsList/TabsList.styles.js.map +1 -0
- package/dist/components/tabs/TabsList/TabsList.types.d.ts +7 -0
- package/dist/components/tabs/TabsList/index.d.ts +2 -0
- package/dist/components/tabs/TabsTrigger/TabsTrigger.d.ts +2 -0
- package/dist/components/tabs/TabsTrigger/TabsTrigger.js +71 -0
- package/dist/components/tabs/TabsTrigger/TabsTrigger.js.map +1 -0
- package/dist/components/tabs/TabsTrigger/TabsTrigger.styles.d.ts +1 -0
- package/dist/components/tabs/TabsTrigger/TabsTrigger.styles.js +7 -0
- package/dist/components/tabs/TabsTrigger/TabsTrigger.styles.js.map +1 -0
- package/dist/components/tabs/TabsTrigger/TabsTrigger.types.d.ts +6 -0
- package/dist/components/tabs/TabsTrigger/index.d.ts +2 -0
- package/dist/components/tabs/index.d.ts +4 -0
- package/dist/components/tabs/index.js +5 -0
- package/dist/components/tooltip/TooltipContent/TooltipContent.js +25 -27
- package/dist/components/tooltip/TooltipContent/TooltipContent.js.map +1 -1
- package/dist/components/tooltip/TooltipContent/useTooltipContent.js +3 -3
- package/dist/components/tooltip/TooltipTrigger/TooltipTrigger.js +11 -15
- package/dist/components/tooltip/TooltipTrigger/TooltipTrigger.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +167 -154
- package/dist/lib/positioner/middleware/size.js +21 -0
- package/dist/lib/positioner/middleware/size.js.map +1 -0
- package/dist/ui.css +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +3 -2
- package/dist/utils/ref.d.ts +11 -0
- package/dist/utils/ref.js +10 -0
- package/dist/utils/ref.js.map +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useSelectContext } from '../Select/Select.context';
|
|
2
|
+
import { SelectItemProps } from './SelectItem.types';
|
|
3
|
+
export interface UseSelectItemResult {
|
|
4
|
+
ctx: ReturnType<typeof useSelectContext>;
|
|
5
|
+
label: () => string;
|
|
6
|
+
isSelected: () => boolean;
|
|
7
|
+
isActive: () => boolean;
|
|
8
|
+
select: () => void;
|
|
9
|
+
onMouseEnter: () => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function useSelectItem(props: () => SelectItemProps): UseSelectItemResult;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useSelectContext as e } from "../Select/Select.context.js";
|
|
2
|
+
import { createMemo as t, onCleanup as n, onMount as r } from "solid-js";
|
|
3
|
+
//#region src/components/select/SelectItem/useSelectItem.ts
|
|
4
|
+
function i(i) {
|
|
5
|
+
let a = e("SelectItem"), o = () => {
|
|
6
|
+
let e = i();
|
|
7
|
+
return e.label ? e.label : typeof e.children == "string" ? e.children : e.value;
|
|
8
|
+
};
|
|
9
|
+
return r(() => {
|
|
10
|
+
let e = i(), t = a.registerItem({
|
|
11
|
+
value: e.value,
|
|
12
|
+
label: o(),
|
|
13
|
+
disabled: e.disabled
|
|
14
|
+
});
|
|
15
|
+
n(t);
|
|
16
|
+
}), {
|
|
17
|
+
ctx: a,
|
|
18
|
+
label: o,
|
|
19
|
+
isSelected: t(() => a.value() === i().value),
|
|
20
|
+
isActive: t(() => a.activeValue() === i().value),
|
|
21
|
+
select: () => {
|
|
22
|
+
i().disabled || a.selectValue(i().value);
|
|
23
|
+
},
|
|
24
|
+
onMouseEnter: () => {
|
|
25
|
+
i().disabled || a.setActiveValue(i().value);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { i as useSelectItem };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=useSelectItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSelectItem.js","names":[],"sources":["../../../../src/components/select/SelectItem/useSelectItem.ts"],"sourcesContent":["import { onMount, onCleanup, createMemo } from \"solid-js\";\nimport { useSelectContext } from \"../Select/Select.context\";\nimport type { SelectItemProps } from \"./SelectItem.types\";\n\nexport interface UseSelectItemResult {\n ctx: ReturnType<typeof useSelectContext>;\n label: () => string;\n isSelected: () => boolean;\n isActive: () => boolean;\n select: () => void;\n onMouseEnter: () => void;\n}\n\nexport function useSelectItem(\n props: () => SelectItemProps,\n): UseSelectItemResult {\n const ctx = useSelectContext(\"SelectItem\");\n\n const label = () => {\n const p = props();\n if (p.label) return p.label;\n return typeof p.children === \"string\" ? p.children : p.value;\n };\n\n onMount(() => {\n const p = props();\n const unregister = ctx.registerItem({\n value: p.value,\n label: label(),\n disabled: p.disabled,\n });\n onCleanup(unregister);\n });\n\n const isSelected = createMemo(() => ctx.value() === props().value);\n const isActive = createMemo(() => ctx.activeValue() === props().value);\n\n const select = () => {\n if (props().disabled) return;\n ctx.selectValue(props().value);\n };\n\n const onMouseEnter = () => {\n if (!props().disabled) ctx.setActiveValue(props().value);\n };\n\n return { ctx, label, isSelected, isActive, select, onMouseEnter };\n}\n"],"mappings":";;;AAaA,SAAgB,EACd,GACqB;CACrB,IAAM,IAAM,EAAiB,YAAY,GAEnC,UAAc;EAClB,IAAM,IAAI,EAAM;EAEhB,OADI,EAAE,QAAc,EAAE,QACf,OAAO,EAAE,YAAa,WAAW,EAAE,WAAW,EAAE;CACzD;CAwBA,OAtBA,QAAc;EACZ,IAAM,IAAI,EAAM,GACV,IAAa,EAAI,aAAa;GAClC,OAAO,EAAE;GACT,OAAO,EAAM;GACb,UAAU,EAAE;EACd,CAAC;EACD,EAAU,CAAU;CACtB,CAAC,GAcM;EAAE;EAAK;EAAO,YAZF,QAAiB,EAAI,MAAM,MAAM,EAAM,CAAC,CAAC,KAYvC;EAAY,UAXhB,QAAiB,EAAI,YAAY,MAAM,EAAM,CAAC,CAAC,KAW/B;EAAU,cATtB;GACf,EAAM,CAAC,CAAC,YACZ,EAAI,YAAY,EAAM,CAAC,CAAC,KAAK;EAC/B;EAMmD,oBAJxB;GACzB,AAAK,EAAM,CAAC,CAAC,YAAU,EAAI,eAAe,EAAM,CAAC,CAAC,KAAK;EACzD;CAEgE;AAClE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { clsx as e } from "../../../utils/clsx.js";
|
|
2
|
+
import { Label as t } from "../../label/Label.js";
|
|
3
|
+
import { createComponent as n, mergeProps as r } from "solid-js/web";
|
|
4
|
+
//#region src/components/select/SelectLabel/SelectLabel.tsx
|
|
5
|
+
function i(i) {
|
|
6
|
+
return n(t, r(i, { get class() {
|
|
7
|
+
return e("px-2 py-1.5 text-xs font-medium text-neutral-500", i.class);
|
|
8
|
+
} }));
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { i as SelectLabel };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=SelectLabel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectLabel.js","names":["Label","LabelProps","clsx","SelectLabel","props","_$createComponent","_$mergeProps","class"],"sources":["../../../../src/components/select/SelectLabel/SelectLabel.tsx"],"sourcesContent":["import { Label, type LabelProps } from \"~/components/label\";\nimport { clsx } from \"~/utils\";\n\nexport function SelectLabel(props: LabelProps) {\n return (\n <Label\n {...props}\n class={clsx(\n \"px-2 py-1.5 text-xs font-medium text-neutral-500\",\n props.class,\n )}\n />\n );\n}\n"],"mappings":";;;;AAGA,SAAgBG,EAAYC,GAAmB;CAC7C,OAAAC,EACGL,GAAKM,EACAF,GAAK,EAAA,IAAA,QAAA;EAAA,OACFF,EACL,oDACAE,EAAMG,KACR;CAAC,EAAA,CAAA,CAAA;AAGP"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SelectLabel } from './SelectLabel';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { clsx as e } from "../../../utils/clsx.js";
|
|
2
|
+
import { Separator as t } from "../../separator/Separator.js";
|
|
3
|
+
import { createComponent as n, mergeProps as r } from "solid-js/web";
|
|
4
|
+
//#region src/components/select/SelectSeparator/SelectSeparator.tsx
|
|
5
|
+
function i(i) {
|
|
6
|
+
return n(t, r(i, { get class() {
|
|
7
|
+
return e("my-1", i.class);
|
|
8
|
+
} }));
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { i as SelectSeparator };
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=SelectSeparator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectSeparator.js","names":["Separator","SeparatorProps","clsx","SelectSeparator","props","_$createComponent","_$mergeProps","class"],"sources":["../../../../src/components/select/SelectSeparator/SelectSeparator.tsx"],"sourcesContent":["import { Separator, type SeparatorProps } from \"~/components/separator\";\nimport { clsx } from \"~/utils\";\n\nexport function SelectSeparator(props: SeparatorProps) {\n return <Separator {...props} class={clsx(\"my-1\", props.class)} />;\n}\n"],"mappings":";;;;AAGA,SAAgBG,EAAgBC,GAAuB;CACrD,OAAAC,EAAQL,GAASM,EAAKF,GAAK,EAAA,IAAA,QAAA;EAAA,OAASF,EAAK,QAAQE,EAAMG,KAAK;CAAC,EAAA,CAAA,CAAA;AAC/D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SelectSeparator } from './SelectSeparator';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ValidComponent } from 'solid-js';
|
|
2
|
+
import { SelectTriggerProps } from './SelectTrigger.types';
|
|
3
|
+
import { Button } from '../../button';
|
|
4
|
+
export declare const SelectTrigger: <T extends ValidComponent = typeof Button<"button">>(props: SelectTriggerProps<T>) => import("solid-js").JSX.Element;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { clsx as e } from "../../../utils/clsx.js";
|
|
2
|
+
import { mergeRefs as t } from "../../../utils/ref.js";
|
|
3
|
+
import { Button as n } from "../../button/Button.js";
|
|
4
|
+
import { useSelectTrigger as r } from "./useSelectTrigger.js";
|
|
5
|
+
import { Dynamic as i, createComponent as a, memo as o, mergeProps as s } from "solid-js/web";
|
|
6
|
+
import { ChevronDown as c } from "lucide-solid";
|
|
7
|
+
//#region src/components/select/SelectTrigger/SelectTrigger.tsx
|
|
8
|
+
var l = (l) => {
|
|
9
|
+
let { ctx: u, isDisabled: d, attachListeners: f } = r(() => l);
|
|
10
|
+
return a(i, s(l, {
|
|
11
|
+
get disabled() {
|
|
12
|
+
return d();
|
|
13
|
+
},
|
|
14
|
+
get icon() {
|
|
15
|
+
return a(c, {});
|
|
16
|
+
},
|
|
17
|
+
iconPosition: "right",
|
|
18
|
+
get component() {
|
|
19
|
+
return l.component ?? n;
|
|
20
|
+
},
|
|
21
|
+
get variant() {
|
|
22
|
+
return l.variant ?? "outline";
|
|
23
|
+
},
|
|
24
|
+
ref(e) {
|
|
25
|
+
var n = t(u.setReference, l.ref, f);
|
|
26
|
+
typeof n == "function" && n(e);
|
|
27
|
+
},
|
|
28
|
+
role: "combobox",
|
|
29
|
+
"aria-haspopup": "listbox",
|
|
30
|
+
get "aria-expanded"() {
|
|
31
|
+
return u.open();
|
|
32
|
+
},
|
|
33
|
+
get "aria-controls"() {
|
|
34
|
+
return o(() => !!u.open())() ? u.contentId : void 0;
|
|
35
|
+
},
|
|
36
|
+
get "data-state"() {
|
|
37
|
+
return u.open() ? "open" : "closed";
|
|
38
|
+
},
|
|
39
|
+
get "data-disabled"() {
|
|
40
|
+
return d() ? "" : void 0;
|
|
41
|
+
},
|
|
42
|
+
get class() {
|
|
43
|
+
return e("justify-between", l.class);
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
export { l as SelectTrigger };
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=SelectTrigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectTrigger.js","names":["ValidComponent","Dynamic","useSelectTrigger","SelectTriggerProps","clsx","mergeRefs","Button","ChevronDown","SelectTrigger","props","T","ctx","isDisabled","attachListeners","_$createComponent","_$mergeProps","disabled","icon","iconPosition","component","variant","ref","r$","_ref$","setReference","role","aria-expanded","open","aria-controls","_$memo","contentId","undefined","data-state","data-disabled","class"],"sources":["../../../../src/components/select/SelectTrigger/SelectTrigger.tsx"],"sourcesContent":["import type { ValidComponent } from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { useSelectTrigger } from \"./useSelectTrigger\";\nimport type { SelectTriggerProps } from \"./SelectTrigger.types\";\nimport { clsx, mergeRefs } from \"~/utils\";\nimport { Button } from \"~/components/button\";\nimport { ChevronDown } from \"lucide-solid\";\n\nexport const SelectTrigger = <\n T extends ValidComponent = typeof Button<\"button\">,\n>(\n props: SelectTriggerProps<T>,\n) => {\n const { ctx, isDisabled, attachListeners } = useSelectTrigger(() => props);\n\n return (\n <Dynamic\n {...props}\n disabled={isDisabled()}\n icon={<ChevronDown />}\n iconPosition=\"right\"\n component={(props.component as ValidComponent) ?? Button<\"button\">}\n variant={props.variant ?? \"outline\"}\n ref={mergeRefs(ctx.setReference, props.ref, attachListeners)}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={ctx.open()}\n aria-controls={ctx.open() ? ctx.contentId : undefined}\n data-state={ctx.open() ? \"open\" : \"closed\"}\n data-disabled={isDisabled() ? \"\" : undefined}\n class={clsx(\"justify-between\", props.class)}\n />\n );\n};\n"],"mappings":";;;;;;;AAQA,IAAaQ,KAGXC,MACG;CACH,IAAM,EAAEE,QAAKC,eAAYC,uBAAoBX,QAAuBO,CAAK;CAEzE,OAAAK,EACGb,GAAOc,EACFN,GAAK;EAAA,IACTO,WAAQ;GAAA,OAAEJ,EAAW;EAAC;EAAA,IACtBK,OAAI;GAAA,OAAAH,EAAGP,GAAW,CAAA,CAAA;EAAA;EAClBW,cAAY;EAAA,IACZC,YAAS;GAAA,OAAGV,EAAMU,aAAgCb;EAAgB;EAAA,IAClEc,UAAO;GAAA,OAAEX,EAAMW,WAAW;EAAS;EAAAC,IAAAC,GAAA;GAAA,IAAAC,IAC9BlB,EAAUM,EAAIa,cAAcf,EAAMY,KAAKR,CAAe;GAAC,OAAAU,KAAA,cAAAA,EAAAD,CAAA;EAAA;EAC5DG,MAAI;EAAA,iBAAA;EAAA,IAAA,kBAAA;GAAA,OAEWd,EAAIgB,KAAK;EAAC;EAAA,IAAA,kBAAA;GAAA,OACVE,QAAA,CAAA,CAAAlB,EAAIgB,KAAK,CAAC,CAAA,CAAA,IAAGhB,EAAImB,YAAYC,KAAAA;EAAS;EAAA,IAAA,eAAA;GAAA,OACzCpB,EAAIgB,KAAK,IAAI,SAAS;EAAQ;EAAA,IAAA,kBAAA;GAAA,OAC3Bf,EAAW,IAAI,KAAKmB,KAAAA;EAAS;EAAA,IAAA,QAAA;GAAA,OACrC3B,EAAK,mBAAmBK,EAAMyB,KAAK;EAAC;CAAA,CAAA,CAAA;AAGjD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ValidComponent } from 'solid-js';
|
|
2
|
+
import { useSelectContext } from '../Select/Select.context';
|
|
3
|
+
import { SelectTriggerProps } from './SelectTrigger.types';
|
|
4
|
+
export interface UseSelectTriggerResult {
|
|
5
|
+
ctx: ReturnType<typeof useSelectContext>;
|
|
6
|
+
isDisabled: () => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* 把开关下拉相关的原生事件监听器绑定到真正的 DOM 元素上(通过 ref 调用)。
|
|
9
|
+
* 用 addEventListener 而不是 JSX 的 onXxx prop,是为了不占用这些 prop 名——
|
|
10
|
+
* 调用方可以在 <SelectTrigger onClick={...}> 上自由传自己的原生事件处理,
|
|
11
|
+
* 两者是完全独立的两套机制,互不覆盖。
|
|
12
|
+
*/
|
|
13
|
+
attachListeners: (el: Element) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function useSelectTrigger<T extends ValidComponent>(props: () => SelectTriggerProps<T>): UseSelectTriggerResult;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { useSelectContext as e } from "../Select/Select.context.js";
|
|
2
|
+
import { onCleanup as t } from "solid-js";
|
|
3
|
+
//#region src/components/select/SelectTrigger/useSelectTrigger.ts
|
|
4
|
+
function n(n) {
|
|
5
|
+
let r = e("SelectTrigger"), i = () => r.disabled() || !!n().disabled, a = () => {
|
|
6
|
+
i() || (r.setActiveValue(r.value() ?? r.items.find((e) => !e.disabled)?.value), r.setOpen(!0));
|
|
7
|
+
};
|
|
8
|
+
return {
|
|
9
|
+
ctx: r,
|
|
10
|
+
isDisabled: i,
|
|
11
|
+
attachListeners: (e) => {
|
|
12
|
+
let n = () => {
|
|
13
|
+
i() || (r.open() ? r.setOpen(!1) : a());
|
|
14
|
+
}, o = (e) => {
|
|
15
|
+
if (i()) return;
|
|
16
|
+
let t = e;
|
|
17
|
+
if (!r.open()) {
|
|
18
|
+
[
|
|
19
|
+
"ArrowDown",
|
|
20
|
+
"ArrowUp",
|
|
21
|
+
"Enter",
|
|
22
|
+
" "
|
|
23
|
+
].includes(t.key) && (t.preventDefault(), a());
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
t.key === "Escape" && (t.stopPropagation(), r.close());
|
|
27
|
+
};
|
|
28
|
+
e.addEventListener("click", n), e.addEventListener("keydown", o), t(() => {
|
|
29
|
+
e.removeEventListener("click", n), e.removeEventListener("keydown", o);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { n as useSelectTrigger };
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=useSelectTrigger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSelectTrigger.js","names":[],"sources":["../../../../src/components/select/SelectTrigger/useSelectTrigger.ts"],"sourcesContent":["import { onCleanup, type ValidComponent } from \"solid-js\";\nimport { useSelectContext } from \"../Select/Select.context\";\nimport type { SelectTriggerProps } from \"./SelectTrigger.types\";\n\nexport interface UseSelectTriggerResult {\n ctx: ReturnType<typeof useSelectContext>;\n isDisabled: () => boolean;\n /**\n * 把开关下拉相关的原生事件监听器绑定到真正的 DOM 元素上(通过 ref 调用)。\n * 用 addEventListener 而不是 JSX 的 onXxx prop,是为了不占用这些 prop 名——\n * 调用方可以在 <SelectTrigger onClick={...}> 上自由传自己的原生事件处理,\n * 两者是完全独立的两套机制,互不覆盖。\n */\n attachListeners: (el: Element) => void;\n}\n\nexport function useSelectTrigger<T extends ValidComponent>(\n props: () => SelectTriggerProps<T>,\n): UseSelectTriggerResult {\n const ctx = useSelectContext(\"SelectTrigger\");\n\n const isDisabled = () => ctx.disabled() || !!props().disabled;\n\n const openAndHighlightSelected = () => {\n if (isDisabled()) return;\n ctx.setActiveValue(\n ctx.value() ?? ctx.items.find((it) => !it.disabled)?.value,\n );\n ctx.setOpen(true);\n };\n\n const attachListeners = (el: Element) => {\n const onClick = () => {\n if (isDisabled()) return;\n if (ctx.open()) ctx.setOpen(false);\n else openAndHighlightSelected();\n };\n\n const onKeyDown = (e: Event) => {\n if (isDisabled()) return;\n const keyboardEvent = e as KeyboardEvent;\n\n if (!ctx.open()) {\n if (\n [\"ArrowDown\", \"ArrowUp\", \"Enter\", \" \"].includes(keyboardEvent.key)\n ) {\n keyboardEvent.preventDefault();\n openAndHighlightSelected();\n }\n return;\n }\n\n if (keyboardEvent.key === \"Escape\") {\n keyboardEvent.stopPropagation();\n ctx.close();\n }\n };\n\n el.addEventListener(\"click\", onClick);\n el.addEventListener(\"keydown\", onKeyDown);\n\n onCleanup(() => {\n el.removeEventListener(\"click\", onClick);\n el.removeEventListener(\"keydown\", onKeyDown);\n });\n };\n\n return { ctx, isDisabled, attachListeners };\n}\n"],"mappings":";;;AAgBA,SAAgB,EACd,GACwB;CACxB,IAAM,IAAM,EAAiB,eAAe,GAEtC,UAAmB,EAAI,SAAS,KAAK,CAAC,CAAC,EAAM,CAAC,CAAC,UAE/C,UAAiC;EACjC,EAAW,MACf,EAAI,eACF,EAAI,MAAM,KAAK,EAAI,MAAM,MAAM,MAAO,CAAC,EAAG,QAAQ,CAAC,EAAE,KACvD,GACA,EAAI,QAAQ,EAAI;CAClB;CAsCA,OAAO;EAAE;EAAK;EAAY,kBApCD,MAAgB;GACvC,IAAM,UAAgB;IAChB,EAAW,MACX,EAAI,KAAK,IAAG,EAAI,QAAQ,EAAK,IAC5B,EAAyB;GAChC,GAEM,KAAa,MAAa;IAC9B,IAAI,EAAW,GAAG;IAClB,IAAM,IAAgB;IAEtB,IAAI,CAAC,EAAI,KAAK,GAAG;KACf,AACE;MAAC;MAAa;MAAW;MAAS;KAAG,CAAC,CAAC,SAAS,EAAc,GAAG,MAEjE,EAAc,eAAe,GAC7B,EAAyB;KAE3B;IACF;IAEA,AAAI,EAAc,QAAQ,aACxB,EAAc,gBAAgB,GAC9B,EAAI,MAAM;GAEd;GAKA,AAHA,EAAG,iBAAiB,SAAS,CAAO,GACpC,EAAG,iBAAiB,WAAW,CAAS,GAExC,QAAgB;IAEd,AADA,EAAG,oBAAoB,SAAS,CAAO,GACvC,EAAG,oBAAoB,WAAW,CAAS;GAC7C,CAAC;EACH;CAE0C;AAC5C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { clsx as e } from "../../../utils/clsx.js";
|
|
2
|
+
import { useSelectContext as t } from "../Select/Select.context.js";
|
|
3
|
+
import { className as n, effect as r, insert as i, template as a } from "solid-js/web";
|
|
4
|
+
import { createMemo as o } from "solid-js";
|
|
5
|
+
//#region src/components/select/SelectValue/SelectValue.tsx
|
|
6
|
+
var s = /*#__PURE__*/ a("<span>");
|
|
7
|
+
function c(a) {
|
|
8
|
+
let c = t("SelectValue"), l = o(() => {
|
|
9
|
+
let e = c.value();
|
|
10
|
+
if (e !== void 0) return c.items.find((t) => t.value === e)?.label ?? e;
|
|
11
|
+
});
|
|
12
|
+
return (() => {
|
|
13
|
+
var t = s();
|
|
14
|
+
return i(t, () => l() ?? a.placeholder ?? ""), r(() => n(t, e(!l() && "text-neutral-500", a.class))), t;
|
|
15
|
+
})();
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { c as SelectValue };
|
|
19
|
+
|
|
20
|
+
//# sourceMappingURL=SelectValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectValue.js","names":["createMemo","useSelectContext","SelectValueProps","clsx","SelectValue","props","ctx","label","v","value","undefined","items","find","it","_el$","_tmpl$","_$insert","placeholder","_$effect","_$className","class"],"sources":["../../../../src/components/select/SelectValue/SelectValue.tsx"],"sourcesContent":["import { createMemo } from \"solid-js\";\nimport { useSelectContext } from \"../Select/Select.context\";\nimport type { SelectValueProps } from \"./SelectValue.types\";\nimport { clsx } from \"~/utils\";\n\nexport function SelectValue(props: SelectValueProps) {\n const ctx = useSelectContext(\"SelectValue\");\n\n const label = createMemo(() => {\n const v = ctx.value();\n if (v === undefined) return undefined;\n return ctx.items.find((it) => it.value === v)?.label ?? v;\n });\n\n return (\n <span class={clsx(!label() && \"text-neutral-500\", props.class)}>\n {label() ?? props.placeholder ?? \"\"}\n </span>\n );\n}\n"],"mappings":";;;;;;AAKA,SAAgBI,EAAYC,GAAyB;CACnD,IAAMC,IAAML,EAAiB,aAAa,GAEpCM,IAAQP,QAAiB;EAC7B,IAAMQ,IAAIF,EAAIG,MAAM;EAChBD,UAAME,KAAAA,GACV,OAAOJ,EAAIK,MAAMC,MAAMC,MAAOA,EAAGJ,UAAUD,CAAC,CAAC,EAAED,SAASC;CAC1D,CAAC;CAED,cAAA;EAAA,IAAAM,IAAAC,EAAA;EACgE,OADhEC,EAAAF,SAEKP,EAAM,KAAKF,EAAMY,eAAe,EAAE,GAAAC,QAAAC,EAAAL,GADxBX,EAAK,CAACI,EAAM,KAAK,oBAAoBF,EAAMe,KAAK,CAAC,CAAA,GAAAN;CAAA,EAAA,CAAA;AAIlE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { Select } from './Select';
|
|
2
|
+
export type { SelectProps, SelectContextValue, SelectItemMeta } from './Select';
|
|
3
|
+
export { SelectTrigger } from './SelectTrigger';
|
|
4
|
+
export type { SelectTriggerProps } from './SelectTrigger';
|
|
5
|
+
export { SelectValue } from './SelectValue';
|
|
6
|
+
export type { SelectValueProps } from './SelectValue';
|
|
7
|
+
export { SelectContent } from './SelectContent';
|
|
8
|
+
export type { SelectContentProps } from './SelectContent';
|
|
9
|
+
export { SelectItem } from './SelectItem';
|
|
10
|
+
export type { SelectItemProps } from './SelectItem';
|
|
11
|
+
export { SelectGroup } from './SelectGroup';
|
|
12
|
+
export { SelectLabel } from './SelectLabel';
|
|
13
|
+
export { SelectSeparator } from './SelectSeparator';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Select as e } from "./Select/Select.js";
|
|
2
|
+
import { SelectTrigger as t } from "./SelectTrigger/SelectTrigger.js";
|
|
3
|
+
import { SelectValue as n } from "./SelectValue/SelectValue.js";
|
|
4
|
+
import { SelectContent as r } from "./SelectContent/SelectContent.js";
|
|
5
|
+
import { SelectItem as i } from "./SelectItem/SelectItem.js";
|
|
6
|
+
import { SelectGroup as a } from "./SelectGroup/SelectGroup.js";
|
|
7
|
+
import { SelectLabel as o } from "./SelectLabel/SelectLabel.js";
|
|
8
|
+
import { SelectSeparator as s } from "./SelectSeparator/SelectSeparator.js";
|
|
9
|
+
export { e as Select, r as SelectContent, a as SelectGroup, i as SelectItem, o as SelectLabel, s as SelectSeparator, t as SelectTrigger, n as SelectValue };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { clsx as e } from "../../utils/clsx.js";
|
|
2
2
|
//#region src/components/switch/Switch.styles.ts
|
|
3
3
|
var t = {
|
|
4
|
-
switch: e("peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=md]:h-[18.4px] data-[size=md]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[checked=true]:bg-primary data-[checked=false]:bg-input dark:data-[checked=false]:bg-input/80 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50"),
|
|
4
|
+
switch: e("peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=md]:h-[18.4px] data-[size=md]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[checked=true]:bg-primary data-[checked=false]:bg-input dark:data-[checked=false]:bg-input/80 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 data-[disabled=true]:pointer-events-none"),
|
|
5
5
|
thumb: e("pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=md]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=md]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] dark:data-[checked=true]:bg-primary-foreground group-data-[size=md]/switch:data-[checked=false]:translate-x-0 group-data-[size=sm]/switch:data-[checked=false]:translate-x-0 dark:data-[checked=false]:bg-foreground")
|
|
6
6
|
};
|
|
7
7
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.styles.js","names":[],"sources":["../../../src/components/switch/Switch.styles.ts"],"sourcesContent":["import { clsx } from \"~/utils\";\n\nexport const classes = {\n switch: clsx(\n // \"relative inline-flex shrink-0 items-center after:absolute after:-inset-x-3 after:-inset-y-2\",\n // \"rounded-full border border-transparent focus-visible:border-neutral-400 dark:focus-visible:border-neutral-500 aria-invalid:border-red-600 dark:aria-invalid:border-red-400/50\",\n // \"focus-visible:ring-neutral-400/50 dark:focus-visible:ring-neutral-500/50 aria-invalid:ring-red-600/20 dark:aria-invalid:ring-red-400/40 data-[checked=true]:bg-neutral-900 dark:data-[checked=true]:bg-neutral-200 data-[checked=false]:bg-neutral-200 dark:data-[checked=false]:bg-white/12\",\n // \"data-[size=md]:h-[18.4px] data-[size=md]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6\",\n // \"peer group/switch transition-all outline-none focus-visible:ring-3 aria-invalid:ring-3 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 data-[disabled=true]:pointer-events-none\",\n \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=md]:h-[18.4px] data-[size=md]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[checked=true]:bg-primary data-[checked=false]:bg-input dark:data-[checked=false]:bg-input/80 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50\",\n ),\n thumb: clsx(\n // \"pointer-events-none\",\n // \"block\",\n // \"rounded-full\",\n // \"ring-0\",\n // \"transition-transform\",\n // \"group-data-[size=md]/switch:size-4 group-data-[size=sm]/switch:size-3\",\n // \"group-data-[size=md]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] group-data-[size=md]/switch:data-[checked=false]:translate-x-0 group-data-[size=sm]/switch:data-[checked=false]:translate-x-0\",\n // \"bg-white dark:bg-neutral-950 dark:data-[checked=true]:bg-neutral-900 dark:data-[checked=false]:bg-neutral-50\",\n \"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=md]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=md]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] dark:data-[checked=true]:bg-primary-foreground group-data-[size=md]/switch:data-[checked=false]:translate-x-0 group-data-[size=sm]/switch:data-[checked=false]:translate-x-0 dark:data-[checked=false]:bg-foreground\",\n ),\n} as const;\n"],"mappings":";;AAEA,IAAa,IAAU;CACrB,QAAQ,EAMN
|
|
1
|
+
{"version":3,"file":"Switch.styles.js","names":[],"sources":["../../../src/components/switch/Switch.styles.ts"],"sourcesContent":["import { clsx } from \"~/utils\";\n\nexport const classes = {\n switch: clsx(\n // \"relative inline-flex shrink-0 items-center after:absolute after:-inset-x-3 after:-inset-y-2\",\n // \"rounded-full border border-transparent focus-visible:border-neutral-400 dark:focus-visible:border-neutral-500 aria-invalid:border-red-600 dark:aria-invalid:border-red-400/50\",\n // \"focus-visible:ring-neutral-400/50 dark:focus-visible:ring-neutral-500/50 aria-invalid:ring-red-600/20 dark:aria-invalid:ring-red-400/40 data-[checked=true]:bg-neutral-900 dark:data-[checked=true]:bg-neutral-200 data-[checked=false]:bg-neutral-200 dark:data-[checked=false]:bg-white/12\",\n // \"data-[size=md]:h-[18.4px] data-[size=md]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6\",\n // \"peer group/switch transition-all outline-none focus-visible:ring-3 aria-invalid:ring-3 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 data-[disabled=true]:pointer-events-none\",\n \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=md]:h-[18.4px] data-[size=md]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-[checked=true]:bg-primary data-[checked=false]:bg-input dark:data-[checked=false]:bg-input/80 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 data-[disabled=true]:pointer-events-none\",\n ),\n thumb: clsx(\n // \"pointer-events-none\",\n // \"block\",\n // \"rounded-full\",\n // \"ring-0\",\n // \"transition-transform\",\n // \"group-data-[size=md]/switch:size-4 group-data-[size=sm]/switch:size-3\",\n // \"group-data-[size=md]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] group-data-[size=md]/switch:data-[checked=false]:translate-x-0 group-data-[size=sm]/switch:data-[checked=false]:translate-x-0\",\n // \"bg-white dark:bg-neutral-950 dark:data-[checked=true]:bg-neutral-900 dark:data-[checked=false]:bg-neutral-50\",\n \"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=md]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=md]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[checked=true]:translate-x-[calc(100%-2px)] dark:data-[checked=true]:bg-primary-foreground group-data-[size=md]/switch:data-[checked=false]:translate-x-0 group-data-[size=sm]/switch:data-[checked=false]:translate-x-0 dark:data-[checked=false]:bg-foreground\",\n ),\n} as const;\n"],"mappings":";;AAEA,IAAa,IAAU;CACrB,QAAQ,EAMN,wsBACF;CACA,OAAO,EASL,ugBACF;AACF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Accessor, ParentProps } from 'solid-js';
|
|
2
|
+
import { TabsValue } from './Tabs.types';
|
|
3
|
+
interface TriggerEntry {
|
|
4
|
+
value: TabsValue;
|
|
5
|
+
/** accessor,支持运行时 disabled 翻转 */
|
|
6
|
+
disabled: () => boolean;
|
|
7
|
+
element: HTMLElement;
|
|
8
|
+
}
|
|
9
|
+
export interface TabsContextValue {
|
|
10
|
+
/** 当前激活值(受控优先,否则内部状态) */
|
|
11
|
+
value: Accessor<TabsValue | undefined>;
|
|
12
|
+
setValue: (value: TabsValue) => void;
|
|
13
|
+
isSelected: (value: TabsValue) => boolean;
|
|
14
|
+
orientation: Accessor<"horizontal" | "vertical">;
|
|
15
|
+
dir: Accessor<"ltr" | "rtl" | "auto">;
|
|
16
|
+
loop: Accessor<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* 当前焦点高亮 tab,与激活值分离:
|
|
19
|
+
* 默认(activateOnFocus=false)聚焦/键盘导航只更新高亮,不激活;
|
|
20
|
+
* 激活只发生在点击(click)时。与 base-ui 的 highlighted/active 语义一致。
|
|
21
|
+
*/
|
|
22
|
+
highlightedValue: Accessor<TabsValue | undefined>;
|
|
23
|
+
setHighlightedValue: (value: TabsValue) => void;
|
|
24
|
+
/** 按挂载顺序注册 trigger,返回注销函数;仅用于渲染期推导与键盘导航 */
|
|
25
|
+
registerTrigger: (entry: TriggerEntry) => () => void;
|
|
26
|
+
/** 已注册的 trigger 列表(挂载顺序) */
|
|
27
|
+
getTriggers: () => TriggerEntry[];
|
|
28
|
+
/** 无高亮时,该 value 是否为第一个可用 trigger(键盘 tabindex 起点) */
|
|
29
|
+
isFirstEnabled: (value: TabsValue) => boolean;
|
|
30
|
+
/** 该 value 对应的 trigger 当前是否可用(已注册且未 disabled) */
|
|
31
|
+
isUsable: (value: TabsValue) => boolean;
|
|
32
|
+
/** value -> triggerId / contentId 交叉注册,供 aria-controls / aria-labelledby 使用 */
|
|
33
|
+
setTriggerId: (value: TabsValue, id: string) => void;
|
|
34
|
+
getTriggerId: (value: TabsValue) => string | undefined;
|
|
35
|
+
setContentId: (value: TabsValue, id: string) => void;
|
|
36
|
+
getContentId: (value: TabsValue) => string | undefined;
|
|
37
|
+
}
|
|
38
|
+
export declare function TabsProvider(props: ParentProps & {
|
|
39
|
+
defaultValue?: TabsValue;
|
|
40
|
+
value?: TabsValue;
|
|
41
|
+
onValueChange?: (value: TabsValue) => void;
|
|
42
|
+
orientation: "horizontal" | "vertical";
|
|
43
|
+
dir: "ltr" | "rtl" | "auto";
|
|
44
|
+
loop: boolean;
|
|
45
|
+
}): import("solid-js").JSX.Element;
|
|
46
|
+
export declare const useTabsContext: () => TabsContextValue;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createComponent as e } from "solid-js/web";
|
|
2
|
+
import { createContext as t, createEffect as n, createSignal as r, useContext as i } from "solid-js";
|
|
3
|
+
import { createStore as a } from "solid-js/store";
|
|
4
|
+
//#region src/components/tabs/Tabs/Tabs.context.tsx
|
|
5
|
+
var o = t();
|
|
6
|
+
function s(t) {
|
|
7
|
+
let [i, s] = r(t.defaultValue), [c, l] = r(), [u, d] = r([]), [f, p] = a({
|
|
8
|
+
trigger: {},
|
|
9
|
+
content: {}
|
|
10
|
+
}), m = () => t.value ?? i(), h = (e) => {
|
|
11
|
+
if (t.value !== void 0) {
|
|
12
|
+
t.onValueChange?.(e);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
s(e), t.onValueChange?.(e);
|
|
16
|
+
}, g = (e) => m() === e;
|
|
17
|
+
n(() => {
|
|
18
|
+
let e = m();
|
|
19
|
+
e !== void 0 && document.activeElement?.getAttribute("role") !== "tab" && l(e);
|
|
20
|
+
});
|
|
21
|
+
let _ = {
|
|
22
|
+
value: m,
|
|
23
|
+
setValue: h,
|
|
24
|
+
isSelected: g,
|
|
25
|
+
orientation: () => t.orientation,
|
|
26
|
+
dir: () => t.dir,
|
|
27
|
+
loop: () => t.loop,
|
|
28
|
+
highlightedValue: c,
|
|
29
|
+
setHighlightedValue: l,
|
|
30
|
+
registerTrigger: (e) => (d((t) => [...t, e]), () => d((t) => t.filter((t) => t.value !== e.value))),
|
|
31
|
+
getTriggers: () => u(),
|
|
32
|
+
isFirstEnabled: (e) => u().find((e) => !e.disabled())?.value === e,
|
|
33
|
+
isUsable: (e) => u().some((t) => t.value === e && !t.disabled()),
|
|
34
|
+
setTriggerId: (e, t) => p("trigger", String(e), t),
|
|
35
|
+
getTriggerId: (e) => f.trigger[String(e)],
|
|
36
|
+
setContentId: (e, t) => p("content", String(e), t),
|
|
37
|
+
getContentId: (e) => f.content[String(e)]
|
|
38
|
+
};
|
|
39
|
+
return e(o.Provider, {
|
|
40
|
+
value: _,
|
|
41
|
+
get children() {
|
|
42
|
+
return t.children;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
var c = () => {
|
|
47
|
+
let e = i(o);
|
|
48
|
+
if (!e) throw Error("useTabsContext must be used within a <Tabs> component");
|
|
49
|
+
return e;
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
export { s as TabsProvider, c as useTabsContext };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=Tabs.context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.context.js","names":["createContext","createEffect","createSignal","Accessor","ParentProps","useContext","createStore","TabsValue","TriggerEntry","value","disabled","element","HTMLElement","TabsContextValue","setValue","isSelected","orientation","dir","loop","highlightedValue","setHighlightedValue","registerTrigger","entry","getTriggers","isFirstEnabled","isUsable","setTriggerId","id","getTriggerId","setContentId","getContentId","TabsContext","TabsProvider","props","defaultValue","onValueChange","internalValue","setInternalValue","triggerOrder","setTriggerOrder","ids","setIds","trigger","Record","content","next","undefined","v","current","active","document","activeElement","getAttribute","prev","filter","t","first","find","some","String","contextValue","_$createComponent","Provider","children","useTabsContext","context","Error"],"sources":["../../../../src/components/tabs/Tabs/Tabs.context.tsx"],"sourcesContent":["import {\n createContext,\n createEffect,\n createSignal,\n type Accessor,\n type ParentProps,\n useContext,\n} from \"solid-js\";\nimport { createStore } from \"solid-js/store\";\nimport type { TabsValue } from \"./Tabs.types\";\n\ninterface TriggerEntry {\n value: TabsValue;\n /** accessor,支持运行时 disabled 翻转 */\n disabled: () => boolean;\n element: HTMLElement;\n}\n\nexport interface TabsContextValue {\n /** 当前激活值(受控优先,否则内部状态) */\n value: Accessor<TabsValue | undefined>;\n setValue: (value: TabsValue) => void;\n isSelected: (value: TabsValue) => boolean;\n orientation: Accessor<\"horizontal\" | \"vertical\">;\n dir: Accessor<\"ltr\" | \"rtl\" | \"auto\">;\n loop: Accessor<boolean>;\n /**\n * 当前焦点高亮 tab,与激活值分离:\n * 默认(activateOnFocus=false)聚焦/键盘导航只更新高亮,不激活;\n * 激活只发生在点击(click)时。与 base-ui 的 highlighted/active 语义一致。\n */\n highlightedValue: Accessor<TabsValue | undefined>;\n setHighlightedValue: (value: TabsValue) => void;\n /** 按挂载顺序注册 trigger,返回注销函数;仅用于渲染期推导与键盘导航 */\n registerTrigger: (entry: TriggerEntry) => () => void;\n /** 已注册的 trigger 列表(挂载顺序) */\n getTriggers: () => TriggerEntry[];\n /** 无高亮时,该 value 是否为第一个可用 trigger(键盘 tabindex 起点) */\n isFirstEnabled: (value: TabsValue) => boolean;\n /** 该 value 对应的 trigger 当前是否可用(已注册且未 disabled) */\n isUsable: (value: TabsValue) => boolean;\n /** value -> triggerId / contentId 交叉注册,供 aria-controls / aria-labelledby 使用 */\n setTriggerId: (value: TabsValue, id: string) => void;\n getTriggerId: (value: TabsValue) => string | undefined;\n setContentId: (value: TabsValue, id: string) => void;\n getContentId: (value: TabsValue) => string | undefined;\n}\n\nconst TabsContext = createContext<TabsContextValue>();\n\nexport function TabsProvider(\n props: ParentProps & {\n defaultValue?: TabsValue;\n value?: TabsValue;\n onValueChange?: (value: TabsValue) => void;\n orientation: \"horizontal\" | \"vertical\";\n dir: \"ltr\" | \"rtl\" | \"auto\";\n loop: boolean;\n },\n) {\n const [internalValue, setInternalValue] = createSignal<TabsValue | undefined>(\n props.defaultValue,\n );\n const [highlightedValue, setHighlightedValue] = createSignal<\n TabsValue | undefined\n >();\n const [triggerOrder, setTriggerOrder] = createSignal<TriggerEntry[]>([]);\n const [ids, setIds] = createStore<{\n trigger: Record<string, string>;\n content: Record<string, string>;\n }>({ trigger: {}, content: {} });\n\n // 受控优先:props.value 存在时读外部值,否则读内部状态\n const value = (): TabsValue | undefined => props.value ?? internalValue();\n\n const setValue = (next: TabsValue) => {\n // 受控模式:只通知外部,不改本地状态\n if (props.value !== undefined) {\n props.onValueChange?.(next);\n return;\n }\n setInternalValue(next);\n props.onValueChange?.(next);\n };\n\n const isSelected = (v: TabsValue) => value() === v;\n\n // 对齐 base-ui:激活值变化时,若焦点不在 tab 上,将高亮同步到激活 tab\n // (键盘 roving focus 过程中不覆盖,保持相对当前位置导航)\n createEffect(() => {\n const current = value();\n if (current === undefined) return;\n const active = document.activeElement as HTMLElement | null;\n if (active?.getAttribute(\"role\") !== \"tab\") {\n setHighlightedValue(current);\n }\n });\n\n const registerTrigger = (entry: TriggerEntry) => {\n setTriggerOrder((prev) => [...prev, entry]);\n return () =>\n setTriggerOrder((prev) => prev.filter((t) => t.value !== entry.value));\n };\n\n const isFirstEnabled = (v: TabsValue) => {\n const first = triggerOrder().find((t) => !t.disabled());\n return first?.value === v;\n };\n\n const isUsable = (v: TabsValue) =>\n triggerOrder().some((t) => t.value === v && !t.disabled());\n\n const setTriggerId = (v: TabsValue, id: string) =>\n setIds(\"trigger\", String(v), id);\n const getTriggerId = (v: TabsValue) => ids.trigger[String(v)];\n const setContentId = (v: TabsValue, id: string) =>\n setIds(\"content\", String(v), id);\n const getContentId = (v: TabsValue) => ids.content[String(v)];\n\n const contextValue: TabsContextValue = {\n value,\n setValue,\n isSelected,\n orientation: () => props.orientation,\n dir: () => props.dir,\n loop: () => props.loop,\n highlightedValue,\n setHighlightedValue,\n registerTrigger,\n getTriggers: () => triggerOrder(),\n isFirstEnabled,\n isUsable,\n setTriggerId,\n getTriggerId,\n setContentId,\n getContentId,\n };\n\n return (\n <TabsContext.Provider value={contextValue}>\n {props.children}\n </TabsContext.Provider>\n );\n}\n\nexport const useTabsContext = () => {\n const context = useContext(TabsContext);\n if (!context)\n throw new Error(\"useTabsContext must be used within a <Tabs> component\");\n return context;\n};\n"],"mappings":";;;;AAgDA,IAAM+B,IAAc/B,EAAgC;AAEpD,SAAgBgC,EACdC,GAQA;CACA,IAAM,CAACG,GAAeC,KAAoBnC,EACxC+B,EAAMC,YACR,GACM,CAACf,GAAkBC,KAAuBlB,EAE9C,GACI,CAACoC,GAAcC,KAAmBrC,EAA6B,CAAA,CAAE,GACjE,CAACsC,GAAKC,KAAUnC,EAGnB;EAAEoC,SAAS,CAAC;EAAGE,SAAS,CAAC;CAAE,CAAC,GAGzBnC,UAAqCwB,EAAMxB,SAAS2B,EAAc,GAElEtB,KAAY+B,MAAoB;EAEpC,IAAIZ,EAAMxB,UAAUqC,KAAAA,GAAW;GAC7Bb,EAAME,gBAAgBU,CAAI;GAC1B;EACF;EAEAZ,AADAI,EAAiBQ,CAAI,GACrBZ,EAAME,gBAAgBU,CAAI;CAC5B,GAEM9B,KAAcgC,MAAiBtC,EAAM,MAAMsC;CAIjD9C,QAAmB;EACjB,IAAM+C,IAAUvC,EAAM;EAClBuC,MAAYF,KAAAA,KACDI,SAASC,eACZC,aAAa,MAAM,MAAM,SACnChC,EAAoB4B,CAAO;CAE/B,CAAC;CAuBD,IAAMY,IAAiC;EACrCnD;EACAK;EACAC;EACAC,mBAAmBiB,EAAMjB;EACzBC,WAAWgB,EAAMhB;EACjBC,YAAYe,EAAMf;EAClBC;EACAC;EACAC,kBA9BuBC,OACvBiB,GAAiBc,MAAS,CAAC,GAAGA,GAAM/B,CAAK,CAAC,SAExCiB,GAAiBc,MAASA,EAAKC,QAAQC,MAAMA,EAAE9C,UAAUa,EAAMb,KAAK,CAAC;EA4BvEc,mBAAmBe,EAAa;EAChCd,iBA1BsBuB,MACRT,EAAa,CAAC,CAACmB,MAAMF,MAAM,CAACA,EAAE7C,SAAS,CAC9C8C,CAAAA,EAAO/C,UAAUsC;EAyBxBtB,WAtBgBsB,MAChBT,EAAa,CAAC,CAACoB,MAAMH,MAAMA,EAAE9C,UAAUsC,KAAK,CAACQ,EAAE7C,SAAS,CAAC;EAsBzDgB,eApBoBqB,GAAcpB,MAClCc,EAAO,WAAWkB,OAAOZ,CAAC,GAAGpB,CAAE;EAoB/BC,eAnBoBmB,MAAiBP,EAAIE,QAAQiB,OAAOZ,CAAC;EAoBzDlB,eAnBoBkB,GAAcpB,MAClCc,EAAO,WAAWkB,OAAOZ,CAAC,GAAGpB,CAAE;EAmB/BG,eAlBoBiB,MAAiBP,EAAII,QAAQe,OAAOZ,CAAC;CAmB3D;CAEA,OAAAc,EACG9B,EAAY+B,UAAQ;EAACrD,OAAOmD;EAAY,IAAAG,WAAA;GAAA,OACtC9B,EAAM8B;EAAQ;CAAA,CAAA;AAGrB;AAEA,IAAaC,UAAuB;CAClC,IAAMC,IAAU5D,EAAW0B,CAAW;CACtC,IAAI,CAACkC,GACH,MAAUC,MAAM,uDAAuD;CACzE,OAAOD;AACT"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { clsx as e } from "../../../utils/clsx.js";
|
|
2
|
+
import { TabsProvider as t } from "./Tabs.context.js";
|
|
3
|
+
import { createComponent as n, insert as r, mergeProps as i, spread as a, template as o } from "solid-js/web";
|
|
4
|
+
import { mergeProps as s, splitProps as c } from "solid-js";
|
|
5
|
+
//#region src/components/tabs/Tabs/Tabs.tsx
|
|
6
|
+
var l = /*#__PURE__*/ o("<div data-slot=tabs>"), u = (o) => {
|
|
7
|
+
let u = s({
|
|
8
|
+
orientation: "horizontal",
|
|
9
|
+
loop: !0,
|
|
10
|
+
dir: "ltr"
|
|
11
|
+
}, o), [d, f] = c(u, [
|
|
12
|
+
"defaultValue",
|
|
13
|
+
"value",
|
|
14
|
+
"onValueChange",
|
|
15
|
+
"orientation",
|
|
16
|
+
"loop",
|
|
17
|
+
"dir",
|
|
18
|
+
"class",
|
|
19
|
+
"classList",
|
|
20
|
+
"children"
|
|
21
|
+
]), p = () => d.orientation === "vertical";
|
|
22
|
+
return (() => {
|
|
23
|
+
var o = l();
|
|
24
|
+
return a(o, i({
|
|
25
|
+
get "data-orientation"() {
|
|
26
|
+
return d.orientation;
|
|
27
|
+
},
|
|
28
|
+
get "data-vertical"() {
|
|
29
|
+
return p() ? "" : null;
|
|
30
|
+
},
|
|
31
|
+
get "data-horizontal"() {
|
|
32
|
+
return p() ? null : "";
|
|
33
|
+
},
|
|
34
|
+
get dir() {
|
|
35
|
+
return d.dir;
|
|
36
|
+
},
|
|
37
|
+
get class() {
|
|
38
|
+
return e("group/tabs flex gap-2 data-[orientation=horizontal]:flex-col", d.class);
|
|
39
|
+
},
|
|
40
|
+
get classList() {
|
|
41
|
+
return d.classList;
|
|
42
|
+
}
|
|
43
|
+
}, f), !1, !0), r(o, n(t, {
|
|
44
|
+
get defaultValue() {
|
|
45
|
+
return d.defaultValue;
|
|
46
|
+
},
|
|
47
|
+
get value() {
|
|
48
|
+
return d.value;
|
|
49
|
+
},
|
|
50
|
+
get onValueChange() {
|
|
51
|
+
return d.onValueChange;
|
|
52
|
+
},
|
|
53
|
+
get orientation() {
|
|
54
|
+
return d.orientation;
|
|
55
|
+
},
|
|
56
|
+
get dir() {
|
|
57
|
+
return d.dir;
|
|
58
|
+
},
|
|
59
|
+
get loop() {
|
|
60
|
+
return d.loop;
|
|
61
|
+
},
|
|
62
|
+
get children() {
|
|
63
|
+
return d.children;
|
|
64
|
+
}
|
|
65
|
+
})), o;
|
|
66
|
+
})();
|
|
67
|
+
};
|
|
68
|
+
//#endregion
|
|
69
|
+
export { u as Tabs };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=Tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.js","names":["mergeProps","splitProps","TabsProps","clsx","TabsProvider","Tabs","props","merged","orientation","loop","dir","const","local","others","isVertical","_el$","_tmpl$","_$spread","_$mergeProps","data-orientation","data-vertical","data-horizontal","class","classList","_$insert","_$createComponent","defaultValue","value","onValueChange","children"],"sources":["../../../../src/components/tabs/Tabs/Tabs.tsx"],"sourcesContent":["import { mergeProps, splitProps } from \"solid-js\";\nimport type { TabsProps } from \"./Tabs.types\";\nimport { clsx } from \"~/utils\";\nimport { TabsProvider } from \"./Tabs.context\";\n\nexport const Tabs = (props: TabsProps) => {\n const merged = mergeProps(\n {\n orientation: \"horizontal\",\n loop: true,\n dir: \"ltr\",\n } as const,\n props,\n );\n const [local, others] = splitProps(merged, [\n \"defaultValue\",\n \"value\",\n \"onValueChange\",\n \"orientation\",\n \"loop\",\n \"dir\",\n \"class\",\n \"classList\",\n \"children\",\n ]);\n\n const isVertical = () => local.orientation === \"vertical\";\n\n return (\n <div\n data-slot=\"tabs\"\n data-orientation={local.orientation}\n // 现有样式依赖 group-data-vertical/tabs 与 group-data-horizontal/tabs,\n // 需要根元素上的 data-vertical / data-horizontal 属性才能生效\n data-vertical={isVertical() ? \"\" : null}\n data-horizontal={isVertical() ? null : \"\"}\n dir={local.dir}\n class={clsx(\n \"group/tabs flex gap-2 data-[orientation=horizontal]:flex-col\",\n local.class,\n )}\n classList={local.classList}\n {...others}\n >\n <TabsProvider\n defaultValue={local.defaultValue}\n value={local.value}\n onValueChange={local.onValueChange}\n orientation={local.orientation}\n dir={local.dir}\n loop={local.loop}\n >\n {local.children}\n </TabsProvider>\n </div>\n );\n};\n"],"mappings":";;;;;iDAKaK,KAAQC,MAAqB;CACxC,IAAMC,IAASP,EACb;EACEQ,aAAa;EACbC,MAAM;EACNC,KAAK;CACP,GACAJ,CACF,GACM,CAACM,GAAOC,KAAUZ,EAAWM,GAAQ;EACzC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAAU,CACX,GAEKO,UAAmBF,EAAMJ,gBAAgB;CAE/C,cAAA;EAAA,IAAAO,IAAAC,EAAA;EAwBqB,OAxBrBC,EAAAF,GAAAG,EAAA;GAAA,IAAA,qBAAA;IAAA,OAGsBN,EAAMJ;GAAW;GAAA,IAAA,kBAAA;IAAA,OAGpBM,EAAW,IAAI,KAAK;GAAI;GAAA,IAAA,oBAAA;IAAA,OACtBA,EAAW,IAAI,OAAO;GAAE;GAAA,IACzCJ,MAAG;IAAA,OAAEE,EAAMF;GAAG;GAAA,IAAA,QAAA;IAAA,OACPP,EACL,gEACAS,EAAMU,KACR;GAAC;GAAA,IACDC,YAAS;IAAA,OAAEX,EAAMW;GAAS;EAAA,GACtBV,CAAM,GAAA,IAAA,EAAA,GAAAW,EAAAT,GAAAU,EAETrB,GAAY;GAAA,IACXsB,eAAY;IAAA,OAAEd,EAAMc;GAAY;GAAA,IAChCC,QAAK;IAAA,OAAEf,EAAMe;GAAK;GAAA,IAClBC,gBAAa;IAAA,OAAEhB,EAAMgB;GAAa;GAAA,IAClCpB,cAAW;IAAA,OAAEI,EAAMJ;GAAW;GAAA,IAC9BE,MAAG;IAAA,OAAEE,EAAMF;GAAG;GAAA,IACdD,OAAI;IAAA,OAAEG,EAAMH;GAAI;GAAA,IAAAoB,WAAA;IAAA,OAEfjB,EAAMiB;GAAQ;EAAA,CAAA,CAAA,GAAAd;CAAA,EAAA,CAAA;AAIvB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseProps, PolymorphicProps } from '../../../types';
|
|
2
|
+
export type TabsValue = string | number;
|
|
3
|
+
interface BaseTabsProps extends BaseProps {
|
|
4
|
+
/** 非受控模式:初始激活值 */
|
|
5
|
+
defaultValue?: TabsValue;
|
|
6
|
+
/** 受控模式:激活值(提供后组件不再自管状态) */
|
|
7
|
+
value?: TabsValue;
|
|
8
|
+
/** 值变化回调(受控与非受控都会触发) */
|
|
9
|
+
onValueChange?: (value: TabsValue) => void;
|
|
10
|
+
/** 布局方向,默认 "horizontal" */
|
|
11
|
+
orientation?: "horizontal" | "vertical";
|
|
12
|
+
/** 方向键是否循环,默认 true */
|
|
13
|
+
loop?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export type TabsProps = PolymorphicProps<"div", BaseTabsProps, false>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/components/tabs/Tabs/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/tabs/Tabs/call-event-handler.ts"],"sourcesContent":["/**\n * 调用用户传入的事件处理器(兼容 Solid 的函数或函数数组形式)。\n * splitProps restKeys 提取出的事件类型是 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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TabsContextValue } from './Tabs.context';
|
|
2
|
+
/**
|
|
3
|
+
* tablist 的 roving focus 键盘导航(纯逻辑,可在事件中独立单测)
|
|
4
|
+
*
|
|
5
|
+
* 方向映射:
|
|
6
|
+
* - horizontal + ltr: ArrowRight → next, ArrowLeft → prev
|
|
7
|
+
* - horizontal + rtl: 左右反转
|
|
8
|
+
* - vertical: ArrowDown → next, ArrowUp → prev
|
|
9
|
+
* - Home → 第一个,End → 最后一个
|
|
10
|
+
* - loop=true 环绕,false 边界停止;跳过 disabled 的 trigger
|
|
11
|
+
*
|
|
12
|
+
* 与 base-ui 一致:方向键只移动焦点(触发 onFocus 更新高亮),不激活;
|
|
13
|
+
* 激活靠点击(Enter/Space 触发 button 的 click)。activateOnFocus 时的
|
|
14
|
+
* 聚焦激活由 TabsTrigger 的 onFocus 处理,这里不做。
|
|
15
|
+
*/
|
|
16
|
+
export declare function useTabsKeyboard(ctx: TabsContextValue): {
|
|
17
|
+
handleKeyDown: (e: KeyboardEvent) => void;
|
|
18
|
+
};
|