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.
Files changed (121) hide show
  1. package/dist/components/pages/security/auth/PageAuth01.svelte +65 -0
  2. package/dist/components/pages/security/auth/PageAuth01.svelte.d.ts +17 -0
  3. package/dist/components/pages/security/auth/PageAuth02.svelte +45 -0
  4. package/dist/components/pages/security/auth/PageAuth02.svelte.d.ts +17 -0
  5. package/dist/components/pages/security/auth/PageAuth03.svelte +45 -0
  6. package/dist/components/pages/security/auth/PageAuth03.svelte.d.ts +17 -0
  7. package/dist/components/pages/security/login/01/ui/PageLogin01.svelte +15 -40
  8. package/dist/components/pages/security/login/02/ui/LoginCard02.svelte +15 -4
  9. package/dist/components/pages/security/login/02/ui/PageLogin02.svelte +15 -20
  10. package/dist/components/pages/security/login/03/ui/LoginCard03.svelte +34 -16
  11. package/dist/components/pages/security/login/03/ui/PageLogin03.svelte +15 -20
  12. package/dist/components/pages/security/register/01/ui/PageRegister01.svelte +64 -0
  13. package/dist/components/pages/security/register/01/ui/PageRegister01.svelte.d.ts +3 -0
  14. package/dist/components/pages/security/register/01/ui/RegisterCard.svelte +100 -0
  15. package/dist/components/pages/security/register/01/ui/RegisterCard.svelte.d.ts +12 -0
  16. package/dist/components/pages/security/register/02/ui/PageRegister02.svelte +76 -0
  17. package/dist/components/pages/security/register/02/ui/PageRegister02.svelte.d.ts +4 -0
  18. package/dist/components/pages/security/register/02/ui/RegisterCard02.svelte +98 -0
  19. package/dist/components/pages/security/register/02/ui/RegisterCard02.svelte.d.ts +12 -0
  20. package/dist/components/pages/security/register/03/ui/PageRegister03.svelte +76 -0
  21. package/dist/components/pages/security/register/03/ui/PageRegister03.svelte.d.ts +4 -0
  22. package/dist/components/pages/security/register/03/ui/RegisterCard03.svelte +103 -0
  23. package/dist/components/pages/security/register/03/ui/RegisterCard03.svelte.d.ts +12 -0
  24. package/dist/components/pages/security/register/FormRegister.svelte +120 -0
  25. package/dist/components/pages/security/register/FormRegister.svelte.d.ts +8 -0
  26. package/dist/components/pages/security/register/PageRegister.svelte +30 -0
  27. package/dist/components/pages/security/register/PageRegister.svelte.d.ts +8 -0
  28. package/dist/components/pages/security/register/types.d.ts +51 -0
  29. package/dist/components/pages/security/register/types.js +1 -0
  30. package/dist/components/ui/form/Form.svelte +171 -0
  31. package/dist/components/ui/form/Form.svelte.d.ts +4 -0
  32. package/dist/components/ui/form/types.d.ts +78 -0
  33. package/dist/components/ui/form/types.js +1 -0
  34. package/dist/components/ui/form/ui/input-badges.svelte +214 -0
  35. package/dist/components/ui/form/ui/input-badges.svelte.d.ts +14 -0
  36. package/dist/components/ui/form/ui/input-checkbox.svelte +86 -0
  37. package/dist/components/ui/form/ui/input-checkbox.svelte.d.ts +17 -0
  38. package/dist/components/ui/form/ui/input-radio.svelte +82 -0
  39. package/dist/components/ui/form/ui/input-radio.svelte.d.ts +17 -0
  40. package/dist/components/ui/form/ui/input-select.svelte +195 -0
  41. package/dist/components/ui/form/ui/input-select.svelte.d.ts +17 -0
  42. package/dist/components/ui/form/ui/input-textarea.svelte +61 -0
  43. package/dist/components/ui/form/ui/input-textarea.svelte.d.ts +13 -0
  44. package/dist/components/ui/form/ui/input-toggle.svelte +89 -0
  45. package/dist/components/ui/form/ui/input-toggle.svelte.d.ts +11 -0
  46. package/dist/components/ui/modal/badge/index.d.ts +3 -0
  47. package/dist/components/ui/modal/badge/index.js +2 -0
  48. package/dist/components/ui/modal/badge/types.d.ts +35 -0
  49. package/dist/components/ui/modal/badge/types.js +1 -0
  50. package/dist/components/ui/modal/badge/ui/ModalBadgeSelection.svelte +87 -0
  51. package/dist/components/ui/modal/badge/ui/ModalBadgeSelection.svelte.d.ts +4 -0
  52. package/dist/components/ui/modal/core/index.d.ts +3 -0
  53. package/dist/components/ui/modal/core/index.js +2 -0
  54. package/dist/components/ui/modal/core/types.d.ts +84 -0
  55. package/dist/components/ui/modal/core/types.js +1 -0
  56. package/dist/components/ui/modal/core/ui/ModalCore.svelte +132 -0
  57. package/dist/components/ui/modal/core/ui/ModalCore.svelte.d.ts +4 -0
  58. package/dist/components/ui/modal/feedback/index.d.ts +3 -0
  59. package/dist/components/ui/modal/feedback/index.js +2 -0
  60. package/dist/components/ui/modal/feedback/types.d.ts +32 -0
  61. package/dist/components/ui/modal/feedback/types.js +1 -0
  62. package/dist/components/ui/modal/feedback/ui/ModalFeedback.svelte +135 -0
  63. package/dist/components/ui/modal/feedback/ui/ModalFeedback.svelte.d.ts +4 -0
  64. package/dist/components/ui/modal/form/index.d.ts +3 -0
  65. package/dist/components/ui/modal/form/index.js +2 -0
  66. package/dist/components/ui/modal/form/types.d.ts +38 -0
  67. package/dist/components/ui/modal/form/types.js +1 -0
  68. package/dist/components/ui/modal/form/ui/ModalForm.svelte +67 -0
  69. package/dist/components/ui/modal/form/ui/ModalForm.svelte.d.ts +4 -0
  70. package/dist/components/ui/modal/grid/index.d.ts +5 -0
  71. package/dist/components/ui/modal/grid/index.js +4 -0
  72. package/dist/components/ui/modal/grid/types.d.ts +51 -0
  73. package/dist/components/ui/modal/grid/types.js +1 -0
  74. package/dist/components/ui/modal/grid/ui/01/ModalGridSelection01.svelte +83 -0
  75. package/dist/components/ui/modal/grid/ui/01/ModalGridSelection01.svelte.d.ts +4 -0
  76. package/dist/components/ui/modal/grid/ui/02/ModalGridSelection02.svelte +146 -0
  77. package/dist/components/ui/modal/grid/ui/02/ModalGridSelection02.svelte.d.ts +4 -0
  78. package/dist/components/ui/modal/grid/ui/ModalGridSelection.svelte +60 -0
  79. package/dist/components/ui/modal/grid/ui/ModalGridSelection.svelte.d.ts +4 -0
  80. package/dist/components/ui/modal/map/index.d.ts +3 -0
  81. package/dist/components/ui/modal/map/index.js +2 -0
  82. package/dist/components/ui/modal/map/types.d.ts +48 -0
  83. package/dist/components/ui/modal/map/types.js +1 -0
  84. package/dist/components/ui/modal/map/ui/ModalMap.svelte +187 -0
  85. package/dist/components/ui/modal/map/ui/ModalMap.svelte.d.ts +4 -0
  86. package/dist/components/ui/modal/notification/index.d.ts +3 -0
  87. package/dist/components/ui/modal/notification/index.js +2 -0
  88. package/dist/components/ui/modal/notification/types.d.ts +26 -0
  89. package/dist/components/ui/modal/notification/types.js +1 -0
  90. package/dist/components/ui/modal/notification/ui/ModalNotification.svelte +65 -0
  91. package/dist/components/ui/modal/notification/ui/ModalNotification.svelte.d.ts +4 -0
  92. package/dist/components/ui/modal/share/index.d.ts +3 -0
  93. package/dist/components/ui/modal/share/index.js +2 -0
  94. package/dist/components/ui/modal/share/types.d.ts +47 -0
  95. package/dist/components/ui/modal/share/types.js +1 -0
  96. package/dist/components/ui/modal/share/ui/ModalShareSelection.svelte +156 -0
  97. package/dist/components/ui/modal/share/ui/ModalShareSelection.svelte.d.ts +4 -0
  98. package/dist/components/ui/modal/upload/index.d.ts +3 -0
  99. package/dist/components/ui/modal/upload/index.js +2 -0
  100. package/dist/components/ui/modal/upload/types.d.ts +79 -0
  101. package/dist/components/ui/modal/upload/types.js +1 -0
  102. package/dist/components/ui/modal/upload/ui/ModalUpload.svelte +268 -0
  103. package/dist/components/ui/modal/upload/ui/ModalUpload.svelte.d.ts +4 -0
  104. package/dist/components/ui/section/Section01.svelte +90 -0
  105. package/dist/components/ui/section/Section01.svelte.d.ts +4 -0
  106. package/dist/components/ui/section/Section02.svelte +68 -0
  107. package/dist/components/ui/section/Section02.svelte.d.ts +4 -0
  108. package/dist/components/ui/section/Section03.svelte +52 -0
  109. package/dist/components/ui/section/Section03.svelte.d.ts +4 -0
  110. package/dist/components/ui/section/index.d.ts +4 -0
  111. package/dist/components/ui/section/index.js +3 -0
  112. package/dist/components/ui/section/types.d.ts +46 -0
  113. package/dist/components/ui/section/types.js +1 -0
  114. package/dist/docs/DocsSidebar.svelte +58 -1
  115. package/dist/docs/components.d.ts +1 -1
  116. package/dist/docs/components.js +968 -0
  117. package/dist/globals.css +360 -0
  118. package/dist/index.d.ts +185 -0
  119. package/dist/index.js +185 -0
  120. package/dist/types/index.d.ts +53 -0
  121. package/package.json +1 -1
@@ -0,0 +1,195 @@
1
+ <script lang="ts">
2
+ import { Label } from "../../label";
3
+ import { cn } from "../../../../utils";
4
+ import type { InputLabelProps } from "../data/InputLabel.svelte";
5
+
6
+ type SelectOption = { value: string; label: string };
7
+
8
+ let {
9
+ label,
10
+ isLabel = false,
11
+ value = $bindable(""),
12
+ disabled = false,
13
+ required = false,
14
+ placeholder = "Select an option",
15
+ options = [],
16
+ multiple = false,
17
+ class: className,
18
+ ...restProps
19
+ }: InputLabelProps & {
20
+ value?: string | string[];
21
+ options?: SelectOption[];
22
+ multiple?: boolean;
23
+ placeholder?: string;
24
+ disabled?: boolean;
25
+ required?: boolean;
26
+ class?: string;
27
+ } = $props();
28
+
29
+ let isOpen = $state(false);
30
+ let selectRef = $state<HTMLDivElement | null>(null);
31
+
32
+ function handleSelect(option: SelectOption) {
33
+ if (multiple) {
34
+ const arr = Array.isArray(value) ? value : [];
35
+ const idx = arr.indexOf(option.value);
36
+ if (idx >= 0) {
37
+ value = arr.filter((v) => v !== option.value);
38
+ } else {
39
+ value = [...arr, option.value];
40
+ }
41
+ } else {
42
+ value = option.value;
43
+ isOpen = false;
44
+ }
45
+ }
46
+
47
+ function isSelected(option: SelectOption): boolean {
48
+ if (multiple) {
49
+ return Array.isArray(value) && value.includes(option.value);
50
+ }
51
+ return value === option.value;
52
+ }
53
+
54
+ function getDisplayText(): string {
55
+ if (multiple) {
56
+ const arr = Array.isArray(value) ? value : [];
57
+ if (arr.length === 0) return placeholder;
58
+ return arr
59
+ .map((v) => options.find((o) => o.value === v)?.label ?? v)
60
+ .join(", ");
61
+ }
62
+ return options.find((o) => o.value === value)?.label ?? placeholder;
63
+ }
64
+
65
+ function handleClickOutside(e: MouseEvent) {
66
+ if (selectRef && !selectRef.contains(e.target as Node)) {
67
+ isOpen = false;
68
+ }
69
+ }
70
+ </script>
71
+
72
+ <svelte:window onclick={handleClickOutside} />
73
+
74
+ {#if isLabel}
75
+ <div class="flex w-full flex-col gap-3">
76
+ {#if label}
77
+ <Label>{label}</Label>
78
+ {/if}
79
+ <div bind:this={selectRef} class={cn("relative", className)}>
80
+ <button
81
+ type="button"
82
+ {disabled}
83
+ class="flex h-10 w-full items-center justify-between rounded-md border border-input bg-card px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
84
+ onclick={() => (isOpen = !isOpen)}
85
+ >
86
+ <span class={cn(!value && "text-muted-foreground")}>
87
+ {getDisplayText()}
88
+ </span>
89
+ <svg
90
+ class={cn("size-4 shrink-0 opacity-50 transition-transform", isOpen && "rotate-180")}
91
+ xmlns="http://www.w3.org/2000/svg"
92
+ viewBox="0 0 24 24"
93
+ fill="none"
94
+ stroke="currentColor"
95
+ stroke-width="2"
96
+ stroke-linecap="round"
97
+ stroke-linejoin="round"
98
+ >
99
+ <path d="m6 9 6 6 6-6" />
100
+ </svg>
101
+ </button>
102
+
103
+ {#if isOpen}
104
+ <div class="absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border border-border bg-card shadow-md">
105
+ {#each options as option (option.value)}
106
+ <button
107
+ type="button"
108
+ class={cn(
109
+ "flex w-full items-center px-3 py-2 text-sm transition-colors hover:bg-muted",
110
+ isSelected(option) && "bg-muted font-medium"
111
+ )}
112
+ onclick={() => handleSelect(option)}
113
+ >
114
+ {#if multiple}
115
+ <span
116
+ class={cn(
117
+ "mr-2 flex size-4 items-center justify-center rounded border",
118
+ isSelected(option)
119
+ ? "border-primary bg-primary text-primary-foreground"
120
+ : "border-input"
121
+ )}
122
+ >
123
+ {#if isSelected(option)}
124
+ <svg class="size-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
125
+ <path d="M20 6 9 17l-5-5" />
126
+ </svg>
127
+ {/if}
128
+ </span>
129
+ {/if}
130
+ {option.label}
131
+ </button>
132
+ {/each}
133
+ </div>
134
+ {/if}
135
+ </div>
136
+ </div>
137
+ {:else}
138
+ <div bind:this={selectRef} class={cn("relative", className)}>
139
+ <button
140
+ type="button"
141
+ {disabled}
142
+ class="flex h-10 w-full items-center justify-between rounded-md border border-input bg-card px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
143
+ onclick={() => (isOpen = !isOpen)}
144
+ >
145
+ <span class={cn(!value && "text-muted-foreground")}>
146
+ {getDisplayText()}
147
+ </span>
148
+ <svg
149
+ class={cn("size-4 shrink-0 opacity-50 transition-transform", isOpen && "rotate-180")}
150
+ xmlns="http://www.w3.org/2000/svg"
151
+ viewBox="0 0 24 24"
152
+ fill="none"
153
+ stroke="currentColor"
154
+ stroke-width="2"
155
+ stroke-linecap="round"
156
+ stroke-linejoin="round"
157
+ >
158
+ <path d="m6 9 6 6 6-6" />
159
+ </svg>
160
+ </button>
161
+
162
+ {#if isOpen}
163
+ <div class="absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-md border border-border bg-card shadow-md">
164
+ {#each options as option (option.value)}
165
+ <button
166
+ type="button"
167
+ class={cn(
168
+ "flex w-full items-center px-3 py-2 text-sm transition-colors hover:bg-muted",
169
+ isSelected(option) && "bg-muted font-medium"
170
+ )}
171
+ onclick={() => handleSelect(option)}
172
+ >
173
+ {#if multiple}
174
+ <span
175
+ class={cn(
176
+ "mr-2 flex size-4 items-center justify-center rounded border",
177
+ isSelected(option)
178
+ ? "border-primary bg-primary text-primary-foreground"
179
+ : "border-input"
180
+ )}
181
+ >
182
+ {#if isSelected(option)}
183
+ <svg class="size-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
184
+ <path d="M20 6 9 17l-5-5" />
185
+ </svg>
186
+ {/if}
187
+ </span>
188
+ {/if}
189
+ {option.label}
190
+ </button>
191
+ {/each}
192
+ </div>
193
+ {/if}
194
+ </div>
195
+ {/if}
@@ -0,0 +1,17 @@
1
+ import type { InputLabelProps } from "../data/InputLabel.svelte";
2
+ type SelectOption = {
3
+ value: string;
4
+ label: string;
5
+ };
6
+ type $$ComponentProps = InputLabelProps & {
7
+ value?: string | string[];
8
+ options?: SelectOption[];
9
+ multiple?: boolean;
10
+ placeholder?: string;
11
+ disabled?: boolean;
12
+ required?: boolean;
13
+ class?: string;
14
+ };
15
+ declare const InputSelect: import("svelte").Component<$$ComponentProps, {}, "value">;
16
+ type InputSelect = ReturnType<typeof InputSelect>;
17
+ export default InputSelect;
@@ -0,0 +1,61 @@
1
+ <script lang="ts">
2
+ import { cn } from "../../../../utils";
3
+ import { Label } from "../../label";
4
+ import type { HTMLTextareaAttributes } from "svelte/elements";
5
+ import type { WithElementRef } from "../../../../utils";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ value = $bindable(""),
10
+ label,
11
+ isLabel = false,
12
+ placeholder,
13
+ disabled = false,
14
+ required = false,
15
+ rows = 4,
16
+ class: className,
17
+ ...restProps
18
+ }: WithElementRef<HTMLTextareaAttributes> & {
19
+ label?: string;
20
+ isLabel?: boolean;
21
+ placeholder?: string;
22
+ disabled?: boolean;
23
+ required?: boolean;
24
+ rows?: number;
25
+ } = $props();
26
+ </script>
27
+
28
+ {#if isLabel}
29
+ <div class="flex w-full flex-col gap-2">
30
+ {#if label}
31
+ <Label>{label}</Label>
32
+ {/if}
33
+ <textarea
34
+ bind:this={ref}
35
+ bind:value
36
+ {placeholder}
37
+ {disabled}
38
+ {required}
39
+ {rows}
40
+ class={cn(
41
+ "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 placeholder:text-muted-foreground flex min-h-[80px] w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm",
42
+ className
43
+ )}
44
+ {...restProps}
45
+ ></textarea>
46
+ </div>
47
+ {:else}
48
+ <textarea
49
+ bind:this={ref}
50
+ bind:value
51
+ {placeholder}
52
+ {disabled}
53
+ {required}
54
+ {rows}
55
+ class={cn(
56
+ "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 placeholder:text-muted-foreground flex min-h-[80px] w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 md:text-sm",
57
+ className
58
+ )}
59
+ {...restProps}
60
+ ></textarea>
61
+ {/if}
@@ -0,0 +1,13 @@
1
+ import type { HTMLTextareaAttributes } from "svelte/elements";
2
+ import type { WithElementRef } from "../../../../utils";
3
+ type $$ComponentProps = WithElementRef<HTMLTextareaAttributes> & {
4
+ label?: string;
5
+ isLabel?: boolean;
6
+ placeholder?: string;
7
+ disabled?: boolean;
8
+ required?: boolean;
9
+ rows?: number;
10
+ };
11
+ declare const InputTextarea: import("svelte").Component<$$ComponentProps, {}, "ref" | "value">;
12
+ type InputTextarea = ReturnType<typeof InputTextarea>;
13
+ export default InputTextarea;
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import { Label } from "../../label";
3
+ import { cn } from "../../../../utils";
4
+
5
+ let {
6
+ label,
7
+ isLabel = false,
8
+ value = $bindable(false),
9
+ disabled = false,
10
+ description,
11
+ class: className,
12
+ }: {
13
+ label?: string;
14
+ isLabel?: boolean;
15
+ value?: boolean;
16
+ disabled?: boolean;
17
+ description?: string;
18
+ class?: string;
19
+ } = $props();
20
+
21
+ function toggle() {
22
+ if (disabled) return;
23
+ value = !value;
24
+ }
25
+ </script>
26
+
27
+ {#if isLabel}
28
+ <div class={cn("flex w-full flex-col gap-2", className)}>
29
+ <div class="flex items-center justify-between">
30
+ <div class="flex flex-col gap-0.5">
31
+ {#if label}
32
+ <Label>{label}</Label>
33
+ {/if}
34
+ {#if description}
35
+ <p class="text-xs text-muted-foreground">{description}</p>
36
+ {/if}
37
+ </div>
38
+ <button
39
+ type="button"
40
+ role="switch"
41
+ aria-checked={value}
42
+ aria-label={label ?? "Toggle"}
43
+ {disabled}
44
+ class={cn(
45
+ "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
46
+ value ? "bg-primary" : "bg-input"
47
+ )}
48
+ onclick={toggle}
49
+ >
50
+ <span
51
+ class={cn(
52
+ "pointer-events-none block size-5 rounded-full bg-background shadow-lg ring-0 transition-transform",
53
+ value ? "translate-x-5" : "translate-x-0"
54
+ )}
55
+ ></span>
56
+ </button>
57
+ </div>
58
+ </div>
59
+ {:else}
60
+ <div class={cn("flex items-center justify-between", className)}>
61
+ <div class="flex flex-col gap-0.5">
62
+ {#if label}
63
+ <Label>{label}</Label>
64
+ {/if}
65
+ {#if description}
66
+ <p class="text-xs text-muted-foreground">{description}</p>
67
+ {/if}
68
+ </div>
69
+ <button
70
+ type="button"
71
+ role="switch"
72
+ aria-checked={value}
73
+ aria-label={label ?? "Toggle"}
74
+ {disabled}
75
+ class={cn(
76
+ "peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
77
+ value ? "bg-primary" : "bg-input"
78
+ )}
79
+ onclick={toggle}
80
+ >
81
+ <span
82
+ class={cn(
83
+ "pointer-events-none block size-5 rounded-full bg-background shadow-lg ring-0 transition-transform",
84
+ value ? "translate-x-5" : "translate-x-0"
85
+ )}
86
+ ></span>
87
+ </button>
88
+ </div>
89
+ {/if}
@@ -0,0 +1,11 @@
1
+ type $$ComponentProps = {
2
+ label?: string;
3
+ isLabel?: boolean;
4
+ value?: boolean;
5
+ disabled?: boolean;
6
+ description?: string;
7
+ class?: string;
8
+ };
9
+ declare const InputToggle: import("svelte").Component<$$ComponentProps, {}, "value">;
10
+ type InputToggle = ReturnType<typeof InputToggle>;
11
+ export default InputToggle;
@@ -0,0 +1,3 @@
1
+ import Root from "./ui/ModalBadgeSelection.svelte";
2
+ export { Root, Root as ModalBadgeSelection, };
3
+ export type { ModelBadge, ModalBadgeSelectionProps } from "./types";
@@ -0,0 +1,2 @@
1
+ import Root from "./ui/ModalBadgeSelection.svelte";
2
+ export { Root, Root as ModalBadgeSelection, };
@@ -0,0 +1,35 @@
1
+ import type { ModelBadge } from "../core/types";
2
+ export type { ModelBadge } from "../core/types";
3
+ /**
4
+ * Props do componente ModalBadgeSelection — modal de seleção com badges/pills.
5
+ * Segunda variação do sistema de modais do NegoDesign.
6
+ * @property title - Título principal do modal.
7
+ * @property subtitle - Subtítulo/descrição abaixo do título.
8
+ * @property badges - Lista de badges/pills seleccionáveis.
9
+ * @property selectedBadge - Badge actualmente seleccionado.
10
+ * @property multiple - Permite seleção múltipla de badges.
11
+ * @property totalSteps - Número total de passos (para a progress bar).
12
+ * @property currentStep - Passo actual.
13
+ * @property isOpen - Controla a visibilidade do modal.
14
+ * @property onSelect - Chamado ao seleccionar um badge.
15
+ * @property onBack - Chamado ao clicar no botão "Back".
16
+ * @property onContinue - Chamado ao clicar no botão "Continue".
17
+ * @property onSkip - Chamado ao clicar no "Skip This Step".
18
+ * @property class - Classe CSS extra no container do modal.
19
+ */
20
+ export type ModalBadgeSelectionProps = {
21
+ title: string;
22
+ subtitle?: string;
23
+ badges: ModelBadge[];
24
+ selectedBadge?: ModelBadge | null;
25
+ selectedBadges?: ModelBadge[];
26
+ multiple?: boolean;
27
+ totalSteps?: number;
28
+ currentStep?: number;
29
+ isOpen?: boolean;
30
+ onSelect?: (badge: ModelBadge) => void;
31
+ onBack?: () => void;
32
+ onContinue?: () => void;
33
+ onSkip?: () => void;
34
+ class?: string;
35
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,87 @@
1
+ <script lang="ts">
2
+ import { cn } from "../../../../../utils";
3
+ import { HugeiconsIcon } from "@hugeicons/svelte";
4
+ import ModalCore from "../../core/ui/ModalCore.svelte";
5
+ import type { ModalBadgeSelectionProps, ModelBadge } from "../types";
6
+
7
+ let {
8
+ title,
9
+ subtitle,
10
+ badges = [],
11
+ selectedBadge = $bindable(null),
12
+ selectedBadges = $bindable([]),
13
+ multiple = false,
14
+ totalSteps = 1,
15
+ currentStep = 1,
16
+ isOpen = $bindable(false),
17
+ onSelect,
18
+ onBack,
19
+ onContinue,
20
+ onSkip,
21
+ class: className,
22
+ }: ModalBadgeSelectionProps = $props();
23
+
24
+ function handleSelect(badge: ModelBadge) {
25
+ if (multiple) {
26
+ const exists = selectedBadges.some((b) => b.value === badge.value);
27
+ if (exists) {
28
+ selectedBadges = selectedBadges.filter((b) => b.value !== badge.value);
29
+ } else {
30
+ selectedBadges = [...selectedBadges, badge];
31
+ }
32
+ onSelect?.(badge);
33
+ } else {
34
+ selectedBadge = badge;
35
+ onSelect?.(badge);
36
+ }
37
+ }
38
+
39
+ function isSelected(badge: ModelBadge): boolean {
40
+ if (multiple) {
41
+ return selectedBadges.some((b) => b.value === badge.value);
42
+ }
43
+ return selectedBadge?.value === badge.value;
44
+ }
45
+ </script>
46
+
47
+ <ModalCore
48
+ bind:isOpen
49
+ {title}
50
+ {subtitle}
51
+ {totalSteps}
52
+ {currentStep}
53
+ showProgress={true}
54
+ showBack={false}
55
+ showSkip={true}
56
+ {onBack}
57
+ {onContinue}
58
+ {onSkip}
59
+ class={className}
60
+ >
61
+ {#snippet content()}
62
+ <div class="flex flex-wrap gap-3">
63
+ {#each badges as badge (badge.value)}
64
+ {@const selected = isSelected(badge)}
65
+ <button
66
+ type="button"
67
+ class={cn(
68
+ "inline-flex items-center gap-2 rounded-full border px-5 py-2.5 text-sm font-medium transition-all duration-200",
69
+ selected
70
+ ? "border-foreground bg-foreground text-background shadow-md"
71
+ : "border-border bg-card text-foreground hover:border-foreground/50 hover:shadow-sm"
72
+ )}
73
+ onclick={() => handleSelect(badge)}
74
+ >
75
+ {#if badge.icon}
76
+ {#if typeof badge.icon === "string"}
77
+ <i class="{badge.icon} text-sm"></i>
78
+ {:else}
79
+ <HugeiconsIcon icon={badge.icon} class="size-4" />
80
+ {/if}
81
+ {/if}
82
+ {badge.label}
83
+ </button>
84
+ {/each}
85
+ </div>
86
+ {/snippet}
87
+ </ModalCore>
@@ -0,0 +1,4 @@
1
+ import type { ModalBadgeSelectionProps } from "../types";
2
+ declare const ModalBadgeSelection: import("svelte").Component<ModalBadgeSelectionProps, {}, "isOpen" | "selectedBadge" | "selectedBadges">;
3
+ type ModalBadgeSelection = ReturnType<typeof ModalBadgeSelection>;
4
+ export default ModalBadgeSelection;
@@ -0,0 +1,3 @@
1
+ import Root from "./ui/ModalCore.svelte";
2
+ export { Root, Root as ModalCore, };
3
+ export type { ModalCoreProps, ModelBadge, ModelGridCard, ModelSocialShare } from "./types";
@@ -0,0 +1,2 @@
1
+ import Root from "./ui/ModalCore.svelte";
2
+ export { Root, Root as ModalCore, };
@@ -0,0 +1,84 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { IconSvgElement } from "@hugeicons/svelte";
3
+ /**
4
+ * Props do componente ModalCore — contentor base reutilizável para todos os modais.
5
+ * Fornece overlay, container com gradiente, cabeçalho, rodapé com progress bar e navegação.
6
+ * @property isOpen - Controla a visibilidade do modal (bindable).
7
+ * @property title - Título principal do modal.
8
+ * @property subtitle - Subtítulo/descrição abaixo do título.
9
+ * @property totalSteps - Número total de passos (para a progress bar).
10
+ * @property currentStep - Passo actual (para a progress bar).
11
+ * @property showProgress - Exibe a progress bar.
12
+ * @property showBack - Exibe o botão "Back".
13
+ * @property showSkip - Exibe o botão/link "Skip".
14
+ * @property skipText - Texto do botão/link de skip.
15
+ * @property continueText - Texto do botão "Continue".
16
+ * @property backText - Texto do botão "Back".
17
+ * @property onBack - Chamado ao clicar no botão "Back".
18
+ * @property onContinue - Chamado ao clicar no botão "Continue".
19
+ * @property onSkip - Chamado ao clicar no skip.
20
+ * @property onClose - Chamado ao clicar no overlay (fechar).
21
+ * @property content - Snippet com o conteúdo principal do modal.
22
+ * @property footer - Snippet personalizado para o rodapé (substitui o padrão).
23
+ * @property class - Classe CSS extra no container do modal.
24
+ */
25
+ export type ModalCoreProps = {
26
+ isOpen: boolean;
27
+ title: string;
28
+ subtitle?: string;
29
+ totalSteps?: number;
30
+ currentStep?: number;
31
+ showProgress?: boolean;
32
+ showBack?: boolean;
33
+ showSkip?: boolean;
34
+ skipText?: string;
35
+ continueText?: string;
36
+ backText?: string;
37
+ onBack?: () => void;
38
+ onContinue?: () => void;
39
+ onSkip?: () => void;
40
+ onClose?: () => void;
41
+ content?: Snippet;
42
+ footer?: Snippet;
43
+ class?: string;
44
+ };
45
+ /**
46
+ * Modelo de dados para um badge/pill seleccionável dentro do modal.
47
+ * Cada badge representa uma opção simples (ex: "Marketing", "Engineering").
48
+ * @property label - Texto visível do badge.
49
+ * @property value - Valor identificador do badge.
50
+ * @property icon - Ícone opcional exibido antes do label.
51
+ */
52
+ export type ModelBadge = {
53
+ label: string;
54
+ value: string;
55
+ icon?: string | IconSvgElement;
56
+ };
57
+ /**
58
+ * Modelo de dados para um card seleccionável dentro do grid do modal.
59
+ * Cada card representa uma opção com ícone, título e descrição (ex: "Estudante", "Empresa").
60
+ * @property title - Título visível do card.
61
+ * @property description - Descrição curta exibida abaixo do título.
62
+ * @property icon - Ícone exibido no topo do card (string CSS ou HugeIcons).
63
+ */
64
+ export type ModelGridCard = {
65
+ title: string;
66
+ description?: string;
67
+ icon: string | IconSvgElement;
68
+ };
69
+ /**
70
+ * Modelo de dados para uma rede social no modal de partilha.
71
+ * Cada item representa uma plataforma de redes sociais para partilhar conteúdo.
72
+ * @property name - Nome da rede social (ex: "Facebook", "Twitter").
73
+ * @property icon - Ícone da rede social (string CSS ou HugeIcons).
74
+ * @property img - URL da imagem/imagem de marca da rede social.
75
+ * @property color - Cor da rede social (hex, rgb, etc.).
76
+ * @property url - URL de partilha da rede social.
77
+ */
78
+ export type ModelSocialShare = {
79
+ name: string;
80
+ icon?: string | IconSvgElement;
81
+ img?: string;
82
+ color?: string;
83
+ url?: string;
84
+ };
@@ -0,0 +1 @@
1
+ export {};