Theme
This commit is contained in:
parent
adf31c79d7
commit
7d8a9356e2
7 changed files with 194 additions and 9 deletions
|
|
@ -5,16 +5,16 @@ export default (node, props) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
update(new_props) {
|
update(newProps) {
|
||||||
Object.entries(new_props).forEach(([key, value]) => {
|
Object.entries(newProps).forEach(([key, value]) => {
|
||||||
node.style.setProperty(`--${key}`, value);
|
node.style.setProperty(`--${key}`, value);
|
||||||
delete props[key];
|
delete props[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.keys(props).forEach(name =>
|
Object.keys(props).forEach((name) => {
|
||||||
node.style.removeProperty(`--${name}`),
|
node.style.removeProperty(`--${name}`);
|
||||||
);
|
});
|
||||||
props = new_props;
|
props = newProps;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@ You can use `GraphicBlock` with components created by [ai2svelte](https://github
|
||||||
notes="Note: A shakemap represents the ground shaking produced by an earthquake."
|
notes="Note: A shakemap represents the ground shaking produced by an earthquake."
|
||||||
ariaDescription="A map showing shake intensity of the quake."
|
ariaDescription="A map showing shake intensity of the quake."
|
||||||
>
|
>
|
||||||
<MyAiMap basePath={assets} />
|
<MyAiMap assetsPath={assets} />
|
||||||
</GraphicBlock>
|
</GraphicBlock>
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ The `ariaDescription` string will be processed as markdown, so you can add multi
|
||||||
notes="Note: A shakemap represents the ground shaking produced by an earthquake."
|
notes="Note: A shakemap represents the ground shaking produced by an earthquake."
|
||||||
ariaDescription="A map showing the shake intensity produced by the earthquake."
|
ariaDescription="A map showing the shake intensity produced by the earthquake."
|
||||||
>
|
>
|
||||||
<MyAiMap basePath={assets} />
|
<MyAiMap assetsPath={assets} />
|
||||||
</GraphicBlock>
|
</GraphicBlock>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
100
src/components/Theme/Theme.stories.svelte
Normal file
100
src/components/Theme/Theme.stories.svelte
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
<script>
|
||||||
|
import { Meta, Template, Story } from '@storybook/addon-svelte-csf';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
import componentDocs from './stories/docs/component.md?raw';
|
||||||
|
|
||||||
|
import Theme, { themes } from './Theme.svelte';
|
||||||
|
|
||||||
|
import {
|
||||||
|
withComponentDocs
|
||||||
|
} from '$lib/docs/utils/withParams.js';
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Components/Theme',
|
||||||
|
component: Theme,
|
||||||
|
...withComponentDocs(componentDocs),
|
||||||
|
argTypes: {
|
||||||
|
styles: {
|
||||||
|
options: Object.keys(themes), // An array of serializable values
|
||||||
|
mapping: themes, // Maps serializable option values to complex arg values
|
||||||
|
control: {
|
||||||
|
type: 'select', // Type 'select' is automatically inferred when 'options' is defined
|
||||||
|
labels: {
|
||||||
|
// 'labels' maps option values to string labels
|
||||||
|
main: 'Main',
|
||||||
|
dark: 'Dark',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Meta {...meta} />
|
||||||
|
|
||||||
|
<Template let:args>
|
||||||
|
<Theme {...args}>
|
||||||
|
<div class="themed">
|
||||||
|
<p>My theme</p>
|
||||||
|
</div>
|
||||||
|
</Theme>
|
||||||
|
</Template>
|
||||||
|
|
||||||
|
<Story
|
||||||
|
name="Default"
|
||||||
|
args={{
|
||||||
|
styles: themes.main,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Story
|
||||||
|
name="Inheritance"
|
||||||
|
args={{
|
||||||
|
styles: themes.main,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Theme styles={themes.main}>
|
||||||
|
<div class="themed">
|
||||||
|
<p>My theme</p>
|
||||||
|
<Theme styles={themes.dark}>
|
||||||
|
<div class="themed">
|
||||||
|
<p>My sub-theme</p>
|
||||||
|
<Theme styles={themes.main}>
|
||||||
|
<div class="themed">
|
||||||
|
<p>My sub-sub-theme</p>
|
||||||
|
</div>
|
||||||
|
</Theme>
|
||||||
|
<Theme styles={{ colour: { background: 'steelblue', primary: '#fff' } }}>
|
||||||
|
<div class="themed">
|
||||||
|
<p>My other sub-sub-theme</p>
|
||||||
|
</div>
|
||||||
|
</Theme>
|
||||||
|
</div>
|
||||||
|
</Theme>
|
||||||
|
</div>
|
||||||
|
</Theme>
|
||||||
|
</Story>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "../../scss/mixins/fonts";
|
||||||
|
div.themed {
|
||||||
|
background-color: var(--theme-colour-background);
|
||||||
|
padding: 2rem;
|
||||||
|
width: 80%;
|
||||||
|
margin: 1rem auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-flow: column;
|
||||||
|
border: 1px solid var(--theme-colour-primary);
|
||||||
|
border-radius: 20px;
|
||||||
|
p {
|
||||||
|
@include font-display;
|
||||||
|
color: var(--theme-colour-primary);
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
42
src/components/Theme/Theme.svelte
Normal file
42
src/components/Theme/Theme.svelte
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<script context="module" lang="ts">
|
||||||
|
const main = {
|
||||||
|
colour: {
|
||||||
|
background: '#ffffff',
|
||||||
|
primary: '#333333',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const dark = {
|
||||||
|
colour: {
|
||||||
|
background: '#333333',
|
||||||
|
primary: '#ffffff',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const themes = {
|
||||||
|
main,
|
||||||
|
dark,
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export let styles: object = main;
|
||||||
|
export let name: string = 'theme';
|
||||||
|
|
||||||
|
import cssVariables from '../../actions/cssVariables';
|
||||||
|
import flatten from './utils/flatten';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="theme theme-{name}"
|
||||||
|
style="display: contents;"
|
||||||
|
use:cssVariables={flatten({ [name]: styles })}
|
||||||
|
>
|
||||||
|
<!-- Clients can override the theme above by attaching custom properties to this element. -->
|
||||||
|
<div
|
||||||
|
class="theme-client-override theme-{name}"
|
||||||
|
style="display: contents;"
|
||||||
|
>
|
||||||
|
<!-- Themed content -->
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
3
src/components/Theme/stories/docs/component.md
Normal file
3
src/components/Theme/stories/docs/component.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
> ⏳ Coming soon!
|
||||||
|
|
||||||
|
Set a theme for your page.
|
||||||
40
src/components/Theme/utils/flatten.js
Normal file
40
src/components/Theme/utils/flatten.js
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
function isBuffer(obj) {
|
||||||
|
return obj &&
|
||||||
|
obj.constructor &&
|
||||||
|
(typeof obj.constructor.isBuffer === 'function') &&
|
||||||
|
obj.constructor.isBuffer(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
const transformKey = (key) => key.replace(/[^a-z0-9-]/gi, '');
|
||||||
|
|
||||||
|
export default function flatten(target) {
|
||||||
|
const delimiter = '-';
|
||||||
|
const output = {};
|
||||||
|
|
||||||
|
function step(object, prev, currentDepth = 1) {
|
||||||
|
Object.keys(object).forEach(function(key) {
|
||||||
|
const value = object[key];
|
||||||
|
const isArray = Array.isArray(value);
|
||||||
|
const type = Object.prototype.toString.call(value);
|
||||||
|
const isbuffer = isBuffer(value);
|
||||||
|
const isObject = (
|
||||||
|
type === '[object Object]' ||
|
||||||
|
type === '[object Array]'
|
||||||
|
);
|
||||||
|
|
||||||
|
const newKey = prev ?
|
||||||
|
prev + delimiter + transformKey(key) :
|
||||||
|
transformKey(key);
|
||||||
|
|
||||||
|
if (!isArray && !isbuffer && isObject && Object.keys(value).length) {
|
||||||
|
return step(value, newKey, currentDepth + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
output[newKey] = value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
step(target);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue