@applicaster/zapp-react-native-ui-components
Version:
Applicaster Zapp React Native ui components for the Quick Brick App
158 lines (133 loc) • 4.3 kB
text/typescript
import * as R from "ramda";
import throttle from "lodash/throttle";
import { toCamelCase } from "@applicaster/zapp-react-native-utils/stringUtils";
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
import { mapKeys } from "@applicaster/zapp-react-native-utils/objectUtils";
const throttleWait = 50;
const throttleOpts = {
leading: false,
trailing: true,
};
export const scrollToSelectedIndex = (flatListRef, config, length) =>
throttle(
(index: number = 0, viewPosition: number = 0) => {
const { tab_bar_type: type, component_padding_left: paddingLeft } =
config;
const isHorizontal = R.equals("horizontal", type);
const isLast = R.equals(index, length - 1);
const isFirst = R.equals(index, 0);
if (!isHorizontal) {
flatListRef?.current?.scrollToIndex({
index: index,
viewPosition: R.equals(0, viewPosition) ? 0 : 0.5,
animated: true,
});
} else {
flatListRef?.current?.scrollToIndex({
index: index,
viewPosition: R.equals(0, viewPosition) ? 0 : 0.5,
viewOffset: isHorizontal && (isFirst || isLast) ? paddingLeft : 0,
animated: true,
});
}
},
throttleWait,
throttleOpts
);
export const getId = R.prop("id");
export const generateFocusableId = (itemId) => `TabBarItem.${itemId}`;
const is = (val) => () => val;
export const getStyleKey = ({ styleKey, focused, selected }) => {
return R.compose(
toCamelCase,
R.tail,
R.join(""),
R.when(is(selected), R.prepend("_selected")),
R.when(is(focused), R.prepend("_focused")),
R.append(R.__, []),
R.concat("_")
)(styleKey);
};
const getPlatformData = (specs) => {
// can't use optionals in process.env calls because of webpack
if (process.env.NODE_ENV === "test") {
try {
return specs[(global as any)?.__test_platform];
} catch (e) {
// this is only used to get a specific value
// when running test. this is ignored on dev / production
}
}
return platformSelect(specs);
};
const getFontConfig = R.compose(
R.partition(
R.compose(
R.test(/font_family|font_size|line_height|letter_spacing/),
R.head
)
),
R.toPairs
);
const platformPrefixes = {
android_tv: "android_tv_",
tvos: "tvos_",
samsung_tv: "samsung_tv_",
lg_tv: "lg_tv_",
web: "samsung_tv_",
default: "samsung_tv_",
};
export function applyFontConfig(config) {
const [fontConfig, rest] = getFontConfig(config);
const platformPrefix = getPlatformData(platformPrefixes);
const fontProps = R.compose(
mapKeys(R.replace(platformPrefix, "")),
R.fromPairs,
R.filter(R.compose(R.contains(platformPrefix), R.head))
)(fontConfig);
const otherProps = R.fromPairs(rest);
return {
...fontProps,
...otherProps,
};
}
/* eslint-disable padding-line-between-statements */
export const typePath = R.prop("tab_bar_type");
export const displayTypePath = R.prop("tab_bar_display_mode");
export const itemsAlignmentPath = R.prop("tab_bar_alignment");
export const itemAlignmentPath = R.prop("tab_bar_item_alignment");
export const itemSizeTypePath = R.prop("tab_bar_item_size");
export const isFixed = R.equals("fixed");
export const transformValue = (value, type) => {
switch (type) {
case "justifyContent":
case "alignItems":
if (value === "left") {
return "flex-start";
} else if (value === "right") {
return "flex-end";
} else {
return value;
}
case "flexDirectionAsset":
if (value === "right") return "row-reverse";
else if (value === "top") return "column";
else if (value === "bottom") return "column-reverse";
else return "row";
case "textAlign":
return value;
default:
// eslint-disable-next-line no-console
console.log(`type '${type}' doesn\\'t exist`);
return null;
}
};
type valueFromConfigType<T> = (
config: T
) => (key: string, prefix?: string, component?: string) => unknown;
export const valueFromConfig: valueFromConfigType<PlatformConfiguration> = (
config
) => {
return (key, prefix = "", component = "tab_bar_item") =>
config?.[`${component}${prefix.length > 0 ? `_${prefix}` : ""}_${key}`];
};