+
+
+
16px
+
+ Compact UIs, toolbars, dense tables. Example shows a Word document filetype icon.
+
+
+
+
+
20px
+
+ Compact lists, navigation items. Example shows a folder, referenced via FileIconType.
+
+
+
+
+
24px
+
Standard list items, search results. Example shows a Word document.
+
+
+
+
32px
+
+ Standard cards, file browsers. Example shows a PowerPoint presentation with a legacy file extension.
+
+
+
+
+
40px
+
Featured items, file pickers. Example shows a video file.
+
+
+
+
48px
+
+ Grid views, attachment previews. Example shows a Microsoft Lists object.
+
+
+
+
+
64px
+
Large grid items, file upload zones. Text file.
+
+
+
+
96px
+
Hero sections, large previews. Example shows a shared folder.
+
+
+ );
+};
+
+Default.parameters = {
+ docs: {
+ description: {
+ story:
+ 'FileTypeIcon supports 8 size variants (16, 20, 24, 32, 40, 48, 64, and 96 pixels) to accommodate different UI contexts. Choose smaller sizes for compact interfaces and larger sizes for featured content or file upload experiences.',
+ },
+ },
+};
diff --git a/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconDescription.md b/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconDescription.md
new file mode 100644
index 00000000000000..1674419d5c509c
--- /dev/null
+++ b/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconDescription.md
@@ -0,0 +1,23 @@
+# FileTypeIcon
+
+Filetype icons represent a file or other "digital object" based on its extension or a special type (like folder). This Fluent UI design system component provides consistent, recognizable visual representations of the user's items and documents across your application, aligned with Microsoft 365.
+
+The component automatically selects the appropriate icon from the comprehensive Fluent Design file type icon set and handles device pixel ratio for optimal display quality on all screens.
+
+## Use Filetype Icons when you need to:
+
+- **Display file lists or grids** - Help users quickly identify file types in recent lists, document libraries, file browsers, or search results
+- **Show file attachments or file upload interfaces** - Indicate attachment types in emails, messages, or forms. Provide visual feedback about accepted or uploaded file types
+- **Represent documents in workflows** - Show file types in approval processes, cloud content management interfaces, document workflows, or collaboration tools
+
+This control integrates seamlessly with other Fluent UI v9 components using the same design principles. It can be used in `DataGrid`, `List`, and `Card` components for displaying file collections, following consistent theming, spacing and sizing patterns with the broader Fluent Design System.
+
+## Features
+
+- **Automatic icon selection**: Matches file extensions to the appropriate icon from a comprehensive library
+- **Multiple sizes**: Supports 16, 20, 24, 32, 40, 48, 64, and 96 pixel sizes for different UI contexts
+- **Format support**: Renders icons as SVG (default, recommended) or PNG for maximum compatibility
+- **Special types**: Supports non-file-based icons like folders, shared folders, list items, docsets, and generic files
+- **Accessibility**: Includes appropriate alt text for screen readers and follows WCAG guidelines
+- **Device-aware rendering**: Automatically handles different pixel densities for crisp display on all screens
+- **Customizable base URL**: Configure a custom CDN or asset path for icon resources
diff --git a/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconEdgeCases.stories.tsx b/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconEdgeCases.stories.tsx
new file mode 100644
index 00000000000000..e5e2e61ffb3a36
--- /dev/null
+++ b/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconEdgeCases.stories.tsx
@@ -0,0 +1,249 @@
+/* eslint-disable @fluentui/no-restricted-imports */
+import * as React from 'react';
+import { makeStyles, tokens } from '@fluentui/react-components';
+import type { JSXElement } from '@fluentui/react-components';
+import { FileTypeIcon } from '@fluentui/react-file-type-icons';
+
+const useStyles = makeStyles({
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '32px',
+ },
+ section: {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '12px',
+ },
+ sectionTitle: {
+ fontSize: tokens.fontSizeBase400,
+ fontWeight: tokens.fontWeightSemibold,
+ marginBottom: '8px',
+ },
+ description: {
+ fontSize: tokens.fontSizeBase300,
+ color: tokens.colorNeutralForeground3,
+ marginBottom: '8px',
+ },
+ exampleGrid: {
+ display: 'grid',
+ gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
+ gap: '16px',
+ },
+ exampleItem: {
+ display: 'flex',
+ alignItems: 'center',
+ gap: '12px',
+ padding: '12px',
+ backgroundColor: tokens.colorNeutralBackground1,
+ borderRadius: tokens.borderRadiusMedium,
+ },
+ label: {
+ fontSize: tokens.fontSizeBase300,
+ fontFamily: tokens.fontFamilyMonospace,
+ },
+ fallbackNote: {
+ fontSize: tokens.fontSizeBase200,
+ color: tokens.colorNeutralForeground3,
+ fontStyle: 'italic',
+ },
+ warningBox: {
+ padding: '12px 16px',
+ backgroundColor: tokens.colorPaletteYellowBackground2,
+ borderLeft: `4px solid ${tokens.colorPaletteYellowBorder1}`,
+ borderRadius: tokens.borderRadiusMedium,
+ fontSize: tokens.fontSizeBase300,
+ },
+ codeBlock: {
+ backgroundColor: tokens.colorNeutralBackground3,
+ padding: '12px',
+ borderRadius: tokens.borderRadiusMedium,
+ fontFamily: tokens.fontFamilyMonospace,
+ fontSize: tokens.fontSizeBase200,
+ overflowX: 'auto',
+ },
+ truncatedText: {
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap',
+ flex: 1,
+ },
+});
+
+export const EdgeCases = (): JSXElement => {
+ const styles = useStyles();
+
+ return (
+
+
+
Unknown Extensions
+
+ When FileTypeIcon encounters an unknown or unsupported file extension, it automatically falls back to the
+ generic file icon, ensuring consistent visual representation.
+
+
+
+
+
+
.xyz123
+
→ genericFile
+
+
+
+
+
+
.unknown
+
→ genericFile
+
+
+
+
+
+
.custom
+
→ genericFile
+
+
+
+
+
+
.proprietary
+
→ genericFile
+
+
+
+
+
+
+
Empty or Null Extensions
+
+ When no extension is provided or the extension is empty, the component gracefully handles the case by showing
+ the generic file icon.
+
+
+
+
+
+
extension=""
+
→ genericFile
+
+
+
+
+
+
no extension prop
+
→ genericFile
+
+
+
+
+
+
+
Special Characters in Extensions
+
+ Extensions with special characters, numbers, or unusual formatting are handled gracefully, though they
+ typically fall back to the generic icon if not recognized.
+
+
+
+
+
+
.file.bak
+
Handles dots
+
+
+
+
+
+
.tar.gz
+
Double extension
+
+
+
+
+
+
+
+
+
Very Long File Names
+
+ The icon component focuses on the extension, not the filename length. Regardless of filename length, the
+ correct icon is displayed. However, UI layouts should handle text truncation appropriately.
+
+
+
+
+
+ This_is_a_very_long_filename_that_could_cause_layout_issues_in_some_contexts_Q4_2025_Final_Report_v3.pdf
+
+
+
+
+ Note: While FileTypeIcon handles any extension length, consider truncating long filenames in
+ your UI layout to maintain readability and prevent overflow issues.
+
+
+
+
+
Case Sensitivity and Periods
+
+ File extensions are handled in a case-insensitive manner. The component recognizes extensions regardless of
+ capitalization. Periods before the extension will be ignored.
+
+
+
+ All variations display the same PDF icon. If you want to further sanitize your code, consider extracting and
+ normalizing file extensions from full filenames:
+
+
+
+ {`// Extract extension from filename
+const getExtension = (filename: string): string => {
+ const parts = filename.split('.');
+ return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : '';
+};
+
+// Usage
+const filename = "Report.Final.PDF";
+const extension = getExtension(filename); // "pdf"
+
+`}
+
+
+
+
+ );
+};
+
+EdgeCases.parameters = {
+ docs: {
+ description: {
+ story:
+ 'FileTypeIcon gracefully handles edge cases including unknown extensions, empty values, special characters, and case variations. The component falls back to a generic file icon for unrecognized extensions, ensuring your UI always displays something meaningful.',
+ },
+ },
+};
diff --git a/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconUrlAndHtml.stories.tsx b/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconUrlAndHtml.stories.tsx
new file mode 100644
index 00000000000000..9af847edfcc730
--- /dev/null
+++ b/packages/react-components/react-file-type-icons/stories/src/FileTypeIcon/FileTypeIconUrlAndHtml.stories.tsx
@@ -0,0 +1,225 @@
+/* eslint-disable @fluentui/no-restricted-imports */
+import * as React from 'react';
+import { makeStyles, tokens } from '@fluentui/react-components';
+import type { JSXElement } from '@fluentui/react-components';
+import { getFileTypeIconAsUrl, getFileTypeIconAsHTMLString } from '@fluentui/react-file-type-icons';
+
+const useStyles = makeStyles({
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '24px',
+ },
+ section: {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '12px',
+ padding: '16px',
+ border: `1px solid ${tokens.colorNeutralStroke1}`,
+ borderRadius: tokens.borderRadiusMedium,
+ },
+ sectionTitle: {
+ fontSize: tokens.fontSizeBase400,
+ fontWeight: tokens.fontWeightSemibold,
+ marginBottom: '8px',
+ },
+ grid: {
+ display: 'grid',
+ gridTemplateColumns: 'repeat(3, 1fr)',
+ gap: '16px',
+ },
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '8px',
+ padding: '12px',
+ backgroundColor: tokens.colorNeutralBackground2,
+ borderRadius: tokens.borderRadiusSmall,
+ },
+ cardTitle: {
+ fontSize: tokens.fontSizeBase300,
+ fontWeight: tokens.fontWeightSemibold,
+ marginBottom: '4px',
+ },
+ iconPreview: {
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ padding: '12px',
+ backgroundColor: tokens.colorNeutralBackground1,
+ borderRadius: tokens.borderRadiusSmall,
+ minHeight: '60px',
+ },
+ code: {
+ fontSize: tokens.fontSizeBase100,
+ fontFamily: tokens.fontFamilyMonospace,
+ backgroundColor: tokens.colorNeutralBackground1,
+ padding: '8px',
+ borderRadius: tokens.borderRadiusSmall,
+ overflowX: 'auto',
+ wordBreak: 'break-all',
+ },
+ label: {
+ fontSize: tokens.fontSizeBase200,
+ color: tokens.colorNeutralForeground3,
+ fontWeight: tokens.fontWeightMedium,
+ },
+});
+
+const commonFileTypes = ['docx', 'pdf', 'xlsx'];
+
+export const UrlAndHtml = (): JSXElement => {
+ const styles = useStyles();
+ const [devicePixelRatio, setDevicePixelRatio] = React.useState