Skip to content

Commit db8f828

Browse files
committed
feat: add explicit sizing to SFSymbol component
- Set default size to "body" text style - Calculate pixel dimensions from size prop - Apply width/height style to enforce sizing - Map text styles to point sizes - Export SFSymbolResizeMode type
1 parent 136efe8 commit db8f828

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

src/components/SFSymbol.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { StyleSheet, type ColorValue, type StyleProp, type TextStyle } from "rea
44
import NativeSFSymbolViewNativeComponent, {
55
type NativeSFSymbolProps,
66
type NativeSFSymbolRenderingMode,
7+
type NativeSFSymbolResizeMode,
78
type NativeSFSymbolScale,
89
type NativeSFSymbolTextStyle,
910
type NativeSFSymbolWeight,
@@ -14,8 +15,23 @@ type NativeSFSymbolComponentRef = React.ComponentRef<typeof NativeSFSymbolViewNa
1415
export type SFSymbolWeight = NativeSFSymbolWeight;
1516
export type SFSymbolScale = NativeSFSymbolScale;
1617
export type SFSymbolRenderingMode = NativeSFSymbolRenderingMode;
18+
export type SFSymbolResizeMode = NativeSFSymbolResizeMode;
1719
export type SFSymbolTextStyle = NativeSFSymbolTextStyle;
1820

21+
const TEXT_STYLE_TO_POINTS: Record<SFSymbolTextStyle, number> = {
22+
largeTitle: 34,
23+
title: 28,
24+
title2: 22,
25+
title3: 20,
26+
headline: 17,
27+
subheadline: 15,
28+
body: 17,
29+
callout: 16,
30+
footnote: 13,
31+
caption: 12,
32+
caption2: 11,
33+
};
34+
1935
export type SFSymbolProps = Omit<NativeSFSymbolProps, "size" | "textStyle" | "style" | "colors"> & {
2036
/**
2137
* Size of the symbol. Can be a number (point size) or a text style string.
@@ -79,11 +95,19 @@ export type SFSymbolProps = Omit<NativeSFSymbolProps, "size" | "textStyle" | "st
7995
* ```
8096
*/
8197
export const SFSymbol = forwardRef<NativeSFSymbolComponentRef, SFSymbolProps>(
82-
({ size, color, colors, style, ...restProps }, ref) => {
98+
({ size = "body", color, colors, style, ...restProps }, ref) => {
8399
// Determine if size is a number (point size) or string (text style)
84100
const sizeProps: Pick<NativeSFSymbolProps, "size" | "textStyle"> =
85101
typeof size === "number" ? { size } : typeof size === "string" ? { textStyle: size } : {};
86102

103+
// Calculate dimension for explicit sizing
104+
const dimension = useMemo(() => {
105+
if (typeof size === "number") {
106+
return size;
107+
}
108+
return TEXT_STYLE_TO_POINTS[size in TEXT_STYLE_TO_POINTS ? size : "body"];
109+
}, [size]);
110+
87111
// Resolve colors: colors prop > color prop > style.color
88112
const resolvedColors = useMemo(() => {
89113
if (colors && colors.length > 0) {
@@ -99,12 +123,17 @@ export const SFSymbol = forwardRef<NativeSFSymbolComponentRef, SFSymbolProps>(
99123
return undefined;
100124
}, [colors, color, style]);
101125

126+
// Combine user style with explicit sizing
127+
const combinedStyle = useMemo(() => {
128+
return [{ width: dimension, height: dimension }, style];
129+
}, [dimension, style]);
130+
102131
return (
103132
<NativeSFSymbolViewNativeComponent
104133
{...restProps}
105134
{...sizeProps}
106135
colors={resolvedColors}
107-
style={style}
136+
style={combinedStyle}
108137
ref={ref}
109138
/>
110139
);

0 commit comments

Comments
 (0)