Skip to content

Commit 6e24d92

Browse files
committed
Merge branch 'main' into jsdocs
* main: v0.1.0 (#26) WEBDEV-8109 Expand status indicator capabilities (#23) WEBDEV-8100 Encapsulate style settings (#22) Load snowflakes async (#12) WEBDEV-8019 Add basic loading indicator (#17) Fix issue with css property values not updating (#19) WEBDEV-8098: Component Demo Light Mode (#18) WEBDEV-8037 Create CSS theme structure (#16)
2 parents 024efa2 + b6bb965 commit 6e24d92

16 files changed

+1035
-138
lines changed

demo/app-root.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@ import { customElement } from 'lit/decorators.js';
33

44
import '@src/elements/ia-button/ia-button-story';
55
import '@src/labs/ia-snow/ia-snow-story';
6+
import '@src/elements/ia-status-indicator/ia-status-indicator-story';
67

78
@customElement('app-root')
89
export class AppRoot extends LitElement {
910
render() {
1011
return html`
1112
<h1>🏛️ Internet Archive Elements ⚛️</h1>
1213
13-
<ia-button-story></ia-button-story>
14+
<h2>🚀 Production-Ready Elements</h2>
15+
16+
<ia-status-indicator-story></ia-status-indicator-story>
17+
18+
<h2>🧪 Labs Elements</h2>
1419
1520
<ia-snow-story></ia-snow-story>
21+
<ia-button-story></ia-button-story>
1622
`;
1723
}
1824
}

demo/index.css

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
line-height: 1.5;
44
font-weight: 400;
55

6-
color-scheme: light dark;
7-
color: rgba(255, 255, 255, 0.87);
8-
background-color: #242424;
6+
color-scheme: light;
7+
color: #213547;
8+
background-color: #ffffff;
99

1010
font-synthesis: none;
1111
text-rendering: optimizeLegibility;
@@ -28,10 +28,3 @@ body {
2828
min-width: 320px;
2929
min-height: 100vh;
3030
}
31-
32-
@media (prefers-color-scheme: light) {
33-
:root {
34-
color: #213547;
35-
background-color: #ffffff;
36-
}
37-
}

demo/story-template.ts

Lines changed: 154 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,33 @@
1-
import { css, html, LitElement, type CSSResultGroup } from 'lit';
2-
import { property, state } from 'lit/decorators.js';
1+
import {
2+
css,
3+
html,
4+
LitElement,
5+
nothing,
6+
TemplateResult,
7+
type CSSResultGroup,
8+
} from 'lit';
9+
import { property, queryAll, state } from 'lit/decorators.js';
310
import { customElement } from 'lit/decorators/custom-element.js';
411
import { when } from 'lit/directives/when.js';
12+
import { ifDefined } from 'lit/directives/if-defined.js';
513

614
import './syntax-highlighter';
15+
import themeStyles from '@src/themes/theme-styles';
716

817
import arrow from './arrow.svg';
918
import testTube from './test-tube.svg';
1019

20+
export type StyleInputSettings = {
21+
label: string;
22+
cssVariable: string;
23+
defaultValue?: string;
24+
inputType?: 'color' | 'text';
25+
};
26+
27+
export type StyleInputData = {
28+
settings: StyleInputSettings[];
29+
};
30+
1131
/**
1232
* A template for demoing the use of a custom element.
1333
*/
@@ -17,10 +37,21 @@ export class StoryTemplate extends LitElement {
1737

1838
@property({ type: String }) exampleUsage = '';
1939

40+
@property({ type: Object }) styleInputData?: StyleInputData;
41+
2042
@property({ type: Boolean }) labs = false;
2143

2244
@state() private visible = false;
2345

46+
/* Stringified styles applied for the demo component */
47+
@state() private appliedStyles?: string;
48+
49+
/* Whether settings inputs have been slotted in and should be displayed */
50+
@state() private shouldShowPropertySettings: boolean = false;
51+
52+
@queryAll('.style-input')
53+
private styleInputs?: NodeListOf<HTMLInputElement>;
54+
2455
render() {
2556
return html`
2657
<h2>
@@ -48,28 +79,78 @@ export class StoryTemplate extends LitElement {
4879
return html`
4980
<div id="container">
5081
<h3>Demo</h3>
51-
<div class="slot-container">
82+
<div class="slot-container" style=${ifDefined(this.appliedStyles)}>
5283
<slot name="demo"></slot>
5384
</div>
5485
<h3>Import</h3>
5586
<syntax-highlighter .code=${this.importCode}></syntax-highlighter>
5687
<h3>Usage</h3>
57-
<syntax-highlighter .code=${this.exampleUsage}></syntax-highlighter>
58-
<h3>Settings</h3>
59-
<div class="slot-container">
88+
<syntax-highlighter
89+
.code=${this.exampleUsage + this.cssCode}
90+
></syntax-highlighter>
91+
${this.styleSettingsTemplate}
92+
${this.shouldShowPropertySettings ? html` <h3>Settings</h3>` : nothing}
93+
<div
94+
class="slot-container"
95+
style="${!this.shouldShowPropertySettings ? 'display: none' : ''}"
96+
@slotchange=${this.handleSettingsSlotChange}
97+
>
6098
<slot name="settings"></slot>
6199
</div>
62100
</div>
63101
`;
64102
}
65103

104+
private get styleSettingsTemplate(): TemplateResult | typeof nothing {
105+
if (!this.styleInputData) return nothing;
106+
107+
return html`
108+
<h3>Styles</h3>
109+
<div class="style-options">
110+
<table>
111+
${this.styleInputData.settings.map(
112+
(input) => html`
113+
<tr>
114+
<td>
115+
<label for=${this.labelToId(input.label)}
116+
>${input.label}</label
117+
>
118+
</td>
119+
<td>
120+
<input
121+
id=${this.labelToId(input.label)}
122+
class="style-input"
123+
type=${input.inputType ?? 'text'}
124+
value=${input.defaultValue ?? ''}
125+
data-variable=${input.cssVariable}
126+
/>
127+
</td>
128+
</tr>
129+
`,
130+
)}
131+
</table>
132+
<button @click=${this.applyStyles}>Apply</button>
133+
</div>
134+
`;
135+
}
136+
66137
private get importCode(): string {
67138
return `
68139
import '${this.modulePath}';
69140
import { ${this.elementClassName} } from '${this.modulePath}';
70141
`;
71142
}
72143

144+
private get cssCode(): string {
145+
if (!this.appliedStyles) return '';
146+
return `
147+
148+
${this.elementTag} {
149+
${this.appliedStyles}
150+
}
151+
`;
152+
}
153+
73154
private get elementClassName(): string | undefined {
74155
return customElements.get(this.elementTag)?.name;
75156
}
@@ -80,47 +161,73 @@ import { ${this.elementClassName} } from '${this.modulePath}';
80161
: `@internetarchive/elements/${this.elementTag}/${this.elementTag}`;
81162
}
82163

164+
/* Toggles visibility of section depending on whether inputs have been slotted into it */
165+
private handleSettingsSlotChange(e: Event): void {
166+
const slottedChildren = (e.target as HTMLSlotElement).assignedElements();
167+
this.shouldShowPropertySettings = slottedChildren.length > 0;
168+
}
169+
170+
/* Applies styles to demo component. */
171+
private applyStyles(): void {
172+
const appliedStyles: string[] = [];
173+
174+
this.styleInputs?.forEach((input) => {
175+
if (!input.dataset.variable || !input.value) return;
176+
appliedStyles.push(`${input.dataset.variable}: ${input.value};`);
177+
});
178+
179+
this.appliedStyles = appliedStyles.join('\n ');
180+
}
181+
182+
/* Converts a label to a usable input id, i.e. My setting -> my-setting */
183+
private labelToId(label: string): string {
184+
return label.toLowerCase().split(' ').join('-');
185+
}
186+
83187
static get styles(): CSSResultGroup {
84-
return css`
85-
#container {
86-
border: 1px solid #ccc;
87-
padding: 0 16px 16px 16px;
88-
}
89-
90-
h2 {
91-
cursor: pointer;
92-
margin-top: 8px;
93-
margin-bottom: 8px;
94-
}
95-
96-
h3 {
97-
margin-bottom: 8px;
98-
}
99-
100-
.slot-container {
101-
background: #282c34;
102-
padding: 1em;
103-
}
104-
105-
.disclosure-arrow {
106-
width: 12px;
107-
height: 12px;
108-
transform: rotate(-90deg);
109-
filter: invert(1);
110-
transition: transform 0.2s ease-in-out;
111-
}
112-
113-
.disclosure-arrow.open {
114-
transform: rotate(0deg);
115-
}
116-
117-
.labs-icon {
118-
width: 20px;
119-
height: 20px;
120-
margin-left: 4px;
121-
filter: invert(1);
122-
vertical-align: middle;
123-
}
124-
`;
188+
return [
189+
themeStyles,
190+
css`
191+
#container {
192+
border: 1px solid #ccc;
193+
padding: 0 16px 16px 16px;
194+
}
195+
196+
h2 {
197+
cursor: pointer;
198+
margin-top: 8px;
199+
margin-bottom: 8px;
200+
}
201+
202+
h3 {
203+
margin-bottom: 8px;
204+
}
205+
206+
.slot-container,
207+
.style-options {
208+
background-color: var(--primary-background-color);
209+
padding: 1em;
210+
}
211+
212+
.disclosure-arrow {
213+
width: 12px;
214+
height: 12px;
215+
transform: rotate(-90deg);
216+
transition: transform 0.2s ease-in-out;
217+
}
218+
219+
.disclosure-arrow.open {
220+
transform: rotate(0deg);
221+
}
222+
223+
.labs-icon {
224+
width: 20px;
225+
height: 20px;
226+
margin-left: 4px;
227+
filter: invert(1);
228+
vertical-align: middle;
229+
}
230+
`,
231+
];
125232
}
126233
}

demo/syntax-highlighter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
} from 'lit';
99
import { customElement, property, state } from 'lit/decorators.js';
1010
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
11-
import { syntaxStyles } from './syntax-style';
11+
import { syntaxStyles } from './syntax-style-light';
1212

1313
/**
1414
* An element that syntax highlights and displays TypeScript code

0 commit comments

Comments
 (0)