@oslokommune/punkt-elements 19.6.0 → 19.8.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 +13 -0
- package/dist/{alert-IaZzEgyI.cjs → alert-CKqtC9AM.cjs} +1 -1
- package/dist/{alert-C0PiYnot.js → alert-WME3geaX.js} +5 -0
- package/dist/base-elements/input-element.d.ts +1 -0
- package/dist/combobox-89Ohd1Oe.cjs +139 -0
- package/dist/{combobox-CWzWHBaw.js → combobox-Cpb67TV0.js} +47 -423
- package/dist/components/combobox/combobox-base.d.ts +2 -2
- package/dist/components/combobox/combobox.d.ts +9 -26
- package/dist/components/input-wrapper/input-wrapper.d.ts +1 -0
- package/dist/components/messagebox/messagebox.d.ts +2 -6
- package/dist/{datepicker-CWHYYj-H.cjs → datepicker-B9NCJX4o.cjs} +1 -1
- package/dist/{datepicker-Bs7Z3EFn.js → datepicker-DBEKa1aJ.js} +1 -1
- package/dist/{fileupload-CMIFZWJ5.cjs → fileupload-2YAbjYuU.cjs} +1 -1
- package/dist/{fileupload-BQFJx1ok.js → fileupload-DqWCXMPz.js} +2 -2
- package/dist/{header-C4Uojzoy.cjs → header-9Y6Q6Cfq.cjs} +1 -1
- package/dist/{header-Cc1Cy0U3.js → header-Dp0Lq7wS.js} +1 -1
- package/dist/{input-wrapper-BoTugCvh.js → input-wrapper-C9K-_7g-.js} +1 -1
- package/dist/{input-wrapper-J3mEKhvR.cjs → input-wrapper-CTMf4kCK.cjs} +1 -1
- package/dist/{messagebox-DPFBuisE.js → messagebox-D17GYxb9.js} +5 -45
- package/dist/messagebox-X01V2l_N.cjs +13 -0
- package/dist/pkt-alert.cjs +1 -1
- package/dist/pkt-alert.js +1 -1
- package/dist/pkt-combobox.cjs +1 -1
- package/dist/pkt-combobox.js +1 -1
- package/dist/pkt-datepicker.cjs +1 -1
- package/dist/pkt-datepicker.js +1 -1
- package/dist/pkt-fileupload.cjs +1 -1
- package/dist/pkt-fileupload.js +1 -1
- package/dist/pkt-header.cjs +1 -1
- package/dist/pkt-header.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +28 -28
- package/dist/pkt-input-wrapper.cjs +1 -1
- package/dist/pkt-input-wrapper.js +1 -1
- package/dist/pkt-messagebox.cjs +1 -1
- package/dist/pkt-messagebox.js +1 -1
- package/dist/pkt-select.cjs +1 -1
- package/dist/pkt-select.js +1 -1
- package/dist/pkt-textarea.cjs +1 -1
- package/dist/pkt-textarea.js +1 -1
- package/dist/pkt-textinput.cjs +1 -1
- package/dist/pkt-textinput.js +1 -1
- package/dist/pkt-timepicker.cjs +1 -1
- package/dist/pkt-timepicker.js +1 -1
- package/dist/{select-CZYQ5Dmx.cjs → select-CZk57p1_.cjs} +1 -1
- package/dist/{select-DYjKMmHa.js → select-Cz80KV3g.js} +1 -1
- package/dist/shared-types/combobox.d.ts +73 -5
- package/dist/shared-types/index.d.ts +6 -2
- package/dist/shared-types/messagebox.d.ts +32 -0
- package/dist/shared-types/size.d.ts +3 -3
- package/dist/shared-types/skin.d.ts +1 -4
- package/dist/{textarea-C2oaRlfb.js → textarea-Dfvx1I60.js} +1 -1
- package/dist/{textarea-H1Lt2o6K.cjs → textarea-Dwjx-Crl.cjs} +1 -1
- package/dist/{textinput-C0eu70sH.js → textinput-7zTPlXVj.js} +1 -1
- package/dist/{textinput-C2Tx-OrN.cjs → textinput-BeraGRzb.cjs} +1 -1
- package/dist/{timepicker-B8TwchA2.js → timepicker-C0dSH4Ij.js} +1 -1
- package/dist/{timepicker-DZG_gHIa.cjs → timepicker-DarB9eA6.cjs} +1 -1
- package/package.json +2 -2
- package/src/components/alert/alert.ts +1 -1
- package/src/components/combobox/combobox-base.ts +14 -8
- package/src/components/combobox/combobox-value.ts +2 -2
- package/src/components/combobox/combobox.attributes.test.ts +3 -2
- package/src/components/combobox/combobox.ts +26 -26
- package/src/components/input-wrapper/input-wrapper.ts +1 -0
- package/src/components/messagebox/messagebox.test.ts +1 -1
- package/src/components/messagebox/messagebox.ts +6 -12
- package/dist/combobox-FCguoyDH.cjs +0 -139
- package/dist/messagebox-JWKMJEFc.cjs +0 -13
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
* combobox.ts
|
|
3
3
|
*
|
|
4
4
|
* Type definitions for the combobox and listbox components.
|
|
5
|
-
* Used by both Elements and React implementations
|
|
6
|
-
*
|
|
5
|
+
* Used by both Elements and React implementations,
|
|
6
|
+
* the shared combobox helper functions, and typed component specs.
|
|
7
7
|
*/
|
|
8
|
+
import type { IFormFieldErrorProps, IFormFieldLabelProps, IHelptextProps, ITagOptionalRequiredProps } from './form-field';
|
|
9
|
+
import type { TPktInputSize } from './size';
|
|
8
10
|
/**
|
|
9
11
|
* Tag skin colors available for combobox option tags.
|
|
10
12
|
* Matches the TTagSkin values from the tag component.
|
|
11
13
|
*/
|
|
12
|
-
export
|
|
14
|
+
export declare const COMBOBOX_TAG_SKINS: readonly ['blue', 'blue-dark', 'blue-light', 'green', 'red', 'yellow', 'beige', 'gray', 'grey'];
|
|
15
|
+
export type TPktComboboxTagSkin = (typeof COMBOBOX_TAG_SKINS)[number];
|
|
13
16
|
/**
|
|
14
17
|
* Represents a single option in a combobox or listbox.
|
|
15
18
|
*/
|
|
@@ -27,8 +30,73 @@ export interface IPktComboboxOption {
|
|
|
27
30
|
/**
|
|
28
31
|
* How the selected value is displayed in the combobox input.
|
|
29
32
|
*/
|
|
30
|
-
export
|
|
33
|
+
export declare const COMBOBOX_DISPLAY_VALUES: readonly ['label', 'value', 'prefixAndValue'];
|
|
34
|
+
export type TPktComboboxDisplayValue = (typeof COMBOBOX_DISPLAY_VALUES)[number];
|
|
31
35
|
/**
|
|
32
36
|
* Placement of selected value tags in multiple selection mode.
|
|
33
37
|
*/
|
|
34
|
-
export
|
|
38
|
+
export declare const COMBOBOX_TAG_PLACEMENTS: readonly ['inside', 'outside'];
|
|
39
|
+
export type TPktComboboxTagPlacement = (typeof COMBOBOX_TAG_PLACEMENTS)[number];
|
|
40
|
+
/**
|
|
41
|
+
* Combobox props shared by React, Elements, and typed component specs.
|
|
42
|
+
*
|
|
43
|
+
* @remarks Both frameworks extend this with `Omit<>` and widen a few props:
|
|
44
|
+
* - React widens `helptext`, `helptextDropdown` and `errorMessage` to `ReactNode`.
|
|
45
|
+
* - Elements widens string/number props to `| null` (Lit uses `null` for an unset attribute,
|
|
46
|
+
* see `PktInputElement`) and `useWrapper` to `Booleanish`. Elements omits `form`, which is
|
|
47
|
+
* a getter returning the associated `HTMLFormElement`, not the form id.
|
|
48
|
+
*
|
|
49
|
+
* `hasFieldset` and `counter` are tri-state: `null` means the component derives the value.
|
|
50
|
+
*/
|
|
51
|
+
export interface IPktComboboxBase extends IFormFieldLabelProps, IHelptextProps, IFormFieldErrorProps, ITagOptionalRequiredProps {
|
|
52
|
+
id?: string;
|
|
53
|
+
name?: string;
|
|
54
|
+
form?: string;
|
|
55
|
+
ariaDescribedby?: string;
|
|
56
|
+
placeholder?: string;
|
|
57
|
+
required?: boolean;
|
|
58
|
+
value?: string | string[];
|
|
59
|
+
defaultValue?: string | string[];
|
|
60
|
+
options?: IPktComboboxOption[];
|
|
61
|
+
defaultOptions?: IPktComboboxOption[];
|
|
62
|
+
multiple?: boolean;
|
|
63
|
+
maxlength?: number;
|
|
64
|
+
typeahead?: boolean;
|
|
65
|
+
includeSearch?: boolean;
|
|
66
|
+
allowUserInput?: boolean;
|
|
67
|
+
searchPlaceholder?: string;
|
|
68
|
+
displayValueAs?: TPktComboboxDisplayValue;
|
|
69
|
+
tagPlacement?: TPktComboboxTagPlacement;
|
|
70
|
+
inputSize?: TPktInputSize;
|
|
71
|
+
fullwidth?: boolean;
|
|
72
|
+
inline?: boolean;
|
|
73
|
+
useWrapper?: boolean;
|
|
74
|
+
hasFieldset?: boolean | null;
|
|
75
|
+
counter?: boolean | null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Documented Combobox props (subset of `IPktComboboxBase`).
|
|
79
|
+
* Used for typed component specs in documentation.
|
|
80
|
+
*/
|
|
81
|
+
export type IComboboxSpecProps = Pick<IPktComboboxBase, 'name' | 'form' | 'ariaDescribedby' | 'id' | 'label' | 'placeholder' | 'multiple' | 'tagPlacement' | 'maxlength' | 'typeahead' | 'includeSearch' | 'allowUserInput' | 'searchPlaceholder' | 'displayValueAs' | 'inputSize' | 'value' | 'helptext' | 'helptextDropdown' | 'helptextDropdownButton' | 'disabled' | 'hasError' | 'errorMessage' | 'required' | 'requiredTag' | 'requiredText' | 'optionalTag' | 'optionalText' | 'tagText' | 'fullwidth' | 'defaultOptions' | 'options' | 'inline' | 'useWrapper' | 'hasFieldset' | 'counter' | 'defaultValue'>;
|
|
82
|
+
/**
|
|
83
|
+
* Default values for pkt-combobox. Single source of truth for both frameworks.
|
|
84
|
+
* Array defaults (`options`, `defaultOptions`) are intentionally absent — a shared array
|
|
85
|
+
* instance would be mutated across component instances.
|
|
86
|
+
*/
|
|
87
|
+
export declare const COMBOBOX_DEFAULTS: {
|
|
88
|
+
readonly multiple: false;
|
|
89
|
+
readonly typeahead: false;
|
|
90
|
+
readonly includeSearch: false;
|
|
91
|
+
readonly allowUserInput: false;
|
|
92
|
+
readonly displayValueAs: 'label';
|
|
93
|
+
readonly inputSize: 'medium';
|
|
94
|
+
readonly disabled: false;
|
|
95
|
+
readonly hasError: false;
|
|
96
|
+
readonly required: false;
|
|
97
|
+
readonly requiredTag: false;
|
|
98
|
+
readonly optionalTag: false;
|
|
99
|
+
readonly fullwidth: false;
|
|
100
|
+
readonly inline: false;
|
|
101
|
+
readonly useWrapper: true;
|
|
102
|
+
};
|
|
@@ -20,6 +20,7 @@ export type { TIconSizeClass, IPktIconBase, IIconSpecProps } from './icon';
|
|
|
20
20
|
export { LAYOUT_DIRECTIONS } from './layout';
|
|
21
21
|
export type { TLayout, TVerticalPosition, THorizontalPosition, TPosition, TPositionWithCenter, } from './layout';
|
|
22
22
|
export type { THTMLButtonType, TSelectionMode } from './form';
|
|
23
|
+
export { INPUT_SIZES } from './size';
|
|
23
24
|
export type { TPktInputSize, TSize3, TSize5, TSize7 } from './size';
|
|
24
25
|
export { ACCORDION_SKINS } from './accordion';
|
|
25
26
|
export type { TAccordionSkin, IPktAccordionBase, IPktAccordionItemBase, IAccordionSpecProps, IAccordionItemSpecProps, IAccordionVisualProps, } from './accordion';
|
|
@@ -33,7 +34,9 @@ export type { TBreadcrumbsNavigationType, IBreadcrumb, IBreadcrumbItem, IBreadcr
|
|
|
33
34
|
export type { IRenderLink, TRenderLink } from './render-link';
|
|
34
35
|
export type { IPktStringsProps } from '../shared-strings';
|
|
35
36
|
export type { IHelptextProps, ITagOptionalRequiredProps, IFormFieldLabelProps, IFormFieldErrorProps, IFormFieldCommonProps, TFormFieldCommonSpecKeys, } from './form-field';
|
|
36
|
-
export type {
|
|
37
|
+
export type { TTagSkin } from './skin';
|
|
38
|
+
export { MESSAGEBOX_SKINS, MESSAGEBOX_DEFAULTS } from './messagebox';
|
|
39
|
+
export type { TMessageboxSkin, IPktMessageboxBase, IMessageboxSpecProps } from './messagebox';
|
|
37
40
|
export { CALENDAR_DEFAULTS } from './calendar';
|
|
38
41
|
export type { IPktCalendarBase, ICalendarSpecProps, IDateConstraints, ICalendarGridDimensions, IGridCellPosition, TDateRangeMap, ISelectionState, ISelectionOptions, } from './calendar';
|
|
39
42
|
export type { IDatepickerStrings } from './datepicker';
|
|
@@ -41,7 +44,8 @@ export { defaultSingleStrings, defaultRangeStrings } from './datepicker';
|
|
|
41
44
|
export type { ITimepickerStrings } from './timepicker';
|
|
42
45
|
export { defaultTimepickerStrings } from './timepicker';
|
|
43
46
|
export type { TProgressbarRole, TProgressbarSkin, TProgressbarStatusPlacement, TProgressbarStatusType, TProgressbarTitlePosition, } from './progressbar';
|
|
44
|
-
export
|
|
47
|
+
export { COMBOBOX_TAG_SKINS, COMBOBOX_DISPLAY_VALUES, COMBOBOX_TAG_PLACEMENTS, COMBOBOX_DEFAULTS, } from './combobox';
|
|
48
|
+
export type { IPktComboboxOption, TPktComboboxTagSkin, TPktComboboxDisplayValue, TPktComboboxTagPlacement, IPktComboboxBase, IComboboxSpecProps, } from './combobox';
|
|
45
49
|
export type { IPktSelectOption, TSelectOption } from './select';
|
|
46
50
|
export type { TPktSearchInputAppearance, TPktSearchInputMethod, IPktSearchInputSuggestion, IPktSearchInput, } from './searchinput';
|
|
47
51
|
export { UPLOAD_STRATEGIES, FILE_UPLOAD_ITEM_RENDERERS, PREVIEW_UPLOAD_STATUS, } from './fileupload';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* messagebox.ts
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for pkt-messagebox.
|
|
5
|
+
* Used by React, Elements, and typed component specs.
|
|
6
|
+
*/
|
|
7
|
+
/** Messagebox skin variants — shared runtime source for types, specs, and Preview. */
|
|
8
|
+
export declare const MESSAGEBOX_SKINS: readonly ['beige', 'blue', 'red', 'green'];
|
|
9
|
+
export type TMessageboxSkin = (typeof MESSAGEBOX_SKINS)[number];
|
|
10
|
+
/**
|
|
11
|
+
* Messagebox props shared by React and Elements.
|
|
12
|
+
*
|
|
13
|
+
* @remarks React widens `title` to `ReactNode` and adds `onClose`.
|
|
14
|
+
* Elements dispatches a `close` event instead (and `on-close` for legacy Vue setups).
|
|
15
|
+
*/
|
|
16
|
+
export interface IPktMessageboxBase {
|
|
17
|
+
skin?: TMessageboxSkin;
|
|
18
|
+
title?: string;
|
|
19
|
+
compact?: boolean;
|
|
20
|
+
closable?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Documented Messagebox props (subset of `IPktMessageboxBase`).
|
|
24
|
+
* Used for typed component specs in documentation.
|
|
25
|
+
*/
|
|
26
|
+
export type IMessageboxSpecProps = Pick<IPktMessageboxBase, 'title' | 'skin' | 'compact' | 'closable'>;
|
|
27
|
+
/** Default values for pkt-messagebox. Single source of truth for both frameworks. */
|
|
28
|
+
export declare const MESSAGEBOX_DEFAULTS: {
|
|
29
|
+
readonly skin: 'beige';
|
|
30
|
+
readonly compact: false;
|
|
31
|
+
readonly closable: false;
|
|
32
|
+
};
|
|
@@ -17,7 +17,7 @@ export type TSize5 = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge';
|
|
|
17
17
|
*/
|
|
18
18
|
export type TSize7 = 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge';
|
|
19
19
|
/**
|
|
20
|
-
* Sizes used in our input components
|
|
20
|
+
* Sizes used in our input components — shared runtime source for types, specs, and Preview.
|
|
21
21
|
*/
|
|
22
|
-
export declare const
|
|
23
|
-
export type TPktInputSize = (typeof
|
|
22
|
+
export declare const INPUT_SIZES: readonly ['xsmall', 'small', 'medium'];
|
|
23
|
+
export type TPktInputSize = (typeof INPUT_SIZES)[number];
|
|
@@ -8,10 +8,7 @@
|
|
|
8
8
|
export { ALERT_SKINS, type TAlertSkin } from './alert';
|
|
9
9
|
export { ACCORDION_SKINS, type TAccordionSkin } from './accordion';
|
|
10
10
|
export { CARD_SKINS, type TCardSkin } from './card';
|
|
11
|
-
|
|
12
|
-
* Messagebox component skin variants
|
|
13
|
-
*/
|
|
14
|
-
export type TMessageboxSkin = 'beige' | 'blue' | 'red' | 'green';
|
|
11
|
+
export { MESSAGEBOX_SKINS, type TMessageboxSkin } from './messagebox';
|
|
15
12
|
/**
|
|
16
13
|
* Tag component skin variants
|
|
17
14
|
*/
|
|
@@ -6,7 +6,7 @@ import "./icon-JigbxxF7.js";
|
|
|
6
6
|
import { t as m } from "./if-defined-Bebu3LXY.js";
|
|
7
7
|
import { n as h, t as g } from "./ref-CCSGk4MP.js";
|
|
8
8
|
import { t as _ } from "./input-element-lLzfwdim.js";
|
|
9
|
-
import { r as v } from "./input-wrapper-
|
|
9
|
+
import { r as v } from "./input-wrapper-C9K-_7g-.js";
|
|
10
10
|
//#region ../../node_modules/lit-html/directives/live.js
|
|
11
11
|
var y = n(class extends c {
|
|
12
12
|
constructor(e) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./directive-helpers-BRrz3Bcj.cjs"),r=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const i=require("./if-defined-2mkIDgOm.cjs"),a=require("./ref-Emu5PNxk.cjs"),o=require("./input-element-CSfDGslx.cjs"),s=require("./input-wrapper-
|
|
1
|
+
const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./directive-helpers-BRrz3Bcj.cjs"),r=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const i=require("./if-defined-2mkIDgOm.cjs"),a=require("./ref-Emu5PNxk.cjs"),o=require("./input-element-CSfDGslx.cjs"),s=require("./input-wrapper-CTMf4kCK.cjs");var c=e.f(class extends e.p{constructor(t){if(super(t),t.type!==e.m.PROPERTY&&t.type!==e.m.ATTRIBUTE&&t.type!==e.m.BOOLEAN_ATTRIBUTE)throw Error("The `live` directive is not allowed on child or event bindings");if(!n.i(t))throw Error("`live` bindings can only contain a single expression")}render(e){return e}update(t,[r]){if(r===e.g||r===e.h)return r;let i=t.element,a=t.name;if(t.type===e.m.PROPERTY){if(r===i[a])return e.g}else if(t.type===e.m.BOOLEAN_ATTRIBUTE){if(!!r===i.hasAttribute(a))return e.g}else if(t.type===e.m.ATTRIBUTE&&i.getAttribute(a)===r+``)return e.g;return n.r(t),r}}),l=class extends o.t{constructor(...e){super(...e),this.inputRef=a.t(),this.value=``,this.autocomplete=`off`,this.rows=null,this.cols=null,this.counterCurrent=0}attributeChangedCallback(e,t,n){e===`value`&&this.value!==t&&(this.counterCurrent=n?n.length:0),super.attributeChangedCallback(e,t,n)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&(this.counterCurrent=this.value?.length||0),e.has(`id`)&&!this.name&&this.id&&(this.name=this.id)}updated(e){super.updated(e),this.classList.add(`pkt-textinput`,`pkt-textarea`),e.has(`value`)&&this.valueChanged(this.value,e.get(`value`))}render(){let n=this.effectiveCounter(this.counterMaxLength>0),o=t.t({"pkt-input":!0,[`pkt-input--${this.inputSize}`]:!0,"pkt-input--fullwidth":this.fullwidth,"pkt-input--counter-error":n&&this.counterMaxLength>0&&this.value.length>this.counterMaxLength}),l=this.ariaLabelledby||`${this.id}-input-label`;return e._`<pkt-input-wrapper
|
|
2
2
|
${r.n(this,[`helptext`])}
|
|
3
3
|
.strings=${this.strings}
|
|
4
4
|
label=${this.label}
|
|
@@ -5,7 +5,7 @@ import "./icon-JigbxxF7.js";
|
|
|
5
5
|
import { t as c } from "./if-defined-Bebu3LXY.js";
|
|
6
6
|
import { n as l, t as u } from "./ref-CCSGk4MP.js";
|
|
7
7
|
import { t as d } from "./input-element-lLzfwdim.js";
|
|
8
|
-
import { r as f } from "./input-wrapper-
|
|
8
|
+
import { r as f } from "./input-wrapper-C9K-_7g-.js";
|
|
9
9
|
//#region src/components/textinput/textinput.ts
|
|
10
10
|
var p = class extends d {
|
|
11
11
|
constructor(...e) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const r=require("./if-defined-2mkIDgOm.cjs"),i=require("./ref-Emu5PNxk.cjs"),a=require("./input-element-CSfDGslx.cjs"),o=require("./input-wrapper-
|
|
1
|
+
const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const r=require("./if-defined-2mkIDgOm.cjs"),i=require("./ref-Emu5PNxk.cjs"),a=require("./input-element-CSfDGslx.cjs"),o=require("./input-wrapper-CTMf4kCK.cjs");var s=class extends a.t{constructor(...e){super(...e),this.inputRef=i.t(),this.value=``,this.type=`text`,this.size=null,this.autocomplete=null,this.iconNameRight=null,this.prefix=null,this.suffix=null,this.omitSearchIcon=!1,this.counterCurrent=0}attributeChangedCallback(e,t,n){e===`value`&&this.value!==t&&(this.counterCurrent=n?n.length:0),super.attributeChangedCallback(e,t,n)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&(this.counterCurrent=this.value?.length||0),e.has(`id`)&&!this.name&&this.id&&(this.name=this.id)}updated(e){super.updated(e),this.classList.add(`pkt-textinput`),e.has(`value`)&&this.valueChanged(this.value,e.get(`value`))}render(){let a=this.type===`search`&&!this.iconNameRight&&!this.omitSearchIcon,s=this.effectiveCounter(this.counterMaxLength>0),c=t.t({"pkt-input":!0,[`pkt-input--${this.inputSize}`]:!0,"pkt-input--fullwidth":this.fullwidth,"pkt-input--counter-error":s&&this.counterMaxLength>0&&this.value.length>this.counterMaxLength}),l=this.ariaLabelledby||`${this.id}-input-label`;return e._`
|
|
2
2
|
<pkt-input-wrapper
|
|
3
3
|
${n.n(this,[`helptext`])}
|
|
4
4
|
.strings=${this.strings}
|
|
@@ -6,7 +6,7 @@ import "./icon-JigbxxF7.js";
|
|
|
6
6
|
import { t as l } from "./if-defined-Bebu3LXY.js";
|
|
7
7
|
import { n as u, t as d } from "./ref-CCSGk4MP.js";
|
|
8
8
|
import { t as f } from "./input-element-lLzfwdim.js";
|
|
9
|
-
import { r as p } from "./input-wrapper-
|
|
9
|
+
import { r as p } from "./input-wrapper-C9K-_7g-.js";
|
|
10
10
|
//#region ../../shared-utils/timepicker/time-utils.ts
|
|
11
11
|
var m = (e) => /^\d{2}:\d{2}$/.test(e) && parseInt(e.slice(0, 2), 10) <= 23 && parseInt(e.slice(3), 10) <= 59, h = (e) => {
|
|
12
12
|
let [t, n] = e.split(":").map(Number);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./format-B8meU8Tm.cjs"),r=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const i=require("./if-defined-2mkIDgOm.cjs"),a=require("./ref-Emu5PNxk.cjs"),o=require("./input-element-CSfDGslx.cjs"),s=require("./input-wrapper-J3mEKhvR.cjs");var c=e=>/^\d{2}:\d{2}$/.test(e)&&parseInt(e.slice(0,2),10)<=23&&parseInt(e.slice(3),10)<=59,l=e=>{let[t,n]=e.split(`:`).map(Number);return t*60+n},u=e=>e?Math.max(1,Math.round(e/60)):1,d=(e,t)=>{let n=e?parseInt(String(e).split(`:`)[0],10):0,r=t?parseInt(String(t).split(`:`)[0],10):23;return Array.from({length:r-n+1},(e,t)=>t+n)},f=e=>{let t=u(e);return Array.from({length:Math.floor(60/t)},(e,n)=>n*t)},p=(e,t,n,r)=>{let i=e===``?n===1?0:23:parseInt(e,10),a=t===``?n===1?0:Math.floor(59/r)*r:parseInt(t,10);return a+=n*r,a>59?(a=0,i=(i+1)%24):a<0&&(a=Math.floor(59/r)*r,i=(i-1+24)%24),{hours:String(i).padStart(2,`0`),minutes:String(a).padStart(2,`0`)}},m=class extends o.t{constructor(...e){super(...e),this.hiddenInputRef=a.t(),this.hoursInputRef=a.t(),this.minutesInputRef=a.t(),this.buttonRef=a.t(),this.value=``,this.hidePicker=!1,this.stepArrows=!1,this._hours=``,this._minutes=``,this._isOpen=!1,this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._hasFocus=!1,this._outsideClickHandler=e=>{this.contains(e.target)||this._closePopup()},this._handleComponentFocusIn=()=>{this._hasFocus||(this._hasFocus=!0,this.onFocus())},this._handleComponentFocusOut=e=>{this.contains(e.relatedTarget)||(this._hasFocus=!1,this.onBlur())},this._handleHoursKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t+1)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t-1+24)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowRight`:e.preventDefault(),this.minutesInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._hoursDigitCount=0,this._hoursFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._hoursDigitCount===0)this._hoursFirstDigit=t,this._hours=String(t).padStart(2,`0`),this._hoursDigitCount=1,this.onInput(),t>=3&&(this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.minutesInputRef.value?.focus());else{let e=this._hoursFirstDigit*10+t;this._hours=e<=23?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.onInput(),this.minutesInputRef.value?.focus()}}else e.preventDefault()}},this._handleHoursBlur=()=>{this._hours!==``&&(this._hours=String(parseInt(this._hours,10)).padStart(2,`0`)),this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._syncValueFromDisplay()},this._handleMinutesKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t+this._minuteStep)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t-this._minuteStep+60)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowLeft`:e.preventDefault(),this.hoursInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._minutesDigitCount=0,this._minutesFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._minutesDigitCount===0)this._minutesFirstDigit=t,this._minutes=String(t).padStart(2,`0`),this._minutesDigitCount=1,this.onInput(),t>=6&&(this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay());else{let e=this._minutesFirstDigit*10+t;this._minutes=e<=59?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay(),this.onInput()}}else e.preventDefault()}},this._handleMinutesBlur=()=>{this._minutes!==``&&(this._minutes=String(parseInt(this._minutes,10)).padStart(2,`0`)),this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._syncValueFromDisplay()},this._handlePopupKeydown=e=>{let t=document.activeElement,n=t.closest(`.pkt-timepicker-popup__col`);if(!n)return;let r=Array.from(n.querySelectorAll(`.pkt-timepicker-popup__option`)),i=r.indexOf(t),a=t.dataset.type??``;switch(e.key){case`ArrowDown`:e.preventDefault(),this._focusOptionAndSync(r[Math.min(i+1,r.length-1)],a);break;case`ArrowUp`:e.preventDefault(),this._focusOptionAndSync(r[Math.max(i-1,0)],a);break;case`Home`:e.preventDefault(),this._focusOptionAndSync(r[0],a);break;case`End`:e.preventDefault(),this._focusOptionAndSync(r[r.length-1],a);break;case`ArrowRight`:e.preventDefault(),a===`hour`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`minute`)}));break;case`ArrowLeft`:e.preventDefault(),a===`minute`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)}));break;case`Enter`:case` `:e.preventDefault(),t.click();break;case`Escape`:e.preventDefault(),this._closePopup(),this.buttonRef.value?.focus()}}}get inputRef(){return this.hiddenInputRef}manageValidity(e){let t=this.hoursInputRef.value;if(!t)return;let r=this.pktStrings.get(`validation`);if(this.required&&!this.value){this.internals.setValidity({valueMissing:!0},r.valueMissing,t),this._setAriaInvalid(!0);return}if(!this.value){this.internals.setValidity({}),this._setAriaInvalid(!1);return}let i=l(this.value),a=u(this.step);if(this.min&&i<l(String(this.min))){this.internals.setValidity({rangeUnderflow:!0},n.t(r.rangeUnderflowMin,{min:String(this.min)}),t),this._setAriaInvalid(!0);return}if(this.max&&i>l(String(this.max))){this.internals.setValidity({rangeOverflow:!0},n.t(r.rangeOverflowMax,{max:String(this.max)}),t),this._setAriaInvalid(!0);return}if(this.step&&i%a!==0){let e=a===60?r.timeStepMismatchHour:a===30?r.timeStepMismatchHalfHour:n.t(r.timeStepMismatch,{step:`${a}, ${a*2}, ${a*3}`});this.internals.setValidity({stepMismatch:!0},e,t),this._setAriaInvalid(!0);return}this.internals.setValidity({}),this._setAriaInvalid(!1)}_describedBy(){return s.r({id:`${this.id}-hours`,hasHelptext:!!this.helptext||this.hasSlotContent(`helptext`),ariaDescribedby:this.ariaDescribedby})}_setAriaInvalid(e){if(!this.touched&&e)return;let t=this.hoursInputRef.value,n=this.minutesInputRef.value;if(e)t?.setAttribute(`aria-invalid`,`true`),n?.setAttribute(`aria-invalid`,`true`);else{if(this.hasError)return;t?.removeAttribute(`aria-invalid`),n?.removeAttribute(`aria-invalid`)}}connectedCallback(){super.connectedCallback(),this.addEventListener(`focusin`,this._handleComponentFocusIn),this.addEventListener(`focusout`,this._handleComponentFocusOut),document.addEventListener(`click`,this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(`focusin`,this._handleComponentFocusIn),this.removeEventListener(`focusout`,this._handleComponentFocusOut),document.removeEventListener(`click`,this._outsideClickHandler)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&this._syncDisplayFromValue()}updated(e){super.updated(e),this.classList.add(`pkt-timepicker`),this.classList.toggle(`pkt-timepicker--stepper`,this.stepArrows),this.classList.toggle(`pkt-timepicker--fullwidth`,this.fullwidth),this.classList.toggle(`pkt-timepicker--medium`,this.inputSize===`medium`),this.classList.toggle(`pkt-timepicker--small`,this.inputSize===`small`),this.classList.toggle(`pkt-timepicker--xsmall`,this.inputSize===`xsmall`),e.has(`step`)&&this.step!==null&&!this._isValidStep(this.step)&&console.warn(`pkt-timepicker: step="${this.step}" er ikke en gyldig verdi. Step må være et multiplum av 60 (hele minutter) eller nøyaktig 3600 (hel time).`)}formResetCallback(){super.formResetCallback(),this._hours=``,this._minutes=``,this._isOpen=!1}_isValidStep(e){return e===3600||e<3600&&3600%e==0&&e%60==0}_syncDisplayFromValue(){let e=c(this.value)?this.value.split(`:`):null;e?(this._hours=e[0],this._minutes=e[1]):(this._hours=``,this._minutes=``)}_syncValueFromDisplay(){if(this._hours!==``&&this._minutes!==``){let e=`${this._hours}:${this._minutes}`;e!==this.value&&(this.value=e,this.onChange(e))}else this.value!==``&&(this.value=``,this.onChange(``))}get _minuteStep(){return u(this.step)}get _hourOptions(){return d(this.min,this.max)}get _minuteOptions(){return f(this.step)}_openPopup(){this._isOpen=!0,this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)})}_closePopup(){this._isOpen=!1,this._syncValueFromDisplay()}_togglePopup(){this._isOpen?this._closePopup():this._openPopup()}_scrollToSelected(){let e=this.querySelector(`.pkt-timepicker-popup`);e&&e.querySelectorAll(`.pkt-timepicker-popup__col`).forEach(e=>{let t=e.querySelector(`.pkt-timepicker-popup__option--selected`);t&&t.scrollIntoView({block:`center`})})}_focusSelectedOrFirst(e){let t=this.querySelector(`.pkt-timepicker-popup`);if(!t)return;let n=t.querySelectorAll(`.pkt-timepicker-popup__col`),r=e===`hour`?n[0]:n[1];if(!r)return;let i=r.querySelector(`.pkt-timepicker-popup__option--selected`),a=r.querySelector(`.pkt-timepicker-popup__option`);(i||a)?.focus()}_handleOptionClick(e,t){let n=String(e).padStart(2,`0`);t===`hour`?(this._hours=n,this.updateComplete.then(()=>this._focusSelectedOrFirst(`minute`))):(this._minutes=n,this._closePopup(),this.buttonRef.value?.focus())}_focusOptionAndSync(e,t){if(!e)return;let n=parseInt(e.dataset.value??`0`,10);t===`hour`?this._hours=String(n).padStart(2,`0`):this._minutes=String(n).padStart(2,`0`),e.focus()}_stepTime(e){let t=p(this._hours,this._minutes,e,this._minuteStep);this._hours=t.hours,this._minutes=t.minutes,this._syncValueFromDisplay()}_renderOption(n,r){let i=String(n).padStart(2,`0`),a=n===(r===`hour`?this._hours===``?NaN:parseInt(this._hours,10):this._minutes===``?NaN:parseInt(this._minutes,10));return e._`
|
|
1
|
+
const e=require("./element-BOmr9YLv.cjs"),t=require("./class-map-Drv0_anQ.cjs"),n=require("./format-B8meU8Tm.cjs"),r=require("./element-with-slot-D7sTqOr3.cjs");require("./icon-Dnv6LtPC.cjs");const i=require("./if-defined-2mkIDgOm.cjs"),a=require("./ref-Emu5PNxk.cjs"),o=require("./input-element-CSfDGslx.cjs"),s=require("./input-wrapper-CTMf4kCK.cjs");var c=e=>/^\d{2}:\d{2}$/.test(e)&&parseInt(e.slice(0,2),10)<=23&&parseInt(e.slice(3),10)<=59,l=e=>{let[t,n]=e.split(`:`).map(Number);return t*60+n},u=e=>e?Math.max(1,Math.round(e/60)):1,d=(e,t)=>{let n=e?parseInt(String(e).split(`:`)[0],10):0,r=t?parseInt(String(t).split(`:`)[0],10):23;return Array.from({length:r-n+1},(e,t)=>t+n)},f=e=>{let t=u(e);return Array.from({length:Math.floor(60/t)},(e,n)=>n*t)},p=(e,t,n,r)=>{let i=e===``?n===1?0:23:parseInt(e,10),a=t===``?n===1?0:Math.floor(59/r)*r:parseInt(t,10);return a+=n*r,a>59?(a=0,i=(i+1)%24):a<0&&(a=Math.floor(59/r)*r,i=(i-1+24)%24),{hours:String(i).padStart(2,`0`),minutes:String(a).padStart(2,`0`)}},m=class extends o.t{constructor(...e){super(...e),this.hiddenInputRef=a.t(),this.hoursInputRef=a.t(),this.minutesInputRef=a.t(),this.buttonRef=a.t(),this.value=``,this.hidePicker=!1,this.stepArrows=!1,this._hours=``,this._minutes=``,this._isOpen=!1,this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._hasFocus=!1,this._outsideClickHandler=e=>{this.contains(e.target)||this._closePopup()},this._handleComponentFocusIn=()=>{this._hasFocus||(this._hasFocus=!0,this.onFocus())},this._handleComponentFocusOut=e=>{this.contains(e.relatedTarget)||(this._hasFocus=!1,this.onBlur())},this._handleHoursKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t+1)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._hours===``?0:parseInt(this._hours,10);this._hours=String((t-1+24)%24).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowRight`:e.preventDefault(),this.minutesInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._hoursDigitCount=0,this._hoursFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._hoursDigitCount===0)this._hoursFirstDigit=t,this._hours=String(t).padStart(2,`0`),this._hoursDigitCount=1,this.onInput(),t>=3&&(this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.minutesInputRef.value?.focus());else{let e=this._hoursFirstDigit*10+t;this._hours=e<=23?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._hoursFirstDigit=-1,this._hoursDigitCount=0,this._syncValueFromDisplay(),this.onInput(),this.minutesInputRef.value?.focus()}}else e.preventDefault()}},this._handleHoursBlur=()=>{this._hours!==``&&(this._hours=String(parseInt(this._hours,10)).padStart(2,`0`)),this._hoursDigitCount=0,this._hoursFirstDigit=-1,this._syncValueFromDisplay()},this._handleMinutesKeydown=e=>{let t=e.target;switch(e.key){case`ArrowUp`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t+this._minuteStep)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowDown`:{e.preventDefault();let t=this._minutes===``?0:parseInt(this._minutes,10);this._minutes=String((t-this._minuteStep+60)%60).padStart(2,`0`),this._syncValueFromDisplay(),this.onInput();break}case`ArrowLeft`:e.preventDefault(),this.hoursInputRef.value?.focus();break;case`Backspace`:case`Delete`:this._minutesDigitCount=0,this._minutesFirstDigit=-1;break;case`Tab`:break;case`Enter`:{e.preventDefault();let n=this.internals.form;n?n.requestSubmit():t.blur();break}default:if(/^\d$/.test(e.key)){e.preventDefault();let t=parseInt(e.key,10);if(this._minutesDigitCount===0)this._minutesFirstDigit=t,this._minutes=String(t).padStart(2,`0`),this._minutesDigitCount=1,this.onInput(),t>=6&&(this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay());else{let e=this._minutesFirstDigit*10+t;this._minutes=e<=59?String(e).padStart(2,`0`):String(t).padStart(2,`0`),this._minutesFirstDigit=-1,this._minutesDigitCount=0,this._syncValueFromDisplay(),this.onInput()}}else e.preventDefault()}},this._handleMinutesBlur=()=>{this._minutes!==``&&(this._minutes=String(parseInt(this._minutes,10)).padStart(2,`0`)),this._minutesDigitCount=0,this._minutesFirstDigit=-1,this._syncValueFromDisplay()},this._handlePopupKeydown=e=>{let t=document.activeElement,n=t.closest(`.pkt-timepicker-popup__col`);if(!n)return;let r=Array.from(n.querySelectorAll(`.pkt-timepicker-popup__option`)),i=r.indexOf(t),a=t.dataset.type??``;switch(e.key){case`ArrowDown`:e.preventDefault(),this._focusOptionAndSync(r[Math.min(i+1,r.length-1)],a);break;case`ArrowUp`:e.preventDefault(),this._focusOptionAndSync(r[Math.max(i-1,0)],a);break;case`Home`:e.preventDefault(),this._focusOptionAndSync(r[0],a);break;case`End`:e.preventDefault(),this._focusOptionAndSync(r[r.length-1],a);break;case`ArrowRight`:e.preventDefault(),a===`hour`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`minute`)}));break;case`ArrowLeft`:e.preventDefault(),a===`minute`&&(this._focusOptionAndSync(t,a),this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)}));break;case`Enter`:case` `:e.preventDefault(),t.click();break;case`Escape`:e.preventDefault(),this._closePopup(),this.buttonRef.value?.focus()}}}get inputRef(){return this.hiddenInputRef}manageValidity(e){let t=this.hoursInputRef.value;if(!t)return;let r=this.pktStrings.get(`validation`);if(this.required&&!this.value){this.internals.setValidity({valueMissing:!0},r.valueMissing,t),this._setAriaInvalid(!0);return}if(!this.value){this.internals.setValidity({}),this._setAriaInvalid(!1);return}let i=l(this.value),a=u(this.step);if(this.min&&i<l(String(this.min))){this.internals.setValidity({rangeUnderflow:!0},n.t(r.rangeUnderflowMin,{min:String(this.min)}),t),this._setAriaInvalid(!0);return}if(this.max&&i>l(String(this.max))){this.internals.setValidity({rangeOverflow:!0},n.t(r.rangeOverflowMax,{max:String(this.max)}),t),this._setAriaInvalid(!0);return}if(this.step&&i%a!==0){let e=a===60?r.timeStepMismatchHour:a===30?r.timeStepMismatchHalfHour:n.t(r.timeStepMismatch,{step:`${a}, ${a*2}, ${a*3}`});this.internals.setValidity({stepMismatch:!0},e,t),this._setAriaInvalid(!0);return}this.internals.setValidity({}),this._setAriaInvalid(!1)}_describedBy(){return s.r({id:`${this.id}-hours`,hasHelptext:!!this.helptext||this.hasSlotContent(`helptext`),ariaDescribedby:this.ariaDescribedby})}_setAriaInvalid(e){if(!this.touched&&e)return;let t=this.hoursInputRef.value,n=this.minutesInputRef.value;if(e)t?.setAttribute(`aria-invalid`,`true`),n?.setAttribute(`aria-invalid`,`true`);else{if(this.hasError)return;t?.removeAttribute(`aria-invalid`),n?.removeAttribute(`aria-invalid`)}}connectedCallback(){super.connectedCallback(),this.addEventListener(`focusin`,this._handleComponentFocusIn),this.addEventListener(`focusout`,this._handleComponentFocusOut),document.addEventListener(`click`,this._outsideClickHandler)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(`focusin`,this._handleComponentFocusIn),this.removeEventListener(`focusout`,this._handleComponentFocusOut),document.removeEventListener(`click`,this._outsideClickHandler)}willUpdate(e){super.willUpdate(e),e.has(`value`)&&this._syncDisplayFromValue()}updated(e){super.updated(e),this.classList.add(`pkt-timepicker`),this.classList.toggle(`pkt-timepicker--stepper`,this.stepArrows),this.classList.toggle(`pkt-timepicker--fullwidth`,this.fullwidth),this.classList.toggle(`pkt-timepicker--medium`,this.inputSize===`medium`),this.classList.toggle(`pkt-timepicker--small`,this.inputSize===`small`),this.classList.toggle(`pkt-timepicker--xsmall`,this.inputSize===`xsmall`),e.has(`step`)&&this.step!==null&&!this._isValidStep(this.step)&&console.warn(`pkt-timepicker: step="${this.step}" er ikke en gyldig verdi. Step må være et multiplum av 60 (hele minutter) eller nøyaktig 3600 (hel time).`)}formResetCallback(){super.formResetCallback(),this._hours=``,this._minutes=``,this._isOpen=!1}_isValidStep(e){return e===3600||e<3600&&3600%e==0&&e%60==0}_syncDisplayFromValue(){let e=c(this.value)?this.value.split(`:`):null;e?(this._hours=e[0],this._minutes=e[1]):(this._hours=``,this._minutes=``)}_syncValueFromDisplay(){if(this._hours!==``&&this._minutes!==``){let e=`${this._hours}:${this._minutes}`;e!==this.value&&(this.value=e,this.onChange(e))}else this.value!==``&&(this.value=``,this.onChange(``))}get _minuteStep(){return u(this.step)}get _hourOptions(){return d(this.min,this.max)}get _minuteOptions(){return f(this.step)}_openPopup(){this._isOpen=!0,this.updateComplete.then(()=>{this._scrollToSelected(),this._focusSelectedOrFirst(`hour`)})}_closePopup(){this._isOpen=!1,this._syncValueFromDisplay()}_togglePopup(){this._isOpen?this._closePopup():this._openPopup()}_scrollToSelected(){let e=this.querySelector(`.pkt-timepicker-popup`);e&&e.querySelectorAll(`.pkt-timepicker-popup__col`).forEach(e=>{let t=e.querySelector(`.pkt-timepicker-popup__option--selected`);t&&t.scrollIntoView({block:`center`})})}_focusSelectedOrFirst(e){let t=this.querySelector(`.pkt-timepicker-popup`);if(!t)return;let n=t.querySelectorAll(`.pkt-timepicker-popup__col`),r=e===`hour`?n[0]:n[1];if(!r)return;let i=r.querySelector(`.pkt-timepicker-popup__option--selected`),a=r.querySelector(`.pkt-timepicker-popup__option`);(i||a)?.focus()}_handleOptionClick(e,t){let n=String(e).padStart(2,`0`);t===`hour`?(this._hours=n,this.updateComplete.then(()=>this._focusSelectedOrFirst(`minute`))):(this._minutes=n,this._closePopup(),this.buttonRef.value?.focus())}_focusOptionAndSync(e,t){if(!e)return;let n=parseInt(e.dataset.value??`0`,10);t===`hour`?this._hours=String(n).padStart(2,`0`):this._minutes=String(n).padStart(2,`0`),e.focus()}_stepTime(e){let t=p(this._hours,this._minutes,e,this._minuteStep);this._hours=t.hours,this._minutes=t.minutes,this._syncValueFromDisplay()}_renderOption(n,r){let i=String(n).padStart(2,`0`),a=n===(r===`hour`?this._hours===``?NaN:parseInt(this._hours,10):this._minutes===``?NaN:parseInt(this._minutes,10));return e._`
|
|
2
2
|
<button
|
|
3
3
|
class=${t.t({"pkt-btn":!0,"pkt-btn--tertiary":!0,"pkt-btn--small":!0,"pkt-btn--label-only":!0,"pkt-timepicker-popup__option":!0,"pkt-timepicker-popup__option--selected":a})}
|
|
4
4
|
type="button"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oslokommune/punkt-elements",
|
|
3
|
-
"version": "19.
|
|
3
|
+
"version": "19.8.0",
|
|
4
4
|
"description": "Komponentbiblioteket til Punkt, designsystem for Oslo kommune",
|
|
5
5
|
"homepage": "https://punkt.oslo.kommune.no",
|
|
6
6
|
"author": "Team Designsystem, Oslo kommune",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"engines": {
|
|
85
85
|
"node": "^22.19.0 || ^24.0.0 || ^26.0.0"
|
|
86
86
|
},
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "aac1152f60412d31e67493d4813afebe5dcea8bb"
|
|
88
88
|
}
|
|
@@ -149,7 +149,7 @@ export class PktAlert extends PktElementWithSlot<IPktAlert> implements IPktAlert
|
|
|
149
149
|
this.dispatchEvent(
|
|
150
150
|
new CustomEvent('close', { detail: { origin: event }, bubbles: true, composed: true }),
|
|
151
151
|
)
|
|
152
|
-
//
|
|
152
|
+
// Deprecated: beholdt for eldre Vue-oppsett. Bruk `close`, `on-close` fjernes i en senere hovedversjon.
|
|
153
153
|
this.dispatchEvent(
|
|
154
154
|
new CustomEvent('on-close', { detail: { origin: event }, bubbles: true, composed: true }),
|
|
155
155
|
)
|
|
@@ -3,9 +3,13 @@ import { Ref, createRef } from 'lit/directives/ref.js'
|
|
|
3
3
|
import { PktInputElement } from '@/base-elements/input-element'
|
|
4
4
|
import { PktOptionsSlotController } from '@/controllers/pkt-options-controller'
|
|
5
5
|
import { isMaxSelectionReached } from 'shared-utils/combobox/option-utils'
|
|
6
|
-
import
|
|
6
|
+
import { COMBOBOX_DEFAULTS } from 'shared-types/combobox'
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
IPktComboboxOption,
|
|
10
|
+
TPktComboboxDisplayValue,
|
|
11
|
+
TPktComboboxTagPlacement,
|
|
12
|
+
} from './combobox-types'
|
|
9
13
|
import type { IPktStringsProps } from 'shared-strings'
|
|
10
14
|
import PktListbox from '../listbox'
|
|
11
15
|
import type { TComboboxMessageKey } from 'shared-utils/combobox'
|
|
@@ -24,15 +28,17 @@ export class ComboboxBase extends PktInputElement<IPktStringsProps<'combobox' |
|
|
|
24
28
|
@property({ type: String, reflect: true }) value: string | string[] = ''
|
|
25
29
|
@property({ type: Array }) options: IPktComboboxOption[] = []
|
|
26
30
|
@property({ type: Array, attribute: 'default-options' }) defaultOptions: IPktComboboxOption[] = []
|
|
27
|
-
@property({ type: Boolean, attribute: 'allow-user-input' }) allowUserInput: boolean =
|
|
28
|
-
|
|
29
|
-
@property({ type: Boolean
|
|
31
|
+
@property({ type: Boolean, attribute: 'allow-user-input' }) allowUserInput: boolean =
|
|
32
|
+
COMBOBOX_DEFAULTS.allowUserInput
|
|
33
|
+
@property({ type: Boolean }) typeahead: boolean = COMBOBOX_DEFAULTS.typeahead
|
|
34
|
+
@property({ type: Boolean, attribute: 'include-search' }) includeSearch: boolean =
|
|
35
|
+
COMBOBOX_DEFAULTS.includeSearch
|
|
30
36
|
@property({ type: String, attribute: 'search-placeholder' }) searchPlaceholder: string | null =
|
|
31
37
|
null
|
|
32
|
-
@property({ type: Boolean }) multiple: boolean =
|
|
38
|
+
@property({ type: Boolean }) multiple: boolean = COMBOBOX_DEFAULTS.multiple
|
|
33
39
|
@property({ type: Number }) maxlength: number | null = null
|
|
34
|
-
@property({ type: String, attribute: 'display-value-as' })
|
|
35
|
-
|
|
40
|
+
@property({ type: String, attribute: 'display-value-as' })
|
|
41
|
+
displayValueAs: TPktComboboxDisplayValue = COMBOBOX_DEFAULTS.displayValueAs
|
|
36
42
|
@property({ type: String, attribute: 'tag-placement' })
|
|
37
43
|
tagPlacement: TPktComboboxTagPlacement | null = null
|
|
38
44
|
// Internal use only — syncs to _isOptionsOpen in willUpdate(), but does not
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IPktComboboxOption
|
|
1
|
+
import type { IPktComboboxOption } from './combobox-types'
|
|
2
2
|
import {
|
|
3
3
|
findOptionByValue,
|
|
4
4
|
getOptionDisplayText,
|
|
@@ -87,7 +87,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
87
87
|
? getSingleValueForInput(valueFromOptions || '', this.options, this.displayValueAs)
|
|
88
88
|
: getOptionDisplayText(
|
|
89
89
|
findOptionByValue(this.options, valueFromOptions),
|
|
90
|
-
this.displayValueAs
|
|
90
|
+
this.displayValueAs,
|
|
91
91
|
)
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '@testing-library/jest-dom'
|
|
2
2
|
|
|
3
|
-
import spec from 'componentSpecs/combobox.
|
|
3
|
+
import spec from 'componentSpecs/combobox.spec'
|
|
4
4
|
import './combobox'
|
|
5
5
|
import { PktCombobox } from './combobox'
|
|
6
6
|
|
|
@@ -18,6 +18,7 @@ const cases: { attribute: string; property: keyof PktCombobox; set: string; expe
|
|
|
18
18
|
{ attribute: 'display-value-as', property: 'displayValueAs', set: 'value', expect: 'value' },
|
|
19
19
|
{ attribute: 'search-placeholder', property: 'searchPlaceholder', set: 'x', expect: 'x' },
|
|
20
20
|
{ attribute: 'tag-placement', property: 'tagPlacement', set: 'outside', expect: 'outside' },
|
|
21
|
+
{ attribute: 'aria-describedby', property: 'ariaDescribedby', set: 'x', expect: 'x' },
|
|
21
22
|
{ attribute: 'defaultvalue', property: 'defaultValue', set: 'x', expect: 'x' },
|
|
22
23
|
{ attribute: 'errormessage', property: 'errorMessage', set: 'x', expect: 'x' },
|
|
23
24
|
{ attribute: 'helptextdropdown', property: 'helptextDropdown', set: 'x', expect: 'x' },
|
|
@@ -71,7 +72,7 @@ describe('PktCombobox attributes', () => {
|
|
|
71
72
|
})
|
|
72
73
|
|
|
73
74
|
test('every renamed attribute in the component spec is declared', () => {
|
|
74
|
-
const renamed = Object.entries(spec.props)
|
|
75
|
+
const renamed = Object.entries(spec.props ?? {})
|
|
75
76
|
.filter(([name, prop]) => 'attribute' in prop && prop.attribute !== name)
|
|
76
77
|
.map(([, prop]) => (prop as { attribute: string }).attribute)
|
|
77
78
|
// input-size and data-testid come from the shared input wrapper, not combobox
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
TPktComboboxTagPlacement,
|
|
11
11
|
TPktComboboxDisplayValue,
|
|
12
12
|
} from './combobox-types'
|
|
13
|
+
import type { IPktComboboxBase } from 'shared-types/combobox'
|
|
13
14
|
import { findOptionByValue, findOptionIndex } from 'shared-utils/combobox/option-utils'
|
|
14
15
|
import { getSingleValueForInput } from 'shared-utils/combobox/input-utils'
|
|
15
16
|
import { slotUtils, optionStateUtils } from './combobox-utils'
|
|
@@ -29,37 +30,36 @@ import '../listbox'
|
|
|
29
30
|
// Re-export types for backward compatibility
|
|
30
31
|
export type { IPktComboboxOption, TPktComboboxTagPlacement } from './combobox-types'
|
|
31
32
|
|
|
32
|
-
export interface IPktCombobox
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
export interface IPktCombobox
|
|
34
|
+
extends
|
|
35
|
+
Omit<
|
|
36
|
+
IPktComboboxBase,
|
|
37
|
+
| 'form'
|
|
38
|
+
| 'ariaDescribedby'
|
|
39
|
+
| 'label'
|
|
40
|
+
| 'helptext'
|
|
41
|
+
| 'helptextDropdown'
|
|
42
|
+
| 'helptextDropdownButton'
|
|
43
|
+
| 'placeholder'
|
|
44
|
+
| 'searchPlaceholder'
|
|
45
|
+
| 'maxlength'
|
|
46
|
+
| 'tagPlacement'
|
|
47
|
+
| 'defaultValue'
|
|
48
|
+
| 'useWrapper'
|
|
49
|
+
>,
|
|
50
|
+
IPktStringsProps<'combobox' | 'listbox'> {
|
|
51
|
+
ariaDescribedby?: string | null
|
|
52
|
+
label?: string | null
|
|
40
53
|
helptext?: string | null
|
|
41
54
|
helptextDropdown?: string | null
|
|
55
|
+
/** @deprecated Bruk `strings={{ forms: { readMore: '…' } }}` eller `setPktStrings()`. */
|
|
42
56
|
helptextDropdownButton?: string | null
|
|
43
|
-
id?: string
|
|
44
|
-
includeSearch?: boolean
|
|
45
|
-
label?: string | null
|
|
46
|
-
maxlength?: number | null
|
|
47
|
-
minlength?: number | null
|
|
48
|
-
multiple?: boolean
|
|
49
|
-
name?: string
|
|
50
|
-
optionalTag?: boolean
|
|
51
|
-
optionalText?: string
|
|
52
|
-
options?: IPktComboboxOption[]
|
|
53
|
-
defaultOptions?: IPktComboboxOption[]
|
|
54
57
|
placeholder?: string | null
|
|
55
|
-
requiredTag?: boolean
|
|
56
|
-
requiredText?: string
|
|
57
58
|
searchPlaceholder?: string | null
|
|
59
|
+
maxlength?: number | null
|
|
60
|
+
minlength?: number | null
|
|
58
61
|
tagPlacement?: TPktComboboxTagPlacement | null
|
|
59
|
-
tagText?: string | null
|
|
60
|
-
value?: string | string[]
|
|
61
62
|
defaultValue?: string | string[] | null
|
|
62
|
-
hasFieldset?: boolean | null
|
|
63
63
|
useWrapper?: Booleanish
|
|
64
64
|
isOpen?: boolean
|
|
65
65
|
}
|
|
@@ -72,7 +72,7 @@ export interface IPktCombobox extends IPktStringsProps<'combobox' | 'listbox'> {
|
|
|
72
72
|
export interface IPktComboboxAttributes {
|
|
73
73
|
'allow-user-input'?: boolean
|
|
74
74
|
'default-options'?: IPktComboboxOption[]
|
|
75
|
-
'display-value-as'?:
|
|
75
|
+
'display-value-as'?: TPktComboboxDisplayValue
|
|
76
76
|
'include-search'?: boolean
|
|
77
77
|
'search-placeholder'?: string | null
|
|
78
78
|
'tag-placement'?: TPktComboboxTagPlacement | null
|
|
@@ -574,7 +574,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
|
|
|
574
574
|
|
|
575
575
|
private renderValueTag(option: IPktComboboxOption | null) {
|
|
576
576
|
if (!option) return ''
|
|
577
|
-
const displayAs = this.displayValueAs
|
|
577
|
+
const displayAs = this.displayValueAs
|
|
578
578
|
switch (displayAs) {
|
|
579
579
|
case 'prefixAndValue':
|
|
580
580
|
return html`<span class="pkt-combobox__value">${option.prefix || ''} ${option.value}</span>`
|
|
@@ -52,6 +52,7 @@ export class PktInputWrapper extends PktElementWithSlot<Props> {
|
|
|
52
52
|
@property({ type: String }) label: string = ''
|
|
53
53
|
@property({ type: String }) helptext: string | null = null
|
|
54
54
|
@property({ type: String }) helptextDropdown: string | null = null
|
|
55
|
+
/** @deprecated Bruk `strings={{ forms: { readMore: '…' } }}` eller `setPktStrings()`. */
|
|
55
56
|
@property({ type: String }) helptextDropdownButton: string | null = null
|
|
56
57
|
@property({ type: Boolean }) counter: boolean = specs.props.counter.default
|
|
57
58
|
@property({ type: Number }) counterCurrent: number = 0
|
|
@@ -72,7 +72,7 @@ describe('PktMessagebox', () => {
|
|
|
72
72
|
expect(messagebox.closable).toBe(false)
|
|
73
73
|
expect(messagebox.compact).toBe(false)
|
|
74
74
|
expect(messagebox.title).toBe('')
|
|
75
|
-
expect(messagebox.skin).
|
|
75
|
+
expect(messagebox.skin).toBe('beige')
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
test('sets properties correctly', async () => {
|
|
@@ -3,20 +3,14 @@ import { slotContent } from '@/directives/slot-content'
|
|
|
3
3
|
import { html, nothing, PropertyValues } from 'lit'
|
|
4
4
|
import { classMap } from 'lit/directives/class-map.js'
|
|
5
5
|
import { customElement, property, state } from 'lit/decorators.js'
|
|
6
|
-
import specs from 'componentSpecs/messagebox.json'
|
|
7
6
|
|
|
8
7
|
import '@/components/icon'
|
|
9
8
|
import { updateClassAttribute } from '@/utils/classutils'
|
|
10
|
-
import type
|
|
9
|
+
import { MESSAGEBOX_DEFAULTS, type IPktMessageboxBase, type TMessageboxSkin } from 'shared-types'
|
|
11
10
|
|
|
12
11
|
export type { TMessageboxSkin }
|
|
13
12
|
|
|
14
|
-
export interface IPktMessagebox {
|
|
15
|
-
skin?: TMessageboxSkin
|
|
16
|
-
title?: string
|
|
17
|
-
compact?: boolean
|
|
18
|
-
closable?: boolean
|
|
19
|
-
}
|
|
13
|
+
export interface IPktMessagebox extends IPktMessageboxBase {}
|
|
20
14
|
|
|
21
15
|
export class PktMessagebox extends PktElementWithSlot implements IPktMessagebox {
|
|
22
16
|
constructor() {
|
|
@@ -26,10 +20,10 @@ export class PktMessagebox extends PktElementWithSlot implements IPktMessagebox
|
|
|
26
20
|
|
|
27
21
|
// Properties
|
|
28
22
|
|
|
29
|
-
@property({ type: Boolean, reflect: true }) closable =
|
|
30
|
-
@property({ type: Boolean, reflect: true }) compact =
|
|
23
|
+
@property({ type: Boolean, reflect: true }) closable: boolean = MESSAGEBOX_DEFAULTS.closable
|
|
24
|
+
@property({ type: Boolean, reflect: true }) compact: boolean = MESSAGEBOX_DEFAULTS.compact
|
|
31
25
|
@property({ type: String, reflect: true }) title = ''
|
|
32
|
-
@property({ type: String, reflect: true }) skin?: TMessageboxSkin =
|
|
26
|
+
@property({ type: String, reflect: true }) skin?: TMessageboxSkin = MESSAGEBOX_DEFAULTS.skin
|
|
33
27
|
|
|
34
28
|
@state() _isClosed: boolean = false
|
|
35
29
|
|
|
@@ -75,7 +69,7 @@ export class PktMessagebox extends PktElementWithSlot implements IPktMessagebox
|
|
|
75
69
|
private close = (event: MouseEvent) => {
|
|
76
70
|
this._isClosed = true
|
|
77
71
|
this.dispatchEvent(new CustomEvent('close', { detail: { origin: event }, bubbles: true }))
|
|
78
|
-
//
|
|
72
|
+
// Deprecated: beholdt for eldre Vue-oppsett. Bruk `close`, `on-close` fjernes i en senere hovedversjon.
|
|
79
73
|
this.dispatchEvent(new CustomEvent('on-close', { detail: { origin: event }, bubbles: true }))
|
|
80
74
|
}
|
|
81
75
|
}
|