|
| 1 | + |
| 2 | +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; |
| 3 | + |
| 4 | +<Meta title="1 Welcome / Migration Guide" /> |
| 5 | + |
| 6 | +# Migration Guide |
| 7 | + |
| 8 | +## Migrating from 0.8.X to 0.9.0 |
| 9 | +Migrating your app from 0.8.X to 0.9.0 requires a few updates to the API properties, this includes dependencies, theming, event handling and prop changes. |
| 10 | + |
| 11 | +### Breaking changes |
| 12 | +For a complete list of breaking changes from 0.8.X to 0.9.0, please refer to [the list of releases](https://github.com/SAP/ui5-webcomponents-react/releases) or the [changelog](https://github.com/SAP/ui5-webcomponents-react/blob/master/CHANGELOG.md). |
| 13 | +Most important breaking changes: |
| 14 | +- configuring of compact size is removed, use the ui5-content-density-compact CSS class to apply compact size. |
| 15 | +- `@ui5/webcomponents`, `@ui5/webcomponents-icons` and `@ui5/webcomponents-fiori` are now `peerDependencies` |
| 16 | +- **Replaced Components with potential new API** |
| 17 | + - Avatar |
| 18 | + - Carousel |
| 19 | + - SegmentedButton |
| 20 | + - Toast (replaces MessageToast) |
| 21 | +- **ThemeProvider**: |
| 22 | + - does not longer render a `JSSProvider` and the `jss`-prop is removed. If you need a custom JSS setup, please render your own JSSProvider. |
| 23 | + - remove prop `withToastContainer` |
| 24 | +- **AnalyticalTable**: |
| 25 | + - replace `noSelectionColumn` prop with `selectionBehavior` enum |
| 26 | + - column option `groupable` replaced by `disableGroupBy`: boolean |
| 27 | + - column option `sortable` replaced by `disableSortBy`: boolean |
| 28 | + - column option `filterable` replaced by `disableFilters`: boolean |
| 29 | + - Enabling grouping, sorting or filtering on column level by e.g disableGroupBy: false will not overwrite the table overall setting in case e.g. groupable={false} |
| 30 | +- **ButtonDesign**: RenameAccept to Positive |
| 31 | +- **ButtonDesign**: RenameReject to Negative |
| 32 | +- **InputType**: Rename Url to URL |
| 33 | +- **BusyIndicator** : change default size of busy dots to Medium |
| 34 | +- **MessageStrip** : replace icon property with icon slot to allow setting arbitrary content by the user |
| 35 | +- **MultiComboBox** : Does not longer accept StandardListItem as child, use MultiComboBoxItem instead |
| 36 | +- **ShellBar** : profile property is removed in favour of profile slot |
| 37 | +- **TabContainer** : onItemSelect event is renamed to onTabSelect and the item event parameter is renamed to tab. |
| 38 | +- **Card** : the property subtitle has been renamed to subheading |
| 39 | +- **TextArea** : the property maxLength has been renamed to maxlength |
| 40 | +- **Popover/Dialog** |
| 41 | + - Removed custom API for opening, please see details at [Opening Popovers](#opening-popovers) |
| 42 | +- **Deleted Components** |
| 43 | + - SegmentedButtonItem: replaced by ToggleButton |
| 44 | + |
| 45 | +## Dependencies |
| 46 | +The dependencies `@ui5/webcomponents`, `@ui5/webcomponents-fiori` and `@ui5/webcomponents-icons` are now `peerDependencies` and have to be installed next to `@ui5/webcomponents-react`. |
| 47 | + |
| 48 | +npm: |
| 49 | +```sh |
| 50 | +npm install @ui5/webcomponents --save |
| 51 | +npm install @ui5/webcomponents-fiori --save |
| 52 | +npm install @ui5/webcomponents-icons --save |
| 53 | +``` |
| 54 | +yarn: |
| 55 | +```sh |
| 56 | +yarn add @ui5/webcomponents |
| 57 | +yarn add @ui5/webcomponents-fiori |
| 58 | +yarn add @ui5/webcomponents-icons |
| 59 | +``` |
| 60 | + |
| 61 | +## Configure content density |
| 62 | +Configuration of compact size is removed. |
| 63 | +The default configuration is `Cozy`, to enable `Compact`, provide the `ui5-content-density-compact` CSS class to any of your HTML elements, and it applies compact size to all of its children. |
| 64 | + |
| 65 | +Add `ui5-content-density-compact` to your `<body>` element to apply compact setting to the whole app: |
| 66 | +```html |
| 67 | +<body class="ui5-content-density-compact"> |
| 68 | + <div> |
| 69 | + <ShellBar /> |
| 70 | + <Button /> |
| 71 | + </div> |
| 72 | +</body> |
| 73 | +``` |
| 74 | +Or just to a single container or component: |
| 75 | +```html |
| 76 | +<Button className="ui5-content-density-compact">Compact Button</Button> |
| 77 | +``` |
| 78 | + |
| 79 | +## Theming |
| 80 | +UI5 Web Components and UI5 Web Components for React are both coming with the `sap_fiori_3` a.k.a. `Quartz` Theme built in. |
| 81 | +In case you want to change your applications' theme, you have to import a couple of modules: |
| 82 | +```js |
| 83 | +import { setTheme } from '@ui5/webcomponents-base/dist/config/Theme'; |
| 84 | +import '@ui5/webcomponents-theme-base/dist/Assets'; |
| 85 | +import '@ui5/webcomponents/dist/generated/json-imports/Themes'; |
| 86 | +import '@ui5/webcomponents-fiori/dist/generated/json-imports/Themes'; // only if you are using the ShellBar, Product Switch or UploadCollection |
| 87 | +``` |
| 88 | + |
| 89 | +Now you can call `setTheme` with a string parameter of the new theme. |
| 90 | +Available Themes: |
| 91 | +- `sap_fiori_3` (default) |
| 92 | +- `sap_fiori_dark` |
| 93 | +- `sap_belize` |
| 94 | +- `sap_belize_hcb` |
| 95 | +- `sap_belize_hcw` |
| 96 | + |
| 97 | +Example for applying the `sap_fiori_3_dark` theme: |
| 98 | +```jsx |
| 99 | +setTheme(Themes.sap_fiori_3_dark); |
| 100 | + |
| 101 | +const App = () => { |
| 102 | + return ( |
| 103 | + <ThemeProvider> |
| 104 | + <ShellBar /> |
| 105 | + <Page showHeader={false}> |
| 106 | + <Text>Some Content</Text> |
| 107 | + </Page> |
| 108 | + </ThemeProvider> |
| 109 | + ); |
| 110 | +}; |
| 111 | +``` |
| 112 | + |
| 113 | +## Style custom components |
| 114 | +If you want to use our central styling approach with your custom components you can now use the `ThemingParameters`. |
| 115 | +With these parameters you get all available CSS Variables as a static import. As a consequence, you can now define your `react-jss` styles as a static object. |
| 116 | + |
| 117 | +```JSX |
| 118 | +import React from 'react'; |
| 119 | +import { createUseStyles } from 'react-jss'; |
| 120 | +import { ThemingParameters } from '@ui5/webcomponents-react-base/lib/ThemingParameters'; |
| 121 | + |
| 122 | +const styles = { |
| 123 | + container: { |
| 124 | + backgroundColor: ThemingParameters.sapBackgroundColor, |
| 125 | + fontFamily: ThemingParameters.sapFontFamily, |
| 126 | + height: '50px', |
| 127 | + display: 'flex', |
| 128 | + justifyContent: 'center', |
| 129 | + alignItems: 'center' |
| 130 | + } |
| 131 | +}; |
| 132 | + |
| 133 | +const useStyles = createUseStyles(styles); |
| 134 | + |
| 135 | +const MyCustomElement = () => { |
| 136 | + const classes = useStyles(); |
| 137 | + return ( |
| 138 | + <div className={classes.container}> |
| 139 | + <span style={{ color: ThemingParameters.sapNegativeColor, fontSize: ThemingParameters.sapFontLargeSize }}> |
| 140 | + My Text |
| 141 | + </span> |
| 142 | + </div> |
| 143 | + ); |
| 144 | +}; |
| 145 | +``` |
| 146 | + |
| 147 | +## Opening Popovers |
| 148 | +Our library used to provide a custom API on top of all UI5 Web Components Popovers/Dialogs. |
| 149 | +For the sake of consistency, we removed that extension and now handle popovers the same way as UI5 Web Components does. |
| 150 | +Popovers like the `Dialog`, `Popover` and `ResponsivePopover` now only can be opened by attaching a `ref` to the component |
| 151 | +and then call the corresponding `open` method: |
| 152 | + |
| 153 | +* Dialog - `.open()`: |
| 154 | + ```JSX |
| 155 | + const DialogComponent = () => { |
| 156 | + const dialogRef = useRef(); |
| 157 | + const onButtonClick = useCallback(() => { |
| 158 | + dialogRef.current.open(); |
| 159 | + }, [dialogRef]); |
| 160 | + |
| 161 | + return ( |
| 162 | + <> |
| 163 | + <Button onClick={onButtonClick}>Open Dialog</Button> |
| 164 | + <Dialog ref={dialogRef}>Some Content</Dialog> |
| 165 | + </> |
| 166 | + ); |
| 167 | + }; |
| 168 | + ``` |
| 169 | +* Popover - `.openBy(event.target)`: |
| 170 | + ```JSX |
| 171 | + const PopoverComponent = () => { |
| 172 | + const popoverRef = useRef(); |
| 173 | + const onButtonClick = useCallback( |
| 174 | + (e) => { |
| 175 | + popoverRef.current.openBy(e.target); |
| 176 | + }, |
| 177 | + [popoverRef] |
| 178 | + ); |
| 179 | + return ( |
| 180 | + <> |
| 181 | + <Button onClick={onButtonClick}>Open Popover</Button> |
| 182 | + <Popover ref={popoverRef}>Some Content</Popover> |
| 183 | + </> |
| 184 | + ); |
| 185 | + }; |
| 186 | + ``` |
| 187 | +* ResponsivePopover - `.open(event.target)`: |
| 188 | + ```JSX |
| 189 | + const ResponsivePopoverComponent = () => { |
| 190 | + const popoverRef = useRef(); |
| 191 | + const onButtonClick = useCallback( |
| 192 | + (e) => { |
| 193 | + popoverRef.current.open(e.target); |
| 194 | + }, |
| 195 | + [popoverRef] |
| 196 | + ); |
| 197 | + return ( |
| 198 | + <> |
| 199 | + <Button onClick={onButtonClick}>Open Responsive Popover</Button> |
| 200 | + <ResponsivePopover ref={popoverRef}>Some Content</ResponsivePopover> |
| 201 | + </> |
| 202 | + ); |
| 203 | + }; |
| 204 | + ``` |
| 205 | + |
| 206 | +## Event System |
| 207 | +The custom API for events is deprecated as it's incompatible with the UI5 Web Components API and will be removed in `0.10.0`. |
| 208 | + |
| 209 | +Now, all event handlers are called with an Object which is compatible with the `CustomEvent` API. |
| 210 | +Sometimes a UI5 Custom Event is passed, sometimes a React SyntheticEvent and all details are in the `detail` object. |
| 211 | + |
| 212 | +**The legacy event API is still supported but will be removed with `0.10.0`** |
| 213 | + |
| 214 | +Examples: |
| 215 | + |
| 216 | +* Access selected option in `Select` component: |
| 217 | + ```JSX |
| 218 | + export const SelectComponent = () => { |
| 219 | + const handleSelect = (event) => { |
| 220 | + const selectedOption = event.detail.selectedOption; //new |
| 221 | + const selectedOption = event.parameters.selectedOption; //deprecated |
| 222 | + }; |
| 223 | + return ( |
| 224 | + <Select onChange={handleSelect}> |
| 225 | + <Option>Option 1</Option> |
| 226 | + <Option>Option 2</Option> |
| 227 | + </Select> |
| 228 | + ); |
| 229 | + }; |
| 230 | + ``` |
| 231 | + |
| 232 | +* Get state of `CheckBox`: |
| 233 | + ```JSX |
| 234 | + export const CheckBoxComponent = () => { |
| 235 | + const handleChange = (event) => { |
| 236 | + const isChecked = event.target.checked; //new |
| 237 | + const isChecked = event.parameters.checked; //deprecated |
| 238 | + }; |
| 239 | + return <CheckBox onChange={handleChange} />; |
| 240 | + }; |
| 241 | + ``` |
| 242 | + |
| 243 | +## Replace render props with slots |
| 244 | +UI5 Web Components for React used to have `renderXYZ` props for adding custom content into components, e.g. `renderCustomHeader`. |
| 245 | +For providing a unified API, these props have been deprecated and corresponding slots have been added. |
| 246 | +Slots can be passed a `ReactNode` and depending on the case also a `ReactNodeArray`. |
| 247 | + |
| 248 | +**The `renderXYZ` props are still supported but will be removed with `0.10.0`** |
| 249 | + |
| 250 | + |
| 251 | +```JSX |
| 252 | +export const BarComponent = () => { |
| 253 | + return ( |
| 254 | + <Bar |
| 255 | + contentLeft={<Label>Content Left</Label>} //new |
| 256 | + contentMiddle={<Label>Content Middle</Label>} //new |
| 257 | + contentRight={<Label>Content Right</Label>} //new |
| 258 | + renderContentLeft={() => <Label>Content Left</Label>} //deprecated |
| 259 | + renderContentMiddle={() => <Label>Content Middle</Label>} //deprecated |
| 260 | + renderContentRight={() => <Label>Content Right</Label>} //deprecated |
| 261 | + /> |
| 262 | + ); |
| 263 | +}; |
| 264 | +``` |
| 265 | + |
| 266 | +## New components with different API |
| 267 | +Avatar: |
| 268 | +* props: |
| 269 | + * `onClick`: Has been removed. |
| 270 | + * `customDisplaySize` and `customFontSize`: Has been replaced by `size`. Uses `AvatarSize` enum. |
| 271 | + * `backgroundColor`: Defines the background color. Uses `AvatarBackgroundColor` enum. |
| 272 | + * `icon`: Defines the name of the UI5 Icon as string. _Remember that icons have to be imported first._ |
| 273 | + * `imageFitType`: Defines the fit type of the desired image. Uses `AvatarFitType` enum. |
| 274 | + |
| 275 | +Carousel: |
| 276 | +* props: |
| 277 | + * `onPageChanged`: Has been replaced by `onNavigate` |
| 278 | + * `width`: Has been removed. |
| 279 | + * `height`: Has been removed. |
| 280 | + * `showPageIndicator`: Has been removed. _To hide the navigation-bar use `hideNavigation`._ |
| 281 | + * `pageIndicatorPlacement`: Has been removed. |
| 282 | + * `loop`: Has been replaced by `cyclic`. |
| 283 | + * `activePage`: Has been replaced by `selectedIndex`. |
| 284 | + |
| 285 | +MessageToast: |
| 286 | +* Has been replaced by the `Toast` component. |
| 287 | + |
| 288 | +MultiComboBox: |
| 289 | +* Does not accept `StandardListItem` as children anymore. Use `MultiComboBoxItem` instead. |
| 290 | + |
| 291 | +SegmentedButton: |
| 292 | +* `SegementedButtonItem` has been replaced by `ToggleButton` |
| 293 | +* props: |
| 294 | + * `disabled`: Has been removed. |
| 295 | + * `selectedKey`: Has been removed. _To initially select a button set the `pressed` prop of the `ToggleButton` to `true`._ |
| 296 | + * `onItemSelected`: Has been replaced by `onSelectionChange` and is fired when the button selection changes. To get the selected button you can use the following function: |
| 297 | + ```JSX |
| 298 | + const onSelectionChange = (event) => { |
| 299 | + const selectedButton = event.detail.selectedButton; |
| 300 | + }; |
| 301 | + ``` |
| 302 | + |
| 303 | +ShellBar: |
| 304 | +* props: |
| 305 | + * `profile`: Is now a slot where you should use the `Avatar` component. |
| 306 | + |
0 commit comments