Skip to content

[WC-3448]: Add datamatrix option for Barcode Generation - #2319

Open
samuelreichert wants to merge 16 commits into
mainfrom
WC-3448/add-datamatrix-generation
Open

[WC-3448]: Add datamatrix option for Barcode Generation#2319
samuelreichert wants to merge 16 commits into
mainfrom
WC-3448/add-datamatrix-generation

Conversation

@samuelreichert

Copy link
Copy Markdown
Contributor

Pull request type

New feature (non-breaking change which adds functionality)


Description

@samuelreichert
samuelreichert force-pushed the WC-3448/add-datamatrix-generation branch from 431b188 to d9b57b4 Compare July 10, 2026 15:26
@samuelreichert
samuelreichert marked this pull request as ready for review July 16, 2026 07:40
@samuelreichert
samuelreichert requested a review from a team as a code owner July 16, 2026 07:40
@github-actions

This comment has been minimized.

@samuelreichert
samuelreichert force-pushed the WC-3448/add-datamatrix-generation branch from 312ba29 to f568c62 Compare July 20, 2026 08:01
@github-actions

This comment has been minimized.

Comment thread packages/pluggableWidgets/barcode-generator-web/src/config/validation.ts Outdated
gjulivan
gjulivan previously approved these changes Jul 27, 2026
@github-actions

This comment has been minimized.

samuelreichert and others added 8 commits August 13, 2026 09:42
Adds the tree-shakeable bwip-js browser entry, the only maintained
library with native GS1 Data Matrix support, for upcoming Data Matrix
generation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds "Data Matrix" to the top-level barcode format and a new
"Advanced Data Matrix Settings" group (GS1 mode toggle, square/rectangle
shape, size). Regenerates the widget prop typings to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds DataMatrixTypeConfig to the BarcodeConfig union with a
format === "DataMatrix" branch in barcodeConfig(), plus a DataMatrix
value check and a loose GS1 Application Identifier syntax validator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds DataMatrixRenderer as a third render path. Selects the bwip-js
encoder by GS1 mode and shape (datamatrix / gs1datamatrix /
*rectangular), renders inline SVG, and reuses the existing SVG->PNG
download pipeline. Wires the dispatch in BarcodeGenerator and the
download filename prefix for the datamatrix type.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Renders a representative Data Matrix glyph in the Studio Pro page
editor when the Data Matrix format is selected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds config-mapping and validation unit tests plus render tests
asserting encoder selection (plain vs GS1, rectangular) and the
malformed-GS1 error path. Mocks bwip-js and adds the new required
Data Matrix props to the shared test props builder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Proposal, design, specs, and task checklist for adding Data Matrix
and GS1 Data Matrix generation to the barcode generator widget.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@samuelreichert
samuelreichert force-pushed the WC-3448/add-datamatrix-generation branch from 9cc45a5 to db1c6ac Compare August 13, 2026 07:45
@github-actions

This comment has been minimized.

samuelreichert and others added 8 commits August 13, 2026 10:20
Move the add-datamatrix-generation change folder under
packages/pluggableWidgets/barcode-generator-web/openspec/ instead of the
repo-root openspec/ folder, per AGENTS.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bwip-js SVGs carry only a viewBox, no width/height attributes, so the
rendered element defaulted to intrinsic sizing instead of the
configured size. Derive pixel dimensions from the viewBox and apply
them via inline style.
…class, tighten memo deps

Data Matrix code value comes from a Mendix DynamicValue and reaches the
DOM via dangerouslySetInnerHTML; sanitize the bwip-js SVG output with
DOMPurify before injecting it. Also prefix the preview image class per
widget style convention and destructure encodeDataMatrix's params so the
useMemo dependency list stays exhaustive without a lint suppression.
Data Matrix reused codeMargin, which is documented in pixels, but bwip-js
multiplies paddingwidth/paddingheight by scale — so the Data Matrix margin
is in module units, like qrMargin. A codeMargin of 0 chosen for a 1D barcode
therefore stripped the Data Matrix quiet zone and made the symbol unscannable.

Add dmMargin (module units, default 2) and branch the margin per format.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… format

The Advanced Data Matrix Settings group was never hidden, so it showed for
Barcode, QR Code and Custom. The reverse leaked too: because the existing
conditions enumerated QRCode/CODE128/Custom, selecting Data Matrix still
showed bar width, code height, display value, EAN-128, Mod43 and the EAN
addon properties.

Replace the enumerated format checks with intent-named booleans so adding a
format cannot silently reopen these, and gate check() to validate only the
sizing properties that are visible. Also report QR size problems on qrSize
instead of codeHeight, and validate static GS1 values at design time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replace the placeholder body assertion with plain render, GS1 render,
rectangular shape, value re-render and PNG download tests.

These stay dormant: mendix/testProjects has no barcode-generator-web branch
yet, so the e2e script remains stubbed. The spec header lists the page route
and mx-names the test project needs before the runner can be enabled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add requirements for the dedicated Data Matrix sizing/quiet zone and for
format-scoped property visibility, resolve the design doc's open question on
sizing props with the bwip-js scaling evidence, and update the task list:
the build now succeeds (~228 KB minified / ~73 KB gzipped for the tree-shaken
Data Matrix encoders) and e2e is written but dormant.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@samuelreichert
samuelreichert force-pushed the WC-3448/add-datamatrix-generation branch from db1c6ac to 8086499 Compare August 13, 2026 08:29
@github-actions

Copy link
Copy Markdown
Contributor

AI Code Review

⚠️ Approved with suggestions — low-severity items only, safe to merge


What was reviewed

File Change
src/components/DataMatrix.tsx New DataMatrix renderer using bwip-js, DOMPurify sanitization, SVG download
src/components/preview/DataMatrixPreview.tsx Studio Pro design-time preview for Data Matrix
src/BarcodeGenerator.tsx Dispatch updated to route config.type === "datamatrix"
src/BarcodeGenerator.xml DataMatrix enum added, dm* property group added
src/BarcodeGenerator.editorConfig.ts Visibility/validation extended for Data Matrix
src/BarcodeGenerator.editorPreview.tsx Preview dispatch updated
src/config/Barcode.config.ts DataMatrixTypeConfig added to discriminated union; getMargin extended
src/config/validation.ts validateBarcodeValue("DataMatrix") + validateGs1DataMatrixValue added
src/utils/download-code.ts datamatrix / datamatrix_gs1 filename prefix
src/ui/BarcodeGenerator.scss .datamatrix-svg + .barcode-generator-datamatrix-preview-image
typings/BarcodeGeneratorProps.d.ts Regenerated — DataMatrix, DmShapeEnum, dm* props
src/__tests__/BarcodeGenerator.spec.tsx Data Matrix render, encoder dispatch, GS1 validation tests
src/__tests__/BarcodeGenerator.editorConfig.spec.ts Visibility + check() tests for Data Matrix
src/config/__tests__/validation.spec.ts validateBarcodeValue("DataMatrix") + validateGs1DataMatrixValue tests
src/config/__tests__/Barcode.config.spec.ts barcodeConfig mapping tests for Data Matrix
e2e/BarcodeGenerator.spec.js Playwright specs written but dormant (no test project yet)
CHANGELOG.md Keep a Changelog entry added under [Unreleased]
package.json @bwip-js/browser + dompurify added

Skipped (out of scope): pnpm-lock.yaml, openspec/changes/**

CI check result: could not retrieve (permission not granted) — no failing checks observed from context.


Findings

⚠️ Low — logLevel in useMemo deps causes unnecessary SVG re-renders

File: packages/pluggableWidgets/barcode-generator-web/src/components/DataMatrix.tsx line 88
Note: logLevel appears in the useMemo dependency array, but the memo's return value — the SVG string or error boolean — doesn't depend on logLevel. Only the printError side-effect call uses it. Changing the log level at runtime will needlessly re-run the encoder.

// before
}, [codeValue, size, gs1Mode, shape, margin, logLevel]);

// after — logLevel only drives the side-effect, not the computed value
}, [codeValue, size, gs1Mode, shape, margin]);

⚠️ Low — DataMatrixPreview ignores dmShape, always renders a square symbol

File: packages/pluggableWidgets/barcode-generator-web/src/components/preview/DataMatrixPreview.tsx lines 21-26
Note: The preview always calls the square datamatrix/gs1datamatrix encoder, regardless of restProps.dmShape. A developer who sets Symbol shape = Rectangle in Studio Pro sees a square symbol in the editor, which may be confusing. Runtime rendering is unaffected.

Consider branching on restProps.dmShape === "rectangle" and calling datamatrixrectangular/gs1datamatrixrectangular — same pattern as DataMatrixRenderer.


⚠️ Low — E2E tests written but dormant; no testProjects branch yet

File: packages/pluggableWidgets/barcode-generator-web/e2e/BarcodeGenerator.spec.js line 1-36
Note: The spec is well-structured and covers the right scenarios, but package.json keeps "e2e": "echo ...", so these tests never run in CI. The comment block explains what page content is needed in mendix/testProjects. Track the barcode-generator-web test project branch as a follow-up work item so the tests are activated before the next release.


⚠️ Low — No unit test for the encoder throw path or for logLevel: "None" suppressing the error UI

File: packages/pluggableWidgets/barcode-generator-web/src/__tests__/BarcodeGenerator.spec.tsx line 1058
Note: The Data Matrix test block covers plain, GS1, rectangular, and GS1 validation failure — good coverage. Two gaps remain:

  1. No test for when encodeDataMatrix itself throws (the try/catch at DataMatrix.tsx:81) — verify the error alert appears.
  2. No test confirming logLevel: "None" suppresses the error UI — existing tests only use "Debug".

These gaps are low-risk (the paths exist in the existing barcode tests as precedent) but worth adding for symmetry.


Positives

  • DOMPurify applied correctly — raw bwip-js SVG markup is sanitized with USE_PROFILES: { svg: true, svgFilters: true } before injection via dangerouslySetInnerHTML, both in the runtime renderer and the Studio Pro preview. This is the right approach for untrusted SVG strings.
  • Clean discriminated union architectureDataMatrixTypeConfig follows exactly the same pattern as QRCodeTypeConfig and BarcodeTypeConfig, making the dispatch in BarcodeGenerator.tsx and download-code.ts straightforward to extend.
  • Format-scoped property visibilitygetProperties correctly hides 1D-only props (bar sizing, display value, EAN addons, Mod43) for Data Matrix and vice versa; backed by a dedicated editorConfig.spec.ts test matrix.
  • Dedicated dmMargin vs codeMargin — the design correctly separates module-unit margin (Data Matrix, QR) from pixel margin (1D barcodes), with the rationale documented in design.md and enforced by the getMargin dispatch.
  • Tree-shakeable bwip-js import — named datamatrix/gs1datamatrix/drawingSVG imports instead of the monolithic toSVG(), as the design doc requires.
  • Quiet zone validationdmMargin < 1 correctly emits a "warning" (not "error") in check(), matching the spec requirement that at least 1 module unit is needed for scannability.
  • GS1 validation is appropriately loose — the regex checks structural correctness ((nn)data groups) but delegates encoding validity to bwip-js, with a clear comment explaining why (bwip-js is the source of truth).

@iobuhov iobuhov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants