@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.
- package/CHANGELOG.md +35 -0
- package/dist/index.d.ts +16 -6
- package/dist/punkt-react.es.js +2772 -15000
- package/dist/punkt-react.umd.js +2 -2422
- package/dist/shared-types/index.d.ts +1 -0
- package/dist/shared-types/select.d.ts +12 -0
- package/package.json +2 -9
- package/src/components/breadcrumbs/Breadcrumbs.test.tsx +0 -5
- package/src/components/button/Button.tsx +4 -1
- package/src/components/consent/Consent.test.tsx +217 -0
- package/src/components/consent/Consent.tsx +277 -18
- package/src/components/consent/strings.ts +125 -0
- package/src/components/icon/Icon.tsx +8 -21
- package/src/components/searchinput/SearchInput.test.tsx +0 -8
- package/src/components/select/Select.tsx +2 -6
- package/src/components/tag/Tag.test.tsx +0 -1
- package/src/components/textarea/Textarea.test.tsx +0 -1
- package/src/components/timepicker/Timepicker.test.tsx +0 -1
- package/dist/dialog-polyfill.esm-0dVT8G1o-Cf1Ux-Z9.js +0 -315
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export const consentStrings = {
|
|
2
|
+
i18n: {
|
|
3
|
+
nb: {
|
|
4
|
+
contentPresentation: {
|
|
5
|
+
title: 'Oslo kommune bruker informasjonskapsler',
|
|
6
|
+
description: [
|
|
7
|
+
'For at nettstedet skal fungere og være trygt, bruker Oslo kommune informasjonskapsler. Noen er teknisk nødvendige, mens andre sikrer ulik funksjonalitet.',
|
|
8
|
+
'Godtar du alle informasjonskapsler, tillater du også at vi samler inn data om statistikk og brukeradferd. Da hjelper du oss med å lage et bedre nettsted uten at du trenger å dele noe personlig informasjon med oss.',
|
|
9
|
+
],
|
|
10
|
+
buttons: {
|
|
11
|
+
accept: 'Godta alle',
|
|
12
|
+
reject: 'Kun nødvendige',
|
|
13
|
+
settings: 'Innstillinger for informasjonskapsler',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
contentSettings: {
|
|
17
|
+
title: 'Innstillinger for informasjonskapsler',
|
|
18
|
+
description: [
|
|
19
|
+
'Her kan du velge hvilke typer informasjonskapsler du vil tillate. Tillatelsen gjelder i 90 dager. Husk at nødvendige informasjonskapsler ikke kan velges bort.',
|
|
20
|
+
'Du kan når som helst endre innstillingene og finne mer informasjon nederst på nettstedet under «Innstillinger for informasjonskapsler» og «Personvern og informasjonskapsler».',
|
|
21
|
+
],
|
|
22
|
+
buttons: {
|
|
23
|
+
back: 'Tilbake',
|
|
24
|
+
save: 'Lagre innstillinger',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
en: {
|
|
29
|
+
contentPresentation: {
|
|
30
|
+
title: 'Before you visit Oslo kommune ...',
|
|
31
|
+
description: [
|
|
32
|
+
'This website uses cookies to make improvements. In this context, we need your consent to measure the traffic on the website in relation to statistics and feedback.',
|
|
33
|
+
'To read more about what we use cookies for, go to our privacy declaration which you will find at the bottom of our websites.',
|
|
34
|
+
],
|
|
35
|
+
buttons: {
|
|
36
|
+
accept: 'Yes, I accept',
|
|
37
|
+
reject: 'Only necessary',
|
|
38
|
+
settings: 'Go to settings',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
contentSettings: {
|
|
42
|
+
title: 'Her kan du aktivt velge mellom ulike informasjonskapsler',
|
|
43
|
+
description: [
|
|
44
|
+
'For å lese mer om hva vi bruker informasjonskapsler til gå til vår personvernserklering som du finner på våre nettsider',
|
|
45
|
+
],
|
|
46
|
+
buttons: {
|
|
47
|
+
back: 'Back',
|
|
48
|
+
save: 'Save settings',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
cookies: [
|
|
54
|
+
{
|
|
55
|
+
name: 'statistics',
|
|
56
|
+
defaultValue: null,
|
|
57
|
+
i18n: {
|
|
58
|
+
nb: {
|
|
59
|
+
title: 'Statistikk og analyse',
|
|
60
|
+
description:
|
|
61
|
+
'Jeg godtar at Oslo kommune bruker informasjonskapsler til å innhente data om statistikk og brukeradferd.',
|
|
62
|
+
buttons: {
|
|
63
|
+
yes: 'Ja',
|
|
64
|
+
no: 'Nei',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
en: {
|
|
68
|
+
title: 'Statistics and analytics',
|
|
69
|
+
description: 'Select your preference for statistics and analytics',
|
|
70
|
+
buttons: {
|
|
71
|
+
yes: 'Yes',
|
|
72
|
+
no: 'No',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'survey',
|
|
79
|
+
defaultValue: null,
|
|
80
|
+
i18n: {
|
|
81
|
+
nb: {
|
|
82
|
+
title: 'Skriftlige tilbakemeldinger',
|
|
83
|
+
description:
|
|
84
|
+
'Jeg godtar at Oslo kommune bruker informasjonskapsler til å vise responsfelt og registrere tilbakemeldinger.',
|
|
85
|
+
buttons: {
|
|
86
|
+
yes: 'Ja',
|
|
87
|
+
no: 'Nei',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
en: {
|
|
91
|
+
title: 'Survey',
|
|
92
|
+
description: 'Select your preference for survey',
|
|
93
|
+
buttons: {
|
|
94
|
+
yes: 'Yes',
|
|
95
|
+
no: 'No',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'functional',
|
|
102
|
+
defaultValue: true,
|
|
103
|
+
i18n: {
|
|
104
|
+
nb: {
|
|
105
|
+
title: 'Funksjonelle informasjonskapsler',
|
|
106
|
+
description:
|
|
107
|
+
'Jeg godtar at Oslo kommune bruker informasjonskapsler for å gjøre ulike funksjoner på nettstedet mulige (for eksempel skjemaer og barnehagevelger).',
|
|
108
|
+
buttons: {
|
|
109
|
+
yes: 'Ja',
|
|
110
|
+
no: 'Nei',
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
en: {
|
|
114
|
+
title: 'Functional cookies',
|
|
115
|
+
description:
|
|
116
|
+
'For the website to function optimally, we recommend that you accept these cookies',
|
|
117
|
+
buttons: {
|
|
118
|
+
yes: 'Yes',
|
|
119
|
+
no: 'No',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
}
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames'
|
|
4
|
-
import {
|
|
5
|
-
forwardRef,
|
|
6
|
-
HTMLAttributes,
|
|
7
|
-
MutableRefObject,
|
|
8
|
-
useEffect,
|
|
9
|
-
useLayoutEffect,
|
|
10
|
-
useRef,
|
|
11
|
-
} from 'react'
|
|
4
|
+
import { forwardRef, HTMLAttributes, MutableRefObject, useEffect, useLayoutEffect, useRef } from 'react'
|
|
12
5
|
import type { Booleanish } from 'shared-types'
|
|
13
6
|
|
|
14
7
|
const defaultPath = 'https://punkt-cdn.oslo.kommune.no/latest/icons/'
|
|
15
8
|
|
|
16
9
|
if (typeof window !== 'undefined') {
|
|
17
|
-
window.pktFetch =
|
|
18
|
-
window.pktFetch === undefined ? (fetch as unknown as typeof window.pktFetch) : window.pktFetch
|
|
10
|
+
window.pktFetch = window.pktFetch === undefined ? (fetch as unknown as typeof window.pktFetch) : window.pktFetch
|
|
19
11
|
window.pktIconPath = window.pktIconPath || defaultPath
|
|
20
12
|
}
|
|
21
13
|
|
|
@@ -24,8 +16,7 @@ const dlCache: { [key: string]: Promise<string> } = {}
|
|
|
24
16
|
const MAX_RETRIES = 2
|
|
25
17
|
const RETRY_DELAY = 1500
|
|
26
18
|
|
|
27
|
-
const isSessionStorageAvailable =
|
|
28
|
-
typeof Storage !== 'undefined' && typeof sessionStorage !== 'undefined'
|
|
19
|
+
const isSessionStorageAvailable = typeof Storage !== 'undefined' && typeof sessionStorage !== 'undefined'
|
|
29
20
|
|
|
30
21
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect
|
|
31
22
|
|
|
@@ -45,21 +36,19 @@ const fetchIcon = (url: string): Promise<string> =>
|
|
|
45
36
|
const fetchIconWithRetry = async (url: string, retries = MAX_RETRIES): Promise<string> => {
|
|
46
37
|
try {
|
|
47
38
|
return await fetchIcon(url)
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- we want to catch all errors, including from fetchIcon
|
|
48
40
|
} catch (error) {
|
|
49
41
|
if (retries > 0) {
|
|
50
42
|
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY))
|
|
51
43
|
return fetchIconWithRetry(url, retries - 1)
|
|
52
44
|
}
|
|
53
|
-
// eslint-disable-next-line no-console
|
|
45
|
+
// eslint-disable-next-line no-console -- we want to log the error when all retries have been exhausted
|
|
54
46
|
console.error('Failed to fetch icon: ' + url)
|
|
55
47
|
return errorSvg
|
|
56
48
|
}
|
|
57
49
|
}
|
|
58
50
|
|
|
59
|
-
const downloadIconOrGetFromCache = async (
|
|
60
|
-
name: string,
|
|
61
|
-
path: string | undefined,
|
|
62
|
-
): Promise<string | null> => {
|
|
51
|
+
const downloadIconOrGetFromCache = async (name: string, path: string | undefined): Promise<string | null> => {
|
|
63
52
|
const key = path + name + '.svg'
|
|
64
53
|
|
|
65
54
|
if (isSessionStorageAvailable && sessionStorage.getItem(key)) {
|
|
@@ -108,14 +97,12 @@ export const PktIcon = forwardRef<HTMLSpanElement, IPktIcon>(function PktIcon(
|
|
|
108
97
|
},
|
|
109
98
|
forwardedRef,
|
|
110
99
|
) {
|
|
111
|
-
const resolvedPath =
|
|
112
|
-
path ?? (typeof window !== 'undefined' ? window.pktIconPath : defaultPath)
|
|
100
|
+
const resolvedPath = path ?? (typeof window !== 'undefined' ? window.pktIconPath : defaultPath)
|
|
113
101
|
const elementRef = useRef<HTMLSpanElement | null>(null)
|
|
114
102
|
|
|
115
103
|
const explicitAriaHidden = toBoolean(ariaHidden) ?? toBoolean(ariaHiddenAttr)
|
|
116
104
|
const explicitAriaLabel = ariaLabel ?? ariaLabelAttr
|
|
117
|
-
const effectiveAriaHidden =
|
|
118
|
-
explicitAriaHidden !== undefined ? explicitAriaHidden : !explicitAriaLabel
|
|
105
|
+
const effectiveAriaHidden = explicitAriaHidden !== undefined ? explicitAriaHidden : !explicitAriaLabel
|
|
119
106
|
const effectiveAriaLabel = effectiveAriaHidden ? undefined : explicitAriaLabel || name
|
|
120
107
|
|
|
121
108
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -25,26 +25,22 @@ const Wrapper = (props: { onChange: (e: ChangeEvent) => void }) => {
|
|
|
25
25
|
describe('PktSearchInput', () => {
|
|
26
26
|
it('renders with form element when action prop exists', async () => {
|
|
27
27
|
const { container } = render(<PktSearchInput id="test-search-input" action="/search" />)
|
|
28
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
29
28
|
expect(container.querySelector('form')).toBeInTheDocument()
|
|
30
29
|
})
|
|
31
30
|
|
|
32
31
|
it('renders with div element when action prop does not exist', async () => {
|
|
33
32
|
const { container } = render(<PktSearchInput id="test-search-input" />)
|
|
34
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
35
33
|
expect(container.querySelector('div')).toBeInTheDocument()
|
|
36
34
|
expect(container.querySelector('form')).not.toBeInTheDocument()
|
|
37
35
|
})
|
|
38
36
|
|
|
39
37
|
it('renders with label element when label prop exists', async () => {
|
|
40
38
|
const { container } = render(<PktSearchInput id="test-search-input" label="Test Label" />)
|
|
41
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
42
39
|
expect(container.querySelector('label')).toBeInTheDocument()
|
|
43
40
|
})
|
|
44
41
|
|
|
45
42
|
it('renders with div element when label prop does not exist', async () => {
|
|
46
43
|
const { container } = render(<PktSearchInput id="test-search-input" />)
|
|
47
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
48
44
|
expect(container.querySelector('div')).toBeInTheDocument()
|
|
49
45
|
expect(container.querySelector('label')).not.toBeInTheDocument()
|
|
50
46
|
})
|
|
@@ -52,7 +48,6 @@ describe('PktSearchInput', () => {
|
|
|
52
48
|
it('calls onSearch prop with input value on button click', async () => {
|
|
53
49
|
const mockOnSearch = vi.fn()
|
|
54
50
|
const { getByRole, getByPlaceholderText } = render(<Wrapper onChange={mockOnSearch} />)
|
|
55
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
56
51
|
|
|
57
52
|
const inputElement = getByPlaceholderText('Søk…')
|
|
58
53
|
const buttonElement = getByRole('button')
|
|
@@ -76,7 +71,6 @@ describe('PktSearchInput', () => {
|
|
|
76
71
|
suggestions={[{ text: 'Ingen resultater', nonInteractive: true }]}
|
|
77
72
|
/>,
|
|
78
73
|
)
|
|
79
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
80
74
|
|
|
81
75
|
const row = screen.getByText('Ingen resultater').closest('.pkt-searchinput__suggestion')
|
|
82
76
|
expect(row?.tagName.toLowerCase()).toBe('div')
|
|
@@ -90,7 +84,6 @@ describe('PktSearchInput', () => {
|
|
|
90
84
|
]
|
|
91
85
|
|
|
92
86
|
render(<PktSearchInput id="test-search-input" suggestions={suggestions} />)
|
|
93
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
94
87
|
|
|
95
88
|
// Check if suggestion elements are rendered
|
|
96
89
|
suggestions.forEach((suggestion) => {
|
|
@@ -105,7 +98,6 @@ describe('PktSearchInput', () => {
|
|
|
105
98
|
{ title: 'Suggestion 2', onClick: vi.fn() },
|
|
106
99
|
]
|
|
107
100
|
const { container } = render(<PktSearchInput id="test-search-input" label="My label" suggestions={suggestions} />)
|
|
108
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
109
101
|
const results = await axe(container)
|
|
110
102
|
expect(results).toHaveNoViolations()
|
|
111
103
|
})
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { ForwardedRef, forwardRef, ReactNode, SelectHTMLAttributes } from 'react'
|
|
4
|
+
import type { TSelectOption } from 'shared-types'
|
|
4
5
|
|
|
5
6
|
import { PktInputWrapper } from '../inputwrapper/InputWrapper'
|
|
6
7
|
|
|
7
|
-
export type TSelectOption
|
|
8
|
-
value: string
|
|
9
|
-
label: string
|
|
10
|
-
selected?: boolean
|
|
11
|
-
disabled?: boolean
|
|
12
|
-
}
|
|
8
|
+
export type { TSelectOption }
|
|
13
9
|
|
|
14
10
|
export interface IPktSelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
|
|
15
11
|
ariaDescribedby?: string
|
|
@@ -14,7 +14,6 @@ const render = async (
|
|
|
14
14
|
options?: Omit<RenderOptions, 'queries'> | undefined,
|
|
15
15
|
): Promise<RenderResult> => {
|
|
16
16
|
const renderResult = originalRender(ui, options)
|
|
17
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
18
17
|
return Promise.resolve(renderResult)
|
|
19
18
|
}
|
|
20
19
|
|
|
@@ -57,7 +57,6 @@ describe('PktTextarea', () => {
|
|
|
57
57
|
describe('accessibility', () => {
|
|
58
58
|
it('renders with no wcag errors with axe', async () => {
|
|
59
59
|
const { container } = render(<PktTextarea label="Input Label" id="inputId" />)
|
|
60
|
-
await window.customElements.whenDefined('pkt-textarea')
|
|
61
60
|
const results = await axe(container)
|
|
62
61
|
expect(results).toHaveNoViolations()
|
|
63
62
|
})
|
|
@@ -269,7 +269,6 @@ describe('PktTimepicker', () => {
|
|
|
269
269
|
describe('Accessibility', () => {
|
|
270
270
|
test('passes axe in default state', async () => {
|
|
271
271
|
const { container } = render(<PktTimepicker id={id} name="t" label={label} />)
|
|
272
|
-
await window.customElements.whenDefined('pkt-icon')
|
|
273
272
|
const results = await axe(container)
|
|
274
273
|
expect(results).toHaveNoViolations()
|
|
275
274
|
})
|
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
if (typeof HTMLElement === 'undefined') { globalThis.HTMLElement = function() {} };
|
|
3
|
-
if (typeof document === 'undefined') {
|
|
4
|
-
globalThis.document = {
|
|
5
|
-
createTreeWalker: function() {
|
|
6
|
-
return {
|
|
7
|
-
currentNode: null,
|
|
8
|
-
nextNode: function() { return null; },
|
|
9
|
-
previousNode: function() { return null; },
|
|
10
|
-
parentNode: function() { return null; },
|
|
11
|
-
firstChild: function() { return null; },
|
|
12
|
-
lastChild: function() { return null; },
|
|
13
|
-
previousSibling: function() { return null; },
|
|
14
|
-
nextSibling: function() { return null; }
|
|
15
|
-
};
|
|
16
|
-
},
|
|
17
|
-
getElementsByTagName: function() { return []; },
|
|
18
|
-
querySelectorAll: function() { return []; },
|
|
19
|
-
querySelector: function() {
|
|
20
|
-
return {
|
|
21
|
-
querySelectorAll: function() { return []; },
|
|
22
|
-
getElementsByTagName: function() { return []; }
|
|
23
|
-
};
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
if (typeof customElements === 'undefined') { globalThis.customElements = { define: function() {} }; }
|
|
28
|
-
if (typeof window === 'undefined') { globalThis.window = globalThis; }
|
|
29
|
-
if (typeof SVGElement === 'undefined') { globalThis.SVGElement = function() {} };
|
|
30
|
-
if (typeof Element === 'undefined') {
|
|
31
|
-
globalThis.Element = function() {};
|
|
32
|
-
globalThis.Element.prototype.querySelectorAll = function() {
|
|
33
|
-
return [];
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
//#region ../elements/dist/dialog-polyfill.esm-0dVT8G1o.js
|
|
37
|
-
var e = window.CustomEvent;
|
|
38
|
-
(!e || typeof e == "object") && (e = function(e, t) {
|
|
39
|
-
t ||= {};
|
|
40
|
-
var n = document.createEvent("CustomEvent");
|
|
41
|
-
return n.initCustomEvent(e, !!t.bubbles, !!t.cancelable, t.detail || null), n;
|
|
42
|
-
}, e.prototype = window.Event.prototype);
|
|
43
|
-
function t(e, t) {
|
|
44
|
-
var n = "on" + t.type.toLowerCase();
|
|
45
|
-
return typeof e[n] == "function" && e[n](t), e.dispatchEvent(t);
|
|
46
|
-
}
|
|
47
|
-
function n(e) {
|
|
48
|
-
for (; e && e !== document.body;) {
|
|
49
|
-
var t = window.getComputedStyle(e), n = function(e, n) {
|
|
50
|
-
return !(t[e] === void 0 || t[e] === n);
|
|
51
|
-
};
|
|
52
|
-
if (t.opacity < 1 || n("zIndex", "auto") || n("transform", "none") || n("mixBlendMode", "normal") || n("filter", "none") || n("perspective", "none") || t.isolation === "isolate" || t.position === "fixed" || t.webkitOverflowScrolling === "touch") return !0;
|
|
53
|
-
e = e.parentElement;
|
|
54
|
-
}
|
|
55
|
-
return !1;
|
|
56
|
-
}
|
|
57
|
-
function r(e) {
|
|
58
|
-
for (; e;) {
|
|
59
|
-
if (e.localName === "dialog") return e;
|
|
60
|
-
e = e.parentElement ? e.parentElement : e.parentNode ? e.parentNode.host : null;
|
|
61
|
-
}
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
function i(e) {
|
|
65
|
-
for (; e && e.shadowRoot && e.shadowRoot.activeElement;) e = e.shadowRoot.activeElement;
|
|
66
|
-
e && e.blur && e !== document.body && e.blur();
|
|
67
|
-
}
|
|
68
|
-
function a(e, t) {
|
|
69
|
-
for (var n = 0; n < e.length; ++n) if (e[n] === t) return !0;
|
|
70
|
-
return !1;
|
|
71
|
-
}
|
|
72
|
-
function o(e) {
|
|
73
|
-
return !e || !e.hasAttribute("method") ? !1 : e.getAttribute("method").toLowerCase() === "dialog";
|
|
74
|
-
}
|
|
75
|
-
function s(e) {
|
|
76
|
-
var t = [
|
|
77
|
-
"button",
|
|
78
|
-
"input",
|
|
79
|
-
"keygen",
|
|
80
|
-
"select",
|
|
81
|
-
"textarea"
|
|
82
|
-
].map(function(e) {
|
|
83
|
-
return e + ":not([disabled])";
|
|
84
|
-
});
|
|
85
|
-
t.push("[tabindex]:not([disabled]):not([tabindex=\"\"])");
|
|
86
|
-
var n = e.querySelector(t.join(", "));
|
|
87
|
-
if (!n && "attachShadow" in Element.prototype) for (var r = e.querySelectorAll("*"), i = 0; i < r.length && !(r[i].tagName && r[i].shadowRoot && (n = s(r[i].shadowRoot), n)); i++);
|
|
88
|
-
return n;
|
|
89
|
-
}
|
|
90
|
-
function c(e) {
|
|
91
|
-
return e.isConnected || document.body.contains(e);
|
|
92
|
-
}
|
|
93
|
-
function l(e) {
|
|
94
|
-
if (e.submitter) return e.submitter;
|
|
95
|
-
var t = e.target;
|
|
96
|
-
if (!(t instanceof HTMLFormElement)) return null;
|
|
97
|
-
var n = f.formSubmitter;
|
|
98
|
-
if (!n) {
|
|
99
|
-
var r = e.target;
|
|
100
|
-
n = ("getRootNode" in r && r.getRootNode() || document).activeElement;
|
|
101
|
-
}
|
|
102
|
-
return !n || n.form !== t ? null : n;
|
|
103
|
-
}
|
|
104
|
-
function u(e) {
|
|
105
|
-
if (!e.defaultPrevented) {
|
|
106
|
-
var t = e.target, n = f.imagemapUseValue, i = l(e);
|
|
107
|
-
n === null && i && (n = i.value);
|
|
108
|
-
var a = r(t);
|
|
109
|
-
a && (i && i.getAttribute("formmethod") || t.getAttribute("method")) === "dialog" && (e.preventDefault(), n == null ? a.close() : a.close(n));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
function d(e) {
|
|
113
|
-
if (this.dialog_ = e, this.replacedStyleTop_ = !1, this.openAsModal_ = !1, e.hasAttribute("role") || e.setAttribute("role", "dialog"), e.show = this.show.bind(this), e.showModal = this.showModal.bind(this), e.close = this.close.bind(this), e.addEventListener("submit", u, !1), "returnValue" in e || (e.returnValue = ""), "MutationObserver" in window) new MutationObserver(this.maybeHideModal.bind(this)).observe(e, {
|
|
114
|
-
attributes: !0,
|
|
115
|
-
attributeFilter: ["open"]
|
|
116
|
-
});
|
|
117
|
-
else {
|
|
118
|
-
var t = !1, n = function() {
|
|
119
|
-
t ? this.downgradeModal() : this.maybeHideModal(), t = !1;
|
|
120
|
-
}.bind(this), r, i = function(i) {
|
|
121
|
-
if (i.target === e) {
|
|
122
|
-
var a = "DOMNodeRemoved";
|
|
123
|
-
t |= i.type.substr(0, a.length) === a, window.clearTimeout(r), r = window.setTimeout(n, 0);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
[
|
|
127
|
-
"DOMAttrModified",
|
|
128
|
-
"DOMNodeRemoved",
|
|
129
|
-
"DOMNodeRemovedFromDocument"
|
|
130
|
-
].forEach(function(t) {
|
|
131
|
-
e.addEventListener(t, i);
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
Object.defineProperty(e, "open", {
|
|
135
|
-
set: this.setOpen.bind(this),
|
|
136
|
-
get: e.hasAttribute.bind(e, "open")
|
|
137
|
-
}), this.backdrop_ = document.createElement("div"), this.backdrop_.className = "backdrop", this.backdrop_.addEventListener("mouseup", this.backdropMouseEvent_.bind(this)), this.backdrop_.addEventListener("mousedown", this.backdropMouseEvent_.bind(this)), this.backdrop_.addEventListener("click", this.backdropMouseEvent_.bind(this));
|
|
138
|
-
}
|
|
139
|
-
d.prototype = {
|
|
140
|
-
get dialog() {
|
|
141
|
-
return this.dialog_;
|
|
142
|
-
},
|
|
143
|
-
maybeHideModal: function() {
|
|
144
|
-
this.dialog_.hasAttribute("open") && c(this.dialog_) || this.downgradeModal();
|
|
145
|
-
},
|
|
146
|
-
downgradeModal: function() {
|
|
147
|
-
this.openAsModal_ && (this.openAsModal_ = !1, this.dialog_.style.zIndex = "", this.replacedStyleTop_ &&= (this.dialog_.style.top = "", !1), this.backdrop_.parentNode && this.backdrop_.parentNode.removeChild(this.backdrop_), f.dm.removeDialog(this));
|
|
148
|
-
},
|
|
149
|
-
setOpen: function(e) {
|
|
150
|
-
e ? this.dialog_.hasAttribute("open") || this.dialog_.setAttribute("open", "") : (this.dialog_.removeAttribute("open"), this.maybeHideModal());
|
|
151
|
-
},
|
|
152
|
-
backdropMouseEvent_: function(e) {
|
|
153
|
-
if (this.dialog_.hasAttribute("tabindex")) this.dialog_.focus();
|
|
154
|
-
else {
|
|
155
|
-
var t = document.createElement("div");
|
|
156
|
-
this.dialog_.insertBefore(t, this.dialog_.firstChild), t.tabIndex = -1, t.focus(), this.dialog_.removeChild(t);
|
|
157
|
-
}
|
|
158
|
-
var n = document.createEvent("MouseEvents");
|
|
159
|
-
n.initMouseEvent(e.type, e.bubbles, e.cancelable, window, e.detail, e.screenX, e.screenY, e.clientX, e.clientY, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget), this.dialog_.dispatchEvent(n), e.stopPropagation();
|
|
160
|
-
},
|
|
161
|
-
focus_: function() {
|
|
162
|
-
var e = this.dialog_.querySelector("[autofocus]:not([disabled])");
|
|
163
|
-
!e && this.dialog_.tabIndex >= 0 && (e = this.dialog_), e ||= s(this.dialog_), i(document.activeElement), e && e.focus();
|
|
164
|
-
},
|
|
165
|
-
updateZIndex: function(e, t) {
|
|
166
|
-
if (e < t) throw Error("dialogZ should never be < backdropZ");
|
|
167
|
-
this.dialog_.style.zIndex = e, this.backdrop_.style.zIndex = t;
|
|
168
|
-
},
|
|
169
|
-
show: function() {
|
|
170
|
-
this.dialog_.open || (this.setOpen(!0), this.focus_());
|
|
171
|
-
},
|
|
172
|
-
showModal: function() {
|
|
173
|
-
if (this.dialog_.hasAttribute("open")) throw Error("Failed to execute 'showModal' on dialog: The element is already open, and therefore cannot be opened modally.");
|
|
174
|
-
if (!c(this.dialog_)) throw Error("Failed to execute 'showModal' on dialog: The element is not in a Document.");
|
|
175
|
-
if (!f.dm.pushDialog(this)) throw Error("Failed to execute 'showModal' on dialog: There are too many open modal dialogs.");
|
|
176
|
-
n(this.dialog_.parentElement) && console.warn("A dialog is being shown inside a stacking context. This may cause it to be unusable. For more information, see this link: https://github.com/GoogleChrome/dialog-polyfill/#stacking-context"), this.setOpen(!0), this.openAsModal_ = !0, f.needsCentering(this.dialog_) ? (f.reposition(this.dialog_), this.replacedStyleTop_ = !0) : this.replacedStyleTop_ = !1, this.dialog_.parentNode.insertBefore(this.backdrop_, this.dialog_.nextSibling), this.focus_();
|
|
177
|
-
},
|
|
178
|
-
close: function(n) {
|
|
179
|
-
if (!this.dialog_.hasAttribute("open")) throw Error("Failed to execute 'close' on dialog: The element does not have an 'open' attribute, and therefore cannot be closed.");
|
|
180
|
-
this.setOpen(!1), n !== void 0 && (this.dialog_.returnValue = n);
|
|
181
|
-
var r = new e("close", {
|
|
182
|
-
bubbles: !1,
|
|
183
|
-
cancelable: !1
|
|
184
|
-
});
|
|
185
|
-
t(this.dialog_, r);
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
var f = {};
|
|
189
|
-
if (f.reposition = function(e) {
|
|
190
|
-
var t = document.body.scrollTop || document.documentElement.scrollTop, n = t + (window.innerHeight - e.offsetHeight) / 2;
|
|
191
|
-
e.style.top = Math.max(t, n) + "px";
|
|
192
|
-
}, f.isInlinePositionSetByStylesheet = function(e) {
|
|
193
|
-
for (var t = 0; t < document.styleSheets.length; ++t) {
|
|
194
|
-
var n = document.styleSheets[t], r = null;
|
|
195
|
-
try {
|
|
196
|
-
r = n.cssRules;
|
|
197
|
-
} catch {}
|
|
198
|
-
if (r) for (var i = 0; i < r.length; ++i) {
|
|
199
|
-
var o = r[i], s = null;
|
|
200
|
-
try {
|
|
201
|
-
s = document.querySelectorAll(o.selectorText);
|
|
202
|
-
} catch {}
|
|
203
|
-
if (!(!s || !a(s, e))) {
|
|
204
|
-
var c = o.style.getPropertyValue("top"), l = o.style.getPropertyValue("bottom");
|
|
205
|
-
if (c && c !== "auto" || l && l !== "auto") return !0;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
return !1;
|
|
210
|
-
}, f.needsCentering = function(e) {
|
|
211
|
-
return window.getComputedStyle(e).position !== "absolute" || e.style.top !== "auto" && e.style.top !== "" || e.style.bottom !== "auto" && e.style.bottom !== "" ? !1 : !f.isInlinePositionSetByStylesheet(e);
|
|
212
|
-
}, f.forceRegisterDialog = function(e) {
|
|
213
|
-
if ((window.HTMLDialogElement || e.showModal) && console.warn("This browser already supports <dialog>, the polyfill may not work correctly", e), e.localName !== "dialog") throw Error("Failed to register dialog: The element is not a dialog.");
|
|
214
|
-
new d(e);
|
|
215
|
-
}, f.registerDialog = function(e) {
|
|
216
|
-
e.showModal || f.forceRegisterDialog(e);
|
|
217
|
-
}, f.DialogManager = function() {
|
|
218
|
-
this.pendingDialogStack = [];
|
|
219
|
-
var e = this.checkDOM_.bind(this);
|
|
220
|
-
this.overlay = document.createElement("div"), this.overlay.className = "_dialog_overlay", this.overlay.addEventListener("click", function(t) {
|
|
221
|
-
this.forwardTab_ = void 0, t.stopPropagation(), e([]);
|
|
222
|
-
}.bind(this)), this.handleKey_ = this.handleKey_.bind(this), this.handleFocus_ = this.handleFocus_.bind(this), this.zIndexLow_ = 1e5, this.zIndexHigh_ = 100150, this.forwardTab_ = void 0, "MutationObserver" in window && (this.mo_ = new MutationObserver(function(t) {
|
|
223
|
-
var n = [];
|
|
224
|
-
t.forEach(function(e) {
|
|
225
|
-
for (var t = 0, r; r = e.removedNodes[t]; ++t) {
|
|
226
|
-
if (r instanceof Element) r.localName === "dialog" && n.push(r);
|
|
227
|
-
else continue;
|
|
228
|
-
n = n.concat(r.querySelectorAll("dialog"));
|
|
229
|
-
}
|
|
230
|
-
}), n.length && e(n);
|
|
231
|
-
}));
|
|
232
|
-
}, f.DialogManager.prototype.blockDocument = function() {
|
|
233
|
-
document.documentElement.addEventListener("focus", this.handleFocus_, !0), document.addEventListener("keydown", this.handleKey_), this.mo_ && this.mo_.observe(document, {
|
|
234
|
-
childList: !0,
|
|
235
|
-
subtree: !0
|
|
236
|
-
});
|
|
237
|
-
}, f.DialogManager.prototype.unblockDocument = function() {
|
|
238
|
-
document.documentElement.removeEventListener("focus", this.handleFocus_, !0), document.removeEventListener("keydown", this.handleKey_), this.mo_ && this.mo_.disconnect();
|
|
239
|
-
}, f.DialogManager.prototype.updateStacking = function() {
|
|
240
|
-
for (var e = this.zIndexHigh_, t = 0, n; n = this.pendingDialogStack[t]; ++t) n.updateZIndex(--e, --e), t === 0 && (this.overlay.style.zIndex = --e);
|
|
241
|
-
var r = this.pendingDialogStack[0];
|
|
242
|
-
r ? (r.dialog.parentNode || document.body).appendChild(this.overlay) : this.overlay.parentNode && this.overlay.parentNode.removeChild(this.overlay);
|
|
243
|
-
}, f.DialogManager.prototype.containedByTopDialog_ = function(e) {
|
|
244
|
-
for (; e = r(e);) {
|
|
245
|
-
for (var t = 0, n; n = this.pendingDialogStack[t]; ++t) if (n.dialog === e) return t === 0;
|
|
246
|
-
e = e.parentElement;
|
|
247
|
-
}
|
|
248
|
-
return !1;
|
|
249
|
-
}, f.DialogManager.prototype.handleFocus_ = function(e) {
|
|
250
|
-
var t = e.composedPath ? e.composedPath()[0] : e.target;
|
|
251
|
-
if (!this.containedByTopDialog_(t) && document.activeElement !== document.documentElement && (e.preventDefault(), e.stopPropagation(), i(t), this.forwardTab_ !== void 0)) {
|
|
252
|
-
var n = this.pendingDialogStack[0];
|
|
253
|
-
return n.dialog.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_PRECEDING && (this.forwardTab_ ? n.focus_() : t !== document.documentElement && document.documentElement.focus()), !1;
|
|
254
|
-
}
|
|
255
|
-
}, f.DialogManager.prototype.handleKey_ = function(n) {
|
|
256
|
-
if (this.forwardTab_ = void 0, n.keyCode === 27) {
|
|
257
|
-
n.preventDefault(), n.stopPropagation();
|
|
258
|
-
var r = new e("cancel", {
|
|
259
|
-
bubbles: !1,
|
|
260
|
-
cancelable: !0
|
|
261
|
-
}), i = this.pendingDialogStack[0];
|
|
262
|
-
i && t(i.dialog, r) && i.dialog.close();
|
|
263
|
-
} else n.keyCode === 9 && (this.forwardTab_ = !n.shiftKey);
|
|
264
|
-
}, f.DialogManager.prototype.checkDOM_ = function(e) {
|
|
265
|
-
this.pendingDialogStack.slice().forEach(function(t) {
|
|
266
|
-
e.indexOf(t.dialog) === -1 ? t.maybeHideModal() : t.downgradeModal();
|
|
267
|
-
});
|
|
268
|
-
}, f.DialogManager.prototype.pushDialog = function(e) {
|
|
269
|
-
var t = (this.zIndexHigh_ - this.zIndexLow_) / 2 - 1;
|
|
270
|
-
return this.pendingDialogStack.length >= t ? !1 : (this.pendingDialogStack.unshift(e) === 1 && this.blockDocument(), this.updateStacking(), !0);
|
|
271
|
-
}, f.DialogManager.prototype.removeDialog = function(e) {
|
|
272
|
-
var t = this.pendingDialogStack.indexOf(e);
|
|
273
|
-
t !== -1 && (this.pendingDialogStack.splice(t, 1), this.pendingDialogStack.length === 0 && this.unblockDocument(), this.updateStacking());
|
|
274
|
-
}, f.dm = new f.DialogManager(), f.formSubmitter = null, f.imagemapUseValue = null, window.HTMLDialogElement === void 0) {
|
|
275
|
-
var p = document.createElement("form");
|
|
276
|
-
if (p.setAttribute("method", "dialog"), p.method !== "dialog") {
|
|
277
|
-
var m = Object.getOwnPropertyDescriptor(HTMLFormElement.prototype, "method");
|
|
278
|
-
if (m) {
|
|
279
|
-
var h = m.get;
|
|
280
|
-
m.get = function() {
|
|
281
|
-
return o(this) ? "dialog" : h.call(this);
|
|
282
|
-
};
|
|
283
|
-
var g = m.set;
|
|
284
|
-
m.set = function(e) {
|
|
285
|
-
return typeof e == "string" && e.toLowerCase() === "dialog" ? this.setAttribute("method", e) : g.call(this, e);
|
|
286
|
-
}, Object.defineProperty(HTMLFormElement.prototype, "method", m);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
document.addEventListener("click", function(e) {
|
|
290
|
-
if (f.formSubmitter = null, f.imagemapUseValue = null, !e.defaultPrevented) {
|
|
291
|
-
var t = e.target;
|
|
292
|
-
if ("composedPath" in e && (t = e.composedPath().shift() || t), !(!t || !o(t.form))) {
|
|
293
|
-
if (!(t.type === "submit" && ["button", "input"].indexOf(t.localName) > -1)) {
|
|
294
|
-
if (!(t.localName === "input" && t.type === "image")) return;
|
|
295
|
-
f.imagemapUseValue = e.offsetX + "," + e.offsetY;
|
|
296
|
-
}
|
|
297
|
-
r(t) && (f.formSubmitter = t);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}, !1), document.addEventListener("submit", function(e) {
|
|
301
|
-
var t = e.target;
|
|
302
|
-
if (!r(t)) {
|
|
303
|
-
var n = l(e);
|
|
304
|
-
(n && n.getAttribute("formmethod") || t.getAttribute("method")) === "dialog" && e.preventDefault();
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
var _ = HTMLFormElement.prototype.submit, v = function() {
|
|
308
|
-
if (!o(this)) return _.call(this);
|
|
309
|
-
var e = r(this);
|
|
310
|
-
e && e.close();
|
|
311
|
-
};
|
|
312
|
-
HTMLFormElement.prototype.submit = v;
|
|
313
|
-
}
|
|
314
|
-
//#endregion
|
|
315
|
-
export { f as default };
|