62 lines
3.1 KiB
TypeScript
62 lines
3.1 KiB
TypeScript
import type { InventorySearch } from './useInventorySearch';
|
||
import { RATING_DEFS, WEAPON_TYPES } from './constants';
|
||
|
||
interface Chip { label: string; gold?: boolean; remove: () => void; }
|
||
|
||
export function ActiveChips({ search }: { search: InventorySearch }) {
|
||
const { filters: f, update } = search;
|
||
const chips: Chip[] = [];
|
||
if (f.text) chips.push({ label: `"${f.text}"`, remove: () => update({ text: '' }) });
|
||
if (f.characters !== 'all') chips.push({
|
||
label: `${f.characters.length} character${f.characters.length === 1 ? '' : 's'}`,
|
||
remove: () => update({ characters: 'all' }),
|
||
});
|
||
if (f.itemType !== 'all') chips.push({
|
||
label: f.itemType[0].toUpperCase() + f.itemType.slice(1),
|
||
remove: () => update({ itemType: 'all', weaponTypes: [] }),
|
||
});
|
||
if (f.itemType === 'weapon') for (const wt of f.weaponTypes) {
|
||
const label = WEAPON_TYPES.find(w => w.value === wt)?.label ?? wt;
|
||
chips.push({ label, remove: () => update({ weaponTypes: f.weaponTypes.filter(x => x !== wt) }) });
|
||
}
|
||
for (const s of f.slots) chips.push({ label: `Slot: ${s}`, remove: () => update({ slots: f.slots.filter(x => x !== s) }) });
|
||
for (const c of f.cantrips) chips.push({
|
||
label: c.replace(/^Legendary /, 'Leg. '), gold: true,
|
||
remove: () => update({ cantrips: f.cantrips.filter(x => x !== c) }),
|
||
});
|
||
if (f.spellContains) chips.push({ label: `Spell: ${f.spellContains}`, remove: () => update({ spellContains: '' }) });
|
||
for (const [param, v] of Object.entries(f.ratings)) if (v !== '') {
|
||
const def = RATING_DEFS.find(r => r.param === param);
|
||
chips.push({
|
||
label: `${def?.label ?? param} ≥ ${v}`,
|
||
remove: () => {
|
||
const { [param]: _omit, ...rest } = f.ratings;
|
||
update({ ratings: rest });
|
||
},
|
||
});
|
||
}
|
||
if (f.itemSet) chips.push({ label: `Set: ${f.itemSet}`, remove: () => update({ itemSet: '' }) });
|
||
if (f.equipStatus) chips.push({
|
||
label: f.equipStatus === 'equipped' ? 'Equipped' : 'Not equipped',
|
||
remove: () => update({ equipStatus: '' }),
|
||
});
|
||
if (f.bonded) chips.push({ label: 'Bonded', remove: () => update({ bonded: false }) });
|
||
if (f.attuned) chips.push({ label: 'Attuned', remove: () => update({ attuned: false }) });
|
||
if (f.rare) chips.push({ label: 'Rare', remove: () => update({ rare: false }) });
|
||
if (f.maxLevel !== '') chips.push({ label: `Wield ≤ ${f.maxLevel}`, remove: () => update({ maxLevel: '' }) });
|
||
if (f.minValue !== '') chips.push({ label: `Value ≥ ${f.minValue}`, remove: () => update({ minValue: '' }) });
|
||
if (f.minWorkmanship !== '') chips.push({ label: `Work ≥ ${f.minWorkmanship}`, remove: () => update({ minWorkmanship: '' }) });
|
||
if (f.maxBurden !== '') chips.push({ label: `Burden ≤ ${f.maxBurden}`, remove: () => update({ maxBurden: '' }) });
|
||
|
||
if (!chips.length) return null;
|
||
return (
|
||
<div className="inv-chipsrow">
|
||
<span className="inv-chips-lbl">ACTIVE</span>
|
||
{chips.map((c, i) => (
|
||
<span className={`inv-chip${c.gold ? ' inv-chip-gold' : ''}`} key={i}>
|
||
{c.label} <span className="inv-chip-x" onClick={c.remove}>×</span>
|
||
</span>
|
||
))}
|
||
</div>
|
||
);
|
||
}
|