diff --git a/news/changelog-1.8.md b/news/changelog-1.8.md index 6fb2558af1d..34e0fba015e 100644 --- a/news/changelog-1.8.md +++ b/news/changelog-1.8.md @@ -19,6 +19,7 @@ All changes included in 1.8: - ([#12734](https://github.com/quarto-dev/quarto-cli/issues/12734)): `highlight-style` now correctly supports setting a different `light` and `dark`. - ([#12747](https://github.com/quarto-dev/quarto-cli/issues/12747)): Ensure `th` elements are properly restored when Quarto's HTML table processing is happening. - ([#12766](https://github.com/quarto-dev/quarto-cli/issues/12766)): Use consistent equation numbering display for `html-math-method` and `html-math-method.method` for MathJax and KaTeX (author: @mcanouil) +- ([#12797](https://github.com/quarto-dev/quarto-cli/issues/12797)): Allow light and dark brands to be specified in one file, by specializing colors with `light:` and `dark:`. ### `revealjs` diff --git a/src/core/brand/brand.ts b/src/core/brand/brand.ts index 94fc0edd425..3fe5666a262 100644 --- a/src/core/brand/brand.ts +++ b/src/core/brand/brand.ts @@ -7,13 +7,16 @@ */ import { - Brand as BrandJson, + BrandColorLightDark, BrandFont, BrandLogoExplicitResource, BrandNamedThemeColor, - BrandTypography, + BrandSingle, BrandTypographyOptionsBase, - BrandTypographyOptionsHeadings, + BrandTypographyOptionsHeadingsSingle, + BrandTypographySingle, + BrandTypographyUnified, + BrandUnified, Zod, } from "../../resources/types/zod/schema-types.ts"; import { InternalError } from "../lib/error.ts"; @@ -53,7 +56,7 @@ type CanonicalLogoInfo = { type ProcessedBrandData = { color: Record; - typography: BrandTypography; + typography: BrandTypographySingle; logo: { small?: CanonicalLogoInfo; medium?: CanonicalLogoInfo; @@ -63,7 +66,7 @@ type ProcessedBrandData = { }; export class Brand { - data: BrandJson; + data: BrandSingle; brandDir: string; projectDir: string; processedData: ProcessedBrandData; @@ -73,13 +76,13 @@ export class Brand { brandDir: string, projectDir: string, ) { - this.data = Zod.Brand.parse(brand); + this.data = Zod.BrandSingle.parse(brand); this.brandDir = brandDir; this.projectDir = projectDir; this.processedData = this.processData(this.data); } - processData(data: BrandJson): ProcessedBrandData { + processData(data: BrandSingle): ProcessedBrandData { const color: Record = {}; for (const colorName of Object.keys(data.color?.palette ?? {})) { color[colorName] = this.getColor(colorName); @@ -91,7 +94,7 @@ export class Brand { color[colorName] = this.getColor(colorName); } - const typography: BrandTypography = {}; + const typography: BrandTypographySingle = {}; const base = this.getFont("base"); if (base) { typography.base = base; @@ -221,7 +224,10 @@ export class Brand { getFont( name: string, - ): BrandTypographyOptionsBase | BrandTypographyOptionsHeadings | undefined { + ): + | BrandTypographyOptionsBase + | BrandTypographyOptionsHeadingsSingle + | undefined { if (!this.data.typography) { return undefined; } @@ -304,6 +310,11 @@ export type LightDarkBrand = { dark?: Brand; }; +export type LightDarkColor = { + light?: string; + dark?: string; +}; + export const getFavicon = (brand: Brand): string | undefined => { const logoInfo = brand.getLogo("small"); if (!logoInfo) { @@ -311,3 +322,241 @@ export const getFavicon = (brand: Brand): string | undefined => { } return logoInfo.light.path; }; + +function splitColorLightDark( + bcld: BrandColorLightDark, +): LightDarkColor { + if (typeof bcld === "string") { + return { light: bcld, dark: bcld }; + } + return bcld; +} +function colorIsUnified(blcd: BrandColorLightDark) { + return typeof blcd === "object" && "dark" in blcd; +} +export function brandIsUnified(brand: BrandUnified): boolean { + if (brand.color) { + for (const colorName of Zod.BrandNamedThemeColor.options) { + if (!brand.color[colorName]) { + continue; + } + if (colorIsUnified(brand.color![colorName])) { + return true; + } + } + } + if (brand.typography) { + for (const elementName of Zod.BrandNamedTypographyElements.options) { + const element = brand.typography![elementName]; + if (!element || typeof element === "string") { + continue; + } + if ( + "background-color" in element && element["background-color"] && + colorIsUnified(element["background-color"]) + ) { + return true; + } + if ( + "color" in element && element["color"] && + colorIsUnified(element["color"]) + ) { + return true; + } + } + } + return false; +} +function sharedTypography( + unified: BrandTypographyUnified, +): BrandTypographySingle { + const ret: BrandTypographySingle = { + fonts: unified.fonts, + }; + for (const elementName of Zod.BrandNamedTypographyElements.options) { + if (!unified[elementName]) { + continue; + } + if (typeof unified[elementName] === "string") { + ret[elementName] = unified[elementName]; + continue; + } + ret[elementName] = Object.fromEntries( + Object.entries(unified[elementName]).filter( + ([key, _]) => !["color", "background-color"].includes(key), + ), + ); + } + return ret; +} +export function splitUnifiedBrand( + unified: unknown, + brandDir: string, + projectDir: string, +): LightDarkBrand { + const unifiedBrand: BrandUnified = Zod.BrandUnified.parse(unified); + let typography: BrandTypographySingle | undefined = undefined; + let headingsColor: LightDarkColor | undefined = undefined; + let monospaceColor: LightDarkColor | undefined = undefined; + let monospaceBackgroundColor: LightDarkColor | undefined = undefined; + let monospaceInlineColor: LightDarkColor | undefined = undefined; + let monospaceInlineBackgroundColor: LightDarkColor | undefined = undefined; + let monospaceBlockColor: LightDarkColor | undefined = undefined; + let monospaceBlockBackgroundColor: LightDarkColor | undefined = undefined; + let linkColor: LightDarkColor | undefined = undefined; + let linkBackgroundColor: LightDarkColor | undefined = undefined; + if (unifiedBrand.typography) { + typography = sharedTypography(unifiedBrand.typography); + if ( + unifiedBrand.typography.headings && + typeof unifiedBrand.typography.headings !== "string" && + unifiedBrand.typography.headings.color + ) { + headingsColor = splitColorLightDark( + unifiedBrand.typography.headings.color, + ); + } + if ( + unifiedBrand.typography.monospace && + typeof unifiedBrand.typography.monospace !== "string" + ) { + if (unifiedBrand.typography.monospace.color) { + monospaceColor = splitColorLightDark( + unifiedBrand.typography.monospace.color, + ); + } + if (unifiedBrand.typography.monospace["background-color"]) { + monospaceBackgroundColor = splitColorLightDark( + unifiedBrand.typography.monospace["background-color"], + ); + } + } + if ( + unifiedBrand.typography["monospace-inline"] && + typeof unifiedBrand.typography["monospace-inline"] !== "string" + ) { + if (unifiedBrand.typography["monospace-inline"].color) { + monospaceInlineColor = splitColorLightDark( + unifiedBrand.typography["monospace-inline"].color, + ); + } + if (unifiedBrand.typography["monospace-inline"]["background-color"]) { + monospaceInlineBackgroundColor = splitColorLightDark( + unifiedBrand.typography["monospace-inline"]["background-color"], + ); + } + } + if ( + unifiedBrand.typography["monospace-block"] && + typeof unifiedBrand.typography["monospace-block"] !== "string" + ) { + if (unifiedBrand.typography["monospace-block"].color) { + monospaceBlockColor = splitColorLightDark( + unifiedBrand.typography["monospace-block"].color, + ); + } + if (unifiedBrand.typography["monospace-block"]["background-color"]) { + monospaceBlockBackgroundColor = splitColorLightDark( + unifiedBrand.typography["monospace-block"]["background-color"], + ); + } + } + if ( + unifiedBrand.typography.link && + typeof unifiedBrand.typography.link !== "string" + ) { + if (unifiedBrand.typography.link.color) { + linkColor = splitColorLightDark( + unifiedBrand.typography.link.color, + ); + } + if (unifiedBrand.typography.link["background-color"]) { + linkBackgroundColor = splitColorLightDark( + unifiedBrand.typography.link["background-color"], + ); + } + } + } + const specializeTypography = ( + typography: BrandTypographySingle, + mode: "light" | "dark", + ) => + typography && { + fonts: typography.fonts && [...typography.fonts], + base: !typography.base || typeof typography.base === "string" + ? typography.base + : { ...typography.base }, + headings: !typography.headings || typeof typography.headings === "string" + ? typography.headings + : { + ...typography.headings, + color: headingsColor && headingsColor[mode], + }, + monospace: + !typography.monospace || typeof typography.monospace === "string" + ? typography.monospace + : { + ...typography.monospace, + color: monospaceColor && monospaceColor[mode], + "background-color": monospaceBackgroundColor && + monospaceBackgroundColor[mode], + }, + "monospace-inline": !typography["monospace-inline"] || + typeof typography["monospace-inline"] === "string" + ? typography["monospace-inline"] + : { + ...typography["monospace-inline"], + color: monospaceInlineColor && monospaceInlineColor[mode], + "background-color": monospaceInlineBackgroundColor && + monospaceInlineBackgroundColor[mode], + }, + "monospace-block": !typography["monospace-block"] || + typeof typography["monospace-block"] === "string" + ? typography["monospace-block"] + : { + ...typography["monospace-block"], + color: monospaceBlockColor && monospaceBlockColor[mode], + "background-color": monospaceBlockBackgroundColor && + monospaceBlockBackgroundColor[mode], + }, + link: !typography.link || typeof typography.link === "string" + ? typography.link + : { + ...typography.link, + color: linkColor && linkColor[mode], + "background-color": linkBackgroundColor && + linkBackgroundColor[mode], + }, + }; + const lightBrand: BrandSingle = { + meta: unifiedBrand.meta, + color: { palette: unifiedBrand.color && { ...unifiedBrand.color.palette } }, + typography: typography && specializeTypography(typography, "light"), + logo: unifiedBrand.logo, + defaults: unifiedBrand.defaults, + }; + const darkBrand: BrandSingle = { + meta: unifiedBrand.meta, + color: { palette: unifiedBrand.color && { ...unifiedBrand.color.palette } }, + typography: typography && specializeTypography(typography, "dark"), + logo: unifiedBrand.logo, + defaults: unifiedBrand.defaults, + }; + if (unifiedBrand.color) { + for (const colorName of Zod.BrandNamedThemeColor.options) { + if (!unifiedBrand.color[colorName]) { + continue; + } + ({ + light: lightBrand.color![colorName], + dark: darkBrand.color![colorName], + } = splitColorLightDark(unifiedBrand.color![colorName])); + } + } + return { + light: new Brand(lightBrand, brandDir, projectDir), + dark: brandIsUnified(unifiedBrand) + ? new Brand(darkBrand, brandDir, projectDir) + : undefined, + }; +} diff --git a/src/core/sass/brand.ts b/src/core/sass/brand.ts index 69ab57f4599..c85daeb4941 100644 --- a/src/core/sass/brand.ts +++ b/src/core/sass/brand.ts @@ -664,7 +664,7 @@ export async function brandSassFormatExtras( dark: htmlSassBundleLayers.dark.length ? { user: htmlSassBundleLayers.dark, - default: darkModeDefault(format.metadata), + default: darkModeDefault(format), } : undefined, }, diff --git a/src/format/html/format-html-bootstrap.ts b/src/format/html/format-html-bootstrap.ts index b414422c810..0d5a51f46f6 100644 --- a/src/format/html/format-html-bootstrap.ts +++ b/src/format/html/format-html-bootstrap.ts @@ -1072,7 +1072,7 @@ function bootstrapHtmlFinalizer(format: Format, flags: PandocFlags) { // start body with light or dark class for proper display when JS is disabled let initialLightDarkClass = "quarto-light"; - if (darkModeDefault(format.metadata)) { + if (darkModeDefault(format)) { initialLightDarkClass = "quarto-dark"; } doc.body.classList.add(initialLightDarkClass); diff --git a/src/format/html/format-html-info.ts b/src/format/html/format-html-info.ts index d5923c3bbb2..6477d752f3a 100644 --- a/src/format/html/format-html-info.ts +++ b/src/format/html/format-html-info.ts @@ -6,7 +6,7 @@ * Copyright (C) 2020-2022 Posit Software, PBC */ -import { kTheme, kBrand } from "../../config/constants.ts"; +import { kBrand, kTheme } from "../../config/constants.ts"; import { isHtmlDashboardOutput, isHtmlOutput } from "../../config/format.ts"; import { Format, Metadata } from "../../config/types.ts"; @@ -33,16 +33,28 @@ export function hasBootstrapTheme(metadata: Metadata) { export function formatDarkMode(format: Format): boolean | undefined { const isBootstrap = formatHasBootstrap(format); if (isBootstrap) { - return darkModeDefault(format.metadata); + return darkModeDefault(format); } return undefined; } -export function darkModeDefault(metadata?: Metadata): boolean | undefined { +export function darkModeDefault(format: Format): boolean | undefined { + const metadata = format.metadata; + const brand = format.render.brand; if (metadata !== undefined) { - for (const darkable of [metadata[kTheme], metadata[kBrand]]) { - if (darkable && typeof (darkable) === "object") { - const keys = Object.keys(darkable); + if (metadata[kTheme] && typeof metadata[kTheme] === "object") { + const keys = Object.keys(metadata[kTheme]); + if (keys.includes("dark")) { + if (keys[0] === "dark") { + return true; + } else { + return false; + } + } + } + if (metadata[kBrand] || brand) { + if (metadata[kBrand] && typeof metadata[kBrand] === "object") { + const keys = Object.keys(metadata[kBrand]); if (keys.includes("dark")) { if (keys[0] === "dark") { return true; @@ -51,6 +63,10 @@ export function darkModeDefault(metadata?: Metadata): boolean | undefined { } } } + if (brand && brand.dark) { + // unified brand has no author preference but it can have dark mode + return false; + } } } return undefined; diff --git a/src/format/html/format-html.ts b/src/format/html/format-html.ts index 6f1d1446516..0116419ce82 100644 --- a/src/format/html/format-html.ts +++ b/src/format/html/format-html.ts @@ -349,7 +349,7 @@ export async function htmlFormatExtras( options.zenscroll = format.metadata[kSmoothScroll]; options.codeTools = formatHasCodeTools(format); options.darkMode = formatDarkMode(format); - options.darkModeDefault = darkModeDefault(format.metadata); + options.darkModeDefault = darkModeDefault(format); options.respectUserColorScheme = format.metadata[kRespectUserColorScheme] || false; options.linkExternalIcon = format.render[kLinkExternalIcon]; diff --git a/src/project/project-shared.ts b/src/project/project-shared.ts index 234908ecc34..6557d9dd9c9 100644 --- a/src/project/project-shared.ts +++ b/src/project/project-shared.ts @@ -48,9 +48,13 @@ import { DirectiveCell } from "../core/lib/break-quarto-md-types.ts"; import { QuartoJSONSchema, readYamlFromMarkdown } from "../core/yaml.ts"; import { refSchema } from "../core/lib/yaml-schema/common.ts"; import { Zod } from "../resources/types/zod/schema-types.ts"; -import { Brand } from "../core/brand/brand.ts"; +import { + Brand, + LightDarkBrand, + splitUnifiedBrand, +} from "../core/brand/brand.ts"; import { assert } from "testing/asserts"; -import { Cloneable } from "../core/safe-clone-deep.ts"; +import { Cloneable, safeCloneDeep } from "../core/safe-clone-deep.ts"; export function projectExcludeDirs(context: ProjectContext): string[] { const outputDir = projectOutputDir(context); @@ -517,25 +521,33 @@ export async function projectResolveBrand( project: ProjectContext, fileName?: string, ): Promise<{ light?: Brand; dark?: Brand } | undefined> { - async function loadBrand(brandPath: string): Promise { + async function loadSingleBrand(brandPath: string): Promise { const brand = await readAndValidateYamlFromFile( brandPath, - refSchema("brand", "Format-independent brand configuration."), + refSchema("brand-single", "Format-independent brand configuration."), "Brand validation failed for " + brandPath + ".", ); return new Brand(brand, dirname(brandPath), project.dir); } - async function loadRelativeBrand( + async function loadUnifiedBrand(brandPath: string): Promise { + const brand = await readAndValidateYamlFromFile( + brandPath, + refSchema("brand-unified", "Format-independent brand configuration."), + "Brand validation failed for " + brandPath + ".", + ); + return splitUnifiedBrand(brand, dirname(brandPath), project.dir); + } + function resolveBrandPath( brandPath: string, dir: string = dirname(fileName!), - ): Promise { + ): string { let resolved: string = ""; if (brandPath.startsWith("/")) { resolved = join(project.dir, brandPath); } else { resolved = join(dir, brandPath); } - return await loadBrand(resolved); + return resolved; } if (fileName === undefined) { if (project.brandCache) { @@ -559,10 +571,10 @@ export async function projectResolveBrand( ) { project.brandCache.brand = { light: brand.light - ? await loadRelativeBrand(brand.light, project.dir) + ? await loadSingleBrand(resolveBrandPath(brand.light, project.dir)) : undefined, dark: brand.dark - ? await loadRelativeBrand(brand.dark, project.dir) + ? await loadSingleBrand(resolveBrandPath(brand.dark, project.dir)) : undefined, }; return project.brandCache.brand; @@ -575,7 +587,7 @@ export async function projectResolveBrand( if (!existsSync(brandPath)) { continue; } - project.brandCache.brand = { light: await loadBrand(brandPath) }; + project.brandCache.brand = await loadUnifiedBrand(brandPath); } return project.brandCache.brand; } else { @@ -595,14 +607,14 @@ export async function projectResolveBrand( return fileInformation.brand; } if (typeof brand === "string") { - fileInformation.brand = { light: await loadRelativeBrand(brand) }; + fileInformation.brand = await loadUnifiedBrand(resolveBrandPath(brand)); return fileInformation.brand; } else { assert(typeof brand === "object"); if ("light" in brand || "dark" in brand) { let light, dark; if (typeof brand.light === "string") { - light = await loadRelativeBrand(brand.light); + light = await loadSingleBrand(resolveBrandPath(brand.light)); } else if (brand.light) { light = new Brand( brand.light, @@ -611,7 +623,7 @@ export async function projectResolveBrand( ); } if (typeof brand.dark === "string") { - dark = await loadRelativeBrand(brand.dark); + dark = await loadSingleBrand(resolveBrandPath(brand.dark)); } else if (brand.dark) { dark = new Brand( brand.dark, @@ -621,13 +633,11 @@ export async function projectResolveBrand( } fileInformation.brand = { light, dark }; } else { - fileInformation.brand = { - light: new Brand( - brand, - dirname(fileName), - project.dir, - ), - }; + fileInformation.brand = splitUnifiedBrand( + brand, + dirname(fileName), + project.dir, + ); } return fileInformation.brand; } diff --git a/src/resources/editor/tools/vs-code.mjs b/src/resources/editor/tools/vs-code.mjs index 313786325b5..aa2f3d08db9 100644 --- a/src/resources/editor/tools/vs-code.mjs +++ b/src/resources/editor/tools/vs-code.mjs @@ -11927,7 +11927,40 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-logo", + id: "brand-logo-single", + description: "Provide definitions and defaults for brand's logo in various formats and sizes.\n", + object: { + closed: true, + properties: { + images: { + description: "A dictionary of named logo resources.", + schema: { + object: { + additionalProperties: { + schema: { + ref: "brand-logo-resource" + } + } + } + } + }, + small: { + description: "A link or path to the brand's small-sized logo or icon.\n", + schema: "string" + }, + medium: { + description: "A link or path to the brand's medium-sized logo.\n", + schema: "string" + }, + large: { + description: "A link or path to the brand's large- or full-sized logo.\n", + schema: "string" + } + } + } + }, + { + id: "brand-logo-unified", description: "Provide definitions and defaults for brand's logo in various formats and sizes.\n", object: { closed: true, @@ -11979,7 +12012,7 @@ var require_yaml_intelligence_resources = __commonJS({ schema: "string" }, { - id: "brand-color", + id: "brand-color-single", description: "The brand's custom color palette and theme.\n", object: { closed: true, @@ -12071,6 +12104,126 @@ var require_yaml_intelligence_resources = __commonJS({ } } }, + { + id: "brand-color-light-dark", + anyOf: [ + { + ref: "brand-color-value" + }, + { + object: { + closed: true, + properties: { + light: { + schema: { + ref: "brand-color-value" + }, + description: "A link or path to the brand's light-colored logo or icon.\n" + }, + dark: { + schema: { + ref: "brand-color-value" + }, + description: "A link or path to the brand's dark-colored logo or icon.\n" + } + } + } + } + ] + }, + { + id: "brand-color-unified", + description: "The brand's custom color palette and theme.\n", + object: { + closed: true, + properties: { + palette: { + description: "The brand's custom color palette. Any number of colors can be defined, each color having a custom name.\n", + object: { + additionalProperties: { + schema: { + ref: "brand-color-value" + } + } + } + }, + foreground: { + description: "The foreground color, used for text.", + schema: { + ref: "brand-color-light-dark" + }, + default: "black" + }, + background: { + description: "The background color, used for the page background.", + schema: { + ref: "brand-color-light-dark" + }, + default: "white" + }, + primary: { + description: "The primary accent color, i.e. the main theme color. Typically used for hyperlinks, active states, primary action buttons, etc.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + secondary: { + description: "The secondary accent color. Typically used for lighter text or disabled states.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + tertiary: { + description: "The tertiary accent color. Typically an even lighter color, used for hover states, accents, and wells.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + success: { + description: "The color used for positive or successful actions and information.", + schema: { + ref: "brand-color-light-dark" + } + }, + info: { + description: "The color used for neutral or informational actions and information.", + schema: { + ref: "brand-color-light-dark" + } + }, + warning: { + description: "The color used for warning or cautionary actions and information.", + schema: { + ref: "brand-color-light-dark" + } + }, + danger: { + description: "The color used for errors, dangerous actions, or negative information.", + schema: { + ref: "brand-color-light-dark" + } + }, + light: { + description: "A bright color, used as a high-contrast foreground color on dark elements or low-contrast background color on light elements.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + dark: { + description: "A dark color, used as a high-contrast foreground color on light elements or high-contrast background color on light elements.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + link: { + description: "The color used for hyperlinks. If not defined, the `primary` color is used.\n", + schema: { + ref: "brand-color-light-dark" + } + } + } + } + }, { id: "brand-maybe-named-color", description: "A color, which may be a named brand color.\n", @@ -12083,6 +12236,33 @@ var require_yaml_intelligence_resources = __commonJS({ } ] }, + { + id: "brand-maybe-named-color-light-dark", + anyOf: [ + { + ref: "brand-maybe-named-color" + }, + { + object: { + closed: true, + properties: { + light: { + schema: { + ref: "brand-maybe-named-color" + }, + description: "A link or path to the brand's light-colored logo or icon.\n" + }, + dark: { + schema: { + ref: "brand-maybe-named-color" + }, + description: "A link or path to the brand's dark-colored logo or icon.\n" + } + } + } + } + ] + }, { id: "brand-named-theme-color", description: "A named brand color, taken either from `color.theme` or `color.palette` (in that order).\n", @@ -12102,7 +12282,7 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-typography", + id: "brand-typography-single", description: "Typography definitions for the brand.", object: { closed: true, @@ -12119,23 +12299,62 @@ var require_yaml_intelligence_resources = __commonJS({ }, headings: { description: "Settings for headings, or a string specifying the font family only.", - ref: "brand-typography-options-headings" + ref: "brand-typography-options-headings-single" }, monospace: { description: "Settings for monospace text, or a string specifying the font family only.", - ref: "brand-typography-options-monospace" + ref: "brand-typography-options-monospace-single" }, "monospace-inline": { description: "Settings for inline code, or a string specifying the font family only.", - ref: "brand-typography-options-monospace-inline" + ref: "brand-typography-options-monospace-inline-single" }, "monospace-block": { description: "Settings for code blocks, or a string specifying the font family only.", - ref: "brand-typography-options-monospace-block" + ref: "brand-typography-options-monospace-block-single" }, link: { description: "Settings for links.", - ref: "brand-typography-options-link" + ref: "brand-typography-options-link-single" + } + } + } + }, + { + id: "brand-typography-unified", + description: "Typography definitions for the brand.", + object: { + closed: true, + properties: { + fonts: { + description: "Font files and definitions for the brand.", + arrayOf: { + ref: "brand-font" + } + }, + base: { + description: "The base font settings for the brand. These are used as the default for all text.\n", + ref: "brand-typography-options-base" + }, + headings: { + description: "Settings for headings, or a string specifying the font family only.", + ref: "brand-typography-options-headings-unified" + }, + monospace: { + description: "Settings for monospace text, or a string specifying the font family only.", + ref: "brand-typography-options-monospace-unified" + }, + "monospace-inline": { + description: "Settings for inline code, or a string specifying the font family only.", + ref: "brand-typography-options-monospace-inline-unified" + }, + "monospace-block": { + description: "Settings for code blocks, or a string specifying the font family only.", + ref: "brand-typography-options-monospace-block-unified" + }, + link: { + description: "Settings for links.", + ref: "brand-typography-options-link-unified" } } } @@ -12163,7 +12382,7 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-typography-options-headings", + id: "brand-typography-options-headings-single", description: "Typographic options for headings.", anyOf: [ "string", @@ -12190,7 +12409,34 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-typography-options-monospace", + id: "brand-typography-options-headings-unified", + description: "Typographic options for headings.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + weight: { + ref: "brand-font-weight" + }, + style: { + ref: "brand-font-style" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "line-height": { + ref: "line-height-number-string" + } + } + } + } + ] + }, + { + id: "brand-typography-options-monospace-single", description: "Typographic options for monospace elements.", anyOf: [ "string", @@ -12215,7 +12461,32 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-typography-options-monospace-inline", + id: "brand-typography-options-monospace-unified", + description: "Typographic options for monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + size: "string", + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + } + } + } + } + ] + }, + { + id: "brand-typography-options-monospace-inline-single", description: "Typographic options for inline monospace elements.", anyOf: [ "string", @@ -12239,6 +12510,31 @@ var require_yaml_intelligence_resources = __commonJS({ } ] }, + { + id: "brand-typography-options-monospace-inline-unified", + description: "Typographic options for inline monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + size: "string", + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + } + } + } + } + ] + }, { id: "line-height-number-string", description: "Line height", @@ -12248,7 +12544,7 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-typography-options-monospace-block", + id: "brand-typography-options-monospace-block-single", description: "Typographic options for block monospace elements.", anyOf: [ "string", @@ -12276,7 +12572,35 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-typography-options-link", + id: "brand-typography-options-monospace-block-unified", + description: "Typographic options for block monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + size: "string", + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + }, + "line-height": { + ref: "line-height-number-string" + } + } + } + } + ] + }, + { + id: "brand-typography-options-link-single", description: "Typographic options for inline monospace elements.", anyOf: [ "string", @@ -12300,12 +12624,39 @@ var require_yaml_intelligence_resources = __commonJS({ ] }, { - id: "brand-named-font", - description: "Names of customizeable fonts", + id: "brand-typography-options-link-unified", + description: "Typographic options for inline monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + }, + decoration: "string" + } + } + } + ] + }, + { + id: "brand-named-typography-elements", + description: "Names of customizeable typography elements", enum: [ "base", "headings", - "monospace" + "monospace", + "monospace-inline", + "monospace-block", + "link" ] }, { @@ -12522,7 +12873,7 @@ var require_yaml_intelligence_resources = __commonJS({ schema: "string" }, { - id: "brand", + id: "brand-single", object: { closed: true, properties: { @@ -12530,13 +12881,36 @@ var require_yaml_intelligence_resources = __commonJS({ ref: "brand-meta" }, logo: { - ref: "brand-logo" + ref: "brand-logo-unified" }, color: { - ref: "brand-color" + ref: "brand-color-single" }, typography: { - ref: "brand-typography" + ref: "brand-typography-single" + }, + defaults: { + ref: "brand-defaults" + } + } + } + }, + { + id: "brand-unified", + object: { + closed: true, + properties: { + meta: { + ref: "brand-meta" + }, + logo: { + ref: "brand-logo-unified" + }, + color: { + ref: "brand-color-unified" + }, + typography: { + ref: "brand-typography-unified" }, defaults: { ref: "brand-defaults" @@ -12557,7 +12931,7 @@ var require_yaml_intelligence_resources = __commonJS({ anyOf: [ "string", { - ref: "brand" + ref: "brand-single" } ], description: "The path to a light brand file or an inline light brand definition.\n" @@ -12566,7 +12940,7 @@ var require_yaml_intelligence_resources = __commonJS({ anyOf: [ "string", { - ref: "brand" + ref: "brand-single" } ], description: "The path to a dark brand file or an inline dark brand definition.\n" @@ -12575,10 +12949,10 @@ var require_yaml_intelligence_resources = __commonJS({ } }, { - ref: "brand" + ref: "brand-unified" } ], - description: "Branding information to use for this document. If a string, the path to a brand file.\nIf false, don't use branding on this document. If an object, an inline brand\ndefinition, or an object with light and dark brand paths or definitions.\n" + description: "Branding information to use for this document. If a string, the path to a brand file.\nIf false, don't use branding on this document. If an object, an inline (unified) brand\ndefinition, or an object with light and dark brand paths or definitions.\n" }, { id: "brand-defaults", @@ -22255,6 +22629,7 @@ var require_yaml_intelligence_resources = __commonJS({ "Document title", "Identifies the subtitle of the document.", "Document date", + "Date format for the document", "Document date modified", "Author or authors of the document", { @@ -24117,7 +24492,75 @@ var require_yaml_intelligence_resources = __commonJS({ "Manuscript configuration", "internal-schema-hack", "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto\u2019s default order\nis \u2018knitr\u2019, \u2018jupyter\u2019, \u2018markdown\u2019, \u2018julia\u2019.", - "Date format for the document" + "Provide definitions and defaults for brand\u2019s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", + "A link or path to the brand\u2019s small-sized logo or icon.", + "A link or path to the brand\u2019s medium-sized logo.", + "A link or path to the brand\u2019s large- or full-sized logo.", + "Provide definitions and defaults for brand\u2019s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", + "A link or path to the brand\u2019s small-sized logo or icon, or a link or\npath to both the light and dark versions.", + "A link or path to the brand\u2019s medium-sized logo, or a link or path to\nboth the light and dark versions.", + "A link or path to the brand\u2019s large- or full-sized logo, or a link or\npath to both the light and dark versions.", + "The brand\u2019s custom color palette and theme.", + "The brand\u2019s custom color palette. Any number of colors can be\ndefined, each color having a custom name.", + "The foreground color, used for text.", + "The background color, used for the page background.", + "The primary accent color, i.e. the main theme color. Typically used\nfor hyperlinks, active states, primary action buttons, etc.", + "The secondary accent color. Typically used for lighter text or\ndisabled states.", + "The tertiary accent color. Typically an even lighter color, used for\nhover states, accents, and wells.", + "The color used for positive or successful actions and\ninformation.", + "The color used for neutral or informational actions and\ninformation.", + "The color used for warning or cautionary actions and information.", + "The color used for errors, dangerous actions, or negative\ninformation.", + "A bright color, used as a high-contrast foreground color on dark\nelements or low-contrast background color on light elements.", + "A dark color, used as a high-contrast foreground color on light\nelements or high-contrast background color on light elements.", + "The color used for hyperlinks. If not defined, the\nprimary color is used.", + "A link or path to the brand\u2019s light-colored logo or icon.", + "A link or path to the brand\u2019s dark-colored logo or icon.", + "The brand\u2019s custom color palette and theme.", + "The brand\u2019s custom color palette. Any number of colors can be\ndefined, each color having a custom name.", + "The foreground color, used for text.", + "The background color, used for the page background.", + "The primary accent color, i.e. the main theme color. Typically used\nfor hyperlinks, active states, primary action buttons, etc.", + "The secondary accent color. Typically used for lighter text or\ndisabled states.", + "The tertiary accent color. Typically an even lighter color, used for\nhover states, accents, and wells.", + "The color used for positive or successful actions and\ninformation.", + "The color used for neutral or informational actions and\ninformation.", + "The color used for warning or cautionary actions and information.", + "The color used for errors, dangerous actions, or negative\ninformation.", + "A bright color, used as a high-contrast foreground color on dark\nelements or low-contrast background color on light elements.", + "A dark color, used as a high-contrast foreground color on light\nelements or high-contrast background color on light elements.", + "The color used for hyperlinks. If not defined, the\nprimary color is used.", + "A link or path to the brand\u2019s light-colored logo or icon.", + "A link or path to the brand\u2019s dark-colored logo or icon.", + "Typography definitions for the brand.", + "Font files and definitions for the brand.", + "The base font settings for the brand. These are used as the default\nfor all text.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Typography definitions for the brand.", + "Font files and definitions for the brand.", + "The base font settings for the brand. These are used as the default\nfor all text.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Typographic options for headings.", + "Typographic options for headings.", + "Typographic options for monospace elements.", + "Typographic options for monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for block monospace elements.", + "Typographic options for block monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for inline monospace elements.", + "Names of customizeable typography elements" ], "schema/external-schemas.yml": [ { @@ -24346,12 +24789,12 @@ var require_yaml_intelligence_resources = __commonJS({ mermaid: "%%" }, "handlers/mermaid/schema.yml": { - _internalId: 196444, + _internalId: 197022, type: "object", description: "be an object", properties: { "mermaid-format": { - _internalId: 196436, + _internalId: 197014, type: "enum", enum: [ "png", @@ -24367,7 +24810,7 @@ var require_yaml_intelligence_resources = __commonJS({ exhaustiveCompletions: true }, theme: { - _internalId: 196443, + _internalId: 197021, type: "anyOf", anyOf: [ { diff --git a/src/resources/editor/tools/yaml/web-worker.js b/src/resources/editor/tools/yaml/web-worker.js index 952163776c1..a50cbb1a528 100644 --- a/src/resources/editor/tools/yaml/web-worker.js +++ b/src/resources/editor/tools/yaml/web-worker.js @@ -11928,7 +11928,40 @@ try { ] }, { - id: "brand-logo", + id: "brand-logo-single", + description: "Provide definitions and defaults for brand's logo in various formats and sizes.\n", + object: { + closed: true, + properties: { + images: { + description: "A dictionary of named logo resources.", + schema: { + object: { + additionalProperties: { + schema: { + ref: "brand-logo-resource" + } + } + } + } + }, + small: { + description: "A link or path to the brand's small-sized logo or icon.\n", + schema: "string" + }, + medium: { + description: "A link or path to the brand's medium-sized logo.\n", + schema: "string" + }, + large: { + description: "A link or path to the brand's large- or full-sized logo.\n", + schema: "string" + } + } + } + }, + { + id: "brand-logo-unified", description: "Provide definitions and defaults for brand's logo in various formats and sizes.\n", object: { closed: true, @@ -11980,7 +12013,7 @@ try { schema: "string" }, { - id: "brand-color", + id: "brand-color-single", description: "The brand's custom color palette and theme.\n", object: { closed: true, @@ -12072,6 +12105,126 @@ try { } } }, + { + id: "brand-color-light-dark", + anyOf: [ + { + ref: "brand-color-value" + }, + { + object: { + closed: true, + properties: { + light: { + schema: { + ref: "brand-color-value" + }, + description: "A link or path to the brand's light-colored logo or icon.\n" + }, + dark: { + schema: { + ref: "brand-color-value" + }, + description: "A link or path to the brand's dark-colored logo or icon.\n" + } + } + } + } + ] + }, + { + id: "brand-color-unified", + description: "The brand's custom color palette and theme.\n", + object: { + closed: true, + properties: { + palette: { + description: "The brand's custom color palette. Any number of colors can be defined, each color having a custom name.\n", + object: { + additionalProperties: { + schema: { + ref: "brand-color-value" + } + } + } + }, + foreground: { + description: "The foreground color, used for text.", + schema: { + ref: "brand-color-light-dark" + }, + default: "black" + }, + background: { + description: "The background color, used for the page background.", + schema: { + ref: "brand-color-light-dark" + }, + default: "white" + }, + primary: { + description: "The primary accent color, i.e. the main theme color. Typically used for hyperlinks, active states, primary action buttons, etc.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + secondary: { + description: "The secondary accent color. Typically used for lighter text or disabled states.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + tertiary: { + description: "The tertiary accent color. Typically an even lighter color, used for hover states, accents, and wells.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + success: { + description: "The color used for positive or successful actions and information.", + schema: { + ref: "brand-color-light-dark" + } + }, + info: { + description: "The color used for neutral or informational actions and information.", + schema: { + ref: "brand-color-light-dark" + } + }, + warning: { + description: "The color used for warning or cautionary actions and information.", + schema: { + ref: "brand-color-light-dark" + } + }, + danger: { + description: "The color used for errors, dangerous actions, or negative information.", + schema: { + ref: "brand-color-light-dark" + } + }, + light: { + description: "A bright color, used as a high-contrast foreground color on dark elements or low-contrast background color on light elements.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + dark: { + description: "A dark color, used as a high-contrast foreground color on light elements or high-contrast background color on light elements.\n", + schema: { + ref: "brand-color-light-dark" + } + }, + link: { + description: "The color used for hyperlinks. If not defined, the `primary` color is used.\n", + schema: { + ref: "brand-color-light-dark" + } + } + } + } + }, { id: "brand-maybe-named-color", description: "A color, which may be a named brand color.\n", @@ -12084,6 +12237,33 @@ try { } ] }, + { + id: "brand-maybe-named-color-light-dark", + anyOf: [ + { + ref: "brand-maybe-named-color" + }, + { + object: { + closed: true, + properties: { + light: { + schema: { + ref: "brand-maybe-named-color" + }, + description: "A link or path to the brand's light-colored logo or icon.\n" + }, + dark: { + schema: { + ref: "brand-maybe-named-color" + }, + description: "A link or path to the brand's dark-colored logo or icon.\n" + } + } + } + } + ] + }, { id: "brand-named-theme-color", description: "A named brand color, taken either from `color.theme` or `color.palette` (in that order).\n", @@ -12103,7 +12283,7 @@ try { ] }, { - id: "brand-typography", + id: "brand-typography-single", description: "Typography definitions for the brand.", object: { closed: true, @@ -12120,23 +12300,62 @@ try { }, headings: { description: "Settings for headings, or a string specifying the font family only.", - ref: "brand-typography-options-headings" + ref: "brand-typography-options-headings-single" }, monospace: { description: "Settings for monospace text, or a string specifying the font family only.", - ref: "brand-typography-options-monospace" + ref: "brand-typography-options-monospace-single" }, "monospace-inline": { description: "Settings for inline code, or a string specifying the font family only.", - ref: "brand-typography-options-monospace-inline" + ref: "brand-typography-options-monospace-inline-single" }, "monospace-block": { description: "Settings for code blocks, or a string specifying the font family only.", - ref: "brand-typography-options-monospace-block" + ref: "brand-typography-options-monospace-block-single" }, link: { description: "Settings for links.", - ref: "brand-typography-options-link" + ref: "brand-typography-options-link-single" + } + } + } + }, + { + id: "brand-typography-unified", + description: "Typography definitions for the brand.", + object: { + closed: true, + properties: { + fonts: { + description: "Font files and definitions for the brand.", + arrayOf: { + ref: "brand-font" + } + }, + base: { + description: "The base font settings for the brand. These are used as the default for all text.\n", + ref: "brand-typography-options-base" + }, + headings: { + description: "Settings for headings, or a string specifying the font family only.", + ref: "brand-typography-options-headings-unified" + }, + monospace: { + description: "Settings for monospace text, or a string specifying the font family only.", + ref: "brand-typography-options-monospace-unified" + }, + "monospace-inline": { + description: "Settings for inline code, or a string specifying the font family only.", + ref: "brand-typography-options-monospace-inline-unified" + }, + "monospace-block": { + description: "Settings for code blocks, or a string specifying the font family only.", + ref: "brand-typography-options-monospace-block-unified" + }, + link: { + description: "Settings for links.", + ref: "brand-typography-options-link-unified" } } } @@ -12164,7 +12383,7 @@ try { ] }, { - id: "brand-typography-options-headings", + id: "brand-typography-options-headings-single", description: "Typographic options for headings.", anyOf: [ "string", @@ -12191,7 +12410,34 @@ try { ] }, { - id: "brand-typography-options-monospace", + id: "brand-typography-options-headings-unified", + description: "Typographic options for headings.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + weight: { + ref: "brand-font-weight" + }, + style: { + ref: "brand-font-style" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "line-height": { + ref: "line-height-number-string" + } + } + } + } + ] + }, + { + id: "brand-typography-options-monospace-single", description: "Typographic options for monospace elements.", anyOf: [ "string", @@ -12216,7 +12462,32 @@ try { ] }, { - id: "brand-typography-options-monospace-inline", + id: "brand-typography-options-monospace-unified", + description: "Typographic options for monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + size: "string", + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + } + } + } + } + ] + }, + { + id: "brand-typography-options-monospace-inline-single", description: "Typographic options for inline monospace elements.", anyOf: [ "string", @@ -12240,6 +12511,31 @@ try { } ] }, + { + id: "brand-typography-options-monospace-inline-unified", + description: "Typographic options for inline monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + size: "string", + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + } + } + } + } + ] + }, { id: "line-height-number-string", description: "Line height", @@ -12249,7 +12545,7 @@ try { ] }, { - id: "brand-typography-options-monospace-block", + id: "brand-typography-options-monospace-block-single", description: "Typographic options for block monospace elements.", anyOf: [ "string", @@ -12277,7 +12573,35 @@ try { ] }, { - id: "brand-typography-options-link", + id: "brand-typography-options-monospace-block-unified", + description: "Typographic options for block monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + family: "string", + size: "string", + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + }, + "line-height": { + ref: "line-height-number-string" + } + } + } + } + ] + }, + { + id: "brand-typography-options-link-single", description: "Typographic options for inline monospace elements.", anyOf: [ "string", @@ -12301,12 +12625,39 @@ try { ] }, { - id: "brand-named-font", - description: "Names of customizeable fonts", + id: "brand-typography-options-link-unified", + description: "Typographic options for inline monospace elements.", + anyOf: [ + "string", + { + object: { + closed: true, + properties: { + weight: { + ref: "brand-font-weight" + }, + color: { + ref: "brand-maybe-named-color-light-dark" + }, + "background-color": { + ref: "brand-maybe-named-color-light-dark" + }, + decoration: "string" + } + } + } + ] + }, + { + id: "brand-named-typography-elements", + description: "Names of customizeable typography elements", enum: [ "base", "headings", - "monospace" + "monospace", + "monospace-inline", + "monospace-block", + "link" ] }, { @@ -12523,7 +12874,7 @@ try { schema: "string" }, { - id: "brand", + id: "brand-single", object: { closed: true, properties: { @@ -12531,13 +12882,36 @@ try { ref: "brand-meta" }, logo: { - ref: "brand-logo" + ref: "brand-logo-unified" }, color: { - ref: "brand-color" + ref: "brand-color-single" }, typography: { - ref: "brand-typography" + ref: "brand-typography-single" + }, + defaults: { + ref: "brand-defaults" + } + } + } + }, + { + id: "brand-unified", + object: { + closed: true, + properties: { + meta: { + ref: "brand-meta" + }, + logo: { + ref: "brand-logo-unified" + }, + color: { + ref: "brand-color-unified" + }, + typography: { + ref: "brand-typography-unified" }, defaults: { ref: "brand-defaults" @@ -12558,7 +12932,7 @@ try { anyOf: [ "string", { - ref: "brand" + ref: "brand-single" } ], description: "The path to a light brand file or an inline light brand definition.\n" @@ -12567,7 +12941,7 @@ try { anyOf: [ "string", { - ref: "brand" + ref: "brand-single" } ], description: "The path to a dark brand file or an inline dark brand definition.\n" @@ -12576,10 +12950,10 @@ try { } }, { - ref: "brand" + ref: "brand-unified" } ], - description: "Branding information to use for this document. If a string, the path to a brand file.\nIf false, don't use branding on this document. If an object, an inline brand\ndefinition, or an object with light and dark brand paths or definitions.\n" + description: "Branding information to use for this document. If a string, the path to a brand file.\nIf false, don't use branding on this document. If an object, an inline (unified) brand\ndefinition, or an object with light and dark brand paths or definitions.\n" }, { id: "brand-defaults", @@ -22256,6 +22630,7 @@ try { "Document title", "Identifies the subtitle of the document.", "Document date", + "Date format for the document", "Document date modified", "Author or authors of the document", { @@ -24118,7 +24493,75 @@ try { "Manuscript configuration", "internal-schema-hack", "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto\u2019s default order\nis \u2018knitr\u2019, \u2018jupyter\u2019, \u2018markdown\u2019, \u2018julia\u2019.", - "Date format for the document" + "Provide definitions and defaults for brand\u2019s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", + "A link or path to the brand\u2019s small-sized logo or icon.", + "A link or path to the brand\u2019s medium-sized logo.", + "A link or path to the brand\u2019s large- or full-sized logo.", + "Provide definitions and defaults for brand\u2019s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", + "A link or path to the brand\u2019s small-sized logo or icon, or a link or\npath to both the light and dark versions.", + "A link or path to the brand\u2019s medium-sized logo, or a link or path to\nboth the light and dark versions.", + "A link or path to the brand\u2019s large- or full-sized logo, or a link or\npath to both the light and dark versions.", + "The brand\u2019s custom color palette and theme.", + "The brand\u2019s custom color palette. Any number of colors can be\ndefined, each color having a custom name.", + "The foreground color, used for text.", + "The background color, used for the page background.", + "The primary accent color, i.e. the main theme color. Typically used\nfor hyperlinks, active states, primary action buttons, etc.", + "The secondary accent color. Typically used for lighter text or\ndisabled states.", + "The tertiary accent color. Typically an even lighter color, used for\nhover states, accents, and wells.", + "The color used for positive or successful actions and\ninformation.", + "The color used for neutral or informational actions and\ninformation.", + "The color used for warning or cautionary actions and information.", + "The color used for errors, dangerous actions, or negative\ninformation.", + "A bright color, used as a high-contrast foreground color on dark\nelements or low-contrast background color on light elements.", + "A dark color, used as a high-contrast foreground color on light\nelements or high-contrast background color on light elements.", + "The color used for hyperlinks. If not defined, the\nprimary color is used.", + "A link or path to the brand\u2019s light-colored logo or icon.", + "A link or path to the brand\u2019s dark-colored logo or icon.", + "The brand\u2019s custom color palette and theme.", + "The brand\u2019s custom color palette. Any number of colors can be\ndefined, each color having a custom name.", + "The foreground color, used for text.", + "The background color, used for the page background.", + "The primary accent color, i.e. the main theme color. Typically used\nfor hyperlinks, active states, primary action buttons, etc.", + "The secondary accent color. Typically used for lighter text or\ndisabled states.", + "The tertiary accent color. Typically an even lighter color, used for\nhover states, accents, and wells.", + "The color used for positive or successful actions and\ninformation.", + "The color used for neutral or informational actions and\ninformation.", + "The color used for warning or cautionary actions and information.", + "The color used for errors, dangerous actions, or negative\ninformation.", + "A bright color, used as a high-contrast foreground color on dark\nelements or low-contrast background color on light elements.", + "A dark color, used as a high-contrast foreground color on light\nelements or high-contrast background color on light elements.", + "The color used for hyperlinks. If not defined, the\nprimary color is used.", + "A link or path to the brand\u2019s light-colored logo or icon.", + "A link or path to the brand\u2019s dark-colored logo or icon.", + "Typography definitions for the brand.", + "Font files and definitions for the brand.", + "The base font settings for the brand. These are used as the default\nfor all text.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Typography definitions for the brand.", + "Font files and definitions for the brand.", + "The base font settings for the brand. These are used as the default\nfor all text.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Typographic options for headings.", + "Typographic options for headings.", + "Typographic options for monospace elements.", + "Typographic options for monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for block monospace elements.", + "Typographic options for block monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for inline monospace elements.", + "Names of customizeable typography elements" ], "schema/external-schemas.yml": [ { @@ -24347,12 +24790,12 @@ try { mermaid: "%%" }, "handlers/mermaid/schema.yml": { - _internalId: 196444, + _internalId: 197022, type: "object", description: "be an object", properties: { "mermaid-format": { - _internalId: 196436, + _internalId: 197014, type: "enum", enum: [ "png", @@ -24368,7 +24811,7 @@ try { exhaustiveCompletions: true }, theme: { - _internalId: 196443, + _internalId: 197021, type: "anyOf", anyOf: [ { diff --git a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json index 72577b32391..ee5aeabc094 100644 --- a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json +++ b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json @@ -4899,7 +4899,40 @@ ] }, { - "id": "brand-logo", + "id": "brand-logo-single", + "description": "Provide definitions and defaults for brand's logo in various formats and sizes.\n", + "object": { + "closed": true, + "properties": { + "images": { + "description": "A dictionary of named logo resources.", + "schema": { + "object": { + "additionalProperties": { + "schema": { + "ref": "brand-logo-resource" + } + } + } + } + }, + "small": { + "description": "A link or path to the brand's small-sized logo or icon.\n", + "schema": "string" + }, + "medium": { + "description": "A link or path to the brand's medium-sized logo.\n", + "schema": "string" + }, + "large": { + "description": "A link or path to the brand's large- or full-sized logo.\n", + "schema": "string" + } + } + } + }, + { + "id": "brand-logo-unified", "description": "Provide definitions and defaults for brand's logo in various formats and sizes.\n", "object": { "closed": true, @@ -4951,7 +4984,7 @@ "schema": "string" }, { - "id": "brand-color", + "id": "brand-color-single", "description": "The brand's custom color palette and theme.\n", "object": { "closed": true, @@ -5043,6 +5076,126 @@ } } }, + { + "id": "brand-color-light-dark", + "anyOf": [ + { + "ref": "brand-color-value" + }, + { + "object": { + "closed": true, + "properties": { + "light": { + "schema": { + "ref": "brand-color-value" + }, + "description": "A link or path to the brand's light-colored logo or icon.\n" + }, + "dark": { + "schema": { + "ref": "brand-color-value" + }, + "description": "A link or path to the brand's dark-colored logo or icon.\n" + } + } + } + } + ] + }, + { + "id": "brand-color-unified", + "description": "The brand's custom color palette and theme.\n", + "object": { + "closed": true, + "properties": { + "palette": { + "description": "The brand's custom color palette. Any number of colors can be defined, each color having a custom name.\n", + "object": { + "additionalProperties": { + "schema": { + "ref": "brand-color-value" + } + } + } + }, + "foreground": { + "description": "The foreground color, used for text.", + "schema": { + "ref": "brand-color-light-dark" + }, + "default": "black" + }, + "background": { + "description": "The background color, used for the page background.", + "schema": { + "ref": "brand-color-light-dark" + }, + "default": "white" + }, + "primary": { + "description": "The primary accent color, i.e. the main theme color. Typically used for hyperlinks, active states, primary action buttons, etc.\n", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "secondary": { + "description": "The secondary accent color. Typically used for lighter text or disabled states.\n", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "tertiary": { + "description": "The tertiary accent color. Typically an even lighter color, used for hover states, accents, and wells.\n", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "success": { + "description": "The color used for positive or successful actions and information.", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "info": { + "description": "The color used for neutral or informational actions and information.", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "warning": { + "description": "The color used for warning or cautionary actions and information.", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "danger": { + "description": "The color used for errors, dangerous actions, or negative information.", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "light": { + "description": "A bright color, used as a high-contrast foreground color on dark elements or low-contrast background color on light elements.\n", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "dark": { + "description": "A dark color, used as a high-contrast foreground color on light elements or high-contrast background color on light elements.\n", + "schema": { + "ref": "brand-color-light-dark" + } + }, + "link": { + "description": "The color used for hyperlinks. If not defined, the `primary` color is used.\n", + "schema": { + "ref": "brand-color-light-dark" + } + } + } + } + }, { "id": "brand-maybe-named-color", "description": "A color, which may be a named brand color.\n", @@ -5055,6 +5208,33 @@ } ] }, + { + "id": "brand-maybe-named-color-light-dark", + "anyOf": [ + { + "ref": "brand-maybe-named-color" + }, + { + "object": { + "closed": true, + "properties": { + "light": { + "schema": { + "ref": "brand-maybe-named-color" + }, + "description": "A link or path to the brand's light-colored logo or icon.\n" + }, + "dark": { + "schema": { + "ref": "brand-maybe-named-color" + }, + "description": "A link or path to the brand's dark-colored logo or icon.\n" + } + } + } + } + ] + }, { "id": "brand-named-theme-color", "description": "A named brand color, taken either from `color.theme` or `color.palette` (in that order).\n", @@ -5074,7 +5254,7 @@ ] }, { - "id": "brand-typography", + "id": "brand-typography-single", "description": "Typography definitions for the brand.", "object": { "closed": true, @@ -5091,23 +5271,62 @@ }, "headings": { "description": "Settings for headings, or a string specifying the font family only.", - "ref": "brand-typography-options-headings" + "ref": "brand-typography-options-headings-single" }, "monospace": { "description": "Settings for monospace text, or a string specifying the font family only.", - "ref": "brand-typography-options-monospace" + "ref": "brand-typography-options-monospace-single" }, "monospace-inline": { "description": "Settings for inline code, or a string specifying the font family only.", - "ref": "brand-typography-options-monospace-inline" + "ref": "brand-typography-options-monospace-inline-single" }, "monospace-block": { "description": "Settings for code blocks, or a string specifying the font family only.", - "ref": "brand-typography-options-monospace-block" + "ref": "brand-typography-options-monospace-block-single" }, "link": { "description": "Settings for links.", - "ref": "brand-typography-options-link" + "ref": "brand-typography-options-link-single" + } + } + } + }, + { + "id": "brand-typography-unified", + "description": "Typography definitions for the brand.", + "object": { + "closed": true, + "properties": { + "fonts": { + "description": "Font files and definitions for the brand.", + "arrayOf": { + "ref": "brand-font" + } + }, + "base": { + "description": "The base font settings for the brand. These are used as the default for all text.\n", + "ref": "brand-typography-options-base" + }, + "headings": { + "description": "Settings for headings, or a string specifying the font family only.", + "ref": "brand-typography-options-headings-unified" + }, + "monospace": { + "description": "Settings for monospace text, or a string specifying the font family only.", + "ref": "brand-typography-options-monospace-unified" + }, + "monospace-inline": { + "description": "Settings for inline code, or a string specifying the font family only.", + "ref": "brand-typography-options-monospace-inline-unified" + }, + "monospace-block": { + "description": "Settings for code blocks, or a string specifying the font family only.", + "ref": "brand-typography-options-monospace-block-unified" + }, + "link": { + "description": "Settings for links.", + "ref": "brand-typography-options-link-unified" } } } @@ -5135,7 +5354,7 @@ ] }, { - "id": "brand-typography-options-headings", + "id": "brand-typography-options-headings-single", "description": "Typographic options for headings.", "anyOf": [ "string", @@ -5162,7 +5381,34 @@ ] }, { - "id": "brand-typography-options-monospace", + "id": "brand-typography-options-headings-unified", + "description": "Typographic options for headings.", + "anyOf": [ + "string", + { + "object": { + "closed": true, + "properties": { + "family": "string", + "weight": { + "ref": "brand-font-weight" + }, + "style": { + "ref": "brand-font-style" + }, + "color": { + "ref": "brand-maybe-named-color-light-dark" + }, + "line-height": { + "ref": "line-height-number-string" + } + } + } + } + ] + }, + { + "id": "brand-typography-options-monospace-single", "description": "Typographic options for monospace elements.", "anyOf": [ "string", @@ -5187,7 +5433,32 @@ ] }, { - "id": "brand-typography-options-monospace-inline", + "id": "brand-typography-options-monospace-unified", + "description": "Typographic options for monospace elements.", + "anyOf": [ + "string", + { + "object": { + "closed": true, + "properties": { + "family": "string", + "size": "string", + "weight": { + "ref": "brand-font-weight" + }, + "color": { + "ref": "brand-maybe-named-color-light-dark" + }, + "background-color": { + "ref": "brand-maybe-named-color-light-dark" + } + } + } + } + ] + }, + { + "id": "brand-typography-options-monospace-inline-single", "description": "Typographic options for inline monospace elements.", "anyOf": [ "string", @@ -5211,6 +5482,31 @@ } ] }, + { + "id": "brand-typography-options-monospace-inline-unified", + "description": "Typographic options for inline monospace elements.", + "anyOf": [ + "string", + { + "object": { + "closed": true, + "properties": { + "family": "string", + "size": "string", + "weight": { + "ref": "brand-font-weight" + }, + "color": { + "ref": "brand-maybe-named-color-light-dark" + }, + "background-color": { + "ref": "brand-maybe-named-color-light-dark" + } + } + } + } + ] + }, { "id": "line-height-number-string", "description": "Line height", @@ -5220,7 +5516,7 @@ ] }, { - "id": "brand-typography-options-monospace-block", + "id": "brand-typography-options-monospace-block-single", "description": "Typographic options for block monospace elements.", "anyOf": [ "string", @@ -5248,7 +5544,35 @@ ] }, { - "id": "brand-typography-options-link", + "id": "brand-typography-options-monospace-block-unified", + "description": "Typographic options for block monospace elements.", + "anyOf": [ + "string", + { + "object": { + "closed": true, + "properties": { + "family": "string", + "size": "string", + "weight": { + "ref": "brand-font-weight" + }, + "color": { + "ref": "brand-maybe-named-color-light-dark" + }, + "background-color": { + "ref": "brand-maybe-named-color-light-dark" + }, + "line-height": { + "ref": "line-height-number-string" + } + } + } + } + ] + }, + { + "id": "brand-typography-options-link-single", "description": "Typographic options for inline monospace elements.", "anyOf": [ "string", @@ -5272,12 +5596,39 @@ ] }, { - "id": "brand-named-font", - "description": "Names of customizeable fonts", + "id": "brand-typography-options-link-unified", + "description": "Typographic options for inline monospace elements.", + "anyOf": [ + "string", + { + "object": { + "closed": true, + "properties": { + "weight": { + "ref": "brand-font-weight" + }, + "color": { + "ref": "brand-maybe-named-color-light-dark" + }, + "background-color": { + "ref": "brand-maybe-named-color-light-dark" + }, + "decoration": "string" + } + } + } + ] + }, + { + "id": "brand-named-typography-elements", + "description": "Names of customizeable typography elements", "enum": [ "base", "headings", - "monospace" + "monospace", + "monospace-inline", + "monospace-block", + "link" ] }, { @@ -5494,7 +5845,7 @@ "schema": "string" }, { - "id": "brand", + "id": "brand-single", "object": { "closed": true, "properties": { @@ -5502,13 +5853,36 @@ "ref": "brand-meta" }, "logo": { - "ref": "brand-logo" + "ref": "brand-logo-unified" }, "color": { - "ref": "brand-color" + "ref": "brand-color-single" }, "typography": { - "ref": "brand-typography" + "ref": "brand-typography-single" + }, + "defaults": { + "ref": "brand-defaults" + } + } + } + }, + { + "id": "brand-unified", + "object": { + "closed": true, + "properties": { + "meta": { + "ref": "brand-meta" + }, + "logo": { + "ref": "brand-logo-unified" + }, + "color": { + "ref": "brand-color-unified" + }, + "typography": { + "ref": "brand-typography-unified" }, "defaults": { "ref": "brand-defaults" @@ -5529,7 +5903,7 @@ "anyOf": [ "string", { - "ref": "brand" + "ref": "brand-single" } ], "description": "The path to a light brand file or an inline light brand definition.\n" @@ -5538,7 +5912,7 @@ "anyOf": [ "string", { - "ref": "brand" + "ref": "brand-single" } ], "description": "The path to a dark brand file or an inline dark brand definition.\n" @@ -5547,10 +5921,10 @@ } }, { - "ref": "brand" + "ref": "brand-unified" } ], - "description": "Branding information to use for this document. If a string, the path to a brand file.\nIf false, don't use branding on this document. If an object, an inline brand\ndefinition, or an object with light and dark brand paths or definitions.\n" + "description": "Branding information to use for this document. If a string, the path to a brand file.\nIf false, don't use branding on this document. If an object, an inline (unified) brand\ndefinition, or an object with light and dark brand paths or definitions.\n" }, { "id": "brand-defaults", @@ -15227,6 +15601,7 @@ "Document title", "Identifies the subtitle of the document.", "Document date", + "Date format for the document", "Document date modified", "Author or authors of the document", { @@ -17089,7 +17464,75 @@ "Manuscript configuration", "internal-schema-hack", "List execution engines you want to give priority when determining\nwhich engine should render a notebook. If two engines have support for a\nnotebook, the one listed earlier will be chosen. Quarto’s default order\nis ‘knitr’, ‘jupyter’, ‘markdown’, ‘julia’.", - "Date format for the document" + "Provide definitions and defaults for brand’s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", + "A link or path to the brand’s small-sized logo or icon.", + "A link or path to the brand’s medium-sized logo.", + "A link or path to the brand’s large- or full-sized logo.", + "Provide definitions and defaults for brand’s logo in various formats\nand sizes.", + "A dictionary of named logo resources.", + "A link or path to the brand’s small-sized logo or icon, or a link or\npath to both the light and dark versions.", + "A link or path to the brand’s medium-sized logo, or a link or path to\nboth the light and dark versions.", + "A link or path to the brand’s large- or full-sized logo, or a link or\npath to both the light and dark versions.", + "The brand’s custom color palette and theme.", + "The brand’s custom color palette. Any number of colors can be\ndefined, each color having a custom name.", + "The foreground color, used for text.", + "The background color, used for the page background.", + "The primary accent color, i.e. the main theme color. Typically used\nfor hyperlinks, active states, primary action buttons, etc.", + "The secondary accent color. Typically used for lighter text or\ndisabled states.", + "The tertiary accent color. Typically an even lighter color, used for\nhover states, accents, and wells.", + "The color used for positive or successful actions and\ninformation.", + "The color used for neutral or informational actions and\ninformation.", + "The color used for warning or cautionary actions and information.", + "The color used for errors, dangerous actions, or negative\ninformation.", + "A bright color, used as a high-contrast foreground color on dark\nelements or low-contrast background color on light elements.", + "A dark color, used as a high-contrast foreground color on light\nelements or high-contrast background color on light elements.", + "The color used for hyperlinks. If not defined, the\nprimary color is used.", + "A link or path to the brand’s light-colored logo or icon.", + "A link or path to the brand’s dark-colored logo or icon.", + "The brand’s custom color palette and theme.", + "The brand’s custom color palette. Any number of colors can be\ndefined, each color having a custom name.", + "The foreground color, used for text.", + "The background color, used for the page background.", + "The primary accent color, i.e. the main theme color. Typically used\nfor hyperlinks, active states, primary action buttons, etc.", + "The secondary accent color. Typically used for lighter text or\ndisabled states.", + "The tertiary accent color. Typically an even lighter color, used for\nhover states, accents, and wells.", + "The color used for positive or successful actions and\ninformation.", + "The color used for neutral or informational actions and\ninformation.", + "The color used for warning or cautionary actions and information.", + "The color used for errors, dangerous actions, or negative\ninformation.", + "A bright color, used as a high-contrast foreground color on dark\nelements or low-contrast background color on light elements.", + "A dark color, used as a high-contrast foreground color on light\nelements or high-contrast background color on light elements.", + "The color used for hyperlinks. If not defined, the\nprimary color is used.", + "A link or path to the brand’s light-colored logo or icon.", + "A link or path to the brand’s dark-colored logo or icon.", + "Typography definitions for the brand.", + "Font files and definitions for the brand.", + "The base font settings for the brand. These are used as the default\nfor all text.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Typography definitions for the brand.", + "Font files and definitions for the brand.", + "The base font settings for the brand. These are used as the default\nfor all text.", + "Settings for headings, or a string specifying the font family\nonly.", + "Settings for monospace text, or a string specifying the font family\nonly.", + "Settings for inline code, or a string specifying the font family\nonly.", + "Settings for code blocks, or a string specifying the font family\nonly.", + "Settings for links.", + "Typographic options for headings.", + "Typographic options for headings.", + "Typographic options for monospace elements.", + "Typographic options for monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for block monospace elements.", + "Typographic options for block monospace elements.", + "Typographic options for inline monospace elements.", + "Typographic options for inline monospace elements.", + "Names of customizeable typography elements" ], "schema/external-schemas.yml": [ { @@ -17318,12 +17761,12 @@ "mermaid": "%%" }, "handlers/mermaid/schema.yml": { - "_internalId": 196444, + "_internalId": 197022, "type": "object", "description": "be an object", "properties": { "mermaid-format": { - "_internalId": 196436, + "_internalId": 197014, "type": "enum", "enum": [ "png", @@ -17339,7 +17782,7 @@ "exhaustiveCompletions": true }, "theme": { - "_internalId": 196443, + "_internalId": 197021, "type": "anyOf", "anyOf": [ { diff --git a/src/resources/schema/definitions.yml b/src/resources/schema/definitions.yml index 7f758272466..2776f6d50fb 100644 --- a/src/resources/schema/definitions.yml +++ b/src/resources/schema/definitions.yml @@ -221,7 +221,7 @@ You can quickly find this by using the configuration tool at [https://giscus.app](https://giscus.app). If this is not provided, Quarto will attempt to discover it at render time. mapping: - schema: + schema: anyOf: - string - number @@ -229,7 +229,7 @@ - pathname - url - title - - og:title + - og:title description: short: The mapping between the page and the embedded discussion. long: | @@ -2539,7 +2539,32 @@ - string - ref: brand-logo-explicit-resource -- id: brand-logo +- id: brand-logo-single + description: > + Provide definitions and defaults for brand's logo in various formats and sizes. + object: + closed: true + properties: + images: + description: A dictionary of named logo resources. + schema: + object: + additionalProperties: + schema: { ref: brand-logo-resource } + small: + description: > + A link or path to the brand's small-sized logo or icon. + schema: string + medium: + description: > + A link or path to the brand's medium-sized logo. + schema: string + large: + description: > + A link or path to the brand's large- or full-sized logo. + schema: string + +- id: brand-logo-unified description: > Provide definitions and defaults for brand's logo in various formats and sizes. object: @@ -2577,7 +2602,7 @@ - id: brand-color-value schema: string -- id: brand-color +- id: brand-color-single description: > The brand's custom color palette and theme. object: @@ -2652,6 +2677,98 @@ schema: ref: brand-color-value +- id: brand-color-light-dark + anyOf: + - ref: brand-color-value + - object: + closed: true + properties: + light: + schema: + ref: brand-color-value + description: > + A link or path to the brand's light-colored logo or icon. + dark: + schema: + ref: brand-color-value + description: > + A link or path to the brand's dark-colored logo or icon. + +- id: brand-color-unified + description: > + The brand's custom color palette and theme. + object: + closed: true + properties: + palette: + description: > + The brand's custom color palette. Any number of colors can be defined, + each color having a custom name. + object: + additionalProperties: + schema: + ref: brand-color-value + foreground: + description: The foreground color, used for text. + schema: + ref: brand-color-light-dark + default: black + background: + description: The background color, used for the page background. + schema: + ref: brand-color-light-dark + default: white + primary: + description: > + The primary accent color, i.e. the main theme color. Typically used for + hyperlinks, active states, primary action buttons, etc. + schema: + ref: brand-color-light-dark + secondary: + description: > + The secondary accent color. Typically used for lighter text or disabled states. + schema: + ref: brand-color-light-dark + tertiary: + description: > + The tertiary accent color. Typically an even lighter color, used for hover states, + accents, and wells. + schema: + ref: brand-color-light-dark + success: + description: The color used for positive or successful actions and information. + schema: + ref: brand-color-light-dark + info: + description: The color used for neutral or informational actions and information. + schema: + ref: brand-color-light-dark + warning: + description: The color used for warning or cautionary actions and information. + schema: + ref: brand-color-light-dark + danger: + description: The color used for errors, dangerous actions, or negative information. + schema: + ref: brand-color-light-dark + light: + description: > + A bright color, used as a high-contrast foreground color on dark elements + or low-contrast background color on light elements. + schema: + ref: brand-color-light-dark + dark: + description: > + A dark color, used as a high-contrast foreground color on light elements + or high-contrast background color on light elements. + schema: + ref: brand-color-light-dark + link: + description: > + The color used for hyperlinks. If not defined, the `primary` color is used. + schema: + ref: brand-color-light-dark + - id: brand-maybe-named-color description: > A color, which may be a named brand color. @@ -2659,6 +2776,23 @@ - ref: brand-named-theme-color - schema: string +- id: brand-maybe-named-color-light-dark + anyOf: + - ref: brand-maybe-named-color + - object: + closed: true + properties: + light: + schema: + ref: brand-maybe-named-color + description: > + A link or path to the brand's light-colored logo or icon. + dark: + schema: + ref: brand-maybe-named-color + description: > + A link or path to the brand's dark-colored logo or icon. + - id: brand-named-theme-color description: > A named brand color, taken either from `color.theme` or `color.palette` (in that order). @@ -2678,7 +2812,37 @@ link, ] -- id: brand-typography +- id: brand-typography-single + description: Typography definitions for the brand. + object: + closed: true + properties: + fonts: + description: Font files and definitions for the brand. + arrayOf: + ref: brand-font + base: + description: > + The base font settings for the brand. These are used as the default for + all text. + ref: brand-typography-options-base + headings: + description: Settings for headings, or a string specifying the font family only. + ref: brand-typography-options-headings-single + monospace: + description: Settings for monospace text, or a string specifying the font family only. + ref: brand-typography-options-monospace-single + monospace-inline: + description: Settings for inline code, or a string specifying the font family only. + ref: brand-typography-options-monospace-inline-single + monospace-block: + description: Settings for code blocks, or a string specifying the font family only. + ref: brand-typography-options-monospace-block-single + link: + description: Settings for links. + ref: brand-typography-options-link-single + +- id: brand-typography-unified description: Typography definitions for the brand. object: closed: true @@ -2694,19 +2858,19 @@ ref: brand-typography-options-base headings: description: Settings for headings, or a string specifying the font family only. - ref: brand-typography-options-headings + ref: brand-typography-options-headings-unified monospace: description: Settings for monospace text, or a string specifying the font family only. - ref: brand-typography-options-monospace + ref: brand-typography-options-monospace-unified monospace-inline: description: Settings for inline code, or a string specifying the font family only. - ref: brand-typography-options-monospace-inline + ref: brand-typography-options-monospace-inline-unified monospace-block: description: Settings for code blocks, or a string specifying the font family only. - ref: brand-typography-options-monospace-block + ref: brand-typography-options-monospace-block-unified link: description: Settings for links. - ref: brand-typography-options-link + ref: brand-typography-options-link-unified - id: brand-typography-options-base description: Base typographic options. @@ -2722,7 +2886,7 @@ line-height: ref: line-height-number-string -- id: brand-typography-options-headings +- id: brand-typography-options-headings-single description: Typographic options for headings. anyOf: - string @@ -2739,7 +2903,24 @@ line-height: ref: line-height-number-string -- id: brand-typography-options-monospace +- id: brand-typography-options-headings-unified + description: Typographic options for headings. + anyOf: + - string + - object: + closed: true + properties: + family: string + weight: + ref: brand-font-weight + style: + ref: brand-font-style + color: + ref: brand-maybe-named-color-light-dark + line-height: + ref: line-height-number-string + +- id: brand-typography-options-monospace-single description: Typographic options for monospace elements. anyOf: - string @@ -2755,7 +2936,23 @@ background-color: ref: brand-maybe-named-color -- id: brand-typography-options-monospace-inline +- id: brand-typography-options-monospace-unified + description: Typographic options for monospace elements. + anyOf: + - string + - object: + closed: true + properties: + family: string + size: string + weight: + ref: brand-font-weight + color: + ref: brand-maybe-named-color-light-dark + background-color: + ref: brand-maybe-named-color-light-dark + +- id: brand-typography-options-monospace-inline-single description: Typographic options for inline monospace elements. anyOf: - string @@ -2771,11 +2968,27 @@ background-color: ref: brand-maybe-named-color +- id: brand-typography-options-monospace-inline-unified + description: Typographic options for inline monospace elements. + anyOf: + - string + - object: + closed: true + properties: + family: string + size: string + weight: + ref: brand-font-weight + color: + ref: brand-maybe-named-color-light-dark + background-color: + ref: brand-maybe-named-color-light-dark + - id: line-height-number-string description: Line height anyOf: [number, string] -- id: brand-typography-options-monospace-block +- id: brand-typography-options-monospace-block-single description: Typographic options for block monospace elements. anyOf: - string @@ -2793,7 +3006,25 @@ line-height: ref: line-height-number-string -- id: brand-typography-options-link +- id: brand-typography-options-monospace-block-unified + description: Typographic options for block monospace elements. + anyOf: + - string + - object: + closed: true + properties: + family: string + size: string + weight: + ref: brand-font-weight + color: + ref: brand-maybe-named-color-light-dark + background-color: + ref: brand-maybe-named-color-light-dark + line-height: + ref: line-height-number-string + +- id: brand-typography-options-link-single description: Typographic options for inline monospace elements. anyOf: - string @@ -2808,9 +3039,24 @@ ref: brand-maybe-named-color decoration: string -- id: brand-named-font - description: Names of customizeable fonts - enum: [base, headings, monospace] +- id: brand-typography-options-link-unified + description: Typographic options for inline monospace elements. + anyOf: + - string + - object: + closed: true + properties: + weight: + ref: brand-font-weight + color: + ref: brand-maybe-named-color-light-dark + background-color: + ref: brand-maybe-named-color-light-dark + decoration: string + +- id: brand-named-typography-elements + description: Names of customizeable typography elements + enum: [base, headings, monospace, monospace-inline, monospace-block, link] - id: brand-font description: Font files and definitions for the brand. @@ -2969,18 +3215,33 @@ for ensuring that the font is installed on their system. schema: string -- id: brand +- id: brand-single object: closed: true properties: meta: ref: brand-meta logo: - ref: brand-logo + ref: brand-logo-unified # temporary color: - ref: brand-color + ref: brand-color-single typography: - ref: brand-typography + ref: brand-typography-single + defaults: + ref: brand-defaults + +- id: brand-unified + object: + closed: true + properties: + meta: + ref: brand-meta + logo: + ref: brand-logo-unified + color: + ref: brand-color-unified + typography: + ref: brand-typography-unified defaults: ref: brand-defaults @@ -2994,19 +3255,19 @@ light: anyOf: - string - - ref: brand + - ref: brand-single description: > The path to a light brand file or an inline light brand definition. dark: anyOf: - string - - ref: brand + - ref: brand-single description: > The path to a dark brand file or an inline dark brand definition. - - ref: brand + - ref: brand-unified description: | Branding information to use for this document. If a string, the path to a brand file. - If false, don't use branding on this document. If an object, an inline brand + If false, don't use branding on this document. If an object, an inline (unified) brand definition, or an object with light and dark brand paths or definitions. - id: brand-defaults @@ -3029,5 +3290,4 @@ - string - boolean - number - # - id: quarto-extension diff --git a/src/resources/schema/json-schemas.json b/src/resources/schema/json-schemas.json index 02fc87b9a6f..9ed8ecd4069 100644 --- a/src/resources/schema/json-schemas.json +++ b/src/resources/schema/json-schemas.json @@ -3177,7 +3177,27 @@ } ] }, - "BrandLogo": { + "BrandLogoSingle": { + "object": { + "properties": { + "images": { + "object": { + "properties": {} + } + }, + "small": { + "type": "string" + }, + "medium": { + "type": "string" + }, + "large": { + "type": "string" + } + } + } + }, + "BrandLogoUnified": { "object": { "properties": { "images": { @@ -3207,7 +3227,7 @@ "BrandColorValue": { "type": "string" }, - "BrandColor": { + "BrandColorSingle": { "object": { "properties": { "palette": { @@ -3254,6 +3274,72 @@ } } }, + "BrandColorLightDark": { + "anyOf": [ + { + "$ref": "#/$defs/BrandColorValue" + }, + { + "object": { + "properties": { + "light": { + "$ref": "#/$defs/BrandColorValue" + }, + "dark": { + "$ref": "#/$defs/BrandColorValue" + } + } + } + } + ] + }, + "BrandColorUnified": { + "object": { + "properties": { + "palette": { + "object": { + "properties": {} + } + }, + "foreground": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "background": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "primary": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "secondary": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "tertiary": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "success": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "info": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "warning": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "danger": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "light": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "dark": { + "$ref": "#/$defs/BrandColorLightDark" + }, + "link": { + "$ref": "#/$defs/BrandColorLightDark" + } + } + } + }, "BrandMaybeNamedColor": { "anyOf": [ { @@ -3264,6 +3350,25 @@ } ] }, + "BrandMaybeNamedColorLightDark": { + "anyOf": [ + { + "$ref": "#/$defs/BrandMaybeNamedColor" + }, + { + "object": { + "properties": { + "light": { + "$ref": "#/$defs/BrandMaybeNamedColor" + }, + "dark": { + "$ref": "#/$defs/BrandMaybeNamedColor" + } + } + } + } + ] + }, "BrandNamedThemeColor": { "enum": [ "foreground", @@ -3280,7 +3385,7 @@ "link" ] }, - "BrandTypography": { + "BrandTypographySingle": { "object": { "properties": { "fonts": { @@ -3293,19 +3398,49 @@ "$ref": "#/$defs/BrandTypographyOptionsBase" }, "headings": { - "$ref": "#/$defs/BrandTypographyOptionsHeadings" + "$ref": "#/$defs/BrandTypographyOptionsHeadingsSingle" }, "monospace": { - "$ref": "#/$defs/BrandTypographyOptionsMonospace" + "$ref": "#/$defs/BrandTypographyOptionsMonospaceSingle" }, "monospace-inline": { - "$ref": "#/$defs/BrandTypographyOptionsMonospaceInline" + "$ref": "#/$defs/BrandTypographyOptionsMonospaceInlineSingle" }, "monospace-block": { - "$ref": "#/$defs/BrandTypographyOptionsMonospaceBlock" + "$ref": "#/$defs/BrandTypographyOptionsMonospaceBlockSingle" }, "link": { - "$ref": "#/$defs/BrandTypographyOptionsLink" + "$ref": "#/$defs/BrandTypographyOptionsLinkSingle" + } + } + } + }, + "BrandTypographyUnified": { + "object": { + "properties": { + "fonts": { + "type": "array", + "items": { + "$ref": "#/$defs/BrandFont" + } + }, + "base": { + "$ref": "#/$defs/BrandTypographyOptionsBase" + }, + "headings": { + "$ref": "#/$defs/BrandTypographyOptionsHeadingsUnified" + }, + "monospace": { + "$ref": "#/$defs/BrandTypographyOptionsMonospaceUnified" + }, + "monospace-inline": { + "$ref": "#/$defs/BrandTypographyOptionsMonospaceInlineUnified" + }, + "monospace-block": { + "$ref": "#/$defs/BrandTypographyOptionsMonospaceBlockUnified" + }, + "link": { + "$ref": "#/$defs/BrandTypographyOptionsLinkUnified" } } } @@ -3335,7 +3470,7 @@ } ] }, - "BrandTypographyOptionsHeadings": { + "BrandTypographyOptionsHeadingsSingle": { "anyOf": [ { "type": "string" @@ -3363,7 +3498,35 @@ } ] }, - "BrandTypographyOptionsMonospace": { + "BrandTypographyOptionsHeadingsUnified": { + "anyOf": [ + { + "type": "string" + }, + { + "object": { + "properties": { + "family": { + "type": "string" + }, + "weight": { + "$ref": "#/$defs/BrandFontWeight" + }, + "style": { + "$ref": "#/$defs/BrandFontStyle" + }, + "color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + }, + "line-height": { + "$ref": "#/$defs/LineHeightNumberString" + } + } + } + } + ] + }, + "BrandTypographyOptionsMonospaceSingle": { "anyOf": [ { "type": "string" @@ -3391,7 +3554,35 @@ } ] }, - "BrandTypographyOptionsMonospaceInline": { + "BrandTypographyOptionsMonospaceUnified": { + "anyOf": [ + { + "type": "string" + }, + { + "object": { + "properties": { + "family": { + "type": "string" + }, + "size": { + "type": "string" + }, + "weight": { + "$ref": "#/$defs/BrandFontWeight" + }, + "color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + }, + "background-color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + } + } + } + } + ] + }, + "BrandTypographyOptionsMonospaceInlineSingle": { "anyOf": [ { "type": "string" @@ -3419,6 +3610,34 @@ } ] }, + "BrandTypographyOptionsMonospaceInlineUnified": { + "anyOf": [ + { + "type": "string" + }, + { + "object": { + "properties": { + "family": { + "type": "string" + }, + "size": { + "type": "string" + }, + "weight": { + "$ref": "#/$defs/BrandFontWeight" + }, + "color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + }, + "background-color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + } + } + } + } + ] + }, "LineHeightNumberString": { "anyOf": [ { @@ -3429,7 +3648,7 @@ } ] }, - "BrandTypographyOptionsMonospaceBlock": { + "BrandTypographyOptionsMonospaceBlockSingle": { "anyOf": [ { "type": "string" @@ -3460,7 +3679,38 @@ } ] }, - "BrandTypographyOptionsLink": { + "BrandTypographyOptionsMonospaceBlockUnified": { + "anyOf": [ + { + "type": "string" + }, + { + "object": { + "properties": { + "family": { + "type": "string" + }, + "size": { + "type": "string" + }, + "weight": { + "$ref": "#/$defs/BrandFontWeight" + }, + "color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + }, + "background-color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + }, + "line-height": { + "$ref": "#/$defs/LineHeightNumberString" + } + } + } + } + ] + }, + "BrandTypographyOptionsLinkSingle": { "anyOf": [ { "type": "string" @@ -3485,11 +3735,39 @@ } ] }, - "BrandNamedFont": { + "BrandTypographyOptionsLinkUnified": { + "anyOf": [ + { + "type": "string" + }, + { + "object": { + "properties": { + "weight": { + "$ref": "#/$defs/BrandFontWeight" + }, + "color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + }, + "background-color": { + "$ref": "#/$defs/BrandMaybeNamedColorLightDark" + }, + "decoration": { + "type": "string" + } + } + } + } + ] + }, + "BrandNamedTypographyElements": { "enum": [ "base", "headings", - "monospace" + "monospace", + "monospace-inline", + "monospace-block", + "link" ] }, "BrandFont": { @@ -3663,20 +3941,41 @@ "BrandFontFamily": { "type": "string" }, - "Brand": { + "BrandSingle": { + "object": { + "properties": { + "meta": { + "$ref": "#/$defs/BrandMeta" + }, + "logo": { + "$ref": "#/$defs/BrandLogoUnified" + }, + "color": { + "$ref": "#/$defs/BrandColorSingle" + }, + "typography": { + "$ref": "#/$defs/BrandTypographySingle" + }, + "defaults": { + "$ref": "#/$defs/BrandDefaults" + } + } + } + }, + "BrandUnified": { "object": { "properties": { "meta": { "$ref": "#/$defs/BrandMeta" }, "logo": { - "$ref": "#/$defs/BrandLogo" + "$ref": "#/$defs/BrandLogoUnified" }, "color": { - "$ref": "#/$defs/BrandColor" + "$ref": "#/$defs/BrandColorUnified" }, "typography": { - "$ref": "#/$defs/BrandTypography" + "$ref": "#/$defs/BrandTypographyUnified" }, "defaults": { "$ref": "#/$defs/BrandDefaults" @@ -3701,7 +4000,7 @@ "type": "string" }, { - "$ref": "#/$defs/Brand" + "$ref": "#/$defs/BrandSingle" } ] }, @@ -3711,7 +4010,7 @@ "type": "string" }, { - "$ref": "#/$defs/Brand" + "$ref": "#/$defs/BrandSingle" } ] } @@ -3719,7 +4018,7 @@ } }, { - "$ref": "#/$defs/Brand" + "$ref": "#/$defs/BrandUnified" } ] }, diff --git a/src/resources/types/schema-types.ts b/src/resources/types/schema-types.ts index e4af358ecdc..893101b45fe 100644 --- a/src/resources/types/schema-types.ts +++ b/src/resources/types/schema-types.ts @@ -1242,7 +1242,14 @@ export type BrandLogoExplicitResource = { alt?: string; path: string }; export type BrandLogoResource = string | BrandLogoExplicitResource; -export type BrandLogo = { +export type BrandLogoSingle = { + images?: { [key: string]: BrandLogoResource }; + large?: string; + medium?: string; + small?: string; +}; /* Provide definitions and defaults for brand's logo in various formats and sizes. */ + +export type BrandLogoUnified = { images?: { [key: string]: BrandLogoResource }; large?: BrandStringLightDark; medium?: BrandStringLightDark; @@ -1256,7 +1263,7 @@ export type BrandNamedLogo = export type BrandColorValue = string; -export type BrandColor = { +export type BrandColorSingle = { background?: BrandColorValue; danger?: BrandColorValue; dark?: BrandColorValue; @@ -1274,10 +1281,38 @@ export type BrandColor = { warning?: BrandColorValue; }; /* The brand's custom color palette and theme. */ +export type BrandColorLightDark = BrandColorValue | { + dark?: BrandColorValue; + light?: BrandColorValue; +}; + +export type BrandColorUnified = { + background?: BrandColorLightDark; + danger?: BrandColorLightDark; + dark?: BrandColorLightDark; + foreground?: BrandColorLightDark; + info?: BrandColorLightDark; + light?: BrandColorLightDark; + link?: BrandColorLightDark; + palette?: { + [key: string]: BrandColorValue; + } /* The brand's custom color palette. Any number of colors can be defined, each color having a custom name. */; + primary?: BrandColorLightDark; + secondary?: BrandColorLightDark; + success?: BrandColorLightDark; + tertiary?: BrandColorLightDark; + warning?: BrandColorLightDark; +}; /* The brand's custom color palette and theme. */ + export type BrandMaybeNamedColor = | BrandNamedThemeColor | string; /* A color, which may be a named brand color. */ +export type BrandMaybeNamedColorLightDark = BrandMaybeNamedColor | { + dark?: BrandMaybeNamedColor; + light?: BrandMaybeNamedColor; +}; + export type BrandNamedThemeColor = | "foreground" | "background" @@ -1292,14 +1327,24 @@ export type BrandNamedThemeColor = | "dark" | "link"; /* A named brand color, taken either from `color.theme` or `color.palette` (in that order). */ -export type BrandTypography = { - "monospace-inline"?: BrandTypographyOptionsMonospaceInline; - "monospace-block"?: BrandTypographyOptionsMonospaceBlock; +export type BrandTypographySingle = { + "monospace-inline"?: BrandTypographyOptionsMonospaceInlineSingle; + "monospace-block"?: BrandTypographyOptionsMonospaceBlockSingle; + base?: BrandTypographyOptionsBase; + fonts?: (BrandFont)[] /* Font files and definitions for the brand. */; + headings?: BrandTypographyOptionsHeadingsSingle; + link?: BrandTypographyOptionsLinkSingle; + monospace?: BrandTypographyOptionsMonospaceSingle; +}; /* Typography definitions for the brand. */ + +export type BrandTypographyUnified = { + "monospace-inline"?: BrandTypographyOptionsMonospaceInlineUnified; + "monospace-block"?: BrandTypographyOptionsMonospaceBlockUnified; base?: BrandTypographyOptionsBase; fonts?: (BrandFont)[] /* Font files and definitions for the brand. */; - headings?: BrandTypographyOptionsHeadings; - link?: BrandTypographyOptionsLink; - monospace?: BrandTypographyOptionsMonospace; + headings?: BrandTypographyOptionsHeadingsUnified; + link?: BrandTypographyOptionsLinkUnified; + monospace?: BrandTypographyOptionsMonospaceUnified; }; /* Typography definitions for the brand. */ export type BrandTypographyOptionsBase = string | { @@ -1309,7 +1354,7 @@ export type BrandTypographyOptionsBase = string | { weight?: BrandFontWeight; }; /* Base typographic options. */ -export type BrandTypographyOptionsHeadings = string | { +export type BrandTypographyOptionsHeadingsSingle = string | { "line-height"?: LineHeightNumberString; color?: BrandMaybeNamedColor; family?: string; @@ -1317,7 +1362,15 @@ export type BrandTypographyOptionsHeadings = string | { weight?: BrandFontWeight; }; /* Typographic options for headings. */ -export type BrandTypographyOptionsMonospace = string | { +export type BrandTypographyOptionsHeadingsUnified = string | { + "line-height"?: LineHeightNumberString; + color?: BrandMaybeNamedColorLightDark; + family?: string; + style?: BrandFontStyle; + weight?: BrandFontWeight; +}; /* Typographic options for headings. */ + +export type BrandTypographyOptionsMonospaceSingle = string | { "background-color"?: BrandMaybeNamedColor; color?: BrandMaybeNamedColor; family?: string; @@ -1325,7 +1378,15 @@ export type BrandTypographyOptionsMonospace = string | { weight?: BrandFontWeight; }; /* Typographic options for monospace elements. */ -export type BrandTypographyOptionsMonospaceInline = string | { +export type BrandTypographyOptionsMonospaceUnified = string | { + "background-color"?: BrandMaybeNamedColorLightDark; + color?: BrandMaybeNamedColorLightDark; + family?: string; + size?: string; + weight?: BrandFontWeight; +}; /* Typographic options for monospace elements. */ + +export type BrandTypographyOptionsMonospaceInlineSingle = string | { "background-color"?: BrandMaybeNamedColor; color?: BrandMaybeNamedColor; family?: string; @@ -1333,9 +1394,17 @@ export type BrandTypographyOptionsMonospaceInline = string | { weight?: BrandFontWeight; }; /* Typographic options for inline monospace elements. */ +export type BrandTypographyOptionsMonospaceInlineUnified = string | { + "background-color"?: BrandMaybeNamedColorLightDark; + color?: BrandMaybeNamedColorLightDark; + family?: string; + size?: string; + weight?: BrandFontWeight; +}; /* Typographic options for inline monospace elements. */ + export type LineHeightNumberString = number | string; /* Line height */ -export type BrandTypographyOptionsMonospaceBlock = string | { +export type BrandTypographyOptionsMonospaceBlockSingle = string | { "background-color"?: BrandMaybeNamedColor; "line-height"?: LineHeightNumberString; color?: BrandMaybeNamedColor; @@ -1344,17 +1413,36 @@ export type BrandTypographyOptionsMonospaceBlock = string | { weight?: BrandFontWeight; }; /* Typographic options for block monospace elements. */ -export type BrandTypographyOptionsLink = string | { +export type BrandTypographyOptionsMonospaceBlockUnified = string | { + "background-color"?: BrandMaybeNamedColorLightDark; + "line-height"?: LineHeightNumberString; + color?: BrandMaybeNamedColorLightDark; + family?: string; + size?: string; + weight?: BrandFontWeight; +}; /* Typographic options for block monospace elements. */ + +export type BrandTypographyOptionsLinkSingle = string | { "background-color"?: BrandMaybeNamedColor; color?: BrandMaybeNamedColor; decoration?: string; weight?: BrandFontWeight; }; /* Typographic options for inline monospace elements. */ -export type BrandNamedFont = +export type BrandTypographyOptionsLinkUnified = string | { + "background-color"?: BrandMaybeNamedColorLightDark; + color?: BrandMaybeNamedColorLightDark; + decoration?: string; + weight?: BrandFontWeight; +}; /* Typographic options for inline monospace elements. */ + +export type BrandNamedTypographyElements = | "base" | "headings" - | "monospace"; /* Names of customizeable fonts */ + | "monospace" + | "monospace-inline" + | "monospace-block" + | "link"; /* Names of customizeable typography elements */ export type BrandFont = | BrandFontGoogle @@ -1428,12 +1516,20 @@ export type BrandFontFile = { export type BrandFontFamily = string; -export type Brand = { - color?: BrandColor; +export type BrandSingle = { + color?: BrandColorSingle; + defaults?: BrandDefaults; + logo?: BrandLogoUnified; + meta?: BrandMeta; + typography?: BrandTypographySingle; +}; + +export type BrandUnified = { + color?: BrandColorUnified; defaults?: BrandDefaults; - logo?: BrandLogo; + logo?: BrandLogoUnified; meta?: BrandMeta; - typography?: BrandTypography; + typography?: BrandTypographyUnified; }; export type BrandPathBoolLightDark = @@ -1442,13 +1538,13 @@ export type BrandPathBoolLightDark = | { dark?: | string - | Brand /* The path to a dark brand file or an inline dark brand definition. */; + | BrandSingle /* The path to a dark brand file or an inline dark brand definition. */; light?: | string - | Brand; /* The path to a light brand file or an inline light brand definition. */ + | BrandSingle; /* The path to a light brand file or an inline light brand definition. */ } - | Brand; /* Branding information to use for this document. If a string, the path to a brand file. -If false, don't use branding on this document. If an object, an inline brand + | BrandUnified; /* Branding information to use for this document. If a string, the path to a brand file. +If false, don't use branding on this document. If an object, an inline (unified) brand definition, or an object with light and dark brand paths or definitions. */ export type BrandDefaults = { diff --git a/src/resources/types/zod/schema-types.ts b/src/resources/types/zod/schema-types.ts index 42e8001f291..d267260b955 100644 --- a/src/resources/types/zod/schema-types.ts +++ b/src/resources/types/zod/schema-types.ts @@ -1323,7 +1323,16 @@ export const ZodBrandLogoResource = z.union([ z.lazy(() => ZodBrandLogoExplicitResource), ]); -export const ZodBrandLogo = z.object({ +export const ZodBrandLogoSingle = z.object({ + images: z.record(z.lazy(() => ZodBrandLogoResource)).and( + z.object({}).passthrough().partial(), + ), + small: z.string(), + medium: z.string(), + large: z.string(), +}).strict().partial(); + +export const ZodBrandLogoUnified = z.object({ images: z.record(z.lazy(() => ZodBrandLogoResource)).and( z.object({}).passthrough().partial(), ), @@ -1336,7 +1345,7 @@ export const ZodBrandNamedLogo = z.enum(["small", "medium", "large"] as const); export const ZodBrandColorValue = z.string(); -export const ZodBrandColor = z.object({ +export const ZodBrandColorSingle = z.object({ palette: z.record(z.lazy(() => ZodBrandColorValue)).and( z.object({}).passthrough().partial(), ), @@ -1354,11 +1363,45 @@ export const ZodBrandColor = z.object({ link: z.lazy(() => ZodBrandColorValue), }).strict().partial(); +export const ZodBrandColorLightDark = z.union([ + z.lazy(() => ZodBrandColorValue), + z.object({ + light: z.lazy(() => ZodBrandColorValue), + dark: z.lazy(() => ZodBrandColorValue), + }).strict().partial(), +]); + +export const ZodBrandColorUnified = z.object({ + palette: z.record(z.lazy(() => ZodBrandColorValue)).and( + z.object({}).passthrough().partial(), + ), + foreground: z.lazy(() => ZodBrandColorLightDark), + background: z.lazy(() => ZodBrandColorLightDark), + primary: z.lazy(() => ZodBrandColorLightDark), + secondary: z.lazy(() => ZodBrandColorLightDark), + tertiary: z.lazy(() => ZodBrandColorLightDark), + success: z.lazy(() => ZodBrandColorLightDark), + info: z.lazy(() => ZodBrandColorLightDark), + warning: z.lazy(() => ZodBrandColorLightDark), + danger: z.lazy(() => ZodBrandColorLightDark), + light: z.lazy(() => ZodBrandColorLightDark), + dark: z.lazy(() => ZodBrandColorLightDark), + link: z.lazy(() => ZodBrandColorLightDark), +}).strict().partial(); + export const ZodBrandMaybeNamedColor = z.union([ z.lazy(() => ZodBrandNamedThemeColor), z.string(), ]); +export const ZodBrandMaybeNamedColorLightDark = z.union([ + z.lazy(() => ZodBrandMaybeNamedColor), + z.object({ + light: z.lazy(() => ZodBrandMaybeNamedColor), + dark: z.lazy(() => ZodBrandMaybeNamedColor), + }).strict().partial(), +]); + export const ZodBrandNamedThemeColor = z.enum( [ "foreground", @@ -1376,14 +1419,32 @@ export const ZodBrandNamedThemeColor = z.enum( ] as const, ); -export const ZodBrandTypography = z.object({ +export const ZodBrandTypographySingle = z.object({ fonts: z.array(z.lazy(() => ZodBrandFont)), base: z.lazy(() => ZodBrandTypographyOptionsBase), - headings: z.lazy(() => ZodBrandTypographyOptionsHeadings), - monospace: z.lazy(() => ZodBrandTypographyOptionsMonospace), - "monospace-inline": z.lazy(() => ZodBrandTypographyOptionsMonospaceInline), - "monospace-block": z.lazy(() => ZodBrandTypographyOptionsMonospaceBlock), - link: z.lazy(() => ZodBrandTypographyOptionsLink), + headings: z.lazy(() => ZodBrandTypographyOptionsHeadingsSingle), + monospace: z.lazy(() => ZodBrandTypographyOptionsMonospaceSingle), + "monospace-inline": z.lazy(() => + ZodBrandTypographyOptionsMonospaceInlineSingle + ), + "monospace-block": z.lazy(() => + ZodBrandTypographyOptionsMonospaceBlockSingle + ), + link: z.lazy(() => ZodBrandTypographyOptionsLinkSingle), +}).strict().partial(); + +export const ZodBrandTypographyUnified = z.object({ + fonts: z.array(z.lazy(() => ZodBrandFont)), + base: z.lazy(() => ZodBrandTypographyOptionsBase), + headings: z.lazy(() => ZodBrandTypographyOptionsHeadingsUnified), + monospace: z.lazy(() => ZodBrandTypographyOptionsMonospaceUnified), + "monospace-inline": z.lazy(() => + ZodBrandTypographyOptionsMonospaceInlineUnified + ), + "monospace-block": z.lazy(() => + ZodBrandTypographyOptionsMonospaceBlockUnified + ), + link: z.lazy(() => ZodBrandTypographyOptionsLinkUnified), }).strict().partial(); export const ZodBrandTypographyOptionsBase = z.union([ @@ -1396,7 +1457,7 @@ export const ZodBrandTypographyOptionsBase = z.union([ }).strict().partial(), ]); -export const ZodBrandTypographyOptionsHeadings = z.union([ +export const ZodBrandTypographyOptionsHeadingsSingle = z.union([ z.string(), z.object({ family: z.string(), @@ -1407,7 +1468,18 @@ export const ZodBrandTypographyOptionsHeadings = z.union([ }).strict().partial(), ]); -export const ZodBrandTypographyOptionsMonospace = z.union([ +export const ZodBrandTypographyOptionsHeadingsUnified = z.union([ + z.string(), + z.object({ + family: z.string(), + weight: z.lazy(() => ZodBrandFontWeight), + style: z.lazy(() => ZodBrandFontStyle), + color: z.lazy(() => ZodBrandMaybeNamedColorLightDark), + "line-height": z.lazy(() => ZodLineHeightNumberString), + }).strict().partial(), +]); + +export const ZodBrandTypographyOptionsMonospaceSingle = z.union([ z.string(), z.object({ family: z.string(), @@ -1418,7 +1490,18 @@ export const ZodBrandTypographyOptionsMonospace = z.union([ }).strict().partial(), ]); -export const ZodBrandTypographyOptionsMonospaceInline = z.union([ +export const ZodBrandTypographyOptionsMonospaceUnified = z.union([ + z.string(), + z.object({ + family: z.string(), + size: z.string(), + weight: z.lazy(() => ZodBrandFontWeight), + color: z.lazy(() => ZodBrandMaybeNamedColorLightDark), + "background-color": z.lazy(() => ZodBrandMaybeNamedColorLightDark), + }).strict().partial(), +]); + +export const ZodBrandTypographyOptionsMonospaceInlineSingle = z.union([ z.string(), z.object({ family: z.string(), @@ -1429,9 +1512,20 @@ export const ZodBrandTypographyOptionsMonospaceInline = z.union([ }).strict().partial(), ]); +export const ZodBrandTypographyOptionsMonospaceInlineUnified = z.union([ + z.string(), + z.object({ + family: z.string(), + size: z.string(), + weight: z.lazy(() => ZodBrandFontWeight), + color: z.lazy(() => ZodBrandMaybeNamedColorLightDark), + "background-color": z.lazy(() => ZodBrandMaybeNamedColorLightDark), + }).strict().partial(), +]); + export const ZodLineHeightNumberString = z.union([z.number(), z.string()]); -export const ZodBrandTypographyOptionsMonospaceBlock = z.union([ +export const ZodBrandTypographyOptionsMonospaceBlockSingle = z.union([ z.string(), z.object({ family: z.string(), @@ -1443,7 +1537,19 @@ export const ZodBrandTypographyOptionsMonospaceBlock = z.union([ }).strict().partial(), ]); -export const ZodBrandTypographyOptionsLink = z.union([ +export const ZodBrandTypographyOptionsMonospaceBlockUnified = z.union([ + z.string(), + z.object({ + family: z.string(), + size: z.string(), + weight: z.lazy(() => ZodBrandFontWeight), + color: z.lazy(() => ZodBrandMaybeNamedColorLightDark), + "background-color": z.lazy(() => ZodBrandMaybeNamedColorLightDark), + "line-height": z.lazy(() => ZodLineHeightNumberString), + }).strict().partial(), +]); + +export const ZodBrandTypographyOptionsLinkSingle = z.union([ z.string(), z.object({ weight: z.lazy(() => ZodBrandFontWeight), @@ -1453,8 +1559,25 @@ export const ZodBrandTypographyOptionsLink = z.union([ }).strict().partial(), ]); -export const ZodBrandNamedFont = z.enum( - ["base", "headings", "monospace"] as const, +export const ZodBrandTypographyOptionsLinkUnified = z.union([ + z.string(), + z.object({ + weight: z.lazy(() => ZodBrandFontWeight), + color: z.lazy(() => ZodBrandMaybeNamedColorLightDark), + "background-color": z.lazy(() => ZodBrandMaybeNamedColorLightDark), + decoration: z.string(), + }).strict().partial(), +]); + +export const ZodBrandNamedTypographyElements = z.enum( + [ + "base", + "headings", + "monospace", + "monospace-inline", + "monospace-block", + "link", + ] as const, ); export const ZodBrandFont = z.union([ @@ -1570,11 +1693,19 @@ export const ZodBrandFontFile = z.object({ export const ZodBrandFontFamily = z.string(); -export const ZodBrand = z.object({ +export const ZodBrandSingle = z.object({ + meta: z.lazy(() => ZodBrandMeta), + logo: z.lazy(() => ZodBrandLogoUnified), + color: z.lazy(() => ZodBrandColorSingle), + typography: z.lazy(() => ZodBrandTypographySingle), + defaults: z.lazy(() => ZodBrandDefaults), +}).strict().partial(); + +export const ZodBrandUnified = z.object({ meta: z.lazy(() => ZodBrandMeta), - logo: z.lazy(() => ZodBrandLogo), - color: z.lazy(() => ZodBrandColor), - typography: z.lazy(() => ZodBrandTypography), + logo: z.lazy(() => ZodBrandLogoUnified), + color: z.lazy(() => ZodBrandColorUnified), + typography: z.lazy(() => ZodBrandTypographyUnified), defaults: z.lazy(() => ZodBrandDefaults), }).strict().partial(); @@ -1582,10 +1713,10 @@ export const ZodBrandPathBoolLightDark = z.union([ z.string(), z.boolean(), z.object({ - light: z.union([z.string(), z.lazy(() => ZodBrand)]), - dark: z.union([z.string(), z.lazy(() => ZodBrand)]), + light: z.union([z.string(), z.lazy(() => ZodBrandSingle)]), + dark: z.union([z.string(), z.lazy(() => ZodBrandSingle)]), }).strict().partial(), - z.lazy(() => ZodBrand), + z.lazy(() => ZodBrandUnified), ]); export const ZodBrandDefaults = z.object({ @@ -1731,47 +1862,81 @@ export type BrandLogoExplicitResource = z.infer< export type BrandLogoResource = z.infer; -export type BrandLogo = z.infer; +export type BrandLogoSingle = z.infer; + +export type BrandLogoUnified = z.infer; export type BrandNamedLogo = z.infer; export type BrandColorValue = z.infer; -export type BrandColor = z.infer; +export type BrandColorSingle = z.infer; + +export type BrandColorLightDark = z.infer; + +export type BrandColorUnified = z.infer; export type BrandMaybeNamedColor = z.infer; +export type BrandMaybeNamedColorLightDark = z.infer< + typeof ZodBrandMaybeNamedColorLightDark +>; + export type BrandNamedThemeColor = z.infer; -export type BrandTypography = z.infer; +export type BrandTypographySingle = z.infer; + +export type BrandTypographyUnified = z.infer; export type BrandTypographyOptionsBase = z.infer< typeof ZodBrandTypographyOptionsBase >; -export type BrandTypographyOptionsHeadings = z.infer< - typeof ZodBrandTypographyOptionsHeadings +export type BrandTypographyOptionsHeadingsSingle = z.infer< + typeof ZodBrandTypographyOptionsHeadingsSingle >; -export type BrandTypographyOptionsMonospace = z.infer< - typeof ZodBrandTypographyOptionsMonospace +export type BrandTypographyOptionsHeadingsUnified = z.infer< + typeof ZodBrandTypographyOptionsHeadingsUnified >; -export type BrandTypographyOptionsMonospaceInline = z.infer< - typeof ZodBrandTypographyOptionsMonospaceInline +export type BrandTypographyOptionsMonospaceSingle = z.infer< + typeof ZodBrandTypographyOptionsMonospaceSingle +>; + +export type BrandTypographyOptionsMonospaceUnified = z.infer< + typeof ZodBrandTypographyOptionsMonospaceUnified +>; + +export type BrandTypographyOptionsMonospaceInlineSingle = z.infer< + typeof ZodBrandTypographyOptionsMonospaceInlineSingle +>; + +export type BrandTypographyOptionsMonospaceInlineUnified = z.infer< + typeof ZodBrandTypographyOptionsMonospaceInlineUnified >; export type LineHeightNumberString = z.infer; -export type BrandTypographyOptionsMonospaceBlock = z.infer< - typeof ZodBrandTypographyOptionsMonospaceBlock +export type BrandTypographyOptionsMonospaceBlockSingle = z.infer< + typeof ZodBrandTypographyOptionsMonospaceBlockSingle >; -export type BrandTypographyOptionsLink = z.infer< - typeof ZodBrandTypographyOptionsLink +export type BrandTypographyOptionsMonospaceBlockUnified = z.infer< + typeof ZodBrandTypographyOptionsMonospaceBlockUnified >; -export type BrandNamedFont = z.infer; +export type BrandTypographyOptionsLinkSingle = z.infer< + typeof ZodBrandTypographyOptionsLinkSingle +>; + +export type BrandTypographyOptionsLinkUnified = z.infer< + typeof ZodBrandTypographyOptionsLinkUnified +>; + +export type BrandNamedTypographyElements = z.infer< + typeof ZodBrandNamedTypographyElements +>; export type BrandFont = z.infer; @@ -1791,7 +1956,9 @@ export type BrandFontFile = z.infer; export type BrandFontFamily = z.infer; -export type Brand = z.infer; +export type BrandSingle = z.infer; + +export type BrandUnified = z.infer; export type BrandPathBoolLightDark = z.infer; @@ -1858,22 +2025,38 @@ export const Zod = { BrandStringLightDark: ZodBrandStringLightDark, BrandLogoExplicitResource: ZodBrandLogoExplicitResource, BrandLogoResource: ZodBrandLogoResource, - BrandLogo: ZodBrandLogo, + BrandLogoSingle: ZodBrandLogoSingle, + BrandLogoUnified: ZodBrandLogoUnified, BrandNamedLogo: ZodBrandNamedLogo, BrandColorValue: ZodBrandColorValue, - BrandColor: ZodBrandColor, + BrandColorSingle: ZodBrandColorSingle, + BrandColorLightDark: ZodBrandColorLightDark, + BrandColorUnified: ZodBrandColorUnified, BrandMaybeNamedColor: ZodBrandMaybeNamedColor, + BrandMaybeNamedColorLightDark: ZodBrandMaybeNamedColorLightDark, BrandNamedThemeColor: ZodBrandNamedThemeColor, - BrandTypography: ZodBrandTypography, + BrandTypographySingle: ZodBrandTypographySingle, + BrandTypographyUnified: ZodBrandTypographyUnified, BrandTypographyOptionsBase: ZodBrandTypographyOptionsBase, - BrandTypographyOptionsHeadings: ZodBrandTypographyOptionsHeadings, - BrandTypographyOptionsMonospace: ZodBrandTypographyOptionsMonospace, - BrandTypographyOptionsMonospaceInline: - ZodBrandTypographyOptionsMonospaceInline, + BrandTypographyOptionsHeadingsSingle: ZodBrandTypographyOptionsHeadingsSingle, + BrandTypographyOptionsHeadingsUnified: + ZodBrandTypographyOptionsHeadingsUnified, + BrandTypographyOptionsMonospaceSingle: + ZodBrandTypographyOptionsMonospaceSingle, + BrandTypographyOptionsMonospaceUnified: + ZodBrandTypographyOptionsMonospaceUnified, + BrandTypographyOptionsMonospaceInlineSingle: + ZodBrandTypographyOptionsMonospaceInlineSingle, + BrandTypographyOptionsMonospaceInlineUnified: + ZodBrandTypographyOptionsMonospaceInlineUnified, LineHeightNumberString: ZodLineHeightNumberString, - BrandTypographyOptionsMonospaceBlock: ZodBrandTypographyOptionsMonospaceBlock, - BrandTypographyOptionsLink: ZodBrandTypographyOptionsLink, - BrandNamedFont: ZodBrandNamedFont, + BrandTypographyOptionsMonospaceBlockSingle: + ZodBrandTypographyOptionsMonospaceBlockSingle, + BrandTypographyOptionsMonospaceBlockUnified: + ZodBrandTypographyOptionsMonospaceBlockUnified, + BrandTypographyOptionsLinkSingle: ZodBrandTypographyOptionsLinkSingle, + BrandTypographyOptionsLinkUnified: ZodBrandTypographyOptionsLinkUnified, + BrandNamedTypographyElements: ZodBrandNamedTypographyElements, BrandFont: ZodBrandFont, BrandFontWeight: ZodBrandFontWeight, BrandFontStyle: ZodBrandFontStyle, @@ -1883,7 +2066,8 @@ export const Zod = { BrandFontBunny: ZodBrandFontBunny, BrandFontFile: ZodBrandFontFile, BrandFontFamily: ZodBrandFontFamily, - Brand: ZodBrand, + BrandSingle: ZodBrandSingle, + BrandUnified: ZodBrandUnified, BrandPathBoolLightDark: ZodBrandPathBoolLightDark, BrandDefaults: ZodBrandDefaults, BrandDefaultsBootstrap: ZodBrandDefaultsBootstrap, diff --git a/tests/docs/playwright/html/unified-brand/brand-unified.yml b/tests/docs/playwright/html/unified-brand/brand-unified.yml new file mode 100644 index 00000000000..2e2e3cc3981 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/brand-unified.yml @@ -0,0 +1,17 @@ +color: + foreground: + light: "#222" + dark: "#eee" + background: + light: "#eee" + dark: "#222" +typography: + monospace: + background-color: + dark: "#321" + link: + background-color: + light: "#efe" + dark: "#421" + color: + dark: "#c3a" diff --git a/tests/docs/playwright/html/unified-brand/dark-brand-only-file.qmd b/tests/docs/playwright/html/unified-brand/dark-brand-only-file.qmd new file mode 100644 index 00000000000..ffba792c97d --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/dark-brand-only-file.qmd @@ -0,0 +1,21 @@ +--- +format: html +title: dark brand in file +brand: + dark: dark-brand.yml +--- + +Quarto creates a default light mode if only dark mode is specified. + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/dark-brand-only.qmd b/tests/docs/playwright/html/unified-brand/dark-brand-only.qmd new file mode 100644 index 00000000000..f31c53bf583 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/dark-brand-only.qmd @@ -0,0 +1,30 @@ +--- +format: html +title: dark brand inline +brand: + dark: + color: + foreground: '#eee' + background: '#222' + typography: + monospace: + background-color: '#321' + link: + background-color: '#421' + color: '#c3a' +--- + +Quarto creates a default light mode if only dark mode is specified. + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/dark-brand.yml b/tests/docs/playwright/html/unified-brand/dark-brand.yml new file mode 100644 index 00000000000..6cdd653d3aa --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/dark-brand.yml @@ -0,0 +1,9 @@ +color: + foreground: "#eee" + background: "#222" +typography: + monospace: + background-color: "#321" + link: + background-color: "#421" + color: "#c3a" diff --git a/tests/docs/playwright/html/unified-brand/dark-light-brand-file.qmd b/tests/docs/playwright/html/unified-brand/dark-light-brand-file.qmd new file mode 100644 index 00000000000..e3adb0f9f13 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/dark-light-brand-file.qmd @@ -0,0 +1,20 @@ +--- +format: html +title: light and dark brand files +brand: + dark: dark-brand.yml + light: light-brand.yml +--- + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/dark-light-brand.qmd b/tests/docs/playwright/html/unified-brand/dark-light-brand.qmd new file mode 100644 index 00000000000..0c42c81be47 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/dark-light-brand.qmd @@ -0,0 +1,35 @@ +--- +format: html +title: light and dark brands inline +brand: + dark: + color: + foreground: '#eee' + background: '#222' + typography: + monospace: + background-color: '#321' + link: + background-color: '#421' + color: '#c3a' + light: + color: + foreground: '#222' + background: '#eee' + typography: + link: + background-color: '#efe' +--- + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/light-brand-only-file.qmd b/tests/docs/playwright/html/unified-brand/light-brand-only-file.qmd new file mode 100644 index 00000000000..eade320a721 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/light-brand-only-file.qmd @@ -0,0 +1,19 @@ +--- +format: html +title: light brand in file +brand: light-brand.yml +--- + + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/light-brand-only.qmd b/tests/docs/playwright/html/unified-brand/light-brand-only.qmd new file mode 100644 index 00000000000..6c5ca09d5ad --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/light-brand-only.qmd @@ -0,0 +1,24 @@ +--- +format: html +title: light brand inline +brand: + color: + foreground: '#222' + background: '#eee' + typography: + link: + background-color: '#efe' +--- + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/light-brand.yml b/tests/docs/playwright/html/unified-brand/light-brand.yml new file mode 100644 index 00000000000..af75972e9b4 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/light-brand.yml @@ -0,0 +1,6 @@ +color: + foreground: "#222" + background: "#eee" +typography: + link: + background-color: "#efe" diff --git a/tests/docs/playwright/html/unified-brand/light-dark-brand-file.qmd b/tests/docs/playwright/html/unified-brand/light-dark-brand-file.qmd new file mode 100644 index 00000000000..318e6a3c04f --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/light-dark-brand-file.qmd @@ -0,0 +1,20 @@ +--- +format: html +title: light and dark brand files +brand: + light: light-brand.yml + dark: dark-brand.yml +--- + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/light-dark-brand.qmd b/tests/docs/playwright/html/unified-brand/light-dark-brand.qmd new file mode 100644 index 00000000000..ae11046e80f --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/light-dark-brand.qmd @@ -0,0 +1,35 @@ +--- +format: html +title: light and dark brands inline +brand: + light: + color: + foreground: '#222' + background: '#eee' + typography: + link: + background-color: '#efe' + dark: + color: + foreground: '#eee' + background: '#222' + typography: + monospace: + background-color: '#321' + link: + background-color: '#421' + color: '#c3a' +--- + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/unified-colors-file.qmd b/tests/docs/playwright/html/unified-brand/unified-colors-file.qmd new file mode 100644 index 00000000000..0438935f747 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/unified-colors-file.qmd @@ -0,0 +1,18 @@ +--- +format: html +title: unified light and dark brand file +brand: brand-unified.yml +--- + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/unified-colors.qmd b/tests/docs/playwright/html/unified-brand/unified-colors.qmd new file mode 100644 index 00000000000..1acd08d62a7 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/unified-colors.qmd @@ -0,0 +1,36 @@ +--- +format: html +title: unified light and dark brand inline +brand: + color: + foreground: + light: '#222' + dark: '#eee' + background: + light: '#eee' + dark: '#222' + typography: + monospace: + background-color: + dark: '#321' + link: + background-color: + light: '#efe' + dark: '#421' + color: + dark: '#c3a' +--- + + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/unified-light-only.qmd b/tests/docs/playwright/html/unified-brand/unified-light-only.qmd new file mode 100644 index 00000000000..9e55ec1e01b --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/unified-light-only.qmd @@ -0,0 +1,26 @@ +--- +format: html +title: light brand with only light customizations +brand: + color: + foreground: '#222' + background: + light: '#eee' + typography: + link: + background-color: + light: '#efe' +--- + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/docs/playwright/html/unified-brand/unified-typography.qmd b/tests/docs/playwright/html/unified-brand/unified-typography.qmd new file mode 100644 index 00000000000..812f4595984 --- /dev/null +++ b/tests/docs/playwright/html/unified-brand/unified-typography.qmd @@ -0,0 +1,29 @@ +--- +format: html +title: unified light and dark brand inline +brand: + typography: + monospace: + background-color: + dark: '#321' + link: + background-color: + light: '#efe' + dark: '#421' + color: + dark: '#c3a' +--- + + +```{r} +#| lst-label: lst-fibonacci +#| lst-cap: A naive algorithm for computing Fibonacci numbers. +fib <- function(x) { + if (x < 2) 1 else fib(x - 1) + fib(x - 2) +} +``` + +Here is [a link](https://example.com). + +{{< lipsum 2 >}} + diff --git a/tests/integration/playwright/tests/html-unified-brand.spec.ts b/tests/integration/playwright/tests/html-unified-brand.spec.ts new file mode 100644 index 00000000000..65e8ce4ac87 --- /dev/null +++ b/tests/integration/playwright/tests/html-unified-brand.spec.ts @@ -0,0 +1,101 @@ +import { test, expect } from '@playwright/test'; + +const expectedColors = { + 'quarto-light': { + 'background-color': 'rgb(238, 255, 238)', + 'color': 'rgb(13, 110, 253)' + }, + 'quarto-dark': { + 'background-color': 'rgb(68, 34, 17)', + 'color': 'rgb(204, 51, 170)' + } +} +const otherClass = s => s === 'quarto-light' ? 'quarto-dark' : s === 'quarto-dark' ? 'quarto-light': undefined; +async function check_link_colors(page, class_) { + const locatr = await page.locator('body').first(); + await expect(locatr).toHaveClass(`fullcontent ${class_}`); + const linkLocatr = await page.locator('a[href*="example.com"]'); + await expect(linkLocatr).toHaveCSS('background-color', expectedColors[class_]['background-color']); + await expect(linkLocatr).toHaveCSS('color', expectedColors[class_].color); + + await page.locator("a.quarto-color-scheme-toggle").click(); + const otherClass_ = otherClass(class_); + console.assert(otherClass_ && typeof otherClass_ === 'string'); + await expect(linkLocatr).toHaveCSS('background-color', expectedColors[otherClass_!]['background-color']); + await expect(linkLocatr).toHaveCSS('color', expectedColors[otherClass_!].color); +} + +test('Light brand in file', async ({ page }) => { + await page.goto('./html/unified-brand/light-brand-only-file.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(0); +}); + +test('Light brand inline', async ({ page }) => { + await page.goto('./html/unified-brand/light-brand-only.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(0); +}); + +test('Light brand with unified entries only light', async ({ page }) => { + await page.goto('./html/unified-brand/unified-light-only.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(0); +}); + +test('Dark brand in file', async ({ page }) => { + await page.goto('./html/unified-brand/dark-brand-only-file.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); +}); + +test('Dark brand inline', async ({ page }) => { + await page.goto('./html/unified-brand/dark-brand-only.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); +}); + +test('Light and dark brand files', async ({ page }) => { + await page.goto('./html/unified-brand/light-dark-brand-file.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); + + await check_link_colors(page, 'quarto-light'); +}); + +test('Light and dark brands inline', async ({ page }) => { + await page.goto('./html/unified-brand/light-dark-brand.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); + + await check_link_colors(page, 'quarto-light'); +}); + +test('Dark and light brand files', async ({ page }) => { + await page.goto('./html/unified-brand/dark-light-brand-file.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); + + await check_link_colors(page, 'quarto-dark'); +}); + +test('Dark and light brands inline', async ({ page }) => { + await page.goto('./html/unified-brand/dark-light-brand.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); + + await check_link_colors(page, 'quarto-dark'); +}); + + +test('Unified light and dark brand file', async ({ page }) => { + await page.goto('./html/unified-brand/unified-colors-file.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); + + await check_link_colors(page, 'quarto-light'); +}); + +test('Unified light and dark brand inline', async ({ page }) => { + await page.goto('./html/unified-brand/unified-colors.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); + + await check_link_colors(page, 'quarto-light'); +}); + +test('Unified light and dark typography inline', async ({ page }) => { + await page.goto('./html/unified-brand/unified-typography.html'); + expect(await page.locator('a.quarto-color-scheme-toggle').count()).toEqual(1); + + await check_link_colors(page, 'quarto-light'); +});