xref: /expo/docs/common/utilities.ts (revision 5959d3ad)
1import GithubSlugger from 'github-slugger';
2import React from 'react';
3
4function hasChildren(node: React.ReactNode): node is React.ReactElement {
5  return (node as React.ReactElement)?.props?.children !== undefined;
6}
7
8/**
9 * Converts any object to string accepted by _Slugger_.
10 * This is needed, because sometimes we receive pure string node,
11 * but sometimes (e.g. when using styled text), we receive whole object (React.Element)
12 *
13 * @param {React.ReactNode} node React Node object to stringify
14 */
15export const toString = (node: React.ReactNode): string => {
16  if (typeof node === 'string') {
17    return node;
18  } else if (Array.isArray(node)) {
19    return node.map(toString).join('');
20  } else if (hasChildren(node)) {
21    return toString(node.props.children);
22  } else {
23    return '';
24  }
25};
26
27export const generateSlug = (slugger: GithubSlugger, node: React.ReactNode, length = 7): string => {
28  const stringToSlug = toString(node).split(' ').splice(0, length).join('-');
29
30  // NOTE(jim): This will strip out commas from stringToSlug
31  return slugger.slug(stringToSlug);
32};
33
34/**
35 * Replace the version in the pathname from the URL.
36 */
37export const replaceVersionInUrl = (url: string, replaceWith: string) => {
38  const urlArr = url.split('/');
39  urlArr[2] = replaceWith;
40  return urlArr.join('/');
41};
42
43/**
44 * Get the user facing or human-readable version from the SDK version.
45 * If you provide a `latestVersion` or `betaVersion`, matching entries will include the correct label in parentheses.
46 */
47export const getUserFacingVersionString = (
48  version: string,
49  latestVersion?: string,
50  betaVersion?: string
51): string => {
52  const versionString = `SDK ${version?.substring(1, 3)}`;
53
54  if (version === 'latest') {
55    return latestVersion ? `${getUserFacingVersionString(latestVersion)} (Latest)` : 'Latest';
56  } else if (version === betaVersion) {
57    return `${versionString} (Beta)`;
58  } else if (version === 'unversioned') {
59    return 'Unversioned';
60  }
61
62  return versionString;
63};
64
65export const stripVersionFromPath = (path?: string) => {
66  if (!path) {
67    return path;
68  }
69  return path.replace(/\/versions\/[\w.]+/, '');
70};
71
72export const pathStartsWith = (name: string, path: string) => {
73  return path.startsWith(`/${name}`);
74};
75
76export const chunkArray = (array: any[], chunkSize: number) => {
77  return array.reduce((acc, _, i) => {
78    if (i % chunkSize === 0) acc.push(array.slice(i, i + chunkSize));
79    return acc;
80  }, []);
81};
82