Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 119 additions & 4 deletions src/core/sass/brand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,24 @@ const brandColorBundle = (
"/* color variables from _brand.yml */",
'// quarto-scss-analysis-annotation { "action": "push", "origin": "_brand.yml color" }',
];
const colorCssVariables: string[] = [
"/* color CSS variables from _brand.yml */",
'// quarto-scss-analysis-annotation { "action": "push", "origin": "_brand.yml color" }',
":root {",
];

// Create `brand-` prefixed Sass and CSS variables from color.palette
for (const colorKey of Object.keys(brand.data?.color?.palette ?? {})) {
const colorVar = colorKey.replace(/[^a-zA-Z0-9_-]+/, "-");
colorVariables.push(
`$${colorKey}: ${brand.getColor(colorKey)} !default;`,
`$brand-${colorVar}: ${brand.getColor(colorKey)} !default;`,
);
colorCssVariables.push(
` --brand-${colorVar}: ${brand.getColor(colorKey)};`,
)
}

// Map theme colors directly to Sass variables
for (const colorKey of Object.keys(brand.data.color ?? {})) {
if (colorKey === "palette") {
continue;
Expand All @@ -197,6 +210,7 @@ const brandColorBundle = (
`$${colorKey}: ${brand.getColor(colorKey)} !default;`,
);
}

// format-specific name mapping
for (const [key, value] of Object.entries(nameMap)) {
const resolvedValue = brand.getColor(value);
Expand All @@ -208,6 +222,7 @@ const brandColorBundle = (
}
// const colorEntries = Object.keys(brand.color);
colorVariables.push('// quarto-scss-analysis-annotation { "action": "pop" }');
colorCssVariables.push("}", '// quarto-scss-analysis-annotation { "action": "pop" }');
const colorBundle: SassBundleLayers = {
key,
// dependency: "bootstrap",
Expand All @@ -216,12 +231,91 @@ const brandColorBundle = (
uses: "",
functions: "",
mixins: "",
rules: "",
rules: colorCssVariables.join("\n"),
},
};
return colorBundle;
};

const brandBootstrapBundle = (
brand: Brand,
key: string
): SassBundleLayers => {
// Bootstrap Variables from brand.defaults.bootstrap
const brandBootstrap = (brand?.data?.defaults?.bootstrap as unknown as Record<
string,
Record<string, string | boolean | number | null>
>);

const bsVariables: string[] = [
"/* Bootstrap variables from _brand.yml */",
'// quarto-scss-analysis-annotation { "action": "push", "origin": "_brand.yml defaults.bootstrap" }',
];
for (const bsVar of Object.keys(brandBootstrap)) {
if (bsVar === "version") {
continue;
}
bsVariables.push(
`$${bsVar}: ${brandBootstrap[bsVar]} !default;`,
);
}
bsVariables.push('// quarto-scss-analysis-annotation { "action": "pop" }');

// Bootstrap Colors from color.palette
let bootstrapColorVariables: string[] = [];
if (Number(brandBootstrap?.version ?? 5) === 5) {
// https://getbootstrap.com/docs/5.3/customize/color/#color-sass-maps
bootstrapColorVariables = [
"blue",
"indigo",
"purple",
"pink",
"red",
"orange",
"yellow",
"green",
"teal",
"cyan",
"black",
"white",
"gray",
"gray-dark"
]
}

const bsColors: string[] = [
"/* Bootstrap color variables from _brand.yml */",
'// quarto-scss-analysis-annotation { "action": "push", "origin": "_brand.yml color.palette" }',
];

if (bootstrapColorVariables.length > 0) {
for (const colorKey of Object.keys(brand.data?.color?.palette ?? {})) {
if (!bootstrapColorVariables.includes(colorKey)) {
continue;
}

bsColors.push(
`$${colorKey}: ${brand.getColor(colorKey)} !default;`,
);
}
}

bsColors.push('// quarto-scss-analysis-annotation { "action": "pop" }');

const bsBundle: SassBundleLayers = {
key,
// dependency: "bootstrap",
quarto: {
defaults: bsColors.join("\n") + "\n" + bsVariables.join("\n"),
uses: "",
functions: "",
mixins: "",
rules: "",
},
};
return bsBundle;
};

const brandTypographyBundle = (
brand: Brand,
key: string,
Expand Down Expand Up @@ -446,7 +540,7 @@ const brandTypographyBundle = (
return typographyBundle;
};

export async function brandBootstrapSassBundleLayers(
export async function brandSassBundleLayers(
fileName: string | undefined,
project: ProjectContext,
key: string,
Expand All @@ -466,12 +560,33 @@ export async function brandBootstrapSassBundleLayers(
return sassBundles;
}

export async function brandBootstrapSassBundleLayers(
fileName: string | undefined,
project: ProjectContext,
key: string,
nameMap: Record<string, string> = {},
): Promise<SassBundleLayers[]> {
const brand = await project.resolveBrand(fileName);
const sassBundles = await brandSassBundleLayers(fileName, project, key, nameMap);

if (brand?.data?.defaults?.bootstrap) {
const bsBundle = brandBootstrapBundle(brand, key);
if (bsBundle) {
// Add bsBundle to the beginning of the array so that defaults appear
// *after* the rest of the brand variables.
sassBundles.unshift(bsBundle);
}
}

return sassBundles;
}

export async function brandRevealSassBundleLayers(
input: string | undefined,
_format: Format,
project: ProjectContext,
): Promise<SassBundleLayers[]> {
return brandBootstrapSassBundleLayers(
return brandSassBundleLayers(
input,
project,
"reveal-theme",
Expand Down
11 changes: 3 additions & 8 deletions src/resources/editor/tools/vs-code.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21771,11 +21771,6 @@ var require_yaml_intelligence_resources = __commonJS({
"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.",
"Names of customizeable logos",
"Source path or source path with layout options for logo",
"X-Y positioning of logo",
"Padding of logo",
"Width of logo",
"Source path of logo",
"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.",
Expand Down Expand Up @@ -24123,12 +24118,12 @@ var require_yaml_intelligence_resources = __commonJS({
mermaid: "%%"
},
"handlers/mermaid/schema.yml": {
_internalId: 192336,
_internalId: 192600,
type: "object",
description: "be an object",
properties: {
"mermaid-format": {
_internalId: 192328,
_internalId: 192592,
type: "enum",
enum: [
"png",
Expand All @@ -24144,7 +24139,7 @@ var require_yaml_intelligence_resources = __commonJS({
exhaustiveCompletions: true
},
theme: {
_internalId: 192335,
_internalId: 192599,
type: "anyOf",
anyOf: [
{
Expand Down
11 changes: 3 additions & 8 deletions src/resources/editor/tools/yaml/web-worker.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 3 additions & 8 deletions src/resources/editor/tools/yaml/yaml-intelligence-resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -14743,11 +14743,6 @@
"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.",
"Names of customizeable logos",
"Source path or source path with layout options for logo",
"X-Y positioning of logo",
"Padding of logo",
"Width of logo",
"Source path of logo",
"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.",
Expand Down Expand Up @@ -17095,12 +17090,12 @@
"mermaid": "%%"
},
"handlers/mermaid/schema.yml": {
"_internalId": 192336,
"_internalId": 192600,
"type": "object",
"description": "be an object",
"properties": {
"mermaid-format": {
"_internalId": 192328,
"_internalId": 192592,
"type": "enum",
"enum": [
"png",
Expand All @@ -17116,7 +17111,7 @@
"exhaustiveCompletions": true
},
"theme": {
"_internalId": 192335,
"_internalId": 192599,
"type": "anyOf",
"anyOf": [
{
Expand Down
Loading