hamzus-ui 0.0.94 → 0.0.95
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/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/src/components/hamzus-ui/Button/Button.svelte +1 -0
- package/src/components/hamzus-ui/Button/Button_default.svelte +1 -0
- package/src/components/hamzus-ui/ButtonGroup/ButtonGroup.svelte +41 -0
- package/src/components/hamzus-ui/DropdownMenu/Content.svelte +2 -0
- package/src/components/hamzus-ui/DropdownMenu/Root.svelte +337 -189
- package/src/components/hamzus-ui/DropdownMenu copy/Button.svelte +46 -0
- package/src/components/hamzus-ui/DropdownMenu copy/Content.svelte +23 -0
- package/src/components/hamzus-ui/DropdownMenu copy/Label.svelte +1 -0
- package/src/components/hamzus-ui/DropdownMenu copy/Root.svelte +361 -0
- package/src/components/hamzus-ui/DropdownMenu copy/Separator.svelte +12 -0
- package/src/components/hamzus-ui/DropdownMenu copy/Trigger.svelte +1 -0
- package/src/components/hamzus-ui/DropdownMenu copy/index.js +6 -0
- package/src/components/hamzus-ui/IconButton/IconButton.svelte +1 -0
- package/src/components/hamzus-ui/Skeleton/Skeleton.svelte +2 -1
package/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// button
|
|
4
4
|
export { default as Button } from "./src/components/hamzus-ui/Button/Button.svelte"
|
|
5
|
+
export { default as ButtonGroup } from "./src/components/hamzus-ui/ButtonGroup/ButtonGroup.svelte"
|
|
5
6
|
export { default as IconButton } from "./src/components/hamzus-ui/IconButton/IconButton.svelte"
|
|
6
7
|
// text
|
|
7
8
|
export { default as Chips } from "./src/components/hamzus-ui/Chips/Chips.svelte"
|
package/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// button
|
|
2
2
|
export { default as Button } from "./src/components/hamzus-ui/Button/Button.svelte"
|
|
3
|
+
export { default as ButtonGroup } from "./src/components/hamzus-ui/ButtonGroup/ButtonGroup.svelte"
|
|
3
4
|
export { default as IconButton } from "./src/components/hamzus-ui/IconButton/IconButton.svelte"
|
|
4
5
|
// text
|
|
5
6
|
export { default as Chips } from "./src/components/hamzus-ui/Chips/Chips.svelte"
|
package/package.json
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
<div class="button-group">
|
|
4
|
+
<slot></slot>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<style>
|
|
8
|
+
.button-group {
|
|
9
|
+
display: flex;
|
|
10
|
+
height: fit-content;
|
|
11
|
+
}
|
|
12
|
+
.button-group :global(.button) {
|
|
13
|
+
border-radius: 0px !important;
|
|
14
|
+
}
|
|
15
|
+
/* tout les element sauf le premier doivent avoir une ligne a gauche */
|
|
16
|
+
.button-group :global(> .parent-button-hamzus:not(.parent-button-hamzus:first-child) > .button) {
|
|
17
|
+
border-left: 0px solid var(--button-hover-border) !important;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.button-group :global(> .parent-button-hamzus:first-child > .button) {
|
|
21
|
+
border-top-left-radius: var(--radius-m) !important;
|
|
22
|
+
border-bottom-left-radius: var(--radius-m) !important;
|
|
23
|
+
}
|
|
24
|
+
.button-group :global(> .parent-button-hamzus:last-child > .button) {
|
|
25
|
+
border-top-right-radius: var(--radius-m) !important;
|
|
26
|
+
border-bottom-right-radius: var(--radius-m) !important;
|
|
27
|
+
}
|
|
28
|
+
/* tout les element sauf le premier doivent avoir une ligne a gauche */
|
|
29
|
+
.button-group :global(> .parent-popover-hamzus:not(.parent-popover-hamzus:first-child) .button) {
|
|
30
|
+
border-left: 0px solid var(--button-hover-border) !important;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.button-group :global(> .parent-popover-hamzus:first-child .button) {
|
|
34
|
+
border-top-left-radius: var(--radius-m) !important;
|
|
35
|
+
border-bottom-left-radius: var(--radius-m) !important;
|
|
36
|
+
}
|
|
37
|
+
.button-group :global(> .parent-popover-hamzus:last-child .button) {
|
|
38
|
+
border-top-right-radius: var(--radius-m) !important;
|
|
39
|
+
border-bottom-right-radius: var(--radius-m) !important;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import Portal from '../Portal/Portal.svelte';
|
|
3
|
-
import { onDestroy, onMount } from 'svelte';
|
|
3
|
+
import { onDestroy, onMount } from 'svelte';
|
|
4
4
|
|
|
5
5
|
// import
|
|
6
6
|
|
|
@@ -8,8 +8,12 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
8
8
|
export let triggerFullWidth = false;
|
|
9
9
|
export let direction = 'bottom';
|
|
10
10
|
export let onOpen = undefined;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
export let avoidOpening = false;
|
|
12
|
+
export let avoidClosing = false;
|
|
13
|
+
export let forceOpen = false;
|
|
14
|
+
export let forceClose = false;
|
|
15
|
+
export let style = '';
|
|
16
|
+
export let parentTag = null;
|
|
13
17
|
// locale var
|
|
14
18
|
let display = false;
|
|
15
19
|
let exit = false;
|
|
@@ -19,40 +23,70 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
19
23
|
let content;
|
|
20
24
|
let contentContainer;
|
|
21
25
|
|
|
26
|
+
let interval = null;
|
|
27
|
+
|
|
28
|
+
let maxContentHeight = null;
|
|
29
|
+
let maxContentWidth = null;
|
|
30
|
+
let triggerHeight = 0;
|
|
31
|
+
let triggerWidth = 0;
|
|
22
32
|
let top = 0;
|
|
23
33
|
let left = 0;
|
|
24
34
|
|
|
25
35
|
const padding = 7;
|
|
26
36
|
|
|
37
|
+
$: if (forceOpen === true) {
|
|
38
|
+
open()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
forceOpen = false
|
|
42
|
+
}
|
|
43
|
+
$: if (forceClose === true) {
|
|
44
|
+
close()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
forceClose = false
|
|
48
|
+
}
|
|
49
|
+
|
|
27
50
|
const entryPosition = {
|
|
28
51
|
bottom: ['-12px', '0px'],
|
|
52
|
+
[`bottom-right`]: ['-12px', '-12px'],
|
|
53
|
+
[`bottom-left`]: ['-12px', '12px'],
|
|
29
54
|
top: ['12px', '0px'],
|
|
55
|
+
[`top-right`]: ['12px', '12px'],
|
|
56
|
+
[`top-left`]: ['12px', '-12px'],
|
|
30
57
|
left: ['0px', '12px'],
|
|
31
|
-
|
|
58
|
+
[`left-top`]: ['-12px', '12px'],
|
|
59
|
+
[`left-bottom`]: ['12px', '12px'],
|
|
60
|
+
right: ['0px', '-12px'],
|
|
61
|
+
[`right-top`]: ['-12px', '-12px'],
|
|
62
|
+
[`right-bottom`]: ['12px', '-12px']
|
|
32
63
|
};
|
|
33
64
|
// function
|
|
34
|
-
function handleDisplay(e) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (!
|
|
65
|
+
function handleDisplay(e, force) {
|
|
66
|
+
if (!force && avoidOpening) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!entryPosition[direction]) {
|
|
39
70
|
console.error('Error : direction props not found !');
|
|
40
|
-
|
|
71
|
+
return;
|
|
41
72
|
}
|
|
42
73
|
|
|
43
74
|
if (!display) {
|
|
44
|
-
|
|
75
|
+
calculate();
|
|
45
76
|
}
|
|
46
77
|
|
|
47
78
|
toggleDisplay();
|
|
48
79
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
80
|
+
if (onOpen !== undefined && typeof onOpen === 'function') {
|
|
81
|
+
onOpen(e);
|
|
82
|
+
}
|
|
52
83
|
}
|
|
53
84
|
|
|
54
85
|
export let toggleDisplay = () => {
|
|
55
86
|
if (display) {
|
|
87
|
+
clearInterval(interval);
|
|
88
|
+
interval = null;
|
|
89
|
+
|
|
56
90
|
// appliquer une animation
|
|
57
91
|
exit = true;
|
|
58
92
|
setTimeout(() => {
|
|
@@ -62,167 +96,221 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
62
96
|
disableExitEvent();
|
|
63
97
|
enableScroll();
|
|
64
98
|
} else {
|
|
99
|
+
|
|
100
|
+
interval = setInterval(() => {
|
|
101
|
+
calculate();
|
|
102
|
+
}, 100);
|
|
103
|
+
|
|
65
104
|
enableExitEvent();
|
|
66
105
|
disableScroll();
|
|
67
106
|
}
|
|
68
|
-
|
|
107
|
+
|
|
69
108
|
display = !display;
|
|
70
|
-
}
|
|
109
|
+
};
|
|
71
110
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
111
|
+
let open = () => {
|
|
112
|
+
if (display) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
calculate();
|
|
76
116
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
117
|
+
toggleDisplay();
|
|
118
|
+
};
|
|
119
|
+
let close = () => {
|
|
120
|
+
if (!display) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
83
123
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const calc = {
|
|
88
|
-
bottom: () => {
|
|
89
|
-
// recuperer la taille du content
|
|
90
|
-
const contentWidth = content.offsetWidth;
|
|
91
|
-
const contentHeight = content.offsetHeight;
|
|
92
|
-
// recuperer la taille du trigger
|
|
93
|
-
const triggerWidth = trigger.offsetWidth;
|
|
94
|
-
const triggerHeight = trigger.offsetHeight;
|
|
95
|
-
// recuperer la position du trigger par rapport a la fenetre
|
|
96
|
-
const triggerRect = trigger.getBoundingClientRect();
|
|
97
|
-
const triggerTop = triggerRect.top;
|
|
98
|
-
const triggerLeft = triggerRect.left;
|
|
99
|
-
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
100
|
-
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
101
|
-
|
|
102
|
-
// return values
|
|
103
|
-
let topCalc = triggerTop + triggerHeight + padding;
|
|
104
|
-
let leftCalc = triggerLeft - (contentWidth - triggerWidth) / 2;
|
|
105
|
-
|
|
106
|
-
// verifier si il y a assez de la place en bas
|
|
107
|
-
if (triggerBottom < contentHeight) {
|
|
108
|
-
topCalc = window.innerHeight - contentHeight - padding;
|
|
109
|
-
}
|
|
110
|
-
// verifier si il y a assez de place a droite
|
|
111
|
-
if (triggerRight < (contentWidth - triggerWidth) / 2) {
|
|
112
|
-
leftCalc = window.innerWidth - contentWidth - padding;
|
|
113
|
-
}
|
|
114
|
-
// verifier si il y a assez de place a gauche
|
|
124
|
+
toggleDisplay();
|
|
125
|
+
};
|
|
115
126
|
|
|
116
|
-
|
|
117
|
-
|
|
127
|
+
function calculate() {
|
|
128
|
+
|
|
129
|
+
// recuperer les données
|
|
130
|
+
maxContentHeight = null;
|
|
131
|
+
maxContentWidth = null;
|
|
132
|
+
|
|
133
|
+
// recuperer le contenue du trigger
|
|
134
|
+
const triggerContent = getFirstChild(trigger);
|
|
135
|
+
|
|
136
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
137
|
+
const triggerRect = triggerContent.getBoundingClientRect();
|
|
138
|
+
|
|
139
|
+
// recuperer la taille du trigger
|
|
140
|
+
triggerWidth = triggerContent.offsetWidth;
|
|
141
|
+
triggerHeight = triggerContent.offsetHeight;
|
|
142
|
+
|
|
143
|
+
// recuperer l'espace autour du trigger
|
|
144
|
+
const triggerTop = triggerRect.top;
|
|
145
|
+
const triggerLeft = triggerRect.left;
|
|
146
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
147
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
148
|
+
|
|
149
|
+
const calc = {
|
|
150
|
+
bottom: () => {
|
|
151
|
+
// limiter la height par la height disponible en dessous du trigger
|
|
152
|
+
maxContentHeight = triggerBottom - padding;
|
|
153
|
+
|
|
154
|
+
// recuperer le contenue du dropdown
|
|
155
|
+
const contentContent = getFirstChild(content);
|
|
156
|
+
|
|
157
|
+
// recuperer la taille du content
|
|
158
|
+
const contentWidth = contentContent.offsetWidth;
|
|
159
|
+
const contentHeight = contentContent.scrollHeight;
|
|
160
|
+
|
|
161
|
+
// return values
|
|
162
|
+
let topCalc = triggerTop + triggerHeight + padding;
|
|
163
|
+
let leftCalc = triggerLeft - (contentWidth - triggerWidth) / 2; // centrer
|
|
164
|
+
|
|
165
|
+
// si il y a pas assez de place en bas on verifie si ya plus de place en haut, si ya plus de place en haut on display en haut
|
|
166
|
+
if (triggerBottom < contentHeight) {
|
|
167
|
+
// y a pas assez de place si il y a plus de place en haut on display en haut
|
|
168
|
+
if (triggerBottom < triggerTop) {
|
|
169
|
+
calc['top']();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
// ya plus de place ne bas du coup on display en bas et on contraint la hauteur du content
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
top = topCalc;
|
|
176
|
+
left = leftCalc;
|
|
177
|
+
},
|
|
178
|
+
top: () => {
|
|
179
|
+
// contraindre la hauteur maximum disponible pour afficher le dropdown
|
|
180
|
+
maxContentHeight = triggerTop - padding;
|
|
181
|
+
|
|
182
|
+
// recuperer le contenue du dropdown
|
|
183
|
+
const contentContent = getFirstChild(content);
|
|
184
|
+
|
|
185
|
+
// recuperer la taille du content
|
|
186
|
+
const contentWidth = contentContent.offsetWidth;
|
|
187
|
+
const contentHeight = contentContent.offsetHeight;
|
|
188
|
+
|
|
189
|
+
// return values
|
|
190
|
+
let topCalc = triggerTop - contentHeight - padding;
|
|
191
|
+
let leftCalc = triggerLeft - (contentWidth - triggerWidth) / 2; // centrer
|
|
192
|
+
|
|
193
|
+
// verifier si il y a assez de la place en haut
|
|
194
|
+
if (triggerTop < contentHeight) {
|
|
195
|
+
// si y a plus de place en bas que en haut on display en bas
|
|
196
|
+
if (triggerTop < triggerBottom) {
|
|
197
|
+
calc['bottom']();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// on contraint la max height du dropdown
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
top = topCalc;
|
|
205
|
+
left = leftCalc;
|
|
206
|
+
},
|
|
207
|
+
left: () => {
|
|
208
|
+
// limiter la height par la height disponible en dessous du trigger
|
|
209
|
+
maxContentHeight = triggerBottom - padding;
|
|
210
|
+
maxContentWidth = triggerLeft - padding;
|
|
211
|
+
|
|
212
|
+
// recuperer le contenue du dropdown
|
|
213
|
+
const contentContent = getFirstChild(content);
|
|
214
|
+
|
|
215
|
+
// recuperer la taille du content
|
|
216
|
+
const contentWidth = contentContent.offsetWidth;
|
|
217
|
+
const contentHeight = contentContent.scrollHeight;
|
|
218
|
+
|
|
219
|
+
// return values
|
|
220
|
+
let topCalc = triggerTop - (contentHeight - triggerHeight) / 2; // centrer;
|
|
221
|
+
let leftCalc = triggerLeft - contentWidth - padding;
|
|
222
|
+
|
|
223
|
+
// verifier si il y a assez de place a gauche
|
|
224
|
+
if (triggerLeft < contentWidth + padding) {
|
|
225
|
+
// si y a plus de place a droite que gauche on display a droite
|
|
226
|
+
if (triggerLeft < triggerRight) {
|
|
227
|
+
calc['right']();
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// la width est contraint pour l'affichage
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
top = topCalc;
|
|
235
|
+
left = leftCalc;
|
|
236
|
+
},
|
|
237
|
+
right: () => {
|
|
238
|
+
// limiter la height par la height disponible en dessous du trigger
|
|
239
|
+
maxContentHeight = triggerBottom - padding;
|
|
240
|
+
maxContentWidth = triggerRight - padding;
|
|
241
|
+
|
|
242
|
+
// recuperer le contenue du dropdown
|
|
243
|
+
const contentContent = getFirstChild(content);
|
|
244
|
+
|
|
245
|
+
// recuperer la taille du content
|
|
246
|
+
const contentWidth = contentContent.offsetWidth;
|
|
247
|
+
const contentHeight = contentContent.scrollHeight;
|
|
248
|
+
|
|
249
|
+
// return values
|
|
250
|
+
let topCalc = triggerTop - (contentHeight - triggerHeight) / 2; // centrer;
|
|
251
|
+
let leftCalc = triggerLeft + triggerWidth + padding;
|
|
252
|
+
|
|
253
|
+
// verifier si il y a assez de place a droite
|
|
254
|
+
if (triggerRight < contentWidth + padding) {
|
|
255
|
+
// si y a pas assez de place a droite on verifie si y a plus de place a gauche on display a gauche
|
|
256
|
+
if (triggerRight < triggerLeft) {
|
|
257
|
+
calc['left']();
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// la width est contraint pour l'affichage
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
top = topCalc;
|
|
265
|
+
left = leftCalc;
|
|
118
266
|
}
|
|
267
|
+
};
|
|
119
268
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
// verifier si il y a assez de place a droite
|
|
153
|
-
if (triggerRight < (contentWidth - triggerWidth) / 2) {
|
|
154
|
-
leftCalc = window.innerWidth - contentWidth - padding;
|
|
269
|
+
const subCalc = {
|
|
270
|
+
bottom: () => {
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
// aligner le contenue au bas du trigger
|
|
274
|
+
top = triggerTop;
|
|
275
|
+
},
|
|
276
|
+
top: () => {
|
|
277
|
+
// recuperer le contenue du dropdown
|
|
278
|
+
const contentContent = getFirstChild(content);
|
|
279
|
+
|
|
280
|
+
// recuperer la taille du content
|
|
281
|
+
const contentWidth = contentContent.offsetWidth;
|
|
282
|
+
const contentHeight = contentContent.offsetHeight;
|
|
283
|
+
|
|
284
|
+
// aligner le contenue au bas du trigger
|
|
285
|
+
top = triggerTop - (contentHeight - triggerHeight);
|
|
286
|
+
},
|
|
287
|
+
left: () => {
|
|
288
|
+
// recuperer le contenue du dropdown
|
|
289
|
+
const contentContent = getFirstChild(content);
|
|
290
|
+
|
|
291
|
+
// recuperer la taille du content
|
|
292
|
+
const contentWidth = contentContent.offsetWidth;
|
|
293
|
+
const contentHeight = contentContent.offsetHeight;
|
|
294
|
+
|
|
295
|
+
// aligner le contenue a la droite du trigger
|
|
296
|
+
left = triggerLeft - (contentWidth - triggerWidth);
|
|
297
|
+
},
|
|
298
|
+
right: () => {
|
|
299
|
+
left = triggerLeft;
|
|
155
300
|
}
|
|
301
|
+
};
|
|
156
302
|
|
|
157
|
-
|
|
158
|
-
},
|
|
159
|
-
left: () => {
|
|
160
|
-
// recuperer la taille du content
|
|
161
|
-
const contentWidth = content.offsetWidth;
|
|
162
|
-
const contentHeight = content.offsetHeight;
|
|
163
|
-
// recuperer la taille du trigger
|
|
164
|
-
const triggerWidth = trigger.offsetWidth;
|
|
165
|
-
const triggerHeight = trigger.offsetHeight;
|
|
166
|
-
// recuperer la position du trigger par rapport a la fenetre
|
|
167
|
-
const triggerRect = trigger.getBoundingClientRect();
|
|
168
|
-
const triggerTop = triggerRect.top;
|
|
169
|
-
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
170
|
-
const triggerLeft = triggerRect.left;
|
|
171
|
-
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
172
|
-
|
|
173
|
-
// return values
|
|
174
|
-
let topCalc = triggerTop;
|
|
175
|
-
let leftCalc = triggerLeft - contentWidth - padding;
|
|
176
|
-
|
|
177
|
-
// verifier si il y a assez de la place en haut
|
|
178
|
-
if (triggerTop < 0) {
|
|
179
|
-
topCalc = padding;
|
|
180
|
-
}
|
|
181
|
-
// verifier si il y a assez de la place en bas
|
|
182
|
-
if (triggerBottom < (contentHeight - triggerHeight)) {
|
|
183
|
-
topCalc = window.innerHeight - contentHeight - padding;
|
|
184
|
-
}
|
|
185
|
-
// verifier si il y a assez de place a gauche
|
|
186
|
-
if (triggerLeft < contentWidth + padding) {
|
|
187
|
-
leftCalc = padding;
|
|
188
|
-
}
|
|
303
|
+
const directionData = direction.split('-');
|
|
189
304
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
right: () => {
|
|
193
|
-
// recuperer la taille du content
|
|
194
|
-
const contentWidth = content.offsetWidth;
|
|
195
|
-
const contentHeight = content.offsetHeight;
|
|
196
|
-
// recuperer la taille du trigger
|
|
197
|
-
const triggerWidth = trigger.offsetWidth;
|
|
198
|
-
const triggerHeight = trigger.offsetHeight;
|
|
199
|
-
// recuperer la position du trigger par rapport a la fenetre
|
|
200
|
-
const triggerRect = trigger.getBoundingClientRect();
|
|
201
|
-
const triggerTop = triggerRect.top;
|
|
202
|
-
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
203
|
-
const triggerLeft = triggerRect.left;
|
|
204
|
-
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
205
|
-
|
|
206
|
-
// return values
|
|
207
|
-
let topCalc = triggerTop;
|
|
208
|
-
let leftCalc = triggerLeft + triggerWidth + padding;
|
|
209
|
-
|
|
210
|
-
// verifier si il y a assez de la place en haut
|
|
211
|
-
if (triggerTop < 0) {
|
|
212
|
-
topCalc = padding;
|
|
213
|
-
}
|
|
214
|
-
// verifier si il y a assez de la place en bas
|
|
215
|
-
if (triggerBottom < (contentHeight - triggerHeight)) {
|
|
216
|
-
topCalc = window.innerHeight - contentHeight - padding;
|
|
217
|
-
}
|
|
218
|
-
// verifier si il y a assez de place a droite
|
|
219
|
-
if (triggerRight < contentWidth + padding) {
|
|
220
|
-
leftCalc = window.innerWidth - contentWidth - padding - triggerWidth;
|
|
221
|
-
}
|
|
305
|
+
const axe = directionData[0];
|
|
306
|
+
const subDirection = directionData[1];
|
|
222
307
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
308
|
+
calc[axe]();
|
|
309
|
+
|
|
310
|
+
if (subDirection) {
|
|
311
|
+
subCalc[subDirection]()
|
|
312
|
+
}
|
|
313
|
+
}
|
|
226
314
|
|
|
227
315
|
// Bloquer le scroll
|
|
228
316
|
function disableScroll() {
|
|
@@ -237,13 +325,14 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
237
325
|
}
|
|
238
326
|
function updatePos(e) {
|
|
239
327
|
// recalculer la position
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
328
|
+
if (!display) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
calculate();
|
|
244
332
|
}
|
|
245
333
|
|
|
246
334
|
function enableExitEvent() {
|
|
335
|
+
|
|
247
336
|
document.addEventListener('click', checkClick);
|
|
248
337
|
}
|
|
249
338
|
function disableExitEvent() {
|
|
@@ -252,17 +341,64 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
252
341
|
|
|
253
342
|
function checkClick(event) {
|
|
254
343
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
if (event.target.closest('.content-popover-hamzus')) {
|
|
344
|
+
// si avoidClosing est true on skip
|
|
345
|
+
if (avoidClosing) {
|
|
259
346
|
return
|
|
260
347
|
}
|
|
348
|
+
|
|
349
|
+
// si il click sur le trigger alors on skip
|
|
350
|
+
if (
|
|
351
|
+
event.target.closest('.parent-popover-hamzus') &&
|
|
352
|
+
event.target.closest('.parent-popover-hamzus') === originalParent
|
|
353
|
+
) {
|
|
354
|
+
const triggerContent = getFirstChild(event.target.closest('.parent-popover-hamzus'));
|
|
355
|
+
|
|
356
|
+
// si le curseur a cliquer dans le triggerContent on skip
|
|
357
|
+
// si le curseur a cliquer dans le triggerContent on skip
|
|
358
|
+
if (triggerContent && triggerContent.contains(event.target)) {
|
|
359
|
+
return; // on skip
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// si il clique sur un contenue on skip
|
|
364
|
+
|
|
365
|
+
if (event.target.closest('.content-popover-hamzus')) {
|
|
261
366
|
|
|
262
|
-
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
handleDisplay(null, true);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function getFirstChild(node) {
|
|
374
|
+
if (!node) return null;
|
|
375
|
+
|
|
376
|
+
for (const child of node.children) {
|
|
377
|
+
const display = getComputedStyle(child).display;
|
|
378
|
+
|
|
379
|
+
if (display !== 'contents') {
|
|
380
|
+
return child; // trouvé !
|
|
381
|
+
} else {
|
|
382
|
+
// le child est "contents", on cherche dans ses enfants
|
|
383
|
+
const realChild = getFirstChild(child);
|
|
384
|
+
if (realChild) return realChild;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return null; // aucun enfant réel trouvé
|
|
263
389
|
}
|
|
264
390
|
|
|
265
391
|
onMount(() => {
|
|
392
|
+
// recuperer le contenue du trigger
|
|
393
|
+
const triggerContent = getFirstChild(trigger);
|
|
394
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
395
|
+
const triggerRect = triggerContent.getBoundingClientRect();
|
|
396
|
+
|
|
397
|
+
// recuperer la taille du trigger
|
|
398
|
+
triggerWidth = triggerContent.offsetWidth;
|
|
399
|
+
triggerHeight = triggerContent.offsetHeight;
|
|
400
|
+
|
|
401
|
+
|
|
266
402
|
return () => {
|
|
267
403
|
document.removeEventListener('userScroll', updatePos);
|
|
268
404
|
window.removeEventListener('scroll', updatePos);
|
|
@@ -271,32 +407,44 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
271
407
|
});
|
|
272
408
|
</script>
|
|
273
409
|
|
|
274
|
-
<dropdown
|
|
275
|
-
|
|
410
|
+
<dropdown
|
|
411
|
+
bind:this={originalParent}
|
|
412
|
+
style="{triggerFullWidth ? 'width:100%;' : ''} {style}"
|
|
413
|
+
class="parent-popover-hamzus"
|
|
414
|
+
>
|
|
415
|
+
<div bind:this={trigger} class="trigger" on:click={handleDisplay}>
|
|
276
416
|
<slot name="trigger" />
|
|
277
417
|
</div>
|
|
278
418
|
<Portal disabled={!display} target="body">
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
419
|
+
<content-container
|
|
420
|
+
bind:this={contentContainer}
|
|
421
|
+
class="content-container {!display ? 'hidden' : ''}"
|
|
422
|
+
style="
|
|
423
|
+
--hamzus-tigger-width:{triggerWidth}px;
|
|
424
|
+
{maxContentHeight ? `--hamzus-max-content-height:${maxContentHeight}px;` : ''}
|
|
425
|
+
{maxContentWidth ? `--hamzus-max-content-width:${maxContentWidth}px;` : ''}
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
"
|
|
429
|
+
>
|
|
430
|
+
<content
|
|
431
|
+
bind:this={content}
|
|
432
|
+
class="content content-popover-hamzus {parentTag}"
|
|
433
|
+
class:display
|
|
434
|
+
class:exit
|
|
435
|
+
style="--left:{left}px;--top:{top}px;--transform-x:{entryPosition[
|
|
436
|
+
direction
|
|
437
|
+
][1]};--transform-y:{entryPosition[direction][0]};"
|
|
438
|
+
>
|
|
439
|
+
<slot name="content" />
|
|
440
|
+
</content>
|
|
441
|
+
</content-container>
|
|
442
|
+
</Portal>
|
|
293
443
|
</dropdown>
|
|
294
444
|
|
|
295
445
|
<style>
|
|
296
446
|
.trigger {
|
|
297
|
-
|
|
298
|
-
width: max-content;
|
|
299
|
-
display: inline-block;
|
|
447
|
+
display: contents;
|
|
300
448
|
}
|
|
301
449
|
|
|
302
450
|
.content {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let onClick = undefined
|
|
3
|
+
export let label = ""
|
|
4
|
+
function handleClick() {
|
|
5
|
+
if (onClick && typeof onClick === 'function') {
|
|
6
|
+
onClick()
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<button class="button" on:click={handleClick} {...$$restProps}>
|
|
12
|
+
{#if label}
|
|
13
|
+
<h4>{label}</h4>
|
|
14
|
+
{:else}
|
|
15
|
+
<slot/>
|
|
16
|
+
{/if}
|
|
17
|
+
</button>
|
|
18
|
+
|
|
19
|
+
<style>
|
|
20
|
+
.button{
|
|
21
|
+
width: 100%;
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
column-gap: var(--pad-m);
|
|
25
|
+
padding: var(--pad-s) var(--pad-m);
|
|
26
|
+
border-radius: var(--radius-m);
|
|
27
|
+
color: var(--font-2);
|
|
28
|
+
cursor: pointer;
|
|
29
|
+
transition: transform .2s ease-out;
|
|
30
|
+
}
|
|
31
|
+
.button:active {
|
|
32
|
+
transform: scale(.98);
|
|
33
|
+
}
|
|
34
|
+
.button :global(> *) {
|
|
35
|
+
color: var(--font-2);
|
|
36
|
+
fill: var(--font-2);
|
|
37
|
+
}
|
|
38
|
+
.button:hover{
|
|
39
|
+
background-color: var(--bg-3);
|
|
40
|
+
color: var(--font-1);
|
|
41
|
+
}
|
|
42
|
+
.button:hover :global(> *) {
|
|
43
|
+
color: var(--font-1);
|
|
44
|
+
fill: var(--font-2);
|
|
45
|
+
}
|
|
46
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
|
|
3
|
+
export let width = "max-content"
|
|
4
|
+
export let style;
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<div class="content" style="--width:{width};{style}" {...$$restProps}>
|
|
8
|
+
<slot/>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<style>
|
|
12
|
+
.content{
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
row-gap: var(--pad-m);
|
|
16
|
+
padding: var(--pad-m) var(--pad-l);
|
|
17
|
+
background-color: var(--bg-1);
|
|
18
|
+
border-radius: var(--radius-l);
|
|
19
|
+
border: 1px solid var(--bg-3);
|
|
20
|
+
width: min(100vw, var(--width));
|
|
21
|
+
max-height: 100vh;
|
|
22
|
+
}
|
|
23
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h5><slot/></h5>
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import Portal from '../Portal/Portal.svelte';
|
|
3
|
+
import { onDestroy, onMount } from 'svelte';
|
|
4
|
+
|
|
5
|
+
// import
|
|
6
|
+
|
|
7
|
+
// props
|
|
8
|
+
export let triggerFullWidth = false;
|
|
9
|
+
export let direction = 'bottom';
|
|
10
|
+
export let onOpen = undefined;
|
|
11
|
+
export let avoidOpening = false
|
|
12
|
+
export let style = ""
|
|
13
|
+
// locale var
|
|
14
|
+
let display = false;
|
|
15
|
+
let exit = false;
|
|
16
|
+
|
|
17
|
+
let originalParent;
|
|
18
|
+
let trigger;
|
|
19
|
+
let content;
|
|
20
|
+
let contentContainer;
|
|
21
|
+
|
|
22
|
+
let top = 0;
|
|
23
|
+
let left = 0;
|
|
24
|
+
|
|
25
|
+
const padding = 7;
|
|
26
|
+
|
|
27
|
+
const entryPosition = {
|
|
28
|
+
bottom: ['-12px', '0px'],
|
|
29
|
+
top: ['12px', '0px'],
|
|
30
|
+
left: ['0px', '12px'],
|
|
31
|
+
right: ['0px', '-12px']
|
|
32
|
+
};
|
|
33
|
+
// function
|
|
34
|
+
function handleDisplay(e) {
|
|
35
|
+
if (avoidOpening) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
if (!calc[direction]) {
|
|
39
|
+
console.error('Error : direction props not found !');
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!display) {
|
|
44
|
+
[top, left] = calc[direction]();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
toggleDisplay();
|
|
48
|
+
|
|
49
|
+
if (onOpen !== undefined && typeof onOpen === 'function') {
|
|
50
|
+
onOpen(e)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export let toggleDisplay = () => {
|
|
55
|
+
if (display) {
|
|
56
|
+
// appliquer une animation
|
|
57
|
+
exit = true;
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
exit = false;
|
|
60
|
+
}, 200);
|
|
61
|
+
|
|
62
|
+
disableExitEvent();
|
|
63
|
+
enableScroll();
|
|
64
|
+
} else {
|
|
65
|
+
enableExitEvent();
|
|
66
|
+
disableScroll();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
display = !display;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export let open = ()=>{
|
|
73
|
+
if (display) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
toggleDisplay()
|
|
78
|
+
}
|
|
79
|
+
export let close = ()=>{
|
|
80
|
+
if (!display) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
toggleDisplay()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const calc = {
|
|
88
|
+
bottom: () => {
|
|
89
|
+
// recuperer la taille du content
|
|
90
|
+
const contentWidth = content.offsetWidth;
|
|
91
|
+
const contentHeight = content.offsetHeight;
|
|
92
|
+
// recuperer la taille du trigger
|
|
93
|
+
const triggerWidth = trigger.offsetWidth;
|
|
94
|
+
const triggerHeight = trigger.offsetHeight;
|
|
95
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
96
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
97
|
+
const triggerTop = triggerRect.top;
|
|
98
|
+
const triggerLeft = triggerRect.left;
|
|
99
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
100
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
101
|
+
|
|
102
|
+
// return values
|
|
103
|
+
let topCalc = triggerTop + triggerHeight + padding;
|
|
104
|
+
let leftCalc = triggerLeft - (contentWidth - triggerWidth) / 2;
|
|
105
|
+
|
|
106
|
+
// verifier si il y a assez de la place en bas
|
|
107
|
+
if (triggerBottom < contentHeight) {
|
|
108
|
+
topCalc = window.innerHeight - contentHeight - padding;
|
|
109
|
+
}
|
|
110
|
+
// verifier si il y a assez de place a droite
|
|
111
|
+
if (triggerRight < (contentWidth - triggerWidth) / 2) {
|
|
112
|
+
leftCalc = window.innerWidth - contentWidth - padding;
|
|
113
|
+
}
|
|
114
|
+
// verifier si il y a assez de place a gauche
|
|
115
|
+
|
|
116
|
+
if (triggerLeft < (contentWidth - triggerWidth) / 2) {
|
|
117
|
+
leftCalc = padding;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return [topCalc, leftCalc];
|
|
121
|
+
},
|
|
122
|
+
top: () => {
|
|
123
|
+
// recuperer la taille du content
|
|
124
|
+
const contentWidth = content.offsetWidth;
|
|
125
|
+
const contentHeight = content.offsetHeight;
|
|
126
|
+
// recuperer la taille du trigger
|
|
127
|
+
const triggerWidth = trigger.offsetWidth;
|
|
128
|
+
const triggerHeight = trigger.offsetHeight;
|
|
129
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
130
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
131
|
+
const triggerTop = triggerRect.top;
|
|
132
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
133
|
+
const triggerLeft = triggerRect.left;
|
|
134
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
135
|
+
|
|
136
|
+
// return values
|
|
137
|
+
let topCalc = triggerTop - contentHeight - padding;
|
|
138
|
+
let leftCalc = triggerLeft - (contentWidth - triggerWidth) / 2;
|
|
139
|
+
|
|
140
|
+
// verifier si il y a assez de la place en haut
|
|
141
|
+
if (triggerTop < contentHeight) {
|
|
142
|
+
topCalc = padding;
|
|
143
|
+
}
|
|
144
|
+
// verifier si il y a assez de la place en bas
|
|
145
|
+
if (triggerBottom + triggerHeight < contentHeight) {
|
|
146
|
+
topCalc = padding;
|
|
147
|
+
}
|
|
148
|
+
// verifier si il y a assez de place a gauche
|
|
149
|
+
if (triggerLeft < (contentWidth - triggerWidth) / 2) {
|
|
150
|
+
leftCalc = padding;
|
|
151
|
+
}
|
|
152
|
+
// verifier si il y a assez de place a droite
|
|
153
|
+
if (triggerRight < (contentWidth - triggerWidth) / 2) {
|
|
154
|
+
leftCalc = window.innerWidth - contentWidth - padding;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return [topCalc, leftCalc];
|
|
158
|
+
},
|
|
159
|
+
left: () => {
|
|
160
|
+
// recuperer la taille du content
|
|
161
|
+
const contentWidth = content.offsetWidth;
|
|
162
|
+
const contentHeight = content.offsetHeight;
|
|
163
|
+
// recuperer la taille du trigger
|
|
164
|
+
const triggerWidth = trigger.offsetWidth;
|
|
165
|
+
const triggerHeight = trigger.offsetHeight;
|
|
166
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
167
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
168
|
+
const triggerTop = triggerRect.top;
|
|
169
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
170
|
+
const triggerLeft = triggerRect.left;
|
|
171
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
172
|
+
|
|
173
|
+
// return values
|
|
174
|
+
let topCalc = triggerTop;
|
|
175
|
+
let leftCalc = triggerLeft - contentWidth - padding;
|
|
176
|
+
|
|
177
|
+
// verifier si il y a assez de la place en haut
|
|
178
|
+
if (triggerTop < 0) {
|
|
179
|
+
topCalc = padding;
|
|
180
|
+
}
|
|
181
|
+
// verifier si il y a assez de la place en bas
|
|
182
|
+
if (triggerBottom < (contentHeight - triggerHeight)) {
|
|
183
|
+
topCalc = window.innerHeight - contentHeight - padding;
|
|
184
|
+
}
|
|
185
|
+
// verifier si il y a assez de place a gauche
|
|
186
|
+
if (triggerLeft < contentWidth + padding) {
|
|
187
|
+
leftCalc = padding;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return [topCalc, leftCalc];
|
|
191
|
+
},
|
|
192
|
+
right: () => {
|
|
193
|
+
// recuperer la taille du content
|
|
194
|
+
const contentWidth = content.offsetWidth;
|
|
195
|
+
const contentHeight = content.offsetHeight;
|
|
196
|
+
// recuperer la taille du trigger
|
|
197
|
+
const triggerWidth = trigger.offsetWidth;
|
|
198
|
+
const triggerHeight = trigger.offsetHeight;
|
|
199
|
+
// recuperer la position du trigger par rapport a la fenetre
|
|
200
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
201
|
+
const triggerTop = triggerRect.top;
|
|
202
|
+
const triggerBottom = window.innerHeight - triggerTop - triggerHeight;
|
|
203
|
+
const triggerLeft = triggerRect.left;
|
|
204
|
+
const triggerRight = window.innerWidth - triggerLeft - triggerWidth;
|
|
205
|
+
|
|
206
|
+
// return values
|
|
207
|
+
let topCalc = triggerTop;
|
|
208
|
+
let leftCalc = triggerLeft + triggerWidth + padding;
|
|
209
|
+
|
|
210
|
+
// verifier si il y a assez de la place en haut
|
|
211
|
+
if (triggerTop < 0) {
|
|
212
|
+
topCalc = padding;
|
|
213
|
+
}
|
|
214
|
+
// verifier si il y a assez de la place en bas
|
|
215
|
+
if (triggerBottom < (contentHeight - triggerHeight)) {
|
|
216
|
+
topCalc = window.innerHeight - contentHeight - padding;
|
|
217
|
+
}
|
|
218
|
+
// verifier si il y a assez de place a droite
|
|
219
|
+
if (triggerRight < contentWidth + padding) {
|
|
220
|
+
leftCalc = window.innerWidth - contentWidth - padding - triggerWidth;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return [topCalc, leftCalc];
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// Bloquer le scroll
|
|
228
|
+
function disableScroll() {
|
|
229
|
+
document.addEventListener('userScroll', updatePos);
|
|
230
|
+
window.addEventListener('scroll', updatePos);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Réactiver le scroll
|
|
234
|
+
function enableScroll() {
|
|
235
|
+
document.removeEventListener('userScroll', updatePos);
|
|
236
|
+
window.removeEventListener('scroll', updatePos);
|
|
237
|
+
}
|
|
238
|
+
function updatePos(e) {
|
|
239
|
+
// recalculer la position
|
|
240
|
+
if (!display) {
|
|
241
|
+
return
|
|
242
|
+
}
|
|
243
|
+
[top, left] = calc[direction]();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function enableExitEvent() {
|
|
247
|
+
document.addEventListener('click', checkClick);
|
|
248
|
+
}
|
|
249
|
+
function disableExitEvent() {
|
|
250
|
+
document.removeEventListener('click', checkClick);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function checkClick(event) {
|
|
254
|
+
|
|
255
|
+
if (event.target.closest('.parent-popover-hamzus') && event.target.closest('.parent-popover-hamzus') === originalParent) {
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
if (event.target.closest('.content-popover-hamzus')) {
|
|
259
|
+
return
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
handleDisplay();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
onMount(() => {
|
|
266
|
+
return () => {
|
|
267
|
+
document.removeEventListener('userScroll', updatePos);
|
|
268
|
+
window.removeEventListener('scroll', updatePos);
|
|
269
|
+
document.removeEventListener('click', checkClick);
|
|
270
|
+
};
|
|
271
|
+
});
|
|
272
|
+
</script>
|
|
273
|
+
|
|
274
|
+
<dropdown bind:this={originalParent} style="{triggerFullWidth ? "width:100%;" : ""} {style}" class="parent-popover-hamzus">
|
|
275
|
+
<div bind:this={trigger} class="trigger" style="{triggerFullWidth ? "width:100%;" : ""}" okn:click={handleDisplay}>
|
|
276
|
+
<slot name="trigger" />
|
|
277
|
+
</div>
|
|
278
|
+
<Portal disabled={!display} target="body">
|
|
279
|
+
<content-container bind:this={contentContainer} class="content-container {!display ? "hidden" : ""}">
|
|
280
|
+
<content
|
|
281
|
+
bind:this={content}
|
|
282
|
+
class="content content-popover-hamzus"
|
|
283
|
+
class:display
|
|
284
|
+
class:exit
|
|
285
|
+
style="--left:{left}px;--top:{top}px;--transform-x:{entryPosition[
|
|
286
|
+
direction
|
|
287
|
+
][1]};--transform-y:{entryPosition[direction][0]};"
|
|
288
|
+
>
|
|
289
|
+
<slot name="content" />
|
|
290
|
+
</content>
|
|
291
|
+
</content-container>
|
|
292
|
+
</Portal>
|
|
293
|
+
</dropdown>
|
|
294
|
+
|
|
295
|
+
<style>
|
|
296
|
+
.trigger {
|
|
297
|
+
all: unset;
|
|
298
|
+
width: max-content;
|
|
299
|
+
display: inline-block;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.content {
|
|
303
|
+
position: fixed;
|
|
304
|
+
top: var(--top);
|
|
305
|
+
left: var(--left);
|
|
306
|
+
display: block;
|
|
307
|
+
user-select: none;
|
|
308
|
+
pointer-events: none;
|
|
309
|
+
opacity: 0;
|
|
310
|
+
z-index: 20;
|
|
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
|
+
|
|
329
|
+
@keyframes entry {
|
|
330
|
+
from {
|
|
331
|
+
display: block;
|
|
332
|
+
opacity: 0;
|
|
333
|
+
user-select: none;
|
|
334
|
+
pointer-events: none;
|
|
335
|
+
transform: translate(var(--transform-x), var(--transform-y)) scale(0.86);
|
|
336
|
+
}
|
|
337
|
+
to {
|
|
338
|
+
display: block;
|
|
339
|
+
opacity: 1;
|
|
340
|
+
user-select: initial;
|
|
341
|
+
pointer-events: initial;
|
|
342
|
+
transform: translate(0px, 0px) scale(1);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
@keyframes exit {
|
|
346
|
+
from {
|
|
347
|
+
display: block;
|
|
348
|
+
opacity: 1;
|
|
349
|
+
user-select: initial;
|
|
350
|
+
pointer-events: initial;
|
|
351
|
+
transform: translate(0px, 0px) scale(1);
|
|
352
|
+
}
|
|
353
|
+
to {
|
|
354
|
+
display: block;
|
|
355
|
+
opacity: 0;
|
|
356
|
+
user-select: none;
|
|
357
|
+
pointer-events: none;
|
|
358
|
+
transform: translate(var(--transform-x), var(--transform-y)) scale(0.86);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
</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';
|
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
<style>
|
|
8
8
|
.skeleton {
|
|
9
|
+
display: flex;
|
|
9
10
|
background: linear-gradient(90deg, var(--bg-2) 25%, var(--bg-3) 50%, var(--bg-2) 75%);
|
|
10
11
|
background-size: 200% 100%;
|
|
11
12
|
animation: skeleton-loading 1.5s infinite;
|
|
12
13
|
border-radius: 4px; /* Pour arrondir les coins */
|
|
13
|
-
flex-shrink: 0;
|
|
14
|
+
/* flex-shrink: 0; */
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
/* Animation */
|