const { useMemo: useMemoDistrict } = React; function DistrictSheet({ open, onClose, options, selectedDistricts, onChange, countMode = 'rooms', }) { const selectedSet = useMemoDistrict(() => new Set(selectedDistricts || []), [selectedDistricts]); if (!open) return null; const toggleDistrict = (districtKey) => { const next = selectedSet.has(districtKey) ? selectedDistricts.filter((item) => item !== districtKey) : [...selectedDistricts, districtKey]; onChange(next); }; const clearAll = () => onChange([]); const labelOf = (districtKey) => { const match = (options || []).find((item) => item.key === districtKey); return match?.label || districtKey; }; const sheetContent = (
event.stopPropagation()}>
选择区域
按区市町村进一步细分
{selectedDistricts.length > 0 && (
{selectedDistricts.map((districtKey) => ( ))}
)}
{(options || []).length === 0 ? (
当前片区下没有可选区域
) : (
{options.map((option) => { const selected = selectedSet.has(option.key); const meta = countMode === 'properties' ? `${option.propertyCount || 0} 个物件名` : `${option.propertyCount || 0} 个房源 · ${option.roomCount || 0} 套空房`; return ( ); })}
)}
); return ReactDOM.createPortal(sheetContent, document.body); } const districtStyles = { backdrop: { position: 'fixed', inset: 0, background: 'rgba(20,18,14,0.38)', display: 'flex', alignItems: 'flex-end', zIndex: 1000, animation: 'fadeIn 180ms ease' }, sheet: { width: '100%', background: '#FAF8F5', borderTopLeftRadius: 20, borderTopRightRadius: 20, display: 'flex', flexDirection: 'column', height: '72dvh', minHeight: 420, maxHeight: '72dvh', boxShadow: '0 -8px 32px rgba(0,0,0,0.12)', animation: 'slideUp 260ms cubic-bezier(.2,.8,.2,1)' }, grabber: { width: 36, height: 4, borderRadius: 2, background: '#D4CCBE', margin: '8px auto 0' }, header: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 20px 10px' }, headerTitle: { fontSize: 17, fontWeight: 600, color: '#1A1A1A', letterSpacing: '0.01em' }, headerSub: { fontSize: 11, color: '#8A7F72', marginTop: 4 }, closeBtn: { width: 32, height: 32, borderRadius: 16, border: 'none', background: '#EFEAE0', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer' }, chipRow: { display: 'flex', flexWrap: 'wrap', gap: 6, padding: '6px 20px 12px', alignItems: 'center' }, chip: { display: 'inline-flex', alignItems: 'center', gap: 6, padding: '5px 10px', borderRadius: 999, background: '#FFF1E8', fontSize: 12, color: '#9A4E34', cursor: 'pointer', fontWeight: 600, border: 'none' }, clearBtn: { border: 'none', background: 'transparent', color: '#6B6258', fontSize: 12, textDecoration: 'underline', cursor: 'pointer', padding: 4 }, body: { flex: 1, minHeight: 0, overflowY: 'auto', padding: '0 18px 16px' }, emptyCard: { marginTop: 12, padding: '16px', borderRadius: 16, border: '1px solid #E4DFD6', background: '#FFFFFF', color: '#8A7F72', fontSize: 13, textAlign: 'center' }, optionList: { display: 'flex', flexDirection: 'column', gap: 10, paddingTop: 6 }, optionCard: { border: '1px solid #E4DFD6', borderRadius: 16, background: '#FFFFFF', padding: '14px 14px 12px', textAlign: 'left', fontFamily: 'inherit', cursor: 'pointer' }, optionTop: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }, optionName: { fontSize: 15, fontWeight: 700, color: '#1A1A1A' }, optionBadge: { padding: '4px 10px', borderRadius: 999, fontSize: 11, fontWeight: 700, whiteSpace: 'nowrap' }, optionMeta: { fontSize: 11, color: '#8A7F72', marginTop: 8, lineHeight: 1.5 }, footer: { padding: '12px 18px calc(18px + env(safe-area-inset-bottom, 0px))', borderTop: '1px solid #EDE6D9', background: '#FAF8F5' }, applyBtn: { width: '100%', border: 'none', borderRadius: 14, background: '#1A1A1A', color: '#FAF8F5', padding: '14px', fontSize: 14, fontWeight: 600, fontFamily: 'inherit', cursor: 'pointer' }, };