Improve the Data panel's data display with monospaced text and copyable number values (#4040)
* Improve the Data panel's data display with monospaced text and copyable number values * Revert attempted fix for dropdown menus appearing lower in scrolled Properties panel, since it makes other floating menus freeze the app * Code review
This commit is contained in:
parent
e2117d9a02
commit
fcf9396a71
|
|
@ -362,6 +362,7 @@ pub struct TextAreaInput {
|
||||||
pub value: String,
|
pub value: String,
|
||||||
pub label: Option<String>,
|
pub label: Option<String>,
|
||||||
pub disabled: bool,
|
pub disabled: bool,
|
||||||
|
pub monospace: bool,
|
||||||
|
|
||||||
// Tooltips
|
// Tooltips
|
||||||
#[serde(rename = "tooltipLabel")]
|
#[serde(rename = "tooltipLabel")]
|
||||||
|
|
|
||||||
|
|
@ -584,7 +584,7 @@ impl TableRowLayout for f64 {
|
||||||
"Number (f64)".to_string()
|
"Number (f64)".to_string()
|
||||||
}
|
}
|
||||||
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
||||||
let widgets = vec![TextLabel::new(self.to_string()).widget_instance()];
|
let widgets = vec![NumberInput::new(Some(*self)).disabled(true).max_width(220).display_decimal_places(20).widget_instance()];
|
||||||
vec![LayoutGroup::row(widgets)]
|
vec![LayoutGroup::row(widgets)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -597,7 +597,7 @@ impl TableRowLayout for u32 {
|
||||||
"Number (u32)".to_string()
|
"Number (u32)".to_string()
|
||||||
}
|
}
|
||||||
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
||||||
let widgets = vec![TextLabel::new(self.to_string()).widget_instance()];
|
let widgets = vec![NumberInput::new(Some(*self as f64)).disabled(true).max_width(220).display_decimal_places(20).widget_instance()];
|
||||||
vec![LayoutGroup::row(widgets)]
|
vec![LayoutGroup::row(widgets)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +610,8 @@ impl TableRowLayout for u64 {
|
||||||
"Number (u64)".to_string()
|
"Number (u64)".to_string()
|
||||||
}
|
}
|
||||||
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
||||||
let widgets = vec![TextLabel::new(self.to_string()).widget_instance()];
|
// TODO: Make this robust for large u64 values that don't fit in f64 (above roughly 2^53). Perhaps using a bigint kind of approach through the widget's data flow.
|
||||||
|
let widgets = vec![NumberInput::new(Some(*self as f64)).disabled(true).max_width(220).display_decimal_places(20).widget_instance()];
|
||||||
vec![LayoutGroup::row(widgets)]
|
vec![LayoutGroup::row(widgets)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -642,7 +643,7 @@ impl TableRowLayout for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
fn element_page(&self, _data: &mut LayoutData) -> Vec<LayoutGroup> {
|
||||||
let widgets = vec![TextAreaInput::new(self.to_string()).disabled(true).widget_instance()];
|
let widgets = vec![TextAreaInput::new(self.to_string()).monospace(true).disabled(true).widget_instance()];
|
||||||
vec![LayoutGroup::row(widgets)]
|
vec![LayoutGroup::row(widgets)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2355,7 +2355,12 @@ pub mod choice {
|
||||||
.map(|(item, metadata)| {
|
.map(|(item, metadata)| {
|
||||||
let updater = updater_factory();
|
let updater = updater_factory();
|
||||||
let committer = committer_factory();
|
let committer = committer_factory();
|
||||||
MenuListEntry::new(metadata.name).label(metadata.label).on_update(move |_| updater(item)).on_commit(committer)
|
MenuListEntry::new(metadata.name)
|
||||||
|
.label(metadata.label)
|
||||||
|
.tooltip_label(metadata.label)
|
||||||
|
.tooltip_description(metadata.description.unwrap_or_default())
|
||||||
|
.on_update(move |_| updater(item))
|
||||||
|
.on_commit(committer)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -261,9 +261,27 @@
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
tab-size: 4;
|
||||||
color: var(--color-e-nearwhite);
|
color: var(--color-e-nearwhite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body,
|
||||||
|
textarea,
|
||||||
|
input {
|
||||||
|
&::selection {
|
||||||
|
background-color: var(--color-4-dimgray);
|
||||||
|
|
||||||
|
// Target only Safari
|
||||||
|
@supports (background: -webkit-named-image(i)) {
|
||||||
|
& {
|
||||||
|
// Setting an alpha value opts out of Safari's "fancy" (but not visible on dark backgrounds) selection highlight rendering
|
||||||
|
// https://stackoverflow.com/a/71753552/775283
|
||||||
|
background-color: rgba(var(--color-4-dimgray-rgb), calc(254 / 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
svg,
|
svg,
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,16 @@
|
||||||
.widget-span:has(.text-area-input) {
|
.widget-span:has(.text-area-input) {
|
||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
|
|
||||||
.text-area-input textarea {
|
.text-area-input {
|
||||||
height: 100%;
|
margin: 0;
|
||||||
margin-top: 0;
|
padding: 4px 0;
|
||||||
margin-bottom: 0;
|
|
||||||
resize: none;
|
textarea {
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -519,7 +519,7 @@
|
||||||
style:--node-chain-area-left-extension={layerChainWidth !== 0 ? layerChainWidth + 0.5 : 0}
|
style:--node-chain-area-left-extension={layerChainWidth !== 0 ? layerChainWidth + 0.5 : 0}
|
||||||
data-tooltip-label={nodeNameTooltipLabel(node)}
|
data-tooltip-label={nodeNameTooltipLabel(node)}
|
||||||
data-tooltip-description={`
|
data-tooltip-description={`
|
||||||
${(description || "").trim()}${editor.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
${(description || "").trim()}${editor.inDevelopmentMode() ? `\n\n*ID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).*` : ""}
|
||||||
`.trim()}
|
`.trim()}
|
||||||
data-node={node.id}
|
data-node={node.id}
|
||||||
>
|
>
|
||||||
|
|
@ -682,7 +682,7 @@
|
||||||
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
|
||||||
data-tooltip-label={nodeNameTooltipLabel(node)}
|
data-tooltip-label={nodeNameTooltipLabel(node)}
|
||||||
data-tooltip-description={`
|
data-tooltip-description={`
|
||||||
${(description || "").trim()}${editor.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).` : ""}
|
${(description || "").trim()}${editor.inDevelopmentMode() ? `\n\n*ID: ${node.id}. Position: (${node.position[0]}, ${node.position[1]}).*` : ""}
|
||||||
`.trim()}
|
`.trim()}
|
||||||
data-node={node.id}
|
data-node={node.id}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,31 @@
|
||||||
export let tooltipShortcut: ActionShortcut | undefined = undefined;
|
export let tooltipShortcut: ActionShortcut | undefined = undefined;
|
||||||
// Callbacks
|
// Callbacks
|
||||||
export let action: (index: number) => void;
|
export let action: (index: number) => void;
|
||||||
|
|
||||||
|
function truncate(label: string): string {
|
||||||
|
let maxLength = 40;
|
||||||
|
|
||||||
|
if (label.length <= maxLength) return label;
|
||||||
|
|
||||||
|
let truncated = label;
|
||||||
|
const hasQuotes = label.startsWith(`"`) && label.endsWith(`"`);
|
||||||
|
|
||||||
|
if (hasQuotes) {
|
||||||
|
truncated = label.slice(1, -1);
|
||||||
|
maxLength -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
truncated = truncated.slice(0, maxLength - 1) + "…";
|
||||||
|
|
||||||
|
if (hasQuotes) truncated = `"${truncated}"`;
|
||||||
|
|
||||||
|
return truncated;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LayoutRow class="breadcrumb-trail-buttons" {tooltipLabel} {tooltipDescription} {tooltipShortcut}>
|
<LayoutRow class="breadcrumb-trail-buttons" {tooltipLabel} {tooltipDescription} {tooltipShortcut}>
|
||||||
{#each labels as label, index}
|
{#each labels as label, index}
|
||||||
<TextButton {label} emphasized={index === labels.length - 1} {disabled} action={() => !disabled && index !== labels.length - 1 && action(index)} />
|
<TextButton label={truncate(label)} emphasized={index === labels.length - 1} {disabled} action={() => !disabled && index !== labels.length - 1 && action(index)} />
|
||||||
{/each}
|
{/each}
|
||||||
</LayoutRow>
|
</LayoutRow>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
export let label: string | undefined = undefined;
|
export let label: string | undefined = undefined;
|
||||||
export let spellcheck = false;
|
export let spellcheck = false;
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
|
export let monospace = false;
|
||||||
export let narrow = false;
|
export let narrow = false;
|
||||||
export let textarea = false;
|
export let textarea = false;
|
||||||
export let tooltipLabel: string | undefined = undefined;
|
export let tooltipLabel: string | undefined = undefined;
|
||||||
|
|
@ -75,7 +76,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- This is a base component, extended by others like NumberInput and TextInput. It should not be used directly. -->
|
<!-- This is a base component, extended by others like NumberInput and TextInput. It should not be used directly. -->
|
||||||
<LayoutRow class={`field-input ${className}`} classes={{ disabled, narrow, ...classes }} style={styleName} {styles} {tooltipLabel} {tooltipDescription} {tooltipShortcut}>
|
<LayoutRow class={`field-input ${className}`} classes={{ disabled, narrow, monospace, ...classes }} style={styleName} {styles} {tooltipLabel} {tooltipDescription} {tooltipShortcut}>
|
||||||
{#if !textarea}
|
{#if !textarea}
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -133,6 +134,13 @@
|
||||||
--widget-height: 20px;
|
--widget-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.monospace {
|
||||||
|
input,
|
||||||
|
textarea {
|
||||||
|
font-family: "Source Code Pro", monospace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
line-height: calc(var(--widget-height) - 6px);
|
line-height: calc(var(--widget-height) - 6px);
|
||||||
|
|
@ -163,19 +171,6 @@
|
||||||
color: var(--color-e-nearwhite);
|
color: var(--color-e-nearwhite);
|
||||||
caret-color: var(--color-e-nearwhite);
|
caret-color: var(--color-e-nearwhite);
|
||||||
unicode-bidi: plaintext;
|
unicode-bidi: plaintext;
|
||||||
|
|
||||||
&::selection {
|
|
||||||
background-color: var(--color-4-dimgray);
|
|
||||||
|
|
||||||
// Target only Safari
|
|
||||||
@supports (background: -webkit-named-image(i)) {
|
|
||||||
& {
|
|
||||||
// Setting an alpha value opts out of Safari's "fancy" (but not visible on dark backgrounds) selection highlight rendering
|
|
||||||
// https://stackoverflow.com/a/71753552/775283
|
|
||||||
background-color: rgba(var(--color-4-dimgray-rgb), calc(254 / 255));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
|
@ -210,11 +205,6 @@
|
||||||
textarea {
|
textarea {
|
||||||
color: var(--color-8-uppergray);
|
color: var(--color-8-uppergray);
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
|
||||||
// Disables drag-selecting the text, since `user-select: none` doesn't work for input elements
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
export let tooltipDescription: string | undefined = undefined;
|
export let tooltipDescription: string | undefined = undefined;
|
||||||
export let tooltipShortcut: ActionShortcut | undefined = undefined;
|
export let tooltipShortcut: ActionShortcut | undefined = undefined;
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
|
export let monospace = false;
|
||||||
|
|
||||||
let self: FieldInput | undefined;
|
let self: FieldInput | undefined;
|
||||||
let editing = false;
|
let editing = false;
|
||||||
|
|
@ -57,6 +58,7 @@
|
||||||
spellcheck={true}
|
spellcheck={true}
|
||||||
{label}
|
{label}
|
||||||
{disabled}
|
{disabled}
|
||||||
|
{monospace}
|
||||||
{tooltipLabel}
|
{tooltipLabel}
|
||||||
{tooltipDescription}
|
{tooltipDescription}
|
||||||
{tooltipShortcut}
|
{tooltipShortcut}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue