diff --git a/.changeset/giant-birds-eat.md b/.changeset/giant-birds-eat.md new file mode 100644 index 0000000000..6e73b30e96 --- /dev/null +++ b/.changeset/giant-birds-eat.md @@ -0,0 +1,15 @@ +--- +'@rainbow-me/rainbowkit': patch +--- + +Add `fontStack` option to built-in themes, supporting `"rounded"` and `"system"` variants. + +You can now opt out of using [SF Pro Rounded,](https://developer.apple.com/fonts) using default system fonts instead. + +**Example usage** + +```tsx +const theme = lightTheme({ + fontStack: 'system', +}); +``` diff --git a/README.md b/README.md index 3610d9ab7d..2c3f5c0765 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,12 @@ The built-in theme functions also accept an options object, allowing you to sele "large" The size of the entire border radius scale + + fontStack + "rounded" | "system" + "rounded" + The font stack used throughout the UI. Note that ‘rounded’ attempts to use SF Pro Rounded, falling back to system fonts when it isn’t available. + diff --git a/packages/example/pages/_app.tsx b/packages/example/pages/_app.tsx index 3b4d5f61fa..a197511367 100644 --- a/packages/example/pages/_app.tsx +++ b/packages/example/pages/_app.tsx @@ -55,6 +55,9 @@ const themes = [ ] as const; type ThemeName = typeof themes[number]['name']; +const fontStacks = ['rounded', 'system'] as const; +type FontStack = typeof fontStacks[number]; + const accentColors = [ 'blue', 'green', @@ -71,6 +74,7 @@ type RadiusScale = typeof radiusScales[number]; function App({ Component, pageProps }: AppProps) { const [selectedThemeName, setThemeName] = useState('light'); + const [selectedFontStack, setFontStack] = useState('rounded'); const [selectedAccentColor, setAccentColor] = useState('blue'); const [selectedRadiusScale, setRadiusScale] = useState('large'); @@ -79,6 +83,7 @@ function App({ Component, pageProps }: AppProps) { ?.theme({ accentColor: selectedAccentColor, borderRadius: selectedRadiusScale, + fontStack: selectedFontStack, }); return ( @@ -122,6 +127,30 @@ function App({ Component, pageProps }: AppProps) { ))} +
+

Font stack

+
+ {fontStacks.map(fontStack => ( + + ))} +
+

Accent

{ "--rk-colors-profileForeground": "rgba(60, 66, 66, 0.1)", "--rk-colors-selectedOptionBorder": "rgba(60, 66, 66, 0.1)", "--rk-colors-standby": "#FFD641", - "--rk-fonts-body": "SFRounded,ui-rounded,SF Pro Rounded,system-ui,Helvetica Neue,Arial,Helvetica,sans-serif", + "--rk-fonts-body": "SFRounded, ui-rounded, SF Pro Rounded, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol", "--rk-radii-actionButton": "9999px", "--rk-radii-connectButton": "12px", "--rk-radii-menuButton": "12px", diff --git a/packages/rainbowkit/src/css/cssStringFromTheme.test.ts b/packages/rainbowkit/src/css/cssStringFromTheme.test.ts index 0036b62622..fd00672674 100644 --- a/packages/rainbowkit/src/css/cssStringFromTheme.test.ts +++ b/packages/rainbowkit/src/css/cssStringFromTheme.test.ts @@ -5,7 +5,7 @@ import { cssStringFromTheme } from './cssStringFromTheme'; describe('cssStringFromTheme', () => { it('converts themes to CSS strings', () => { expect(cssStringFromTheme(lightTheme())).toMatchInlineSnapshot( - '"--rk-fonts-body:SFRounded,ui-rounded,SF Pro Rounded,system-ui,Helvetica Neue,Arial,Helvetica,sans-serif;--rk-radii-actionButton:9999px;--rk-radii-connectButton:12px;--rk-radii-menuButton:12px;--rk-radii-modal:24px;--rk-radii-modalMobile:28px;--rk-borders-modalBorderWidth:0px;--rk-colors-accentColor:#0E76FD;--rk-colors-actionButtonBorder:rgba(0, 0, 0, 0.04);--rk-colors-actionButtonBorderMobile:rgba(0, 0, 0, 0);--rk-colors-actionButtonSecondaryBackground:rgba(0, 0, 0, 0.06);--rk-colors-actionButtonText:#FFF;--rk-colors-closeButton:rgba(60, 66, 66, 0.8);--rk-colors-closeButtonBackground:rgba(0, 0, 0, 0.06);--rk-colors-connectButtonBackground:#FFF;--rk-colors-connectButtonBackgroundError:#FF494A;--rk-colors-connectButtonInnerBackground:linear-gradient(0deg, rgba(0, 0, 0, 0.03), rgba(0, 0, 0, 0.06));--rk-colors-connectButtonText:#25292E;--rk-colors-connectButtonTextError:#FFF;--rk-colors-connectionIndicator:#30E000;--rk-colors-error:#FF494A;--rk-colors-generalBorder:rgba(0, 0, 0, 0.06);--rk-colors-generalBorderDim:rgba(0, 0, 0, 0.03);--rk-colors-menuItemBackground:rgba(60, 66, 66, 0.1);--rk-colors-modalBackdrop:rgba(0, 0, 0, 0.3);--rk-colors-modalBackground:#FFF;--rk-colors-modalBorder:rgba(255, 255, 255, 0);--rk-colors-modalText:#25292E;--rk-colors-modalTextDim:rgba(60, 66, 66, 0.3);--rk-colors-modalTextSecondary:rgba(60, 66, 66, 0.6);--rk-colors-profileAction:#FFF;--rk-colors-profileActionHover:rgba(255, 255, 255, 0.5);--rk-colors-profileForeground:rgba(60, 66, 66, 0.1);--rk-colors-selectedOptionBorder:rgba(60, 66, 66, 0.1);--rk-colors-standby:#FFD641;--rk-shadows-connectButton:0px 4px 12px rgba(0, 0, 0, 0.1);--rk-shadows-dialog:0px 8px 32px rgba(0, 0, 0, 0.32);--rk-shadows-profileDetailsAction:0px 2px 6px rgba(37, 41, 46, 0.04);--rk-shadows-selectedOption:0px 2px 6px rgba(0, 0, 0, 0.24);--rk-shadows-selectedWallet:0px 2px 6px rgba(0, 0, 0, 0.12);"' + '"--rk-fonts-body:SFRounded, ui-rounded, SF Pro Rounded, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;--rk-radii-actionButton:9999px;--rk-radii-connectButton:12px;--rk-radii-menuButton:12px;--rk-radii-modal:24px;--rk-radii-modalMobile:28px;--rk-borders-modalBorderWidth:0px;--rk-colors-accentColor:#0E76FD;--rk-colors-actionButtonBorder:rgba(0, 0, 0, 0.04);--rk-colors-actionButtonBorderMobile:rgba(0, 0, 0, 0);--rk-colors-actionButtonSecondaryBackground:rgba(0, 0, 0, 0.06);--rk-colors-actionButtonText:#FFF;--rk-colors-closeButton:rgba(60, 66, 66, 0.8);--rk-colors-closeButtonBackground:rgba(0, 0, 0, 0.06);--rk-colors-connectButtonBackground:#FFF;--rk-colors-connectButtonBackgroundError:#FF494A;--rk-colors-connectButtonInnerBackground:linear-gradient(0deg, rgba(0, 0, 0, 0.03), rgba(0, 0, 0, 0.06));--rk-colors-connectButtonText:#25292E;--rk-colors-connectButtonTextError:#FFF;--rk-colors-connectionIndicator:#30E000;--rk-colors-error:#FF494A;--rk-colors-generalBorder:rgba(0, 0, 0, 0.06);--rk-colors-generalBorderDim:rgba(0, 0, 0, 0.03);--rk-colors-menuItemBackground:rgba(60, 66, 66, 0.1);--rk-colors-modalBackdrop:rgba(0, 0, 0, 0.3);--rk-colors-modalBackground:#FFF;--rk-colors-modalBorder:rgba(255, 255, 255, 0);--rk-colors-modalText:#25292E;--rk-colors-modalTextDim:rgba(60, 66, 66, 0.3);--rk-colors-modalTextSecondary:rgba(60, 66, 66, 0.6);--rk-colors-profileAction:#FFF;--rk-colors-profileActionHover:rgba(255, 255, 255, 0.5);--rk-colors-profileForeground:rgba(60, 66, 66, 0.1);--rk-colors-selectedOptionBorder:rgba(60, 66, 66, 0.1);--rk-colors-standby:#FFD641;--rk-shadows-connectButton:0px 4px 12px rgba(0, 0, 0, 0.1);--rk-shadows-dialog:0px 8px 32px rgba(0, 0, 0, 0.32);--rk-shadows-profileDetailsAction:0px 2px 6px rgba(37, 41, 46, 0.04);--rk-shadows-selectedOption:0px 2px 6px rgba(0, 0, 0, 0.24);--rk-shadows-selectedWallet:0px 2px 6px rgba(0, 0, 0, 0.12);"' ); }); }); diff --git a/packages/rainbowkit/src/themes/baseTheme.ts b/packages/rainbowkit/src/themes/baseTheme.ts index 3e9c86017b..99731a60d0 100644 --- a/packages/rainbowkit/src/themes/baseTheme.ts +++ b/packages/rainbowkit/src/themes/baseTheme.ts @@ -1,6 +1,25 @@ import { ThemeVars } from '../css/sprinkles.css'; -const radii: Record = { +// Source: https://css-tricks.com/snippets/css/system-font-stack +// Note that quotes have been removed to avoid escaping and server/client mismatch issues +const systemFontStack = + '-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol'; +const fontStacks = { + rounded: `SFRounded, ui-rounded, SF Pro Rounded, ${systemFontStack}`, + system: systemFontStack, +} as const; +type FontStack = keyof typeof fontStacks; + +type RadiusScale = 'large' | 'medium' | 'small' | 'none'; +const radiusScales: Record< + RadiusScale, + { + actionButton: string; + connectButton: string; + modal: string; + modalMobile: string; + } +> = { large: { actionButton: '9999px', connectButton: '12px', @@ -27,29 +46,27 @@ const radii: Record = { }, }; +interface BaseThemeOptions { + borderRadius?: RadiusScale; + fontStack?: FontStack; +} + export const baseTheme = ({ borderRadius = 'large', -}: Pick): Pick => ({ + fontStack = 'rounded', +}: BaseThemeOptions): Pick => ({ fonts: { - body: 'SFRounded,ui-rounded,SF Pro Rounded,system-ui,Helvetica Neue,Arial,Helvetica,sans-serif', + body: fontStacks[fontStack], }, radii: { - actionButton: radii[borderRadius].actionButton, - connectButton: radii[borderRadius].connectButton, - menuButton: radii[borderRadius].connectButton, - modal: radii[borderRadius].modal, - modalMobile: radii[borderRadius].modalMobile, + actionButton: radiusScales[borderRadius].actionButton, + connectButton: radiusScales[borderRadius].connectButton, + menuButton: radiusScales[borderRadius].connectButton, + modal: radiusScales[borderRadius].modal, + modalMobile: radiusScales[borderRadius].modalMobile, }, }); -type RadiiScale = { - actionButton: string; - connectButton: string; - modal: string; - modalMobile: string; -}; -type RadiiValues = 'large' | 'medium' | 'small' | 'none'; - export type AccentValues = | 'blue' | 'green' @@ -59,7 +76,6 @@ export type AccentValues = | 'orange' | 'yellow'; -export interface ThemeOptions { +export interface ThemeOptions extends BaseThemeOptions { accentColor?: AccentValues; - borderRadius?: RadiiValues; } diff --git a/packages/rainbowkit/src/themes/darkTheme.ts b/packages/rainbowkit/src/themes/darkTheme.ts index 02fe700811..4c21163fe2 100644 --- a/packages/rainbowkit/src/themes/darkTheme.ts +++ b/packages/rainbowkit/src/themes/darkTheme.ts @@ -12,9 +12,9 @@ const accents: Record = { export const darkTheme = ({ accentColor = 'blue', - borderRadius, + ...baseThemeOptions }: ThemeOptions = {}) => ({ - ...baseTheme({ borderRadius }), + ...baseTheme(baseThemeOptions), borders: { modalBorderWidth: '1px', }, diff --git a/packages/rainbowkit/src/themes/lightTheme.ts b/packages/rainbowkit/src/themes/lightTheme.ts index f10a99e7e1..091f8a5647 100644 --- a/packages/rainbowkit/src/themes/lightTheme.ts +++ b/packages/rainbowkit/src/themes/lightTheme.ts @@ -12,9 +12,9 @@ const accents: Record = { export const lightTheme = ({ accentColor = 'blue', - borderRadius, + ...baseThemeOptions }: ThemeOptions = {}) => ({ - ...baseTheme({ borderRadius }), + ...baseTheme(baseThemeOptions), borders: { modalBorderWidth: '0px', }, diff --git a/packages/rainbowkit/src/themes/midnightTheme.ts b/packages/rainbowkit/src/themes/midnightTheme.ts index 68480bf8b3..68ac1e5835 100644 --- a/packages/rainbowkit/src/themes/midnightTheme.ts +++ b/packages/rainbowkit/src/themes/midnightTheme.ts @@ -12,9 +12,9 @@ const accents: Record = { export const midnightTheme = ({ accentColor = 'blue', - borderRadius, + ...baseThemeOptions }: ThemeOptions = {}) => ({ - ...baseTheme({ borderRadius }), + ...baseTheme(baseThemeOptions), borders: { modalBorderWidth: '1px', },