Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@rolemodel/spider",
"description": "Shared high level web components for RoleModel Software and beyond",
"packageManager": "yarn@4.12.0",
"version": "0.0.9",
"version": "0.0.10",
"author": "RoleModel Software",
"license": "MIT",
"type": "module",
Expand Down
13 changes: 5 additions & 8 deletions src/components/pdf-viewer/pdf-viewer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { html } from 'lit'
import { html, adoptStyles } from 'lit'
import { ContextProvider } from '@lit/context'
import './url-parse-polyfill.js'
import * as pdfjsLib from 'pdfjs-dist'
Expand All @@ -8,7 +8,7 @@ import openjpegWasmUrl from 'pdfjs-dist/wasm/openjpeg.wasm?url'
import qcmsWasmUrl from 'pdfjs-dist/wasm/qcms_bg.wasm?url'
import styles from './pdf-viewer.styles.js'
import { pdfContext } from './pdf-context.js'
import { createThemeStyleSheet } from './theme-config.js'
import { createThemeStyles } from './theme-config.js'
import { normalizeText } from './helpers/text-helper.js'
import './toolbar/pdf-toolbar.js'
import './sidebar/pdf-sidebar.js'
Expand Down Expand Up @@ -83,7 +83,7 @@ export default class PDFViewer extends RoleModelElement {
this.searchOpen = false
this.error = null
this.loading = false
this.themeStyleSheet = createThemeStyleSheet(this.themeHue, this.themeSaturation)
this.themeStyleSheet = createThemeStyles(this.themeHue, this.themeSaturation)
this.fitToScreenScale = null

this._provider = new ContextProvider(this, {
Expand Down Expand Up @@ -381,11 +381,8 @@ export default class PDFViewer extends RoleModelElement {
}

_updateThemeColors() {
this.themeStyleSheet = createThemeStyleSheet(this.themeHue, this.themeSaturation)
this.shadowRoot.adoptedStyleSheets = [
...this.constructor.elementStyles.map(s => s.styleSheet),
this.themeStyleSheet
]
this.themeStyleSheet = createThemeStyles(this.themeHue, this.themeSaturation)
adoptStyles(this.shadowRoot, [...this.constructor.elementStyles, this.themeStyleSheet])
}

async firstUpdated() {
Expand Down
13 changes: 6 additions & 7 deletions src/components/pdf-viewer/theme-config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export const createThemeStyleSheet = (hue = 217, saturation = 89) => {
const css = `
import { css } from 'lit'

// Returns a lazy CSSResult instead of constructing a CSSStyleSheet directly:
// `new CSSStyleSheet()` throws "Illegal constructor" on browsers without
// constructable stylesheet support (e.g. Safari < 16.4).
export const createThemeStyles = (hue = 217, saturation = 89) => css`
:host {
--theme-primary: light-dark(hsl(${hue}, ${saturation}%, 50%), hsl(${hue}, ${saturation}%, 60%));
--theme-primary-light: light-dark(hsl(${hue}, ${saturation}%, 90%), hsl(${hue}, ${saturation}%, 30%));
Expand Down Expand Up @@ -44,8 +48,3 @@ export const createThemeStyleSheet = (hue = 217, saturation = 89) => {
--theme-icon-size-lg: 18px;
}
`

const sheet = new CSSStyleSheet()
sheet.replaceSync(css)
return sheet
}
46 changes: 28 additions & 18 deletions test/components/theme-config.test.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
import { describe, it, expect } from 'vitest'
import { createThemeStyleSheet } from '../../src/components/pdf-viewer/theme-config.js'
import { CSSResult } from 'lit'
import { createThemeStyles } from '../../src/components/pdf-viewer/theme-config.js'

describe('Theme Configuration', () => {
describe('createThemeStyleSheet', () => {
it('should create a CSSStyleSheet with default values', () => {
const sheet = createThemeStyleSheet()
describe('createThemeStyles', () => {
it('should create a CSSResult with default values', () => {
const styles = createThemeStyles()

expect(sheet).toBeInstanceOf(CSSStyleSheet)
expect(sheet.cssRules.length).toBeGreaterThan(0)
expect(styles).toBeInstanceOf(CSSResult)
expect(styles.cssText.length).toBeGreaterThan(0)
})

it('should create a stylesheet with custom hue', () => {
const sheet = createThemeStyleSheet(150, 89)
it('should create styles with custom hue', () => {
const styles = createThemeStyles(150, 89)

expect(sheet).toBeInstanceOf(CSSStyleSheet)
expect(sheet.cssRules[0].cssText).toContain('150')
expect(styles.cssText).toContain('150')
})

it('should create a stylesheet with custom saturation', () => {
const sheet = createThemeStyleSheet(217, 50)
it('should create styles with custom saturation', () => {
const styles = createThemeStyles(217, 50)

expect(sheet).toBeInstanceOf(CSSStyleSheet)
expect(sheet.cssRules[0].cssText).toContain('50%')
expect(styles.cssText).toContain('50%')
})

it('should include all theme CSS variables', () => {
const sheet = createThemeStyleSheet()
const cssText = sheet.cssRules[0].cssText
const cssText = createThemeStyles().cssText

expect(cssText).toContain('--theme-primary')
expect(cssText).toContain('--theme-neutral-')
Expand All @@ -37,10 +35,22 @@ describe('Theme Configuration', () => {
})

it('should use light-dark() function for color properties', () => {
const sheet = createThemeStyleSheet()
const cssText = sheet.cssRules[0].cssText
const cssText = createThemeStyles().cssText

expect(cssText).toContain('light-dark')
})

it('should not construct a CSSStyleSheet eagerly (Safari < 16.4 has no constructor)', () => {
const originalCSSStyleSheet = globalThis.CSSStyleSheet
globalThis.CSSStyleSheet = function () {
throw new TypeError('Illegal constructor')
}

try {
expect(() => createThemeStyles(217, 89)).not.toThrow()
} finally {
globalThis.CSSStyleSheet = originalCSSStyleSheet
}
})
})
})
Loading