@designcrowd/library.brand-page 5.8.7 → 5.8.8

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 (24) hide show
  1. package/lib/src/brand-page/components/media/Shape.mixin.js +3 -0
  2. package/lib/src/brand-page/constants/misc.constants.d.ts +0 -22
  3. package/lib/src/brand-page/constants/misc.constants.js +0 -22
  4. package/lib/src/brand-page/utils/color.util.d.ts +2 -0
  5. package/lib/src/brand-page/utils/color.util.js +13 -0
  6. package/lib/src/brand-page/utils/style.util.d.ts +6 -2
  7. package/lib/src/brand-page/utils/style.util.js +43 -27
  8. package/lib/src/brand-page-maker/components/admin-background-settings/AdminBackgroundSettings.mixin.d.ts +0 -22
  9. package/lib/src/index.mjs +14680 -13727
  10. package/lib/src/shared/content-settings/components/color-field/ColorField.mixin.d.ts +8 -26
  11. package/lib/src/shared/content-settings/components/color-field/ColorField.mixin.js +3 -2
  12. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +0 -22
  13. package/package.json +2 -1
  14. package/src/brand-page/components/media/Shape.mixin.ts +4 -0
  15. package/src/brand-page/constants/misc.constants.ts +0 -22
  16. package/src/brand-page/utils/color.util.test.ts +47 -0
  17. package/src/brand-page/utils/color.util.ts +18 -0
  18. package/src/brand-page/utils/style.util.test.ts +1 -0
  19. package/src/brand-page/utils/style.util.ts +94 -27
  20. package/src/shared/content-settings/components/color-field/ColorField.mixin.ts +3 -2
  21. package/src/shared/content-settings/components/color-replacements-field/ColorReplacementsField.vue +126 -37
  22. package/lib/src/shared/content-settings/components/color-replacements-field/ColorReplacementsField.mixin.d.ts +0 -112
  23. package/lib/src/shared/content-settings/components/color-replacements-field/ColorReplacementsField.mixin.js +0 -104
  24. package/src/shared/content-settings/components/color-replacements-field/ColorReplacementsField.mixin.ts +0 -118
@@ -7,11 +7,12 @@ import type { UpdateItemValuePayload } from '../../models';
7
7
  declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
8
8
  id: {
9
9
  type: StringConstructor;
10
- required: true;
10
+ required: false;
11
+ default: string;
11
12
  };
12
13
  isToggled: {
13
14
  type: BooleanConstructor;
14
- required: true;
15
+ required: false;
15
16
  };
16
17
  name: {
17
18
  type: StringConstructor;
@@ -271,28 +272,6 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
271
272
  styleThemeKeys: Readonly<{
272
273
  LogoTextColor: "logo-text-color";
273
274
  LogoBackgroundColor: "logo-background-color";
274
- LogoTextColor50: "logo-text-color-50";
275
- LogoTextColor100: "logo-text-color-100";
276
- LogoTextColor200: "logo-text-color-200";
277
- LogoTextColor300: "logo-text-color-300";
278
- LogoTextColor400: "logo-text-color-400";
279
- LogoTextColor500: "logo-text-color-500";
280
- LogoTextColor600: "logo-text-color-600";
281
- LogoTextColor700: "logo-text-color-700";
282
- LogoTextColor800: "logo-text-color-800";
283
- LogoTextColor900: "logo-text-color-900";
284
- LogoTextColor950: "logo-text-color-950";
285
- LogoBackgroundColor50: "logo-background-color-50";
286
- LogoBackgroundColor100: "logo-background-color-100";
287
- LogoBackgroundColor200: "logo-background-color-200";
288
- LogoBackgroundColor300: "logo-background-color-300";
289
- LogoBackgroundColor400: "logo-background-color-400";
290
- LogoBackgroundColor500: "logo-background-color-500";
291
- LogoBackgroundColor600: "logo-background-color-600";
292
- LogoBackgroundColor700: "logo-background-color-700";
293
- LogoBackgroundColor800: "logo-background-color-800";
294
- LogoBackgroundColor900: "logo-background-color-900";
295
- LogoBackgroundColor950: "logo-background-color-950";
296
275
  }>;
297
276
  popup: boolean;
298
277
  }, {
@@ -308,11 +287,12 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
308
287
  }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("update:modelValue" | "on-toggle-state-change")[], "update:modelValue" | "on-toggle-state-change", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
309
288
  id: {
310
289
  type: StringConstructor;
311
- required: true;
290
+ required: false;
291
+ default: string;
312
292
  };
313
293
  isToggled: {
314
294
  type: BooleanConstructor;
315
- required: true;
295
+ required: false;
316
296
  };
317
297
  name: {
318
298
  type: StringConstructor;
@@ -369,11 +349,13 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
369
349
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
370
350
  "onOn-toggle-state-change"?: ((...args: any[]) => any) | undefined;
371
351
  }>, {
352
+ id: string;
372
353
  label: string;
373
354
  disableTransparent: boolean;
374
355
  valueConvertor: ValueConvertor<string | BrandPageCssStyle, string | undefined, string | BrandPageCssStyle>;
375
356
  showGradients: boolean;
376
357
  useV2: boolean;
358
+ isToggled: boolean;
377
359
  toggleUniqueId: string;
378
360
  enableColorMatch: boolean;
379
361
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -11,11 +11,12 @@ export default defineComponent({
11
11
  props: {
12
12
  id: {
13
13
  type: String,
14
- required: true,
14
+ required: false,
15
+ default: '',
15
16
  },
16
17
  isToggled: {
17
18
  type: Boolean,
18
- required: true,
19
+ required: false,
19
20
  },
20
21
  name: {
21
22
  type: String,
@@ -852,28 +852,6 @@ declare const _default: import("vue").DefineComponent<{}, {
852
852
  styleThemeKeys: Readonly<{
853
853
  LogoTextColor: "logo-text-color";
854
854
  LogoBackgroundColor: "logo-background-color";
855
- LogoTextColor50: "logo-text-color-50";
856
- LogoTextColor100: "logo-text-color-100";
857
- LogoTextColor200: "logo-text-color-200";
858
- LogoTextColor300: "logo-text-color-300";
859
- LogoTextColor400: "logo-text-color-400";
860
- LogoTextColor500: "logo-text-color-500";
861
- LogoTextColor600: "logo-text-color-600";
862
- LogoTextColor700: "logo-text-color-700";
863
- LogoTextColor800: "logo-text-color-800";
864
- LogoTextColor900: "logo-text-color-900";
865
- LogoTextColor950: "logo-text-color-950";
866
- LogoBackgroundColor50: "logo-background-color-50";
867
- LogoBackgroundColor100: "logo-background-color-100";
868
- LogoBackgroundColor200: "logo-background-color-200";
869
- LogoBackgroundColor300: "logo-background-color-300";
870
- LogoBackgroundColor400: "logo-background-color-400";
871
- LogoBackgroundColor500: "logo-background-color-500";
872
- LogoBackgroundColor600: "logo-background-color-600";
873
- LogoBackgroundColor700: "logo-background-color-700";
874
- LogoBackgroundColor800: "logo-background-color-800";
875
- LogoBackgroundColor900: "logo-background-color-900";
876
- LogoBackgroundColor950: "logo-background-color-950";
877
855
  }>;
878
856
  isColorMatch: {};
879
857
  popup: boolean;
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": "5.8.7",
4
+ "version": "5.8.8",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -64,6 +64,7 @@
64
64
  "axios": "1.6.7",
65
65
  "chroma-js": "2.4.2",
66
66
  "click-outside-vue3": "4.0.1",
67
+ "color": "5.0.0",
67
68
  "config": "3.3.10",
68
69
  "core-js": "3.35.1",
69
70
  "css-color-names": "1.0.1",
@@ -85,6 +85,10 @@ export default defineComponent({
85
85
  },
86
86
  methods: {
87
87
  async rerender() {
88
+ if (!this.originalSvgData) {
89
+ return;
90
+ }
91
+
88
92
  this.svgData = applyColorReplacementsToSvgString(
89
93
  this.originalSvgData,
90
94
  this.colorReplacements,
@@ -67,28 +67,6 @@ export const HEADER_CSRF_TOKEN = 'csrf-token';
67
67
  export const STYLE_THEME_KEYS = Object.freeze({
68
68
  LogoTextColor: 'logo-text-color',
69
69
  LogoBackgroundColor: 'logo-background-color',
70
- LogoTextColor50: 'logo-text-color-50',
71
- LogoTextColor100: 'logo-text-color-100',
72
- LogoTextColor200: 'logo-text-color-200',
73
- LogoTextColor300: 'logo-text-color-300',
74
- LogoTextColor400: 'logo-text-color-400',
75
- LogoTextColor500: 'logo-text-color-500',
76
- LogoTextColor600: 'logo-text-color-600',
77
- LogoTextColor700: 'logo-text-color-700',
78
- LogoTextColor800: 'logo-text-color-800',
79
- LogoTextColor900: 'logo-text-color-900',
80
- LogoTextColor950: 'logo-text-color-950',
81
- LogoBackgroundColor50: 'logo-background-color-50',
82
- LogoBackgroundColor100: 'logo-background-color-100',
83
- LogoBackgroundColor200: 'logo-background-color-200',
84
- LogoBackgroundColor300: 'logo-background-color-300',
85
- LogoBackgroundColor400: 'logo-background-color-400',
86
- LogoBackgroundColor500: 'logo-background-color-500',
87
- LogoBackgroundColor600: 'logo-background-color-600',
88
- LogoBackgroundColor700: 'logo-background-color-700',
89
- LogoBackgroundColor800: 'logo-background-color-800',
90
- LogoBackgroundColor900: 'logo-background-color-900',
91
- LogoBackgroundColor950: 'logo-background-color-950',
92
70
  });
93
71
 
94
72
  export const BoxShadowSpread = 0.5;
@@ -0,0 +1,47 @@
1
+ import { getNewColorBasedOnTargetColorTheme } from './color.util';
2
+
3
+ describe('color.util - getNewColorBasedOnTargetColorTheme', () => {
4
+ [
5
+ {
6
+ original: '#2B2B2B',
7
+ expectedNewColor: 'rgb(58, 23, 63)',
8
+ },
9
+ {
10
+ original: '#FFB751',
11
+ expectedNewColor: 'rgb(215, 164, 222)',
12
+ },
13
+ {
14
+ original: '#FFE070',
15
+ expectedNewColor: 'rgb(233, 205, 237)',
16
+ },
17
+ {
18
+ original: '#789461',
19
+ expectedNewColor: 'rgb(177, 77, 191)',
20
+ },
21
+ {
22
+ original: '#8CAD72',
23
+ expectedNewColor: 'rgb(191, 110, 203)',
24
+ },
25
+ {
26
+ original: '#A4CB85',
27
+ expectedNewColor: 'rgb(209, 150, 217)',
28
+ },
29
+ {
30
+ original: '#000',
31
+ expectedNewColor: 'rgb(0, 0, 0)',
32
+ },
33
+ {
34
+ original: '#fff',
35
+ expectedNewColor: 'rgb(255, 255, 255)',
36
+ },
37
+ ].forEach((testItem) => {
38
+ test(`given value ${testItem.original} should return expected new color ${testItem.expectedNewColor}`, () => {
39
+ const newColor = getNewColorBasedOnTargetColorTheme(
40
+ testItem.original,
41
+ '#ab43ba',
42
+ );
43
+
44
+ expect(newColor?.toString()).equals(testItem.expectedNewColor);
45
+ });
46
+ });
47
+ });
@@ -1,6 +1,7 @@
1
1
  import isHexColor from 'validator/lib/isHexColor';
2
2
  import { hexToRGBA, isColor } from '../../utils/helpers';
3
3
  import type { LogoTheme, Theme } from '../models';
4
+ import Color, { type ColorInstance } from 'color';
4
5
 
5
6
  // function from https://stackoverflow.com/a/9733420/3695983
6
7
  export const luminance = (r: number, g: number, b: number): number => {
@@ -95,3 +96,20 @@ export const getThemeByTextStyleAndLogoTheme = (
95
96
  secondaryColor,
96
97
  };
97
98
  };
99
+
100
+ export const getNewColorBasedOnTargetColorTheme = (
101
+ originalColor: string,
102
+ targetColor: string,
103
+ ): ColorInstance | undefined => {
104
+ try {
105
+ const originalColorGrayScaled = Color(originalColor).grayscale().hsl();
106
+
107
+ const targetHslColor = Color(targetColor)
108
+ .hsl()
109
+ .lightness(originalColorGrayScaled.lightness());
110
+
111
+ return targetHslColor.rgb();
112
+ } catch (e) {
113
+ return;
114
+ }
115
+ };
@@ -253,6 +253,7 @@ describe('style.util', () => {
253
253
  // Act
254
254
  const { newStyle } = applyLogoThemeToBrandPageStyleRecursive(
255
255
  logoTheme,
256
+ 'style',
256
257
  style,
257
258
  );
258
259
 
@@ -24,6 +24,7 @@ import {
24
24
  import {
25
25
  addTransparentAlphaChannelToHex,
26
26
  calculateLuminanceRatio,
27
+ getNewColorBasedOnTargetColorTheme,
27
28
  } from './color.util';
28
29
  import chroma from 'chroma-js';
29
30
 
@@ -70,34 +71,49 @@ export const colorMatchCssKeyValue = (
70
71
  cssKey: string,
71
72
  cssValue: string,
72
73
  logoTheme: LogoTheme,
74
+ applyColorWithMatchingLuminance?: {
75
+ originalColor: string;
76
+ },
73
77
  ): { cssValue: string; isModified: boolean } => {
74
- switch (cssValue) {
75
- case STYLE_THEME_KEYS.LogoBackgroundColor:
76
- cssValue = getColorValueForCorrectCssProperty(
77
- cssKey,
78
- logoTheme.logoBackgroundColor,
79
- );
78
+ if (applyColorWithMatchingLuminance?.originalColor) {
79
+ const styleThemeMatch = Object.values(STYLE_THEME_KEYS).find(
80
+ (k) => cssValue === k,
81
+ );
80
82
 
81
- return { cssValue, isModified: true };
82
- case STYLE_THEME_KEYS.LogoTextColor:
83
- cssValue = getColorValueForCorrectCssProperty(
84
- cssKey,
85
- logoTheme.logoTextColor,
86
- );
83
+ if (styleThemeMatch) {
84
+ const theme = styleThemeMatch.startsWith(STYLE_THEME_KEYS.LogoTextColor)
85
+ ? logoTheme.logoTextColor
86
+ : logoTheme.logoBackgroundColor;
87
+
88
+ let newColor = applyColorWithMatchingLuminance.originalColor;
87
89
 
88
- return { cssValue, isModified: true };
90
+ try {
91
+ newColor = getNewColorBasedOnTargetColorTheme(
92
+ applyColorWithMatchingLuminance.originalColor,
93
+ theme.rgb,
94
+ )!.toString();
95
+ } catch (e) {}
96
+
97
+ return { cssValue: newColor, isModified: true };
98
+ }
89
99
  }
90
100
 
91
- const match = Object.values(STYLE_THEME_KEYS).find((k) => cssValue === k);
101
+ if (cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoTextColor, 'g'))) {
102
+ cssValue = getColorValueForCorrectCssProperty(
103
+ cssKey,
104
+ logoTheme.logoTextColor,
105
+ );
92
106
 
93
- if (match) {
94
- const split = match.split('-');
95
- const colorShadeKey = split[split.length - 1];
96
- const colorKey = match.startsWith(STYLE_THEME_KEYS.LogoBackgroundColor)
97
- ? logoTheme.logoBackgroundColor
98
- : logoTheme.logoTextColor;
107
+ return { cssValue, isModified: true };
108
+ } else if (
109
+ cssValue.match(new RegExp(STYLE_THEME_KEYS.LogoBackgroundColor, 'g'))
110
+ ) {
111
+ cssValue = getColorValueForCorrectCssProperty(
112
+ cssKey,
113
+ logoTheme.logoBackgroundColor,
114
+ );
99
115
 
100
- return { cssValue: colorKey[colorShadeKey], isModified: true };
116
+ return { cssValue, isModified: true };
101
117
  }
102
118
 
103
119
  return { cssValue, isModified: false };
@@ -107,7 +123,11 @@ type Style = Record<string, string | any>;
107
123
 
108
124
  export const applyLogoThemeToBrandPageStyleRecursive = (
109
125
  logoTheme: LogoTheme,
126
+ attribute: string,
110
127
  style: Style | Style[],
128
+ options?: {
129
+ isMultiColorShape: boolean;
130
+ },
111
131
  ): {
112
132
  newStyle: Style | Style[];
113
133
  isApplied: boolean;
@@ -117,7 +137,23 @@ export const applyLogoThemeToBrandPageStyleRecursive = (
117
137
 
118
138
  if (Array.isArray(style)) {
119
139
  newStyle = style.map((s: Style) => {
120
- const output = applyLogoThemeToBrandPageStyleRecursive(logoTheme, s);
140
+ const isShapeColorReplacement = attribute === 'colorReplacements';
141
+
142
+ const output = applyLogoThemeToBrandPageStyleRecursive(
143
+ logoTheme,
144
+ attribute,
145
+ s,
146
+ isShapeColorReplacement
147
+ ? {
148
+ isMultiColorShape:
149
+ style.filter(
150
+ (x) =>
151
+ x.originalColor.toLowerCase() !== '' &&
152
+ x.originalColor.toLowerCase() !== 'none',
153
+ ).length > 1,
154
+ }
155
+ : undefined,
156
+ );
121
157
 
122
158
  isApplied = isApplied || output.isApplied;
123
159
 
@@ -126,13 +162,26 @@ export const applyLogoThemeToBrandPageStyleRecursive = (
126
162
  } else if (style && typeof style === 'object') {
127
163
  for (const [key, value] of Object.entries(style)) {
128
164
  if (typeof value === 'string') {
129
- const output = colorMatchCssKeyValue(key, value, logoTheme);
165
+ const applyColorWithMatchingLuminance =
166
+ options?.isMultiColorShape && key === `replacementColor`
167
+ ? {
168
+ originalColor: style[`originalColor`],
169
+ }
170
+ : undefined;
171
+
172
+ const output = colorMatchCssKeyValue(
173
+ key,
174
+ value,
175
+ logoTheme,
176
+ applyColorWithMatchingLuminance,
177
+ );
130
178
 
131
179
  newStyle[key] = output.cssValue;
132
180
  isApplied = isApplied || output.isModified;
133
181
  } else if (typeof value === 'object') {
134
182
  const output = applyLogoThemeToBrandPageStyleRecursive(
135
183
  logoTheme,
184
+ key,
136
185
  value as Style,
137
186
  );
138
187
 
@@ -207,7 +256,11 @@ export const applyLogoThemeToBrandPageNavigationStyles = (
207
256
  if (typeof value === 'string' || typeof value === 'boolean') {
208
257
  newNavigation[key] = value;
209
258
  } else {
210
- const output = applyLogoThemeToBrandPageStyleRecursive(logoTheme, value);
259
+ const output = applyLogoThemeToBrandPageStyleRecursive(
260
+ logoTheme,
261
+ key,
262
+ value,
263
+ );
211
264
 
212
265
  newNavigation[key] = output.newStyle;
213
266
  isModified = isModified || output.isApplied;
@@ -246,7 +299,11 @@ export const applyLogoThemeToBrandPageHeaderStyles = (
246
299
  ) {
247
300
  newPageHeader[key] = value;
248
301
  } else {
249
- const output = applyLogoThemeToBrandPageStyleRecursive(logoTheme, value);
302
+ const output = applyLogoThemeToBrandPageStyleRecursive(
303
+ logoTheme,
304
+ key,
305
+ value,
306
+ );
250
307
 
251
308
  newPageHeader[key] = output.newStyle;
252
309
  isModified = isModified || output.isApplied;
@@ -284,7 +341,11 @@ export const applyLogoThemeToBrandPageFooterStyles = (
284
341
  ) {
285
342
  newPageFooter[key] = value;
286
343
  } else {
287
- const output = applyLogoThemeToBrandPageStyleRecursive(logoTheme, value);
344
+ const output = applyLogoThemeToBrandPageStyleRecursive(
345
+ logoTheme,
346
+ key,
347
+ value,
348
+ );
288
349
 
289
350
  newPageFooter[key] = output.newStyle;
290
351
  isModified = isModified || output.isApplied;
@@ -323,6 +384,7 @@ export const applyLogoThemeToContents = (
323
384
  for (const styleKey of styleKeys) {
324
385
  const { newStyle, isApplied } = applyLogoThemeToBrandPageStyleRecursive(
325
386
  logoTheme,
387
+ styleKey,
326
388
  content[styleKey],
327
389
  );
328
390
 
@@ -351,6 +413,7 @@ export const applyLogoThemeToBrandPageStyles = (
351
413
  for (let i = 0; i < value.length; i++) {
352
414
  const output = applyLogoThemeToBrandPageStyleRecursive(
353
415
  logoTheme,
416
+ `pageStyles`,
354
417
  value[i],
355
418
  );
356
419
 
@@ -358,7 +421,11 @@ export const applyLogoThemeToBrandPageStyles = (
358
421
  isModified = isModified || output.isApplied;
359
422
  }
360
423
  } else {
361
- const output = applyLogoThemeToBrandPageStyleRecursive(logoTheme, value);
424
+ const output = applyLogoThemeToBrandPageStyleRecursive(
425
+ logoTheme,
426
+ key,
427
+ value,
428
+ );
362
429
 
363
430
  newStyle[key] = output.newStyle;
364
431
  isModified = isModified || output.isApplied;
@@ -25,11 +25,12 @@ export default defineComponent({
25
25
  props: {
26
26
  id: {
27
27
  type: String,
28
- required: true,
28
+ required: false,
29
+ default: '',
29
30
  },
30
31
  isToggled: {
31
32
  type: Boolean,
32
- required: true,
33
+ required: false,
33
34
  },
34
35
  name: {
35
36
  type: String,
@@ -12,7 +12,9 @@
12
12
  >{{ label }}
13
13
  </span>
14
14
  <Toggle
15
- v-if="isAdmin && colorReplacements && colorReplacements.length > 0"
15
+ v-if="
16
+ isAdmin && data.colorReplacements && data.colorReplacements.length > 0
17
+ "
16
18
  :id="`${id}-${name}-color-matched${toggleIdSuffix}`"
17
19
  :model-value="isOptionColorMatched"
18
20
  color="info"
@@ -21,11 +23,14 @@
21
23
  @update:model-value="onColorMatchToggled"
22
24
  />
23
25
  <div
24
- class="tw-flex tw-flex-wrap tw-gap-2"
25
- :class="{ 'tw-flex-col': isOptionColorMatched }"
26
+ class="tw-flex tw-flex-wrap"
27
+ :class="{
28
+ 'tw-flex-col': isOptionColorMatched,
29
+ 'tw-gap-2': !isOptionColorMatched,
30
+ }"
26
31
  >
27
32
  <div
28
- v-for="(colorReplacement, index) in colorReplacements"
33
+ v-for="(colorReplacement, index) in data.colorReplacements"
29
34
  :key="`${colorReplacement.attribute}-${colorReplacement.originalColor}`"
30
35
  >
31
36
  <ColorField
@@ -37,47 +42,131 @@
37
42
  :logo-theme="logoTheme"
38
43
  @update:model-value="onColorPickerInput($event, index)"
39
44
  />
40
- <!-- Start Admin Style Theme Key Select -->
41
- <div v-else class="tw-flex tw-gap-2 tw-items-center">
42
- <div
43
- class="tw-w-4 tw-h-4 tw-rounded tw-border tw-border-solid tw-border-grayscale-500"
44
- :style="{ backgroundColor: colorReplacement.originalColor }"
45
- />
46
- <select
47
- class="c-select c-button-style tw-flex-grow tw-border tw-appearance-none tw-border-none tw-h-10 tw-pl-2 tw-rounded tw-cursor-pointer tw-transition-all tw-duration-300 tw-bg-white"
48
- @change.stop="
49
- onColorPickerInputDropdown($event.target.value, index)
50
- "
45
+ </div>
46
+ <div
47
+ v-if="
48
+ isAdmin &&
49
+ data.colorReplacements &&
50
+ data.colorReplacements.length > 0 &&
51
+ isOptionColorMatched
52
+ "
53
+ >
54
+ <select
55
+ class="c-select c-button-style tw-flex-grow tw-border tw-appearance-none tw-border-none tw-h-10 tw-pl-2 tw-rounded tw-cursor-pointer tw-transition-all tw-duration-300 tw-bg-white"
56
+ @change.stop="
57
+ onColorPickerInputDropdown(($event!.target as any).value)
58
+ "
59
+ >
60
+ <option
61
+ v-for="(styleThemeKey, styleKeyThemeIndex) in data.styleThemeKeys"
62
+ :key="styleKeyThemeIndex"
63
+ :value="styleThemeKey"
64
+ :selected="styleThemeKey === selectedColor"
51
65
  >
52
- <option
53
- v-for="(styleThemeKey, styleKeyThemeIndex) in styleThemeKeys"
54
- :key="styleKeyThemeIndex"
55
- :value="styleThemeKey"
56
- :selected="
57
- styleThemeKey === colorReplacement.replacementColor
58
- ? 'selected'
59
- : null
60
- "
61
- >
62
- {{ styleThemeKey }}
63
- </option>
64
- </select>
65
- </div>
66
- <!-- End Admin Style Theme Key Select -->
66
+ {{ styleThemeKey }}
67
+ </option>
68
+ </select>
67
69
  </div>
68
70
  </div>
69
71
  </div>
70
72
  </template>
71
- <script>
73
+ <script setup lang="ts">
72
74
  import { Toggle } from '@designcrowd/fe-shared-lib';
73
- import ColorReplacementsFieldMixin from './ColorReplacementsField.mixin.ts';
74
75
  import ColorField from '../../../content-settings/components/color-field/ColorField.vue';
76
+ import type { ColorReplacement, LogoTheme } from '../../../../brand-page';
77
+ import { reactive, watch, computed } from 'vue';
78
+ import { STYLE_THEME_KEYS } from '../../../../brand-page/constants';
79
+ import cloneDeep from 'lodash.clonedeep';
80
+ import debounce from 'lodash.debounce';
81
+ import { isColorMatched } from '../../../../brand-page-maker/utils';
82
+ import type { DebounceHandle } from 'lodash.debounce';
83
+ import type { UpdateItemValuePayload } from '../../../content-settings/models';
84
+
85
+ const DEBOUNCE_WAIT_IN_MS = 10;
86
+
87
+ const props = defineProps<{
88
+ id: string;
89
+ name: string;
90
+ value: ColorReplacement[];
91
+ isAdmin: boolean;
92
+ label?: string;
93
+ toggleUniqueId?: string;
94
+ logoTheme: LogoTheme;
95
+ }>();
75
96
 
76
- export default {
77
- components: {
78
- Toggle,
79
- ColorField,
97
+ const emit = defineEmits(['update:modelValue']);
98
+
99
+ const changeColor = () => {
100
+ emit('update:modelValue', {
101
+ id: props.id,
102
+ name: props.name,
103
+ value: data.colorReplacements,
104
+ });
105
+ };
106
+
107
+ const data = reactive<{
108
+ colorReplacements: ColorReplacement[];
109
+ changeColorDebounce: DebounceHandle;
110
+ styleThemeKeys: typeof STYLE_THEME_KEYS;
111
+ }>({
112
+ colorReplacements: cloneDeep(props.value),
113
+ changeColorDebounce: debounce(changeColor, DEBOUNCE_WAIT_IN_MS),
114
+ styleThemeKeys: STYLE_THEME_KEYS,
115
+ });
116
+
117
+ watch(
118
+ () => props.value,
119
+ (newVal: ColorReplacement[]) => {
120
+ data.colorReplacements = cloneDeep(newVal);
80
121
  },
81
- mixins: [ColorReplacementsFieldMixin],
122
+ );
123
+
124
+ const selectedColor = computed(
125
+ () => data.colorReplacements[0]?.replacementColor,
126
+ );
127
+
128
+ const isOptionColorMatched = computed(() =>
129
+ data.colorReplacements?.every((x) => isColorMatched(x.replacementColor)),
130
+ );
131
+
132
+ const toggleIdSuffix = computed(() =>
133
+ props.toggleUniqueId ? `-${props.toggleUniqueId}` : '',
134
+ );
135
+
136
+ const onColorPickerInput = (
137
+ color: UpdateItemValuePayload<string>,
138
+ index: number,
139
+ ) => {
140
+ if (color) {
141
+ if (typeof color.value === 'string') {
142
+ data.colorReplacements[index].replacementColor = color.value;
143
+ }
144
+ }
145
+
146
+ data.changeColorDebounce();
147
+ };
148
+
149
+ const onColorPickerInputDropdown = (color: string) => {
150
+ if (typeof color === 'string') {
151
+ data.colorReplacements.forEach((c) => {
152
+ c.replacementColor = color;
153
+ });
154
+ }
155
+
156
+ data.changeColorDebounce();
157
+ };
158
+
159
+ const onColorMatchToggled = (value: boolean) => {
160
+ if (value) {
161
+ data.colorReplacements.forEach((x) => {
162
+ x.replacementColor = STYLE_THEME_KEYS.LogoTextColor;
163
+ });
164
+ } else {
165
+ data.colorReplacements.forEach((x) => {
166
+ x.replacementColor = x.originalColor;
167
+ });
168
+ }
169
+
170
+ data.changeColorDebounce();
82
171
  };
83
172
  </script>