Skip to content

Commit 64bb327

Browse files
committed
feat: add barcode support and enhance properties conditional visibility
1 parent 8994496 commit 64bb327

File tree

7 files changed

+121
-39
lines changed

7 files changed

+121
-39
lines changed

packages/pluggableWidgets/qrcode-generator-web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
},
4545
"dependencies": {
4646
"classnames": "^2.5.1",
47+
"jsbarcode": "^3.12.1",
4748
"qrcode.react": "^4.2.0"
4849
},
4950
"devDependencies": {

packages/pluggableWidgets/qrcode-generator-web/src/QRCodeGenerator.editorConfig.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { hidePropertiesIn, Properties } from "@mendix/pluggable-widgets-tools";
12
import { QRCodeGeneratorPreviewProps } from "../typings/QRCodeGeneratorProps";
23

34
export type Problem = {
@@ -9,14 +10,39 @@ export type Problem = {
910
studioUrl?: string; // studio-specific link
1011
};
1112

13+
export function getProperties(values: QRCodeGeneratorPreviewProps, defaultProperties: Properties): Properties {
14+
if (values.codeFormat === "QR") {
15+
hidePropertiesIn(defaultProperties, values, ["codeWidth", "codeHeight", "displayValue"]);
16+
} else {
17+
hidePropertiesIn(defaultProperties, values, ["qrSize"]);
18+
}
19+
return defaultProperties;
20+
}
21+
1222
export function check(_values: QRCodeGeneratorPreviewProps): Problem[] {
1323
const errors: Problem[] = [];
1424

25+
if (!_values.codeWidth || _values.codeWidth < 1) {
26+
errors.push({
27+
property: `codeWidth`,
28+
severity: "error",
29+
message: `The value of 'Bar width' must be at least 1.`
30+
});
31+
}
32+
33+
if (!_values.codeHeight || _values.codeHeight < 20) {
34+
errors.push({
35+
property: `codeHeight`,
36+
severity: "error",
37+
message: `The value of 'Code height' must be at least 20.`
38+
});
39+
}
40+
1541
if (!_values.qrSize || _values.qrSize < 50) {
1642
errors.push({
17-
property: `qrSize`,
43+
property: `codeHeight`,
1844
severity: "error",
19-
message: `The value of 'QR Code Size' may not be smaller than 50px.`
45+
message: `The value of 'QR size' must be at least 50.`
2046
});
2147
}
2248

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,53 @@
1-
import { createElement, ReactElement, useMemo } from "react";
1+
import { createElement, ReactElement, useEffect, useRef } from "react";
22
import { QRCodeGeneratorContainerProps } from "../typings/QRCodeGeneratorProps";
3-
import { QRCodeSVG } from "qrcode.react"; // Changed to named import QRCodeSVG
3+
import { QRCodeSVG } from "qrcode.react";
4+
import JsBarcode from "jsbarcode";
5+
46
import "./ui/QRCodeGenerator.scss";
57

68
export default function QRCodeGenerator({
7-
qrValue,
9+
codeValue,
10+
codeWidth,
11+
codeHeight,
12+
codeFormat,
13+
codeMargin,
14+
displayValue,
815
qrSize,
9-
qrMargin,
1016
tabIndex
1117
}: QRCodeGeneratorContainerProps): ReactElement {
12-
// Handle Mendix data binding
13-
const value = qrValue?.status === "available" ? qrValue.value : "";
18+
const svgRef = useRef<SVGSVGElement>(null);
19+
20+
const value = codeValue?.status === "available" ? codeValue.value : "";
21+
const width = codeWidth ?? 128;
22+
const height = codeHeight ?? 128;
23+
const format = codeFormat ?? "CODE128";
24+
const margin = codeMargin ?? 2;
25+
const showValue = displayValue ?? false;
1426
const size = qrSize ?? 128;
15-
const margin = qrMargin ?? 2;
1627

17-
// Memoize QR code rendering
18-
const qrCode = useMemo(() => {
19-
if (!value) return null;
20-
return (
21-
<QRCodeSVG
22-
value={value}
23-
size={size}
24-
level="M" // Error correction level
25-
marginSize={margin ?? 2}
26-
aria-label={`QR code for: ${value}`}
27-
/>
28-
);
29-
}, [value, size, margin]);
28+
useEffect(() => {
29+
if (format !== "QR" && svgRef.current && value) {
30+
try {
31+
JsBarcode(svgRef.current, value, {
32+
format,
33+
width,
34+
height,
35+
margin,
36+
displayValue: showValue
37+
});
38+
} catch (error) {
39+
console.error("Error generating barcode:", error);
40+
}
41+
}
42+
}, [value, width, height, format, margin, showValue]);
43+
44+
if (!value) {
45+
return <span>No barcode value provided</span>;
46+
}
3047

3148
return (
32-
<div className="qr-code-widget" tabIndex={tabIndex}>
33-
{qrCode ?? (
34-
<span className="text-muted">
35-
{qrValue?.status === "loading" ? "Loading..." : "No QR code to display"}
36-
</span>
37-
)}
49+
<div className="barcode-generator" tabIndex={tabIndex}>
50+
{format === "QR" ? <QRCodeSVG value={value} size={size} /> : <svg ref={svgRef} />}
3851
</div>
3952
);
4053
}

packages/pluggableWidgets/qrcode-generator-web/src/QRCodeGenerator.xml

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,40 @@
88
<properties>
99
<propertyGroup caption="General">
1010
<propertyGroup caption="Data source">
11-
<property key="qrValue" type="attribute" required="true">
11+
<property key="codeValue" type="attribute" required="true">
1212
<caption>Dynamic value</caption>
1313
<description>String to encode in the QR code</description>
1414
<attributeTypes>
1515
<attributeType name="String" />
1616
</attributeTypes>
1717
</property>
18+
<property key="codeFormat" type="enumeration" required="true" defaultValue="CODE128">
19+
<caption>Barcode Format</caption>
20+
<description>Choose between QR or other barcode types</description>
21+
<enumerationValues>
22+
<enumerationValue key="CODE128">CODE 128</enumerationValue>
23+
<enumerationValue key="QR">QR Code</enumerationValue>
24+
</enumerationValues>
25+
</property>
26+
<property key="displayValue" type="boolean" defaultValue="false">
27+
<caption>Display value</caption>
28+
<description>Display the value below the code</description>
29+
</property>
30+
<property key="codeWidth" type="integer" required="true" defaultValue="2">
31+
<caption>Bar width</caption>
32+
<description>Width of the barcode bars</description>
33+
</property>
34+
<property key="codeHeight" type="integer" required="true" defaultValue="200">
35+
<caption>Code height</caption>
36+
<description>In pixels</description>
37+
</property>
1838
<property key="qrSize" type="integer" required="true" defaultValue="128">
19-
<caption>QR Code Size</caption>
20-
<description>Size of the QR code in pixels</description>
39+
<caption>QR Size</caption>
40+
<description>The size of the QR box</description>
2141
</property>
22-
<property key="qrMargin" type="integer" required="true" defaultValue="2">
23-
<caption>QR Margin Size</caption>
24-
<description>Size of the QR margin in pixels</description>
42+
<property key="codeMargin" type="integer" required="true" defaultValue="2">
43+
<caption>Margin size</caption>
44+
<description>In pixels</description>
2545
</property>
2646
</propertyGroup>
2747
</propertyGroup>

packages/pluggableWidgets/qrcode-generator-web/src/ui/QRCodeGenerator.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// QR Code Generator Widget Styles
2-
$widget-prefix: "qr-code-generator";
2+
$widget-prefix: "barcode-generator";
33

44
.#{$widget-prefix} {
55
display: inline-block;

packages/pluggableWidgets/qrcode-generator-web/typings/QRCodeGeneratorProps.d.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66
import { CSSProperties } from "react";
77
import { EditableValue } from "mendix";
88

9+
export type CodeFormatEnum = "CODE128" | "QR";
10+
911
export interface QRCodeGeneratorContainerProps {
1012
name: string;
1113
class: string;
1214
style?: CSSProperties;
1315
tabIndex?: number;
14-
qrValue: EditableValue<string>;
16+
codeValue: EditableValue<string>;
17+
codeFormat: CodeFormatEnum;
18+
displayValue: boolean;
19+
codeWidth: number;
20+
codeHeight: number;
1521
qrSize: number;
16-
qrMargin: number;
22+
codeMargin: number;
1723
}
1824

1925
export interface QRCodeGeneratorPreviewProps {
@@ -27,7 +33,11 @@ export interface QRCodeGeneratorPreviewProps {
2733
readOnly: boolean;
2834
renderMode: "design" | "xray" | "structure";
2935
translate: (text: string) => string;
30-
qrValue: string;
36+
codeValue: string;
37+
codeFormat: CodeFormatEnum;
38+
displayValue: boolean;
39+
codeWidth: number | null;
40+
codeHeight: number | null;
3141
qrSize: number | null;
32-
qrMargin: number | null;
42+
codeMargin: number | null;
3343
}

pnpm-lock.yaml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)