feat(statuspage): refactor shared styles and modernize components for consistent theming, spacing and APIs
This commit is contained in:
10
changelog.md
10
changelog.md
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-12-23 - 1.1.0 - feat(statuspage)
|
||||
refactor shared styles and modernize components for consistent theming, spacing and APIs
|
||||
|
||||
- Centralized styles: switch to a single sharedStyles module and extend design tokens (colors, spacing, shadows, borderRadius, easings, durations, accent colors).
|
||||
- Component modernization: replace many destructured style imports with sharedStyles and convert numerous @property fields to 'accessor' for updated component APIs.
|
||||
- Visual/layout updates: adjust typography, spacing scale, responsive rules and polish header/statusbar/footer/stats/incident components (improved gaps, paddings, status pills, loading skeletons, and button styles).
|
||||
- Dependency bumps: updated @design.estate and @git.zone packages as well as @push.rocks dev deps and @types/node.
|
||||
- Build/config changes: tsconfig.json flags removed (experimentalDecorators, useDefineForClassFields) and npmextra.json updated with registry/release config and new package keys.
|
||||
- Docs and demos: expanded README content and added demo/test files (test/test.ts, test-shadcn-spacing.html) to showcase spacing and layout changes.
|
||||
|
||||
## 2024-06-27 - 1.0.74 - fix(core)
|
||||
Updated font loading strategy in index.html for improved performance
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"gitzone": {
|
||||
"@git.zone/cli": {
|
||||
"projectType": "wcc",
|
||||
"module": {
|
||||
"githost": "code.foss.global",
|
||||
@@ -23,11 +23,17 @@
|
||||
"UI",
|
||||
"catalog"
|
||||
]
|
||||
},
|
||||
"release": {
|
||||
"registries": [
|
||||
"https://verdaccio.lossless.digital",
|
||||
"https://registry.npmjs.org"
|
||||
],
|
||||
"accessLevel": "public"
|
||||
}
|
||||
},
|
||||
"npmci": {
|
||||
"@ship.zone/szci": {
|
||||
"npmGlobalTools": [],
|
||||
"npmAccessLevel": "private",
|
||||
"npmRegistryUrl": "verdaccio.lossless.one"
|
||||
}
|
||||
}
|
||||
20
package.json
20
package.json
@@ -15,19 +15,19 @@
|
||||
"author": "Lossless GmbH",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@design.estate/dees-domtools": "^2.3.3",
|
||||
"@design.estate/dees-element": "^2.0.45",
|
||||
"@design.estate/dees-wcctools": "^1.1.0",
|
||||
"@design.estate/dees-domtools": "^2.3.6",
|
||||
"@design.estate/dees-element": "^2.1.3",
|
||||
"@design.estate/dees-wcctools": "^3.2.0",
|
||||
"@uptime.link/interfaces": "^2.0.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^2.6.4",
|
||||
"@git.zone/tsbundle": "^2.5.1",
|
||||
"@git.zone/tsrun": "^1.3.3",
|
||||
"@git.zone/tswatch": "^2.1.2",
|
||||
"@push.rocks/projectinfo": "^5.0.1",
|
||||
"@push.rocks/smartenv": "^5.0.0",
|
||||
"@types/node": "^24.0.7"
|
||||
"@git.zone/tsbuild": "^4.0.2",
|
||||
"@git.zone/tsbundle": "^2.6.3",
|
||||
"@git.zone/tsrun": "^2.0.1",
|
||||
"@git.zone/tswatch": "^2.3.13",
|
||||
"@push.rocks/projectinfo": "^5.0.2",
|
||||
"@push.rocks/smartenv": "^6.0.0",
|
||||
"@types/node": "^25.0.3"
|
||||
},
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
|
||||
5310
pnpm-lock.yaml
generated
5310
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
497
readme.md
497
readme.md
@@ -1,205 +1,382 @@
|
||||
# @uptime.link/statuspage
|
||||
a catalog with webcomponents for uptimelink dashboard
|
||||
|
||||
## Install
|
||||
🚀 **A powerful collection of web components for building stunning status pages** — because your users deserve to know what's happening, and you deserve to look good while telling them.
|
||||
|
||||
To install the `@uptime.link/statuspage` module, you can use npm. Make sure you have Node.js and npm installed, then run:
|
||||
Built with [Lit](https://lit.dev/) and TypeScript, these components are designed to be composable, customizable, and production-ready out of the box.
|
||||
|
||||
```sh
|
||||
## Issue Reporting and Security
|
||||
|
||||
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
||||
|
||||
---
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- 🎨 **Themeable** — Automatic light/dark mode support with CSS custom properties
|
||||
- 📱 **Responsive** — Looks great on everything from mobile to ultrawide
|
||||
- 🔌 **Composable** — Use components individually or build complete status pages
|
||||
- 🎯 **Type-Safe** — Full TypeScript support with exported interfaces
|
||||
- ⚡ **Performant** — Lit-based components with minimal overhead
|
||||
- 🎭 **Pre-built Pages** — Demo, all-green, outage, and maintenance page templates included
|
||||
|
||||
---
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
```bash
|
||||
npm install @uptime.link/statuspage
|
||||
```
|
||||
|
||||
## Usage
|
||||
Or with pnpm:
|
||||
|
||||
The `@uptime.link/statuspage` module provides a collection of web components to build a comprehensive status page for Uptime.link dashboards. This includes headers, status bars, asset selectors, status details, incident lists, and more.
|
||||
```bash
|
||||
pnpm add @uptime.link/statuspage
|
||||
```
|
||||
|
||||
Here’s a detailed guide on how to use each component in your TypeScript project with ESM syntax. We will walk through creating a complete status page using the provided components.
|
||||
---
|
||||
|
||||
### Step-by-Step Example
|
||||
## 🚀 Quick Start
|
||||
|
||||
1. **Setup Your Project:**
|
||||
Import the components and start building:
|
||||
|
||||
Ensure you have a TypeScript project setup. Here's a minimal `tsconfig.json` to get started:
|
||||
```typescript
|
||||
import '@uptime.link/statuspage';
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
Then use them in your HTML:
|
||||
|
||||
```html
|
||||
<upl-statuspage-header></upl-statuspage-header>
|
||||
<upl-statuspage-statusbar></upl-statuspage-statusbar>
|
||||
<upl-statuspage-incidents></upl-statuspage-incidents>
|
||||
<upl-statuspage-footer></upl-statuspage-footer>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Components
|
||||
|
||||
### `<upl-statuspage-header>`
|
||||
|
||||
The main navigation header with branding and action buttons.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `pageTitle` | `string` | `'Status'` | Title displayed in the header |
|
||||
| `logoUrl` | `string` | `''` | URL to your logo image |
|
||||
| `showReportButton` | `boolean` | `false` | Show "Report Incident" button |
|
||||
| `showSubscribeButton` | `boolean` | `false` | Show "Subscribe" button |
|
||||
|
||||
**Events:**
|
||||
- `reportNewIncident` — Fired when report button is clicked
|
||||
- `statusSubscribe` — Fired when subscribe button is clicked
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-pagetitle>`
|
||||
|
||||
A hero section with title and subtitle.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `pageTitle` | `string` | `'System Status'` | Main heading |
|
||||
| `pageSubtitle` | `string` | `''` | Optional description text |
|
||||
| `centered` | `boolean` | `false` | Center-align the content |
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-statusbar>`
|
||||
|
||||
The overall status indicator — the heart of any status page.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `overallStatus` | `IOverallStatus` | — | Current system status object |
|
||||
| `loading` | `boolean` | `false` | Show loading skeleton |
|
||||
|
||||
The status object supports: `operational`, `degraded`, `partial_outage`, `major_outage`, `maintenance`
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-statsgrid>`
|
||||
|
||||
Key metrics at a glance — uptime, response time, incidents.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `currentStatus` | `string` | `'operational'` | Current status indicator |
|
||||
| `uptime` | `number` | `100` | Uptime percentage |
|
||||
| `avgResponseTime` | `number` | `0` | Average response time (ms) |
|
||||
| `totalIncidents` | `number` | `0` | Incident count |
|
||||
| `affectedServices` | `number` | `0` | Currently affected services |
|
||||
| `totalServices` | `number` | `0` | Total monitored services |
|
||||
| `timePeriod` | `string` | `'30 days'` | Time range label |
|
||||
| `loading` | `boolean` | `false` | Show loading skeleton |
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-assetsselector>`
|
||||
|
||||
Interactive service selector with filtering and search.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `services` | `IServiceStatus[]` | `[]` | Array of service objects |
|
||||
| `filterText` | `string` | `''` | Search filter text |
|
||||
| `filterCategory` | `string` | `'all'` | Category filter |
|
||||
| `showOnlySelected` | `boolean` | `false` | Show only selected services |
|
||||
| `loading` | `boolean` | `false` | Show loading state |
|
||||
| `expanded` | `boolean` | `false` | Expand the selector panel |
|
||||
|
||||
**Events:**
|
||||
- `selectionChanged` — Fired with `{ selectedServices: string[] }` when selection changes
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-statusdetails>`
|
||||
|
||||
Hourly status timeline visualization.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `dataPoints` | `IStatusHistoryPoint[]` | `[]` | Hourly status data |
|
||||
| `historyData` | `IStatusHistoryPoint[]` | `[]` | Alternative data property |
|
||||
| `serviceId` | `string` | `''` | Service identifier |
|
||||
| `serviceName` | `string` | `'Service'` | Display name |
|
||||
| `hoursToShow` | `number` | `48` | Number of hours to display |
|
||||
| `loading` | `boolean` | `false` | Show loading skeleton |
|
||||
|
||||
**Events:**
|
||||
- `barClick` — Fired with `{ timestamp, status, responseTime, serviceId }` on bar click
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-statusmonth>`
|
||||
|
||||
Calendar-style monthly uptime visualization.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `monthlyData` | `IMonthlyUptime[]` | `[]` | Monthly uptime data |
|
||||
| `serviceId` | `string` | `'all'` | Service identifier |
|
||||
| `serviceName` | `string` | `'All Services'` | Display name |
|
||||
| `loading` | `boolean` | `false` | Show loading skeleton |
|
||||
|
||||
**Events:**
|
||||
- `dayClick` — Fired with day details when a day cell is clicked
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-incidents>`
|
||||
|
||||
Incident feed with expandable details and status updates.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `currentIncidents` | `IIncidentDetails[]` | `[]` | Active incidents |
|
||||
| `pastIncidents` | `IIncidentDetails[]` | `[]` | Resolved incidents |
|
||||
| `maxPastIncidents` | `number` | `10` | Max past incidents to show |
|
||||
| `loading` | `boolean` | `false` | Show loading skeleton |
|
||||
| `enableSubscription` | `boolean` | `false` | Allow incident subscriptions |
|
||||
| `subscribedIncidentIds` | `string[]` | `[]` | Pre-subscribed incident IDs |
|
||||
|
||||
**Events:**
|
||||
- `subscribeToIncident` — Fired with incident ID on subscription toggle
|
||||
|
||||
---
|
||||
|
||||
### `<upl-statuspage-footer>`
|
||||
|
||||
Full-featured footer with links, social icons, and subscription.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `companyName` | `string` | `''` | Company name |
|
||||
| `legalUrl` | `string` | `''` | Terms/legal page URL |
|
||||
| `supportEmail` | `string` | `''` | Support email address |
|
||||
| `statusPageUrl` | `string` | `''` | Status page URL |
|
||||
| `lastUpdated` | `number` | — | Last update timestamp |
|
||||
| `currentYear` | `number` | `2024` | Copyright year |
|
||||
| `socialLinks` | `ISocialLink[]` | `[]` | Social media links |
|
||||
| `rssFeedUrl` | `string` | `''` | RSS feed URL |
|
||||
| `apiStatusUrl` | `string` | `''` | Status API URL |
|
||||
| `enableSubscribe` | `boolean` | `false` | Show subscribe button |
|
||||
| `subscriberCount` | `number` | `0` | Display subscriber count |
|
||||
| `additionalLinks` | `IFooterLink[]` | `[]` | Extra footer links |
|
||||
|
||||
**Events:**
|
||||
- `subscribeClick` — Fired when subscribe button is clicked
|
||||
|
||||
---
|
||||
|
||||
## 📐 Interfaces
|
||||
|
||||
All TypeScript interfaces are exported for type safety:
|
||||
|
||||
```typescript
|
||||
import type {
|
||||
IServiceStatus,
|
||||
IStatusHistoryPoint,
|
||||
IIncidentDetails,
|
||||
IIncidentUpdate,
|
||||
IMonthlyUptime,
|
||||
IUptimeDay,
|
||||
IOverallStatus,
|
||||
IStatusPageConfig,
|
||||
ISubscription
|
||||
} from '@uptime.link/statuspage';
|
||||
```
|
||||
|
||||
### Key Interfaces
|
||||
|
||||
```typescript
|
||||
interface IServiceStatus {
|
||||
id: string;
|
||||
name: string;
|
||||
displayName: string;
|
||||
description?: string;
|
||||
currentStatus: 'operational' | 'degraded' | 'partial_outage' | 'major_outage' | 'maintenance';
|
||||
lastChecked: number;
|
||||
uptime30d: number;
|
||||
uptime90d: number;
|
||||
responseTime: number;
|
||||
category?: string;
|
||||
selected?: boolean;
|
||||
}
|
||||
|
||||
interface IIncidentDetails {
|
||||
id: string;
|
||||
title: string;
|
||||
status: 'investigating' | 'identified' | 'monitoring' | 'resolved' | 'postmortem';
|
||||
severity: 'critical' | 'major' | 'minor' | 'maintenance';
|
||||
affectedServices: string[];
|
||||
startTime: number;
|
||||
endTime?: number;
|
||||
updates: IIncidentUpdate[];
|
||||
impact: string;
|
||||
rootCause?: string;
|
||||
resolution?: string;
|
||||
}
|
||||
|
||||
interface IOverallStatus {
|
||||
status: 'operational' | 'degraded' | 'partial_outage' | 'major_outage' | 'maintenance';
|
||||
message: string;
|
||||
lastUpdated: number;
|
||||
affectedServices: number;
|
||||
totalServices: number;
|
||||
}
|
||||
```
|
||||
|
||||
2. **Import Components:**
|
||||
---
|
||||
|
||||
Create an `index.ts` file, and import the components you need:
|
||||
## 🎬 Complete Example
|
||||
|
||||
Build a full status page in minutes:
|
||||
|
||||
```typescript
|
||||
import './elements/index.js';
|
||||
import { page1 } from './pages/index.js';
|
||||
```
|
||||
import '@uptime.link/statuspage';
|
||||
import type { IServiceStatus, IOverallStatus, IIncidentDetails } from '@uptime.link/statuspage';
|
||||
|
||||
3. **Creating a Status Page:**
|
||||
// Get your components
|
||||
const header = document.querySelector('upl-statuspage-header');
|
||||
const statusBar = document.querySelector('upl-statuspage-statusbar');
|
||||
const statsGrid = document.querySelector('upl-statuspage-statsgrid');
|
||||
const incidents = document.querySelector('upl-statuspage-incidents');
|
||||
const footer = document.querySelector('upl-statuspage-footer');
|
||||
|
||||
Here, we'll create a simple status page using the imported components. We'll create individual components like headers, status bars, footers, etc., and combine them into a single page.
|
||||
// Configure the header
|
||||
header.pageTitle = 'Acme Cloud';
|
||||
header.logoUrl = '/logo.svg';
|
||||
header.showSubscribeButton = true;
|
||||
|
||||
### UplStatuspageHeader
|
||||
// Set overall status
|
||||
statusBar.overallStatus = {
|
||||
status: 'operational',
|
||||
message: 'All systems operational',
|
||||
lastUpdated: Date.now(),
|
||||
affectedServices: 0,
|
||||
totalServices: 12
|
||||
};
|
||||
|
||||
```typescript
|
||||
import { UplStatuspageHeader } from './elements/upl-statuspage-header.js';
|
||||
// Configure stats
|
||||
statsGrid.uptime = 99.98;
|
||||
statsGrid.avgResponseTime = 45;
|
||||
statsGrid.totalServices = 12;
|
||||
|
||||
const header: UplStatuspageHeader = document.createElement('upl-statuspage-header');
|
||||
header.pageTitle = "Uptime Link Status Page";
|
||||
document.body.appendChild(header);
|
||||
```
|
||||
|
||||
### UplStatuspageStatusbar
|
||||
|
||||
```typescript
|
||||
import { UplStatuspageStatusbar } from './elements/upl-statuspage-statusbar.js';
|
||||
|
||||
const statusBar: UplStatuspageStatusbar = document.createElement('upl-statuspage-statusbar');
|
||||
document.body.appendChild(statusBar);
|
||||
```
|
||||
|
||||
### UplStatuspageAssetsselector
|
||||
|
||||
```typescript
|
||||
import { UplStatuspageAssetsselector } from './elements/upl-statuspage-assetsselector.js';
|
||||
|
||||
const assetsSelector: UplStatuspageAssetsselector = document.createElement('upl-statuspage-assetsselector');
|
||||
document.body.appendChild(assetsSelector);
|
||||
```
|
||||
|
||||
### UplStatuspageStatusdetails
|
||||
|
||||
```typescript
|
||||
import { UplStatuspageStatusdetails } from './elements/upl-statuspage-statusdetails.js';
|
||||
|
||||
const statusDetails: UplStatuspageStatusdetails = document.createElement('upl-statuspage-statusdetails');
|
||||
document.body.appendChild(statusDetails);
|
||||
```
|
||||
|
||||
### UplStatuspageStatusmonth
|
||||
|
||||
```typescript
|
||||
import { UplStatuspageStatusmonth } from './elements/upl-statuspage-statusmonth.js';
|
||||
|
||||
const statusMonth: UplStatuspageStatusmonth = document.createElement('upl-statuspage-statusmonth');
|
||||
document.body.appendChild(statusMonth);
|
||||
```
|
||||
|
||||
### UplStatuspageIncidents
|
||||
|
||||
```typescript
|
||||
import { UplStatuspageIncidents } from './elements/upl-statuspage-incidents.js';
|
||||
import { uplInterfaces } from './plugins.js';
|
||||
|
||||
const incidents: UplStatuspageIncidents = document.createElement('upl-statuspage-incidents');
|
||||
incidents.currentIncidences = [
|
||||
// Example incident data
|
||||
// Add incidents
|
||||
incidents.currentIncidents = []; // No current incidents
|
||||
incidents.pastIncidents = [
|
||||
{
|
||||
id: "incident1",
|
||||
title: "Server Outage",
|
||||
description: "There was an outage on the main server.",
|
||||
status: "resolved",
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString()
|
||||
id: 'inc-001',
|
||||
title: 'Scheduled Maintenance Complete',
|
||||
status: 'resolved',
|
||||
severity: 'maintenance',
|
||||
impact: 'Database maintenance window',
|
||||
affectedServices: ['Database'],
|
||||
startTime: Date.now() - 86400000,
|
||||
endTime: Date.now() - 82800000,
|
||||
updates: [
|
||||
{
|
||||
id: 'upd-1',
|
||||
timestamp: Date.now() - 82800000,
|
||||
status: 'resolved',
|
||||
message: 'Maintenance completed successfully'
|
||||
}
|
||||
]
|
||||
}
|
||||
] as uplInterfaces.IIncident[];
|
||||
];
|
||||
|
||||
incidents.pastIncidences = [
|
||||
// Example past incident data
|
||||
{
|
||||
id: "incident2",
|
||||
title: "Database Maintenance",
|
||||
description: "Scheduled maintenance on the database.",
|
||||
status: "completed",
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString()
|
||||
}
|
||||
] as uplInterfaces.IIncident[];
|
||||
|
||||
document.body.appendChild(incidents);
|
||||
// Configure footer
|
||||
footer.companyName = 'Acme Cloud';
|
||||
footer.supportEmail = 'support@acme.cloud';
|
||||
footer.enableSubscribe = true;
|
||||
```
|
||||
|
||||
### UplStatuspageFooter
|
||||
---
|
||||
|
||||
## 📄 Pre-built Page Templates
|
||||
|
||||
The package includes ready-to-use page templates:
|
||||
|
||||
```typescript
|
||||
import { UplStatuspageFooter } from './elements/upl-statuspage-footer.js';
|
||||
|
||||
const footer: UplStatuspageFooter = document.createElement('upl-statuspage-footer');
|
||||
footer.legalInfo = "https://example.com/legal";
|
||||
document.body.appendChild(footer);
|
||||
import {
|
||||
statuspageDemo, // Full demo with sample data
|
||||
statuspageAllgreen, // All systems operational
|
||||
statuspageOutage, // Major outage scenario
|
||||
statuspageMaintenance // Scheduled maintenance
|
||||
} from '@uptime.link/statuspage/pages';
|
||||
```
|
||||
|
||||
### Full Example
|
||||
---
|
||||
|
||||
Here’s how you can put it all together to create a full status page:
|
||||
## 🎨 Theming
|
||||
|
||||
```typescript
|
||||
import './elements/index.js';
|
||||
import { page1 } from './pages/index.js';
|
||||
import { UplStatuspageHeader } from './elements/upl-statuspage-header.js';
|
||||
import { UplStatuspageStatusbar } from './elements/upl-statuspage-statusbar.js';
|
||||
import { UplStatuspageAssetsselector } from './elements/upl-statuspage-assetsselector.js';
|
||||
import { UplStatuspageStatusdetails } from './elements/upl-statuspage-statusdetails.js';
|
||||
import { UplStatuspageStatusmonth } from './elements/upl-statuspage-statusmonth.js';
|
||||
import { UplStatuspageIncidents } from './elements/upl-statuspage-incidents.js';
|
||||
import { UplStatuspageFooter } from './elements/upl-statuspage-footer.js';
|
||||
import { uplInterfaces } from './plugins.js';
|
||||
Components automatically adapt to light/dark mode using `cssManager.bdTheme()`. The design follows a modern, minimal aesthetic with:
|
||||
|
||||
const header: UplStatuspageHeader = document.createElement('upl-statuspage-header');
|
||||
header.pageTitle = "Uptime Link Status Page";
|
||||
document.body.appendChild(header);
|
||||
- Clean typography with `-apple-system, BlinkMacSystemFont, 'Segoe UI'` font stack
|
||||
- Subtle shadows and borders
|
||||
- Semantic status colors (green, yellow, orange, red, blue)
|
||||
- Smooth transitions and hover states
|
||||
|
||||
const statusBar: UplStatuspageStatusbar = document.createElement('upl-statuspage-statusbar');
|
||||
document.body.appendChild(statusBar);
|
||||
---
|
||||
|
||||
const assetsSelector: UplStatuspageAssetsselector = document.createElement('upl-statuspage-assetsselector');
|
||||
document.body.appendChild(assetsSelector);
|
||||
## License and Legal Information
|
||||
|
||||
const statusDetails: UplStatuspageStatusdetails = document.createElement('upl-statuspage-statusdetails');
|
||||
document.body.appendChild(statusDetails);
|
||||
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
|
||||
|
||||
const statusMonth: UplStatuspageStatusmonth = document.createElement('upl-statuspage-statusmonth');
|
||||
document.body.appendChild(statusMonth);
|
||||
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||||
|
||||
const incidents: UplStatuspageIncidents = document.createElement('upl-statuspage-incidents');
|
||||
incidents.currentIncidences = [
|
||||
{
|
||||
id: "incident1",
|
||||
title: "Server Outage",
|
||||
description: "There was an outage on the main server.",
|
||||
status: "resolved",
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString()
|
||||
}
|
||||
] as uplInterfaces.IIncident[];
|
||||
### Trademarks
|
||||
|
||||
incidents.pastIncidences = [
|
||||
{
|
||||
id: "incident2",
|
||||
title: "Database Maintenance",
|
||||
description: "Scheduled maintenance on the database.",
|
||||
status: "completed",
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString()
|
||||
}
|
||||
] as uplInterfaces.IIncident[];
|
||||
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
|
||||
|
||||
document.body.appendChild(incidents);
|
||||
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
|
||||
|
||||
const footer: UplStatuspageFooter = document.createElement('upl-statuspage-footer');
|
||||
footer.legalInfo = "https://example.com/legal";
|
||||
document.body.appendChild(footer);
|
||||
```
|
||||
### Company Information
|
||||
|
||||
This example uses all the components provided by `@uptime.link/statuspage` to create a functional status page. Modify the data, styles, and structure to suit your requirements.
|
||||
undefined
|
||||
Task Venture Capital GmbH
|
||||
Registered at District Court Bremen HRB 35230 HB, Germany
|
||||
|
||||
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
||||
|
||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
||||
|
||||
175
test-shadcn-spacing.html
Normal file
175
test-shadcn-spacing.html
Normal file
@@ -0,0 +1,175 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>shadcn-Aligned Spacing Test</title>
|
||||
<script type="module" src="./dist_bundle/bundle.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Geist Sans', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
background: #fafafa;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background: #09090b;
|
||||
}
|
||||
}
|
||||
.demo-wrapper {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px; /* Using consistent spacing between components */
|
||||
}
|
||||
.spacing-info {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
font-size: 13px;
|
||||
max-width: 300px;
|
||||
z-index: 1000;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.spacing-info {
|
||||
background: rgba(18, 18, 18, 0.9);
|
||||
border-color: #27272a;
|
||||
}
|
||||
}
|
||||
.spacing-info h3 {
|
||||
margin: 0 0 12px 0;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.spacing-info ul {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.spacing-info code {
|
||||
background: #f3f4f6;
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.spacing-info code {
|
||||
background: #27272a;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="demo-wrapper">
|
||||
<upl-statuspage-header
|
||||
page-title="CloudFlow"
|
||||
show-report-button="true"
|
||||
show-subscribe-button="true"
|
||||
></upl-statuspage-header>
|
||||
|
||||
<upl-statuspage-pagetitle
|
||||
page-title="Service Status"
|
||||
page-subtitle="Current operational status of CloudFlow Infrastructure services"
|
||||
></upl-statuspage-pagetitle>
|
||||
|
||||
<upl-statuspage-statusbar id="statusbar"></upl-statuspage-statusbar>
|
||||
|
||||
<upl-statuspage-statsgrid
|
||||
current-status="operational"
|
||||
uptime="99.95"
|
||||
avg-response-time="125"
|
||||
total-incidents="2"
|
||||
></upl-statuspage-statsgrid>
|
||||
|
||||
<upl-statuspage-assetsselector id="assets"></upl-statuspage-assetsselector>
|
||||
|
||||
<upl-statuspage-statusdetails id="details"></upl-statuspage-statusdetails>
|
||||
|
||||
<upl-statuspage-statusmonth id="month"></upl-statuspage-statusmonth>
|
||||
|
||||
<upl-statuspage-incidents id="incidents"></upl-statuspage-incidents>
|
||||
|
||||
<upl-statuspage-footer
|
||||
company-name="CloudFlow Infrastructure"
|
||||
enable-subscribe="true"
|
||||
subscriber-count="1234"
|
||||
></upl-statuspage-footer>
|
||||
</div>
|
||||
|
||||
<div class="spacing-info">
|
||||
<h3>shadcn Spacing Improvements</h3>
|
||||
<ul>
|
||||
<li>Page title padding reduced from <code>48px</code> to <code>24px</code></li>
|
||||
<li>Mini-heading padding reduced from <code>16px</code> to <code>8px</code></li>
|
||||
<li>All arbitrary values replaced with spacing scale</li>
|
||||
<li>Consistent <code>24px</code> gap between components</li>
|
||||
<li>More compact, professional layout</li>
|
||||
<li>Follows shadcn's minimal spacing approach</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const statusbar = document.getElementById('statusbar');
|
||||
const assets = document.getElementById('assets');
|
||||
const details = document.getElementById('details');
|
||||
const month = document.getElementById('month');
|
||||
const incidents = document.getElementById('incidents');
|
||||
|
||||
// Configure status bar
|
||||
statusbar.overallStatus = {
|
||||
status: 'operational',
|
||||
message: 'All systems operational',
|
||||
lastUpdated: Date.now()
|
||||
};
|
||||
|
||||
// Configure services
|
||||
const services = [
|
||||
{
|
||||
id: 'api',
|
||||
name: 'API Gateway',
|
||||
displayName: 'API Gateway',
|
||||
currentStatus: 'operational',
|
||||
uptime30d: 99.99,
|
||||
category: 'Core Services',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 'database',
|
||||
name: 'Database Cluster',
|
||||
displayName: 'Database Cluster',
|
||||
currentStatus: 'operational',
|
||||
uptime30d: 99.95,
|
||||
category: 'Core Services',
|
||||
selected: true
|
||||
}
|
||||
];
|
||||
|
||||
assets.services = services;
|
||||
details.services = services;
|
||||
|
||||
// Configure monthly data
|
||||
month.monthlyData = [{
|
||||
month: '2024-01',
|
||||
days: Array(31).fill(null).map((_, i) => ({
|
||||
date: `2024-01-${String(i + 1).padStart(2, '0')}`,
|
||||
uptime: 100,
|
||||
incidents: 0
|
||||
})),
|
||||
overallUptime: 100,
|
||||
totalIncidents: 0
|
||||
}];
|
||||
|
||||
// Configure incidents
|
||||
incidents.currentIncidents = [];
|
||||
incidents.pastIncidents = [];
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1
test/test.ts
Normal file
1
test/test.ts
Normal file
@@ -0,0 +1 @@
|
||||
console.log('hello');
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@uptime.link/statuspage',
|
||||
version: '1.0.74',
|
||||
version: '1.1.0',
|
||||
description: 'A catalog of web components for the UptimeLink dashboard.'
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { customElement, DeesElement, html, type TemplateResult, css, cssManager, unsafeCSS } from '@design.estate/dees-element';
|
||||
import * as domtools from '@design.estate/dees-domtools';
|
||||
import { fonts, colors, spacing } from '../../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../../styles/shared.styles.js';
|
||||
|
||||
@customElement('uplinternal-miniheading')
|
||||
export class UplinternalMiniheading extends DeesElement {
|
||||
@@ -9,18 +9,18 @@ export class UplinternalMiniheading extends DeesElement {
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
}
|
||||
|
||||
h5 {
|
||||
display: block;
|
||||
max-width: 1200px;
|
||||
margin: 0px auto;
|
||||
padding: 0px 0px ${unsafeCSS(spacing.md)} 0px;
|
||||
color: ${colors.text.secondary};
|
||||
font-size: 14px;
|
||||
padding: 0px 0px ${unsafeCSS(sharedStyles.spacing.sm)} 0px;
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.025em;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
`
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@design.estate/dees-element';
|
||||
import * as domtools from '@design.estate/dees-domtools';
|
||||
import type { IServiceStatus } from '../interfaces/index.js';
|
||||
import { fonts, colors, shadows, borderRadius, spacing, commonStyles, getStatusColor } from '../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../styles/shared.styles.js';
|
||||
|
||||
import './internal/uplinternal-miniheading.js';
|
||||
import { demoFunc } from './upl-statuspage-assetsselector.demo.js';
|
||||
@@ -26,22 +26,22 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@property({ type: Array })
|
||||
public services: IServiceStatus[] = [];
|
||||
accessor services: IServiceStatus[] = [];
|
||||
|
||||
@property({ type: String })
|
||||
public filterText: string = '';
|
||||
accessor filterText: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
public filterCategory: string = 'all';
|
||||
accessor filterCategory: string = 'all';
|
||||
|
||||
@property({ type: Boolean })
|
||||
public showOnlySelected: boolean = false;
|
||||
accessor showOnlySelected: boolean = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public loading: boolean = false;
|
||||
|
||||
accessor loading: boolean = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public expanded: boolean = false;
|
||||
accessor expanded: boolean = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -49,25 +49,25 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
commonStyles,
|
||||
sharedStyles.commonStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
background: transparent;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
color: ${colors.text.primary};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
gap: ${unsafeCSS(spacing.sm)};
|
||||
margin-bottom: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -75,13 +75,13 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
.search-input {
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.sm)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
font-size: 13px;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
transition: all 0.2s ease;
|
||||
height: 32px;
|
||||
}
|
||||
@@ -99,15 +99,15 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.sm)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
background: transparent;
|
||||
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
transition: all 0.2s ease;
|
||||
height: 32px;
|
||||
}
|
||||
@@ -126,83 +126,83 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
.selected-services {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: ${unsafeCSS(spacing.sm)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
.service-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(spacing.xs)};
|
||||
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.full)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
|
||||
font-size: 13px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.service-pill:hover {
|
||||
border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
}
|
||||
|
||||
|
||||
.service-pill .status-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
|
||||
.manage-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(spacing.xs)};
|
||||
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
background: transparent;
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
}
|
||||
|
||||
|
||||
.manage-button:hover {
|
||||
border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
}
|
||||
|
||||
|
||||
.expandable-section {
|
||||
margin-top: ${unsafeCSS(spacing.lg)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
.expandable-content {
|
||||
padding: ${unsafeCSS(spacing.lg)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
}
|
||||
|
||||
|
||||
.assets-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: ${unsafeCSS(spacing.sm)};
|
||||
margin-top: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.asset-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: ${unsafeCSS(spacing.sm)} ${unsafeCSS(spacing.md)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.sm)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
gap: ${unsafeCSS(spacing.sm)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
}
|
||||
|
||||
.asset-card:hover {
|
||||
@@ -218,7 +218,7 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
accent-color: ${colors.text.primary};
|
||||
accent-color: ${sharedStyles.colors.text.primary};
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
.asset-name {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin-bottom: ${unsafeCSS(spacing.xs)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -238,7 +238,7 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
|
||||
.asset-description {
|
||||
font-size: 13px;
|
||||
color: ${colors.text.secondary};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -247,14 +247,14 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
.asset-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(spacing.xs)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: ${unsafeCSS(borderRadius.full)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
|
||||
}
|
||||
|
||||
.status-indicator.operational, .status-dot.operational { background: #22c55e; }
|
||||
@@ -266,14 +266,14 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
.status-text {
|
||||
font-size: 12px;
|
||||
text-transform: capitalize;
|
||||
color: ${colors.text.secondary};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
}
|
||||
|
||||
.loading-message,
|
||||
.no-results {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: ${unsafeCSS(spacing.xl)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xl)};
|
||||
color: ${cssManager.bdTheme('#9ca3af', '#71717a')};
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -281,12 +281,12 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
.summary {
|
||||
text-align: right;
|
||||
font-size: 12px;
|
||||
margin-top: ${unsafeCSS(spacing.md)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
color: ${cssManager.bdTheme('#9ca3af', '#71717a')};
|
||||
}
|
||||
|
||||
|
||||
.no-services {
|
||||
padding: ${unsafeCSS(spacing.xl)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xl)};
|
||||
text-align: center;
|
||||
color: ${cssManager.bdTheme('#9ca3af', '#71717a')};
|
||||
font-size: 13px;
|
||||
@@ -294,7 +294,7 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.controls {
|
||||
@@ -310,21 +310,21 @@ export class UplStatuspageAssetsselector extends DeesElement {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
|
||||
.service-pill {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
|
||||
.expandable-content {
|
||||
padding: ${unsafeCSS(spacing.md)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
|
||||
.assets-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.asset-card {
|
||||
padding: ${unsafeCSS(spacing.sm)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
}
|
||||
}
|
||||
`,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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, shadows } from '../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../styles/shared.styles.js';
|
||||
import { demoFunc } from './upl-statuspage-header.demo.js';
|
||||
|
||||
declare global {
|
||||
@@ -16,19 +16,19 @@ export class UplStatuspageHeader extends DeesElement {
|
||||
|
||||
// INSTANCE
|
||||
@property({ type: String })
|
||||
public pageTitle: string = "Statuspage Title";
|
||||
|
||||
accessor pageTitle: string = "Statuspage Title";
|
||||
|
||||
@property({ type: Boolean })
|
||||
public showReportButton: boolean = true;
|
||||
|
||||
accessor showReportButton: boolean = true;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public showSubscribeButton: boolean = true;
|
||||
|
||||
accessor showSubscribeButton: boolean = true;
|
||||
|
||||
@property({ type: String })
|
||||
public logoUrl: string = '';
|
||||
|
||||
accessor logoUrl: string = '';
|
||||
|
||||
@property({ type: Boolean })
|
||||
public loading: boolean = false;
|
||||
accessor loading: boolean = false;
|
||||
|
||||
|
||||
constructor() {
|
||||
@@ -39,136 +39,193 @@ export class UplStatuspageHeader extends DeesElement {
|
||||
domtools.elementBasic.staticStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 40;
|
||||
}
|
||||
display: block;
|
||||
background: ${sharedStyles.colors.background.primary};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
border-bottom: 1px solid ${sharedStyles.colors.border.default};
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 40;
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.header-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
}
|
||||
|
||||
.actionButton {
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
padding: 0 14px;
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 36px;
|
||||
background: transparent;
|
||||
border: 1px solid ${sharedStyles.colors.border.default};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.actionButton:hover {
|
||||
background: ${sharedStyles.colors.background.secondary};
|
||||
border-color: ${sharedStyles.colors.border.muted};
|
||||
box-shadow: ${unsafeCSS(sharedStyles.shadows.xs)};
|
||||
}
|
||||
|
||||
.actionButton:active {
|
||||
transform: scale(0.98);
|
||||
transition-duration: ${unsafeCSS(sharedStyles.durations.fast)};
|
||||
}
|
||||
|
||||
.actionButton:focus-visible {
|
||||
outline: 2px solid ${sharedStyles.colors.accent.focus};
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 28px;
|
||||
width: auto;
|
||||
filter: ${cssManager.bdTheme('none', 'brightness(0) invert(1)')};
|
||||
transition: opacity ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.page-info {
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)} 0 ${unsafeCSS(sharedStyles.spacing.xl)} 0;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.03em;
|
||||
line-height: 1.1;
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 18px;
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Primary button variant */
|
||||
.actionButton.primary {
|
||||
background: ${sharedStyles.colors.accent.primary};
|
||||
color: ${sharedStyles.colors.background.primary};
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.actionButton.primary:hover {
|
||||
background: ${sharedStyles.colors.accent.hover};
|
||||
box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
|
||||
}
|
||||
|
||||
.loading-skeleton {
|
||||
height: 64px;
|
||||
background: ${sharedStyles.colors.background.secondary};
|
||||
border-bottom: 1px solid ${sharedStyles.colors.border.default};
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.loading-skeleton::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: ${cssManager.bdTheme(
|
||||
'linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.04) 50%, transparent 100%)',
|
||||
'linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.04) 50%, transparent 100%)'
|
||||
)};
|
||||
animation: loading 1.5s ${unsafeCSS(sharedStyles.easings.default)} infinite;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(200%); }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.header-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 24px;
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 64px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.actionButton {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 36px;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
}
|
||||
|
||||
.actionButton:hover {
|
||||
background: ${cssManager.bdTheme('#f4f4f5', '#27272a')};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.02em;
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 24px;
|
||||
width: auto;
|
||||
filter: ${cssManager.bdTheme('none', 'brightness(0) invert(1)')};
|
||||
}
|
||||
|
||||
.page-info {
|
||||
padding: 48px 0 64px 0;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
line-height: 1.1;
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 20px;
|
||||
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Primary button variant */
|
||||
.actionButton.primary {
|
||||
background: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
color: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.actionButton {
|
||||
font-size: 12px;
|
||||
padding: 0 12px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.actionButton.primary:hover {
|
||||
background: ${cssManager.bdTheme('#262626', '#e5e7eb')};
|
||||
border-color: ${cssManager.bdTheme('#262626', '#e5e7eb')};
|
||||
.page-title {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
.loading-skeleton {
|
||||
height: 64px;
|
||||
background: ${cssManager.bdTheme('#f9fafb', '#0a0a0a')};
|
||||
border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.header-nav {
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.actionButton {
|
||||
font-size: 13px;
|
||||
padding: 6px 10px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
gap: 6px;
|
||||
}
|
||||
}
|
||||
`
|
||||
]
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
unsafeCSS,
|
||||
} from '@design.estate/dees-element';
|
||||
import type { IIncidentDetails } from '../interfaces/index.js';
|
||||
import { fonts, colors, shadows, borderRadius, spacing, commonStyles } from '../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../styles/shared.styles.js';
|
||||
import './internal/uplinternal-miniheading.js';
|
||||
import { demoFunc } from './upl-statuspage-incidents.demo.js';
|
||||
|
||||
@@ -29,44 +29,44 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
@property({
|
||||
type: Array,
|
||||
})
|
||||
public currentIncidents: IIncidentDetails[] = [];
|
||||
accessor currentIncidents: IIncidentDetails[] = [];
|
||||
|
||||
@property({
|
||||
type: Array,
|
||||
})
|
||||
public pastIncidents: IIncidentDetails[] = [];
|
||||
accessor pastIncidents: IIncidentDetails[] = [];
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
})
|
||||
public whitelabel = false;
|
||||
accessor whitelabel = false;
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
})
|
||||
public loading = false;
|
||||
accessor loading = false;
|
||||
|
||||
@property({
|
||||
type: Number,
|
||||
})
|
||||
public daysToShow = 90;
|
||||
accessor daysToShow = 90;
|
||||
|
||||
@property({
|
||||
type: Array,
|
||||
})
|
||||
public subscribedIncidentIds: string[] = [];
|
||||
accessor subscribedIncidentIds: string[] = [];
|
||||
|
||||
@property({
|
||||
type: Object,
|
||||
state: true,
|
||||
})
|
||||
private expandedIncidents: Set<string> = new Set();
|
||||
private accessor expandedIncidents: Set<string> = new Set();
|
||||
|
||||
@property({
|
||||
type: Object,
|
||||
state: true,
|
||||
})
|
||||
private subscribedIncidents: Set<string> = new Set();
|
||||
private accessor subscribedIncidents: Set<string> = new Set();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -89,75 +89,75 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
|
||||
public static styles = [
|
||||
plugins.domtools.elementBasic.staticStyles,
|
||||
commonStyles,
|
||||
sharedStyles.commonStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
background: transparent;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
color: ${colors.text.primary};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.noIncidentBox {
|
||||
background: ${colors.background.card};
|
||||
padding: ${unsafeCSS(spacing.xl)};
|
||||
margin-bottom: ${unsafeCSS(spacing.lg)};
|
||||
border-radius: ${unsafeCSS(borderRadius.md)};
|
||||
border: 1px solid ${colors.border.default};
|
||||
background: ${sharedStyles.colors.background.card};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xl)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.md)};
|
||||
border: 1px solid ${sharedStyles.colors.border.default};
|
||||
text-align: center;
|
||||
color: ${colors.text.secondary};
|
||||
box-shadow: ${unsafeCSS(shadows.sm)};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
|
||||
}
|
||||
|
||||
.incident-card {
|
||||
background: ${colors.background.card};
|
||||
border-radius: ${unsafeCSS(borderRadius.md)};
|
||||
margin-bottom: ${unsafeCSS(spacing.lg)};
|
||||
background: ${sharedStyles.colors.background.card};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.md)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
overflow: hidden;
|
||||
box-shadow: ${unsafeCSS(shadows.sm)};
|
||||
border: 1px solid ${colors.border.default};
|
||||
box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
|
||||
border: 1px solid ${sharedStyles.colors.border.default};
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.incident-card.expanded {
|
||||
box-shadow: ${unsafeCSS(shadows.md)};
|
||||
box-shadow: ${unsafeCSS(sharedStyles.shadows.md)};
|
||||
}
|
||||
|
||||
.incident-header {
|
||||
padding: ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
border-left: 4px solid;
|
||||
display: flex;
|
||||
align-items: start;
|
||||
justify-content: space-between;
|
||||
gap: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.incident-header:hover {
|
||||
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.02)', 'rgba(255, 255, 255, 0.02)')};
|
||||
}
|
||||
|
||||
.incident-header.critical {
|
||||
border-left-color: ${colors.status.major};
|
||||
border-left-color: ${sharedStyles.colors.status.major};
|
||||
}
|
||||
|
||||
.incident-header.major {
|
||||
border-left-color: ${colors.status.partial};
|
||||
border-left-color: ${sharedStyles.colors.status.partial};
|
||||
}
|
||||
|
||||
.incident-header.minor {
|
||||
border-left-color: ${colors.status.degraded};
|
||||
border-left-color: ${sharedStyles.colors.status.degraded};
|
||||
}
|
||||
|
||||
.incident-header.maintenance {
|
||||
border-left-color: ${colors.status.maintenance};
|
||||
border-left-color: ${sharedStyles.colors.status.maintenance};
|
||||
}
|
||||
|
||||
.incident-title {
|
||||
@@ -169,19 +169,19 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
|
||||
.incident-meta {
|
||||
display: flex;
|
||||
gap: ${unsafeCSS(spacing.lg)};
|
||||
margin-top: ${unsafeCSS(spacing.sm)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
font-size: 13px;
|
||||
color: ${colors.text.secondary};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.incident-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(spacing.xs)};
|
||||
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.md)};
|
||||
border-radius: ${unsafeCSS(borderRadius.full)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
@@ -215,49 +215,49 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
}
|
||||
|
||||
.incident-body {
|
||||
padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.incident-impact {
|
||||
margin: ${unsafeCSS(spacing.md)} 0;
|
||||
padding: ${unsafeCSS(spacing.md)};
|
||||
background: ${colors.background.secondary};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
margin: ${unsafeCSS(sharedStyles.spacing.md)} 0;
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
background: ${sharedStyles.colors.background.secondary};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.affected-services {
|
||||
margin-top: ${unsafeCSS(spacing.md)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.affected-services-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
margin-bottom: ${unsafeCSS(spacing.sm)};
|
||||
color: ${colors.text.primary};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.service-tag {
|
||||
display: inline-block;
|
||||
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.sm)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
margin: 2px;
|
||||
background: ${colors.background.muted};
|
||||
border-radius: ${unsafeCSS(borderRadius.sm)};
|
||||
background: ${sharedStyles.colors.background.muted};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.sm)};
|
||||
font-size: 12px;
|
||||
color: ${colors.text.secondary};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
}
|
||||
|
||||
.incident-updates {
|
||||
margin-top: ${unsafeCSS(spacing.lg)};
|
||||
border-top: 1px solid ${colors.border.default};
|
||||
padding-top: ${unsafeCSS(spacing.lg)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
border-top: 1px solid ${sharedStyles.colors.border.default};
|
||||
padding-top: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.update-item {
|
||||
position: relative;
|
||||
padding-left: ${unsafeCSS(spacing.lg)};
|
||||
margin-bottom: ${unsafeCSS(spacing.md)};
|
||||
padding-left: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.update-item::before {
|
||||
@@ -267,27 +267,27 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
top: 6px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: ${unsafeCSS(borderRadius.full)};
|
||||
background: ${colors.border.muted};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
|
||||
background: ${sharedStyles.colors.border.muted};
|
||||
}
|
||||
|
||||
.update-time {
|
||||
font-size: 12px;
|
||||
color: ${colors.text.secondary};
|
||||
margin-bottom: ${unsafeCSS(spacing.xs)};
|
||||
font-family: ${unsafeCSS(fonts.mono)};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.mono)};
|
||||
}
|
||||
|
||||
.update-message {
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: ${colors.text.primary};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.update-author {
|
||||
font-size: 12px;
|
||||
color: ${colors.text.secondary};
|
||||
margin-top: ${unsafeCSS(spacing.xs)};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@@ -299,8 +299,8 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
)};
|
||||
background-size: 200% 100%;
|
||||
animation: loading 1.5s infinite;
|
||||
border-radius: ${unsafeCSS(borderRadius.md)};
|
||||
margin-bottom: ${unsafeCSS(spacing.lg)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.md)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
@@ -310,63 +310,63 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
|
||||
.show-more {
|
||||
text-align: center;
|
||||
margin-top: ${unsafeCSS(spacing.lg)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.show-more-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: ${unsafeCSS(spacing.sm)} ${unsafeCSS(spacing.lg)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.sm)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
background: transparent;
|
||||
border: 1px solid ${colors.border.default};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border: 1px solid ${sharedStyles.colors.border.default};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
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)};
|
||||
}
|
||||
|
||||
.show-more-button:hover {
|
||||
background: ${colors.background.secondary};
|
||||
border-color: ${colors.border.muted};
|
||||
background: ${sharedStyles.colors.background.secondary};
|
||||
border-color: ${sharedStyles.colors.border.muted};
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.show-more-button:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
|
||||
.incident-actions {
|
||||
display: flex;
|
||||
gap: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
align-items: center;
|
||||
margin-top: ${unsafeCSS(spacing.lg)};
|
||||
padding-top: ${unsafeCSS(spacing.lg)};
|
||||
border-top: 1px solid ${colors.border.default};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
padding-top: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
border-top: 1px solid ${sharedStyles.colors.border.default};
|
||||
}
|
||||
|
||||
|
||||
.subscribe-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(spacing.xs)};
|
||||
padding: ${unsafeCSS(spacing.xs)} ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
background: transparent;
|
||||
border: 1px solid ${colors.border.default};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border: 1px solid ${sharedStyles.colors.border.default};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
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)};
|
||||
}
|
||||
|
||||
|
||||
.subscribe-button:hover {
|
||||
background: ${colors.background.secondary};
|
||||
border-color: ${colors.border.muted};
|
||||
background: ${sharedStyles.colors.background.secondary};
|
||||
border-color: ${sharedStyles.colors.border.muted};
|
||||
}
|
||||
|
||||
.subscribe-button.subscribed {
|
||||
@@ -381,24 +381,24 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
|
||||
.collapsed-hint {
|
||||
font-size: 12px;
|
||||
color: ${colors.text.secondary};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
text-align: center;
|
||||
margin-top: ${unsafeCSS(spacing.md)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
|
||||
.incident-header {
|
||||
padding: ${unsafeCSS(spacing.md)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.incident-meta {
|
||||
flex-direction: column;
|
||||
gap: ${unsafeCSS(spacing.xs)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
}
|
||||
}
|
||||
`,
|
||||
@@ -456,12 +456,12 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
</div>
|
||||
${!this.expandedIncidents.has(incident.id) ? html`
|
||||
<div style="
|
||||
margin-top: ${unsafeCSS(spacing.sm)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
font-size: 13px;
|
||||
color: ${colors.text.secondary};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
">
|
||||
${incident.impact ? html`
|
||||
<span style="
|
||||
@@ -480,7 +480,7 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: ${unsafeCSS(spacing.md)};">
|
||||
<div style="display: flex; align-items: center; gap: ${unsafeCSS(sharedStyles.spacing.md)};">
|
||||
<div class="incident-status ${latestUpdate.status}">
|
||||
${this.getStatusIcon(latestUpdate.status)}
|
||||
${latestUpdate.status.replace(/_/g, ' ')}
|
||||
@@ -590,10 +590,10 @@ export class UplStatuspageIncidents extends DeesElement {
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
margin-right: 4px;
|
||||
background: ${status === 'resolved' ? colors.status.operational :
|
||||
status === 'monitoring' ? colors.status.maintenance :
|
||||
status === 'identified' ? colors.status.degraded :
|
||||
colors.status.partial};
|
||||
background: ${status === 'resolved' ? sharedStyles.colors.status.operational :
|
||||
status === 'monitoring' ? sharedStyles.colors.status.maintenance :
|
||||
status === 'identified' ? sharedStyles.colors.status.degraded :
|
||||
sharedStyles.colors.status.partial};
|
||||
"></span>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 } from '../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../styles/shared.styles.js';
|
||||
import { demoFunc } from './upl-statuspage-pagetitle.demo.js';
|
||||
|
||||
declare global {
|
||||
@@ -14,13 +14,13 @@ export class UplStatuspagePagetitle extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@property({ type: String })
|
||||
public pageTitle: string = 'System Status';
|
||||
accessor pageTitle: string = 'System Status';
|
||||
|
||||
@property({ type: String })
|
||||
public pageSubtitle: string = '';
|
||||
@property({ type: String })
|
||||
accessor pageSubtitle: string = '';
|
||||
|
||||
@property({ type: Boolean })
|
||||
public centered: boolean = false;
|
||||
accessor centered: boolean = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -31,13 +31,13 @@ export class UplStatuspagePagetitle extends DeesElement {
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
}
|
||||
|
||||
.title-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 48px 24px 24px 24px;
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.title-container.centered {
|
||||
@@ -47,30 +47,30 @@ export class UplStatuspagePagetitle extends DeesElement {
|
||||
h1 {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
letter-spacing: -0.03em;
|
||||
line-height: 1.1;
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
margin: 0 0 16px 0;
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
margin: 0 0 ${unsafeCSS(sharedStyles.spacing.md)} 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 20px;
|
||||
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
||||
font-size: 18px;
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.title-container {
|
||||
padding: 32px 16px 20px 16px;
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
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 './internal/uplinternal-miniheading.js';
|
||||
import { demoFunc } from './upl-statuspage-statsgrid.demo.js';
|
||||
@@ -25,28 +25,28 @@ export class UplStatuspageStatsgrid extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@property({ type: Number })
|
||||
public uptime: number = 99.99;
|
||||
accessor uptime: number = 99.99;
|
||||
|
||||
@property({ type: Number })
|
||||
public avgResponseTime: number = 125;
|
||||
accessor avgResponseTime: number = 125;
|
||||
|
||||
@property({ type: Number })
|
||||
public totalIncidents: number = 0;
|
||||
accessor totalIncidents: number = 0;
|
||||
|
||||
@property({ type: Number })
|
||||
public affectedServices: number = 0;
|
||||
accessor affectedServices: number = 0;
|
||||
|
||||
@property({ type: Number })
|
||||
public totalServices: number = 0;
|
||||
accessor totalServices: number = 0;
|
||||
|
||||
@property({ type: String })
|
||||
public currentStatus: string = 'operational';
|
||||
accessor currentStatus: string = 'operational';
|
||||
|
||||
@property({ type: Boolean })
|
||||
public loading: boolean = false;
|
||||
accessor loading: boolean = false;
|
||||
|
||||
@property({ type: String })
|
||||
public timePeriod: string = '90 days';
|
||||
accessor timePeriod: string = '90 days';
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -54,32 +54,32 @@ export class UplStatuspageStatsgrid extends DeesElement {
|
||||
|
||||
public static styles = [
|
||||
domtools.elementBasic.staticStyles,
|
||||
commonStyles,
|
||||
sharedStyles.commonStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
background: transparent;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
color: ${colors.text.primary};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
padding: ${unsafeCSS(spacing.lg)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
@@ -97,10 +97,10 @@ export class UplStatuspageStatsgrid extends DeesElement {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-weight: 500;
|
||||
margin-bottom: ${unsafeCSS(spacing.sm)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(spacing.xs)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
@@ -120,7 +120,7 @@ export class UplStatuspageStatsgrid extends DeesElement {
|
||||
|
||||
.stat-change {
|
||||
font-size: 12px;
|
||||
margin-top: ${unsafeCSS(spacing.xs)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
@@ -141,14 +141,14 @@ export class UplStatuspageStatsgrid extends DeesElement {
|
||||
.loading-skeleton {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.skeleton-card {
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
padding: ${unsafeCSS(spacing.lg)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ export class UplStatuspageStatsgrid extends DeesElement {
|
||||
width: 80px;
|
||||
background: ${cssManager.bdTheme('#f3f4f6', '#27272a')};
|
||||
border-radius: 4px;
|
||||
margin-bottom: ${unsafeCSS(spacing.sm)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@@ -183,37 +183,37 @@ export class UplStatuspageStatsgrid extends DeesElement {
|
||||
}
|
||||
|
||||
.status-indicator.operational {
|
||||
background: ${colors.status.operational};
|
||||
background: ${sharedStyles.colors.status.operational};
|
||||
}
|
||||
|
||||
.status-indicator.degraded {
|
||||
background: ${colors.status.degraded};
|
||||
background: ${sharedStyles.colors.status.degraded};
|
||||
}
|
||||
|
||||
.status-indicator.partial_outage {
|
||||
background: ${colors.status.partial};
|
||||
background: ${sharedStyles.colors.status.partial};
|
||||
}
|
||||
|
||||
.status-indicator.major_outage {
|
||||
background: ${colors.status.major};
|
||||
background: ${sharedStyles.colors.status.major};
|
||||
}
|
||||
|
||||
.status-indicator.maintenance {
|
||||
background: ${colors.status.maintenance};
|
||||
background: ${sharedStyles.colors.status.maintenance};
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: ${unsafeCSS(spacing.sm)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
padding: ${unsafeCSS(spacing.md)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DeesElement, property, html, customElement, type TemplateResult, cssManager, css, unsafeCSS } from '@design.estate/dees-element';
|
||||
import * as domtools from '@design.estate/dees-domtools';
|
||||
import type { IOverallStatus } from '../interfaces/index.js';
|
||||
import { fonts, colors } from '../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../styles/shared.styles.js';
|
||||
import { demoFunc } from './upl-statuspage-statusbar.demo.js';
|
||||
|
||||
declare global {
|
||||
@@ -15,7 +15,7 @@ export class UplStatuspageStatusbar extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@property({ type: Object })
|
||||
public overallStatus: IOverallStatus = {
|
||||
accessor overallStatus: IOverallStatus = {
|
||||
status: 'operational',
|
||||
message: 'All Systems Operational',
|
||||
lastUpdated: Date.now(),
|
||||
@@ -24,10 +24,10 @@ export class UplStatuspageStatusbar extends DeesElement {
|
||||
};
|
||||
|
||||
@property({ type: Boolean })
|
||||
public loading: boolean = false;
|
||||
accessor loading: boolean = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public expandable: boolean = true;
|
||||
accessor expandable: boolean = true;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -37,149 +37,236 @@ export class UplStatuspageStatusbar extends DeesElement {
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
padding: 0;
|
||||
display: block;
|
||||
background: transparent;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
}
|
||||
padding: 0;
|
||||
display: block;
|
||||
background: transparent;
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
}
|
||||
|
||||
.statusbar-container {
|
||||
margin: auto;
|
||||
max-width: 1200px;
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.statusbar-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 64px;
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
|
||||
cursor: default;
|
||||
transition: all ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
letter-spacing: -0.01em;
|
||||
background: ${sharedStyles.colors.background.card};
|
||||
border: 1px solid ${sharedStyles.colors.border.default};
|
||||
box-shadow: ${unsafeCSS(sharedStyles.shadows.sm)};
|
||||
}
|
||||
|
||||
.statusbar-inner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 4px;
|
||||
transition: background ${unsafeCSS(sharedStyles.durations.normal)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||
}
|
||||
|
||||
.statusbar-inner.operational::before {
|
||||
background: ${sharedStyles.colors.status.operational};
|
||||
}
|
||||
|
||||
.statusbar-inner.degraded::before {
|
||||
background: ${sharedStyles.colors.status.degraded};
|
||||
}
|
||||
|
||||
.statusbar-inner.partial_outage::before {
|
||||
background: ${sharedStyles.colors.status.partial};
|
||||
}
|
||||
|
||||
.statusbar-inner.major_outage::before {
|
||||
background: ${sharedStyles.colors.status.major};
|
||||
}
|
||||
|
||||
.statusbar-inner.maintenance::before {
|
||||
background: ${sharedStyles.colors.status.maintenance};
|
||||
}
|
||||
|
||||
.statusbar-inner:hover {
|
||||
border-color: ${sharedStyles.colors.border.muted};
|
||||
box-shadow: ${unsafeCSS(sharedStyles.shadows.base)};
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.status-indicator::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -3px;
|
||||
border-radius: 50%;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.statusbar-inner.operational .status-indicator {
|
||||
background: ${sharedStyles.colors.status.operational};
|
||||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(22, 163, 74, 0.15)', 'rgba(34, 197, 94, 0.2)')};
|
||||
}
|
||||
|
||||
.statusbar-inner.operational .status-indicator::after {
|
||||
background: ${sharedStyles.colors.status.operational};
|
||||
animation: pulse-ring 2s ease-out infinite;
|
||||
}
|
||||
|
||||
.statusbar-inner.degraded .status-indicator {
|
||||
background: ${sharedStyles.colors.status.degraded};
|
||||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(217, 119, 6, 0.15)', 'rgba(251, 191, 36, 0.2)')};
|
||||
}
|
||||
|
||||
.statusbar-inner.partial_outage .status-indicator {
|
||||
background: ${sharedStyles.colors.status.partial};
|
||||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(220, 38, 38, 0.15)', 'rgba(248, 113, 113, 0.2)')};
|
||||
}
|
||||
|
||||
.statusbar-inner.major_outage .status-indicator {
|
||||
background: ${sharedStyles.colors.status.major};
|
||||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(185, 28, 28, 0.15)', 'rgba(239, 68, 68, 0.2)')};
|
||||
animation: pulse-indicator 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.statusbar-inner.maintenance .status-indicator {
|
||||
background: ${sharedStyles.colors.status.maintenance};
|
||||
box-shadow: 0 0 0 3px ${cssManager.bdTheme('rgba(37, 99, 235, 0.15)', 'rgba(96, 165, 250, 0.2)')};
|
||||
}
|
||||
|
||||
@keyframes pulse-ring {
|
||||
0% { transform: scale(1); opacity: 0.2; }
|
||||
50% { transform: scale(1.5); opacity: 0; }
|
||||
100% { transform: scale(1); opacity: 0; }
|
||||
}
|
||||
|
||||
@keyframes pulse-indicator {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.6; }
|
||||
}
|
||||
|
||||
.status-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
flex: 1;
|
||||
padding-left: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
}
|
||||
|
||||
.status-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.status-message {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-details {
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
}
|
||||
|
||||
.loading-skeleton {
|
||||
background: ${sharedStyles.colors.background.card};
|
||||
border: 1px solid ${sharedStyles.colors.border.default};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.lg)};
|
||||
height: 64px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.loading-skeleton::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: ${cssManager.bdTheme(
|
||||
'linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.04) 50%, transparent 100%)',
|
||||
'linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.04) 50%, transparent 100%)'
|
||||
)};
|
||||
animation: loading 1.5s ${unsafeCSS(sharedStyles.easings.default)} infinite;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% { transform: translateX(-100%); }
|
||||
100% { transform: translateX(200%); }
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
font-size: 12px;
|
||||
color: ${sharedStyles.colors.text.muted};
|
||||
white-space: nowrap;
|
||||
padding: 4px 10px;
|
||||
background: ${sharedStyles.colors.background.muted};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.full)};
|
||||
transition: all ${unsafeCSS(sharedStyles.durations.fast)} ${unsafeCSS(sharedStyles.easings.default)};
|
||||
}
|
||||
|
||||
.statusbar-inner:hover .last-updated {
|
||||
background: ${cssManager.bdTheme('#e4e4e7', '#3f3f46')};
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.statusbar-container {
|
||||
margin: auto;
|
||||
max-width: 1200px;
|
||||
padding: 24px 24px;
|
||||
position: relative;
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.statusbar-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 56px;
|
||||
padding: 16px 20px;
|
||||
border-radius: 6px;
|
||||
cursor: ${cssManager.bdTheme('default', 'default')};
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
box-shadow: ${cssManager.bdTheme('0 1px 2px 0 rgba(0, 0, 0, 0.05)', 'none')};
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
min-height: auto;
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
.statusbar-inner:hover {
|
||||
background: ${cssManager.bdTheme('#f9fafb', '#0f0f0f')};
|
||||
.status-main {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
align-self: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.statusbar-inner {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.statusbar-inner.operational .status-indicator {
|
||||
background: ${colors.status.operational};
|
||||
}
|
||||
|
||||
.statusbar-inner.degraded .status-indicator {
|
||||
background: ${colors.status.degraded};
|
||||
}
|
||||
|
||||
.statusbar-inner.partial_outage .status-indicator {
|
||||
background: ${colors.status.partial};
|
||||
}
|
||||
|
||||
.statusbar-inner.major_outage .status-indicator {
|
||||
background: ${colors.status.major};
|
||||
}
|
||||
|
||||
.statusbar-inner.maintenance .status-indicator {
|
||||
background: ${colors.status.maintenance};
|
||||
}
|
||||
|
||||
.status-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.status-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
}
|
||||
|
||||
.status-details {
|
||||
font-size: 13px;
|
||||
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
||||
}
|
||||
|
||||
.loading-skeleton {
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: 6px;
|
||||
height: 56px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.loading-skeleton::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: ${cssManager.bdTheme(
|
||||
'linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.03) 50%, transparent 100%)',
|
||||
'linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.03) 50%, transparent 100%)'
|
||||
)};
|
||||
animation: loading 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
font-size: 12px;
|
||||
color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.statusbar-container {
|
||||
padding: 16px 16px;
|
||||
}
|
||||
|
||||
.statusbar-inner {
|
||||
font-size: 13px;
|
||||
padding: 12px 16px;
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.status-content {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
font-size: 11px;
|
||||
}
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
`,
|
||||
]
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
unsafeCSS,
|
||||
} from '@design.estate/dees-element';
|
||||
import type { IStatusHistoryPoint } from '../interfaces/index.js';
|
||||
import { fonts, colors, shadows, borderRadius, spacing, commonStyles, getStatusColor } from '../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../styles/shared.styles.js';
|
||||
|
||||
import './internal/uplinternal-miniheading.js';
|
||||
import { demoFunc } from './upl-statuspage-statusdetails.demo.js';
|
||||
@@ -26,22 +26,22 @@ export class UplStatuspageStatusdetails extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@property({ type: Array })
|
||||
public historyData: IStatusHistoryPoint[] = [];
|
||||
|
||||
accessor historyData: IStatusHistoryPoint[] = [];
|
||||
|
||||
@property({ type: Array })
|
||||
public dataPoints: IStatusHistoryPoint[] = [];
|
||||
accessor dataPoints: IStatusHistoryPoint[] = [];
|
||||
|
||||
@property({ type: String })
|
||||
public serviceId: string = '';
|
||||
accessor serviceId: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
public serviceName: string = 'Service';
|
||||
accessor serviceName: string = 'Service';
|
||||
|
||||
@property({ type: Boolean })
|
||||
public loading: boolean = false;
|
||||
accessor loading: boolean = false;
|
||||
|
||||
@property({ type: Number })
|
||||
public hoursToShow: number = 48;
|
||||
accessor hoursToShow: number = 48;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -49,20 +49,20 @@ export class UplStatuspageStatusdetails extends DeesElement {
|
||||
|
||||
public static styles = [
|
||||
plugins.domtools.elementBasic.staticStyles,
|
||||
commonStyles,
|
||||
sharedStyles.commonStyles,
|
||||
css`
|
||||
:host {
|
||||
position: relative;
|
||||
display: block;
|
||||
background: transparent;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
color: ${colors.text.primary};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.graph-wrapper {
|
||||
@@ -86,10 +86,10 @@ export class UplStatuspageStatusdetails extends DeesElement {
|
||||
position: relative;
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
padding: ${unsafeCSS(spacing.sm)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
overflow: hidden;
|
||||
height: 40px;
|
||||
}
|
||||
@@ -138,10 +138,10 @@ export class UplStatuspageStatusdetails extends DeesElement {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0;
|
||||
margin-top: ${unsafeCSS(spacing.xs)};
|
||||
margin-top: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
font-size: 10px;
|
||||
color: ${cssManager.bdTheme('#9ca3af', '#71717a')};
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@@ -202,16 +202,16 @@ export class UplStatuspageStatusdetails extends DeesElement {
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
|
||||
.graph-container {
|
||||
padding: ${unsafeCSS(spacing.sm)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
}
|
||||
|
||||
.mainbox .barContainer {
|
||||
height: 32px;
|
||||
padding: ${unsafeCSS(spacing.xs)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.xs)};
|
||||
}
|
||||
|
||||
.time-labels {
|
||||
@@ -221,7 +221,7 @@ export class UplStatuspageStatusdetails extends DeesElement {
|
||||
.stats-row {
|
||||
font-size: 11px;
|
||||
flex-direction: column;
|
||||
gap: ${unsafeCSS(spacing.sm)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ export class UplStatuspageStatusdetails extends DeesElement {
|
||||
<div class="mainbox">
|
||||
${this.loading ? html`
|
||||
<div class="graph-container">
|
||||
<div class="barContainer" style="background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#f3f4f6', '#1f1f1f')}; border-radius: ${borderRadius.base}; padding: ${spacing.sm}; height: 40px;">
|
||||
<div class="barContainer" style="background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#f3f4f6', '#1f1f1f')}; border-radius: ${sharedStyles.borderRadius.base}; padding: ${sharedStyles.spacing.sm}; height: 40px;">
|
||||
<div class="loading-skeleton">
|
||||
${Array(this.hoursToShow).fill(0).map(() => html`<div class="skeleton-bar"></div>`)}
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@design.estate/dees-element';
|
||||
import * as domtools from '@design.estate/dees-domtools';
|
||||
import type { IMonthlyUptime } from '../interfaces/index.js';
|
||||
import { fonts, colors, shadows, borderRadius, spacing, commonStyles } from '../styles/shared.styles.js';
|
||||
import * as sharedStyles from '../styles/shared.styles.js';
|
||||
|
||||
import './internal/uplinternal-miniheading.js';
|
||||
import { demoFunc } from './upl-statuspage-statusmonth.demo.js';
|
||||
@@ -26,22 +26,22 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
@property({ type: Array })
|
||||
public monthlyData: IMonthlyUptime[] = [];
|
||||
accessor monthlyData: IMonthlyUptime[] = [];
|
||||
|
||||
@property({ type: String })
|
||||
public serviceId: string = '';
|
||||
accessor serviceId: string = '';
|
||||
|
||||
@property({ type: String })
|
||||
public serviceName: string = 'Service';
|
||||
accessor serviceName: string = 'Service';
|
||||
|
||||
@property({ type: Boolean })
|
||||
public loading: boolean = false;
|
||||
accessor loading: boolean = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public showTooltip: boolean = true;
|
||||
accessor showTooltip: boolean = true;
|
||||
|
||||
@property({ type: Number })
|
||||
public monthsToShow: number = 5;
|
||||
accessor monthsToShow: number = 5;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -49,32 +49,32 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
|
||||
public static styles = [
|
||||
domtools.elementBasic.staticStyles,
|
||||
commonStyles,
|
||||
sharedStyles.commonStyles,
|
||||
css`
|
||||
:host {
|
||||
position: relative;
|
||||
display: block;
|
||||
background: transparent;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
color: ${colors.text.primary};
|
||||
font-family: ${unsafeCSS(sharedStyles.fonts.base)};
|
||||
color: ${sharedStyles.colors.text.primary};
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)} ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.mainbox {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
gap: ${unsafeCSS(spacing.lg)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
.statusMonth {
|
||||
background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')};
|
||||
padding: ${unsafeCSS(spacing.lg)};
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
border-radius: ${unsafeCSS(sharedStyles.borderRadius.base)};
|
||||
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
|
||||
position: relative;
|
||||
transition: all 0.2s ease;
|
||||
@@ -83,7 +83,7 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
min-height: 280px;
|
||||
box-shadow: ${cssManager.bdTheme('0 1px 2px 0 rgba(0, 0, 0, 0.05)', 'none')};
|
||||
}
|
||||
|
||||
|
||||
.statusMonth:hover {
|
||||
border-color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
box-shadow: ${cssManager.bdTheme('0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', '0 0 0 1px rgba(255, 255, 255, 0.1)')};
|
||||
@@ -92,7 +92,7 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
.month-header {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
margin-bottom: ${unsafeCSS(spacing.md)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')};
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
@@ -102,9 +102,9 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: ${unsafeCSS(spacing.lg)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.lg)};
|
||||
}
|
||||
|
||||
|
||||
.days-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
@@ -119,7 +119,7 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
font-weight: 500;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: ${unsafeCSS(spacing.sm)};
|
||||
margin-bottom: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
.overall-uptime {
|
||||
font-size: 12px;
|
||||
margin-top: auto;
|
||||
padding-top: ${unsafeCSS(spacing.md)};
|
||||
padding-top: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -195,7 +195,7 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
.loading-skeleton {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: ${unsafeCSS(spacing.sm)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.sm)};
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -264,28 +264,28 @@ export class UplStatuspageStatusmonth extends DeesElement {
|
||||
.no-data-message {
|
||||
grid-column: 1 / -1;
|
||||
text-align: center;
|
||||
padding: ${unsafeCSS(spacing['2xl'])};
|
||||
color: ${colors.text.secondary};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing['2xl'])};
|
||||
color: ${sharedStyles.colors.text.secondary};
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)};
|
||||
padding: 0 ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)} ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
|
||||
.mainbox {
|
||||
grid-template-columns: 1fr;
|
||||
gap: ${unsafeCSS(spacing.md)};
|
||||
gap: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
|
||||
|
||||
.statusMonth {
|
||||
padding: ${unsafeCSS(spacing.md)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
min-height: 260px;
|
||||
}
|
||||
|
||||
|
||||
.loading-skeleton {
|
||||
height: 180px;
|
||||
padding: ${unsafeCSS(spacing.md)};
|
||||
padding: ${unsafeCSS(sharedStyles.spacing.md)};
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@@ -7,6 +7,11 @@ export const statuspageAllgreen = () => html`
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
.demo-page-wrapper > dees-demowrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
|
||||
@@ -7,6 +7,11 @@ export const statuspageDemo = () => html`
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
.demo-page-wrapper > dees-demowrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
|
||||
@@ -7,6 +7,11 @@ export const statuspageMaintenance = () => html`
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
.demo-page-wrapper > dees-demowrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
|
||||
@@ -7,6 +7,11 @@ export const statuspageOutage = () => html`
|
||||
min-height: 100vh;
|
||||
background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
|
||||
}
|
||||
.demo-page-wrapper > dees-demowrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="demo-page-wrapper">
|
||||
|
||||
@@ -8,49 +8,63 @@ export const fonts = {
|
||||
export const colors = {
|
||||
// Background colors
|
||||
background: {
|
||||
primary: cssManager.bdTheme('#ffffff', '#0a0a0a'),
|
||||
secondary: cssManager.bdTheme('#f9fafb', '#18181b'),
|
||||
muted: cssManager.bdTheme('#f3f4f6', '#27272a'),
|
||||
card: cssManager.bdTheme('#ffffff', '#18181b')
|
||||
primary: cssManager.bdTheme('#ffffff', '#09090b'),
|
||||
secondary: cssManager.bdTheme('#fafafa', '#18181b'),
|
||||
muted: cssManager.bdTheme('#f4f4f5', '#27272a'),
|
||||
card: cssManager.bdTheme('#ffffff', '#0f0f12'),
|
||||
elevated: cssManager.bdTheme('#ffffff', '#1a1a1e')
|
||||
},
|
||||
|
||||
|
||||
// Border colors
|
||||
border: {
|
||||
default: cssManager.bdTheme('#e5e7eb', '#27272a'),
|
||||
muted: cssManager.bdTheme('#f3f4f6', '#3f3f46')
|
||||
default: cssManager.bdTheme('#e4e4e7', '#27272a'),
|
||||
muted: cssManager.bdTheme('#f4f4f5', '#3f3f46'),
|
||||
subtle: cssManager.bdTheme('#f0f0f2', '#1f1f23')
|
||||
},
|
||||
|
||||
|
||||
// Text colors
|
||||
text: {
|
||||
primary: cssManager.bdTheme('#0a0a0a', '#fafafa'),
|
||||
secondary: cssManager.bdTheme('#6b7280', '#a1a1aa'),
|
||||
muted: cssManager.bdTheme('#9ca3af', '#71717a')
|
||||
primary: cssManager.bdTheme('#09090b', '#fafafa'),
|
||||
secondary: cssManager.bdTheme('#71717a', '#a1a1aa'),
|
||||
muted: cssManager.bdTheme('#a1a1aa', '#71717a')
|
||||
},
|
||||
|
||||
// Status colors - using bright colors for better visibility in both themes
|
||||
|
||||
// Status colors - vibrant and accessible
|
||||
status: {
|
||||
operational: cssManager.bdTheme('#22c55e', '#22c55e'),
|
||||
degraded: cssManager.bdTheme('#fbbf24', '#fbbf24'),
|
||||
partial: cssManager.bdTheme('#f87171', '#f87171'),
|
||||
major: cssManager.bdTheme('#ef4444', '#ef4444'),
|
||||
maintenance: cssManager.bdTheme('#60a5fa', '#60a5fa')
|
||||
operational: cssManager.bdTheme('#16a34a', '#22c55e'),
|
||||
degraded: cssManager.bdTheme('#d97706', '#fbbf24'),
|
||||
partial: cssManager.bdTheme('#dc2626', '#f87171'),
|
||||
major: cssManager.bdTheme('#b91c1c', '#ef4444'),
|
||||
maintenance: cssManager.bdTheme('#2563eb', '#60a5fa')
|
||||
},
|
||||
|
||||
// Accent colors for interactive elements
|
||||
accent: {
|
||||
primary: cssManager.bdTheme('#09090b', '#fafafa'),
|
||||
hover: cssManager.bdTheme('#18181b', '#e4e4e7'),
|
||||
focus: cssManager.bdTheme('#3b82f6', '#60a5fa')
|
||||
}
|
||||
};
|
||||
|
||||
export const shadows = {
|
||||
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
||||
base: '0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06)',
|
||||
md: '0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06)',
|
||||
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
|
||||
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)'
|
||||
xs: '0 1px 2px 0 rgba(0, 0, 0, 0.03)',
|
||||
sm: '0 1px 3px 0 rgba(0, 0, 0, 0.06), 0 1px 2px -1px rgba(0, 0, 0, 0.06)',
|
||||
base: '0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05)',
|
||||
md: '0 6px 12px -2px rgba(0, 0, 0, 0.08), 0 3px 7px -3px rgba(0, 0, 0, 0.05)',
|
||||
lg: '0 12px 24px -4px rgba(0, 0, 0, 0.1), 0 6px 12px -6px rgba(0, 0, 0, 0.05)',
|
||||
xl: '0 24px 48px -12px rgba(0, 0, 0, 0.12), 0 12px 24px -12px rgba(0, 0, 0, 0.05)',
|
||||
inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.04)',
|
||||
glow: '0 0 20px -5px rgba(34, 197, 94, 0.3)'
|
||||
};
|
||||
|
||||
export const borderRadius = {
|
||||
xs: '3px',
|
||||
sm: '4px',
|
||||
base: '6px',
|
||||
md: '8px',
|
||||
lg: '12px',
|
||||
xl: '16px',
|
||||
'2xl': '24px',
|
||||
full: '9999px'
|
||||
};
|
||||
|
||||
@@ -61,7 +75,24 @@ export const spacing = {
|
||||
lg: '24px',
|
||||
xl: '32px',
|
||||
'2xl': '48px',
|
||||
'3xl': '64px'
|
||||
'3xl': '64px',
|
||||
'4xl': '96px'
|
||||
};
|
||||
|
||||
// Animation easings
|
||||
export const easings = {
|
||||
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
smooth: 'cubic-bezier(0.4, 0, 0.6, 1)',
|
||||
bounce: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)',
|
||||
snappy: 'cubic-bezier(0.2, 0, 0, 1)'
|
||||
};
|
||||
|
||||
// Durations
|
||||
export const durations = {
|
||||
fast: '100ms',
|
||||
normal: '200ms',
|
||||
slow: '300ms',
|
||||
slower: '500ms'
|
||||
};
|
||||
|
||||
export const commonStyles = css`
|
||||
@@ -71,78 +102,233 @@ export const commonStyles = css`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: ${unsafeCSS(fonts.base)};
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
height: 36px;
|
||||
padding: 0 16px;
|
||||
padding: 0 14px;
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
border: 1px solid ${colors.border.default};
|
||||
background: transparent;
|
||||
background: ${colors.background.primary};
|
||||
color: ${colors.text.primary};
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all 0.2s ease;
|
||||
gap: 8px;
|
||||
transition: all ${unsafeCSS(durations.normal)} ${unsafeCSS(easings.default)};
|
||||
gap: 6px;
|
||||
white-space: nowrap;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
|
||||
.button:hover {
|
||||
background: ${cssManager.bdTheme('#f9fafb', '#262626')};
|
||||
border-color: ${cssManager.bdTheme('#d1d5db', '#404040')};
|
||||
transform: translateY(-1px);
|
||||
background: ${colors.background.secondary};
|
||||
border-color: ${cssManager.bdTheme('#d4d4d8', '#3f3f46')};
|
||||
box-shadow: ${unsafeCSS(shadows.xs)};
|
||||
}
|
||||
|
||||
|
||||
.button:active {
|
||||
transform: translateY(0);
|
||||
transform: scale(0.98);
|
||||
transition-duration: ${unsafeCSS(durations.fast)};
|
||||
}
|
||||
|
||||
|
||||
.button:focus-visible {
|
||||
outline: 2px solid ${colors.accent.focus};
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.button.primary {
|
||||
background: ${colors.text.primary};
|
||||
background: ${colors.accent.primary};
|
||||
color: ${colors.background.primary};
|
||||
border-color: ${colors.text.primary};
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
.button.primary:hover {
|
||||
background: ${cssManager.bdTheme('#262626', '#f4f4f5')};
|
||||
border-color: ${cssManager.bdTheme('#262626', '#f4f4f5')};
|
||||
background: ${colors.accent.hover};
|
||||
box-shadow: ${unsafeCSS(shadows.sm)};
|
||||
}
|
||||
|
||||
|
||||
.button.ghost {
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.button.ghost:hover {
|
||||
background: ${colors.background.muted};
|
||||
}
|
||||
|
||||
.button.sm {
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.button.lg {
|
||||
height: 44px;
|
||||
padding: 0 20px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* Card styles */
|
||||
.card {
|
||||
background: ${colors.background.card};
|
||||
border: 1px solid ${colors.border.default};
|
||||
border-radius: ${unsafeCSS(borderRadius.md)};
|
||||
border-radius: ${unsafeCSS(borderRadius.lg)};
|
||||
padding: ${unsafeCSS(spacing.lg)};
|
||||
box-shadow: ${unsafeCSS(shadows.sm)};
|
||||
transition: all ${unsafeCSS(durations.normal)} ${unsafeCSS(easings.default)};
|
||||
}
|
||||
|
||||
|
||||
.card:hover {
|
||||
border-color: ${colors.border.muted};
|
||||
box-shadow: ${unsafeCSS(shadows.base)};
|
||||
}
|
||||
|
||||
.card.interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card.interactive:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: ${unsafeCSS(shadows.md)};
|
||||
}
|
||||
|
||||
/* Loading skeleton */
|
||||
.skeleton {
|
||||
background: ${cssManager.bdTheme(
|
||||
'linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%)',
|
||||
'linear-gradient(90deg, #1f1f1f 25%, #262626 50%, #1f1f1f 75%)'
|
||||
'linear-gradient(90deg, #f4f4f5 0%, #e4e4e7 50%, #f4f4f5 100%)',
|
||||
'linear-gradient(90deg, #18181b 0%, #27272a 50%, #18181b 100%)'
|
||||
)};
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s infinite;
|
||||
animation: skeleton-loading 1.5s ease-in-out infinite;
|
||||
border-radius: ${unsafeCSS(borderRadius.base)};
|
||||
}
|
||||
|
||||
|
||||
@keyframes skeleton-loading {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
|
||||
/* Pulse animation for status indicators */
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
/* Fade in animation */
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn ${unsafeCSS(durations.slow)} ${unsafeCSS(easings.default)} forwards;
|
||||
}
|
||||
|
||||
/* Scale in animation */
|
||||
@keyframes scaleIn {
|
||||
from { opacity: 0; transform: scale(0.95); }
|
||||
to { opacity: 1; transform: scale(1); }
|
||||
}
|
||||
|
||||
.scale-in {
|
||||
animation: scaleIn ${unsafeCSS(durations.slow)} ${unsafeCSS(easings.bounce)} forwards;
|
||||
}
|
||||
|
||||
/* Container styles */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 ${unsafeCSS(spacing.lg)};
|
||||
}
|
||||
|
||||
|
||||
/* Status pill */
|
||||
.status-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 4px 10px;
|
||||
border-radius: ${unsafeCSS(borderRadius.full)};
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.status-pill .status-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.status-pill.operational {
|
||||
background: ${cssManager.bdTheme('rgba(22, 163, 74, 0.1)', 'rgba(34, 197, 94, 0.15)')};
|
||||
color: ${cssManager.bdTheme('#15803d', '#4ade80')};
|
||||
}
|
||||
|
||||
.status-pill.operational .status-dot {
|
||||
background: ${colors.status.operational};
|
||||
}
|
||||
|
||||
.status-pill.degraded {
|
||||
background: ${cssManager.bdTheme('rgba(217, 119, 6, 0.1)', 'rgba(251, 191, 36, 0.15)')};
|
||||
color: ${cssManager.bdTheme('#b45309', '#fcd34d')};
|
||||
}
|
||||
|
||||
.status-pill.degraded .status-dot {
|
||||
background: ${colors.status.degraded};
|
||||
}
|
||||
|
||||
.status-pill.partial_outage,
|
||||
.status-pill.major_outage {
|
||||
background: ${cssManager.bdTheme('rgba(220, 38, 38, 0.1)', 'rgba(248, 113, 113, 0.15)')};
|
||||
color: ${cssManager.bdTheme('#b91c1c', '#fca5a5')};
|
||||
}
|
||||
|
||||
.status-pill.partial_outage .status-dot,
|
||||
.status-pill.major_outage .status-dot {
|
||||
background: ${colors.status.major};
|
||||
}
|
||||
|
||||
.status-pill.maintenance {
|
||||
background: ${cssManager.bdTheme('rgba(37, 99, 235, 0.1)', 'rgba(96, 165, 250, 0.15)')};
|
||||
color: ${cssManager.bdTheme('#1d4ed8', '#93c5fd')};
|
||||
}
|
||||
|
||||
.status-pill.maintenance .status-dot {
|
||||
background: ${colors.status.maintenance};
|
||||
}
|
||||
|
||||
/* Responsive utilities */
|
||||
@media (max-width: 1024px) {
|
||||
.container {
|
||||
padding: 0 ${unsafeCSS(spacing.md)};
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 0 ${unsafeCSS(spacing.md)};
|
||||
}
|
||||
|
||||
.button {
|
||||
height: 40px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.button.sm {
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Visually hidden (for accessibility) */
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
|
||||
Reference in New Issue
Block a user