negodesign 0.0.28 → 0.0.30
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/dist/assets/lonely-404.mp4 +0 -0
- package/dist/components/core/banner/AdCardBanner.svelte +74 -0
- package/dist/components/core/banner/AdCardBanner.svelte.d.ts +4 -0
- package/dist/components/core/banner/CtaCardBanner.svelte +118 -0
- package/dist/components/core/banner/CtaCardBanner.svelte.d.ts +4 -0
- package/dist/components/core/banner/NotificationBanner.svelte +95 -0
- package/dist/components/core/banner/NotificationBanner.svelte.d.ts +4 -0
- package/dist/components/core/banner/types.d.ts +63 -0
- package/dist/components/core/banner/types.js +1 -0
- package/dist/components/core/card/highlight/01/CardHighlight01.svelte +20 -27
- package/dist/components/core/card/highlight/02/CardHighlight02.svelte +18 -27
- package/dist/components/core/card/highlight/data.js +1 -4
- package/dist/components/core/card/media/01/CardMedia01.svelte +114 -98
- package/dist/components/core/card/media/02/CardMedia02.svelte +115 -99
- package/dist/components/core/card/media/CardMedia.svelte +10 -9
- package/dist/components/core/card/media/CardMedia.svelte.d.ts +1 -0
- package/dist/components/core/card/profile/01/CardProfile01.svelte +104 -86
- package/dist/components/core/card/profile/02/CardProfile02.svelte +103 -87
- package/dist/components/core/card/profile/CardProfile.svelte +8 -7
- package/dist/components/core/card/profile/CardProfile.svelte.d.ts +1 -0
- package/dist/components/core/card/promotion/CardPromotion.svelte +10 -4
- package/dist/components/core/card/shared/CardButton.svelte +38 -23
- package/dist/components/core/card/shared/CardButton.svelte.d.ts +2 -1
- package/dist/components/core/card/shared/CardDescription.svelte +30 -30
- package/dist/components/core/card/shared/CardLogo.svelte +19 -0
- package/dist/components/core/card/shared/CardLogo.svelte.d.ts +7 -0
- package/dist/components/core/card/shared/CardStarRating.svelte +18 -14
- package/dist/components/core/card/shared/CardStarRating.svelte.d.ts +1 -0
- package/dist/components/core/card/shared/CardStartPrice.svelte +1 -1
- package/dist/components/core/card/shared/CardThumbnailVideo.svelte +210 -148
- package/dist/components/core/card/shared/CardThumbnailVideo.svelte.d.ts +1 -0
- package/dist/components/core/card/types.d.ts +5 -0
- package/dist/components/core/carousel/grid/media/types.d.ts +11 -0
- package/dist/components/core/carousel/grid/media/types.js +1 -0
- package/dist/components/core/carousel/grid/media/ui/CarouselGridMedia.svelte +49 -0
- package/dist/components/core/carousel/grid/media/ui/CarouselGridMedia.svelte.d.ts +4 -0
- package/dist/components/core/carousel/grid/profile/types.d.ts +11 -0
- package/dist/components/core/carousel/grid/profile/types.js +1 -0
- package/dist/components/core/carousel/grid/profile/ui/CarouselGridProfile.svelte +49 -0
- package/dist/components/core/carousel/grid/profile/ui/CarouselGridProfile.svelte.d.ts +4 -0
- package/dist/components/core/carousel/grid/shared/ui/CarouselGridSlot.svelte +33 -0
- package/dist/components/core/carousel/grid/shared/ui/CarouselGridSlot.svelte.d.ts +11 -0
- package/dist/components/core/carousel/hero/CarouselHero.svelte +21 -19
- package/dist/components/core/carousel/hero/CarouselHero.svelte.d.ts +1 -0
- package/dist/components/core/carousel/highlights/types.d.ts +4 -4
- package/dist/components/core/carousel/highlights/ui/CarouselHighlights.svelte +4 -22
- package/dist/components/core/carousel/promotion/types.d.ts +5 -5
- package/dist/components/core/carousel/promotion/ui/CarouselPromotion.svelte +4 -21
- package/dist/components/core/carousel/shared/ui/CarouselHeader.svelte +6 -1
- package/dist/components/core/carousel/types.d.ts +1 -0
- package/dist/components/core/footer/types.d.ts +23 -0
- package/dist/components/core/footer/types.js +1 -0
- package/dist/components/core/footer/ui/01/Footer01.svelte +76 -0
- package/dist/components/core/footer/ui/01/Footer01.svelte.d.ts +4 -0
- package/dist/components/core/footer/ui/02/Footer02.svelte +53 -0
- package/dist/components/core/footer/ui/02/Footer02.svelte.d.ts +4 -0
- package/dist/components/core/footer/ui/Footer.svelte +18 -0
- package/dist/components/core/footer/ui/Footer.svelte.d.ts +7 -0
- package/dist/components/core/footer/ui/shared/FooterColumn.svelte +18 -0
- package/dist/components/core/footer/ui/shared/FooterColumn.svelte.d.ts +4 -0
- package/dist/components/core/footer/ui/shared/FooterNewsLetter.svelte +57 -0
- package/dist/components/core/footer/ui/shared/FooterNewsLetter.svelte.d.ts +9 -0
- package/dist/components/core/footer/ui/shared/FooterSocialIcon.svelte +62 -0
- package/dist/components/core/footer/ui/shared/FooterSocialIcon.svelte.d.ts +4 -0
- package/dist/components/core/panel/CarouselSlot.svelte +4 -15
- package/dist/components/core/panel/CarouselSlot.svelte.d.ts +2 -12
- package/dist/components/core/panel/LeftHero.svelte +2 -2
- package/dist/components/core/panel/type.d.ts +11 -0
- package/dist/components/core/panel/type.js +1 -0
- package/dist/globals.css +463 -47
- package/dist/i18n/langs/en.d.ts +4 -0
- package/dist/i18n/langs/en.js +4 -0
- package/dist/i18n/langs/pt.d.ts +4 -0
- package/dist/i18n/langs/pt.js +10 -6
- package/dist/i18n/translations.d.ts +8 -0
- package/dist/index.d.ts +17 -5
- package/dist/index.js +17 -5
- package/dist/styles/globals.css +1 -1
- package/package.json +1 -1
|
Binary file
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { HugeiconsIcon } from "@hugeicons/svelte";
|
|
3
|
+
import Button from "../../ui/button/button.svelte";
|
|
4
|
+
import type { BannerProps } from "./types";
|
|
5
|
+
import { AdvertisimentIcon } from "@hugeicons/core-free-icons";
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
tagText,
|
|
9
|
+
titleHighlight,
|
|
10
|
+
titleMain,
|
|
11
|
+
buttonText = "Saiba mais",
|
|
12
|
+
onClickButton,
|
|
13
|
+
href,
|
|
14
|
+
class: className = "",
|
|
15
|
+
titleHighlightClass,
|
|
16
|
+
titleMainClass,
|
|
17
|
+
tagTextClass,
|
|
18
|
+
buttonClass,
|
|
19
|
+
titleBgClass,
|
|
20
|
+
tagBgClass,
|
|
21
|
+
}: BannerProps = $props();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
{#snippet content()}
|
|
25
|
+
<article
|
|
26
|
+
class="relative flex w-full items-stretch overflow-hidden rounded-lg border border-transparent {className}"
|
|
27
|
+
>
|
|
28
|
+
<!-- Left accent strip -->
|
|
29
|
+
<aside
|
|
30
|
+
class="flex w-28 shrink-0 flex-col justify-center gap-1 {tagBgClass ||
|
|
31
|
+
'bg-blue-400'} px-3 py-2 sm:w-32"
|
|
32
|
+
>
|
|
33
|
+
<HugeiconsIcon
|
|
34
|
+
icon={AdvertisimentIcon}
|
|
35
|
+
size={30}
|
|
36
|
+
color="#ffffff"
|
|
37
|
+
strokeWidth={1}
|
|
38
|
+
/>
|
|
39
|
+
<p
|
|
40
|
+
class={`text-sm leading-tight font-bold ${tagTextClass || "text-[#dce9e7]"}`}
|
|
41
|
+
>
|
|
42
|
+
{tagText}
|
|
43
|
+
</p>
|
|
44
|
+
</aside>
|
|
45
|
+
|
|
46
|
+
<!-- Main content -->
|
|
47
|
+
<div
|
|
48
|
+
class="flex flex-1 flex-wrap items-center justify-between gap-3 {titleBgClass ||
|
|
49
|
+
'bg-[#dabc16]'} px-4 py-3 sm:px-6"
|
|
50
|
+
>
|
|
51
|
+
<h3 class="text-lg font-extrabold tracking-tight sm:text-2xl">
|
|
52
|
+
<span class="{titleHighlightClass || 'text-white'} pr-2"
|
|
53
|
+
>{titleHighlight}</span
|
|
54
|
+
>
|
|
55
|
+
<span class={titleMainClass || "text-gray-200"}>{titleMain}</span>
|
|
56
|
+
</h3>
|
|
57
|
+
|
|
58
|
+
<Button
|
|
59
|
+
onclick={() => onClickButton?.()}
|
|
60
|
+
class="shrink-0 rounded-md bg-white px-4 py-2 text-sm font-medium text-indigo-600 hover:bg-white/90 {buttonClass}"
|
|
61
|
+
>
|
|
62
|
+
{buttonText}
|
|
63
|
+
</Button>
|
|
64
|
+
</div>
|
|
65
|
+
</article>
|
|
66
|
+
{/snippet}
|
|
67
|
+
|
|
68
|
+
{#if href}
|
|
69
|
+
<a {href} class="block">
|
|
70
|
+
{@render content()}
|
|
71
|
+
</a>
|
|
72
|
+
{:else}
|
|
73
|
+
{@render content()}
|
|
74
|
+
{/if}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CtaCardBannerProps } from "./types";
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
title,
|
|
6
|
+
description,
|
|
7
|
+
primaryText,
|
|
8
|
+
secondaryText,
|
|
9
|
+
onClickPrimary,
|
|
10
|
+
onClickSecondary,
|
|
11
|
+
primaryHref,
|
|
12
|
+
secondaryHref,
|
|
13
|
+
class: className = "",
|
|
14
|
+
rings: customRings = [],
|
|
15
|
+
}: CtaCardBannerProps = $props();
|
|
16
|
+
|
|
17
|
+
// Painter's-algorithm rings: largest/darkest first, smallest/lightest last.
|
|
18
|
+
const rings = $derived(
|
|
19
|
+
customRings && customRings.length > 0
|
|
20
|
+
? customRings
|
|
21
|
+
: [
|
|
22
|
+
{ size: 920, color: "#2563EB" },
|
|
23
|
+
{ size: 760, color: "#3B76ED" },
|
|
24
|
+
{ size: 610, color: "#548BF0" },
|
|
25
|
+
{ size: 470, color: "#7FA6F3" },
|
|
26
|
+
{ size: 340, color: "#A9C2F6" },
|
|
27
|
+
{ size: 220, color: "#CFDEFA" },
|
|
28
|
+
{ size: 110, color: "#EEF3FD" },
|
|
29
|
+
],
|
|
30
|
+
);
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
{#snippet pill(
|
|
34
|
+
label: string,
|
|
35
|
+
onClick: (() => void) | undefined,
|
|
36
|
+
href: string | undefined,
|
|
37
|
+
)}
|
|
38
|
+
{#snippet inner()}
|
|
39
|
+
<span class="whitespace-nowrap">{label}</span>
|
|
40
|
+
<span
|
|
41
|
+
class="flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-white"
|
|
42
|
+
>
|
|
43
|
+
<svg
|
|
44
|
+
width="12"
|
|
45
|
+
height="12"
|
|
46
|
+
viewBox="0 0 24 24"
|
|
47
|
+
fill="none"
|
|
48
|
+
stroke="#111"
|
|
49
|
+
stroke-width="2.2"
|
|
50
|
+
stroke-linecap="round"
|
|
51
|
+
stroke-linejoin="round"
|
|
52
|
+
aria-hidden="true"
|
|
53
|
+
>
|
|
54
|
+
<path d="M7 17 L17 7" />
|
|
55
|
+
<path d="M8 7 L17 7 L17 16" />
|
|
56
|
+
</svg>
|
|
57
|
+
</span>
|
|
58
|
+
{/snippet}
|
|
59
|
+
|
|
60
|
+
{#if href}
|
|
61
|
+
<a
|
|
62
|
+
{href}
|
|
63
|
+
class="inline-flex items-center gap-3 rounded-full bg-neutral-900 py-3 pr-2 pl-5 text-sm font-medium text-white transition-colors hover:bg-neutral-800"
|
|
64
|
+
>
|
|
65
|
+
{@render inner()}
|
|
66
|
+
</a>
|
|
67
|
+
{:else}
|
|
68
|
+
<button
|
|
69
|
+
type="button"
|
|
70
|
+
onclick={() => onClick?.()}
|
|
71
|
+
class="inline-flex items-center gap-3 rounded-full bg-neutral-900 py-3 pr-2 pl-5 text-sm font-medium text-white transition-colors hover:bg-neutral-800"
|
|
72
|
+
>
|
|
73
|
+
{@render inner()}
|
|
74
|
+
</button>
|
|
75
|
+
{/if}
|
|
76
|
+
{/snippet}
|
|
77
|
+
|
|
78
|
+
<article
|
|
79
|
+
class="relative isolate overflow-hidden rounded-3xl bg-gradient p-1 shadow-sm {className}"
|
|
80
|
+
>
|
|
81
|
+
<div
|
|
82
|
+
class="relative overflow-hidden rounded-[1.35rem] px-6 py-10 sm:px-10 sm:py-12"
|
|
83
|
+
>
|
|
84
|
+
<!-- Concentric ring decoration -->
|
|
85
|
+
<div class="pointer-events-none absolute inset-0 -z-10" aria-hidden="true">
|
|
86
|
+
{#each rings as ring (ring.size)}
|
|
87
|
+
<div
|
|
88
|
+
class="absolute top-1/2 right-0 rounded-full"
|
|
89
|
+
style="
|
|
90
|
+
width: {ring.size}px;
|
|
91
|
+
height: {ring.size}px;
|
|
92
|
+
background: {ring.color};
|
|
93
|
+
transform: translate(45%, -50%);
|
|
94
|
+
"
|
|
95
|
+
></div>
|
|
96
|
+
{/each}
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<div class="relative z-10 max-w-md">
|
|
100
|
+
<h2 class="text-3xl font-extrabold text-white sm:text-4xl">
|
|
101
|
+
{title}
|
|
102
|
+
</h2>
|
|
103
|
+
|
|
104
|
+
{#if description}
|
|
105
|
+
<p class="mt-3 text-sm leading-relaxed text-white/85 sm:text-base">
|
|
106
|
+
{description}
|
|
107
|
+
</p>
|
|
108
|
+
{/if}
|
|
109
|
+
|
|
110
|
+
<div class="mt-7 flex flex-wrap items-center gap-3">
|
|
111
|
+
{@render pill(primaryText, onClickPrimary, primaryHref)}
|
|
112
|
+
{#if secondaryText}
|
|
113
|
+
{@render pill(secondaryText, onClickSecondary, secondaryHref)}
|
|
114
|
+
{/if}
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</article>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { NotificationBannerProps } from "./types";
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
strongText,
|
|
6
|
+
description,
|
|
7
|
+
ctaText,
|
|
8
|
+
ctaHref,
|
|
9
|
+
onCtaClick,
|
|
10
|
+
onDismiss,
|
|
11
|
+
bgClass = "bg-gray-800/50",
|
|
12
|
+
textClass = "text-gray-100",
|
|
13
|
+
ctaClass,
|
|
14
|
+
class: className = "",
|
|
15
|
+
}: NotificationBannerProps = $props();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<div
|
|
19
|
+
class="relative isolate flex items-center gap-x-6 overflow-hidden {bgClass} px-6 py-2.5 after:pointer-events-none after:absolute after:inset-x-0 after:bottom-0 after:h-px after:bg-white/10 sm:px-3.5 sm:before:flex-1 {className}"
|
|
20
|
+
>
|
|
21
|
+
<!-- Blur decorations -->
|
|
22
|
+
<div
|
|
23
|
+
aria-hidden="true"
|
|
24
|
+
class="absolute top-1/2 left-[max(-7rem,calc(50%-52rem))] -z-10 -translate-y-1/2 transform-gpu blur-2xl"
|
|
25
|
+
>
|
|
26
|
+
<div
|
|
27
|
+
style="clip-path: polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)"
|
|
28
|
+
class="aspect-577/310 w-144.25 bg-linear-to-r from-[#ff80b5] to-[#9089fc] opacity-40"
|
|
29
|
+
></div>
|
|
30
|
+
</div>
|
|
31
|
+
<div
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
class="absolute top-1/2 left-[max(45rem,calc(50%+8rem))] -z-10 -translate-y-1/2 transform-gpu blur-2xl"
|
|
34
|
+
>
|
|
35
|
+
<div
|
|
36
|
+
style="clip-path: polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)"
|
|
37
|
+
class="aspect-577/310 w-144.25 bg-linear-to-r from-[#ff80b5] to-[#9089fc] opacity-40"
|
|
38
|
+
></div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- Content -->
|
|
42
|
+
<div class="flex flex-wrap items-center gap-x-4 gap-y-2">
|
|
43
|
+
<p class="text-sm/6 {textClass}">
|
|
44
|
+
{#if strongText}
|
|
45
|
+
<strong class="font-semibold">{strongText}</strong><svg
|
|
46
|
+
viewBox="0 0 2 2"
|
|
47
|
+
aria-hidden="true"
|
|
48
|
+
class="mx-2 inline size-0.5 fill-current"
|
|
49
|
+
><circle r="1" cx="1" cy="1" /></svg
|
|
50
|
+
>
|
|
51
|
+
{/if}
|
|
52
|
+
{description}
|
|
53
|
+
</p>
|
|
54
|
+
{#if ctaText}
|
|
55
|
+
{#if ctaHref}
|
|
56
|
+
<a
|
|
57
|
+
href={ctaHref}
|
|
58
|
+
class="flex-none rounded-full bg-white/10 px-3.5 py-1 text-sm font-semibold text-white shadow-xs inset-ring-white/20 hover:bg-white/15 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white {ctaClass}"
|
|
59
|
+
>
|
|
60
|
+
{ctaText} <span aria-hidden="true">→</span>
|
|
61
|
+
</a>
|
|
62
|
+
{:else}
|
|
63
|
+
<button
|
|
64
|
+
type="button"
|
|
65
|
+
onclick={onCtaClick}
|
|
66
|
+
class="flex-none rounded-full bg-white/10 px-3.5 py-1 text-sm font-semibold text-white shadow-xs inset-ring-white/20 hover:bg-white/15 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white {ctaClass}"
|
|
67
|
+
>
|
|
68
|
+
{ctaText} <span aria-hidden="true">→</span>
|
|
69
|
+
</button>
|
|
70
|
+
{/if}
|
|
71
|
+
{/if}
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<!-- Dismiss -->
|
|
75
|
+
<div class="flex flex-1 justify-end">
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
onclick={onDismiss}
|
|
79
|
+
class="-m-3 p-3 focus-visible:-outline-offset-4"
|
|
80
|
+
>
|
|
81
|
+
<span class="sr-only">Dismiss</span>
|
|
82
|
+
<svg
|
|
83
|
+
viewBox="0 0 20 20"
|
|
84
|
+
fill="currentColor"
|
|
85
|
+
data-slot="icon"
|
|
86
|
+
aria-hidden="true"
|
|
87
|
+
class="size-5 text-gray-100"
|
|
88
|
+
>
|
|
89
|
+
<path
|
|
90
|
+
d="M6.28 5.22a.75.75 0 0 0-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 1 0 1.06 1.06L10 11.06l3.72 3.72a.75.75 0 1 0 1.06-1.06L11.06 10l3.72-3.72a.75.75 0 0 0-1.06-1.06L10 8.94 6.28 5.22Z"
|
|
91
|
+
/>
|
|
92
|
+
</svg>
|
|
93
|
+
</button>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export type BannerProps = {
|
|
2
|
+
/** Text shown stacked inside the amber side strip, e.g. "Este anúncio pode ser seu." */
|
|
3
|
+
tagText: string;
|
|
4
|
+
/** First part of the headline (rendered in the amber accent color) */
|
|
5
|
+
titleHighlight: string;
|
|
6
|
+
/** Second part of the headline (rendered in the green accent color) */
|
|
7
|
+
titleMain: string;
|
|
8
|
+
/** CTA button label */
|
|
9
|
+
buttonText?: string;
|
|
10
|
+
/** Called when the CTA button is clicked */
|
|
11
|
+
onClickButton?: () => void;
|
|
12
|
+
/** Optional href — if provided, the whole card navigates on click */
|
|
13
|
+
href?: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
titleHighlightClass?: string;
|
|
16
|
+
titleMainClass?: string;
|
|
17
|
+
titleBgClass?: string;
|
|
18
|
+
tagTextClass?: string;
|
|
19
|
+
buttonClass?: string;
|
|
20
|
+
tagBgClass?: string;
|
|
21
|
+
};
|
|
22
|
+
export type NotificationBannerProps = {
|
|
23
|
+
/** Strong text before the separator, e.g. "GeneriCon 2023" */
|
|
24
|
+
strongText?: string;
|
|
25
|
+
/** Main description text */
|
|
26
|
+
description: string;
|
|
27
|
+
/** CTA button label */
|
|
28
|
+
ctaText?: string;
|
|
29
|
+
/** CTA button href */
|
|
30
|
+
ctaHref?: string;
|
|
31
|
+
/** Called when the CTA button is clicked */
|
|
32
|
+
onCtaClick?: () => void;
|
|
33
|
+
/** Called when the dismiss button is clicked */
|
|
34
|
+
onDismiss?: () => void;
|
|
35
|
+
/** Background class, default: bg-gray-800/50 */
|
|
36
|
+
bgClass?: string;
|
|
37
|
+
/** Text class for the description */
|
|
38
|
+
textClass?: string;
|
|
39
|
+
/** CTA button class */
|
|
40
|
+
ctaClass?: string;
|
|
41
|
+
class?: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* "Let's get in touch" style CTA banner: bold title, supporting copy,
|
|
45
|
+
* and up to two pill-shaped action buttons, with a concentric-ring
|
|
46
|
+
* decoration bleeding off the right edge.
|
|
47
|
+
* @component
|
|
48
|
+
*/
|
|
49
|
+
export type CtaCardBannerProps = {
|
|
50
|
+
title: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
primaryText: string;
|
|
53
|
+
secondaryText?: string;
|
|
54
|
+
onClickPrimary?: () => void;
|
|
55
|
+
onClickSecondary?: () => void;
|
|
56
|
+
primaryHref?: string;
|
|
57
|
+
secondaryHref?: string;
|
|
58
|
+
class?: string;
|
|
59
|
+
rings?: Array<{
|
|
60
|
+
size: number;
|
|
61
|
+
color: string;
|
|
62
|
+
}>;
|
|
63
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import Button from "../../../../ui/button/button.svelte";
|
|
3
2
|
import Skeleton from "../../../../ui/skeleton/skeleton.svelte";
|
|
4
|
-
import
|
|
3
|
+
import ImgPlaceholder from "../../../../../assets/placeholder-image.png";
|
|
5
4
|
import CardDescription from "../../shared/CardDescription.svelte";
|
|
6
5
|
import CardFavorite from "../../shared/CardFavorite.svelte";
|
|
7
6
|
import CardTags from "../../shared/CardTags.svelte";
|
|
8
|
-
import ImgPlaceholderCompany from "../../../../../assets/placeholder-company.png";
|
|
9
|
-
import ImgPlaceholder from "../../../../../assets/placeholder-image.png";
|
|
10
7
|
|
|
11
8
|
/**
|
|
12
9
|
* Card component with a title and content.
|
|
13
10
|
* @component
|
|
14
11
|
*/
|
|
15
12
|
import type { CardHighlightProps } from "../../types";
|
|
13
|
+
import CardButton from "../../shared/CardButton.svelte";
|
|
14
|
+
import CardLogo from "../../shared/CardLogo.svelte";
|
|
15
|
+
import { t } from "../../../../../i18n";
|
|
16
16
|
|
|
17
17
|
let {
|
|
18
18
|
id,
|
|
@@ -24,8 +24,10 @@
|
|
|
24
24
|
isLoading = false,
|
|
25
25
|
isFavorite = false,
|
|
26
26
|
buttonText,
|
|
27
|
+
buttonClass,
|
|
27
28
|
isDescriptionIcon,
|
|
28
29
|
isDescriptionLabel,
|
|
30
|
+
isExpandButton = false,
|
|
29
31
|
onClickBtn,
|
|
30
32
|
onClickFavorite,
|
|
31
33
|
}: CardHighlightProps = $props();
|
|
@@ -36,21 +38,7 @@
|
|
|
36
38
|
>
|
|
37
39
|
<aside class="relative rounded-lg border h-50">
|
|
38
40
|
<div class="absolute top-3 left-1 z-2 flex gap-1 w-50">
|
|
39
|
-
{
|
|
40
|
-
<Skeleton class="w-hull h-full rounded-lg" />
|
|
41
|
-
{:else if logo}
|
|
42
|
-
<img
|
|
43
|
-
src={logo}
|
|
44
|
-
alt={`Logo company ${title}`}
|
|
45
|
-
class="rounded-lg w-8 h-8 object-cover object-center"
|
|
46
|
-
/>
|
|
47
|
-
{:else}
|
|
48
|
-
<img
|
|
49
|
-
src={ImgPlaceholderCompany}
|
|
50
|
-
alt={logo}
|
|
51
|
-
class="rounded-lg w-8 h-8 object-cover object-center"
|
|
52
|
-
/>
|
|
53
|
-
{/if}
|
|
41
|
+
<CardLogo {isLoading} {logo} />
|
|
54
42
|
</div>
|
|
55
43
|
|
|
56
44
|
<div class="absolute top-3 right-1 z-2">
|
|
@@ -97,14 +85,19 @@
|
|
|
97
85
|
/>
|
|
98
86
|
</div>
|
|
99
87
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{:else}
|
|
105
|
-
<Button onclick={() => onClickBtn!(id)} class="mt-2 md:mt-3 md:min-w-32">
|
|
106
|
-
{buttonText || $t("label.buy")}
|
|
107
|
-
</Button>
|
|
88
|
+
{#if tags && tags.length > 0}
|
|
89
|
+
<div class="w-full mb-2">
|
|
90
|
+
<CardTags {tags} />
|
|
91
|
+
</div>
|
|
108
92
|
{/if}
|
|
93
|
+
|
|
94
|
+
<CardButton
|
|
95
|
+
{id}
|
|
96
|
+
{isLoading}
|
|
97
|
+
className={buttonClass}
|
|
98
|
+
isFlex={isExpandButton}
|
|
99
|
+
onClick={() => onClickBtn!(id)}
|
|
100
|
+
text={buttonText || $t("label.buy")}
|
|
101
|
+
/>
|
|
109
102
|
</div>
|
|
110
103
|
</article>
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* @component
|
|
13
13
|
*/
|
|
14
14
|
import type { CardHighlightProps } from "../../types";
|
|
15
|
+
import CardButton from "../../shared/CardButton.svelte";
|
|
16
|
+
import CardLogo from "../../shared/CardLogo.svelte";
|
|
15
17
|
|
|
16
18
|
let {
|
|
17
19
|
id,
|
|
@@ -24,7 +26,9 @@
|
|
|
24
26
|
isFavorite = false,
|
|
25
27
|
isDescriptionIcon,
|
|
26
28
|
isDescriptionLabel,
|
|
29
|
+
isExpandButton = false,
|
|
27
30
|
buttonText,
|
|
31
|
+
buttonClass,
|
|
28
32
|
onClickBtn,
|
|
29
33
|
onClickFavorite,
|
|
30
34
|
}: CardHighlightProps = $props();
|
|
@@ -35,23 +39,7 @@
|
|
|
35
39
|
>
|
|
36
40
|
<aside class="relative rounded-lg border h-36">
|
|
37
41
|
<div class="absolute top-3 left-1 z-2 flex gap-1">
|
|
38
|
-
{
|
|
39
|
-
<Skeleton class="w-full h-full rounded-lg" />
|
|
40
|
-
{:else if logo}
|
|
41
|
-
<img
|
|
42
|
-
src={logo}
|
|
43
|
-
alt={logo}
|
|
44
|
-
class="rounded-lg w-8 h-8 object-cover object-center"
|
|
45
|
-
onerror={(e) =>
|
|
46
|
-
((e.target as HTMLImageElement).src = ImgPlaceholderCompany)}
|
|
47
|
-
/>
|
|
48
|
-
{:else}
|
|
49
|
-
<img
|
|
50
|
-
src={ImgPlaceholderCompany}
|
|
51
|
-
alt={logo}
|
|
52
|
-
class="rounded-lg w-8 h-8 object-cover object-center"
|
|
53
|
-
/>
|
|
54
|
-
{/if}
|
|
42
|
+
<CardLogo {isLoading} {logo} />
|
|
55
43
|
</div>
|
|
56
44
|
|
|
57
45
|
<div class="absolute top-3 right-1 z-2">
|
|
@@ -93,16 +81,19 @@
|
|
|
93
81
|
/>
|
|
94
82
|
</div>
|
|
95
83
|
|
|
96
|
-
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
{#if isLoading}
|
|
101
|
-
<Skeleton class="h-10 w-full rounded-md mt-2 md:mt-3" />
|
|
102
|
-
{:else}
|
|
103
|
-
<Button onclick={() => onClickBtn!(id)} class="mt-2 md:mt-3 md:min-w-32">
|
|
104
|
-
{buttonText || $t("label.buy")}
|
|
105
|
-
</Button>
|
|
84
|
+
{#if tags && tags.length > 0}
|
|
85
|
+
<div class="my-2">
|
|
86
|
+
<CardTags {tags} {isLoading} />
|
|
87
|
+
</div>
|
|
106
88
|
{/if}
|
|
89
|
+
|
|
90
|
+
<CardButton
|
|
91
|
+
{id}
|
|
92
|
+
{isLoading}
|
|
93
|
+
className={buttonClass}
|
|
94
|
+
isFlex={isExpandButton}
|
|
95
|
+
onClick={() => onClickBtn!(id)}
|
|
96
|
+
text={buttonText || $t("label.buy")}
|
|
97
|
+
/>
|
|
107
98
|
</div>
|
|
108
99
|
</article>
|
|
@@ -14,8 +14,7 @@ const items = [
|
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
id: 2,
|
|
17
|
-
|
|
18
|
-
imageUrl: undefined,
|
|
17
|
+
imageUrl: 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
19
18
|
title: 'Miramar Suites',
|
|
20
19
|
content: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since 1966, when designers at Letraset and James Mosley, the librarian at St Bride Printing Library in London, took a 1914 Cicero translation and scrambled it to make dummy text for Letraset's Body Type sheets. It has survived not only many decades, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised thanks to these sheets and more recently with desktop publishing software like Aldus PageMaker and Microsoft Word including versions of Lorem Ipsum",
|
|
21
20
|
tags: [
|
|
@@ -24,7 +23,6 @@ const items = [
|
|
|
24
23
|
{ icon: NecklaceIcon, text: 'Rua 19', },
|
|
25
24
|
]
|
|
26
25
|
},
|
|
27
|
-
/*
|
|
28
26
|
{
|
|
29
27
|
id: 3,
|
|
30
28
|
imageUrl: 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
|
|
@@ -60,6 +58,5 @@ const items = [
|
|
|
60
58
|
{ icon: NecklaceIcon, text: 'Rua 19', },
|
|
61
59
|
]
|
|
62
60
|
},
|
|
63
|
-
*/
|
|
64
61
|
];
|
|
65
62
|
export default items;
|