@itwin/quantity-formatting-react
v0.1.3
Published
React components and utilities for quantity formatting
Downloads
480
Readme
@itwin/quantity-formatting-react
React components for quantity formatting in iTwin.js applications.
Description
This package provides React components for working with quantities and their formatting in iTwin.js applications. It includes components for configuring, displaying, and converting quantities with proper unit handling and formatting options.
Key Features:
- Comprehensive Format Configuration: Support for Decimal, Fractional, Scientific, Station, Azimuth, Bearing, and Ratio formats
- Real-time Preview: Live formatting preview as you adjust settings
- Unit Management: Support for composite units and unit conversion
- Flexible UI Components: Modular components that can be embedded in dialogs, panels, or custom UIs
- Format Selection: Choose from predefined formats to customize
Installation
npm install @itwin/quantity-formatting-reactCommon Worfklow
The typical workflow involves selecting a format and customizing it to meet your needs:
- Select a Format: Use the
FormatSelectorto choose from available predefined formats - Customize Settings: Modify format properties like precision, units, and display options
- Preview Changes: See real-time formatting preview as you make adjustments
- Save or Reset: Apply your changes or revert to the original format
Example Workflow
FormatSelector and QuantityFormatPanel are separate components, that can be used together. The following example's code can be found in this repository's QuantityFormatButton.tsx
Editing a Format
Starting with the FormatSelector, this component shows all available formats to choose from. It also includes a search bar, allowing you to filter formats based on their labels:
After selecting a format from the FormatSelector, the QuantityFormatPanel appears. Initially, the Save and Clear buttons are disabled when no changes have been made.
You can then customize the format by changing properties like the unit. For example, changing from feet to meters:
After making changes, notice how the Save and Clear buttons become enabled (highlighted), indicating that modifications can now be applied or discarded. The preview panel also now shows the value converted to meters:
Click Save to apply your changes or Clear to reset back to the original format settings.
Editing a Format Set
This is for applications that enable users to edit a format set. This is opt in. Otherwise, the input fields will be greyed out and disabled.
We start off by showing a FormatSetSelector, and in this example, the currently active format set is initially selected. The FormatSetPanel, shown on the right, shows a label, unit system, and description. While a format set, contains a name that can uniquely identify the set, it is omitted from the component, opting to show the label only.
A format set might not capture all the formatting options used in an iTwin application. When this happens, a format set can rely on it's unit system to tell the application to show formatting in that unit system. There's a dropdown selector to configure which unit system a format set uses, which an application can use.
After making changes, notice how the Apply and Clear buttons become enabled (highlighted), indicating that modifications can now be applied or discarded.
Components
This package provides six main React components for quantity formatting:
- QuantityFormatPanel: Complete formatting configuration with live preview
- FormatPanel: Flexible format property editor
- FormatSample: Real-time formatting preview component
- FormatSelector: Component for selecting from predefined formats within a format set
- FormatSetSelector: Component for selecting from multiple format sets
- FormatSetPanel: Component for viewing and editing format set properties
QuantityFormatPanel
The main component for configuring quantity formatting. It provides a complete user interface for setting up format properties and includes a live formatting preview.
QuantityFormatPanel Properties
interface QuantityFormatPanelProps {
formatDefinition: FormatDefinition; // Current format configuration
unitsProvider: UnitsProvider; // Provider for unit definitions
onFormatChange: (formatProps: FormatDefinition) => void; // Callback when format changes
initialMagnitude?: number; // Initial value for sample preview (default: 0)
showSample?: boolean; // Whether to show the format sample (default: true)
}QuantityFormatPanel Usage
import { QuantityFormatPanel } from "@itwin/quantity-formatting-react";
import { IModelApp } from "@itwin/core-frontend";
import type { FormatDefinition } from "@itwin/core-quantity";
const formatDefinition: FormatDefinition = {
precision: 4,
type: "Decimal",
composite: {
units: [{ name: "Units.M", label: "m" }],
},
};
const handleFormatChange = (_newFormat: FormatDefinition) => {
// Handle format change
};
render(
<QuantityFormatPanel
formatDefinition={formatDefinition}
unitsProvider={IModelApp.quantityFormatter.unitsProvider}
onFormatChange={handleFormatChange}
initialMagnitude={123.456}
/>,
);FormatPanel
A flexible component for editing format properties with customizable primary and secondary sections. This component provides more granular control than QuantityFormatPanel.
FormatPanel Properties
interface FormatPanelProps {
formatDefinition: FormatDefinition; // Current format configuration
unitsProvider: UnitsProvider; // Provider for unit definitions
onFormatChange: (formatProps: FormatDefinition) => void; // Callback when format changes
persistenceUnit?: UnitProps; // Unit for persistence/storage
}FormatPanel Usage
import React, { useState } from "react";
import { FormatPanel } from "@itwin/quantity-formatting-react";
import { IModelApp } from "@itwin/core-frontend";
import type { FormatDefinition } from "@itwin/core-quantity";
function CustomFormatEditor() {
const [format, setFormat] = useState<FormatDefinition>({
precision: 2,
type: "Decimal",
formatTraits: ["showUnitLabel"],
composite: {
units: [{ name: "Units.FT", label: "ft" }],
},
});
const persistenceUnit = await IModelApp.quantityFormatter.unitsProvider.findUnit("Units.M");
return (
<div style={{ padding: "16px" }}>
<h3>Custom Format Editor</h3>
<FormatPanel
formatDefinition={format}
unitsProvider={IModelApp.quantityFormatter.unitsProvider}
onFormatChange={setFormat}
persistenceUnit={persistenceUnit}
/>
<div style={{ marginTop: "16px" }}>
<h4>Current Format Configuration:</h4>
<pre>{JSON.stringify(format, null, 2)}</pre>
</div>
</div>
);
}FormatSample
A component that provides real-time preview of how values will be formatted using the current format configuration. Shows both the input value and the formatted output.
FormatSample Properties
interface FormatSampleProps {
formatProps: FormatDefinition; // Format configuration to preview
unitsProvider: UnitsProvider; // Provider for unit definitions
persistenceUnit?: UnitProps; // Unit for the input value
initialMagnitude?: number; // Initial value to display (default: 0)
}FormatSample Usage
import React, { useState } from "react";
import { FormatSample } from "@itwin/quantity-formatting-react";
import { IModelApp } from "@itwin/core-frontend";
import type { FormatDefinition } from "@itwin/core-quantity";
function FormatPreview() {
const [format] = useState<FormatDefinition>({
precision: 3,
type: "Decimal",
formatTraits: ["showUnitLabel"],
composite: {
units: [{ name: "Units.M", label: "m" }],
},
});
return (
<div style={{ padding: "16px" }}>
<h3>Format Preview</h3>
<FormatSample formatProps={format} unitsProvider={IModelApp.quantityFormatter.unitsProvider} initialMagnitude={123.456789} />
</div>
);
}FormatSelector
A component for selecting from predefined format definitions within a format set.
FormatSelector Properties
interface FormatSelectorProps {
activeFormatSet?: FormatSet; // Set of available formats
activeFormatDefinitionKey?: string; // Currently selected format key
onListItemChange: (formatDefinition: FormatDefinition, key: string) => void; // Selection callback
}FormatSelector Usage
import { FormatSelector } from "@itwin/quantity-formatting-react";
import type { FormatDefinition } from "@itwin/core-quantity";
import type { FormatSet } from "@itwin/ecschema-metadata";
const formatSet: FormatSet = {
name: "TestSet",
label: "Test Format Set",
unitSystem: "metric",
formats: {
"test-format": {
name: "test-format",
label: "Test Format",
type: "Decimal",
precision: 2,
composite: { units: [{ name: "Units.M", label: "m" }] },
},
},
} as FormatSet;
const handleFormatSelection = (_formatDef: FormatDefinition, _key: string) => {
// Handle format selection
};
render(<FormatSelector activeFormatSet={formatSet} activeFormatDefinitionKey={undefined} onListItemChange={handleFormatSelection} />);FormatSetSelector
A component for selecting from multiple format sets. This is useful when you have multiple predefined collections of formats (e.g., different format sets for different projects or disciplines).
FormatSetSelector Properties
interface FormatSetSelectorProps {
formatSets: FormatSet[]; // Array of available format sets
selectedFormatSetKey?: string; // Key of currently selected format set in the UI
activeFormatSetKey?: string; // Key of currently active/applied format set (shows badge)
onFormatSetChange: (formatSet: FormatSet, key: string) => void; // Selection callback
}FormatSetSelector Usage
import { FormatSetSelector } from "@itwin/quantity-formatting-react";
import type { FormatSet } from "@itwin/ecschema-metadata";
const formatSets: FormatSet[] = [
{
name: "MetricSet",
label: "Metric Formats",
unitSystem: "metric",
description: "Standard metric unit formats",
formats: {},
} as FormatSet,
{
name: "ImperialSet",
label: "Imperial Formats",
unitSystem: "imperial",
description: "Imperial unit formats",
formats: {},
} as FormatSet,
];
const handleFormatSetChange = (_formatSet: FormatSet, _key: string) => {
// Handle format set change
};
render(
<FormatSetSelector formatSets={formatSets} selectedFormatSetKey="MetricSet" activeFormatSetKey="ImperialSet" onFormatSetChange={handleFormatSetChange} />,
);FormatSetPanel
A component for viewing and editing format set properties such as label, unit system, and description. This component can be used in both read-only and editable modes.
FormatSetPanel Properties
type FormatSetPanelProps = {
formatSet: FormatSet; // Format set to display/edit (required)
} & (
| {
editable: true; // Edit mode enabled
onFormatSetChange: (formatSet: FormatSet) => void; // Required when editable
}
| {
editable?: false; // Read-only mode (default)
onFormatSetChange?: undefined; // Not used in read-only mode
}
);FormatSetPanel Usage
Editable Mode:
import { FormatSetPanel } from "@itwin/quantity-formatting-react";
import type { FormatSet } from "@itwin/ecschema-metadata";
const formatSet: FormatSet = {
name: "CustomSet",
label: "Custom Format Set",
unitSystem: "metric",
description: "A custom format set",
formats: {},
} as FormatSet;
const handleFormatSetChange = (_updatedFormatSet: FormatSet) => {
// Handle format set change
};
render(<FormatSetPanel formatSet={formatSet} editable={true} onFormatSetChange={handleFormatSetChange} />);Read-only Mode:
import { FormatSetPanel } from "@itwin/quantity-formatting-react";
import type { FormatSet } from "@itwin/ecschema-metadata";
const formatSet: FormatSet = {
name: "ReadOnlySet",
label: "Read-Only Format Set",
unitSystem: "imperial",
description: "A read-only format set",
formats: {},
} as FormatSet;
render(<FormatSetPanel formatSet={formatSet} editable={false} />);Complete Example
A comprehensive example showing how to use FormatSelector together with QuantityFormatPanel can be found in this repository's test-viewer, found in QuantityFormatButton.tsx. The common workflow in the section above walks through the component in pictures.
Initialization
Before using the components, initialize the localization support:
import { QuantityFormatting } from "@itwin/quantity-formatting-react";
import { IModelApp } from "@itwin/core-frontend";
// Initialize during application startup
await QuantityFormatting.startup({
localization: IModelApp.localization, // Optional: use custom localization
});License
This project is licensed under the MIT License - see the LICENSE.md file for details.
