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": "minor",
"comment": "feat: add base hooks for Badge",
"packageName": "@fluentui/react-badge",
"email": "dmytrokirpa@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import type { SlotClassNames } from '@fluentui/react-utilities';
// @public
export const Badge: ForwardRefComponent<BadgeProps>;

// @public (undocumented)
export type BadgeBaseProps = Omit<BadgeProps, 'appearance' | 'color' | 'shape' | 'size'>;

// @public (undocumented)
export type BadgeBaseState = Omit<BadgeState, 'appearance' | 'color' | 'shape' | 'size'>;

// @public (undocumented)
export const badgeClassNames: SlotClassNames<BadgeSlots>;

Expand All @@ -39,6 +45,12 @@ export type BadgeState = ComponentState<BadgeSlots> & Required<Pick<BadgeProps,
// @public
export const CounterBadge: ForwardRefComponent<CounterBadgeProps>;

// @public (undocumented)
export type CounterBadgeBaseProps = Omit<CounterBadgeProps, 'appearance' | 'color' | 'shape' | 'size'>;

// @public (undocumented)
export type CounterBadgeBaseState = Omit<CounterBadgeState, 'appearance' | 'color' | 'shape' | 'size'>;

// @public (undocumented)
export const counterBadgeClassNames: SlotClassNames<BadgeSlots>;

Expand Down Expand Up @@ -71,6 +83,12 @@ export const presenceAwayRegular: Record<PresenceBadgeState['size'], React_2.Fun
// @public
export const PresenceBadge: ForwardRefComponent<PresenceBadgeProps>;

// @public (undocumented)
export type PresenceBadgeBaseProps = Omit<PresenceBadgeProps, 'size'>;

// @public (undocumented)
export type PresenceBadgeBaseState = Omit<PresenceBadgeState, 'appearance' | 'color' | 'shape' | 'size'>;

// @public (undocumented)
export const presenceBadgeClassNames: SlotClassNames<BadgeSlots>;

Expand Down Expand Up @@ -108,23 +126,32 @@ export const presenceOofRegular: Record<PresenceBadgeState['size'], React_2.Func
export const presenceUnknownRegular: Record<PresenceBadgeState['size'], React_2.FunctionComponent>;

// @public (undocumented)
export const renderBadge_unstable: (state: BadgeState) => JSXElement;
export const renderBadge_unstable: (state: BadgeBaseState) => JSXElement;

// @public
export const useBadge_unstable: (props: BadgeProps, ref: React_2.Ref<HTMLElement>) => BadgeState;

// @public
export const useBadgeBase_unstable: (props: BadgeBaseProps, ref: React_2.Ref<HTMLDivElement>) => BadgeBaseState;

// @public
export const useBadgeStyles_unstable: (state: BadgeState) => BadgeState;

// @public
export const useCounterBadge_unstable: (props: CounterBadgeProps, ref: React_2.Ref<HTMLElement>) => CounterBadgeState;

// @public
export const useCounterBadgeBase_unstable: (props: CounterBadgeBaseProps, ref: React_2.Ref<HTMLElement>) => CounterBadgeBaseState;

// @public
export const useCounterBadgeStyles_unstable: (state: CounterBadgeState) => CounterBadgeState;

// @public
export const usePresenceBadge_unstable: (props: PresenceBadgeProps, ref: React_2.Ref<HTMLElement>) => PresenceBadgeState;

// @public
export const usePresenceBadgeBase_unstable: (props: PresenceBadgeBaseProps, ref: React_2.Ref<HTMLElement>) => PresenceBadgeBaseState;

// @public
export const usePresenceBadgeStyles_unstable: (state: PresenceBadgeState) => PresenceBadgeState;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
export type { BadgeProps, BadgeSlots, BadgeState } from './components/Badge/index';
export type { BadgeBaseProps, BadgeProps, BadgeSlots, BadgeBaseState, BadgeState } from './components/Badge/index';
export {
Badge,
badgeClassNames,
renderBadge_unstable,
useBadgeStyles_unstable,
useBadge_unstable,
useBadgeBase_unstable,
} from './components/Badge/index';
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
export type { CounterBadgeProps, CounterBadgeState } from './components/CounterBadge/index';
export type {
CounterBadgeProps,
CounterBadgeState,
CounterBadgeBaseProps,
CounterBadgeBaseState,
} from './components/CounterBadge/index';
export {
CounterBadge,
counterBadgeClassNames,
useCounterBadgeStyles_unstable,
useCounterBadge_unstable,
useCounterBadgeBase_unstable,
} from './components/CounterBadge/index';
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export type { PresenceBadgeProps, PresenceBadgeState, PresenceBadgeStatus } from './components/PresenceBadge/index';
export type {
PresenceBadgeProps,
PresenceBadgeState,
PresenceBadgeStatus,
PresenceBadgeBaseProps,
PresenceBadgeBaseState,
} from './components/PresenceBadge/index';
export {
PresenceBadge,
presenceAvailableFilled,
Expand All @@ -15,4 +21,5 @@ export {
presenceUnknownRegular,
usePresenceBadgeStyles_unstable,
usePresenceBadge_unstable,
usePresenceBadgeBase_unstable,
} from './components/PresenceBadge/index';
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ export type BadgeProps = Omit<ComponentProps<BadgeSlots>, 'color'> & {

export type BadgeState = ComponentState<BadgeSlots> &
Required<Pick<BadgeProps, 'appearance' | 'color' | 'iconPosition' | 'shape' | 'size'>>;

export type BadgeBaseProps = Omit<BadgeProps, 'appearance' | 'color' | 'shape' | 'size'>;

export type BadgeBaseState = Omit<BadgeState, 'appearance' | 'color' | 'shape' | 'size'>;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { Badge } from './Badge';
// Explicit exports to omit BadgeCommons
export type { BadgeProps, BadgeSlots, BadgeState } from './Badge.types';
export type { BadgeBaseProps, BadgeBaseState, BadgeProps, BadgeSlots, BadgeState } from './Badge.types';
export { renderBadge_unstable } from './renderBadge';
export { useBadge_unstable } from './useBadge';
export { useBadge_unstable, useBadgeBase_unstable } from './useBadge';
export { badgeClassNames, useBadgeStyles_unstable } from './useBadgeStyles.styles';
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import { assertSlots } from '@fluentui/react-utilities';
import type { JSXElement } from '@fluentui/react-utilities';

import type { BadgeState, BadgeSlots } from './Badge.types';
import type { BadgeBaseState, BadgeSlots } from './Badge.types';

export const renderBadge_unstable = (state: BadgeState): JSXElement => {
export const renderBadge_unstable = (state: BadgeBaseState): JSXElement => {
assertSlots<BadgeSlots>(state);

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,48 @@
'use client';

import * as React from 'react';
import { getIntrinsicElementProps, slot } from '@fluentui/react-utilities';
import type { BadgeProps, BadgeState } from './Badge.types';
import type { BadgeBaseProps, BadgeBaseState, BadgeProps, BadgeState } from './Badge.types';

/**
* Returns the props and state required to render the component
*/
export const useBadge_unstable = (props: BadgeProps, ref: React.Ref<HTMLElement>): BadgeState => {
const {
shape = 'circular',
size = 'medium',
iconPosition = 'before',
appearance = 'filled',
color = 'brand',
} = props;
const { shape = 'circular', size = 'medium', appearance = 'filled', color = 'brand', ...badgeProps } = props;

const state = useBadgeBase_unstable(badgeProps, ref as React.Ref<HTMLDivElement>);

const state: BadgeState = {
return {
...state,
shape,
size,
iconPosition,
appearance,
color,
};
};

/**
* Base hook for Badge component, which manages state related to slots structure and ARIA attributes.
*
* @param props - User provided props to the Badge component.
* @param ref - User provided ref to be passed to the Badge component.
*/
export const useBadgeBase_unstable = (props: BadgeBaseProps, ref: React.Ref<HTMLDivElement>): BadgeBaseState => {
const { iconPosition = 'before' } = props;

return {
iconPosition,
components: {
root: 'div',
icon: 'span',
},
root: slot.always(
getIntrinsicElementProps('div', {
// FIXME:
// `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`
// but since it would be a breaking change to fix it, we are casting ref to it's proper type
ref: ref as React.Ref<HTMLDivElement>,
ref,
...props,
}),
{ elementType: 'div' },
),
icon: slot.optional(props.icon, { elementType: 'span' }),
};

return state;
};
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ export type CounterBadgeProps = Omit<BadgeProps, 'appearance' | 'color' | 'shape

export type CounterBadgeState = Omit<BadgeState, 'appearance' | 'color' | 'shape'> &
Required<Pick<CounterBadgeProps, 'appearance' | 'color' | 'count' | 'dot' | 'shape' | 'showZero'>>;

export type CounterBadgeBaseProps = Omit<CounterBadgeProps, 'appearance' | 'color' | 'shape' | 'size'>;

export type CounterBadgeBaseState = Omit<CounterBadgeState, 'appearance' | 'color' | 'shape' | 'size'>;
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export { CounterBadge } from './CounterBadge';
export type { CounterBadgeProps, CounterBadgeState } from './CounterBadge.types';
export { useCounterBadge_unstable } from './useCounterBadge';
export type {
CounterBadgeBaseProps,
CounterBadgeBaseState,
CounterBadgeProps,
CounterBadgeState,
} from './CounterBadge.types';
export { useCounterBadge_unstable, useCounterBadgeBase_unstable } from './useCounterBadge';
export { counterBadgeClassNames, useCounterBadgeStyles_unstable } from './useCounterBadgeStyles.styles';
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
'use client';

import * as React from 'react';
import type { BadgeState } from '../Badge/index';
import { useBadge_unstable } from '../Badge/index';
import type { CounterBadgeProps, CounterBadgeState } from './CounterBadge.types';
import { useBadgeBase_unstable } from '../Badge/index';
import type {
CounterBadgeBaseProps,
CounterBadgeBaseState,
CounterBadgeProps,
CounterBadgeState,
} from './CounterBadge.types';

/**
* Returns the props and state required to render the component
*/
export const useCounterBadge_unstable = (props: CounterBadgeProps, ref: React.Ref<HTMLElement>): CounterBadgeState => {
const {
shape = 'circular',
appearance = 'filled',
showZero = false,
overflowCount = 99,
count = 0,
dot = false,
} = props;

const state: CounterBadgeState = {
...(useBadge_unstable(props, ref) as Pick<CounterBadgeState, keyof BadgeState>),
const { shape = 'circular', appearance = 'filled', color = 'brand', size = 'medium', ...counterBadgeProps } = props;

const state = useCounterBadgeBase_unstable(counterBadgeProps, ref);

return {
...state,
shape,
appearance,
color,
size,
};
};

/**
* Base hook for CounterBadge component, which manages state related to slots structure and counter logic.
*
* @param props - User provided props to the CounterBadge component.
* @param ref - User provided ref to be passed to the CounterBadge component.
*/
export const useCounterBadgeBase_unstable = (
props: CounterBadgeBaseProps,
ref: React.Ref<HTMLElement>,
): CounterBadgeBaseState => {
const { showZero = false, overflowCount = 99, count = 0, dot = false, ...badgeProps } = props;

const state: CounterBadgeBaseState = {
...useBadgeBase_unstable(badgeProps, ref as React.Ref<HTMLDivElement>),
showZero,
count,
dot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ export type PresenceBadgeProps = Omit<ComponentProps<Pick<BadgeSlots, 'root' | '
export type PresenceBadgeState = ComponentState<BadgeSlots> &
BadgeState &
Required<Pick<PresenceBadgeProps, 'status' | 'outOfOffice'>>;

export type PresenceBadgeBaseProps = Omit<PresenceBadgeProps, 'size'>;

export type PresenceBadgeBaseState = Omit<PresenceBadgeState, 'appearance' | 'color' | 'shape' | 'size'>;
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
export { PresenceBadge } from './PresenceBadge';
export type { PresenceBadgeProps, PresenceBadgeState, PresenceBadgeStatus } from './PresenceBadge.types';
export { usePresenceBadge_unstable } from './usePresenceBadge';
export type {
PresenceBadgeBaseProps,
PresenceBadgeBaseState,
PresenceBadgeProps,
PresenceBadgeState,
PresenceBadgeStatus,
} from './PresenceBadge.types';
export { usePresenceBadge_unstable, usePresenceBadgeBase_unstable } from './usePresenceBadge';
export { presenceBadgeClassNames, usePresenceBadgeStyles_unstable } from './usePresenceBadgeStyles.styles';
export {
presenceAvailableFilled,
Expand Down
Loading
Loading