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,250 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
DEFAULT_STRINGS: function() {
return DEFAULT_STRINGS;
},
useAvatarBase_unstable: function() {
return useAvatarBase_unstable;
},
useAvatar_unstable: function() {
return useAvatar_unstable;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _reactutilities = require("@fluentui/react-utilities");
const _index = require("../../utils/index");
const _reacticons = require("@fluentui/react-icons");
const _reactbadge = require("@fluentui/react-badge");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _AvatarContext = require("../../contexts/AvatarContext");
const DEFAULT_STRINGS = {
active: 'active',
inactive: 'inactive'
};
const useAvatar_unstable = (props, ref)=>{
const { dir } = (0, _reactsharedcontexts.useFluent_unstable)();
const { shape: contextShape, size: contextSize } = (0, _AvatarContext.useAvatarContext)();
const { size = contextSize !== null && contextSize !== void 0 ? contextSize : 32, shape = contextShape !== null && contextShape !== void 0 ? contextShape : 'circular', active = 'unset', activeAppearance = 'ring', idForColor, color: propColor = 'neutral', ...rest } = props;
const state = useAvatarBase_unstable(rest, ref);
var _ref;
// Resolve 'colorful' to a specific color name
const color = propColor === 'colorful' ? avatarColors[getHashCode((_ref = idForColor !== null && idForColor !== void 0 ? idForColor : props.name) !== null && _ref !== void 0 ? _ref : '') % avatarColors.length] : propColor;
if (state.initials) {
var _state_initials;
state.initials = _reactutilities.slot.optional(props.initials, {
renderByDefault: true,
defaultProps: {
children: (0, _index.getInitials)(props.name, dir === 'rtl', {
firstInitialOnly: size <= 16
}),
id: (_state_initials = state.initials) === null || _state_initials === void 0 ? void 0 : _state_initials.id
},
elementType: 'span'
});
}
if (state.icon) {
var _state_icon;
var _children;
(_children = (_state_icon = state.icon).children) !== null && _children !== void 0 ? _children : _state_icon.children = /*#__PURE__*/ _react.createElement(_reacticons.PersonRegular, null);
}
const badge = _reactutilities.slot.optional(props.badge, {
defaultProps: {
size: getBadgeSize(size),
id: state.root.id + '__badge'
},
elementType: _reactbadge.PresenceBadge
});
let activeAriaLabelElement = state.activeAriaLabelElement;
// Enhance aria-label and/or aria-labelledby to include badge and active state
// Only process if aria attributes were not explicitly provided by the user
const userProvidedAriaLabel = props['aria-label'] !== undefined;
const userProvidedAriaLabelledby = props['aria-labelledby'] !== undefined;
if (!userProvidedAriaLabel && !userProvidedAriaLabelledby) {
if (props.name) {
if (badge) {
state.root['aria-labelledby'] = state.root.id + ' ' + badge.id;
}
} else if (state.initials) {
// root's aria-label should be the name, but fall back to being labelledby the initials if name is missing
state.root['aria-labelledby'] = state.initials.id + (badge ? ' ' + badge.id : '');
delete state.root['aria-label'];
}
// Add the active state to the aria label
if (active === 'active' || active === 'inactive') {
const activeText = DEFAULT_STRINGS[active];
if (state.root['aria-labelledby']) {
// If using aria-labelledby, render a hidden span and append it to the labelledby
const activeId = state.root.id + '__active';
state.root['aria-labelledby'] += ' ' + activeId;
activeAriaLabelElement = /*#__PURE__*/ _react.createElement("span", {
hidden: true,
id: activeId
}, activeText);
} else if (state.root['aria-label']) {
// Otherwise, just append it to the aria-label
state.root['aria-label'] += ' ' + activeText;
}
}
}
return {
...state,
size,
shape,
active,
activeAppearance,
activeAriaLabelElement,
color,
badge,
// eslint-disable-next-line @typescript-eslint/no-deprecated
components: {
...state.components,
badge: _reactbadge.PresenceBadge
}
};
};
const useAvatarBase_unstable = (props, ref)=>{
const { dir } = (0, _reactsharedcontexts.useFluent_unstable)();
const { name, ...rest } = props;
const baseId = (0, _reactutilities.useId)('avatar-');
const root = _reactutilities.slot.always({
role: 'img',
id: baseId,
ref,
...rest
}, {
elementType: 'span'
});
const [imageHidden, setImageHidden] = _react.useState(undefined);
let image = _reactutilities.slot.optional(props.image, {
defaultProps: {
alt: '',
role: 'presentation',
'aria-hidden': true,
hidden: imageHidden
},
elementType: 'img'
});
// Image shouldn't be rendered if its src is not set
if (!(image === null || image === void 0 ? void 0 : image.src)) {
image = undefined;
}
// Hide the image if it fails to load and restore it on a successful load
if (image) {
image.onError = (0, _reactutilities.mergeCallbacks)(image.onError, ()=>setImageHidden(true));
image.onLoad = (0, _reactutilities.mergeCallbacks)(image.onLoad, ()=>setImageHidden(undefined));
}
// Resolve the initials slot, defaulted to getInitials
let initials = _reactutilities.slot.optional(props.initials, {
renderByDefault: true,
defaultProps: {
children: (0, _index.getInitials)(name, dir === 'rtl'),
id: baseId + '__initials'
},
elementType: 'span'
});
// Don't render the initials slot if it's empty
if (!(initials === null || initials === void 0 ? void 0 : initials.children)) {
initials = undefined;
}
// Render the icon slot *only if* there aren't any initials or image to display
let icon = undefined;
if (!initials && (!image || imageHidden)) {
icon = _reactutilities.slot.optional(props.icon, {
renderByDefault: true,
defaultProps: {
'aria-hidden': true
},
elementType: 'span'
});
}
let activeAriaLabelElement;
// Resolve aria-label and/or aria-labelledby if not provided by the user
if (!root['aria-label'] && !root['aria-labelledby']) {
if (name) {
root['aria-label'] = name;
} else if (initials) {
// root's aria-label should be the name, but fall back to being labelledby the initials if name is missing
root['aria-labelledby'] = initials.id;
}
}
return {
activeAriaLabelElement,
components: {
root: 'span',
initials: 'span',
icon: 'span',
image: 'img'
},
root,
initials,
icon,
image
};
};
const getBadgeSize = (size)=>{
if (size >= 96) {
return 'extra-large';
} else if (size >= 64) {
return 'large';
} else if (size >= 56) {
return 'medium';
} else if (size >= 40) {
return 'small';
} else if (size >= 28) {
return 'extra-small';
} else {
return 'tiny';
}
};
const avatarColors = [
'dark-red',
'cranberry',
'red',
'pumpkin',
'peach',
'marigold',
'gold',
'brass',
'brown',
'forest',
'seafoam',
'dark-green',
'light-teal',
'teal',
'steel',
'blue',
'royal-blue',
'cornflower',
'navy',
'lavender',
'purple',
'grape',
'lilac',
'pink',
'magenta',
'plum',
'beige',
'mink',
'platinum',
'anchor'
];
const getHashCode = (str)=>{
let hashCode = 0;
for(let len = str.length - 1; len >= 0; len--){
const ch = str.charCodeAt(len);
const shift = len % 8;
hashCode ^= (ch << shift) + (ch >> 8 - shift); // eslint-disable-line no-bitwise
}
return hashCode;
};