@oslokommune/punkt-react 17.1.3 → 18.1.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/components/accordion/Accordion.d.ts +2 -12
- package/dist/components/accordion/AccordionItem.d.ts +2 -8
- package/dist/components/alert/Alert.d.ts +4 -3
- package/dist/components/backlink/BackLink.d.ts +3 -10
- package/dist/components/breadcrumbs/Breadcrumbs.d.ts +7 -13
- package/dist/components/calendar/types.d.ts +14 -12
- package/dist/components/checkbox/Checkbox.d.ts +5 -0
- package/dist/components/combobox/types.d.ts +5 -0
- package/dist/components/consent/strings.d.ts +1 -85
- package/dist/components/datepicker/DateTags.d.ts +2 -2
- package/dist/components/datepicker/types.d.ts +6 -3
- package/dist/components/fileupload/DropZone.d.ts +3 -0
- package/dist/components/fileupload/FileUpload.d.ts +9 -61
- package/dist/components/header/types.d.ts +5 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/inputwrapper/InputWrapper.d.ts +6 -0
- package/dist/components/link/Link.d.ts +2 -6
- package/dist/components/radio/RadioButton.d.ts +5 -0
- package/dist/components/searchinput/SearchInput.d.ts +4 -0
- package/dist/components/select/Select.d.ts +3 -0
- package/dist/components/strings/PktStringsProvider.d.ts +21 -0
- package/dist/components/strings/strings-override.test.d.ts +1 -0
- package/dist/components/tag/Tag.d.ts +3 -0
- package/dist/components/textarea/Textarea.d.ts +3 -0
- package/dist/components/textinput/Textinput.d.ts +3 -0
- package/dist/components/timepicker/types.d.ts +3 -2
- package/dist/components/timepicker/useTimepickerState.d.ts +9 -1
- package/dist/punkt-react.cjs +1 -1
- package/dist/punkt-react.js +2982 -2757
- package/dist/shared-strings/consent.d.ts +71 -0
- package/dist/shared-strings/format.d.ts +21 -0
- package/dist/shared-strings/index.d.ts +14 -0
- package/dist/shared-strings/nb.d.ts +121 -0
- package/dist/shared-strings/resolve.d.ts +12 -0
- package/dist/shared-strings/store.d.ts +27 -0
- package/dist/shared-strings/types.d.ts +40 -0
- package/dist/shared-types/accordion.d.ts +58 -0
- package/dist/shared-types/alert.d.ts +20 -0
- package/dist/shared-types/aria.d.ts +2 -1
- package/dist/shared-types/backlink.d.ts +23 -0
- package/dist/shared-types/breadcrumbs.d.ts +33 -0
- package/dist/shared-types/fileupload.d.ts +55 -28
- package/dist/shared-types/footer.d.ts +10 -0
- package/dist/shared-types/form-field.d.ts +45 -0
- package/dist/shared-types/header-footer.d.ts +2 -0
- package/dist/shared-types/index.d.ts +15 -6
- package/dist/shared-types/render-link.d.ts +22 -0
- package/dist/shared-types/skin.d.ts +2 -9
- package/dist/shared-utils/combobox/index.d.ts +1 -0
- package/dist/shared-utils/combobox/input-utils.d.ts +2 -1
- package/dist/shared-utils/combobox/messages.d.ts +7 -0
- package/dist/shared-utils/combobox/option-utils.d.ts +2 -1
- package/dist/shared-utils/combobox/selection-manager.d.ts +3 -2
- package/package.json +4 -4
- package/src/components/accordion/Accordion.tsx +2 -12
- package/src/components/accordion/AccordionItem.tsx +2 -8
- package/src/components/alert/Alert.tsx +12 -5
- package/src/components/backlink/BackLink.tsx +12 -12
- package/src/components/breadcrumbs/Breadcrumbs.tsx +19 -15
- package/src/components/calendar/Calendar.core.test.tsx +7 -5
- package/src/components/calendar/types.ts +14 -34
- package/src/components/calendar/useCalendarState.ts +16 -2
- package/src/components/checkbox/Checkbox.tsx +20 -4
- package/src/components/combobox/Combobox.tsx +1 -0
- package/src/components/combobox/Listbox.tsx +4 -2
- package/src/components/combobox/types.ts +6 -0
- package/src/components/combobox/useComboboxState.ts +15 -8
- package/src/components/consent/strings.ts +1 -125
- package/src/components/datepicker/DateTags.tsx +4 -3
- package/src/components/datepicker/Datepicker.accessibility.test.tsx +2 -2
- package/src/components/datepicker/Datepicker.tsx +1 -0
- package/src/components/datepicker/DatepickerInputs.tsx +6 -6
- package/src/components/datepicker/types.ts +6 -3
- package/src/components/datepicker/useDatepickerState.ts +4 -5
- package/src/components/fileupload/DropZone.tsx +20 -15
- package/src/components/fileupload/FileUpload.test.tsx +37 -0
- package/src/components/fileupload/FileUpload.tsx +63 -73
- package/src/components/header/HeaderGlobal.tsx +5 -2
- package/src/components/header/HeaderService.tsx +12 -7
- package/src/components/header/types.ts +6 -0
- package/src/components/index.ts +10 -0
- package/src/components/inputwrapper/InputWrapper.tsx +28 -6
- package/src/components/link/Link.tsx +2 -6
- package/src/components/radio/RadioButton.tsx +18 -2
- package/src/components/searchinput/SearchInput.tsx +13 -3
- package/src/components/select/Select.tsx +5 -0
- package/src/components/strings/PktStringsProvider.tsx +38 -0
- package/src/components/strings/strings-override.test.tsx +130 -0
- package/src/components/tag/Tag.tsx +13 -2
- package/src/components/textarea/Textarea.tsx +5 -0
- package/src/components/textinput/Textinput.tsx +5 -0
- package/src/components/timepicker/Timepicker.tsx +1 -0
- package/src/components/timepicker/types.ts +3 -2
- package/src/components/timepicker/useTimepickerState.ts +20 -22
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
export type { Booleanish } from './booleanish';
|
|
2
2
|
export { booleanishConverter, nullableBooleanishConverter } from './booleanish';
|
|
3
|
-
export type
|
|
3
|
+
export { ARIA_LIVE_VALUES, type TAriaBoolean, type TAriaBooleanMixed, type TAriaCurrent, type TAriaHasPopup, type TAriaInvalid, type TAriaLive, type TAriaRelevant, type TAriaSort, type TAriaAutoComplete, type TAriaOrientation, type IAriaAttributes, type TAlertRole, } from './aria';
|
|
4
|
+
export { ALERT_SKINS, ALERT_SIZES, type TAlertSkin, type TAlertSize, type IAlertSpecProps, } from './alert';
|
|
4
5
|
export type { THeadingLevel, THeadingSize, THeadingWeight } from './heading';
|
|
5
6
|
export type { User, Representing, UserMenuItem, InternalMenuItemBase, InternalMenuLink, InternalMenuButton, TInternalMenuItem, TSlotMenuVariant, THeaderMenu, TLogOutButtonPlacement, THeaderPosition, THeaderScrollBehavior, } from './header';
|
|
6
7
|
export { convertUserMenuItem } from './header';
|
|
8
|
+
export { HEADER_MENU_LOCALES, DEFAULT_HEADER_FOOTER_URL, DEFAULT_HEADER_LOGO_LINK, } from './header-footer';
|
|
7
9
|
export type { THeaderMenuLocale, IHeaderMenuLink, IHeaderMenuIconLink, IHeaderMenuButton, IHeaderMenuServices, IHeaderMenuSection, IMegaMenu, IHeaderFooter, IHeaderFooterLocaleData, THeaderFooterApi, IPktHeaderMenu, IPktHeaderGlobal, } from './header-footer';
|
|
8
|
-
export {
|
|
9
|
-
export type { IPktFooterLink, IPktFooterColumn, IPktFooterSocialLink, IPktFooterBase, IPktFooterProps, IPktFooterSimpleProps, } from './footer';
|
|
10
|
+
export type { IPktFooterLink, IPktFooterColumn, IPktFooterSocialLink, IPktFooterBase, IPktFooterProps, IPktFooterSimpleProps, IFooterSimpleSpecProps, IFooterSpecProps, } from './footer';
|
|
10
11
|
export { DEFAULT_FOOTER_PERSONVERN_URL, DEFAULT_FOOTER_TILGJENGELIGHET_URL } from './footer';
|
|
11
12
|
export type { TLayout, TVerticalPosition, THorizontalPosition, TPosition, TPositionWithCenter, } from './layout';
|
|
12
13
|
export type { THTMLButtonType, TSelectionMode } from './form';
|
|
13
14
|
export type { TPktInputSize, TSize3, TSize5, TSize7 } from './size';
|
|
14
|
-
export
|
|
15
|
+
export { ACCORDION_SKINS } from './accordion';
|
|
16
|
+
export type { TAccordionSkin, IPktAccordionBase, IPktAccordionItemBase, IAccordionSpecProps, IAccordionItemSpecProps, IAccordionVisualProps, } from './accordion';
|
|
17
|
+
export type { IPktBackLinkBase, IBacklinkSpecProps } from './backlink';
|
|
18
|
+
export { BREADCRUMBS_NAVIGATION_TYPES } from './breadcrumbs';
|
|
19
|
+
export type { TBreadcrumbsNavigationType, IBreadcrumb, IBreadcrumbItem, IBreadcrumbs, IPktBreadcrumbsBase, IBreadcrumbsSpecProps, } from './breadcrumbs';
|
|
20
|
+
export type { IRenderLink, TRenderLink } from './render-link';
|
|
21
|
+
export type { IPktStringsProps } from '../shared-strings';
|
|
22
|
+
export type { IHelptextProps, ITagOptionalRequiredProps, IFormFieldLabelProps, IFormFieldErrorProps, IFormFieldCommonProps, TFormFieldCommonSpecKeys, } from './form-field';
|
|
23
|
+
export type { TMessageboxSkin, TCardSkin, TTagSkin } from './skin';
|
|
15
24
|
export type { IDateConstraints, ICalendarGridDimensions, IGridCellPosition, TDateRangeMap, ISelectionState, ISelectionOptions, } from './calendar';
|
|
16
25
|
export type { IDatepickerStrings } from './datepicker';
|
|
17
26
|
export { defaultSingleStrings, defaultRangeStrings } from './datepicker';
|
|
@@ -21,5 +30,5 @@ export type { TProgressbarRole, TProgressbarSkin, TProgressbarStatusPlacement, T
|
|
|
21
30
|
export type { IPktComboboxOption, TPktComboboxTagSkin, TPktComboboxDisplayValue, TPktComboboxTagPlacement, } from './combobox';
|
|
22
31
|
export type { IPktSelectOption, TSelectOption } from './select';
|
|
23
32
|
export type { TPktSearchInputAppearance, TPktSearchInputMethod, IPktSearchInputSuggestion, IPktSearchInput, } from './searchinput';
|
|
24
|
-
export
|
|
25
|
-
export {
|
|
33
|
+
export { UPLOAD_STRATEGIES, FILE_UPLOAD_ITEM_RENDERERS, PREVIEW_UPLOAD_STATUS, } from './fileupload';
|
|
34
|
+
export type { TUploadStrategy as TFileUploadStrategy, TFileUploadItemRenderer, TPreviewUploadStatus, TFilesChangedReason, TFileValidator, TTransferProgress, IFileItem, IFileTransfer, IFileValidateDetail, ITransferCancelledDetail, IFilesChangedDetail, IFileUploadSpecProps, IPktFileUploadBase, } from './fileupload';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* render-link.ts
|
|
3
|
+
*
|
|
4
|
+
* Shared React `renderLink` callback shape used by Link, BackLink, and Breadcrumbs.
|
|
5
|
+
* Elements components do not expose this prop.
|
|
6
|
+
*/
|
|
7
|
+
/** Object passed to a custom link renderer (`renderLink` prop). */
|
|
8
|
+
export type IRenderLink<TChildren = unknown, TAnchorProps = Record<string, unknown>> = {
|
|
9
|
+
href: string;
|
|
10
|
+
className: string;
|
|
11
|
+
/** Link label/content — typically `ReactNode` in `@oslokommune/punkt-react`. */
|
|
12
|
+
children: TChildren;
|
|
13
|
+
/** Remaining anchor attributes spread onto the rendered link. */
|
|
14
|
+
props: TAnchorProps;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* React-only callback to render a custom link component (Next.js Link, React Router, etc.).
|
|
18
|
+
*
|
|
19
|
+
* @typeParam TReturn — Return value / children type (typically `ReactNode`).
|
|
20
|
+
* @typeParam TAnchorProps — Anchor attribute bag passed in `args.props`.
|
|
21
|
+
*/
|
|
22
|
+
export type TRenderLink<TReturn = unknown, TAnchorProps = Record<string, unknown>> = (args: IRenderLink<TReturn, TAnchorProps>) => TReturn;
|
|
@@ -5,19 +5,12 @@
|
|
|
5
5
|
* Only includes skin types that are identical across packages.
|
|
6
6
|
* Component-specific skin types should remain in their respective component files.
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* Used for semantic color coding of alerts (error, success, warning, info)
|
|
11
|
-
*/
|
|
12
|
-
export type TAlertSkin = 'error' | 'success' | 'warning' | 'info';
|
|
8
|
+
export { ALERT_SKINS, type TAlertSkin } from './alert';
|
|
9
|
+
export { ACCORDION_SKINS, type TAccordionSkin } from './accordion';
|
|
13
10
|
/**
|
|
14
11
|
* Messagebox component skin variants
|
|
15
12
|
*/
|
|
16
13
|
export type TMessageboxSkin = 'beige' | 'blue' | 'red' | 'green';
|
|
17
|
-
/**
|
|
18
|
-
* Accordion component skin variants
|
|
19
|
-
*/
|
|
20
|
-
export type TAccordionSkin = 'borderless' | 'outlined' | 'beige' | 'blue' | 'plus-minus';
|
|
21
14
|
/**
|
|
22
15
|
* Card component skin variants
|
|
23
16
|
*/
|
|
@@ -8,3 +8,4 @@ export { isLetterOrSpace, createTypeaheadHandler, findTypeaheadOptionMatch } fro
|
|
|
8
8
|
export { getInputKeyAction, isArrowToggleKey, getInputValueAction, checkForMatches, getSingleValueForInput, } from './input-utils';
|
|
9
9
|
export type { TInputKeyAction, TFocusOutAction, IFocusOutResult, ICheckForMatchesResult, } from './input-utils';
|
|
10
10
|
export { focusAndScrollIntoView, getOptionElements, focusNextOption, focusPreviousOption, focusFirstOption, focusLastOption, focusFirstOrSelectedOption, } from './keyboard-navigation';
|
|
11
|
+
export type { TComboboxMessageKey } from './messages';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TComboboxMessageKey } from './messages';
|
|
1
2
|
/**
|
|
2
3
|
* Shared combobox input utility functions used by both Elements and React packages.
|
|
3
4
|
* Covers keyboard actions, focus-out validation, match checking, and input display.
|
|
@@ -23,7 +24,7 @@ export interface IFocusOutResult {
|
|
|
23
24
|
export declare const getInputValueAction: (inputValue: string, currentValues: string[], options: IPktComboboxOption[], allowUserInput: boolean, multiple: boolean) => IFocusOutResult;
|
|
24
25
|
export interface ICheckForMatchesResult {
|
|
25
26
|
addValueText: string | null;
|
|
26
|
-
userInfoMessage:
|
|
27
|
+
userInfoMessage: TComboboxMessageKey;
|
|
27
28
|
shouldRemoveValue: boolean;
|
|
28
29
|
shouldResetInput: boolean;
|
|
29
30
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TPktStrings } from '../../shared-strings';
|
|
2
|
+
/**
|
|
3
|
+
* Nøkkelen til en statusmelding i comboboxen, eller tom streng når det ikke er
|
|
4
|
+
* noe å melde. Utvalgslogikken her returnerer nøkler i stedet for ferdig tekst,
|
|
5
|
+
* slik at Elements og React kan slå opp teksten i sin egen tekstkatalog.
|
|
6
|
+
*/
|
|
7
|
+
export type TComboboxMessageKey = keyof TPktStrings['combobox'] | '';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TComboboxMessageKey } from './messages';
|
|
1
2
|
/**
|
|
2
3
|
* Shared combobox option utility functions used by both Elements and React packages.
|
|
3
4
|
* Only framework-agnostic functions belong here.
|
|
@@ -46,5 +47,5 @@ export declare const findTypeaheadMatches: (options: IPktComboboxOption[], searc
|
|
|
46
47
|
*/
|
|
47
48
|
export declare const getSearchInfoMessage: (searchValue: string, selectedValues: string[], options: IPktComboboxOption[], allowUserInput: boolean) => {
|
|
48
49
|
addValueText: string | null;
|
|
49
|
-
userInfoMessage:
|
|
50
|
+
userInfoMessage: TComboboxMessageKey;
|
|
50
51
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TComboboxMessageKey } from './messages';
|
|
1
2
|
/**
|
|
2
3
|
* Shared combobox selection management functions used by both Elements and React packages.
|
|
3
4
|
* Only framework-agnostic functions belong here.
|
|
@@ -20,7 +21,7 @@ export interface IToggleSelectionResult {
|
|
|
20
21
|
options: IPktComboboxOption[];
|
|
21
22
|
shouldOptionsBeOpen: boolean;
|
|
22
23
|
shouldResetInput: boolean;
|
|
23
|
-
userInfoMessage:
|
|
24
|
+
userInfoMessage: TComboboxMessageKey;
|
|
24
25
|
searchValue: string;
|
|
25
26
|
newUserOption: IPktComboboxOption | null;
|
|
26
27
|
}
|
|
@@ -47,7 +48,7 @@ export declare const deselectOption: (value: string | null, currentValues: strin
|
|
|
47
48
|
export declare const selectAllOptions: (options: IPktComboboxOption[], maxlength: number | null) => {
|
|
48
49
|
values: string[];
|
|
49
50
|
options: IPktComboboxOption[];
|
|
50
|
-
userInfoMessage:
|
|
51
|
+
userInfoMessage: TComboboxMessageKey;
|
|
51
52
|
};
|
|
52
53
|
/**
|
|
53
54
|
* Clears all selections.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oslokommune/punkt-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "18.1.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",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"@eslint/compat": "^2.1.0",
|
|
45
45
|
"@eslint/eslintrc": "^3.3.5",
|
|
46
46
|
"@eslint/js": "^10.0.1",
|
|
47
|
-
"@oslokommune/punkt-assets": "^
|
|
48
|
-
"@oslokommune/punkt-css": "^
|
|
47
|
+
"@oslokommune/punkt-assets": "^18.0.0",
|
|
48
|
+
"@oslokommune/punkt-css": "^18.0.0",
|
|
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": "087459aca13f8ff3a34afc42f8e1cd73900d4896"
|
|
106
106
|
}
|
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { createContext, forwardRef, ReactNode, useContext } from 'react'
|
|
4
|
-
import type { TAccordionSkin } from 'shared-types'
|
|
4
|
+
import type { IPktAccordionBase, TAccordionSkin } from 'shared-types'
|
|
5
5
|
|
|
6
6
|
export type TPktAccordionSkin = TAccordionSkin
|
|
7
7
|
|
|
8
|
-
export interface IPktAccordion {
|
|
9
|
-
compact?: boolean
|
|
10
|
-
/**
|
|
11
|
-
* @default skin: "borderless"
|
|
12
|
-
*/
|
|
13
|
-
skin?: TPktAccordionSkin
|
|
14
|
-
/**
|
|
15
|
-
* @description A unique identifier to connect the accordion with a heading
|
|
16
|
-
*/
|
|
17
|
-
ariaLabelledBy?: string
|
|
8
|
+
export interface IPktAccordion extends IPktAccordionBase {
|
|
18
9
|
children?: ReactNode
|
|
19
|
-
name?: string
|
|
20
10
|
className?: string
|
|
21
11
|
}
|
|
22
12
|
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { forwardRef, type MouseEvent, type ReactNode, type SyntheticEvent, useState } from 'react'
|
|
4
|
-
import type { TAccordionSkin } from 'shared-types'
|
|
4
|
+
import type { IPktAccordionItemBase, TAccordionSkin } from 'shared-types'
|
|
5
5
|
|
|
6
6
|
import { PktIcon } from '../icon/Icon'
|
|
7
7
|
import { useAccordionContext } from './Accordion'
|
|
8
8
|
|
|
9
9
|
export type TPktAccordionSkin = TAccordionSkin
|
|
10
10
|
|
|
11
|
-
export interface IPktAccordionItem {
|
|
12
|
-
defaultOpen?: boolean
|
|
13
|
-
id: string
|
|
11
|
+
export interface IPktAccordionItem extends Omit<IPktAccordionItemBase, 'title'> {
|
|
14
12
|
title: string | ReactNode
|
|
15
|
-
skin?: TPktAccordionSkin
|
|
16
|
-
compact?: boolean
|
|
17
|
-
isOpen?: boolean
|
|
18
13
|
children?: ReactNode
|
|
19
|
-
name?: string
|
|
20
14
|
className?: string
|
|
21
15
|
onClick?: (e: MouseEvent<HTMLDetailsElement>) => void
|
|
22
16
|
onToggle?: (e: SyntheticEvent<HTMLDetailsElement>) => void
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import classNames from 'classnames'
|
|
4
4
|
import { FC, HTMLAttributes, ReactElement, ReactNode, useCallback, useState } from 'react'
|
|
5
|
-
import type { TAlertRole, TAlertSkin, TAriaLive } from 'shared-types'
|
|
5
|
+
import type { TAlertRole, TAlertSkin, TAlertSize, TAriaLive } from 'shared-types'
|
|
6
|
+
import { formatString, type IPktStringsProps } from 'shared-strings'
|
|
6
7
|
|
|
7
8
|
import { PktButton } from '../button/Button'
|
|
8
9
|
import { PktIcon } from '../icon/Icon'
|
|
10
|
+
import { usePktStrings } from '../../hooks/usePktStrings'
|
|
9
11
|
|
|
10
|
-
export interface IPktAlert
|
|
12
|
+
export interface IPktAlert
|
|
13
|
+
extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>, IPktStringsProps {
|
|
11
14
|
skin?: TAlertSkin
|
|
12
15
|
closeAlert?: boolean
|
|
13
16
|
title?: ReactNode
|
|
@@ -23,7 +26,7 @@ export interface IPktAlert extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
|
|
|
23
26
|
*
|
|
24
27
|
* @default medium
|
|
25
28
|
*/
|
|
26
|
-
size?:
|
|
29
|
+
size?: TAlertSize
|
|
27
30
|
onClose?: (e: CustomEvent) => void
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -41,9 +44,11 @@ export const PktAlert: FC<IPktAlert> = ({
|
|
|
41
44
|
role = 'status',
|
|
42
45
|
skin = 'info' as TAlertSkin,
|
|
43
46
|
className,
|
|
47
|
+
strings,
|
|
44
48
|
...props
|
|
45
49
|
}: IPktAlert): ReactElement => {
|
|
46
50
|
const [isClosed, setIsClosed] = useState(false)
|
|
51
|
+
const s = usePktStrings(['generic', 'alert'], strings)
|
|
47
52
|
|
|
48
53
|
const classes = {
|
|
49
54
|
'pkt-alert': true,
|
|
@@ -87,7 +92,7 @@ export const PktAlert: FC<IPktAlert> = ({
|
|
|
87
92
|
variant="icon-only"
|
|
88
93
|
onClick={onClose}
|
|
89
94
|
>
|
|
90
|
-
<span className="sr-only">
|
|
95
|
+
<span className="sr-only">{s.generic.close}</span>
|
|
91
96
|
</PktButton>
|
|
92
97
|
</div>
|
|
93
98
|
)}
|
|
@@ -95,7 +100,9 @@ export const PktAlert: FC<IPktAlert> = ({
|
|
|
95
100
|
|
|
96
101
|
<div className="pkt-alert__text">{children}</div>
|
|
97
102
|
|
|
98
|
-
{date &&
|
|
103
|
+
{date && (
|
|
104
|
+
<div className="pkt-alert__date">{formatString(s.alert.lastUpdated, { date })}</div>
|
|
105
|
+
)}
|
|
99
106
|
</div>
|
|
100
107
|
</div>
|
|
101
108
|
)
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import { AnchorHTMLAttributes, forwardRef, ReactNode, Ref } from 'react'
|
|
4
|
+
import type { IPktBackLinkBase, TRenderLink } from 'shared-types'
|
|
4
5
|
|
|
5
6
|
import { PktIcon } from '../icon/Icon'
|
|
7
|
+
import { usePktStrings } from '../../hooks/usePktStrings'
|
|
6
8
|
|
|
7
|
-
export interface IPktBackLink
|
|
8
|
-
href
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
renderLink?: (args: {
|
|
12
|
-
href: string
|
|
13
|
-
className: string
|
|
14
|
-
children: ReactNode
|
|
15
|
-
props: AnchorHTMLAttributes<HTMLAnchorElement>
|
|
16
|
-
}) => ReactNode
|
|
9
|
+
export interface IPktBackLink
|
|
10
|
+
extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>,
|
|
11
|
+
IPktBackLinkBase {
|
|
12
|
+
renderLink?: TRenderLink<ReactNode, AnchorHTMLAttributes<HTMLAnchorElement>>
|
|
17
13
|
ref?: Ref<HTMLElement>
|
|
18
14
|
}
|
|
19
15
|
|
|
20
16
|
export const PktBackLink = forwardRef<HTMLElement, IPktBackLink>(
|
|
21
|
-
(
|
|
17
|
+
(
|
|
18
|
+
{ href = '/', text = 'Forsiden', ariaLabel, renderLink, className, strings, ...props },
|
|
19
|
+
ref,
|
|
20
|
+
) => {
|
|
22
21
|
const linkChildren = (
|
|
23
22
|
<>
|
|
24
23
|
<PktIcon className="pkt-back-link__icon pkt-icon pkt-link__icon" name="chevron-thin-left" aria-hidden="true" />
|
|
@@ -34,10 +33,11 @@ export const PktBackLink = forwardRef<HTMLElement, IPktBackLink>(
|
|
|
34
33
|
</a>
|
|
35
34
|
))
|
|
36
35
|
|
|
36
|
+
const s = usePktStrings(['backlink'], strings)
|
|
37
37
|
const classes = ['pkt-back-link', className].filter(Boolean).join(' ')
|
|
38
38
|
|
|
39
39
|
return (
|
|
40
|
-
<nav className={classes} aria-label={ariaLabel
|
|
40
|
+
<nav className={classes} aria-label={ariaLabel ?? s.backlink.label} ref={ref}>
|
|
41
41
|
{linkRenderer({
|
|
42
42
|
href,
|
|
43
43
|
className: 'pkt-link pkt-link--icon-left',
|
|
@@ -2,28 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
import { ForwardedRef, forwardRef, type AnchorHTMLAttributes, type ReactNode } from 'react'
|
|
4
4
|
import { Link } from 'react-router-dom'
|
|
5
|
+
import type {
|
|
6
|
+
IBreadcrumb,
|
|
7
|
+
IPktBreadcrumbsBase,
|
|
8
|
+
TBreadcrumbsNavigationType,
|
|
9
|
+
TRenderLink,
|
|
10
|
+
} from 'shared-types'
|
|
5
11
|
|
|
6
12
|
import { PktIcon } from '../icon/Icon'
|
|
13
|
+
import { usePktStrings } from '../../hooks/usePktStrings'
|
|
7
14
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
export type { IBreadcrumb }
|
|
16
|
+
|
|
17
|
+
/** @deprecated Use `IBreadcrumb`. */
|
|
18
|
+
export type IBreadcrumbs = IBreadcrumb
|
|
12
19
|
|
|
13
|
-
export interface IPktBreadcrumbs
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
className: string
|
|
19
|
-
children: ReactNode
|
|
20
|
-
props: AnchorHTMLAttributes<HTMLAnchorElement>
|
|
21
|
-
}) => ReactNode
|
|
20
|
+
export interface IPktBreadcrumbs
|
|
21
|
+
extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'children'>,
|
|
22
|
+
IPktBreadcrumbsBase {
|
|
23
|
+
navigationType?: TBreadcrumbsNavigationType
|
|
24
|
+
renderLink?: TRenderLink<ReactNode, AnchorHTMLAttributes<HTMLAnchorElement>>
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
export const PktBreadcrumbs = forwardRef(
|
|
25
28
|
(
|
|
26
|
-
{ breadcrumbs, navigationType, renderLink, className, ...props }: IPktBreadcrumbs,
|
|
29
|
+
{ breadcrumbs, navigationType, renderLink, className, strings, ...props }: IPktBreadcrumbs,
|
|
27
30
|
ref: ForwardedRef<HTMLAnchorElement>,
|
|
28
31
|
) => {
|
|
29
32
|
const slicedBreadcrumbs = breadcrumbs
|
|
@@ -31,6 +34,7 @@ export const PktBreadcrumbs = forwardRef(
|
|
|
31
34
|
const backLink = slicedBreadcrumbs[slicedBreadcrumbs.length - 2]
|
|
32
35
|
|
|
33
36
|
// Define the classes
|
|
37
|
+
const s = usePktStrings(['breadcrumbs'], strings)
|
|
34
38
|
const classes = [className, 'pkt-breadcrumbs'].filter(Boolean).join(' ')
|
|
35
39
|
|
|
36
40
|
// Create a default renderLink implementation based on navigationType
|
|
@@ -50,7 +54,7 @@ export const PktBreadcrumbs = forwardRef(
|
|
|
50
54
|
|
|
51
55
|
// Mobile and desktop have different markup
|
|
52
56
|
return (
|
|
53
|
-
<nav ref={ref} aria-label=
|
|
57
|
+
<nav ref={ref} aria-label={s.breadcrumbs.ariaLabel} className={classes}>
|
|
54
58
|
<ol className="pkt-breadcrumbs__list pkt-breadcrumbs--desktop">
|
|
55
59
|
{slicedBreadcrumbs.map((item, index) => (
|
|
56
60
|
<li key={`breadcrumb-${index}`} className="pkt-breadcrumbs__item">
|
|
@@ -223,7 +223,7 @@ describe('PktCalendar', () => {
|
|
|
223
223
|
|
|
224
224
|
test('handles custom day strings', () => {
|
|
225
225
|
const { container } = createCalendar({
|
|
226
|
-
strings: { daysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'] },
|
|
226
|
+
strings: { dates: { daysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'] } },
|
|
227
227
|
})
|
|
228
228
|
|
|
229
229
|
const dayHeaders = container.querySelectorAll('.pkt-calendar__day-name')
|
|
@@ -235,10 +235,12 @@ describe('PktCalendar', () => {
|
|
|
235
235
|
const { container } = createCalendar({
|
|
236
236
|
withcontrols: true,
|
|
237
237
|
strings: {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
dates: {
|
|
239
|
+
months: [
|
|
240
|
+
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
|
241
|
+
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
|
|
242
|
+
],
|
|
243
|
+
},
|
|
242
244
|
},
|
|
243
245
|
})
|
|
244
246
|
|
|
@@ -1,38 +1,17 @@
|
|
|
1
1
|
import type { IDateConstraints, TDateRangeMap } from 'shared-types/calendar'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
month: 'Måned',
|
|
5
|
-
year: 'År',
|
|
6
|
-
days: ['Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag', 'Søndag'],
|
|
7
|
-
daysShort: ['Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør', 'Søn'],
|
|
8
|
-
months: [
|
|
9
|
-
'Januar',
|
|
10
|
-
'Februar',
|
|
11
|
-
'Mars',
|
|
12
|
-
'April',
|
|
13
|
-
'Mai',
|
|
14
|
-
'Juni',
|
|
15
|
-
'Juli',
|
|
16
|
-
'August',
|
|
17
|
-
'September',
|
|
18
|
-
'Oktober',
|
|
19
|
-
'November',
|
|
20
|
-
'Desember',
|
|
21
|
-
],
|
|
22
|
-
week: 'Uke',
|
|
23
|
-
prevMonth: 'Forrige måned',
|
|
24
|
-
nextMonth: 'Neste måned',
|
|
25
|
-
}
|
|
3
|
+
import type { TPktStringsOverride } from 'shared-strings'
|
|
26
4
|
|
|
5
|
+
/** Datonavn og navigasjonstekster slik kalender-underkomponentene forventer dem. */
|
|
27
6
|
export interface IPktCalendarStrings {
|
|
28
|
-
month
|
|
29
|
-
year
|
|
30
|
-
days
|
|
31
|
-
daysShort
|
|
32
|
-
months
|
|
33
|
-
week
|
|
34
|
-
prevMonth
|
|
35
|
-
nextMonth
|
|
7
|
+
month: string
|
|
8
|
+
year: string
|
|
9
|
+
days: string[]
|
|
10
|
+
daysShort: string[]
|
|
11
|
+
months: string[]
|
|
12
|
+
week: string
|
|
13
|
+
prevMonth: string
|
|
14
|
+
nextMonth: string
|
|
36
15
|
}
|
|
37
16
|
|
|
38
17
|
export interface PktCalendarHandle {
|
|
@@ -64,7 +43,8 @@ export interface IPktCalendar {
|
|
|
64
43
|
today?: string
|
|
65
44
|
|
|
66
45
|
// Localization
|
|
67
|
-
|
|
46
|
+
/** Overstyrer tekster for denne komponenten. */
|
|
47
|
+
strings?: TPktStringsOverride
|
|
68
48
|
|
|
69
49
|
// Callbacks
|
|
70
50
|
onDateSelected?: (selected: string[]) => void
|
|
@@ -87,7 +67,7 @@ export type TDayViewData = {
|
|
|
87
67
|
|
|
88
68
|
export interface ICalendarState {
|
|
89
69
|
componentId: string
|
|
90
|
-
strings:
|
|
70
|
+
strings: IPktCalendarStrings
|
|
91
71
|
|
|
92
72
|
// Navigation
|
|
93
73
|
year: number
|
|
@@ -148,7 +128,7 @@ export interface ICalendarState {
|
|
|
148
128
|
|
|
149
129
|
export interface ICalendarNavProps {
|
|
150
130
|
componentId: string
|
|
151
|
-
strings:
|
|
131
|
+
strings: IPktCalendarStrings
|
|
152
132
|
year: number
|
|
153
133
|
month: number
|
|
154
134
|
earliest: string | null
|
|
@@ -17,7 +17,8 @@ import {
|
|
|
17
17
|
getKeyDirection,
|
|
18
18
|
} from 'shared-utils/calendar/keyboard-navigation'
|
|
19
19
|
|
|
20
|
-
import {
|
|
20
|
+
import { type IPktCalendar, type ICalendarState } from './types'
|
|
21
|
+
import { usePktStrings } from '../../hooks/usePktStrings'
|
|
21
22
|
|
|
22
23
|
export function useCalendarState(props: IPktCalendar): ICalendarState {
|
|
23
24
|
const {
|
|
@@ -43,7 +44,20 @@ export function useCalendarState(props: IPktCalendar): ICalendarState {
|
|
|
43
44
|
const generatedId = useId()
|
|
44
45
|
const componentId = idProp ?? generatedId
|
|
45
46
|
|
|
46
|
-
const
|
|
47
|
+
const catalog = usePktStrings(['dates', 'calendar'], stringsProp)
|
|
48
|
+
const strings = useMemo(
|
|
49
|
+
() => ({
|
|
50
|
+
month: catalog.dates.month,
|
|
51
|
+
year: catalog.dates.year,
|
|
52
|
+
week: catalog.dates.week,
|
|
53
|
+
days: catalog.dates.days,
|
|
54
|
+
daysShort: catalog.dates.daysShort,
|
|
55
|
+
months: catalog.dates.months,
|
|
56
|
+
prevMonth: catalog.calendar.prevMonth,
|
|
57
|
+
nextMonth: catalog.calendar.nextMonth,
|
|
58
|
+
}),
|
|
59
|
+
[catalog],
|
|
60
|
+
)
|
|
47
61
|
|
|
48
62
|
const todayDate = useMemo(
|
|
49
63
|
() => (todayProp ? parseISODateString(todayProp) : todayInTz()),
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
useEffect,
|
|
9
9
|
useRef,
|
|
10
10
|
} from 'react'
|
|
11
|
+
import { usePktStrings } from '../../hooks/usePktStrings'
|
|
12
|
+
import type { TPktStringsOverride } from 'shared-strings'
|
|
11
13
|
|
|
12
14
|
export interface IPktCheckbox extends InputHTMLAttributes<HTMLInputElement> {
|
|
13
15
|
id: string
|
|
@@ -24,9 +26,13 @@ export interface IPktCheckbox extends InputHTMLAttributes<HTMLInputElement> {
|
|
|
24
26
|
hideLabel?: boolean
|
|
25
27
|
labelPosition?: 'right' | 'left'
|
|
26
28
|
optionalTag?: boolean
|
|
29
|
+
/** @deprecated Bruk `strings={{ forms: { optional: '…' } }}` eller `setPktStrings()`. */
|
|
27
30
|
optionalText?: string
|
|
28
31
|
requiredTag?: boolean
|
|
32
|
+
/** @deprecated Bruk `strings={{ forms: { required: '…' } }}` eller `setPktStrings()`. */
|
|
29
33
|
requiredText?: string
|
|
34
|
+
/** Overstyrer tekster for denne komponenten. */
|
|
35
|
+
strings?: TPktStringsOverride
|
|
30
36
|
tagText?: string | null
|
|
31
37
|
onChange?: ChangeEventHandler<HTMLInputElement>
|
|
32
38
|
}
|
|
@@ -48,14 +54,16 @@ export const PktCheckbox = forwardRef(
|
|
|
48
54
|
checked,
|
|
49
55
|
indeterminate,
|
|
50
56
|
optionalTag,
|
|
51
|
-
optionalText
|
|
57
|
+
optionalText,
|
|
52
58
|
requiredTag,
|
|
53
|
-
requiredText
|
|
59
|
+
requiredText,
|
|
60
|
+
strings,
|
|
54
61
|
tagText,
|
|
55
62
|
...props
|
|
56
63
|
}: IPktCheckbox,
|
|
57
64
|
ref: ForwardedRef<HTMLInputElement>,
|
|
58
65
|
): ReactElement => {
|
|
66
|
+
const s = usePktStrings(['forms'], strings)
|
|
59
67
|
const internalRef = useRef<HTMLInputElement>(null)
|
|
60
68
|
|
|
61
69
|
useEffect(() => {
|
|
@@ -97,8 +105,16 @@ export const PktCheckbox = forwardRef(
|
|
|
97
105
|
return (
|
|
98
106
|
<>
|
|
99
107
|
{tagText && <span className={tagClasses + ` pkt-tag--gray`}>{tagText}</span>}
|
|
100
|
-
{optionalTag &&
|
|
101
|
-
|
|
108
|
+
{optionalTag && (
|
|
109
|
+
<span className={tagClasses + ` pkt-tag--blue-light`}>
|
|
110
|
+
{optionalText ?? s.forms.optional}
|
|
111
|
+
</span>
|
|
112
|
+
)}
|
|
113
|
+
{requiredTag && (
|
|
114
|
+
<span className={tagClasses + ` pkt-tag--beige`}>
|
|
115
|
+
{requiredText ?? s.forms.required}
|
|
116
|
+
</span>
|
|
117
|
+
)}
|
|
102
118
|
</>
|
|
103
119
|
)
|
|
104
120
|
}
|
|
@@ -27,6 +27,7 @@ export const PktCombobox = forwardRef<HTMLDivElement, IPktCombobox>((props, ref)
|
|
|
27
27
|
return (
|
|
28
28
|
<div className={outerClasses} ref={state.wrapperRef} id={state.id || undefined}>
|
|
29
29
|
<PktInputWrapper
|
|
30
|
+
strings={state.strings}
|
|
30
31
|
forId={wrapperForId}
|
|
31
32
|
hasFieldset={props.hasFieldset ?? !hasTextInput}
|
|
32
33
|
label={state.label || ''}
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import type { IComboboxState } from './types'
|
|
4
4
|
import { PktIcon } from '../icon/Icon'
|
|
5
|
+
import { usePktStrings } from '../../hooks/usePktStrings'
|
|
5
6
|
|
|
6
7
|
interface IListboxProps {
|
|
7
8
|
state: IComboboxState
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export const Listbox = ({ state }: IListboxProps) => {
|
|
12
|
+
const s = usePktStrings(['listbox'], state.strings)
|
|
11
13
|
const {
|
|
12
14
|
listboxId,
|
|
13
15
|
label,
|
|
@@ -59,9 +61,9 @@ export const Listbox = ({ state }: IListboxProps) => {
|
|
|
59
61
|
<input
|
|
60
62
|
className="pkt-txt-16-light"
|
|
61
63
|
type="text"
|
|
62
|
-
aria-label=
|
|
64
|
+
aria-label={s.listbox.searchLabel}
|
|
63
65
|
form=""
|
|
64
|
-
placeholder={searchPlaceholder
|
|
66
|
+
placeholder={searchPlaceholder ?? s.listbox.searchPlaceholder}
|
|
65
67
|
onChange={handleSearchInput}
|
|
66
68
|
onKeyDown={handleSearchKeydown}
|
|
67
69
|
value={searchValue}
|