Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added

- Comprehensive configuration and styling settings for various barcode types
- Download functionality for barcodes

## [1.0.0] - 2025-10-09

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
"@mendix/widget-plugin-component-kit": "workspace:*",
"@mendix/widget-plugin-platform": "workspace:*",
"@mendix/widget-plugin-test-utils": "workspace:*",
"cross-env": "^7.0.3"
"@types/react": "^18.2.36",
"cross-env": "^7.0.3",
"eslint": "^9.37.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hidePropertiesIn, Properties } from "@mendix/pluggable-widgets-tools";
import { hidePropertiesIn, hidePropertyIn, Properties } from "@mendix/pluggable-widgets-tools";
import { BarcodeGeneratorPreviewProps } from "../typings/BarcodeGeneratorProps";

export type Problem = {
Expand All @@ -12,14 +12,78 @@ export type Problem = {

export function getProperties(values: BarcodeGeneratorPreviewProps, defaultProperties: Properties): Properties {
if (values.codeFormat === "QRCode") {
hidePropertiesIn(defaultProperties, values, ["codeWidth", "codeHeight", "displayValue"]);
hidePropertiesIn(defaultProperties, values, ["codeWidth", "codeHeight", "displayValue", "codeMargin"]);
} else {
hidePropertiesIn(defaultProperties, values, ["qrSize"]);
hidePropertiesIn(defaultProperties, values, ["qrImage", "qrSize", "qrMargin", "qrLevel", "qrTitle"]);
}

if (values.codeFormat !== "QRCode" || !values.qrImage) {
hidePropertiesIn(defaultProperties, values, [
"qrImageSrc",
"qrImageCenter",
"qrImageWidth",
"qrImageHeight",
"qrImageX",
"qrImageY",
"qrImageOpacity",
"qrImageExcavate"
]);
}

if (values.codeFormat !== "CODE128" && values.customCodeFormat !== "CODE128") {
hidePropertyIn(defaultProperties, values, "enableEan128");
}

if (
values.codeFormat === "QRCode" ||
values.codeFormat === "CODE128" ||
(values.codeFormat === "Custom" &&
values.customCodeFormat !== "EAN13" &&
values.customCodeFormat !== "EAN8" &&
values.customCodeFormat !== "UPC")
) {
hidePropertyIn(defaultProperties, values, "enableFlat");
}

if (
values.codeFormat === "QRCode" ||
values.codeFormat === "CODE128" ||
(values.codeFormat === "Custom" && values.customCodeFormat !== "EAN13")
) {
hidePropertyIn(defaultProperties, values, "lastChar");
}

if (
values.codeFormat === "QRCode" ||
values.codeFormat === "CODE128" ||
(values.codeFormat === "Custom" && values.customCodeFormat !== "EAN13" && values.customCodeFormat !== "EAN8")
) {
hidePropertiesIn(defaultProperties, values, ["addonFormat", "addonValue", "addonSpacing"]);
}
if (
values.codeFormat === "QRCode" ||
values.codeFormat === "CODE128" ||
(values.codeFormat === "Custom" && values.addonFormat !== "EAN5" && values.addonFormat !== "EAN2")
) {
hidePropertiesIn(defaultProperties, values, ["addonValue", "addonSpacing"]);
}

if (
values.codeFormat === "QRCode" ||
values.codeFormat === "CODE128" ||
(values.codeFormat === "Custom" && values.customCodeFormat !== "CODE39")
) {
hidePropertyIn(defaultProperties, values, "enableMod43");
}

if (values.qrImageCenter) {
hidePropertiesIn(defaultProperties, values, ["qrImageX", "qrImageY"]);
}

if (values.codeFormat !== "Custom") {
hidePropertiesIn(defaultProperties, values, ["customCodeFormat"]);
}

return defaultProperties;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,32 @@
import JsBarcode from "jsbarcode";
import { QRCodeSVG } from "qrcode.react";
import { ReactElement, useEffect, useRef } from "react";
import { ReactElement } from "react";
import { BarcodeGeneratorContainerProps } from "../typings/BarcodeGeneratorProps";
import { barcodeConfig } from "./config/Barcode.config";
import { BarcodeContextProvider, useBarcodeConfig } from "./config/BarcodeContext";
import { QRCodeRenderer } from "./components/QRCode";
import { BarcodeRenderer } from "./components/Barcode";

import "./ui/BarcodeGenerator.scss";

export default function BarcodeGenerator({
codeValue,
codeWidth,
codeHeight,
codeFormat,
codeMargin,
displayValue,
qrSize,
tabIndex
}: BarcodeGeneratorContainerProps): ReactElement {
const svgRef = useRef<SVGSVGElement>(null);
function BarcodeContainer({ tabIndex }: { tabIndex?: number }): ReactElement {
const config = useBarcodeConfig();

const value = codeValue?.status === "available" ? codeValue.value : "";
const width = codeWidth ?? 128;
const height = codeHeight ?? 128;
const format = codeFormat ?? "CODE128";
const margin = codeMargin ?? 2;
const showValue = displayValue ?? false;
const size = qrSize ?? 128;
return (
<div className="barcode-generator" tabIndex={tabIndex}>
{config.isQRCode ? <QRCodeRenderer /> : <BarcodeRenderer />}
</div>
);
}

useEffect(() => {
if (format !== "QRCode" && svgRef.current && value) {
try {
JsBarcode(svgRef.current, value, {
format,
width,
height,
margin,
displayValue: showValue
});
} catch (error) {
console.error("Error generating barcode:", error);
}
}
}, [value, width, height, format, margin, showValue]);
export default function BarcodeGenerator(props: BarcodeGeneratorContainerProps): ReactElement {
const config = barcodeConfig(props);

if (!value) {
if (!config.value) {
return <span>No barcode value provided</span>;
}

return (
<div className="barcode-generator" tabIndex={tabIndex}>
{format === "QRCode" ? <QRCodeSVG value={value} size={size} /> : <svg ref={svgRef} />}
</div>
<BarcodeContextProvider config={config}>
<BarcodeContainer tabIndex={props.tabIndex} />
</BarcodeContextProvider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,67 @@
<enumerationValues>
<enumerationValue key="CODE128">Barcode</enumerationValue>
<enumerationValue key="QRCode">QR Code</enumerationValue>
<enumerationValue key="Custom">Custom Format</enumerationValue>
<enumerationValue key="Custom">Custom</enumerationValue>
</enumerationValues>
</property>
<property key="customCodeFormat" type="enumeration" required="true" defaultValue="CODE128">
<caption>Custom Format</caption>
<description>Choose between barcode types format</description>
<enumerationValues>
<enumerationValue key="CODE128">CODE128</enumerationValue>
<enumerationValue key="EAN13">EAN-13</enumerationValue>
<enumerationValue key="EAN8">EAN-8</enumerationValue>
<enumerationValue key="UPC">UPC</enumerationValue>
<enumerationValue key="CODE39">CODE39</enumerationValue>
<enumerationValue key="ITF14">ITF-14</enumerationValue>
<enumerationValue key="MSI">MSI</enumerationValue>
<enumerationValue key="pharmacode">Pharmacode</enumerationValue>
<enumerationValue key="codabar">Codabar</enumerationValue>
<enumerationValue key="CODE93">CODE93</enumerationValue>
</enumerationValues>
</property>
<property key="enableEan128" type="boolean" defaultValue="false">
<caption>EAN-128</caption>
<description>Enable encoding CODE128 as GS1-128/EAN-128</description>
</property>
<property key="enableFlat" type="boolean" defaultValue="false">
<caption>Flat</caption>
<description>Enable flat barcode, skip guard bars</description>
</property>
<property key="lastChar" type="string" required="false">
<caption>Last character</caption>
<description>Character after the barcode</description>
</property>
<property key="enableMod43" type="boolean" required="true" defaultValue="false">
<caption>Mod43</caption>
<description>For code 39 if used with modulo 43 check digit</description>
</property>
<property key="allowDownload" type="boolean" defaultValue="false">
<caption>Allow download</caption>
<description>Adds a download button</description>
</property>
</propertyGroup>
<propertyGroup caption="EAN Addons">
<property key="addonFormat" type="enumeration" required="true" defaultValue="None">
<caption>Addon format</caption>
<description>Choose between EAN-5 or EAN-2 addon format</description>
<enumerationValues>
<enumerationValue key="None">None</enumerationValue>
<enumerationValue key="EAN5">EAN-5</enumerationValue>
<enumerationValue key="EAN2">EAN-2</enumerationValue>
</enumerationValues>
</property>
<property key="addonValue" type="attribute" required="true">
<caption>Addon value</caption>
<description>Value for the addon barcode (5 digits for EAN-5, 2 digits for EAN-2)</description>
<attributeTypes>
<attributeType name="String" />
</attributeTypes>
</property>
<property key="addonSpacing" type="integer" required="true" defaultValue="20">
<caption>Addon spacing</caption>
<description>Space between main barcode and addon (in pixels)</description>
</property>
</propertyGroup>
<propertyGroup caption="Display">
<property key="displayValue" type="boolean" defaultValue="false">
Expand All @@ -32,41 +90,75 @@
</property>
<property key="codeWidth" type="integer" required="true" defaultValue="2">
<caption>Bar width</caption>
<description>Width of the barcode bars</description>
<description>Width of a single bar</description>
</property>
<property key="codeHeight" type="integer" required="true" defaultValue="200">
<caption>Code height</caption>
<description>Height of the barcode</description>
</property>
<property key="codeMargin" type="integer" required="true" defaultValue="2">
<caption>Margin size</caption>
<description>In pixels</description>
</property>
<property key="qrSize" type="integer" required="true" defaultValue="128">
<caption>QR Size</caption>
<description>The size of the QR box</description>
</property>
<property key="codeMargin" type="integer" required="true" defaultValue="2">
<property key="qrMargin" type="integer" required="true" defaultValue="2">
<caption>Margin size</caption>
<description>In pixels</description>
<description />
</property>
<property key="qrTitle" type="string" required="true">
<caption>Title</caption>
<description>Used for accessibility reasons</description>
</property>
<property key="qrLevel" type="enumeration" required="true" defaultValue="L">
<caption>Level</caption>
<description>The Error Correction Level to use</description>
<enumerationValues>
<enumerationValue key="L">L</enumerationValue>
<enumerationValue key="M">M</enumerationValue>
<enumerationValue key="Q">Q</enumerationValue>
<enumerationValue key="H">H</enumerationValue>
</enumerationValues>
</property>
<property key="qrImage" type="boolean" required="true" defaultValue="false">
<caption>Image</caption>
<description>Include an image on top the QR code</description>
</property>
<property key="qrImageSrc" type="image" required="true">
<caption>Image source</caption>
<description>URL or path to the image to display on the QR code</description>
</property>
<property key="qrImageCenter" type="boolean" required="true" defaultValue="true">
<caption>Center image</caption>
<description>Center the image in the QR code</description>
</property>
<property key="qrImageX" type="integer" required="true" defaultValue="0">
<caption>Image X position</caption>
<description>Horizontal position of the image</description>
</property>
<property key="qrImageY" type="integer" required="true" defaultValue="0">
<caption>Image Y position</caption>
<description>Vertical position of the image</description>
</property>
<property key="qrImageHeight" type="integer" required="true" defaultValue="24">
<caption>Image height</caption>
<description>Height of the image in pixels</description>
</property>
<property key="qrImageWidth" type="integer" required="true" defaultValue="24">
<caption>Image width</caption>
<description>Width of the image in pixels</description>
</property>
<property key="qrImageOpacity" type="decimal" required="true" defaultValue="1">
<caption>Image opacity</caption>
<description>Opacity of the image (0.0 to 1.0)</description>
</property>
<property key="qrImageExcavate" type="boolean" required="true" defaultValue="true">
<caption>Excavate background</caption>
<description>Remove QR code dots behind the image</description>
</property>
</propertyGroup>
</propertyGroup>
<propertyGroup caption="Advanced">
<property key="customCodeFormat" type="enumeration" required="true" defaultValue="CODE128">
<caption>Barcode Format</caption>
<description>Choose between barcode types format</description>
<enumerationValues>
<enumerationValue key="CODE128">CODE128</enumerationValue>
<enumerationValue key="EAN13">EAN-13</enumerationValue>
<enumerationValue key="EAN8">EAN-8</enumerationValue>
<enumerationValue key="EAN5">EAN-5</enumerationValue>
<enumerationValue key="EAN2">EAN-2</enumerationValue>
<enumerationValue key="UPC">UPC</enumerationValue>
<enumerationValue key="CODE39">CODE39</enumerationValue>
<enumerationValue key="ITF14">ITF-14</enumerationValue>
<enumerationValue key="MSI">MSI</enumerationValue>
<enumerationValue key="pharmacode">Pharmacode</enumerationValue>
<enumerationValue key="codabar">Codabar</enumerationValue>
<enumerationValue key="CODE93">CODE93</enumerationValue>
</enumerationValues>
</property>
</propertyGroup>
</properties>
</widget>
Loading
Loading