@datadog/mobile-react-native
Version:
A client-side React Native module to interact with Datadog
120 lines (108 loc) • 4.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.__ddExtractText = __ddExtractText;
var React = _interopRequireWildcard(require("react"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const LABEL_PROPS = ['children', 'label', 'title', 'text'];
const normalize = s => s.replace(/\s+/g, ' ').trim();
/**
* Extracts readable text from arbitrary values commonly found in React trees.
*
* @param node - Any value: primitives, arrays, iterables, functions, or React elements.
* @param prefer - Optional list of preferred values (e.g., title/label) to attempt first.
* @returns Array of strings.
*/
function __ddExtractText(node, prefer) {
// If caller provided preferred values (title/label/etc.), use those first.
if (Array.isArray(prefer)) {
const preferred = prefer.flatMap(v => __ddExtractText(v)) // recurse so expressions/arrays work
.map(normalize).filter(Boolean);
if (preferred.length) {
return preferred;
}
}
// Base cases
if (node == null || typeof node === 'boolean') {
return [];
}
if (typeof node === 'string' || typeof node === 'number') {
return [normalize(String(node))];
}
// Arrays / iterables → flatten results (don’t concatenate yet)
if (Array.isArray(node)) {
return node.flatMap(x => __ddExtractText(x)).map(normalize).filter(Boolean);
}
if (typeof node === 'object' && Symbol.iterator in node) {
return Array.from(node).flatMap(x => __ddExtractText(x)).map(normalize).filter(Boolean);
}
// Zero-arg render prop
if (typeof node === 'function' && node.length === 0) {
try {
return __ddExtractText(node());
} catch {
return [];
}
}
// React elements
if (/*#__PURE__*/React.isValidElement(node)) {
const props = node.props ?? {};
// If the element itself has a direct label-ish prop, prefer it.
for (const propKey of LABEL_PROPS) {
if (propKey === 'children') {
continue; // handle children below
}
const propValue = props[propKey];
if (propValue != null) {
const got = __ddExtractText(propValue).map(normalize).filter(Boolean);
if (got.length) {
return got;
}
}
}
// Inspect children. Decide whether to return ONE joined label or MANY.
const rawChildData = Array.isArray(props.children) ? props.children : [props.children];
const children = rawChildData.filter(c => c != null && c !== false);
if (children.length === 0) {
return [];
}
// Extract each child to a list of strings (not joined)
const perChild = children.map(child => __ddExtractText(child));
// Heuristic: treat as *compound* if multiple children look like “items”
// e.g., at least two direct children have a label-ish prop or yield non-empty text individually.
let labeledChildCount = 0;
children.forEach((child, i) => {
let hasLabelProp = false;
if (/*#__PURE__*/React.isValidElement(child)) {
const childProps = child.props ?? {};
hasLabelProp = LABEL_PROPS.some(k => childProps?.[k] != null);
}
const childTextCount = perChild[i].filter(Boolean).length;
if (hasLabelProp || childTextCount > 0) {
labeledChildCount++;
}
});
const flat = perChild.flat().map(normalize).filter(Boolean);
// If there are multiple *direct* labelled children, return many (compound).
// Otherwise, return a single joined label.
if (labeledChildCount > 1) {
// De-duplicate while preserving order
const seen = new Set();
const out = [];
for (const str of flat) {
const key = str;
if (!seen.has(key)) {
seen.add(key);
out.push(str);
}
}
return out;
}
// Not “compound”: join everything into one readable string
const joined = normalize(flat.join(' '));
return joined ? [joined] : [];
}
return [];
}
//# sourceMappingURL=ddBabelUtils.js.map