mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 07:10:41 +00:00
Add tooltips to all buttons and tweak hover colors
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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>}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)}/>
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user