@react-native-vector-icons/common
Version:
Customizable Icons for React Native with support for image source and full styling.
114 lines (113 loc) • 4.13 kB
JavaScript
;
import React, { forwardRef, useEffect } from 'react';
import { Platform, Text } from 'react-native';
import { createIconSourceCache } from "./create-icon-source-cache.js";
import { DEFAULT_ICON_COLOR, DEFAULT_ICON_SIZE } from "./defaults.js";
import { dynamicLoader } from "./dynamicLoading/dynamic-font-loading.js";
import { isDynamicLoadingEnabled } from "./dynamicLoading/dynamic-loading-setting.js";
import { getImageSource as getImageSourceImpl, getImageSourceSync as getImageSourceSyncImpl } from "./get-image-source.js";
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
export function createIconSet(glyphMap, postScriptNameOrOptions, fontFileNameParam, fontStyleParam) {
const {
postScriptName,
fontFileName,
fontStyle
} = typeof postScriptNameOrOptions === 'string' ? {
postScriptName: postScriptNameOrOptions,
fontFileName: fontFileNameParam,
fontStyle: fontStyleParam
} : postScriptNameOrOptions;
const fontBasename = fontFileName ? fontFileName.replace(/\.(otf|ttf)$/, '') : postScriptName;
const fontReference = Platform.select({
windows: `/Assets/${fontFileName}#${postScriptName}`,
android: fontBasename,
default: postScriptName
});
const styleOverrides = {
fontFamily: fontReference,
fontWeight: 'normal',
fontStyle: 'normal'
};
const fontSource = typeof postScriptNameOrOptions === 'object' && postScriptNameOrOptions?.fontSource;
const resolveGlyph = name => {
const glyph = glyphMap[name] || '?';
if (typeof glyph === 'number') {
return String.fromCodePoint(glyph);
}
return glyph;
};
const Icon = ({
name,
size = DEFAULT_ICON_SIZE,
color = DEFAULT_ICON_COLOR,
style,
children,
allowFontScaling = false,
innerRef,
...props
}) => {
const canUseDynamicLoading = !!fontSource && isDynamicLoadingEnabled();
const [isFontLoaded, setIsFontLoaded] = React.useState(canUseDynamicLoading ? dynamicLoader.isLoaded(fontReference) : true);
const glyph = isFontLoaded && name ? resolveGlyph(name) : '';
const shouldLoadFontDynamically = !isFontLoaded && canUseDynamicLoading;
// biome-ignore lint/correctness/useExhaustiveDependencies: the dependencies never change
useEffect(() => {
let isMounted = true;
if (shouldLoadFontDynamically) {
dynamicLoader.loadFontAsync(fontReference, fontSource).finally(() => {
if (isMounted) {
setIsFontLoaded(true);
}
});
}
return () => {
isMounted = false;
};
}, []);
const styleDefaults = {
fontSize: size,
color
};
const newProps = {
...props,
style: [styleDefaults, style, styleOverrides, fontStyle],
allowFontScaling
};
return /*#__PURE__*/_jsxs(Text, {
ref: innerRef,
selectable: false,
...newProps,
children: [glyph, children]
});
};
const WrappedIcon = /*#__PURE__*/forwardRef((props, ref) => /*#__PURE__*/_jsx(Icon, {
innerRef: ref,
...props
}));
WrappedIcon.displayName = `Icon(${postScriptName})`;
const imageSourceCache = createIconSourceCache();
const getImageSource = async (name, sizeOrOptions, color) => {
const canUseDynamicLoading = !!fontSource && isDynamicLoadingEnabled();
if (canUseDynamicLoading && !dynamicLoader.isLoaded(fontReference)) {
await dynamicLoader.loadFontAsync(fontReference, fontSource);
}
const options = typeof sizeOrOptions === 'object' ? sizeOrOptions : {
size: sizeOrOptions,
color
};
return getImageSourceImpl(imageSourceCache, fontReference, resolveGlyph(name), options);
};
const getImageSourceSync = (name, sizeOrOptions, color) => {
const options = typeof sizeOrOptions === 'object' ? sizeOrOptions : {
size: sizeOrOptions,
color
};
return getImageSourceSyncImpl(imageSourceCache, fontReference, resolveGlyph(name), options);
};
const IconNamespace = Object.assign(WrappedIcon, {
getImageSource,
getImageSourceSync
});
return IconNamespace;
}
//# sourceMappingURL=create-icon-set.js.map