From ea18bcbce013ca9602df682b87160629b9e9e61a Mon Sep 17 00:00:00 2001
From: Andis Redmans <90789422+815are@users.noreply.github.com>
Date: Fri, 18 Oct 2024 16:36:35 +0300
Subject: [PATCH] feat(ui-components): new API method `initTheme` to override
default Fluent UI styles, removing `-webkit-font-smoothing: antialiased`.
(#2478)
* feat: init theme to avoid font smoothing
init theme to avoid font smoothing
* test: additional test
additional test
* fix: execute from storybook
execute from storybook
* comment
comment
* test: coverage
coverage
---
.changeset/gorgeous-melons-develop.md | 5 +++++
packages/ui-components/.storybook/preview.js | 5 +++++
packages/ui-components/src/index.tsx | 1 +
packages/ui-components/src/theme/index.ts | 15 +++++++++++++++
.../ui-components/stories/UICallout.story.tsx | 4 +---
.../UICalloutCollisionTransform.story.tsx | 3 ---
.../ui-components/stories/UICheckbox.story.tsx | 4 ----
.../stories/UIChoiceGroup.story.tsx | 4 ----
.../ui-components/stories/UICombobox.story.tsx | 3 ---
.../stories/UIContextualMenu.story.tsx | 4 +---
.../stories/UICreateSelect.story.tsx | 3 ---
.../stories/UIDatePicker.story.tsx | 4 ----
.../ui-components/stories/UIDialog.story.tsx | 4 ----
.../ui-components/stories/UIDropdown.story.tsx | 3 ---
.../stories/UIFlexibleTable.story.tsx | 4 ----
.../ui-components/stories/UIIcon.story.tsx | 3 ---
.../ui-components/stories/UILabel.story.tsx | 3 ---
.../ui-components/stories/UILoader.story.tsx | 2 --
.../stories/UIQuickNavigation.story.tsx | 18 ++++++++++--------
.../stories/UISearchBox.story.tsx | 3 ---
.../stories/UITextInput.story.tsx | 3 ---
.../stories/UIToggleGroup.story.tsx | 3 ---
.../ui-components/stories/UITooltip.story.tsx | 3 ---
.../stories/UITranslationInput.story.tsx | 4 +---
.../ui-components/stories/Utilities.story.tsx | 15 +++++++--------
.../test/unit/theme/Theme.test.ts | 14 ++++++++++++++
26 files changed, 60 insertions(+), 77 deletions(-)
create mode 100644 .changeset/gorgeous-melons-develop.md
create mode 100644 packages/ui-components/.storybook/preview.js
create mode 100644 packages/ui-components/src/theme/index.ts
create mode 100644 packages/ui-components/test/unit/theme/Theme.test.ts
diff --git a/.changeset/gorgeous-melons-develop.md b/.changeset/gorgeous-melons-develop.md
new file mode 100644
index 0000000000..3967ae95c2
--- /dev/null
+++ b/.changeset/gorgeous-melons-develop.md
@@ -0,0 +1,5 @@
+---
+'@sap-ux/ui-components': minor
+---
+
+Added new API method `initTheme` to override default Fluent UI styles, removing `-webkit-font-smoothing: antialiased`.
diff --git a/packages/ui-components/.storybook/preview.js b/packages/ui-components/.storybook/preview.js
new file mode 100644
index 0000000000..a8f2d55d73
--- /dev/null
+++ b/packages/ui-components/.storybook/preview.js
@@ -0,0 +1,5 @@
+import { initTheme } from '../src/theme';
+import { initIcons } from '../src/components/Icons';
+
+initTheme();
+initIcons();
diff --git a/packages/ui-components/src/index.tsx b/packages/ui-components/src/index.tsx
index d81f0ae31c..a7ed41ead3 100644
--- a/packages/ui-components/src/index.tsx
+++ b/packages/ui-components/src/index.tsx
@@ -1,2 +1,3 @@
export * from './components';
export * from './utilities';
+export * from './theme';
diff --git a/packages/ui-components/src/theme/index.ts b/packages/ui-components/src/theme/index.ts
new file mode 100644
index 0000000000..d3cc46dfd2
--- /dev/null
+++ b/packages/ui-components/src/theme/index.ts
@@ -0,0 +1,15 @@
+import type { Theme } from '@fluentui/react';
+import { createTheme, loadTheme } from '@fluentui/react';
+
+/**
+ * Method intializes default styles for 'ui-components' theme.
+ */
+export function initTheme(): void {
+ const appTheme: Theme = createTheme({
+ defaultFontStyle: {
+ WebkitFontSmoothing: ''
+ }
+ });
+
+ loadTheme(appTheme);
+}
diff --git a/packages/ui-components/stories/UICallout.story.tsx b/packages/ui-components/stories/UICallout.story.tsx
index 5ad8eb9449..829c5783b4 100644
--- a/packages/ui-components/stories/UICallout.story.tsx
+++ b/packages/ui-components/stories/UICallout.story.tsx
@@ -2,9 +2,7 @@ import React, { useState } from 'react';
import { UIDefaultButton, UIIconButton } from '../src/components/UIButton';
import { UICallout, UICalloutContentPadding } from '../src/components/UICallout';
import { UIFocusZone } from '../src/components/UIFocusZone';
-import { initIcons, UiIcons } from '../src/components/Icons';
-
-initIcons();
+import { UiIcons } from '../src/components/Icons';
export default { title: 'Dropdowns/Callout' };
diff --git a/packages/ui-components/stories/UICalloutCollisionTransform.story.tsx b/packages/ui-components/stories/UICalloutCollisionTransform.story.tsx
index b63eed819a..f7f3f764d7 100644
--- a/packages/ui-components/stories/UICalloutCollisionTransform.story.tsx
+++ b/packages/ui-components/stories/UICalloutCollisionTransform.story.tsx
@@ -10,13 +10,10 @@ import {
UITextInput,
UICallout,
UICheckbox,
- initIcons,
CalloutCollisionTransform
} from '../src/components';
import { data } from '../test/__mock__/select-data';
-initIcons();
-
export default { title: 'Dialogs/Dialogs' };
enum ControlTypes {
diff --git a/packages/ui-components/stories/UICheckbox.story.tsx b/packages/ui-components/stories/UICheckbox.story.tsx
index 2fc7bff66f..01a771acf6 100644
--- a/packages/ui-components/stories/UICheckbox.story.tsx
+++ b/packages/ui-components/stories/UICheckbox.story.tsx
@@ -4,10 +4,6 @@ import { Text, Stack } from '@fluentui/react';
import { UICheckbox } from '../src/components/UICheckbox';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
-
export default { title: 'Basic Inputs/Checkbox' };
const stackTokens: IStackTokens = { childrenGap: 40 };
diff --git a/packages/ui-components/stories/UIChoiceGroup.story.tsx b/packages/ui-components/stories/UIChoiceGroup.story.tsx
index 620c992fc3..e02e04f84f 100644
--- a/packages/ui-components/stories/UIChoiceGroup.story.tsx
+++ b/packages/ui-components/stories/UIChoiceGroup.story.tsx
@@ -4,10 +4,6 @@ import { Text, Stack } from '@fluentui/react';
import type { ChoiceGroupOption } from '../src/components/UIChoiceGroup';
import { UIChoiceGroup } from '../src/components/UIChoiceGroup';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
-
export default { title: 'Basic Inputs/ChoiceGroup' };
const props: any = {
diff --git a/packages/ui-components/stories/UICombobox.story.tsx b/packages/ui-components/stories/UICombobox.story.tsx
index 1b84e26718..a8ec6e157e 100644
--- a/packages/ui-components/stories/UICombobox.story.tsx
+++ b/packages/ui-components/stories/UICombobox.story.tsx
@@ -12,11 +12,8 @@ import {
import { UICheckbox } from '../src/components/UICheckbox';
import { data, groupsData } from '../test/__mock__/select-data';
-import { initIcons } from '../src/components/Icons';
import { UITextInput } from '../src/components';
-initIcons();
-
export default { title: 'Dropdowns/Combobox' };
export const SearchHighlight = (): JSX.Element => (
diff --git a/packages/ui-components/stories/UIContextualMenu.story.tsx b/packages/ui-components/stories/UIContextualMenu.story.tsx
index bac38f00a6..7f981fbea2 100644
--- a/packages/ui-components/stories/UIContextualMenu.story.tsx
+++ b/packages/ui-components/stories/UIContextualMenu.story.tsx
@@ -10,12 +10,10 @@ import {
} from '../src/components/UIContextualMenu';
import { UIDefaultButton, UIIconButton } from '../src/components/UIButton';
import { UIDirectionalHint } from '../src/components/UITreeDropdown';
-import { initIcons, UiIcons } from '../src/components/Icons';
+import { UiIcons } from '../src/components/Icons';
import { UIDropdown } from '../src/components/UIDropdown';
import { UIToggle } from '../src/components/UIToggle';
-initIcons();
-
export default { title: 'Dropdowns/ContextualMenu' };
const stackTokens: IStackTokens = { childrenGap: 40 };
function getItems(iconsToLeft = false): UIContextualMenuItem[] {
diff --git a/packages/ui-components/stories/UICreateSelect.story.tsx b/packages/ui-components/stories/UICreateSelect.story.tsx
index 32cdb2f258..43a508b397 100644
--- a/packages/ui-components/stories/UICreateSelect.story.tsx
+++ b/packages/ui-components/stories/UICreateSelect.story.tsx
@@ -10,9 +10,6 @@ import {
UICreateSelectInstance
} from '../src/components/UICreateSelect';
import { UILabel } from '../src/components/UILabel';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
export default { title: 'Dropdowns/CreateSelect' };
const stackTokens: IStackTokens = { childrenGap: 40 };
diff --git a/packages/ui-components/stories/UIDatePicker.story.tsx b/packages/ui-components/stories/UIDatePicker.story.tsx
index fb54354943..955566f5ab 100644
--- a/packages/ui-components/stories/UIDatePicker.story.tsx
+++ b/packages/ui-components/stories/UIDatePicker.story.tsx
@@ -4,10 +4,6 @@ import { Text, Stack } from '@fluentui/react';
import { UIDatePicker } from '../src/components/UIDatePicker';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
-
export default { title: 'Basic Inputs/DatePicker' };
const stackTokens: IStackTokens = { childrenGap: 40 };
diff --git a/packages/ui-components/stories/UIDialog.story.tsx b/packages/ui-components/stories/UIDialog.story.tsx
index ec9b540a3c..2c5f23ef14 100644
--- a/packages/ui-components/stories/UIDialog.story.tsx
+++ b/packages/ui-components/stories/UIDialog.story.tsx
@@ -10,10 +10,6 @@ import { UIDropdown } from '../src/components/UIDropdown';
import { UIComboBox } from '../src/components/UIComboBox';
import { UICheckbox } from '../src/components/UICheckbox';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
-
export default { title: 'Dialogs/Dialogs' };
const stackTokens: IStackTokens = { childrenGap: 40 };
diff --git a/packages/ui-components/stories/UIDropdown.story.tsx b/packages/ui-components/stories/UIDropdown.story.tsx
index 5ba60d228d..77a6cdd21c 100644
--- a/packages/ui-components/stories/UIDropdown.story.tsx
+++ b/packages/ui-components/stories/UIDropdown.story.tsx
@@ -5,14 +5,11 @@ import {
UISelectableOptionMenuItemType,
UICheckbox,
UIDropdown,
- initIcons,
UISelectableOption,
UITextInput
} from '../src/components';
import { data, shortData, groupsData } from '../test/__mock__/select-data';
-initIcons();
-
export default { title: 'Dropdowns/Dropdown' };
export const Basic = (): JSX.Element => (
diff --git a/packages/ui-components/stories/UIFlexibleTable.story.tsx b/packages/ui-components/stories/UIFlexibleTable.story.tsx
index 6e5e196805..6fe55fa349 100644
--- a/packages/ui-components/stories/UIFlexibleTable.story.tsx
+++ b/packages/ui-components/stories/UIFlexibleTable.story.tsx
@@ -25,10 +25,6 @@ import {
import { arrayMove } from 'react-movable';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
-
export default { title: 'Tables/UIFlexibleTable' };
const tableIds = ['table1', 'table2'];
diff --git a/packages/ui-components/stories/UIIcon.story.tsx b/packages/ui-components/stories/UIIcon.story.tsx
index b395b5c0ee..32251a41c2 100644
--- a/packages/ui-components/stories/UIIcon.story.tsx
+++ b/packages/ui-components/stories/UIIcon.story.tsx
@@ -2,12 +2,9 @@ import React from 'react';
import type { IColumn } from '@fluentui/react';
import { DetailsList, SelectionMode } from '@fluentui/react';
import { UIIcon } from '../src/components/UIIcon';
-import { initIcons, UiIcons } from '../src/components/Icons';
export default { title: 'Utilities/Icons' };
-initIcons();
-
const items: any = [];
for (const icon in UiIcons) {
items.push(icon);
diff --git a/packages/ui-components/stories/UILabel.story.tsx b/packages/ui-components/stories/UILabel.story.tsx
index 10c6b0422d..d5c427f03e 100644
--- a/packages/ui-components/stories/UILabel.story.tsx
+++ b/packages/ui-components/stories/UILabel.story.tsx
@@ -2,9 +2,6 @@ import React from 'react';
import type { IStackTokens } from '@fluentui/react';
import { Text, Stack } from '@fluentui/react';
import { UILabel } from '../src/components/UILabel';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
export default { title: 'Basic Inputs/Label' };
const stackTokens: IStackTokens = { childrenGap: 40 };
diff --git a/packages/ui-components/stories/UILoader.story.tsx b/packages/ui-components/stories/UILoader.story.tsx
index af6a41801b..4c0d2ea134 100644
--- a/packages/ui-components/stories/UILoader.story.tsx
+++ b/packages/ui-components/stories/UILoader.story.tsx
@@ -3,13 +3,11 @@ import type { IStackTokens } from '@fluentui/react';
import { Text, Stack, SpinnerSize } from '@fluentui/react';
import { UILoader } from '../src/components/UILoader';
-import { initIcons } from '../src/components/Icons';
import { UIDefaultButton } from '../src/components/UIButton';
import { UIDialog } from '../src/components/UIDialog';
export default { title: 'Progress/Loader' };
-initIcons();
const stackTokens: IStackTokens = { childrenGap: 40 };
export const Loaders = () => (
diff --git a/packages/ui-components/stories/UIQuickNavigation.story.tsx b/packages/ui-components/stories/UIQuickNavigation.story.tsx
index 15c5daf69f..994e705bf8 100644
--- a/packages/ui-components/stories/UIQuickNavigation.story.tsx
+++ b/packages/ui-components/stories/UIQuickNavigation.story.tsx
@@ -3,7 +3,6 @@ import React from 'react';
import {
UIQuickNavigation,
UIDefaultButton,
- initIcons,
UITextInput,
setQuickNavigationKey,
UIQuickNavigationOffset
@@ -11,8 +10,6 @@ import {
export default { title: 'Utilities/Quick Navigation' };
-initIcons();
-
const value = {
name: 'Hello, world!',
html: 'Tag: name'
@@ -67,9 +64,14 @@ export const External = () => {
};
export const ExternalWithCustomOffset = () => {
- return ;
+ return (
+
+ );
};
diff --git a/packages/ui-components/stories/UISearchBox.story.tsx b/packages/ui-components/stories/UISearchBox.story.tsx
index 838524fb0a..ffa67871e3 100644
--- a/packages/ui-components/stories/UISearchBox.story.tsx
+++ b/packages/ui-components/stories/UISearchBox.story.tsx
@@ -3,14 +3,11 @@ import type { ISearchBoxProps, IStackTokens } from '@fluentui/react';
import { Text, Stack } from '@fluentui/react';
import { UISearchBox } from '../src/components/UISearchBox';
-import { initIcons } from '../src/components/Icons';
import { UICheckbox } from '../src/components';
export default { title: 'Basic Inputs/Search' };
const stackTokens: IStackTokens = { childrenGap: 40 };
-initIcons();
-
export const SearchBox = () => {
const [query, setQuery] = useState('');
diff --git a/packages/ui-components/stories/UITextInput.story.tsx b/packages/ui-components/stories/UITextInput.story.tsx
index 6adaebeeb3..de34697d35 100644
--- a/packages/ui-components/stories/UITextInput.story.tsx
+++ b/packages/ui-components/stories/UITextInput.story.tsx
@@ -4,12 +4,9 @@ import { Text, Stack, Separator } from '@fluentui/react';
import { UITextInput } from '../src/components/UIInput';
import { UICheckbox } from '../src/components/UICheckbox';
-import { initIcons } from '../src/components/Icons';
export default { title: 'Basic Inputs/Input' };
-initIcons();
-
const stackTokens: IStackTokens = { childrenGap: 40 };
const iconFolderProps = { iconName: 'FolderOpened' };
diff --git a/packages/ui-components/stories/UIToggleGroup.story.tsx b/packages/ui-components/stories/UIToggleGroup.story.tsx
index e50a1232e1..26e83509c8 100644
--- a/packages/ui-components/stories/UIToggleGroup.story.tsx
+++ b/packages/ui-components/stories/UIToggleGroup.story.tsx
@@ -2,9 +2,6 @@ import React, { useState } from 'react';
import type { IStackTokens } from '@fluentui/react';
import { Text, Stack } from '@fluentui/react';
import { UIToggleGroup } from '../src/components/UIToggleGroup';
-import { initIcons } from '../src/components/Icons';
-
-initIcons();
export default { title: 'Basic Inputs/Toggle/Group' };
const stackTokens: IStackTokens = { childrenGap: 40 };
diff --git a/packages/ui-components/stories/UITooltip.story.tsx b/packages/ui-components/stories/UITooltip.story.tsx
index 87074dd8a1..2fe24020eb 100644
--- a/packages/ui-components/stories/UITooltip.story.tsx
+++ b/packages/ui-components/stories/UITooltip.story.tsx
@@ -2,12 +2,9 @@ import React from 'react';
import { UITooltip, UITooltipUtils } from '../src/components/UITooltip';
import { UIDefaultButton } from '../src/components/UIButton';
-import { initIcons } from '../src/components/Icons';
export default { title: 'Dropdowns/Tooltip' };
-initIcons();
-
const value = {
name: 'Hello, world!',
html: 'Tag: name'
diff --git a/packages/ui-components/stories/UITranslationInput.story.tsx b/packages/ui-components/stories/UITranslationInput.story.tsx
index 747b541306..c9c5ee8a8f 100644
--- a/packages/ui-components/stories/UITranslationInput.story.tsx
+++ b/packages/ui-components/stories/UITranslationInput.story.tsx
@@ -4,7 +4,7 @@ import type { IStackTokens } from '@fluentui/react';
import { Stack } from '@fluentui/react';
import type { I18nBundle, TranslationEntry } from '../src/components/UITranslationInput';
import { TranslationTextPattern, UITranslationInput } from '../src/components/UITranslationInput';
-import { initIcons, UiIcons } from '../src/components/Icons';
+import { UiIcons } from '../src/components/Icons';
import { UITable } from '../src/components/UITable';
import type { UIColumn } from '../src/components/UITable';
import { UIIconButton } from '../src/components/UIButton';
@@ -26,8 +26,6 @@ interface CustomTranslationEntry extends TranslationEntry {
dummyPath: string;
}
-initIcons();
-
const stackTokens: IStackTokens = { childrenGap: 60 };
const I18N_BUNDLE_KEY = 'ui-components-i18n-bundle';
diff --git a/packages/ui-components/stories/Utilities.story.tsx b/packages/ui-components/stories/Utilities.story.tsx
index 0e7b0300bd..d00934c294 100644
--- a/packages/ui-components/stories/Utilities.story.tsx
+++ b/packages/ui-components/stories/Utilities.story.tsx
@@ -1,9 +1,7 @@
import React, { useState } from 'react';
import { Stack } from '@fluentui/react';
import type { IStackTokens } from '@fluentui/react';
-import { initIcons, UICallout } from '../src/components';
-
-initIcons();
+import { UICallout } from '../src/components';
export default { title: 'Utilities/Misc' };
@@ -15,11 +13,12 @@ const getContent = (name: string): JSX.Element => {
style={{
padding: 10
}}>
- {name}
- lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et
- dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
- commodo consequat duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
- nulla pariatur excepteur sint occaecat cupidatat non proident sunt in culpa qui officia deserunt
+ {name}
+
+ lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore
+ magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
+ consequat duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
+ pariatur excepteur sint occaecat cupidatat non proident sunt in culpa qui officia deserunt
);
};
diff --git a/packages/ui-components/test/unit/theme/Theme.test.ts b/packages/ui-components/test/unit/theme/Theme.test.ts
new file mode 100644
index 0000000000..0b89b2371c
--- /dev/null
+++ b/packages/ui-components/test/unit/theme/Theme.test.ts
@@ -0,0 +1,14 @@
+import { initTheme } from '../../../src';
+import * as fluentUI from '@fluentui/react';
+
+describe('initTheme', () => {
+ it('initTheme', () => {
+ const createThemeSpy = jest.spyOn(fluentUI, 'createTheme');
+ initTheme();
+ expect(createThemeSpy).toBeCalledWith({
+ defaultFontStyle: {
+ WebkitFontSmoothing: ''
+ }
+ });
+ });
+});