feat: Add custom branding functionality with CSS and JSON configuration

- Introduced custom branding CSS styles in `custom-branding.css`.
- Created example JSON configuration for custom branding in `custom-branding.example.json`.
- Implemented branding configuration logic in `BrandingConfig.ts` to normalize and validate branding settings.
- Developed CSS loader to manage loading and unloading of custom stylesheets in `BrandingCssLoader.ts`.
- Added DOM rendering capabilities for branding elements in `BrandingDomRenderer.ts`.
- Defined types and interfaces for branding elements and configurations in `BrandingTypes.ts`.
- Included localization support for German in `de-de.js`.
- Added unit tests for branding configuration, CSS loader, and DOM renderer.
- Validated project structure and static assets with new validation scripts.
This commit is contained in:
Torsten Brendgen
2026-07-20 22:55:47 +02:00
parent b99ac31f4d
commit 490e9adbd8
29 changed files with 1809 additions and 588 deletions

View File

@@ -0,0 +1,44 @@
.custom-branding-banner {
align-items: center;
background: #f3f2f1;
border-bottom: 1px solid #edebe9;
box-sizing: border-box;
color: #323130;
display: flex;
font-family: "Segoe UI", "Segoe UI Web (West European)", sans-serif;
font-size: 14px;
gap: 16px;
min-height: 40px;
padding: 8px 24px;
}
.custom-branding-link {
color: #005a9e;
text-decoration: none;
}
.custom-branding-link:hover {
color: #004578;
text-decoration: underline;
}
.custom-branding-link:focus-visible,
.custom-branding-banner button:focus-visible {
outline: 2px solid #005a9e;
outline-offset: 2px;
}
@media screen and (max-width: 640px) {
.custom-branding-banner {
align-items: flex-start;
flex-direction: column;
gap: 4px;
padding: 8px 12px;
}
}
@media (forced-colors: active) {
.custom-branding-banner {
border-bottom: 1px solid CanvasText;
}
}

View File

@@ -0,0 +1,41 @@
{
"schemaVersion": 2,
"enabled": true,
"debug": false,
"allowedCssHosts": [],
"cssfiles": [
{
"path": "~sitecollection/SiteAssets/branding/custom-branding.css",
"media": "all"
}
],
"placeholdertop": {
"elements": [
{
"type": "section",
"attributes": {
"class": "custom-branding-banner",
"role": "region",
"aria-label": "Portalhinweis"
},
"children": [
{
"type": "strong",
"content": "Willkommen im Portal"
},
{
"type": "a",
"content": "Zur Startseite",
"attributes": {
"href": "~sitecollection/SitePages/Home.aspx",
"class": "custom-branding-link"
}
}
]
}
]
},
"placeholderbottom": {
"elements": []
}
}