Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 10 additions & 1 deletion packages/pxweb2/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
Expand Down Expand Up @@ -57,9 +57,18 @@
type="font/ttf"
/>
<script src="./config/config.js?v=__BUILD_DATE__"></script>

<link
rel="stylesheet"
href="./theme/variables.css?v=2026-01-07T12:27:34.137Z"
/>
<link rel="stylesheet" href="./ssbstyle.css" />
<script src="./ssbscript.js" type="module"></script>
</head>

<body>
<div id="root"></div>

<script type="module" src="src/main.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('Footer', () => {
// Fast-forward all timers
vi.runAllTimers();

expect(container.scrollTop).toBe(0);
expect(container.scrollTop).toBe(1000);
vi.useRealTimers();
});

Expand Down
2 changes: 1 addition & 1 deletion packages/pxweb2/src/app/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function scrollToTop(ref?: React.RefObject<HTMLDivElement | null>) {
function animateScroll(time: number) {
const elapsed = time - startTime;
const progress = Math.min(elapsed / duration, 1);
container.scrollTop = start * (1 - progress);
window.scrollTo({ top: start * (1 - progress), behavior: 'smooth' });
if (progress < 1) {
requestAnimationFrame(animateScroll);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,12 @@
border-end-end-radius: var(--px-border-radius-xlarge);
border-end-start-radius: var(--px-border-radius-none);

// Not from Figma
position: absolute;
// Make the drawer sticky under the header
position: sticky;
top: 0;
inset-inline-start: 120px; // Instead of "left" to handle rtl languages
z-index: 999;

// Position NavigationDrawer below the header
top: fixed.$spacing-22;

&.skipToMainContentVisible {
// Calculate position of NavigationDrawer below the header and SkipToMainContent
top: calc(fixed.$spacing-22 + var(--skip-to-main-content-height));
Expand All @@ -86,6 +84,11 @@
width: 396px;
padding: 0px fixed.$spacing-8 fixed.$spacing-8 0px;
border-radius: var(--px-border-radius-none);

// Stick under header
position: sticky;
top: 0;
height: calc(100vh - fixed.$spacing-22);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
// large, xlarge and xxlarge
@media ((min-width: fixed.$breakpoints-large-min-width) and (max-width: fixed.$breakpoints-xlarge-max-width)) or ((min-width: fixed.$breakpoints-xxlarge-min-width)) {
display: flex;
position: sticky;
top: 0;
}

&:focus-visible {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
background: var(--px-color-surface-default);
align-self: stretch;
position: relative;
overflow: hidden;

container-type: inline-size;
container-name: contentCont;
Expand All @@ -15,12 +16,6 @@
.tableContainer {
width: 100cqw;
overflow-x: auto;

&:focus-visible {
outline: 2px solid var(--px-color-border-focus-outline);
outline-offset: -2px;
border-radius: var(--px-border-radius-medium);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,14 @@

display: flex;
background: var(--px-color-surface-subtle);

// Calculate height of main container, minus the header
height: calc(100vh - fixed.$spacing-20);
height: 100%;

// xsmall, small and medium general settings
@media (breakpoints.$xsmall) or (breakpoints.$small) or (breakpoints.$medium) {
background: var(--px-color-surface-default);
width: 100%;
}

// height calculations
@media (breakpoints.$xsmall) or (breakpoints.$small) {
// Calculate height of main container, minus the header and navigation bar heights
height: calc(100vh - fixed.$spacing-19 - 78px);

&.skipToMainContentVisible {
// Calculate height of main container, minus the header and navigation bar and SkipToMainContent heights
height: calc(
100vh - fixed.$spacing-19 -
fixed.$spacing-20 - var(--skip-to-main-content-height)
);
}
}
@media (breakpoints.$medium) {
// Calculate height of main container, minus the header and navigation bar heights
height: calc(100vh - fixed.$spacing-20 - 78px);

&.skipToMainContentVisible {
// Calculate height of main container, minus the header and navigation bar and SkipToMainContent heights
height: calc(
100vh - fixed.$spacing-20 -
fixed.$spacing-20 - var(--skip-to-main-content-height)
);
}
}

// large, xlarge and xxlarge
@media (breakpoints.$large) or (breakpoints.$xlarge) or (breakpoints.$xxlarge) {
width: calc(100% - 120px);
Expand Down
11 changes: 3 additions & 8 deletions packages/pxweb2/src/app/util/startPageFilters.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, it, expect, vi } from 'vitest';
import { describe, it, expect } from 'vitest';
import {
findAncestors,
findChildren,
Expand Down Expand Up @@ -332,13 +332,8 @@ describe('getYearRanges', () => {
});
});

it('returns default range on empty input array', () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2025-06-01T12:00:00.000Z'));

expect(getYearRanges([])).toEqual({ min: 1900, max: 2025 });

vi.useRealTimers();
it('throws on empty input array', () => {
expect(getYearRanges([])).toEqual({ min: 1900, max: 2026 });
});
});

Expand Down
124 changes: 124 additions & 0 deletions packages/pxweb2/ssbscript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
(function () {
document.addEventListener('DOMContentLoaded', function () {
const html = `
<div id="alert-container" class="container oldLinkClass">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
role="img"
aria-hidden="true"
class="info-icon"
>
<path
d="M12 21.75C17.3848 21.75 21.75 17.3848 21.75 12C21.75 6.61522 17.3848 2.25 12 2.25C6.61522 2.25 2.25 6.61522 2.25 12C2.25 17.3848 6.61522 21.75 12 21.75ZM11 8C11 7.44771 11.4477 7 12 7C12.5523 7 13 7.44771 13 8C13 8.55228 12.5523 9 12 9C11.4477 9 11 8.55228 11 8ZM12 10.25C12.4142 10.25 12.75 10.5858 12.75 11L12.75 16.5C12.75 16.9142 12.4142 17.25 12 17.25C11.5858 17.25 11.25 16.9142 11.25 16.5L11.25 11C11.25 10.5858 11.5858 10.25 12 10.25Z"
fill="#0179C8"
/>
</svg>
<div id="info-text-container">
</div>
</div>
`;

// Insert at the very start of <body>
document.body.insertAdjacentHTML('afterbegin', html);
});

function checkLanguage() {
const url = new URL(globalThis.location.href);
if (url.pathname.includes('/en/')) {
return 'en';
} else {
return 'no';
}
}
/**
* Fires update() on initial load and on every SPA navigation:
* - history.pushState / replaceState (programmatic navigation)
* - popstate (back/forward)
*/
function computeTransformedUrl() {
const url = new URL(globalThis.location.href);
let newUrl;

if (checkLanguage() === 'en') {
// Replace it with '/en/statbank/'
newUrl = url.pathname.replace('/statbank2/en/', '/en/statbank/');
} else {
newUrl = url.pathname.replace('/statbank2/', '/statbank/');
}
return newUrl.toString();
}
function update() {
const language = checkLanguage();
const outerContainer = document.getElementById('alert-container');
if (outerContainer) {
let mySpan = document.querySelector('span.sr-only');
if (!mySpan) {
mySpan = document.createElement('span');
}
mySpan.textContent = language === 'en' ? 'Information' : 'Informasjon';
mySpan.classList.add('sr-only');
outerContainer.prepend(mySpan);
} else {
return;
}

const container = document.getElementById('info-text-container');
let before;
let mytext;

while (container.firstChild) {
container.removeChild(container.firstChild);
}

if (language === 'en') {
before = document.createTextNode(
"Welcome to the new Statbank! We're still fine-tuning things. " +
'If something is missing, you can still ',
);
mytext = 'access the old version';
} else {
before = document.createTextNode(
'Velkommen til nye Statistikkbanken! Vi jobber med de siste detaljene. ' +
'Skulle du savne noe, kan du fortsatt ',
);
mytext = 'bruke den gamle løsningen';
}
const newUrl = computeTransformedUrl();
const linkId = 'myLink';

const link = document.createElement('a');
link.id = linkId;
link.className = 'oldLinkClass';
link.href = newUrl;
link.textContent = mytext; // Safe text assignment
link.target = '_blank'; // open in new tab
link.rel = 'noopener noreferrer'; // safe when target=_blank

const after = document.createTextNode('.');

// Sørg for at alt ligger i samme linje (standard inline flow):
container.appendChild(before);
container.appendChild(link);
container.appendChild(after);
}

// Patch pushState / replaceState to emit a custom event
['pushState', 'replaceState'].forEach((method) => {
const original = history[method];
history[method] = function () {
const ret = original.apply(this, arguments);
globalThis.dispatchEvent(new Event('rr-nav')); // custom event for SPA navigation
return ret;
};
});

// Listen for both our custom event and browser back/forward
globalThis.addEventListener('rr-nav', update);
globalThis.addEventListener('popstate', update);

// Initial run after DOM is ready
document.addEventListener('DOMContentLoaded', update);
})();
66 changes: 66 additions & 0 deletions packages/pxweb2/ssbstyle.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
.container {
@media (min-width: 0px) and (max-width: 575px) {
padding: 20px 16px;
}
@media (min-width: 576px) and (max-width: 767px) {
padding: 20px 24px;
}
@media (min-width: 768px) and (max-width: 991px) {
padding: 20px 24px;
}
@media (min-width: 992px) and (max-width: 1199px) {
padding: 20px 24px;
}
@media (min-width: 1200px) and (max-width: 1399px) {
padding: 20px 24px;
}
@media (min-width: 1400px) {
padding: 20px 24px;
}
}

.oldLinkClass {
display: inline-flex;
background-color: #c3e6fe;
width: 100%;
font-family: 'PxWeb-font';
font-weight: 400;
font-size: 1rem;
font-style: normal;
line-height: 1.75rem;
text-decoration: none;
color: #162327;
gap: 12px;
}
a.oldLinkClass {
display: inline;
padding: 0px;
text-decoration-line: underline;
color: #274247;
}
a.oldLinkClass:hover {
text-decoration: none;
}
a.oldLinkClass:focus-visible {
outline: 3px solid var(--px-color-border-focus-outline);
outline-offset: 5px;
box-shadow: 0 0 0 3px var(--px-color-border-focus-boxshadow);
}
svg.info-icon {
min-width: max-content;
}
.info-text {
margin-block-start: 0px;
}

.sr-only {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0 0 0 0) !important;
white-space: nowrap !important;
border: 0 !important;
}