mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-20 02:47:34 +03:00
snake_case theme (#2661)
This PR moves the theme / `/styles` typescript app to use snake_case to better align with the rust app and make it easier to reference things across both apps. It also configures ESLint in the styles app and fixes many ESLint errors. Going forward from this PR we will use `snake_case` throughout the theme. Release Notes: - N/A (No public facing changes)
This commit is contained in:
commit
c7c38c7da2
33
styles/.eslintrc.js
Normal file
33
styles/.eslintrc.js
Normal file
@ -0,0 +1,33 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/typescript",
|
||||
],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
},
|
||||
plugins: ["@typescript-eslint", "import"],
|
||||
globals: {
|
||||
module: true,
|
||||
},
|
||||
settings: {
|
||||
"import/parsers": {
|
||||
"@typescript-eslint/parser": [".ts"],
|
||||
},
|
||||
"import/resolver": {
|
||||
typescript: true,
|
||||
node: true,
|
||||
},
|
||||
"import/extensions": [".ts"],
|
||||
},
|
||||
rules: {
|
||||
"linebreak-style": ["error", "unix"],
|
||||
semi: ["error", "never"],
|
||||
},
|
||||
}
|
6
styles/.prettierrc
Normal file
6
styles/.prettierrc
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"semi": false,
|
||||
"printWidth": 80,
|
||||
"htmlWhitespaceSensitivity": "strict",
|
||||
"tabWidth": 4
|
||||
}
|
2682
styles/package-lock.json
generated
2682
styles/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,22 @@
|
||||
{
|
||||
"name": "styles",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"description": "Typescript app that builds Zed's themes",
|
||||
"main": "./src/build_themes.ts",
|
||||
"scripts": {
|
||||
"build": "ts-node ./src/buildThemes.ts",
|
||||
"build-licenses": "ts-node ./src/buildLicenses.ts",
|
||||
"build-tokens": "ts-node ./src/buildTokens.ts",
|
||||
"build-types": "ts-node ./src/buildTypes.ts",
|
||||
"build": "ts-node ./src/build_themes.ts",
|
||||
"build-licenses": "ts-node ./src/build_licenses.ts",
|
||||
"build-tokens": "ts-node ./src/build_tokens.ts",
|
||||
"build-types": "ts-node ./src/build_types.ts",
|
||||
"test": "vitest"
|
||||
},
|
||||
"author": "",
|
||||
"author": "Zed Industries (https://github.com/zed-industries/)",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@tokens-studio/types": "^0.2.3",
|
||||
"@types/chroma-js": "^2.4.0",
|
||||
"@types/node": "^18.14.1",
|
||||
"ayu": "^8.0.1",
|
||||
"bezier-easing": "^2.1.0",
|
||||
"case-anything": "^2.1.10",
|
||||
"chroma-js": "^2.4.2",
|
||||
"deepmerge": "^4.3.0",
|
||||
"json-schema-to-typescript": "^13.0.2",
|
||||
@ -26,15 +24,13 @@
|
||||
"ts-deepmerge": "^6.0.3",
|
||||
"ts-node": "^10.9.1",
|
||||
"utility-types": "^3.10.0",
|
||||
"vitest": "^0.32.0"
|
||||
},
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
"printWidth": 80,
|
||||
"htmlWhitespaceSensitivity": "strict",
|
||||
"tabWidth": 4
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitest/coverage-v8": "^0.32.0"
|
||||
"vitest": "^0.32.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||
"@typescript-eslint/parser": "^5.60.1",
|
||||
"@vitest/coverage-v8": "^0.32.0",
|
||||
"eslint": "^8.43.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.5",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"typescript": "^5.1.5"
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
import * as fs from "fs"
|
||||
import toml from "toml"
|
||||
import { themes } from "./themes"
|
||||
import { ThemeConfig } from "./common"
|
||||
|
||||
const ACCEPTED_LICENSES_FILE = `${__dirname}/../../script/licenses/zed-licenses.toml`
|
||||
|
||||
// Use the cargo-about configuration file as the source of truth for supported licenses.
|
||||
function parseAcceptedToml(file: string): string[] {
|
||||
let buffer = fs.readFileSync(file).toString()
|
||||
|
||||
let obj = toml.parse(buffer)
|
||||
|
||||
if (!Array.isArray(obj.accepted)) {
|
||||
throw Error("Accepted license source is malformed")
|
||||
}
|
||||
|
||||
return obj.accepted
|
||||
}
|
||||
|
||||
function checkLicenses(themes: ThemeConfig[]) {
|
||||
for (const theme of themes) {
|
||||
if (!theme.licenseFile) {
|
||||
throw Error(`Theme ${theme.name} should have a LICENSE file`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateLicenseFile(themes: ThemeConfig[]) {
|
||||
checkLicenses(themes)
|
||||
for (const theme of themes) {
|
||||
const licenseText = fs.readFileSync(theme.licenseFile).toString()
|
||||
writeLicense(theme.name, licenseText, theme.licenseUrl)
|
||||
}
|
||||
}
|
||||
|
||||
function writeLicense(
|
||||
themeName: string,
|
||||
licenseText: string,
|
||||
licenseUrl?: string
|
||||
) {
|
||||
process.stdout.write(
|
||||
licenseUrl
|
||||
? `## [${themeName}](${licenseUrl})\n\n${licenseText}\n********************************************************************************\n\n`
|
||||
: `## ${themeName}\n\n${licenseText}\n********************************************************************************\n\n`
|
||||
)
|
||||
}
|
||||
|
||||
const acceptedLicenses = parseAcceptedToml(ACCEPTED_LICENSES_FILE)
|
||||
generateLicenseFile(themes)
|
@ -1,43 +0,0 @@
|
||||
import * as fs from "fs"
|
||||
import { tmpdir } from "os"
|
||||
import * as path from "path"
|
||||
import app from "./styleTree/app"
|
||||
import { ColorScheme, createColorScheme } from "./theme/colorScheme"
|
||||
import snakeCase from "./utils/snakeCase"
|
||||
import { themes } from "./themes"
|
||||
|
||||
const assetsDirectory = `${__dirname}/../../assets`
|
||||
const tempDirectory = fs.mkdtempSync(path.join(tmpdir(), "build-themes"))
|
||||
|
||||
// Clear existing themes
|
||||
function clearThemes(themeDirectory: string) {
|
||||
if (!fs.existsSync(themeDirectory)) {
|
||||
fs.mkdirSync(themeDirectory, { recursive: true })
|
||||
} else {
|
||||
for (const file of fs.readdirSync(themeDirectory)) {
|
||||
if (file.endsWith(".json")) {
|
||||
fs.unlinkSync(path.join(themeDirectory, file))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function writeThemes(colorSchemes: ColorScheme[], outputDirectory: string) {
|
||||
clearThemes(outputDirectory)
|
||||
for (let colorScheme of colorSchemes) {
|
||||
let styleTree = snakeCase(app(colorScheme))
|
||||
let styleTreeJSON = JSON.stringify(styleTree, null, 2)
|
||||
let tempPath = path.join(tempDirectory, `${colorScheme.name}.json`)
|
||||
let outPath = path.join(outputDirectory, `${colorScheme.name}.json`)
|
||||
fs.writeFileSync(tempPath, styleTreeJSON)
|
||||
fs.renameSync(tempPath, outPath)
|
||||
console.log(`- ${outPath} created`)
|
||||
}
|
||||
}
|
||||
|
||||
const colorSchemes: ColorScheme[] = themes.map((theme) =>
|
||||
createColorScheme(theme)
|
||||
)
|
||||
|
||||
// Write new themes to theme directory
|
||||
writeThemes(colorSchemes, `${assetsDirectory}/themes`)
|
@ -1,87 +0,0 @@
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import { ColorScheme, createColorScheme } from "./common"
|
||||
import { themes } from "./themes"
|
||||
import { slugify } from "./utils/slugify"
|
||||
import { colorSchemeTokens } from "./theme/tokens/colorScheme"
|
||||
|
||||
const TOKENS_DIRECTORY = path.join(__dirname, "..", "target", "tokens")
|
||||
const TOKENS_FILE = path.join(TOKENS_DIRECTORY, "$themes.json")
|
||||
const METADATA_FILE = path.join(TOKENS_DIRECTORY, "$metadata.json")
|
||||
|
||||
function clearTokens(tokensDirectory: string) {
|
||||
if (!fs.existsSync(tokensDirectory)) {
|
||||
fs.mkdirSync(tokensDirectory, { recursive: true })
|
||||
} else {
|
||||
for (const file of fs.readdirSync(tokensDirectory)) {
|
||||
if (file.endsWith(".json")) {
|
||||
fs.unlinkSync(path.join(tokensDirectory, file))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type TokenSet = {
|
||||
id: string
|
||||
name: string
|
||||
selectedTokenSets: { [key: string]: "enabled" }
|
||||
}
|
||||
|
||||
function buildTokenSetOrder(colorSchemes: ColorScheme[]): {
|
||||
tokenSetOrder: string[]
|
||||
} {
|
||||
const tokenSetOrder: string[] = colorSchemes.map((scheme) =>
|
||||
scheme.name.toLowerCase().replace(/\s+/g, "_")
|
||||
)
|
||||
return { tokenSetOrder }
|
||||
}
|
||||
|
||||
function buildThemesIndex(colorSchemes: ColorScheme[]): TokenSet[] {
|
||||
const themesIndex: TokenSet[] = colorSchemes.map((scheme, index) => {
|
||||
const id = `${scheme.isLight ? "light" : "dark"}_${scheme.name
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, "_")}_${index}`
|
||||
const selectedTokenSets: { [key: string]: "enabled" } = {}
|
||||
const tokenSet = scheme.name.toLowerCase().replace(/\s+/g, "_")
|
||||
selectedTokenSets[tokenSet] = "enabled"
|
||||
|
||||
return {
|
||||
id,
|
||||
name: `${scheme.name} - ${scheme.isLight ? "Light" : "Dark"}`,
|
||||
selectedTokenSets,
|
||||
}
|
||||
})
|
||||
|
||||
return themesIndex
|
||||
}
|
||||
|
||||
function writeTokens(colorSchemes: ColorScheme[], tokensDirectory: string) {
|
||||
clearTokens(tokensDirectory)
|
||||
|
||||
for (const colorScheme of colorSchemes) {
|
||||
const fileName = slugify(colorScheme.name) + ".json"
|
||||
const tokens = colorSchemeTokens(colorScheme)
|
||||
const tokensJSON = JSON.stringify(tokens, null, 2)
|
||||
const outPath = path.join(tokensDirectory, fileName)
|
||||
fs.writeFileSync(outPath, tokensJSON, { mode: 0o644 })
|
||||
console.log(`- ${outPath} created`)
|
||||
}
|
||||
|
||||
const themeIndexData = buildThemesIndex(colorSchemes)
|
||||
|
||||
const themesJSON = JSON.stringify(themeIndexData, null, 2)
|
||||
fs.writeFileSync(TOKENS_FILE, themesJSON, { mode: 0o644 })
|
||||
console.log(`- ${TOKENS_FILE} created`)
|
||||
|
||||
const tokenSetOrderData = buildTokenSetOrder(colorSchemes)
|
||||
|
||||
const metadataJSON = JSON.stringify(tokenSetOrderData, null, 2)
|
||||
fs.writeFileSync(METADATA_FILE, metadataJSON, { mode: 0o644 })
|
||||
console.log(`- ${METADATA_FILE} created`)
|
||||
}
|
||||
|
||||
const colorSchemes: ColorScheme[] = themes.map((theme) =>
|
||||
createColorScheme(theme)
|
||||
)
|
||||
|
||||
writeTokens(colorSchemes, TOKENS_DIRECTORY)
|
@ -1,64 +0,0 @@
|
||||
import * as fs from "fs/promises"
|
||||
import * as fsSync from "fs"
|
||||
import * as path from "path"
|
||||
import { compile } from "json-schema-to-typescript"
|
||||
|
||||
const BANNER = `/*
|
||||
* This file is autogenerated
|
||||
*/\n\n`
|
||||
const dirname = __dirname
|
||||
|
||||
async function main() {
|
||||
let schemasPath = path.join(dirname, "../../", "crates/theme/schemas")
|
||||
let schemaFiles = (await fs.readdir(schemasPath)).filter((x) =>
|
||||
x.endsWith(".json")
|
||||
)
|
||||
|
||||
let compiledTypes = new Set()
|
||||
|
||||
for (let filename of schemaFiles) {
|
||||
let filePath = path.join(schemasPath, filename)
|
||||
const fileContents = await fs.readFile(filePath)
|
||||
let schema = JSON.parse(fileContents.toString())
|
||||
let compiled = await compile(schema, schema.title, {
|
||||
bannerComment: "",
|
||||
})
|
||||
let eachType = compiled.split("export")
|
||||
for (let type of eachType) {
|
||||
if (!type) {
|
||||
continue
|
||||
}
|
||||
compiledTypes.add("export " + type.trim())
|
||||
}
|
||||
}
|
||||
|
||||
let output = BANNER + Array.from(compiledTypes).join("\n\n")
|
||||
let outputPath = path.join(dirname, "../../styles/src/types/zed.ts")
|
||||
|
||||
try {
|
||||
let existing = await fs.readFile(outputPath)
|
||||
if (existing.toString() == output) {
|
||||
// Skip writing if it hasn't changed
|
||||
console.log("Schemas are up to date")
|
||||
return
|
||||
}
|
||||
} catch (e) {
|
||||
// It's fine if there's no output from a previous run.
|
||||
// @ts-ignore
|
||||
if (e.code !== "ENOENT") {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const typesDic = path.dirname(outputPath)
|
||||
if (!fsSync.existsSync(typesDic)) {
|
||||
await fs.mkdir(typesDic)
|
||||
}
|
||||
await fs.writeFile(outputPath, output)
|
||||
console.log(`Wrote Typescript types to ${outputPath}`)
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
})
|
50
styles/src/build_licenses.ts
Normal file
50
styles/src/build_licenses.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import * as fs from "fs"
|
||||
import toml from "toml"
|
||||
import { themes } from "./themes"
|
||||
import { ThemeConfig } from "./common"
|
||||
|
||||
const ACCEPTED_LICENSES_FILE = `${__dirname}/../../script/licenses/zed-licenses.toml`
|
||||
|
||||
// Use the cargo-about configuration file as the source of truth for supported licenses.
|
||||
function parse_accepted_toml(file: string): string[] {
|
||||
const buffer = fs.readFileSync(file).toString()
|
||||
|
||||
const obj = toml.parse(buffer)
|
||||
|
||||
if (!Array.isArray(obj.accepted)) {
|
||||
throw Error("Accepted license source is malformed")
|
||||
}
|
||||
|
||||
return obj.accepted
|
||||
}
|
||||
|
||||
function check_licenses(themes: ThemeConfig[]) {
|
||||
for (const theme of themes) {
|
||||
if (!theme.license_file) {
|
||||
throw Error(`Theme ${theme.name} should have a LICENSE file`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generate_license_file(themes: ThemeConfig[]) {
|
||||
check_licenses(themes)
|
||||
for (const theme of themes) {
|
||||
const license_text = fs.readFileSync(theme.license_file).toString()
|
||||
write_license(theme.name, license_text, theme.license_url)
|
||||
}
|
||||
}
|
||||
|
||||
function write_license(
|
||||
theme_name: string,
|
||||
license_text: string,
|
||||
license_url?: string
|
||||
) {
|
||||
process.stdout.write(
|
||||
license_url
|
||||
? `## [${theme_name}](${license_url})\n\n${license_text}\n********************************************************************************\n\n`
|
||||
: `## ${theme_name}\n\n${license_text}\n********************************************************************************\n\n`
|
||||
)
|
||||
}
|
||||
|
||||
const accepted_licenses = parse_accepted_toml(ACCEPTED_LICENSES_FILE)
|
||||
generate_license_file(themes)
|
43
styles/src/build_themes.ts
Normal file
43
styles/src/build_themes.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import * as fs from "fs"
|
||||
import { tmpdir } from "os"
|
||||
import * as path from "path"
|
||||
import app from "./style_tree/app"
|
||||
import { ColorScheme, create_color_scheme } from "./theme/color_scheme"
|
||||
import { themes } from "./themes"
|
||||
|
||||
const assets_directory = `${__dirname}/../../assets`
|
||||
const temp_directory = fs.mkdtempSync(path.join(tmpdir(), "build-themes"))
|
||||
|
||||
function clear_themes(theme_directory: string) {
|
||||
if (!fs.existsSync(theme_directory)) {
|
||||
fs.mkdirSync(theme_directory, { recursive: true })
|
||||
} else {
|
||||
for (const file of fs.readdirSync(theme_directory)) {
|
||||
if (file.endsWith(".json")) {
|
||||
fs.unlinkSync(path.join(theme_directory, file))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function write_themes(themes: ColorScheme[], output_directory: string) {
|
||||
clear_themes(output_directory)
|
||||
for (const color_scheme of themes) {
|
||||
const style_tree = app(color_scheme)
|
||||
const style_tree_json = JSON.stringify(style_tree, null, 2)
|
||||
const temp_path = path.join(temp_directory, `${color_scheme.name}.json`)
|
||||
const out_path = path.join(
|
||||
output_directory,
|
||||
`${color_scheme.name}.json`
|
||||
)
|
||||
fs.writeFileSync(temp_path, style_tree_json)
|
||||
fs.renameSync(temp_path, out_path)
|
||||
console.log(`- ${out_path} created`)
|
||||
}
|
||||
}
|
||||
|
||||
const all_themes: ColorScheme[] = themes.map((theme) =>
|
||||
create_color_scheme(theme)
|
||||
)
|
||||
|
||||
write_themes(all_themes, `${assets_directory}/themes`)
|
87
styles/src/build_tokens.ts
Normal file
87
styles/src/build_tokens.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import { ColorScheme, create_color_scheme } from "./common"
|
||||
import { themes } from "./themes"
|
||||
import { slugify } from "./utils/slugify"
|
||||
import { theme_tokens } from "./theme/tokens/color_scheme"
|
||||
|
||||
const TOKENS_DIRECTORY = path.join(__dirname, "..", "target", "tokens")
|
||||
const TOKENS_FILE = path.join(TOKENS_DIRECTORY, "$themes.json")
|
||||
const METADATA_FILE = path.join(TOKENS_DIRECTORY, "$metadata.json")
|
||||
|
||||
function clear_tokens(tokens_directory: string) {
|
||||
if (!fs.existsSync(tokens_directory)) {
|
||||
fs.mkdirSync(tokens_directory, { recursive: true })
|
||||
} else {
|
||||
for (const file of fs.readdirSync(tokens_directory)) {
|
||||
if (file.endsWith(".json")) {
|
||||
fs.unlinkSync(path.join(tokens_directory, file))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type TokenSet = {
|
||||
id: string
|
||||
name: string
|
||||
selected_token_sets: { [key: string]: "enabled" }
|
||||
}
|
||||
|
||||
function build_token_set_order(theme: ColorScheme[]): {
|
||||
token_set_order: string[]
|
||||
} {
|
||||
const token_set_order: string[] = theme.map((scheme) =>
|
||||
scheme.name.toLowerCase().replace(/\s+/g, "_")
|
||||
)
|
||||
return { token_set_order }
|
||||
}
|
||||
|
||||
function build_themes_index(theme: ColorScheme[]): TokenSet[] {
|
||||
const themes_index: TokenSet[] = theme.map((scheme, index) => {
|
||||
const id = `${scheme.is_light ? "light" : "dark"}_${scheme.name
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, "_")}_${index}`
|
||||
const selected_token_sets: { [key: string]: "enabled" } = {}
|
||||
const token_set = scheme.name.toLowerCase().replace(/\s+/g, "_")
|
||||
selected_token_sets[token_set] = "enabled"
|
||||
|
||||
return {
|
||||
id,
|
||||
name: `${scheme.name} - ${scheme.is_light ? "Light" : "Dark"}`,
|
||||
selected_token_sets,
|
||||
}
|
||||
})
|
||||
|
||||
return themes_index
|
||||
}
|
||||
|
||||
function write_tokens(themes: ColorScheme[], tokens_directory: string) {
|
||||
clear_tokens(tokens_directory)
|
||||
|
||||
for (const theme of themes) {
|
||||
const file_name = slugify(theme.name) + ".json"
|
||||
const tokens = theme_tokens(theme)
|
||||
const tokens_json = JSON.stringify(tokens, null, 2)
|
||||
const out_path = path.join(tokens_directory, file_name)
|
||||
fs.writeFileSync(out_path, tokens_json, { mode: 0o644 })
|
||||
console.log(`- ${out_path} created`)
|
||||
}
|
||||
|
||||
const theme_index_data = build_themes_index(themes)
|
||||
|
||||
const themes_json = JSON.stringify(theme_index_data, null, 2)
|
||||
fs.writeFileSync(TOKENS_FILE, themes_json, { mode: 0o644 })
|
||||
console.log(`- ${TOKENS_FILE} created`)
|
||||
|
||||
const token_set_order_data = build_token_set_order(themes)
|
||||
|
||||
const metadata_json = JSON.stringify(token_set_order_data, null, 2)
|
||||
fs.writeFileSync(METADATA_FILE, metadata_json, { mode: 0o644 })
|
||||
console.log(`- ${METADATA_FILE} created`)
|
||||
}
|
||||
|
||||
const all_themes: ColorScheme[] = themes.map((theme) =>
|
||||
create_color_scheme(theme)
|
||||
)
|
||||
|
||||
write_tokens(all_themes, TOKENS_DIRECTORY)
|
62
styles/src/build_types.ts
Normal file
62
styles/src/build_types.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import * as fs from "fs/promises"
|
||||
import * as fsSync from "fs"
|
||||
import * as path from "path"
|
||||
import { compile } from "json-schema-to-typescript"
|
||||
|
||||
const BANNER = `/*
|
||||
* This file is autogenerated
|
||||
*/\n\n`
|
||||
const dirname = __dirname
|
||||
|
||||
async function main() {
|
||||
const schemas_path = path.join(dirname, "../../", "crates/theme/schemas")
|
||||
const schema_files = (await fs.readdir(schemas_path)).filter((x) =>
|
||||
x.endsWith(".json")
|
||||
)
|
||||
|
||||
const compiled_types = new Set()
|
||||
|
||||
for (const filename of schema_files) {
|
||||
const file_path = path.join(schemas_path, filename)
|
||||
const file_contents = await fs.readFile(file_path)
|
||||
const schema = JSON.parse(file_contents.toString())
|
||||
const compiled = await compile(schema, schema.title, {
|
||||
bannerComment: "",
|
||||
})
|
||||
const each_type = compiled.split("export")
|
||||
for (const type of each_type) {
|
||||
if (!type) {
|
||||
continue
|
||||
}
|
||||
compiled_types.add("export " + type.trim())
|
||||
}
|
||||
}
|
||||
|
||||
const output = BANNER + Array.from(compiled_types).join("\n\n")
|
||||
const output_path = path.join(dirname, "../../styles/src/types/zed.ts")
|
||||
|
||||
try {
|
||||
const existing = await fs.readFile(output_path)
|
||||
if (existing.toString() == output) {
|
||||
// Skip writing if it hasn't changed
|
||||
console.log("Schemas are up to date")
|
||||
return
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.code !== "ENOENT") {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const types_dic = path.dirname(output_path)
|
||||
if (!fsSync.existsSync(types_dic)) {
|
||||
await fs.mkdir(types_dic)
|
||||
}
|
||||
await fs.writeFile(output_path, output)
|
||||
console.log(`Wrote Typescript types to ${output_path}`)
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error(e)
|
||||
process.exit(1)
|
||||
})
|
@ -2,42 +2,24 @@ import chroma from "chroma-js"
|
||||
export * from "./theme"
|
||||
export { chroma }
|
||||
|
||||
export const fontFamilies = {
|
||||
export const font_families = {
|
||||
sans: "Zed Sans",
|
||||
mono: "Zed Mono",
|
||||
}
|
||||
|
||||
export const fontSizes = {
|
||||
"3xs": 8,
|
||||
export const font_sizes = {
|
||||
"2xs": 10,
|
||||
xs: 12,
|
||||
sm: 14,
|
||||
md: 16,
|
||||
lg: 18,
|
||||
xl: 20,
|
||||
}
|
||||
|
||||
export type FontWeight =
|
||||
| "thin"
|
||||
| "extra_light"
|
||||
| "light"
|
||||
| "normal"
|
||||
| "medium"
|
||||
| "semibold"
|
||||
| "bold"
|
||||
| "extra_bold"
|
||||
| "black"
|
||||
export type FontWeight = "normal" | "bold"
|
||||
|
||||
export const fontWeights: { [key: string]: FontWeight } = {
|
||||
thin: "thin",
|
||||
extra_light: "extra_light",
|
||||
light: "light",
|
||||
export const font_weights: { [key: string]: FontWeight } = {
|
||||
normal: "normal",
|
||||
medium: "medium",
|
||||
semibold: "semibold",
|
||||
bold: "bold",
|
||||
extra_bold: "extra_bold",
|
||||
black: "black",
|
||||
}
|
||||
|
||||
export const sizes = {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ColorScheme } from "../common"
|
||||
import { interactive, toggleable } from "../element"
|
||||
import { background, foreground } from "../styleTree/components"
|
||||
import { background, foreground } from "../style_tree/components"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
|
||||
export type Margin = {
|
||||
top: number
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { ColorScheme } from "../common"
|
||||
import { interactive, toggleable } from "../element"
|
||||
import {
|
||||
TextProperties,
|
||||
background,
|
||||
foreground,
|
||||
text,
|
||||
} from "../styleTree/components"
|
||||
} from "../style_tree/components"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { Margin } from "./icon_button"
|
||||
|
||||
interface TextButtonOptions {
|
||||
|
@ -8,7 +8,7 @@ import { describe, it, expect } from "vitest"
|
||||
describe("interactive", () => {
|
||||
it("creates an Interactive<Element> with base properties and states", () => {
|
||||
const result = interactive({
|
||||
base: { fontSize: 10, color: "#FFFFFF" },
|
||||
base: { font_size: 10, color: "#FFFFFF" },
|
||||
state: {
|
||||
hovered: { color: "#EEEEEE" },
|
||||
clicked: { color: "#CCCCCC" },
|
||||
@ -16,25 +16,25 @@ describe("interactive", () => {
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
default: { color: "#FFFFFF", fontSize: 10 },
|
||||
hovered: { color: "#EEEEEE", fontSize: 10 },
|
||||
clicked: { color: "#CCCCCC", fontSize: 10 },
|
||||
default: { color: "#FFFFFF", font_size: 10 },
|
||||
hovered: { color: "#EEEEEE", font_size: 10 },
|
||||
clicked: { color: "#CCCCCC", font_size: 10 },
|
||||
})
|
||||
})
|
||||
|
||||
it("creates an Interactive<Element> with no base properties", () => {
|
||||
const result = interactive({
|
||||
state: {
|
||||
default: { color: "#FFFFFF", fontSize: 10 },
|
||||
default: { color: "#FFFFFF", font_size: 10 },
|
||||
hovered: { color: "#EEEEEE" },
|
||||
clicked: { color: "#CCCCCC" },
|
||||
},
|
||||
})
|
||||
|
||||
expect(result).toEqual({
|
||||
default: { color: "#FFFFFF", fontSize: 10 },
|
||||
hovered: { color: "#EEEEEE", fontSize: 10 },
|
||||
clicked: { color: "#CCCCCC", fontSize: 10 },
|
||||
default: { color: "#FFFFFF", font_size: 10 },
|
||||
hovered: { color: "#EEEEEE", font_size: 10 },
|
||||
clicked: { color: "#CCCCCC", font_size: 10 },
|
||||
})
|
||||
})
|
||||
|
||||
@ -48,7 +48,7 @@ describe("interactive", () => {
|
||||
|
||||
it("throws error when no other state besides default is present", () => {
|
||||
const state = {
|
||||
default: { fontSize: 10 },
|
||||
default: { font_size: 10 },
|
||||
}
|
||||
|
||||
expect(() => interactive({ state })).toThrow(NOT_ENOUGH_STATES_ERROR)
|
||||
|
@ -37,61 +37,61 @@ interface InteractiveProps<T> {
|
||||
* @param state Object containing optional modified fields to be included in the resulting object for each state.
|
||||
* @returns Interactive<T> object with fields from `base` and `state`.
|
||||
*/
|
||||
export function interactive<T extends Object>({
|
||||
export function interactive<T extends object>({
|
||||
base,
|
||||
state,
|
||||
}: InteractiveProps<T>): Interactive<T> {
|
||||
if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR)
|
||||
|
||||
let defaultState: T
|
||||
let default_state: T
|
||||
|
||||
if (state.default && base) {
|
||||
defaultState = merge(base, state.default) as T
|
||||
default_state = merge(base, state.default) as T
|
||||
} else {
|
||||
defaultState = base ? base : (state.default as T)
|
||||
default_state = base ? base : (state.default as T)
|
||||
}
|
||||
|
||||
let interactiveObj: Interactive<T> = {
|
||||
default: defaultState,
|
||||
const interactive_obj: Interactive<T> = {
|
||||
default: default_state,
|
||||
}
|
||||
|
||||
let stateCount = 0
|
||||
let state_count = 0
|
||||
|
||||
if (state.hovered !== undefined) {
|
||||
interactiveObj.hovered = merge(
|
||||
interactiveObj.default,
|
||||
interactive_obj.hovered = merge(
|
||||
interactive_obj.default,
|
||||
state.hovered
|
||||
) as T
|
||||
stateCount++
|
||||
state_count++
|
||||
}
|
||||
|
||||
if (state.clicked !== undefined) {
|
||||
interactiveObj.clicked = merge(
|
||||
interactiveObj.default,
|
||||
interactive_obj.clicked = merge(
|
||||
interactive_obj.default,
|
||||
state.clicked
|
||||
) as T
|
||||
stateCount++
|
||||
state_count++
|
||||
}
|
||||
|
||||
if (state.selected !== undefined) {
|
||||
interactiveObj.selected = merge(
|
||||
interactiveObj.default,
|
||||
interactive_obj.selected = merge(
|
||||
interactive_obj.default,
|
||||
state.selected
|
||||
) as T
|
||||
stateCount++
|
||||
state_count++
|
||||
}
|
||||
|
||||
if (state.disabled !== undefined) {
|
||||
interactiveObj.disabled = merge(
|
||||
interactiveObj.default,
|
||||
interactive_obj.disabled = merge(
|
||||
interactive_obj.default,
|
||||
state.disabled
|
||||
) as T
|
||||
stateCount++
|
||||
state_count++
|
||||
}
|
||||
|
||||
if (stateCount < 1) {
|
||||
if (state_count < 1) {
|
||||
throw new Error(NOT_ENOUGH_STATES_ERROR)
|
||||
}
|
||||
|
||||
return interactiveObj
|
||||
return interactive_obj
|
||||
}
|
||||
|
@ -35,13 +35,13 @@ export function toggleable<T extends object>(
|
||||
if (!base && !state.inactive) throw new Error(NO_INACTIVE_OR_BASE_ERROR)
|
||||
if (!state.active) throw new Error(NO_ACTIVE_ERROR)
|
||||
|
||||
const inactiveState = base
|
||||
const inactive_state = base
|
||||
? ((state.inactive ? merge(base, state.inactive) : base) as T)
|
||||
: (state.inactive as T)
|
||||
|
||||
const toggleObj: Toggleable<T> = {
|
||||
inactive: inactiveState,
|
||||
const toggle_obj: Toggleable<T> = {
|
||||
inactive: inactive_state,
|
||||
active: merge(base ?? {}, state.active) as T,
|
||||
}
|
||||
return toggleObj
|
||||
return toggle_obj
|
||||
}
|
||||
|
@ -1,75 +0,0 @@
|
||||
import contactFinder from "./contactFinder"
|
||||
import contactsPopover from "./contactsPopover"
|
||||
import commandPalette from "./commandPalette"
|
||||
import editor from "./editor"
|
||||
import projectPanel from "./projectPanel"
|
||||
import search from "./search"
|
||||
import picker from "./picker"
|
||||
import workspace from "./workspace"
|
||||
import contextMenu from "./contextMenu"
|
||||
import sharedScreen from "./sharedScreen"
|
||||
import projectDiagnostics from "./projectDiagnostics"
|
||||
import contactNotification from "./contactNotification"
|
||||
import updateNotification from "./updateNotification"
|
||||
import simpleMessageNotification from "./simpleMessageNotification"
|
||||
import projectSharedNotification from "./projectSharedNotification"
|
||||
import tooltip from "./tooltip"
|
||||
import terminal from "./terminal"
|
||||
import contactList from "./contactList"
|
||||
import toolbarDropdownMenu from "./toolbarDropdownMenu"
|
||||
import incomingCallNotification from "./incomingCallNotification"
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import feedback from "./feedback"
|
||||
import welcome from "./welcome"
|
||||
import copilot from "./copilot"
|
||||
import assistant from "./assistant"
|
||||
import { titlebar } from "./titlebar"
|
||||
|
||||
export default function app(colorScheme: ColorScheme): Object {
|
||||
return {
|
||||
meta: {
|
||||
name: colorScheme.name,
|
||||
isLight: colorScheme.isLight,
|
||||
},
|
||||
commandPalette: commandPalette(colorScheme),
|
||||
contactNotification: contactNotification(colorScheme),
|
||||
projectSharedNotification: projectSharedNotification(colorScheme),
|
||||
incomingCallNotification: incomingCallNotification(colorScheme),
|
||||
picker: picker(colorScheme),
|
||||
workspace: workspace(colorScheme),
|
||||
titlebar: titlebar(colorScheme),
|
||||
copilot: copilot(colorScheme),
|
||||
welcome: welcome(colorScheme),
|
||||
contextMenu: contextMenu(colorScheme),
|
||||
editor: editor(colorScheme),
|
||||
projectDiagnostics: projectDiagnostics(colorScheme),
|
||||
projectPanel: projectPanel(colorScheme),
|
||||
contactsPopover: contactsPopover(colorScheme),
|
||||
contactFinder: contactFinder(colorScheme),
|
||||
contactList: contactList(colorScheme),
|
||||
toolbarDropdownMenu: toolbarDropdownMenu(colorScheme),
|
||||
search: search(colorScheme),
|
||||
sharedScreen: sharedScreen(colorScheme),
|
||||
updateNotification: updateNotification(colorScheme),
|
||||
simpleMessageNotification: simpleMessageNotification(colorScheme),
|
||||
tooltip: tooltip(colorScheme),
|
||||
terminal: terminal(colorScheme),
|
||||
assistant: assistant(colorScheme),
|
||||
feedback: feedback(colorScheme),
|
||||
colorScheme: {
|
||||
...colorScheme,
|
||||
players: Object.values(colorScheme.players),
|
||||
ramps: {
|
||||
neutral: colorScheme.ramps.neutral.colors(100, "hex"),
|
||||
red: colorScheme.ramps.red.colors(100, "hex"),
|
||||
orange: colorScheme.ramps.orange.colors(100, "hex"),
|
||||
yellow: colorScheme.ramps.yellow.colors(100, "hex"),
|
||||
green: colorScheme.ramps.green.colors(100, "hex"),
|
||||
cyan: colorScheme.ramps.cyan.colors(100, "hex"),
|
||||
blue: colorScheme.ramps.blue.colors(100, "hex"),
|
||||
violet: colorScheme.ramps.violet.colors(100, "hex"),
|
||||
magenta: colorScheme.ramps.magenta.colors(100, "hex"),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
import picker from "./picker"
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
|
||||
export default function contactFinder(colorScheme: ColorScheme): any {
|
||||
let layer = colorScheme.middle
|
||||
|
||||
const sideMargin = 6
|
||||
const contactButton = {
|
||||
background: background(layer, "variant"),
|
||||
color: foreground(layer, "variant"),
|
||||
iconWidth: 8,
|
||||
buttonWidth: 16,
|
||||
cornerRadius: 8,
|
||||
}
|
||||
|
||||
const pickerStyle = picker(colorScheme)
|
||||
const pickerInput = {
|
||||
background: background(layer, "on"),
|
||||
cornerRadius: 6,
|
||||
text: text(layer, "mono"),
|
||||
placeholderText: text(layer, "mono", "on", "disabled", { size: "xs" }),
|
||||
selection: colorScheme.players[0],
|
||||
border: border(layer),
|
||||
padding: {
|
||||
bottom: 4,
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 4,
|
||||
},
|
||||
margin: {
|
||||
left: sideMargin,
|
||||
right: sideMargin,
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
picker: {
|
||||
emptyContainer: {},
|
||||
item: {
|
||||
...pickerStyle.item,
|
||||
margin: { left: sideMargin, right: sideMargin },
|
||||
},
|
||||
noMatches: pickerStyle.noMatches,
|
||||
inputEditor: pickerInput,
|
||||
emptyInputEditor: pickerInput,
|
||||
},
|
||||
rowHeight: 28,
|
||||
contactAvatar: {
|
||||
cornerRadius: 10,
|
||||
width: 18,
|
||||
},
|
||||
contactUsername: {
|
||||
padding: {
|
||||
left: 8,
|
||||
},
|
||||
},
|
||||
contactButton: {
|
||||
...contactButton,
|
||||
hover: {
|
||||
background: background(layer, "variant", "hovered"),
|
||||
},
|
||||
},
|
||||
disabledContactButton: {
|
||||
...contactButton,
|
||||
background: background(layer, "disabled"),
|
||||
color: foreground(layer, "disabled"),
|
||||
},
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, foreground, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
const avatarSize = 12
|
||||
const headerPadding = 8
|
||||
|
||||
export default function contactNotification(colorScheme: ColorScheme): Object {
|
||||
let layer = colorScheme.lowest
|
||||
return {
|
||||
headerAvatar: {
|
||||
height: avatarSize,
|
||||
width: avatarSize,
|
||||
cornerRadius: 6,
|
||||
},
|
||||
headerMessage: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
margin: { left: headerPadding, right: headerPadding },
|
||||
},
|
||||
headerHeight: 18,
|
||||
bodyMessage: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 },
|
||||
},
|
||||
button: interactive({
|
||||
base: {
|
||||
...text(layer, "sans", "on", { size: "xs" }),
|
||||
background: background(layer, "on"),
|
||||
padding: 4,
|
||||
cornerRadius: 6,
|
||||
margin: { left: 6 },
|
||||
},
|
||||
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
dismissButton: {
|
||||
default: {
|
||||
color: foreground(layer, "variant"),
|
||||
iconWidth: 8,
|
||||
iconHeight: 8,
|
||||
buttonWidth: 8,
|
||||
buttonHeight: 8,
|
||||
hover: {
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
|
||||
export default function contactsPopover(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
const sidePadding = 12
|
||||
return {
|
||||
background: background(layer),
|
||||
cornerRadius: 6,
|
||||
padding: { top: 6, bottom: 6 },
|
||||
shadow: colorScheme.popoverShadow,
|
||||
border: border(layer),
|
||||
width: 300,
|
||||
height: 400,
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, borderColor, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function contextMenu(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
return {
|
||||
background: background(layer),
|
||||
cornerRadius: 10,
|
||||
padding: 4,
|
||||
shadow: colorScheme.popoverShadow,
|
||||
border: border(layer),
|
||||
keystrokeMargin: 30,
|
||||
item: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
iconSpacing: 8,
|
||||
iconWidth: 14,
|
||||
padding: { left: 6, right: 6, top: 2, bottom: 2 },
|
||||
cornerRadius: 6,
|
||||
label: text(layer, "sans", { size: "sm" }),
|
||||
keystroke: {
|
||||
...text(layer, "sans", "variant", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
padding: { left: 3, right: 3 },
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "hovered"),
|
||||
label: text(layer, "sans", "hovered", { size: "sm" }),
|
||||
keystroke: {
|
||||
...text(layer, "sans", "hovered", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
padding: { left: 3, right: 3 },
|
||||
},
|
||||
},
|
||||
clicked: {
|
||||
background: background(layer, "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
background: background(layer, "active"),
|
||||
},
|
||||
hovered: {
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
background: background(layer, "pressed"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
separator: {
|
||||
background: borderColor(layer),
|
||||
margin: { top: 2, bottom: 2 },
|
||||
},
|
||||
}
|
||||
}
|
@ -1,314 +0,0 @@
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { ColorScheme, Layer, StyleSets } from "../theme/colorScheme"
|
||||
import { background, border, borderColor, foreground, text } from "./components"
|
||||
import hoverPopover from "./hoverPopover"
|
||||
|
||||
import { buildSyntax } from "../theme/syntax"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function editor(colorScheme: ColorScheme) {
|
||||
const { isLight } = colorScheme
|
||||
|
||||
let layer = colorScheme.highest
|
||||
|
||||
const autocompleteItem = {
|
||||
cornerRadius: 6,
|
||||
padding: {
|
||||
bottom: 2,
|
||||
left: 6,
|
||||
right: 6,
|
||||
top: 2,
|
||||
},
|
||||
}
|
||||
|
||||
function diagnostic(layer: Layer, styleSet: StyleSets) {
|
||||
return {
|
||||
textScaleFactor: 0.857,
|
||||
header: {
|
||||
border: border(layer, {
|
||||
top: true,
|
||||
}),
|
||||
},
|
||||
message: {
|
||||
text: text(layer, "sans", styleSet, "default", { size: "sm" }),
|
||||
highlightText: text(layer, "sans", styleSet, "default", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(colorScheme)
|
||||
|
||||
return {
|
||||
textColor: syntax.primary.color,
|
||||
background: background(layer),
|
||||
activeLineBackground: withOpacity(background(layer, "on"), 0.75),
|
||||
highlightedLineBackground: background(layer, "on"),
|
||||
// Inline autocomplete suggestions, Co-pilot suggestions, etc.
|
||||
suggestion: syntax.predictive,
|
||||
codeActions: {
|
||||
indicator: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "variant"),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "variant", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(layer, "variant", "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
color: foreground(layer, "accent"),
|
||||
},
|
||||
hovered: {
|
||||
color: foreground(layer, "accent", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(layer, "accent", "pressed"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
verticalScale: 0.55,
|
||||
},
|
||||
folds: {
|
||||
iconMarginScale: 2.5,
|
||||
foldedIcon: "icons/chevron_right_8.svg",
|
||||
foldableIcon: "icons/chevron_down_8.svg",
|
||||
indicator: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "variant"),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "on"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(layer, "base"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
color: foreground(layer, "default"),
|
||||
},
|
||||
hovered: {
|
||||
color: foreground(layer, "variant"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
ellipses: {
|
||||
textColor: colorScheme.ramps.neutral(0.71).hex(),
|
||||
cornerRadiusFactor: 0.15,
|
||||
background: {
|
||||
// Copied from hover_popover highlight
|
||||
default: {
|
||||
color: colorScheme.ramps.neutral(0.5).alpha(0.0).hex(),
|
||||
},
|
||||
|
||||
hovered: {
|
||||
color: colorScheme.ramps.neutral(0.5).alpha(0.5).hex(),
|
||||
},
|
||||
|
||||
clicked: {
|
||||
color: colorScheme.ramps.neutral(0.5).alpha(0.7).hex(),
|
||||
},
|
||||
},
|
||||
},
|
||||
foldBackground: foreground(layer, "variant"),
|
||||
},
|
||||
diff: {
|
||||
deleted: isLight
|
||||
? colorScheme.ramps.red(0.5).hex()
|
||||
: colorScheme.ramps.red(0.4).hex(),
|
||||
modified: isLight
|
||||
? colorScheme.ramps.yellow(0.5).hex()
|
||||
: colorScheme.ramps.yellow(0.5).hex(),
|
||||
inserted: isLight
|
||||
? colorScheme.ramps.green(0.4).hex()
|
||||
: colorScheme.ramps.green(0.5).hex(),
|
||||
removedWidthEm: 0.275,
|
||||
widthEm: 0.15,
|
||||
cornerRadius: 0.05,
|
||||
},
|
||||
/** Highlights matching occurrences of what is under the cursor
|
||||
* as well as matched brackets
|
||||
*/
|
||||
documentHighlightReadBackground: withOpacity(
|
||||
foreground(layer, "accent"),
|
||||
0.1
|
||||
),
|
||||
documentHighlightWriteBackground: colorScheme.ramps
|
||||
.neutral(0.5)
|
||||
.alpha(0.4)
|
||||
.hex(), // TODO: This was blend * 2
|
||||
errorColor: background(layer, "negative"),
|
||||
gutterBackground: background(layer),
|
||||
gutterPaddingFactor: 3.5,
|
||||
lineNumber: withOpacity(foreground(layer), 0.35),
|
||||
lineNumberActive: foreground(layer),
|
||||
renameFade: 0.6,
|
||||
unnecessaryCodeFade: 0.5,
|
||||
selection: colorScheme.players[0],
|
||||
whitespace: colorScheme.ramps.neutral(0.5).hex(),
|
||||
guestSelections: [
|
||||
colorScheme.players[1],
|
||||
colorScheme.players[2],
|
||||
colorScheme.players[3],
|
||||
colorScheme.players[4],
|
||||
colorScheme.players[5],
|
||||
colorScheme.players[6],
|
||||
colorScheme.players[7],
|
||||
],
|
||||
autocomplete: {
|
||||
background: background(colorScheme.middle),
|
||||
cornerRadius: 8,
|
||||
padding: 4,
|
||||
margin: {
|
||||
left: -14,
|
||||
},
|
||||
border: border(colorScheme.middle),
|
||||
shadow: colorScheme.popoverShadow,
|
||||
matchHighlight: foreground(colorScheme.middle, "accent"),
|
||||
item: autocompleteItem,
|
||||
hoveredItem: {
|
||||
...autocompleteItem,
|
||||
matchHighlight: foreground(
|
||||
colorScheme.middle,
|
||||
"accent",
|
||||
"hovered"
|
||||
),
|
||||
background: background(colorScheme.middle, "hovered"),
|
||||
},
|
||||
selectedItem: {
|
||||
...autocompleteItem,
|
||||
matchHighlight: foreground(
|
||||
colorScheme.middle,
|
||||
"accent",
|
||||
"active"
|
||||
),
|
||||
background: background(colorScheme.middle, "active"),
|
||||
},
|
||||
},
|
||||
diagnosticHeader: {
|
||||
background: background(colorScheme.middle),
|
||||
iconWidthFactor: 1.5,
|
||||
textScaleFactor: 0.857,
|
||||
border: border(colorScheme.middle, {
|
||||
bottom: true,
|
||||
top: true,
|
||||
}),
|
||||
code: {
|
||||
...text(colorScheme.middle, "mono", { size: "sm" }),
|
||||
margin: {
|
||||
left: 10,
|
||||
},
|
||||
},
|
||||
source: {
|
||||
text: text(colorScheme.middle, "sans", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
message: {
|
||||
highlightText: text(colorScheme.middle, "sans", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
text: text(colorScheme.middle, "sans", { size: "sm" }),
|
||||
},
|
||||
},
|
||||
diagnosticPathHeader: {
|
||||
background: background(colorScheme.middle),
|
||||
textScaleFactor: 0.857,
|
||||
filename: text(colorScheme.middle, "mono", { size: "sm" }),
|
||||
path: {
|
||||
...text(colorScheme.middle, "mono", { size: "sm" }),
|
||||
margin: {
|
||||
left: 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
errorDiagnostic: diagnostic(colorScheme.middle, "negative"),
|
||||
warningDiagnostic: diagnostic(colorScheme.middle, "warning"),
|
||||
informationDiagnostic: diagnostic(colorScheme.middle, "accent"),
|
||||
hintDiagnostic: diagnostic(colorScheme.middle, "warning"),
|
||||
invalidErrorDiagnostic: diagnostic(colorScheme.middle, "base"),
|
||||
invalidHintDiagnostic: diagnostic(colorScheme.middle, "base"),
|
||||
invalidInformationDiagnostic: diagnostic(colorScheme.middle, "base"),
|
||||
invalidWarningDiagnostic: diagnostic(colorScheme.middle, "base"),
|
||||
hoverPopover: hoverPopover(colorScheme),
|
||||
linkDefinition: {
|
||||
color: syntax.linkUri.color,
|
||||
underline: syntax.linkUri.underline,
|
||||
},
|
||||
jumpIcon: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "on"),
|
||||
iconWidth: 20,
|
||||
buttonWidth: 20,
|
||||
cornerRadius: 6,
|
||||
padding: {
|
||||
top: 6,
|
||||
bottom: 6,
|
||||
left: 6,
|
||||
right: 6,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
scrollbar: {
|
||||
width: 12,
|
||||
minHeightFactor: 1.0,
|
||||
track: {
|
||||
border: border(layer, "variant", { left: true }),
|
||||
},
|
||||
thumb: {
|
||||
background: withOpacity(background(layer, "inverted"), 0.3),
|
||||
border: {
|
||||
width: 1,
|
||||
color: borderColor(layer, "variant"),
|
||||
top: false,
|
||||
right: true,
|
||||
left: true,
|
||||
bottom: false,
|
||||
},
|
||||
},
|
||||
git: {
|
||||
deleted: isLight
|
||||
? withOpacity(colorScheme.ramps.red(0.5).hex(), 0.8)
|
||||
: withOpacity(colorScheme.ramps.red(0.4).hex(), 0.8),
|
||||
modified: isLight
|
||||
? withOpacity(colorScheme.ramps.yellow(0.5).hex(), 0.8)
|
||||
: withOpacity(colorScheme.ramps.yellow(0.4).hex(), 0.8),
|
||||
inserted: isLight
|
||||
? withOpacity(colorScheme.ramps.green(0.5).hex(), 0.8)
|
||||
: withOpacity(colorScheme.ramps.green(0.4).hex(), 0.8),
|
||||
},
|
||||
},
|
||||
compositionMark: {
|
||||
underline: {
|
||||
thickness: 1.0,
|
||||
color: borderColor(layer),
|
||||
},
|
||||
},
|
||||
syntax,
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function feedback(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
|
||||
return {
|
||||
submit_button: interactive({
|
||||
base: {
|
||||
...text(layer, "mono", "on"),
|
||||
background: background(layer, "on"),
|
||||
cornerRadius: 6,
|
||||
border: border(layer, "on"),
|
||||
margin: {
|
||||
right: 4,
|
||||
},
|
||||
padding: {
|
||||
bottom: 2,
|
||||
left: 10,
|
||||
right: 10,
|
||||
top: 2,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
clicked: {
|
||||
...text(layer, "mono", "on", "pressed"),
|
||||
background: background(layer, "on", "pressed"),
|
||||
border: border(layer, "on", "pressed"),
|
||||
},
|
||||
hovered: {
|
||||
...text(layer, "mono", "on", "hovered"),
|
||||
background: background(layer, "on", "hovered"),
|
||||
border: border(layer, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
button_margin: 8,
|
||||
info_text_default: text(layer, "sans", "default", { size: "xs" }),
|
||||
link_text_default: text(layer, "sans", "default", {
|
||||
size: "xs",
|
||||
underline: true,
|
||||
}),
|
||||
link_text_hover: text(layer, "sans", "hovered", {
|
||||
size: "xs",
|
||||
underline: true,
|
||||
}),
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
|
||||
export default function HoverPopover(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
let baseContainer = {
|
||||
background: background(layer),
|
||||
cornerRadius: 8,
|
||||
padding: {
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
},
|
||||
shadow: colorScheme.popoverShadow,
|
||||
border: border(layer),
|
||||
margin: {
|
||||
left: -8,
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
container: baseContainer,
|
||||
infoContainer: {
|
||||
...baseContainer,
|
||||
background: background(layer, "accent"),
|
||||
border: border(layer, "accent"),
|
||||
},
|
||||
warningContainer: {
|
||||
...baseContainer,
|
||||
background: background(layer, "warning"),
|
||||
border: border(layer, "warning"),
|
||||
},
|
||||
errorContainer: {
|
||||
...baseContainer,
|
||||
background: background(layer, "negative"),
|
||||
border: border(layer, "negative"),
|
||||
},
|
||||
blockStyle: {
|
||||
padding: { top: 4 },
|
||||
},
|
||||
prose: text(layer, "sans", { size: "sm" }),
|
||||
diagnosticSourceHighlight: { color: foreground(layer, "accent") },
|
||||
highlight: colorScheme.ramps.neutral(0.5).alpha(0.2).hex(), // TODO: blend was used here. Replace with something better
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
|
||||
export default function incomingCallNotification(
|
||||
colorScheme: ColorScheme
|
||||
): Object {
|
||||
let layer = colorScheme.middle
|
||||
const avatarSize = 48
|
||||
return {
|
||||
windowHeight: 74,
|
||||
windowWidth: 380,
|
||||
background: background(layer),
|
||||
callerContainer: {
|
||||
padding: 12,
|
||||
},
|
||||
callerAvatar: {
|
||||
height: avatarSize,
|
||||
width: avatarSize,
|
||||
cornerRadius: avatarSize / 2,
|
||||
},
|
||||
callerMetadata: {
|
||||
margin: { left: 10 },
|
||||
},
|
||||
callerUsername: {
|
||||
...text(layer, "sans", { size: "sm", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
callerMessage: {
|
||||
...text(layer, "sans", "variant", { size: "xs" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
worktreeRoots: {
|
||||
...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
buttonWidth: 96,
|
||||
acceptButton: {
|
||||
background: background(layer, "accent"),
|
||||
border: border(layer, { left: true, bottom: true }),
|
||||
...text(layer, "sans", "positive", {
|
||||
size: "xs",
|
||||
weight: "extra_bold",
|
||||
}),
|
||||
},
|
||||
declineButton: {
|
||||
border: border(layer, { left: true }),
|
||||
...text(layer, "sans", "negative", {
|
||||
size: "xs",
|
||||
weight: "extra_bold",
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, text } from "./components"
|
||||
|
||||
export default function projectDiagnostics(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
return {
|
||||
background: background(layer),
|
||||
tabIconSpacing: 4,
|
||||
tabIconWidth: 13,
|
||||
tabSummarySpacing: 10,
|
||||
emptyMessage: text(layer, "sans", "variant", { size: "md" }),
|
||||
}
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import {
|
||||
Border,
|
||||
TextStyle,
|
||||
background,
|
||||
border,
|
||||
foreground,
|
||||
text,
|
||||
} from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
import merge from "ts-deepmerge"
|
||||
export default function projectPanel(colorScheme: ColorScheme) {
|
||||
const { isLight } = colorScheme
|
||||
|
||||
let layer = colorScheme.middle
|
||||
|
||||
type EntryStateProps = {
|
||||
background?: string
|
||||
border?: Border
|
||||
text?: TextStyle
|
||||
iconColor?: string
|
||||
}
|
||||
|
||||
type EntryState = {
|
||||
default: EntryStateProps
|
||||
hovered?: EntryStateProps
|
||||
clicked?: EntryStateProps
|
||||
}
|
||||
|
||||
const entry = (unselected?: EntryState, selected?: EntryState) => {
|
||||
const git_status = {
|
||||
git: {
|
||||
modified: isLight
|
||||
? colorScheme.ramps.yellow(0.6).hex()
|
||||
: colorScheme.ramps.yellow(0.5).hex(),
|
||||
inserted: isLight
|
||||
? colorScheme.ramps.green(0.45).hex()
|
||||
: colorScheme.ramps.green(0.5).hex(),
|
||||
conflict: isLight
|
||||
? colorScheme.ramps.red(0.6).hex()
|
||||
: colorScheme.ramps.red(0.5).hex(),
|
||||
},
|
||||
}
|
||||
|
||||
const base_properties = {
|
||||
height: 22,
|
||||
background: background(layer),
|
||||
iconColor: foreground(layer, "variant"),
|
||||
iconSize: 7,
|
||||
iconSpacing: 5,
|
||||
text: text(layer, "mono", "variant", { size: "sm" }),
|
||||
status: {
|
||||
...git_status,
|
||||
},
|
||||
}
|
||||
|
||||
const selectedStyle: EntryState | undefined = selected
|
||||
? selected
|
||||
: unselected
|
||||
|
||||
const unselected_default_style = merge(
|
||||
base_properties,
|
||||
unselected?.default ?? {},
|
||||
{}
|
||||
)
|
||||
const unselected_hovered_style = merge(
|
||||
base_properties,
|
||||
unselected?.hovered ?? {},
|
||||
{ background: background(layer, "variant", "hovered") }
|
||||
)
|
||||
const unselected_clicked_style = merge(
|
||||
base_properties,
|
||||
unselected?.clicked ?? {},
|
||||
{ background: background(layer, "variant", "pressed") }
|
||||
)
|
||||
const selected_default_style = merge(
|
||||
base_properties,
|
||||
selectedStyle?.default ?? {},
|
||||
{ background: background(layer) }
|
||||
)
|
||||
const selected_hovered_style = merge(
|
||||
base_properties,
|
||||
selectedStyle?.hovered ?? {},
|
||||
{ background: background(layer, "variant", "hovered") }
|
||||
)
|
||||
const selected_clicked_style = merge(
|
||||
base_properties,
|
||||
selectedStyle?.clicked ?? {},
|
||||
{ background: background(layer, "variant", "pressed") }
|
||||
)
|
||||
|
||||
return toggleable({
|
||||
state: {
|
||||
inactive: interactive({
|
||||
state: {
|
||||
default: unselected_default_style,
|
||||
hovered: unselected_hovered_style,
|
||||
clicked: unselected_clicked_style,
|
||||
},
|
||||
}),
|
||||
active: interactive({
|
||||
state: {
|
||||
default: selected_default_style,
|
||||
hovered: selected_hovered_style,
|
||||
clicked: selected_clicked_style,
|
||||
},
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const defaultEntry = entry()
|
||||
|
||||
return {
|
||||
openProjectButton: interactive({
|
||||
base: {
|
||||
background: background(layer),
|
||||
border: border(layer, "active"),
|
||||
cornerRadius: 4,
|
||||
margin: {
|
||||
top: 16,
|
||||
left: 16,
|
||||
right: 16,
|
||||
},
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
...text(layer, "sans", "default", { size: "sm" }),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(layer, "sans", "default", { size: "sm" }),
|
||||
background: background(layer, "hovered"),
|
||||
border: border(layer, "active"),
|
||||
},
|
||||
clicked: {
|
||||
...text(layer, "sans", "default", { size: "sm" }),
|
||||
background: background(layer, "pressed"),
|
||||
border: border(layer, "active"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
background: background(layer),
|
||||
padding: { left: 6, right: 6, top: 0, bottom: 6 },
|
||||
indentWidth: 12,
|
||||
entry: defaultEntry,
|
||||
draggedEntry: {
|
||||
...defaultEntry.inactive.default,
|
||||
text: text(layer, "mono", "on", { size: "sm" }),
|
||||
background: withOpacity(background(layer, "on"), 0.9),
|
||||
border: border(layer),
|
||||
},
|
||||
ignoredEntry: entry(
|
||||
{
|
||||
default: {
|
||||
text: text(layer, "mono", "disabled"),
|
||||
},
|
||||
},
|
||||
{
|
||||
default: {
|
||||
iconColor: foreground(layer, "variant"),
|
||||
},
|
||||
}
|
||||
),
|
||||
cutEntry: entry(
|
||||
{
|
||||
default: {
|
||||
text: text(layer, "mono", "disabled"),
|
||||
},
|
||||
},
|
||||
{
|
||||
default: {
|
||||
background: background(layer, "active"),
|
||||
text: text(layer, "mono", "disabled", { size: "sm" }),
|
||||
},
|
||||
}
|
||||
),
|
||||
filenameEditor: {
|
||||
background: background(layer, "on"),
|
||||
text: text(layer, "mono", "on", { size: "sm" }),
|
||||
selection: colorScheme.players[0],
|
||||
},
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
|
||||
export default function projectSharedNotification(
|
||||
colorScheme: ColorScheme
|
||||
): Object {
|
||||
let layer = colorScheme.middle
|
||||
|
||||
const avatarSize = 48
|
||||
return {
|
||||
windowHeight: 74,
|
||||
windowWidth: 380,
|
||||
background: background(layer),
|
||||
ownerContainer: {
|
||||
padding: 12,
|
||||
},
|
||||
ownerAvatar: {
|
||||
height: avatarSize,
|
||||
width: avatarSize,
|
||||
cornerRadius: avatarSize / 2,
|
||||
},
|
||||
ownerMetadata: {
|
||||
margin: { left: 10 },
|
||||
},
|
||||
ownerUsername: {
|
||||
...text(layer, "sans", { size: "sm", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
message: {
|
||||
...text(layer, "sans", "variant", { size: "xs" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
worktreeRoots: {
|
||||
...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
buttonWidth: 96,
|
||||
openButton: {
|
||||
background: background(layer, "accent"),
|
||||
border: border(layer, { left: true, bottom: true }),
|
||||
...text(layer, "sans", "accent", {
|
||||
size: "xs",
|
||||
weight: "extra_bold",
|
||||
}),
|
||||
},
|
||||
dismissButton: {
|
||||
border: border(layer, { left: true }),
|
||||
...text(layer, "sans", "variant", {
|
||||
size: "xs",
|
||||
weight: "extra_bold",
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function search(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
|
||||
// Search input
|
||||
const editor = {
|
||||
background: background(layer),
|
||||
cornerRadius: 8,
|
||||
minWidth: 200,
|
||||
maxWidth: 500,
|
||||
placeholderText: text(layer, "mono", "disabled"),
|
||||
selection: colorScheme.players[0],
|
||||
text: text(layer, "mono", "default"),
|
||||
border: border(layer),
|
||||
margin: {
|
||||
right: 12,
|
||||
},
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 12,
|
||||
right: 8,
|
||||
},
|
||||
}
|
||||
|
||||
const includeExcludeEditor = {
|
||||
...editor,
|
||||
minWidth: 100,
|
||||
maxWidth: 250,
|
||||
}
|
||||
|
||||
return {
|
||||
// TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
|
||||
matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
|
||||
optionButton: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
...text(layer, "mono", "on"),
|
||||
background: background(layer, "on"),
|
||||
cornerRadius: 6,
|
||||
border: border(layer, "on"),
|
||||
margin: {
|
||||
right: 4,
|
||||
},
|
||||
padding: {
|
||||
bottom: 2,
|
||||
left: 10,
|
||||
right: 10,
|
||||
top: 2,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(layer, "mono", "on", "hovered"),
|
||||
background: background(layer, "on", "hovered"),
|
||||
border: border(layer, "on", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
...text(layer, "mono", "on", "pressed"),
|
||||
background: background(layer, "on", "pressed"),
|
||||
border: border(layer, "on", "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
...text(layer, "mono", "accent"),
|
||||
},
|
||||
hovered: {
|
||||
...text(layer, "mono", "accent", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
...text(layer, "mono", "accent", "pressed"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
editor,
|
||||
invalidEditor: {
|
||||
...editor,
|
||||
border: border(layer, "negative"),
|
||||
},
|
||||
includeExcludeEditor,
|
||||
invalidIncludeExcludeEditor: {
|
||||
...includeExcludeEditor,
|
||||
border: border(layer, "negative"),
|
||||
},
|
||||
matchIndex: {
|
||||
...text(layer, "mono", "variant"),
|
||||
padding: {
|
||||
left: 6,
|
||||
},
|
||||
},
|
||||
optionButtonGroup: {
|
||||
padding: {
|
||||
left: 12,
|
||||
right: 12,
|
||||
},
|
||||
},
|
||||
includeExcludeInputs: {
|
||||
...text(layer, "mono", "variant"),
|
||||
padding: {
|
||||
right: 6,
|
||||
},
|
||||
},
|
||||
resultsStatus: {
|
||||
...text(layer, "mono", "on"),
|
||||
size: 18,
|
||||
},
|
||||
dismissButton: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "variant"),
|
||||
iconWidth: 12,
|
||||
buttonWidth: 14,
|
||||
padding: {
|
||||
left: 10,
|
||||
right: 10,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(layer, "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background } from "./components"
|
||||
|
||||
export default function sharedScreen(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
return {
|
||||
background: background(layer),
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
const headerPadding = 8
|
||||
|
||||
export default function simpleMessageNotification(
|
||||
colorScheme: ColorScheme
|
||||
): Object {
|
||||
let layer = colorScheme.middle
|
||||
return {
|
||||
message: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
margin: { left: headerPadding, right: headerPadding },
|
||||
},
|
||||
actionMessage: interactive({
|
||||
base: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
border: border(layer, "active"),
|
||||
cornerRadius: 4,
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
|
||||
margin: { left: headerPadding, top: 6, bottom: 6 },
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(layer, "sans", "default", { size: "xs" }),
|
||||
background: background(layer, "hovered"),
|
||||
border: border(layer, "active"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
dismissButton: interactive({
|
||||
base: {
|
||||
color: foreground(layer),
|
||||
iconWidth: 8,
|
||||
iconHeight: 8,
|
||||
buttonWidth: 8,
|
||||
buttonHeight: 8,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
|
||||
export default function terminal(colorScheme: ColorScheme) {
|
||||
/**
|
||||
* Colors are controlled per-cell in the terminal grid.
|
||||
* Cells can be set to any of these more 'theme-capable' colors
|
||||
* or can be set directly with RGB values.
|
||||
* Here are the common interpretations of these names:
|
||||
* https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
||||
*/
|
||||
return {
|
||||
black: colorScheme.ramps.neutral(0).hex(),
|
||||
red: colorScheme.ramps.red(0.5).hex(),
|
||||
green: colorScheme.ramps.green(0.5).hex(),
|
||||
yellow: colorScheme.ramps.yellow(0.5).hex(),
|
||||
blue: colorScheme.ramps.blue(0.5).hex(),
|
||||
magenta: colorScheme.ramps.magenta(0.5).hex(),
|
||||
cyan: colorScheme.ramps.cyan(0.5).hex(),
|
||||
white: colorScheme.ramps.neutral(1).hex(),
|
||||
brightBlack: colorScheme.ramps.neutral(0.4).hex(),
|
||||
brightRed: colorScheme.ramps.red(0.25).hex(),
|
||||
brightGreen: colorScheme.ramps.green(0.25).hex(),
|
||||
brightYellow: colorScheme.ramps.yellow(0.25).hex(),
|
||||
brightBlue: colorScheme.ramps.blue(0.25).hex(),
|
||||
brightMagenta: colorScheme.ramps.magenta(0.25).hex(),
|
||||
brightCyan: colorScheme.ramps.cyan(0.25).hex(),
|
||||
brightWhite: colorScheme.ramps.neutral(1).hex(),
|
||||
/**
|
||||
* Default color for characters
|
||||
*/
|
||||
foreground: colorScheme.ramps.neutral(1).hex(),
|
||||
/**
|
||||
* Default color for the rectangle background of a cell
|
||||
*/
|
||||
background: colorScheme.ramps.neutral(0).hex(),
|
||||
modalBackground: colorScheme.ramps.neutral(0.1).hex(),
|
||||
/**
|
||||
* Default color for the cursor
|
||||
*/
|
||||
cursor: colorScheme.players[0].cursor,
|
||||
dimBlack: colorScheme.ramps.neutral(1).hex(),
|
||||
dimRed: colorScheme.ramps.red(0.75).hex(),
|
||||
dimGreen: colorScheme.ramps.green(0.75).hex(),
|
||||
dimYellow: colorScheme.ramps.yellow(0.75).hex(),
|
||||
dimBlue: colorScheme.ramps.blue(0.75).hex(),
|
||||
dimMagenta: colorScheme.ramps.magenta(0.75).hex(),
|
||||
dimCyan: colorScheme.ramps.cyan(0.75).hex(),
|
||||
dimWhite: colorScheme.ramps.neutral(0.6).hex(),
|
||||
brightForeground: colorScheme.ramps.neutral(1).hex(),
|
||||
dimForeground: colorScheme.ramps.neutral(0).hex(),
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import merge from "ts-deepmerge"
|
||||
|
||||
type ToggleState = "inactive" | "active"
|
||||
|
||||
type Toggleable<T> = Record<ToggleState, T>
|
||||
|
||||
const NO_INACTIVE_OR_BASE_ERROR =
|
||||
"A toggleable object must have an inactive state, or a base property."
|
||||
const NO_ACTIVE_ERROR = "A toggleable object must have an active state."
|
||||
|
||||
interface ToggleableProps<T> {
|
||||
base?: T
|
||||
state: Partial<Record<ToggleState, T>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for creating Toggleable objects.
|
||||
* @template T The type of the object being toggled.
|
||||
* @param props Object containing the base (inactive) state and state modifications to create the active state.
|
||||
* @returns A Toggleable object containing both the inactive and active states.
|
||||
* @example
|
||||
* ```
|
||||
* toggleable({
|
||||
* base: { background: "#000000", text: "#CCCCCC" },
|
||||
* state: { active: { text: "#CCCCCC" } },
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
export function toggleable<T extends object>(
|
||||
props: ToggleableProps<T>
|
||||
): Toggleable<T> {
|
||||
const { base, state } = props
|
||||
|
||||
if (!base && !state.inactive) throw new Error(NO_INACTIVE_OR_BASE_ERROR)
|
||||
if (!state.active) throw new Error(NO_ACTIVE_ERROR)
|
||||
|
||||
const inactiveState = base
|
||||
? ((state.inactive ? merge(base, state.inactive) : base) as T)
|
||||
: (state.inactive as T)
|
||||
|
||||
const toggleObj: Toggleable<T> = {
|
||||
inactive: inactiveState,
|
||||
active: merge(base ?? {}, state.active) as T,
|
||||
}
|
||||
|
||||
return toggleObj
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
export default function dropdownMenu(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
|
||||
return {
|
||||
rowHeight: 30,
|
||||
background: background(layer),
|
||||
border: border(layer),
|
||||
shadow: colorScheme.popoverShadow,
|
||||
header: interactive({
|
||||
base: {
|
||||
...text(layer, "sans", { size: "sm" }),
|
||||
secondaryText: text(layer, "sans", {
|
||||
size: "sm",
|
||||
color: "#aaaaaa",
|
||||
}),
|
||||
secondaryTextSpacing: 10,
|
||||
padding: { left: 8, right: 8, top: 2, bottom: 2 },
|
||||
cornerRadius: 6,
|
||||
background: background(layer, "on"),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
background: background(layer, "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
sectionHeader: {
|
||||
...text(layer, "sans", { size: "sm" }),
|
||||
padding: { left: 8, right: 8, top: 8, bottom: 8 },
|
||||
},
|
||||
item: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
...text(layer, "sans", { size: "sm" }),
|
||||
secondaryTextSpacing: 10,
|
||||
secondaryText: text(layer, "sans", { size: "sm" }),
|
||||
padding: { left: 18, right: 18, top: 2, bottom: 2 },
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "hovered"),
|
||||
...text(layer, "sans", "hovered", { size: "sm" }),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
background: background(layer, "active"),
|
||||
},
|
||||
hovered: {
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, text } from "./components"
|
||||
|
||||
export default function tooltip(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
return {
|
||||
background: background(layer),
|
||||
border: border(layer),
|
||||
padding: { top: 4, bottom: 4, left: 8, right: 8 },
|
||||
margin: { top: 6, left: 6 },
|
||||
shadow: colorScheme.popoverShadow,
|
||||
cornerRadius: 6,
|
||||
text: text(layer, "sans", { size: "xs" }),
|
||||
keystroke: {
|
||||
background: background(layer, "on"),
|
||||
cornerRadius: 4,
|
||||
margin: { left: 6 },
|
||||
padding: { left: 4, right: 4 },
|
||||
...text(layer, "mono", "on", { size: "xs", weight: "bold" }),
|
||||
},
|
||||
maxTextWidth: 200,
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { foreground, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
const headerPadding = 8
|
||||
|
||||
export default function updateNotification(colorScheme: ColorScheme): Object {
|
||||
let layer = colorScheme.middle
|
||||
return {
|
||||
message: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
margin: { left: headerPadding, right: headerPadding },
|
||||
},
|
||||
actionMessage: interactive({
|
||||
base: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
margin: { left: headerPadding, top: 6, bottom: 6 },
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
dismissButton: interactive({
|
||||
base: {
|
||||
color: foreground(layer),
|
||||
iconWidth: 8,
|
||||
iconHeight: 8,
|
||||
buttonWidth: 8,
|
||||
buttonHeight: 8,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import {
|
||||
border,
|
||||
background,
|
||||
foreground,
|
||||
text,
|
||||
TextProperties,
|
||||
svg,
|
||||
} from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function welcome(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
|
||||
let checkboxBase = {
|
||||
cornerRadius: 4,
|
||||
padding: {
|
||||
left: 3,
|
||||
right: 3,
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
},
|
||||
// shadow: colorScheme.popoverShadow,
|
||||
border: border(layer),
|
||||
margin: {
|
||||
right: 8,
|
||||
top: 5,
|
||||
bottom: 5,
|
||||
},
|
||||
}
|
||||
|
||||
let interactive_text_size: TextProperties = { size: "sm" }
|
||||
|
||||
return {
|
||||
pageWidth: 320,
|
||||
logo: svg(foreground(layer, "default"), "icons/logo_96.svg", 64, 64),
|
||||
logoSubheading: {
|
||||
...text(layer, "sans", "variant", { size: "md" }),
|
||||
margin: {
|
||||
top: 10,
|
||||
bottom: 7,
|
||||
},
|
||||
},
|
||||
buttonGroup: {
|
||||
margin: {
|
||||
top: 8,
|
||||
bottom: 16,
|
||||
},
|
||||
},
|
||||
headingGroup: {
|
||||
margin: {
|
||||
top: 8,
|
||||
bottom: 12,
|
||||
},
|
||||
},
|
||||
checkboxGroup: {
|
||||
border: border(layer, "variant"),
|
||||
background: withOpacity(background(layer, "hovered"), 0.25),
|
||||
cornerRadius: 4,
|
||||
padding: {
|
||||
left: 12,
|
||||
top: 2,
|
||||
bottom: 2,
|
||||
},
|
||||
},
|
||||
button: interactive({
|
||||
base: {
|
||||
background: background(layer),
|
||||
border: border(layer, "active"),
|
||||
cornerRadius: 4,
|
||||
margin: {
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
},
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
...text(layer, "sans", "default", interactive_text_size),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(layer, "sans", "default", interactive_text_size),
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
usageNote: {
|
||||
...text(layer, "sans", "variant", { size: "2xs" }),
|
||||
padding: {
|
||||
top: -4,
|
||||
},
|
||||
},
|
||||
checkboxContainer: {
|
||||
margin: {
|
||||
top: 4,
|
||||
},
|
||||
padding: {
|
||||
bottom: 8,
|
||||
},
|
||||
},
|
||||
checkbox: {
|
||||
label: {
|
||||
...text(layer, "sans", interactive_text_size),
|
||||
// Also supports margin, container, border, etc.
|
||||
},
|
||||
icon: svg(foreground(layer, "on"), "icons/check_12.svg", 12, 12),
|
||||
default: {
|
||||
...checkboxBase,
|
||||
background: background(layer, "default"),
|
||||
border: border(layer, "active"),
|
||||
},
|
||||
checked: {
|
||||
...checkboxBase,
|
||||
background: background(layer, "hovered"),
|
||||
border: border(layer, "active"),
|
||||
},
|
||||
hovered: {
|
||||
...checkboxBase,
|
||||
background: background(layer, "hovered"),
|
||||
border: border(layer, "active"),
|
||||
},
|
||||
hoveredAndChecked: {
|
||||
...checkboxBase,
|
||||
background: background(layer, "hovered"),
|
||||
border: border(layer, "active"),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import {
|
||||
background,
|
||||
border,
|
||||
borderColor,
|
||||
foreground,
|
||||
svg,
|
||||
text,
|
||||
} from "./components"
|
||||
import statusBar from "./statusBar"
|
||||
import tabBar from "./tabBar"
|
||||
import { interactive } from "../element"
|
||||
|
||||
import { titlebar } from "./titlebar"
|
||||
export default function workspace(colorScheme: ColorScheme) {
|
||||
const layer = colorScheme.lowest
|
||||
const isLight = colorScheme.isLight
|
||||
|
||||
return {
|
||||
background: background(colorScheme.lowest),
|
||||
blankPane: {
|
||||
logoContainer: {
|
||||
width: 256,
|
||||
height: 256,
|
||||
},
|
||||
logo: svg(
|
||||
withOpacity("#000000", colorScheme.isLight ? 0.6 : 0.8),
|
||||
"icons/logo_96.svg",
|
||||
256,
|
||||
256
|
||||
),
|
||||
|
||||
logoShadow: svg(
|
||||
withOpacity(
|
||||
colorScheme.isLight
|
||||
? "#FFFFFF"
|
||||
: colorScheme.lowest.base.default.background,
|
||||
colorScheme.isLight ? 1 : 0.6
|
||||
),
|
||||
"icons/logo_96.svg",
|
||||
256,
|
||||
256
|
||||
),
|
||||
keyboardHints: {
|
||||
margin: {
|
||||
top: 96,
|
||||
},
|
||||
cornerRadius: 4,
|
||||
},
|
||||
keyboardHint: interactive({
|
||||
base: {
|
||||
...text(layer, "sans", "variant", { size: "sm" }),
|
||||
padding: {
|
||||
top: 3,
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 3,
|
||||
},
|
||||
cornerRadius: 8,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(layer, "sans", "active", { size: "sm" }),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
keyboardHintWidth: 320,
|
||||
},
|
||||
joiningProjectAvatar: {
|
||||
cornerRadius: 40,
|
||||
width: 80,
|
||||
},
|
||||
joiningProjectMessage: {
|
||||
padding: 12,
|
||||
...text(layer, "sans", { size: "lg" }),
|
||||
},
|
||||
externalLocationMessage: {
|
||||
background: background(colorScheme.middle, "accent"),
|
||||
border: border(colorScheme.middle, "accent"),
|
||||
cornerRadius: 6,
|
||||
padding: 12,
|
||||
margin: { bottom: 8, right: 8 },
|
||||
...text(colorScheme.middle, "sans", "accent", { size: "xs" }),
|
||||
},
|
||||
leaderBorderOpacity: 0.7,
|
||||
leaderBorderWidth: 2.0,
|
||||
tabBar: tabBar(colorScheme),
|
||||
modal: {
|
||||
margin: {
|
||||
bottom: 52,
|
||||
top: 52,
|
||||
},
|
||||
cursor: "Arrow",
|
||||
},
|
||||
zoomedBackground: {
|
||||
cursor: "Arrow",
|
||||
background: isLight
|
||||
? withOpacity(background(colorScheme.lowest), 0.8)
|
||||
: withOpacity(background(colorScheme.highest), 0.6),
|
||||
},
|
||||
zoomedPaneForeground: {
|
||||
margin: 16,
|
||||
shadow: colorScheme.modalShadow,
|
||||
border: border(colorScheme.lowest, { overlay: true }),
|
||||
},
|
||||
zoomedPanelForeground: {
|
||||
margin: 16,
|
||||
border: border(colorScheme.lowest, { overlay: true }),
|
||||
},
|
||||
dock: {
|
||||
left: {
|
||||
border: border(layer, { right: true }),
|
||||
},
|
||||
bottom: {
|
||||
border: border(layer, { top: true }),
|
||||
},
|
||||
right: {
|
||||
border: border(layer, { left: true }),
|
||||
},
|
||||
},
|
||||
paneDivider: {
|
||||
color: borderColor(layer),
|
||||
width: 1,
|
||||
},
|
||||
statusBar: statusBar(colorScheme),
|
||||
titlebar: titlebar(colorScheme),
|
||||
toolbar: {
|
||||
height: 34,
|
||||
background: background(colorScheme.highest),
|
||||
border: border(colorScheme.highest, { bottom: true }),
|
||||
itemSpacing: 8,
|
||||
navButton: interactive({
|
||||
base: {
|
||||
color: foreground(colorScheme.highest, "on"),
|
||||
iconWidth: 12,
|
||||
buttonWidth: 24,
|
||||
cornerRadius: 6,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(colorScheme.highest, "on", "hovered"),
|
||||
background: background(
|
||||
colorScheme.highest,
|
||||
"on",
|
||||
"hovered"
|
||||
),
|
||||
},
|
||||
disabled: {
|
||||
color: foreground(
|
||||
colorScheme.highest,
|
||||
"on",
|
||||
"disabled"
|
||||
),
|
||||
},
|
||||
},
|
||||
}),
|
||||
padding: { left: 8, right: 8, top: 4, bottom: 4 },
|
||||
},
|
||||
breadcrumbHeight: 24,
|
||||
breadcrumbs: interactive({
|
||||
base: {
|
||||
...text(colorScheme.highest, "sans", "variant"),
|
||||
cornerRadius: 6,
|
||||
padding: {
|
||||
left: 6,
|
||||
right: 6,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(colorScheme.highest, "on", "hovered"),
|
||||
background: background(
|
||||
colorScheme.highest,
|
||||
"on",
|
||||
"hovered"
|
||||
),
|
||||
},
|
||||
},
|
||||
}),
|
||||
disconnectedOverlay: {
|
||||
...text(layer, "sans"),
|
||||
background: withOpacity(background(layer), 0.8),
|
||||
},
|
||||
notification: {
|
||||
margin: { top: 10 },
|
||||
background: background(colorScheme.middle),
|
||||
cornerRadius: 6,
|
||||
padding: 12,
|
||||
border: border(colorScheme.middle),
|
||||
shadow: colorScheme.popoverShadow,
|
||||
},
|
||||
notifications: {
|
||||
width: 400,
|
||||
margin: { right: 10, bottom: 10 },
|
||||
},
|
||||
dropTargetOverlayColor: withOpacity(foreground(layer, "variant"), 0.5),
|
||||
}
|
||||
}
|
75
styles/src/style_tree/app.ts
Normal file
75
styles/src/style_tree/app.ts
Normal file
@ -0,0 +1,75 @@
|
||||
import contact_finder from "./contact_finder"
|
||||
import contacts_popover from "./contacts_popover"
|
||||
import command_palette from "./command_palette"
|
||||
import project_panel from "./project_panel"
|
||||
import search from "./search"
|
||||
import picker from "./picker"
|
||||
import workspace from "./workspace"
|
||||
import context_menu from "./context_menu"
|
||||
import shared_screen from "./shared_screen"
|
||||
import project_diagnostics from "./project_diagnostics"
|
||||
import contact_notification from "./contact_notification"
|
||||
import update_notification from "./update_notification"
|
||||
import simple_message_notification from "./simple_message_notification"
|
||||
import project_shared_notification from "./project_shared_notification"
|
||||
import tooltip from "./tooltip"
|
||||
import terminal from "./terminal"
|
||||
import contact_list from "./contact_list"
|
||||
import toolbar_dropdown_menu from "./toolbar_dropdown_menu"
|
||||
import incoming_call_notification from "./incoming_call_notification"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import welcome from "./welcome"
|
||||
import copilot from "./copilot"
|
||||
import assistant from "./assistant"
|
||||
import { titlebar } from "./titlebar"
|
||||
import editor from "./editor"
|
||||
import feedback from "./feedback"
|
||||
|
||||
export default function app(theme: ColorScheme): any {
|
||||
return {
|
||||
meta: {
|
||||
name: theme.name,
|
||||
is_light: theme.is_light,
|
||||
},
|
||||
command_palette: command_palette(theme),
|
||||
contact_notification: contact_notification(theme),
|
||||
project_shared_notification: project_shared_notification(theme),
|
||||
incoming_call_notification: incoming_call_notification(theme),
|
||||
picker: picker(theme),
|
||||
workspace: workspace(theme),
|
||||
titlebar: titlebar(theme),
|
||||
copilot: copilot(theme),
|
||||
welcome: welcome(theme),
|
||||
context_menu: context_menu(theme),
|
||||
editor: editor(theme),
|
||||
project_diagnostics: project_diagnostics(theme),
|
||||
project_panel: project_panel(theme),
|
||||
contacts_popover: contacts_popover(theme),
|
||||
contact_finder: contact_finder(theme),
|
||||
contact_list: contact_list(theme),
|
||||
toolbar_dropdown_menu: toolbar_dropdown_menu(theme),
|
||||
search: search(theme),
|
||||
shared_screen: shared_screen(theme),
|
||||
update_notification: update_notification(theme),
|
||||
simple_message_notification: simple_message_notification(theme),
|
||||
tooltip: tooltip(theme),
|
||||
terminal: terminal(theme),
|
||||
assistant: assistant(theme),
|
||||
feedback: feedback(theme),
|
||||
color_scheme: {
|
||||
...theme,
|
||||
players: Object.values(theme.players),
|
||||
ramps: {
|
||||
neutral: theme.ramps.neutral.colors(100, "hex"),
|
||||
red: theme.ramps.red.colors(100, "hex"),
|
||||
orange: theme.ramps.orange.colors(100, "hex"),
|
||||
yellow: theme.ramps.yellow.colors(100, "hex"),
|
||||
green: theme.ramps.green.colors(100, "hex"),
|
||||
cyan: theme.ramps.cyan.colors(100, "hex"),
|
||||
blue: theme.ramps.blue.colors(100, "hex"),
|
||||
violet: theme.ramps.violet.colors(100, "hex"),
|
||||
magenta: theme.ramps.magenta.colors(100, "hex"),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
@ -1,23 +1,21 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { text, border, background, foreground } from "./components"
|
||||
import editor from "./editor"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function assistant(colorScheme: ColorScheme) {
|
||||
const layer = colorScheme.highest
|
||||
export default function assistant(theme: ColorScheme): any {
|
||||
return {
|
||||
container: {
|
||||
background: editor(colorScheme).background,
|
||||
background: background(theme.highest),
|
||||
padding: { left: 12 },
|
||||
},
|
||||
messageHeader: {
|
||||
message_header: {
|
||||
margin: { bottom: 6, top: 6 },
|
||||
background: editor(colorScheme).background,
|
||||
background: background(theme.highest),
|
||||
},
|
||||
hamburgerButton: interactive({
|
||||
hamburger_button: interactive({
|
||||
base: {
|
||||
icon: {
|
||||
color: foreground(layer, "variant"),
|
||||
color: foreground(theme.highest, "variant"),
|
||||
asset: "icons/hamburger_15.svg",
|
||||
dimensions: {
|
||||
width: 15,
|
||||
@ -31,15 +29,15 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
splitButton: interactive({
|
||||
split_button: interactive({
|
||||
base: {
|
||||
icon: {
|
||||
color: foreground(layer, "variant"),
|
||||
color: foreground(theme.highest, "variant"),
|
||||
asset: "icons/split_message_15.svg",
|
||||
dimensions: {
|
||||
width: 15,
|
||||
@ -53,15 +51,15 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
quoteButton: interactive({
|
||||
quote_button: interactive({
|
||||
base: {
|
||||
icon: {
|
||||
color: foreground(layer, "variant"),
|
||||
color: foreground(theme.highest, "variant"),
|
||||
asset: "icons/quote_15.svg",
|
||||
dimensions: {
|
||||
width: 15,
|
||||
@ -75,15 +73,15 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
assistButton: interactive({
|
||||
assist_button: interactive({
|
||||
base: {
|
||||
icon: {
|
||||
color: foreground(layer, "variant"),
|
||||
color: foreground(theme.highest, "variant"),
|
||||
asset: "icons/assist_15.svg",
|
||||
dimensions: {
|
||||
width: 15,
|
||||
@ -97,15 +95,15 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
zoomInButton: interactive({
|
||||
zoom_in_button: interactive({
|
||||
base: {
|
||||
icon: {
|
||||
color: foreground(layer, "variant"),
|
||||
color: foreground(theme.highest, "variant"),
|
||||
asset: "icons/maximize_8.svg",
|
||||
dimensions: {
|
||||
width: 12,
|
||||
@ -119,15 +117,15 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
zoomOutButton: interactive({
|
||||
zoom_out_button: interactive({
|
||||
base: {
|
||||
icon: {
|
||||
color: foreground(layer, "variant"),
|
||||
color: foreground(theme.highest, "variant"),
|
||||
asset: "icons/minimize_8.svg",
|
||||
dimensions: {
|
||||
width: 12,
|
||||
@ -141,15 +139,15 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
plusButton: interactive({
|
||||
plus_button: interactive({
|
||||
base: {
|
||||
icon: {
|
||||
color: foreground(layer, "variant"),
|
||||
color: foreground(theme.highest, "variant"),
|
||||
asset: "icons/plus_12.svg",
|
||||
dimensions: {
|
||||
width: 12,
|
||||
@ -163,109 +161,109 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
title: {
|
||||
...text(layer, "sans", "default", { size: "sm" }),
|
||||
...text(theme.highest, "sans", "default", { size: "sm" }),
|
||||
},
|
||||
savedConversation: {
|
||||
saved_conversation: {
|
||||
container: interactive({
|
||||
base: {
|
||||
background: background(layer, "on"),
|
||||
background: background(theme.highest, "on"),
|
||||
padding: { top: 4, bottom: 4 },
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "on", "hovered"),
|
||||
background: background(theme.highest, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
savedAt: {
|
||||
saved_at: {
|
||||
margin: { left: 8 },
|
||||
...text(layer, "sans", "default", { size: "xs" }),
|
||||
...text(theme.highest, "sans", "default", { size: "xs" }),
|
||||
},
|
||||
title: {
|
||||
margin: { left: 16 },
|
||||
...text(layer, "sans", "default", {
|
||||
...text(theme.highest, "sans", "default", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
},
|
||||
userSender: {
|
||||
user_sender: {
|
||||
default: {
|
||||
...text(layer, "sans", "default", {
|
||||
...text(theme.highest, "sans", "default", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
},
|
||||
assistantSender: {
|
||||
assistant_sender: {
|
||||
default: {
|
||||
...text(layer, "sans", "accent", {
|
||||
...text(theme.highest, "sans", "accent", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
},
|
||||
systemSender: {
|
||||
system_sender: {
|
||||
default: {
|
||||
...text(layer, "sans", "variant", {
|
||||
...text(theme.highest, "sans", "variant", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
},
|
||||
sentAt: {
|
||||
sent_at: {
|
||||
margin: { top: 2, left: 8 },
|
||||
...text(layer, "sans", "default", { size: "2xs" }),
|
||||
...text(theme.highest, "sans", "default", { size: "2xs" }),
|
||||
},
|
||||
model: interactive({
|
||||
base: {
|
||||
background: background(layer, "on"),
|
||||
background: background(theme.highest, "on"),
|
||||
margin: { left: 12, right: 12, top: 12 },
|
||||
padding: 4,
|
||||
cornerRadius: 4,
|
||||
...text(layer, "sans", "default", { size: "xs" }),
|
||||
corner_radius: 4,
|
||||
...text(theme.highest, "sans", "default", { size: "xs" }),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "on", "hovered"),
|
||||
border: border(layer, "on", { overlay: true }),
|
||||
background: background(theme.highest, "on", "hovered"),
|
||||
border: border(theme.highest, "on", { overlay: true }),
|
||||
},
|
||||
},
|
||||
}),
|
||||
remainingTokens: {
|
||||
background: background(layer, "on"),
|
||||
remaining_tokens: {
|
||||
background: background(theme.highest, "on"),
|
||||
margin: { top: 12, right: 24 },
|
||||
padding: 4,
|
||||
cornerRadius: 4,
|
||||
...text(layer, "sans", "positive", { size: "xs" }),
|
||||
corner_radius: 4,
|
||||
...text(theme.highest, "sans", "positive", { size: "xs" }),
|
||||
},
|
||||
noRemainingTokens: {
|
||||
background: background(layer, "on"),
|
||||
no_remaining_tokens: {
|
||||
background: background(theme.highest, "on"),
|
||||
margin: { top: 12, right: 24 },
|
||||
padding: 4,
|
||||
cornerRadius: 4,
|
||||
...text(layer, "sans", "negative", { size: "xs" }),
|
||||
corner_radius: 4,
|
||||
...text(theme.highest, "sans", "negative", { size: "xs" }),
|
||||
},
|
||||
errorIcon: {
|
||||
error_icon: {
|
||||
margin: { left: 8 },
|
||||
color: foreground(layer, "negative"),
|
||||
color: foreground(theme.highest, "negative"),
|
||||
width: 12,
|
||||
},
|
||||
apiKeyEditor: {
|
||||
background: background(layer, "on"),
|
||||
cornerRadius: 6,
|
||||
text: text(layer, "mono", "on"),
|
||||
placeholderText: text(layer, "mono", "on", "disabled", {
|
||||
api_key_editor: {
|
||||
background: background(theme.highest, "on"),
|
||||
corner_radius: 6,
|
||||
text: text(theme.highest, "mono", "on"),
|
||||
placeholder_text: text(theme.highest, "mono", "on", "disabled", {
|
||||
size: "xs",
|
||||
}),
|
||||
selection: colorScheme.players[0],
|
||||
border: border(layer, "on"),
|
||||
selection: theme.players[0],
|
||||
border: border(theme.highest, "on"),
|
||||
padding: {
|
||||
bottom: 4,
|
||||
left: 8,
|
||||
@ -273,9 +271,9 @@ export default function assistant(colorScheme: ColorScheme) {
|
||||
top: 4,
|
||||
},
|
||||
},
|
||||
apiKeyPrompt: {
|
||||
api_key_prompt: {
|
||||
padding: 10,
|
||||
...text(layer, "sans", "default", { size: "xs" }),
|
||||
...text(theme.highest, "sans", "default", { size: "xs" }),
|
||||
},
|
||||
}
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import { text, background } from "./components"
|
||||
import { toggleable } from "../element"
|
||||
|
||||
export default function commandPalette(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest
|
||||
|
||||
export default function command_palette(theme: ColorScheme): any {
|
||||
const key = toggleable({
|
||||
base: {
|
||||
text: text(layer, "mono", "variant", "default", { size: "xs" }),
|
||||
cornerRadius: 2,
|
||||
background: background(layer, "on"),
|
||||
text: text(theme.highest, "mono", "variant", "default", {
|
||||
size: "xs",
|
||||
}),
|
||||
corner_radius: 2,
|
||||
background: background(theme.highest, "on"),
|
||||
padding: {
|
||||
top: 1,
|
||||
bottom: 1,
|
||||
@ -25,14 +25,16 @@ export default function commandPalette(colorScheme: ColorScheme) {
|
||||
},
|
||||
state: {
|
||||
active: {
|
||||
text: text(layer, "mono", "on", "default", { size: "xs" }),
|
||||
background: withOpacity(background(layer, "on"), 0.2),
|
||||
text: text(theme.highest, "mono", "on", "default", {
|
||||
size: "xs",
|
||||
}),
|
||||
background: with_opacity(background(theme.highest, "on"), 0.2),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
keystrokeSpacing: 8,
|
||||
keystroke_spacing: 8,
|
||||
// TODO: This should be a Toggle<ContainedText> on the rust side so we don't have to do this
|
||||
key: {
|
||||
inactive: { ...key.inactive },
|
@ -1,7 +1,7 @@
|
||||
import { fontFamilies, fontSizes, FontWeight } from "../common"
|
||||
import { Layer, Styles, StyleSets, Style } from "../theme/colorScheme"
|
||||
import { font_families, font_sizes, FontWeight } from "../common"
|
||||
import { Layer, Styles, StyleSets, Style } from "../theme/color_scheme"
|
||||
|
||||
function isStyleSet(key: any): key is StyleSets {
|
||||
function is_style_set(key: any): key is StyleSets {
|
||||
return [
|
||||
"base",
|
||||
"variant",
|
||||
@ -13,7 +13,7 @@ function isStyleSet(key: any): key is StyleSets {
|
||||
].includes(key)
|
||||
}
|
||||
|
||||
function isStyle(key: any): key is Styles {
|
||||
function is_style(key: any): key is Styles {
|
||||
return [
|
||||
"default",
|
||||
"active",
|
||||
@ -23,78 +23,70 @@ function isStyle(key: any): key is Styles {
|
||||
"inverted",
|
||||
].includes(key)
|
||||
}
|
||||
function getStyle(
|
||||
function get_style(
|
||||
layer: Layer,
|
||||
possibleStyleSetOrStyle?: any,
|
||||
possibleStyle?: any
|
||||
possible_style_set_or_style?: any,
|
||||
possible_style?: any
|
||||
): Style {
|
||||
let styleSet: StyleSets = "base"
|
||||
let style_set: StyleSets = "base"
|
||||
let style: Styles = "default"
|
||||
if (isStyleSet(possibleStyleSetOrStyle)) {
|
||||
styleSet = possibleStyleSetOrStyle
|
||||
} else if (isStyle(possibleStyleSetOrStyle)) {
|
||||
style = possibleStyleSetOrStyle
|
||||
if (is_style_set(possible_style_set_or_style)) {
|
||||
style_set = possible_style_set_or_style
|
||||
} else if (is_style(possible_style_set_or_style)) {
|
||||
style = possible_style_set_or_style
|
||||
}
|
||||
|
||||
if (isStyle(possibleStyle)) {
|
||||
style = possibleStyle
|
||||
if (is_style(possible_style)) {
|
||||
style = possible_style
|
||||
}
|
||||
|
||||
return layer[styleSet][style]
|
||||
return layer[style_set][style]
|
||||
}
|
||||
|
||||
export function background(layer: Layer, style?: Styles): string
|
||||
export function background(
|
||||
layer: Layer,
|
||||
styleSet?: StyleSets,
|
||||
style_set?: StyleSets,
|
||||
style?: Styles
|
||||
): string
|
||||
export function background(
|
||||
layer: Layer,
|
||||
styleSetOrStyles?: StyleSets | Styles,
|
||||
style_set_or_styles?: StyleSets | Styles,
|
||||
style?: Styles
|
||||
): string {
|
||||
return getStyle(layer, styleSetOrStyles, style).background
|
||||
return get_style(layer, style_set_or_styles, style).background
|
||||
}
|
||||
|
||||
export function borderColor(layer: Layer, style?: Styles): string
|
||||
export function borderColor(
|
||||
export function border_color(layer: Layer, style?: Styles): string
|
||||
export function border_color(
|
||||
layer: Layer,
|
||||
styleSet?: StyleSets,
|
||||
style_set?: StyleSets,
|
||||
style?: Styles
|
||||
): string
|
||||
export function borderColor(
|
||||
export function border_color(
|
||||
layer: Layer,
|
||||
styleSetOrStyles?: StyleSets | Styles,
|
||||
style_set_or_styles?: StyleSets | Styles,
|
||||
style?: Styles
|
||||
): string {
|
||||
return getStyle(layer, styleSetOrStyles, style).border
|
||||
return get_style(layer, style_set_or_styles, style).border
|
||||
}
|
||||
|
||||
export function foreground(layer: Layer, style?: Styles): string
|
||||
export function foreground(
|
||||
layer: Layer,
|
||||
styleSet?: StyleSets,
|
||||
style_set?: StyleSets,
|
||||
style?: Styles
|
||||
): string
|
||||
export function foreground(
|
||||
layer: Layer,
|
||||
styleSetOrStyles?: StyleSets | Styles,
|
||||
style_set_or_styles?: StyleSets | Styles,
|
||||
style?: Styles
|
||||
): string {
|
||||
return getStyle(layer, styleSetOrStyles, style).foreground
|
||||
}
|
||||
|
||||
interface Text extends Object {
|
||||
family: keyof typeof fontFamilies
|
||||
color: string
|
||||
size: number
|
||||
weight?: FontWeight
|
||||
underline?: boolean
|
||||
return get_style(layer, style_set_or_styles, style).foreground
|
||||
}
|
||||
|
||||
export interface TextStyle extends Object {
|
||||
family: keyof typeof fontFamilies
|
||||
family: keyof typeof font_families
|
||||
color: string
|
||||
size: number
|
||||
weight?: FontWeight
|
||||
@ -102,7 +94,7 @@ export interface TextStyle extends Object {
|
||||
}
|
||||
|
||||
export interface TextProperties {
|
||||
size?: keyof typeof fontSizes
|
||||
size?: keyof typeof font_sizes
|
||||
weight?: FontWeight
|
||||
underline?: boolean
|
||||
color?: string
|
||||
@ -182,49 +174,53 @@ interface FontFeatures {
|
||||
|
||||
export function text(
|
||||
layer: Layer,
|
||||
fontFamily: keyof typeof fontFamilies,
|
||||
styleSet: StyleSets,
|
||||
font_family: keyof typeof font_families,
|
||||
style_set: StyleSets,
|
||||
style: Styles,
|
||||
properties?: TextProperties
|
||||
): Text
|
||||
): TextStyle
|
||||
export function text(
|
||||
layer: Layer,
|
||||
fontFamily: keyof typeof fontFamilies,
|
||||
styleSet: StyleSets,
|
||||
font_family: keyof typeof font_families,
|
||||
style_set: StyleSets,
|
||||
properties?: TextProperties
|
||||
): Text
|
||||
): TextStyle
|
||||
export function text(
|
||||
layer: Layer,
|
||||
fontFamily: keyof typeof fontFamilies,
|
||||
font_family: keyof typeof font_families,
|
||||
style: Styles,
|
||||
properties?: TextProperties
|
||||
): Text
|
||||
): TextStyle
|
||||
export function text(
|
||||
layer: Layer,
|
||||
fontFamily: keyof typeof fontFamilies,
|
||||
font_family: keyof typeof font_families,
|
||||
properties?: TextProperties
|
||||
): Text
|
||||
): TextStyle
|
||||
export function text(
|
||||
layer: Layer,
|
||||
fontFamily: keyof typeof fontFamilies,
|
||||
styleSetStyleOrProperties?: StyleSets | Styles | TextProperties,
|
||||
styleOrProperties?: Styles | TextProperties,
|
||||
font_family: keyof typeof font_families,
|
||||
style_set_style_or_properties?: StyleSets | Styles | TextProperties,
|
||||
style_or_properties?: Styles | TextProperties,
|
||||
properties?: TextProperties
|
||||
) {
|
||||
let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
|
||||
const style = get_style(
|
||||
layer,
|
||||
style_set_style_or_properties,
|
||||
style_or_properties
|
||||
)
|
||||
|
||||
if (typeof styleSetStyleOrProperties === "object") {
|
||||
properties = styleSetStyleOrProperties
|
||||
if (typeof style_set_style_or_properties === "object") {
|
||||
properties = style_set_style_or_properties
|
||||
}
|
||||
if (typeof styleOrProperties === "object") {
|
||||
properties = styleOrProperties
|
||||
if (typeof style_or_properties === "object") {
|
||||
properties = style_or_properties
|
||||
}
|
||||
|
||||
let size = fontSizes[properties?.size || "sm"]
|
||||
let color = properties?.color || style.foreground
|
||||
const size = font_sizes[properties?.size || "sm"]
|
||||
const color = properties?.color || style.foreground
|
||||
|
||||
return {
|
||||
family: fontFamilies[fontFamily],
|
||||
family: font_families[font_family],
|
||||
...properties,
|
||||
color,
|
||||
size,
|
||||
@ -252,13 +248,13 @@ export interface BorderProperties {
|
||||
|
||||
export function border(
|
||||
layer: Layer,
|
||||
styleSet: StyleSets,
|
||||
style_set: StyleSets,
|
||||
style: Styles,
|
||||
properties?: BorderProperties
|
||||
): Border
|
||||
export function border(
|
||||
layer: Layer,
|
||||
styleSet: StyleSets,
|
||||
style_set: StyleSets,
|
||||
properties?: BorderProperties
|
||||
): Border
|
||||
export function border(
|
||||
@ -269,17 +265,17 @@ export function border(
|
||||
export function border(layer: Layer, properties?: BorderProperties): Border
|
||||
export function border(
|
||||
layer: Layer,
|
||||
styleSetStyleOrProperties?: StyleSets | Styles | BorderProperties,
|
||||
styleOrProperties?: Styles | BorderProperties,
|
||||
style_set_or_properties?: StyleSets | Styles | BorderProperties,
|
||||
style_or_properties?: Styles | BorderProperties,
|
||||
properties?: BorderProperties
|
||||
): Border {
|
||||
let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
|
||||
const style = get_style(layer, style_set_or_properties, style_or_properties)
|
||||
|
||||
if (typeof styleSetStyleOrProperties === "object") {
|
||||
properties = styleSetStyleOrProperties
|
||||
if (typeof style_set_or_properties === "object") {
|
||||
properties = style_set_or_properties
|
||||
}
|
||||
if (typeof styleOrProperties === "object") {
|
||||
properties = styleOrProperties
|
||||
if (typeof style_or_properties === "object") {
|
||||
properties = style_or_properties
|
||||
}
|
||||
|
||||
return {
|
||||
@ -291,9 +287,9 @@ export function border(
|
||||
|
||||
export function svg(
|
||||
color: string,
|
||||
asset: String,
|
||||
width: Number,
|
||||
height: Number
|
||||
asset: string,
|
||||
width: number,
|
||||
height: number
|
||||
) {
|
||||
return {
|
||||
color,
|
70
styles/src/style_tree/contact_finder.ts
Normal file
70
styles/src/style_tree/contact_finder.ts
Normal file
@ -0,0 +1,70 @@
|
||||
import picker from "./picker"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
|
||||
export default function contact_finder(theme: ColorScheme): any {
|
||||
const side_margin = 6
|
||||
const contact_button = {
|
||||
background: background(theme.middle, "variant"),
|
||||
color: foreground(theme.middle, "variant"),
|
||||
icon_width: 8,
|
||||
button_width: 16,
|
||||
corner_radius: 8,
|
||||
}
|
||||
|
||||
const picker_style = picker(theme)
|
||||
const picker_input = {
|
||||
background: background(theme.middle, "on"),
|
||||
corner_radius: 6,
|
||||
text: text(theme.middle, "mono"),
|
||||
placeholder_text: text(theme.middle, "mono", "on", "disabled", {
|
||||
size: "xs",
|
||||
}),
|
||||
selection: theme.players[0],
|
||||
border: border(theme.middle),
|
||||
padding: {
|
||||
bottom: 4,
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 4,
|
||||
},
|
||||
margin: {
|
||||
left: side_margin,
|
||||
right: side_margin,
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
picker: {
|
||||
empty_container: {},
|
||||
item: {
|
||||
...picker_style.item,
|
||||
margin: { left: side_margin, right: side_margin },
|
||||
},
|
||||
no_matches: picker_style.no_matches,
|
||||
input_editor: picker_input,
|
||||
empty_input_editor: picker_input,
|
||||
},
|
||||
row_height: 28,
|
||||
contact_avatar: {
|
||||
corner_radius: 10,
|
||||
width: 18,
|
||||
},
|
||||
contact_username: {
|
||||
padding: {
|
||||
left: 8,
|
||||
},
|
||||
},
|
||||
contact_button: {
|
||||
...contact_button,
|
||||
hover: {
|
||||
background: background(theme.middle, "variant", "hovered"),
|
||||
},
|
||||
},
|
||||
disabled_contact_button: {
|
||||
...contact_button,
|
||||
background: background(theme.middle, "disabled"),
|
||||
color: foreground(theme.middle, "disabled"),
|
||||
},
|
||||
}
|
||||
}
|
@ -1,56 +1,62 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { background, border, borderColor, foreground, text } from "./components"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import {
|
||||
background,
|
||||
border,
|
||||
border_color,
|
||||
foreground,
|
||||
text,
|
||||
} from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
const nameMargin = 8
|
||||
const sidePadding = 12
|
||||
export default function contacts_panel(theme: ColorScheme): any {
|
||||
const name_margin = 8
|
||||
const side_padding = 12
|
||||
|
||||
let layer = colorScheme.middle
|
||||
const layer = theme.middle
|
||||
|
||||
const contactButton = {
|
||||
const contact_button = {
|
||||
background: background(layer, "on"),
|
||||
color: foreground(layer, "on"),
|
||||
iconWidth: 8,
|
||||
buttonWidth: 16,
|
||||
cornerRadius: 8,
|
||||
icon_width: 8,
|
||||
button_width: 16,
|
||||
corner_radius: 8,
|
||||
}
|
||||
const projectRow = {
|
||||
guestAvatarSpacing: 4,
|
||||
const project_row = {
|
||||
guest_avatar_spacing: 4,
|
||||
height: 24,
|
||||
guestAvatar: {
|
||||
cornerRadius: 8,
|
||||
guest_avatar: {
|
||||
corner_radius: 8,
|
||||
width: 14,
|
||||
},
|
||||
name: {
|
||||
...text(layer, "mono", { size: "sm" }),
|
||||
margin: {
|
||||
left: nameMargin,
|
||||
left: name_margin,
|
||||
right: 6,
|
||||
},
|
||||
},
|
||||
guests: {
|
||||
margin: {
|
||||
left: nameMargin,
|
||||
right: nameMargin,
|
||||
left: name_margin,
|
||||
right: name_margin,
|
||||
},
|
||||
},
|
||||
padding: {
|
||||
left: sidePadding,
|
||||
right: sidePadding,
|
||||
left: side_padding,
|
||||
right: side_padding,
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
background: background(layer),
|
||||
padding: { top: 12 },
|
||||
userQueryEditor: {
|
||||
user_query_editor: {
|
||||
background: background(layer, "on"),
|
||||
cornerRadius: 6,
|
||||
corner_radius: 6,
|
||||
text: text(layer, "mono", "on"),
|
||||
placeholderText: text(layer, "mono", "on", "disabled", {
|
||||
placeholder_text: text(layer, "mono", "on", "disabled", {
|
||||
size: "xs",
|
||||
}),
|
||||
selection: colorScheme.players[0],
|
||||
selection: theme.players[0],
|
||||
border: border(layer, "on"),
|
||||
padding: {
|
||||
bottom: 4,
|
||||
@ -62,23 +68,23 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
left: 6,
|
||||
},
|
||||
},
|
||||
userQueryEditorHeight: 33,
|
||||
addContactButton: {
|
||||
user_query_editor_height: 33,
|
||||
add_contact_button: {
|
||||
margin: { left: 6, right: 12 },
|
||||
color: foreground(layer, "on"),
|
||||
buttonWidth: 28,
|
||||
iconWidth: 16,
|
||||
button_width: 28,
|
||||
icon_width: 16,
|
||||
},
|
||||
rowHeight: 28,
|
||||
sectionIconSize: 8,
|
||||
headerRow: toggleable({
|
||||
row_height: 28,
|
||||
section_icon_size: 8,
|
||||
header_row: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
...text(layer, "mono", { size: "sm" }),
|
||||
margin: { top: 14 },
|
||||
padding: {
|
||||
left: sidePadding,
|
||||
right: sidePadding,
|
||||
left: side_padding,
|
||||
right: side_padding,
|
||||
},
|
||||
background: background(layer, "default"), // posiewic: breaking change
|
||||
},
|
||||
@ -106,11 +112,11 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
}),
|
||||
leaveCall: interactive({
|
||||
leave_call: interactive({
|
||||
base: {
|
||||
background: background(layer),
|
||||
border: border(layer),
|
||||
cornerRadius: 6,
|
||||
corner_radius: 6,
|
||||
margin: {
|
||||
top: 1,
|
||||
},
|
||||
@ -130,12 +136,12 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
}),
|
||||
contactRow: {
|
||||
contact_row: {
|
||||
inactive: {
|
||||
default: {
|
||||
padding: {
|
||||
left: sidePadding,
|
||||
right: sidePadding,
|
||||
left: side_padding,
|
||||
right: side_padding,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -143,84 +149,83 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
default: {
|
||||
background: background(layer, "active"),
|
||||
padding: {
|
||||
left: sidePadding,
|
||||
right: sidePadding,
|
||||
left: side_padding,
|
||||
right: side_padding,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
contactAvatar: {
|
||||
cornerRadius: 10,
|
||||
contact_avatar: {
|
||||
corner_radius: 10,
|
||||
width: 18,
|
||||
},
|
||||
contactStatusFree: {
|
||||
cornerRadius: 4,
|
||||
contact_status_free: {
|
||||
corner_radius: 4,
|
||||
padding: 4,
|
||||
margin: { top: 12, left: 12 },
|
||||
background: foreground(layer, "positive"),
|
||||
},
|
||||
contactStatusBusy: {
|
||||
cornerRadius: 4,
|
||||
contact_status_busy: {
|
||||
corner_radius: 4,
|
||||
padding: 4,
|
||||
margin: { top: 12, left: 12 },
|
||||
background: foreground(layer, "negative"),
|
||||
},
|
||||
contactUsername: {
|
||||
contact_username: {
|
||||
...text(layer, "mono", { size: "sm" }),
|
||||
margin: {
|
||||
left: nameMargin,
|
||||
left: name_margin,
|
||||
},
|
||||
},
|
||||
contactButtonSpacing: nameMargin,
|
||||
contactButton: interactive({
|
||||
base: { ...contactButton },
|
||||
contact_button_spacing: name_margin,
|
||||
contact_button: interactive({
|
||||
base: { ...contact_button },
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
disabledButton: {
|
||||
...contactButton,
|
||||
disabled_button: {
|
||||
...contact_button,
|
||||
background: background(layer, "on"),
|
||||
color: foreground(layer, "on"),
|
||||
},
|
||||
callingIndicator: {
|
||||
calling_indicator: {
|
||||
...text(layer, "mono", "variant", { size: "xs" }),
|
||||
},
|
||||
treeBranch: toggleable({
|
||||
tree_branch: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
color: borderColor(layer),
|
||||
color: border_color(layer),
|
||||
width: 1,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: borderColor(layer),
|
||||
color: border_color(layer),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
color: borderColor(layer),
|
||||
color: border_color(layer),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
projectRow: toggleable({
|
||||
project_row: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
...projectRow,
|
||||
...project_row,
|
||||
background: background(layer),
|
||||
icon: {
|
||||
margin: { left: nameMargin },
|
||||
margin: { left: name_margin },
|
||||
color: foreground(layer, "variant"),
|
||||
width: 12,
|
||||
},
|
||||
name: {
|
||||
...projectRow.name,
|
||||
...project_row.name,
|
||||
...text(layer, "mono", { size: "sm" }),
|
||||
},
|
||||
},
|
53
styles/src/style_tree/contact_notification.ts
Normal file
53
styles/src/style_tree/contact_notification.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, foreground, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function contact_notification(theme: ColorScheme): any {
|
||||
const avatar_size = 12
|
||||
const header_padding = 8
|
||||
|
||||
return {
|
||||
header_avatar: {
|
||||
height: avatar_size,
|
||||
width: avatar_size,
|
||||
corner_radius: 6,
|
||||
},
|
||||
header_message: {
|
||||
...text(theme.lowest, "sans", { size: "xs" }),
|
||||
margin: { left: header_padding, right: header_padding },
|
||||
},
|
||||
header_height: 18,
|
||||
body_message: {
|
||||
...text(theme.lowest, "sans", { size: "xs" }),
|
||||
margin: { left: avatar_size + header_padding, top: 6, bottom: 6 },
|
||||
},
|
||||
button: interactive({
|
||||
base: {
|
||||
...text(theme.lowest, "sans", "on", { size: "xs" }),
|
||||
background: background(theme.lowest, "on"),
|
||||
padding: 4,
|
||||
corner_radius: 6,
|
||||
margin: { left: 6 },
|
||||
},
|
||||
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(theme.lowest, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
dismiss_button: {
|
||||
default: {
|
||||
color: foreground(theme.lowest, "variant"),
|
||||
icon_width: 8,
|
||||
icon_height: 8,
|
||||
button_width: 8,
|
||||
button_height: 8,
|
||||
hover: {
|
||||
color: foreground(theme.lowest, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
14
styles/src/style_tree/contacts_popover.ts
Normal file
14
styles/src/style_tree/contacts_popover.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border } from "./components"
|
||||
|
||||
export default function contacts_popover(theme: ColorScheme): any {
|
||||
return {
|
||||
background: background(theme.middle),
|
||||
corner_radius: 6,
|
||||
padding: { top: 6, bottom: 6 },
|
||||
shadow: theme.popover_shadow,
|
||||
border: border(theme.middle),
|
||||
width: 300,
|
||||
height: 400,
|
||||
}
|
||||
}
|
68
styles/src/style_tree/context_menu.ts
Normal file
68
styles/src/style_tree/context_menu.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, border_color, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function context_menu(theme: ColorScheme): any {
|
||||
return {
|
||||
background: background(theme.middle),
|
||||
corner_radius: 10,
|
||||
padding: 4,
|
||||
shadow: theme.popover_shadow,
|
||||
border: border(theme.middle),
|
||||
keystroke_margin: 30,
|
||||
item: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
icon_spacing: 8,
|
||||
icon_width: 14,
|
||||
padding: { left: 6, right: 6, top: 2, bottom: 2 },
|
||||
corner_radius: 6,
|
||||
label: text(theme.middle, "sans", { size: "sm" }),
|
||||
keystroke: {
|
||||
...text(theme.middle, "sans", "variant", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
padding: { left: 3, right: 3 },
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(theme.middle, "hovered"),
|
||||
label: text(theme.middle, "sans", "hovered", {
|
||||
size: "sm",
|
||||
}),
|
||||
keystroke: {
|
||||
...text(theme.middle, "sans", "hovered", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
padding: { left: 3, right: 3 },
|
||||
},
|
||||
},
|
||||
clicked: {
|
||||
background: background(theme.middle, "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
background: background(theme.middle, "active"),
|
||||
},
|
||||
hovered: {
|
||||
background: background(theme.middle, "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
background: background(theme.middle, "pressed"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
separator: {
|
||||
background: border_color(theme.middle),
|
||||
margin: { top: 2, bottom: 2 },
|
||||
},
|
||||
}
|
||||
}
|
@ -1,18 +1,16 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, foreground, svg, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
export default function copilot(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle
|
||||
export default function copilot(theme: ColorScheme): any {
|
||||
const content_width = 264
|
||||
|
||||
let content_width = 264
|
||||
|
||||
let ctaButton =
|
||||
const cta_button =
|
||||
// Copied from welcome screen. FIXME: Move this into a ZDS component
|
||||
interactive({
|
||||
base: {
|
||||
background: background(layer),
|
||||
border: border(layer, "default"),
|
||||
cornerRadius: 4,
|
||||
background: background(theme.middle),
|
||||
border: border(theme.middle, "default"),
|
||||
corner_radius: 4,
|
||||
margin: {
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
@ -25,49 +23,52 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
...text(layer, "sans", "default", { size: "sm" }),
|
||||
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(layer, "sans", "default", { size: "sm" }),
|
||||
background: background(layer, "hovered"),
|
||||
border: border(layer, "active"),
|
||||
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||
background: background(theme.middle, "hovered"),
|
||||
border: border(theme.middle, "active"),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
outLinkIcon: interactive({
|
||||
out_link_icon: interactive({
|
||||
base: {
|
||||
icon: svg(
|
||||
foreground(layer, "variant"),
|
||||
foreground(theme.middle, "variant"),
|
||||
"icons/link_out_12.svg",
|
||||
12,
|
||||
12
|
||||
),
|
||||
container: {
|
||||
cornerRadius: 6,
|
||||
corner_radius: 6,
|
||||
padding: { left: 6 },
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
icon: {
|
||||
color: foreground(layer, "hovered"),
|
||||
color: foreground(theme.middle, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
modal: {
|
||||
titleText: {
|
||||
title_text: {
|
||||
default: {
|
||||
...text(layer, "sans", { size: "xs", weight: "bold" }),
|
||||
...text(theme.middle, "sans", {
|
||||
size: "xs",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
},
|
||||
titlebar: {
|
||||
background: background(colorScheme.lowest),
|
||||
border: border(layer, "active"),
|
||||
background: background(theme.lowest),
|
||||
border: border(theme.middle, "active"),
|
||||
padding: {
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
@ -76,7 +77,7 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
container: {
|
||||
background: background(colorScheme.lowest),
|
||||
background: background(theme.lowest),
|
||||
padding: {
|
||||
top: 0,
|
||||
left: 0,
|
||||
@ -84,16 +85,16 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
bottom: 8,
|
||||
},
|
||||
},
|
||||
closeIcon: interactive({
|
||||
close_icon: interactive({
|
||||
base: {
|
||||
icon: svg(
|
||||
foreground(layer, "variant"),
|
||||
foreground(theme.middle, "variant"),
|
||||
"icons/x_mark_8.svg",
|
||||
8,
|
||||
8
|
||||
),
|
||||
container: {
|
||||
cornerRadius: 2,
|
||||
corner_radius: 2,
|
||||
padding: {
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
@ -108,7 +109,7 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
hovered: {
|
||||
icon: svg(
|
||||
foreground(layer, "on"),
|
||||
foreground(theme.middle, "on"),
|
||||
"icons/x_mark_8.svg",
|
||||
8,
|
||||
8
|
||||
@ -116,7 +117,7 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
clicked: {
|
||||
icon: svg(
|
||||
foreground(layer, "base"),
|
||||
foreground(theme.middle, "base"),
|
||||
"icons/x_mark_8.svg",
|
||||
8,
|
||||
8
|
||||
@ -133,11 +134,11 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
auth: {
|
||||
content_width,
|
||||
|
||||
ctaButton,
|
||||
cta_button,
|
||||
|
||||
header: {
|
||||
icon: svg(
|
||||
foreground(layer, "default"),
|
||||
foreground(theme.middle, "default"),
|
||||
"icons/zed_plus_copilot_32.svg",
|
||||
92,
|
||||
32
|
||||
@ -154,7 +155,7 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
|
||||
prompting: {
|
||||
subheading: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
...text(theme.middle, "sans", { size: "xs" }),
|
||||
margin: {
|
||||
top: 6,
|
||||
bottom: 12,
|
||||
@ -164,19 +165,22 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
|
||||
hint: {
|
||||
...text(layer, "sans", { size: "xs", color: "#838994" }),
|
||||
...text(theme.middle, "sans", {
|
||||
size: "xs",
|
||||
color: "#838994",
|
||||
}),
|
||||
margin: {
|
||||
top: 6,
|
||||
bottom: 2,
|
||||
},
|
||||
},
|
||||
|
||||
deviceCode: {
|
||||
text: text(layer, "mono", { size: "sm" }),
|
||||
device_code: {
|
||||
text: text(theme.middle, "mono", { size: "sm" }),
|
||||
cta: {
|
||||
...ctaButton,
|
||||
background: background(colorScheme.lowest),
|
||||
border: border(colorScheme.lowest, "inverted"),
|
||||
...cta_button,
|
||||
background: background(theme.lowest),
|
||||
border: border(theme.lowest, "inverted"),
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
@ -189,7 +193,7 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
left: content_width / 2,
|
||||
leftContainer: {
|
||||
left_container: {
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
@ -198,9 +202,9 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
right: (content_width * 1) / 3,
|
||||
rightContainer: interactive({
|
||||
right_container: interactive({
|
||||
base: {
|
||||
border: border(colorScheme.lowest, "inverted", {
|
||||
border: border(theme.lowest, "inverted", {
|
||||
bottom: false,
|
||||
right: false,
|
||||
top: false,
|
||||
@ -215,7 +219,7 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
border: border(layer, "active", {
|
||||
border: border(theme.middle, "active", {
|
||||
bottom: false,
|
||||
right: false,
|
||||
top: false,
|
||||
@ -227,9 +231,9 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
|
||||
notAuthorized: {
|
||||
not_authorized: {
|
||||
subheading: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
...text(theme.middle, "sans", { size: "xs" }),
|
||||
|
||||
margin: {
|
||||
top: 16,
|
||||
@ -240,13 +244,13 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
|
||||
warning: {
|
||||
...text(layer, "sans", {
|
||||
...text(theme.middle, "sans", {
|
||||
size: "xs",
|
||||
color: foreground(layer, "warning"),
|
||||
color: foreground(theme.middle, "warning"),
|
||||
}),
|
||||
border: border(layer, "warning"),
|
||||
background: background(layer, "warning"),
|
||||
cornerRadius: 2,
|
||||
border: border(theme.middle, "warning"),
|
||||
background: background(theme.middle, "warning"),
|
||||
corner_radius: 2,
|
||||
padding: {
|
||||
top: 4,
|
||||
left: 4,
|
||||
@ -263,7 +267,7 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
|
||||
authorized: {
|
||||
subheading: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
...text(theme.middle, "sans", { size: "xs" }),
|
||||
|
||||
margin: {
|
||||
top: 16,
|
||||
@ -272,7 +276,10 @@ export default function copilot(colorScheme: ColorScheme) {
|
||||
},
|
||||
|
||||
hint: {
|
||||
...text(layer, "sans", { size: "xs", color: "#838994" }),
|
||||
...text(theme.middle, "sans", {
|
||||
size: "xs",
|
||||
color: "#838994",
|
||||
}),
|
||||
margin: {
|
||||
top: 24,
|
||||
bottom: 4,
|
312
styles/src/style_tree/editor.ts
Normal file
312
styles/src/style_tree/editor.ts
Normal file
@ -0,0 +1,312 @@
|
||||
import { with_opacity } from "../theme/color"
|
||||
import { ColorScheme, Layer, StyleSets } from "../theme/color_scheme"
|
||||
import {
|
||||
background,
|
||||
border,
|
||||
border_color,
|
||||
foreground,
|
||||
text,
|
||||
} from "./components"
|
||||
import hover_popover from "./hover_popover"
|
||||
|
||||
import { build_syntax } from "../theme/syntax"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function editor(theme: ColorScheme): any {
|
||||
const { is_light } = theme
|
||||
|
||||
const layer = theme.highest
|
||||
|
||||
const autocomplete_item = {
|
||||
corner_radius: 6,
|
||||
padding: {
|
||||
bottom: 2,
|
||||
left: 6,
|
||||
right: 6,
|
||||
top: 2,
|
||||
},
|
||||
}
|
||||
|
||||
function diagnostic(layer: Layer, style_set: StyleSets) {
|
||||
return {
|
||||
text_scale_factor: 0.857,
|
||||
header: {
|
||||
border: border(layer, {
|
||||
top: true,
|
||||
}),
|
||||
},
|
||||
message: {
|
||||
text: text(layer, "sans", style_set, "default", { size: "sm" }),
|
||||
highlight_text: text(layer, "sans", style_set, "default", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const syntax = build_syntax(theme)
|
||||
|
||||
return {
|
||||
text_color: syntax.primary.color,
|
||||
background: background(layer),
|
||||
active_line_background: with_opacity(background(layer, "on"), 0.75),
|
||||
highlighted_line_background: background(layer, "on"),
|
||||
// Inline autocomplete suggestions, Co-pilot suggestions, etc.
|
||||
suggestion: syntax.predictive,
|
||||
code_actions: {
|
||||
indicator: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "variant"),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "variant", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(layer, "variant", "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
color: foreground(layer, "accent"),
|
||||
},
|
||||
hovered: {
|
||||
color: foreground(layer, "accent", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(layer, "accent", "pressed"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
vertical_scale: 0.55,
|
||||
},
|
||||
folds: {
|
||||
icon_margin_scale: 2.5,
|
||||
folded_icon: "icons/chevron_right_8.svg",
|
||||
foldable_icon: "icons/chevron_down_8.svg",
|
||||
indicator: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "variant"),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(layer, "on"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(layer, "base"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
color: foreground(layer, "default"),
|
||||
},
|
||||
hovered: {
|
||||
color: foreground(layer, "variant"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
ellipses: {
|
||||
text_color: theme.ramps.neutral(0.71).hex(),
|
||||
corner_radius_factor: 0.15,
|
||||
background: {
|
||||
// Copied from hover_popover highlight
|
||||
default: {
|
||||
color: theme.ramps.neutral(0.5).alpha(0.0).hex(),
|
||||
},
|
||||
|
||||
hovered: {
|
||||
color: theme.ramps.neutral(0.5).alpha(0.5).hex(),
|
||||
},
|
||||
|
||||
clicked: {
|
||||
color: theme.ramps.neutral(0.5).alpha(0.7).hex(),
|
||||
},
|
||||
},
|
||||
},
|
||||
fold_background: foreground(layer, "variant"),
|
||||
},
|
||||
diff: {
|
||||
deleted: is_light
|
||||
? theme.ramps.red(0.5).hex()
|
||||
: theme.ramps.red(0.4).hex(),
|
||||
modified: is_light
|
||||
? theme.ramps.yellow(0.5).hex()
|
||||
: theme.ramps.yellow(0.5).hex(),
|
||||
inserted: is_light
|
||||
? theme.ramps.green(0.4).hex()
|
||||
: theme.ramps.green(0.5).hex(),
|
||||
removed_width_em: 0.275,
|
||||
width_em: 0.15,
|
||||
corner_radius: 0.05,
|
||||
},
|
||||
/** Highlights matching occurrences of what is under the cursor
|
||||
* as well as matched brackets
|
||||
*/
|
||||
document_highlight_read_background: with_opacity(
|
||||
foreground(layer, "accent"),
|
||||
0.1
|
||||
),
|
||||
document_highlight_write_background: theme.ramps
|
||||
.neutral(0.5)
|
||||
.alpha(0.4)
|
||||
.hex(), // TODO: This was blend * 2
|
||||
error_color: background(layer, "negative"),
|
||||
gutter_background: background(layer),
|
||||
gutter_padding_factor: 3.5,
|
||||
line_number: with_opacity(foreground(layer), 0.35),
|
||||
line_number_active: foreground(layer),
|
||||
rename_fade: 0.6,
|
||||
unnecessary_code_fade: 0.5,
|
||||
selection: theme.players[0],
|
||||
whitespace: theme.ramps.neutral(0.5).hex(),
|
||||
guest_selections: [
|
||||
theme.players[1],
|
||||
theme.players[2],
|
||||
theme.players[3],
|
||||
theme.players[4],
|
||||
theme.players[5],
|
||||
theme.players[6],
|
||||
theme.players[7],
|
||||
],
|
||||
autocomplete: {
|
||||
background: background(theme.middle),
|
||||
corner_radius: 8,
|
||||
padding: 4,
|
||||
margin: {
|
||||
left: -14,
|
||||
},
|
||||
border: border(theme.middle),
|
||||
shadow: theme.popover_shadow,
|
||||
match_highlight: foreground(theme.middle, "accent"),
|
||||
item: autocomplete_item,
|
||||
hovered_item: {
|
||||
...autocomplete_item,
|
||||
match_highlight: foreground(theme.middle, "accent", "hovered"),
|
||||
background: background(theme.middle, "hovered"),
|
||||
},
|
||||
selected_item: {
|
||||
...autocomplete_item,
|
||||
match_highlight: foreground(theme.middle, "accent", "active"),
|
||||
background: background(theme.middle, "active"),
|
||||
},
|
||||
},
|
||||
diagnostic_header: {
|
||||
background: background(theme.middle),
|
||||
icon_width_factor: 1.5,
|
||||
text_scale_factor: 0.857,
|
||||
border: border(theme.middle, {
|
||||
bottom: true,
|
||||
top: true,
|
||||
}),
|
||||
code: {
|
||||
...text(theme.middle, "mono", { size: "sm" }),
|
||||
margin: {
|
||||
left: 10,
|
||||
},
|
||||
},
|
||||
source: {
|
||||
text: text(theme.middle, "sans", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
message: {
|
||||
highlight_text: text(theme.middle, "sans", {
|
||||
size: "sm",
|
||||
weight: "bold",
|
||||
}),
|
||||
text: text(theme.middle, "sans", { size: "sm" }),
|
||||
},
|
||||
},
|
||||
diagnostic_path_header: {
|
||||
background: background(theme.middle),
|
||||
text_scale_factor: 0.857,
|
||||
filename: text(theme.middle, "mono", { size: "sm" }),
|
||||
path: {
|
||||
...text(theme.middle, "mono", { size: "sm" }),
|
||||
margin: {
|
||||
left: 12,
|
||||
},
|
||||
},
|
||||
},
|
||||
error_diagnostic: diagnostic(theme.middle, "negative"),
|
||||
warning_diagnostic: diagnostic(theme.middle, "warning"),
|
||||
information_diagnostic: diagnostic(theme.middle, "accent"),
|
||||
hint_diagnostic: diagnostic(theme.middle, "warning"),
|
||||
invalid_error_diagnostic: diagnostic(theme.middle, "base"),
|
||||
invalid_hint_diagnostic: diagnostic(theme.middle, "base"),
|
||||
invalid_information_diagnostic: diagnostic(theme.middle, "base"),
|
||||
invalid_warning_diagnostic: diagnostic(theme.middle, "base"),
|
||||
hover_popover: hover_popover(theme),
|
||||
link_definition: {
|
||||
color: syntax.link_uri.color,
|
||||
underline: syntax.link_uri.underline,
|
||||
},
|
||||
jump_icon: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "on"),
|
||||
icon_width: 20,
|
||||
button_width: 20,
|
||||
corner_radius: 6,
|
||||
padding: {
|
||||
top: 6,
|
||||
bottom: 6,
|
||||
left: 6,
|
||||
right: 6,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(layer, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
scrollbar: {
|
||||
width: 12,
|
||||
min_height_factor: 1.0,
|
||||
track: {
|
||||
border: border(layer, "variant", { left: true }),
|
||||
},
|
||||
thumb: {
|
||||
background: with_opacity(background(layer, "inverted"), 0.3),
|
||||
border: {
|
||||
width: 1,
|
||||
color: border_color(layer, "variant"),
|
||||
top: false,
|
||||
right: true,
|
||||
left: true,
|
||||
bottom: false,
|
||||
},
|
||||
},
|
||||
git: {
|
||||
deleted: is_light
|
||||
? with_opacity(theme.ramps.red(0.5).hex(), 0.8)
|
||||
: with_opacity(theme.ramps.red(0.4).hex(), 0.8),
|
||||
modified: is_light
|
||||
? with_opacity(theme.ramps.yellow(0.5).hex(), 0.8)
|
||||
: with_opacity(theme.ramps.yellow(0.4).hex(), 0.8),
|
||||
inserted: is_light
|
||||
? with_opacity(theme.ramps.green(0.5).hex(), 0.8)
|
||||
: with_opacity(theme.ramps.green(0.4).hex(), 0.8),
|
||||
},
|
||||
},
|
||||
composition_mark: {
|
||||
underline: {
|
||||
thickness: 1.0,
|
||||
color: border_color(layer),
|
||||
},
|
||||
},
|
||||
syntax,
|
||||
}
|
||||
}
|
49
styles/src/style_tree/feedback.ts
Normal file
49
styles/src/style_tree/feedback.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function feedback(theme: ColorScheme): any {
|
||||
return {
|
||||
submit_button: interactive({
|
||||
base: {
|
||||
...text(theme.highest, "mono", "on"),
|
||||
background: background(theme.highest, "on"),
|
||||
corner_radius: 6,
|
||||
border: border(theme.highest, "on"),
|
||||
margin: {
|
||||
right: 4,
|
||||
},
|
||||
padding: {
|
||||
bottom: 2,
|
||||
left: 10,
|
||||
right: 10,
|
||||
top: 2,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
clicked: {
|
||||
...text(theme.highest, "mono", "on", "pressed"),
|
||||
background: background(theme.highest, "on", "pressed"),
|
||||
border: border(theme.highest, "on", "pressed"),
|
||||
},
|
||||
hovered: {
|
||||
...text(theme.highest, "mono", "on", "hovered"),
|
||||
background: background(theme.highest, "on", "hovered"),
|
||||
border: border(theme.highest, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
button_margin: 8,
|
||||
info_text_default: text(theme.highest, "sans", "default", {
|
||||
size: "xs",
|
||||
}),
|
||||
link_text_default: text(theme.highest, "sans", "default", {
|
||||
size: "xs",
|
||||
underline: true,
|
||||
}),
|
||||
link_text_hover: text(theme.highest, "sans", "hovered", {
|
||||
size: "xs",
|
||||
underline: true,
|
||||
}),
|
||||
}
|
||||
}
|
47
styles/src/style_tree/hover_popover.ts
Normal file
47
styles/src/style_tree/hover_popover.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
|
||||
export default function hover_popover(theme: ColorScheme): any {
|
||||
const base_container = {
|
||||
background: background(theme.middle),
|
||||
corner_radius: 8,
|
||||
padding: {
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
},
|
||||
shadow: theme.popover_shadow,
|
||||
border: border(theme.middle),
|
||||
margin: {
|
||||
left: -8,
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
container: base_container,
|
||||
info_container: {
|
||||
...base_container,
|
||||
background: background(theme.middle, "accent"),
|
||||
border: border(theme.middle, "accent"),
|
||||
},
|
||||
warning_container: {
|
||||
...base_container,
|
||||
background: background(theme.middle, "warning"),
|
||||
border: border(theme.middle, "warning"),
|
||||
},
|
||||
error_container: {
|
||||
...base_container,
|
||||
background: background(theme.middle, "negative"),
|
||||
border: border(theme.middle, "negative"),
|
||||
},
|
||||
block_style: {
|
||||
padding: { top: 4 },
|
||||
},
|
||||
prose: text(theme.middle, "sans", { size: "sm" }),
|
||||
diagnostic_source_highlight: {
|
||||
color: foreground(theme.middle, "accent"),
|
||||
},
|
||||
highlight: theme.ramps.neutral(0.5).alpha(0.2).hex(), // TODO: blend was used here. Replace with something better
|
||||
}
|
||||
}
|
55
styles/src/style_tree/incoming_call_notification.ts
Normal file
55
styles/src/style_tree/incoming_call_notification.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, text } from "./components"
|
||||
|
||||
export default function incoming_call_notification(
|
||||
theme: ColorScheme
|
||||
): unknown {
|
||||
const avatar_size = 48
|
||||
return {
|
||||
window_height: 74,
|
||||
window_width: 380,
|
||||
background: background(theme.middle),
|
||||
caller_container: {
|
||||
padding: 12,
|
||||
},
|
||||
caller_avatar: {
|
||||
height: avatar_size,
|
||||
width: avatar_size,
|
||||
corner_radius: avatar_size / 2,
|
||||
},
|
||||
caller_metadata: {
|
||||
margin: { left: 10 },
|
||||
},
|
||||
caller_username: {
|
||||
...text(theme.middle, "sans", { size: "sm", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
caller_message: {
|
||||
...text(theme.middle, "sans", "variant", { size: "xs" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
worktree_roots: {
|
||||
...text(theme.middle, "sans", "variant", {
|
||||
size: "xs",
|
||||
weight: "bold",
|
||||
}),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
button_width: 96,
|
||||
accept_button: {
|
||||
background: background(theme.middle, "accent"),
|
||||
border: border(theme.middle, { left: true, bottom: true }),
|
||||
...text(theme.middle, "sans", "positive", {
|
||||
size: "xs",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
decline_button: {
|
||||
border: border(theme.middle, { left: true }),
|
||||
...text(theme.middle, "sans", "negative", {
|
||||
size: "xs",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
@ -1,24 +1,23 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import { background, border, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function picker(colorScheme: ColorScheme): any {
|
||||
let layer = colorScheme.lowest
|
||||
export default function picker(theme: ColorScheme): any {
|
||||
const container = {
|
||||
background: background(layer),
|
||||
border: border(layer),
|
||||
shadow: colorScheme.modalShadow,
|
||||
cornerRadius: 12,
|
||||
background: background(theme.lowest),
|
||||
border: border(theme.lowest),
|
||||
shadow: theme.modal_shadow,
|
||||
corner_radius: 12,
|
||||
padding: {
|
||||
bottom: 4,
|
||||
},
|
||||
}
|
||||
const inputEditor = {
|
||||
placeholderText: text(layer, "sans", "on", "disabled"),
|
||||
selection: colorScheme.players[0],
|
||||
text: text(layer, "mono", "on"),
|
||||
border: border(layer, { bottom: true }),
|
||||
const input_editor = {
|
||||
placeholder_text: text(theme.lowest, "sans", "on", "disabled"),
|
||||
selection: theme.players[0],
|
||||
text: text(theme.lowest, "mono", "on"),
|
||||
border: border(theme.lowest, { bottom: true }),
|
||||
padding: {
|
||||
bottom: 8,
|
||||
left: 16,
|
||||
@ -29,13 +28,13 @@ export default function picker(colorScheme: ColorScheme): any {
|
||||
bottom: 4,
|
||||
},
|
||||
}
|
||||
const emptyInputEditor: any = { ...inputEditor }
|
||||
delete emptyInputEditor.border
|
||||
delete emptyInputEditor.margin
|
||||
const empty_input_editor: any = { ...input_editor }
|
||||
delete empty_input_editor.border
|
||||
delete empty_input_editor.margin
|
||||
|
||||
return {
|
||||
...container,
|
||||
emptyContainer: {
|
||||
empty_container: {
|
||||
...container,
|
||||
padding: {},
|
||||
},
|
||||
@ -53,22 +52,22 @@ export default function picker(colorScheme: ColorScheme): any {
|
||||
left: 4,
|
||||
right: 4,
|
||||
},
|
||||
cornerRadius: 8,
|
||||
text: text(layer, "sans", "variant"),
|
||||
highlightText: text(layer, "sans", "accent", {
|
||||
corner_radius: 8,
|
||||
text: text(theme.lowest, "sans", "variant"),
|
||||
highlight_text: text(theme.lowest, "sans", "accent", {
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: withOpacity(
|
||||
background(layer, "hovered"),
|
||||
background: with_opacity(
|
||||
background(theme.lowest, "hovered"),
|
||||
0.5
|
||||
),
|
||||
},
|
||||
clicked: {
|
||||
background: withOpacity(
|
||||
background(layer, "pressed"),
|
||||
background: with_opacity(
|
||||
background(theme.lowest, "pressed"),
|
||||
0.5
|
||||
),
|
||||
},
|
||||
@ -77,20 +76,20 @@ export default function picker(colorScheme: ColorScheme): any {
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
background: withOpacity(
|
||||
background(layer, "base", "active"),
|
||||
background: with_opacity(
|
||||
background(theme.lowest, "base", "active"),
|
||||
0.5
|
||||
),
|
||||
},
|
||||
hovered: {
|
||||
background: withOpacity(
|
||||
background(layer, "hovered"),
|
||||
background: with_opacity(
|
||||
background(theme.lowest, "hovered"),
|
||||
0.5
|
||||
),
|
||||
},
|
||||
clicked: {
|
||||
background: withOpacity(
|
||||
background(layer, "pressed"),
|
||||
background: with_opacity(
|
||||
background(theme.lowest, "pressed"),
|
||||
0.5
|
||||
),
|
||||
},
|
||||
@ -98,10 +97,10 @@ export default function picker(colorScheme: ColorScheme): any {
|
||||
},
|
||||
}),
|
||||
|
||||
inputEditor,
|
||||
emptyInputEditor,
|
||||
noMatches: {
|
||||
text: text(layer, "sans", "variant"),
|
||||
input_editor,
|
||||
empty_input_editor,
|
||||
no_matches: {
|
||||
text: text(theme.lowest, "sans", "variant"),
|
||||
padding: {
|
||||
bottom: 8,
|
||||
left: 16,
|
12
styles/src/style_tree/project_diagnostics.ts
Normal file
12
styles/src/style_tree/project_diagnostics.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, text } from "./components"
|
||||
|
||||
export default function project_diagnostics(theme: ColorScheme): any {
|
||||
return {
|
||||
background: background(theme.highest),
|
||||
tab_icon_spacing: 4,
|
||||
tab_icon_width: 13,
|
||||
tab_summary_spacing: 10,
|
||||
empty_message: text(theme.highest, "sans", "variant", { size: "md" }),
|
||||
}
|
||||
}
|
188
styles/src/style_tree/project_panel.ts
Normal file
188
styles/src/style_tree/project_panel.ts
Normal file
@ -0,0 +1,188 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import {
|
||||
Border,
|
||||
TextStyle,
|
||||
background,
|
||||
border,
|
||||
foreground,
|
||||
text,
|
||||
} from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
import merge from "ts-deepmerge"
|
||||
export default function project_panel(theme: ColorScheme): any {
|
||||
const { is_light } = theme
|
||||
|
||||
type EntryStateProps = {
|
||||
background?: string
|
||||
border?: Border
|
||||
text?: TextStyle
|
||||
icon_color?: string
|
||||
}
|
||||
|
||||
type EntryState = {
|
||||
default: EntryStateProps
|
||||
hovered?: EntryStateProps
|
||||
clicked?: EntryStateProps
|
||||
}
|
||||
|
||||
const entry = (unselected?: EntryState, selected?: EntryState) => {
|
||||
const git_status = {
|
||||
git: {
|
||||
modified: is_light
|
||||
? theme.ramps.yellow(0.6).hex()
|
||||
: theme.ramps.yellow(0.5).hex(),
|
||||
inserted: is_light
|
||||
? theme.ramps.green(0.45).hex()
|
||||
: theme.ramps.green(0.5).hex(),
|
||||
conflict: is_light
|
||||
? theme.ramps.red(0.6).hex()
|
||||
: theme.ramps.red(0.5).hex(),
|
||||
},
|
||||
}
|
||||
|
||||
const base_properties = {
|
||||
height: 22,
|
||||
background: background(theme.middle),
|
||||
icon_color: foreground(theme.middle, "variant"),
|
||||
icon_size: 7,
|
||||
icon_spacing: 5,
|
||||
text: text(theme.middle, "mono", "variant", { size: "sm" }),
|
||||
status: {
|
||||
...git_status,
|
||||
},
|
||||
}
|
||||
|
||||
const selected_style: EntryState | undefined = selected
|
||||
? selected
|
||||
: unselected
|
||||
|
||||
const unselected_default_style = merge(
|
||||
base_properties,
|
||||
unselected?.default ?? {},
|
||||
{}
|
||||
)
|
||||
const unselected_hovered_style = merge(
|
||||
base_properties,
|
||||
unselected?.hovered ?? {},
|
||||
{ background: background(theme.middle, "variant", "hovered") }
|
||||
)
|
||||
const unselected_clicked_style = merge(
|
||||
base_properties,
|
||||
unselected?.clicked ?? {},
|
||||
{ background: background(theme.middle, "variant", "pressed") }
|
||||
)
|
||||
const selected_default_style = merge(
|
||||
base_properties,
|
||||
selected_style?.default ?? {},
|
||||
{ background: background(theme.middle) }
|
||||
)
|
||||
const selected_hovered_style = merge(
|
||||
base_properties,
|
||||
selected_style?.hovered ?? {},
|
||||
{ background: background(theme.middle, "variant", "hovered") }
|
||||
)
|
||||
const selected_clicked_style = merge(
|
||||
base_properties,
|
||||
selected_style?.clicked ?? {},
|
||||
{ background: background(theme.middle, "variant", "pressed") }
|
||||
)
|
||||
|
||||
return toggleable({
|
||||
state: {
|
||||
inactive: interactive({
|
||||
state: {
|
||||
default: unselected_default_style,
|
||||
hovered: unselected_hovered_style,
|
||||
clicked: unselected_clicked_style,
|
||||
},
|
||||
}),
|
||||
active: interactive({
|
||||
state: {
|
||||
default: selected_default_style,
|
||||
hovered: selected_hovered_style,
|
||||
clicked: selected_clicked_style,
|
||||
},
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const default_entry = entry()
|
||||
|
||||
return {
|
||||
open_project_button: interactive({
|
||||
base: {
|
||||
background: background(theme.middle),
|
||||
border: border(theme.middle, "active"),
|
||||
corner_radius: 4,
|
||||
margin: {
|
||||
top: 16,
|
||||
left: 16,
|
||||
right: 16,
|
||||
},
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||
background: background(theme.middle, "hovered"),
|
||||
border: border(theme.middle, "active"),
|
||||
},
|
||||
clicked: {
|
||||
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||
background: background(theme.middle, "pressed"),
|
||||
border: border(theme.middle, "active"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
background: background(theme.middle),
|
||||
padding: { left: 6, right: 6, top: 0, bottom: 6 },
|
||||
indent_width: 12,
|
||||
entry: default_entry,
|
||||
dragged_entry: {
|
||||
...default_entry.inactive.default,
|
||||
text: text(theme.middle, "mono", "on", { size: "sm" }),
|
||||
background: with_opacity(background(theme.middle, "on"), 0.9),
|
||||
border: border(theme.middle),
|
||||
},
|
||||
ignored_entry: entry(
|
||||
{
|
||||
default: {
|
||||
text: text(theme.middle, "mono", "disabled"),
|
||||
},
|
||||
},
|
||||
{
|
||||
default: {
|
||||
icon_color: foreground(theme.middle, "variant"),
|
||||
},
|
||||
}
|
||||
),
|
||||
cut_entry: entry(
|
||||
{
|
||||
default: {
|
||||
text: text(theme.middle, "mono", "disabled"),
|
||||
},
|
||||
},
|
||||
{
|
||||
default: {
|
||||
background: background(theme.middle, "active"),
|
||||
text: text(theme.middle, "mono", "disabled", {
|
||||
size: "sm",
|
||||
}),
|
||||
},
|
||||
}
|
||||
),
|
||||
filename_editor: {
|
||||
background: background(theme.middle, "on"),
|
||||
text: text(theme.middle, "mono", "on", { size: "sm" }),
|
||||
selection: theme.players[0],
|
||||
},
|
||||
}
|
||||
}
|
55
styles/src/style_tree/project_shared_notification.ts
Normal file
55
styles/src/style_tree/project_shared_notification.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, text } from "./components"
|
||||
|
||||
export default function project_shared_notification(
|
||||
theme: ColorScheme
|
||||
): unknown {
|
||||
const avatar_size = 48
|
||||
return {
|
||||
window_height: 74,
|
||||
window_width: 380,
|
||||
background: background(theme.middle),
|
||||
owner_container: {
|
||||
padding: 12,
|
||||
},
|
||||
owner_avatar: {
|
||||
height: avatar_size,
|
||||
width: avatar_size,
|
||||
corner_radius: avatar_size / 2,
|
||||
},
|
||||
owner_metadata: {
|
||||
margin: { left: 10 },
|
||||
},
|
||||
owner_username: {
|
||||
...text(theme.middle, "sans", { size: "sm", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
message: {
|
||||
...text(theme.middle, "sans", "variant", { size: "xs" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
worktree_roots: {
|
||||
...text(theme.middle, "sans", "variant", {
|
||||
size: "xs",
|
||||
weight: "bold",
|
||||
}),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
button_width: 96,
|
||||
open_button: {
|
||||
background: background(theme.middle, "accent"),
|
||||
border: border(theme.middle, { left: true, bottom: true }),
|
||||
...text(theme.middle, "sans", "accent", {
|
||||
size: "xs",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
dismiss_button: {
|
||||
border: border(theme.middle, { left: true }),
|
||||
...text(theme.middle, "sans", "variant", {
|
||||
size: "xs",
|
||||
weight: "bold",
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
136
styles/src/style_tree/search.ts
Normal file
136
styles/src/style_tree/search.ts
Normal file
@ -0,0 +1,136 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function search(theme: ColorScheme): any {
|
||||
// Search input
|
||||
const editor = {
|
||||
background: background(theme.highest),
|
||||
corner_radius: 8,
|
||||
min_width: 200,
|
||||
max_width: 500,
|
||||
placeholder_text: text(theme.highest, "mono", "disabled"),
|
||||
selection: theme.players[0],
|
||||
text: text(theme.highest, "mono", "default"),
|
||||
border: border(theme.highest),
|
||||
margin: {
|
||||
right: 12,
|
||||
},
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 12,
|
||||
right: 8,
|
||||
},
|
||||
}
|
||||
|
||||
const include_exclude_editor = {
|
||||
...editor,
|
||||
min_width: 100,
|
||||
max_width: 250,
|
||||
}
|
||||
|
||||
return {
|
||||
// TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
|
||||
match_background: with_opacity(
|
||||
foreground(theme.highest, "accent"),
|
||||
0.4
|
||||
),
|
||||
option_button: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
...text(theme.highest, "mono", "on"),
|
||||
background: background(theme.highest, "on"),
|
||||
corner_radius: 6,
|
||||
border: border(theme.highest, "on"),
|
||||
margin: {
|
||||
right: 4,
|
||||
},
|
||||
padding: {
|
||||
bottom: 2,
|
||||
left: 10,
|
||||
right: 10,
|
||||
top: 2,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(theme.highest, "mono", "on", "hovered"),
|
||||
background: background(theme.highest, "on", "hovered"),
|
||||
border: border(theme.highest, "on", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
...text(theme.highest, "mono", "on", "pressed"),
|
||||
background: background(theme.highest, "on", "pressed"),
|
||||
border: border(theme.highest, "on", "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
...text(theme.highest, "mono", "accent"),
|
||||
},
|
||||
hovered: {
|
||||
...text(theme.highest, "mono", "accent", "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
...text(theme.highest, "mono", "accent", "pressed"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
editor,
|
||||
invalid_editor: {
|
||||
...editor,
|
||||
border: border(theme.highest, "negative"),
|
||||
},
|
||||
include_exclude_editor,
|
||||
invalid_include_exclude_editor: {
|
||||
...include_exclude_editor,
|
||||
border: border(theme.highest, "negative"),
|
||||
},
|
||||
match_index: {
|
||||
...text(theme.highest, "mono", "variant"),
|
||||
padding: {
|
||||
left: 6,
|
||||
},
|
||||
},
|
||||
option_button_group: {
|
||||
padding: {
|
||||
left: 12,
|
||||
right: 12,
|
||||
},
|
||||
},
|
||||
include_exclude_inputs: {
|
||||
...text(theme.highest, "mono", "variant"),
|
||||
padding: {
|
||||
right: 6,
|
||||
},
|
||||
},
|
||||
results_status: {
|
||||
...text(theme.highest, "mono", "on"),
|
||||
size: 18,
|
||||
},
|
||||
dismiss_button: interactive({
|
||||
base: {
|
||||
color: foreground(theme.highest, "variant"),
|
||||
icon_width: 12,
|
||||
button_width: 14,
|
||||
padding: {
|
||||
left: 10,
|
||||
right: 10,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(theme.highest, "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
color: foreground(theme.highest, "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
8
styles/src/style_tree/shared_screen.ts
Normal file
8
styles/src/style_tree/shared_screen.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background } from "./components"
|
||||
|
||||
export default function sharedScreen(theme: ColorScheme) {
|
||||
return {
|
||||
background: background(theme.highest),
|
||||
}
|
||||
}
|
50
styles/src/style_tree/simple_message_notification.ts
Normal file
50
styles/src/style_tree/simple_message_notification.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function simple_message_notification(theme: ColorScheme): any {
|
||||
const header_padding = 8
|
||||
|
||||
return {
|
||||
message: {
|
||||
...text(theme.middle, "sans", { size: "xs" }),
|
||||
margin: { left: header_padding, right: header_padding },
|
||||
},
|
||||
action_message: interactive({
|
||||
base: {
|
||||
...text(theme.middle, "sans", { size: "xs" }),
|
||||
border: border(theme.middle, "active"),
|
||||
corner_radius: 4,
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
|
||||
margin: { left: header_padding, top: 6, bottom: 6 },
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(theme.middle, "sans", "default", { size: "xs" }),
|
||||
background: background(theme.middle, "hovered"),
|
||||
border: border(theme.middle, "active"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
dismiss_button: interactive({
|
||||
base: {
|
||||
color: foreground(theme.middle),
|
||||
icon_width: 8,
|
||||
icon_height: 8,
|
||||
button_width: 8,
|
||||
button_height: 8,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(theme.middle, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
@ -1,22 +1,22 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
export default function statusBar(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.lowest
|
||||
export default function status_bar(theme: ColorScheme): any {
|
||||
const layer = theme.lowest
|
||||
|
||||
const statusContainer = {
|
||||
cornerRadius: 6,
|
||||
const status_container = {
|
||||
corner_radius: 6,
|
||||
padding: { top: 3, bottom: 3, left: 6, right: 6 },
|
||||
}
|
||||
|
||||
const diagnosticStatusContainer = {
|
||||
cornerRadius: 6,
|
||||
const diagnostic_status_container = {
|
||||
corner_radius: 6,
|
||||
padding: { top: 1, bottom: 1, left: 6, right: 6 },
|
||||
}
|
||||
|
||||
return {
|
||||
height: 30,
|
||||
itemSpacing: 8,
|
||||
item_spacing: 8,
|
||||
padding: {
|
||||
top: 1,
|
||||
bottom: 1,
|
||||
@ -24,8 +24,8 @@ export default function statusBar(colorScheme: ColorScheme) {
|
||||
right: 6,
|
||||
},
|
||||
border: border(layer, { top: true, overlay: true }),
|
||||
cursorPosition: text(layer, "sans", "variant"),
|
||||
activeLanguage: interactive({
|
||||
cursor_position: text(layer, "sans", "variant"),
|
||||
active_language: interactive({
|
||||
base: {
|
||||
padding: { left: 6, right: 6 },
|
||||
...text(layer, "sans", "variant"),
|
||||
@ -36,83 +36,83 @@ export default function statusBar(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
}),
|
||||
autoUpdateProgressMessage: text(layer, "sans", "variant"),
|
||||
autoUpdateDoneMessage: text(layer, "sans", "variant"),
|
||||
lspStatus: interactive({
|
||||
auto_update_progress_message: text(layer, "sans", "variant"),
|
||||
auto_update_done_message: text(layer, "sans", "variant"),
|
||||
lsp_status: interactive({
|
||||
base: {
|
||||
...diagnosticStatusContainer,
|
||||
iconSpacing: 4,
|
||||
iconWidth: 14,
|
||||
...diagnostic_status_container,
|
||||
icon_spacing: 4,
|
||||
icon_width: 14,
|
||||
height: 18,
|
||||
message: text(layer, "sans"),
|
||||
iconColor: foreground(layer),
|
||||
icon_color: foreground(layer),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
message: text(layer, "sans"),
|
||||
iconColor: foreground(layer),
|
||||
icon_color: foreground(layer),
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
diagnosticMessage: interactive({
|
||||
diagnostic_message: interactive({
|
||||
base: {
|
||||
...text(layer, "sans"),
|
||||
},
|
||||
state: { hovered: text(layer, "sans", "hovered") },
|
||||
}),
|
||||
diagnosticSummary: interactive({
|
||||
diagnostic_summary: interactive({
|
||||
base: {
|
||||
height: 20,
|
||||
iconWidth: 16,
|
||||
iconSpacing: 2,
|
||||
summarySpacing: 6,
|
||||
icon_width: 16,
|
||||
icon_spacing: 2,
|
||||
summary_spacing: 6,
|
||||
text: text(layer, "sans", { size: "sm" }),
|
||||
iconColorOk: foreground(layer, "variant"),
|
||||
iconColorWarning: foreground(layer, "warning"),
|
||||
iconColorError: foreground(layer, "negative"),
|
||||
containerOk: {
|
||||
cornerRadius: 6,
|
||||
icon_color_ok: foreground(layer, "variant"),
|
||||
icon_color_warning: foreground(layer, "warning"),
|
||||
icon_color_error: foreground(layer, "negative"),
|
||||
container_ok: {
|
||||
corner_radius: 6,
|
||||
padding: { top: 3, bottom: 3, left: 7, right: 7 },
|
||||
},
|
||||
containerWarning: {
|
||||
...diagnosticStatusContainer,
|
||||
container_warning: {
|
||||
...diagnostic_status_container,
|
||||
background: background(layer, "warning"),
|
||||
border: border(layer, "warning"),
|
||||
},
|
||||
containerError: {
|
||||
...diagnosticStatusContainer,
|
||||
container_error: {
|
||||
...diagnostic_status_container,
|
||||
background: background(layer, "negative"),
|
||||
border: border(layer, "negative"),
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
iconColorOk: foreground(layer, "on"),
|
||||
containerOk: {
|
||||
icon_color_ok: foreground(layer, "on"),
|
||||
container_ok: {
|
||||
background: background(layer, "on", "hovered"),
|
||||
},
|
||||
containerWarning: {
|
||||
container_warning: {
|
||||
background: background(layer, "warning", "hovered"),
|
||||
border: border(layer, "warning", "hovered"),
|
||||
},
|
||||
containerError: {
|
||||
container_error: {
|
||||
background: background(layer, "negative", "hovered"),
|
||||
border: border(layer, "negative", "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
panelButtons: {
|
||||
groupLeft: {},
|
||||
groupBottom: {},
|
||||
groupRight: {},
|
||||
panel_buttons: {
|
||||
group_left: {},
|
||||
group_bottom: {},
|
||||
group_right: {},
|
||||
button: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
...statusContainer,
|
||||
iconSize: 16,
|
||||
iconColor: foreground(layer, "variant"),
|
||||
...status_container,
|
||||
icon_size: 16,
|
||||
icon_color: foreground(layer, "variant"),
|
||||
label: {
|
||||
margin: { left: 6 },
|
||||
...text(layer, "sans", { size: "sm" }),
|
||||
@ -120,7 +120,7 @@ export default function statusBar(colorScheme: ColorScheme) {
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
iconColor: foreground(layer, "hovered"),
|
||||
icon_color: foreground(layer, "hovered"),
|
||||
background: background(layer, "variant"),
|
||||
},
|
||||
},
|
||||
@ -128,22 +128,22 @@ export default function statusBar(colorScheme: ColorScheme) {
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
iconColor: foreground(layer, "active"),
|
||||
icon_color: foreground(layer, "active"),
|
||||
background: background(layer, "active"),
|
||||
},
|
||||
hovered: {
|
||||
iconColor: foreground(layer, "hovered"),
|
||||
icon_color: foreground(layer, "hovered"),
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
iconColor: foreground(layer, "pressed"),
|
||||
icon_color: foreground(layer, "pressed"),
|
||||
background: background(layer, "pressed"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
badge: {
|
||||
cornerRadius: 3,
|
||||
corner_radius: 3,
|
||||
padding: 2,
|
||||
margin: { bottom: -1, right: -1 },
|
||||
border: border(layer),
|
@ -1,13 +1,13 @@
|
||||
import { ColorScheme } from "../theme/colorScheme"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import { text, border, background, foreground } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
|
||||
export default function tabBar(colorScheme: ColorScheme) {
|
||||
export default function tab_bar(theme: ColorScheme): any {
|
||||
const height = 32
|
||||
|
||||
let activeLayer = colorScheme.highest
|
||||
let layer = colorScheme.middle
|
||||
const active_layer = theme.highest
|
||||
const layer = theme.middle
|
||||
|
||||
const tab = {
|
||||
height,
|
||||
@ -25,16 +25,16 @@ export default function tabBar(colorScheme: ColorScheme) {
|
||||
spacing: 8,
|
||||
|
||||
// Tab type icons (e.g. Project Search)
|
||||
typeIconWidth: 14,
|
||||
type_icon_width: 14,
|
||||
|
||||
// Close icons
|
||||
closeIconWidth: 8,
|
||||
iconClose: foreground(layer, "variant"),
|
||||
iconCloseActive: foreground(layer, "hovered"),
|
||||
close_icon_width: 8,
|
||||
icon_close: foreground(layer, "variant"),
|
||||
icon_close_active: foreground(layer, "hovered"),
|
||||
|
||||
// Indicators
|
||||
iconConflict: foreground(layer, "warning"),
|
||||
iconDirty: foreground(layer, "accent"),
|
||||
icon_conflict: foreground(layer, "warning"),
|
||||
icon_dirty: foreground(layer, "accent"),
|
||||
|
||||
// When two tabs of the same name are open, a label appears next to them
|
||||
description: {
|
||||
@ -43,25 +43,25 @@ export default function tabBar(colorScheme: ColorScheme) {
|
||||
},
|
||||
}
|
||||
|
||||
const activePaneActiveTab = {
|
||||
const active_pane_active_tab = {
|
||||
...tab,
|
||||
background: background(activeLayer),
|
||||
text: text(activeLayer, "sans", "active", { size: "sm" }),
|
||||
background: background(active_layer),
|
||||
text: text(active_layer, "sans", "active", { size: "sm" }),
|
||||
border: {
|
||||
...tab.border,
|
||||
bottom: false,
|
||||
},
|
||||
}
|
||||
|
||||
const inactivePaneInactiveTab = {
|
||||
const inactive_pane_inactive_tab = {
|
||||
...tab,
|
||||
background: background(layer),
|
||||
text: text(layer, "sans", "variant", { size: "sm" }),
|
||||
}
|
||||
|
||||
const inactivePaneActiveTab = {
|
||||
const inactive_pane_active_tab = {
|
||||
...tab,
|
||||
background: background(activeLayer),
|
||||
background: background(active_layer),
|
||||
text: text(layer, "sans", "variant", { size: "sm" }),
|
||||
border: {
|
||||
...tab.border,
|
||||
@ -69,31 +69,31 @@ export default function tabBar(colorScheme: ColorScheme) {
|
||||
},
|
||||
}
|
||||
|
||||
const draggedTab = {
|
||||
...activePaneActiveTab,
|
||||
background: withOpacity(tab.background, 0.9),
|
||||
const dragged_tab = {
|
||||
...active_pane_active_tab,
|
||||
background: with_opacity(tab.background, 0.9),
|
||||
border: undefined as any,
|
||||
shadow: colorScheme.popoverShadow,
|
||||
shadow: theme.popover_shadow,
|
||||
}
|
||||
|
||||
return {
|
||||
height,
|
||||
background: background(layer),
|
||||
activePane: {
|
||||
activeTab: activePaneActiveTab,
|
||||
inactiveTab: tab,
|
||||
active_pane: {
|
||||
active_tab: active_pane_active_tab,
|
||||
inactive_tab: tab,
|
||||
},
|
||||
inactivePane: {
|
||||
activeTab: inactivePaneActiveTab,
|
||||
inactiveTab: inactivePaneInactiveTab,
|
||||
inactive_pane: {
|
||||
active_tab: inactive_pane_active_tab,
|
||||
inactive_tab: inactive_pane_inactive_tab,
|
||||
},
|
||||
draggedTab,
|
||||
paneButton: toggleable({
|
||||
dragged_tab,
|
||||
pane_button: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
color: foreground(layer, "variant"),
|
||||
iconWidth: 12,
|
||||
buttonWidth: activePaneActiveTab.height,
|
||||
icon_width: 12,
|
||||
button_width: active_pane_active_tab.height,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
@ -118,7 +118,7 @@ export default function tabBar(colorScheme: ColorScheme) {
|
||||
},
|
||||
},
|
||||
}),
|
||||
paneButtonContainer: {
|
||||
pane_button_container: {
|
||||
background: tab.background,
|
||||
border: {
|
||||
...tab.border,
|
52
styles/src/style_tree/terminal.ts
Normal file
52
styles/src/style_tree/terminal.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
|
||||
export default function terminal(theme: ColorScheme) {
|
||||
/**
|
||||
* Colors are controlled per-cell in the terminal grid.
|
||||
* Cells can be set to any of these more 'theme-capable' colors
|
||||
* or can be set directly with RGB values.
|
||||
* Here are the common interpretations of these names:
|
||||
* https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
||||
*/
|
||||
return {
|
||||
black: theme.ramps.neutral(0).hex(),
|
||||
red: theme.ramps.red(0.5).hex(),
|
||||
green: theme.ramps.green(0.5).hex(),
|
||||
yellow: theme.ramps.yellow(0.5).hex(),
|
||||
blue: theme.ramps.blue(0.5).hex(),
|
||||
magenta: theme.ramps.magenta(0.5).hex(),
|
||||
cyan: theme.ramps.cyan(0.5).hex(),
|
||||
white: theme.ramps.neutral(1).hex(),
|
||||
bright_black: theme.ramps.neutral(0.4).hex(),
|
||||
bright_red: theme.ramps.red(0.25).hex(),
|
||||
bright_green: theme.ramps.green(0.25).hex(),
|
||||
bright_yellow: theme.ramps.yellow(0.25).hex(),
|
||||
bright_blue: theme.ramps.blue(0.25).hex(),
|
||||
bright_magenta: theme.ramps.magenta(0.25).hex(),
|
||||
bright_cyan: theme.ramps.cyan(0.25).hex(),
|
||||
bright_white: theme.ramps.neutral(1).hex(),
|
||||
/**
|
||||
* Default color for characters
|
||||
*/
|
||||
foreground: theme.ramps.neutral(1).hex(),
|
||||
/**
|
||||
* Default color for the rectangle background of a cell
|
||||
*/
|
||||
background: theme.ramps.neutral(0).hex(),
|
||||
modal_background: theme.ramps.neutral(0.1).hex(),
|
||||
/**
|
||||
* Default color for the cursor
|
||||
*/
|
||||
cursor: theme.players[0].cursor,
|
||||
dim_black: theme.ramps.neutral(1).hex(),
|
||||
dim_red: theme.ramps.red(0.75).hex(),
|
||||
dim_green: theme.ramps.green(0.75).hex(),
|
||||
dim_yellow: theme.ramps.yellow(0.75).hex(),
|
||||
dim_blue: theme.ramps.blue(0.75).hex(),
|
||||
dim_magenta: theme.ramps.magenta(0.75).hex(),
|
||||
dim_cyan: theme.ramps.cyan(0.75).hex(),
|
||||
dim_white: theme.ramps.neutral(0.6).hex(),
|
||||
bright_foreground: theme.ramps.neutral(1).hex(),
|
||||
dim_foreground: theme.ramps.neutral(0).hex(),
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import { ColorScheme } from "../common"
|
||||
import { icon_button, toggleable_icon_button } from "../component/icon_button"
|
||||
import { toggleable_text_button } from "../component/text_button"
|
||||
import { interactive, toggleable } from "../element"
|
||||
import { withOpacity } from "../theme/color"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import { background, border, foreground, text } from "./components"
|
||||
|
||||
const ITEM_SPACING = 8
|
||||
@ -17,8 +17,8 @@ function build_spacing(
|
||||
group: spacing,
|
||||
item: spacing / 2,
|
||||
half_item: spacing / 4,
|
||||
marginY: (container_height - element_height) / 2,
|
||||
marginX: (container_height - element_height) / 2,
|
||||
margin_y: (container_height - element_height) / 2,
|
||||
margin_x: (container_height - element_height) / 2,
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,15 +26,15 @@ function call_controls(theme: ColorScheme) {
|
||||
const button_height = 18
|
||||
|
||||
const space = build_spacing(TITLEBAR_HEIGHT, button_height, ITEM_SPACING)
|
||||
const marginY = {
|
||||
top: space.marginY,
|
||||
bottom: space.marginY,
|
||||
const margin_y = {
|
||||
top: space.margin_y,
|
||||
bottom: space.margin_y,
|
||||
}
|
||||
|
||||
return {
|
||||
toggle_microphone_button: toggleable_icon_button(theme, {
|
||||
margin: {
|
||||
...marginY,
|
||||
...margin_y,
|
||||
left: space.group,
|
||||
right: space.half_item,
|
||||
},
|
||||
@ -43,7 +43,7 @@ function call_controls(theme: ColorScheme) {
|
||||
|
||||
toggle_speakers_button: toggleable_icon_button(theme, {
|
||||
margin: {
|
||||
...marginY,
|
||||
...margin_y,
|
||||
left: space.half_item,
|
||||
right: space.half_item,
|
||||
},
|
||||
@ -51,7 +51,7 @@ function call_controls(theme: ColorScheme) {
|
||||
|
||||
screen_share_button: toggleable_icon_button(theme, {
|
||||
margin: {
|
||||
...marginY,
|
||||
...margin_y,
|
||||
left: space.half_item,
|
||||
right: space.group,
|
||||
},
|
||||
@ -78,7 +78,7 @@ function user_menu(theme: ColorScheme) {
|
||||
const button = toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
cornerRadius: 6,
|
||||
corner_radius: 6,
|
||||
height: button_height,
|
||||
width: online ? 37 : 24,
|
||||
padding: {
|
||||
@ -150,20 +150,20 @@ function user_menu(theme: ColorScheme) {
|
||||
}
|
||||
}
|
||||
return {
|
||||
userMenuButtonOnline: build_button({ online: true }),
|
||||
userMenuButtonOffline: build_button({ online: false }),
|
||||
user_menu_button_online: build_button({ online: true }),
|
||||
user_menu_button_offline: build_button({ online: false }),
|
||||
}
|
||||
}
|
||||
|
||||
export function titlebar(theme: ColorScheme) {
|
||||
const avatarWidth = 15
|
||||
const avatarOuterWidth = avatarWidth + 4
|
||||
const followerAvatarWidth = 14
|
||||
const followerAvatarOuterWidth = followerAvatarWidth + 4
|
||||
export function titlebar(theme: ColorScheme): any {
|
||||
const avatar_width = 15
|
||||
const avatar_outer_width = avatar_width + 4
|
||||
const follower_avatar_width = 14
|
||||
const follower_avatar_outer_width = follower_avatar_width + 4
|
||||
|
||||
return {
|
||||
item_spacing: ITEM_SPACING,
|
||||
facePileSpacing: 2,
|
||||
face_pile_spacing: 2,
|
||||
height: TITLEBAR_HEIGHT,
|
||||
background: background(theme.lowest),
|
||||
border: border(theme.lowest, { bottom: true }),
|
||||
@ -177,21 +177,21 @@ export function titlebar(theme: ColorScheme) {
|
||||
highlight_color: text(theme.lowest, "sans", "active").color,
|
||||
|
||||
// Collaborators
|
||||
leaderAvatar: {
|
||||
width: avatarWidth,
|
||||
outerWidth: avatarOuterWidth,
|
||||
cornerRadius: avatarWidth / 2,
|
||||
outerCornerRadius: avatarOuterWidth / 2,
|
||||
leader_avatar: {
|
||||
width: avatar_width,
|
||||
outer_width: avatar_outer_width,
|
||||
corner_radius: avatar_width / 2,
|
||||
outer_corner_radius: avatar_outer_width / 2,
|
||||
},
|
||||
followerAvatar: {
|
||||
width: followerAvatarWidth,
|
||||
outerWidth: followerAvatarOuterWidth,
|
||||
cornerRadius: followerAvatarWidth / 2,
|
||||
outerCornerRadius: followerAvatarOuterWidth / 2,
|
||||
follower_avatar: {
|
||||
width: follower_avatar_width,
|
||||
outer_width: follower_avatar_outer_width,
|
||||
corner_radius: follower_avatar_width / 2,
|
||||
outer_corner_radius: follower_avatar_outer_width / 2,
|
||||
},
|
||||
inactiveAvatarGrayscale: true,
|
||||
followerAvatarOverlap: 8,
|
||||
leaderSelection: {
|
||||
inactive_avatar_grayscale: true,
|
||||
follower_avatar_overlap: 8,
|
||||
leader_selection: {
|
||||
margin: {
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
@ -202,16 +202,16 @@ export function titlebar(theme: ColorScheme) {
|
||||
top: 2,
|
||||
bottom: 2,
|
||||
},
|
||||
cornerRadius: 6,
|
||||
corner_radius: 6,
|
||||
},
|
||||
avatarRibbon: {
|
||||
avatar_ribbon: {
|
||||
height: 3,
|
||||
width: 14,
|
||||
// TODO: Chore: Make avatarRibbon colors driven by the theme rather than being hard coded.
|
||||
},
|
||||
|
||||
sign_in_button: toggleable_text_button(theme, {}),
|
||||
offlineIcon: {
|
||||
offline_icon: {
|
||||
color: foreground(theme.lowest, "variant"),
|
||||
width: 16,
|
||||
margin: {
|
||||
@ -223,9 +223,9 @@ export function titlebar(theme: ColorScheme) {
|
||||
},
|
||||
|
||||
// When the collaboration server is out of date, show a warning
|
||||
outdatedWarning: {
|
||||
outdated_warning: {
|
||||
...text(theme.lowest, "sans", "warning", { size: "xs" }),
|
||||
background: withOpacity(background(theme.lowest, "warning"), 0.3),
|
||||
background: with_opacity(background(theme.lowest, "warning"), 0.3),
|
||||
border: border(theme.lowest, "warning"),
|
||||
margin: {
|
||||
left: ITEM_SPACING,
|
||||
@ -234,7 +234,7 @@ export function titlebar(theme: ColorScheme) {
|
||||
left: 8,
|
||||
right: 8,
|
||||
},
|
||||
cornerRadius: 6,
|
||||
corner_radius: 6,
|
||||
},
|
||||
|
||||
leave_call_button: icon_button(theme, {
|
||||
@ -253,14 +253,14 @@ export function titlebar(theme: ColorScheme) {
|
||||
}),
|
||||
|
||||
// Jewel that notifies you that there are new contact requests
|
||||
toggleContactsBadge: {
|
||||
cornerRadius: 3,
|
||||
toggle_contacts_badge: {
|
||||
corner_radius: 3,
|
||||
padding: 2,
|
||||
margin: { top: 3, left: 3 },
|
||||
border: border(theme.lowest),
|
||||
background: foreground(theme.lowest, "accent"),
|
||||
},
|
||||
shareButton: toggleable_text_button(theme, {}),
|
||||
share_button: toggleable_text_button(theme, {}),
|
||||
user_menu: user_menu(theme),
|
||||
}
|
||||
}
|
64
styles/src/style_tree/toolbar_dropdown_menu.ts
Normal file
64
styles/src/style_tree/toolbar_dropdown_menu.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, text } from "./components"
|
||||
import { interactive, toggleable } from "../element"
|
||||
export default function dropdown_menu(theme: ColorScheme): any {
|
||||
return {
|
||||
row_height: 30,
|
||||
background: background(theme.middle),
|
||||
border: border(theme.middle),
|
||||
shadow: theme.popover_shadow,
|
||||
header: interactive({
|
||||
base: {
|
||||
...text(theme.middle, "sans", { size: "sm" }),
|
||||
secondary_text: text(theme.middle, "sans", {
|
||||
size: "sm",
|
||||
color: "#aaaaaa",
|
||||
}),
|
||||
secondary_text_spacing: 10,
|
||||
padding: { left: 8, right: 8, top: 2, bottom: 2 },
|
||||
corner_radius: 6,
|
||||
background: background(theme.middle, "on"),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(theme.middle, "hovered"),
|
||||
},
|
||||
clicked: {
|
||||
background: background(theme.middle, "pressed"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
section_header: {
|
||||
...text(theme.middle, "sans", { size: "sm" }),
|
||||
padding: { left: 8, right: 8, top: 8, bottom: 8 },
|
||||
},
|
||||
item: toggleable({
|
||||
base: interactive({
|
||||
base: {
|
||||
...text(theme.middle, "sans", { size: "sm" }),
|
||||
secondary_text_spacing: 10,
|
||||
secondary_text: text(theme.middle, "sans", { size: "sm" }),
|
||||
padding: { left: 18, right: 18, top: 2, bottom: 2 },
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
background: background(theme.middle, "hovered"),
|
||||
...text(theme.middle, "sans", "hovered", {
|
||||
size: "sm",
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
state: {
|
||||
active: {
|
||||
default: {
|
||||
background: background(theme.middle, "active"),
|
||||
},
|
||||
hovered: {
|
||||
background: background(theme.middle, "hovered"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
22
styles/src/style_tree/tooltip.ts
Normal file
22
styles/src/style_tree/tooltip.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { background, border, text } from "./components"
|
||||
|
||||
export default function tooltip(theme: ColorScheme): any {
|
||||
return {
|
||||
background: background(theme.middle),
|
||||
border: border(theme.middle),
|
||||
padding: { top: 4, bottom: 4, left: 8, right: 8 },
|
||||
margin: { top: 6, left: 6 },
|
||||
shadow: theme.popover_shadow,
|
||||
corner_radius: 6,
|
||||
text: text(theme.middle, "sans", { size: "xs" }),
|
||||
keystroke: {
|
||||
background: background(theme.middle, "on"),
|
||||
corner_radius: 4,
|
||||
margin: { left: 6 },
|
||||
padding: { left: 4, right: 4 },
|
||||
...text(theme.middle, "mono", "on", { size: "xs", weight: "bold" }),
|
||||
},
|
||||
max_text_width: 200,
|
||||
}
|
||||
}
|
39
styles/src/style_tree/update_notification.ts
Normal file
39
styles/src/style_tree/update_notification.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { foreground, text } from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function update_notification(theme: ColorScheme): any {
|
||||
const header_padding = 8
|
||||
|
||||
return {
|
||||
message: {
|
||||
...text(theme.middle, "sans", { size: "xs" }),
|
||||
margin: { left: header_padding, right: header_padding },
|
||||
},
|
||||
action_message: interactive({
|
||||
base: {
|
||||
...text(theme.middle, "sans", { size: "xs" }),
|
||||
margin: { left: header_padding, top: 6, bottom: 6 },
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(theme.middle, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
dismiss_button: interactive({
|
||||
base: {
|
||||
color: foreground(theme.middle),
|
||||
icon_width: 8,
|
||||
icon_height: 8,
|
||||
button_width: 8,
|
||||
button_height: 8,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(theme.middle, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
155
styles/src/style_tree/welcome.ts
Normal file
155
styles/src/style_tree/welcome.ts
Normal file
@ -0,0 +1,155 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import {
|
||||
border,
|
||||
background,
|
||||
foreground,
|
||||
text,
|
||||
TextProperties,
|
||||
svg,
|
||||
} from "./components"
|
||||
import { interactive } from "../element"
|
||||
|
||||
export default function welcome(theme: ColorScheme): any {
|
||||
const checkbox_base = {
|
||||
corner_radius: 4,
|
||||
padding: {
|
||||
left: 3,
|
||||
right: 3,
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
},
|
||||
// shadow: theme.popover_shadow,
|
||||
border: border(theme.highest),
|
||||
margin: {
|
||||
right: 8,
|
||||
top: 5,
|
||||
bottom: 5,
|
||||
},
|
||||
}
|
||||
|
||||
const interactive_text_size: TextProperties = { size: "sm" }
|
||||
|
||||
return {
|
||||
page_width: 320,
|
||||
logo: svg(
|
||||
foreground(theme.highest, "default"),
|
||||
"icons/logo_96.svg",
|
||||
64,
|
||||
64
|
||||
),
|
||||
logo_subheading: {
|
||||
...text(theme.highest, "sans", "variant", { size: "md" }),
|
||||
margin: {
|
||||
top: 10,
|
||||
bottom: 7,
|
||||
},
|
||||
},
|
||||
button_group: {
|
||||
margin: {
|
||||
top: 8,
|
||||
bottom: 16,
|
||||
},
|
||||
},
|
||||
heading_group: {
|
||||
margin: {
|
||||
top: 8,
|
||||
bottom: 12,
|
||||
},
|
||||
},
|
||||
checkbox_group: {
|
||||
border: border(theme.highest, "variant"),
|
||||
background: with_opacity(
|
||||
background(theme.highest, "hovered"),
|
||||
0.25
|
||||
),
|
||||
corner_radius: 4,
|
||||
padding: {
|
||||
left: 12,
|
||||
top: 2,
|
||||
bottom: 2,
|
||||
},
|
||||
},
|
||||
button: interactive({
|
||||
base: {
|
||||
background: background(theme.highest),
|
||||
border: border(theme.highest, "active"),
|
||||
corner_radius: 4,
|
||||
margin: {
|
||||
top: 4,
|
||||
bottom: 4,
|
||||
},
|
||||
padding: {
|
||||
top: 3,
|
||||
bottom: 3,
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
...text(
|
||||
theme.highest,
|
||||
"sans",
|
||||
"default",
|
||||
interactive_text_size
|
||||
),
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(
|
||||
theme.highest,
|
||||
"sans",
|
||||
"default",
|
||||
interactive_text_size
|
||||
),
|
||||
background: background(theme.highest, "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
usage_note: {
|
||||
...text(theme.highest, "sans", "variant", { size: "2xs" }),
|
||||
padding: {
|
||||
top: -4,
|
||||
},
|
||||
},
|
||||
checkbox_container: {
|
||||
margin: {
|
||||
top: 4,
|
||||
},
|
||||
padding: {
|
||||
bottom: 8,
|
||||
},
|
||||
},
|
||||
checkbox: {
|
||||
label: {
|
||||
...text(theme.highest, "sans", interactive_text_size),
|
||||
// Also supports margin, container, border, etc.
|
||||
},
|
||||
icon: svg(
|
||||
foreground(theme.highest, "on"),
|
||||
"icons/check_12.svg",
|
||||
12,
|
||||
12
|
||||
),
|
||||
default: {
|
||||
...checkbox_base,
|
||||
background: background(theme.highest, "default"),
|
||||
border: border(theme.highest, "active"),
|
||||
},
|
||||
checked: {
|
||||
...checkbox_base,
|
||||
background: background(theme.highest, "hovered"),
|
||||
border: border(theme.highest, "active"),
|
||||
},
|
||||
hovered: {
|
||||
...checkbox_base,
|
||||
background: background(theme.highest, "hovered"),
|
||||
border: border(theme.highest, "active"),
|
||||
},
|
||||
hovered_and_checked: {
|
||||
...checkbox_base,
|
||||
background: background(theme.highest, "hovered"),
|
||||
border: border(theme.highest, "active"),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
190
styles/src/style_tree/workspace.ts
Normal file
190
styles/src/style_tree/workspace.ts
Normal file
@ -0,0 +1,190 @@
|
||||
import { ColorScheme } from "../theme/color_scheme"
|
||||
import { with_opacity } from "../theme/color"
|
||||
import {
|
||||
background,
|
||||
border,
|
||||
border_color,
|
||||
foreground,
|
||||
svg,
|
||||
text,
|
||||
} from "./components"
|
||||
import statusBar from "./status_bar"
|
||||
import tabBar from "./tab_bar"
|
||||
import { interactive } from "../element"
|
||||
|
||||
import { titlebar } from "./titlebar"
|
||||
export default function workspace(theme: ColorScheme): any {
|
||||
const { is_light } = theme
|
||||
|
||||
return {
|
||||
background: background(theme.lowest),
|
||||
blank_pane: {
|
||||
logo_container: {
|
||||
width: 256,
|
||||
height: 256,
|
||||
},
|
||||
logo: svg(
|
||||
with_opacity("#000000", theme.is_light ? 0.6 : 0.8),
|
||||
"icons/logo_96.svg",
|
||||
256,
|
||||
256
|
||||
),
|
||||
|
||||
logo_shadow: svg(
|
||||
with_opacity(
|
||||
theme.is_light
|
||||
? "#FFFFFF"
|
||||
: theme.lowest.base.default.background,
|
||||
theme.is_light ? 1 : 0.6
|
||||
),
|
||||
"icons/logo_96.svg",
|
||||
256,
|
||||
256
|
||||
),
|
||||
keyboard_hints: {
|
||||
margin: {
|
||||
top: 96,
|
||||
},
|
||||
corner_radius: 4,
|
||||
},
|
||||
keyboard_hint: interactive({
|
||||
base: {
|
||||
...text(theme.lowest, "sans", "variant", { size: "sm" }),
|
||||
padding: {
|
||||
top: 3,
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 3,
|
||||
},
|
||||
corner_radius: 8,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
...text(theme.lowest, "sans", "active", { size: "sm" }),
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
keyboard_hint_width: 320,
|
||||
},
|
||||
joining_project_avatar: {
|
||||
corner_radius: 40,
|
||||
width: 80,
|
||||
},
|
||||
joining_project_message: {
|
||||
padding: 12,
|
||||
...text(theme.lowest, "sans", { size: "lg" }),
|
||||
},
|
||||
external_location_message: {
|
||||
background: background(theme.middle, "accent"),
|
||||
border: border(theme.middle, "accent"),
|
||||
corner_radius: 6,
|
||||
padding: 12,
|
||||
margin: { bottom: 8, right: 8 },
|
||||
...text(theme.middle, "sans", "accent", { size: "xs" }),
|
||||
},
|
||||
leader_border_opacity: 0.7,
|
||||
leader_border_width: 2.0,
|
||||
tab_bar: tabBar(theme),
|
||||
modal: {
|
||||
margin: {
|
||||
bottom: 52,
|
||||
top: 52,
|
||||
},
|
||||
cursor: "Arrow",
|
||||
},
|
||||
zoomed_background: {
|
||||
cursor: "Arrow",
|
||||
background: is_light
|
||||
? with_opacity(background(theme.lowest), 0.8)
|
||||
: with_opacity(background(theme.highest), 0.6),
|
||||
},
|
||||
zoomed_pane_foreground: {
|
||||
margin: 16,
|
||||
shadow: theme.modal_shadow,
|
||||
border: border(theme.lowest, { overlay: true }),
|
||||
},
|
||||
zoomed_panel_foreground: {
|
||||
margin: 16,
|
||||
border: border(theme.lowest, { overlay: true }),
|
||||
},
|
||||
dock: {
|
||||
left: {
|
||||
border: border(theme.lowest, { right: true }),
|
||||
},
|
||||
bottom: {
|
||||
border: border(theme.lowest, { top: true }),
|
||||
},
|
||||
right: {
|
||||
border: border(theme.lowest, { left: true }),
|
||||
},
|
||||
},
|
||||
pane_divider: {
|
||||
color: border_color(theme.lowest),
|
||||
width: 1,
|
||||
},
|
||||
status_bar: statusBar(theme),
|
||||
titlebar: titlebar(theme),
|
||||
toolbar: {
|
||||
height: 34,
|
||||
background: background(theme.highest),
|
||||
border: border(theme.highest, { bottom: true }),
|
||||
item_spacing: 8,
|
||||
nav_button: interactive({
|
||||
base: {
|
||||
color: foreground(theme.highest, "on"),
|
||||
icon_width: 12,
|
||||
button_width: 24,
|
||||
corner_radius: 6,
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(theme.highest, "on", "hovered"),
|
||||
background: background(theme.highest, "on", "hovered"),
|
||||
},
|
||||
disabled: {
|
||||
color: foreground(theme.highest, "on", "disabled"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
padding: { left: 8, right: 8, top: 4, bottom: 4 },
|
||||
},
|
||||
breadcrumb_height: 24,
|
||||
breadcrumbs: interactive({
|
||||
base: {
|
||||
...text(theme.highest, "sans", "variant"),
|
||||
corner_radius: 6,
|
||||
padding: {
|
||||
left: 6,
|
||||
right: 6,
|
||||
},
|
||||
},
|
||||
state: {
|
||||
hovered: {
|
||||
color: foreground(theme.highest, "on", "hovered"),
|
||||
background: background(theme.highest, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
}),
|
||||
disconnected_overlay: {
|
||||
...text(theme.lowest, "sans"),
|
||||
background: with_opacity(background(theme.lowest), 0.8),
|
||||
},
|
||||
notification: {
|
||||
margin: { top: 10 },
|
||||
background: background(theme.middle),
|
||||
corner_radius: 6,
|
||||
padding: 12,
|
||||
border: border(theme.middle),
|
||||
shadow: theme.popover_shadow,
|
||||
},
|
||||
notifications: {
|
||||
width: 400,
|
||||
margin: { right: 10, bottom: 10 },
|
||||
},
|
||||
drop_target_overlay_color: with_opacity(
|
||||
foreground(theme.lowest, "variant"),
|
||||
0.5
|
||||
),
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
/** Converts a percentage scale value (0-100) to normalized scale (0-1) value. */
|
||||
export function percentageToNormalized(value: number) {
|
||||
const normalized = value / 100
|
||||
return normalized
|
||||
}
|
||||
|
||||
/** Converts a normalized scale (0-1) value to a percentage scale (0-100) value. */
|
||||
export function normalizedToPercetage(value: number) {
|
||||
const percentage = value * 100
|
||||
return percentage
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import bezier from "bezier-easing"
|
||||
import { Curve } from "../ref/curves"
|
||||
|
||||
/**
|
||||
* Formats our Curve data structure into a bezier easing function.
|
||||
* @param {Curve} curve - The curve to format.
|
||||
* @param {Boolean} inverted - Whether or not to invert the curve.
|
||||
* @returns {EasingFunction} The formatted easing function.
|
||||
*/
|
||||
export function curve(curve: Curve, inverted?: Boolean) {
|
||||
if (inverted) {
|
||||
return bezier(
|
||||
curve.value[3],
|
||||
curve.value[2],
|
||||
curve.value[1],
|
||||
curve.value[0]
|
||||
)
|
||||
}
|
||||
|
||||
return bezier(
|
||||
curve.value[0],
|
||||
curve.value[1],
|
||||
curve.value[2],
|
||||
curve.value[3]
|
||||
)
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
import bezier from "bezier-easing"
|
||||
import chroma from "chroma-js"
|
||||
import { Color, ColorFamily, ColorFamilyConfig, ColorScale } from "../types"
|
||||
import { percentageToNormalized } from "./convert"
|
||||
import { curve } from "./curve"
|
||||
|
||||
// Re-export interface in a more standard format
|
||||
export type EasingFunction = bezier.EasingFunction
|
||||
|
||||
/**
|
||||
* Generates a color, outputs it in multiple formats, and returns a variety of useful metadata.
|
||||
*
|
||||
* @param {EasingFunction} hueEasing - An easing function for the hue component of the color.
|
||||
* @param {EasingFunction} saturationEasing - An easing function for the saturation component of the color.
|
||||
* @param {EasingFunction} lightnessEasing - An easing function for the lightness component of the color.
|
||||
* @param {ColorFamilyConfig} family - Configuration for the color family.
|
||||
* @param {number} step - The current step.
|
||||
* @param {number} steps - The total number of steps in the color scale.
|
||||
*
|
||||
* @returns {Color} The generated color, with its calculated contrast against black and white, as well as its LCH values, RGBA array, hexadecimal representation, and a flag indicating if it is light or dark.
|
||||
*/
|
||||
function generateColor(
|
||||
hueEasing: EasingFunction,
|
||||
saturationEasing: EasingFunction,
|
||||
lightnessEasing: EasingFunction,
|
||||
family: ColorFamilyConfig,
|
||||
step: number,
|
||||
steps: number
|
||||
) {
|
||||
const { hue, saturation, lightness } = family.color
|
||||
|
||||
const stepHue = hueEasing(step / steps) * (hue.end - hue.start) + hue.start
|
||||
const stepSaturation =
|
||||
saturationEasing(step / steps) * (saturation.end - saturation.start) +
|
||||
saturation.start
|
||||
const stepLightness =
|
||||
lightnessEasing(step / steps) * (lightness.end - lightness.start) +
|
||||
lightness.start
|
||||
|
||||
const color = chroma.hsl(
|
||||
stepHue,
|
||||
percentageToNormalized(stepSaturation),
|
||||
percentageToNormalized(stepLightness)
|
||||
)
|
||||
|
||||
const contrast = {
|
||||
black: {
|
||||
value: chroma.contrast(color, "black"),
|
||||
aaPass: chroma.contrast(color, "black") >= 4.5,
|
||||
aaaPass: chroma.contrast(color, "black") >= 7,
|
||||
},
|
||||
white: {
|
||||
value: chroma.contrast(color, "white"),
|
||||
aaPass: chroma.contrast(color, "white") >= 4.5,
|
||||
aaaPass: chroma.contrast(color, "white") >= 7,
|
||||
},
|
||||
}
|
||||
|
||||
const lch = color.lch()
|
||||
const rgba = color.rgba()
|
||||
const hex = color.hex()
|
||||
|
||||
// 55 is a magic number. It's the lightness value at which we consider a color to be "light".
|
||||
// It was picked by eye with some testing. We might want to use a more scientific approach in the future.
|
||||
const isLight = lch[0] > 55
|
||||
|
||||
const result: Color = {
|
||||
step,
|
||||
lch,
|
||||
hex,
|
||||
rgba,
|
||||
contrast,
|
||||
isLight,
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a color scale based on a color family configuration.
|
||||
*
|
||||
* @param {ColorFamilyConfig} config - The configuration for the color family.
|
||||
* @param {Boolean} inverted - Specifies whether the color scale should be inverted or not.
|
||||
*
|
||||
* @returns {ColorScale} The generated color scale.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const colorScale = generateColorScale({
|
||||
* name: "blue",
|
||||
* color: {
|
||||
* hue: {
|
||||
* start: 210,
|
||||
* end: 240,
|
||||
* curve: "easeInOut"
|
||||
* },
|
||||
* saturation: {
|
||||
* start: 100,
|
||||
* end: 100,
|
||||
* curve: "easeInOut"
|
||||
* },
|
||||
* lightness: {
|
||||
* start: 50,
|
||||
* end: 50,
|
||||
* curve: "easeInOut"
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
|
||||
export function generateColorScale(
|
||||
config: ColorFamilyConfig,
|
||||
inverted: Boolean = false
|
||||
) {
|
||||
const { hue, saturation, lightness } = config.color
|
||||
|
||||
// 101 steps means we get values from 0-100
|
||||
const NUM_STEPS = 101
|
||||
|
||||
const hueEasing = curve(hue.curve, inverted)
|
||||
const saturationEasing = curve(saturation.curve, inverted)
|
||||
const lightnessEasing = curve(lightness.curve, inverted)
|
||||
|
||||
let scale: ColorScale = {
|
||||
colors: [],
|
||||
values: [],
|
||||
}
|
||||
|
||||
for (let i = 0; i < NUM_STEPS; i++) {
|
||||
const color = generateColor(
|
||||
hueEasing,
|
||||
saturationEasing,
|
||||
lightnessEasing,
|
||||
config,
|
||||
i,
|
||||
NUM_STEPS
|
||||
)
|
||||
|
||||
scale.colors.push(color)
|
||||
scale.values.push(color.hex)
|
||||
}
|
||||
|
||||
return scale
|
||||
}
|
||||
|
||||
/** Generates a color family with a scale and an inverted scale. */
|
||||
export function generateColorFamily(config: ColorFamilyConfig) {
|
||||
const scale = generateColorScale(config, false)
|
||||
const invertedScale = generateColorScale(config, true)
|
||||
|
||||
const family: ColorFamily = {
|
||||
name: config.name,
|
||||
scale,
|
||||
invertedScale,
|
||||
}
|
||||
|
||||
return family
|
||||
}
|
@ -1,445 +0,0 @@
|
||||
import { generateColorFamily } from "../lib/generate"
|
||||
import { curve } from "./curves"
|
||||
|
||||
// These are the source colors for the color scales in the system.
|
||||
// These should never directly be used directly in components or themes as they generate thousands of lines of code.
|
||||
// Instead, use the outputs from the reference palette which exports a smaller subset of colors.
|
||||
|
||||
// Token or user-facing colors should use short, clear names and a 100-900 scale to match the font weight scale.
|
||||
|
||||
// Light Gray ======================================== //
|
||||
|
||||
export const lightgray = generateColorFamily({
|
||||
name: "lightgray",
|
||||
color: {
|
||||
hue: {
|
||||
start: 210,
|
||||
end: 210,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 10,
|
||||
end: 15,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 50,
|
||||
curve: curve.linear,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Light Dark ======================================== //
|
||||
|
||||
export const darkgray = generateColorFamily({
|
||||
name: "darkgray",
|
||||
color: {
|
||||
hue: {
|
||||
start: 210,
|
||||
end: 210,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 15,
|
||||
end: 20,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 55,
|
||||
end: 8,
|
||||
curve: curve.linear,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Red ======================================== //
|
||||
|
||||
export const red = generateColorFamily({
|
||||
name: "red",
|
||||
color: {
|
||||
hue: {
|
||||
start: 0,
|
||||
end: 0,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 95,
|
||||
end: 75,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 25,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Sunset ======================================== //
|
||||
|
||||
export const sunset = generateColorFamily({
|
||||
name: "sunset",
|
||||
color: {
|
||||
hue: {
|
||||
start: 15,
|
||||
end: 15,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 100,
|
||||
end: 90,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 25,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Orange ======================================== //
|
||||
|
||||
export const orange = generateColorFamily({
|
||||
name: "orange",
|
||||
color: {
|
||||
hue: {
|
||||
start: 25,
|
||||
end: 25,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 100,
|
||||
end: 95,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 20,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Amber ======================================== //
|
||||
|
||||
export const amber = generateColorFamily({
|
||||
name: "amber",
|
||||
color: {
|
||||
hue: {
|
||||
start: 38,
|
||||
end: 38,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 100,
|
||||
end: 100,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 18,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Yellow ======================================== //
|
||||
|
||||
export const yellow = generateColorFamily({
|
||||
name: "yellow",
|
||||
color: {
|
||||
hue: {
|
||||
start: 48,
|
||||
end: 48,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 90,
|
||||
end: 100,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 15,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Lemon ======================================== //
|
||||
|
||||
export const lemon = generateColorFamily({
|
||||
name: "lemon",
|
||||
color: {
|
||||
hue: {
|
||||
start: 55,
|
||||
end: 55,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 85,
|
||||
end: 95,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 15,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Citron ======================================== //
|
||||
|
||||
export const citron = generateColorFamily({
|
||||
name: "citron",
|
||||
color: {
|
||||
hue: {
|
||||
start: 70,
|
||||
end: 70,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 85,
|
||||
end: 90,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 15,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Lime ======================================== //
|
||||
|
||||
export const lime = generateColorFamily({
|
||||
name: "lime",
|
||||
color: {
|
||||
hue: {
|
||||
start: 85,
|
||||
end: 85,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 85,
|
||||
end: 80,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 18,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Green ======================================== //
|
||||
|
||||
export const green = generateColorFamily({
|
||||
name: "green",
|
||||
color: {
|
||||
hue: {
|
||||
start: 108,
|
||||
end: 108,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 60,
|
||||
end: 70,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 18,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Mint ======================================== //
|
||||
|
||||
export const mint = generateColorFamily({
|
||||
name: "mint",
|
||||
color: {
|
||||
hue: {
|
||||
start: 142,
|
||||
end: 142,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 60,
|
||||
end: 75,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 20,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Cyan ======================================== //
|
||||
|
||||
export const cyan = generateColorFamily({
|
||||
name: "cyan",
|
||||
color: {
|
||||
hue: {
|
||||
start: 179,
|
||||
end: 179,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 70,
|
||||
end: 80,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 20,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Sky ======================================== //
|
||||
|
||||
export const sky = generateColorFamily({
|
||||
name: "sky",
|
||||
color: {
|
||||
hue: {
|
||||
start: 195,
|
||||
end: 205,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 85,
|
||||
end: 90,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 15,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Blue ======================================== //
|
||||
|
||||
export const blue = generateColorFamily({
|
||||
name: "blue",
|
||||
color: {
|
||||
hue: {
|
||||
start: 218,
|
||||
end: 218,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 85,
|
||||
end: 70,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 15,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Indigo ======================================== //
|
||||
|
||||
export const indigo = generateColorFamily({
|
||||
name: "indigo",
|
||||
color: {
|
||||
hue: {
|
||||
start: 245,
|
||||
end: 245,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 60,
|
||||
end: 50,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 22,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Purple ======================================== //
|
||||
|
||||
export const purple = generateColorFamily({
|
||||
name: "purple",
|
||||
color: {
|
||||
hue: {
|
||||
start: 260,
|
||||
end: 270,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 65,
|
||||
end: 55,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 20,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Pink ======================================== //
|
||||
|
||||
export const pink = generateColorFamily({
|
||||
name: "pink",
|
||||
color: {
|
||||
hue: {
|
||||
start: 320,
|
||||
end: 330,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 70,
|
||||
end: 65,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 32,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Rose ======================================== //
|
||||
|
||||
export const rose = generateColorFamily({
|
||||
name: "rose",
|
||||
color: {
|
||||
hue: {
|
||||
start: 345,
|
||||
end: 345,
|
||||
curve: curve.linear,
|
||||
},
|
||||
saturation: {
|
||||
start: 90,
|
||||
end: 70,
|
||||
curve: curve.saturation,
|
||||
},
|
||||
lightness: {
|
||||
start: 97,
|
||||
end: 32,
|
||||
curve: curve.lightness,
|
||||
},
|
||||
},
|
||||
})
|
@ -1,25 +0,0 @@
|
||||
export interface Curve {
|
||||
name: string
|
||||
value: number[]
|
||||
}
|
||||
|
||||
export interface Curves {
|
||||
lightness: Curve
|
||||
saturation: Curve
|
||||
linear: Curve
|
||||
}
|
||||
|
||||
export const curve: Curves = {
|
||||
lightness: {
|
||||
name: "lightnessCurve",
|
||||
value: [0.2, 0, 0.75, 1.0],
|
||||
},
|
||||
saturation: {
|
||||
name: "saturationCurve",
|
||||
value: [0.67, 0.6, 0.55, 1.0],
|
||||
},
|
||||
linear: {
|
||||
name: "linear",
|
||||
value: [0.5, 0.5, 0.5, 0.5],
|
||||
},
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import chroma from "chroma-js"
|
||||
import * as colorFamily from "./ref/color"
|
||||
|
||||
const color = {
|
||||
lightgray: chroma
|
||||
.scale(colorFamily.lightgray.scale.values)
|
||||
.mode("lch")
|
||||
.colors(9),
|
||||
darkgray: chroma
|
||||
.scale(colorFamily.darkgray.scale.values)
|
||||
.mode("lch")
|
||||
.colors(9),
|
||||
red: chroma.scale(colorFamily.red.scale.values).mode("lch").colors(9),
|
||||
sunset: chroma.scale(colorFamily.sunset.scale.values).mode("lch").colors(9),
|
||||
orange: chroma.scale(colorFamily.orange.scale.values).mode("lch").colors(9),
|
||||
amber: chroma.scale(colorFamily.amber.scale.values).mode("lch").colors(9),
|
||||
yellow: chroma.scale(colorFamily.yellow.scale.values).mode("lch").colors(9),
|
||||
lemon: chroma.scale(colorFamily.lemon.scale.values).mode("lch").colors(9),
|
||||
citron: chroma.scale(colorFamily.citron.scale.values).mode("lch").colors(9),
|
||||
lime: chroma.scale(colorFamily.lime.scale.values).mode("lch").colors(9),
|
||||
green: chroma.scale(colorFamily.green.scale.values).mode("lch").colors(9),
|
||||
mint: chroma.scale(colorFamily.mint.scale.values).mode("lch").colors(9),
|
||||
cyan: chroma.scale(colorFamily.cyan.scale.values).mode("lch").colors(9),
|
||||
sky: chroma.scale(colorFamily.sky.scale.values).mode("lch").colors(9),
|
||||
blue: chroma.scale(colorFamily.blue.scale.values).mode("lch").colors(9),
|
||||
indigo: chroma.scale(colorFamily.indigo.scale.values).mode("lch").colors(9),
|
||||
purple: chroma.scale(colorFamily.purple.scale.values).mode("lch").colors(9),
|
||||
pink: chroma.scale(colorFamily.pink.scale.values).mode("lch").colors(9),
|
||||
rose: chroma.scale(colorFamily.rose.scale.values).mode("lch").colors(9),
|
||||
}
|
||||
|
||||
export { color }
|
@ -1,66 +0,0 @@
|
||||
import { Curve } from "./ref/curves"
|
||||
|
||||
export interface ColorAccessibilityValue {
|
||||
value: number
|
||||
aaPass: boolean
|
||||
aaaPass: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the color contrast between a specified color and its corresponding background and foreground colors.
|
||||
*
|
||||
* @note This implementation is currently basic – Currently we only calculate contrasts against black and white, in the future will allow for dynamic color contrast calculation based on the colors present in a given palette.
|
||||
* @note The goal is to align with WCAG3 accessibility standards as they become stabilized. See the [WCAG 3 Introduction](https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/) for more information.
|
||||
*/
|
||||
export interface ColorAccessibility {
|
||||
black: ColorAccessibilityValue
|
||||
white: ColorAccessibilityValue
|
||||
}
|
||||
|
||||
export type Color = {
|
||||
step: number
|
||||
contrast: ColorAccessibility
|
||||
hex: string
|
||||
lch: number[]
|
||||
rgba: number[]
|
||||
isLight: boolean
|
||||
}
|
||||
|
||||
export interface ColorScale {
|
||||
colors: Color[]
|
||||
// An array of hex values for each color in the scale
|
||||
values: string[]
|
||||
}
|
||||
|
||||
export type ColorFamily = {
|
||||
name: string
|
||||
scale: ColorScale
|
||||
invertedScale: ColorScale
|
||||
}
|
||||
|
||||
export interface ColorFamilyHue {
|
||||
start: number
|
||||
end: number
|
||||
curve: Curve
|
||||
}
|
||||
|
||||
export interface ColorFamilySaturation {
|
||||
start: number
|
||||
end: number
|
||||
curve: Curve
|
||||
}
|
||||
|
||||
export interface ColorFamilyLightness {
|
||||
start: number
|
||||
end: number
|
||||
curve: Curve
|
||||
}
|
||||
|
||||
export interface ColorFamilyConfig {
|
||||
name: string
|
||||
color: {
|
||||
hue: ColorFamilyHue
|
||||
saturation: ColorFamilySaturation
|
||||
lightness: ColorFamilyLightness
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import chroma from "chroma-js"
|
||||
|
||||
export function withOpacity(color: string, opacity: number): string {
|
||||
export function with_opacity(color: string, opacity: number): string {
|
||||
return chroma(color).alpha(opacity).hex()
|
||||
}
|
||||
|
@ -1,286 +0,0 @@
|
||||
import { Scale, Color } from "chroma-js"
|
||||
import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax"
|
||||
export { Syntax, ThemeSyntax, SyntaxHighlightStyle }
|
||||
import {
|
||||
ThemeConfig,
|
||||
ThemeAppearance,
|
||||
ThemeConfigInputColors,
|
||||
} from "./themeConfig"
|
||||
import { getRamps } from "./ramps"
|
||||
|
||||
export interface ColorScheme {
|
||||
name: string
|
||||
isLight: boolean
|
||||
|
||||
lowest: Layer
|
||||
middle: Layer
|
||||
highest: Layer
|
||||
|
||||
ramps: RampSet
|
||||
|
||||
popoverShadow: Shadow
|
||||
modalShadow: Shadow
|
||||
|
||||
players: Players
|
||||
syntax?: Partial<ThemeSyntax>
|
||||
}
|
||||
|
||||
export interface Meta {
|
||||
name: string
|
||||
author: string
|
||||
url: string
|
||||
license: License
|
||||
}
|
||||
|
||||
export interface License {
|
||||
SPDX: SPDXExpression
|
||||
}
|
||||
|
||||
// License name -> License text
|
||||
export interface Licenses {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
// FIXME: Add support for the SPDX expression syntax
|
||||
export type SPDXExpression = "MIT"
|
||||
|
||||
export interface Player {
|
||||
cursor: string
|
||||
selection: string
|
||||
}
|
||||
|
||||
export interface Players {
|
||||
"0": Player
|
||||
"1": Player
|
||||
"2": Player
|
||||
"3": Player
|
||||
"4": Player
|
||||
"5": Player
|
||||
"6": Player
|
||||
"7": Player
|
||||
}
|
||||
|
||||
export interface Shadow {
|
||||
blur: number
|
||||
color: string
|
||||
offset: number[]
|
||||
}
|
||||
|
||||
export type StyleSets = keyof Layer
|
||||
export interface Layer {
|
||||
base: StyleSet
|
||||
variant: StyleSet
|
||||
on: StyleSet
|
||||
accent: StyleSet
|
||||
positive: StyleSet
|
||||
warning: StyleSet
|
||||
negative: StyleSet
|
||||
}
|
||||
|
||||
export interface RampSet {
|
||||
neutral: Scale
|
||||
red: Scale
|
||||
orange: Scale
|
||||
yellow: Scale
|
||||
green: Scale
|
||||
cyan: Scale
|
||||
blue: Scale
|
||||
violet: Scale
|
||||
magenta: Scale
|
||||
}
|
||||
|
||||
export type Styles = keyof StyleSet
|
||||
export interface StyleSet {
|
||||
default: Style
|
||||
active: Style
|
||||
disabled: Style
|
||||
hovered: Style
|
||||
pressed: Style
|
||||
inverted: Style
|
||||
}
|
||||
|
||||
export interface Style {
|
||||
background: string
|
||||
border: string
|
||||
foreground: string
|
||||
}
|
||||
|
||||
export function createColorScheme(theme: ThemeConfig): ColorScheme {
|
||||
const {
|
||||
name,
|
||||
appearance,
|
||||
inputColor,
|
||||
override: { syntax },
|
||||
} = theme
|
||||
|
||||
const isLight = appearance === ThemeAppearance.Light
|
||||
const colorRamps: ThemeConfigInputColors = inputColor
|
||||
|
||||
// Chromajs scales from 0 to 1 flipped if isLight is true
|
||||
const ramps = getRamps(isLight, colorRamps)
|
||||
const lowest = lowestLayer(ramps)
|
||||
const middle = middleLayer(ramps)
|
||||
const highest = highestLayer(ramps)
|
||||
|
||||
const popoverShadow = {
|
||||
blur: 4,
|
||||
color: ramps
|
||||
.neutral(isLight ? 7 : 0)
|
||||
.darken()
|
||||
.alpha(0.2)
|
||||
.hex(), // TODO used blend previously. Replace with something else
|
||||
offset: [1, 2],
|
||||
}
|
||||
|
||||
const modalShadow = {
|
||||
blur: 16,
|
||||
color: ramps
|
||||
.neutral(isLight ? 7 : 0)
|
||||
.darken()
|
||||
.alpha(0.2)
|
||||
.hex(), // TODO used blend previously. Replace with something else
|
||||
offset: [0, 2],
|
||||
}
|
||||
|
||||
const players = {
|
||||
"0": player(ramps.blue),
|
||||
"1": player(ramps.green),
|
||||
"2": player(ramps.magenta),
|
||||
"3": player(ramps.orange),
|
||||
"4": player(ramps.violet),
|
||||
"5": player(ramps.cyan),
|
||||
"6": player(ramps.red),
|
||||
"7": player(ramps.yellow),
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
isLight,
|
||||
|
||||
ramps,
|
||||
|
||||
lowest,
|
||||
middle,
|
||||
highest,
|
||||
|
||||
popoverShadow,
|
||||
modalShadow,
|
||||
|
||||
players,
|
||||
syntax,
|
||||
}
|
||||
}
|
||||
|
||||
function player(ramp: Scale): Player {
|
||||
return {
|
||||
selection: ramp(0.5).alpha(0.24).hex(),
|
||||
cursor: ramp(0.5).hex(),
|
||||
}
|
||||
}
|
||||
|
||||
function lowestLayer(ramps: RampSet): Layer {
|
||||
return {
|
||||
base: buildStyleSet(ramps.neutral, 0.2, 1),
|
||||
variant: buildStyleSet(ramps.neutral, 0.2, 0.7),
|
||||
on: buildStyleSet(ramps.neutral, 0.1, 1),
|
||||
accent: buildStyleSet(ramps.blue, 0.1, 0.5),
|
||||
positive: buildStyleSet(ramps.green, 0.1, 0.5),
|
||||
warning: buildStyleSet(ramps.yellow, 0.1, 0.5),
|
||||
negative: buildStyleSet(ramps.red, 0.1, 0.5),
|
||||
}
|
||||
}
|
||||
|
||||
function middleLayer(ramps: RampSet): Layer {
|
||||
return {
|
||||
base: buildStyleSet(ramps.neutral, 0.1, 1),
|
||||
variant: buildStyleSet(ramps.neutral, 0.1, 0.7),
|
||||
on: buildStyleSet(ramps.neutral, 0, 1),
|
||||
accent: buildStyleSet(ramps.blue, 0.1, 0.5),
|
||||
positive: buildStyleSet(ramps.green, 0.1, 0.5),
|
||||
warning: buildStyleSet(ramps.yellow, 0.1, 0.5),
|
||||
negative: buildStyleSet(ramps.red, 0.1, 0.5),
|
||||
}
|
||||
}
|
||||
|
||||
function highestLayer(ramps: RampSet): Layer {
|
||||
return {
|
||||
base: buildStyleSet(ramps.neutral, 0, 1),
|
||||
variant: buildStyleSet(ramps.neutral, 0, 0.7),
|
||||
on: buildStyleSet(ramps.neutral, 0.1, 1),
|
||||
accent: buildStyleSet(ramps.blue, 0.1, 0.5),
|
||||
positive: buildStyleSet(ramps.green, 0.1, 0.5),
|
||||
warning: buildStyleSet(ramps.yellow, 0.1, 0.5),
|
||||
negative: buildStyleSet(ramps.red, 0.1, 0.5),
|
||||
}
|
||||
}
|
||||
|
||||
function buildStyleSet(
|
||||
ramp: Scale,
|
||||
backgroundBase: number,
|
||||
foregroundBase: number,
|
||||
step: number = 0.08
|
||||
): StyleSet {
|
||||
let styleDefinitions = buildStyleDefinition(
|
||||
backgroundBase,
|
||||
foregroundBase,
|
||||
step
|
||||
)
|
||||
|
||||
function colorString(indexOrColor: number | Color): string {
|
||||
if (typeof indexOrColor === "number") {
|
||||
return ramp(indexOrColor).hex()
|
||||
} else {
|
||||
return indexOrColor.hex()
|
||||
}
|
||||
}
|
||||
|
||||
function buildStyle(style: Styles): Style {
|
||||
return {
|
||||
background: colorString(styleDefinitions.background[style]),
|
||||
border: colorString(styleDefinitions.border[style]),
|
||||
foreground: colorString(styleDefinitions.foreground[style]),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
default: buildStyle("default"),
|
||||
hovered: buildStyle("hovered"),
|
||||
pressed: buildStyle("pressed"),
|
||||
active: buildStyle("active"),
|
||||
disabled: buildStyle("disabled"),
|
||||
inverted: buildStyle("inverted"),
|
||||
}
|
||||
}
|
||||
|
||||
function buildStyleDefinition(
|
||||
bgBase: number,
|
||||
fgBase: number,
|
||||
step: number = 0.08
|
||||
) {
|
||||
return {
|
||||
background: {
|
||||
default: bgBase,
|
||||
hovered: bgBase + step,
|
||||
pressed: bgBase + step * 1.5,
|
||||
active: bgBase + step * 2.2,
|
||||
disabled: bgBase,
|
||||
inverted: fgBase + step * 6,
|
||||
},
|
||||
border: {
|
||||
default: bgBase + step * 1,
|
||||
hovered: bgBase + step,
|
||||
pressed: bgBase + step,
|
||||
active: bgBase + step * 3,
|
||||
disabled: bgBase + step * 0.5,
|
||||
inverted: bgBase - step * 3,
|
||||
},
|
||||
foreground: {
|
||||
default: fgBase,
|
||||
hovered: fgBase,
|
||||
pressed: fgBase,
|
||||
active: fgBase + step * 6,
|
||||
disabled: bgBase + step * 4,
|
||||
inverted: bgBase + step * 2,
|
||||
},
|
||||
}
|
||||
}
|
282
styles/src/theme/color_scheme.ts
Normal file
282
styles/src/theme/color_scheme.ts
Normal file
@ -0,0 +1,282 @@
|
||||
import { Scale, Color } from "chroma-js"
|
||||
import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax"
|
||||
export { Syntax, ThemeSyntax, SyntaxHighlightStyle }
|
||||
import {
|
||||
ThemeConfig,
|
||||
ThemeAppearance,
|
||||
ThemeConfigInputColors,
|
||||
} from "./theme_config"
|
||||
import { get_ramps } from "./ramps"
|
||||
|
||||
export interface ColorScheme {
|
||||
name: string
|
||||
is_light: boolean
|
||||
|
||||
lowest: Layer
|
||||
middle: Layer
|
||||
highest: Layer
|
||||
|
||||
ramps: RampSet
|
||||
|
||||
popover_shadow: Shadow
|
||||
modal_shadow: Shadow
|
||||
|
||||
players: Players
|
||||
syntax?: Partial<ThemeSyntax>
|
||||
}
|
||||
|
||||
export interface Meta {
|
||||
name: string
|
||||
author: string
|
||||
url: string
|
||||
license: License
|
||||
}
|
||||
|
||||
export interface License {
|
||||
SPDX: SPDXExpression
|
||||
}
|
||||
|
||||
// License name -> License text
|
||||
export interface Licenses {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
// FIXME: Add support for the SPDX expression syntax
|
||||
export type SPDXExpression = "MIT"
|
||||
|
||||
export interface Player {
|
||||
cursor: string
|
||||
selection: string
|
||||
}
|
||||
|
||||
export interface Players {
|
||||
"0": Player
|
||||
"1": Player
|
||||
"2": Player
|
||||
"3": Player
|
||||
"4": Player
|
||||
"5": Player
|
||||
"6": Player
|
||||
"7": Player
|
||||
}
|
||||
|
||||
export interface Shadow {
|
||||
blur: number
|
||||
color: string
|
||||
offset: number[]
|
||||
}
|
||||
|
||||
export type StyleSets = keyof Layer
|
||||
export interface Layer {
|
||||
base: StyleSet
|
||||
variant: StyleSet
|
||||
on: StyleSet
|
||||
accent: StyleSet
|
||||
positive: StyleSet
|
||||
warning: StyleSet
|
||||
negative: StyleSet
|
||||
}
|
||||
|
||||
export interface RampSet {
|
||||
neutral: Scale
|
||||
red: Scale
|
||||
orange: Scale
|
||||
yellow: Scale
|
||||
green: Scale
|
||||
cyan: Scale
|
||||
blue: Scale
|
||||
violet: Scale
|
||||
magenta: Scale
|
||||
}
|
||||
|
||||
export type Styles = keyof StyleSet
|
||||
export interface StyleSet {
|
||||
default: Style
|
||||
active: Style
|
||||
disabled: Style
|
||||
hovered: Style
|
||||
pressed: Style
|
||||
inverted: Style
|
||||
}
|
||||
|
||||
export interface Style {
|
||||
background: string
|
||||
border: string
|
||||
foreground: string
|
||||
}
|
||||
|
||||
export function create_color_scheme(theme: ThemeConfig): ColorScheme {
|
||||
const {
|
||||
name,
|
||||
appearance,
|
||||
input_color,
|
||||
override: { syntax },
|
||||
} = theme
|
||||
|
||||
const is_light = appearance === ThemeAppearance.Light
|
||||
const color_ramps: ThemeConfigInputColors = input_color
|
||||
|
||||
// Chromajs scales from 0 to 1 flipped if is_light is true
|
||||
const ramps = get_ramps(is_light, color_ramps)
|
||||
const lowest = lowest_layer(ramps)
|
||||
const middle = middle_layer(ramps)
|
||||
const highest = highest_layer(ramps)
|
||||
|
||||
const popover_shadow = {
|
||||
blur: 4,
|
||||
color: ramps
|
||||
.neutral(is_light ? 7 : 0)
|
||||
.darken()
|
||||
.alpha(0.2)
|
||||
.hex(), // TODO used blend previously. Replace with something else
|
||||
offset: [1, 2],
|
||||
}
|
||||
|
||||
const modal_shadow = {
|
||||
blur: 16,
|
||||
color: ramps
|
||||
.neutral(is_light ? 7 : 0)
|
||||
.darken()
|
||||
.alpha(0.2)
|
||||
.hex(), // TODO used blend previously. Replace with something else
|
||||
offset: [0, 2],
|
||||
}
|
||||
|
||||
const players = {
|
||||
"0": player(ramps.blue),
|
||||
"1": player(ramps.green),
|
||||
"2": player(ramps.magenta),
|
||||
"3": player(ramps.orange),
|
||||
"4": player(ramps.violet),
|
||||
"5": player(ramps.cyan),
|
||||
"6": player(ramps.red),
|
||||
"7": player(ramps.yellow),
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
is_light,
|
||||
|
||||
ramps,
|
||||
|
||||
lowest,
|
||||
middle,
|
||||
highest,
|
||||
|
||||
popover_shadow,
|
||||
modal_shadow,
|
||||
|
||||
players,
|
||||
syntax,
|
||||
}
|
||||
}
|
||||
|
||||
function player(ramp: Scale): Player {
|
||||
return {
|
||||
selection: ramp(0.5).alpha(0.24).hex(),
|
||||
cursor: ramp(0.5).hex(),
|
||||
}
|
||||
}
|
||||
|
||||
function lowest_layer(ramps: RampSet): Layer {
|
||||
return {
|
||||
base: build_style_set(ramps.neutral, 0.2, 1),
|
||||
variant: build_style_set(ramps.neutral, 0.2, 0.7),
|
||||
on: build_style_set(ramps.neutral, 0.1, 1),
|
||||
accent: build_style_set(ramps.blue, 0.1, 0.5),
|
||||
positive: build_style_set(ramps.green, 0.1, 0.5),
|
||||
warning: build_style_set(ramps.yellow, 0.1, 0.5),
|
||||
negative: build_style_set(ramps.red, 0.1, 0.5),
|
||||
}
|
||||
}
|
||||
|
||||
function middle_layer(ramps: RampSet): Layer {
|
||||
return {
|
||||
base: build_style_set(ramps.neutral, 0.1, 1),
|
||||
variant: build_style_set(ramps.neutral, 0.1, 0.7),
|
||||
on: build_style_set(ramps.neutral, 0, 1),
|
||||
accent: build_style_set(ramps.blue, 0.1, 0.5),
|
||||
positive: build_style_set(ramps.green, 0.1, 0.5),
|
||||
warning: build_style_set(ramps.yellow, 0.1, 0.5),
|
||||
negative: build_style_set(ramps.red, 0.1, 0.5),
|
||||
}
|
||||
}
|
||||
|
||||
function highest_layer(ramps: RampSet): Layer {
|
||||
return {
|
||||
base: build_style_set(ramps.neutral, 0, 1),
|
||||
variant: build_style_set(ramps.neutral, 0, 0.7),
|
||||
on: build_style_set(ramps.neutral, 0.1, 1),
|
||||
accent: build_style_set(ramps.blue, 0.1, 0.5),
|
||||
positive: build_style_set(ramps.green, 0.1, 0.5),
|
||||
warning: build_style_set(ramps.yellow, 0.1, 0.5),
|
||||
negative: build_style_set(ramps.red, 0.1, 0.5),
|
||||
}
|
||||
}
|
||||
|
||||
function build_style_set(
|
||||
ramp: Scale,
|
||||
background_base: number,
|
||||
foreground_base: number,
|
||||
step = 0.08
|
||||
): StyleSet {
|
||||
const style_definitions = build_style_definition(
|
||||
background_base,
|
||||
foreground_base,
|
||||
step
|
||||
)
|
||||
|
||||
function color_string(index_or_color: number | Color): string {
|
||||
if (typeof index_or_color === "number") {
|
||||
return ramp(index_or_color).hex()
|
||||
} else {
|
||||
return index_or_color.hex()
|
||||
}
|
||||
}
|
||||
|
||||
function build_style(style: Styles): Style {
|
||||
return {
|
||||
background: color_string(style_definitions.background[style]),
|
||||
border: color_string(style_definitions.border[style]),
|
||||
foreground: color_string(style_definitions.foreground[style]),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
default: build_style("default"),
|
||||
hovered: build_style("hovered"),
|
||||
pressed: build_style("pressed"),
|
||||
active: build_style("active"),
|
||||
disabled: build_style("disabled"),
|
||||
inverted: build_style("inverted"),
|
||||
}
|
||||
}
|
||||
|
||||
function build_style_definition(bg_base: number, fg_base: number, step = 0.08) {
|
||||
return {
|
||||
background: {
|
||||
default: bg_base,
|
||||
hovered: bg_base + step,
|
||||
pressed: bg_base + step * 1.5,
|
||||
active: bg_base + step * 2.2,
|
||||
disabled: bg_base,
|
||||
inverted: fg_base + step * 6,
|
||||
},
|
||||
border: {
|
||||
default: bg_base + step * 1,
|
||||
hovered: bg_base + step,
|
||||
pressed: bg_base + step,
|
||||
active: bg_base + step * 3,
|
||||
disabled: bg_base + step * 0.5,
|
||||
inverted: bg_base - step * 3,
|
||||
},
|
||||
foreground: {
|
||||
default: fg_base,
|
||||
hovered: fg_base,
|
||||
pressed: fg_base,
|
||||
active: fg_base + step * 6,
|
||||
disabled: bg_base + step * 4,
|
||||
inverted: bg_base + step * 2,
|
||||
},
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export * from "./colorScheme"
|
||||
export * from "./color_scheme"
|
||||
export * from "./ramps"
|
||||
export * from "./syntax"
|
||||
export * from "./themeConfig"
|
||||
export * from "./theme_config"
|
||||
|
@ -1,14 +1,14 @@
|
||||
import chroma, { Color, Scale } from "chroma-js"
|
||||
import { RampSet } from "./colorScheme"
|
||||
import { RampSet } from "./color_scheme"
|
||||
import {
|
||||
ThemeConfigInputColors,
|
||||
ThemeConfigInputColorsKeys,
|
||||
} from "./themeConfig"
|
||||
} from "./theme_config"
|
||||
|
||||
export function colorRamp(color: Color): Scale {
|
||||
let endColor = color.desaturate(1).brighten(5)
|
||||
let startColor = color.desaturate(1).darken(4)
|
||||
return chroma.scale([startColor, color, endColor]).mode("lab")
|
||||
export function color_ramp(color: Color): Scale {
|
||||
const end_color = color.desaturate(1).brighten(5)
|
||||
const start_color = color.desaturate(1).darken(4)
|
||||
return chroma.scale([start_color, color, end_color]).mode("lab")
|
||||
}
|
||||
|
||||
/**
|
||||
@ -18,29 +18,29 @@ export function colorRamp(color: Color): Scale {
|
||||
theme so that we don't modify the passed in ramps.
|
||||
This combined with an error in the type definitions for chroma js means we have to cast the colors
|
||||
function to any in order to get the colors back out from the original ramps.
|
||||
* @param isLight
|
||||
* @param colorRamps
|
||||
* @returns
|
||||
* @param is_light
|
||||
* @param color_ramps
|
||||
* @returns
|
||||
*/
|
||||
export function getRamps(
|
||||
isLight: boolean,
|
||||
colorRamps: ThemeConfigInputColors
|
||||
export function get_ramps(
|
||||
is_light: boolean,
|
||||
color_ramps: ThemeConfigInputColors
|
||||
): RampSet {
|
||||
const ramps: RampSet = {} as any
|
||||
const colorsKeys = Object.keys(colorRamps) as ThemeConfigInputColorsKeys[]
|
||||
const ramps: RampSet = {} as any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
const color_keys = Object.keys(color_ramps) as ThemeConfigInputColorsKeys[]
|
||||
|
||||
if (isLight) {
|
||||
for (const rampName of colorsKeys) {
|
||||
ramps[rampName] = chroma.scale(
|
||||
colorRamps[rampName].colors(100).reverse()
|
||||
if (is_light) {
|
||||
for (const ramp_name of color_keys) {
|
||||
ramps[ramp_name] = chroma.scale(
|
||||
color_ramps[ramp_name].colors(100).reverse()
|
||||
)
|
||||
}
|
||||
ramps.neutral = chroma.scale(colorRamps.neutral.colors(100).reverse())
|
||||
ramps.neutral = chroma.scale(color_ramps.neutral.colors(100).reverse())
|
||||
} else {
|
||||
for (const rampName of colorsKeys) {
|
||||
ramps[rampName] = chroma.scale(colorRamps[rampName].colors(100))
|
||||
for (const ramp_name of color_keys) {
|
||||
ramps[ramp_name] = chroma.scale(color_ramps[ramp_name].colors(100))
|
||||
}
|
||||
ramps.neutral = chroma.scale(colorRamps.neutral.colors(100))
|
||||
ramps.neutral = chroma.scale(color_ramps.neutral.colors(100))
|
||||
}
|
||||
|
||||
return ramps
|
||||
|
@ -1,6 +1,6 @@
|
||||
import deepmerge from "deepmerge"
|
||||
import { FontWeight, fontWeights } from "../common"
|
||||
import { ColorScheme } from "./colorScheme"
|
||||
import { FontWeight, font_weights } from "../common"
|
||||
import { ColorScheme } from "./color_scheme"
|
||||
import chroma from "chroma-js"
|
||||
|
||||
export interface SyntaxHighlightStyle {
|
||||
@ -22,8 +22,8 @@ export interface Syntax {
|
||||
emphasis: SyntaxHighlightStyle
|
||||
"emphasis.strong": SyntaxHighlightStyle
|
||||
title: SyntaxHighlightStyle
|
||||
linkUri: SyntaxHighlightStyle
|
||||
linkText: SyntaxHighlightStyle
|
||||
link_uri: SyntaxHighlightStyle
|
||||
link_text: SyntaxHighlightStyle
|
||||
/** md: indented_code_block, fenced_code_block, code_span */
|
||||
"text.literal": SyntaxHighlightStyle
|
||||
|
||||
@ -56,7 +56,7 @@ export interface Syntax {
|
||||
|
||||
// == Types ====== /
|
||||
// We allow Function here because all JS objects literals have this property
|
||||
constructor: SyntaxHighlightStyle | Function
|
||||
constructor: SyntaxHighlightStyle | Function // eslint-disable-line @typescript-eslint/ban-types
|
||||
variant: SyntaxHighlightStyle
|
||||
type: SyntaxHighlightStyle
|
||||
// js: predefined_type
|
||||
@ -116,13 +116,13 @@ export interface Syntax {
|
||||
|
||||
export type ThemeSyntax = Partial<Syntax>
|
||||
|
||||
const defaultSyntaxHighlightStyle: Omit<SyntaxHighlightStyle, "color"> = {
|
||||
const default_syntax_highlight_style: Omit<SyntaxHighlightStyle, "color"> = {
|
||||
weight: "normal",
|
||||
underline: false,
|
||||
italic: false,
|
||||
}
|
||||
|
||||
function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
// Make a temporary object that is allowed to be missing
|
||||
// the "color" property for each style
|
||||
const syntax: {
|
||||
@ -132,7 +132,7 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
// then spread the default to each style
|
||||
for (const key of Object.keys({} as Syntax)) {
|
||||
syntax[key as keyof Syntax] = {
|
||||
...defaultSyntaxHighlightStyle,
|
||||
...default_syntax_highlight_style,
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,35 +140,35 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
// predictive color distinct from any other color in the theme
|
||||
const predictive = chroma
|
||||
.mix(
|
||||
colorScheme.ramps.neutral(0.4).hex(),
|
||||
colorScheme.ramps.blue(0.4).hex(),
|
||||
color_scheme.ramps.neutral(0.4).hex(),
|
||||
color_scheme.ramps.blue(0.4).hex(),
|
||||
0.45,
|
||||
"lch"
|
||||
)
|
||||
.hex()
|
||||
|
||||
const color = {
|
||||
primary: colorScheme.ramps.neutral(1).hex(),
|
||||
comment: colorScheme.ramps.neutral(0.71).hex(),
|
||||
punctuation: colorScheme.ramps.neutral(0.86).hex(),
|
||||
primary: color_scheme.ramps.neutral(1).hex(),
|
||||
comment: color_scheme.ramps.neutral(0.71).hex(),
|
||||
punctuation: color_scheme.ramps.neutral(0.86).hex(),
|
||||
predictive: predictive,
|
||||
emphasis: colorScheme.ramps.blue(0.5).hex(),
|
||||
string: colorScheme.ramps.orange(0.5).hex(),
|
||||
function: colorScheme.ramps.yellow(0.5).hex(),
|
||||
type: colorScheme.ramps.cyan(0.5).hex(),
|
||||
constructor: colorScheme.ramps.blue(0.5).hex(),
|
||||
variant: colorScheme.ramps.blue(0.5).hex(),
|
||||
property: colorScheme.ramps.blue(0.5).hex(),
|
||||
enum: colorScheme.ramps.orange(0.5).hex(),
|
||||
operator: colorScheme.ramps.orange(0.5).hex(),
|
||||
number: colorScheme.ramps.green(0.5).hex(),
|
||||
boolean: colorScheme.ramps.green(0.5).hex(),
|
||||
constant: colorScheme.ramps.green(0.5).hex(),
|
||||
keyword: colorScheme.ramps.blue(0.5).hex(),
|
||||
emphasis: color_scheme.ramps.blue(0.5).hex(),
|
||||
string: color_scheme.ramps.orange(0.5).hex(),
|
||||
function: color_scheme.ramps.yellow(0.5).hex(),
|
||||
type: color_scheme.ramps.cyan(0.5).hex(),
|
||||
constructor: color_scheme.ramps.blue(0.5).hex(),
|
||||
variant: color_scheme.ramps.blue(0.5).hex(),
|
||||
property: color_scheme.ramps.blue(0.5).hex(),
|
||||
enum: color_scheme.ramps.orange(0.5).hex(),
|
||||
operator: color_scheme.ramps.orange(0.5).hex(),
|
||||
number: color_scheme.ramps.green(0.5).hex(),
|
||||
boolean: color_scheme.ramps.green(0.5).hex(),
|
||||
constant: color_scheme.ramps.green(0.5).hex(),
|
||||
keyword: color_scheme.ramps.blue(0.5).hex(),
|
||||
}
|
||||
|
||||
// Then assign colors and use Syntax to enforce each style getting it's own color
|
||||
const defaultSyntax: Syntax = {
|
||||
const default_syntax: Syntax = {
|
||||
...syntax,
|
||||
comment: {
|
||||
color: color.comment,
|
||||
@ -188,18 +188,18 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
},
|
||||
"emphasis.strong": {
|
||||
color: color.emphasis,
|
||||
weight: fontWeights.bold,
|
||||
weight: font_weights.bold,
|
||||
},
|
||||
title: {
|
||||
color: color.primary,
|
||||
weight: fontWeights.bold,
|
||||
weight: font_weights.bold,
|
||||
},
|
||||
linkUri: {
|
||||
color: colorScheme.ramps.green(0.5).hex(),
|
||||
link_uri: {
|
||||
color: color_scheme.ramps.green(0.5).hex(),
|
||||
underline: true,
|
||||
},
|
||||
linkText: {
|
||||
color: colorScheme.ramps.orange(0.5).hex(),
|
||||
link_text: {
|
||||
color: color_scheme.ramps.orange(0.5).hex(),
|
||||
italic: true,
|
||||
},
|
||||
"text.literal": {
|
||||
@ -215,7 +215,7 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
color: color.punctuation,
|
||||
},
|
||||
"punctuation.special": {
|
||||
color: colorScheme.ramps.neutral(0.86).hex(),
|
||||
color: color_scheme.ramps.neutral(0.86).hex(),
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
color: color.punctuation,
|
||||
@ -236,10 +236,10 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
color: color.string,
|
||||
},
|
||||
constructor: {
|
||||
color: colorScheme.ramps.blue(0.5).hex(),
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
variant: {
|
||||
color: colorScheme.ramps.blue(0.5).hex(),
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
type: {
|
||||
color: color.type,
|
||||
@ -248,16 +248,16 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
color: color.primary,
|
||||
},
|
||||
label: {
|
||||
color: colorScheme.ramps.blue(0.5).hex(),
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
tag: {
|
||||
color: colorScheme.ramps.blue(0.5).hex(),
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
attribute: {
|
||||
color: colorScheme.ramps.blue(0.5).hex(),
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
property: {
|
||||
color: colorScheme.ramps.blue(0.5).hex(),
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
constant: {
|
||||
color: color.constant,
|
||||
@ -288,17 +288,20 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
|
||||
},
|
||||
}
|
||||
|
||||
return defaultSyntax
|
||||
return default_syntax
|
||||
}
|
||||
|
||||
function mergeSyntax(defaultSyntax: Syntax, colorScheme: ColorScheme): Syntax {
|
||||
if (!colorScheme.syntax) {
|
||||
return defaultSyntax
|
||||
function merge_syntax(
|
||||
default_syntax: Syntax,
|
||||
color_scheme: ColorScheme
|
||||
): Syntax {
|
||||
if (!color_scheme.syntax) {
|
||||
return default_syntax
|
||||
}
|
||||
|
||||
return deepmerge<Syntax, Partial<ThemeSyntax>>(
|
||||
defaultSyntax,
|
||||
colorScheme.syntax,
|
||||
default_syntax,
|
||||
color_scheme.syntax,
|
||||
{
|
||||
arrayMerge: (destinationArray, sourceArray) => [
|
||||
...destinationArray,
|
||||
@ -308,10 +311,10 @@ function mergeSyntax(defaultSyntax: Syntax, colorScheme: ColorScheme): Syntax {
|
||||
)
|
||||
}
|
||||
|
||||
export function buildSyntax(colorScheme: ColorScheme): Syntax {
|
||||
const defaultSyntax: Syntax = buildDefaultSyntax(colorScheme)
|
||||
export function build_syntax(color_scheme: ColorScheme): Syntax {
|
||||
const default_syntax: Syntax = build_default_syntax(color_scheme)
|
||||
|
||||
const syntax = mergeSyntax(defaultSyntax, colorScheme)
|
||||
const syntax = merge_syntax(default_syntax, color_scheme)
|
||||
|
||||
return syntax
|
||||
}
|
||||
|
@ -17,15 +17,15 @@ interface ThemeMeta {
|
||||
*
|
||||
* Example: `MIT`
|
||||
*/
|
||||
licenseType?: string | ThemeLicenseType
|
||||
licenseUrl?: string
|
||||
licenseFile: string
|
||||
themeUrl?: string
|
||||
license_type?: string | ThemeLicenseType
|
||||
license_url?: string
|
||||
license_file: string
|
||||
theme_url?: string
|
||||
}
|
||||
|
||||
export type ThemeFamilyMeta = Pick<
|
||||
ThemeMeta,
|
||||
"name" | "author" | "licenseType" | "licenseUrl"
|
||||
"name" | "author" | "license_type" | "license_url"
|
||||
>
|
||||
|
||||
export interface ThemeConfigInputColors {
|
||||
@ -62,7 +62,7 @@ interface ThemeConfigOverrides {
|
||||
}
|
||||
|
||||
type ThemeConfigProperties = ThemeMeta & {
|
||||
inputColor: ThemeConfigInputColors
|
||||
input_color: ThemeConfigInputColors
|
||||
override: ThemeConfigOverrides
|
||||
}
|
||||
|
@ -1,99 +0,0 @@
|
||||
import {
|
||||
SingleBoxShadowToken,
|
||||
SingleColorToken,
|
||||
SingleOtherToken,
|
||||
TokenTypes,
|
||||
} from "@tokens-studio/types"
|
||||
import {
|
||||
ColorScheme,
|
||||
Shadow,
|
||||
SyntaxHighlightStyle,
|
||||
ThemeSyntax,
|
||||
} from "../colorScheme"
|
||||
import { LayerToken, layerToken } from "./layer"
|
||||
import { PlayersToken, playersToken } from "./players"
|
||||
import { colorToken } from "./token"
|
||||
import { Syntax } from "../syntax"
|
||||
import editor from "../../styleTree/editor"
|
||||
|
||||
interface ColorSchemeTokens {
|
||||
name: SingleOtherToken
|
||||
appearance: SingleOtherToken
|
||||
lowest: LayerToken
|
||||
middle: LayerToken
|
||||
highest: LayerToken
|
||||
players: PlayersToken
|
||||
popoverShadow: SingleBoxShadowToken
|
||||
modalShadow: SingleBoxShadowToken
|
||||
syntax?: Partial<ThemeSyntaxColorTokens>
|
||||
}
|
||||
|
||||
const createShadowToken = (
|
||||
shadow: Shadow,
|
||||
tokenName: string
|
||||
): SingleBoxShadowToken => {
|
||||
return {
|
||||
name: tokenName,
|
||||
type: TokenTypes.BOX_SHADOW,
|
||||
value: `${shadow.offset[0]}px ${shadow.offset[1]}px ${shadow.blur}px 0px ${shadow.color}`,
|
||||
}
|
||||
}
|
||||
|
||||
const popoverShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => {
|
||||
const shadow = colorScheme.popoverShadow
|
||||
return createShadowToken(shadow, "popoverShadow")
|
||||
}
|
||||
|
||||
const modalShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => {
|
||||
const shadow = colorScheme.modalShadow
|
||||
return createShadowToken(shadow, "modalShadow")
|
||||
}
|
||||
|
||||
type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
|
||||
|
||||
function syntaxHighlightStyleColorTokens(
|
||||
syntax: Syntax
|
||||
): ThemeSyntaxColorTokens {
|
||||
const styleKeys = Object.keys(syntax) as (keyof Syntax)[]
|
||||
|
||||
return styleKeys.reduce((acc, styleKey) => {
|
||||
// Hack: The type of a style could be "Function"
|
||||
// This can happen because we have a "constructor" property on the syntax object
|
||||
// and a "constructor" property on the prototype of the syntax object
|
||||
// To work around this just assert that the type of the style is not a function
|
||||
if (!syntax[styleKey] || typeof syntax[styleKey] === "function")
|
||||
return acc
|
||||
const { color } = syntax[styleKey] as Required<SyntaxHighlightStyle>
|
||||
return { ...acc, [styleKey]: colorToken(styleKey, color) }
|
||||
}, {} as ThemeSyntaxColorTokens)
|
||||
}
|
||||
|
||||
const syntaxTokens = (
|
||||
colorScheme: ColorScheme
|
||||
): ColorSchemeTokens["syntax"] => {
|
||||
const syntax = editor(colorScheme).syntax
|
||||
|
||||
return syntaxHighlightStyleColorTokens(syntax)
|
||||
}
|
||||
|
||||
export function colorSchemeTokens(colorScheme: ColorScheme): ColorSchemeTokens {
|
||||
return {
|
||||
name: {
|
||||
name: "themeName",
|
||||
value: colorScheme.name,
|
||||
type: TokenTypes.OTHER,
|
||||
},
|
||||
appearance: {
|
||||
name: "themeAppearance",
|
||||
value: colorScheme.isLight ? "light" : "dark",
|
||||
type: TokenTypes.OTHER,
|
||||
},
|
||||
lowest: layerToken(colorScheme.lowest, "lowest"),
|
||||
middle: layerToken(colorScheme.middle, "middle"),
|
||||
highest: layerToken(colorScheme.highest, "highest"),
|
||||
popoverShadow: popoverShadowToken(colorScheme),
|
||||
modalShadow: modalShadowToken(colorScheme),
|
||||
players: playersToken(colorScheme),
|
||||
syntax: syntaxTokens(colorScheme),
|
||||
}
|
||||
}
|
97
styles/src/theme/tokens/color_scheme.ts
Normal file
97
styles/src/theme/tokens/color_scheme.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import {
|
||||
SingleBoxShadowToken,
|
||||
SingleColorToken,
|
||||
SingleOtherToken,
|
||||
TokenTypes,
|
||||
} from "@tokens-studio/types"
|
||||
import {
|
||||
ColorScheme,
|
||||
Shadow,
|
||||
SyntaxHighlightStyle,
|
||||
ThemeSyntax,
|
||||
} from "../color_scheme"
|
||||
import { LayerToken, layer_token } from "./layer"
|
||||
import { PlayersToken, players_token } from "./players"
|
||||
import { color_token } from "./token"
|
||||
import { Syntax } from "../syntax"
|
||||
import editor from "../../style_tree/editor"
|
||||
|
||||
interface ColorSchemeTokens {
|
||||
name: SingleOtherToken
|
||||
appearance: SingleOtherToken
|
||||
lowest: LayerToken
|
||||
middle: LayerToken
|
||||
highest: LayerToken
|
||||
players: PlayersToken
|
||||
popover_shadow: SingleBoxShadowToken
|
||||
modal_shadow: SingleBoxShadowToken
|
||||
syntax?: Partial<ThemeSyntaxColorTokens>
|
||||
}
|
||||
|
||||
const create_shadow_token = (
|
||||
shadow: Shadow,
|
||||
token_name: string
|
||||
): SingleBoxShadowToken => {
|
||||
return {
|
||||
name: token_name,
|
||||
type: TokenTypes.BOX_SHADOW,
|
||||
value: `${shadow.offset[0]}px ${shadow.offset[1]}px ${shadow.blur}px 0px ${shadow.color}`,
|
||||
}
|
||||
}
|
||||
|
||||
const popover_shadow_token = (theme: ColorScheme): SingleBoxShadowToken => {
|
||||
const shadow = theme.popover_shadow
|
||||
return create_shadow_token(shadow, "popover_shadow")
|
||||
}
|
||||
|
||||
const modal_shadow_token = (theme: ColorScheme): SingleBoxShadowToken => {
|
||||
const shadow = theme.modal_shadow
|
||||
return create_shadow_token(shadow, "modal_shadow")
|
||||
}
|
||||
|
||||
type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
|
||||
|
||||
function syntax_highlight_style_color_tokens(
|
||||
syntax: Syntax
|
||||
): ThemeSyntaxColorTokens {
|
||||
const style_keys = Object.keys(syntax) as (keyof Syntax)[]
|
||||
|
||||
return style_keys.reduce((acc, style_key) => {
|
||||
// Hack: The type of a style could be "Function"
|
||||
// This can happen because we have a "constructor" property on the syntax object
|
||||
// and a "constructor" property on the prototype of the syntax object
|
||||
// To work around this just assert that the type of the style is not a function
|
||||
if (!syntax[style_key] || typeof syntax[style_key] === "function")
|
||||
return acc
|
||||
const { color } = syntax[style_key] as Required<SyntaxHighlightStyle>
|
||||
return { ...acc, [style_key]: color_token(style_key, color) }
|
||||
}, {} as ThemeSyntaxColorTokens)
|
||||
}
|
||||
|
||||
const syntax_tokens = (theme: ColorScheme): ColorSchemeTokens["syntax"] => {
|
||||
const syntax = editor(theme).syntax
|
||||
|
||||
return syntax_highlight_style_color_tokens(syntax)
|
||||
}
|
||||
|
||||
export function theme_tokens(theme: ColorScheme): ColorSchemeTokens {
|
||||
return {
|
||||
name: {
|
||||
name: "themeName",
|
||||
value: theme.name,
|
||||
type: TokenTypes.OTHER,
|
||||
},
|
||||
appearance: {
|
||||
name: "themeAppearance",
|
||||
value: theme.is_light ? "light" : "dark",
|
||||
type: TokenTypes.OTHER,
|
||||
},
|
||||
lowest: layer_token(theme.lowest, "lowest"),
|
||||
middle: layer_token(theme.middle, "middle"),
|
||||
highest: layer_token(theme.highest, "highest"),
|
||||
popover_shadow: popover_shadow_token(theme),
|
||||
modal_shadow: modal_shadow_token(theme),
|
||||
players: players_token(theme),
|
||||
syntax: syntax_tokens(theme),
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { SingleColorToken } from "@tokens-studio/types"
|
||||
import { Layer, Style, StyleSet } from "../colorScheme"
|
||||
import { colorToken } from "./token"
|
||||
import { Layer, Style, StyleSet } from "../color_scheme"
|
||||
import { color_token } from "./token"
|
||||
|
||||
interface StyleToken {
|
||||
background: SingleColorToken
|
||||
@ -27,36 +27,36 @@ export interface LayerToken {
|
||||
negative: StyleSetToken
|
||||
}
|
||||
|
||||
export const styleToken = (style: Style, name: string): StyleToken => {
|
||||
export const style_token = (style: Style, name: string): StyleToken => {
|
||||
const token = {
|
||||
background: colorToken(`${name}Background`, style.background),
|
||||
border: colorToken(`${name}Border`, style.border),
|
||||
foreground: colorToken(`${name}Foreground`, style.foreground),
|
||||
background: color_token(`${name}Background`, style.background),
|
||||
border: color_token(`${name}Border`, style.border),
|
||||
foreground: color_token(`${name}Foreground`, style.foreground),
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
export const styleSetToken = (
|
||||
styleSet: StyleSet,
|
||||
export const style_set_token = (
|
||||
style_set: StyleSet,
|
||||
name: string
|
||||
): StyleSetToken => {
|
||||
const token: StyleSetToken = {} as StyleSetToken
|
||||
|
||||
for (const style in styleSet) {
|
||||
for (const style in style_set) {
|
||||
const s = style as keyof StyleSet
|
||||
token[s] = styleToken(styleSet[s], `${name}${style}`)
|
||||
token[s] = style_token(style_set[s], `${name}${style}`)
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
export const layerToken = (layer: Layer, name: string): LayerToken => {
|
||||
export const layer_token = (layer: Layer, name: string): LayerToken => {
|
||||
const token: LayerToken = {} as LayerToken
|
||||
|
||||
for (const styleSet in layer) {
|
||||
const s = styleSet as keyof Layer
|
||||
token[s] = styleSetToken(layer[s], `${name}${styleSet}`)
|
||||
for (const style_set in layer) {
|
||||
const s = style_set as keyof Layer
|
||||
token[s] = style_set_token(layer[s], `${name}${style_set}`)
|
||||
}
|
||||
|
||||
return token
|
||||
|
@ -1,36 +1,33 @@
|
||||
import { SingleColorToken } from "@tokens-studio/types"
|
||||
import { ColorScheme, Players } from "../../common"
|
||||
import { colorToken } from "./token"
|
||||
import { color_token } from "./token"
|
||||
import { ColorScheme, Players } from "../color_scheme"
|
||||
|
||||
export type PlayerToken = Record<"selection" | "cursor", SingleColorToken>
|
||||
|
||||
export type PlayersToken = Record<keyof Players, PlayerToken>
|
||||
|
||||
function buildPlayerToken(
|
||||
colorScheme: ColorScheme,
|
||||
index: number
|
||||
): PlayerToken {
|
||||
const playerNumber = index.toString() as keyof Players
|
||||
function build_player_token(theme: ColorScheme, index: number): PlayerToken {
|
||||
const player_number = index.toString() as keyof Players
|
||||
|
||||
return {
|
||||
selection: colorToken(
|
||||
selection: color_token(
|
||||
`player${index}Selection`,
|
||||
colorScheme.players[playerNumber].selection
|
||||
theme.players[player_number].selection
|
||||
),
|
||||
cursor: colorToken(
|
||||
cursor: color_token(
|
||||
`player${index}Cursor`,
|
||||
colorScheme.players[playerNumber].cursor
|
||||
theme.players[player_number].cursor
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
export const playersToken = (colorScheme: ColorScheme): PlayersToken => ({
|
||||
"0": buildPlayerToken(colorScheme, 0),
|
||||
"1": buildPlayerToken(colorScheme, 1),
|
||||
"2": buildPlayerToken(colorScheme, 2),
|
||||
"3": buildPlayerToken(colorScheme, 3),
|
||||
"4": buildPlayerToken(colorScheme, 4),
|
||||
"5": buildPlayerToken(colorScheme, 5),
|
||||
"6": buildPlayerToken(colorScheme, 6),
|
||||
"7": buildPlayerToken(colorScheme, 7),
|
||||
export const players_token = (theme: ColorScheme): PlayersToken => ({
|
||||
"0": build_player_token(theme, 0),
|
||||
"1": build_player_token(theme, 1),
|
||||
"2": build_player_token(theme, 2),
|
||||
"3": build_player_token(theme, 3),
|
||||
"4": build_player_token(theme, 4),
|
||||
"5": build_player_token(theme, 5),
|
||||
"6": build_player_token(theme, 6),
|
||||
"7": build_player_token(theme, 7),
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { SingleColorToken, TokenTypes } from "@tokens-studio/types"
|
||||
|
||||
export function colorToken(
|
||||
export function color_token(
|
||||
name: string,
|
||||
value: string,
|
||||
description?: string
|
||||
|
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {
|
||||
chroma,
|
||||
colorRamp,
|
||||
color_ramp,
|
||||
ThemeAppearance,
|
||||
ThemeLicenseType,
|
||||
ThemeConfig,
|
||||
@ -10,10 +10,10 @@ export const dark: ThemeConfig = {
|
||||
name: "Andromeda",
|
||||
author: "EliverLara",
|
||||
appearance: ThemeAppearance.Dark,
|
||||
licenseType: ThemeLicenseType.MIT,
|
||||
licenseUrl: "https://github.com/EliverLara/Andromeda",
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: ThemeLicenseType.MIT,
|
||||
license_url: "https://github.com/EliverLara/Andromeda",
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma
|
||||
.scale([
|
||||
"#1E2025",
|
||||
@ -26,14 +26,14 @@ export const dark: ThemeConfig = {
|
||||
"#F7F7F8",
|
||||
])
|
||||
.domain([0, 0.15, 0.25, 0.35, 0.7, 0.8, 0.9, 1]),
|
||||
red: colorRamp(chroma("#F92672")),
|
||||
orange: colorRamp(chroma("#F39C12")),
|
||||
yellow: colorRamp(chroma("#FFE66D")),
|
||||
green: colorRamp(chroma("#96E072")),
|
||||
cyan: colorRamp(chroma("#00E8C6")),
|
||||
blue: colorRamp(chroma("#0CA793")),
|
||||
violet: colorRamp(chroma("#8A3FA6")),
|
||||
magenta: colorRamp(chroma("#C74DED")),
|
||||
red: color_ramp(chroma("#F92672")),
|
||||
orange: color_ramp(chroma("#F39C12")),
|
||||
yellow: color_ramp(chroma("#FFE66D")),
|
||||
green: color_ramp(chroma("#96E072")),
|
||||
cyan: color_ramp(chroma("#00E8C6")),
|
||||
blue: color_ramp(chroma("#0CA793")),
|
||||
violet: color_ramp(chroma("#8A3FA6")),
|
||||
magenta: color_ramp(chroma("#C74DED")),
|
||||
},
|
||||
override: { syntax: {} },
|
||||
}
|
||||
|
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Cave Dark`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Dark,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale([
|
||||
colors.base00,
|
||||
colors.base01,
|
||||
@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base06,
|
||||
colors.base07,
|
||||
]),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Cave Light`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Light,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale(
|
||||
[
|
||||
colors.base00,
|
||||
@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base07,
|
||||
].reverse()
|
||||
),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Dune Dark`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Dark,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale([
|
||||
colors.base00,
|
||||
colors.base01,
|
||||
@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base06,
|
||||
colors.base07,
|
||||
]),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Dune Light`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Light,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale(
|
||||
[
|
||||
colors.base00,
|
||||
@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base07,
|
||||
].reverse()
|
||||
),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Estuary Dark`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Dark,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale([
|
||||
colors.base00,
|
||||
colors.base01,
|
||||
@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base06,
|
||||
colors.base07,
|
||||
]),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Estuary Light`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Light,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale(
|
||||
[
|
||||
colors.base00,
|
||||
@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base07,
|
||||
].reverse()
|
||||
),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Forest Dark`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Dark,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale([
|
||||
colors.base00,
|
||||
colors.base01,
|
||||
@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base06,
|
||||
colors.base07,
|
||||
]),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
|
||||
import { meta, buildSyntax, Variant } from "./common"
|
||||
import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
|
||||
import { meta, build_syntax, Variant } from "./common"
|
||||
|
||||
const variant: Variant = {
|
||||
colors: {
|
||||
@ -22,19 +22,19 @@ const variant: Variant = {
|
||||
},
|
||||
}
|
||||
|
||||
const syntax = buildSyntax(variant)
|
||||
const syntax = build_syntax(variant)
|
||||
|
||||
const getTheme = (variant: Variant): ThemeConfig => {
|
||||
const get_theme = (variant: Variant): ThemeConfig => {
|
||||
const { colors } = variant
|
||||
|
||||
return {
|
||||
name: `${meta.name} Forest Light`,
|
||||
author: meta.author,
|
||||
appearance: ThemeAppearance.Light,
|
||||
licenseType: meta.licenseType,
|
||||
licenseUrl: meta.licenseUrl,
|
||||
licenseFile: `${__dirname}/LICENSE`,
|
||||
inputColor: {
|
||||
license_type: meta.license_type,
|
||||
license_url: meta.license_url,
|
||||
license_file: `${__dirname}/LICENSE`,
|
||||
input_color: {
|
||||
neutral: chroma.scale(
|
||||
[
|
||||
colors.base00,
|
||||
@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
|
||||
colors.base07,
|
||||
].reverse()
|
||||
),
|
||||
red: colorRamp(chroma(colors.base08)),
|
||||
orange: colorRamp(chroma(colors.base09)),
|
||||
yellow: colorRamp(chroma(colors.base0A)),
|
||||
green: colorRamp(chroma(colors.base0B)),
|
||||
cyan: colorRamp(chroma(colors.base0C)),
|
||||
blue: colorRamp(chroma(colors.base0D)),
|
||||
violet: colorRamp(chroma(colors.base0E)),
|
||||
magenta: colorRamp(chroma(colors.base0F)),
|
||||
red: color_ramp(chroma(colors.base08)),
|
||||
orange: color_ramp(chroma(colors.base09)),
|
||||
yellow: color_ramp(chroma(colors.base0A)),
|
||||
green: color_ramp(chroma(colors.base0B)),
|
||||
cyan: color_ramp(chroma(colors.base0C)),
|
||||
blue: color_ramp(chroma(colors.base0D)),
|
||||
violet: color_ramp(chroma(colors.base0E)),
|
||||
magenta: color_ramp(chroma(colors.base0F)),
|
||||
},
|
||||
override: { syntax },
|
||||
}
|
||||
}
|
||||
|
||||
export const theme = getTheme(variant)
|
||||
export const theme = get_theme(variant)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user