{"id":16283003,"url":"https://github.com/angelmunoz/fable.shadowstyles","last_synced_at":"2025-06-27T00:36:22.491Z","repository":{"id":87151985,"uuid":"401493585","full_name":"AngelMunoz/Fable.ShadowStyles","owner":"AngelMunoz","description":"Type Safe CSS for FSharp, a wrapper over https://developers.google.com/web/updates/2019/02/constructable-stylesheets","archived":false,"fork":false,"pushed_at":"2024-09-22T13:52:42.000Z","size":169,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-22T14:12:01.941Z","etag":null,"topics":["constructable-stylesheets","css","fable","fsharp","library"],"latest_commit_sha":null,"homepage":"","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AngelMunoz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-30T21:41:33.000Z","updated_at":"2024-09-22T13:52:45.000Z","dependencies_parsed_at":"2024-10-27T21:41:36.144Z","dependency_job_id":"ecbdf18c-a7f9-4013-a556-3eb03e390b25","html_url":"https://github.com/AngelMunoz/Fable.ShadowStyles","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AngelMunoz/Fable.ShadowStyles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FFable.ShadowStyles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FFable.ShadowStyles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FFable.ShadowStyles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FFable.ShadowStyles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AngelMunoz","download_url":"https://codeload.github.com/AngelMunoz/Fable.ShadowStyles/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FFable.ShadowStyles/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262166194,"owners_count":23268998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["constructable-stylesheets","css","fable","fsharp","library"],"created_at":"2024-10-10T19:12:16.416Z","updated_at":"2025-06-27T00:36:22.461Z","avatar_url":"https://github.com/AngelMunoz.png","language":"F#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ShadowStyles\n\n[fable.haunted]: https://github.com/AngelMunoz/Fable.Haunted\n[lit-html]: https://github.com/alfonsogarciacaro/Fable.Lit\n[sutil]: https://github.com/davedawkins/Sutil\n[css in js]: https://medium.com/dailyjs/what-is-actually-css-in-js-f2f529a2757\n[feliz.engine]: https://github.com/alfonsogarciacaro/Feliz.Engine\n[constructable stylesheets]: https://developers.google.com/web/updates/2019/02/constructable-stylesheets\n\n\u003e Powered by [Feliz.Engine]\n\nShadow Styles is a [constructable stylesheets] F# wrapper that enables you to add styles to your Fable apps that generate Custom Elements or even Web components like [lit-html] + [Fable.Haunted] and in the future [Sutil] + [Fable.Haunted].\n\n# CSS in F#\n\nconstructable stylesheets (along with css module imports spec) try to solve the [css in js] dilema, while shadow DOM solves encapsulation, it makes it hard to share styles hence why we'd like to use something like constructable stylesheets\n\n# Usage Example\n\nHere we'll use [Fable.Haunted] and [lit-html] to define a web component (i.e a custom element with a shadow root)\nwe'll add a stylesheet to the current document and a local stylesheet to the `flit-app` web component\n\n\u003e **_NOTE_**: For Safari and Firefox a polyfill is required\n\u003e\n\u003e ```html\n\u003e \u003cscript src=\"https://unpkg.com/construct-style-sheets-polyfill\"\u003e\u003c/script\u003e\n\u003e ```\n\n```fsharp\nmodule Main\n\nopen Browser.Dom\nopen Lit\nopen Haunted\nopen Fable.Core.JsInterop\n\nopen ShadowStyles\nopen ShadowStyles.Types\nopen ShadowStyles.Operators\n\n// note we use SCss to prevent colisions with things like Fable.Lit Css\n\nlet globalStyles =\n  [ \"html, body\"\n    =\u003e [ SCss.padding 0\n         SCss.margin 0\n         SCss.fontFamily\n           \"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif\" ]\n    \"body\" =\u003e [ SCss.color \"blue\" ] ]\n\n/// the `=\u003e` operator is a proxy for: `CSSRule(selector, cssPropertySequence)`\n\n// these get applied to the whole document (false means we're not using shadowDOM)\nShadowStyles.adoptStyleSheet (document, globalStyles, false)\n\nlet myComponent () =\n  // with Haunted, the functions are binded to the HTML element they are assigned\n  let host = jsThis\n  // which helps us get a reference to the element's shadow root\n\n  let localStyles =\n    // while classes are not required because inside\n    // shadow DOM element styles are isolated\n    // we'll use it for ilustration purposes\n    [ \".my-rule\"\n      =\u003e [ SCss.displayFlex\n           SCss.alignContentCenter\n           SCss.color \"red\" ] ]\n\n  // the following function call applies multiple (and local) styles to the host even in shadowDOM\n  // let existingGlobalStyles = document?adoptedStyleSheets\n  // ShadowStyles.adoptStyleSheets (host, existingGlobalStyles, localStyles)\n\n  // this applies a single style to the host in shadowDOM\n  ShadowStyles.adoptStyleSheet (host, localStyles)\n\n  html\n    $\"\"\"\n    \u003cdiv class=\"my-rule\"\u003e\n      \u003ch1\u003eHello, World!\u003c/h1\u003e\n    \u003c/div\u003e\n  \"\"\"\n\ndefineComponent\n  \"flit-app\"\n  (Haunted.Component(myComponent, {| useShadowDOM = true |}))\n```\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003ctitle\u003eLit + Fable Template\u003c/title\u003e\n    \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /\u003e\n    \u003clink rel=\"shortcut icon\" href=\"fable.ico\" /\u003e\n    \u003c!-- The polyfill is required for Safari and Firefox untill they enable the feature natively\n        blink browsers already support this natively (chrome, edge, opera, etc...) --\u003e\n    \u003cscript src=\"https://unpkg.com/construct-style-sheets-polyfill\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cdiv\u003eoutside flit-app!\u003c/div\u003e\n    \u003cflit-app\u003e\u003c/flit-app\u003e\n    \u003cscript type=\"module\" src=\"/dist/Main.fs.js\"\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangelmunoz%2Ffable.shadowstyles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangelmunoz%2Ffable.shadowstyles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangelmunoz%2Ffable.shadowstyles/lists"}