Skip to content

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

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

[WC-3448]: Add datamatrix option for Barcode Generation#2319
samuelreichert wants to merge 10 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 and others added 8 commits July 10, 2026 17:26
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 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
Move openspec change/archive folders under each widget's own
package directory instead of the repo-root openspec/ folder.
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.
@github-actions

Copy link
Copy Markdown
Contributor

AI Code Review

🔶 Changes requested — one or more medium-severity items must be addressed


What was reviewed

File Change
src/components/DataMatrix.tsx New DataMatrix renderer component using bwip-js
src/components/preview/DataMatrixPreview.tsx Studio Pro editor preview for DataMatrix
src/config/Barcode.config.ts Added DataMatrixTypeConfig to the BarcodeConfig union
src/config/validation.ts Added DataMatrix case + new validateGs1DataMatrixValue()
src/config/__tests__/Barcode.config.spec.ts New unit tests for DataMatrix config mapping
src/config/__tests__/validation.spec.ts New unit tests for plain + GS1 validation
src/__tests__/BarcodeGenerator.spec.tsx Added DataMatrix integration tests
src/BarcodeGenerator.tsx Added datamatrix dispatch branch
src/BarcodeGenerator.editorPreview.tsx Added isDataMatrix preview branch
src/BarcodeGenerator.xml Added DataMatrix enum value + Data Matrix property group
typings/BarcodeGeneratorProps.d.ts Regenerated: CodeFormatEnum, DmShapeEnum, new props
src/ui/BarcodeGenerator.scss Added .datamatrix-svg + .datamatrix-preview-image styles
src/utils/download-code.ts Added datamatrix filename prefix branch
CHANGELOG.md Unreleased entry for DataMatrix support
package.json Added @bwip-js/browser ^4.11.2 dependency
openspec/changes/add-datamatrix-generation/* OpenSpec artifacts (design, proposal, spec, tasks)
document-viewer-web/openspec/changes/archive/* Archived document-viewer change (renames only)

Skipped (out of scope): pnpm-lock.yaml


Findings

🚨 High — dangerouslySetInnerHTML with unsanitized bwip-js output

File: src/components/DataMatrix.tsx line 606
Problem: The SVG string returned by encodeDataMatrix(config) — which receives config.codeValue directly from a Mendix DynamicValue — is injected via dangerouslySetInnerHTML without passing through a sanitizer. While bwip-js converts input into barcode matrix paths (not rendered text), if bwip-js ever embeds the input literal (e.g. human-readable text rows), a crafted value could inject SVG <script> or onload attributes. DOMPurify with an SVG allowlist eliminates this class of risk.
Fix:

import DOMPurify from "dompurify";

// in DataMatrixRenderer, replace the raw injection:
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(svg, { USE_PROFILES: { svg: true, svgFilters: true } }) }}

Add dompurify (+ @types/dompurify) to package.json dependencies. The DataMatrixPreview.tsx version uses hardcoded sample strings so its risk is negligible, but applying the same sanitizer there is good defence-in-depth.


🔶 Medium — E2E test not implemented

File: openspec/changes/add-datamatrix-generation/tasks.md line 260 (task 6.2)
Problem: Task 6.2 (Playwright E2E: render + download a DataMatrix) is unchecked and marked blocked. Per repo conventions, new interactive behaviour should have E2E coverage. The blocker is a missing Studio Pro test-project page — not a code issue — but the gap should be tracked as a follow-up issue so it doesn't silently fall through.
Fix: Open a follow-up ticket / GitHub issue for task 6.2 before or immediately after merge, and link it from this PR description. This satisfies the "related PRs/issues linked" template requirement.


⚠️ Low — .datamatrix-preview-image class not scoped under widget prefix

File: src/ui/BarcodeGenerator.scss line 908
Note: .datamatrix-preview-image is added at the top level of the file, outside any widget-root or .barcode-renderer block, with no widget-name prefix. Per frontend guidelines, custom classes must be prefixed to avoid conflicts (.barcode-generator-datamatrix-preview-image). The .datamatrix-svg class nested inside .barcode-renderer is fine by contrast.


⚠️ Low — Manual useMemo dep list with suppressed exhaustive-deps lint

File: src/components/DataMatrix.tsx line 571–572
Note: The eslint-disable-next-line react-hooks/exhaustive-deps comment was needed because encodeDataMatrix(config) takes the full config object while individual fields are listed in the dep array. The current dep list is complete and correct. The fragility is that future DataMatrixTypeConfig fields used inside encodeDataMatrix won't trigger a lint warning — they'd silently be missing from deps. Consider destructuring all consumed fields at the top of the memo body and removing the disable comment, or adding a brief explanation comment of which fields are intentionally omitted (e.g. config object identity).


Positives

  • The discriminated union + dispatch architecture (BarcodeTypeConfig | QRCodeTypeConfig | DataMatrixTypeConfig) mirrors the existing QR pattern perfectly — no new abstractions, no over-engineering.
  • Named imports from @bwip-js/browser (datamatrix, drawingSVG, etc.) correctly implement tree-shaking as required by the design doc — toSVG() (which links all 100 BWIPP encoders) is explicitly avoided.
  • Validation is layered correctly: cheap structural check (validateGs1DataMatrixValue) runs before the encoder, and try/catch catches bwip-js errors at render time — consistent with how 1D barcode errors are handled.
  • XML property keys (dmGs1Mode, dmShape, dmSize) are all lowerCamelCase and align exactly with the regenerated BarcodeGeneratorProps.d.ts typings.
  • Unit tests use @mendix/widget-plugin-test-utils builders (dynamic.available(...)) and the { virtual: true } ESM mock for bwip-js is a clean workaround for Jest's CJS transform boundary.
  • CHANGELOG entry is user-facing behaviour only ("Added Data Matrix and GS1 Data Matrix generation support"), no implementation details — matches repo convention.

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.

1 participant