@fremtind/jokul 4.5.0 → 4.6.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.
Files changed (89) hide show
  1. package/build/build-stats.html +1 -1
  2. package/build/cjs/components/datepicker/DatePicker.cjs +1 -1
  3. package/build/cjs/components/datepicker/DatePicker.cjs.map +1 -1
  4. package/build/cjs/components/icon/Icon.cjs +1 -1
  5. package/build/cjs/components/icon/Icon.cjs.map +1 -1
  6. package/build/cjs/components/icon/Icon.d.cts +2 -2
  7. package/build/cjs/components/icon/icons/GreenCheckIcon.cjs +1 -1
  8. package/build/cjs/components/icon/icons/GreenCheckIcon.cjs.map +1 -1
  9. package/build/cjs/components/icon/icons/GreenCheckIcon.d.cts +2 -3
  10. package/build/cjs/components/icon/icons/RedCrossIcon.cjs +1 -1
  11. package/build/cjs/components/icon/icons/RedCrossIcon.cjs.map +1 -1
  12. package/build/cjs/components/icon/icons/RedCrossIcon.d.cts +2 -3
  13. package/build/cjs/components/number-input/NumberInput.cjs +2 -0
  14. package/build/cjs/components/number-input/NumberInput.cjs.map +1 -0
  15. package/build/cjs/components/number-input/NumberInput.d.cts +7 -0
  16. package/build/cjs/components/number-input/index.cjs +2 -0
  17. package/build/cjs/components/number-input/index.cjs.map +1 -0
  18. package/build/cjs/components/number-input/index.d.cts +2 -0
  19. package/build/cjs/components/number-input/types.cjs +2 -0
  20. package/build/cjs/components/number-input/types.cjs.map +1 -0
  21. package/build/cjs/components/number-input/types.d.cts +20 -0
  22. package/build/cjs/components/text-area/BaseTextArea.cjs +1 -1
  23. package/build/cjs/components/text-area/BaseTextArea.cjs.map +1 -1
  24. package/build/cjs/components/text-area/counter.cjs +2 -0
  25. package/build/cjs/components/text-area/counter.cjs.map +1 -0
  26. package/build/cjs/components/text-area/counter.d.cts +2 -0
  27. package/build/cjs/components/text-area/types.d.cts +21 -1
  28. package/build/es/components/datepicker/DatePicker.js +1 -1
  29. package/build/es/components/datepicker/DatePicker.js.map +1 -1
  30. package/build/es/components/icon/Icon.d.ts +2 -2
  31. package/build/es/components/icon/Icon.js +1 -1
  32. package/build/es/components/icon/Icon.js.map +1 -1
  33. package/build/es/components/icon/icons/GreenCheckIcon.d.ts +2 -3
  34. package/build/es/components/icon/icons/GreenCheckIcon.js +1 -1
  35. package/build/es/components/icon/icons/GreenCheckIcon.js.map +1 -1
  36. package/build/es/components/icon/icons/RedCrossIcon.d.ts +2 -3
  37. package/build/es/components/icon/icons/RedCrossIcon.js +1 -1
  38. package/build/es/components/icon/icons/RedCrossIcon.js.map +1 -1
  39. package/build/es/components/number-input/NumberInput.d.ts +7 -0
  40. package/build/es/components/number-input/NumberInput.js +2 -0
  41. package/build/es/components/number-input/NumberInput.js.map +1 -0
  42. package/build/es/components/number-input/index.d.ts +2 -0
  43. package/build/es/components/number-input/index.js +2 -0
  44. package/build/es/components/number-input/index.js.map +1 -0
  45. package/build/es/components/number-input/types.d.ts +20 -0
  46. package/build/es/components/number-input/types.js +2 -0
  47. package/build/es/components/number-input/types.js.map +1 -0
  48. package/build/es/components/text-area/BaseTextArea.js +1 -1
  49. package/build/es/components/text-area/BaseTextArea.js.map +1 -1
  50. package/build/es/components/text-area/counter.d.ts +2 -0
  51. package/build/es/components/text-area/counter.js +2 -0
  52. package/build/es/components/text-area/counter.js.map +1 -0
  53. package/build/es/components/text-area/types.d.ts +21 -1
  54. package/package.json +13 -1
  55. package/styles/components/countdown/countdown.css +2 -2
  56. package/styles/components/countdown/countdown.min.css +1 -1
  57. package/styles/components/feedback/feedback.css +2 -2
  58. package/styles/components/feedback/feedback.min.css +1 -1
  59. package/styles/components/file-input/file-input.css +9 -9
  60. package/styles/components/file-input/file-input.min.css +1 -1
  61. package/styles/components/icon/icon.css +28 -14
  62. package/styles/components/icon/icon.min.css +1 -1
  63. package/styles/components/icon/icon.scss +26 -20
  64. package/styles/components/input-group/input-group.css +2 -2
  65. package/styles/components/input-group/input-group.min.css +1 -1
  66. package/styles/components/list/list.css +34 -40
  67. package/styles/components/list/list.min.css +1 -1
  68. package/styles/components/list/list.scss +23 -25
  69. package/styles/components/loader/loader.css +6 -6
  70. package/styles/components/loader/loader.min.css +1 -1
  71. package/styles/components/loader/skeleton-loader.css +3 -3
  72. package/styles/components/loader/skeleton-loader.min.css +1 -1
  73. package/styles/components/message/message.css +2 -2
  74. package/styles/components/message/message.min.css +1 -1
  75. package/styles/components/number-input/_index.scss +2 -0
  76. package/styles/components/number-input/number-input.css +222 -0
  77. package/styles/components/number-input/number-input.min.css +1 -0
  78. package/styles/components/number-input/number-input.scss +121 -0
  79. package/styles/components/progress-bar/progress-bar.css +1 -1
  80. package/styles/components/progress-bar/progress-bar.min.css +1 -1
  81. package/styles/components/segmented-control/segmented-control.css +30 -16
  82. package/styles/components/segmented-control/segmented-control.min.css +1 -1
  83. package/styles/components/system-message/system-message.css +2 -2
  84. package/styles/components/system-message/system-message.min.css +1 -1
  85. package/styles/components/toast/toast.css +4 -4
  86. package/styles/components/toast/toast.min.css +1 -1
  87. package/styles/styles.css +305 -78
  88. package/styles/styles.min.css +1 -1
  89. package/styles/styles.scss +1 -0
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("../../../clsx-E3yX_9sL.cjs"),r=require("../../../utils-DxmZDrR9.cjs"),a=require("react"),n=require("react-dom"),l=require("../../utilities/formatters/date/formatDate.cjs"),o=require("../icon-button/IconButton.cjs"),u=require("../icon/icons/CalendarIcon.cjs"),s=require("../input-group/InputGroup.cjs"),i=require("../popover/Popover.cjs"),c=require("../text-input/BaseTextInput.cjs"),d=require("./internal/Calendar.cjs"),p=require("./utils.cjs"),v=require("./validation.cjs"),f=a.forwardRef((f,D)=>{const{"data-testautoid":b,id:m,className:g="",label:j="Velg dato",labelProps:k,defaultValue:h,defaultShow:y=!1,value:x,disableBeforeDate:C,disableAfterDate:S,yearsToShow:L,name:P,helpLabel:q,errorLabel:w,invalid:I,days:O,months:T,monthLabel:B,yearLabel:E,placeholder:_="dd.mm.åååå",width:N="11.25rem",onChange:R,onBlur:U,onFocus:V,onKeyDown:F,action:K,showCalendarLabel:M="Åpne kalender",hideCalendarLabel:W="Lukk kalender",supportLabelProps:A,tooltip:G,textInputProps:H,description:$,...z}=f;"production"!==process.env.NODE_ENV&&x&&h&&console.warn("DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.");const J=p.parseDateString(C),Q=J?r.dayjs(J).startOf("day").toDate():void 0,X=p.parseDateString(S),Y=X?r.dayjs(X).startOf("day").toDate():void 0,[Z,ee]=a.useState(r.getInitialDate(x,h,Q,Y)),[te,re]=a.useState(null),[ae,ne]=a.useState(y),le=a.useRef(null),oe=a.useRef(null),ue=a.useRef(null),se=a.useRef(null),ie=a.useCallback(e=>{se.current=e,D&&("function"==typeof D?D(e):D.current=e)},[D]),ce=a.useCallback(e=>{V&&oe.current&&(oe.current.contains(e.relatedTarget)||V(e,Z,{error:te,value:e.target.value}))},[V,Z,te]),de=a.useCallback(e=>{U&&U(e,Z,{error:te,value:e.target.value})},[U,Z,te]),pe=a.useCallback(e=>{"Escape"===e.key&&(ne(!1),e.preventDefault(),e.stopPropagation()),K?.onKeyDown&&K.onKeyDown(e)},[K]),ve=a.useCallback(e=>{const t=e.currentTarget.value,r=(e=>{const t=e.replace(/\D/g,""),r=l.formatDateString(t,{partial:!0}),a=e.replace(/\D+$/,""),n=8===t.length?l.formatDateString(t):e,o=p.parseDateString(n)?n:null,u=e!==t&&a===r&&void 0===p.parseDateString(e)&&null===o;return o??(u?t:e)})(t);r!==t&&((e,t)=>{const r=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set;r?r.call(e,t):e.value=t})(e.currentTarget,r);const{date:a,error:n}=(({value:e,minDate:t,maxDate:r})=>{if(!e)return{date:null,error:null};const a=p.parseDateString(e);return a?t&&!v.isWithinLowerBound(a,t)?{date:a,error:"OUTSIDE_LOWER_BOUND"}:r&&!v.isWithinUpperBound(a,r)?{date:a,error:"OUTSIDE_UPPER_BOUND"}:{date:a,error:null}:{date:null,error:"WRONG_FORMAT"}})({value:r,minDate:Q,maxDate:Y});a&&!n&&ne(!1),re(n),ee(a),R&&R(e,a,{error:n,value:r})},[R,Q,Y]),fe=a.useCallback(e=>{n.flushSync(()=>{ne(!ae)});const t=le.current,r=t&&t.querySelector('[aria-pressed="true"]');window.requestAnimationFrame(()=>r?.focus()),K?.onClick&&K.onClick(e)},[ae,K]),De=a.useCallback(({date:e})=>{if(ne(!1),ee(e),se.current){const t=se.current;t.value=p.formatInput(e);const r=document.createEvent("HTMLEvents");r.initEvent("input",!0,!1),t.dispatchEvent(r),t.focus(),R&&R(r,e,{error:null,value:t.value})}},[R]),be=a.useCallback(e=>{e.preventDefault(),ne(!1),ue.current?.focus()},[]);return e.jsx(s.InputGroup,{id:m,className:t.clsx("jkl-datepicker",g),...z,ref:oe,label:j,labelProps:k,helpLabel:q,errorLabel:w,supportLabelProps:A,tooltip:G,description:$,render:t=>e.jsx(c.BaseTextInput,{"data-focused":ae?"true":void 0,ref:ie,"data-testid":"jkl-datepicker__input","data-testautoid":b,className:"jkl-datepicker__input",name:P,defaultValue:h,value:x,type:"text",placeholder:_,width:N,onFocus:ce,onBlur:de,onChange:ve,actionButton:e.jsxs(i.Popover,{positionReference:se,open:ae,onOpenChange:()=>ne(!ae),offset:8,children:[e.jsx(i.Popover.Trigger,{...K,"data-testid":"jkl-datepicker__trigger",className:"jkl-text-input-action-button",title:ae?W:M,tabIndex:0,onClick:fe,onKeyDown:pe,asChild:!0,children:e.jsx(o.IconButton,{children:e.jsx(u.CalendarIcon,{})})}),e.jsx(i.Popover.Content,{initialFocus:-1,padding:24,children:e.jsx(d.Calendar,{ref:le,date:Z,minDate:Q,maxDate:Y,days:O,months:T,monthLabel:B,yearLabel:E,yearsToShow:L,onDateSelected:De,onTabOutside:be})})]}),...H,...t,"aria-invalid":I||!!w})})});f.displayName="DatePicker",exports.DatePicker=f;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("../../../clsx-E3yX_9sL.cjs"),r=require("../../../utils-DxmZDrR9.cjs"),a=require("react"),n=require("react-dom"),o=require("../../utilities/formatters/date/formatDate.cjs"),l=require("../icon-button/IconButton.cjs"),u=require("../icon/icons/CalendarIcon.cjs"),s=require("../input-group/InputGroup.cjs"),i=require("../popover/Popover.cjs"),c=require("../text-input/BaseTextInput.cjs"),d=require("./internal/Calendar.cjs"),p=require("./utils.cjs"),f=require("./validation.cjs"),v=a.forwardRef((v,D)=>{const{"data-testautoid":m,id:b,className:g="",label:j="Velg dato",labelProps:k,defaultValue:h,defaultShow:y=!1,value:x,disableBeforeDate:C,disableAfterDate:S,yearsToShow:L,name:P,helpLabel:q,errorLabel:w,invalid:I,days:O,months:T,monthLabel:B,yearLabel:E,placeholder:_="dd.mm.åååå",width:R="11.25rem",onChange:N,onBlur:U,onFocus:V,onKeyDown:F,action:K,showCalendarLabel:M="Åpne kalender",hideCalendarLabel:W="Lukk kalender",supportLabelProps:A,tooltip:G,textInputProps:H,description:$,...z}=v;"production"!==process.env.NODE_ENV&&x&&h&&console.warn("DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.");const J=p.parseDateString(C),Q=J?r.dayjs(J).startOf("day").toDate():void 0,X=p.parseDateString(S),Y=X?r.dayjs(X).startOf("day").toDate():void 0,[Z,ee]=a.useState(r.getInitialDate(x,h,Q,Y)),[te,re]=a.useState(null),[ae,ne]=a.useState(y),oe=a.useRef(null),le=a.useRef(null),ue=a.useRef(null),se=a.useRef(null),ie=a.useRef(!1),ce=a.useCallback(e=>{se.current=e,D&&("function"==typeof D?D(e):D.current=e)},[D]),de=a.useCallback(e=>{V&&le.current&&(le.current.contains(e.relatedTarget)||V(e,Z,{error:te,value:e.target.value}))},[V,Z,te]),pe=a.useCallback(e=>{U&&U(e,Z,{error:te,value:e.target.value})},[U,Z,te]),fe=a.useCallback(e=>{"Escape"===e.key&&(ne(!1),e.preventDefault(),e.stopPropagation()),K?.onKeyDown&&K.onKeyDown(e)},[K]),ve=a.useCallback(e=>{const t=e.currentTarget.value,r=((e,t)=>{const r=e.replace(/\D/g,""),a=o.formatDateString(r,{partial:!0}),n=e.replace(/\D+$/,""),l=8===r.length?o.formatDateString(r):e,u=p.parseDateString(l)?l:null,s=t&&e!==r&&n===a&&void 0===p.parseDateString(e)&&null===u;return u??(s?r:e)})(t,ie.current);r!==t&&((e,t)=>{const r=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set;r?r.call(e,t):e.value=t})(e.currentTarget,r);const a=t.replace(/\D/g,"");ie.current=t===a&&r===o.formatDateString(a)&&r!==t&&void 0!==p.parseDateString(r);const{date:n,error:l}=(({value:e,minDate:t,maxDate:r})=>{if(!e)return{date:null,error:null};const a=p.parseDateString(e);return a?t&&!f.isWithinLowerBound(a,t)?{date:a,error:"OUTSIDE_LOWER_BOUND"}:r&&!f.isWithinUpperBound(a,r)?{date:a,error:"OUTSIDE_UPPER_BOUND"}:{date:a,error:null}:{date:null,error:"WRONG_FORMAT"}})({value:r,minDate:Q,maxDate:Y});n&&!l&&ne(!1),re(l),ee(n),N&&N(e,n,{error:l,value:r})},[N,Q,Y]),De=a.useCallback(e=>{n.flushSync(()=>{ne(!ae)});const t=oe.current,r=t&&t.querySelector('[aria-pressed="true"]');window.requestAnimationFrame(()=>r?.focus()),K?.onClick&&K.onClick(e)},[ae,K]),me=a.useCallback(({date:e})=>{if(ne(!1),ee(e),se.current){const t=se.current;ie.current=!1,t.value=p.formatInput(e);const r=document.createEvent("HTMLEvents");r.initEvent("input",!0,!1),t.dispatchEvent(r),t.focus(),N&&N(r,e,{error:null,value:t.value})}},[N]),be=a.useCallback(e=>{e.preventDefault(),ne(!1),ue.current?.focus()},[]);return e.jsx(s.InputGroup,{id:b,className:t.clsx("jkl-datepicker",g),...z,ref:le,label:j,labelProps:k,helpLabel:q,errorLabel:w,supportLabelProps:A,tooltip:G,description:$,render:t=>e.jsx(c.BaseTextInput,{"data-focused":ae?"true":void 0,ref:ce,"data-testid":"jkl-datepicker__input","data-testautoid":m,className:"jkl-datepicker__input",name:P,defaultValue:h,value:x,type:"text",placeholder:_,width:R,onFocus:de,onBlur:pe,onChange:ve,actionButton:e.jsxs(i.Popover,{positionReference:se,open:ae,onOpenChange:()=>ne(!ae),offset:8,children:[e.jsx(i.Popover.Trigger,{...K,"data-testid":"jkl-datepicker__trigger",className:"jkl-text-input-action-button",title:ae?W:M,tabIndex:0,onClick:De,onKeyDown:fe,asChild:!0,children:e.jsx(l.IconButton,{children:e.jsx(u.CalendarIcon,{})})}),e.jsx(i.Popover.Content,{initialFocus:-1,padding:24,children:e.jsx(d.Calendar,{ref:oe,date:Z,minDate:Q,maxDate:Y,days:O,months:T,monthLabel:B,yearLabel:E,yearsToShow:L,onDateSelected:me,onTabOutside:be})})]}),...H,...t,"aria-invalid":I||!!w})})});v.displayName="DatePicker",exports.DatePicker=v;
2
2
  //# sourceMappingURL=DatePicker.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker.cjs","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport React, {\n type ChangeEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { formatDateString } from \"../../utilities/formatters/date/formatDate.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CalendarIcon } from \"../icon/icons/CalendarIcon.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport Popover from \"../popover/Popover.js\";\nimport { BaseTextInput } from \"../text-input/BaseTextInput.js\";\nimport { Calendar } from \"./internal/Calendar.js\";\nimport { type DateInfo, getInitialDate } from \"./internal/utils.js\";\nimport type { DatePickerProps, DateValidationError } from \"./types.js\";\nimport { formatInput, parseDateString } from \"./utils.js\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation.js\";\n\nconst setInputValue = (input: HTMLInputElement, value: string) => {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set;\n\n if (nativeSetter) {\n nativeSetter.call(input, value);\n } else {\n input.value = value;\n }\n};\n\nconst normalizeInputValue = (rawValue: string) => {\n const digits = rawValue.replace(/\\D/g, \"\");\n const partialCompactDate = formatDateString(digits, {\n partial: true,\n });\n const rawValueWithoutTrailingPunctuation = rawValue.replace(/\\D+$/, \"\");\n const compactDateCandidate =\n digits.length === 8 ? formatDateString(digits) : rawValue;\n const validCompactDate = parseDateString(compactDateCandidate)\n ? compactDateCandidate\n : null;\n const shouldRemoveFormatting =\n rawValue !== digits &&\n rawValueWithoutTrailingPunctuation === partialCompactDate &&\n parseDateString(rawValue) === undefined &&\n validCompactDate === null;\n\n return validCompactDate ?? (shouldRemoveFormatting ? digits : rawValue);\n};\n\nconst getInputValidationState = ({\n value,\n minDate,\n maxDate,\n}: {\n value: string;\n minDate?: Date;\n maxDate?: Date;\n}): { date: Date | null; error: DateValidationError | null } => {\n if (!value) {\n return { date: null, error: null };\n }\n\n const parsedDate = parseDateString(value);\n\n if (!parsedDate) {\n return { date: null, error: \"WRONG_FORMAT\" };\n }\n\n if (minDate && !isWithinLowerBound(parsedDate, minDate)) {\n return { date: parsedDate, error: \"OUTSIDE_LOWER_BOUND\" };\n }\n\n if (maxDate && !isWithinUpperBound(parsedDate, maxDate)) {\n return { date: parsedDate, error: \"OUTSIDE_UPPER_BOUND\" };\n }\n\n return { date: parsedDate, error: null };\n};\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(\n (props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltip,\n textInputProps,\n description,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate\n ? dayjs(disableBeforeDate).startOf(\"day\").toDate()\n : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate\n ? dayjs(disableAfterDate).startOf(\"day\").toDate()\n : undefined;\n\n const [date, setDate] = useState(\n getInitialDate(value, defaultValue, minDate, maxDate),\n );\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n\n const calendarRef = useRef<HTMLDivElement>(null);\n const datepickerRef = useRef<HTMLDivElement>(null);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [forwardedInputRef],\n );\n\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [action],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.currentTarget.value;\n const formattedValue = normalizeInputValue(rawValue);\n\n if (formattedValue !== rawValue) {\n setInputValue(e.currentTarget, formattedValue);\n }\n\n const { date: nextDate, error: nextError } =\n getInputValidationState({\n value: formattedValue,\n minDate,\n maxDate,\n });\n\n if (nextDate && !nextError) {\n setShowCalendar(false);\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, {\n error: nextError,\n value: formattedValue,\n });\n }\n },\n [onChange, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button =\n calendarEl &&\n (calendarEl.querySelector(\n '[aria-pressed=\"true\"]',\n ) as HTMLButtonElement);\n // Make sure the popover-modal is correctly positioned before focusing a button\n // so we avoid accidentally scrolling to the top of the page\n window.requestAnimationFrame(() => button?.focus());\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [showCalendar, action],\n );\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(\n event as unknown as ChangeEvent<HTMLInputElement>,\n date,\n {\n error: null,\n value: node.value,\n },\n );\n }\n }\n },\n [onChange],\n );\n\n const handleTabOutsideCalendar = useCallback((e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current?.focus();\n }, []);\n\n return (\n <InputGroup\n id={id}\n className={clsx(\"jkl-datepicker\", className)}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltip={tooltip}\n description={description}\n render={(inputProps) => (\n <BaseTextInput\n data-focused={showCalendar ? \"true\" : undefined}\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n actionButton={\n <Popover\n positionReference={inputRef}\n open={showCalendar}\n onOpenChange={() =>\n setShowCalendar(!showCalendar)\n }\n offset={8}\n >\n <Popover.Trigger\n {...action}\n data-testid=\"jkl-datepicker__trigger\"\n className=\"jkl-text-input-action-button\"\n title={\n showCalendar\n ? hideCalendarLabel\n : showCalendarLabel\n }\n tabIndex={0}\n onClick={clickCalendar}\n onKeyDown={handleKeyDownAction}\n asChild\n >\n <IconButton>\n <CalendarIcon />\n </IconButton>\n </Popover.Trigger>\n <Popover.Content initialFocus={-1} padding={24}>\n <Calendar\n ref={calendarRef}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </Popover.Content>\n </Popover>\n }\n {...textInputProps}\n {...inputProps}\n aria-invalid={invalid || !!errorLabel}\n />\n )}\n />\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltip","textInputProps","description","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","dayjs","startOf","toDate","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useRef","datepickerRef","iconButtonRef","inputRef","unifiedInputRef","useCallback","instance","current","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleChange","rawValue","currentTarget","formattedValue","digits","replace","partialCompactDate","formatDateString","partial","rawValueWithoutTrailingPunctuation","compactDateCandidate","length","validCompactDate","shouldRemoveFormatting","normalizeInputValue","input","nativeSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","setInputValue","nextDate","nextError","parsedDate","isWithinLowerBound","isWithinUpperBound","getInputValidationState","clickCalendar","flushSync","calendarEl","button","querySelector","window","requestAnimationFrame","focus","onClick","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","jsx","InputGroup","clsx","ref","render","inputProps","BaseTextInput","type","actionButton","jsxs","Popover","positionReference","open","onOpenChange","offset","children","Trigger","title","tabIndex","asChild","IconButton","CalendarIcon","Content","initialFocus","padding","Calendar","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"DatePicker.cjs","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport React, {\n type ChangeEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { formatDateString } from \"../../utilities/formatters/date/formatDate.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CalendarIcon } from \"../icon/icons/CalendarIcon.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport Popover from \"../popover/Popover.js\";\nimport { BaseTextInput } from \"../text-input/BaseTextInput.js\";\nimport { Calendar } from \"./internal/Calendar.js\";\nimport { type DateInfo, getInitialDate } from \"./internal/utils.js\";\nimport type { DatePickerProps, DateValidationError } from \"./types.js\";\nimport { formatInput, parseDateString } from \"./utils.js\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation.js\";\n\nconst setInputValue = (input: HTMLInputElement, value: string) => {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set;\n\n if (nativeSetter) {\n nativeSetter.call(input, value);\n } else {\n input.value = value;\n }\n};\n\nconst normalizeInputValue = (\n rawValue: string,\n shouldStripAutoFormatting: boolean,\n) => {\n const digits = rawValue.replace(/\\D/g, \"\");\n const partialCompactDate = formatDateString(digits, {\n partial: true,\n });\n const rawValueWithoutTrailingPunctuation = rawValue.replace(/\\D+$/, \"\");\n const compactDateCandidate =\n digits.length === 8 ? formatDateString(digits) : rawValue;\n const validCompactDate = parseDateString(compactDateCandidate)\n ? compactDateCandidate\n : null;\n const shouldRemoveFormatting =\n shouldStripAutoFormatting &&\n rawValue !== digits &&\n rawValueWithoutTrailingPunctuation === partialCompactDate &&\n parseDateString(rawValue) === undefined &&\n validCompactDate === null;\n\n return validCompactDate ?? (shouldRemoveFormatting ? digits : rawValue);\n};\n\nconst getInputValidationState = ({\n value,\n minDate,\n maxDate,\n}: {\n value: string;\n minDate?: Date;\n maxDate?: Date;\n}): { date: Date | null; error: DateValidationError | null } => {\n if (!value) {\n return { date: null, error: null };\n }\n\n const parsedDate = parseDateString(value);\n\n if (!parsedDate) {\n return { date: null, error: \"WRONG_FORMAT\" };\n }\n\n if (minDate && !isWithinLowerBound(parsedDate, minDate)) {\n return { date: parsedDate, error: \"OUTSIDE_LOWER_BOUND\" };\n }\n\n if (maxDate && !isWithinUpperBound(parsedDate, maxDate)) {\n return { date: parsedDate, error: \"OUTSIDE_UPPER_BOUND\" };\n }\n\n return { date: parsedDate, error: null };\n};\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(\n (props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltip,\n textInputProps,\n description,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate\n ? dayjs(disableBeforeDate).startOf(\"day\").toDate()\n : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate\n ? dayjs(disableAfterDate).startOf(\"day\").toDate()\n : undefined;\n\n const [date, setDate] = useState(\n getInitialDate(value, defaultValue, minDate, maxDate),\n );\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n\n const calendarRef = useRef<HTMLDivElement>(null);\n const datepickerRef = useRef<HTMLDivElement>(null);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const didAutoFormatCompactInputRef = useRef(false);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [forwardedInputRef],\n );\n\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [action],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.currentTarget.value;\n const formattedValue = normalizeInputValue(\n rawValue,\n didAutoFormatCompactInputRef.current,\n );\n\n if (formattedValue !== rawValue) {\n setInputValue(e.currentTarget, formattedValue);\n }\n\n const digits = rawValue.replace(/\\D/g, \"\");\n didAutoFormatCompactInputRef.current =\n rawValue === digits &&\n formattedValue === formatDateString(digits) &&\n formattedValue !== rawValue &&\n parseDateString(formattedValue) !== undefined;\n\n const { date: nextDate, error: nextError } =\n getInputValidationState({\n value: formattedValue,\n minDate,\n maxDate,\n });\n\n if (nextDate && !nextError) {\n setShowCalendar(false);\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, {\n error: nextError,\n value: formattedValue,\n });\n }\n },\n [onChange, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button =\n calendarEl &&\n (calendarEl.querySelector(\n '[aria-pressed=\"true\"]',\n ) as HTMLButtonElement);\n // Make sure the popover-modal is correctly positioned before focusing a button\n // so we avoid accidentally scrolling to the top of the page\n window.requestAnimationFrame(() => button?.focus());\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [showCalendar, action],\n );\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n didAutoFormatCompactInputRef.current = false;\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(\n event as unknown as ChangeEvent<HTMLInputElement>,\n date,\n {\n error: null,\n value: node.value,\n },\n );\n }\n }\n },\n [onChange],\n );\n\n const handleTabOutsideCalendar = useCallback((e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current?.focus();\n }, []);\n\n return (\n <InputGroup\n id={id}\n className={clsx(\"jkl-datepicker\", className)}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltip={tooltip}\n description={description}\n render={(inputProps) => (\n <BaseTextInput\n data-focused={showCalendar ? \"true\" : undefined}\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n actionButton={\n <Popover\n positionReference={inputRef}\n open={showCalendar}\n onOpenChange={() =>\n setShowCalendar(!showCalendar)\n }\n offset={8}\n >\n <Popover.Trigger\n {...action}\n data-testid=\"jkl-datepicker__trigger\"\n className=\"jkl-text-input-action-button\"\n title={\n showCalendar\n ? hideCalendarLabel\n : showCalendarLabel\n }\n tabIndex={0}\n onClick={clickCalendar}\n onKeyDown={handleKeyDownAction}\n asChild\n >\n <IconButton>\n <CalendarIcon />\n </IconButton>\n </Popover.Trigger>\n <Popover.Content initialFocus={-1} padding={24}>\n <Calendar\n ref={calendarRef}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </Popover.Content>\n </Popover>\n }\n {...textInputProps}\n {...inputProps}\n aria-invalid={invalid || !!errorLabel}\n />\n )}\n />\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltip","textInputProps","description","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","dayjs","startOf","toDate","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useRef","datepickerRef","iconButtonRef","inputRef","didAutoFormatCompactInputRef","unifiedInputRef","useCallback","instance","current","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleChange","rawValue","currentTarget","formattedValue","shouldStripAutoFormatting","digits","replace","partialCompactDate","formatDateString","partial","rawValueWithoutTrailingPunctuation","compactDateCandidate","length","validCompactDate","shouldRemoveFormatting","normalizeInputValue","input","nativeSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","setInputValue","nextDate","nextError","parsedDate","isWithinLowerBound","isWithinUpperBound","getInputValidationState","clickCalendar","flushSync","calendarEl","button","querySelector","window","requestAnimationFrame","focus","onClick","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","jsx","InputGroup","clsx","ref","render","inputProps","BaseTextInput","type","actionButton","jsxs","Popover","positionReference","open","onOpenChange","offset","children","Trigger","title","tabIndex","asChild","IconButton","CalendarIcon","Content","initialFocus","padding","Calendar","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),r=require("../../../clsx-E3yX_9sL.cjs"),c=require("react").forwardRef(function(c,i){const{bold:l,children:n,className:o,filled:s,variant:t,...a}=c;return e.jsx("span",{"aria-hidden":!0,ref:i,className:r.clsx("jkl-icon",o,{"jkl-icon--filled":s,"jkl-icon--bold":l}),...a,children:n})});exports.Icon=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),r=require("../../../clsx-E3yX_9sL.cjs"),i=require("react").forwardRef(function(i,s){const{as:a="span",bold:c,children:l,className:n,filled:d,variant:o,...t}=i,u=r.clsx("jkl-icon",n,{"jkl-icon--filled":d,"jkl-icon--bold":c});return"div"===a?e.jsx("div",{"aria-hidden":!0,ref:s,className:u,...t,children:l}):e.jsx("span",{"aria-hidden":!0,ref:s,className:u,...t,children:l})});exports.Icon=i;
2
2
  //# sourceMappingURL=Icon.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.cjs","sources":["../../../../src/components/icon/Icon.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React from \"react\";\nimport type {\n PolymorphicPropsWithRef,\n PolymorphicRef,\n} from \"../../utilities/polymorphism/polymorphism.js\";\nimport type { IconVariant } from \"./types.js\";\n\ntype IconComponentProps<\n ElementType extends Extract<React.ElementType, \"span\" | \"div\">,\n> = PolymorphicPropsWithRef<\n ElementType,\n {\n \"data-testid\"?: string;\n /**\n * Størrelsesvarianten til ikonet. `\"small\"` er 16px med 20px bounding box, og `\"medium\"` er 20px med 24px bounding box.\n * `\"inherit\"` setter størrelsen til ikonet (ikke bounding box) lik skriftstørrelsen (1em).\n */\n variant?: IconVariant;\n /**\n * Angir om ikonet skal vises i fet versjon\n * @default false\n */\n bold?: boolean;\n filled?: boolean;\n className?: string;\n style?: React.CSSProperties;\n }\n>;\n\nexport type IconComponent = (<\n ElementType extends Extract<React.ElementType, \"span\" | \"div\"> = \"span\",\n>(\n props: IconComponentProps<ElementType>,\n) => React.ReactElement | null) & { displayName?: string };\n\nexport const Icon: IconComponent = React.forwardRef(function Icon<\n ElementType extends Extract<React.ElementType, \"span\" | \"div\"> = \"span\",\n>(props: IconComponentProps<ElementType>, ref?: PolymorphicRef<ElementType>) {\n const { bold, children, className, filled, variant, ...iconProps } = props;\n\n return (\n <span\n aria-hidden\n ref={ref}\n className={clsx(\"jkl-icon\", className, {\n \"jkl-icon--filled\": filled,\n \"jkl-icon--bold\": bold,\n })}\n {...iconProps}\n >\n {children}\n </span>\n );\n}) as IconComponent;\n"],"names":["Icon","forwardRef","props","ref","bold","children","className","filled","variant","iconProps","jsx","clsx"],"mappings":"6JAoCaA,mBAA4BC,WAAW,SAElDC,EAAwCC,GACtC,MAAQC,KAAAA,EAAMC,SAAAA,EAAUC,UAAAA,EAAWC,OAAAA,EAAQC,QAAAA,KAAYC,GAAcP,EAErE,OACIQ,EAAAA,IAAC,OAAA,CACG,eAAW,EACXP,IAAAA,EACAG,UAAWK,EAAAA,KAAK,WAAYL,EAAW,CACnC,mBAAoBC,EACpB,iBAAkBH,OAElBK,EAEHJ,SAAAA,GAGb"}
1
+ {"version":3,"file":"Icon.cjs","sources":["../../../../src/components/icon/Icon.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React from \"react\";\nimport type {\n PolymorphicPropsWithRef,\n PolymorphicRef,\n} from \"../../utilities/polymorphism/polymorphism.js\";\nimport type { IconVariant } from \"./types.js\";\n\ntype IconComponentProps<\n ElementType extends \"span\" | \"div\",\n> = PolymorphicPropsWithRef<\n ElementType,\n {\n \"data-testid\"?: string;\n /**\n * Størrelsesvarianten til ikonet. `\"small\"` er 16px med 20px bounding box, og `\"medium\"` er 20px med 24px bounding box.\n * `\"inherit\"` setter størrelsen til ikonet (ikke bounding box) lik skriftstørrelsen (1em).\n */\n variant?: IconVariant;\n /**\n * Angir om ikonet skal vises i fet versjon\n * @default false\n */\n bold?: boolean;\n filled?: boolean;\n className?: string;\n style?: React.CSSProperties;\n }\n>;\n\nexport type IconComponent = (<\n ElementType extends \"span\" | \"div\" = \"span\",\n>(\n props: IconComponentProps<ElementType>,\n) => React.ReactElement | null) & { displayName?: string };\n\nexport const Icon: IconComponent = React.forwardRef(function Icon<\n ElementType extends \"span\" | \"div\" = \"span\",\n>(props: IconComponentProps<ElementType>, ref?: PolymorphicRef<ElementType>) {\n const {\n as = \"span\",\n bold,\n children,\n className,\n filled,\n variant,\n ...iconProps\n } = props;\n const iconClassName = clsx(\"jkl-icon\", className, {\n \"jkl-icon--filled\": filled,\n \"jkl-icon--bold\": bold,\n });\n\n if (as === \"div\") {\n return (\n <div\n aria-hidden\n ref={ref as PolymorphicRef<\"div\">}\n className={iconClassName}\n {...(iconProps as React.HTMLAttributes<HTMLDivElement>)}\n >\n {children}\n </div>\n );\n }\n\n return (\n <span\n aria-hidden\n ref={ref as PolymorphicRef<\"span\">}\n className={iconClassName}\n {...(iconProps as React.HTMLAttributes<HTMLSpanElement>)}\n >\n {children}\n </span>\n );\n}) as IconComponent;\n"],"names":["Icon","forwardRef","props","ref","as","bold","children","className","filled","variant","iconProps","iconClassName","clsx","jsx"],"mappings":"6JAoCaA,mBAA4BC,WAAW,SAElDC,EAAwCC,GACtC,MACIC,GAAAA,EAAK,OACLC,KAAAA,EACAC,SAAAA,EACAC,UAAAA,EACAC,OAAAA,EACAC,QAAAA,KACGC,GACHR,EACES,EAAgBC,EAAAA,KAAK,WAAYL,EAAW,CAC9C,mBAAoBC,EACpB,iBAAkBH,IAGtB,MAAW,QAAPD,EAEIS,EAAAA,IAAC,MAAA,CACG,eAAW,EACXV,IAAAA,EACAI,UAAWI,KACND,EAEJJ,SAAAA,IAMTO,EAAAA,IAAC,OAAA,CACG,eAAW,EACXV,IAAAA,EACAI,UAAWI,KACND,EAEJJ,SAAAA,GAGb"}
@@ -1,7 +1,7 @@
1
1
  import { default as React } from 'react';
2
2
  import { PolymorphicPropsWithRef } from '../../utilities/polymorphism/polymorphism.cjs';
3
3
  import { IconVariant } from './types.cjs';
4
- type IconComponentProps<ElementType extends Extract<React.ElementType, "span" | "div">> = PolymorphicPropsWithRef<ElementType, {
4
+ type IconComponentProps<ElementType extends "span" | "div"> = PolymorphicPropsWithRef<ElementType, {
5
5
  "data-testid"?: string;
6
6
  /**
7
7
  * Størrelsesvarianten til ikonet. `"small"` er 16px med 20px bounding box, og `"medium"` er 20px med 24px bounding box.
@@ -17,7 +17,7 @@ type IconComponentProps<ElementType extends Extract<React.ElementType, "span" |
17
17
  className?: string;
18
18
  style?: React.CSSProperties;
19
19
  }>;
20
- export type IconComponent = (<ElementType extends Extract<React.ElementType, "span" | "div"> = "span">(props: IconComponentProps<ElementType>) => React.ReactElement | null) & {
20
+ export type IconComponent = (<ElementType extends "span" | "div" = "span">(props: IconComponentProps<ElementType>) => React.ReactElement | null) & {
21
21
  displayName?: string;
22
22
  };
23
23
  export declare const Icon: IconComponent;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("../../../../clsx-E3yX_9sL.cjs");require("react");const c=({as:c="div",bold:r=!1,className:s,variant:i="inherit","data-testid":l,style:n,...o})=>{const a=c;return e.jsx(a,{className:t.clsx(s,"jkl-icon","jkl-icon-green-check",`jkl-icon--${i}`,{"jkl-icon--bold":r}),"aria-hidden":"true",style:n,"data-testid":l,...o,children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"24px",height:"24px",children:[e.jsx("circle",{cx:"12",cy:"12",r:"10"}),e.jsx("path",{fillRule:"evenodd",d:"M17.52 9.54 10.7 16.2l-4.21-4.1 1.04-1.08 3.17 3.09 5.79-5.65 1.04 1.08Z",clipRule:"evenodd"})]})})};c.displayName="GreenCheckIcon",exports.GreenCheckIcon=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("../../../../clsx-E3yX_9sL.cjs");require("react");const r=require("../Icon.cjs"),s=s=>e.jsx(r.Icon,{...s,className:c.clsx("jkl-icon-green-check",s.className),children:""});s.displayName="GreenCheckIcon",exports.GreenCheckIcon=s;
2
2
  //# sourceMappingURL=GreenCheckIcon.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"GreenCheckIcon.cjs","sources":["../../../../../src/components/icon/icons/GreenCheckIcon.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { type FC } from \"react\";\nimport type { IconProps } from \"../types.js\";\n\n/*\n * NOTE: The green-check and red-cross icons also exists as a copy in the jkl-list package.\n * If you're here to change them, consider changing them there as well, or\n * finding a technical solution to sharing the SVG markup\n */\nexport const GreenCheckIcon: FC<IconProps> = ({\n as = \"div\",\n bold = false,\n className,\n variant = \"inherit\",\n \"data-testid\": testId,\n style,\n ...rest\n}) => {\n const El = as;\n\n return (\n <El\n className={clsx(\n className,\n \"jkl-icon\",\n \"jkl-icon-green-check\",\n `jkl-icon--${variant}`,\n {\n \"jkl-icon--bold\": bold,\n },\n )}\n aria-hidden=\"true\"\n style={style}\n data-testid={testId}\n {...rest}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width=\"24px\"\n height=\"24px\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path\n fillRule=\"evenodd\"\n d=\"M17.52 9.54 10.7 16.2l-4.21-4.1 1.04-1.08 3.17 3.09 5.79-5.65 1.04 1.08Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </El>\n );\n};\nGreenCheckIcon.displayName = \"GreenCheckIcon\";\n"],"names":["GreenCheckIcon","as","bold","className","variant","testId","style","rest","El","jsx","clsx","children","jsxs","xmlns","viewBox","width","height","cx","cy","r","fillRule","d","clipRule","displayName"],"mappings":"iLASO,MAAMA,EAAgC,EACzCC,GAAAA,EAAK,MACLC,KAAAA,GAAO,EACPC,UAAAA,EACAC,QAAAA,EAAU,UACV,cAAeC,EACfC,MAAAA,KACGC,MAEH,MAAMC,EAAKP,EAEX,OACIQ,EAAAA,IAACD,EAAA,CACGL,UAAWO,EAAAA,KACPP,EACA,WACA,uBACA,aAAaC,IACb,CACI,iBAAkBF,IAG1B,cAAY,OACZI,MAAAA,EACA,cAAaD,KACTE,EAEJI,SAAAC,EAAAA,KAAC,MAAA,CACGC,MAAM,6BACNC,QAAQ,YACRC,MAAM,OACNC,OAAO,OAEPL,SAAA,CAAAF,MAAC,UAAOQ,GAAG,KAAKC,GAAG,KAAKC,EAAE,OAC1BV,EAAAA,IAAC,OAAA,CACGW,SAAS,UACTC,EAAE,2EACFC,SAAS,kBAM7BtB,EAAeuB,YAAc"}
1
+ {"version":3,"file":"GreenCheckIcon.cjs","sources":["../../../../../src/components/icon/icons/GreenCheckIcon.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React from \"react\";\nimport { Icon, type IconComponent } from \"../Icon.js\";\nimport type { IconProps } from \"../types.js\";\n\nexport const GreenCheckIcon: IconComponent = (props: IconProps) => (\n <Icon {...props} className={clsx(\"jkl-icon-green-check\", props.className)}>\n {\"\\ue5ca\"}\n </Icon>\n);\nGreenCheckIcon.displayName = \"GreenCheckIcon\";\n"],"names":["GreenCheckIcon","props","jsx","Icon","className","clsx","children","displayName"],"mappings":"gNAKaA,EAAiCC,GAC1CC,EAAAA,IAACC,EAAAA,KAAA,IAASF,EAAOG,UAAWC,EAAAA,KAAK,uBAAwBJ,EAAMG,WAC1DE,SAAA,MAGTN,EAAeO,YAAc"}
@@ -1,3 +1,2 @@
1
- import { FC } from 'react';
2
- import { IconProps } from '../types.cjs';
3
- export declare const GreenCheckIcon: FC<IconProps>;
1
+ import { IconComponent } from '../Icon.cjs';
2
+ export declare const GreenCheckIcon: IconComponent;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),s=require("../../../../clsx-E3yX_9sL.cjs");require("react");const t=({as:t="div",bold:r=!1,className:i,variant:c="inherit","data-testid":o,style:a,...l})=>{const d=t;return e.jsx(d,{className:s.clsx(i,"jkl-icon","jkl-icon-red-cross",`jkl-icon--${c}`,{"jkl-icon--bold":r}),"aria-hidden":"true",style:a,"data-testid":o,...l,children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"24px",height:"24px",children:[e.jsx("circle",{cx:"12",cy:"12",r:"10"}),e.jsx("path",{d:"m15.71 7.23 1.06 1.06-8.48 8.48-1.06-1.06 8.48-8.48Z"}),e.jsx("path",{d:"m8.29 7.23 8.48 8.48-1.06 1.06L7.23 8.3l1.06-1.06Z"})]})})};t.displayName="RedCrossIcon",exports.RedCrossIcon=t;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),s=require("../../../../clsx-E3yX_9sL.cjs");require("react");const r=require("../Icon.cjs"),c=c=>e.jsx(r.Icon,{...c,className:s.clsx("jkl-icon-red-cross",c.className),children:""});c.displayName="RedCrossIcon",exports.RedCrossIcon=c;
2
2
  //# sourceMappingURL=RedCrossIcon.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"RedCrossIcon.cjs","sources":["../../../../../src/components/icon/icons/RedCrossIcon.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { type FC } from \"react\";\nimport type { IconProps } from \"../types.js\";\n\n/*\n * NOTE: The green-check and red-cross icons also exists as a copy in the jkl-list package.\n * If you're here to change them, consider changing them there as well, or\n * finding a technical solution to sharing the SVG markup\n */\nexport const RedCrossIcon: FC<IconProps> = ({\n as = \"div\",\n bold = false,\n className,\n variant = \"inherit\",\n \"data-testid\": testId,\n style,\n ...rest\n}) => {\n const El = as;\n\n return (\n <El\n className={clsx(\n className,\n \"jkl-icon\",\n \"jkl-icon-red-cross\",\n `jkl-icon--${variant}`,\n {\n \"jkl-icon--bold\": bold,\n },\n )}\n aria-hidden=\"true\"\n style={style}\n data-testid={testId}\n {...rest}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width=\"24px\"\n height=\"24px\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m15.71 7.23 1.06 1.06-8.48 8.48-1.06-1.06 8.48-8.48Z\" />\n <path d=\"m8.29 7.23 8.48 8.48-1.06 1.06L7.23 8.3l1.06-1.06Z\" />\n </svg>\n </El>\n );\n};\nRedCrossIcon.displayName = \"RedCrossIcon\";\n"],"names":["RedCrossIcon","as","bold","className","variant","testId","style","rest","El","jsx","clsx","children","jsxs","xmlns","viewBox","width","height","cx","cy","r","d","displayName"],"mappings":"iLASO,MAAMA,EAA8B,EACvCC,GAAAA,EAAK,MACLC,KAAAA,GAAO,EACPC,UAAAA,EACAC,QAAAA,EAAU,UACV,cAAeC,EACfC,MAAAA,KACGC,MAEH,MAAMC,EAAKP,EAEX,OACIQ,EAAAA,IAACD,EAAA,CACGL,UAAWO,EAAAA,KACPP,EACA,WACA,qBACA,aAAaC,IACb,CACI,iBAAkBF,IAG1B,cAAY,OACZI,MAAAA,EACA,cAAaD,KACTE,EAEJI,SAAAC,EAAAA,KAAC,MAAA,CACGC,MAAM,6BACNC,QAAQ,YACRC,MAAM,OACNC,OAAO,OAEPL,SAAA,CAAAF,MAAC,UAAOQ,GAAG,KAAKC,GAAG,KAAKC,EAAE,OAC1BV,EAAAA,IAAC,OAAA,CAAKW,EAAE,yDACRX,EAAAA,IAAC,OAAA,CAAKW,EAAE,6DAKxBpB,EAAaqB,YAAc"}
1
+ {"version":3,"file":"RedCrossIcon.cjs","sources":["../../../../../src/components/icon/icons/RedCrossIcon.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React from \"react\";\nimport { Icon, type IconComponent } from \"../Icon.js\";\nimport type { IconProps } from \"../types.js\";\n\nexport const RedCrossIcon: IconComponent = (props: IconProps) => (\n <Icon {...props} className={clsx(\"jkl-icon-red-cross\", props.className)}>\n {\"\\ue5cd\"}\n </Icon>\n);\nRedCrossIcon.displayName = \"RedCrossIcon\";\n"],"names":["RedCrossIcon","props","jsx","Icon","className","clsx","children","displayName"],"mappings":"gNAKaA,EAA+BC,GACxCC,EAAAA,IAACC,EAAAA,KAAA,IAASF,EAAOG,UAAWC,EAAAA,KAAK,qBAAsBJ,EAAMG,WACxDE,SAAA,MAGTN,EAAaO,YAAc"}
@@ -1,3 +1,2 @@
1
- import { FC } from 'react';
2
- import { IconProps } from '../types.cjs';
3
- export declare const RedCrossIcon: FC<IconProps>;
1
+ import { IconComponent } from '../Icon.cjs';
2
+ export declare const RedCrossIcon: IconComponent;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("../../../clsx-E3yX_9sL.cjs"),i=require("react"),r=require("../../utilities/mergeRefs.cjs");require("../icon/Icon.cjs"),require("../icon/icons/animated/ArrowVerticalAnimated.cjs"),require("../icon/icons/animated/ArrowHorizontalAnimated.cjs"),require("../icon/icons/animated/PlusRemoveAnimated.cjs"),require("../icon/icons/ArrowDownIcon.cjs"),require("../icon/icons/ArrowLeftIcon.cjs"),require("../icon/icons/ArrowNorthEastIcon.cjs"),require("../icon/icons/ArrowRightIcon.cjs"),require("../icon/icons/ArrowUpIcon.cjs"),require("../icon/icons/CalendarIcon.cjs"),require("../icon/icons/CheckIcon.cjs"),require("../icon/icons/ChevronDownIcon.cjs"),require("../icon/icons/ChevronLeftIcon.cjs"),require("../icon/icons/ChevronRightIcon.cjs"),require("../icon/icons/ChevronUpIcon.cjs"),require("../icon/icons/CloseIcon.cjs"),require("../icon/icons/CopyIcon.cjs"),require("../icon/icons/DotsIcon.cjs"),require("../icon/icons/DragIcon.cjs"),require("../icon/icons/ErrorIcon.cjs"),require("../icon/icons/GreenCheckIcon.cjs"),require("../icon/icons/HamburgerIcon.cjs"),require("../icon/icons/InfoIcon.cjs"),require("../icon/icons/LinkIcon.cjs");const c=require("../icon/icons/MinusIcon.cjs");require("../icon/icons/OpenInNewIcon.cjs"),require("../icon/icons/PenIcon.cjs");const o=require("../icon/icons/PlusIcon.cjs");require("../icon/icons/QuestionIcon.cjs"),require("../icon/icons/RedCrossIcon.cjs"),require("../icon/icons/SearchIcon.cjs"),require("../icon/icons/SuccessIcon.cjs"),require("../icon/icons/ThumbDownIcon.cjs"),require("../icon/icons/ThumbUpIcon.cjs"),require("../icon/icons/TrashCanIcon.cjs"),require("../icon/icons/WarningIcon.cjs");const s=require("../input-group/InputGroup.cjs"),t={decrement:{label:"Senk verdien",Icon:c.MinusIcon},increment:{label:"Øk verdien",Icon:o.PlusIcon}};function u({direction:n,disabled:i,onClick:r}){const{label:c,Icon:o}=t[n];return e.jsx("button",{type:"button",className:"jkl-button jkl-button--ghost","aria-label":c,"data-direction":n,onPointerDown:e=>e.preventDefault(),onClick:r,disabled:i,children:e.jsx("span",{"aria-hidden":"true",children:e.jsx(o,{})})})}const a=i.forwardRef((c,o)=>{const{"data-size":t,"data-testautoid":a,"data-testid":l,align:d="left",id:p,label:j,className:m,style:b,errorLabel:I,helpLabel:q,inputClassName:h,labelProps:N,supportLabelProps:v,stepper:f=!1,tooltip:g,description:w,width:k,onChange:C,...x}=c,y=i.useRef(null),A=r.mergeRefs(y,o),[P,_]=i.useState(x.defaultValue),L=void 0!==x.value?x.value:P,D=e=>{void 0===x.value&&_(e.target.value),C?.(e)},R=function(e){return"number"==typeof e?e:"string"==typeof e&&""!==e.trim()?Number(e):Number.NaN}(L),S=void 0!==x.min?Number(x.min):Number.NaN,E=void 0!==x.max?Number(x.max):Number.NaN,F=Number.isFinite(R)&&Number.isFinite(S)&&R<=S,O=Number.isFinite(R)&&Number.isFinite(E)&&R>=E,T=b||k?{...b,...k?{width:k}:void 0}:void 0,U={id:p,label:j,errorLabel:I,helpLabel:q,labelProps:N,supportLabelProps:v,tooltip:g,description:w},z=e=>{const n=y.current;if(!n||n.disabled||n.readOnly)return;const i=n.value;n.focus();try{"increment"===e?n.stepUp():n.stepDown()}catch{return}n.value!==i&&n.dispatchEvent(new Event("input",{bubbles:!0}))},G=x.disabled||x.readOnly;return e.jsx(s.InputGroup,{...U,className:n.clsx(m,"jkl-number-input"),"data-size":t,"data-testid":l??"jkl-number-input",render:i=>e.jsxs("div",{className:n.clsx("jkl-number-input__wrapper",{"jkl-number-input__wrapper--stepper":f}),"data-invalid":i["aria-invalid"],style:T,children:[f&&e.jsx(u,{direction:"decrement",disabled:G||F,onClick:()=>z("decrement")}),e.jsx("input",{...i,...x,ref:A,type:"number",onChange:D,className:n.clsx("jkl-number-input__input",{"jkl-number-input__input--stepper":f,"jkl-number-input__input--align-right":!f&&"right"===d},h),"data-testautoid":a}),f&&e.jsx(u,{direction:"increment",disabled:G||O,onClick:()=>z("increment")})]})})});a.displayName="NumberInput",exports.NumberInput=a;
2
+ //# sourceMappingURL=NumberInput.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NumberInput.cjs","sources":["../../../../src/components/number-input/NumberInput.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n type ComponentType,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport { mergeRefs } from \"../../utilities/mergeRefs.js\";\nimport { MinusIcon, PlusIcon } from \"../icon/index.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport type { NumberInputProps } from \"./types.js\";\n\ntype NumberInputValue = string | number | readonly string[] | undefined;\n\ntype StepDirection = \"increment\" | \"decrement\";\n\nconst stepperConfig: Record<\n StepDirection,\n { label: string; Icon: ComponentType }\n> = {\n decrement: { label: \"Senk verdien\", Icon: MinusIcon },\n increment: { label: \"Øk verdien\", Icon: PlusIcon },\n};\n\nfunction toNumeric(value: NumberInputValue): number {\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\" && value.trim() !== \"\") {\n return Number(value);\n }\n return Number.NaN;\n}\n\ntype StepperButtonProps = {\n direction: StepDirection;\n disabled: boolean;\n onClick: () => void;\n};\n\nfunction StepperButton({ direction, disabled, onClick }: StepperButtonProps) {\n const { label, Icon } = stepperConfig[direction];\n\n return (\n <button\n type=\"button\"\n className=\"jkl-button jkl-button--ghost\"\n aria-label={label}\n data-direction={direction}\n onPointerDown={(event) => event.preventDefault()}\n onClick={onClick}\n disabled={disabled}\n >\n <span aria-hidden=\"true\">\n <Icon />\n </span>\n </button>\n );\n}\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n (props, ref) => {\n const {\n \"data-size\": dataSize,\n \"data-testautoid\": testAutoId,\n \"data-testid\": dataTestId,\n align = \"left\",\n id,\n label,\n className,\n style,\n errorLabel,\n helpLabel,\n inputClassName,\n labelProps,\n supportLabelProps,\n stepper = false,\n tooltip,\n description,\n width,\n onChange,\n ...rest\n } = props;\n const internalRef = useRef<HTMLInputElement>(null);\n const mergedRef = mergeRefs(internalRef, ref);\n const [uncontrolledValue, setUncontrolledValue] =\n useState<NumberInputValue>(rest.defaultValue);\n\n // I kontrollert bruk må vi lese direkte fra `value` for at disabled-\n // state på stepper-knappene skal følge prop-en i samme render. Bruker\n // intern state som fallback for ukontrollert bruk.\n const effectiveValue =\n rest.value !== undefined ? rest.value : uncontrolledValue;\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (rest.value === undefined) {\n setUncontrolledValue(event.target.value);\n }\n onChange?.(event);\n };\n\n const numericValue = toNumeric(effectiveValue);\n const minNumeric =\n rest.min !== undefined ? Number(rest.min) : Number.NaN;\n const maxNumeric =\n rest.max !== undefined ? Number(rest.max) : Number.NaN;\n const isAtOrBelowMin =\n Number.isFinite(numericValue) &&\n Number.isFinite(minNumeric) &&\n numericValue <= minNumeric;\n const isAtOrAboveMax =\n Number.isFinite(numericValue) &&\n Number.isFinite(maxNumeric) &&\n numericValue >= maxNumeric;\n\n const inputWrapperStyle =\n style || width\n ? {\n ...style,\n ...(width ? { width } : undefined),\n }\n : undefined;\n const inputGroupProps = {\n id,\n label,\n errorLabel,\n helpLabel,\n labelProps,\n supportLabelProps,\n tooltip,\n description,\n };\n\n const triggerStep = (direction: StepDirection) => {\n const input = internalRef.current;\n\n if (!input || input.disabled || input.readOnly) {\n return;\n }\n\n const previousValue = input.value;\n input.focus();\n\n try {\n if (direction === \"increment\") {\n input.stepUp();\n } else {\n input.stepDown();\n }\n } catch {\n return;\n }\n\n if (input.value === previousValue) {\n return;\n }\n\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n\n const stepperDisabled = rest.disabled || rest.readOnly;\n\n return (\n <InputGroup\n {...inputGroupProps}\n className={clsx(className, \"jkl-number-input\")}\n data-size={dataSize}\n data-testid={dataTestId ?? \"jkl-number-input\"}\n render={(inputProps) => (\n <div\n className={clsx(\"jkl-number-input__wrapper\", {\n \"jkl-number-input__wrapper--stepper\": stepper,\n })}\n data-invalid={inputProps[\"aria-invalid\"]}\n style={inputWrapperStyle}\n >\n {stepper && (\n <StepperButton\n direction=\"decrement\"\n disabled={stepperDisabled || isAtOrBelowMin}\n onClick={() => triggerStep(\"decrement\")}\n />\n )}\n <input\n {...inputProps}\n {...rest}\n ref={mergedRef}\n type=\"number\"\n onChange={handleChange}\n className={clsx(\n \"jkl-number-input__input\",\n {\n \"jkl-number-input__input--stepper\": stepper,\n \"jkl-number-input__input--align-right\":\n !stepper && align === \"right\",\n },\n inputClassName,\n )}\n data-testautoid={testAutoId}\n />\n {stepper && (\n <StepperButton\n direction=\"increment\"\n disabled={stepperDisabled || isAtOrAboveMax}\n onClick={() => triggerStep(\"increment\")}\n />\n )}\n </div>\n )}\n />\n );\n },\n);\n\nNumberInput.displayName = \"NumberInput\";\n"],"names":["stepperConfig","decrement","label","Icon","MinusIcon","increment","PlusIcon","StepperButton","direction","disabled","onClick","jsx","type","className","onPointerDown","event","preventDefault","children","NumberInput","forwardRef","props","ref","dataSize","testAutoId","dataTestId","align","id","style","errorLabel","helpLabel","inputClassName","labelProps","supportLabelProps","stepper","tooltip","description","width","onChange","rest","internalRef","useRef","mergedRef","mergeRefs","uncontrolledValue","setUncontrolledValue","useState","defaultValue","effectiveValue","value","handleChange","target","numericValue","trim","Number","NaN","toNumeric","minNumeric","min","maxNumeric","max","isAtOrBelowMin","isFinite","isAtOrAboveMax","inputWrapperStyle","inputGroupProps","triggerStep","input","current","readOnly","previousValue","focus","stepUp","stepDown","dispatchEvent","Event","bubbles","stepperDisabled","InputGroup","clsx","render","inputProps","jsxs","displayName"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export declare const NumberInput: React.ForwardRefExoticComponent<Omit<import('../input-group/types.js').InputGroupProps, "children" | "inline" | "render"> & Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "children"> & {
3
+ align?: "left" | "right";
4
+ width?: string;
5
+ inputClassName?: string;
6
+ stepper?: boolean;
7
+ } & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./NumberInput.cjs");exports.NumberInput=e.NumberInput;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export { NumberInput } from './NumberInput.cjs';
2
+ export type { NumberInputProps } from './types.cjs';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ import { InputHTMLAttributes } from 'react';
2
+ import { InputGroupProps } from '../input-group/types.cjs';
3
+ export type NumberInputProps = Omit<InputGroupProps, "children" | "inline" | "render"> & Omit<InputHTMLAttributes<HTMLInputElement>, "children" | "type"> & {
4
+ /**
5
+ * Justerer teksten i inputfeltet.
6
+ * @default "left"
7
+ */
8
+ align?: "left" | "right";
9
+ /**
10
+ * CSS-verdi for bredden til input-feltet.
11
+ */
12
+ width?: string;
13
+ inputClassName?: string;
14
+ /**
15
+ * Viser knapper på hver side av feltet som bruker native stepping.
16
+ * Respekterer `min`, `max` og `step`.
17
+ * @default false
18
+ */
19
+ stepper?: boolean;
20
+ };
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),a=t.forwardRef((a,r)=>{const{autoExpand:s,counter:n,onBlur:o,onFocus:l,rows:i=7,placeholder:u=" ",startOpen:c,style:d,value:h,"aria-invalid":x,onChange:g,...v}=a,[f,p]=t.useState(()=>typeof h>"u"?0:"number"==typeof h?String(h).length:h.length),[j,y]=t.useState(!1),m=t.useRef(null),_=r||m;t.useEffect(()=>{const e=_.current;if(e){if(!s)return void(e.style.height="");j||h?(e.style.height="auto",e.style.height=`${e.scrollHeight}px`):e.style.height=""}},[s,_,h,j,f]);const k=n?.maxLength||0,w=k-f;const N=!(!x&&!(n&&f>k?`Du har skrevet ${f-k} tegn for mye`:void 0)),S={overflowX:s?"hidden":void 0};return e.jsxs("div",{className:"jkl-text-area-wrapper","data-invalid":N,"data-has-content":f>0,children:[e.jsx("textarea",{"aria-invalid":N,className:`jkl-text-area__text-area jkl-text-area__text-area--${i}-rows`,onBlur:function(e){y(!1),o&&o(e)},onFocus:function(e){y(!0),l&&l(e)},onChange:function(e){p(e.target.value.length),g&&g(e)},ref:_,style:{...d,...S},placeholder:u,value:h,...v}),n&&e.jsxs("div",{className:"jkl-text-area__counter","aria-hidden":"true",children:[e.jsxs("div",{className:"jkl-text-area__counter-count",children:[f," / ",k]}),!n.hideProgress&&e.jsx("div",{className:"jkl-text-area__counter-progress",style:{"--progress-width":(B=w,b=k,B<=0||0===b?0:100*B/b)+"%"}})]})]});var B,b});a.displayName="BaseTextArea",exports.BaseTextArea=a;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),a=require("./counter.cjs"),r=t.forwardRef((r,s)=>{const{autoExpand:l,counter:n,defaultValue:o,onBlur:u,onFocus:i,rows:c=7,placeholder:d=" ",startOpen:h,style:x,value:f,"aria-invalid":g,onChange:v,...j}=r,p=n?.strategy??"characters",y=typeof f<"u",[_,m]=t.useState(o),[k,w]=t.useState(!1),N=t.useRef(null),B=s||N,S=y?f:_,q=y?{value:f}:{defaultValue:o},C=a.getCounterValue(S,p),T=n?.maxLength||0,V=T-C,b=!(!g&&!!!(n&&C>T));t.useEffect(()=>{const e=B.current;if(e){if(!l)return void(e.style.height="");k||S?(e.style.height="auto",e.style.height=`${e.scrollHeight}px`):e.style.height=""}},[l,B,S,k,C]);const A={overflowX:l?"hidden":void 0};return e.jsxs("div",{className:"jkl-text-area-wrapper","data-invalid":b,"data-has-content":C>0,children:[e.jsx("textarea",{"aria-invalid":b,className:`jkl-text-area__text-area jkl-text-area__text-area--${c}-rows`,onBlur:function(e){w(!1),u&&u(e)},onFocus:function(e){w(!0),i&&i(e)},onChange:function(e){y||m(e.target.value),v&&v(e)},ref:B,style:{...x,...A},placeholder:d,...q,...j}),n&&e.jsxs("div",{className:"jkl-text-area__counter","aria-hidden":"true",children:[e.jsxs("div",{className:"jkl-text-area__counter-count",children:[C," / ",T]}),!n.hideProgress&&e.jsx("div",{className:"jkl-text-area__counter-progress",style:{"--progress-width":(E=V,F=T,E<=0||0===F?0:100*E/F)+"%"}})]})]});var E,F});r.displayName="BaseTextArea",exports.BaseTextArea=r;
2
2
  //# sourceMappingURL=BaseTextArea.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseTextArea.cjs","sources":["../../../../src/components/text-area/BaseTextArea.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { BaseTextAreaProps } from \"./types.js\";\n\nexport const BaseTextArea = forwardRef<HTMLTextAreaElement, BaseTextAreaProps>(\n (props, ref) => {\n const {\n autoExpand,\n counter,\n onBlur,\n onFocus,\n rows = 7,\n placeholder = \" \", // This space intentionally left blank. Denne + rows trengs for å få den ekspanderende effekten.\n startOpen,\n style,\n value,\n \"aria-invalid\": ariaInvalid,\n onChange,\n ...rest\n } = props;\n\n const [counterCurrent, setCounterCurrent] = useState(() => {\n if (typeof value === \"undefined\") {\n return 0;\n }\n\n if (typeof value === \"number\") {\n return String(value).length;\n }\n\n return value.length;\n });\n const [textAreaFocused, setTextAreaFocused] = useState(false);\n const internalRef = useRef<HTMLTextAreaElement>(null);\n const textAreaRef =\n (ref as RefObject<HTMLTextAreaElement>) || internalRef;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: counterCurrent trengs for å lytte på tekstendringer i textarea for auto-expand funksjonalitet\n useEffect(() => {\n const textAreaElement = textAreaRef.current;\n if (textAreaElement) {\n if (!autoExpand) {\n textAreaElement.style.height = \"\";\n return;\n }\n\n if (textAreaFocused || value) {\n textAreaElement.style.height = \"auto\"; // Sett til auto før scrollhøyden leses, sånn at redusering av høyde ved sletting av tekst fungerer\n textAreaElement.style.height = `${textAreaElement.scrollHeight}px`;\n } else {\n textAreaElement.style.height = \"\";\n }\n }\n }, [autoExpand, textAreaRef, value, textAreaFocused, counterCurrent]);\n\n function handleOnFocus(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(true);\n if (onFocus) {\n onFocus(e);\n }\n }\n\n function handleOnBlur(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(false);\n if (onBlur) {\n onBlur(e);\n }\n }\n\n function handleOnChange(e: ChangeEvent<HTMLTextAreaElement>) {\n setCounterCurrent(e.target.value.length);\n if (onChange) {\n onChange(e);\n }\n }\n\n const counterTotal: number = counter?.maxLength || 0;\n const progressCurrent: number = counterTotal - counterCurrent;\n function calculatePercentage(current: number, total: number): number {\n if (current <= 0) {\n return 0;\n }\n return total === 0 ? 0 : (current * 100) / total;\n }\n const counterLabel =\n counter && counterCurrent > counterTotal\n ? `Du har skrevet ${counterCurrent - counterTotal} tegn for mye`\n : undefined;\n\n const invalid = Boolean(ariaInvalid || counterLabel);\n\n const overflowStyle = {\n overflowX: autoExpand ? \"hidden\" : undefined, // Must set overflowX hidden for Firefox https://stackoverflow.com/a/22700700\n } as React.CSSProperties;\n\n return (\n <div\n className=\"jkl-text-area-wrapper\"\n data-invalid={invalid}\n data-has-content={counterCurrent > 0}\n >\n <textarea\n aria-invalid={invalid}\n className={`jkl-text-area__text-area jkl-text-area__text-area--${rows}-rows`}\n onBlur={handleOnBlur}\n onFocus={handleOnFocus}\n onChange={handleOnChange}\n ref={textAreaRef}\n style={{ ...style, ...overflowStyle }}\n placeholder={placeholder}\n value={value}\n {...rest}\n />\n {counter && (\n <div className=\"jkl-text-area__counter\" aria-hidden=\"true\">\n <div className=\"jkl-text-area__counter-count\">\n {counterCurrent}&nbsp;/&nbsp;{counterTotal}\n </div>\n {!counter.hideProgress && (\n <div\n className=\"jkl-text-area__counter-progress\"\n style={{\n [\"--progress-width\" as string]: `${calculatePercentage(\n progressCurrent,\n counterTotal,\n )}%`,\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n },\n);\nBaseTextArea.displayName = \"BaseTextArea\";\n"],"names":["BaseTextArea","forwardRef","props","ref","autoExpand","counter","onBlur","onFocus","rows","placeholder","startOpen","style","value","ariaInvalid","onChange","rest","counterCurrent","setCounterCurrent","useState","String","length","textAreaFocused","setTextAreaFocused","internalRef","useRef","textAreaRef","useEffect","textAreaElement","current","height","scrollHeight","counterTotal","maxLength","progressCurrent","invalid","overflowStyle","overflowX","jsxs","className","children","jsx","e","target","hideProgress","total","displayName"],"mappings":"wIAWaA,EAAeC,EAAAA,WACxB,CAACC,EAAOC,KACJ,MACIC,WAAAA,EACAC,QAAAA,EACAC,OAAAA,EACAC,QAAAA,EACAC,KAAAA,EAAO,EACPC,YAAAA,EAAc,IACdC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,eAAgBC,EAChBC,SAAAA,KACGC,GACHb,GAEGc,EAAgBC,GAAqBC,EAAAA,SAAS,WACtCN,EAAU,IACV,EAGU,iBAAVA,EACAO,OAAOP,GAAOQ,OAGlBR,EAAMQ,SAEVC,EAAiBC,GAAsBJ,EAAAA,UAAS,GACjDK,EAAcC,EAAAA,OAA4B,MAC1CC,EACDtB,GAA0CoB,EAG/CG,EAAAA,UAAU,KACN,MAAMC,EAAkBF,EAAYG,QACpC,GAAID,EAAiB,CACjB,IAAKvB,EAED,YADAuB,EAAgBhB,MAAMkB,OAAS,IAI/BR,GAAmBT,GACnBe,EAAgBhB,MAAMkB,OAAS,OAC/BF,EAAgBhB,MAAMkB,OAAS,GAAGF,EAAgBG,kBAElDH,EAAgBhB,MAAMkB,OAAS,EAEvC,GACD,CAACzB,EAAYqB,EAAab,EAAOS,EAAiBL,IAuBrD,MAAMe,EAAuB1B,GAAS2B,WAAa,EAC7CC,EAA0BF,EAAef,EAO/C,MAKMkB,KAAkBrB,KAJpBR,GAAWW,EAAiBe,EACtB,kBAAkBf,EAAiBe,sBACnC,IAIJI,EAAgB,CAClBC,UAAWhC,EAAa,cAAW,GAGvC,OACIiC,EAAAA,KAAC,MAAA,CACGC,UAAU,wBACV,eAAcJ,EACd,mBAAkBlB,EAAiB,EAEnCuB,SAAA,CAAAC,EAAAA,IAAC,WAAA,CACG,eAAcN,EACdI,UAAW,sDAAsD9B,SACjEF,OA1CZ,SAAsBmC,GAClBnB,GAAmB,GACfhB,GACAA,EAAOmC,EAEf,EAsCYlC,QAlDZ,SAAuBkC,GACnBnB,GAAmB,GACff,GACAA,EAAQkC,EAEhB,EA8CY3B,SArCZ,SAAwB2B,GACpBxB,EAAkBwB,EAAEC,OAAO9B,MAAMQ,QAC7BN,GACAA,EAAS2B,EAEjB,EAiCYtC,IAAKsB,EACLd,MAAO,IAAKA,KAAUwB,GACtB1B,YAAAA,EACAG,MAAAA,KACIG,IAEPV,GACGgC,EAAAA,KAAC,MAAA,CAAIC,UAAU,yBAAyB,cAAY,OAChDC,SAAA,CAAAF,EAAAA,KAAC,MAAA,CAAIC,UAAU,+BACVC,SAAA,CAAAvB,EAAe,MAAce,MAEhC1B,EAAQsC,cACNH,EAAAA,IAAC,MAAA,CACGF,UAAU,kCACV3B,MAAO,CACF,oBA5CAiB,EA6CGK,EA7CcW,EA8Cdb,EA7CxBH,GAAW,GAGE,IAAVgB,EAFI,EAEyB,IAAVhB,EAAiBgB,GAwCa,aA5C5D,IAA6BhB,EAAiBgB,IAyDtD5C,EAAa6C,YAAc"}
1
+ {"version":3,"file":"BaseTextArea.cjs","sources":["../../../../src/components/text-area/BaseTextArea.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { getCounterValue } from \"./counter.js\";\nimport type { BaseTextAreaProps } from \"./types.js\";\n\nexport const BaseTextArea = forwardRef<HTMLTextAreaElement, BaseTextAreaProps>(\n (props, ref) => {\n const {\n autoExpand,\n counter,\n defaultValue,\n onBlur,\n onFocus,\n rows = 7,\n placeholder = \" \", // This space intentionally left blank. Denne + rows trengs for å få den ekspanderende effekten.\n startOpen,\n style,\n value,\n \"aria-invalid\": ariaInvalid,\n onChange,\n ...rest\n } = props;\n\n const strategy = counter?.strategy ?? \"characters\";\n const isControlled = typeof value !== \"undefined\";\n\n const [uncontrolledValue, setUncontrolledValue] =\n useState(defaultValue);\n const [textAreaFocused, setTextAreaFocused] = useState(false);\n const internalRef = useRef<HTMLTextAreaElement>(null);\n const textAreaRef =\n (ref as RefObject<HTMLTextAreaElement>) || internalRef;\n\n // Hvis feltet styres utenfra bruker vi `value`, ellers holder vi styr på verdien selv.\n const textAreaValue = isControlled ? value : uncontrolledValue;\n const textAreaValueProps = isControlled ? { value } : { defaultValue };\n\n const counterCurrent = getCounterValue(textAreaValue, strategy);\n const counterTotal: number = counter?.maxLength || 0;\n const progressCurrent: number = counterTotal - counterCurrent;\n const isOverLimit = Boolean(counter && counterCurrent > counterTotal);\n const invalid = Boolean(ariaInvalid || isOverLimit);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: counterCurrent trengs for å lytte på tekstendringer i textarea for auto-expand funksjonalitet\n useEffect(() => {\n const textAreaElement = textAreaRef.current;\n if (textAreaElement) {\n if (!autoExpand) {\n textAreaElement.style.height = \"\";\n return;\n }\n\n if (textAreaFocused || textAreaValue) {\n textAreaElement.style.height = \"auto\"; // Sett til auto før scrollhøyden leses, sånn at redusering av høyde ved sletting av tekst fungerer\n textAreaElement.style.height = `${textAreaElement.scrollHeight}px`;\n } else {\n textAreaElement.style.height = \"\";\n }\n }\n }, [\n autoExpand,\n textAreaRef,\n textAreaValue,\n textAreaFocused,\n counterCurrent,\n ]);\n\n function handleOnFocus(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(true);\n if (onFocus) {\n onFocus(e);\n }\n }\n\n function handleOnBlur(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(false);\n if (onBlur) {\n onBlur(e);\n }\n }\n\n function handleOnChange(e: ChangeEvent<HTMLTextAreaElement>) {\n if (!isControlled) {\n setUncontrolledValue(e.target.value);\n }\n\n if (onChange) {\n onChange(e);\n }\n }\n function calculatePercentage(current: number, total: number): number {\n if (current <= 0) {\n return 0;\n }\n return total === 0 ? 0 : (current * 100) / total;\n }\n\n const overflowStyle = {\n overflowX: autoExpand ? \"hidden\" : undefined, // Must set overflowX hidden for Firefox https://stackoverflow.com/a/22700700\n } as React.CSSProperties;\n\n return (\n <div\n className=\"jkl-text-area-wrapper\"\n data-invalid={invalid}\n data-has-content={counterCurrent > 0}\n >\n <textarea\n aria-invalid={invalid}\n className={`jkl-text-area__text-area jkl-text-area__text-area--${rows}-rows`}\n onBlur={handleOnBlur}\n onFocus={handleOnFocus}\n onChange={handleOnChange}\n ref={textAreaRef}\n style={{ ...style, ...overflowStyle }}\n placeholder={placeholder}\n {...textAreaValueProps}\n {...rest}\n />\n {counter && (\n <div className=\"jkl-text-area__counter\" aria-hidden=\"true\">\n <div className=\"jkl-text-area__counter-count\">\n {counterCurrent}&nbsp;/&nbsp;{counterTotal}\n </div>\n {!counter.hideProgress && (\n <div\n className=\"jkl-text-area__counter-progress\"\n style={{\n [\"--progress-width\" as string]: `${calculatePercentage(\n progressCurrent,\n counterTotal,\n )}%`,\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n },\n);\nBaseTextArea.displayName = \"BaseTextArea\";\n"],"names":["BaseTextArea","forwardRef","props","ref","autoExpand","counter","defaultValue","onBlur","onFocus","rows","placeholder","startOpen","style","value","ariaInvalid","onChange","rest","strategy","isControlled","uncontrolledValue","setUncontrolledValue","useState","textAreaFocused","setTextAreaFocused","internalRef","useRef","textAreaRef","textAreaValue","textAreaValueProps","counterCurrent","getCounterValue","counterTotal","maxLength","progressCurrent","invalid","useEffect","textAreaElement","current","height","scrollHeight","overflowStyle","overflowX","jsxs","className","children","jsx","e","target","hideProgress","total","displayName"],"mappings":"mKAYaA,EAAeC,EAAAA,WACxB,CAACC,EAAOC,KACJ,MACIC,WAAAA,EACAC,QAAAA,EACAC,aAAAA,EACAC,OAAAA,EACAC,QAAAA,EACAC,KAAAA,EAAO,EACPC,YAAAA,EAAc,IACdC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,eAAgBC,EAChBC,SAAAA,KACGC,GACHd,EAEEe,EAAWZ,GAASY,UAAY,aAChCC,SAAsBL,EAAU,KAE/BM,EAAmBC,GACtBC,EAAAA,SAASf,IACNgB,EAAiBC,GAAsBF,EAAAA,UAAS,GACjDG,EAAcC,EAAAA,OAA4B,MAC1CC,EACDvB,GAA0CqB,EAGzCG,EAAgBT,EAAeL,EAAQM,EACvCS,EAAqBV,EAAe,CAAEL,MAAAA,GAAU,CAAEP,aAAAA,GAElDuB,EAAiBC,EAAAA,gBAAgBH,EAAeV,GAChDc,EAAuB1B,GAAS2B,WAAa,EAC7CC,EAA0BF,EAAeF,EAEzCK,KAAkBpB,OADIT,GAAWwB,EAAiBE,IAIxDI,EAAAA,UAAU,KACN,MAAMC,EAAkBV,EAAYW,QACpC,GAAID,EAAiB,CACjB,IAAKhC,EAED,YADAgC,EAAgBxB,MAAM0B,OAAS,IAI/BhB,GAAmBK,GACnBS,EAAgBxB,MAAM0B,OAAS,OAC/BF,EAAgBxB,MAAM0B,OAAS,GAAGF,EAAgBG,kBAElDH,EAAgBxB,MAAM0B,OAAS,EAEvC,GACD,CACClC,EACAsB,EACAC,EACAL,EACAO,IAiCJ,MAAMW,EAAgB,CAClBC,UAAWrC,EAAa,cAAW,GAGvC,OACIsC,EAAAA,KAAC,MAAA,CACGC,UAAU,wBACV,eAAcT,EACd,mBAAkBL,EAAiB,EAEnCe,SAAA,CAAAC,EAAAA,IAAC,WAAA,CACG,eAAcX,EACdS,UAAW,sDAAsDlC,SACjEF,OApCZ,SAAsBuC,GAClBvB,GAAmB,GACfhB,GACAA,EAAOuC,EAEf,EAgCYtC,QA5CZ,SAAuBsC,GACnBvB,GAAmB,GACff,GACAA,EAAQsC,EAEhB,EAwCY/B,SA/BZ,SAAwB+B,GACf5B,GACDE,EAAqB0B,EAAEC,OAAOlC,OAG9BE,GACAA,EAAS+B,EAEjB,EAwBY3C,IAAKuB,EACLd,MAAO,IAAKA,KAAU4B,GACtB9B,YAAAA,KACIkB,KACAZ,IAEPX,GACGqC,EAAAA,KAAC,MAAA,CAAIC,UAAU,yBAAyB,cAAY,OAChDC,SAAA,CAAAF,EAAAA,KAAC,MAAA,CAAIC,UAAU,+BACVC,SAAA,CAAAf,EAAe,MAAcE,MAEhC1B,EAAQ2C,cACNH,EAAAA,IAAC,MAAA,CACGF,UAAU,kCACV/B,MAAO,CACF,oBAtCAyB,EAuCGJ,EAvCcgB,EAwCdlB,EAvCxBM,GAAW,GAGE,IAAVY,EAFI,EAEyB,IAAVZ,EAAiBY,GAkCa,aAtC5D,IAA6BZ,EAAiBY,IAmDtDjD,EAAakD,YAAc"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=new TextEncoder;exports.getCounterValue=function(t,r="characters"){if(typeof t>"u")return 0;const n="string"==typeof t?t:Array.isArray(t)?t.join(""):String(t);return"bytes"===r?e.encode(n).length:n.length};
2
+ //# sourceMappingURL=counter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter.cjs","sources":["../../../../src/components/text-area/counter.ts"],"sourcesContent":["import type { CounterStrategy } from \"./types.js\";\n\nconst textEncoder = new TextEncoder();\n\nexport function getCounterValue(\n value: string | number | readonly string[] | undefined,\n strategy: CounterStrategy = \"characters\",\n): number {\n if (typeof value === \"undefined\") {\n return 0;\n }\n\n const normalizedValue =\n typeof value === \"string\"\n ? value\n : Array.isArray(value)\n ? value.join(\"\")\n : String(value);\n\n if (strategy === \"bytes\") {\n return textEncoder.encode(normalizedValue).length;\n }\n\n return normalizedValue.length;\n}\n"],"names":["textEncoder","TextEncoder","value","strategy","normalizedValue","Array","isArray","join","String","encode","length"],"mappings":"gFAEA,MAAMA,EAAc,IAAIC,oCAEjB,SACHC,EACAC,EAA4B,cAE5B,UAAWD,EAAU,IACjB,OAAO,EAGX,MAAME,EACe,iBAAVF,EACDA,EACAG,MAAMC,QAAQJ,GACZA,EAAMK,KAAK,IACXC,OAAON,GAEnB,MAAiB,UAAbC,EACOH,EAAYS,OAAOL,GAAiBM,OAGxCN,EAAgBM,MAC3B"}
@@ -0,0 +1,2 @@
1
+ import { CounterStrategy } from './types.cjs';
2
+ export declare function getCounterValue(value: string | number | readonly string[] | undefined, strategy?: CounterStrategy): number;
@@ -1,8 +1,28 @@
1
1
  import { TextareaHTMLAttributes } from 'react';
2
2
  import { InputGroupProps } from '../input-group/types.cjs';
3
+ export type CounterStrategy = "characters" | "bytes";
3
4
  export type Counter = {
4
- /** Antall tegn før telleren når maksimum og vi viser en feilmelding */
5
+ /**
6
+ * Maksverdi for telleren.
7
+ *
8
+ * Enheten avhenger av `strategy`:
9
+ * - `"characters"`: antall tegn
10
+ * - `"bytes"`: antall UTF-8-bytes
11
+ */
5
12
  maxLength: number;
13
+ /**
14
+ * Bestemmer hva telleren måler.
15
+ *
16
+ * - "characters" teller tekst på samme måte som i dag og er standard
17
+ * - "bytes" teller antall UTF-8-bytes, for usecaser der backend eller API
18
+ * håndhever en bytegrense
19
+ *
20
+ * Unngå å kombinere `strategy="bytes"` med native `maxLength` på
21
+ * `<textarea>`, siden nettleseren fortsatt håndhever `maxLength` som tegn.
22
+ *
23
+ * @default "characters"
24
+ */
25
+ strategy?: CounterStrategy;
6
26
  /**
7
27
  * Med teller vises en progress-bar i bunnen av tekstfeltet som krymper
8
28
  * ned fra 100% (null tegn skrevet) til 0% (maks antall tegn skrevet).
@@ -1,2 +1,2 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as a}from"../../../clsx-BeLtu-UY.js";import{d as r,g as o}from"../../../utils-CcE6HjQp.js";import{forwardRef as n,useState as l,useRef as s,useCallback as i}from"react";import{flushSync as u}from"react-dom";import{formatDateString as d}from"../../utilities/formatters/date/formatDate.js";import{IconButton as c}from"../icon-button/IconButton.js";import{CalendarIcon as p}from"../icon/icons/CalendarIcon.js";import{InputGroup as m}from"../input-group/InputGroup.js";import{Popover as f}from"../popover/Popover.js";import{BaseTextInput as v}from"../text-input/BaseTextInput.js";import{Calendar as D}from"./internal/Calendar.js";import{parseDateString as h,formatInput as b}from"./utils.js";import{isWithinLowerBound as g,isWithinUpperBound as k}from"./validation.js";const j=n((n,j)=>{const{"data-testautoid":y,id:L,className:w="",label:x="Velg dato",labelProps:C,defaultValue:I,defaultShow:O=!1,value:P,disableBeforeDate:T,disableAfterDate:B,yearsToShow:E,name:_,helpLabel:S,errorLabel:N,invalid:R,days:U,months:V,monthLabel:F,yearLabel:K,placeholder:W="dd.mm.åååå",width:A="11.25rem",onChange:G,onBlur:H,onFocus:M,onKeyDown:q,action:$,showCalendarLabel:z="Åpne kalender",hideCalendarLabel:J="Lukk kalender",supportLabelProps:Q,tooltip:X,textInputProps:Y,description:Z,...ee}=n;"production"!==process.env.NODE_ENV&&P&&I&&console.warn("DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.");const te=h(T),ae=te?r(te).startOf("day").toDate():void 0,re=h(B),oe=re?r(re).startOf("day").toDate():void 0,[ne,le]=l(o(P,I,ae,oe)),[se,ie]=l(null),[ue,de]=l(O),ce=s(null),pe=s(null),me=s(null),fe=s(null),ve=i(e=>{fe.current=e,j&&("function"==typeof j?j(e):j.current=e)},[j]),De=i(e=>{M&&pe.current&&(pe.current.contains(e.relatedTarget)||M(e,ne,{error:se,value:e.target.value}))},[M,ne,se]),he=i(e=>{H&&H(e,ne,{error:se,value:e.target.value})},[H,ne,se]),be=i(e=>{"Escape"===e.key&&(de(!1),e.preventDefault(),e.stopPropagation()),$?.onKeyDown&&$.onKeyDown(e)},[$]),ge=i(e=>{const t=e.currentTarget.value,a=(e=>{const t=e.replace(/\D/g,""),a=d(t,{partial:!0}),r=e.replace(/\D+$/,""),o=8===t.length?d(t):e,n=h(o)?o:null,l=e!==t&&r===a&&void 0===h(e)&&null===n;return n??(l?t:e)})(t);a!==t&&((e,t)=>{const a=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set;a?a.call(e,t):e.value=t})(e.currentTarget,a);const{date:r,error:o}=(({value:e,minDate:t,maxDate:a})=>{if(!e)return{date:null,error:null};const r=h(e);return r?t&&!g(r,t)?{date:r,error:"OUTSIDE_LOWER_BOUND"}:a&&!k(r,a)?{date:r,error:"OUTSIDE_UPPER_BOUND"}:{date:r,error:null}:{date:null,error:"WRONG_FORMAT"}})({value:a,minDate:ae,maxDate:oe});r&&!o&&de(!1),ie(o),le(r),G&&G(e,r,{error:o,value:a})},[G,ae,oe]),ke=i(e=>{u(()=>{de(!ue)});const t=ce.current,a=t&&t.querySelector('[aria-pressed="true"]');window.requestAnimationFrame(()=>a?.focus()),$?.onClick&&$.onClick(e)},[ue,$]),je=i(({date:e})=>{if(de(!1),le(e),fe.current){const t=fe.current;t.value=b(e);const a=document.createEvent("HTMLEvents");a.initEvent("input",!0,!1),t.dispatchEvent(a),t.focus(),G&&G(a,e,{error:null,value:t.value})}},[G]),ye=i(e=>{e.preventDefault(),de(!1),me.current?.focus()},[]);return e(m,{id:L,className:a("jkl-datepicker",w),...ee,ref:pe,label:x,labelProps:C,helpLabel:S,errorLabel:N,supportLabelProps:Q,tooltip:X,description:Z,render:a=>e(v,{"data-focused":ue?"true":void 0,ref:ve,"data-testid":"jkl-datepicker__input","data-testautoid":y,className:"jkl-datepicker__input",name:_,defaultValue:I,value:P,type:"text",placeholder:W,width:A,onFocus:De,onBlur:he,onChange:ge,actionButton:t(f,{positionReference:fe,open:ue,onOpenChange:()=>de(!ue),offset:8,children:[e(f.Trigger,{...$,"data-testid":"jkl-datepicker__trigger",className:"jkl-text-input-action-button",title:ue?J:z,tabIndex:0,onClick:ke,onKeyDown:be,asChild:!0,children:e(c,{children:e(p,{})})}),e(f.Content,{initialFocus:-1,padding:24,children:e(D,{ref:ce,date:ne,minDate:ae,maxDate:oe,days:U,months:V,monthLabel:F,yearLabel:K,yearsToShow:E,onDateSelected:je,onTabOutside:ye})})]}),...Y,...a,"aria-invalid":R||!!N})})});j.displayName="DatePicker";export{j as DatePicker};
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as r}from"../../../clsx-BeLtu-UY.js";import{d as a,g as o}from"../../../utils-CcE6HjQp.js";import{forwardRef as n,useState as l,useRef as s,useCallback as i}from"react";import{flushSync as u}from"react-dom";import{formatDateString as c}from"../../utilities/formatters/date/formatDate.js";import{IconButton as d}from"../icon-button/IconButton.js";import{CalendarIcon as p}from"../icon/icons/CalendarIcon.js";import{InputGroup as m}from"../input-group/InputGroup.js";import{Popover as f}from"../popover/Popover.js";import{BaseTextInput as v}from"../text-input/BaseTextInput.js";import{Calendar as D}from"./internal/Calendar.js";import{parseDateString as h,formatInput as b}from"./utils.js";import{isWithinLowerBound as g,isWithinUpperBound as k}from"./validation.js";const j=n((n,j)=>{const{"data-testautoid":y,id:L,className:w="",label:x="Velg dato",labelProps:C,defaultValue:I,defaultShow:O=!1,value:P,disableBeforeDate:T,disableAfterDate:B,yearsToShow:E,name:_,helpLabel:S,errorLabel:N,invalid:R,days:U,months:V,monthLabel:F,yearLabel:K,placeholder:W="dd.mm.åååå",width:A="11.25rem",onChange:G,onBlur:H,onFocus:M,onKeyDown:q,action:$,showCalendarLabel:z="Åpne kalender",hideCalendarLabel:J="Lukk kalender",supportLabelProps:Q,tooltip:X,textInputProps:Y,description:Z,...ee}=n;"production"!==process.env.NODE_ENV&&P&&I&&console.warn("DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.");const te=h(T),re=te?a(te).startOf("day").toDate():void 0,ae=h(B),oe=ae?a(ae).startOf("day").toDate():void 0,[ne,le]=l(o(P,I,re,oe)),[se,ie]=l(null),[ue,ce]=l(O),de=s(null),pe=s(null),me=s(null),fe=s(null),ve=s(!1),De=i(e=>{fe.current=e,j&&("function"==typeof j?j(e):j.current=e)},[j]),he=i(e=>{M&&pe.current&&(pe.current.contains(e.relatedTarget)||M(e,ne,{error:se,value:e.target.value}))},[M,ne,se]),be=i(e=>{H&&H(e,ne,{error:se,value:e.target.value})},[H,ne,se]),ge=i(e=>{"Escape"===e.key&&(ce(!1),e.preventDefault(),e.stopPropagation()),$?.onKeyDown&&$.onKeyDown(e)},[$]),ke=i(e=>{const t=e.currentTarget.value,r=((e,t)=>{const r=e.replace(/\D/g,""),a=c(r,{partial:!0}),o=e.replace(/\D+$/,""),n=8===r.length?c(r):e,l=h(n)?n:null,s=t&&e!==r&&o===a&&void 0===h(e)&&null===l;return l??(s?r:e)})(t,ve.current);r!==t&&((e,t)=>{const r=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set;r?r.call(e,t):e.value=t})(e.currentTarget,r);const a=t.replace(/\D/g,"");ve.current=t===a&&r===c(a)&&r!==t&&void 0!==h(r);const{date:o,error:n}=(({value:e,minDate:t,maxDate:r})=>{if(!e)return{date:null,error:null};const a=h(e);return a?t&&!g(a,t)?{date:a,error:"OUTSIDE_LOWER_BOUND"}:r&&!k(a,r)?{date:a,error:"OUTSIDE_UPPER_BOUND"}:{date:a,error:null}:{date:null,error:"WRONG_FORMAT"}})({value:r,minDate:re,maxDate:oe});o&&!n&&ce(!1),ie(n),le(o),G&&G(e,o,{error:n,value:r})},[G,re,oe]),je=i(e=>{u(()=>{ce(!ue)});const t=de.current,r=t&&t.querySelector('[aria-pressed="true"]');window.requestAnimationFrame(()=>r?.focus()),$?.onClick&&$.onClick(e)},[ue,$]),ye=i(({date:e})=>{if(ce(!1),le(e),fe.current){const t=fe.current;ve.current=!1,t.value=b(e);const r=document.createEvent("HTMLEvents");r.initEvent("input",!0,!1),t.dispatchEvent(r),t.focus(),G&&G(r,e,{error:null,value:t.value})}},[G]),Le=i(e=>{e.preventDefault(),ce(!1),me.current?.focus()},[]);return e(m,{id:L,className:r("jkl-datepicker",w),...ee,ref:pe,label:x,labelProps:C,helpLabel:S,errorLabel:N,supportLabelProps:Q,tooltip:X,description:Z,render:r=>e(v,{"data-focused":ue?"true":void 0,ref:De,"data-testid":"jkl-datepicker__input","data-testautoid":y,className:"jkl-datepicker__input",name:_,defaultValue:I,value:P,type:"text",placeholder:W,width:A,onFocus:he,onBlur:be,onChange:ke,actionButton:t(f,{positionReference:fe,open:ue,onOpenChange:()=>ce(!ue),offset:8,children:[e(f.Trigger,{...$,"data-testid":"jkl-datepicker__trigger",className:"jkl-text-input-action-button",title:ue?J:z,tabIndex:0,onClick:je,onKeyDown:ge,asChild:!0,children:e(d,{children:e(p,{})})}),e(f.Content,{initialFocus:-1,padding:24,children:e(D,{ref:de,date:ne,minDate:re,maxDate:oe,days:U,months:V,monthLabel:F,yearLabel:K,yearsToShow:E,onDateSelected:ye,onTabOutside:Le})})]}),...Y,...r,"aria-invalid":R||!!N})})});j.displayName="DatePicker";export{j as DatePicker};
2
2
  //# sourceMappingURL=DatePicker.js.map