feat(statuspage): refactor shared styles and modernize components for consistent theming, spacing and APIs

This commit is contained in:
2025-12-23 09:26:37 +00:00
parent 891eb04d11
commit ed9728dd4a
24 changed files with 4177 additions and 3542 deletions

View File

@@ -1,6 +1,6 @@
import { DeesElement, property, html, customElement, type TemplateResult, css, cssManager, unsafeCSS } from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
import { fonts, colors, shadows, borderRadius, spacing, commonStyles } from '../styles/shared.styles.js';
import * as sharedStyles from '../styles/shared.styles.js';
import { demoFunc } from './upl-statuspage-footer.demo.js';
declare global {
@@ -16,76 +16,76 @@ export class UplStatuspageFooter extends DeesElement {
// INSTANCE
@property({ type: String })
public companyName: string = '';
accessor companyName: string = '';
@property({ type: String })
public legalUrl: string = '';
accessor legalUrl: string = '';
@property({ type: String })
public supportEmail: string = '';
accessor supportEmail: string = '';
@property({ type: String })
public statusPageUrl: string = '';
accessor statusPageUrl: string = '';
@property({ type: Boolean })
public whitelabel: boolean = false;
accessor whitelabel: boolean = false;
@property({ type: Number })
public lastUpdated: number | null = null;
accessor lastUpdated: number | null = null;
@property({ type: Number })
public currentYear: number = new Date().getFullYear();
accessor currentYear: number = new Date().getFullYear();
@property({ type: Array })
public socialLinks: Array<{ platform: string; url: string }> = [];
accessor socialLinks: Array<{ platform: string; url: string }> = [];
@property({ type: Array })
public additionalLinks: Array<{ label: string; url: string }> = [];
accessor additionalLinks: Array<{ label: string; url: string }> = [];
@property({ type: String })
public rssFeedUrl: string = '';
accessor rssFeedUrl: string = '';
@property({ type: String })
public apiStatusUrl: string = '';
accessor apiStatusUrl: string = '';
@property({ type: Boolean })
public loading: boolean = false;
accessor loading: boolean = false;
@property({ type: String })
public errorMessage: string | null = null;
accessor errorMessage: string | null = null;
@property({ type: Boolean })
public offline: boolean = false;
accessor offline: boolean = false;
@property({ type: String })
public latestStatusUpdate: string = '';
accessor latestStatusUpdate: string = '';
@property({ type: Boolean })
public enableSubscribe: boolean = false;
accessor enableSubscribe: boolean = false;
@property({ type: Boolean })
public enableReportIssue: boolean = false;
accessor enableReportIssue: boolean = false;
@property({ type: Boolean })
public enableLanguageSelector: boolean = false;
accessor enableLanguageSelector: boolean = false;
@property({ type: Boolean })
public enableThemeToggle: boolean = false;
accessor enableThemeToggle: boolean = false;
@property({ type: Array })
public languageOptions: Array<{ code: string; label: string }> = [];
accessor languageOptions: Array<{ code: string; label: string }> = [];
@property({ type: String })
public currentLanguage: string = 'en';
accessor currentLanguage: string = 'en';
@property({ type: String })
public currentTheme: string = 'light';
accessor currentTheme: string = 'light';
@property({ type: Number })
public subscriberCount: number = 0;
accessor subscriberCount: number = 0;
@property({ type: Object })
public customBranding: { primaryColor?: string; logoUrl?: string; footerText?: string } | null = null;
accessor customBranding: { primaryColor?: string; logoUrl?: string; footerText?: string } | null = null;
constructor() {
@@ -94,53 +94,53 @@ export class UplStatuspageFooter extends DeesElement {
public static styles = [
domtools.elementBasic.staticStyles,
commonStyles,
sharedStyles.commonStyles,
css`
:host {
display: block;
background: ${colors.background.primary};
font-family: ${unsafeCSS(fonts.base)};
color: ${colors.text.primary};
background: ${sharedStyles.colors.background.primary};
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
color: ${sharedStyles.colors.text.primary};
font-size: 14px;
border-top: 1px solid ${colors.border.default};
border-top: 1px solid ${sharedStyles.colors.border.default};
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: ${unsafeCSS(spacing['2xl'])} ${unsafeCSS(spacing.lg)};
padding: ${unsafeCSS(sharedStyles.spacing['2xl'])} ${unsafeCSS(sharedStyles.spacing.lg)};
}
.footer-content {
display: flex;
flex-direction: column;
gap: ${unsafeCSS(spacing.xl)};
gap: ${unsafeCSS(sharedStyles.spacing.xl)};
}
.footer-main {
display: flex;
justify-content: space-between;
align-items: start;
gap: ${unsafeCSS(spacing['2xl'])};
gap: ${unsafeCSS(sharedStyles.spacing['2xl'])};
}
.company-info {
display: flex;
flex-direction: column;
gap: ${unsafeCSS(spacing.lg)};
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
}
.company-name {
font-size: 16px;
font-weight: 500;
color: ${colors.text.primary};
color: ${sharedStyles.colors.text.primary};
letter-spacing: -0.01em;
}
.company-links {
display: flex;
flex-wrap: wrap;
gap: ${unsafeCSS(spacing.lg)};
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
}
.footer-link {
@@ -152,15 +152,15 @@ export class UplStatuspageFooter extends DeesElement {
}
.footer-link:hover {
color: ${colors.text.primary};
color: ${sharedStyles.colors.text.primary};
}
.footer-actions {
display: flex;
flex-direction: column;
gap: ${unsafeCSS(spacing.md)};
gap: ${unsafeCSS(sharedStyles.spacing.md)};
}
.action-button {
padding: 8px 16px;
height: 36px;
@@ -173,8 +173,8 @@ export class UplStatuspageFooter extends DeesElement {
white-space: nowrap;
font-size: 13px;
font-weight: 400;
color: ${colors.text.primary};
font-family: ${unsafeCSS(fonts.base)};
color: ${sharedStyles.colors.text.primary};
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
display: inline-flex;
align-items: center;
justify-content: center;
@@ -189,21 +189,21 @@ export class UplStatuspageFooter extends DeesElement {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: ${unsafeCSS(spacing.lg)};
margin-top: ${unsafeCSS(spacing.lg)};
padding-top: ${unsafeCSS(sharedStyles.spacing.lg)};
margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
border-top: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
}
.footer-meta {
display: flex;
gap: ${unsafeCSS(spacing.lg)};
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
align-items: center;
flex-wrap: wrap;
}
.social-links {
display: flex;
gap: ${unsafeCSS(spacing.md)};
gap: ${unsafeCSS(sharedStyles.spacing.md)};
align-items: center;
}
@@ -219,7 +219,7 @@ export class UplStatuspageFooter extends DeesElement {
}
.social-link:hover {
color: ${colors.text.primary};
color: ${sharedStyles.colors.text.primary};
background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
}
@@ -252,57 +252,57 @@ export class UplStatuspageFooter extends DeesElement {
}
.powered-by a:hover {
color: ${colors.text.primary};
color: ${sharedStyles.colors.text.primary};
}
.status-update {
padding: 12px 16px;
background: ${cssManager.bdTheme('#f9fafb', '#18181b')};
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
border-radius: 6px;
font-size: 13px;
margin-bottom: ${unsafeCSS(spacing.lg)};
margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
line-height: 1.5;
color: ${cssManager.bdTheme('#4b5563', '#d1d5db')};
}
.language-selector {
position: relative;
}
.language-selector select {
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.sm)};
border: 1px solid ${colors.border.default};
background: ${colors.background.primary};
color: ${colors.text.primary};
border-radius: ${unsafeCSS(borderRadius.base)};
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.sm)};
border: 1px solid ${sharedStyles.colors.border.default};
background: ${sharedStyles.colors.background.primary};
color: ${sharedStyles.colors.text.primary};
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
font-size: 14px;
cursor: pointer;
font-family: ${unsafeCSS(fonts.base)};
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
}
.theme-toggle {
cursor: pointer;
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.sm)};
border: 1px solid ${colors.border.default};
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.sm)};
border: 1px solid ${sharedStyles.colors.border.default};
background: transparent;
border-radius: ${unsafeCSS(borderRadius.base)};
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
font-size: 14px;
transition: all 0.2s ease;
color: ${colors.text.primary};
font-family: ${unsafeCSS(fonts.base)};
color: ${sharedStyles.colors.text.primary};
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
}
.theme-toggle:hover {
background: ${colors.background.secondary};
border-color: ${colors.border.muted};
background: ${sharedStyles.colors.background.secondary};
border-color: ${sharedStyles.colors.border.muted};
}
.subscribe-wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: ${unsafeCSS(spacing.xs)};
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
}
.subscriber-count {
@@ -311,27 +311,27 @@ export class UplStatuspageFooter extends DeesElement {
}
.error-message {
padding: ${unsafeCSS(spacing.md)};
padding: ${unsafeCSS(sharedStyles.spacing.md)};
background: ${cssManager.bdTheme('#fee9e9', '#7f1d1d')};
color: ${cssManager.bdTheme('#dc2626', '#fca5a5')};
border-radius: ${unsafeCSS(borderRadius.base)};
margin-bottom: ${unsafeCSS(spacing.lg)};
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
font-size: 14px;
border: 1px solid ${cssManager.bdTheme('#fecaca', '#991b1b')};
}
.offline-indicator {
display: inline-flex;
align-items: center;
gap: ${unsafeCSS(spacing.xs)};
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.md)};
background: ${colors.status.degraded};
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.md)};
background: ${sharedStyles.colors.status.degraded};
color: white;
border-radius: ${unsafeCSS(borderRadius.full)};
border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
font-size: 13px;
font-weight: 500;
}
.loading-skeleton {
height: 200px;
background: ${cssManager.bdTheme(
@@ -340,7 +340,7 @@ export class UplStatuspageFooter extends DeesElement {
)};
background-size: 200% 100%;
animation: loading 1.5s infinite;
border-radius: ${unsafeCSS(borderRadius.md)};
border-radius: ${unsafeCSS(sharedStyles.borderRadius.md)};
}
@keyframes loading {
@@ -351,48 +351,48 @@ export class UplStatuspageFooter extends DeesElement {
.additional-links {
display: flex;
flex-wrap: wrap;
gap: ${unsafeCSS(spacing.md)};
margin-top: ${unsafeCSS(spacing.md)};
gap: ${unsafeCSS(sharedStyles.spacing.md)};
margin-top: ${unsafeCSS(sharedStyles.spacing.md)};
}
.additional-link {
font-size: 13px;
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
text-decoration: none;
transition: color 0.15s ease;
}
.additional-link:hover {
color: ${colors.text.primary};
color: ${sharedStyles.colors.text.primary};
}
@media (max-width: 640px) {
.container {
padding: ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.md)};
padding: ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.md)};
}
.footer-main {
flex-direction: column;
gap: ${unsafeCSS(spacing.lg)};
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
}
.footer-bottom {
flex-direction: column;
gap: ${unsafeCSS(spacing.lg)};
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
align-items: start;
}
.footer-meta {
flex-direction: column;
align-items: start;
gap: ${unsafeCSS(spacing.md)};
gap: ${unsafeCSS(sharedStyles.spacing.md)};
}
.company-links {
flex-direction: column;
gap: ${unsafeCSS(spacing.sm)};
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
}
.powered-by {
text-align: left;
}