Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/test-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@
"@itwin/reality-data-client": "^1.4.0",
"@itwin/service-authorization": "^2.1.1",
"@itwin/webgl-compatibility": "catalog:",
"@stratakit/bricks": "catalog:",
"@mui/material": "catalog:",
"@stratakit/foundations": "catalog:",
"@stratakit/icons": "catalog:",
"@stratakit/mui": "catalog:",
"@tanstack/react-router": "^1.168.19",
"classnames": "2.5.1",
"react": "catalog:",
Expand Down
4 changes: 1 addition & 3 deletions apps/test-app/src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
SideNavigation,
ThemeProvider,
} from "@itwin/itwinui-react";
import { Root } from "@stratakit/foundations";
import { Root } from "@stratakit/mui";
import {
createRootRouteWithContext,
Outlet,
Expand Down Expand Up @@ -176,8 +176,6 @@ function ThemeBridge({ children }: React.PropsWithChildren) {
return (
<Root
colorScheme={prefersDark ? "dark" : "light"}
density="dense"
synchronizeColorScheme
render={(props: any) => (
<ThemeProvider future={{ themeBridge, applyBackground }} {...props} />
)}
Expand Down
3 changes: 2 additions & 1 deletion apps/test-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"lib": ["dom", "dom.iterable", "esnext"]
"lib": ["dom", "dom.iterable", "esnext"],
"types": ["@stratakit/mui/types.d.ts"]
},
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["./src/backend/**/*.ts"]
Expand Down
8 changes: 8 additions & 0 deletions apps/test-app/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ export default defineConfig(({ mode }) => {
return {
build: {
chunkSizeWarningLimit: 7000,
assetsInlineLimit: (filePath) => {
if (
filePath.includes("node_modules/@stratakit/icons") &&
filePath.endsWith(".svg")
) {
return false;
}
},
Comment thread
GerardasB marked this conversation as resolved.
},
customLogger,
plugins: [
Expand Down
21 changes: 21 additions & 0 deletions docs/storybook/.storybook/addons/theme-bridge/StrataKitIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from "react";
import { SvgPlaceholder } from "@itwin/itwinui-icons-react";
import { Icon } from "@stratakit/mui";
import { ThemeBridgeContext } from "./ThemeBridge";

interface StrataKitIconProps {
href: string;
}

export function StrataKitIcon(props: StrataKitIconProps) {
const themeBridge = React.useContext(ThemeBridgeContext);
if (!themeBridge) {
return <SvgPlaceholder />;
}

return <Icon href={props.href} />;
}
42 changes: 42 additions & 0 deletions docs/storybook/.storybook/addons/theme-bridge/ThemeBridge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from "react";
import { ThemeProvider } from "@itwin/itwinui-react";
import type { Decorator } from "@storybook/react-vite";
import { ThemeBridgeRoot } from "./ThemeBridgeRoot";

export const withThemeBridge: Decorator = (Story, context) => {
const themeBridge = !!context.globals.themeBridge;

if (themeBridge) {
return (
<ThemeBridgeRoot>
<Story />
</ThemeBridgeRoot>
);
}

return (
<ThemeProvider>
<></>
<Story />
</ThemeProvider>
);
Comment thread
GerardasB marked this conversation as resolved.
};

export const themeBridgeGlobalType = {
description: "iTwinUI v5 theme bridge",
defaultValue: undefined,
toolbar: {
title: "Theme bridge",
icon: "paintbrush",
items: [
{ title: "Enable", value: "true" },
{ title: "Disable", type: "reset" },
],
},
};

export const ThemeBridgeContext = React.createContext(false);
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,32 @@
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import React from "react";
import type { Decorator } from "@storybook/react-vite";
import * as React from "react";
import { ThemeProvider } from "@itwin/itwinui-react";
import { Root } from "@stratakit/foundations";
import { Root } from "@stratakit/mui";
import { ThemeBridgeContext } from "./ThemeBridge";

export const withThemeBridge: Decorator = (Story, context) => {
const themeBridge = !!context.globals.themeBridge;
type ThemeProviderProps = React.ComponentProps<typeof ThemeProvider>;

export function ThemeBridgeRoot(props: React.PropsWithChildren) {
const prefersDark = useMediaQuery("(prefers-color-scheme: dark)");

if (themeBridge) {
return (
return (
<ThemeBridgeContext value={true}>
<Root
colorScheme={prefersDark ? "dark" : "light"}
density="dense"
synchronizeColorScheme
render={(props: any) => (
<ThemeProvider future={{ themeBridge }} {...props} />
render={(props: unknown) => (
<ThemeProvider
future={{ themeBridge: true }}
{...(props as ThemeProviderProps)}
/>
)}
>
<Story />
{props.children}
</Root>
);
}

return (
<ThemeProvider>
<Story />
</ThemeProvider>
</ThemeBridgeContext>
);
};
}

function useMediaQuery(query: string) {
const getClientSnapshot = React.useCallback(() => {
Expand All @@ -49,16 +45,3 @@ function useMediaQuery(query: string) {

return React.useSyncExternalStore(subscribe, getClientSnapshot);
}

export const themeBridgeGlobalType = {
description: "iTwinUI v5 theme bridge",
defaultValue: undefined,
toolbar: {
title: "Theme bridge",
icon: "paintbrush",
items: [
{ title: "Enable", value: "true" },
{ title: "Disable", type: "reset" },
],
},
};
8 changes: 8 additions & 0 deletions docs/storybook/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ const config: StorybookConfig = {
config.build.chunkSizeWarningLimit = 5000;
// This prevents component name mangling in stories.
config.build.minify = false;
config.build.assetsInlineLimit = (filePath) => {
if (
filePath.includes("node_modules/@stratakit/icons") &&
filePath.endsWith(".svg")
) {
return false;
}
};
Comment thread
GerardasB marked this conversation as resolved.
return config;
},
};
Expand Down
5 changes: 4 additions & 1 deletion docs/storybook/.storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import type { Preview } from "@storybook/react-vite";
import { withDemoIModel, demoIModelGlobalType } from "./addons/DemoIModel";
import { resizerGlobalType } from "./addons/Resizer";
import { themeBridgeGlobalType, withThemeBridge } from "./addons/ThemeBridge";
import {
themeBridgeGlobalType,
withThemeBridge,
} from "./addons/theme-bridge/ThemeBridge";

const preview: Preview = {
parameters: {
Expand Down
3 changes: 2 additions & 1 deletion docs/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@
"@itwin/imodels-client-authoring": "^6.1.0",
"@itwin/itwinui-icons-react": "^2.11.0",
"@itwin/itwinui-react": "catalog:",
"@stratakit/bricks": "catalog:",
"@mui/material": "catalog:",
"@stratakit/foundations": "catalog:",
"@stratakit/icons": "catalog:",
"@stratakit/mui": "catalog:",
"react": "catalog:",
"react-dom": "catalog:",
"react-redux": "^9.2.0"
Expand Down
55 changes: 14 additions & 41 deletions docs/storybook/src/widget/Widget.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite";
import { WidgetState } from "@itwin/appui-react";
import { BadgeType } from "@itwin/core-react";
import { SvgPlaceholder } from "@itwin/itwinui-icons-react";
import { Icon as SKIcon } from "@stratakit/foundations";
import { StrataKitIcon } from "../../.storybook/addons/theme-bridge/StrataKitIcon";
import { AppUiDecorator } from "../Decorators";
import { Page } from "../AppUiStory";
import { WidgetStory } from "./Widget";
Expand All @@ -25,6 +25,7 @@ const meta = {
},
args: {
widgets: [{}, {}],
widgetTabActions: false,
},
} satisfies Meta<typeof WidgetStory>;

Expand Down Expand Up @@ -55,48 +56,20 @@ export const Badge: Story = {
},
};

export const Icon: Story = {
name: "Icon (iTwinUI)",
args: {
widgets: [{ iconNode: <SvgPlaceholder /> }, {}, {}, {}, {}],
},
};

export const IconStrataKit: Story = {
name: "Icon (StrataKit)",
export const Icons: Story = {
args: {
widgets: [
{ iconNode: <SKIcon href={placeholderIcon} /> },
{ iconNode: <SKIcon href={placeholderIcon} /> },
{ iconNode: <SKIcon href={placeholderIcon} /> },
{ iconNode: <SKIcon href={placeholderIcon} /> },
{ iconNode: <SKIcon href={placeholderIcon} /> },
],
},
};

export const CSSIcon: Story = {
args: {
widgets: [
{ iconNode: <i className="icon icon-placeholder" /> },
{},
{},
{},
{},
{ iconNode: <SvgPlaceholder />, label: "iTwinUI icon" },
{
iconNode: <StrataKitIcon href={placeholderIcon} />,
label: "StrataKit icon",
},
{ icon: <SvgPlaceholder />, label: "iTwinUI icon spec (deprecated)" },
{ icon: "icon-placeholder", label: "Font icon spec (deprecated)" },
{
iconNode: <i className="icon icon-placeholder" />,
label: "Font icon (deprecated)",
},
],
},
};

export const IconSpec: Story = {
name: "Icon Spec (deprecated)",
args: {
widgets: [{ icon: "icon-placeholder" }, {}, {}, {}, {}],
},
};

export const IconSpecNode: Story = {
name: "Icon Spec Node (deprecated)",
args: {
widgets: [{ icon: <SvgPlaceholder /> }, {}, {}, {}, {}],
},
};
41 changes: 27 additions & 14 deletions docs/storybook/src/widget/Widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import React from "react";
import {
PreviewFeatures,
PreviewFeaturesProvider,
StagePanelState,
UiItemsProvider,
Widget,
} from "@itwin/appui-react";
import { action } from "storybook/actions";
import { StagePanelState, UiItemsProvider, Widget } from "@itwin/appui-react";
import { AppUiStory } from "../AppUiStory";
import { createFrontstage, createWidget } from "../Utils";

Expand Down Expand Up @@ -34,25 +40,32 @@ function createProvider(widgets: WidgetStoryProps["widgets"]): UiItemsProvider {
};
}

interface WidgetStoryProps {
interface WidgetStoryProps
extends Pick<Required<PreviewFeatures>, "widgetTabActions"> {
widgets: Partial<Widget>[];
}

/** [Widget](https://www.itwinjs.org/reference/appui-react/widget/widget) interface allows you to configure the widget. */
export function WidgetStory(props: WidgetStoryProps) {
const provider = createProvider(props.widgets);
return (
<AppUiStory
frontstages={[
createFrontstage({
leftPanelProps: {
defaultState: StagePanelState.Open,
pinned: true,
},
}),
]}
itemProviders={[provider]}
{...props}
/>
<PreviewFeaturesProvider
features={{
widgetTabActions: props.widgetTabActions,
}}
>
<AppUiStory
frontstages={[
createFrontstage({
leftPanelProps: {
defaultState: StagePanelState.Open,
pinned: true,
},
}),
]}
itemProviders={[provider]}
{...props}
/>
</PreviewFeaturesProvider>
);
}
7 changes: 2 additions & 5 deletions docs/storybook/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,

/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
Expand All @@ -24,12 +22,11 @@
"./node_modules/@itwin/imodel-components-react/*"
]
},

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
"noFallthroughCasesInSwitch": true,
"types": ["@stratakit/mui/types.d.ts"]
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
Expand Down
Loading
Loading