feat: allow custom nearby radius
This commit is contained in:
@@ -48,9 +48,11 @@ const namedAreas = [
|
|||||||
const radiusOptions = [50, 100, 250, 500, 1000];
|
const radiusOptions = [50, 100, 250, 500, 1000];
|
||||||
const customChoice = 'custom';
|
const customChoice = 'custom';
|
||||||
const noNearbyChoice = 'none';
|
const noNearbyChoice = 'none';
|
||||||
|
const customRadiusChoice = 'custom-radius';
|
||||||
|
|
||||||
type RequestStatus = 'idle' | 'loading' | 'success' | 'error';
|
type RequestStatus = 'idle' | 'loading' | 'success' | 'error';
|
||||||
type NearbyChoice = typeof noNearbyChoice | typeof customChoice | string;
|
type NearbyChoice = typeof noNearbyChoice | typeof customChoice | string;
|
||||||
|
type RadiusChoice = number | typeof customRadiusChoice;
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
const [category, setCategory] = useState(searchPresetCategories[0]);
|
const [category, setCategory] = useState(searchPresetCategories[0]);
|
||||||
@@ -64,6 +66,7 @@ export function App() {
|
|||||||
const [nearbyChoice, setNearbyChoice] = useState<NearbyChoice>(noNearbyChoice);
|
const [nearbyChoice, setNearbyChoice] = useState<NearbyChoice>(noNearbyChoice);
|
||||||
const [nearbyCustomKey, setNearbyCustomKey] = useState('');
|
const [nearbyCustomKey, setNearbyCustomKey] = useState('');
|
||||||
const [nearbyCustomValue, setNearbyCustomValue] = useState('');
|
const [nearbyCustomValue, setNearbyCustomValue] = useState('');
|
||||||
|
const [radiusChoice, setRadiusChoice] = useState<RadiusChoice>(100);
|
||||||
const [nearbyRadius, setNearbyRadius] = useState(100);
|
const [nearbyRadius, setNearbyRadius] = useState(100);
|
||||||
const [areaMode, setAreaMode] = useState<SearchArea['mode']>('bbox');
|
const [areaMode, setAreaMode] = useState<SearchArea['mode']>('bbox');
|
||||||
const [bbox, setBBox] = useState<BBox>(DEFAULT_BBOX);
|
const [bbox, setBBox] = useState<BBox>(DEFAULT_BBOX);
|
||||||
@@ -238,6 +241,25 @@ export function App() {
|
|||||||
setNearbyCustomValue('');
|
setNearbyCustomValue('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleRadiusChoiceChange(value: string) {
|
||||||
|
if (value === customRadiusChoice) {
|
||||||
|
setRadiusChoice(customRadiusChoice);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const radius = Number(value);
|
||||||
|
setRadiusChoice(radius);
|
||||||
|
setNearbyRadius(radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCustomRadiusChange(value: string) {
|
||||||
|
const radius = Number(value);
|
||||||
|
|
||||||
|
if (Number.isFinite(radius)) {
|
||||||
|
setNearbyRadius(radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleClearResults() {
|
function handleClearResults() {
|
||||||
setResults([]);
|
setResults([]);
|
||||||
setSelectedResultId(null);
|
setSelectedResultId(null);
|
||||||
@@ -462,18 +484,32 @@ export function App() {
|
|||||||
|
|
||||||
<div className="control-group">
|
<div className="control-group">
|
||||||
<label htmlFor="nearby-radius">Radius</label>
|
<label htmlFor="nearby-radius">Radius</label>
|
||||||
|
<div className="radius-controls">
|
||||||
<select
|
<select
|
||||||
id="nearby-radius"
|
id="nearby-radius"
|
||||||
value={nearbyRadius}
|
value={radiusChoice}
|
||||||
disabled={nearbyChoice === noNearbyChoice}
|
disabled={nearbyChoice === noNearbyChoice}
|
||||||
onChange={(event) => setNearbyRadius(Number(event.target.value))}
|
onChange={(event) => handleRadiusChoiceChange(event.target.value)}
|
||||||
>
|
>
|
||||||
{radiusOptions.map((radius) => (
|
{radiusOptions.map((radius) => (
|
||||||
<option key={radius} value={radius}>
|
<option key={radius} value={radius}>
|
||||||
{radius} meters
|
{radius} meters
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
|
<option value={customRadiusChoice}>Custom</option>
|
||||||
</select>
|
</select>
|
||||||
|
{radiusChoice === customRadiusChoice ? (
|
||||||
|
<input
|
||||||
|
aria-label="Custom radius in meters"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
step="1"
|
||||||
|
value={nearbyRadius}
|
||||||
|
disabled={nearbyChoice === noNearbyChoice}
|
||||||
|
onChange={(event) => handleCustomRadiusChange(event.target.value)}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,12 @@ a {
|
|||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radius-controls {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) minmax(96px, 0.55fr);
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.checkbox-grid {
|
.checkbox-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
@@ -457,6 +463,7 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.custom-fields,
|
.custom-fields,
|
||||||
|
.radius-controls,
|
||||||
.segmented-control,
|
.segmented-control,
|
||||||
.checkbox-grid {
|
.checkbox-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|||||||
Reference in New Issue
Block a user