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

fix: input bind value can't be updated in real time #152

Merged
merged 3 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions components/Input/__test__/__snapshots__/input.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Test: KInput > props: attrs 1`] = `"<div class=\\"k-input--base k-input--base__dark k-input--base__hover k-input--base__focus \\"> <input class=\\"k-input--inner k-input--inner__dark \\" placeholder=\\"\\" type=\\"number\\" strattr=\\"你干嘛,哎哟\\" numattr=\\"8\\" objattr=\\"[object Object]\\" arrattr=\\"i,kun\\"> </div>"`;
exports[`Test: KInput > props: attrs 1`] = `"<div class=\\"k-input k-input--base k-input--base__dark k-input--base__hover k-input--base__focus\\"> <input class=\\"k-input--inner k-input--inner__dark\\" placeholder=\\"\\" type=\\"number\\" strattr=\\"你干嘛,哎哟\\" numattr=\\"8\\" objattr=\\"[object Object]\\" arrattr=\\"i,kun\\"> </div>"`;

exports[`Test: KInput > props: cls 1`] = `"<div class=\\"k-input--base k-input--base__dark k-input--base__hover k-input--base__focus ikun\\"> <input class=\\"k-input--inner k-input--inner__dark \\" placeholder=\\"\\"> </div>"`;
exports[`Test: KInput > props: cls 1`] = `"<div class=\\"k-input k-input--base k-input--base__dark k-input--base__hover k-input--base__focus ikun\\"> <input class=\\"k-input--inner k-input--inner__dark\\" placeholder=\\"\\"> </div>"`;

exports[`Test: KInput > props: disabled 1`] = `"<div class=\\"k-input--base k-input--base__dark k-input--base__disabled k-input--base__disabled__dark k-input--base__hover k-input--base__focus \\"> <input class=\\"k-input--inner k-input--inner__dark k-input--base__disabled k-input--base__disabled__dark\\" disabled=\\"\\" placeholder=\\"\\"> </div>"`;
exports[`Test: KInput > props: disabled 1`] = `"<div class=\\"k-input k-input--base k-input--base__dark k-input--base__disabled k-input--base__disabled__dark k-input--base__hover k-input--base__focus\\"> <input class=\\"k-input--inner k-input--inner__dark k-input--base__disabled k-input--base__disabled__dark\\" disabled=\\"\\" placeholder=\\"\\"> </div>"`;

exports[`Test: KInput > props: iconPrefix 1`] = `"<div class=\\"k-input--base k-input--base__dark k-input--base__hover k-input--base__focus \\"> <div role=\\"\\" aria-hidden=\\"true\\" class=\\"k-icon--base k-icon--base__dark k-input--icon\\"><div class=\\"i-carbon-logo-svelte k-icon-transition \\" style=\\"width: 24px; height: 24px;\\"></div></div> <input class=\\"k-input--inner k-input--inner__dark \\" placeholder=\\"\\"> </div>"`;
exports[`Test: KInput > props: iconPrefix 1`] = `"<div class=\\"k-input k-input--base k-input--base__dark k-input--base__hover k-input--base__focus\\"> <div role=\\"\\" aria-hidden=\\"true\\" class=\\"k-icon--base k-icon--base__dark k-input--icon\\"><div class=\\"i-carbon-logo-svelte k-icon-transition \\" style=\\"width: 24px; height: 24px;\\"></div></div> <input class=\\"k-input--inner k-input--inner__dark\\" placeholder=\\"\\"> </div>"`;

exports[`Test: KInput > props: iconSuffix 1`] = `"<div class=\\"k-input--base k-input--base__dark k-input--base__hover k-input--base__focus \\"> <input class=\\"k-input--inner k-input--inner__dark \\" placeholder=\\"\\"> <div role=\\"\\" aria-hidden=\\"true\\" class=\\"k-icon--base k-icon--base__dark k-input--icon\\"><div class=\\"i-carbon-search k-icon-transition \\" style=\\"width: 24px; height: 24px;\\"></div></div></div>"`;
exports[`Test: KInput > props: iconSuffix 1`] = `"<div class=\\"k-input k-input--base k-input--base__dark k-input--base__hover k-input--base__focus\\"> <input class=\\"k-input--inner k-input--inner__dark\\" placeholder=\\"\\"> <div role=\\"\\" aria-hidden=\\"true\\" class=\\"k-icon--base k-icon--base__dark k-input--icon\\"><div class=\\"i-carbon-search k-icon-transition \\" style=\\"width: 24px; height: 24px;\\"></div></div></div>"`;

exports[`Test: KInput > props: placeholder 1`] = `"<div class=\\"k-input--base k-input--base__dark k-input--base__hover k-input--base__focus \\"> <input class=\\"k-input--inner k-input--inner__dark \\" placeholder=\\"我见青山多妩媚,料青山见我应如是\\"> </div>"`;
exports[`Test: KInput > props: placeholder 1`] = `"<div class=\\"k-input k-input--base k-input--base__dark k-input--base__hover k-input--base__focus\\"> <input class=\\"k-input--inner k-input--inner__dark\\" placeholder=\\"我见青山多妩媚,料青山见我应如是\\"> </div>"`;

exports[`Test: KInput > props: value 1`] = `"<div class=\\"k-input--base k-input--base__dark k-input--base__hover k-input--base__focus \\"> <input class=\\"k-input--inner k-input--inner__dark \\" placeholder=\\"\\"> </div>"`;
exports[`Test: KInput > props: value 1`] = `"<div class=\\"k-input k-input--base k-input--base__dark k-input--base__hover k-input--base__focus\\"> <input class=\\"k-input--inner k-input--inner__dark\\" placeholder=\\"\\"> </div>"`;
8 changes: 8 additions & 0 deletions components/Input/__test__/input.bind.value.update.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
import KInput from '../src';

let value = '';
</script>

<KInput bind:value></KInput>
<span>{value}</span>
23 changes: 23 additions & 0 deletions components/Input/__test__/input.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { tick } from 'svelte';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { fireEvent } from '@testing-library/svelte';
import KInput from '../src';
import KInputSlots from './input.slots.svelte';
import KInputBindValueUpdate from './input.bind.value.update.svelte';

let host: HTMLElement;

Expand Down Expand Up @@ -257,4 +259,25 @@ describe('Test: KInput', () => {
expect(prefixElm).toBeTruthy();
expect(suffixElm).toBeTruthy();
});

test('props: bind value be updated in real time', async () => {
const instance = new KInputBindValueUpdate({
target: host
});
expect(instance).toBeTruthy();

const spanElm = host.querySelector('span');
expect(spanElm).toBeTruthy();
expect(spanElm?.textContent).toBe('');

const inputElm = host.querySelector('input');
expect(inputElm).toBeTruthy();

await fireEvent.input(inputElm, { target: { value: 'input change' } });
await tick();

expect(inputElm.value).toBe('input change');

expect(spanElm?.textContent).toBe('input change');
});
});
82 changes: 49 additions & 33 deletions components/Input/src/index.svelte
Original file line number Diff line number Diff line change
@@ -1,53 +1,71 @@
<script lang="ts">
import type { KInputProps } from './types';
import { createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
import { KIcon } from '@ikun-ui/icon';
export let iconPrefix = '';
export let iconSuffix = '';
export let value = '';
export let cls = '';
export let placeholder = '';
export let disabled = false;
export let attrs = {};
import { createCls, getPrefixCls } from '@ikun-ui/utils';

export let value: KInputProps['value'] = '';
export let placeholder: KInputProps['placeholder'] = '';
export let disabled: KInputProps['disabled'] = false;
export let iconPrefix: KInputProps['iconPrefix'] = '';
export let iconSuffix: KInputProps['iconSuffix'] = '';
export let cls: KInputProps['cls'] = '';
export let attrs: KInputProps['attrs'] = {};
/**
* @internal
*/
export let isError: boolean = false;
export let isError: KInputProps['isError'] = false;
/**
* @internal
*/
export let errorMsg: string = '';
export let errorMsg: KInputProps['errorMsg'] = '';

const dispatch = createEventDispatcher();
const onUpdated = (e: Event) => {

const onInput = (e: InputEvent) => {
if (disabled) return;
dispatch('input', (e.target as HTMLInputElement).value);
};

const onChange = (e: Event) => {
if (disabled) return;
dispatch('change', e);
};

const onEnter = (e: KeyboardEvent) => {
if (disabled) return;
if (e.key === 'Enter') dispatch('enter', e);
else dispatch('keydown', e);
};
const onChange = (e: Event) => {
if (disabled) return;
dispatch('change', e);
};
let valueInner = value;

// class names
const prefixCls = getPrefixCls('input');
$: baseCls = createCls(
prefixCls,
`${prefixCls}--base`,
`${prefixCls}--base__dark`,
{
[`${prefixCls}--base__disabled`]: disabled,
[`${prefixCls}--base__disabled__dark`]: disabled
},
{
[`${prefixCls}--base__error`]: isError,
[`${prefixCls}--base__hover`]: !isError,
[`${prefixCls}--base__focus`]: !isError
},
cls
);
$: errorMsgCls = createCls(`${prefixCls}--base__msg__error`);
$: inputCls = createCls(`${prefixCls}--inner`, `${prefixCls}--inner__dark`, {
[`${prefixCls}--base__disabled`]: disabled,
[`${prefixCls}--base__disabled__dark`]: disabled
});
</script>

<div
class="
k-input--base
k-input--base__dark
{disabled ? 'k-input--base__disabled k-input--base__disabled__dark' : ''}
{isError ? 'k-input--base__error' : 'k-input--base__hover k-input--base__focus'}
{cls}"
>
<div class={baseCls}>
{#if isError}
<span
out:fade={{ duration: 200 }}
in:fade={{ duration: 200 }}
class="k-input--base__msg__error"
>
<span class={errorMsgCls} transition:fade={{ duration: 200 }}>
{errorMsg}
</span>
{/if}
Expand All @@ -57,12 +75,10 @@
{/if}
</slot>
<input
class="k-input--inner k-input--inner__dark {disabled
? 'k-input--base__disabled k-input--base__disabled__dark'
: ''}"
bind:value={valueInner}
class={inputCls}
bind:value
{disabled}
on:input={onUpdated}
on:input={onInput}
on:change={onChange}
on:keydown={onEnter}
{placeholder}
Expand Down
11 changes: 11 additions & 0 deletions components/Input/src/types.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
/// <reference types="svelte" />
export type KInputProps = {
value: string;
placeholder: string;
disabled: boolean;
iconPrefix: string;
iconSuffix: string;
isError: boolean;
errorMsg: string;
cls: string;
attrs: Record<string, string>;
};
44 changes: 26 additions & 18 deletions play/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -63,29 +63,39 @@
const spinOptions = {
show: false,
text: 'loading...',
fullScreen: true
fullScreen: true
};


const handleToggleSpin = () => {
spinOptions.show = !spinOptions.show;
};


$: breadcrumbList = [
{ label: 'home', href: '/' },
{ label: 'breadcrumb', href: '' }
];
const addBreadcrumb = () => {
breadcrumbList.push({ label: 'test', href: '' });
breadcrumbList = breadcrumbList;
};
const delBreadcrumb = () => {
breadcrumbList.pop();
breadcrumbList = breadcrumbList;
};
$: breadcrumbList = [
{ label: 'home', href: '/' },
{ label: 'breadcrumb', href: '' }
];
const addBreadcrumb = () => {
breadcrumbList.push({ label: 'test', href: '' });
breadcrumbList = breadcrumbList;
};
const delBreadcrumb = () => {
breadcrumbList.pop();
breadcrumbList = breadcrumbList;
};
</script>

<div class="my-10px">
<div class="my-10px">KInput</div>
<KInput
bind:value={inputValue}
placeholder="inputValue"
iconPrefix="i-carbon-settings"
on:input={() => {
console.log('on:input =>', inputValue);
}}
></KInput>
</div>

<div class="my-10px">
<div class="mb-10px">Breadcrumb</div>
<KBreadcrumb separator="/">
Expand Down Expand Up @@ -140,8 +150,6 @@
<KButton type="primary" on:click={() => open()}>KEyeDropper</KButton>
</KEyeDropper>

<KInput value={inputValue} placeholder="inputValue" iconPrefix="i-carbon-settings"></KInput>

<KTooltip content="KTooltip - content" placement="bottom">
<KButton type="warning" slot="triggerEl">KTooltip - trigger</KButton>
</KTooltip>
Expand Down Expand Up @@ -214,4 +222,4 @@
<KButton on:click={handleToggleSpin}>ToggleSpin</KButton>
<div use:KSpin={spinOptions} class="w-200px h-50px bg-red"></div>

<KBacktop bottom="{100}" right="{100}" show-height="100"/>
<KBacktop bottom={100} right={100} show-height="100" />