fix(frontend): Minor app editor updates (#1458)

* fix(frontend): Update clearable inputs

* update icon picker popup

* update
This commit is contained in:
Ádám Kovács
2023-04-25 12:28:27 +02:00
committed by GitHub
parent 630399d59e
commit 272fabe2e2
7 changed files with 87 additions and 128 deletions

View File

@@ -311,7 +311,7 @@
<TabContent value="insert">
<ComponentList />
</TabContent>
<TabContent value="css">
<TabContent value="css" class="h-full">
<CssSettings />
</TabContent>
</div>

View File

@@ -11,9 +11,9 @@
} from '../component'
import ListItem from './ListItem.svelte'
import { appComponentFromType, insertNewGridItem } from '../appUtils'
import { X } from 'lucide-svelte'
import { push } from '$lib/history'
import { flip } from 'svelte/animate'
import { ClearableInput } from '../../../common'
const { app, selectedComponent, focusedGrid } = getContext<AppViewerContext>('AppViewerContext')
@@ -47,22 +47,7 @@
</script>
<section class="p-2 sticky bg-white w-full z-10 top-0">
<div class="relative">
<input
bind:value={search}
class="px-2 py-1 border border-gray-300 rounded-sm !pr-6"
placeholder="Search components..."
/>
{#if search !== ''}
<button
class="absolute right-2 top-1/2 transform -translate-y-1/2 hover:bg-gray-500 bg-gray-300 transition-all rounded-full p-0.5"
on:click|stopPropagation|preventDefault={() => (search = '')}
>
<X size="10" color="white" />
</button>
{/if}
</div>
<ClearableInput bind:value={search} placeholder="Search components..." />
</section>
<div class="relative">

View File

@@ -1,13 +1,14 @@
<script lang="ts">
import { getContext } from 'svelte'
import { LayoutDashboardIcon, MousePointer2, CurlyBraces, X } from 'lucide-svelte'
import { LayoutDashboardIcon, MousePointer2, CurlyBraces } from 'lucide-svelte'
import SimpleEditor from '$lib/components/SimpleEditor.svelte'
import { emptyString } from '$lib/utils'
import { Tab, TabContent, Tabs } from '../../../common'
import { ClearableInput, Tab, TabContent, Tabs } from '../../../common'
import type { AppViewerContext } from '../../types'
import ListItem from './ListItem.svelte'
import CssProperty from './CssProperty.svelte'
import { ccomponents, components } from '../component'
import { slide } from 'svelte/transition'
const STATIC_ELEMENTS = ['app'] as const
const TITLE_PREFIX = 'Css.' as const
@@ -27,6 +28,7 @@
$: rawCode && parseJson()
let jsonError = ''
let jsonErrorHeight: number
function parseJson() {
try {
@@ -67,8 +69,8 @@
let search = ''
</script>
<div class="w-full text-lg font-semibold text-center text-gray-600 p-2">Global Styling</div>
<Tabs selected="ui" on:selected={(e) => switchTab(e.detail === 'json')} class="relative">
<!-- <div class="w-full text-lg font-semibold text-center text-gray-600 p-2">Global Styling</div> -->
<Tabs selected="ui" on:selected={(e) => switchTab(e.detail === 'json')} class="h-full">
<Tab value="ui" size="xs" class="w-1/2">
<div class="m-1 center-center">
<MousePointer2 size={16} />
@@ -81,80 +83,64 @@
<span class="pl-1">JSON</span>
</div>
</Tab>
<div slot="content" class="h-full overflow-y-auto">
<TabContent value="ui">
<div class="sticky top-0 left-0 w-full bg-white p-2">
<div class="relative">
<input
bind:value={search}
class="px-2 pb-1 border border-gray-300 rounded-sm {search ? 'pr-8' : ''}"
placeholder="Search..."
/>
{#if search}
<button
class="absolute right-2 top-1/2 transform -translate-y-1/2 hover:bg-gray-200 rounded-full p-0.5"
on:click|stopPropagation|preventDefault={() => (search = '')}
>
<X size="14" />
</button>
{/if}
</div>
<div slot="content" class="h-[calc(100%-35px)] overflow-auto">
<TabContent value="ui" class="h-full">
<div class="p-2">
<ClearableInput bind:value={search} placeholder="Search..." />
</div>
{#each search != '' ? entries.filter((x) => x.name
.toLowerCase()
.includes(search.toLowerCase())) : entries as { type, name, icon, ids } (name)}
{#if ids.length > 0}
<ListItem
title={name}
prefix={TITLE_PREFIX}
on:open={(e) => {
if ($app.css != undefined) {
if (e.detail && $app.css[type] == undefined) {
$app.css[type] = Object.fromEntries(ids.map(({ id }) => [id, {}]))
<div class="h-[calc(100%-50px)] overflow-auto relative">
{#each search != '' ? entries.filter((x) => x.name
.toLowerCase()
.includes(search.toLowerCase())) : entries as { type, name, icon, ids } (name)}
{#if ids.length > 0}
<ListItem
title={name}
prefix={TITLE_PREFIX}
on:open={(e) => {
if ($app.css != undefined) {
if (e.detail && $app.css[type] == undefined) {
$app.css[type] = Object.fromEntries(ids.map(({ id }) => [id, {}]))
}
}
}
}}
>
<div slot="title" class="flex items-center">
<svelte:component this={icon} size={18} />
<span class="ml-1">
{name}
</span>
</div>
<div class="pb-2">
{#each ids as { id, forceStyle, forceClass }}
<div class="mb-3">
{#if $app?.css?.[type]}
<CssProperty
{forceClass}
{forceStyle}
name={id}
bind:value={$app.css[type][id]}
/>
{/if}
</div>
{/each}
</div>
</ListItem>
{/if}
{/each}
}}
>
<div slot="title" class="flex items-center">
<svelte:component this={icon} size={18} />
<span class="ml-1">
{name}
</span>
</div>
<div class="pb-2">
{#each ids as { id, forceStyle, forceClass }}
<div class="mb-3">
{#if $app?.css?.[type]}
<CssProperty
{forceClass}
{forceStyle}
name={id}
bind:value={$app.css[type][id]}
/>
{/if}
</div>
{/each}
</div>
</ListItem>
{/if}
{/each}
</div>
</TabContent>
<TabContent value="json">
<TabContent value="json" class="h-full">
{#if !emptyString(jsonError)}
<span class="text-red-400 text-xs mb-1 flex flex-row-reverse">
<div
transition:slide={{ duration: 200 }}
bind:clientHeight={jsonErrorHeight}
class="text-red-500 text-xs p-1"
>
{jsonError}
</span>
{:else}
<div class="py-2" />
</div>
{/if}
<div class="h-full w-full py-1">
<SimpleEditor
autoHeight
class="editor"
lang="json"
bind:code={rawCode}
fixedOverflowWidgets={false}
/>
<div style="height: calc(100% - {jsonErrorHeight || 0}px);">
<SimpleEditor class="h-full" lang="json" bind:code={rawCode} fixedOverflowWidgets={false} />
</div>
</TabContent>
</div>

View File

@@ -1,6 +1,5 @@
<script lang="ts">
import { classNames } from '$lib/utils'
import { X } from 'lucide-svelte'
import { getContext } from 'svelte'
import type { AppViewerContext, ContextPanelContext } from '../../types'
@@ -10,6 +9,7 @@
import ComponentOutputViewer from './ComponentOutputViewer.svelte'
import BackgroundScriptsOutput from './components/BackgroundScriptsOutput.svelte'
import OutputHeader from './components/OutputHeader.svelte'
import { ClearableInput } from '../../../common'
const { connectingInput, app } = getContext<AppViewerContext>('AppViewerContext')
const { search } = getContext<ContextPanelContext>('ContextPanel')
@@ -26,21 +26,7 @@
>
<div class="min-w-[150px]">
<div class="sticky z-10 top-0 left-0 w-full bg-white p-1.5">
<div class="relative w-full">
<input
bind:value={$search}
class="!border-gray-200 !rounded-md !text-xs !pr-6"
placeholder="Search outputs..."
/>
{#if $search !== ''}
<button
class="absolute right-2 top-1/2 transform -translate-y-1/2 hover:bg-gray-500 bg-gray-300 transition-all rounded-full p-0.5"
on:click|stopPropagation|preventDefault={() => ($search = '')}
>
<X size="10" color="white" />
</button>
{/if}
</div>
<ClearableInput bind:value={$search} placeholder="Search outputs..." />
</div>
<div class="flex flex-col gap-4">

View File

@@ -46,7 +46,7 @@
}
.color-picker-input span > div.wrapper {
box-shadow: 0 5px 30px -5px rgba(0, 0, 0, 0.25) !important;
box-shadow: 0 10px 40px -5px rgba(0, 0, 0, 0.25) !important;
border-style: none !important;
border-radius: 0.375rem !important;
top: 6px !important;

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import type { StaticInput } from '../../../inputType'
import { Loader2, X } from 'lucide-svelte'
import { Popup } from '../../../../common'
import { Loader2 } from 'lucide-svelte'
import { ClearableInput, Popup } from '../../../../common'
import { fade } from 'svelte/transition'
export let componentInput: StaticInput<string>
@@ -52,11 +52,11 @@
}
</script>
<div class="relative">
<input
<div bind:this={anchor} class="relative">
<ClearableInput
readonly
value={formatName(componentInput.value)}
bind:this={anchor}
on:change={({ detail }) => (componentInput.value = detail)}
on:focus={getData}
class="!pr-6"
/>
@@ -64,28 +64,24 @@
<div class="center-center absolute right-2 top-1/2 transform -translate-y-1/2 p-0.5">
<Loader2 class="animate-spin" size={16} />
</div>
{:else if componentInput.value}
<button
class="absolute right-2 top-1/2 transform -translate-y-1/2 hover:bg-gray-500 bg-gray-300 transition-all rounded-full p-0.5"
on:click|stopPropagation|preventDefault={() => (componentInput.value = undefined)}
title="Clear"
aria-label="Clear"
>
<X size="10" color="white" />
</button>
{/if}
</div>
{#if anchor}
<Popup
ref={anchor}
closeOn={[]}
options={{ placement: 'bottom' }}
options={{
placement: 'bottom-start',
strategy: 'fixed',
modifiers: [{ name: 'offset', options: { offset: [0, 6] } }]
}}
bind:open={openPopup}
let:close
transition={fade}
wrapperClasses=" z-[1002]"
>
{#if !loading}
<div class="max-w-xs shadow-[0_10px_40px_-5px_rgba(0,0,0,0.25)] bg-white rounded-md p-2">
<div class="w-72 shadow-[0_10px_40px_-5px_rgba(0,0,0,0.25)] bg-white rounded-md p-2">
{#if filteredItems}
<input
on:keydown={(event) => {

View File

@@ -10,6 +10,7 @@
export let wrapperClass = ''
export let buttonClass = ''
const dispatch = createEventDispatcher()
let isHovered = false
$: isNumeric = ['number', 'range'].includes(type)
$: dispatch('change', value)
@@ -23,7 +24,11 @@
}
</script>
<div class="relative grow {wrapperClass}">
<div
class="relative grow {wrapperClass}"
on:mouseenter={() => (isHovered = true)}
on:mouseleave={() => (isHovered = false)}
>
{#if type === 'textarea'}
<textarea
{value}
@@ -47,14 +52,15 @@
on:blur
/>
{/if}
{#if value}
{#if value && isHovered}
<button
transition:fade|local={{ duration: 100 }}
class="absolute z-10 top-1.5 right-1 rounded-full p-1 bg-white/60 duration-200 hover:bg-gray-200 {buttonClass}"
transition:fade|local={{ duration: 80 }}
class="absolute z-10 top-[9.5px] right-2 rounded-full p-0.5 text-white bg-gray-300
duration-200 hover:bg-gray-600 focus:bg-gray-600 {buttonClass}"
aria-label="Clear"
on:click|preventDefault|stopPropagation={clear}
>
<X size={14} />
<X size={11} class="" />
</button>
{/if}
<slot />