Skip to content

Commit

Permalink
feat: completed preset select
Browse files Browse the repository at this point in the history
  • Loading branch information
bbtgnn committed Jul 25, 2024
1 parent 8f793f7 commit 2064b8a
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 22 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"ansi-to-html": "^0.7.2",
"codemirror": "^6.0.1",
"effect": "^3.5.7",
"fuse.js": "^7.0.0",
"has-ansi": "^6.0.0",
"lucide-react": "^0.396.0",
"nanoid": "^5.0.7",
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

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

Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
:host {
display: block;
}

::backdrop {
background: black;
opacity: 0.75;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Host, Prop, State, Element, Watch, h } from '@stencil/core';
import SlangroomPresets from './utils/slangroom-presets.json';
import { EditorId } from '../dyne-slangroom-editor/dyne-slangroom-editor';
import { Array as A, pipe, Effect } from 'effect';
import Fuse from 'fuse.js';

@Component({
tag: 'dyne-slangroom-preset-loader',
Expand All @@ -14,12 +15,9 @@ export class DyneSlangroomPresetLoader {
@Prop({ reflect: true }) editorId: string;

@State() presets: SlangroomPreset[] = SlangroomPresets;
@State() filteredPresets: SlangroomPreset[] = this.presets;

@Watch('presets')
updatePresetsSearch() {
this.filteredPresets = this.presets;
}
@State() filteredPresets: SlangroomPreset[] = this.presets;
@State() searchText = '';

get dialog() {
return this.el.shadowRoot?.querySelector('dialog');
Expand All @@ -29,15 +27,29 @@ export class DyneSlangroomPresetLoader {
return document.getElementById(this.editorId) as HTMLDyneSlangroomEditorElement;
}

async componentDidLoad() {
await this.loadPresetsFromElements();
lockScrollOnDialogOpen(this.dialog!);
}

// Preset selection

private onPresetSelect(preset: SlangroomPreset) {
this.loadPresetInEditor(preset);
this.dialog?.close();
}

private async loadPresetInEditor(preset: SlangroomPreset) {
await this.editor.setContent(EditorId.CONTRACT, preset.contract);
await this.editor.setContent(EditorId.DATA, preset.data);
await this.editor.setContent(EditorId.KEYS, preset.keys);
}

private onPresetSelect(preset: SlangroomPreset) {
this.loadPresetInEditor(preset);
this.dialog?.close();
// Load presets from dyne-slangroom-preset

private async loadPresetsFromElements() {
const presets = await this.readPresetsFromElements();
this.addPresets(presets);
}

private readPresetsFromElements() {
Expand All @@ -60,25 +72,58 @@ export class DyneSlangroomPresetLoader {
this.presets = [...this.presets, ...presets];
}

async componentDidLoad() {
pipe(await this.readPresetsFromElements(), presets => this.addPresets(presets));
@Watch('presets')
updatePresetsSearch() {
this.filteredPresets = this.presets;
}

// Search

private updateSearchText(e: Event) {
this.searchText = (e.target as any).value;
}

@Watch('searchText')
filterPresets() {
this.filteredPresets = filterPresetsByText(this.presets, this.searchText);
}

// Utils

private setDialogEvents() {
this.dialog?.addEventListener('close', () => unlockScroll());
this.dialog?.addEventListener('cancel', () => unlockScroll());
this.dialog?.addEventListener('cancel', () => unlockScroll());
}

//

render() {
return (
<Host>
<dyne-button size="small" emphasis="m" onClick={() => this.dialog?.showModal()}>
Select preset
</dyne-button>
<dialog class="rounded-lg">
<div class="flex gap-4 justify-between items-center p-4 border-b sticky top-0 bg-white">
<p>Select a slangroom preset</p>
<dyne-button size="small" emphasis="m" onClick={() => this.dialog?.close()}>
X
</dyne-button>
<dialog class="backdrop:bg-black backdrop:opacity-75 h-screen m-0">
<div class="sticky top-0 bg-white">
<div class="flex gap-4 justify-between items-center p-4 border-b ">
<p>Select a Slangroom preset</p>
<dyne-button size="small" emphasis="m" onClick={() => this.dialog?.close()}>
X
</dyne-button>
</div>
<div class="p-4 border-b">
<input
class="block border w-full p-2 rounded-md hover:bg-slate-100 focus:bg-transparent"
name="search"
value={this.searchText}
placeholder="Search for a topic"
onInput={e => this.updateSearchText(e)}
></input>
</div>
</div>
<PresetsSelect
presets={this.presets}
presets={this.filteredPresets}
onPresetSelect={this.onPresetSelect.bind(this)}
></PresetsSelect>
</dialog>
Expand Down Expand Up @@ -126,3 +171,38 @@ function PresetsSelect(props: PresetsProps) {
</div>
);
}

//

function filterPresetsByText(presets: SlangroomPreset[], text: string): SlangroomPreset[] {
if (!Boolean(text)) return presets;
const fuse = new Fuse(presets, {
keys: ['name', 'group', 'meta.title'],
threshold: 0.4,
});
return fuse.search(text).map(result => result.item);
}

function lockScroll() {
document.body.style.overflow = 'hidden';
}

function unlockScroll() {
document.body.style.overflow = '';
}

function lockScrollOnDialogOpen(dialog: HTMLDialogElement) {
const observer = new MutationObserver(mutationsList => {
mutationsList
.filter(mutation => mutation.attributeName === 'open')
.forEach(() => {
if (dialog.open) {
lockScroll();
} else {
unlockScroll();
}
});
});

observer.observe(dialog, { attributes: true });
}

0 comments on commit 2064b8a

Please sign in to comment.