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

How would you use svelte-formula with "componized" input elements #8

Open
maku opened this issue Mar 11, 2021 · 6 comments
Open

How would you use svelte-formula with "componized" input elements #8

maku opened this issue Mar 11, 2021 · 6 comments
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@maku
Copy link

maku commented Mar 11, 2021

Assuming that the input elements are abstracted into their own svelte components, how can you use the lib?

@tanepiper
Copy link
Owner

@maku Good question - and maybe one I don't have an answer to yet?

When I was building this library I saw it more as something you would always use on top of HTML5 forms - so you would build your form, apply Formula - the form itself would be the component and use an event dispatcher to pass any data up to parent components.

If you have a component that's custom, it would have to adhere to some kind of API that matches an input - maybe it would work with bind:value and a custom validator passed to formula()

I just knocked together a quick demo - maybe something like this might work? https://svelte.dev/repl/57fbdfeebe8840ef86b0b855a40f86cf

@maku
Copy link
Author

maku commented Mar 11, 2021

@tanepiper thank you for answering. I never use "pure" HTML5 forms. (maybe because I worked mainly in big Angular apps). But when I think about it, I realized that either you use a JS-Lib and integrate it into svelte or you use a CSS Lib like tailwind. In both ways you are rather forced to create your own components or use components already build from the lib.

For my use case, in a side project which is based on tailwind, every input component has a value property, which seems to be enough to work with formula (according to your example app)

Nonetheless, thank you for your work ...

@tanepiper
Copy link
Owner

@maku Can you provide an example of a component you might use? Although that was the initial goal, I don't see why the library can't support custom components?

@tanepiper
Copy link
Owner

@maku Outside of knowing your specific needs I've added some ability to do custom events https://formula.svelte.codes/docs/examples/custom-event

I also made an example with a third-party component and some hidden fields (which I've supported in 0.10.0) https://svelte.dev/repl/32d7417f604a49559464257dec35d6a4?version=3.31.2 - it's not idea and it still requires another field for now to trigger the change event (which I can fix in the next release)

@tanepiper tanepiper self-assigned this Mar 12, 2021
@tanepiper tanepiper added enhancement New feature or request question Further information is requested labels Mar 12, 2021
@maku
Copy link
Author

maku commented Mar 12, 2021

@tanepiper Here is a very simple example of wrapping a textfield of material components web (https://github.com/material-components/material-components-web/tree/master/packages/mdc-textfield).

I tried to use this component with formula and I had no problems with basic functionality. Of course there are many areas to address but I think it is rather manageable when you wrap a js lib yourself.

e.g.

<div use:form style="border: 1px solid silver; padding: 20px;">
  <UiInput name="name" label="Name" bind:value={customer.name} /> <br />

  <UiInput name="email" label="Email" bind:value={customer.email} />
</div>

UiInput.svelte

<script lang="ts">
  import { MDCTextField } from '@material/textfield';
  import { onDestroy, onMount } from 'svelte';

  let element: HTMLElement;
  export let value = '';
  export let label: string;
  export let name = '';

  let textField: MDCTextField;

  onMount(() => {
    textField = new MDCTextField(element);
  });

  onDestroy(() => {
    textField.destroy();
  });
</script>

<label bind:this={element} class="mdc-text-field mdc-text-field--outlined">
  <span class="mdc-notched-outline">
    <span class="mdc-notched-outline__leading" />
    <span class="mdc-notched-outline__notch">
      <span class="mdc-floating-label" id="{name}-label">{label}</span>
    </span>
    <span class="mdc-notched-outline__trailing" />
  </span>
  <input
    name={name}
    type="text"
    class="mdc-text-field__input"
    aria-labelledby="{name}-label"
    bind:value
  />
</label>

Probably it would be harder using a lib like https://github.com/hperrin/svelte-material-ui which provides the wrapping where you do not have the full control of the components...

@benwoodward
Copy link

Thanks for building this plugin @tanepiper, really well designed API. I struggled for a while trying to figure out why I couldn't get my Formula form to detect values from https://github.com/rob-balfre/svelte-select.

  let selectValue = "";
  let hiddenSelectInput;

  function handleSelect(event) {
    selectValue = event.detail.value;
    hiddenSelectInput.dispatchEvent(new Event('customEvent'))
  }

  function clearSelect() {
    selectValue = "";
    hiddenSelectInput.dispatchEvent(new Event('customEvent'))
  }
<label for="primary-language" class="leading-7 text-sm text-gray-600">Primary Language</label>
<input type="text" id="primary-language" name="primaryLanguage" hidden=true bind:value={selectValue} bind:this={hiddenSelectInput} data-formula-bind='customEvent'/>
<Select {items} selectedValue={selectedValue.label} on:select={handleSelect} on:clear={clearSelect}></Select>

I figured out that there needed to be an input with a name attribute, but it wasn't obvious to me that the input needed to emit an event for Formula to detect changes. Would be great if the above setup wasn't necessary somehow.

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

No branches or pull requests

3 participants