Skip to content

feat(theming): consolidate IONOS theming into apps/theming - #321

Open
tanyaka wants to merge 17 commits into
ionos-dev-v33from
ionos-dev-v33-enhanced-theming
Open

feat(theming): consolidate IONOS theming into apps/theming#321
tanyaka wants to merge 17 commits into
ionos-dev-v33from
ionos-dev-v33-enhanced-theming

Conversation

@tanyaka

@tanyaka tanyaka commented Aug 21, 2026

Copy link
Copy Markdown

Summary

Migrates IONOS-specific theming out of the two external submodules (`apps-custom/nc_theming`, `themes/nc-ionos-theme`) and into the core `apps/theming` app via a native `IonosTheme` class that implements Nextcloud's `ITheme` interface.

What changed

  • New `IonosTheme` class (`apps/theming/lib/Themes/IonosTheme.php`): implements `ITheme`, registered in `ThemesService` as `enforce_theme = ionos`. Provides IONOS color palette as CSS variables, custom CSS via `getCustomCss()`, Open Sans font-faces via `@font-face`, a `color-scheme: light dark` meta tag, and a dynamic `--current-year` variable (set from `date('Y')`) for the footer copyright string.
  • New test (`apps/theming/tests/Themes/IonosThemeTest.php`): 10 tests, 1 skipped (CSS `light-dark()` values not evaluatable by the hex checker). All other ThemesService tests pass (23/23).
  • IONOS CSS + assets migrated to `apps/theming/css/ionos/` and `apps/theming/img/` / `apps/theming/fonts/`.
  • Submodules removed from `.gitmodules` (`nc_theming`, `nc-ionos-theme`).
  • IONOS nc-config submodule bumped — see companion PR in nc-config (feat(theming): migrate from nc_theming to apps/theming IonosTheme nc-config#151): switches `enforce_theme = ionos`, updates favicon path, clears slogan (footer text now provided by CSS).
  • simplenavigation submodule bumped — see companion PR (fix(styles): resize header icons to 30px and tighten gap nc-simplenavigation#42): header icons resized to 30px, unified-search SVG max-size fix, icon gap 8px, IONOS logo on guest/share-link pages with full-width fixed header.
  • Layout fixes (browser-tested):
    • `body` background-color set for IONOS light/dark mode
    • `#content-vue` margin preserves `--header-height` offset
    • `--header-height` set to `64px` to match `simplenavigation`'s forced `height: 64px !important`
    • `--body-container-margin` set to `0px` to remove the 8px bottom gap
    • "Files settings" button hidden in sidebar (rule ported from `nc-ionos-theme/core/css/server.css`)
    • Breadcrumb button horizontal padding restored
    • `--color-primary-element` adapts to light/dark mode
  • CSS variable fix (`IonosTheme.php`): removed `--default-line-height: 24px` override. NC core uses this variable as a unitless multiplier in `calc()` expressions (e.g. `calc(var(--default-line-height) * 6 * var(--font-size-small))`). A `px` value produces `px²` which is invalid and silently collapses to `0px`. The default unitless `1.5` is visually equivalent (`1.5 × 15px = 22.5px`).
  • `public_share.css` (`apps/theming/css/ionos/public_share.css`): login page footer — removes box-shadow, centers full-width, replaces NC entity link text with `© YEAR IONOS SE` via CSS `::before` (year from `--current-year` variable; href still points to `ionos_homepage` from system config). Footer is hidden entirely on `body#body-public` (public share pages). Also contains `.guest-box` card styling for password-protected shares and file drop forms.
  • `files_sharing.css` reworked: removed ~560 lines of dead code referencing PHP-era selectors that no longer exist in V33 (`#header-primary-action`, `.files-filestable`, `#ionos-global-nav`, `#notemenu`, `#downloadFile.button`, etc. — all replaced by Vue-based rendering since NC 25). The file now only contains sharing sidebar styles (`#app-sidebar-vue .sharingTab`, `li.vs__dropdown-option`).
  • `buttons.css` fix: `#body-login a.button:hover` referenced undefined `--ion-button-tertiary-text-hover`; corrected to the existing `--ion-button-tertiary-text`.

Dependencies

Test plan

  • Run `phpunit apps/theming/tests/Themes/IonosThemeTest.php` — 10 tests pass, 1 skipped
  • Run `phpunit apps/theming/tests/Service/ThemesServiceTest.php` — 23/23 pass
  • Set `enforce_theme = ionos` in `config/config.php`, clear cache, verify IONOS theme loads
  • Verify `#content-vue` is not overlapping the header
  • Verify no 8px gap at the bottom of the viewport
  • Verify "Files settings" button is not visible in the sidebar settings section
  • Verify Open Sans font loads correctly
  • Verify body background is white in light mode, `#02102B` in dark mode
  • Verify header icons (search, mail, account) render at 30px
  • Verify breadcrumb "Alle Dateien" button has horizontal padding
  • Verify IONOS logo appears on password-protected share link pages (not the default NC logo)
  • Verify guest header spans full viewport width on share-link/login pages
  • Verify login page footer shows `© YEAR IONOS SE` centered, no shadow or background; year matches current year
  • Verify public share pages (`body#body-public`) show no footer
  • Verify password-protected share form box has IONOS card styling (rounded corners, correct background)
  • Verify two-factor provider selection page (`/login/selectchallenge`) — button hover/focus styles render correctly
  • Verify `AbsenceForm` and similar components using `calc(var(--default-line-height) * ...)` render at non-zero height
  • Confirm `nc_theming` and `nc-ionos-theme` submodules are no longer referenced

AI disclosure

This implementation was assisted by Claude Code (claude-sonnet-4-6). All code has been reviewed, tested in a live Nextcloud container, and browser-verified by the contributor.

@tanyaka
tanyaka force-pushed the ionos-dev-v33-enhanced-theming branch 5 times, most recently from c021630 to fffdd84 Compare August 27, 2026 13:16
Move IONOS theme class from apps-custom/nc_theming into the core
theming app, mirroring the ncw-server pattern.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
Inject IonosTheme into ThemesService so it is selectable and
enforceable via enforce_theme = 'ionos' in system config.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
@tanyaka
tanyaka force-pushed the ionos-dev-v33-enhanced-theming branch from fffdd84 to 99020e8 Compare August 27, 2026 13:20
@tanyaka
tanyaka requested a lite review from Copilot August 27, 2026 13:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates IONOS-specific theming from external submodules into the core apps/theming app by introducing a native IonosTheme (ITheme implementation) and wiring it into ThemesService, alongside new CSS/assets and targeted tests.

Changes:

  • Added OCA\Theming\Themes\IonosTheme and registered it in ThemesService (including enforce_theme=ionos behavior).
  • Migrated IONOS styling into apps/theming/css/ionos/* and added Open Sans font assets.
  • Added/updated PHPUnit tests to cover the new theme and enforced-theme theme list.

Reviewed changes

Copilot reviewed 18 out of 34 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
apps/theming/lib/Themes/IonosTheme.php New theme implementation providing IONOS variables, custom CSS, and font-face generation
apps/theming/lib/Service/ThemesService.php Registers ionos theme provider in service and supports enforced theme selection including ionos
apps/theming/tests/Themes/IonosThemeTest.php New unit tests for IonosTheme metadata/CSS variables/custom CSS
apps/theming/tests/Service/ThemesServiceTest.php Extends themes list assertions and adds enforced-ionos test case
apps/theming/css/ionos/_layout.css IONOS layout overrides (body background, header/content spacing)
apps/theming/css/ionos/variables.css IONOS design tokens expressed as CSS custom properties
apps/theming/css/ionos/navigation.css IONOS navigation styling overrides
apps/theming/css/ionos/buttons.css IONOS button styling overrides across contexts
apps/theming/css/ionos/files.css IONOS Files app UI tweaks (breadcrumbs, dialogs, hover/active styles)
apps/theming/css/ionos/files_sharing.css IONOS public/share page styling overrides
apps/theming/css/ionos/guest.css Guest/login footer styling adjustments and footer text replacement
apps/theming/fonts/OpenSans/OpenSans-Bold-webfont.svg Added Open Sans font asset (SVG)
apps/theming/composer/composer/autoload_static.php Adds classmap entry for IonosTheme
apps/theming/composer/composer/autoload_classmap.php Adds classmap entry for IonosTheme
.gitmodules Removes IONOS theming-related submodules

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/theming/lib/Themes/IonosTheme.php
Comment thread apps/theming/lib/Themes/IonosTheme.php
Comment thread apps/theming/css/ionos/files_sharing.css Outdated
Comment thread apps/theming/css/ionos/buttons.css
@tanyaka
tanyaka force-pushed the ionos-dev-v33-enhanced-theming branch 2 times, most recently from a9dc4e9 to b9bc12d Compare August 28, 2026 08:29
tanyaka added 13 commits August 28, 2026 14:08
Copy CSS files, Open Sans font variants, and favicon from
apps-custom/nc_theming into apps/theming in preparation for
submodule removal.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
Theming is now fully consolidated in apps/theming. The nc_theming
app (override via DI container) and nc-ionos-theme (OC_Theme product
identity) are no longer needed.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
Updates submodule pointer to include:
  - enforce_theme: 'ionos' (was 'nc-ionos-theme')
  - configure.sh: FAVICON_DIR points to apps/theming/img
  - Makefile: nc_theming build target removed

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
margin: 0 was removing the top margin that positions content below the
NC header. nc-ionos-theme's server.css previously compensated with
margin-top: 64px !important. Replace with margin-top: var(--header-height)
which is correct now that the OC_Theme is gone.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
simplenavigation forces #header to 64px via !important, so --header-height
must match for margin-top: var(--header-height) on #content-vue to be correct.
--body-container-margin defaults to 8px in NC (2 * grid-baseline) which left
a gap at the bottom; IONOS uses a flush full-height layout so 0px is correct.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
Port missing rule from nc-ionos-theme/core/css/server.css which was
previously loaded as OC_Theme CSS but is no longer applied.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
on breadcrumb new looking last button with a dropdown in V33


Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
… fix)

1.resize header icons

  References IONOS-Productivity/nc-simplenavigation#42 — mail/account
  icons 26px→30px, unified-search SVG max-size fix, icon gap 16px→8px.

2. fix parrword protected guest header

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
- Add --current-year CSS variable (set from date('Y') in IonosTheme::getCSSVariables())
  so the guest-page footer copyright year is not hardcoded
- Use content: '© ' var(--current-year) ' IONOS SE' in public_share.css

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
Removed and fallback to default --default-line-height: 1.5; from css/default.css

NC designed --default-line-height as a unitless ratio (like CSS
line-height: 1.5), not a length. It is used in expressions such as:

  calc(var(--default-line-height) * 6 * var(--font-size-small))

With 24px this becomes px * px (invalid unit), which the browser
discards — the property silently collapses to 0px. With the unitless
default 1.5 it becomes number * number * px = px, which is valid.

Setting a px value works where the variable is used directly as a
line-height property (lengths are accepted there), but breaks every
calc() multiplication. Removing the override lets DefaultTheme's 1.5
apply, which is visually equivalent (1.5 * 15px = 22.5px).

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
Remove ~560 lines targeting selectors that no longer exist in V33
(PHP-rendered public share UI was replaced by Vue in NC 25+):

- @media rules for #header-primary-action / #header-actions-menu
  (replaced by #public-page-menu--primary / #public-page-menu)
- #content.app-files_sharing subtree: .files-filestable, .files-controls,
  #view-toggle, #uploadprogressbar, .newFileMenu, .breadcrumb .crumbhome,
  #imgframe, #downloadFile.button, .popovermenu — all PHP-rendered, gone
- #notemenu — never existed in V33
- #ionos-global-nav — from old OC_Theme custom header template, gone
- .header-info :not(:has(+#content .directDownload)): .directDownload
  never exists in V33, permanently hiding .header-info (bug)

Keep V33-alive selectors:
- #app-sidebar-vue .sharingTab / .sharingTabDetailsView__quick-permissions
- .guest-box card (password-protected share / file drop form)
- li.vs__dropdown-option (SharingInput.vue uses Vue Select)

Hide footer on public share pages (body#body-public footer.guest-box):
layout.public.php renders a footer that is not part of the IONOS
public share design.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
…lic_share.css

files_sharing.css now only contains sharing sidebar styles
(#app-sidebar-vue .sharingTab, li.vs__dropdown-option).

public_share.css gets the public page rules:
- body#body-public footer.guest-box: hide footer on public share pages
- .guest-box: card styling for password-protected shares and file drops

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
@tanyaka
tanyaka force-pushed the ionos-dev-v33-enhanced-theming branch from 075c75f to 061ddf6 Compare August 28, 2026 12:54
… hover

The original rule referenced --ion-button-tertiary-text-hover which is
not defined anywhere in the IONOS CSS variables. Replace with the
existing --ion-button-tertiary-text variable.

The #body-login a.button selectors are live code: they target the
two-factor provider selection page (twofactorselectchallenge.php),
which renders under RENDER_AS_GUEST (body#body-login) and contains
<a class="button primary two-factor-primary"> elements.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
… SBOM matrix

Both submodules (apps-custom/nc_theming and themes/nc-ionos-theme)
were removed in a prior commit. Remove their SBOM matrix entries and
the comment referencing the legacy theme. IONOS theming is now part
of apps/theming which is covered by the root nextcloud entry.

Signed-off-by: Tatjana Kaschperko Lindt <[email protected]>
Assisted-by: ClaudeCode:claude-sonnet-4-6
@tanyaka tanyaka added this to the web-v33-1 milestone Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants