Class AppPaletteCSS

java.lang.Object
com.iizix.prop.AppPaletteCSS

public final class AppPaletteCSS extends Object
The application's palette block: the app's palette colors and families delivered to the client as CSS custom properties, generated by the server at session start and installed at the app location, after the shipped theme sheet, so that an app overrides a role simply by redefining it (THEME-DESIGN.md sections 4.5 and 5, phase B2).

What the block holds. One rule per scheme. The default rule (:root, and :root[data-iz-scheme][data-iz-mode] so that it outranks the shipped sheet's family blocks) declares the 37 role aliases, --izc-accent:var(--iz-acc), so that a bare role reference follows the family in force; then every palette color of every module under its module-qualified slug (ColorSlug), --izc-lib-brand-primary:#0A84FF, with its value for the light scheme; then one alias per palette color for its module-relative form, --izc-brand-primary:var(--izc-lib-brand-primary), so that %/style/Brand/Primary and %Lib:/style/Brand/Primary both resolve; then the role overrides, --iz-bd:var(--izc-app-border), for every palette color named by a role at the top of a module's style folder. The dark rule, for the shipped families' dark members, and a rule per custom scheme (an app family) declare what differs from light; a palette color without a value for a scheme falls through to the default rule by the cascade, exactly as ColorResolver falls back to the default scheme. A page that runs no theme script gets the dark values from a prefers-color-scheme media rule, as the shipped sheet gives it the dark tokens.

Custom themes. After those rules, every AppTheme of every module gets one rule per mode, :root[data-iz-scheme="ocean"][data-iz-mode="light"] and the same with dark, holding color-scheme and all 48 tokens - the 37 roles and the 11 shape, type and motion tokens of ThemeTokens - so that a theme is complete whatever it sets (order CC-THEME-TE1-MODEL). The value of each token composes, later winning: the theme's base family's member for that mode, read from the shipped sheet (ThemeSheetPalette.getSheet()); then the application's role override, as var() of the overriding color, so that the app's brand reaches a theme that does not speak of that role; then the theme's own value, a literal or a var() of the palette color it points at. A theme with one member writes it under both selectors. The dark rule above also selects every theme family that has a dark member, so that a palette color's dark value is what a theme's dark member points at. A theme whose family name is reserved or invalid, whose base is unknown, or whose family name another theme also folds to, is refused with an error naming it; the rest of the block is delivered.

Values. A literal is written as GColor.getCSSValue() writes it. A pointer at another palette color is written as var() of that color's slug, so that a chain of references is a chain of custom properties the browser follows, a palette edit changes one declaration, and a pointer that ends in a platform role follows the family; a pointer the resolver reports as a cycle, too deep or missing is written as the unresolved magenta, what the resolver sends as the fallback. Every value is decided by ColorResolver, the one algorithm; the block only spells its answer in CSS.

Collisions. Every name goes through a ColorSlug.Table. Two palette colors whose module-qualified paths fold to one slug are both refused, with an error naming the pair: neither is delivered, and a panel referencing either paints the fallback the server resolved. A module-relative alias that another module or a role already owns is refused with a warning; the module-qualified form still works. Two modules overriding one role are both refused as overrides.

Delivery and the delta. push(PropCnr,Collection,PropCnr) sets the block as the client root's $palette string property, which iz/ClientProps.js writes into one style element at the app location. Calling it again after a palette edit is the delta push: the property model carries the block only when it changed, and the client rewrites its element. The theme roller (a later phase) calls it; nothing else needs to.

Author:
Christopher Mindus
  • Field Details

    • ATOM

      public static final Atom ATOM
      The name of the client root's string property that carries the block: $palette.
  • Method Details

    • push

      public static boolean push(PropCnr clientRoot, Collection<? extends PropCnr> moduleRoots, PropCnr basePalette)
      Generates the block and sets it as the client root's $palette property: at session start the installation, later the delta push after a palette edit. The refusals are logged here, an error per colliding pair and a warning per alias not delivered.
      Parameters:
      clientRoot - The client root property container.
      moduleRoots - The application's module roots, each holding its style folder.
      basePalette - The platform base palette, or null for none.
      Returns:
      true when the property changed, false when the block is what the client already has.
    • generate

      public static AppPaletteCSS.Block generate(Collection<? extends PropCnr> moduleRoots, PropCnr basePalette)
      Generates the block, the custom themes composed on the installed sheet's members (ThemeSheetPalette.getSheet()).
      Parameters:
      moduleRoots - The application's module roots, each holding its style folder; a root without one contributes nothing.
      basePalette - The platform base palette, or null for none.
      Returns:
      The block, never null: at least the default rule with the role aliases.
    • generate

      public static AppPaletteCSS.Block generate(Collection<? extends PropCnr> moduleRoots, PropCnr basePalette, ThemeSheetPalette.Sheet sheet)
      Generates the block.
      Parameters:
      moduleRoots - The application's module roots, each holding its style folder; a root without one contributes nothing.
      basePalette - The platform base palette, or null for none.
      sheet - The family members of the shipped sheet the custom themes are composed on, or null for none: every theme is then refused.
      Returns:
      The block, never null: at least the default rule with the role aliases.