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

Perhaps add JSDocs to the main autoComplete function? #228

Closed
folknor opened this issue May 29, 2021 · 8 comments
Closed

Perhaps add JSDocs to the main autoComplete function? #228

folknor opened this issue May 29, 2021 · 8 comments
Labels
enhancement New feature or request

Comments

@folknor
Copy link

folknor commented May 29, 2021

I'm not sure if this is useful for anyone else. I do not wish to have it added just for me.
I think maybe the whole API should change instead, but for the time being maybe this is helpful?

Below I just added a few of the config options for testing. You can see how it works.

  • =xxx is a default value.
  • [] means it's optional.
/**
 * @desc This is autoComplete.js
 * @version 10.0.0
 * @example const autoCompleteJS = new autoComplete({config});
 *
 * @param {Object} config - Configuration options
 * @param {string} [config.name=autoComplete] - Prepended to all created DOM element class names.
 * @param {(string|Function)} [config.selector=#autoComplete] - Must point to or return the relevant input field or element that autoComplete.js should act upon.
 * @param {Object} config.data - Data source.
 * @param {(Array|Function} config.data.src - An array of values to search or a async or immediate function that returns an array of values to search.
 * @param {string[]} [config.data.keys] - Only used if config.data.src is an array of objects. Specifies which keys in the objects autoComplete.js should search.
 * @param {boolean} [config.data.cache=false] - Whether or not autoComplete.js should cache results from config.data.src or not.
 * @param {Function} [config.data.filter] - A function used to filter the returns from config.data.src before showing them to the user. Function signature: (Array), is given the results from config.data.src.
 */
export default function autoComplete(config) {
...
}

If you want, I can write it all.

Do you think it would be useful to anyone, or is it a waste of time?

@folknor folknor added the enhancement New feature or request label May 29, 2021
@folknor
Copy link
Author

folknor commented May 29, 2021

@TarekRaafat
Copy link
Owner

I believe that would be very helpful to many, and please feel free to pull a PR with the finalized version of it.

I think maybe the whole API should change instead

What do you propose to be changed with the API?

@folknor
Copy link
Author

folknor commented May 30, 2021

Cool, I will write up a proposal for the JSDoc. I've not used autoComplete.js for that long, so I will probably make some mistakes in the docs. Feel free to edit as much as you want.

I will not make a PR, I'll just dump it here.

Regarding the API, it's a bit confusing right now. I believe autoComplete.js is an older project so I think it would be good to first take a look at what is necessary, and what is good to have, and what is just not needed.

For example, with my limited knowledge of the code, of what users use in the library, and with no knowledge of your projects history, I think these things can just simply be removed completely:

  1. config.name - This can be removed and this code can be changed to just remove "#" and other symbols from the .selector and use that instead
  ctx.selector = ctx.selector || "#" + name;
  resultsList.destination = resultsList.destination || ctx.selector;
  resultsList.id = resultsList.id || name + "_list_" + id;
  resultItem.id = resultItem.id || name + "_result";
  1. config.data.cache
  2. config.data.filter - people can just filter in config.data.src before returning
  3. config.placeHolder
  4. config.observe and the whole preInit concept
  5. the DOMContentLoaded / readyState check in init
  6. config.resultItem.highlight can just be a boolean, people can write their CSS to match it easily
  7. config.selector can just be a string, I don't understand why the option for a function is there
  8. config.resultItem.selected can be removed and just preconfigured to config.selector + "_selected"

But I am very ignorant and have a completely outside perspective. And there's probably other things that can be removed or simplified without hurting users that I've not seen yet.

Please don't think I'm attacking you or the code here, I am just trying to see how it can be made simpler and easier to use.

@folknor
Copy link
Author

folknor commented May 30, 2021

Here we go :-D Probably lots of mistakes in it, feel free to edit 👍

/**
 * @description Creates a new instance of autoComplete.js with the given configuration.
 * @version 10.1.1
 * @see {@link https://tarekraafat.github.io/autoComplete.js/#/configuration}
 * @example
 * const autoCompleteJS = new autoComplete({config});
 * @param {Object} config - Configuration options.
 * @param {string} [config.name=autoComplete] - Prepended to all created DOM element class names.
 * @param {(string|Function)} [config.selector=#autoComplete] - Must point to or return the relevant input field or element that autoComplete.js should act upon.
 * @param {Object} config.data - Data source.
 * @param {(Array|Function)} config.data.src - Values to search or an async or immediate function that returns an array of values to search.
 * @param {string[]} [config.data.keys] - Only used if config.data.src is an array of objects. Specifies which keys in the objects autoComplete.js should search.
 * @param {boolean} [config.data.cache=false] - If true, autoComplete.js fetches all config.data.src when initialized and never again.
 * @param {Function} [config.data.filter] - Used to filter returns from config.data.src before showing them to the user. Signature: (Array), is given the results from config.data.src.
 * @param {Function} [config.trigger] - Return true if you want autoComplete.js to start. Signature: (event, query). Default trigger function returns true if input field is *NOT* empty *and* greater than or equal to config.threshold.
 * @param {Function} [config.query] - For manipulating the input value before running the search, for example if you want to remove spaces or anything else. Signature: (string), must return string, is given the raw input value.
 * @param {string} [config.placeHolder] - Placeholder to set on the input element. For example "Search...".
 * @param {boolean} [config.observe=false] - Uses a mutation observer to listen for when an input element is added to the DOM that matches config.selector, then creates the autoComplete.js configuration for it and stops observing.
 * @param {Number} [config.threshold=1] - Minimum number of characters required in the input before triggering autocompletion.
 * @param {Number} [config.debounce=0] - Delay in milliseconds after input for autocompletion to start.
 * @param {boolean} [config.wrapper=1] - Wraps the input element in a div for a11y purposes, adding some ARIA attributes.
 * @param {(string|Function)} [config.searchEngine=strict] - "strict" checks if the given query is contained within the data, "loose" returns every result where every character in the query is present in the data in any order and location. Signature: (query: string, record: any), given the manipulated query input and each data.src array entry or for each entry[config.data.keys].
 * @param {boolean} [config.diacritics=false] - Enable to normalize query and data values using String.normalize and by removing u0300 through u036f. See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize}.
 * @param {(Object|boolean)} [config.resultsList] - false to disable result list rendering.
 * @param {string} [config.resultsList.tag=ul] - HTML tag to use for rendering the result container.
 * @param {string} [config.resultsList.id=autoComplete_list] - ID given to the result container.
 * @param {string} [config.resultsList.class] - Class names to give to the result container.
 * @param {(string|Function)} [config.resultsList.destination] - Selector that points to where you want to insert the result elements. Defaults to config.selector. Signature: ().
 * @param {string} [config.resultsList.position=afterend] - Position relative to config.selector where to insert the results list. See {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement#parameters}.
 * @param {Function} [config.resultsList.element] - Invoked before showing the results list. Allows manipulation of the DOM before it is added to the document. Signature: (list: HTMLElement, data: { query, matches, results }), where list is the container element.
 * @param {Number} [config.resultsList.maxResults=5] - Maximum number of results to render.
 * @param {boolean} [config.resultsList.tabSelect=false] - Allows the user to navigate the results list using Tab key. If disabled (as default), Tab key will close the list.
 * @param {boolean} [config.resultsList.noResults=false] - If enabled the results list will render when there are zero matches. For example if you want to show a custom message or help to the user in config.resultsList.element.
 * @param {Object} [config.resultItem] - Customize each rendered autocompletion result.
 * @param {string} [config.resultItem.tag=li] - HTML tag to use for rendering each result.
 * @param {string} [config.resultItem.id=autoComplete_result_index] - Prefix to use for the ID of each result element. _ and a number from 0 to maxResults is appended, so the final ID is for example "autoComplete_result_0" to "autoComplete_result_10".
 * @param {string} [config.resultItem.class] - Class names to give to each result element.
 * @param {Function} [config.resultItem.element] - Invoked before showing the results list. Allows manipulation of the DOM before it is added to the document. Signature: (item: HTMLElement, data: { match, value, [key] }).
 * @param {(boolean|string)} [config.resultItem.highlight=false] - Enable to highlight matching characters using HTMLMarkElement, or a string of CSS classes to add to any generated mark elements.
 * @param {string} [config.resultItem.selected] - CSS classes to add and remove from result items the user navigates to using the keyboard.
 * @param {Object} [config.events] - Allows adding custom or overriding internal event handling.
 * @param {Object} [config.events.input] - Maps event names to event handlers for the input element. Each key must be a valid event name, see {@link https://developer.mozilla.org/en-US/docs/Web/Events}, and each value must be an event handler function. Default handlers are keydown and blur.
 * @param {Object} [config.events.list] - Same as config.events.input, but for the result list container element. Default handlers are mousedown and click.
 */

@TarekRaafat
Copy link
Owner

Thanks a lot for your great efforts!

I highly appreciate constructive feedback like yours. It's essential for the library's healthy development.

I see you got good points, and I'll make sure to consider them, noting that I rely on this library for my personal projects, and I believe other people also do, which makes me kind of responsible for their experience as well.

Yet, please never stop sharing your kind feedback. It will always be more than welcome as long as it's constructive, and I'll make sure to accommodate them as much as possible.

Thanks again! :)

@folknor
Copy link
Author

folknor commented May 30, 2021

Thank you for listening.

I've updated my comment above now, I found some places where I forgot closing parantheses ) and I added text to config.observe, which previously said ??? :-D

Like I said, I think step one is to simplify - and there are a few good reasons for this; one is that it makes the library easier to use/understand for the first time, second is that there's less code to maintain, but more importantly for my thoughts it makes it easier to get a top down overview and the process of evaluating how the API surface might be improved in the future.

When I say "improve" API, I also mean so that it makes it easier for people to use. Not technically improving it. I don't care if it's a function, class, ES7, blah blah - the way it is set up currently I would describe it as a "magic object". It's just a tree of data, functions, and events that is hard to get a grip on when you first start using the library.

Modern editors provide so much help if the API is structured in such a way that they can help. With a "magic object", they don't help as effectively.

I hope that makes sense.

EDIT: And I'm not saying there is a "better" way of exposing the API. I'm just thinking that maybe there is, and starting by removing unneeded features would make it easier to do this evaluation. But of course I am a bad judge of what is unneeded and not because of my limited history with the code and project.

@folknor
Copy link
Author

folknor commented Jun 1, 2021

Updated with config.wrapper.

@TarekRaafat
Copy link
Owner

Many thanks! :)

@folknor folknor closed this as completed Jun 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants