Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: replace Svelte with vanilla JS #381

Merged
merged 121 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
3740477
feat: upgrade to svelte v5
nolanlawson Nov 11, 2023
4d6e0cb
fix: svelte v4->v5 bugs
nolanlawson Nov 11, 2023
a70518c
fix: use snippets
nolanlawson Nov 11, 2023
449e42f
Revert "fix: use snippets"
nolanlawson Nov 11, 2023
09539d1
Merge remote-tracking branch 'origin/master' into svelte-5
nolanlawson Nov 12, 2023
8b15439
chore: bump bundlesize
nolanlawson Nov 12, 2023
66f35ab
fix: remove when unmounting
nolanlawson Nov 12, 2023
56da858
fix: coverage
nolanlawson Nov 12, 2023
cccd759
fix: update again
nolanlawson Nov 15, 2023
02c1a20
Revert "Revert "fix: use snippets""
nolanlawson Nov 15, 2023
30215fd
fix: fix snippets
nolanlawson Nov 15, 2023
1ecd040
fix: reduce size using hacks
nolanlawson Nov 15, 2023
08dac46
perf: remove transitions code
nolanlawson Nov 15, 2023
bd0f807
fix: remove more code
nolanlawson Nov 16, 2023
0d09db2
fix: revert hacks for now
nolanlawson Nov 18, 2023
24cfa3a
fix: migrate Picker.js to vanilla
nolanlawson Nov 18, 2023
a21771e
fix: move to tagged template literals
nolanlawson Nov 18, 2023
498a0f8
fix: do bind:this
nolanlawson Nov 18, 2023
ab18d69
fix: finish up dom bindings
nolanlawson Nov 18, 2023
9477fbb
fix: event listeners and bindings
nolanlawson Nov 19, 2023
235470e
fix: beginning of framework
nolanlawson Nov 19, 2023
7ce1a5d
fix: nodes within nodes
nolanlawson Nov 19, 2023
f1b36fb
fix: more progress on framework
nolanlawson Nov 19, 2023
2bc4909
fix: progress
nolanlawson Nov 20, 2023
e530558
fix: standard style
nolanlawson Nov 20, 2023
cba0962
fix: progress
nolanlawson Nov 20, 2023
a75357d
fix: progress
nolanlawson Nov 20, 2023
791d3c1
fix: working
nolanlawson Nov 20, 2023
8069d64
fix: try to improve reactivity
nolanlawson Nov 20, 2023
079bcd3
fix: try to make progress
nolanlawson Nov 20, 2023
59301c0
fix: back to working again
nolanlawson Nov 21, 2023
9318d7e
fix: back to working again
nolanlawson Nov 21, 2023
198f3ca
Revert "fix: back to working again"
nolanlawson Nov 21, 2023
f3fe6c0
fix: progress on avoiding creating new dom
nolanlawson Nov 21, 2023
baf1a47
fix: skip re-renders
nolanlawson Nov 22, 2023
653b16a
fix: more optimizations
nolanlawson Nov 22, 2023
280a1c1
fix: more optimizations
nolanlawson Nov 22, 2023
8572c4b
fix: try to fix infinite loop
nolanlawson Nov 22, 2023
a61a7d4
fix: infinite loop
nolanlawson Nov 23, 2023
5ed4058
perf: minify html literals
nolanlawson Nov 23, 2023
acd2847
perf: dedupe emojiList as snippet
nolanlawson Nov 23, 2023
5be3bcd
fix: remove svelte and reduce bundlesize test
nolanlawson Nov 23, 2023
8ecabec
fix: keyboard shortcuts
nolanlawson Nov 23, 2023
6779cf3
fix: another infinite cycle
nolanlawson Nov 23, 2023
9cfd72d
fix: fix some tests
nolanlawson Nov 23, 2023
5f5e6da
fix: comment
nolanlawson Nov 23, 2023
10839c6
fix: fix bugs at cost of perf
nolanlawson Nov 23, 2023
53f24fa
fix: rendering bug
nolanlawson Nov 23, 2023
d6604b2
fix: nav button and resize observer
nolanlawson Nov 23, 2023
cf19d90
fix: forgot config file
nolanlawson Nov 23, 2023
e657e94
fix: fix more tests
nolanlawson Nov 23, 2023
4d3b4d8
fix: typo
nolanlawson Nov 24, 2023
4729ab2
refactor: refactor
nolanlawson Nov 24, 2023
8c6ffd2
refactor: refactor
nolanlawson Nov 24, 2023
eda1371
refactor: refactor
nolanlawson Nov 24, 2023
54498fd
fix: bundlesize limit
nolanlawson Nov 24, 2023
55d3ba9
refactor: refactor
nolanlawson Nov 26, 2023
6019cc7
refactor: refactor
nolanlawson Nov 26, 2023
4509a6a
perf: avoid structuredClone
nolanlawson Nov 26, 2023
2d10f0e
fix: simplify utils
nolanlawson Nov 26, 2023
16ec554
test: reduce bundlesize limit
nolanlawson Nov 26, 2023
963f9b9
Merge remote-tracking branch 'origin/master' into vanilla-js
nolanlawson Nov 26, 2023
d588593
fix: remove unnecessary change from master
nolanlawson Nov 26, 2023
9dd313e
fix: whoops forgot plugins
nolanlawson Nov 26, 2023
5142eeb
fix: reduce coverage threshold and remove unused code
nolanlawson Nov 26, 2023
5ec1417
fix: coverage
nolanlawson Nov 26, 2023
f17d7b6
fix: coverage
nolanlawson Nov 26, 2023
0df4633
fix: coverage
nolanlawson Nov 26, 2023
a632a89
refactor: simplify framework code
nolanlawson Nov 27, 2023
911c134
Merge remote-tracking branch 'origin/master' into vanilla-js
nolanlawson Dec 9, 2023
7c4939c
fix: fix flash of unstyled emoji
nolanlawson Dec 9, 2023
d45fda7
fix: on destroy remove window.state in dev mode to avoid leaks
nolanlawson Dec 10, 2023
ff0ba32
Merge remote-tracking branch 'origin/master' into vanilla-js
nolanlawson Dec 10, 2023
7ad02d1
Merge remote-tracking branch 'origin/master' into vanilla-js
nolanlawson Dec 10, 2023
92b79cb
fix: simplify html minification logic
nolanlawson Dec 10, 2023
068c310
fix: simplify - remove .dom member
nolanlawson Dec 10, 2023
810eb36
fix: more comments
nolanlawson Dec 10, 2023
1895f1f
fix: simplify children patching logic
nolanlawson Dec 10, 2023
4c07257
fix: comment
nolanlawson Dec 10, 2023
77f565b
fix: unused code
nolanlawson Dec 10, 2023
7b7c03b
fix: simplify further
nolanlawson Dec 10, 2023
8abbd89
fix: polyfill replaceChildren for old safari
nolanlawson Dec 10, 2023
be7e3d4
fix: fix error when calculating zwj filtered emojis
nolanlawson Dec 10, 2023
0fd0211
fix: simplify exposed svelte.js module
nolanlawson Dec 10, 2023
4765163
fix: clarify
nolanlawson Dec 10, 2023
68c7650
docs: update contributing.md
nolanlawson Dec 10, 2023
695be06
refactor: simplify map() impl
nolanlawson Dec 11, 2023
e98c6a0
refactor: simplify placeholder impl
nolanlawson Dec 11, 2023
8db0d43
Merge remote-tracking branch 'origin/master' into vanilla-js
nolanlawson Dec 11, 2023
ef06501
Merge remote-tracking branch 'origin/master' into vanilla-js
nolanlawson Dec 11, 2023
80493d3
refactor: simplify implementation
nolanlawson Dec 11, 2023
5fcb739
fix: use element not node
nolanlawson Dec 11, 2023
ff3bb13
refactor: avoid polymorphism in framework and simplify
nolanlawson Dec 12, 2023
baa696b
refactor: simplify further
nolanlawson Dec 12, 2023
9df6a58
refactor: rename variable
nolanlawson Dec 12, 2023
962ad95
refactor: move dev-only check
nolanlawson Dec 12, 2023
b9f7bfe
refactor: simplify placeholder lookup logic
nolanlawson Dec 12, 2023
8ca786a
refactor: clean up logic a bit
nolanlawson Dec 12, 2023
12615eb
refactor: refactor destroy logic further
nolanlawson Dec 12, 2023
f1ddec2
Merge remote-tracking branch 'origin/master' into vanilla-js
nolanlawson Dec 12, 2023
71511d9
fix: improve coverage on the picker
nolanlawson Dec 16, 2023
b0e9181
fix: improve coverage on framework itself
nolanlawson Dec 16, 2023
ef5e816
fix: more code coverage improvements
nolanlawson Dec 16, 2023
b4c1dfb
fix: 100% code coverage
nolanlawson Dec 16, 2023
18a766e
fix: add more safety checks
nolanlawson Dec 16, 2023
ba02269
docs: add notes on limitations of the framework
nolanlawson Dec 16, 2023
49cadcf
fix: better docs and debuggability
nolanlawson Dec 16, 2023
2477f5b
fix: simplify regexes
nolanlawson Dec 16, 2023
de395de
refactor: simplify code a bit
nolanlawson Dec 16, 2023
d7dcbb4
refactor: better name
nolanlawson Dec 16, 2023
ed57e94
test: add more framework tests
nolanlawson Dec 17, 2023
0efcfc4
fix: fix issue with safari 12
nolanlawson Dec 17, 2023
850c5d4
chore: test commit
nolanlawson Dec 17, 2023
6a15361
fix: fix comment
nolanlawson Dec 17, 2023
79ef4cb
fix: fix comment
nolanlawson Dec 17, 2023
6f5fce3
fix: more comments and code cleanup
nolanlawson Dec 17, 2023
a0d430b
fix: use nodeValue instead of textContent
nolanlawson Dec 17, 2023
b24ca38
fix: improve comment
nolanlawson Dec 17, 2023
472a27b
fix: use queueMicrotask
nolanlawson Dec 17, 2023
ea25409
fix: more lightweight replaceChildren polyfill
nolanlawson Dec 17, 2023
89c4973
test: fix code coverage
nolanlawson Dec 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ dist
/trimEmojiData.js.map
/trimEmojiData.cjs
/trimEmojiData.cjs.map
/svelte.js
/svelte.js.map

/docs-tmp
/ts-tmp
Expand Down
29 changes: 23 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,32 @@ Build the GitHub Pages docs site:

Some explanations of why the code is structured the way it is, in case it's confusing.

### Why is it one big Svelte component?
### Why a custom framework?

When you build Svelte components with `customElement: true`, it makes _each individual component_ into a web component. This can be bad for perf reasons (lots of repetition, [constructible stylesheets](https://wicg.github.io/construct-stylesheets/) aren't a thing yet, event and prop overhead) as well as correctness reasons (e.g. I want an `<li>` inside of a `<ul>`, not a `<custom-element>` with a shadow DOM and the `<li>` inside of it).
It was [a good learning exercise](https://nolanlawson.com/2023/12/02/lets-learn-how-modern-javascript-frameworks-work-by-building-one/), and it reduced the bundle size quite a bit to switch from Svelte to a custom framework. Plus, `emoji-picker-element` no longer needs to keep
up with breaking changes in Svelte or the tools in the Svelte ecosystem (e.g. Rollup and Jest plugins).

So for now: it's one big component.
### What are some of the quirks of the custom framework?

### Why use svelte-preprocess?
The framework mostly gets the job done, but I took a few shortcuts since we didn't need all the possible bells and whistles. Here is a brief description.

Since it's one big component, it's more readable if we split up the HTML/CSS/JS. Plus, we can lint the JS more easily that way. Plus, I like SCSS.
First, all the DOM nodes and update functions for those nodes are kept in-memory via a `WeakMap` where the key is the `state`. There's one `state` per instance of the `Picker.js` Svelte-esque component. So when the instance is GC'ed, everything related to the DOM and update functions should be GC'ed. (The exception is the global `parseCache`, which only contains the clone-able `template` and bindings for each unique `tokens` array, which is unique per `html` tag template literal. These templates/bindings never changes per component instance, so it makes sense to just parse once and cache them forever, in case the `<emoji-picker>` element itself is constantly unmounted and re-created.)

Second, I took a shortcut, which is that all unique (non-`<template>`) DOM nodes and update functions are keyed off of 1) the unique tokens for the tag template literal plus 2) a unique `key` from the `map` function (if it exists). These are only GC'ed when the whole `state` is GC'ed. So in the worst case, every DOM node for every emoji in the picker is kept in memory (e.g. if you click on every tab button), but this seemed like a reasonable tradeoff for simplicity, plus the perf improvement of avoiding re-rendering the same node when it's unchanged (this is especially important if the reactivity system is kind of chatty, and is constantly setting the same arrays over and over – the framework just notices that all the `children` are the same objects and doesn't re-render). This also works because the `map`ed DOM nodes are not highly dynamic.

Third, all refs and event listeners are only bound once – this just happens to work since most of the event listeners are hoisted (delegated) anyway.

Fourth, `map`ped iterations without a single top-level element are unsupported – this makes updating iterations much easier, since I can just use `Element.replaceChildren()` instead of having to keep bookmark comment nodes or something.

Fifth, the reactivity system is really bare-bones and doesn't check for cycles or avoid wasteful re-renderings or anything. So there's a lot of guardrails to avoid setting the same object over and over to avoid infinite cycles or to avoid excessive re-renders.

Sixth, I tried to get fine-grained reactivity working but gave up, so basically the whole top-level `PickerTemplate.js` function is executed over and over again anytime anything changes. So there are guardrails in place to make sure this isn't expensive (e.g. the caching mechanisms described above).

There's also a long tail of things that aren't supported in the HTML parser, like funky characters like `<` and `=` inside of text nodes, which could confuse the parser (so I just don't support them).

Also, it's assumed that we're using some kind of minifier for the HTML tagged template literals – it would be annoying to have to author `PickerTemplate.js` without any whitespace. So the parser doesn't support comments since those are assumed to be stripped out anyway.

That's about it, there are probably bugs in the framework if you tried to use it for something other than `emoji-picker-element`, but that's fine – it only needs to support one component anyway.

### Why are the built JS files at the root of the project?

Expand All @@ -77,4 +94,4 @@ I could also build a `pkg/` directory and copy the `package.json` into it (this

### Why build two separate bundles?

`picker.js` and `database.js` are designed to be independentally `import`-able. The only way to do this correctly with the right behavior from bundlers like Rollup and Webpack is to create two separate files. Otherwise the bundler would not be able to tree-shake `picker` from `database`.
`picker.js` and `database.js` are designed to be independently `import`-able. The only way to do this correctly with the right behavior from bundlers like Rollup and Webpack is to create two separate files. Otherwise the bundler would not be able to tree-shake `picker` from `database`.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -827,17 +827,22 @@ The reason for this is that `Picker` automatically registers itself as a custom

### Within a Svelte project

`emoji-picker-element` is explicitly designed as a custom element, and won't work
as a direct Svelte component. However, if you're already using Svelte 3, then you
can avoid importing Svelte twice by using:
> [!WARNING]
> `emoji-picker-element` is no longer based on Svelte, so importing from `emoji-picker-element/svelte` is now deprecated.

Previously, `emoji-picker-element` was based on Svelte v3/v4, and you could do:

```js
import Picker from 'emoji-picker-element/svelte';
```

`svelte.js` is the same as `picker.js`, except it `import`s Svelte rather than bundling it.
The goal was to slightly reduce the bundle size by sharing common `svelte` imports.

This is still supported for backwards compatibility, but it is deprecated and just re-exports the Picker. Instead, do:

While this option can reduce your bundle size, note that it only works with compatible Svelte versions. Currently Svelte v3 and v4 are supported.
```js
import Picker from 'emoji-picker-element/picker';
```

## Data and offline

Expand Down
4 changes: 2 additions & 2 deletions bin/bundlesize.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { promisify } from 'node:util'
import prettyBytes from 'pretty-bytes'
import fs from 'node:fs/promises'

const MAX_SIZE_MIN = '42.7 kB'
const MAX_SIZE_MINGZ = '15 kB'
const MAX_SIZE_MIN = '37 kB'
const MAX_SIZE_MINGZ = '13 kB'

const FILENAME = './bundle.js'

Expand Down
9 changes: 9 additions & 0 deletions config/minifyHtmlInJest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { minifyHTMLLiterals } from 'minify-html-literals'

export default {
processAsync (source, fileName) {
return minifyHTMLLiterals(source, {
fileName
})
}
}
5 changes: 0 additions & 5 deletions config/svelte.config.js

This file was deleted.

16 changes: 2 additions & 14 deletions jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,9 @@ module.exports = {
'<rootDir>/test/spec/**/*.{spec,test}.{js,jsx,ts,tsx}'
],
transform: {
'^.+\\.svelte$': ['svelte-jester', {
preprocess: './config/svelte.config.js',
compilerOptions: {
dev: false
}
}]
'^.*PickerTemplate.js$': './config/minifyHtmlInJest.js'
},
moduleFileExtensions: ['js', 'svelte'],
extensionsToTreatAsEsm: ['.svelte'],
moduleFileExtensions: ['js'],
testPathIgnorePatterns: ['node_modules'],
bail: true,
verbose: true,
Expand All @@ -31,12 +25,6 @@ module.exports = {
branches: 100,
functions: 100,
lines: 100
},
'./src/picker/components/Picker/Picker.svelte': {
statements: 90,
branches: 85,
functions: 90,
lines: 90
}
}
}
12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@
"custom",
"element",
"web",
"component",
"svelte"
"component"
],
"author": "Nolan Lawson <[email protected]>",
"license": "Apache-2.0",
Expand Down Expand Up @@ -101,17 +100,16 @@
"jest-environment-jsdom": "^29.7.0",
"lint-staged": "^15.2.0",
"lodash-es": "^4.17.15",
"magic-string": "^0.30.5",
"markdown-table": "^3.0.2",
"markdown-toc": "^1.2.0",
"minify-html-literals": "^1.3.5",
"npm-run-all": "^4.1.5",
"playwright": "^1.40.1",
"pretty-bytes": "^6.1.1",
"puppeteer": "^21.6.0",
"recursive-readdir": "^2.2.3",
"rollup": "^4.7.0",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-svelte": "^7.1.6",
"rollup-plugin-terser": "^7.0.2",
"sass": "^1.69.5",
"shx": "^0.3.4",
Expand All @@ -120,9 +118,6 @@
"stylelint": "^15.11.0",
"stylelint-config-recommended-scss": "^13.1.0",
"stylelint-scss": "^5.3.1",
"svelte": "^4.2.8",
"svelte-jester": "^3.0.0",
"svelte-preprocess": "^5.1.1",
"svgo": "^3.0.5",
"tachometer": "^0.7.0",
"terser": "^5.26.0"
Expand Down Expand Up @@ -151,11 +146,14 @@
"Event",
"fetch",
"getComputedStyle",
"Element",
"indexedDB",
"IDBKeyRange",
"Headers",
"HTMLElement",
"matchMedia",
"Node",
"NodeFilter",
"performance",
"ResizeObserver",
"Response",
Expand Down
97 changes: 15 additions & 82 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,14 @@
import MagicString from 'magic-string'
import inject from '@rollup/plugin-inject'
import cjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import replace from '@rollup/plugin-replace'
import strip from '@rollup/plugin-strip'
import svelte from 'rollup-plugin-svelte'
import preprocess from 'svelte-preprocess'
import analyze from 'rollup-plugin-analyzer'
import { buildStyles } from './bin/buildStyles.js'
import { minifyHTMLLiterals } from 'minify-html-literals'

const { NODE_ENV, DEBUG } = process.env
const dev = NODE_ENV !== 'production'

const preprocessConfig = preprocess()

const origMarkup = preprocessConfig.markup
// minify the HTML by removing extra whitespace
// TODO: this is fragile, but it also results in a lot of bundlesize savings. let's find a better solution
preprocessConfig.markup = async function () {
const res = await origMarkup.apply(this, arguments)

// remove whitespace
res.code = res.code.replace(/([>}])\s+([<{])/sg, '$1$2')

return res
}

// Build Database.test.js and Picker.js as separate modules at build times so that they are properly tree-shakeable.
// Most of this has to happen because customElements.define() has side effects
const baseConfig = {
Expand All @@ -43,25 +26,18 @@ const baseConfig = {
delimiters: ['', ''],
preventAssignment: true
}),
svelte({
compilerOptions: {
dev,
discloseVersion: false
},
preprocess: preprocessConfig
}),
// make the svelte output slightly smaller
replace({
'options.anchor': 'undefined',
'options.context': 'undefined',
'options.customElement': 'undefined',
'options.hydrate': 'undefined',
'options.intro': 'undefined',
delimiters: ['', ''],
preventAssignment: true
}),
{
name: 'minify-html-in-tag-template-literals',
transform (content, id) {
if (id.includes('PickerTemplate.js')) {
return minifyHTMLLiterals(content, {
fileName: id
})
}
}
},
strip({
include: ['**/*.js', '**/*.svelte'],
include: ['**/*.js'],
functions: [
(!dev && !process.env.PERF) && 'performance.*',
!dev && 'console.log'
Expand All @@ -78,18 +54,7 @@ const baseConfig = {
const entryPoints = [
{
input: './src/picker/PickerElement.js',
output: './picker.js',
plugins: [
// Replace newer syntax in Svelte v4 to avoid breaking iOS <13.4
// https://github.com/nolanlawson/emoji-picker-element/pull/379
replace({
'array_like_or_iterator?.length': 'array_like_or_iterator && array_like_or_iterator.length',
'$$ = undefined;': '', // not necessary to initialize class prop to undefined
'$$set = undefined;': '', // not necessary to initialize class prop to undefined
delimiters: ['', ''],
preventAssignment: true
})
]
output: './picker.js'
},
{
input: './src/database/Database.js',
Expand All @@ -103,42 +68,10 @@ const entryPoints = [
input: './src/trimEmojiData.js',
output: './trimEmojiData.cjs',
format: 'cjs'
},
{
input: './src/picker/PickerElement.js',
output: './svelte.js',
external: ['svelte', 'svelte/internal'],
// TODO: drop Svelte v3 support
// ensure_array_like was added in Svelte v4 - we shim it to avoid breaking Svelte v3 users
plugins: [
{
name: 'svelte-v3-compat',
transform (source) {
const magicString = new MagicString(source)
magicString.replaceAll('ensure_array_like(', 'ensure_array_like_shim(')

return {
code: magicString.toString(),
map: magicString.generateMap()
}
}
},
inject({
ensure_array_like_shim: [
'../../../../shims/svelte-v3-shim.js',
'ensure_array_like_shim'
]
})
],
onwarn (warning) {
if (!warning.message.includes('ensure_array_like')) { // intentionally ignore warning for unused import
console.warn(warning.message)
}
}
}
]

export default entryPoints.map(({ input, output, format = 'es', external = [], plugins = [], onwarn }) => {
export default entryPoints.map(({ input, output, format = 'es', external = [], onwarn }) => {
return {
input,
output: {
Expand All @@ -148,7 +81,7 @@ export default entryPoints.map(({ input, output, format = 'es', external = [], p
exports: 'auto'
},
external: [...baseConfig.external, ...external],
plugins: [...baseConfig.plugins, ...plugins],
plugins: baseConfig.plugins,
onwarn
}
})
9 changes: 0 additions & 9 deletions shims/svelte-v3-shim.js

This file was deleted.

12 changes: 5 additions & 7 deletions src/picker/PickerElement.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import SveltePicker from './components/Picker/Picker.svelte'
import { createRoot } from './components/Picker/Picker.js'
import { DEFAULT_DATA_SOURCE, DEFAULT_LOCALE } from '../database/constants'
import { DEFAULT_CATEGORY_SORTING, DEFAULT_SKIN_TONE_EMOJI, FONT_FAMILY } from './constants'
import enI18n from './i18n/en.js'
import Database from './ImportedDatabase'
import { queueMicrotask } from './utils/queueMicrotask.js'

const PROPS = [
'customEmoji',
Expand Down Expand Up @@ -51,17 +52,14 @@ export default class PickerElement extends HTMLElement {
// The _cmp may be defined if the component was immediately disconnected and then reconnected. In that case,
// do nothing (preserve the state)
if (!this._cmp) {
this._cmp = new SveltePicker({
target: this.shadowRoot,
props: this._ctx
})
this._cmp = createRoot(this.shadowRoot, this._ctx)
}
}

disconnectedCallback () {
// Check in a microtask if the element is still connected. If so, treat this as a "move" rather than a disconnect
// Inspired by Vue: https://vuejs.org/guide/extras/web-components.html#building-custom-elements-with-vue
Promise.resolve().then(() => {
queueMicrotask(() => {
// this._cmp may be defined if connect-disconnect-connect-disconnect occurs synchronously
if (!this.isConnected && this._cmp) {
this._cmp.$destroy()
Expand Down Expand Up @@ -110,7 +108,7 @@ export default class PickerElement extends HTMLElement {
// Update the Database in one microtask if the locale/dataSource change. We do one microtask
// so we don't create two Databases if e.g. both the locale and the dataSource change
_dbFlush () {
Promise.resolve().then(() => (
queueMicrotask(() => (
this._dbCreate()
))
}
Expand Down
Loading
Loading