"use strict";(globalThis.webpackChunk_elliemae_pui_app_sdk=globalThis.webpackChunk_elliemae_pui_app_sdk||[]).push([[9825],{"./lib/view/fields/autocomplete/async-suggestions-autocomplete.stories.tsx":(A,p,e)=>{e.r(p),e.d(p,{AsyncSuggestionsAutocomplete:()=>C,__namedExportsOrder:()=>w,default:()=>k});var f=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/jsx.js"),t=e.n(f),c=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/slicedToArray.js"),d=e.n(c),m=e("./node_modules/.pnpm/react@18.3.1/node_modules/react/index.js"),l=e("./node_modules/.pnpm/@elliemae+ds-grid@3.54.6_@elliemae+pui-theme@2.13.0/node_modules/@elliemae/ds-grid/dist/esm/Grid.js"),_=e("./node_modules/.pnpm/@elliemae+ds-legacy-button-v2@1.0.16_@elliemae+pui-theme@2.13.0/node_modules/@elliemae/ds-legacy-button-v2/dist/esm/DSButtonV2.js"),u=e("./node_modules/.pnpm/react-hook-form@7.63.0_react@18.3.1/node_modules/react-hook-form/dist/index.esm.mjs"),s=e("./lib/view/form/index.tsx"),i=e("./lib/view/fields/form-layout-block-item/index.tsx"),a=e("./lib/view/fields/autocomplete/index.tsx"),r=e("./lib/view/fields/input-text/index.tsx"),n=e("./lib/view/fields/watch-value.tsx"),o=e("./node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js"),v,g=`
    
    // @ts-nocheck
    // @ts-ignore
    var __STORY__ = "import React from 'react';\\nimport { Story, Meta } from '@storybook/react';\\nimport { Grid } from '@elliemae/ds-grid';\\nimport { DSButtonV2 } from '@elliemae/ds-button';\\nimport { useFormContext } from 'react-hook-form';\\nimport { Form } from '../../form/index.js';\\nimport { FormLayoutBlockItem } from '../form-layout-block-item/index.js';\\nimport { Autocomplete, AutocompleteProps } from './index.js';\\nimport { InputText } from '../input-text/index.js';\\nimport { WatchValue } from '../watch-value.js';\\n\\nexport default {\\n  title: 'Components/Form/Controls/Autocomplete',\\n  component: Autocomplete,\\n} as Meta;\\n\\ntype FakeOption = {\\n  dsId: string;\\n  type: 'option';\\n  value: string;\\n  label: string;\\n};\\nconst fakeOptionsFromServer: FakeOption[] = [\\n  {\\n    dsId: '1',\\n    type: 'option',\\n    value: 'Luke Skywalker too long this text is super long',\\n    label: 'Luke Skywalker too long this text is super long',\\n  },\\n  {\\n    dsId: '2',\\n    type: 'option',\\n    value: 'Obi-Wan Kenobi',\\n    label: 'Obi-Wan Kenobi',\\n  },\\n  {\\n    dsId: '3',\\n    type: 'option',\\n    value: 'Padme Amidala',\\n    label: 'Padme Amidala',\\n  },\\n];\\n\\nconst getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>\\n  new Promise((resolve) => {\\n    setTimeout(() => {\\n      if (value.length < 3) return resolve([]);\\n      return resolve(\\n        fakeOptionsFromServer.filter((option) =>\\n          option.value.toLowerCase().includes(value.toLowerCase()),\\n        ),\\n      );\\n    }, 2000);\\n  });\\n\\nconst AsyncAutoComplete = (args: AutocompleteProps) => {\\n  const { watch } = useFormContext();\\n  const [options, setOptions] = React.useState<FakeOption[]>([]);\\n\\n  const asyncSetOptions = React.useCallback((value: string) => {\\n    getFakeAsyncFilteredOptions(value)\\n      .then((filteredOptions) => {\\n        setOptions(filteredOptions);\\n      })\\n      .catch((error) => {\\n        console.error(error);\\n      });\\n  }, []);\\n\\n  React.useEffect(() => {\\n    const subscription = watch((value, { name }) => {\\n      if (name === args.name) {\\n        // clear options until we get new ones from server\\n        // in a real app,\\n        //   you ideally would memoize the options in a cache\\n        //   to reduce the number of requests to the server & reduce UX latency\\n        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete\\n        //   for a trie implementation in JS that you can use to memoize options\\n        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree\\n        setOptions([]);\\n        asyncSetOptions(value[name] as string);\\n      }\\n    });\\n    return () => subscription.unsubscribe();\\n  }, [args.name, asyncSetOptions, watch]);\\n\\n  return (\\n    <FormLayoutBlockItem\\n      inputID=\\"star_wars_character\\"\\n      label=\\"Favourite Star Wars character\\"\\n    >\\n      <Autocomplete name={args.name} options={options}>\\n        <InputText name={args.name} defaultValue={args.defaultValue} />\\n      </Autocomplete>\\n    </FormLayoutBlockItem>\\n  );\\n};\\n\\nconst Template: Story<AutocompleteProps> = (args) => (\\n  <Grid p=\\"m\\">\\n    <Form>\\n      <AsyncAutoComplete {...args} />\\n      <DSButtonV2>Submit</DSButtonV2>\\n      <WatchValue label=\\"Favourite Star Wars character\\" {...args} />\\n    </Form>\\n  </Grid>\\n);\\n\\nexport const AsyncSuggestionsAutocomplete = Template.bind({});\\n\\nAsyncSuggestionsAutocomplete.args = {\\n  name: 'star_wars_character',\\n  defaultValue: 'Obi',\\n  options: [],\\n};\\n";
    // @ts-ignore
    var __LOCATIONS_MAP__ = {"AsyncSuggestionsAutocomplete":{"startLoc":{"col":43,"line":99},"endLoc":{"col":1,"line":107},"startBody":{"col":43,"line":99},"endBody":{"col":1,"line":107}}};
    
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Grid } from '@elliemae/ds-grid';
import { DSButtonV2 } from '@elliemae/ds-button';
import { useFormContext } from 'react-hook-form';
import { Form } from '../../form/index.js';
import { FormLayoutBlockItem } from '../form-layout-block-item/index.js';
import { Autocomplete, AutocompleteProps } from './index.js';
import { InputText } from '../input-text/index.js';
import { WatchValue } from '../watch-value.js';

export default {parameters: {"storySource":{"source":"import React from 'react';\\nimport { Story, Meta } from '@storybook/react';\\nimport { Grid } from '@elliemae/ds-grid';\\nimport { DSButtonV2 } from '@elliemae/ds-button';\\nimport { useFormContext } from 'react-hook-form';\\nimport { Form } from '../../form/index.js';\\nimport { FormLayoutBlockItem } from '../form-layout-block-item/index.js';\\nimport { Autocomplete, AutocompleteProps } from './index.js';\\nimport { InputText } from '../input-text/index.js';\\nimport { WatchValue } from '../watch-value.js';\\n\\nexport default {\\n  title: 'Components/Form/Controls/Autocomplete',\\n  component: Autocomplete,\\n} as Meta;\\n\\ntype FakeOption = {\\n  dsId: string;\\n  type: 'option';\\n  value: string;\\n  label: string;\\n};\\nconst fakeOptionsFromServer: FakeOption[] = [\\n  {\\n    dsId: '1',\\n    type: 'option',\\n    value: 'Luke Skywalker too long this text is super long',\\n    label: 'Luke Skywalker too long this text is super long',\\n  },\\n  {\\n    dsId: '2',\\n    type: 'option',\\n    value: 'Obi-Wan Kenobi',\\n    label: 'Obi-Wan Kenobi',\\n  },\\n  {\\n    dsId: '3',\\n    type: 'option',\\n    value: 'Padme Amidala',\\n    label: 'Padme Amidala',\\n  },\\n];\\n\\nconst getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>\\n  new Promise((resolve) => {\\n    setTimeout(() => {\\n      if (value.length < 3) return resolve([]);\\n      return resolve(\\n        fakeOptionsFromServer.filter((option) =>\\n          option.value.toLowerCase().includes(value.toLowerCase()),\\n        ),\\n      );\\n    }, 2000);\\n  });\\n\\nconst AsyncAutoComplete = (args: AutocompleteProps) => {\\n  const { watch } = useFormContext();\\n  const [options, setOptions] = React.useState<FakeOption[]>([]);\\n\\n  const asyncSetOptions = React.useCallback((value: string) => {\\n    getFakeAsyncFilteredOptions(value)\\n      .then((filteredOptions) => {\\n        setOptions(filteredOptions);\\n      })\\n      .catch((error) => {\\n        console.error(error);\\n      });\\n  }, []);\\n\\n  React.useEffect(() => {\\n    const subscription = watch((value, { name }) => {\\n      if (name === args.name) {\\n        // clear options until we get new ones from server\\n        // in a real app,\\n        //   you ideally would memoize the options in a cache\\n        //   to reduce the number of requests to the server & reduce UX latency\\n        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete\\n        //   for a trie implementation in JS that you can use to memoize options\\n        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree\\n        setOptions([]);\\n        asyncSetOptions(value[name] as string);\\n      }\\n    });\\n    return () => subscription.unsubscribe();\\n  }, [args.name, asyncSetOptions, watch]);\\n\\n  return (\\n    <FormLayoutBlockItem\\n      inputID=\\"star_wars_character\\"\\n      label=\\"Favourite Star Wars character\\"\\n    >\\n      <Autocomplete name={args.name} options={options}>\\n        <InputText name={args.name} defaultValue={args.defaultValue} />\\n      </Autocomplete>\\n    </FormLayoutBlockItem>\\n  );\\n};\\n\\nconst Template: Story<AutocompleteProps> = (args) => (\\n  <Grid p=\\"m\\">\\n    <Form>\\n      <AsyncAutoComplete {...args} />\\n      <DSButtonV2>Submit</DSButtonV2>\\n      <WatchValue label=\\"Favourite Star Wars character\\" {...args} />\\n    </Form>\\n  </Grid>\\n);\\n\\nexport const AsyncSuggestionsAutocomplete = Template.bind({});\\n\\nAsyncSuggestionsAutocomplete.args = {\\n  name: 'star_wars_character',\\n  defaultValue: 'Obi',\\n  options: [],\\n};\\n","locationsMap":{"async-suggestions-autocomplete":{"startLoc":{"col":43,"line":99},"endLoc":{"col":1,"line":107},"startBody":{"col":43,"line":99},"endBody":{"col":1,"line":107}}}},},
  title: 'Components/Form/Controls/Autocomplete',
  component: Autocomplete,
} as Meta;

type FakeOption = {
  dsId: string;
  type: 'option';
  value: string;
  label: string;
};
const fakeOptionsFromServer: FakeOption[] = [
  {
    dsId: '1',
    type: 'option',
    value: 'Luke Skywalker too long this text is super long',
    label: 'Luke Skywalker too long this text is super long',
  },
  {
    dsId: '2',
    type: 'option',
    value: 'Obi-Wan Kenobi',
    label: 'Obi-Wan Kenobi',
  },
  {
    dsId: '3',
    type: 'option',
    value: 'Padme Amidala',
    label: 'Padme Amidala',
  },
];

const getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>
  new Promise((resolve) => {
    setTimeout(() => {
      if (value.length < 3) return resolve([]);
      return resolve(
        fakeOptionsFromServer.filter((option) =>
          option.value.toLowerCase().includes(value.toLowerCase()),
        ),
      );
    }, 2000);
  });

const AsyncAutoComplete = (args: AutocompleteProps) => {
  const { watch } = useFormContext();
  const [options, setOptions] = React.useState<FakeOption[]>([]);

  const asyncSetOptions = React.useCallback((value: string) => {
    getFakeAsyncFilteredOptions(value)
      .then((filteredOptions) => {
        setOptions(filteredOptions);
      })
      .catch((error) => {
        console.error(error);
      });
  }, []);

  React.useEffect(() => {
    const subscription = watch((value, { name }) => {
      if (name === args.name) {
        // clear options until we get new ones from server
        // in a real app,
        //   you ideally would memoize the options in a cache
        //   to reduce the number of requests to the server & reduce UX latency
        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete
        //   for a trie implementation in JS that you can use to memoize options
        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree
        setOptions([]);
        asyncSetOptions(value[name] as string);
      }
    });
    return () => subscription.unsubscribe();
  }, [args.name, asyncSetOptions, watch]);

  return (
    <FormLayoutBlockItem
      inputID="star_wars_character"
      label="Favourite Star Wars character"
    >
      <Autocomplete name={args.name} options={options}>
        <InputText name={args.name} defaultValue={args.defaultValue} />
      </Autocomplete>
    </FormLayoutBlockItem>
  );
};

const Template: Story<AutocompleteProps> = (args) => (
  <Grid p="m">
    <Form>
      <AsyncAutoComplete {...args} />
      <DSButtonV2>Submit</DSButtonV2>
      <WatchValue label="Favourite Star Wars character" {...args} />
    </Form>
  </Grid>
);

export const AsyncSuggestionsAutocomplete = Template.bind({});

AsyncSuggestionsAutocomplete.args = {
  name: 'star_wars_character',
  defaultValue: 'Obi',
  options: [],
};
`,y={AsyncSuggestionsAutocomplete:{startLoc:{col:43,line:107},endLoc:{col:1,line:115},startBody:{col:43,line:107},endBody:{col:1,line:115}}},g=`import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Grid } from '@elliemae/ds-grid';
import { DSButtonV2 } from '@elliemae/ds-button';
import { useFormContext } from 'react-hook-form';
import { Form } from '../../form/index.js';
import { FormLayoutBlockItem } from '../form-layout-block-item/index.js';
import { Autocomplete, AutocompleteProps } from './index.js';
import { InputText } from '../input-text/index.js';
import { WatchValue } from '../watch-value.js';

export default {
  title: 'Components/Form/Controls/Autocomplete',
  component: Autocomplete,
} as Meta;

type FakeOption = {
  dsId: string;
  type: 'option';
  value: string;
  label: string;
};
const fakeOptionsFromServer: FakeOption[] = [
  {
    dsId: '1',
    type: 'option',
    value: 'Luke Skywalker too long this text is super long',
    label: 'Luke Skywalker too long this text is super long',
  },
  {
    dsId: '2',
    type: 'option',
    value: 'Obi-Wan Kenobi',
    label: 'Obi-Wan Kenobi',
  },
  {
    dsId: '3',
    type: 'option',
    value: 'Padme Amidala',
    label: 'Padme Amidala',
  },
];

const getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>
  new Promise((resolve) => {
    setTimeout(() => {
      if (value.length < 3) return resolve([]);
      return resolve(
        fakeOptionsFromServer.filter((option) =>
          option.value.toLowerCase().includes(value.toLowerCase()),
        ),
      );
    }, 2000);
  });

const AsyncAutoComplete = (args: AutocompleteProps) => {
  const { watch } = useFormContext();
  const [options, setOptions] = React.useState<FakeOption[]>([]);

  const asyncSetOptions = React.useCallback((value: string) => {
    getFakeAsyncFilteredOptions(value)
      .then((filteredOptions) => {
        setOptions(filteredOptions);
      })
      .catch((error) => {
        console.error(error);
      });
  }, []);

  React.useEffect(() => {
    const subscription = watch((value, { name }) => {
      if (name === args.name) {
        // clear options until we get new ones from server
        // in a real app,
        //   you ideally would memoize the options in a cache
        //   to reduce the number of requests to the server & reduce UX latency
        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete
        //   for a trie implementation in JS that you can use to memoize options
        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree
        setOptions([]);
        asyncSetOptions(value[name] as string);
      }
    });
    return () => subscription.unsubscribe();
  }, [args.name, asyncSetOptions, watch]);

  return (
    <FormLayoutBlockItem
      inputID="star_wars_character"
      label="Favourite Star Wars character"
    >
      <Autocomplete name={args.name} options={options}>
        <InputText name={args.name} defaultValue={args.defaultValue} />
      </Autocomplete>
    </FormLayoutBlockItem>
  );
};

const Template: Story<AutocompleteProps> = (args) => (
  <Grid p="m">
    <Form>
      <AsyncAutoComplete {...args} />
      <DSButtonV2>Submit</DSButtonV2>
      <WatchValue label="Favourite Star Wars character" {...args} />
    </Form>
  </Grid>
);

export const AsyncSuggestionsAutocomplete = Template.bind({});

AsyncSuggestionsAutocomplete.args = {
  name: 'star_wars_character',
  defaultValue: 'Obi',
  options: [],
};
`,y={AsyncSuggestionsAutocomplete:{startLoc:{col:43,line:99},endLoc:{col:1,line:107},startBody:{col:43,line:99},endBody:{col:1,line:107}}};const k={parameters:{storySource:{source:`
    
    // @ts-nocheck
    // @ts-ignore
    var __STORY__ = "import React from 'react';\\nimport { Story, Meta } from '@storybook/react';\\nimport { Grid } from '@elliemae/ds-grid';\\nimport { DSButtonV2 } from '@elliemae/ds-button';\\nimport { useFormContext } from 'react-hook-form';\\nimport { Form } from '../../form/index.js';\\nimport { FormLayoutBlockItem } from '../form-layout-block-item/index.js';\\nimport { Autocomplete, AutocompleteProps } from './index.js';\\nimport { InputText } from '../input-text/index.js';\\nimport { WatchValue } from '../watch-value.js';\\n\\nexport default {\\n  title: 'Components/Form/Controls/Autocomplete',\\n  component: Autocomplete,\\n} as Meta;\\n\\ntype FakeOption = {\\n  dsId: string;\\n  type: 'option';\\n  value: string;\\n  label: string;\\n};\\nconst fakeOptionsFromServer: FakeOption[] = [\\n  {\\n    dsId: '1',\\n    type: 'option',\\n    value: 'Luke Skywalker too long this text is super long',\\n    label: 'Luke Skywalker too long this text is super long',\\n  },\\n  {\\n    dsId: '2',\\n    type: 'option',\\n    value: 'Obi-Wan Kenobi',\\n    label: 'Obi-Wan Kenobi',\\n  },\\n  {\\n    dsId: '3',\\n    type: 'option',\\n    value: 'Padme Amidala',\\n    label: 'Padme Amidala',\\n  },\\n];\\n\\nconst getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>\\n  new Promise((resolve) => {\\n    setTimeout(() => {\\n      if (value.length < 3) return resolve([]);\\n      return resolve(\\n        fakeOptionsFromServer.filter((option) =>\\n          option.value.toLowerCase().includes(value.toLowerCase()),\\n        ),\\n      );\\n    }, 2000);\\n  });\\n\\nconst AsyncAutoComplete = (args: AutocompleteProps) => {\\n  const { watch } = useFormContext();\\n  const [options, setOptions] = React.useState<FakeOption[]>([]);\\n\\n  const asyncSetOptions = React.useCallback((value: string) => {\\n    getFakeAsyncFilteredOptions(value)\\n      .then((filteredOptions) => {\\n        setOptions(filteredOptions);\\n      })\\n      .catch((error) => {\\n        console.error(error);\\n      });\\n  }, []);\\n\\n  React.useEffect(() => {\\n    const subscription = watch((value, { name }) => {\\n      if (name === args.name) {\\n        // clear options until we get new ones from server\\n        // in a real app,\\n        //   you ideally would memoize the options in a cache\\n        //   to reduce the number of requests to the server & reduce UX latency\\n        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete\\n        //   for a trie implementation in JS that you can use to memoize options\\n        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree\\n        setOptions([]);\\n        asyncSetOptions(value[name] as string);\\n      }\\n    });\\n    return () => subscription.unsubscribe();\\n  }, [args.name, asyncSetOptions, watch]);\\n\\n  return (\\n    <FormLayoutBlockItem\\n      inputID=\\"star_wars_character\\"\\n      label=\\"Favourite Star Wars character\\"\\n    >\\n      <Autocomplete name={args.name} options={options}>\\n        <InputText name={args.name} defaultValue={args.defaultValue} />\\n      </Autocomplete>\\n    </FormLayoutBlockItem>\\n  );\\n};\\n\\nconst Template: Story<AutocompleteProps> = (args) => (\\n  <Grid p=\\"m\\">\\n    <Form>\\n      <AsyncAutoComplete {...args} />\\n      <DSButtonV2>Submit</DSButtonV2>\\n      <WatchValue label=\\"Favourite Star Wars character\\" {...args} />\\n    </Form>\\n  </Grid>\\n);\\n\\nexport const AsyncSuggestionsAutocomplete = Template.bind({});\\n\\nAsyncSuggestionsAutocomplete.args = {\\n  name: 'star_wars_character',\\n  defaultValue: 'Obi',\\n  options: [],\\n};\\n";
    // @ts-ignore
    var __LOCATIONS_MAP__ = {"AsyncSuggestionsAutocomplete":{"startLoc":{"col":43,"line":99},"endLoc":{"col":1,"line":107},"startBody":{"col":43,"line":99},"endBody":{"col":1,"line":107}}};
    
import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Grid } from '@elliemae/ds-grid';
import { DSButtonV2 } from '@elliemae/ds-button';
import { useFormContext } from 'react-hook-form';
import { Form } from '../../form/index.js';
import { FormLayoutBlockItem } from '../form-layout-block-item/index.js';
import { Autocomplete, AutocompleteProps } from './index.js';
import { InputText } from '../input-text/index.js';
import { WatchValue } from '../watch-value.js';

export default {parameters: {"storySource":{"source":"import React from 'react';\\nimport { Story, Meta } from '@storybook/react';\\nimport { Grid } from '@elliemae/ds-grid';\\nimport { DSButtonV2 } from '@elliemae/ds-button';\\nimport { useFormContext } from 'react-hook-form';\\nimport { Form } from '../../form/index.js';\\nimport { FormLayoutBlockItem } from '../form-layout-block-item/index.js';\\nimport { Autocomplete, AutocompleteProps } from './index.js';\\nimport { InputText } from '../input-text/index.js';\\nimport { WatchValue } from '../watch-value.js';\\n\\nexport default {\\n  title: 'Components/Form/Controls/Autocomplete',\\n  component: Autocomplete,\\n} as Meta;\\n\\ntype FakeOption = {\\n  dsId: string;\\n  type: 'option';\\n  value: string;\\n  label: string;\\n};\\nconst fakeOptionsFromServer: FakeOption[] = [\\n  {\\n    dsId: '1',\\n    type: 'option',\\n    value: 'Luke Skywalker too long this text is super long',\\n    label: 'Luke Skywalker too long this text is super long',\\n  },\\n  {\\n    dsId: '2',\\n    type: 'option',\\n    value: 'Obi-Wan Kenobi',\\n    label: 'Obi-Wan Kenobi',\\n  },\\n  {\\n    dsId: '3',\\n    type: 'option',\\n    value: 'Padme Amidala',\\n    label: 'Padme Amidala',\\n  },\\n];\\n\\nconst getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>\\n  new Promise((resolve) => {\\n    setTimeout(() => {\\n      if (value.length < 3) return resolve([]);\\n      return resolve(\\n        fakeOptionsFromServer.filter((option) =>\\n          option.value.toLowerCase().includes(value.toLowerCase()),\\n        ),\\n      );\\n    }, 2000);\\n  });\\n\\nconst AsyncAutoComplete = (args: AutocompleteProps) => {\\n  const { watch } = useFormContext();\\n  const [options, setOptions] = React.useState<FakeOption[]>([]);\\n\\n  const asyncSetOptions = React.useCallback((value: string) => {\\n    getFakeAsyncFilteredOptions(value)\\n      .then((filteredOptions) => {\\n        setOptions(filteredOptions);\\n      })\\n      .catch((error) => {\\n        console.error(error);\\n      });\\n  }, []);\\n\\n  React.useEffect(() => {\\n    const subscription = watch((value, { name }) => {\\n      if (name === args.name) {\\n        // clear options until we get new ones from server\\n        // in a real app,\\n        //   you ideally would memoize the options in a cache\\n        //   to reduce the number of requests to the server & reduce UX latency\\n        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete\\n        //   for a trie implementation in JS that you can use to memoize options\\n        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree\\n        setOptions([]);\\n        asyncSetOptions(value[name] as string);\\n      }\\n    });\\n    return () => subscription.unsubscribe();\\n  }, [args.name, asyncSetOptions, watch]);\\n\\n  return (\\n    <FormLayoutBlockItem\\n      inputID=\\"star_wars_character\\"\\n      label=\\"Favourite Star Wars character\\"\\n    >\\n      <Autocomplete name={args.name} options={options}>\\n        <InputText name={args.name} defaultValue={args.defaultValue} />\\n      </Autocomplete>\\n    </FormLayoutBlockItem>\\n  );\\n};\\n\\nconst Template: Story<AutocompleteProps> = (args) => (\\n  <Grid p=\\"m\\">\\n    <Form>\\n      <AsyncAutoComplete {...args} />\\n      <DSButtonV2>Submit</DSButtonV2>\\n      <WatchValue label=\\"Favourite Star Wars character\\" {...args} />\\n    </Form>\\n  </Grid>\\n);\\n\\nexport const AsyncSuggestionsAutocomplete = Template.bind({});\\n\\nAsyncSuggestionsAutocomplete.args = {\\n  name: 'star_wars_character',\\n  defaultValue: 'Obi',\\n  options: [],\\n};\\n","locationsMap":{"async-suggestions-autocomplete":{"startLoc":{"col":43,"line":99},"endLoc":{"col":1,"line":107},"startBody":{"col":43,"line":99},"endBody":{"col":1,"line":107}}}},},
  title: 'Components/Form/Controls/Autocomplete',
  component: Autocomplete,
} as Meta;

type FakeOption = {
  dsId: string;
  type: 'option';
  value: string;
  label: string;
};
const fakeOptionsFromServer: FakeOption[] = [
  {
    dsId: '1',
    type: 'option',
    value: 'Luke Skywalker too long this text is super long',
    label: 'Luke Skywalker too long this text is super long',
  },
  {
    dsId: '2',
    type: 'option',
    value: 'Obi-Wan Kenobi',
    label: 'Obi-Wan Kenobi',
  },
  {
    dsId: '3',
    type: 'option',
    value: 'Padme Amidala',
    label: 'Padme Amidala',
  },
];

const getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>
  new Promise((resolve) => {
    setTimeout(() => {
      if (value.length < 3) return resolve([]);
      return resolve(
        fakeOptionsFromServer.filter((option) =>
          option.value.toLowerCase().includes(value.toLowerCase()),
        ),
      );
    }, 2000);
  });

const AsyncAutoComplete = (args: AutocompleteProps) => {
  const { watch } = useFormContext();
  const [options, setOptions] = React.useState<FakeOption[]>([]);

  const asyncSetOptions = React.useCallback((value: string) => {
    getFakeAsyncFilteredOptions(value)
      .then((filteredOptions) => {
        setOptions(filteredOptions);
      })
      .catch((error) => {
        console.error(error);
      });
  }, []);

  React.useEffect(() => {
    const subscription = watch((value, { name }) => {
      if (name === args.name) {
        // clear options until we get new ones from server
        // in a real app,
        //   you ideally would memoize the options in a cache
        //   to reduce the number of requests to the server & reduce UX latency
        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete
        //   for a trie implementation in JS that you can use to memoize options
        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree
        setOptions([]);
        asyncSetOptions(value[name] as string);
      }
    });
    return () => subscription.unsubscribe();
  }, [args.name, asyncSetOptions, watch]);

  return (
    <FormLayoutBlockItem
      inputID="star_wars_character"
      label="Favourite Star Wars character"
    >
      <Autocomplete name={args.name} options={options}>
        <InputText name={args.name} defaultValue={args.defaultValue} />
      </Autocomplete>
    </FormLayoutBlockItem>
  );
};

const Template: Story<AutocompleteProps> = (args) => (
  <Grid p="m">
    <Form>
      <AsyncAutoComplete {...args} />
      <DSButtonV2>Submit</DSButtonV2>
      <WatchValue label="Favourite Star Wars character" {...args} />
    </Form>
  </Grid>
);

export const AsyncSuggestionsAutocomplete = Template.bind({});

AsyncSuggestionsAutocomplete.args = {
  name: 'star_wars_character',
  defaultValue: 'Obi',
  options: [],
};
`,locationsMap:{"async-suggestions-autocomplete":{startLoc:{col:43,line:107},endLoc:{col:1,line:115},startBody:{col:43,line:107},endBody:{col:1,line:115}}}},storySource:{source:`import React from 'react';
import { Story, Meta } from '@storybook/react';
import { Grid } from '@elliemae/ds-grid';
import { DSButtonV2 } from '@elliemae/ds-button';
import { useFormContext } from 'react-hook-form';
import { Form } from '../../form/index.js';
import { FormLayoutBlockItem } from '../form-layout-block-item/index.js';
import { Autocomplete, AutocompleteProps } from './index.js';
import { InputText } from '../input-text/index.js';
import { WatchValue } from '../watch-value.js';

export default {
  title: 'Components/Form/Controls/Autocomplete',
  component: Autocomplete,
} as Meta;

type FakeOption = {
  dsId: string;
  type: 'option';
  value: string;
  label: string;
};
const fakeOptionsFromServer: FakeOption[] = [
  {
    dsId: '1',
    type: 'option',
    value: 'Luke Skywalker too long this text is super long',
    label: 'Luke Skywalker too long this text is super long',
  },
  {
    dsId: '2',
    type: 'option',
    value: 'Obi-Wan Kenobi',
    label: 'Obi-Wan Kenobi',
  },
  {
    dsId: '3',
    type: 'option',
    value: 'Padme Amidala',
    label: 'Padme Amidala',
  },
];

const getFakeAsyncFilteredOptions = (value: string): Promise<FakeOption[]> =>
  new Promise((resolve) => {
    setTimeout(() => {
      if (value.length < 3) return resolve([]);
      return resolve(
        fakeOptionsFromServer.filter((option) =>
          option.value.toLowerCase().includes(value.toLowerCase()),
        ),
      );
    }, 2000);
  });

const AsyncAutoComplete = (args: AutocompleteProps) => {
  const { watch } = useFormContext();
  const [options, setOptions] = React.useState<FakeOption[]>([]);

  const asyncSetOptions = React.useCallback((value: string) => {
    getFakeAsyncFilteredOptions(value)
      .then((filteredOptions) => {
        setOptions(filteredOptions);
      })
      .catch((error) => {
        console.error(error);
      });
  }, []);

  React.useEffect(() => {
    const subscription = watch((value, { name }) => {
      if (name === args.name) {
        // clear options until we get new ones from server
        // in a real app,
        //   you ideally would memoize the options in a cache
        //   to reduce the number of requests to the server & reduce UX latency
        //   checkout https://stackfull.dev/trie-in-javascript-the-data-structure-behind-autocomplete
        //   for a trie implementation in JS that you can use to memoize options
        //   dimsum offers a tree data structure that you can use for this at https://qa.dimsum.rd.elliemae.io/?path=/story/hooks--use-ds-tree
        setOptions([]);
        asyncSetOptions(value[name] as string);
      }
    });
    return () => subscription.unsubscribe();
  }, [args.name, asyncSetOptions, watch]);

  return (
    <FormLayoutBlockItem
      inputID="star_wars_character"
      label="Favourite Star Wars character"
    >
      <Autocomplete name={args.name} options={options}>
        <InputText name={args.name} defaultValue={args.defaultValue} />
      </Autocomplete>
    </FormLayoutBlockItem>
  );
};

const Template: Story<AutocompleteProps> = (args) => (
  <Grid p="m">
    <Form>
      <AsyncAutoComplete {...args} />
      <DSButtonV2>Submit</DSButtonV2>
      <WatchValue label="Favourite Star Wars character" {...args} />
    </Form>
  </Grid>
);

export const AsyncSuggestionsAutocomplete = Template.bind({});

AsyncSuggestionsAutocomplete.args = {
  name: 'star_wars_character',
  defaultValue: 'Obi',
  options: [],
};
`,locationsMap:{"async-suggestions-autocomplete":{startLoc:{col:43,line:99},endLoc:{col:1,line:107},startBody:{col:43,line:99},endBody:{col:1,line:107}}}}},title:"Components/Form/Controls/Autocomplete",component:a.j};var O=[{dsId:"1",type:"option",value:"Luke Skywalker too long this text is super long",label:"Luke Skywalker too long this text is super long"},{dsId:"2",type:"option",value:"Obi-Wan Kenobi",label:"Obi-Wan Kenobi"},{dsId:"3",type:"option",value:"Padme Amidala",label:"Padme Amidala"}],S=function(h){return new Promise(function(P){setTimeout(function(){return h.length<3?P([]):P(O.filter(function(I){return I.value.toLowerCase().includes(h.toLowerCase())}))},2e3)})},x=function(h){var P=(0,u.xW)(),I=P.watch,M=m.useState([]),j=d()(M,2),W=j[0],D=j[1],L=m.useCallback(function(E){S(E).then(function(F){D(F)}).catch(function(F){console.error(F)})},[]);return m.useEffect(function(){var E=I(function(F,T){var B=T.name;B===h.name&&(D([]),L(F[B]))});return function(){return E.unsubscribe()}},[h.name,L,I]),t()(i.B,{inputID:"star_wars_character",label:"Favourite Star Wars character"},void 0,t()(a.j,{name:h.name,options:W},void 0,t()(r.S,{name:h.name,defaultValue:h.defaultValue})))};x.displayName="AsyncAutoComplete";var b=function(h){return t()(l.Ay,{p:"m"},void 0,t()(s.l,{},void 0,(0,o.jsx)(x,Object.assign({},h)),v||(v=t()(_.e,{},void 0,"Submit")),(0,o.jsx)(n.n,Object.assign({label:"Favourite Star Wars character"},h))))};b.displayName="Template";var C=b.bind({});C.args={name:"star_wars_character",defaultValue:"Obi",options:[]};var w=["AsyncSuggestionsAutocomplete"]},"./lib/view/fields/autocomplete/index.tsx":(A,p,e)=>{e.d(p,{j:()=>i});var f=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/jsx.js"),t=e.n(f),c=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),d=e.n(c),m=e("./node_modules/.pnpm/react@18.3.1/node_modules/react/index.js"),l=e("./node_modules/.pnpm/@elliemae+ds-form-layout-autocomplete@3.54.6_@elliemae+pui-theme@2.13.0/node_modules/@elliemae/ds-form-layout-autocomplete/dist/esm/Autocomplete.js"),_=e("./node_modules/.pnpm/react-hook-form@7.63.0_react@18.3.1/node_modules/react-hook-form/dist/index.esm.mjs"),u=["children"],s=function(a,r){if(!r)return a;var n=a.filter(function(o){return o.type==="section"||o.label.toLowerCase().includes(r?.toLowerCase())});return n.length===1&&n[0].type==="section"?[]:n},i=function(a){var r=a.children,n=d()(a,u),o=(0,_.xW)(),v=o.watch,g=o.setValue,y=v(n.name),k=(0,m.useCallback)(function(O){for(var S=arguments.length,x=new Array(S>1?S-1:0),b=1;b<S;b++)x[b-1]=arguments[b];n.onSelect?n.onSelect.apply(n,[O].concat(x)):g(n.name,O,{shouldValidate:!0,shouldDirty:!0,shouldTouch:!0})},[n,g]);return t()(l.A,{id:"",filter:y??"",onSelect:k,options:s(n.options,y)},void 0,r)};i.displayName="Autocomplete"},"./lib/view/fields/form-layout-block-item/index.tsx":(A,p,e)=>{e.d(p,{B:()=>_});var f=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),t=e.n(f),c=e("./node_modules/.pnpm/@elliemae+ds-form-layout-blocks@3.54.6_@elliemae+pui-theme@2.13.0/node_modules/@elliemae/ds-form-layout-blocks/dist/esm/form-layout-block-item/DSFormLayoutBlockItem.js"),d=e("./node_modules/.pnpm/react-hook-form@7.63.0_react@18.3.1/node_modules/react-hook-form/dist/index.esm.mjs"),m=e("./node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js"),l=["inputID","label"],_=function(u){var s=u.inputID,i=u.label,a=t()(u,l),r=(0,d.lN)({name:s}),n=r.errors,o=(0,d.Jt)(n,s),v=!!o,g=o?.message;return(0,m.jsx)(c.U,Object.assign({inputID:s,label:i,hasError:v,validationMessage:g},a))};_.displayName="FormLayoutBlockItem"},"./lib/view/fields/input-text/index.tsx":(A,p,e)=>{e.d(p,{S:()=>s});var f=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/jsx.js"),t=e.n(f),c=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),d=e.n(c),m=e("./node_modules/.pnpm/@elliemae+ds-form-input-text@3.54.6_@elliemae+pui-theme@2.13.0/node_modules/@elliemae/ds-form-input-text/dist/esm/DSInputText.js"),l=e("./node_modules/.pnpm/react-hook-form@7.63.0_react@18.3.1/node_modules/react-hook-form/dist/index.esm.mjs"),_=e("./node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js"),u=["name","defaultValue","rules"],s=function(i){var a=i.name,r=i.defaultValue,n=r===void 0?"":r,o=i.rules,v=o===void 0?{}:o,g=d()(i,u);return t()(l.xI,{name:a,defaultValue:n,rules:v,render:function(y){var k=y.field,O=y.fieldState.error;return(0,_.jsx)(m.B,Object.assign({hasError:!!O},k,g))}})};s.displayName="InputText"},"./lib/view/fields/watch-value.tsx":(A,p,e)=>{e.d(p,{n:()=>s});var f=e("./node_modules/.pnpm/@babel+runtime@7.28.4/node_modules/@babel/runtime/helpers/jsx.js"),t=e.n(f),c=e("./node_modules/.pnpm/styled-components@5.3.11_react-dom@18.3.1_react@18.3.1/node_modules/styled-components/dist/styled-components.browser.esm.js"),d=e("./node_modules/.pnpm/@elliemae+ds-grid@3.54.6_@elliemae+pui-theme@2.13.0/node_modules/@elliemae/ds-grid/dist/esm/Grid.js"),m=e("./node_modules/.pnpm/react-hook-form@7.63.0_react@18.3.1/node_modules/react-hook-form/dist/index.esm.mjs"),l,_=c.Ay.section.withConfig({componentId:"sc-1va6d9p-0"})(["margin-top:10px;border-top:2px blue dotted;width:100%;"]),u=c.Ay.div.withConfig({componentId:"sc-1va6d9p-1"})(["display:flex;flex-direction:column;padding-left:10px;align-items:flex-start;"]),s=function(i){var a=i.name,r=i.label,n=(0,m.xW)(),o=n.watch,v=o(a,!1)||"";return t()(d.Ay,{},void 0,t()(_,{},void 0,l||(l=t()("h4",{},void 0,"Form Data:")),t()(u,{},void 0,t()("div",{},void 0,r," : ",t()("strong",{},void 0,JSON.stringify(v))))))};s.displayName="WatchValue"},"./lib/view/form/index.tsx":(A,p,e)=>{e.d(p,{l:()=>m});var f=e("./node_modules/.pnpm/styled-components@5.3.11_react-dom@18.3.1_react@18.3.1/node_modules/styled-components/dist/styled-components.browser.esm.js"),t=e("./node_modules/.pnpm/react-hook-form@7.63.0_react@18.3.1/node_modules/react-hook-form/dist/index.esm.mjs"),c=e("./node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js"),d=f.Ay.form.withConfig({componentId:"sc-1pyjvv3-0"})(["width:100%;"]),m=function(l){var _=l.classname,u=l.reactHookFormProps,s=u===void 0?{mode:"onBlur"}:u,i=l.children,a=l.onSubmit,r=(0,t.mN)(s),n={};a&&(n.onSubmit=r.handleSubmit(a));var o=Object.assign(r,{formProps:s});return(0,c.jsx)(t.Op,Object.assign({},o,{children:(0,c.jsx)(d,Object.assign({className:_},n,{children:i}))}))};m.displayName="Form"}}]);
