{"id":28959669,"url":"https://github.com/seawind543/react-token-input","last_synced_at":"2025-06-24T00:03:34.372Z","repository":{"id":32873468,"uuid":"144865042","full_name":"seawind543/react-token-input","owner":"seawind543","description":"A react token (tag) input component. Allow customize data structure and Look \u0026 Feel","archived":false,"fork":false,"pushed_at":"2025-06-06T23:45:16.000Z","size":11159,"stargazers_count":33,"open_issues_count":6,"forks_count":7,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-16T20:07:13.519Z","etag":null,"topics":["customize","customize-data-structure","customize-render-functions","inline-edit","input","paste","preprocesss","react","react-component","react-customize-token-input","react-token-input","tag","tag-input","token-input"],"latest_commit_sha":null,"homepage":"https://seawind543.github.io/react-token-input/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seawind543.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-15T14:41:06.000Z","updated_at":"2025-06-11T07:39:47.000Z","dependencies_parsed_at":"2024-01-31T18:50:51.042Z","dependency_job_id":"63046fec-0972-407b-aef3-25de4052d40f","html_url":"https://github.com/seawind543/react-token-input","commit_stats":{"total_commits":198,"total_committers":3,"mean_commits":66.0,"dds":0.06565656565656564,"last_synced_commit":"33dc6c4ca50208ad5ddc0ee539b08be0ed94b67f"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/seawind543/react-token-input","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seawind543%2Freact-token-input","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seawind543%2Freact-token-input/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seawind543%2Freact-token-input/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seawind543%2Freact-token-input/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seawind543","download_url":"https://codeload.github.com/seawind543/react-token-input/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seawind543%2Freact-token-input/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261578042,"owners_count":23179768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["customize","customize-data-structure","customize-render-functions","inline-edit","input","paste","preprocesss","react","react-component","react-customize-token-input","react-token-input","tag","tag-input","token-input"],"created_at":"2025-06-24T00:03:33.634Z","updated_at":"2025-06-24T00:03:34.363Z","avatar_url":"https://github.com/seawind543.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React TokenInput [![build status](https://travis-ci.org/seawind543/react-token-input.svg?branch=master)](https://travis-ci.org/seawind543/react-token-input) [![Coverage Status](https://coveralls.io/repos/github/seawind543/react-token-input/badge.svg?branch=master)](https://coveralls.io/github/seawind543/react-token-input?branch=master)\n\n[![NPM](https://nodei.co/npm/react-customize-token-input.png?downloads=true\u0026stars=true)](https://www.npmjs.com/package/react-customize-token-input/)\n\nLive Demo: https://seawind543.github.io/react-token-input/\n\nReact TokenInput (react-customize-token-input)\n\nA react token (tag) `controlled` input component, which support:\n\n- Accept **customize data structure**.\n- **Customize token (tag) Look \u0026 Feel** on the `label` [Demo](https://seawind543.github.io/react-token-input/#example-customize-label), `delete button` [Demo](https://seawind543.github.io/react-token-input/#example-customize-delete-button), or even override `the whole Token component` [Demo](https://seawind543.github.io/react-token-input/#example-customize-token-component).\n- Customize **separate characters** to separate the end-user input string. [Demo](https://seawind543.github.io/react-token-input/#example-customize-separators)\n- **Inline editing** on exist token.\n- **Paste** values. [Demo](https://seawind543.github.io/react-token-input/#example-customize-separators)\n- **Preprocessing** function to **normalized** user input value.\nIt could be helpful to reproduce a single value into multiple values too. [Demo](https://seawind543.github.io/react-token-input/#example-preprocess)\n- **Validate** function.\n\n## Installation\n\n1. Install the latest version of [react](https://github.com/facebook/react) and [react-customize-token-input](https://github.com/seawind543/react-token-input):\n\n  ```\n  yarn add react react-customize-token-input\n  ```\n\n2. At this point you can import `react-customize-token-input` and its styles in your application by:\n\n  ```JavaScript\n  import TokenInput from 'react-customize-token-input';\n\n  // Be sure to include styles at some point, probably during your bootstraping\n  import 'react-customize-token-input/dist/react-customize-token-input.css';\n\n  // Could find the not minimize version to easily customize style from:\n  // 'react-customize-token-input/dist/react-customize-token-input.original.css';\n  ```\n\n## Dev\n\n1. Run `yarn install` to install required packages.\n2. Run `yarn dev` to launch `webpack-dev-server`.\n3. After step 2, you will see following message output in command console.\n\n```\n｢wds｣: Project is running at http://0.0.0.0:8000/\n｢wds｣: webpack output is served from /\n｢wds｣: Content not from webpack is served from ../docs\n```\n\n\u003e Note: To stop the program, just type ```ctrl + c``` in command console.\n\n4. After step 3 complete, you could access `http://localhost:8000/` to see result.\n\n## Usage\n\nSee Live Examples: https://seawind543.github.io/react-token-input/\n\nNote: Sources code of Examples in the folder `examples/`\n\n## Props\n\n```JavaScript\n/**\n * @template VT, ET\n * @typedef {Object} TokenInputProps\n */\ninterface TokenInputProps\u003cVT = string, ET = string\u003e {\n  /**\n   * @prop {CSSProperties} [style]\n   * @description An optional prop, for assigning style to TokenInput\n   */\n  style?: CSSProperties;\n\n  /**\n   * @prop {string} [className]\n   * @description An optional prop, for assigning class name to TokenInput\n   */\n  className?: string;\n\n  /**\n   * @prop {string} [placeholder]\n   * @description An optional prop, for assigning placeholder to TokenInput\n   */\n  placeholder?: string;\n\n  /**\n   * @prop {boolean} [readOnly = false]\n   * @description An optional prop, to control TokenInput is `readOnly mode`\n   */\n  readOnly?: boolean;\n\n  /**\n   * @prop {boolean} [disableCreateOnBlur]\n   * @description An optional prop, to control TokenInput creates a new token when blurring on the creator\n   */\n  disableCreateOnBlur?: boolean;\n\n  /**\n   * @prop {boolean} [autoFocus = false]\n   * @description\n   * An optional prop, to control TokenInput is `autoFocus mode`.\n   * Will be deprecated in the next major release. Took ref.current.focus() instead.\n   */\n  autoFocus?: boolean;\n\n  /**\n   * @template VT\n   * @prop {VT[]} tokenValues\n   * @description\n   * The array of tokenValue of TokenInput.\n   * This array will be used to render the tokens.\n   *\n   * Type: VT\n   * Description:\n   * Customize data structure data\n   * Could be string | number | object | customized data structure...etc.\n   */\n  tokenValues: VT[];\n\n  // TokenCreator props\n\n  /**\n   * @prop {TokenSeparator[]} [separators]\n   * @description\n   * An array of characters to split the user input string into array.\n   * For example,\n   * Split the user input string `abc;def` into `['abc', 'def']`\n   * by separators `[';']`\n   *\n   * @see {@link TokenSeparator}\n   * Note:\n   * It take the `String.prototype.split(separators.join('|'))`\n   * and `RegExp` to split the user input string.\n   * \n   * @example\n   * ```js\n   * value.split(separators.join('|'));\n   * ```\n   *\n   * Make sure your customized separators could be used with\n   * (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp)[`RegExp`]}.\n   */\n  separators?: TokenSeparator[];\n\n\n  /**\n   * @prop {SpecialKeyDownConfig} [specialKeyDown=DEFAULT_SPECIAL_KEY_DOWN_CONFIG]\n   * @description\n   * [Beta; Might be change in the future version]\n   * Current only apply to the `TokenCreator`\n   *\n   * The settings to control the behavior of specials keyDown's event handler.\n   * Recommend to use the built-in constant `KEY_DOWN_HANDLER_CONFIG_OPTION` to config the setting.\n   *\n   * @see KEY_DOWN_HANDLER_CONFIG_OPTION for the accepted config values\n   * @see DEFAULT_SPECIAL_KEY_DOWN_CONFIG for the default settings\n   */\n  specialKeyDown?: SpecialKeyDownConfig;\n\n  /**\n   * @prop {OnInputValueChange} [onInputValueChange]\n   * @description\n   * A callback function invoked when end-user typing but not become token yet\n   *\n   * @example\n   * ```js\n   * onInputValueChange(newValue, previousValue)\n   * ```\n   *\n   * @param {InputString} newValue\n   * The end-user's input string\n   *\n   * @param {InputString} previousValue\n   * The previous input string\n   *\n   * @returns {void}\n   */\n  onInputValueChange?: OnInputValueChange;\n\n  /**\n   * @prop {OnPreprocess} [onPreprocess]\n   * @description\n   * A callback function to `preprocessing` the user input string.\n   *\n   * Note: This function execute after `split by TokenSeparator[]` but before `onBuildTokenValue`\n   * inputString -\u003e spilt(inputString) -\u003e preprocess(spilt(inputString)) -\u003e onBuildTokenValue(preprocess(spilt(inputString)))\n   *\n   * [Use case 1]\n   *  Make your normalize process in this function, such as `String.prototype.trim()`.\n   *\n   * [Use case 2]\n   * Sometimes, we will want to auto-fit the user input, this function could help with it.\n   * For example, the user input string is `www.google.com`,\n   * and we want to auto-fit it into `http://www.google.com` and `https://www.google.com`.\n   *\n   * @example\n   * ```js\n   * onPreprocess(inputStringValues)\n   * ```\n   *\n   * @param {InputString[]} inputStringValues\n   * The user input string values\n   * (An array of string, which split from the original input string via the `separators`)\n   *\n   * @returns {InputString[]}\n   * An array of string\n   */\n  onPreprocess?: OnPreprocess;\n\n  /**\n   * @template VT, ET\n   * @prop {OnTokenValueValidate\u003cVT, ET\u003e} [onTokenValueValidate=defaultTokenValueValidate]\n   * @description\n   * A callback function to validate a tokenValue\n   * (The returned result will be set into the TokenMeta \u0026 pass to `onGetTokenErrorMessage`)\n   *\n   * @example\n   * ```js\n   * onTokenValueValidate(tokenValue, index, tokenValues)\n   * ```\n   *\n   * @param {VT} tokenValue\n   * The tokenValue built by `onBuildTokenValue`\n   *\n   * @param {Index} index\n   * The array index of this tokenValue in tokenValues\n   *\n   * @param {VT[]} tokenValues\n   * The array of tokenValue of TokenInput\n   *\n   * @returns {TokenMeta\u003cET\u003e['error']}\n   * The customized error.\n   * Specific the token's validate status or errorMessage.\n   * Could be `an error message` to display, or an error object for further operations.\n   *\n   * @see TokenMeta for more information about TokenMeta\u003cET\u003e['error']\n   *\n   * Note: Return `Nullish` types means the token is valid.\n   * @see Nullish\n   */\n  onTokenValueValidate?: OnTokenValueValidate\u003cVT, ET\u003e;\n\n  // Token related props\n\n  /**\n   * @template VT\n   * @prop {OnTokenValuesChange\u003cVT\u003e} [onTokenValuesChange]\n   * @description\n   * A callback function invoked when tokenValues update\n   *\n   * @example\n   * ```js\n   * onTokenValuesChange(modifiedTokenValues)\n   * ```\n   *\n   * @param {VT[]} modifiedTokenValues\n   * The new tokenValues\n   *\n   * @returns {void}\n   */\n  onTokenValuesChange?: OnTokenValuesChange\u003cVT\u003e;\n\n  /**\n   * @template VT\n   * @prop {OnBuildTokenValue\u003cVT\u003e} [onBuildTokenValue=defaultBuildTokenValue]\n   * @description\n   * A callback function to build `user input string value` into\n   * the `tokenValue` (customized data structure).\n   *\n   * Note: You could make your normalize process in this function too.\n   *\n   * @example\n   * ```js\n   * onBuildTokenValue(inputString)\n   * ```\n   *\n   * @param {InputString} inputString\n   * The user input value // (A value split by TokenSeparator[])\n   * Example:\n   * - Input string \"ABC, DEF\" and separators is `,`\n   * - The `onBuildTokenValue` will be called twice as\n   * ```\n   * onBuildTokenValue('ABC') and onBuildTokenValue('DEF')\n   * ```\n   *\n   * @returns {VT}\n   * The customized data structure data\n   * Could be string | number | object | customized data structure...etc.\n   */\n  onBuildTokenValue?: OnBuildTokenValue\u003cVT\u003e;\n\n  /**\n   * @prop {Component} [customizeTokenComponent]\n   * A customize react component to rendering a token\n   * Apply this to customize all token function.\n   *\n   * @example\n   * ```js\n   * customizeTokenComponent={MyToken}\n   * ```\n   *\n   * @returns {ReactElement | null}\n   */\n  customizeTokenComponent?: (\n    props: TokenProps\u003cVT, ET\u003e\n  ) =\u003e ReactElement | null;\n\n  /**\n   * @template VT, ET\n   * @prop {OnGetTokenClassName\u003cVT, ET\u003e} [onGetTokenClassName]\n   * @description\n   * A callback function to getting customizes `className` to set on a `token`\n   *\n   * ```js\n   * onGetTokenClassName(tokenValue, tokenMeta)\n   * ```\n   *\n   * @param {VT} tokenValue\n   * The tokenValue built by `onBuildTokenValue`\n   *\n   * @param {TokenMeta\u003cET\u003e} tokenMeta\n   * The token's meta data\n   *\n   * @returns {undefined | string}\n   * The customizes className\n   */\n  onGetTokenClassName?: OnGetTokenClassName\u003cVT, ET\u003e;\n\n  /**\n   * @template VT, ET\n   * @prop  {OnGetTokenDisplayLabel\u003cVT, ET\u003e} [onGetTokenDisplayLabel=defaultGetTokenEditableValue]\n   * @description\n   * A callback function to getting displayable `label` of a token\n   * Apply this to customize the token's content\n   * For example, render token with `icon` or `Additional text`\n   *\n   * @example\n   * ```js\n   * onGetTokenDisplayLabel(tokenValue, tokenMeta)\n   * ```\n   *\n   * @param {VT} tokenValue\n   * The tokenValue built by `onBuildTokenValue`\n   *\n   * @param {TokenMeta\u003cET\u003e} tokenMeta\n   * The token's meta data\n   *\n   * @returns {InputString | ReactNode}\n   * The token's display content.\n   */\n  onGetTokenDisplayLabel?: OnGetTokenDisplayLabel\u003cVT, ET\u003e;\n\n  /**\n   * @prop {OnRenderTokenDeleteButtonContent} [onRenderTokenDeleteButtonContent]\n   * @description\n   * A callback function to render content of the delete button of token\n   * Apply this to customize the token's content of the delete button.\n   * For example, replace the built-in `x` by Google font material-icons\n   *\n   * @example\n   * ```js\n   * onRenderTokenDeleteButtonContent()\n   * ```\n   *\n   * @returns {ReactNode}\n   * The content of the delete button of the token.\n   * By default, TokenInput render a built-in `x` icon\n   */\n  onRenderTokenDeleteButtonContent?: OnRenderTokenDeleteButtonContent;\n\n  /**\n   * @template VT, ET\n   * @prop {OnGetIsTokenEditable\u003cVT, ET\u003e} [onGetIsTokenEditable=defaultGetIsTokenEditable]\n   * @description\n   * A callback function to determine whether the token is `inline editable`.\n   *\n   * @example\n   * ```js\n   * onGetIsTokenEditable(tokenValue, tokenMeta)\n   * ```\n   *\n   * @param {VT} tokenValue\n   * The tokenValue built by `onBuildTokenValue`\n   *\n   * @param {TokenMeta\u003cET\u003e} tokenMeta\n   * The token's meta data\n   *\n   * @returns {boolean}\n   * - `true`: Editable.\n   * - `false`: Not editable.\n   */\n  onGetIsTokenEditable?: OnGetIsTokenEditable\u003cVT, ET\u003e;\n\n  /**\n   * @template VT, ET\n   * @prop {OnGetTokenEditableValue\u003cVT, ET\u003e} [onGetTokenEditableValue=defaultGetTokenEditableValue]\n   * @description\n   * A callback function to getting `string input value`\n   * from `tokenValue` for the end-user to perform `inline edit`\n   *\n   * @example\n   * ```js\n   * onGetTokenEditableValue(tokenValue, tokenMeta)\n   * ```\n   *\n   * @param {VT} tokenValue\n   * The tokenValue built by `onBuildTokenValue`\n   *\n   * @param {TokenMeta\u003cET\u003e} tokenMeta\n   * The token's meta data\n   *\n   * @returns {InputString}\n   * The value for end-user to `edit` in an input field\n   */\n  onGetTokenEditableValue?: OnGetTokenEditableValue\u003cVT, ET\u003e;\n\n  /**\n   * @template VT, ET\n   * @prop {OnGetTokenErrorMessage\u003cVT, ET\u003e} [onGetTokenErrorMessage=defaultGetTokenErrorMessage]\n   * @description\n   * A callback function to getting the `Error Message` to\n   * apply into the `title` attribute of the built-in Token Component\n   *\n   * @example\n   * ```js\n   * onGetTokenErrorMessage(tokenValue, tokenMeta)\n   * ```\n   *\n   * @param {VT} tokenValue\n   * The tokenValue built by `onBuildTokenValue`\n   *\n   * @param {TokenMeta\u003cET\u003e} tokenMeta\n   * The token's meta data\n   *\n   * @returns {string | Nullish}\n   * The `Error Message` of the token.\n   * Return `string type` will let the built-in Token component apply the message\n   * into the `title` attribute. Otherwise, will simply be ignored\n   */\n  onGetTokenErrorMessage?: OnGetTokenErrorMessage\u003cVT, ET\u003e;\n\n  /**\n   * @prop {React.FocusEventHandler\u003cHTMLInputElement\u003e} [onCreatorFocus]\n   * @description\n   * A callback function invoked on TokenCreator focused\n   *\n   * @example\n   * ```js\n   * onCreatorFocus(e)\n   * ```\n   *\n   * @param {React.FocusEvent\u003cHTMLInputElement\u003e} event\n   * The FocusEvent of the input of TokenCreator\n   *\n   * @returns {void}\n   */\n  onCreatorFocus?: React.FocusEventHandler\u003cHTMLInputElement\u003e;\n\n  /**\n   * @prop {React.FocusEventHandler\u003cHTMLInputElement\u003e} [onCreatorBlur]\n   * @description\n   * A callback function invoked on TokenCreator blur\n   *\n   * @example\n   * ```js\n   * onCreatorBlur(e)\n   * ```\n   *\n   * @param {React.FocusEvent\u003cHTMLInputElement\u003e} event\n   * The FocusEvent of the input of TokenCreator\n   *\n   * @returns {void}\n   */\n  onCreatorBlur?: React.FocusEventHandler\u003cHTMLInputElement\u003e;\n\n  /**\n   * @prop {React.KeyboardEventHandler\u003cHTMLInputElement\u003e} [onCreatorKeyDown]\n   * @description\n   * A callback function invoked when keyDown on TokenCreator\n   *\n   * @example\n   * ```js\n   * onCreatorKeyDown(e)\n   * ```\n   *\n   * @param {React.KeyboardEvent\u003cHTMLInputElement\u003e} event\n   * The KeyboardEvent of the input of TokenCreator\n   *\n   * @returns {void}\n   */\n  onCreatorKeyDown?: React.KeyboardEventHandler\u003cHTMLInputElement\u003e;\n}\n```\n\n## Methods in ref of TokenInput\n\nTokenInput provide the following method in the ref of it.\n\nMethod     | Description   | Parameter     | Return\n---------- | :------------ | :------------ | :------------\nfocus  | Set focus on TokenInput. It will focus on the creator not the inline-editor | Same as [HTMLElement.focus()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) | void |\nsetCreatorValue  | Set value of TokenCreator | value: string | void\ngetCreatorValue  | Get value of TokenCreator | void          | string\ncreateTokens     | Trigger tokens create. If param.value undefined, then apply the value of TokenCreator directly.    | value?: string | void\n\nCould reference [Demo](https://seawind543.github.io/react-token-input/#example-ref-methods), and its source code `ExampleRefMethods` in the folder `examples/`.\n\nIf you are using TypeScript, reference the code below for the typing of useRef.\n\n```TypeScript\nimport TokenInput, { type TokenInputRef } from 'react-customize-token-input';\nconst tokenInputRef = useRef\u003cTokenInputRef\u003e(null);\n// ... omit\nconst handleFocusButtonClick = () =\u003e {\n  tokenInputRef.current?.focus();\n}\n// ... omit\n\u003cTokenInput\n  ref={tokenInputRef}\n  tokenValues={values}\n  onTokenValuesChange={setValues}\n/\u003e\n```\n\n## Predefined KeyDown Event Handlers\n\nTokenInput has the following **Predefined** KeyDown event handlers.\n\n### For Token Create\n\nKeyDown    | Description   | Note\n---------- | :------------ | :---\nBackspace  | In case the current inputValue is an `empty string`, the latest **token** in the list tail will be deleted. |\nEscape     | Clear the input-box's value. | A.K.A. Reset.\nEnter      | Create a token with the inputValue and continually focused on the inputBox for the next inputting. |\nTab  | Same as onEnter.  | \u003cul\u003e \u003cli\u003eDefault not apply\u003c/li\u003e \u003cli\u003eUnder Beta\u003c/li\u003e \u003c/ul\u003e\n\n### For Inline editing\n\nKeyDown    | Description | Note\n---------- | :---------- | :---\nEscape     | End editing without change the value of the token. | A.K.A. Reset\nEnter      | End editing and apply the new value. In case the new value is an `empty string`, will perform the `onEscape`. |\n\n## Default value of the optional Props\n\n```JavaScript\n    style = undefined,\n    className = undefined,\n    placeholder = undefined,\n    readOnly = false,\n    disableCreateOnBlur = undefined,\n    autoFocus = false,\n\n    // TokenCreator\n    separators = DEFAULT_SEPARATORS,\n    /*\n    [\n      ',',\n      ';',\n      '\\n', // for copy and paste\n      '\\r', // for copy and paste\n      '\\r\\n', // for copy and paste\n    ];\n    */\n\n    specialKeyDown = DEFAULT_SPECIAL_KEY_DOWN_CONFIG,\n    /*\n    {\n      onBackspace: KEY_DOWN_HANDLER_CONFIG_OPTION.ON,\n      onTab: KEY_DOWN_HANDLER_CONFIG_OPTION.OFF,\n      onEnter: KEY_DOWN_HANDLER_CONFIG_OPTION.ON,\n      onEscape: KEY_DOWN_HANDLER_CONFIG_OPTION.ON,\n    },\n    */\n\n    onInputValueChange = undefined,\n    onPreprocess = undefined,\n\n    onTokenValueValidate = defaultTokenValueValidate,\n\n    onTokenValuesChange = undefined,\n\n    // Token\n    onBuildTokenValue = defaultBuildTokenValue,\n\n    customizeTokenComponent = undefined,\n    onGetTokenClassName = undefined,\n\n    onGetTokenDisplayLabel = defaultGetTokenEditableValue,\n\n    onRenderTokenDeleteButtonContent = undefined,\n\n    onGetIsTokenEditable = defaultGetIsTokenEditable,\n    onGetTokenEditableValue = defaultGetTokenEditableValue,\n    onGetTokenErrorMessage = defaultGetTokenErrorMessage,\n```\n\n## Props of customizeTokenComponent\n\nYour CustomizeTokenComponent will receive these props from TokenInput. You could decide where \u0026 how to use them to `customize` your Token component.\n\nCould also reference this [Demo](https://seawind543.github.io/react-token-input/#example-customize-token-component) and its source code `ExampleCustomizeToken` in the folder `examples/`.\n\n```JavaScript\n/**\n * @template VT, ET\n * @typedef {Object} TokenProps\n */\nexport interface TokenProps\u003cVT = string, ET = string\u003e {\n  /**\n   * @property {boolean} readOnly\n   * @description\n   * Same as TokenInputProps {@see 'TokenInputProps['readOnly']}\n   */\n  readOnly: boolean;\n\n  /**\n   * @type {VT}\n   * @description This token's tokenValue\n   */\n  tokenValue: VT;\n  /**\n   * @template ET\n   * @type {TokenMeta\u003cET\u003e} tokenMeta\n   * @description This token's meta data\n   */\n  tokenMeta: TokenMeta\u003cET\u003e;\n\n  /**\n   * @template VT, ET\n   * @prop {OnGetTokenClassName\u003cVT, ET\u003e} [onGetClassName]\n   * @description\n   * Same as TokenInputProps {@see TokenInputProps['onGetTokenClassName']}\n   */\n  onGetClassName?: OnGetTokenClassName\u003cVT, ET\u003e;\n\n  /**\n   * @template VT, ET\n   * @prop  {OnGetTokenDisplayLabel\u003cVT, ET\u003e} [onGetTokenDisplayLabel=defaultGetTokenEditableValue]\n   * @description\n   * Same as TokenInputProps {@see TokenInputProps['onGetTokenDisplayLabel']}\n   */\n  onGetDisplayLabel: OnGetTokenDisplayLabel\u003cVT, ET\u003e;\n\n  /**\n   * @callback OnRenderTokenDeleteButtonContent\n   * @description\n   * Same as TokenInputProps {@see TokenInputProps['onRenderTokenDeleteButtonContent']}\n   */\n  onRenderDeleteButtonContent?: OnRenderTokenDeleteButtonContent;\n\n  /**\n   * @template VT, ET\n   * @callback OnGetIsTokenEditable\n   * @description\n   * Same as TokenInputProps {@see TokenInputProps['onGetIsTokenEditable']}\n   */\n  onGetIsEditable: OnGetIsTokenEditable\u003cVT, ET\u003e;\n\n  /**\n   * @template VT, ET\n   * @callback OnGetTokenEditableValue\n   * @description\n   * Same as TokenInputProps {@see TokenInputProps['onGetTokenEditableValue']}\n   */\n  onGetEditableValue: OnGetTokenEditableValue\u003cVT, ET\u003e;\n\n  /**\n   * @template VT\n   * @callback OnBuildTokenValue\n   * @description\n   * Same as TokenInputProps {@see TokenInputProps['onBuildTokenValue']}\n   */\n  onBuildTokenValue: OnBuildTokenValue\u003cVT\u003e;\n\n  /**\n   * @template VT, ET\n   * @callback OnGetTokenErrorMessage\n   * @description\n   * Same as TokenInputProps {@see TokenInputProps['onGetTokenErrorMessage']}\n   */\n  onGetErrorMessage: OnGetTokenErrorMessage\u003cVT, ET\u003e;\n\n  /**\n   * @callback\n   * @description\n   * A callback function, which you should `call`\n   * when the end-user `start editing`\n   *\n   * Note:\n   * Call this function to tell TokenInput it is start to editing the token.\n   * As result, TokenInput will set `tokenMeta.activate` to `true`\n   *\n   * @example\n   * ```js\n   * onEditStart()\n   * ```\n   *\n   * @returns {void}\n   */\n  onEditStart: () =\u003e void;\n\n  /**\n   * @callback\n   * @description\n   * A callback function, which you should `call`\n   * when end-user `end the edit`\n   *\n   * Note:\n   * Call this function to tell TokenInput to finish the `editing` of the token.\n   * As result, TokenInput will set `tokenMeta.activate` to `false`.\n   *\n   * Also, TokenInput will based on the value of the parameter newTokenValue to\n   * update the tokenValue of the token,\n   * and call the callback `onTokenValuesChange`\n   *\n   * @example\n   * ```js\n   * onEditEnd(newTokenValue);\n   * // or\n   * onEditEnd();\n   * ```\n   *\n   * @param {VT} [newTokenValue]\n   * The new tokenValue built by `onBuildTokenValue.\n   *\n   * Note:\n   * if `newTokenValue` is `undefined`,\n   * TokenInput will treat as `Cancel` (Edit will end without update the tokenValue).\n   * The callback `onTokenValuesChange` will also not be called.\n   *\n   * @returns {void}\n   */\n  onEditEnd: (newTokenValue?: VT) =\u003e void;\n\n  /**\n   * @callback\n   * @description\n   * A callback function, which you should `call`\n   * when the end-user `delete` the token\n   *\n   * Note:\n   * Call this function to tell TokenInput to delete the token.\n   * As result, TokenInput will remove the token,\n   * and call `onTokenValuesChange` to update tokenValues.\n   *\n   * @example\n   * ```js\n   * onDelete()\n   * ```\n   *\n   * @returns {void}\n   */\n  onDelete: () =\u003e void;\n}\n```\n\n## License\n\n[MIT](./LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseawind543%2Freact-token-input","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseawind543%2Freact-token-input","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseawind543%2Freact-token-input/lists"}