@tpzdsp/next-toolkit 1.15.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ type Props = {
|
|
|
11
11
|
title: string;
|
|
12
12
|
children: ReactNode;
|
|
13
13
|
defaultOpen?: boolean;
|
|
14
|
+
disabled?: boolean;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
export type AccordionProps = ExtendProps<'div', Props>;
|
|
@@ -19,6 +20,7 @@ export const Accordion = ({
|
|
|
19
20
|
title,
|
|
20
21
|
children,
|
|
21
22
|
defaultOpen = false,
|
|
23
|
+
disabled = false,
|
|
22
24
|
className,
|
|
23
25
|
...props
|
|
24
26
|
}: AccordionProps) => {
|
|
@@ -28,14 +30,25 @@ export const Accordion = ({
|
|
|
28
30
|
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
29
31
|
|
|
30
32
|
return (
|
|
31
|
-
<div
|
|
33
|
+
<div
|
|
34
|
+
className={cn(
|
|
35
|
+
'flex flex-col border-l-2 border-neutral-100',
|
|
36
|
+
disabled ? 'opacity-50' : '',
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
32
41
|
<button
|
|
33
|
-
aria-expanded={isOpen}
|
|
34
|
-
aria-controls={contentId}
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
aria-expanded={disabled ? undefined : isOpen}
|
|
43
|
+
aria-controls={disabled ? undefined : contentId}
|
|
44
|
+
disabled={disabled}
|
|
45
|
+
className={cn(
|
|
46
|
+
`flex justify-between items-center px-2 py-1 bg-[#fefefefe] text-[color:#000000]
|
|
47
|
+
border-y-2 border-neutral-100`,
|
|
48
|
+
disabled ? 'cursor-not-allowed' : 'focus-yellow',
|
|
49
|
+
)}
|
|
37
50
|
id={buttonId}
|
|
38
|
-
onClick={() => setIsOpen(!isOpen)}
|
|
51
|
+
onClick={disabled ? undefined : () => setIsOpen(!isOpen)}
|
|
39
52
|
type="button"
|
|
40
53
|
>
|
|
41
54
|
<span>{title}</span>
|
|
@@ -45,14 +58,16 @@ export const Accordion = ({
|
|
|
45
58
|
</span>
|
|
46
59
|
</button>
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
{!disabled ? (
|
|
62
|
+
<section
|
|
63
|
+
id={contentId}
|
|
64
|
+
aria-labelledby={buttonId}
|
|
65
|
+
aria-hidden={!isOpen}
|
|
66
|
+
className={cn('p-2 bg-[#efefef]', isOpen ? 'block' : 'hidden')}
|
|
67
|
+
>
|
|
68
|
+
{children}
|
|
69
|
+
</section>
|
|
70
|
+
) : null}
|
|
56
71
|
</div>
|
|
57
72
|
);
|
|
58
73
|
};
|
package/src/map/MapComponent.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { memo, useEffect, useRef, useState } from 'react';
|
|
4
4
|
|
|
5
|
-
import { Map, Overlay, View } from 'ol';
|
|
5
|
+
import { Feature, Map, Overlay, View } from 'ol';
|
|
6
6
|
import { Attribution, ScaleLine, Zoom } from 'ol/control';
|
|
7
7
|
import { fromLonLat } from 'ol/proj';
|
|
8
8
|
|
|
@@ -11,7 +11,7 @@ import { FullScreenControl } from './FullScreenControl';
|
|
|
11
11
|
import { LayerSwitcherControl } from './LayerSwitcherControl';
|
|
12
12
|
import { useMap } from './MapContext';
|
|
13
13
|
import { Popup } from './Popup';
|
|
14
|
-
import { getPopupPositionClass } from './utils';
|
|
14
|
+
import { getPopupPositionClass, LAYER_NAMES } from './utils';
|
|
15
15
|
import type { PopupDirection } from '../types/map';
|
|
16
16
|
|
|
17
17
|
export type MapComponentProps = {
|
|
@@ -44,7 +44,7 @@ const arrowStyles: Record<PopupDirection, string> = {
|
|
|
44
44
|
* @return {*}
|
|
45
45
|
*/
|
|
46
46
|
const MapComponentBase = ({ osMapsApiKey, basePath }: MapComponentProps) => {
|
|
47
|
-
const [popupFeatures, setPopupFeatures] = useState([]);
|
|
47
|
+
const [popupFeatures, setPopupFeatures] = useState<Feature[]>([]);
|
|
48
48
|
const [popupCoordinate, setPopupCoordinate] = useState<number[] | null>(null);
|
|
49
49
|
const [popupPositionClass, setPopupPositionClass] = useState<PopupDirection>('bottom-right');
|
|
50
50
|
|
|
@@ -117,17 +117,41 @@ const MapComponentBase = ({ osMapsApiKey, basePath }: MapComponentProps) => {
|
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
newMap.forEachFeatureAtPixel(event.pixel, (feature) => {
|
|
121
|
-
const
|
|
120
|
+
newMap.forEachFeatureAtPixel(event.pixel, (feature, layer) => {
|
|
121
|
+
const clusterFeatures = feature.get('features');
|
|
122
|
+
const layerName = (layer as { get(k: string): unknown } | null)?.get('name');
|
|
122
123
|
|
|
123
|
-
if (
|
|
124
|
+
if (clusterFeatures?.length > 0) {
|
|
124
125
|
const coordinate = event.coordinate;
|
|
125
126
|
const direction = getPopupPositionClass(coordinate, newMap);
|
|
126
127
|
|
|
127
|
-
setPopupFeatures(
|
|
128
|
+
setPopupFeatures(clusterFeatures);
|
|
128
129
|
setPopupCoordinate(coordinate);
|
|
129
130
|
setPopupPositionClass(direction);
|
|
130
131
|
overlay.setPosition(event.coordinate);
|
|
132
|
+
|
|
133
|
+
return true; // stop iteration
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Direct feature (e.g. polygon) — only show popup for the sampling points
|
|
137
|
+
// layer, not boundary or AOI layers which may also have name properties.
|
|
138
|
+
if (layerName !== LAYER_NAMES.SamplingPoints) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const name = feature.get('name');
|
|
143
|
+
const notation = feature.get('notation');
|
|
144
|
+
|
|
145
|
+
if (name || notation) {
|
|
146
|
+
const coordinate = event.coordinate;
|
|
147
|
+
const direction = getPopupPositionClass(coordinate, newMap);
|
|
148
|
+
|
|
149
|
+
setPopupFeatures([feature as Feature]);
|
|
150
|
+
setPopupCoordinate(coordinate);
|
|
151
|
+
setPopupPositionClass(direction);
|
|
152
|
+
overlay.setPosition(event.coordinate);
|
|
153
|
+
|
|
154
|
+
return true; // stop iteration
|
|
131
155
|
}
|
|
132
156
|
});
|
|
133
157
|
});
|
package/src/map/Popup.tsx
CHANGED
|
@@ -41,13 +41,16 @@ export const Popup = ({
|
|
|
41
41
|
rounded-lg divide-y divide-gray-300"
|
|
42
42
|
>
|
|
43
43
|
{features.map((feature) => {
|
|
44
|
-
const id = feature.get('id');
|
|
45
44
|
const name = feature.get('name');
|
|
46
45
|
const notation = feature.get('notation');
|
|
47
|
-
const
|
|
46
|
+
const libraryNotation = feature.get('libraryNotation');
|
|
47
|
+
const identifier = notation ?? name;
|
|
48
|
+
const url = libraryNotation
|
|
49
|
+
? `${baseUrl}${libraryNotation}/${identifier}`
|
|
50
|
+
: `${baseUrl}${identifier}`;
|
|
48
51
|
|
|
49
52
|
return (
|
|
50
|
-
<div key={
|
|
53
|
+
<div key={identifier}>
|
|
51
54
|
<strong>
|
|
52
55
|
<ExternalLink
|
|
53
56
|
href={url}
|