11import "../index.css" ;
22import React from "react" ;
33import { UiDependencyProvider } from "@apify/ui-library" ;
4- import { tokens as lightCssVariables } from "@apify/ui-library/dist/src/design_system/colors/generated/css_variables.light.js" ;
5- import { tokens as darkCssVariables } from "@apify/ui-library/dist/src/design_system/colors/generated/css_variables.dark.js" ;
4+ import { cssColorsVariablesLight , cssColorsVariablesDark } from "@apify/ui-library" ;
65import { ThemeProvider } from "styled-components" ;
76import { createRoot } from "react-dom/client" ;
87
@@ -18,6 +17,68 @@ function applyTheme(theme: "light" | "dark") {
1817 document . documentElement . classList . toggle ( "dark" , theme === "dark" ) ;
1918}
2019
20+ /**
21+ * Helper to create and inject a link or style element if it doesn't already exist.
22+ */
23+ function injectElement < K extends "link" | "style" > (
24+ id : string ,
25+ tagName : K ,
26+ attributes : Partial < HTMLLinkElement | HTMLStyleElement >
27+ ) : void {
28+ if ( document . getElementById ( id ) ) {
29+ return ;
30+ }
31+
32+ const element = document . createElement ( tagName ) ;
33+ element . id = id ;
34+
35+ // Apply all attributes to the element
36+ Object . entries ( attributes ) . forEach ( ( [ key , value ] ) => {
37+ if ( value !== undefined && value !== null ) {
38+ ( element as any ) [ key ] = value ;
39+ }
40+ } ) ;
41+
42+ // Insert at the beginning of head to allow user styles to override
43+ if ( document . head . firstChild ) {
44+ document . head . insertBefore ( element , document . head . firstChild ) ;
45+ } else {
46+ document . head . appendChild ( element ) ;
47+ }
48+ }
49+
50+ /**
51+ * Injects all required stylesheets, fonts, and CSS variables into the document head.
52+ */
53+ function injectStylesheets ( ) : void {
54+ // Preconnect to Google Fonts for better performance
55+ injectElement ( "apify-fonts-preconnect-1" , "link" , {
56+ rel : "preconnect" ,
57+ href : "https://fonts.googleapis.com" ,
58+ } ) ;
59+
60+ injectElement ( "apify-fonts-preconnect-2" , "link" , {
61+ rel : "preconnect" ,
62+ href : "https://fonts.gstatic.com" ,
63+ crossOrigin : "anonymous" ,
64+ } ) ;
65+
66+ // Load Google Fonts stylesheet
67+ injectElement ( "apify-fonts-stylesheet" , "link" , {
68+ rel : "stylesheet" ,
69+ href : "https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=IBM+Plex+Mono:wght@400;500;600;700&display=swap" ,
70+ } ) ;
71+
72+ // Inject CSS variables
73+ injectElement ( "apify-css-variables" , "style" , {
74+ textContent : `:root {${ cssColorsVariablesLight } }` ,
75+ } ) ;
76+
77+ injectElement ( "apify-dark-css-variables" , "style" , {
78+ textContent : `:root[data-theme="dark"] { ${ cssColorsVariablesDark } }` ,
79+ } ) ;
80+ }
81+
2182export const renderWidget = ( Component : React . FC ) => {
2283 const initWidget = ( ) => {
2384 const rootElement = document . getElementById ( "root" ) ;
@@ -45,49 +106,9 @@ export const renderWidget = (Component: React.FC) => {
45106
46107 window . setInterval ( checkTheme , 1000 ) ;
47108
48- const root = createRoot ( rootElement ) ;
109+ injectStylesheets ( ) ;
49110
50- // Inject fonts and CSS variables for proper styling
51- const head = document . head || document . getElementsByTagName ( "head" ) [ 0 ] ;
52- if ( head ) {
53- // Fonts preconnect + stylesheet
54- if ( ! document . getElementById ( "apify-fonts-preconnect-1" ) ) {
55- const link1 = document . createElement ( "link" ) ;
56- link1 . id = "apify-fonts-preconnect-1" ;
57- link1 . rel = "preconnect" ;
58- link1 . href = "https://fonts.googleapis.com" ;
59- head . appendChild ( link1 ) ;
60- }
61- if ( ! document . getElementById ( "apify-fonts-preconnect-2" ) ) {
62- const link2 = document . createElement ( "link" ) ;
63- link2 . id = "apify-fonts-preconnect-2" ;
64- link2 . rel = "preconnect" ;
65- link2 . href = "https://fonts.gstatic.com" ;
66- link2 . crossOrigin = "anonymous" ;
67- head . appendChild ( link2 ) ;
68- }
69- if ( ! document . getElementById ( "apify-fonts-stylesheet" ) ) {
70- const linkFonts = document . createElement ( "link" ) ;
71- linkFonts . id = "apify-fonts-stylesheet" ;
72- linkFonts . rel = "stylesheet" ;
73- linkFonts . href = "https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=IBM+Plex+Mono:wght@400;500;600;700&display=swap" ;
74- head . appendChild ( linkFonts ) ;
75- }
76-
77- // CSS variables for light/dark themes
78- if ( ! document . getElementById ( "apify-css-variables" ) ) {
79- const styleLight = document . createElement ( "style" ) ;
80- styleLight . id = "apify-css-variables" ;
81- styleLight . textContent = `:root {${ lightCssVariables } }` ;
82- head . appendChild ( styleLight ) ;
83- }
84- if ( ! document . getElementById ( "apify-dark-css-variables" ) ) {
85- const styleDark = document . createElement ( "style" ) ;
86- styleDark . id = "apify-dark-css-variables" ;
87- styleDark . textContent = `:root[data-theme="dark"] { ${ darkCssVariables } }` ;
88- head . appendChild ( styleDark ) ;
89- }
90- }
111+ const root = createRoot ( rootElement ) ;
91112
92113 const dependencies = {
93114 InternalLink : React . forwardRef < HTMLAnchorElement , React . AnchorHTMLAttributes < HTMLAnchorElement > & { href : string ; replace ?: boolean } > (
0 commit comments