@box/blueprint-web 6.18.0 → 6.19.1

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 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
- .tabs_module_tabsListContainer--23e09{
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--23e09 .tabs_module_tabList--23e09{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tabSeparator--23e09{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tabSeparator--23e09:last-child{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tabSeparator--23e09{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09,.tabs_module_tabsListContainer--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09 .tabs_module_hiddenWidthSetter--23e09{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09 .tabs_module_hiddenWidthSetter--23e09{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09:hover{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09:hover[aria-selected=true]{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09:active{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09:active[aria-selected=true]{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09:focus-visible,.tabs_module_tabsListContainer--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09[data-focus-visible]{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09:focus-visible[aria-selected=true],.tabs_module_tabsListContainer--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09[data-focus-visible][aria-selected=true]{
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--23e09 .tabs_module_tabList--23e09 .tabs_module_tab--23e09[aria-disabled=true]{
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("./tabs").TabsProps) => JSX.Element) & {
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: import("react").ForwardRefExoticComponent<Omit<import("@ariakit/react").TabOptions<"button"> & Omit<Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & {
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("./tab-list").TabListProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
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("./tab-panel").TabPanelProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
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
- import { type TabListProps as PrimitiveTabListProps } from '@ariakit/react';
3
- export type TabListProps = Omit<PrimitiveTabListProps, 'store'>;
4
- export declare const TabList: import("react").ForwardRefExoticComponent<Omit<TabListProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
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 as PrimitiveTabPanelProps } from '@ariakit/react';
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 as PrimitiveTabProps } from '@ariakit/react';
3
- export type TabProps = PrimitiveTabProps;
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 { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
- import { Tab as Tab$1 } 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';
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 scrollSelectedTabIntoView = (tabRef, isSelected) => {
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
- className,
22
- children,
23
- id,
7
+ variant = 'default',
24
8
  ...rest
25
9
  } = props;
26
- const tabRef = useRef(null);
27
- const selectedTabId = useTabs()?.useState('selectedId');
28
- const isTabSelected = selectedTabId === id;
29
- const tabId = id ? {
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
- import { type TabStoreProps } from '@ariakit/react';
2
- import { type ReactNode } from 'react';
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(TabProvider, {
9
- selectOnMove: false,
10
- ...props,
11
- children: children
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--23e09","tabList":"tabs_module_tabList--23e09","tabSeparator":"tabs_module_tabSeparator--23e09","tab":"tabs_module_tab--23e09","hiddenWidthSetter":"tabs_module_hiddenWidthSetter--23e09"};
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
+ };
@@ -1,2 +1,3 @@
1
+ /// <reference types="react" />
1
2
  import { type FocusTrapProps } from './types';
2
3
  export declare const FocusTrap: ({ containerRef, children, customInitialFocus }: FocusTrapProps) => JSX.Element;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  export declare function sleep(ms: number): Promise<unknown>;
2
3
  export declare const docsDisabledNotice: {
3
4
  docs: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@box/blueprint-web",
3
- "version": "6.18.0",
3
+ "version": "6.19.1",
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": "712a73b1a539afe140ea0623caf6f168a4fe2099",
60
+ "gitHead": "d16a621ecdb9a71b9bfb8c788986ccb7f871ad42",
61
61
  "module": "lib-esm/index.js",
62
62
  "main": "lib-esm/index.js",
63
63
  "exports": {