Skip to content

Commit

Permalink
Merge branch 'master' into fix/disabled-tab-nav
Browse files Browse the repository at this point in the history
  • Loading branch information
mj12albert authored Feb 24, 2025
2 parents dc4cf93 + 20bf89e commit ee90169
Show file tree
Hide file tree
Showing 76 changed files with 1,167 additions and 1,114 deletions.
2 changes: 1 addition & 1 deletion docs/reference/generated/alert-dialog-root.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "(open, event, reason) => void",
"description": "Event handler called when the dialog is opened or closed."
},
"action": {
"actionsRef": {
"type": "{ current: { unmount: func } }",
"description": "A ref to imperative actions."
},
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/generated/dialog-root.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "(open, event, reason) => void",
"description": "Event handler called when the dialog is opened or closed."
},
"action": {
"actionsRef": {
"type": "{ current: { unmount: func } }",
"description": "A ref to imperative actions."
},
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/generated/menu-root.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "(open, event) => void",
"description": "Event handler called when the menu is opened or closed."
},
"action": {
"actionsRef": {
"type": "{ current: { unmount: func } }",
"description": "A ref to imperative actions."
},
Expand Down
5 changes: 0 additions & 5 deletions docs/reference/generated/menu-submenu-trigger.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
"type": "string",
"description": "Overrides the text label to use when the item is matched during keyboard text navigation."
},
"disabled": {
"type": "boolean",
"default": "false",
"description": "Whether the component should ignore user interaction."
},
"className": {
"type": "string | (state) => string",
"description": "CSS class applied to the element, or a function that\nreturns a class based on the component’s state."
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/generated/popover-root.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "(open, event, reason) => void",
"description": "Event handler called when the popover is opened or closed."
},
"action": {
"actionsRef": {
"type": "{ current: { unmount: func } }",
"description": "A ref to imperative actions."
},
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/generated/preview-card-root.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "(open, event, reason) => void",
"description": "Event handler called when the preview card is opened or closed."
},
"action": {
"actionsRef": {
"type": "{ current: { unmount: func } }",
"description": "A ref to imperative actions."
},
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/generated/tooltip-root.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "(open, event, reason) => void",
"description": "Event handler called when the tooltip is opened or closed."
},
"action": {
"actionsRef": {
"type": "{ current: { unmount: func } }",
"description": "A ref to imperative actions."
},
Expand Down
91 changes: 86 additions & 5 deletions docs/src/app/(private)/experiments/menu/menu-fully-featured.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,40 @@ interface Settings {
customAnchor: boolean;
modal: boolean;
openOnHover: boolean;
disabled: boolean;
customTriggerElement: boolean;
side: Menu.Positioner.Props['side'];
align: Menu.Positioner.Props['align'];
}

export default function MenuFullyFeatured() {
const { settings } = useExperimentSettings<Settings>();

const anchorRef = React.useRef<HTMLDivElement>(null);

const triggerRender = React.useMemo(
() => (settings.customTriggerElement ? <span /> : undefined),
[settings.customTriggerElement],
);

return (
<div>
<Menu.Root openOnHover={settings.openOnHover} modal={settings.modal}>
<Menu.Trigger className={classes.Button}>
<h1>Fully featured menu</h1>
<Menu.Root
openOnHover={settings.openOnHover}
modal={settings.modal}
disabled={settings.disabled}
>
<Menu.Trigger className={classes.Button} render={triggerRender}>
Menu <ChevronDownIcon className={classes.ButtonIcon} />
</Menu.Trigger>
<Menu.Portal keepMounted>
<Menu.Positioner
className={classes.Positioner}
sideOffset={8}
anchor={settings.customAnchor ? anchorRef : undefined}
side={settings.side}
align={settings.align}
>
<Menu.Popup className={classes.Popup}>
<Menu.Arrow className={classes.Arrow}>
Expand Down Expand Up @@ -59,7 +76,7 @@ export default function MenuFullyFeatured() {
Radio items
</Menu.GroupLabel>
<Menu.RadioGroup>
<Menu.RadioItem className={classes.RadioItem} value="date">
<Menu.RadioItem className={classes.RadioItem} value="o1">
<Menu.RadioItemIndicator
className={classes.RadioItemIndicator}
>
Expand All @@ -69,7 +86,7 @@ export default function MenuFullyFeatured() {
</Menu.RadioItemIndicator>
<span className={classes.RadioItemText}>Option 1</span>
</Menu.RadioItem>
<Menu.RadioItem className={classes.RadioItem} value="name">
<Menu.RadioItem className={classes.RadioItem} value="o2">
<Menu.RadioItemIndicator
className={classes.RadioItemIndicator}
>
Expand All @@ -81,7 +98,7 @@ export default function MenuFullyFeatured() {
</Menu.RadioItem>
<Menu.RadioItem
className={classes.RadioItem}
value="type"
value="o3"
closeOnClick
>
<Menu.RadioItemIndicator
Expand All @@ -95,6 +112,22 @@ export default function MenuFullyFeatured() {
Option 3 (close on click)
</span>
</Menu.RadioItem>
<Menu.RadioItem
className={classes.RadioItem}
value="o4"
disabled
>
<Menu.RadioItemIndicator
className={classes.RadioItemIndicator}
>
<CheckIcon
className={classes.RadioItemIndicatorIcon}
/>
</Menu.RadioItemIndicator>
<span className={classes.RadioItemText}>
Disabled option
</span>
</Menu.RadioItem>
</Menu.RadioGroup>
</Menu.Group>

Expand Down Expand Up @@ -139,6 +172,18 @@ export default function MenuFullyFeatured() {
Option C (close on click)
</span>
</Menu.CheckboxItem>
<Menu.CheckboxItem className={classes.CheckboxItem} disabled>
<Menu.CheckboxItemIndicator
className={classes.CheckboxItemIndicator}
>
<CheckIcon
className={classes.CheckboxItemIndicatorIcon}
/>
</Menu.CheckboxItemIndicator>
<span className={classes.CheckboxItemText}>
Disabled option
</span>
</Menu.CheckboxItem>
</Menu.Group>

<Menu.Separator className={classes.Separator} />
Expand Down Expand Up @@ -171,6 +216,22 @@ export default function MenuFullyFeatured() {
</Menu.Positioner>
</Menu.Portal>
</Menu.Root>

<Menu.Root disabled>
<Menu.SubmenuTrigger className={classes.SubmenuTrigger}>
Disabled nested menu
<ChevronRightIcon />
</Menu.SubmenuTrigger>
<Menu.Portal>
<Menu.Positioner className={classes.Positioner} sideOffset={8}>
<Menu.Popup className={classes.Popup}>
<Menu.Item className={classes.Item}>
This should not appear
</Menu.Item>
</Menu.Popup>
</Menu.Positioner>
</Menu.Portal>
</Menu.Root>
</Menu.Popup>
</Menu.Positioner>
</Menu.Portal>
Expand Down Expand Up @@ -199,6 +260,26 @@ export const settingsMetadata: SettingsMetadata<Settings> = {
type: 'boolean',
label: 'Open on hover',
},
disabled: {
type: 'boolean',
label: 'Disabled',
},
customTriggerElement: {
type: 'boolean',
label: 'Trigger as <span>',
},
side: {
type: 'string',
label: 'Side',
options: ['top', 'right', 'bottom', 'left'],
default: 'bottom',
},
align: {
type: 'string',
label: 'Align',
options: ['start', 'center', 'end'],
default: 'center',
},
};

function ChevronDownIcon(props: React.ComponentProps<'svg'>) {
Expand Down
2 changes: 1 addition & 1 deletion docs/src/app/(private)/experiments/menu/menu-nested.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default function NestedMenu() {
Paragraph
</MenuItem>
<Menu.Root disabled>
<SubmenuTrigger disabled>List</SubmenuTrigger>
<SubmenuTrigger>List</SubmenuTrigger>
<Menu.Portal>
<Menu.Positioner
align="start"
Expand Down
8 changes: 8 additions & 0 deletions docs/src/app/(private)/experiments/menu/menu.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@
border-radius: 0.25rem;
background-color: var(--color-gray-900);
}

&[data-disabled][data-highlighted]::before {
background-color: var(--color-gray-300);
}

&[data-disabled] {
color: var(--color-gray-400);
}
}

.CheckboxItemIndicator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function MenuDemo({ modal }: Props) {
Paragraph
</MenuItem>
<Menu.Root disabled>
<SubmenuTrigger disabled>List</SubmenuTrigger>
<SubmenuTrigger>List</SubmenuTrigger>
<Menu.Portal>
<Menu.Positioner
align="start"
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-material-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"devDependencies": {
"@types/eslint": "^8.56.12",
"@typescript-eslint/experimental-utils": "^5.62.0",
"@typescript-eslint/parser": "^8.24.0"
"@typescript-eslint/parser": "^8.24.1"
},
"license": "MIT"
}
6 changes: 3 additions & 3 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"typescript": "tsc -b tsconfig.json"
},
"dependencies": {
"@babel/runtime": "^7.26.7",
"@babel/runtime": "^7.26.9",
"@floating-ui/react": "^0.27.4",
"@floating-ui/utils": "^0.2.9",
"@react-aria/overlays": "^3.25.0",
Expand All @@ -99,10 +99,10 @@
"chai": "^4.5.0",
"fs-extra": "^11.3.0",
"lodash": "^4.17.21",
"publint": "^0.3.4",
"publint": "^0.3.5",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.1.5",
"react-router-dom": "^7.2.0",
"sinon": "^19.0.2",
"typescript": "^5.7.3"
},
Expand Down
7 changes: 2 additions & 5 deletions packages/react/src/accordion/root/AccordionRoot.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import { expect } from 'chai';
import { spy } from 'sinon';
import { flushMicrotasks } from '@mui/internal-test-utils';
import { DirectionProvider } from '@base-ui-components/react/direction-provider';
import { Accordion } from '@base-ui-components/react/accordion';
import { createRenderer, describeConformance, isJSDOM } from '#test-utils';
Expand Down Expand Up @@ -149,17 +148,15 @@ describe('<Accordion.Root />', () => {
expect(trigger).to.have.attribute('aria-expanded', 'false');
expect(queryByText(PANEL_CONTENT_1)).to.equal(null);

setProps({ value: [0] });
await flushMicrotasks();
await setProps({ value: [0] });

expect(trigger).to.have.attribute('aria-expanded', 'true');
expect(trigger).to.have.attribute('data-panel-open');
expect(queryByText(PANEL_CONTENT_1)).to.not.equal(null);
expect(queryByText(PANEL_CONTENT_1)).toBeVisible();
expect(queryByText(PANEL_CONTENT_1)).to.have.attribute('data-open');

setProps({ value: [] });
await flushMicrotasks();
await setProps({ value: [] });

expect(trigger).to.have.attribute('aria-expanded', 'false');
expect(queryByText(PANEL_CONTENT_1)).to.equal(null);
Expand Down
16 changes: 15 additions & 1 deletion packages/react/src/alert-dialog/root/AlertDialogRoot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import { expect } from 'chai';
import { act, screen, waitFor } from '@mui/internal-test-utils';
import { AlertDialog } from '@base-ui-components/react/alert-dialog';
import { createRenderer, isJSDOM } from '#test-utils';
import { createRenderer, isJSDOM, popupConformanceTests } from '#test-utils';
import { spy } from 'sinon';

describe('<AlertDialog.Root />', () => {
Expand All @@ -12,6 +12,20 @@ describe('<AlertDialog.Root />', () => {
globalThis.BASE_UI_ANIMATIONS_DISABLED = true;
});

popupConformanceTests({
createComponent: (props) => (
<AlertDialog.Root {...props.root}>
<AlertDialog.Trigger {...props.trigger}>Open dialog</AlertDialog.Trigger>
<AlertDialog.Portal {...props.portal}>
<AlertDialog.Popup {...props.popup}>Dialog</AlertDialog.Popup>
</AlertDialog.Portal>
</AlertDialog.Root>
),
render,
triggerMouseAction: 'click',
expectedPopupRole: 'alertdialog',
});

it('ARIA attributes', async () => {
const { queryByRole, getByText } = await render(
<AlertDialog.Root open>
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/alert-dialog/root/AlertDialogRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ AlertDialogRoot.propTypes /* remove-proptypes */ = {
/**
* A ref to imperative actions.
*/
action: PropTypes.shape({
actionsRef: PropTypes.shape({
current: PropTypes.shape({
unmount: PropTypes.func.isRequired,
}).isRequired,
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/checkbox/root/CheckboxRoot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ describe('<Checkbox.Root />', () => {
expect(indicator).to.have.attribute('data-readonly', '');
expect(indicator).to.have.attribute('data-required', '');

setProps({ disabled: false, readOnly: false });
await setProps({ disabled: false, readOnly: false });
fireEvent.click(checkbox);

expect(checkbox).to.have.attribute('data-unchecked', '');
Expand Down
Loading

0 comments on commit ee90169

Please sign in to comment.