@reach/router#useLocation TypeScript Examples
The following examples show how to use
@reach/router#useLocation.
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: useSearchModal.ts From usehooks-ts with MIT License | 6 votes |
useSearchModal = (): [boolean, Record<string, () => void>] => {
const { value, setTrue: openModal, setFalse: closeModal } = useBoolean(false)
const location = useLocation()
useUpdateEffect(() => {
closeModal()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location])
return [value, { openModal, closeModal }]
}
Example #2
Source File: Feedback.tsx From website-docs with MIT License | 6 votes |
export function FeedbackDoc({ pathConfig, filePath }: Props) {
const { site } = useStaticQuery(graphql`
query {
site {
siteMetadata {
siteUrl
}
}
}
`)
let { pathname } = useLocation()
if (pathname.endsWith('/')) {
pathname = pathname.slice(0, -1) // unify client and ssr
}
return (
<a
className="doc-help-link feedback"
href={`https://github.com/${getRepo(
pathConfig
)}/issues/new?body=File:%20[/${pathConfig.branch}/${filePath}](${
site.siteMetadata.siteUrl
}${pathname})`}
target="_blank"
rel="noreferrer">
<Trans i18nKey="doc.feedback" />
</a>
)
}
Example #3
Source File: announcement.tsx From web with Apache License 2.0 | 6 votes |
Announcement = ({
longText,
shortText,
link,
className,
openInNewWindow = false
}: PropTypes) => {
const location = useLocation()
if (location.pathname.replace(/\/+$/, '') === link.replace(/\/+$/, '')) {
return null
}
return (
<div className={className}>
<AnnouncementBanner
text={longText}
link={link}
lengthy={true}
openInNewWindow={openInNewWindow}
/>
<AnnouncementBanner
text={shortText}
link={link}
lengthy={false}
openInNewWindow={openInNewWindow}
/>
</div>
)
}
Example #4
Source File: SignInView.tsx From Frontend with MIT License | 5 votes |
LoginView: React.FC<RouteComponentProps> = (props) => {
const { search } = useLocation();
const { locationStore } = useStores();
const intl = useIntl();
const queryParams = queryString.parse(search) as any;
if (queryParams.next) {
locationStore.setNext(queryParams.next);
} else {
locationStore.setNext('/me');
}
console.log(props);
return (
<>
<PageHeader
heading={intl.formatMessage({ id: 'SigninView.heading' })}
lead={intl.formatMessage({ id: 'SigninView.lead' })}
/>
<FormState.Provider>
<Tabs variant="soft-rounded" variantColor="teal">
<TabList>
<Tab>Sign In</Tab>
<Tab>Sign Up</Tab>
</TabList>
<TabPanels>
<TabPanel>
<SignInForm></SignInForm>
</TabPanel>
<TabPanel>
<SignUpForm></SignUpForm>
</TabPanel>
</TabPanels>
</Tabs>
<Form
onLoginSuccess={(user) => {
navigate('/me');
}}
></Form>
</FormState.Provider>
</>
);
}
Example #5
Source File: tab-navigation.tsx From desktop with MIT License | 5 votes |
export function SiteTabLink({ site, ...props }: ITabProps): JSX.Element {
const { removeTab } = useSiteTabs()
const location = useLocation()
const url = `/sites/${site.hash}`
const isActive = location.pathname === url
const remove = useCallback(() => {
if (isActive) {
navigate(`/sites`)
}
removeTab(site.hash)
}, [removeTab, site, isActive])
return (
<Flex
sx={{
alignItems: `center`,
pr: 2,
py: 3,
...(isActive && {
backgroundColor: `purple.80`,
color: `white`,
}),
}}
>
<TabLink {...props} to={url}>
<SiteStatusDot status={site.siteStatus.status} sx={{ mr: 2 }} />
{site.name}
</TabLink>
<button
onClick={remove}
aria-label="Close tab"
sx={{
p: 3,
background: `none`,
border: `none`,
fontFamily: `sans`,
fontWeight: 500,
textDecoration: `none`,
color: `primaryBackground`,
display: `flex`,
alignItems: `center`,
}}
>
<MdClear />
</button>
</Flex>
)
}
Example #6
Source File: seo.tsx From usehooks-ts with MIT License | 5 votes |
SEO: FC<SEOProps> = ({
title,
description = '',
lang = 'en',
meta = [],
}) => {
const location = useLocation()
const siteMetadata = useSiteMetadata()
const metaDescription = description || siteMetadata.description
const url = `${siteMetadata.siteUrl}${location.pathname}`
const hookPageRegExp = new RegExp('/react-hook/')
const isHookPage = hookPageRegExp.test(url)
// Build image from title using "Typescript blue" optimized for Facebook banned
const image = `https://via.placeholder.com/1200x630.png/007ACC/fff/?text=${title}`
return (
<Helmet
htmlAttributes={{
lang,
}}
title={title}
titleTemplate={`%s`}
link={[{ rel: 'canonical', key: url, href: url }]}
meta={[
{
name: `description`,
content: metaDescription,
},
{
property: `og:title`,
content: title,
},
{
property: `og:image`,
content: image,
},
{
property: `og:description`,
content: metaDescription,
},
{
property: `og:site_name`,
content: siteMetadata.title,
},
{
property: `og:type`,
content: isHookPage ? `article` : `website`,
},
{
property: `og:url`,
content: url,
},
{
name: `twitter:card`,
content: `summary`,
},
// {
// name: `twitter:creator`,
// content: siteMetadata.author,
// },
{
name: `twitter:title`,
content: title,
},
{
name: `twitter:description`,
content: metaDescription,
},
].concat(meta)}
/>
)
}
Example #7
Source File: NavbarDocsCategory.tsx From mantine with MIT License | 5 votes |
export default function NavbarDocsCategory({ group, onLinkClick }: NavbarDocsCategoryProps) {
const { classes, cx } = useStyles();
const { pathname } = useLocation();
const [collapsed, setCollapsed] = useState(!hasActiveLink(group, pathname));
const itemRefs = useRef<Record<string, HTMLElement>>({});
useEffect(() => {
if (hasActiveLink(group, pathname) && itemRefs.current[pathname]) {
const element = itemRefs.current[pathname];
const height = typeof window !== 'undefined' ? window.innerHeight : 0;
const { top, bottom } = element.getBoundingClientRect();
if (top < HEADER_HEIGHT || bottom > height) {
element.scrollIntoView({ block: 'center' });
}
}
}, [pathname]);
const uncategorized = (
group.group === 'changelog' ? [...group.uncategorized].reverse() : group.uncategorized
).map((link) => (
<Link
key={link.slug}
className={classes.link}
activeClassName={classes.linkActive}
to={link.slug}
onClick={onLinkClick}
ref={(r) => {
itemRefs.current[link.slug] = r;
}}
>
{link.title}
</Link>
));
const categorized = !Array.isArray(group.groups)
? []
: group.groups.map((part) => {
if (!part || !Array.isArray(part.pages)) {
return null;
}
const links = part.pages.map((link) => (
<Link
key={link.slug}
className={classes.link}
activeClassName={classes.linkActive}
to={link.slug}
onClick={onLinkClick}
ref={(r) => {
itemRefs.current[link.slug] = r;
}}
>
{link.title}
</Link>
));
return (
<div className={classes.innerCategory} key={part.category.title}>
<Text className={classes.innerCategoryTitle}>
<part.category.icon className={classes.innerCategoryIcon} />
{part.category.title}
</Text>
{links}
</div>
);
});
return (
<div className={cx(classes.category, { [classes.categoryCollapsed]: collapsed })}>
<button className={classes.header} type="button" onClick={() => setCollapsed((c) => !c)}>
<ChevronDownIcon className={cx(classes.icon, { [classes.iconCollapsed]: collapsed })} />
<Text className={classes.title} weight={700} size="xs" transform="uppercase">
{group.group.replace('-', ' ')}
</Text>
</button>
{!collapsed && uncategorized}
{!collapsed && categorized}
</div>
);
}
Example #8
Source File: TableOfContents.tsx From mantine with MIT License | 5 votes |
export default function TableOfContents({ headings, withTabs }: TableOfContentsProps) {
const theme = useMantineTheme();
const { classes, cx } = useStyles();
const slugger = new Slugger();
const [active, setActive] = useState(0);
const { pathname } = useLocation();
const slugs = useRef<HTMLDivElement[]>([]);
const filteredHeadings = headings.filter((heading) => heading.depth > 1);
useEffect(() => {
slugger.reset();
slugs.current = filteredHeadings.map(
(heading) => document.getElementById(slugger.slug(heading.value)) as HTMLDivElement
);
}, [headings]);
const handleScroll = () => {
setActive(getActiveElement(slugs.current.map((d) => d.getBoundingClientRect())));
};
useEffect(() => {
setActive(getActiveElement(slugs.current.map((d) => d.getBoundingClientRect())));
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
if (filteredHeadings.length === 0) {
return null;
}
const items = filteredHeadings.map((heading, index) => {
const slug = slugger.slug(heading.value);
return (
<Text<'a'>
key={slug}
component="a"
size="sm"
className={cx(classes.link, { [classes.linkActive]: active === index })}
href={`#${slug}`}
sx={{ paddingLeft: (heading.depth - 1) * theme.spacing.lg }}
onClick={(event) => {
event.preventDefault();
navigate(`${pathname}#${slug}`, { replace: true });
}}
>
{heading.value}
</Text>
);
});
return (
<nav className={cx(classes.wrapper, { [classes.withTabs]: withTabs })}>
<div className={classes.inner}>
<div>
<div className={classes.header}>
<ActivityLogIcon />
<Text className={classes.title}>Table of contents</Text>
</div>
<div className={classes.items}>{items}</div>
</div>
</div>
</nav>
);
}
Example #9
Source File: SimpleTab.tsx From website-docs with MIT License | 5 votes |
export function SimpleTab({
children,
}: {
children: ReactElement<{ label: string; href?: string; children: ReactElement[] }>[]
}) {
const location = useLocation()
const [activeTab, setActiveTab] = useState(0)
useEffect(() => {
let active = children.findIndex(
child => {
const activeJudge: string = child.props?.href || child.props.label;
return activeJudge === decodeURIComponent(location.hash.slice(1))
}
)
if (active === -1) {
active = 0
}
setActiveTab(active)
}, [location.hash, children])
return (
<>
<ul className={tabs}>
{children.map((child, index) => {
const id: string = child.props?.href || child.props.label;
return (
<li key={id} id={id}>
<a
href={`#${id}`}
className={activeTab === index ? active : normal}>
{child.props.label}
</a>
</li>
)
})}
</ul>
{children.map((child, index) => {
const id: string = child.props?.href || child.props.label;
return (
<div
key={id}
className={clsx(activeTab !== index && hidden)}>
{child.props.children}
</div>
)
})}
</>
)
}
Example #10
Source File: pricing-table.tsx From admin with MIT License | 5 votes |
PricingTable = () => {
const location = useLocation()
const params = usePriceListFilters(location.search, defaultQueryProps)
const [columns] = usePriceListTableColumns()
const { price_lists, isLoading, count = 0 } = useAdminPriceLists(
params.queryObject,
{
keepPreviousData: true,
}
)
useSetSearchParams(params.representationObject)
const resetFilters = () => {
params.setQuery("")
params.reset()
}
return (
<div className="w-full overflow-y-auto flex flex-col justify-between min-h-[300px] h-full ">
<LoadingContainer isLoading={isLoading}>
<PriceListTable
columns={columns}
count={count}
priceLists={price_lists || []}
options={{
enableSearch: true,
filter: (
<PriceListsFilter
filters={params.filters}
submitFilters={params.setFilters}
clearFilters={resetFilters}
tabs={params.availableTabs}
onTabClick={params.setTab}
activeTab={params.activeFilterTab}
onRemoveTab={params.removeTab}
onSaveTab={params.saveTab}
/>
),
}}
{...params}
/>
</LoadingContainer>
</div>
)
}
Example #11
Source File: index.tsx From website-docs with MIT License | 4 votes |
export default function Search() {
const { language } = useI18next()
const location = useLocation()
const searchParams = new URLSearchParams(location.search)
const type = searchParams.get('type') || defaultDocInfo['type']
const version = searchParams.get('version') || defaultDocInfo['version']
const query = searchParams.get('q')
const dispatch = useDispatch()
const loading = useSelector(state => state.loading)
const [selectedType, setSelectedType] = useState(type)
const toAlgoliaVersion = version =>
version === 'stable'
? convertVersionName(replaceStableVersion(selectedType))
: version !== 'null' ? version : null
const [selectedVersion, _setSelectedVersion] = useState(
toAlgoliaVersion(version)
)
const setSelectedVersion = version =>
_setSelectedVersion(toAlgoliaVersion(version))
const [selectedVersionList, setSelectedVersionList] = useState(
matchToVersionList(type)
)
const [results, setResults] = useState([])
const [searched, setSearched] = useState(false)
const [docsTypesByLang, setDocsTypesByLang] = useState([])
useEffect(() => {
return () => dispatch(setSearchValue(''))
}, [dispatch])
useEffect(() => {
const types = [
{
name: 'TiDB',
match: 'tidb',
},
{
name: 'TiDB in Kubernetes',
match: 'tidb-in-kubernetes',
},
{
name: 'TiDB Data Migration (DM)',
match: 'tidb-data-migration',
},
]
const getDocsTypesByLang = () => {
switch (language) {
case 'zh':
types.push({
name: '开发指南',
match: 'appdev',
})
break
default:
types.push(
{
name: 'Cloud',
match: 'tidbcloud',
},
{
name: 'App Dev',
match: 'appdev',
}
)
break
}
return types
}
setDocsTypesByLang(getDocsTypesByLang())
}, [language])
const handleSetVersionList = match => () => {
const versionList = matchToVersionList(match)
setSelectedType(match)
setSelectedVersionList(versionList)
setSelectedVersion(versionList ? versionList[0] : null)
}
function execSearch() {
dispatch(setLoading(true))
const index = algoliaClient.initIndex(
`${language}-${selectedType}${selectedVersion ? '-' + selectedVersion : ''}`
)
index
.search(query, {
hitsPerPage: 150,
})
.then(({ hits }) => {
setResults(hits)
setSearched(true)
dispatch(setLoading(false))
})
}
useEffect(() => {
if (selectedType && query) {
execSearch()
} else {
setResults([])
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedType, selectedVersion, query])
return (
<Layout>
<Seo title="Search" noindex />
<div>
<div>
<div className={select}>
<span className={optionLabel}>
<Trans i18nKey="search.type" />
</span>
{docsTypesByLang.map(type => (
<button
key={type.name}
className={clsx(
optionItem,
selectedType === type.match && isActive
)}
onClick={handleSetVersionList(type.match)}>
{type.name}
</button>
))}
</div>
{selectedVersionList && (
<div className={select}>
<span className={optionLabel}>
<Trans i18nKey="search.version" />
</span>
{selectedVersionList.map(version => (
<button
key={version}
className={clsx(
optionItem,
selectedVersion === toAlgoliaVersion(version) && isActive
)}
onClick={() => setSelectedVersion(toAlgoliaVersion(version))}>
{toAlgoliaVersion(version)}
</button>
))}
</div>
)}
</div>
<div style={{ position: 'relative' }}>
<SearchResult results={results} searched={searched} />
{loading && (
<Loading
stretched
style={{ alignItems: 'start' }}
imgProps={{
style: {
marginTop: '2rem',
},
}}
/>
)}
</div>
</div>
</Layout>
)
}
Example #12
Source File: InviteView.tsx From Frontend with MIT License | 4 votes |
InviteView: React.FC<RouteComponentProps> = () => {
const { connectionMade } = useAnalytics();
const { uid }: params = useParams();
const location = useLocation();
const toast = useToast();
const intl = useIntl();
const { profile } = useAuth();
const [value, loading] = useObjectVal<Profile>(
firebase.database().ref(`profiles/${uid}`)
);
const [
createKnowsMutation,
{ loading: isLoadingConnection }
] = useCreateKnowsMutation({
onCompleted() {
connectionMade();
toast({
position: 'bottom-right',
title: intl.formatMessage({ id: 'InviteView.Connected' }),
description: intl.formatMessage(
{
id: 'InviteView.Connected-Description'
},
{
name: value.displayName
}
),
status: 'success',
isClosable: true
});
}
});
if (loading) {
return <Spinner />;
}
const displayName = value && value.displayName ? value.displayName : 'user';
const photoURL = value && value.photoURL ? value.photoURL : null;
const shouldShowConnectButton = profile?.uid !== uid;
return (
<>
<PageHeader
heading={intl.formatMessage({ id: 'InviteView.heading' })}
lead={intl.formatMessage(
{
id: 'InviteView.lead'
},
{
name: value.displayName
}
)}
/>
<AvatarGroup size="xl" max={2} mb={12}>
<Avatar name={displayName} src={photoURL} />
<Avatar bg="none" name="Contact Tracing" src={icon} />
</AvatarGroup>
{shouldShowConnectButton && (
<Button
isLoading={isLoadingConnection}
width="200px"
mb={16}
variantColor="teal"
onClick={() => {
if (!profile) {
navigate(`/me/sign-in?next=${location.pathname}`);
return;
}
createKnowsMutation({
variables: {
fromUid: profile?.uid,
toUid: uid
}
});
}}
>
<FormattedMessage id="InviteView.Connect-button" />
</Button>
)}
<Heading as="h3" mb={2} size="lg">
<FormattedMessage id="InviteView.why-use" />
</Heading>
<List styleType="disc">
<ListItem>
<FormattedMessage id="InviteView.why-1" />
</ListItem>
<ListItem>
<FormattedMessage id="InviteView.why-2" />
</ListItem>
<ListItem>
<FormattedMessage id="InviteView.why-3" />
</ListItem>
</List>
</>
);
}
Example #13
Source File: index.tsx From admin with MIT License | 4 votes |
ProductIndex = () => {
const location = useLocation()
const [view, setView] = useState("products")
const notification = useNotification()
const createCollection = useAdminCreateCollection()
useEffect(() => {
if (location.search.includes("?view=collections")) {
setView("collections")
}
}, [location])
useEffect(() => {
location.search = ""
}, [view])
const CurrentView = () => {
switch (view) {
case "products":
return <ProductTable />
default:
return <CollectionsTable />
}
}
const CurrentAction = () => {
switch (view) {
case "products":
return [
{
label: "New Product",
onClick: () => navigate("/a/products/new"),
icon: (
<span className="text-grey-90">
<PlusIcon size={20} />
</span>
),
},
]
default:
return [
{
label: "New Collection",
onClick: () => setShowNewCollection(!showNewCollection),
icon: (
<span className="text-grey-90">
<PlusIcon size={20} />
</span>
),
},
]
}
}
const [showNewCollection, setShowNewCollection] = useState(false)
const handleCreateCollection = async (data, colMetadata) => {
const metadata = colMetadata
.filter((m) => m.key && m.value) // remove empty metadata
.reduce((acc, next) => {
return {
...acc,
[next.key]: next.value,
}
}, {})
await createCollection.mutateAsync(
{ ...data, metadata },
{
onSuccess: ({ collection }) => {
notification("Success", "Successfully created collection", "success")
navigate(`/a/collections/${collection.id}`)
setShowNewCollection(false)
},
onError: (err) => notification("Error", getErrorMessage(err), "error"),
}
)
}
return (
<>
<div className="flex flex-col grow h-full">
<div className="w-full flex flex-col grow">
<BodyCard
actionables={CurrentAction()}
customHeader={
<TableViewHeader
views={VIEWS}
setActiveView={setView}
activeView={view}
/>
}
>
<CurrentView />
</BodyCard>
</div>
</div>
{showNewCollection && (
<AddCollectionModal
onClose={() => setShowNewCollection(!showNewCollection)}
onSubmit={handleCreateCollection}
/>
)}
</>
)
}
Example #14
Source File: index.tsx From admin with MIT License | 4 votes |
ProductTable: React.FC<ProductTableProps> = () => {
const location = useLocation()
const {
removeTab,
setTab,
saveTab,
availableTabs: filterTabs,
activeFilterTab,
reset,
paginate,
setFilters,
setLimit,
filters,
setQuery: setFreeText,
queryObject,
representationObject,
} = useProductFilters(location.search, defaultQueryProps)
const offs = parseInt(queryObject.offset) || 0
const limit = parseInt(queryObject.limit)
const [query, setQuery] = useState(queryObject.query)
const [numPages, setNumPages] = useState(0)
const clearFilters = () => {
reset()
setQuery("")
}
const { products, isLoading, isRefetching, count } = useAdminProducts({
...queryObject,
})
useEffect(() => {
if (typeof count !== "undefined") {
const controlledPageCount = Math.ceil(count / limit)
setNumPages(controlledPageCount)
}
}, [count])
const updateUrlFromFilter = (obj = {}) => {
const stringified = qs.stringify(obj)
window.history.replaceState(`/a/products`, "", `${`?${stringified}`}`)
}
const refreshWithFilters = () => {
const filterObj = representationObject
if (isEmpty(filterObj)) {
updateUrlFromFilter({ offset: 0, limit: DEFAULT_PAGE_SIZE })
} else {
updateUrlFromFilter(filterObj)
}
}
useEffect(() => {
refreshWithFilters()
}, [representationObject])
const setTileView = () => {
setLimit(DEFAULT_PAGE_SIZE_TILE_VIEW)
setShowList(false)
}
const setListView = () => {
setLimit(DEFAULT_PAGE_SIZE)
setShowList(true)
}
const [showList, setShowList] = React.useState(true)
const [columns] = useProductTableColumn({
setTileView,
setListView,
showList,
})
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
gotoPage,
canPreviousPage,
canNextPage,
pageCount,
nextPage,
previousPage,
// Get the state from the instance
state: { pageIndex, pageSize },
} = useTable(
{
columns,
data: products || [],
manualPagination: true,
initialState: {
pageIndex: Math.floor(offs / limit),
pageSize: limit,
},
pageCount: numPages,
autoResetPage: false,
},
usePagination
)
// Debounced search
useEffect(() => {
const delayDebounceFn = setTimeout(() => {
if (query) {
setFreeText(query)
gotoPage(0)
} else {
if (typeof query !== "undefined") {
// if we delete query string, we reset the table view
reset()
}
}
}, 400)
return () => clearTimeout(delayDebounceFn)
}, [query])
const handleNext = () => {
if (canNextPage) {
paginate(1)
nextPage()
}
}
const handlePrev = () => {
if (canPreviousPage) {
paginate(-1)
previousPage()
}
}
return (
<div className="w-full h-full overflow-y-auto">
<>
<Table
filteringOptions={
<ProductsFilter
filters={filters}
submitFilters={setFilters}
clearFilters={clearFilters}
tabs={filterTabs}
onTabClick={setTab}
activeTab={activeFilterTab}
onRemoveTab={removeTab}
onSaveTab={saveTab}
/>
}
enableSearch
handleSearch={setQuery}
{...getTableProps()}
>
{showList ? (
<>
<Table.Head>
{headerGroups?.map((headerGroup) => (
<Table.HeadRow {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((col) => (
<Table.HeadCell
className="min-w-[100px]"
{...col.getHeaderProps()}
>
{col.render("Header")}
</Table.HeadCell>
))}
</Table.HeadRow>
))}
</Table.Head>
<LoadingContainer
isLoading={isLoading || isRefetching || !products}
>
<Table.Body {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row)
return <ProductRow row={row} />
})}
</Table.Body>
</LoadingContainer>
</>
) : (
<LoadingContainer
isLoading={isLoading || isRefetching || !products}
>
<ProductOverview
products={products}
toggleListView={setListView}
/>
</LoadingContainer>
)}
</Table>
<TablePagination
count={count!}
limit={limit}
offset={offs}
pageSize={offs + rows.length}
title="Products"
currentPage={pageIndex + 1}
pageCount={pageCount}
nextPage={handleNext}
prevPage={handlePrev}
hasNext={canNextPage}
hasPrev={canPreviousPage}
/>
</>
</div>
)
}
Example #15
Source File: index.tsx From admin with MIT License | 4 votes |
OrderTable: React.FC<RouteComponentProps> = () => { const location = useLocation() const { removeTab, setTab, saveTab, availableTabs: filterTabs, activeFilterTab, reset, paginate, setFilters, filters, setQuery: setFreeText, queryObject, representationObject, } = useOrderFilters(location.search, defaultQueryProps) const filtersOnLoad = queryObject const offs = parseInt(filtersOnLoad?.offset) || 0 const lim = parseInt(filtersOnLoad.limit) || DEFAULT_PAGE_SIZE const [query, setQuery] = useState(filtersOnLoad?.query) const [numPages, setNumPages] = useState(0) const { orders, isLoading, count } = useAdminOrders(queryObject) useEffect(() => { const controlledPageCount = Math.ceil(count! / queryObject.limit) setNumPages(controlledPageCount) }, [orders]) const [columns] = useOrderTableColums() const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, canPreviousPage, canNextPage, pageCount, gotoPage, nextPage, previousPage, // Get the state from the instance state: { pageIndex }, } = useTable( { columns, data: orders || [], manualPagination: true, initialState: { pageSize: lim, pageIndex: offs / lim, }, pageCount: numPages, autoResetPage: false, }, usePagination ) // Debounced search useEffect(() => { const delayDebounceFn = setTimeout(() => { if (query) { setFreeText(query) gotoPage(0) } else { // if we delete query string, we reset the table view reset() } }, 400) return () => clearTimeout(delayDebounceFn) }, [query]) const handleNext = () => { if (canNextPage) { paginate(1) nextPage() } } const handlePrev = () => { if (canPreviousPage) { paginate(-1) previousPage() } } const updateUrlFromFilter = (obj = {}) => { const stringified = qs.stringify(obj) window.history.replaceState(`/a/orders`, "", `${`?${stringified}`}`) } const refreshWithFilters = () => { const filterObj = representationObject if (isEmpty(filterObj)) { updateUrlFromFilter({ offset: 0, limit: DEFAULT_PAGE_SIZE }) } else { updateUrlFromFilter(filterObj) } } const clearFilters = () => { reset() setQuery("") } useEffect(() => { refreshWithFilters() }, [representationObject]) return ( <div className="w-full overflow-y-auto flex flex-col justify-between min-h-[300px] h-full "> <Table filteringOptions={ <OrderFilters filters={filters} submitFilters={setFilters} clearFilters={clearFilters} tabs={filterTabs} onTabClick={setTab} activeTab={activeFilterTab} onRemoveTab={removeTab} onSaveTab={saveTab} /> } enableSearch handleSearch={setQuery} searchValue={query} {...getTableProps()} className={clsx({ ["relative"]: isLoading })} > <Table.Head> {headerGroups?.map((headerGroup, index) => ( <Table.HeadRow {...headerGroup.getHeaderGroupProps()}> {headerGroup.headers.map((col, headerIndex) => ( <Table.HeadCell {...col.getHeaderProps()}> {col.render("Header")} </Table.HeadCell> ))} </Table.HeadRow> ))} </Table.Head> {isLoading || !orders ? ( <div className="flex w-full h-full absolute items-center justify-center mt-10"> <div className=""> <Spinner size={"large"} variant={"secondary"} /> </div> </div> ) : ( <Table.Body {...getTableBodyProps()}> {rows.map((row) => { prepareRow(row) return ( <Table.Row color={"inherit"} linkTo={row.original.id} {...row.getRowProps()} className="group" > {row.cells.map((cell, index) => { return cell.render("Cell", { index }) })} </Table.Row> ) })} </Table.Body> )} </Table> <TablePagination count={count!} limit={queryObject.limit} offset={queryObject.offset} pageSize={queryObject.offset + rows.length} title="Orders" currentPage={pageIndex + 1} pageCount={pageCount} nextPage={handleNext} prevPage={handlePrev} hasNext={canNextPage} hasPrev={canPreviousPage} /> </div> ) }
Example #16
Source File: index.tsx From admin with MIT License | 4 votes |
DraftOrderTable: React.FC<RouteComponentProps> = () => { const location = useLocation() const { reset, paginate, setQuery: setFreeText, queryObject, } = useDraftOrderFilters(location.search, {}) const filtersOnLoad = queryObject const offs = parseInt(filtersOnLoad?.offset) || 0 const lim = parseInt(filtersOnLoad?.limit) || DEFAULT_PAGE_SIZE const [query, setQuery] = useState(filtersOnLoad?.query) const [numPages, setNumPages] = useState(0) const { draft_orders, isLoading, isRefetching, count } = useAdminDraftOrders( queryObject ) useEffect(() => { const controlledPageCount = Math.ceil(count! / queryObject.limit) setNumPages(controlledPageCount) }, [count, queryObject]) const [columns] = useDraftOrderTableColumns() const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, canPreviousPage, canNextPage, pageCount, gotoPage, nextPage, previousPage, // Get the state from the instance state: { pageIndex }, } = useTable( { columns, data: draft_orders || [], manualPagination: true, initialState: { pageSize: lim, pageIndex: offs / lim, }, pageCount: numPages, autoResetPage: false, }, usePagination ) // Debounced search useEffect(() => { const delayDebounceFn = setTimeout(() => { if (query) { setFreeText(query) gotoPage(0) } else { // if we delete query string, we reset the table view reset() } }, 400) return () => clearTimeout(delayDebounceFn) }, [query]) const handleNext = () => { if (canNextPage) { paginate(1) nextPage() } } const handlePrev = () => { if (canPreviousPage) { paginate(-1) previousPage() } } return ( <div className="w-full h-full overflow-y-auto flex flex-col justify-between"> {isLoading || isRefetching || !draft_orders ? ( <div className="w-full pt-2xlarge flex items-center justify-center"> <Spinner size={"large"} variant={"secondary"} /> </div> ) : ( <> <Table filteringOptions={[]} enableSearch handleSearch={setQuery} searchValue={query} {...getTableProps()} > <Table.Head> {headerGroups?.map((headerGroup, index) => ( <Table.HeadRow {...headerGroup.getHeaderGroupProps()}> {headerGroup.headers.map((col, headerIndex) => ( <Table.HeadCell className="w-[100px]" {...col.getHeaderProps()} > {col.render("Header")} </Table.HeadCell> ))} </Table.HeadRow> ))} </Table.Head> <Table.Body {...getTableBodyProps()}> {rows.map((row) => { prepareRow(row) return ( <Table.Row color={"inherit"} linkTo={`/a/draft-orders/${row.original.id}`} {...row.getRowProps()} > {row.cells.map((cell, index) => { return cell.render("Cell", { index }) })} </Table.Row> ) })} </Table.Body> </Table> <TablePagination count={count!} limit={queryObject.limit} offset={queryObject.offset} pageSize={queryObject.offset + rows.length} title="Draft Orders" currentPage={pageIndex + 1} pageCount={pageCount} nextPage={handleNext} prevPage={handlePrev} hasNext={canNextPage} hasPrev={canPreviousPage} /> </> )} </div> ) }
Example #17
Source File: MdxPageTabs.tsx From mantine with MIT License | 4 votes |
export function MdxPageTabs({ body, frontmatter, headings, siblings }: MdxPageProps) {
const [query, setQuery] = useState('');
const { classes } = useStyles();
const mobile = useMediaQuery('(max-width: 500px)');
const location = useLocation();
const initialTab = getInitialTab(location.search.replace('?t=', '') || 'docs');
const hasProps = Array.isArray(frontmatter.props);
const hasStyles = Array.isArray(frontmatter.styles);
if (!hasProps && !hasStyles) {
return null;
}
const propsTables = hasProps
? frontmatter.props.map((component) => (
<div key={component}>
<Title order={2} sx={{ fontWeight: 600 }} mb={20}>
{component} component props
</Title>
<PropsTable key={component} component={component} query={query} />
</div>
))
: null;
return (
<MdxPageBase>
<Tabs
variant="outline"
initialTab={initialTab}
onTabChange={(index) => {
const q = getTabQuery(index);
navigate(q ? `${location.pathname}?t=${q}` : location.pathname, {
replace: true,
});
}}
classNames={{ tabsList: classes.tabsList, tabsListWrapper: classes.tabsWrapper }}
>
<Tab label="Documentation" className={classes.tab}>
<div
className={classes.tabContent}
style={{
display: 'flex',
position: 'relative',
justifyContent: 'space-between',
}}
>
<div className={classes.main}>
<MDXRenderer>{body}</MDXRenderer>
<MdxSiblings siblings={siblings} />
</div>
<div className={classes.tableOfContents}>
<TableOfContents headings={headings} withTabs />
</div>
</div>
</Tab>
{hasProps && (
<Tab label={mobile ? 'Props' : 'Component props'} className={classes.tab}>
<div
style={{ maxWidth: 1178, marginLeft: 'auto', marginRight: 'auto', marginTop: 24 }}
className={classes.tabContent}
>
<TextInput
autoFocus
icon={<MagnifyingGlassIcon />}
placeholder="Search props"
mb={20}
value={query}
onChange={(event) => setQuery(event.currentTarget.value)}
/>
{propsTables}
</div>
</Tab>
)}
{hasStyles && (
<Tab label={mobile ? 'Styles' : 'Styles API'} className={classes.tab}>
<div
style={{ maxWidth: 1178, marginLeft: 'auto', marginRight: 'auto', marginTop: 24 }}
className={classes.tabContent}
>
<StylesApi components={frontmatter.styles} />
</div>
</Tab>
)}
</Tabs>
</MdxPageBase>
);
}