Skip to content

Commit

Permalink
fix: Breadcrumbs not working without BreadcrumbsContext (#464)
Browse files Browse the repository at this point in the history
  • Loading branch information
dogmar authored Apr 20, 2023
1 parent 10133d2 commit e535483
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/components/Breadcrumbs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function CrumbLink({
const { Link } = useNavigationContext()

return (
<CrumbLinkWrap>
<CrumbLinkWrap {...(isLast ? { 'aria-current': 'page' } : {})}>
<CrumbLinkText className={classNames({ isLast })}>
{isLast || typeof crumb.url !== 'string' ? (
crumb.label
Expand Down Expand Up @@ -361,7 +361,7 @@ export function Breadcrumbs({
breadcrumbs: propsCrumbs,
...props
}: BreadcrumbsProps) {
const { breadcrumbs: contextCrumbs } = useContext(BreadcrumbsContext)
const contextCrumbs = useContext(BreadcrumbsContext)?.breadcrumbs
const breadcrumbs = propsCrumbs || contextCrumbs

if (!breadcrumbs) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/TabPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { type MakeOptional, type Renderer, type TabStateRef } from './TabList'

/*
mode='multipanel'
Use when you all tab content visible in the DOM at all time (such as for
Use when you want all tab content visible in the DOM at all times (such as for
search indexing the docs site, etc).
In this mode, each tab will need it's own TabPanel with the `tabKey` prop set
to the same key as the tab associated with it.
Expand Down
6 changes: 3 additions & 3 deletions src/markdoc/components/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { createColumnHelper } from '@tanstack/react-table'

import { Fragment } from 'react'

import { Table as PluralTable } from '../../index'

type TableProps = {
Expand All @@ -14,12 +16,10 @@ function Table({ thead, tbody }: TableProps) {
return null
}

// const data = tbody.map(tr => Object.fromEntries(tr.map((td, idx) => [`x${idx}`, td])))

const columns = thead.map((th, idx) =>
columnHelper.accessor((row) => row[idx], {
id: th,
cell: (info: any) => info.getValue(),
cell: (info) => <Fragment key={idx}>{info.getValue()}</Fragment>,
header: () => <span>{th}</span>,
})
)
Expand Down
18 changes: 13 additions & 5 deletions src/markdoc/components/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
type PropsWithChildren,
type ReactNode,
createContext,
useMemo,
useRef,
useState,
} from 'react'
Expand All @@ -28,6 +29,9 @@ type TabProps = {
children: ReactNode
}

const getTabKey = (tab: TabProps, index: number) =>
`${tab.title ?? ''}-${index}`

export function Tabs({ tabs }: { tabs: TabProps[] }) {
const tabStateRef = useRef<any>()
const [selectedKey, setSelectedKey] = useState<Key>(tabs[0].title || '')
Expand All @@ -37,26 +41,30 @@ export function Tabs({ tabs }: { tabs: TabProps[] }) {
selectedKey,
onSelectionChange: setSelectedKey,
}
const keyedTabs = useMemo(
() => tabs.map((tab, i) => ({ key: getTabKey(tab, i), ...tab })),
[tabs]
)

return (
<TabContext.Provider value={selectedKey}>
<TabListStyled
stateRef={tabStateRef}
stateProps={tabListStateProps}
>
{tabs.map(({ title }) => (
{keyedTabs.map(({ key, title }) => (
<TabComponent
key={title}
key={key}
textValue={title}
>
{title}
</TabComponent>
))}
</TabListStyled>
{tabs.map(({ children, title }) => (
{keyedTabs.map(({ key, children }) => (
<TabPanel
key={title}
tabKey={title}
key={key}
tabKey={key}
mode="multipanel"
stateRef={tabStateRef}
>
Expand Down
61 changes: 56 additions & 5 deletions src/stories/Breadcrumbs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const crumbList: Breadcrumb[] = [

const crumbLists = crumbList.map((_, i) => crumbList.slice(0, i + 1))

function CrumbSetter() {
function CrumbContextSetter() {
const [selectedList, setSelectedList] = useState<string>(
(crumbLists.length - 1).toString()
)
Expand Down Expand Up @@ -96,7 +96,7 @@ function CrumbSetter() {
)
}

function Template(args: any) {
function WithContextTemplate(args: any) {
return (
<NavContextProviderStub>
<BreadcrumbsProvider>
Expand All @@ -109,16 +109,67 @@ function Template(args: any) {
{...args}
marginBottom="xlarge"
/>
<CrumbSetter />
<CrumbContextSetter />
</Flex>
</BreadcrumbsProvider>
</NavContextProviderStub>
)
}

export const Default = Template.bind({})
function ManualTemplate(args: any) {
const [selectedList, setSelectedList] = useState<string>(
(crumbLists.length - 1).toString()
)

const crumbList = crumbLists[selectedList]

return (
<NavContextProviderStub>
<Flex
flexDirection="column"
gap="large"
>
{/* SINGLE SELECT */}
<Breadcrumbs
{...args}
breadcrumbs={crumbList}
marginBottom="xlarge"
/>
<FormField label="Select a page">
<Select
label="..."
selectedKey={selectedList}
onSelectionChange={(key) => setSelectedList(key as string)}
>
{crumbLists.map((crumbs, i) => {
const lastCrumb = crumbs[crumbs.length - 1]

return (
<ListBoxItem
key={i.toString()}
textValue={lastCrumb.textValue}
label={lastCrumb.label}
/>
)
})}
</Select>
</FormField>
</Flex>
</NavContextProviderStub>
)
}

export const UsingContext = WithContextTemplate.bind({})

UsingContext.args = {
minLength: undefined,
maxLength: undefined,
collapsible: true,
}

export const Manual = ManualTemplate.bind({})

Default.args = {
Manual.args = {
minLength: undefined,
maxLength: undefined,
collapsible: true,
Expand Down

0 comments on commit e535483

Please sign in to comment.