@designcrowd/fe-shared-lib 1.5.26 → 1.5.27-ENG-3954
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.
- package/package.json +1 -1
- package/src/atoms/components/Button/variants/ButtonGray.vue +5 -7
- package/src/atoms/components/Icon/Icon.stories.js +2 -7
- package/src/atoms/components/Icon/Icon.vue +19 -15
- package/src/atoms/components/Icon/icons/crown-alt.vue +5 -0
- package/src/atoms/components/Icon/icons/crown.vue +6 -0
- package/src/experiences/components/SideNavigationPanel/MenuCta.vue +62 -0
- package/src/experiences/components/SideNavigationPanel/MenuItem.vue +47 -0
- package/src/experiences/components/SideNavigationPanel/SideNavigationPanel.stories.js +219 -0
- package/src/experiences/components/SideNavigationPanel/SideNavigationPanel.vue +57 -0
package/package.json
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<button
|
|
3
3
|
v-if="!url"
|
|
4
|
-
class="tw-font-sans tw-
|
|
4
|
+
class="tw-font-sans tw-font-bold tw-text-grayscale-800 tw-uppercase tw-border-solid tw-transition-colors tw-duration-300"
|
|
5
5
|
:class="[
|
|
6
6
|
classes,
|
|
7
7
|
computedClasses,
|
|
8
8
|
{
|
|
9
9
|
'no-rounded-l': !rounded && !roundedLeft,
|
|
10
10
|
'no-rounded-r': !rounded && !roundedRight,
|
|
11
|
-
'tw-cursor-pointer tw-bg-grayscale-300
|
|
12
|
-
!disabled,
|
|
11
|
+
'tw-cursor-pointer tw-bg-grayscale-300 hover:tw-bg-grayscale-500': !disabled,
|
|
13
12
|
'tw-bg-grayscale-100 tw-border-grayscale-300 tw-cursor-not-allowed': disabled,
|
|
14
13
|
},
|
|
15
14
|
]"
|
|
@@ -23,16 +22,15 @@
|
|
|
23
22
|
<a
|
|
24
23
|
v-else
|
|
25
24
|
:href="computedUrl"
|
|
26
|
-
class="tw-justify-center tw-font-sans tw-inline-flex tw-
|
|
25
|
+
class="tw-justify-center tw-font-sans tw-inline-flex tw-font-bold tw-text-grayscale-800 hover:tw-text-grayscale-800 tw-uppercase tw-border-solid tw-transition-colors tw-duration-300 tw-no-underline"
|
|
27
26
|
:class="[
|
|
28
27
|
classes,
|
|
29
28
|
computedClasses,
|
|
30
29
|
{
|
|
31
30
|
'no-rounded-l': !rounded && !roundedLeft,
|
|
32
31
|
'no-rounded-r': !rounded && !roundedRight,
|
|
33
|
-
'tw-cursor-pointer tw-bg-grayscale-300
|
|
34
|
-
|
|
35
|
-
'tw-bg-grayscale-100 tw-border-grayscale-100 tw-cursor-not-allowed': disabled,
|
|
32
|
+
'tw-cursor-pointer tw-bg-grayscale-300 hover:tw-bg-grayscale-500': !disabled,
|
|
33
|
+
'tw-bg-grayscale-100 tw-cursor-not-allowed': disabled,
|
|
36
34
|
},
|
|
37
35
|
]"
|
|
38
36
|
:download="download"
|
|
@@ -14,12 +14,8 @@ export const IconSample = () => {
|
|
|
14
14
|
return {
|
|
15
15
|
sizes: ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl'],
|
|
16
16
|
icons: [
|
|
17
|
-
{ name: '
|
|
18
|
-
{ name: '
|
|
19
|
-
{ name: 'websites-upgrade-to-remove-watermark' },
|
|
20
|
-
{ name: 'websites-upgrade-to-publish' },
|
|
21
|
-
{ name: 'websites-upgrade-to-videos' },
|
|
22
|
-
{ name: 'websites-upgrade-to-maps' },
|
|
17
|
+
{ name: 'crown' },
|
|
18
|
+
{ name: 'crown-alt' },
|
|
23
19
|
{ name: 'add-page' },
|
|
24
20
|
{ name: 'ai' },
|
|
25
21
|
{ name: 'arrow-down' },
|
|
@@ -387,7 +383,6 @@ export const IconSample = () => {
|
|
|
387
383
|
<div class="tw-grid tw-grid-cols-8 tw-gap-4 tw-items-center" style="grid-template-columns: repeat(8, minmax(0, 1fr));">
|
|
388
384
|
<Icon
|
|
389
385
|
v-for="size in sizes"
|
|
390
|
-
viewBox="0 0 96 96"
|
|
391
386
|
:name="icon.name"
|
|
392
387
|
:alt-text="icon.altText"
|
|
393
388
|
:size="size"
|
|
@@ -50,12 +50,12 @@ import IconAttach from './icons/attach.vue';
|
|
|
50
50
|
import IconAuthFacebookWhite from './icons/auth-facebook-white.vue';
|
|
51
51
|
import IconAuthFacebook from './icons/auth-facebook.vue';
|
|
52
52
|
import IconAuthGoogle from './icons/auth-google.vue';
|
|
53
|
-
import IconBriefcase from './icons/briefcase.vue';
|
|
54
53
|
import IconBackground from './icons/background.vue';
|
|
55
54
|
import IconBannerCentered from './icons/banner-centered.vue';
|
|
56
55
|
import IconBannerLeft from './icons/banner-left.vue';
|
|
57
56
|
import IconBanner from './icons/banner.vue';
|
|
58
57
|
import IconBcMast from './icons/bc-mast.vue';
|
|
58
|
+
import IconBriefcase from './icons/briefcase.vue';
|
|
59
59
|
import IconBrush from './icons/brush.vue';
|
|
60
60
|
import IconBusinessCardFilled from './icons/business-card-filled.vue';
|
|
61
61
|
import IconBusiness from './icons/business.vue';
|
|
@@ -105,6 +105,8 @@ import IconCopy from './icons/copy.vue';
|
|
|
105
105
|
import IconFilterCrazyDomains from './icons/crazy-domains/filter.vue';
|
|
106
106
|
import IconGlobeCrazyDomains from './icons/crazy-domains/globe.vue';
|
|
107
107
|
import IconHomeCrazyDomains from './icons/crazy-domains/home.vue';
|
|
108
|
+
import IconCrownAlt from './icons/crown-alt.vue';
|
|
109
|
+
import IconCrown from './icons/crown.vue';
|
|
108
110
|
import IconDelete from './icons/delete.vue';
|
|
109
111
|
import IconDesigns from './icons/designs.vue';
|
|
110
112
|
import IconDesktop from './icons/desktop.vue';
|
|
@@ -222,11 +224,14 @@ import IconSocialInstagramCrazyDomains from './icons/crazy-domains/social-instag
|
|
|
222
224
|
import IconSocialTwitterCrazyDomains from './icons/crazy-domains/social-twitter.vue';
|
|
223
225
|
import IconSocialYoutubeCrazyDomains from './icons/crazy-domains/social-youtube.vue';
|
|
224
226
|
import IconCrop from './icons/crop.vue';
|
|
227
|
+
import IconDigitalBusinessCardFilled from './icons/digital-business-card-filled.vue';
|
|
225
228
|
import IconFormMessage from './icons/form-message.vue';
|
|
226
229
|
import IconGodaddy from './icons/godaddy/logo.vue';
|
|
227
230
|
import IconIconStyleCircleBg from './icons/icon-style-circle-bg.vue';
|
|
228
231
|
import IconIconStyleNoBg from './icons/icon-style-no-bg.vue';
|
|
229
232
|
import IconIconStyleSquareBg from './icons/icon-style-square-bg.vue';
|
|
233
|
+
import IconLinkInBioFilled from './icons/link-in-bio-filled.vue';
|
|
234
|
+
import IconMedia from './icons/media.vue';
|
|
230
235
|
import IconMinusCircleLight from './icons/minus-circle-light.vue';
|
|
231
236
|
import IconMinus from './icons/minus.vue';
|
|
232
237
|
import IconMobile from './icons/mobile.vue';
|
|
@@ -254,9 +259,8 @@ import IconQuestion from './icons/question.vue';
|
|
|
254
259
|
import IconQuote from './icons/quote.vue';
|
|
255
260
|
import IconReload from './icons/reload.vue';
|
|
256
261
|
import IconReorderable from './icons/reorderable.vue';
|
|
257
|
-
import IconResize from './icons/resize.vue';
|
|
258
|
-
import IconMedia from './icons/media.vue';
|
|
259
262
|
import IconRequestPayment from './icons/request-payment.vue';
|
|
263
|
+
import IconResize from './icons/resize.vue';
|
|
260
264
|
import IconSearch from './icons/search.vue';
|
|
261
265
|
import IconSecure from './icons/secure.vue';
|
|
262
266
|
import IconSend from './icons/send.vue';
|
|
@@ -265,7 +269,6 @@ import IconSettings from './icons/settings.vue';
|
|
|
265
269
|
import IconShare from './icons/share.vue';
|
|
266
270
|
import IconShieldTick from './icons/shield-tick.vue';
|
|
267
271
|
import IconShop from './icons/shop.vue';
|
|
268
|
-
import IconStop from './icons/stop.vue';
|
|
269
272
|
import IconSms from './icons/sms.vue';
|
|
270
273
|
import IconSocialFacebookColor from './icons/social-facebook-color.vue';
|
|
271
274
|
import IconSocialFacebook from './icons/social-facebook.vue';
|
|
@@ -277,6 +280,7 @@ import IconSocialTwitterColor from './icons/social-twitter-color.vue';
|
|
|
277
280
|
import IconStarFilled from './icons/star-filled.vue';
|
|
278
281
|
import IconStarHollow from './icons/star-hollow.vue';
|
|
279
282
|
import IconSticker from './icons/sticker.vue';
|
|
283
|
+
import IconStop from './icons/stop.vue';
|
|
280
284
|
import IconStyles from './icons/styles.vue';
|
|
281
285
|
import IconSubmit from './icons/submit.vue';
|
|
282
286
|
import IconTemplates from './icons/templates.vue';
|
|
@@ -304,8 +308,6 @@ import IconWatchlistFilled from './icons/watchlist-filled.vue';
|
|
|
304
308
|
import IconWatchlistHollowAlt from './icons/watchlist-hollow-alt.vue';
|
|
305
309
|
import IconWatchlistHollow from './icons/watchlist-hollow.vue';
|
|
306
310
|
import IconWebsiteFilled from './icons/website-filled.vue';
|
|
307
|
-
import IconDigitalBusinessCardFilled from './icons/digital-business-card-filled.vue';
|
|
308
|
-
import IconLinkInBioFilled from './icons/link-in-bio-filled.vue';
|
|
309
311
|
import IconWebsite from './icons/website.vue';
|
|
310
312
|
import IconWholesale from './icons/wholesale.vue';
|
|
311
313
|
import IconZoomIn from './icons/zoom-in.vue';
|
|
@@ -327,6 +329,7 @@ import IconShape from './icons/shape.vue';
|
|
|
327
329
|
// New icons copied from dcom
|
|
328
330
|
import IconAnnotateHeart from './icons/annotate-heart.vue';
|
|
329
331
|
import IconAward from './icons/award.vue';
|
|
332
|
+
import IconBezierCurveOutline from './icons/bezier-curve-outline.vue';
|
|
330
333
|
import IconBezierCurve from './icons/bezier-curve.vue';
|
|
331
334
|
import IconBrowser from './icons/browser.vue';
|
|
332
335
|
import IconCardVertical from './icons/card-vertical.vue';
|
|
@@ -336,12 +339,11 @@ import IconHeadphones from './icons/headphones.vue';
|
|
|
336
339
|
import IconImage from './icons/image.vue';
|
|
337
340
|
import IconLightning from './icons/lightning.vue';
|
|
338
341
|
import IconLogo from './icons/logo.vue';
|
|
339
|
-
import
|
|
342
|
+
import IconPaletteOutline from './icons/palette-outline.vue';
|
|
340
343
|
import IconPenOutline from './icons/pen-outline.vue';
|
|
341
344
|
import IconPenSparkle from './icons/pen-sparkle.vue';
|
|
345
|
+
import IconPen from './icons/pen.vue';
|
|
342
346
|
import IconSparkleSquare from './icons/sparkle-square.vue';
|
|
343
|
-
import IconBezierCurveOutline from './icons/bezier-curve-outline.vue';
|
|
344
|
-
import IconPaletteOutline from './icons/palette-outline.vue';
|
|
345
347
|
|
|
346
348
|
// Maker Icons
|
|
347
349
|
import IconMakerAlignCenter from './icons/maker/align-center.vue';
|
|
@@ -422,18 +424,18 @@ import IconFlipVertical from './icons/flip-vertical.vue';
|
|
|
422
424
|
import IconVolumeMuted from './icons/volume-muted.vue';
|
|
423
425
|
import IconVolume from './icons/volume.vue';
|
|
424
426
|
|
|
425
|
-
import IconFile from './icons/file.vue';
|
|
426
|
-
import IconPenTool from './icons/pen-tool.vue';
|
|
427
|
-
import IconClipboardCheck from './icons/clipboard-check.vue';
|
|
428
427
|
import IconBadge from './icons/badge.vue';
|
|
429
428
|
import IconCalculator from './icons/calculator.vue';
|
|
429
|
+
import IconClipboardCheck from './icons/clipboard-check.vue';
|
|
430
|
+
import IconFile from './icons/file.vue';
|
|
431
|
+
import IconPenTool from './icons/pen-tool.vue';
|
|
430
432
|
import IconWebsitesUpgradeToAddPage from './icons/websites/upgrade-to-add-page.vue';
|
|
431
433
|
import IconWebsitesUpgradeToContactForm from './icons/websites/upgrade-to-contact-form.vue';
|
|
432
|
-
import
|
|
434
|
+
import IconWebsitesUpgradeToGoogleAd from './icons/websites/upgrade-to-google-ad.vue';
|
|
435
|
+
import IconWebsitesUpgradeToMaps from './icons/websites/upgrade-to-maps.vue';
|
|
433
436
|
import IconWebsitesUpgradeToPublish from './icons/websites/upgrade-to-publish.vue';
|
|
437
|
+
import IconWebsitesUpgradeToRemoveWatermark from './icons/websites/upgrade-to-remove-watermark.vue';
|
|
434
438
|
import IconWebsitesUpgradeToVideos from './icons/websites/upgrade-to-videos.vue';
|
|
435
|
-
import IconWebsitesUpgradeToMaps from './icons/websites/upgrade-to-maps.vue';
|
|
436
|
-
import IconWebsitesUpgradeToGoogleAd from './icons/websites/upgrade-to-google-ad.vue';
|
|
437
439
|
|
|
438
440
|
import IconGroup from './icons/group.vue';
|
|
439
441
|
import IconPremiumContent from './icons/premium-content.vue';
|
|
@@ -506,6 +508,7 @@ export default {
|
|
|
506
508
|
IconColumn2,
|
|
507
509
|
IconColumn3,
|
|
508
510
|
IconColumn4,
|
|
511
|
+
IconCrownAlt,
|
|
509
512
|
IconCopy,
|
|
510
513
|
IconDelete,
|
|
511
514
|
IconDesigns,
|
|
@@ -612,6 +615,7 @@ export default {
|
|
|
612
615
|
IconDisplayStyleContact5,
|
|
613
616
|
IconDisplayStyleContact6,
|
|
614
617
|
IconLetterheadFilled,
|
|
618
|
+
IconCrown,
|
|
615
619
|
IconLink,
|
|
616
620
|
IconLocation,
|
|
617
621
|
IconLock,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<path
|
|
3
|
+
d="M12.55 12.125C12.6521 12.125 12.7323 12.1536 12.7906 12.2109C12.8635 12.2826 12.9 12.3685 12.9 12.4688V13.1562C12.9 13.2565 12.8635 13.3353 12.7906 13.3926C12.7323 13.4642 12.6521 13.5 12.55 13.5H3.45C3.34792 13.5 3.26042 13.4642 3.1875 13.3926C3.12917 13.3353 3.1 13.2565 3.1 13.1562V12.4688C3.1 12.3685 3.12917 12.2826 3.1875 12.2109C3.26042 12.1536 3.34792 12.125 3.45 12.125H12.55ZM13.2063 5.55078C13.4104 5.35026 13.6583 5.25 13.95 5.25C14.2417 5.25 14.4896 5.35026 14.6938 5.55078C14.8979 5.7513 15 5.99479 15 6.28125C15 6.56771 14.8979 6.8112 14.6938 7.01172C14.4896 7.21224 14.2417 7.3125 13.95 7.3125C13.9062 7.3125 13.8479 7.30534 13.775 7.29102L12.2 11.4375H3.8L2.225 7.29102C2.15208 7.30534 2.09375 7.3125 2.05 7.3125C1.75833 7.3125 1.51042 7.21224 1.30625 7.01172C1.10208 6.8112 1 6.56771 1 6.28125C1 5.99479 1.10208 5.7513 1.30625 5.55078C1.51042 5.35026 1.75833 5.25 2.05 5.25C2.34167 5.25 2.58958 5.35026 2.79375 5.55078C2.99792 5.7513 3.1 5.99479 3.1 6.28125C3.1 6.42448 3.07083 6.56771 3.0125 6.71094L4.5875 7.63477C4.74792 7.73503 4.92292 7.76367 5.1125 7.7207C5.31667 7.66341 5.4625 7.55599 5.55 7.39844L7.34375 4.32617C7.08125 4.11133 6.95 3.84635 6.95 3.53125C6.95 3.24479 7.05208 3.0013 7.25625 2.80078C7.46042 2.60026 7.70833 2.5 8 2.5C8.29167 2.5 8.53958 2.60026 8.74375 2.80078C8.94792 3.0013 9.05 3.24479 9.05 3.53125C9.05 3.84635 8.91875 4.11133 8.65625 4.32617L10.45 7.39844C10.5375 7.55599 10.676 7.66341 10.8656 7.7207C11.0552 7.76367 11.2375 7.73503 11.4125 7.63477L12.9875 6.71094C12.9292 6.56771 12.9 6.42448 12.9 6.28125C12.9 5.99479 13.0021 5.7513 13.2063 5.55078Z"
|
|
4
|
+
/>
|
|
5
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<path
|
|
3
|
+
d="M12.55 12.125C12.6521 12.125 12.7323 12.1536 12.7906 12.2109C12.8635 12.2826 12.9 12.3685 12.9 12.4688V13.1562C12.9 13.2565 12.8635 13.3353 12.7906 13.3926C12.7323 13.4642 12.6521 13.5 12.55 13.5H3.45C3.34792 13.5 3.26042 13.4642 3.1875 13.3926C3.12917 13.3353 3.1 13.2565 3.1 13.1562V12.4688C3.1 12.3685 3.12917 12.2826 3.1875 12.2109C3.26042 12.1536 3.34792 12.125 3.45 12.125H12.55ZM13.2063 5.55078C13.4104 5.35026 13.6583 5.25 13.95 5.25C14.2417 5.25 14.4896 5.35026 14.6938 5.55078C14.8979 5.7513 15 5.99479 15 6.28125C15 6.56771 14.8979 6.8112 14.6938 7.01172C14.4896 7.21224 14.2417 7.3125 13.95 7.3125C13.9062 7.3125 13.8479 7.30534 13.775 7.29102L12.2 11.4375H3.8L2.225 7.29102C2.15208 7.30534 2.09375 7.3125 2.05 7.3125C1.75833 7.3125 1.51042 7.21224 1.30625 7.01172C1.10208 6.8112 1 6.56771 1 6.28125C1 5.99479 1.10208 5.7513 1.30625 5.55078C1.51042 5.35026 1.75833 5.25 2.05 5.25C2.34167 5.25 2.58958 5.35026 2.79375 5.55078C2.99792 5.7513 3.1 5.99479 3.1 6.28125C3.1 6.42448 3.07083 6.56771 3.0125 6.71094L4.5875 7.63477C4.74792 7.73503 4.92292 7.76367 5.1125 7.7207C5.31667 7.66341 5.4625 7.55599 5.55 7.39844L7.34375 4.32617C7.08125 4.11133 6.95 3.84635 6.95 3.53125C6.95 3.24479 7.05208 3.0013 7.25625 2.80078C7.46042 2.60026 7.70833 2.5 8 2.5C8.29167 2.5 8.53958 2.60026 8.74375 2.80078C8.94792 3.0013 9.05 3.24479 9.05 3.53125C9.05 3.84635 8.91875 4.11133 8.65625 4.32617L10.45 7.39844C10.5375 7.55599 10.676 7.66341 10.8656 7.7207C11.0552 7.76367 11.2375 7.73503 11.4125 7.63477L12.9875 6.71094C12.9292 6.56771 12.9 6.42448 12.9 6.28125C12.9 5.99479 13.0021 5.7513 13.2063 5.55078Z"
|
|
4
|
+
fill="#E3A008"
|
|
5
|
+
/>
|
|
6
|
+
</template>
|
|
@@ -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,47 @@
|
|
|
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
|
+
|
|
18
|
+
type IMenuItem = {
|
|
19
|
+
label: string;
|
|
20
|
+
url?: string;
|
|
21
|
+
action?: () => void;
|
|
22
|
+
icon: string;
|
|
23
|
+
isActive: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const props = defineProps<IMenuItem>();
|
|
27
|
+
|
|
28
|
+
const componentTag = computed(() => (props.action ? 'button' : 'a'));
|
|
29
|
+
|
|
30
|
+
const componentAttrs = computed(() => (props.action ? {} : { href: props.url }));
|
|
31
|
+
|
|
32
|
+
const handleClick = () => {
|
|
33
|
+
if (props.action) {
|
|
34
|
+
props.action();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<style scoped>
|
|
40
|
+
.menu-item {
|
|
41
|
+
@apply tw-p-2 tw-mb-1 tw-flex tw-gap-2 tw-items-center tw-rounded-lg tw-cursor-pointer;
|
|
42
|
+
height: 36px;
|
|
43
|
+
}
|
|
44
|
+
.icon svg {
|
|
45
|
+
color: var(--text-secondary, rgba(61, 61, 61, 1));
|
|
46
|
+
}
|
|
47
|
+
</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,57 @@
|
|
|
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 defineProps from 'vue';
|
|
25
|
+
import MenuCta from './MenuCta.vue';
|
|
26
|
+
import MenuItem from './MenuItem.vue';
|
|
27
|
+
|
|
28
|
+
type IMenuItem = {
|
|
29
|
+
label: string;
|
|
30
|
+
url: string | undefined;
|
|
31
|
+
action: Function | undefined; // might need to implement actions on menu items
|
|
32
|
+
icon: string;
|
|
33
|
+
isActive: Boolean;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const props = defineProps({
|
|
37
|
+
menuItems: {
|
|
38
|
+
type: Array<IMenuItem>,
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
createNewDesignCta: {
|
|
42
|
+
type: Object,
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
// ctaItems: {},
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
<style scoped>
|
|
49
|
+
.sidebar {
|
|
50
|
+
@apply tw-p-2 tw-flex tw-flex-col tw-h-full tw-justify-between tw-w-[14rem];
|
|
51
|
+
background-color: rgba(245, 245, 245, 1);
|
|
52
|
+
border-right: 1px rgba(227, 227, 227, 1) solid;
|
|
53
|
+
}
|
|
54
|
+
.ctas {
|
|
55
|
+
text-align: center;
|
|
56
|
+
}
|
|
57
|
+
</style>
|