ComboBox
This commit is contained in:
+1
-4
@@ -11,8 +11,7 @@
|
||||
npm/bootstrap@4.6.1/dist/css/bootstrap-grid.min.css,
|
||||
npm/codemirror@5.65.5/lib/codemirror.min.css,
|
||||
npm/codemirror@5.65.5/addon/scroll/simplescrollbars.css,
|
||||
npm/codemirror@5.65.5/theme/dracula.min.css,
|
||||
npm/microtip@0.2.2/microtip.min.css"
|
||||
npm/codemirror@5.65.5/theme/dracula.min.css"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
@@ -22,8 +21,6 @@ npm/microtip@0.2.2/microtip.min.css"
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/combine/
|
||||
npm/lzma@2.3.2/src/lzma.min.js,
|
||||
npm/clipboard@2.0.11/dist/clipboard.min.js,
|
||||
npm/micromodal@0.4.10/dist/micromodal.min.js,
|
||||
npm/codemirror@5.65.5,
|
||||
npm/codemirror@5.65.5/addon/mode/loadmode.min.js,
|
||||
npm/codemirror@5.65.5/addon/mode/overlay.min.js,
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<script lang="ts">
|
||||
import { clickoutside } from '@svelte-put/clickoutside'
|
||||
import { onMount, tick } from 'svelte'
|
||||
|
||||
type Item = { text: string }
|
||||
export let value: Item | null = null
|
||||
export let items: Item[]
|
||||
let filteredItems: Item[] = []
|
||||
|
||||
let inputFilter: HTMLInputElement | null = null
|
||||
let filter = ''
|
||||
|
||||
let divContainer: HTMLDivElement | null = null
|
||||
|
||||
let areOptionsVisible = false
|
||||
|
||||
$: {
|
||||
if (filter) {
|
||||
filteredItems = items.filter((item) => item.text.toLowerCase().includes(filter.toLowerCase()))
|
||||
} else {
|
||||
filteredItems = [...items]
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
// Watch filter value
|
||||
if (filter) {
|
||||
tick().then(() => {
|
||||
if (divContainer) {
|
||||
if (divContainer.scrollHeight > divContainer.clientHeight) {
|
||||
divContainer.classList.add('h-96')
|
||||
} else {
|
||||
divContainer.classList.remove('h-96')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function showOptions() {
|
||||
// Add a delay so that the click outside event doesn't trigger too soon
|
||||
setTimeout(() => {
|
||||
areOptionsVisible = true
|
||||
tick().then(() => inputFilter?.select())
|
||||
}, 0)
|
||||
setTimeout(() => {}, 100)
|
||||
}
|
||||
|
||||
function hideOptions() {
|
||||
areOptionsVisible = false
|
||||
}
|
||||
|
||||
function selectItem(item: Item) {
|
||||
value = item
|
||||
hideOptions()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="relative" use:clickoutside on:clickoutside={hideOptions}>
|
||||
{#if areOptionsVisible}
|
||||
<input
|
||||
type="text"
|
||||
bind:value={filter}
|
||||
bind:this={inputFilter}
|
||||
class={$$restProps.class ?? ''}
|
||||
/>
|
||||
<div
|
||||
class="absolute top-full left-0 w-full bg-gray-700 max-h-[90vh] overflow-y-auto"
|
||||
bind:this={divContainer}
|
||||
>
|
||||
{#each filteredItems as item}
|
||||
<div class="p-1 hover:bg-gray-600" on:click={() => selectItem(item)}>{item.text}</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<input
|
||||
type="text"
|
||||
readonly
|
||||
value={value?.text ?? ''}
|
||||
class={$$restProps.class ?? ''}
|
||||
on:click={showOptions}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
select {
|
||||
appearance: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,20 +0,0 @@
|
||||
<script lang="ts">
|
||||
type Item = { text: string }
|
||||
export let value: Item | null = null
|
||||
export let items: Item[]
|
||||
|
||||
</script>
|
||||
|
||||
<select bind:value={value} class={ ($$restProps.class ?? '') }>
|
||||
{#each items as item}
|
||||
<option value={item}>
|
||||
{item.text}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
|
||||
<style lang="scss">
|
||||
select {
|
||||
appearance: none;
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { onMount, tick } from 'svelte'
|
||||
import { shorten } from '$lib/utils'
|
||||
import Select from './Select.svelte'
|
||||
import type { Editor } from 'codemirror'
|
||||
import { shareUrl, selectedLang } from '../store'
|
||||
import ComboBox from './ComboBox.svelte'
|
||||
|
||||
type Language = {
|
||||
text: string
|
||||
@@ -64,11 +64,11 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex justify-between p-2 text-sm relative z-10 shadow-md">
|
||||
<div>NoPaste</div>
|
||||
<div class="flex justify-between items-center px-3 py-1 text-sm relative z-10 shadow-md">
|
||||
<h1 class="text-xl">NoPaste</h1>
|
||||
<div class="flex justify-end gap-2">
|
||||
<div>
|
||||
<Select
|
||||
<ComboBox
|
||||
items={languages}
|
||||
bind:value={selectedLanguage}
|
||||
class="bg-gray-700 border border-gray-300 p-1"
|
||||
|
||||
Reference in New Issue
Block a user