@streamscloud/kit 0.0.1-1770887346972 → 0.0.1-1770903095775
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/dist/core/utils/compact-number.d.ts +8 -0
- package/dist/core/utils/compact-number.js +35 -0
- package/dist/core/utils/index.d.ts +1 -0
- package/dist/core/utils/index.js +1 -0
- package/dist/core/utils/number-helper.d.ts +0 -1
- package/dist/core/utils/number-helper.js +0 -10
- package/dist/ui/card-actions/card-action-container.d.ts +2 -0
- package/dist/ui/card-actions/card-action-container.js +17 -0
- package/dist/ui/card-actions/cmp.card-action.svelte +28 -0
- package/dist/ui/card-actions/cmp.card-action.svelte.d.ts +10 -0
- package/dist/ui/card-actions/cmp.card-actions.svelte +65 -0
- package/dist/ui/card-actions/cmp.card-actions.svelte.d.ts +9 -0
- package/dist/ui/card-actions/index.d.ts +4 -0
- package/dist/ui/card-actions/index.js +3 -0
- package/dist/ui/card-actions/types.d.ts +9 -0
- package/dist/ui/card-actions/types.js +1 -0
- package/dist/ui/dropdown/cmp.dropdown.svelte +171 -0
- package/dist/ui/dropdown/cmp.dropdown.svelte.d.ts +24 -0
- package/dist/ui/dropdown/dropdown-ignore.d.ts +4 -0
- package/dist/ui/dropdown/dropdown-ignore.js +8 -0
- package/dist/ui/dropdown/index.d.ts +3 -0
- package/dist/ui/dropdown/index.js +2 -0
- package/dist/ui/dynamic-component/cmp.dynamic-component.svelte +5 -0
- package/dist/ui/dynamic-component/cmp.dynamic-component.svelte.d.ts +7 -0
- package/dist/ui/dynamic-component/index.d.ts +2 -0
- package/dist/ui/dynamic-component/index.js +2 -0
- package/dist/ui/dynamic-component/types.svelte.d.ts +11 -0
- package/dist/ui/dynamic-component/types.svelte.js +12 -0
- package/dist/ui/swipe-indicator/cmp.swipe-indicator.svelte +113 -0
- package/dist/ui/swipe-indicator/cmp.swipe-indicator.svelte.d.ts +6 -0
- package/dist/ui/swipe-indicator/index.d.ts +1 -0
- package/dist/ui/swipe-indicator/index.js +1 -0
- package/dist/ui/swipe-indicator/swipe-indicator-localization.d.ts +3 -0
- package/dist/ui/swipe-indicator/swipe-indicator-localization.js +12 -0
- package/package.json +17 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getLocale } from '../../locale';
|
|
2
|
+
const THOUSAND = 1_000;
|
|
3
|
+
const MILLION = 1_000_000;
|
|
4
|
+
const BILLION = 1_000_000_000;
|
|
5
|
+
const TRILLION = 1_000_000_000_000;
|
|
6
|
+
export const compactNumber = (value, options = {}) => {
|
|
7
|
+
const { decimals = 1, trimZeros = true, locale = getLocale() } = options;
|
|
8
|
+
const abs = Math.abs(value);
|
|
9
|
+
const formatter = makeNumberFormatter(locale, decimals, trimZeros);
|
|
10
|
+
if (abs >= TRILLION) {
|
|
11
|
+
return `${formatter.format(value / TRILLION)}${loc.T[locale]}`;
|
|
12
|
+
}
|
|
13
|
+
if (abs >= BILLION) {
|
|
14
|
+
return `${formatter.format(value / BILLION)}${loc.B[locale]}`;
|
|
15
|
+
}
|
|
16
|
+
if (abs >= MILLION) {
|
|
17
|
+
return `${formatter.format(value / MILLION)}${loc.M[locale]}`;
|
|
18
|
+
}
|
|
19
|
+
if (abs >= THOUSAND) {
|
|
20
|
+
return `${formatter.format(value / THOUSAND)}${loc.K[locale]}`;
|
|
21
|
+
}
|
|
22
|
+
return formatter.format(value);
|
|
23
|
+
};
|
|
24
|
+
const makeNumberFormatter = (locale, decimals, trimZeros) => new Intl.NumberFormat(loc.numberLocale[locale], {
|
|
25
|
+
minimumFractionDigits: trimZeros ? 0 : decimals,
|
|
26
|
+
maximumFractionDigits: decimals,
|
|
27
|
+
useGrouping: false
|
|
28
|
+
});
|
|
29
|
+
const loc = {
|
|
30
|
+
K: { en: 'K', no: 'K' },
|
|
31
|
+
M: { en: 'M', no: 'M' },
|
|
32
|
+
B: { en: 'B', no: 'B' },
|
|
33
|
+
T: { en: 'T', no: 'T' },
|
|
34
|
+
numberLocale: { en: 'nb-NO', no: 'nb-NO' }
|
|
35
|
+
};
|
package/dist/core/utils/index.js
CHANGED
|
@@ -15,16 +15,6 @@ export class NumberHelper {
|
|
|
15
15
|
output.unshift(modulo);
|
|
16
16
|
return `${isNegative ? '-' : ''}${output.join(' ')}`;
|
|
17
17
|
};
|
|
18
|
-
static formatCompactNumber = (num, locale) => {
|
|
19
|
-
if (num < 1000) {
|
|
20
|
-
return num.toString();
|
|
21
|
-
}
|
|
22
|
-
return new Intl.NumberFormat(locale, {
|
|
23
|
-
notation: 'compact',
|
|
24
|
-
compactDisplay: 'short',
|
|
25
|
-
maximumFractionDigits: 1
|
|
26
|
-
}).format(num);
|
|
27
|
-
};
|
|
28
18
|
static randomIntFromInterval = (min, max) => {
|
|
29
19
|
// min and max included
|
|
30
20
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const cardActionContainer = (node) => {
|
|
2
|
+
const handleHover = () => {
|
|
3
|
+
node.style.setProperty('--card-actions--opacity', '1');
|
|
4
|
+
};
|
|
5
|
+
const handleHoverOut = () => {
|
|
6
|
+
node.style.setProperty('--card-actions--opacity', '');
|
|
7
|
+
};
|
|
8
|
+
node.addEventListener('mouseenter', handleHover);
|
|
9
|
+
node.addEventListener('mouseleave', handleHoverOut);
|
|
10
|
+
node.style.position = 'relative';
|
|
11
|
+
return {
|
|
12
|
+
destroy() {
|
|
13
|
+
node.removeEventListener('mouseenter', handleHover);
|
|
14
|
+
node.removeEventListener('mouseleave', handleHoverOut);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script lang="ts">import { Icon } from '../icon';
|
|
2
|
+
let { action, on } = $props();
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<button
|
|
6
|
+
type="button"
|
|
7
|
+
class="card-action"
|
|
8
|
+
title={action.title ?? ''}
|
|
9
|
+
onclick={(e) => {
|
|
10
|
+
if (!action.propagateClickEvent) {
|
|
11
|
+
e.stopPropagation();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
action.callback?.();
|
|
15
|
+
on?.click?.();
|
|
16
|
+
}}>
|
|
17
|
+
<Icon src={action.icon} color={action.iconColor ?? 'text'} />
|
|
18
|
+
</button>
|
|
19
|
+
|
|
20
|
+
<style>.card-action {
|
|
21
|
+
--_card-action--padding: var(--card-action--padding, 0.3125em);
|
|
22
|
+
padding: var(--_card-action--padding);
|
|
23
|
+
transition: transform 0.3s;
|
|
24
|
+
line-height: 0;
|
|
25
|
+
}
|
|
26
|
+
.card-action:hover {
|
|
27
|
+
transform: scale(1.2);
|
|
28
|
+
}</style>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script lang="ts">import { Dropdown } from '../dropdown';
|
|
2
|
+
import CardAction from './cmp.card-action.svelte';
|
|
3
|
+
import IconMoreVertical from '@fluentui/svg-icons/icons/more_vertical_20_regular.svg?raw';
|
|
4
|
+
let { actions, dropdownPosition = 'bottom-start' } = $props();
|
|
5
|
+
let toggleDropdown = $state.raw(null);
|
|
6
|
+
let closeDropdown = () => {
|
|
7
|
+
if (toggleDropdown) {
|
|
8
|
+
toggleDropdown(false);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
{#if actions.length}
|
|
14
|
+
<div class="card-actions">
|
|
15
|
+
<Dropdown position={dropdownPosition} on={{ mounted: (v) => (toggleDropdown = v.toggleOpen) }}>
|
|
16
|
+
{#snippet trigger()}
|
|
17
|
+
<CardAction action={{ icon: IconMoreVertical, propagateClickEvent: true }} />
|
|
18
|
+
{/snippet}
|
|
19
|
+
|
|
20
|
+
<div class="card-actions__dropdown-content">
|
|
21
|
+
{#each actions as action (action)}
|
|
22
|
+
<CardAction action={action} on={{ click: closeDropdown }} />
|
|
23
|
+
{/each}
|
|
24
|
+
</div>
|
|
25
|
+
</Dropdown>
|
|
26
|
+
</div>
|
|
27
|
+
{/if}
|
|
28
|
+
|
|
29
|
+
<style>.card-actions {
|
|
30
|
+
--_card-actions--background: var(--card-actions--background, light-dark(#f9fafb, #111827));
|
|
31
|
+
--_card-actions--border-radius: var(--card-actions--border-radius, 0.1875em);
|
|
32
|
+
--_card-actions--dropdown-background: var(--card-actions--dropdown-background, var(--_card-actions--background));
|
|
33
|
+
--_card-actions--font-size: var(--card-actions--font-size, 1rem);
|
|
34
|
+
--_card-actions--left-offset: var(--card-actions--left-offset, 0.3125em);
|
|
35
|
+
--_card-actions--opacity: var(--card-actions--opacity, 0);
|
|
36
|
+
--_card-actions--right-offset: var(--card-actions--right-offset, auto);
|
|
37
|
+
--_card-actions--top-offset: var(--card-actions--top-offset, 0.3125em);
|
|
38
|
+
position: absolute;
|
|
39
|
+
top: var(--_card-actions--top-offset);
|
|
40
|
+
right: var(--_card-actions--right-offset);
|
|
41
|
+
left: var(--_card-actions--left-offset);
|
|
42
|
+
--icon--stroke-width: 0.3;
|
|
43
|
+
font-size: var(--_card-actions--font-size);
|
|
44
|
+
opacity: var(--_card-actions--opacity);
|
|
45
|
+
transition: opacity ease-in-out 0.4s;
|
|
46
|
+
display: flex;
|
|
47
|
+
background: var(--_card-actions--background);
|
|
48
|
+
border-radius: var(--_card-actions--border-radius);
|
|
49
|
+
}
|
|
50
|
+
.card-actions__dropdown-content {
|
|
51
|
+
padding: 0 0.3125em;
|
|
52
|
+
background: var(--_card-actions--dropdown-background);
|
|
53
|
+
}
|
|
54
|
+
@media (any-hover: none) {
|
|
55
|
+
.card-actions {
|
|
56
|
+
opacity: 1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:global(.card-actions-container) {
|
|
61
|
+
position: relative;
|
|
62
|
+
}
|
|
63
|
+
:global(.card-actions-container):hover .card-actions {
|
|
64
|
+
opacity: 1;
|
|
65
|
+
}</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type DropdownPosition } from '../dropdown';
|
|
2
|
+
import type { CardActionModel } from './types';
|
|
3
|
+
type Props = {
|
|
4
|
+
actions: CardActionModel[];
|
|
5
|
+
dropdownPosition?: DropdownPosition;
|
|
6
|
+
};
|
|
7
|
+
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type Cmp = ReturnType<typeof Cmp>;
|
|
9
|
+
export default Cmp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<script lang="ts">import { Icon } from '../icon';
|
|
2
|
+
import { isIgnored } from './dropdown-ignore';
|
|
3
|
+
import IconChevronDown from '@fluentui/svg-icons/icons/chevron_down_20_regular.svg?raw';
|
|
4
|
+
import { createPopper } from '@popperjs/core';
|
|
5
|
+
import { untrack } from 'svelte';
|
|
6
|
+
let { position = 'bottom-start', disabled = false, keepDropdownOpen = false, fixedPosition = false, offset = 8, boundaryMargin = 8, backdrop = false, isOpenRequested, on, children, trigger } = $props();
|
|
7
|
+
let opened = $state(false);
|
|
8
|
+
$effect(() => untrack(() => {
|
|
9
|
+
on?.mounted?.({
|
|
10
|
+
toggleOpen: (value) => {
|
|
11
|
+
if (value === undefined) {
|
|
12
|
+
if (opened) {
|
|
13
|
+
close();
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
open();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else if (value) {
|
|
20
|
+
open();
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
close();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}));
|
|
28
|
+
$effect(() => {
|
|
29
|
+
if (opened) {
|
|
30
|
+
on?.opened?.();
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
on?.closed?.();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
$effect(() => untrack(() => {
|
|
37
|
+
if (isOpenRequested) {
|
|
38
|
+
open();
|
|
39
|
+
}
|
|
40
|
+
}));
|
|
41
|
+
$effect(() => {
|
|
42
|
+
return () => {
|
|
43
|
+
window.removeEventListener('click', close);
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
const open = () => {
|
|
47
|
+
opened = true;
|
|
48
|
+
window.addEventListener('click', close);
|
|
49
|
+
};
|
|
50
|
+
const close = () => {
|
|
51
|
+
opened = false;
|
|
52
|
+
window.removeEventListener('click', close);
|
|
53
|
+
};
|
|
54
|
+
const handleClick = (event) => {
|
|
55
|
+
event.stopPropagation();
|
|
56
|
+
if (disabled) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (!opened) {
|
|
60
|
+
open();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (canClose(event.target, event.currentTarget)) {
|
|
64
|
+
close();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const canClose = (target, container) => {
|
|
68
|
+
if (keepDropdownOpen) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
let node = target;
|
|
72
|
+
while (node && node !== container) {
|
|
73
|
+
if (isIgnored(node)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
node = node.parentElement;
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
};
|
|
80
|
+
const initPopper = (node) => {
|
|
81
|
+
const triggerEl = node.previousElementSibling;
|
|
82
|
+
const popper = createPopper(triggerEl, node, {
|
|
83
|
+
placement: position,
|
|
84
|
+
strategy: fixedPosition ? 'fixed' : 'absolute',
|
|
85
|
+
modifiers: [
|
|
86
|
+
{
|
|
87
|
+
name: 'offset',
|
|
88
|
+
options: {
|
|
89
|
+
offset: () => [0, offset]
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{ name: 'eventListeners', enabled: true },
|
|
93
|
+
{ name: 'flip' },
|
|
94
|
+
{
|
|
95
|
+
name: 'preventOverflow',
|
|
96
|
+
options: {
|
|
97
|
+
boundary: document.body,
|
|
98
|
+
padding: boundaryMargin
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
destroy() {
|
|
105
|
+
popper.destroy();
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
{#if opened && backdrop}
|
|
112
|
+
<div
|
|
113
|
+
class="dropdown-backdrop"
|
|
114
|
+
onclick={(e) => {
|
|
115
|
+
e.stopPropagation();
|
|
116
|
+
close();
|
|
117
|
+
}}
|
|
118
|
+
onkeydown={() => ({})}
|
|
119
|
+
role="none">
|
|
120
|
+
</div>
|
|
121
|
+
{/if}
|
|
122
|
+
<div class="dropdown" class:dropdown--disabled={disabled} onclick={handleClick} onkeydown={() => ({})} role="none">
|
|
123
|
+
<button type="button" class="dropdown__trigger">
|
|
124
|
+
{#if trigger}
|
|
125
|
+
{@render trigger()}
|
|
126
|
+
{:else}
|
|
127
|
+
<Icon src={IconChevronDown} />
|
|
128
|
+
{/if}
|
|
129
|
+
</button>
|
|
130
|
+
{#if opened}
|
|
131
|
+
<div use:initPopper class="dropdown__content" role="tooltip" tabindex="-1">
|
|
132
|
+
{@render children()}
|
|
133
|
+
</div>
|
|
134
|
+
{/if}
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<style>.dropdown-backdrop {
|
|
138
|
+
position: fixed;
|
|
139
|
+
inset: 0;
|
|
140
|
+
background: light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.1));
|
|
141
|
+
z-index: 998;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.dropdown {
|
|
145
|
+
--_dropdown--width: var(--dropdown--width, auto);
|
|
146
|
+
height: 100%;
|
|
147
|
+
width: var(--_dropdown--width);
|
|
148
|
+
-webkit-user-drag: none;
|
|
149
|
+
user-select: none;
|
|
150
|
+
}
|
|
151
|
+
.dropdown :global([contenteditable]) {
|
|
152
|
+
user-select: text;
|
|
153
|
+
}
|
|
154
|
+
.dropdown__trigger {
|
|
155
|
+
height: 100%;
|
|
156
|
+
width: 100%;
|
|
157
|
+
display: flex;
|
|
158
|
+
align-items: center;
|
|
159
|
+
line-height: 1;
|
|
160
|
+
}
|
|
161
|
+
.dropdown--disabled {
|
|
162
|
+
opacity: 0.5;
|
|
163
|
+
pointer-events: none;
|
|
164
|
+
}
|
|
165
|
+
.dropdown__content {
|
|
166
|
+
width: max-content;
|
|
167
|
+
z-index: 999;
|
|
168
|
+
}
|
|
169
|
+
.dropdown :global([data-popper-escaped]) {
|
|
170
|
+
visibility: hidden !important;
|
|
171
|
+
}</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Placement } from '@popperjs/core';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type Props = {
|
|
4
|
+
position?: Placement;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
keepDropdownOpen?: boolean;
|
|
7
|
+
fixedPosition?: boolean;
|
|
8
|
+
offset?: number;
|
|
9
|
+
boundaryMargin?: number;
|
|
10
|
+
backdrop?: boolean;
|
|
11
|
+
isOpenRequested?: boolean;
|
|
12
|
+
on?: {
|
|
13
|
+
opened?: () => void;
|
|
14
|
+
closed?: () => void;
|
|
15
|
+
mounted?: (callbacks: {
|
|
16
|
+
toggleOpen: (value?: boolean) => void;
|
|
17
|
+
}) => void;
|
|
18
|
+
};
|
|
19
|
+
children: Snippet;
|
|
20
|
+
trigger?: Snippet;
|
|
21
|
+
};
|
|
22
|
+
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
23
|
+
type Cmp = ReturnType<typeof Cmp>;
|
|
24
|
+
export default Cmp;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const IGNORE_ATTRIBUTE = 'dropdownIgnore';
|
|
2
|
+
export const dropdownIgnore = (node, value = true) => {
|
|
3
|
+
node.dataset[IGNORE_ATTRIBUTE] = value.toString();
|
|
4
|
+
return {
|
|
5
|
+
destroy() { }
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export const isIgnored = (node) => node.dataset[IGNORE_ATTRIBUTE] === 'true';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Component } from 'svelte';
|
|
2
|
+
export type DynamicComponentProps<TComponent extends Component> = TComponent extends Component<infer Props> ? Props : never;
|
|
3
|
+
export declare class DynamicComponentModel<TComponent extends Component<any> = Component<any>> {
|
|
4
|
+
component: TComponent;
|
|
5
|
+
props: DynamicComponentProps<TComponent>;
|
|
6
|
+
constructor(init: {
|
|
7
|
+
component: TComponent;
|
|
8
|
+
props: DynamicComponentProps<TComponent>;
|
|
9
|
+
});
|
|
10
|
+
updateProps(props: Partial<DynamicComponentProps<TComponent>>): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
2
|
+
export class DynamicComponentModel {
|
|
3
|
+
component;
|
|
4
|
+
props = $state(null);
|
|
5
|
+
constructor(init) {
|
|
6
|
+
this.component = init.component;
|
|
7
|
+
this.props = init.props;
|
|
8
|
+
}
|
|
9
|
+
updateProps(props) {
|
|
10
|
+
this.props = { ...this.props, ...props };
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script lang="ts">import { Icon } from '../icon';
|
|
2
|
+
import { SwipeIndicatorLocalization } from './swipe-indicator-localization';
|
|
3
|
+
import IconArrowUp from '@fluentui/svg-icons/icons/arrow_up_20_regular.svg?raw';
|
|
4
|
+
let { fadeTimeout = 2000 } = $props();
|
|
5
|
+
const localization = new SwipeIndicatorLocalization();
|
|
6
|
+
let isFaded = $state(false);
|
|
7
|
+
const indicatorMounted = (_) => {
|
|
8
|
+
if (fadeTimeout) {
|
|
9
|
+
const timeout = setTimeout(() => {
|
|
10
|
+
isFaded = true;
|
|
11
|
+
}, fadeTimeout);
|
|
12
|
+
return {
|
|
13
|
+
destroy() {
|
|
14
|
+
clearTimeout(timeout);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<div class="swipe-indicator" class:swipe-indicator--faded={isFaded} use:indicatorMounted>
|
|
22
|
+
<div class="swipe-indicator__icon">
|
|
23
|
+
<Icon src={IconArrowUp} />
|
|
24
|
+
</div>
|
|
25
|
+
<div class="swipe-indicator__text">
|
|
26
|
+
{localization.swipe}
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<style>.swipe-indicator {
|
|
31
|
+
--_swipe-indicator--color: var(--swipe-indicator--color, #ffffff);
|
|
32
|
+
--_swipe-indicator--font-size: var(--swipe-indicator--font-size, 1rem);
|
|
33
|
+
--_swipe-indicator--icon-size: var(--swipe-indicator--icon-size, var(--_swipe-indicator--font-size));
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
position: absolute;
|
|
39
|
+
top: 80%;
|
|
40
|
+
left: 50%;
|
|
41
|
+
transform: translate(-50%, -50%);
|
|
42
|
+
z-index: 10;
|
|
43
|
+
color: var(--_swipe-indicator--color);
|
|
44
|
+
opacity: 1;
|
|
45
|
+
transition: opacity 2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
46
|
+
}
|
|
47
|
+
.swipe-indicator--faded {
|
|
48
|
+
opacity: 0;
|
|
49
|
+
pointer-events: none;
|
|
50
|
+
}
|
|
51
|
+
.swipe-indicator:before {
|
|
52
|
+
content: "";
|
|
53
|
+
position: absolute;
|
|
54
|
+
inset: 0;
|
|
55
|
+
z-index: 0;
|
|
56
|
+
pointer-events: none;
|
|
57
|
+
border-radius: 50%;
|
|
58
|
+
background: #000000;
|
|
59
|
+
filter: blur(12px);
|
|
60
|
+
transform: scale(3);
|
|
61
|
+
}
|
|
62
|
+
.swipe-indicator__icon {
|
|
63
|
+
font-size: var(--_swipe-indicator--icon-size);
|
|
64
|
+
animation: bounce 2.7s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
|
|
65
|
+
will-change: transform;
|
|
66
|
+
z-index: 1;
|
|
67
|
+
}
|
|
68
|
+
.swipe-indicator__text {
|
|
69
|
+
font-size: var(--_swipe-indicator--font-size);
|
|
70
|
+
z-index: 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@keyframes bounce {
|
|
74
|
+
0%, 100% {
|
|
75
|
+
transform: translateY(0);
|
|
76
|
+
}
|
|
77
|
+
10% {
|
|
78
|
+
transform: translateY(-24px);
|
|
79
|
+
}
|
|
80
|
+
18% {
|
|
81
|
+
transform: translateY(0);
|
|
82
|
+
}
|
|
83
|
+
26% {
|
|
84
|
+
transform: translateY(-12px);
|
|
85
|
+
}
|
|
86
|
+
34% {
|
|
87
|
+
transform: translateY(0);
|
|
88
|
+
}
|
|
89
|
+
41% {
|
|
90
|
+
transform: translateY(-8px);
|
|
91
|
+
}
|
|
92
|
+
48% {
|
|
93
|
+
transform: translateY(0);
|
|
94
|
+
}
|
|
95
|
+
54% {
|
|
96
|
+
transform: translateY(-4px);
|
|
97
|
+
}
|
|
98
|
+
60% {
|
|
99
|
+
transform: translateY(0);
|
|
100
|
+
}
|
|
101
|
+
65% {
|
|
102
|
+
transform: translateY(-2px);
|
|
103
|
+
}
|
|
104
|
+
70% {
|
|
105
|
+
transform: translateY(0);
|
|
106
|
+
}
|
|
107
|
+
75% {
|
|
108
|
+
transform: translateY(-1px);
|
|
109
|
+
}
|
|
110
|
+
80% {
|
|
111
|
+
transform: translateY(0);
|
|
112
|
+
}
|
|
113
|
+
}</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as SwipeIndicator } from './cmp.swipe-indicator.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as SwipeIndicator } from './cmp.swipe-indicator.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamscloud/kit",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-1770903095775",
|
|
4
4
|
"author": "StreamsCloud",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -88,10 +88,22 @@
|
|
|
88
88
|
"types": "./dist/ui/button/index.d.ts",
|
|
89
89
|
"svelte": "./dist/ui/button/index.js"
|
|
90
90
|
},
|
|
91
|
+
"./ui/card-actions": {
|
|
92
|
+
"types": "./dist/ui/card-actions/index.d.ts",
|
|
93
|
+
"svelte": "./dist/ui/card-actions/index.js"
|
|
94
|
+
},
|
|
91
95
|
"./ui/dialog": {
|
|
92
96
|
"types": "./dist/ui/dialog/index.d.ts",
|
|
93
97
|
"svelte": "./dist/ui/dialog/index.js"
|
|
94
98
|
},
|
|
99
|
+
"./ui/dynamic-component": {
|
|
100
|
+
"types": "./dist/ui/dynamic-component/index.d.ts",
|
|
101
|
+
"svelte": "./dist/ui/dynamic-component/index.js"
|
|
102
|
+
},
|
|
103
|
+
"./ui/dropdown": {
|
|
104
|
+
"types": "./dist/ui/dropdown/index.d.ts",
|
|
105
|
+
"svelte": "./dist/ui/dropdown/index.js"
|
|
106
|
+
},
|
|
95
107
|
"./ui/icon": {
|
|
96
108
|
"types": "./dist/ui/icon/index.d.ts",
|
|
97
109
|
"svelte": "./dist/ui/icon/index.js"
|
|
@@ -124,6 +136,10 @@
|
|
|
124
136
|
"types": "./dist/ui/seek-bar/index.d.ts",
|
|
125
137
|
"svelte": "./dist/ui/seek-bar/index.js"
|
|
126
138
|
},
|
|
139
|
+
"./ui/swipe-indicator": {
|
|
140
|
+
"types": "./dist/ui/swipe-indicator/index.d.ts",
|
|
141
|
+
"svelte": "./dist/ui/swipe-indicator/index.js"
|
|
142
|
+
},
|
|
127
143
|
"./ui/time-ago": {
|
|
128
144
|
"types": "./dist/ui/time-ago/index.d.ts",
|
|
129
145
|
"svelte": "./dist/ui/time-ago/index.js"
|