web: Fix inline documentation rendering (#13379)
web: Fix issues surrounding markdown rendering. - Fix issue where Mermaid diagrams do not render. - Fix link colors in dark mode. - Fix anchored links triggering router. - Fix issue where links occasionally link to missing page.
This commit is contained in:
12
package-lock.json
generated
Normal file
12
package-lock.json
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "@goauthentik/authentik",
|
||||||
|
"version": "2025.2.1",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "@goauthentik/authentik",
|
||||||
|
"version": "2025.2.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,6 +13,7 @@ const importInlinePatterns = [
|
|||||||
'import AKGlobal from "@goauthentik/common/styles/authentik\\.css',
|
'import AKGlobal from "@goauthentik/common/styles/authentik\\.css',
|
||||||
'import PF.+ from "@patternfly/patternfly/\\S+\\.css',
|
'import PF.+ from "@patternfly/patternfly/\\S+\\.css',
|
||||||
'import ThemeDark from "@goauthentik/common/styles/theme-dark\\.css',
|
'import ThemeDark from "@goauthentik/common/styles/theme-dark\\.css',
|
||||||
|
'import OneDark from "@goauthentik/common/styles/one-dark\\.css',
|
||||||
'import styles from "\\./LibraryPageImpl\\.css',
|
'import styles from "\\./LibraryPageImpl\\.css',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -39,6 +40,10 @@ const config: StorybookConfig = {
|
|||||||
from: "../src/common/styles/theme-dark.css",
|
from: "../src/common/styles/theme-dark.css",
|
||||||
to: "@goauthentik/common/styles/theme-dark.css",
|
to: "@goauthentik/common/styles/theme-dark.css",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
from: "../src/common/styles/one-dark.css",
|
||||||
|
to: "@goauthentik/common/styles/one-dark.css",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
framework: {
|
framework: {
|
||||||
name: "@storybook/web-components-vite",
|
name: "@storybook/web-components-vite",
|
||||||
|
@ -71,7 +71,7 @@ export default [
|
|||||||
...globals.node,
|
...globals.node,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
files: ["scripts/*.mjs", "*.ts", "*.mjs"],
|
files: ["scripts/**/*.mjs", "*.ts", "*.mjs"],
|
||||||
rules: {
|
rules: {
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
// We WANT our scripts to output to the console!
|
// We WANT our scripts to output to the console!
|
||||||
|
4375
web/package-lock.json
generated
4375
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,8 @@
|
|||||||
"@lit/localize": "^0.12.2",
|
"@lit/localize": "^0.12.2",
|
||||||
"@lit/reactive-element": "^2.0.4",
|
"@lit/reactive-element": "^2.0.4",
|
||||||
"@lit/task": "^1.0.1",
|
"@lit/task": "^1.0.1",
|
||||||
|
"@mdx-js/esbuild": "^3.1.0",
|
||||||
|
"@mdx-js/mdx": "^3.1.0",
|
||||||
"@open-wc/lit-helpers": "^0.7.0",
|
"@open-wc/lit-helpers": "^0.7.0",
|
||||||
"@patternfly/elements": "^4.0.2",
|
"@patternfly/elements": "^4.0.2",
|
||||||
"@patternfly/patternfly": "^4.224.2",
|
"@patternfly/patternfly": "^4.224.2",
|
||||||
@ -36,9 +38,11 @@
|
|||||||
"guacamole-common-js": "^1.5.0",
|
"guacamole-common-js": "^1.5.0",
|
||||||
"lit": "^3.2.0",
|
"lit": "^3.2.0",
|
||||||
"md-front-matter": "^1.0.4",
|
"md-front-matter": "^1.0.4",
|
||||||
|
"mdx-mermaid": "^2.0.3",
|
||||||
"mermaid": "^11.4.1",
|
"mermaid": "^11.4.1",
|
||||||
"rapidoc": "^9.3.7",
|
"rapidoc": "^9.3.7",
|
||||||
"showdown": "^2.1.0",
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1",
|
||||||
"style-mod": "^4.1.2",
|
"style-mod": "^4.1.2",
|
||||||
"ts-pattern": "^5.4.0",
|
"ts-pattern": "^5.4.0",
|
||||||
"webcomponent-qr-code": "^1.2.0",
|
"webcomponent-qr-code": "^1.2.0",
|
||||||
@ -66,13 +70,13 @@
|
|||||||
"@types/guacamole-common-js": "^1.5.2",
|
"@types/guacamole-common-js": "^1.5.2",
|
||||||
"@types/mocha": "^10.0.8",
|
"@types/mocha": "^10.0.8",
|
||||||
"@types/node": "^22.7.4",
|
"@types/node": "^22.7.4",
|
||||||
"@types/showdown": "^2.0.6",
|
"@types/react": "^18.3.13",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
||||||
"@typescript-eslint/parser": "^8.8.0",
|
"@typescript-eslint/parser": "^8.8.0",
|
||||||
"@wdio/browser-runner": "9.4",
|
"@wdio/browser-runner": "9.4",
|
||||||
"@wdio/cli": "9.4",
|
"@wdio/cli": "9.4",
|
||||||
"@wdio/spec-reporter": "^9.1.2",
|
"@wdio/spec-reporter": "^9.1.2",
|
||||||
"chokidar": "^4.0.1",
|
"change-case": "^5.4.4",
|
||||||
"chromedriver": "^131.0.1",
|
"chromedriver": "^131.0.1",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"eslint": "^9.11.1",
|
"eslint": "^9.11.1",
|
||||||
@ -87,6 +91,13 @@
|
|||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"pseudolocale": "^2.1.0",
|
"pseudolocale": "^2.1.0",
|
||||||
|
"rehype-highlight": "^7.0.2",
|
||||||
|
"rehype-parse": "^9.0.1",
|
||||||
|
"rehype-stringify": "^10.0.1",
|
||||||
|
"remark-directive": "^4.0.0",
|
||||||
|
"remark-frontmatter": "^5.0.0",
|
||||||
|
"remark-gfm": "^4.0.1",
|
||||||
|
"remark-mdx-frontmatter": "^5.0.0",
|
||||||
"rollup-plugin-modify": "^3.0.0",
|
"rollup-plugin-modify": "^3.0.0",
|
||||||
"rollup-plugin-postcss-lit": "^2.1.0",
|
"rollup-plugin-postcss-lit": "^2.1.0",
|
||||||
"storybook": "^8.3.4",
|
"storybook": "^8.3.4",
|
||||||
@ -118,7 +129,7 @@
|
|||||||
"build-locales:build": "wireit",
|
"build-locales:build": "wireit",
|
||||||
"build-proxy": "wireit",
|
"build-proxy": "wireit",
|
||||||
"build:sfe": "wireit",
|
"build:sfe": "wireit",
|
||||||
"esbuild:watch": "node build.mjs --watch",
|
"esbuild:watch": "node scripts/build-web.mjs --watch",
|
||||||
"extract-locales": "wireit",
|
"extract-locales": "wireit",
|
||||||
"format": "wireit",
|
"format": "wireit",
|
||||||
"lint": "wireit",
|
"lint": "wireit",
|
||||||
@ -153,7 +164,7 @@
|
|||||||
"instead of `npm run watch`. The former is more comprehensive, but ",
|
"instead of `npm run watch`. The former is more comprehensive, but ",
|
||||||
"the latter is faster."
|
"the latter is faster."
|
||||||
],
|
],
|
||||||
"command": "${NODE_RUNNER} build.mjs",
|
"command": "${NODE_RUNNER} scripts/build-web.mjs",
|
||||||
"files": [
|
"files": [
|
||||||
"src/**/*.{css,jpg,png,ts,js,json}",
|
"src/**/*.{css,jpg,png,ts,js,json}",
|
||||||
"!src/**/*.stories.ts",
|
"!src/**/*.stories.ts",
|
||||||
@ -173,6 +184,7 @@
|
|||||||
"./dist/poly-*.js.map",
|
"./dist/poly-*.js.map",
|
||||||
"./dist/custom.css",
|
"./dist/custom.css",
|
||||||
"./dist/theme-dark.css",
|
"./dist/theme-dark.css",
|
||||||
|
"./dist/one-dark.css",
|
||||||
"./dist/patternfly.min.css"
|
"./dist/patternfly.min.css"
|
||||||
],
|
],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
@ -195,7 +207,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"build-proxy": {
|
"build-proxy": {
|
||||||
"command": "node build.mjs --proxy",
|
"command": "node scripts/build-web.mjs --proxy",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"build-locales"
|
"build-locales"
|
||||||
]
|
]
|
||||||
|
@ -3,15 +3,16 @@ import esbuild from "esbuild";
|
|||||||
import findFreePorts from "find-free-ports";
|
import findFreePorts from "find-free-ports";
|
||||||
import { copyFileSync, mkdirSync, readFileSync, statSync } from "fs";
|
import { copyFileSync, mkdirSync, readFileSync, statSync } from "fs";
|
||||||
import { globSync } from "glob";
|
import { globSync } from "glob";
|
||||||
import path from "path";
|
import * as path from "path";
|
||||||
import { cwd } from "process";
|
import { cwd } from "process";
|
||||||
import process from "process";
|
import process from "process";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
|
|
||||||
import { buildObserverPlugin } from "./build-observer-plugin.mjs";
|
import { mdxPlugin } from "./esbuild/build-mdx-plugin.mjs";
|
||||||
|
import { buildObserverPlugin } from "./esbuild/build-observer-plugin.mjs";
|
||||||
|
|
||||||
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
||||||
let authentikProjectRoot = __dirname + "../";
|
let authentikProjectRoot = path.join(__dirname, "..", "..");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Use the package.json file in the root folder, as it has the current version information.
|
// Use the package.json file in the root folder, as it has the current version information.
|
||||||
@ -122,11 +123,10 @@ const BASE_ESBUILD_OPTIONS = {
|
|||||||
loader: {
|
loader: {
|
||||||
".css": "text",
|
".css": "text",
|
||||||
".md": "text",
|
".md": "text",
|
||||||
".mdx": "text",
|
|
||||||
},
|
},
|
||||||
define: definitions,
|
define: definitions,
|
||||||
format: "esm",
|
format: "esm",
|
||||||
plugins: [],
|
plugins: [mdxPlugin()],
|
||||||
logOverride: {
|
logOverride: {
|
||||||
/**
|
/**
|
||||||
* HACK: Silences issue originating in ESBuild.
|
* HACK: Silences issue originating in ESBuild.
|
||||||
@ -161,7 +161,7 @@ function composeVersionID() {
|
|||||||
* @throws {Error} on build failure
|
* @throws {Error} on build failure
|
||||||
*/
|
*/
|
||||||
function createEntryPointOptions([source, dest], overrides = {}) {
|
function createEntryPointOptions([source, dest], overrides = {}) {
|
||||||
const outdir = path.join(__dirname, "./dist", dest);
|
const outdir = path.join(__dirname, "..", "dist", dest);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...BASE_ESBUILD_OPTIONS,
|
...BASE_ESBUILD_OPTIONS,
|
||||||
@ -214,7 +214,7 @@ async function doWatch() {
|
|||||||
buildObserverPlugin({
|
buildObserverPlugin({
|
||||||
serverURL,
|
serverURL,
|
||||||
logPrefix: entryPoint[1],
|
logPrefix: entryPoint[1],
|
||||||
relativeRoot: __dirname,
|
relativeRoot: path.join(__dirname, ".."),
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
define: {
|
define: {
|
299
web/scripts/esbuild/build-mdx-plugin.mjs
Normal file
299
web/scripts/esbuild/build-mdx-plugin.mjs
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
/**
|
||||||
|
* @import {Options as HighlightOptions} from 'rehype-highlight'
|
||||||
|
* @import {CompileOptions} from '@mdx-js/mdx'
|
||||||
|
* @import {mdxmermaid} from 'mdx-mermaid'
|
||||||
|
* @import {Message,
|
||||||
|
OnLoadArgs,
|
||||||
|
OnLoadResult,
|
||||||
|
Plugin,
|
||||||
|
PluginBuild
|
||||||
|
* } from 'esbuild'
|
||||||
|
*/
|
||||||
|
import { run as runMDX } from "@mdx-js/mdx";
|
||||||
|
import { createFormatAwareProcessors } from "@mdx-js/mdx/internal-create-format-aware-processors";
|
||||||
|
import { extnamesToRegex } from "@mdx-js/mdx/internal-extnames-to-regex";
|
||||||
|
import apacheGrammar from "highlight.js/lib/languages/apache";
|
||||||
|
import diffGrammar from "highlight.js/lib/languages/diff";
|
||||||
|
import confGrammar from "highlight.js/lib/languages/ini";
|
||||||
|
import nginxGrammar from "highlight.js/lib/languages/nginx";
|
||||||
|
import { common } from "lowlight";
|
||||||
|
import mdxMermaid from "mdx-mermaid";
|
||||||
|
import { Mermaid } from "mdx-mermaid/lib/Mermaid";
|
||||||
|
import assert from "node:assert";
|
||||||
|
import fs from "node:fs/promises";
|
||||||
|
import path from "node:path";
|
||||||
|
import React from "react";
|
||||||
|
import { renderToStaticMarkup } from "react-dom/server";
|
||||||
|
import * as runtime from "react/jsx-runtime";
|
||||||
|
import rehypeHighlight from "rehype-highlight";
|
||||||
|
import remarkDirective from "remark-directive";
|
||||||
|
import remarkFrontmatter from "remark-frontmatter";
|
||||||
|
import remarkGFM from "remark-gfm";
|
||||||
|
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
|
||||||
|
import remarkParse from "remark-parse";
|
||||||
|
import { SourceMapGenerator } from "source-map";
|
||||||
|
import { VFile } from "vfile";
|
||||||
|
import { VFileMessage } from "vfile-message";
|
||||||
|
|
||||||
|
import { remarkAdmonition } from "./remark/remark-admonition.mjs";
|
||||||
|
import { remarkHeadings } from "./remark/remark-headings.mjs";
|
||||||
|
import { remarkLinks } from "./remark/remark-links.mjs";
|
||||||
|
import { remarkLists } from "./remark/remark-lists.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Omit<OnLoadArgs, 'pluginData'> & LoadDataFields} LoadData
|
||||||
|
* Data passed to `onload`.
|
||||||
|
*
|
||||||
|
* @typedef LoadDataFields
|
||||||
|
* Extra fields given in `data` to `onload`.
|
||||||
|
* @property {PluginData | null | undefined} [pluginData]
|
||||||
|
* Plugin data.
|
||||||
|
*
|
||||||
|
* @typedef {CompileOptions} Options
|
||||||
|
* Configuration.
|
||||||
|
*
|
||||||
|
* Options are the same as `compile` from `@mdx-js/mdx`.
|
||||||
|
*
|
||||||
|
* @typedef PluginData
|
||||||
|
* Extra data passed.
|
||||||
|
* @property {Buffer | string | null | undefined} [contents]
|
||||||
|
* File contents.
|
||||||
|
*
|
||||||
|
* @typedef State
|
||||||
|
* Info passed around.
|
||||||
|
* @property {string} doc
|
||||||
|
* File value.
|
||||||
|
* @property {string} name
|
||||||
|
* Plugin name.
|
||||||
|
* @property {string} path
|
||||||
|
* File path.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const eol = /\r\n|\r|\n|\u2028|\u2029/g;
|
||||||
|
|
||||||
|
const name = "@mdx-js/esbuild";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile MDX to HTML.
|
||||||
|
* *
|
||||||
|
* @param {Readonly<Options> | null | undefined} [mdxOptions]
|
||||||
|
* Configuration (optional).
|
||||||
|
* @return {Plugin}
|
||||||
|
* Plugin.
|
||||||
|
*/
|
||||||
|
export function mdxPlugin(mdxOptions) {
|
||||||
|
/** @type {mdxmermaid.Config} */
|
||||||
|
const mermaidConfig = {
|
||||||
|
output: "svg",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {HighlightOptions}
|
||||||
|
*/
|
||||||
|
const highlightThemeOptions = {
|
||||||
|
languages: {
|
||||||
|
...common,
|
||||||
|
nginx: nginxGrammar,
|
||||||
|
apache: apacheGrammar,
|
||||||
|
conf: confGrammar,
|
||||||
|
diff: diffGrammar,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { extnames, process } = createFormatAwareProcessors({
|
||||||
|
...mdxOptions,
|
||||||
|
SourceMapGenerator,
|
||||||
|
outputFormat: "function-body",
|
||||||
|
|
||||||
|
remarkPlugins: [
|
||||||
|
remarkParse,
|
||||||
|
remarkDirective,
|
||||||
|
remarkAdmonition,
|
||||||
|
remarkGFM,
|
||||||
|
remarkFrontmatter,
|
||||||
|
remarkMdxFrontmatter,
|
||||||
|
remarkHeadings,
|
||||||
|
remarkLinks,
|
||||||
|
remarkLists,
|
||||||
|
[mdxMermaid, mermaidConfig],
|
||||||
|
],
|
||||||
|
rehypePlugins: [[rehypeHighlight, highlightThemeOptions]],
|
||||||
|
});
|
||||||
|
|
||||||
|
return { name, setup };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {PluginBuild} build
|
||||||
|
* Build.
|
||||||
|
* @returns {undefined}
|
||||||
|
* Nothing.
|
||||||
|
*/
|
||||||
|
function setup(build) {
|
||||||
|
build.onLoad({ filter: extnamesToRegex(extnames) }, onload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {LoadData} data
|
||||||
|
* Data.
|
||||||
|
* @returns {Promise<OnLoadResult>}
|
||||||
|
* Result.
|
||||||
|
*/
|
||||||
|
async function onload(data) {
|
||||||
|
const document = String(
|
||||||
|
data.pluginData &&
|
||||||
|
data.pluginData.contents !== null &&
|
||||||
|
data.pluginData.contents !== undefined
|
||||||
|
? data.pluginData.contents
|
||||||
|
: await fs.readFile(data.path),
|
||||||
|
);
|
||||||
|
|
||||||
|
/** @type {State} */
|
||||||
|
const state = {
|
||||||
|
doc: document,
|
||||||
|
name,
|
||||||
|
path: data.path,
|
||||||
|
};
|
||||||
|
|
||||||
|
let file = new VFile({
|
||||||
|
path: data.path,
|
||||||
|
value: document,
|
||||||
|
});
|
||||||
|
|
||||||
|
/** @type {string | undefined} */
|
||||||
|
let value;
|
||||||
|
|
||||||
|
/** @type {Array<VFileMessage>} */
|
||||||
|
let messages = [];
|
||||||
|
|
||||||
|
/** @type {Array<Message>} */
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
/** @type {Array<Message>} */
|
||||||
|
const warnings = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {React.ComponentType<{children: React.ReactNode, frontmatter: Record<string, string>}>}
|
||||||
|
*/
|
||||||
|
const wrapper = ({ children, frontmatter }) => {
|
||||||
|
const title = frontmatter.title;
|
||||||
|
const nextChildren = React.Children.toArray(children);
|
||||||
|
|
||||||
|
if (title) {
|
||||||
|
nextChildren.unshift(React.createElement("h1", { key: "title" }, title));
|
||||||
|
}
|
||||||
|
|
||||||
|
return React.createElement(React.Fragment, null, nextChildren);
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
file = await process(file);
|
||||||
|
const { default: Content, ...mdxExports } = await runMDX(file, {
|
||||||
|
...runtime,
|
||||||
|
useMDXComponents: () => {
|
||||||
|
return {
|
||||||
|
mermaid: Mermaid,
|
||||||
|
Mermaid,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
baseUrl: import.meta.url,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { frontmatter = {} } = mdxExports;
|
||||||
|
const result = renderToStaticMarkup(
|
||||||
|
Content({
|
||||||
|
frontmatter,
|
||||||
|
components: {
|
||||||
|
wrapper,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
value = result;
|
||||||
|
|
||||||
|
messages = file.messages;
|
||||||
|
} catch (error_) {
|
||||||
|
const cause = /** @type {VFileMessage | Error} */ (error_);
|
||||||
|
|
||||||
|
console.error(cause);
|
||||||
|
|
||||||
|
const message =
|
||||||
|
"reason" in cause
|
||||||
|
? cause
|
||||||
|
: new VFileMessage("Cannot process MDX file with esbuild", {
|
||||||
|
cause,
|
||||||
|
ruleId: "process-error",
|
||||||
|
source: "@mdx-js/esbuild",
|
||||||
|
});
|
||||||
|
|
||||||
|
message.fatal = true;
|
||||||
|
messages.push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const message of messages) {
|
||||||
|
const list = message.fatal ? errors : warnings;
|
||||||
|
list.push(vfileMessageToEsbuild(state, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safety check: the file has a path, so there has to be a `dirname`.
|
||||||
|
assert(file.dirname, "expected `dirname` to be defined");
|
||||||
|
|
||||||
|
return {
|
||||||
|
contents: value || "",
|
||||||
|
loader: "text",
|
||||||
|
errors,
|
||||||
|
resolveDir: path.resolve(file.cwd, file.dirname),
|
||||||
|
warnings,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Readonly<State>} state
|
||||||
|
* Info passed around.
|
||||||
|
* @param {Readonly<VFileMessage>} message
|
||||||
|
* VFile message or error.
|
||||||
|
* @returns {Message}
|
||||||
|
* ESBuild message.
|
||||||
|
*/
|
||||||
|
function vfileMessageToEsbuild(state, message) {
|
||||||
|
const place = message.place;
|
||||||
|
const start = place ? ("start" in place ? place.start : place) : undefined;
|
||||||
|
const end = place && "end" in place ? place.end : undefined;
|
||||||
|
let length = 0;
|
||||||
|
let lineStart = 0;
|
||||||
|
let line = 0;
|
||||||
|
let column = 0;
|
||||||
|
|
||||||
|
if (start && start.offset !== undefined) {
|
||||||
|
line = start.line;
|
||||||
|
column = start.column - 1;
|
||||||
|
lineStart = start.offset - column;
|
||||||
|
length = 1;
|
||||||
|
|
||||||
|
if (end && end.offset !== undefined) {
|
||||||
|
length = end.offset - start.offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eol.lastIndex = lineStart;
|
||||||
|
|
||||||
|
const match = eol.exec(state.doc);
|
||||||
|
const lineEnd = match ? match.index : state.doc.length;
|
||||||
|
|
||||||
|
return {
|
||||||
|
detail: message,
|
||||||
|
id: "",
|
||||||
|
location: {
|
||||||
|
column,
|
||||||
|
file: state.path,
|
||||||
|
length: Math.min(length, lineEnd),
|
||||||
|
line,
|
||||||
|
lineText: state.doc.slice(lineStart, lineEnd),
|
||||||
|
namespace: "file",
|
||||||
|
suggestion: "",
|
||||||
|
},
|
||||||
|
notes: [],
|
||||||
|
pluginName: state.name,
|
||||||
|
text: message.reason,
|
||||||
|
};
|
||||||
|
}
|
@ -8,7 +8,7 @@ import path from "path";
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function serializeCustomEventToStream(event) {
|
export function serializeCustomEventToStream(event) {
|
||||||
// @ts-ignore
|
// @ts-expect-error - TS doesn't know about the detail property
|
||||||
const data = event.detail ?? {};
|
const data = event.detail ?? {};
|
||||||
|
|
||||||
const eventContent = [`event: ${event.type}`, `data: ${JSON.stringify(data)}`];
|
const eventContent = [`event: ${event.type}`, `data: ${JSON.stringify(data)}`];
|
46
web/scripts/esbuild/remark/remark-admonition.mjs
Normal file
46
web/scripts/esbuild/remark/remark-admonition.mjs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @import {Plugin} from 'unified'
|
||||||
|
* @import {Directives} from 'mdast-util-directive'
|
||||||
|
* @import {} from 'mdast-util-to-hast'
|
||||||
|
* @import {Root} from 'mdast'
|
||||||
|
* @import {VFile} from 'vfile'
|
||||||
|
*/
|
||||||
|
import { h } from "hastscript";
|
||||||
|
import { visit } from "unist-util-visit";
|
||||||
|
|
||||||
|
const ADMONITION_TYPES = new Set(["info", "warning", "danger", "note"]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remark plugin to process links
|
||||||
|
* @type {Plugin<[unknown], Root, VFile>}
|
||||||
|
*/
|
||||||
|
export function remarkAdmonition() {
|
||||||
|
return function transformer(tree) {
|
||||||
|
/**
|
||||||
|
* @param {Directives} node
|
||||||
|
*/
|
||||||
|
const visitor = (node) => {
|
||||||
|
if (
|
||||||
|
node.type === "containerDirective" ||
|
||||||
|
node.type === "leafDirective" ||
|
||||||
|
node.type === "textDirective"
|
||||||
|
) {
|
||||||
|
if (!ADMONITION_TYPES.has(node.name)) return;
|
||||||
|
|
||||||
|
const data = node.data || (node.data = {});
|
||||||
|
|
||||||
|
const tagName = node.type === "textDirective" ? "span" : "ak-alert";
|
||||||
|
|
||||||
|
data.hName = tagName;
|
||||||
|
|
||||||
|
const element = h(tagName, node.attributes || {});
|
||||||
|
|
||||||
|
data.hProperties = element.properties || {};
|
||||||
|
data.hProperties.level = `pf-m-${node.name}`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore - visit cannot infer the type of the visitor.
|
||||||
|
visit(tree, visitor);
|
||||||
|
};
|
||||||
|
}
|
33
web/scripts/esbuild/remark/remark-headings.mjs
Normal file
33
web/scripts/esbuild/remark/remark-headings.mjs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* @import {Plugin} from 'unified'
|
||||||
|
* @import {Root, Heading} from 'mdast'
|
||||||
|
* @import {VFile} from 'vfile'
|
||||||
|
*/
|
||||||
|
import { kebabCase } from "change-case";
|
||||||
|
import { toString } from "mdast-util-to-string";
|
||||||
|
import { visit } from "unist-util-visit";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remark plugin to process links
|
||||||
|
* @type {Plugin<[unknown], Root, VFile>}
|
||||||
|
*/
|
||||||
|
export const remarkHeadings = () => {
|
||||||
|
return function transformer(tree) {
|
||||||
|
/**
|
||||||
|
* @param {Heading} node
|
||||||
|
*/
|
||||||
|
const visitor = (node) => {
|
||||||
|
const textContent = toString(node);
|
||||||
|
const id = kebabCase(textContent);
|
||||||
|
|
||||||
|
node.data = node.data || {};
|
||||||
|
node.data.hProperties = {
|
||||||
|
...node.data.hProperties,
|
||||||
|
id,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore - visit cannot infer the type of the visitor.
|
||||||
|
visit(tree, "heading", visitor);
|
||||||
|
};
|
||||||
|
};
|
59
web/scripts/esbuild/remark/remark-links.mjs
Normal file
59
web/scripts/esbuild/remark/remark-links.mjs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* @import {Plugin} from 'unified'
|
||||||
|
* @import {} from 'mdast-util-directive'
|
||||||
|
* @import {} from 'mdast-util-to-hast'
|
||||||
|
* @import {Root, Link} from 'mdast'
|
||||||
|
* @import {VFile} from 'vfile'
|
||||||
|
*/
|
||||||
|
import * as path from "node:path";
|
||||||
|
import { visit } from "unist-util-visit";
|
||||||
|
|
||||||
|
const DOCS_DOMAIN = "https://goauthentik.io";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remark plugin to process links
|
||||||
|
* @type {Plugin<[unknown], Root, VFile>}
|
||||||
|
*/
|
||||||
|
export const remarkLinks = () => {
|
||||||
|
return function transformer(tree, file) {
|
||||||
|
const docsRoot = path.resolve(file.cwd, "..", "website");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Link} node
|
||||||
|
*/
|
||||||
|
const visitor = (node) => {
|
||||||
|
node.data = node.data || {};
|
||||||
|
|
||||||
|
if (node.url.startsWith("#")) {
|
||||||
|
node.data.hProperties = {
|
||||||
|
className: "markdown-heading",
|
||||||
|
};
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node.data.hProperties = {
|
||||||
|
...node.data.hProperties,
|
||||||
|
rel: "noopener noreferrer",
|
||||||
|
target: "_blank",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (node.url.startsWith(".") && file.dirname) {
|
||||||
|
const nextPathname = path.resolve(
|
||||||
|
"/",
|
||||||
|
path.relative(docsRoot, file.dirname),
|
||||||
|
node.url,
|
||||||
|
);
|
||||||
|
const nextURL = new URL(nextPathname, DOCS_DOMAIN);
|
||||||
|
|
||||||
|
// Remove trailing .md and .mdx, and trailing "index".
|
||||||
|
nextURL.pathname = nextURL.pathname.replace(/(index)?\.mdx?$/, "");
|
||||||
|
|
||||||
|
node.data.hProperties.href = nextURL.toString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore - visit cannot infer the type of the visitor.
|
||||||
|
visit(tree, "link", visitor);
|
||||||
|
};
|
||||||
|
};
|
29
web/scripts/esbuild/remark/remark-lists.mjs
Normal file
29
web/scripts/esbuild/remark/remark-lists.mjs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* @import {Plugin} from 'unified'
|
||||||
|
* @import {Root, List} from 'mdast'
|
||||||
|
* @import {VFile} from 'vfile'
|
||||||
|
*/
|
||||||
|
import { visit } from "unist-util-visit";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remark plugin to process links
|
||||||
|
* @type {Plugin<[unknown], Root, VFile>}
|
||||||
|
*/
|
||||||
|
export const remarkLists = () => {
|
||||||
|
return function transformer(tree) {
|
||||||
|
/**
|
||||||
|
* @param {List} node
|
||||||
|
*/
|
||||||
|
const visitor = (node) => {
|
||||||
|
node.data = node.data || {};
|
||||||
|
|
||||||
|
node.data.hProperties = {
|
||||||
|
...node.data.hProperties,
|
||||||
|
className: "pf-c-list",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore - visit cannot infer the type of the visitor.
|
||||||
|
visit(tree, "list", visitor);
|
||||||
|
};
|
||||||
|
};
|
@ -89,7 +89,7 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
|||||||
return html`<div class="pf-c-sidebar__panel pf-m-width-25">
|
return html`<div class="pf-c-sidebar__panel pf-m-width-25">
|
||||||
<div class="pf-c-card">
|
<div class="pf-c-card">
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<ak-markdown .md=${MDApplication} meta="applications/index.md"></ak-markdown>
|
<ak-markdown .content=${MDApplication}></ak-markdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
@ -221,7 +221,7 @@ export class OAuth2ProviderViewPage extends AKElement {
|
|||||||
>
|
>
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="pf-c-description-list__description">
|
<dd class="pf-c-description-list__description">
|
||||||
<div class="pf-c-description-list__text">
|
<div class="pf-c-description-list__text pf-m-monospace">
|
||||||
${this.provider.clientId}
|
${this.provider.clientId}
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
@ -236,7 +236,9 @@ export class OAuth2ProviderViewPage extends AKElement {
|
|||||||
<div class="pf-c-description-list__text">
|
<div class="pf-c-description-list__text">
|
||||||
<ul>
|
<ul>
|
||||||
${this.provider.redirectUris.map((ru) => {
|
${this.provider.redirectUris.map((ru) => {
|
||||||
return html`<li>${ru.matchingMode}: ${ru.url}</li>`;
|
return html`<li class="pf-m-monospace">
|
||||||
|
${ru.matchingMode}: ${ru.url}
|
||||||
|
</li>`;
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -356,6 +358,7 @@ export class OAuth2ProviderViewPage extends AKElement {
|
|||||||
>
|
>
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<ak-markdown
|
<ak-markdown
|
||||||
|
.content=${MDProviderOAuth2}
|
||||||
.replacers=${[
|
.replacers=${[
|
||||||
(input: string) => {
|
(input: string) => {
|
||||||
if (!this.provider) {
|
if (!this.provider) {
|
||||||
@ -367,8 +370,6 @@ export class OAuth2ProviderViewPage extends AKElement {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
.md=${MDProviderOAuth2}
|
|
||||||
meta="providers/oauth2/index.md"
|
|
||||||
></ak-markdown>
|
></ak-markdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -196,8 +196,8 @@ export class ProxyProviderViewPage extends AKElement {
|
|||||||
class="pf-c-page__main-section pf-m-no-padding-mobile ak-markdown-section"
|
class="pf-c-page__main-section pf-m-no-padding-mobile ak-markdown-section"
|
||||||
>
|
>
|
||||||
<ak-markdown
|
<ak-markdown
|
||||||
|
.content=${server.md}
|
||||||
.replacers=${replacers}
|
.replacers=${replacers}
|
||||||
.md=${server.md}
|
|
||||||
meta=${server.meta}
|
meta=${server.meta}
|
||||||
></ak-markdown>
|
></ak-markdown>
|
||||||
</section>`;
|
</section>`;
|
||||||
@ -266,7 +266,7 @@ export class ProxyProviderViewPage extends AKElement {
|
|||||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<ak-markdown
|
<ak-markdown
|
||||||
.md=${MDHeaderAuthentication}
|
.content=${MDHeaderAuthentication}
|
||||||
meta="proxy/header_authentication.md"
|
meta="proxy/header_authentication.md"
|
||||||
></ak-markdown>
|
></ak-markdown>
|
||||||
</div>
|
</div>
|
||||||
|
@ -244,7 +244,7 @@ export class SCIMProviderViewPage extends AKElement {
|
|||||||
<div class="pf-c-card pf-l-grid__item pf-m-5-col">
|
<div class="pf-c-card pf-l-grid__item pf-m-5-col">
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<ak-markdown
|
<ak-markdown
|
||||||
.md=${MDSCIMProvider}
|
.content=${MDSCIMProvider}
|
||||||
meta="providers/scim/index.md"
|
meta="providers/scim/index.md"
|
||||||
></ak-markdown>
|
></ak-markdown>
|
||||||
</div>
|
</div>
|
||||||
|
@ -137,10 +137,13 @@ export class SSFProviderViewPage extends AKElement {
|
|||||||
<dd class="pf-c-description-list__description">
|
<dd class="pf-c-description-list__description">
|
||||||
<div class="pf-c-description-list__text">
|
<div class="pf-c-description-list__text">
|
||||||
<input
|
<input
|
||||||
class="pf-c-form-control"
|
class="pf-c-form-control pf-m-monospace"
|
||||||
readonly
|
readonly
|
||||||
type="text"
|
type="text"
|
||||||
value=${this.provider.ssfUrl || ""}
|
value=${this.provider.ssfUrl || ""}
|
||||||
|
placeholder=${this.provider.ssfUrl
|
||||||
|
? msg("SSF URL")
|
||||||
|
: msg("No assigned application")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -187,7 +187,7 @@ export class KerberosSourceViewPage extends AKElement {
|
|||||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||||
<div class="pf-c-card__body">
|
<div class="pf-c-card__body">
|
||||||
<ak-markdown
|
<ak-markdown
|
||||||
.md=${MDSourceKerberosBrowser}
|
.content=${MDSourceKerberosBrowser}
|
||||||
meta="users-sources/protocols/kerberos/browser.md"
|
meta="users-sources/protocols/kerberos/browser.md"
|
||||||
;
|
;
|
||||||
></ak-markdown>
|
></ak-markdown>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/* #region Global */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--ak-accent: #fd4b2d;
|
--ak-accent: #fd4b2d;
|
||||||
|
|
||||||
@ -45,7 +47,44 @@ html > form > input {
|
|||||||
left: -2000px;
|
left: -2000px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#region Icons*/
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Anchors */
|
||||||
|
|
||||||
|
a {
|
||||||
|
--pf-global--link--Color: var(--pf-global--link--Color--light);
|
||||||
|
--pf-global--link--Color--hover: var(--pf-global--link--Color--light--hover);
|
||||||
|
--pf-global--link--Color--visited: var(--pf-global--link--Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note that order of anchor pseudo-selectors must follow:
|
||||||
|
|
||||||
|
1. link
|
||||||
|
2. visited
|
||||||
|
3. hover
|
||||||
|
4. active
|
||||||
|
*/
|
||||||
|
|
||||||
|
a:link {
|
||||||
|
color: var(--pf-global--link--Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: var(--pf-global--link--Color--visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--pf-global--link--Color--hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:active {
|
||||||
|
color: var(--pf-global--link--Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Icons */
|
||||||
|
|
||||||
.pf-icon {
|
.pf-icon {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -66,7 +105,7 @@ html > form > input {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#endregion*/
|
/* #endregion */
|
||||||
|
|
||||||
.pf-c-page__header {
|
.pf-c-page__header {
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
@ -74,15 +113,15 @@ html > form > input {
|
|||||||
box-shadow: var(--pf-global--BoxShadow--lg-bottom);
|
box-shadow: var(--pf-global--BoxShadow--lg-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************
|
/* #region Login adjustments */
|
||||||
* Login adjustments
|
|
||||||
*****************************/
|
|
||||||
/* Ensure card is displayed on small screens */
|
/* Ensure card is displayed on small screens */
|
||||||
.pf-c-login__main {
|
.pf-c-login__main {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ak-login-container {
|
.ak-login-container {
|
||||||
height: calc(100vh - var(--pf-global--spacer--lg) - var(--pf-global--spacer--lg));
|
height: calc(100vh - var(--pf-global--spacer--lg) - var(--pf-global--spacer--lg));
|
||||||
width: 35rem;
|
width: 35rem;
|
||||||
@ -90,30 +129,34 @@ html > form > input {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-login__header {
|
.pf-c-login__header {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-login__footer {
|
.pf-c-login__footer {
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-login__footer ul.pf-c-list.pf-m-inline {
|
.pf-c-login__footer ul.pf-c-list.pf-m-inline {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
}
|
}
|
||||||
/*****************************
|
|
||||||
* End Login adjustments
|
/* #endregion */
|
||||||
*****************************/
|
|
||||||
|
|
||||||
.pf-c-content h1 {
|
.pf-c-content h1 {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-content h1 i {
|
.pf-c-content h1 i {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-content h1 :first-child {
|
.pf-c-content h1 :first-child {
|
||||||
margin-right: var(--pf-global--spacer--sm);
|
margin-right: var(--pf-global--spacer--sm);
|
||||||
}
|
}
|
||||||
@ -127,9 +170,11 @@ html > form > input {
|
|||||||
.pf-m-success {
|
.pf-m-success {
|
||||||
color: var(--pf-global--success-color--100) !important;
|
color: var(--pf-global--success-color--100) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-m-warning {
|
.pf-m-warning {
|
||||||
color: var(--pf-global--warning-color--100);
|
color: var(--pf-global--warning-color--100);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-m-danger {
|
.pf-m-danger {
|
||||||
color: var(--pf-global--danger-color--100);
|
color: var(--pf-global--danger-color--100);
|
||||||
}
|
}
|
||||||
@ -167,6 +212,7 @@ html > form > input {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ak-brand img {
|
.ak-brand img {
|
||||||
padding: 0 2rem;
|
padding: 0 2rem;
|
||||||
max-height: inherit;
|
max-height: inherit;
|
||||||
@ -181,3 +227,48 @@ html > form > input {
|
|||||||
.pf-c-data-list {
|
.pf-c-data-list {
|
||||||
padding-inline-start: 0;
|
padding-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #region Mermaid */
|
||||||
|
|
||||||
|
svg[id^="mermaid-svg-"] {
|
||||||
|
.rect {
|
||||||
|
fill: var(
|
||||||
|
--ak-mermaid-box-background-color,
|
||||||
|
var(--pf-global--BackgroundColor--light-300)
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.messageText {
|
||||||
|
stroke-width: 4;
|
||||||
|
fill: var(--ak-mermaid-message-text) !important;
|
||||||
|
paint-order: stroke;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Tables */
|
||||||
|
|
||||||
|
table thead,
|
||||||
|
table tr:nth-child(2n) {
|
||||||
|
background-color: var(
|
||||||
|
--ak-table-stripe-background,
|
||||||
|
var(--pf-global--BackgroundColor--light-200)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
table td,
|
||||||
|
table th {
|
||||||
|
border: var(--pf-table-border-width) solid var(--ifm-table-border-color);
|
||||||
|
padding: var(--pf-global--spacer--md);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Code blocks */
|
||||||
|
|
||||||
|
pre:has(.hljs) {
|
||||||
|
padding: var(--pf-global--spacer--md);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
98
web/src/common/styles/one-dark.css
Normal file
98
web/src/common/styles/one-dark.css
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Atom One Dark by Daniel Gamage
|
||||||
|
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||||
|
|
||||||
|
base: #282c34
|
||||||
|
mono-1: #abb2bf
|
||||||
|
mono-2: #818896
|
||||||
|
mono-3: #5c6370
|
||||||
|
hue-1: #56b6c2
|
||||||
|
hue-2: #61aeee
|
||||||
|
hue-3: #c678dd
|
||||||
|
hue-4: #98c379
|
||||||
|
hue-5: #e06c75
|
||||||
|
hue-5-2: #be5046
|
||||||
|
hue-6: #d19a66
|
||||||
|
hue-6-2: #e6c07b
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
color: #abb2bf;
|
||||||
|
background: #282c34;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre:has(.hljs) {
|
||||||
|
background: #282c34;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #5c6370;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-doctag,
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-formula {
|
||||||
|
color: #c678dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-deletion,
|
||||||
|
.hljs-subst {
|
||||||
|
color: #e06c75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-literal {
|
||||||
|
color: #56b6c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-addition,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-meta .hljs-string {
|
||||||
|
color: #98c379;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-pseudo,
|
||||||
|
.hljs-number {
|
||||||
|
color: #d19a66;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-title {
|
||||||
|
color: #61aeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-title.class_,
|
||||||
|
.hljs-class .hljs-title {
|
||||||
|
color: #e6c07b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-link {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
@ -1,59 +1,84 @@
|
|||||||
|
/* #region Global */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--pf-global--Color--100: var(--ak-dark-foreground) !important;
|
--pf-global--Color--100: var(--ak-dark-foreground) !important;
|
||||||
--ak-global--Color--100: var(--ak-dark-foreground) !important;
|
--ak-global--Color--100: var(--ak-dark-foreground) !important;
|
||||||
--pf-c-page__main-section--m-light--BackgroundColor: var(--ak-dark-background-darker);
|
--pf-c-page__main-section--m-light--BackgroundColor: var(--ak-dark-background-darker);
|
||||||
--pf-global--link--Color: var(--ak-dark-foreground-link) !important;
|
|
||||||
--pf-global--BorderColor--100: var(--ak-dark-background-lighter) !important;
|
--pf-global--BorderColor--100: var(--ak-dark-background-lighter) !important;
|
||||||
|
--ak-mermaid-message-text: var(--ak-dark-foreground) !important;
|
||||||
|
--ak-mermaid-box-background-color: var(--ak-dark-background-lighter) !important;
|
||||||
|
--ak-table-stripe-background: var(--pf-global--BackgroundColor--dark-200);
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: var(--ak-dark-background) !important;
|
background-color: var(--ak-dark-background) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-radio {
|
.pf-c-radio {
|
||||||
--pf-c-radio__label--Color: var(--ak-dark-foreground);
|
--pf-c-radio__label--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Global page background colour */
|
/* Global page background colour */
|
||||||
.pf-c-page {
|
.pf-c-page {
|
||||||
--pf-c-page--BackgroundColor: var(--ak-dark-background);
|
--pf-c-page--BackgroundColor: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-drawer__content {
|
.pf-c-drawer__content {
|
||||||
--pf-c-drawer__content--BackgroundColor: var(--ak-dark-background);
|
--pf-c-drawer__content--BackgroundColor: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-title {
|
.pf-c-title {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-u-mb-xl {
|
.pf-u-mb-xl {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
/* Header sections */
|
/* Header sections */
|
||||||
|
|
||||||
.pf-c-page__main-section {
|
.pf-c-page__main-section {
|
||||||
--pf-c-page__main-section--BackgroundColor: var(--ak-dark-background);
|
--pf-c-page__main-section--BackgroundColor: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-trigger,
|
.sidebar-trigger,
|
||||||
.notification-trigger {
|
.notification-trigger {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-content {
|
.pf-c-content {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
/* Card */
|
|
||||||
|
/* #region Card */
|
||||||
|
|
||||||
.pf-c-card {
|
.pf-c-card {
|
||||||
--pf-c-card--BackgroundColor: var(--ak-dark-background-light);
|
--pf-c-card--BackgroundColor: var(--ak-dark-background-light);
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-card.pf-m-non-selectable-raised {
|
.pf-c-card.pf-m-non-selectable-raised {
|
||||||
--pf-c-card--BackgroundColor: var(--ak-dark-background-lighter);
|
--pf-c-card--BackgroundColor: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-card__title,
|
.pf-c-card__title,
|
||||||
.pf-c-card__body {
|
.pf-c-card__body {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
.pf-c-toolbar {
|
.pf-c-toolbar {
|
||||||
--pf-c-toolbar--BackgroundColor: var(--ak-dark-background-light);
|
--pf-c-toolbar--BackgroundColor: var(--ak-dark-background-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-pagination.pf-m-bottom {
|
.pf-c-pagination.pf-m-bottom {
|
||||||
background-color: var(--ak-dark-background-light);
|
background-color: var(--ak-dark-background-light);
|
||||||
}
|
}
|
||||||
/* table */
|
|
||||||
|
/* #region Tables */
|
||||||
.pf-c-table {
|
.pf-c-table {
|
||||||
--pf-c-table--BackgroundColor: var(--ak-dark-background-light);
|
--pf-c-table--BackgroundColor: var(--ak-dark-background-light);
|
||||||
--pf-c-table--BorderColor: var(--ak-dark-background-lighter);
|
--pf-c-table--BorderColor: var(--ak-dark-background-lighter);
|
||||||
@ -61,41 +86,58 @@ body {
|
|||||||
--pf-c-table--tr--m-hoverable--hover--BackgroundColor: var(--ak-dark-background-light-ish);
|
--pf-c-table--tr--m-hoverable--hover--BackgroundColor: var(--ak-dark-background-light-ish);
|
||||||
--pf-c-table--tr--m-hoverable--active--BackgroundColor: var(--ak-dark-background-lighter);
|
--pf-c-table--tr--m-hoverable--active--BackgroundColor: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-table__text {
|
.pf-c-table__text {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-table__sort:not(.pf-m-selected) .pf-c-table__button .pf-c-table__text {
|
.pf-c-table__sort:not(.pf-m-selected) .pf-c-table__button .pf-c-table__text {
|
||||||
color: var(--ak-dark-foreground) !important;
|
color: var(--ak-dark-foreground) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-table__sort-indicator i {
|
.pf-c-table__sort-indicator i {
|
||||||
color: var(--ak-dark-foreground) !important;
|
color: var(--ak-dark-foreground) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-table__expandable-row.pf-m-expanded {
|
.pf-c-table__expandable-row.pf-m-expanded {
|
||||||
--pf-c-table__expandable-row--m-expanded--BorderBottomColor: var(--ak-dark-background-lighter);
|
--pf-c-table__expandable-row--m-expanded--BorderBottomColor: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
/* tabs */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Tabs */
|
||||||
|
|
||||||
.pf-c-tabs {
|
.pf-c-tabs {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tabs.pf-m-box.pf-m-vertical .pf-c-tabs__list::before {
|
.pf-c-tabs.pf-m-box.pf-m-vertical .pf-c-tabs__list::before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tabs.pf-m-box .pf-c-tabs__item.pf-m-current:first-child .pf-c-tabs__link::before {
|
.pf-c-tabs.pf-m-box .pf-c-tabs__item.pf-m-current:first-child .pf-c-tabs__link::before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tabs__link::before {
|
.pf-c-tabs__link::before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tabs__item.pf-m-current {
|
.pf-c-tabs__item.pf-m-current {
|
||||||
--pf-c-tabs__link--after--BorderColor: var(--ak-accent);
|
--pf-c-tabs__link--after--BorderColor: var(--ak-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tabs__link {
|
.pf-c-tabs__link {
|
||||||
--pf-c-tabs__link--Color: var(--ak-dark-foreground);
|
--pf-c-tabs__link--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tabs.pf-m-vertical .pf-c-tabs__link {
|
.pf-c-tabs.pf-m-vertical .pf-c-tabs__link {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
/* table, on mobile */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #Region Mobile Tables */
|
||||||
@media screen and (max-width: 1200px) {
|
@media screen and (max-width: 1200px) {
|
||||||
.pf-m-grid-xl.pf-c-table tbody:first-of-type {
|
.pf-m-grid-xl.pf-c-table tbody:first-of-type {
|
||||||
border-top-color: var(--ak-dark-background);
|
border-top-color: var(--ak-dark-background);
|
||||||
@ -104,32 +146,42 @@ body {
|
|||||||
border-bottom-color: var(--ak-dark-background);
|
border-bottom-color: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
/* class for pagination text */
|
/* class for pagination text */
|
||||||
.pf-c-options-menu__toggle {
|
.pf-c-options-menu__toggle {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* table icon used for expanding rows */
|
/* table icon used for expanding rows */
|
||||||
.pf-c-table__toggle-icon {
|
.pf-c-table__toggle-icon {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expandable elements */
|
/* expandable elements */
|
||||||
.pf-c-expandable-section__toggle-text {
|
.pf-c-expandable-section__toggle-text {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-expandable-section__toggle-icon {
|
.pf-c-expandable-section__toggle-icon {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-expandable-section.pf-m-display-lg {
|
.pf-c-expandable-section.pf-m-display-lg {
|
||||||
background-color: var(--ak-dark-background-light-ish);
|
background-color: var(--ak-dark-background-light-ish);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* header for form group */
|
/* header for form group */
|
||||||
.pf-c-form__field-group-header-title-text {
|
.pf-c-form__field-group-header-title-text {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-form__field-group {
|
.pf-c-form__field-group {
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
/* inputs */
|
|
||||||
|
/* #region Inputs */
|
||||||
optgroup,
|
optgroup,
|
||||||
option {
|
option {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
@ -138,9 +190,11 @@ select[multiple] optgroup:checked,
|
|||||||
select[multiple] option:checked {
|
select[multiple] option:checked {
|
||||||
color: var(--ak-dark-background);
|
color: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-input-group {
|
.pf-c-input-group {
|
||||||
--pf-c-input-group--BackgroundColor: transparent;
|
--pf-c-input-group--BackgroundColor: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-form-control {
|
.pf-c-form-control {
|
||||||
--pf-c-form-control--BorderTopColor: transparent !important;
|
--pf-c-form-control--BorderTopColor: transparent !important;
|
||||||
--pf-c-form-control--BorderRightColor: transparent !important;
|
--pf-c-form-control--BorderRightColor: transparent !important;
|
||||||
@ -149,12 +203,15 @@ select[multiple] option:checked {
|
|||||||
--pf-c-form-control--BackgroundColor: var(--ak-dark-background-light);
|
--pf-c-form-control--BackgroundColor: var(--ak-dark-background-light);
|
||||||
--pf-c-form-control--Color: var(--ak-dark-foreground) !important;
|
--pf-c-form-control--Color: var(--ak-dark-foreground) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-form-control:disabled {
|
.pf-c-form-control:disabled {
|
||||||
background-color: var(--ak-dark-background-light);
|
background-color: var(--ak-dark-background-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-form-control[readonly] {
|
.pf-c-form-control[readonly] {
|
||||||
background-color: var(--ak-dark-background-light) !important;
|
background-color: var(--ak-dark-background-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-switch__input:checked ~ .pf-c-switch__label {
|
.pf-c-switch__input:checked ~ .pf-c-switch__label {
|
||||||
--pf-c-switch__input--checked__label--Color: var(--ak-dark-foreground);
|
--pf-c-switch__input--checked__label--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
@ -162,38 +219,47 @@ input[type="datetime-local"]::-webkit-calendar-picker-indicator,
|
|||||||
input[type="date"]::-webkit-calendar-picker-indicator {
|
input[type="date"]::-webkit-calendar-picker-indicator {
|
||||||
filter: invert(1);
|
filter: invert(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* select toggle */
|
/* select toggle */
|
||||||
.pf-c-select__toggle::before {
|
.pf-c-select__toggle::before {
|
||||||
--pf-c-select__toggle--before--BorderTopColor: var(--ak-dark-background-lighter);
|
--pf-c-select__toggle--before--BorderTopColor: var(--ak-dark-background-lighter);
|
||||||
--pf-c-select__toggle--before--BorderRightColor: var(--ak-dark-background-lighter);
|
--pf-c-select__toggle--before--BorderRightColor: var(--ak-dark-background-lighter);
|
||||||
--pf-c-select__toggle--before--BorderLeftColor: var(--ak-dark-background-lighter);
|
--pf-c-select__toggle--before--BorderLeftColor: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-select__toggle.pf-m-typeahead {
|
.pf-c-select__toggle.pf-m-typeahead {
|
||||||
--pf-c-select__toggle--BackgroundColor: var(--ak-dark-background-light);
|
--pf-c-select__toggle--BackgroundColor: var(--ak-dark-background-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-select__menu {
|
.pf-c-select__menu {
|
||||||
--pf-c-select__menu--BackgroundColor: var(--ak-dark-background-light-ish);
|
--pf-c-select__menu--BackgroundColor: var(--ak-dark-background-light-ish);
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-select__menu-item {
|
.pf-c-select__menu-item {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-select__menu-wrapper:hover,
|
.pf-c-select__menu-wrapper:hover,
|
||||||
.pf-c-select__menu-item:hover {
|
.pf-c-select__menu-item:hover {
|
||||||
--pf-c-select__menu-item--hover--BackgroundColor: var(--ak-dark-background-lighter);
|
--pf-c-select__menu-item--hover--BackgroundColor: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-select__menu-wrapper:focus-within,
|
.pf-c-select__menu-wrapper:focus-within,
|
||||||
.pf-c-select__menu-wrapper.pf-m-focus,
|
.pf-c-select__menu-wrapper.pf-m-focus,
|
||||||
.pf-c-select__menu-item:focus,
|
.pf-c-select__menu-item:focus,
|
||||||
.pf-c-select__menu-item.pf-m-focus {
|
.pf-c-select__menu-item.pf-m-focus {
|
||||||
--pf-c-select__menu-item--focus--BackgroundColor: var(--ak-dark-background-light-ish);
|
--pf-c-select__menu-item--focus--BackgroundColor: var(--ak-dark-background-light-ish);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-button:disabled {
|
.pf-c-button:disabled {
|
||||||
color: var(--ak-dark-background-lighter);
|
color: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-button.pf-m-plain:hover {
|
.pf-c-button.pf-m-plain:hover {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-button.pf-m-control {
|
.pf-c-button.pf-m-control {
|
||||||
--pf-c-button--after--BorderColor: var(--ak-dark-background-lighter)
|
--pf-c-button--after--BorderColor: var(--ak-dark-background-lighter)
|
||||||
var(--ak-dark-background-lighter) var(--pf-c-button--m-control--after--BorderBottomColor)
|
var(--ak-dark-background-lighter) var(--pf-c-button--m-control--after--BorderBottomColor)
|
||||||
@ -201,92 +267,127 @@ input[type="date"]::-webkit-calendar-picker-indicator {
|
|||||||
background-color: var(--ak-dark-background-light);
|
background-color: var(--ak-dark-background-light);
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-m-tertiary,
|
.pf-m-tertiary,
|
||||||
.pf-c-button.pf-m-tertiary {
|
.pf-c-button.pf-m-tertiary {
|
||||||
--pf-c-button--after--BorderColor: var(--ak-dark-foreground-darker);
|
--pf-c-button--after--BorderColor: var(--ak-dark-foreground-darker);
|
||||||
color: var(--ak-dark-foreground-darker);
|
color: var(--ak-dark-foreground-darker);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-m-tertiary:hover,
|
.pf-m-tertiary:hover,
|
||||||
.pf-c-button.pf-m-tertiary:hover {
|
.pf-c-button.pf-m-tertiary:hover {
|
||||||
--pf-c-button--after--BorderColor: var(--ak-dark-background-lighter);
|
--pf-c-button--after--BorderColor: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-form__label-text {
|
.pf-c-form__label-text {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-check__label {
|
.pf-c-check__label {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-dropdown__toggle::before {
|
.pf-c-dropdown__toggle::before {
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-dropdown__menu {
|
.pf-c-dropdown__menu {
|
||||||
--pf-c-dropdown__menu--BackgroundColor: var(--ak-dark-background);
|
--pf-c-dropdown__menu--BackgroundColor: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-dropdown__menu-item {
|
.pf-c-dropdown__menu-item {
|
||||||
--pf-c-dropdown__menu-item--BackgroundColor: var(--ak-dark-background);
|
--pf-c-dropdown__menu-item--BackgroundColor: var(--ak-dark-background);
|
||||||
--pf-c-dropdown__menu-item--Color: var(--ak-dark-foreground);
|
--pf-c-dropdown__menu-item--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-dropdown__menu-item:hover,
|
.pf-c-dropdown__menu-item:hover,
|
||||||
.pf-c-dropdown__menu-item:focus {
|
.pf-c-dropdown__menu-item:focus {
|
||||||
--pf-c-dropdown__menu-item--BackgroundColor: var(--ak-dark-background-light-ish);
|
--pf-c-dropdown__menu-item--BackgroundColor: var(--ak-dark-background-light-ish);
|
||||||
--pf-c-dropdown__menu-item--Color: var(--ak-dark-foreground);
|
--pf-c-dropdown__menu-item--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-toggle-group__button {
|
.pf-c-toggle-group__button {
|
||||||
color: var(--ak-dark-foreground) !important;
|
color: var(--ak-dark-foreground) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-toggle-group__button:not(.pf-m-selected) {
|
.pf-c-toggle-group__button:not(.pf-m-selected) {
|
||||||
background-color: var(--ak-dark-background-light) !important;
|
background-color: var(--ak-dark-background-light) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-toggle-group__button.pf-m-selected {
|
.pf-c-toggle-group__button.pf-m-selected {
|
||||||
color: var(--ak-dark-foreground) !important;
|
color: var(--ak-dark-foreground) !important;
|
||||||
background-color: var(--pf-global--primary-color--100) !important;
|
background-color: var(--pf-global--primary-color--100) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inputs help text */
|
/* inputs help text */
|
||||||
.pf-c-form__helper-text:not(.pf-m-error) {
|
.pf-c-form__helper-text:not(.pf-m-error) {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
/* modal */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Modal */
|
||||||
|
|
||||||
.pf-c-modal-box,
|
.pf-c-modal-box,
|
||||||
.pf-c-modal-box__header,
|
.pf-c-modal-box__header,
|
||||||
.pf-c-modal-box__footer,
|
.pf-c-modal-box__footer,
|
||||||
.pf-c-modal-box__body {
|
.pf-c-modal-box__body {
|
||||||
background-color: var(--ak-dark-background);
|
background-color: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
/* sidebar */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Sidebar */
|
||||||
|
|
||||||
.pf-c-nav {
|
.pf-c-nav {
|
||||||
background-color: var(--ak-dark-background-light);
|
background-color: var(--ak-dark-background-light);
|
||||||
}
|
}
|
||||||
/* flows */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Flows */
|
||||||
|
|
||||||
.pf-c-login__main {
|
.pf-c-login__main {
|
||||||
--pf-c-login__main--BackgroundColor: var(--ak-dark-background);
|
--pf-c-login__main--BackgroundColor: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-login__main-body,
|
.pf-c-login__main-body,
|
||||||
.pf-c-login__main-header,
|
.pf-c-login__main-header,
|
||||||
.pf-c-login__main-header-desc {
|
.pf-c-login__main-header-desc {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-login__main-footer-links-item img,
|
.pf-c-login__main-footer-links-item img,
|
||||||
.pf-c-login__main-footer-links-item .fas {
|
.pf-c-login__main-footer-links-item .fas {
|
||||||
filter: invert(1);
|
filter: invert(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-login__main-footer-band {
|
.pf-c-login__main-footer-band {
|
||||||
--pf-c-login__main-footer-band--BackgroundColor: var(--ak-dark-background-lighter);
|
--pf-c-login__main-footer-band--BackgroundColor: var(--ak-dark-background-lighter);
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control-static {
|
.form-control-static {
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
/* notifications */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Notifications */
|
||||||
|
|
||||||
.pf-c-drawer__panel {
|
.pf-c-drawer__panel {
|
||||||
background-color: var(--ak-dark-background);
|
background-color: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-notification-drawer {
|
.pf-c-notification-drawer {
|
||||||
--pf-c-notification-drawer--BackgroundColor: var(--ak-dark-background);
|
--pf-c-notification-drawer--BackgroundColor: var(--ak-dark-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-notification-drawer__header {
|
.pf-c-notification-drawer__header {
|
||||||
background-color: var(--ak-dark-background-lighter);
|
background-color: var(--ak-dark-background-lighter);
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-notification-drawer__list-item {
|
.pf-c-notification-drawer__list-item {
|
||||||
background-color: var(--ak-dark-background-light-ish);
|
background-color: var(--ak-dark-background-light-ish);
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
@ -294,46 +395,84 @@ input[type="date"]::-webkit-calendar-picker-indicator {
|
|||||||
--ak-dark-background-lighter
|
--ak-dark-background-lighter
|
||||||
) !important;
|
) !important;
|
||||||
}
|
}
|
||||||
/* data list */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Data List */
|
||||||
|
|
||||||
.pf-c-data-list {
|
.pf-c-data-list {
|
||||||
padding-inline-start: 0;
|
padding-inline-start: 0;
|
||||||
border-top-color: var(--ak-dark-background-lighter);
|
border-top-color: var(--ak-dark-background-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-data-list__item {
|
.pf-c-data-list__item {
|
||||||
--pf-c-data-list__item--BackgroundColor: transparent;
|
--pf-c-data-list__item--BackgroundColor: transparent;
|
||||||
--pf-c-data-list__item--BorderBottomColor: var(--ak-dark-background-lighter);
|
--pf-c-data-list__item--BorderBottomColor: var(--ak-dark-background-lighter);
|
||||||
color: var(--ak-dark-foreground);
|
color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
/* wizards */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Wizards */
|
||||||
|
|
||||||
.pf-c-wizard__nav {
|
.pf-c-wizard__nav {
|
||||||
--pf-c-wizard__nav--BackgroundColor: var(--ak-dark-background-lighter);
|
--pf-c-wizard__nav--BackgroundColor: var(--ak-dark-background-lighter);
|
||||||
--pf-c-wizard__nav--lg--BorderRightColor: transparent;
|
--pf-c-wizard__nav--lg--BorderRightColor: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-wizard__main {
|
.pf-c-wizard__main {
|
||||||
background-color: var(--ak-dark-background-light-ish);
|
background-color: var(--ak-dark-background-light-ish);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-wizard__footer {
|
.pf-c-wizard__footer {
|
||||||
--pf-c-wizard__footer--BackgroundColor: var(--ak-dark-background-light-ish);
|
--pf-c-wizard__footer--BackgroundColor: var(--ak-dark-background-light-ish);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-wizard__toggle-num,
|
.pf-c-wizard__toggle-num,
|
||||||
.pf-c-wizard__nav-link::before {
|
.pf-c-wizard__nav-link::before {
|
||||||
--pf-c-wizard__nav-link--before--BackgroundColor: transparent;
|
--pf-c-wizard__nav-link--before--BackgroundColor: transparent;
|
||||||
}
|
}
|
||||||
/* tree view */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Tree view */
|
||||||
|
|
||||||
.pf-c-tree-view__node {
|
.pf-c-tree-view__node {
|
||||||
--pf-c-tree-view__node--Color: var(--ak-dark-foreground);
|
--pf-c-tree-view__node--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tree-view__node-toggle {
|
.pf-c-tree-view__node-toggle {
|
||||||
--pf-c-tree-view__node-toggle--Color: var(--ak-dark-foreground);
|
--pf-c-tree-view__node-toggle--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tree-view__node:focus {
|
.pf-c-tree-view__node:focus {
|
||||||
--pf-c-tree-view__node--focus--BackgroundColor: var(--ak-dark-background-light-ish);
|
--pf-c-tree-view__node--focus--BackgroundColor: var(--ak-dark-background-light-ish);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pf-c-tree-view__content:hover,
|
.pf-c-tree-view__content:hover,
|
||||||
.pf-c-tree-view__content:focus-within {
|
.pf-c-tree-view__content:focus-within {
|
||||||
--pf-c-tree-view__node--hover--BackgroundColor: var(--ak-dark-background-light-ish);
|
--pf-c-tree-view__node--hover--BackgroundColor: var(--ak-dark-background-light-ish);
|
||||||
}
|
}
|
||||||
/* stepper */
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Stepper */
|
||||||
.pf-c-progress-stepper__step-title {
|
.pf-c-progress-stepper__step-title {
|
||||||
--pf-c-progress-stepper__step-title--Color: var(--ak-dark-foreground);
|
--pf-c-progress-stepper__step-title--Color: var(--ak-dark-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
|
||||||
|
/* #region Mermaid */
|
||||||
|
|
||||||
|
svg[id^="mermaid-svg-"] {
|
||||||
|
line[class^="messageLine"] {
|
||||||
|
/*
|
||||||
|
Mermaid's support for dynamic palette changes leaves a lot to be desired.
|
||||||
|
This is a workaround to keep content readable while not breaking the rest of the theme.
|
||||||
|
*/
|
||||||
|
filter: invert(1) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion */
|
||||||
|
@ -8,6 +8,7 @@ import { localized } from "@lit/localize";
|
|||||||
import { LitElement, ReactiveElement } from "lit";
|
import { LitElement, ReactiveElement } from "lit";
|
||||||
|
|
||||||
import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
||||||
|
import OneDark from "@goauthentik/common/styles/one-dark.css";
|
||||||
import ThemeDark from "@goauthentik/common/styles/theme-dark.css";
|
import ThemeDark from "@goauthentik/common/styles/theme-dark.css";
|
||||||
|
|
||||||
import { Config, CurrentBrand, UiThemeEnum } from "@goauthentik/api";
|
import { Config, CurrentBrand, UiThemeEnum } from "@goauthentik/api";
|
||||||
@ -70,6 +71,7 @@ export class AKElement extends LitElement {
|
|||||||
styleRoot.adoptedStyleSheets = adaptCSS([
|
styleRoot.adoptedStyleSheets = adaptCSS([
|
||||||
...styleRoot.adoptedStyleSheets,
|
...styleRoot.adoptedStyleSheets,
|
||||||
ensureCSSStyleSheet(AKGlobal),
|
ensureCSSStyleSheet(AKGlobal),
|
||||||
|
ensureCSSStyleSheet(OneDark),
|
||||||
]);
|
]);
|
||||||
this._initTheme(styleRoot);
|
this._initTheme(styleRoot);
|
||||||
this._initCustomCSS(styleRoot);
|
this._initCustomCSS(styleRoot);
|
||||||
|
@ -1,30 +1,19 @@
|
|||||||
import { docLink } from "@goauthentik/common/global";
|
|
||||||
import "@goauthentik/elements/Alert";
|
import "@goauthentik/elements/Alert";
|
||||||
import { Level } from "@goauthentik/elements/Alert";
|
|
||||||
import { AKElement } from "@goauthentik/elements/Base";
|
import { AKElement } from "@goauthentik/elements/Base";
|
||||||
import { matter } from "md-front-matter";
|
|
||||||
import * as showdown from "showdown";
|
|
||||||
|
|
||||||
import { CSSResult, PropertyValues, css, html, nothing } from "lit";
|
import { CSSResult, PropertyValues, css, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
||||||
|
|
||||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||||
import PFList from "@patternfly/patternfly/components/List/list.css";
|
import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||||
|
|
||||||
export interface MarkdownDocument {
|
export type Replacer = (input: string) => string;
|
||||||
path: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Replacer = (input: string, md: MarkdownDocument) => string;
|
|
||||||
|
|
||||||
const isRelativeLink = /href="(\.[^"]*)"/gm;
|
|
||||||
const isFile = /[^/]+\.md/;
|
|
||||||
|
|
||||||
@customElement("ak-markdown")
|
@customElement("ak-markdown")
|
||||||
export class Markdown extends AKElement {
|
export class Markdown extends AKElement {
|
||||||
@property()
|
@property()
|
||||||
md: string = "";
|
content: string = "";
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
meta: string = "";
|
meta: string = "";
|
||||||
@ -32,14 +21,7 @@ export class Markdown extends AKElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
replacers: Replacer[] = [];
|
replacers: Replacer[] = [];
|
||||||
|
|
||||||
docHtml = "";
|
resolvedHTML = "";
|
||||||
docTitle = "";
|
|
||||||
|
|
||||||
defaultReplacers: Replacer[] = [
|
|
||||||
this.replaceAdmonitions,
|
|
||||||
this.replaceList,
|
|
||||||
this.replaceRelativeLinks,
|
|
||||||
];
|
|
||||||
|
|
||||||
static get styles(): CSSResult[] {
|
static get styles(): CSSResult[] {
|
||||||
return [
|
return [
|
||||||
@ -53,55 +35,47 @@ export class Markdown extends AKElement {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
converter = new showdown.Converter({ metadata: true, tables: true });
|
protected firstUpdated(changedProperties: PropertyValues): void {
|
||||||
|
super.updated(changedProperties);
|
||||||
|
|
||||||
replaceAdmonitions(input: string): string {
|
const headingLinks =
|
||||||
const admonitionStart = /:::(\w+)(<br\s*\/>|\s*$)/gm;
|
this.shadowRoot?.querySelectorAll<HTMLAnchorElement>("a.markdown-heading") ?? [];
|
||||||
const admonitionEnd = /:::/gm;
|
|
||||||
return (
|
|
||||||
input
|
|
||||||
.replaceAll(admonitionStart, "<ak-alert level='pf-m-$1'>")
|
|
||||||
.replaceAll(admonitionEnd, "</ak-alert>")
|
|
||||||
// Workaround for admonitions using caution instead of warning
|
|
||||||
.replaceAll("pf-m-caution", Level.Warning)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
replaceList(input: string): string {
|
for (const headingLink of headingLinks) {
|
||||||
return input.replace("<ul>", "<ul class='pf-c-list'>");
|
headingLink.addEventListener("click", (ev) => {
|
||||||
}
|
ev.preventDefault();
|
||||||
|
|
||||||
replaceRelativeLinks(input: string, md: MarkdownDocument): string {
|
const url = new URL(headingLink.href);
|
||||||
const baseName = md.path.replace(isFile, "");
|
const elementID = url.hash.slice(1);
|
||||||
const baseUrl = docLink("");
|
|
||||||
return input.replace(isRelativeLink, (_match, path) => {
|
const target = this.shadowRoot?.getElementById(elementID);
|
||||||
const pathName = path.replace(".md", "");
|
|
||||||
const link = `docs/${baseName}${pathName}`;
|
if (!target) {
|
||||||
const url = new URL(link, baseUrl).toString();
|
console.warn(`Element with ID ${elementID} not found`);
|
||||||
return `href="${url}" _target="blank" rel="noopener noreferrer"`;
|
return;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
target.scrollIntoView({
|
||||||
|
behavior: "smooth",
|
||||||
|
block: "center",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
willUpdate(properties: PropertyValues<this>) {
|
willUpdate(properties: PropertyValues<this>) {
|
||||||
if (properties.has("md") || properties.has("meta")) {
|
if (properties.has("content")) {
|
||||||
const parsedContent = matter(this.md);
|
this.resolvedHTML = this.replacers.reduce(
|
||||||
const parsedHTML = this.converter.makeHtml(parsedContent.content);
|
(html, replacer) => replacer(html),
|
||||||
const replacers = [...this.defaultReplacers, ...this.replacers];
|
this.content,
|
||||||
this.docTitle = parsedContent?.data?.title ?? "";
|
|
||||||
this.docHtml = replacers.reduce(
|
|
||||||
(html, replacer) => replacer(html, { path: this.meta }),
|
|
||||||
parsedHTML,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.md) {
|
if (!this.content) return nothing;
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`${this.docTitle ? html`<h2>${this.docTitle}</h2>` : nothing}
|
return unsafeHTML(this.resolvedHTML);
|
||||||
${unsafeHTML(this.docHtml)}`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
web/src/global.d.ts
vendored
12
web/src/global.d.ts
vendored
@ -1,15 +1,19 @@
|
|||||||
declare module "*.css";
|
declare module "*.css";
|
||||||
|
|
||||||
declare module "*.md" {
|
declare module "*.md" {
|
||||||
|
/**
|
||||||
|
* The HTML content of the markdown file.
|
||||||
|
*/
|
||||||
const html: string;
|
const html: string;
|
||||||
const metadata: { [key: string]: string };
|
export default html;
|
||||||
const filename: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.mdx" {
|
declare module "*.mdx" {
|
||||||
|
/**
|
||||||
|
* The HTML content of the markdown file.
|
||||||
|
*/
|
||||||
const html: string;
|
const html: string;
|
||||||
const metadata: { [key: string]: string };
|
export default html;
|
||||||
const filename: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare namespace Intl {
|
declare namespace Intl {
|
||||||
|
@ -39,7 +39,7 @@ sequenceDiagram
|
|||||||
user->>op: User authentication & authorization occurs
|
user->>op: User authentication & authorization occurs
|
||||||
op->>rp: Redirect back to the RP with an authorization code
|
op->>rp: Redirect back to the RP with an authorization code
|
||||||
|
|
||||||
rect rgb(255, 255, 191)
|
rect
|
||||||
|
|
||||||
rp->>op: Exchange authorization code
|
rp->>op: Exchange authorization code
|
||||||
op->>rp: RP receives Access token (optionally Refresh Token)
|
op->>rp: RP receives Access token (optionally Refresh Token)
|
||||||
@ -138,6 +138,7 @@ By default, every user that has access to an application can request any of the
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
# There are additional fields set in the context, use `ak_logger.debug(request.context)` to see them.
|
# There are additional fields set in the context, use `ak_logger.debug(request.context)` to see them.
|
||||||
|
|
||||||
if "my-admin-scope" in request.context["oauth_scopes"]:
|
if "my-admin-scope" in request.context["oauth_scopes"]:
|
||||||
return ak_is_group_member(request.user, name="my-admin-group")
|
return ak_is_group_member(request.user, name="my-admin-group")
|
||||||
return True
|
return True
|
||||||
|
@ -163,8 +163,10 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.badge--support-community {
|
.badge--support-community {
|
||||||
--ifm-badge-background-color: var(--ifm-color-secondary);
|
--ifm-badge-background-color: var(
|
||||||
--ifm-badge-border-color: var(--ifm-color-secondary-contrast-background);
|
--ifm-color-secondary-contrast-foreground
|
||||||
|
);
|
||||||
|
--ifm-badge-border-color: var(--ifm-color-secondary-dark);
|
||||||
--ifm-badge-color: var(--ifm-color-secondary-contrast-background);
|
--ifm-badge-color: var(--ifm-color-secondary-contrast-background);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,15 +178,14 @@ body {
|
|||||||
|
|
||||||
.badge--support-authentik {
|
.badge--support-authentik {
|
||||||
--ifm-badge-background-color: var(--ifm-color-primary);
|
--ifm-badge-background-color: var(--ifm-color-primary);
|
||||||
--ifm-badge-border-color: var(--ifm-color-primary-contrast-foreground);
|
--ifm-badge-border-color: var(--ifm-color-secondary);
|
||||||
--ifm-badge-color: var(--ifm-color-primary-contrast-foreground);
|
--ifm-badge-color: var(--ifm-color-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge--version {
|
.badge--version {
|
||||||
--ifm-badge-background-color: var(--ifm-color-primary-contrast-background);
|
--ifm-badge-background-color: var(--ifm-color-primary-contrast-background);
|
||||||
--ifm-badge-border-color: var(--ifm-color-primary-contrast-foreground);
|
--ifm-badge-border-color: var(--ifm-color-primary-contrast-foreground);
|
||||||
--ifm-badge-color: var(--ifm-color-primary-contrast-foreground);
|
--ifm-badge-color: var(--ifm-color-primary-contrast-foreground);
|
||||||
cursor: help;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge--preview {
|
.badge--preview {
|
||||||
|
Reference in New Issue
Block a user