@smartnet360/svelte-components 0.0.70 → 0.0.72
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/dist/map-v2/demo/DemoMap.svelte +29 -1
- package/dist/map-v2/demo/demo-repeaters.d.ts +13 -0
- package/dist/map-v2/demo/demo-repeaters.js +74 -0
- package/dist/map-v2/features/cells/layers/CellLabelsLayer.svelte +9 -8
- package/dist/map-v2/features/repeaters/constants/radiusMultipliers.d.ts +26 -0
- package/dist/map-v2/features/repeaters/constants/radiusMultipliers.js +40 -0
- package/dist/map-v2/features/repeaters/constants/techBandZOrder.d.ts +25 -0
- package/dist/map-v2/features/repeaters/constants/techBandZOrder.js +43 -0
- package/dist/map-v2/features/repeaters/constants/zIndex.d.ts +11 -0
- package/dist/map-v2/features/repeaters/constants/zIndex.js +11 -0
- package/dist/map-v2/features/repeaters/controls/RepeaterFilterControl.svelte +172 -0
- package/dist/map-v2/features/repeaters/controls/RepeaterFilterControl.svelte.d.ts +18 -0
- package/dist/map-v2/features/repeaters/index.d.ts +13 -0
- package/dist/map-v2/features/repeaters/index.js +16 -0
- package/dist/map-v2/features/repeaters/layers/RepeaterLabelsLayer.svelte +301 -0
- package/dist/map-v2/features/repeaters/layers/RepeaterLabelsLayer.svelte.d.ts +10 -0
- package/dist/map-v2/features/repeaters/layers/RepeatersLayer.svelte +259 -0
- package/dist/map-v2/features/repeaters/layers/RepeatersLayer.svelte.d.ts +10 -0
- package/dist/map-v2/features/repeaters/stores/repeaterStoreContext.svelte.d.ts +69 -0
- package/dist/map-v2/features/repeaters/stores/repeaterStoreContext.svelte.js +222 -0
- package/dist/map-v2/features/repeaters/types.d.ts +59 -0
- package/dist/map-v2/features/repeaters/types.js +4 -0
- package/dist/map-v2/features/repeaters/utils/repeaterGeoJSON.d.ts +20 -0
- package/dist/map-v2/features/repeaters/utils/repeaterGeoJSON.js +90 -0
- package/dist/map-v2/features/repeaters/utils/repeaterTree.d.ts +23 -0
- package/dist/map-v2/features/repeaters/utils/repeaterTree.js +111 -0
- package/dist/map-v2/shared/controls/FeatureSettingsControl.svelte +27 -21
- package/dist/map-v2/shared/controls/FeatureSettingsControl.svelte.d.ts +3 -0
- package/dist/map-v2/shared/controls/panels/RepeaterSettingsPanel.svelte +280 -5
- package/dist/map-v2/shared/controls/panels/RepeaterSettingsPanel.svelte.d.ts +17 -16
- package/package.json +1 -1
|
@@ -1,19 +1,294 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/**
|
|
3
3
|
* RepeaterSettingsPanel - Repeater visualization settings
|
|
4
|
-
*
|
|
4
|
+
*
|
|
5
|
+
* Provides controls for:
|
|
6
|
+
* - Base radius (arc size)
|
|
7
|
+
* - Fill opacity
|
|
8
|
+
* - Line width
|
|
9
|
+
* - Show labels checkbox
|
|
10
|
+
* - Label field selection
|
|
11
|
+
* - Label size, color, and offset
|
|
5
12
|
*/
|
|
13
|
+
import type { RepeaterStoreContext } from '../../../features/repeaters/stores/repeaterStoreContext.svelte';
|
|
14
|
+
import type { Repeater } from '../../../features/repeaters/types';
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
/** Repeater store context */
|
|
18
|
+
store: RepeaterStoreContext;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let { store }: Props = $props();
|
|
22
|
+
|
|
23
|
+
// Available label fields for repeaters
|
|
24
|
+
const labelFieldOptions: Array<keyof Repeater> = [
|
|
25
|
+
'repeaterId',
|
|
26
|
+
'donorCellId',
|
|
27
|
+
'donorCellName',
|
|
28
|
+
'tech',
|
|
29
|
+
'fband',
|
|
30
|
+
'azimuth',
|
|
31
|
+
'height',
|
|
32
|
+
'factory_nbr',
|
|
33
|
+
'provider',
|
|
34
|
+
'featureGroup'
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
// Human-readable labels for fields
|
|
38
|
+
function getFieldLabel(field: keyof Repeater | 'none'): string {
|
|
39
|
+
const labels: Record<string, string> = {
|
|
40
|
+
repeaterId: 'Repeater ID',
|
|
41
|
+
donorCellId: 'Donor Cell ID',
|
|
42
|
+
donorCellName: 'Donor Cell Name',
|
|
43
|
+
tech: 'Technology',
|
|
44
|
+
fband: 'Frequency Band',
|
|
45
|
+
azimuth: 'Azimuth',
|
|
46
|
+
height: 'Height',
|
|
47
|
+
factory_nbr: 'Factory Number',
|
|
48
|
+
provider: 'Provider',
|
|
49
|
+
featureGroup: 'Feature Group',
|
|
50
|
+
none: 'None'
|
|
51
|
+
};
|
|
52
|
+
return labels[field] || String(field);
|
|
53
|
+
}
|
|
6
54
|
</script>
|
|
7
55
|
|
|
8
56
|
<div class="settings-panel">
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
57
|
+
|
|
58
|
+
<!-- Base radius slider -->
|
|
59
|
+
<div class="control-row">
|
|
60
|
+
<label for="repeater-radius-slider" class="control-label">
|
|
61
|
+
Base Radius: <strong>{store.baseRadius}m</strong>
|
|
62
|
+
</label>
|
|
63
|
+
<input
|
|
64
|
+
id="repeater-radius-slider"
|
|
65
|
+
type="range"
|
|
66
|
+
class="form-range"
|
|
67
|
+
min="100"
|
|
68
|
+
max="2000"
|
|
69
|
+
step="50"
|
|
70
|
+
value={store.baseRadius}
|
|
71
|
+
oninput={(e) => store.setBaseRadius(Number(e.currentTarget.value))}
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<!-- Line width slider -->
|
|
76
|
+
<div class="control-row">
|
|
77
|
+
<label for="repeater-line-width-slider" class="control-label">
|
|
78
|
+
Line Width: <strong>{store.lineWidth}px</strong>
|
|
79
|
+
</label>
|
|
80
|
+
<input
|
|
81
|
+
id="repeater-line-width-slider"
|
|
82
|
+
type="range"
|
|
83
|
+
class="form-range"
|
|
84
|
+
min="1"
|
|
85
|
+
max="5"
|
|
86
|
+
step="0.5"
|
|
87
|
+
value={store.lineWidth}
|
|
88
|
+
oninput={(e) => store.setLineWidth(Number(e.currentTarget.value))}
|
|
89
|
+
/>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<!-- Fill opacity slider -->
|
|
93
|
+
<div class="control-row">
|
|
94
|
+
<label for="repeater-opacity-slider" class="control-label">
|
|
95
|
+
Fill Opacity: <strong>{Math.round(store.fillOpacity * 100)}%</strong>
|
|
96
|
+
</label>
|
|
97
|
+
<input
|
|
98
|
+
id="repeater-opacity-slider"
|
|
99
|
+
type="range"
|
|
100
|
+
class="form-range"
|
|
101
|
+
min="0"
|
|
102
|
+
max="1"
|
|
103
|
+
step="0.1"
|
|
104
|
+
value={store.fillOpacity}
|
|
105
|
+
oninput={(e) => store.setFillOpacity(Number(e.currentTarget.value))}
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<!-- Repeater Labels Section -->
|
|
110
|
+
<hr class="section-divider" />
|
|
111
|
+
|
|
112
|
+
<!-- Show labels toggle -->
|
|
113
|
+
<div class="control-row">
|
|
114
|
+
<label for="repeater-labels-toggle" class="control-label">
|
|
115
|
+
Show Labels
|
|
116
|
+
</label>
|
|
117
|
+
<div class="form-check form-switch">
|
|
118
|
+
<input
|
|
119
|
+
id="repeater-labels-toggle"
|
|
120
|
+
type="checkbox"
|
|
121
|
+
class="form-check-input"
|
|
122
|
+
role="switch"
|
|
123
|
+
checked={store.showLabels}
|
|
124
|
+
onchange={(e) => store.setShowLabels(e.currentTarget.checked)}
|
|
125
|
+
/>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
{#if store.showLabels}
|
|
130
|
+
<!-- Primary Label Field -->
|
|
131
|
+
<div class="control-row">
|
|
132
|
+
<label for="repeater-label-primary" class="control-label">
|
|
133
|
+
Primary Field
|
|
134
|
+
</label>
|
|
135
|
+
<select
|
|
136
|
+
id="repeater-label-primary"
|
|
137
|
+
class="form-select form-select-sm"
|
|
138
|
+
value={store.primaryLabelField}
|
|
139
|
+
onchange={(e) => store.setPrimaryLabelField(e.currentTarget.value as keyof Repeater)}
|
|
140
|
+
>
|
|
141
|
+
{#each labelFieldOptions as field}
|
|
142
|
+
<option value={field}>{getFieldLabel(field)}</option>
|
|
143
|
+
{/each}
|
|
144
|
+
</select>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<!-- Secondary Label Field -->
|
|
148
|
+
<div class="control-row">
|
|
149
|
+
<label for="repeater-label-secondary" class="control-label">
|
|
150
|
+
Secondary Field
|
|
151
|
+
</label>
|
|
152
|
+
<select
|
|
153
|
+
id="repeater-label-secondary"
|
|
154
|
+
class="form-select form-select-sm"
|
|
155
|
+
value={store.secondaryLabelField}
|
|
156
|
+
onchange={(e) => store.setSecondaryLabelField(e.currentTarget.value as keyof Repeater | 'none')}
|
|
157
|
+
>
|
|
158
|
+
<option value="none">None</option>
|
|
159
|
+
{#each labelFieldOptions as field}
|
|
160
|
+
<option value={field}>{getFieldLabel(field)}</option>
|
|
161
|
+
{/each}
|
|
162
|
+
</select>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
<!-- Label Size -->
|
|
166
|
+
<div class="control-row">
|
|
167
|
+
<label for="repeater-label-size-slider" class="control-label">
|
|
168
|
+
Label Size: <strong>{store.labelSize}px</strong>
|
|
169
|
+
</label>
|
|
170
|
+
<input
|
|
171
|
+
id="repeater-label-size-slider"
|
|
172
|
+
type="range"
|
|
173
|
+
class="form-range"
|
|
174
|
+
min="8"
|
|
175
|
+
max="20"
|
|
176
|
+
step="1"
|
|
177
|
+
value={store.labelSize}
|
|
178
|
+
oninput={(e) => store.setLabelSize(Number(e.currentTarget.value))}
|
|
179
|
+
/>
|
|
180
|
+
</div>
|
|
181
|
+
|
|
182
|
+
<!-- Label Color -->
|
|
183
|
+
<div class="control-row">
|
|
184
|
+
<label for="repeater-label-color-picker" class="control-label">
|
|
185
|
+
Label Color
|
|
186
|
+
</label>
|
|
187
|
+
<input
|
|
188
|
+
id="repeater-label-color-picker"
|
|
189
|
+
type="color"
|
|
190
|
+
class="form-control form-control-color"
|
|
191
|
+
value={store.labelColor}
|
|
192
|
+
oninput={(e) => store.setLabelColor(e.currentTarget.value)}
|
|
193
|
+
/>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<!-- Label Offset -->
|
|
197
|
+
<div class="control-row">
|
|
198
|
+
<label for="repeater-label-offset-slider" class="control-label">
|
|
199
|
+
Label Offset: <strong>{store.labelOffset}%</strong>
|
|
200
|
+
</label>
|
|
201
|
+
<input
|
|
202
|
+
id="repeater-label-offset-slider"
|
|
203
|
+
type="range"
|
|
204
|
+
class="form-range"
|
|
205
|
+
min="0"
|
|
206
|
+
max="500"
|
|
207
|
+
step="25"
|
|
208
|
+
value={store.labelOffset}
|
|
209
|
+
oninput={(e) => store.setLabelOffset(Number(e.currentTarget.value))}
|
|
210
|
+
/>
|
|
211
|
+
</div>
|
|
212
|
+
|
|
213
|
+
<!-- Min Label Zoom -->
|
|
214
|
+
<div class="control-row">
|
|
215
|
+
<label for="repeater-min-zoom-slider" class="control-label">
|
|
216
|
+
Min Zoom: <strong>{store.minLabelZoom}</strong>
|
|
217
|
+
</label>
|
|
218
|
+
<input
|
|
219
|
+
id="repeater-min-zoom-slider"
|
|
220
|
+
type="range"
|
|
221
|
+
class="form-range"
|
|
222
|
+
min="0"
|
|
223
|
+
max="18"
|
|
224
|
+
step="1"
|
|
225
|
+
value={store.minLabelZoom}
|
|
226
|
+
oninput={(e) => store.setMinLabelZoom(Number(e.currentTarget.value))}
|
|
227
|
+
/>
|
|
228
|
+
</div>
|
|
229
|
+
{/if}
|
|
12
230
|
</div>
|
|
13
231
|
|
|
14
232
|
<style>
|
|
15
233
|
.settings-panel {
|
|
16
234
|
width: 100%;
|
|
17
|
-
|
|
235
|
+
display: flex;
|
|
236
|
+
flex-direction: column;
|
|
237
|
+
gap: 0.75rem;
|
|
238
|
+
padding: 0.5rem 0;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.control-row {
|
|
242
|
+
display: flex;
|
|
243
|
+
align-items: center;
|
|
244
|
+
gap: 0.5rem;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.control-label {
|
|
248
|
+
flex: 0 0 auto;
|
|
249
|
+
min-width: 120px;
|
|
250
|
+
font-size: 0.875rem;
|
|
251
|
+
margin: 0;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.form-range {
|
|
255
|
+
flex: 1;
|
|
256
|
+
min-width: 140px;
|
|
257
|
+
max-width: 140px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.form-select {
|
|
261
|
+
flex: 1;
|
|
262
|
+
min-width: 140px;
|
|
263
|
+
max-width: 140px;
|
|
264
|
+
font-size: 0.875rem;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.form-control-color {
|
|
268
|
+
flex: 0 0 auto;
|
|
269
|
+
width: 40px;
|
|
270
|
+
height: 32px;
|
|
271
|
+
padding: 2px;
|
|
272
|
+
border-radius: 4px;
|
|
273
|
+
cursor: pointer;
|
|
274
|
+
margin-right: auto;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.form-check {
|
|
278
|
+
flex: 0 0 auto;
|
|
279
|
+
margin: 0;
|
|
280
|
+
margin-right: auto;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.form-check-input {
|
|
284
|
+
cursor: pointer;
|
|
285
|
+
width: 40px;
|
|
286
|
+
height: 20px;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.section-divider {
|
|
290
|
+
margin: 0.5rem 0;
|
|
291
|
+
border-color: var(--bs-border-color);
|
|
292
|
+
opacity: 0.5;
|
|
18
293
|
}
|
|
19
294
|
</style>
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
/**
|
|
2
|
+
* RepeaterSettingsPanel - Repeater visualization settings
|
|
3
|
+
*
|
|
4
|
+
* Provides controls for:
|
|
5
|
+
* - Base radius (arc size)
|
|
6
|
+
* - Fill opacity
|
|
7
|
+
* - Line width
|
|
8
|
+
* - Show labels checkbox
|
|
9
|
+
* - Label field selection
|
|
10
|
+
* - Label size, color, and offset
|
|
11
|
+
*/
|
|
12
|
+
import type { RepeaterStoreContext } from '../../../features/repeaters/stores/repeaterStoreContext.svelte';
|
|
13
|
+
interface Props {
|
|
14
|
+
/** Repeater store context */
|
|
15
|
+
store: RepeaterStoreContext;
|
|
13
16
|
}
|
|
14
|
-
declare const RepeaterSettingsPanel:
|
|
15
|
-
|
|
16
|
-
}, {}, {}, string>;
|
|
17
|
-
type RepeaterSettingsPanel = InstanceType<typeof RepeaterSettingsPanel>;
|
|
17
|
+
declare const RepeaterSettingsPanel: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type RepeaterSettingsPanel = ReturnType<typeof RepeaterSettingsPanel>;
|
|
18
19
|
export default RepeaterSettingsPanel;
|