feat: use slot & constructable stylesheet

This commit is contained in:
ayo 2026-05-08 14:01:27 +02:00
parent fee257cd15
commit 762ca1b3ab
3 changed files with 118 additions and 2 deletions

View file

@ -7,6 +7,6 @@
<script type="module" src="./src/status-indicator.ts"></script>
</head>
<body>
<status-indicator></status-indicator>
<status-indicator>All systems operational</status-indicator>
</body>
</html>

View file

@ -1,9 +1,12 @@
import { WebComponent, html } from 'web-component-base'
import stylesheet from './stylesheets'
console.log(stylesheet.cssRules)
class StatusIndicator extends WebComponent {
get template(): any {
return html`
<h1>Hello, World!</h1>
<slot></slot>
`
}
}

113
src/stylesheets.ts Normal file
View file

@ -0,0 +1,113 @@
const sheet = new CSSStyleSheet()
sheet.replaceSync(`
:root {
--status-indicator-size: 0.5rem;
--status-indicator-animation-duration: 2s;
--status-indicator-color: rgb(216, 226, 233);
--status-indicator-color-semi: rgba(216, 226, 233, .5);
--status-indicator-color-transparent: rgba(216, 226, 233, 0);
--status-indicator-color-active: rgb(0, 149, 255);
--status-indicator-color-active-semi: rgba(0, 149, 255, .5);
--status-indicator-color-active-transparent: rgba(0, 149, 255, 0);
--status-indicator-color-positive: rgb(75, 210, 143);
--status-indicator-color-positive-semi: rgba(75, 210, 143, .5);
--status-indicator-color-positive-transparent: rgba(75, 210, 143, 0);
--status-indicator-color-intermediary: rgb(255, 170, 0);
--status-indicator-color-intermediary-semi: rgba(255, 170, 0, .5);
--status-indicator-color-intermediary-transparent: rgba(255, 170, 0, 0);
--status-indicator-color-negative: rgb(255, 77, 77);
--status-indicator-color-negative-semi: rgba(255, 77, 77, .5);
--status-indicator-color-negative-transparent: rgba(255, 77, 77, 0);
}
@keyframes status-indicator-pulse {
0% { box-shadow: 0 0 0 0 var(--status-indicator-color-semi); }
70% { box-shadow: 0 0 0 var(--status-indicator-size) var(--status-indicator-color-transparent); }
100% { box-shadow: 0 0 0 0 var(--status-indicator-color-transparent); }
}
@keyframes status-indicator-pulse-active {
0% { box-shadow: 0 0 0 0 var(--status-indicator-color-active-semi); }
70% { box-shadow: 0 0 0 var(--status-indicator-size) var(--status-indicator-color-active-transparent); }
100% { box-shadow: 0 0 0 0 var(--status-indicator-color-active-transparent); }
}
@keyframes status-indicator-pulse-positive {
0% { box-shadow: 0 0 0 0 var(--status-indicator-color-positive-semi); }
70% { box-shadow: 0 0 0 var(--status-indicator-size) var(--status-indicator-color-positive-transparent); }
100% { box-shadow: 0 0 0 0 var(--status-indicator-color-positive-transparent); }
}
@keyframes status-indicator-pulse-intermediary {
0% { box-shadow: 0 0 0 0 var(--status-indicator-color-intermediary-semi); }
70% { box-shadow: 0 0 0 var(--status-indicator-size) var(--status-indicator-color-intermediary-transparent); }
100% { box-shadow: 0 0 0 0 var(--status-indicator-color-intermediary-transparent); }
}
@keyframes status-indicator-pulse-negative {
0% { box-shadow: 0 0 0 0 var(--status-indicator-color-negative-semi); }
70% { box-shadow: 0 0 0 var(--status-indicator-size) var(--status-indicator-color-negative-transparent); }
100% { box-shadow: 0 0 0 0 var(--status-indicator-color-negative-transparent); }
}
status-indicator {
display: inline-block;
border-radius: 50%;
cursor: pointer;
width: var(--status-indicator-size);
height: var(--status-indicator-size);
background-color: var(--status-indicator-color);
}
status-indicator[pulse] {
animation-name: status-indicator-pulse;
animation-duration: var(--status-indicator-animation-duration);
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-direction: normal;
animation-delay: 0;
animation-fill-mode: none;
}
status-indicator[active] {
background-color: var(--status-indicator-color-active);
}
status-indicator[active][pulse] {
animation-name: status-indicator-pulse-active;
}
status-indicator[positive] {
background-color: var(--status-indicator-color-positive);
animation-name: status-indicator-pulse-positive;
}
status-indicator[positive][pulse] {
animation-name: status-indicator-pulse-positive;
}
status-indicator[intermediary] {
background-color: var(--status-indicator-color-intermediary);
}
status-indicator[intermediary][pulse] {
animation-name: status-indicator-pulse-intermediary;
}
status-indicator[negative] {
background-color: var(--status-indicator-color-negative);
animation-name: status-indicator-pulse-negative;
}
status-indicator[negative][pulse] {
animation-name: status-indicator-pulse-negative;
}
`)
export default sheet