@designcrowd/fe-shared-lib 1.6.0 → 1.6.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 (185) hide show
  1. package/.github/workflows/claude.yml +72 -0
  2. package/.storybook/main.ts +2 -5
  3. package/CLAUDE.md +78 -55
  4. package/dist/css/tailwind-brandCrowd.css +25 -4
  5. package/dist/css/tailwind-brandPage.css +16 -3
  6. package/dist/css/tailwind-crazyDomains.css +25 -4
  7. package/dist/css/tailwind-designCom.css +25 -4
  8. package/dist/css/tailwind-designCrowd.css +25 -4
  9. package/index.js +1 -0
  10. package/package.json +36 -32
  11. package/src/atoms/components/AiPoweredLoader/AiPoweredLoader.stories.js +364 -0
  12. package/src/atoms/components/AiPoweredLoader/AiPoweredLoader.vue +296 -0
  13. package/src/atoms/components/Button/variants/ButtonGray.vue +3 -3
  14. package/src/atoms/components/Carousel/Carousel.vue +7 -2
  15. package/src/atoms/components/Icon/Icon.stories.js +5 -7
  16. package/src/atoms/components/Icon/Icon.vue +25 -15
  17. package/src/atoms/components/Icon/icons/crown-alt.vue +5 -0
  18. package/src/atoms/components/Icon/icons/crown.vue +6 -0
  19. package/src/atoms/components/Icon/icons/home-outline.vue +6 -0
  20. package/src/atoms/components/Icon/icons/page-blank.vue +6 -0
  21. package/src/atoms/components/Icon/icons/question-alt.vue +20 -0
  22. package/src/atoms/components/Price/Price.stories.js +42 -21
  23. package/src/experiences/components/AuthFlow/SignIn.vue +10 -3
  24. package/src/experiences/components/AuthFlow/SignUp.vue +1 -1
  25. package/src/experiences/components/SideNavigationPanel/MenuCta.vue +62 -0
  26. package/src/experiences/components/SideNavigationPanel/MenuItem.vue +40 -0
  27. package/src/experiences/components/SideNavigationPanel/SideNavigationPanel.stories.js +219 -0
  28. package/src/experiences/components/SideNavigationPanel/SideNavigationPanel.vue +48 -0
  29. package/src/experiences/components/SideNavigationPanel/types.ts +7 -0
  30. package/src/experiences/components/UploadYourLogoApplication/UploadYourLogoApplication.vue +5 -3
  31. package/src/experiences/components/UploadYourLogoOnBoarding/LogoUploader.vue +8 -1
  32. package/src/experiences/components/UploadYourLogoOnBoarding/LogoUploadingLoader.vue +17 -0
  33. package/src/experiences/components/UploadYourLogoOnBoarding/UploadYourLogoOnBoarding.vue +10 -1
  34. package/src/experiences/components/WebsitesContextualUpgradeModal/WebsiteContextualUpgradeModal.vue +2 -2
  35. package/tailwind.config.js +1 -1
  36. package/vite.config.ts +4 -0
  37. package/.claude/settings.local.json +0 -56
  38. package/.storybook-static/assets/Auth-DT64t5h-.css +0 -1
  39. package/.storybook-static/assets/Auth.stories-C6eXcTSu.js +0 -490
  40. package/.storybook-static/assets/AuthCrazyDomains.stories-DGvEoWCa.js +0 -73
  41. package/.storybook-static/assets/Button-5UzSGUF6.css +0 -1
  42. package/.storybook-static/assets/Button-DKdQT6Fq.js +0 -1
  43. package/.storybook-static/assets/ButtonGroup-DDPXuhxR.css +0 -1
  44. package/.storybook-static/assets/ButtonGroup.stories-DlrYMRSk.js +0 -504
  45. package/.storybook-static/assets/ButtonPrimary-Bu6bXb_c.css +0 -1
  46. package/.storybook-static/assets/ButtonPrimary-BvWW6Duz.js +0 -1
  47. package/.storybook-static/assets/Buttons.stories-CKmd6hkZ.js +0 -761
  48. package/.storybook-static/assets/ButtonsCrazyDomains.stories-DdEuOUrn.js +0 -199
  49. package/.storybook-static/assets/Checkbox.mixin-DkHpdvGa.js +0 -1
  50. package/.storybook-static/assets/Checkbox.stories-DPBUC2Mx.js +0 -246
  51. package/.storybook-static/assets/Checktile.stories-ByaFwplD.js +0 -88
  52. package/.storybook-static/assets/CollapsiblePanel.stories-Y6q3gP9j.js +0 -56
  53. package/.storybook-static/assets/ColorPicker.stories-DdxPUB_R.js +0 -73
  54. package/.storybook-static/assets/CopyToClipboardText.stories-J9qndWxd.js +0 -32
  55. package/.storybook-static/assets/Dropdown.stories-1zKPATii.js +0 -159
  56. package/.storybook-static/assets/DropdownItem-BV-BdThU.css +0 -1
  57. package/.storybook-static/assets/DropdownItem-DA6TdpDb.js +0 -1
  58. package/.storybook-static/assets/FormControl.mixin-DcEBwrV3.js +0 -1
  59. package/.storybook-static/assets/HashRouteModal.stories-BGxvqE22.js +0 -60
  60. package/.storybook-static/assets/HelloBar-CYEZR2kQ.js +0 -1
  61. package/.storybook-static/assets/HelloBar.stories-597Kxj0W.js +0 -342
  62. package/.storybook-static/assets/Icon-C17LFvsP.js +0 -145
  63. package/.storybook-static/assets/Icon.stories-B9iAmcTU.js +0 -151
  64. package/.storybook-static/assets/Icon.stories-CR5vT9H7.js +0 -791
  65. package/.storybook-static/assets/Loader-BWGoT_xC.js +0 -1
  66. package/.storybook-static/assets/LogoBusinessBrandColours-CExzox1Z.js +0 -1
  67. package/.storybook-static/assets/LogoBusinessBrandColours-CeAaMKke.css +0 -1
  68. package/.storybook-static/assets/LogoBusinessBrandColours.stories-kuxAH8B8.js +0 -36
  69. package/.storybook-static/assets/Masonry-C2MNiGg0.css +0 -1
  70. package/.storybook-static/assets/Masonry.stories-CTXJLQ_i.js +0 -71
  71. package/.storybook-static/assets/Modal-CGwEIF5R.css +0 -1
  72. package/.storybook-static/assets/Modal-CydTNprT.js +0 -1
  73. package/.storybook-static/assets/Modal.stories-DZiG5NGM.js +0 -345
  74. package/.storybook-static/assets/Notice.stories-ChOj8CWm.js +0 -222
  75. package/.storybook-static/assets/NumberStepper-Blffv09R.css +0 -1
  76. package/.storybook-static/assets/NumberStepper.stories-CVbKJ_oJ.js +0 -64
  77. package/.storybook-static/assets/PaymentConfigList-BpUMV6cp.css +0 -1
  78. package/.storybook-static/assets/PaymentConfigList.stories-DUD7OZBS.js +0 -130
  79. package/.storybook-static/assets/Picture-B8m1I9xN.js +0 -1
  80. package/.storybook-static/assets/Picture.stories-MMzybhJ6.js +0 -119
  81. package/.storybook-static/assets/Pill-DLXZ_TL8.js +0 -1
  82. package/.storybook-static/assets/Pill.stories-DCP7szJm.js +0 -18
  83. package/.storybook-static/assets/PillBar-os4mJV3M.css +0 -1
  84. package/.storybook-static/assets/PillBar.stories-Bry-zQ6f.js +0 -41
  85. package/.storybook-static/assets/Price-C4GZbDSa.js +0 -1
  86. package/.storybook-static/assets/Price.stories-CMHly9V0.js +0 -337
  87. package/.storybook-static/assets/PromoCard.stories-xsbFtADE.js +0 -299
  88. package/.storybook-static/assets/PublishBrandPageModal-Q9-mNG1q.css +0 -1
  89. package/.storybook-static/assets/PublishBrandPageModal.stories-C9XzW_1m.js +0 -324
  90. package/.storybook-static/assets/SearchBar.stories-DaIneOSz.js +0 -12
  91. package/.storybook-static/assets/Select-DnioWQmi.css +0 -1
  92. package/.storybook-static/assets/Select.stories-BmGYB4pw.js +0 -108
  93. package/.storybook-static/assets/SellDomainNameList.fixtures-LC6fjr_b.js +0 -1
  94. package/.storybook-static/assets/SellDomainNameListModal-DH6khE10.css +0 -1
  95. package/.storybook-static/assets/SellDomainNameListModal-ymtVclFP.js +0 -1
  96. package/.storybook-static/assets/SellDomainNameListModal.stories-DvGvylgx.js +0 -71
  97. package/.storybook-static/assets/SellDomainNameListSearchResult-Cpxq0jDA.css +0 -1
  98. package/.storybook-static/assets/SellDomainNameListSearchResult-D-1CrQyf.js +0 -1
  99. package/.storybook-static/assets/SellDomainNameSearchWithResults-bX--zu97.js +0 -1
  100. package/.storybook-static/assets/SellDomainNameSearchWithResults.stories-DRUJjSdH.js +0 -37
  101. package/.storybook-static/assets/SellDomainNameWidget.stories-CC3LX10s.js +0 -36
  102. package/.storybook-static/assets/SignIn-CPjf8_2O.css +0 -1
  103. package/.storybook-static/assets/SignIn-DI0DSDFe.js +0 -1
  104. package/.storybook-static/assets/Slider-Cog2FFdj.css +0 -1
  105. package/.storybook-static/assets/Slider.stories-B2KGwnJy.js +0 -141
  106. package/.storybook-static/assets/SparkleIcon.stories-Dk904hVE.js +0 -547
  107. package/.storybook-static/assets/StarRating-BtKh7pzm.css +0 -1
  108. package/.storybook-static/assets/StarRating.stories-d2mgOuo2.js +0 -45
  109. package/.storybook-static/assets/TabMenu.stories-Cg2yenqj.js +0 -47
  110. package/.storybook-static/assets/TextCopyField-B66NKTk_.js +0 -1
  111. package/.storybook-static/assets/TextCopyField.stories-B4_ZlfLU.js +0 -47
  112. package/.storybook-static/assets/TextInput-CMoUjT_5.js +0 -1
  113. package/.storybook-static/assets/TextInput.stories-oyyxxf3j.js +0 -233
  114. package/.storybook-static/assets/Textarea.stories-BvhZR6K2.js +0 -207
  115. package/.storybook-static/assets/Toggle.stories-yT5-rL2k.js +0 -161
  116. package/.storybook-static/assets/Tooltip-DyXIgFQH.css +0 -1
  117. package/.storybook-static/assets/Tooltip-ZukyujG5.js +0 -1
  118. package/.storybook-static/assets/Tooltip.stories-sJFylRS_.js +0 -953
  119. package/.storybook-static/assets/UploadYourLogoApplication-Dmw8QcH3.css +0 -1
  120. package/.storybook-static/assets/UploadYourLogoApplication.stories-C9AvzHO_.js +0 -186
  121. package/.storybook-static/assets/UploadYourLogoDropzone-B1ffcicv.js +0 -24
  122. package/.storybook-static/assets/UploadYourLogoDropzone-DQqACf-e.css +0 -1
  123. package/.storybook-static/assets/UploadYourLogoDropzone.stories-D1Dt2ord.js +0 -55
  124. package/.storybook-static/assets/UploadedLogoSearchResultCard.stories-D8oF1Yrx.js +0 -79
  125. package/.storybook-static/assets/WebsiteContextualUpgradeModal-8u1zOZrW.css +0 -1
  126. package/.storybook-static/assets/WebsiteContextualUpgradeModal.stories-mtcvWOAg.js +0 -211
  127. package/.storybook-static/assets/_commonjsHelpers-CE1G-McA.js +0 -1
  128. package/.storybook-static/assets/_plugin-vue_export-helper-DlAUqK2U.js +0 -1
  129. package/.storybook-static/assets/api-lSJGRrF2.js +0 -1
  130. package/.storybook-static/assets/axe-DrS73Vi2.js +0 -20
  131. package/.storybook-static/assets/brand-crowd-api.client-D45NKshX.js +0 -1
  132. package/.storybook-static/assets/bundled-translations-BoWhEDU_.js +0 -1
  133. package/.storybook-static/assets/bundled-translations.de-DE-C4lqla4O.js +0 -1
  134. package/.storybook-static/assets/bundled-translations.es-ES-BxMIllUH.js +0 -1
  135. package/.storybook-static/assets/bundled-translations.fr-CA-MxZpyz0w.js +0 -1
  136. package/.storybook-static/assets/bundled-translations.fr-FR-N7UPCZVr.js +0 -1
  137. package/.storybook-static/assets/bundled-translations.pt-BR-C8tscYuG.js +0 -1
  138. package/.storybook-static/assets/bundled-translations.pt-PT-Dszj5Xfa.js +0 -1
  139. package/.storybook-static/assets/carousel-BelyIYOK.css +0 -1
  140. package/.storybook-static/assets/carousel.stories-CJw3-Iy6.js +0 -668
  141. package/.storybook-static/assets/event-constants-CMO9VQVu.js +0 -1
  142. package/.storybook-static/assets/iframe-B3A6OXQU.js +0 -1104
  143. package/.storybook-static/assets/index-B-eiLVzF.js +0 -7
  144. package/.storybook-static/assets/index-QquxUozE.js +0 -6
  145. package/.storybook-static/assets/matchers-5TDFFDYO-HJu_DfWo.js +0 -14
  146. package/.storybook-static/assets/mediaQueryMixin-CISNqd93.js +0 -1
  147. package/.storybook-static/assets/preload-helper-PPVm8Dsz.js +0 -1
  148. package/.storybook-static/assets/tracking-ATsLLehC.js +0 -1
  149. package/.storybook-static/css/tailwind-brandCrowd.css +0 -2508
  150. package/.storybook-static/css/tailwind-brandPage.css +0 -2188
  151. package/.storybook-static/css/tailwind-crazyDomains.css +0 -2508
  152. package/.storybook-static/css/tailwind-designCom.css +0 -2508
  153. package/.storybook-static/css/tailwind-designCrowd.css +0 -2508
  154. package/.storybook-static/favicon-wrapper.svg +0 -46
  155. package/.storybook-static/favicon.svg +0 -1
  156. package/.storybook-static/iframe.html +0 -713
  157. package/.storybook-static/index.html +0 -148
  158. package/.storybook-static/index.json +0 -1
  159. package/.storybook-static/nunito-sans-bold-italic.woff2 +0 -0
  160. package/.storybook-static/nunito-sans-bold.woff2 +0 -0
  161. package/.storybook-static/nunito-sans-italic.woff2 +0 -0
  162. package/.storybook-static/nunito-sans-regular.woff2 +0 -0
  163. package/.storybook-static/project.json +0 -1
  164. package/.storybook-static/sb-addons/a11y-1/manager-bundle.js +0 -57
  165. package/.storybook-static/sb-addons/links-2/manager-bundle.js +0 -3
  166. package/.storybook-static/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +0 -628
  167. package/.storybook-static/sb-addons/themes-3/manager-bundle.js +0 -3
  168. package/.storybook-static/sb-common-assets/favicon-wrapper.svg +0 -46
  169. package/.storybook-static/sb-common-assets/favicon.svg +0 -1
  170. package/.storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  171. package/.storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  172. package/.storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  173. package/.storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  174. package/.storybook-static/sb-manager/globals-runtime.js +0 -77935
  175. package/.storybook-static/sb-manager/globals.js +0 -24
  176. package/.storybook-static/sb-manager/manager-stores.js +0 -23
  177. package/.storybook-static/sb-manager/runtime.js +0 -20404
  178. package/.storybook-static/vite-inject-mocker-entry.js +0 -2
  179. package/docs/plans/2026-01-30-upgrade-vite7-storybook10-design.md +0 -177
  180. package/docs/plans/2026-01-30-upgrade-vite7-storybook10.md +0 -388
  181. package/public/css/tailwind-brandCrowd.css +0 -2508
  182. package/public/css/tailwind-brandPage.css +0 -2188
  183. package/public/css/tailwind-crazyDomains.css +0 -2508
  184. package/public/css/tailwind-designCom.css +0 -2508
  185. package/public/css/tailwind-designCrowd.css +0 -2508
@@ -1,9 +1,7 @@
1
- import Price from './Price.vue';
1
+ import { defineComponent } from 'vue';
2
+ import { setSharedLibLocaleAsync } from '../../../useSharedLibTranslate';
2
3
  import { currencies, locales } from './Price.fixtures';
3
- import { setSharedLibLocaleAsync } from "../../../useSharedLibTranslate";
4
- import { defineComponent } from "vue";
5
-
6
- await setSharedLibLocaleAsync();
4
+ import Price from './Price.vue';
7
5
 
8
6
  // noinspection JSUnusedGlobalSymbols
9
7
  export default {
@@ -11,7 +9,7 @@ export default {
11
9
  component: Price,
12
10
  args: {
13
11
  currencyName: currencies[0].name,
14
- locale: locales[0]
12
+ locale: locales[0],
15
13
  },
16
14
  argTypes: {
17
15
  amount: {
@@ -44,6 +42,9 @@ export const Sample = {
44
42
  return locales.find((x) => x === this.args.locale);
45
43
  },
46
44
  },
45
+ async mounted() {
46
+ await setSharedLibLocaleAsync();
47
+ },
47
48
  template: `
48
49
  <span>
49
50
  <price
@@ -76,6 +77,9 @@ export const WithFraction = {
76
77
  return locales.find((x) => x === this.args.locale);
77
78
  },
78
79
  },
80
+ async mounted() {
81
+ await setSharedLibLocaleAsync();
82
+ },
79
83
  template: `
80
84
  <span>
81
85
  <price
@@ -109,6 +113,9 @@ export const AlwaysShowFractionOn = {
109
113
  return locales.find((x) => x === this.args.locale);
110
114
  },
111
115
  },
116
+ async mounted() {
117
+ await setSharedLibLocaleAsync();
118
+ },
112
119
  template: `
113
120
  <span>
114
121
  <price
@@ -140,6 +147,9 @@ export const AlwaysShowFractionOff = {
140
147
  return currencies.find((x) => x.name === this.args.currencyName);
141
148
  },
142
149
  },
150
+ async mounted() {
151
+ await setSharedLibLocaleAsync();
152
+ },
143
153
  template: `
144
154
  <span>
145
155
  <price
@@ -174,6 +184,9 @@ export const WithSuffix = {
174
184
  return locales.find((x) => x === this.args.locale);
175
185
  },
176
186
  },
187
+ async mounted() {
188
+ await setSharedLibLocaleAsync();
189
+ },
177
190
  template: `
178
191
  <span>
179
192
  <price
@@ -210,6 +223,9 @@ export const WithLocale = {
210
223
  return locales.find((x) => x === this.args.locale);
211
224
  },
212
225
  },
226
+ async mounted() {
227
+ await setSharedLibLocaleAsync();
228
+ },
213
229
  template: `
214
230
  <span>
215
231
  <price
@@ -235,12 +251,17 @@ export const AllLocalesAndCurrencies = (args, { argTypes }) => {
235
251
  data() {
236
252
  const combos = new Array(locales.length).fill(0);
237
253
  combos.forEach((item, index) => {
238
- combos[index] = new Array(currencies.length).fill(0).map((item2, index2) => ({"locale": locales[index], "currency": currencies[index2]}));
239
- })
254
+ combos[index] = new Array(currencies.length)
255
+ .fill(0)
256
+ .map((item2, index2) => ({ locale: locales[index], currency: currencies[index2] }));
257
+ });
240
258
  return {
241
259
  variants: combos,
242
260
  };
243
261
  },
262
+ async mounted() {
263
+ await setSharedLibLocaleAsync();
264
+ },
244
265
  template: `
245
266
  <StorybookPriceComponent
246
267
  :variants="variants"/>
@@ -253,20 +274,20 @@ export const AllLocalesAndCurrencies = (args, { argTypes }) => {
253
274
  };
254
275
 
255
276
  const StorybookPriceComponent = defineComponent({
256
- components: {
257
- Price,
277
+ components: {
278
+ Price,
279
+ },
280
+ props: {
281
+ variants: {
282
+ type: Array,
283
+ required: true,
258
284
  },
259
- props: {
260
- variants: {
261
- type: Array,
262
- required: true,
263
- },
264
- showAbbreviation: {
265
- type: Boolean,
266
- default: false,
267
- },
285
+ showAbbreviation: {
286
+ type: Boolean,
287
+ default: false,
268
288
  },
269
- template: `
289
+ },
290
+ template: `
270
291
  <table class="tw-w-full">
271
292
  <thead>
272
293
  <tr>
@@ -289,4 +310,4 @@ const StorybookPriceComponent = defineComponent({
289
310
  </tbody>
290
311
  </table>
291
312
  `,
292
- });
313
+ });
@@ -52,9 +52,12 @@
52
52
  >
53
53
  {{ title }}
54
54
  </h2>
55
- <p v-if="description" class="tw-text-center tw-mb-6 tw-text-grayscale-600 tw-mt-0">
55
+ <p v-if="description && !resetPasswordDescription" class="tw-text-center tw-mb-6 tw-text-grayscale-600 tw-mt-0">
56
56
  {{ description }}
57
57
  </p>
58
+ <p v-if="resetPasswordDescription" class="tw-text-center tw-mb-6 tw-font-semibold tw-text-info-500 tw-mt-0">
59
+ {{ resetPasswordDescription }}
60
+ </p>
58
61
  <div class="tw-flex tw-flex-col">
59
62
  <div>
60
63
  <form id="signin" :action="getSignInAction" method="post" @submit="validate">
@@ -92,12 +95,13 @@
92
95
  <p v-if="capturePassword && !!passwordError" class="tw-text-error-500 tw-text-sm tw-text-left tw-mb-4">
93
96
  {{ passwordError }}
94
97
  </p>
95
- <p v-if="capturePassword" class="tw-w-full tw-text-left tw-mb-4">
98
+ <p v-if="capturePassword || resetPasswordDescription" class="tw-w-full tw-text-left tw-mb-4">
96
99
  <a class="tw-text-info-500 tw-cursor-pointer hover:tw-underline" @click="forgotPasswordClick()">
97
100
  {{ forgotPasswordLabel }}
98
101
  </a>
99
102
  </p>
100
103
  <SubmissionButton
104
+ v-if="!resetPasswordDescription"
101
105
  data-test-login-button
102
106
  variant="primary"
103
107
  size="medium"
@@ -254,9 +258,12 @@ export default {
254
258
  },
255
259
  capturePassword: {
256
260
  type: Boolean,
257
- required: false,
258
261
  default: true,
259
262
  },
263
+ resetPasswordDescription: {
264
+ type: String,
265
+ default: undefined,
266
+ },
260
267
  emailLoading: {
261
268
  type: Boolean,
262
269
  required: false,
@@ -228,7 +228,7 @@ export default {
228
228
  }
229
229
 
230
230
  const url = new URL(`https://${window.location.host}${this.recommendedActionLink}`);
231
- if (this.aUserName) {
231
+ if (this.aUserName && !url.searchParams.has('email')) {
232
232
  url.searchParams.append('email', this.aUserName);
233
233
  }
234
234
  return url?.toString();
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <component :is="componentTag" class="menu-item" :class="variantClasses" v-bind="componentAttrs" @click="handleClick">
3
+ <Icon v-if="icon" :name="icon" :size="iconSize" />
4
+ <span>{{ label }}</span>
5
+ </component>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ import { computed } from 'vue';
10
+ import Icon from '../../../atoms/components/Icon/Icon.vue';
11
+
12
+ type MenuCtaVariant = 'primary' | 'secondary' | 'empty';
13
+
14
+ interface MenuCtaProps {
15
+ label: string;
16
+ variant?: MenuCtaVariant;
17
+ icon?: string;
18
+ iconSize?: 'sm' | 'md' | 'lg';
19
+ url?: string;
20
+ action?: () => void;
21
+ }
22
+
23
+ const props = withDefaults(defineProps<MenuCtaProps>(), {
24
+ variant: 'primary',
25
+ iconSize: 'sm',
26
+ });
27
+
28
+ const emit = defineEmits<{
29
+ click: [event: MouseEvent];
30
+ }>();
31
+
32
+ const componentTag = computed(() => (props.action ? 'button' : 'a'));
33
+
34
+ const componentAttrs = computed(() => (props.action ? {} : { href: props.url }));
35
+
36
+ const variantClasses = computed(() => {
37
+ switch (props.variant) {
38
+ case 'primary':
39
+ return 'tw-bg-primary-500 tw-text-white hover:tw-bg-primary-700';
40
+ case 'secondary':
41
+ return 'tw-justify-center tw-bg-secondary-500 tw-text-white hover:tw-bg-secondary-700';
42
+ case 'empty':
43
+ return 'tw-justify-center tw-text-grayscale-700 hover:tw-bg-gray-600 tw-text-center';
44
+ default:
45
+ return '';
46
+ }
47
+ });
48
+
49
+ const handleClick = (event: MouseEvent) => {
50
+ if (props.action) {
51
+ props.action();
52
+ }
53
+ emit('click', event);
54
+ };
55
+ </script>
56
+
57
+ <style scoped>
58
+ .menu-item {
59
+ @apply tw-p-2 tw-flex tw-gap-2 tw-items-center tw-rounded-lg tw-font-normal tw-cursor-pointer;
60
+ height: 36px;
61
+ }
62
+ </style>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <component
3
+ :is="componentTag"
4
+ class="menu-item"
5
+ :class="{ 'tw-bg-grayscale-400': isActive, 'hover:tw-bg-grayscale-300': !isActive }"
6
+ v-bind="componentAttrs"
7
+ @click="handleClick"
8
+ >
9
+ <Icon class="icon" :name="icon" size="sm" />
10
+ <span class="tw-text-md tw-font-medium tw-text-grayscale-700">{{ label }}</span>
11
+ </component>
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+ import { computed } from 'vue';
16
+ import Icon from '../../../atoms/components/Icon/Icon.vue';
17
+ import type { IMenuItem } from './types';
18
+
19
+ const props = defineProps<IMenuItem>();
20
+
21
+ const componentTag = computed(() => (props.action ? 'button' : 'a'));
22
+
23
+ const componentAttrs = computed(() => (props.action ? {} : { href: props.url }));
24
+
25
+ const handleClick = () => {
26
+ if (props.action) {
27
+ props.action();
28
+ }
29
+ };
30
+ </script>
31
+
32
+ <style scoped>
33
+ .menu-item {
34
+ @apply tw-p-2 tw-mb-1 tw-flex tw-gap-2 tw-items-center tw-rounded-lg tw-cursor-pointer;
35
+ height: 36px;
36
+ }
37
+ .icon svg {
38
+ color: var(--text-secondary, rgba(61, 61, 61, 1));
39
+ }
40
+ </style>
@@ -0,0 +1,219 @@
1
+ import SideNavigationPanel from './SideNavigationPanel.vue';
2
+
3
+ export default {
4
+ title: 'Experiences/SideNavigationPanel',
5
+ component: SideNavigationPanel,
6
+ argTypes: {
7
+ menuItems: {
8
+ control: 'object',
9
+ description: 'Array of menu items with label, url, icon, and isActive properties',
10
+ },
11
+ createNewDesignCta: {
12
+ control: 'object',
13
+ description: 'CTA object for "Create New Design" button with url property',
14
+ },
15
+ upgradeCta: {
16
+ control: 'object',
17
+ description: 'CTA object for "Upgrade" button with url property',
18
+ },
19
+ rateCta: {
20
+ control: 'object',
21
+ description: 'CTA object for "Rate Design.com" button with action property',
22
+ },
23
+ },
24
+ parameters: {
25
+ layout: 'fullscreen',
26
+ },
27
+ };
28
+
29
+ // Default menu items representing a typical navigation structure
30
+ const defaultMenuItems = [
31
+ { label: 'Logos', icon: 'star-hollow', url: '#logos', isActive: true, action: undefined },
32
+ { label: 'Designs', icon: 'designs', url: '#designs', isActive: false, action: undefined },
33
+ { label: 'Printing', icon: 'printing', url: '#printing', isActive: false, action: undefined },
34
+ { label: 'Websites', icon: 'website', url: '#websites', isActive: false, action: undefined },
35
+ { label: 'Domains', icon: 'globe', url: '#domains', isActive: false, action: undefined },
36
+ { label: 'Settings', icon: 'settings', url: '#settings', isActive: false, action: undefined },
37
+ ];
38
+
39
+ const defaultCreateNewDesignCta = {
40
+ url: '#create-new-design',
41
+ };
42
+
43
+ const defaultUpgradeCta = {
44
+ url: '#upgrade',
45
+ };
46
+
47
+ const defaultRateCta = {
48
+ action: () => console.log('Rate Design.com clicked'),
49
+ };
50
+
51
+ const Template = (args) => ({
52
+ components: { SideNavigationPanel },
53
+ setup() {
54
+ return { args };
55
+ },
56
+ template: `
57
+ <div style="width: 100vw; height: 100vh; display: flex;">
58
+ <SideNavigationPanel v-bind="args" />
59
+ <div style="flex: 1; padding: 2rem; background: white;">
60
+ <h1 style="font-size: 2rem; margin-bottom: 1rem;">Content Area</h1>
61
+ <p>This is where your main content would appear. The side navigation panel is on the left.</p>
62
+ <p style="margin-top: 1rem;">Click on the menu items to see the active state change (in a real app).</p>
63
+ </div>
64
+ </div>
65
+ `,
66
+ });
67
+
68
+ export const Default = Template.bind({});
69
+ Default.args = {
70
+ menuItems: defaultMenuItems,
71
+ createNewDesignCta: defaultCreateNewDesignCta,
72
+ upgradeCta: defaultUpgradeCta,
73
+ rateCta: defaultRateCta,
74
+ };
75
+ Default.parameters = {
76
+ docs: {
77
+ description: {
78
+ story: 'Default side navigation panel with all CTAs and the first menu item active.',
79
+ },
80
+ },
81
+ };
82
+
83
+ export const DesignsActive = Template.bind({});
84
+ DesignsActive.args = {
85
+ menuItems: [
86
+ { label: 'Logos', icon: 'star-hollow', url: '#logos', isActive: false, action: undefined },
87
+ { label: 'Designs', icon: 'designs', url: '#designs', isActive: true, action: undefined },
88
+ { label: 'Printing', icon: 'printing', url: '#printing', isActive: false, action: undefined },
89
+ { label: 'Websites', icon: 'website', url: '#websites', isActive: false, action: undefined },
90
+ { label: 'Domains', icon: 'globe', url: '#domains', isActive: false, action: undefined },
91
+ { label: 'Settings', icon: 'settings', url: '#settings', isActive: false, action: undefined },
92
+ ],
93
+ createNewDesignCta: defaultCreateNewDesignCta,
94
+ upgradeCta: defaultUpgradeCta,
95
+ rateCta: defaultRateCta,
96
+ };
97
+ DesignsActive.parameters = {
98
+ docs: {
99
+ description: {
100
+ story: 'Side navigation panel with the "Designs" menu item active.',
101
+ },
102
+ },
103
+ };
104
+
105
+ export const SettingsActive = Template.bind({});
106
+ SettingsActive.args = {
107
+ menuItems: [
108
+ { label: 'Logos', icon: 'star-hollow', url: '#logos', isActive: false, action: undefined },
109
+ { label: 'Designs', icon: 'designs', url: '#designs', isActive: false, action: undefined },
110
+ { label: 'Printing', icon: 'printing', url: '#printing', isActive: false, action: undefined },
111
+ { label: 'Websites', icon: 'website', url: '#websites', isActive: false, action: undefined },
112
+ { label: 'Domains', icon: 'globe', url: '#domains', isActive: false, action: undefined },
113
+ { label: 'Settings', icon: 'settings', url: '#settings', isActive: true, action: undefined },
114
+ ],
115
+ createNewDesignCta: defaultCreateNewDesignCta,
116
+ upgradeCta: defaultUpgradeCta,
117
+ rateCta: defaultRateCta,
118
+ };
119
+ SettingsActive.parameters = {
120
+ docs: {
121
+ description: {
122
+ story: 'Side navigation panel with the "Settings" menu item active.',
123
+ },
124
+ },
125
+ };
126
+
127
+ export const NoActiveItem = Template.bind({});
128
+ NoActiveItem.args = {
129
+ menuItems: [
130
+ { label: 'Logos', icon: 'star-hollow', url: '#logos', isActive: false, action: undefined },
131
+ { label: 'Designs', icon: 'designs', url: '#designs', isActive: false, action: undefined },
132
+ { label: 'Printing', icon: 'printing', url: '#printing', isActive: false, action: undefined },
133
+ { label: 'Websites', icon: 'website', url: '#websites', isActive: false, action: undefined },
134
+ { label: 'Domains', icon: 'globe', url: '#domains', isActive: false, action: undefined },
135
+ { label: 'Settings', icon: 'settings', url: '#settings', isActive: false, action: undefined },
136
+ ],
137
+ createNewDesignCta: defaultCreateNewDesignCta,
138
+ upgradeCta: defaultUpgradeCta,
139
+ rateCta: defaultRateCta,
140
+ };
141
+ NoActiveItem.parameters = {
142
+ docs: {
143
+ description: {
144
+ story: 'Side navigation panel with no active menu item.',
145
+ },
146
+ },
147
+ };
148
+
149
+ export const WithActionBasedMenuItems = Template.bind({});
150
+ WithActionBasedMenuItems.args = {
151
+ menuItems: [
152
+ { label: 'Logos', icon: 'star-hollow', url: '#logos', isActive: true, action: undefined },
153
+ { label: 'Designs', icon: 'designs', url: '#designs', isActive: false, action: undefined },
154
+ {
155
+ label: 'Export Data',
156
+ icon: 'download',
157
+ url: undefined,
158
+ isActive: false,
159
+ action: () => console.log('Export data action triggered'),
160
+ },
161
+ { label: 'Websites', icon: 'website', url: '#websites', isActive: false, action: undefined },
162
+ { label: 'Settings', icon: 'settings', url: '#settings', isActive: false, action: undefined },
163
+ ],
164
+ createNewDesignCta: defaultCreateNewDesignCta,
165
+ upgradeCta: defaultUpgradeCta,
166
+ rateCta: defaultRateCta,
167
+ };
168
+ WithActionBasedMenuItems.parameters = {
169
+ docs: {
170
+ description: {
171
+ story:
172
+ 'Side navigation panel with an action-based menu item (Export Data) that triggers a function instead of navigation. Check console for action output.',
173
+ },
174
+ },
175
+ };
176
+
177
+ export const MinimalMenuItems = Template.bind({});
178
+ MinimalMenuItems.args = {
179
+ menuItems: [
180
+ { label: 'Dashboard', icon: 'star-hollow', url: '#dashboard', isActive: true, action: undefined },
181
+ { label: 'Projects', icon: 'designs', url: '#projects', isActive: false, action: undefined },
182
+ { label: 'Help', icon: 'help', url: '#help', isActive: false, action: undefined },
183
+ ],
184
+ createNewDesignCta: defaultCreateNewDesignCta,
185
+ upgradeCta: defaultUpgradeCta,
186
+ rateCta: defaultRateCta,
187
+ };
188
+ MinimalMenuItems.parameters = {
189
+ docs: {
190
+ description: {
191
+ story: 'Side navigation panel with a minimal set of menu items.',
192
+ },
193
+ },
194
+ };
195
+
196
+ export const ExtendedMenuItems = Template.bind({});
197
+ ExtendedMenuItems.args = {
198
+ menuItems: [
199
+ { label: 'Logos', icon: 'star-hollow', url: '#logos', isActive: false, action: undefined },
200
+ { label: 'Designs', icon: 'designs', url: '#designs', isActive: false, action: undefined },
201
+ { label: 'Printing', icon: 'printing', url: '#printing', isActive: false, action: undefined },
202
+ { label: 'Websites', icon: 'website', url: '#websites', isActive: true, action: undefined },
203
+ { label: 'Domains', icon: 'globe', url: '#domains', isActive: false, action: undefined },
204
+ { label: 'Marketing', icon: 'megaphone', url: '#marketing', isActive: false, action: undefined },
205
+ { label: 'Analytics', icon: 'chart', url: '#analytics', isActive: false, action: undefined },
206
+ { label: 'Billing', icon: 'creditcard', url: '#billing', isActive: false, action: undefined },
207
+ { label: 'Settings', icon: 'settings', url: '#settings', isActive: false, action: undefined },
208
+ ],
209
+ createNewDesignCta: defaultCreateNewDesignCta,
210
+ upgradeCta: defaultUpgradeCta,
211
+ rateCta: defaultRateCta,
212
+ };
213
+ ExtendedMenuItems.parameters = {
214
+ docs: {
215
+ description: {
216
+ story: 'Side navigation panel with an extended list of menu items to test scrolling behavior.',
217
+ },
218
+ },
219
+ };
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <!-- Side Navigation Component following these figma designs: https://www.figma.com/design/UUZ56EQZbb1Ua9NBMm6Rt5/DCOM---My-Account-Left-Nav -->
3
+ <div class="sidebar">
4
+ <div class="menu tw-mb-4">
5
+ <MenuCta class="tw-mt-2 tw-mb-4" label="Create New Design" variant="primary" icon="plus" icon-size="xs" />
6
+ <div class="menuitemcontainer">
7
+ <MenuItem
8
+ v-for="item in menuItems"
9
+ :key="item.label"
10
+ :label="item.label"
11
+ :url="item.action ? '' : item.url"
12
+ :icon="item.icon"
13
+ :is-active="item.isActive"
14
+ />
15
+ </div>
16
+ </div>
17
+ <div class="ctas tw-flex tw-flex-col tw-gap-2">
18
+ <MenuCta label="Upgrade" variant="secondary" icon="crown" icon-size="sm" />
19
+ <MenuCta label="Rate Design.com" variant="empty" />
20
+ </div>
21
+ </div>
22
+ </template>
23
+ <script setup lang="ts">
24
+ import MenuCta from './MenuCta.vue';
25
+ import MenuItem from './MenuItem.vue';
26
+ import type { IMenuItem } from './types';
27
+
28
+ defineProps({
29
+ menuItems: {
30
+ type: Array<IMenuItem>,
31
+ required: true,
32
+ },
33
+ createNewDesignCta: {
34
+ type: Object,
35
+ required: true,
36
+ },
37
+ });
38
+ </script>
39
+ <style scoped>
40
+ .sidebar {
41
+ @apply tw-p-2 tw-flex tw-flex-col tw-h-full tw-justify-between tw-w-[14rem];
42
+ background-color: rgba(245, 245, 245, 1);
43
+ border-right: 1px rgba(227, 227, 227, 1) solid;
44
+ }
45
+ .ctas {
46
+ text-align: center;
47
+ }
48
+ </style>
@@ -0,0 +1,7 @@
1
+ export type IMenuItem = {
2
+ label: string;
3
+ url?: string;
4
+ action?: () => void;
5
+ icon: string;
6
+ isActive: boolean;
7
+ };
@@ -6,6 +6,7 @@
6
6
  :custom-upload-data="customUploadData"
7
7
  :use-dropzone="useDropzone"
8
8
  :is-post-purchase-user-upload="isPostPurchaseUserUpload"
9
+ :is-ai-powered="isAiPowered"
9
10
  @on-exit="onExit"
10
11
  @on-upload-error="onUploadError"
11
12
  @on-file-change="onFileChange"
@@ -29,19 +30,20 @@ export default {
29
30
  props: {
30
31
  useDropzone: {
31
32
  type: Boolean,
32
- required: false,
33
33
  default: false,
34
34
  },
35
35
  isPostPurchaseUserUpload: {
36
36
  type: Boolean,
37
- required: false,
38
37
  default: false,
39
38
  },
40
39
  customUploadData: {
41
40
  type: Object,
42
- required: false,
43
41
  default: null,
44
42
  },
43
+ isAiPowered: {
44
+ type: Boolean,
45
+ default: false,
46
+ },
45
47
  },
46
48
  data() {
47
49
  return {
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <LogoUploadingLoader :loading-text="uploadYourLogoTr('uploadingAndConverting')" />
2
+ <LogoUploadingLoader
3
+ :loading-text="uploadYourLogoTr('uploadingAndConverting')"
4
+ :is-ai-powered="isAiPowered"
5
+ />
3
6
  </template>
4
7
  <script>
5
8
  import brandCrowdClient from '../../clients/brand-crowd-api.client';
@@ -28,6 +31,10 @@ export default {
28
31
  type: String,
29
32
  required: true,
30
33
  },
34
+ isAiPowered: {
35
+ type: Boolean,
36
+ default: false,
37
+ },
31
38
  },
32
39
  setup() {
33
40
  return {
@@ -1,22 +1,39 @@
1
1
  <template>
2
2
  <div class="tw-pt-12 tw-pb-16 tw-flex tw-flex-col tw-items-center tw-justify-center">
3
+ <!-- AI-powered sparkle animation -->
4
+ <div v-if="isAiPowered" class="tw-mb-8">
5
+ <AiPoweredLoader alt="AI-powered loading" />
6
+ </div>
7
+
8
+ <!-- Traditional GIF loader -->
3
9
  <img
10
+ v-else
4
11
  src="https://dcstatic.com/images/brandcrowd/on-boarding/loading/preloader-1-d1cc0b885f.gif"
5
12
  alt="Loading"
6
13
  class="tw-block tw-mb-8"
7
14
  />
15
+
8
16
  <p class="tw-text-black tw-text-2xl tw-font-bold tw-text-center">
9
17
  {{ loadingText }}
10
18
  </p>
11
19
  </div>
12
20
  </template>
13
21
  <script>
22
+ import AiPoweredLoader from '../../../atoms/components/AiPoweredLoader/AiPoweredLoader.vue';
23
+
14
24
  export default {
25
+ components: {
26
+ AiPoweredLoader,
27
+ },
15
28
  props: {
16
29
  loadingText: {
17
30
  type: String,
18
31
  required: true,
19
32
  },
33
+ isAiPowered: {
34
+ type: Boolean,
35
+ default: false,
36
+ },
20
37
  },
21
38
  };
22
39
  </script>