@huin-core/react-tabs 1.0.2 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.d.mts +66 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +245 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +213 -0
- package/dist/index.mjs.map +7 -0
- package/package.json +3 -2
package/dist/index.d.mts
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import React__default from 'react';
|
3
|
+
import { Primitive } from '@huin-core/react-primitive';
|
4
|
+
import * as RovingFocusGroup from '@huin-core/react-roving-focus';
|
5
|
+
|
6
|
+
type Scope<C = any> = {
|
7
|
+
[scopeName: string]: React.Context<C>[];
|
8
|
+
} | undefined;
|
9
|
+
type ScopeHook = (scope: Scope) => {
|
10
|
+
[__scopeProp: string]: Scope;
|
11
|
+
};
|
12
|
+
interface CreateScope {
|
13
|
+
scopeName: string;
|
14
|
+
(): ScopeHook;
|
15
|
+
}
|
16
|
+
|
17
|
+
declare const createTabsScope: CreateScope;
|
18
|
+
type RovingFocusGroupProps = React.ComponentPropsWithoutRef<typeof RovingFocusGroup.Root>;
|
19
|
+
type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
|
20
|
+
interface TabsProps extends PrimitiveDivProps {
|
21
|
+
/** The value for the selected tab, if controlled */
|
22
|
+
value?: string;
|
23
|
+
/** The value of the tab to select by default, if uncontrolled */
|
24
|
+
defaultValue?: string;
|
25
|
+
/** A function called when a new tab is selected */
|
26
|
+
onValueChange?: (value: string) => void;
|
27
|
+
/**
|
28
|
+
* The orientation the tabs are layed out.
|
29
|
+
* Mainly so arrow navigation is done accordingly (left & right vs. up & down)
|
30
|
+
* @defaultValue horizontal
|
31
|
+
*/
|
32
|
+
orientation?: RovingFocusGroupProps["orientation"];
|
33
|
+
/**
|
34
|
+
* The direction of navigation between toolbar items.
|
35
|
+
*/
|
36
|
+
dir?: RovingFocusGroupProps["dir"];
|
37
|
+
/**
|
38
|
+
* Whether a tab is activated automatically or manually.
|
39
|
+
* @defaultValue automatic
|
40
|
+
* */
|
41
|
+
activationMode?: "automatic" | "manual";
|
42
|
+
}
|
43
|
+
declare const Tabs: React.ForwardRefExoticComponent<TabsProps & React.RefAttributes<HTMLDivElement>>;
|
44
|
+
|
45
|
+
interface TabsListProps extends PrimitiveDivProps {
|
46
|
+
loop?: RovingFocusGroupProps["loop"];
|
47
|
+
}
|
48
|
+
declare const TabsList: React__default.ForwardRefExoticComponent<TabsListProps & React__default.RefAttributes<HTMLDivElement>>;
|
49
|
+
|
50
|
+
type PrimitiveButtonProps = React__default.ComponentPropsWithoutRef<typeof Primitive.button>;
|
51
|
+
interface TabsTriggerProps extends PrimitiveButtonProps {
|
52
|
+
value: string;
|
53
|
+
}
|
54
|
+
declare const TabsTrigger: React__default.ForwardRefExoticComponent<TabsTriggerProps & React__default.RefAttributes<HTMLButtonElement>>;
|
55
|
+
|
56
|
+
interface TabsContentProps extends PrimitiveDivProps {
|
57
|
+
value: string;
|
58
|
+
/**
|
59
|
+
* Used to force mounting when more control is needed. Useful when
|
60
|
+
* controlling animation with React animation libraries.
|
61
|
+
*/
|
62
|
+
forceMount?: true;
|
63
|
+
}
|
64
|
+
declare const TabsContent: React__default.ForwardRefExoticComponent<TabsContentProps & React__default.RefAttributes<HTMLDivElement>>;
|
65
|
+
|
66
|
+
export { Tabs, TabsContent, type TabsContentProps, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsTriggerProps, createTabsScope };
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import React__default from 'react';
|
3
|
+
import { Primitive } from '@huin-core/react-primitive';
|
4
|
+
import * as RovingFocusGroup from '@huin-core/react-roving-focus';
|
5
|
+
|
6
|
+
type Scope<C = any> = {
|
7
|
+
[scopeName: string]: React.Context<C>[];
|
8
|
+
} | undefined;
|
9
|
+
type ScopeHook = (scope: Scope) => {
|
10
|
+
[__scopeProp: string]: Scope;
|
11
|
+
};
|
12
|
+
interface CreateScope {
|
13
|
+
scopeName: string;
|
14
|
+
(): ScopeHook;
|
15
|
+
}
|
16
|
+
|
17
|
+
declare const createTabsScope: CreateScope;
|
18
|
+
type RovingFocusGroupProps = React.ComponentPropsWithoutRef<typeof RovingFocusGroup.Root>;
|
19
|
+
type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;
|
20
|
+
interface TabsProps extends PrimitiveDivProps {
|
21
|
+
/** The value for the selected tab, if controlled */
|
22
|
+
value?: string;
|
23
|
+
/** The value of the tab to select by default, if uncontrolled */
|
24
|
+
defaultValue?: string;
|
25
|
+
/** A function called when a new tab is selected */
|
26
|
+
onValueChange?: (value: string) => void;
|
27
|
+
/**
|
28
|
+
* The orientation the tabs are layed out.
|
29
|
+
* Mainly so arrow navigation is done accordingly (left & right vs. up & down)
|
30
|
+
* @defaultValue horizontal
|
31
|
+
*/
|
32
|
+
orientation?: RovingFocusGroupProps["orientation"];
|
33
|
+
/**
|
34
|
+
* The direction of navigation between toolbar items.
|
35
|
+
*/
|
36
|
+
dir?: RovingFocusGroupProps["dir"];
|
37
|
+
/**
|
38
|
+
* Whether a tab is activated automatically or manually.
|
39
|
+
* @defaultValue automatic
|
40
|
+
* */
|
41
|
+
activationMode?: "automatic" | "manual";
|
42
|
+
}
|
43
|
+
declare const Tabs: React.ForwardRefExoticComponent<TabsProps & React.RefAttributes<HTMLDivElement>>;
|
44
|
+
|
45
|
+
interface TabsListProps extends PrimitiveDivProps {
|
46
|
+
loop?: RovingFocusGroupProps["loop"];
|
47
|
+
}
|
48
|
+
declare const TabsList: React__default.ForwardRefExoticComponent<TabsListProps & React__default.RefAttributes<HTMLDivElement>>;
|
49
|
+
|
50
|
+
type PrimitiveButtonProps = React__default.ComponentPropsWithoutRef<typeof Primitive.button>;
|
51
|
+
interface TabsTriggerProps extends PrimitiveButtonProps {
|
52
|
+
value: string;
|
53
|
+
}
|
54
|
+
declare const TabsTrigger: React__default.ForwardRefExoticComponent<TabsTriggerProps & React__default.RefAttributes<HTMLButtonElement>>;
|
55
|
+
|
56
|
+
interface TabsContentProps extends PrimitiveDivProps {
|
57
|
+
value: string;
|
58
|
+
/**
|
59
|
+
* Used to force mounting when more control is needed. Useful when
|
60
|
+
* controlling animation with React animation libraries.
|
61
|
+
*/
|
62
|
+
forceMount?: true;
|
63
|
+
}
|
64
|
+
declare const TabsContent: React__default.ForwardRefExoticComponent<TabsContentProps & React__default.RefAttributes<HTMLDivElement>>;
|
65
|
+
|
66
|
+
export { Tabs, TabsContent, type TabsContentProps, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsTriggerProps, createTabsScope };
|
package/dist/index.js
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
"use strict";
|
2
|
+
"use client";
|
3
|
+
var __create = Object.create;
|
4
|
+
var __defProp = Object.defineProperty;
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
9
|
+
var __export = (target, all) => {
|
10
|
+
for (var name in all)
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
12
|
+
};
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
15
|
+
for (let key of __getOwnPropNames(from))
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
18
|
+
}
|
19
|
+
return to;
|
20
|
+
};
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
27
|
+
mod
|
28
|
+
));
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
30
|
+
|
31
|
+
// packages/react/tabs/src/index.ts
|
32
|
+
var src_exports = {};
|
33
|
+
__export(src_exports, {
|
34
|
+
Tabs: () => Tabs,
|
35
|
+
TabsContent: () => TabsContent,
|
36
|
+
TabsList: () => TabsList,
|
37
|
+
TabsTrigger: () => TabsTrigger,
|
38
|
+
createTabsScope: () => createTabsScope
|
39
|
+
});
|
40
|
+
module.exports = __toCommonJS(src_exports);
|
41
|
+
|
42
|
+
// packages/react/tabs/src/Tabs.tsx
|
43
|
+
var React = __toESM(require("react"));
|
44
|
+
var import_react_context = require("@huin-core/react-context");
|
45
|
+
var import_react_roving_focus = require("@huin-core/react-roving-focus");
|
46
|
+
var import_react_primitive = require("@huin-core/react-primitive");
|
47
|
+
var import_react_direction = require("@huin-core/react-direction");
|
48
|
+
var import_react_use_controllable_state = require("@huin-core/react-use-controllable-state");
|
49
|
+
var import_react_id = require("@huin-core/react-id");
|
50
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
51
|
+
var TABS_NAME = "Tabs";
|
52
|
+
var [createTabsContext, createTabsScope] = (0, import_react_context.createContextScope)(TABS_NAME, [
|
53
|
+
import_react_roving_focus.createRovingFocusGroupScope
|
54
|
+
]);
|
55
|
+
var [TabsProvider, useTabsContext] = createTabsContext(TABS_NAME);
|
56
|
+
var Tabs = React.forwardRef(
|
57
|
+
(props, forwardedRef) => {
|
58
|
+
const {
|
59
|
+
__scopeTabs,
|
60
|
+
value: valueProp,
|
61
|
+
onValueChange,
|
62
|
+
defaultValue,
|
63
|
+
orientation = "horizontal",
|
64
|
+
dir,
|
65
|
+
activationMode = "automatic",
|
66
|
+
...tabsProps
|
67
|
+
} = props;
|
68
|
+
const direction = (0, import_react_direction.useDirection)(dir);
|
69
|
+
const [value, setValue] = (0, import_react_use_controllable_state.useControllableState)({
|
70
|
+
prop: valueProp,
|
71
|
+
onChange: onValueChange,
|
72
|
+
defaultProp: defaultValue
|
73
|
+
});
|
74
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
75
|
+
TabsProvider,
|
76
|
+
{
|
77
|
+
scope: __scopeTabs,
|
78
|
+
baseId: (0, import_react_id.useId)(),
|
79
|
+
value,
|
80
|
+
onValueChange: setValue,
|
81
|
+
orientation,
|
82
|
+
dir: direction,
|
83
|
+
activationMode,
|
84
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
85
|
+
import_react_primitive.Primitive.div,
|
86
|
+
{
|
87
|
+
dir: direction,
|
88
|
+
"data-orientation": orientation,
|
89
|
+
...tabsProps,
|
90
|
+
ref: forwardedRef
|
91
|
+
}
|
92
|
+
)
|
93
|
+
}
|
94
|
+
);
|
95
|
+
}
|
96
|
+
);
|
97
|
+
Tabs.displayName = TABS_NAME;
|
98
|
+
|
99
|
+
// packages/react/tabs/src/TabsList.tsx
|
100
|
+
var import_react = __toESM(require("react"));
|
101
|
+
var import_react_primitive2 = require("@huin-core/react-primitive");
|
102
|
+
var import_react_roving_focus2 = require("@huin-core/react-roving-focus");
|
103
|
+
var RovingFocusGroup = __toESM(require("@huin-core/react-roving-focus"));
|
104
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
105
|
+
var TAB_LIST_NAME = "TabsList";
|
106
|
+
var useRovingFocusGroupScope = (0, import_react_roving_focus2.createRovingFocusGroupScope)();
|
107
|
+
var TabsList = import_react.default.forwardRef(
|
108
|
+
(props, forwardedRef) => {
|
109
|
+
const { __scopeTabs, loop = true, ...listProps } = props;
|
110
|
+
const context = useTabsContext(TAB_LIST_NAME, __scopeTabs);
|
111
|
+
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);
|
112
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
113
|
+
RovingFocusGroup.Root,
|
114
|
+
{
|
115
|
+
asChild: true,
|
116
|
+
...rovingFocusGroupScope,
|
117
|
+
orientation: context.orientation,
|
118
|
+
dir: context.dir,
|
119
|
+
loop,
|
120
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
121
|
+
import_react_primitive2.Primitive.div,
|
122
|
+
{
|
123
|
+
role: "tablist",
|
124
|
+
"aria-orientation": context.orientation,
|
125
|
+
...listProps,
|
126
|
+
ref: forwardedRef
|
127
|
+
}
|
128
|
+
)
|
129
|
+
}
|
130
|
+
);
|
131
|
+
}
|
132
|
+
);
|
133
|
+
TabsList.displayName = TAB_LIST_NAME;
|
134
|
+
|
135
|
+
// packages/react/tabs/src/TabsTrigger.tsx
|
136
|
+
var import_react3 = __toESM(require("react"));
|
137
|
+
var import_react_primitive4 = require("@huin-core/react-primitive");
|
138
|
+
|
139
|
+
// packages/react/tabs/src/TabsContent.tsx
|
140
|
+
var import_react2 = __toESM(require("react"));
|
141
|
+
var import_react_primitive3 = require("@huin-core/react-primitive");
|
142
|
+
var import_react_presence = require("@huin-core/react-presence");
|
143
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
144
|
+
var CONTENT_NAME = "TabsContent";
|
145
|
+
var TabsContent = import_react2.default.forwardRef(
|
146
|
+
(props, forwardedRef) => {
|
147
|
+
const { __scopeTabs, value, forceMount, children, ...contentProps } = props;
|
148
|
+
const context = useTabsContext(CONTENT_NAME, __scopeTabs);
|
149
|
+
const triggerId = makeTriggerId(context.baseId, value);
|
150
|
+
const contentId = makeContentId(context.baseId, value);
|
151
|
+
const isSelected = value === context.value;
|
152
|
+
const isMountAnimationPreventedRef = import_react2.default.useRef(isSelected);
|
153
|
+
import_react2.default.useEffect(() => {
|
154
|
+
const rAF = requestAnimationFrame(
|
155
|
+
() => isMountAnimationPreventedRef.current = false
|
156
|
+
);
|
157
|
+
return () => cancelAnimationFrame(rAF);
|
158
|
+
}, []);
|
159
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_presence.Presence, { present: forceMount || isSelected, children: ({ present }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
160
|
+
import_react_primitive3.Primitive.div,
|
161
|
+
{
|
162
|
+
"data-state": isSelected ? "active" : "inactive",
|
163
|
+
"data-orientation": context.orientation,
|
164
|
+
role: "tabpanel",
|
165
|
+
"aria-labelledby": triggerId,
|
166
|
+
hidden: !present,
|
167
|
+
id: contentId,
|
168
|
+
tabIndex: 0,
|
169
|
+
...contentProps,
|
170
|
+
ref: forwardedRef,
|
171
|
+
style: {
|
172
|
+
...props.style,
|
173
|
+
animationDuration: isMountAnimationPreventedRef.current ? "0s" : void 0
|
174
|
+
},
|
175
|
+
children: present && children
|
176
|
+
}
|
177
|
+
) });
|
178
|
+
}
|
179
|
+
);
|
180
|
+
TabsContent.displayName = CONTENT_NAME;
|
181
|
+
function makeTriggerId(baseId, value) {
|
182
|
+
return `${baseId}-trigger-${value}`;
|
183
|
+
}
|
184
|
+
function makeContentId(baseId, value) {
|
185
|
+
return `${baseId}-content-${value}`;
|
186
|
+
}
|
187
|
+
|
188
|
+
// packages/react/tabs/src/TabsTrigger.tsx
|
189
|
+
var RovingFocusGroup2 = __toESM(require("@huin-core/react-roving-focus"));
|
190
|
+
var import_primitive = require("@huin-core/primitive");
|
191
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
192
|
+
var TRIGGER_NAME = "TabsTrigger";
|
193
|
+
var TabsTrigger = import_react3.default.forwardRef(
|
194
|
+
(props, forwardedRef) => {
|
195
|
+
const { __scopeTabs, value, disabled = false, ...triggerProps } = props;
|
196
|
+
const context = useTabsContext(TRIGGER_NAME, __scopeTabs);
|
197
|
+
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);
|
198
|
+
const triggerId = makeTriggerId(context.baseId, value);
|
199
|
+
const contentId = makeContentId(context.baseId, value);
|
200
|
+
const isSelected = value === context.value;
|
201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
202
|
+
RovingFocusGroup2.Item,
|
203
|
+
{
|
204
|
+
asChild: true,
|
205
|
+
...rovingFocusGroupScope,
|
206
|
+
focusable: !disabled,
|
207
|
+
active: isSelected,
|
208
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
209
|
+
import_react_primitive4.Primitive.button,
|
210
|
+
{
|
211
|
+
type: "button",
|
212
|
+
role: "tab",
|
213
|
+
"aria-selected": isSelected,
|
214
|
+
"aria-controls": contentId,
|
215
|
+
"data-state": isSelected ? "active" : "inactive",
|
216
|
+
"data-disabled": disabled ? "" : void 0,
|
217
|
+
disabled,
|
218
|
+
id: triggerId,
|
219
|
+
...triggerProps,
|
220
|
+
ref: forwardedRef,
|
221
|
+
onMouseDown: (0, import_primitive.composeEventHandlers)(props.onMouseDown, (event) => {
|
222
|
+
if (!disabled && event.button === 0 && event.ctrlKey === false) {
|
223
|
+
context.onValueChange(value);
|
224
|
+
} else {
|
225
|
+
event.preventDefault();
|
226
|
+
}
|
227
|
+
}),
|
228
|
+
onKeyDown: (0, import_primitive.composeEventHandlers)(props.onKeyDown, (event) => {
|
229
|
+
if ([" ", "Enter"].includes(event.key))
|
230
|
+
context.onValueChange(value);
|
231
|
+
}),
|
232
|
+
onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, () => {
|
233
|
+
const isAutomaticActivation = context.activationMode !== "manual";
|
234
|
+
if (!isSelected && !disabled && isAutomaticActivation) {
|
235
|
+
context.onValueChange(value);
|
236
|
+
}
|
237
|
+
})
|
238
|
+
}
|
239
|
+
)
|
240
|
+
}
|
241
|
+
);
|
242
|
+
}
|
243
|
+
);
|
244
|
+
TabsTrigger.displayName = TRIGGER_NAME;
|
245
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../src/index.ts", "../src/Tabs.tsx", "../src/TabsList.tsx", "../src/TabsTrigger.tsx", "../src/TabsContent.tsx"],
|
4
|
+
"sourcesContent": ["\"use client\";\nexport { createTabsScope, Tabs } from \"./Tabs\";\nexport { TabsList } from \"./TabsList\";\nexport { TabsTrigger } from \"./TabsTrigger\";\nexport { TabsContent } from \"./TabsContent\";\n\nexport type { TabsProps } from \"./Tabs\";\nexport type { TabsListProps } from \"./TabsList\";\nexport type { TabsTriggerProps } from \"./TabsTrigger\";\nexport type { TabsContentProps } from \"./TabsContent\";\n", "import * as React from \"react\";\nimport { createContextScope } from \"@huin-core/react-context\";\nimport { createRovingFocusGroupScope } from \"@huin-core/react-roving-focus\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport * as RovingFocusGroup from \"@huin-core/react-roving-focus\";\nimport { useDirection } from \"@huin-core/react-direction\";\nimport { useControllableState } from \"@huin-core/react-use-controllable-state\";\nimport { useId } from \"@huin-core/react-id\";\nimport type { Scope } from \"@huin-core/react-context\";\n\n/* -------------------------------------------------------------------------------------------------\n * Tabs\n * -----------------------------------------------------------------------------------------------*/\n\nconst TABS_NAME = \"Tabs\";\n\nexport type ScopedProps<P> = P & { __scopeTabs?: Scope };\nconst [createTabsContext, createTabsScope] = createContextScope(TABS_NAME, [\n createRovingFocusGroupScope,\n]);\n\ntype TabsContextValue = {\n baseId: string;\n value?: string;\n onValueChange: (value: string) => void;\n orientation?: TabsProps[\"orientation\"];\n dir?: TabsProps[\"dir\"];\n activationMode?: TabsProps[\"activationMode\"];\n};\n\nexport const [TabsProvider, useTabsContext] =\n createTabsContext<TabsContextValue>(TABS_NAME);\n\ntype TabsElement = React.ElementRef<typeof Primitive.div>;\nexport type RovingFocusGroupProps = React.ComponentPropsWithoutRef<\n typeof RovingFocusGroup.Root\n>;\nexport type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface TabsProps extends PrimitiveDivProps {\n /** The value for the selected tab, if controlled */\n value?: string;\n /** The value of the tab to select by default, if uncontrolled */\n defaultValue?: string;\n /** A function called when a new tab is selected */\n onValueChange?: (value: string) => void;\n /**\n * The orientation the tabs are layed out.\n * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n * @defaultValue horizontal\n */\n orientation?: RovingFocusGroupProps[\"orientation\"];\n /**\n * The direction of navigation between toolbar items.\n */\n dir?: RovingFocusGroupProps[\"dir\"];\n /**\n * Whether a tab is activated automatically or manually.\n * @defaultValue automatic\n * */\n activationMode?: \"automatic\" | \"manual\";\n}\n\nconst Tabs = React.forwardRef<TabsElement, TabsProps>(\n (props: ScopedProps<TabsProps>, forwardedRef) => {\n const {\n __scopeTabs,\n value: valueProp,\n onValueChange,\n defaultValue,\n orientation = \"horizontal\",\n dir,\n activationMode = \"automatic\",\n ...tabsProps\n } = props;\n const direction = useDirection(dir);\n const [value, setValue] = useControllableState({\n prop: valueProp,\n onChange: onValueChange,\n defaultProp: defaultValue,\n });\n\n return (\n <TabsProvider\n scope={__scopeTabs}\n baseId={useId()}\n value={value}\n onValueChange={setValue}\n orientation={orientation}\n dir={direction}\n activationMode={activationMode}\n >\n <Primitive.div\n dir={direction}\n data-orientation={orientation}\n {...tabsProps}\n ref={forwardedRef}\n />\n </TabsProvider>\n );\n }\n);\n\nTabs.displayName = TABS_NAME;\n\nconst Root = Tabs;\n\nexport {\n createTabsScope,\n //\n Tabs,\n //\n Root,\n};\nexport type { TabsProps };\n", "import React from \"react\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport {\n PrimitiveDivProps,\n RovingFocusGroupProps,\n ScopedProps,\n useTabsContext,\n} from \"./Tabs\";\nimport { createRovingFocusGroupScope } from \"@huin-core/react-roving-focus\";\nimport * as RovingFocusGroup from \"@huin-core/react-roving-focus\";\n\nconst TAB_LIST_NAME = \"TabsList\";\n\ntype TabsListElement = React.ElementRef<typeof Primitive.div>;\ninterface TabsListProps extends PrimitiveDivProps {\n loop?: RovingFocusGroupProps[\"loop\"];\n}\nexport const useRovingFocusGroupScope = createRovingFocusGroupScope();\n\nconst TabsList = React.forwardRef<TabsListElement, TabsListProps>(\n (props: ScopedProps<TabsListProps>, forwardedRef) => {\n const { __scopeTabs, loop = true, ...listProps } = props;\n const context = useTabsContext(TAB_LIST_NAME, __scopeTabs);\n const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);\n return (\n <RovingFocusGroup.Root\n asChild\n {...rovingFocusGroupScope}\n orientation={context.orientation}\n dir={context.dir}\n loop={loop}\n >\n <Primitive.div\n role=\"tablist\"\n aria-orientation={context.orientation}\n {...listProps}\n ref={forwardedRef}\n />\n </RovingFocusGroup.Root>\n );\n }\n);\n\nTabsList.displayName = TAB_LIST_NAME;\n\nexport { TabsList };\nexport type { TabsListProps };\n", "import React from \"react\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport { ScopedProps, useTabsContext } from \"./Tabs\";\nimport { useRovingFocusGroupScope } from \"./TabsList\";\nimport { makeContentId, makeTriggerId } from \"./TabsContent\";\nimport * as RovingFocusGroup from \"@huin-core/react-roving-focus\";\nimport { composeEventHandlers } from \"@huin-core/primitive\";\n\nconst TRIGGER_NAME = \"TabsTrigger\";\n\ntype TabsTriggerElement = React.ElementRef<typeof Primitive.button>;\ntype PrimitiveButtonProps = React.ComponentPropsWithoutRef<\n typeof Primitive.button\n>;\ninterface TabsTriggerProps extends PrimitiveButtonProps {\n value: string;\n}\n\nconst TabsTrigger = React.forwardRef<TabsTriggerElement, TabsTriggerProps>(\n (props: ScopedProps<TabsTriggerProps>, forwardedRef) => {\n const { __scopeTabs, value, disabled = false, ...triggerProps } = props;\n const context = useTabsContext(TRIGGER_NAME, __scopeTabs);\n const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);\n const triggerId = makeTriggerId(context.baseId, value);\n const contentId = makeContentId(context.baseId, value);\n const isSelected = value === context.value;\n return (\n <RovingFocusGroup.Item\n asChild\n {...rovingFocusGroupScope}\n focusable={!disabled}\n active={isSelected}\n >\n <Primitive.button\n type=\"button\"\n role=\"tab\"\n aria-selected={isSelected}\n aria-controls={contentId}\n data-state={isSelected ? \"active\" : \"inactive\"}\n data-disabled={disabled ? \"\" : undefined}\n disabled={disabled}\n id={triggerId}\n {...triggerProps}\n ref={forwardedRef}\n onMouseDown={composeEventHandlers(props.onMouseDown, (event) => {\n // only call handler if it's the left button (mousedown gets triggered by all mouse buttons)\n // but not when the control key is pressed (avoiding MacOS right click)\n if (!disabled && event.button === 0 && event.ctrlKey === false) {\n context.onValueChange(value);\n } else {\n // prevent focus to avoid accidental activation\n event.preventDefault();\n }\n })}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if ([\" \", \"Enter\"].includes(event.key))\n context.onValueChange(value);\n })}\n onFocus={composeEventHandlers(props.onFocus, () => {\n // handle \"automatic\" activation if necessary\n // ie. activate tab following focus\n const isAutomaticActivation = context.activationMode !== \"manual\";\n if (!isSelected && !disabled && isAutomaticActivation) {\n context.onValueChange(value);\n }\n })}\n />\n </RovingFocusGroup.Item>\n );\n }\n);\n\nTabsTrigger.displayName = TRIGGER_NAME;\n\nexport { TabsTrigger };\nexport type { TabsTriggerProps };\n", "import React from \"react\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport { PrimitiveDivProps, ScopedProps, useTabsContext } from \"./Tabs\";\nimport { Presence } from \"@huin-core/react-presence\";\n\nconst CONTENT_NAME = \"TabsContent\";\n\ntype TabsContentElement = React.ElementRef<typeof Primitive.div>;\ninterface TabsContentProps extends PrimitiveDivProps {\n value: string;\n\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with React animation libraries.\n */\n forceMount?: true;\n}\n\nconst TabsContent = React.forwardRef<TabsContentElement, TabsContentProps>(\n (props: ScopedProps<TabsContentProps>, forwardedRef) => {\n const { __scopeTabs, value, forceMount, children, ...contentProps } = props;\n const context = useTabsContext(CONTENT_NAME, __scopeTabs);\n const triggerId = makeTriggerId(context.baseId, value);\n const contentId = makeContentId(context.baseId, value);\n const isSelected = value === context.value;\n const isMountAnimationPreventedRef = React.useRef(isSelected);\n\n React.useEffect(() => {\n const rAF = requestAnimationFrame(\n () => (isMountAnimationPreventedRef.current = false)\n );\n return () => cancelAnimationFrame(rAF);\n }, []);\n return (\n <Presence present={forceMount || isSelected}>\n {({ present }) => (\n <Primitive.div\n data-state={isSelected ? \"active\" : \"inactive\"}\n data-orientation={context.orientation}\n role=\"tabpanel\"\n aria-labelledby={triggerId}\n hidden={!present}\n id={contentId}\n tabIndex={0}\n {...contentProps}\n ref={forwardedRef}\n style={{\n ...props.style,\n animationDuration: isMountAnimationPreventedRef.current\n ? \"0s\"\n : undefined,\n }}\n >\n {present && children}\n </Primitive.div>\n )}\n </Presence>\n );\n }\n);\n\nTabsContent.displayName = CONTENT_NAME;\n\n/* ---------------------------------------------------------------------------------------------- */\n\nexport function makeTriggerId(baseId: string, value: string) {\n return `${baseId}-trigger-${value}`;\n}\nexport function makeContentId(baseId: string, value: string) {\n return `${baseId}-content-${value}`;\n}\n\nexport { TabsContent };\nexport type { TabsContentProps };\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["import_react_primitive", "import_react_roving_focus", "import_jsx_runtime", "React", "import_react", "import_react_primitive", "import_react", "import_react_primitive", "import_jsx_runtime", "React", "RovingFocusGroup", "import_jsx_runtime", "React"]
|
7
|
+
}
|
package/dist/index.mjs
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
// packages/react/tabs/src/Tabs.tsx
|
4
|
+
import * as React from "react";
|
5
|
+
import { createContextScope } from "@huin-core/react-context";
|
6
|
+
import { createRovingFocusGroupScope } from "@huin-core/react-roving-focus";
|
7
|
+
import { Primitive } from "@huin-core/react-primitive";
|
8
|
+
import { useDirection } from "@huin-core/react-direction";
|
9
|
+
import { useControllableState } from "@huin-core/react-use-controllable-state";
|
10
|
+
import { useId } from "@huin-core/react-id";
|
11
|
+
import { jsx } from "react/jsx-runtime";
|
12
|
+
var TABS_NAME = "Tabs";
|
13
|
+
var [createTabsContext, createTabsScope] = createContextScope(TABS_NAME, [
|
14
|
+
createRovingFocusGroupScope
|
15
|
+
]);
|
16
|
+
var [TabsProvider, useTabsContext] = createTabsContext(TABS_NAME);
|
17
|
+
var Tabs = React.forwardRef(
|
18
|
+
(props, forwardedRef) => {
|
19
|
+
const {
|
20
|
+
__scopeTabs,
|
21
|
+
value: valueProp,
|
22
|
+
onValueChange,
|
23
|
+
defaultValue,
|
24
|
+
orientation = "horizontal",
|
25
|
+
dir,
|
26
|
+
activationMode = "automatic",
|
27
|
+
...tabsProps
|
28
|
+
} = props;
|
29
|
+
const direction = useDirection(dir);
|
30
|
+
const [value, setValue] = useControllableState({
|
31
|
+
prop: valueProp,
|
32
|
+
onChange: onValueChange,
|
33
|
+
defaultProp: defaultValue
|
34
|
+
});
|
35
|
+
return /* @__PURE__ */ jsx(
|
36
|
+
TabsProvider,
|
37
|
+
{
|
38
|
+
scope: __scopeTabs,
|
39
|
+
baseId: useId(),
|
40
|
+
value,
|
41
|
+
onValueChange: setValue,
|
42
|
+
orientation,
|
43
|
+
dir: direction,
|
44
|
+
activationMode,
|
45
|
+
children: /* @__PURE__ */ jsx(
|
46
|
+
Primitive.div,
|
47
|
+
{
|
48
|
+
dir: direction,
|
49
|
+
"data-orientation": orientation,
|
50
|
+
...tabsProps,
|
51
|
+
ref: forwardedRef
|
52
|
+
}
|
53
|
+
)
|
54
|
+
}
|
55
|
+
);
|
56
|
+
}
|
57
|
+
);
|
58
|
+
Tabs.displayName = TABS_NAME;
|
59
|
+
|
60
|
+
// packages/react/tabs/src/TabsList.tsx
|
61
|
+
import React2 from "react";
|
62
|
+
import { Primitive as Primitive2 } from "@huin-core/react-primitive";
|
63
|
+
import { createRovingFocusGroupScope as createRovingFocusGroupScope2 } from "@huin-core/react-roving-focus";
|
64
|
+
import * as RovingFocusGroup from "@huin-core/react-roving-focus";
|
65
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
66
|
+
var TAB_LIST_NAME = "TabsList";
|
67
|
+
var useRovingFocusGroupScope = createRovingFocusGroupScope2();
|
68
|
+
var TabsList = React2.forwardRef(
|
69
|
+
(props, forwardedRef) => {
|
70
|
+
const { __scopeTabs, loop = true, ...listProps } = props;
|
71
|
+
const context = useTabsContext(TAB_LIST_NAME, __scopeTabs);
|
72
|
+
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);
|
73
|
+
return /* @__PURE__ */ jsx2(
|
74
|
+
RovingFocusGroup.Root,
|
75
|
+
{
|
76
|
+
asChild: true,
|
77
|
+
...rovingFocusGroupScope,
|
78
|
+
orientation: context.orientation,
|
79
|
+
dir: context.dir,
|
80
|
+
loop,
|
81
|
+
children: /* @__PURE__ */ jsx2(
|
82
|
+
Primitive2.div,
|
83
|
+
{
|
84
|
+
role: "tablist",
|
85
|
+
"aria-orientation": context.orientation,
|
86
|
+
...listProps,
|
87
|
+
ref: forwardedRef
|
88
|
+
}
|
89
|
+
)
|
90
|
+
}
|
91
|
+
);
|
92
|
+
}
|
93
|
+
);
|
94
|
+
TabsList.displayName = TAB_LIST_NAME;
|
95
|
+
|
96
|
+
// packages/react/tabs/src/TabsTrigger.tsx
|
97
|
+
import React4 from "react";
|
98
|
+
import { Primitive as Primitive4 } from "@huin-core/react-primitive";
|
99
|
+
|
100
|
+
// packages/react/tabs/src/TabsContent.tsx
|
101
|
+
import React3 from "react";
|
102
|
+
import { Primitive as Primitive3 } from "@huin-core/react-primitive";
|
103
|
+
import { Presence } from "@huin-core/react-presence";
|
104
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
105
|
+
var CONTENT_NAME = "TabsContent";
|
106
|
+
var TabsContent = React3.forwardRef(
|
107
|
+
(props, forwardedRef) => {
|
108
|
+
const { __scopeTabs, value, forceMount, children, ...contentProps } = props;
|
109
|
+
const context = useTabsContext(CONTENT_NAME, __scopeTabs);
|
110
|
+
const triggerId = makeTriggerId(context.baseId, value);
|
111
|
+
const contentId = makeContentId(context.baseId, value);
|
112
|
+
const isSelected = value === context.value;
|
113
|
+
const isMountAnimationPreventedRef = React3.useRef(isSelected);
|
114
|
+
React3.useEffect(() => {
|
115
|
+
const rAF = requestAnimationFrame(
|
116
|
+
() => isMountAnimationPreventedRef.current = false
|
117
|
+
);
|
118
|
+
return () => cancelAnimationFrame(rAF);
|
119
|
+
}, []);
|
120
|
+
return /* @__PURE__ */ jsx3(Presence, { present: forceMount || isSelected, children: ({ present }) => /* @__PURE__ */ jsx3(
|
121
|
+
Primitive3.div,
|
122
|
+
{
|
123
|
+
"data-state": isSelected ? "active" : "inactive",
|
124
|
+
"data-orientation": context.orientation,
|
125
|
+
role: "tabpanel",
|
126
|
+
"aria-labelledby": triggerId,
|
127
|
+
hidden: !present,
|
128
|
+
id: contentId,
|
129
|
+
tabIndex: 0,
|
130
|
+
...contentProps,
|
131
|
+
ref: forwardedRef,
|
132
|
+
style: {
|
133
|
+
...props.style,
|
134
|
+
animationDuration: isMountAnimationPreventedRef.current ? "0s" : void 0
|
135
|
+
},
|
136
|
+
children: present && children
|
137
|
+
}
|
138
|
+
) });
|
139
|
+
}
|
140
|
+
);
|
141
|
+
TabsContent.displayName = CONTENT_NAME;
|
142
|
+
function makeTriggerId(baseId, value) {
|
143
|
+
return `${baseId}-trigger-${value}`;
|
144
|
+
}
|
145
|
+
function makeContentId(baseId, value) {
|
146
|
+
return `${baseId}-content-${value}`;
|
147
|
+
}
|
148
|
+
|
149
|
+
// packages/react/tabs/src/TabsTrigger.tsx
|
150
|
+
import * as RovingFocusGroup2 from "@huin-core/react-roving-focus";
|
151
|
+
import { composeEventHandlers } from "@huin-core/primitive";
|
152
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
153
|
+
var TRIGGER_NAME = "TabsTrigger";
|
154
|
+
var TabsTrigger = React4.forwardRef(
|
155
|
+
(props, forwardedRef) => {
|
156
|
+
const { __scopeTabs, value, disabled = false, ...triggerProps } = props;
|
157
|
+
const context = useTabsContext(TRIGGER_NAME, __scopeTabs);
|
158
|
+
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);
|
159
|
+
const triggerId = makeTriggerId(context.baseId, value);
|
160
|
+
const contentId = makeContentId(context.baseId, value);
|
161
|
+
const isSelected = value === context.value;
|
162
|
+
return /* @__PURE__ */ jsx4(
|
163
|
+
RovingFocusGroup2.Item,
|
164
|
+
{
|
165
|
+
asChild: true,
|
166
|
+
...rovingFocusGroupScope,
|
167
|
+
focusable: !disabled,
|
168
|
+
active: isSelected,
|
169
|
+
children: /* @__PURE__ */ jsx4(
|
170
|
+
Primitive4.button,
|
171
|
+
{
|
172
|
+
type: "button",
|
173
|
+
role: "tab",
|
174
|
+
"aria-selected": isSelected,
|
175
|
+
"aria-controls": contentId,
|
176
|
+
"data-state": isSelected ? "active" : "inactive",
|
177
|
+
"data-disabled": disabled ? "" : void 0,
|
178
|
+
disabled,
|
179
|
+
id: triggerId,
|
180
|
+
...triggerProps,
|
181
|
+
ref: forwardedRef,
|
182
|
+
onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
|
183
|
+
if (!disabled && event.button === 0 && event.ctrlKey === false) {
|
184
|
+
context.onValueChange(value);
|
185
|
+
} else {
|
186
|
+
event.preventDefault();
|
187
|
+
}
|
188
|
+
}),
|
189
|
+
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
190
|
+
if ([" ", "Enter"].includes(event.key))
|
191
|
+
context.onValueChange(value);
|
192
|
+
}),
|
193
|
+
onFocus: composeEventHandlers(props.onFocus, () => {
|
194
|
+
const isAutomaticActivation = context.activationMode !== "manual";
|
195
|
+
if (!isSelected && !disabled && isAutomaticActivation) {
|
196
|
+
context.onValueChange(value);
|
197
|
+
}
|
198
|
+
})
|
199
|
+
}
|
200
|
+
)
|
201
|
+
}
|
202
|
+
);
|
203
|
+
}
|
204
|
+
);
|
205
|
+
TabsTrigger.displayName = TRIGGER_NAME;
|
206
|
+
export {
|
207
|
+
Tabs,
|
208
|
+
TabsContent,
|
209
|
+
TabsList,
|
210
|
+
TabsTrigger,
|
211
|
+
createTabsScope
|
212
|
+
};
|
213
|
+
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../src/Tabs.tsx", "../src/TabsList.tsx", "../src/TabsTrigger.tsx", "../src/TabsContent.tsx"],
|
4
|
+
"sourcesContent": ["import * as React from \"react\";\nimport { createContextScope } from \"@huin-core/react-context\";\nimport { createRovingFocusGroupScope } from \"@huin-core/react-roving-focus\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport * as RovingFocusGroup from \"@huin-core/react-roving-focus\";\nimport { useDirection } from \"@huin-core/react-direction\";\nimport { useControllableState } from \"@huin-core/react-use-controllable-state\";\nimport { useId } from \"@huin-core/react-id\";\nimport type { Scope } from \"@huin-core/react-context\";\n\n/* -------------------------------------------------------------------------------------------------\n * Tabs\n * -----------------------------------------------------------------------------------------------*/\n\nconst TABS_NAME = \"Tabs\";\n\nexport type ScopedProps<P> = P & { __scopeTabs?: Scope };\nconst [createTabsContext, createTabsScope] = createContextScope(TABS_NAME, [\n createRovingFocusGroupScope,\n]);\n\ntype TabsContextValue = {\n baseId: string;\n value?: string;\n onValueChange: (value: string) => void;\n orientation?: TabsProps[\"orientation\"];\n dir?: TabsProps[\"dir\"];\n activationMode?: TabsProps[\"activationMode\"];\n};\n\nexport const [TabsProvider, useTabsContext] =\n createTabsContext<TabsContextValue>(TABS_NAME);\n\ntype TabsElement = React.ElementRef<typeof Primitive.div>;\nexport type RovingFocusGroupProps = React.ComponentPropsWithoutRef<\n typeof RovingFocusGroup.Root\n>;\nexport type PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface TabsProps extends PrimitiveDivProps {\n /** The value for the selected tab, if controlled */\n value?: string;\n /** The value of the tab to select by default, if uncontrolled */\n defaultValue?: string;\n /** A function called when a new tab is selected */\n onValueChange?: (value: string) => void;\n /**\n * The orientation the tabs are layed out.\n * Mainly so arrow navigation is done accordingly (left & right vs. up & down)\n * @defaultValue horizontal\n */\n orientation?: RovingFocusGroupProps[\"orientation\"];\n /**\n * The direction of navigation between toolbar items.\n */\n dir?: RovingFocusGroupProps[\"dir\"];\n /**\n * Whether a tab is activated automatically or manually.\n * @defaultValue automatic\n * */\n activationMode?: \"automatic\" | \"manual\";\n}\n\nconst Tabs = React.forwardRef<TabsElement, TabsProps>(\n (props: ScopedProps<TabsProps>, forwardedRef) => {\n const {\n __scopeTabs,\n value: valueProp,\n onValueChange,\n defaultValue,\n orientation = \"horizontal\",\n dir,\n activationMode = \"automatic\",\n ...tabsProps\n } = props;\n const direction = useDirection(dir);\n const [value, setValue] = useControllableState({\n prop: valueProp,\n onChange: onValueChange,\n defaultProp: defaultValue,\n });\n\n return (\n <TabsProvider\n scope={__scopeTabs}\n baseId={useId()}\n value={value}\n onValueChange={setValue}\n orientation={orientation}\n dir={direction}\n activationMode={activationMode}\n >\n <Primitive.div\n dir={direction}\n data-orientation={orientation}\n {...tabsProps}\n ref={forwardedRef}\n />\n </TabsProvider>\n );\n }\n);\n\nTabs.displayName = TABS_NAME;\n\nconst Root = Tabs;\n\nexport {\n createTabsScope,\n //\n Tabs,\n //\n Root,\n};\nexport type { TabsProps };\n", "import React from \"react\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport {\n PrimitiveDivProps,\n RovingFocusGroupProps,\n ScopedProps,\n useTabsContext,\n} from \"./Tabs\";\nimport { createRovingFocusGroupScope } from \"@huin-core/react-roving-focus\";\nimport * as RovingFocusGroup from \"@huin-core/react-roving-focus\";\n\nconst TAB_LIST_NAME = \"TabsList\";\n\ntype TabsListElement = React.ElementRef<typeof Primitive.div>;\ninterface TabsListProps extends PrimitiveDivProps {\n loop?: RovingFocusGroupProps[\"loop\"];\n}\nexport const useRovingFocusGroupScope = createRovingFocusGroupScope();\n\nconst TabsList = React.forwardRef<TabsListElement, TabsListProps>(\n (props: ScopedProps<TabsListProps>, forwardedRef) => {\n const { __scopeTabs, loop = true, ...listProps } = props;\n const context = useTabsContext(TAB_LIST_NAME, __scopeTabs);\n const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);\n return (\n <RovingFocusGroup.Root\n asChild\n {...rovingFocusGroupScope}\n orientation={context.orientation}\n dir={context.dir}\n loop={loop}\n >\n <Primitive.div\n role=\"tablist\"\n aria-orientation={context.orientation}\n {...listProps}\n ref={forwardedRef}\n />\n </RovingFocusGroup.Root>\n );\n }\n);\n\nTabsList.displayName = TAB_LIST_NAME;\n\nexport { TabsList };\nexport type { TabsListProps };\n", "import React from \"react\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport { ScopedProps, useTabsContext } from \"./Tabs\";\nimport { useRovingFocusGroupScope } from \"./TabsList\";\nimport { makeContentId, makeTriggerId } from \"./TabsContent\";\nimport * as RovingFocusGroup from \"@huin-core/react-roving-focus\";\nimport { composeEventHandlers } from \"@huin-core/primitive\";\n\nconst TRIGGER_NAME = \"TabsTrigger\";\n\ntype TabsTriggerElement = React.ElementRef<typeof Primitive.button>;\ntype PrimitiveButtonProps = React.ComponentPropsWithoutRef<\n typeof Primitive.button\n>;\ninterface TabsTriggerProps extends PrimitiveButtonProps {\n value: string;\n}\n\nconst TabsTrigger = React.forwardRef<TabsTriggerElement, TabsTriggerProps>(\n (props: ScopedProps<TabsTriggerProps>, forwardedRef) => {\n const { __scopeTabs, value, disabled = false, ...triggerProps } = props;\n const context = useTabsContext(TRIGGER_NAME, __scopeTabs);\n const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);\n const triggerId = makeTriggerId(context.baseId, value);\n const contentId = makeContentId(context.baseId, value);\n const isSelected = value === context.value;\n return (\n <RovingFocusGroup.Item\n asChild\n {...rovingFocusGroupScope}\n focusable={!disabled}\n active={isSelected}\n >\n <Primitive.button\n type=\"button\"\n role=\"tab\"\n aria-selected={isSelected}\n aria-controls={contentId}\n data-state={isSelected ? \"active\" : \"inactive\"}\n data-disabled={disabled ? \"\" : undefined}\n disabled={disabled}\n id={triggerId}\n {...triggerProps}\n ref={forwardedRef}\n onMouseDown={composeEventHandlers(props.onMouseDown, (event) => {\n // only call handler if it's the left button (mousedown gets triggered by all mouse buttons)\n // but not when the control key is pressed (avoiding MacOS right click)\n if (!disabled && event.button === 0 && event.ctrlKey === false) {\n context.onValueChange(value);\n } else {\n // prevent focus to avoid accidental activation\n event.preventDefault();\n }\n })}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if ([\" \", \"Enter\"].includes(event.key))\n context.onValueChange(value);\n })}\n onFocus={composeEventHandlers(props.onFocus, () => {\n // handle \"automatic\" activation if necessary\n // ie. activate tab following focus\n const isAutomaticActivation = context.activationMode !== \"manual\";\n if (!isSelected && !disabled && isAutomaticActivation) {\n context.onValueChange(value);\n }\n })}\n />\n </RovingFocusGroup.Item>\n );\n }\n);\n\nTabsTrigger.displayName = TRIGGER_NAME;\n\nexport { TabsTrigger };\nexport type { TabsTriggerProps };\n", "import React from \"react\";\nimport { Primitive } from \"@huin-core/react-primitive\";\nimport { PrimitiveDivProps, ScopedProps, useTabsContext } from \"./Tabs\";\nimport { Presence } from \"@huin-core/react-presence\";\n\nconst CONTENT_NAME = \"TabsContent\";\n\ntype TabsContentElement = React.ElementRef<typeof Primitive.div>;\ninterface TabsContentProps extends PrimitiveDivProps {\n value: string;\n\n /**\n * Used to force mounting when more control is needed. Useful when\n * controlling animation with React animation libraries.\n */\n forceMount?: true;\n}\n\nconst TabsContent = React.forwardRef<TabsContentElement, TabsContentProps>(\n (props: ScopedProps<TabsContentProps>, forwardedRef) => {\n const { __scopeTabs, value, forceMount, children, ...contentProps } = props;\n const context = useTabsContext(CONTENT_NAME, __scopeTabs);\n const triggerId = makeTriggerId(context.baseId, value);\n const contentId = makeContentId(context.baseId, value);\n const isSelected = value === context.value;\n const isMountAnimationPreventedRef = React.useRef(isSelected);\n\n React.useEffect(() => {\n const rAF = requestAnimationFrame(\n () => (isMountAnimationPreventedRef.current = false)\n );\n return () => cancelAnimationFrame(rAF);\n }, []);\n return (\n <Presence present={forceMount || isSelected}>\n {({ present }) => (\n <Primitive.div\n data-state={isSelected ? \"active\" : \"inactive\"}\n data-orientation={context.orientation}\n role=\"tabpanel\"\n aria-labelledby={triggerId}\n hidden={!present}\n id={contentId}\n tabIndex={0}\n {...contentProps}\n ref={forwardedRef}\n style={{\n ...props.style,\n animationDuration: isMountAnimationPreventedRef.current\n ? \"0s\"\n : undefined,\n }}\n >\n {present && children}\n </Primitive.div>\n )}\n </Presence>\n );\n }\n);\n\nTabsContent.displayName = CONTENT_NAME;\n\n/* ---------------------------------------------------------------------------------------------- */\n\nexport function makeTriggerId(baseId: string, value: string) {\n return `${baseId}-trigger-${value}`;\n}\nexport function makeContentId(baseId: string, value: string) {\n return `${baseId}-content-${value}`;\n}\n\nexport { TabsContent };\nexport type { TabsContentProps };\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["React", "Primitive", "createRovingFocusGroupScope", "jsx", "React", "Primitive", "React", "Primitive", "React", "Primitive", "jsx", "React", "Primitive", "RovingFocusGroup", "jsx", "React", "Primitive"]
|
7
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@huin-core/react-tabs",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.4",
|
4
4
|
"license": "MIT",
|
5
5
|
"exports": {
|
6
6
|
".": {
|
@@ -20,7 +20,8 @@
|
|
20
20
|
"types": "./dist/index.d.ts",
|
21
21
|
"files": [
|
22
22
|
"dist",
|
23
|
-
"README.md"
|
23
|
+
"README.md",
|
24
|
+
"package.json"
|
24
25
|
],
|
25
26
|
"sideEffects": false,
|
26
27
|
"scripts": {
|