Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/imodel-browser-react",
"comment": "Controlled table sorting for iTwin/iModel tables",
Comment thread
arome marked this conversation as resolved.
Outdated
"type": "minor"
}
],
"packageName": "@itwin/imodel-browser-react"
}
50 changes: 25 additions & 25 deletions packages/apps/storybook/.storybook/itwinTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ export const lightTheme = create({
base: "light",
brandTitle: "iTwin Admin Components",

colorPrimary: '#0071B8', // --iui-color-background-accent
colorSecondary: '#0071B8', // --iui-color-background-accent
colorPrimary: "#0071B8", // --iui-color-background-accent
colorSecondary: "#0071B8", // --iui-color-background-accent

// UI
appBg: '#FFFFFF', // --iui-color-background
appContentBg: '#FFFFFF', // --iui-color-background
appBorderColor: '#b3bcc1', // --iui-color-border
appBg: "#FFFFFF", // --iui-color-background
appContentBg: "#FFFFFF", // --iui-color-background
appBorderColor: "#b3bcc1", // --iui-color-border
appBorderRadius: 9,

// Typography
Expand All @@ -24,31 +24,31 @@ export const lightTheme = create({
'"Noto Sans Mono", ui-monospace, "SF Mono", SFMono-Regular, "DejaVu Sans Mono", Menlo, Consolas, monospace',

// Text colors
textColor: '#242424', //--iui-color-text
textColor: "#242424", //--iui-color-text

// Toolbar default and active colors
barTextColor: '#242424', //--iui-color-text
barSelectedColor: '#0071B8', // --iui-color-background-accent
barBg: '#FFFFFF', // --iui-color-background
barTextColor: "#242424", //--iui-color-text
barSelectedColor: "#0071B8", // --iui-color-background-accent
barBg: "#FFFFFF", // --iui-color-background

// Form colors
inputBg: '#FFFFFF', // --iui-color-background
inputBorder: '#b3bcc1', // --iui-color-border
inputTextColor: '#242424', //--iui-color-text
inputBg: "#FFFFFF", // --iui-color-background
inputBorder: "#b3bcc1", // --iui-color-border
inputTextColor: "#242424", //--iui-color-text
inputBorderRadius: 3,
});

export const darkTheme = create({
base: "dark",
brandTitle: "iTwin Admin Components",

colorPrimary: '#0071B8', // --iui-color-background-accent
colorSecondary: '#94befa', // --iui-color-text-accent
colorPrimary: "#0071B8", // --iui-color-background-accent
colorSecondary: "#94befa", // --iui-color-text-accent

// UI
appBg: '#333c41', // --iui-color-background
appContentBg: '#333c41', // --iui-color-background
appBorderColor: '#49555d', // --iui-color-border
appBg: "#333c41", // --iui-color-background
appContentBg: "#333c41", // --iui-color-background
appBorderColor: "#49555d", // --iui-color-border
appBorderRadius: 9,

// Typography
Expand All @@ -58,16 +58,16 @@ export const darkTheme = create({
'"Noto Sans Mono", ui-monospace, "SF Mono", SFMono-Regular, "DejaVu Sans Mono", Menlo, Consolas, monospace',

// Text colors
textColor: '#dbdbdb', //--iui-color-text
textColor: "#dbdbdb", //--iui-color-text

// Toolbar default and active colors
barTextColor: '#dbdbdb', //--iui-color-text
barSelectedColor: '#94befa', // --iui-color-text-accent
barBg: '#333c41', // --iui-color-background
barTextColor: "#dbdbdb", //--iui-color-text
barSelectedColor: "#94befa", // --iui-color-text-accent
barBg: "#333c41", // --iui-color-background

// Form colors
inputBg: '#333c41', // --iui-color-background
inputBorder: '#49555d', // --iui-color-border
inputTextColor: '#dbdbdb', //--iui-color-text
inputBorderRadius: 3
inputBg: "#333c41", // --iui-color-background
inputBorder: "#49555d", // --iui-color-border
inputTextColor: "#dbdbdb", //--iui-color-text
inputBorderRadius: 3,
});
4 changes: 4 additions & 0 deletions packages/apps/storybook/src/addon/preset.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
module.exports = {
managerEntries: [require.resolve("./manager.jsx")],
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { LabeledInput, LabeledSelect } from "@itwin/itwinui-react";
import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";

import { iTwinAndAccessTokenArgTypes } from "../utils/storyHelp";

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { UpdateIModel } from "@itwin/create-imodel-react";
import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React from "react";

import { accessTokenArgTypes } from "../utils/storyHelp";

function base64ToArrayBuffer(base64: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DeleteIModel, DeleteIModelProps } from "@itwin/delete-imodel-react";
import { Button } from "@itwin/itwinui-react";
import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React, { useState } from "react";

import { accessTokenArgTypes } from "../utils/storyHelp";

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DeleteITwin, DeleteITwinProps } from "@itwin/delete-itwin-react";
import { Button } from "@itwin/itwinui-react";
import type { Meta, StoryObj } from "@storybook/react-webpack5";
import React, { useState } from "react";

import { accessTokenArgTypes } from "../utils/storyHelp";

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import type { Meta, StoryObj } from "@storybook/react-webpack5";

import { accessTokenArgTypes } from "../utils/storyHelp";
import { Authentiated } from "./Authenticated";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/

import type { Meta, StoryObj } from "@storybook/react-webpack5";

import { ITwinAwareComponent } from "./ITwinAwareComponent";

export default {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ 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/actions";
import type { Meta, StoryObj } from "@storybook/react-webpack5";
import svgGeo from "@stratakit/icons/geospatial-features.svg";
import svgPin from "@stratakit/icons/pin.svg";
Expand All @@ -16,6 +15,7 @@ import svgStatusError from "@stratakit/icons/status-error.svg";
import svgStatusSuccess from "@stratakit/icons/status-success.svg";
import svgStatusWarning from "@stratakit/icons/status-warning.svg";
import React from "react";
import { action } from "storybook/actions";

import {
BaseCard,
Expand Down Expand Up @@ -255,7 +255,11 @@ export const OpenSitePlus: StoryObj<typeof BaseCardStory> = {
icon: svgGeo,
},
{ key: "share", label: "Share", onClick: action("menu: share clicked") },
{ key: "delete", label: "Delete", onClick: action("menu: delete clicked") },
{
key: "delete",
label: "Delete",
onClick: action("menu: delete clicked"),
},
],
actions: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import {
type IModelFull,
type IModelGridProps as IModelGridMUIProps,
type IModelTableSortModel,
DataStatus,
IModelCellColumn,
IModelGrid as ExternalComponent,
IModelSortOptions,
} from "@itwin/imodel-browser-react/mui";
import Avatar from "@mui/material/Avatar";
import AvatarGroup from "@mui/material/AvatarGroup";
Expand Down Expand Up @@ -153,6 +155,88 @@ export const TableViewWithOverrides: StoryObj<typeof IModelGridMUI> = {
},
};

const TableWithControlledSortRender = (args: IModelGridMUIProps) => {
const [sortModel, setSortModel] = React.useState<IModelSortOptions>({
sortType: "name",
descending: true,
});

return (
<div>
<div
style={{
display: "flex",
gap: 8,
marginBottom: 8,
alignItems: "center",
}}
>
<Typography variant="body2">Sort by:</Typography>
<Chip
label="Name"
clickable
variant={sortModel.sortType === "name" ? "filled" : "outlined"}
onClick={() =>
setSortModel((prev) => ({ ...prev, sortType: "name" }))
}
/>
<Chip
label="Last Modified"
clickable
variant={
sortModel.sortType === "lastChangesetPushDateTime"
? "filled"
: "outlined"
}
onClick={() =>
setSortModel((prev) => ({
...prev,
sortType: "lastChangesetPushDateTime",
}))
}
/>
<Chip
label={sortModel.descending ? "↓ Descending" : "↑ Ascending"}
clickable
variant="outlined"
onClick={() =>
setSortModel((prev) => ({
...prev,
descending: !prev.descending,
}))
}
/>
</div>
<ExternalComponent
{...args}
sortOptions={sortModel}
onSortModelChange={(newSortModel: IModelTableSortModel) => {
if (newSortModel.length > 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this should have an action to match iTwin Grid - I also didn't see anything firing when I tried it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the action as suggested, the action fires when you click on the table column headers. The idea is to be able to sync the table sorting with external sorting used in the app.

const newSort = newSortModel[0];
setSortModel({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to call setSortModel here when it's already being called in the click handlers? Same for iTwinGrid.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as described in my other comment, the click handlers (chips at the top of the table) are not part of the iModelGridMUI, theyre just there in the story to simulate sorting done outside of the iModelGrid (similar to the sorting dropdown available in studio). So an app using iModelGrid should sync its sorting logic when the sort is changed using the table header sorting.

sortType: newSort.field,
descending: newSort.sort === "desc",
});
}
}}
/>
</div>
);
};

export const TableWithControlledSort: StoryObj<typeof IModelGridMUI> = {
Comment thread
arome marked this conversation as resolved.
render: (args) => <TableWithControlledSortRender {...args} />,
args: { ...baseArgs },
parameters: {
docs: {
description: {
story:
"The sort state is fully controlled by the parent via `sortModel` and `onSortModelChange`, so it can be saved anywhere the consumer wants.",
},
},
},
};

const OverrideApiDataWithLoadMoreRender = (args: IModelGridMUIProps) => {
const [data, setData] = React.useState<IModelFull[]>(initialData);
const [isLoading, setIsLoading] = React.useState(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ 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/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";
import React from "react";
import { action } from "storybook/actions";

import bridgeThumbnail from "../../utils/bridge.jpg";
import overpassThumbnail from "../../utils/overpass.jpg";
Expand Down
Loading
Loading