Files
FixIt/assets/js/modules/core.ts
T
Cell 8af8e806d7 feat(assets): integrate UnoCSS for utility classes and presetIcons (#795)
* refactor(assets): integrate UnoCSS for utility classes

- Add UnoCSS with presetWind3 as pre-built CSS (assets/css/unocss.css)
- Add uno.config.ts with theme breakpoints, colors, safelist, and blocklist
- Replace SCSS utility classes with UnoCSS atomic classes:
  - d-none → hidden
  - d-none-desktop → sm:hidden
  - d-none-mobile → max-sm:hidden
  - order-* (safelist)
  - variant-numeric → tabular-nums lining-nums
- Rename .blur to .is-blur to avoid UnoCSS conflict
- Add @unocss-skip comments for SVG path elements to prevent false positives
- Remove redundant _utilities.scss ($orders map) and simplify _common.scss
- Update documentation (CLAUDE.md, CONTRIBUTING.md, copilot-instructions.md)

* refactor(assets): replace 404/offline SCSS with UnoCSS atomic classes

- Replace _404.scss styles with atomic classes on template elements
- Replace _offline.scss styles with atomic classes on template elements
- Keep selectors (id/class) as user customization hooks
- Delete assets/scss/pages/_404.scss and _offline.scss

* refactor(assets): simplify SCSS with UnoCSS atomic classes

- Replace _bilibili.scss with atomic classes (relative, aspect-video, inset-0)
- Replace _version.scss with atomic classes (whitespace-nowrap, align-text-bottom)
- Replace _noscript-warning.scss with atomic classes (bg-danger, fixed, z-200)
- Add semantic z-index shortcuts (z-hide, z-auto, z-base, z-loading, z-sticky, z-fixed)
- Add h1-h6 to UnoCSS blocklist to prevent false positives
- Use Source path for UnoCSS CSS loading to enable Hugo minify

* chore(assets): minor SCSS and template cleanup

* fix(assets): add secondary color to UnoCSS theme config

text-secondary was broken because the secondary color mapping was missing.

* feat(assets): add UnoCSS presetIcons support and z-index shortcuts

- Add presetIcons preset with empty collections (ready for custom icon sets)
- Add @iconify/json and @iconify/utils devDependencies
- Add semantic z-index shortcuts (z-hide, z-auto, z-base, z-loading, z-sticky, z-fixed)
- Add secondary color to UnoCSS theme config

* refactor(assets): replace SVG icons with UnoCSS presetIcons

- Add Lucide and Octicons icon collections to presetIcons config
- Replace arrow-up/down and enter-key SVGs with Lucide icons
- Replace alert icons (info, light-bulb, report, alert, stop) with Octicons
- Delete replaced SVG files from assets/images/icons/
- Keep custom SVGs (csdn, plume, rootme)

* refactor(layouts): redesign 404 and offline pages with UnoCSS

- Replace translate-y-[30vh] with self-stretch flex centering below header
- Remove arbitrary values (text-[3.6rem], text-[1.8rem], etc.)
- Restore @page print styles in _common.scss
- Simplify offline page layout (icon + title + text)
- Fix hardcoded #57606a → text-secondary
2026-06-27 06:27:12 +08:00

88 lines
2.6 KiB
TypeScript

import type { CoreService } from '../core/tokens'
import type { FixItConfig, MaskOverlayHandler } from '../types'
import { getThemeMode, isDarkMode } from '../utils'
/**
* Core module — shared state initialization and mask overlay management.
*
* Responsibilities:
* - Load and expose page/site configuration from `window.config`.
* - Track theme mode (light/dark) and provide `isDark` / `themeMode` accessors.
* - Manage mask overlay visibility for search and menu drawers.
*/
export class CoreModule implements CoreService {
readonly config: FixItConfig
readonly version: string
themeMode: string
isDark: boolean
private activeMaskOverlay: string | null = null
private readonly maskOverlays = new Map<string, MaskOverlayHandler>()
constructor() {
this.config = window.config
this.version = this.config.version
this.themeMode = getThemeMode()
this.isDark = isDarkMode()
window.objectFitImages?.()
}
/** Register a named mask overlay with open/close/isActive handlers. */
registerMaskOverlay(name: string, handlers: MaskOverlayHandler) {
this.maskOverlays.set(name, handlers)
}
/** Toggle the mask element's blur class based on active overlay state. */
syncMaskState() {
document.getElementById('mask')?.classList.toggle('is-blur', Boolean(this.activeMaskOverlay))
}
/** Open a named mask overlay, closing any previously active one. */
openMaskOverlay(name: string) {
const overlay = this.maskOverlays.get(name)
if (!overlay)
return
if (this.activeMaskOverlay && this.activeMaskOverlay !== name) {
this.closeMaskOverlay(this.activeMaskOverlay, true)
}
overlay.onOpen?.()
this.activeMaskOverlay = name
this.syncMaskState()
}
/** Close a named mask overlay and optionally skip mask state sync. */
closeMaskOverlay(name: string, skipSync = false) {
const overlay = this.maskOverlays.get(name)
if (!overlay)
return
overlay.onClose?.()
if (this.activeMaskOverlay === name) {
this.activeMaskOverlay = null
}
!skipSync && this.syncMaskState()
}
/** Toggle a named mask overlay open/closed. */
toggleMaskOverlay(name: string) {
const overlay = this.maskOverlays.get(name)
if (!overlay)
return
const isActive = overlay.isActive?.() ?? this.activeMaskOverlay === name
if (this.activeMaskOverlay === name && isActive) {
this.closeMaskOverlay(name)
return
}
this.openMaskOverlay(name)
}
/** Close whichever mask overlay is currently active. */
closeActiveMaskOverlay() {
if (!this.activeMaskOverlay) {
this.syncMaskState()
return
}
this.closeMaskOverlay(this.activeMaskOverlay)
}
}