-
Notifications
You must be signed in to change notification settings - Fork 620
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(text): cases #4082
feat(text): cases #4082
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done! Just a few nits.
Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
I updated the PR so split takes Note there might be data loss between cases, but I think that makes sense for those cases. |
text/_util.ts
Outdated
export function split( | ||
input: string, | ||
{ singleDelimiter = false, removeSpecialCharacters }: SplitOptions = {}, | ||
) { | ||
if (removeSpecialCharacters) { | ||
input = input.replaceAll(/[^a-zA-Z0-9\s-_]/g, ""); | ||
} | ||
if (singleDelimiter) { | ||
if (/\s+/.test(input)) return input.split(/\s+/).filter(Boolean); | ||
if (/-+/.test(input)) return input.split(/-+/).filter(Boolean); | ||
if (/_+/.test(input)) return input.split(/_+/).filter(Boolean); | ||
} else { | ||
if (/[\s-_]+/.test(input)) return input.split(/[\s-_]+/).filter(Boolean); | ||
} | ||
return input.split(/(?=[A-Z])+/).filter(Boolean); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's revert this to the original version. It was good for the first-pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure? I think it is an improvement that handles a bunch of edge cases concerning delimiters, whitespaces and special characters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for now. I know it won't be what's published upon release, but it allows us to explore ideas. Frankly, I'm not a fan of the SplitOptions
argument here. My idea was to perhaps have a 2nd optional parameter, say separator: string | RegExp
, that the user can define but has a reasonable default. Again, I'd want to play with the idea a little first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get what you mean. But then again, that complicates things. Imo instead of providing configurations and options for special cases to the user, special cases should be handled on the string manually, or via preprocess and then apply the case after.
split()
and SplitOptions
is just used internally, so this can be changed if needed. The return values of public to*Case
is what most would expected now imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this function is that there's a seemingly arbitrary order of precedence in the characters that the word is split by. I.e. the word is split by spaces if spaces are what's first detected. Then dashes. Then underscores. Why in that order?
I think we should just split by all of these delimiters in one hit, as I previously suggested. I understand that it'll also split words with delimiters of mixed types. But that seems like the correct behaviour to me and is behaviour that's easier to understand. Also, that's what lodash does.
import camelCase from "npm:lodash.camelcase";
console.log(camelCase("why hello-there")); // "whyHelloThere"
text/_util.ts
Outdated
export function split( | ||
input: string, | ||
{ singleDelimiter = false, removeSpecialCharacters }: SplitOptions = {}, | ||
) { | ||
if (removeSpecialCharacters) { | ||
input = input.replaceAll(/[^a-zA-Z0-9\s-_]/g, ""); | ||
} | ||
if (singleDelimiter) { | ||
if (/\s+/.test(input)) return input.split(/\s+/).filter(Boolean); | ||
if (/-+/.test(input)) return input.split(/-+/).filter(Boolean); | ||
if (/_+/.test(input)) return input.split(/_+/).filter(Boolean); | ||
} else { | ||
if (/[\s-_]+/.test(input)) return input.split(/[\s-_]+/).filter(Boolean); | ||
} | ||
return input.split(/(?=[A-Z])+/).filter(Boolean); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this function is that there's a seemingly arbitrary order of precedence in the characters that the word is split by. I.e. the word is split by spaces if spaces are what's first detected. Then dashes. Then underscores. Why in that order?
I think we should just split by all of these delimiters in one hit, as I previously suggested. I understand that it'll also split words with delimiters of mixed types. But that seems like the correct behaviour to me and is behaviour that's easier to understand. Also, that's what lodash does.
import camelCase from "npm:lodash.camelcase";
console.log(camelCase("why hello-there")); // "whyHelloThere"
@iuioiua I think we could solve that if we create a separate splitter for |
Ok, I looked at some more implementations and would suggest the following:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PTAL at some of the suggestions in my previous review.
I'm happy to add
👍🏾
One question I have is why each function must split its words differently. IMO, each phrase should be split in the same way. It'd make understanding and working with all these functions much easier and still provide good DX. WDYT, @kt3k and @timreichen? |
What I meant was that |
I had a chat with Yoshiya. He also thinks that It'd be good to get this PR over the line. I suggest we do the following:
That should be good enough for the first pass. We can discuss and iterate after. |
Ok, done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work! LGTM. Thank you again, Tim.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This is the successor of #3440. Big thanks to @Gustrb for the initial PR.
implements the following cases:
toCamelCase()
toKebabCase()
toPascalCase()
toSentenceCase()
toSnakeCase()
toTitleCase()
They are interoperable, so this works: