feat(inventory): replace prompt dialogs with inline editing
Replaced all prompt() and confirm() dialogs with contenteditable fields and inline UI components for a better user experience. Changes: - Made inventory fields (On Person, Stored items, Assets) contenteditable with blur-to-save functionality - Replaced "Add Location" prompt with inline form (hidden by default) - Replaced "Remove Location" confirm with inline confirmation UI - Added CSS styling for inline editing states (hover, focus, empty) - Added CSS for inline forms, buttons, and confirmation UI - Fixed bug where inventory sub-tabs were unclickable due to incorrect container ID in toggleLocationCollapse() and switchInventoryTab() functions All inline edits now save automatically on blur, matching the UX pattern used elsewhere in the extension (mood/conditions fields).
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
import { extensionSettings, lastGeneratedData } from '../../core/state.js';
|
import { extensionSettings, lastGeneratedData } from '../../core/state.js';
|
||||||
import { saveSettings, saveChatData, updateMessageSwipeData } from '../../core/persistence.js';
|
import { saveSettings, saveChatData, updateMessageSwipeData } from '../../core/persistence.js';
|
||||||
import { buildInventorySummary } from '../generation/promptBuilder.js';
|
import { buildInventorySummary } from '../generation/promptBuilder.js';
|
||||||
import { renderInventory, updateInventoryDisplay } from '../rendering/inventory.js';
|
import { renderInventory } from '../rendering/inventory.js';
|
||||||
|
|
||||||
// Type imports
|
// Type imports
|
||||||
/** @typedef {import('../../types/inventory.js').InventoryV2} InventoryV2 */
|
/** @typedef {import('../../types/inventory.js').InventoryV2} InventoryV2 */
|
||||||
@@ -43,124 +43,151 @@ function updateLastGeneratedDataInventory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits items currently on the character's person.
|
* Handles blur event for contenteditable "On Person" field.
|
||||||
* @returns {Promise<void>}
|
* Saves changes when user finishes editing.
|
||||||
|
* @param {HTMLElement} element - The contenteditable element
|
||||||
*/
|
*/
|
||||||
export async function editOnPerson() {
|
export function handleOnPersonBlur(element) {
|
||||||
const inventory = extensionSettings.userStats.inventory;
|
const inventory = extensionSettings.userStats.inventory;
|
||||||
const current = inventory.onPerson || 'None';
|
const newValue = element.textContent.trim() || 'None';
|
||||||
|
|
||||||
const newValue = prompt('Edit items on person (carried/worn):', current);
|
// Only save if value actually changed
|
||||||
if (newValue === null) return; // User cancelled
|
if (newValue !== inventory.onPerson) {
|
||||||
|
inventory.onPerson = newValue;
|
||||||
inventory.onPerson = newValue.trim() || 'None';
|
|
||||||
|
|
||||||
updateLastGeneratedDataInventory();
|
updateLastGeneratedDataInventory();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
saveChatData();
|
saveChatData();
|
||||||
updateMessageSwipeData();
|
updateMessageSwipeData();
|
||||||
|
}
|
||||||
// Re-render inventory UI
|
|
||||||
updateInventoryDisplay('rpg-inventory-content', {
|
|
||||||
activeSubTab: currentActiveSubTab,
|
|
||||||
collapsedLocations
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits items stored at a specific location.
|
* Handles blur event for contenteditable stored location field.
|
||||||
|
* Saves changes when user finishes editing.
|
||||||
|
* @param {HTMLElement} element - The contenteditable element
|
||||||
* @param {string} locationName - Name of the storage location
|
* @param {string} locationName - Name of the storage location
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
*/
|
||||||
export async function editStoredLocation(locationName) {
|
export function handleStoredLocationBlur(element, locationName) {
|
||||||
const inventory = extensionSettings.userStats.inventory;
|
const inventory = extensionSettings.userStats.inventory;
|
||||||
const current = inventory.stored[locationName] || 'None';
|
const newValue = element.textContent.trim() || 'None';
|
||||||
|
|
||||||
const newValue = prompt(`Edit items stored at "${locationName}":`, current);
|
// Only save if value actually changed
|
||||||
if (newValue === null) return; // User cancelled
|
if (newValue !== inventory.stored[locationName]) {
|
||||||
|
inventory.stored[locationName] = newValue;
|
||||||
inventory.stored[locationName] = newValue.trim() || 'None';
|
|
||||||
|
|
||||||
updateLastGeneratedDataInventory();
|
updateLastGeneratedDataInventory();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
saveChatData();
|
saveChatData();
|
||||||
updateMessageSwipeData();
|
updateMessageSwipeData();
|
||||||
|
}
|
||||||
// Re-render inventory UI
|
|
||||||
updateInventoryDisplay('rpg-inventory-content', {
|
|
||||||
activeSubTab: currentActiveSubTab,
|
|
||||||
collapsedLocations
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits character's assets (vehicles, property, major possessions).
|
* Handles blur event for contenteditable "Assets" field.
|
||||||
* @returns {Promise<void>}
|
* Saves changes when user finishes editing.
|
||||||
|
* @param {HTMLElement} element - The contenteditable element
|
||||||
*/
|
*/
|
||||||
export async function editAssets() {
|
export function handleAssetsBlur(element) {
|
||||||
const inventory = extensionSettings.userStats.inventory;
|
const inventory = extensionSettings.userStats.inventory;
|
||||||
const current = inventory.assets || 'None';
|
const newValue = element.textContent.trim() || 'None';
|
||||||
|
|
||||||
const newValue = prompt('Edit assets (vehicles, property, equipment):', current);
|
// Only save if value actually changed
|
||||||
if (newValue === null) return; // User cancelled
|
if (newValue !== inventory.assets) {
|
||||||
|
inventory.assets = newValue;
|
||||||
inventory.assets = newValue.trim() || 'None';
|
|
||||||
|
|
||||||
updateLastGeneratedDataInventory();
|
updateLastGeneratedDataInventory();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
saveChatData();
|
saveChatData();
|
||||||
updateMessageSwipeData();
|
updateMessageSwipeData();
|
||||||
|
}
|
||||||
// Re-render inventory UI
|
|
||||||
updateInventoryDisplay('rpg-inventory-content', {
|
|
||||||
activeSubTab: currentActiveSubTab,
|
|
||||||
collapsedLocations
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new storage location to the inventory.
|
* Shows the inline form for adding a new storage location.
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
*/
|
||||||
export async function addStorageLocation() {
|
export function showAddLocationForm() {
|
||||||
|
const form = $('#rpg-add-location-form');
|
||||||
|
const input = $('#rpg-new-location-name');
|
||||||
|
|
||||||
|
form.show();
|
||||||
|
input.val('').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the inline form for adding a new storage location.
|
||||||
|
*/
|
||||||
|
export function hideAddLocationForm() {
|
||||||
|
const form = $('#rpg-add-location-form');
|
||||||
|
const input = $('#rpg-new-location-name');
|
||||||
|
|
||||||
|
form.hide();
|
||||||
|
input.val('');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a new storage location from the inline form.
|
||||||
|
*/
|
||||||
|
export function saveAddLocation() {
|
||||||
const inventory = extensionSettings.userStats.inventory;
|
const inventory = extensionSettings.userStats.inventory;
|
||||||
|
const input = $('#rpg-new-location-name');
|
||||||
|
const locationName = input.val().trim();
|
||||||
|
|
||||||
const locationName = prompt('Enter name for new storage location:');
|
if (!locationName) {
|
||||||
if (!locationName) return; // User cancelled or entered empty string
|
hideAddLocationForm();
|
||||||
|
return;
|
||||||
const trimmedName = locationName.trim();
|
}
|
||||||
|
|
||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
if (inventory.stored[trimmedName]) {
|
if (inventory.stored[locationName]) {
|
||||||
alert(`Storage location "${trimmedName}" already exists.`);
|
alert(`Storage location "${locationName}" already exists.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new location with default "None"
|
// Create new location with default "None"
|
||||||
inventory.stored[trimmedName] = 'None';
|
inventory.stored[locationName] = 'None';
|
||||||
|
|
||||||
updateLastGeneratedDataInventory();
|
updateLastGeneratedDataInventory();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
saveChatData();
|
saveChatData();
|
||||||
updateMessageSwipeData();
|
updateMessageSwipeData();
|
||||||
|
|
||||||
// Switch to stored tab and re-render
|
// Hide form and re-render
|
||||||
currentActiveSubTab = 'stored';
|
hideAddLocationForm();
|
||||||
updateInventoryDisplay('rpg-inventory-content', {
|
renderInventory();
|
||||||
activeSubTab: currentActiveSubTab,
|
|
||||||
collapsedLocations
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a storage location from the inventory.
|
* Shows the inline confirmation UI for removing a storage location.
|
||||||
* @param {string} locationName - Name of location to remove
|
* @param {string} locationName - Name of location to remove
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
*/
|
||||||
export async function removeStorageLocation(locationName) {
|
export function showRemoveConfirmation(locationName) {
|
||||||
const confirmed = confirm(`Remove storage location "${locationName}"?\n\nThis will delete all items stored there.`);
|
const confirmId = `rpg-remove-confirm-${locationName.replace(/\s+/g, '-')}`;
|
||||||
if (!confirmed) return;
|
const confirmUI = $(`#${confirmId}`);
|
||||||
|
|
||||||
|
if (confirmUI.length > 0) {
|
||||||
|
confirmUI.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the inline confirmation UI for removing a storage location.
|
||||||
|
* @param {string} locationName - Name of location
|
||||||
|
*/
|
||||||
|
export function hideRemoveConfirmation(locationName) {
|
||||||
|
const confirmId = `rpg-remove-confirm-${locationName.replace(/\s+/g, '-')}`;
|
||||||
|
const confirmUI = $(`#${confirmId}`);
|
||||||
|
|
||||||
|
if (confirmUI.length > 0) {
|
||||||
|
confirmUI.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirms and removes a storage location from the inventory.
|
||||||
|
* @param {string} locationName - Name of location to remove
|
||||||
|
*/
|
||||||
|
export function confirmRemoveLocation(locationName) {
|
||||||
const inventory = extensionSettings.userStats.inventory;
|
const inventory = extensionSettings.userStats.inventory;
|
||||||
delete inventory.stored[locationName];
|
delete inventory.stored[locationName];
|
||||||
|
|
||||||
@@ -176,10 +203,7 @@ export async function removeStorageLocation(locationName) {
|
|||||||
updateMessageSwipeData();
|
updateMessageSwipeData();
|
||||||
|
|
||||||
// Re-render inventory UI
|
// Re-render inventory UI
|
||||||
updateInventoryDisplay('rpg-inventory-content', {
|
renderInventory();
|
||||||
activeSubTab: currentActiveSubTab,
|
|
||||||
collapsedLocations
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -202,10 +226,7 @@ export function toggleLocationCollapse(locationName) {
|
|||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
// Re-render inventory UI
|
// Re-render inventory UI
|
||||||
updateInventoryDisplay('rpg-inventory-content', {
|
renderInventory();
|
||||||
activeSubTab: currentActiveSubTab,
|
|
||||||
collapsedLocations
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -216,10 +237,7 @@ export function switchInventoryTab(tabName) {
|
|||||||
currentActiveSubTab = tabName;
|
currentActiveSubTab = tabName;
|
||||||
|
|
||||||
// Re-render inventory UI
|
// Re-render inventory UI
|
||||||
updateInventoryDisplay('rpg-inventory-content', {
|
renderInventory();
|
||||||
activeSubTab: currentActiveSubTab,
|
|
||||||
collapsedLocations
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,40 +250,66 @@ export function initInventoryEventListeners() {
|
|||||||
collapsedLocations = extensionSettings.collapsedInventoryLocations;
|
collapsedLocations = extensionSettings.collapsedInventoryLocations;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event delegation for all inventory buttons
|
// Contenteditable blur handlers (inline editing)
|
||||||
$(document).on('click', '.rpg-inventory-edit-btn', function(e) {
|
$(document).on('blur', '.rpg-inventory-text[contenteditable="true"]', function() {
|
||||||
e.preventDefault();
|
const field = $(this).data('field');
|
||||||
const action = $(this).data('action');
|
const element = this;
|
||||||
|
|
||||||
if (action === 'edit-onperson') {
|
if (field === 'onPerson') {
|
||||||
editOnPerson();
|
handleOnPersonBlur(element);
|
||||||
} else if (action === 'edit-location') {
|
} else if (field === 'stored') {
|
||||||
const location = $(this).data('location');
|
const location = $(this).data('location');
|
||||||
editStoredLocation(location);
|
handleStoredLocationBlur(element, location);
|
||||||
} else if (action === 'edit-assets') {
|
} else if (field === 'assets') {
|
||||||
editAssets();
|
handleAssetsBlur(element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add location button
|
// Add location button - shows inline form
|
||||||
$(document).on('click', '.rpg-inventory-add-btn', function(e) {
|
$(document).on('click', '.rpg-inventory-add-btn[data-action="add-location"]', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const action = $(this).data('action');
|
showAddLocationForm();
|
||||||
|
});
|
||||||
|
|
||||||
if (action === 'add-location') {
|
// Add location inline form - save button
|
||||||
addStorageLocation();
|
$(document).on('click', '.rpg-inline-btn[data-action="save-add-location"]', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
saveAddLocation();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add location inline form - cancel button
|
||||||
|
$(document).on('click', '.rpg-inline-btn[data-action="cancel-add-location"]', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
hideAddLocationForm();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add location inline form - enter key to save
|
||||||
|
$(document).on('keypress', '#rpg-new-location-name', function(e) {
|
||||||
|
if (e.which === 13) { // Enter key
|
||||||
|
e.preventDefault();
|
||||||
|
saveAddLocation();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove location buttons
|
// Remove location button - shows inline confirmation
|
||||||
$(document).on('click', '.rpg-inventory-remove-btn', function(e) {
|
$(document).on('click', '.rpg-inventory-remove-btn[data-action="remove-location"]', function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const action = $(this).data('action');
|
|
||||||
|
|
||||||
if (action === 'remove-location') {
|
|
||||||
const location = $(this).data('location');
|
const location = $(this).data('location');
|
||||||
removeStorageLocation(location);
|
showRemoveConfirmation(location);
|
||||||
}
|
});
|
||||||
|
|
||||||
|
// Remove location inline confirmation - confirm button
|
||||||
|
$(document).on('click', '.rpg-inline-btn[data-action="confirm-remove-location"]', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const location = $(this).data('location');
|
||||||
|
confirmRemoveLocation(location);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove location inline confirmation - cancel button
|
||||||
|
$(document).on('click', '.rpg-inline-btn[data-action="cancel-remove-location"]', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const location = $(this).data('location');
|
||||||
|
hideRemoveConfirmation(location);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Collapse toggle buttons
|
// Collapse toggle buttons
|
||||||
|
|||||||
@@ -41,12 +41,9 @@ export function renderOnPersonView(onPersonItems) {
|
|||||||
<div class="rpg-inventory-section" data-section="onPerson">
|
<div class="rpg-inventory-section" data-section="onPerson">
|
||||||
<div class="rpg-inventory-header">
|
<div class="rpg-inventory-header">
|
||||||
<h4>Items Currently Carried</h4>
|
<h4>Items Currently Carried</h4>
|
||||||
<button class="rpg-inventory-edit-btn" data-action="edit-onperson" title="Edit on-person inventory">
|
|
||||||
<i class="fa-solid fa-pen"></i> Edit
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="rpg-inventory-content">
|
<div class="rpg-inventory-content">
|
||||||
<div class="rpg-inventory-text">${escapeHtml(displayText)}</div>
|
<div class="rpg-inventory-text rpg-editable" contenteditable="true" data-field="onPerson" title="Click to edit">${escapeHtml(displayText)}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -70,6 +67,17 @@ export function renderStoredView(stored, collapsedLocations = []) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="rpg-inventory-content">
|
<div class="rpg-inventory-content">
|
||||||
|
<div class="rpg-inline-form" id="rpg-add-location-form" style="display: none;">
|
||||||
|
<input type="text" class="rpg-inline-input" id="rpg-new-location-name" placeholder="Enter location name..." />
|
||||||
|
<div class="rpg-inline-buttons">
|
||||||
|
<button class="rpg-inline-btn rpg-inline-cancel" data-action="cancel-add-location">
|
||||||
|
<i class="fa-solid fa-times"></i> Cancel
|
||||||
|
</button>
|
||||||
|
<button class="rpg-inline-btn rpg-inline-save" data-action="save-add-location">
|
||||||
|
<i class="fa-solid fa-check"></i> Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (locations.length === 0) {
|
if (locations.length === 0) {
|
||||||
@@ -90,16 +98,24 @@ export function renderStoredView(stored, collapsedLocations = []) {
|
|||||||
</button>
|
</button>
|
||||||
<h5 class="rpg-storage-name">${escapeHtml(location)}</h5>
|
<h5 class="rpg-storage-name">${escapeHtml(location)}</h5>
|
||||||
<div class="rpg-storage-actions">
|
<div class="rpg-storage-actions">
|
||||||
<button class="rpg-inventory-edit-btn" data-action="edit-location" data-location="${escapeHtml(location)}" title="Edit items at this location">
|
|
||||||
<i class="fa-solid fa-pen"></i>
|
|
||||||
</button>
|
|
||||||
<button class="rpg-inventory-remove-btn" data-action="remove-location" data-location="${escapeHtml(location)}" title="Remove this storage location">
|
<button class="rpg-inventory-remove-btn" data-action="remove-location" data-location="${escapeHtml(location)}" title="Remove this storage location">
|
||||||
<i class="fa-solid fa-trash"></i>
|
<i class="fa-solid fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rpg-storage-content" ${isCollapsed ? 'style="display:none;"' : ''}>
|
<div class="rpg-storage-content" ${isCollapsed ? 'style="display:none;"' : ''}>
|
||||||
<div class="rpg-inventory-text">${escapeHtml(items || 'None')}</div>
|
<div class="rpg-inventory-text rpg-editable" contenteditable="true" data-field="stored" data-location="${escapeHtml(location)}" title="Click to edit">${escapeHtml(items || 'None')}</div>
|
||||||
|
</div>
|
||||||
|
<div class="rpg-inline-confirmation" id="rpg-remove-confirm-${escapeHtml(location).replace(/\s+/g, '-')}" style="display: none;">
|
||||||
|
<p>Remove "${escapeHtml(location)}"? This will delete all items stored there.</p>
|
||||||
|
<div class="rpg-inline-buttons">
|
||||||
|
<button class="rpg-inline-btn rpg-inline-cancel" data-action="cancel-remove-location" data-location="${escapeHtml(location)}">
|
||||||
|
<i class="fa-solid fa-times"></i> Cancel
|
||||||
|
</button>
|
||||||
|
<button class="rpg-inline-btn rpg-inline-confirm" data-action="confirm-remove-location" data-location="${escapeHtml(location)}">
|
||||||
|
<i class="fa-solid fa-check"></i> Confirm
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -125,12 +141,9 @@ export function renderAssetsView(assets) {
|
|||||||
<div class="rpg-inventory-section" data-section="assets">
|
<div class="rpg-inventory-section" data-section="assets">
|
||||||
<div class="rpg-inventory-header">
|
<div class="rpg-inventory-header">
|
||||||
<h4>Vehicles, Property & Major Possessions</h4>
|
<h4>Vehicles, Property & Major Possessions</h4>
|
||||||
<button class="rpg-inventory-edit-btn" data-action="edit-assets" title="Edit assets">
|
|
||||||
<i class="fa-solid fa-pen"></i> Edit
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="rpg-inventory-content">
|
<div class="rpg-inventory-content">
|
||||||
<div class="rpg-inventory-text">${escapeHtml(displayText)}</div>
|
<div class="rpg-inventory-text rpg-editable" contenteditable="true" data-field="assets" title="Click to edit">${escapeHtml(displayText)}</div>
|
||||||
<div class="rpg-inventory-hint">
|
<div class="rpg-inventory-hint">
|
||||||
<i class="fa-solid fa-info-circle"></i>
|
<i class="fa-solid fa-info-circle"></i>
|
||||||
Assets include vehicles (cars, motorcycles), property (homes, apartments),
|
Assets include vehicles (cars, motorcycles), property (homes, apartments),
|
||||||
|
|||||||
@@ -4109,6 +4109,121 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Inline Editing Styles */
|
||||||
|
.rpg-inventory-text.rpg-editable {
|
||||||
|
cursor: text;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
min-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inventory-text.rpg-editable:hover {
|
||||||
|
background: var(--SmartThemeQuoteColor);
|
||||||
|
border-color: var(--ac-style-color-matchedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inventory-text.rpg-editable:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--ac-style-color-matchedText);
|
||||||
|
background: var(--SmartThemeEmColor);
|
||||||
|
box-shadow: 0 0 0 2px rgba(var(--ac-style-color-matchedText-rgb, 66, 135, 245), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inventory-text.rpg-editable:empty::before {
|
||||||
|
content: 'Click to edit...';
|
||||||
|
color: var(--SmartThemeFastUISliderColColor);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline Forms */
|
||||||
|
.rpg-inline-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: var(--SmartThemeQuoteColor);
|
||||||
|
border: 1px solid var(--ac-style-color-matchedText);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-input {
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
background: var(--SmartThemeBlurTintColor);
|
||||||
|
border: 1px solid var(--SmartThemeBorderColor);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
color: var(--SmartThemeBodyColor);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--ac-style-color-matchedText);
|
||||||
|
box-shadow: 0 0 0 2px rgba(var(--ac-style-color-matchedText-rgb, 66, 135, 245), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-buttons {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-btn {
|
||||||
|
padding: 0.4rem 0.75rem;
|
||||||
|
border: 1px solid var(--SmartThemeBorderColor);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
background: var(--SmartThemeBlurTintColor);
|
||||||
|
color: var(--SmartThemeBodyColor);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-btn:hover {
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-cancel {
|
||||||
|
background: var(--SmartThemeBlurTintColor);
|
||||||
|
color: var(--SmartThemeFastUISliderColColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-cancel:hover {
|
||||||
|
background: #6c757d;
|
||||||
|
border-color: #6c757d;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-save,
|
||||||
|
.rpg-inline-confirm {
|
||||||
|
background: var(--ac-style-color-matchedText);
|
||||||
|
border-color: var(--ac-style-color-matchedText);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-save:hover,
|
||||||
|
.rpg-inline-confirm:hover {
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline Confirmation */
|
||||||
|
.rpg-inline-confirmation {
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: var(--SmartThemeQuoteColor);
|
||||||
|
border: 1px solid #dc3545;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rpg-inline-confirmation p {
|
||||||
|
margin: 0 0 0.75rem 0;
|
||||||
|
color: var(--SmartThemeBodyColor);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================
|
/* ============================================
|
||||||
DESKTOP TABS SYSTEM
|
DESKTOP TABS SYSTEM
|
||||||
============================================ */
|
============================================ */
|
||||||
|
|||||||
Reference in New Issue
Block a user