城市合伙人端开店城市屁默认郑州
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { codeToText } from 'element-china-area-data';
|
||||
import { CHINA_REGION_OPTIONS, formatRegionLabel, parseRegionCodes } from '../lib/china-region';
|
||||
import {
|
||||
CHINA_REGION_OPTIONS,
|
||||
DEFAULT_REGION_CODES,
|
||||
formatRegionLabel,
|
||||
parseRegionCodes,
|
||||
} from '../lib/china-region';
|
||||
|
||||
type RegionNode = {
|
||||
value: string;
|
||||
@@ -40,10 +45,26 @@ function lockBodyScroll(lock: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
function buildInitialDraft(value: string[]): { draft: string[]; step: number } {
|
||||
if (value.length === 3) {
|
||||
return { draft: [...value], step: 2 };
|
||||
}
|
||||
if (value.length > 0) {
|
||||
const draft = [...value];
|
||||
for (let i = value.length; i < DEFAULT_REGION_CODES.length; i += 1) {
|
||||
draft.push(DEFAULT_REGION_CODES[i]);
|
||||
}
|
||||
return { draft, step: Math.min(value.length, 2) };
|
||||
}
|
||||
return { draft: [...DEFAULT_REGION_CODES], step: 1 };
|
||||
}
|
||||
|
||||
export default function ChinaRegionPicker({ value = [], onChange, disabled }: ChinaRegionPickerProps) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [draft, setDraft] = useState<string[]>(value);
|
||||
const [step, setStep] = useState(0);
|
||||
const listRef = useRef<HTMLDivElement>(null);
|
||||
const activeItemRef = useRef<HTMLButtonElement | null>(null);
|
||||
|
||||
const options = CHINA_REGION_OPTIONS as RegionNode[];
|
||||
const parsed = parseRegionCodes(value);
|
||||
@@ -69,11 +90,23 @@ export default function ChinaRegionPicker({ value = [], onChange, disabled }: Ch
|
||||
return () => lockBodyScroll(false);
|
||||
}, [open]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const timer = window.setTimeout(() => {
|
||||
const container = listRef.current;
|
||||
const activeEl = activeItemRef.current;
|
||||
if (!container || !activeEl) return;
|
||||
const offset = activeEl.offsetTop - container.clientHeight / 2 + activeEl.clientHeight / 2;
|
||||
container.scrollTo({ top: Math.max(0, offset), behavior: 'smooth' });
|
||||
}, 0);
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [open, step, activeCode, listItems]);
|
||||
|
||||
function openPicker() {
|
||||
if (disabled) return;
|
||||
const next = value.length === 3 ? [...value] : [];
|
||||
const { draft: next, step: initialStep } = buildInitialDraft(value);
|
||||
setDraft(next);
|
||||
setStep(next.length >= 3 ? 2 : next.length);
|
||||
setStep(initialStep);
|
||||
setOpen(true);
|
||||
}
|
||||
|
||||
@@ -147,13 +180,14 @@ export default function ChinaRegionPicker({ value = [], onChange, disabled }: Ch
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="partner-region-list" role="listbox">
|
||||
<div className="partner-region-list" role="listbox" ref={listRef}>
|
||||
{listItems.map((item) => (
|
||||
<button
|
||||
key={item.value}
|
||||
type="button"
|
||||
role="option"
|
||||
aria-selected={activeCode === item.value}
|
||||
ref={activeCode === item.value ? (el) => { activeItemRef.current = el; } : undefined}
|
||||
className={`partner-region-item${activeCode === item.value ? ' partner-region-item--active' : ''}`}
|
||||
onClick={() => selectItem(item.value)}
|
||||
>
|
||||
@@ -175,4 +209,4 @@ export default function ChinaRegionPicker({ value = [], onChange, disabled }: Ch
|
||||
{typeof document !== 'undefined' ? createPortal(modal, document.body) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user