Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
dc85645
refactor(core): enable TypeScript support for i18n
oeninghe-dataport Aug 26, 2025
0c5d11b
refactor(core): configuration-agnostic i18n plugin
oeninghe-dataport Aug 26, 2025
55eec5b
refactor(core): use precise type for locale overrides
oeninghe-dataport Aug 26, 2025
869433f
refactor(core): pass mapConfig via props to CE
oeninghe-dataport Aug 27, 2025
1792840
Merge branch 'vue3/migrate-plugin-toast' into feature/multiple-elements
oeninghe-dataport Aug 28, 2025
04a0681
refactor(iconMenu): adapt to refactored core
oeninghe-dataport Aug 28, 2025
a7af0e8
Merge branch 'vue3/migrate-plugin-toast' into feature/multiple-elements
oeninghe-dataport Aug 28, 2025
3e942d5
feat(fullscreen): allow passing no options
oeninghe-dataport Aug 28, 2025
fd71c31
refactor(core): use reactive for plugin array in plugin store
oeninghe-dataport Aug 28, 2025
955041c
chore: move d-ts files to @types folder
oeninghe-dataport Aug 28, 2025
c34a8a5
fix(core): declare store explicit as exposed
oeninghe-dataport Aug 28, 2025
f139ea4
chore: improve iceberg
oeninghe-dataport Aug 28, 2025
a201b30
chore: improve iceberg [wip]
oeninghe-dataport Aug 28, 2025
72a5689
Merge branch 'next' into feature/multiple-elements
dopenguin Aug 29, 2025
59de509
Merge branch 'next' into feature/multiple-elements
dopenguin Sep 4, 2025
bda1ebd
Merge branch 'next' into feature/multiple-elements
dopenguin Sep 15, 2025
899e38d
refactor(iconMenu): remove pluginStore from store
oeninghe-dataport Sep 22, 2025
27343bd
docs(core): clarify usage of register/createMap and add missing docs
oeninghe-dataport Sep 22, 2025
b4413d0
Merge branch 'next' into feature/multiple-elements
oeninghe-dataport Sep 22, 2025
3cfc4cf
style(snowbox): fix HTML indentation
oeninghe-dataport Sep 22, 2025
7a90f58
style(iceberg): remove superfluous type hint
oeninghe-dataport Sep 22, 2025
f3deaec
refactor(core): move action logger to separate file
oeninghe-dataport Sep 22, 2025
fe38c75
build: accept HMR for pinia stores
oeninghe-dataport Sep 30, 2025
0e432d7
fix: do not create pinia stores w/o instance reference anymore
oeninghe-dataport Sep 30, 2025
0fddd2a
Merge branch 'next' into feature/multiple-elements
oeninghe-dataport Sep 30, 2025
6697f1b
fix(core): adapt subscribe and updateState to multi-map support
oeninghe-dataport Sep 30, 2025
51776c7
test(iceberg): improve styling
oeninghe-dataport Sep 30, 2025
ea5c7a2
test(iceberg): add language switcher
oeninghe-dataport Sep 30, 2025
024e6b5
style(iceberg): fix HTML indentation
oeninghe-dataport Sep 30, 2025
b43828b
fix(core): live translation updates for overlay messages
oeninghe-dataport Sep 30, 2025
cc3ed40
fix(toast): live translation updates for toast messages
oeninghe-dataport Sep 30, 2025
952e614
Merge branch 'next' into feature/multiple-elements
oeninghe-dataport Sep 30, 2025
e0f3b57
fix(core): initialize serviceRegister to ensure sync map creation
oeninghe-dataport Oct 1, 2025
725b14b
refactor(core): remove map null-checks from PolarMap SFC
oeninghe-dataport Oct 1, 2025
492c983
test(snowbox): fix selectedCoordinates subscribe
oeninghe-dataport Oct 6, 2025
e8ad512
test(snowbox): add jsconfig.json for IntelliSense in VSCode
oeninghe-dataport Oct 6, 2025
96504e3
test(snowbox): do not use internal POLAR APIs for language change
oeninghe-dataport Oct 6, 2025
fb755d9
refactor(core): simplify language property in export store
oeninghe-dataport Oct 6, 2025
68ba7c3
test(snowbox): use getStore instead of map.store.getPluginStore
oeninghe-dataport Oct 6, 2025
25d932f
style: enforce use of self-closing tags
oeninghe-dataport Oct 6, 2025
fecdbce
style(core): add hint on exposed store DOM prop
oeninghe-dataport Oct 7, 2025
393a7a5
refactor(core): use typed pinia extensions
oeninghe-dataport Oct 7, 2025
9806e7d
feat(core): provide convenience wrapper createMap (similar to POLAR@2)
oeninghe-dataport Oct 7, 2025
fafeae0
refactor(core): split exported utils to separate files
oeninghe-dataport Oct 7, 2025
d512aaa
refactor(core): move re-compution of t result to notifyUser
oeninghe-dataport Oct 7, 2025
ab0711b
test(iceberg): enable checkServiceAvailability
oeninghe-dataport Oct 7, 2025
0184567
fix(core): revert to-be-discussed live-updates
oeninghe-dataport Oct 7, 2025
16e5a21
fix(core): revert to-be-discussed default style for polar-map
oeninghe-dataport Oct 7, 2025
86ac358
build(iceberg): add missing d.ts reference
oeninghe-dataport Oct 7, 2025
022f91b
chore: move computedT to match architectural constraints
oeninghe-dataport Oct 7, 2025
085c76a
docs(core): add hint about plugin.options
oeninghe-dataport Oct 8, 2025
6c09939
fix(core): revert to-be-discussed watcher for live-updates
oeninghe-dataport Oct 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ const polarVueConfig = {
},
}

const polarHtmlConfig = {
rules: {
// POLAR-specific rules
'@html-eslint/require-closing-tags': ['error', { selfClosing: 'always' }],
'@html-eslint/no-extra-spacing-attrs': [
'error',
{ enforceBeforeSelfClose: true },
],
},
}

export default defineConfig([
{
ignores: [
Expand Down Expand Up @@ -130,6 +141,12 @@ export default defineConfig([
polarVueConfig,
],
},
{
files: ['**/examples/**/*.vue'],
rules: {
'vue/enforce-style-attribute': ['error', { allow: ['scoped', 'module'] }],
},
},
{
files: ['**/*.json'],
ignores: ['package-lock.json'],
Expand All @@ -141,6 +158,6 @@ export default defineConfig([
},
{
files: ['**/*.html'],
extends: [htmlConfig],
extends: [htmlConfig, polarHtmlConfig],
},
])
2 changes: 1 addition & 1 deletion examples/github-io/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<title>POLAR@next</title>
<meta charset="utf-8">
<meta charset="utf-8" />
</head>

<body>
Expand Down
107 changes: 89 additions & 18 deletions examples/iceberg/App.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,108 @@
<template>
<h1 class="kern-heading-display">Eisberg-Register</h1>
<h2 class="kern-heading-large">Nicht genehmigten Eisberg melden</h2>
<polar-map ref="map"></polar-map>
<main :class="$style.main">
<div v-if="view !== 'menu'" style="margin-bottom: 2em">
<a href="#" class="kern-link" @click.prevent="view = 'menu'">
<span class="kern-icon kern-icon--arrow-back" aria-hidden="true" />
Zurück zur Übersicht
</a>
</div>
<TaskMenu
v-if="view === 'menu'"
:config-tasks="configTasks"
@select="view = $event"
/>
<IcebergMap v-else-if="view === 'map'" />
<component :is="configTaskComponent" v-else-if="configTaskComponent" />
<div
v-if="view !== 'menu'"
style="display: flex; gap: 2em; margin-top: 2em"
>
<button
v-if="viewIndex > 1"
class="kern-btn kern-btn--secondary"
style="flex: 1"
@click="viewIndex = viewIndex - 1"
>
<span class="kern-icon kern-icon--arrow-back" aria-hidden="true" />
<span class="kern-label">Zurück</span>
</button>
<button
v-if="viewIndex <= configTasks.length"
class="kern-btn kern-btn--primary"
style="flex: 1"
@click="viewIndex = viewIndex + 1"
>
<span class="kern-label">Weiter</span>
<span class="kern-icon kern-icon--arrow-forward" aria-hidden="true" />
</button>
</div>
</main>
</template>

<script setup lang="ts">
import { useTemplateRef } from 'vue'
import { createMap } from '@polar/polar'
const map = useTemplateRef('map')
import { computed, ref } from 'vue'
import kernExtraIcons from 'virtual:kern-extra-icons'
import LayoutChooser from './components/LayoutChooser.vue'
import TaskMenu from './components/TaskMenu.vue'
import IcebergMap from './components/IcebergMap.vue'

createMap(
const configTasks = [
{
layers: [
{
id: '23420',
visibility: true,
type: 'background',
name: 'snowbox.layers.basemap',
},
],
id: 'choose-layout',
label: 'Layout wählen',
component: LayoutChooser,
},
'https://geodienste.hamburg.de/services-internet.json'
]
const tasks = computed(() => [
'menu',
...configTasks.map(({ id }) => id),
'map',
])

const view = ref('menu')
const viewIndex = computed({
get: () => tasks.value.indexOf(view.value),
set: (value) => {
view.value = tasks.value[value] || 'menu'
},
})

const configTaskComponent = computed(
() => configTasks.find((task) => task.id === view.value)?.component
)

document.adoptedStyleSheets.push(kernExtraIcons)
if (import.meta.hot) {
import.meta.hot.on('kern-extra-icons', ({ icons }) => {
icons.forEach((icon) => kernExtraIcons.insertRule(icon))
})
}
</script>

<!-- eslint-disable-next-line vue/enforce-style-attribute -->
<style>
@import url('@kern-ux/native/dist/kern.css');
@import url('@kern-ux/native/dist/fonts/fira-sans.css');
@import url('@polar/polar/polar.css');
</style>

<style scoped>
.kern-link {
color: blue !important;
& > .kern-icon {
background-color: blue !important;
}
}
</style>

<style module>
.main {
position: relative;
margin: 2em 4em;

polar-map {
width: 100%;
height: 20em;
@media (max-width: 65em) {
margin: 1.5em 0.5em;
}
}
</style>
84 changes: 84 additions & 0 deletions examples/iceberg/components/IcebergMap.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<template>
<div :class="$style['language-chooser']">
<button class="kern-btn kern-btn--secondary" @click="switchLanguage">
<span class="kern-icon kern-icon--flag" />
<span class="kern-label">{{
language === 'de' ? 'Switch to English' : 'Zu Deutsch wechseln'
}}</span>
</button>
</div>
<polar-map
v-if="store.serviceRegister.length"
ref="map"
:map-configuration="store.mapConfiguration"
:service-register="store.serviceRegister"
/>
</template>

<script setup lang="ts">
import { ref, useTemplateRef, watch } from 'vue'

import { addPlugins, getStore, subscribe } from '@polar/polar'
import type { PolarContainer } from '@polar/polar'
import pluginIconMenu from '@polar/polar/plugins/iconMenu'
import pluginFullscreen from '@polar/polar/plugins/fullscreen'
import pluginToast from '@polar/polar/plugins/toast'

import { useIcebergStore } from '../stores/iceberg'

const store = useIcebergStore()

const language = ref('de')

const map = useTemplateRef<typeof PolarContainer>('map')
watch(map, (map) => {
if (!map) {
return
}
addPlugins(map, [
pluginIconMenu({
displayComponent: true,
layoutTag: 'TOP_RIGHT',
menus: [
{
plugin: pluginFullscreen(),
hint: 'Full of yourself',
},
],
}),
pluginToast({
displayComponent: true,
layoutTag: 'BOTTOM_MIDDLE',
}),
])

subscribe(map, 'core', 'language', (newLanguage) => {
language.value = newLanguage as string
})
})

function switchLanguage() {
if (!map.value) {
return
}

const coreStore = getStore(map.value, 'core')
coreStore.language = language.value === 'de' ? 'en' : 'de'
}
</script>

<style scoped>
@import url('@polar/polar/polar.css');

polar-map {
display: block;
width: 100%;
height: 20em;
}
</style>

<style module>
.language-chooser {
margin-bottom: 1em;
}
</style>
47 changes: 47 additions & 0 deletions examples/iceberg/components/LayoutChooser.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<fieldset class="kern-fieldset">
<legend class="kern-label">Welches Kartenlayout möchten Sie nutzen?</legend>
<div class="kern-fieldset__body">
<div
v-for="layout of layouts"
:key="layout.value"
class="kern-form-check"
>
<input
:id="`${id}-${layout.value}`"
v-model="store.mapConfiguration.layout"
class="kern-form-check__radio"
:name="`${id}-layout`"
type="radio"
:value="layout.value"
/>
<label :for="`${id}-${layout.value}`" class="kern-label">
{{ layout.label }}
</label>
</div>
</div>
</fieldset>
</template>

<script setup lang="ts">
import type { MapConfiguration } from '@polar/polar'
import { useId } from 'vue'
import { useIcebergStore } from '../stores/iceberg'

const id = useId()
const store = useIcebergStore()

const layouts = [
{
value: 'standard',
label: 'Standard-Layout',
},
{
value: 'nineRegions',
label: 'Klassisches Layout',
},
] satisfies {
value: MapConfiguration['layout']
label: string
}[]
</script>
55 changes: 55 additions & 0 deletions examples/iceberg/components/TaskMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<div class="kern-task-list">
<div class="kern-task-list__header">
<h2 class="kern-heading-medium">Karte konfigurieren</h2>
</div>
<ul class="kern-task-list__list">
<li
v-for="(task, idx) of configTasks"
:key="idx"
class="kern-task-list__item"
>
<span class="kern-number">{{ idx + 1 }}</span>
<div :id="`task${idx + 1}-title`" class="kern-task-list__title">
<a
href="#"
class="kern-link kern-link--stretched"
@click.prevent="emit('select', task.id)"
>
{{ task.label }}
</a>
</div>
</li>
</ul>
<div class="kern-task-list__header">
<h2 class="kern-heading-medium">Eisberg-Meldung</h2>
</div>
<ul class="kern-task-list__list">
<li class="kern-task-list__item">
<span class="kern-number">{{ props.configTasks.length + 1 }}</span>
<div :id="`task-map-title`" class="kern-task-list__title">
<a
href="#"
class="kern-link kern-link--stretched"
@click="emit('select', 'map')"
>
Karte anzeigen
</a>
</div>
</li>
</ul>
</div>
</template>

<script setup lang="ts">
const props = defineProps<{
configTasks: {
id: string
label: string
}[]
}>()

const emit = defineEmits<{
select: [string]
}>()
</script>
6 changes: 3 additions & 3 deletions examples/iceberg/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<html lang="de">
<head>
<title>Eisberg-Melderegister</title>
<meta charset="utf-8">
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate, max-age=0">
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate, max-age=0" />
<script type="module" defer src="index.js"></script>
</head>

Expand Down
6 changes: 5 additions & 1 deletion examples/iceberg/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import { register as registerPolar } from '@polar/polar'
import App from './App.vue'
createApp(App).mount('#app')

registerPolar()
createApp(App).use(createPinia()).mount('#app')
9 changes: 9 additions & 0 deletions examples/iceberg/polar-vue.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { PolarContainer } from '@polar/polar'

declare module 'vue' {
interface GlobalComponents {
/* eslint-disable @typescript-eslint/naming-convention */
'polar-map': typeof PolarContainer
/* eslint-enable @typescript-eslint/naming-convention */
}
}
Loading