@dative-gpi/foundation-shared-components 1.1.8 → 1.1.9-sandbox-2

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.
@@ -48,26 +48,30 @@ export default {
48
48
  to: {
49
49
  type: Object as PropType<RouteLocation | null>,
50
50
  required: false
51
+ },
52
+ html: {
53
+ type: [String, HTMLElement] as PropType<string | HTMLElement>,
54
+ required: false
51
55
  }
52
56
  },
53
57
  emits: ['click', 'auxclick'],
54
58
  setup(props, { emit }) {
55
59
  const map = inject<Ref<Map | null>>(MAP);
56
60
  const markerClusterGroup = inject<Ref<MarkerClusterGroup | null>>(MARKERCLUSTERGROUP, ref(null));
57
-
61
+
58
62
  const { getColors } = useColors();
59
63
  const { handleRoutingEvent } = useRouting();
60
64
 
61
- if(!map) {
65
+ if (!map) {
62
66
  throw new Error('FSMapTileLayer must be used inside a FSMap component');
63
67
  }
64
68
 
65
- if(!map.value) {
69
+ if (!map.value) {
66
70
  throw new Error('FSMapTileLayer must be used inside a FSMap component with a map');
67
71
  }
68
-
72
+
69
73
  const getMarkerIcon = () => {
70
- if(props.variant === 'gps') {
74
+ if (props.variant === 'gps') {
71
75
  const size = 16;
72
76
  return divIcon({
73
77
  html: gpsMarkerHtml(),
@@ -77,7 +81,7 @@ export default {
77
81
  });
78
82
  }
79
83
 
80
- if(props.variant === 'location') {
84
+ if (props.variant === 'location') {
81
85
  const size = 36;
82
86
  return divIcon({
83
87
  html: locationMarkerHtml(props.icon ?? "mdi-map-marker", getColors(props.color).base, props.label),
@@ -89,7 +93,7 @@ export default {
89
93
 
90
94
  const size = 16;
91
95
  return divIcon({
92
- html: pinMarkerHtml(getColors(props.color).base, props.label),
96
+ html: props.html ?? pinMarkerHtml(getColors(props.color).base, props.label),
93
97
  iconSize: [size, size],
94
98
  className: props.selected ? 'fs-map-marker fs-map-pin fs-map-pin-selected' : 'fs-map-marker fs-map-pin',
95
99
  iconAnchor: [size / 2, size / 2],
@@ -103,11 +107,11 @@ export default {
103
107
  });
104
108
 
105
109
  const onClick = (event: MouseEvent) => {
106
- if(props.to) {
110
+ if (props.to) {
107
111
  handleRoutingEvent(event, props.to, true);
108
112
  return;
109
113
  }
110
-
114
+
111
115
  emit('click', {
112
116
  ...event,
113
117
  latlng: props.latlng
@@ -115,7 +119,7 @@ export default {
115
119
  }
116
120
 
117
121
  const onAuxClick = (event: MouseEvent) => {
118
- if(props.to) {
122
+ if (props.to) {
119
123
  handleRoutingEvent(event, props.to);
120
124
  return;
121
125
  }
@@ -127,19 +131,19 @@ export default {
127
131
  }
128
132
 
129
133
  watch(map, () => {
130
- if(!map.value) {
134
+ if (!map.value) {
131
135
  return;
132
136
  }
133
137
 
134
- if(markerClusterGroup && markerClusterGroup.value) {
138
+ if (markerClusterGroup && markerClusterGroup.value) {
135
139
  actualMarker.value.addTo(markerClusterGroup.value);
136
140
  } else {
137
141
  actualMarker.value.addTo(map.value);
138
142
  }
139
143
  }, { immediate: true });
140
144
 
141
- watch([() => props.variant, () => props.color, () => props.selected], () => {
142
- if(!actualMarker.value || !map.value) {
145
+ watch([() => props.variant, () => props.color, () => props.selected, () => props.html], () => {
146
+ if (!actualMarker.value || !map.value) {
143
147
  return;
144
148
  }
145
149
 
@@ -148,7 +152,7 @@ export default {
148
152
  });
149
153
 
150
154
  watch([() => props.latlng?.lat, () => props.latlng?.lng], () => {
151
- if(!actualMarker.value || !map.value || !props.latlng) {
155
+ if (!actualMarker.value || !map.value || !props.latlng) {
152
156
  return;
153
157
  }
154
158
 
@@ -156,7 +160,7 @@ export default {
156
160
  });
157
161
 
158
162
  watch(markerElement, (newMarkerElement) => {
159
- if(!newMarkerElement) {
163
+ if (!newMarkerElement) {
160
164
  return;
161
165
  }
162
166
 
@@ -165,8 +169,8 @@ export default {
165
169
  }, { immediate: true });
166
170
 
167
171
  onUnmounted(() => {
168
- if(actualMarker.value && map.value) {
169
- if(markerClusterGroup && markerClusterGroup.value) {
172
+ if (actualMarker.value && map.value) {
173
+ if (markerClusterGroup && markerClusterGroup.value) {
170
174
  markerClusterGroup.value.removeLayer(actualMarker.value as Marker);
171
175
  } else {
172
176
  map.value.removeLayer(actualMarker.value as Marker);
@@ -5,8 +5,10 @@ export * from "./useBreakpoints";
5
5
  export * from "./useColors";
6
6
  export * from "./useCountUp";
7
7
  export * from "./useDebounce";
8
+ export * from "./useDomRenderer";
8
9
  export * from "./useElementVisibility";
9
10
  export * from "./useMapLayers";
11
+ export * from "./useResize";
10
12
  export * from "./useRules";
11
13
  export * from "./useSlots";
12
14
  export * from "./useTables";
@@ -0,0 +1,83 @@
1
+ import { h, render, getCurrentInstance, onBeforeUnmount, toValue, type Component, type MaybeRefOrGetter, watch } from "vue";
2
+
3
+ interface RenderHandle {
4
+ unsubscribe: () => void;
5
+ getElement: (style?: Partial<CSSStyleDeclaration>) => HTMLElement;
6
+ }
7
+
8
+ interface Subscription {
9
+ container: HTMLElement;
10
+ mountPoint: HTMLElement;
11
+ stopWatching: () => void;
12
+ }
13
+
14
+ function destroySubscription(subscription: Subscription) {
15
+ subscription.stopWatching();
16
+ render(null, subscription.container);
17
+ subscription.container.remove();
18
+ subscription.mountPoint.remove();
19
+ }
20
+
21
+ export function useDomRenderer<TProps extends Record<string, any>>(component: Component<TProps>) {
22
+
23
+ const instance = getCurrentInstance();
24
+ if (!instance) {
25
+ throw new Error("useDomRenderer must be used inside setup()");
26
+ }
27
+
28
+ const appContext = instance.appContext;
29
+ const subscriptions = new Set<Subscription>();
30
+
31
+ const subscribe = (getProps: MaybeRefOrGetter<TProps>, style?: Partial<CSSStyleDeclaration>): RenderHandle => {
32
+ const mountPoint = document.createElement("div");
33
+
34
+ const container = document.createElement("div");
35
+ mountPoint.appendChild(container);
36
+
37
+ const stopWatching = watch(
38
+ getProps,
39
+ () => {
40
+ const vnode = h(component, toValue(getProps));
41
+ vnode.appContext = appContext;
42
+ render(vnode, container);
43
+ },
44
+ { immediate: true }
45
+ );
46
+
47
+ const subscription: Subscription = { container, mountPoint, stopWatching };
48
+ subscriptions.add(subscription);
49
+
50
+ const unsubscribe = () => {
51
+ if (!subscriptions.has(subscription)) {
52
+ return;
53
+ }
54
+ destroySubscription(subscription);
55
+ subscriptions.delete(subscription);
56
+ };
57
+
58
+ const getElement = (newStyle?: Partial<CSSStyleDeclaration>): HTMLElement => {
59
+ if (!subscriptions.has(subscription)) {
60
+ throw new Error("This render handle has already been unsubscribed");
61
+ }
62
+ mountPoint.style.cssText = "";
63
+ Object.assign(mountPoint.style, style ?? {}, newStyle ?? {});
64
+ return mountPoint;
65
+ };
66
+
67
+ return { unsubscribe, getElement };
68
+ };
69
+
70
+ const unsubscribeAll = () => {
71
+ for (const subscription of subscriptions) {
72
+ destroySubscription(subscription);
73
+ }
74
+ subscriptions.clear();
75
+ };
76
+
77
+ onBeforeUnmount(unsubscribeAll);
78
+
79
+ return {
80
+ subscribe,
81
+ unsubscribeAll,
82
+ };
83
+ }
@@ -0,0 +1,28 @@
1
+ import { watch } from 'vue';
2
+
3
+ export function useResize(
4
+ getElement: () => HTMLElement | null | undefined,
5
+ onResize: () => void
6
+ ) {
7
+ let resizeObserver: ResizeObserver | null = null;
8
+
9
+ watch(
10
+ () => getElement(),
11
+ (newElement, _, onCleanup) => {
12
+ if (newElement && typeof ResizeObserver !== 'undefined') {
13
+ resizeObserver = new ResizeObserver(() => {
14
+ onResize();
15
+ });
16
+ resizeObserver.observe(newElement);
17
+
18
+ onCleanup(() => {
19
+ resizeObserver?.disconnect();
20
+ resizeObserver = null;
21
+ });
22
+ }
23
+ },
24
+ { immediate: true }
25
+ );
26
+
27
+ return {};
28
+ }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "url": "https://github.com/Dative-GPI/foundation-shared-ui.git"
5
5
  },
6
6
  "sideEffects": false,
7
- "version": "1.1.8",
7
+ "version": "1.1.9-sandbox-2",
8
8
  "description": "",
9
9
  "publishConfig": {
10
10
  "access": "public"
@@ -13,8 +13,8 @@
13
13
  "author": "",
14
14
  "license": "ISC",
15
15
  "dependencies": {
16
- "@dative-gpi/foundation-shared-domain": "1.1.8",
17
- "@dative-gpi/foundation-shared-services": "1.1.8"
16
+ "@dative-gpi/foundation-shared-domain": "1.1.9-sandbox-2",
17
+ "@dative-gpi/foundation-shared-services": "1.1.9-sandbox-2"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "@dative-gpi/bones-ui": "^1.0.0",
@@ -38,5 +38,5 @@
38
38
  "sass": "1.71.1",
39
39
  "sass-loader": "13.3.2"
40
40
  },
41
- "gitHead": "d3acfab8c634278f1fe3794747580d0b00f10d0a"
41
+ "gitHead": "a26ae1e0964030d75000054d021c1d45feadb98e"
42
42
  }