@versatiles/style 5.5.2 → 5.7.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.
@@ -193,7 +193,6 @@ export function getShortbreadLayers(option: { readonly language: Language }): Ma
193
193
  });
194
194
 
195
195
  // no links
196
- const noDrivewayExpression: LegacyFilterSpecification = ['!=', 'service', 'driveway'];
197
196
  ['track', 'pedestrian', 'service', 'living_street', 'residential', 'unclassified'].forEach(t => {
198
197
  results.push({
199
198
  id: prefix + 'street-' + t.replace(/_/g, '') + suffix,
@@ -202,7 +201,6 @@ export function getShortbreadLayers(option: { readonly language: Language }): Ma
202
201
  filter: ['all',
203
202
  ['==', 'kind', t],
204
203
  ...filter,
205
- ...(t === 'service') ? [noDrivewayExpression] : [], // ignore driveways
206
204
  ],
207
205
  });
208
206
  });
@@ -217,7 +215,6 @@ export function getShortbreadLayers(option: { readonly language: Language }): Ma
217
215
  ['==', 'kind', t],
218
216
  ['==', 'bicycle', 'designated'],
219
217
  ...filter,
220
- ...(t === 'service') ? [noDrivewayExpression] : [], // ignore driveways
221
218
  ],
222
219
  });
223
220
  });
@@ -254,8 +251,11 @@ export function getShortbreadLayers(option: { readonly language: Language }): Ma
254
251
 
255
252
  // separate outline for trains
256
253
  [':outline', ''].forEach(suffix => {
257
- // transport
258
- ['rail', 'light_rail', 'subway', 'narrow_gauge', 'tram', 'funicular', 'monorail', 'bus_guideway', 'busway'].reverse().forEach((t) => {
254
+
255
+ // with service distinction
256
+ ['rail', 'light_rail', 'subway', 'narrow_gauge', 'tram'].reverse().forEach((t) => {
257
+
258
+ // main rail
259
259
  results.push({
260
260
  id: prefix + 'transport-' + t.replace(/_/g, '') + suffix,
261
261
  type: 'line',
@@ -266,6 +266,31 @@ export function getShortbreadLayers(option: { readonly language: Language }): Ma
266
266
  ...filter,
267
267
  ],
268
268
  });
269
+
270
+ // service rail (crossover, siding, spur, yard)
271
+ results.push({
272
+ id: prefix + 'transport-' + t.replace(/_/g, '') + '-service' + suffix,
273
+ type: 'line',
274
+ 'source-layer': 'streets',
275
+ filter: ['all',
276
+ ['in', 'kind', t],
277
+ ['has', 'service'],
278
+ ...filter,
279
+ ],
280
+ });
281
+ });
282
+
283
+ // other transport
284
+ ['funicular', 'monorail', 'bus_guideway', 'busway'].reverse().forEach((t) => {
285
+ results.push({
286
+ id: prefix + 'transport-' + t.replace(/_/g, '') + suffix,
287
+ type: 'line',
288
+ 'source-layer': 'streets',
289
+ filter: ['all',
290
+ ['in', 'kind', t],
291
+ ...filter,
292
+ ],
293
+ });
269
294
  });
270
295
 
271
296
  if (c === 'street') {
@@ -15,6 +15,8 @@ describe('recolor', () => {
15
15
  brightness: 0,
16
16
  tint: 0,
17
17
  tintColor: '#FF0000',
18
+ blend: 0,
19
+ blendColor: '#000000',
18
20
  });
19
21
  });
20
22
  });
@@ -188,6 +190,50 @@ describe('recolor', () => {
188
190
  expect(colors2string(colors)).toBe('7766DD00,0033EE55,1100FFAA,221188,665C99');
189
191
  });
190
192
  });
193
+
194
+ describe('blend', () => {
195
+ it('should not blend at all', () => {
196
+ const colors = getTestColors();
197
+ recolorArray(colors, { blend: 0, blendColor: '#F00' });
198
+ expect(colors2string(colors)).toBe('FFAA5500,00FFAA55,5500FFAA,AA5500,AA7755');
199
+ });
200
+
201
+ it('should blend a little bit red', () => {
202
+ const colors = getTestColors();
203
+ recolorArray(colors, { blend: 0.5, blendColor: '#F00' });
204
+ expect(colors2string(colors)).toBe('FF552B00,80805555,AA0080AA,D52B00,D53C2B');
205
+ });
206
+
207
+ it('should blend a little bit yellow', () => {
208
+ const colors = getTestColors();
209
+ recolorArray(colors, { blend: 0.2, blendColor: '#FF0' });
210
+ expect(colors2string(colors)).toBe('FFBB4400,33FF8855,7733CCAA,BB7700,BB9244');
211
+ });
212
+
213
+ it('should blend a little bit green', () => {
214
+ const colors = getTestColors();
215
+ recolorArray(colors, { blend: 0.2, blendColor: '#0F0' });
216
+ expect(colors2string(colors)).toBe('CCBB4400,00FF8855,4433CCAA,887700,889244');
217
+ });
218
+
219
+ it('should blend a little bit blue', () => {
220
+ const colors = getTestColors();
221
+ recolorArray(colors, { blend: 0.2, blendColor: '#00F' });
222
+ expect(colors2string(colors)).toBe('CC887700,00CCBB55,4400FFAA,884433,885F77');
223
+ });
224
+
225
+ it('should blend strongly orange', () => {
226
+ const colors = getTestColors();
227
+ recolorArray(colors, { blend: 0.8, blendColor: '#F80' });
228
+ expect(colors2string(colors)).toBe('FF8F1100,CCA02255,DD6D33AA,EE7E00,EE8511');
229
+ });
230
+
231
+ it('should blend a strongly blue', () => {
232
+ const colors = getTestColors();
233
+ recolorArray(colors, { blend: 0.8, blendColor: '#00F' });
234
+ expect(colors2string(colors)).toBe('3322DD00,0033EE55,1100FFAA,2211CC,2218DD');
235
+ });
236
+ });
191
237
  });
192
238
 
193
239
  describe('recolorObject', () => {
@@ -1,31 +1,124 @@
1
+ /**
2
+ * Module for applying various color transformations such as hue rotation, saturation, contrast, brightness,
3
+ * tinting, and blending. These transformations are defined through the `RecolorOptions` interface.
4
+ */
5
+
1
6
  import { Color } from '../color/index.js';
2
7
 
8
+ /**
9
+ * Configuration options for recoloring all map colors.
10
+ *
11
+ * The transformations (if specified) are done in the following order:
12
+ * 1. [Invert brightness](#invertbrightness)
13
+ * 2. [Rotate hue](#rotate)
14
+ * 3. [Saturate](#saturate)
15
+ * 4. [Gamma correction](#gamma)
16
+ * 5. [Contrast adjustment](#contrast)
17
+ * 6. [Brightness adjustment](#brightness)
18
+ * 7. [Tinting](#tint)
19
+ * 8. [Blending](#blend)
20
+ *
21
+ * Usage Examples
22
+ *
23
+ * ```typescript
24
+ * const style = VersaTilesStyle.colorful({
25
+ * recolor: {
26
+ * rotate: 180,
27
+ * saturate: 0.5,
28
+ * brightness: 0.2,
29
+ * }
30
+ * };
31
+ * ```
32
+ *
33
+ * If you want do make you map simply brighter or darker, you can use the `blend` option:
34
+ * ```typescript
35
+ * const style = VersaTilesStyle.colorful({
36
+ * recolor: {
37
+ * blend: 0.5,
38
+ * blendColor: '#000000', // to blend all colors with black
39
+ * // or blendColor: '#FFFFFF', // to blend all colors with white
40
+ * }
41
+ * };
42
+ * ```
43
+ *
44
+ */
45
+
3
46
  export interface RecolorOptions {
4
- // If true, inverts all colors.
47
+ /**
48
+ * If true, inverts all colors' brightness.
49
+ * See also {@link HSL.invertLuminosity}
50
+ */
5
51
  invertBrightness?: boolean;
6
52
 
7
- // Rotate the hue of all colors (in degrees).
53
+ /**
54
+ * Rotate the hue of all colors in degrees (0-360).
55
+ * See also {@link HSL.rotateHue}
56
+ */
8
57
  rotate?: number;
9
58
 
10
- // Adjusts the saturation level of all colors. Positive values increase saturation, negative values decrease it.
59
+ /**
60
+ * Adjust the saturation level. Positive values increase, negative values decrease saturation.
61
+ * |value|effect |
62
+ * |----:|-----------------|
63
+ * | -1|grayscale |
64
+ * | 0|no effect |
65
+ * | 1|double saturation|
66
+ *
67
+ * See also {@link HSL.saturate}
68
+ */
11
69
  saturate?: number;
12
70
 
13
- // Adjusts the gamma of all colors. Affects the brightness in a non-linear manner.
71
+ /**
72
+ * Adjust the gamma (non-linear brightness adjustment).
73
+ * Defaults to 1.
74
+ * See also {@link RGB.gamma}
75
+ */
14
76
  gamma?: number;
15
77
 
16
- // Adjusts the contrast of all colors. Higher values produce more contrast.
78
+ /**
79
+ * Adjust the contrast level.
80
+ * Values > 1 increase contrast, values < 1 decrease it.
81
+ * Defaults to 1.
82
+ * See also {@link RGB.contrast}
83
+ */
17
84
  contrast?: number;
18
85
 
19
- // Adjusts the brightness of all colors. Positive values make it brighter, negative values make it darker.
86
+ /**
87
+ * Adjust the brightness level.
88
+ * Positive values make it brighter, negative values make it darker.
89
+ * Defaults to 0.
90
+ * See also {@link RGB.brightness}
91
+ */
20
92
  brightness?: number;
21
93
 
22
- // Specifies the intensity of the tinting effect. Ranges from 0 (no effect) to 1 (full effect).
94
+ /**
95
+ * Intensity of the tinting effect (0 = none, 1 = full effect).
96
+ * See also {@link RGB.tint}
97
+ */
23
98
  tint?: number;
24
99
 
25
- // Specifies the color used for tinting, in a string format (e.g., '#FF0000').
100
+ /**
101
+ * The tinting color in hex format (default: '#FF0000').
102
+ * See also {@link RGB.tint}
103
+ */
26
104
  tintColor?: string;
105
+
106
+ /**
107
+ * Intensity of the blending effect (0 = none, 1 = full effect).
108
+ * See also {@link RGB.blend}
109
+ */
110
+ blend?: number;
111
+
112
+ /**
113
+ * The blending color in hex format (default: '#000000').
114
+ * See also {@link RGB.blend}
115
+ */
116
+ blendColor?: string;
27
117
  }
28
118
 
119
+ /**
120
+ * Returns the default recolor settings.
121
+ */
29
122
  export function getDefaultRecolorFlags(): RecolorOptions {
30
123
  return {
31
124
  invertBrightness: false,
@@ -36,30 +129,49 @@ export function getDefaultRecolorFlags(): RecolorOptions {
36
129
  brightness: 0,
37
130
  tint: 0,
38
131
  tintColor: '#FF0000',
132
+ blend: 0,
133
+ blendColor: '#000000',
39
134
  };
40
135
  }
41
136
 
137
+ /**
138
+ * Checks if the given options object contains any active recolor transformations.
139
+ * @param opt The recolor options to validate.
140
+ */
42
141
  function isValidRecolorOptions(opt?: RecolorOptions): opt is RecolorOptions {
43
142
  if (!opt) return false;
44
- if ((opt.invertBrightness != null) && opt.invertBrightness) return true;
45
- if ((opt.rotate != null) && (opt.rotate !== 0)) return true;
46
- if ((opt.saturate != null) && (opt.saturate !== 0)) return true;
47
- if ((opt.gamma != null) && (opt.gamma !== 1)) return true;
48
- if ((opt.contrast != null) && (opt.contrast !== 1)) return true;
49
- if ((opt.brightness != null) && (opt.brightness !== 0)) return true;
50
- if ((opt.tint != null) && (opt.tint !== 0)) return true;
51
- if ((opt.tintColor != null) && (opt.tintColor !== '#FF0000')) return true;
52
- return false;
143
+ return (
144
+ opt.invertBrightness ||
145
+ (opt.rotate != null && opt.rotate !== 0) ||
146
+ (opt.saturate != null && opt.saturate !== 0) ||
147
+ (opt.gamma != null && opt.gamma !== 1) ||
148
+ (opt.contrast != null && opt.contrast !== 1) ||
149
+ (opt.brightness != null && opt.brightness !== 0) ||
150
+ (opt.tint != null && opt.tint !== 0) ||
151
+ (opt.tintColor != null && opt.tintColor !== '#FF0000') ||
152
+ (opt.blend != null && opt.blend !== 0) ||
153
+ (opt.blendColor != null && opt.blendColor !== '#000000')
154
+ );
53
155
  }
54
156
 
157
+ /**
158
+ * Applies recoloring transformations to a record of colors.
159
+ * @param colors A record of color names to `Color` instances.
160
+ * @param opt Optional recolor options.
161
+ */
55
162
  export function recolorObject(colors: Record<string, Color>, opt?: RecolorOptions): void {
56
163
  if (!isValidRecolorOptions(opt)) return;
57
164
 
58
- for (const [k, c] of Object.entries(colors)) {
59
- colors[k] = recolor(c, opt);
165
+ for (const [key, color] of Object.entries(colors)) {
166
+ colors[key] = recolor(color, opt);
60
167
  }
61
168
  }
62
169
 
170
+ /**
171
+ * Applies recoloring transformations to an array of colors.
172
+ * @param colors An array of `Color` instances.
173
+ * @param opt Optional recolor options.
174
+ */
63
175
  export function recolorArray(colors: Color[], opt?: RecolorOptions): void {
64
176
  if (!isValidRecolorOptions(opt)) return;
65
177
 
@@ -68,43 +180,58 @@ export function recolorArray(colors: Color[], opt?: RecolorOptions): void {
68
180
  }
69
181
  }
70
182
 
183
+ /**
184
+ * Caches recolored colors to optimize performance.
185
+ */
71
186
  export class CachedRecolor {
72
187
  private readonly skip: boolean;
73
-
74
188
  private readonly opt?: RecolorOptions;
75
-
76
189
  private readonly cache: Map<string, Color>;
77
190
 
191
+ /**
192
+ * Creates a cached recolor instance.
193
+ * @param opt Optional recolor options.
194
+ */
78
195
  public constructor(opt?: RecolorOptions) {
79
196
  this.skip = !isValidRecolorOptions(opt);
80
197
  this.cache = new Map();
81
198
  this.opt = opt;
82
199
  }
83
200
 
201
+ /**
202
+ * Applies cached recoloring to a given color.
203
+ * @param color The color to recolor.
204
+ * @returns The recolored color, either from cache or newly computed.
205
+ */
84
206
  public do(color: Color): Color {
85
207
  if (this.skip) return color;
86
208
 
87
209
  const key = color.asHex();
210
+ if (this.cache.has(key)) return this.cache.get(key)!;
88
211
 
89
- const result = this.cache.get(key);
90
- if (result) return result;
91
-
92
- color = recolor(color, this.opt);
93
- this.cache.set(key, color);
94
- return color;
212
+ const recolored = recolor(color, this.opt);
213
+ this.cache.set(key, recolored);
214
+ return recolored;
95
215
  }
96
216
  }
97
217
 
218
+ /**
219
+ * Applies the specified recoloring transformations to a single color.
220
+ * @param color The original color.
221
+ * @param opt Optional recolor options.
222
+ * @returns A new `Color` instance with applied transformations.
223
+ */
98
224
  export function recolor(color: Color, opt?: RecolorOptions): Color {
99
225
  if (!isValidRecolorOptions(opt)) return color;
100
226
 
101
- if (opt.invertBrightness ?? false) color = color.invertLuminosity();
102
- if ((opt.rotate !== undefined) && (opt.rotate !== 0)) color = color.rotateHue(opt.rotate);
103
- if ((opt.saturate !== undefined) && (opt.saturate !== 0)) color = color.saturate(opt.saturate);
104
- if ((opt.gamma !== undefined) && (opt.gamma !== 1)) color = color.gamma(opt.gamma);
105
- if ((opt.contrast !== undefined) && (opt.contrast !== 1)) color = color.contrast(opt.contrast);
106
- if ((opt.brightness !== undefined) && (opt.brightness !== 0)) color = color.brightness(opt.brightness);
107
- if ((opt.tint !== undefined) && (opt.tintColor !== undefined) && (opt.tint !== 0)) color = color.tint(opt.tint, Color.parse(opt.tintColor));
227
+ if (opt.invertBrightness) color = color.invertLuminosity();
228
+ if (opt.rotate) color = color.rotateHue(opt.rotate);
229
+ if (opt.saturate) color = color.saturate(opt.saturate);
230
+ if (opt.gamma != null && opt.gamma != 1) color = color.gamma(opt.gamma);
231
+ if (opt.contrast != null && opt.contrast != 1) color = color.contrast(opt.contrast);
232
+ if (opt.brightness) color = color.brightness(opt.brightness);
233
+ if (opt.tint && opt.tintColor != null) color = color.tint(opt.tint, Color.parse(opt.tintColor));
234
+ if (opt.blend && opt.blendColor != null) color = color.blend(opt.blend, Color.parse(opt.blendColor));
108
235
 
109
236
  return color;
110
237
  }
@@ -80,6 +80,8 @@ describe('StyleBuilder', () => {
80
80
  saturate: 0,
81
81
  tint: 0,
82
82
  tintColor: '#FF0000',
83
+ blend: 0,
84
+ blendColor: '#000000',
83
85
  },
84
86
  sprite: '',
85
87
  tiles: [],
@@ -4,7 +4,7 @@ import { decorate } from './decorator.js';
4
4
  import { CachedRecolor, getDefaultRecolorFlags } from './recolor.js';
5
5
  import { basename, deepClone, resolveUrl } from '../lib/utils.js';
6
6
  import type { MaplibreLayer, MaplibreLayerDefinition, StyleSpecification } from '../types/maplibre.js';
7
- import type { StyleBuilderColors, StyleBuilderColorsEnsured, StyleBuilderFonts, StyleBuilderOptions } from './types.js';
7
+ import { styleBuilderColorKeys, type StyleBuilderColors, type StyleBuilderFonts, type StyleBuilderOptions } from './types.js';
8
8
  import type { StyleRules, StyleRulesOptions } from './types.js';
9
9
  import { SpriteSpecification } from '@maplibre/maplibre-gl-style-spec';
10
10
 
@@ -37,7 +37,7 @@ export abstract class StyleBuilder {
37
37
 
38
38
  const colors = this.getColors(this.defaultColors);
39
39
  if (options.colors) {
40
- let key: keyof StyleBuilderColorsEnsured;
40
+ let key: keyof StyleBuilderColors;
41
41
  for (key in options.colors) {
42
42
  const value = options.colors[key];
43
43
  if (value != null) colors[key] = Color.parse(value);
@@ -104,9 +104,9 @@ export abstract class StyleBuilder {
104
104
  return style;
105
105
  }
106
106
 
107
- public getColors(colors: StyleBuilderColors): StyleBuilderColorsEnsured {
107
+ public getColors(colors: StyleBuilderColors): StyleBuilderColors<Color> {
108
108
  const entriesString = Object.entries(colors) as [keyof StyleBuilderColors, string | Color][];
109
- const result = Object.fromEntries(entriesString.map(([key, value]) => [key, Color.parse(value)])) as StyleBuilderColorsEnsured;
109
+ const result = Object.fromEntries(entriesString.map(([key, value]) => [key, Color.parse(value)])) as StyleBuilderColors<Color>;
110
110
  return result;
111
111
  }
112
112
 
@@ -114,9 +114,9 @@ export abstract class StyleBuilder {
114
114
  return {
115
115
  baseUrl: '',
116
116
  bounds: [
117
- -180,
118
- -85.0511287798066,
119
- 180,
117
+ -180,
118
+ -85.0511287798066,
119
+ 180,
120
120
  85.0511287798066
121
121
  ],
122
122
  glyphs: '',
@@ -132,8 +132,7 @@ export abstract class StyleBuilder {
132
132
 
133
133
  protected transformDefaultColors(callback: (color: Color) => Color): void {
134
134
  const colors = this.getColors(this.defaultColors);
135
- let key: keyof StyleBuilderColorsEnsured;
136
- for (key in colors) {
135
+ for (const key of styleBuilderColorKeys) {
137
136
  this.defaultColors[key] = callback(colors[key]);
138
137
  }
139
138
  }
@@ -5,113 +5,78 @@ import { SpriteSpecification } from '@maplibre/maplibre-gl-style-spec';
5
5
  /** Represents language suffixes used in map styles. */
6
6
  export type Language = 'de' | 'en' | null;
7
7
 
8
- /** Options for configuring a style builder. */
8
+ /**
9
+ * Options for configuring the style builder.
10
+ */
9
11
  export interface StyleBuilderOptions {
10
12
  /**
11
13
  * The base URL for loading external resources like tiles, sprites, and fonts.
12
- * Default: document.location.origin (in the browser), or 'https://tiles.versatiles.org'
14
+ * @default document.location.origin (in the browser), or 'https://tiles.versatiles.org'
13
15
  */
14
16
  baseUrl?: string;
15
17
 
16
- /**
17
- * The bounding box for the map, formatted as [sw.lng, sw.lat, ne.lng, ne.lat].
18
- * Default: [-180, -85.0511287798066, 180, 85.0511287798066]
19
- */
20
- bounds?: [number, number, number, number];
18
+ /**
19
+ * The bounding box for the map, formatted as [sw.lng, sw.lat, ne.lng, ne.lat].
20
+ * @default [-180, -85.0511287798066, 180, 85.0511287798066]
21
+ */
22
+ bounds?: [number, number, number, number];
21
23
 
22
24
  /**
23
25
  * The URL template for loading font glyphs, formatted with '{fontstack}' and '{range}' placeholders.
24
- * Default: '/assets/glyphs/{fontstack}/{range}.pbf'
26
+ * @default '/assets/glyphs/{fontstack}/{range}.pbf'
25
27
  */
26
28
  glyphs?: string;
27
29
 
28
30
  /**
29
31
  * The URL for loading sprite images and metadata.
30
- * Default: [{ id: 'basics', url: '/assets/sprites/basics/sprites' }]
32
+ * @default [{ id: 'basics', url: '/assets/sprites/basics/sprites' }]
31
33
  */
32
34
  sprite?: SpriteSpecification;
33
35
 
34
36
  /**
35
37
  * An array of URL templates for loading map tiles, using '{z}', '{x}', and '{y}' placeholders.
36
- * Default: ['/tiles/osm/{z}/{x}/{y}']
38
+ * @default ['/tiles/osm/{z}/{x}/{y}']
37
39
  */
38
40
  tiles?: string[];
39
41
 
40
42
  /**
41
43
  * If set to true, hides all map labels.
42
- * Default: false
44
+ * @default false
43
45
  */
44
46
  hideLabels?: boolean;
45
47
 
46
48
  /**
47
49
  * Set the language ('en', 'de') of all map labels.
48
50
  * A null value means that the language of the country in which the label is drawn will be used.
49
- * Default: null
51
+ * See also: {@link Language}
52
+ * @default null
50
53
  */
51
54
  language?: Language;
52
55
 
53
56
  /**
54
57
  * An object specifying overrides for default color values, keyed by the color names.
58
+ * See also: {@link StyleBuilderColors}
55
59
  */
56
60
  colors?: Partial<StyleBuilderColors>;
57
61
 
58
62
  /**
59
63
  * An object specifying overrides for default font names, keyed by the font names.
64
+ * See also: {@link StyleBuilderFonts}
60
65
  */
61
66
  fonts?: Partial<StyleBuilderFonts>;
62
67
 
63
68
  /**
64
69
  * Options for color adjustments and transformations applied to the entire style.
70
+ * See also: {@link RecolorOptions}
65
71
  */
66
72
  recolor?: RecolorOptions;
67
73
  }
68
74
 
69
- /** Records string values for color properties in a style builder. */
70
- export interface StyleBuilderColors {
71
- agriculture: Color | string;
72
- boundary: Color | string;
73
- building: Color | string;
74
- buildingbg: Color | string;
75
- burial: Color | string;
76
- commercial: Color | string;
77
- construction: Color | string;
78
- cycle: Color | string;
79
- danger: Color | string;
80
- disputed: Color | string;
81
- education: Color | string;
82
- foot: Color | string;
83
- glacier: Color | string;
84
- grass: Color | string;
85
- hospital: Color | string;
86
- industrial: Color | string;
87
- label: Color | string;
88
- labelHalo: Color | string;
89
- land: Color | string;
90
- leisure: Color | string;
91
- motorway: Color | string;
92
- motorwaybg: Color | string;
93
- park: Color | string;
94
- parking: Color | string;
95
- poi: Color | string;
96
- prison: Color | string;
97
- rail: Color | string;
98
- residential: Color | string;
99
- rock: Color | string;
100
- sand: Color | string;
101
- shield: Color | string;
102
- street: Color | string;
103
- streetbg: Color | string;
104
- subway: Color | string;
105
- symbol: Color | string;
106
- trunk: Color | string;
107
- trunkbg: Color | string;
108
- waste: Color | string;
109
- water: Color | string;
110
- wetland: Color | string;
111
- wood: Color | string;
112
- };
75
+ export type StyleBuilderColorKey = 'agriculture' | 'boundary' | 'building' | 'buildingbg' | 'burial' | 'commercial' | 'construction' | 'cycle' | 'danger' | 'disputed' | 'education' | 'foot' | 'glacier' | 'grass' | 'hospital' | 'industrial' | 'label' | 'labelHalo' | 'land' | 'leisure' | 'motorway' | 'motorwaybg' | 'park' | 'parking' | 'poi' | 'prison' | 'rail' | 'residential' | 'rock' | 'sand' | 'shield' | 'street' | 'streetbg' | 'subway' | 'symbol' | 'trunk' | 'trunkbg' | 'waste' | 'water' | 'wetland' | 'wood';
76
+ export const styleBuilderColorKeys: StyleBuilderColorKey[] = ['agriculture', 'boundary', 'building', 'buildingbg', 'burial', 'commercial', 'construction', 'cycle', 'danger', 'disputed', 'education', 'foot', 'glacier', 'grass', 'hospital', 'industrial', 'label', 'labelHalo', 'land', 'leisure', 'motorway', 'motorwaybg', 'park', 'parking', 'poi', 'prison', 'rail', 'residential', 'rock', 'sand', 'shield', 'street', 'streetbg', 'subway', 'symbol', 'trunk', 'trunkbg', 'waste', 'water', 'wetland', 'wood'] as const;
113
77
 
114
- export type StyleBuilderColorsEnsured = Record<keyof StyleBuilderColors, Color>;
78
+ /** Records string values for color properties in a style builder. */
79
+ export type StyleBuilderColors<T = Color | string> = Record<StyleBuilderColorKey, T>;
115
80
 
116
81
  /** Records string values for font properties in a style builder. */
117
82
  export type StyleBuilderFonts = {
@@ -124,7 +89,7 @@ export interface StyleRulesOptions {
124
89
  /**
125
90
  * The set of colors used in the style builder.
126
91
  */
127
- colors: StyleBuilderColorsEnsured;
92
+ colors: StyleBuilderColors<Color>;
128
93
 
129
94
  /**
130
95
  * The set of fonts used in the style builder.