@sakuzu/maplibre-gl-draw-ui 1.0.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.
@@ -0,0 +1,237 @@
1
+ import type { Draw, Mode } from '@sakuzu/maplibre-gl-draw';
2
+ import type { InspectorHandle, InspectorOptions } from './inspector/types.js';
3
+ import type { Locale } from './messages.js';
4
+ import type { Theme } from './theme.js';
5
+ /** The name of a built-in tool */
6
+ export type ToolId = 'select' | 'point' | 'line' | 'polygon' | 'circle' | 'freehand' | 'image';
7
+ /** A tool of the toolbar */
8
+ export interface ToolSpec {
9
+ /** The name of the tool, unique in the toolbar */
10
+ id: string;
11
+ /** The mode of core the tool enters */
12
+ mode: Mode;
13
+ /** The name shown in its tooltip and read by assistive technology */
14
+ label: string;
15
+ /**
16
+ * The icon: SVG markup (an `<svg>` element drawn with `currentColor`, shown at the size of the
17
+ * icons of the toolbar), or the name of a built-in icon (a built-in tool's ID, `delete` or
18
+ * `snapping`). The markup is inserted as it is, so it must come from the application, never
19
+ * from a user
20
+ */
21
+ icon: string;
22
+ /** The key that picks the tool, such as `T`, or with modifiers joined by `+` (`shift+t`) */
23
+ shortcut?: string;
24
+ /** Tools of the same group sit together; a tool without one is in a group of its own */
25
+ group?: string;
26
+ }
27
+ /** A tool as the options name it: a built-in tool by its ID, or a tool of the application */
28
+ export type ToolEntry = ToolId | ToolSpec;
29
+ /** Where a part of the interface put alone goes, its words and its theme */
30
+ export interface AloneOptions {
31
+ /** The element to put it in */
32
+ target: HTMLElement;
33
+ /** The words: `en` (the default), `ja`, or words laid over English */
34
+ locale?: Locale;
35
+ /**
36
+ * The theme: `light`, `dark`, or `auto` (the default) to follow the system's preference
37
+ * (prefers-color-scheme), also when it changes
38
+ */
39
+ theme?: Theme;
40
+ }
41
+ /** What the toolbar shows */
42
+ export interface ToolbarOptions {
43
+ /**
44
+ * The tools, in order: built-in tools by their ID and tools of the application. All seven
45
+ * built-in tools when left out
46
+ */
47
+ tools?: ToolEntry[];
48
+ /** Whether the delete button shows; true when left out */
49
+ delete?: boolean;
50
+ /** Whether the snapping switch shows; true when left out */
51
+ snapping?: boolean;
52
+ }
53
+ /** What `createDrawUI` puts on the map */
54
+ export interface DrawUIOptions {
55
+ /**
56
+ * The element the interface is laid over, which must be positioned (relative, absolute or
57
+ * fixed). The map's container when left out
58
+ */
59
+ container?: HTMLElement;
60
+ /** The toolbar at the bottom, or false for none; true when left out */
61
+ toolbar?: boolean | ToolbarOptions;
62
+ /**
63
+ * The inspector on the right, open while something is selected, or false for none; true when
64
+ * left out
65
+ */
66
+ inspector?: boolean | InspectorOptions;
67
+ /**
68
+ * The layer panel on the left, in a tab beside the legend, or false for none; true when left
69
+ * out
70
+ */
71
+ layers?: boolean | LayerPanelOptions;
72
+ /** The legend, in a tab beside the layer panel, or false for none; true when left out */
73
+ legend?: boolean;
74
+ /** The words: `en` (the default), `ja`, or words laid over English */
75
+ locale?: Locale;
76
+ /**
77
+ * The theme: `light`, `dark`, or `auto` (the default) to follow the system's preference
78
+ * (prefers-color-scheme), also when it changes
79
+ */
80
+ theme?: Theme;
81
+ /**
82
+ * The units of the measurements of the inspector, unless its options name others; metric when
83
+ * left out
84
+ */
85
+ units?: 'metric' | 'imperial';
86
+ /**
87
+ * Whether the keyboard shortcuts are on: the keys of the tools, Delete and Backspace for the
88
+ * selection, and ? for the list of the shortcuts; true when left out
89
+ */
90
+ shortcuts?: boolean;
91
+ /**
92
+ * Whether the map's padding follows the interface: the width of a panel that stands beside the
93
+ * map on its side, and the toolbar's height with its gap at the bottom, so that `fitBounds` and
94
+ * `easeTo` keep clear of them. Floating panels and sheets leave it at 0. The padding the map
95
+ * had is given back by `destroy()`. True when left out
96
+ */
97
+ padding?: boolean;
98
+ /**
99
+ * Where the side panels go on a wide map: `'floating'` lays them over the map, gap-md from
100
+ * its edges and as tall as their content (the default, as the reference layout); `'beside'`
101
+ * docks them beside the map from 64rem. Below 48rem both become sheets
102
+ */
103
+ side?: 'floating' | 'beside';
104
+ /**
105
+ * Whether a button at the top right of the map switches between the light and the dark look:
106
+ * it sets the theme to the look that is not shown now (from `auto`, the one the system does not
107
+ * prefer). True when left out
108
+ */
109
+ themeToggle?: boolean;
110
+ /**
111
+ * maplibre-gl's own controls, added to the map as maplibre-gl draws them: at the bottom right,
112
+ * from the top, the globe, the compass and the zoom; at the bottom left, the scale. True (all
113
+ * four) when left out; false for none, as for a page that adds controls of its own; an object
114
+ * for some of them. `destroy()` removes them
115
+ */
116
+ mapControls?: boolean | MapControlsOptions;
117
+ }
118
+ /** Which of maplibre-gl's own controls `createDrawUI` adds to the map; each is true when left out */
119
+ export interface MapControlsOptions {
120
+ /** The globe control (GlobeControl), which switches between the globe and the flat map */
121
+ globe?: boolean;
122
+ /** The compass (a NavigationControl without zoom), which resets the bearing and the pitch */
123
+ compass?: boolean;
124
+ /** The zoom buttons (a NavigationControl without compass) */
125
+ zoom?: boolean;
126
+ /** The scale bar (ScaleControl) */
127
+ scale?: boolean;
128
+ }
129
+ /** A toolbar on the page */
130
+ export interface ToolbarHandle {
131
+ /** The element of the toolbar */
132
+ readonly element: HTMLElement;
133
+ /** Removes the toolbar. A second call does nothing */
134
+ destroy(): void;
135
+ }
136
+ /** The tools of the toolbar, to add to and to remove from */
137
+ export interface ToolsHandle {
138
+ /**
139
+ * Adds a tool after the last tool of its group, or at the end
140
+ *
141
+ * @returns The function that removes it again
142
+ * @throws Error when the tool is not valid or its ID is taken
143
+ */
144
+ add(spec: ToolSpec): () => void;
145
+ /**
146
+ * Removes a tool, built-in or added
147
+ *
148
+ * @returns Whether there was a tool with this ID
149
+ */
150
+ remove(id: string): boolean;
151
+ /** The tools in the order of the toolbar; a built-in tool has its built-in icon's name */
152
+ list(): ToolSpec[];
153
+ }
154
+ /** The interface on a map */
155
+ export interface DrawUI {
156
+ /** The root element of the interface (the class `mgd-ui`) */
157
+ readonly element: HTMLElement;
158
+ /** The toolbar, or null when there is none */
159
+ readonly toolbar: ToolbarHandle | null;
160
+ /** The tools of the toolbar */
161
+ readonly tools: ToolsHandle;
162
+ /** The layer panel, or null when there is none */
163
+ readonly layers: LayerPanelHandle | null;
164
+ /** The legend, or null when there is none */
165
+ readonly legend: LegendHandle | null;
166
+ /** The inspector, or null when there is none */
167
+ readonly inspector: InspectorHandle | null;
168
+ /** Changes the words */
169
+ setLocale(locale: Locale): void;
170
+ /**
171
+ * Changes the theme
172
+ *
173
+ * @throws Error when the theme is not `light`, `dark` or `auto`
174
+ */
175
+ setTheme(theme: Theme): void;
176
+ /** Removes the interface and stops following the draw instance. A second call does nothing */
177
+ destroy(): void;
178
+ }
179
+ /** What the toolbar of `createDrawUI` shows, or null when there is no toolbar */
180
+ export interface ToolbarSettings {
181
+ /** Whether the delete button shows */
182
+ deletable: boolean;
183
+ /** Whether the snapping switch shows */
184
+ snapping: boolean;
185
+ }
186
+ /** The members of a draw instance that the toolbar uses */
187
+ export type ToolbarDraw = Pick<Draw, 'getMode' | 'setMode' | 'on' | 'off'> & {
188
+ readonly selection: Pick<Draw['selection'], 'get' | 'delete'>;
189
+ readonly options: Pick<Draw['options'], 'get' | 'update'>;
190
+ };
191
+ /** The members of a draw instance that the whole interface uses */
192
+ export type DrawUIDraw = ToolbarDraw & Pick<Draw, 'getMap'> & {
193
+ readonly selection: Pick<Draw['selection'], 'get' | 'delete' | 'clear'>;
194
+ };
195
+ /** What the layer panel shows */
196
+ export interface LayerPanelOptions {
197
+ /** Whether the features show under the layers and the groups; true when left out */
198
+ features?: boolean;
199
+ /** Whether the add menu (a new layer, a new group) shows; true when left out */
200
+ add?: boolean;
201
+ /** Whether the rows can be dragged to reorder them; true when left out */
202
+ reorder?: boolean;
203
+ }
204
+ /** A layer panel on the page */
205
+ export interface LayerPanelHandle {
206
+ /** The element of the layer panel */
207
+ readonly element: HTMLElement;
208
+ /** Removes the layer panel. A second call does nothing */
209
+ destroy(): void;
210
+ }
211
+ /** A legend on the page */
212
+ export interface LegendHandle {
213
+ /** The element of the legend */
214
+ readonly element: HTMLElement;
215
+ /** Removes the legend. A second call does nothing */
216
+ destroy(): void;
217
+ }
218
+ /** What the left region of `createDrawUI` shows, or null when there is no left region */
219
+ export interface LeftSettings {
220
+ /** The layer panel, or null for none */
221
+ layers: Required<LayerPanelOptions> | null;
222
+ /** Whether the legend shows */
223
+ legend: boolean;
224
+ }
225
+ /** The members of a draw instance that the layer panel uses */
226
+ export type LayerPanelDraw = Pick<Draw, 'on' | 'off'> & {
227
+ readonly layers: Pick<Draw['layers'], 'get' | 'getOrder' | 'reorder' | 'create' | 'update' | 'getActive' | 'setActive'>;
228
+ readonly groups: Pick<Draw['groups'], 'get' | 'update' | 'move'>;
229
+ readonly features: Pick<Draw['features'], 'get' | 'update' | 'move' | 'getAppliedStyle'>;
230
+ readonly selection: Pick<Draw['selection'], 'get' | 'set' | 'clear' | 'group'>;
231
+ readonly hidden: Pick<Draw['hidden'], 'has' | 'remove'>;
232
+ };
233
+ /** The members of a draw instance that the legend uses */
234
+ export type LegendDraw = Pick<Draw, 'on' | 'off'> & {
235
+ readonly layers: Pick<Draw['layers'], 'get' | 'getOrder'>;
236
+ readonly features: Pick<Draw['features'], 'list'>;
237
+ };
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "@sakuzu/maplibre-gl-draw-ui",
3
+ "version": "1.0.0",
4
+ "description": "The standard user interface of @sakuzu/maplibre-gl-draw: a toolbar of drawing tools and keyboard shortcuts over the map, with a plain JavaScript API.",
5
+ "keywords": [
6
+ "maplibre",
7
+ "maplibre-gl",
8
+ "map",
9
+ "draw",
10
+ "drawing",
11
+ "editor",
12
+ "toolbar",
13
+ "ui"
14
+ ],
15
+ "license": "AGPL-3.0-only",
16
+ "author": "SAKAIDA Atsushi",
17
+ "homepage": "https://github.com/sakuzu/maplibre-gl-draw/tree/main/ui#readme",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/sakuzu/maplibre-gl-draw.git",
21
+ "directory": "ui"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/sakuzu/maplibre-gl-draw/issues"
25
+ },
26
+ "type": "module",
27
+ "main": "./dist/index.js",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "style": "./dist/style.css",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js",
35
+ "default": "./dist/index.js"
36
+ },
37
+ "./style.css": "./dist/style.css",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "sideEffects": [
41
+ "**/*.css"
42
+ ],
43
+ "engines": {
44
+ "node": ">=22"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "README.md",
49
+ "LICENSE",
50
+ "THIRD_PARTY_NOTICES.md",
51
+ "CHANGELOG.md"
52
+ ],
53
+ "publishConfig": {
54
+ "access": "public"
55
+ },
56
+ "scripts": {
57
+ "build": "node scripts/need-core.mjs && rm -rf dist && vite build && vite build --mode bundle && tsc -p tsconfig.build.json && node scripts/check-dist.mjs",
58
+ "typecheck": "node scripts/need-core.mjs && tsc --noEmit && svelte-check --tsconfig ./tsconfig.json --fail-on-warnings",
59
+ "lint": "biome check . && node scripts/check-imports.mjs",
60
+ "check:imports": "node scripts/check-imports.mjs",
61
+ "test": "node scripts/need-core.mjs && vitest run",
62
+ "test:e2e": "node scripts/need-core.mjs && vitest run --config e2e/vitest.config.ts",
63
+ "test:watch": "vitest",
64
+ "dev": "node scripts/need-core.mjs && vite --config vite.dev.config.ts",
65
+ "prepack": "npm run build"
66
+ },
67
+ "peerDependencies": {
68
+ "@sakuzu/maplibre-gl-draw": "^2.0.0",
69
+ "maplibre-gl": ">=4"
70
+ },
71
+ "dependencies": {
72
+ "svelte": "5.57.1"
73
+ },
74
+ "devDependencies": {
75
+ "@lucide/svelte": "^1.49.0",
76
+ "@sakuzu/kata": "^1.2.0",
77
+ "@sakuzu/maplibre-gl-draw": "file:..",
78
+ "@sveltejs/vite-plugin-svelte": "^7.3.1",
79
+ "@testing-library/svelte": "^5.4.2",
80
+ "jsdom": "^30.1.1",
81
+ "maplibre-gl": "6.11.1",
82
+ "postcss": "^8.5.28",
83
+ "svelte-check": "^4.7.6",
84
+ "typescript": "^6.0.3",
85
+ "vite": "^8.2.2",
86
+ "vitest": "^4.1.11"
87
+ }
88
+ }