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,48 @@
|
|
|
1
|
+
import { writable } from "svelte/store";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* objet de clé value contenant en clé l'id de la table et en valeur un objet contenant les données de la table
|
|
6
|
+
*/
|
|
7
|
+
export const tableData = writable({})
|
|
8
|
+
|
|
9
|
+
// // exemple
|
|
10
|
+
// const dataTable = {
|
|
11
|
+
// "user_12" : { // table identifiant
|
|
12
|
+
// globalSearch:"",// global search
|
|
13
|
+
// columns : [ //columns list
|
|
14
|
+
// {
|
|
15
|
+
// label:"prénom", // le nom a affiche
|
|
16
|
+
// name:"firstname", // le nom a envoyé a l'api lors du filtre
|
|
17
|
+
// isSearchable:true, // la colonne peut etre filtré
|
|
18
|
+
// searchChoices:[ {value:"active",label:"actif"},{value:"inactive",label:"inactif"}], // la colonne peut etre filtré en fonction de plusieur choix
|
|
19
|
+
// initialWidth : 50, // une width par defaut fournis
|
|
20
|
+
// hidden: false, //est ce que la colonne est caché
|
|
21
|
+
// }
|
|
22
|
+
// ],
|
|
23
|
+
// filters:{
|
|
24
|
+
// firstname:"Hamz"
|
|
25
|
+
// },
|
|
26
|
+
// actions : [//actions list (quand des element sont selectionné)
|
|
27
|
+
// {
|
|
28
|
+
// label:"suprimmer",
|
|
29
|
+
// function:handleDelete
|
|
30
|
+
// }
|
|
31
|
+
// ],
|
|
32
|
+
// rows:[ // the rows of the table
|
|
33
|
+
// {
|
|
34
|
+
// "firstname":"Hamzus"
|
|
35
|
+
// },
|
|
36
|
+
// {
|
|
37
|
+
// "firstname":{
|
|
38
|
+
// component:Tag,
|
|
39
|
+
// props:{
|
|
40
|
+
// label:"Hamzus"
|
|
41
|
+
// }
|
|
42
|
+
// }
|
|
43
|
+
// }
|
|
44
|
+
// ],
|
|
45
|
+
// totalOfRows:0 //number of rows
|
|
46
|
+
// }
|
|
47
|
+
// }
|
|
48
|
+
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let links = [];
|
|
3
|
+
|
|
4
|
+
let activeStyle = 'color:var(--font-u);background-color:var(--bg-2);';
|
|
5
|
+
|
|
6
|
+
import TinyScrollArea from '@hamzus-ui/TinyScrollArea/TinyScrollArea.svelte';
|
|
7
|
+
import Button from '@hamzus-ui/Button/Button.svelte';
|
|
8
|
+
|
|
9
|
+
import { page } from '$app/stores';
|
|
10
|
+
|
|
11
|
+
let activeButton = null;
|
|
12
|
+
|
|
13
|
+
let left = 0;
|
|
14
|
+
let width = 0;
|
|
15
|
+
|
|
16
|
+
$: if (activeButton) {
|
|
17
|
+
// return
|
|
18
|
+
left = activeButton.offsetLeft;
|
|
19
|
+
width = activeButton.offsetWidth;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function handleClick(link) {
|
|
23
|
+
if (link.onClick != undefined) {
|
|
24
|
+
link.onClick(link);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<TinyScrollArea style="display: flex;" proximity={0}>
|
|
30
|
+
<div class="tabs" style="--left:{left}px;--width:{width}px;">
|
|
31
|
+
{#each links as link}
|
|
32
|
+
{#if link.label}
|
|
33
|
+
{#if link.active}
|
|
34
|
+
<div bind:this={activeButton} class="active">
|
|
35
|
+
<Button
|
|
36
|
+
variant="ghost"
|
|
37
|
+
style="flex-shrink:0;{link.active ? activeStyle : ''}"
|
|
38
|
+
label={link.label}
|
|
39
|
+
onClick={() => {
|
|
40
|
+
handleClick(link);
|
|
41
|
+
}}
|
|
42
|
+
></Button>
|
|
43
|
+
</div>
|
|
44
|
+
{:else}
|
|
45
|
+
<Button
|
|
46
|
+
variant="ghost"
|
|
47
|
+
style="flex-shrink:0;{link.active ? activeStyle : ''}"
|
|
48
|
+
label={link.label}
|
|
49
|
+
onClick={() => {
|
|
50
|
+
handleClick(link);
|
|
51
|
+
}}
|
|
52
|
+
></Button>
|
|
53
|
+
{/if}
|
|
54
|
+
<span class="active-line"></span>
|
|
55
|
+
{/if}
|
|
56
|
+
{/each}
|
|
57
|
+
</div>
|
|
58
|
+
</TinyScrollArea>
|
|
59
|
+
|
|
60
|
+
<style>
|
|
61
|
+
.tabs {
|
|
62
|
+
min-width: 100%;
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
justify-content: baseline;
|
|
66
|
+
column-gap: var(--pad-m);
|
|
67
|
+
padding-bottom: var(--pad-m);
|
|
68
|
+
position: relative;
|
|
69
|
+
}
|
|
70
|
+
.active {
|
|
71
|
+
all: unset;
|
|
72
|
+
min-width: max-content;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.active-line {
|
|
76
|
+
position: absolute;
|
|
77
|
+
bottom: 0px;
|
|
78
|
+
left: var(--left);
|
|
79
|
+
width: var(--width);
|
|
80
|
+
height: 1px;
|
|
81
|
+
background-color: var(--accent);
|
|
82
|
+
z-index: 1;
|
|
83
|
+
transition-property: left, width;
|
|
84
|
+
transition-duration: 0.2s;
|
|
85
|
+
transition-timing-function: cubic-bezier(0.17, 0.84, 0.44, 1);
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let links = [];
|
|
3
|
+
|
|
4
|
+
let activeStyle = 'color:var(--font-u);background-color:var(--bg-2);';
|
|
5
|
+
|
|
6
|
+
import TinyScrollArea from '@hamzus-ui/TinyScrollArea/TinyScrollArea.svelte';
|
|
7
|
+
import Button from '@hamzus-ui/Button/Button.svelte';
|
|
8
|
+
|
|
9
|
+
import { page } from '$app/stores';
|
|
10
|
+
|
|
11
|
+
let activeButton = null
|
|
12
|
+
|
|
13
|
+
let left = 0
|
|
14
|
+
let width = 0
|
|
15
|
+
|
|
16
|
+
$: currentPath = $page.url.pathname;
|
|
17
|
+
|
|
18
|
+
$: if (currentPath && activeButton) {
|
|
19
|
+
left = activeButton.offsetLeft
|
|
20
|
+
width = activeButton.offsetWidth
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<TinyScrollArea style="display: flex;" proximity={0}>
|
|
27
|
+
<div class="tabs" style="--left:{left}px;--width:{width}px;">
|
|
28
|
+
{#each links as link}
|
|
29
|
+
{#if link.label}
|
|
30
|
+
{#if currentPath == link.href}
|
|
31
|
+
<div bind:this={activeButton} class="active">
|
|
32
|
+
<Button
|
|
33
|
+
variant="ghost"
|
|
34
|
+
style="flex-shrink:0;{currentPath == link.href ? activeStyle : ''}"
|
|
35
|
+
label={link.label}
|
|
36
|
+
href={link.href}
|
|
37
|
+
></Button>
|
|
38
|
+
</div>
|
|
39
|
+
{:else}
|
|
40
|
+
<Button
|
|
41
|
+
variant="ghost"
|
|
42
|
+
style="flex-shrink:0;{currentPath == link.href ? activeStyle : ''}"
|
|
43
|
+
label={link.label}
|
|
44
|
+
href={link.href}
|
|
45
|
+
></Button>
|
|
46
|
+
{/if}
|
|
47
|
+
<span class="active-line"></span>
|
|
48
|
+
{/if}
|
|
49
|
+
{/each}
|
|
50
|
+
</div>
|
|
51
|
+
</TinyScrollArea>
|
|
52
|
+
|
|
53
|
+
<style>
|
|
54
|
+
.tabs {
|
|
55
|
+
min-width: 100%;
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
justify-content: baseline;
|
|
59
|
+
column-gap: var(--pad-m);
|
|
60
|
+
padding-bottom: var(--pad-m);
|
|
61
|
+
position: relative;
|
|
62
|
+
}
|
|
63
|
+
.active{
|
|
64
|
+
all: unset;
|
|
65
|
+
min-width: max-content;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.active-line{
|
|
69
|
+
position: absolute;
|
|
70
|
+
bottom: 0px;
|
|
71
|
+
left: var(--left);
|
|
72
|
+
width: var(--width);
|
|
73
|
+
height: 1px;
|
|
74
|
+
background-color: var(--accent);
|
|
75
|
+
z-index: 1;
|
|
76
|
+
transition-property: left, width;
|
|
77
|
+
transition-duration: .2s;
|
|
78
|
+
transition-timing-function: cubic-bezier(.17,.84,.44,1);
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export let color= "accent";
|
|
3
|
+
export let icon= null;
|
|
4
|
+
export let label= "";
|
|
5
|
+
export let style= "";
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<tag class="tag h6" style="--tag-color:var(--{color}-b);--font-color:var(--{color});{style}">
|
|
9
|
+
{#if icon}
|
|
10
|
+
{@html icon}
|
|
11
|
+
{/if}
|
|
12
|
+
{#if label}
|
|
13
|
+
<h6>{label}</h6>
|
|
14
|
+
{/if}
|
|
15
|
+
{#if $$slots.default}
|
|
16
|
+
<slot/>
|
|
17
|
+
{/if}
|
|
18
|
+
</tag>
|
|
19
|
+
|
|
20
|
+
<style>
|
|
21
|
+
.tag{
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
padding: var(--pad-xs) var(--pad-s);
|
|
24
|
+
border-radius: var(--radius-m);
|
|
25
|
+
font-weight: 300;
|
|
26
|
+
background-color: var(--tag-color);
|
|
27
|
+
color: var(--font-color);
|
|
28
|
+
align-items: center;
|
|
29
|
+
column-gap: var(--pad-m);
|
|
30
|
+
}
|
|
31
|
+
.tag :global(*){
|
|
32
|
+
color: var(--font-color);
|
|
33
|
+
}
|
|
34
|
+
.tag :global(svg){
|
|
35
|
+
height: 18px;
|
|
36
|
+
width: auto;
|
|
37
|
+
flex-shrink: 0;
|
|
38
|
+
}
|
|
39
|
+
.tag :global(svg *),
|
|
40
|
+
.tag :global(svg path){
|
|
41
|
+
fill: var(--font-color);
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { onDestroy, onMount } from 'svelte';
|
|
3
|
+
|
|
4
|
+
export let style = '';
|
|
5
|
+
export let additionalStyle = '';
|
|
6
|
+
export let className = '';
|
|
7
|
+
export let proximity = 0;
|
|
8
|
+
export let isReverse = false
|
|
9
|
+
|
|
10
|
+
let isVisible = true;
|
|
11
|
+
let lastMove = 0;
|
|
12
|
+
|
|
13
|
+
let focusVerticalTrack = false;
|
|
14
|
+
let focusHorizontalTrack = false;
|
|
15
|
+
|
|
16
|
+
let overflowX = true;
|
|
17
|
+
let overflowY = true;
|
|
18
|
+
|
|
19
|
+
let overflowXY = true;
|
|
20
|
+
|
|
21
|
+
let topTrack = 0;
|
|
22
|
+
let leftTrack = 0;
|
|
23
|
+
|
|
24
|
+
let heightTrack = 0;
|
|
25
|
+
let widthTrack = 0;
|
|
26
|
+
|
|
27
|
+
let scrollContainer;
|
|
28
|
+
let offsetHeight;
|
|
29
|
+
let offsetWidth;
|
|
30
|
+
|
|
31
|
+
let scrollArea;
|
|
32
|
+
let scrollHeight;
|
|
33
|
+
let scrollWidth;
|
|
34
|
+
let startscrollTop;
|
|
35
|
+
let startscrollLeft;
|
|
36
|
+
|
|
37
|
+
let startDragX;
|
|
38
|
+
let startDragY;
|
|
39
|
+
|
|
40
|
+
let mousemoveEvent = null;
|
|
41
|
+
let mouseupEvent = null;
|
|
42
|
+
|
|
43
|
+
onMount(mount);
|
|
44
|
+
|
|
45
|
+
let scrollEvent = null
|
|
46
|
+
|
|
47
|
+
function scrollEventEmmiter() {
|
|
48
|
+
const monEvenement = new CustomEvent("userScroll",{});
|
|
49
|
+
document.dispatchEvent(monEvenement);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function mount() {
|
|
53
|
+
scrollEvent = scrollArea.addEventListener('scroll', scrollEventEmmiter)
|
|
54
|
+
|
|
55
|
+
// calculer la height de la track
|
|
56
|
+
scrollHeight = scrollArea.scrollHeight;
|
|
57
|
+
offsetHeight = scrollContainer.offsetHeight;
|
|
58
|
+
|
|
59
|
+
scrollWidth = scrollArea.scrollWidth;
|
|
60
|
+
offsetWidth = scrollContainer.offsetWidth;
|
|
61
|
+
|
|
62
|
+
const verticalTrackSize = (offsetHeight / scrollHeight) * 100;
|
|
63
|
+
const horizontalTrackSize = (offsetWidth / scrollWidth) * 100;
|
|
64
|
+
|
|
65
|
+
overflowX = scrollWidth != offsetWidth;
|
|
66
|
+
overflowY = scrollHeight != offsetHeight;
|
|
67
|
+
|
|
68
|
+
overflowXY = overflowX && overflowY;
|
|
69
|
+
|
|
70
|
+
heightTrack = verticalTrackSize;
|
|
71
|
+
widthTrack = horizontalTrackSize;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
onDestroy(()=>{
|
|
75
|
+
if (scrollEvent) {
|
|
76
|
+
scrollArea.removeEventListener('scroll', scrollEventEmmiter)
|
|
77
|
+
scrollEvent = null
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
function handleStartScrollVertical(event) {
|
|
82
|
+
startDragX = null;
|
|
83
|
+
startDragY = event.clientY;
|
|
84
|
+
|
|
85
|
+
// verifier sa position relativement a la scroll bar
|
|
86
|
+
let scrollAreaTop = scrollContainer.getBoundingClientRect()[isReverse ? "bottom" : "top"];
|
|
87
|
+
let relativePosFromTop = startDragY - scrollAreaTop;
|
|
88
|
+
let topRatio = relativePosFromTop / scrollContainer.getBoundingClientRect().height;
|
|
89
|
+
|
|
90
|
+
// recuperer en ratio la taille de la demi de la scrolltrack
|
|
91
|
+
let scrollTrackHeightRatio = heightTrack / 100;
|
|
92
|
+
if (isReverse) {
|
|
93
|
+
scrollTrackHeightRatio = - scrollTrackHeightRatio
|
|
94
|
+
}
|
|
95
|
+
scrollArea.scrollTo(
|
|
96
|
+
scrollArea.scrollLeft,
|
|
97
|
+
scrollArea.scrollHeight * (topRatio - scrollTrackHeightRatio / 2)
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// let percentTop = relativePosFromTop / scrollContainer.offsetHeight
|
|
101
|
+
|
|
102
|
+
// let initialProgress = scrollArea.scrollHeight * percentTop
|
|
103
|
+
// console.log(scrollArea.scrollHeight);
|
|
104
|
+
// console.log(initialProgress);
|
|
105
|
+
// scrollArea.scrollTo(scrollArea.scrollLeft, initialProgress)
|
|
106
|
+
|
|
107
|
+
focusVerticalTrack = true;
|
|
108
|
+
|
|
109
|
+
startscrollTop = scrollArea.scrollTop;
|
|
110
|
+
|
|
111
|
+
// calculer le deplacement
|
|
112
|
+
mousemoveEvent = document.addEventListener('mousemove', handleMouseMove);
|
|
113
|
+
|
|
114
|
+
mouseupEvent = document.addEventListener('mouseup', handleStopScroll);
|
|
115
|
+
}
|
|
116
|
+
function handleStartScrollHorizontal(event) {
|
|
117
|
+
startDragX = event.clientX;
|
|
118
|
+
startDragY = null;
|
|
119
|
+
|
|
120
|
+
// verifier sa position relativement a la scroll bar
|
|
121
|
+
let scrollAreaLeft = scrollContainer.getBoundingClientRect().left;
|
|
122
|
+
let relativePosFromLeft = startDragX - scrollAreaLeft;
|
|
123
|
+
let leftRatio = relativePosFromLeft / scrollContainer.getBoundingClientRect().width;
|
|
124
|
+
|
|
125
|
+
// recuperer en ratio la taille de la demi de la scrolltrack
|
|
126
|
+
let scrollTrackWidthRatio = widthTrack / 100;
|
|
127
|
+
|
|
128
|
+
scrollArea.scrollTo(
|
|
129
|
+
scrollArea.scrollWidth * (leftRatio - scrollTrackWidthRatio / 2),
|
|
130
|
+
scrollArea.scrollTop
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
focusHorizontalTrack = true;
|
|
134
|
+
|
|
135
|
+
startscrollLeft = scrollArea.scrollLeft;
|
|
136
|
+
// calculer le deplacement
|
|
137
|
+
mousemoveEvent = document.addEventListener('mousemove', handleMouseMove);
|
|
138
|
+
|
|
139
|
+
mouseupEvent = document.addEventListener('mouseup', handleStopScroll);
|
|
140
|
+
}
|
|
141
|
+
function handleMouseMove(event) {
|
|
142
|
+
// calculer la pose et scroll
|
|
143
|
+
if (startDragX) {
|
|
144
|
+
// scroll horizontal
|
|
145
|
+
const deltaX = event.clientX - startDragX;
|
|
146
|
+
const cursorToScroll = (deltaX / offsetWidth) * scrollWidth;
|
|
147
|
+
scrollArea.scrollTo(startscrollLeft + cursorToScroll, scrollArea.scrollTop);
|
|
148
|
+
} else {
|
|
149
|
+
// scroll vertical
|
|
150
|
+
const deltaY = event.clientY - startDragY;
|
|
151
|
+
const cursorToScroll = (deltaY / offsetHeight) * scrollHeight;
|
|
152
|
+
scrollArea.scrollTo(scrollArea.scrollLeft, startscrollTop + cursorToScroll);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function handleStopScroll(event) {
|
|
157
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
158
|
+
mousemoveEvent = null;
|
|
159
|
+
|
|
160
|
+
document.removeEventListener('mouseup', handleStopScroll);
|
|
161
|
+
mouseupEvent = null;
|
|
162
|
+
|
|
163
|
+
// calculer la pose et scroll
|
|
164
|
+
if (startDragX) {
|
|
165
|
+
// scroll horizontal
|
|
166
|
+
const deltaX = event.clientX - startDragX;
|
|
167
|
+
const cursorToScroll = (deltaX / offsetWidth) * scrollWidth;
|
|
168
|
+
scrollArea.scrollTo(startscrollLeft + cursorToScroll, scrollArea.scrollTop);
|
|
169
|
+
focusHorizontalTrack = false;
|
|
170
|
+
} else {
|
|
171
|
+
// scroll vertical
|
|
172
|
+
const deltaY = event.clientY - startDragY;
|
|
173
|
+
const cursorToScroll = (deltaY / offsetHeight) * scrollHeight;
|
|
174
|
+
scrollArea.scrollTo(scrollArea.scrollLeft, startscrollTop + cursorToScroll);
|
|
175
|
+
focusVerticalTrack = false;
|
|
176
|
+
}
|
|
177
|
+
startDragX = null
|
|
178
|
+
startDragY = null
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function handleScroll() {
|
|
182
|
+
let calcTop = (scrollArea.scrollTop / scrollHeight) * 100;
|
|
183
|
+
leftTrack = (scrollArea.scrollLeft / scrollWidth) * 100;
|
|
184
|
+
|
|
185
|
+
topTrack = isReverse ? -calcTop : calcTop
|
|
186
|
+
|
|
187
|
+
}
|
|
188
|
+
function handleDisplayScrollBar() {
|
|
189
|
+
|
|
190
|
+
if (lastMove + 800 < Date.now()) {
|
|
191
|
+
mount();
|
|
192
|
+
}
|
|
193
|
+
isVisible = true;
|
|
194
|
+
lastMove = Date.now();
|
|
195
|
+
setTimeout(() => {
|
|
196
|
+
if (lastMove + 750 < Date.now()) {
|
|
197
|
+
isVisible = false;
|
|
198
|
+
}
|
|
199
|
+
}, 800);
|
|
200
|
+
}
|
|
201
|
+
</script>
|
|
202
|
+
|
|
203
|
+
<scrollarea-container
|
|
204
|
+
role="scrollbar"
|
|
205
|
+
tabindex="-1"
|
|
206
|
+
bind:this={scrollContainer}
|
|
207
|
+
on:resize={mount}
|
|
208
|
+
class="scrollarea-container"
|
|
209
|
+
{style}
|
|
210
|
+
on:mousemove={handleDisplayScrollBar}
|
|
211
|
+
>
|
|
212
|
+
<scrollarea
|
|
213
|
+
on:scroll={handleScroll}
|
|
214
|
+
bind:this={scrollArea}
|
|
215
|
+
style="{style + additionalStyle}"
|
|
216
|
+
class="scrollarea {className}"
|
|
217
|
+
>
|
|
218
|
+
<slot />
|
|
219
|
+
</scrollarea>
|
|
220
|
+
{#if overflowY && (isVisible || startDragY)}
|
|
221
|
+
<div
|
|
222
|
+
role="button"
|
|
223
|
+
tabindex="-1"
|
|
224
|
+
class="vertical-sb {overflowXY ? 'global-overflow' : ''}"
|
|
225
|
+
on:mousedown|preventDefault={handleStartScrollVertical}
|
|
226
|
+
>
|
|
227
|
+
<span
|
|
228
|
+
class="vertical-track {proximity ? 'proxy' : ''} {focusVerticalTrack ? 'focus' : ''}"
|
|
229
|
+
style="--proximity:{proximity}px;height:{heightTrack}%;{isReverse ? "bottom" : "top"}:{topTrack}%;"
|
|
230
|
+
></span>
|
|
231
|
+
</div>
|
|
232
|
+
{/if}
|
|
233
|
+
{#if overflowX && (isVisible || startDragX)}
|
|
234
|
+
<div
|
|
235
|
+
role="button"
|
|
236
|
+
tabindex="-1"
|
|
237
|
+
class="horizontal-sb {overflowXY ? 'global-overflow' : ''}"
|
|
238
|
+
on:mousedown|preventDefault={handleStartScrollHorizontal}
|
|
239
|
+
>
|
|
240
|
+
<span
|
|
241
|
+
class="horizontal-track {proximity ? 'proxy' : ''} {focusHorizontalTrack ? 'focus' : ''}"
|
|
242
|
+
style="--proximity:{proximity}px;width:{widthTrack}%;left:{leftTrack}%;"
|
|
243
|
+
></span>
|
|
244
|
+
</div>
|
|
245
|
+
{/if}
|
|
246
|
+
{#if overflowXY}
|
|
247
|
+
<div class="overflow-xy-corner"></div>
|
|
248
|
+
{/if}
|
|
249
|
+
</scrollarea-container>
|
|
250
|
+
|
|
251
|
+
<style>
|
|
252
|
+
.scrollarea-container {
|
|
253
|
+
position: relative;
|
|
254
|
+
display: flex;
|
|
255
|
+
overflow: hidden;
|
|
256
|
+
width: 100%;
|
|
257
|
+
height: 100%;
|
|
258
|
+
flex: 1;
|
|
259
|
+
}
|
|
260
|
+
.scrollarea {
|
|
261
|
+
overflow: scroll;
|
|
262
|
+
width: 100%;
|
|
263
|
+
height: 100%;
|
|
264
|
+
flex: 1;
|
|
265
|
+
display: flex;
|
|
266
|
+
flex-direction: column;
|
|
267
|
+
/* Pour Firefox plus ancien */
|
|
268
|
+
overflow: -moz-scrollbars-none;
|
|
269
|
+
/* Pour Internet Explorer et Edge */
|
|
270
|
+
-ms-overflow-style: none;
|
|
271
|
+
scrollbar-width: none;
|
|
272
|
+
padding-bottom: var(--size);
|
|
273
|
+
/* display: contents; */
|
|
274
|
+
}
|
|
275
|
+
.scrollarea::-webkit-scrollbar {
|
|
276
|
+
display: none;
|
|
277
|
+
/* Chrome, Safari, Edge */
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.vertical-sb {
|
|
281
|
+
position: absolute;
|
|
282
|
+
top: 0;
|
|
283
|
+
right: 0;
|
|
284
|
+
height: 100%;
|
|
285
|
+
width: 12px;
|
|
286
|
+
z-index: 10;
|
|
287
|
+
}
|
|
288
|
+
.vertical-sb.global-overflow {
|
|
289
|
+
height: calc(100% - 12px);
|
|
290
|
+
}
|
|
291
|
+
.vertical-track {
|
|
292
|
+
--size: 4px;
|
|
293
|
+
position: absolute;
|
|
294
|
+
right: 0px;
|
|
295
|
+
width: var(--size);
|
|
296
|
+
background-color: rgba(122, 122, 122, 0.336);
|
|
297
|
+
transition: width 0.2s ease-out;
|
|
298
|
+
}
|
|
299
|
+
.vertical-track.proxy::after {
|
|
300
|
+
content: '';
|
|
301
|
+
position: absolute;
|
|
302
|
+
top: 0;
|
|
303
|
+
right: 0;
|
|
304
|
+
width: calc(12px + var(--proximity));
|
|
305
|
+
height: 100%;
|
|
306
|
+
}
|
|
307
|
+
.vertical-track.proxy:hover,
|
|
308
|
+
.vertical-track.proxy.focus {
|
|
309
|
+
width: calc(100% + var(--proximity));
|
|
310
|
+
}
|
|
311
|
+
.horizontal-sb {
|
|
312
|
+
position: absolute;
|
|
313
|
+
bottom: 0;
|
|
314
|
+
left: 0;
|
|
315
|
+
height: 12px;
|
|
316
|
+
width: 100%;
|
|
317
|
+
z-index: 10;
|
|
318
|
+
}
|
|
319
|
+
.horizontal-sb.global-overflow {
|
|
320
|
+
width: calc(100% - 12px);
|
|
321
|
+
}
|
|
322
|
+
.horizontal-track {
|
|
323
|
+
--size: 4px;
|
|
324
|
+
position: absolute;
|
|
325
|
+
bottom: 0;
|
|
326
|
+
height: var(--size);
|
|
327
|
+
background-color: rgba(122, 122, 122, 0.336);
|
|
328
|
+
transition: height 0.2s ease-out;
|
|
329
|
+
}
|
|
330
|
+
.horizontal-track.proxy::after {
|
|
331
|
+
content: '';
|
|
332
|
+
position: absolute;
|
|
333
|
+
bottom: 0;
|
|
334
|
+
right: 0;
|
|
335
|
+
height: calc(12px + var(--proximity));
|
|
336
|
+
width: 100%;
|
|
337
|
+
}
|
|
338
|
+
.horizontal-track.proxy:hover,
|
|
339
|
+
.horizontal-track.proxy.focus {
|
|
340
|
+
height: calc(100% + var(--proximity));
|
|
341
|
+
}
|
|
342
|
+
.overflow-xy-corner {
|
|
343
|
+
position: absolute;
|
|
344
|
+
bottom: 0;
|
|
345
|
+
right: 0;
|
|
346
|
+
width: 12px;
|
|
347
|
+
height: 12px;
|
|
348
|
+
background-color: rgba(143, 143, 143, 0.082);
|
|
349
|
+
}
|
|
350
|
+
</style>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/* font */
|
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Geist:wght@100..900&display=swap');
|
|
3
|
+
/* font */
|
|
4
|
+
:root {
|
|
5
|
+
/* text size */
|
|
6
|
+
--text-1: 70px;
|
|
7
|
+
--text-2: 24px;
|
|
8
|
+
--text-3: 20px;
|
|
9
|
+
--text-4: 16px;
|
|
10
|
+
--text-5: 14px;
|
|
11
|
+
--text-6: 12px;
|
|
12
|
+
--text-p: 16px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.h1, h1 {
|
|
16
|
+
font-size: var(--text-1);
|
|
17
|
+
font-family: 'Geist', 'Inter', sans-serif;
|
|
18
|
+
font-weight: bold;
|
|
19
|
+
color: var(--font-u);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.h2, h2 {
|
|
23
|
+
font-size: var(--text-2);
|
|
24
|
+
line-height: 2rem;
|
|
25
|
+
font-family: 'Geist', 'Inter', sans-serif;
|
|
26
|
+
font-weight: bold;
|
|
27
|
+
color: var(--font-u);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.h3, h3 {
|
|
31
|
+
font-size: var(--text-3);
|
|
32
|
+
line-height: 1.75rem;
|
|
33
|
+
font-family: 'Geist', 'Inter', sans-serif;
|
|
34
|
+
font-weight: bold;
|
|
35
|
+
color: var(--font-u);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.h4, h4 {
|
|
39
|
+
font-size: var(--text-4);
|
|
40
|
+
line-height: 1.5rem;
|
|
41
|
+
font-family: 'Geist', 'Inter', sans-serif;
|
|
42
|
+
font-weight: 500;
|
|
43
|
+
color: var(--font-d);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.h5, h5 {
|
|
47
|
+
font-size: var(--text-5);
|
|
48
|
+
line-height: 1.25rem;
|
|
49
|
+
font-family: 'Geist', 'Inter', sans-serif;
|
|
50
|
+
font-weight: 400;
|
|
51
|
+
color: var(--font-d);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.h6, h6 {
|
|
55
|
+
font-size: var(--text-6);
|
|
56
|
+
line-height: 1rem;
|
|
57
|
+
font-family: 'Geist', 'Inter', sans-serif;
|
|
58
|
+
font-weight: 300;
|
|
59
|
+
color: var(--font-u);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.p, p {
|
|
63
|
+
font-size: var(--text-p);
|
|
64
|
+
font-family: 'Geist', 'Inter', sans-serif;
|
|
65
|
+
font-weight: 300;
|
|
66
|
+
color: var(--font-d);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.mono {
|
|
70
|
+
font-family:"Geist Mono", 'Inter', sans-serif;
|
|
71
|
+
}
|