hamzus-ui 0.0.68 → 0.0.69
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/DropdownMenu/Root.svelte +4 -3
- package/src/components/hamzus-ui/Slider/Slider.svelte +278 -0
- package/src/components/hamzus-ui/Slider copy/Slider.svelte +276 -0
- package/src/components/hamzus-ui/Slider copy/slider/+page.svelte +49 -0
- package/src/components/hamzus-ui/SoundTrackSlider/SoundTrack.svelte +226 -0
package/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export { default as TextArea } from "./src/components/hamzus-ui/TextArea/TextAre
|
|
|
23
23
|
export { default as Checkbox } from "./src/components/hamzus-ui/Checkboxes/Checkbox/Checkbox.svelte"
|
|
24
24
|
export { default as Switch } from "./src/components/hamzus-ui/Switch/Switch.svelte"
|
|
25
25
|
export { default as InputFile } from "./src/components/hamzus-ui/InputFile/InputFile.svelte"
|
|
26
|
+
export { default as Slider } from "./src/components/hamzus-ui/Slider/Slider.svelte"
|
|
26
27
|
|
|
27
28
|
// navigation
|
|
28
29
|
export * as Tabs from "./src/components/hamzus-ui/Tabs"
|
package/index.js
CHANGED
|
@@ -19,6 +19,7 @@ export { default as TextArea } from "./src/components/hamzus-ui/TextArea/TextAre
|
|
|
19
19
|
export { default as Checkbox } from "./src/components/hamzus-ui/Checkboxes/Checkbox/Checkbox.svelte"
|
|
20
20
|
export { default as Switch } from "./src/components/hamzus-ui/Switch/Switch.svelte"
|
|
21
21
|
export { default as InputFile } from "./src/components/hamzus-ui/InputFile/InputFile.svelte"
|
|
22
|
+
export { default as Slider } from "./src/components/hamzus-ui/Slider/Slider.svelte"
|
|
22
23
|
|
|
23
24
|
// navigation
|
|
24
25
|
export * as Tabs from "./src/components/hamzus-ui/Tabs"
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
9
9
|
export let direction = 'bottom';
|
|
10
10
|
export let onOpen = undefined;
|
|
11
11
|
export let avoidOpening = false
|
|
12
|
+
export let style = ""
|
|
12
13
|
// locale var
|
|
13
14
|
let display = false;
|
|
14
15
|
let exit = false;
|
|
@@ -270,12 +271,12 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
270
271
|
});
|
|
271
272
|
</script>
|
|
272
273
|
|
|
273
|
-
<dropdown bind:this={originalParent} style="{triggerFullWidth ? "width:100%;" : ""}" class="parent-popover-hamzus">
|
|
274
|
+
<dropdown bind:this={originalParent} style="{triggerFullWidth ? "width:100%;" : ""} {style}" class="parent-popover-hamzus">
|
|
274
275
|
<div bind:this={trigger} class="trigger" style="{triggerFullWidth ? "width:100%;" : ""}" on:click={handleDisplay}>
|
|
275
276
|
<slot name="trigger" />
|
|
276
277
|
</div>
|
|
277
278
|
<Portal disabled={!display} target="body">
|
|
278
|
-
<content-container bind:this={contentContainer}>
|
|
279
|
+
<content-container bind:this={contentContainer} class="content-container {!display ? "hidden" : ""}">
|
|
279
280
|
<content
|
|
280
281
|
bind:this={content}
|
|
281
282
|
class="content content-popover-hamzus"
|
|
@@ -306,7 +307,7 @@ import { onDestroy, onMount } from 'svelte';
|
|
|
306
307
|
user-select: none;
|
|
307
308
|
pointer-events: none;
|
|
308
309
|
opacity: 0;
|
|
309
|
-
z-index:
|
|
310
|
+
z-index: 20;
|
|
310
311
|
}
|
|
311
312
|
|
|
312
313
|
.content.exit {
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let orientation = 'horizontal';
|
|
3
|
+
export let name = 'slider';
|
|
4
|
+
export let min = 0;
|
|
5
|
+
export let max = 100;
|
|
6
|
+
export let value = 50;
|
|
7
|
+
export let step = 0.01;
|
|
8
|
+
export let scaleFactor = 1.4;
|
|
9
|
+
export let displayStep = false;
|
|
10
|
+
export let stepWidth = 2;
|
|
11
|
+
export let stepHeight = 16;
|
|
12
|
+
|
|
13
|
+
let slider;
|
|
14
|
+
|
|
15
|
+
let isDraging = false;
|
|
16
|
+
|
|
17
|
+
let actualX = null;
|
|
18
|
+
let actualY = null;
|
|
19
|
+
|
|
20
|
+
$: percent = getPercentage(min, max, value);
|
|
21
|
+
|
|
22
|
+
$: stepValues = getStepValues(min, max, step);
|
|
23
|
+
|
|
24
|
+
function getStepValues(min, max, step) {
|
|
25
|
+
const result = [];
|
|
26
|
+
|
|
27
|
+
// Trouver le premier multiple de `step` >= min
|
|
28
|
+
const first = Math.ceil(min / step) * step;
|
|
29
|
+
|
|
30
|
+
for (let val = first; val <= max + step / 10; val += step) {
|
|
31
|
+
// push le step en pourcent
|
|
32
|
+
result.push(parseFloat(((val - min) / (max - min) * 100).toFixed(10)));
|
|
33
|
+
}
|
|
34
|
+
// si il n y a pas zero et 100 on le push
|
|
35
|
+
if (!result.includes(0)) {
|
|
36
|
+
result.push(0)
|
|
37
|
+
}
|
|
38
|
+
if (!result.includes(100)) {
|
|
39
|
+
result.push(100)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getPercentage(min, max, value) {
|
|
46
|
+
let maxFromZero = max - min;
|
|
47
|
+
|
|
48
|
+
let ratio = (value - min) / maxFromZero;
|
|
49
|
+
|
|
50
|
+
return ratio * 100;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function handleClickDown(event) {
|
|
54
|
+
event.preventDefault()
|
|
55
|
+
|
|
56
|
+
isDraging = true;
|
|
57
|
+
|
|
58
|
+
actualX = event.clientX;
|
|
59
|
+
actualY = event.clientY;
|
|
60
|
+
|
|
61
|
+
// calculer la nouvelle valeur en fonction de la position du curseur
|
|
62
|
+
updateValue();
|
|
63
|
+
|
|
64
|
+
document.addEventListener('mousemove', handleUpdateCursorState);
|
|
65
|
+
document.addEventListener('mouseup', handleClickUp);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function handleUpdateCursorState(event) {
|
|
69
|
+
actualX = event.clientX;
|
|
70
|
+
actualY = event.clientY;
|
|
71
|
+
|
|
72
|
+
updateValue();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function handleClickUp() {
|
|
76
|
+
isDraging = false;
|
|
77
|
+
|
|
78
|
+
actualX = null;
|
|
79
|
+
actualY = null;
|
|
80
|
+
|
|
81
|
+
document.removeEventListener('mouseup', handleClickUp);
|
|
82
|
+
document.removeEventListener('mousemove', handleUpdateCursorState);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function updateValue() {
|
|
86
|
+
// mettre a jour la valeur en fonction de la position
|
|
87
|
+
|
|
88
|
+
let sliderSize = slider[orientation === 'horizontal' ? 'offsetWidth' : 'offsetHeight']; // taille du slider
|
|
89
|
+
|
|
90
|
+
let sliderOffset =
|
|
91
|
+
slider.getBoundingClientRect()[orientation === 'horizontal' ? 'left' : 'top']; // position de depart du slider dans la vue
|
|
92
|
+
|
|
93
|
+
let movementRelativeToSlider =
|
|
94
|
+
(orientation === 'horizontal' ? actualX : actualY) - sliderOffset; // mouvement en pixel par rapport a la position de depart du slider
|
|
95
|
+
|
|
96
|
+
let ratioMovement = movementRelativeToSlider / sliderSize;
|
|
97
|
+
|
|
98
|
+
// inverser le ratio car le slider vertical demarre d en bas
|
|
99
|
+
if (orientation === 'vertical') {
|
|
100
|
+
ratioMovement = 1 - ratioMovement;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// convertir le pourcentage en valeur en fonction du min et max
|
|
104
|
+
let maxFromZero = max - min;
|
|
105
|
+
|
|
106
|
+
let newPercentFromZero = ratioMovement * maxFromZero;
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
let newValue = Math.round((newPercentFromZero + min) / step) * step;
|
|
110
|
+
|
|
111
|
+
// si le nouveau pourcentage est plus pres de 100% que le pourcentage de la nouvelleValeur on met a 100 et inversement pour 0
|
|
112
|
+
let newValuePercent = getPercentage(min, max, newValue)
|
|
113
|
+
|
|
114
|
+
if (Math.abs(newPercentFromZero - newValuePercent) > Math.abs(newPercentFromZero - 100)) {
|
|
115
|
+
newValue = max
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (Math.abs(newPercentFromZero - newValuePercent) > Math.abs(newPercentFromZero - 0)) {
|
|
119
|
+
newValue = min
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (newValue > max) {
|
|
123
|
+
newValue = max;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (newValue < min) {
|
|
127
|
+
newValue = min;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
value = newValue;
|
|
131
|
+
}
|
|
132
|
+
</script>
|
|
133
|
+
|
|
134
|
+
<div
|
|
135
|
+
class="slider-container {orientation === 'horizontal' ? 'horizontal' : 'vertical'}"
|
|
136
|
+
style="--step-width:{stepWidth}px;--step-height:{stepHeight}px;"
|
|
137
|
+
>
|
|
138
|
+
<input type="hidden" {name} {value} />
|
|
139
|
+
<div
|
|
140
|
+
bind:this={slider}
|
|
141
|
+
on:mousedown={handleClickDown}
|
|
142
|
+
class="slider {isDraging ? 'hover' : ''}"
|
|
143
|
+
style="--scale-factor:{scaleFactor};"
|
|
144
|
+
>
|
|
145
|
+
<span class="progress" style="--progress:{percent}%;"></span>
|
|
146
|
+
<span class="track" style="--progress:{percent}%;"></span>
|
|
147
|
+
</div>
|
|
148
|
+
{#if displayStep}
|
|
149
|
+
<!-- parcourir les step du min au max -->
|
|
150
|
+
{#each stepValues as stepValue}
|
|
151
|
+
<span class="step" style="--offset:{stepValue}%;"></span>
|
|
152
|
+
{/each}
|
|
153
|
+
{/if}
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<style>
|
|
157
|
+
.slider-container {
|
|
158
|
+
display: flex;
|
|
159
|
+
position: relative;
|
|
160
|
+
}
|
|
161
|
+
.slider-container.horizontal {
|
|
162
|
+
width: 100%;
|
|
163
|
+
height: 7px;
|
|
164
|
+
align-items: center;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.slider-container.vertical {
|
|
168
|
+
width: 7px;
|
|
169
|
+
height: 100%;
|
|
170
|
+
justify-content: center;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.slider {
|
|
174
|
+
background-color: var(--accent-b);
|
|
175
|
+
display: flex;
|
|
176
|
+
border-radius: 100px;
|
|
177
|
+
outline: 3px solid var(--bg-blur);
|
|
178
|
+
cursor: pointer;
|
|
179
|
+
position: relative;
|
|
180
|
+
|
|
181
|
+
transition-property: height, width;
|
|
182
|
+
transition-duration: 0.1s;
|
|
183
|
+
transition-timing-function: ease-out;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.horizontal .slider {
|
|
187
|
+
width: 100%;
|
|
188
|
+
height: 5px;
|
|
189
|
+
}
|
|
190
|
+
.horizontal .slider.hover,
|
|
191
|
+
.horizontal .slider:hover {
|
|
192
|
+
height: 7px;
|
|
193
|
+
/* transform: scaleY(var(--scale-factor)); */
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.vertical .slider {
|
|
197
|
+
width: 5px;
|
|
198
|
+
height: 100%;
|
|
199
|
+
align-items: end;
|
|
200
|
+
}
|
|
201
|
+
.vertical .slider.hover,
|
|
202
|
+
.vertical .slider:hover {
|
|
203
|
+
width: 7px;
|
|
204
|
+
/* transform: scaleX(var(--scale-factor)); */
|
|
205
|
+
}
|
|
206
|
+
.slider::after {
|
|
207
|
+
content: '';
|
|
208
|
+
position: absolute;
|
|
209
|
+
top: -7px;
|
|
210
|
+
left: -7px;
|
|
211
|
+
width: calc(100% + 14px);
|
|
212
|
+
height: calc(100% + 14px);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.progress {
|
|
216
|
+
background-color: var(--accent);
|
|
217
|
+
border-radius: 3px;
|
|
218
|
+
z-index: 2;
|
|
219
|
+
}
|
|
220
|
+
.horizontal .progress {
|
|
221
|
+
width: var(--progress);
|
|
222
|
+
height: 100%;
|
|
223
|
+
}
|
|
224
|
+
.vertical .progress {
|
|
225
|
+
width: 100%;
|
|
226
|
+
height: var(--progress);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.track {
|
|
230
|
+
z-index: 3;
|
|
231
|
+
width: 12px;
|
|
232
|
+
height: 12px;
|
|
233
|
+
border-radius: 12.5px;
|
|
234
|
+
background-color: var(--bg-1);
|
|
235
|
+
border: 1px solid var(--stroke);
|
|
236
|
+
/* outline: 2px solid var(--bg-blur); */
|
|
237
|
+
position: absolute;
|
|
238
|
+
transition-property: width, height;
|
|
239
|
+
transition-duration: 0.1s;
|
|
240
|
+
transition-timing-function: ease-out;
|
|
241
|
+
}
|
|
242
|
+
.horizontal .track {
|
|
243
|
+
left: var(--progress);
|
|
244
|
+
top: 50%;
|
|
245
|
+
transform: translate(-50%, -50%);
|
|
246
|
+
}
|
|
247
|
+
.vertical .track {
|
|
248
|
+
bottom: var(--progress);
|
|
249
|
+
left: 50%;
|
|
250
|
+
transform: translate(-50%, 50%);
|
|
251
|
+
}
|
|
252
|
+
.slider-container:has(.slider.hover) .track,
|
|
253
|
+
.slider-container:hover .track {
|
|
254
|
+
width: 16px;
|
|
255
|
+
height: 16px;
|
|
256
|
+
outline: 2px solid var(--bg-blur);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.step {
|
|
260
|
+
background-color: var(--bg-2);
|
|
261
|
+
border-radius: 700px;
|
|
262
|
+
position: absolute;
|
|
263
|
+
z-index: 1;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.horizontal .step {
|
|
267
|
+
width: var(--step-width);
|
|
268
|
+
height: var(--step-height);
|
|
269
|
+
transform: translateX(-50%);
|
|
270
|
+
left: var(--offset);
|
|
271
|
+
}
|
|
272
|
+
.vertical .step {
|
|
273
|
+
width: var(--step-height);
|
|
274
|
+
height: var(--step-width);
|
|
275
|
+
transform: translateY(50%);
|
|
276
|
+
bottom: var(--offset);
|
|
277
|
+
}
|
|
278
|
+
</style>
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let orientation = 'horizontal';
|
|
3
|
+
export let name = 'slider';
|
|
4
|
+
export let min = 0;
|
|
5
|
+
export let max = 100;
|
|
6
|
+
export let value = 50;
|
|
7
|
+
export let step = 0.01;
|
|
8
|
+
export let scaleFactor = 1.4;
|
|
9
|
+
export let displayStep = false;
|
|
10
|
+
export let stepWidth = 2;
|
|
11
|
+
export let stepHeight = 16;
|
|
12
|
+
|
|
13
|
+
let slider;
|
|
14
|
+
|
|
15
|
+
let isDraging = false;
|
|
16
|
+
|
|
17
|
+
let actualX = null;
|
|
18
|
+
let actualY = null;
|
|
19
|
+
|
|
20
|
+
$: percent = getPercentage(min, max, value);
|
|
21
|
+
|
|
22
|
+
$: stepValues = getStepValues(min, max, step);
|
|
23
|
+
|
|
24
|
+
function getStepValues(min, max, step) {
|
|
25
|
+
const result = [];
|
|
26
|
+
|
|
27
|
+
// Trouver le premier multiple de `step` >= min
|
|
28
|
+
const first = Math.ceil(min / step) * step;
|
|
29
|
+
|
|
30
|
+
for (let val = first; val <= max + step / 10; val += step) {
|
|
31
|
+
// push le step en pourcent
|
|
32
|
+
result.push(parseFloat(((val - min) / (max - min) * 100).toFixed(10)));
|
|
33
|
+
}
|
|
34
|
+
// si il n y a pas zero et 100 on le push
|
|
35
|
+
if (!result.includes(0)) {
|
|
36
|
+
result.push(0)
|
|
37
|
+
}
|
|
38
|
+
if (!result.includes(100)) {
|
|
39
|
+
result.push(100)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getPercentage(min, max, value) {
|
|
46
|
+
let maxFromZero = max - min;
|
|
47
|
+
|
|
48
|
+
let ratio = (value - min) / maxFromZero;
|
|
49
|
+
|
|
50
|
+
return ratio * 100;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function handleClickDown(event) {
|
|
54
|
+
isDraging = true;
|
|
55
|
+
|
|
56
|
+
actualX = event.clientX;
|
|
57
|
+
actualY = event.clientY;
|
|
58
|
+
|
|
59
|
+
// calculer la nouvelle valeur en fonction de la position du curseur
|
|
60
|
+
updateValue();
|
|
61
|
+
|
|
62
|
+
document.addEventListener('mousemove', handleUpdateCursorState);
|
|
63
|
+
document.addEventListener('mouseup', handleClickUp);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function handleUpdateCursorState(event) {
|
|
67
|
+
actualX = event.clientX;
|
|
68
|
+
actualY = event.clientY;
|
|
69
|
+
|
|
70
|
+
updateValue();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function handleClickUp() {
|
|
74
|
+
isDraging = false;
|
|
75
|
+
|
|
76
|
+
actualX = null;
|
|
77
|
+
actualY = null;
|
|
78
|
+
|
|
79
|
+
document.removeEventListener('mouseup', handleClickUp);
|
|
80
|
+
document.removeEventListener('mousemove', handleUpdateCursorState);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function updateValue() {
|
|
84
|
+
// mettre a jour la valeur en fonction de la position
|
|
85
|
+
|
|
86
|
+
let sliderSize = slider[orientation === 'horizontal' ? 'offsetWidth' : 'offsetHeight']; // taille du slider
|
|
87
|
+
|
|
88
|
+
let sliderOffset =
|
|
89
|
+
slider.getBoundingClientRect()[orientation === 'horizontal' ? 'left' : 'top']; // position de depart du slider dans la vue
|
|
90
|
+
|
|
91
|
+
let movementRelativeToSlider =
|
|
92
|
+
(orientation === 'horizontal' ? actualX : actualY) - sliderOffset; // mouvement en pixel par rapport a la position de depart du slider
|
|
93
|
+
|
|
94
|
+
let ratioMovement = movementRelativeToSlider / sliderSize;
|
|
95
|
+
|
|
96
|
+
// inverser le ratio car le slider vertical demarre d en bas
|
|
97
|
+
if (orientation === 'vertical') {
|
|
98
|
+
ratioMovement = 1 - ratioMovement;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// convertir le pourcentage en valeur en fonction du min et max
|
|
102
|
+
let maxFromZero = max - min;
|
|
103
|
+
|
|
104
|
+
let newPercentFromZero = ratioMovement * maxFromZero;
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
let newValue = Math.round((newPercentFromZero + min) / step) * step;
|
|
108
|
+
|
|
109
|
+
// si le nouveau pourcentage est plus pres de 100% que le pourcentage de la nouvelleValeur on met a 100 et inversement pour 0
|
|
110
|
+
let newValuePercent = getPercentage(min, max, newValue)
|
|
111
|
+
|
|
112
|
+
if (Math.abs(newPercentFromZero - newValuePercent) > Math.abs(newPercentFromZero - 100)) {
|
|
113
|
+
newValue = max
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (Math.abs(newPercentFromZero - newValuePercent) > Math.abs(newPercentFromZero - 0)) {
|
|
117
|
+
newValue = min
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (newValue > max) {
|
|
121
|
+
newValue = max;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (newValue < min) {
|
|
125
|
+
newValue = min;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
value = newValue;
|
|
129
|
+
}
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<div
|
|
133
|
+
class="slider-container {orientation === 'horizontal' ? 'horizontal' : 'vertical'}"
|
|
134
|
+
style="--step-width:{stepWidth}px;--step-height:{stepHeight}px;"
|
|
135
|
+
>
|
|
136
|
+
<input type="hidden" {name} {value} />
|
|
137
|
+
<div
|
|
138
|
+
bind:this={slider}
|
|
139
|
+
on:mousedown={handleClickDown}
|
|
140
|
+
class="slider {isDraging ? 'hover' : ''}"
|
|
141
|
+
style="--scale-factor:{scaleFactor};"
|
|
142
|
+
>
|
|
143
|
+
<span class="progress" style="--progress:{percent}%;"></span>
|
|
144
|
+
<span class="track" style="--progress:{percent}%;"></span>
|
|
145
|
+
</div>
|
|
146
|
+
{#if displayStep}
|
|
147
|
+
<!-- parcourir les step du min au max -->
|
|
148
|
+
{#each stepValues as stepValue}
|
|
149
|
+
<span class="step" style="--offset:{stepValue}%;"></span>
|
|
150
|
+
{/each}
|
|
151
|
+
{/if}
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
<style>
|
|
155
|
+
.slider-container {
|
|
156
|
+
display: flex;
|
|
157
|
+
position: relative;
|
|
158
|
+
}
|
|
159
|
+
.slider-container.horizontal {
|
|
160
|
+
width: 100%;
|
|
161
|
+
height: 7px;
|
|
162
|
+
align-items: center;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.slider-container.vertical {
|
|
166
|
+
width: 7px;
|
|
167
|
+
height: 100%;
|
|
168
|
+
justify-content: center;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.slider {
|
|
172
|
+
background-color: var(--accent-b);
|
|
173
|
+
display: flex;
|
|
174
|
+
border-radius: 100px;
|
|
175
|
+
outline: 3px solid var(--bg-blur);
|
|
176
|
+
cursor: pointer;
|
|
177
|
+
position: relative;
|
|
178
|
+
|
|
179
|
+
transition-property: height, width;
|
|
180
|
+
transition-duration: 0.1s;
|
|
181
|
+
transition-timing-function: ease-out;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.horizontal .slider {
|
|
185
|
+
width: 100%;
|
|
186
|
+
height: 5px;
|
|
187
|
+
}
|
|
188
|
+
.horizontal .slider.hover,
|
|
189
|
+
.horizontal .slider:hover {
|
|
190
|
+
height: 7px;
|
|
191
|
+
/* transform: scaleY(var(--scale-factor)); */
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.vertical .slider {
|
|
195
|
+
width: 5px;
|
|
196
|
+
height: 100%;
|
|
197
|
+
align-items: end;
|
|
198
|
+
}
|
|
199
|
+
.vertical .slider.hover,
|
|
200
|
+
.vertical .slider:hover {
|
|
201
|
+
width: 7px;
|
|
202
|
+
/* transform: scaleX(var(--scale-factor)); */
|
|
203
|
+
}
|
|
204
|
+
.slider::after {
|
|
205
|
+
content: '';
|
|
206
|
+
position: absolute;
|
|
207
|
+
top: -7px;
|
|
208
|
+
left: -7px;
|
|
209
|
+
width: calc(100% + 14px);
|
|
210
|
+
height: calc(100% + 14px);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.progress {
|
|
214
|
+
background-color: var(--accent);
|
|
215
|
+
border-radius: 3px;
|
|
216
|
+
z-index: 2;
|
|
217
|
+
}
|
|
218
|
+
.horizontal .progress {
|
|
219
|
+
width: var(--progress);
|
|
220
|
+
height: 100%;
|
|
221
|
+
}
|
|
222
|
+
.vertical .progress {
|
|
223
|
+
width: 100%;
|
|
224
|
+
height: var(--progress);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.track {
|
|
228
|
+
z-index: 3;
|
|
229
|
+
width: 12px;
|
|
230
|
+
height: 12px;
|
|
231
|
+
border-radius: 12.5px;
|
|
232
|
+
background-color: var(--bg-1);
|
|
233
|
+
border: 1px solid var(--stroke);
|
|
234
|
+
/* outline: 2px solid var(--bg-blur); */
|
|
235
|
+
position: absolute;
|
|
236
|
+
transition-property: width, height;
|
|
237
|
+
transition-duration: 0.1s;
|
|
238
|
+
transition-timing-function: ease-out;
|
|
239
|
+
}
|
|
240
|
+
.horizontal .track {
|
|
241
|
+
left: var(--progress);
|
|
242
|
+
top: 50%;
|
|
243
|
+
transform: translate(-50%, -50%);
|
|
244
|
+
}
|
|
245
|
+
.vertical .track {
|
|
246
|
+
bottom: var(--progress);
|
|
247
|
+
left: 50%;
|
|
248
|
+
transform: translate(-50%, 50%);
|
|
249
|
+
}
|
|
250
|
+
.slider-container:has(.slider.hover) .track,
|
|
251
|
+
.slider-container:hover .track {
|
|
252
|
+
width: 16px;
|
|
253
|
+
height: 16px;
|
|
254
|
+
outline: 2px solid var(--bg-blur);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.step {
|
|
258
|
+
background-color: var(--bg-2);
|
|
259
|
+
border-radius: 700px;
|
|
260
|
+
position: absolute;
|
|
261
|
+
z-index: 1;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.horizontal .step {
|
|
265
|
+
width: var(--step-width);
|
|
266
|
+
height: var(--step-height);
|
|
267
|
+
transform: translateX(-50%);
|
|
268
|
+
left: var(--offset);
|
|
269
|
+
}
|
|
270
|
+
.vertical .step {
|
|
271
|
+
width: var(--step-height);
|
|
272
|
+
height: var(--step-width);
|
|
273
|
+
transform: translateY(50%);
|
|
274
|
+
bottom: var(--offset);
|
|
275
|
+
}
|
|
276
|
+
</style>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
<script>
|
|
3
|
+
import Slider from "@hamzus-ui/Slider/Slider.svelte";
|
|
4
|
+
import Exemple from "../../../../components/docComponent/Exemple/Exemple.svelte";
|
|
5
|
+
import DataList from "@hamzus-ui/DataList/DataList.svelte";
|
|
6
|
+
import CopyCode from "@hamzus-ui/CopyCode/CopyCode.svelte";
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<h2>Carte informatif</h2>
|
|
10
|
+
|
|
11
|
+
<h3>Import</h3>
|
|
12
|
+
|
|
13
|
+
<CopyCode label={`import { Slider } from "hamzus-ui"`}></CopyCode>
|
|
14
|
+
|
|
15
|
+
<h3>Exemple</h3>
|
|
16
|
+
|
|
17
|
+
<Exemple code={'<Slider></Slider>'}>
|
|
18
|
+
<div class="exemple">
|
|
19
|
+
<Slider></Slider>
|
|
20
|
+
</div>
|
|
21
|
+
</Exemple>
|
|
22
|
+
|
|
23
|
+
<h3>Minimum/Maximum</h3>
|
|
24
|
+
<Exemple code={'<Slider step={25} displayStep></Slider>'}>
|
|
25
|
+
<div class="exemple">
|
|
26
|
+
<Slider step={25} min={10} max={110} displayStep></Slider>
|
|
27
|
+
</div>
|
|
28
|
+
</Exemple>
|
|
29
|
+
|
|
30
|
+
<h3>Etape</h3>
|
|
31
|
+
<Exemple code={'<Slider step={25} displayStep></Slider>'}>
|
|
32
|
+
<div class="exemple">
|
|
33
|
+
<Slider step={25} displayStep></Slider>
|
|
34
|
+
</div>
|
|
35
|
+
</Exemple>
|
|
36
|
+
|
|
37
|
+
<h3>Orientation (vertical)</h3>
|
|
38
|
+
<Exemple code={'<Slider step={50} displayStep orientation="vertical"></Slider>'}>
|
|
39
|
+
<div class="exemple" style="height: 60px;">
|
|
40
|
+
<Slider step={50} displayStep orientation='vertical'></Slider>
|
|
41
|
+
</div>
|
|
42
|
+
</Exemple>
|
|
43
|
+
|
|
44
|
+
<h3>Step size</h3>
|
|
45
|
+
<Exemple code={'<Slider step={50} stepWidth={8} stepHeight={20} displayStep></Slider>'}>
|
|
46
|
+
<div class="exemple">
|
|
47
|
+
<Slider step={50} stepWidth={8} stepHeight={20} displayStep></Slider>
|
|
48
|
+
</div>
|
|
49
|
+
</Exemple>
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let orientation = 'horizontal';
|
|
3
|
+
export let name = 'slider';
|
|
4
|
+
export let min = 0;
|
|
5
|
+
export let max = 60;
|
|
6
|
+
export let value = 50;
|
|
7
|
+
export let step = 1;
|
|
8
|
+
export let label = 'Al Fatiha';
|
|
9
|
+
|
|
10
|
+
let slider;
|
|
11
|
+
|
|
12
|
+
let isDraging = false;
|
|
13
|
+
|
|
14
|
+
let actualX = null;
|
|
15
|
+
let actualY = null;
|
|
16
|
+
|
|
17
|
+
let startLabel = '';
|
|
18
|
+
let endLabel = '';
|
|
19
|
+
|
|
20
|
+
$: percent = getPercentage(min, max, value);
|
|
21
|
+
|
|
22
|
+
$: {
|
|
23
|
+
startLabel = formatSeconds(value)
|
|
24
|
+
endLabel = '- ' + formatSeconds(max - value)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getPercentage(min, max, value) {
|
|
28
|
+
|
|
29
|
+
let maxFromZero = max - min;
|
|
30
|
+
|
|
31
|
+
let ratio = (value - min) / maxFromZero;
|
|
32
|
+
|
|
33
|
+
return ratio * 100;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function formatSeconds(seconds) {
|
|
37
|
+
const minutes = Math.floor(seconds / 60);
|
|
38
|
+
const secs = Math.floor(seconds % 60);
|
|
39
|
+
return `${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function handleClickDown(event) {
|
|
43
|
+
event.preventDefault()
|
|
44
|
+
isDraging = true;
|
|
45
|
+
|
|
46
|
+
actualX = event.clientX;
|
|
47
|
+
actualY = event.clientY;
|
|
48
|
+
|
|
49
|
+
// calculer la nouvelle valeur en fonction de la position du curseur
|
|
50
|
+
updateValue();
|
|
51
|
+
|
|
52
|
+
document.addEventListener('mousemove', handleUpdateCursorState);
|
|
53
|
+
document.addEventListener('mouseup', handleClickUp);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function handleUpdateCursorState(event) {
|
|
57
|
+
actualX = event.clientX;
|
|
58
|
+
actualY = event.clientY;
|
|
59
|
+
|
|
60
|
+
updateValue();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function handleClickUp() {
|
|
64
|
+
isDraging = false;
|
|
65
|
+
|
|
66
|
+
actualX = null;
|
|
67
|
+
actualY = null;
|
|
68
|
+
|
|
69
|
+
document.removeEventListener('mouseup', handleClickUp);
|
|
70
|
+
document.removeEventListener('mousemove', handleUpdateCursorState);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function updateValue() {
|
|
74
|
+
// mettre a jour la valeur en fonction de la position
|
|
75
|
+
|
|
76
|
+
let sliderSize = slider[orientation === 'horizontal' ? 'offsetWidth' : 'offsetHeight']; // taille du slider
|
|
77
|
+
|
|
78
|
+
let sliderOffset =
|
|
79
|
+
slider.getBoundingClientRect()[orientation === 'horizontal' ? 'left' : 'top']; // position de depart du slider dans la vue
|
|
80
|
+
|
|
81
|
+
let movementRelativeToSlider =
|
|
82
|
+
(orientation === 'horizontal' ? actualX : actualY) - sliderOffset; // mouvement en pixel par rapport a la position de depart du slider
|
|
83
|
+
|
|
84
|
+
let ratioMovement = movementRelativeToSlider / sliderSize;
|
|
85
|
+
|
|
86
|
+
// inverser le ratio car le slider vertical demarre d en bas
|
|
87
|
+
if (orientation === 'vertical') {
|
|
88
|
+
ratioMovement = 1 - ratioMovement;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// convertir le pourcentage en valeur en fonction du min et max
|
|
92
|
+
let maxFromZero = max - min;
|
|
93
|
+
|
|
94
|
+
let newPercentFromZero = ratioMovement * maxFromZero;
|
|
95
|
+
|
|
96
|
+
let newValue = Math.round((newPercentFromZero + min) / step) * step;
|
|
97
|
+
|
|
98
|
+
// si le nouveau pourcentage est plus pres de 100% que le pourcentage de la nouvelleValeur on met a 100 et inversement pour 0
|
|
99
|
+
let newValuePercent = getPercentage(min, max, newValue);
|
|
100
|
+
|
|
101
|
+
if (newValue > max) {
|
|
102
|
+
newValue = max;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (newValue < min) {
|
|
106
|
+
newValue = min;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
value = newValue;
|
|
111
|
+
}
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<div class="slider-container {orientation === 'horizontal' ? 'horizontal' : 'vertical'}">
|
|
115
|
+
<input type="hidden" {name} {value} />
|
|
116
|
+
<div bind:this={slider} on:mousedown={handleClickDown} class="slider {isDraging ? 'hover' : ''}">
|
|
117
|
+
<span class="progress" style="--progress:{percent}%;"></span>
|
|
118
|
+
<!-- <span class="track" style="--progress:{percent}%;"></span> -->
|
|
119
|
+
<h5 class="label">{label}</h5>
|
|
120
|
+
<h5
|
|
121
|
+
class="label top"
|
|
122
|
+
style="mask-image: linear-gradient(to right, black {percent}%, transparent {percent}%);
|
|
123
|
+
-webkit-mask-image: linear-gradient(to right, black {percent}%, transparent {percent}%);"
|
|
124
|
+
>
|
|
125
|
+
{label}
|
|
126
|
+
</h5>
|
|
127
|
+
|
|
128
|
+
<h5 class="start">{startLabel}</h5>
|
|
129
|
+
<h5 class="end">{endLabel}</h5>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
<style>
|
|
134
|
+
.slider-container {
|
|
135
|
+
display: flex;
|
|
136
|
+
position: relative;
|
|
137
|
+
}
|
|
138
|
+
.slider-container.horizontal {
|
|
139
|
+
width: 100%;
|
|
140
|
+
height: 25px;
|
|
141
|
+
align-items: center;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.slider-container.vertical {
|
|
145
|
+
width: 25px;
|
|
146
|
+
height: 100%;
|
|
147
|
+
justify-content: center;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.slider {
|
|
151
|
+
background-color: var(--bg-3);
|
|
152
|
+
display: flex;
|
|
153
|
+
border-radius: var(--radius-m);
|
|
154
|
+
cursor: pointer;
|
|
155
|
+
position: relative;
|
|
156
|
+
overflow: hidden;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.horizontal .slider {
|
|
160
|
+
width: 100%;
|
|
161
|
+
height: calc(25px - 2px);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.vertical .slider {
|
|
165
|
+
width: calc(25px - 2px);
|
|
166
|
+
height: 100%;
|
|
167
|
+
align-items: end;
|
|
168
|
+
}
|
|
169
|
+
.slider::after {
|
|
170
|
+
content: '';
|
|
171
|
+
position: absolute;
|
|
172
|
+
top: -7px;
|
|
173
|
+
left: -7px;
|
|
174
|
+
width: calc(100% + 14px);
|
|
175
|
+
height: calc(100% + 14px);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.progress {
|
|
179
|
+
background-color: var(--accent);
|
|
180
|
+
border-radius: var(--radius-s) var(--radius-xs) var(--radius-xs) var(--radius-s);
|
|
181
|
+
z-index: 2;
|
|
182
|
+
}
|
|
183
|
+
.horizontal .progress {
|
|
184
|
+
width: var(--progress);
|
|
185
|
+
height: 100%;
|
|
186
|
+
}
|
|
187
|
+
.vertical .progress {
|
|
188
|
+
width: 100%;
|
|
189
|
+
height: var(--progress);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.label {
|
|
193
|
+
position: absolute;
|
|
194
|
+
top: 50%;
|
|
195
|
+
left: 50%;
|
|
196
|
+
transform: translate(-50%, -50%);
|
|
197
|
+
z-index: 1;
|
|
198
|
+
color: var(--font-1);
|
|
199
|
+
user-select: none;
|
|
200
|
+
pointer-events: none;
|
|
201
|
+
width: 100%;
|
|
202
|
+
text-align: center;
|
|
203
|
+
}
|
|
204
|
+
.label.top {
|
|
205
|
+
z-index: 2;
|
|
206
|
+
color: var(--white);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.start,
|
|
210
|
+
.end {
|
|
211
|
+
position: absolute;
|
|
212
|
+
z-index:3;
|
|
213
|
+
user-select: none;
|
|
214
|
+
pointer-events: none;
|
|
215
|
+
color:var(--white);
|
|
216
|
+
top: 50%;
|
|
217
|
+
transform: translateY(-50%);
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
.start {
|
|
221
|
+
left: var(--pad-m);
|
|
222
|
+
}
|
|
223
|
+
.end {
|
|
224
|
+
right: var(--pad-m);
|
|
225
|
+
}
|
|
226
|
+
</style>
|