Skip to content

Instantly share code, notes, and snippets.

@zachfedor
Created July 18, 2022 15:06
Show Gist options
  • Save zachfedor/236239fb5b7ba49521a48a7d58ff5ae1 to your computer and use it in GitHub Desktop.
Save zachfedor/236239fb5b7ba49521a48a7d58ff5ae1 to your computer and use it in GitHub Desktop.
import * as React from "react";
interface WordBreakProps {
value: string;
on?: string | string[] | RegExp;
}
/**
* Insert <wbr/> element into long text string according to matching rules
*
* You can match a single substring, or an array of substrings, that will capture any
* matches and append the word break. You can also provide a custom Regular Expression.
*
* Example:
* ```
* const value = "/possible/long/file_name.jpg";
* <WordBreak on={["/", "_", "."]} value={value} />
* // Output <>/<wbr/>possible/<wbr/>long/<wbr/>file_<wbr/>name.<wbr/>jpg</>
* ```
*/
function WordBreak({ value, on = "-" }: WordBreakProps) {
if (!value.length) return <>{value}</>;
let regex: RegExp;
// Allow for overriding regular capture behavior with custom regex
if (on instanceof RegExp) regex = on;
else {
// Convert string separator to regex that will split string into array
// while _also_ keeping the separator values inside the array
const captures = typeof on === "string" ? [on] : on;
regex = new RegExp(`([${captures.join("")}])`);
}
const pieces = value.split(regex);
// NOTE: we can't guarantee uniqueness within the array, so we have to use index key
/* eslint-disable react/no-array-index-key */
return (
<>
{pieces.map((piece, index) => (
<React.Fragment key={index}>
{piece}
{!!piece.match(regex) && <wbr />}
</React.Fragment>
))}
</>
);
/* eslint-enable react/no-array-index-key */
}
export { WordBreak };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment