Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
8dc462a
Bump @commitlint/cli from 20.2.0 to 20.3.0
dependabot[bot] Jan 2, 2026
0328f14
ci(iceberg): make tsc acknowledge vitest-caused node types
oeninghe-dataport Jan 5, 2026
07048a5
fix(core): enforce usage of `Icon` type
oeninghe-dataport Jan 7, 2026
2fa72f1
feat(filter): migrate plugin
oeninghe-dataport Jan 2, 2026
6aabb56
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Jan 16, 2026
cd23d05
fix(filter): use correct import for export store
dopenguin Jan 16, 2026
56ea116
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Jan 19, 2026
9c92633
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Jan 20, 2026
e6916db
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Jan 22, 2026
25d11ec
style: apply new linting rule for self-closing
oeninghe-dataport Jan 23, 2026
b7b6c3b
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Jan 23, 2026
0d1200c
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Jan 23, 2026
52c14f3
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Jan 28, 2026
e973288
fix(filter): remove bottom padding that was mitigation for a fixed bug
oeninghe-dataport Jan 30, 2026
1a1516e
fix(filter): use sensible defaults for user-defined locales
oeninghe-dataport Jan 30, 2026
7c65f97
docs(filter): recommend l10n
oeninghe-dataport Feb 2, 2026
8daf691
fix(filter): show layer name instead of ID
oeninghe-dataport Feb 2, 2026
0fb038b
fix(filter): show layer name if only one layer is offered
oeninghe-dataport Feb 2, 2026
bdb3cd6
refactor(filter): use `PluginId` as namespace for i18n
oeninghe-dataport Feb 2, 2026
952f425
refactor: move `getVectorSource` to global lib functions
oeninghe-dataport Feb 2, 2026
e573790
refactor(filter): move common getters to store
oeninghe-dataport Feb 3, 2026
49d36bb
refactor(filter): introduce store logic for time-related filters
oeninghe-dataport Feb 3, 2026
20d3c31
fix: reserve space for border in KernBlockButtonX
oeninghe-dataport Feb 3, 2026
36777db
chore(filter): add missing store files
oeninghe-dataport Feb 3, 2026
ac723a0
refactor: show focus for KernBlockButtonX
oeninghe-dataport Feb 3, 2026
715c37b
chore: remove now unused @ts-expect-error directives
oeninghe-dataport Feb 3, 2026
01f8943
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Feb 4, 2026
3288804
feat(filter): allow multiple filter categories for a targetProperty
oeninghe-dataport Feb 6, 2026
2f0ef30
refactor(filter): replace non-null-assertion w/ explicit type assertion
oeninghe-dataport Feb 6, 2026
873e53f
feat(filter): allow grouping multiple values to a single category entry
oeninghe-dataport Feb 6, 2026
4e97981
refactor(filter): remove card CSS that is no longer needed
oeninghe-dataport Feb 9, 2026
1a9f2a7
fix: prohibit that PolarCard is sometimes focusable in Gecko
oeninghe-dataport Feb 9, 2026
413aece
fix: hide block button input elements w/ Gecko
oeninghe-dataport Feb 9, 2026
c879fbf
feat: radio groups behave more like buttons
oeninghe-dataport Feb 16, 2026
cd44fbc
feat: show focus for block buttons only if keyboard-focused
oeninghe-dataport Feb 16, 2026
afb71b1
feat: allow enabling/toggling w/ enter for block buttons
oeninghe-dataport Feb 16, 2026
c7942f3
feat(filter): improved scrolling behavior for tab navigation
oeninghe-dataport Feb 16, 2026
04d38ef
refactor(core): rename `getLayerConfiguration` and improve types
oeninghe-dataport Feb 16, 2026
537f5d2
feat(filter): add nine-regions-style layout
oeninghe-dataport Feb 16, 2026
740e0a8
refactor(filter): initialize state non-lazily
oeninghe-dataport Feb 16, 2026
b19e761
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Feb 16, 2026
117f4ba
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Feb 18, 2026
b893b49
test(iceberg): add example for filter plugin
oeninghe-dataport Feb 19, 2026
8a29bb2
fix(filter): add FilterPluginOptions to core configuration type
oeninghe-dataport Feb 19, 2026
983e153
fix: remove KERN example label from radio group
oeninghe-dataport Feb 19, 2026
166e67b
refactor: use index instead of value for building IDs
oeninghe-dataport Feb 19, 2026
836dee8
Update src/core/types/main.ts
oeninghe-dataport Feb 20, 2026
8bd2a54
Merge branch 'next' into vue3/migrate-plugin-filter
oeninghe-dataport Feb 20, 2026
49689db
fix(iconMenu): consider default plugin icon for nine regions menu
oeninghe-dataport Feb 20, 2026
9476c57
fix(filter): use accordion for filter in nine-regions
oeninghe-dataport Feb 20, 2026
efd4b66
refactor(core): use dash as ID separator for radio group
oeninghe-dataport Feb 20, 2026
fff615e
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Feb 23, 2026
f6e7ebd
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Feb 23, 2026
f2071ff
docs(filter): add hint that icon is standard-specific
oeninghe-dataport Mar 3, 2026
5cbfa00
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Mar 5, 2026
a8fbc28
Merge branch 'next' into vue3/migrate-plugin-filter
dopenguin Mar 5, 2026
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
34 changes: 34 additions & 0 deletions examples/iceberg/components/IcebergMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type { PolarContainer } from '@polar/polar'

import { addPlugins, getStore, subscribe } from '@polar/polar'
import pluginAddressSearch from '@polar/polar/plugins/addressSearch'
import pluginFilter from '@polar/polar/plugins/filter'
import pluginFullscreen from '@polar/polar/plugins/fullscreen'
import pluginIconMenu from '@polar/polar/plugins/iconMenu'
import pluginLayerChooser from '@polar/polar/plugins/layerChooser'
Expand All @@ -56,6 +57,39 @@ watch(map, (map) => {
displayComponent: true,
layoutTag: 'TOP_RIGHT',
menus: [
[
{
plugin: pluginFilter({
layers: {
6059: {
categories: [
{
targetProperty: 'statu',
knownValues: [
{
key: 'todo',
values: ['In Bearbeitung'],
icon: 'kern-icon--assignment',
},
{
key: 'done',
values: ['abgeschlossen'],
icon: 'kern-icon--check',
},
],
},
],
time: {
targetProperty: 'start',
freeSelection: 'until',
last: [7],
pattern: 'YYYYMMDD',
},
},
},
}),
},
],
[
{
plugin: pluginLayerChooser({}),
Expand Down
30 changes: 30 additions & 0 deletions examples/iceberg/stores/iceberg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ export const useIcebergStore = defineStore('iceberg', () => {
},
},
},
{
id: '6059',
visibility: true,
type: 'mask',
name: 'snowbox.layers.mml',
},
],
startCenter: [565874, 5934140],
layout: 'nineRegions',
Expand Down Expand Up @@ -92,6 +98,30 @@ export const useIcebergStore = defineStore('iceberg', () => {
displayComponent: true,
layoutTag: 'TOP_RIGHT',
},
markers: {
layers: [
{
id: '6059',
defaultStyle: {
stroke: '#FFFFFF',
fill: '#005CA9',
},
hoverStyle: {
stroke: '#46688E',
fill: '#8BA1B8',
},
selectionStyle: {
stroke: '#FFFFFF',
fill: '#E10019',
},
unselectableStyle: {
stroke: '#FFFFFF',
fill: '#333333',
},
},
],
clusterClickZoom: true,
},
pins: {
coordinateSources: [{ plugin: 'addressSearch', key: 'chosenAddress' }],
movable: 'drag',
Expand Down
1 change: 1 addition & 0 deletions examples/iceberg/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"types": [
"vitest/importMeta",
"vitest/jsdom",
"node",
"../../src/@types/vite-env.d.ts",
"../../src/@types/i18next.d.ts",
"../../src/@types/pinia.d.ts",
Expand Down
92 changes: 91 additions & 1 deletion examples/snowbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
updateState,
} from '@polar/polar'
import pluginAddressSearch from '@polar/polar/plugins/addressSearch'
import pluginFilter from '@polar/polar/plugins/filter'
import pluginFooter from '@polar/polar/plugins/footer'
import pluginFullscreen from '@polar/polar/plugins/fullscreen'
import pluginGeoLocation from '@polar/polar/plugins/geoLocation'
Expand Down Expand Up @@ -182,6 +183,30 @@ const map = await createMap(
{
type: 'de',
resources: {
filter: {
layer: {
[reports]: {
category: {
skat: {
title: 'Schadensart',
knownValue: {
'1xx': 'Alle Wege- und Straßenschäden',
100: 'Wege und Straßen',
101: 'Schlagloch und Wegeschaden',
102: 'Verunreinigung und Vandalismus',
},
},
statu: {
title: 'Bearbeitungsstatus',
knownValue: {
todo: 'In Bearbeitung',
done: 'Abgeschlossen',
},
},
},
},
},
},
fullscreen: {
button: {
label_on: 'Mach groß',
Expand Down Expand Up @@ -336,7 +361,6 @@ addPlugin(
},
],
menus: [
// TODO: Delete the mock plugins including the components once the correct plugins have been implemented
[
{
plugin: pluginFullscreen({}),
Expand All @@ -345,6 +369,7 @@ addPlugin(
plugin: pluginLayerChooser({}),
},
],
// TODO: Delete the mock plugins including the components once the correct plugins have been implemented
[
{
plugin: {
Expand All @@ -355,6 +380,71 @@ addPlugin(
icon: 'kern-icon-fill--share',
},
],
[
{
plugin: pluginFilter({
layers: {
[reports]: {
categories: [
{
targetProperty: 'skat',
knownValues: [
{
key: '100',
values: ['100'],
icon: 'kern-icon--road',
},
{
key: '101',
values: ['101'],
icon: 'kern-icon--remove-road',
},
{
key: '102',
values: ['102'],
icon: 'kern-icon--destruction',
},
],
selectAll: true,
},
{
targetProperty: 'skat',
knownValues: [
{
key: '1xx',
values: ['100', '101', '102'],
icon: 'kern-icon--road',
},
],
selectAll: true,
},
{
targetProperty: 'statu',
knownValues: [
{
key: 'todo',
values: ['In Bearbeitung'],
icon: 'kern-icon--assignment',
},
{
key: 'done',
values: ['abgeschlossen'],
icon: 'kern-icon--check',
},
],
},
],
time: {
targetProperty: 'start',
freeSelection: 'until',
last: [0, 7, 30],
pattern: 'YYYYMMDD',
},
},
},
}),
},
],
[
{
plugin: pluginGeoLocation({
Expand Down
2 changes: 1 addition & 1 deletion src/architecture.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('Architectural checks', () => {
.matchingPattern('^plugins/.*$')
.should()
.matchPattern(
'^plugins/[^/]+/((index|locales|store|types)\\.ts|utils/.*\\.ts|components/.*\\.spec\\.ts)$'
'^plugins/[^/]+/((index|locales|store|types)\\.ts|utils/.*\\.ts|components/.*\\.spec\\.ts|stores/.*\\.ts)$'
)
.check()
expect(violations).toEqual([])
Expand Down
2 changes: 1 addition & 1 deletion src/components/PolarCard.ce.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<article class="kern-card kern-card--small">
<article class="kern-card kern-card--small" tabindex="-1">
<div class="kern-card__container">
<slot />
</div>
Expand Down
7 changes: 7 additions & 0 deletions src/components/PolarTemplate.ce.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template>
<slot />
</template>

<script setup lang="ts">
// This can be used to render a container that does not emit a DOM element.
</script>
37 changes: 37 additions & 0 deletions src/components/kern/KernBlockButton.ce.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<button
class="kern-btn kern-btn--block kern-btn--tertiary"
@click="emit('click')"
>
<span
v-if="props.icon"
:class="{ 'kern-icon': true, [props.icon]: true }"
aria-hidden="true"
/>
<span class="kern-label">{{ props.label }}</span>
</button>
</template>

<script setup lang="ts">
import type { Icon } from '@/core'

const props = defineProps<{
icon?: Icon | false
label: string
}>()

const emit = defineEmits<{
click: []
}>()
</script>

<style scoped>
.kern-btn--tertiary {
background-color: #edf1fa;
justify-content: left;

.kern-label {
text-decoration: none;
}
}
</style>
78 changes: 78 additions & 0 deletions src/components/kern/KernBlockButtonCheckbox.ce.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<template>
<input
:id="id"
v-model="model"
type="checkbox"
@keydown.prevent.enter="model = !model"
@focus="scrollVisible($event)"
/>
<label :for="id" class="kern-btn kern-btn--block kern-btn--tertiary">
<span
v-if="props.icon"
:class="{ 'kern-icon': true, [props.icon]: true }"
aria-hidden="true"
/>
<span class="kern-label">{{ props.label }}</span>
</label>
</template>

<script setup lang="ts">
import { useId } from 'vue'

import type { Icon } from '@/core'

const props = defineProps<{
icon?: Icon | false
label: string
}>()

const model = defineModel<boolean>({ required: true })

const id = useId()

function scrollVisible(evt: FocusEvent) {
const target = evt.target as HTMLInputElement
const label = target.parentElement?.querySelector(`label[for="${target.id}"]`)
if (label?.scrollIntoView) {
label.scrollIntoView({
behavior: 'smooth',
block: 'nearest',
inline: 'nearest',
})
}
}
</script>

<style scoped>
.kern-btn--tertiary {
background-color: #edf1fa;
justify-content: left;

.kern-label {
text-decoration: none;
}
}

label {
border: var(--kern-metric-border-width-default) solid transparent;
}

input[type='checkbox'] {
position: absolute;
height: 0;
clip-path: circle(0);

&:focus-visible + label {
padding: var(--kern-metric-space-none) var(--kern-metric-space-default);
border-radius: var(--kern-metric-border-radius-default);
box-shadow:
0 0 0 2px var(--kern-color-action-on-default),
0 0 0 4px var(--kern-color-action-focus-border-inside),
0 0 0 6px var(--kern-color-action-focus-border-outside);
}

&:checked + label {
border-color: var(--kern-color-action-default);
}
}
</style>
Loading
Loading