Skip to content

Commit

Permalink
Merge pull request #45 from josefaidt/next
Browse files Browse the repository at this point in the history
  • Loading branch information
josefaidt committed Jan 23, 2022
2 parents e327259 + e31c13a commit 8f89ec1
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ node_modules
/lib

.vercel
coverage
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,29 @@ Described below is the pattern used for accessing `theme` context to create your
</ThemeWrapper>
```

## Actions

### use:theme

```svelte
<script>
import { theme } from 'svelte-themer/use'
export let myTheme = {
text: 'red',
}
</script>

<div use:theme="{myTheme}">
<p>Hello, World!</p>
</div>

<style>
p {
color: var(--text);
}
</style>
```

## Contributing

Refer to the [contributing guidelines](CONTRIBUTING.md).
Expand Down
7 changes: 4 additions & 3 deletions components/ThemeWrapper.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import { onMount, afterUpdate, setContext } from 'svelte'
import { presets } from './presets'
import toggle from '../support/toggle'
import { createCSS } from '../support/css'
import { createCSSTemplate } from '../support/css'
import {
currentThemeName,
currentThemeObject,
Expand Down Expand Up @@ -63,12 +63,13 @@

themesStore.set(themes)
const [fallback] = Object.keys(themes)
if (!Object.keys(themes).includes($currentThemeName))
if (!Object.keys(themes).includes($currentThemeName)) {
currentThemeName.set(fallback)
}
$: currentThemeObject.set(themes[$currentThemeName])

// create CSS
const style = createCSS(prefix, base, themes)
const style = createCSSTemplate(prefix, base, themes)

setContext(CONTEXT_KEY, {
current: currentThemeName,
Expand Down
1 change: 1 addition & 0 deletions components/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as ThemeWrapper } from './ThemeWrapper.svelte'
export { default as ThemeToggle } from './ThemeToggle.svelte'
export { presets } from './presets.js'
31 changes: 31 additions & 0 deletions components/use.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createCSSVariableCollection } from '../support/css'

/**
*
* @param {HTMLElement} node
* @param {Object.<string, string|number>} theme
* @returns
*/
export async function theme(node, theme) {
/**
*
* @param {string} name
* @param {string} value
* @returns {void}
*/
function setProperty(name, value) {
if (!node.style && node.document?.documentElement) {
node.document.documentElement.style.setProperty(name, value)
return
}
node.style.setProperty(name, value)
return
}

const variables = createCSSVariableCollection(theme)
for (let [name, value] of variables) {
setProperty(name, value)
}

return {}
}
4 changes: 2 additions & 2 deletions docs/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
<meta property="og:url" content="{url}" />
<meta property="og:title" content="{title}" />
<meta property="og:description" content="{description}" />
<meta property="og:image" content="/favicon.png" />
<meta property="og:image" content="/favicon.ico" />

<meta name="twitter:card" content="summary" />
<meta name="twitter:creator" content="{author}" />
<meta name="twitter:title" content="{title}" />
<meta name="twitter:description" content="{description}" />
<meta name="twitter:image" content="/favicon.png" />
<meta name="twitter:image" content="/favicon.ico" />
</svelte:head>

<ThemeWrapper base="{base}">
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "svelte-themer",
"type": "module",
"version": "0.5.2",
"version": "0.5.3-next.1",
"homepage": "https://svelte-themer.vercel.app",
"license": "MIT",
"repository": {
Expand All @@ -16,7 +16,8 @@
},
"./package.json": "./package.json",
"./components": "./components/index.js",
"./store": "./support/store.js"
"./store": "./support/store.js",
"./use": "./components/use.js"
},
"files": [
"components",
Expand Down
22 changes: 19 additions & 3 deletions support/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,30 @@ export function createCSSVariableOverride({
return `${initialVariableName}: var(${themeVariableName});`
}

/**
*
* @param {object} config
* @param {Object} options
* @param {string} options.prefix
* @returns {[CSSVariableName, <string,CSSVariableName>]}
*/
export function createCSSVariableCollection(config, { prefix } = {}) {
const variablePrefix = prefix ? `--${prefix}` : '-'
const processedConfig = processConfig(config)
const variables = Object.entries(processedConfig).map(([prop, value]) => {
return [createCSSVariableName({ variablePrefix, prop }), value]
})
return variables
}

/**
* Create CSS template
* @name setCSS
* @name createCSSTemplate
* @param {string} prefix - CSS variable prefix
* @param {Object[]} themes - themes array
* @returns {string} CSS template
*/
export function createCSS(prefix, base = {}) {
export function createCSSTemplate(prefix, base = {}) {
const variablePrefix = prefix ? `--${prefix}` : '-'

const themes = get(themesStore)
Expand Down Expand Up @@ -125,7 +141,7 @@ export function createCSS(prefix, base = {}) {
:root {
${rootCSSVariables
.map(vars => createCSSVariableStatement(...vars))
.join('\n\t')}
.join('')}
}

${themeCSSContent.join('')}
Expand Down
11 changes: 11 additions & 0 deletions test/support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function render(Component, props = {}) {
const host = document.createElement('div')
host.setAttribute('id', 'host')
document.body.appendChild(host)
const instance = new Component({ target: host, props })
return instance
}

export function getByTestId(id) {
return document.querySelector(`[data-testid="${id}"]`)
}
24 changes: 24 additions & 0 deletions test/use.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect, it } from 'vitest'
import UseComponent from './use.test.svelte'
import { render as _render, getByTestId } from './support.js'

function render(props = {}) {
return _render(UseComponent, props)
}

describe('Theme Action', () => {
it('should render', () => {
const instance = render()
expect(instance).toBeTruthy()
})

it('should create inline styles', () => {
const myTheme = {
text: 'red',
}
const instance = render({ myTheme })
const container = getByTestId('container')
expect(container.style).toBeTruthy()
expect(container.style.getPropertyValue('--text')).toBe('red')
})
})
16 changes: 16 additions & 0 deletions test/use.test.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script>
import { theme } from '../components/use'
export let myTheme = {
text: 'red',
}
</script>

<div use:theme="{myTheme}" data-testid="container">
<p data-testid="paragraph">Hello, World!</p>
</div>

<style>
p {
color: var(--text);
}
</style>
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as ThemeWrapper } from "./ThemeWrapper.svelte";
export { default as ThemeToggle } from "./ThemeToggle.svelte";
export { default as presets } from "./presets.js";

1 comment on commit 8f89ec1

@vercel
Copy link

@vercel vercel bot commented on 8f89ec1 Jan 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.