Add internal mix tag input for calculator and goal tree formulas
All checks were successful
Deploy Sokko G / deploy (push) Successful in 15s

This commit is contained in:
Shinuwa 2026-08-24 13:24:44 +02:00
parent 5c8148c905
commit ae503c7260
13 changed files with 929 additions and 23 deletions

View file

@ -357,6 +357,11 @@
-webkit-mask-image: url("/static/icons/refresh.svg");
}
.ui-icon-parent {
mask-image: url("/static/icons/parent.svg");
-webkit-mask-image: url("/static/icons/parent.svg");
}
.ui-icon-back {
mask-image: url("/static/icons/back.svg");
-webkit-mask-image: url("/static/icons/back.svg");

View file

@ -8,6 +8,7 @@
}
.calculator-form label,
.calculator-field,
.calculator-result {
display: grid;
width: 100%;
@ -27,11 +28,12 @@
}
.tool-split-entry-list li.is-editing > .calculator-entry.has-drag-handle {
grid-template-columns: 30px auto minmax(0, 1fr) 34px 34px;
grid-template-columns: 30px minmax(0, 1fr) 34px 34px;
align-items: start;
}
.tool-split-entry-list li.is-editing.can-edit-formula > .calculator-entry.has-drag-handle {
grid-template-columns: 30px minmax(92px, 0.9fr) minmax(80px, 1fr) 34px 34px;
.tool-split-entry-list li.is-editing > .calculator-entry.has-drag-handle .calculator-drag-handle {
grid-row: 1 / span 2;
}
.calculator-entry-formula {
@ -39,7 +41,11 @@
}
.calculator-entry-edit-fields {
display: contents;
display: grid;
min-width: 0;
gap: 6px;
grid-column: 2;
grid-row: 1 / span 2;
}
.calculator-drag-handle {
@ -108,6 +114,7 @@
}
.calculator-form label span,
.calculator-field > span,
.calculator-result span,
.tool-split-root-button {
color: var(--color-text-secondary);

View file

@ -128,11 +128,12 @@
"label delete";
}
.goal-tree-content-editor-row.is-checklist input:first-child {
.goal-tree-content-label-input {
grid-area: label;
}
.goal-tree-content-editor-row.is-checklist input:nth-child(2) {
.goal-tree-content-formula-input,
.goal-tree-content-editor-row.is-checklist .mix-tags-input-wrap {
grid-area: total;
}

View file

@ -346,6 +346,144 @@
padding-right: 8px;
}
.mix-tags-input-wrap {
position: relative;
display: flex;
box-sizing: border-box;
width: 100%;
min-width: 0;
min-height: 44px;
overflow: hidden;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
background: rgba(21, 26, 48, 0.92);
color: var(--color-text-primary);
padding-right: 34px;
transition:
transform var(--duration-fast) var(--ease-standard),
border-color var(--duration-fast) var(--ease-standard),
background-color var(--duration-fast) var(--ease-standard),
color var(--duration-fast) var(--ease-standard),
box-shadow var(--duration-fast) var(--ease-standard);
}
.mix-tags-input {
position: relative;
display: block;
box-sizing: border-box;
flex: 1 1 auto;
width: 100%;
min-width: 0;
max-width: 100%;
height: 42px;
min-height: 42px;
overflow-x: auto;
overflow-y: hidden;
padding: 10px 4px 4px 7px;
border: 0;
background: transparent;
color: inherit;
caret-color: var(--color-text-primary);
font: inherit;
font-variant-numeric: tabular-nums;
line-height: 20px;
outline: none;
scrollbar-width: none;
white-space: nowrap;
cursor: text;
}
.mix-tags-input-wrap:hover,
.mix-tags-input-wrap:has(.mix-tags-input.is-focused) {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.16);
}
.mix-tags-input-wrap:has(.mix-tags-input:focus-visible) {
outline: 2px solid var(--color-accent-gold);
outline-offset: 3px;
}
.mix-tags-input-wrap:has(.mix-tags-input.is-focused) {
color: var(--color-text-primary);
}
.mix-tags-input::-webkit-scrollbar {
display: none;
}
.mix-tags-input:empty::before {
content: attr(data-placeholder);
color: var(--color-text-muted);
opacity: 0.58;
}
.mix-tags-input::selection {
background: rgba(139, 92, 246, 0.42);
}
.mix-tags-input-tag {
position: relative;
top: -1px;
display: inline-flex;
width: 68px;
min-width: 68px;
height: 24px;
align-items: center;
justify-content: center;
margin: 0 4px;
padding: 1px 5px;
border: 1px solid rgba(150, 165, 205, 0.18);
border-radius: var(--radius-sm);
background: rgba(150, 165, 205, 0.07);
color: var(--color-text-secondary);
font-size: 0.62rem;
font-weight: 700;
line-height: 11px;
text-align: center;
white-space: normal;
vertical-align: middle;
}
.mix-tags-input-tag-text {
overflow: hidden;
line-height: 11px;
text-overflow: clip;
}
.mix-tags-input-insert-button {
position: absolute;
z-index: 2;
top: 0;
right: 0;
bottom: 0;
display: inline-flex;
box-sizing: border-box;
width: 34px;
min-width: 34px;
min-height: 0;
align-items: center;
justify-content: center;
padding: 0;
border: 0;
border-left: 1px solid rgba(165, 180, 252, 0.12);
border-radius: 0 calc(var(--radius-md) - 1px) calc(var(--radius-md) - 1px) 0;
background: transparent;
color: var(--color-text-muted);
}
.mix-tags-input-insert-button:hover,
.mix-tags-input-insert-button:focus-visible {
background: rgba(196, 181, 253, 0.08);
color: var(--color-text-primary);
}
.mix-tags-input-insert-button .ui-icon {
display: block;
width: 15px;
height: 15px;
}
.tool-split-entry-list {
display: grid;
gap: 6px;
@ -471,6 +609,45 @@
color: var(--color-text-primary);
}
.mix-tags-input-wrap--small .mix-tags-input {
display: block;
height: 34px;
min-height: 34px;
padding: 6px 4px 6px 9px;
white-space: nowrap;
text-overflow: clip;
}
.mix-tags-input-wrap--small .mix-tags-input-tag {
top: 0;
width: 62px;
min-width: 62px;
height: 22px;
}
.mix-tags-input-wrap--small {
height: 36px;
min-height: 36px;
max-height: 36px;
}
.mix-tags-input-wrap--small .mix-tags-input-insert-button {
top: 0;
right: 0;
bottom: 0;
width: 34px;
min-width: 34px;
height: 34px;
min-height: 34px;
border-radius: 0 calc(var(--radius-md) - 1px) calc(var(--radius-md) - 1px) 0;
}
.mix-tags-input-wrap--small .mix-tags-input-insert-button .ui-icon {
display: block;
width: 14px;
height: 14px;
}
.tool-split-entry .ui-icon {
width: 16px;
height: 16px;
@ -481,6 +658,10 @@
min-height: 36px;
}
.tool-split-entry > button.active:not(.tool-split-entry-summary, .tool-split-entry-value, .danger) {
@include mixins.temporary-toggle-active;
}
.tool-split-entry-list li.active > .tool-split-entry > .tool-split-entry-summary,
.tool-split-entry-list li.active > .tool-split-entry > .tool-split-entry-value,
.tool-split-entry-list li.active > .tool-split-entry > .tool-split-entry-label {