Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
cfd4879
Fluent: style feedback buttons and form through the CSS module theme
Oct 30, 2026
4379c14
Fluent: style code blocks and the view code dialog through the CSS mo…
Oct 30, 2026
f6f25ba
Fluent: style the attachment bar and text area through the CSS module…
Oct 30, 2026
b75cc17
Fluent: style the transcript focus indicators through the CSS module …
Oct 30, 2026
392714b
Fluent: style the stacked layout, bubbles and carousel through the CS…
Oct 30, 2026
98b9a97
Fluent: style grouping, text, citations and Adaptive Cards through th…
Oct 30, 2026
36d197b
Give the activity button text a CSS module class, so Fluent styles it…
Oct 30, 2026
fb284c4
Declare lightningcss, which fluentCSSModuleOverrides.spec.ts imports,…
Oct 30, 2026
baed602
Check that Fluent lists every Web Chat local name its CSS modules use
Oct 30, 2026
6aeacbf
Keep class names of CSS module rules without styles through --webchat…
Oct 31, 2026
c310cf0
Move Fluent's rules for the feedback form and thumb buttons to overri…
Oct 31, 2026
fb0812f
Move Fluent's rules for code blocks to override modules
Oct 31, 2026
66028d0
Move Fluent's rules for the send box to override modules
Oct 31, 2026
4c7366a
Move Fluent's rules for the transcript focus to an override module
Oct 31, 2026
4ddeb96
Move Fluent's rules for activity layout to override modules
Oct 31, 2026
7736c88
Move Fluent's rules for part grouping to override modules
Oct 31, 2026
78b3ada
Move Fluent's rules for text and Markdown to override modules
Oct 31, 2026
4a79ead
Move Fluent's rules for Adaptive Cards and animated images to overrid…
Oct 31, 2026
518cd05
Drop the lists of Web Chat local names and pickCSSModule, now that ev…
Oct 31, 2026
ba8d210
Write the ButtonText system color in TitleCase in the activity button…
Oct 31, 2026
8a8dd78
Keep Fluent's scrollbar rules together in the code block content over…
Oct 31, 2026
4acd8cc
Fail the CSS check of the build when --webchat-preserve-reason reache…
Oct 31, 2026
fa74636
Run the second Lightning CSS pass only on the CSS of CSS modules, not…
Oct 31, 2026
1255369
Put every Fluent rule for Web Chat elements in one override CSS module
Oct 31, 2026
6f1fc06
Merge branch 'main' into OEvgeny/fix-css-fluent-context
OEvgeny Oct 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions esbuildPlugins.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { Buffer } from 'buffer';
import { transform } from 'lightningcss';
import { fileURLToPath } from 'url';
import lightningCssPlugin from 'unplugin-lightningcss/esbuild';

// A CSS module rule without styles of its own keeps its class name (e.g. for themes) with this declaration:
// Lightning CSS drops empty rules, and their class names with them.
// Once the class map is built, the declaration, and the rule if it becomes empty, are removed from the CSS.
const PRESERVE_REASON_PROPERTY = '--webchat-preserve-reason';

const removePreserveReasonVisitor = Object.freeze({
Declaration: Object.freeze({ custom: Object.freeze({ [PRESERVE_REASON_PROPERTY]: () => [] }) })
});

// Due to a bug in unplugin, we cannot use the Lightning CSS unplugin directly.
// https://github.com/unjs/unplugin/issues/546
// To workaround the bug, we are converting it back to esbuild plugin so we can apply a custom `filter`.
Expand All @@ -26,8 +37,25 @@ const cssPlugin = {
}
}).setup({
...build,
// eslint-disable-next-line require-unicode-regexp
onLoad: (_filter, fn) => build.onLoad({ filter: /(\.module_built\.css|\?css_module)$/ }, fn)
onLoad: (_filter, fn) =>
// eslint-disable-next-line require-unicode-regexp
build.onLoad({ filter: /(\.module_built\.css|\?css_module)$/ }, async args => {
const result = await fn(args);

// Only the CSS of a CSS module, not its JavaScript class map, and only if it has the declaration.
return args.path.endsWith('.module_built.css') &&
typeof result?.contents === 'string' &&
result.contents.includes(PRESERVE_REASON_PROPERTY)
? {
...result,
contents: transform({
Comment thread
OEvgeny marked this conversation as resolved.
Resolved
code: Buffer.from(result.contents),
filename: args.path,
visitor: removePreserveReasonVisitor
}).code.toString()
}
: result;
})
});
}
};
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@
"jest": "^29.7.0",
"jest-image-snapshot": "^6.5.2",
"keep-a-changelog": "^3.0.4",
"lightningcss": "^1.32.0",
"lint-staged": "^17.0.5",
"lolex": "^6.0.0",
"minimatch": "^10.2.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@
--webchat__component-icon--color: buttonText;
}
}

.activity-button__text {
--webchat-preserve-reason: target-class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const ActivityButton = forwardRef<HTMLButtonElement, ActivityButtonProps>((props
type="button"
>
{icon && <ComponentIcon appearance="text" className={classNames['activity-button__icon']} icon={icon} />}
{text && <span className="activity-button__text">{text}</span>}
{text && <span className={classNames['activity-button__text']}>{text}</span>}
{children}
</button>
);
Expand Down
Loading
Loading