Open Tommertom opened 1 year ago
@Tommertom
I would suggest another workaround: using actions. This way neither wrappers for the actual components (having the styling issue) have to be written nor the event listeners have to be set manually. The only drawback is, as far as I can grasp, that writeable
stores have to be used instead of plain component properties.
<script lang="ts">
import { bindIonInputValue } from "../ionActions";
let text = writable("text")
</script>
<ion-input use:bindIonInputValue={text} label={"my label"}/>
ionActions
import type { InputChangeEventDetail, IonInputCustomEvent } from "@ionic/core/dist/types/components";
import { type Writable, get } from "svelte/store";
export function bindIonInputValue(element: HTMLIonInputElement, store: Writable<string | number>): ActionReturn<Writable<string | number>> {
function eventListener(e: IonInputCustomEvent<InputChangeEventDetail>) {
store.set(e.detail.value)
}
function _set(store: Writable<string | number>) {
element.value = get(store)
element.addEventListener('ionInput', eventListener)
}
_set(store)
return {
update: _set,
destroy: () => element.removeEventListener('ionInput', eventListener)
}
}
export interface ActionReturn<Parameter = any> {
update?: (parameter: Parameter) => void;
destroy?: () => void;
}
@Tommertom
I would suggest another workaround: using actions. This way neither wrappers for the actual components (having the styling issue) have to be written nor the event listeners have to be set manually. The only drawback is, as far as I can grasp, that
writeable
stores have to be used instead of plain component properties.<script lang="ts"> import { bindIonInputValue } from "../ionActions"; let text = writable("text") </script> <ion-input use:bindIonInputValue={text} label={"my label"}/>
ionActions
import type { InputChangeEventDetail, IonInputCustomEvent } from "@ionic/core/dist/types/components"; import { type Writable, get } from "svelte/store"; export function bindIonInputValue(element: HTMLIonInputElement, store: Writable<string | number>): ActionReturn<Writable<string | number>> { function eventListener(e: IonInputCustomEvent<InputChangeEventDetail>) { store.set(e.detail.value) } function _set(store: Writable<string | number>) { element.value = get(store) element.addEventListener('ionInput', eventListener) } _set(store) return { update: _set, destroy: () => element.removeEventListener('ionInput', eventListener) } } export interface ActionReturn<Parameter = any> { update?: (parameter: Parameter) => void; destroy?: () => void; }
Thanks for sharing - got to think this through. I like to avoid creating documentation and deviations from the ionic api docs- but it does look interesting
@Tommertom I'll answer here to avoid out-of-topic posts in svelte thread.
For svelte-native
, we use svelte-native-preprocessor
As of what it's doing, here's an example:
Before preprocessing:
<textfield bind:text={myText}/>
After:
<textfield text={myText} on:textChange={(e) => myText = e.value}/>
Each NativeScript attribute has support for a corresponding event and that's why this is possible. This preprocessing is a bit slow however, as it's developed to turn markup content to AST and traverses it to modify binding attributes. I truly hope this helps you somehow, until svelte makes a decision.
Copy from https://github.com/Tommertom/svelte-ionic-app/issues/33
Reason why this is not work : https://github.com/sveltejs/svelte/issues/4838
Workaround - grab
ionChange
event onion-input
and use theevent.detail.value
to change the variable.Or if you are using bigger forms, an integrated forms-suite that handles this for you is even better. Then you get more goodies https://github.com/Tommertom/svelte-ionic-app/issues/33#issuecomment-1193364960
The earlier mentioned alternative to create svelte native wrappers like
IonInput.svelte
will resolve this too, but then we run into other problems with respect to styling of elements. So that route seems a dead end for now.Keeping this issue open until something better comes up