@hyvor/design 1.1.13 → 1.1.15
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/components/Dropdown/Dropdown.svelte +7 -3
- package/dist/components/Dropdown/Dropdown.svelte.d.ts +4 -2
- package/dist/components/Dropdown/DropdownContent.svelte +5 -9
- package/dist/components/Dropdown/DropdownContent.svelte.d.ts +1 -0
- package/dist/components/Dropdown/dropdown.types.d.ts +2 -0
- package/dist/components/Dropdown/dropdown.types.js +1 -0
- package/dist/components/EmojiPicker/EmojiPicker.svelte +70 -0
- package/dist/components/EmojiPicker/EmojiPicker.svelte.d.ts +14 -0
- package/dist/components/EmojiPicker/EmojiSelector.svelte +214 -0
- package/dist/components/EmojiPicker/EmojiSelector.svelte.d.ts +8 -0
- package/dist/components/EmojiPicker/emojidata.d.ts +22 -0
- package/dist/components/EmojiPicker/emojidata.js +31 -0
- package/dist/components/HyvorBar/BarUser.svelte +22 -18
- package/dist/components/HyvorBar/BarUser.svelte.d.ts +2 -0
- package/dist/components/HyvorBar/BarUserPicture.svelte +33 -0
- package/dist/components/HyvorBar/BarUserPicture.svelte.d.ts +18 -0
- package/dist/components/HyvorBar/BarUserPreview.svelte +9 -2
- package/dist/components/HyvorBar/HyvorBar.svelte +44 -11
- package/dist/components/HyvorBar/HyvorBar.svelte.d.ts +11 -1
- package/dist/components/HyvorBar/bar.d.ts +4 -5
- package/dist/components/HyvorBar/bar.js +2 -2
- package/dist/components/IconButton/IconButton.svelte +37 -13
- package/dist/components/IconButton/IconButton.svelte.d.ts +13 -2
- package/dist/components/IconButton/iconButton.types.d.ts +2 -0
- package/dist/components/IconButton/iconButton.types.js +1 -0
- package/dist/components/TextInput/TextInput.svelte +48 -22
- package/dist/components/TextInput/TextInput.svelte.d.ts +11 -0
- package/dist/variables.scss +5 -2
- package/package.json +2 -1
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import DropdownContent from './DropdownContent.svelte';
|
|
4
|
+
import type { DropdownAlign, DropdownPosition } from './dropdown.types.js';
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
show?: boolean;
|
|
7
8
|
width?: number;
|
|
8
9
|
relative?: boolean;
|
|
9
10
|
closeOnOutsideClick?: boolean;
|
|
10
|
-
align?:
|
|
11
|
-
position?:
|
|
11
|
+
align?: DropdownAlign;
|
|
12
|
+
position?: DropdownPosition;
|
|
12
13
|
trigger?: Snippet;
|
|
13
14
|
content?: Snippet;
|
|
15
|
+
contentPadding?: number;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
let {
|
|
@@ -21,7 +23,8 @@
|
|
|
21
23
|
align = 'start',
|
|
22
24
|
position = 'bottom',
|
|
23
25
|
trigger,
|
|
24
|
-
content
|
|
26
|
+
content,
|
|
27
|
+
contentPadding
|
|
25
28
|
}: Props = $props();
|
|
26
29
|
|
|
27
30
|
let triggerEl: HTMLElement | undefined = $state();
|
|
@@ -52,6 +55,7 @@
|
|
|
52
55
|
{position}
|
|
53
56
|
{relative}
|
|
54
57
|
trigger={triggerEl}
|
|
58
|
+
padding={contentPadding}
|
|
55
59
|
>
|
|
56
60
|
{@render content?.()}
|
|
57
61
|
</DropdownContent>
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { DropdownAlign, DropdownPosition } from './dropdown.types.js';
|
|
2
3
|
interface Props {
|
|
3
4
|
show?: boolean;
|
|
4
5
|
width?: number;
|
|
5
6
|
relative?: boolean;
|
|
6
7
|
closeOnOutsideClick?: boolean;
|
|
7
|
-
align?:
|
|
8
|
-
position?:
|
|
8
|
+
align?: DropdownAlign;
|
|
9
|
+
position?: DropdownPosition;
|
|
9
10
|
trigger?: Snippet;
|
|
10
11
|
content?: Snippet;
|
|
12
|
+
contentPadding?: number;
|
|
11
13
|
}
|
|
12
14
|
declare const Dropdown: import("svelte").Component<Props, {}, "show">;
|
|
13
15
|
type Dropdown = ReturnType<typeof Dropdown>;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { run } from 'svelte/legacy';
|
|
3
|
-
|
|
4
2
|
import { onMount } from 'svelte';
|
|
5
3
|
import { clickOutside } from '../directives/clickOutside.js';
|
|
6
4
|
import debounce from '../directives/debounce.js';
|
|
@@ -15,6 +13,7 @@
|
|
|
15
13
|
position: 'left' | 'right' | 'bottom' | 'top';
|
|
16
14
|
trigger: HTMLElement;
|
|
17
15
|
children?: import('svelte').Snippet;
|
|
16
|
+
padding?: number;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
let {
|
|
@@ -25,7 +24,8 @@
|
|
|
25
24
|
align,
|
|
26
25
|
position,
|
|
27
26
|
trigger,
|
|
28
|
-
children
|
|
27
|
+
children,
|
|
28
|
+
padding = 10
|
|
29
29
|
}: Props = $props();
|
|
30
30
|
|
|
31
31
|
let contentWrap: HTMLElement | undefined = $state();
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
position;
|
|
95
95
|
align;
|
|
96
96
|
positionWrap();
|
|
97
|
-
})
|
|
97
|
+
});
|
|
98
98
|
|
|
99
99
|
function debouncedPosition() {
|
|
100
100
|
debounce(positionWrap, 10)();
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
style="width: {width}px"
|
|
143
143
|
transition:slideIn
|
|
144
144
|
>
|
|
145
|
-
<div class="hds-box content">
|
|
145
|
+
<div class="hds-box content" style:padding="{padding}px">
|
|
146
146
|
{@render children?.()}
|
|
147
147
|
</div>
|
|
148
148
|
</div>
|
|
@@ -150,8 +150,4 @@
|
|
|
150
150
|
<style>.content-wrap {
|
|
151
151
|
position: fixed;
|
|
152
152
|
z-index: 1000000;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
.content-wrap > .content {
|
|
156
|
-
padding: 10px;
|
|
157
153
|
}</style>
|
|
@@ -7,6 +7,7 @@ interface Props {
|
|
|
7
7
|
position: 'left' | 'right' | 'bottom' | 'top';
|
|
8
8
|
trigger: HTMLElement;
|
|
9
9
|
children?: import('svelte').Snippet;
|
|
10
|
+
padding?: number;
|
|
10
11
|
}
|
|
11
12
|
declare const DropdownContent: import("svelte").Component<Props, {}, "show">;
|
|
12
13
|
type DropdownContent = ReturnType<typeof DropdownContent>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Dropdown from '../Dropdown/Dropdown.svelte';
|
|
3
|
+
import type { DropdownAlign, DropdownPosition } from '../Dropdown/dropdown.types.js';
|
|
4
|
+
import IconButton from '../IconButton/IconButton.svelte';
|
|
5
|
+
import type { IconButtonColor, IconButtonSize } from '../IconButton/iconButton.types.js';
|
|
6
|
+
import EmojiSelector from './EmojiSelector.svelte';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
emoji?: string;
|
|
10
|
+
iconButtonSize?: IconButtonSize;
|
|
11
|
+
iconButtonColor?: IconButtonColor;
|
|
12
|
+
dropdownAlign?: DropdownAlign;
|
|
13
|
+
dropdownPosition?: DropdownPosition;
|
|
14
|
+
onselect?: (emoji: string | undefined) => void;
|
|
15
|
+
removable?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let show = $state(false);
|
|
19
|
+
|
|
20
|
+
let {
|
|
21
|
+
emoji = $bindable(undefined),
|
|
22
|
+
iconButtonSize = undefined,
|
|
23
|
+
iconButtonColor = undefined,
|
|
24
|
+
dropdownAlign = 'center',
|
|
25
|
+
dropdownPosition = 'bottom',
|
|
26
|
+
onselect = undefined,
|
|
27
|
+
removable = false
|
|
28
|
+
}: Props = $props();
|
|
29
|
+
|
|
30
|
+
function handleOnSelect(e: string | undefined) {
|
|
31
|
+
emoji = e;
|
|
32
|
+
show = false;
|
|
33
|
+
onselect?.(e);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function handleClose() {
|
|
37
|
+
show = false;
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<Dropdown
|
|
42
|
+
bind:show
|
|
43
|
+
align={dropdownAlign}
|
|
44
|
+
position={dropdownPosition}
|
|
45
|
+
width={420}
|
|
46
|
+
contentPadding={0}
|
|
47
|
+
>
|
|
48
|
+
{#snippet trigger()}
|
|
49
|
+
<IconButton size={iconButtonSize} color={iconButtonColor}>
|
|
50
|
+
{#if emoji === undefined}
|
|
51
|
+
<span class="no-emoji">😀</span>
|
|
52
|
+
{:else}
|
|
53
|
+
<span class="emoji">{emoji}</span>
|
|
54
|
+
{/if}
|
|
55
|
+
</IconButton>
|
|
56
|
+
{/snippet}
|
|
57
|
+
{#snippet content()}
|
|
58
|
+
<EmojiSelector onselect={handleOnSelect} onclose={handleClose} {removable} />
|
|
59
|
+
{/snippet}
|
|
60
|
+
</Dropdown>
|
|
61
|
+
|
|
62
|
+
<style>
|
|
63
|
+
.no-emoji {
|
|
64
|
+
filter: grayscale(100%);
|
|
65
|
+
font-size: 18px;
|
|
66
|
+
}
|
|
67
|
+
.emoji {
|
|
68
|
+
font-size: 18px;
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DropdownAlign, DropdownPosition } from '../Dropdown/dropdown.types.js';
|
|
2
|
+
import type { IconButtonColor, IconButtonSize } from '../IconButton/iconButton.types.js';
|
|
3
|
+
interface Props {
|
|
4
|
+
emoji?: string;
|
|
5
|
+
iconButtonSize?: IconButtonSize;
|
|
6
|
+
iconButtonColor?: IconButtonColor;
|
|
7
|
+
dropdownAlign?: DropdownAlign;
|
|
8
|
+
dropdownPosition?: DropdownPosition;
|
|
9
|
+
onselect?: (emoji: string | undefined) => void;
|
|
10
|
+
removable?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const EmojiPicker: import("svelte").Component<Props, {}, "emoji">;
|
|
13
|
+
type EmojiPicker = ReturnType<typeof EmojiPicker>;
|
|
14
|
+
export default EmojiPicker;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount, tick } from 'svelte';
|
|
3
|
+
import { loadEmojis, type CompactEmoji, type EmojiGroup } from './emojidata.js';
|
|
4
|
+
import Loader from '../Loader/Loader.svelte';
|
|
5
|
+
import TextInput from '../TextInput/TextInput.svelte';
|
|
6
|
+
import Button from '../Button/Button.svelte';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
onselect: (emoji: string | undefined) => void;
|
|
10
|
+
onclose: () => void;
|
|
11
|
+
removable: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let { onselect, onclose, removable }: Props = $props();
|
|
15
|
+
|
|
16
|
+
let loading = $state(true);
|
|
17
|
+
let searchInput = $state({} as HTMLInputElement);
|
|
18
|
+
let groupsEl = $state({} as HTMLDivElement);
|
|
19
|
+
|
|
20
|
+
let data: EmojiGroup[] = $state([]);
|
|
21
|
+
let search = $state('');
|
|
22
|
+
|
|
23
|
+
let searchedEmojis: CompactEmoji[] | null = $derived.by(() => {
|
|
24
|
+
let searchVal = search.trim().toLowerCase();
|
|
25
|
+
if (!searchVal) return null;
|
|
26
|
+
|
|
27
|
+
return data
|
|
28
|
+
.flatMap((group) => group.emojis)
|
|
29
|
+
.filter((emoji) => {
|
|
30
|
+
const shortcodes = emoji.shortcodes || [];
|
|
31
|
+
const tags = emoji.tags || [];
|
|
32
|
+
|
|
33
|
+
const searchIn = [emoji.unicode, emoji.annotation, ...shortcodes, ...tags]
|
|
34
|
+
.filter((s) => Boolean(s))
|
|
35
|
+
.map((s) => s.toLowerCase());
|
|
36
|
+
|
|
37
|
+
return searchIn.some((code) => code.includes(searchVal));
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
async function load() {
|
|
42
|
+
data = await loadEmojis();
|
|
43
|
+
loading = false;
|
|
44
|
+
|
|
45
|
+
await tick();
|
|
46
|
+
searchInput?.focus();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function handleSectionButtonClick(group: number) {
|
|
50
|
+
if (!groupsEl) return;
|
|
51
|
+
|
|
52
|
+
const groupEl = groupsEl.querySelector(`.group[data-group="${group}"]`);
|
|
53
|
+
if (groupEl) {
|
|
54
|
+
groupEl.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function handleKeydown(e: KeyboardEvent) {
|
|
59
|
+
if (e.key === 'Escape') {
|
|
60
|
+
onclose();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
onMount(() => {
|
|
65
|
+
load();
|
|
66
|
+
});
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<div class="wrap">
|
|
70
|
+
{#if loading}
|
|
71
|
+
<Loader padding={100} block />
|
|
72
|
+
{:else}
|
|
73
|
+
<div class="header">
|
|
74
|
+
<div class="left">
|
|
75
|
+
{@render SectionButton('☺️', 0)}
|
|
76
|
+
{@render SectionButton('👋', 1)}
|
|
77
|
+
{@render SectionButton('😺', 2)}
|
|
78
|
+
{@render SectionButton('🍕', 3)}
|
|
79
|
+
{@render SectionButton('🗼', 4)}
|
|
80
|
+
{@render SectionButton('⚽', 5)}
|
|
81
|
+
{@render SectionButton('📕', 6)}
|
|
82
|
+
{@render SectionButton('✔️', 7)}
|
|
83
|
+
{@render SectionButton('🇨🇵', 8)}
|
|
84
|
+
</div>
|
|
85
|
+
<div class="right">
|
|
86
|
+
{#if removable}
|
|
87
|
+
<Button size="small" color="input" onclick={() => onselect(undefined)}
|
|
88
|
+
>Remove</Button
|
|
89
|
+
>
|
|
90
|
+
{/if}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
<div class="input">
|
|
94
|
+
<TextInput
|
|
95
|
+
block
|
|
96
|
+
bind:value={search}
|
|
97
|
+
bind:input={searchInput}
|
|
98
|
+
onkeydown={handleKeydown}
|
|
99
|
+
/>
|
|
100
|
+
</div>
|
|
101
|
+
<div class="groups" bind:this={groupsEl}>
|
|
102
|
+
{#if searchedEmojis !== null}
|
|
103
|
+
{#if searchedEmojis.length === 0}
|
|
104
|
+
<div class="no-results">No results found</div>
|
|
105
|
+
{:else}
|
|
106
|
+
<div class="group">
|
|
107
|
+
<div class="name">Search Results</div>
|
|
108
|
+
{@render Emojis(searchedEmojis)}
|
|
109
|
+
</div>
|
|
110
|
+
{/if}
|
|
111
|
+
{:else}
|
|
112
|
+
{#each data as group, i}
|
|
113
|
+
<div class="group" data-group={i}>
|
|
114
|
+
<div class="name">{group.name}</div>
|
|
115
|
+
{@render Emojis(group.emojis)}
|
|
116
|
+
</div>
|
|
117
|
+
{/each}
|
|
118
|
+
{/if}
|
|
119
|
+
</div>
|
|
120
|
+
{/if}
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
{#snippet Emojis(emojis: CompactEmoji[])}
|
|
124
|
+
<div class="emojis">
|
|
125
|
+
{#each emojis as emoji}
|
|
126
|
+
<button class="emoji" onclick={() => onselect(emoji.unicode)}>
|
|
127
|
+
{emoji.unicode}
|
|
128
|
+
</button>
|
|
129
|
+
{/each}
|
|
130
|
+
</div>
|
|
131
|
+
{/snippet}
|
|
132
|
+
|
|
133
|
+
{#snippet SectionButton(icon: string, group: number)}
|
|
134
|
+
<button
|
|
135
|
+
class="section-button"
|
|
136
|
+
data-group={group}
|
|
137
|
+
onclick={() => handleSectionButtonClick(group)}
|
|
138
|
+
>
|
|
139
|
+
{icon}
|
|
140
|
+
</button>
|
|
141
|
+
{/snippet}
|
|
142
|
+
|
|
143
|
+
<style>
|
|
144
|
+
.group {
|
|
145
|
+
display: flex;
|
|
146
|
+
flex-direction: column;
|
|
147
|
+
margin-bottom: 20px;
|
|
148
|
+
}
|
|
149
|
+
.group .name {
|
|
150
|
+
font-weight: 600;
|
|
151
|
+
margin-bottom: 10px;
|
|
152
|
+
}
|
|
153
|
+
.input {
|
|
154
|
+
padding: 0 10px;
|
|
155
|
+
margin: 10px 0;
|
|
156
|
+
}
|
|
157
|
+
.groups {
|
|
158
|
+
padding: 15px;
|
|
159
|
+
padding-top: 5px;
|
|
160
|
+
max-height: 370px;
|
|
161
|
+
overflow-y: auto;
|
|
162
|
+
}
|
|
163
|
+
.wrap {
|
|
164
|
+
}
|
|
165
|
+
.emojis {
|
|
166
|
+
display: flex;
|
|
167
|
+
flex-wrap: wrap;
|
|
168
|
+
}
|
|
169
|
+
.emoji {
|
|
170
|
+
font-size: 22px;
|
|
171
|
+
cursor: pointer;
|
|
172
|
+
transition: transform 0.2s;
|
|
173
|
+
width: 34px;
|
|
174
|
+
height: 34px;
|
|
175
|
+
text-align: center;
|
|
176
|
+
border-radius: 5px;
|
|
177
|
+
}
|
|
178
|
+
.emoji:hover {
|
|
179
|
+
background-color: var(--hover-dark);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.no-results {
|
|
183
|
+
color: var(--text-light);
|
|
184
|
+
font-size: 14px;
|
|
185
|
+
text-align: center;
|
|
186
|
+
padding: 30px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.header {
|
|
190
|
+
padding: 0 15px;
|
|
191
|
+
border-bottom: 1px solid var(--border);
|
|
192
|
+
display: flex;
|
|
193
|
+
align-items: center;
|
|
194
|
+
}
|
|
195
|
+
.header .left {
|
|
196
|
+
flex: 1;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.section-button {
|
|
200
|
+
font-size: 20px;
|
|
201
|
+
padding: 10px 4px;
|
|
202
|
+
cursor: pointer;
|
|
203
|
+
color: var(--text-light);
|
|
204
|
+
filter: grayscale(100%);
|
|
205
|
+
border-bottom: 2px solid transparent;
|
|
206
|
+
transition:
|
|
207
|
+
filter 0.2s,
|
|
208
|
+
border-bottom 0.2s;
|
|
209
|
+
}
|
|
210
|
+
.section-button:hover {
|
|
211
|
+
filter: grayscale(50%);
|
|
212
|
+
border-bottom: 2px solid var(--text-light);
|
|
213
|
+
}
|
|
214
|
+
</style>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
onselect: (emoji: string | undefined) => void;
|
|
3
|
+
onclose: () => void;
|
|
4
|
+
removable: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare const EmojiSelector: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type EmojiSelector = ReturnType<typeof EmojiSelector>;
|
|
8
|
+
export default EmojiSelector;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface CompactEmoji {
|
|
2
|
+
annotation: string;
|
|
3
|
+
group: number;
|
|
4
|
+
hexcode: string;
|
|
5
|
+
order: number;
|
|
6
|
+
shortcodes: string[];
|
|
7
|
+
tags: string[];
|
|
8
|
+
unicode: string;
|
|
9
|
+
skins: {
|
|
10
|
+
annotation: string;
|
|
11
|
+
group: number;
|
|
12
|
+
hexcode: string;
|
|
13
|
+
order: number;
|
|
14
|
+
shortcodes: string[];
|
|
15
|
+
unicode: string;
|
|
16
|
+
}[];
|
|
17
|
+
}
|
|
18
|
+
export interface EmojiGroup {
|
|
19
|
+
name: string;
|
|
20
|
+
emojis: CompactEmoji[];
|
|
21
|
+
}
|
|
22
|
+
export declare function loadEmojis(): Promise<EmojiGroup[]>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// https://emojibase.dev/docs/datasets/#compact-format
|
|
2
|
+
let emojis = [];
|
|
3
|
+
const groups = [
|
|
4
|
+
'Smileys & Emotion',
|
|
5
|
+
'People & Body',
|
|
6
|
+
'Components', // removed
|
|
7
|
+
'Animals & Nature',
|
|
8
|
+
'Food & Drink',
|
|
9
|
+
'Travel & Places',
|
|
10
|
+
'Activities',
|
|
11
|
+
'Objects',
|
|
12
|
+
'Symbols',
|
|
13
|
+
'Flags'
|
|
14
|
+
];
|
|
15
|
+
// check if the emoji is a ZWJ (Zero Width Joiner) sequence
|
|
16
|
+
// when I tested on MacOS, ZWJs were shown as separate emojis
|
|
17
|
+
function isZWJEmoji(emoji) {
|
|
18
|
+
return emoji.includes('\u200D');
|
|
19
|
+
}
|
|
20
|
+
export async function loadEmojis() {
|
|
21
|
+
const data = await import('emojibase-data/en/compact.json');
|
|
22
|
+
const emojiData = data.default;
|
|
23
|
+
emojis = emojiData.filter(emoji => emoji.group !== undefined);
|
|
24
|
+
const groupedEmojis = groups.map(group => ({
|
|
25
|
+
name: group,
|
|
26
|
+
emojis: emojis.filter(emoji => emoji.group === groups.indexOf(group) && !isZWJEmoji(emoji.unicode))
|
|
27
|
+
}));
|
|
28
|
+
// remove components
|
|
29
|
+
groupedEmojis.splice(2, 1);
|
|
30
|
+
return groupedEmojis;
|
|
31
|
+
}
|
|
@@ -3,23 +3,27 @@
|
|
|
3
3
|
import ActionListItem from '../ActionList/ActionListItem.svelte';
|
|
4
4
|
import Dropdown from '../Dropdown/Dropdown.svelte';
|
|
5
5
|
import IconBoxArrowUpRight from '@hyvor/icons/IconBoxArrowUpRight';
|
|
6
|
-
import { barUser } from './bar.js';
|
|
7
6
|
import BarUserPreview from './BarUserPreview.svelte';
|
|
7
|
+
import BarUserPicture from './BarUserPicture.svelte';
|
|
8
8
|
|
|
9
9
|
interface Props {
|
|
10
10
|
instance: string;
|
|
11
|
+
logoutUrl?: string;
|
|
12
|
+
cloud: boolean;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
let {
|
|
15
|
+
let {
|
|
16
|
+
instance,
|
|
17
|
+
logoutUrl = `${instance}/account/logout`,
|
|
18
|
+
cloud,
|
|
19
|
+
}: Props = $props();
|
|
14
20
|
</script>
|
|
15
21
|
|
|
16
22
|
<div class="wrap">
|
|
17
23
|
<Dropdown align="end" width={325}>
|
|
18
24
|
{#snippet trigger()}
|
|
19
25
|
<button class="user-wrap">
|
|
20
|
-
|
|
21
|
-
<img class="user-picture" src={$barUser?.picture_url} alt={$barUser?.name} />
|
|
22
|
-
{/if}
|
|
26
|
+
<BarUserPicture />
|
|
23
27
|
</button>
|
|
24
28
|
{/snippet}
|
|
25
29
|
|
|
@@ -27,15 +31,19 @@
|
|
|
27
31
|
<ActionList>
|
|
28
32
|
<BarUserPreview />
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
{#if cloud}
|
|
35
|
+
<a href="{instance}/account" target="_blank">
|
|
36
|
+
<ActionListItem>
|
|
37
|
+
Manage Account
|
|
38
|
+
{#snippet end()}
|
|
39
|
+
<IconBoxArrowUpRight size={12} />
|
|
40
|
+
{/snippet}
|
|
41
|
+
</ActionListItem>
|
|
42
|
+
</a>
|
|
43
|
+
{/if}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<a href="{logoutUrl}">
|
|
39
47
|
<ActionListItem>Logout</ActionListItem>
|
|
40
48
|
</a>
|
|
41
49
|
</ActionList>
|
|
@@ -65,8 +73,4 @@
|
|
|
65
73
|
.user-wrap:hover {
|
|
66
74
|
box-shadow: 0 0 0 4px var(--input);
|
|
67
75
|
}
|
|
68
|
-
img {
|
|
69
|
-
width: 100%;
|
|
70
|
-
height: 100%;
|
|
71
|
-
}
|
|
72
76
|
</style>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { barUser } from "./bar.js";
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
{#if $barUser}
|
|
7
|
+
{#if $barUser.picture_url}
|
|
8
|
+
<img src={$barUser.picture_url} alt={$barUser.name} />
|
|
9
|
+
{:else}
|
|
10
|
+
<span class="user-placeholder">
|
|
11
|
+
{$barUser.name ? $barUser.name[0].toUpperCase() : '?'}
|
|
12
|
+
</span>
|
|
13
|
+
{/if}
|
|
14
|
+
{/if}
|
|
15
|
+
|
|
16
|
+
<style>
|
|
17
|
+
img {
|
|
18
|
+
width: 30px;
|
|
19
|
+
height: 30px;
|
|
20
|
+
border-radius: 50%;
|
|
21
|
+
}
|
|
22
|
+
.user-placeholder {
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
width: 30px;
|
|
27
|
+
height: 30px;
|
|
28
|
+
border-radius: 50%;
|
|
29
|
+
color: var(--text);
|
|
30
|
+
font-size: 14px;
|
|
31
|
+
background-color: var(--input);
|
|
32
|
+
}
|
|
33
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const BarUserPicture: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type BarUserPicture = InstanceType<typeof BarUserPicture>;
|
|
18
|
+
export default BarUserPicture;
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { barUser } from './bar.js';
|
|
3
|
+
import BarUserPicture from './BarUserPicture.svelte';
|
|
3
4
|
</script>
|
|
4
5
|
|
|
5
6
|
{#if $barUser}
|
|
6
7
|
<div class="preview">
|
|
7
8
|
<div class="left">
|
|
8
|
-
<
|
|
9
|
+
<BarUserPicture />
|
|
9
10
|
</div>
|
|
10
11
|
<div class="right">
|
|
11
|
-
<div class="username"
|
|
12
|
+
<div class="username">
|
|
13
|
+
{#if $barUser.username}
|
|
14
|
+
@{$barUser.username}
|
|
15
|
+
{:else if $barUser.name}
|
|
16
|
+
{$barUser.name}
|
|
17
|
+
{/if}
|
|
18
|
+
</div>
|
|
12
19
|
<div class="email">{$barUser.email}</div>
|
|
13
20
|
</div>
|
|
14
21
|
</div>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { onMount } from 'svelte';
|
|
4
4
|
import BarProducts, { PRODUCTS } from './BarProducts.svelte';
|
|
5
5
|
import BarSupport from './BarSupport.svelte';
|
|
6
|
-
import {
|
|
6
|
+
import { barUser, initBar, setInstanceAndProduct, type BarConfig, type BarUser as BarUserType } from './bar.js';
|
|
7
7
|
import BarUpdates from './BarUpdates.svelte';
|
|
8
8
|
import IconCaretDownFill from '@hyvor/icons/IconCaretDownFill';
|
|
9
9
|
import BarNotice from './Notice/BarNotice.svelte';
|
|
@@ -13,9 +13,31 @@
|
|
|
13
13
|
instance?: string;
|
|
14
14
|
product: string;
|
|
15
15
|
config?: Partial<BarConfig>;
|
|
16
|
+
|
|
17
|
+
// set a custom logo URL
|
|
18
|
+
// defaults to instance + '/api/public/logo/' + product + '.svg'
|
|
19
|
+
// recommended to use this for self-hostable products
|
|
20
|
+
logo?: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Whether it is a HYVOR cloud-hosted product.
|
|
24
|
+
* If false, we will hide some features
|
|
25
|
+
*/
|
|
26
|
+
cloud?: boolean;
|
|
27
|
+
authOverride?: {
|
|
28
|
+
user: BarUserType | null;
|
|
29
|
+
logoutUrl: string;
|
|
30
|
+
}
|
|
16
31
|
}
|
|
17
32
|
|
|
18
|
-
let {
|
|
33
|
+
let {
|
|
34
|
+
instance = 'https://hyvor.com',
|
|
35
|
+
product,
|
|
36
|
+
logo = `${instance}/api/public/logo/${product}.svg`,
|
|
37
|
+
config = {},
|
|
38
|
+
cloud = true,
|
|
39
|
+
authOverride = undefined
|
|
40
|
+
}: Props = $props();
|
|
19
41
|
|
|
20
42
|
let mobileShow = $state(false);
|
|
21
43
|
|
|
@@ -41,7 +63,14 @@
|
|
|
41
63
|
|
|
42
64
|
onMount(() => {
|
|
43
65
|
setInstanceAndProduct(instance, product);
|
|
44
|
-
|
|
66
|
+
|
|
67
|
+
if (cloud) {
|
|
68
|
+
initBar();
|
|
69
|
+
} else {
|
|
70
|
+
if (authOverride) {
|
|
71
|
+
barUser.set(authOverride.user);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
45
74
|
});
|
|
46
75
|
|
|
47
76
|
function getName() {
|
|
@@ -59,7 +88,7 @@
|
|
|
59
88
|
<div class="left">
|
|
60
89
|
<a class="logo" href="/">
|
|
61
90
|
<img
|
|
62
|
-
src={
|
|
91
|
+
src={logo}
|
|
63
92
|
alt={product}
|
|
64
93
|
width="20"
|
|
65
94
|
height="20"
|
|
@@ -74,16 +103,20 @@
|
|
|
74
103
|
<BarNotice {instance} />
|
|
75
104
|
|
|
76
105
|
<div class="hidden-on-mobile">
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
106
|
+
{#if cloud}
|
|
107
|
+
<BarSupport config={configComplete} {product} mobile={mobileShow} />
|
|
108
|
+
<BarProducts {instance} mobile={mobileShow} />
|
|
109
|
+
<BarUpdates {instance} {product} />
|
|
110
|
+
{/if}
|
|
80
111
|
</div>
|
|
81
112
|
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
|
|
113
|
+
{#if cloud}
|
|
114
|
+
<div class="mobile">
|
|
115
|
+
<IconCaretDownFill />
|
|
116
|
+
</div>
|
|
117
|
+
{/if}
|
|
85
118
|
|
|
86
|
-
<BarUser {instance} />
|
|
119
|
+
<BarUser {instance} logoutUrl={authOverride?.logoutUrl} {cloud} />
|
|
87
120
|
</div>
|
|
88
121
|
</div>
|
|
89
122
|
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import { type BarConfig } from './bar.js';
|
|
1
|
+
import { type BarConfig, type BarUser as BarUserType } from './bar.js';
|
|
2
2
|
interface Props {
|
|
3
3
|
instance?: string;
|
|
4
4
|
product: string;
|
|
5
5
|
config?: Partial<BarConfig>;
|
|
6
|
+
logo?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Whether it is a HYVOR cloud-hosted product.
|
|
9
|
+
* If false, we will hide some features
|
|
10
|
+
*/
|
|
11
|
+
cloud?: boolean;
|
|
12
|
+
authOverride?: {
|
|
13
|
+
user: BarUserType | null;
|
|
14
|
+
logoutUrl: string;
|
|
15
|
+
};
|
|
6
16
|
}
|
|
7
17
|
declare const HyvorBar: import("svelte").Component<Props, {}, "">;
|
|
8
18
|
type HyvorBar = ReturnType<typeof HyvorBar>;
|
|
@@ -5,11 +5,11 @@ export interface BarConfig {
|
|
|
5
5
|
chat: boolean;
|
|
6
6
|
g2: string | null;
|
|
7
7
|
}
|
|
8
|
-
interface BarUser {
|
|
8
|
+
export interface BarUser {
|
|
9
9
|
name: string | null;
|
|
10
|
-
username
|
|
10
|
+
username?: string | null;
|
|
11
11
|
email: string;
|
|
12
|
-
picture_url: string;
|
|
12
|
+
picture_url: string | null;
|
|
13
13
|
}
|
|
14
14
|
export interface BarUpdate {
|
|
15
15
|
id: number;
|
|
@@ -34,7 +34,7 @@ export declare const barUnreadUpdates: import("svelte/store").Writable<number>;
|
|
|
34
34
|
export declare const barLicense: import("svelte/store").Writable<BarResolvedLicense | null>;
|
|
35
35
|
export declare const barHasFailedInvoices: import("svelte/store").Writable<boolean>;
|
|
36
36
|
export declare function setInstanceAndProduct(instance_: string, product_: string): void;
|
|
37
|
-
export declare function
|
|
37
|
+
export declare function initBar(): void;
|
|
38
38
|
export declare class UnreadUpdatesTimeLocalStorage {
|
|
39
39
|
static KEY: string;
|
|
40
40
|
static get(): number | null;
|
|
@@ -49,4 +49,3 @@ export declare const bar: {
|
|
|
49
49
|
*/
|
|
50
50
|
reload: () => void;
|
|
51
51
|
};
|
|
52
|
-
export {};
|
|
@@ -9,7 +9,7 @@ export function setInstanceAndProduct(instance_, product_) {
|
|
|
9
9
|
instance = instance_;
|
|
10
10
|
product = product_;
|
|
11
11
|
}
|
|
12
|
-
export function
|
|
12
|
+
export function initBar() {
|
|
13
13
|
const query = new URLSearchParams();
|
|
14
14
|
query.set('product', product);
|
|
15
15
|
const lastUnreadTime = UnreadUpdatesTimeLocalStorage.get();
|
|
@@ -90,6 +90,6 @@ export const bar = {
|
|
|
90
90
|
* This is useful to create after, for example, a user creates a new blog
|
|
91
91
|
*/
|
|
92
92
|
reload: () => {
|
|
93
|
-
|
|
93
|
+
initBar();
|
|
94
94
|
}
|
|
95
95
|
};
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { createBubbler } from 'svelte/legacy';
|
|
3
|
+
import type { IconButtonSize, IconButtonColor } from './iconButton.types.js';
|
|
4
|
+
import { legacyHandlers } from '../../legacy.js';
|
|
3
5
|
|
|
4
6
|
const bubble = createBubbler();
|
|
5
7
|
|
|
6
8
|
interface Props {
|
|
7
|
-
size?:
|
|
8
|
-
|
|
9
|
-
color?: 'accent' | 'gray' | 'input' | 'green' | 'red' | 'blue' | 'orange';
|
|
9
|
+
size?: IconButtonSize;
|
|
10
|
+
color?: IconButtonColor;
|
|
10
11
|
variant?: 'fill' | 'fill-light' | 'outline' | 'outline-fill' | 'invisible';
|
|
11
12
|
as?: 'button' | 'a';
|
|
12
13
|
children?: import('svelte').Snippet;
|
|
13
14
|
[key: string]: any;
|
|
15
|
+
|
|
16
|
+
onkeyup?: (event: KeyboardEvent) => void;
|
|
17
|
+
onkeydown?: (event: KeyboardEvent) => void;
|
|
18
|
+
onkeypress?: (event: KeyboardEvent) => void;
|
|
19
|
+
onfocus?: (event: FocusEvent) => void;
|
|
20
|
+
onblur?: (event: FocusEvent) => void;
|
|
21
|
+
onclick?: (event: MouseEvent) => void;
|
|
22
|
+
onmouseover?: (event: MouseEvent) => void;
|
|
23
|
+
onmouseenter?: (event: MouseEvent) => void;
|
|
24
|
+
onmouseleave?: (event: MouseEvent) => void;
|
|
25
|
+
onchange?: (event: Event) => void;
|
|
14
26
|
}
|
|
15
27
|
|
|
16
28
|
let {
|
|
@@ -19,6 +31,18 @@
|
|
|
19
31
|
variant = 'fill',
|
|
20
32
|
as = 'button',
|
|
21
33
|
children,
|
|
34
|
+
|
|
35
|
+
onkeyup,
|
|
36
|
+
onkeydown,
|
|
37
|
+
onkeypress,
|
|
38
|
+
onfocus,
|
|
39
|
+
onblur,
|
|
40
|
+
onclick,
|
|
41
|
+
onmouseover,
|
|
42
|
+
onmouseenter,
|
|
43
|
+
onmouseleave,
|
|
44
|
+
onchange,
|
|
45
|
+
|
|
22
46
|
...rest
|
|
23
47
|
}: Props = $props();
|
|
24
48
|
|
|
@@ -36,16 +60,16 @@
|
|
|
36
60
|
class="button {color} {variant}"
|
|
37
61
|
style:width={size}
|
|
38
62
|
style:height={size}
|
|
39
|
-
onkeyup={bubble('keyup')}
|
|
40
|
-
onkeydown={bubble('keydown')}
|
|
41
|
-
onkeypress={bubble('keypress')}
|
|
42
|
-
onfocus={bubble('focus')}
|
|
43
|
-
onblur={bubble('blur')}
|
|
44
|
-
onclick={bubble('click')}
|
|
45
|
-
onmouseover={bubble('mouseover')}
|
|
46
|
-
onmouseenter={bubble('mouseenter')}
|
|
47
|
-
onmouseleave={bubble('mouseleave')}
|
|
48
|
-
onchange={bubble('change')}
|
|
63
|
+
onkeyup={legacyHandlers(onkeyup, bubble('keyup'))}
|
|
64
|
+
onkeydown={legacyHandlers(onkeydown, bubble('keydown'))}
|
|
65
|
+
onkeypress={legacyHandlers(onkeypress, bubble('keypress'))}
|
|
66
|
+
onfocus={legacyHandlers(onfocus, bubble('focus'))}
|
|
67
|
+
onblur={legacyHandlers(onblur, bubble('blur'))}
|
|
68
|
+
onclick={legacyHandlers(onclick, bubble('click'))}
|
|
69
|
+
onmouseover={legacyHandlers(onmouseover, bubble('mouseover'))}
|
|
70
|
+
onmouseenter={legacyHandlers(onmouseenter, bubble('mouseenter'))}
|
|
71
|
+
onmouseleave={legacyHandlers(onmouseleave, bubble('mouseleave'))}
|
|
72
|
+
onchange={legacyHandlers(onchange, bubble('change'))}
|
|
49
73
|
role="button"
|
|
50
74
|
tabindex="0"
|
|
51
75
|
{...rest}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
import type { IconButtonSize, IconButtonColor } from './iconButton.types.js';
|
|
1
2
|
interface Props {
|
|
2
|
-
size?:
|
|
3
|
-
color?:
|
|
3
|
+
size?: IconButtonSize;
|
|
4
|
+
color?: IconButtonColor;
|
|
4
5
|
variant?: 'fill' | 'fill-light' | 'outline' | 'outline-fill' | 'invisible';
|
|
5
6
|
as?: 'button' | 'a';
|
|
6
7
|
children?: import('svelte').Snippet;
|
|
7
8
|
[key: string]: any;
|
|
9
|
+
onkeyup?: (event: KeyboardEvent) => void;
|
|
10
|
+
onkeydown?: (event: KeyboardEvent) => void;
|
|
11
|
+
onkeypress?: (event: KeyboardEvent) => void;
|
|
12
|
+
onfocus?: (event: FocusEvent) => void;
|
|
13
|
+
onblur?: (event: FocusEvent) => void;
|
|
14
|
+
onclick?: (event: MouseEvent) => void;
|
|
15
|
+
onmouseover?: (event: MouseEvent) => void;
|
|
16
|
+
onmouseenter?: (event: MouseEvent) => void;
|
|
17
|
+
onmouseleave?: (event: MouseEvent) => void;
|
|
18
|
+
onchange?: (event: Event) => void;
|
|
8
19
|
}
|
|
9
20
|
declare const IconButton: import("svelte").Component<Props, {}, "size">;
|
|
10
21
|
type IconButton = ReturnType<typeof IconButton>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { legacyHandlers } from '../../legacy.js';
|
|
2
3
|
import { createBubbler } from 'svelte/legacy';
|
|
3
4
|
|
|
4
5
|
const bubble = createBubbler();
|
|
@@ -14,6 +15,18 @@
|
|
|
14
15
|
select?: boolean;
|
|
15
16
|
selectInput?: HTMLSelectElement;
|
|
16
17
|
[key: string]: any;
|
|
18
|
+
|
|
19
|
+
onkeyup?: (event: KeyboardEvent) => void;
|
|
20
|
+
onkeydown?: (event: KeyboardEvent) => void;
|
|
21
|
+
onkeypress?: (event: KeyboardEvent) => void;
|
|
22
|
+
onfocus?: (event: FocusEvent) => void;
|
|
23
|
+
onblur?: (event: FocusEvent) => void;
|
|
24
|
+
onclick?: (event: MouseEvent) => void;
|
|
25
|
+
onmouseover?: (event: MouseEvent) => void;
|
|
26
|
+
onmouseenter?: (event: MouseEvent) => void;
|
|
27
|
+
onmouseleave?: (event: MouseEvent) => void;
|
|
28
|
+
onchange?: (event: Event) => void;
|
|
29
|
+
oninput?: (event: InputEvent) => void;
|
|
17
30
|
}
|
|
18
31
|
|
|
19
32
|
let {
|
|
@@ -26,6 +39,19 @@
|
|
|
26
39
|
end,
|
|
27
40
|
select = false,
|
|
28
41
|
selectInput = $bindable({} as HTMLSelectElement),
|
|
42
|
+
|
|
43
|
+
onkeyup,
|
|
44
|
+
onkeydown,
|
|
45
|
+
onkeypress,
|
|
46
|
+
onfocus,
|
|
47
|
+
onblur,
|
|
48
|
+
onclick,
|
|
49
|
+
onmouseover,
|
|
50
|
+
onmouseenter,
|
|
51
|
+
onmouseleave,
|
|
52
|
+
onchange,
|
|
53
|
+
oninput,
|
|
54
|
+
|
|
29
55
|
...rest
|
|
30
56
|
}: Props = $props();
|
|
31
57
|
</script>
|
|
@@ -42,17 +68,17 @@
|
|
|
42
68
|
{...rest}
|
|
43
69
|
bind:value
|
|
44
70
|
bind:this={selectInput}
|
|
45
|
-
onkeyup={bubble('keyup')}
|
|
46
|
-
onkeydown={bubble('keydown')}
|
|
47
|
-
onkeypress={bubble('keypress')}
|
|
48
|
-
onfocus={bubble('focus')}
|
|
49
|
-
onblur={bubble('blur')}
|
|
50
|
-
onclick={bubble('click')}
|
|
51
|
-
onmouseover={bubble('mouseover')}
|
|
52
|
-
onmouseenter={bubble('mouseenter')}
|
|
53
|
-
onmouseleave={bubble('mouseleave')}
|
|
54
|
-
onchange={bubble('change')}
|
|
55
|
-
oninput={bubble('input')}
|
|
71
|
+
onkeyup={legacyHandlers(onkeyup, bubble('keyup'))}
|
|
72
|
+
onkeydown={legacyHandlers(onkeydown, bubble('keydown'))}
|
|
73
|
+
onkeypress={legacyHandlers(onkeypress, bubble('keypress'))}
|
|
74
|
+
onfocus={legacyHandlers(onfocus, bubble('focus'))}
|
|
75
|
+
onblur={legacyHandlers(onblur, bubble('blur'))}
|
|
76
|
+
onclick={legacyHandlers(onclick, bubble('click'))}
|
|
77
|
+
onmouseover={legacyHandlers(onmouseover, bubble('mouseover'))}
|
|
78
|
+
onmouseenter={legacyHandlers(onmouseenter, bubble('mouseenter'))}
|
|
79
|
+
onmouseleave={legacyHandlers(onmouseleave, bubble('mouseleave'))}
|
|
80
|
+
onchange={legacyHandlers(onchange, bubble('change'))}
|
|
81
|
+
oninput={legacyHandlers(oninput, bubble('input'))}
|
|
56
82
|
>
|
|
57
83
|
{@render rest?.children()}
|
|
58
84
|
</select>
|
|
@@ -61,17 +87,17 @@
|
|
|
61
87
|
{...rest}
|
|
62
88
|
bind:value
|
|
63
89
|
bind:this={input}
|
|
64
|
-
onkeyup={bubble('keyup')}
|
|
65
|
-
onkeydown={bubble('keydown')}
|
|
66
|
-
onkeypress={bubble('keypress')}
|
|
67
|
-
onfocus={bubble('focus')}
|
|
68
|
-
onblur={bubble('blur')}
|
|
69
|
-
onclick={bubble('click')}
|
|
70
|
-
onmouseover={bubble('mouseover')}
|
|
71
|
-
onmouseenter={bubble('mouseenter')}
|
|
72
|
-
onmouseleave={bubble('mouseleave')}
|
|
73
|
-
onchange={bubble('change')}
|
|
74
|
-
oninput={bubble('input')}
|
|
90
|
+
onkeyup={legacyHandlers(onkeyup, bubble('keyup'))}
|
|
91
|
+
onkeydown={legacyHandlers(onkeydown, bubble('keydown'))}
|
|
92
|
+
onkeypress={legacyHandlers(onkeypress, bubble('keypress'))}
|
|
93
|
+
onfocus={legacyHandlers(onfocus, bubble('focus'))}
|
|
94
|
+
onblur={legacyHandlers(onblur, bubble('blur'))}
|
|
95
|
+
onclick={legacyHandlers(onclick, bubble('click'))}
|
|
96
|
+
onmouseover={legacyHandlers(onmouseover, bubble('mouseover'))}
|
|
97
|
+
onmouseenter={legacyHandlers(onmouseenter, bubble('mouseenter'))}
|
|
98
|
+
onmouseleave={legacyHandlers(onmouseleave, bubble('mouseleave'))}
|
|
99
|
+
onchange={legacyHandlers(onchange, bubble('change'))}
|
|
100
|
+
oninput={legacyHandlers(oninput, bubble('input'))}
|
|
75
101
|
/>
|
|
76
102
|
{/if}
|
|
77
103
|
|
|
@@ -9,6 +9,17 @@ interface Props {
|
|
|
9
9
|
select?: boolean;
|
|
10
10
|
selectInput?: HTMLSelectElement;
|
|
11
11
|
[key: string]: any;
|
|
12
|
+
onkeyup?: (event: KeyboardEvent) => void;
|
|
13
|
+
onkeydown?: (event: KeyboardEvent) => void;
|
|
14
|
+
onkeypress?: (event: KeyboardEvent) => void;
|
|
15
|
+
onfocus?: (event: FocusEvent) => void;
|
|
16
|
+
onblur?: (event: FocusEvent) => void;
|
|
17
|
+
onclick?: (event: MouseEvent) => void;
|
|
18
|
+
onmouseover?: (event: MouseEvent) => void;
|
|
19
|
+
onmouseenter?: (event: MouseEvent) => void;
|
|
20
|
+
onmouseleave?: (event: MouseEvent) => void;
|
|
21
|
+
onchange?: (event: Event) => void;
|
|
22
|
+
oninput?: (event: InputEvent) => void;
|
|
12
23
|
}
|
|
13
24
|
declare const TextInput: import("svelte").Component<Props, {}, "value" | "input" | "selectInput">;
|
|
14
25
|
type TextInput = ReturnType<typeof TextInput>;
|
package/dist/variables.scss
CHANGED
|
@@ -41,10 +41,13 @@
|
|
|
41
41
|
--gray-dark: #555;
|
|
42
42
|
|
|
43
43
|
--hover: #fafafa;
|
|
44
|
+
--hover-dark: #f0f0f0;
|
|
45
|
+
|
|
44
46
|
--link: #1d85d2;
|
|
45
47
|
|
|
46
48
|
--input: #f3f3f3;
|
|
47
|
-
--input-hover: #ccc;
|
|
49
|
+
--input-hover: #ccc;
|
|
50
|
+
/* checkbox/radio */
|
|
48
51
|
|
|
49
52
|
--box-shadow: 0 0 30px #0000000d;
|
|
50
53
|
--box-shadow-light: 0 0 10px 6px rgba(0, 0, 0, 0.06);
|
|
@@ -76,4 +79,4 @@ $breakpoint-xs: 320px;
|
|
|
76
79
|
$breakpoint-sm: 576px;
|
|
77
80
|
$breakpoint-md: 768px;
|
|
78
81
|
$breakpoint-lg: 992px;
|
|
79
|
-
$breakpoint-xl: 1200px;
|
|
82
|
+
$breakpoint-xl: 1200px;
|
package/package.json
CHANGED
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@fontsource/readex-pro": "^5.0.8",
|
|
51
51
|
"@hyvor/icons": "^1.1.1",
|
|
52
52
|
"deepmerge-ts": "^5.1.0",
|
|
53
|
+
"emojibase-data": "^16.0.3",
|
|
53
54
|
"highlight.js": "^11.9.0",
|
|
54
55
|
"intl-messageformat": "^10.5.11",
|
|
55
56
|
"svelte-awesome-color-picker": "^3.0.4",
|
|
@@ -59,5 +60,5 @@
|
|
|
59
60
|
"publishConfig": {
|
|
60
61
|
"access": "public"
|
|
61
62
|
},
|
|
62
|
-
"version": "1.1.
|
|
63
|
+
"version": "1.1.15"
|
|
63
64
|
}
|