hsuanyi-chou / shadcn-ui-expansions

More components built on top of shadcn-ui.
https://shadcnui-expansions.typeart.cc/
MIT License
560 stars 25 forks source link

Slowing down/freezing when using creatable #29

Closed emino07 closed 5 months ago

emino07 commented 5 months ago

Entering a long string in a creatable selector causes the browser tab to slow down and eventually freeze (starts around 45 characters). Pasting a long string also immediately freezes the tab.

Steps to reproduce:

  1. Go to https://shadcnui-expansions.typeart.cc/docs/multiple-selector#Creatable%20Selector
  2. Paste a long string or repeatedly paste a short one.

Tested on Chromium and Firefox. I was able to profile it on Firefox and it seems to be caused by some recursive call.

hsuanyi-chou commented 5 months ago

Try-and-error many times and I found it's related to cmdk.

You can provide a filter in Command and the creatable selector won't freeze.

return (
      <Command
        {...commandProps}
        onKeyDown={(e) => {
          handleKeyDown(e);
          commandProps?.onKeyDown?.(e);
        }}
        className={cn('overflow-visible bg-transparent', commandProps?.className)}
        shouldFilter={
          commandProps?.shouldFilter !== undefined ? commandProps.shouldFilter : !onSearch
        } // When onSearch is provided, we don't want to filter the options. You can still override it.
+        filter={(value, search) => {
+          return value.toLowerCase().includes(search.toLowerCase()) ? 1 : -1;
+        }}
      >

here is a fixed version if you want to fix it yourself.

or an easy way to fix it without modifying multipleSelector.tsx by giving prop:

const MultipleSelectorCreatable = () => {
  return (
    <div className="w-full px-10">
      <MultipleSelector
        defaultOptions={OPTIONS}
        placeholder="Type something that does not exist in dropdowns..."
        creatable
        emptyIndicator={
          <p className="text-center text-lg leading-10 text-gray-600 dark:text-gray-400">
            no results found.
          </p>
        }
+        commandProps={{
+          filter: (value, search) => {
+              return value.toLowerCase().includes(search.toLowerCase()) ? 1 : -1;  // write your own filtering logic.
+          },
+        }}
      />
    </div>
  );
};

An known issue: The filtering logic value.toLowerCase().includes(search.toLowerCase()) ? 1 : -1; will cause CreatableItem disappear when typing a space in the end. For example: Hello, a space in the end and the CreatableItem disappeared.

but Hello my friend works fine.

Because the value in cmdk is trim() so that they won't match.

image image