gtritchie_bulk-properties/styles.css
Gary Ritchie f7e28e5e2c
Replace comma-separated textarea with pill-style input for multi-value properties (#22)
* Replace comma-separated textarea with pill-style input for tags

Use Obsidian's native .multi-select-pill CSS classes for tags,
aliases, and multitext property types. Pills are added via Enter,
comma, or paste and removed via × button or Backspace. Dedup
applies to tags/aliases only; multitext allows duplicates. IME
composition is respected to avoid breaking CJK input.

* Add x icon to pill remove button via setIcon

* Fix paste merging and blur commit behavior for pill input

Paste now merges clipboard text with existing input value at the
cursor position before splitting on commas. The trailing segment
after the last comma stays in the input for further editing.

Blur only commits pending text when focus leaves the pill container
entirely, not when clicking a remove button inside it.

* Move pending-text commit to container focusout

Replace the input-level blur handler with a container-level focusout
listener that commits pending text only when focus leaves the pill
container entirely. This covers the keyboard path where focus moves
from a remove button to outside the container.

* Strip border from pill remove button and reduce pill size

* Add hover and focus-visible styles to pill remove button

* Use span with role=button for pill remove to match Obsidian's DOM

Obsidian's native multi-select pills use a span for the remove
control, not a button element. The button element picks up
Obsidian's base button styling (visible border) that can't be
easily overridden. Switching to a span with role="button" and
tabindex="0" matches the native DOM while preserving keyboard
accessibility via an explicit keydown handler.

* Match native button behavior: activate Space on keyup, not keydown

* Validate tag names against Obsidian's naming rules

Reject tags containing spaces, invalid characters, or only digits.
Strip leading # from user input. Show a Notice with the specific
reason when a tag is rejected. Validation applies only to the tags
property type, not aliases or multitext.

* Show notice when bare # is entered as a tag name

* Restore focus to pill input after adding or removing a pill

* Only refocus pill input from keyboard and paste, not blur commits

* Fix duplicate pill on multitext by clearing input before addPill

renderPills() detaches and reattaches the input element, which can
fire a focusout event mid-operation. The focusout handler would then
see the still-populated input and commit the same value again. For
tags/aliases this was masked by dedup, but multitext allows
duplicates so the double-add was visible. Fix by capturing and
clearing the input value before calling addPill.
2026-04-01 19:55:02 -06:00

94 lines
2.3 KiB
CSS

.bulk-properties-modal {
max-width: 500px;
}
.bulk-properties-date-input,
.bulk-properties-number-input {
background: var(--background-modifier-form-field);
border: 1px solid var(--background-modifier-border);
border-radius: var(--input-radius);
color: var(--text-normal);
padding: var(--size-4-1) var(--size-4-2);
font-size: var(--font-ui-medium);
}
.bulk-properties-file-list {
max-height: 200px;
overflow-y: auto;
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-s);
padding: var(--size-4-1);
margin-bottom: var(--size-4-4);
}
.bulk-properties-file-row {
display: flex;
align-items: center;
gap: var(--size-4-2);
padding: var(--size-2-1) 0;
}
.bulk-properties-file-path {
font-size: var(--font-ui-small);
color: var(--text-normal);
}
.bulk-properties-cancel-btn {
margin-left: var(--size-4-2);
}
.bulk-properties-pill-container {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--size-2-2);
min-height: var(--input-height);
padding: var(--size-4-1) var(--size-4-2);
background: var(--background-modifier-form-field);
border: 1px solid var(--background-modifier-border);
border-radius: var(--input-radius);
cursor: text;
}
.bulk-properties-pill-container:focus-within {
border-color: var(--background-modifier-border-focus);
box-shadow: 0 0 0 2px var(--background-modifier-border-focus);
}
.bulk-properties-pill-container .multi-select-pill {
font-size: var(--font-ui-smaller);
padding: var(--size-2-1) var(--size-2-3);
}
.bulk-properties-pill-container .multi-select-pill-remove-button {
border: none;
background: none;
padding: var(--size-2-1);
border-radius: var(--radius-s);
cursor: pointer;
color: var(--text-muted);
display: flex;
align-items: center;
}
.bulk-properties-pill-container .multi-select-pill-remove-button:hover {
color: var(--text-normal);
background: var(--background-modifier-hover);
}
.bulk-properties-pill-container .multi-select-pill-remove-button:focus-visible {
color: var(--text-normal);
outline: 2px solid var(--background-modifier-border-focus);
outline-offset: -1px;
}
.bulk-properties-pill-input {
flex: 1 1 80px;
min-width: 80px;
border: none;
background: transparent;
color: var(--text-normal);
font-size: var(--font-ui-medium);
outline: none;
padding: 0;
}