Skip to content

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

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

[WC-3448]: Add datamatrix option for Barcode Generation#2319
samuelreichert wants to merge 12 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
samuelreichert and others added 12 commits July 29, 2026 12:18
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>
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.
…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.
@samuelreichert
samuelreichert force-pushed the WC-3448/add-datamatrix-generation branch from 3abcf4d to 9cc45a5 Compare July 29, 2026 10:19
@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 with bwip-js + DOMPurify
src/components/preview/DataMatrixPreview.tsx Studio Pro editor preview for DataMatrix format
src/config/Barcode.config.ts New DataMatrixTypeConfig union member and barcodeConfig() branch
src/config/validation.ts Added DataMatrix case and validateGs1DataMatrixValue()
src/utils/download-code.ts DataMatrix filename-prefix branch
src/BarcodeGenerator.tsx Dispatch to DataMatrixRenderer
src/BarcodeGenerator.editorPreview.tsx Routes DataMatrix to new preview component
src/BarcodeGenerator.xml New DataMatrix enum value + Data Matrix property group
src/ui/BarcodeGenerator.scss .datamatrix-svg and preview image styles
typings/BarcodeGeneratorProps.d.ts Regenerated with DataMatrix, DmShapeEnum, new props
src/__tests__/BarcodeGenerator.spec.tsx Integration tests for DataMatrix render paths
src/config/__tests__/Barcode.config.spec.ts Unit tests for barcodeConfig DataMatrix mapping
src/config/__tests__/validation.spec.ts Unit tests for DataMatrix/GS1 validation
package.json Added @bwip-js/browser and dompurify dependencies
CHANGELOG.md User-facing entry for DataMatrix/GS1 support
openspec/changes/add-datamatrix-generation/** OpenSpec change artifacts (design, spec, tasks)
document-viewer-web/openspec/changes/archive/… File moves only (renames)

Skipped (out of scope): pnpm-lock.yaml, openspec/ artifact files


Findings

🔶 Medium — CI: "Run code quality check" and "Plan E2E matrix" are failing

File: CI (workflow run 30443193344)
Problem: Two checks are currently failing: Run code quality check and Plan E2E matrix. The lint/quality failure is particularly important — it may indicate a lint error introduced by this PR. Per the review guidelines, PRs with failing CI checks must not be approved until the failures are explained or resolved.
Fix: Investigate the failing Run code quality check job. If the failure is pre-existing or unrelated to this PR, document that in the PR description. Otherwise fix the lint/type error before merge.


🔶 Medium — DataMatrix margin uses codeMargin but is labelled as a separate dmSize option

File: src/config/Barcode.config.ts:83
Problem: baseConfig.margin is set to props.qrMargin for QR and props.codeMargin for everything else, including DataMatrix. DataMatrix therefore reuses codeMargin ("Bar width"), which is a 1D-barcode-specific property with a misleading label in Studio Pro. The design document called out "add dedicated dmSize/dmMargin props to avoid overloading 1D bar-width semantics" — dmSize was added but dmMargin was not, so users have no obvious way to control DataMatrix padding independently.
Fix: Either add a dmMargin XML property and branch margin on format (similar to qrMargin), or add a Studio Pro caption/description to codeMargin clarifying it also controls DataMatrix padding. Keeping the current silent reuse is technically functional but surprising to users.


⚠️ Low — DOMPurify used in Studio Pro editor preview (SSR environment)

File: src/components/preview/DataMatrixPreview.tsx:2
Note: DOMPurify requires a DOM environment (window, document). Editor preview components run in the Studio Pro design-time sandbox, which is not always a full browser environment and may lack these globals. The existing DataMatrix.tsx runtime component has the same import, but the preview component is the higher-risk site. Consider guarding with typeof window !== "undefined" before calling DOMPurify.sanitize, or use isomorphic-dompurify/DOMPurify.sanitize with a fallback stub so the preview degrades gracefully rather than throwing.


⚠️ Low — getSvgElement defined inside render, new function reference every render

File: src/components/DataMatrix.tsx:103
Note: getSvgElement is redefined on every render:

const getSvgElement = (): SVGSVGElement | null => containerRef.current?.querySelector("svg") ?? null;

This is minor (it's a tiny closure) but inconsistent with how similar helpers are handled elsewhere. Inlining it directly into the DownloadButton.onClick callback, or defining it outside the component (taking containerRef as an arg), would be cleaner.


⚠️ Low — SCSS .barcode-generator-datamatrix-preview-image defined outside .barcode-renderer block

File: src/ui/BarcodeGenerator.scss:112
Note: .datamatrix-svg (used in runtime) is correctly nested inside .barcode-renderer. However, .barcode-generator-datamatrix-preview-image (used in preview) is a free-standing top-level class at line 112, not scoped to the widget prefix .barcode-generator. This deviates from the BEM-like widget-prefix convention. Consider nesting it under .barcode-generator or the .barcode-renderer block for consistency.


Positives

  • DOMPurify is used with USE_PROFILES: { svg: true, svgFilters: true } — the right profile for bwip-js SVG output, not a raw passthrough. Security handling is correct.
  • bwip-js is imported via named tree-shakeable exports (datamatrix, drawingSVG, etc.), not the bundle-everything toSVG() — exactly as the design spec required.
  • The discriminated union (BarcodeConfig = … | DataMatrixTypeConfig) pattern mirrors the existing QR path cleanly; dispatch in BarcodeGenerator.tsx stays a simple ternary chain.
  • validateGs1DataMatrixValue is deliberately minimal (structural check only) and delegates encoding correctness to bwip-js, which is the right call given the complexity of GS1 AI rules.
  • Tests cover all four encoder paths (plain square, plain rect, GS1 square, GS1 rect), config mapping, and validation edge cases; builder utilities from @mendix/widget-plugin-test-utils are used correctly.
  • CHANGELOG entry is user-facing, concise, and correctly placed under [Unreleased].

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.

2 participants