-
Notifications
You must be signed in to change notification settings - Fork 0
Description
The CSS Modules repo suggests handling theming like this. I tried to use a similar approach with this library but ran into a typing issue.
Given an Elmish component like this in a component library:
module MyLib.MyComponent
open Fable.Core.JsInterop
open Feliz
let private classes: CssModules.MyComponent = import "default" "./MyComponent.module.scss"
type State = { Text: string; Theme: option }
let render (state: State) dispatch =
let theme = Option.defaultValue classes state.Theme
Html.div [
prop.classes [ theme.myClass ]
prop.children [ prop.text state.Text ]
]
Trying to pass a different generated CSS module from a consuming app (expectedly) results in a different interface type:
module MyApp.ConsumingComponent
open Fable.Core.JsInterop
open Feliz
let private myComponentTheme: CssModules.MyCustomComponent = import "default" "./MyCustomComponent.module.scss"
let render (state: State) dispatch =
MyLib.MyComponent.render ({ Text: "MyString"; Theme = Some myComponentTheme }) dispatch // Error; Type mismatch
Since import
is not strongly typed, I could change the type of myComponentTheme
to MyLib.CssModules.MyComponent
to work around the error. However, this does not force the CSS module to actually define the interface members at compile time.
Do you have any thoughts on how to approach this problem? Perhaps there should be a way to define an interface the CSS module needs to implement, then the generated file would fail to compile if the implementing type did not contain the appropriate members. For example:
[<RequireQualifiedAccess>]
module CssModules
open Fable.Core
[<AbstractClass>]
type MyCustomComponent =
/// <summary>
/// Binding for <c>someOtherClass</c> class
/// </summary>
[<Emit("$0[\"someOtherClass\"]")>]
abstract someOtherClass: string;
interface MyLib.CssModules.MyComponent with
member x.myClass = x.myClass // Error; MyCustomComponent missing myClass member
As for how to indicate the interface that needs to be implemented... I'm not sure. I suppose there would have to be some sort of directive in the CSS file. fable-css-modules
would also have to have context about the referenced libraries to discover the interface members, which I'm not sure is a simple task. Perhaps I'm overthinking this.