=
- withITwinIdOverride(
- withAccessTokenOverride((args) => {
- const [filter, setFilter] = React.useState("");
- const filterOrAddStartTile = React.useCallback(
- (iModels: IModelFull[], status?: DataStatus) => {
- if (status !== DataStatus.Complete) {
- return iModels;
- }
- const filterText = filter.toLocaleLowerCase().trim();
- if (filterText) {
- return iModels.filter((iModel) =>
- iModel.displayName?.toLocaleLowerCase().includes(filterText)
- );
- }
- iModels.unshift({
- id: "newiModel",
- displayName: "New iModel",
- description: "Click on this tile to create a new iModel",
- thumbnail:
- "https://unpkg.com/@bentley/icons-generic@1.0.34/icons/add.svg",
- });
- return iModels;
- },
- [filter]
- );
- return (
-
- Description
-
- Property postProcessCallback allows modification of the
- data that is sent to the grid, here, we either apply a filter, or
- add a new tile at the start of the list for a 'New iModel' when
- there is no filter defined.
-
- {
- const {
- target: { value },
- } = event;
- setFilter(value);
- }}
- />
-
-
- );
- })
+const WithPostProcessCallbackRender = (args: IModelGridProps) => {
+ const [filter, setFilter] = React.useState("");
+ const filterOrAddStartTile = React.useCallback(
+ (iModels: IModelFull[], status?: DataStatus) => {
+ if (status !== DataStatus.Complete) {
+ return iModels;
+ }
+ const filterText = filter.toLocaleLowerCase().trim();
+ if (filterText) {
+ return iModels.filter((iModel) =>
+ iModel.displayName?.toLocaleLowerCase().includes(filterText)
+ );
+ }
+ iModels.unshift({
+ id: "newiModel",
+ displayName: "New iModel",
+ description: "Click on this tile to create a new iModel",
+ thumbnail:
+ "https://unpkg.com/@bentley/icons-generic@1.0.34/icons/add.svg",
+ });
+ return iModels;
+ },
+ [filter]
);
-WithPostProcessCallback.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
-};
-
-export const DefaultNoStateComponentOverride = Template.bind({});
-DefaultNoStateComponentOverride.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- emptyStateComponent: (
+ return (
- There are no iModels to show.
+ Description
+
+ Property postProcessCallback allows modification of the
+ data that is sent to the grid, here, we either apply a filter, or add a
+ new tile at the start of the list for a 'New iModel' when there is no
+ filter defined.
+
+ {
+ const {
+ target: { value },
+ } = event;
+ setFilter(value);
+ }}
+ />
+
- ),
+ );
};
-export const DisableAddToRecents = Template.bind({});
-DisableAddToRecents.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- disableAddToRecents: true,
+export const WithPostProcessCallback: StoryObj = {
+ render: (args) => ,
};
-DisableAddToRecents.argTypes = {
- accessToken: { table: { disable: true } },
- onThumbnailClick: { table: { disable: true } },
- sortOptions: { table: { disable: true } },
- iModelActions: { table: { disable: true } },
- useIndividualState: { table: { disable: true } },
- tileOverrides: { table: { disable: true } },
- stringsOverrides: { table: { disable: true } },
- apiOverrides: { table: { disable: true } },
- postProcessCallback: { table: { disable: true } },
- emptyStateComponent: { table: { disable: true } },
- searchText: { table: { disable: true } },
- viewMode: { table: { disable: true } },
- pageSize: { table: { disable: true } },
- maxCount: { table: { disable: true } },
- cellOverrides: { table: { disable: true } },
- className: { table: { disable: true } },
+
+export const DefaultNoStateComponentOverride: StoryObj = {
+ args: {
+ emptyStateComponent: (
+
+ There are no iModels to show.
+
+ ),
+ },
};
-export const Recents = Template.bind({});
-Recents.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- requestType: "recents",
+export const DisableAddToRecents: StoryObj = {
+ args: {
+ disableAddToRecents: true,
+ },
+ argTypes: {
+ accessToken: { table: { disable: true } },
+ onThumbnailClick: { table: { disable: true } },
+ sortOptions: { table: { disable: true } },
+ iModelActions: { table: { disable: true } },
+ useIndividualState: { table: { disable: true } },
+ tileOverrides: { table: { disable: true } },
+ stringsOverrides: { table: { disable: true } },
+ apiOverrides: { table: { disable: true } },
+ postProcessCallback: { table: { disable: true } },
+ emptyStateComponent: { table: { disable: true } },
+ searchText: { table: { disable: true } },
+ viewMode: { table: { disable: true } },
+ pageSize: { table: { disable: true } },
+ maxCount: { table: { disable: true } },
+ cellOverrides: { table: { disable: true } },
+ className: { table: { disable: true } },
+ },
};
-export const RecentsWithCustomIcon = Template.bind({});
-RecentsWithCustomIcon.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- requestType: "recents",
- removeFromRecentsIcon: ,
+export const Recents: StoryObj = {
+ args: {
+ requestType: "recents",
+ },
};
-export const RecentsWithCloseIcon = Template.bind({});
-RecentsWithCloseIcon.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- requestType: "recents",
- removeFromRecentsIcon: ,
+export const RecentsWithCustomIcon: StoryObj = {
+ args: {
+ requestType: "recents",
+ removeFromRecentsIcon: ,
+ },
+};
+
+export const RecentsWithCloseIcon: StoryObj = {
+ args: {
+ requestType: "recents",
+ removeFromRecentsIcon: ,
+ },
};
diff --git a/packages/apps/storybook/src/imodel-browser/IModelGridMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/IModelGridMUI.stories.tsx
index de284f53..b402d382 100644
--- a/packages/apps/storybook/src/imodel-browser/IModelGridMUI.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/IModelGridMUI.stories.tsx
@@ -13,8 +13,8 @@ import Avatar from "@mui/material/Avatar";
import AvatarGroup from "@mui/material/AvatarGroup";
import Chip from "@mui/material/Chip";
import Typography from "@mui/material/Typography";
-import { action } from "@storybook/addon-actions";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import { action } from "storybook/actions";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import SvgDelete from "@stratakit/icons/delete.svg";
import React from "react";
@@ -22,8 +22,6 @@ import bridgeThumbnail from "../utils/bridge.jpg";
import nightThumbnail from "../utils/night.jpg";
import {
accessTokenArgTypes,
- withAccessTokenOverride,
- withITwinIdOverride,
} from "../utils/storyHelp";
import {
additionalData,
@@ -42,10 +40,6 @@ export default {
excludeStories: ["IModelGridMUI"],
} as Meta;
-const Template: Story = withITwinIdOverride(
- withAccessTokenOverride((args) => )
-);
-
const baseArgs: IModelGridMUIProps = {
apiOverrides: { serverEnvironmentPrefix: "qa" },
sortOptions: { sortType: "name", descending: false },
@@ -72,17 +66,19 @@ const baseArgs: IModelGridMUIProps = {
],
};
-export const Primary = Template.bind({});
-Primary.args = { ...baseArgs };
+export const Primary: StoryObj = {
+ args: { ...baseArgs },
+};
-export const TableView = Template.bind({});
-TableView.args = {
- ...baseArgs,
- viewMode: "cells",
+export const TableView: StoryObj = {
+ args: {
+ ...baseArgs,
+ viewMode: "cells",
+ },
};
-export const TableViewWithOverrides = Template.bind({});
-TableViewWithOverrides.args = {
+export const TableViewWithOverrides: StoryObj = {
+ args: {
...baseArgs,
actions: [
{
@@ -127,11 +123,10 @@ TableViewWithOverrides.args = {
},
hideColumns: [IModelCellColumn.LastModified],
},
+ },
};
-export const OverrideApiDataWithLoadMore: Story =
- withITwinIdOverride(
- withAccessTokenOverride((args) => {
+const OverrideApiDataWithLoadMoreRender = (args: IModelGridMUIProps) => {
const [data, setData] = React.useState(initialData);
const [isLoading, setIsLoading] = React.useState(false);
const [hasMore, setHasMore] = React.useState(true);
@@ -170,11 +165,15 @@ export const OverrideApiDataWithLoadMore: Story =
onLoadMore={handleLoadMore}
/>
);
- })
- );
+};
+
+export const OverrideApiDataWithLoadMore: StoryObj = {
+ render: (args) => ,
+ args: { ...baseArgs },
+};
-export const ContextualActions = Template.bind({});
-ContextualActions.args = {
+export const ContextualActions: StoryObj = {
+ args: {
...baseArgs,
actions: [
{
@@ -215,29 +214,32 @@ ContextualActions.args = {
action("Edit description: " + iModel?.displayName)(iModel),
},
],
+ },
};
-export const SimpleTilePropsOverrides = Template.bind({});
-SimpleTilePropsOverrides.args = {
- ...baseArgs,
- tileOverrides: {
- thumbnail: bridgeThumbnail,
- thumbnailBottomRight: ,
- thumbnailBottomLeft: ,
- thumbnailTopLeft: (
-
-
-
-
-
- ),
+export const SimpleTilePropsOverrides: StoryObj = {
+ args: {
+ ...baseArgs,
+ tileOverrides: {
+ thumbnail: bridgeThumbnail,
+ thumbnailBottomRight: ,
+ thumbnailBottomLeft: ,
+ thumbnailTopLeft: (
+
+
+
+
+
+ ),
+ },
},
};
-export const StatefulPropsOverrides = Template.bind({});
-StatefulPropsOverrides.args = {
- ...baseArgs,
- useIndividualState,
+export const StatefulPropsOverrides: StoryObj = {
+ args: {
+ ...baseArgs,
+ useIndividualState,
+ },
};
function addStartTileCallback(iModels: IModelFull[], status?: DataStatus) {
@@ -254,127 +256,134 @@ function addStartTileCallback(iModels: IModelFull[], status?: DataStatus) {
return iModels;
}
-export const WithPostProcessCallback = Template.bind({});
-WithPostProcessCallback.args = {
- ...baseArgs,
- postProcessCallback: addStartTileCallback,
+export const WithPostProcessCallback: StoryObj = {
+ args: {
+ ...baseArgs,
+ postProcessCallback: addStartTileCallback,
+ },
};
-export const DefaultNoStateComponentOverride = Template.bind({});
-DefaultNoStateComponentOverride.args = {
- ...baseArgs,
- emptyStateComponent: (
-
- {/* eslint-disable-next-line jsx-a11y/heading-has-content */}
- }>
- There are no iModels to show.
-
-
- ),
+export const DefaultNoStateComponentOverride: StoryObj = {
+ args: {
+ ...baseArgs,
+ emptyStateComponent: (
+
+ {/* eslint-disable-next-line jsx-a11y/heading-has-content */}
+ }>
+ There are no iModels to show.
+
+
+ ),
+ },
};
-export const DisableAddToRecents = Template.bind({});
-DisableAddToRecents.args = {
- ...baseArgs,
- disableAddToRecents: true,
-};
-DisableAddToRecents.argTypes = {
- accessToken: { table: { disable: true } },
- actions: { table: { disable: true } },
- sortOptions: { table: { disable: true } },
- moreActions: { table: { disable: true } },
- useIndividualState: { table: { disable: true } },
- tileOverrides: { table: { disable: true } },
- stringsOverrides: { table: { disable: true } },
- apiOverrides: { table: { disable: true } },
- postProcessCallback: { table: { disable: true } },
- emptyStateComponent: { table: { disable: true } },
- searchText: { table: { disable: true } },
- viewMode: { table: { disable: true } },
- pageSize: { table: { disable: true } },
- maxCount: { table: { disable: true } },
- tableOverrides: { table: { disable: true } },
- className: { table: { disable: true } },
+export const DisableAddToRecents: StoryObj = {
+ args: {
+ ...baseArgs,
+ disableAddToRecents: true,
+ },
+ argTypes: {
+ accessToken: { table: { disable: true } },
+ actions: { table: { disable: true } },
+ sortOptions: { table: { disable: true } },
+ moreActions: { table: { disable: true } },
+ useIndividualState: { table: { disable: true } },
+ tileOverrides: { table: { disable: true } },
+ stringsOverrides: { table: { disable: true } },
+ apiOverrides: { table: { disable: true } },
+ postProcessCallback: { table: { disable: true } },
+ emptyStateComponent: { table: { disable: true } },
+ searchText: { table: { disable: true } },
+ viewMode: { table: { disable: true } },
+ pageSize: { table: { disable: true } },
+ maxCount: { table: { disable: true } },
+ tableOverrides: { table: { disable: true } },
+ className: { table: { disable: true } },
+ },
};
-export const Recents = Template.bind({});
-Recents.args = {
- ...baseArgs,
- requestType: "recents",
+export const Recents: StoryObj = {
+ args: {
+ ...baseArgs,
+ requestType: "recents",
+ },
};
-export const RecentsWithCustomIcon = Template.bind({});
-RecentsWithCustomIcon.args = {
- ...baseArgs,
- requestType: "recents",
- removeFromRecentsIcon: SvgDelete,
+export const RecentsWithCustomIcon: StoryObj = {
+ args: {
+ ...baseArgs,
+ requestType: "recents",
+ removeFromRecentsIcon: SvgDelete,
+ },
};
-export const NoResultsWithDefaultEmptyState = Template.bind({});
-NoResultsWithDefaultEmptyState.args = {
- ...baseArgs,
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- postProcessCallback: (iModels, status) => {
- return [];
+export const NoResultsWithDefaultEmptyState: StoryObj = {
+ args: {
+ ...baseArgs,
+ apiOverrides: { serverEnvironmentPrefix: "qa" },
+ postProcessCallback: (iModels, status) => {
+ return [];
+ },
},
};
-export const StringsOverrideGrid = Template.bind({});
-StringsOverrideGrid.args = {
- ...baseArgs,
- moreActions: [
- {
- label: "Some action",
- key: "something",
- onClick: (iModel) => action("clicked " + iModel?.displayName)(iModel),
+export const StringsOverrideGrid: StoryObj = {
+ args: {
+ ...baseArgs,
+ moreActions: [
+ {
+ label: "Some action",
+ key: "something",
+ onClick: (iModel) => action("clicked " + iModel?.displayName)(iModel),
+ },
+ ],
+ stringsOverrides: {
+ moreOptions: "Fleiri valkostir",
+ addToFavorites: "Bæta við eftirlæti",
+ removeFromFavorites: "Fjarlægja úr eftirlætum",
+ tableColumnName: "Heiti iModel",
+ tableColumnDescription: "Lýsing iModel",
+ tableColumnLastModified: "Síðast breytt",
+ noRowsLabel: "Engar raðir",
+ noResultsOverlayLabel: "Engar niðurstöður fundust.",
+ paginationRowsPerPage: "Raðir á síðu:",
+ footerRowSelected: (count: number) =>
+ count !== 1
+ ? `${count.toLocaleString()} raðir valdar`
+ : `${count.toLocaleString()} röð valin`,
+ footerTotalVisibleRows: (visibleCount: number, totalCount: number) =>
+ `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`,
},
- ],
- stringsOverrides: {
- moreOptions: "Fleiri valkostir",
- addToFavorites: "Bæta við eftirlæti",
- removeFromFavorites: "Fjarlægja úr eftirlætum",
- tableColumnName: "Heiti iModel",
- tableColumnDescription: "Lýsing iModel",
- tableColumnLastModified: "Síðast breytt",
- noRowsLabel: "Engar raðir",
- noResultsOverlayLabel: "Engar niðurstöður fundust.",
- paginationRowsPerPage: "Raðir á síðu:",
- footerRowSelected: (count: number) =>
- count !== 1
- ? `${count.toLocaleString()} raðir valdar`
- : `${count.toLocaleString()} röð valin`,
- footerTotalVisibleRows: (visibleCount: number, totalCount: number) =>
- `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`,
},
};
-export const StringsOverrideTable = Template.bind({});
-StringsOverrideTable.args = {
- ...baseArgs,
- viewMode: "cells",
-
- moreActions: [
- {
- label: "Some action",
- key: "something",
- onClick: (iModel) => action("clicked " + iModel?.displayName)(iModel),
+export const StringsOverrideTable: StoryObj = {
+ args: {
+ ...baseArgs,
+ viewMode: "cells",
+ moreActions: [
+ {
+ label: "Some action",
+ key: "something",
+ onClick: (iModel) => action("clicked " + iModel?.displayName)(iModel),
+ },
+ ],
+ stringsOverrides: {
+ moreOptions: "Fleiri valkostir",
+ addToFavorites: "Bæta við eftirlæti",
+ removeFromFavorites: "Fjarlægja úr eftirlætum",
+ tableColumnName: "Heiti iModel",
+ tableColumnDescription: "Lýsing iModel",
+ tableColumnLastModified: "Síðast breytt",
+ noRowsLabel: "Engar raðir",
+ noResultsOverlayLabel: "Engar niðurstöður fundust.",
+ paginationRowsPerPage: "Raðir á síðu:",
+ footerRowSelected: (count: number) =>
+ count !== 1
+ ? `${count.toLocaleString()} raðir valdar`
+ : `${count.toLocaleString()} röð valin`,
+ footerTotalVisibleRows: (visibleCount: number, totalCount: number) =>
+ `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`,
},
- ],
- stringsOverrides: {
- moreOptions: "Fleiri valkostir",
- addToFavorites: "Bæta við eftirlæti",
- removeFromFavorites: "Fjarlægja úr eftirlætum",
- tableColumnName: "Heiti iModel",
- tableColumnDescription: "Lýsing iModel",
- tableColumnLastModified: "Síðast breytt",
- noRowsLabel: "Engar raðir",
- noResultsOverlayLabel: "Engar niðurstöður fundust.",
- paginationRowsPerPage: "Raðir á síðu:",
- footerRowSelected: (count: number) =>
- count !== 1
- ? `${count.toLocaleString()} raðir valdar`
- : `${count.toLocaleString()} röð valin`,
- footerTotalVisibleRows: (visibleCount: number, totalCount: number) =>
- `${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`,
},
};
diff --git a/packages/apps/storybook/src/imodel-browser/IModelTile.stories.tsx b/packages/apps/storybook/src/imodel-browser/IModelTile.stories.tsx
index fdec087b..2a3a4868 100644
--- a/packages/apps/storybook/src/imodel-browser/IModelTile.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/IModelTile.stories.tsx
@@ -5,7 +5,7 @@
import { IModelTile as C, IModelTileProps } from "@itwin/imodel-browser-react";
import { SvgImodel, SvgPlaceholder } from "@itwin/itwinui-icons-react";
import { Badge, Button } from "@itwin/itwinui-react";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";
export const IModelTile = (props: IModelTileProps) => ;
@@ -16,32 +16,31 @@ export default {
excludeStories: ["IModelTile"],
} as Meta;
-const Template: Story = (args) => ;
-
-export const Primary = Template.bind({});
-Primary.args = {
- iModel: {
- id: "1",
- displayName: "iModel Name",
- description: "iModel Description",
- },
- iModelOptions: [
- { key: "option-1", children: "Option 1" },
- { key: "option-2", children: "Option 2" },
- ],
- tileProps: {
- status: "positive",
- isDisabled: false,
- isLoading: false,
- isSelected: false,
- isNew: false,
- badge: Badge ,
- leftIcon: ,
- rightIcon: ,
- buttons: [
- Button 1 ,
- Button 2 ,
+export const Primary: StoryObj = {
+ args: {
+ iModel: {
+ id: "1",
+ displayName: "iModel Name",
+ description: "iModel Description",
+ },
+ iModelOptions: [
+ { key: "option-1", children: "Option 1" },
+ { key: "option-2", children: "Option 2" },
],
- thumbnail: ,
+ tileProps: {
+ status: "positive",
+ isDisabled: false,
+ isLoading: false,
+ isSelected: false,
+ isNew: false,
+ badge: Badge ,
+ leftIcon: ,
+ rightIcon: ,
+ buttons: [
+ Button 1 ,
+ Button 2 ,
+ ],
+ thumbnail: ,
+ },
},
};
diff --git a/packages/apps/storybook/src/imodel-browser/IModelTileMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/IModelTileMUI.stories.tsx
index da09c32a..bfb3342c 100644
--- a/packages/apps/storybook/src/imodel-browser/IModelTileMUI.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/IModelTileMUI.stories.tsx
@@ -11,8 +11,8 @@ import Avatar from "@mui/material/Avatar";
import AvatarGroup from "@mui/material/AvatarGroup";
import Box from "@mui/material/Box";
import Chip from "@mui/material/Chip";
-import { action } from "@storybook/addon-actions";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import { action } from "storybook/actions";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import SvgDelete from "@stratakit/icons/delete.svg";
import svgRoad from "@stratakit/icons/road.svg";
import SvgShare from "@stratakit/icons/share.svg";
@@ -61,10 +61,6 @@ export default {
},
} as Meta;
-const Template: Story = (args) => (
-
-);
-
const baseArgs: IModelTileMUIProps = {
iModel: {
id: "1",
@@ -99,48 +95,52 @@ const baseArgs: IModelTileMUIProps = {
],
};
-export const Default = Template.bind({});
-Default.args = {
- ...baseArgs,
+export const Default: StoryObj = {
+ args: {
+ ...baseArgs,
+ },
};
-export const Extensive = Template.bind({});
-Extensive.args = {
- ...baseArgs,
- title: "Overridden Title",
- description: "Overriden description",
- subheader: "Additional description",
- thumbnail: overpassThumbnail,
- getBadge: () => ,
- thumbnailTopLeft: (
-
-
-
-
-
- ),
- actions: [
- {
- key: "open",
- label: "Open in App",
- onClick: action("iModel opened"),
- },
- {
- key: "vr",
- label: "Open in VR Headset",
- onClick: action("VR Headset clicked"),
- },
- ],
+export const Extensive: StoryObj = {
+ args: {
+ ...baseArgs,
+ title: "Overridden Title",
+ description: "Overriden description",
+ subheader: "Additional description",
+ thumbnail: overpassThumbnail,
+ getBadge: () => ,
+ thumbnailTopLeft: (
+
+
+
+
+
+ ),
+ actions: [
+ {
+ key: "open",
+ label: "Open in App",
+ onClick: action("iModel opened"),
+ },
+ {
+ key: "vr",
+ label: "Open in VR Headset",
+ onClick: action("VR Headset clicked"),
+ },
+ ],
+ },
};
-export const NoThumbnail = Template.bind({});
-NoThumbnail.args = {
- ...baseArgs,
- thumbnail: undefined,
+export const NoThumbnail: StoryObj = {
+ args: {
+ ...baseArgs,
+ thumbnail: undefined,
+ },
};
-export const CustomSvgThumbnail = Template.bind({});
-CustomSvgThumbnail.args = {
- ...baseArgs,
- thumbnail: ,
+export const CustomSvgThumbnail: StoryObj = {
+ args: {
+ ...baseArgs,
+ thumbnail: ,
+ },
};
diff --git a/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx b/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx
index 3cf45a61..8d4b70f8 100644
--- a/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/ITwinGrid.stories.tsx
@@ -21,13 +21,9 @@ import {
Text,
Tile,
} from "@itwin/itwinui-react";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React, { PropsWithChildren } from "react";
-
-import {
- accessTokenArgTypes,
- withAccessTokenOverride,
-} from "../utils/storyHelp";
+import { accessTokenArgTypes } from "../utils/storyHelp";
type TileProps = React.ComponentPropsWithoutRef;
@@ -35,97 +31,92 @@ export const ITwinGrid = (props: ITwinGridProps) => (
);
-const accessToken = accessTokenArgTypes.accessToken;
export default {
title: "imodel-browser/ITwinGrid",
component: ITwinGrid,
- argTypes: {
- accessToken,
- },
+ argTypes: accessTokenArgTypes,
+ args: { apiOverrides: { serverEnvironmentPrefix: "qa" } },
excludeStories: ["ITwinGrid"],
} as Meta;
-const Template: Story = withAccessTokenOverride((args) => (
-
-));
-export const Primary = Template.bind({});
-Primary.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
+export const Primary: StoryObj = {};
+
+export const OverrideCellData: StoryObj = {
+ args: {
+ viewMode: "cells",
+ cellOverrides: {
+ ITwinNumber: (props) => (
+
+ {
+ e.stopPropagation();
+ console.log("Icon Clicked");
+ }}
+ >
+
+ {" "}
+ {props.value}
+
+ ),
+ ITwinName: (props) => {props.value} ,
+ hideColumns: [ITwinCellColumn.LastModified],
+ },
+ },
};
-export const OverrideCellData = Template.bind({});
-OverrideCellData.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- viewMode: "cells",
- cellOverrides: {
- ITwinNumber: (props) => (
-
- {
- e.stopPropagation();
- console.log("Icon Clicked");
- }}
- >
-
- {" "}
- {props.value}
-
- ),
- ITwinName: (props) => {props.value} ,
- hideColumns: [ITwinCellColumn.LastModified],
+export const OverrideApiData: StoryObj = {
+ args: {
+ apiOverrides: {
+ data: [
+ {
+ id: "1",
+ displayName: "Provided iTwin",
+ number: "No Network Calls",
+ },
+ {
+ id: "2",
+ displayName: "Useful iTwin",
+ number:
+ "Use if the data comes from a different API or needs to be tweaked",
+ },
+ ],
+ },
},
};
-export const OverrideApiData = Template.bind({});
-OverrideApiData.args = {
- apiOverrides: {
- data: [
+export const IndividualContextMenu: StoryObj = {
+ args: {
+ iTwinActions: [
{
- id: "1",
- displayName: "Provided iTwin",
- number: "No Network Calls",
+ children: "displayName contains 'R'",
+ visible: (iTwin) => iTwin.displayName?.includes("R") ?? false,
+ key: "withR",
+ onClick: (iTwin) => alert("Contains R" + iTwin?.displayName),
},
{
- id: "2",
- displayName: "Useful iTwin",
- number:
- "Use if the data comes from a different API or needs to be tweaked",
+ children: "Add iTwinNumber",
+ visible: (iTwin) => !iTwin.number,
+ key: "addD",
+ onClick: (iTwin) => alert("Add iTwinNumber to " + iTwin?.displayName),
+ },
+ {
+ children: "Edit iTwinNumber",
+ visible: (iTwin) => !!iTwin.number,
+ key: "editD",
+ onClick: (iTwin) => alert("Edit iTwinNumber: " + iTwin?.number),
},
],
},
};
-export const IndividualContextMenu = Template.bind({});
-IndividualContextMenu.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- iTwinActions: [
- {
- children: "displayName contains 'R'",
- visible: (iTwin) => iTwin.displayName?.includes("R") ?? false,
- key: "withR",
- onClick: (iTwin) => alert("Contains R" + iTwin?.displayName),
- },
- {
- children: "Add iTwinNumber",
- visible: (iTwin) => !iTwin.number,
- key: "addD",
- onClick: (iTwin) => alert("Add iTwinNumber to " + iTwin?.displayName),
+export const SimpleTilePropsOverrides: StoryObj = {
+ args: {
+ tileOverrides: {
+ tileProps: { style: { width: "100%" }, variant: "folder" },
},
- {
- children: "Edit iTwinNumber",
- visible: (iTwin) => !!iTwin.number,
- key: "editD",
- onClick: (iTwin) => alert("Edit iTwinNumber: " + iTwin?.number),
- },
- ],
-};
-
-export const SimpleTilePropsOverrides = Template.bind({});
-SimpleTilePropsOverrides.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- tileOverrides: { tileProps: { style: { width: "100%" }, variant: "folder" } },
+ },
};
interface IModelMinimal {
@@ -147,28 +138,27 @@ const buildMenuItems =
close: () => void,
setVersion: React.Dispatch>
) =>
- (v: IModelMinimal) =>
- (
- {
- event.stopPropagation();
- }}
- >
- {v.id === "loading" ? (
-
- ) : (
- {
- close();
- v.id !== "loading" && setVersion(v);
- }}
- >
- {v.displayName}
-
- )}
-
- );
+ (v: IModelMinimal) => (
+ {
+ event.stopPropagation();
+ }}
+ >
+ {v.id === "loading" ? (
+
+ ) : (
+ {
+ close();
+ v.id !== "loading" && setVersion(v);
+ }}
+ >
+ {v.displayName}
+
+ )}
+
+ );
const Pager = (props: PropsWithChildren<{ onClick: () => void }>) => (
@@ -258,7 +248,7 @@ const useIndividualState: IndividualITwinStateHook = (iTwin, props) => {
metadata: (
{
- imodels === undefined && fetchIModelList();
+ imodels === undefined && void fetchIModelList();
}}
>
{
};
};
-export const StatefulPropsOverrides = Template.bind({});
-StatefulPropsOverrides.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- useIndividualState,
+export const StatefulPropsOverrides: StoryObj = {
+ args: {
+ useIndividualState,
+ },
};
-export const WithPostProcessCallback: Story =
- withAccessTokenOverride((args) => {
- const addStartTile = React.useCallback(
- (iTwins: ITwinFull[], status: DataStatus | undefined) => {
- if (status !== DataStatus.Complete) {
- return iTwins;
- }
- iTwins.unshift({
- id: "newProject",
- displayName: "New Project",
- number: "Click on this tile to create a new ITwin",
- });
+const WithPostProcessCallbackRender = (args: ITwinGridProps) => {
+ const addStartTile = React.useCallback(
+ (iTwins: ITwinFull[], status: DataStatus | undefined) => {
+ if (status !== DataStatus.Complete) {
return iTwins;
- },
- []
- );
- return (
-
- Description
-
- Property postProcessCallback allows modification of the
- data that is sent to the grid, here, we add a new tile at the start of
- the list for a 'New Project'.
-
-
-
- );
- });
-WithPostProcessCallback.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
+ }
+ iTwins.unshift({
+ id: "newProject",
+ displayName: "New Project",
+ number: "Click on this tile to create a new ITwin",
+ });
+ return iTwins;
+ },
+ []
+ );
+ return (
+
+ Description
+
+ Property postProcessCallback allows modification of the
+ data that is sent to the grid, here, we add a new tile at the start of
+ the list for a 'New Project'.
+
+
+
+ );
+};
+
+export const WithPostProcessCallback: StoryObj = {
+ render: (args) => ,
};
-export const FetchAllSubclasses = Template.bind({});
-FetchAllSubclasses.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- iTwinSubClass: "All",
+export const FetchAllSubclasses: StoryObj = {
+ args: {
+ iTwinSubClass: "All",
+ },
};
diff --git a/packages/apps/storybook/src/imodel-browser/ITwinGridMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/ITwinGridMUI.stories.tsx
index 16419f33..69227270 100644
--- a/packages/apps/storybook/src/imodel-browser/ITwinGridMUI.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/ITwinGridMUI.stories.tsx
@@ -18,8 +18,8 @@ import AvatarGroup from "@mui/material/AvatarGroup";
import Box from "@mui/material/Box";
import Chip from "@mui/material/Chip";
import Typography from "@mui/material/Typography";
-import { action } from "@storybook/addon-actions";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import { action } from "storybook/actions";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";
import bridgeThumbnail from "../utils/bridge.jpg";
@@ -28,7 +28,6 @@ import overpassThumbnail from "../utils/overpass.jpg";
import powerThumbnail from "../utils/power.jpg";
import {
accessTokenArgTypes,
- withAccessTokenOverride,
} from "../utils/storyHelp";
type ITwinTileType = React.ComponentPropsWithoutRef;
@@ -39,9 +38,14 @@ export const ITwinGrid = (props: ITwinGridProps) => (
const accessToken = accessTokenArgTypes.accessToken;
-const Template: Story = withAccessTokenOverride((args) => (
-
-));
+export default {
+ title: "imodel-browser/ITwinGridMUI",
+ component: ITwinGrid,
+ argTypes: {
+ accessToken,
+ },
+ excludeStories: ["ITwinGrid"],
+} as Meta;
const baseArgs: ITwinGridProps = {
apiOverrides: { serverEnvironmentPrefix: "qa" },
@@ -55,13 +59,14 @@ const baseArgs: ITwinGridProps = {
],
};
-export const Primary = Template.bind({});
-Primary.args = {
- ...baseArgs,
+export const Primary: StoryObj = {
+ args: {
+ ...baseArgs,
+ },
};
-export const TableView = Template.bind({});
-TableView.args = {
+export const TableView: StoryObj = {
+ args: {
...baseArgs,
viewMode: "cells",
moreActions: [
@@ -77,10 +82,11 @@ TableView.args = {
action("clicked something else " + iTwin?.displayName)(iTwin),
},
],
+ },
};
-export const TableViewWithOverrides = Template.bind({});
-TableViewWithOverrides.args = {
+export const TableViewWithOverrides: StoryObj = {
+ args: {
...baseArgs,
viewMode: "cells",
actions: [
@@ -121,10 +127,11 @@ TableViewWithOverrides.args = {
},
hideColumns: [ITwinCellColumn.LastModified],
},
+ },
};
-export const OverrideApiData = Template.bind({});
-OverrideApiData.args = {
+export const OverrideApiData: StoryObj = {
+ args: {
...baseArgs,
apiOverrides: {
data: [
@@ -155,10 +162,11 @@ OverrideApiData.args = {
},
],
},
+ },
};
-export const IndividualContextMenu = Template.bind({});
-IndividualContextMenu.args = {
+export const IndividualContextMenu: StoryObj = {
+ args: {
...baseArgs,
moreActions: [
{
@@ -181,10 +189,11 @@ IndividualContextMenu.args = {
onClick: (iTwin) => action("Edit iTwinNumber: " + iTwin?.number)(iTwin),
},
],
+ },
};
-export const SimpleTilePropsOverrides = Template.bind({});
-SimpleTilePropsOverrides.args = {
+export const SimpleTilePropsOverrides: StoryObj = {
+ args: {
...baseArgs,
tileOverrides: {
status: "negative",
@@ -199,6 +208,7 @@ SimpleTilePropsOverrides.args = {
),
},
+ },
};
const useIndividualState: IndividualITwinStateHook = (iTwin, props) => {
@@ -231,14 +241,14 @@ const useIndividualState: IndividualITwinStateHook = (iTwin, props) => {
};
};
-export const UseIndividualState = Template.bind({});
-UseIndividualState.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- useIndividualState,
+export const UseIndividualState: StoryObj = {
+ args: {
+ apiOverrides: { serverEnvironmentPrefix: "qa" },
+ useIndividualState,
+ },
};
-export const WithPostProcessCallback: Story =
- withAccessTokenOverride((args) => {
+const WithPostProcessCallbackRender = (args: ITwinGridProps) => {
const addStartTile = React.useCallback(
(iTwins: ITwinFull[], status: any) => {
if (status !== (DataStatus as any).Complete) {
@@ -258,42 +268,49 @@ export const WithPostProcessCallback: Story =
Property postProcessCallback allows modification of the
data that is sent to the grid, here, we add a new tile at the start of
- the list for a 'New Project'.
+ the list for a 'New Project'.
);
- });
-WithPostProcessCallback.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
};
-export const FetchAllSubclasses = Template.bind({});
-FetchAllSubclasses.args = {
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- iTwinSubClass: "All",
+export const WithPostProcessCallback: StoryObj = {
+ render: (args) => ,
+ args: {
+ apiOverrides: { serverEnvironmentPrefix: "qa" },
+ },
};
-export const NoResultsWithDefaultEmptyState = Template.bind({});
-NoResultsWithDefaultEmptyState.args = {
- ...baseArgs,
- apiOverrides: { serverEnvironmentPrefix: "qa" },
- postProcessCallback: (iModels, status) => {
- return [];
+export const FetchAllSubclasses: StoryObj = {
+ args: {
+ apiOverrides: { serverEnvironmentPrefix: "qa" },
+ iTwinSubClass: "All",
},
};
-export const TableViewWithNoResults = Template.bind({});
-TableViewWithNoResults.args = {
- ...baseArgs,
- viewMode: "cells",
- postProcessCallback: (iModels, status) => {
- return [];
+export const NoResultsWithDefaultEmptyState: StoryObj = {
+ args: {
+ ...baseArgs,
+ apiOverrides: { serverEnvironmentPrefix: "qa" },
+ postProcessCallback: (iModels, status) => {
+ return [];
+ },
},
};
-export const StringsOverrideGrid = Template.bind({});
-StringsOverrideGrid.args = {
+export const TableViewWithNoResults: StoryObj = {
+ args: {
+ ...baseArgs,
+ viewMode: "cells",
+ postProcessCallback: (iModels, status) => {
+ return [];
+ },
+ },
+};
+
+export const StringsOverrideGrid: StoryObj = {
+ args: {
...baseArgs,
apiOverrides: {
data: [
@@ -342,10 +359,11 @@ StringsOverrideGrid.args = {
`${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`,
paginationRowsPerPage: "Rækker per side:",
},
+ },
};
-export const StringsOverrideTable = Template.bind({});
-StringsOverrideTable.args = {
+export const StringsOverrideTable: StoryObj = {
+ args: {
...baseArgs,
viewMode: "cells",
apiOverrides: {
@@ -398,13 +416,5 @@ StringsOverrideTable.args = {
`${visibleCount.toLocaleString()} af ${totalCount.toLocaleString()}`,
paginationRowsPerPage: "Rækker per side:",
},
-};
-
-export default {
- title: "imodel-browser/ITwinGridMUI",
- component: ITwinGrid,
- argTypes: {
- accessToken,
},
- excludeStories: ["ITwinGrid"],
-} as Meta;
+};
diff --git a/packages/apps/storybook/src/imodel-browser/ITwinTile.stories.tsx b/packages/apps/storybook/src/imodel-browser/ITwinTile.stories.tsx
index 42965b88..ff44c825 100644
--- a/packages/apps/storybook/src/imodel-browser/ITwinTile.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/ITwinTile.stories.tsx
@@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { ITwinTile as C, ITwinTileProps } from "@itwin/imodel-browser-react";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";
export const ITwinTile = (props: ITwinTileProps) => ;
@@ -14,12 +14,11 @@ export default {
excludeStories: ["ITwinTile"],
} as Meta;
-const Template: Story = (args) => ;
-
-export const Primary = Template.bind({});
-Primary.args = {
- iTwin: {
- id: "1",
- displayName: "iTwin Name",
+export const Primary: StoryObj = {
+ args: {
+ iTwin: {
+ id: "1",
+ displayName: "iTwin Name",
+ },
},
};
diff --git a/packages/apps/storybook/src/imodel-browser/ITwinTileMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/ITwinTileMUI.stories.tsx
index 78bb34b1..4d5674f0 100644
--- a/packages/apps/storybook/src/imodel-browser/ITwinTileMUI.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/ITwinTileMUI.stories.tsx
@@ -10,8 +10,8 @@ import {
import { SvgThumbnail } from "@itwin/imodel-browser-react/mui";
import Box from "@mui/material/Box";
import Chip from "@mui/material/Chip";
-import { action } from "@storybook/addon-actions";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import { action } from "storybook/actions";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import svgMagnet from "@stratakit/icons/magnet.svg";
import React from "react";
@@ -117,46 +117,46 @@ export default {
},
} as Meta;
-const Template: Story = (args) => (
-
-);
-
-export const Default = Template.bind({});
-Default.args = {
- ...baseArgs,
- isFavorite: false,
- disabled: false,
- loading: false,
+export const Default: StoryObj = {
+ args: {
+ ...baseArgs,
+ isFavorite: false,
+ disabled: false,
+ loading: false,
+ },
};
-export const Extensive = Template.bind({});
-Extensive.args = {
- ...baseArgs,
- status: "warning",
- isFavorite: true,
- title: "Overridden Title",
- description: "Overriden description",
- disabled: false,
- loading: false,
- thumbnail: powerThumbnail,
- thumbnailBottomRight: ,
- thumbnailTopLeft: ,
- thumbnailBottomLeft: ,
- actions: [
- { key: "open", label: "Open", onClick: action("iTwin open clicked") },
- { key: "share", label: "Share", onClick: action("iTwin share clicked") },
- ],
+export const Extensive: StoryObj = {
+ args: {
+ ...baseArgs,
+ status: "warning",
+ isFavorite: true,
+ title: "Overridden Title",
+ description: "Overriden description",
+ disabled: false,
+ loading: false,
+ thumbnail: powerThumbnail,
+ thumbnailBottomRight: ,
+ thumbnailTopLeft: ,
+ thumbnailBottomLeft: ,
+ actions: [
+ { key: "open", label: "Open", onClick: action("iTwin open clicked") },
+ { key: "share", label: "Share", onClick: action("iTwin share clicked") },
+ ],
+ },
};
-export const DefaultThumbnailStory = Template.bind({});
-DefaultThumbnailStory.args = {
- ...baseArgs,
- thumbnail: ,
+export const DefaultThumbnailStory: StoryObj = {
+ name: "Default Thumbnail",
+ args: {
+ ...baseArgs,
+ thumbnail: ,
+ },
};
-DefaultThumbnailStory.storyName = "Default Thumbnail";
-export const CustomSvgThumbnail = Template.bind({});
-CustomSvgThumbnail.args = {
- ...baseArgs,
- thumbnail: ,
+export const CustomSvgThumbnail: StoryObj = {
+ args: {
+ ...baseArgs,
+ thumbnail: ,
+ },
};
diff --git a/packages/apps/storybook/src/imodel-browser/NoResults.stories.tsx b/packages/apps/storybook/src/imodel-browser/NoResults.stories.tsx
index ea9a48de..32e9de63 100644
--- a/packages/apps/storybook/src/imodel-browser/NoResults.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/NoResults.stories.tsx
@@ -6,7 +6,7 @@ import {
NoResults as ExternalComponent,
NoResultsProps,
} from "@itwin/imodel-browser-react";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";
export const NoResults = (props: NoResultsProps) => (
@@ -19,7 +19,4 @@ export default {
excludeStories: ["NoResults"],
} as Meta;
-const Template: Story = (args) => ;
-
-export const Primary = Template.bind({});
-Primary.args = {};
+export const Primary: StoryObj = {};
diff --git a/packages/apps/storybook/src/imodel-browser/NoResultsMUI.stories.tsx b/packages/apps/storybook/src/imodel-browser/NoResultsMUI.stories.tsx
index abe95dda..74ed2a6c 100644
--- a/packages/apps/storybook/src/imodel-browser/NoResultsMUI.stories.tsx
+++ b/packages/apps/storybook/src/imodel-browser/NoResultsMUI.stories.tsx
@@ -6,7 +6,7 @@ import {
NoResults as ExternalComponent,
type NoResultsProps as NoResultsMUIProps,
} from "@itwin/imodel-browser-react/mui";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";
export const NoResults = (props: NoResultsMUIProps) => (
@@ -19,22 +19,23 @@ export default {
excludeStories: ["NoResults"],
} as Meta;
-const Template: Story = (args) => ;
-
-export const Primary = Template.bind({});
-Primary.args = {
- text: "No iModels available",
+export const Primary: StoryObj = {
+ args: {
+ text: "No iModels available",
+ },
};
-export const SearchResults = Template.bind({});
-SearchResults.args = {
- text: "No search results",
- subtext: "Try adjusting your search criteria.",
- isSearchResult: true,
+export const SearchResults: StoryObj = {
+ args: {
+ text: "No search results",
+ subtext: "Try adjusting your search criteria.",
+ isSearchResult: true,
+ },
};
-export const WithSubtext = Template.bind({});
-WithSubtext.args = {
- text: "No iModels available",
- subtext: "Please check back later.",
+export const WithSubtext: StoryObj = {
+ args: {
+ text: "No iModels available",
+ subtext: "Please check back later.",
+ },
};
diff --git a/packages/apps/storybook/src/manage-versions/ManageVersions.stories.tsx b/packages/apps/storybook/src/manage-versions/ManageVersions.stories.tsx
index 17b76fa5..f26e77ac 100644
--- a/packages/apps/storybook/src/manage-versions/ManageVersions.stories.tsx
+++ b/packages/apps/storybook/src/manage-versions/ManageVersions.stories.tsx
@@ -7,14 +7,10 @@ import {
ManageVersions as ExternalComponent,
ManageVersionsProps,
} from "@itwin/manage-versions-react";
-import { action } from "@storybook/addon-actions";
-import { Meta, Story } from "@storybook/react/types-6-0";
+import { action } from "storybook/actions";
+import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";
-
-import {
- accessTokenArgTypes,
- withAccessTokenOverride,
-} from "../utils/storyHelp";
+import { accessTokenArgTypes } from "../utils/storyHelp";
export const ManageVersions = (props: ManageVersionsProps) => (
@@ -26,21 +22,19 @@ export default {
excludeStories: ["ManageVersions"],
argTypes: {
...accessTokenArgTypes,
- log: { defaultValue: action("Error logged. "), control: { disable: true } },
- onViewClick: {
- defaultValue: action("View Named Version clicked"),
- control: { disable: true },
- },
+ log: { control: { disable: true } },
+ onViewClick: { control: { disable: true } },
+ },
+ args: {
+ log: action("Error logged."),
+ onViewClick: action("View Named Version clicked"),
},
} as Meta;
-const Template: Story = withAccessTokenOverride((args) => (
-
-));
-
-export const Primary = Template.bind({});
-Primary.args = {
- apiOverrides: {
- serverEnvironmentPrefix: "qa",
+export const Primary: StoryObj = {
+ args: {
+ apiOverrides: {
+ serverEnvironmentPrefix: "qa",
+ },
},
};
diff --git a/packages/apps/storybook/src/utils/storyHelp.ts b/packages/apps/storybook/src/utils/storyHelp.ts
index 82a583b9..ca1c378f 100644
--- a/packages/apps/storybook/src/utils/storyHelp.ts
+++ b/packages/apps/storybook/src/utils/storyHelp.ts
@@ -2,35 +2,29 @@
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
-import { Story } from "@storybook/react/types-6-0";
const ACCESS_TOKEN_DEFAULT_VALUE =
"In this storybook, this is provided by clicking on the key in the toolbar";
export const accessTokenArgTypes = {
accessToken: {
- defaultValue: ACCESS_TOKEN_DEFAULT_VALUE,
+ control: { type: "text" },
+ table: { defaultValue: { summary: ACCESS_TOKEN_DEFAULT_VALUE } },
},
};
-/** HOC that will override the "accessToken" prop with the Addon token */
-export const withAccessTokenOverride: <
- T extends { accessToken?: string | (() => Promise) }
->(
- story: Story
-) => Story = (Story) => (args, context) =>
- Story({ ...args, accessToken: context.globals.accessToken }, context);
+const ITWIN_ID_DEFAULT_VALUE =
+ "In this storybook, this is provided by selecting an iTwin in the toolbar";
+export const iTwinIdArgTypes = {
+ iTwinId: {
+ description: "iTwin ID to load data from",
+ control: { type: "text" },
+ table: { defaultValue: { summary: ITWIN_ID_DEFAULT_VALUE } },
+ },
+};
-/** HOC that will override the "iTwinId" prop with the Addon iTwinId */
-export const withITwinIdOverride: (
- story: Story
-) => Story = (Story) => (args, context) =>
- Story(
- {
- ...args,
- iTwinId:
- args.iTwinId ??
- context.globals.iTwinId ??
- process.env.STORYBOOK_ITWIN_ID,
- },
- context
- );
+/** Combined helper for stories that need both access token (auth toolbar)
+ * and iTwin ID (project selector toolbar). */
+export const iTwinAndAccessTokenArgTypes = {
+ ...accessTokenArgTypes,
+ ...iTwinIdArgTypes,
+};
diff --git a/packages/modules/storybook-auth-addon/register.js b/packages/modules/storybook-auth-addon/manager.jsx
similarity index 71%
rename from packages/modules/storybook-auth-addon/register.js
rename to packages/modules/storybook-auth-addon/manager.jsx
index d369ef4f..f381d369 100644
--- a/packages/modules/storybook-auth-addon/register.js
+++ b/packages/modules/storybook-auth-addon/manager.jsx
@@ -5,24 +5,30 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { ClientRequestContext } from "@bentley/bentleyjs-core";
import { BrowserAuthorizationClient } from "@bentley/frontend-authorization-client";
-import addons, { types } from "@storybook/addons";
-import { useAddonState, useGlobals, useParameter } from "@storybook/api";
-import { IconButton, Icons, Loader, WithTooltip } from "@storybook/components";
+import {
+ addons,
+ types,
+ useAddonState,
+ useParameter,
+} from "storybook/manager-api";
+import { IconButton, WithTooltip } from "storybook/internal/components";
+import { AlertIcon, KeyIcon, LockIcon } from "@storybook/icons";
import React, { useRef, useState } from "react";
+const ACCESS_TOKEN_EVENT = "auth/toolbar/set-access-token";
+
addons.register("auth/toolbar", () => {
addons.add("auth-toolbar-addon/toolbar", {
title: "OIDC Authentication toolbar",
- //👇 Sets the type of UI element in Storybook
type: types.TOOL,
- //👇 Shows the Toolbar UI element if either the Canvas or Docs tab is active
match: ({ viewMode }) => !!viewMode?.match(/^(story|docs)$/),
render: () => {
- const [globals, updateGlobals] = useGlobals();
+ const channel = addons.getChannel();
const redirectURI = `${window.location.origin}${window.location.pathname}signin-oidc.html`;
const [state, setState] = useAddonState("auth/toolbar", {
loading: false,
email: "",
+ accessToken: "",
});
const authClientConfig = useParameter("authClientConfig", {});
const client = useRef(null);
@@ -55,8 +61,8 @@ addons.register("auth/toolbar", () => {
});
client.current.onUserStateChanged.addListener((accessToken) => {
if (!accessToken) {
- updateGlobals({ accessToken: "" });
- setState({ loading: false });
+ setState({ loading: false, email: "", accessToken: "" });
+ channel.emit(ACCESS_TOKEN_EVENT, "");
return;
}
let tokenString = accessToken.toTokenString();
@@ -65,22 +71,22 @@ addons.register("auth/toolbar", () => {
email = JSON.parse(
atob(tokenString.split(" ")[1]?.split(".")[1])
).email;
- } catch (e) {
+ } catch {
email = "Email parsing failed";
}
- updateGlobals({ accessToken: tokenString });
- setState({ loading: false, email });
+ setState({ loading: false, email, accessToken: tokenString });
+ channel.emit(ACCESS_TOKEN_EVENT, tokenString);
});
}
const context = new ClientRequestContext();
- if (!globals.accessToken) {
+ if (!state.accessToken) {
await client.current.signInPopup(context);
} else {
await client.current.signOutPopup(context).catch(() => {
// Intentionally a noop, user closing the window is not an issue.
});
}
- } catch (e) {
+ } catch {
setState({ loading: false });
}
};
@@ -102,36 +108,31 @@ addons.register("auth/toolbar", () => {
{clientIdMissing
? `No client Id configured: clientId must be provided in 'authClientConfig' parameter in preview.js`
: buildMissing
- ? `${redirectURI} not found: "storybook-auth-addon" is likely not built, run "rush build"`
- : state.loading
- ? "Authenticating..."
- : globals.accessToken
- ? `Authenticated: ${state.email}, click to sign off`
- : `Authenticate`}
+ ? `${redirectURI} not found: "storybook-auth-addon" is likely not built, run "rush build"`
+ : state.loading
+ ? "Authenticating..."
+ : state.accessToken
+ ? `Authenticated: ${state.email}, click to sign off`
+ : `Authenticate`}
);
}}
>
authenticate()}
>
{buildMissing || clientIdMissing ? (
-
+
) : state.loading ? (
-
+ ...
+ ) : state.accessToken ? (
+
) : (
-
+
)}
diff --git a/packages/modules/storybook-auth-addon/package.json b/packages/modules/storybook-auth-addon/package.json
index 7a9c87ea..b370c1b6 100644
--- a/packages/modules/storybook-auth-addon/package.json
+++ b/packages/modules/storybook-auth-addon/package.json
@@ -4,9 +4,8 @@
"private": true,
"homepage": ".",
"dependencies": {
- "@storybook/addons": "^6.5.16",
- "@storybook/api": "^6.5.16",
- "@storybook/components": "^6.5.16"
+ "@storybook/icons": "^2.0.2",
+ "storybook": "^10.4.0"
},
"devDependencies": {
"@bentley/bentleyjs-core": "2.11.0",
diff --git a/packages/modules/storybook-auth-addon/preset.js b/packages/modules/storybook-auth-addon/preset.js
new file mode 100644
index 00000000..68ef12e3
--- /dev/null
+++ b/packages/modules/storybook-auth-addon/preset.js
@@ -0,0 +1,3 @@
+module.exports = {
+ managerEntries: [require.resolve("./manager.jsx")],
+};