Skip to content
Merged
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
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Creating AvatarGroupItem component.",
"packageName": "@fluentui/react-avatar",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "./api-extractor.json",
"mainEntryPointFilePath": "<projectFolder>/dist/packages/react-components/<unscopedPackageName>/src/index.d.ts"
"mainEntryPointFilePath": "<projectFolder>/dist/types/packages/react-components/<unscopedPackageName>/src/index.d.ts"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why is this change needed in this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create-component added it, it doesn't seem to affect anything though. I can remove it just in case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure what this actually does. But if it was added by create-component, and it doesn't break things, then it should be fine.

}
26 changes: 26 additions & 0 deletions packages/react-components/react-avatar/etc/react-avatar.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ export const AvatarGroup: ForwardRefComponent<AvatarGroupProps>;
// @public (undocumented)
export const avatarGroupClassNames: SlotClassNames<AvatarGroupSlots>;

// @public
export const AvatarGroupItem: ForwardRefComponent<AvatarGroupItemProps>;

// @public (undocumented)
export const avatarGroupItemClassNames: SlotClassNames<AvatarGroupItemSlots>;

// @public
export type AvatarGroupItemProps = ComponentProps<AvatarGroupItemSlots> & {};

// @public (undocumented)
export type AvatarGroupItemSlots = {
root: Slot<'div'>;
};

// @public
export type AvatarGroupItemState = ComponentState<AvatarGroupItemSlots>;

// @public
export type AvatarGroupProps = ComponentProps<AvatarGroupSlots> & {
layout?: 'spread' | 'stack' | 'pie';
Expand Down Expand Up @@ -91,12 +108,21 @@ export const renderAvatar_unstable: (state: AvatarState) => JSX.Element;
// @public
export const renderAvatarGroup_unstable: (state: AvatarGroupState) => JSX.Element;

// @public
export const renderAvatarGroupItem_unstable: (state: AvatarGroupItemState) => JSX.Element;

// @public (undocumented)
export const useAvatar_unstable: (props: AvatarProps, ref: React_2.Ref<HTMLElement>) => AvatarState;

// @public
export const useAvatarGroup_unstable: (props: AvatarGroupProps, ref: React_2.Ref<HTMLElement>) => AvatarGroupState;

// @public
export const useAvatarGroupItem_unstable: (props: AvatarGroupItemProps, ref: React_2.Ref<HTMLElement>) => AvatarGroupItemState;

// @public
export const useAvatarGroupItemStyles_unstable: (state: AvatarGroupItemState) => AvatarGroupItemState;

// @public
export const useAvatarGroupStyles_unstable: (state: AvatarGroupState) => AvatarGroupState;

Expand Down
2 changes: 1 addition & 1 deletion packages/react-components/react-avatar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"start": "yarn storybook",
"test": "jest --passWithNoTests",
"docs": "api-extractor run --config=config/api-extractor.local.json --local",
"build:local": "tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/packages/react-components/react-avatar/src && yarn docs",
"build:local": "tsc -p ./tsconfig.lib.json --module esnext --emitDeclarationOnly && node ../../../scripts/typescript/normalize-import --output ./dist/types/packages/react-components/react-avatar/src && yarn docs",
"storybook": "node ../../../scripts/storybook/runner",
"type-check": "tsc -b tsconfig.json"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/AvatarGroupItem/index';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { AvatarGroupItem } from './AvatarGroupItem';
import { isConformant } from '../../common/isConformant';

describe('AvatarGroupItem', () => {
isConformant({
Component: AvatarGroupItem,
displayName: 'AvatarGroupItem',
disabledTests: ['component-has-static-classname', 'component-has-static-classname-exported'],
});

// TODO add more tests here, and create visual regression tests in /apps/vr-tests

it('renders a default state', () => {
const result = render(<AvatarGroupItem>Default AvatarGroupItem</AvatarGroupItem>);
expect(result.container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import { useAvatarGroupItem_unstable } from './useAvatarGroupItem';
import { renderAvatarGroupItem_unstable } from './renderAvatarGroupItem';
import { useAvatarGroupItemStyles_unstable } from './useAvatarGroupItemStyles';
import type { AvatarGroupItemProps } from './AvatarGroupItem.types';
import type { ForwardRefComponent } from '@fluentui/react-utilities';

/**
* AvatarGroupItem component - TODO: add more docs
*/
export const AvatarGroupItem: ForwardRefComponent<AvatarGroupItemProps> = React.forwardRef((props, ref) => {
const state = useAvatarGroupItem_unstable(props, ref);

useAvatarGroupItemStyles_unstable(state);
return renderAvatarGroupItem_unstable(state);
});

AvatarGroupItem.displayName = 'AvatarGroupItem';
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';

export type AvatarGroupItemSlots = {
root: Slot<'div'>;
};

/**
* AvatarGroupItem Props
*/
export type AvatarGroupItemProps = ComponentProps<AvatarGroupItemSlots> & {};

/**
* State used in rendering AvatarGroupItem
*/
export type AvatarGroupItemState = ComponentState<AvatarGroupItemSlots>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AvatarGroupItem renders a default state 1`] = `
<div>
<div
class="fui-AvatarGroupItem"
>
Default AvatarGroupItem
</div>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './AvatarGroupItem';
export * from './AvatarGroupItem.types';
export * from './renderAvatarGroupItem';
export * from './useAvatarGroupItem';
export * from './useAvatarGroupItemStyles';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import { getSlots } from '@fluentui/react-utilities';
import type { AvatarGroupItemState, AvatarGroupItemSlots } from './AvatarGroupItem.types';

/**
* Render the final JSX of AvatarGroupItem
*/
export const renderAvatarGroupItem_unstable = (state: AvatarGroupItemState) => {
const { slots, slotProps } = getSlots<AvatarGroupItemSlots>(state);

// TODO Add additional slots in the appropriate place
return <slots.root {...slotProps.root} />;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react';
import { getNativeElementProps } from '@fluentui/react-utilities';
import type { AvatarGroupItemProps, AvatarGroupItemState } from './AvatarGroupItem.types';

/**
* Create the state required to render AvatarGroupItem.
*
* The returned state can be modified with hooks such as useAvatarGroupItemStyles_unstable,
* before being passed to renderAvatarGroupItem_unstable.
*
* @param props - props from this instance of AvatarGroupItem
* @param ref - reference to root HTMLElement of AvatarGroupItem
*/
export const useAvatarGroupItem_unstable = (
props: AvatarGroupItemProps,
ref: React.Ref<HTMLElement>,
): AvatarGroupItemState => {
return {
// TODO add appropriate props/defaults
components: {
// TODO add each slot's element type or component
root: 'div',
},
// TODO add appropriate slots, for example:
// mySlot: resolveShorthand(props.mySlot),
root: getNativeElementProps('div', {
ref,
...props,
}),
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { makeStyles, mergeClasses } from '@griffel/react';
import type { AvatarGroupItemSlots, AvatarGroupItemState } from './AvatarGroupItem.types';
import type { SlotClassNames } from '@fluentui/react-utilities';

export const avatarGroupItemClassNames: SlotClassNames<AvatarGroupItemSlots> = {
root: 'fui-AvatarGroupItem',
// TODO: add class names for all slots on AvatarGroupItemSlots.
// Should be of the form `<slotName>: 'fui-AvatarGroupItem__<slotName>`
};

/**
* Styles for the root slot
*/
const useStyles = makeStyles({
root: {
// TODO Add default styles for the root element
},

// TODO add additional classes for different states and/or slots
});

/**
* Apply styling to the AvatarGroupItem slots based on the state
*/
export const useAvatarGroupItemStyles_unstable = (state: AvatarGroupItemState): AvatarGroupItemState => {
const styles = useStyles();
state.root.className = mergeClasses(avatarGroupItemClassNames.root, styles.root, state.root.className);

// TODO Add class names to slots, for example:
// state.mySlot.className = mergeClasses(styles.mySlot, state.mySlot.className);

return state;
};
8 changes: 8 additions & 0 deletions packages/react-components/react-avatar/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ export {
useAvatarGroup_unstable,
} from './AvatarGroup';
export type { AvatarGroupProps, AvatarGroupSlots, AvatarGroupState } from './AvatarGroup';
export {
AvatarGroupItem,
avatarGroupItemClassNames,
renderAvatarGroupItem_unstable,
useAvatarGroupItemStyles_unstable,
useAvatarGroupItem_unstable,
} from './AvatarGroupItem';
export type { AvatarGroupItemProps, AvatarGroupItemSlots, AvatarGroupItemState } from './AvatarGroupItem';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { AvatarGroupItem } from '../index';

import descriptionMd from './AvatarGroupItemDescription.md';
import bestPracticesMd from './AvatarGroupItemBestPractices.md';

export { Default } from './AvatarGroupItemDefault.stories';

export default {
title: 'Components/AvatarGroupItem',
component: AvatarGroupItem,
parameters: {
docs: {
description: {
component: [descriptionMd, bestPracticesMd].join('\n'),
},
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Best practices

### Do

### Don't
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as React from 'react';
import { AvatarGroupItem, AvatarGroupItemProps } from '../index';

export const Default = (props: Partial<AvatarGroupItemProps>) => <AvatarGroupItem {...props} />;