@oslokommune/punkt-react 16.17.2 → 16.17.4

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.
@@ -9,7 +9,7 @@ export { DEFAULT_HEADER_FOOTER_URL } from './header-menu';
9
9
  export type { TLayout, TVerticalPosition, THorizontalPosition, TPosition, TPositionWithCenter, } from './layout';
10
10
  export type { THTMLButtonType, TSelectionMode } from './form';
11
11
  export type { TSize3, TSize5, TSize7 } from './size';
12
- export type { TAlertSkin, TMessageboxSkin, TAccordionSkin, TCardSkin } from './skin';
12
+ export type { TAlertSkin, TMessageboxSkin, TAccordionSkin, TCardSkin, TTagSkin } from './skin';
13
13
  export type { IDateConstraints, ICalendarGridDimensions, IGridCellPosition, TDateRangeMap, ISelectionState, ISelectionOptions, } from './calendar';
14
14
  export type { IDatepickerStrings } from './datepicker';
15
15
  export { defaultSingleStrings, defaultRangeStrings } from './datepicker';
@@ -22,3 +22,7 @@ export type TAccordionSkin = 'borderless' | 'outlined' | 'beige' | 'blue' | 'plu
22
22
  * Card component skin variants
23
23
  */
24
24
  export type TCardSkin = 'outlined' | 'outlined-beige' | 'gray' | 'beige' | 'green' | 'blue';
25
+ /**
26
+ * Tag component skin variants
27
+ */
28
+ export type TTagSkin = 'blue' | 'blue-light' | 'blue-dark' | 'green' | 'red' | 'beige' | 'yellow' | 'grey' | 'gray';
@@ -0,0 +1,10 @@
1
+ export declare const acquireModalScrollLock: (token: {
2
+ locked: boolean;
3
+ }) => void;
4
+ export declare const releaseModalScrollLock: (token: {
5
+ locked: boolean;
6
+ }) => void;
7
+ export type ModalScrollLockToken = {
8
+ locked: boolean;
9
+ };
10
+ export declare const createModalScrollLockToken: () => ModalScrollLockToken;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-react",
3
- "version": "16.17.2",
3
+ "version": "16.17.4",
4
4
  "description": "React komponentbibliotek til Punkt, et designsystem laget av Oslo Origo",
5
5
  "homepage": "https://punkt.oslo.kommune.no",
6
6
  "author": "Team Designsystem, Oslo Origo",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@lit-labs/ssr-dom-shim": "^1.2.1",
41
41
  "@lit/react": "^1.0.7",
42
- "@oslokommune/punkt-elements": "^16.17.2",
42
+ "@oslokommune/punkt-elements": "^16.17.3",
43
43
  "classnames": "^2.5.1",
44
44
  "prettier": "^3.3.3",
45
45
  "react-hook-form": "^7.53.0"
@@ -109,5 +109,5 @@
109
109
  "url": "https://github.com/oslokommune/punkt/issues"
110
110
  },
111
111
  "license": "MIT",
112
- "gitHead": "3eda56e8d6942a8f8aba63b79a469ac12b375e2d"
112
+ "gitHead": "28b1f5b48d08a18a1b237b2220f9f1f1e88a5b7f"
113
113
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import classNames from 'classnames'
4
4
  import { forwardRef, HTMLAttributes, ReactNode, Ref } from 'react'
5
- import type { TCardSkin, TLayout } from 'shared-types'
5
+ import type { TCardSkin, TLayout, TTagSkin } from 'shared-types'
6
6
 
7
7
  import { PktTag } from '../tag/Tag'
8
8
 
@@ -12,8 +12,6 @@ type TCardImageShape = 'square' | 'round'
12
12
  type TCardTagPosition = 'top' | 'bottom'
13
13
  type THeadingLevel = 1 | 2 | 3 | 4 | 5 | 6
14
14
 
15
- type TTagSkin = 'blue' | 'blue-light' | 'blue-dark' | 'green' | 'red' | 'beige' | 'yellow' | 'grey' | 'gray'
16
-
17
15
  interface ICardTag {
18
16
  skin?: TTagSkin
19
17
  iconName?: string
@@ -347,7 +347,7 @@ export const PktHeaderService = forwardRef(
347
347
  </span>
348
348
  )}
349
349
  {serviceName && (
350
- <span className="pkt-header-service__service-name">
350
+ <span className="pkt-header-service__service-name" translate="no">
351
351
  {serviceLink ? (
352
352
  <PktLink href={serviceLink} className="pkt-header-service__service-link ">
353
353
  {serviceName}
@@ -505,7 +505,7 @@ export const PktHeaderService = forwardRef(
505
505
  onClick={() => handleMenuToggle('user')}
506
506
  >
507
507
  <span className="pkt-sr-only">Brukermeny: </span>
508
- {representing?.name || user.name}
508
+ <span translate="no">{representing?.name || user.name}</span>
509
509
  </PktButton>
510
510
  {openMenu === 'user' && user && (
511
511
  <div
@@ -13,6 +13,12 @@ import {
13
13
  useRef,
14
14
  } from 'react'
15
15
 
16
+ import {
17
+ acquireModalScrollLock,
18
+ createModalScrollLockToken,
19
+ releaseModalScrollLock,
20
+ } from 'shared-utils/modal-scroll-lock'
21
+
16
22
  import { PktButton } from '../button/Button'
17
23
 
18
24
  export interface IPktModal
@@ -53,6 +59,7 @@ export const PktModal = forwardRef(
53
59
  ref: ForwardedRef<HTMLDialogElement>,
54
60
  ) => {
55
61
  const internalRef = useRef<HTMLDialogElement | null>(null)
62
+ const scrollLockToken = useRef(createModalScrollLockToken())
56
63
 
57
64
  // Merge consumer ref + internal ref so we always have a working DOM handle
58
65
  // for our own logic, regardless of whether the consumer passes a callback ref
@@ -69,38 +76,33 @@ export const PktModal = forwardRef(
69
76
  const close = useCallback(() => {
70
77
  if (!internalRef.current?.open) return
71
78
  internalRef.current.close()
79
+ releaseModalScrollLock(scrollLockToken.current)
72
80
  onClose?.()
73
81
  }, [onClose])
74
82
 
75
- // Synkroniser scroll-lock med dialogens faktiske åpen/lukket-tilstand
76
- useEffect(() => {
77
- const dialog = internalRef.current
78
- if (!dialog) return
79
-
80
- const observer = new MutationObserver(() => {
81
- if (dialog.open) {
82
- document.body.classList.add('pkt-modal--open')
83
- } else {
84
- document.body.classList.remove('pkt-modal--open')
85
- }
86
- })
87
- observer.observe(dialog, { attributes: true, attributeFilter: ['open'] })
88
- return () => observer.disconnect()
89
- }, [])
90
-
91
83
  // Deklarativ åpne/lukke via open-prop
92
84
  useEffect(() => {
93
85
  if (open) {
94
86
  if (!internalRef.current?.open) {
95
87
  internalRef.current?.showModal()
96
88
  }
89
+ acquireModalScrollLock(scrollLockToken.current)
97
90
  } else {
98
91
  if (internalRef.current?.open) {
99
92
  internalRef.current.close()
100
93
  }
94
+ releaseModalScrollLock(scrollLockToken.current)
101
95
  }
102
96
  }, [open])
103
97
 
98
+ // Rydd opp scroll-lock hvis modalen avmonteres mens den er åpen
99
+ useEffect(() => {
100
+ const token = scrollLockToken.current
101
+ return () => {
102
+ releaseModalScrollLock(token)
103
+ }
104
+ }, [])
105
+
104
106
  const handleBackdropClick = useCallback(
105
107
  (event: React.MouseEvent<HTMLDialogElement>) => {
106
108
  if (closeOnBackdropClick && event.target === internalRef.current) {
@@ -111,6 +113,7 @@ export const PktModal = forwardRef(
111
113
  )
112
114
 
113
115
  const handleNativeClose = useCallback(() => {
116
+ releaseModalScrollLock(scrollLockToken.current)
114
117
  onClose?.()
115
118
  }, [onClose])
116
119
 
@@ -3,10 +3,10 @@
3
3
  import { forwardRef, type KeyboardEvent, type MouseEvent, type ReactNode } from 'react'
4
4
 
5
5
  import { PktIcon } from '../icon/Icon'
6
- import { type IPktTag, PktTag } from '../tag/Tag'
7
- import { useTabsContext } from './Tabs'
6
+ import type { TTagSkin } from 'shared-types'
8
7
 
9
- export type TSkin = IPktTag['skin']
8
+ import { PktTag } from '../tag/Tag'
9
+ import { useTabsContext } from './Tabs'
10
10
 
11
11
  export interface IPktTabItem {
12
12
  children: ReactNode
@@ -17,7 +17,7 @@ export interface IPktTabItem {
17
17
  icon?: string
18
18
  controls?: string
19
19
  tag?: string
20
- tagSkin?: TSkin
20
+ tagSkin?: TTagSkin
21
21
  index?: number
22
22
  }
23
23
 
@@ -12,11 +12,11 @@ import {
12
12
  useRef,
13
13
  } from 'react'
14
14
 
15
+ import type { TTagSkin } from 'shared-types'
16
+
15
17
  import { PktIcon } from '../icon/Icon'
16
18
  import { PktTabItem } from './TabItem'
17
19
 
18
- export type TSkin = 'blue' | 'green' | 'red' | 'beige' | 'yellow' | 'grey' | 'gray' | 'blue-light'
19
-
20
20
  // Context for passing tab navigation logic to children
21
21
  interface ITabsContext {
22
22
  arrowNav: boolean
@@ -48,7 +48,7 @@ export interface IPktTab {
48
48
  controls?: string
49
49
  tag?: {
50
50
  text: string
51
- skin: TSkin | undefined
51
+ skin: TTagSkin | undefined
52
52
  }
53
53
  active?: boolean
54
54
  }
@@ -14,10 +14,12 @@ import {
14
14
  useState,
15
15
  } from 'react'
16
16
 
17
+ import type { TTagSkin } from 'shared-types'
18
+
17
19
  import { PktIcon } from '..'
18
20
 
19
21
  interface BasePktTagProps {
20
- skin?: 'blue' | 'blue-light' | 'blue-dark' | 'green' | 'red' | 'beige' | 'yellow' | 'grey' | 'gray'
22
+ skin?: TTagSkin
21
23
  textStyle?: 'normal-text' | 'thin-text'
22
24
  size?: 'small' | 'medium' | 'large'
23
25
  closeTag?: boolean