@designcrowd/library.brand-page 6.0.6-json-prereq-4 → 6.0.6-json-prereq-6

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.
Files changed (29) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-B75jYGAG.js → CreatedOnBrandCrowd-de-de-DwDGgsOX.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-CoDbU42G.js → CreatedOnBrandCrowd-en-us-BlggichW.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-CkQBC_E2.js → CreatedOnBrandCrowd-es-es-3Rikujvn.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-BueYGoqR.js → CreatedOnBrandCrowd-fr-ca-Xr3RDKuy.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-BueYGoqR.js → CreatedOnBrandCrowd-fr-fr-Xr3RDKuy.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-iVkkV5mY.js → CreatedOnBrandCrowd-pt-br-BvWREclI.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-iVkkV5mY.js → CreatedOnBrandCrowd-pt-pt-BvWREclI.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-DTcMQ9rQ.js → CreatedOnDcom-de-de-C9NLGl1Q.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-C6KX2pNG.js → CreatedOnDcom-en-us-BD9JNz8i.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-Bx2DoOtp.js → CreatedOnDcom-es-es-xLNmYxXL.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CMnpCJqe.js → CreatedOnDcom-fr-ca-CqEWAxjs.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-CIDsOdaw.js → CreatedOnDcom-fr-fr-BvBl-ljV.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-CbrdeuQe.js → CreatedOnDcom-pt-br-D8BDaORl.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-nOvChX6_.js → CreatedOnDcom-pt-pt-DJQecXvW.js} +1 -1
  15. package/lib/src/brand-page-maker/validators/field.validator.js +10 -7
  16. package/lib/src/{bundled-translations-BUyt4scr.js → bundled-translations-DY44n5a1.js} +1 -1
  17. package/lib/src/bundles/bundled-translations.json +1 -0
  18. package/lib/src/css/library.brand-page-brandCrowd.min.css +36 -36
  19. package/lib/src/css/library.brand-page-brandPage.min.css +36 -36
  20. package/lib/src/css/library.brand-page-designCom.min.css +36 -36
  21. package/lib/src/css/library.brand-page-preview.min.css +36 -36
  22. package/lib/src/index.mjs +1 -1
  23. package/lib/src/{lib-BXP4Pl2X.js → lib-D9IAQIwh.js} +6598 -6590
  24. package/package.json +1 -1
  25. package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +16 -0
  26. package/src/brand-page-maker/validators/field.validator.test.ts +15 -10
  27. package/src/brand-page-maker/validators/field.validator.ts +10 -7
  28. package/src/bundles/bundled-translations.json +1 -0
  29. package/src/shared/content-settings/components/content-settings/i18n/content-settings.json +1 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "6.0.6-json-prereq-4",
4
+ "version": "6.0.6-json-prereq-6",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -342,7 +342,15 @@
342
342
  <TextInput
343
343
  v-model="markedText"
344
344
  :placeholder="contentSettingsTr('displayTextPlaceholder')"
345
+ :error="isDisplayTextTooLong"
345
346
  />
347
+ <p
348
+ v-if="isDisplayTextTooLong"
349
+ class="tw-text-error-500 tw-text-sm"
350
+ data-test-tag="hyperlink-display-text-error"
351
+ >
352
+ {{ contentSettingsTr('displayTextMaxLimitError') }}
353
+ </p>
346
354
 
347
355
  <FieldSubHeader :title="contentSettingsTr('linkToLabel')" />
348
356
  <ButtonGroup
@@ -661,6 +669,14 @@ const urlValidationSettings = computed(() => {
661
669
  };
662
670
  });
663
671
 
672
+ // BP-5859: the hyperlink display text is inserted into the RTE, so it shares
673
+ // the RTE max-char limit. We don't block adding the link; instead we surface an
674
+ // error below the display-text field (the over-limit text is still truncated to
675
+ // the limit on insert, matching the RTE's own behaviour).
676
+ const isDisplayTextTooLong = computed(
677
+ () => markedText.value.length > props.maxLength,
678
+ );
679
+
664
680
  const isAddLinkButtonDisabled = computed(() => {
665
681
  if (selectedLinkType.value === HYPERLINK_TYPE.url) {
666
682
  const urlValue = hyperlinkUrlValue.value;
@@ -2,11 +2,12 @@ import { describe, it, expect } from 'vitest';
2
2
  import { validatorDict } from './field.validator';
3
3
 
4
4
  /**
5
- * BP-5857 — the `title` field validator must accept RTE content in both forms.
6
- * After BP-5787, switchAllContentToRTE converts section titles (Payments, Store,
7
- * Tipping, Social Links) from a plain string to a Tiptap JSON doc. The old
8
- * `typeof value === 'string'` check then flagged a title that clearly HAS text
9
- * as empty ("Please enter a value"). The validator now dual-reads the value.
5
+ * BP-5857 — the `title` validator must preserve pre-JSON (staging) semantics.
6
+ * An RTE field's value used to be inline HTML: an empty editor was "<p></p>",
7
+ * a non-empty string, so the required check always PASSED for RTE fields — it
8
+ * only failed for genuinely empty PLAIN inputs. RTE fields are now Tiptap JSON
9
+ * docs, so any doc must likewise count as "present" (valid); a plain string is
10
+ * still required to be non-empty.
10
11
  */
11
12
  describe('field.validator — title (nonEmptyString)', () => {
12
13
  const titleValidator = validatorDict.title;
@@ -23,22 +24,26 @@ describe('field.validator — title (nonEmptyString)', () => {
23
24
  ],
24
25
  });
25
26
 
26
- it('accepts a non-empty legacy string', () => {
27
+ it('accepts a non-empty plain string', () => {
27
28
  expect(titleValidator.validate('title', 'Payments').isValid).toBe(true);
28
29
  });
29
30
 
30
- it('rejects an empty string', () => {
31
+ it('rejects an empty plain string (required still enforced for plain inputs)', () => {
31
32
  expect(titleValidator.validate('title', '').isValid).toBe(false);
32
33
  });
33
34
 
34
- it('accepts a Tiptap JSON doc that has visible text (BP-5857)', () => {
35
+ it('accepts legacy empty RTE HTML "<p></p>" (non-empty string — staging parity)', () => {
36
+ expect(titleValidator.validate('title', '<p></p>').isValid).toBe(true);
37
+ });
38
+
39
+ it('accepts a Tiptap JSON doc with visible text', () => {
35
40
  expect(titleValidator.validate('title', jsonDoc('Payments')).isValid).toBe(
36
41
  true,
37
42
  );
38
43
  });
39
44
 
40
- it('rejects an empty Tiptap JSON doc', () => {
41
- expect(titleValidator.validate('title', jsonDoc('')).isValid).toBe(false);
45
+ it('accepts an empty Tiptap JSON doc (RTE parity — empty editor is "present")', () => {
46
+ expect(titleValidator.validate('title', jsonDoc('')).isValid).toBe(true);
42
47
  });
43
48
 
44
49
  it('rejects null/undefined without throwing', () => {
@@ -1,6 +1,6 @@
1
1
  import { isURL, isEmail, isTel } from '@utils/validator.util';
2
2
  import type { ItemFieldType, Validator } from '@brand-page-maker/models';
3
- import { YOUTUBE_URL_RE, getPlainTextFromRTE } from '@brand-page-maker/utils';
3
+ import { YOUTUBE_URL_RE, isTiptapDocument } from '@brand-page-maker/utils';
4
4
  import { validatorTr } from '@src/composables/useTranslate';
5
5
 
6
6
  const addressValueValidator: Validator = {
@@ -76,12 +76,15 @@ export const dummyValidator: Validator = {
76
76
 
77
77
  const nonEmptyStringValidator: Validator = {
78
78
  validate: (name, value: any) => {
79
- // BP-5787/BP-5857: `title` fields may now hold Tiptap JSON (an RTE doc)
80
- // rather than a plain string once switchAllContentToRTE converts them.
81
- // Validate the visible text either way — a doc with text is "entered",
82
- // even though `typeof value` is 'object'. getPlainTextFromRTE dual-reads
83
- // both forms (string → stripped text, JSON → concatenated text).
84
- const isValid = getPlainTextFromRTE(value).trim().length > 0;
79
+ // BP-5787/BP-5857: match legacy (pre-JSON) validation semantics.
80
+ // An RTE field's stored value used to be inline HTML — an empty editor was
81
+ // "<p></p>", a NON-empty string, so the required check always passed for RTE
82
+ // fields (it only ever failed for genuinely empty PLAIN inputs). Now RTE
83
+ // fields are Tiptap JSON docs; treat any doc as "present" so behaviour
84
+ // stays identical. A plain string is still required to be non-empty.
85
+ const isValid = isTiptapDocument(value)
86
+ ? true
87
+ : typeof value === 'string' && value.length > 0;
85
88
 
86
89
  return {
87
90
  isValid,
@@ -1609,6 +1609,7 @@
1609
1609
  "linkToLabel": "Link to",
1610
1610
  "addLinkButtonText": "Add Link",
1611
1611
  "enterValidUrlError": "Please enter a valid URL",
1612
+ "displayTextMaxLimitError": "Display text exceeds the maximum character limit",
1612
1613
  "enterTextHerePlaceholder": "Enter text here...",
1613
1614
  "bookNowLabel": "Book Now",
1614
1615
  "shippingLabel": "Enable Shipping Address",
@@ -203,6 +203,7 @@
203
203
  "linkToLabel": "Link to",
204
204
  "addLinkButtonText": "Add Link",
205
205
  "enterValidUrlError": "Please enter a valid URL",
206
+ "displayTextMaxLimitError": "Display text exceeds the maximum character limit",
206
207
  "enterTextHerePlaceholder": "Enter text here...",
207
208
  "bookNowLabel": "Book Now",
208
209
  "shippingLabel": "Enable Shipping Address",