throttle-debounce#debounce TypeScript Examples
The following examples show how to use
throttle-debounce#debounce.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ui.ts From monkeytype with GNU General Public License v3.0 | 6 votes |
debouncedEvent = debounce(250, async () => {
Caret.updatePosition();
if (
Config.tapeMode !== "off" &&
getActivePage() === "test" &&
!TestUI.resultVisible
) {
TestUI.scrollTape();
}
setTimeout(() => {
Caret.show();
}, 250);
})
Example #2
Source File: useElementAspectRatio.tsx From amazon-chime-sdk-smart-video-sending-demo with Apache License 2.0 | 6 votes |
useElementAspectRatio = (ref: RefObject<HTMLElement>): AspectRatio | null => {
const [ratio, setRatio] = useState<AspectRatio | null>(null);
useLayoutEffect(() => {
if (!ref.current) {
return;
}
const { height, width } = ref.current.getBoundingClientRect();
setRatio(getAspectRatio(height, width));
}, []);
useEffect(() => {
if (!ref.current) {
return;
}
const handleResize = debounce(50, (entries: any) => {
const { height, width } = entries[0].contentRect;
setRatio(getAspectRatio(height, width));
});
const resizeObserver = new ResizeObserver(handleResize);
resizeObserver.observe(ref.current);
return () => resizeObserver.disconnect();
}, []);
return ratio;
}
Example #3
Source File: useDynamicFontSize.tsx From amazon-chime-live-events with Apache License 2.0 | 6 votes |
useDynamicFontSize = (ref: RefObject<HTMLElement>) => {
const [fontSize, setFontSize] = useState<string>();
useLayoutEffect(() => {
if (!ref.current) {
return;
}
const { width } = ref.current.getBoundingClientRect();
setFontSize(getNamePlateFontSize(width));
}, []);
useEffect(() => {
const el = ref.current;
if (!el) {
return;
}
const handleResize = debounce(50, (entries: any) => {
const { width } = entries[0].contentRect;
setFontSize(getNamePlateFontSize(width));
});
const resizeObserver = new ResizeObserver(handleResize);
resizeObserver.observe(el);
return () => resizeObserver.unobserve(el);
}, []);
return fontSize;
}
Example #4
Source File: Dropdown.tsx From design-system with MIT License | 6 votes |
debounceSearch = debounce(this.props.searchDebounceDuration, () => {
this.setState(
{
searchInit: false,
},
() => {
this.updateOptions(false);
}
);
});
Example #5
Source File: useDebounceState.ts From react-datasheet-grid with MIT License | 6 votes |
useDebounceState = <T>(
defaultValue: T,
delay: number
): [T, (nextVal: T) => void] => {
const [debouncedValue, setDebouncedValue] = useState(defaultValue)
const cancelRef = useRef<debounce<(newValue: T) => void>>()
useEffect(() => () => cancelRef.current?.cancel(), [])
const setValue = useMemo(
() =>
(cancelRef.current = debounce(delay, (newValue: T) => {
setDebouncedValue(newValue)
})),
[delay]
)
return [debouncedValue, setValue]
}
Example #6
Source File: Table.tsx From design-system with MIT License | 6 votes |
constructor(props: TableProps) {
super(props);
const async = 'fetchData' in this.props;
const data = props.data || [];
const schema = props.schema || [];
this.state = {
async,
data: !async ? data : [],
schema: !async ? schema : [],
page: props.page,
sortingList: props.sortingList,
filterList: props.filterList,
totalRecords: !async ? data.length : 0,
loading: !async ? props.loading : true,
error: !async ? props.error : false,
errorType: props.errorType,
selectAll: getSelectAll([]),
searchTerm: undefined,
};
this.debounceUpdate = debounce(props.searchDebounceDuration, this.updateDataFn);
}
Example #7
Source File: CList.tsx From Cromwell with MIT License | 6 votes |
private onScroll = debounce(50, () => {
const props = this.getProps();
if (props.useAutoLoading) {
const minRangeToLoad = props.minRangeToLoad ?? 200;
if (this.scrollBoxRef.current && this.wrapperRef.current) {
const scrollTop = this.scrollBoxRef.current.scrollTop;
const scrollBottom = this.wrapperRef.current.clientHeight - this.scrollBoxRef.current.clientHeight - scrollTop;
this.setThrobberAutoloadingAfter();
// Rendered last row from data list, but has more pages to load from server
if (scrollBottom < minRangeToLoad) {
if (this.maxPage > this.maxPageBound) {
// console.log('onScroll: need to load next page', this.maxPageBound);
if (!this.isPageLoading) {
this.loadNextPage();
return;
}
}
}
// Rendered first element but has more pages to load previously from server
// console.log('scrollTop', scrollTop, 'scrollBottom', scrollBottom)
if (this.minPageBound > 1) {
if (scrollTop === 0) this.scrollBoxRef.current.scrollTop = 10;
if (scrollTop < minRangeToLoad) {
// console.log('onScroll: need to load prev page', this.minPageBound);
if (!this.isPageLoading) {
this.loadPreviousPage();
}
}
}
}
}
})
Example #8
Source File: config-change-manager.ts From karma-test-explorer with MIT License | 6 votes |
public constructor(private readonly logger: Logger, options?: ConfigChangeManagerOptions) {
this.configPrefix = options?.configNamespace ? `${options.configNamespace}.` : '';
const debouncedConfigChangeHandler = debounce(
options?.changeHandlingDelay ?? CONFIG_FILE_CHANGE_BATCH_DELAY,
options?.changeHandlingDelayMode === 'Ending' ? false : true,
this.handleConfigurationChange.bind(this)
);
this.logger.debug(() => 'Creating config change subscription');
const configChangeSubscription = workspace.onDidChangeConfiguration(debouncedConfigChangeHandler);
this.disposables.push(configChangeSubscription, logger);
}
Example #9
Source File: login.ts From monkeytype with GNU General Public License v3.0 | 6 votes |
checkNameDebounced = debounce(1000, async () => {
const val = $(
".page.pageLogin .register.side .usernameInput"
).val() as string;
if (!val) {
updateSignupButton();
return;
}
const response = await Ape.users.getNameAvailability(val);
if (response.status === 200) {
nameIndicator.show("available", response.message);
} else if (response.status === 422) {
nameIndicator.show("unavailable", response.message);
} else if (response.status === 409) {
nameIndicator.show("taken", response.message);
} else {
nameIndicator.show("unavailable", response.message);
Notifications.add(
"Failed to check name availability: " + response.message,
-1
);
}
updateSignupButton();
})
Example #10
Source File: google-sign-up-popup.ts From monkeytype with GNU General Public License v3.0 | 6 votes |
checkNameDebounced = debounce(1000, async () => {
const val = $("#googleSignUpPopup input").val() as string;
if (!val) return;
const response = await Ape.users.getNameAvailability(val);
if (response.status === 200) {
nameIndicator.show("available", response.message);
enableButton();
return;
}
if (response.status == 422) {
nameIndicator.show("unavailable", response.message);
return;
}
if (response.status == 409) {
nameIndicator.show("taken", response.message);
return;
}
if (response.status !== 200) {
nameIndicator.show("unavailable");
return Notifications.add(
"Failed to check name availability: " + response.message,
-1
);
}
})
Example #11
Source File: file-watcher.ts From karma-test-explorer with MIT License | 5 votes |
private createFileWatchers(): Disposable[] {
this.logger.debug(() => 'Creating file watchers for monitored files');
const reloadTriggerFilesRelativePaths = this.reloadTriggerFiles.map(triggerFile =>
normalizePath(relative(this.projectRootPath, triggerFile))
);
this.logger.trace(
() =>
`Monitored files ( configured --> normalized): ` +
`${JSON.stringify(this.reloadTriggerFiles, null, 2)} --> ` +
`${JSON.stringify(reloadTriggerFilesRelativePaths, null, 2)}`
);
const reloadTriggerFilesWatchers = this.registerFileHandler(
reloadTriggerFilesRelativePaths,
debounce(WATCHED_FILE_CHANGE_BATCH_DELAY, filePath => {
this.logger.info(() => `Reloading due to monitored file changed: ${filePath}`);
this.projectCommands.execute(ProjectCommand.Reset);
})
);
this.logger.debug(() => 'Creating file watchers for test file changes');
const testFileGlobs = this.testFilePatterns;
const reloadTestFilesWatchers = this.registerFileHandler(testFileGlobs, async (changedTestFile, changeType) => {
if (!this.testLocator?.isTestFile(changedTestFile)) {
this.logger.warn(() => `Expected changed file to be spec file but it is not: ${changedTestFile}`);
return;
}
this.logger.debug(() => `Changed file is spec file: ${changedTestFile}`);
await (changeType === FileChangeType.Deleted
? this.testLocator.removeFiles([changedTestFile])
: this.testLocator.refreshFiles([changedTestFile]));
if (this.fileWatcherOptions.retireTestsInChangedFiles) {
const changedTestIds = this.testStore?.getTestsByFile(changedTestFile).map(changedTest => changedTest.id) ?? [];
if (changedTestIds.length > 0) {
this.logger.debug(() => `Retiring ${changedTestIds.length} tests from updated spec file: ${changedTestFile}`);
this.testRetireEventEmitter.fire({ tests: changedTestIds });
}
}
});
return [...reloadTriggerFilesWatchers, ...reloadTestFilesWatchers];
}
Example #12
Source File: TalentsScreen.tsx From jobsgowhere with MIT License | 5 votes |
TalentsScreen: React.FC = function () {
const [state, actions] = useTalentsReducer();
const { isDetailView } = useMobileViewContext();
const { updateTalents, refreshTalents } = actions;
const active = Boolean(state.activeTalent) && isDetailView;
const pageRef = React.useRef<number>(1);
const auth0Ready = useAuth0Ready();
const debouncedSearch = debounce(500, false, (query) => {
const body = { text: query };
ApiClient.post<PostInterface[]>(`${process.env.REACT_APP_API}/talents/search`, body).then(
(res) => {
refreshTalents(res.data);
},
);
});
const onSearchChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
debouncedSearch(e.target.value);
};
const fetchTalents = React.useCallback(
(page: number): Promise<void> => {
return ApiClient.get<PostInterface[]>(`${process.env.REACT_APP_API}/talents/${page}`).then(
(res) => {
updateTalents(res.data);
},
);
},
[updateTalents],
);
function handleLoadMore() {
const nextPage = ++pageRef.current;
return fetchTalents(nextPage);
}
React.useEffect(() => {
if (auth0Ready) {
fetchTalents(pageRef.current);
}
}, [auth0Ready, fetchTalents]);
return (
<Main active={active}>
<Helmet>
<title>Talents listing</title>
</Helmet>
<Search placeholder="Search talents" onChange={onSearchChange} />
<CategorySelector category="talents" />
<PostsContainer>
{state.fetched ? (
<>
{state.talents.map((talent: PostInterface) => (
<PostBlock key={talent.id}>
<Post category="talents" active={talent.active} data={talent} />
</PostBlock>
))}
<PostLoader hasMore={state.more} onLoadMore={handleLoadMore} />
</>
) : (
<PostSpinner />
)}
</PostsContainer>
<DetailsContainer active={active}>
{state.activeTalent ? (
<PostDetail data={state.activeTalent} category="talents" />
) : (
<PostDetailPlaceholder type="talents" />
)}
</DetailsContainer>
</Main>
);
}
Example #13
Source File: config.ts From monkeytype with GNU General Public License v3.0 | 5 votes |
saveToDatabase = debounce(1000, () => {
delete configToSend.resultFilters;
if (Object.keys(configToSend).length > 0) DB.saveConfig(configToSend);
configToSend = {} as MonkeyTypes.Config;
})
Example #14
Source File: JobsScreen.tsx From jobsgowhere with MIT License | 5 votes |
JobsScreen: React.FC = function () {
const [state, actions] = usePostsReducer();
const { isDetailView } = useMobileViewContext();
const { updateJobs, refreshJobs } = actions;
const active = Boolean(state.activeJob && isDetailView);
const pageRef = React.useRef<number>(1);
const auth0Ready = useAuth0Ready();
const debouncedSearch = debounce(500, false, (query) => {
const body = { text: query };
ApiClient.post<PostInterface[]>(`${process.env.REACT_APP_API}/jobs/search`, body).then(
(res) => {
refreshJobs(res.data);
},
);
});
const onSearchChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
debouncedSearch(e.target.value);
};
const fetchJobs = React.useCallback(
(page: number): Promise<void> => {
return ApiClient.get<PostInterface[]>(`${process.env.REACT_APP_API}/jobs/${page}`).then(
(res) => {
updateJobs(res.data);
},
);
},
[updateJobs],
);
function handleLoadMore() {
const nextPage = ++pageRef.current;
return fetchJobs(nextPage);
}
React.useEffect(() => {
if (auth0Ready) {
fetchJobs(pageRef.current);
}
}, [auth0Ready, fetchJobs]);
return (
<Main active={active}>
<Helmet>
<title>Jobs listing</title>
</Helmet>
<Search placeholder="Search job postings" onChange={onSearchChange} />
<CategorySelector category="jobs" />
<PostsContainer>
{state.fetched ? (
<>
{state.jobs.map((post: PostInterface) => (
<PostBlock key={post.id}>
<Post category="jobs" active={post.active} data={post} />
</PostBlock>
))}
<PostLoader hasMore={state.more} onLoadMore={handleLoadMore} />
</>
) : (
<PostSpinner />
)}
</PostsContainer>
<DetailsContainer active={active}>
{state.activeJob ? (
<PostDetail data={state.activeJob} category="jobs" />
) : (
<PostDetailPlaceholder type="jobs" />
)}
</DetailsContainer>
</Main>
);
}
Example #15
Source File: notifications.ts From monkeytype with GNU General Public License v3.0 | 5 votes |
debouncedMarginUpdate = debounce(100, updateMargin)
Example #16
Source File: Dropdown.tsx From design-system with MIT License | 5 votes |
debounceClear = debounce(250, () => this.updateOptions(false));
Example #17
Source File: quote-search-popup.ts From monkeytype with GNU General Public License v3.0 | 5 votes |
searchForQuotes = debounce(250, (): void => {
const searchText = (<HTMLInputElement>document.getElementById("searchBox"))
.value;
updateResults(searchText);
})
Example #18
Source File: index.tsx From amazon-chime-live-events with Apache License 2.0 | 5 votes |
VideoGrid: React.FC<Props> = ({ children, size, className }) => {
const gridEl = createRef<HTMLDivElement>();
const [ratio, setRatio] = useState<any>();
useLayoutEffect(() => {
if (!gridEl.current) {
return;
}
const { height, width } = gridEl.current?.getBoundingClientRect();
setRatio(getAspectRatio(height, width));
}, []);
useEffect(() => {
const el = gridEl.current;
if (!el) {
return;
}
const handleResize = debounce(100, (entries: any) => {
const { height, width } = entries[0].contentRect;
setRatio(getAspectRatio(height, width));
});
const resizeObserver = new ResizeObserver(handleResize);
resizeObserver.observe(el);
return () => resizeObserver.unobserve(el);
}, []);
return (
<div
ref={gridEl}
className={cx('grid', `grid--size-${size}`, ratio, className)}
>
{children}
</div>
);
}
Example #19
Source File: Filter.tsx From Cromwell with MIT License | 5 votes |
private onPriceRangeChange = debounce(500, (newValue: number[]) => {
this.priceRange = newValue;
this.applyFilter();
});
Example #20
Source File: HeaderSearch.tsx From Cromwell with MIT License | 5 votes |
private searchRequest = debounce(500, async (postName: string) => {
const pagedParams: TPagedParams<TPost> = {
pageNumber: 1,
pageSize: 10,
}
const filterParams: TPostFilter = {
titleSearch: postName
}
const client = getGraphQLClient();
if (!this.state.isLoading)
this.setState({ isLoading: true });
try {
const data = await client?.query({
query: gql`
query getFilteredPosts($pagedParams: PagedParamsInput, $filterParams: PostFilterInput) {
getFilteredPosts(pagedParams: $pagedParams, filterParams: $filterParams) {
pagedMeta {
...PagedMetaFragment
}
elements {
id
isEnabled
slug
title
mainImage
}
}
}
${client?.PagedMetaFragment}
`,
variables: {
pagedParams,
filterParams,
}
});
const elements = data?.data?.getFilteredPosts?.elements;
if (elements) this.setState({ searchItems: elements });
} catch (e) {
console.error(e);
}
this.setState({ isLoading: false });
});
Example #21
Source File: ThemeMarket.tsx From Cromwell with MIT License | 5 votes |
private handleFilterInput = debounce(400, () => {
this.resetList();
});
Example #22
Source File: EditorBlock.tsx From Cromwell with MIT License | 5 votes |
private handleSaveDebounced = debounce(200, async () => {
this.handleSaveEditor();
});
Example #23
Source File: PluginMarket.tsx From Cromwell with MIT License | 5 votes |
private handleFilterInput = debounce(400, () => {
this.resetList();
});
Example #24
Source File: Dashboard.tsx From Cromwell with MIT License | 5 votes |
private onLayoutChange = debounce(200, (currentLayout, allLayouts, shouldUpdate?: boolean) => {
window.localStorage.setItem('crw_dashboard_layout', JSON.stringify(allLayouts));
if (shouldUpdate) this.forceUpdate();
})
Example #25
Source File: customFields.tsx From Cromwell with MIT License | 5 votes |
RenderCustomFields = (props: {
entityType: EDBEntity | string;
entityData: TBasePageEntity;
refetchMeta: () => Promise<Record<string, string> | undefined | null>;
}) => {
const { entityType, entityData, refetchMeta } = props;
const forceUpdate = useForceUpdate();
customFieldsForceUpdates[entityType] = forceUpdate;
const [updatedMeta, setUpdatedMeta] = useState<Record<string, string> | null>(null);
useEffect(() => {
// If some field registered after this page has fetched entity data, we need to
// re-request data for this field to get its custom meta
const onFieldRegistered = debounce(300, async () => {
const newMeta = await refetchMeta();
if (newMeta) setUpdatedMeta(newMeta);
});
addOnFieldRegisterEventListener(entityType, onFieldRegistered);
return () => {
removeOnFieldRegisterEventListener(entityType);
delete customFieldsForceUpdates[entityType];
}
}, []);
// Just update the values that are undefined, but leave the rest
// for user input to be untouched
const customMeta = Object.assign({}, updatedMeta, entityData?.customMeta);
return <>{Object.values(customFields[entityType] ?? {})
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
.map(field => {
const Comp = field.component;
return <Comp
key={field.key}
initialValue={customMeta?.[field.key]}
entity={entityData}
/>
})}</>
}
Example #26
Source File: Autocomplete.tsx From Cromwell with MIT License | 5 votes |
private searchRequest = debounce(500, async () => {
const list = getBlockInstance<TCList>(this.listId)?.getContentInstance();
if (!list) {
return;
}
list.clearState();
list.init();
});
Example #27
Source File: Filter.tsx From Cromwell with MIT License | 5 votes |
private onSearchChange = debounce(500, (newValue: string) => {
this.search = newValue;
this.applyFilter();
});
Example #28
Source File: ProductSearch.tsx From Cromwell with MIT License | 4 votes |
/**
* Search input field. Queries products in the store. Results are shown in pop-up window on user input.
*/
export function ProductSearch(props: ProductSearchProps) {
const { text, classes } = props;
const { TextField = BaseTextField, Popper = BasePopper,
ListItem = DefaultListItem } = props.elements ?? {};
const [searchOpen, setSearchOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [searchItems, setSearchItems] = useState<TProduct[]>([]);
const searchAnchorRef = useRef<HTMLDivElement | null>(null);
const searchRequest = useCallback(debounce(500, async (productName: string) => {
const pagedParams: TPagedParams<TProduct> = {
pageNumber: 1,
pageSize: 10,
}
const filterParams = {
nameSearch: productName
}
const client = getGraphQLClient();
if (!isLoading) setIsLoading(true);
const fragment = props.customFragment ?? gql`
fragment ProductSearchFragment on Product {
id
isEnabled
slug
pageTitle
name
price
oldPrice
mainImage
}`;
const fragmentName = props.customFragmentName ?? 'ProductSearchFragment';
try {
const data = await client?.query({
query: gql`
query getFilteredProducts($pagedParams: PagedParamsInput, $filterParams: ProductFilterInput) {
getFilteredProducts(pagedParams: $pagedParams, filterParams: $filterParams) {
pagedMeta {
...PagedMetaFragment
}
elements {
...${fragmentName}
}
}
}
${fragment}
${client?.PagedMetaFragment}`,
variables: {
pagedParams,
filterParams,
}
});
const products = data?.data?.getFilteredProducts?.elements;
if (products) setSearchItems(products);
} catch (e) {
console.error(e);
}
setIsLoading(false);
}), []);
const handleSearchInput = (productName: string) => {
if (!isLoading) setIsLoading(true);
if (!searchOpen) {
setSearchOpen(true);
}
searchRequest(productName);
}
const handleSearchClose = () => {
setSearchOpen(false);
}
return (
<div className={clsx(styles.ProductSearch, classes?.root)} ref={searchAnchorRef}>
<TextField
label={text?.searchLabel ?? "Search..."}
onChange={(event) => handleSearchInput(event.currentTarget.value)}
/>
<Popper open={searchOpen}
anchorEl={searchAnchorRef.current}
onClose={handleSearchClose}
>
<div className={clsx(styles.searchContent, classes?.content)}
onClick={handleSearchClose}
>
{isLoading && (
<LoadBox size={100} />
)}
{!isLoading && searchItems.length === 0 && (
<p className={clsx(styles.searchNotFoundText, classes?.notFoundText)}
>{text?.notFound ?? 'No items found'}</p>
)}
{!isLoading && searchItems?.map(product => (
<ListItem
key={product.id}
product={product}
searchProps={props}
/>
))}
</div>
</Popper>
</div>
);
}
Example #29
Source File: search.tsx From Cromwell with MIT License | 4 votes |
SearchPage: TPageWithLayout<SearchPageProps> = (props) => {
const filterInput = useRef<TPostFilter>({});
const listId = 'Blog_list_01';
const publishSort = useRef<"ASC" | "DESC">('DESC');
const forceUpdate = useForceUpdate();
const titleSearchId = "post-filter-search";
const updateList = () => {
const list = getBlockInstance<TCList>(listId)?.getContentInstance();
list?.clearState();
list?.init();
list?.updateData();
}
const handleChangeTags = (event: any, newValue?: (TTag | undefined | string)[]) => {
filterInput.current.tagIds = newValue?.map(tag => (tag as TTag)?.id);
forceUpdate();
updateList();
}
const handleGetPosts = (params: TPagedParams<TPost>) => {
params.orderBy = 'publishDate';
params.order = publishSort.current;
return handleGetFilteredPosts(params, filterInput.current);
}
const handleChangeSort = (event: SelectChangeEvent<unknown>) => {
if (event.target.value === 'Newest') publishSort.current = 'DESC';
if (event.target.value === 'Oldest') publishSort.current = 'ASC';
updateList();
}
const handleTagClick = (tag?: TTag) => {
if (!tag) return;
if (filterInput.current.tagIds?.length === 1 &&
filterInput.current.tagIds[0] === tag.id) return;
handleChangeTags(null, [tag]);
forceUpdate();
}
const handleTitleInput = debounce(400, () => {
filterInput.current.titleSearch = (document.getElementById(titleSearchId) as HTMLInputElement)?.value ?? undefined;
updateList();
});
return (
<CContainer className={commonStyles.content} id="search_01">
<CContainer className={styles.filter} id="search_02">
<div className={styles.filterLeft}>
<TextField
className={styles.filterItem}
placeholder="Search by title"
id={titleSearchId}
variant="standard"
onChange={handleTitleInput}
/>
<Autocomplete
multiple
freeSolo
value={filterInput.current.tagIds?.map(id => props.tags?.find(tag => tag.id === id)) ?? []}
className={styles.filterItem}
options={props.tags ?? []}
getOptionLabel={(option: any) => option?.name ?? ''}
style={{ width: 300 }}
onChange={handleChangeTags}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
placeholder="Tags"
/>
)}
/>
</div>
<FormControl className={styles.filterItem}>
<InputLabel className={styles.sortLabel}>Sort</InputLabel>
<Select
style={{ width: '100px' }}
onChange={handleChangeSort}
variant="standard"
defaultValue='Newest'
>
{['Newest', 'Oldest'].map(sort => (
<MenuItem value={sort} key={sort}>{sort}</MenuItem>
))}
</Select>
</FormControl>
</CContainer>
<CContainer style={{ marginBottom: '20px' }} id="search_03">
<CList<TPost>
id={listId}
ListItem={(props) => (
<div className={styles.postWrapper}>
<PostCard onTagClick={handleTagClick} data={props.data} key={props.data?.id} />
</div>
)}
usePagination
useShowMoreButton
useQueryPagination
disableCaching
pageSize={20}
scrollContainerSelector={`.${layoutStyles.Layout}`}
firstBatch={props.posts}
loader={handleGetPosts}
cssClasses={{
page: styles.postList
}}
elements={{
pagination: Pagination
}}
/>
</CContainer>
</CContainer>
);
}