diff --git a/CHANGELOG.md b/CHANGELOG.md
index c4d332cb..00e19cd3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## 0.10.0 - 2025-06-16
+
+### Added
+
+- GetCssCompletions parameter to inject additional variable and class name completins to CSS
+
## 0.9.2 - 2025-02-26
### ⬆️ Upgrade dependencies
diff --git a/CodeMirror6/CodeMirror6.csproj b/CodeMirror6/CodeMirror6.csproj
index 5394933f..efa1be0d 100644
--- a/CodeMirror6/CodeMirror6.csproj
+++ b/CodeMirror6/CodeMirror6.csproj
@@ -9,7 +9,7 @@
GaelJ.BlazorCodeMirror6
true
GaelJ.BlazorCodeMirror6
- 0.9.2
+ 0.10.0
true
snupkg
true
diff --git a/CodeMirror6/CodeMirror6Wrapper.razor b/CodeMirror6/CodeMirror6Wrapper.razor
index 2a5e6875..63eb2ff6 100644
--- a/CodeMirror6/CodeMirror6Wrapper.razor
+++ b/CodeMirror6/CodeMirror6Wrapper.razor
@@ -13,6 +13,7 @@
Editable="@Editable"
FocusChanged="@FocusChanged"
GetMentionCompletions="@GetMentionCompletions"
+ GetCssCompletions="@GetCssCompletions"
IndentationUnit="@IndentationUnit"
Language="@Language"
LineWrapping="@LineWrapping"
diff --git a/CodeMirror6/CodeMirror6Wrapper.razor.cs b/CodeMirror6/CodeMirror6Wrapper.razor.cs
index de511a07..101c7692 100644
--- a/CodeMirror6/CodeMirror6Wrapper.razor.cs
+++ b/CodeMirror6/CodeMirror6Wrapper.razor.cs
@@ -107,6 +107,12 @@ public partial class CodeMirror6Wrapper : ComponentBase
/// Get all users available for @user mention completions
///
[Parameter] public Func>>? GetMentionCompletions { get; set; }
+
+ ///
+ /// Gets a list of additional variables and class names available for autocomplete in CSS documents.
+ ///
+ [Parameter] public Func>>? GetCssCompletions { get; set; }
+
///
/// Upload an IBrowserFile to a server and returns the URL to the file
///
diff --git a/CodeMirror6/CodeMirror6WrapperInternal.razor.cs b/CodeMirror6/CodeMirror6WrapperInternal.razor.cs
index f4eeeeb0..7f4517ed 100644
--- a/CodeMirror6/CodeMirror6WrapperInternal.razor.cs
+++ b/CodeMirror6/CodeMirror6WrapperInternal.razor.cs
@@ -111,6 +111,12 @@ public partial class CodeMirror6WrapperInternal : ComponentBase, IAsyncDisposabl
/// Get all users available for @user mention completions
///
[Parameter] public Func>>? GetMentionCompletions { get; set; }
+
+ ///
+ /// Gets a list of additional variables and class names available for autocomplete in CSS documents.
+ ///
+ [Parameter] public Func>>? GetCssCompletions { get; set; }
+
///
/// Upload an IBrowserFile to a server and returns the URL to the file
///
@@ -367,6 +373,14 @@ private async Task InitializeJsInterop()
if (token.IsCancellationRequested) return;
if (!await CmJsInterop.PropertySetters.SetMentionCompletions(mentionCompletions)) return;
}
+
+ if (GetCssCompletions is not null) {
+ var cssCompletions = await GetCssCompletions();
+ if (token.IsCancellationRequested) return;
+ if (!await CmJsInterop.PropertySetters.SetCssCompletions(cssCompletions)) return;
+ }
+
+
if (token.IsCancellationRequested) return;
IsCodeMirrorInitialized = true;
await InvokeAsync(StateHasChanged);
diff --git a/CodeMirror6/Commands/CMConfigurationSetters.cs b/CodeMirror6/Commands/CMConfigurationSetters.cs
index cd63f065..5a83f318 100644
--- a/CodeMirror6/Commands/CMConfigurationSetters.cs
+++ b/CodeMirror6/Commands/CMConfigurationSetters.cs
@@ -29,6 +29,11 @@ internal Task SetMentionCompletions(List mentionComp
mentionCompletions
);
+ internal Task SetCssCompletions(List cssCompletions) => cmJsInterop.ModuleInvokeVoidAsync(
+ "setCssCompletions",
+ cssCompletions
+ );
+
internal Task ForceRedraw() => cmJsInterop.ModuleInvokeVoidAsync(
"forceRedraw"
);
diff --git a/CodeMirror6/NodeLib/src/CmCssCompletion.ts b/CodeMirror6/NodeLib/src/CmCssCompletion.ts
new file mode 100644
index 00000000..012f4b36
--- /dev/null
+++ b/CodeMirror6/NodeLib/src/CmCssCompletion.ts
@@ -0,0 +1,61 @@
+import { Completion, CompletionContext, CompletionSource, autocompletion } from "@codemirror/autocomplete"
+import { cssCompletionSource } from "@codemirror/lang-css";
+import { syntaxTree } from "@codemirror/language";
+
+let cachedCssVariableCompletions: Completion[] = []
+let cachedCssClassNameCompletions: Completion[] = []
+
+function createCssCompletionsSource(): CompletionSource {
+ return async (context: CompletionContext) => {
+
+
+ let defaultResult = await cssCompletionSource(context);
+ let res;
+ let from;
+ let match;
+
+ var node = syntaxTree(context.state).resolveInner(context.pos, -1);
+ console.log("Node type: ", node.type.name, " at pos: ", context.pos, " from: ", node.from, " to: ", node.to);
+
+ if (node.type.name == "VariableName" ) {
+ res = cachedCssVariableCompletions;
+ from = node.from;
+ } else if (node.type.name == "ClassSelector") {
+ res = cachedCssClassNameCompletions;
+ from = context.pos - 1;//node.from;
+ } else if (node.type.name == "ClassName") {
+ res = cachedCssClassNameCompletions;
+ from = node.from-1;
+ }
+ else if (match = context.matchBefore(/(?<=var\(\s*)-(-)?\w*/)) //this one was necessary because it sometimes bugs out and doesn't report VariableName when typing var(-
+ {
+ res = cachedCssVariableCompletions;
+ from = match.from;
+ }
+ else {
+ return defaultResult;
+ }
+
+ if (defaultResult && defaultResult.options) {
+ res = [...res, ...defaultResult.options];
+ }
+
+ return {
+ from: from,
+ to: context.pos,
+ options: res,
+ filter: true,
+ validFor: defaultResult ? defaultResult.validFor : undefined
+ };
+ };
+}
+
+export function setCachedCssCompletions(completions: Completion[]) {
+ cachedCssVariableCompletions = completions.filter(c => c.label.startsWith('--'));
+ cachedCssClassNameCompletions = completions.filter(c => c.label.startsWith('.')); // filter for class names
+}
+
+export const cssCompletionExtension = (enabled: boolean) => {
+ if (!enabled) return []
+ return [createCssCompletionsSource()]
+}
diff --git a/CodeMirror6/NodeLib/src/index.ts b/CodeMirror6/NodeLib/src/index.ts
index 49895713..3952f7d0 100644
--- a/CodeMirror6/NodeLib/src/index.ts
+++ b/CodeMirror6/NodeLib/src/index.ts
@@ -45,6 +45,7 @@ import { blockquote } from "./CmBlockquote"
import { listsExtension } from "./CmLists"
import { dynamicHrExtension } from "./CmHorizontalRule"
import { mentionCompletionExtension, setCachedCompletions } from "./CmMentionsCompletion"
+import { cssCompletionExtension, setCachedCssCompletions } from "./CmCssCompletion"
import { mentionDecorationExtension } from "./CmMentionsView"
import { viewEmojiExtension } from "./CmEmojiView"
import { emojiCompletionExtension } from "./CmEmojiCompletion"
@@ -200,6 +201,13 @@ export async function initCodeMirror(
extensions.push(...getFileUploadExtensions(id, setup))
+
+ if (setup.autocompletion === true && initialConfig.languageName === "CSS") {
+ extensions.push(autocompletion({
+ override: [...cssCompletionExtension(true)]
+ }))
+ }
+
const pasteHandler = EditorView.domEventHandlers({
paste(event: ClipboardEvent, view: EditorView) {
const transfer = event.clipboardData
@@ -469,6 +477,11 @@ export function setMentionCompletions(id: string, mentionCompletions: Completion
forceRedraw(id)
}
+export function setCssCompletions(id: string, cssCompletions: Completion[]) {
+ setCachedCssCompletions(cssCompletions)
+ forceRedraw(id)
+}
+
export function forceRedraw(id: string) {
const view = CMInstances[id].view
if (!view) {
diff --git a/Examples.BlazorServer/Examples.BlazorServer.csproj b/Examples.BlazorServer/Examples.BlazorServer.csproj
index 437ca8e3..64a00634 100644
--- a/Examples.BlazorServer/Examples.BlazorServer.csproj
+++ b/Examples.BlazorServer/Examples.BlazorServer.csproj
@@ -4,7 +4,7 @@
enable
false
enable
- 0.9.2
+ 0.10.0
diff --git a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
index 63820733..3fd6101a 100644
--- a/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
+++ b/Examples.BlazorServerInteractive/Examples.BlazorServerInteractive.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.9.2
+ 0.10.0
diff --git a/Examples.BlazorWasm/Examples.BlazorWasm.csproj b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
index 0df8de19..3d589dae 100644
--- a/Examples.BlazorWasm/Examples.BlazorWasm.csproj
+++ b/Examples.BlazorWasm/Examples.BlazorWasm.csproj
@@ -4,7 +4,7 @@
enable
enable
false
- 0.9.2
+ 0.10.0
diff --git a/Examples.Common/Examples.Common.csproj b/Examples.Common/Examples.Common.csproj
index 820b7b82..ae641ff5 100644
--- a/Examples.Common/Examples.Common.csproj
+++ b/Examples.Common/Examples.Common.csproj
@@ -5,7 +5,7 @@
enable
enable
false
- 0.9.2
+ 0.10.0
diff --git a/NEW_CHANGELOG.md b/NEW_CHANGELOG.md
index ff78bc12..47b7303d 100644
--- a/NEW_CHANGELOG.md
+++ b/NEW_CHANGELOG.md
@@ -1,11 +1,3 @@
-### ⬆️ Upgrade dependencies
+### Added
-- Update nuget packages
-
-### 🐛 Fix a bug
-
-- Fix logs not in color
-
-### 🗑️ Deprecate code that needs to be cleaned up
-
-- Explicitly loading BlazorCodeMirror6.bundle.scp.css is unneeded and broken (#210)
+- GetCssCompletions parameter to inject additional variable and class name completins to CSS