@box/blueprint-web 12.119.0 → 12.121.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/dist/lib-esm/index.css +387 -162
- package/dist/lib-esm/index.d.ts +1 -0
- package/dist/lib-esm/index.js +2 -0
- package/dist/lib-esm/large-list-v2/index.d.ts +42 -0
- package/dist/lib-esm/large-list-v2/index.js +47 -0
- package/dist/lib-esm/large-list-v2/large-list-v2-content.d.ts +7 -0
- package/dist/lib-esm/large-list-v2/large-list-v2-content.js +23 -0
- package/dist/lib-esm/large-list-v2/large-list-v2.d.ts +9 -0
- package/dist/lib-esm/large-list-v2/large-list-v2.js +25 -0
- package/dist/lib-esm/large-list-v2/types.d.ts +8 -0
- package/dist/lib-esm/page/index.d.ts +6 -0
- package/dist/lib-esm/page/index.js +5 -1
- package/dist/lib-esm/page/page-context.d.ts +19 -2
- package/dist/lib-esm/page/page-context.js +29 -3
- package/dist/lib-esm/page/page-portal.d.ts +52 -0
- package/dist/lib-esm/page/page-portal.js +83 -0
- package/dist/lib-esm/page/page-subnavigation.js +4 -1
- package/dist/lib-esm/primitives/page-header/page-header.js +8 -2
- package/dist/lib-esm/text-button/text-button.js +2 -0
- package/dist/lib-esm/text-button/types.d.ts +7 -1
- package/dist/lib-esm/util-components/base-grid-list-item/base-grid-list-item-actions.js +1 -1
- package/dist/lib-esm/util-components/base-grid-list-item/base-grid-list-item-thumbnail.js +1 -1
- package/dist/lib-esm/util-components/base-grid-list-item/base-grid-list-item.js +20 -12
- package/dist/lib-esm/util-components/base-grid-list-item/base-grid-list-item.module.js +1 -1
- package/dist/lib-esm/util-components/base-grid-list-item/base-grid-list.js +4 -0
- package/dist/lib-esm/util-components/base-grid-list-item/types.d.ts +2 -1
- package/dist/lib-esm/utils/fast-context.d.ts +2 -0
- package/dist/lib-esm/utils/fast-context.js +31 -1
- package/package.json +3 -3
package/dist/lib-esm/index.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export * from './inline-notice/inline-notice';
|
|
|
34
34
|
export * from './inline-table/inline-table';
|
|
35
35
|
export * from './input-chip';
|
|
36
36
|
export * from './large-list-item';
|
|
37
|
+
export * from './large-list-v2';
|
|
37
38
|
export * from './list-item/list-item';
|
|
38
39
|
export * from './loading-indicator/loading-indicator';
|
|
39
40
|
export * from './modal';
|
package/dist/lib-esm/index.js
CHANGED
|
@@ -42,6 +42,7 @@ export { InlineNotice } from './inline-notice/inline-notice.js';
|
|
|
42
42
|
export { InlineTable } from './inline-table/inline-table.js';
|
|
43
43
|
export { InputChip } from './input-chip/input-chip.js';
|
|
44
44
|
export { LargeList } from './large-list-item/index.js';
|
|
45
|
+
export { LargeListV2 } from './large-list-v2/index.js';
|
|
45
46
|
export { ActionCell, Cell, Column, DropIndicator, Row, Table, TableBody, TableHeader } from './list-item/list-item.js';
|
|
46
47
|
export { LoadingIndicator } from './loading-indicator/loading-indicator.js';
|
|
47
48
|
export { AlertModal } from './modal/alert-modal.js';
|
|
@@ -114,5 +115,6 @@ export { useIsEllipsized } from './utils/useIsEllipsized.js';
|
|
|
114
115
|
export { getUniqueId, useUniqueId } from './utils/useUniqueId.js';
|
|
115
116
|
export { VisuallyHidden } from './visually-hidden/visually-hidden.js';
|
|
116
117
|
export { useMainSectionSidebar, usePageNavigation } from './page/page-context.js';
|
|
118
|
+
export { PageHeaderEndElementsPortal, PageHeaderStartElementsPortal, PageSubNavigationPortal } from './page/page-portal.js';
|
|
117
119
|
export { useNotification } from './primitives/notification/notification-provider.js';
|
|
118
120
|
export { useTabs } from './primitives/tabs/use-tabs.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type { LargeListV2ActionIconButtonProps, LargeListV2ActionsProps, LargeListV2HeaderProps, LargeListV2ItemProps, LargeListV2Props, LargeListV2SubtitleProps, LargeListV2ThumbnailProps, } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* LargeListV2 - A modernized horizontal list component for displaying items in a compact row layout.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```tsx
|
|
7
|
+
* <LargeListV2 aria-label="Files" selectionMode="multiple">
|
|
8
|
+
* <LargeListV2.Item id="1" textValue="Document.pdf">
|
|
9
|
+
* <LargeListV2.Thumbnail fileExtension="pdf" fileCategory="pdf">
|
|
10
|
+
* <img src="/thumbnail.jpg" alt="Document preview" />
|
|
11
|
+
* </LargeListV2.Thumbnail>
|
|
12
|
+
* <LargeListV2.Content>
|
|
13
|
+
* <LargeListV2.Header>Document.pdf</LargeListV2.Header>
|
|
14
|
+
* <LargeListV2.Subtitle>Modified 2 days ago</LargeListV2.Subtitle>
|
|
15
|
+
* </LargeListV2.Content>
|
|
16
|
+
* <LargeListV2.Actions>
|
|
17
|
+
* <LargeListV2.ActionIconButton icon={MoreIcon} aria-label="More actions" />
|
|
18
|
+
* </LargeListV2.Actions>
|
|
19
|
+
* </LargeListV2.Item>
|
|
20
|
+
* </LargeListV2>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const LargeListV2: import("react").ForwardRefExoticComponent<import("./types").LargeListV2Props & import("react").RefAttributes<HTMLDivElement>> & {
|
|
24
|
+
/** An individual item in the list. */
|
|
25
|
+
Item: import("react").ForwardRefExoticComponent<import("../util-components/base-grid-list-item").BaseGridListItemProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
26
|
+
/** Styled wrapper for the thumbnail/icon (4:3 aspect ratio). */
|
|
27
|
+
Thumbnail: import("react").ForwardRefExoticComponent<Omit<import("../util-components/base-grid-list-item").BaseGridListThumbnailProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
28
|
+
/** Content wrapper that groups header and subtitle. */
|
|
29
|
+
Content: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
30
|
+
ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
|
|
31
|
+
}, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
32
|
+
/** Title/name of the item (15px/20px). */
|
|
33
|
+
Header: import("react").ForwardRefExoticComponent<Omit<import("../util-components/base-grid-list-item").BaseGridListHeaderProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
|
|
34
|
+
/** Secondary text below the header (13px/20px). */
|
|
35
|
+
Subtitle: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
|
|
36
|
+
ref?: ((instance: HTMLSpanElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLSpanElement> | null | undefined;
|
|
37
|
+
}, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
|
|
38
|
+
/** Container for action buttons and selection checkbox. */
|
|
39
|
+
Actions: import("react").ForwardRefExoticComponent<Omit<import("../util-components/base-grid-list-item").BaseGridListActionsProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
40
|
+
/** Icon button for item actions (32x32px). */
|
|
41
|
+
ActionIconButton: import("react").ForwardRefExoticComponent<(Omit<import("../primitives/icon-button/types").IconButtonVariantsProps, "ref"> | Omit<import("../primitives/icon-button/types").IconButtonSmallUtilityVariantProps, "ref">) & import("react").RefAttributes<HTMLButtonElement>>;
|
|
42
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { BaseGridListItem } from '../util-components/base-grid-list-item/base-grid-list-item.js';
|
|
2
|
+
import { BaseGridListActionIconButton, BaseGridListActions } from '../util-components/base-grid-list-item/base-grid-list-item-actions.js';
|
|
3
|
+
import { BaseGridListHeader } from '../util-components/base-grid-list-item/base-grid-list-item-header.js';
|
|
4
|
+
import { BaseGridListSubtitle } from '../util-components/base-grid-list-item/base-grid-list-item-subtitle.js';
|
|
5
|
+
import { BaseGridListThumbnail } from '../util-components/base-grid-list-item/base-grid-list-item-thumbnail.js';
|
|
6
|
+
import { LargeListV2Root } from './large-list-v2.js';
|
|
7
|
+
import { LargeListV2Content } from './large-list-v2-content.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* LargeListV2 - A modernized horizontal list component for displaying items in a compact row layout.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <LargeListV2 aria-label="Files" selectionMode="multiple">
|
|
15
|
+
* <LargeListV2.Item id="1" textValue="Document.pdf">
|
|
16
|
+
* <LargeListV2.Thumbnail fileExtension="pdf" fileCategory="pdf">
|
|
17
|
+
* <img src="/thumbnail.jpg" alt="Document preview" />
|
|
18
|
+
* </LargeListV2.Thumbnail>
|
|
19
|
+
* <LargeListV2.Content>
|
|
20
|
+
* <LargeListV2.Header>Document.pdf</LargeListV2.Header>
|
|
21
|
+
* <LargeListV2.Subtitle>Modified 2 days ago</LargeListV2.Subtitle>
|
|
22
|
+
* </LargeListV2.Content>
|
|
23
|
+
* <LargeListV2.Actions>
|
|
24
|
+
* <LargeListV2.ActionIconButton icon={MoreIcon} aria-label="More actions" />
|
|
25
|
+
* </LargeListV2.Actions>
|
|
26
|
+
* </LargeListV2.Item>
|
|
27
|
+
* </LargeListV2>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
const LargeListV2 = Object.assign(LargeListV2Root, {
|
|
31
|
+
/** An individual item in the list. */
|
|
32
|
+
Item: BaseGridListItem,
|
|
33
|
+
/** Styled wrapper for the thumbnail/icon (4:3 aspect ratio). */
|
|
34
|
+
Thumbnail: BaseGridListThumbnail,
|
|
35
|
+
/** Content wrapper that groups header and subtitle. */
|
|
36
|
+
Content: LargeListV2Content,
|
|
37
|
+
/** Title/name of the item (15px/20px). */
|
|
38
|
+
Header: BaseGridListHeader,
|
|
39
|
+
/** Secondary text below the header (13px/20px). */
|
|
40
|
+
Subtitle: BaseGridListSubtitle,
|
|
41
|
+
/** Container for action buttons and selection checkbox. */
|
|
42
|
+
Actions: BaseGridListActions,
|
|
43
|
+
/** Icon button for item actions (32x32px). */
|
|
44
|
+
ActionIconButton: BaseGridListActionIconButton
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export { LargeListV2 };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content wrapper for LargeListV2 items.
|
|
3
|
+
* Groups the header and subtitle in a vertical stack.
|
|
4
|
+
*/
|
|
5
|
+
export declare const LargeListV2Content: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
6
|
+
ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
|
|
7
|
+
}, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import styles from '../util-components/base-grid-list-item/base-grid-list-item.module.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Content wrapper for LargeListV2 items.
|
|
7
|
+
* Groups the header and subtitle in a vertical stack.
|
|
8
|
+
*/
|
|
9
|
+
const LargeListV2Content = /*#__PURE__*/forwardRef(function LargeListV2Content(props, ref) {
|
|
10
|
+
const {
|
|
11
|
+
children,
|
|
12
|
+
className,
|
|
13
|
+
...rest
|
|
14
|
+
} = props;
|
|
15
|
+
return jsx("div", {
|
|
16
|
+
...rest,
|
|
17
|
+
ref: ref,
|
|
18
|
+
className: `${styles.content} ${className ?? ''}`,
|
|
19
|
+
children: children
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export { LargeListV2Content };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type LargeListV2Props } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* LargeListV2 is a modernized horizontal list component for displaying items in a compact row layout.
|
|
4
|
+
* Each item displays a thumbnail on the left, content (title/subtitle) in the middle,
|
|
5
|
+
* and actions on the right.
|
|
6
|
+
*
|
|
7
|
+
* This component ships post-UI-Uplift and uses modern Blueprint tokens by default.
|
|
8
|
+
*/
|
|
9
|
+
export declare const LargeListV2Root: import("react").ForwardRefExoticComponent<LargeListV2Props & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { BaseGridList } from '../util-components/base-grid-list-item/base-grid-list.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* LargeListV2 is a modernized horizontal list component for displaying items in a compact row layout.
|
|
7
|
+
* Each item displays a thumbnail on the left, content (title/subtitle) in the middle,
|
|
8
|
+
* and actions on the right.
|
|
9
|
+
*
|
|
10
|
+
* This component ships post-UI-Uplift and uses modern Blueprint tokens by default.
|
|
11
|
+
*/
|
|
12
|
+
const LargeListV2Root = /*#__PURE__*/forwardRef(function LargeListV2(props, forwardedRef) {
|
|
13
|
+
const {
|
|
14
|
+
children,
|
|
15
|
+
...rest
|
|
16
|
+
} = props;
|
|
17
|
+
return jsx(BaseGridList, {
|
|
18
|
+
...rest,
|
|
19
|
+
ref: forwardedRef,
|
|
20
|
+
layoutStyle: "list-v2",
|
|
21
|
+
children: children
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export { LargeListV2Root };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type BaseGridListActionIconButtonProps, type BaseGridListActionsProps, type BaseGridListHeaderProps, type BaseGridListItemProps, type BaseGridListProps, type BaseGridListSubtitleProps, type BaseGridListThumbnailProps } from '../util-components/base-grid-list-item/types';
|
|
2
|
+
export type LargeListV2Props = Omit<BaseGridListProps, 'layoutStyle' | 'centerText' | 'variant'>;
|
|
3
|
+
export type LargeListV2ItemProps = BaseGridListItemProps;
|
|
4
|
+
export type LargeListV2ThumbnailProps = BaseGridListThumbnailProps;
|
|
5
|
+
export type LargeListV2HeaderProps = BaseGridListHeaderProps;
|
|
6
|
+
export type LargeListV2SubtitleProps = BaseGridListSubtitleProps;
|
|
7
|
+
export type LargeListV2ActionsProps = BaseGridListActionsProps;
|
|
8
|
+
export type LargeListV2ActionIconButtonProps = BaseGridListActionIconButtonProps;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export { useMainSectionSidebar, usePageNavigation } from './page-context';
|
|
2
|
+
export type { PagePortalRefs } from './page-context';
|
|
3
|
+
export { PageHeaderEndElementsPortal, PageHeaderStartElementsPortal, PageSubNavigationPortal } from './page-portal';
|
|
4
|
+
export type { PagePortalProps } from './page-portal';
|
|
2
5
|
export * from './types';
|
|
3
6
|
export declare const Page: import("react").ForwardRefExoticComponent<import("./types").PageLayoutProps & import("react").RefAttributes<HTMLDivElement>> & {
|
|
4
7
|
/**
|
|
@@ -27,10 +30,13 @@ export declare const Page: import("react").ForwardRefExoticComponent<import("./t
|
|
|
27
30
|
};
|
|
28
31
|
/**
|
|
29
32
|
* Sub navigation area of the page.
|
|
33
|
+
* Content can be portaled here using PageSubNavigationPortal from child routes.
|
|
30
34
|
*/
|
|
31
35
|
SubNavigation: import("react").ForwardRefExoticComponent<import("./types").PageSubNavigationProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
32
36
|
/**
|
|
33
37
|
* Page header with title and actions.
|
|
38
|
+
* Content can be portaled to StartElements and EndElements using
|
|
39
|
+
* PageHeaderStartElementsPortal and PageHeaderEndElementsPortal from child routes.
|
|
34
40
|
*/
|
|
35
41
|
PageHeader: ((props: import("./types").PagePageHeaderProps) => import("react/jsx-runtime").JSX.Element) & {
|
|
36
42
|
StartElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -4,8 +4,9 @@ import { PageNavigation } from './page-navigation.js';
|
|
|
4
4
|
import { PagePageHeader } from './page-page-header.js';
|
|
5
5
|
import { PageRoot } from './page-root.js';
|
|
6
6
|
import { PageSubNavigation } from './page-subnavigation.js';
|
|
7
|
-
import 'react/jsx-runtime';
|
|
8
7
|
import 'react';
|
|
8
|
+
import 'react/jsx-runtime';
|
|
9
|
+
export { PageHeaderEndElementsPortal, PageHeaderStartElementsPortal, PageSubNavigationPortal } from './page-portal.js';
|
|
9
10
|
|
|
10
11
|
const Page = Object.assign(PageRoot, {
|
|
11
12
|
/**
|
|
@@ -28,10 +29,13 @@ const Page = Object.assign(PageRoot, {
|
|
|
28
29
|
MainSection,
|
|
29
30
|
/**
|
|
30
31
|
* Sub navigation area of the page.
|
|
32
|
+
* Content can be portaled here using PageSubNavigationPortal from child routes.
|
|
31
33
|
*/
|
|
32
34
|
SubNavigation: PageSubNavigation,
|
|
33
35
|
/**
|
|
34
36
|
* Page header with title and actions.
|
|
37
|
+
* Content can be portaled to StartElements and EndElements using
|
|
38
|
+
* PageHeaderStartElementsPortal and PageHeaderEndElementsPortal from child routes.
|
|
35
39
|
*/
|
|
36
40
|
PageHeader: PagePageHeader
|
|
37
41
|
});
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { type ForwardedRef } from 'react';
|
|
2
|
+
export interface PagePortalRefs {
|
|
3
|
+
/** Reference to the PageHeader.StartElements container */
|
|
4
|
+
pageHeaderStartElementsRef: HTMLDivElement | null;
|
|
5
|
+
/** Reference to the PageHeader.EndElements container */
|
|
6
|
+
pageHeaderEndElementsRef: HTMLDivElement | null;
|
|
7
|
+
/** Reference to the PageSubNavigation container */
|
|
8
|
+
pageSubNavigationRef: HTMLDivElement | null;
|
|
9
|
+
}
|
|
10
|
+
export interface PageFastContextValuesType extends PagePortalRefs {
|
|
2
11
|
navigationExpanded: boolean;
|
|
3
12
|
pageContainer: HTMLElement | null;
|
|
4
13
|
globalHeaderContainer: HTMLDivElement | null;
|
|
@@ -6,7 +15,7 @@ export interface PageFastContextValuesType {
|
|
|
6
15
|
}
|
|
7
16
|
export declare const PageProvider: ({ children }: {
|
|
8
17
|
children: React.ReactNode;
|
|
9
|
-
}) => import("react/jsx-runtime").JSX.Element, usePageStore: <SelectorOutput>(selector: (store: PageFastContextValuesType) => SelectorOutput) => [SelectorOutput, (value: Partial<PageFastContextValuesType>) => void], usePageStoreSetter: () => (value: Partial<PageFastContextValuesType>) => void;
|
|
18
|
+
}) => import("react/jsx-runtime").JSX.Element, usePageStore: <SelectorOutput>(selector: (store: PageFastContextValuesType) => SelectorOutput) => [SelectorOutput, (value: Partial<PageFastContextValuesType>) => void], usePageStoreSafe: <SelectorOutput>(selector: (store: PageFastContextValuesType) => SelectorOutput) => [SelectorOutput, (value: Partial<PageFastContextValuesType>) => void] | null, usePageStoreSetter: () => (value: Partial<PageFastContextValuesType>) => void, usePageStoreSetterSafe: () => ((value: Partial<PageFastContextValuesType>) => void) | null;
|
|
10
19
|
export declare const usePageNavigation: () => {
|
|
11
20
|
navigationExpanded: boolean;
|
|
12
21
|
setNavigationExpanded: (expanded: boolean) => void;
|
|
@@ -17,3 +26,11 @@ export declare const useMainSectionSidebar: () => {
|
|
|
17
26
|
setMainSectionSidebarVisible: (visible: boolean) => void;
|
|
18
27
|
toggleMainSectionSidebarVisible: () => void;
|
|
19
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Hook that creates a callback ref which stores the node in the PageStore
|
|
31
|
+
* and forwards it to an optional forwardedRef.
|
|
32
|
+
*
|
|
33
|
+
* Works both with and without a PageProvider - when used standalone,
|
|
34
|
+
* it simply forwards the ref without storing it.
|
|
35
|
+
*/
|
|
36
|
+
export declare function usePageStoreRef<T extends HTMLElement>(storeKey: keyof PagePortalRefs, forwardedRef: ForwardedRef<T>): (node: T | null) => void;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
1
2
|
import { createFastContext } from '../utils/fast-context.js';
|
|
2
3
|
|
|
3
4
|
const {
|
|
4
5
|
Provider: PageProvider,
|
|
5
6
|
useStore: usePageStore,
|
|
6
|
-
|
|
7
|
+
useStoreSafe: usePageStoreSafe,
|
|
8
|
+
useStoreSetter: usePageStoreSetter,
|
|
9
|
+
useStoreSetterSafe: usePageStoreSetterSafe
|
|
7
10
|
} = createFastContext({
|
|
8
11
|
globalHeaderContainer: null,
|
|
9
12
|
mainSectionSidebarVisible: true,
|
|
10
13
|
navigationExpanded: true,
|
|
11
|
-
pageContainer: null
|
|
14
|
+
pageContainer: null,
|
|
15
|
+
pageHeaderStartElementsRef: null,
|
|
16
|
+
pageHeaderEndElementsRef: null,
|
|
17
|
+
pageSubNavigationRef: null
|
|
12
18
|
});
|
|
13
19
|
const usePageNavigation = () => {
|
|
14
20
|
const [navigationExpanded, setPageStore] = usePageStore(store => store.navigationExpanded);
|
|
@@ -46,5 +52,25 @@ const useMainSectionSidebar = () => {
|
|
|
46
52
|
toggleMainSectionSidebarVisible
|
|
47
53
|
};
|
|
48
54
|
};
|
|
55
|
+
/**
|
|
56
|
+
* Hook that creates a callback ref which stores the node in the PageStore
|
|
57
|
+
* and forwards it to an optional forwardedRef.
|
|
58
|
+
*
|
|
59
|
+
* Works both with and without a PageProvider - when used standalone,
|
|
60
|
+
* it simply forwards the ref without storing it.
|
|
61
|
+
*/
|
|
62
|
+
function usePageStoreRef(storeKey, forwardedRef) {
|
|
63
|
+
const setPageStore = usePageStoreSetterSafe();
|
|
64
|
+
return useCallback(node => {
|
|
65
|
+
setPageStore?.({
|
|
66
|
+
[storeKey]: node
|
|
67
|
+
});
|
|
68
|
+
if (typeof forwardedRef === 'function') {
|
|
69
|
+
forwardedRef(node);
|
|
70
|
+
} else if (forwardedRef) {
|
|
71
|
+
forwardedRef.current = node;
|
|
72
|
+
}
|
|
73
|
+
}, [forwardedRef, setPageStore, storeKey]);
|
|
74
|
+
}
|
|
49
75
|
|
|
50
|
-
export { PageProvider, useMainSectionSidebar, usePageNavigation, usePageStore, usePageStoreSetter };
|
|
76
|
+
export { PageProvider, useMainSectionSidebar, usePageNavigation, usePageStore, usePageStoreRef, usePageStoreSafe, usePageStoreSetter, usePageStoreSetterSafe };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface PagePortalProps {
|
|
3
|
+
/** Content to render in the portal target location. */
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/**
|
|
6
|
+
* Content to render before the portal target is available (e.g., during SSR or before mount).
|
|
7
|
+
* @default null
|
|
8
|
+
*/
|
|
9
|
+
fallback?: ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* When `true`, children are portaled to the target Page slot.
|
|
12
|
+
* When `false`, children render in place without portaling (useful for feature flags or gradual migration).
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
isPortalActive?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Portal to Page.PageHeader.StartElements
|
|
19
|
+
* Use this to render breadcrumbs, titles, etc. from child routes.
|
|
20
|
+
*
|
|
21
|
+
* @example Conditionally enable portal based on feature flag
|
|
22
|
+
* ```tsx
|
|
23
|
+
* <PageHeaderStartElementsPortal isPortalActive={featureEnabled}>
|
|
24
|
+
* <Breadcrumb>Home / Settings</Breadcrumb>
|
|
25
|
+
* </PageHeaderStartElementsPortal>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare const PageHeaderStartElementsPortal: import("react").ForwardRefExoticComponent<PagePortalProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
29
|
+
/**
|
|
30
|
+
* Portal to Page.PageHeader.EndElements
|
|
31
|
+
* Use this to render action buttons, status indicators, etc. from child routes.
|
|
32
|
+
*
|
|
33
|
+
* @example Conditionally enable portal based on feature flag
|
|
34
|
+
* ```tsx
|
|
35
|
+
* <PageHeaderEndElementsPortal isPortalActive={featureEnabled}>
|
|
36
|
+
* <Button>Save</Button>
|
|
37
|
+
* </PageHeaderEndElementsPortal>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare const PageHeaderEndElementsPortal: import("react").ForwardRefExoticComponent<PagePortalProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
41
|
+
/**
|
|
42
|
+
* Portal to Page.SubNavigation
|
|
43
|
+
* Use this to render sub-tabs, secondary navigation, etc. from child routes.
|
|
44
|
+
*
|
|
45
|
+
* @example Conditionally enable portal based on feature flag
|
|
46
|
+
* ```tsx
|
|
47
|
+
* <PageSubNavigationPortal isPortalActive={featureEnabled}>
|
|
48
|
+
* <ExistingSubNavigation />
|
|
49
|
+
* </PageSubNavigationPortal>
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare const PageSubNavigationPortal: import("react").ForwardRefExoticComponent<PagePortalProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { forwardRef, useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
3
|
+
import { usePageStoreSafe } from './page-context.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a portal component for a specific Page destination.
|
|
7
|
+
* Caches the last valid ref to prevent flashing during route transitions.
|
|
8
|
+
*/
|
|
9
|
+
const createPagePortal = (refKey, displayName) => {
|
|
10
|
+
const Component = /*#__PURE__*/forwardRef(({
|
|
11
|
+
children,
|
|
12
|
+
fallback = null,
|
|
13
|
+
isPortalActive = true
|
|
14
|
+
}, forwardedRef) => {
|
|
15
|
+
const [mounted, setMounted] = useState(false);
|
|
16
|
+
const storeResult = usePageStoreSafe(store => store[refKey]);
|
|
17
|
+
const targetRef = storeResult?.[0] ?? null;
|
|
18
|
+
const cachedRef = useRef(null);
|
|
19
|
+
if (targetRef) {
|
|
20
|
+
cachedRef.current = targetRef;
|
|
21
|
+
}
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const target = targetRef || cachedRef.current;
|
|
24
|
+
if (typeof forwardedRef === 'function') {
|
|
25
|
+
forwardedRef(target);
|
|
26
|
+
} else if (forwardedRef) {
|
|
27
|
+
forwardedRef.current = target;
|
|
28
|
+
}
|
|
29
|
+
}, [targetRef, forwardedRef]);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setMounted(true);
|
|
32
|
+
}, []);
|
|
33
|
+
// If no PageProvider or portal is disabled, render children in place
|
|
34
|
+
if (!storeResult || !isPortalActive) {
|
|
35
|
+
return children;
|
|
36
|
+
}
|
|
37
|
+
const portalTarget = targetRef || cachedRef.current;
|
|
38
|
+
if (!mounted || !portalTarget) {
|
|
39
|
+
return fallback;
|
|
40
|
+
}
|
|
41
|
+
return /*#__PURE__*/createPortal(children, portalTarget);
|
|
42
|
+
});
|
|
43
|
+
Component.displayName = displayName;
|
|
44
|
+
return Component;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Portal to Page.PageHeader.StartElements
|
|
48
|
+
* Use this to render breadcrumbs, titles, etc. from child routes.
|
|
49
|
+
*
|
|
50
|
+
* @example Conditionally enable portal based on feature flag
|
|
51
|
+
* ```tsx
|
|
52
|
+
* <PageHeaderStartElementsPortal isPortalActive={featureEnabled}>
|
|
53
|
+
* <Breadcrumb>Home / Settings</Breadcrumb>
|
|
54
|
+
* </PageHeaderStartElementsPortal>
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
const PageHeaderStartElementsPortal = createPagePortal('pageHeaderStartElementsRef', 'PageHeaderStartElementsPortal');
|
|
58
|
+
/**
|
|
59
|
+
* Portal to Page.PageHeader.EndElements
|
|
60
|
+
* Use this to render action buttons, status indicators, etc. from child routes.
|
|
61
|
+
*
|
|
62
|
+
* @example Conditionally enable portal based on feature flag
|
|
63
|
+
* ```tsx
|
|
64
|
+
* <PageHeaderEndElementsPortal isPortalActive={featureEnabled}>
|
|
65
|
+
* <Button>Save</Button>
|
|
66
|
+
* </PageHeaderEndElementsPortal>
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
const PageHeaderEndElementsPortal = createPagePortal('pageHeaderEndElementsRef', 'PageHeaderEndElementsPortal');
|
|
70
|
+
/**
|
|
71
|
+
* Portal to Page.SubNavigation
|
|
72
|
+
* Use this to render sub-tabs, secondary navigation, etc. from child routes.
|
|
73
|
+
*
|
|
74
|
+
* @example Conditionally enable portal based on feature flag
|
|
75
|
+
* ```tsx
|
|
76
|
+
* <PageSubNavigationPortal isPortalActive={featureEnabled}>
|
|
77
|
+
* <ExistingSubNavigation />
|
|
78
|
+
* </PageSubNavigationPortal>
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
const PageSubNavigationPortal = createPagePortal('pageSubNavigationRef', 'PageSubNavigationPortal');
|
|
82
|
+
|
|
83
|
+
export { PageHeaderEndElementsPortal, PageHeaderStartElementsPortal, PageSubNavigationPortal };
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
|
+
import { usePageStoreRef } from './page-context.js';
|
|
3
4
|
|
|
4
5
|
const PageSubNavigation = /*#__PURE__*/forwardRef(({
|
|
5
6
|
className,
|
|
6
7
|
...rest
|
|
7
8
|
}, forwardedRef) => {
|
|
9
|
+
const setRef = usePageStoreRef('pageSubNavigationRef', forwardedRef);
|
|
8
10
|
return jsx("div", {
|
|
9
11
|
...rest,
|
|
10
|
-
ref:
|
|
12
|
+
ref: setRef,
|
|
11
13
|
className: className
|
|
12
14
|
});
|
|
13
15
|
});
|
|
16
|
+
PageSubNavigation.displayName = 'PageSubNavigation';
|
|
14
17
|
|
|
15
18
|
export { PageSubNavigation };
|
|
@@ -2,6 +2,7 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { forwardRef, createElement } from 'react';
|
|
4
4
|
import { useBlueprintModernization } from '../../blueprint-modernization-context/useBlueprintModernization.js';
|
|
5
|
+
import { usePageStoreRef } from '../../page/page-context.js';
|
|
5
6
|
import styles from './page-header.module.js';
|
|
6
7
|
|
|
7
8
|
const PageHeaderRoot = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
@@ -48,9 +49,10 @@ const PageHeaderStartElements = /*#__PURE__*/forwardRef((props, forwardedRef) =>
|
|
|
48
49
|
children,
|
|
49
50
|
...rest
|
|
50
51
|
} = props;
|
|
52
|
+
const setRef = usePageStoreRef('pageHeaderStartElementsRef', forwardedRef);
|
|
51
53
|
return jsx("div", {
|
|
52
54
|
...rest,
|
|
53
|
-
ref:
|
|
55
|
+
ref: setRef,
|
|
54
56
|
className: clsx(styles.startElements, className),
|
|
55
57
|
children: children
|
|
56
58
|
});
|
|
@@ -61,13 +63,17 @@ const PageHeaderEndElements = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
|
|
61
63
|
children,
|
|
62
64
|
...rest
|
|
63
65
|
} = props;
|
|
66
|
+
const setRef = usePageStoreRef('pageHeaderEndElementsRef', forwardedRef);
|
|
64
67
|
return jsx("div", {
|
|
65
68
|
...rest,
|
|
66
|
-
ref:
|
|
69
|
+
ref: setRef,
|
|
67
70
|
className: clsx(styles.endElements, className),
|
|
68
71
|
children: children
|
|
69
72
|
});
|
|
70
73
|
});
|
|
74
|
+
PageHeaderStartElements.displayName = 'PageHeaderStartElements';
|
|
75
|
+
PageHeaderEndElements.displayName = 'PageHeaderEndElements';
|
|
76
|
+
PageHeaderCorner.displayName = 'PageHeaderCorner';
|
|
71
77
|
const PageHeader = {
|
|
72
78
|
Root: PageHeaderRoot,
|
|
73
79
|
StartElements: PageHeaderStartElements,
|
|
@@ -15,6 +15,7 @@ const TextButton = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
15
15
|
icon,
|
|
16
16
|
inheritFont,
|
|
17
17
|
className,
|
|
18
|
+
textRef,
|
|
18
19
|
...rest
|
|
19
20
|
} = getButtonOptions(props);
|
|
20
21
|
const {
|
|
@@ -31,6 +32,7 @@ const TextButton = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
31
32
|
}, className),
|
|
32
33
|
"data-modern": enableModernizedComponents ? 'true' : 'false',
|
|
33
34
|
children: [jsx("span", {
|
|
35
|
+
ref: textRef,
|
|
34
36
|
className: clsx({
|
|
35
37
|
[styles.hideTextContent]: loading
|
|
36
38
|
}),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ButtonProps as AriakitButtonProps } from '@ariakit/react';
|
|
2
|
-
import { type FunctionComponent, type PropsWithChildren, type SVGProps } from 'react';
|
|
2
|
+
import { type FunctionComponent, type PropsWithChildren, type Ref, type SVGProps } from 'react';
|
|
3
3
|
import { type RequireAllOrNone } from 'type-fest';
|
|
4
4
|
export interface Loading {
|
|
5
5
|
/** Whether the button is loading. */
|
|
@@ -20,5 +20,11 @@ export interface TextButtonBase extends AriakitButtonProps {
|
|
|
20
20
|
* When property is falsy, button uses default style.
|
|
21
21
|
* */
|
|
22
22
|
inheritFont?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Ref to the inner span element that wraps the text content.
|
|
25
|
+
*
|
|
26
|
+
* Useful for measuring text overflow with hooks like `useIsEllipsized`.
|
|
27
|
+
*/
|
|
28
|
+
textRef?: Ref<HTMLSpanElement>;
|
|
23
29
|
}
|
|
24
30
|
export type TextButtonProps = TextButtonBase & RequireAllOrNone<Loading, keyof Loading>;
|
|
@@ -120,7 +120,7 @@ const BaseGridListActions = /*#__PURE__*/forwardRef(function BaseGridListActions
|
|
|
120
120
|
if (loading) {
|
|
121
121
|
return null;
|
|
122
122
|
}
|
|
123
|
-
const isList = layoutStyle === 'list' || layoutStyle === 'small-list';
|
|
123
|
+
const isList = layoutStyle === 'list' || layoutStyle === 'list-v2' || layoutStyle === 'small-list';
|
|
124
124
|
const isGridV2 = layoutStyle === 'grid-v2';
|
|
125
125
|
const isSelectionEnabled = selectionMode === 'multiple';
|
|
126
126
|
const isRenderPropUsed = typeof children === 'function';
|
|
@@ -125,7 +125,7 @@ const BaseGridListThumbnail = /*#__PURE__*/forwardRef(function BaseGridListThumb
|
|
|
125
125
|
style: extensionColor ? {
|
|
126
126
|
color: extensionColor
|
|
127
127
|
} : undefined,
|
|
128
|
-
variant: "
|
|
128
|
+
variant: "captionBold",
|
|
129
129
|
children: normalizedExtension
|
|
130
130
|
})]
|
|
131
131
|
})]
|