negodesign 0.0.35 → 0.0.37

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 (95) hide show
  1. package/dist/components/core/card/product/01/CardProduct01.svelte +130 -0
  2. package/dist/components/core/card/product/01/CardProduct01.svelte.d.ts +4 -0
  3. package/dist/components/core/card/product/02/CardProduct02.svelte +118 -0
  4. package/dist/components/core/card/product/02/CardProduct02.svelte.d.ts +4 -0
  5. package/dist/components/core/card/product/CardProduct.svelte +22 -0
  6. package/dist/components/core/card/product/CardProduct.svelte.d.ts +11 -0
  7. package/dist/components/core/card/product/data.d.ts +3 -0
  8. package/dist/components/core/card/product/data.js +89 -0
  9. package/dist/components/core/card/profile/01/CardProfile01.svelte +0 -1
  10. package/dist/components/core/card/promotion/CardPromotion.svelte +1 -1
  11. package/dist/components/core/card/promotion/CardPromotionPrice.svelte.d.ts +8 -0
  12. package/dist/components/core/card/shared/CardPhoneOrWhatsapp.svelte +12 -5
  13. package/dist/components/core/card/shared/CardTags.svelte +49 -24
  14. package/dist/components/core/card/shared/CardTitlePrice.svelte +24 -0
  15. package/dist/components/core/card/shared/CardTitlePrice.svelte.d.ts +15 -0
  16. package/dist/components/core/card/shared/TruncatableText.svelte +1 -1
  17. package/dist/components/core/card/types.d.ts +48 -0
  18. package/dist/components/core/carousel/grid/media/ui/CarouselGridMedia.svelte +38 -28
  19. package/dist/components/core/carousel/grid/product/types.d.ts +22 -0
  20. package/dist/components/core/carousel/grid/product/types.js +1 -0
  21. package/dist/components/core/carousel/grid/product/ui/CarouselGridProduct.svelte +71 -0
  22. package/dist/components/core/carousel/grid/product/ui/CarouselGridProduct.svelte.d.ts +4 -0
  23. package/dist/components/core/carousel/grid/profile/ui/CarouselGridProfile.svelte +56 -46
  24. package/dist/components/core/carousel/grid/promotion/types.d.ts +23 -0
  25. package/dist/components/core/carousel/grid/promotion/types.js +1 -0
  26. package/dist/components/core/carousel/grid/promotion/ui/CarouselGridPromotion.svelte +68 -0
  27. package/dist/components/core/carousel/grid/promotion/ui/CarouselGridPromotion.svelte.d.ts +4 -0
  28. package/dist/components/core/carousel/highlights/ui/CarouselHighlights.svelte +57 -47
  29. package/dist/components/core/carousel/product/types.d.ts +21 -0
  30. package/dist/components/core/carousel/product/types.js +1 -0
  31. package/dist/components/core/carousel/product/ui/CarouselProduct.svelte +57 -0
  32. package/dist/components/core/carousel/product/ui/CarouselProduct.svelte.d.ts +4 -0
  33. package/dist/components/core/carousel/promotion/ui/CarouselPromotion.svelte +57 -47
  34. package/dist/components/core/panel/NotFoundEmpty.svelte +76 -0
  35. package/dist/components/core/panel/NotFoundEmpty.svelte.d.ts +16 -0
  36. package/dist/components/pages/company-profile/CompanyProfile.svelte +144 -0
  37. package/dist/components/pages/company-profile/CompanyProfile.svelte.d.ts +4 -0
  38. package/dist/components/pages/company-profile/data.d.ts +2 -0
  39. package/dist/components/pages/company-profile/data.js +115 -0
  40. package/dist/components/pages/company-profile/shared/ProfileAboutCompany.svelte +79 -0
  41. package/dist/components/pages/company-profile/shared/ProfileAboutCompany.svelte.d.ts +9 -0
  42. package/dist/components/pages/company-profile/shared/ProfileBanner.svelte +270 -0
  43. package/dist/components/pages/company-profile/shared/ProfileBanner.svelte.d.ts +14 -0
  44. package/dist/components/pages/company-profile/shared/ProfileGallery.svelte +198 -0
  45. package/dist/components/pages/company-profile/shared/ProfileGallery.svelte.d.ts +9 -0
  46. package/dist/components/pages/company-profile/shared/ProfileMenuBadge.svelte +56 -0
  47. package/dist/components/pages/company-profile/shared/ProfileMenuBadge.svelte.d.ts +11 -0
  48. package/dist/components/pages/company-profile/shared/ProfileProducts.svelte +62 -0
  49. package/dist/components/pages/company-profile/shared/ProfileProducts.svelte.d.ts +9 -0
  50. package/dist/components/pages/company-profile/shared/ProfileSidebar.svelte +57 -0
  51. package/dist/components/pages/company-profile/shared/ProfileSidebar.svelte.d.ts +11 -0
  52. package/dist/components/pages/company-profile/types.d.ts +137 -0
  53. package/dist/components/pages/company-profile/types.js +1 -0
  54. package/dist/components/pages/privacy-policy-or-terms-of-use/data.d.ts +3 -0
  55. package/dist/components/pages/privacy-policy-or-terms-of-use/data.js +179 -0
  56. package/dist/components/pages/privacy-policy-or-terms-of-use/shared/DocSectionView.svelte +2 -1
  57. package/dist/components/pages/privacy-policy-or-terms-of-use/shared/DocSectionView.svelte.d.ts +1 -0
  58. package/dist/components/pages/product-details/01/ProductDetails01.svelte +19 -7
  59. package/dist/components/pages/product-details/02/ProductDetails02.svelte +42 -37
  60. package/dist/components/pages/product-details/03/ProductDetails03.svelte +33 -29
  61. package/dist/components/pages/product-details/ProductDetails.svelte +11 -7
  62. package/dist/components/pages/product-details/shared/ProductDetailFeatures.svelte +11 -5
  63. package/dist/components/pages/product-details/shared/ProductDetailFeatures.svelte.d.ts +2 -1
  64. package/dist/components/pages/product-details/shared/ProductDetailFilesVertical.svelte +52 -20
  65. package/dist/components/pages/product-details/shared/ProductDetailFilesVertical.svelte.d.ts +1 -1
  66. package/dist/components/pages/product-details/shared/ProductDetailImage.svelte +51 -20
  67. package/dist/components/pages/product-details/shared/ProductDetailImage.svelte.d.ts +1 -1
  68. package/dist/components/pages/product-details/shared/ProductDetailPrice.svelte +1 -1
  69. package/dist/components/pages/product-details/types.d.ts +9 -2
  70. package/dist/components/pages/profile-user/types.d.ts +7 -0
  71. package/dist/components/ui/empty/empty-content.svelte +23 -0
  72. package/dist/components/ui/empty/empty-content.svelte.d.ts +5 -0
  73. package/dist/components/ui/empty/empty-description.svelte +23 -0
  74. package/dist/components/ui/empty/empty-description.svelte.d.ts +5 -0
  75. package/dist/components/ui/empty/empty-header.svelte +20 -0
  76. package/dist/components/ui/empty/empty-header.svelte.d.ts +5 -0
  77. package/dist/components/ui/empty/empty-media.svelte +41 -0
  78. package/dist/components/ui/empty/empty-media.svelte.d.ts +26 -0
  79. package/dist/components/ui/empty/empty-title.svelte +20 -0
  80. package/dist/components/ui/empty/empty-title.svelte.d.ts +5 -0
  81. package/dist/components/ui/empty/empty.svelte +23 -0
  82. package/dist/components/ui/empty/empty.svelte.d.ts +5 -0
  83. package/dist/components/ui/empty/index.d.ts +7 -0
  84. package/dist/components/ui/empty/index.js +9 -0
  85. package/dist/globals.css +301 -5
  86. package/dist/i18n/langs/en.d.ts +25 -0
  87. package/dist/i18n/langs/en.js +25 -0
  88. package/dist/i18n/langs/pt.d.ts +25 -0
  89. package/dist/i18n/langs/pt.js +25 -0
  90. package/dist/i18n/translations.d.ts +50 -0
  91. package/package.json +1 -1
  92. package/dist/components/core/card/shared/CardStartPrice.svelte.d.ts +0 -8
  93. package/dist/components/pages/product-details/04/ProductDetails04.svelte +0 -65
  94. package/dist/components/pages/product-details/04/ProductDetails04.svelte.d.ts +0 -11
  95. /package/dist/components/core/card/{shared/CardStartPrice.svelte → promotion/CardPromotionPrice.svelte} +0 -0
@@ -0,0 +1,130 @@
1
+ <script lang="ts">
2
+ import Button from "../../../../ui/button/button.svelte";
3
+ import Skeleton from "../../../../ui/skeleton/skeleton.svelte";
4
+ import { t } from "../../../../../i18n";
5
+ import ImgPlaceHolderGallery from "../../../../../assets/placeholder-image.png";
6
+ import ImgPlaceholderCompany from "../../../../../assets/placeholder-company.png";
7
+ import type { CardProductProps } from "../../types";
8
+ import CardFavorite from "../../shared/CardFavorite.svelte";
9
+ import CardCart from "../../shared/CardCart.svelte";
10
+ import CardDescription from "../../shared/CardDescription.svelte";
11
+ import CardTags from "../../shared/CardTags.svelte";
12
+ import CardTitlePrice from "../../shared/CardTitlePrice.svelte";
13
+
14
+ /**
15
+ * Card component with a title and content.
16
+ * @component
17
+ */
18
+
19
+ let {
20
+ id,
21
+ tags,
22
+ logo,
23
+ title,
24
+ imageUrl,
25
+ rating = 0,
26
+ isFavorite = false,
27
+ isCart = false,
28
+ isLoading = false,
29
+ content,
30
+ price,
31
+ buttonBuyText,
32
+ buttonBuyClass,
33
+ isDescriptionIcon,
34
+ isDescriptionLabel,
35
+ onClickBuy,
36
+ onClickShop,
37
+ onClickFavorite,
38
+ }: CardProductProps = $props();
39
+ </script>
40
+
41
+ <article class="relative rounded-lg border">
42
+ <aside class="relative w-full p-2">
43
+ <div class="absolute top-2 left-2 z-2 gap-1 p-2">
44
+ {#if isLoading}
45
+ <Skeleton class="h-5 w-20 rounded-full bg-black/20" />
46
+ {:else if logo}
47
+ <img
48
+ src={logo}
49
+ width={30}
50
+ height={30}
51
+ alt={title}
52
+ onerror={(e) =>
53
+ ((e.target as HTMLImageElement).src = ImgPlaceholderCompany)}
54
+ class="rounded-lg"
55
+ />
56
+ {:else}
57
+ <img
58
+ src={ImgPlaceholderCompany}
59
+ width={30}
60
+ height={30}
61
+ alt={title}
62
+ class="rounded-lg"
63
+ />
64
+ {/if}
65
+ </div>
66
+
67
+ <div class="absolute top-2 right-2 z-2 flex items-center gap-1 p-2">
68
+ <CardFavorite
69
+ {id}
70
+ {isFavorite}
71
+ {isLoading}
72
+ onFavoriteClick={onClickFavorite}
73
+ />
74
+ <CardCart {id} {isCart} {isLoading} onCartClick={onClickShop} />
75
+ </div>
76
+
77
+ {#if isLoading}
78
+ <Skeleton
79
+ class="rounded-lg h-30 w-full object-cover object-center bg-black/15"
80
+ />
81
+ {:else if imageUrl}
82
+ <img
83
+ src={imageUrl}
84
+ alt={imageUrl}
85
+ class="rounded-lg h-36 md:h-44 w-full object-cover object-center"
86
+ onerror={(e) =>
87
+ ((e.target as HTMLImageElement).src = ImgPlaceHolderGallery)}
88
+ />
89
+ {/if}
90
+ <div class="absolute inset-0 bg-black/5 rounded-sm h-full w-full"></div>
91
+ </aside>
92
+
93
+ <aside
94
+ class="bottom-1 inset-x-0 flex flex-col items-center justify-center gap-0.5 m-auto max-w-11/12 p-1 rounded-md"
95
+ >
96
+ <div class="flex justify-between w-full items-center mb-1">
97
+ {#if title}
98
+ {#if isLoading}
99
+ <Skeleton class="h-4 w-30 rounded-lg" />
100
+ {:else}
101
+ <div class="font-semibold line-clamp-1 flex-nowrap">
102
+ {title}
103
+ </div>
104
+ {/if}
105
+ {/if}
106
+ <CardTitlePrice {title} {isLoading} {price} />
107
+ </div>
108
+
109
+ {#if tags && tags.length > 0}
110
+ <div class="w-full my-1">
111
+ <CardTags {tags} />
112
+ </div>
113
+ {/if}
114
+
115
+ <div>
116
+ <CardDescription {content} {isDescriptionIcon} {isDescriptionLabel} />
117
+ </div>
118
+
119
+ {#if isLoading}
120
+ <Skeleton class="h-9 w-full rounded-md" />
121
+ {:else}
122
+ <Button
123
+ onclick={() => onClickBuy!(id)}
124
+ class="w-full mb-2 bg-gradient text-white rounded-full {buttonBuyClass}"
125
+ >
126
+ {buttonBuyText || $t("label.buy")}
127
+ </Button>
128
+ {/if}
129
+ </aside>
130
+ </article>
@@ -0,0 +1,4 @@
1
+ import type { CardProductProps } from "../../types";
2
+ declare const CardProduct01: import("svelte").Component<CardProductProps, {}, "">;
3
+ type CardProduct01 = ReturnType<typeof CardProduct01>;
4
+ export default CardProduct01;
@@ -0,0 +1,118 @@
1
+ <script lang="ts">
2
+ import Button from "../../../../ui/button/button.svelte";
3
+ import Skeleton from "../../../../ui/skeleton/skeleton.svelte";
4
+ import { t } from "../../../../../i18n";
5
+ import ImgPlaceHolderGallery from "../../../../../assets/placeholder-image.png";
6
+ import ImgPlaceholderCompany from "../../../../../assets/placeholder-company.png";
7
+ import type { CardProductProps } from "../../types";
8
+ import CardFavorite from "../../shared/CardFavorite.svelte";
9
+ import CardCart from "../../shared/CardCart.svelte";
10
+ import CardDescription from "../../shared/CardDescription.svelte";
11
+ import CardTags from "../../shared/CardTags.svelte";
12
+ import CardTitlePrice from "../../shared/CardTitlePrice.svelte";
13
+
14
+ /**
15
+ * Card component with a title and content.
16
+ * @component
17
+ */
18
+
19
+ let {
20
+ id,
21
+ tags,
22
+ logo,
23
+ title,
24
+ imageUrl,
25
+ isFavorite = false,
26
+ isCart = false,
27
+ isLoading = false,
28
+ content,
29
+ price,
30
+ buttonBuyText,
31
+ buttonBuyClass,
32
+ isDescriptionIcon,
33
+ isDescriptionLabel,
34
+ onClickBuy,
35
+ onClickShop,
36
+ onClickFavorite,
37
+ }: CardProductProps = $props();
38
+ </script>
39
+
40
+ <article class="relative rounded-lg border">
41
+ <aside class="relative w-full">
42
+ <div class="absolute top-1 left-1 z-2 gap-1 p-2">
43
+ {#if isLoading}
44
+ <Skeleton class="h-5 w-20 rounded-full bg-black/20" />
45
+ {:else if logo}
46
+ <img
47
+ src={logo}
48
+ width={30}
49
+ height={30}
50
+ alt={title}
51
+ onerror={(e) =>
52
+ ((e.target as HTMLImageElement).src = ImgPlaceholderCompany)}
53
+ class="rounded-lg"
54
+ />
55
+ {:else}
56
+ <img
57
+ src={ImgPlaceholderCompany}
58
+ width={30}
59
+ height={30}
60
+ alt={title}
61
+ class="rounded-lg"
62
+ />
63
+ {/if}
64
+ </div>
65
+
66
+ <div class="absolute top-1 right-1 z-2 flex items-center gap-1 p-2">
67
+ <CardFavorite
68
+ {id}
69
+ {isFavorite}
70
+ {isLoading}
71
+ onFavoriteClick={onClickFavorite}
72
+ />
73
+ <CardCart {id} {isCart} {isLoading} onCartClick={onClickShop} />
74
+ </div>
75
+
76
+ {#if isLoading}
77
+ <Skeleton
78
+ class="rounded-lg h-30 w-full object-cover object-center bg-black/15"
79
+ />
80
+ {:else if imageUrl}
81
+ <img
82
+ src={imageUrl}
83
+ alt={imageUrl}
84
+ class="rounded-tr-lg rounded-tl-lg h-36 md:h-44 w-full object-cover object-center"
85
+ onerror={(e) =>
86
+ ((e.target as HTMLImageElement).src = ImgPlaceHolderGallery)}
87
+ />
88
+ {/if}
89
+ <div class="absolute inset-0 bg-black/5 rounded-sm h-full w-full"></div>
90
+ </aside>
91
+
92
+ <aside
93
+ class="bottom-1 inset-x-0 flex flex-col items-center justify-center gap-0.5 m-auto max-w-11/12 p-1 rounded-md"
94
+ >
95
+ <CardTitlePrice {title} {isLoading} {price} />
96
+
97
+ <div>
98
+ <CardDescription {content} {isDescriptionIcon} {isDescriptionLabel} />
99
+ </div>
100
+
101
+ {#if tags && tags.length > 0}
102
+ <div class="w-full mb-2">
103
+ <CardTags {tags} />
104
+ </div>
105
+ {/if}
106
+
107
+ {#if isLoading}
108
+ <Skeleton class="h-9 w-full rounded-md" />
109
+ {:else}
110
+ <Button
111
+ onclick={() => onClickBuy!(id)}
112
+ class="w-full bottom-0 bg-gradient {buttonBuyClass}"
113
+ >
114
+ {buttonBuyText || $t("label.buy")}
115
+ </Button>
116
+ {/if}
117
+ </aside>
118
+ </article>
@@ -0,0 +1,4 @@
1
+ import type { CardProductProps } from "../../types";
2
+ declare const CardProduct02: import("svelte").Component<CardProductProps, {}, "">;
3
+ type CardProduct02 = ReturnType<typeof CardProduct02>;
4
+ export default CardProduct02;
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ /**
3
+ * Card component with a title and content.
4
+ * @component
5
+ */
6
+ import type { CardProductProps } from "../types";
7
+ import CardProduct01 from "./01/CardProduct01.svelte";
8
+ import CardProduct02 from "./02/CardProduct02.svelte";
9
+
10
+ let {
11
+ variant,
12
+ ...restProps
13
+ }: CardProductProps & {
14
+ variant?: 1 | 2;
15
+ } = $props();
16
+ </script>
17
+
18
+ {#if variant === 2}
19
+ <CardProduct02 {...restProps} />
20
+ {:else}
21
+ <CardProduct01 {...restProps} />
22
+ {/if}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Card component with a title and content.
3
+ * @component
4
+ */
5
+ import type { CardProductProps } from "../types";
6
+ type $$ComponentProps = CardProductProps & {
7
+ variant?: 1 | 2;
8
+ };
9
+ declare const CardProduct: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type CardProduct = ReturnType<typeof CardProduct>;
11
+ export default CardProduct;
@@ -0,0 +1,3 @@
1
+ import type { CardProductProps } from "../types";
2
+ declare const items: CardProductProps[];
3
+ export default items;
@@ -0,0 +1,89 @@
1
+ import { GlobalIcon, MapPin, NecklaceIcon } from "@hugeicons/core-free-icons";
2
+ const items = [
3
+ {
4
+ id: 1,
5
+ 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",
6
+ title: "Hotel Baía Azul",
7
+ content: "Acomodação premium de frente para o mar com quartos luxuosos, restaurante internacional, piscina aquecida e serviço de transfer exclusivo para hóspedes.",
8
+ isFavorite: true,
9
+ price: "45.000 Kz",
10
+ buttonBuyText: "Comprar",
11
+ onClickBuy: (id) => alert(`Comprar produto ${id}`),
12
+ onClickShop: (id) => alert(`Adicionar ao carrinho ${id}`),
13
+ isCart: true,
14
+ tags: [
15
+ { icon: GlobalIcon, text: "Luanda" },
16
+ { icon: MapPin, text: "Ilha do Cabo" },
17
+ { icon: NecklaceIcon, text: "Frente ao Mar" },
18
+ ],
19
+ },
20
+ {
21
+ id: 2,
22
+ imageUrl: "https://images.unsplash.com/photo-1566073771259-6a8506099945?q=80&w=1170&auto=format&fit=crop",
23
+ title: "Miramar Suites",
24
+ content: "Suítes executivas com vista panorâmica da baía, internet de alta velocidade, pequeno-almoço buffet incluído e centro de conferências moderno.",
25
+ isFavorite: false,
26
+ price: "38.500 Kz",
27
+ buttonBuyText: "Comprar",
28
+ onClickBuy: (id) => alert(`Comprar produto ${id}`),
29
+ onClickShop: (id) => alert(`Adicionar ao carrinho ${id}`),
30
+ isCart: true,
31
+ tags: [
32
+ { icon: GlobalIcon, text: "Luanda" },
33
+ { icon: MapPin, text: "Miramar" },
34
+ { icon: NecklaceIcon, text: "Executivo" },
35
+ ],
36
+ },
37
+ {
38
+ id: 3,
39
+ imageUrl: "https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?q=80&w=1170&auto=format&fit=crop",
40
+ title: "Palm Resort & Spa",
41
+ content: "Resort paradisíaco rodeado por palmeiras com spa completo, campos de ténis, atividades infantis e acesso privativo à praia.",
42
+ isFavorite: true,
43
+ price: "52.000 Kz",
44
+ buttonBuyText: "Comprar",
45
+ onClickBuy: (id) => alert(`Comprar produto ${id}`),
46
+ onClickShop: (id) => alert(`Adicionar ao carrinho ${id}`),
47
+ isCart: true,
48
+ tags: [
49
+ { icon: GlobalIcon, text: "Benguela" },
50
+ { icon: MapPin, text: "Baía Farta" },
51
+ { icon: NecklaceIcon, text: "Spa & Lazer" },
52
+ ],
53
+ },
54
+ {
55
+ id: 4,
56
+ imageUrl: "https://images.unsplash.com/photo-1542314831-068cd1dbfeeb?q=80&w=1170&auto=format&fit=crop",
57
+ title: "Hotel Central Park",
58
+ content: "Localização privilegiada no coração financeiro da cidade, perfeito para viagens de negócios e turismo cultural.",
59
+ isFavorite: false,
60
+ price: "29.900 Kz",
61
+ buttonBuyText: "Comprar",
62
+ onClickBuy: (id) => alert(`Comprar produto ${id}`),
63
+ onClickShop: (id) => alert(`Adicionar ao carrinho ${id}`),
64
+ isCart: true,
65
+ tags: [
66
+ { icon: GlobalIcon, text: "Huambo" },
67
+ { icon: MapPin, text: "Centro" },
68
+ { icon: NecklaceIcon, text: "Urbano" },
69
+ ],
70
+ },
71
+ {
72
+ id: 5,
73
+ imageUrl: "https://images.unsplash.com/photo-1571896349842-33c89424de2d?q=80&w=1170&auto=format&fit=crop",
74
+ title: "Villa Serena Boutique",
75
+ content: "Charme e tranquilidade num ambiente intimista com arquitetura rústica, piscina infinita e gastronomia regional selecionada.",
76
+ isFavorite: true,
77
+ price: "60.000 Kz",
78
+ buttonBuyText: "Comprar",
79
+ onClickBuy: (id) => alert(`Comprar produto ${id}`),
80
+ onClickShop: (id) => alert(`Adicionar ao carrinho ${id}`),
81
+ isCart: true,
82
+ tags: [
83
+ { icon: GlobalIcon, text: "Namibe" },
84
+ { icon: MapPin, text: "Praia Amélia" },
85
+ { icon: NecklaceIcon, text: "Boutique" },
86
+ ],
87
+ },
88
+ ];
89
+ export default items;
@@ -93,7 +93,6 @@
93
93
  {isLoading}
94
94
  {isDescriptionIcon}
95
95
  {isDescriptionLabel}
96
- lines={tags.length == 0 ? 3 : 2}
97
96
  />
98
97
  </div>
99
98
 
@@ -5,7 +5,7 @@
5
5
  import CardCart from "../shared/CardCart.svelte";
6
6
  import CardDescription from "../shared/CardDescription.svelte";
7
7
  import CardFavorite from "../shared/CardFavorite.svelte";
8
- import CardStartPrice from "../shared/CardStartPrice.svelte";
8
+ import CardStartPrice from "./CardPromotionPrice.svelte";
9
9
  import CardTags from "../shared/CardTags.svelte";
10
10
  import ImgPlaceHolderGallery from "../../../../assets/placeholder-image.png";
11
11
  import ImgPlaceholderCompany from "../../../../assets/placeholder-company.png";
@@ -0,0 +1,8 @@
1
+ type Props = {
2
+ newPrice?: string | number;
3
+ oldPrice?: string | number;
4
+ type?: "start" | "normal";
5
+ };
6
+ declare const CardPromotionPrice: import("svelte").Component<Props, {}, "">;
7
+ type CardPromotionPrice = ReturnType<typeof CardPromotionPrice>;
8
+ export default CardPromotionPrice;
@@ -3,18 +3,25 @@
3
3
  import { HugeiconsIcon } from "@hugeicons/svelte";
4
4
  import type { CardPhoneOrWhatsappProps } from "../types";
5
5
 
6
- let { id, onEmailClick, onWhatsappClick }: CardPhoneOrWhatsappProps =
7
- $props();
6
+ let {
7
+ id,
8
+ className,
9
+ buttonClass,
10
+ btnWhatsappClass,
11
+ btnEmailClass,
12
+ onEmailClick,
13
+ onWhatsappClick,
14
+ }: CardPhoneOrWhatsappProps = $props();
8
15
 
9
16
  let isFlex = $derived(onEmailClick && onWhatsappClick);
10
17
  </script>
11
18
 
12
- <div class="flex border-t border-gray-300 dark:border-gray-700">
19
+ <div class="flex border-t border-gray-300 dark:border-gray-700 {className}">
13
20
  {#if onEmailClick}
14
21
  <button
15
22
  class="flex-1 flex justify-center items-center gap-2 p-3 hover:bg-red-800 hover:text-white cursor-pointer rounded-bl-lg {!isFlex
16
23
  ? 'rounded-br-lg'
17
- : ''}"
24
+ : ''} {buttonClass} {btnEmailClass}"
18
25
  onclick={() => onEmailClick?.(id)}
19
26
  >
20
27
  <HugeiconsIcon icon={Mail01Icon} size={20} />
@@ -28,7 +35,7 @@
28
35
  <button
29
36
  class="flex-1 flex justify-center items-center gap-2 p-3 hover:bg-green-600 hover:text-white cursor-pointer rounded-br-lg {!isFlex
30
37
  ? 'rounded-bl-lg'
31
- : ''}"
38
+ : ''} {buttonClass} {btnWhatsappClass}"
32
39
  onclick={() => onWhatsappClick?.(id)}
33
40
  >
34
41
  <HugeiconsIcon icon={WhatsappIcon} size={20} />
@@ -2,6 +2,7 @@
2
2
  import { HugeiconsIcon } from "@hugeicons/svelte";
3
3
  import type { CardTagsProps } from "../types";
4
4
  import Skeleton from "../../../ui/skeleton/skeleton.svelte";
5
+ import * as Popover from "../../../ui/popover"; // adjust path to your setup
5
6
 
6
7
  type Props = {
7
8
  className?: string;
@@ -20,13 +21,14 @@
20
21
  }: Props = $props();
21
22
 
22
23
  let isJustify = $derived(tags?.length == 2 || tags?.length == 3);
24
+ let open = $state(false);
23
25
  </script>
24
26
 
25
- {#snippet createBadge(tag: CardTagsProps)}
27
+ {#snippet createBadge(tag: CardTagsProps, clasName?: string)}
26
28
  <div
27
29
  class="flex items-center h-5 shrink-0 {isTagBorderBottom
28
30
  ? 'border border-gray-200 rounded-full px-2 py-1'
29
- : ''}"
31
+ : ''} {clasName}"
30
32
  >
31
33
  {#if tag.icon}
32
34
  <HugeiconsIcon icon={tag.icon} class="mr-0.5 h-3.75 w-3.75 shrink-0" />
@@ -43,28 +45,51 @@
43
45
  </div>
44
46
  {/snippet}
45
47
 
46
- {#if isWrap}
47
- <div class="flex flex-wrap gap-2 md:gap-5 {className}">
48
- {#if isLoading}
49
- {@render skeletonTag()}
50
- {:else if tags && tags.length > 0}
51
- {#each tags as tag, i (i)}
52
- {@render createBadge(tag)}
53
- {/each}
54
- {/if}
55
- </div>
56
- {:else}
57
- <div
58
- class="flex overflow-x-auto no-scrollbar w-full min-w-0
59
- {isJustify ? 'justify-between gap-3' : 'gap-4 md:gap-5 lg:gap-10'}
60
- {className}"
48
+ {#snippet tagsRow()}
49
+ {#if isWrap}
50
+ <div class="flex flex-wrap gap-2 md:gap-5 {className}">
51
+ {#if isLoading}
52
+ {@render skeletonTag()}
53
+ {:else if tags && tags.length > 0}
54
+ {#each tags as tag, i (i)}
55
+ {@render createBadge(tag)}
56
+ {/each}
57
+ {/if}
58
+ </div>
59
+ {:else}
60
+ <div
61
+ class="flex overflow-x-auto no-scrollbar w-full min-w-0
62
+ {isJustify ? 'justify-between gap-3' : 'gap-4 md:gap-5 lg:gap-10'}
63
+ {className}"
64
+ >
65
+ {#if isLoading}
66
+ {@render skeletonTag()}
67
+ {:else if tags && tags.length > 0}
68
+ {#each tags as tag, i (i)}
69
+ {@render createBadge(tag)}
70
+ {/each}
71
+ {/if}
72
+ </div>
73
+ {/if}
74
+ {/snippet}
75
+
76
+ <Popover.Root bind:open>
77
+ <Popover.Trigger
78
+ onmouseenter={() => (open = true)}
79
+ onmouseleave={() => (open = false)}
80
+ class="block w-full text-left"
81
+ >
82
+ {@render tagsRow()}
83
+ </Popover.Trigger>
84
+ <Popover.Content
85
+ class="w-auto max-w-xs p-3"
86
+ onmouseenter={() => (open = true)}
87
+ onmouseleave={() => (open = false)}
61
88
  >
62
- {#if isLoading}
63
- {@render skeletonTag()}
64
- {:else if tags && tags.length > 0}
89
+ <div class="flex flex-col gap-2">
65
90
  {#each tags as tag, i (i)}
66
- {@render createBadge(tag)}
91
+ {@render createBadge(tag, "gap-2")}
67
92
  {/each}
68
- {/if}
69
- </div>
70
- {/if}
93
+ </div>
94
+ </Popover.Content>
95
+ </Popover.Root>
@@ -0,0 +1,24 @@
1
+ <script>
2
+ import Skeleton from "../../../ui/skeleton/skeleton.svelte";
3
+
4
+ let { title, isLoading, price } = $props();
5
+ </script>
6
+
7
+ <div class="flex justify-between w-full items-center">
8
+ {#if title}
9
+ {#if isLoading}
10
+ <Skeleton class="h-4 w-30 rounded-lg" />
11
+ {:else}
12
+ <div class="font-semibold line-clamp-1 flex-nowrap">
13
+ {title}
14
+ </div>
15
+ {/if}
16
+ {/if}
17
+ <div class="flex justify-start gap-2">
18
+ {#if isLoading}
19
+ <Skeleton class="h-5 bg-black/10 w-25 my-2 mr-2" />
20
+ {:else if price}
21
+ <div class="text-lg font-semibold text-primary">{price}</div>
22
+ {/if}
23
+ </div>
24
+ </div>
@@ -0,0 +1,15 @@
1
+ export default CardTitlePrice;
2
+ type CardTitlePrice = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ declare const CardTitlePrice: import("svelte").Component<{
7
+ title: any;
8
+ isLoading: any;
9
+ price: any;
10
+ }, {}, "">;
11
+ type $$ComponentProps = {
12
+ title: any;
13
+ isLoading: any;
14
+ price: any;
15
+ };
@@ -29,7 +29,7 @@
29
29
  </script>
30
30
 
31
31
  <div class="relative">
32
- <p bind:this={textEl} class="line-clamp-{lines} {className}">
32
+ <p bind:this={textEl} class="line-clamp-3 {className}">
33
33
  {text}
34
34
  </p>
35
35
 
@@ -189,6 +189,54 @@ export interface CardHighlightProps {
189
189
  }
190
190
  export interface CardPhoneOrWhatsappProps {
191
191
  id: string | number;
192
+ className?: string;
193
+ buttonClass?: string;
194
+ btnWhatsappClass?: string;
195
+ btnEmailClass?: string;
192
196
  onEmailClick?: (id: string | number) => void;
193
197
  onWhatsappClick?: (id: string | number) => void;
194
198
  }
199
+ /**
200
+ * Props do CardProduct — card de produto com preço antigo/novo,
201
+ * botão de comprar, favoritar e adicionar ao carrinho.
202
+ */
203
+ export interface CardProductProps {
204
+ /** Identificador único da produto */
205
+ id: string | number;
206
+ /** Rating da produto */
207
+ rating?: number;
208
+ /** URL do logotipo */
209
+ logo?: string;
210
+ /** URL da imagem do produto em produto */
211
+ imageUrl?: string;
212
+ /** Nome/título da produto */
213
+ title?: string;
214
+ /** Descrição da produto */
215
+ content?: string;
216
+ /** Classe CSS adicional */
217
+ className?: string;
218
+ /** Indica se o botão de carrinho está ativo */
219
+ isCart?: boolean;
220
+ /** Estado de carregamento (skeleton) */
221
+ isLoading?: boolean;
222
+ /** Indica se está marcado como favorito */
223
+ isFavorite?: boolean;
224
+ /** Lista de tags */
225
+ tags?: CardTagsProps[];
226
+ /** Preço do produto */
227
+ price?: string | number;
228
+ /** Texto do botão de compra (padrão: "Comprar") */
229
+ buttonBuyText?: string;
230
+ /** Classe CSS personalizada para o botão comprar */
231
+ buttonBuyClass?: string;
232
+ /** Exibe ícone antes da descrição */
233
+ isDescriptionIcon?: boolean;
234
+ /** Exibe etiqueta (label) na descrição */
235
+ isDescriptionLabel?: boolean;
236
+ /** Callback ao clicar no botão comprar */
237
+ onClickBuy?: (id: string | number) => void;
238
+ /** Callback ao clicar no botão carrinho */
239
+ onClickShop?: (id: string | number) => void;
240
+ /** Callback ao clicar no botão favorito */
241
+ onClickFavorite?: (id: string | number) => void;
242
+ }