import { useState, useRef, useEffect, useMemo } from 'react'; import { Search, Loader2, ChevronDown, Cloud, CloudOff } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import type { FilamentSectionProps, FilamentOption } from './types'; import { KNOWN_VARIANTS } from './constants'; import { parsePresetName } from './utils'; // The identity fields a slicer preset can auto-fill. type PresetFilledField = 'material' | 'brand' | 'subtype'; // Split a dropdown's options into the ones the catalog/presets pair with the // other field's current value and everything else (#1905). Suggestions are only // a sort order — nothing is ever hidden, so an unusual-but-real combination // (Elegoo ASA) stays one click away. function splitSuggested(options: string[], suggested: string[]): { top: string[]; rest: string[] } { if (suggested.length === 0) return { top: [], rest: options }; const keys = new Set(suggested.map(s => s.toLowerCase())); return { top: options.filter(o => keys.has(o.toLowerCase())), rest: options.filter(o => !keys.has(o.toLowerCase())), }; } function GroupHeading({ label }: { label: string }) { return (
{errors.slicer_filament}
)}{errors.material}
)}{errors.brand}
)}{errors.subtype}
)}