@nice2dev/ui-printing 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -149,6 +149,7 @@ function historyReducer(state: HistoryState, action: HistoryAction): HistoryStat
149
149
  */
150
150
  const INK = '#000000';
151
151
  /** Same, for the faint grey a watermark is drawn in. */
152
+ // audit-allow: literal-color — ink on the white page - a print colour
152
153
  const INK_FAINT = '#94a3b8';
153
154
 
154
155
  function uid() {
@@ -285,6 +286,7 @@ const FieldElement: React.FC<FieldElementProps> = ({
285
286
  onResizeStart,
286
287
  readOnly,
287
288
  }) => {
289
+ const { t } = useNiceTranslation();
288
290
  const pos = field.position;
289
291
  const st = field.style;
290
292
  const mm = (v: number) => v * zoom * MM_TO_PX;
@@ -344,7 +346,7 @@ const FieldElement: React.FC<FieldElementProps> = ({
344
346
  ) : isBarcode ? (
345
347
  <div className={styles.fieldBarcodePlaceholder}>
346
348
  <NiceIcon name={field.type === 'qr' ? 'qr-code' : 'barcode'} size={14} />{' '}
347
- {field.type === 'qr' ? 'QR' : 'Barcode'}
349
+ {field.type === 'qr' ? 'QR' : t('templateEditor.barcode', 'Barcode')}
348
350
  </div>
349
351
  ) : field.type === 'signature' ? (
350
352
  <div className={styles.fieldSignaturePlaceholder}>
@@ -395,6 +397,7 @@ const SectionCanvas: React.FC<SectionCanvasProps> = ({
395
397
  const [draggingOver, setDraggingOver] = useState(false);
396
398
 
397
399
  const sectionTypeColors: Record<string, string> = {
400
+ // audit-allow: literal-color +3 — band tints on the white page - print colours
398
401
  header: 'rgba(219,234,254,0.35)',
399
402
  footer: 'rgba(220,252,231,0.35)',
400
403
  background: 'rgba(254,249,195,0.35)',
@@ -556,6 +559,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
556
559
  onSendBackward,
557
560
  onSave,
558
561
  }) => {
562
+ const { t } = useNiceTranslation();
559
563
  const { t: tr } = useNiceTranslation();
560
564
  const [insertOpen, setInsertOpen] = useState(false);
561
565
  const ZOOM_PRESETS = [0.5, 0.75, 1, 1.25, 1.5, 2];
@@ -578,14 +582,14 @@ const Toolbar: React.FC<ToolbarProps> = ({
578
582
  <button
579
583
  className={`${styles.toolbarBtn} ${tpl.orientation === 'portrait' ? styles.toolbarBtnActive : ''}`}
580
584
  onClick={() => onPaperChange(tpl.paperSize, 'portrait')}
581
- title="Pion"
585
+ title={t('templateEditor.portrait', 'Portrait')}
582
586
  >
583
587
  <NiceIcon name="file" size={14} />
584
588
  </button>
585
589
  <button
586
590
  className={`${styles.toolbarBtn} ${tpl.orientation === 'landscape' ? styles.toolbarBtnActive : ''}`}
587
591
  onClick={() => onPaperChange(tpl.paperSize, 'landscape')}
588
- title="Poziom"
592
+ title={t('templateEditor.landscape', 'Landscape')}
589
593
  >
590
594
  <NiceIcon name="file" size={14} style={{ transform: 'rotate(90deg)' }} />
591
595
  </button>
@@ -641,7 +645,9 @@ const Toolbar: React.FC<ToolbarProps> = ({
641
645
  {fieldTypeLabel(tr, t)}
642
646
  </button>
643
647
  ))}
644
- <div className={styles.insertCategory}>Elementy statyczne</div>
648
+ <div className={styles.insertCategory}>
649
+ {t('templateEditor.staticElements', 'Static elements')}
650
+ </div>
645
651
  {[
646
652
  'static_text',
647
653
  'static_image',
@@ -663,7 +669,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
663
669
  {fieldTypeLabel(tr, t)}
664
670
  </button>
665
671
  ))}
666
- <div className={styles.insertCategory}>Specjalne</div>
672
+ <div className={styles.insertCategory}>{t('templateEditor.special', 'Special')}</div>
667
673
  <button
668
674
  className={styles.insertItem}
669
675
  onClick={() => {
@@ -754,7 +760,11 @@ const Toolbar: React.FC<ToolbarProps> = ({
754
760
  ⊥
755
761
  </button>
756
762
  <span className={styles.toolbarSep} />
757
- <button className={styles.toolbarBtn} onClick={onBringForward} title="Do przodu">
763
+ <button
764
+ className={styles.toolbarBtn}
765
+ onClick={onBringForward}
766
+ title={t('templateEditor.bringForward', 'Bring forward')}
767
+ >
758
768
  <NiceIcon name="arrow-up" size={14} />
759
769
  </button>
760
770
  <button
@@ -844,6 +854,7 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
844
854
  onUpdateTpl,
845
855
  onReorderField,
846
856
  }) => {
857
+ const { t } = useNiceTranslation();
847
858
  const { t: tr } = useNiceTranslation();
848
859
  const [search, setSearch] = useState('');
849
860
  const filteredFields = schema?.fields.filter(
@@ -982,7 +993,7 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
982
993
  {/* ── Watermarks tab ── */}
983
994
  {activeTab === 'watermarks' && (
984
995
  <>
985
- <div className={styles.panelHeader}>Znaki wodne</div>
996
+ <div className={styles.panelHeader}>{t('templateEditor.watermarks', 'Watermarks')}</div>
986
997
  <div className={styles.wmList}>
987
998
  {(tpl.watermarks ?? []).map((wm) => (
988
999
  <div key={wm.id} className={styles.wmItem}>
@@ -1022,7 +1033,7 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
1022
1033
  </div>
1023
1034
  )}
1024
1035
  <div className={styles.wmRow}>
1025
- <span className={styles.wmLabel}>Krycie</span>
1036
+ <span className={styles.wmLabel}>{t('templateEditor.opacity', 'Opacity')}</span>
1026
1037
  <input
1027
1038
  type="range"
1028
1039
  min={0.02}
@@ -1111,7 +1122,7 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
1111
1122
  {
1112
1123
  id: uid(),
1113
1124
  type: 'text',
1114
- text: 'COPY',
1125
+ text: t('templateEditor.copy', 'COPY'),
1115
1126
  opacity: 0.12,
1116
1127
  angle: -45,
1117
1128
  fontSize: 60,
@@ -1131,12 +1142,12 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
1131
1142
  {/* ── Signatures tab ── */}
1132
1143
  {activeTab === 'signatures' && (
1133
1144
  <>
1134
- <div className={styles.panelHeader}>Podpisy</div>
1145
+ <div className={styles.panelHeader}>{t('templateEditor.signatures', 'Signatures')}</div>
1135
1146
  <div className={styles.wmList}>
1136
1147
  {(tpl.signatures ?? []).map((sig) => (
1137
1148
  <div key={sig.id} className={styles.wmItem}>
1138
1149
  <div className={styles.wmRow}>
1139
- <span className={styles.wmLabel}>Etykieta</span>
1150
+ <span className={styles.wmLabel}>{t('templateEditor.label', 'Label')}</span>
1140
1151
  <input
1141
1152
  className={styles.wmInput}
1142
1153
  value={sig.label}
@@ -1150,7 +1161,7 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
1150
1161
  />
1151
1162
  </div>
1152
1163
  <div className={styles.wmRow}>
1153
- <span className={styles.wmLabel}>Nazwisko</span>
1164
+ <span className={styles.wmLabel}>{t('templateEditor.signerName', 'Name')}</span>
1154
1165
  <input
1155
1166
  className={styles.wmInput}
1156
1167
  value={sig.signerName ?? ''}
@@ -1254,7 +1265,9 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
1254
1265
  />
1255
1266
  </div>
1256
1267
  <div className={styles.settingsRow}>
1257
- <label className={styles.settingsLabel}>Kategoria</label>
1268
+ <label className={styles.settingsLabel}>
1269
+ {t('templateEditor.category', 'Category')}
1270
+ </label>
1258
1271
  <input
1259
1272
  className={styles.settingsInput}
1260
1273
  value={tpl.category ?? ''}
@@ -1286,7 +1299,7 @@ const LeftPanel: React.FC<LeftPanelProps> = ({
1286
1299
  onUpdateTpl({ margins: { ...tpl.margins, [side]: +e.target.value } })
1287
1300
  }
1288
1301
  />
1289
- <span className={styles.settingsUnit}>mm</span>
1302
+ <span className={styles.settingsUnit}>{t('templateEditor.mm', 'mm')}</span>
1290
1303
  </div>
1291
1304
  ))}
1292
1305
  </div>
@@ -1315,6 +1328,7 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1315
1328
  paperWidthMm,
1316
1329
  paperHeightMm: _paperHeightMm,
1317
1330
  }) => {
1331
+ const { t } = useNiceTranslation();
1318
1332
  const { t: tr } = useNiceTranslation();
1319
1333
  const p = useCallback(
1320
1334
  (patch: Partial<FieldPosition>) =>
@@ -1396,8 +1410,8 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1396
1410
  {[
1397
1411
  { key: 'x' as const, label: 'X', unit: 'mm' },
1398
1412
  { key: 'y' as const, label: 'Y', unit: 'mm' },
1399
- { key: 'width' as const, label: 'Szer.', unit: 'mm' },
1400
- { key: 'height' as const, label: 'Wys.', unit: 'mm' },
1413
+ { key: 'width' as const, label: t('templateEditor.widthShort', 'W'), unit: 'mm' },
1414
+ { key: 'height' as const, label: t('templateEditor.heightShort', 'H'), unit: 'mm' },
1401
1415
  ].map(({ key, label, unit }) => (
1402
1416
  <div key={key} className={styles.posCell}>
1403
1417
  <label className={styles.posLabel}>{label}</label>
@@ -1425,7 +1439,7 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1425
1439
  <span className={styles.posUnit}>°</span>
1426
1440
  </div>
1427
1441
  <div className={styles.posCell}>
1428
- <label className={styles.posLabel}>Z-idx</label>
1442
+ <label className={styles.posLabel}>{t('templateEditor.zIdx', 'Z-idx')}</label>
1429
1443
  <input
1430
1444
  type="number"
1431
1445
  step={1}
@@ -1473,9 +1487,11 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1473
1487
  <>
1474
1488
  {hasText && (
1475
1489
  <div className={styles.styleGroup}>
1476
- <div className={styles.styleGroupTitle}>Czcionka</div>
1490
+ <div className={styles.styleGroupTitle}>{t('templateEditor.font', 'Font')}</div>
1477
1491
  <div className={styles.styleRow}>
1478
- <label className={styles.styleLabel}>Rodzina</label>
1492
+ <label className={styles.styleLabel}>
1493
+ {t('templateEditor.fontFamily', 'Family')}
1494
+ </label>
1479
1495
  <select
1480
1496
  className={styles.styleSelectFull}
1481
1497
  value={field.style.fontFamily ?? 'sans-serif'}
@@ -1574,7 +1590,9 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1574
1590
  </div>
1575
1591
  </div>
1576
1592
  <div className={styles.styleRow}>
1577
- <label className={styles.styleLabel}>W. linii</label>
1593
+ <label className={styles.styleLabel}>
1594
+ {t('templateEditor.lineHeight', 'Line h.')}
1595
+ </label>
1578
1596
  <input
1579
1597
  type="number"
1580
1598
  step={0.1}
@@ -1624,7 +1642,7 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1624
1642
  </button>
1625
1643
  </div>
1626
1644
  <div className={styles.styleRow}>
1627
- <label className={styles.styleLabel}>Ramka</label>
1645
+ <label className={styles.styleLabel}>{t('templateEditor.border', 'Border')}</label>
1628
1646
  <input
1629
1647
  type="number"
1630
1648
  step={0.5}
@@ -1651,7 +1669,7 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1651
1669
  </select>
1652
1670
  </div>
1653
1671
  <div className={styles.styleRow}>
1654
- <label className={styles.styleLabel}>Zaokr.</label>
1672
+ <label className={styles.styleLabel}>{t('templateEditor.radius', 'Radius')}</label>
1655
1673
  <input
1656
1674
  type="number"
1657
1675
  step={1}
@@ -1664,7 +1682,9 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1664
1682
  <span className={styles.styleUnit}>px</span>
1665
1683
  </div>
1666
1684
  <div className={styles.styleRow}>
1667
- <label className={styles.styleLabel}>Padding</label>
1685
+ <label className={styles.styleLabel}>
1686
+ {t('templateEditor.padding', 'Padding')}
1687
+ </label>
1668
1688
  <input
1669
1689
  type="number"
1670
1690
  step={0.5}
@@ -1674,10 +1694,12 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1674
1694
  value={field.style.padding ?? 0}
1675
1695
  onChange={(e) => s({ padding: +e.target.value })}
1676
1696
  />
1677
- <span className={styles.styleUnit}>mm</span>
1697
+ <span className={styles.styleUnit}>{t('templateEditor.mm', 'mm')}</span>
1678
1698
  </div>
1679
1699
  <div className={styles.styleRow}>
1680
- <label className={styles.styleLabel}>Krycie</label>
1700
+ <label className={styles.styleLabel}>
1701
+ {t('templateEditor.opacity', 'Opacity')}
1702
+ </label>
1681
1703
  <input
1682
1704
  type="range"
1683
1705
  min={0.1}
@@ -1707,7 +1729,7 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1707
1729
  className={styles.styleInputFull}
1708
1730
  value={field.dataPath}
1709
1731
  onChange={(e) => onChange({ dataPath: e.target.value })}
1710
- placeholder="np. invoice.number"
1732
+ placeholder={t('templateEditor.egInvoiceNumber', 'e.g. invoice.number')}
1711
1733
  />
1712
1734
  </div>
1713
1735
  <div className={styles.styleRow}>
@@ -1716,7 +1738,7 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1716
1738
  className={styles.styleInputFull}
1717
1739
  value={field.format ?? ''}
1718
1740
  onChange={(e) => onChange({ format: e.target.value })}
1719
- placeholder="DD.MM.YYYY / #,##0.00"
1741
+ placeholder={t('templateEditor.ddMmYyyy000', 'DD.MM.YYYY / #,##0.00')}
1720
1742
  />
1721
1743
  </div>
1722
1744
  <div className={styles.styleRow}>
@@ -1793,11 +1815,13 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1793
1815
  },
1794
1816
  })
1795
1817
  }
1796
- placeholder="np. invoice.isPaid"
1818
+ placeholder={t('templateEditor.egInvoiceIsPaid', 'e.g. invoice.isPaid')}
1797
1819
  />
1798
1820
  </div>
1799
1821
  <div className={styles.styleRow}>
1800
- <label className={styles.styleLabel}>Operator</label>
1822
+ <label className={styles.styleLabel}>
1823
+ {t('templateEditor.operator', 'Operator')}
1824
+ </label>
1801
1825
  <select
1802
1826
  className={styles.styleSelectFull}
1803
1827
  value={field.conditional?.operator ?? 'eq'}
@@ -1815,9 +1839,9 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1815
1839
  >
1816
1840
  <option value="eq">= {tr('printing.editor.opEqual', 'equal')}</option>
1817
1841
  <option value="neq">≠ {tr('printing.editor.opNotEqual', 'not equal')}</option>
1818
- <option value="gt">&gt; wieksze</option>
1819
- <option value="lt">&lt; mniejsze</option>
1820
- <option value="contains">zawiera</option>
1842
+ <option value="gt">{t('templateEditor.greaterThan', '> greater than')}</option>
1843
+ <option value="lt">{t('templateEditor.lessThan', '< less than')}</option>
1844
+ <option value="contains">{t('templateEditor.contains', 'contains')}</option>
1821
1845
  </select>
1822
1846
  </div>
1823
1847
  <div className={styles.styleRow}>
@@ -1834,7 +1858,7 @@ const PropertiesPanel: React.FC<PropertiesPanelProps> = ({
1834
1858
  },
1835
1859
  })
1836
1860
  }
1837
- placeholder='np. true / "PAID"'
1861
+ placeholder={t('templateEditor.egTruePaid', 'e.g. true / "PAID"')}
1838
1862
  />
1839
1863
  </div>
1840
1864
  {field.conditional?.field && (
@@ -1883,6 +1907,7 @@ export const NiceTemplateEditor: React.FC<NiceTemplateEditorProps> = ({
1883
1907
  style,
1884
1908
  theme = 'light',
1885
1909
  }) => {
1910
+ const { t } = useNiceTranslation();
1886
1911
  const [{ past, present: tpl, future }, dispatch] = useReducer(historyReducer, {
1887
1912
  past: [],
1888
1913
  present: initialTemplate ?? defaultTemplate(),
@@ -1961,7 +1986,7 @@ export const NiceTemplateEditor: React.FC<NiceTemplateEditorProps> = ({
1961
1986
  {
1962
1987
  id: uid(),
1963
1988
  type: 'text',
1964
- text: 'COPY',
1989
+ text: t('templateEditor.copy', 'COPY'),
1965
1990
  opacity: 0.12,
1966
1991
  angle: -45,
1967
1992
  fontSize: 60,
@@ -2004,7 +2029,7 @@ export const NiceTemplateEditor: React.FC<NiceTemplateEditorProps> = ({
2004
2029
  onChange?.({ ...tpl, ...updated });
2005
2030
  setSelectedIds(new Set([field.id]));
2006
2031
  },
2007
- [tpl, activeSection, onChange],
2032
+ [tpl, activeSection, onChange, t, tr, update],
2008
2033
  );
2009
2034
 
2010
2035
  // -- Drop from left panel --
@@ -2031,7 +2056,11 @@ export const NiceTemplateEditor: React.FC<NiceTemplateEditorProps> = ({
2031
2056
  if (e.ctrlKey || e.metaKey) {
2032
2057
  setSelectedIds((prev) => {
2033
2058
  const n = new Set(prev);
2034
- n.has(id) ? n.delete(id) : n.add(id);
2059
+ if (n.has(id)) {
2060
+ n.delete(id);
2061
+ } else {
2062
+ n.add(id);
2063
+ }
2035
2064
  return n;
2036
2065
  });
2037
2066
  } else if (e.shiftKey) {
@@ -752,7 +752,7 @@
752
752
  }
753
753
 
754
754
  .dark .testDataBar {
755
- background: #1c1709;
755
+ background: var(--nice-warning-bg, #1c1709);
756
756
  border-bottom-color: var(--nice-warning-dark, #78350f);
757
757
  }
758
758
 
@@ -902,7 +902,7 @@
902
902
  .marginGuide {
903
903
  position: absolute;
904
904
  pointer-events: none;
905
- border: 1px dashed rgba(59, 130, 246, 0.35);
905
+ border: 1px dashed color-mix(in srgb, var(--nice-color-primary, #3b82f6) 35%, transparent);
906
906
  z-index: 0;
907
907
  }
908
908
 
@@ -941,7 +941,7 @@
941
941
  letter-spacing: 0.06em;
942
942
  padding: var(--nice-space-px, 1px) var(--nice-space-1-25, 5px);
943
943
  border-radius: var(--nice-radius-sm, 3px);
944
- background: rgba(148, 163, 184, 0.25);
944
+ background: color-mix(in srgb, var(--nice-text-muted, #94a3b8) 25%, transparent);
945
945
  color: var(--nice-text-secondary, #64748b);
946
946
  pointer-events: none;
947
947
  z-index: 50;
@@ -238,7 +238,7 @@ export interface NiceTemplateEditorProps {
238
238
  }
239
239
 
240
240
  export interface NiceTemplateBrowserProps {
241
- templates: PrintTemplate[];
241
+ templates?: PrintTemplate[];
242
242
  selectedId?: TemplateId;
243
243
  onSelect?: (template: PrintTemplate) => void;
244
244
  onImport?: (template: PrintTemplate) => void;
@@ -271,7 +271,7 @@ export interface NicePrintPreviewProps {
271
271
  }
272
272
 
273
273
  export interface NicePrintQueueProps {
274
- jobs: PrintJob[];
274
+ jobs?: PrintJob[];
275
275
  printers?: PrinterInfo[];
276
276
  onJobUpdate: (id: PrintJobId, patch: Partial<PrintJob>) => void;
277
277
  onJobRemove: (id: PrintJobId) => void;