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,15 @@
'use client';
import * as React from 'react';
import { useToastTitle_unstable } from './useToastTitle';
import { renderToastTitle_unstable } from './renderToastTitle';
import { useToastTitleStyles_unstable } from './useToastTitleStyles.styles';
import { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';
/**
* ToastTitle component
*/ export const ToastTitle = /*#__PURE__*/ React.forwardRef((props, ref)=>{
const state = useToastTitle_unstable(props, ref);
useToastTitleStyles_unstable(state);
useCustomStyleHook_unstable('useToastTitleStyles_unstable')(state);
return renderToastTitle_unstable(state);
});
ToastTitle.displayName = 'ToastTitle';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/ToastTitle/ToastTitle.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useToastTitle_unstable } from './useToastTitle';\nimport { renderToastTitle_unstable } from './renderToastTitle';\nimport { useToastTitleStyles_unstable } from './useToastTitleStyles.styles';\nimport type { ToastTitleProps } from './ToastTitle.types';\nimport type { ForwardRefComponent } from '@fluentui/react-utilities';\nimport { useCustomStyleHook_unstable } from '@fluentui/react-shared-contexts';\n\n/**\n * ToastTitle component\n */\nexport const ToastTitle: ForwardRefComponent<ToastTitleProps> = React.forwardRef((props, ref) => {\n const state = useToastTitle_unstable(props, ref);\n\n useToastTitleStyles_unstable(state);\n useCustomStyleHook_unstable('useToastTitleStyles_unstable')(state);\n\n return renderToastTitle_unstable(state);\n});\n\nToastTitle.displayName = 'ToastTitle';\n"],"names":["React","useToastTitle_unstable","renderToastTitle_unstable","useToastTitleStyles_unstable","useCustomStyleHook_unstable","ToastTitle","forwardRef","props","ref","state","displayName"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,sBAAsB,QAAQ,kBAAkB;AACzD,SAASC,yBAAyB,QAAQ,qBAAqB;AAC/D,SAASC,4BAA4B,QAAQ,+BAA+B;AAG5E,SAASC,2BAA2B,QAAQ,kCAAkC;AAE9E;;CAEC,GACD,OAAO,MAAMC,2BAAmDL,MAAMM,UAAU,CAAC,CAACC,OAAOC;IACvF,MAAMC,QAAQR,uBAAuBM,OAAOC;IAE5CL,6BAA6BM;IAC7BL,4BAA4B,gCAAgCK;IAE5D,OAAOP,0BAA0BO;AACnC,GAAG;AAEHJ,WAAWK,WAAW,GAAG"}

View File

@@ -0,0 +1,3 @@
/**
* State used in rendering ToastTitle
*/ export { };

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/ToastTitle/ToastTitle.types.ts"],"sourcesContent":["import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities';\nimport { BackgroundAppearanceContextValue } from '@fluentui/react-shared-contexts';\nimport { ToastContainerContextValue } from '../../contexts/toastContainerContext';\n\nexport type ToastTitleSlots = {\n root: NonNullable<Slot<'div'>>;\n media?: Slot<'div'>;\n action?: Slot<'div'>;\n};\n\n/**\n * ToastTitle Props\n */\nexport type ToastTitleProps = ComponentProps<ToastTitleSlots> & {};\n\n/**\n * State used in rendering ToastTitle\n */\nexport type ToastTitleState = ComponentState<ToastTitleSlots> &\n Pick<ToastContainerContextValue, 'intent'> & {\n backgroundAppearance: BackgroundAppearanceContextValue;\n };\n"],"names":[],"mappings":"AAeA;;CAEC,GACD,WAGI"}

View File

@@ -0,0 +1,4 @@
export { ToastTitle } from './ToastTitle';
export { renderToastTitle_unstable } from './renderToastTitle';
export { useToastTitle_unstable } from './useToastTitle';
export { toastTitleClassNames, useToastTitleStyles_unstable } from './useToastTitleStyles.styles';

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/ToastTitle/index.ts"],"sourcesContent":["export { ToastTitle } from './ToastTitle';\nexport type { ToastTitleProps, ToastTitleSlots, ToastTitleState } from './ToastTitle.types';\nexport { renderToastTitle_unstable } from './renderToastTitle';\nexport { useToastTitle_unstable } from './useToastTitle';\nexport { toastTitleClassNames, useToastTitleStyles_unstable } from './useToastTitleStyles.styles';\n"],"names":["ToastTitle","renderToastTitle_unstable","useToastTitle_unstable","toastTitleClassNames","useToastTitleStyles_unstable"],"mappings":"AAAA,SAASA,UAAU,QAAQ,eAAe;AAE1C,SAASC,yBAAyB,QAAQ,qBAAqB;AAC/D,SAASC,sBAAsB,QAAQ,kBAAkB;AACzD,SAASC,oBAAoB,EAAEC,4BAA4B,QAAQ,+BAA+B"}

View File

@@ -0,0 +1,14 @@
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@fluentui/react-jsx-runtime/jsx-runtime";
import { assertSlots } from '@fluentui/react-utilities';
/**
* Render the final JSX of ToastTitle
*/ export const renderToastTitle_unstable = (state)=>{
assertSlots(state);
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
state.media ? /*#__PURE__*/ _jsx(state.media, {}) : null,
/*#__PURE__*/ _jsx(state.root, {}),
state.action ? /*#__PURE__*/ _jsx(state.action, {}) : null
]
});
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/ToastTitle/renderToastTitle.tsx"],"sourcesContent":["/** @jsxRuntime automatic */\n/** @jsxImportSource @fluentui/react-jsx-runtime */\n\nimport { assertSlots } from '@fluentui/react-utilities';\nimport type { JSXElement } from '@fluentui/react-utilities';\nimport type { ToastTitleState, ToastTitleSlots } from './ToastTitle.types';\n\n/**\n * Render the final JSX of ToastTitle\n */\nexport const renderToastTitle_unstable = (state: ToastTitleState): JSXElement => {\n assertSlots<ToastTitleSlots>(state);\n\n return (\n <>\n {state.media ? <state.media /> : null}\n <state.root />\n {state.action ? <state.action /> : null}\n </>\n );\n};\n"],"names":["assertSlots","renderToastTitle_unstable","state","media","root","action"],"mappings":"AAAA,0BAA0B,GAC1B,iDAAiD;AAEjD,SAASA,WAAW,QAAQ,4BAA4B;AAIxD;;CAEC,GACD,OAAO,MAAMC,4BAA4B,CAACC;IACxCF,YAA6BE;IAE7B,qBACE;;YACGA,MAAMC,KAAK,iBAAG,KAACD,MAAMC,KAAK,QAAM;0BACjC,KAACD,MAAME,IAAI;YACVF,MAAMG,MAAM,iBAAG,KAACH,MAAMG,MAAM,QAAM;;;AAGzC,EAAE"}

View File

@@ -0,0 +1,63 @@
'use client';
import * as React from 'react';
import { CheckmarkCircleFilled, DiamondDismissFilled, InfoFilled, WarningFilled } from '@fluentui/react-icons';
import { getIntrinsicElementProps, slot } from '@fluentui/react-utilities';
import { useBackgroundAppearance } from '@fluentui/react-shared-contexts';
import { useToastContainerContext } from '../../contexts/toastContainerContext';
/**
* Create the state required to render ToastTitle.
*
* The returned state can be modified with hooks such as useToastTitleStyles_unstable,
* before being passed to renderToastTitle_unstable.
*
* @param props - props from this instance of ToastTitle
* @param ref - reference to root HTMLElement of ToastTitle
*/ export const useToastTitle_unstable = (props, ref)=>{
const { intent, titleId } = useToastContainerContext();
const backgroundAppearance = useBackgroundAppearance();
/** Determine the role and media to render based on the intent */ let defaultIcon;
switch(intent){
case 'success':
defaultIcon = /*#__PURE__*/ React.createElement(CheckmarkCircleFilled, null);
break;
case 'error':
defaultIcon = /*#__PURE__*/ React.createElement(DiamondDismissFilled, null);
break;
case 'warning':
defaultIcon = /*#__PURE__*/ React.createElement(WarningFilled, null);
break;
case 'info':
defaultIcon = /*#__PURE__*/ React.createElement(InfoFilled, null);
break;
}
return {
action: slot.optional(props.action, {
elementType: 'div'
}),
components: {
root: 'div',
media: 'div',
action: 'div'
},
media: slot.optional(props.media, {
renderByDefault: !!intent,
defaultProps: {
children: defaultIcon
},
elementType: 'div'
}),
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,
children: props.children,
id: titleId,
...props
}), {
elementType: 'div'
}),
intent,
backgroundAppearance
};
};

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../src/components/ToastTitle/useToastTitle.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { CheckmarkCircleFilled, DiamondDismissFilled, InfoFilled, WarningFilled } from '@fluentui/react-icons';\nimport { getIntrinsicElementProps, slot } from '@fluentui/react-utilities';\nimport { useBackgroundAppearance } from '@fluentui/react-shared-contexts';\n\nimport type { ToastTitleProps, ToastTitleState } from './ToastTitle.types';\nimport { useToastContainerContext } from '../../contexts/toastContainerContext';\n\n/**\n * Create the state required to render ToastTitle.\n *\n * The returned state can be modified with hooks such as useToastTitleStyles_unstable,\n * before being passed to renderToastTitle_unstable.\n *\n * @param props - props from this instance of ToastTitle\n * @param ref - reference to root HTMLElement of ToastTitle\n */\nexport const useToastTitle_unstable = (props: ToastTitleProps, ref: React.Ref<HTMLElement>): ToastTitleState => {\n const { intent, titleId } = useToastContainerContext();\n const backgroundAppearance = useBackgroundAppearance();\n\n /** Determine the role and media to render based on the intent */\n let defaultIcon;\n switch (intent) {\n case 'success':\n defaultIcon = <CheckmarkCircleFilled />;\n break;\n case 'error':\n defaultIcon = <DiamondDismissFilled />;\n break;\n case 'warning':\n defaultIcon = <WarningFilled />;\n break;\n case 'info':\n defaultIcon = <InfoFilled />;\n break;\n }\n\n return {\n action: slot.optional(props.action, { elementType: 'div' }),\n components: { root: 'div', media: 'div', action: 'div' },\n media: slot.optional(props.media, {\n renderByDefault: !!intent,\n defaultProps: { children: defaultIcon },\n elementType: 'div',\n }),\n root: slot.always(\n getIntrinsicElementProps('div', {\n // FIXME:\n // `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`\n // but since it would be a breaking change to fix it, we are casting ref to it's proper type\n ref: ref as React.Ref<HTMLDivElement>,\n children: props.children,\n id: titleId,\n ...props,\n }),\n { elementType: 'div' },\n ),\n intent,\n backgroundAppearance,\n };\n};\n"],"names":["React","CheckmarkCircleFilled","DiamondDismissFilled","InfoFilled","WarningFilled","getIntrinsicElementProps","slot","useBackgroundAppearance","useToastContainerContext","useToastTitle_unstable","props","ref","intent","titleId","backgroundAppearance","defaultIcon","action","optional","elementType","components","root","media","renderByDefault","defaultProps","children","always","id"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,qBAAqB,EAAEC,oBAAoB,EAAEC,UAAU,EAAEC,aAAa,QAAQ,wBAAwB;AAC/G,SAASC,wBAAwB,EAAEC,IAAI,QAAQ,4BAA4B;AAC3E,SAASC,uBAAuB,QAAQ,kCAAkC;AAG1E,SAASC,wBAAwB,QAAQ,uCAAuC;AAEhF;;;;;;;;CAQC,GACD,OAAO,MAAMC,yBAAyB,CAACC,OAAwBC;IAC7D,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAE,GAAGL;IAC5B,MAAMM,uBAAuBP;IAE7B,+DAA+D,GAC/D,IAAIQ;IACJ,OAAQH;QACN,KAAK;YACHG,4BAAc,oBAACd;YACf;QACF,KAAK;YACHc,4BAAc,oBAACb;YACf;QACF,KAAK;YACHa,4BAAc,oBAACX;YACf;QACF,KAAK;YACHW,4BAAc,oBAACZ;YACf;IACJ;IAEA,OAAO;QACLa,QAAQV,KAAKW,QAAQ,CAACP,MAAMM,MAAM,EAAE;YAAEE,aAAa;QAAM;QACzDC,YAAY;YAAEC,MAAM;YAAOC,OAAO;YAAOL,QAAQ;QAAM;QACvDK,OAAOf,KAAKW,QAAQ,CAACP,MAAMW,KAAK,EAAE;YAChCC,iBAAiB,CAAC,CAACV;YACnBW,cAAc;gBAAEC,UAAUT;YAAY;YACtCG,aAAa;QACf;QACAE,MAAMd,KAAKmB,MAAM,CACfpB,yBAAyB,OAAO;YAC9B,SAAS;YACT,4EAA4E;YAC5E,4FAA4F;YAC5FM,KAAKA;YACLa,UAAUd,MAAMc,QAAQ;YACxBE,IAAIb;YACJ,GAAGH,KAAK;QACV,IACA;YAAEQ,aAAa;QAAM;QAEvBN;QACAE;IACF;AACF,EAAE"}

View File

@@ -0,0 +1,81 @@
'use client';
import { __styles, __resetStyles, mergeClasses } from '@griffel/react';
import { tokens } from '@fluentui/react-theme';
export const toastTitleClassNames = {
root: 'fui-ToastTitle',
media: 'fui-ToastTitle__media',
action: 'fui-ToastTitle__action'
};
const useRootBaseClassName = /*#__PURE__*/__resetStyles("rdjap1e", null, [".rdjap1e{display:flex;grid-column-end:3;color:var(--colorNeutralForeground1);word-break:break-word;}"]);
const useMediaBaseClassName = /*#__PURE__*/__resetStyles("r8x5mrd", "r1soj19y", [".r8x5mrd{display:flex;padding-top:2px;grid-column-end:2;padding-right:8px;font-size:16px;color:var(--colorNeutralForeground1);}", ".r1soj19y{display:flex;padding-top:2px;grid-column-end:2;padding-left:8px;font-size:16px;color:var(--colorNeutralForeground1);}"]);
const useActionBaseClassName = /*#__PURE__*/__resetStyles("r2j19ip", "rjfozdo", [".r2j19ip{display:flex;align-items:start;padding-left:12px;grid-column-end:-1;color:var(--colorBrandForeground1);}", ".rjfozdo{display:flex;align-items:start;padding-right:12px;grid-column-end:-1;color:var(--colorBrandForeground1);}"]);
const useInvertedStyles = /*#__PURE__*/__styles({
root: {
sj55zd: "f1w7i9ko"
},
action: {
sj55zd: "f1qz2gb0"
},
media: {
sj55zd: "fqpbvvt"
}
}, {
d: [".f1w7i9ko{color:var(--colorNeutralForegroundInverted2);}", ".f1qz2gb0{color:var(--colorBrandForegroundInverted);}", ".fqpbvvt{color:var(--colorNeutralForegroundInverted);}"]
});
const useIntentIconStyles = /*#__PURE__*/__styles({
success: {
sj55zd: "f36rra6"
},
error: {
sj55zd: "f1ca9wz"
},
warning: {
sj55zd: "f13isgzr"
},
info: {
sj55zd: "fkfq4zb"
}
}, {
d: [".f36rra6{color:var(--colorStatusSuccessForeground1);}", ".f1ca9wz{color:var(--colorStatusDangerForeground1);}", ".f13isgzr{color:var(--colorStatusWarningForeground1);}", ".fkfq4zb{color:var(--colorNeutralForeground2);}"]
});
const useIntentIconStylesInverted = /*#__PURE__*/__styles({
success: {
sj55zd: "ff3wk4x"
},
error: {
sj55zd: "fbq2gqr"
},
warning: {
sj55zd: "fx6hq1t"
},
info: {
sj55zd: "f1w7i9ko"
}
}, {
d: [".ff3wk4x{color:var(--colorStatusSuccessForegroundInverted);}", ".fbq2gqr{color:var(--colorStatusDangerForegroundInverted);}", ".fx6hq1t{color:var(--colorStatusWarningForegroundInverted);}", ".f1w7i9ko{color:var(--colorNeutralForegroundInverted2);}"]
});
/**
* Apply styling to the ToastTitle slots based on the state
*/
export const useToastTitleStyles_unstable = state => {
'use no memo';
const rootBaseClassName = useRootBaseClassName();
const actionBaseClassName = useActionBaseClassName();
const mediaBaseClassName = useMediaBaseClassName();
const intentIconStyles = useIntentIconStyles();
const intentIconStylesInverted = useIntentIconStylesInverted();
const {
intent
} = state;
const invertedStyles = useInvertedStyles();
state.root.className = mergeClasses(toastTitleClassNames.root, rootBaseClassName, state.backgroundAppearance === 'inverted' && invertedStyles.root, state.root.className);
if (state.media) {
state.media.className = mergeClasses(toastTitleClassNames.media, mediaBaseClassName, state.backgroundAppearance === 'inverted' && invertedStyles.media, intent && intentIconStyles[intent], intent && state.backgroundAppearance === 'inverted' && intentIconStylesInverted[intent], state.media.className);
}
if (state.action) {
state.action.className = mergeClasses(toastTitleClassNames.action, actionBaseClassName, state.backgroundAppearance === 'inverted' && invertedStyles.action, state.action.className);
}
return state;
};

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,88 @@
'use client';
import { makeStyles, makeResetStyles, mergeClasses } from '@griffel/react';
import { tokens } from '@fluentui/react-theme';
export const toastTitleClassNames = {
root: 'fui-ToastTitle',
media: 'fui-ToastTitle__media',
action: 'fui-ToastTitle__action'
};
const useRootBaseClassName = makeResetStyles({
display: 'flex',
gridColumnEnd: 3,
color: tokens.colorNeutralForeground1,
wordBreak: 'break-word'
});
const useMediaBaseClassName = makeResetStyles({
display: 'flex',
paddingTop: '2px',
gridColumnEnd: 2,
paddingRight: '8px',
fontSize: '16px',
color: tokens.colorNeutralForeground1
});
const useActionBaseClassName = makeResetStyles({
display: 'flex',
alignItems: 'start',
paddingLeft: '12px',
gridColumnEnd: -1,
color: tokens.colorBrandForeground1
});
const useInvertedStyles = makeStyles({
root: {
color: tokens.colorNeutralForegroundInverted2
},
action: {
color: tokens.colorBrandForegroundInverted
},
media: {
color: tokens.colorNeutralForegroundInverted
}
});
const useIntentIconStyles = makeStyles({
success: {
color: tokens.colorStatusSuccessForeground1
},
error: {
color: tokens.colorStatusDangerForeground1
},
warning: {
color: tokens.colorStatusWarningForeground1
},
info: {
color: tokens.colorNeutralForeground2
}
});
const useIntentIconStylesInverted = makeStyles({
success: {
color: tokens.colorStatusSuccessForegroundInverted
},
error: {
color: tokens.colorStatusDangerForegroundInverted
},
warning: {
color: tokens.colorStatusWarningForegroundInverted
},
info: {
color: tokens.colorNeutralForegroundInverted2
}
});
/**
* Apply styling to the ToastTitle slots based on the state
*/ export const useToastTitleStyles_unstable = (state)=>{
'use no memo';
const rootBaseClassName = useRootBaseClassName();
const actionBaseClassName = useActionBaseClassName();
const mediaBaseClassName = useMediaBaseClassName();
const intentIconStyles = useIntentIconStyles();
const intentIconStylesInverted = useIntentIconStylesInverted();
const { intent } = state;
const invertedStyles = useInvertedStyles();
state.root.className = mergeClasses(toastTitleClassNames.root, rootBaseClassName, state.backgroundAppearance === 'inverted' && invertedStyles.root, state.root.className);
if (state.media) {
state.media.className = mergeClasses(toastTitleClassNames.media, mediaBaseClassName, state.backgroundAppearance === 'inverted' && invertedStyles.media, intent && intentIconStyles[intent], intent && state.backgroundAppearance === 'inverted' && intentIconStylesInverted[intent], state.media.className);
}
if (state.action) {
state.action.className = mergeClasses(toastTitleClassNames.action, actionBaseClassName, state.backgroundAppearance === 'inverted' && invertedStyles.action, state.action.className);
}
return state;
};

File diff suppressed because one or more lines are too long