Skip to content

Commit f269137

Browse files
committed
chore: add .gitignore
1 parent cb4cb38 commit f269137

18 files changed

+776
-87
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/tests/TestProjects/**/.classpath
2+
/tests/TestProjects/**/.project
3+
/tests/TestProjects/**/javascriptsource
4+
/tests/TestProjects/**/javasource
5+
/tests/TestProjects/**/resources
6+
/tests/TestProjects/**/userlib
7+
8+
/tests/TestProjects/Mendix8/theme/styles/native
9+
/tests/TestProjects/Mendix8/theme/styles/web/sass
10+
/tests/TestProjects/Mendix8/theme/*.*
11+
!/tests/TestProjects/Mendix8/theme/components.json
12+
!/tests/TestProjects/Mendix8/theme/favicon.ico
13+
!/tests/TestProjects/Mendix8/theme/LICENSE
14+
!/tests/TestProjects/Mendix8/theme/settings.json
15+
16+
/test-results/
17+
/playwright-report/
18+
/playwright/.cache/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("@mendix/prettier-config-web-widgets");
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Changelog
2+
3+
All notable changes to this widget will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## [Unreleased]
8+
9+
## [1.0.0] - 2025-10-09
10+
11+
### Added
12+
13+
- Initial release of QR Code Generator widget
14+
- Generate QR codes from string input
15+
- Configurable QR code properties
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!-- Please see [QR Code Generator](https://docs.mendix.com/appstore/widgets/qr-code-generator) in the Mendix documentation for details. -->
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { test, expect } from "@playwright/test";
2+
3+
test.afterEach("Cleanup session", async ({ page }) => {
4+
// Because the test isolation that will open a new session for every test executed, and that exceeds Mendix's license limit of 5 sessions, so we need to force logout after each test.
5+
await page.evaluate(() => window.mx.session.logout());
6+
});
7+
8+
test.describe("QRCodeGenerator", () => {
9+
test.beforeEach(async ({ page }) => {
10+
await page.goto("/");
11+
await page.waitForLoadState("networkidle");
12+
});
13+
14+
test("renders QR code generator widget", async ({ page }) => {
15+
// TODO: Replace with actual QR code generator test when implementation is complete
16+
// Example test structure for QR code generator:
17+
// await expect(page.locator(".mx-name-qrCodeGenerator").first()).toBeVisible();
18+
// await page.locator(".mx-name-textInput").fill("Test QR Code");
19+
// await expect(page.locator(".mx-name-qrCodeGenerator canvas")).toBeVisible();
20+
21+
// Placeholder test for now
22+
await expect(page.locator("body")).toBeVisible();
23+
});
24+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import config from "@mendix/eslint-config-web-widgets/widget-ts.mjs";
2+
3+
export default config;
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"name": "@mendix/qrcode-generator-web",
3+
"widgetName": "QRCodeGenerator",
4+
"version": "1.0.0",
5+
"description": "Generate a QR code from a string input",
6+
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
7+
"license": "Apache-2.0",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/mendix/web-widgets.git"
11+
},
12+
"config": {},
13+
"mxpackage": {
14+
"name": "QRCodeGenerator",
15+
"type": "widget",
16+
"mpkName": "QRCodeGenerator.mpk"
17+
},
18+
"packagePath": "com.mendix.widget.custom",
19+
"marketplace": {
20+
"minimumMXVersion": "9.6.0",
21+
"appNumber": 0,
22+
"appName": "QR Code Generator",
23+
"reactReady": true
24+
},
25+
"testProject": {
26+
"githubUrl": "https://github.com/mendix/testProjects",
27+
"branchName": "qrcode-generator-web"
28+
},
29+
"scripts": {
30+
"build": "cross-env MPKOUTPUT=QRCodeGenerator.mpk pluggable-widgets-tools build:web",
31+
"create-gh-release": "rui-create-gh-release",
32+
"create-translation": "rui-create-translation",
33+
"dev": "cross-env MPKOUTPUT=QRCodeGenerator.mpk pluggable-widgets-tools start:web",
34+
"e2e": "run-e2e ci",
35+
"e2edev": "run-e2e dev --with-preps",
36+
"format": "prettier --ignore-path ./node_modules/@mendix/prettier-config-web-widgets/global-prettierignore --write .",
37+
"lint": "../../../node_modules/.bin/eslint src/ package.json",
38+
"publish-marketplace": "rui-publish-marketplace",
39+
"release": "cross-env MPKOUTPUT=QRCodeGenerator.mpk pluggable-widgets-tools release:web",
40+
"start": "cross-env MPKOUTPUT=QRCodeGenerator.mpk pluggable-widgets-tools start:server",
41+
"test": "pluggable-widgets-tools test:unit:web:enzyme-free",
42+
"update-changelog": "rui-update-changelog-widget",
43+
"verify": "rui-verify-package-format"
44+
},
45+
"dependencies": {
46+
"classnames": "^2.5.1"
47+
},
48+
"devDependencies": {
49+
"@mendix/automation-utils": "workspace:*",
50+
"@mendix/eslint-config-web-widgets": "workspace:*",
51+
"@mendix/pluggable-widgets-tools": "*",
52+
"@mendix/prettier-config-web-widgets": "workspace:*",
53+
"@mendix/run-e2e": "workspace:*",
54+
"@mendix/widget-plugin-component-kit": "workspace:*",
55+
"@mendix/widget-plugin-platform": "workspace:*",
56+
"@mendix/widget-plugin-test-utils": "workspace:*",
57+
"cross-env": "^7.0.3"
58+
}
59+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require("@mendix/run-e2e/playwright.config.cjs");
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { QRCodeGeneratorPreviewProps } from "../typings/QRCodeGeneratorProps";
2+
3+
export type Platform = "web" | "desktop";
4+
5+
export type Properties = PropertyGroup[];
6+
7+
type PropertyGroup = {
8+
caption: string;
9+
propertyGroups?: PropertyGroup[];
10+
properties?: Property[];
11+
};
12+
13+
type Property = {
14+
key: string;
15+
caption: string;
16+
description?: string;
17+
objectHeaders?: string[]; // used for customizing object grids
18+
objects?: ObjectProperties[];
19+
properties?: Properties[];
20+
};
21+
22+
type ObjectProperties = {
23+
properties: PropertyGroup[];
24+
captions?: string[]; // used for customizing object grids
25+
};
26+
27+
export type Problem = {
28+
property?: string; // key of the property, at which the problem exists
29+
severity?: "error" | "warning" | "deprecation"; // default = "error"
30+
message: string; // description of the problem
31+
studioMessage?: string; // studio-specific message, defaults to message
32+
url?: string; // link with more information about the problem
33+
studioUrl?: string; // studio-specific link
34+
};
35+
36+
type BaseProps = {
37+
type: "Image" | "Container" | "RowLayout" | "Text" | "DropZone" | "Selectable" | "Datasource";
38+
grow?: number; // optionally sets a growth factor if used in a layout (default = 1)
39+
};
40+
41+
type ImageProps = BaseProps & {
42+
type: "Image";
43+
document?: string; // svg image
44+
data?: string; // base64 image
45+
property?: object; // widget image property object from Values API
46+
width?: number; // sets a fixed maximum width
47+
height?: number; // sets a fixed maximum height
48+
};
49+
50+
type ContainerProps = BaseProps & {
51+
type: "Container" | "RowLayout";
52+
children: PreviewProps[]; // any other preview element
53+
borders?: boolean; // sets borders around the layout to visually group its children
54+
borderRadius?: number; // integer. Can be used to create rounded borders
55+
backgroundColor?: string; // HTML color, formatted #RRGGBB
56+
borderWidth?: number; // sets the border width
57+
padding?: number; // integer. adds padding around the container
58+
};
59+
60+
type RowLayoutProps = ContainerProps & {
61+
type: "RowLayout";
62+
columnSize?: "fixed" | "grow"; // default is fixed
63+
};
64+
65+
type TextProps = BaseProps & {
66+
type: "Text";
67+
content: string; // text that should be shown
68+
fontSize?: number; // sets the font size
69+
fontColor?: string; // HTML color, formatted #RRGGBB
70+
bold?: boolean;
71+
italic?: boolean;
72+
};
73+
74+
type DropZoneProps = BaseProps & {
75+
type: "DropZone";
76+
property: object; // widgets property object from Values API
77+
placeholder: string; // text to be shown inside the dropzone when empty
78+
showDataSourceHeader?: boolean; // true by default. Toggles whether to show a header containing information about the datasource
79+
};
80+
81+
type SelectableProps = BaseProps & {
82+
type: "Selectable";
83+
object: object; // object property instance from the Value API
84+
child: PreviewProps; // any type of preview property to visualize the object instance
85+
};
86+
87+
type DatasourceProps = BaseProps & {
88+
type: "Datasource";
89+
property: object | null; // datasource property object from Values API
90+
child?: PreviewProps; // any type of preview property component (optional)
91+
};
92+
93+
export type PreviewProps =
94+
| ImageProps
95+
| ContainerProps
96+
| RowLayoutProps
97+
| TextProps
98+
| DropZoneProps
99+
| SelectableProps
100+
| DatasourceProps;
101+
102+
export function getProperties(
103+
_values: QRCodeGeneratorPreviewProps,
104+
defaultProperties: Properties /* , target: Platform*/
105+
): Properties {
106+
// Do the values manipulation here to control the visibility of properties in Studio and Studio Pro conditionally.
107+
/* Example
108+
if (values.myProperty === "custom") {
109+
delete defaultProperties.properties.myOtherProperty;
110+
}
111+
*/
112+
return defaultProperties;
113+
}
114+
115+
// export function check(_values: QRCodeGeneratorPreviewProps): Problem[] {
116+
// const errors: Problem[] = [];
117+
// // Add errors to the above array to throw errors in Studio and Studio Pro.
118+
// /* Example
119+
// if (values.myProperty !== "custom") {
120+
// errors.push({
121+
// property: `myProperty`,
122+
// message: `The value of 'myProperty' is different of 'custom'.`,
123+
// url: "https://github.com/myrepo/mywidget"
124+
// });
125+
// }
126+
// */
127+
// return errors;
128+
// }
129+
130+
// export function getPreview(values: QRCodeGeneratorPreviewProps, isDarkMode: boolean, version: number[]): PreviewProps {
131+
// // Customize your pluggable widget appearance for Studio Pro.
132+
// return {
133+
// type: "Container",
134+
// children: []
135+
// }
136+
// }
137+
138+
// export function getCustomCaption(values: QRCodeGeneratorPreviewProps, platform: Platform): string {
139+
// return "Qrcodegeneratorweb";
140+
// }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { createElement, ReactElement } from "react";
2+
3+
import { QRCodeGeneratorContainerProps } from "../typings/QRCodeGeneratorProps";
4+
5+
import "./ui/QRCodeGenerator.scss";
6+
7+
export default function QRCodeGenerator(props: QRCodeGeneratorContainerProps): ReactElement {
8+
const value = props.valueAttribute?.value ?? "No value";
9+
10+
return (
11+
<div className={props.class} style={props.style} tabIndex={props.tabIndex}>
12+
<div className="qr-code-generator">
13+
<p>QR Code Generator</p>
14+
<p>Value: {value}</p>
15+
</div>
16+
</div>
17+
);
18+
}

0 commit comments

Comments
 (0)