Skip to content

Commit

Permalink
Fix registering ToolbarLink as composite item
Browse files Browse the repository at this point in the history
  • Loading branch information
mj12albert committed Jan 27, 2025
1 parent f79f0e5 commit 2901a4d
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 17 deletions.
8 changes: 2 additions & 6 deletions packages/react/src/toolbar/button/ToolbarButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@ import { useComponentRenderer } from '../../utils/useComponentRenderer';
import { BaseUIComponentProps } from '../../utils/types';
import { useButton } from '../../use-button';
import { CompositeItem } from '../../composite/item/CompositeItem';
import type { ToolbarRoot } from '../root/ToolbarRoot';
import type { ToolbarRoot, ToolbarItemMetadata } from '../root/ToolbarRoot';
import { useToolbarRootContext } from '../root/ToolbarRootContext';
import { useToolbarGroupContext } from '../group/ToolbarGroupContext';

export interface ToolbarButtonMetadata {
focusableWhenDisabled: boolean;
}

/**
* A button that can be used as-is or as a trigger for other components.
* Renders a `<button>` element.
Expand Down Expand Up @@ -63,7 +59,7 @@ const ToolbarButton = React.forwardRef(function ToolbarButton(
extraProps: otherProps,
});

return <CompositeItem<ToolbarButtonMetadata> metadata={itemMetadata} render={renderElement()} />;
return <CompositeItem<ToolbarItemMetadata> metadata={itemMetadata} render={renderElement()} />;
});

export namespace ToolbarButton {
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/toolbar/link/ToolbarLink.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ describe('<Toolbar.Link />', () => {
it('renders an anchor', async () => {
const { getByTestId } = await render(
<Toolbar.Root>
<Toolbar.Link data-testid="link" />
<Toolbar.Link data-testid="link" href="https://base-ui.com" />
</Toolbar.Root>,
);

expect(getByTestId('button')).to.equal(screen.getByRole('button'));
expect(getByTestId('link')).to.equal(screen.getByRole('link'));
});
});
});
10 changes: 8 additions & 2 deletions packages/react/src/toolbar/link/ToolbarLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import { useComponentRenderer } from '../../utils/useComponentRenderer';
import { BaseUIComponentProps } from '../../utils/types';
import { useButton } from '../../use-button';
import { CompositeItem } from '../../composite/item/CompositeItem';
import type { ToolbarOrientation } from '../root/ToolbarRoot';
import type { ToolbarOrientation, ToolbarItemMetadata } from '../root/ToolbarRoot';
import { useToolbarRootContext } from '../root/ToolbarRootContext';

const TOOLBAR_LINK_METADATA = {
focusableWhenDisabled: true,
};

const ToolbarLink = React.forwardRef(function ToolbarLink(
props: ToolbarLink.Props,
forwardedRef: React.ForwardedRef<HTMLAnchorElement>,
Expand Down Expand Up @@ -36,7 +40,9 @@ const ToolbarLink = React.forwardRef(function ToolbarLink(
extraProps: otherProps,
});

return <CompositeItem render={renderElement()} />;
return (
<CompositeItem<ToolbarItemMetadata> metadata={TOOLBAR_LINK_METADATA} render={renderElement()} />
);
});

export namespace ToolbarLink {
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/toolbar/root/ToolbarRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ const ToolbarRoot = React.forwardRef(function ToolbarRoot(

export type ToolbarOrientation = 'horizontal' | 'vertical';

export interface ToolbarItemMetadata {
focusableWhenDisabled: boolean;
}

namespace ToolbarRoot {
export type State = {
disabled: boolean;
Expand Down
5 changes: 2 additions & 3 deletions packages/react/src/toolbar/root/ToolbarRootContext.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
'use client';
import * as React from 'react';
import type { CompositeMetadata } from '../../composite/list/CompositeList';
import type { ToolbarButtonMetadata } from '../button/ToolbarButton';
import type { ToolbarOrientation } from './ToolbarRoot';
import type { ToolbarOrientation, ToolbarItemMetadata } from './ToolbarRoot';

export interface ToolbarRootContext {
disabled: boolean;
orientation: ToolbarOrientation;
setItemMap: React.Dispatch<
React.SetStateAction<Map<Node, CompositeMetadata<ToolbarButtonMetadata> | null>>
React.SetStateAction<Map<Node, CompositeMetadata<ToolbarItemMetadata> | null>>
>;
}

Expand Down
6 changes: 3 additions & 3 deletions packages/react/src/toolbar/root/useToolbarRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import * as React from 'react';
import { mergeReactProps } from '../../utils/mergeReactProps';
import { GenericHTMLProps } from '../../utils/types';
import type { ToolbarButtonMetadata } from '../button/ToolbarButton';
import type { CompositeMetadata } from '../../composite/list/CompositeList';
import type { ToolbarItemMetadata } from './ToolbarRoot';

function useToolbarRoot(parameters: useToolbarRoot.Parameters): useToolbarRoot.ReturnValue {
const { orientation } = parameters;

const [itemMap, setItemMap] = React.useState(
() => new Map<Node, CompositeMetadata<ToolbarButtonMetadata> | null>(),
() => new Map<Node, CompositeMetadata<ToolbarItemMetadata> | null>(),
);

const disabledIndices = React.useMemo(() => {
Expand Down Expand Up @@ -60,7 +60,7 @@ namespace useToolbarRoot {
getRootProps: (externalProps?: GenericHTMLProps) => GenericHTMLProps;
disabledIndices: number[];
setItemMap: React.Dispatch<
React.SetStateAction<Map<Node, CompositeMetadata<ToolbarButtonMetadata> | null>>
React.SetStateAction<Map<Node, CompositeMetadata<ToolbarItemMetadata> | null>>
>;
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/use-button/useButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ export function useButton(parameters: useButton.Parameters = {}): useButton.Retu
} else if (elementName !== '') {
if (elementName !== 'A') {
additionalProps.role = 'button';
additionalProps.tabIndex = tabIndex ?? 0;
} else if (tabIndex) {
additionalProps.tabIndex = tabIndex;
}
additionalProps.tabIndex = tabIndex ?? 0;
if (disabled) {
additionalProps['aria-disabled'] = disabled as boolean;
additionalProps.tabIndex = focusableWhenDisabled ? (tabIndex ?? 0) : -1;
Expand Down

0 comments on commit 2901a4d

Please sign in to comment.