Routing for operators, Styling for main page
This commit is contained in:
@@ -2,18 +2,16 @@ import { Suspense } from "react";
|
||||
|
||||
import { Routes, Route, Outlet } from "react-router-dom";
|
||||
import Home from "./pages/Home";
|
||||
import Dynamic from "./pages/Dynamic";
|
||||
import Operators from "./pages/Operators";
|
||||
import NoMatch from "./pages/NoMatch";
|
||||
import NavBar from "./components/NavBar";
|
||||
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import { Container } from "react-bootstrap";
|
||||
|
||||
import { useTranslation, initReactI18next } from "react-i18next";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
import i18next from "i18next";
|
||||
import resourcesToBackend from "i18next-resources-to-backend";
|
||||
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
|
||||
i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((language: string, namespace: string) => import(`../../shared-operations/public/locales/${namespace}/${language}.json`)))
|
||||
.init({
|
||||
@@ -27,8 +25,6 @@ i18next.use(LanguageDetector).use(initReactI18next).use(resourcesToBackend((lang
|
||||
initImmediate: false // Makes loading blocking but sync
|
||||
}); // TODO: use i18next.config.ts instead
|
||||
|
||||
import "./root.css";
|
||||
|
||||
export default function App() {
|
||||
|
||||
return (
|
||||
@@ -39,13 +35,21 @@ export default function App() {
|
||||
<Routes>
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="dynamic" element={<Dynamic />} />
|
||||
|
||||
{/* Using path="*"" means "match anything", so this route
|
||||
acts like a catch-all for URLs that we don't have explicit
|
||||
routes for. */}
|
||||
<Route path="*" element={<NoMatch />} />
|
||||
</Route>
|
||||
|
||||
<Route path="/operators" element={<Layout />}>
|
||||
<Route index element={<NoMatch />} />
|
||||
{listOperatorNames().map((name) => {
|
||||
return <Route key={name} path={name} element={<Operators/>} />;
|
||||
})}
|
||||
<Route path="*" element={<NoMatch />} />
|
||||
</Route>
|
||||
|
||||
<Route path="/convert" element={<Layout />}>
|
||||
{/* <Route path="file-to-pdf" element={<ToPdf />} /> */}
|
||||
<Route path="*" element={<NoMatch />} />
|
||||
@@ -69,9 +73,7 @@ function Layout() {
|
||||
{/* An <Outlet> renders whatever child route is currently active,
|
||||
so you can think about this <Outlet> as a placeholder for
|
||||
the child routes we defined above. */}
|
||||
<Container fluid="sm" className="">
|
||||
<Outlet/>
|
||||
</Container>
|
||||
<Outlet/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import { Container } from "react-bootstrap";
|
||||
import StirlingLogo from "../assets/favicon.svg";
|
||||
import NavBarStyles from "./NavBar.module.css";
|
||||
|
||||
function NavBar() {
|
||||
return (
|
||||
<nav>
|
||||
<Container>
|
||||
<a className={NavBarStyles.navbar_brand} href="/">
|
||||
<img className={NavBarStyles.main_icon} src={StirlingLogo} alt="icon"/>
|
||||
<span className={NavBarStyles.icon_text}>Stirling PDF</span>
|
||||
</a>
|
||||
</Container>
|
||||
<a className={NavBarStyles.navbar_brand} href="/">
|
||||
<img className={NavBarStyles.main_icon} src={StirlingLogo} alt="icon"/>
|
||||
<span className={NavBarStyles.icon_text}>Stirling PDF</span>
|
||||
</a>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
22
client-tauri/src/components/OperatorCard.module.css
Normal file
22
client-tauri/src/components/OperatorCard.module.css
Normal file
@@ -0,0 +1,22 @@
|
||||
.operator_card {
|
||||
border: 1px solid var(--md-sys-color-surface-5);
|
||||
border-radius: 1.75rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: var(--md-sys-color-surface-5);
|
||||
transition: transform 0.3s, border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 0px solid transparent;
|
||||
}
|
||||
|
||||
.operator_card h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.operator_card:hover {
|
||||
cursor: pointer;
|
||||
transform: scale(1.08);
|
||||
box-shadow: var(--md-sys-elevation-2);
|
||||
}
|
||||
33
client-tauri/src/components/OperatorCard.tsx
Normal file
33
client-tauri/src/components/OperatorCard.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { getSchemaByName } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
|
||||
import styles from './OperatorCard.module.css';
|
||||
interface OperatorCardProps {
|
||||
/** The text to display inside the button */
|
||||
operatorInternalName: string;
|
||||
}
|
||||
|
||||
export function OperatorCard({ operatorInternalName }: OperatorCardProps) {
|
||||
const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type
|
||||
|
||||
useEffect(() => {
|
||||
getSchemaByName(operatorInternalName).then(schema => {
|
||||
if(schema) {
|
||||
setSchema(schema.schema);
|
||||
}
|
||||
});
|
||||
}, [operatorInternalName]);
|
||||
|
||||
return (
|
||||
<a key={operatorInternalName} href={"/operators/" + operatorInternalName}>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div className={styles.operator_card}>
|
||||
<h3>{ schema?.describe().flags.label }</h3>
|
||||
{ schema?.describe().flags.description }
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
@@ -10,22 +10,15 @@ interface BuildFieldsProps {
|
||||
|
||||
export function BuildFields({ schemaDescription, onSubmit }: BuildFieldsProps) {
|
||||
console.log("Render Build Fields", schemaDescription);
|
||||
const label = (schemaDescription?.flags as any)?.label
|
||||
const description = (schemaDescription?.flags as any)?.description;
|
||||
const values = (schemaDescription?.keys as any)?.values.keys as { [key: string]: Joi.Description};
|
||||
return (
|
||||
<div>
|
||||
<h3>{label}</h3>
|
||||
{description}
|
||||
<hr />
|
||||
<form onSubmit={(e) => { onSubmit(e); e.preventDefault(); }}>
|
||||
{
|
||||
values ? Object.keys(values).map((key) => {
|
||||
return (<GenericField key={key} fieldName={key} joiDefinition={values[key]} />)
|
||||
}) : undefined
|
||||
}
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
</div>
|
||||
<form onSubmit={(e) => { onSubmit(e); e.preventDefault(); }}>
|
||||
{
|
||||
values ? Object.keys(values).map((key) => {
|
||||
return (<GenericField key={key} fieldName={key} joiDefinition={values[key]} />)
|
||||
}) : undefined
|
||||
}
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
import { Link } from "react-router-dom";
|
||||
import { getOperatorByName, getSchemaByName, listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
|
||||
import styles from './home.module.css';
|
||||
import { listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
import { OperatorCard } from "../components/OperatorCard";
|
||||
|
||||
|
||||
import styles from './Home.module.css';
|
||||
|
||||
function Home() {
|
||||
const operators = listOperatorNames();
|
||||
@@ -20,13 +23,10 @@ function Home() {
|
||||
<div className={styles.operator_container}>
|
||||
{
|
||||
operators.map((operator) => {
|
||||
return (<a key={operator} href={"/operators/" + operator}><div className={styles.operator_card}>{operator}</div></a>)
|
||||
return (<OperatorCard key={operator} operatorInternalName={operator}></OperatorCard>)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
<Link to="/dynamic">Dynamic</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Fragment } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function NoMatch() {
|
||||
return (
|
||||
<div>
|
||||
<Fragment>
|
||||
<h2>The Page you are trying to access does not exist.</h2>
|
||||
<p>
|
||||
<Link to="/">Go back home...</Link>
|
||||
</p>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,53 +1,52 @@
|
||||
import { Link } from "react-router-dom";
|
||||
import { Fragment } from "react";
|
||||
import { Fragment, useEffect } from "react";
|
||||
|
||||
import { BaseSyntheticEvent, useRef, useState } from "react";
|
||||
import { Operator, OperatorSchema } from "@stirling-pdf/shared-operations/src/functions";
|
||||
import Joi from "@stirling-tools/joi";
|
||||
import { BuildFields } from "../components/fields/BuildFields";
|
||||
import { getOperatorByName, getSchemaByName, listOperatorNames } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
import { getOperatorByName, getSchemaByName } from "@stirling-pdf/shared-operations/src/workflow/operatorAccessor";
|
||||
import { PdfFile, RepresentationType } from "@stirling-pdf/shared-operations/src/wrappers/PdfFile";
|
||||
import { Action } from "@stirling-pdf/shared-operations/declarations/Action";
|
||||
|
||||
import { useLocation } from 'react-router-dom'
|
||||
|
||||
|
||||
function Dynamic() {
|
||||
const [schemaDescription, setSchemaDescription] = useState<Joi.Description>();
|
||||
const [schema, setSchema] = useState<any>(undefined); // TODO: Type as joi type
|
||||
|
||||
const operators = listOperatorNames();
|
||||
const location = useLocation();
|
||||
|
||||
const activeOperatorName = useRef<string>();
|
||||
const activeOperator = useRef<typeof Operator>();
|
||||
const activeSchema = useRef<OperatorSchema>();
|
||||
const operatorInternalName = location.pathname.split("/")[2]; // /operators/<operatorInternalName>
|
||||
|
||||
async function selectionChanged(s: BaseSyntheticEvent) {
|
||||
const selectedValue = s.target.value;
|
||||
console.log("Selection changed to", selectedValue);
|
||||
if(selectedValue == "none") {
|
||||
setSchemaDescription(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
getSchemaByName(selectedValue).then(async schema => {
|
||||
useEffect(() => {
|
||||
getSchemaByName(operatorInternalName).then(schema => {
|
||||
if(schema) {
|
||||
const description = schema.schema.describe();
|
||||
activeOperatorName.current = selectedValue;
|
||||
activeOperator.current = await getOperatorByName(selectedValue);
|
||||
activeSchema.current = schema;
|
||||
|
||||
// This will update children
|
||||
setSchemaDescription(description);
|
||||
setSchema(schema.schema);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<h3>{ schema?.describe().flags.label }</h3>
|
||||
{ schema?.describe().flags.description }
|
||||
|
||||
<br />
|
||||
<input type="file" id="pdfFile" accept=".pdf" multiple />
|
||||
<br />
|
||||
|
||||
<div id="values">
|
||||
<BuildFields schemaDescription={schema?.describe()} onSubmit={handleSubmit}></BuildFields>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
async function handleSubmit(e: BaseSyntheticEvent) {
|
||||
console.clear();
|
||||
if(!activeOperatorName.current || !activeOperator.current || !activeSchema.current) {
|
||||
throw new Error("Please select an Operator in the Dropdown");
|
||||
}
|
||||
|
||||
const formData = new FormData(e.target);
|
||||
const values = Object.fromEntries(formData.entries());
|
||||
let action: Action = {type: activeOperatorName.current, values: values};
|
||||
let action: Action = {type: operatorInternalName, values: values};
|
||||
|
||||
// Validate PDF File
|
||||
|
||||
@@ -71,14 +70,16 @@ function Dynamic() {
|
||||
}
|
||||
}
|
||||
|
||||
const validationResults = activeSchema.current.schema.validate({input: inputs, values: action.values});
|
||||
const validationResults = schema.validate({input: inputs, values: action.values});
|
||||
|
||||
if(validationResults.error) {
|
||||
console.error({error: "Validation failed", details: validationResults.error.message}, validationResults.error.stack);
|
||||
}
|
||||
else {
|
||||
action.values = validationResults.value.values;
|
||||
const operation = new activeOperator.current(action);
|
||||
const Operator = (await getOperatorByName(operatorInternalName))!;
|
||||
|
||||
const operation = new Operator(action);
|
||||
operation.run(validationResults.value.input, (progress) => {
|
||||
console.log("OperationProgress: " + progress.operationProgress, "CurFileProgress: " + progress.curFileProgress);
|
||||
}).then(async pdfFiles => {
|
||||
@@ -92,29 +93,6 @@ function Dynamic() {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<h2>Dynamic test page for operators</h2>
|
||||
|
||||
<input type="file" id="pdfFile" accept=".pdf" multiple />
|
||||
<br />
|
||||
<select id="pdfOptions" onChange={selectionChanged}>
|
||||
<option value="none">none</option>
|
||||
{ operators.map((operator) => {
|
||||
return (<option key={operator} value={operator}>{operator}</option>)
|
||||
}) }
|
||||
</select>
|
||||
|
||||
<div id="values">
|
||||
<BuildFields schemaDescription={schemaDescription} onSubmit={handleSubmit}></BuildFields>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<Link to="/">Go back home...</Link>
|
||||
</p>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,4 @@
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 3fr));
|
||||
gap: 30px 30px;
|
||||
}
|
||||
|
||||
.operator_card {
|
||||
border: 1px solid var(--md-sys-color-surface-5);
|
||||
border-radius: 1.75rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: var(--md-sys-color-surface-5);
|
||||
transition: transform 0.3s, border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 0px solid transparent;
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
:root {
|
||||
--md-sys-color-primary: rgb(162 201 255);
|
||||
--md-sys-color-surface-tint: rgb(162 201 255);
|
||||
--md-sys-color-on-primary: rgb(0 49 92);
|
||||
--md-sys-color-primary-container: rgb(0 118 208);
|
||||
--md-sys-color-on-primary-container: rgb(255 255 255);
|
||||
--md-sys-color-secondary: rgb(169 201 246);
|
||||
--md-sys-color-on-secondary: rgb(12 49 87);
|
||||
--md-sys-color-secondary-container: rgb(29 62 100);
|
||||
--md-sys-color-on-secondary-container: rgb(180 210 255);
|
||||
--md-sys-color-tertiary: rgb(193 194 248);
|
||||
--md-sys-color-on-tertiary: rgb(42 44 88);
|
||||
--md-sys-color-tertiary-container: rgb(110 112 161);
|
||||
--md-sys-color-on-tertiary-container: rgb(255 255 255);
|
||||
--md-sys-color-error: rgb(255 180 171);
|
||||
--md-sys-color-on-error: rgb(105 0 5);
|
||||
--md-sys-color-error-container: rgb(147 0 10);
|
||||
--md-sys-color-on-error-container: rgb(255 218 214);
|
||||
--md-sys-color-background: rgb(15 20 26);
|
||||
--md-sys-color-on-background: rgb(223 226 235);
|
||||
--md-sys-color-surface: rgb(15 20 26);
|
||||
--md-sys-color-on-surface: rgb(223 226 235);
|
||||
--md-sys-color-surface-variant: rgb(64 71 83);
|
||||
--md-sys-color-on-surface-variant: rgb(192 199 213);
|
||||
--md-sys-color-outline: rgb(138 145 158);
|
||||
--md-sys-color-outline-variant: rgb(64 71 83);
|
||||
--md-sys-color-primary: rgb(0 96 170);
|
||||
--md-sys-color-surface-tint: rgb(0 96 170);
|
||||
--md-sys-color-on-primary: rgb(255 255 255);
|
||||
--md-sys-color-primary-container: rgb(80 163 255);
|
||||
--md-sys-color-on-primary-container: rgb(0 20 43);
|
||||
--md-sys-color-secondary: rgb(65 96 136);
|
||||
--md-sys-color-on-secondary: rgb(255 255 255);
|
||||
--md-sys-color-secondary-container: rgb(188 215 255);
|
||||
--md-sys-color-on-secondary-container: rgb(32 65 103);
|
||||
--md-sys-color-tertiary: rgb(88 90 138);
|
||||
--md-sys-color-on-tertiary: rgb(255 255 255);
|
||||
--md-sys-color-tertiary-container: rgb(151 153 205);
|
||||
--md-sys-color-on-tertiary-container: rgb(7 9 55);
|
||||
--md-sys-color-error: rgb(186 26 26);
|
||||
--md-sys-color-on-error: rgb(255 255 255);
|
||||
--md-sys-color-error-container: rgb(255 218 214);
|
||||
--md-sys-color-on-error-container: rgb(65 0 2);
|
||||
--md-sys-color-background: rgb(248 249 255);
|
||||
--md-sys-color-on-background: rgb(24 28 34);
|
||||
--md-sys-color-surface: rgb(248 249 255);
|
||||
--md-sys-color-on-surface: rgb(24 28 34);
|
||||
--md-sys-color-surface-variant: rgb(220 227 241);
|
||||
--md-sys-color-on-surface-variant: rgb(64 71 83);
|
||||
--md-sys-color-outline: rgb(112 119 132);
|
||||
--md-sys-color-outline-variant: rgb(192 199 213);
|
||||
--md-sys-color-shadow: rgb(0 0 0);
|
||||
--md-sys-color-scrim: rgb(0 0 0);
|
||||
--md-sys-color-inverse-surface: rgb(223 226 235);
|
||||
--md-sys-color-inverse-on-surface: rgb(45 49 55);
|
||||
--md-sys-color-inverse-primary: rgb(0 96 170);
|
||||
--md-sys-color-inverse-surface: rgb(45 49 55);
|
||||
--md-sys-color-inverse-on-surface: rgb(238 241 250);
|
||||
--md-sys-color-inverse-primary: rgb(162 201 255);
|
||||
--md-sys-color-primary-fixed: rgb(211 228 255);
|
||||
--md-sys-color-on-primary-fixed: rgb(0 28 56);
|
||||
--md-sys-color-primary-fixed-dim: rgb(162 201 255);
|
||||
@@ -41,33 +41,58 @@
|
||||
--md-sys-color-on-tertiary-fixed: rgb(20 22 66);
|
||||
--md-sys-color-tertiary-fixed-dim: rgb(193 194 248);
|
||||
--md-sys-color-on-tertiary-fixed-variant: rgb(64 67 112);
|
||||
--md-sys-color-surface-dim: rgb(15 20 26);
|
||||
--md-sys-color-surface-bright: rgb(53 57 64);
|
||||
--md-sys-color-surface-container-lowest: rgb(10 14 20);
|
||||
--md-sys-color-surface-container-low: rgb(24 28 34);
|
||||
--md-sys-color-surface-container: rgb(28 32 38);
|
||||
--md-sys-color-surface-container-high: rgb(38 42 49);
|
||||
--md-sys-color-surface-container-highest: rgb(49 53 60);
|
||||
--md-sys-color-surface-dim: rgb(215 218 227);
|
||||
--md-sys-color-surface-bright: rgb(248 249 255);
|
||||
--md-sys-color-surface-container-lowest: rgb(255 255 255);
|
||||
--md-sys-color-surface-container-low: rgb(241 243 253);
|
||||
--md-sys-color-surface-container: rgb(235 238 247);
|
||||
--md-sys-color-surface-container-high: rgb(229 232 241);
|
||||
--md-sys-color-surface-container-highest: rgb(223 226 235);
|
||||
--md-nav-section-color-opacity: 1;
|
||||
--md-nav-on-section-color-opacity: 1;
|
||||
--md-nav-section-color-sign: rgba(25, 101, 212, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-sign: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-sign: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-organize: rgba(120, 130, 255, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-organize: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-organize: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-convert: rgba(25, 177, 212, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-convert: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-convert: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-security: rgba(255, 120, 146, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-security: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-security: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-other: rgba(72, 189, 84, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-other: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-other: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-advance: rgba(245, 84, 84, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-advance: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-advance: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-image: rgba(212, 172, 25, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-image: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-image: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-word: rgba(61, 153, 245, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-word: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-word: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-section-color-ppt: rgba(255, 128, 0, var(--md-nav-section-color-opacity));
|
||||
--md-nav-on-section-color-ppt: rgba(28, 27, 31, var(--md-nav-on-section-color-opacity));
|
||||
--md-nav-on-section-color-ppt: rgba(255, 251, 254, var(--md-nav-on-section-color-opacity));
|
||||
|
||||
--bs-blue: #0d6efd;
|
||||
--bs-indigo: #6610f2;
|
||||
--bs-purple: #6f42c1;
|
||||
--bs-pink: #d63384;
|
||||
--bs-red: #dc3545;
|
||||
--bs-orange: #fd7e14;
|
||||
--bs-yellow: #ffc107;
|
||||
--bs-green: #198754;
|
||||
--bs-teal: #20c997;
|
||||
--bs-cyan: #0dcaf0;
|
||||
--bs-white: #fff;
|
||||
--bs-gray: #6c757d;
|
||||
--bs-gray-dark: #343a40;
|
||||
--bs-primary: #0d6efd;
|
||||
--bs-secondary: #6c757d;
|
||||
--bs-success: #198754;
|
||||
--bs-info: #0dcaf0;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #212529;
|
||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
:where(html, .light-theme, .dark-theme), .tokens, :host {
|
||||
@@ -100,8 +125,10 @@ body, select, textarea {
|
||||
background-color: var(--md-sys-color-surface);
|
||||
color: var(--md-sys-color-on-surface);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
margin: 10px auto;
|
||||
padding: 0 20px;
|
||||
font-family: var(--bs-font-sans-serif);
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
@@ -110,4 +137,11 @@ body {
|
||||
background-color: #fff;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
Reference in New Issue
Block a user