Skip to content

Commit

Permalink
perf: replace svelte-select with custom select
Browse files Browse the repository at this point in the history
  • Loading branch information
azat-io committed Oct 29, 2023
1 parent 5d1993b commit b8d8d76
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 75 deletions.
18 changes: 6 additions & 12 deletions docs/components/code.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,22 @@
let set = (key: string, value: string) => {
root.style.setProperty(key, value)
}
set('--view-background', colors['editor.background'])
set('--view-color', colors['editor.foreground'])
set('--view-background-primary', colors['editor.background'])
set('--view-color-primary', colors['editor.foreground'])
set('--view-border-active', colors['editor.foreground'])
set(
'--view-border',
!colors['tab.border'].startsWith(colors['editor.background'])
? colors['tab.border']
: colors['editorGroup.border'],
)
set(
'--view-tab-active-background',
'--view-background-secondary',
!colors['tab.activeBackground'].startsWith(colors['editor.background'])
? colors['tab.activeBackground']
: colors['tab.inactiveBackground'],
)
set(
'--view-tab-background',
!colors['tab.activeBackground'].startsWith(colors['editor.background'])
? colors['tab.inactiveBackground']
: colors['tab.activeBackground'],
)
set('--view-tab-active-color', colors['tab.activeForeground'])
set('--view-tab-color', colors['tab.inactiveForeground'])
}
let getHighlightedCode = async (colorThemeName: string): Promise<string> => {
Expand Down Expand Up @@ -70,7 +64,7 @@

<style>
.code {
background: var(--view-background);
background: var(--view-background-primary);
padding: 10px;
}
</style>
167 changes: 167 additions & 0 deletions docs/components/select.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<script lang="ts">
type Option = {
label: string
value: string
}
export let options: Option[] = []
export let value = options[0].value
let getLabel = (value: string) => {
let option = options.find(option => option.value === value)
return option!.label
}
let valueToShow = getLabel(value)
let ref: HTMLInputElement
let show = false
let selectValue = (newValue?: string) => {
if (newValue) {
value = newValue
valueToShow = getLabel(newValue)
} else {
valueToShow = getLabel(value)
}
show = false
ref.blur()
}
let onEnterPress = (event: KeyboardEvent) => {
if (event.key === 'Enter') {
let option = optionsToShow[0]
selectValue(option.value)
show = false
}
}
let handleFocus = () => {
valueToShow = ''
show = true
window.addEventListener('keydown', onEnterPress)
}
let handleBlur = () => {
selectValue()
window.removeEventListener('keydown', onEnterPress)
}
let handleClick = (event: MouseEvent, option: Option) => {
selectValue(option.value)
}
$: optionsToShow = options.filter(option =>
option.label.toLowerCase().includes(valueToShow.toLowerCase()),
)
</script>

<div class="wrapper">
<input
bind:value={valueToShow}
on:focus={handleFocus}
on:blur={handleBlur}
bind:this={ref}
class="input"
type="text"
/>
{#if show}
<div class="options">
<ul class="list">
{#each optionsToShow as option}
<li class="item">
<button
class="button"
on:mousedown={event => {
handleClick(event, option)
}}
>
{@html option.label.replace(
new RegExp(valueToShow, 'gi'),
match => `<b>${match}</b>`,
)}
</button>
</li>
{/each}
</ul>
</div>
{/if}
</div>

<style>
.wrapper {
position: relative;
}
.input {
inline-size: 100%;
padding: 8px 16px;
font-size: 12px;
border: 1px solid var(--view-border);
color: var(--view-color-primary);
background: var(--view-background-primary);
border-radius: 8px;
cursor: pointer;
transition: border-color 300ms;
outline: none;
}
.input:hover,
.input:focus-visible {
border-color: var(--view-border-active);
}
.options {
position: absolute;
max-block-size: 200px;
inline-size: 100%;
background: #fff;
border: 1px solid var(--view-border);
border-radius: 8px;
overflow: hidden;
z-index: 1;
margin-block-start: 4px;
transform: scaleY(0);
transform-origin: top center;
animation: grow-down 250ms ease-in-out forwards;
}
.list {
margin-block: 0;
padding-inline-start: 0;
list-style-type: none;
}
.item {
font-size: 12px;
overflow: hidden;
}
.button {
background: var(--view-background-primary);
color: var(--view-color-primary);
inline-size: 100%;
block-size: 100%;
padding: 8px 12px;
border: 0;
text-align: start;
}
.button:hover,
.button:focus-visible {
background: var(--view-background-secondary);
}
@keyframes grow-down {
0% {
transform: scaleY(0);
}
80% {
transform: scaleY(1.1);
}
100% {
transform: scaleY(1);
}
}
</style>
34 changes: 6 additions & 28 deletions docs/components/view.svelte
Original file line number Diff line number Diff line change
@@ -1,43 +1,21 @@
<script lang="ts">
import Select from 'svelte-select'
import { themes } from '../../data/themes'
import Select from './select.svelte'
import Code from './code.svelte'
let items = themes.map(theme => ({
label: theme.name,
value: theme.id,
}))
let selectedTheme = items[0]
console.log(selectedTheme)
let theme = items[0].value
</script>

<div class="view">
<div class="icons">
<Select
{items}
bind:value={selectedTheme}
clearable={false}
--item-is-active-bg="var(--view-tab-active-background)"
--item-is-active-color="var(--view-tab-active-color)"
--item-hover-bg="var(--view-tab-active-background)"
--item-hover-color="var(--view-tab-active-color)"
--border-focused="1px solid var(--view-border)"
--list-background="var(--view-tab-background)"
--list-border="1px solid var(--view-border)"
--border-hover="1px solid var(--view-color)"
--border="1px solid var(--view-border)"
--background="var(--view-background)"
--list-color="var(--view-tab-color)"
--value-container-padding="0"
--font-family="inherit"
--font-size="12px"
--height="32px"
/>
<Select options={items} bind:value={theme} />
</div>
<Code bind:theme={selectedTheme.value} />
<Code {theme} />
</div>

<style>
Expand All @@ -48,8 +26,8 @@
}
.icons {
background: var(--view-background);
color: var(--view-color);
background: var(--view-background-primary);
color: var(--view-color-primary);
padding: 10px;
border-inline-end: 1px solid var(--view-border);
}
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
"stylelint-order": "^6.0.3",
"stylelint-plugin-logical-css": "^0.13.2",
"svelte": "^4.2.2",
"svelte-select": "^5.7.0",
"svgo": "^3.0.2",
"tsm": "^2.3.0",
"typescript": "^5.2.2",
Expand Down
34 changes: 0 additions & 34 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b8d8d76

Please sign in to comment.