Skip to content

Commit 3b19fc4

Browse files
authored
Merge pull request #11447 from weirdwater/wtf/build-a-widget
Update the Build a Pluggable Widget How-To
2 parents 092a990 + ca25cb6 commit 3b19fc4

2 files changed

Lines changed: 21 additions & 22 deletions

File tree

content/en/docs/howto/extensibility/pluggable-widgets/create-a-pluggable-widget-one.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ As part of the widget scaffolding, the generator builds the widget for the first
9595

9696
There is also a watcher available that will rebuild your widget as you make changes to files. Start the watcher by running `npm start`.
9797

98-
{{% alert color="info" %}}
99-
NPM version 7 changed the resolution behavior of peerDependencies. Try adding `--legacy-peer-deps` to your install command if it results in peer dependency resolution errors.
100-
{{% /alert %}}
101-
10298
### Using the Widget
10399

104100
When the build script completes it will package your widget as a `.mpk` file and copy it to the `widgets/` directory in your Mendix app. Now that the generator has finished its job it is time to use the widget in Studio Pro. To use the widget, do the following:
@@ -118,9 +114,9 @@ Open the *(YourMendixApp)/myPluggableWidgets/textBox* folder in your IDE of choi
118114
1. Remove the file *src/components/HelloWorldSample.tsx*. Errors in *TextBox.editorPreview.tsx* will be dealt with in step 6 below.
119115
2. The generator creates the widget definition file `src/TextBox.xml` with preset properties. Replace the `sampleText` property following this snippet:
120116

121-
```xml
117+
```xml {hl_lines=["7-15"]}
122118
<?xml version="1.0" encoding="utf-8" ?>
123-
<widget id="mendix.textbox.TextBox" pluginWidget="true" needsEntityContext="true" supportedPlatform="Web" offlineCapable="true" xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../xsd/widget.xsd">
119+
<widget id="mendix.textbox.TextBox" pluginWidget="true" needsEntityContext="true" supportedPlatform="Web" offlineCapable="true" xmlns="http://www.mendix.com/widget/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">
124120
<name>Text Box</name>
125121
<description>Edit text input</description>
126122
<icon/>
@@ -141,7 +137,7 @@ Open the *(YourMendixApp)/myPluggableWidgets/textBox* folder in your IDE of choi
141137
Explaining the code:
142138

143139
* *TextBox.xml* is the [widget definition file](/apidocs-mxsdk/apidocs/pluggable-widgets/#widget-definition) used in Studio Pro which reads the widget's capabilities
144-
* The property `pluginWidget=true` will make the widget work with the new widget API
140+
* The property `pluginWidget=true` will make the widget work with the [Pluggable Widgets API](/apidocs-mxsdk/apidocs/pluggable-widgets/)
145141
* The property `needsEntityContext=true` is set up to allow the attribute to be taken from context
146142
* The property of the [type attribute](/apidocs-mxsdk/apidocs/pluggable-widgets-property-types/#attribute) only allows the selection of string attributes from the domain model
147143

@@ -156,7 +152,7 @@ Open the *(YourMendixApp)/myPluggableWidgets/textBox* folder in your IDE of choi
156152
Paste the following [React function component](https://react.dev/learn/your-first-component) into the newly create `TextInput.tsx` file.
157153

158154
```tsx
159-
import { createElement, ReactElement } from "react";
155+
import { ReactElement } from "react";
160156

161157
export interface TextInputProps {
162158
value: string;
@@ -172,14 +168,14 @@ Open the *(YourMendixApp)/myPluggableWidgets/textBox* folder in your IDE of choi
172168
5. The container component *src/TextBox.tsx* receives the properties in the runtime, and forwards the data to the display component. The container works like glue between the Mendix application and the display component. In *TextBox.tsx* update the component to look like this:
173169

174170
```tsx
175-
import { createElement, ReactElement } from "react";
171+
import { ReactElement } from "react";
176172
import { TextBoxContainerProps } from "../typings/TextBoxProps";
177173
import { TextInput } from "./components/TextInput";
178174

179175
import "./ui/TextBox.css";
180176

181177
export function TextBox(props: TextBoxContainerProps): ReactElement {
182-
const value = props.textAttribute.value || "";
178+
const value = props.textAttribute.value ?? "";
183179
return <TextInput value={value} />;
184180
}
185181
```
@@ -193,7 +189,7 @@ Open the *(YourMendixApp)/myPluggableWidgets/textBox* folder in your IDE of choi
193189
6. Pluggable Widgets also have a Preview component, which is used in the design mode of the Studio Pro page editor. Update *src/TextBox.editorPreview.tsx* such that the deleted `HelloWorldSample` component is replaced by our `TextInput` component. This will resolve the errors thrown by `npm start`.
194190

195191
```tsx
196-
import { ReactElement, createElement } from "react";
192+
import { ReactElement } from "react";
197193
import { TextBoxPreviewProps } from "../typings/TextBoxProps";
198194
import { TextInput } from "./components/TextInput";
199195

@@ -224,7 +220,7 @@ The input works, but the styling could be improved. In the next code snippets, y
224220

225221
```tsx
226222
export function TextBox(props: TextBoxContainerProps): ReactElement {
227-
const value = props.textAttribute.value || "";
223+
const value = props.textAttribute.value ?? "";
228224
return <TextInput
229225
value={value}
230226
style={props.style}
@@ -239,7 +235,7 @@ The input works, but the styling could be improved. In the next code snippets, y
239235
2. Until we update the type of our TextInputProps, Typescript will display errors in *TextBox.tsx*. In *src/components/TextInput.tsx*, add the missing properties to the interface and pass them to the `input` component:
240236

241237
```tsx
242-
import { createElement, CSSProperties, ReactElement } from "react";
238+
import { CSSProperties, ReactElement } from "react";
243239

244240
export interface TextInputProps {
245241
value: string;
@@ -282,8 +278,11 @@ Comparing our widget to the Mendix text input widget we are still missing a labe
282278

283279
1. Open *src/TextBox.tsx* and remove the `style` and `className` props from `TextInput`. Now that the widget is a labeled input, it should no longer have the layout styling applied to it. In fact, the `pluggable-widget-tools` removed them from the type definition in *typings/TextBoxProps.d.ts*.
284280

285-
```tsx
286-
return <TextInput value={value} tabIndex={props.tabIndex} />;
281+
```tsx {hl_lines=[3]}
282+
export function TextBox(props: TextBoxContainerProps): ReactElement {
283+
const value = props.textAttribute.value ?? "";
284+
return <TextInput value={value} tabIndex={props.tabIndex} />;
285+
}
287286
```
288287

289288
1. **Synchronize** your project and **update** all widgets. Now open the widget **Properties** and open the **Label** tab.
@@ -344,7 +343,7 @@ Our widget now looks like a Mendix widget, but does not behave like one yet. Whi
344343

345344
```tsx {hl_lines=5}
346345
export function TextBox(props: TextBoxContainerProps): ReactElement {
347-
const value = props.textAttribute.value || "";
346+
const value = props.textAttribute.value ?? "";
348347
return <TextInput
349348
value={value}
350349
onChange={props.textAttribute.setValue}

content/en/docs/howto/extensibility/pluggable-widgets/create-a-pluggable-widget-two.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ To add these restrictions, follow the instructions below:
7676
4. In *components/TextInput.tsx*, add the `disabled` property to the `TextInputProps` interface and set the HTML input attribute to `disabled`:
7777

7878
```tsx
79-
import { createElement, CSSProperties, ReactElement } from "react";
79+
import { CSSProperties, ReactElement } from "react";
8080

8181
export interface TextInputProps {
8282
value: string;
@@ -146,7 +146,7 @@ This section teaches you how to add validation to your TextBox widget. Using mic
146146
3. To render the message, create a new component *components/Alert.tsx*:
147147

148148
```tsx
149-
import { FunctionComponent, createElement, ReactNode } from "react";
149+
import { FunctionComponent, ReactNode } from "react";
150150

151151
export interface AlertProps {
152152
alertStyle?: "default" | "primary" | "success" | "info" | "warning" | "danger";
@@ -194,7 +194,7 @@ This section teaches you how to add validation to your TextBox widget. Using mic
194194
5. Add `Fragment` to the current React import (shown below), and add a new `Alert` import underneath the existing imports in *TextBox.tsx*:
195195

196196
```tsx
197-
import { createElement, ReactElement, Fragment } from "react";
197+
import { ReactElement, Fragment } from "react";
198198
import { Alert } from "./components/Alert";
199199
```
200200

@@ -314,7 +314,7 @@ Until now the components did not keep any state. Each keystroke passed through t
314314
2. In *TextBox.tsx*, check if `onChangeAction` is available and call the execute function `onLeave` when the value is changed. When doing this, replace the `onUpdate` function with your new `onLeave` function:
315315

316316
```tsx
317-
import { createElement, Fragment, ReactElement, useEffect } from "react";
317+
import { Fragment, ReactElement, useEffect } from "react";
318318
import { TextBoxContainerProps } from "../typings/TextBoxProps";
319319
import { TextInput } from "./components/TextInput";
320320

@@ -357,7 +357,7 @@ Until now the components did not keep any state. Each keystroke passed through t
357357
3. In *components/TextInput.tsx*, introduce a state for input changes and use the `onBlur` function to call the `onLeave` function by replacing the `onUpdate` function:
358358

359359
```tsx
360-
import { createElement, CSSProperties, ReactElement, useEffect, useState } from "react";
360+
import { CSSProperties, ReactElement, useEffect, useState } from "react";
361361

362362
export interface TextInputProps {
363363
value: string;
@@ -546,7 +546,7 @@ To easily view changes to your widget while in Studio Pro's **Design mode**, you
546546
To add preview mode functionality, create a new file *src/TextBox.editorPreview.tsx* and add this code to it:
547547

548548
```tsx
549-
import { createElement, ReactElement } from "react";
549+
import { ReactElement } from "react";
550550
import { TextBoxPreviewProps } from "../typings/TextBoxProps";
551551
import { TextInput } from "./components/TextInput";
552552

0 commit comments

Comments
 (0)