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

AutoObject should display arrays #20

Open
mingfang opened this issue Oct 17, 2024 · 4 comments
Open

AutoObject should display arrays #20

mingfang opened this issue Oct 17, 2024 · 4 comments
Assignees
Labels
enhancement New feature or request

Comments

@mingfang
Copy link

mingfang commented Oct 17, 2024

Given an object like with an array field, e.g.

let test = {
    array: ['a', 'b', 'c']
}

AutoObject prints this error

No matching controller for 'array'

Ideally AutoObject can display the array like this
image

This is the possible code change in AutoObject

{#each Object.keys(object) as key (key)}

{#each Object.keys(object) as key (key)}
    {#if object[key].constructor === Object}
        <Folder title={prettify(key)}>
            <AutoObject bind:object={object[key]}/>
        </Folder>
    {:else if typeof object[key] === 'string'}
        <Text
                bind:value={object[key]}
                label={prettify(key)}
        />
    {:else if Array.isArray(object[key])}
        <Folder title={prettify(key)}>
            {#each object[key].map((value, i)=> ({[i]: value})) as value}
                <AutoObject bind:object={value}/>
            {/each}
        </Folder>
    {:else}
        <Binding
                bind:object
                {key}
                label={prettify(key)}
        />
    {/if}
{/each}
@kitschpatrol kitschpatrol self-assigned this Oct 17, 2024
@kitschpatrol kitschpatrol added the enhancement New feature or request label Oct 17, 2024
@kitschpatrol
Copy link
Owner

kitschpatrol commented Oct 17, 2024

Hi mingfang, thanks for using the library and for this suggestion.

See #3 for a somewhat-related discussion on what to do with arrays, though I see that your suggestion is different.

It's worth noting that vanilla Tweakpane ignores arrays, for example this results in an empty pane:

import { Pane } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/tweakpane.min.js'

const params = {
  array: ['a', 'b', 'c'],
}

const pane = new Pane({})
pane.addBinding(params, 'array')

There's also some confusing precedent from the rest of Svelte Tweakpane UI, where certain controls can accept tuple values.

So I'm not sure at the moment of the "least surprising" way to handle this case.

@mingfang
Copy link
Author

The code that I have works locally so this is not urgent.
Feel free to close if there's no plans to add this feature.
I suggest at least ignore unknown types to avoid erroring out by default.

@mingfang
Copy link
Author

mingfang commented Oct 17, 2024

Another option is for AutoObject to use slots, like this

{#each Object.keys(object) as key (key)}
    {#if object[key].constructor === Object}
        <slot name="object" {object} {key}>
            <Folder title={prettify(key)}>
                <AutoObject bind:object={object[key]}/>
            </Folder>
        </slot>
    {:else if typeof object[key] === 'string'}
        <slot name="string" {object} {key}>
            <Text bind:value={object[key]} label={prettify(key)}/>
        </slot>
    {:else if Array.isArray(object[key])}
        <slot name="array" {object} {key}>
            <Folder title={prettify(key)}>
                {#each object[key].map((value, i) => ({[i]: value})) as value}
                    <AutoObject bind:object={value}/>
                {/each}
            </Folder>
        </slot>
    {:else}
        <slot {object} {key}>
            <Binding bind:object {key} label={prettify(key)}/>
        </slot>
    {/if}
{/each}

Then the user can override, say array like this

<AutoObject object={object}>
    <svelte:fragment slot="array" let:object let:key>
        <Text value={object[key].toString()} label={key}/>
    </svelte:fragment>
</AutoObjec>

The only downside is you can't bind to a let variable.

@kitschpatrol
Copy link
Owner

Thanks! The slot approach is very interesting — though losing the let binding is tough.

I'll leave this issue open as I'd like to implement something when I have a moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants