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,8 @@
import type { FluentIcon } from './shared';
/**
* Base bundleIcon — combines Filled and Regular icon variants.
*
* Renders both icons; the inactive variant gets `data-fui-icon-hidden`.
* The shipped base.css handles visibility via `[data-fui-icon-hidden] { display: none }`.
*/
export declare const bundleIcon: (FilledIcon: FluentIcon, RegularIcon: FluentIcon) => FluentIcon;

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bundleIcon = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const shared_1 = require("./shared");
/**
* Base bundleIcon — combines Filled and Regular icon variants.
*
* Renders both icons; the inactive variant gets `data-fui-icon-hidden`.
* The shipped base.css handles visibility via `[data-fui-icon-hidden] { display: none }`.
*/
const bundleIcon = (FilledIcon, RegularIcon) => {
const Component = (props) => {
const { className, filled, ...rest } = props;
return (React.createElement(React.Fragment, null,
React.createElement(FilledIcon, Object.assign({}, rest, { className: shared_1.cx(shared_1.iconFilledClassName, className) }, (!filled ? { [shared_1.DATA_FUI_ICON_HIDDEN]: '' } : undefined))),
React.createElement(RegularIcon, Object.assign({}, rest, { className: shared_1.cx(shared_1.iconRegularClassName, className) }, (filled ? { [shared_1.DATA_FUI_ICON_HIDDEN]: '' } : undefined)))));
};
Component.displayName = 'CompoundIcon';
return Component;
};
exports.bundleIcon = bundleIcon;

View File

@@ -0,0 +1,20 @@
import * as React from 'react';
import type { FluentIconsProps } from './shared';
export declare type FluentIcon = React.FC<FluentIconsProps>;
export declare type CreateFluentIconOptions = {
flipInRtl?: boolean;
color?: boolean;
};
/**
* Base createFluentIcon — SVG icon factory without Styles.
*
* Returns a React component that renders an SVG icon with:
* - data-fui-icon attribute for CSS targeting
* - a11y attributes (aria-hidden, aria-label, role)
* - RTL flip via data-fui-icon-rtl attribute
* - HCM forced-color-adjust via CSS attribute selector
*
* @access private
* @alpha
*/
export declare const createFluentIcon: (displayName: string, width: string, pathsOrSvg: string[] | string, options?: CreateFluentIconOptions | undefined) => FluentIcon;

View File

@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFluentIcon = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const shared_1 = require("./shared");
const useIconState_1 = require("./useIconState");
/**
* Base createFluentIcon — SVG icon factory without Styles.
*
* Returns a React component that renders an SVG icon with:
* - data-fui-icon attribute for CSS targeting
* - a11y attributes (aria-hidden, aria-label, role)
* - RTL flip via data-fui-icon-rtl attribute
* - HCM forced-color-adjust via CSS attribute selector
*
* @access private
* @alpha
*/
const createFluentIcon = (displayName, width, pathsOrSvg, options) => {
const viewBoxWidth = width === '1em' ? '20' : width;
const Icon = React.forwardRef((props, ref) => {
const iconState = useIconState_1.useIconState(props, { flipInRtl: options === null || options === void 0 ? void 0 : options.flipInRtl });
const state = {
...iconState,
className: shared_1.cx(shared_1.iconClassName, iconState.className),
ref,
width,
height: width,
viewBox: `0 0 ${viewBoxWidth} ${viewBoxWidth}`,
xmlns: 'http://www.w3.org/2000/svg',
};
if (typeof pathsOrSvg === 'string') {
return React.createElement('svg', { ...state, dangerouslySetInnerHTML: { __html: pathsOrSvg } });
}
else {
return React.createElement('svg', state, ...pathsOrSvg.map((d) => React.createElement('path', { d, fill: state.fill })));
}
});
Icon.displayName = displayName;
return Icon;
};
exports.createFluentIcon = createFluentIcon;

View File

@@ -0,0 +1,9 @@
import type { FluentIcon, CreateFluentIconOptions } from './createFluentIcon';
export type { FluentIcon, CreateFluentIconOptions } from './createFluentIcon';
/**
* Base createFluentIcon for sprite-based icons.
*
* @access private
* @alpha
*/
export declare const createFluentIcon: (iconId: string, size: string, spritePath?: string | undefined, options?: CreateFluentIconOptions | undefined) => FluentIcon;

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFluentIcon = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const shared_1 = require("./shared");
const useIconState_1 = require("./useIconState");
/**
* Base createFluentIcon for sprite-based icons.
*
* @access private
* @alpha
*/
const createFluentIcon = (iconId, size, spritePath, options) => {
const viewBoxWidth = size === '1em' ? '20' : size;
const Icon = React.forwardRef((props, ref) => {
const iconState = useIconState_1.useIconState(props, { flipInRtl: options === null || options === void 0 ? void 0 : options.flipInRtl });
const state = {
...iconState,
className: shared_1.cx(shared_1.iconClassName, iconState.className),
ref,
width: size,
height: size,
viewBox: `0 0 ${viewBoxWidth} ${viewBoxWidth}`,
xmlns: 'http://www.w3.org/2000/svg',
};
const href = spritePath ? `${spritePath}#${iconId}` : `#${iconId}`;
return React.createElement('svg', state, React.createElement('use', { href }));
});
Icon.displayName = iconId;
return Icon;
};
exports.createFluentIcon = createFluentIcon;

View File

@@ -0,0 +1,20 @@
import * as React from 'react';
import type { FluentIconsProps } from '../shared';
import { FontFile } from '../../utils/fonts/createFluentFontIcon.shared';
export declare type CreateFluentFontIconOptions = {
flipInRtl?: boolean;
};
export declare type FluentFontIcon = React.FC<FluentIconsProps<React.HTMLAttributes<HTMLElement>, HTMLElement>> & {
codepoint: string;
};
/**
* Headless createFluentFontIcon — font icon factory without Griffel.
*
* Sets data attributes for CSS targeting:
* - data-fui-icon="font" for base font icon styles
* - data-fui-icon-font="filled|regular|..." for font-family selection
*
* @access private
* @alpha
*/
export declare function createFluentFontIcon(displayName: string, codepoint: string, font: FontFile, fontSize?: number, options?: CreateFluentFontIconOptions): FluentFontIcon;

View File

@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFluentFontIcon = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const shared_1 = require("../shared");
const useIconState_1 = require("../useIconState");
const FONT_VARIANT_MAP = {
[0 /* Filled */]: 'filled',
[1 /* Regular */]: 'regular',
[2 /* Resizable */]: 'resizable',
[3 /* Light */]: 'light',
};
/**
* Headless createFluentFontIcon — font icon factory without Griffel.
*
* Sets data attributes for CSS targeting:
* - data-fui-icon="font" for base font icon styles
* - data-fui-icon-font="filled|regular|..." for font-family selection
*
* @access private
* @alpha
*/
function createFluentFontIcon(displayName, codepoint, font, fontSize, options) {
const Component = (props) => {
const className = shared_1.cx(shared_1.fontIconClassName, props.className);
const state = useIconState_1.useIconState({ ...props, className }, { flipInRtl: options === null || options === void 0 ? void 0 : options.flipInRtl });
// Override the default data-fui-icon to "font" for font-specific styles
state[shared_1.DATA_FUI_ICON] = 'font';
state[shared_1.DATA_FUI_ICON_FONT] = FONT_VARIANT_MAP[font];
// Map primaryFill to color for font icons
if (props.primaryFill && props.primaryFill.toLowerCase() !== 'currentcolor') {
state.style = {
...state.style,
color: props.primaryFill,
};
}
if (fontSize) {
state.style = {
...state.style,
fontSize,
};
}
return React.createElement("i", Object.assign({}, state), codepoint);
};
Component.displayName = displayName;
Component.codepoint = codepoint;
return Component;
}
exports.createFluentFontIcon = createFluentFontIcon;

View File

@@ -0,0 +1,2 @@
export { createFluentFontIcon } from './createFluentFontIcon';
export type { FluentFontIcon, CreateFluentFontIconOptions } from './createFluentFontIcon';

View File

@@ -0,0 +1,6 @@
"use strict";
// Base Fluent Font Icons API
Object.defineProperty(exports, "__esModule", { value: true });
exports.createFluentFontIcon = void 0;
var createFluentFontIcon_1 = require("./createFluentFontIcon");
Object.defineProperty(exports, "createFluentFontIcon", { enumerable: true, get: function () { return createFluentFontIcon_1.createFluentFontIcon; } });

View File

@@ -0,0 +1,8 @@
export type { FluentIconsProps, FluentIcon, CreateFluentIconOptions } from './shared';
export { iconClassName, iconFilledClassName, iconRegularClassName, iconLightClassName, iconColorClassName, fontIconClassName, DATA_FUI_ICON, DATA_FUI_ICON_RTL, DATA_FUI_ICON_HIDDEN, DATA_FUI_ICON_FONT, cx, } from './shared';
export { IconDirectionContextProvider, useIconContext } from '../contexts/index';
export type { IconDirectionContextValue } from '../contexts/index';
export { useIconState } from './useIconState';
export type { UseIconStateOptions } from './useIconState';
export { createFluentIcon } from './createFluentIcon';
export { bundleIcon } from './bundleIcon';

View File

@@ -0,0 +1,31 @@
"use strict";
// Base Fluent Icons API
// Import the shipped CSS file (base.css) for default styling via data-attribute selectors.
Object.defineProperty(exports, "__esModule", { value: true });
exports.bundleIcon = exports.createFluentIcon = exports.useIconState = exports.useIconContext = exports.IconDirectionContextProvider = exports.cx = exports.DATA_FUI_ICON_FONT = exports.DATA_FUI_ICON_HIDDEN = exports.DATA_FUI_ICON_RTL = exports.DATA_FUI_ICON = exports.fontIconClassName = exports.iconColorClassName = exports.iconLightClassName = exports.iconRegularClassName = exports.iconFilledClassName = exports.iconClassName = void 0;
var shared_1 = require("./shared");
Object.defineProperty(exports, "iconClassName", { enumerable: true, get: function () { return shared_1.iconClassName; } });
Object.defineProperty(exports, "iconFilledClassName", { enumerable: true, get: function () { return shared_1.iconFilledClassName; } });
Object.defineProperty(exports, "iconRegularClassName", { enumerable: true, get: function () { return shared_1.iconRegularClassName; } });
Object.defineProperty(exports, "iconLightClassName", { enumerable: true, get: function () { return shared_1.iconLightClassName; } });
Object.defineProperty(exports, "iconColorClassName", { enumerable: true, get: function () { return shared_1.iconColorClassName; } });
Object.defineProperty(exports, "fontIconClassName", { enumerable: true, get: function () { return shared_1.fontIconClassName; } });
Object.defineProperty(exports, "DATA_FUI_ICON", { enumerable: true, get: function () { return shared_1.DATA_FUI_ICON; } });
Object.defineProperty(exports, "DATA_FUI_ICON_RTL", { enumerable: true, get: function () { return shared_1.DATA_FUI_ICON_RTL; } });
Object.defineProperty(exports, "DATA_FUI_ICON_HIDDEN", { enumerable: true, get: function () { return shared_1.DATA_FUI_ICON_HIDDEN; } });
Object.defineProperty(exports, "DATA_FUI_ICON_FONT", { enumerable: true, get: function () { return shared_1.DATA_FUI_ICON_FONT; } });
Object.defineProperty(exports, "cx", { enumerable: true, get: function () { return shared_1.cx; } });
// Context
var index_1 = require("../contexts/index");
Object.defineProperty(exports, "IconDirectionContextProvider", { enumerable: true, get: function () { return index_1.IconDirectionContextProvider; } });
Object.defineProperty(exports, "useIconContext", { enumerable: true, get: function () { return index_1.useIconContext; } });
// Core hook
var useIconState_1 = require("./useIconState");
Object.defineProperty(exports, "useIconState", { enumerable: true, get: function () { return useIconState_1.useIconState; } });
// SVG icon factories
var createFluentIcon_1 = require("./createFluentIcon");
Object.defineProperty(exports, "createFluentIcon", { enumerable: true, get: function () { return createFluentIcon_1.createFluentIcon; } });
var bundleIcon_1 = require("./bundleIcon");
Object.defineProperty(exports, "bundleIcon", { enumerable: true, get: function () { return bundleIcon_1.bundleIcon; } });
// TODO: to maintain API compat for build transform we will probably need to export this as well
// export { wrapIcon } from './wrapIcon';

View File

@@ -0,0 +1,15 @@
/** Base data attribute applied to all icons (SVG and font). */
export declare const DATA_FUI_ICON = "data-fui-icon";
/** Data attribute applied to icons that should flip in RTL text direction. */
export declare const DATA_FUI_ICON_RTL = "data-fui-icon-rtl";
/** Data attribute applied to the inactive variant in a bundled icon pair. */
export declare const DATA_FUI_ICON_HIDDEN = "data-fui-icon-hidden";
/** Data attribute for font icon font-family variant selection (filled|regular|resizable|light). */
export declare const DATA_FUI_ICON_FONT = "data-fui-icon-font";
export { iconClassName, iconFilledClassName, iconRegularClassName, iconLightClassName, iconColorClassName, fontIconClassName, } from '../utils/constants';
export type { FluentIconsProps } from '../utils/FluentIconsProps.types';
export type { FluentIcon, CreateFluentIconOptions } from './createFluentIcon';
/**
* Joins class name strings, filtering out falsy values.
*/
export declare function cx(...classes: (string | false | undefined | null)[]): string | undefined;

View File

@@ -0,0 +1,29 @@
"use strict";
// Data attribute names used by base icons for CSS targeting.
// The shipped base.css file uses these attribute selectors for styling.
Object.defineProperty(exports, "__esModule", { value: true });
exports.cx = exports.fontIconClassName = exports.iconColorClassName = exports.iconLightClassName = exports.iconRegularClassName = exports.iconFilledClassName = exports.iconClassName = exports.DATA_FUI_ICON_FONT = exports.DATA_FUI_ICON_HIDDEN = exports.DATA_FUI_ICON_RTL = exports.DATA_FUI_ICON = void 0;
/** Base data attribute applied to all icons (SVG and font). */
exports.DATA_FUI_ICON = 'data-fui-icon';
/** Data attribute applied to icons that should flip in RTL text direction. */
exports.DATA_FUI_ICON_RTL = 'data-fui-icon-rtl';
/** Data attribute applied to the inactive variant in a bundled icon pair. */
exports.DATA_FUI_ICON_HIDDEN = 'data-fui-icon-hidden';
/** Data attribute for font icon font-family variant selection (filled|regular|resizable|light). */
exports.DATA_FUI_ICON_FONT = 'data-fui-icon-font';
// Re-export existing constants (CSS class names for consumer targeting)
var constants_1 = require("../utils/constants");
Object.defineProperty(exports, "iconClassName", { enumerable: true, get: function () { return constants_1.iconClassName; } });
Object.defineProperty(exports, "iconFilledClassName", { enumerable: true, get: function () { return constants_1.iconFilledClassName; } });
Object.defineProperty(exports, "iconRegularClassName", { enumerable: true, get: function () { return constants_1.iconRegularClassName; } });
Object.defineProperty(exports, "iconLightClassName", { enumerable: true, get: function () { return constants_1.iconLightClassName; } });
Object.defineProperty(exports, "iconColorClassName", { enumerable: true, get: function () { return constants_1.iconColorClassName; } });
Object.defineProperty(exports, "fontIconClassName", { enumerable: true, get: function () { return constants_1.fontIconClassName; } });
/**
* Joins class name strings, filtering out falsy values.
*/
function cx(...classes) {
const result = classes.filter(Boolean).join(' ');
return result || undefined;
}
exports.cx = cx;

View File

@@ -0,0 +1,15 @@
import * as React from 'react';
import type { FluentIconsProps } from './shared';
export declare type UseIconStateOptions = {
flipInRtl?: boolean;
};
/**
* Base version of useIconState
*
* Handles:
* - a11y: aria-hidden, aria-label, role="img"
* - RTL: sets data-fui-icon-rtl attribute when flipInRtl + RTL context
* - Base: sets data-fui-icon attribute for CSS targeting
* - Fill: maps primaryFill to fill prop
*/
export declare const useIconState: <TBaseAttributes extends React.HTMLAttributes<HTMLElement> | React.SVGAttributes<SVGElement> = React.SVGAttributes<SVGElement>, TRefType extends HTMLElement | SVGSVGElement = SVGSVGElement>(props: FluentIconsProps<TBaseAttributes, TRefType>, options?: UseIconStateOptions | undefined) => Pick<FluentIconsProps<TBaseAttributes, TRefType>, "title" | "filled" | "ref" | "key" | "className" | Exclude<keyof TBaseAttributes, "primaryFill">>;

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useIconState = void 0;
const contexts_1 = require("../contexts");
const shared_1 = require("./shared");
/**
* Base version of useIconState
*
* Handles:
* - a11y: aria-hidden, aria-label, role="img"
* - RTL: sets data-fui-icon-rtl attribute when flipInRtl + RTL context
* - Base: sets data-fui-icon attribute for CSS targeting
* - Fill: maps primaryFill to fill prop
*/
const useIconState = (props, options) => {
const {
// remove unwanted props to be set on the svg/html element
// eslint-disable-next-line @typescript-eslint/no-unused-vars
filled, title, primaryFill = 'currentColor', ...rest } = props;
const state = {
...rest,
fill: primaryFill,
};
const iconContext = contexts_1.useIconContext();
const isRtlFlip = (options === null || options === void 0 ? void 0 : options.flipInRtl) && (iconContext === null || iconContext === void 0 ? void 0 : iconContext.textDirection) === 'rtl';
// Data attributes for CSS targeting
state[shared_1.DATA_FUI_ICON] = '';
if (isRtlFlip) {
state[shared_1.DATA_FUI_ICON_RTL] = '';
}
if (title) {
state['aria-label'] = title;
}
if (!state['aria-label'] && !state['aria-labelledby']) {
state['aria-hidden'] = true;
}
else {
state['role'] = 'img';
}
return state;
};
exports.useIconState = useIconState;