From 3e4b23d687f7551aff1a6a9f9b50cea0b7088be0 Mon Sep 17 00:00:00 2001 From: Mick Ryan Date: Tue, 23 Jun 2026 18:47:23 -0400 Subject: [PATCH] feat(preview): use @box/item-icon markdown icon for loading screen Markdown files (md, markdown, mdown) on the preview loading screen previously rendered the legacy IconFileCode content icon. Switch them to the dedicated markdown icon from @box/item-icon. Bump @box/item-icon ^2.37.5 -> ^3.2.0 (resolves 3.2.2); the markdown file category/icon was added in 3.2.0, 2.x only had code. Register itemIconTable.markdown for those extensions in previewIcons.ts and update PreviewLoading tests (markdown for md/markdown/mdown, code still for html). PREVIEW-739 Co-Authored-By: Claude Opus 4.8 (1M context) --- package.json | 4 ++-- .../preview/__tests__/PreviewLoading.test.tsx | 16 ++++++++++++++++ src/components/preview/previewIcons.ts | 8 +++++--- yarn.lock | 8 ++++---- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 3ce9e3c2ee..5092ed145e 100644 --- a/package.json +++ b/package.json @@ -136,7 +136,7 @@ "@box/content-field": "^1.40.23", "@box/copy-input": "^1.42.16", "@box/frontend": "^11.0.1", - "@box/item-icon": "^2.37.5", + "@box/item-icon": "^3.2.0", "@box/languages": "^1.0.0", "@box/metadata-editor": "^1.73.4", "@box/metadata-filter": "^1.80.23", @@ -305,7 +305,7 @@ "@box/combobox-with-api": "^1.42.22", "@box/content-field": "^1.40.23", "@box/copy-input": "^1.42.16", - "@box/item-icon": "^2.37.5", + "@box/item-icon": "^3.2.0", "@box/metadata-editor": "^1.73.4", "@box/metadata-filter": "^1.80.23", "@box/metadata-template-browser": "^1.24.11", diff --git a/src/components/preview/__tests__/PreviewLoading.test.tsx b/src/components/preview/__tests__/PreviewLoading.test.tsx index ff05119130..d651ef9b1b 100644 --- a/src/components/preview/__tests__/PreviewLoading.test.tsx +++ b/src/components/preview/__tests__/PreviewLoading.test.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; +import { itemIconTable } from '@box/item-icon'; import { shallow } from 'enzyme'; import { PreviewLoading, PreviewLoadingRing, getIcon } from '..'; +import IconFileCode from '../../../icon/content/FileCode32'; import { bdlBoxBlue } from '../../../styles/variables'; const getWrapper = (props = {}) => shallow(); @@ -15,6 +17,20 @@ describe('components/preview/PreviewLoading', () => { expect(wrapper.find(PreviewLoadingRing).prop('color')).toEqual('#D0021B'); }); + test.each(['md', 'markdown', 'mdown'])('should use the Markdown icon for %s files', extension => { + const wrapper = getWrapper({ extension }); + + expect(getIcon(extension)).toEqual(itemIconTable.markdown); + expect(wrapper.children().type()).toEqual(itemIconTable.markdown); + }); + + test('should keep using the code icon for HTML files', () => { + const wrapper = getWrapper({ extension: 'html' }); + + expect(getIcon('html')).toEqual(IconFileCode); + expect(wrapper.children().type()).toEqual(IconFileCode); + }); + test('should get a default color and icon if no extension is provided', () => { const DefaultIcon = getIcon(); const wrapper = getWrapper(); diff --git a/src/components/preview/previewIcons.ts b/src/components/preview/previewIcons.ts index 170b3266b2..ab2b08b7a5 100644 --- a/src/components/preview/previewIcons.ts +++ b/src/components/preview/previewIcons.ts @@ -3,6 +3,9 @@ * file-specific loading icons for file types that can be previewed. Unsupported files show a default * icon, even if they have a relevant thumbnail/icon that is displayed within the item list, for example. */ +import { itemIconTable } from '@box/item-icon'; +import type { ComponentType } from 'react'; + import * as vars from '../../styles/variables'; import IconFileAudio from '../../icon/content/FileAudio32'; import IconFileBoxCanvas from '../../icon/content/FileCanvas32'; @@ -33,11 +36,10 @@ import IconFileWord from '../../icon/content/FileWord32'; import IconFileXbd from '../../icon/content/FileXbd32'; import IconFileXdw from '../../icon/content/FileXdw32'; import IconFileZip from '../../icon/content/FileZip32'; -import { SVGProps } from '../accessible-svg/AccessibleSVG'; type Config = { color: string; icon: Icon }; type Configs = { [key: string]: Config }; // { docx: { color: '#333', icon: IconFileWord } -type Icon = (props: SVGProps) => JSX.Element; +type Icon = ComponentType<{ className?: string }>; const configs: Configs = {}; const register = (icon: Icon, color: string, extensions: string[]): void => { @@ -88,7 +90,6 @@ register(IconFileCode, '#E33D55', [ 'less', 'm', 'make', - 'md', 'ml', 'mm', 'php', @@ -142,6 +143,7 @@ register(IconFileImage, '#3FB87F', [ ]); register(IconFileIndesign, '#FF57A1', ['idml', 'indd', 'indt', 'inx']); register(IconFileKeynote, '#007AFF', ['key']); +register(itemIconTable.markdown, vars.bdlBoxBlue, ['md', 'markdown', 'mdown']); register(IconFileNumbers, '#00A650', ['numbers']); register(IconFilePDF, '#D0021B', ['pdf']); register(IconFilePages, '#FF9500', ['pages']); diff --git a/yarn.lock b/yarn.lock index bb591037f8..84fa7f6fda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1169,10 +1169,10 @@ rimraf "^3.0.0" semver "^7.4.0" -"@box/item-icon@^2.37.5": - version "2.37.5" - resolved "https://registry.yarnpkg.com/@box/item-icon/-/item-icon-2.37.5.tgz#887b58a66dee13f494d38709d7d6c0f7bdcc995f" - integrity sha512-GNcFK2Ehq0RFHxq8lbZD4J9UZZyxf/Y9l4PdoLQsfQWi/phWw27+v5dQBdfTBNHZGmfs4hNe+M2mUxqnOlG+Ng== +"@box/item-icon@^3.2.0": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@box/item-icon/-/item-icon-3.2.2.tgz#7afa9ddbbd0d519e780c532ad7ec75b037cfc88f" + integrity sha512-By6AT/TbrVIgK9dC0YiTh3xmq8NPwQwg1/Wup1VDBKOOYGGlxvxJFyHI6rDDtFEU/cGIiaTKlp+3bbrWeHv3Hg== "@box/languages@^1.0.0": version "1.1.2"