@oslokommune/punkt-react 16.21.0 → 16.22.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.
@@ -8,6 +8,7 @@ export type { THeaderMenuLocale, IHeaderMenuLink, IHeaderMenuIconLink, IHeaderMe
8
8
  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
+ export type { TSelectOption } from './select';
11
12
  export type { TSize3, TSize5, TSize7 } from './size';
12
13
  export type { TAlertSkin, TMessageboxSkin, TAccordionSkin, TCardSkin, TTagSkin } from './skin';
13
14
  export type { IDateConstraints, ICalendarGridDimensions, IGridCellPosition, TDateRangeMap, ISelectionState, ISelectionOptions, } from './calendar';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shape of a single option in a `<pkt-select>` / `<PktSelect>` component.
3
+ * Lives in shared-types so both `@oslokommune/punkt-elements` and
4
+ * `@oslokommune/punkt-react` can re-export the same canonical type.
5
+ */
6
+ export type TSelectOption = {
7
+ value: string;
8
+ label: string;
9
+ selected?: boolean;
10
+ disabled?: boolean;
11
+ hidden?: boolean;
12
+ };
package/package.json CHANGED
@@ -1,15 +1,11 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-react",
3
- "version": "16.21.0",
3
+ "version": "16.22.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",
7
7
  "main": "dist/punkt-react.umd.js",
8
8
  "module": "dist/punkt-react.es.js",
9
- "nohoist": [
10
- "**/@lit",
11
- "**/@lit/**"
12
- ],
13
9
  "files": [
14
10
  "/dist",
15
11
  "src/components/**/*",
@@ -37,9 +33,6 @@
37
33
  "test:watch": "vitest"
38
34
  },
39
35
  "dependencies": {
40
- "@lit-labs/ssr-dom-shim": "^1.2.1",
41
- "@lit/react": "^1.0.7",
42
- "@oslokommune/punkt-elements": "^16.21.0",
43
36
  "classnames": "^2.5.1",
44
37
  "prettier": "^3.3.3",
45
38
  "react-hook-form": "^7.53.0"
@@ -109,5 +102,5 @@
109
102
  "url": "https://github.com/oslokommune/punkt/issues"
110
103
  },
111
104
  "license": "MIT",
112
- "gitHead": "f7f1779ccee5d510e6d011e7ec3edba89b41c255"
105
+ "gitHead": "23fb504541072d6e50b5f23d6c13208e5c0c03ce"
113
106
  }
@@ -34,7 +34,6 @@ describe('PktBreadcrumbs Component', () => {
34
34
  <PktBreadcrumbs breadcrumbs={breadcrumbs} navigationType="router" />
35
35
  </TestRouter>,
36
36
  )
37
- await window.customElements.whenDefined('pkt-icon')
38
37
 
39
38
  expect(getAllByText('Home')).toBeTruthy()
40
39
  expect(getAllByText('Products')).toBeTruthy()
@@ -43,7 +42,6 @@ describe('PktBreadcrumbs Component', () => {
43
42
 
44
43
  it('renders breadcrumbs correctly with anchor navigation', async () => {
45
44
  const { getAllByText } = render(<PktBreadcrumbs breadcrumbs={breadcrumbs} navigationType="anchor" />)
46
- await window.customElements.whenDefined('pkt-icon')
47
45
 
48
46
  expect(getAllByText('Home')).toBeTruthy()
49
47
  expect(getAllByText('Products')).toBeTruthy()
@@ -56,7 +54,6 @@ describe('PktBreadcrumbs Component', () => {
56
54
  <PktBreadcrumbs breadcrumbs={breadcrumbs} navigationType="router" />
57
55
  </TestRouter>,
58
56
  )
59
- await window.customElements.whenDefined('pkt-icon')
60
57
 
61
58
  expect(getAllByText('Home')).toBeTruthy()
62
59
  expect(getAllByText('Products')).toBeTruthy()
@@ -65,7 +62,6 @@ describe('PktBreadcrumbs Component', () => {
65
62
 
66
63
  it('renders back link correctly on mobile with anchor navigation', async () => {
67
64
  const { getAllByText } = render(<PktBreadcrumbs breadcrumbs={breadcrumbs} navigationType="anchor" />)
68
- await window.customElements.whenDefined('pkt-icon')
69
65
 
70
66
  expect(getAllByText('Home')).toBeTruthy()
71
67
  expect(getAllByText('Products')).toBeTruthy()
@@ -74,7 +70,6 @@ describe('PktBreadcrumbs Component', () => {
74
70
 
75
71
  it('renders with no wcag errors with axe', async () => {
76
72
  const { container } = render(<PktBreadcrumbs breadcrumbs={breadcrumbs} navigationType="anchor" />)
77
- await window.customElements.whenDefined('pkt-icon')
78
73
  const results = await axe(container)
79
74
 
80
75
  expect(results).toHaveNoViolations()
@@ -8,7 +8,10 @@ declare global {
8
8
  }
9
9
  }
10
10
 
11
- window.pktAnimationPath = window.pktAnimationPath || 'https://punkt-cdn.oslo.kommune.no/latest/animations/'
11
+ if (typeof window !== 'undefined') {
12
+ window.pktAnimationPath =
13
+ window.pktAnimationPath || 'https://punkt-cdn.oslo.kommune.no/latest/animations/'
14
+ }
12
15
 
13
16
  export interface IPktButton extends ButtonHTMLAttributes<HTMLButtonElement> {
14
17
  iconName?: string
@@ -0,0 +1,217 @@
1
+ import '@testing-library/jest-dom'
2
+
3
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react'
4
+ import { axe, toHaveNoViolations } from 'jest-axe'
5
+ import { afterEach, beforeEach, vi } from 'vitest'
6
+
7
+ import { PktConsent } from './Consent'
8
+
9
+ expect.extend(toHaveNoViolations)
10
+
11
+ type CapturedHandler = ((consent: { value: string | { items: unknown[] } }) => void) | undefined
12
+ let capturedHandler: CapturedHandler
13
+
14
+ const installCookieBannerStub = ({ hasConsent = false }: { hasConsent?: boolean } = {}) => {
15
+ Object.defineProperty(window, 'cookieBanner', {
16
+ value: {
17
+ cookieConsent: {
18
+ validateConsentCookie: vi.fn().mockResolvedValue(hasConsent),
19
+ getConsentCookie: vi.fn().mockReturnValue('{"items":[]}'),
20
+ },
21
+ openCookieModal: vi.fn(),
22
+ },
23
+ writable: true,
24
+ configurable: true,
25
+ })
26
+ capturedHandler = undefined
27
+ Object.defineProperty(window, '__cookieEvents', {
28
+ value: {
29
+ on: vi.fn((_event: string, handler: CapturedHandler) => {
30
+ capturedHandler = handler
31
+ }),
32
+ off: vi.fn(),
33
+ },
34
+ writable: true,
35
+ configurable: true,
36
+ })
37
+ }
38
+
39
+ const preInjectScriptMarker = () => {
40
+ // The component's loadConsentScript() resolves immediately if the marker
41
+ // script is already in the DOM. Inject it up-front so the test doesn't
42
+ // depend on a network fetch that jsdom can't fulfil.
43
+ if (!document.querySelector('#oslo-consent-script')) {
44
+ const marker = document.createElement('script')
45
+ marker.id = 'oslo-consent-script'
46
+ document.head.appendChild(marker)
47
+ }
48
+ }
49
+
50
+ describe('PktConsent', () => {
51
+ beforeEach(() => {
52
+ preInjectScriptMarker()
53
+ installCookieBannerStub()
54
+ })
55
+
56
+ afterEach(() => {
57
+ document.querySelector('#oslo-consent-script')?.remove()
58
+ document.querySelector('#oslo-consent-styles')?.remove()
59
+ delete (window as { cookieBanner?: unknown }).cookieBanner
60
+ delete (window as { __cookieEvents?: unknown }).__cookieEvents
61
+ capturedHandler = undefined
62
+ })
63
+
64
+ describe('Trigger rendering', () => {
65
+ test('renders the default button trigger with the bokmål settings label', () => {
66
+ render(<PktConsent />)
67
+
68
+ expect(
69
+ screen.getByRole('button', { name: 'Innstillinger for informasjonskapsler' }),
70
+ ).toBeInTheDocument()
71
+ })
72
+
73
+ test('uses the English settings label when i18nLanguage is "en"', () => {
74
+ render(<PktConsent i18nLanguage="en" />)
75
+
76
+ expect(screen.getByRole('button', { name: 'Go to settings' })).toBeInTheDocument()
77
+ })
78
+
79
+ test('renders a custom triggerText when provided', () => {
80
+ render(<PktConsent triggerText="Endre samtykke" />)
81
+
82
+ expect(screen.getByRole('button', { name: 'Endre samtykke' })).toBeInTheDocument()
83
+ })
84
+
85
+ test('renders a link trigger when triggerType="link"', () => {
86
+ const { container } = render(<PktConsent triggerType="link" triggerText="Innstillinger" />)
87
+
88
+ const link = container.querySelector('a.pkt-link')
89
+ expect(link).toBeInTheDocument()
90
+ expect(link).toHaveAttribute('href', '#')
91
+ expect(link).toHaveTextContent('Innstillinger')
92
+ })
93
+
94
+ test('renders a footer link with chevron icon when triggerType="footerlink"', () => {
95
+ const { container } = render(
96
+ <PktConsent triggerType="footerlink" triggerText="Innstillinger" />,
97
+ )
98
+
99
+ const link = container.querySelector('a.pkt-footer__link')
100
+ expect(link).toBeInTheDocument()
101
+ expect(link?.querySelector('.pkt-icon')).toHaveAttribute('name', 'chevron-right')
102
+ })
103
+
104
+ test('renders an icon-only button when triggerType="icon"', () => {
105
+ const { container } = render(<PktConsent triggerType="icon" triggerText="Cookies" />)
106
+
107
+ const button = container.querySelector('button')
108
+ expect(button).toHaveClass('pkt-btn--icon-only')
109
+ expect(button).toHaveClass('pkt-btn--tertiary')
110
+ })
111
+ })
112
+
113
+ describe('Click behaviour', () => {
114
+ test('opens the cookie modal on button click', () => {
115
+ vi.useFakeTimers()
116
+ try {
117
+ render(<PktConsent />)
118
+ fireEvent.click(screen.getByRole('button'))
119
+ vi.runAllTimers()
120
+ expect(window.cookieBanner?.openCookieModal).toHaveBeenCalled()
121
+ } finally {
122
+ vi.useRealTimers()
123
+ }
124
+ })
125
+
126
+ test('opens the cookie modal on link click', () => {
127
+ vi.useFakeTimers()
128
+ try {
129
+ const { container } = render(<PktConsent triggerType="link" />)
130
+ const link = container.querySelector('a.pkt-link') as HTMLAnchorElement
131
+ fireEvent.click(link)
132
+ vi.runAllTimers()
133
+ expect(window.cookieBanner?.openCookieModal).toHaveBeenCalled()
134
+ } finally {
135
+ vi.useRealTimers()
136
+ }
137
+ })
138
+ })
139
+
140
+ describe('Side effects', () => {
141
+ test('sets the cookie banner globals from props', async () => {
142
+ render(
143
+ <PktConsent
144
+ devMode
145
+ googleAnalyticsId="GA-123"
146
+ hotjarId="HJ-456"
147
+ cookieDomain=".example.com"
148
+ cookieSecure="true"
149
+ cookieExpiryDays="90"
150
+ />,
151
+ )
152
+
153
+ await waitFor(() => {
154
+ expect(window.cookieBanner_googleAnalyticsId).toBe('GA-123')
155
+ })
156
+ expect(window.cookieBanner_hotjarId).toBe('HJ-456')
157
+ expect(window.cookieBanner_cookieDomain).toBe('.example.com')
158
+ expect(window.cookieBanner_cookieSecure).toBe('true')
159
+ expect(window.cookieBanner_cookieExpiryDays).toBe('90')
160
+ expect(window.cookieBanner_devMode).toBe(true)
161
+ })
162
+ })
163
+
164
+ describe('onToggleConsent', () => {
165
+ test('invokes onToggleConsent with a CustomEvent carrying parsed consent details', async () => {
166
+ installCookieBannerStub({ hasConsent: true })
167
+ const onToggle = vi.fn()
168
+
169
+ render(<PktConsent onToggleConsent={onToggle} />)
170
+
171
+ // First emit comes from the initial consent-cookie read; wait for it,
172
+ // then clear so we can assert specifically on the handler-driven call.
173
+ await waitFor(() => expect(capturedHandler).toBeDefined())
174
+ await waitFor(() => expect(onToggle).toHaveBeenCalled())
175
+ onToggle.mockClear()
176
+
177
+ capturedHandler!({
178
+ value: JSON.stringify({
179
+ items: [
180
+ { name: 'statistics', consent: true },
181
+ { name: 'survey', consent: false },
182
+ ],
183
+ }),
184
+ })
185
+
186
+ expect(onToggle).toHaveBeenCalledTimes(1)
187
+ const event = onToggle.mock.calls[0][0] as CustomEvent<Record<string, boolean>>
188
+ expect(event).toBeInstanceOf(CustomEvent)
189
+ expect(event.type).toBe('toggle-consent')
190
+ expect(event.detail).toEqual({ statistics: true, survey: false })
191
+ })
192
+ })
193
+
194
+ describe('Accessibility', () => {
195
+ test('button trigger has no axe violations', async () => {
196
+ const { container } = render(<PktConsent triggerText="Cookie settings" />)
197
+ const results = await axe(container)
198
+ expect(results).toHaveNoViolations()
199
+ })
200
+
201
+ test('link trigger has no axe violations', async () => {
202
+ const { container } = render(
203
+ <PktConsent triggerType="link" triggerText="Cookie settings" />,
204
+ )
205
+ const results = await axe(container)
206
+ expect(results).toHaveNoViolations()
207
+ })
208
+
209
+ test('footer link trigger has no axe violations', async () => {
210
+ const { container } = render(
211
+ <PktConsent triggerType="footerlink" triggerText="Cookie settings" />,
212
+ )
213
+ const results = await axe(container)
214
+ expect(results).toHaveNoViolations()
215
+ })
216
+ })
217
+ })
@@ -1,23 +1,282 @@
1
1
  'use client'
2
2
 
3
- import { createComponent, EventName } from '@lit/react'
4
- import { type IPktConsent as IPktElConsent, PktConsent as PktElConsent } from '@oslokommune/punkt-elements'
5
- // eslint-disable-next-line no-restricted-syntax -- React is required for createComponent
6
- import React, { ForwardRefExoticComponent, LegacyRef } from 'react'
7
-
8
- export interface IPktConsent extends IPktElConsent {
9
- ref?: LegacyRef<HTMLDivElement>
10
- onToggleConsent?: (e: CustomEvent) => void
11
- }
12
-
13
- export const PktConsent: ForwardRefExoticComponent<IPktConsent> = createComponent({
14
- tagName: 'pkt-consent',
15
- elementClass: PktElConsent,
16
- react: React,
17
- displayName: 'PktConsent',
18
- events: {
19
- onToggleConsent: 'toggle-consent' as EventName<CustomEvent>,
3
+ import {
4
+ forwardRef,
5
+ HTMLAttributes,
6
+ MouseEvent as ReactMouseEvent,
7
+ Ref,
8
+ useEffect,
9
+ useRef,
10
+ } from 'react'
11
+
12
+ import { PktButton } from '../button/Button'
13
+ import { PktIcon } from '../icon/Icon'
14
+ import { consentStrings } from './strings'
15
+
16
+ interface ConsentItem {
17
+ name: string
18
+ consent: boolean
19
+ }
20
+
21
+ interface ConsentValue {
22
+ items: ConsentItem[]
23
+ }
24
+
25
+ interface CookieConsentEvent {
26
+ value: string | ConsentValue
27
+ }
28
+
29
+ type ConsentDetailsMap = Record<string, boolean>
30
+
31
+ type CookieEventHandler = (consent: CookieConsentEvent) => void
32
+
33
+ interface CookieEvents {
34
+ on(eventName: string, handler: CookieEventHandler): void
35
+ off(eventName: string, handler: CookieEventHandler): void
36
+ }
37
+
38
+ interface CookieBannerApi {
39
+ cookieConsent: {
40
+ validateConsentCookie(): Promise<boolean>
41
+ getConsentCookie(): string | ConsentValue
42
+ }
43
+ openCookieModal(): void
44
+ }
45
+
46
+ declare global {
47
+ interface Window {
48
+ cookieBanner_devMode?: boolean
49
+ cookieBanner_cookieDomain?: string | null
50
+ cookieBanner_cookieSecure?: string | null
51
+ cookieBanner_cookieExpiryDays?: string | null
52
+ cookieBanner_googleAnalyticsId?: string | null
53
+ cookieBanner_hotjarId?: string | null
54
+ cookieBanner?: CookieBannerApi
55
+ __cookieEvents?: CookieEvents
56
+ }
57
+ }
58
+
59
+ let consentScriptPromise: Promise<void> | null = null
60
+
61
+ const loadConsentScript = (): Promise<void> => {
62
+ if (consentScriptPromise) return consentScriptPromise
63
+
64
+ consentScriptPromise = new Promise((resolve, reject) => {
65
+ if (document.querySelector('#oslo-consent-script')) {
66
+ resolve()
67
+ return
68
+ }
69
+ const script = document.createElement('script')
70
+ script.src = 'https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.js'
71
+ script.id = 'oslo-consent-script'
72
+ script.onload = () => resolve()
73
+ script.onerror = reject
74
+ document.head.appendChild(script)
75
+
76
+ const styles = document.createElement('link')
77
+ styles.href = 'https://cdn.web.oslo.kommune.no/cb/cb-v1.1.0.css'
78
+ styles.type = 'text/css'
79
+ styles.rel = 'stylesheet'
80
+ styles.id = 'oslo-consent-styles'
81
+ document.head.appendChild(styles)
82
+ })
83
+
84
+ return consentScriptPromise
85
+ }
86
+
87
+ const parseJsonOrPassThrough = <T,>(value: T | string): T => {
88
+ if (typeof value !== 'string') return value
89
+ try {
90
+ return JSON.parse(value) as T
91
+ } catch {
92
+ return value as unknown as T
93
+ }
94
+ }
95
+
96
+ const toConsentDetails = (consent: CookieConsentEvent): ConsentDetailsMap => {
97
+ const parsed = parseJsonOrPassThrough<ConsentValue>(consent.value)
98
+ return parsed.items.reduce<ConsentDetailsMap>((acc, item) => {
99
+ acc[item.name] = item.consent
100
+ return acc
101
+ }, {})
102
+ }
103
+
104
+ export type TPktConsentTriggerType = 'button' | 'link' | 'footerlink' | 'icon'
105
+
106
+ export interface IPktConsent extends HTMLAttributes<HTMLElement> {
107
+ devMode?: boolean
108
+ cookieDomain?: string | null
109
+ cookieSecure?: string | null
110
+ cookieExpiryDays?: string | null
111
+ hotjarId?: string | null
112
+ googleAnalyticsId?: string | null
113
+ i18nLanguage?: string
114
+ triggerType?: TPktConsentTriggerType | null
115
+ triggerText?: string | null
116
+ onToggleConsent?: (e: CustomEvent<ConsentDetailsMap>) => void
117
+ }
118
+
119
+ export const PktConsent = forwardRef<HTMLElement, IPktConsent>(function PktConsent(
120
+ {
121
+ devMode = false,
122
+ cookieDomain = null,
123
+ cookieSecure = null,
124
+ cookieExpiryDays = null,
125
+ hotjarId = null,
126
+ googleAnalyticsId = null,
127
+ i18nLanguage = 'nb',
128
+ triggerType = 'button',
129
+ triggerText,
130
+ onToggleConsent,
131
+ ...rest
20
132
  },
21
- }) as ForwardRefExoticComponent<IPktConsent>
133
+ ref,
134
+ ) {
135
+ const onToggleRef = useRef(onToggleConsent)
136
+ onToggleRef.current = onToggleConsent
137
+
138
+ const configRef = useRef({
139
+ devMode,
140
+ cookieDomain,
141
+ cookieSecure,
142
+ cookieExpiryDays,
143
+ hotjarId,
144
+ googleAnalyticsId,
145
+ })
146
+ configRef.current = {
147
+ devMode,
148
+ cookieDomain,
149
+ cookieSecure,
150
+ cookieExpiryDays,
151
+ hotjarId,
152
+ googleAnalyticsId,
153
+ }
154
+
155
+ const triggerInitRef = useRef<() => void>(() => {})
156
+
157
+ const language = (i18nLanguage in consentStrings.i18n
158
+ ? i18nLanguage
159
+ : 'nb') as keyof typeof consentStrings.i18n
160
+ const resolvedTriggerText =
161
+ triggerText ?? consentStrings.i18n[language].contentPresentation.buttons.settings
162
+
163
+ useEffect(() => {
164
+ let cancelled = false
165
+ let cookieEventHandler: CookieEventHandler | undefined
166
+
167
+ const config = configRef.current
168
+ // cookieBanner_* identifiers are defined by the external cookie banner script
169
+ /* eslint-disable camelcase */
170
+ window.cookieBanner_googleAnalyticsId = config.googleAnalyticsId
171
+ window.cookieBanner_hotjarId = config.hotjarId
172
+ if (config.cookieDomain) window.cookieBanner_cookieDomain = config.cookieDomain
173
+ if (config.cookieSecure) window.cookieBanner_cookieSecure = config.cookieSecure
174
+ if (config.cookieExpiryDays) window.cookieBanner_cookieExpiryDays = config.cookieExpiryDays
175
+ if (config.devMode) window.cookieBanner_devMode = config.devMode
176
+ /* eslint-enable camelcase */
177
+
178
+ const emitConsents = (consent: CookieConsentEvent) => {
179
+ const handler = onToggleRef.current
180
+ if (!handler) return
181
+ handler(
182
+ new CustomEvent<ConsentDetailsMap>('toggle-consent', {
183
+ detail: toConsentDetails(consent),
184
+ bubbles: true,
185
+ cancelable: false,
186
+ }),
187
+ )
188
+ }
189
+
190
+ triggerInitRef.current = () => {
191
+ window.document.dispatchEvent(
192
+ new Event('CookieBannerReady', { bubbles: true, cancelable: true }),
193
+ )
194
+
195
+ const banner = window.cookieBanner
196
+ const events = window.__cookieEvents
197
+ if (!banner || !events) return
198
+
199
+ banner.cookieConsent.validateConsentCookie().then((hasConsent) => {
200
+ if (cancelled || !hasConsent) return
201
+
202
+ const cookie = banner.cookieConsent.getConsentCookie()
203
+ window.setTimeout(() => {
204
+ if (!cancelled) emitConsents({ value: cookie })
205
+ }, 0)
206
+
207
+ if (cookieEventHandler) {
208
+ events.off('CookieManager.setCookie', cookieEventHandler)
209
+ }
210
+ cookieEventHandler = (consent) => emitConsents(consent)
211
+ events.on('CookieManager.setCookie', cookieEventHandler)
212
+ })
213
+ }
214
+
215
+ loadConsentScript().then(() => {
216
+ if (!cancelled) triggerInitRef.current()
217
+ })
218
+
219
+ return () => {
220
+ cancelled = true
221
+ if (cookieEventHandler) {
222
+ window.__cookieEvents?.off('CookieManager.setCookie', cookieEventHandler)
223
+ }
224
+ }
225
+ }, [])
226
+
227
+ const openModal = (e: ReactMouseEvent<HTMLElement>) => {
228
+ e.preventDefault()
229
+ if (!window.cookieBanner?.cookieConsent) {
230
+ triggerInitRef.current()
231
+ }
232
+ setTimeout(() => window.cookieBanner?.openCookieModal())
233
+ }
234
+
235
+ if (triggerType === 'link') {
236
+ return (
237
+ <a
238
+ {...rest}
239
+ ref={ref as Ref<HTMLAnchorElement>}
240
+ href="#"
241
+ className="pkt-link"
242
+ onClick={openModal}
243
+ >
244
+ {resolvedTriggerText}
245
+ </a>
246
+ )
247
+ }
248
+ if (triggerType === 'footerlink') {
249
+ return (
250
+ <a
251
+ {...rest}
252
+ ref={ref as Ref<HTMLAnchorElement>}
253
+ href="#"
254
+ className="pkt-footer__link"
255
+ onClick={openModal}
256
+ >
257
+ <PktIcon name="chevron-right" className="pkt-footer__link-icon" />
258
+ {resolvedTriggerText}
259
+ </a>
260
+ )
261
+ }
262
+ if (triggerType === 'icon') {
263
+ return (
264
+ <PktButton
265
+ ref={ref as Ref<HTMLButtonElement>}
266
+ skin="tertiary"
267
+ variant="icon-only"
268
+ iconName="cookie"
269
+ onClick={openModal}
270
+ >
271
+ {resolvedTriggerText}
272
+ </PktButton>
273
+ )
274
+ }
275
+ return (
276
+ <PktButton ref={ref as Ref<HTMLButtonElement>} onClick={openModal}>
277
+ {resolvedTriggerText}
278
+ </PktButton>
279
+ )
280
+ })
22
281
 
23
282
  PktConsent.displayName = 'PktConsent'