@designcrowd/fe-shared-lib 1.2.1-rr-7 → 1.2.2-ast-disabled-1

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 (31) hide show
  1. package/Dockerfile +2 -0
  2. package/index.js +2 -0
  3. package/nodemon.translation.json +7 -0
  4. package/package.json +7 -2
  5. package/{dist → public}/css/tailwind-brandCrowd.css +510 -592
  6. package/{dist → public}/css/tailwind-brandPage.css +434 -512
  7. package/{dist → public}/css/tailwind-crazyDomains.css +510 -592
  8. package/{dist → public}/css/tailwind-designCom.css +510 -592
  9. package/{dist → public}/css/tailwind-designCrowd.css +510 -592
  10. package/src/atoms/components/ButtonGroup/ButtonGroup.stories.js +1 -0
  11. package/src/atoms/components/ButtonGroup/ButtonGroup.vue +24 -12
  12. package/src/atoms/components/FormControl/FormControl.mixin.js +1 -10
  13. package/src/atoms/components/Icon/Icon.vue +3 -3
  14. package/src/atoms/components/TextInput/TextInput.vue +1 -5
  15. package/src/bundleTranslation.js +89 -0
  16. package/src/bundles/bundled-translations.de-DE.json +5 -0
  17. package/src/bundles/bundled-translations.es-ES.json +5 -0
  18. package/src/bundles/bundled-translations.fr-FR.json +5 -0
  19. package/src/bundles/bundled-translations.json +5 -0
  20. package/src/bundles/bundled-translations.pt-PT.json +5 -0
  21. package/src/experiences/components/PaymentConfigList/PaymentConfig.mixin.js +1 -1
  22. package/src/experiences/components/PublishBrandPageModal/PublishBrandPageModal.vue +22 -9
  23. package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.de-DE.json +5 -0
  24. package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.es-ES.json +5 -0
  25. package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.fr-FR.json +5 -0
  26. package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.json +5 -0
  27. package/src/experiences/components/PublishBrandPageModal/i18n/publish-modal.pt-PT.json +5 -0
  28. package/src/experiences/components/SellDomainNameList/SellDomainNameList.vue +1 -0
  29. package/src/experiences/components/SellDomainNameSearchResult/SellDomainNameListSearchResult.vue +4 -0
  30. package/src/experiences/components/SellDomainNameSearchWithResults/SellDomainNameSearchWithResults.vue +4 -0
  31. package/src/useSharedLibTranslate.js +38 -0
@@ -21,6 +21,7 @@ export const Sample = () => {
21
21
  {
22
22
  label: 'Medium',
23
23
  value: 'medium',
24
+ disabled: true,
24
25
  },
25
26
  {
26
27
  label: 'Large',
@@ -10,11 +10,14 @@
10
10
  <button
11
11
  class="button-group-item tw-text-xs tw-shadow-inner tw-w-full tw-py-2"
12
12
  :class="{
13
- '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
14
- '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200 hover:!tw-shadow-info-500': !option.isSelected,
13
+ '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
14
+ '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
15
+ 'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
16
+ 'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
15
17
  }"
18
+ :disabled="option.disabled"
16
19
  v-bind="option.dataAttribute ? { [option.dataAttribute]: '' } : {}"
17
- @click="$emit('on-select', option)"
20
+ @click="!option.disabled && $emit('on-select', option)"
18
21
  >
19
22
  <slot name="content" :option="option"></slot>
20
23
  </button>
@@ -35,8 +38,10 @@
35
38
  <button
36
39
  v-if="variant === 'icon'"
37
40
  :class="{
38
- '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
39
- '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200 hover:!tw-shadow-info-500': !option.isSelected,
41
+ '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
42
+ '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
43
+ 'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
44
+ 'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
40
45
  'tw-px-2': !option.iconViewBox,
41
46
  'tw-px-px':
42
47
  option.iconViewBox && !option.isSelected && !option.iconName.includes('display-style') && btnStyleVariant, // TODO - move style logic to computed prop
@@ -45,9 +50,10 @@
45
50
  'tw-px-0 tw-py-0': option.iconName.includes('display-style') || btnStyleVariant === 'compressed',
46
51
  }"
47
52
  :style="option.iconName.includes('display-style') ? { lineHeight: 0 } : {}"
53
+ :disabled="option.disabled"
48
54
  class="tw-text-xs button-group-icon-button tw-shadow-inner"
49
55
  v-bind="option.dataAttribute ? { [option.dataAttribute]: '' } : {}"
50
- @click="$emit('on-select', option)"
56
+ @click="!option.disabled && $emit('on-select', option)"
51
57
  >
52
58
  <div
53
59
  :class="{
@@ -67,12 +73,15 @@
67
73
  <button
68
74
  v-else
69
75
  :class="{
70
- '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
71
- '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200 hover:!tw-shadow-info-500': !option.isSelected,
76
+ '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
77
+ '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
78
+ 'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
79
+ 'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
72
80
  }"
81
+ :disabled="option.disabled"
73
82
  class="tw-text-xs button-group-image-button tw-shadow-inner"
74
83
  v-bind="option.dataAttribute ? { [option.dataAttribute]: '' } : {}"
75
- @click="$emit('on-select', option)"
84
+ @click="!option.disabled && $emit('on-select', option)"
76
85
  >
77
86
  <img :src="option.src" :alt="option.alt" class="tw-w-full tw-h-full" />
78
87
  </button>
@@ -90,11 +99,14 @@
90
99
  :key="`button-${option.value}`"
91
100
  :class="{
92
101
  'tw-ml-2': idx > 0 && !columns,
93
- '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected,
94
- '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200 hover:!tw-shadow-info-500': !option.isSelected,
102
+ '!tw-shadow-[0_0_0_2px] !tw-shadow-info-500': option.isSelected && !option.disabled,
103
+ '!tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': !option.isSelected && !option.disabled,
104
+ 'hover:!tw-shadow-info-500': !option.isSelected && !option.disabled,
105
+ 'tw-opacity-50 !tw-cursor-not-allowed !tw-shadow-[0_0_0_1px] !tw-shadow-secondary-200': option.disabled,
95
106
  }"
107
+ :disabled="option.disabled"
96
108
  class="tw-text-xs button-group-button tw-shadow-inner"
97
- @click="$emit('on-select', option)"
109
+ @click="!option.disabled && $emit('on-select', option)"
98
110
  >
99
111
  {{ option.label }}
100
112
  </button>
@@ -97,20 +97,11 @@ export default {
97
97
  required: false,
98
98
  default: false,
99
99
  },
100
- requiredMessage: {
101
- type: String,
102
- required: false,
103
- default: 'Please fill in this field.',
104
- },
105
100
  },
106
101
  methods: {
107
- input(modelValue, event) {
102
+ input(modelValue) {
108
103
  this.$emit('update:modelValue', modelValue);
109
104
  this.$emit('input', modelValue);
110
-
111
- if (event?.target) {
112
- event.target.setCustomValidity('');
113
- }
114
105
  },
115
106
  keyup(modelValue) {
116
107
  this.$emit('keyup', modelValue);
@@ -20,8 +20,8 @@
20
20
  aria-labelledby="title"
21
21
  aria-describedby="desc"
22
22
  >
23
- <title :id="`${name}-${id}-title`" lang="en">{{ title }}</title>
24
- <desc :id="`${name}-${id}-desc`" lang="en">{{ description }}</desc>
23
+ <title v-if="title" :id="`${name}-${id}-title`" lang="en">{{ title }}</title>
24
+ <desc v-if="description" :id="`${name}-${id}-desc`" lang="en">{{ description }}</desc>
25
25
  <component :is="`icon-${iconName}`"></component>
26
26
  </svg>
27
27
  </div>
@@ -799,7 +799,7 @@ export default {
799
799
  return css || null;
800
800
  },
801
801
  title() {
802
- return this.altText || `${this.titleCase(this.name)}`;
802
+ return this.altText;
803
803
  },
804
804
  description() {
805
805
  return `${this.title} Icon`;
@@ -73,8 +73,7 @@
73
73
  },
74
74
  ]"
75
75
  class="tw-text-grayscale-600 tw-box-border tw-w-full tw-text-base tw-px-4 tw-border tw-border-solid focus:tw-outline-none tw-transition-colors tw-duration-300 tw-ease-out tw-shadow-inner"
76
- @invalid="setValidationMessage"
77
- @input.stop="input($event.target.value, $event)"
76
+ @input.stop="input($event.target.value)"
78
77
  @keyup.stop="keyup($event.target.value)"
79
78
  @keydown.stop="keydown($event.target.value, $event)"
80
79
  @focus="focus($event.target.value)"
@@ -152,9 +151,6 @@ export default {
152
151
  this.$emit('on-clear-confirmation');
153
152
  }
154
153
  },
155
- setValidationMessage(event) {
156
- event.target.setCustomValidity(this.requiredMessage);
157
- },
158
154
  },
159
155
  };
160
156
  </script>
@@ -0,0 +1,89 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+
4
+ const localeSuffixes = ['.de-DE', '.fr-FR', '.es-ES', '.pt-PT', ''];
5
+
6
+ const findTranslationFiles = (dir, localeString) => {
7
+ const files = [];
8
+ const entries = fs.readdirSync(dir);
9
+
10
+ entries.forEach((entry) => {
11
+ const fullPath = path.join(dir, entry);
12
+
13
+ if (fs.statSync(fullPath).isDirectory()) {
14
+ if (entry === 'i18n') {
15
+ files.push(
16
+ ...fs
17
+ .readdirSync(fullPath)
18
+ .filter((file) => {
19
+ if (localeString === '') {
20
+ return (
21
+ !file.includes('.de-DE') &&
22
+ !file.includes('.fr-FR') &&
23
+ !file.includes('.es-ES') &&
24
+ !file.includes('.pt-PT')
25
+ );
26
+ }
27
+ return file.endsWith(`${localeString}.json`);
28
+ })
29
+ .map((file) => path.join(fullPath, file)),
30
+ );
31
+ } else {
32
+ // Recursively find translation files in nested folders
33
+ files.push(...findTranslationFiles(fullPath, localeString));
34
+ }
35
+ }
36
+ });
37
+
38
+ return files;
39
+ };
40
+
41
+ const bundle = () => {
42
+ console.log('Bundling translations...', __dirname);
43
+
44
+ const bundlesDir = path.resolve(__dirname, './bundles');
45
+
46
+ console.log('bundlesDir', bundlesDir);
47
+
48
+ if (!fs.existsSync(bundlesDir)) {
49
+ console.log('Creating bundles dir');
50
+ fs.mkdirSync(bundlesDir);
51
+ }
52
+
53
+ const rootDir = path.resolve(__dirname, '../src');
54
+
55
+ localeSuffixes.forEach((locale) => {
56
+ const outputFile = path.resolve(bundlesDir, `bundled-translations${locale}.json`);
57
+
58
+ const translationFiles = findTranslationFiles(rootDir, locale);
59
+
60
+ console.log(
61
+ `Found ${translationFiles.length} translation files in BrandPage for file prefix: ${`bundled-translations${locale}.json`}`,
62
+ );
63
+
64
+ const translations = {};
65
+
66
+ translationFiles.forEach((file) => {
67
+ const fileContent = fs.readFileSync(file, 'utf-8');
68
+
69
+ Object.assign(translations, JSON.parse(fileContent));
70
+ });
71
+
72
+ console.log(`Writing bundled translations to: ${outputFile}`);
73
+
74
+ try {
75
+ const potentiallyExistingFile = fs.readFileSync(outputFile, 'utf-8');
76
+
77
+ if (potentiallyExistingFile === JSON.stringify(translations, null, 2)) {
78
+ console.log('Current translations are the same as the existing file - skipping write');
79
+ } else {
80
+ fs.writeFileSync(outputFile, JSON.stringify(translations, null, 2));
81
+ }
82
+ } catch (e) {
83
+ console.log("Translation file doesn't exist, creating new one");
84
+ fs.writeFileSync(outputFile, JSON.stringify(translations, null, 2));
85
+ }
86
+ });
87
+ };
88
+
89
+ bundle();
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "DE-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "ES-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "FR-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "EN-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "PT-Publish Brand Page"
4
+ }
5
+ }
@@ -1,5 +1,5 @@
1
- import brandPageApiClient from '../../clients/brand-page-api.client';
2
1
  import vClickOutside from 'click-outside-vue3';
2
+ import brandPageApiClient from '../../clients/brand-page-api.client';
3
3
 
4
4
  export const paymentConfigStatuses = Object.freeze({
5
5
  active: 'Active',
@@ -50,7 +50,7 @@
50
50
  <div v-if="isNotPublished || isSlugEditMode" class="tw-mt-4">
51
51
  <PublishBrandPageCard
52
52
  v-if="!hasPurchasedDomains"
53
- :imgUrl="iconUrl"
53
+ :img-url="iconUrl"
54
54
  title="Free Address"
55
55
  description="Choose a free address to publish now. You can always edit the URL later"
56
56
  :is-design-com="isDesignCom"
@@ -84,11 +84,11 @@
84
84
  data-test-brand-page-publish-button
85
85
  variant="primary"
86
86
  size="small-medium"
87
- @on-click="onPublish"
88
87
  :full-width="isMobile"
89
88
  :class="{
90
89
  'tw-uppercase': !isDesignCom,
91
90
  }"
91
+ @on-click="onPublish"
92
92
  />
93
93
  </div>
94
94
  </template>
@@ -196,6 +196,7 @@
196
196
  :display-result-limit="4"
197
197
  :domain-search-location="sitePublishedModal"
198
198
  @on-change-search="onSearchTextChanged"
199
+ @on-buy-now-click="onBuyNowClick"
199
200
  />
200
201
  </div>
201
202
  <Button
@@ -245,19 +246,21 @@
245
246
  </div>
246
247
  </template>
247
248
  <script>
248
- import Modal from '../../../../src/atoms/components/Modal/Modal.vue';
249
+ import { computed } from 'vue';
250
+ import Modal from '../../../atoms/components/Modal/Modal.vue';
249
251
  import PublishBrandPageCard from './PublishBrandPageCard.vue';
250
- import TextInput from '../../../../src/atoms/components/TextInput/TextInput.vue';
251
- import Dropdown from '../../../../src/atoms/components/Dropdown/Dropdown.vue';
252
- import DropdownItem from '../../../../src/atoms/components/Dropdown/DropdownItem.vue';
253
- import Button from '../../../../src/atoms/components/Button/Button.vue';
254
- import TextCopyField from '../../../../src/atoms/components/TextCopyField/TextCopyField.vue';
252
+ import TextInput from '../../../atoms/components/TextInput/TextInput.vue';
253
+ import Dropdown from '../../../atoms/components/Dropdown/Dropdown.vue';
254
+ import DropdownItem from '../../../atoms/components/Dropdown/DropdownItem.vue';
255
+ import Button from '../../../atoms/components/Button/Button.vue';
256
+ import TextCopyField from '../../../atoms/components/TextCopyField/TextCopyField.vue';
255
257
 
256
258
  import SellDomainNameSearchWithResults from '../SellDomainNameSearchWithResults/SellDomainNameSearchWithResults.vue';
257
259
  import SellDomainNameListModal from '../SellDomainNameListModal/SellDomainNameListModal.vue';
258
260
  import brandCrowdApiClient from '../../clients/brand-crowd-api.client';
259
261
  import Events, { sitePublishedModal } from '../../constants/event-constants';
260
262
  import mediaQueryMixin from '../../mixins/mediaQueryMixin';
263
+ import { tr } from '../../../useSharedLibTranslate';
261
264
 
262
265
  const headerSubtitle = 'Buy matching domain name for your brand';
263
266
 
@@ -412,6 +415,12 @@ export default {
412
415
  'on-view-more-domains',
413
416
  'on-slug-changed',
414
417
  ],
418
+ setup() {
419
+ return {
420
+ tr,
421
+ testMessage: computed(() => tr('publishModal.test')),
422
+ };
423
+ },
415
424
  data() {
416
425
  return {
417
426
  DOMAIN_TYPES,
@@ -489,7 +498,7 @@ export default {
489
498
  this.$emit('on-hide-domain-modal');
490
499
  },
491
500
  onCopyUrlClick() {
492
- this.$emit('copy-url-click');
501
+ this.$emit('copy-url-clicked');
493
502
  },
494
503
  onSlugChanged(e) {
495
504
  this.searchText = e;
@@ -509,6 +518,7 @@ export default {
509
518
  },
510
519
  onSearchTextChanged(val) {
511
520
  this.searchText = val;
521
+ this.$emit('on-change-search', val);
512
522
  },
513
523
  onSelectPurchasedDomain(newVal) {
514
524
  this.selectedCustomDomain = newVal;
@@ -524,6 +534,9 @@ export default {
524
534
  onSellDomainNameListCloseModal() {
525
535
  this.$emit('on-hide-domain-modal');
526
536
  },
537
+ onBuyNowClick() {
538
+ this.$emit('on-buy-now-clicked');
539
+ },
527
540
  async searchDomainName(isUserTriggered) {
528
541
  this.isLoading = true;
529
542
  let searchSlug = '';
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "DE-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "ES-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "FR-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "EN-Publish Brand Page"
4
+ }
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "publishModal": {
3
+ "test": "PT-Publish Brand Page"
4
+ }
5
+ }
@@ -114,6 +114,7 @@ export default {
114
114
  if (typeof this.domainSearchLocation !== 'undefined') {
115
115
  request.domainSearchLocation = this.domainSearchLocation;
116
116
  }
117
+ this.$emit('on-buy-now-click');
117
118
  window.dispatchEvent(
118
119
  new CustomEvent(Events.DomainSelectedEvent, {
119
120
  detail: request,
@@ -25,6 +25,7 @@
25
25
  :load-more-domains-button-text="loadMoreDomainsButtonText"
26
26
  :domain-search-location="domainSearchLocation"
27
27
  @load-more-domains="onLoadMoreDomains"
28
+ @on-buy-now-click="onBuyNowClick"
28
29
  />
29
30
  <div v-else-if="shouldShowDomainNameNotFound" class="tw-flex tw-justify-center tw-text-center">
30
31
  Sorry, we couldn't find any domain for "{{ previousSearchText }}".
@@ -145,6 +146,9 @@ export default {
145
146
  window.dispatchEvent(new CustomEvent(Events.DomainLoadMoreEvent));
146
147
  this.domainNameItemsInView += this.domainNameItemsPerPage;
147
148
  },
149
+ onBuyNowClick() {
150
+ this.$emit('on-buy-now-click');
151
+ },
148
152
  resetDomainNameItemsInView() {
149
153
  this.domainNameItemsInView = this.domainNameItemsPerPage;
150
154
  },
@@ -20,6 +20,7 @@
20
20
  :domain-name-items-per-page="domainNameItemsPerPage"
21
21
  :load-more-domains-button-text="loadMoreDomainsButtonText"
22
22
  :domain-search-location="domainSearchLocation"
23
+ @on-buy-now-click="onBuyNowClick"
23
24
  />
24
25
  </div>
25
26
  </template>
@@ -170,6 +171,9 @@ export default {
170
171
  this.isBusy = false;
171
172
  }
172
173
  },
174
+ onBuyNowClick() {
175
+ this.$emit('on-buy-now-click');
176
+ },
173
177
  cleanText(inputText) {
174
178
  // In this function, we use the Unicode property escapes \p{L} and \p{N} to match any Unicode letters (characters from various scripts) and Unicode numbers, respectively.
175
179
  const cleanedText = inputText.replace(/[^\p{L}\p{N}\-.]+/gu, '');
@@ -0,0 +1,38 @@
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
+ import i18next from 'i18next';
3
+
4
+ const fallbackLocale = 'en-US';
5
+
6
+ const relativePathsToTranslationFiles = {
7
+ 'en-US': () => import('./bundles/bundled-translations.json'),
8
+ 'de-DE': () => import('./bundles/bundled-translations.de-DE.json'),
9
+ 'fr-FR': () => import('./bundles/bundled-translations.fr-FR.json'),
10
+ 'es-ES': () => import('./bundles/bundled-translations.es-ES.json'),
11
+ 'pt-PT': () => import('./bundles/bundled-translations.pt-PT.json'),
12
+ };
13
+
14
+ const setLocaleAsync = async (locale = 'en-US') => {
15
+ const localeToUse = locale;
16
+
17
+ if (!i18next.isInitialized) {
18
+ await i18next.init({
19
+ debug: false,
20
+ fallbackLng: fallbackLocale,
21
+ lng: localeToUse,
22
+ });
23
+ }
24
+
25
+ const languageFile = (await relativePathsToTranslationFiles[localeToUse]()).default;
26
+
27
+ await i18next.addResourceBundle(localeToUse, 'fe-shared-lib', {
28
+ ...languageFile,
29
+ });
30
+ };
31
+
32
+ const tr = (key, valuesToInterpolate = {}) => {
33
+ const translated = i18next.t(key, { ns: 'fe-shared-lib', ...valuesToInterpolate });
34
+
35
+ return translated;
36
+ };
37
+
38
+ export { setLocaleAsync, tr };