@hyvor/design 1.1.14 → 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/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
|
+
}
|
|
@@ -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
|
}
|