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

Support for two-way binding on custom elements #892

Closed
nsaunders opened this issue Oct 11, 2017 · 9 comments
Closed

Support for two-way binding on custom elements #892

nsaunders opened this issue Oct 11, 2017 · 9 comments
Labels
awaiting submitter needs a reproduction, or clarification custom element

Comments

@nsaunders
Copy link

Custom Elements (as in Web Components) cannot currently take advantage of two-way binding syntax.

For example, instead of this...

<custom-textbox
  label="Email Address"
  type="email"
  placeholder="Enter your email address"
  style="width: 300px"
  bind:value="email" />

...I have to do this...

<custom-textbox
  label="Email Address"
  type="email"
  placeholder="Enter your email address"
  style="width: 300px"
  value="{{email}}"
  on:input="set({ email: event.target.value })" />

I think this is kind of a bummer. :-(

@arxpoetica arxpoetica added awaiting submitter needs a reproduction, or clarification question labels Jan 8, 2018
@tionkje
Copy link

tionkje commented Jun 5, 2019

Wrote a simple example using a web component library that shows this

https://svelte.dev/repl/bc48abd5c41d4dee833e5757745cf57f?version=3.4.4

Seems like this is blocked in the compiler.
But it does not work when bypassing this validation

               this.bindings.forEach(binding => {                                                                                                                                                                 
                    const { name } = binding;
                    if (name === 'value') {
                        if (this.name !== 'input' &&
                            this.name !== 'textarea' &&
                            this.name !== 'select') {
                            component.error(binding, {
                                code: `invalid-binding`,
                                message: `'value' is not a valid binding on <${this.name}> elements`
                            });
                        }

@Conduitry Conduitry changed the title Support for custom elements Support for two-way binding on custom elements Oct 3, 2019
@tsulatsitamim
Copy link

@nsaunders I don't know if this is what you looking for, I try to add bind:value on bootstrap modal, and it works.

Modal.svelte

<script>
  import { onMount } from 'svelte'
  export let value = false

  let modalElement

  const displayModal = value => {
    if (process.browser) {
      value
        ? window.$(modalElement).modal('show')
        : window.$(modalElement).modal('hide')
    }
  }

  onMount(() => {
    window.$(modalElement).on('hidden.bs.modal', () => {
      value = false
    })
  })

  $: process.browser && displayModal(value)'
</script>

Parent.svelte

<script>
  import Modal from '../Modal.svelte'

  let modal
</script>

<div>
  <button
    on:click={() => (modal = true)}
    class="btn btn-label-primary">
    Add New
  </button>

  <Modal bind:value={modal}/>
</div>

@sudomaxime
Copy link

sudomaxime commented Mar 7, 2020

If someones comes across this is search of a clearer answer,

If you want to bind to a "regular" html input, you can use the usual bind:value={yourValue}.

If you want to bind to a custom element you created:

<YourComponent bind:yourExportedVarNameHere={yourValue} />

then in your custom component:

<script>
    export let yourExportedVarNameHere;
</script>

Cheers,

@antony antony closed this as completed Apr 9, 2020
@knuspertante
Copy link

@sudomaxime any hint while this is not working for ui5-input element?

The propname in ui5-input is "value"

https://codesandbox.io/s/divine-architecture-3qvlc?file=/App.svelte

@ERICCYS
Copy link

ERICCYS commented Jun 4, 2020

It seems the method mentioned by @sudomaxime is not working when customElement: true is set in rollup.config.js.

HelloWorld.svelte (child)

<script>
    import Hello from './components/Hello'
    import World from './components/World'
    export let value;
</script>

<svelte:options tag={'x-app-helloworld'}/>
<input type="text" bind:value={value} >

<input>
<x-app-hello />
<x-app-world />

App.svslte(parent)

<x-app-helloworld bind:value={value}/>

Then the parent will show an error: 'value' is not a valid binding on <x-app-helloworld> elements.

How can I solve this?

@knuspertante
Copy link

@MAXI0008 I opened another issue... #4838

@Tommertom
Copy link

Same issue with ionic ion-input element. A webcomponent too.

@Tommertom
Copy link

Tommertom commented Jul 11, 2022

Hi @antony - just curious if it is possible to reopen this one? You closed it maybe because of @sudomaxime comment, but that solution only works if you control the webcomponent

As you can see per later comments and still there - looking at my comment - if you don't control the webcomponent you can still not bind:value to get the binding to the elements value property.

Or do we need a workaround like mentioned here - https://css-tricks.com/using-custom-elements-in-svelte/

Wrapping the custom element in another custom element and then making the property reflective or something like that? Or even use:action for it?

@Tommertom
Copy link

#4838

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting submitter needs a reproduction, or clarification custom element
Projects
None yet
Development

No branches or pull requests

10 participants