Update UI widget designs to improve color consistency and add a narrow height mode

This commit is contained in:
Keavon Chambers
2025-09-08 21:48:22 -07:00
parent 485152bf8d
commit 22aa8c1264
41 changed files with 364 additions and 197 deletions
@@ -13,6 +13,7 @@
export let value: FillChoice;
export let disabled = false;
export let narrow = false;
export let allowNone = false;
export let menuDirection: MenuDirection = "Bottom";
// export let allowTransparency = false; // TODO: Implement
@@ -25,7 +26,7 @@
$: transparency = value instanceof Gradient ? value.stops.some((stop) => stop.color.alpha < 1) : value.alpha < 1;
</script>
<LayoutCol class="color-button" classes={{ open, disabled, none, transparency, outlined, "direction-top": menuDirection === "Top" }} {tooltip}>
<LayoutCol class="color-button" classes={{ open, disabled, narrow, none, transparency, outlined, "direction-top": menuDirection === "Top" }} {tooltip}>
<button style:--chosen-gradient={chosenGradient} style:--outline-amount={outlineFactor} on:click={() => (open = true)} tabindex="0" data-floating-menu-spawner>
<!-- {#if disabled && value instanceof Color && !value.none}
<TextLabel>sRGB</TextLabel>
@@ -55,6 +56,10 @@
position: relative;
min-width: 80px;
&.narrow.narrow {
--widget-height: 20px;
}
> button {
border: none;
border-radius: 2px;
@@ -20,6 +20,7 @@
export let drawIcon = false;
export let interactive = true;
export let disabled = false;
export let narrow = false;
export let tooltip: string | undefined = undefined;
export let minWidth = 0;
export let maxWidth = 0;
@@ -86,7 +87,11 @@
<LayoutRow
class="dropdown-input"
styles={{ ...(minWidth > 0 ? { "min-width": `${minWidth}px` } : {}), ...(maxWidth > 0 ? { "max-width": `${maxWidth}px` } : {}) }}
classes={{ narrow }}
styles={{
...(minWidth > 0 ? { "min-width": `${minWidth}px` } : {}),
...(maxWidth > 0 ? { "max-width": `${maxWidth}px` } : {}),
}}
bind:this={self}
data-dropdown-input
>
@@ -107,12 +112,12 @@
</LayoutRow>
<MenuList
on:naturalWidth={({ detail }) => (minWidth = detail)}
{activeEntry}
on:activeEntry={({ detail }) => (activeEntry = detail)}
on:hoverInEntry={({ detail }) => dispatchHoverInEntry(detail)}
on:hoverOutEntry={() => dispatchHoverOutEntry()}
{open}
on:open={({ detail }) => (open = detail)}
{open}
{activeEntry}
{entries}
{drawIcon}
{interactive}
@@ -125,13 +130,18 @@
<style lang="scss" global>
.dropdown-input {
position: relative;
--widget-height: 24px;
&.narrow.narrow {
--widget-height: 20px;
}
.dropdown-box {
align-items: center;
white-space: nowrap;
background: var(--color-1-nearblack);
height: 24px;
border-radius: 2px;
background: var(--color-1-nearblack);
height: var(--widget-height);
.dropdown-label {
margin: 0;
@@ -23,6 +23,7 @@
export let label: string | undefined = undefined;
export let spellcheck = false;
export let disabled = false;
export let narrow = false;
export let textarea = false;
export let tooltip: string | undefined = undefined;
export let placeholder: string | undefined = undefined;
@@ -73,7 +74,7 @@
</script>
<!-- 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, ...classes }} style={styleName} {styles} {tooltip}>
<LayoutRow class={`field-input ${className}`} classes={{ disabled, narrow, ...classes }} style={styleName} {styles} {tooltip}>
{#if !textarea}
<input
type="text"
@@ -127,9 +128,13 @@
background: var(--color-1-nearblack);
flex-direction: row-reverse;
&.narrow.narrow {
--widget-height: 20px;
}
label {
flex: 0 0 auto;
line-height: 18px;
line-height: calc(var(--widget-height) - 6px);
padding: 3px 0;
padding-right: 4px;
margin-left: 8px;
@@ -147,8 +152,8 @@
flex: 1 1 100%;
width: 0;
min-width: 30px;
height: 18px;
line-height: 18px;
height: calc(var(--widget-height) - 6px);
line-height: calc(var(--widget-height) - 6px);
margin: 0 8px;
padding: 3px 0;
outline: none; // Ok for input/textarea element
@@ -189,7 +194,7 @@
}
textarea {
min-height: calc(18px * 3);
min-height: calc((var(--widget-height) - 6px) * 3);
margin: 3px;
padding: 0 5px;
box-sizing: border-box;
@@ -22,6 +22,9 @@
// Disabled
export let disabled = false;
// Narrow
export let narrow = false;
// Value
// When `value` is not provided (i.e. it's `undefined`), a dash is displayed.
export let value: number | undefined = undefined; // NOTE: Do not update this directly, do so by calling `updateValue()` instead.
@@ -642,6 +645,7 @@
<FieldInput
class="number-input"
classes={{
narrow,
increment: mode === "Increment",
range: mode === "Range",
}}
@@ -653,6 +657,7 @@
on:pointerdown={onDragPointerDown}
{label}
{disabled}
{narrow}
{tooltip}
{styles}
hideContextMenu={true}
@@ -709,7 +714,13 @@
text-align: center;
}
&.narrow {
--widget-height: 20px;
}
&.increment {
--arrow-radius: 3px;
// Widen the label and input margins from the edges by an extra 8px to make room for the increment arrows
label {
margin-left: 8px;
@@ -738,7 +749,7 @@
position: absolute;
top: 0;
margin: 0;
padding: 9px 0;
padding: calc(var(--widget-height) / 2 - var(--arrow-radius)) 0;
border: none;
border-radius: 2px;
background: rgba(var(--color-1-nearblack-rgb), 0.5);
@@ -759,7 +770,7 @@
width: 0;
height: 0;
border-style: solid;
border-width: 3px 0 3px 3px;
border-width: var(--arrow-radius) 0 var(--arrow-radius) var(--arrow-radius);
border-color: transparent transparent transparent var(--color-e-nearwhite);
}
}
@@ -775,7 +786,7 @@
width: 0;
height: 0;
border-style: solid;
border-width: 3px 3px 3px 0;
border-width: var(--arrow-radius) var(--arrow-radius) var(--arrow-radius) 0;
border-color: transparent var(--color-e-nearwhite) transparent transparent;
}
}
@@ -845,7 +856,7 @@
appearance: none;
border-radius: 2px;
width: 4px;
height: 22px;
height: calc(var(--widget-height) - 2px);
background: #494949; // Becomes var(--color-5-dullgray) with screen blend mode over var(--color-1-nearblack) background
}
@@ -862,7 +873,7 @@
border: none;
border-radius: 2px;
width: 4px;
height: 22px;
height: calc(var(--widget-height) - 2px);
background: #494949; // Becomes var(--color-5-dullgray) with screen blend mode over var(--color-1-nearblack) background
}
@@ -900,7 +911,7 @@
border-radius: 2px;
margin-left: -2px;
width: 4px;
height: 22px;
height: calc(var(--widget-height) - 2px);
top: 1px;
left: calc(var(--progress-factor) * 100%);
background: #5b5b5b; // Becomes var(--color-6-lowergray) with screen blend mode over var(--color-1-nearblack) background
@@ -13,6 +13,7 @@
export let selectedIndex: number | undefined = undefined;
export let disabled = false;
export let minWidth = 0;
export let narrow = false;
$: mixed = selectedIndex === undefined && !disabled;
@@ -24,7 +25,7 @@
}
</script>
<LayoutRow class="radio-input" classes={{ disabled, mixed }} styles={{ ...(minWidth > 0 ? { "min-width": `${minWidth}px` } : {}) }}>
<LayoutRow class="radio-input" classes={{ disabled, narrow, mixed }} styles={{ ...(minWidth > 0 ? { "min-width": `${minWidth}px` } : {}) }}>
{#each entries as entry, index}
<button class:active={!mixed ? index === selectedIndex : undefined} on:click={() => handleEntryClick(entry)} title={entry.tooltip} tabindex={index === selectedIndex ? -1 : 0} {disabled}>
{#if entry.icon}
@@ -39,12 +40,13 @@
<style lang="scss" global>
.radio-input {
background: var(--color-5-dullgray);
background: var(--color-4-dimgray);
border-radius: 2px;
height: 24px;
--widget-height: 24px;
height: var(--widget-height);
button {
background: var(--color-5-dullgray);
background: var(--color-4-dimgray);
fill: var(--color-e-nearwhite);
border-radius: 2px;
height: 20px;
@@ -100,33 +102,35 @@
}
}
&.mixed {
background: var(--color-4-dimgray);
&.narrow.narrow {
--widget-height: 20px;
height: var(--widget-height);
button {
height: 16px;
}
}
&.mixed {
button:not(:hover),
&.disabled button:hover {
background: var(--color-5-dullgray);
}
}
&.disabled {
background: var(--color-4-dimgray);
&.disabled button {
color: var(--color-8-uppergray);
button {
background: var(--color-4-dimgray);
color: var(--color-8-uppergray);
svg {
fill: var(--color-8-uppergray);
}
&.active {
background: var(--color-8-uppergray);
color: var(--color-2-mildblack);
svg {
fill: var(--color-8-uppergray);
}
&.active {
background: var(--color-8-uppergray);
color: var(--color-2-mildblack);
svg {
fill: var(--color-2-mildblack);
}
fill: var(--color-2-mildblack);
}
}
}
@@ -11,6 +11,8 @@
export let placeholder: string | undefined = undefined;
// Disabled
export let disabled = false;
// Narrow
export let narrow = false;
// Value
export let value: string;
// Styling
@@ -76,6 +78,7 @@
spellcheck={true}
{label}
{disabled}
{narrow}
{tooltip}
{placeholder}
bind:this={self}