@box/blueprint-web 6.18.0 → 6.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib-esm/index.css +86 -31
- package/lib-esm/primitives/tabs/content-switch-tab.d.ts +8 -0
- package/lib-esm/primitives/tabs/content-switch-tab.js +43 -0
- package/lib-esm/primitives/tabs/default-tab.d.ts +8 -0
- package/lib-esm/primitives/tabs/default-tab.js +57 -0
- package/lib-esm/primitives/tabs/index.d.ts +7 -12
- package/lib-esm/primitives/tabs/tab-list.d.ts +3 -3
- package/lib-esm/primitives/tabs/tab-list.js +3 -2
- package/lib-esm/primitives/tabs/tab-panel.d.ts +1 -2
- package/lib-esm/primitives/tabs/tab.d.ts +2 -7
- package/lib-esm/primitives/tabs/tab.js +10 -51
- package/lib-esm/primitives/tabs/tabs-width-context.d.ts +17 -0
- package/lib-esm/primitives/tabs/tabs-width-context.js +31 -0
- package/lib-esm/primitives/tabs/tabs.d.ts +2 -5
- package/lib-esm/primitives/tabs/tabs.js +7 -4
- package/lib-esm/primitives/tabs/tabs.module.js +1 -1
- package/lib-esm/primitives/tabs/types.d.ts +13 -0
- package/lib-esm/util-components/focus-trap/focus-trap.d.ts +1 -0
- package/lib-esm/utils/testStories.utils.d.ts +1 -0
- package/package.json +2 -2
package/lib-esm/index.css
CHANGED
|
@@ -4135,29 +4135,100 @@ table.inline_table_module_inlineTable--b023b tr:not(:last-child) td{
|
|
|
4135
4135
|
opacity:.3;
|
|
4136
4136
|
}
|
|
4137
4137
|
|
|
4138
|
-
.
|
|
4138
|
+
.tabs_module_hiddenWidthSetter--6a56b{
|
|
4139
|
+
display:block;
|
|
4140
|
+
font-family:Lato, -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
|
4141
|
+
font-size:.875rem;
|
|
4142
|
+
font-weight:700;
|
|
4143
|
+
height:0;
|
|
4144
|
+
letter-spacing:.01875rem;
|
|
4145
|
+
line-height:1.25rem;
|
|
4146
|
+
overflow:hidden;
|
|
4147
|
+
text-decoration:none;
|
|
4148
|
+
text-transform:none;
|
|
4149
|
+
visibility:hidden;
|
|
4150
|
+
}
|
|
4151
|
+
.tabs_module_hiddenWidthSetter--6a56b > *{
|
|
4152
|
+
visibility:hidden;
|
|
4153
|
+
}
|
|
4154
|
+
|
|
4155
|
+
.tabs_module_contentSwitchTabList--6a56b{
|
|
4156
|
+
background:var(--surface-contentswitcher-surface);
|
|
4157
|
+
border-radius:var(--radius-3);
|
|
4158
|
+
display:grid;
|
|
4159
|
+
gap:var(--space-1);
|
|
4160
|
+
grid-auto-columns:1fr;
|
|
4161
|
+
grid-auto-flow:column;
|
|
4162
|
+
min-width:-moz-fit-content;
|
|
4163
|
+
min-width:fit-content;
|
|
4164
|
+
padding:var(--space-1);
|
|
4165
|
+
}
|
|
4166
|
+
.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b{
|
|
4167
|
+
align-items:center;
|
|
4168
|
+
background:#0000;
|
|
4169
|
+
border:none;
|
|
4170
|
+
border-radius:var(--radius-2);
|
|
4171
|
+
display:flex;
|
|
4172
|
+
flex-direction:column;
|
|
4173
|
+
font-weight:400;
|
|
4174
|
+
height:var(--size-8);
|
|
4175
|
+
justify-content:center;
|
|
4176
|
+
outline:none;
|
|
4177
|
+
padding-inline:var(--space-4);
|
|
4178
|
+
white-space:nowrap;
|
|
4179
|
+
}
|
|
4180
|
+
.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b,.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b[aria-selected=true]{
|
|
4181
|
+
font-family:Lato, -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
|
4182
|
+
font-size:.875rem;
|
|
4183
|
+
letter-spacing:.01875rem;
|
|
4184
|
+
line-height:1.25rem;
|
|
4185
|
+
text-decoration:none;
|
|
4186
|
+
text-transform:none;
|
|
4187
|
+
}
|
|
4188
|
+
.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b[aria-selected=true]{
|
|
4189
|
+
background:var(--surface-cta-surface-secondary);
|
|
4190
|
+
box-shadow:0 0 0 var(--border-1) var(--gray-50);
|
|
4191
|
+
color:var(--text-text-on-light);
|
|
4192
|
+
font-weight:700;
|
|
4193
|
+
}
|
|
4194
|
+
.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b:not([aria-disabled=true])[data-focus-visible]{
|
|
4195
|
+
border-color:#0000;
|
|
4196
|
+
box-shadow:0 0 0 var(--border-2) var(--outline-focus-on-light);
|
|
4197
|
+
}
|
|
4198
|
+
.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b:not([aria-disabled=true]):hover{
|
|
4199
|
+
background:var(--surface-surface-hover);
|
|
4200
|
+
}
|
|
4201
|
+
.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b:not([aria-disabled=true]):active{
|
|
4202
|
+
background:var(--surface-cta-surface-secondary-pressed);
|
|
4203
|
+
}
|
|
4204
|
+
.tabs_module_contentSwitchTabList--6a56b .tabs_module_contentSwitchTab--6a56b[aria-disabled=true]{
|
|
4205
|
+
opacity:.3;
|
|
4206
|
+
pointer-events:none;
|
|
4207
|
+
}
|
|
4208
|
+
|
|
4209
|
+
.tabs_module_tabsListContainer--6a56b{
|
|
4139
4210
|
height:calc(var(--size-10) + (var(--border-3) + 1px)*2);
|
|
4140
4211
|
overflow-y:hidden;
|
|
4141
4212
|
scroll-behavior:smooth;
|
|
4142
4213
|
}
|
|
4143
|
-
.tabs_module_tabsListContainer--
|
|
4214
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b{
|
|
4144
4215
|
display:flex;
|
|
4145
4216
|
overflow-x:auto;
|
|
4146
4217
|
padding:calc(var(--border-3) + 1px);
|
|
4147
4218
|
}
|
|
4148
|
-
.tabs_module_tabsListContainer--
|
|
4219
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tabSeparator--6a56b{
|
|
4149
4220
|
border-bottom:var(--border-2) solid var(--border-tab-border);
|
|
4150
4221
|
min-width:var(--space-4);
|
|
4151
4222
|
}
|
|
4152
|
-
.tabs_module_tabsListContainer--
|
|
4223
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tabSeparator--6a56b:last-child{
|
|
4153
4224
|
display:none;
|
|
4154
4225
|
}
|
|
4155
4226
|
@media only screen and (max-width: 1023px){
|
|
4156
|
-
.tabs_module_tabsListContainer--
|
|
4227
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tabSeparator--6a56b{
|
|
4157
4228
|
min-width:calc(var(--border-3) + 1px);
|
|
4158
4229
|
}
|
|
4159
4230
|
}
|
|
4160
|
-
.tabs_module_tabsListContainer--
|
|
4231
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b{
|
|
4161
4232
|
background:var(--background-background);
|
|
4162
4233
|
border-style:none;
|
|
4163
4234
|
border-bottom:var(--border-2) solid var(--border-tab-border);
|
|
@@ -4171,7 +4242,7 @@ table.inline_table_module_inlineTable--b023b tr:not(:last-child) td{
|
|
|
4171
4242
|
scroll-margin:calc(var(--border-3) + 1px);
|
|
4172
4243
|
z-index:2;
|
|
4173
4244
|
}
|
|
4174
|
-
.tabs_module_tabsListContainer--
|
|
4245
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b,.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b[aria-selected=true]{
|
|
4175
4246
|
font-family:Lato, -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
|
4176
4247
|
font-size:.875rem;
|
|
4177
4248
|
letter-spacing:.01875rem;
|
|
@@ -4179,42 +4250,26 @@ table.inline_table_module_inlineTable--b023b tr:not(:last-child) td{
|
|
|
4179
4250
|
text-decoration:none;
|
|
4180
4251
|
text-transform:none;
|
|
4181
4252
|
}
|
|
4182
|
-
.tabs_module_tabsListContainer--
|
|
4183
|
-
display:block;
|
|
4184
|
-
font-weight:700;
|
|
4185
|
-
height:0;
|
|
4186
|
-
overflow:hidden;
|
|
4187
|
-
visibility:hidden;
|
|
4188
|
-
}
|
|
4189
|
-
.tabs_module_tabsListContainer--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09 .tabs_module_hiddenWidthSetter--23e09 > *{
|
|
4190
|
-
visibility:hidden;
|
|
4191
|
-
}
|
|
4192
|
-
.tabs_module_tabsListContainer--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09[aria-selected=true]{
|
|
4253
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b[aria-selected=true]{
|
|
4193
4254
|
border-bottom:var(--border-2) solid var(--border-tab-border-selected);
|
|
4194
4255
|
color:var(--text-cta-link);
|
|
4195
|
-
font-family:Lato, -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
|
4196
|
-
font-size:.875rem;
|
|
4197
4256
|
font-weight:700;
|
|
4198
|
-
letter-spacing:.01875rem;
|
|
4199
|
-
line-height:1.25rem;
|
|
4200
|
-
text-decoration:none;
|
|
4201
|
-
text-transform:none;
|
|
4202
4257
|
}
|
|
4203
|
-
.tabs_module_tabsListContainer--
|
|
4258
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b:hover{
|
|
4204
4259
|
background-color:var(--surface-tab-surface-hover);
|
|
4205
4260
|
color:var(--text-text-on-light-secondary-hover);
|
|
4206
4261
|
}
|
|
4207
|
-
.tabs_module_tabsListContainer--
|
|
4262
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b:hover[aria-selected=true]{
|
|
4208
4263
|
color:var(--text-cta-link);
|
|
4209
4264
|
}
|
|
4210
|
-
.tabs_module_tabsListContainer--
|
|
4265
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b:active{
|
|
4211
4266
|
background-color:var(--surface-tab-surface-pressed);
|
|
4212
4267
|
color:var(--text-text-on-light-secondary-hover);
|
|
4213
4268
|
}
|
|
4214
|
-
.tabs_module_tabsListContainer--
|
|
4269
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b:active[aria-selected=true]{
|
|
4215
4270
|
color:var(--text-cta-link);
|
|
4216
4271
|
}
|
|
4217
|
-
.tabs_module_tabsListContainer--
|
|
4272
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b:focus-visible,.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b[data-focus-visible]{
|
|
4218
4273
|
background-color:var(--surface-tab-surface-hover);
|
|
4219
4274
|
border-radius:var(--radius-05);
|
|
4220
4275
|
box-shadow:inset 0 0 0 1px #fff;
|
|
@@ -4222,10 +4277,10 @@ table.inline_table_module_inlineTable--b023b tr:not(:last-child) td{
|
|
|
4222
4277
|
outline:var(--border-3) solid var(--outline-focus-on-light);
|
|
4223
4278
|
outline-offset:1px;
|
|
4224
4279
|
}
|
|
4225
|
-
.tabs_module_tabsListContainer--
|
|
4280
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b:focus-visible[aria-selected=true],.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b[data-focus-visible][aria-selected=true]{
|
|
4226
4281
|
color:var(--text-cta-link);
|
|
4227
4282
|
}
|
|
4228
|
-
.tabs_module_tabsListContainer--
|
|
4283
|
+
.tabs_module_tabsListContainer--6a56b .tabs_module_tabList--6a56b .tabs_module_tab--6a56b[aria-disabled=true]{
|
|
4229
4284
|
opacity:.5;
|
|
4230
4285
|
}
|
|
4231
4286
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const ContentSwitchTab: import("react").ForwardRefExoticComponent<Omit<import("@ariakit/react").TabOptions<"button"> & Omit<Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
3
|
+
ref?: ((instance: HTMLButtonElement | null) => void) | import("react").RefObject<HTMLButtonElement> | null | undefined;
|
|
4
|
+
}, keyof import("@ariakit/react").TabOptions<T>> & {
|
|
5
|
+
[index: `data-${string}`]: unknown;
|
|
6
|
+
} & {
|
|
7
|
+
variant?: import("./types").TabsVariant | undefined;
|
|
8
|
+
}, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Tab } from '@ariakit/react';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import { forwardRef, useRef, useEffect } from 'react';
|
|
5
|
+
import { useTabsWidthContext } from './tabs-width-context.js';
|
|
6
|
+
import styles from './tabs.module.js';
|
|
7
|
+
|
|
8
|
+
const ContentSwitchTab = /*#__PURE__*/forwardRef(function Tab$1(props, ref) {
|
|
9
|
+
const {
|
|
10
|
+
className,
|
|
11
|
+
children,
|
|
12
|
+
...rest
|
|
13
|
+
} = props;
|
|
14
|
+
const widthSetterRef = useRef(null);
|
|
15
|
+
const {
|
|
16
|
+
minTabWidth,
|
|
17
|
+
addTabWidth
|
|
18
|
+
} = useTabsWidthContext();
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const tabElement = widthSetterRef.current;
|
|
21
|
+
if (!tabElement) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const tabWidth = tabElement.getBoundingClientRect().width;
|
|
25
|
+
addTabWidth(tabWidth);
|
|
26
|
+
}, [addTabWidth]);
|
|
27
|
+
return jsxs(Tab, {
|
|
28
|
+
...rest,
|
|
29
|
+
ref: ref,
|
|
30
|
+
className: clsx(styles.contentSwitchTab, className),
|
|
31
|
+
children: [children, jsx("span", {
|
|
32
|
+
ref: widthSetterRef,
|
|
33
|
+
className: styles.hiddenWidthSetter,
|
|
34
|
+
style: {
|
|
35
|
+
minWidth: minTabWidth
|
|
36
|
+
},
|
|
37
|
+
children: children
|
|
38
|
+
})]
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
ContentSwitchTab.displayName = 'ContentSwitchTab';
|
|
42
|
+
|
|
43
|
+
export { ContentSwitchTab };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const DefaultTab: import("react").ForwardRefExoticComponent<Omit<import("@ariakit/react").TabOptions<"button"> & Omit<Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
3
|
+
ref?: import("react").RefObject<HTMLButtonElement> | ((instance: HTMLButtonElement | null) => void) | null | undefined;
|
|
4
|
+
}, keyof import("@ariakit/react").TabOptions<T>> & {
|
|
5
|
+
[index: `data-${string}`]: unknown;
|
|
6
|
+
} & {
|
|
7
|
+
variant?: import("./types").TabsVariant | undefined;
|
|
8
|
+
}, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Tab } from '@ariakit/react';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import { forwardRef, useRef, useEffect } from 'react';
|
|
5
|
+
import { useForkRef } from '../../utils/useForkRef.js';
|
|
6
|
+
import styles from './tabs.module.js';
|
|
7
|
+
import { useTabs } from './use-tabs.js';
|
|
8
|
+
|
|
9
|
+
const outlineWidth = 3;
|
|
10
|
+
const outlineOffset = 1;
|
|
11
|
+
const padding = 12;
|
|
12
|
+
const scrollTabIntoViewIfSelected = (tabRef, isSelected) => {
|
|
13
|
+
const tabElement = tabRef.current;
|
|
14
|
+
const tabParentElement = tabRef.current?.parentElement;
|
|
15
|
+
const scrollOffset = outlineWidth + outlineOffset + padding;
|
|
16
|
+
if (!isSelected || !tabElement || !tabParentElement) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const scrollHorizontalPosition = tabElement.getBoundingClientRect().left - scrollOffset;
|
|
20
|
+
tabParentElement.scrollLeft = scrollHorizontalPosition;
|
|
21
|
+
};
|
|
22
|
+
const DefaultTab = /*#__PURE__*/forwardRef(function Tab$1(props, ref) {
|
|
23
|
+
const {
|
|
24
|
+
className,
|
|
25
|
+
children,
|
|
26
|
+
...rest
|
|
27
|
+
} = props;
|
|
28
|
+
const tabRef = useRef(null);
|
|
29
|
+
const selectedTabId = useTabs()?.useState('selectedId');
|
|
30
|
+
const isTabSelected = selectedTabId === rest?.id;
|
|
31
|
+
const checkedScrollOnMount = useRef(false);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (checkedScrollOnMount.current) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
scrollTabIntoViewIfSelected(tabRef, isTabSelected);
|
|
37
|
+
checkedScrollOnMount.current = true;
|
|
38
|
+
}, [isTabSelected]);
|
|
39
|
+
return jsxs(Fragment, {
|
|
40
|
+
children: [jsxs(Tab, {
|
|
41
|
+
...rest,
|
|
42
|
+
ref: useForkRef(tabRef, ref),
|
|
43
|
+
className: clsx(styles.tab, className),
|
|
44
|
+
children: [children, jsx("span", {
|
|
45
|
+
className: styles.hiddenWidthSetter,
|
|
46
|
+
children: children
|
|
47
|
+
})]
|
|
48
|
+
}), jsx("div", {
|
|
49
|
+
"aria-hidden": "true",
|
|
50
|
+
className: styles.tabSeparator,
|
|
51
|
+
role: "presentation"
|
|
52
|
+
})]
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
DefaultTab.displayName = 'DefaultTab';
|
|
56
|
+
|
|
57
|
+
export { DefaultTab };
|
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export declare const Tabs: ((props: import("./
|
|
2
|
+
export declare const Tabs: ((props: import("./types").TabsProps) => JSX.Element) & {
|
|
3
3
|
/**
|
|
4
4
|
* The component that displays a Tab name and allows selection.
|
|
5
5
|
*/
|
|
6
|
-
Tab:
|
|
7
|
-
ref?: ((instance: HTMLButtonElement | null) => void) | import("react").RefObject<HTMLButtonElement> | null | undefined;
|
|
8
|
-
}, keyof import("@ariakit/react").TabOptions<T>> & {
|
|
9
|
-
[index: `data-${string}`]: unknown;
|
|
10
|
-
}, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
6
|
+
Tab: (props: import("./types").TabProps) => JSX.Element;
|
|
11
7
|
/**
|
|
12
8
|
* Wrapper for a list of Tabs.
|
|
13
9
|
*/
|
|
14
|
-
TabList: import("react").ForwardRefExoticComponent<Omit<import("
|
|
10
|
+
TabList: import("react").ForwardRefExoticComponent<Omit<Omit<import("@ariakit/react").TabListProps<"div">, "store"> & {
|
|
11
|
+
variant?: import("./types").TabsVariant | undefined;
|
|
12
|
+
}, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
15
13
|
/**
|
|
16
14
|
* The content for a single Tab.
|
|
17
15
|
*/
|
|
18
|
-
TabPanel: import("react").ForwardRefExoticComponent<Omit<import("./
|
|
16
|
+
TabPanel: import("react").ForwardRefExoticComponent<Omit<import("./types").TabPanelProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
19
17
|
};
|
|
18
|
+
export { type TabListProps, type TabPanelProps, type TabProps, type TabsProps } from './types';
|
|
20
19
|
export { useTabs } from './use-tabs';
|
|
21
|
-
export { type TabProps } from './tab';
|
|
22
|
-
export { type TabListProps } from './tab-list';
|
|
23
|
-
export { type TabPanelProps } from './tab-panel';
|
|
24
|
-
export { type TabsProps } from './tabs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
export declare const TabList: import("react").ForwardRefExoticComponent<Omit<Omit<import("@ariakit/react").TabListProps<"div">, "store"> & {
|
|
3
|
+
variant?: import("./types").TabsVariant | undefined;
|
|
4
|
+
}, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -7,7 +7,8 @@ import { useTabs } from './use-tabs.js';
|
|
|
7
7
|
|
|
8
8
|
const TabList = /*#__PURE__*/forwardRef(function TabList(props, ref) {
|
|
9
9
|
const {
|
|
10
|
-
className
|
|
10
|
+
className,
|
|
11
|
+
variant = 'default'
|
|
11
12
|
} = props;
|
|
12
13
|
const tab = useTabs();
|
|
13
14
|
if (!tab) {
|
|
@@ -18,7 +19,7 @@ const TabList = /*#__PURE__*/forwardRef(function TabList(props, ref) {
|
|
|
18
19
|
children: jsx(TabList$1, {
|
|
19
20
|
...props,
|
|
20
21
|
ref: ref,
|
|
21
|
-
className: clsx(styles.tabList, className),
|
|
22
|
+
className: clsx(variant === 'contentSwitcher' ? styles.contentSwitchTabList : styles.tabList, className),
|
|
22
23
|
store: tab
|
|
23
24
|
})
|
|
24
25
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { type TabPanelProps
|
|
3
|
-
export type TabPanelProps = Omit<PrimitiveTabPanelProps, 'store'>;
|
|
2
|
+
import { type TabPanelProps } from './types';
|
|
4
3
|
export declare const TabPanel: import("react").ForwardRefExoticComponent<Omit<TabPanelProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { type TabProps
|
|
3
|
-
export
|
|
4
|
-
export declare const Tab: import("react").ForwardRefExoticComponent<Omit<import("@ariakit/react").TabOptions<"button"> & Omit<Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
|
|
5
|
-
ref?: ((instance: HTMLButtonElement | null) => void) | import("react").RefObject<HTMLButtonElement> | null | undefined;
|
|
6
|
-
}, keyof import("@ariakit/react").TabOptions<T>> & {
|
|
7
|
-
[index: `data-${string}`]: unknown;
|
|
8
|
-
}, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
2
|
+
import { type TabProps } from './types';
|
|
3
|
+
export declare const Tab: (props: TabProps) => JSX.Element;
|
|
@@ -1,58 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import { forwardRef, useRef, useEffect } from 'react';
|
|
5
|
-
import { useForkRef } from '../../utils/useForkRef.js';
|
|
6
|
-
import styles from './tabs.module.js';
|
|
7
|
-
import { useTabs } from './use-tabs.js';
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { ContentSwitchTab } from './content-switch-tab.js';
|
|
3
|
+
import { DefaultTab } from './default-tab.js';
|
|
8
4
|
|
|
9
|
-
const
|
|
10
|
-
const tabElement = tabRef.current;
|
|
11
|
-
const tabParentElement = tabRef.current?.parentElement;
|
|
12
|
-
const outlineWidthAndOffset = 4;
|
|
13
|
-
if (!isSelected || !tabElement || !tabParentElement) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const scrollHorizontalPosition = tabElement.getBoundingClientRect().left + outlineWidthAndOffset;
|
|
17
|
-
tabParentElement.scrollLeft = scrollHorizontalPosition;
|
|
18
|
-
};
|
|
19
|
-
const Tab = /*#__PURE__*/forwardRef(function Tab(props, ref) {
|
|
5
|
+
const Tab = props => {
|
|
20
6
|
const {
|
|
21
|
-
|
|
22
|
-
children,
|
|
23
|
-
id,
|
|
7
|
+
variant = 'default',
|
|
24
8
|
...rest
|
|
25
9
|
} = props;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
id
|
|
31
|
-
} : {};
|
|
32
|
-
const scrolledOnMount = useRef(false);
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
if (scrolledOnMount.current === true) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
scrollSelectedTabIntoView(tabRef, isTabSelected);
|
|
38
|
-
scrolledOnMount.current = true;
|
|
39
|
-
}, [isTabSelected]);
|
|
40
|
-
return jsxs(Fragment, {
|
|
41
|
-
children: [jsxs(Tab$1, {
|
|
42
|
-
...rest,
|
|
43
|
-
ref: useForkRef(tabRef, ref),
|
|
44
|
-
className: clsx(styles.tab, className),
|
|
45
|
-
...tabId,
|
|
46
|
-
children: [children, jsx("span", {
|
|
47
|
-
className: styles.hiddenWidthSetter,
|
|
48
|
-
children: children
|
|
49
|
-
})]
|
|
50
|
-
}), jsx("div", {
|
|
51
|
-
"aria-hidden": "true",
|
|
52
|
-
className: styles.tabSeparator,
|
|
53
|
-
role: "presentation"
|
|
54
|
-
})]
|
|
10
|
+
return variant === 'contentSwitcher' ? jsx(ContentSwitchTab, {
|
|
11
|
+
...rest
|
|
12
|
+
}) : jsx(DefaultTab, {
|
|
13
|
+
...rest
|
|
55
14
|
});
|
|
56
|
-
}
|
|
15
|
+
};
|
|
57
16
|
|
|
58
17
|
export { Tab };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface TabsWidthContextData {
|
|
3
|
+
/**
|
|
4
|
+
* Minimum width of each rendered tab, derived from a tab with the longest label with minimal paddings.
|
|
5
|
+
*/
|
|
6
|
+
minTabWidth: number;
|
|
7
|
+
/**
|
|
8
|
+
* Register width of a tab in context.
|
|
9
|
+
*/
|
|
10
|
+
addTabWidth: (width: number) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface TabsWidthContextProps {
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
export declare const TabsWidthContext: import("react").Context<TabsWidthContextData | undefined>;
|
|
16
|
+
export declare const useTabsWidthContext: () => TabsWidthContextData;
|
|
17
|
+
export declare const TabsWidthProvider: (props: TabsWidthContextProps) => JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useContext, useState, useCallback, useMemo, createContext } from 'react';
|
|
3
|
+
|
|
4
|
+
const TabsWidthContext = /*#__PURE__*/createContext(undefined);
|
|
5
|
+
const useTabsWidthContext = () => {
|
|
6
|
+
const tabsWidthContextData = useContext(TabsWidthContext);
|
|
7
|
+
if (!tabsWidthContextData) {
|
|
8
|
+
throw new Error('Tabs subcomponents must be wrapped in Tabs component.');
|
|
9
|
+
}
|
|
10
|
+
return tabsWidthContextData;
|
|
11
|
+
};
|
|
12
|
+
const TabsWidthProvider = props => {
|
|
13
|
+
const {
|
|
14
|
+
children
|
|
15
|
+
} = props;
|
|
16
|
+
const [tabWidths, setTabWidths] = useState([]);
|
|
17
|
+
const minTabWidth = Math.max(...tabWidths);
|
|
18
|
+
const addTabWidth = useCallback(width => {
|
|
19
|
+
setTabWidths(prev => [...prev, width]);
|
|
20
|
+
}, []);
|
|
21
|
+
const store = useMemo(() => ({
|
|
22
|
+
minTabWidth,
|
|
23
|
+
addTabWidth
|
|
24
|
+
}), [minTabWidth, addTabWidth]);
|
|
25
|
+
return jsx(TabsWidthContext.Provider, {
|
|
26
|
+
value: store,
|
|
27
|
+
children: children
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { TabsWidthContext, TabsWidthProvider, useTabsWidthContext };
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import { type
|
|
3
|
-
export type TabsProps = TabStoreProps & {
|
|
4
|
-
children: ReactNode;
|
|
5
|
-
};
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { type TabsProps } from './types';
|
|
6
3
|
export declare const Tabs: (props: TabsProps) => JSX.Element;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { TabProvider } from '@ariakit/react';
|
|
3
|
+
import { TabsWidthProvider } from './tabs-width-context.js';
|
|
3
4
|
|
|
4
5
|
const Tabs = props => {
|
|
5
6
|
const {
|
|
6
7
|
children
|
|
7
8
|
} = props;
|
|
8
|
-
return jsx(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
return jsx(TabsWidthProvider, {
|
|
10
|
+
children: jsx(TabProvider, {
|
|
11
|
+
selectOnMove: false,
|
|
12
|
+
...props,
|
|
13
|
+
children: children
|
|
14
|
+
})
|
|
12
15
|
});
|
|
13
16
|
};
|
|
14
17
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import '../../index.css';
|
|
2
|
-
var styles = {"tabsListContainer":"tabs_module_tabsListContainer--
|
|
2
|
+
var styles = {"hiddenWidthSetter":"tabs_module_hiddenWidthSetter--6a56b","contentSwitchTabList":"tabs_module_contentSwitchTabList--6a56b","contentSwitchTab":"tabs_module_contentSwitchTab--6a56b","tabsListContainer":"tabs_module_tabsListContainer--6a56b","tabList":"tabs_module_tabList--6a56b","tabSeparator":"tabs_module_tabSeparator--6a56b","tab":"tabs_module_tab--6a56b"};
|
|
3
3
|
|
|
4
4
|
export { styles as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type TabListProps as PrimitiveTabListProps, type TabPanelProps as PrimitiveTabPanelProps, type TabProps as PrimitiveTabProps, type TabStoreProps as PrimitiveTabStoreProps } from '@ariakit/react';
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
export type TabsVariant = 'default' | 'contentSwitcher';
|
|
4
|
+
export type TabListProps = Omit<PrimitiveTabListProps, 'store'> & {
|
|
5
|
+
variant?: TabsVariant;
|
|
6
|
+
};
|
|
7
|
+
export type TabPanelProps = Omit<PrimitiveTabPanelProps, 'store'>;
|
|
8
|
+
export type TabProps = PrimitiveTabProps & {
|
|
9
|
+
variant?: TabsVariant;
|
|
10
|
+
};
|
|
11
|
+
export type TabsProps = PrimitiveTabStoreProps & {
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@box/blueprint-web",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.19.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@box/storybook-utils": "^0.0.3"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "05fe9fbc44f97b1e8b5df6062ded4ef9fc1d05ae",
|
|
61
61
|
"module": "lib-esm/index.js",
|
|
62
62
|
"main": "lib-esm/index.js",
|
|
63
63
|
"exports": {
|