@itwin/appui-react 5.24.2 → 5.26.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 (71) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/lib/appui-react/layout/target/TitleBarTarget.d.ts +1 -1
  3. package/lib/appui-react/layout/target/TitleBarTarget.d.ts.map +1 -1
  4. package/lib/appui-react/layout/target/TitleBarTarget.js +3 -3
  5. package/lib/appui-react/layout/target/TitleBarTarget.js.map +1 -1
  6. package/lib/appui-react/layout/target/TitleBarTarget.scss +9 -7
  7. package/lib/appui-react/layout/widget/ContentContainer.d.ts +2 -0
  8. package/lib/appui-react/layout/widget/ContentContainer.d.ts.map +1 -1
  9. package/lib/appui-react/layout/widget/ContentContainer.js +16 -16
  10. package/lib/appui-react/layout/widget/ContentContainer.js.map +1 -1
  11. package/lib/appui-react/layout/widget/FloatingWidget.d.ts +56 -4
  12. package/lib/appui-react/layout/widget/FloatingWidget.d.ts.map +1 -1
  13. package/lib/appui-react/layout/widget/FloatingWidget.js +97 -51
  14. package/lib/appui-react/layout/widget/FloatingWidget.js.map +1 -1
  15. package/lib/appui-react/layout/widget/PanelWidget.d.ts +2 -2
  16. package/lib/appui-react/layout/widget/PanelWidget.d.ts.map +1 -1
  17. package/lib/appui-react/layout/widget/PanelWidget.js +6 -4
  18. package/lib/appui-react/layout/widget/PanelWidget.js.map +1 -1
  19. package/lib/appui-react/layout/widget/TabBar.d.ts +2 -0
  20. package/lib/appui-react/layout/widget/TabBar.d.ts.map +1 -1
  21. package/lib/appui-react/layout/widget/TabBar.js +13 -12
  22. package/lib/appui-react/layout/widget/TabBar.js.map +1 -1
  23. package/lib/appui-react/layout/widget/Widget.d.ts +6 -3
  24. package/lib/appui-react/layout/widget/Widget.d.ts.map +1 -1
  25. package/lib/appui-react/layout/widget/Widget.js +29 -31
  26. package/lib/appui-react/layout/widget/Widget.js.map +1 -1
  27. package/lib/appui-react/layout/widget/widget-content-layout/WidgetContentLayout.d.ts +4 -0
  28. package/lib/appui-react/layout/widget/widget-content-layout/WidgetContentLayout.d.ts.map +1 -1
  29. package/lib/appui-react/layout/widget/widget-content-layout/WidgetContentLayout.js +2 -2
  30. package/lib/appui-react/layout/widget/widget-content-layout/WidgetContentLayout.js.map +1 -1
  31. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.d.ts +2 -2
  32. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.d.ts.map +1 -1
  33. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.js +4 -4
  34. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.js.map +1 -1
  35. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.scss +9 -2
  36. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.d.ts +1 -1
  37. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.d.ts.map +1 -1
  38. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.js +1 -1
  39. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.js.map +1 -1
  40. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.d.ts +2 -4
  41. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.d.ts.map +1 -1
  42. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.js +2 -2
  43. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.js.map +1 -1
  44. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.d.ts +1 -1
  45. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.d.ts.map +1 -1
  46. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.js +1 -1
  47. package/lib/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.js.map +1 -1
  48. package/lib/appui-react/preview/PreviewFeatures.d.ts +11 -3
  49. package/lib/appui-react/preview/PreviewFeatures.d.ts.map +1 -1
  50. package/lib/appui-react/preview/PreviewFeatures.js +4 -2
  51. package/lib/appui-react/preview/PreviewFeatures.js.map +1 -1
  52. package/lib/appui-react/preview/control-widget-visibility/CloseWidgetButton.d.ts +3 -0
  53. package/lib/appui-react/preview/control-widget-visibility/CloseWidgetButton.d.ts.map +1 -1
  54. package/lib/appui-react/preview/control-widget-visibility/CloseWidgetButton.js +11 -2
  55. package/lib/appui-react/preview/control-widget-visibility/CloseWidgetButton.js.map +1 -1
  56. package/lib/appui-react/preview/widget-tab-actions/Widget.d.ts +10 -0
  57. package/lib/appui-react/preview/widget-tab-actions/Widget.d.ts.map +1 -0
  58. package/lib/appui-react/preview/widget-tab-actions/Widget.js +242 -0
  59. package/lib/appui-react/preview/widget-tab-actions/Widget.js.map +1 -0
  60. package/lib/appui-react/preview/widget-tab-actions/Widget.scss +198 -0
  61. package/lib/appui-react/preview/widget-tab-actions/useWidgetTabActions.d.ts +6 -0
  62. package/lib/appui-react/preview/widget-tab-actions/useWidgetTabActions.d.ts.map +1 -0
  63. package/lib/appui-react/preview/widget-tab-actions/useWidgetTabActions.js +18 -0
  64. package/lib/appui-react/preview/widget-tab-actions/useWidgetTabActions.js.map +1 -0
  65. package/lib/cjs/appui-react/layout/target/TitleBarTarget.scss +9 -7
  66. package/lib/cjs/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.scss +9 -2
  67. package/lib/cjs/appui-react/preview/widget-tab-actions/Widget.scss +198 -0
  68. package/lib/esm/appui-react/layout/target/TitleBarTarget.scss +9 -7
  69. package/lib/esm/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.scss +9 -2
  70. package/lib/esm/appui-react/preview/widget-tab-actions/Widget.scss +198 -0
  71. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderIconToolbar.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderIconToolbar.scss\";\nimport * as React from \"react\";\nimport {\n ButtonGroup,\n Divider,\n DropdownMenu,\n IconButton,\n MenuDivider,\n MenuItem,\n Text,\n Tooltip,\n} from \"@itwin/itwinui-react\";\nimport { SvgMore, SvgSearch } from \"@itwin/itwinui-icons-react\";\nimport { HeaderSearch } from \"./HeaderSearch.js\";\nimport type { WidgetContentLayout } from \"../WidgetContentLayout.js\";\n\ntype WidgetContentLayoutHeaderProps = React.ComponentProps<\n typeof WidgetContentLayout.Header\n>;\ntype IconMenu = NonNullable<WidgetContentLayoutHeaderProps[\"icons\"]>[number];\n\ninterface IconMenuSearch {\n type: \"search\";\n}\n\ntype SearchExpandedState = [\n boolean,\n React.Dispatch<React.SetStateAction<boolean>>\n];\n\ninterface HeaderIconToolbarProps\n extends Pick<WidgetContentLayoutHeaderProps, \"iconSize\" | \"onSearch\"> {\n /** Array of icon menu items to display, including regular icons, search, and dividers. */\n menuIcons: (IconMenu | IconMenuSearch)[];\n /** State tuple controlling whether the search box is expanded or collapsed. */\n searchExpandedState: SearchExpandedState;\n}\n\n/**\n * Header toolbar component that displays menu icons with overflow handling.\n * Renders a button group with icons, search functionality, and an overflow menu.\n * Icons that don't fit in the available space are moved into a dropdown menu.\n * @internal\n */\nexport function HeaderIconToolbar(props: HeaderIconToolbarProps) {\n const [searchIsExpanded, setSearchIsExpanded] = props.searchExpandedState;\n const searchState = React.useState(\"\");\n\n return (\n <div\n className=\"nz-widget-widgetContentLayout-header-headerIconToolbar\"\n data-_appui-icon-size={props.iconSize}\n data-_appui-search-expanded={searchIsExpanded ? \"true\" : \"false\"}\n data-_appui-single-item={props.menuIcons.length === 1 ? \"true\" : \"false\"}\n >\n <ButtonGroup\n key={String(searchIsExpanded)}\n className=\"nz-buttonGroup\"\n overflowPlacement=\"end\"\n overflowButton={(overflowStart) => (\n <DropdownMenu\n menuItems={(close) =>\n Array(props.menuIcons.length - overflowStart)\n .fill(null)\n .map((_, _index) => {\n const index = overflowStart + _index;\n const icon = props.menuIcons.at(index);\n if (!icon) return <></>;\n return icon.type === \"divider\" ? (\n _index === 0 || searchIsExpanded ? (\n <React.Fragment key={index}></React.Fragment>\n ) : (\n <MenuDivider key={index} />\n )\n ) : icon.type === \"search\" ? (\n !searchIsExpanded ? (\n <MenuItem\n key={index}\n onClick={() => {\n close();\n setSearchIsExpanded(true);\n }}\n startIcon={<SvgSearch />}\n >\n Search\n </MenuItem>\n ) : (\n <React.Fragment key={index}></React.Fragment>\n )\n ) : icon.tooltipContent ? (\n <Tooltip content={icon.tooltipContent} key={index}>\n <MenuItem\n isSelected={icon.isActive}\n disabled={icon.disabled}\n key={index}\n onClick={() => {\n icon.onClick();\n close();\n }}\n startIcon={<>{icon.icon}</>}\n >\n {icon.label}\n </MenuItem>\n </Tooltip>\n ) : (\n <MenuItem\n isSelected={icon.isActive}\n disabled={icon.disabled}\n key={index}\n onClick={() => {\n icon.onClick();\n close();\n }}\n startIcon={<>{icon.icon}</>}\n >\n {icon.label}\n </MenuItem>\n );\n })\n }\n >\n <IconButton\n size={props.iconSize}\n styleType=\"borderless\"\n aria-label=\"More\"\n >\n <SvgMore />\n </IconButton>\n </DropdownMenu>\n )}\n >\n {props.menuIcons.map((icon, index) =>\n icon.type === \"divider\" ? (\n <Divider\n orientation=\"vertical\"\n key={icon.key ?? `divider-${index}`}\n />\n ) : icon.type === \"search\" ? (\n <HeaderSearch\n key=\"search\"\n searchExpandedState={props.searchExpandedState}\n searchState={searchState}\n iconSize={props.iconSize}\n onSearch={props.onSearch}\n />\n ) : (\n <IconButton\n disabled={icon.disabled}\n label={\n icon.tooltipContent ? (\n <div className=\"nz-widget-widgetContentLayout-header-headerIconToolbar-iconButton-tooltip\">\n <Text variant=\"small\">{icon.label}</Text>\n <Text isMuted variant=\"small\">\n {icon.tooltipContent}\n </Text>\n </div>\n ) : (\n icon.label\n )\n }\n key={icon.label}\n size={props.iconSize}\n styleType=\"borderless\"\n onClick={icon.onClick}\n labelProps={{ placement: \"bottom\" }}\n isActive={icon.isActive}\n className=\"nz-iconButton\"\n >\n {icon.icon}\n </IconButton>\n )\n )}\n </ButtonGroup>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"HeaderIconToolbar.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderIconToolbar.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderIconToolbar.scss\";\nimport React from \"react\";\nimport {\n ButtonGroup,\n Divider,\n DropdownMenu,\n IconButton,\n MenuDivider,\n MenuItem,\n Text,\n Tooltip,\n} from \"@itwin/itwinui-react\";\nimport { SvgMore, SvgSearch } from \"@itwin/itwinui-icons-react\";\nimport { HeaderSearch } from \"./HeaderSearch.js\";\nimport type { WidgetContentLayout } from \"../WidgetContentLayout.js\";\n\ntype WidgetContentLayoutHeaderProps = React.ComponentProps<\n typeof WidgetContentLayout.Header\n>;\ntype IconMenu = NonNullable<WidgetContentLayoutHeaderProps[\"icons\"]>[number];\n\ninterface IconMenuSearch {\n type: \"search\";\n}\n\ntype SearchExpandedState = [\n boolean,\n React.Dispatch<React.SetStateAction<boolean>>\n];\n\ninterface HeaderIconToolbarProps\n extends Pick<\n WidgetContentLayoutHeaderProps,\n \"iconSize\" | \"onSearch\" | \"disableSearch\"\n > {\n /** Array of icon menu items to display, including regular icons, search, and dividers. */\n menuIcons: (IconMenu | IconMenuSearch)[];\n /** State tuple controlling whether the search box is expanded or collapsed. */\n searchExpandedState: SearchExpandedState;\n}\n\n/**\n * Header toolbar component that displays menu icons with overflow handling.\n * Renders a button group with icons, search functionality, and an overflow menu.\n * Icons that don't fit in the available space are moved into a dropdown menu.\n * @internal\n */\nexport function HeaderIconToolbar(props: HeaderIconToolbarProps) {\n const [searchIsExpanded, setSearchIsExpanded] = props.searchExpandedState;\n const searchState = React.useState(\"\");\n\n return (\n <div\n className=\"nz-widget-widgetContentLayout-header-headerIconToolbar\"\n data-_appui-icon-size={props.iconSize}\n data-_appui-search-expanded={searchIsExpanded ? \"true\" : \"false\"}\n data-_appui-single-item={props.menuIcons.length === 1 ? \"true\" : \"false\"}\n >\n <ButtonGroup\n key={String(searchIsExpanded)}\n className=\"nz-buttonGroup\"\n overflowPlacement=\"end\"\n overflowButton={(overflowStart) => (\n <DropdownMenu\n menuItems={(close) =>\n Array(props.menuIcons.length - overflowStart)\n .fill(null)\n .map((_, _index) => {\n const index = overflowStart + _index;\n const icon = props.menuIcons.at(index);\n if (!icon) return <></>;\n return icon.type === \"divider\" ? (\n _index === 0 || searchIsExpanded ? (\n <React.Fragment key={index}></React.Fragment>\n ) : (\n <MenuDivider key={index} />\n )\n ) : icon.type === \"search\" ? (\n !searchIsExpanded ? (\n <MenuItem\n key={index}\n onClick={() => {\n close();\n setSearchIsExpanded(true);\n }}\n startIcon={<SvgSearch />}\n disabled={props.disableSearch}\n >\n Search\n </MenuItem>\n ) : (\n <React.Fragment key={index}></React.Fragment>\n )\n ) : icon.tooltipContent ? (\n <Tooltip content={icon.tooltipContent} key={index}>\n <MenuItem\n isSelected={icon.isActive}\n disabled={icon.disabled}\n key={index}\n onClick={() => {\n icon.onClick();\n close();\n }}\n startIcon={<>{icon.icon}</>}\n >\n {icon.label}\n </MenuItem>\n </Tooltip>\n ) : (\n <MenuItem\n isSelected={icon.isActive}\n disabled={icon.disabled}\n key={index}\n onClick={() => {\n icon.onClick();\n close();\n }}\n startIcon={<>{icon.icon}</>}\n >\n {icon.label}\n </MenuItem>\n );\n })\n }\n >\n <IconButton\n size={props.iconSize}\n styleType=\"borderless\"\n aria-label=\"More\"\n className=\"nz-header-overflow-button\"\n >\n <SvgMore />\n </IconButton>\n </DropdownMenu>\n )}\n >\n {props.menuIcons.map((icon, index) =>\n icon.type === \"divider\" ? (\n <Divider\n orientation=\"vertical\"\n key={icon.key ?? `divider-${index}`}\n />\n ) : icon.type === \"search\" ? (\n <HeaderSearch\n key=\"search\"\n searchExpandedState={props.searchExpandedState}\n searchState={searchState}\n iconSize={props.iconSize}\n onSearch={props.onSearch}\n disableSearch={props.disableSearch}\n />\n ) : (\n <IconButton\n disabled={icon.disabled}\n label={\n icon.tooltipContent ? (\n <div className=\"nz-widget-widgetContentLayout-header-headerIconToolbar-iconButton-tooltip\">\n <Text variant=\"small\">{icon.label}</Text>\n <Text isMuted variant=\"small\">\n {icon.tooltipContent}\n </Text>\n </div>\n ) : (\n icon.label\n )\n }\n key={icon.label}\n size={props.iconSize}\n styleType=\"borderless\"\n onClick={icon.onClick}\n labelProps={{ placement: \"bottom\" }}\n isActive={icon.isActive}\n className=\"nz-iconButton\"\n >\n {icon.icon}\n </IconButton>\n )\n )}\n </ButtonGroup>\n </div>\n );\n}\n"]}
@@ -1,16 +1,17 @@
1
1
  @layer appui.component {
2
2
  .nz-widget-widgetContentLayout-header-headerIconToolbar {
3
+ display: flex;
3
4
  --_appui-icon-size: var(--iui-component-height);
4
5
  --_appui-max-search-width: 200px;
5
6
  min-width: var(--_appui-icon-size);
6
7
  min-height: var(--_appui-icon-size);
7
8
 
8
9
  &[data-_appui-icon-size="small"] {
9
- --icon-size: var(--iui-component-height-small);
10
+ --_appui-icon-size: var(--iui-component-height-small);
10
11
  }
11
12
 
12
13
  &[data-_appui-icon-size="large"] {
13
- --icon-size: var(--iui-component-height-large);
14
+ --_appui-icon-size: var(--iui-component-height-large);
14
15
  }
15
16
 
16
17
  &[data-_appui-search-expanded="true"] {
@@ -40,5 +41,11 @@
40
41
  inset-block: unset;
41
42
  }
42
43
  }
44
+
45
+ // when icon-size is small, the button width is 2px wider than the icon size due to a transparent border,
46
+ // so we need to remove the border to make it the same width as the icon
47
+ .nz-header-overflow-button {
48
+ border: 0px;
49
+ }
43
50
  }
44
51
  }
@@ -2,7 +2,7 @@ import "./HeaderLayout.scss";
2
2
  import * as React from "react";
3
3
  import type { WidgetContentLayout } from "../WidgetContentLayout.js";
4
4
  type WidgetContentLayoutHeaderProps = React.ComponentProps<typeof WidgetContentLayout.Header>;
5
- type HeaderLayoutProps = Pick<WidgetContentLayoutHeaderProps, "toggle" | "buttons" | "menu" | "title" | "onSearch" | "icons" | "iconSize" | "children">;
5
+ type HeaderLayoutProps = Pick<WidgetContentLayoutHeaderProps, "toggle" | "buttons" | "menu" | "title" | "onSearch" | "disableSearch" | "icons" | "iconSize" | "children">;
6
6
  /**
7
7
  * A layout component for the header, including optional search, icons, buttons, title, and a menu.
8
8
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderLayout.d.ts","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.tsx"],"names":[],"mappings":"AAKA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,KAAK,8BAA8B,GAAG,KAAK,CAAC,cAAc,CACxD,OAAO,mBAAmB,CAAC,MAAM,CAClC,CAAC;AAEF,KAAK,iBAAiB,GAAG,IAAI,CAC3B,8BAA8B,EAC5B,QAAQ,GACR,SAAS,GACT,MAAM,GACN,OAAO,GACP,UAAU,GACV,OAAO,GACP,UAAU,GACV,UAAU,CACb,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,qBAkDpD"}
1
+ {"version":3,"file":"HeaderLayout.d.ts","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.tsx"],"names":[],"mappings":"AAKA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,KAAK,8BAA8B,GAAG,KAAK,CAAC,cAAc,CACxD,OAAO,mBAAmB,CAAC,MAAM,CAClC,CAAC;AAEF,KAAK,iBAAiB,GAAG,IAAI,CAC3B,8BAA8B,EAC5B,QAAQ,GACR,SAAS,GACT,MAAM,GACN,OAAO,GACP,UAAU,GACV,eAAe,GACf,OAAO,GACP,UAAU,GACV,UAAU,CACb,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,qBAmDpD"}
@@ -25,7 +25,7 @@ export function HeaderLayout(props) {
25
25
  : leftItems.slice(0, 1);
26
26
  const remainingLeftItems = props.title ? leftItems : leftItems.slice(1);
27
27
  return (React.createElement("div", { className: "nz-widget-widgetContentLayout-header-headerLayout" },
28
- (props.onSearch || topBarLeftItems.length > 0 || icons.length > 0) && (React.createElement(HeaderTopBar, { primaryContent: topBarLeftItems, onSearch: props.onSearch, icons: icons, iconSize: props.iconSize })),
28
+ (props.onSearch || topBarLeftItems.length > 0 || icons.length > 0) && (React.createElement(HeaderTopBar, { primaryContent: topBarLeftItems, onSearch: props.onSearch, disableSearch: props.disableSearch, icons: icons, iconSize: props.iconSize })),
29
29
  remainingLeftItems.map((item) => (React.createElement("div", { className: "nz-remainingItems", key: item.key }, item))),
30
30
  props.children));
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderLayout.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EACL,cAAc,EACd,QAAQ,EACR,IAAI,EACJ,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAmBjD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG;QAChB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAC,YAAY,IAAC,GAAG,EAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,GAAI,CAAC,CAAC,CAAC,SAAS;QAC1E,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CACX,oBAAC,cAAc,IACb,GAAG,EAAC,MAAM,EACV,SAAS,EAAC,SAAS,EACnB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACrC,oBAAC,QAAQ,IAAC,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IACvC,CAAC,CAAC,KAAK,CACC,CACZ,CAAC,IAED,KAAK,CAAC,IAAI,CAAC,KAAK,CACF,CAClB,CAAC,CAAC,CAAC,SAAS;QACb,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACnB,6BAAK,GAAG,EAAC,SAAS,EAAC,SAAS,EAAC,YAAY,IACtC,OAAO,CACJ,CACP,CAAC,CAAC,CAAC,SAAS;KACd,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK;QACjC,CAAC,CAAC;YACE,oBAAC,IAAI,IAAC,GAAG,EAAC,OAAO,EAAC,SAAS,EAAC,UAAU,IACnC,KAAK,CAAC,KAAK,CACP;SACR;QACH,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,MAAM,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,CACL,6BAAK,SAAS,EAAC,mDAAmD;QAC/D,CAAC,KAAK,CAAC,QAAQ,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CACrE,oBAAC,YAAY,IACX,cAAc,EAAE,eAAe,EAC/B,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,CACH;QACA,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAChC,6BAAK,SAAS,EAAC,mBAAmB,EAAC,GAAG,EAAE,IAAI,CAAC,GAAG,IAC7C,IAAI,CACD,CACP,CAAC;QACD,KAAK,CAAC,QAAQ,CACX,CACP,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderLayout.scss\";\nimport * as React from \"react\";\nimport {\n DropdownButton,\n MenuItem,\n Text,\n ToggleSwitch,\n} from \"@itwin/itwinui-react\";\nimport { HeaderTopBar } from \"./HeaderTopBar.js\";\nimport type { WidgetContentLayout } from \"../WidgetContentLayout.js\";\n\ntype WidgetContentLayoutHeaderProps = React.ComponentProps<\n typeof WidgetContentLayout.Header\n>;\n\ntype HeaderLayoutProps = Pick<\n WidgetContentLayoutHeaderProps,\n | \"toggle\"\n | \"buttons\"\n | \"menu\"\n | \"title\"\n | \"onSearch\"\n | \"icons\"\n | \"iconSize\"\n | \"children\"\n>;\n\n/**\n * A layout component for the header, including optional search, icons, buttons, title, and a menu.\n * @internal\n */\nexport function HeaderLayout(props: HeaderLayoutProps) {\n const buttons = props.buttons || [];\n const icons = props.icons || [];\n const leftItems = [\n props.toggle ? <ToggleSwitch key=\"toggle\" {...props.toggle} /> : undefined,\n props.menu ? (\n <DropdownButton\n key=\"menu\"\n className=\"nz-menu\"\n menuItems={props.menu.items.map((i) => (\n <MenuItem key={i.label} onClick={i.onClick}>\n {i.label}\n </MenuItem>\n ))}\n >\n {props.menu.title}\n </DropdownButton>\n ) : undefined,\n buttons.length > 0 ? (\n <div key=\"buttons\" className=\"nz-buttons\">\n {buttons}\n </div>\n ) : undefined,\n ].filter((item) => !!item);\n const topBarLeftItems = props.title\n ? [\n <Text key=\"title\" className=\"nz-title\">\n {props.title}\n </Text>,\n ]\n : leftItems.slice(0, 1);\n const remainingLeftItems = props.title ? leftItems : leftItems.slice(1);\n return (\n <div className=\"nz-widget-widgetContentLayout-header-headerLayout\">\n {(props.onSearch || topBarLeftItems.length > 0 || icons.length > 0) && (\n <HeaderTopBar\n primaryContent={topBarLeftItems}\n onSearch={props.onSearch}\n icons={icons}\n iconSize={props.iconSize}\n />\n )}\n {remainingLeftItems.map((item) => (\n <div className=\"nz-remainingItems\" key={item.key}>\n {item}\n </div>\n ))}\n {props.children}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"HeaderLayout.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderLayout.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EACL,cAAc,EACd,QAAQ,EACR,IAAI,EACJ,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAoBjD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG;QAChB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,oBAAC,YAAY,IAAC,GAAG,EAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,GAAI,CAAC,CAAC,CAAC,SAAS;QAC1E,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CACX,oBAAC,cAAc,IACb,GAAG,EAAC,MAAM,EACV,SAAS,EAAC,SAAS,EACnB,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACrC,oBAAC,QAAQ,IAAC,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IACvC,CAAC,CAAC,KAAK,CACC,CACZ,CAAC,IAED,KAAK,CAAC,IAAI,CAAC,KAAK,CACF,CAClB,CAAC,CAAC,CAAC,SAAS;QACb,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACnB,6BAAK,GAAG,EAAC,SAAS,EAAC,SAAS,EAAC,YAAY,IACtC,OAAO,CACJ,CACP,CAAC,CAAC,CAAC,SAAS;KACd,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK;QACjC,CAAC,CAAC;YACE,oBAAC,IAAI,IAAC,GAAG,EAAC,OAAO,EAAC,SAAS,EAAC,UAAU,IACnC,KAAK,CAAC,KAAK,CACP;SACR;QACH,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,MAAM,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,CACL,6BAAK,SAAS,EAAC,mDAAmD;QAC/D,CAAC,KAAK,CAAC,QAAQ,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CACrE,oBAAC,YAAY,IACX,cAAc,EAAE,eAAe,EAC/B,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,aAAa,EAAE,KAAK,CAAC,aAAa,EAClC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,CACH;QACA,kBAAkB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAChC,6BAAK,SAAS,EAAC,mBAAmB,EAAC,GAAG,EAAE,IAAI,CAAC,GAAG,IAC7C,IAAI,CACD,CACP,CAAC;QACD,KAAK,CAAC,QAAQ,CACX,CACP,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderLayout.scss\";\nimport * as React from \"react\";\nimport {\n DropdownButton,\n MenuItem,\n Text,\n ToggleSwitch,\n} from \"@itwin/itwinui-react\";\nimport { HeaderTopBar } from \"./HeaderTopBar.js\";\nimport type { WidgetContentLayout } from \"../WidgetContentLayout.js\";\n\ntype WidgetContentLayoutHeaderProps = React.ComponentProps<\n typeof WidgetContentLayout.Header\n>;\n\ntype HeaderLayoutProps = Pick<\n WidgetContentLayoutHeaderProps,\n | \"toggle\"\n | \"buttons\"\n | \"menu\"\n | \"title\"\n | \"onSearch\"\n | \"disableSearch\"\n | \"icons\"\n | \"iconSize\"\n | \"children\"\n>;\n\n/**\n * A layout component for the header, including optional search, icons, buttons, title, and a menu.\n * @internal\n */\nexport function HeaderLayout(props: HeaderLayoutProps) {\n const buttons = props.buttons || [];\n const icons = props.icons || [];\n const leftItems = [\n props.toggle ? <ToggleSwitch key=\"toggle\" {...props.toggle} /> : undefined,\n props.menu ? (\n <DropdownButton\n key=\"menu\"\n className=\"nz-menu\"\n menuItems={props.menu.items.map((i) => (\n <MenuItem key={i.label} onClick={i.onClick}>\n {i.label}\n </MenuItem>\n ))}\n >\n {props.menu.title}\n </DropdownButton>\n ) : undefined,\n buttons.length > 0 ? (\n <div key=\"buttons\" className=\"nz-buttons\">\n {buttons}\n </div>\n ) : undefined,\n ].filter((item) => !!item);\n const topBarLeftItems = props.title\n ? [\n <Text key=\"title\" className=\"nz-title\">\n {props.title}\n </Text>,\n ]\n : leftItems.slice(0, 1);\n const remainingLeftItems = props.title ? leftItems : leftItems.slice(1);\n return (\n <div className=\"nz-widget-widgetContentLayout-header-headerLayout\">\n {(props.onSearch || topBarLeftItems.length > 0 || icons.length > 0) && (\n <HeaderTopBar\n primaryContent={topBarLeftItems}\n onSearch={props.onSearch}\n disableSearch={props.disableSearch}\n icons={icons}\n iconSize={props.iconSize}\n />\n )}\n {remainingLeftItems.map((item) => (\n <div className=\"nz-remainingItems\" key={item.key}>\n {item}\n </div>\n ))}\n {props.children}\n </div>\n );\n}\n"]}
@@ -1,10 +1,8 @@
1
1
  import "./HeaderSearch.scss";
2
- import * as React from "react";
3
- import type { WidgetContentLayout } from "../WidgetContentLayout.js";
2
+ import React from "react";
4
3
  import type { HeaderIconToolbar } from "./HeaderIconToolbar.js";
5
- type WidgetContentLayoutHeaderProps = React.ComponentProps<typeof WidgetContentLayout.Header>;
6
4
  type HeaderIconToolbarProps = React.ComponentProps<typeof HeaderIconToolbar>;
7
- interface HeaderSearchProps extends Pick<WidgetContentLayoutHeaderProps, "iconSize" | "onSearch">, Pick<HeaderIconToolbarProps, "searchExpandedState"> {
5
+ interface HeaderSearchProps extends Pick<HeaderIconToolbarProps, "iconSize" | "onSearch" | "disableSearch" | "searchExpandedState"> {
8
6
  /** State tuple for the search text value and its setter function. */
9
7
  searchState: [string, React.Dispatch<React.SetStateAction<string>>];
10
8
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderSearch.d.ts","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.tsx"],"names":[],"mappings":"AAKA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,KAAK,8BAA8B,GAAG,KAAK,CAAC,cAAc,CACxD,OAAO,mBAAmB,CAAC,MAAM,CAClC,CAAC;AACF,KAAK,sBAAsB,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE7E,UAAU,iBACR,SAAQ,IAAI,CAAC,8BAA8B,EAAE,UAAU,GAAG,UAAU,CAAC,EACnE,IAAI,CAAC,sBAAsB,EAAE,qBAAqB,CAAC;IACrD,qEAAqE;IACrE,WAAW,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACrE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,qBA+DpD"}
1
+ {"version":3,"file":"HeaderSearch.d.ts","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.tsx"],"names":[],"mappings":"AAKA,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,KAAK,sBAAsB,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE7E,UAAU,iBACR,SAAQ,IAAI,CACV,sBAAsB,EACtB,UAAU,GAAG,UAAU,GAAG,eAAe,GAAG,qBAAqB,CAClE;IACD,qEAAqE;IACrE,WAAW,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACrE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,qBAgEpD"}
@@ -3,7 +3,7 @@
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import "./HeaderSearch.scss";
6
- import * as React from "react";
6
+ import React from "react";
7
7
  import { SearchBox } from "@itwin/itwinui-react";
8
8
  import { SvgClose, SvgSearch } from "@itwin/itwinui-icons-react";
9
9
  /**
@@ -32,7 +32,7 @@ export function HeaderSearch(props) {
32
32
  }, [isExpanded]);
33
33
  return (React.createElement(SearchBox, { onExpand: () => setIsExpanded(true), isExpanded: isExpanded, className: "nz-widget-widgetContentLayout-header-headerSearch", expandable: true, size: props.iconSize },
34
34
  React.createElement(SearchBox.CollapsedState, null,
35
- React.createElement(SearchBox.ExpandButton, { label: "Search", labelProps: { placement: "bottom" }, size: props.iconSize, styleType: "borderless" },
35
+ React.createElement(SearchBox.ExpandButton, { label: "Search", labelProps: { placement: "bottom" }, size: props.iconSize, styleType: "borderless", disabled: props.disableSearch },
36
36
  React.createElement(SvgSearch, null))),
37
37
  React.createElement(SearchBox.ExpandedState, null,
38
38
  React.createElement(SearchBox.Icon, { size: props.iconSize },
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderSearch.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAgBjE;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,mBAAmB,CAAC;IAC9D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAA0B,IAAI,CAAC,CAAC;IAE7D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,8EAA8E;QAC9E,MAAM,EAAE,GAAG,qBAAqB,CAAC,GAAG,EAAE;YACpC,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC;gBAAE,EAAE,CAAC,cAAc,GAAG,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;QACxD,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO,CACL,oBAAC,SAAS,IACR,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EACnC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAC,mDAAmD,EAC7D,UAAU,QACV,IAAI,EAAE,KAAK,CAAC,QAAQ;QAEpB,oBAAC,SAAS,CAAC,cAAc;YACvB,oBAAC,SAAS,CAAC,YAAY,IACrB,KAAK,EAAC,QAAQ,EACd,UAAU,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,EACnC,IAAI,EAAE,KAAK,CAAC,QAAQ,EACpB,SAAS,EAAC,YAAY;gBAEtB,oBAAC,SAAS,OAAG,CACU,CACA;QAC3B,oBAAC,SAAS,CAAC,aAAa;YACtB,oBAAC,SAAS,CAAC,IAAI,IAAC,IAAI,EAAE,KAAK,CAAC,QAAQ;gBAClC,oBAAC,SAAS,OAAG,CACE;YACjB,oBAAC,SAAS,CAAC,KAAK,IACd,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,CAAC,CAAsC,EAAQ,EAAE;oBACzD,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;oBACrC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC1C,CAAC,EACD,KAAK,EAAE,UAAU,GACjB;YACF,oBAAC,SAAS,CAAC,cAAc,IACvB,IAAI,EAAE,KAAK,CAAC,QAAQ,EACpB,KAAK,EAAC,OAAO,EACb,UAAU,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,EACnC,OAAO,EAAE,GAAG,EAAE;oBACZ,aAAa,CAAC,KAAK,CAAC,CAAC;oBACrB,aAAa,CAAC,EAAE,CAAC,CAAC;oBAClB,IAAI,UAAU;wBAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;gBAED,oBAAC,QAAQ,OAAG,CACa,CACH,CAChB,CACb,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderSearch.scss\";\nimport * as React from \"react\";\n\nimport { SearchBox } from \"@itwin/itwinui-react\";\n\nimport { SvgClose, SvgSearch } from \"@itwin/itwinui-icons-react\";\nimport type { WidgetContentLayout } from \"../WidgetContentLayout.js\";\nimport type { HeaderIconToolbar } from \"./HeaderIconToolbar.js\";\n\ntype WidgetContentLayoutHeaderProps = React.ComponentProps<\n typeof WidgetContentLayout.Header\n>;\ntype HeaderIconToolbarProps = React.ComponentProps<typeof HeaderIconToolbar>;\n\ninterface HeaderSearchProps\n extends Pick<WidgetContentLayoutHeaderProps, \"iconSize\" | \"onSearch\">,\n Pick<HeaderIconToolbarProps, \"searchExpandedState\"> {\n /** State tuple for the search text value and its setter function. */\n searchState: [string, React.Dispatch<React.SetStateAction<string>>];\n}\n\n/**\n * A collapsible search box component for widget headers.\n * Provides an expandable search input with icons that automatically focuses when expanded.\n * @internal\n */\nexport function HeaderSearch(props: HeaderSearchProps) {\n const [isExpanded, setIsExpanded] = props.searchExpandedState;\n const [searchText, setSearchText] = props.searchState;\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n\n React.useEffect(() => {\n if (!isExpanded) return;\n const el = inputRef.current;\n if (!el) return;\n // Focus on next animation frame to allow expand animation / layout to settle.\n const id = requestAnimationFrame(() => {\n el.focus();\n const v = el.value;\n if (v) el.selectionStart = el.selectionEnd = v.length;\n });\n return () => cancelAnimationFrame(id);\n }, [isExpanded]);\n\n return (\n <SearchBox\n onExpand={() => setIsExpanded(true)}\n isExpanded={isExpanded}\n className=\"nz-widget-widgetContentLayout-header-headerSearch\"\n expandable\n size={props.iconSize}\n >\n <SearchBox.CollapsedState>\n <SearchBox.ExpandButton\n label=\"Search\"\n labelProps={{ placement: \"bottom\" }}\n size={props.iconSize}\n styleType=\"borderless\"\n >\n <SvgSearch />\n </SearchBox.ExpandButton>\n </SearchBox.CollapsedState>\n <SearchBox.ExpandedState>\n <SearchBox.Icon size={props.iconSize}>\n <SvgSearch />\n </SearchBox.Icon>\n <SearchBox.Input\n ref={inputRef}\n onChange={(e: React.ChangeEvent<HTMLInputElement>): void => {\n setSearchText(e.currentTarget.value);\n props.onSearch?.(e.currentTarget.value);\n }}\n value={searchText}\n />\n <SearchBox.CollapseButton\n size={props.iconSize}\n label=\"Clear\"\n labelProps={{ placement: \"bottom\" }}\n onClick={() => {\n setIsExpanded(false);\n setSearchText(\"\");\n if (searchText) props.onSearch?.(\"\");\n }}\n >\n <SvgClose />\n </SearchBox.CollapseButton>\n </SearchBox.ExpandedState>\n </SearchBox>\n );\n}\n"]}
1
+ {"version":3,"file":"HeaderSearch.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderSearch.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,qBAAqB,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAcjE;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,mBAAmB,CAAC;IAC9D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;IACtD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAA0B,IAAI,CAAC,CAAC;IAE7D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,8EAA8E;QAC9E,MAAM,EAAE,GAAG,qBAAqB,CAAC,GAAG,EAAE;YACpC,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC;gBAAE,EAAE,CAAC,cAAc,GAAG,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;QACxD,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjB,OAAO,CACL,oBAAC,SAAS,IACR,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EACnC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAC,mDAAmD,EAC7D,UAAU,QACV,IAAI,EAAE,KAAK,CAAC,QAAQ;QAEpB,oBAAC,SAAS,CAAC,cAAc;YACvB,oBAAC,SAAS,CAAC,YAAY,IACrB,KAAK,EAAC,QAAQ,EACd,UAAU,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,EACnC,IAAI,EAAE,KAAK,CAAC,QAAQ,EACpB,SAAS,EAAC,YAAY,EACtB,QAAQ,EAAE,KAAK,CAAC,aAAa;gBAE7B,oBAAC,SAAS,OAAG,CACU,CACA;QAC3B,oBAAC,SAAS,CAAC,aAAa;YACtB,oBAAC,SAAS,CAAC,IAAI,IAAC,IAAI,EAAE,KAAK,CAAC,QAAQ;gBAClC,oBAAC,SAAS,OAAG,CACE;YACjB,oBAAC,SAAS,CAAC,KAAK,IACd,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,CAAC,CAAsC,EAAQ,EAAE;oBACzD,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;oBACrC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC1C,CAAC,EACD,KAAK,EAAE,UAAU,GACjB;YACF,oBAAC,SAAS,CAAC,cAAc,IACvB,IAAI,EAAE,KAAK,CAAC,QAAQ,EACpB,KAAK,EAAC,OAAO,EACb,UAAU,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,EACnC,OAAO,EAAE,GAAG,EAAE;oBACZ,aAAa,CAAC,KAAK,CAAC,CAAC;oBACrB,aAAa,CAAC,EAAE,CAAC,CAAC;oBAClB,IAAI,UAAU;wBAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;gBAED,oBAAC,QAAQ,OAAG,CACa,CACH,CAChB,CACb,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderSearch.scss\";\nimport React from \"react\";\n\nimport { SearchBox } from \"@itwin/itwinui-react\";\n\nimport { SvgClose, SvgSearch } from \"@itwin/itwinui-icons-react\";\nimport type { HeaderIconToolbar } from \"./HeaderIconToolbar.js\";\n\ntype HeaderIconToolbarProps = React.ComponentProps<typeof HeaderIconToolbar>;\n\ninterface HeaderSearchProps\n extends Pick<\n HeaderIconToolbarProps,\n \"iconSize\" | \"onSearch\" | \"disableSearch\" | \"searchExpandedState\"\n > {\n /** State tuple for the search text value and its setter function. */\n searchState: [string, React.Dispatch<React.SetStateAction<string>>];\n}\n\n/**\n * A collapsible search box component for widget headers.\n * Provides an expandable search input with icons that automatically focuses when expanded.\n * @internal\n */\nexport function HeaderSearch(props: HeaderSearchProps) {\n const [isExpanded, setIsExpanded] = props.searchExpandedState;\n const [searchText, setSearchText] = props.searchState;\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n\n React.useEffect(() => {\n if (!isExpanded) return;\n const el = inputRef.current;\n if (!el) return;\n // Focus on next animation frame to allow expand animation / layout to settle.\n const id = requestAnimationFrame(() => {\n el.focus();\n const v = el.value;\n if (v) el.selectionStart = el.selectionEnd = v.length;\n });\n return () => cancelAnimationFrame(id);\n }, [isExpanded]);\n\n return (\n <SearchBox\n onExpand={() => setIsExpanded(true)}\n isExpanded={isExpanded}\n className=\"nz-widget-widgetContentLayout-header-headerSearch\"\n expandable\n size={props.iconSize}\n >\n <SearchBox.CollapsedState>\n <SearchBox.ExpandButton\n label=\"Search\"\n labelProps={{ placement: \"bottom\" }}\n size={props.iconSize}\n styleType=\"borderless\"\n disabled={props.disableSearch}\n >\n <SvgSearch />\n </SearchBox.ExpandButton>\n </SearchBox.CollapsedState>\n <SearchBox.ExpandedState>\n <SearchBox.Icon size={props.iconSize}>\n <SvgSearch />\n </SearchBox.Icon>\n <SearchBox.Input\n ref={inputRef}\n onChange={(e: React.ChangeEvent<HTMLInputElement>): void => {\n setSearchText(e.currentTarget.value);\n props.onSearch?.(e.currentTarget.value);\n }}\n value={searchText}\n />\n <SearchBox.CollapseButton\n size={props.iconSize}\n label=\"Clear\"\n labelProps={{ placement: \"bottom\" }}\n onClick={() => {\n setIsExpanded(false);\n setSearchText(\"\");\n if (searchText) props.onSearch?.(\"\");\n }}\n >\n <SvgClose />\n </SearchBox.CollapseButton>\n </SearchBox.ExpandedState>\n </SearchBox>\n );\n}\n"]}
@@ -2,7 +2,7 @@ import "./HeaderTopBar.scss";
2
2
  import * as React from "react";
3
3
  import type { WidgetContentLayout } from "../WidgetContentLayout.js";
4
4
  type WidgetContentLayoutHeaderProps = React.ComponentProps<typeof WidgetContentLayout.Header>;
5
- interface HeaderTopBarProps extends Pick<WidgetContentLayoutHeaderProps, "icons" | "onSearch" | "iconSize"> {
5
+ interface HeaderTopBarProps extends Pick<WidgetContentLayoutHeaderProps, "icons" | "onSearch" | "iconSize" | "disableSearch"> {
6
6
  primaryContent: React.JSX.Element[];
7
7
  }
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderTopBar.d.ts","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.tsx"],"names":[],"mappings":"AAKA,OAAO,qBAAqB,CAAC;AAE7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,KAAK,8BAA8B,GAAG,KAAK,CAAC,cAAc,CACxD,OAAO,mBAAmB,CAAC,MAAM,CAClC,CAAC;AAGF,UAAU,iBACR,SAAQ,IAAI,CACV,8BAA8B,EAC9B,OAAO,GAAG,UAAU,GAAG,UAAU,CAClC;IACD,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,qBA0CpD"}
1
+ {"version":3,"file":"HeaderTopBar.d.ts","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.tsx"],"names":[],"mappings":"AAKA,OAAO,qBAAqB,CAAC;AAE7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,KAAK,8BAA8B,GAAG,KAAK,CAAC,cAAc,CACxD,OAAO,mBAAmB,CAAC,MAAM,CAClC,CAAC;AAGF,UAAU,iBACR,SAAQ,IAAI,CACV,8BAA8B,EAC9B,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,CACpD;IACD,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,qBA2CpD"}
@@ -30,6 +30,6 @@ export function HeaderTopBar(props) {
30
30
  return (React.createElement("div", { className: classNames("nz-widget-widgetContentLayout-header-headerTopBar", (props.primaryContent.length === 0 || menuIcons.length === 0) &&
31
31
  "nz-singleColumn"), "data-search-expanded": searchExpandedState[0] },
32
32
  props.primaryContent.length > 0 && (React.createElement("div", { className: "nz-primaryContent" }, props.primaryContent)),
33
- menuIcons.length > 0 && (React.createElement(HeaderIconToolbar, { menuIcons: menuIcons, onSearch: props.onSearch, searchExpandedState: searchExpandedState, iconSize: props.iconSize }))));
33
+ menuIcons.length > 0 && (React.createElement(HeaderIconToolbar, { menuIcons: menuIcons, onSearch: props.onSearch, searchExpandedState: searchExpandedState, iconSize: props.iconSize, disableSearch: props.disableSearch }))));
34
34
  }
35
35
  //# sourceMappingURL=HeaderTopBar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderTopBar.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,qBAAqB,CAAC;AAC7B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAgB3D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,KAAK,GAAwC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACnE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAClB,KAAK,GAAG;oBACN,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EAAE;oBAC1C,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAC3B,IAAI,CAAC,IAAI,KAAK,SAAS;wBACrB,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,WAAW,KAAK,EAAE,EAAE;wBACtC,CAAC,CAAC,IAAI,CACT;iBACF,CAAC;YACJ,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAElC,MAAM,mBAAmB,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,OAAO,CACL,6BACE,SAAS,EAAE,UAAU,CACnB,mDAAmD,EACnD,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;YAC3D,iBAAiB,CACpB,0BACqB,mBAAmB,CAAC,CAAC,CAAC;QAE3C,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,CAClC,6BAAK,SAAS,EAAC,mBAAmB,IAAE,KAAK,CAAC,cAAc,CAAO,CAChE;QACA,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CACvB,oBAAC,iBAAiB,IAChB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,CACH,CACG,CACP,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderTopBar.scss\";\nimport classNames from \"classnames\";\nimport * as React from \"react\";\n\nimport { HeaderIconToolbar } from \"./HeaderIconToolbar.js\";\nimport type { WidgetContentLayout } from \"../WidgetContentLayout.js\";\n\ntype WidgetContentLayoutHeaderProps = React.ComponentProps<\n typeof WidgetContentLayout.Header\n>;\ntype HeaderIconToolbarProps = React.ComponentProps<typeof HeaderIconToolbar>;\n\ninterface HeaderTopBarProps\n extends Pick<\n WidgetContentLayoutHeaderProps,\n \"icons\" | \"onSearch\" | \"iconSize\"\n > {\n primaryContent: React.JSX.Element[];\n}\n\n/**\n * Internal layout component that renders the top bar of the widget header,\n * including optional left content and a top-right icon/search area.\n * @internal\n */\nexport function HeaderTopBar(props: HeaderTopBarProps) {\n const menuIcons = React.useMemo(() => {\n let icons: HeaderIconToolbarProps[\"menuIcons\"] = props.icons || [];\n if (props.onSearch) {\n if (icons.length > 0)\n icons = [\n { type: \"divider\", key: \"search-divider\" },\n ...icons.map((icon, index) =>\n icon.type === \"divider\"\n ? { ...icon, key: `divider-${index}` }\n : icon\n ),\n ];\n icons = [{ type: \"search\" }, ...icons];\n }\n return icons;\n }, [props.icons, props.onSearch]);\n\n const searchExpandedState = React.useState(false);\n\n return (\n <div\n className={classNames(\n \"nz-widget-widgetContentLayout-header-headerTopBar\",\n (props.primaryContent.length === 0 || menuIcons.length === 0) &&\n \"nz-singleColumn\"\n )}\n data-search-expanded={searchExpandedState[0]}\n >\n {props.primaryContent.length > 0 && (\n <div className=\"nz-primaryContent\">{props.primaryContent}</div>\n )}\n {menuIcons.length > 0 && (\n <HeaderIconToolbar\n menuIcons={menuIcons}\n onSearch={props.onSearch}\n searchExpandedState={searchExpandedState}\n iconSize={props.iconSize}\n />\n )}\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"HeaderTopBar.js","sourceRoot":"","sources":["../../../../../../src/appui-react/layout/widget/widget-content-layout/header/HeaderTopBar.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,qBAAqB,CAAC;AAC7B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAgB3D;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,KAAK,GAAwC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACnE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAClB,KAAK,GAAG;oBACN,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,gBAAgB,EAAE;oBAC1C,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAC3B,IAAI,CAAC,IAAI,KAAK,SAAS;wBACrB,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,WAAW,KAAK,EAAE,EAAE;wBACtC,CAAC,CAAC,IAAI,CACT;iBACF,CAAC;YACJ,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAElC,MAAM,mBAAmB,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,OAAO,CACL,6BACE,SAAS,EAAE,UAAU,CACnB,mDAAmD,EACnD,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;YAC3D,iBAAiB,CACpB,0BACqB,mBAAmB,CAAC,CAAC,CAAC;QAE3C,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,CAClC,6BAAK,SAAS,EAAC,mBAAmB,IAAE,KAAK,CAAC,cAAc,CAAO,CAChE;QACA,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CACvB,oBAAC,iBAAiB,IAChB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,aAAa,EAAE,KAAK,CAAC,aAAa,GAClC,CACH,CACG,CACP,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./HeaderTopBar.scss\";\nimport classNames from \"classnames\";\nimport * as React from \"react\";\n\nimport { HeaderIconToolbar } from \"./HeaderIconToolbar.js\";\nimport type { WidgetContentLayout } from \"../WidgetContentLayout.js\";\n\ntype WidgetContentLayoutHeaderProps = React.ComponentProps<\n typeof WidgetContentLayout.Header\n>;\ntype HeaderIconToolbarProps = React.ComponentProps<typeof HeaderIconToolbar>;\n\ninterface HeaderTopBarProps\n extends Pick<\n WidgetContentLayoutHeaderProps,\n \"icons\" | \"onSearch\" | \"iconSize\" | \"disableSearch\"\n > {\n primaryContent: React.JSX.Element[];\n}\n\n/**\n * Internal layout component that renders the top bar of the widget header,\n * including optional left content and a top-right icon/search area.\n * @internal\n */\nexport function HeaderTopBar(props: HeaderTopBarProps) {\n const menuIcons = React.useMemo(() => {\n let icons: HeaderIconToolbarProps[\"menuIcons\"] = props.icons || [];\n if (props.onSearch) {\n if (icons.length > 0)\n icons = [\n { type: \"divider\", key: \"search-divider\" },\n ...icons.map((icon, index) =>\n icon.type === \"divider\"\n ? { ...icon, key: `divider-${index}` }\n : icon\n ),\n ];\n icons = [{ type: \"search\" }, ...icons];\n }\n return icons;\n }, [props.icons, props.onSearch]);\n\n const searchExpandedState = React.useState(false);\n\n return (\n <div\n className={classNames(\n \"nz-widget-widgetContentLayout-header-headerTopBar\",\n (props.primaryContent.length === 0 || menuIcons.length === 0) &&\n \"nz-singleColumn\"\n )}\n data-search-expanded={searchExpandedState[0]}\n >\n {props.primaryContent.length > 0 && (\n <div className=\"nz-primaryContent\">{props.primaryContent}</div>\n )}\n {menuIcons.length > 0 && (\n <HeaderIconToolbar\n menuIcons={menuIcons}\n onSearch={props.onSearch}\n searchExpandedState={searchExpandedState}\n iconSize={props.iconSize}\n disableSearch={props.disableSearch}\n />\n )}\n </div>\n );\n}\n"]}
@@ -53,6 +53,12 @@ interface KnownPreviewFeatures {
53
53
  * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/859
54
54
  */
55
55
  controlWidgetVisibility: boolean | WidgetDef["id"][];
56
+ /** If `true`, widget tab actions are displayed for individual tabs instead of the default behavior where only active tab actions are exposed.
57
+ * Note that this feature replaces the overflow dropdown menu with a scrollable container to display all tab actions.
58
+ *
59
+ * Close button will be shown in widget tab when `controlWidgetVisibility` preview feature is enabled.
60
+ */
61
+ widgetTabActions: boolean;
56
62
  /**
57
63
  * If `true`, the tool settings will be using the new editor API. The new system delivers same default editors as the old one.
58
64
  * However, in order to use custom editors they need to be provided using `EditorsRegistryProvider` component.
@@ -77,7 +83,7 @@ interface KnownPreviewFeatures {
77
83
  * This list is expected to change over time, the interface is made
78
84
  * so that new features can be added or removed without breaking existing code.
79
85
  * A console warning will simply appear if unknown features are passed.
80
- * @beta
86
+ * @public
81
87
  */
82
88
  export interface PreviewFeatures extends Partial<KnownPreviewFeatures> {
83
89
  [featureName: string]: any;
@@ -88,11 +94,13 @@ export interface PreviewFeatures extends Partial<KnownPreviewFeatures> {
88
94
  export declare function usePreviewFeatures(): PreviewFeatures;
89
95
  /** Props for PreviewFeaturesProvider.
90
96
  * @beta
97
+ * @deprecated in 5.26.0. Use `React.ComponentProps<typeof PreviewFeaturesProvider>`
91
98
  */
92
99
  export interface PreviewFeaturesProviderProps {
93
100
  children?: React.ReactNode;
94
101
  features?: PreviewFeatures;
95
102
  }
103
+ type ProviderProps = PreviewFeaturesProviderProps;
96
104
  /** Set which preview features are enabled. These features are not yet ready for production use nor have
97
105
  * a proper API defined yet.
98
106
  * The available set of features are defined in the [[PreviewFeatures]] interface.
@@ -108,8 +116,8 @@ export interface PreviewFeaturesProviderProps {
108
116
  * </Provider>
109
117
  * </PreviewFeaturesProvider>
110
118
  * ```
111
- * @beta
119
+ * @public
112
120
  */
113
- export declare function PreviewFeaturesProvider({ children, features, }: PreviewFeaturesProviderProps): React.JSX.Element;
121
+ export declare function PreviewFeaturesProvider(props: ProviderProps): React.JSX.Element;
114
122
  export {};
115
123
  //# sourceMappingURL=PreviewFeatures.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PreviewFeatures.d.ts","sourceRoot":"","sources":["../../../src/appui-react/preview/PreviewFeatures.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzD,sCAAsC;AACtC,UAAU,oBAAoB;IAC5B;;;;OAIG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,6BAA6B,EAAE,OAAO,CAAC;IACvC;;;OAGG;IACH,0BAA0B,EAAE,OAAO,CAAC;IACpC;;;OAGG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,oBAAoB,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C;;;OAGG;IACH,wCAAwC,EAAE,OAAO,CAAC;IAClD;;;;;;OAMG;IACH,qBAAqB,EAAE,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD;;;;;OAKG;IACH,uBAAuB,EAAE,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACrD;;;OAGG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,0BAA0B,EAAE,OAAO,CAAC;IACpC;;OAEG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAoBD;;;;;GAKG;AACH,MAAM,WAAW,eAAgB,SAAQ,OAAO,CAAC,oBAAoB,CAAC;IACpE,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC;CAC5B;AAuDD;;GAEG;AACH,wBAAgB,kBAAkB,oBAEjC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,QAAQ,GACT,EAAE,4BAA4B,qBAgB9B"}
1
+ {"version":3,"file":"PreviewFeatures.d.ts","sourceRoot":"","sources":["../../../src/appui-react/preview/PreviewFeatures.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAGzD,sCAAsC;AACtC,UAAU,oBAAoB;IAC5B;;;;OAIG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,6BAA6B,EAAE,OAAO,CAAC;IACvC;;;OAGG;IACH,0BAA0B,EAAE,OAAO,CAAC;IACpC;;;OAGG;IACH,wBAAwB,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,oBAAoB,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C;;;OAGG;IACH,wCAAwC,EAAE,OAAO,CAAC;IAClD;;;;;;OAMG;IACH,qBAAqB,EAAE,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD;;;;;OAKG;IACH,uBAAuB,EAAE,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACrD;;;;OAIG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,0BAA0B,EAAE,OAAO,CAAC;IACpC;;OAEG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAqBD;;;;;GAKG;AACH,MAAM,WAAW,eAAgB,SAAQ,OAAO,CAAC,oBAAoB,CAAC;IACpE,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC;CAC5B;AAuDD;;GAEG;AACH,wBAAgB,kBAAkB,oBAEjC;AAED;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAGD,KAAK,aAAa,GAAG,4BAA4B,CAAC;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,qBAiB3D"}
@@ -21,6 +21,7 @@ const knownFeaturesObject = {
21
21
  allowBearingLettersInAccuDrawInputFields: undefined,
22
22
  reparentPopoutWidgets: undefined,
23
23
  controlWidgetVisibility: undefined,
24
+ widgetTabActions: undefined,
24
25
  toolSettingsNewEditors: undefined,
25
26
  toolSettingsLockButton: undefined,
26
27
  toolSettingsKeyPressCommit: undefined,
@@ -85,9 +86,10 @@ export function usePreviewFeatures() {
85
86
  * </Provider>
86
87
  * </PreviewFeaturesProvider>
87
88
  * ```
88
- * @beta
89
+ * @public
89
90
  */
90
- export function PreviewFeaturesProvider({ children, features, }) {
91
+ export function PreviewFeaturesProvider(props) {
92
+ const { children, features } = props;
91
93
  const setPreviewFeatures = usePreviewFeaturesStore((state) => state.setPreviewFeatures);
92
94
  React.useEffect(() => {
93
95
  setPreviewFeatures(features ?? {});
@@ -1 +1 @@
1
- {"version":3,"file":"PreviewFeatures.js","sourceRoot":"","sources":["../../../src/appui-react/preview/PreviewFeatures.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utilities\n */\n\nimport * as React from \"react\";\nimport { create } from \"zustand\";\nimport { Logger } from \"@itwin/core-bentley\";\nimport { UiFramework } from \"../UiFramework.js\";\nimport type { useTransientState } from \"../widget-panels/useTransientState.js\";\nimport type { WidgetDef } from \"../widgets/WidgetDef.js\";\nimport type { UiItemsManager } from \"../ui-items-provider/UiItemsManager.js\";\n\n/** List of known preview features. */\ninterface KnownPreviewFeatures {\n /** If `true`, the panels and tool settings will always be rendered over the content.\n * The content will never change size.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/672\n */\n contentAlwaysMaxSize: boolean;\n /** If `true`, the floating widget will have a \"maximize\" button. Use `enableMaximizedPanelWidget` to enable the feature for panel widgets.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/673\n */\n enableMaximizedFloatingWidget: boolean;\n /** If `true`, the panel widget will have a \"maximize\" button. Use `enableMaximizedFloatingWidget` to enable the feature for floating widgets.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/673\n */\n enableMaximizedPanelWidget: boolean;\n /** If `true`, the horizontal panels will have an additional \"Align\" button.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/706\n */\n horizontalPanelAlignment: boolean;\n /** If enabled, a dropdown menu will be rendered for widgets that exceed the specified threshold of title bar buttons.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/723\n */\n widgetActionDropdown: { threshold: number };\n /** If `true`, the accudraw input field will accept some letters for bearing angle. Defaults to `false`.\n *\n * This allows to type letters for Bearing angles in the accudraw input field. (N, S, E, W)\n */\n allowBearingLettersInAccuDrawInputFields: boolean;\n /** If `true`, popout widgets will not be rendered in a separate element tree, instead widget content will be re-parented to a popout content container.\n * Alternatively, an array of widget ids can be specified to only re-parent specific widgets.\n * @note Use {@link useTransientState} to save and restore DOM transient state when re-parenting widgets.\n * @note There is a known limitation where iTwinUI v2 popover elements will be rendered in the main window. Prefer using iTwinUI v3 when using this feature.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/925\n */\n reparentPopoutWidgets: boolean | WidgetDef[\"id\"][];\n /** If `true`, additional UI elements are rendered to allow the end user of the layout to control widget visibility.\n * Alternatively, an array of widget ids can be specified to only control specific widgets.\n * @note Use {@link UiItemsManager} APIs to manage what widgets are available to the end-user.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/859\n */\n controlWidgetVisibility: boolean | WidgetDef[\"id\"][];\n /**\n * If `true`, the tool settings will be using the new editor API. The new system delivers same default editors as the old one.\n * However, in order to use custom editors they need to be provided using `EditorsRegistryProvider` component.\n */\n toolSettingsNewEditors: boolean;\n /**\n * If `true`, the default tool settings lock editor will be rendered as an icon button rather than a checkbox.\n * Consumers can still use a custom component to render the lock by customizing the `PropertyDescription`.\n * Additionally, the icon button will be rendered as an input decoration in editors that support it.\n */\n toolSettingsLockButton: boolean;\n /**\n * If `true`, the input-like editors rendered in the tool settings will commit the entered value on key press.\n */\n toolSettingsKeyPressCommit: boolean;\n /**\n * If `true`, the content layout will not re-mount given the same configuration.\n */\n stableContentLayout: boolean;\n}\n\n/** Object used trim to only known features at runtime.\n * @internal\n */\nconst knownFeaturesObject: Record<keyof KnownPreviewFeatures, undefined> = {\n contentAlwaysMaxSize: undefined,\n enableMaximizedFloatingWidget: undefined,\n enableMaximizedPanelWidget: undefined,\n horizontalPanelAlignment: undefined,\n widgetActionDropdown: undefined,\n allowBearingLettersInAccuDrawInputFields: undefined,\n reparentPopoutWidgets: undefined,\n controlWidgetVisibility: undefined,\n toolSettingsNewEditors: undefined,\n toolSettingsLockButton: undefined,\n toolSettingsKeyPressCommit: undefined,\n stableContentLayout: undefined,\n};\n\n/** List of preview features that can be enabled/disabled.\n * This list is expected to change over time, the interface is made\n * so that new features can be added or removed without breaking existing code.\n * A console warning will simply appear if unknown features are passed.\n * @beta\n */\nexport interface PreviewFeatures extends Partial<KnownPreviewFeatures> {\n [featureName: string]: any;\n}\n\n/** Trim an object to only contain known feature keys.\n * @param previewFeatures object potentially containing unknown features\n * @returns object containing only known features\n * @internal\n */\nfunction trimToKnownFeaturesOnly(previewFeatures: PreviewFeatures) {\n const knownFeatureKeys = Object.keys(knownFeaturesObject);\n const [knownFeatures, unknownFeatures] = Object.entries(\n previewFeatures\n ).reduce(\n ([known, unknown], [key, value]) => {\n if (knownFeatureKeys.includes(key)) {\n known[key] = value;\n } else {\n unknown.push(key);\n }\n return [known, unknown];\n },\n [{}, []] as [PreviewFeatures, string[]]\n );\n if (Object.keys(unknownFeatures).length > 0) {\n Logger.logWarning(\n UiFramework.loggerCategory(\"trimToKnownFeaturesOnly\"),\n `Features used in \"setPreviewFeatures\" are unknown or no longer in preview`,\n {\n unknownFeatures,\n }\n );\n }\n return knownFeatures;\n}\n\ninterface PreviewFeaturesState {\n previewFeatures: PreviewFeatures;\n setPreviewFeatures: (previewFeatures: PreviewFeatures) => void;\n}\n\n/** Preview features store used by `UiFramework.previewFeatures` and `UiFramework.setPreviewFeatures()` APIs to manage the preview features.\n * Use `usePreviewFeatures` hook to access the preview features set from a react component.\n * Use `usePreviewFeaturesStore.getState().previewFeatures` to access the preview features set from a non-react component.\n * Use `usePreviewFeaturesStore.subscribe()` to subscribe to changes to the preview features set from a non-react component.\n * @internal\n */\nconst usePreviewFeaturesStore = create<PreviewFeaturesState>((set) => {\n return {\n previewFeatures: {},\n setPreviewFeatures: (newPreviewFeatures: PreviewFeatures) => {\n const previewFeatures = trimToKnownFeaturesOnly(newPreviewFeatures);\n set({ previewFeatures });\n },\n };\n});\n\n/** Hook to access the preview features set.\n * @internal\n */\nexport function usePreviewFeatures() {\n return usePreviewFeaturesStore((state) => state.previewFeatures);\n}\n\n/** Props for PreviewFeaturesProvider.\n * @beta\n */\nexport interface PreviewFeaturesProviderProps {\n children?: React.ReactNode;\n features?: PreviewFeatures;\n}\n\n/** Set which preview features are enabled. These features are not yet ready for production use nor have\n * a proper API defined yet.\n * The available set of features are defined in the [[PreviewFeatures]] interface.\n *\n * This component should wrap the Provider component.\n *\n * ```tsx\n * <PreviewFeaturesProvider features={{ enableMaximizedFloatingWidget: true }}>\n * <Provider store={UiFramework.store}>\n * [...]\n * <ConfigurableUIContent />\n * [/...]\n * </Provider>\n * </PreviewFeaturesProvider>\n * ```\n * @beta\n */\nexport function PreviewFeaturesProvider({\n children,\n features,\n}: PreviewFeaturesProviderProps) {\n const setPreviewFeatures = usePreviewFeaturesStore(\n (state) => state.setPreviewFeatures\n );\n React.useEffect(() => {\n setPreviewFeatures(features ?? {});\n }, [features, setPreviewFeatures]);\n\n // Clear preview features when unmounting.\n React.useEffect(\n () => () => {\n setPreviewFeatures({});\n },\n [setPreviewFeatures]\n );\n return <>{children}</>;\n}\n"]}
1
+ {"version":3,"file":"PreviewFeatures.js","sourceRoot":"","sources":["../../../src/appui-react/preview/PreviewFeatures.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Utilities\n */\n\nimport * as React from \"react\";\nimport { create } from \"zustand\";\nimport { Logger } from \"@itwin/core-bentley\";\nimport { UiFramework } from \"../UiFramework.js\";\nimport type { useTransientState } from \"../widget-panels/useTransientState.js\";\nimport type { WidgetDef } from \"../widgets/WidgetDef.js\";\nimport type { UiItemsManager } from \"../ui-items-provider/UiItemsManager.js\";\n\n/** List of known preview features. */\ninterface KnownPreviewFeatures {\n /** If `true`, the panels and tool settings will always be rendered over the content.\n * The content will never change size.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/672\n */\n contentAlwaysMaxSize: boolean;\n /** If `true`, the floating widget will have a \"maximize\" button. Use `enableMaximizedPanelWidget` to enable the feature for panel widgets.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/673\n */\n enableMaximizedFloatingWidget: boolean;\n /** If `true`, the panel widget will have a \"maximize\" button. Use `enableMaximizedFloatingWidget` to enable the feature for floating widgets.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/673\n */\n enableMaximizedPanelWidget: boolean;\n /** If `true`, the horizontal panels will have an additional \"Align\" button.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/706\n */\n horizontalPanelAlignment: boolean;\n /** If enabled, a dropdown menu will be rendered for widgets that exceed the specified threshold of title bar buttons.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/723\n */\n widgetActionDropdown: { threshold: number };\n /** If `true`, the accudraw input field will accept some letters for bearing angle. Defaults to `false`.\n *\n * This allows to type letters for Bearing angles in the accudraw input field. (N, S, E, W)\n */\n allowBearingLettersInAccuDrawInputFields: boolean;\n /** If `true`, popout widgets will not be rendered in a separate element tree, instead widget content will be re-parented to a popout content container.\n * Alternatively, an array of widget ids can be specified to only re-parent specific widgets.\n * @note Use {@link useTransientState} to save and restore DOM transient state when re-parenting widgets.\n * @note There is a known limitation where iTwinUI v2 popover elements will be rendered in the main window. Prefer using iTwinUI v3 when using this feature.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/925\n */\n reparentPopoutWidgets: boolean | WidgetDef[\"id\"][];\n /** If `true`, additional UI elements are rendered to allow the end user of the layout to control widget visibility.\n * Alternatively, an array of widget ids can be specified to only control specific widgets.\n * @note Use {@link UiItemsManager} APIs to manage what widgets are available to the end-user.\n *\n * Discuss or upvote this feature: https://github.com/iTwin/appui/discussions/859\n */\n controlWidgetVisibility: boolean | WidgetDef[\"id\"][];\n /** If `true`, widget tab actions are displayed for individual tabs instead of the default behavior where only active tab actions are exposed.\n * Note that this feature replaces the overflow dropdown menu with a scrollable container to display all tab actions.\n *\n * Close button will be shown in widget tab when `controlWidgetVisibility` preview feature is enabled.\n */\n widgetTabActions: boolean;\n /**\n * If `true`, the tool settings will be using the new editor API. The new system delivers same default editors as the old one.\n * However, in order to use custom editors they need to be provided using `EditorsRegistryProvider` component.\n */\n toolSettingsNewEditors: boolean;\n /**\n * If `true`, the default tool settings lock editor will be rendered as an icon button rather than a checkbox.\n * Consumers can still use a custom component to render the lock by customizing the `PropertyDescription`.\n * Additionally, the icon button will be rendered as an input decoration in editors that support it.\n */\n toolSettingsLockButton: boolean;\n /**\n * If `true`, the input-like editors rendered in the tool settings will commit the entered value on key press.\n */\n toolSettingsKeyPressCommit: boolean;\n /**\n * If `true`, the content layout will not re-mount given the same configuration.\n */\n stableContentLayout: boolean;\n}\n\n/** Object used trim to only known features at runtime.\n * @internal\n */\nconst knownFeaturesObject: Record<keyof KnownPreviewFeatures, undefined> = {\n contentAlwaysMaxSize: undefined,\n enableMaximizedFloatingWidget: undefined,\n enableMaximizedPanelWidget: undefined,\n horizontalPanelAlignment: undefined,\n widgetActionDropdown: undefined,\n allowBearingLettersInAccuDrawInputFields: undefined,\n reparentPopoutWidgets: undefined,\n controlWidgetVisibility: undefined,\n widgetTabActions: undefined,\n toolSettingsNewEditors: undefined,\n toolSettingsLockButton: undefined,\n toolSettingsKeyPressCommit: undefined,\n stableContentLayout: undefined,\n};\n\n/** List of preview features that can be enabled/disabled.\n * This list is expected to change over time, the interface is made\n * so that new features can be added or removed without breaking existing code.\n * A console warning will simply appear if unknown features are passed.\n * @public\n */\nexport interface PreviewFeatures extends Partial<KnownPreviewFeatures> {\n [featureName: string]: any;\n}\n\n/** Trim an object to only contain known feature keys.\n * @param previewFeatures object potentially containing unknown features\n * @returns object containing only known features\n * @internal\n */\nfunction trimToKnownFeaturesOnly(previewFeatures: PreviewFeatures) {\n const knownFeatureKeys = Object.keys(knownFeaturesObject);\n const [knownFeatures, unknownFeatures] = Object.entries(\n previewFeatures\n ).reduce(\n ([known, unknown], [key, value]) => {\n if (knownFeatureKeys.includes(key)) {\n known[key] = value;\n } else {\n unknown.push(key);\n }\n return [known, unknown];\n },\n [{}, []] as [PreviewFeatures, string[]]\n );\n if (Object.keys(unknownFeatures).length > 0) {\n Logger.logWarning(\n UiFramework.loggerCategory(\"trimToKnownFeaturesOnly\"),\n `Features used in \"setPreviewFeatures\" are unknown or no longer in preview`,\n {\n unknownFeatures,\n }\n );\n }\n return knownFeatures;\n}\n\ninterface PreviewFeaturesState {\n previewFeatures: PreviewFeatures;\n setPreviewFeatures: (previewFeatures: PreviewFeatures) => void;\n}\n\n/** Preview features store used by `UiFramework.previewFeatures` and `UiFramework.setPreviewFeatures()` APIs to manage the preview features.\n * Use `usePreviewFeatures` hook to access the preview features set from a react component.\n * Use `usePreviewFeaturesStore.getState().previewFeatures` to access the preview features set from a non-react component.\n * Use `usePreviewFeaturesStore.subscribe()` to subscribe to changes to the preview features set from a non-react component.\n * @internal\n */\nconst usePreviewFeaturesStore = create<PreviewFeaturesState>((set) => {\n return {\n previewFeatures: {},\n setPreviewFeatures: (newPreviewFeatures: PreviewFeatures) => {\n const previewFeatures = trimToKnownFeaturesOnly(newPreviewFeatures);\n set({ previewFeatures });\n },\n };\n});\n\n/** Hook to access the preview features set.\n * @internal\n */\nexport function usePreviewFeatures() {\n return usePreviewFeaturesStore((state) => state.previewFeatures);\n}\n\n/** Props for PreviewFeaturesProvider.\n * @beta\n * @deprecated in 5.26.0. Use `React.ComponentProps<typeof PreviewFeaturesProvider>`\n */\nexport interface PreviewFeaturesProviderProps {\n children?: React.ReactNode;\n features?: PreviewFeatures;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-deprecated\ntype ProviderProps = PreviewFeaturesProviderProps;\n\n/** Set which preview features are enabled. These features are not yet ready for production use nor have\n * a proper API defined yet.\n * The available set of features are defined in the [[PreviewFeatures]] interface.\n *\n * This component should wrap the Provider component.\n *\n * ```tsx\n * <PreviewFeaturesProvider features={{ enableMaximizedFloatingWidget: true }}>\n * <Provider store={UiFramework.store}>\n * [...]\n * <ConfigurableUIContent />\n * [/...]\n * </Provider>\n * </PreviewFeaturesProvider>\n * ```\n * @public\n */\nexport function PreviewFeaturesProvider(props: ProviderProps) {\n const { children, features } = props;\n const setPreviewFeatures = usePreviewFeaturesStore(\n (state) => state.setPreviewFeatures\n );\n React.useEffect(() => {\n setPreviewFeatures(features ?? {});\n }, [features, setPreviewFeatures]);\n\n // Clear preview features when unmounting.\n React.useEffect(\n () => () => {\n setPreviewFeatures({});\n },\n [setPreviewFeatures]\n );\n return <>{children}</>;\n}\n"]}
@@ -2,8 +2,11 @@
2
2
  * @module Widget
3
3
  */
4
4
  import * as React from "react";
5
+ import type { TabState } from "../../layout/state/TabState.js";
5
6
  /** @internal */
6
7
  export declare function CloseWidgetButton(): React.JSX.Element;
7
8
  /** @internal */
9
+ export declare function useControlWidgetVisibility(id: TabState["id"]): boolean;
10
+ /** @internal */
8
11
  export declare function useCloseTab(): boolean;
9
12
  //# sourceMappingURL=CloseWidgetButton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CloseWidgetButton.d.ts","sourceRoot":"","sources":["../../../../src/appui-react/preview/control-widget-visibility/CloseWidgetButton.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,gBAAgB;AAChB,wBAAgB,iBAAiB,sBAgBhC;AAED,gBAAgB;AAChB,wBAAgB,WAAW,YAO1B"}
1
+ {"version":3,"file":"CloseWidgetButton.d.ts","sourceRoot":"","sources":["../../../../src/appui-react/preview/control-widget-visibility/CloseWidgetButton.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE/D,gBAAgB;AAChB,wBAAgB,iBAAiB,sBAgBhC;AAED,gBAAgB;AAChB,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,WAM5D;AAED,gBAAgB;AAChB,wBAAgB,WAAW,YAO1B"}
@@ -23,12 +23,21 @@ export function CloseWidgetButton() {
23
23
  } }));
24
24
  }
25
25
  /** @internal */
26
- export function useCloseTab() {
27
- const id = useActiveTabId();
26
+ export function useControlWidgetVisibility(id) {
28
27
  const { controlWidgetVisibility } = usePreviewFeatures();
29
28
  if (Array.isArray(controlWidgetVisibility)) {
30
29
  return controlWidgetVisibility.includes(id);
31
30
  }
32
31
  return !!controlWidgetVisibility;
33
32
  }
33
+ /** @internal */
34
+ export function useCloseTab() {
35
+ const id = useActiveTabId();
36
+ const controlWidgetVisibility = useControlWidgetVisibility(id);
37
+ const { widgetTabActions } = usePreviewFeatures();
38
+ // Close tab button is displayed for each individual tab.
39
+ if (widgetTabActions)
40
+ return false;
41
+ return controlWidgetVisibility;
42
+ }
34
43
  //# sourceMappingURL=CloseWidgetButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CloseWidgetButton.js","sourceRoot":"","sources":["../../../../src/appui-react/preview/control-widget-visibility/CloseWidgetButton.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,gBAAgB;AAChB,MAAM,UAAU,iBAAiB;IAC/B,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAE3D,OAAO,CACL,oBAAC,YAAY,IACX,IAAI,EAAE,oBAAC,aAAa,OAAG,EACvB,KAAK,EAAC,cAAc,EACpB,OAAO,EAAE,GAAG,EAAE;YACZ,QAAQ,CAAC;gBACP,IAAI,EAAE,iBAAiB;gBACvB,EAAE;aACH,CAAC,CAAC;QACL,CAAC,GACD,CACH,CAAC;AACJ,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAC5B,MAAM,EAAE,uBAAuB,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACzD,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAC3C,OAAO,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,CAAC,uBAAuB,CAAC;AACnC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Widget\n */\n\nimport * as React from \"react\";\nimport { SvgCloseSmall } from \"@itwin/itwinui-icons-react\";\nimport { WidgetAction } from \"../../layout/widget/WidgetAction.js\";\nimport { usePreviewFeatures } from \"../PreviewFeatures.js\";\nimport { useActiveTabId } from \"../../layout/widget/Widget.js\";\nimport { NineZoneDispatchContext } from \"../../layout/base/NineZone.js\";\n\n/** @internal */\nexport function CloseWidgetButton() {\n const id = useActiveTabId();\n const dispatch = React.useContext(NineZoneDispatchContext);\n\n return (\n <WidgetAction\n icon={<SvgCloseSmall />}\n label=\"Close widget\"\n onClick={() => {\n dispatch({\n type: \"WIDGET_TAB_HIDE\",\n id,\n });\n }}\n />\n );\n}\n\n/** @internal */\nexport function useCloseTab() {\n const id = useActiveTabId();\n const { controlWidgetVisibility } = usePreviewFeatures();\n if (Array.isArray(controlWidgetVisibility)) {\n return controlWidgetVisibility.includes(id);\n }\n return !!controlWidgetVisibility;\n}\n"]}
1
+ {"version":3,"file":"CloseWidgetButton.js","sourceRoot":"","sources":["../../../../src/appui-react/preview/control-widget-visibility/CloseWidgetButton.tsx"],"names":[],"mappings":"AAAA;;;gGAGgG;AAChG;;GAEG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAGxE,gBAAgB;AAChB,MAAM,UAAU,iBAAiB;IAC/B,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;IAE3D,OAAO,CACL,oBAAC,YAAY,IACX,IAAI,EAAE,oBAAC,aAAa,OAAG,EACvB,KAAK,EAAC,cAAc,EACpB,OAAO,EAAE,GAAG,EAAE;YACZ,QAAQ,CAAC;gBACP,IAAI,EAAE,iBAAiB;gBACvB,EAAE;aACH,CAAC,CAAC;QACL,CAAC,GACD,CACH,CAAC;AACJ,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,0BAA0B,CAAC,EAAkB;IAC3D,MAAM,EAAE,uBAAuB,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACzD,IAAI,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAC3C,OAAO,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,CAAC,uBAAuB,CAAC;AACnC,CAAC;AAED,gBAAgB;AAChB,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAC5B,MAAM,uBAAuB,GAAG,0BAA0B,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,EAAE,gBAAgB,EAAE,GAAG,kBAAkB,EAAE,CAAC;IAClD,yDAAyD;IACzD,IAAI,gBAAgB;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,uBAAuB,CAAC;AACjC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Widget\n */\n\nimport * as React from \"react\";\nimport { SvgCloseSmall } from \"@itwin/itwinui-icons-react\";\nimport { WidgetAction } from \"../../layout/widget/WidgetAction.js\";\nimport { usePreviewFeatures } from \"../PreviewFeatures.js\";\nimport { useActiveTabId } from \"../../layout/widget/Widget.js\";\nimport { NineZoneDispatchContext } from \"../../layout/base/NineZone.js\";\nimport type { TabState } from \"../../layout/state/TabState.js\";\n\n/** @internal */\nexport function CloseWidgetButton() {\n const id = useActiveTabId();\n const dispatch = React.useContext(NineZoneDispatchContext);\n\n return (\n <WidgetAction\n icon={<SvgCloseSmall />}\n label=\"Close widget\"\n onClick={() => {\n dispatch({\n type: \"WIDGET_TAB_HIDE\",\n id,\n });\n }}\n />\n );\n}\n\n/** @internal */\nexport function useControlWidgetVisibility(id: TabState[\"id\"]) {\n const { controlWidgetVisibility } = usePreviewFeatures();\n if (Array.isArray(controlWidgetVisibility)) {\n return controlWidgetVisibility.includes(id);\n }\n return !!controlWidgetVisibility;\n}\n\n/** @internal */\nexport function useCloseTab() {\n const id = useActiveTabId();\n const controlWidgetVisibility = useControlWidgetVisibility(id);\n const { widgetTabActions } = usePreviewFeatures();\n // Close tab button is displayed for each individual tab.\n if (widgetTabActions) return false;\n return controlWidgetVisibility;\n}\n"]}
@@ -0,0 +1,10 @@
1
+ /** @packageDocumentation
2
+ * @module Widget
3
+ */
4
+ import "./Widget.scss";
5
+ import * as React from "react";
6
+ /** @internal */
7
+ export declare function PanelWidget(): React.JSX.Element;
8
+ /** @internal */
9
+ export declare function FloatingWidget(): React.JSX.Element;
10
+ //# sourceMappingURL=Widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Widget.d.ts","sourceRoot":"","sources":["../../../../src/appui-react/preview/widget-tab-actions/Widget.tsx"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,eAAe,CAAC;AAEvB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiX/B,gBAAgB;AAChB,wBAAgB,WAAW,sBAa1B;AAED,gBAAgB;AAChB,wBAAgB,cAAc,sBA2B7B"}