@sakuzu/maplibre-gl-draw-ui 1.1.0 → 1.2.1

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/CHANGELOG.md CHANGED
@@ -7,6 +7,74 @@ follows semantic versioning.
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.2.1] - 2026-10-02
11
+
12
+ ### Fixed in 1.2.1
13
+
14
+ - In a sheet the inspector passes the sheet's height to its panel, so
15
+ the content scrolls and the foot stays in view (#14).
16
+ - The delete button of the toolbar is off while the draw is read-only,
17
+ as the Delete of the inspector is (#19).
18
+ - The bottom corners and the actions card write what their observers
19
+ measure in the next frame, so WebKit reports no ResizeObserver loop
20
+ (#21).
21
+
22
+ ## [1.2.0] - 2026-10-02
23
+
24
+ The narrow screen and the stage, from the visual review: the map's
25
+ padding and its controls follow the panes kata's Shell reports, the
26
+ actions card stands above the attribution and fits the map, the
27
+ inspector takes the width of its sheet and keeps its tabs in the head,
28
+ Delete has one place, maplibre-gl's controls follow the theme, and every
29
+ dataset is dragged among the layers. It reads kata 1.6.0.
30
+
31
+ ### Added in 1.2.0
32
+
33
+ - maplibre-gl's controls in the map's container, those of the
34
+ application too, follow the theme of `createDrawUI` (#10). The control
35
+ container (`.maplibregl-control-container`) has `data-mgd-ui-controls`,
36
+ to which the build moves kata's tokens as it does to `.mgd-ui`, and
37
+ the `data-color-mode` of the root, following `setTheme` and the
38
+ system; `destroy()` removes both. The groups of buttons, the lines
39
+ between them, the attribution and the scale are painted with the
40
+ tokens, and maplibre-gl's icons are inverted in the dark look.
41
+
42
+ ### Changed in 1.2.0
43
+
44
+ - Every dataset is dragged among the layers in the layer panel (#6). A
45
+ dataset of `above-store` or `below-store` dropped among the layers is
46
+ moved to `layer-order` (`datasets.move`) and placed with
47
+ `layers.reorder`; when the reorder is refused, it goes back to its
48
+ own order. `LayerPanelDraw` needs `datasets.move`.
49
+ - The map's padding follows the inset of kata's Shell (`onlayout`)
50
+ (#8): at the left, the room the left pane takes, beside the map or
51
+ floating over it with its gap; at the bottom, the height of the
52
+ sheets. The right pane, which opens with the selection, and the
53
+ toolbar are no longer padding, so the view does not jump on a
54
+ selection.
55
+ - The controls of the bottom right of the map (not the attribution)
56
+ move to the left of the right pane, gap-md apart, while they would be
57
+ under it, and the bottom left corner (the scale) rises above the
58
+ attribution's box where that box reaches it across, as the two-line
59
+ attribution of a narrow map does (#8). The attribution is only read;
60
+ its compact form stays maplibre-gl's own.
61
+ - The actions card stands above the higher of the scale and the
62
+ attribution's box where that box reaches the card across (#7). Its
63
+ height is capped to the map above its place, less gap-md at the top
64
+ and the button that opens the layer panel again while it shows, and
65
+ the whole card scrolls.
66
+ - In a sheet, on a narrow map, the inspector takes the width of the
67
+ sheet instead of the width of a panel (#9). The inspector of a feature
68
+ passes its tabs to kata's InspectorFrame, so they stay in the head
69
+ while the content scrolls; its measurements are under the head, and
70
+ its description starts the content of each tab.
71
+ - Delete is in the lead of the foot for several features, layers or
72
+ groups, as for one feature, instead of among the operations (#11).
73
+ - kata 1.6.0: the Footer of an inspector stacks only when its row does
74
+ not fit, a sheet's half stage is the content's height, a narrow map
75
+ opens one side sheet at a time, and the actions of a row of the layer
76
+ panel that show on hover take no room until the row is hovered.
77
+
10
78
  ## [1.1.0] - 2026-10-01
11
79
 
12
80
  The basemaps as the back of the stack in the layer panel, the datasets
package/README.md CHANGED
@@ -247,10 +247,15 @@ Each switch writes `draw.options.update`, and the settings follow
247
247
  `options.changed`, so a change made by code shows too.
248
248
  The side panels float over the map, gap-md from its edges and as tall
249
249
  as their content; `side: 'beside'` docks them beside the map on a wide
250
- one instead. The map's padding follows the interface, the width of a
251
- panel that stands beside the map and the toolbar's height at the bottom,
252
- so that `fitBounds` and `easeTo` keep clear of them; `padding: false`
253
- leaves the map's padding alone.
250
+ one instead. The map's padding follows the interface: at the left, the
251
+ room the left panel takes (beside the map, or floating over it with its
252
+ gap), and at the bottom, the height of the sheets of a narrow map, as
253
+ kata's Shell reports them (`onlayout`'s inset), so that `fitBounds` and
254
+ `easeTo` keep clear of them. The right panel opens and closes with the
255
+ selection and leaves the padding alone, so that the view does not jump;
256
+ the controls of the bottom right move out of its way instead (see
257
+ [Map controls](#map-controls)). `padding: false` leaves the map's
258
+ padding alone.
254
259
 
255
260
  On the left, the layer panel and the legend share a panel, in two tabs.
256
261
  The layer panel has two sections, Stack and Basemap. Stack is the tree
@@ -269,9 +274,11 @@ among the layers: those of `above-store` in front of every layer, those
269
274
  of `layer-order` where `layers.getOrder()` places them, and those of
270
275
  `below-store` behind every layer. A dataset row shows its ID (core gives
271
276
  a dataset no name), with the eye (`setVisible`) and no lock; a press on
272
- it leaves the selection as it is, and it is dragged among the layers
273
- only when its order is
274
- `layer-order`. Basemap, under it, is the back of the stack (see
277
+ it leaves the selection as it is. Every dataset is dragged among the
278
+ layers: one of `above-store` or `below-store` dropped there is moved to
279
+ `layer-order` (`draw.datasets.move`) and placed where it was dropped
280
+ (`draw.layers.reorder`), and goes back to its own order when the reorder
281
+ is refused. Basemap, under it, is the back of the stack (see
275
282
  [Basemaps](#basemaps)). The legend shows the rows of the style rule
276
283
  (`styleRule`) of each layer and of each dataset that has one, in the
277
284
  order of the stack.
@@ -306,15 +313,18 @@ ui.tools.add({
306
313
 
307
314
  The inspector is the panel on the right of `createDrawUI`. It opens
308
315
  while something is selected and closes, clearing the selection, with its
309
- close button. For one feature it shows its name (`properties.name`,
310
- changed where it stands); under it, its measurements and its description
311
- (`properties.description`, changed where it stands); then a Style tab
312
- with the fields its type reads and an Attributes tab with its other
313
- attributes. Several features
316
+ close button. On a narrow map it is a sheet from the bottom, as wide as
317
+ the map. For one feature it shows its name (`properties.name`, changed
318
+ where it stands); under it, its measurements, and the tabs, which stay
319
+ while the content scrolls: a Style tab with the fields its type reads
320
+ and an Attributes tab with its other attributes. The content of each tab
321
+ starts with its description (`properties.description`, changed where it
322
+ stands). Several features
314
323
  show the fields they share, a field whose values differ being mixed, and
315
324
  the operations that apply to them (union, intersection, difference,
316
325
  split and buffer). A layer and a group show their name, whether they are
317
- visible and whether they are locked.
326
+ visible and whether they are locked. Delete is at the start of the foot
327
+ of every inspector, for one feature and for several things selected.
318
328
 
319
329
  ```ts
320
330
  const ui = createDrawUI(draw, {
@@ -354,15 +364,27 @@ ui.inspector?.sections.add({
354
364
  ## Customize
355
365
 
356
366
  Everything the interface draws is inside its root element, which has the
357
- class `mgd-ui`, and its style sheet reaches nothing outside it. kata's
358
- tokens (the CSS custom properties `--kata-*`) are set on that element;
359
- set them on `.mgd-ui` to change the look. The `theme` option of
367
+ class `mgd-ui`, and its style sheet reaches nothing outside it but
368
+ maplibre-gl's controls of the map (see [Map controls](#map-controls)).
369
+ kata's tokens (the CSS custom properties `--kata-*`) are set on that
370
+ element; set them on `.mgd-ui` to change the look. The `theme` option of
360
371
  `createDrawUI` and of each part put alone is `light`, `dark` or `auto`
361
372
  (the default, which follows the system's `prefers-color-scheme` as it
362
373
  changes), and `ui.setTheme` changes it. kata's theme is dark;
363
374
  `data-color-mode="light"` on the root element, which `light` sets, or on
364
375
  any element around it, turns it light.
365
376
 
377
+ maplibre-gl's controls in the map's container, those of the application
378
+ too, follow the theme of `createDrawUI`: while it is on the map,
379
+ maplibre-gl's control container (`.maplibregl-control-container`) has
380
+ `data-mgd-ui-controls`, which takes kata's tokens, and the
381
+ `data-color-mode` of the root. The groups of buttons, the lines between
382
+ them, the attribution and the scale are painted with the tokens, and
383
+ maplibre-gl's icons, which are dark images, are inverted in the dark
384
+ look (`filter: invert(1)`). Set the tokens on
385
+ `[data-mgd-ui-controls]` to change their look. `destroy()` removes both
386
+ attributes.
387
+
366
388
  A button at the top right of the map switches the look: a sun while it
367
389
  is dark, a moon while it is light. It sets the theme to the look that is
368
390
  not shown, so from `auto` it keeps the one the system does not prefer;
@@ -380,7 +402,8 @@ action of the application (see [Actions](#actions)).
380
402
 
381
403
  An action of the application, such as saving the drawing or turning a
382
404
  setting on and off, is a row of a card at the bottom left of the map,
383
- above maplibre-gl's scale: a switch (`kind: 'toggle'`) or a button
405
+ above maplibre-gl's scale and, where its box reaches the card across, the
406
+ attribution: a switch (`kind: 'toggle'`) or a button
384
407
  (`kind: 'action'`), with its key at the end. A press on the row and its
385
408
  key both call `run`; a switch shows what `checked` returns, read again
386
409
  after each run and on `ui.actions.refresh()`, so the state stays with
@@ -392,7 +415,10 @@ and Shift+L) or another action uses is refused with an error. The card
392
415
  shows while there is an action, its head folds it into one button, and
393
416
  on a map narrower than 48rem it starts folded; where it would reach the
394
417
  toolbar across, it stands above the toolbar, and the layer panel
395
- floating at the left ends above it. Its title is `actionsTitle`, or the
418
+ floating at the left ends above it. The card is no taller than the map
419
+ above its place, less gap-md at the top and the button that opens the
420
+ layer panel again while it shows; the whole card scrolls when its rows
421
+ do not fit. Its title is `actionsTitle`, or the
396
422
  word for actions of the locale.
397
423
 
398
424
  ```ts
@@ -485,12 +511,21 @@ const ui = createDrawUI(draw, {
485
511
  });
486
512
  ```
487
513
 
488
- A page that adds controls of its own passes `mapControls: false`. Where
489
- the toolbar reaches a bottom corner of the map across, as on a narrow
490
- map, that corner (its controls and the attribution) is lifted above the
491
- toolbar. This is the one rule of the style sheet outside the root
492
- element: it applies to the map's container while the interface is on
493
- it.
514
+ A page that adds controls of its own passes `mapControls: false`. The
515
+ bottom corners of the map are kept clear of the interface:
516
+
517
+ - where the toolbar reaches a bottom corner across, as on a narrow map,
518
+ that corner (its controls and the attribution) is lifted above the
519
+ toolbar
520
+ - while the right panel covers the bottom right of the map, the controls
521
+ there (not the attribution) move to the left of it, gap-md apart
522
+ - where the attribution's box reaches the scale across, as the two-line
523
+ attribution of a narrow map does, the bottom left corner is lifted
524
+ above it. The attribution is only read; its compact form is
525
+ maplibre-gl's own
526
+
527
+ These are the rules of the style sheet outside the root element: they
528
+ apply to the map's container while the interface is on it.
494
529
 
495
530
  ## Development
496
531
 
@@ -1,4 +1,5 @@
1
1
  import { type ControlPosition, type IControl } from 'maplibre-gl';
2
+ import type { ShellInset } from './padding.js';
2
3
  import type { MapControlsOptions } from './types.js';
3
4
  /** The members of the map the controls use */
4
5
  export interface ControlsMap {
@@ -20,17 +21,34 @@ export interface MapControls {
20
21
  export declare function mapControls(map: ControlsMap, option: boolean | MapControlsOptions | undefined): MapControls;
21
22
  /** The attribute on the map's container while the interface lifts its bottom corners */
22
23
  export declare const LIFT_ATTRIBUTE = "data-mgd-ui-lift";
23
- /** The bottom corners of the map, lifted above the toolbar while it reaches them */
24
+ /** The bottom corners of the map, kept clear of the interface and of the attribution */
24
25
  export interface CornerLift {
25
- /** Measures again after the toolbar came, went or changed */
26
- update(): void;
26
+ /**
27
+ * Measures again after the toolbar came, went or changed, or the regions of the shell moved;
28
+ * with the inset the shell reported, which is kept until the next one
29
+ */
30
+ update(inset?: ShellInset): void;
27
31
  /** Stops following and puts the corners back */
28
32
  destroy(): void;
29
33
  }
30
34
  /**
31
- * Lifts the bottom corners of maplibre-gl's controls in `container` (the map's container) above
32
- * the toolbar of the interface in `root`, each while the toolbar reaches it across: by the
33
- * distance from the top of the toolbar to the bottom of the map. root.css moves the corners by
34
- * the custom properties this sets on the container (--mgd-ui-lift-left and --mgd-ui-lift-right).
35
+ * Keeps the bottom corners of maplibre-gl's controls in `container` (the map's container) clear
36
+ * of the interface in `root` and of the attribution. root.css moves them by the custom properties
37
+ * this sets on the container:
38
+ *
39
+ * - --mgd-ui-lift-left and --mgd-ui-lift-right lift a corner above the toolbar while the toolbar
40
+ * reaches it across, by the distance from the top of the toolbar to the bottom of the map; the
41
+ * controls of the bottom right moved to the left (below) count as reaching it where they are
42
+ * moved to
43
+ * - --mgd-ui-shift-right moves the controls of the bottom right, not the attribution, to the left
44
+ * while the right region covers the stage (the inset's right) and they are under it up and
45
+ * down: by the inset and gap-md
46
+ * - --mgd-ui-lift-left also lifts the bottom left corner above the attribution's box while that
47
+ * box reaches the corner across
48
+ *
49
+ * The boxes are measured where maplibre-gl places them, without what this moved. The attribution
50
+ * and the right region are followed with a ResizeObserver, as the toolbar and the corners are:
51
+ * the boxes are read in the observer's delivery and the custom properties are written in the next
52
+ * frame, so that what they move is not measured again in the same delivery.
35
53
  */
36
54
  export declare function cornerLift(container: HTMLElement, root: HTMLElement): CornerLift;
package/dist/index.d.ts CHANGED
@@ -31,15 +31,16 @@ export type { ActionSpec, ActionsHandle, AloneOptions, Basemap, BasemapOptions,
31
31
  *
32
32
  * It draws the toolbar, the shortcuts, the layer panel and the legend on the left, and the
33
33
  * inspector on the right while something is selected. The map's padding follows the interface:
34
- * the width of a panel that stands beside the map (on a wide container) and the toolbar's height
34
+ * the room the left panel takes (beside the map or floating over it) at the left and the sheets
35
35
  * at the bottom, so that `fitBounds` and `easeTo` keep clear of them; `destroy()` gives the map
36
36
  * its padding back. The last section of the layer panel is the basemap, whose row opens the
37
37
  * basemaps of `options.basemaps` to choose from on the right, in the place of the inspector, when
38
38
  * there are two or more. A button at the top right switches between the
39
39
  * light and the dark look, and maplibre-gl's own controls go to the bottom corners of the map (the
40
- * globe, the compass and the zoom at the right, the scale at the left); `destroy()` removes them.
41
- * The actions of the application (`options.actions`, `ui.actions`) are rows of a card at the
42
- * bottom left, above the scale, each with its key.
40
+ * globe, the compass and the zoom at the right, the scale at the left), which move out of the way
41
+ * of the toolbar, the right panel and the attribution; `destroy()` removes them. The actions of
42
+ * the application (`options.actions`, `ui.actions`) are rows of a card at the bottom left, above
43
+ * the scale and the attribution, each with its key.
43
44
  *
44
45
  * @param draw - The draw instance
45
46
  * @param options - What to show, the words and the keys