map-gl-style-switcher 0.5.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Muhammad Imran Siddique
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,343 @@
1
+ # Map GL Style Switcher
2
+
3
+ [![npm version](https://badge.fury.io/js/map-gl-style-switcher.svg)](https://badge.fury.io/js/map-gl-style-switcher)
4
+ [![CI](https://github.com/muimsd/map-gl-style-switcher/actions/workflows/ci.yml/badge.svg)](https://github.com/muimsd/map-gl-style-switcher/actions/workflows/ci.yml)
5
+
6
+ <!-- [![Coverage Status](https://codecov.io/gh/muimsd/map-gl-style-switcher/branch/main/graph/badge.svg)](https://codecov.io/gh/muimsd/map-gl-style-switcher) -->
7
+
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ A TypeScript control for switching Mapbox GL / MapLibre GL map styles. Easily add a floating style switcher to your map app, with support for multiple styles, images, dark/light themes, and before/after change callbacks.
11
+
12
+ **[🌐 Live Demo](https://map-gl-style-switcher.netlify.app/)**
13
+
14
+ ## Demo
15
+
16
+ ![Demo GIF](./images/demo.gif)
17
+
18
+ *Live demo of the style switcher control in action*
19
+
20
+ ## Features
21
+
22
+ - IControl implementation for Mapbox GL / MapLibre GL
23
+ - Floating style switcher in any corner (via map.addControl position)
24
+ - Support for multiple map styles with thumbnails
25
+ - Expand/collapse on hover with smooth animations
26
+ - Dark/light/auto theme support
27
+ - RTL text support for Arabic scripts
28
+ - Configurable display options (show/hide labels and images)
29
+ - Callbacks for before/after style change
30
+ - Fully customizable CSS classes
31
+ - TypeScript support
32
+ - Accessibility features (ARIA labels, keyboard navigation)
33
+
34
+ ## Install
35
+
36
+ ```sh
37
+ # Using npm (recommended)
38
+ npm install map-gl-style-switcher
39
+
40
+ # Using yarn
41
+ yarn add map-gl-style-switcher
42
+
43
+ # Using pnpm
44
+ pnpm add map-gl-style-switcher
45
+ ```
46
+
47
+ ## Usage
48
+
49
+ ### Basic MapLibre GL Integration
50
+
51
+ ```ts
52
+ import maplibregl from 'maplibre-gl';
53
+ import { StyleSwitcherControl } from 'map-gl-style-switcher';
54
+ import 'map-gl-style-switcher/dist/map-gl-style-switcher.css';
55
+
56
+ // Define styles
57
+ const styles = [
58
+ {
59
+ id: 'basic',
60
+ name: 'Basic',
61
+ image: 'path/to/thumbnail.png',
62
+ styleUrl: 'https://demotiles.maplibre.org/style.json',
63
+ },
64
+ {
65
+ id: 'satellite',
66
+ name: 'Satellite',
67
+ image: 'path/to/satellite-thumb.png',
68
+ styleUrl: 'https://your-satellite-style.json',
69
+ },
70
+ // ... more styles
71
+ ];
72
+ const defaultStyle = styles[0];
73
+ // Create map
74
+ const map = new maplibregl.Map({
75
+ container: 'map',
76
+ style: defaultStyle.styleUrl,
77
+ center: [0, 0],
78
+ zoom: 2,
79
+ });
80
+
81
+ // Add style switcher control
82
+ const styleSwitcher = new StyleSwitcherControl({
83
+ styles: styles,
84
+ theme: 'light', // 'light', 'dark', or 'auto'
85
+ showLabels: true,
86
+ showImages: true,
87
+ activeStyleId: defaultStyle.id,
88
+ onBeforeStyleChange: (from, to) => {
89
+ console.log(`Switching from ${from.name} to ${to.name}`);
90
+ },
91
+ onAfterStyleChange: (from, to) => {
92
+ map.setStyle(to.styleUrl);
93
+ },
94
+ });
95
+
96
+ map.addControl(styleSwitcher, 'bottom-left');
97
+ ```
98
+ ## Available Styles
99
+
100
+ ![Available Styles](./images/styles.png)
101
+
102
+ ## Configuration Options
103
+
104
+ ```ts
105
+ interface StyleSwitcherControlOptions {
106
+ styles: StyleItem[]; // Array of map styles (required)
107
+ activeStyleId?: string; // Currently active style ID (default: first style)
108
+ onBeforeStyleChange?: (from: StyleItem, to: StyleItem) => void; // Callback before style change
109
+ onAfterStyleChange?: (from: StyleItem, to: StyleItem) => void; // Callback after style change
110
+ showLabels?: boolean; // Show style names (default: true)
111
+ showImages?: boolean; // Show style thumbnails (default: true)
112
+ animationDuration?: number; // Animation duration in ms (default: 200)
113
+ maxHeight?: number; // Max height of expanded list (default: 300)
114
+ theme?: 'light' | 'dark' | 'auto'; // UI theme (default: 'light')
115
+ classNames?: Partial<StyleSwitcherClassNames>; // Custom CSS classes
116
+ rtl?: boolean; // Enable RTL layout (default: false)
117
+ }
118
+
119
+ interface StyleItem {
120
+ id: string; // Unique identifier
121
+ name: string; // Display name
122
+ image: string; // Thumbnail URL or data URI
123
+ styleUrl: string; // MapLibre/Mapbox style URL
124
+ description?: string; // Optional tooltip text
125
+ }
126
+
127
+ interface StyleSwitcherClassNames {
128
+ container: string; // Main container class
129
+ list: string; // Expanded list container class
130
+ item: string; // Individual style item class
131
+ itemSelected: string; // Selected style item class
132
+ itemHideLabel: string; // Hide label utility class
133
+ dark: string; // Dark theme class
134
+ light: string; // Light theme class
135
+ }
136
+ ```
137
+
138
+ *Example of different map styles that can be used with the style switcher*
139
+
140
+ ### Option Details
141
+
142
+ - **`activeStyleId`**: Controls both the initially selected style and what's displayed in the collapsed state
143
+ - **`showLabels`** & **`showImages`**: At least one must be `true`
144
+ - **`theme`**:
145
+ - `'light'`: Light color scheme
146
+ - `'dark'`: Dark color scheme
147
+ - `'auto'`: Auto-detect from system preference
148
+ - **`rtl`**: Enables right-to-left layout for Arabic/Hebrew interfaces
149
+
150
+ ## Customizing CSS Classes
151
+
152
+ You can override all CSS classes used by the style switcher control using the `classNames` option:
153
+
154
+ ```ts
155
+ import { StyleSwitcherControl } from 'map-gl-style-switcher';
156
+
157
+ const styleSwitcher = new StyleSwitcherControl({
158
+ styles,
159
+ showLabels: true,
160
+ showImages: true,
161
+ classNames: {
162
+ container: 'my-style-switcher',
163
+ list: 'my-style-list',
164
+ item: 'my-style-item',
165
+ itemSelected: 'my-style-item-selected',
166
+ itemHideLabel: 'my-style-item-hide-label',
167
+ dark: 'my-style-dark',
168
+ light: 'my-style-light',
169
+ },
170
+ });
171
+ ```
172
+
173
+ See the default class names in the `StyleSwitcherControl` source for all available keys.
174
+
175
+ ## File Structure
176
+
177
+ ```
178
+ map-gl-style-switcher/
179
+ ├── src/
180
+ │ ├── components/
181
+ │ │ └── StyleSwitcherControl.ts # Main IControl implementation
182
+ │ ├── styles/
183
+ │ │ └── style-switcher.css # Control styles (themes, RTL support)
184
+ │ ├── types/
185
+ │ │ ├── index.ts # TypeScript type definitions
186
+ │ │ └── css.d.ts # CSS module declarations
187
+ │ ├── tests/
188
+ │ │ ├── StyleSwitcherControl.test.ts # Test suite
189
+ │ │ └── test-setup.ts # Jest test setup
190
+ │ ├── demo/
191
+ │ │ ├── main.tsx # Demo entry point
192
+ │ │ ├── App.tsx # Demo component
193
+ │ │ └── index.css # Demo-specific styles
194
+ │ └── index.ts # Package entry point
195
+ ├── dist/ # Built package output
196
+ │ ├── index.js # ES Module
197
+ │ ├── index.umd.js # UMD Module
198
+ │ ├── index.d.ts # TypeScript declarations
199
+ │ └── map-gl-style-switcher.css # Bundled CSS
200
+ ├── package.json # Package configuration
201
+ ├── rollup.config.js # Production build configuration
202
+ ├── vite.config.ts # Development build configuration
203
+ ├── jest.config.js # Test configuration
204
+ ├── tsconfig.json # TypeScript configuration
205
+ └── README.md # Documentation
206
+ ```
207
+
208
+ ## Development
209
+
210
+ This project uses npm for dependency management.
211
+
212
+ ### Prerequisites
213
+
214
+ ```sh
215
+ # Ensure you have Node.js 16+ and npm 8+ installed
216
+ node --version
217
+ npm --version
218
+ ```
219
+
220
+ ### Quick Start
221
+
222
+ ```sh
223
+ # Install dependencies
224
+ npm install
225
+
226
+ # Start development server
227
+ npm run dev
228
+
229
+ # Build for production
230
+ npm run build
231
+
232
+ # Run tests
233
+ npm test
234
+
235
+ # Lint and format code
236
+ npm run lint
237
+ npm run format
238
+
239
+ # Validate before publishing
240
+ npm run validate
241
+ ```
242
+
243
+ ## Build for npm
244
+
245
+ The project uses Rollup for optimized production builds, generating:
246
+
247
+ - `dist/index.js` - ES module format
248
+ - `dist/index.umd.js` - UMD format for browser usage
249
+ - `dist/index.d.ts` - TypeScript declarations
250
+ - `dist/map-gl-style-switcher.css` - Minified CSS styles
251
+
252
+ ```sh
253
+ # Standard build
254
+ npm run build
255
+
256
+ # Production build with full validation
257
+ npm run build:prod
258
+ ```
259
+
260
+ ## Contributing
261
+
262
+ We welcome contributions! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
263
+
264
+ ### Development Setup
265
+
266
+ 1. **Clone the repository**
267
+
268
+ ```sh
269
+ git clone https://github.com/muimsd/map-gl-style-switcher
270
+ cd map-gl-style-switcher
271
+ ```
272
+
273
+ 2. **Install dependencies**
274
+
275
+ ```sh
276
+ npm install
277
+ ```
278
+
279
+ 3. **Start development server**
280
+
281
+ ```sh
282
+ npm run dev
283
+ ```
284
+
285
+ 4. **Make your changes**
286
+
287
+ - Follow TypeScript best practices
288
+ - Maintain backward compatibility when possible
289
+ - Add tests for new features
290
+
291
+ 5. **Test your changes**
292
+
293
+ ```sh
294
+ npm run validate # Runs type-check, lint, format-check, and tests
295
+ ```
296
+
297
+ 6. **Submit a pull request**
298
+
299
+ ### Available Scripts
300
+
301
+ - `npm run dev` - Start development server with hot reload
302
+ - `npm run build` - Build library with Rollup (ES modules, UMD, TypeScript declarations, and CSS)
303
+ - `npm run build:prod` - Production build with validation (type-check, lint, and build)
304
+ - `npm run build:watch` - Build in watch mode with Rollup
305
+ - `npm test` - Run tests
306
+ - `npm run test:watch` - Run tests in watch mode
307
+ - `npm run test:coverage` - Run tests with coverage
308
+ - `npm run lint` - Lint code
309
+ - `npm run lint:fix` - Lint and auto-fix issues
310
+ - `npm run format` - Format code with Prettier
311
+ - `npm run format:check` - Check code formatting
312
+ - `npm run validate` - Run all validation checks
313
+ - `npm run type-check` - Type check TypeScript
314
+ - `npm run clean` - Clean build artifacts
315
+
316
+ ### Guidelines
317
+
318
+ - Use npm for dependency management
319
+ - Follow TypeScript best practices
320
+ - Maintain backward compatibility when possible
321
+ - Add tests for new features
322
+ - Update documentation as needed
323
+ - Follow the existing code style
324
+ - Ensure all checks pass: `npm run validate`
325
+
326
+ ## License
327
+
328
+ MIT License - see [LICENSE](LICENSE) file for details.
329
+
330
+ ## Author
331
+
332
+ **Muhammad Imran Siddique**
333
+
334
+ - GitHub: [@muimsd](https://github.com/muimsd)
335
+
336
+ ## Repository
337
+
338
+ - GitHub: [https://github.com/muimsd/map-gl-style-switcher](https://github.com/muimsd/map-gl-style-switcher)
339
+ - Issues: [https://github.com/muimsd/map-gl-style-switcher/issues](https://github.com/muimsd/map-gl-style-switcher/issues)
340
+
341
+ ---
342
+
343
+ Made with ❤️ for the MapLibre GL and Mapbox GL community
@@ -0,0 +1,52 @@
1
+ type MapInstance = any;
2
+ interface IControl {
3
+ onAdd(map: MapInstance): HTMLElement;
4
+ onRemove(map: MapInstance): void;
5
+ }
6
+ interface StyleItem {
7
+ id: string;
8
+ name: string;
9
+ image: string;
10
+ styleUrl: string;
11
+ description?: string;
12
+ }
13
+ interface StyleSwitcherControlOptions {
14
+ styles: StyleItem[];
15
+ activeStyleId?: string;
16
+ onBeforeStyleChange?: (from: StyleItem, to: StyleItem) => void;
17
+ onAfterStyleChange?: (from: StyleItem, to: StyleItem) => void;
18
+ showLabels?: boolean;
19
+ showImages?: boolean;
20
+ animationDuration?: number;
21
+ maxHeight?: number;
22
+ theme?: 'light' | 'dark' | 'auto';
23
+ classNames?: Partial<StyleSwitcherClassNames>;
24
+ rtl?: boolean;
25
+ }
26
+ interface StyleSwitcherClassNames {
27
+ container: string;
28
+ list: string;
29
+ item: string;
30
+ itemSelected: string;
31
+ itemHideLabel: string;
32
+ dark: string;
33
+ light: string;
34
+ }
35
+ declare class StyleSwitcherControl implements IControl {
36
+ private _container;
37
+ private _options;
38
+ private _activeStyleId;
39
+ private _expanded;
40
+ private _classNames;
41
+ constructor(options: StyleSwitcherControlOptions);
42
+ onAdd(_map: MapInstance): HTMLElement;
43
+ private _applyTheme;
44
+ onRemove(): void;
45
+ private _setExpanded;
46
+ private _handleStyleChange;
47
+ private _render;
48
+ private _createStyleItem;
49
+ }
50
+
51
+ export { StyleSwitcherControl };
52
+ export type { StyleItem, StyleSwitcherClassNames, StyleSwitcherControlOptions };
package/dist/index.js ADDED
@@ -0,0 +1,184 @@
1
+ /******************************************************************************
2
+ Copyright (c) Microsoft Corporation.
3
+
4
+ Permission to use, copy, modify, and/or distribute this software for any
5
+ purpose with or without fee is hereby granted.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
11
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
12
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
13
+ PERFORMANCE OF THIS SOFTWARE.
14
+ ***************************************************************************** */
15
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
16
+
17
+
18
+ var __assign = function() {
19
+ __assign = Object.assign || function __assign(t) {
20
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
21
+ s = arguments[i];
22
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
23
+ }
24
+ return t;
25
+ };
26
+ return __assign.apply(this, arguments);
27
+ };
28
+
29
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
30
+ var e = new Error(message);
31
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
32
+ };
33
+
34
+ var StyleSwitcherControl = /** @class */ (function () {
35
+ function StyleSwitcherControl(options) {
36
+ var _a;
37
+ this._container = null;
38
+ this._expanded = false;
39
+ // Ensure at least one of showLabels or showImages is true
40
+ var showLabels = options.showLabels !== false;
41
+ var showImages = options.showImages !== false;
42
+ if (!showLabels && !showImages) {
43
+ throw new Error('At least one of showLabels or showImages must be true.');
44
+ }
45
+ // Validate activeStyleId if provided
46
+ if (options.activeStyleId &&
47
+ !options.styles.find(function (s) { return s.id === options.activeStyleId; })) {
48
+ console.warn("StyleSwitcherControl: activeStyleId \"".concat(options.activeStyleId, "\" does not match any style. Using first style instead."));
49
+ }
50
+ this._options = __assign({ showLabels: showLabels, showImages: showImages, animationDuration: 200, maxHeight: 300, theme: 'light' }, options);
51
+ this._activeStyleId = options.activeStyleId || ((_a = options.styles[0]) === null || _a === void 0 ? void 0 : _a.id);
52
+ this._classNames = __assign({ container: 'maplibregl-ctrl maplibregl-ctrl-group mapboxgl-ctrl mapboxgl-ctrl-group style-switcher', list: 'style-switcher-list', item: 'style-switcher-item', itemSelected: 'selected', itemHideLabel: 'hide-label', dark: 'style-switcher-dark', light: 'style-switcher-light' }, options.classNames);
53
+ }
54
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
55
+ StyleSwitcherControl.prototype.onAdd = function (_map) {
56
+ var _this = this;
57
+ this._container = document.createElement('div');
58
+ this._container.className = this._classNames.container;
59
+ this._container.tabIndex = 0;
60
+ this._container.setAttribute('role', 'button');
61
+ this._container.setAttribute('aria-label', 'Style switcher');
62
+ this._container.setAttribute('aria-expanded', 'false');
63
+ // Apply RTL if specified
64
+ if (this._options.rtl) {
65
+ this._container.setAttribute('dir', 'rtl');
66
+ }
67
+ // Theme support
68
+ this._applyTheme();
69
+ this._container.addEventListener('mouseenter', function () {
70
+ return _this._setExpanded(true);
71
+ });
72
+ this._container.addEventListener('mouseleave', function () {
73
+ return _this._setExpanded(false);
74
+ });
75
+ this._container.addEventListener('focus', function () { return _this._setExpanded(true); });
76
+ this._container.addEventListener('blur', function () { return _this._setExpanded(false); });
77
+ this._render();
78
+ return this._container;
79
+ };
80
+ StyleSwitcherControl.prototype._applyTheme = function () {
81
+ if (!this._container)
82
+ return;
83
+ this._container.classList.remove(this._classNames.dark, this._classNames.light);
84
+ if (this._options.theme === 'dark') {
85
+ this._container.classList.add(this._classNames.dark);
86
+ }
87
+ else if (this._options.theme === 'light') {
88
+ this._container.classList.add(this._classNames.light);
89
+ }
90
+ else if (this._options.theme === 'auto') {
91
+ // Auto-detect dark mode
92
+ var isDark = window.matchMedia &&
93
+ window.matchMedia('(prefers-color-scheme: dark)').matches;
94
+ this._container.classList.add(isDark ? this._classNames.dark : this._classNames.light);
95
+ }
96
+ };
97
+ StyleSwitcherControl.prototype.onRemove = function () {
98
+ if (this._container && this._container.parentNode) {
99
+ this._container.parentNode.removeChild(this._container);
100
+ }
101
+ this._container = null;
102
+ };
103
+ StyleSwitcherControl.prototype._setExpanded = function (expanded) {
104
+ var _a;
105
+ if (this._expanded === expanded)
106
+ return;
107
+ this._expanded = expanded;
108
+ (_a = this._container) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-expanded', expanded.toString());
109
+ this._render();
110
+ this._applyTheme();
111
+ };
112
+ StyleSwitcherControl.prototype._handleStyleChange = function (style) {
113
+ var _this = this;
114
+ if (style.id === this._activeStyleId)
115
+ return;
116
+ var from = this._options.styles.find(function (s) { return s.id === _this._activeStyleId; });
117
+ if (this._options.onBeforeStyleChange)
118
+ this._options.onBeforeStyleChange(from, style);
119
+ this._activeStyleId = style.id;
120
+ this._render();
121
+ if (this._options.onAfterStyleChange)
122
+ this._options.onAfterStyleChange(from, style);
123
+ };
124
+ StyleSwitcherControl.prototype._render = function () {
125
+ var _this = this;
126
+ if (!this._container)
127
+ return;
128
+ this._container.innerHTML = '';
129
+ this._applyTheme();
130
+ var currentStyle = this._options.styles.find(function (s) { return s.id === _this._activeStyleId; }) ||
131
+ this._options.styles[0];
132
+ // List (expanded)
133
+ if (this._expanded) {
134
+ var list = document.createElement('div');
135
+ list.className = this._classNames.list;
136
+ list.style.display = 'flex';
137
+ var _loop_1 = function (style) {
138
+ var item = this_1._createStyleItem(style, style.id === this_1._activeStyleId);
139
+ item.onclick = function () { return _this._handleStyleChange(style); };
140
+ list.appendChild(item);
141
+ };
142
+ var this_1 = this;
143
+ for (var _i = 0, _a = this._options.styles; _i < _a.length; _i++) {
144
+ var style = _a[_i];
145
+ _loop_1(style);
146
+ }
147
+ this._container.appendChild(list);
148
+ }
149
+ // Single (collapsed) - Always show the active style
150
+ var selected = this._createStyleItem(currentStyle, true);
151
+ this._container.appendChild(selected);
152
+ };
153
+ StyleSwitcherControl.prototype._createStyleItem = function (style, selected) {
154
+ var div = document.createElement('div');
155
+ var className = this._classNames.item;
156
+ if (selected)
157
+ className += ' ' + this._classNames.itemSelected;
158
+ if (this._options.showLabels === false)
159
+ className += ' ' + this._classNames.itemHideLabel;
160
+ div.className = className;
161
+ div.setAttribute('role', 'option');
162
+ div.setAttribute('aria-selected', selected.toString());
163
+ div.setAttribute('title', style.description || style.name);
164
+ // Image
165
+ if (this._options.showImages !== false) {
166
+ var img = document.createElement('img');
167
+ img.src = style.image;
168
+ img.alt = style.name;
169
+ img.loading = 'lazy';
170
+ div.appendChild(img);
171
+ }
172
+ // Label
173
+ if (this._options.showLabels !== false) {
174
+ var span = document.createElement('span');
175
+ span.textContent = style.name;
176
+ div.appendChild(span);
177
+ }
178
+ return div;
179
+ };
180
+ return StyleSwitcherControl;
181
+ }());
182
+
183
+ export { StyleSwitcherControl };
184
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../node_modules/tslib/tslib.es6.js","../src/components/StyleSwitcherControl.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nvar ownKeys = function(o) {\r\n ownKeys = Object.getOwnPropertyNames || function (o) {\r\n var ar = [];\r\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\r\n return ar;\r\n };\r\n return ownKeys(o);\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose, inner;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n if (async) inner = dispose;\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n var r, s = 0;\r\n function next() {\r\n while (r = env.stack.pop()) {\r\n try {\r\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n if (r.dispose) {\r\n var result = r.dispose.call(r.value);\r\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n else s |= 1;\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\r\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\r\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\r\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\r\n });\r\n }\r\n return path;\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __esDecorate: __esDecorate,\r\n __runInitializers: __runInitializers,\r\n __propKey: __propKey,\r\n __setFunctionName: __setFunctionName,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,\r\n};\r\n","// Polyfill types for IControl if not present\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MapInstance = any; // This represents either MapLibre GL Map or Mapbox GL Map\n\nexport interface IControl {\n onAdd(map: MapInstance): HTMLElement;\n onRemove(map: MapInstance): void;\n}\n\nexport interface StyleItem {\n id: string;\n name: string;\n image: string;\n styleUrl: string;\n description?: string;\n}\n\nexport interface StyleSwitcherControlOptions {\n styles: StyleItem[];\n activeStyleId?: string; // Currently active style ID (replaces initialStyleId and collapsedStyleId)\n onBeforeStyleChange?: (from: StyleItem, to: StyleItem) => void;\n onAfterStyleChange?: (from: StyleItem, to: StyleItem) => void;\n showLabels?: boolean;\n showImages?: boolean;\n animationDuration?: number;\n maxHeight?: number;\n theme?: 'light' | 'dark' | 'auto';\n classNames?: Partial<StyleSwitcherClassNames>;\n rtl?: boolean; // Enable RTL (Right-to-Left) layout\n}\n\nexport interface StyleSwitcherClassNames {\n container: string;\n list: string;\n item: string;\n itemSelected: string;\n itemHideLabel: string;\n dark: string;\n light: string;\n}\n\nexport class StyleSwitcherControl implements IControl {\n private _container: HTMLElement | null = null;\n private _options: StyleSwitcherControlOptions;\n private _activeStyleId: string;\n private _expanded: boolean = false;\n private _classNames: Required<StyleSwitcherClassNames>;\n\n constructor(options: StyleSwitcherControlOptions) {\n // Ensure at least one of showLabels or showImages is true\n const showLabels = options.showLabels !== false;\n const showImages = options.showImages !== false;\n if (!showLabels && !showImages) {\n throw new Error('At least one of showLabels or showImages must be true.');\n }\n\n // Validate activeStyleId if provided\n if (\n options.activeStyleId &&\n !options.styles.find(s => s.id === options.activeStyleId)\n ) {\n console.warn(\n `StyleSwitcherControl: activeStyleId \"${options.activeStyleId}\" does not match any style. Using first style instead.`\n );\n }\n\n this._options = {\n showLabels,\n showImages,\n animationDuration: 200,\n maxHeight: 300,\n theme: 'light',\n ...options,\n };\n this._activeStyleId = options.activeStyleId || options.styles[0]?.id;\n this._classNames = {\n container:\n 'maplibregl-ctrl maplibregl-ctrl-group mapboxgl-ctrl mapboxgl-ctrl-group style-switcher',\n list: 'style-switcher-list',\n item: 'style-switcher-item',\n itemSelected: 'selected',\n itemHideLabel: 'hide-label',\n dark: 'style-switcher-dark',\n light: 'style-switcher-light',\n ...options.classNames,\n };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onAdd(_map: MapInstance): HTMLElement {\n this._container = document.createElement('div');\n this._container.className = this._classNames.container;\n this._container.tabIndex = 0;\n this._container.setAttribute('role', 'button');\n this._container.setAttribute('aria-label', 'Style switcher');\n this._container.setAttribute('aria-expanded', 'false');\n\n // Apply RTL if specified\n if (this._options.rtl) {\n this._container.setAttribute('dir', 'rtl');\n }\n\n // Theme support\n this._applyTheme();\n\n this._container.addEventListener('mouseenter', () =>\n this._setExpanded(true)\n );\n this._container.addEventListener('mouseleave', () =>\n this._setExpanded(false)\n );\n this._container.addEventListener('focus', () => this._setExpanded(true));\n this._container.addEventListener('blur', () => this._setExpanded(false));\n\n this._render();\n return this._container;\n }\n\n private _applyTheme() {\n if (!this._container) return;\n this._container.classList.remove(\n this._classNames.dark,\n this._classNames.light\n );\n if (this._options.theme === 'dark') {\n this._container.classList.add(this._classNames.dark);\n } else if (this._options.theme === 'light') {\n this._container.classList.add(this._classNames.light);\n } else if (this._options.theme === 'auto') {\n // Auto-detect dark mode\n const isDark =\n window.matchMedia &&\n window.matchMedia('(prefers-color-scheme: dark)').matches;\n this._container.classList.add(\n isDark ? this._classNames.dark : this._classNames.light\n );\n }\n }\n\n onRemove() {\n if (this._container && this._container.parentNode) {\n this._container.parentNode.removeChild(this._container);\n }\n this._container = null;\n }\n\n private _setExpanded(expanded: boolean) {\n if (this._expanded === expanded) return;\n this._expanded = expanded;\n this._container?.setAttribute('aria-expanded', expanded.toString());\n this._render();\n this._applyTheme();\n }\n\n private _handleStyleChange(style: StyleItem) {\n if (style.id === this._activeStyleId) return;\n const from = this._options.styles.find(s => s.id === this._activeStyleId)!;\n if (this._options.onBeforeStyleChange)\n this._options.onBeforeStyleChange(from, style);\n this._activeStyleId = style.id;\n this._render();\n if (this._options.onAfterStyleChange)\n this._options.onAfterStyleChange(from, style);\n }\n\n private _render() {\n if (!this._container) return;\n this._container.innerHTML = '';\n this._applyTheme();\n const currentStyle =\n this._options.styles.find(s => s.id === this._activeStyleId) ||\n this._options.styles[0];\n\n // List (expanded)\n if (this._expanded) {\n const list = document.createElement('div');\n list.className = this._classNames.list;\n list.style.display = 'flex';\n\n for (const style of this._options.styles) {\n const item = this._createStyleItem(\n style,\n style.id === this._activeStyleId\n );\n item.onclick = () => this._handleStyleChange(style);\n list.appendChild(item);\n }\n this._container.appendChild(list);\n }\n\n // Single (collapsed) - Always show the active style\n const selected = this._createStyleItem(currentStyle, true);\n this._container.appendChild(selected);\n }\n\n private _createStyleItem(style: StyleItem, selected: boolean) {\n const div = document.createElement('div');\n let className = this._classNames.item;\n if (selected) className += ' ' + this._classNames.itemSelected;\n if (this._options.showLabels === false)\n className += ' ' + this._classNames.itemHideLabel;\n div.className = className;\n div.setAttribute('role', 'option');\n div.setAttribute('aria-selected', selected.toString());\n div.setAttribute('title', style.description || style.name);\n\n // Image\n if (this._options.showImages !== false) {\n const img = document.createElement('img');\n img.src = style.image;\n img.alt = style.name;\n img.loading = 'lazy';\n div.appendChild(img);\n }\n\n // Label\n if (this._options.showLabels !== false) {\n const span = document.createElement('span');\n span.textContent = style.name;\n div.appendChild(span);\n }\n return div;\n }\n}\n"],"names":[],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1,192 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MapGLStyleSwitcher = {}));
5
+ })(this, (function (exports) { 'use strict';
6
+
7
+ /******************************************************************************
8
+ Copyright (c) Microsoft Corporation.
9
+
10
+ Permission to use, copy, modify, and/or distribute this software for any
11
+ purpose with or without fee is hereby granted.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19
+ PERFORMANCE OF THIS SOFTWARE.
20
+ ***************************************************************************** */
21
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
22
+
23
+
24
+ var __assign = function() {
25
+ __assign = Object.assign || function __assign(t) {
26
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
27
+ s = arguments[i];
28
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
29
+ }
30
+ return t;
31
+ };
32
+ return __assign.apply(this, arguments);
33
+ };
34
+
35
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
36
+ var e = new Error(message);
37
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
38
+ };
39
+
40
+ var StyleSwitcherControl = /** @class */ (function () {
41
+ function StyleSwitcherControl(options) {
42
+ var _a;
43
+ this._container = null;
44
+ this._expanded = false;
45
+ // Ensure at least one of showLabels or showImages is true
46
+ var showLabels = options.showLabels !== false;
47
+ var showImages = options.showImages !== false;
48
+ if (!showLabels && !showImages) {
49
+ throw new Error('At least one of showLabels or showImages must be true.');
50
+ }
51
+ // Validate activeStyleId if provided
52
+ if (options.activeStyleId &&
53
+ !options.styles.find(function (s) { return s.id === options.activeStyleId; })) {
54
+ console.warn("StyleSwitcherControl: activeStyleId \"".concat(options.activeStyleId, "\" does not match any style. Using first style instead."));
55
+ }
56
+ this._options = __assign({ showLabels: showLabels, showImages: showImages, animationDuration: 200, maxHeight: 300, theme: 'light' }, options);
57
+ this._activeStyleId = options.activeStyleId || ((_a = options.styles[0]) === null || _a === void 0 ? void 0 : _a.id);
58
+ this._classNames = __assign({ container: 'maplibregl-ctrl maplibregl-ctrl-group mapboxgl-ctrl mapboxgl-ctrl-group style-switcher', list: 'style-switcher-list', item: 'style-switcher-item', itemSelected: 'selected', itemHideLabel: 'hide-label', dark: 'style-switcher-dark', light: 'style-switcher-light' }, options.classNames);
59
+ }
60
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
61
+ StyleSwitcherControl.prototype.onAdd = function (_map) {
62
+ var _this = this;
63
+ this._container = document.createElement('div');
64
+ this._container.className = this._classNames.container;
65
+ this._container.tabIndex = 0;
66
+ this._container.setAttribute('role', 'button');
67
+ this._container.setAttribute('aria-label', 'Style switcher');
68
+ this._container.setAttribute('aria-expanded', 'false');
69
+ // Apply RTL if specified
70
+ if (this._options.rtl) {
71
+ this._container.setAttribute('dir', 'rtl');
72
+ }
73
+ // Theme support
74
+ this._applyTheme();
75
+ this._container.addEventListener('mouseenter', function () {
76
+ return _this._setExpanded(true);
77
+ });
78
+ this._container.addEventListener('mouseleave', function () {
79
+ return _this._setExpanded(false);
80
+ });
81
+ this._container.addEventListener('focus', function () { return _this._setExpanded(true); });
82
+ this._container.addEventListener('blur', function () { return _this._setExpanded(false); });
83
+ this._render();
84
+ return this._container;
85
+ };
86
+ StyleSwitcherControl.prototype._applyTheme = function () {
87
+ if (!this._container)
88
+ return;
89
+ this._container.classList.remove(this._classNames.dark, this._classNames.light);
90
+ if (this._options.theme === 'dark') {
91
+ this._container.classList.add(this._classNames.dark);
92
+ }
93
+ else if (this._options.theme === 'light') {
94
+ this._container.classList.add(this._classNames.light);
95
+ }
96
+ else if (this._options.theme === 'auto') {
97
+ // Auto-detect dark mode
98
+ var isDark = window.matchMedia &&
99
+ window.matchMedia('(prefers-color-scheme: dark)').matches;
100
+ this._container.classList.add(isDark ? this._classNames.dark : this._classNames.light);
101
+ }
102
+ };
103
+ StyleSwitcherControl.prototype.onRemove = function () {
104
+ if (this._container && this._container.parentNode) {
105
+ this._container.parentNode.removeChild(this._container);
106
+ }
107
+ this._container = null;
108
+ };
109
+ StyleSwitcherControl.prototype._setExpanded = function (expanded) {
110
+ var _a;
111
+ if (this._expanded === expanded)
112
+ return;
113
+ this._expanded = expanded;
114
+ (_a = this._container) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-expanded', expanded.toString());
115
+ this._render();
116
+ this._applyTheme();
117
+ };
118
+ StyleSwitcherControl.prototype._handleStyleChange = function (style) {
119
+ var _this = this;
120
+ if (style.id === this._activeStyleId)
121
+ return;
122
+ var from = this._options.styles.find(function (s) { return s.id === _this._activeStyleId; });
123
+ if (this._options.onBeforeStyleChange)
124
+ this._options.onBeforeStyleChange(from, style);
125
+ this._activeStyleId = style.id;
126
+ this._render();
127
+ if (this._options.onAfterStyleChange)
128
+ this._options.onAfterStyleChange(from, style);
129
+ };
130
+ StyleSwitcherControl.prototype._render = function () {
131
+ var _this = this;
132
+ if (!this._container)
133
+ return;
134
+ this._container.innerHTML = '';
135
+ this._applyTheme();
136
+ var currentStyle = this._options.styles.find(function (s) { return s.id === _this._activeStyleId; }) ||
137
+ this._options.styles[0];
138
+ // List (expanded)
139
+ if (this._expanded) {
140
+ var list = document.createElement('div');
141
+ list.className = this._classNames.list;
142
+ list.style.display = 'flex';
143
+ var _loop_1 = function (style) {
144
+ var item = this_1._createStyleItem(style, style.id === this_1._activeStyleId);
145
+ item.onclick = function () { return _this._handleStyleChange(style); };
146
+ list.appendChild(item);
147
+ };
148
+ var this_1 = this;
149
+ for (var _i = 0, _a = this._options.styles; _i < _a.length; _i++) {
150
+ var style = _a[_i];
151
+ _loop_1(style);
152
+ }
153
+ this._container.appendChild(list);
154
+ }
155
+ // Single (collapsed) - Always show the active style
156
+ var selected = this._createStyleItem(currentStyle, true);
157
+ this._container.appendChild(selected);
158
+ };
159
+ StyleSwitcherControl.prototype._createStyleItem = function (style, selected) {
160
+ var div = document.createElement('div');
161
+ var className = this._classNames.item;
162
+ if (selected)
163
+ className += ' ' + this._classNames.itemSelected;
164
+ if (this._options.showLabels === false)
165
+ className += ' ' + this._classNames.itemHideLabel;
166
+ div.className = className;
167
+ div.setAttribute('role', 'option');
168
+ div.setAttribute('aria-selected', selected.toString());
169
+ div.setAttribute('title', style.description || style.name);
170
+ // Image
171
+ if (this._options.showImages !== false) {
172
+ var img = document.createElement('img');
173
+ img.src = style.image;
174
+ img.alt = style.name;
175
+ img.loading = 'lazy';
176
+ div.appendChild(img);
177
+ }
178
+ // Label
179
+ if (this._options.showLabels !== false) {
180
+ var span = document.createElement('span');
181
+ span.textContent = style.name;
182
+ div.appendChild(span);
183
+ }
184
+ return div;
185
+ };
186
+ return StyleSwitcherControl;
187
+ }());
188
+
189
+ exports.StyleSwitcherControl = StyleSwitcherControl;
190
+
191
+ }));
192
+ //# sourceMappingURL=index.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.js","sources":["../node_modules/tslib/tslib.es6.js","../src/components/StyleSwitcherControl.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.unshift(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.unshift(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\r\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\r\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nvar ownKeys = function(o) {\r\n ownKeys = Object.getOwnPropertyNames || function (o) {\r\n var ar = [];\r\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\r\n return ar;\r\n };\r\n return ownKeys(o);\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n\r\nexport function __addDisposableResource(env, value, async) {\r\n if (value !== null && value !== void 0) {\r\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\r\n var dispose, inner;\r\n if (async) {\r\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\r\n dispose = value[Symbol.asyncDispose];\r\n }\r\n if (dispose === void 0) {\r\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\r\n dispose = value[Symbol.dispose];\r\n if (async) inner = dispose;\r\n }\r\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\r\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\r\n env.stack.push({ value: value, dispose: dispose, async: async });\r\n }\r\n else if (async) {\r\n env.stack.push({ async: true });\r\n }\r\n return value;\r\n\r\n}\r\n\r\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\r\n\r\nexport function __disposeResources(env) {\r\n function fail(e) {\r\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\r\n env.hasError = true;\r\n }\r\n var r, s = 0;\r\n function next() {\r\n while (r = env.stack.pop()) {\r\n try {\r\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\r\n if (r.dispose) {\r\n var result = r.dispose.call(r.value);\r\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\r\n }\r\n else s |= 1;\r\n }\r\n catch (e) {\r\n fail(e);\r\n }\r\n }\r\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\r\n if (env.hasError) throw env.error;\r\n }\r\n return next();\r\n}\r\n\r\nexport function __rewriteRelativeImportExtension(path, preserveJsx) {\r\n if (typeof path === \"string\" && /^\\.\\.?\\//.test(path)) {\r\n return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {\r\n return tsx ? preserveJsx ? \".jsx\" : \".js\" : d && (!ext || !cm) ? m : (d + ext + \".\" + cm.toLowerCase() + \"js\");\r\n });\r\n }\r\n return path;\r\n}\r\n\r\nexport default {\r\n __extends: __extends,\r\n __assign: __assign,\r\n __rest: __rest,\r\n __decorate: __decorate,\r\n __param: __param,\r\n __esDecorate: __esDecorate,\r\n __runInitializers: __runInitializers,\r\n __propKey: __propKey,\r\n __setFunctionName: __setFunctionName,\r\n __metadata: __metadata,\r\n __awaiter: __awaiter,\r\n __generator: __generator,\r\n __createBinding: __createBinding,\r\n __exportStar: __exportStar,\r\n __values: __values,\r\n __read: __read,\r\n __spread: __spread,\r\n __spreadArrays: __spreadArrays,\r\n __spreadArray: __spreadArray,\r\n __await: __await,\r\n __asyncGenerator: __asyncGenerator,\r\n __asyncDelegator: __asyncDelegator,\r\n __asyncValues: __asyncValues,\r\n __makeTemplateObject: __makeTemplateObject,\r\n __importStar: __importStar,\r\n __importDefault: __importDefault,\r\n __classPrivateFieldGet: __classPrivateFieldGet,\r\n __classPrivateFieldSet: __classPrivateFieldSet,\r\n __classPrivateFieldIn: __classPrivateFieldIn,\r\n __addDisposableResource: __addDisposableResource,\r\n __disposeResources: __disposeResources,\r\n __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,\r\n};\r\n","// Polyfill types for IControl if not present\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MapInstance = any; // This represents either MapLibre GL Map or Mapbox GL Map\n\nexport interface IControl {\n onAdd(map: MapInstance): HTMLElement;\n onRemove(map: MapInstance): void;\n}\n\nexport interface StyleItem {\n id: string;\n name: string;\n image: string;\n styleUrl: string;\n description?: string;\n}\n\nexport interface StyleSwitcherControlOptions {\n styles: StyleItem[];\n activeStyleId?: string; // Currently active style ID (replaces initialStyleId and collapsedStyleId)\n onBeforeStyleChange?: (from: StyleItem, to: StyleItem) => void;\n onAfterStyleChange?: (from: StyleItem, to: StyleItem) => void;\n showLabels?: boolean;\n showImages?: boolean;\n animationDuration?: number;\n maxHeight?: number;\n theme?: 'light' | 'dark' | 'auto';\n classNames?: Partial<StyleSwitcherClassNames>;\n rtl?: boolean; // Enable RTL (Right-to-Left) layout\n}\n\nexport interface StyleSwitcherClassNames {\n container: string;\n list: string;\n item: string;\n itemSelected: string;\n itemHideLabel: string;\n dark: string;\n light: string;\n}\n\nexport class StyleSwitcherControl implements IControl {\n private _container: HTMLElement | null = null;\n private _options: StyleSwitcherControlOptions;\n private _activeStyleId: string;\n private _expanded: boolean = false;\n private _classNames: Required<StyleSwitcherClassNames>;\n\n constructor(options: StyleSwitcherControlOptions) {\n // Ensure at least one of showLabels or showImages is true\n const showLabels = options.showLabels !== false;\n const showImages = options.showImages !== false;\n if (!showLabels && !showImages) {\n throw new Error('At least one of showLabels or showImages must be true.');\n }\n\n // Validate activeStyleId if provided\n if (\n options.activeStyleId &&\n !options.styles.find(s => s.id === options.activeStyleId)\n ) {\n console.warn(\n `StyleSwitcherControl: activeStyleId \"${options.activeStyleId}\" does not match any style. Using first style instead.`\n );\n }\n\n this._options = {\n showLabels,\n showImages,\n animationDuration: 200,\n maxHeight: 300,\n theme: 'light',\n ...options,\n };\n this._activeStyleId = options.activeStyleId || options.styles[0]?.id;\n this._classNames = {\n container:\n 'maplibregl-ctrl maplibregl-ctrl-group mapboxgl-ctrl mapboxgl-ctrl-group style-switcher',\n list: 'style-switcher-list',\n item: 'style-switcher-item',\n itemSelected: 'selected',\n itemHideLabel: 'hide-label',\n dark: 'style-switcher-dark',\n light: 'style-switcher-light',\n ...options.classNames,\n };\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onAdd(_map: MapInstance): HTMLElement {\n this._container = document.createElement('div');\n this._container.className = this._classNames.container;\n this._container.tabIndex = 0;\n this._container.setAttribute('role', 'button');\n this._container.setAttribute('aria-label', 'Style switcher');\n this._container.setAttribute('aria-expanded', 'false');\n\n // Apply RTL if specified\n if (this._options.rtl) {\n this._container.setAttribute('dir', 'rtl');\n }\n\n // Theme support\n this._applyTheme();\n\n this._container.addEventListener('mouseenter', () =>\n this._setExpanded(true)\n );\n this._container.addEventListener('mouseleave', () =>\n this._setExpanded(false)\n );\n this._container.addEventListener('focus', () => this._setExpanded(true));\n this._container.addEventListener('blur', () => this._setExpanded(false));\n\n this._render();\n return this._container;\n }\n\n private _applyTheme() {\n if (!this._container) return;\n this._container.classList.remove(\n this._classNames.dark,\n this._classNames.light\n );\n if (this._options.theme === 'dark') {\n this._container.classList.add(this._classNames.dark);\n } else if (this._options.theme === 'light') {\n this._container.classList.add(this._classNames.light);\n } else if (this._options.theme === 'auto') {\n // Auto-detect dark mode\n const isDark =\n window.matchMedia &&\n window.matchMedia('(prefers-color-scheme: dark)').matches;\n this._container.classList.add(\n isDark ? this._classNames.dark : this._classNames.light\n );\n }\n }\n\n onRemove() {\n if (this._container && this._container.parentNode) {\n this._container.parentNode.removeChild(this._container);\n }\n this._container = null;\n }\n\n private _setExpanded(expanded: boolean) {\n if (this._expanded === expanded) return;\n this._expanded = expanded;\n this._container?.setAttribute('aria-expanded', expanded.toString());\n this._render();\n this._applyTheme();\n }\n\n private _handleStyleChange(style: StyleItem) {\n if (style.id === this._activeStyleId) return;\n const from = this._options.styles.find(s => s.id === this._activeStyleId)!;\n if (this._options.onBeforeStyleChange)\n this._options.onBeforeStyleChange(from, style);\n this._activeStyleId = style.id;\n this._render();\n if (this._options.onAfterStyleChange)\n this._options.onAfterStyleChange(from, style);\n }\n\n private _render() {\n if (!this._container) return;\n this._container.innerHTML = '';\n this._applyTheme();\n const currentStyle =\n this._options.styles.find(s => s.id === this._activeStyleId) ||\n this._options.styles[0];\n\n // List (expanded)\n if (this._expanded) {\n const list = document.createElement('div');\n list.className = this._classNames.list;\n list.style.display = 'flex';\n\n for (const style of this._options.styles) {\n const item = this._createStyleItem(\n style,\n style.id === this._activeStyleId\n );\n item.onclick = () => this._handleStyleChange(style);\n list.appendChild(item);\n }\n this._container.appendChild(list);\n }\n\n // Single (collapsed) - Always show the active style\n const selected = this._createStyleItem(currentStyle, true);\n this._container.appendChild(selected);\n }\n\n private _createStyleItem(style: StyleItem, selected: boolean) {\n const div = document.createElement('div');\n let className = this._classNames.item;\n if (selected) className += ' ' + this._classNames.itemSelected;\n if (this._options.showLabels === false)\n className += ' ' + this._classNames.itemHideLabel;\n div.className = className;\n div.setAttribute('role', 'option');\n div.setAttribute('aria-selected', selected.toString());\n div.setAttribute('title', style.description || style.name);\n\n // Image\n if (this._options.showImages !== false) {\n const img = document.createElement('img');\n img.src = style.image;\n img.alt = style.name;\n img.loading = 'lazy';\n div.appendChild(img);\n }\n\n // Label\n if (this._options.showLabels !== false) {\n const span = document.createElement('span');\n span.textContent = style.name;\n div.appendChild(span);\n }\n return div;\n }\n}\n"],"names":[],"mappings":"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","x_google_ignoreList":[0]}
@@ -0,0 +1 @@
1
+ .maplibregl-ctrl.style-switcher,.mapboxgl-ctrl.style-switcher{box-shadow:0 2px 8px rgba(0,0,0,0.15);background:#fff;border-radius:8px;padding:8px;margin:8px;transition:box-shadow 0.2s;min-width:unset;width:auto;user-select:none;cursor:pointer;}[dir='rtl'] .maplibregl-ctrl.style-switcher,[dir='rtl'] .mapboxgl-ctrl.style-switcher,.maplibregl-ctrl.style-switcher[dir='rtl'],.mapboxgl-ctrl.style-switcher[dir='rtl']{direction:rtl;}.maplibregl-ctrl.style-switcher.style-switcher-dark,.mapboxgl-ctrl.style-switcher.style-switcher-dark{background:#2a2a2a;color:#fff;border:1px solid #444;}.maplibregl-ctrl.style-switcher.style-switcher-light,.mapboxgl-ctrl.style-switcher.style-switcher-light{background:#ffffff;color:#333;border:1px solid #ddd;}.style-switcher-list{display:flex;flex-direction:column;gap:4px;margin-bottom:8px;max-height:300px;overflow-y:auto;overflow-x:hidden;}[dir='rtl'] .style-switcher-list,.style-switcher-list[dir='rtl']{direction:rtl;}.style-switcher-item{display:flex;align-items:center;gap:8px;cursor:pointer;padding:6px 8px;border-radius:6px;transition:all 0.2s ease;border:2px solid transparent;position:relative;overflow:hidden;}.style-switcher-item:hover{background:#f0f8ff;transform:translateY(-1px);}.style-switcher-item.selected{background:#e6f0ff;font-weight:600;border:2px solid #0066cc;}.style-switcher-item:not(:has(span)){min-width:unset;width:40px;justify-content:center;padding-left:0;padding-right:0;}.style-switcher-item.hide-label span{display:none !important;}.maplibregl-ctrl.style-switcher.style-switcher-dark .style-switcher-item:hover,.mapboxgl-ctrl.style-switcher.style-switcher-dark .style-switcher-item:hover{background:#333;}.maplibregl-ctrl.style-switcher.style-switcher-dark .style-switcher-item.selected,.mapboxgl-ctrl.style-switcher.style-switcher-dark .style-switcher-item.selected{background:#404040;border-color:#666;}.style-switcher-item img{width:32px;height:32px;object-fit:cover;border-radius:4px;background:#f0f0f0;border:1px solid #ddd;flex-shrink:0;transition:all 0.2s ease;}.maplibregl-ctrl.style-switcher.style-switcher-dark .style-switcher-item img,.mapboxgl-ctrl.style-switcher.style-switcher-dark .style-switcher-item img{background:#555;border-color:#666;}.style-switcher-item span{font-size:14px;line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0;}.maplibregl-ctrl.style-switcher:focus,.mapboxgl-ctrl.style-switcher:focus{outline:2px solid #0066cc;outline-offset:2px;}.style-switcher-item:focus{outline:2px solid #0066cc;outline-offset:1px;}.style-switcher-list{animation:fadeIn 0.2s ease-in-out;}@keyframes fadeIn{from{opacity:0;transform:translateY(-10px);}to{opacity:1;transform:translateY(0);}}.style-switcher-list::-webkit-scrollbar{width:4px;}.style-switcher-list::-webkit-scrollbar-track{background:#f0f0f0;border-radius:2px;}.style-switcher-list::-webkit-scrollbar-thumb{background:#ccc;border-radius:2px;}.maplibregl-ctrl.style-switcher.style-switcher-dark .style-switcher-list::-webkit-scrollbar-track,.mapboxgl-ctrl.style-switcher.style-switcher-dark .style-switcher-list::-webkit-scrollbar-track{background:#2a2a2a;}.maplibregl-ctrl.style-switcher.style-switcher-dark .style-switcher-list::-webkit-scrollbar-thumb,.mapboxgl-ctrl.style-switcher.style-switcher-dark .style-switcher-list::-webkit-scrollbar-thumb{background:#555;}
package/package.json ADDED
@@ -0,0 +1,108 @@
1
+ {
2
+ "name": "map-gl-style-switcher",
3
+ "version": "0.5.0",
4
+ "description": "A customizable style switcher control for Mapbox GL JS and MapLibre GL JS",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "engines": {
15
+ "node": ">=16",
16
+ "npm": ">=8.0.0"
17
+ },
18
+ "keywords": [
19
+ "mapbox",
20
+ "maplibre",
21
+ "map",
22
+ "style",
23
+ "switcher",
24
+ "basemap",
25
+ "control",
26
+ "typescript",
27
+ "accessibility"
28
+ ],
29
+ "author": "Muhammad Imran Siddique <muimsd@gmail.com>",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/muimsd/map-gl-style-switcher.git"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/muimsd/map-gl-style-switcher/issues"
37
+ },
38
+ "homepage": "https://github.com/muimsd/map-gl-style-switcher#readme",
39
+ "demo": "https://map-gl-style-switcher.netlify.app",
40
+ "peerDependencies": {
41
+ "mapbox-gl": ">=1.0.0",
42
+ "maplibre-gl": ">=2.0.0"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "mapbox-gl": {
46
+ "optional": true
47
+ },
48
+ "maplibre-gl": {
49
+ "optional": true
50
+ }
51
+ },
52
+ "scripts": {
53
+ "dev": "vite",
54
+ "build": "npm run clean && npm run type-check && rollup -c",
55
+ "build:prod": "npm run clean && npm run type-check && npm run lint && rollup -c",
56
+ "build:watch": "rollup -c --watch",
57
+ "build:example": "vite build --outDir dist-demo",
58
+ "preview:example": "vite preview --outDir dist-demo",
59
+ "clean": "rimraf dist",
60
+ "type-check": "tsc --noEmit",
61
+ "type-check:watch": "tsc --noEmit --watch",
62
+ "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
63
+ "lint:fix": "eslint src --ext ts,tsx --fix",
64
+ "format": "prettier --write \"src/**/*.{ts,tsx,css,md}\"",
65
+ "format:check": "prettier --check \"src/**/*.{ts,tsx,css,md}\"",
66
+ "test": "jest",
67
+ "test:watch": "jest --watch",
68
+ "test:coverage": "jest --coverage",
69
+ "test:ci": "jest --ci --coverage --watchAll=false",
70
+ "validate": "npm run type-check && npm run lint && npm run format:check && npm run test:ci",
71
+ "release:patch": "npm version patch && npm publish",
72
+ "release:minor": "npm version minor && npm publish",
73
+ "release:major": "npm version major && npm publish",
74
+ "prepublishOnly": "npm run validate && npm run build:prod",
75
+ "postversion": "git push && git push --tags"
76
+ },
77
+ "devDependencies": {
78
+ "@eslint/js": "^9.25.0",
79
+ "@rollup/plugin-node-resolve": "^16.0.1",
80
+ "@rollup/plugin-typescript": "^12.1.2",
81
+ "@types/jest": "^29.5.14",
82
+ "@types/mapbox-gl": "^3.4.1",
83
+ "@types/maplibre-gl": "^1.13.2",
84
+ "@types/node": "^22.10.7",
85
+ "@types/react": "^19.1.2",
86
+ "@types/react-dom": "^19.1.2",
87
+ "@vitejs/plugin-react": "^4.4.1",
88
+ "eslint": "^9.25.0",
89
+ "eslint-plugin-react-hooks": "^5.2.0",
90
+ "eslint-plugin-react-refresh": "^0.4.19",
91
+ "globals": "^16.0.0",
92
+ "jest": "^29.7.0",
93
+ "jest-environment-jsdom": "^29.7.0",
94
+ "maplibre-gl": "^5.6.0",
95
+ "prettier": "^3.4.2",
96
+ "react": "^19.1.0",
97
+ "react-dom": "^19.1.0",
98
+ "rimraf": "^6.0.1",
99
+ "rollup": "^4.43.0",
100
+ "rollup-plugin-dts": "^6.2.1",
101
+ "rollup-plugin-postcss": "^4.0.2",
102
+ "ts-jest": "^29.2.6",
103
+ "tslib": "^2.8.1",
104
+ "typescript": "~5.8.3",
105
+ "typescript-eslint": "^8.30.1",
106
+ "vite": "^6.3.5"
107
+ }
108
+ }