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' },
};