This commit is contained in:
Jon McClure 2022-08-18 22:38:42 +01:00
parent adf31c79d7
commit 7d8a9356e2
7 changed files with 194 additions and 9 deletions

View file

@ -5,16 +5,16 @@ export default (node, props) => {
});
return {
update(new_props) {
Object.entries(new_props).forEach(([key, value]) => {
update(newProps) {
Object.entries(newProps).forEach(([key, value]) => {
node.style.setProperty(`--${key}`, value);
delete props[key];
});
Object.keys(props).forEach(name =>
node.style.removeProperty(`--${name}`),
);
props = new_props;
Object.keys(props).forEach((name) => {
node.style.removeProperty(`--${name}`);
});
props = newProps;
},
};
};
};

View file

@ -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."
ariaDescription="A map showing shake intensity of the quake."
>
<MyAiMap basePath={assets} />
<MyAiMap assetsPath={assets} />
</GraphicBlock>
```

View file

@ -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."
ariaDescription="A map showing the shake intensity produced by the earthquake."
>
<MyAiMap basePath={assets} />
<MyAiMap assetsPath={assets} />
</GraphicBlock>
```

View 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>

View 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>

View file

@ -0,0 +1,3 @@
> ⏳ Coming soon!
Set a theme for your page.

View 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;
}