Skip to content

Commit c965a29

Browse files
ajrothwellclaude
andcommitted
fix lint: unused var and missing prop defaults
Remove unused props assignment in LayerOpacitySlider. Add explicit undefined defaults for optional props across all components to satisfy vue/require-default-prop rule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 69bd5e6 commit c965a29

File tree

9 files changed

+91
-81
lines changed

9 files changed

+91
-81
lines changed

README.md

Lines changed: 47 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ pnpm add vue pinia maplibre-gl @fortawesome/fontawesome-svg-core @fortawesome/fr
2323

2424
```vue
2525
<template>
26-
<Layerboard
27-
title="My Map App"
28-
web-map-id="1596df70df0349e293ceec46a06ccc50"
29-
/>
26+
<Layerboard title="My Map App" web-map-id="1596df70df0349e293ceec46a06ccc50" />
3027
</template>
3128
3229
<script setup>
@@ -48,11 +45,7 @@ All layers in a searchable list. Set `show-default-sidebar` to `true` (default)
4845
Group layers into collapsible accordions using the sidebar slot:
4946

5047
```vue
51-
<Layerboard
52-
title="StreetSmartPHL"
53-
:web-map-id="webMapId"
54-
:show-default-sidebar="false"
55-
>
48+
<Layerboard title="StreetSmartPHL" :web-map-id="webMapId" :show-default-sidebar="false">
5649
<template #sidebar="{ layers, visibleLayers, toggleLayer, setOpacity }">
5750
<TopicAccordion title="Paving" :expanded="true">
5851
<LayerCheckboxSet
@@ -68,56 +61,56 @@ Group layers into collapsible accordions using the sidebar slot:
6861

6962
## Props
7063

71-
| Prop | Type | Default | Description |
72-
|------|------|---------|-------------|
73-
| `title` | `string` | *required* | App title in header |
74-
| `webMapId` | `string` | *required* | ArcGIS Online WebMap ID |
75-
| `subtitle` | `string` || Subtitle in header |
76-
| `themeColor` | `string` | `"#0f4d90"` | Header/footer background color |
77-
| `showDefaultSidebar` | `boolean` | `true` | Show built-in LayerPanel (false for custom sidebar) |
78-
| `sidebarWidth` | `string` | `"30%"` | Sidebar width (CSS units) |
79-
| `sidebarLabel` | `string` | `"Layers"` | Mobile toggle label for sidebar view |
80-
| `mapLabel` | `string` | `"Map"` | Mobile toggle label for map view |
81-
| `fetchMetadata` | `boolean` | `false` | Fetch layer metadata from Carto |
82-
| `tiledLayers` | `TiledLayerConfig[]` | `[]` | ESRI MapServer tiled layers |
83-
| `dataSources` | `DataSourceConfig[]` | `[]` | External API data sources |
84-
| `layerStyleOverrides` | `Record<string, LayerStyleOverride>` | `{}` | Override paint/legend per layer |
85-
| `popupOverrides` | `Record<string, PopupOverride>` | `{}` | Override popup behavior per layer |
86-
| `initialZoom` | `number` || Initial map zoom level |
87-
| `initialCenter` | `[number, number]` || Initial map center `[lng, lat]` |
88-
| `cyclomediaConfig` | `CyclomediaConfig` || Cyclomedia street-level imagery config |
89-
| `pictometryCredentials` | `PictometryCredentials` || Pictometry oblique imagery credentials |
64+
| Prop | Type | Default | Description |
65+
| ----------------------- | ------------------------------------ | ----------- | --------------------------------------------------- |
66+
| `title` | `string` | _required_ | App title in header |
67+
| `webMapId` | `string` | _required_ | ArcGIS Online WebMap ID |
68+
| `subtitle` | `string` | | Subtitle in header |
69+
| `themeColor` | `string` | `"#0f4d90"` | Header/footer background color |
70+
| `showDefaultSidebar` | `boolean` | `true` | Show built-in LayerPanel (false for custom sidebar) |
71+
| `sidebarWidth` | `string` | `"30%"` | Sidebar width (CSS units) |
72+
| `sidebarLabel` | `string` | `"Layers"` | Mobile toggle label for sidebar view |
73+
| `mapLabel` | `string` | `"Map"` | Mobile toggle label for map view |
74+
| `fetchMetadata` | `boolean` | `false` | Fetch layer metadata from Carto |
75+
| `tiledLayers` | `TiledLayerConfig[]` | `[]` | ESRI MapServer tiled layers |
76+
| `dataSources` | `DataSourceConfig[]` | `[]` | External API data sources |
77+
| `layerStyleOverrides` | `Record<string, LayerStyleOverride>` | `{}` | Override paint/legend per layer |
78+
| `popupOverrides` | `Record<string, PopupOverride>` | `{}` | Override popup behavior per layer |
79+
| `initialZoom` | `number` | | Initial map zoom level |
80+
| `initialCenter` | `[number, number]` | | Initial map center `[lng, lat]` |
81+
| `cyclomediaConfig` | `CyclomediaConfig` | | Cyclomedia street-level imagery config |
82+
| `pictometryCredentials` | `PictometryCredentials` | | Pictometry oblique imagery credentials |
9083

9184
### Control Positions
9285

9386
All default to sensible positions. Each accepts `"top-left" | "top-right" | "bottom-left" | "bottom-right"`.
9487

95-
| Prop | Default |
96-
|------|---------|
97-
| `basemapControlPosition` | `"top-right"` |
98-
| `navigationControlPosition` | `"bottom-right"` |
99-
| `geolocationControlPosition` | `"bottom-right"` |
100-
| `searchControlPosition` | `"top-left"` |
101-
| `drawControlPosition` | `"bottom-left"` (or `null` to remove) |
102-
| `cyclomediaButtonPosition` | `"top-right"` |
103-
| `pictometryButtonPosition` | `"top-right"` |
88+
| Prop | Default |
89+
| ---------------------------- | ------------------------------------- |
90+
| `basemapControlPosition` | `"top-right"` |
91+
| `navigationControlPosition` | `"bottom-right"` |
92+
| `geolocationControlPosition` | `"bottom-right"` |
93+
| `searchControlPosition` | `"top-left"` |
94+
| `drawControlPosition` | `"bottom-left"` (or `null` to remove) |
95+
| `cyclomediaButtonPosition` | `"top-right"` |
96+
| `pictometryButtonPosition` | `"top-right"` |
10497

10598
## Events
10699

107-
| Event | Payload | Description |
108-
|-------|---------|-------------|
100+
| Event | Payload | Description |
101+
| ---------------- | --------------- | -------------------------------- |
109102
| `configs-loaded` | `LayerConfig[]` | Layer configs loaded from WebMap |
110-
| `load-error` | `string` | Error message on load failure |
111-
| `zoom` | `number` | Zoom level changed |
103+
| `load-error` | `string` | Error message on load failure |
104+
| `zoom` | `number` | Zoom level changed |
112105

113106
## Slots
114107

115-
| Slot | Scope | Description |
116-
|------|-------|-------------|
117-
| `header` || Replace default header |
118-
| `sidebar` | layer state + methods (see below) | Replace default LayerPanel |
119-
| `footer` | `{ openModal, closeModal, isModalOpen }` | Custom footer content |
120-
| `modal` | `{ closeModal }` | Modal content |
108+
| Slot | Scope | Description |
109+
| --------- | ---------------------------------------- | -------------------------- |
110+
| `header` | | Replace default header |
111+
| `sidebar` | layer state + methods (see below) | Replace default LayerPanel |
112+
| `footer` | `{ openModal, closeModal, isModalOpen }` | Custom footer content |
113+
| `modal` | `{ closeModal }` | Modal content |
121114

122115
### Sidebar Slot Scope
123116

@@ -156,11 +149,11 @@ All components are exported for building custom layouts:
156149

157150
```typescript
158151
import {
159-
Layerboard, // Main framework component
160-
LayerPanel, // Flat layer list with search/legends/opacity
161-
MapPanel, // MapLibre map with layer rendering
162-
TopicAccordion, // Collapsible accordion for topic grouping
163-
LayerCheckboxSet, // Checkbox controls for layer toggling
152+
Layerboard, // Main framework component
153+
LayerPanel, // Flat layer list with search/legends/opacity
154+
MapPanel, // MapLibre map with layer rendering
155+
TopicAccordion, // Collapsible accordion for topic grouping
156+
LayerCheckboxSet, // Checkbox controls for layer toggling
164157
LayerRadioButtonSet, // Radio buttons for mutually exclusive layers
165158
} from "@phila/layerboard";
166159
```
@@ -184,8 +177,8 @@ import type {
184177
LayerboardConfig,
185178
TopicConfig,
186179
FeatureFlags,
187-
CyclomediaConfig, // re-exported from @phila/phila-ui-map-core
188-
PictometryCredentials, // re-exported from @phila/phila-ui-map-core
180+
CyclomediaConfig, // re-exported from @phila/phila-ui-map-core
181+
PictometryCredentials, // re-exported from @phila/phila-ui-map-core
189182
} from "@phila/layerboard";
190183
```
191184

src/components/LayerCheckboxSet.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const props = withDefaults(
4343
currentZoom: 12,
4444
showOpacity: true,
4545
showLegend: true,
46+
groupLabel: undefined,
4647
},
4748
);
4849
@@ -53,13 +54,13 @@ const emit = defineEmits<{
5354
(e: "setOpacity", layerId: string, opacity: number): void;
5455
}>();
5556
56-
const { isVisible, getLayerOpacity, isLayerLoading, getLayerError, isLayerAvailableAtZoom } = useLayerState(() => props);
57+
const { isVisible, getLayerOpacity, isLayerLoading, getLayerError, isLayerAvailableAtZoom } = useLayerState(
58+
() => props,
59+
);
5760
5861
function onToggleLayer(layerId: string) {
5962
emit("toggleLayer", layerId);
6063
}
61-
62-
6364
</script>
6465

6566
<template>
@@ -118,7 +119,12 @@ function onToggleLayer(layerId: string) {
118119
/>
119120

120121
<LayerLegend
121-
v-if="shouldShowLegendBox(layer, showLegend) && isVisible(layer.id) && isLayerAvailableAtZoom(layer) && layer.legend?.length"
122+
v-if="
123+
shouldShowLegendBox(layer, showLegend) &&
124+
isVisible(layer.id) &&
125+
isLayerAvailableAtZoom(layer) &&
126+
layer.legend?.length
127+
"
122128
:items="layer.legend"
123129
:label="'Legend for ' + getLayerDisplayName(layer)"
124130
/>

src/components/LayerOpacitySlider.vue

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
const props = defineProps<{
2+
defineProps<{
33
layerId: string;
44
layerName: string;
55
opacity: number;
@@ -17,9 +17,7 @@ function onInput(event: Event) {
1717

1818
<template>
1919
<div class="opacity-control">
20-
<label class="opacity-label" :for="'opacity-' + layerId">
21-
Opacity: {{ Math.round(opacity * 100) }}%
22-
</label>
20+
<label class="opacity-label" :for="'opacity-' + layerId"> Opacity: {{ Math.round(opacity * 100) }}% </label>
2321
<input
2422
:id="'opacity-' + layerId"
2523
type="range"

src/components/LayerPanel.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ const searchValue = computed({
9797
function onToggleLayer(layerId: string) {
9898
emit("toggleLayer", layerId);
9999
}
100-
101-
102100
</script>
103101

104102
<template>
@@ -173,7 +171,12 @@ function onToggleLayer(layerId: string) {
173171
/>
174172

175173
<LayerLegend
176-
v-if="showLegend && isVisible(layer.config.id) && isLayerAvailableAtZoom(layer.config) && layer.config.legend?.length"
174+
v-if="
175+
showLegend &&
176+
isVisible(layer.config.id) &&
177+
isLayerAvailableAtZoom(layer.config) &&
178+
layer.config.legend?.length
179+
"
177180
:items="layer.config.legend"
178181
:label="'Legend for ' + layer.config.title"
179182
/>

src/components/LayerRadioButtonSet.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const props = withDefaults(
4545
showOpacity: true,
4646
showLegend: true,
4747
groupName: "layer-radio-group",
48+
groupLabel: undefined,
4849
},
4950
);
5051
@@ -55,15 +56,15 @@ const emit = defineEmits<{
5556
(e: "setOpacity", layerId: string, opacity: number): void;
5657
}>();
5758
58-
const { isVisible, getLayerOpacity, isLayerLoading, getLayerError, isLayerAvailableAtZoom } = useLayerState(() => props);
59+
const { isVisible, getLayerOpacity, isLayerLoading, getLayerError, isLayerAvailableAtZoom } = useLayerState(
60+
() => props,
61+
);
5962
6063
function onSelectLayer(layerId: string) {
6164
// Find all currently visible layers in this set to turn off
6265
const previousLayerIds = props.layers.filter(l => props.visibleLayerIds.has(l.id) && l.id !== layerId).map(l => l.id);
6366
emit("selectLayer", layerId, previousLayerIds);
6467
}
65-
66-
6768
</script>
6869

6970
<template>
@@ -103,7 +104,12 @@ function onSelectLayer(layerId: string) {
103104
/>
104105

105106
<LayerLegend
106-
v-if="shouldShowLegendBox(layer, showLegend) && isVisible(layer.id) && isLayerAvailableAtZoom(layer) && layer.legend?.length"
107+
v-if="
108+
shouldShowLegendBox(layer, showLegend) &&
109+
isVisible(layer.id) &&
110+
isLayerAvailableAtZoom(layer) &&
111+
layer.legend?.length
112+
"
107113
:items="layer.legend"
108114
:label="'Legend for ' + getLayerDisplayName(layer)"
109115
/>

src/components/LayerStatusIndicators.vue

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@ defineProps<{
88

99
<template>
1010
<span v-if="loading && !unavailable" class="loading-indicator" role="status"> Loading... </span>
11-
<span
12-
v-if="error"
13-
class="error-indicator"
14-
:aria-label="error"
15-
role="status"
16-
>
17-
Error
18-
</span>
11+
<span v-if="error" class="error-indicator" :aria-label="error" role="status"> Error </span>
1912
<span v-if="unavailable" class="zoom-indicator"> (zoom in) </span>
2013
</template>
2114

src/components/Layerboard.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ const props = withDefaults(
8989
initialCenter?: [number, number];
9090
}>(),
9191
{
92+
subtitle: undefined,
93+
cyclomediaConfig: undefined,
94+
pictometryCredentials: undefined,
95+
initialZoom: undefined,
96+
initialCenter: undefined,
9297
themeColor: "#0f4d90",
9398
showDefaultSidebar: true,
9499
sidebarWidth: "30%",

src/components/MapPanel.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ const props = withDefaults(
5151
initialCenter?: [number, number];
5252
}>(),
5353
{
54+
tiledLayers: undefined,
55+
visibleTiledLayers: undefined,
56+
tiledLayerOpacities: undefined,
57+
cyclomediaConfig: undefined,
58+
pictometryCredentials: undefined,
59+
initialZoom: undefined,
60+
initialCenter: undefined,
5461
basemapControlPosition: "top-right",
5562
navigationControlPosition: "bottom-right",
5663
geolocationControlPosition: "bottom-right",
@@ -147,10 +154,7 @@ async function fetchFeaturesInBounds(
147154
148155
// Ask the server to simplify geometries before sending
149156
// Tolerance is ~1 pixel at the current zoom: detail increases as you zoom in
150-
const simplifyParam =
151-
zoom !== undefined
152-
? `&maxAllowableOffset=${360 / (Math.pow(2, zoom) * 512)}`
153-
: "";
157+
const simplifyParam = zoom !== undefined ? `&maxAllowableOffset=${360 / (Math.pow(2, zoom) * 512)}` : "";
154158
155159
const pageSize = 2000;
156160
let offset = 0;

src/components/TopicAccordion.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const props = withDefaults(
1818
headerClass?: string;
1919
}>(),
2020
{
21+
icon: undefined,
22+
headerClass: undefined,
2123
expanded: false,
2224
layerIds: () => [],
2325
},

0 commit comments

Comments
 (0)