@box/blueprint-web 8.8.1 → 9.0.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.
Files changed (36) hide show
  1. package/lib-esm/index.css +178 -46
  2. package/lib-esm/index.d.ts +1 -0
  3. package/lib-esm/index.js +2 -0
  4. package/lib-esm/page/index.d.ts +30 -6
  5. package/lib-esm/page/index.js +39 -0
  6. package/lib-esm/page/page-context.d.ts +11 -19
  7. package/lib-esm/page/page-context.js +50 -0
  8. package/lib-esm/page/page-global-header-search-container.js +19 -0
  9. package/lib-esm/page/page-global-header-side-content-container.js +18 -0
  10. package/lib-esm/page/page-global-header.d.ts +3 -3
  11. package/lib-esm/page/page-global-header.js +39 -0
  12. package/lib-esm/page/page-main-section-content.d.ts +2 -0
  13. package/lib-esm/page/page-main-section-content.js +17 -0
  14. package/lib-esm/page/page-main-section-sidebar.d.ts +2 -0
  15. package/lib-esm/page/page-main-section-sidebar.js +27 -0
  16. package/lib-esm/page/page-main-section.d.ts +6 -0
  17. package/lib-esm/page/page-main-section.js +23 -0
  18. package/lib-esm/page/page-navigation.js +84 -0
  19. package/lib-esm/page/page-page-header.d.ts +6 -0
  20. package/lib-esm/page/page-page-header.js +18 -0
  21. package/lib-esm/page/page-root.d.ts +2 -2
  22. package/lib-esm/page/page-root.js +100 -0
  23. package/lib-esm/page/page-subnavigation.d.ts +2 -0
  24. package/lib-esm/page/page-subnavigation.js +15 -0
  25. package/lib-esm/page/page.module.js +4 -0
  26. package/lib-esm/page/types.d.ts +22 -12
  27. package/lib-esm/primitives/page-header/page-header.d.ts +4 -4
  28. package/lib-esm/primitives/page-header/page-header.js +8 -8
  29. package/lib-esm/primitives/page-header/types.d.ts +13 -4
  30. package/lib-esm/utils/fast-context.d.ts +8 -0
  31. package/lib-esm/utils/fast-context.js +68 -0
  32. package/lib-esm/utils/useRefWithEffect.d.ts +6 -0
  33. package/lib-esm/utils/useRefWithEffect.js +25 -0
  34. package/package.json +4 -4
  35. package/lib-esm/page/page-content.d.ts +0 -2
  36. package/lib-esm/utils/createSetRefWithCallback.d.ts +0 -10
package/lib-esm/index.css CHANGED
@@ -4171,6 +4171,184 @@ table.bp_inline_table_module_inlineTable--b023b tr:not(:last-child) td{
4171
4171
  margin-block:var(--space-2);
4172
4172
  }
4173
4173
 
4174
+ .bp_page_module_page--47219{
4175
+ --navigation-width-collapsed:var(--space-20);
4176
+ --navigation-width-expanded:calc(var(--space-20)*3);
4177
+ --large-viewport-inline-space:var(--space-8);
4178
+ display:flex;
4179
+ flex-direction:column;
4180
+ height:calc(100vh - var(--space-5));
4181
+ overflow:hidden;
4182
+ padding-block-start:var(--space-5);
4183
+ padding-inline-start:var(--navigation-width-collapsed);
4184
+ position:relative;
4185
+ }
4186
+ .bp_page_module_page--47219 .bp_page_module_globalHeader--47219{
4187
+ align-items:center;
4188
+ display:flex;
4189
+ flex-direction:row;
4190
+ justify-content:space-between;
4191
+ padding-inline:var(--large-viewport-inline-space);
4192
+ position:relative;
4193
+ }
4194
+ .bp_page_module_page--47219 .bp_page_module_globalHeader--47219 .bp_page_module_searchContainer--47219,.bp_page_module_page--47219 .bp_page_module_globalHeader--47219 .bp_page_module_sideContentContainer--47219{
4195
+ display:flex;
4196
+ flex:none;
4197
+ }
4198
+ .bp_page_module_page--47219 .bp_page_module_pageMain--47219{
4199
+ display:flex;
4200
+ flex-direction:column;
4201
+ height:inherit;
4202
+ overflow:hidden;
4203
+ padding-block-start:var(--space-5);
4204
+ padding-inline:var(--large-viewport-inline-space);
4205
+ }
4206
+ .bp_page_module_page--47219 .bp_page_module_pageMain--47219 .bp_page_module_topSection--47219{
4207
+ display:flex;
4208
+ flex-direction:column;
4209
+ flex-shrink:0;
4210
+ gap:var(--space-5);
4211
+ overflow:hidden;
4212
+ }
4213
+ .bp_page_module_page--47219 .bp_page_module_pageMain--47219 .bp_page_module_mainSection--47219{
4214
+ display:flex;
4215
+ flex-direction:row;
4216
+ height:inherit;
4217
+ overflow:hidden;
4218
+ }
4219
+ .bp_page_module_page--47219 .bp_page_module_pageMain--47219 .bp_page_module_mainSection--47219 .bp_page_module_content--47219{
4220
+ flex-grow:1;
4221
+ margin-block-start:var(--space-4);
4222
+ overflow-y:auto;
4223
+ padding-inline-end:var(--space-8);
4224
+ }
4225
+ .bp_page_module_page--47219 .bp_page_module_pageMain--47219 .bp_page_module_mainSection--47219 .bp_page_module_sidebar--47219{
4226
+ flex-shrink:0;
4227
+ margin-inline-start:var(--space-4);
4228
+ }
4229
+ .bp_page_module_page--47219 .bp_page_module_navigationPortal--47219{
4230
+ background-color:var(--box-blue-100);
4231
+ height:100%;
4232
+ left:0;
4233
+ position:absolute;
4234
+ top:0;
4235
+ width:var(--navigation-width);
4236
+ }
4237
+ .bp_page_module_page--47219 .bp_page_module_navigationPortal--47219 .bp_page_module_navigationContent--47219{
4238
+ height:100%;
4239
+ }
4240
+ .bp_page_module_page--47219 .bp_page_module_navigationPortalLargeCollapsed--47219{
4241
+ --navigation-width:var(--navigation-width-collapsed);
4242
+ }
4243
+ .bp_page_module_page--47219 .bp_page_module_navigationPortalLargeExpanded--47219{
4244
+ --navigation-width:var(--navigation-width-expanded);
4245
+ }
4246
+
4247
+ .bp_page_module_hide--47219{
4248
+ visibility:hidden;
4249
+ }
4250
+
4251
+ .bp_page_module_pageMediumOrLessViewport--47219{
4252
+ --global-header-fixed-size-section-height:var(--space-16);
4253
+ --global-header-fixed-size-section-collapsed:var(--space-16);
4254
+ height:calc(100vh - var(--global-header-fixed-size-section-height));
4255
+ padding-block-start:var(--global-header-fixed-size-section-height);
4256
+ padding-inline-start:0;
4257
+ }
4258
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_globalHeader--47219{
4259
+ height:var(--global-header-fixed-size-section-height);
4260
+ left:0;
4261
+ padding-inline:0;
4262
+ padding-inline-start:var(--global-header-fixed-size-section-collapsed);
4263
+ position:fixed;
4264
+ top:0;
4265
+ width:calc(100vw - var(--global-header-fixed-size-section-collapsed));
4266
+ }
4267
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_globalHeader--47219 .bp_page_module_search--47219{
4268
+ width:var(--global-header-fixed-size-section-collapsed);
4269
+ }
4270
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_pageMain--47219{
4271
+ overflow-y:auto;
4272
+ padding-inline:var(--space-4);
4273
+ }
4274
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_pageMain--47219 .bp_page_module_mainSection--47219{
4275
+ overflow:unset;
4276
+ }
4277
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_pageMain--47219 .bp_page_module_mainSection--47219 .bp_page_module_content--47219{
4278
+ overflow-y:unset;
4279
+ }
4280
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_navigationPortalOverlayCollapsed--47219{
4281
+ height:100%;
4282
+ }
4283
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_navigationPortalOverlayCollapsed--47219 .bp_page_module_navigationContent--47219{
4284
+ width:var(--global-header-fixed-size-section-collapsed);
4285
+ }
4286
+ .bp_page_module_pageMediumOrLessViewport--47219 .bp_page_module_navigationPortalOverlayExpanded--47219{
4287
+ height:100vh;
4288
+ width:100vw;
4289
+ z-index:1;
4290
+ }
4291
+
4292
+ .bp_page_module_pageNavigationXXLargeCollapsed--47219{
4293
+ --navigation-width:var(--navigation-width-collapsed);
4294
+ padding-inline-start:var(--navigation-width-collapsed);
4295
+ }
4296
+
4297
+ .bp_page_module_pageNavigationXXLargeExpanded--47219{
4298
+ --navigation-width:var(--navigation-width-expanded);
4299
+ padding-inline-start:var(--navigation-width-expanded);
4300
+ }
4301
+
4302
+ .bp_page_module_portalEntry--47219{
4303
+ display:contents;
4304
+ }
4305
+
4306
+ .bp_page_header_module_pageHeader--d031a{
4307
+ align-items:center;
4308
+ background:var(--surface-surface);
4309
+ display:flex;
4310
+ flex-direction:row;
4311
+ justify-content:space-between;
4312
+ max-height:var(--size-16);
4313
+ min-height:var(--size-10);
4314
+ width:100%;
4315
+ }
4316
+ .bp_page_header_module_pageHeader--d031a.bp_page_header_module_sticky--d031a{
4317
+ bottom:var(--blueprint-page-header-bottom, 0);
4318
+ left:var(--blueprint-page-header-left, 0);
4319
+ position:sticky;
4320
+ right:var(--blueprint-page-header-right, 0);
4321
+ top:var(--blueprint-page-header-top, 0);
4322
+ }
4323
+ .bp_page_header_module_pageHeader--d031a.bp_page_header_module_default--d031a{
4324
+ height:var(--size-16);
4325
+ padding-inline:var(--space-2);
4326
+ }
4327
+ .bp_page_header_module_pageHeader--d031a.bp_page_header_module_inline--d031a{
4328
+ height:var(--size-10);
4329
+ }
4330
+ .bp_page_header_module_pageHeader--d031a .bp_page_header_module_corner--d031a{
4331
+ align-items:center;
4332
+ display:flex;
4333
+ flex-basis:content;
4334
+ flex-grow:0;
4335
+ flex-shrink:0;
4336
+ }
4337
+ .bp_page_header_module_pageHeader--d031a .bp_page_header_module_startElements--d031a{
4338
+ align-items:center;
4339
+ display:flex;
4340
+ flex-grow:1;
4341
+ justify-content:flex-start;
4342
+ overflow:hidden;
4343
+ }
4344
+ .bp_page_header_module_pageHeader--d031a .bp_page_header_module_endElements--d031a{
4345
+ align-items:center;
4346
+ display:flex;
4347
+ flex-direction:row;
4348
+ flex-grow:1;
4349
+ justify-content:flex-end;
4350
+ }
4351
+
4174
4352
  .bp_page_section_module_pageSectionContainer--2add7{
4175
4353
  display:flex;
4176
4354
  flex-direction:column;
@@ -4697,52 +4875,6 @@ table.bp_inline_table_module_inlineTable--b023b tr:not(:last-child) td{
4697
4875
  fill:currentColor;
4698
4876
  }
4699
4877
 
4700
- .bp_page_header_module_pageHeader--d031a{
4701
- align-items:center;
4702
- background:var(--surface-surface);
4703
- display:flex;
4704
- flex-direction:row;
4705
- justify-content:space-between;
4706
- max-height:var(--size-16);
4707
- min-height:var(--size-10);
4708
- width:100%;
4709
- }
4710
- .bp_page_header_module_pageHeader--d031a.bp_page_header_module_sticky--d031a{
4711
- bottom:var(--blueprint-page-header-bottom, 0);
4712
- left:var(--blueprint-page-header-left, 0);
4713
- position:sticky;
4714
- right:var(--blueprint-page-header-right, 0);
4715
- top:var(--blueprint-page-header-top, 0);
4716
- }
4717
- .bp_page_header_module_pageHeader--d031a.bp_page_header_module_default--d031a{
4718
- height:var(--size-16);
4719
- padding-inline:var(--space-2);
4720
- }
4721
- .bp_page_header_module_pageHeader--d031a.bp_page_header_module_inline--d031a{
4722
- height:var(--size-10);
4723
- }
4724
- .bp_page_header_module_pageHeader--d031a .bp_page_header_module_corner--d031a{
4725
- align-items:center;
4726
- display:flex;
4727
- flex-basis:content;
4728
- flex-grow:0;
4729
- flex-shrink:0;
4730
- }
4731
- .bp_page_header_module_pageHeader--d031a .bp_page_header_module_startElements--d031a{
4732
- align-items:center;
4733
- display:flex;
4734
- flex-grow:1;
4735
- justify-content:flex-start;
4736
- overflow:hidden;
4737
- }
4738
- .bp_page_header_module_pageHeader--d031a .bp_page_header_module_endElements--d031a{
4739
- align-items:center;
4740
- display:flex;
4741
- flex-direction:row;
4742
- flex-grow:1;
4743
- justify-content:flex-end;
4744
- }
4745
-
4746
4878
  .bp_popover_module_popoverMainContent--7fad3{
4747
4879
  mask-image:linear-gradient(to top, #0000, var(--gray-black)), linear-gradient(to left, #0000 var(--space-4), var(--gray-black) var(--space-4));
4748
4880
  overflow-y:auto;
@@ -30,6 +30,7 @@ export * from './list-item/list-item';
30
30
  export * from './loading-indicator/loading-indicator';
31
31
  export * from './modal';
32
32
  export * from './navigation-menu';
33
+ export * from './page';
33
34
  export * from './page-section';
34
35
  export * from './password-input';
35
36
  export * from './primitives/calendar';
package/lib-esm/index.js CHANGED
@@ -34,6 +34,7 @@ export { ActionCell, Cell, Column, DropIndicator, Row, Table, TableBody, TableHe
34
34
  export { LoadingIndicator } from './loading-indicator/loading-indicator.js';
35
35
  export { Modal } from './modal/modal.js';
36
36
  export { NavigationMenu } from './navigation-menu/index.js';
37
+ export { Page } from './page/index.js';
37
38
  export { PageSection } from './page-section/index.js';
38
39
  export { PasswordInput } from './password-input/password-input.js';
39
40
  export { Calendar } from './primitives/calendar/calendar.js';
@@ -89,5 +90,6 @@ export { Breakpoint, useBreakpoint } from './utils/useBreakpoint.js';
89
90
  export { useFullTextTooltip } from './utils/useFullTextTooltip.js';
90
91
  export { getUniqueId, useUniqueId } from './utils/useUniqueId.js';
91
92
  export { VisuallyHidden } from './visually-hidden/visually-hidden.js';
93
+ export { useMainSectionSidebar, usePageNavigation } from './page/page-context.js';
92
94
  export { useNotification } from './primitives/notification/notification-provider.js';
93
95
  export { useTabs } from './primitives/tabs/use-tabs.js';
@@ -1,16 +1,40 @@
1
- export { usePage } from './page-context';
1
+ export { useMainSectionSidebar, usePageNavigation } from './page-context';
2
2
  export * from './types';
3
- export declare const Page: import("react").ForwardRefExoticComponent<import("./types").PageProps & import("react").RefAttributes<HTMLDivElement>> & {
3
+ export declare const Page: import("react").ForwardRefExoticComponent<import("./types").PageLayoutProps & import("react").RefAttributes<HTMLDivElement>> & {
4
+ /**
5
+ * Top level navigation landmark on the left side of the page.
6
+ */
4
7
  Navigation: import("react").ForwardRefExoticComponent<import("./types").PageNavigationProps & import("react").RefAttributes<HTMLDivElement>>;
5
8
  /**
6
- * Top level landmark placed at the top of the page.
7
- * Contains two subcomponents for contents:
9
+ * Top level header landmark placed at the top of the page.
10
+ * It should contain two subcomponents:
8
11
  * - PageGlobalHeader.SearchContainer
9
12
  * - PageGlobalHeader.SideContentContainer
10
13
  */
11
- GlobalHeader: import("react").ForwardRefExoticComponent<import("./types").GlobalHeaderProps & import("react").RefAttributes<HTMLDivElement>> & {
14
+ GlobalHeader: import("react").ForwardRefExoticComponent<import("./types").PageGlobalHeaderProps & import("react").RefAttributes<HTMLDivElement>> & {
12
15
  SearchContainer: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
13
16
  SideContentContainer: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
14
17
  };
15
- Content: import("react").ForwardRefExoticComponent<import("./types").PageContentProps & import("react").RefAttributes<HTMLDivElement>>;
18
+ /**
19
+ * Main content area of the page.
20
+ * Contains two subcomponents:
21
+ * - Page.MainContent.ContentScrollableSection
22
+ * - Page.MainContent.Complementary (sidebar-like section with hide/show functionality)
23
+ */
24
+ MainSection: import("react").ForwardRefExoticComponent<import("./types").PageMainSectionProps & import("react").RefAttributes<HTMLDivElement>> & {
25
+ Content: import("react").ForwardRefExoticComponent<import("./types").PageMainProps & import("react").RefAttributes<HTMLDivElement>>;
26
+ Sidebar: import("react").ForwardRefExoticComponent<import("./types").PageMainSectionSidebarProps & import("react").RefAttributes<HTMLDivElement>>;
27
+ };
28
+ /**
29
+ * Sub navigation area of the page.
30
+ */
31
+ SubNavigation: import("react").ForwardRefExoticComponent<import("./types").PageSubNavigationProps & import("react").RefAttributes<HTMLDivElement>>;
32
+ /**
33
+ * Page header with title and actions.
34
+ */
35
+ PageHeader: ((props: import("./types").PagePageHeaderProps) => import("react/jsx-runtime").JSX.Element) & {
36
+ StartElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
37
+ EndElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
38
+ Corner: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
39
+ };
16
40
  };
@@ -0,0 +1,39 @@
1
+ import { PageGlobalHeader } from './page-global-header.js';
2
+ import { MainSection } from './page-main-section.js';
3
+ import { PageNavigation } from './page-navigation.js';
4
+ import { PagePageHeader } from './page-page-header.js';
5
+ import { PageRoot } from './page-root.js';
6
+ import { PageSubNavigation } from './page-subnavigation.js';
7
+ import 'react/jsx-runtime';
8
+ import 'react';
9
+
10
+ const Page = Object.assign(PageRoot, {
11
+ /**
12
+ * Top level navigation landmark on the left side of the page.
13
+ */
14
+ Navigation: PageNavigation,
15
+ /**
16
+ * Top level header landmark placed at the top of the page.
17
+ * It should contain two subcomponents:
18
+ * - PageGlobalHeader.SearchContainer
19
+ * - PageGlobalHeader.SideContentContainer
20
+ */
21
+ GlobalHeader: PageGlobalHeader,
22
+ /**
23
+ * Main content area of the page.
24
+ * Contains two subcomponents:
25
+ * - Page.MainContent.ContentScrollableSection
26
+ * - Page.MainContent.Complementary (sidebar-like section with hide/show functionality)
27
+ */
28
+ MainSection,
29
+ /**
30
+ * Sub navigation area of the page.
31
+ */
32
+ SubNavigation: PageSubNavigation,
33
+ /**
34
+ * Page header with title and actions.
35
+ */
36
+ PageHeader: PagePageHeader
37
+ });
38
+
39
+ export { Page };
@@ -1,27 +1,19 @@
1
- import { type PropsWithChildren } from 'react';
2
- export interface PageContextValuesType {
1
+ export interface PageFastContextValuesType {
3
2
  navigationExpanded: boolean;
4
- setNavigationExpanded: (expanded: boolean) => void;
5
- toggleNavigationExpanded: () => void;
6
3
  pageContainer: HTMLElement | null;
7
- setPageContainer: (container: HTMLDivElement | null) => void;
8
4
  globalHeaderContainer: HTMLDivElement | null;
9
- setGlobalHeaderContainer: (container: HTMLDivElement | null) => void;
5
+ mainSectionSidebarVisible: boolean;
10
6
  }
11
- export interface PageContextProps {
12
- /**
13
- * Whether navigation is initially expanded
14
- * */
15
- defaultNavigationExpanded: boolean;
16
- /**
17
- * Callback called when the navigation is toggled
18
- * */
19
- onToggleNavigationExpanded?: (nextState: boolean) => void;
20
- }
21
- export declare const PageContext: import("react").Context<PageContextValuesType | null>;
22
- export declare const PageContextProvider: ({ children, onToggleNavigationExpanded, defaultNavigationExpanded, }: PropsWithChildren<PageContextProps>) => import("react/jsx-runtime").JSX.Element;
23
- export declare const usePage: () => {
7
+ export declare const PageProvider: ({ children }: {
8
+ 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;
10
+ export declare const usePageNavigation: () => {
24
11
  navigationExpanded: boolean;
25
12
  setNavigationExpanded: (expanded: boolean) => void;
26
13
  toggleNavigationExpanded: () => void;
27
14
  };
15
+ export declare const useMainSectionSidebar: () => {
16
+ mainSectionSidebarVisible: boolean;
17
+ setMainSectionSidebarVisible: (visible: boolean) => void;
18
+ toggleMainSectionSidebarVisible: () => void;
19
+ };
@@ -0,0 +1,50 @@
1
+ import { createFastContext } from '../utils/fast-context.js';
2
+
3
+ const {
4
+ Provider: PageProvider,
5
+ useStore: usePageStore,
6
+ useStoreSetter: usePageStoreSetter
7
+ } = createFastContext({
8
+ globalHeaderContainer: null,
9
+ mainSectionSidebarVisible: true,
10
+ navigationExpanded: true,
11
+ pageContainer: null
12
+ });
13
+ const usePageNavigation = () => {
14
+ const [navigationExpanded, setPageStore] = usePageStore(store => store.navigationExpanded);
15
+ const setNavigationExpanded = expanded => {
16
+ setPageStore({
17
+ navigationExpanded: expanded
18
+ });
19
+ };
20
+ const toggleNavigationExpanded = () => {
21
+ setPageStore({
22
+ navigationExpanded: !navigationExpanded
23
+ });
24
+ };
25
+ return {
26
+ navigationExpanded,
27
+ setNavigationExpanded,
28
+ toggleNavigationExpanded
29
+ };
30
+ };
31
+ const useMainSectionSidebar = () => {
32
+ const [mainSectionSidebarVisible, setPageStore] = usePageStore(store => store.mainSectionSidebarVisible);
33
+ const setMainSectionSidebarVisible = visible => {
34
+ setPageStore({
35
+ mainSectionSidebarVisible: visible
36
+ });
37
+ };
38
+ const toggleMainSectionSidebarVisible = () => {
39
+ setPageStore({
40
+ mainSectionSidebarVisible: !mainSectionSidebarVisible
41
+ });
42
+ };
43
+ return {
44
+ mainSectionSidebarVisible,
45
+ setMainSectionSidebarVisible,
46
+ toggleMainSectionSidebarVisible
47
+ };
48
+ };
49
+
50
+ export { PageProvider, useMainSectionSidebar, usePageNavigation, usePageStore, usePageStoreSetter };
@@ -0,0 +1,19 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef } from 'react';
4
+ import styles from './page.module.js';
5
+
6
+ const SearchContainer = /*#__PURE__*/forwardRef(({
7
+ className,
8
+ ...rest
9
+ }, ref) => {
10
+ return jsx("div", {
11
+ ...rest,
12
+ ref: ref,
13
+ className: clsx(styles.searchContainer, className),
14
+ role: "search"
15
+ });
16
+ });
17
+ SearchContainer.displayName = 'SearchContainer';
18
+
19
+ export { SearchContainer };
@@ -0,0 +1,18 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef } from 'react';
4
+ import styles from './page.module.js';
5
+
6
+ const SideContentContainer = /*#__PURE__*/forwardRef(({
7
+ className,
8
+ ...rest
9
+ }, ref) => {
10
+ return jsx("div", {
11
+ ...rest,
12
+ ref: ref,
13
+ className: clsx(styles.sideContentContainer, className)
14
+ });
15
+ });
16
+ SideContentContainer.displayName = 'SideContentContainer';
17
+
18
+ export { SideContentContainer };
@@ -1,6 +1,6 @@
1
- import { type GlobalHeaderProps } from './types';
2
- export declare const PageGlobalHeader: import("react").ForwardRefExoticComponent<GlobalHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
3
- export declare const GlobalHeader: import("react").ForwardRefExoticComponent<GlobalHeaderProps & import("react").RefAttributes<HTMLDivElement>> & {
1
+ import { type PageGlobalHeaderProps } from './types';
2
+ export declare const PageGlobalHeaderRoot: import("react").ForwardRefExoticComponent<PageGlobalHeaderProps & import("react").RefAttributes<HTMLDivElement>>;
3
+ export declare const PageGlobalHeader: import("react").ForwardRefExoticComponent<PageGlobalHeaderProps & import("react").RefAttributes<HTMLDivElement>> & {
4
4
  /**
5
5
  * Container for components related to global search.
6
6
  */
@@ -0,0 +1,39 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef } from 'react';
4
+ import { useRefWithEffect as useRefWithEffectMemoized } from '../utils/useRefWithEffect.js';
5
+ import { usePageStoreSetter } from './page-context.js';
6
+ import { SearchContainer } from './page-global-header-search-container.js';
7
+ import { SideContentContainer } from './page-global-header-side-content-container.js';
8
+ import styles from './page.module.js';
9
+
10
+ const PageGlobalHeaderRoot = /*#__PURE__*/forwardRef(({
11
+ className,
12
+ ...rest
13
+ }, forwardedRef) => {
14
+ const setPageStore = usePageStoreSetter();
15
+ const setRefs = useRefWithEffectMemoized(forwardedRef, node => {
16
+ setPageStore({
17
+ globalHeaderContainer: node
18
+ });
19
+ });
20
+ return jsx("div", {
21
+ ...rest,
22
+ ref: setRefs,
23
+ className: clsx(styles.globalHeader, className),
24
+ role: "banner"
25
+ });
26
+ });
27
+ PageGlobalHeaderRoot.displayName = 'GlobalHeader';
28
+ const PageGlobalHeader = Object.assign(PageGlobalHeaderRoot, {
29
+ /**
30
+ * Container for components related to global search.
31
+ */
32
+ SearchContainer,
33
+ /**
34
+ * Container for all components excluding ones related to global search.
35
+ */
36
+ SideContentContainer
37
+ });
38
+
39
+ export { PageGlobalHeader, PageGlobalHeaderRoot };
@@ -0,0 +1,2 @@
1
+ import { type PageMainProps } from './types';
2
+ export declare const PageMainSectionContent: import("react").ForwardRefExoticComponent<PageMainProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,17 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef } from 'react';
4
+ import styles from './page.module.js';
5
+
6
+ const PageMainSectionContent = /*#__PURE__*/forwardRef(({
7
+ className,
8
+ ...rest
9
+ }, forwardedRef) => {
10
+ return jsx("div", {
11
+ ...rest,
12
+ ref: forwardedRef,
13
+ className: clsx(styles.content, className)
14
+ });
15
+ });
16
+
17
+ export { PageMainSectionContent };
@@ -0,0 +1,2 @@
1
+ import { type PageMainSectionSidebarProps } from './types';
2
+ export declare const PageMainSectionSidebar: import("react").ForwardRefExoticComponent<PageMainSectionSidebarProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,27 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef } from 'react';
4
+ import { useBreakpoint, Breakpoint } from '../utils/useBreakpoint.js';
5
+ import { useMainSectionSidebar } from './page-context.js';
6
+ import styles from './page.module.js';
7
+
8
+ const PageMainSectionSidebar = /*#__PURE__*/forwardRef(({
9
+ className,
10
+ ...rest
11
+ }, forwardedRef) => {
12
+ const {
13
+ mainSectionSidebarVisible
14
+ } = useMainSectionSidebar();
15
+ const breakpoint = useBreakpoint();
16
+ if (!mainSectionSidebarVisible || breakpoint <= Breakpoint.Medium) {
17
+ return null;
18
+ }
19
+ return jsx("div", {
20
+ ...rest,
21
+ ref: forwardedRef,
22
+ className: clsx(styles.sidebar, className),
23
+ role: "complementary"
24
+ });
25
+ });
26
+
27
+ export { PageMainSectionSidebar };
@@ -0,0 +1,6 @@
1
+ import { type PageMainSectionProps } from './types';
2
+ export declare const PageMainSection: import("react").ForwardRefExoticComponent<PageMainSectionProps & import("react").RefAttributes<HTMLDivElement>>;
3
+ export declare const MainSection: import("react").ForwardRefExoticComponent<PageMainSectionProps & import("react").RefAttributes<HTMLDivElement>> & {
4
+ Content: import("react").ForwardRefExoticComponent<import("./types").PageMainProps & import("react").RefAttributes<HTMLDivElement>>;
5
+ Sidebar: import("react").ForwardRefExoticComponent<import("./types").PageMainSectionSidebarProps & import("react").RefAttributes<HTMLDivElement>>;
6
+ };
@@ -0,0 +1,23 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef } from 'react';
4
+ import { PageMainSectionContent } from './page-main-section-content.js';
5
+ import { PageMainSectionSidebar } from './page-main-section-sidebar.js';
6
+ import styles from './page.module.js';
7
+
8
+ const PageMainSection = /*#__PURE__*/forwardRef(({
9
+ className,
10
+ ...rest
11
+ }, forwardedRef) => {
12
+ return jsx("div", {
13
+ ...rest,
14
+ ref: forwardedRef,
15
+ className: clsx(styles.mainSection, className)
16
+ });
17
+ });
18
+ const MainSection = Object.assign(PageMainSection, {
19
+ Content: PageMainSectionContent,
20
+ Sidebar: PageMainSectionSidebar
21
+ });
22
+
23
+ export { MainSection, PageMainSection };
@@ -0,0 +1,84 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { Portal, FocusTrapRegion } from '@ariakit/react';
3
+ import clsx from 'clsx';
4
+ import { forwardRef, useRef, useCallback } from 'react';
5
+ import { useBreakpoint, Breakpoint } from '../utils/useBreakpoint.js';
6
+ import { usePageStore } from './page-context.js';
7
+ import styles from './page.module.js';
8
+
9
+ const createPortalElementDiv = () => {
10
+ const div = document.createElement('div');
11
+ // Adds className with display:contents property.
12
+ // We want to display only contents of the portal which has position absolute
13
+ // but not the "anchor" which points where the portal should be placed
14
+ div.classList.add(styles.portalEntry);
15
+ return div;
16
+ };
17
+ const PageNavigation = /*#__PURE__*/forwardRef(({
18
+ className,
19
+ children,
20
+ ...rest
21
+ }, forwardedRef) => {
22
+ const [{
23
+ navigationExpanded,
24
+ globalHeaderContainer,
25
+ pageContainer
26
+ }] = usePageStore(store => {
27
+ return {
28
+ navigationExpanded: store.navigationExpanded,
29
+ globalHeaderContainer: store.globalHeaderContainer,
30
+ pageContainer: store.pageContainer
31
+ };
32
+ });
33
+ const breakpoint = useBreakpoint();
34
+ const largeBreakpointActive = breakpoint >= Breakpoint.Large;
35
+ const lessOrEqualMediumBreakpointActive = breakpoint <= Breakpoint.Medium;
36
+ const isFullscreenNavigation = lessOrEqualMediumBreakpointActive && navigationExpanded;
37
+ const portalElement = useRef(null);
38
+ const getPortalElement = useCallback(() => {
39
+ if (!pageContainer || !globalHeaderContainer) {
40
+ return null;
41
+ }
42
+ if (!portalElement.current) {
43
+ portalElement.current = createPortalElementDiv();
44
+ }
45
+ let portalRoot;
46
+ if (lessOrEqualMediumBreakpointActive) {
47
+ portalRoot = globalHeaderContainer;
48
+ if (pageContainer?.contains(portalElement.current)) {
49
+ pageContainer.removeChild(portalElement.current);
50
+ }
51
+ } else {
52
+ portalRoot = pageContainer;
53
+ if (globalHeaderContainer?.contains(portalElement.current)) {
54
+ globalHeaderContainer.removeChild(portalElement.current);
55
+ }
56
+ }
57
+ portalRoot.appendChild(portalElement.current);
58
+ return portalElement.current;
59
+ }, [pageContainer, globalHeaderContainer, lessOrEqualMediumBreakpointActive]);
60
+ return jsx(Portal, {
61
+ ...rest,
62
+ className: clsx(styles.navigationPortal, {
63
+ [styles.navigationPortalLargeExpanded]: largeBreakpointActive && navigationExpanded,
64
+ [styles.navigationPortalLargeCollapsed]: largeBreakpointActive && !navigationExpanded,
65
+ [styles.navigationPortalOverlayCollapsed]: lessOrEqualMediumBreakpointActive && !navigationExpanded,
66
+ [styles.navigationPortalOverlayExpanded]: lessOrEqualMediumBreakpointActive && navigationExpanded
67
+ }),
68
+ "data-state": navigationExpanded ? 'expanded' : 'collapsed',
69
+ portalElement: getPortalElement,
70
+ preserveTabOrder: true,
71
+ role: "navigation",
72
+ children: jsx(FocusTrapRegion, {
73
+ ref: forwardedRef,
74
+ className: clsx(styles.navigationContent, className),
75
+ enabled: isFullscreenNavigation,
76
+ children: typeof children === 'function' ? children({
77
+ expanded: Boolean(navigationExpanded)
78
+ }) : children
79
+ })
80
+ });
81
+ });
82
+ PageNavigation.displayName = 'Navigation';
83
+
84
+ export { PageNavigation };
@@ -0,0 +1,6 @@
1
+ import { type PagePageHeaderProps } from './types';
2
+ export declare const PagePageHeader: ((props: PagePageHeaderProps) => import("react/jsx-runtime").JSX.Element) & {
3
+ StartElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
4
+ EndElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
5
+ Corner: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
6
+ };
@@ -0,0 +1,18 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { PageHeader } from '../primitives/page-header/page-header.js';
3
+
4
+ const PagePageHeaderRoot = props => {
5
+ return jsx(PageHeader.Root, {
6
+ ...props,
7
+ as: "div",
8
+ sticky: false,
9
+ variant: "inline"
10
+ });
11
+ };
12
+ const PagePageHeader = Object.assign(PagePageHeaderRoot, {
13
+ StartElements: PageHeader.StartElements,
14
+ EndElements: PageHeader.EndElements,
15
+ Corner: PageHeader.Corner
16
+ });
17
+
18
+ export { PagePageHeader };
@@ -1,2 +1,2 @@
1
- import { type PageProps } from './types';
2
- export declare const PageRoot: import("react").ForwardRefExoticComponent<PageProps & import("react").RefAttributes<HTMLDivElement>>;
1
+ import { type PageLayoutProps } from './types';
2
+ export declare const PageRoot: import("react").ForwardRefExoticComponent<PageLayoutProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,100 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import clsx from 'clsx';
3
+ import { forwardRef, useEffect, Children, isValidElement } from 'react';
4
+ import { useBreakpoint, Breakpoint } from '../utils/useBreakpoint.js';
5
+ import { useRefWithEffect as useRefWithEffectMemoized } from '../utils/useRefWithEffect.js';
6
+ import { PageProvider, usePageStore } from './page-context.js';
7
+ import { PageGlobalHeader } from './page-global-header.js';
8
+ import { MainSection } from './page-main-section.js';
9
+ import { PageNavigation } from './page-navigation.js';
10
+ import { PagePageHeader } from './page-page-header.js';
11
+ import { PageSubNavigation } from './page-subnavigation.js';
12
+ import styles from './page.module.js';
13
+
14
+ const PageRoot = /*#__PURE__*/forwardRef(({
15
+ onToggleNavigationExpanded,
16
+ defaultNavigationExpanded,
17
+ children,
18
+ ...rest
19
+ }, forwardedRef) => {
20
+ return jsx(PageProvider, {
21
+ children: jsx(PageLayout, {
22
+ ...rest,
23
+ ref: forwardedRef,
24
+ defaultNavigationExpanded: defaultNavigationExpanded,
25
+ onToggleNavigationExpanded: onToggleNavigationExpanded,
26
+ children: children
27
+ })
28
+ });
29
+ });
30
+ PageRoot.displayName = 'PageRoot';
31
+ const PageLayout = /*#__PURE__*/forwardRef(({
32
+ defaultNavigationExpanded,
33
+ className,
34
+ children,
35
+ ...rest
36
+ }, forwardedRef) => {
37
+ const [navigationExpanded, setPageStoreData] = usePageStore(store => store.navigationExpanded);
38
+ const breakpoint = useBreakpoint();
39
+ const xxLargeBreakpointActive = breakpoint === Breakpoint.XXLarge;
40
+ const lessOrEqualMediumBreakpointActive = breakpoint <= Breakpoint.Medium;
41
+ const isFullscreenNavigation = lessOrEqualMediumBreakpointActive && navigationExpanded;
42
+ const setRefs = useRefWithEffectMemoized(forwardedRef, node => setPageStoreData({
43
+ pageContainer: node
44
+ }));
45
+ // this effect has to fire once to set initial state of the navigationExpanded
46
+ useEffect(() => {
47
+ setPageStoreData({
48
+ navigationExpanded: defaultNavigationExpanded ?? xxLargeBreakpointActive
49
+ });
50
+ // eslint-disable-next-line react-hooks/exhaustive-deps
51
+ }, []);
52
+ const Slots = getChildrenForLandmarks(children);
53
+ return jsxs("div", {
54
+ ...rest,
55
+ ref: setRefs,
56
+ className: clsx(styles.page, {
57
+ [styles.pageNavigationXXLargeExpanded]: xxLargeBreakpointActive && navigationExpanded,
58
+ [styles.pageNavigationXXLargeCollapsed]: xxLargeBreakpointActive && !navigationExpanded,
59
+ [styles.pageMediumOrLessViewport]: breakpoint <= Breakpoint.Medium
60
+ }, className),
61
+ children: [Slots.Navigation, Slots.GlobalHeader, jsxs("div", {
62
+ // hide fixed focus trap region problem and overlaying content on the navigation
63
+ className: clsx(styles.pageMain, {
64
+ [styles.hide]: isFullscreenNavigation
65
+ }, className),
66
+ role: "main",
67
+ children: [jsx("div", {
68
+ className: clsx(styles.topSection),
69
+ children: Slots.TopSection
70
+ }), Slots.MainSection]
71
+ })]
72
+ });
73
+ });
74
+ PageLayout.displayName = 'PageLayout';
75
+ const getChildrenForLandmarks = children => {
76
+ return Children.toArray(children).reduce((acc, child) => {
77
+ if (! /*#__PURE__*/isValidElement(child)) {
78
+ return acc;
79
+ }
80
+ if (child.type === PageNavigation) {
81
+ acc.Navigation = child;
82
+ } else if (child.type === PageGlobalHeader) {
83
+ acc.GlobalHeader = child;
84
+ } else if (child.type === MainSection) {
85
+ acc.MainSection = child;
86
+ } else if (child.type === PagePageHeader) {
87
+ acc.TopSection.unshift(child);
88
+ } else if (child.type === PageSubNavigation) {
89
+ acc.TopSection.push(child);
90
+ }
91
+ return acc;
92
+ }, {
93
+ Navigation: null,
94
+ MainSection: null,
95
+ GlobalHeader: null,
96
+ TopSection: []
97
+ });
98
+ };
99
+
100
+ export { PageRoot };
@@ -0,0 +1,2 @@
1
+ import { type PageSubNavigationProps } from './types';
2
+ export declare const PageSubNavigation: import("react").ForwardRefExoticComponent<PageSubNavigationProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,15 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { forwardRef } from 'react';
3
+
4
+ const PageSubNavigation = /*#__PURE__*/forwardRef(({
5
+ className,
6
+ ...rest
7
+ }, forwardedRef) => {
8
+ return jsx("div", {
9
+ ...rest,
10
+ ref: forwardedRef,
11
+ className: className
12
+ });
13
+ });
14
+
15
+ export { PageSubNavigation };
@@ -0,0 +1,4 @@
1
+ import '../index.css';
2
+ var styles = {"page":"bp_page_module_page--47219","globalHeader":"bp_page_module_globalHeader--47219","sideContentContainer":"bp_page_module_sideContentContainer--47219","searchContainer":"bp_page_module_searchContainer--47219","pageMain":"bp_page_module_pageMain--47219","topSection":"bp_page_module_topSection--47219","mainSection":"bp_page_module_mainSection--47219","content":"bp_page_module_content--47219","sidebar":"bp_page_module_sidebar--47219","navigationPortal":"bp_page_module_navigationPortal--47219","navigationContent":"bp_page_module_navigationContent--47219","navigationPortalLargeCollapsed":"bp_page_module_navigationPortalLargeCollapsed--47219","navigationPortalLargeExpanded":"bp_page_module_navigationPortalLargeExpanded--47219","hide":"bp_page_module_hide--47219","pageMediumOrLessViewport":"bp_page_module_pageMediumOrLessViewport--47219","search":"bp_page_module_search--47219","navigationPortalOverlayCollapsed":"bp_page_module_navigationPortalOverlayCollapsed--47219","navigationPortalOverlayExpanded":"bp_page_module_navigationPortalOverlayExpanded--47219","pageNavigationXXLargeCollapsed":"bp_page_module_pageNavigationXXLargeCollapsed--47219","pageNavigationXXLargeExpanded":"bp_page_module_pageNavigationXXLargeExpanded--47219","portalEntry":"bp_page_module_portalEntry--47219"};
3
+
4
+ export { styles as default };
@@ -1,22 +1,32 @@
1
1
  import { type ReactNode } from 'react';
2
- import { type PageContextProps } from './page-context';
3
- export type PageLayoutProps = React.HTMLAttributes<HTMLDivElement>;
4
- export type GlobalHeaderProps = React.HTMLAttributes<HTMLDivElement>;
5
- export type PageContentProps = React.HTMLAttributes<HTMLDivElement>;
6
- export interface PageProps extends PageLayoutProps, Pick<PageContextProps, 'onToggleNavigationExpanded'> {
2
+ import { type PageHeaderProps } from '../primitives/page-header';
3
+ export interface PageLayoutProps extends React.HTMLAttributes<HTMLDivElement> {
7
4
  /**
8
- * Whether the navigation is initially expanded.
9
- *
10
- * If not provided:
11
- * - in screens > 1220px the navigation will be initially expanded,
12
- * - otherwise it will be initially collapsed,
13
- * */
5
+ * Whether navigation is initially expanded.
6
+ * For viewport greater than 1220px it is expanded by default.
7
+ */
14
8
  defaultNavigationExpanded?: boolean;
9
+ /**
10
+ * Whether main content sidebar is initially expanded.
11
+ * @default true
12
+ */
13
+ defaultMainContentSidebarVisible?: boolean;
14
+ /**
15
+ * Callback called when the navigation is toggled
16
+ */
17
+ onToggleNavigationExpanded?: (nextState: boolean) => void;
15
18
  }
19
+ export type PageGlobalHeaderProps = React.HTMLAttributes<HTMLDivElement>;
20
+ export type PagePageHeaderProps = Omit<PageHeaderProps, 'variant' | 'sticky' | 'as'>;
21
+ export type PageMainProps = React.HTMLAttributes<HTMLDivElement>;
22
+ export type PageMainSectionProps = React.HTMLAttributes<HTMLDivElement>;
23
+ export type PageMainSectionSidebarProps = React.HTMLAttributes<HTMLDivElement>;
24
+ export type PageSubNavigationProps = React.HTMLAttributes<HTMLDivElement>;
25
+ export type PageProps = PageLayoutProps;
16
26
  export interface PageNavigationProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
17
27
  /**
18
28
  * The children to render within the navigation
19
- * */
29
+ */
20
30
  children: ReactNode | (({ expanded }: {
21
31
  expanded: boolean;
22
32
  }) => ReactNode);
@@ -1,10 +1,10 @@
1
- import { type PageHeaderProps } from './types';
2
- export declare const PageHeaderRoot: import("react").ForwardRefExoticComponent<Omit<PageHeaderProps, "ref"> & import("react").RefAttributes<HTMLElement>>;
1
+ import { type HeaderElementTypes, type PageHeaderProps } from './types';
2
+ export declare const PageHeaderRoot: import("react").ForwardRefExoticComponent<PageHeaderProps & import("react").RefAttributes<HeaderElementTypes>>;
3
3
  export declare const PageHeaderCorner: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
4
- export declare const PageHeadeStartElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
4
+ export declare const PageHeaderStartElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
5
5
  export declare const PageHeaderEndElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
6
6
  export declare const PageHeader: {
7
- Root: import("react").ForwardRefExoticComponent<Omit<PageHeaderProps, "ref"> & import("react").RefAttributes<HTMLElement>>;
7
+ Root: import("react").ForwardRefExoticComponent<PageHeaderProps & import("react").RefAttributes<HeaderElementTypes>>;
8
8
  StartElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
9
9
  EndElements: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
10
10
  Corner: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,17 +1,18 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
- import { forwardRef } from 'react';
3
+ import { forwardRef, createElement } from 'react';
4
4
  import styles from './page-header.module.js';
5
5
 
6
6
  const PageHeaderRoot = /*#__PURE__*/forwardRef((props, forwardedRef) => {
7
7
  const {
8
+ as = 'header',
8
9
  className,
9
10
  children,
10
11
  variant,
11
12
  sticky = true,
12
13
  ...rest
13
14
  } = props;
14
- return jsx("header", {
15
+ return /*#__PURE__*/createElement(as, {
15
16
  ...rest,
16
17
  ref: forwardedRef,
17
18
  className: clsx(styles.pageHeader, className, {
@@ -20,9 +21,8 @@ const PageHeaderRoot = /*#__PURE__*/forwardRef((props, forwardedRef) => {
20
21
  [styles.inline]: variant === 'inline'
21
22
  }, {
22
23
  [styles.sticky]: sticky
23
- }),
24
- children: children
25
- });
24
+ })
25
+ }, children);
26
26
  });
27
27
  const PageHeaderCorner = /*#__PURE__*/forwardRef((props, forwardedRef) => {
28
28
  const {
@@ -37,7 +37,7 @@ const PageHeaderCorner = /*#__PURE__*/forwardRef((props, forwardedRef) => {
37
37
  children: children
38
38
  });
39
39
  });
40
- const PageHeadeStartElements = /*#__PURE__*/forwardRef((props, forwardedRef) => {
40
+ const PageHeaderStartElements = /*#__PURE__*/forwardRef((props, forwardedRef) => {
41
41
  const {
42
42
  className,
43
43
  children,
@@ -65,9 +65,9 @@ const PageHeaderEndElements = /*#__PURE__*/forwardRef((props, forwardedRef) => {
65
65
  });
66
66
  const PageHeader = {
67
67
  Root: PageHeaderRoot,
68
- StartElements: PageHeadeStartElements,
68
+ StartElements: PageHeaderStartElements,
69
69
  EndElements: PageHeaderEndElements,
70
70
  Corner: PageHeaderCorner
71
71
  };
72
72
 
73
- export { PageHeadeStartElements, PageHeader, PageHeaderCorner, PageHeaderEndElements, PageHeaderRoot };
73
+ export { PageHeader, PageHeaderCorner, PageHeaderEndElements, PageHeaderRoot, PageHeaderStartElements };
@@ -1,8 +1,17 @@
1
- import type React from 'react';
2
- export interface PageHeaderProps extends React.ComponentPropsWithRef<'header'> {
1
+ import { type HTMLAttributes } from 'react';
2
+ interface HeaderProps extends HTMLAttributes<HTMLElement> {
3
+ as?: 'header';
4
+ }
5
+ interface DivProps extends HTMLAttributes<HTMLDivElement> {
6
+ as: 'div';
7
+ }
8
+ export type HeaderElementTypes = HeaderProps | DivProps;
9
+ export type PageHeaderProps = (DivProps | HeaderProps) & {
3
10
  variant: 'default' | 'inline';
4
- /** When true the header will have `position: sticky`
11
+ /**
12
+ * When true the header will have `position: sticky`
5
13
  * @default true
6
14
  */
7
15
  sticky?: boolean;
8
- }
16
+ };
17
+ export {};
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export declare function createFastContext<Store>(initialState: Store): {
3
+ Provider: ({ children }: {
4
+ children: React.ReactNode;
5
+ }) => import("react/jsx-runtime").JSX.Element;
6
+ useStore: <SelectorOutput>(selector: (store: Store) => SelectorOutput) => [SelectorOutput, (value: Partial<Store>) => void];
7
+ useStoreSetter: () => (value: Partial<Store>) => void;
8
+ };
@@ -0,0 +1,68 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useContext, useState, useEffect, useRef, useCallback, createContext } from 'react';
3
+
4
+ function createFastContext(initialState) {
5
+ function useStoreData() {
6
+ const store = useRef(initialState);
7
+ const get = useCallback(() => store.current, []);
8
+ const subscribers = useRef(new Set());
9
+ const set = useCallback(value => {
10
+ store.current = {
11
+ ...store.current,
12
+ ...value
13
+ };
14
+ subscribers.current.forEach(callback => callback());
15
+ }, []);
16
+ const subscribe = useCallback(callback => {
17
+ subscribers.current.add(callback);
18
+ return () => subscribers.current.delete(callback);
19
+ }, []);
20
+ return {
21
+ get,
22
+ set,
23
+ subscribe
24
+ };
25
+ }
26
+ const StoreContext = /*#__PURE__*/createContext(null);
27
+ function Provider({
28
+ children
29
+ }) {
30
+ return jsx(StoreContext.Provider, {
31
+ value: useStoreData(),
32
+ children: children
33
+ });
34
+ }
35
+ function useStore(selector) {
36
+ const store = useContext(StoreContext);
37
+ if (!store) {
38
+ throw new Error('Store not found');
39
+ }
40
+ const [state, setState] = useState(() => selector(store.get() || initialState));
41
+ useEffect(() => {
42
+ return store.subscribe(() => {
43
+ setState(selector(store.get()));
44
+ });
45
+ }, [selector, store]);
46
+ // This is an alternative implementation of above code using useSyncExternalStore - requires react 18
47
+ // const state = useSyncExternalStore(
48
+ // store.subscribe,
49
+ // () => selector(store.get()),
50
+ // () => selector(initialState),
51
+ // );
52
+ return [state, store.set];
53
+ }
54
+ function useStoreSetter() {
55
+ const store = useContext(StoreContext);
56
+ if (!store) {
57
+ throw new Error('Store not found');
58
+ }
59
+ return store.set;
60
+ }
61
+ return {
62
+ Provider,
63
+ useStore,
64
+ useStoreSetter
65
+ };
66
+ }
67
+
68
+ export { createFastContext };
@@ -0,0 +1,6 @@
1
+ import { type ForwardedRef, type RefCallback } from 'react';
2
+ /**
3
+ * Returns memoized function that sets ref with side effect.
4
+ */
5
+ declare function useRefWithEffectMemoized<T>(forwardedRef: ForwardedRef<T>, callback?: RefCallback<T>): (node: T | null) => void;
6
+ export { useRefWithEffectMemoized as useRefWithEffect };
@@ -0,0 +1,25 @@
1
+ import { useMemo } from 'react';
2
+
3
+ /**
4
+ * Returns function that sets ref and invokes provided ref callback function.
5
+ */
6
+ function createSetRefWithEffect(forwardedRef, callback) {
7
+ return node => {
8
+ if (callback) {
9
+ callback(node);
10
+ }
11
+ if (typeof forwardedRef === 'function') {
12
+ forwardedRef(node);
13
+ } else if (forwardedRef) {
14
+ forwardedRef.current = node;
15
+ }
16
+ };
17
+ }
18
+ /**
19
+ * Returns memoized function that sets ref with side effect.
20
+ */
21
+ function useRefWithEffectMemoized(forwardedRef, callback) {
22
+ return useMemo(() => createSetRefWithEffect(forwardedRef, callback), [forwardedRef, callback]);
23
+ }
24
+
25
+ export { useRefWithEffectMemoized as useRefWithEffect };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@box/blueprint-web",
3
- "version": "8.8.1",
3
+ "version": "9.0.0",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "publishConfig": {
@@ -22,8 +22,8 @@
22
22
  "**/*.scss"
23
23
  ],
24
24
  "dependencies": {
25
- "@ariakit/react": "0.4.5",
26
- "@ariakit/react-core": "0.4.5",
25
+ "@ariakit/react": "0.4.14",
26
+ "@ariakit/react-core": "0.4.14",
27
27
  "@box/blueprint-web-assets": "^4.30.0",
28
28
  "@internationalized/date": "^3.5.4",
29
29
  "@radix-ui/react-accordion": "1.1.2",
@@ -63,7 +63,7 @@
63
63
  "react-stately": "^3.31.1",
64
64
  "tsx": "^4.16.5"
65
65
  },
66
- "gitHead": "84b0da3b7df701ce396ed038ab4297e2da27d64f",
66
+ "gitHead": "8371b326ea09e2a07955fb57e63e15e9b14abc4c",
67
67
  "module": "lib-esm/index.js",
68
68
  "main": "lib-esm/index.js",
69
69
  "exports": {
@@ -1,2 +0,0 @@
1
- import { type PageContentProps } from './types';
2
- export declare const PageContent: import("react").ForwardRefExoticComponent<PageContentProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,10 +0,0 @@
1
- import { type ForwardedRef, type RefCallback } from 'react';
2
- /**
3
- * Returns function that sets ref and invokes provided ref callback function.
4
- */
5
- export declare function createSetRefWithCallback<T>(forwardedRef: ForwardedRef<T>, callback?: RefCallback<T>): (node: T | null) => void;
6
- /**
7
- * Memoized version of createSetRefWithCallback.
8
- * Returns function that sets ref and invokes provided ref callback function.
9
- */
10
- export declare function useCreateSetRefWithCallbackMemo<T>(forwardedRef: ForwardedRef<T>, callback?: RefCallback<T>): (node: T | null) => void;