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

Typescript support & typings, VS Code intellisense #205

Open
rallets opened this issue Jun 22, 2023 · 3 comments
Open

Typescript support & typings, VS Code intellisense #205

rallets opened this issue Jun 22, 2023 · 3 comments

Comments

@rallets
Copy link

rallets commented Jun 22, 2023

Hi, I have seen in another issue that you are not interested in releasing a strongly typed version of this component.
So - for who is interested - I have a repo showing one possible solution, using module augmentation and SvelteComponentTyped that supports attributes, events and slots. In this way you get VS code autocompletion and intellisense.

The typings are not comprehensive of all the functionalities, but it could be a good starting point for someone who want to extend it.
It could be also a good example for similar issues with Svelte components.

The interesting part is in this file:
simple-svelte-autocomplete.d.ts

Here you can find the related Svelte language-tools issue

@rallets
Copy link
Author

rallets commented Jun 24, 2023

note that from Svelte 4 SvelteComponentTyped should be renamed in SvelteComponent. No other changes are required.
see: v4-migration-guide

@Astronautilus14
Copy link

Astronautilus14 commented Feb 5, 2024

Here is an updated type with all supported attributes mentioned in the readme

declare module 'simple-svelte-autocomplete' {
	import type { SvelteComponent } from 'svelte';

	export interface AutoCompleteProps<T>
		extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap['div']> {
		items: T[];
		searchFunction?: () => Promise<T[]>;
		delay?: number;
		localFiltering?: boolean;
		localSorting?: boolean;
		cleanUserText?: boolean;
		multiple?: boolean;
		orderableSection?: boolean;
		selectedItem?: T;
		highlightedItem?: T;
		labelFieldName?: string;
		keywordsFieldName?: string;
		value: T;
		valueFieldName?: string;
		labelFunction?: (a: T) => string;
		keywordsFunction?: (a: T) => string;
		valueFunction?: (a: T) => string;
		keywordsCleanFunction?: (string) => string;
		lowercaseKeywords?: boolean;
		textCleanFunction?: (string) => string;
		selectFirstIfEmpty?: boolean;
		minCharactersToSearch?: number;
		maxItemsToShowInList?: number;
		ignoreAccents?: boolean;
		matchAllKeywords?: boolean;
		sortByMatchedKeywords?: boolean;
		itemSortFunction?: (a: T, b: T) => number;
		itemFilterFunction?: (a: T, string) => boolean;
		disabled?: boolean;
		readonly?: boolean;
		lock?: boolean;
		create?: boolean;
		closeOnBlur?: boolean;
		flag?: boolean;

		placeholder?: string;
		noResultsText?: string;
		moreItemsText?: string;
		createText?: string;
		hideArrow?: boolean;
		showClear?: boolean;
		showLoadingIndicator?: boolean;

		className?: string;
		inputClassName?: string;
		noInputClassName?: boolean;
		inputId?: string;
		dropdownClassName?: string;
		name?: string;
		html5autocomplete?: boolean;
		autocompleteOffValue?: string;
		selectName?: string;
		required?: boolean;
		tabIndex?: number;
	}

	export interface AutoCompleteEvents {
		beforeSearch: (oldSelectedItem: T, newSelectedItem: T) => any;
		onChange: (newSelectedItem: T) => any;
		onFocus: () => any;
		onBlur: () => any;
		onCreate: (text: string) => any;
	}

	export default class AutoComplete extends SvelteComponent<
		AutoCompleteProps<T>,
		AutoCompleteEvents,
		{
			item: { item: T };
			'no-results': null;
		}
	> {}
}

@rallets
Copy link
Author

rallets commented Feb 22, 2024

Hi @Astronautilus14 thanks for the improvements! I had the time to check your typings and found that this component doesn't emits events, but it just uses callbacks. So your definition is not correct. To make easier to sync all the attributes, I sorted them by name and split in categories. I did also add some more slots and fixed some parameters here and there. I hope this helps.

/* NB: you cannot have a import or export on top of this file, otherwise it will not work. */
declare module 'simple-svelte-autocomplete' {
    import { SvelteComponent } from 'svelte';

    export interface AutoCompleteAttributes<T>
        extends svelte.JSX.HTMLAttributes<HTMLElementTagNameMap['div']> {
        autocompleteOffValue?: string;
        className?: string;
        cleanUserText?: boolean;
        closeOnBlur?: boolean;
        create?: boolean;
        createText?: string;
        delay?: number;
        disabled?: boolean;
        dropdownClassName?: string;
        flag?: boolean;
        hideArrow?: boolean;
        highlightedItem?: T;
        html5autocomplete?: boolean;
        ignoreAccents?: boolean;
        inputClassName?: string;
        inputId?: string;
        items: T[];
        keywordsFieldName?: string;
        labelFieldName?: string;
        localFiltering?: boolean;
        localSorting?: boolean;
        lock?: boolean;
        lowercaseKeywords?: boolean;
        matchAllKeywords?: boolean;
        maxItemsToShowInList?: number;
        minCharactersToSearch?: number;
        moreItemsText?: string;
        multiple?: boolean;
        name?: string;
        noInputClassName?: boolean;
        noInputStyles?: boolean;
        noResultsText?: string;
        orderableSection?: boolean;
        placeholder?: string;
        readonly?: boolean;
        required?: boolean;
        selectFirstIfEmpty?: boolean;
        selectName?: string;
        selectedItem?: T;
        showClear?: boolean;
        showLoadingIndicator?: boolean;
        sortByMatchedKeywords?: boolean;
        tabIndex?: number;
        value?: T;
        valueFieldName?: string;
    }

    export interface AutoCompleteFunctions<T> {
        itemFilterFunction?: (item: T, keywords: string) => boolean;
        itemSortFunction?: (item1: T, item2: T, keywords: string) => number;
        keywordsCleanFunction?: (keywords: string) => string;
        keywordsFunction?: (item: T) => string;
        labelFunction?: (item: T) => string;
        searchFunction?: (keyword: string, maxItemsToShowInList: number) => Promise<T[]> | boolean;
        textCleanFunction?: (string) => string;
        valueFunction?: (a: T) => string;
    }

    export interface AutoCompleteCallbacks<T> {
        beforeChange?: (oldSelectedItem: T, newSelectedItem: T) => boolean;
        onChange?: (newSelectedItem: T) => void,
        onFocus?: () => void;
        onBlur?: () => void;
        onCreate?: (text: string) => void;
    }

    export interface AutoCompleteSlots<T> {
        'item': { item: T, label: string },
        'no-results': null,
        'loading': { loadingText: string },
        'tag': null,
        'dropdown-header': { nbItems: number, maxItemsToShowInList: number },
        'dropdown-footer': { nbItems: number, maxItemsToShowInList: number }
    }

    export interface AutoCompleteProps<T> extends AutoCompleteAttributes<T>, AutoCompleteCallbacks<T>, AutoCompleteFunctions<T> { }

    export default class AutoComplete extends SvelteComponent<AutoCompleteProps<T>, undefined, AutoCompleteSlots<T>> { }
}

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

No branches or pull requests

2 participants