negodesign 0.0.74 → 0.0.76
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/components/pages/security/auth/PageAuth01.svelte +65 -0
- package/dist/components/pages/security/auth/PageAuth01.svelte.d.ts +17 -0
- package/dist/components/pages/security/auth/PageAuth02.svelte +45 -0
- package/dist/components/pages/security/auth/PageAuth02.svelte.d.ts +17 -0
- package/dist/components/pages/security/auth/PageAuth03.svelte +45 -0
- package/dist/components/pages/security/auth/PageAuth03.svelte.d.ts +17 -0
- package/dist/components/pages/security/login/01/ui/PageLogin01.svelte +15 -40
- package/dist/components/pages/security/login/02/ui/LoginCard02.svelte +15 -4
- package/dist/components/pages/security/login/02/ui/PageLogin02.svelte +15 -20
- package/dist/components/pages/security/login/03/ui/LoginCard03.svelte +34 -16
- package/dist/components/pages/security/login/03/ui/PageLogin03.svelte +15 -20
- package/dist/components/pages/security/register/01/ui/PageRegister01.svelte +64 -0
- package/dist/components/pages/security/register/01/ui/PageRegister01.svelte.d.ts +3 -0
- package/dist/components/pages/security/register/01/ui/RegisterCard.svelte +100 -0
- package/dist/components/pages/security/register/01/ui/RegisterCard.svelte.d.ts +12 -0
- package/dist/components/pages/security/register/02/ui/PageRegister02.svelte +76 -0
- package/dist/components/pages/security/register/02/ui/PageRegister02.svelte.d.ts +4 -0
- package/dist/components/pages/security/register/02/ui/RegisterCard02.svelte +98 -0
- package/dist/components/pages/security/register/02/ui/RegisterCard02.svelte.d.ts +12 -0
- package/dist/components/pages/security/register/03/ui/PageRegister03.svelte +76 -0
- package/dist/components/pages/security/register/03/ui/PageRegister03.svelte.d.ts +4 -0
- package/dist/components/pages/security/register/03/ui/RegisterCard03.svelte +103 -0
- package/dist/components/pages/security/register/03/ui/RegisterCard03.svelte.d.ts +12 -0
- package/dist/components/pages/security/register/FormRegister.svelte +120 -0
- package/dist/components/pages/security/register/FormRegister.svelte.d.ts +8 -0
- package/dist/components/pages/security/register/PageRegister.svelte +30 -0
- package/dist/components/pages/security/register/PageRegister.svelte.d.ts +8 -0
- package/dist/components/pages/security/register/types.d.ts +51 -0
- package/dist/components/pages/security/register/types.js +1 -0
- package/dist/components/ui/form/Form.svelte +171 -0
- package/dist/components/ui/form/Form.svelte.d.ts +4 -0
- package/dist/components/ui/form/types.d.ts +78 -0
- package/dist/components/ui/form/types.js +1 -0
- package/dist/components/ui/form/ui/input-badges.svelte +214 -0
- package/dist/components/ui/form/ui/input-badges.svelte.d.ts +14 -0
- package/dist/components/ui/form/ui/input-checkbox.svelte +86 -0
- package/dist/components/ui/form/ui/input-checkbox.svelte.d.ts +17 -0
- package/dist/components/ui/form/ui/input-radio.svelte +82 -0
- package/dist/components/ui/form/ui/input-radio.svelte.d.ts +17 -0
- package/dist/components/ui/form/ui/input-select.svelte +195 -0
- package/dist/components/ui/form/ui/input-select.svelte.d.ts +17 -0
- package/dist/components/ui/form/ui/input-textarea.svelte +61 -0
- package/dist/components/ui/form/ui/input-textarea.svelte.d.ts +13 -0
- package/dist/components/ui/form/ui/input-toggle.svelte +89 -0
- package/dist/components/ui/form/ui/input-toggle.svelte.d.ts +11 -0
- package/dist/components/ui/modal/badge/index.d.ts +3 -0
- package/dist/components/ui/modal/badge/index.js +2 -0
- package/dist/components/ui/modal/badge/types.d.ts +35 -0
- package/dist/components/ui/modal/badge/types.js +1 -0
- package/dist/components/ui/modal/badge/ui/ModalBadgeSelection.svelte +87 -0
- package/dist/components/ui/modal/badge/ui/ModalBadgeSelection.svelte.d.ts +4 -0
- package/dist/components/ui/modal/core/index.d.ts +3 -0
- package/dist/components/ui/modal/core/index.js +2 -0
- package/dist/components/ui/modal/core/types.d.ts +84 -0
- package/dist/components/ui/modal/core/types.js +1 -0
- package/dist/components/ui/modal/core/ui/ModalCore.svelte +132 -0
- package/dist/components/ui/modal/core/ui/ModalCore.svelte.d.ts +4 -0
- package/dist/components/ui/modal/feedback/index.d.ts +3 -0
- package/dist/components/ui/modal/feedback/index.js +2 -0
- package/dist/components/ui/modal/feedback/types.d.ts +32 -0
- package/dist/components/ui/modal/feedback/types.js +1 -0
- package/dist/components/ui/modal/feedback/ui/ModalFeedback.svelte +135 -0
- package/dist/components/ui/modal/feedback/ui/ModalFeedback.svelte.d.ts +4 -0
- package/dist/components/ui/modal/form/index.d.ts +3 -0
- package/dist/components/ui/modal/form/index.js +2 -0
- package/dist/components/ui/modal/form/types.d.ts +38 -0
- package/dist/components/ui/modal/form/types.js +1 -0
- package/dist/components/ui/modal/form/ui/ModalForm.svelte +67 -0
- package/dist/components/ui/modal/form/ui/ModalForm.svelte.d.ts +4 -0
- package/dist/components/ui/modal/grid/index.d.ts +5 -0
- package/dist/components/ui/modal/grid/index.js +4 -0
- package/dist/components/ui/modal/grid/types.d.ts +51 -0
- package/dist/components/ui/modal/grid/types.js +1 -0
- package/dist/components/ui/modal/grid/ui/01/ModalGridSelection01.svelte +83 -0
- package/dist/components/ui/modal/grid/ui/01/ModalGridSelection01.svelte.d.ts +4 -0
- package/dist/components/ui/modal/grid/ui/02/ModalGridSelection02.svelte +146 -0
- package/dist/components/ui/modal/grid/ui/02/ModalGridSelection02.svelte.d.ts +4 -0
- package/dist/components/ui/modal/grid/ui/ModalGridSelection.svelte +60 -0
- package/dist/components/ui/modal/grid/ui/ModalGridSelection.svelte.d.ts +4 -0
- package/dist/components/ui/modal/map/index.d.ts +3 -0
- package/dist/components/ui/modal/map/index.js +2 -0
- package/dist/components/ui/modal/map/types.d.ts +48 -0
- package/dist/components/ui/modal/map/types.js +1 -0
- package/dist/components/ui/modal/map/ui/ModalMap.svelte +187 -0
- package/dist/components/ui/modal/map/ui/ModalMap.svelte.d.ts +4 -0
- package/dist/components/ui/modal/notification/index.d.ts +3 -0
- package/dist/components/ui/modal/notification/index.js +2 -0
- package/dist/components/ui/modal/notification/types.d.ts +26 -0
- package/dist/components/ui/modal/notification/types.js +1 -0
- package/dist/components/ui/modal/notification/ui/ModalNotification.svelte +65 -0
- package/dist/components/ui/modal/notification/ui/ModalNotification.svelte.d.ts +4 -0
- package/dist/components/ui/modal/share/index.d.ts +3 -0
- package/dist/components/ui/modal/share/index.js +2 -0
- package/dist/components/ui/modal/share/types.d.ts +47 -0
- package/dist/components/ui/modal/share/types.js +1 -0
- package/dist/components/ui/modal/share/ui/ModalShareSelection.svelte +156 -0
- package/dist/components/ui/modal/share/ui/ModalShareSelection.svelte.d.ts +4 -0
- package/dist/components/ui/modal/upload/index.d.ts +3 -0
- package/dist/components/ui/modal/upload/index.js +2 -0
- package/dist/components/ui/modal/upload/types.d.ts +79 -0
- package/dist/components/ui/modal/upload/types.js +1 -0
- package/dist/components/ui/modal/upload/ui/ModalUpload.svelte +268 -0
- package/dist/components/ui/modal/upload/ui/ModalUpload.svelte.d.ts +4 -0
- package/dist/components/ui/section/Section01.svelte +90 -0
- package/dist/components/ui/section/Section01.svelte.d.ts +4 -0
- package/dist/components/ui/section/Section02.svelte +68 -0
- package/dist/components/ui/section/Section02.svelte.d.ts +4 -0
- package/dist/components/ui/section/Section03.svelte +52 -0
- package/dist/components/ui/section/Section03.svelte.d.ts +4 -0
- package/dist/components/ui/section/index.d.ts +4 -0
- package/dist/components/ui/section/index.js +3 -0
- package/dist/components/ui/section/types.d.ts +46 -0
- package/dist/components/ui/section/types.js +1 -0
- package/dist/docs/DocsSidebar.svelte +58 -1
- package/dist/docs/components.d.ts +1 -1
- package/dist/docs/components.js +968 -0
- package/dist/globals.css +360 -0
- package/dist/index.d.ts +185 -0
- package/dist/index.js +185 -0
- package/dist/types/index.d.ts +53 -0
- package/package.json +1 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from "../../../../../../utils";
|
|
3
|
+
import { HugeiconsIcon } from "@hugeicons/svelte";
|
|
4
|
+
import { CheckmarkCircle02Icon } from "@hugeicons/core-free-icons";
|
|
5
|
+
import ModalCore from "../../../core/ui/ModalCore.svelte";
|
|
6
|
+
import type {
|
|
7
|
+
ModalGridSelectionProps,
|
|
8
|
+
ModelGridCard,
|
|
9
|
+
ModelGridCategory,
|
|
10
|
+
} from "../../types";
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
title,
|
|
14
|
+
subtitle,
|
|
15
|
+
categories = [],
|
|
16
|
+
selectedCategory = $bindable(null),
|
|
17
|
+
cards = [],
|
|
18
|
+
selectedCard = $bindable(null),
|
|
19
|
+
selectedCards = $bindable([]),
|
|
20
|
+
multiple = false,
|
|
21
|
+
totalSteps = 1,
|
|
22
|
+
currentStep = 1,
|
|
23
|
+
isOpen = $bindable(false),
|
|
24
|
+
onSelect,
|
|
25
|
+
onSelectCategory,
|
|
26
|
+
onBack,
|
|
27
|
+
onContinue,
|
|
28
|
+
class: className,
|
|
29
|
+
}: ModalGridSelectionProps = $props();
|
|
30
|
+
|
|
31
|
+
function handleSelectCard(card: ModelGridCard) {
|
|
32
|
+
if (multiple) {
|
|
33
|
+
const exists = selectedCards.some(
|
|
34
|
+
(c: ModelGridCard) => c.title === card.title,
|
|
35
|
+
);
|
|
36
|
+
if (exists) {
|
|
37
|
+
selectedCards = selectedCards.filter(
|
|
38
|
+
(c: ModelGridCard) => c.title !== card.title,
|
|
39
|
+
);
|
|
40
|
+
} else {
|
|
41
|
+
selectedCards = [...selectedCards, card];
|
|
42
|
+
}
|
|
43
|
+
onSelect?.(card);
|
|
44
|
+
} else {
|
|
45
|
+
selectedCard = card;
|
|
46
|
+
onSelect?.(card);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function handleSelectCategory(category: ModelGridCategory) {
|
|
51
|
+
selectedCategory = category;
|
|
52
|
+
onSelectCategory?.(category);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isSelectedCard(card: ModelGridCard): boolean {
|
|
56
|
+
if (multiple) {
|
|
57
|
+
return selectedCards.some((c: ModelGridCard) => c.title === card.title);
|
|
58
|
+
}
|
|
59
|
+
return selectedCard?.title === card.title;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function isSelectedCategory(category: ModelGridCategory): boolean {
|
|
63
|
+
return selectedCategory?.value === category.value;
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<ModalCore
|
|
68
|
+
bind:isOpen
|
|
69
|
+
{title}
|
|
70
|
+
{subtitle}
|
|
71
|
+
{totalSteps}
|
|
72
|
+
{currentStep}
|
|
73
|
+
showProgress={false}
|
|
74
|
+
showBack={currentStep > 1}
|
|
75
|
+
{onBack}
|
|
76
|
+
{onContinue}
|
|
77
|
+
class={cn(className)}
|
|
78
|
+
>
|
|
79
|
+
{#snippet content()}
|
|
80
|
+
<!-- Categories -->
|
|
81
|
+
{#if categories.length > 0}
|
|
82
|
+
<div class="mb-6 flex flex-wrap gap-2">
|
|
83
|
+
{#each categories as cat (cat.value)}
|
|
84
|
+
{@const active = isSelectedCategory(cat)}
|
|
85
|
+
<button
|
|
86
|
+
type="button"
|
|
87
|
+
class={cn(
|
|
88
|
+
"rounded-full border px-4 py-1.5 text-sm font-medium transition-all duration-200",
|
|
89
|
+
active ? "" : "",
|
|
90
|
+
)}
|
|
91
|
+
onclick={() => handleSelectCategory(cat)}
|
|
92
|
+
>
|
|
93
|
+
{cat.label}
|
|
94
|
+
</button>
|
|
95
|
+
{/each}
|
|
96
|
+
</div>
|
|
97
|
+
{/if}
|
|
98
|
+
|
|
99
|
+
<!-- Cards Grid -->
|
|
100
|
+
<div class="grid grid-cols-1 gap-3 md:grid-cols-2">
|
|
101
|
+
{#each cards as card, i (i)}
|
|
102
|
+
{@const selected = isSelectedCard(card)}
|
|
103
|
+
<button
|
|
104
|
+
type="button"
|
|
105
|
+
class={cn(
|
|
106
|
+
"relative flex items-center gap-4 rounded-xl border p-4 text-left transition-all duration-200",
|
|
107
|
+
selected ? "" : "",
|
|
108
|
+
)}
|
|
109
|
+
onclick={() => handleSelectCard(card)}
|
|
110
|
+
>
|
|
111
|
+
<!-- Icon -->
|
|
112
|
+
<div
|
|
113
|
+
class={cn(
|
|
114
|
+
"flex size-10 shrink-0 items-center justify-center rounded-lg",
|
|
115
|
+
selected ? "bg-primary/20" : "bg-primary/40",
|
|
116
|
+
)}
|
|
117
|
+
>
|
|
118
|
+
{#if typeof card.icon === "string"}
|
|
119
|
+
<i class="{card.icon} text-lg"></i>
|
|
120
|
+
{:else}
|
|
121
|
+
<HugeiconsIcon icon={card.icon} class="size-5" />
|
|
122
|
+
{/if}
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<!-- Text -->
|
|
126
|
+
<div class="min-w-0 flex-1">
|
|
127
|
+
<p class="text-sm font-bold">{card.title}</p>
|
|
128
|
+
{#if card.description}
|
|
129
|
+
<p class="mt-0.5 line-clamp-1 text-xs">
|
|
130
|
+
{card.description}
|
|
131
|
+
</p>
|
|
132
|
+
{/if}
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<!-- Checkmark -->
|
|
136
|
+
{#if selected}
|
|
137
|
+
<HugeiconsIcon
|
|
138
|
+
icon={CheckmarkCircle02Icon}
|
|
139
|
+
class="size-5 shrink-0 text-primary"
|
|
140
|
+
/>
|
|
141
|
+
{/if}
|
|
142
|
+
</button>
|
|
143
|
+
{/each}
|
|
144
|
+
</div>
|
|
145
|
+
{/snippet}
|
|
146
|
+
</ModalCore>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ModalGridSelectionProps } from "../../types";
|
|
2
|
+
declare const ModalGridSelection02: import("svelte").Component<ModalGridSelectionProps, {}, "isOpen" | "selectedCard" | "selectedCategory" | "selectedCards">;
|
|
3
|
+
type ModalGridSelection02 = ReturnType<typeof ModalGridSelection02>;
|
|
4
|
+
export default ModalGridSelection02;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ModalGridSelectionProps } from "../types";
|
|
3
|
+
import ModalGridSelection01 from "./01/ModalGridSelection01.svelte";
|
|
4
|
+
import ModalGridSelection02 from "./02/ModalGridSelection02.svelte";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
variant = 1,
|
|
8
|
+
title,
|
|
9
|
+
subtitle,
|
|
10
|
+
categories = [],
|
|
11
|
+
selectedCategory = $bindable(null),
|
|
12
|
+
cards = [],
|
|
13
|
+
selectedCard = $bindable(null),
|
|
14
|
+
selectedCards = $bindable([]),
|
|
15
|
+
multiple = false,
|
|
16
|
+
totalSteps = 1,
|
|
17
|
+
currentStep = 1,
|
|
18
|
+
isOpen = $bindable(false),
|
|
19
|
+
onSelect,
|
|
20
|
+
onSelectCategory,
|
|
21
|
+
onBack,
|
|
22
|
+
onContinue,
|
|
23
|
+
class: className,
|
|
24
|
+
}: ModalGridSelectionProps = $props();
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
{#if variant === 2}
|
|
28
|
+
<ModalGridSelection02
|
|
29
|
+
bind:isOpen
|
|
30
|
+
bind:selectedCard
|
|
31
|
+
bind:selectedCards
|
|
32
|
+
bind:selectedCategory
|
|
33
|
+
{title}
|
|
34
|
+
{subtitle}
|
|
35
|
+
{categories}
|
|
36
|
+
{cards}
|
|
37
|
+
{multiple}
|
|
38
|
+
{totalSteps}
|
|
39
|
+
{currentStep}
|
|
40
|
+
{onSelect}
|
|
41
|
+
{onSelectCategory}
|
|
42
|
+
{onBack}
|
|
43
|
+
{onContinue}
|
|
44
|
+
class={className}
|
|
45
|
+
/>
|
|
46
|
+
{:else}
|
|
47
|
+
<ModalGridSelection01
|
|
48
|
+
bind:isOpen
|
|
49
|
+
bind:selectedCard
|
|
50
|
+
{title}
|
|
51
|
+
{subtitle}
|
|
52
|
+
{cards}
|
|
53
|
+
{totalSteps}
|
|
54
|
+
{currentStep}
|
|
55
|
+
{onSelect}
|
|
56
|
+
{onBack}
|
|
57
|
+
{onContinue}
|
|
58
|
+
class={className}
|
|
59
|
+
/>
|
|
60
|
+
{/if}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ModalGridSelectionProps } from "../types";
|
|
2
|
+
declare const ModalGridSelection: import("svelte").Component<ModalGridSelectionProps, {}, "isOpen" | "selectedCard" | "selectedCategory" | "selectedCards">;
|
|
3
|
+
type ModalGridSelection = ReturnType<typeof ModalGridSelection>;
|
|
4
|
+
export default ModalGridSelection;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props do componente ModalMap — modal de seleção de localização com mapa.
|
|
3
|
+
* Sexta variação do sistema de modais do NegoDesign.
|
|
4
|
+
* @property title - Título do popup de localização (ex: "Location").
|
|
5
|
+
* @property searchPlaceholder - Texto placeholder da barra de pesquisa.
|
|
6
|
+
* @property address - Endereço actual.
|
|
7
|
+
* @property addressLabel - Label do campo de endereço (ex: "Address").
|
|
8
|
+
* @property description - Descrição/notas da localização.
|
|
9
|
+
* @property descriptionLabel - Label do campo de descrição (ex: "Description").
|
|
10
|
+
* @property editButtonText - Texto do botão "Edit" do endereço.
|
|
11
|
+
* @property useLocationText - Texto da checkbox de usar localização actual.
|
|
12
|
+
* @property useLocationChecked - Estado da checkbox.
|
|
13
|
+
* @property cancelText - Texto do botão cancelar.
|
|
14
|
+
* @property applyText - Texto do botão aplicar.
|
|
15
|
+
* @property isLoading - Estado de carregamento.
|
|
16
|
+
* @property isOpen - Controla a visibilidade do modal.
|
|
17
|
+
* @property onSearch - Chamado ao pesquisar um endereço.
|
|
18
|
+
* @property onEdit - Chamado ao clicar no botão Edit.
|
|
19
|
+
* @property onApply - Chamado ao clicar no botão Apply.
|
|
20
|
+
* @property onCancel - Chamado ao clicar no botão Cancel.
|
|
21
|
+
* @property onToggleLocation - Chamado ao alterar a checkbox.
|
|
22
|
+
* @property onClose - Chamado ao fechar o modal.
|
|
23
|
+
* @property mapSlot - Snippet personalizado para o conteúdo do mapa.
|
|
24
|
+
* @property class - Classe CSS extra no container do modal.
|
|
25
|
+
*/
|
|
26
|
+
export type ModalMapProps = {
|
|
27
|
+
title?: string;
|
|
28
|
+
searchPlaceholder?: string;
|
|
29
|
+
address?: string;
|
|
30
|
+
addressLabel?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
descriptionLabel?: string;
|
|
33
|
+
editButtonText?: string;
|
|
34
|
+
useLocationText?: string;
|
|
35
|
+
useLocationChecked?: boolean;
|
|
36
|
+
cancelText?: string;
|
|
37
|
+
applyText?: string;
|
|
38
|
+
isLoading?: boolean;
|
|
39
|
+
isOpen?: boolean;
|
|
40
|
+
onSearch?: (query: string) => void;
|
|
41
|
+
onEdit?: () => void;
|
|
42
|
+
onApply?: (address: string, description: string) => void;
|
|
43
|
+
onCancel?: () => void;
|
|
44
|
+
onToggleLocation?: (checked: boolean) => void;
|
|
45
|
+
onClose?: () => void;
|
|
46
|
+
mapSlot?: import("svelte").Snippet;
|
|
47
|
+
class?: string;
|
|
48
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from "../../../../../utils";
|
|
3
|
+
import { Search01Icon, Cancel01Icon } from "@hugeicons/core-free-icons";
|
|
4
|
+
import { HugeiconsIcon } from "@hugeicons/svelte";
|
|
5
|
+
import ModalCore from "../../core/ui/ModalCore.svelte";
|
|
6
|
+
import type { ModalMapProps } from "../types";
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
title = "Location",
|
|
10
|
+
searchPlaceholder = "Search address...",
|
|
11
|
+
address = "",
|
|
12
|
+
addressLabel = "Address",
|
|
13
|
+
description = "",
|
|
14
|
+
descriptionLabel = "Description",
|
|
15
|
+
editButtonText = "Edit",
|
|
16
|
+
useLocationText = "Use your business location",
|
|
17
|
+
useLocationChecked = $bindable(false),
|
|
18
|
+
cancelText = "Cancel",
|
|
19
|
+
applyText = "Apply",
|
|
20
|
+
isLoading = false,
|
|
21
|
+
isOpen = $bindable(false),
|
|
22
|
+
onSearch,
|
|
23
|
+
onEdit,
|
|
24
|
+
onApply,
|
|
25
|
+
onCancel,
|
|
26
|
+
onToggleLocation,
|
|
27
|
+
onClose,
|
|
28
|
+
mapSlot,
|
|
29
|
+
class: className,
|
|
30
|
+
}: ModalMapProps = $props();
|
|
31
|
+
|
|
32
|
+
let searchQuery = $state("");
|
|
33
|
+
let localDescription = $state("");
|
|
34
|
+
|
|
35
|
+
$effect(() => {
|
|
36
|
+
searchQuery = address;
|
|
37
|
+
localDescription = description;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
function handleSearch() {
|
|
41
|
+
onSearch?.(searchQuery);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function handleKeydown(e: KeyboardEvent) {
|
|
45
|
+
if (e.key === "Enter") handleSearch();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function handleApply() {
|
|
49
|
+
onApply?.(searchQuery, localDescription);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function handleCancel() {
|
|
53
|
+
isOpen = false;
|
|
54
|
+
onCancel?.();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function handleToggle(e: Event) {
|
|
58
|
+
const checked = (e.target as HTMLInputElement).checked;
|
|
59
|
+
useLocationChecked = checked;
|
|
60
|
+
onToggleLocation?.(checked);
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<ModalCore
|
|
65
|
+
bind:isOpen
|
|
66
|
+
title=""
|
|
67
|
+
showProgress={false}
|
|
68
|
+
showBack={false}
|
|
69
|
+
{onClose}
|
|
70
|
+
class={cn("max-w-2xl overflow-hidden p-0!", className)}
|
|
71
|
+
>
|
|
72
|
+
{#snippet content()}
|
|
73
|
+
<div class="-mx-8 -mt-6 mb-0 flex flex-col">
|
|
74
|
+
<!-- Map Area -->
|
|
75
|
+
<div class="relative h-72 w-full bg-muted md:h-96">
|
|
76
|
+
{#if mapSlot}
|
|
77
|
+
{@render mapSlot()}
|
|
78
|
+
{:else}
|
|
79
|
+
<!-- Placeholder map with grid pattern -->
|
|
80
|
+
<div class="absolute inset-0 bg-[linear-gradient(to_right,#e5e7eb_1px,transparent_1px),linear-gradient(to_bottom,#e5e7eb_1px,transparent_1px)] bg-size-[20px_20px] opacity-50"></div>
|
|
81
|
+
<div class="absolute inset-0 flex items-center justify-center">
|
|
82
|
+
<div class="flex size-10 items-center justify-center rounded-full bg-primary shadow-lg">
|
|
83
|
+
<div class="size-3 rounded-full bg-white"></div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
{/if}
|
|
87
|
+
|
|
88
|
+
<!-- Search Bar -->
|
|
89
|
+
<div class="absolute left-4 right-4 top-4">
|
|
90
|
+
<div class="flex items-center gap-2 rounded-xl border border-border bg-card shadow-lg">
|
|
91
|
+
<HugeiconsIcon icon={Search01Icon} class="ml-3 size-4 text-muted-foreground" />
|
|
92
|
+
<input
|
|
93
|
+
type="text"
|
|
94
|
+
bind:value={searchQuery}
|
|
95
|
+
placeholder={searchPlaceholder}
|
|
96
|
+
class="flex-1 bg-transparent py-3 pr-4 text-sm text-foreground outline-none placeholder:text-muted-foreground"
|
|
97
|
+
onkeydown={handleKeydown}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<!-- Location Popup Card -->
|
|
103
|
+
<div class="absolute bottom-4 left-4 right-4 rounded-xl border border-border bg-card p-5 shadow-lg md:left-auto md:right-4 md:w-80">
|
|
104
|
+
<div class="mb-4 flex items-center justify-between">
|
|
105
|
+
<h3 class="text-lg font-bold">{title}</h3>
|
|
106
|
+
<button
|
|
107
|
+
type="button"
|
|
108
|
+
class="text-muted-foreground transition hover:text-foreground"
|
|
109
|
+
onclick={() => (isOpen = false)}
|
|
110
|
+
>
|
|
111
|
+
<HugeiconsIcon icon={Cancel01Icon} class="size-4" />
|
|
112
|
+
</button>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<!-- Address -->
|
|
116
|
+
<div class="mb-4">
|
|
117
|
+
<!-- svelte-ignore a11y_label_has_associated_control -->
|
|
118
|
+
<label class="mb-1.5 block text-sm font-medium text-muted-foreground">
|
|
119
|
+
{addressLabel}
|
|
120
|
+
</label>
|
|
121
|
+
<div class="flex items-center gap-2">
|
|
122
|
+
<input
|
|
123
|
+
type="text"
|
|
124
|
+
bind:value={searchQuery}
|
|
125
|
+
class="flex-1 rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground outline-none focus:border-primary focus:ring-1 focus:ring-primary/20"
|
|
126
|
+
/>
|
|
127
|
+
<button
|
|
128
|
+
type="button"
|
|
129
|
+
class="shrink-0 rounded-lg border border-border px-3 py-2 text-sm font-medium text-muted-foreground transition hover:bg-muted"
|
|
130
|
+
onclick={onEdit}
|
|
131
|
+
>
|
|
132
|
+
{editButtonText}
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<!-- Description -->
|
|
138
|
+
<div>
|
|
139
|
+
<!-- svelte-ignore a11y_label_has_associated_control -->
|
|
140
|
+
<label class="mb-1.5 block text-sm font-medium text-muted-foreground">
|
|
141
|
+
{descriptionLabel}
|
|
142
|
+
</label>
|
|
143
|
+
<textarea
|
|
144
|
+
bind:value={localDescription}
|
|
145
|
+
rows={3}
|
|
146
|
+
class="w-full resize-none rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground outline-none focus:border-primary focus:ring-1 focus:ring-primary/20"
|
|
147
|
+
></textarea>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
{/snippet}
|
|
153
|
+
|
|
154
|
+
{#snippet footer()}
|
|
155
|
+
<div class="flex items-center justify-between">
|
|
156
|
+
<!-- Use Location Checkbox -->
|
|
157
|
+
<label class="flex cursor-pointer items-center gap-2.5">
|
|
158
|
+
<input
|
|
159
|
+
type="checkbox"
|
|
160
|
+
checked={useLocationChecked}
|
|
161
|
+
onchange={handleToggle}
|
|
162
|
+
class="size-4 rounded border-border text-primary accent-primary"
|
|
163
|
+
/>
|
|
164
|
+
<span class="text-sm font-medium text-muted-foreground">{useLocationText}</span>
|
|
165
|
+
</label>
|
|
166
|
+
|
|
167
|
+
<!-- Actions -->
|
|
168
|
+
<div class="flex items-center gap-3">
|
|
169
|
+
<button
|
|
170
|
+
type="button"
|
|
171
|
+
class="rounded-lg border border-border px-5 py-2.5 text-sm font-semibold transition hover:bg-muted"
|
|
172
|
+
onclick={handleCancel}
|
|
173
|
+
>
|
|
174
|
+
{cancelText}
|
|
175
|
+
</button>
|
|
176
|
+
<button
|
|
177
|
+
type="button"
|
|
178
|
+
disabled={isLoading}
|
|
179
|
+
class="rounded-lg bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50"
|
|
180
|
+
onclick={handleApply}
|
|
181
|
+
>
|
|
182
|
+
{applyText}
|
|
183
|
+
</button>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
{/snippet}
|
|
187
|
+
</ModalCore>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props do componente ModalNotification — modal de subscrição/notificação por email.
|
|
3
|
+
* Quarta variação do sistema de modais do NegoDesign.
|
|
4
|
+
* @property title - Título principal do modal (ex: "Be the first to know").
|
|
5
|
+
* @property description - Texto descritivo abaixo do título.
|
|
6
|
+
* @property placeholder - Texto placeholder do input de email.
|
|
7
|
+
* @property buttonText - Texto do botão de submissão.
|
|
8
|
+
* @property buttonLoadingText - Texto exibido durante o carregamento.
|
|
9
|
+
* @property isLoading - Estado de carregamento do botão.
|
|
10
|
+
* @property isOpen - Controla a visibilidade do modal.
|
|
11
|
+
* @property onSubmit - Chamado ao submeter o email.
|
|
12
|
+
* @property onClose - Chamado ao fechar o modal.
|
|
13
|
+
* @property class - Classe CSS extra no container do modal.
|
|
14
|
+
*/
|
|
15
|
+
export type ModalNotificationProps = {
|
|
16
|
+
title: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
placeholder?: string;
|
|
19
|
+
buttonText?: string;
|
|
20
|
+
buttonLoadingText?: string;
|
|
21
|
+
isLoading?: boolean;
|
|
22
|
+
isOpen?: boolean;
|
|
23
|
+
onSubmit?: (email: string) => void;
|
|
24
|
+
onClose?: () => void;
|
|
25
|
+
class?: string;
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from "../../../../../utils";
|
|
3
|
+
import ModalCore from "../../core/ui/ModalCore.svelte";
|
|
4
|
+
import type { ModalNotificationProps } from "../types";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
title,
|
|
8
|
+
description,
|
|
9
|
+
placeholder = "Your email address",
|
|
10
|
+
buttonText = "Sign me up",
|
|
11
|
+
buttonLoadingText = "Signing up...",
|
|
12
|
+
isLoading = false,
|
|
13
|
+
isOpen = $bindable(false),
|
|
14
|
+
onSubmit,
|
|
15
|
+
onClose,
|
|
16
|
+
class: className,
|
|
17
|
+
}: ModalNotificationProps = $props();
|
|
18
|
+
|
|
19
|
+
let email = $state("");
|
|
20
|
+
|
|
21
|
+
function handleSubmit() {
|
|
22
|
+
if (!email.trim() || isLoading) return;
|
|
23
|
+
onSubmit?.(email);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function handleKeydown(e: KeyboardEvent) {
|
|
27
|
+
if (e.key === "Enter") handleSubmit();
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<ModalCore
|
|
32
|
+
bind:isOpen
|
|
33
|
+
{title}
|
|
34
|
+
showProgress={false}
|
|
35
|
+
showBack={false}
|
|
36
|
+
{onClose}
|
|
37
|
+
class={cn("max-w-lg", className)}
|
|
38
|
+
>
|
|
39
|
+
{#snippet content()}
|
|
40
|
+
{#if description}
|
|
41
|
+
<p class="text-sm text-muted-foreground">{description}</p>
|
|
42
|
+
{/if}
|
|
43
|
+
|
|
44
|
+
<div class="mt-6 flex items-center gap-3">
|
|
45
|
+
<input
|
|
46
|
+
type="email"
|
|
47
|
+
{placeholder}
|
|
48
|
+
bind:value={email}
|
|
49
|
+
onkeydown={handleKeydown}
|
|
50
|
+
class="flex-1 rounded-lg border border-border bg-card px-4 py-3 text-sm text-foreground placeholder:text-muted-foreground outline-none transition focus:border-primary focus:ring-2 focus:ring-primary/20"
|
|
51
|
+
/>
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
disabled={isLoading || !email.trim()}
|
|
55
|
+
class={cn(
|
|
56
|
+
"shrink-0 rounded-lg bg-primary px-6 py-3 text-sm font-semibold text-primary-foreground transition-all",
|
|
57
|
+
"hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50"
|
|
58
|
+
)}
|
|
59
|
+
onclick={handleSubmit}
|
|
60
|
+
>
|
|
61
|
+
{isLoading ? buttonLoadingText : buttonText}
|
|
62
|
+
</button>
|
|
63
|
+
</div>
|
|
64
|
+
{/snippet}
|
|
65
|
+
</ModalCore>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ModelSocialShare } from "../core/types";
|
|
2
|
+
export type { ModelSocialShare } from "../core/types";
|
|
3
|
+
/**
|
|
4
|
+
* Props do componente ModalShareSelection — modal de partilha em redes sociais.
|
|
5
|
+
* Terceira variação do sistema de modais do NegoDesign.
|
|
6
|
+
* Cada rede social pode ser activada/inactivada com as propriedades isX.
|
|
7
|
+
* @property title - Título principal do modal (ex: "Share this design").
|
|
8
|
+
* @property subtitle - Subtítulo/descrição abaixo do título.
|
|
9
|
+
* @property networks - Lista de redes sociais para partilhar.
|
|
10
|
+
* @property isWhatsapp - Mostra a rede social WhatsApp.
|
|
11
|
+
* @property isInstagram - Mostra a rede social Instagram.
|
|
12
|
+
* @property isFacebook - Mostra a rede social Facebook.
|
|
13
|
+
* @property isTwitter - Mostra a rede social Twitter/X.
|
|
14
|
+
* @property isLinkedin - Mostra a rede social LinkedIn.
|
|
15
|
+
* @property isPinterest - Mostra a rede social Pinterest.
|
|
16
|
+
* @property isTumblr - Mostra a rede social Tumblr.
|
|
17
|
+
* @property linkLabel - Texto acima do input de link (ex: "Or copy link").
|
|
18
|
+
* @property linkValue - URL a ser partilhada/copiada.
|
|
19
|
+
* @property copyText - Texto do botão de copiar.
|
|
20
|
+
* @property copiedText - Texto exibido após copiar com sucesso.
|
|
21
|
+
* @property isOpen - Controla a visibilidade do modal.
|
|
22
|
+
* @property onShare - Chamado ao clicar numa rede social.
|
|
23
|
+
* @property onCopy - Chamado ao clicar no botão copiar.
|
|
24
|
+
* @property onClose - Chamado ao fechar o modal.
|
|
25
|
+
* @property class - Classe CSS extra no container do modal.
|
|
26
|
+
*/
|
|
27
|
+
export type ModalShareSelectionProps = {
|
|
28
|
+
title: string;
|
|
29
|
+
subtitle?: string;
|
|
30
|
+
networks?: ModelSocialShare[];
|
|
31
|
+
isWhatsapp?: boolean;
|
|
32
|
+
isInstagram?: boolean;
|
|
33
|
+
isFacebook?: boolean;
|
|
34
|
+
isTwitter?: boolean;
|
|
35
|
+
isLinkedin?: boolean;
|
|
36
|
+
isPinterest?: boolean;
|
|
37
|
+
isTumblr?: boolean;
|
|
38
|
+
linkLabel?: string;
|
|
39
|
+
linkValue?: string;
|
|
40
|
+
copyText?: string;
|
|
41
|
+
copiedText?: string;
|
|
42
|
+
isOpen?: boolean;
|
|
43
|
+
onShare?: (network: ModelSocialShare) => void;
|
|
44
|
+
onCopy?: (link: string) => void;
|
|
45
|
+
onClose?: () => void;
|
|
46
|
+
class?: string;
|
|
47
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|