Making My Logo a Component
After creating my logo, I wanted to turn it into a re-usable React component that would respond to theming, and let the logo variant be controllable by properties, so that essentially, I would only need one component that I could use wherever I wanted a logo
Variants
expanded | compact | compactSquare |
---|---|---|
Initially, I had one SVG for each variant, in the light and dark theme. I
imported all of them (about ten .SVG files) and used JavaScript logic
to choose between them. To apply my themes, I was using Docusaurus'
provided
ThemedImage
component.
That's where the trouble started.
import useBaseUrl from '@docusaurus/useBaseUrl';
import ThemedImage from '@theme/ThemedImage';
<ThemedImage
alt="Docusaurus themed image"
sources={{
light: useBaseUrl('/img/docusaurus_light.svg'),
dark: useBaseUrl('/img/docusaurus_dark.svg'),
}}
/>;
Those imports at the top are well and good in Docusaurus (and Storybook, it turns out) but when I tried to run my Storybook stories through Jest, those imports failed, sending me on a journey of redefining aliases and configuring preprocessors. I never did find the right combination of aliases definitions, and some of the docusaurus dependencies seem to rely on different paths for the same alias. It's entirely possible I'm misunderstanding what was going on, because I stopped trying to solve that problem before I ever licked it (and while I still had some hair left).
So, what I need then is a way to accomplish the same thing, but without any nested Docusaurus dependencies. I couldn't even programatically detect the theme, because that logic is in a React hook which is also defined in Docusaurus dependencies, and I really didn't want to reinvent that wheel.
It occurred to me that SVG files are stylable with CSS. I'd never done it before, and I wasn't sure how it would go with CSS Modules, but I figured it was worth a shot.
First I had to generalize all my SVG files by removing the "fill" attributes and replace them with 'data-fill' attributes, that I can use as selectors in my CSS:
<svg xmlns="http://www.w3.org/2000/svg" width="180" height="50" fill="none" viewBox="0 0 180 50">
<rect width="180" height="50" fill="#1F1F1F" rx="8"/>
<rect width="180" height="50" data-fill="background" rx="8"/>
<path fill="#1F1F1F" d="M10 9.76h130v30H10v-30Zm157 15a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z"/>
<path fill="#569CD6" fill-rule="evenodd" d="M8.5 8.26h133V23.5h9.599a8.001 8.001 0 1 1 .091 3h-9.69v14.76H8.5v-33Zm3 3v27h127v-27h-127ZM159 29.76a5 5 0 1 0 0-10 5 5 0 0 0 0 10Z" clip-rule="evenodd"/>
<path fill="#4EC9B0" d="M150.196 14.88c-.656 0-1.188-.228-1.596-.684-.4-.456-.6-1.068-.6-1.836v-1.788c0-.776.2-1.392.6-1.848.4-.456.932-.684 1.596-.684.544 0 .976.156 1.296.468.32.304.48.724.48 1.26l-.336-.348h.348l-.048-1.572V6h1.5v8.76h-1.464V13.5h-.336l.336-.348c0 .536-.16.96-.48 1.272-.32.304-.752.456-1.296.456Zm.528-1.296c.384 0 .68-.112.888-.336.216-.232.324-.552.324-.96v-1.656c0-.408-.108-.724-.324-.948-.208-.232-.504-.348-.888-.348s-.684.112-.9.336c-.216.224-.324.544-.324.96v1.656c0 .416.108.736.324.96.216.224.516.336.9.336Zm7.243 1.296c-.56 0-1.048-.108-1.464-.324a2.402 2.402 0 0 1-.972-.9c-.224-.392-.336-.848-.336-1.368v-1.656c0-.52.112-.972.336-1.356.232-.392.556-.696.972-.912.416-.216.904-.324 1.464-.324.552 0 1.032.108 1.44.324.416.216.736.52.96.912.232.384.348.836.348 1.356v1.188h-4.068v.468c0 .464.112.816.336 1.056.224.232.556.348.996.348.336 0 .608-.056.816-.168a.801.801 0 0 0 .396-.516h1.476c-.112.568-.416 1.024-.912 1.368-.488.336-1.084.504-1.788.504Zm1.296-3.9v-.36c0-.456-.108-.804-.324-1.044-.216-.248-.54-.372-.972-.372-.432 0-.76.124-.984.372-.224.248-.336.6-.336 1.056v.252l2.724-.024-.108.12Zm4.928 3.78-2.172-6.6h1.536l1.26 4.008c.072.24.14.488.204.744.072.256.124.46.156.612.04-.152.092-.356.156-.612s.128-.5.192-.732l1.236-4.02h1.524l-2.16 6.6h-1.932Z"/>
<path fill="#CE9178" d="M19.89 32.76v-2.31h3.087V19.74H19.89v-2.31h8.82v2.31h-3.087v10.71h3.087v2.31h-8.82Zm15.72.21c-1.19 0-2.127-.315-2.813-.945-.686-.63-1.03-1.477-1.03-2.541 0-1.134.379-2.009 1.135-2.625.756-.616 1.827-.924 3.213-.924h2.877v-.987c0-.56-.182-.994-.546-1.302-.364-.322-.861-.483-1.491-.483-.574 0-1.05.126-1.428.378a1.476 1.476 0 0 0-.672 1.029h-2.562c.126-1.092.616-1.96 1.47-2.604.854-.644 1.946-.966 3.276-.966 1.414 0 2.527.357 3.339 1.071.826.7 1.239 1.652 1.239 2.856v7.833h-2.541v-2.016h-.42l.42-.567c0 .854-.315 1.533-.945 2.037-.63.504-1.47.756-2.52.756Zm.862-1.974c.742 0 1.344-.189 1.806-.567.476-.378.714-.868.714-1.47v-1.407h-2.835c-.532 0-.96.154-1.281.462-.322.308-.483.714-.483 1.218 0 .546.182.98.546 1.302.378.308.889.462 1.533.462Zm8.308 1.764v-2.394h4.032v-6.783h-3.507V21.21h6.027v9.156h3.57v2.394H44.78Zm5.082-13.482c-.532 0-.952-.133-1.26-.399-.308-.28-.462-.651-.462-1.113 0-.462.154-.826.462-1.092.308-.28.728-.42 1.26-.42s.952.14 1.26.42c.308.266.462.63.462 1.092 0 .462-.154.833-.462 1.113-.308.266-.728.399-1.26.399Zm7.53 13.482V21.21h2.562v2.205h.714l-.714.609c0-.952.273-1.694.82-2.226.56-.532 1.322-.798 2.288-.798 1.134 0 2.037.378 2.71 1.134.685.756 1.028 1.771 1.028 3.045v7.581h-2.625v-7.308c0-.7-.182-1.239-.546-1.617-.364-.378-.875-.567-1.533-.567-.644 0-1.155.196-1.533.588-.364.392-.546.952-.546 1.68v7.224h-2.625Zm12.55 0V17.43H74.5c1.036 0 1.932.196 2.688.588.77.392 1.365.945 1.785 1.659.42.714.63 1.561.63 2.541v5.733c0 .966-.21 1.813-.63 2.541a4.401 4.401 0 0 1-1.785 1.68c-.756.392-1.652.588-2.688.588h-4.557Zm2.625-2.415H74.5c.756 0 1.358-.21 1.806-.63.448-.434.672-1.022.672-1.764v-5.733c0-.728-.224-1.302-.672-1.722-.448-.434-1.05-.651-1.806-.651h-1.932v10.5Zm13.411 2.625c-1.19 0-2.128-.315-2.814-.945-.686-.63-1.029-1.477-1.029-2.541 0-1.134.378-2.009 1.134-2.625.756-.616 1.827-.924 3.213-.924h2.877v-.987c0-.56-.182-.994-.546-1.302-.364-.322-.861-.483-1.491-.483-.574 0-1.05.126-1.428.378a1.476 1.476 0 0 0-.672 1.029H82.66c.126-1.092.616-1.96 1.47-2.604.854-.644 1.946-.966 3.276-.966 1.414 0 2.527.357 3.339 1.071.826.7 1.239 1.652 1.239 2.856v7.833h-2.541v-2.016h-.42l.42-.567c0 .854-.315 1.533-.945 2.037-.63.504-1.47.756-2.52.756Zm.861-1.974c.742 0 1.344-.189 1.806-.567.476-.378.714-.868.714-1.47v-1.407h-2.835c-.532 0-.959.154-1.281.462-.322.308-.483.714-.483 1.218 0 .546.182.98.546 1.302.378.308.889.462 1.533.462ZM98.17 32.76l-3.8-11.55h2.688l2.205 7.014c.126.42.245.854.357 1.302.126.448.217.805.273 1.071.07-.266.161-.623.273-1.071.112-.448.224-.875.336-1.281l2.163-7.035h2.667l-3.78 11.55h-3.381Zm9.569 0v-2.394h4.032v-6.783h-3.507V21.21h6.027v9.156h3.57v2.394h-10.122Zm5.082-13.482c-.532 0-.952-.133-1.26-.399-.308-.28-.462-.651-.462-1.113 0-.462.154-.826.462-1.092.308-.28.728-.42 1.26-.42s.952.14 1.26.42c.308.266.462.63.462 1.092 0 .462-.154.833-.462 1.113-.308.266-.728.399-1.26.399Zm11.772 13.671c-.882 0-1.652-.14-2.31-.42-.658-.28-1.176-.665-1.554-1.155-.364-.504-.56-1.092-.588-1.764h2.625c.028.364.203.658.525.882.336.224.77.336 1.302.336h.924c.644 0 1.127-.126 1.449-.378.322-.252.483-.595.483-1.029 0-.406-.147-.721-.441-.945-.28-.238-.721-.392-1.323-.462l-1.428-.21c-1.316-.182-2.282-.532-2.898-1.05-.616-.518-.924-1.295-.924-2.331 0-1.078.364-1.911 1.092-2.499.728-.602 1.799-.903 3.213-.903h.798c1.288 0 2.317.287 3.087.861.77.574 1.183 1.344 1.239 2.31h-2.625c-.042-.308-.217-.56-.525-.756-.294-.196-.686-.294-1.176-.294h-.798c-.602 0-1.043.112-1.323.336-.266.21-.399.525-.399.945 0 .392.119.686.357.882.238.182.623.315 1.155.399l1.491.21c1.372.196 2.38.567 3.024 1.113.658.532.987 1.323.987 2.373 0 1.12-.385 1.995-1.155 2.625-.756.616-1.876.924-3.36.924h-.924Z"/>
<path data-fill="background" d="M10 9.76h130v30H10v-30Zm157 15a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z"/>
<path data-fill="border" fill-rule="evenodd" d="M8.5 8.26h133V23.5h9.599a8.001 8.001 0 1 1 .091 3h-9.69v14.76H8.5v-33Zm3 3v27h127v-27h-127ZM159 29.76a5 5 0 1 0 0-10 5 5 0 0 0 0 10Z" clip-rule="evenodd"/>
<path data-fill="text-accent" d="M150.196 14.88c-.656 0-1.188-.228-1.596-.684-.4-.456-.6-1.068-.6-1.836v-1.788c0-.776.2-1.392.6-1.848.4-.456.932-.684 1.596-.684.544 0 .976.156 1.296.468.32.304.48.724.48 1.26l-.336-.348h.348l-.048-1.572V6h1.5v8.76h-1.464V13.5h-.336l.336-.348c0 .536-.16.96-.48 1.272-.32.304-.752.456-1.296.456Zm.528-1.296c.384 0 .68-.112.888-.336.216-.232.324-.552.324-.96v-1.656c0-.408-.108-.724-.324-.948-.208-.232-.504-.348-.888-.348s-.684.112-.9.336c-.216.224-.324.544-.324.96v1.656c0 .416.108.736.324.96.216.224.516.336.9.336Zm7.243 1.296c-.56 0-1.048-.108-1.464-.324a2.402 2.402 0 0 1-.972-.9c-.224-.392-.336-.848-.336-1.368v-1.656c0-.52.112-.972.336-1.356.232-.392.556-.696.972-.912.416-.216.904-.324 1.464-.324.552 0 1.032.108 1.44.324.416.216.736.52.96.912.232.384.348.836.348 1.356v1.188h-4.068v.468c0 .464.112.816.336 1.056.224.232.556.348.996.348.336 0 .608-.056.816-.168a.801.801 0 0 0 .396-.516h1.476c-.112.568-.416 1.024-.912 1.368-.488.336-1.084.504-1.788.504Zm1.296-3.9v-.36c0-.456-.108-.804-.324-1.044-.216-.248-.54-.372-.972-.372-.432 0-.76.124-.984.372-.224.248-.336.6-.336 1.056v.252l2.724-.024-.108.12Zm4.928 3.78-2.172-6.6h1.536l1.26 4.008c.072.24.14.488.204.744.072.256.124.46.156.612.04-.152.092-.356.156-.612s.128-.5.192-.732l1.236-4.02h1.524l-2.16 6.6h-1.932Z"/>
<path data-fill="text-main" d="M19.89 32.76v-2.31h3.087V19.74H19.89v-2.31h8.82v2.31h-3.087v10.71h3.087v2.31h-8.82Zm15.72.21c-1.19 0-2.127-.315-2.813-.945-.686-.63-1.03-1.477-1.03-2.541 0-1.134.379-2.009 1.135-2.625.756-.616 1.827-.924 3.213-.924h2.877v-.987c0-.56-.182-.994-.546-1.302-.364-.322-.861-.483-1.491-.483-.574 0-1.05.126-1.428.378a1.476 1.476 0 0 0-.672 1.029h-2.562c.126-1.092.616-1.96 1.47-2.604.854-.644 1.946-.966 3.276-.966 1.414 0 2.527.357 3.339 1.071.826.7 1.239 1.652 1.239 2.856v7.833h-2.541v-2.016h-.42l.42-.567c0 .854-.315 1.533-.945 2.037-.63.504-1.47.756-2.52.756Zm.862-1.974c.742 0 1.344-.189 1.806-.567.476-.378.714-.868.714-1.47v-1.407h-2.835c-.532 0-.96.154-1.281.462-.322.308-.483.714-.483 1.218 0 .546.182.98.546 1.302.378.308.889.462 1.533.462Zm8.308 1.764v-2.394h4.032v-6.783h-3.507V21.21h6.027v9.156h3.57v2.394H44.78Zm5.082-13.482c-.532 0-.952-.133-1.26-.399-.308-.28-.462-.651-.462-1.113 0-.462.154-.826.462-1.092.308-.28.728-.42 1.26-.42s.952.14 1.26.42c.308.266.462.63.462 1.092 0 .462-.154.833-.462 1.113-.308.266-.728.399-1.26.399Zm7.53 13.482V21.21h2.562v2.205h.714l-.714.609c0-.952.273-1.694.82-2.226.56-.532 1.322-.798 2.288-.798 1.134 0 2.037.378 2.71 1.134.685.756 1.028 1.771 1.028 3.045v7.581h-2.625v-7.308c0-.7-.182-1.239-.546-1.617-.364-.378-.875-.567-1.533-.567-.644 0-1.155.196-1.533.588-.364.392-.546.952-.546 1.68v7.224h-2.625Zm12.55 0V17.43H74.5c1.036 0 1.932.196 2.688.588.77.392 1.365.945 1.785 1.659.42.714.63 1.561.63 2.541v5.733c0 .966-.21 1.813-.63 2.541a4.401 4.401 0 0 1-1.785 1.68c-.756.392-1.652.588-2.688.588h-4.557Zm2.625-2.415H74.5c.756 0 1.358-.21 1.806-.63.448-.434.672-1.022.672-1.764v-5.733c0-.728-.224-1.302-.672-1.722-.448-.434-1.05-.651-1.806-.651h-1.932v10.5Zm13.411 2.625c-1.19 0-2.128-.315-2.814-.945-.686-.63-1.029-1.477-1.029-2.541 0-1.134.378-2.009 1.134-2.625.756-.616 1.827-.924 3.213-.924h2.877v-.987c0-.56-.182-.994-.546-1.302-.364-.322-.861-.483-1.491-.483-.574 0-1.05.126-1.428.378a1.476 1.476 0 0 0-.672 1.029H82.66c.126-1.092.616-1.96 1.47-2.604.854-.644 1.946-.966 3.276-.966 1.414 0 2.527.357 3.339 1.071.826.7 1.239 1.652 1.239 2.856v7.833h-2.541v-2.016h-.42l.42-.567c0 .854-.315 1.533-.945 2.037-.63.504-1.47.756-2.52.756Zm.861-1.974c.742 0 1.344-.189 1.806-.567.476-.378.714-.868.714-1.47v-1.407h-2.835c-.532 0-.959.154-1.281.462-.322.308-.483.714-.483 1.218 0 .546.182.98.546 1.302.378.308.889.462 1.533.462ZM98.17 32.76l-3.8-11.55h2.688l2.205 7.014c.126.42.245.854.357 1.302.126.448.217.805.273 1.071.07-.266.161-.623.273-1.071.112-.448.224-.875.336-1.281l2.163-7.035h2.667l-3.78 11.55h-3.381Zm9.569 0v-2.394h4.032v-6.783h-3.507V21.21h6.027v9.156h3.57v2.394h-10.122Zm5.082-13.482c-.532 0-.952-.133-1.26-.399-.308-.28-.462-.651-.462-1.113 0-.462.154-.826.462-1.092.308-.28.728-.42 1.26-.42s.952.14 1.26.42c.308.266.462.63.462 1.092 0 .462-.154.833-.462 1.113-.308.266-.728.399-1.26.399Zm11.772 13.671c-.882 0-1.652-.14-2.31-.42-.658-.28-1.176-.665-1.554-1.155-.364-.504-.56-1.092-.588-1.764h2.625c.028.364.203.658.525.882.336.224.77.336 1.302.336h.924c.644 0 1.127-.126 1.449-.378.322-.252.483-.595.483-1.029 0-.406-.147-.721-.441-.945-.28-.238-.721-.392-1.323-.462l-1.428-.21c-1.316-.182-2.282-.532-2.898-1.05-.616-.518-.924-1.295-.924-2.331 0-1.078.364-1.911 1.092-2.499.728-.602 1.799-.903 3.213-.903h.798c1.288 0 2.317.287 3.087.861.77.574 1.183 1.344 1.239 2.31h-2.625c-.042-.308-.217-.56-.525-.756-.294-.196-.686-.294-1.176-.294h-.798c-.602 0-1.043.112-1.323.336-.266.21-.399.525-.399.945 0 .392.119.686.357.882.238.182.623.315 1.155.399l1.491.21c1.372.196 2.38.567 3.024 1.113.658.532.987 1.323.987 2.373 0 1.12-.385 1.995-1.155 2.625-.756.616-1.876.924-3.36.924h-.924Z"/>
</svg>
Then I had to create my CSS module for the logo component:
:root,
[data-theme='light'] {
--color-logo-background: #FDF6E3;
--color-logo-border: #B58900;
--color-logo-text-main: #2AA198;
--color-logo-text-accent: #CB4B16;
}
[data-theme='dark'] {
--color-logo-background: #1F1F1F;
--color-logo-text-accent: #4EC9B0;
--color-logo-text-main: #CE9178;
--color-logo-border: #569CD6;
}
[data-fill="background"] {
fill: var(--color-logo-background);
}
[data-fill="text-main"] {
fill: var(--color-logo-text-main);
}
[data-fill="text-accent"]{
fill: var(--color-logo-text-accent);
}
[data-fill="border"]{
fill: var(--color-logo-border);
}
and it worked straight away!
At the moment, I still have a dependency on the original .svg files in a couple of places: the favicon for sure. And the navbar expects a file path, instead of a React component. But there is a work-around for that that I've used before when I was working on a project with OAuth login and I wanted to include a login-state component in the navbar. I'll probably re-implement that eventually, and then I can strip down the number of files I'm managing for my logo from something like thirty down to six. I may try to figure out later how to make the back-plate element responsive to styles too, and then I can get that number down even further.
And the resulting React component is more portable, because it has no dependencies on things that are in supplementary Docusaurus addons. And if the time comes I want a variation in different colors, all I have to do is define new CSS variables to get it.