@oslokommune/punkt-react 13.19.1 → 13.20.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-react",
3
- "version": "13.19.1",
3
+ "version": "13.20.0",
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": "^13.19.1",
42
+ "@oslokommune/punkt-elements": "^13.20.0",
43
43
  "classnames": "^2.5.1",
44
44
  "prettier": "^3.3.3",
45
45
  "react-hook-form": "^7.53.0"
@@ -103,5 +103,5 @@
103
103
  "url": "https://github.com/oslokommune/punkt/issues"
104
104
  },
105
105
  "license": "MIT",
106
- "gitHead": "5b4f6001bf615f85b3ea5cac18f4a2f8a14dfbd9"
106
+ "gitHead": "fa8d8103ac24cb2da42e47d09cf04c73f765cfd0"
107
107
  }
@@ -127,3 +127,67 @@ describe('accessibility', () => {
127
127
  expect(results).toHaveNoViolations()
128
128
  })
129
129
  })
130
+
131
+ describe('PktButton icon paths', () => {
132
+ test('passes iconPath to PktIcon when provided', () => {
133
+ const customPath = 'https://custom-cdn.example.com/icons/'
134
+ render(
135
+ <PktButton variant="icon-left" iconName="user" iconPath={customPath}>
136
+ Test Button
137
+ </PktButton>,
138
+ )
139
+
140
+ const icon = document.querySelector('.pkt-btn__icon:not(.pkt-btn__spinner)') as HTMLElement & { path?: string }
141
+ expect(icon?.path).toBe(customPath)
142
+ })
143
+
144
+ test('does not set path property when iconPath is not provided', () => {
145
+ render(
146
+ <PktButton variant="icon-left" iconName="user">
147
+ Test Button
148
+ </PktButton>,
149
+ )
150
+
151
+ const icon = document.querySelector('.pkt-btn__icon:not(.pkt-btn__spinner)') as HTMLElement & { path?: string }
152
+ // When not provided, path uses PktIcon's default
153
+ expect(icon?.path).toBe('https://punkt-cdn.oslo.kommune.no/latest/icons/')
154
+ })
155
+
156
+ test('passes secondIconPath to second PktIcon when provided', () => {
157
+ const customPath = 'https://custom-cdn.example.com/icons/'
158
+ render(
159
+ <PktButton variant="icons-right-and-left" iconName="home" secondIconName="star" secondIconPath={customPath}>
160
+ Test Button
161
+ </PktButton>,
162
+ )
163
+
164
+ const icons = document.querySelectorAll('.pkt-btn__icon:not(.pkt-btn__spinner)') as NodeListOf<
165
+ HTMLElement & { path?: string }
166
+ >
167
+ expect(icons).toHaveLength(2)
168
+ expect(icons[1]?.path).toBe(customPath)
169
+ })
170
+
171
+ test('handles both iconPath and secondIconPath independently', () => {
172
+ const iconPath = 'https://custom-cdn.example.com/icons/'
173
+ const secondIconPath = 'https://another-cdn.example.com/icons/'
174
+ render(
175
+ <PktButton
176
+ variant="icons-right-and-left"
177
+ iconName="home"
178
+ secondIconName="star"
179
+ iconPath={iconPath}
180
+ secondIconPath={secondIconPath}
181
+ >
182
+ Test Button
183
+ </PktButton>,
184
+ )
185
+
186
+ const icons = document.querySelectorAll('.pkt-btn__icon:not(.pkt-btn__spinner)') as NodeListOf<
187
+ HTMLElement & { path?: string }
188
+ >
189
+ expect(icons).toHaveLength(2)
190
+ expect(icons[0]?.path).toBe(iconPath)
191
+ expect(icons[1]?.path).toBe(secondIconPath)
192
+ })
193
+ })
@@ -14,6 +14,8 @@ window.pktAnimationPath = window.pktAnimationPath || 'https://punkt-cdn.oslo.kom
14
14
  export interface IPktButton extends ButtonHTMLAttributes<HTMLButtonElement> {
15
15
  iconName?: string
16
16
  secondIconName?: string
17
+ iconPath?: string
18
+ secondIconPath?: string
17
19
  mode?: 'light' | 'dark'
18
20
  size?: 'small' | 'medium' | 'large'
19
21
  fullWidth?: boolean
@@ -46,6 +48,8 @@ export const PktButton = forwardRef(
46
48
  className,
47
49
  iconName = 'user',
48
50
  secondIconName = 'user',
51
+ iconPath,
52
+ secondIconPath,
49
53
  size = 'medium',
50
54
  fullWidth = false,
51
55
  fullWidthOnMobile = false,
@@ -89,9 +93,17 @@ export const PktButton = forwardRef(
89
93
  {isLoading && (
90
94
  <PktIcon className="pkt-btn__icon pkt-btn__spinner" name="spinner-blue" path={loadingAnimationPath} />
91
95
  )}
92
- {variant !== 'label-only' && <PktIcon className="pkt-btn__icon" name={iconName}></PktIcon>}
96
+ {variant !== 'label-only' && (
97
+ <PktIcon className="pkt-btn__icon" name={iconName} {...(iconPath && { path: iconPath })}></PktIcon>
98
+ )}
93
99
  <span className="pkt-btn__text">{children}</span>
94
- {variant === 'icons-right-and-left' && <PktIcon className="pkt-btn__icon" name={secondIconName}></PktIcon>}
100
+ {variant === 'icons-right-and-left' && (
101
+ <PktIcon
102
+ className="pkt-btn__icon"
103
+ name={secondIconName}
104
+ {...(secondIconPath && { path: secondIconPath })}
105
+ ></PktIcon>
106
+ )}
95
107
  </button>
96
108
  )
97
109
  },
@@ -8,6 +8,7 @@ import {
8
8
  ReactNode,
9
9
  RefObject,
10
10
  useCallback,
11
+ useEffect,
11
12
  useMemo,
12
13
  useRef,
13
14
  useState,
@@ -37,7 +38,7 @@ interface SpanPktTagProps extends BasePktTagProps, HTMLAttributes<HTMLSpanElemen
37
38
  type?: undefined
38
39
  }
39
40
 
40
- export type IPktTag = ButtonPktTagProps | SpanPktTagProps;
41
+ export type IPktTag = ButtonPktTagProps | SpanPktTagProps
41
42
 
42
43
  export const PktTag = forwardRef<HTMLSpanElement | HTMLButtonElement, ButtonPktTagProps | SpanPktTagProps>(
43
44
  (
@@ -67,13 +68,15 @@ export const PktTag = forwardRef<HTMLSpanElement | HTMLButtonElement, ButtonPktT
67
68
  }, [setClosed])
68
69
 
69
70
  const spanRef: RefObject<HTMLButtonElement | HTMLSpanElement> = useRef<HTMLButtonElement | HTMLSpanElement>(null)
71
+ const [labelText, setLabelText] = useState('')
72
+
73
+ useEffect(() => {
74
+ setLabelText(spanRef.current?.textContent?.trim() ?? '')
75
+ }, [children])
70
76
 
71
77
  const ariaDescription = useMemo(() => {
72
- if (closeTag && !ariaLabel) {
73
- const label = spanRef.current?.textContent?.trim()
74
- return (label && `Klikk for å fjerne ${label}`) || ariaDescriptionPropValue
75
- }
76
- }, [closeTag, ariaLabel])
78
+ if (closeTag && !ariaLabel) return (labelText && `Klikk for å fjerne ${labelText}`) || ariaDescriptionPropValue
79
+ }, [closeTag, ariaLabel, labelText, ariaDescriptionPropValue])
77
80
 
78
81
  const classes = {
79
82
  'pkt-tag': true,
@@ -112,7 +115,7 @@ export const PktTag = forwardRef<HTMLSpanElement | HTMLButtonElement, ButtonPktT
112
115
  } else {
113
116
  return (
114
117
  <span {...props} className={classNames(classes, className)} ref={forwardedRef as ForwardedRef<HTMLSpanElement>}>
115
- {iconName && <PktIcon className={'pkt-tag__icon'} name={iconName} />}
118
+ {iconName && <PktIcon className={'pkt-tag__icon'} name={iconName} aria-hidden="true" />}
116
119
  <span ref={spanRef}>{children}</span>
117
120
  </span>
118
121
  )