hamzus-ui 0.0.1
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/README.md +38 -0
- package/index.js +6 -0
- package/package.json +48 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Content.svelte +22 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Label.svelte +1 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Root.svelte +336 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Separator.svelte +12 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Trigger.svelte +5 -0
- package/src/components/hamzus-ui/AdvancedTooltip/index.js +5 -0
- package/src/components/hamzus-ui/AlertCard/AlertCard.svelte +32 -0
- package/src/components/hamzus-ui/Avatar/Avatar.svelte +32 -0
- package/src/components/hamzus-ui/Button/Button.svelte +79 -0
- package/src/components/hamzus-ui/Button/Button_default.svelte +142 -0
- package/src/components/hamzus-ui/Button/Button_link.svelte +138 -0
- package/src/components/hamzus-ui/Checkboxes/Checkbox/Checkbox.svelte +41 -0
- package/src/components/hamzus-ui/Checkboxes/Checkbox/index.css +68 -0
- package/src/components/hamzus-ui/Checkboxes/CheckboxCard/CheckboxCard.svelte +27 -0
- package/src/components/hamzus-ui/Checkboxes/CheckboxCard/index.css +54 -0
- package/src/components/hamzus-ui/Code/Code.svelte +192 -0
- package/src/components/hamzus-ui/CopyCode/CopyCode.svelte +55 -0
- package/src/components/hamzus-ui/CopyLabel/CopyLabel.svelte +43 -0
- package/src/components/hamzus-ui/DataList/DataList.svelte +82 -0
- package/src/components/hamzus-ui/DatePicker/DatePicker.svelte +326 -0
- package/src/components/hamzus-ui/Dialog/Dialog.svelte +61 -0
- package/src/components/hamzus-ui/DropdownMenu/Button.svelte +46 -0
- package/src/components/hamzus-ui/DropdownMenu/Content.svelte +22 -0
- package/src/components/hamzus-ui/DropdownMenu/Label.svelte +1 -0
- package/src/components/hamzus-ui/DropdownMenu/Root.svelte +340 -0
- package/src/components/hamzus-ui/DropdownMenu/Separator.svelte +12 -0
- package/src/components/hamzus-ui/DropdownMenu/Trigger.svelte +1 -0
- package/src/components/hamzus-ui/DropdownMenu/index.js +6 -0
- package/src/components/hamzus-ui/IconButton/IconButton.svelte +80 -0
- package/src/components/hamzus-ui/IconButton/IconButton_default.svelte +140 -0
- package/src/components/hamzus-ui/IconButton/IconButton_link.svelte +141 -0
- package/src/components/hamzus-ui/InfoCard/InfoCard.svelte +32 -0
- package/src/components/hamzus-ui/Input/Input.svelte +304 -0
- package/src/components/hamzus-ui/KBD/KBD.svelte +24 -0
- package/src/components/hamzus-ui/Link/Link.svelte +36 -0
- package/src/components/hamzus-ui/List/List.svelte +30 -0
- package/src/components/hamzus-ui/LoaderCircle/Loader.svelte +25 -0
- package/src/components/hamzus-ui/LoaderCircle/index.js +1 -0
- package/src/components/hamzus-ui/Popover/Button.svelte +46 -0
- package/src/components/hamzus-ui/Popover/Content.svelte +21 -0
- package/src/components/hamzus-ui/Popover/Label.svelte +1 -0
- package/src/components/hamzus-ui/Popover/Root.svelte +374 -0
- package/src/components/hamzus-ui/Popover/Separator.svelte +12 -0
- package/src/components/hamzus-ui/Popover/Trigger.svelte +1 -0
- package/src/components/hamzus-ui/Popover/index.js +6 -0
- package/src/components/hamzus-ui/Portal/Portal.svelte +46 -0
- package/src/components/hamzus-ui/Portal/Wormhole.svelte +7 -0
- package/src/components/hamzus-ui/Radios/Radio/Radio.svelte +43 -0
- package/src/components/hamzus-ui/Radios/Radio/index.css +68 -0
- package/src/components/hamzus-ui/Radios/RadioCard/RadioCard.svelte +32 -0
- package/src/components/hamzus-ui/Radios/RadioCard/index.css +50 -0
- package/src/components/hamzus-ui/Radios/RadioGroup/RadioGroup.svelte +46 -0
- package/src/components/hamzus-ui/Radios/RadioGroup/index.css +8 -0
- package/src/components/hamzus-ui/ScrollArea/ScrollArea.svelte +360 -0
- package/src/components/hamzus-ui/Swicth/Swicth.svelte +84 -0
- package/src/components/hamzus-ui/Swicth/index.css +120 -0
- package/src/components/hamzus-ui/Table/ActionsBar.svelte +174 -0
- package/src/components/hamzus-ui/Table/Content.svelte +68 -0
- package/src/components/hamzus-ui/Table/Header.svelte +268 -0
- package/src/components/hamzus-ui/Table/NavigationBar.svelte +10 -0
- package/src/components/hamzus-ui/Table/Root.svelte +128 -0
- package/src/components/hamzus-ui/Table/index.js +5 -0
- package/src/components/hamzus-ui/Table/table.js +48 -0
- package/src/components/hamzus-ui/Tabs/Tabs.svelte +87 -0
- package/src/components/hamzus-ui/TabsLink/Tabs.svelte +80 -0
- package/src/components/hamzus-ui/Tag/Tag.svelte +43 -0
- package/src/components/hamzus-ui/TinyScrollArea/TinyScrollArea.svelte +350 -0
- package/src/styles/font.css +71 -0
- package/src/styles/global.css +37 -0
- package/src/styles/variables.css +81 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Portal from '@hamzus-ui/Portal/Portal.svelte';
|
|
3
|
+
import { onDestroy, onMount } from 'svelte';
|
|
4
|
+
|
|
5
|
+
// import
|
|
6
|
+
|
|
7
|
+
// props
|
|
8
|
+
export let direction = 'bottom';
|
|
9
|
+
export let triggerFullWidth = false;
|
|
10
|
+
export let onOpen = undefined;
|
|
11
|
+
// locale var
|
|
12
|
+
let display = false;
|
|
13
|
+
let exit = false;
|
|
14
|
+
|
|
15
|
+
let originalParent;
|
|
16
|
+
let trigger;
|
|
17
|
+
let content;
|
|
18
|
+
let contentContainer;
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
let top = 0;
|
|
22
|
+
let left = 0;
|
|
23
|
+
|
|
24
|
+
const padding = 7;
|
|
25
|
+
|
|
26
|
+
let paddingTop = direction === 'bottom' ? padding : 0;
|
|
27
|
+
let paddingBttom = direction === 'top' ? padding : 0;
|
|
28
|
+
let paddingLeft = direction === 'right' ? padding : 0;
|
|
29
|
+
let paddingRight = direction === 'left' ? padding : 0;
|
|
30
|
+
|
|
31
|
+
const entryPosition = {
|
|
32
|
+
bottom: ['-12px', '0px'],
|
|
33
|
+
top: ['12px', '0px'],
|
|
34
|
+
left: ['0px', '12px'],
|
|
35
|
+
right: ['0px', '-12px']
|
|
36
|
+
};
|
|
37
|
+
// function
|
|
38
|
+
function handleDisplay(event) {
|
|
39
|
+
if (!calc[direction]) {
|
|
40
|
+
console.error('Error : direction props not found !');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (display && event.target.closest('.trigger')) {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!display) {
|
|
48
|
+
[top, left] = calc[direction]();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
toggleDisplay();
|
|
52
|
+
|
|
53
|
+
if (onOpen !== undefined && typeof onOpen === 'function') {
|
|
54
|
+
onOpen()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function toggleDisplay() {
|
|
59
|
+
if (display) {
|
|
60
|
+
// appliquer une animation
|
|
61
|
+
exit = true;
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
exit = false;
|
|
64
|
+
}, 200);
|
|
65
|
+
|
|
66
|
+
disableExitEvent();
|
|
67
|
+
enableScroll();
|
|
68
|
+
} else {
|
|
69
|
+
enableExitEvent();
|
|
70
|
+
disableScroll();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
display = !display;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
const calc = {
|
|
78
|
+
bottom: () => {
|
|
79
|
+
// recuperer la taille du content
|
|
80
|
+
const contentWidth = content.offsetWidth;
|
|
81
|
+
const contentHeight = content.offsetHeight;
|
|
82
|
+
// recuperer la taille du trigger
|
|
83
|
+
const triggerWidth = trigger.offsetWidth;
|
|
84
|
+
const triggerHeight = trigger.offsetHeight;
|
|
85
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
86
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
87
|
+
const triggerTop = triggerRect.top;
|
|
88
|
+
const triggerLeft = triggerRect.left;
|
|
89
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
90
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
91
|
+
|
|
92
|
+
// return values
|
|
93
|
+
let topCalc = triggerTop + triggerHeight ;
|
|
94
|
+
let leftCalc = triggerLeft - (contentWidth - triggerWidth) / 2;
|
|
95
|
+
|
|
96
|
+
// verifier si il y a assez de la place en bas
|
|
97
|
+
if (triggerBottom < contentHeight) {
|
|
98
|
+
topCalc = window.innerHeight - contentHeight ;
|
|
99
|
+
}
|
|
100
|
+
// verifier si il y a assez de place a droite
|
|
101
|
+
if (triggerRight < (contentWidth - triggerWidth) / 2) {
|
|
102
|
+
leftCalc = window.innerWidth - contentWidth ;
|
|
103
|
+
}
|
|
104
|
+
// verifier si il y a assez de place a gauche
|
|
105
|
+
|
|
106
|
+
if (triggerLeft < (contentWidth - triggerWidth) / 2) {
|
|
107
|
+
leftCalc = 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return [topCalc, leftCalc];
|
|
111
|
+
},
|
|
112
|
+
top: () => {
|
|
113
|
+
// recuperer la taille du content
|
|
114
|
+
const contentWidth = content.offsetWidth;
|
|
115
|
+
const contentHeight = content.offsetHeight;
|
|
116
|
+
// recuperer la taille du trigger
|
|
117
|
+
const triggerWidth = trigger.offsetWidth;
|
|
118
|
+
const triggerHeight = trigger.offsetHeight;
|
|
119
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
120
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
121
|
+
const triggerTop = triggerRect.top;
|
|
122
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
123
|
+
const triggerLeft = triggerRect.left;
|
|
124
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
125
|
+
|
|
126
|
+
// return values
|
|
127
|
+
let topCalc = triggerTop - contentHeight;
|
|
128
|
+
let leftCalc = triggerLeft - (contentWidth - triggerWidth) / 2;
|
|
129
|
+
|
|
130
|
+
// verifier si il y a assez de la place en haut
|
|
131
|
+
if (triggerTop < contentHeight) {
|
|
132
|
+
topCalc = 0;
|
|
133
|
+
}
|
|
134
|
+
// verifier si il y a assez de la place en bas
|
|
135
|
+
if (triggerBottom + triggerHeight < contentHeight) {
|
|
136
|
+
topCalc = 0;
|
|
137
|
+
}
|
|
138
|
+
// verifier si il y a assez de place a gauche
|
|
139
|
+
if (triggerLeft < (contentWidth - triggerWidth) / 2) {
|
|
140
|
+
leftCalc = 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return [topCalc, leftCalc];
|
|
144
|
+
},
|
|
145
|
+
left: () => {
|
|
146
|
+
// recuperer la taille du content
|
|
147
|
+
const contentWidth = content.offsetWidth;
|
|
148
|
+
const contentHeight = content.offsetHeight;
|
|
149
|
+
// recuperer la taille du trigger
|
|
150
|
+
const triggerWidth = trigger.offsetWidth;
|
|
151
|
+
const triggerHeight = trigger.offsetHeight;
|
|
152
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
153
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
154
|
+
const triggerTop = triggerRect.top;
|
|
155
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
156
|
+
const triggerLeft = triggerRect.left;
|
|
157
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
158
|
+
|
|
159
|
+
// return values
|
|
160
|
+
let topCalc = triggerTop - (contentHeight - triggerHeight) / 2;
|
|
161
|
+
let leftCalc = triggerLeft - contentWidth;
|
|
162
|
+
|
|
163
|
+
// verifier si il y a assez de la place en haut
|
|
164
|
+
if (triggerTop < (contentHeight - triggerHeight) / 2) {
|
|
165
|
+
topCalc = 0;
|
|
166
|
+
}
|
|
167
|
+
// verifier si il y a assez de la place en bas
|
|
168
|
+
if (triggerBottom < (contentHeight - triggerHeight) / 2) {
|
|
169
|
+
topCalc = window.innerHeight - contentHeight ;
|
|
170
|
+
}
|
|
171
|
+
// verifier si il y a assez de place a gauche
|
|
172
|
+
if (triggerLeft < contentWidth) {
|
|
173
|
+
leftCalc = 0;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return [topCalc, leftCalc];
|
|
177
|
+
},
|
|
178
|
+
right: () => {
|
|
179
|
+
// recuperer la taille du content
|
|
180
|
+
const contentWidth = content.offsetWidth;
|
|
181
|
+
const contentHeight = content.offsetHeight;
|
|
182
|
+
// recuperer la taille du trigger
|
|
183
|
+
const triggerWidth = trigger.offsetWidth;
|
|
184
|
+
const triggerHeight = trigger.offsetHeight;
|
|
185
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
186
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
187
|
+
const triggerTop = triggerRect.top;
|
|
188
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
189
|
+
const triggerLeft = triggerRect.left;
|
|
190
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
191
|
+
|
|
192
|
+
// return values
|
|
193
|
+
let topCalc = triggerTop - (contentHeight - triggerHeight) / 2;
|
|
194
|
+
let leftCalc = triggerLeft + triggerWidth ;
|
|
195
|
+
|
|
196
|
+
// verifier si il y a assez de la place en haut
|
|
197
|
+
if (triggerTop < (contentHeight - triggerHeight) / 2) {
|
|
198
|
+
topCalc = 0;
|
|
199
|
+
}
|
|
200
|
+
// verifier si il y a assez de la place en bas
|
|
201
|
+
if (triggerBottom < (contentHeight - triggerHeight) / 2) {
|
|
202
|
+
topCalc = window.innerHeight - contentHeight ;
|
|
203
|
+
}
|
|
204
|
+
// verifier si il y a assez de place a droite
|
|
205
|
+
if (triggerRight < contentWidth ) {
|
|
206
|
+
leftCalc = window.innerWidth - contentWidth - triggerWidth;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return [topCalc, leftCalc];
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// Bloquer le scroll
|
|
214
|
+
function disableScroll() {
|
|
215
|
+
window.addEventListener('scroll', preventDefault, { passive: false });
|
|
216
|
+
window.addEventListener('wheel', preventDefault, { passive: false });
|
|
217
|
+
window.addEventListener('touchmove', preventDefault, { passive: false });
|
|
218
|
+
window.addEventListener('keydown', preventScrollKeys);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Réactiver le scroll
|
|
222
|
+
function enableScroll() {
|
|
223
|
+
window.removeEventListener('scroll', preventDefault);
|
|
224
|
+
window.removeEventListener('wheel', preventDefault);
|
|
225
|
+
window.removeEventListener('touchmove', preventDefault);
|
|
226
|
+
window.removeEventListener('keydown', preventScrollKeys);
|
|
227
|
+
}
|
|
228
|
+
function preventDefault(e) {
|
|
229
|
+
e.preventDefault();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function preventScrollKeys(e) {
|
|
233
|
+
// Désactiver uniquement les touches qui provoquent un défilement
|
|
234
|
+
const keys = ['ArrowUp', 'ArrowDown', 'Space', 'PageUp', 'PageDown'];
|
|
235
|
+
if (keys.includes(e.key)) {
|
|
236
|
+
e.preventDefault();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function enableExitEvent() {
|
|
241
|
+
document.addEventListener('mousemove', checkCursor);
|
|
242
|
+
}
|
|
243
|
+
function disableExitEvent() {
|
|
244
|
+
document.removeEventListener('mousemove', checkCursor);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function checkCursor(event) {
|
|
248
|
+
if ((!event.target.closest('.trigger') || event.target.closest('.trigger') !== trigger ) && (!event.target.closest('.content') || event.target.closest('.content') !== content)) {
|
|
249
|
+
handleDisplay(event);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
onMount(() => {
|
|
254
|
+
return () => {
|
|
255
|
+
window.removeEventListener('scroll', preventDefault);
|
|
256
|
+
window.removeEventListener('wheel', preventDefault);
|
|
257
|
+
window.removeEventListener('touchmove', preventDefault);
|
|
258
|
+
window.removeEventListener('keydown', preventScrollKeys);
|
|
259
|
+
document.removeEventListener('mousemove', checkCursor);
|
|
260
|
+
};
|
|
261
|
+
});
|
|
262
|
+
</script>
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
<dropdown bind:this={originalParent}>
|
|
266
|
+
<div bind:this={trigger} class="trigger" style="{triggerFullWidth ? "width:100%;" : ""}" on:mouseenter={handleDisplay} on:mouseleave={handleDisplay}>
|
|
267
|
+
<slot name="trigger" />
|
|
268
|
+
</div>
|
|
269
|
+
<Portal disabled={!display} target="body">
|
|
270
|
+
<content-container bind:this={contentContainer}>
|
|
271
|
+
<content
|
|
272
|
+
bind:this={content}
|
|
273
|
+
class="content"
|
|
274
|
+
class:display
|
|
275
|
+
class:exit
|
|
276
|
+
style="
|
|
277
|
+
--padding-top:{paddingTop}px;
|
|
278
|
+
--padding-bottom:{paddingBttom}px;
|
|
279
|
+
--padding-left:{paddingLeft}px;
|
|
280
|
+
--padding-right:{paddingRight}px;
|
|
281
|
+
--left:{left}px;
|
|
282
|
+
--top:{top}px;
|
|
283
|
+
--transform-x:{entryPosition[direction][1]};
|
|
284
|
+
--transform-y:{entryPosition[direction][0]};"
|
|
285
|
+
>
|
|
286
|
+
<slot name="content" />
|
|
287
|
+
</content>
|
|
288
|
+
<div class="dropdown-bg-exit"></div>
|
|
289
|
+
</content-container>
|
|
290
|
+
</Portal>
|
|
291
|
+
</dropdown>
|
|
292
|
+
|
|
293
|
+
<style>
|
|
294
|
+
.trigger {
|
|
295
|
+
all: unset;
|
|
296
|
+
z-index: 2;
|
|
297
|
+
position: relative;
|
|
298
|
+
display: inline-block;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.content {
|
|
302
|
+
position: fixed;
|
|
303
|
+
top: var(--top);
|
|
304
|
+
left: var(--left);
|
|
305
|
+
display: block;
|
|
306
|
+
user-select: none;
|
|
307
|
+
pointer-events: none;
|
|
308
|
+
opacity: 0;
|
|
309
|
+
z-index: 2;
|
|
310
|
+
padding:var(--padding-top) var(--padding-right) var(--padding-bottom) var(--padding-left);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.content.exit {
|
|
314
|
+
display: block;
|
|
315
|
+
animation-name: exit;
|
|
316
|
+
animation-duration: 0.2s;
|
|
317
|
+
animation-timing-function: ease-out;
|
|
318
|
+
}
|
|
319
|
+
.content.display {
|
|
320
|
+
display: block;
|
|
321
|
+
animation-name: entry;
|
|
322
|
+
animation-duration: 0.2s;
|
|
323
|
+
animation-timing-function: ease-out;
|
|
324
|
+
user-select: initial;
|
|
325
|
+
pointer-events: initial;
|
|
326
|
+
opacity: 1;
|
|
327
|
+
}
|
|
328
|
+
.dropdown-bg-exit {
|
|
329
|
+
display: none;
|
|
330
|
+
}
|
|
331
|
+
.content.display ~ .dropdown-bg-exit {
|
|
332
|
+
content: '';
|
|
333
|
+
position: fixed;
|
|
334
|
+
top: 0;
|
|
335
|
+
left: 0;
|
|
336
|
+
width: 100%;
|
|
337
|
+
height: 100%;
|
|
338
|
+
z-index: 1;
|
|
339
|
+
display: block;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
@keyframes entry {
|
|
343
|
+
from {
|
|
344
|
+
display: block;
|
|
345
|
+
opacity: 0;
|
|
346
|
+
user-select: none;
|
|
347
|
+
pointer-events: none;
|
|
348
|
+
transform: translate(var(--transform-x), var(--transform-y)) scale(0.9);
|
|
349
|
+
}
|
|
350
|
+
to {
|
|
351
|
+
display: block;
|
|
352
|
+
opacity: 1;
|
|
353
|
+
user-select: initial;
|
|
354
|
+
pointer-events: initial;
|
|
355
|
+
transform: translate(0px, 0px) scale(1);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
@keyframes exit {
|
|
359
|
+
from {
|
|
360
|
+
display: block;
|
|
361
|
+
opacity: 1;
|
|
362
|
+
user-select: initial;
|
|
363
|
+
pointer-events: initial;
|
|
364
|
+
transform: translate(0px, 0px) scale(1);
|
|
365
|
+
}
|
|
366
|
+
to {
|
|
367
|
+
display: block;
|
|
368
|
+
opacity: 0;
|
|
369
|
+
user-select: none;
|
|
370
|
+
pointer-events: none;
|
|
371
|
+
transform: translate(var(--transform-x), var(--transform-y)) scale(0.9);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<slot/>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { default as Root } from './Root.svelte';
|
|
2
|
+
export { default as Trigger } from './Trigger.svelte';
|
|
3
|
+
export { default as Content } from './Content.svelte';
|
|
4
|
+
export { default as Label } from './Label.svelte';
|
|
5
|
+
export { default as Separator } from './Separator.svelte';
|
|
6
|
+
export { default as Button } from './Button.svelte';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { mount, unmount } from 'svelte';
|
|
3
|
+
import Wormhole from './Wormhole.svelte';
|
|
4
|
+
|
|
5
|
+
let { children, target, disabled = false } = $props();
|
|
6
|
+
|
|
7
|
+
$effect(() => {
|
|
8
|
+
let app;
|
|
9
|
+
let element;
|
|
10
|
+
|
|
11
|
+
if (disabled) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!target) {
|
|
16
|
+
console.warn(`[svelte-portal] Invalid Portal target: ${target}`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (typeof target === 'string') {
|
|
21
|
+
element = document.querySelector(target);
|
|
22
|
+
} else {
|
|
23
|
+
element = target;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (element) {
|
|
27
|
+
|
|
28
|
+
app = mount(Wormhole, {
|
|
29
|
+
target: element,
|
|
30
|
+
props: {
|
|
31
|
+
children
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return () => {
|
|
37
|
+
if (app) {
|
|
38
|
+
unmount(app);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
{#if disabled}
|
|
45
|
+
{@render children()}
|
|
46
|
+
{/if}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let name;
|
|
3
|
+
export let value;
|
|
4
|
+
export let group = false;
|
|
5
|
+
export let label;
|
|
6
|
+
export let size = "20px";
|
|
7
|
+
export let disabled = false;
|
|
8
|
+
export let checked = false;
|
|
9
|
+
export let activeColor = 'var(--accent)';
|
|
10
|
+
export let onClick = () => {};
|
|
11
|
+
|
|
12
|
+
import "./index.css";
|
|
13
|
+
|
|
14
|
+
function handleClick() {
|
|
15
|
+
if (disabled) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (!onClick) {
|
|
19
|
+
group = true;
|
|
20
|
+
}
|
|
21
|
+
onClick();
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<label
|
|
26
|
+
class="label-radio {disabled ? 'disabled' : ''}"
|
|
27
|
+
style="--active-color:{activeColor};"
|
|
28
|
+
on:click={handleClick}
|
|
29
|
+
>
|
|
30
|
+
<input
|
|
31
|
+
class="radio"
|
|
32
|
+
type="radio"
|
|
33
|
+
{name}
|
|
34
|
+
{value}
|
|
35
|
+
bind:group
|
|
36
|
+
style="width:{size}; height:{size};"
|
|
37
|
+
disabled={disabled}
|
|
38
|
+
/>
|
|
39
|
+
{#if label}
|
|
40
|
+
<h4>{label}</h4>
|
|
41
|
+
{/if}
|
|
42
|
+
</label>
|
|
43
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
|
|
2
|
+
.label-radio{
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
column-gap: 7px;
|
|
6
|
+
cursor: pointer;
|
|
7
|
+
transition: transform .2s ease-out;
|
|
8
|
+
}
|
|
9
|
+
.label-radio:hover:not(.disabled) > h4{
|
|
10
|
+
color: var(--font-u);
|
|
11
|
+
transition: color .2s ease-out;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
.label-radio:active{
|
|
16
|
+
transform: scale(.9);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.label-radio input[type="radio"].radio{
|
|
20
|
+
width: 16px;
|
|
21
|
+
height: 16px;
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
border-radius: 24px;
|
|
25
|
+
border: 2px solid var(--stroke);
|
|
26
|
+
position: relative;
|
|
27
|
+
transition-property: border background-color ;
|
|
28
|
+
transition-duration: .2s;
|
|
29
|
+
transition-timing-function: ease-out;
|
|
30
|
+
}
|
|
31
|
+
.label-radio:not(.disabled) input[type="radio"].radio{
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.label-radio:not(.disabled) input[type="radio"].radio:hover{
|
|
36
|
+
background-color: var(--bg-2);
|
|
37
|
+
}
|
|
38
|
+
.label-radio input[type="radio"].radio::after{
|
|
39
|
+
content: '';
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 50%;
|
|
42
|
+
left: 50%;
|
|
43
|
+
transform: translate(-50%, -50%) scale(.8);
|
|
44
|
+
width: 60%;
|
|
45
|
+
height: 60%;
|
|
46
|
+
border-radius: 50%;
|
|
47
|
+
background-color: var(--active-color);
|
|
48
|
+
opacity:0;
|
|
49
|
+
transition-property: transform opacity ;
|
|
50
|
+
transition-duration: .2s;
|
|
51
|
+
transition-timing-function: ease-out;
|
|
52
|
+
}
|
|
53
|
+
.label-radio input[type="radio"].radio:checked{
|
|
54
|
+
border: 2px solid var(--active-color);
|
|
55
|
+
}
|
|
56
|
+
.label-radio input[type="radio"].radio:checked::after{
|
|
57
|
+
transform: translate(-50%, -50%) scale(1);
|
|
58
|
+
opacity: 1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
.label-radio.disabled{
|
|
63
|
+
opacity: .8;
|
|
64
|
+
cursor: not-allowed ;
|
|
65
|
+
}
|
|
66
|
+
.label-radio.disabled input[type="radio"].radio{
|
|
67
|
+
cursor: not-allowed !important;
|
|
68
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let title;
|
|
3
|
+
export let text;
|
|
4
|
+
export let icon;
|
|
5
|
+
export let name;
|
|
6
|
+
export let style = null;
|
|
7
|
+
export let value;
|
|
8
|
+
export let onClick = ()=>{};
|
|
9
|
+
export let checked = false;
|
|
10
|
+
export let size = '20px';
|
|
11
|
+
export let disabled = false;
|
|
12
|
+
export let activeColor = 'var(--accent)';
|
|
13
|
+
|
|
14
|
+
import './index.css';
|
|
15
|
+
|
|
16
|
+
import Radio from '../Radio/Radio.svelte';
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<label {style} class="radio-card {disabled ? "disabled" : ""}">
|
|
20
|
+
<div class="radio-left-content">
|
|
21
|
+
{#if icon}
|
|
22
|
+
<svelte:component this={icon} />
|
|
23
|
+
{/if}
|
|
24
|
+
<div class="text">
|
|
25
|
+
<h3>{title}</h3>
|
|
26
|
+
{#if text}
|
|
27
|
+
<p>{text}</p>
|
|
28
|
+
{/if}
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
<Radio {activeColor} {size} {disabled} group={checked} {name} {value} />
|
|
32
|
+
</label>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
.radio-card{
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: space-between;
|
|
6
|
+
padding: var(--pad-xl);
|
|
7
|
+
border-radius: var(--radius-l);
|
|
8
|
+
background-color: var(--bg-2);
|
|
9
|
+
border: 2px solid var(--bg-2);
|
|
10
|
+
column-gap: 24px;
|
|
11
|
+
transition: transform .2s ease-out;
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
}
|
|
14
|
+
.radio-card:not(.disabled):active{
|
|
15
|
+
transform: scale(.95);
|
|
16
|
+
}
|
|
17
|
+
.radio-card:hover{
|
|
18
|
+
background-color: var(--bg-3);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.radio-card .radio-left-content{
|
|
22
|
+
display: flex;
|
|
23
|
+
column-gap: var(--pad-m);
|
|
24
|
+
}
|
|
25
|
+
.radio-card .radio-left-content .text{
|
|
26
|
+
row-gap: -10px;
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
}
|
|
30
|
+
.radio-card .radio-left-content svg{
|
|
31
|
+
width: 30px;
|
|
32
|
+
height: 30px;
|
|
33
|
+
flex-shrink: 0;
|
|
34
|
+
}
|
|
35
|
+
.radio-card .radio-left-content svg path{
|
|
36
|
+
fill: var(--font-d);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.radio-card:has(input:checked){
|
|
40
|
+
border: 2px solid var(--accent);
|
|
41
|
+
}
|
|
42
|
+
.radio-card:has(input:checked) .radio-left-content svg path{
|
|
43
|
+
fill: var(--accent);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* disabled */
|
|
47
|
+
.radio-card.disabled{
|
|
48
|
+
opacity: .5;
|
|
49
|
+
cursor: not-allowed;
|
|
50
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let name = 'name';
|
|
3
|
+
export let options = [];
|
|
4
|
+
export let variant = 'default';
|
|
5
|
+
export let selectedValue = null; // Valeur sélectionnée
|
|
6
|
+
export let onChange = undefined;
|
|
7
|
+
import './index.css';
|
|
8
|
+
|
|
9
|
+
import Radio from '../Radio/Radio.svelte';
|
|
10
|
+
import RadioCard from '../RadioCard/RadioCard.svelte';
|
|
11
|
+
|
|
12
|
+
// Fonction pour mettre à jour la sélection
|
|
13
|
+
function handleSelect(value) {
|
|
14
|
+
selectedValue = value;
|
|
15
|
+
|
|
16
|
+
if (onChange !== undefined && typeof onChange === 'function') {
|
|
17
|
+
onChange()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div class="radio-group radio-group-{variant}">
|
|
23
|
+
{#each options as option}
|
|
24
|
+
{#if variant == 'default'}
|
|
25
|
+
<Radio
|
|
26
|
+
{name}
|
|
27
|
+
value={option.value}
|
|
28
|
+
group={option.value === selectedValue}
|
|
29
|
+
on:select={() => handleSelect(option.value)}
|
|
30
|
+
label={option.label}
|
|
31
|
+
disabled={option.disabled}
|
|
32
|
+
/>
|
|
33
|
+
{:else}
|
|
34
|
+
<RadioCard
|
|
35
|
+
icon={option.icon}
|
|
36
|
+
{name}
|
|
37
|
+
value={option.value}
|
|
38
|
+
checked={option.value === selectedValue}
|
|
39
|
+
on:select={() => handleSelect(option.value)}
|
|
40
|
+
title={option.title}
|
|
41
|
+
text={option.text}
|
|
42
|
+
disabled={option.disabled}
|
|
43
|
+
/>
|
|
44
|
+
{/if}
|
|
45
|
+
{/each}
|
|
46
|
+
</div>
|