Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { createElement } from '@fluentui/react-jsx-runtime';

import { getSlotsNext } from '@fluentui/react-utilities';
import { assertSlots } from '@fluentui/react-utilities';

import { AccordionContext } from './AccordionContext';
import type { AccordionState, AccordionSlots, AccordionContextValues } from './Accordion.types';
Expand All @@ -12,11 +12,11 @@ import type { AccordionState, AccordionSlots, AccordionContextValues } from './A
* Function that renders the final JSX of the component
*/
export const renderAccordion_unstable = (state: AccordionState, contextValues: AccordionContextValues) => {
const { slots, slotProps } = getSlotsNext<AccordionSlots>(state);
assertSlots<AccordionSlots>(state);

return (
<slots.root {...slotProps.root}>
<AccordionContext.Provider value={contextValues.accordion}>{slotProps.root.children}</AccordionContext.Provider>
</slots.root>
<state.root>
<AccordionContext.Provider value={contextValues.accordion}>{state.root.children}</AccordionContext.Provider>
</state.root>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { getNativeElementProps, useControllableState, useEventCallback } from '@fluentui/react-utilities';
import { getNativeElementProps, useControllableState, useEventCallback, slot } from '@fluentui/react-utilities';
import type { AccordionProps, AccordionState, AccordionToggleData, AccordionToggleEvent } from './Accordion.types';
import type { AccordionItemValue } from '../AccordionItem/AccordionItem.types';
import { useArrowNavigationGroup } from '@fluentui/react-tabster';
Expand Down Expand Up @@ -42,11 +42,14 @@ export const useAccordion_unstable = (props: AccordionProps, ref: React.Ref<HTML
components: {
root: 'div',
},
root: getNativeElementProps('div', {
...props,
...(navigation ? arrowNavigationProps : {}),
ref,
}),
root: slot(
getNativeElementProps('div', {
...props,
...(navigation ? arrowNavigationProps : {}),
ref,
}),
{ required: true, elementType: 'div' },
),
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { createElement } from '@fluentui/react-jsx-runtime';

import { getSlotsNext } from '@fluentui/react-utilities';
import { assertSlots } from '@fluentui/react-utilities';
import { AccordionHeaderContext } from './AccordionHeaderContext';
import type { AccordionHeaderState, AccordionHeaderSlots, AccordionHeaderContextValues } from './AccordionHeader.types';

Expand All @@ -14,18 +14,18 @@ export const renderAccordionHeader_unstable = (
state: AccordionHeaderState,
contextValues: AccordionHeaderContextValues,
) => {
const { slots, slotProps } = getSlotsNext<AccordionHeaderSlots>(state);
assertSlots<AccordionHeaderSlots>(state);

return (
<AccordionHeaderContext.Provider value={contextValues.accordionHeader}>
<slots.root {...slotProps.root}>
<slots.button {...slotProps.button}>
{state.expandIconPosition === 'start' && slots.expandIcon && <slots.expandIcon {...slotProps.expandIcon} />}
{slots.icon && <slots.icon {...slotProps.icon} />}
{slotProps.root.children}
{state.expandIconPosition === 'end' && slots.expandIcon && <slots.expandIcon {...slotProps.expandIcon} />}
</slots.button>
</slots.root>
<state.root>
<state.button>
{state.expandIconPosition === 'start' && state.expandIcon && <state.expandIcon />}
{state.icon && <state.icon />}
{state.root.children}
{state.expandIconPosition === 'end' && state.expandIcon && <state.expandIcon />}
</state.button>
</state.root>
</AccordionHeaderContext.Provider>
);
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import * as React from 'react';
import {
getNativeElementProps,
isResolvedShorthand,
resolveShorthand,
useEventCallback,
} from '@fluentui/react-utilities';
import { getNativeElementProps, isResolvedShorthand, slot, useEventCallback } from '@fluentui/react-utilities';
import { useAccordionItemContext_unstable } from '../AccordionItem/index';
import { ARIAButtonSlotProps, useARIAButtonShorthand } from '@fluentui/react-aria';
import type { AccordionHeaderProps, AccordionHeaderState } from './AccordionHeader.types';
Expand Down Expand Up @@ -54,19 +49,23 @@ export const useAccordionHeader_unstable = (
expandIcon: 'span',
icon: 'div',
},
root: getNativeElementProps(as || 'div', {
ref,
...props,
}),
icon: resolveShorthand(icon),
expandIcon: resolveShorthand(expandIcon, {
root: slot(
getNativeElementProps(as || 'div', {
ref,
...props,
}),
{ required: true, elementType: 'div' },
),
icon: slot(icon, { elementType: 'div' }),
expandIcon: slot(expandIcon, {
required: true,
defaultProps: {
children: <ChevronRightRegular style={{ transform: `rotate(${expandIconRotation}deg)` }} />,
'aria-hidden': true,
},
elementType: 'span',
}),
button: resolveShorthand<ARIAButtonSlotProps<'a'>>(
button: slot<ARIAButtonSlotProps<'a'>>(
{
...useARIAButtonShorthand(button, {
required: true,
Expand All @@ -86,7 +85,7 @@ export const useAccordionHeader_unstable = (
}
}),
},
{ required: true },
{ required: true, elementType: 'button' },
),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@

import { createElement } from '@fluentui/react-jsx-runtime';

import { getSlotsNext } from '@fluentui/react-utilities';
import { assertSlots } from '@fluentui/react-utilities';
import { AccordionItemContext } from './AccordionItemContext';
import type { AccordionItemState, AccordionItemSlots, AccordionItemContextValues } from './AccordionItem.types';

/**
* Function that renders the final JSX of the component
*/
export const renderAccordionItem_unstable = (state: AccordionItemState, contextValues: AccordionItemContextValues) => {
const { slots, slotProps } = getSlotsNext<AccordionItemSlots>(state);
assertSlots<AccordionItemSlots>(state);

return (
<slots.root {...slotProps.root}>
<state.root>
<AccordionItemContext.Provider value={contextValues.accordionItem}>
{slotProps.root.children}
{state.root.children}
</AccordionItemContext.Provider>
</slots.root>
</state.root>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { getNativeElementProps } from '@fluentui/react-utilities';
import { getNativeElementProps, slot } from '@fluentui/react-utilities';
import { useAccordionContext_unstable } from '../Accordion/AccordionContext';
import type { AccordionItemProps, AccordionItemState } from './AccordionItem.types';
import type { AccordionToggleEvent } from '../Accordion/Accordion.types';
Expand Down Expand Up @@ -29,9 +29,12 @@ export const useAccordionItem_unstable = (
components: {
root: 'div',
},
root: getNativeElementProps('div', {
ref: ref,
...props,
}),
root: slot(
getNativeElementProps('div', {
ref,
...props,
}),
{ required: true, elementType: 'div' },
),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@

import { createElement } from '@fluentui/react-jsx-runtime';

import { getSlotsNext } from '@fluentui/react-utilities';
import { assertSlots } from '@fluentui/react-utilities';
import type { AccordionPanelState, AccordionPanelSlots } from './AccordionPanel.types';

/**
* Function that renders the final JSX of the component
*/
export const renderAccordionPanel_unstable = (state: AccordionPanelState) => {
const { slots, slotProps } = getSlotsNext<AccordionPanelSlots>(state);
return state.open ? <slots.root {...slotProps.root}>{slotProps.root.children}</slots.root> : null;
assertSlots<AccordionPanelSlots>(state);
return state.open ? <state.root>{state.root.children}</state.root> : null;
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { getNativeElementProps } from '@fluentui/react-utilities';
import { getNativeElementProps, slot } from '@fluentui/react-utilities';
import { useTabsterAttributes } from '@fluentui/react-tabster';
import { useAccordionItemContext_unstable } from '../AccordionItem/index';
import { useAccordionContext_unstable } from '../Accordion/AccordionContext';
Expand All @@ -23,10 +23,13 @@ export const useAccordionPanel_unstable = (
components: {
root: 'div',
},
root: getNativeElementProps('div', {
ref,
...props,
...(navigation && focusableProps),
}),
root: slot(
getNativeElementProps('div', {
ref,
...props,
...(navigation && focusableProps),
}),
{ required: true, elementType: 'div' },
),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
/** @jsx createElement */

import { createElement } from '@fluentui/react-jsx-runtime';
import { getSlotsNext } from '@fluentui/react-utilities';
import { assertSlots } from '@fluentui/react-utilities';

import type { AlertState, AlertSlots } from './Alert.types';

export const renderAlert_unstable = (state: AlertState) => {
const { slots, slotProps } = getSlotsNext<AlertSlots>(state);
assertSlots<AlertSlots>(state);

return (
<slots.root {...slotProps.root}>
{slots.icon && <slots.icon {...slotProps.icon} />}
{slots.avatar && <slots.avatar {...slotProps.avatar} />}
{slotProps.root.children}
{slots.action && <slots.action {...slotProps.action} />}
</slots.root>
<state.root>
{state.icon && <state.icon />}
{state.avatar && <state.avatar />}
{state.root.children}
{state.action && <state.action />}
</state.root>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react';
import { Avatar } from '@fluentui/react-avatar';
import { Button } from '@fluentui/react-button';
import { CheckmarkCircleFilled, DismissCircleFilled, InfoFilled, WarningFilled } from '@fluentui/react-icons';
import { getNativeElementProps, resolveShorthand } from '@fluentui/react-utilities';
import { getNativeElementProps, slot } from '@fluentui/react-utilities';

import type { AlertProps, AlertState } from './Alert.types';

Expand Down Expand Up @@ -39,36 +39,27 @@ export const useAlert_unstable = (props: AlertProps, ref: React.Ref<HTMLElement>
break;
}

const action = resolveShorthand(props.action, { defaultProps: { appearance: 'transparent' } });
const avatar = resolveShorthand(props.avatar);
const action = slot(props.action, { defaultProps: { appearance: 'transparent' }, elementType: Button });
const avatar = slot(props.avatar, { elementType: Avatar });
let icon;
/** Avatar prop takes precedence over the icon or intent prop */
if (!avatar) {
icon = resolveShorthand(props.icon, {
defaultProps: {
children: defaultIcon,
},
required: !!props.intent,
});
/** Avatar prop takes precedence over the icon or intent prop */ if (!avatar) {
icon = slot(props.icon, { defaultProps: { children: defaultIcon }, required: !!props.intent, elementType: 'span' });
}

return {
action,
appearance,
avatar,
components: {
root: 'div',
icon: 'span',
action: Button,
avatar: Avatar,
},
components: { root: 'div', icon: 'span', action: Button, avatar: Avatar },
icon,
intent,
root: getNativeElementProps('div', {
ref,
role: defaultRole,
children: props.children,
...props,
}),
root: slot(
getNativeElementProps('div', {
ref,
role: defaultRole,
children: props.children,
...props,
}),
{ required: true, elementType: 'div' },
),
};
};
1 change: 1 addition & 0 deletions packages/react-components/react-aria/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"dependencies": {
"@fluentui/keyboard-keys": "^9.0.3",
"@fluentui/react-utilities": "^9.9.2",
"@fluentui/react-jsx-runtime": "9.0.0-alpha.6",
"@swc/helpers": "^0.4.14"
},
"peerDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import * as React from 'react';
/** @jsxRuntime classic */
/** @jsx createElement */

import { createElement } from '@fluentui/react-jsx-runtime';

import { useARIAButtonProps } from './useARIAButtonProps';
import { renderHook } from '@testing-library/react-hooks';
import { fireEvent, render } from '@testing-library/react';
import { getSlots, Slot, ComponentProps } from '@fluentui/react-utilities';
import { Slot, ComponentProps, assertSlots } from '@fluentui/react-utilities';
import { ARIAButtonProps, ARIAButtonSlotProps } from './types';
import { useARIAButtonShorthand } from './useARIAButtonShorthand';

const TestButton = (props: ComponentProps<{ root: Slot<ARIAButtonSlotProps> }>) => {
const { slots, slotProps } = getSlots<{ root: Slot<ARIAButtonSlotProps> }>({
components: { root: 'button' },
type TestSlots = { root: Slot<ARIAButtonSlotProps> };
const state = {
components: { root: props.as ?? 'button' },
root: useARIAButtonShorthand(props, { required: true }),
});
return <slots.root {...slotProps.root} />;
};
assertSlots<TestSlots>(state);
return <state.root />;
};

describe('useARIAButton', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { resolveShorthand } from '@fluentui/react-utilities';
import * as React from 'react';
import { isResolvedShorthand, slot } from '@fluentui/react-utilities';
import { useARIAButtonProps } from './useARIAButtonProps';
import type { ResolveShorthandFunction } from '@fluentui/react-utilities';
import type { ARIAButtonProps, ARIAButtonSlotProps, ARIAButtonType } from './types';
Expand All @@ -12,8 +13,13 @@ import type { ARIAButtonProps, ARIAButtonSlotProps, ARIAButtonType } from './typ
* for multiple scenarios of shorthand properties. Ensuring 1st rule of ARIA for cases
* where no attribute addition is required.
*/
export const useARIAButtonShorthand: ResolveShorthandFunction<ARIAButtonSlotProps> = (slot, options) => {
const shorthand = resolveShorthand(slot, options);
// eslint-disable-next-line deprecation/deprecation
export const useARIAButtonShorthand: ResolveShorthandFunction<ARIAButtonSlotProps> = (value, options) => {
const elementType = isResolvedShorthand(value) ? value.as ?? 'button' : ('button' as const);
const shorthand = slot(value, {
...options,
elementType: elementType as React.ElementType<ARIAButtonSlotProps> as React.ComponentType<ARIAButtonSlotProps>,
});
const shorthandARIAButton = useARIAButtonProps<ARIAButtonType, ARIAButtonProps>(shorthand?.as ?? 'button', shorthand);
return shorthand && shorthandARIAButton;
};
Loading