Skip to content

Dbatiste/basic inputs dark mode#6788

Closed
dbatiste wants to merge 3 commits intomainfrom
dbatiste/basic-inputs-dark-mode
Closed

Dbatiste/basic inputs dark mode#6788
dbatiste wants to merge 3 commits intomainfrom
dbatiste/basic-inputs-dark-mode

Conversation

@dbatiste
Copy link
Copy Markdown
Contributor

@dbatiste dbatiste commented Apr 10, 2026

GAUD-9450

This PR:

  • Moves the colors into a JavaScript Map so we can do more with them
  • Provides a registerSemanticSvgVariable that enables the creation of semantic CSS background-image variables that use semantic colors
  • Updates basic inputs to use semantic variables

If there are no objections to doing this, I will proceed with updating select (which needs this) et al. for this PR.

Copy link
Copy Markdown
Contributor Author

@dbatiste dbatiste Apr 10, 2026

Choose a reason for hiding this comment

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

This one uses the mask-image technique. Note the vdiffs the result.

@github-actions
Copy link
Copy Markdown
Contributor

Thanks for the PR! 🎉

We've deployed an automatic preview for this PR - you can see your changes here:

URL https://live.d2l.dev/prs/BrightspaceUI/core/pr-6788/

Note

The build needs to finish before your changes are deployed.
Changes to the PR will automatically update the instance.

</svg>`);
</svg>`);

registerSemanticSvgVariable(
Copy link
Copy Markdown
Contributor Author

@dbatiste dbatiste Apr 10, 2026

Choose a reason for hiding this comment

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

registerSemanticSvgVariable creates this --d2l-input-invalid-icon CSS variable for each color mode. For each color mode, it replaces the semantic colors --d2l-theme-status-color-error and --d2l-theme-background-color-base that would normally work in inline SVGs with the resolved primitive HEX colors. As such, it updates just like the rest without rerendering.

The invalidIcon above would be removed once all usages (ex. our select styles) are updated to var(--d2l-input-invalid-icon).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What makes it so that the custom properties defined on the html element aren't available to the SVG -- is it the shadow DOM? I just did a really simple test and they seem available (without any custom elements).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's that they are background images. Custom CSS variables do indeed work just fine on inline SVGs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah ok gotcha!

Copy link
Copy Markdown
Contributor Author

@dbatiste dbatiste Apr 13, 2026

Choose a reason for hiding this comment

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

So it might be better named registerSvgImageUrlSemanticVariable or registerSemanticVariableForSvgImageUrl. 🤷‍♂️

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't have any qualms with the approach -- very clever!

Do you know roughly how many SVGs we'd be doing this to? Just wondering if it might be easier to just define these up with the palette with lightCss & darkCss as something like lightSvgImageUrls & darkSvgImageUrls? Then they'd end up in the same rule blocks as the other variables instead of creating a bunch of new ones. Definitely not a big deal though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I was thinking about that too. Maybe we'd be "ok" defining our core ones there.

I'm a little worried there are inevitably going to be some cases outside of core that want something special too, and we might have a hard time accepting those things into core. The AI buttons keep coming up, but I think there is a growing argument that it is becoming general enough to accept in core.

Worth noting that these rules are added to the same style element, albeit as new html { ... } blocks. Not sure if that makes much difference.

In any case, I'll poke around to see what else there is.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sounds good. Yeah like if we need to expose it as a utility that others can leverage, that's totally fine. Just wanted to make sure all that was needed though first, and that it's not just <5 cases within core.

Copy link
Copy Markdown
Contributor Author

@dbatiste dbatiste Apr 13, 2026

Choose a reason for hiding this comment

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

👍 . I've done some digging around for this:

There aren't that many cases in core - checkbox (check, indeterminate), radio (the dot), transparent color swatch, select styles, required icon (*). mask-image can sorta handle some of this, but not completely.

Outside of core - lots have their own copy of the invalid icon and the select chevron, and I think we should try to expose these to enable re-use. But there are quite a few others that I think would make this worthwhile.

Aside, some svgs, some pngs (😓). Some url encoded, some base-64 encoded. We at least have a relatively easy way to adapt the svgs. Had to decode some of them to figure out what they are for.

`;
const primitiveCSS = [...primitiveVariables.entries()].map(formatCSSVariable).join('\n');
const lightCSS = [...lightVariables.entries()].map(formatCSSVariable).join('\n');
const darkCSS = [...darkVariables.entries()].map(formatCSSVariable).join('\n');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The other option here would be to use the JavaScript API directly to set the variable values, although maybe that won't allow us to do different things based on an attribute selector...

export const inputStyles = css`
.d2l-input {
background-color: var(--d2l-input-background-color, #ffffff);
background-color: var(--d2l-input-background-color, var(--d2l-theme-background-color-base));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like rubrics is the only one setting --d2l-input-background-color... it'd be nice to be able to get rid of it somehow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I will look into that.

.d2l-input:${focusClass}:disabled,
[aria-invalid="true"].d2l-input:disabled {
border-color: var(--d2l-input-border-color, var(--d2l-color-galena));
border-color: var(--d2l-input-border-color, var(--d2l-theme-border-color-emphasized));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ugh, some places are consuming this and some places are setting it. For the places consuming it, we likely just want to switch them to use the semantic palette. Not sure what to do about the setters.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah. I will look into this as well. We have a section in the Confluence doc where we're keeping track of any overrides that needs to be cleaned up.

}

export function registerSemanticSvgVariable(name, value) {
if (!name || typeof value !== 'string') return;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could this just throw since we should be in control of all uses?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep it could.

</svg>`);
</svg>`);

registerSemanticSvgVariable(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What makes it so that the custom properties defined on the html element aren't available to the SVG -- is it the shadow DOM? I just did a really simple test and they seem available (without any custom elements).

@dbatiste
Copy link
Copy Markdown
Contributor Author

Closing this PR since I decided to break this up.

@dbatiste dbatiste closed this Apr 14, 2026
@dbatiste dbatiste deleted the dbatiste/basic-inputs-dark-mode branch April 15, 2026 13:52
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.

2 participants