From eaadd9cd8b5d4b49652c17b0a0a78231f7df86c2 Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Thu, 11 Jun 2026 20:30:40 +0200 Subject: [PATCH 1/8] traffic-style: fix missing default icon Signed-off-by: Paul Golmann --- .../scripts/dev/import-fontawesome.ts | 77 +++++++++++++++++++ .../traffic-style/src/icons/ort-default.svg | 1 + .../traffic-style/src/icons/ort-plain.svg | 1 + .../traffic-style/src/icons/ort-small.svg | 1 + .../traffic-style/src/icons/ort-xsmall.svg | 1 + packages/traffic-style/src/meta.json | 8 ++ .../traffic-style/src/pictograms/place.svg | 1 + 7 files changed, 90 insertions(+) create mode 100644 packages/traffic-style/src/icons/ort-default.svg create mode 100644 packages/traffic-style/src/icons/ort-plain.svg create mode 100644 packages/traffic-style/src/icons/ort-small.svg create mode 100644 packages/traffic-style/src/icons/ort-xsmall.svg create mode 100644 packages/traffic-style/src/pictograms/place.svg diff --git a/packages/traffic-style/scripts/dev/import-fontawesome.ts b/packages/traffic-style/scripts/dev/import-fontawesome.ts index 75049b4c..b477c3d9 100644 --- a/packages/traffic-style/scripts/dev/import-fontawesome.ts +++ b/packages/traffic-style/scripts/dev/import-fontawesome.ts @@ -5,16 +5,26 @@ import {fileURLToPath} from "node:url"; import { faBicycle, + faBiking, faBolt, faBus, faCar, faChargingStation, + faCloudRain, + faCloudSunRain, + faDroplet, faHospital, + faInfo, + faLeaf, faLocationDot, faMugHot, faSchool, + faTemperatureHigh, faTree, + faUsers, faUtensils, + faVanShuttle, + faWater, } from "@fortawesome/free-solid-svg-icons"; import type {IconDefinition} from "@fortawesome/free-solid-svg-icons"; @@ -98,6 +108,73 @@ const icons: FaIconEntry[] = [ label: {de: "Marker", en: "Marker"}, icon: faLocationDot, }, + // Smart City + { + exportName: "faWater", + id: "fa-water", + label: {de: "Wasser", en: "Water"}, + icon: faWater, + }, + { + exportName: "faDroplet", + id: "fa-water-lower", + label: {de: "Niedriger Wasserstand", en: "Low water level"}, + icon: faDroplet, + }, + { + exportName: "faBiking", + id: "fa-biking", + label: {de: "Radverkehr", en: "Cycling"}, + icon: faBiking, + }, + { + exportName: "faUsers", + id: "fa-users", + label: {de: "Personen", en: "People"}, + icon: faUsers, + }, + { + exportName: "faVanShuttle", + id: "fa-car-bus", + label: {de: "Verkehr", en: "Traffic"}, + icon: faVanShuttle, + }, + { + exportName: "faCloudRain", + id: "fa-cloud-rain", + label: {de: "Regen", en: "Rain"}, + icon: faCloudRain, + }, + { + exportName: "faCloudSunRain", + id: "fa-thunderstorm-sun", + label: {de: "Gewitter", en: "Thunderstorm"}, + icon: faCloudSunRain, + }, + { + exportName: "faTree", + id: "fa-tree-alt", + label: {de: "Bäume", en: "Trees"}, + icon: faTree, + }, + { + exportName: "faLeaf", + id: "fa-leaf-heart", + label: {de: "Umwelt", en: "Environment"}, + icon: faLeaf, + }, + { + exportName: "faInfo", + id: "fa-info", + label: {de: "Info", en: "Info"}, + icon: faInfo, + }, + { + exportName: "faTemperatureHigh", + id: "fa-temperature-high", + label: {de: "Temperatur", en: "Temperature"}, + icon: faTemperatureHigh, + }, ]; function iconToMarkup(icon: IconDefinition): {viewBox: string; markup: string} { diff --git a/packages/traffic-style/src/icons/ort-default.svg b/packages/traffic-style/src/icons/ort-default.svg new file mode 100644 index 00000000..06f91fad --- /dev/null +++ b/packages/traffic-style/src/icons/ort-default.svg @@ -0,0 +1 @@ +mapsight-icons-svg/icn/poi/ort-plain \ No newline at end of file diff --git a/packages/traffic-style/src/icons/ort-plain.svg b/packages/traffic-style/src/icons/ort-plain.svg new file mode 100644 index 00000000..21634d69 --- /dev/null +++ b/packages/traffic-style/src/icons/ort-plain.svg @@ -0,0 +1 @@ +mapsight-icons-svg/icn/poi/ort-plain \ No newline at end of file diff --git a/packages/traffic-style/src/icons/ort-small.svg b/packages/traffic-style/src/icons/ort-small.svg new file mode 100644 index 00000000..fc2d322a --- /dev/null +++ b/packages/traffic-style/src/icons/ort-small.svg @@ -0,0 +1 @@ +mapsight-icons-svg/icn/poi/ort-plain \ No newline at end of file diff --git a/packages/traffic-style/src/icons/ort-xsmall.svg b/packages/traffic-style/src/icons/ort-xsmall.svg new file mode 100644 index 00000000..574d8299 --- /dev/null +++ b/packages/traffic-style/src/icons/ort-xsmall.svg @@ -0,0 +1 @@ +mapsight-icons-svg/icn/poi/ort-plain \ No newline at end of file diff --git a/packages/traffic-style/src/meta.json b/packages/traffic-style/src/meta.json index 50295ebb..4692ffa9 100644 --- a/packages/traffic-style/src/meta.json +++ b/packages/traffic-style/src/meta.json @@ -634,6 +634,14 @@ }, "aliases": [], "groups": ["default", "poi", "poi-generic"], + "render": "sprite" + }, + "place": { + "label": { + "de": "Ort (farbig)", + "en": "Place (custom colors)" + }, + "groups": ["default", "poi", "poi-generic"], "render": "composable" }, "p": { diff --git a/packages/traffic-style/src/pictograms/place.svg b/packages/traffic-style/src/pictograms/place.svg new file mode 100644 index 00000000..274eb917 --- /dev/null +++ b/packages/traffic-style/src/pictograms/place.svg @@ -0,0 +1 @@ +mapsight-icons-svg/icn/poi/ort-plain From d974f3d820e0b1da7cd752fa37d8006f92c188c0 Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Thu, 11 Jun 2026 20:31:02 +0200 Subject: [PATCH 2/8] traffic-style: add font-awesome smart city icons Signed-off-by: Paul Golmann --- packages/traffic-style/scripts/lib/meta.ts | 9 +- packages/traffic-style/src/meta.json | 104 +++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/packages/traffic-style/scripts/lib/meta.ts b/packages/traffic-style/scripts/lib/meta.ts index cb22a0db..8fc2bf8a 100644 --- a/packages/traffic-style/scripts/lib/meta.ts +++ b/packages/traffic-style/scripts/lib/meta.ts @@ -9,6 +9,13 @@ export const IconVariantSchema = z.stringFormat( export type IconId = z.infer; export const IconIdSchema = z.stringFormat("mapsight-icon-id", /[0-9a-z-]+/); +/** Platform ids and legacy names may use camelCase (e.g. bicycleCount). */ +export type IconAlias = z.infer; +export const IconAliasSchema = z.stringFormat( + "mapsight-icon-alias", + /[0-9a-zA-Z-]+/, +); + export type LangCode = z.infer; export const LangCodeSchema = z.stringFormat("mapsight-lang-code", /[a-z]{2}/); @@ -33,7 +40,7 @@ export const IconMetaSchema = z.object({ // and string values for the text. id: IconIdSchema, label: z.record(LangCodeSchema, z.string()).optional(), - aliases: z.array(IconIdSchema).optional(), + aliases: z.array(IconAliasSchema).optional(), groups: z.array(IconGroupNameSchema).optional(), render: IconRenderModeSchema.optional(), colors: IconColorsSchema.optional(), diff --git a/packages/traffic-style/src/meta.json b/packages/traffic-style/src/meta.json index 4692ffa9..9ebd1bde 100644 --- a/packages/traffic-style/src/meta.json +++ b/packages/traffic-style/src/meta.json @@ -404,6 +404,15 @@ "groups": ["poi", "poi-transport"], "render": "composable" }, + "fa-biking": { + "label": { + "de": "Radverkehr", + "en": "Bicycle traffic" + }, + "aliases": ["bicycleCount"], + "groups": ["smart-city"], + "render": "composable" + }, "fa-bolt": { "label": { "de": "Energie", @@ -440,6 +449,15 @@ "groups": ["poi", "poi-transport"], "render": "composable" }, + "fa-car-bus": { + "label": { + "de": "KFZ-Verkehr", + "en": "Motor vehicle traffic" + }, + "aliases": ["carCount"], + "groups": ["smart-city"], + "render": "composable" + }, "fa-charging-station": { "label": { "de": "Ladestation (FA)", @@ -449,6 +467,15 @@ "groups": ["poi", "poi-services"], "render": "composable" }, + "fa-cloud-rain": { + "label": { + "de": "Niederschlag", + "en": "Precipitation" + }, + "aliases": ["weatherRain"], + "groups": ["smart-city"], + "render": "composable" + }, "fa-hospital": { "label": { "de": "Krankenhaus", @@ -458,6 +485,24 @@ "groups": ["poi", "poi-services"], "render": "composable" }, + "fa-info": { + "label": { + "de": "KFZ-Verkehr", + "en": "Motor vehicle traffic" + }, + "aliases": ["carCount"], + "groups": ["smart-city"], + "render": "composable" + }, + "fa-leaf-heart": { + "label": { + "de": "Luftqualität (PM10), Windgeschwindigkeit", + "en": "Air quality (PM10), wind speed" + }, + "aliases": ["airQualityPM10", "weatherWindSpeed"], + "groups": ["smart-city"], + "render": "composable" + }, "fa-marker": { "label": { "de": "Marker (FA)", @@ -476,6 +521,29 @@ "groups": ["poi", "poi-services"], "render": "composable" }, + "fa-temperature-high": { + "label": { + "de": "Wassertemperatur", + "en": "Water temperature" + }, + "aliases": ["waterTemp"], + "groups": ["smart-city"], + "render": "composable" + }, + "fa-thunderstorm-sun": { + "label": { + "de": "Luftfeuchtigkeit, Niederschlag, Lufttemperatur, Windgeschwindigkeit", + "en": "Humidity, precipitation, air temperature, wind speed" + }, + "aliases": [ + "weatherHumidity", + "weatherRain", + "weatherTemp", + "weatherWindSpeed" + ], + "groups": ["smart-city"], + "render": "composable" + }, "fa-tree": { "label": { "de": "Park", @@ -485,6 +553,24 @@ "groups": ["poi", "poi-leisure"], "render": "composable" }, + "fa-tree-alt": { + "label": { + "de": "Luftfeuchtigkeit, Lufttemperatur", + "en": "Humidity, air temperature" + }, + "aliases": ["weatherHumidity", "weatherTemp"], + "groups": ["smart-city"], + "render": "composable" + }, + "fa-users": { + "label": { + "de": "Passanten", + "en": "Pedestrians" + }, + "aliases": ["peopleCount"], + "groups": ["smart-city"], + "render": "composable" + }, "fa-utensils": { "label": { "de": "Gastronomie", @@ -494,6 +580,24 @@ "groups": ["poi", "poi-leisure"], "render": "composable" }, + "fa-water": { + "label": { + "de": "Wasserstand, Wassertemperatur, Lufttemperatur", + "en": "Water level, water temperature, air temperature" + }, + "aliases": ["waterLevelSurface", "waterTemp", "weatherTemp"], + "groups": ["smart-city"], + "render": "composable" + }, + "fa-water-lower": { + "label": { + "de": "Wasserstand, Wassertemperatur", + "en": "Water level, water temperature" + }, + "aliases": ["waterLevelSurface", "waterTemp"], + "groups": ["smart-city"], + "render": "composable" + }, "info": { "label": { "de": "Info", From ee56f317efbc07154ab6ebd333a9251e4111a82d Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Thu, 11 Jun 2026 21:25:13 +0200 Subject: [PATCH 3/8] traffic-style: fix padding for sprite icons Signed-off-by: Paul Golmann --- packages/traffic-style/scripts/traffic-icon-sprite.ts | 6 ++---- packages/traffic-style/src/scss/_icons-1x.scss | 4 +++- packages/traffic-style/src/scss/_icons-2x.scss | 4 +++- packages/traffic-style/src/scss/_variables.scss | 1 + packages/traffic-style/src/scss/default.scss | 7 +------ .../src/scss/mixins/_get-icon-dimensions.scss | 11 +++++++---- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/traffic-style/scripts/traffic-icon-sprite.ts b/packages/traffic-style/scripts/traffic-icon-sprite.ts index be253963..1873f6cc 100644 --- a/packages/traffic-style/scripts/traffic-icon-sprite.ts +++ b/packages/traffic-style/scripts/traffic-icon-sprite.ts @@ -228,10 +228,8 @@ async function buildIcons(opts: Options): Promise { }); const composites = items.map((item) => ({ input: item.meta.buffer, - left: item.x, - top: item.y, - width: item.width, - height: item.height, + left: item.x + marginNum, + top: item.y + marginNum, })); await spriteSharp.composite(composites).png({effort: 10}).toFile(pngFile); console.log(`Generated PNG: ${pngFile} (${layoutWidth}x${layoutHeight})`); diff --git a/packages/traffic-style/src/scss/_icons-1x.scss b/packages/traffic-style/src/scss/_icons-1x.scss index 480d184d..1a22a589 100644 --- a/packages/traffic-style/src/scss/_icons-1x.scss +++ b/packages/traffic-style/src/scss/_icons-1x.scss @@ -1,9 +1,11 @@ -@use "../../mapsight-traffic-style-icon-sprite-1x" as sprite; +@use "../../dist/mapsight-traffic-style-icon-sprite-1x" as sprite; $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: "/img/mapsight-traffic-style-icon-sprite-1x.png?v=2023-08-07-16-00" !default; $MAPSIGHT_TRAFFIC_STYLE__ICONS: sprite.$mapsight-traffic-style-icon-sprite-1x !default; +$MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING: 4 !default; @use "./variables" with ( $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH, $MAPSIGHT_TRAFFIC_STYLE__ICONS: $MAPSIGHT_TRAFFIC_STYLE__ICONS, + $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING: $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING, ); diff --git a/packages/traffic-style/src/scss/_icons-2x.scss b/packages/traffic-style/src/scss/_icons-2x.scss index f1db00e3..3fe1838e 100644 --- a/packages/traffic-style/src/scss/_icons-2x.scss +++ b/packages/traffic-style/src/scss/_icons-2x.scss @@ -1,9 +1,11 @@ -@use "../../mapsight-traffic-style-icon-sprite-2x" as sprite; +@use "../../dist/mapsight-traffic-style-icon-sprite-2x" as sprite; $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: "/img/mapsight-traffic-style-icon-sprite-2x.png?v=2023-08-07-16-00" !default; $MAPSIGHT_TRAFFIC_STYLE__ICONS: sprite.$mapsight-traffic-style-icon-sprite-2x !default; +$MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING: 4 !default; @use "./variables" with ( $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH, $MAPSIGHT_TRAFFIC_STYLE__ICONS: $MAPSIGHT_TRAFFIC_STYLE__ICONS, + $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING: $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING, ); diff --git a/packages/traffic-style/src/scss/_variables.scss b/packages/traffic-style/src/scss/_variables.scss index d236561e..7c01be4e 100644 --- a/packages/traffic-style/src/scss/_variables.scss +++ b/packages/traffic-style/src/scss/_variables.scss @@ -14,6 +14,7 @@ $MAPSIGHT_TRAFFIC_STYLE__IMG_BASE_SCALE: 0.5 !default; $MAPSIGHT_TRAFFIC_STYLE__IMAGE_PATH: "img/" !default; $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: $MAPSIGHT_TRAFFIC_STYLE__IMAGE_PATH + "sprite.png" !default; +$MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING: 0 !default; $MAPSIGHT_TRAFFIC_STYLE__ICONS: ( "ort": ( x: 0, diff --git a/packages/traffic-style/src/scss/default.scss b/packages/traffic-style/src/scss/default.scss index 234ed433..e0bbe647 100644 --- a/packages/traffic-style/src/scss/default.scss +++ b/packages/traffic-style/src/scss/default.scss @@ -1,10 +1,5 @@ // This file is only used to supply pre-compiled style in default.js // do NOT import this anywhere -@use "../../dist/mapsight-traffic-style-icon-sprite-2x" as icons; - -@use "./variables" with ( - $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: "img/mapsight-traffic-style-icon-sprite-2x.png?v=2023-08-07-16-00", - $MAPSIGHT_TRAFFIC_STYLE__ICONS: icons.$mapsight-traffic-style-icon-sprite-2x -); +@use "icons-2x"; @use "./full"; diff --git a/packages/traffic-style/src/scss/mixins/_get-icon-dimensions.scss b/packages/traffic-style/src/scss/mixins/_get-icon-dimensions.scss index 89a4cb77..756727c9 100644 --- a/packages/traffic-style/src/scss/mixins/_get-icon-dimensions.scss +++ b/packages/traffic-style/src/scss/mixins/_get-icon-dimensions.scss @@ -1,12 +1,15 @@ @use "sass:map"; +@use "../variables"; + @mixin getIconDimension($dimensions) { + $padding: variables.$MAPSIGHT_TRAFFIC_STYLE__SPRITE_PADDING; $x: map.get($dimensions, x); $y: map.get($dimensions, y); $width: map.get($dimensions, width); $height: map.get($dimensions, height); - icon-offsetX: $x; - icon-offsetY: $y; - icon-sizeX: $width; - icon-sizeY: $height; + icon-offsetX: $x + $padding; + icon-offsetY: $y + $padding; + icon-sizeX: $width - 2 * $padding; + icon-sizeY: $height - 2 * $padding; } From da9ca4d0ae2a12225fbbe0f7b4a9f7a47872861c Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Thu, 11 Jun 2026 21:25:27 +0200 Subject: [PATCH 4/8] traffic-style: fix missing default.js Signed-off-by: Paul Golmann --- packages/traffic-style/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/traffic-style/package.json b/packages/traffic-style/package.json index d0487d81..e5fb345d 100644 --- a/packages/traffic-style/package.json +++ b/packages/traffic-style/package.json @@ -104,7 +104,7 @@ "build:pictograms:traffic-style": "node scripts/dev/import-pictograms.ts", "build:scripts": "rimraf dist/scripts && tsc --project tsconfig.scripts.json", "build:setup": "mkdirp dist/docs && mkdirp dist/img", - "build:styles": "vector-style-compiler src/scss/default.scss --output tmp/mapsight-vector-styles --name default && cp tmp/mapsight-vector-styles/default.css dist", + "build:styles": "vector-style-compiler src/scss/default.scss --output tmp/mapsight-vector-styles --name default && cp tmp/mapsight-vector-styles/default.js dist && cp tmp/mapsight-vector-styles/default.css dist", "clean": "rimraf tmp/* dist/*", "clean-build": "run-s clean build", "copy": "run-p copy:src copy:misc", From ea72c4bb2c3d9e8095b1bd618ca6e4a133c9afb5 Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Thu, 11 Jun 2026 21:28:19 +0200 Subject: [PATCH 5/8] traffic-style: improve how different icon types (sprite or runtime) work together and how the fallback to a default icon works Signed-off-by: Paul Golmann --- .../traffic-style/docs/CUSTOMIZING_SCSS.md | 12 +-- .../traffic-style/docs/CUSTOM_ICON_BUILDS.md | 2 +- .../traffic-style/docs/ICON_INTEGRATION.md | 12 --- packages/traffic-style/docs/RUNTIME_ICONS.md | 12 +-- packages/traffic-style/src/lib/icon-meta.ts | 3 +- .../traffic-style/src/scss/_variables.scss | 7 +- .../src/scss/features/_base.scss | 68 +++----------- .../src/scss/mixins/_auto-icon.scss | 25 +++-- .../scss/mixins/_runtime-icon-dimensions.scss | 19 ++++ .../src/scss/mixins/_runtime-icon.scss | 92 +++++++++++++++++++ .../js/plugins/common/runtime-icon-style.ts | 5 + 11 files changed, 161 insertions(+), 96 deletions(-) create mode 100644 packages/traffic-style/src/scss/mixins/_runtime-icon-dimensions.scss create mode 100644 packages/traffic-style/src/scss/mixins/_runtime-icon.scss diff --git a/packages/traffic-style/docs/CUSTOMIZING_SCSS.md b/packages/traffic-style/docs/CUSTOMIZING_SCSS.md index 7c3b1f7e..7a46ecf0 100644 --- a/packages/traffic-style/docs/CUSTOMIZING_SCSS.md +++ b/packages/traffic-style/docs/CUSTOMIZING_SCSS.md @@ -53,7 +53,6 @@ overrides into `variables`: @use "@mapsight/traffic-style/src/scss/icons-2x" with ( $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: "/img/mapsight-traffic-style-icon-sprite-2x.png?v=2026-01-01", - $MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED: true, $MAPSIGHT_TRAFFIC_STYLE__FEATURES_BASE_ZOOM_DEFAULT: 14 ); @@ -170,13 +169,12 @@ these zoom thresholds. The compact `mapsightIconId` string does not carry varian ### Runtime (composable) icons -| Variable | Default | Effect | -| ------------------------------------------------ | ------- | ---------------------------------------------------- | -| `$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED` | `true` | Emit `mapsightRuntimeIcon` rules in `features/_base` | -| `$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SCALE` | `0.5` | Icon scale for client-composed icons | +| Variable | Default | Effect | +| --------------------------------------------- | ------- | ------------------------------------ | +| `$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SCALE` | `0.5` | Icon scale for client-composed icons | -When enabled, composable `mapsightIconId` values are drawn at runtime; sprite ids -are still routed to the sheet via `auto-icon` mixins. +Composable `mapsightIconId` values are drawn at runtime; sprite ids are still +routed to the sheet via `auto-icon` mixins. ### Global geometry and labels diff --git a/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md b/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md index 06c18ec4..fe092f00 100644 --- a/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md +++ b/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md @@ -33,7 +33,7 @@ pre-optimized icon PNGs in the package. Icons with `"render": "composable"` in ### Example -From a consuming app (similar to `apps/braunschweig`): +From a consuming app (similar to a private host app under `private/apps/`): ```json { diff --git a/packages/traffic-style/docs/ICON_INTEGRATION.md b/packages/traffic-style/docs/ICON_INTEGRATION.md index 956813a5..11168fdb 100644 --- a/packages/traffic-style/docs/ICON_INTEGRATION.md +++ b/packages/traffic-style/docs/ICON_INTEGRATION.md @@ -116,18 +116,6 @@ needed in production map bundles. --- -## Disable runtime icons - -Set `$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED: false` in the **first** -`@use` of `variables` (together with sprite settings). The `icons-2x` shim only -forwards sprite path variables — use the manual pattern from -[CUSTOMIZING_SCSS.md](CUSTOMIZING_SCSS.md) when toggling runtime icons. - -Composable catalog icons will not render on the map; sprite `auto-icon` rules still -apply. - ---- - ## Direct API reference | Import path | Use | diff --git a/packages/traffic-style/docs/RUNTIME_ICONS.md b/packages/traffic-style/docs/RUNTIME_ICONS.md index 8dbb521b..34ed6ccd 100644 --- a/packages/traffic-style/docs/RUNTIME_ICONS.md +++ b/packages/traffic-style/docs/RUNTIME_ICONS.md @@ -238,7 +238,7 @@ Dev helpers: `defaultIconCache.getStats()`, `prewarmCatalog()` via `runtime-dev` ### Declaring runtime icons in SCSS -`src/scss/features/_base.scss` (when `$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED`): +`src/scss/features/_base.scss`: ```scss [mapsightIconId] { @@ -366,16 +366,6 @@ Variant is selected in SCSS (zoom selectors), not in `mapsightIconId`. --- -## Disabling runtime icons - -```scss -$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED: false; -``` - -Composable catalog icons will not render on the map (sprite `auto-icon` rules still apply). - ---- - ## Testing Run unit tests with `pnpm test` in this package. diff --git a/packages/traffic-style/src/lib/icon-meta.ts b/packages/traffic-style/src/lib/icon-meta.ts index 8051367b..dcb87582 100644 --- a/packages/traffic-style/src/lib/icon-meta.ts +++ b/packages/traffic-style/src/lib/icon-meta.ts @@ -13,7 +13,8 @@ type SourceMeta = { const sourceMeta = meta as SourceMeta; export function getIconRenderMode(id: string): IconRenderMode { - const icon = sourceMeta.icons?.[id]; + const baseId = id.split("/")[0]!; + const icon = sourceMeta.icons?.[baseId]; return icon?.render ?? "sprite"; } diff --git a/packages/traffic-style/src/scss/_variables.scss b/packages/traffic-style/src/scss/_variables.scss index 7c01be4e..93d2cf02 100644 --- a/packages/traffic-style/src/scss/_variables.scss +++ b/packages/traffic-style/src/scss/_variables.scss @@ -50,5 +50,10 @@ $MAPSIGHT_TRAFFIC_STYLE__ICON_FALLBACK_MAP: ( $MAPSIGHT_TRAFFIC_STYLE__ICON_ENABLE_FORCE_BY_ENV: true !default; -$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED: true !default; $MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SCALE: 0.5 !default; +$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_PIXEL_RATIO: 2 !default; +$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SIZES: ( + "default": 40px, + "small": 28px, + "xsmall": 22px, +) !default; diff --git a/packages/traffic-style/src/scss/features/_base.scss b/packages/traffic-style/src/scss/features/_base.scss index 1591cdfb..f188dcd2 100644 --- a/packages/traffic-style/src/scss/features/_base.scss +++ b/packages/traffic-style/src/scss/features/_base.scss @@ -2,6 +2,7 @@ @use "../mixins/icon-base"; @use "../mixins/icon"; @use "../mixins/auto-icon"; +@use "../mixins/runtime-icon"; #features { stroke-width: 4; @@ -9,65 +10,23 @@ // Icon @include icon-base.iconBase; - @if variables.$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED { - [mapsightIconId], - [env|mapsightIconId] { - image-type: icon; - - icon: { - scale: variables.$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SCALE; - src: calc( - mapsightRuntimeIcon( - attr(mapsightIconId), - "default" - ) - ); - snapToPixel: true; - } - } - } - + @include auto-icon.autoIconDefault(); + @include runtime-icon.runtimeIcon("default"); @include auto-icon.autoIcon("default"); - @if variables.$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICONS_ENABLED { - [|js="env.zoom < #{variables.$MAPSIGHT_TRAFFIC_STYLE__FEATURES_BASE_ZOOM_SMALL}"] - :not([state="highlight"]) - :not([state="select"]) { - [mapsightIconId], - [env|mapsightIconId] { - icon-src: calc( - mapsightRuntimeIcon( - attr(mapsightIconId), - "xsmall" - ) - ); - } - } - - [|js="env.zoom >= #{variables.$MAPSIGHT_TRAFFIC_STYLE__FEATURES_BASE_ZOOM_SMALL} && env.zoom < #{variables.$MAPSIGHT_TRAFFIC_STYLE__FEATURES_BASE_ZOOM_DEFAULT}"] - :not([state="highlight"]) - :not([state="select"]) { - [mapsightIconId], - [env|mapsightIconId] { - icon-src: calc( - mapsightRuntimeIcon( - attr(mapsightIconId), - "small" - ) - ); - } - } - } - [|js="env.zoom < #{variables.$MAPSIGHT_TRAFFIC_STYLE__FEATURES_BASE_ZOOM_SMALL}"] - :not([state="highlight"]) - :not([state="select"]) { + :not([state="highlight"]) + :not([state="select"]) { + @include auto-icon.autoIconDefault("xsmall"); + @include runtime-icon.runtimeIconSrc("xsmall"); @include auto-icon.autoIcon("xsmall"); } [|js="env.zoom >= #{variables.$MAPSIGHT_TRAFFIC_STYLE__FEATURES_BASE_ZOOM_SMALL} && env.zoom < #{variables.$MAPSIGHT_TRAFFIC_STYLE__FEATURES_BASE_ZOOM_DEFAULT}"] - :not([state="highlight"]) - :not([state="select"]) { + :not([state="highlight"]) + :not([state="select"]) { + @include auto-icon.autoIconDefault("small"); + @include runtime-icon.runtimeIconSrc("small"); @include auto-icon.autoIcon("small"); } @@ -178,8 +137,9 @@ icon: { anchorX: -14px; anchorY: 12px; - src: variables.$MAPSIGHT_TRAFFIC_STYLE__IMAGE_PATH + - "parking-dynamic/attr(occupancyTrendString).png"; + src: unquote( + 'calc(attr(--env-imagesUrl) + "parking-dynamic/" + attr(occupancyTrendString) + ".png")' + ); } [state="highlight"], diff --git a/packages/traffic-style/src/scss/mixins/_auto-icon.scss b/packages/traffic-style/src/scss/mixins/_auto-icon.scss index ab420ec0..5c36641c 100644 --- a/packages/traffic-style/src/scss/mixins/_auto-icon.scss +++ b/packages/traffic-style/src/scss/mixins/_auto-icon.scss @@ -12,22 +12,29 @@ icon-src: variables.$MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH; } -@mixin autoIcon( +@mixin autoIconDefault( $state: variables.$MAPSIGHT_TRAFFIC_STYLE__STATE_DEFAULT, $iconDefault: variables.$MAPSIGHT_TRAFFIC_STYLE__ICON_DEFAULT, - $iconFallbackMap: variables.$MAPSIGHT_TRAFFIC_STYLE__ICON_FALLBACK_MAP, $icons: variables.$MAPSIGHT_TRAFFIC_STYLE__ICONS ) { - $stateSuffix: "-" + $state; - // default fallback - $defaultName: $iconDefault + $stateSuffix; - $defaultDimensions: map.get($icons, $defaultName); - @if $defaultDimensions { - @include get-icon-dimensions.getIconDimension($defaultDimensions); + $id: $iconDefault + "-" + $state; + $dimensions: map.get($icons, $id); + @if $dimensions { + @include spriteIconSrc; + @include get-icon-dimensions.getIconDimension($dimensions); } @else { - @debug "Default icon not found: " + $defaultName; + @debug "Default icon not found: " + $id; } +} + +@mixin autoIcon( + $state: variables.$MAPSIGHT_TRAFFIC_STYLE__STATE_DEFAULT, + $iconDefault: variables.$MAPSIGHT_TRAFFIC_STYLE__ICON_DEFAULT, + $iconFallbackMap: variables.$MAPSIGHT_TRAFFIC_STYLE__ICON_FALLBACK_MAP, + $icons: variables.$MAPSIGHT_TRAFFIC_STYLE__ICONS +) { + $stateSuffix: "-" + $state; // fallback icons @each $fallbackId, $iconIds in $iconFallbackMap { diff --git a/packages/traffic-style/src/scss/mixins/_runtime-icon-dimensions.scss b/packages/traffic-style/src/scss/mixins/_runtime-icon-dimensions.scss new file mode 100644 index 00000000..02ce36bc --- /dev/null +++ b/packages/traffic-style/src/scss/mixins/_runtime-icon-dimensions.scss @@ -0,0 +1,19 @@ +@use "sass:map"; +@use "../variables"; + +/// Reset sprite-sheet offset/size so full-image runtime icons render correctly. +@mixin runtimeIconDimensions( + $variant: variables.$MAPSIGHT_TRAFFIC_STYLE__STATE_DEFAULT, +) { + $logical-size: map.get( + variables.$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SIZES, + $variant + ); + $pixel-size: $logical-size * + variables.$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_PIXEL_RATIO; + + icon-offsetX: 0; + icon-offsetY: 0; + icon-sizeX: $pixel-size; + icon-sizeY: $pixel-size; +} diff --git a/packages/traffic-style/src/scss/mixins/_runtime-icon.scss b/packages/traffic-style/src/scss/mixins/_runtime-icon.scss new file mode 100644 index 00000000..162a0ad8 --- /dev/null +++ b/packages/traffic-style/src/scss/mixins/_runtime-icon.scss @@ -0,0 +1,92 @@ +@use "../variables"; +@use "./runtime-icon-dimensions"; + +@mixin runtimeIconSrc($state: variables.$MAPSIGHT_TRAFFIC_STYLE__STATE_DEFAULT) { + [env|mapsightIconId] { + icon-src: calc( + mapsightRuntimeIcon( + attr(--env-mapsightIconId), + "#{$state}" + ) + ); + + @include runtime-icon-dimensions.runtimeIconDimensions($state); + } + + [mapsightIconId] { + icon-src: calc( + mapsightRuntimeIcon( + attr(mapsightIconId), + "#{$state}" + ) + ); + + @include runtime-icon-dimensions.runtimeIconDimensions($state); + } + + @if variables.$MAPSIGHT_TRAFFIC_STYLE__ICON_ENABLE_FORCE_BY_ENV { + [env|mapsightIconUse="force"] { + [env|mapsightIconId] { + icon-src: calc( + mapsightRuntimeIcon( + attr(--env-mapsightIconId), + "#{$state}" + ) + ); + + @include runtime-icon-dimensions.runtimeIconDimensions($state); + } + } + } +} + +@mixin runtimeIcon($state: variables.$MAPSIGHT_TRAFFIC_STYLE__STATE_DEFAULT) { + [env|mapsightIconId] { + image-type: icon; + + icon: { + scale: variables.$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SCALE; + src: calc( + mapsightRuntimeIcon( + attr(--env-mapsightIconId), + "#{$state}" + ) + ); + snapToPixel: true; + } + + @include runtime-icon-dimensions.runtimeIconDimensions($state); + } + + [mapsightIconId] { + image-type: icon; + + icon: { + scale: variables.$MAPSIGHT_TRAFFIC_STYLE__RUNTIME_ICON_SCALE; + src: calc( + mapsightRuntimeIcon( + attr(mapsightIconId), + "#{$state}" + ) + ); + snapToPixel: true; + } + + @include runtime-icon-dimensions.runtimeIconDimensions($state); + } + + @if variables.$MAPSIGHT_TRAFFIC_STYLE__ICON_ENABLE_FORCE_BY_ENV { + [env|mapsightIconUse="force"] { + [env|mapsightIconId] { + icon-src: calc( + mapsightRuntimeIcon( + attr(--env-mapsightIconId), + "#{$state}" + ) + ); + + @include runtime-icon-dimensions.runtimeIconDimensions($state); + } + } + } +} diff --git a/packages/ui/src/js/plugins/common/runtime-icon-style.ts b/packages/ui/src/js/plugins/common/runtime-icon-style.ts index 25ba67cc..7f4345a1 100644 --- a/packages/ui/src/js/plugins/common/runtime-icon-style.ts +++ b/packages/ui/src/js/plugins/common/runtime-icon-style.ts @@ -1,15 +1,20 @@ import { + bindRuntimeIconStyleFeatureScope, onRuntimeIconChange, setRuntimeIconMapRenderCallback, } from "@mapsight/traffic-style/runtime"; import {MapController} from "@mapsight/core/lib/map/controller"; +import {addStyleFeatureScopeHooks} from "@mapsight/lib-ol/style/styleFeatureScope"; + import {MAP} from "../../config/constants/controllers"; import type {PluginInstance} from "../../types"; type MapLike = {render: () => void} | null | undefined; +bindRuntimeIconStyleFeatureScope(addStyleFeatureScopeHooks); + let unregisterRuntimeIconChangeListener: (() => void) | null = null; function registerRuntimeIconStyleSupport(getMap: () => MapLike): () => void { From 705a92864db37b887585c7cf01c749897c0f2390 Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Fri, 12 Jun 2026 21:39:52 +0200 Subject: [PATCH 6/8] traffic-style: document workspace quirk Signed-off-by: Paul Golmann --- .../traffic-style/docs/CUSTOM_ICON_BUILDS.md | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md b/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md index fe092f00..54c459e5 100644 --- a/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md +++ b/packages/traffic-style/docs/CUSTOM_ICON_BUILDS.md @@ -15,6 +15,34 @@ Font Awesome pack). For how sprite vs composable icons are classified, see [ICON_CATALOG.md](ICON_CATALOG.md). For runtime pictogram packs, see the same doc. +## Monorepo / pnpm workspace + +This package uses `publishConfig.linkDirectory: true` so workspace consumers +symlink to `dist/` instead of the package root. That mirrors the published tarball +layout and keeps workspace DX “hot”: apps import built assets from `dist` without +`pnpm pack` or republishing on every traffic-style change. + +**Trade-off:** in this setup, pnpm does not reliably expose the `bin` shims +(`traffic-icon-sprite`, `traffic-composable-icons`, …) on `PATH` when you run app +scripts — even though the CLI files exist under +`node_modules/@mapsight/traffic-style/scripts/`. After `pnpm install` from the +registry, the bare command names work as documented below. + +**Workaround in workspace apps:** invoke the script explicitly: + +```json +{ + "scripts": { + "build:iconSprite": "node node_modules/@mapsight/traffic-style/scripts/traffic-icon-sprite.js --output-scss tmp/ --output-img public/img/ --groups default,education" + } +} +``` + +Same pattern for `traffic-composable-icons.js`. Use +`node_modules/@mapsight/traffic-style/meta.json` for `--meta-path` unless you are +editing `src/meta.json` locally and have not rebuilt traffic-style yet (then point +at `packages/traffic-style/src/meta.json` temporarily). + --- ## Custom sprite sheets @@ -33,7 +61,7 @@ pre-optimized icon PNGs in the package. Icons with `"render": "composable"` in ### Example -From a consuming app (similar to a private host app under `private/apps/`): +In a consuming app's `package.json` (registry install — bare CLI names on `PATH`): ```json { @@ -43,6 +71,9 @@ From a consuming app (similar to a private host app under `private/apps/`): } ``` +In a pnpm workspace linked to this repo, use the `node node_modules/…/scripts/…` +form from [Monorepo / pnpm workspace](#monorepo--pnpm-workspace) above instead. + ### Defaults | Option | Default | From 2fe665dccb51011d6fbd28adac7b7b77b8e4133c Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Sun, 14 Jun 2026 02:01:33 +0200 Subject: [PATCH 7/8] changeset: traffic-style icon pipeline Signed-off-by: Paul Golmann Co-authored-by: Cursor --- .changeset/traffic-style-icon-pipeline.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/traffic-style-icon-pipeline.md diff --git a/.changeset/traffic-style-icon-pipeline.md b/.changeset/traffic-style-icon-pipeline.md new file mode 100644 index 00000000..e90248a6 --- /dev/null +++ b/.changeset/traffic-style-icon-pipeline.md @@ -0,0 +1,8 @@ +--- +"@mapsight/traffic-style": minor +"@mapsight/ui": patch +--- + +Improve traffic-style icon pipeline: add Font Awesome smart-city pictograms and default ort icons, fix sprite padding and missing default build output, unify sprite/runtime icon fallback in SCSS mixins, and resolve Sass deprecation warnings. + +--- From cbc910cd5a86fe91674c5066ba1fa4715e10d864 Mon Sep 17 00:00:00 2001 From: Paul Golmann Date: Sun, 14 Jun 2026 02:40:06 +0200 Subject: [PATCH 8/8] traffic-style: fix sprite scss import path for linkDirectory consumers Signed-off-by: Paul Golmann --- packages/traffic-style/package.json | 2 +- packages/traffic-style/src/scss/_icons-1x.scss | 2 +- packages/traffic-style/src/scss/_icons-2x.scss | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/traffic-style/package.json b/packages/traffic-style/package.json index e5fb345d..d26b9254 100644 --- a/packages/traffic-style/package.json +++ b/packages/traffic-style/package.json @@ -91,7 +91,7 @@ "build:composable-icons:svg": "node scripts/dev/build-composable-icons.ts svg", "build:docs": "run-p build:docs:overview", "build:docs:overview": "node scripts/dev/create-overview-md.ts ./src/icons/ ../img/mapsight-icons-svg/ > dist/docs/overview.md", - "build:icon-sprites": "run-p build:icon-sprites:*", + "build:icon-sprites": "run-p build:icon-sprites:* && cp dist/mapsight-traffic-style-icon-sprite-*.scss .", "build:icon-sprites:1x": "node scripts/traffic-icon-sprite.ts ./dist/img/mapsight-icons/ --meta-path dist/meta.json --sprite-name mapsight-traffic-style-icon-sprite-1x", "build:icon-sprites:2x": "node scripts/traffic-icon-sprite.ts ./dist/img/mapsight-icons-2x/ --meta-path dist/meta.json --sprite-name mapsight-traffic-style-icon-sprite-2x", "build:icons": "node scripts/optimize-icons.ts --src ./src/icons/ --dest ./dist/img/mapsight-icons/", diff --git a/packages/traffic-style/src/scss/_icons-1x.scss b/packages/traffic-style/src/scss/_icons-1x.scss index 1a22a589..1a3fe200 100644 --- a/packages/traffic-style/src/scss/_icons-1x.scss +++ b/packages/traffic-style/src/scss/_icons-1x.scss @@ -1,4 +1,4 @@ -@use "../../dist/mapsight-traffic-style-icon-sprite-1x" as sprite; +@use "../../mapsight-traffic-style-icon-sprite-1x" as sprite; $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: "/img/mapsight-traffic-style-icon-sprite-1x.png?v=2023-08-07-16-00" !default; $MAPSIGHT_TRAFFIC_STYLE__ICONS: sprite.$mapsight-traffic-style-icon-sprite-1x !default; diff --git a/packages/traffic-style/src/scss/_icons-2x.scss b/packages/traffic-style/src/scss/_icons-2x.scss index 3fe1838e..47b5aa36 100644 --- a/packages/traffic-style/src/scss/_icons-2x.scss +++ b/packages/traffic-style/src/scss/_icons-2x.scss @@ -1,4 +1,4 @@ -@use "../../dist/mapsight-traffic-style-icon-sprite-2x" as sprite; +@use "../../mapsight-traffic-style-icon-sprite-2x" as sprite; $MAPSIGHT_TRAFFIC_STYLE__SPRITE_PATH: "/img/mapsight-traffic-style-icon-sprite-2x.png?v=2023-08-07-16-00" !default; $MAPSIGHT_TRAFFIC_STYLE__ICONS: sprite.$mapsight-traffic-style-icon-sprite-2x !default;