Private
Public Access
1
0

feat: Fluent UI Outlook Lite + connections mockup

This commit is contained in:
2026-04-14 18:52:25 +00:00
parent 1199eff6c3
commit dfa4010406
34820 changed files with 1003813 additions and 205 deletions

View File

@@ -0,0 +1,135 @@
'use client';
import * as React from 'react';
import { useEventCallback, useControllableState, getIntrinsicElementProps, slot } from '@fluentui/react-utilities';
import { useArrowNavigationGroup } from '@fluentui/react-tabster';
/**
* Create the state required to render Toolbar.
*
* The returned state can be modified with hooks such as useToolbarStyles_unstable,
* before being passed to renderToolbar_unstable.
*
* @param props - props from this instance of Toolbar
* @param ref - reference to root HTMLElement of Toolbar
*/ export const useToolbar_unstable = (props, ref)=>{
const { size = 'medium' } = props;
const state = useToolbarBase_unstable(props, ref);
const arrowNavigationProps = useToolbarArrowNavigationProps_unstable();
return {
size,
...state,
root: {
...state.root,
...arrowNavigationProps
}
};
};
/**
* Base hook that builds Toolbar state for behavior and structure only.
* It does not add arrow key navigation, which is handled by `useToolbar_unstable`.
*
* @internal
* @param props - Props for this Toolbar instance.
* @param ref - Ref to the root HTMLElement.
*/ export const useToolbarBase_unstable = (props, ref)=>{
const { vertical = false } = props;
const initialState = {
vertical,
// 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: slot.always(getIntrinsicElementProps('div', {
role: 'toolbar',
ref: ref,
...vertical && {
'aria-orientation': 'vertical'
},
...props
}), {
elementType: 'div'
})
};
const [checkedValues, onCheckedValueChange] = useToolbarSelectableState({
checkedValues: props.checkedValues,
defaultCheckedValues: props.defaultCheckedValues,
onCheckedValueChange: props.onCheckedValueChange
});
const handleToggleButton = useEventCallback((e, name, value, checked)=>{
if (name && value) {
const checkedItems = (checkedValues === null || checkedValues === void 0 ? void 0 : checkedValues[name]) || [];
const newCheckedItems = [
...checkedItems
];
if (checked) {
newCheckedItems.splice(newCheckedItems.indexOf(value), 1);
} else {
newCheckedItems.push(value);
}
onCheckedValueChange === null || onCheckedValueChange === void 0 ? void 0 : onCheckedValueChange(e, {
name,
checkedItems: newCheckedItems
});
}
});
const handleRadio = useEventCallback((e, name, value, checked)=>{
if (name && value) {
onCheckedValueChange === null || onCheckedValueChange === void 0 ? void 0 : onCheckedValueChange(e, {
name,
checkedItems: [
value
]
});
}
});
return {
...initialState,
handleToggleButton,
handleRadio,
checkedValues: checkedValues !== null && checkedValues !== void 0 ? checkedValues : {}
};
};
/**
* Adds appropriate state values and handlers for selectable items
* i.e checkboxes and radios
*/ const useToolbarSelectableState = (state)=>{
const [checkedValues, setCheckedValues] = useControllableState({
state: state.checkedValues,
defaultState: state.defaultCheckedValues,
initialState: {}
});
const { onCheckedValueChange: onCheckedValueChangeOriginal } = state;
const onCheckedValueChange = useEventCallback((e, { name, checkedItems })=>{
if (onCheckedValueChangeOriginal) {
onCheckedValueChangeOriginal(e, {
name,
checkedItems
});
}
setCheckedValues((s)=>{
return s ? {
...s,
[name]: checkedItems
} : {
[name]: checkedItems
};
});
});
return [
checkedValues,
onCheckedValueChange
];
};
/**
* Hook to add arrow navigation props to the Toolbar.
*
* @internal
* @returns - Tabster DOM attributes for arrow navigation
*/ export const useToolbarArrowNavigationProps_unstable = ()=>{
return useArrowNavigationGroup({
circular: true,
axis: 'both'
});
};