Collection editor: Format topic as hashtag (#38153)
This commit is contained in:
1 parent
3091e2e525
commit
3ef7d2835a
4 files changed
+81
-17
No files matched your search
@@ -0,0 +1,28 @@
|
||||
import { inputToHashtag } from './hashtags';
|
||||
|
||||
describe('inputToHashtag', () => {
|
||||
test.concurrent.each([
|
||||
['', ''],
|
||||
// Prepend or keep hashtag
|
||||
['mastodon', '#mastodon'],
|
||||
['#mastodon', '#mastodon'],
|
||||
// Preserve trailing whitespace
|
||||
['mastodon ', '#mastodon '],
|
||||
[' ', '# '],
|
||||
// Collapse whitespace & capitalise first character
|
||||
['cats of mastodon', '#catsOfMastodon'],
|
||||
['x y z', '#xYZ'],
|
||||
[' mastodon', '#mastodon'],
|
||||
// Preserve initial casing
|
||||
['Log in', '#LogIn'],
|
||||
['#NaturePhotography', '#NaturePhotography'],
|
||||
// Normalise hash symbol variant
|
||||
['#nature', '#nature'],
|
||||
['#Nature Photography', '#NaturePhotography'],
|
||||
// Allow special characters
|
||||
['hello-world', '#hello-world'],
|
||||
['hello,world', '#hello,world'],
|
||||
])('for input "%s", return "%s"', (input, expected) => {
|
||||
expect(inputToHashtag(input)).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -27,3 +27,35 @@ const buildHashtagRegex = () => {
|
||||
export const HASHTAG_PATTERN_REGEX = buildHashtagPatternRegex();
|
||||
|
||||
export const HASHTAG_REGEX = buildHashtagRegex();
|
||||
|
||||
/**
|
||||
* Formats an input string as a hashtag:
|
||||
* - Prepends `#` unless present
|
||||
* - Strips spaces (except at the end, to allow typing it)
|
||||
* - Capitalises first character after stripped space
|
||||
*/
|
||||
export const inputToHashtag = (input: string): string => {
|
||||
if (!input) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const trailingSpace = /\s+$/.exec(input)?.[0] ?? '';
|
||||
const trimmedInput = input.trimEnd();
|
||||
|
||||
const withoutHash =
|
||||
trimmedInput.startsWith('#') || trimmedInput.startsWith('#')
|
||||
? trimmedInput.slice(1)
|
||||
: trimmedInput;
|
||||
|
||||
// Split by space, filter empty strings, and capitalise the start of each word but the first
|
||||
const words = withoutHash
|
||||
.split(/\s+/)
|
||||
.filter((word) => word.length > 0)
|
||||
.map((word, index) =>
|
||||
index === 0
|
||||
? word
|
||||
: word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(),
|
||||
);
|
||||
|
||||
return `#${words.join('')}${trailingSpace}`;
|
||||
};
|
||||
Reference in new issue
Block a user