From 771264b57367ffa2b0f4501be6bd1af134cb1d05 Mon Sep 17 00:00:00 2001 From: jlukic Date: Wed, 4 Jun 2025 21:10:20 -0400 Subject: [PATCH] Add framework css to define component --- packages/component/src/define-component.js | 18 +++++++- .../component/src/helpers/adopt-stylesheet.js | 41 ++++++++++++++----- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/packages/component/src/define-component.js b/packages/component/src/define-component.js index 33bdc6495..8964d8308 100644 --- a/packages/component/src/define-component.js +++ b/packages/component/src/define-component.js @@ -1,5 +1,5 @@ import { Template, TemplateCompiler } from '@semantic-ui/templating'; -import { camelToKebab, each, isClient, isServer, kebabToCamel, noop } from '@semantic-ui/utils'; +import { camelToKebab, each, isClient, isPlainObject, isServer, kebabToCamel, noop } from '@semantic-ui/utils'; import { unsafeCSS } from 'lit'; import { adjustPropertyFromAttribute } from './helpers/adjust-property-from-attribute.js'; @@ -11,6 +11,7 @@ export const defineComponent = ({ ast, css = '', pageCSS = '', + frameworkCSS = {}, tagName, delegatesFocus = false, templateName = kebabToCamel(tagName), @@ -57,6 +58,21 @@ export const defineComponent = ({ adoptStylesheet(pageCSS); } + if (frameworkCSS) { + if (isPlainObject(frameworkCSS)) { + each(frameworkCSS, (css, id) => { + adoptStylesheet(css, { + hash: id, + cacheStylesheet: true, + }); + }); + } + else if (isString(frameworkCSS)) { + adoptStylesheet(frameworkCSS, { + cacheStylesheet: true, + }); + } + } /* Create Component Returns Either a Template or WebComponent diff --git a/packages/component/src/helpers/adopt-stylesheet.js b/packages/component/src/helpers/adopt-stylesheet.js index cde044ecb..eec425b07 100644 --- a/packages/component/src/helpers/adopt-stylesheet.js +++ b/packages/component/src/helpers/adopt-stylesheet.js @@ -1,7 +1,11 @@ import { hashCode, isServer } from '@semantic-ui/utils'; import { scopeStyles } from './scope-styles.js'; -export const adoptStylesheet = (css, adoptedElement, { scopeSelector } = {}) => { +export const adoptStylesheet = (css, adoptedElement, { + scopeSelector, + hash = hashCode(css), + cacheStylesheet = false, +} = {}) => { if (isServer) { return; } @@ -9,26 +13,43 @@ export const adoptStylesheet = (css, adoptedElement, { scopeSelector } = {}) => adoptedElement = document; } - const hash = hashCode(css); if (!adoptedElement.cssHashes) { adoptedElement.cssHashes = []; } + // already added if (adoptedElement.cssHashes.includes(hash)) { - // already added return; } adoptedElement.cssHashes.push(hash); - const stylesheet = new CSSStyleSheet(); + let stylesheet; - // allow selectors to be scoped if passed in - // i.e .foo => .scope .foo - if (scopeSelector) { - css = scopeStyles(css, scopeSelector); + if (cacheStylesheet && document.cachedStylesheets[hash]) { + // reuse stylesheet if cached + stylesheet = documnet.cachedStylesheets[hash]; } - stylesheet.id = hash; - stylesheet.replaceSync(css); + else { + // otherwise create from scratch + stylesheet = new CSSStyleSheet(); + + // allow selectors to be scoped if passed in + // i.e .foo => .scope .foo + if (scopeSelector) { + css = scopeStyles(css, scopeSelector); + } + stylesheet.id = hash; + stylesheet.replaceSync(css); + } + + // store stylesheet globally in cache for reuse if specified + if (cacheStylesheet) { + if (!document.cachedStylesheets) { + document.cachedStylesheets = {}; + } + document.cachedStylesheets[hash] = stylesheet; + } + // adopt this stylesheet after others adoptedElement.adoptedStyleSheets = [ ...adoptedElement.adoptedStyleSheets,