Skip to content
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

CSS Plugin: Handle Whitespace in Token Ids #131

Merged
merged 19 commits into from
Nov 5, 2023

Conversation

dev-nicolaos
Copy link
Contributor

@dev-nicolaos dev-nicolaos commented Oct 18, 2023

Changes

This PR fixes #123 by removing leading and trailing white space from token and token group names and camelCasing those with white space in the middle of their names.

It also adds a new plugin option called generateName that allows the consumer to customize that behavior (and everything else about how a name is generated). This makes the prefix option redundant, so it has been deprecated.

How to Review

I broke the functions in the util.ts file into their own files in a utils folder for improved readability and test-ability, which made it a lot easier to work on the variable name conversion refactor in isolation. I also added tests for the bug fix and the new option.

Observe that the unit and integration tests added for handling whitespace in token and group names pass.

The documentation added can be seen at the bottom of the options section of the plugin's page.

@changeset-bot
Copy link

changeset-bot bot commented Oct 18, 2023

🦋 Changeset detected

Latest commit: 7a7a1d1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@cobalt-ui/plugin-css Minor
@cobalt-ui/plugin-sass Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@dev-nicolaos dev-nicolaos marked this pull request as draft November 2, 2023 18:16
@dev-nicolaos dev-nicolaos marked this pull request as ready for review November 5, 2023 07:46
@dev-nicolaos dev-nicolaos requested a review from drwpow November 5, 2023 07:46
@@ -76,12 +76,14 @@ export default {
embedFiles: false,
/** (optional) transform specific token values */
transform: () => null,
/** (optional) add custom namespace to CSS vars */
/** (deprecated, use generateName instead) add custom namespace to CSS vars */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for updating the JSDoc hints! I can make this change after merge, but I’ll put a /** @deprecated tag on it and that shows up in the IDE

}),
],
};
```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 Awesome docs addition, thank you!

expect(defaultNameGenerator('path.to.token', 'scope-')).toBe('scope-path-to-token');
});
});
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Collaborator

@drwpow drwpow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks awesome! 💯 Sorry for the little bit of change there but I’m really happy with this solution, and it solves multiple problems in one PR. Thank you!

@drwpow drwpow merged commit 6628a8c into terrazzoapp:main Nov 5, 2023
5 checks passed
@github-actions github-actions bot mentioned this pull request Nov 5, 2023
@dev-nicolaos dev-nicolaos deleted the css-handle-whitespace branch November 5, 2023 16:33
variableId: string,
token?: ParsedToken,
): string => {
const name = customNameGenerator ? customNameGenerator(variableId, token) : defaultNameGenerator(variableId, prefix);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like your implementation, but I will make one tiny change here in a patch release: we call a user’s customNameGenerator() on every token, and they’re allowed to return undefined or null if they’d like to defer naming back to us.

This is common plugin behavior (example: Rollup) and is a super minor detail that doesn’t affect the overall code. Just a tiny logical change that rather than checking a user passed the function, instead check the return value of the function and fall back to defaultNameGenerator() if customNameGenerator() executed but returned a falsy value.

Copy link
Collaborator

@drwpow drwpow Nov 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The breakage was really impossible to test for; it had to do with mismatching versions of plugin-css and plugin-sass. And since we didn’t indicate this as a breaking change, we shouldn’t require both be upgraded (I didn’t realize it either). Not really a way to test for this (maintaining old versions in the test suite just to test compatibility is a path to madness).

So note I’m not changing any code you wrote or how this function works; just going to change some internal function signatures and release a patch for plugin-css and plugin-sass so both can work correctly with mismatched versions (which, ironically, updating both to the patched version would fix the problem anyway, but it at least signals to consumers that a problem was identified and fixed).

Again, no one’s fault, not a big deal, and just sort of a weird, unpredictable, hard-to-test-for scenario. But wanted to leave a note.

/** reference an existing CSS var */
export function varRef(id: string, options?: {prefix?: string; suffix?: string; fallbacks?: string[]; mode?: string}): string {
export function varRef(id: string, tokens: ParsedToken[], generateName: ReturnType<typeof makeNameGenerator>, suffix?: string): string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also a note: will have to revert some of the changes to the varRef API as it’s used outside this plugin (may not be best practice, but it is what it is).

Mainly will revert the ordered params and revert back to a single object param for options (which is preferred in general, because then you can add/remove options easily, and handle backwards compatibility, with minimal effort)

export function defaultTransformer(token: ParsedToken, {colorFormat = 'hex', mode, prefix}: {colorFormat: Options['colorFormat']; mode?: string; prefix?: string}): string | number | Record<string, string> {
export function defaultTransformer(
token: ParsedToken,
tokens: ParsedToken[],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here, too—didn’t notice this change to the defaultTransformer() function signature that was a breaking change for this plugin (because it taps into transform()). Again, there were no tests to catch this, so that’s a fault of the test suite! Just leaving notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CSS Custom Props Have Spaces
2 participants