@dative-gpi/foundation-shared-components 1.1.3-sandbox-1 → 1.1.4-groupings

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.
@@ -13,7 +13,7 @@
13
13
  <slot />
14
14
  </FSWrapGroup>
15
15
  <FSSlideGroup
16
- v-if="$props.variant === 'slide'"
16
+ v-else-if="$props.variant === 'slide'"
17
17
  v-bind="$attrs"
18
18
  >
19
19
  <FSChip
@@ -25,23 +25,106 @@
25
25
  />
26
26
  <slot />
27
27
  </FSSlideGroup>
28
+ <FSRow
29
+ v-else-if="$props.variant === 'menu'"
30
+ align="center-left"
31
+ width="hug"
32
+ :wrap="false"
33
+ v-bind="$attrs"
34
+ >
35
+ <component
36
+ v-if="hasSlots"
37
+ :is="slotElements[0]"
38
+ />
39
+ <FSChip
40
+ v-else
41
+ :variant="$props.chipVariant"
42
+ :color="$props.color"
43
+ :label="menuLabels[0]"
44
+ />
45
+ <FSMenu
46
+ v-if="slotElements.length > 1 || menuLabels.length > 1"
47
+ location="bottom end"
48
+ v-model="menuOpen"
49
+ >
50
+ <template
51
+ #activator="{ props: activatorProps }"
52
+ >
53
+ <FSChip
54
+ v-bind="activatorProps"
55
+ variant="full"
56
+ :label="`+${hasSlots ? (slotElements.length - 1) : (menuLabels.length - 1)}`"
57
+ :color="menuActivatorColor"
58
+ :clickable="true"
59
+ />
60
+ </template>
61
+ <FSCard
62
+ padding="16px 24px"
63
+ >
64
+ <template
65
+ #top-right
66
+ >
67
+ <FSButton
68
+ icon="mdi-close"
69
+ variant="icon"
70
+ iconSize="18px"
71
+ :color="ColorEnum.Dark"
72
+ @click="menuOpen = false"
73
+ />
74
+ </template>
75
+ <FSCol
76
+ v-if="hasSlots"
77
+ gap="12px"
78
+ >
79
+ <component
80
+ v-for="(element, index) in slotElements.slice(1)"
81
+ :key="index"
82
+ :is="element"
83
+ />
84
+ </FSCol>
85
+ <FSCol
86
+ v-else
87
+ gap="12px"
88
+ >
89
+ <FSChip
90
+ v-for="(label, index) in menuLabels"
91
+ :key="index"
92
+ :variant="$props.chipVariant"
93
+ :color="$props.color"
94
+ :label="label"
95
+ />
96
+ </FSCol>
97
+ </FSCard>
98
+ </FSMenu>
99
+ </FSRow>
28
100
  </template>
29
101
 
30
102
  <script lang="ts">
31
- import { defineComponent, type PropType } from "vue";
103
+ import { defineComponent, ref, type PropType, useSlots, computed, type VNode } from "vue";
32
104
 
33
105
  import { type CardVariant, CardVariants, type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
34
106
 
35
107
  import FSSlideGroup from "./FSSlideGroup.vue";
36
108
  import FSWrapGroup from "./FSWrapGroup.vue";
109
+ import FSButton from "./FSButton.vue";
37
110
  import FSChip from "./FSChip.vue";
111
+ import FSCard from "./FSCard.vue";
112
+ import FSMenu from "./FSMenu.vue";
113
+ import FSCol from "./FSCol.vue";
114
+ import FSRow from "./FSRow.vue";
115
+ import { useColors } from "../composables";
38
116
 
39
117
  export default defineComponent({
40
118
  name: "FSChipGroup",
41
119
  components: {
42
120
  FSSlideGroup,
43
121
  FSWrapGroup,
44
- FSChip
122
+ FSButton,
123
+ FSChip,
124
+ FSCard,
125
+ FSMenu,
126
+ FSCol,
127
+ FSRow
45
128
  },
46
129
  props: {
47
130
  labels: {
@@ -50,7 +133,7 @@ export default defineComponent({
50
133
  default: () => []
51
134
  },
52
135
  variant: {
53
- type: String as PropType<"wrap" | "slide">,
136
+ type: String as PropType<"wrap" | "slide" | "menu">,
54
137
  required: false,
55
138
  default: "wrap"
56
139
  },
@@ -64,6 +147,45 @@ export default defineComponent({
64
147
  required: false,
65
148
  default: ColorEnum.Light
66
149
  }
150
+ },
151
+ setup(props) {
152
+ const slots = useSlots();
153
+ const { getColors } = useColors();
154
+ const menuOpen = ref(false);
155
+
156
+ const slotElements = computed((): VNode[] => {
157
+ const defaultSlot = slots.default?.();
158
+ if (!defaultSlot) {
159
+ return [];
160
+ }
161
+ return defaultSlot.flatMap(node => {
162
+ if (node.type === Symbol.for('v-fgt')) {
163
+ return (node.children as VNode[]) ?? [];
164
+ }
165
+ return [node];
166
+ }).filter(node => typeof node.type !== 'symbol');
167
+ });
168
+
169
+ const hasSlots = computed((): boolean => {
170
+ return slotElements.value.length > 0;
171
+ });
172
+
173
+ const menuLabels = computed((): string[] => {
174
+ return props.labels ?? [];
175
+ });
176
+
177
+ const menuActivatorColor = computed((): string => {
178
+ return getColors(props.color).dark;
179
+ });
180
+
181
+ return {
182
+ menuActivatorColor,
183
+ slotElements,
184
+ menuLabels,
185
+ ColorEnum,
186
+ hasSlots,
187
+ menuOpen
188
+ };
67
189
  }
68
190
  });
69
191
  </script>
@@ -0,0 +1,116 @@
1
+ <template>
2
+ <FSChip
3
+ :height="$props.height"
4
+ :width="$props.width"
5
+ :variant="$props.variant"
6
+ :color="borderColor"
7
+ :disableHoverStyle="$props.disableHoverStyle"
8
+ >
9
+ <FSRow
10
+ align="center-center"
11
+ width="hug"
12
+ :wrap="false"
13
+ >
14
+ <FSRow
15
+ align="center-center"
16
+ width="hug"
17
+ gap="6px"
18
+ :wrap="false"
19
+ >
20
+ <FSIcon
21
+ :color="$props.iconColor"
22
+ :size="$props.iconSize"
23
+ >
24
+ {{ $props.icon }}
25
+ </FSIcon>
26
+ <FSText
27
+ font="text-overline"
28
+ :color="textColor"
29
+ >
30
+ {{ $props.label }}
31
+ </FSText>
32
+ </FSRow>
33
+ </FSRow>
34
+ </FSChip>
35
+ </template>
36
+
37
+ <script lang="ts">
38
+ import { defineComponent, type PropType } from "vue";
39
+
40
+ import { type CardVariant, CardVariants, type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
41
+
42
+ import FSIcon from "./FSIcon.vue";
43
+ import FSText from "./FSText.vue";
44
+ import FSChip from "./FSChip.vue";
45
+ import FSRow from "./FSRow.vue";
46
+
47
+ import { useColors } from "../composables";
48
+
49
+ export default defineComponent({
50
+ name: "FSSubgroupingChip",
51
+ components: {
52
+ FSChip,
53
+ FSIcon,
54
+ FSText,
55
+ FSRow
56
+ },
57
+ inheritAttrs: false,
58
+ props: {
59
+ label: {
60
+ type: String as PropType<string>,
61
+ required: true
62
+ },
63
+ icon: {
64
+ type: String as PropType<string>,
65
+ required: true
66
+ },
67
+ iconColor: {
68
+ type: String as PropType<ColorBase>,
69
+ required: false,
70
+ default: ColorEnum.Dark
71
+ },
72
+ height: {
73
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
74
+ required: false,
75
+ default: () => [24, 20]
76
+ },
77
+ width: {
78
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
79
+ required: false,
80
+ default: "hug"
81
+ },
82
+ color: {
83
+ type: String as PropType<ColorBase>,
84
+ required: false,
85
+ default: ColorEnum.Light
86
+ },
87
+ variant: {
88
+ type: String as PropType<CardVariant>,
89
+ required: false,
90
+ default: CardVariants.Background
91
+ },
92
+ iconSize: {
93
+ type: [Array, String, Number] as PropType<"s" | "m" | "l" | string[] | number[] | string | number | null>,
94
+ required: false,
95
+ default: "18px"
96
+ },
97
+ disableHoverStyle: {
98
+ type: Boolean,
99
+ required: false,
100
+ default: true
101
+ }
102
+ },
103
+ setup(props) {
104
+ const { getColors } = useColors();
105
+
106
+ const borderColor = getColors(props.color).dark;
107
+ const textColor = getColors(ColorEnum.Dark).dark;
108
+
109
+ return {
110
+ borderColor,
111
+ textColor,
112
+ ColorEnum
113
+ };
114
+ }
115
+ });
116
+ </script>
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <FSChip
3
+ :color="borderColor"
4
+ :width="$props.width"
5
+ :height="$props.height"
6
+ :variant="$props.variant"
7
+ :disableHoverStyle="$props.disableHoverStyle"
8
+ :title="`${$props.groupingLabel} - ${$props.label}`"
9
+ >
10
+ <FSRow
11
+ align="center-left"
12
+ width="fill"
13
+ :wrap="false"
14
+ >
15
+ <FSRow
16
+ align="center-center"
17
+ width="hug"
18
+ gap="6px"
19
+ :wrap="false"
20
+ >
21
+ <FSIcon
22
+ :color="$props.groupingColor"
23
+ :size="$props.iconSize"
24
+ >
25
+ {{ $props.groupingIcon }}
26
+ </FSIcon>
27
+ <FSSpan
28
+ font="text-overline"
29
+ >
30
+ {{ $props.groupingLabel }}
31
+ </FSSpan>
32
+ </FSRow>
33
+ <FSRow
34
+ align="center-center"
35
+ width="hug"
36
+ gap="6px"
37
+ :wrap="false"
38
+ >
39
+ <FSIcon
40
+ :size="$props.iconSize"
41
+ >
42
+ {{ $props.icon }}
43
+ </FSIcon>
44
+ <FSSpan
45
+ font="text-overline"
46
+ >
47
+ {{ $props.label }}
48
+ </FSSpan>
49
+ </FSRow>
50
+ </FSRow>
51
+ </FSChip>
52
+ </template>
53
+
54
+ <script lang="ts">
55
+ import { defineComponent, type PropType } from "vue";
56
+
57
+ import { type CardVariant, CardVariants, type ColorBase, ColorEnum } from "@dative-gpi/foundation-shared-components/models";
58
+
59
+ import FSIcon from "./FSIcon.vue";
60
+ import FSSpan from "./FSSpan.vue";
61
+ import FSChip from "./FSChip.vue";
62
+ import FSRow from "./FSRow.vue";
63
+
64
+ import { useColors } from "../composables";
65
+
66
+ export default defineComponent({
67
+ name: "FSSubgroupingChip",
68
+ components: {
69
+ FSChip,
70
+ FSIcon,
71
+ FSSpan,
72
+ FSRow
73
+ },
74
+ props: {
75
+ groupingLabel: {
76
+ type: String as PropType<string>,
77
+ required: true
78
+ },
79
+ groupingIcon: {
80
+ type: String as PropType<string>,
81
+ required: true
82
+ },
83
+ groupingColor: {
84
+ type: String as PropType<ColorBase>,
85
+ required: false,
86
+ default: ColorEnum.Dark
87
+ },
88
+ label: {
89
+ type: String as PropType<string>,
90
+ required: true
91
+ },
92
+ icon: {
93
+ type: String as PropType<string>,
94
+ required: true
95
+ },
96
+ height: {
97
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
98
+ required: false,
99
+ default: () => [24, 20]
100
+ },
101
+ width: {
102
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
103
+ required: false,
104
+ default: "hug"
105
+ },
106
+ variant: {
107
+ type: String as PropType<CardVariant>,
108
+ required: false,
109
+ default: CardVariants.Background
110
+ },
111
+ color: {
112
+ type: String as PropType<ColorBase>,
113
+ required: false,
114
+ default: ColorEnum.Light
115
+ },
116
+ iconSize: {
117
+ type: [Array, String, Number] as PropType<"s" | "m" | "l" | string[] | number[] | string | number | null>,
118
+ required: false,
119
+ default: "18px"
120
+ },
121
+ disableHoverStyle: {
122
+ type: Boolean,
123
+ required: false,
124
+ default: true
125
+ }
126
+ },
127
+ setup(props) {
128
+ const { getColors } = useColors();
129
+
130
+ const borderColor = getColors(props.color).dark;
131
+
132
+ return {
133
+ borderColor,
134
+ ColorEnum
135
+ };
136
+ }
137
+ });
138
+ </script>
@@ -97,6 +97,14 @@
97
97
  :filters="filters[header.value]"
98
98
  @update:filter="(value) => toggleFilter(header.value, value)"
99
99
  >
100
+ <template
101
+ #custom="{ filter, toggle, variant }"
102
+ >
103
+ <slot
104
+ :name="`${filterSlot(header)}-custom`"
105
+ v-bind="{ filter, toggle, variant }"
106
+ />
107
+ </template>
100
108
  <template
101
109
  #default="{ filter }"
102
110
  >
@@ -57,27 +57,35 @@
57
57
  <FSCol
58
58
  gap="6px"
59
59
  >
60
- <FSChip
60
+ <template
61
61
  v-for="(filter, index) in searchedFilters"
62
- class="fs-filter-button-chip"
63
- :variant="getVariant(filter)"
64
- :height="['30px', '24px']"
65
- :color="$props.color"
66
- :label="filter.text"
67
- align="center-left"
68
- :clickable="true"
69
- :border="false"
70
62
  :key="index"
71
- @click="() => onToggle(filter)"
72
63
  >
73
- <template
74
- #default
64
+ <slot
65
+ name="custom"
66
+ v-bind="{ filter, toggle: () => onToggle(filter), variant: getVariant(filter) }"
75
67
  >
76
- <slot
77
- v-bind="{ filter }"
78
- />
79
- </template>
80
- </FSChip>
68
+ <FSChip
69
+ class="fs-filter-button-chip"
70
+ :variant="getVariant(filter)"
71
+ :height="['30px', '24px']"
72
+ :color="$props.color"
73
+ :label="filter.text"
74
+ align="center-left"
75
+ :clickable="true"
76
+ :border="false"
77
+ @click="() => onToggle(filter)"
78
+ >
79
+ <template
80
+ #default
81
+ >
82
+ <slot
83
+ v-bind="{ filter }"
84
+ />
85
+ </template>
86
+ </FSChip>
87
+ </slot>
88
+ </template>
81
89
  </FSCol>
82
90
  </FSFadeOut>
83
91
  </FSCol>
@@ -48,30 +48,26 @@ 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
55
51
  }
56
52
  },
57
53
  emits: ['click', 'auxclick'],
58
54
  setup(props, { emit }) {
59
55
  const map = inject<Ref<Map | null>>(MAP);
60
56
  const markerClusterGroup = inject<Ref<MarkerClusterGroup | null>>(MARKERCLUSTERGROUP, ref(null));
61
-
57
+
62
58
  const { getColors } = useColors();
63
59
  const { handleRoutingEvent } = useRouting();
64
60
 
65
- if (!map) {
61
+ if(!map) {
66
62
  throw new Error('FSMapTileLayer must be used inside a FSMap component');
67
63
  }
68
64
 
69
- if (!map.value) {
65
+ if(!map.value) {
70
66
  throw new Error('FSMapTileLayer must be used inside a FSMap component with a map');
71
67
  }
72
-
68
+
73
69
  const getMarkerIcon = () => {
74
- if (props.variant === 'gps') {
70
+ if(props.variant === 'gps') {
75
71
  const size = 16;
76
72
  return divIcon({
77
73
  html: gpsMarkerHtml(),
@@ -81,7 +77,7 @@ export default {
81
77
  });
82
78
  }
83
79
 
84
- if (props.variant === 'location') {
80
+ if(props.variant === 'location') {
85
81
  const size = 36;
86
82
  return divIcon({
87
83
  html: locationMarkerHtml(props.icon ?? "mdi-map-marker", getColors(props.color).base, props.label),
@@ -93,7 +89,7 @@ export default {
93
89
 
94
90
  const size = 16;
95
91
  return divIcon({
96
- html: props.html ?? pinMarkerHtml(getColors(props.color).base, props.label),
92
+ html: pinMarkerHtml(getColors(props.color).base, props.label),
97
93
  iconSize: [size, size],
98
94
  className: props.selected ? 'fs-map-marker fs-map-pin fs-map-pin-selected' : 'fs-map-marker fs-map-pin',
99
95
  iconAnchor: [size / 2, size / 2],
@@ -107,11 +103,11 @@ export default {
107
103
  });
108
104
 
109
105
  const onClick = (event: MouseEvent) => {
110
- if (props.to) {
106
+ if(props.to) {
111
107
  handleRoutingEvent(event, props.to, true);
112
108
  return;
113
109
  }
114
-
110
+
115
111
  emit('click', {
116
112
  ...event,
117
113
  latlng: props.latlng
@@ -119,7 +115,7 @@ export default {
119
115
  }
120
116
 
121
117
  const onAuxClick = (event: MouseEvent) => {
122
- if (props.to) {
118
+ if(props.to) {
123
119
  handleRoutingEvent(event, props.to);
124
120
  return;
125
121
  }
@@ -131,19 +127,19 @@ export default {
131
127
  }
132
128
 
133
129
  watch(map, () => {
134
- if (!map.value) {
130
+ if(!map.value) {
135
131
  return;
136
132
  }
137
133
 
138
- if (markerClusterGroup && markerClusterGroup.value) {
134
+ if(markerClusterGroup && markerClusterGroup.value) {
139
135
  actualMarker.value.addTo(markerClusterGroup.value);
140
136
  } else {
141
137
  actualMarker.value.addTo(map.value);
142
138
  }
143
139
  }, { immediate: true });
144
140
 
145
- watch([() => props.variant, () => props.color, () => props.selected, () => props.html], () => {
146
- if (!actualMarker.value || !map.value) {
141
+ watch([() => props.variant, () => props.color, () => props.selected], () => {
142
+ if(!actualMarker.value || !map.value) {
147
143
  return;
148
144
  }
149
145
 
@@ -152,7 +148,7 @@ export default {
152
148
  });
153
149
 
154
150
  watch([() => props.latlng?.lat, () => props.latlng?.lng], () => {
155
- if (!actualMarker.value || !map.value || !props.latlng) {
151
+ if(!actualMarker.value || !map.value || !props.latlng) {
156
152
  return;
157
153
  }
158
154
 
@@ -160,7 +156,7 @@ export default {
160
156
  });
161
157
 
162
158
  watch(markerElement, (newMarkerElement) => {
163
- if (!newMarkerElement) {
159
+ if(!newMarkerElement) {
164
160
  return;
165
161
  }
166
162
 
@@ -169,8 +165,8 @@ export default {
169
165
  }, { immediate: true });
170
166
 
171
167
  onUnmounted(() => {
172
- if (actualMarker.value && map.value) {
173
- if (markerClusterGroup && markerClusterGroup.value) {
168
+ if(actualMarker.value && map.value) {
169
+ if(markerClusterGroup && markerClusterGroup.value) {
174
170
  markerClusterGroup.value.removeLayer(actualMarker.value as Marker);
175
171
  } else {
176
172
  map.value.removeLayer(actualMarker.value as Marker);
@@ -0,0 +1,45 @@
1
+ <template>
2
+ <FSSimpleTileUI
3
+ :bottomColor="null"
4
+ v-bind="$attrs"
5
+ >
6
+ <template
7
+ #append-info
8
+ >
9
+ <FSEntityCountBadge
10
+ :label="$tr('ui.common.equipments', 'Équipements')"
11
+ :count="$props.deviceOrganisationsCount ?? 0"
12
+ :color="ColorEnum.Primary"
13
+ />
14
+ </template>
15
+ </FSSimpleTileUI>
16
+ </template>
17
+
18
+ <script lang="ts">
19
+ import { defineComponent } from "vue";
20
+
21
+ import { ColorEnum } from "@dative-gpi/foundation-shared-components/models";
22
+
23
+ import FSEntityCountBadge from "./FSEntityCountBadge.vue";
24
+ import FSSimpleTileUI from './FSSimpleTileUI.vue';
25
+
26
+ export default defineComponent({
27
+ name: "FSSubgroupingTileUI",
28
+ components: {
29
+ FSSimpleTileUI,
30
+ FSEntityCountBadge
31
+ },
32
+ props: {
33
+ deviceOrganisationsCount: {
34
+ type: Number,
35
+ required: false,
36
+ default: null
37
+ }
38
+ },
39
+ setup() {
40
+ return {
41
+ ColorEnum,
42
+ };
43
+ }
44
+ });
45
+ </script>
@@ -5,10 +5,8 @@ export * from "./useBreakpoints";
5
5
  export * from "./useColors";
6
6
  export * from "./useCountUp";
7
7
  export * from "./useDebounce";
8
- export * from "./useDynamicVNode";
9
8
  export * from "./useElementVisibility";
10
9
  export * from "./useMapLayers";
11
- export * from "./useResize";
12
10
  export * from "./useRules";
13
11
  export * from "./useSlots";
14
12
  export * from "./useTables";
package/models/tables.ts CHANGED
@@ -26,6 +26,7 @@ export interface FSDataTableFilter {
26
26
  text: string;
27
27
  value: string;
28
28
  hidden: boolean;
29
+ custom?: boolean;
29
30
  filter?: ((value: any, property: any, item: any) => boolean) | null;
30
31
  }
31
32
 
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.3-sandbox-1",
7
+ "version": "1.1.4-groupings",
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.3-sandbox-1",
17
- "@dative-gpi/foundation-shared-services": "1.1.3-sandbox-1"
16
+ "@dative-gpi/foundation-shared-domain": "1.1.4-groupings",
17
+ "@dative-gpi/foundation-shared-services": "1.1.4-groupings"
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": "8857dc338d7d3ec5f09ce9f67b0b359ae25e8e40"
41
+ "gitHead": "36d137728515912523b1090f52d6cf9f56974e21"
42
42
  }
@@ -1,5 +1,10 @@
1
1
  .fs-filter-button-menu {
2
- width: 300px;
2
+ max-width: 400px;
3
+ overflow: hidden;
4
+ }
5
+
6
+ .fs-filter-button-menu * {
7
+ min-width: 0;
3
8
  }
4
9
 
5
10
  .fs-filter-button-chip {
@@ -1,62 +0,0 @@
1
- import { h, render, getCurrentInstance, onBeforeUnmount, type Component, type VNode } from "vue";
2
-
3
- export function useDynamicVNode<TProps extends Record<string, any>>(component: Component<TProps>) {
4
-
5
- let vnode: VNode | null = null;
6
- let container: HTMLElement | null = null;
7
- let mountPoint: HTMLElement | null = null;
8
-
9
- const instance = getCurrentInstance();
10
- if (!instance) {
11
- throw new Error("useDynamicVNode must be used inside setup()");
12
- }
13
-
14
- const appContext = instance.appContext;
15
-
16
- const mount = async (props: TProps) => {
17
- if (!mountPoint) {
18
- throw new Error(`You must call getElement() first to create the mount point`);
19
- }
20
-
21
- if (!container) {
22
- container = document.createElement("div");
23
- mountPoint.appendChild(container);
24
- }
25
-
26
- vnode = h(component, props);
27
- vnode.appContext = appContext;
28
-
29
- render(vnode, container);
30
- };
31
-
32
- const unmount = () => {
33
- if (container) {
34
- render(null, container);
35
- container.remove();
36
- }
37
- vnode = null;
38
- container = null;
39
- };
40
-
41
- const getElement = (style?: Partial<CSSStyleDeclaration>): HTMLElement => {
42
- if (!mountPoint) {
43
- mountPoint = document.createElement("div");
44
- }
45
- mountPoint = document.createElement("div");
46
- Object.assign(mountPoint.style, style ?? {});
47
- return mountPoint;
48
- };
49
-
50
- const destroy = () => {
51
- unmount();
52
- mountPoint = null;
53
- };
54
-
55
- onBeforeUnmount(destroy);
56
-
57
- return {
58
- mount,
59
- unmount,
60
- getElement
61
- };
62
- }
@@ -1,32 +0,0 @@
1
- import { onMounted, onBeforeUnmount } from 'vue';
2
-
3
- export function useResize(
4
- getElement: () => HTMLElement | null | undefined,
5
- onResize: () => void
6
- ) {
7
- let resizeObserver: ResizeObserver | null = null;
8
-
9
- onMounted(() => {
10
- if (typeof ResizeObserver !== 'undefined') {
11
- resizeObserver = new ResizeObserver(() => {
12
- onResize();
13
- });
14
- const element = getElement();
15
- if (element) {
16
- resizeObserver.observe(element);
17
- }
18
- }
19
-
20
- window.addEventListener('resize', onResize);
21
- });
22
-
23
- onBeforeUnmount(() => {
24
- window.removeEventListener('resize', onResize);
25
- resizeObserver?.disconnect();
26
- resizeObserver = null;
27
- });
28
-
29
- return {
30
- resize: onResize
31
- };
32
- }