@oslokommune/punkt-react 18.2.0 → 18.3.1
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 +34 -0
- package/dist/components/linkcard/LinkCard.d.ts +4 -8
- package/dist/punkt-react.cjs +1 -1
- package/dist/punkt-react.js +16 -11
- package/dist/shared-strings/nb.d.ts +3 -0
- package/dist/shared-types/index.d.ts +2 -0
- package/dist/shared-types/linkcard.d.ts +24 -0
- package/package.json +3 -3
- package/src/components/linkcard/LinkCard.test.tsx +43 -0
- package/src/components/linkcard/LinkCard.tsx +12 -7
- package/src/components/stepper/Step.tsx +1 -1
- package/src/components/strings/strings-override.test.tsx +13 -0
package/dist/punkt-react.js
CHANGED
|
@@ -62,7 +62,7 @@ var M = /* @__PURE__ */ O((/* @__PURE__ */ E(((e, t) => {
|
|
|
62
62
|
return n;
|
|
63
63
|
}) : window.classNames = n;
|
|
64
64
|
})();
|
|
65
|
-
})))(), 1), N = "https://punkt-cdn.oslo.kommune.no/18.
|
|
65
|
+
})))(), 1), N = "https://punkt-cdn.oslo.kommune.no/18.3/icons/";
|
|
66
66
|
typeof window < "u" && (window.pktFetch = window.pktFetch === void 0 ? fetch : window.pktFetch, window.pktIconPath = window.pktIconPath || N);
|
|
67
67
|
var P = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\"></svg>", ee = {}, te = 2, ne = 1500, F = typeof Storage < "u" && typeof sessionStorage < "u", re = typeof window < "u" ? d : c, ie = (e, t) => !e || !F ? "" : sessionStorage.getItem(t + e + ".svg") ?? "", ae = (e) => window.pktFetch(e).then((t) => {
|
|
68
68
|
if (!t.ok) throw Error("Missing icon: " + e);
|
|
@@ -278,6 +278,7 @@ var ce = {
|
|
|
278
278
|
},
|
|
279
279
|
backlink: { label: "Gå tilbake til forrige side" },
|
|
280
280
|
breadcrumbs: { ariaLabel: "brødsmulemeny" },
|
|
281
|
+
linkcard: { openInNewTab: "Åpnes i ny fane" },
|
|
281
282
|
alert: { lastUpdated: "Sist oppdatert: {date}" },
|
|
282
283
|
tag: { remove: "Klikk for å fjerne {label}" },
|
|
283
284
|
header: {
|
|
@@ -526,7 +527,7 @@ var ge = {
|
|
|
526
527
|
};
|
|
527
528
|
//#endregion
|
|
528
529
|
//#region src/components/button/Button.tsx
|
|
529
|
-
typeof window < "u" && (window.pktAnimationPath = window.pktAnimationPath || "https://punkt-cdn.oslo.kommune.no/18.
|
|
530
|
+
typeof window < "u" && (window.pktAnimationPath = window.pktAnimationPath || "https://punkt-cdn.oslo.kommune.no/18.3/animations/");
|
|
530
531
|
var Y = i(({ children: e, className: t, iconName: n = "user", secondIconName: r = "user", iconPath: i, secondIconPath: a, size: o = "medium", fullWidth: s = !1, fullWidthOnMobile: c = !1, skin: l = "primary", type: u = "button", variant: d = "label-only", state: f, color: p, isLoading: m = void 0, disabled: h = void 0, loadingAnimationPath: g = window.pktAnimationPath, ...y }, b) => {
|
|
531
532
|
let x = [
|
|
532
533
|
t,
|
|
@@ -7074,7 +7075,7 @@ var co = i(({ appearance: e = "local", inputSize: t = "medium", disabled: n = !1
|
|
|
7074
7075
|
co.displayName = "PktSearchInput";
|
|
7075
7076
|
//#endregion
|
|
7076
7077
|
//#region src/components/header/HeaderGlobal.tsx
|
|
7077
|
-
var lo = "https://punkt-cdn.oslo.kommune.no/18.
|
|
7078
|
+
var lo = "https://punkt-cdn.oslo.kommune.no/18.3/logos/";
|
|
7078
7079
|
typeof window < "u" && (window.pktLogoPath = window.pktLogoPath || lo);
|
|
7079
7080
|
var uo = "pkt-header-global-menu", fo = "pkt-header-global-menu-toggle", po = "pkt-header-global-search-panel", mo = "pkt-header-global-search-toggle", ho = i(({ className: e, "data-mode": t, dataUrl: n, data: r, locale: i = "nb-NO", logoLink: a = ga, logoClick: s, logoPath: l = typeof window < "u" ? window.pktLogoPath : lo, showSearch: u = !0, searchPlaceholder: h, onSearch: y, showContact: b = !0, user: x, userMenu: S, representing: C, canChangeRepresentation: w = !1, changeRepresentation: T, logOutButtonPlacement: E = "none", logOut: D, position: O = "fixed", scrollBehavior: k = "hide", mobileBreakpoint: A = 768, tabletBreakpoint: j = 1024, onDataLoaded: N, onDataError: P, strings: ee }, te) => {
|
|
7080
7081
|
let ne = k === "hide", [F, re] = m("none"), [ie, ae] = m(void 0), [oe, se] = m(!1), I = p(N), R = p(P);
|
|
@@ -7431,7 +7432,7 @@ var go = i(({ id: e, ariaDescribedby: t, ariaLabelledby: n, autocomplete: r = "o
|
|
|
7431
7432
|
go.displayName = "PktTextinput";
|
|
7432
7433
|
//#endregion
|
|
7433
7434
|
//#region src/components/header/HeaderService.tsx
|
|
7434
|
-
var _o = "https://punkt-cdn.oslo.kommune.no/18.
|
|
7435
|
+
var _o = "https://punkt-cdn.oslo.kommune.no/18.3/logos/";
|
|
7435
7436
|
typeof window < "u" && (window.pktLogoPath = window.pktLogoPath || _o);
|
|
7436
7437
|
var vo = i(({ mobileBreakpoint: e = 768, tabletBreakpoint: t = 1280, children: n, className: r, compact: i = !1, "data-mode": a, logOutButtonPlacement: s = "none", logOut: l, openedMenu: u, showSearch: d = !1, onSearch: h, onSearchChange: y, searchValue: b, searchPlaceholder: x, representing: S, serviceLink: C, serviceClick: w, serviceName: T, user: E, userMenu: D, userMenuFooter: O, userOptions: k, canChangeRepresentation: A = !1, changeRepresentation: j, hideLogo: N = !1, logoLink: P = ga, logoClick: ee, logoPath: te = typeof window < "u" ? window.pktLogoPath : _o, position: ne = "fixed", scrollBehavior: F = "hide", slotMenuVariant: re = "icon-only", slotMenuText: ie = "Meny", strings: ae }, oe) => {
|
|
7437
7438
|
let se = F === "hide";
|
|
@@ -7752,12 +7753,12 @@ var Co = i(({ label: e, id: t, children: n, ...r }, i) => /* @__PURE__ */ v("div
|
|
|
7752
7753
|
Co.displayName = "PktInput";
|
|
7753
7754
|
//#endregion
|
|
7754
7755
|
//#region src/components/linkcard/LinkCard.tsx
|
|
7755
|
-
var wo = ({ children: e, skin: t, title: n, href: r, iconName: i, openInNewTab: a, external: o, className: s,
|
|
7756
|
-
let
|
|
7756
|
+
var wo = ({ children: e, skin: t, title: n, href: r, iconName: i, openInNewTab: a, external: o, className: s, strings: c, ...l }) => {
|
|
7757
|
+
let u = _e(["linkcard"], c), d = ["pkt-linkcard", t && `pkt-linkcard--${t}`].filter(Boolean).join(" "), f = ["pkt-linkcard__title", o && "pkt-link pkt-link--external"].filter(Boolean).join(" ");
|
|
7757
7758
|
return /* @__PURE__ */ v("a", {
|
|
7758
|
-
...
|
|
7759
|
+
...l,
|
|
7759
7760
|
href: r,
|
|
7760
|
-
className: (0, M.default)(
|
|
7761
|
+
className: (0, M.default)(d, s),
|
|
7761
7762
|
target: a ? "_blank" : "_self",
|
|
7762
7763
|
rel: a ? "noopener noreferrer" : void 0,
|
|
7763
7764
|
children: [
|
|
@@ -7766,9 +7767,13 @@ var wo = ({ children: e, skin: t, title: n, href: r, iconName: i, openInNewTab:
|
|
|
7766
7767
|
name: i
|
|
7767
7768
|
}),
|
|
7768
7769
|
n && /* @__PURE__ */ _("div", {
|
|
7769
|
-
className: (0, M.default)(
|
|
7770
|
+
className: (0, M.default)(f),
|
|
7770
7771
|
children: n
|
|
7771
7772
|
}),
|
|
7773
|
+
a && u.linkcard.openInNewTab ? /* @__PURE__ */ _("span", {
|
|
7774
|
+
className: "pkt-sr-only",
|
|
7775
|
+
children: u.linkcard.openInNewTab
|
|
7776
|
+
}) : null,
|
|
7772
7777
|
/* @__PURE__ */ _("div", {
|
|
7773
7778
|
className: "pkt-linkcard__text",
|
|
7774
7779
|
children: e
|
|
@@ -7778,7 +7783,7 @@ var wo = ({ children: e, skin: t, title: n, href: r, iconName: i, openInNewTab:
|
|
|
7778
7783
|
};
|
|
7779
7784
|
//#endregion
|
|
7780
7785
|
//#region src/components/loader/Loader.tsx
|
|
7781
|
-
wo.displayName = "PktLinkCard", typeof window < "u" && (window.pktAnimationPath = window.pktAnimationPath || "https://punkt-cdn.oslo.kommune.no/18.
|
|
7786
|
+
wo.displayName = "PktLinkCard", typeof window < "u" && (window.pktAnimationPath = window.pktAnimationPath || "https://punkt-cdn.oslo.kommune.no/18.3/animations/");
|
|
7782
7787
|
var To = (e) => {
|
|
7783
7788
|
switch (e) {
|
|
7784
7789
|
case "blue": return "spinner-blue";
|
|
@@ -7972,7 +7977,7 @@ var Ao = /* @__PURE__ */ _("svg", {
|
|
|
7972
7977
|
cx: "12",
|
|
7973
7978
|
cy: "12",
|
|
7974
7979
|
r: "7",
|
|
7975
|
-
style: { fill: "var(--pkt-color-
|
|
7980
|
+
style: { fill: "var(--pkt-color-brand-neutrals-300, #CCC)" }
|
|
7976
7981
|
})
|
|
7977
7982
|
}), jo = /* @__PURE__ */ v("svg", {
|
|
7978
7983
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -15,6 +15,8 @@ export type { TPktInputSize, TSize3, TSize5, TSize7 } from './size';
|
|
|
15
15
|
export { ACCORDION_SKINS } from './accordion';
|
|
16
16
|
export type { TAccordionSkin, IPktAccordionBase, IPktAccordionItemBase, IAccordionSpecProps, IAccordionItemSpecProps, IAccordionVisualProps, } from './accordion';
|
|
17
17
|
export type { IPktBackLinkBase, IBacklinkSpecProps } from './backlink';
|
|
18
|
+
export { LINKCARD_SKINS } from './linkcard';
|
|
19
|
+
export type { TLinkCardSkin, IPktLinkCardBase, ILinkcardSpecProps } from './linkcard';
|
|
18
20
|
export { BREADCRUMBS_NAVIGATION_TYPES } from './breadcrumbs';
|
|
19
21
|
export type { TBreadcrumbsNavigationType, IBreadcrumb, IBreadcrumbItem, IBreadcrumbs, IPktBreadcrumbsBase, IBreadcrumbsSpecProps, } from './breadcrumbs';
|
|
20
22
|
export type { IRenderLink, TRenderLink } from './render-link';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* linkcard.ts
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for pkt-linkcard.
|
|
5
|
+
* Used by React, Elements, and typed component specs.
|
|
6
|
+
*/
|
|
7
|
+
import type { IPktStringsProps } from '../shared-strings';
|
|
8
|
+
/** LinkCard skin variants — shared runtime source for types, specs, and Preview. */
|
|
9
|
+
export declare const LINKCARD_SKINS: readonly ['normal', 'no-padding', 'blue', 'beige', 'green', 'gray', 'beige-outline', 'gray-outline'];
|
|
10
|
+
export type TLinkCardSkin = (typeof LINKCARD_SKINS)[number];
|
|
11
|
+
/** Shared LinkCard props for React, Elements, and typed specs. */
|
|
12
|
+
export type IPktLinkCardBase = IPktStringsProps<'linkcard'> & {
|
|
13
|
+
title?: string;
|
|
14
|
+
href?: string;
|
|
15
|
+
skin?: TLinkCardSkin;
|
|
16
|
+
iconName?: string;
|
|
17
|
+
openInNewTab?: boolean;
|
|
18
|
+
external?: boolean;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Documented LinkCard props (subset of `IPktLinkCardBase`).
|
|
22
|
+
* Used for typed component specs in documentation.
|
|
23
|
+
*/
|
|
24
|
+
export type ILinkcardSpecProps = Pick<IPktLinkCardBase, 'title' | 'href' | 'skin' | 'iconName' | 'openInNewTab' | 'external'>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oslokommune/punkt-react",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.3.1",
|
|
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",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@eslint/eslintrc": "^3.3.5",
|
|
46
46
|
"@eslint/js": "^10.0.1",
|
|
47
47
|
"@oslokommune/punkt-assets": "^18.0.0",
|
|
48
|
-
"@oslokommune/punkt-css": "^18.
|
|
48
|
+
"@oslokommune/punkt-css": "^18.3.1",
|
|
49
49
|
"@testing-library/jest-dom": "^6.9.1",
|
|
50
50
|
"@testing-library/react": "^16.3.2",
|
|
51
51
|
"@testing-library/user-event": "^14.6.1",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"url": "https://github.com/oslokommune/punkt/issues"
|
|
103
103
|
},
|
|
104
104
|
"license": "MIT",
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "076395b7934546d637a3136ac35eef4583d8f8a7"
|
|
106
106
|
}
|
|
@@ -3,6 +3,7 @@ import '@testing-library/jest-dom'
|
|
|
3
3
|
|
|
4
4
|
import { render } from '@testing-library/react'
|
|
5
5
|
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
6
|
+
import { nb } from 'shared-strings'
|
|
6
7
|
|
|
7
8
|
import { PktLinkCard } from './LinkCard'
|
|
8
9
|
|
|
@@ -103,6 +104,48 @@ describe('PktLinkCard', () => {
|
|
|
103
104
|
})
|
|
104
105
|
})
|
|
105
106
|
|
|
107
|
+
describe('openInNewTab strings', () => {
|
|
108
|
+
it('does not announce a new-tab string when openInNewTab is unset', () => {
|
|
109
|
+
const { container, queryByText } = render(<PktLinkCard title="Normal">Content</PktLinkCard>)
|
|
110
|
+
expect(container.querySelector('.pkt-sr-only')).not.toBeInTheDocument()
|
|
111
|
+
expect(queryByText(nb.linkcard.openInNewTab)).not.toBeInTheDocument()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('uses the catalogue default when strings is omitted', () => {
|
|
115
|
+
const { getByText } = render(
|
|
116
|
+
<PktLinkCard title="Normal" openInNewTab>
|
|
117
|
+
Content
|
|
118
|
+
</PktLinkCard>,
|
|
119
|
+
)
|
|
120
|
+
const srOnly = getByText(nb.linkcard.openInNewTab)
|
|
121
|
+
expect(srOnly).toHaveClass('pkt-sr-only')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('uses a custom override from the strings prop', () => {
|
|
125
|
+
const { getByText, queryByText } = render(
|
|
126
|
+
<PktLinkCard
|
|
127
|
+
title="Normal"
|
|
128
|
+
openInNewTab
|
|
129
|
+
strings={{ linkcard: { openInNewTab: 'Opens in a new tab' } }}
|
|
130
|
+
>
|
|
131
|
+
Content
|
|
132
|
+
</PktLinkCard>,
|
|
133
|
+
)
|
|
134
|
+
expect(getByText('Opens in a new tab')).toHaveClass('pkt-sr-only')
|
|
135
|
+
expect(queryByText(nb.linkcard.openInNewTab)).not.toBeInTheDocument()
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('hides the announcement when the override is an empty string', () => {
|
|
139
|
+
const { container, queryByText } = render(
|
|
140
|
+
<PktLinkCard title="Normal" openInNewTab strings={{ linkcard: { openInNewTab: '' } }}>
|
|
141
|
+
Content
|
|
142
|
+
</PktLinkCard>,
|
|
143
|
+
)
|
|
144
|
+
expect(container.querySelector('.pkt-sr-only')).not.toBeInTheDocument()
|
|
145
|
+
expect(queryByText(nb.linkcard.openInNewTab)).not.toBeInTheDocument()
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
|
|
106
149
|
// ACCESSIBILITY TESTS
|
|
107
150
|
|
|
108
151
|
describe('accessibility', () => {
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames'
|
|
4
4
|
import { HTMLAttributes, ReactNode } from 'react'
|
|
5
|
+
import type { IPktLinkCardBase, TLinkCardSkin } from 'shared-types'
|
|
5
6
|
|
|
6
7
|
import { PktIcon } from '../icon/Icon'
|
|
8
|
+
import { usePktStrings } from '../../hooks/usePktStrings'
|
|
7
9
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
openInNewTab?: boolean
|
|
14
|
-
external?: boolean
|
|
10
|
+
export type { TLinkCardSkin }
|
|
11
|
+
|
|
12
|
+
export interface IPktLinkCard
|
|
13
|
+
extends IPktLinkCardBase,
|
|
14
|
+
Omit<HTMLAttributes<HTMLAnchorElement>, 'title'> {
|
|
15
15
|
children?: ReactNode
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -24,8 +24,10 @@ export const PktLinkCard = ({
|
|
|
24
24
|
openInNewTab,
|
|
25
25
|
external,
|
|
26
26
|
className,
|
|
27
|
+
strings,
|
|
27
28
|
...props
|
|
28
29
|
}: IPktLinkCard) => {
|
|
30
|
+
const s = usePktStrings(['linkcard'], strings)
|
|
29
31
|
const classes = ['pkt-linkcard', skin && `pkt-linkcard--${skin}`].filter(Boolean).join(' ')
|
|
30
32
|
|
|
31
33
|
const titleClasses = ['pkt-linkcard__title', external && 'pkt-link pkt-link--external'].filter(Boolean).join(' ')
|
|
@@ -40,6 +42,9 @@ export const PktLinkCard = ({
|
|
|
40
42
|
>
|
|
41
43
|
{iconName && <PktIcon className="pkt-link__icon" name={iconName} />}
|
|
42
44
|
{title && <div className={classNames(titleClasses)}>{title}</div>}
|
|
45
|
+
{openInNewTab && s.linkcard.openInNewTab ? (
|
|
46
|
+
<span className="pkt-sr-only">{s.linkcard.openInNewTab}</span>
|
|
47
|
+
) : null}
|
|
43
48
|
<div className="pkt-linkcard__text">{children}</div>
|
|
44
49
|
</a>
|
|
45
50
|
)
|
|
@@ -26,7 +26,7 @@ export interface IPktStep {
|
|
|
26
26
|
|
|
27
27
|
const incompleteStepSVG = (
|
|
28
28
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none">
|
|
29
|
-
<circle cx="12" cy="12" r="7" style={{ fill: 'var(--pkt-color-
|
|
29
|
+
<circle cx="12" cy="12" r="7" style={{ fill: 'var(--pkt-color-brand-neutrals-300, #CCC)' }} />
|
|
30
30
|
</svg>
|
|
31
31
|
)
|
|
32
32
|
|
|
@@ -5,6 +5,7 @@ import { resetPktStrings, setPktStrings } from 'shared-strings'
|
|
|
5
5
|
import { PktBackLink } from '../backlink/BackLink'
|
|
6
6
|
import { PktBreadcrumbs } from '../breadcrumbs/Breadcrumbs'
|
|
7
7
|
import { PktFileUpload } from '../fileupload/FileUpload'
|
|
8
|
+
import { PktLinkCard } from '../linkcard/LinkCard'
|
|
8
9
|
import { PktSearchInput } from '../searchinput/SearchInput'
|
|
9
10
|
import { PktTextinput } from '../textinput/Textinput'
|
|
10
11
|
import { PktStringsProvider } from './PktStringsProvider'
|
|
@@ -25,6 +26,18 @@ describe('strings-propen per komponent', () => {
|
|
|
25
26
|
expect(screen.getByLabelText('Tilbake til lista')).toBeInTheDocument()
|
|
26
27
|
})
|
|
27
28
|
|
|
29
|
+
test('linkcard bruker teksten fra propen', () => {
|
|
30
|
+
render(
|
|
31
|
+
<PktLinkCard
|
|
32
|
+
title="Dokument"
|
|
33
|
+
href="/"
|
|
34
|
+
openInNewTab
|
|
35
|
+
strings={{ linkcard: { openInNewTab: 'Opens in a new tab' } }}
|
|
36
|
+
/>,
|
|
37
|
+
)
|
|
38
|
+
expect(screen.getByText('Opens in a new tab')).toBeInTheDocument()
|
|
39
|
+
})
|
|
40
|
+
|
|
28
41
|
test('breadcrumbs bruker teksten fra propen', () => {
|
|
29
42
|
render(
|
|
30
43
|
<PktBreadcrumbs
|