Add tooltips to all buttons and tweak hover colors

This commit is contained in:
Misode
2021-09-25 07:10:54 +02:00
parent 7db47938b8
commit 2cb14a2c10
13 changed files with 251 additions and 96 deletions

View File

@@ -4,11 +4,13 @@ type BtnProps = {
icon?: keyof typeof Octicon,
label?: string,
active?: boolean,
tooltip?: string,
tooltipLoc?: 'se' | 'sw' | 'nw',
class?: string,
onClick?: (event: MouseEvent) => unknown,
}
export function Btn({ icon, label, active, class: class_, onClick }: BtnProps) {
return <div class={`btn${active ? ' active' : ''}${class_ ? ` ${class_}` : ''}`} onClick={onClick}>
export function Btn({ icon, label, active, class: clazz, tooltip, tooltipLoc, onClick }: BtnProps) {
return <div class={`btn${active ? ' active' : ''}${clazz ? ` ${clazz}` : ''}${tooltip ? ` tooltipped tip-${tooltipLoc ?? 'sw'}` : ''}`} onClick={onClick} aria-label={tooltip}>
{icon && Octicon[icon]}
{label && <span>{label}</span>}
</div>

View File

@@ -7,9 +7,10 @@ type BtnInputProps = {
large?: boolean,
doSelect?: number,
value?: string,
placeholder?: string,
onChange?: (value: string) => unknown,
}
export function BtnInput({ icon, label, large, doSelect, value, onChange }: BtnInputProps) {
export function BtnInput({ icon, label, large, doSelect, value, placeholder, onChange }: BtnInputProps) {
const onInput = onChange === undefined ? () => {} : (e: any) => {
const value = (e.target as HTMLInputElement).value
onChange?.(value)
@@ -25,6 +26,6 @@ export function BtnInput({ icon, label, large, doSelect, value, onChange }: BtnI
return <div class={`btn btn-input ${large ? 'large-input' : ''}`} onClick={e => e.stopPropagation()}>
{icon && Octicon[icon]}
{label && <span>{label}</span>}
<input ref={ref} type="text" value={value} onChange={onInput} />
<input ref={ref} type="text" value={value} onChange={onInput} placeholder={placeholder} />
</div>
}

View File

@@ -7,13 +7,14 @@ type BtnMenuProps = {
icon?: keyof typeof Octicon,
label?: string,
relative?: boolean,
tooltip?: string,
children: ComponentChildren,
}
export function BtnMenu({ icon, label, relative, children }: BtnMenuProps) {
export function BtnMenu({ icon, label, relative, tooltip, children }: BtnMenuProps) {
const [active, setActive] = useFocus()
return <div class={`btn-menu${relative === false ? ' no-relative' : ''}`}>
<Btn icon={icon} label={label} onClick={setActive} />
<Btn {...{icon, label, tooltip}} onClick={setActive} />
{active && <div class="btn-group">
{children}
</div>}

View File

@@ -27,9 +27,9 @@ export function Header({ lang, title, version, theme, changeTheme, language, cha
return <header>
<div class="title">
<Link class="home-link" href="/">{Icons.home}</Link>
<Link class="home-link" href="/" aria-label={loc('home')}>{Icons.home}</Link>
<h2>{title}</h2>
{gen && <BtnMenu icon="chevron_down">
{gen && <BtnMenu icon="chevron_down" tooltip={loc('switch_generator')}>
{config.generators
.filter(g => g.category === gen?.category && checkVersion(version, g.minVersion))
.map(g =>
@@ -40,7 +40,7 @@ export function Header({ lang, title, version, theme, changeTheme, language, cha
<nav>
<ul>
<li>
<BtnMenu icon="globe">
<BtnMenu icon="globe" tooltip={loc('language')}>
{config.languages.map(({ code, name }) =>
<Btn label={name} active={code === language}
onClick={() => changeLanguage(code)} />
@@ -48,7 +48,7 @@ export function Header({ lang, title, version, theme, changeTheme, language, cha
</BtnMenu>
</li>
<li>
<BtnMenu icon={Themes[theme]}>
<BtnMenu icon={Themes[theme]} tooltip={loc('theme')}>
{Object.entries(Themes).map(([th, icon]) =>
<Btn icon={icon} label={loc(`theme.${th}`)} active={th === theme}
onClick={() => changeTheme(th)} />
@@ -56,7 +56,7 @@ export function Header({ lang, title, version, theme, changeTheme, language, cha
</BtnMenu>
</li>
<li class="dimmed">
<a href="https://github.com/misode/misode.github.io" target="_blank" rel="noreferrer" title={loc('github')}>
<a href="https://github.com/misode/misode.github.io" target="_blank" rel="noreferrer" class="tooltipped tip-sw" aria-label={loc('github')}>
{Octicon.mark_github}
</a>
</li>

View File

@@ -37,7 +37,7 @@ export function SourcePanel({ lang, name, model, blockStates, doCopy, doDownload
const getOutput = useCallback((model: DataModel, blockStates: BlockStateRegistry) => {
const data = model.schema.hook(transformOutput, new ModelPath(model), model.data, { blockStates })
return JSON.stringify(data, null, INDENT[indent]) + '\n'
}, [])
}, [indent])
useEffect(() => {
retransform.current = () => {
@@ -109,7 +109,7 @@ export function SourcePanel({ lang, name, model, blockStates, doCopy, doDownload
return <>
<div class="controls">
<BtnMenu icon="gear">
<BtnMenu icon="gear" tooltip={loc('output_settings')}>
{Object.entries(INDENT).map(([key]) =>
<Btn label={loc(`indentation.${key}`)} active={indent === key}
onClick={() => changeIndent(key)}/>

View File

@@ -5,10 +5,11 @@ import { useEffect, useRef, useState } from 'preact/hooks'
import type { PreviewProps } from '.'
import { Btn } from '..'
import { useCanvas } from '../../hooks'
import { locale } from '../../Locales'
import { biomeMap, getBiome } from '../../previews'
import { newSeed } from '../../Utils'
export const BiomeSourcePreview = ({ model, data, shown, version }: PreviewProps) => {
export const BiomeSourcePreview = ({ model, data, shown, lang, version }: PreviewProps) => {
const [scale, setScale] = useState(2)
const [focused, setFocused] = useState<string | undefined>(undefined)
const offset = useRef<[number, number]>([0, 0])
@@ -69,11 +70,14 @@ export const BiomeSourcePreview = ({ model, data, shown, version }: PreviewProps
<div class="controls">
{focused && <Btn label={focused} class="no-pointer" />}
{(type === 'multi_noise' || type === 'checkerboard') && <>
<Btn icon="dash" onClick={() => changeScale(scale * 1.5)} />
<Btn icon="plus" onClick={() => changeScale(scale / 1.5)} />
<Btn icon="dash" tooltip={locale(lang, 'zoom_out')}
onClick={() => changeScale(scale * 1.5)} />
<Btn icon="plus" tooltip={locale(lang, 'zoom_in')}
onClick={() => changeScale(scale / 1.5)} />
</>}
{type === 'multi_noise' &&
<Btn icon="sync" onClick={() => newSeed(model)} />}
<Btn icon="sync" tooltip={locale(lang, 'generate_new_seed')}
onClick={() => newSeed(model)} />}
</div>
<canvas ref={canvas} width="200" height="200"></canvas>
</>

View File

@@ -2,10 +2,11 @@ import { useEffect, useState } from 'preact/hooks'
import type { PreviewProps } from '.'
import { Btn } from '..'
import { useCanvas } from '../../hooks'
import { locale } from '../../Locales'
import { decorator } from '../../previews'
import { randomSeed } from '../../Utils'
export const DecoratorPreview = ({ data, version, shown }: PreviewProps) => {
export const DecoratorPreview = ({ data, version, shown, lang }: PreviewProps) => {
const [scale, setScale] = useState(4)
const [seed, setSeed] = useState(randomSeed())
@@ -27,9 +28,12 @@ export const DecoratorPreview = ({ data, version, shown }: PreviewProps) => {
return <>
<div class="controls">
<Btn icon="dash" onClick={() => setScale(Math.min(16, scale + 1))} />
<Btn icon="plus" onClick={() => setScale(Math.max(1, scale - 1))} />
<Btn icon="sync" onClick={() => setSeed(randomSeed())} />
<Btn icon="dash" tooltip={locale(lang, 'zoom_out')}
onClick={() => setScale(Math.min(16, scale + 1))} />
<Btn icon="plus" tooltip={locale(lang, 'zoom_in')}
onClick={() => setScale(Math.max(1, scale - 1))} />
<Btn icon="sync" tooltip={locale(lang, 'generate_new_seed')}
onClick={() => setSeed(randomSeed())} />
</div>
<canvas ref={canvas} width="64" height="64"></canvas>
</>

View File

@@ -54,7 +54,7 @@ export const NoiseSettingsPreview = ({ lang, data, shown, version }: PreviewProp
return <>
<div class="controls">
{focused && <Btn label={`Y = ${focused}`} class="no-pointer" />}
<BtnMenu icon="gear">
<BtnMenu icon="gear" tooltip={locale(lang, 'terrain_settings')}>
{hasPeaks ? <>
<BtnInput label={loc('preview.factor')} value={`${biomeFactor}`} onChange={v => setBiomeFactor(Number(v))} />
<BtnInput label={loc('preview.offset')} value={`${biomeOffset}`} onChange={v => setBiomeOffset(Number(v))} />
@@ -64,7 +64,8 @@ export const NoiseSettingsPreview = ({ lang, data, shown, version }: PreviewProp
<BtnInput label={loc('preview.depth')} value={`${biomeOffset}`} onChange={v => setBiomeOffset(Number(v))} />
</>}
</BtnMenu>
<Btn icon="sync" onClick={() => setSeed(randomSeed())} />
<Btn icon="sync" tooltip={locale(lang, 'generate_new_seed')}
onClick={() => setSeed(randomSeed())} />
</div>
<canvas ref={canvas} width={size} height={size}></canvas>
</>

View File

@@ -175,7 +175,7 @@ export function Generator({ lang, changeTitle, version, onChangeVersion }: Gener
<div class="controls">
<Btn icon="upload" label={loc('import')} onClick={importSource} />
<BtnMenu icon="archive" label={loc('presets')} relative={false}>
<BtnInput icon="search" large value={presetFilter} onChange={setPresetFilter} doSelect={1} />
<BtnInput icon="search" large value={presetFilter} onChange={setPresetFilter} doSelect={1} placeholder={loc('search')} />
<div class="result-list">
{presetResults.map(preset => <Btn label={preset} onClick={() => loadPreset(preset)} />)}
</div>
@@ -186,7 +186,7 @@ export function Generator({ lang, changeTitle, version, onChangeVersion }: Gener
<Btn label={v} active={v === version} onClick={() => onChangeVersion(v)} />
)}
</BtnMenu>
<BtnMenu icon="kebab_horizontal">
<BtnMenu icon="kebab_horizontal" tooltip={loc('more')}>
<Btn icon="history" label={loc('reset')} onClick={reset} />
<Btn icon="arrow_left" label={loc('undo')} onClick={undo} />
<Btn icon="arrow_right" label={loc('redo')} onClick={redo} />
@@ -195,17 +195,17 @@ export function Generator({ lang, changeTitle, version, onChangeVersion }: Gener
{error && <ErrorPanel error={error} onDismiss={() => setError(null)} />}
<Tree {...{lang, model, version, blockStates}} onError={setError} />
</main>
<div class="popup-actions" style={`--offset: -${10 + actionsShown * 50}px;`}>
<div class={`popup-action action-preview${hasPreview ? ' shown' : ''}`} onClick={togglePreview}>
<div class="popup-actions" style={`--offset: -${8 + actionsShown * 50}px;`}>
<div class={`popup-action action-preview${hasPreview ? ' shown' : ''} tooltipped tip-nw`} aria-label={loc(previewShown ? 'hide_preview' : 'show_preview')} onClick={togglePreview}>
{previewShown ? Octicon.x_circle : Octicon.play}
</div>
<div class={`popup-action action-download${sourceShown ? ' shown' : ''}`} onClick={downloadSource}>
<div class={`popup-action action-download${sourceShown ? ' shown' : ''} tooltipped tip-nw`} aria-label={loc('download')} onClick={downloadSource}>
{Octicon.download}
</div>
<div class={`popup-action action-copy${sourceShown ? ' shown' : ''}${copyActive ? ' active' : ''}`} onClick={copySource}>
<div class={`popup-action action-copy${sourceShown ? ' shown' : ''}${copyActive ? ' active' : ''} tooltipped tip-nw`} aria-label={loc(copyActive ? 'copied' : 'copy')} onClick={copySource}>
{copyActive ? Octicon.check : Octicon.clippy}
</div>
<div class={'popup-action action-code shown'} onClick={toggleSource}>
<div class={'popup-action action-code shown tooltipped tip-nw'} aria-label={loc(sourceShown ? 'hide_output' : 'show_output')} onClick={toggleSource}>
{sourceShown ? Octicon.chevron_right : Octicon.code}
</div>
</div>

View File

@@ -103,7 +103,7 @@ const renderHtml: RenderHook = {
const node = DataModel.wrapLists(children.default())
path.model.set(path, [...value, { node, id: hexId() }])
}
const suffix = <button class="add" onClick={onAdd}>{Octicon.plus_circle}</button>
const suffix = <button class="add tooltipped tip-se" aria-label={locale(lang, 'add_top')} onClick={onAdd}>{Octicon.plus_circle}</button>
const body = <>
{(value && Array.isArray(value)) && value.map(({ node: cValue, id: cId }, index) => {
if (index === maxShown) {
@@ -123,7 +123,7 @@ const renderHtml: RenderHook = {
if (canToggle && (toggle === false || (toggle === undefined && value.length > 20))) {
return <div class="node node-header" data-category={children.category(cPath)}>
<ErrorPopup lang={lang} path={cPath} nested />
<button class="toggle" onClick={expand(cId)}>{Octicon.chevron_right}</button>
<button class="toggle tooltipped tip-se" aria-label={`${locale(lang, 'expand')}\n${locale(lang, 'expand_all', 'Ctrl')}`} onClick={expand(cId)}>{Octicon.chevron_right}</button>
<label>{pathLocale(lang, cPath, `${index}`)}</label>
<Collapsed key={cId} path={cPath} value={cValue} schema={children} />
</div>
@@ -141,16 +141,16 @@ const renderHtml: RenderHook = {
path.model.set(path, v)
}
return <MemoedTreeNode key={cId} path={cPath} schema={children} value={cValue} lang={lang} states={states} ctx={{...ctx, index: (index === 0 ? 1 : 0) + (index === value.length - 1 ? 2 : 0)}}>
{canToggle && <button class="toggle" onClick={collapse(cId)}>{Octicon.chevron_down}</button>}
<button class="remove" onClick={onRemove}>{Octicon.trashcan}</button>
{canToggle && <button class="toggle tooltipped tip-se" aria-label={`${locale(lang, 'collapse')}\n${locale(lang, 'collapse_all', 'Ctrl')}`} onClick={collapse(cId)}>{Octicon.chevron_down}</button>}
<button class="remove tooltipped tip-se" aria-label={locale(lang, 'remove')} onClick={onRemove}>{Octicon.trashcan}</button>
{value.length > 1 && <div class="node-move">
<button class="move" onClick={onMoveUp} disabled={index === 0}>{Octicon.chevron_up}</button>
<button class="move" onClick={onMoveDown} disabled={index === value.length - 1}>{Octicon.chevron_down}</button>
<button class="move tooltipped tip-se" aria-label={locale(lang, 'move_up')} onClick={onMoveUp} disabled={index === 0}>{Octicon.chevron_up}</button>
<button class="move tooltipped tip-se" aria-label={locale(lang, 'move_down')} onClick={onMoveDown} disabled={index === value.length - 1}>{Octicon.chevron_down}</button>
</div>}
</MemoedTreeNode>
})}
{(value && value.length > 2 && value.length <= maxShown) && <div class="node node-header">
<button class="add" onClick={onAddBottom}>{Octicon.plus_circle}</button>
{(value && value.length > 0 && value.length <= maxShown) && <div class="node node-header">
<button class="add tooltipped tip-se" aria-label={locale(lang, 'add_bottom')} onClick={onAddBottom}>{Octicon.plus_circle}</button>
</div>}
</>
return [null, suffix, body]
@@ -183,7 +183,7 @@ const renderHtml: RenderHook = {
}
const suffix = <>
{keysSchema.hook(this, keyPath, keyPath.get() ?? '', lang, states, ctx)[1]}
<button class="add" onClick={onAdd}>{Octicon.plus_circle}</button>
<button class="add tooltipped tip-se" aria-label={locale(lang, 'add')} onClick={onAdd}>{Octicon.plus_circle}</button>
</>
const body = <>
{typeof value === 'object' && Object.entries(value).map(([key, cValue]) => {
@@ -194,7 +194,7 @@ const renderHtml: RenderHook = {
if (canToggle && (toggle === false || (toggle === undefined && value.length > 20))) {
return <div class="node node-header" data-category={children.category(cPath)}>
<ErrorPopup lang={lang} path={cPath} nested />
<button class="toggle" onClick={expand(key)}>{Octicon.chevron_right}</button>
<button class="toggle tooltipped tip-se" aria-label={`${locale(lang, 'expand')}\n${locale(lang, 'expand_all', 'Ctrl')}`} onClick={expand(key)}>{Octicon.chevron_right}</button>
<label>{key}</label>
<Collapsed key={key} path={cPath} value={cValue} schema={children} />
</div>
@@ -208,8 +208,8 @@ const renderHtml: RenderHook = {
}
const onRemove = () => cPath.set(undefined)
return <MemoedTreeNode key={key} schema={cSchema} path={cPath} value={cValue} {...{lang, states, ctx}} label={key}>
{canToggle && <button class="toggle" onClick={collapse(key)}>{Octicon.chevron_down}</button>}
<button class="remove" onClick={onRemove}>{Octicon.trashcan}</button>
{canToggle && <button class="toggle tooltipped tip-se" aria-label={`${locale(lang, 'collapse')}\n${locale(lang, 'collapse_all', 'Ctrl')}`} onClick={collapse(key)}>{Octicon.chevron_down}</button>}
<button class="remove tooltipped tip-se" aria-label={locale(lang, 'remove')} onClick={onRemove}>{Octicon.trashcan}</button>
</MemoedTreeNode>
})}
</>
@@ -226,10 +226,10 @@ const renderHtml: RenderHook = {
if (node.optional()) {
if (value === undefined) {
const onExpand = () => path.set(DataModel.wrapLists(node.default()))
suffix = <button class="collapse closed" onClick={onExpand}>{Octicon.plus_circle}</button>
suffix = <button class="collapse closed tooltipped tip-se" aria-label={locale(lang, 'expand')} onClick={onExpand}>{Octicon.plus_circle}</button>
} else {
const onCollapse = () => path.set(undefined)
suffix = <button class="collapse open" onClick={onCollapse}>{Octicon.trashcan}</button>
suffix = <button class="collapse open tooltipped tip-se" aria-label={locale(lang, 'remove')} onClick={onCollapse}>{Octicon.trashcan}</button>
}
}
const newCtx = (typeof value === 'object' && value !== null && node.default()?.pools)
@@ -318,13 +318,16 @@ function BooleanSuffix({ path, node, value, lang }: NodeProps<BooleanHookParams>
</>
}
function NumberSuffix({ path, config, integer, value }: NodeProps<NumberHookParams>) {
function NumberSuffix({ path, config, integer, value, lang }: NodeProps<NumberHookParams>) {
const [text, setText] = useState(value ?? '')
const commitTimeout = useRef<number>()
const scheduleCommit = (value: number) => {
const commitValue = useRef<number | undefined>()
const scheduleCommit = (newValue: number) => {
if (commitTimeout.current) clearTimeout(commitTimeout.current)
commitValue.current = newValue
commitTimeout.current = setTimeout(() => {
path.model.set(path, value)
path.model.set(path, commitValue.current)
commitValue.current = undefined
}, 500)
}
const onChange = (evt: Event) => {
@@ -334,7 +337,7 @@ function NumberSuffix({ path, config, integer, value }: NodeProps<NumberHookPara
scheduleCommit(parsed)
}
const onBlur = () => {
setText(value ?? '')
setText(commitValue.current ?? value ?? '')
}
const onColor = (evt: Event) => {
const value = (evt.target as HTMLInputElement).value
@@ -345,7 +348,7 @@ function NumberSuffix({ path, config, integer, value }: NodeProps<NumberHookPara
return <>
<input type="text" value={text} onChange={onChange} onBlur={onBlur} />
{config?.color && <input type="color" value={'#' + (value?.toString(16).padStart(6, '0') ?? '000000')} onChange={onColor} />}
{path.equals(new Path(['generator', 'seed'])) && <button onClick={() => newSeed(path.model)}>{Octicon.sync}</button>}
{path.equals(new Path(['generator', 'seed'])) && <button onClick={() => newSeed(path.model)} class="tooltipped tip-se" aria-label={locale(lang, 'generate_new_seed')}>{Octicon.sync}</button>}
</>
}
@@ -425,7 +428,7 @@ function TreeNode({ label, schema, path, value, lang, states, ctx, children }: T
{label ?? pathLocale(lang, path, `${path.last()}`)}
{active && <div class="node-menu">
<div class="menu-item">
<Btn icon="clippy" onClick={() => navigator.clipboard.writeText(context)} />
<Btn icon="clippy" tooltip={locale(lang, 'copy_context')} tooltipLoc="se" onClick={() => navigator.clipboard.writeText(context)} />
Context:
<span class="menu-item-context">{context}</span>
</div>

View File

@@ -1,18 +1,26 @@
{
"add": "Add",
"add_bottom": "Add to bottom",
"add_top": "Add to top",
"advancement": "Advancement",
"button.add": "Add",
"button.collapse": "Collapse",
"button.expand": "Expand",
"button.remove": "Remove",
"collapse": "Collapse",
"collapse_all": "Hold %0% to collapse all",
"copy": "Copy",
"copied": "Copied!",
"copy_context": "Copy context",
"dimension_type": "Dimension Type",
"dimension": "Dimension",
"download": "Download",
"entries_hidden": "%0% entries hidden",
"entries_hidden.more": "Show %0% more",
"entries_hidden.all": "Show all",
"expand": "Expand",
"expand_all": "Hold %0% to expand all",
"fields": "Fields",
"generate_new_seed": "Generate new seed",
"github": "GitHub",
"hide_output": "Hide JSON output",
"hide_preview": "Hide preview",
"home": "Home",
"import": "Import",
"indentation.2_spaces": "2 spaces",
@@ -21,8 +29,12 @@
"item_modifier": "Item Modifier",
"language": "Language",
"loot_table": "Loot Table",
"more": "More",
"move_down": "Move down",
"move_up": "Move up",
"not_found.description": "The page you were looking for does not exist.",
"no_presets": "No presets",
"output_settings": "JSON output settings",
"predicate": "Predicate",
"redo": "Redo",
"reset": "Reset",
@@ -31,6 +43,7 @@
"settings.fields.path": "Context",
"settings.fields.name": "Name",
"share": "Share",
"theme": "Theme",
"theme.dark": "Dark",
"theme.light": "Light",
"theme.system": "System",
@@ -45,7 +58,13 @@
"preview.offset": "Offset",
"preview.peaks": "Peaks",
"preview.width": "Width",
"remove": "Remove",
"search": "Search",
"show_output": "Show JSON output",
"show_preview": "Show preview",
"source_placeholder": "Paste JSON content here",
"switch_generator": "Switch generator",
"terrain_settings": "Terrain settings",
"undo": "Undo",
"world": "World Settings",
"worldgen": "Worldgen",
@@ -56,5 +75,7 @@
"worldgen/processor_list": "Processor List",
"worldgen/configured_structure_feature": "Structure Feature",
"worldgen/configured_surface_builder": "Surface Builder",
"worldgen/template_pool": "Template Pool"
"worldgen/template_pool": "Template Pool",
"zoom_in": "Zoom in",
"zoom_out": "Zoom out"
}

View File

@@ -1,9 +1,10 @@
:root {
--background-1: #1b1b1b;
--background-2: #252525;
--background-3: #2f2f2f;
--background-3: #222222;
--background-4: #3d3d3d;
--background-5: #464646;
--background-5: #383838;
--background-6: #575757;
--text-1: #ffffff;
--text-2: #dcdcdc;
--text-3: #c3c3c3;
@@ -22,11 +23,12 @@
--background-1: #fafafa;
--background-2: #e2e2e2;
--background-3: #d4d3d3;
--background-4: #cccccc;
--background-5: #d6d6d6;
--background-4: #b8b8b8;
--background-5: #bdbdbd;
--background-6: #cecece;
--text-1: #000000;
--text-2: #505050;
--text-3: #6a6a6a;
--text-2: #2f2f2f;
--text-3: #494949;
--accent-primary: #088cdb;
--accent-success: #1a7f37;
--nav: #343a40;
@@ -43,11 +45,12 @@
--background-1: #fafafa;
--background-2: #e2e2e2;
--background-3: #d4d3d3;
--background-4: #cccccc;
--background-5: #d6d6d6;
--background-4: #b8b8b8;
--background-5: #bdbdbd;
--background-6: #cecece;
--text-1: #000000;
--text-2: #505050;
--text-3: #6a6a6a;
--text-2: #2f2f2f;
--text-3: #494949;
--accent-primary: #088cdb;
--accent-success: #1a7f37;
--nav: #343a40;
@@ -426,9 +429,7 @@ main.has-preview {
bottom: 8px;
left: 100%;
z-index: 5;
padding: 0 8px;
border-top-left-radius: 24px;
border-bottom-left-radius: 24px;
padding-right: 16px;
background-color: var(--background-4);
box-shadow: 0 0 7px -3px #000;
user-select: none;
@@ -437,16 +438,23 @@ main.has-preview {
-ms-user-select: none;
transform: translateX(var(--offset));
transition: padding 0.1s, transform 0.3s;
}
.popup-actions:hover {
background-color: var(--background-5);
border-top-left-radius: 24px;
border-bottom-left-radius: 24px;
}
.popup-action {
padding: 12px;
fill: var(--text-2);
fill: var(--text-3);
cursor: pointer;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
padding-left: 16px;
}
.popup-action.shown ~ .popup-action {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
padding-left: 12px;
}
.popup-action:not(.shown) {
@@ -461,6 +469,10 @@ main.has-preview {
height: 24px;
}
.popup-action:hover {
background-color: var(--background-5);
}
.popup-action.action-preview {
fill: var(--accent-primary);
}
@@ -469,6 +481,94 @@ main.has-preview {
fill: var(--accent-success);
}
.tooltipped {
position: relative;
}
.tooltipped::after {
content: attr(aria-label);
position: absolute;
z-index: 100;
padding: 3px 7px;
display: none;
white-space: pre;
pointer-events: none;
background-color: var(--background-6);
color: var(--text-1);
border-radius: 6px;
font-size: 14px;
line-height: 1.5;
text-align: left;
opacity: 0;
}
.tooltipped.tip-ne::after {
bottom: 100%;
margin-bottom: 6px;
left: 50%;
margin-left: -16px;
}
.tooltipped.tip-nw::after {
bottom: 100%;
margin-bottom: 6px;
right: 50%;
margin-right: -16px;
}
.tooltipped.tip-ne::before,
.tooltipped.tip-nw::before {
bottom: auto;
top: -7px;
border-top-color: var(--background-6);
}
.tooltipped.tip-se::after {
top: 100%;
margin-top: 6px;
left: 50%;
margin-left: -16px;
}
.tooltipped.tip-sw::after {
top: 100%;
margin-top: 6px;
right: 50%;
margin-right: -16px;
}
.tooltipped.tip-se::before,
.tooltipped.tip-sw::before {
top: auto;
bottom: -7px;
border-bottom-color: var(--background-6);
}
.tooltipped::before {
content: '';
position: absolute;
z-index: 100;
display: none;
right: 50%;
width: 0;
height: 0;
margin-right: -8px;
pointer-events: none;
border: 8px solid transparent;
opacity: 0;
}
.tooltipped:not([disabled]):hover::before,
.tooltipped:not([disabled]):hover::after {
display: inline-block;
animation: tooltip-appear 0.1s ease-in 0.4s forwards;
}
@keyframes tooltip-appear {
from { opacity: 0; }
to { opacity: 1; }
}
.error {
padding: 5px 14px;
margin: 12px 16px;

View File

@@ -1,19 +1,20 @@
:root {
--node-border: #4e4e4e;
--node-border: #3f3f3f;
--node-background-label: #1b1b1b;
--node-background-input: #272727;
--node-background-hover: #1f1f1f;
--node-text: #dadada;
--node-text-dimmed: #b4b4b4;
--node-selected: #ad9715;
--node-selected-hover: #a38c0a;
--node-selected-border: #8d7a0d;
--node-add: #487c13;
--node-add-hover: #3e7409;
--node-add-border: #3b6e0c;
--node-remove: #9b341b;
--node-remove-hover: #922d13;
--node-remove-border: #7e1d05;
--node-indent-border: #454749;
--node-popup-background: #0a0a0ae6;
--node-popup-text: #dadada;
--node-popup-text-dimmed: #b4b4b4;
--category-predicate: #306163;
--category-predicate-border: #224849;
--category-predicate-background: #1d3333;
@@ -29,18 +30,19 @@
--node-border: #bcbfc3;
--node-background-label: #e4e4e4;
--node-background-input: #ffffff;
--node-background-hover: #e7e7e7;
--node-text: #000000;
--node-text-dimmed: #2c2c2c;
--node-selected: #f0e65e;
--node-selected-hover: #faf06c;
--node-selected-border: #b9a327;
--node-add: #9bd464;
--node-add-hover: #a5dd70;
--node-add-border: #498d09;
--node-remove: #e76f51;
--node-remove-hover: #f57656;
--node-remove-border: #be4b2e;
--node-indent-border: #b9b9b9;
--node-popup-background: #1f2020e6;
--node-popup-text: #dadada;
--node-popup-text-dimmed: #b4b4b4;
--category-predicate: #65b5b8;
--category-predicate-border: #187e81;
--category-predicate-background: #95c5c7;
@@ -57,18 +59,19 @@
--node-border: #bcbfc3;
--node-background-label: #e4e4e4;
--node-background-input: #ffffff;
--node-background-hover: #e7e7e7;
--node-text: #000000;
--node-text-dimmed: #2c2c2c;
--node-selected: #f0e65e;
--node-selected-hover: #faf06c;
--node-selected-border: #b9a327;
--node-add: #9bd464;
--node-add-hover: #a5dd70;
--node-add-border: #498d09;
--node-remove: #e76f51;
--node-remove-hover: #f57656;
--node-remove-border: #be4b2e;
--node-indent-border: #b9b9b9;
--node-popup-background: #1f2020e6;
--node-popup-text: #dadada;
--node-popup-text-dimmed: #b4b4b4;
--category-predicate: #65b5b8;
--category-predicate-border: #187e81;
--category-predicate-background: #95c5c7;
@@ -91,6 +94,7 @@
.node-header > * {
height: 34px;
/* border: none; */
border: 1px solid;
color: var(--node-text);
border-color: var(--node-border);
@@ -141,6 +145,10 @@
background-color: var(--node-background-input);
}
.node-header button:not([disabled]):hover {
background-color: var(--node-background-hover);
}
.object-node > .node-header > .collapse {
cursor: pointer;
}
@@ -191,6 +199,9 @@ button.selected {
background-color: var(--node-selected);
border-color: var(--node-selected-border);
}
button:not([disabled]).selected:hover {
background-color: var(--node-selected-hover);
}
.collapse svg {
fill: var(--node-text);
@@ -202,12 +213,22 @@ button.add {
border-color: var(--node-add-border);
}
.collapse:not([disabled]).closed:hover,
button:not([disabled]).add:hover {
background-color: var(--node-add-hover);
}
.collapse.open,
button.remove {
background-color: var(--node-remove);
border-color: var(--node-remove-border);
}
.collapse:not([disabled]).open:hover,
button:not([disabled]).remove:hover {
background-color: var(--node-remove-hover);
}
.node-header > button svg {
display: inline-block;
position: relative;
@@ -251,8 +272,8 @@ button.move:disabled {
.node-icon .icon-popup {
visibility: hidden;
width: 240px;
background-color: var(--node-popup-background);
color: var(--node-popup-text);
background-color: var(--background-6);
color: var(--text-1);
text-align: center;
border-radius: 6px;
padding: 8px 4px;
@@ -271,7 +292,7 @@ button.move:disabled {
margin-left: -3px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent var(--node-popup-background) transparent;
border-color: transparent transparent var(--background-6) transparent;
}
.node-icon svg:hover + .icon-popup,
@@ -303,10 +324,11 @@ button.move:disabled {
margin-top: 4px;
margin-left: 4px;
z-index: 1;
color: var(--node-popup-text);
color: var(--text-1);
font-size: 16px;
border-radius: 3px;
background-color: var(--node-popup-background);
border-radius: 6px;
background-color: var(--background-6);
box-shadow: 0 1px 5px -2px #000;
}
.node-menu::after {
@@ -317,7 +339,7 @@ button.move:disabled {
margin-left: 6px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent var(--node-popup-background) transparent;
border-color: transparent transparent var(--background-6) transparent;
}
.menu-item {
@@ -333,6 +355,7 @@ button.move:disabled {
.menu-item .btn {
padding: 8px;
box-shadow: unset;
}
span.menu-item {
@@ -340,12 +363,7 @@ span.menu-item {
}
.menu-item-context {
color: var(--node-popup-text-dimmed);
}
.node-message {
color: var(--node-text-dimmed);
margin: 6px 0;
color: var(--text-2);
}
/* Node body and list entry */