@fremtind/jokul 0.27.6 → 0.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/build/build-stats.html +1 -1
  2. package/build/cjs/components/file-input/File.cjs +2 -0
  3. package/build/cjs/components/file-input/File.cjs.map +1 -0
  4. package/build/cjs/components/file-input/File.d.cts +15 -0
  5. package/build/cjs/components/file-input/FileInput.cjs +2 -0
  6. package/build/cjs/components/file-input/FileInput.cjs.map +1 -0
  7. package/build/cjs/components/file-input/FileInput.d.cts +26 -0
  8. package/build/cjs/components/file-input/index.cjs +2 -0
  9. package/build/cjs/components/file-input/index.cjs.map +1 -0
  10. package/build/cjs/components/file-input/index.d.cts +4 -0
  11. package/build/cjs/components/file-input/internal/Dropzone.cjs +2 -0
  12. package/build/cjs/components/file-input/internal/Dropzone.cjs.map +1 -0
  13. package/build/cjs/components/file-input/internal/Dropzone.d.cts +6 -0
  14. package/build/cjs/components/file-input/internal/Input.cjs +2 -0
  15. package/build/cjs/components/file-input/internal/Input.cjs.map +1 -0
  16. package/build/cjs/components/file-input/internal/Input.d.cts +8 -0
  17. package/build/cjs/components/file-input/internal/Thumbnail.cjs +2 -0
  18. package/build/cjs/components/file-input/internal/Thumbnail.cjs.map +1 -0
  19. package/build/cjs/components/file-input/internal/Thumbnail.d.cts +11 -0
  20. package/build/cjs/components/file-input/internal/fileInputContext.cjs +2 -0
  21. package/build/cjs/components/file-input/internal/fileInputContext.cjs.map +1 -0
  22. package/build/cjs/components/file-input/internal/fileInputContext.d.cts +15 -0
  23. package/build/cjs/components/file-input/internal/validateFile.cjs +2 -0
  24. package/build/cjs/components/file-input/internal/validateFile.cjs.map +1 -0
  25. package/build/cjs/components/file-input/internal/validateFile.d.cts +2 -0
  26. package/build/cjs/components/file-input/types.cjs +2 -0
  27. package/build/cjs/components/file-input/types.cjs.map +1 -0
  28. package/build/cjs/components/file-input/types.d.cts +11 -0
  29. package/build/cjs/components/file-input/utils.cjs +2 -0
  30. package/build/cjs/components/file-input/utils.cjs.map +1 -0
  31. package/build/cjs/components/file-input/utils.d.cts +11 -0
  32. package/build/cjs/components/select/Select.cjs +1 -1
  33. package/build/cjs/components/select/Select.cjs.map +1 -1
  34. package/build/cjs/core/tokens.cjs +1 -1
  35. package/build/cjs/core/tokens.cjs.map +1 -1
  36. package/build/cjs/core/tokens.d.cts +5 -1
  37. package/build/es/components/file-input/File.d.ts +15 -0
  38. package/build/es/components/file-input/File.js +2 -0
  39. package/build/es/components/file-input/File.js.map +1 -0
  40. package/build/es/components/file-input/FileInput.d.ts +26 -0
  41. package/build/es/components/file-input/FileInput.js +2 -0
  42. package/build/es/components/file-input/FileInput.js.map +1 -0
  43. package/build/es/components/file-input/index.d.ts +4 -0
  44. package/build/es/components/file-input/index.js +2 -0
  45. package/build/es/components/file-input/index.js.map +1 -0
  46. package/build/es/components/file-input/internal/Dropzone.d.ts +6 -0
  47. package/build/es/components/file-input/internal/Dropzone.js +2 -0
  48. package/build/es/components/file-input/internal/Dropzone.js.map +1 -0
  49. package/build/es/components/file-input/internal/Input.d.ts +8 -0
  50. package/build/es/components/file-input/internal/Input.js +2 -0
  51. package/build/es/components/file-input/internal/Input.js.map +1 -0
  52. package/build/es/components/file-input/internal/Thumbnail.d.ts +11 -0
  53. package/build/es/components/file-input/internal/Thumbnail.js +2 -0
  54. package/build/es/components/file-input/internal/Thumbnail.js.map +1 -0
  55. package/build/es/components/file-input/internal/fileInputContext.d.ts +15 -0
  56. package/build/es/components/file-input/internal/fileInputContext.js +2 -0
  57. package/build/es/components/file-input/internal/fileInputContext.js.map +1 -0
  58. package/build/es/components/file-input/internal/validateFile.d.ts +2 -0
  59. package/build/es/components/file-input/internal/validateFile.js +2 -0
  60. package/build/es/components/file-input/internal/validateFile.js.map +1 -0
  61. package/build/es/components/file-input/types.d.ts +11 -0
  62. package/build/es/components/file-input/types.js +2 -0
  63. package/build/es/components/file-input/types.js.map +1 -0
  64. package/build/es/components/file-input/utils.d.ts +11 -0
  65. package/build/es/components/file-input/utils.js +2 -0
  66. package/build/es/components/file-input/utils.js.map +1 -0
  67. package/build/es/components/select/Select.js +1 -1
  68. package/build/es/components/select/Select.js.map +1 -1
  69. package/build/es/core/tokens.d.ts +5 -1
  70. package/build/es/core/tokens.js +1 -1
  71. package/build/es/core/tokens.js.map +1 -1
  72. package/package.json +12 -2
  73. package/styles/components/accordion/accordion.css +1 -1
  74. package/styles/components/breadcrumb/breadcrumb.css +1 -1
  75. package/styles/components/button/button.css +3 -3
  76. package/styles/components/button/button.min.css +1 -1
  77. package/styles/components/card/card.css +1 -1
  78. package/styles/components/checkbox/checkbox.css +5 -5
  79. package/styles/components/checkbox/checkbox.min.css +1 -1
  80. package/styles/components/combobox/combobox.css +1 -1
  81. package/styles/components/cookie-consent/cookie-consent.css +1 -1
  82. package/styles/components/datepicker/datepicker.css +1 -1
  83. package/styles/components/description-list/description-list.css +1 -1
  84. package/styles/components/expander/expander.css +1 -1
  85. package/styles/components/feedback/feedback.css +3 -3
  86. package/styles/components/feedback/feedback.min.css +1 -1
  87. package/styles/components/file-input/_file.scss +172 -0
  88. package/styles/components/file-input/_index.scss +1 -0
  89. package/styles/components/file-input/file-input.css +290 -0
  90. package/styles/components/file-input/file-input.min.css +1 -0
  91. package/styles/components/file-input/file-input.scss +119 -0
  92. package/styles/components/icon/icon.css +1 -1
  93. package/styles/components/icon-button/icon-button.css +1 -1
  94. package/styles/components/image/image.css +1 -1
  95. package/styles/components/input-group/input-group.css +3 -3
  96. package/styles/components/input-group/input-group.min.css +1 -1
  97. package/styles/components/link/link.css +1 -1
  98. package/styles/components/link-list/link-list.css +1 -1
  99. package/styles/components/list/list.css +1 -1
  100. package/styles/components/loader/loader.css +7 -7
  101. package/styles/components/loader/loader.min.css +1 -1
  102. package/styles/components/loader/skeleton-loader.css +6 -6
  103. package/styles/components/loader/skeleton-loader.min.css +1 -1
  104. package/styles/components/logo/logo.css +1 -1
  105. package/styles/components/menu/menu.css +1 -1
  106. package/styles/components/message/message.css +3 -3
  107. package/styles/components/message/message.min.css +1 -1
  108. package/styles/components/modal/modal.css +1 -1
  109. package/styles/components/pagination/pagination.css +1 -1
  110. package/styles/components/popover/popover.css +1 -1
  111. package/styles/components/progress-bar/progress-bar.css +3 -3
  112. package/styles/components/progress-bar/progress-bar.min.css +1 -1
  113. package/styles/components/radio-button/radio-button.css +3 -3
  114. package/styles/components/radio-button/radio-button.min.css +1 -1
  115. package/styles/components/radio-panel/radio-panel.css +3 -3
  116. package/styles/components/radio-panel/radio-panel.min.css +1 -1
  117. package/styles/components/select/select.css +55 -145
  118. package/styles/components/select/select.min.css +1 -1
  119. package/styles/components/select/select.scss +62 -119
  120. package/styles/components/summary-table/summary-table.css +1 -1
  121. package/styles/components/system-message/system-message.css +3 -3
  122. package/styles/components/system-message/system-message.min.css +1 -1
  123. package/styles/components/table/table.css +1 -1
  124. package/styles/components/tabs/tabs.css +1 -1
  125. package/styles/components/tag/tag.css +1 -1
  126. package/styles/components/text-input/text-input.css +3 -3
  127. package/styles/components/text-input/text-input.min.css +1 -1
  128. package/styles/components/text-input/text-input.scss +1 -1
  129. package/styles/components/toast/toast.css +5 -5
  130. package/styles/components/toast/toast.min.css +1 -1
  131. package/styles/components/toggle-switch/toggle-switch.css +1 -1
  132. package/styles/components/tooltip/tooltip.css +1 -1
  133. package/styles/core/_color-tokens.scss +3 -1
  134. package/styles/core/_legacy-tokens.scss +1 -1
  135. package/styles/core/_tokens.scss +1 -1
  136. package/styles/core/core.css +8 -4
  137. package/styles/core/core.min.css +1 -1
  138. package/styles/core/jkl/_legacy-tokens.scss +1 -1
  139. package/styles/core/jkl/_tokens.scss +2 -1
  140. package/styles/styles.css +91 -181
  141. package/styles/styles.min.css +1 -1
  142. package/styles/vind/vind.css +1 -1
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),i=require("classnames");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"),require("../icon/icons/PlusIcon.cjs"),require("../icon/icons/QuestionIcon.cjs"),require("../icon/icons/RedCrossIcon.cjs"),require("../icon/icons/SearchIcon.cjs");const c=require("../icon/icons/SuccessIcon.cjs");require("../icon/icons/WarningIcon.cjs"),require("../icon/icons/MinusIcon.cjs"),require("../icon/icons/ThumbDownIcon.cjs"),require("../icon/icons/ThumbUpIcon.cjs");const n=require("../icon/icons/TrashCanIcon.cjs");require("../icon/icons/PenIcon.cjs");const o=require("../icon-button/IconButton.cjs"),r=require("../input-group/SupportLabel.cjs"),s=require("../../hooks/useId/useId.cjs"),l=require("../../utilities/formatters/bytes/formatBytes.cjs"),t=require("./internal/fileInputContext.cjs"),u=require("./internal/Thumbnail.cjs");exports.File=a=>{const{children:j,fileName:q,fileType:I,fileSize:p,path:d,file:h,supportLabel:m,supportLabelType:f,state:b,onRemove:x}=a,k=s.useId("jkl-file-preview"),_=k+"-support",C=t.useFileInputContext(),w=d?"a":"div",v="error"===f||"warning"===f,g="success"===f,y=e.jsxs("div",{id:k,className:"jkl-file",children:[e.jsxs(w,{className:i("jkl-file__content",{"jkl-file__content--error":"error"===f,"jkl-file__content--warning":"warning"===f}),href:d,target:d?"_blank":void 0,children:[e.jsx(u.Thumbnail,{fileName:q,fileType:I,file:h,path:d,state:b,children:j}),e.jsxs("div",{children:[e.jsx("p",{className:"jkl-file__name",children:q}),e.jsxs("p",{className:"jkl-file__description",children:[e.jsx("span",{children:l.formatBytes(p)}),v||g?g?e.jsx(c.SuccessIcon,{variant:"small","aria-label":"Filen ble lastet opp uten feil"}):null:e.jsx(r.SupportLabel,{className:"jkl-file__support-label jkl-body",id:_,label:m,labelType:f})]}),m&&v&&e.jsx(r.SupportLabel,{className:"jkl-file__support-label",id:_,label:m,labelType:f})]})]}),x&&e.jsx(o.IconButton,{className:"jkl-file__delete",onClick:x,title:`Fjern ${q}`,children:e.jsx(n.TrashCanIcon,{})})]});return C?e.jsx("li",{children:y}):y};
2
+ //# sourceMappingURL=File.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"File.cjs","sources":["../../../../src/components/file-input/File.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport React, { FC, MouseEvent } from \"react\";\nimport { TrashCanIcon, SuccessIcon } from \"../../components/icon/index.js\";\nimport { IconButton } from \"../../components/icon-button/IconButton.js\";\nimport { SupportLabel } from \"../../components/input-group/SupportLabel.js\";\nimport { type WithOptionalChildren } from \"../../core/types.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { formatBytes } from \"../../utilities/formatters/bytes/formatBytes.js\";\nimport { useFileInputContext } from \"./internal/fileInputContext.js\";\nimport { Thumbnail } from \"./internal/Thumbnail.js\";\nimport { FileInputFileState } from \"./types.js\";\n\nexport interface FileProps extends WithOptionalChildren {\n fileName: string;\n fileType: string;\n fileSize: number;\n path?: string;\n file?: File;\n supportLabel?: string;\n supportLabelType?: \"help\" | \"error\" | \"warning\" | \"success\";\n state?: FileInputFileState;\n onRemove?: (e: MouseEvent<HTMLButtonElement>) => void;\n}\n\nexport const File: FC<FileProps> = (props) => {\n const {\n children,\n fileName,\n fileType,\n fileSize,\n path,\n file,\n supportLabel,\n supportLabelType,\n state,\n onRemove,\n } = props;\n\n const id = useId(\"jkl-file-preview\");\n const supportId = id + \"-support\";\n\n const context = useFileInputContext();\n\n const Component = path ? \"a\" : \"div\";\n\n const hasErrorOrWarning =\n supportLabelType === \"error\" || supportLabelType === \"warning\";\n const hasSuccess = supportLabelType === \"success\";\n\n const renderFeedbackElement = () => {\n if (!hasErrorOrWarning && !hasSuccess) {\n return (\n <SupportLabel\n className=\"jkl-file__support-label jkl-body\"\n id={supportId}\n label={supportLabel}\n labelType={supportLabelType}\n />\n );\n }\n\n if (hasSuccess)\n return (\n <SuccessIcon\n variant=\"small\"\n aria-label=\"Filen ble lastet opp uten feil\"\n />\n );\n\n return null;\n };\n\n const fileComponent = (\n <div id={id} className=\"jkl-file\">\n <Component\n className={cn(\"jkl-file__content\", {\n \"jkl-file__content--error\": supportLabelType === \"error\",\n \"jkl-file__content--warning\":\n supportLabelType === \"warning\",\n })}\n href={path}\n target={path ? \"_blank\" : undefined}\n >\n <Thumbnail\n fileName={fileName}\n fileType={fileType}\n file={file}\n path={path}\n state={state}\n >\n {children}\n </Thumbnail>\n <div>\n <p className=\"jkl-file__name\">{fileName}</p>\n <p className=\"jkl-file__description\">\n <span>{formatBytes(fileSize)}</span>\n {renderFeedbackElement()}\n </p>\n {supportLabel && hasErrorOrWarning && (\n <SupportLabel\n className=\"jkl-file__support-label\"\n id={supportId}\n label={supportLabel}\n labelType={supportLabelType}\n />\n )}\n </div>\n </Component>\n {onRemove && (\n <IconButton\n className=\"jkl-file__delete\"\n onClick={onRemove}\n title={`Fjern ${fileName}`}\n >\n <TrashCanIcon />\n </IconButton>\n )}\n </div>\n );\n\n return context ? <li>{fileComponent}</li> : fileComponent;\n};\n"],"names":["props","children","fileName","fileType","fileSize","path","file","supportLabel","supportLabelType","state","onRemove","id","useId","supportId","context","useFileInputContext","Component","hasErrorOrWarning","hasSuccess","fileComponent","jsxs","className","cn","href","target","jsx","Thumbnail","formatBytes","SuccessIcon","variant","SupportLabel","label","labelType","IconButton","onClick","title","TrashCanIcon"],"mappings":"i5DAwBoCA,IAC1B,MACFC,SAAAA,EACAC,SAAAA,EACAC,SAAAA,EACAC,SAAAA,EACAC,KAAAA,EACAC,KAAAA,EACAC,aAAAA,EACAC,iBAAAA,EACAC,MAAAA,EACAC,SAAAA,GACAV,EAEEW,EAAKC,QAAM,oBACXC,EAAYF,EAAK,WAEjBG,EAAUC,EAAAA,sBAEVC,EAAYX,EAAO,IAAM,MAEzBY,EACmB,UAArBT,GAAqD,YAArBA,EAC9BU,EAAkC,YAArBV,EAyBbW,EACFC,EAAAA,KAAC,MAAI,CAAAT,GAAAA,EAAQU,UAAU,WACnBpB,SAAA,CAAAmB,EAAAA,KAACJ,EAAA,CACGK,UAAWC,EAAG,oBAAqB,CAC/B,2BAAiD,UAArBd,EAC5B,6BACyB,YAArBA,IAERe,KAAMlB,EACNmB,OAAQnB,EAAO,cAAW,EAE1BJ,SAAA,CAAAwB,EAAAA,IAACC,EAAAA,UAAA,CACGxB,SAAAA,EACAC,SAAAA,EACAG,KAAAA,EACAD,KAAAA,EACAI,MAAAA,EAECR,SAAAA,WAEJ,MACG,CAAAA,SAAA,CAACwB,EAAAA,IAAA,IAAA,CAAEJ,UAAU,iBAAkBpB,SAASC,IACxCkB,EAAAA,KAAC,IAAE,CAAAC,UAAU,wBACTpB,SAAA,CAACwB,EAAAA,IAAA,OAAA,CAAMxB,SAAY0B,EAAAA,YAAAvB,KA7C9Ba,GAAsBC,EAWvBA,EAEIO,EAAAA,IAACG,EAAAA,YAAA,CACGC,QAAQ,QACR,aAAW,mCAIhB,KAjBCJ,EAAAA,IAACK,EAAAA,aAAA,CACGT,UAAU,mCACVV,GAAIE,EACJkB,MAAOxB,EACPyB,UAAWxB,OA0CVD,GAAgBU,GACbQ,EAAAA,IAACK,EAAAA,aAAA,CACGT,UAAU,0BACVV,GAAIE,EACJkB,MAAOxB,EACPyB,UAAWxB,UAK1BE,GACGe,EAAAA,IAACQ,EAAAA,WAAA,CACGZ,UAAU,mBACVa,QAASxB,EACTyB,MAAO,SAASjC,IAEhBD,eAACmC,EAAaA,aAAA,SAM9B,OAAOtB,EAAUW,EAAAA,IAAC,KAAI,CAAAxB,SAAAkB,IAAsBA"}
@@ -0,0 +1,15 @@
1
+ import { FC, MouseEvent } from 'react';
2
+ import { WithOptionalChildren } from '../../core/types.cjs';
3
+ import { FileInputFileState } from './types.cjs';
4
+ export interface FileProps extends WithOptionalChildren {
5
+ fileName: string;
6
+ fileType: string;
7
+ fileSize: number;
8
+ path?: string;
9
+ file?: File;
10
+ supportLabel?: string;
11
+ supportLabelType?: "help" | "error" | "warning" | "success";
12
+ state?: FileInputFileState;
13
+ onRemove?: (e: MouseEvent<HTMLButtonElement>) => void;
14
+ }
15
+ export declare const File: FC<FileProps>;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("classnames"),i=require("react"),t=require("../input-group/FieldGroup.cjs"),n=require("./internal/Dropzone.cjs"),s=require("./internal/fileInputContext.cjs"),r=require("./internal/Input.cjs"),a=i.forwardRef(((i,a)=>{const{accept:c,className:u,children:o,id:p,value:d,density:j,multiple:f=!0,maxSizeBytes:x,onChange:m,variant:h,...g}=i,y=d.length>0;return"small"===h?e.jsx(s.FileInputContextProvider,{context:{accept:c,onChange:m,maxSizeBytes:x,files:d},children:e.jsxs(t.FieldGroup,{className:l("jkl-file-input","jkl-file-input--small",u,{"jkl-file-input--has-files":y}),"data-layout-density":j||"compact",...g,children:[e.jsx(n.Dropzone,{children:e.jsx("div",{className:"jkl-file-input__call-to-action",children:e.jsx(r.Input,{id:p,label:"Legg til fil",multiple:f,ref:a})})}),d.length>0&&e.jsx("ul",{className:"jkl-file-input__files",children:o})]})}):e.jsx(s.FileInputContextProvider,{context:{accept:c,onChange:m,maxSizeBytes:x,files:d},children:e.jsx(t.FieldGroup,{className:l("jkl-file-input",u,{"jkl-file-input--has-files":y}),"data-layout-density":j,...g,children:e.jsxs(n.Dropzone,{children:[d.length>0&&e.jsx("ul",{className:"jkl-file-input__files",children:o}),e.jsx("div",{className:"jkl-file-input__call-to-action",children:e.jsx(r.Input,{id:p,label:f&&y?"Legg til flere filer":"Legg til fil",multiple:f,ref:a})})]})})})}));a.displayName="FileInput",exports.FileInput=a;
2
+ //# sourceMappingURL=FileInput.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileInput.cjs","sources":["../../../../src/components/file-input/FileInput.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport React, { forwardRef } from \"react\";\nimport {\n FieldGroup,\n type FieldGroupProps,\n} from \"../../components/input-group/FieldGroup.js\";\nimport { type Density } from \"../../core/types.js\";\nimport { Dropzone } from \"./internal/Dropzone.js\";\nimport { FileInputContextProvider } from \"./internal/fileInputContext.js\";\nimport { Input } from \"./internal/Input.js\";\nimport { FileInputFile } from \"./types.js\";\n\nexport interface FileInputProps extends Omit<FieldGroupProps, \"onChange\"> {\n className?: string;\n id?: string;\n density?: Density;\n /**\n * En string som begrenser hvilke filtyper som kan velges.\n *\n * Flere filtyper kan defineres som en kommaseparert liste.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept\n */\n accept?: \"image/*\" | \".pdf\" | \"image/*,.pdf\" | HTMLInputElement[\"accept\"];\n maxSizeBytes?: number;\n /**\n * @default true\n */\n multiple?: boolean;\n value: FileInputFile[];\n variant?: \"flexible\" | \"small\";\n onChange: (\n e:\n | React.ChangeEvent<HTMLInputElement>\n | React.DragEvent<HTMLDivElement>,\n files: FileInputFile[],\n ) => void;\n}\n\nexport const FileInput = forwardRef<HTMLInputElement, FileInputProps>(\n (props, ref) => {\n const {\n accept,\n className,\n children,\n id,\n value,\n density,\n multiple = true,\n maxSizeBytes,\n onChange,\n variant,\n ...rest\n } = props;\n\n const hasFiles = value.length > 0;\n\n if (variant === \"small\") {\n return (\n <FileInputContextProvider\n context={{ accept, onChange, maxSizeBytes, files: value }}\n >\n <FieldGroup\n className={cn(\n \"jkl-file-input\",\n \"jkl-file-input--small\",\n className,\n {\n \"jkl-file-input--has-files\": hasFiles,\n },\n )}\n data-layout-density={density ? density : \"compact\"}\n {...rest}\n >\n <Dropzone>\n <div className=\"jkl-file-input__call-to-action\">\n <Input\n id={id}\n label=\"Legg til fil\"\n multiple={multiple}\n ref={ref}\n />\n </div>\n </Dropzone>\n {value.length > 0 && (\n <ul className=\"jkl-file-input__files\">\n {children}\n </ul>\n )}\n </FieldGroup>\n </FileInputContextProvider>\n );\n }\n\n return (\n <FileInputContextProvider\n context={{ accept, onChange, maxSizeBytes, files: value }}\n >\n <FieldGroup\n className={cn(\"jkl-file-input\", className, {\n \"jkl-file-input--has-files\": hasFiles,\n })}\n data-layout-density={density}\n {...rest}\n >\n <Dropzone>\n {value.length > 0 && (\n <ul className=\"jkl-file-input__files\">\n {children}\n </ul>\n )}\n <div className=\"jkl-file-input__call-to-action\">\n <Input\n id={id}\n label={\n multiple && hasFiles\n ? \"Legg til flere filer\"\n : \"Legg til fil\"\n }\n multiple={multiple}\n ref={ref}\n />\n </div>\n </Dropzone>\n </FieldGroup>\n </FileInputContextProvider>\n );\n },\n);\n\nFileInput.displayName = \"FileInput\";\n"],"names":["FileInput","forwardRef","props","ref","accept","className","children","id","value","density","multiple","maxSizeBytes","onChange","variant","rest","hasFiles","length","jsx","FileInputContextProvider","context","files","jsxs","FieldGroup","cn","Dropzone","Input","label","displayName"],"mappings":"+TAuCaA,EAAYC,EAAAA,YACrB,CAACC,EAAOC,KACE,MACFC,OAAAA,EACAC,UAAAA,EACAC,SAAAA,EACAC,GAAAA,EACAC,MAAAA,EACAC,QAAAA,EACAC,SAAAA,GAAW,EACXC,aAAAA,EACAC,SAAAA,EACAC,QAAAA,KACGC,GACHZ,EAEEa,EAAWP,EAAMQ,OAAS,EAEhC,MAAgB,UAAZH,EAEII,EAAAA,IAACC,EAAAA,yBAAA,CACGC,QAAS,CAAEf,OAAAA,EAAQQ,SAAAA,EAAUD,aAAAA,EAAcS,MAAOZ,GAElDF,SAAAe,EAAAA,KAACC,EAAAA,WAAA,CACGjB,UAAWkB,EACP,iBACA,wBACAlB,EACA,CACI,4BAA6BU,IAGrC,sBAAqBN,GAAoB,aACrCK,EAEJR,SAAA,CAAAW,MAACO,EAAAA,SACG,CAAAlB,SAAAW,EAAAA,IAAC,MAAI,CAAAZ,UAAU,iCACXC,SAAAW,EAAAA,IAACQ,EAAAA,MAAA,CACGlB,GAAAA,EACAmB,MAAM,eACNhB,SAAAA,EACAP,IAAAA,QAIXK,EAAMQ,OAAS,SACX,KAAG,CAAAX,UAAU,wBACTC,SAAAA,SASrBW,EAAAA,IAACC,EAAAA,yBAAA,CACGC,QAAS,CAAEf,OAAAA,EAAQQ,SAAAA,EAAUD,aAAAA,EAAcS,MAAOZ,GAElDF,SAAAW,EAAAA,IAACK,EAAAA,WAAA,CACGjB,UAAWkB,EAAG,iBAAkBlB,EAAW,CACvC,4BAA6BU,IAEjC,sBAAqBN,KACjBK,EAEJR,gBAACkB,WACI,CAAAlB,SAAA,CAAAE,EAAMQ,OAAS,GACZC,EAAAA,IAAC,KAAG,CAAAZ,UAAU,wBACTC,SAAAA,IAGTW,EAAAA,IAAC,MAAI,CAAAZ,UAAU,iCACXC,SAAAW,EAAAA,IAACQ,EAAAA,MAAA,CACGlB,GAAAA,EACAmB,MACIhB,GAAYK,EACN,uBACA,eAEVL,SAAAA,EACAP,IAAAA,YAIhB,IAMhBH,EAAU2B,YAAc"}
@@ -0,0 +1,26 @@
1
+ import { default as React } from 'react';
2
+ import { FieldGroupProps } from '../../components/input-group/FieldGroup.cjs';
3
+ import { Density } from '../../core/types.cjs';
4
+ import { FileInputFile } from './types.cjs';
5
+ export interface FileInputProps extends Omit<FieldGroupProps, "onChange"> {
6
+ className?: string;
7
+ id?: string;
8
+ density?: Density;
9
+ /**
10
+ * En string som begrenser hvilke filtyper som kan velges.
11
+ *
12
+ * Flere filtyper kan defineres som en kommaseparert liste.
13
+ *
14
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
15
+ */
16
+ accept?: "image/*" | ".pdf" | "image/*,.pdf" | HTMLInputElement["accept"];
17
+ maxSizeBytes?: number;
18
+ /**
19
+ * @default true
20
+ */
21
+ multiple?: boolean;
22
+ value: FileInputFile[];
23
+ variant?: "flexible" | "small";
24
+ onChange: (e: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLDivElement>, files: FileInputFile[]) => void;
25
+ }
26
+ export declare const FileInput: React.ForwardRefExoticComponent<FileInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./File.cjs"),t=require("./FileInput.cjs"),r=require("./utils.cjs");exports.File=e.File,exports.FileInput=t.FileInput,exports.upload=r.upload;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export { File, type FileProps } from './File.cjs';
2
+ export { FileInput, type FileInputProps } from './FileInput.cjs';
3
+ export type { FileInputFile, FileInputFileValidation, FileInputFileState, } from './types.cjs';
4
+ export { upload } from './utils.cjs';
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),r=require("classnames"),t=require("react"),n=require("./fileInputContext.cjs"),a=require("./validateFile.cjs"),i=t.forwardRef(((i,o)=>{const{children:l,...s}=i,[p,u]=t.useState(""),d=n.useFileInputContext();if(!d)return e.jsx("p",{children:"Dropzone must be placed inside a FileInputContextProvider."});const{maxSizeBytes:f,accept:c,onChange:v}=d;return e.jsx("div",{...s,ref:o,className:r("jkl-file-input__dropzone",p),onDragEnter:e=>{u("jkl-file-input__dropzone--enter"),e.preventDefault()},onDragOver:e=>{u("jkl-file-input__dropzone--enter"),e.preventDefault()},onDrop:e=>{e.preventDefault(),u(""),e.dataTransfer.files&&v(e,[...e.dataTransfer.files].map((e=>({file:e,state:"SELECTED",validation:a.validateFile(e,c,f),uploadProgress:0}))))},onDragLeave:e=>{u(""),e.preventDefault()},children:l})}));i.displayName="Dropzone",exports.Dropzone=i;
2
+ //# sourceMappingURL=Dropzone.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dropzone.cjs","sources":["../../../../../src/components/file-input/internal/Dropzone.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport React, { forwardRef, useState } from \"react\";\nimport { WithChildren } from \"../../../core/types.js\";\nimport { FileInputFile } from \"../types.js\";\nimport { useFileInputContext } from \"./fileInputContext.js\";\nimport { validateFile } from \"./validateFile.js\";\n\ninterface DropzoneProps extends WithChildren {}\n\nexport const Dropzone = forwardRef<HTMLDivElement, DropzoneProps>(\n (props, ref) => {\n const { children, ...rest } = props;\n const [onDragClassName, setOnDragClassName] = useState<string>(\"\");\n\n const context = useFileInputContext();\n if (!context) {\n return (\n <p>\n Dropzone must be placed inside a FileInputContextProvider.\n </p>\n );\n }\n const { maxSizeBytes, accept, onChange } = context;\n\n return (\n <div\n {...rest}\n ref={ref}\n className={cn(\"jkl-file-input__dropzone\", onDragClassName)}\n onDragEnter={(e) => {\n setOnDragClassName(\"jkl-file-input__dropzone--enter\");\n e.preventDefault();\n }}\n onDragOver={(e) => {\n /* Prevent browser from opening file in a new tab */\n setOnDragClassName(\"jkl-file-input__dropzone--enter\");\n e.preventDefault();\n }}\n onDrop={(e) => {\n e.preventDefault();\n setOnDragClassName(\"\");\n\n if (e.dataTransfer.files) {\n onChange(\n e,\n [...e.dataTransfer.files].map<FileInputFile>(\n (file) => ({\n file,\n state: \"SELECTED\",\n validation: validateFile(\n file,\n accept,\n maxSizeBytes,\n ),\n uploadProgress: 0,\n }),\n ),\n );\n }\n }}\n onDragLeave={(e) => {\n setOnDragClassName(\"\");\n e.preventDefault();\n }}\n >\n {children}\n </div>\n );\n },\n);\n\nDropzone.displayName = \"Dropzone\";\n"],"names":["Dropzone","forwardRef","props","ref","children","rest","onDragClassName","setOnDragClassName","useState","context","useFileInputContext","jsx","maxSizeBytes","accept","onChange","className","cn","onDragEnter","e","preventDefault","onDragOver","onDrop","dataTransfer","files","map","file","state","validation","validateFile","uploadProgress","onDragLeave","displayName"],"mappings":"oOASaA,EAAWC,EAAAA,YACpB,CAACC,EAAOC,KACJ,MAAQC,SAAAA,KAAaC,GAASH,GACvBI,EAAiBC,GAAsBC,WAAiB,IAEzDC,EAAUC,EAAAA,sBAChB,IAAKD,EAEG,OAAAE,EAAAA,IAAC,KAAEP,SAEH,+DAGR,MAAQQ,aAAAA,EAAcC,OAAAA,EAAQC,SAAAA,GAAaL,EAGvC,OAAAE,EAAAA,IAAC,MAAA,IACON,EACJF,IAAAA,EACAY,UAAWC,EAAG,2BAA4BV,GAC1CW,YAAcC,IACVX,EAAmB,mCACnBW,EAAEC,gBAAe,EAErBC,WAAaF,IAETX,EAAmB,mCACnBW,EAAEC,gBAAe,EAErBE,OAASH,IACLA,EAAEC,iBACFZ,EAAmB,IAEfW,EAAEI,aAAaC,OACfT,EACII,EACA,IAAIA,EAAEI,aAAaC,OAAOC,KACrBC,IAAAA,CACGA,KAAAA,EACAC,MAAO,WACPC,WAAYC,EAAAA,aACRH,EACAZ,EACAD,GAEJiB,eAAgB,MAExB,EAIZC,YAAcZ,IACVX,EAAmB,IACnBW,EAAEC,gBAAe,EAGpBf,SAAAA,GAAA,IAMjBJ,EAAS+B,YAAc"}
@@ -0,0 +1,6 @@
1
+ import { default as React } from 'react';
2
+ import { WithChildren } from '../../../core/types.cjs';
3
+ interface DropzoneProps extends WithChildren {
4
+ }
5
+ export declare const Dropzone: React.ForwardRefExoticComponent<DropzoneProps & React.RefAttributes<HTMLDivElement>>;
6
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),i=require("../../../hooks/useId/useId.cjs"),r=require("../../../utilities/formatters/bytes/formatBytes.cjs"),s=require("./fileInputContext.cjs"),l=require("./validateFile.cjs"),a=t.forwardRef(((t,a)=>{const{multiple:n,id:u,label:o,...d}=t,p=i.useId(u||"jkl-file-input",{generateSuffix:!u}),c=p+"-description",f=n?"filer":"fil",j=s.useFileInputContext();if(!j)return e.jsx("p",{children:"Input must be placed inside a FileInputContextProvider."});const{accept:m,maxSizeBytes:x,onChange:y,files:h}=j;return e.jsxs(e.Fragment,{children:[e.jsx("label",{className:"jkl-button jkl-button--secondary",htmlFor:p,children:o}),e.jsx("input",{...d,ref:a,id:p,accept:m,"aria-describedby":x?c:void 0,className:"jkl-sr-only",type:"file",multiple:n,onChange:e=>{e.target.files&&y(e,[...e.target.files].map((e=>({file:e,state:"SELECTED",validation:l.validateFile(e,m,x),uploadProgress:0}))))}}),0===h.length&&e.jsxs("p",{children:["eller slipp ",f," her"]}),typeof x<"u"&&e.jsxs("div",{id:c,className:"jkl-file-input__max-size-text",children:["Maks ",r.formatBytes(x)," per fil"]})]})}));a.displayName="Input",exports.Input=a;
2
+ //# sourceMappingURL=Input.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.cjs","sources":["../../../../../src/components/file-input/internal/Input.tsx"],"sourcesContent":["import React, { forwardRef } from \"react\";\nimport { useId } from \"../../../hooks/useId/useId.js\";\nimport { formatBytes } from \"../../../utilities/formatters/bytes/formatBytes.js\";\nimport { FileInputFile } from \"../types.js\";\nimport { useFileInputContext } from \"./fileInputContext.js\";\nimport { validateFile } from \"./validateFile.js\";\n\ninterface FileInputProps {\n id?: string;\n label: string;\n multiple: boolean;\n}\n\nexport const Input = forwardRef<HTMLInputElement, FileInputProps>(\n (props, ref) => {\n const { multiple, id: idProp, label, ...rest } = props;\n\n const id = useId(idProp || \"jkl-file-input\", {\n generateSuffix: !idProp,\n });\n const maxSizeDescriptionId = id + \"-description\";\n const descriptor = multiple ? \"filer\" : \"fil\";\n\n const context = useFileInputContext();\n if (!context) {\n return (\n <p>Input must be placed inside a FileInputContextProvider.</p>\n );\n }\n const { accept, maxSizeBytes, onChange, files } = context;\n\n return (\n <>\n <label\n className=\"jkl-button jkl-button--secondary\"\n htmlFor={id}\n >\n {label}\n </label>\n <input\n {...rest}\n ref={ref}\n id={id}\n accept={accept}\n aria-describedby={\n maxSizeBytes ? maxSizeDescriptionId : undefined\n }\n className=\"jkl-sr-only\"\n type=\"file\"\n multiple={multiple}\n onChange={(e) => {\n if (e.target.files) {\n onChange(\n e,\n [...e.target.files].map<FileInputFile>(\n (file) => ({\n file,\n state: \"SELECTED\",\n validation: validateFile(\n file,\n accept,\n maxSizeBytes,\n ),\n uploadProgress: 0,\n }),\n ),\n );\n }\n }}\n />\n {files.length === 0 && <p>eller slipp {descriptor} her</p>}\n {typeof maxSizeBytes !== \"undefined\" && (\n <div\n id={maxSizeDescriptionId}\n className=\"jkl-file-input__max-size-text\"\n >\n Maks {formatBytes(maxSizeBytes)} per fil\n </div>\n )}\n </>\n );\n },\n);\n\nInput.displayName = \"Input\";\n"],"names":["Input","forwardRef","props","ref","multiple","id","idProp","label","rest","useId","generateSuffix","maxSizeDescriptionId","descriptor","context","useFileInputContext","jsx","children","accept","maxSizeBytes","onChange","files","jsxs","Fragment","className","htmlFor","type","e","target","map","file","state","validation","validateFile","uploadProgress","length","formatBytes","displayName"],"mappings":"yTAaaA,EAAQC,EAAAA,YACjB,CAACC,EAAOC,KACJ,MAAQC,SAAAA,EAAUC,GAAIC,EAAQC,MAAAA,KAAUC,GAASN,EAE3CG,EAAKI,EAAAA,MAAMH,GAAU,iBAAkB,CACzCI,gBAAiBJ,IAEfK,EAAuBN,EAAK,eAC5BO,EAAaR,EAAW,QAAU,MAElCS,EAAUC,EAAAA,sBAChB,IAAKD,EAEG,OAAAE,EAAAA,IAAC,KAAEC,SAAuD,4DAGlE,MAAQC,OAAAA,EAAQC,aAAAA,EAAcC,SAAAA,EAAUC,MAAAA,GAAUP,EAElD,OAEQQ,EAAAA,KAAAC,WAAA,CAAAN,SAAA,CAAAD,EAAAA,IAAC,QAAA,CACGQ,UAAU,mCACVC,QAASnB,EAERW,SAAAT,IAELQ,EAAAA,IAAC,QAAA,IACOP,EACJL,IAAAA,EACAE,GAAAA,EACAY,OAAAA,EACA,mBACIC,EAAeP,OAAuB,EAE1CY,UAAU,cACVE,KAAK,OACLrB,SAAAA,EACAe,SAAWO,IACHA,EAAEC,OAAOP,OACTD,EACIO,EACA,IAAIA,EAAEC,OAAOP,OAAOQ,KACfC,IAAU,CACPA,KAAAA,EACAC,MAAO,WACPC,WAAYC,EAAAA,aACRH,EACAZ,EACAC,GAEJe,eAAgB,MAExB,IAKE,IAAjBb,EAAMc,QAAgBb,EAAAA,KAAC,IAAE,CAAAL,SAAA,CAAA,eAAaJ,EAAW,iBAC1CM,EAAiB,KACrBG,EAAAA,KAAC,MAAA,CACGhB,GAAIM,EACJY,UAAU,gCACbP,SAAA,CAAA,QACSmB,EAAAA,YAAYjB,GAAc,gBAG5C,IAKZlB,EAAMoC,YAAc"}
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+ interface FileInputProps {
3
+ id?: string;
4
+ label: string;
5
+ multiple: boolean;
6
+ }
7
+ export declare const Input: React.ForwardRefExoticComponent<FileInputProps & React.RefAttributes<HTMLInputElement>>;
8
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),l=require("classnames");exports.Thumbnail=i=>{const{fileName:t,fileType:s,path:a,file:r,state:c,children:n}=i,m=l("jkl-file__thumbnail",{"jkl-file__thumbnail--selected":"SELECTED"===c,"jkl-file__thumbnail--uploading":"UPLOADING"===c});return s.startsWith("image/")?e.jsxs("div",{className:"jkl-file__thumbnail-wrapper",children:[e.jsx("img",{className:m,src:r?URL.createObjectURL(r):a,alt:""}),n]}):e.jsx("div",{className:m,children:e.jsx("p",{children:t.split(".").at(-1)})})};
2
+ //# sourceMappingURL=Thumbnail.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Thumbnail.cjs","sources":["../../../../../src/components/file-input/internal/Thumbnail.tsx"],"sourcesContent":["import cn from \"classnames\";\nimport React, { FC } from \"react\";\nimport type { WithOptionalChildren } from \"../../../core/types.js\";\nimport { FileInputFileState } from \"../types.js\";\n\nexport interface ThumbnailProps extends WithOptionalChildren {\n fileName: string;\n fileType: string;\n path?: string;\n file?: File;\n state?: FileInputFileState;\n}\n\nexport const Thumbnail: FC<ThumbnailProps> = (props) => {\n const { fileName, fileType, path, file, state, children } = props;\n\n const classNames = cn(\"jkl-file__thumbnail\", {\n \"jkl-file__thumbnail--selected\": state === \"SELECTED\",\n \"jkl-file__thumbnail--uploading\": state === \"UPLOADING\",\n });\n\n if (fileType.startsWith(\"image/\")) {\n return (\n <div className=\"jkl-file__thumbnail-wrapper\">\n <img\n className={classNames}\n src={file ? URL.createObjectURL(file) : path}\n alt=\"\"\n />\n {children}\n </div>\n );\n }\n\n return (\n <div className={classNames}>\n <p>{fileName.split(\".\").at(-1)}</p>\n </div>\n );\n};\n"],"names":["props","fileName","fileType","path","file","state","children","classNames","cn","startsWith","jsxs","className","jsx","src","URL","createObjectURL","alt","split","at"],"mappings":"+JAa8CA,IAC1C,MAAQC,SAAAA,EAAUC,SAAAA,EAAUC,KAAAA,EAAMC,KAAAA,EAAMC,MAAAA,EAAOC,SAAAA,GAAaN,EAEtDO,EAAaC,EAAG,sBAAuB,CACzC,gCAA2C,aAAVH,EACjC,iCAA4C,cAAVA,IAGlC,OAAAH,EAASO,WAAW,UAEhBC,EAAAA,KAAC,MAAI,CAAAC,UAAU,8BACXL,SAAA,CAAAM,EAAAA,IAAC,MAAA,CACGD,UAAWJ,EACXM,IAAKT,EAAOU,IAAIC,gBAAgBX,GAAQD,EACxCa,IAAI,KAEPV,KAMRM,EAAAA,IAAA,MAAA,CAAID,UAAWJ,EACZD,SAACM,EAAAA,IAAA,IAAA,CAAGN,SAASL,EAAAgB,MAAM,KAAKC,IAAG,MAC/B"}
@@ -0,0 +1,11 @@
1
+ import { FC } from 'react';
2
+ import { WithOptionalChildren } from '../../../core/types.cjs';
3
+ import { FileInputFileState } from '../types.cjs';
4
+ export interface ThumbnailProps extends WithOptionalChildren {
5
+ fileName: string;
6
+ fileType: string;
7
+ path?: string;
8
+ file?: File;
9
+ state?: FileInputFileState;
10
+ }
11
+ export declare const Thumbnail: FC<ThumbnailProps>;
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),r=t.createContext(null);exports.FileInputContextProvider=({context:t,children:o})=>e.jsx(r.Provider,{value:t,children:o}),exports.useFileInputContext=()=>t.useContext(r);
2
+ //# sourceMappingURL=fileInputContext.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileInputContext.cjs","sources":["../../../../../src/components/file-input/internal/fileInputContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport { WithChildren } from \"../../../core/types.js\";\nimport { FileInputFile } from \"../types.js\";\n\ntype FileInputContext = {\n accept?: \"image/*\" | \".pdf\" | \"image/*,.pdf\" | HTMLInputElement[\"accept\"];\n maxSizeBytes?: number;\n files: FileInputFile[];\n onChange: (\n e:\n | React.ChangeEvent<HTMLInputElement>\n | React.DragEvent<HTMLDivElement>,\n files: FileInputFile[],\n ) => void;\n};\n\nconst fileInputContext = createContext<FileInputContext | null>(null);\n\nexport const useFileInputContext = (): FileInputContext | null =>\n useContext(fileInputContext);\n\nexport interface FileInputContextProviderProps extends WithChildren {\n context: FileInputContext;\n}\n\nexport const FileInputContextProvider: React.FC<\n FileInputContextProviderProps\n> = ({ context, children }) => (\n <fileInputContext.Provider value={context}>\n {children}\n </fileInputContext.Provider>\n);\n"],"names":["fileInputContext","createContext","context","children","jsx","Provider","value","useContext"],"mappings":"wIAgBMA,EAAmBC,EAAAA,cAAuC,uCAW5D,EAAGC,QAAAA,EAASC,SAAAA,KACXC,EAAAA,IAAAJ,EAAiBK,SAAjB,CAA0BC,MAAOJ,EAC7BC,SAAAA,gCAX0B,IAC/BI,EAAAA,WAAWP"}
@@ -0,0 +1,15 @@
1
+ import { default as React } from 'react';
2
+ import { WithChildren } from '../../../core/types.cjs';
3
+ import { FileInputFile } from '../types.cjs';
4
+ type FileInputContext = {
5
+ accept?: "image/*" | ".pdf" | "image/*,.pdf" | HTMLInputElement["accept"];
6
+ maxSizeBytes?: number;
7
+ files: FileInputFile[];
8
+ onChange: (e: React.ChangeEvent<HTMLInputElement> | React.DragEvent<HTMLDivElement>, files: FileInputFile[]) => void;
9
+ };
10
+ export declare const useFileInputContext: () => FileInputContext | null;
11
+ export interface FileInputContextProviderProps extends WithChildren {
12
+ context: FileInputContext;
13
+ }
14
+ export declare const FileInputContextProvider: React.FC<FileInputContextProviderProps>;
15
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../../../utilities/formatters/bytes/formatBytes.cjs");exports.validateFile=function(t,s="",i){var r;const a=s.split(",").map((e=>e.toLowerCase())).map((e=>e.replaceAll("*",""))).map((e=>e.trim()));let l=0===a.length;return l=a.reduce(((e,s)=>e||t.type.includes(s)||t.name.endsWith(s)),l),l?typeof i<"u"&&t.size>i?{type:"TOO_LARGE",message:`Filen er ${e.formatBytes(t.size)}, men kan maksimalt være ${e.formatBytes(i)}`}:void 0:{type:"WRONG_TYPE",message:`Filtypen ${(null==(r=t.name)?void 0:r.split(".")[1])||""} støttes ikke`}};
2
+ //# sourceMappingURL=validateFile.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateFile.cjs","sources":["../../../../../src/components/file-input/internal/validateFile.ts"],"sourcesContent":["import { formatBytes } from \"../../../utilities/formatters/bytes/formatBytes.js\";\nimport type { FileInputFileValidation } from \"../types.js\";\n\nexport function validateFile(\n file: File,\n accept = \"\",\n maxSizeBytes?: number,\n): FileInputFileValidation | undefined {\n const acceptStrings = accept\n .split(\",\")\n .map((s) => s.toLowerCase())\n .map((s) => s.replaceAll(\"*\", \"\"))\n .map((s) => s.trim());\n\n let isValidFormat = acceptStrings.length === 0;\n\n isValidFormat = acceptStrings.reduce(\n (found, acceptString) =>\n found ||\n file.type.includes(acceptString) ||\n file.name.endsWith(acceptString),\n isValidFormat,\n );\n\n if (!isValidFormat) {\n return {\n type: \"WRONG_TYPE\",\n message: `Filtypen ${file.name?.split(\".\")[1] || \"\"} støttes ikke`,\n };\n }\n\n if (typeof maxSizeBytes != \"undefined\" && file.size > maxSizeBytes) {\n return {\n type: \"TOO_LARGE\",\n message: `Filen er ${formatBytes(\n file.size,\n )}, men kan maksimalt være ${formatBytes(maxSizeBytes)}`,\n };\n }\n\n return undefined;\n}\n"],"names":["file","accept","maxSizeBytes","acceptStrings","split","map","s","toLowerCase","replaceAll","trim","isValidFormat","length","reduce","found","acceptString","type","includes","name","endsWith","size","message","formatBytes","_a"],"mappings":"4KAGO,SACHA,EACAC,EAAS,GACTC,SAEM,MAAAC,EAAgBF,EACjBG,MAAM,KACNC,KAAKC,GAAMA,EAAEC,gBACbF,KAAKC,GAAMA,EAAEE,WAAW,IAAK,MAC7BH,KAAKC,GAAMA,EAAEG,SAEd,IAAAC,EAAyC,IAAzBP,EAAcQ,OAUlC,OARAD,EAAgBP,EAAcS,QAC1B,CAACC,EAAOC,IACJD,GACAb,EAAKe,KAAKC,SAASF,IACnBd,EAAKiB,KAAKC,SAASJ,IACvBJ,GAGCA,SAOMR,EAAgB,KAAeF,EAAKmB,KAAOjB,EAC3C,CACHa,KAAM,YACNK,QAAS,YAAYC,EAAAA,YACjBrB,EAAKmB,iCACoBE,EAAAA,YAAYnB,WALjD,EANW,CACHa,KAAM,aACNK,QAAS,aAAY,OAAAE,EAAAtB,EAAKiB,WAALK,EAAAA,EAAWlB,MAAM,KAAK,KAAM,kBAc7D"}
@@ -0,0 +1,2 @@
1
+ import { FileInputFileValidation } from '../types.cjs';
2
+ export declare function validateFile(file: File, accept?: string, maxSizeBytes?: number): FileInputFileValidation | undefined;
@@ -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,11 @@
1
+ export interface FileInputFileValidation {
2
+ type: "TOO_LARGE" | "WRONG_TYPE";
3
+ message: string;
4
+ }
5
+ export type FileInputFileState = "SELECTED" | "UPLOADING" | "UPLOAD_ERROR" | "UPLOAD_SUCCESS";
6
+ export interface FileInputFile {
7
+ file: File;
8
+ validation?: FileInputFileValidation;
9
+ state: FileInputFileState;
10
+ uploadProgress: number;
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),exports.upload=async function(e,t,r,s){const n=new XMLHttpRequest;return new Promise(((o,a)=>{n.upload.addEventListener("progress",(e=>{e.lengthComputable&&r&&r(e.loaded/e.total*100)})),n.addEventListener("load",(e=>{n.status>=400&&a(e),o(e)})),n.addEventListener("error",(e=>{a(e)})),n.addEventListener("abort",(e=>{a(e)})),n.open("POST",e),Object.entries(s||{}).forEach((([e,t])=>{n.setRequestHeader(e,t)})),n.send(t)})).then((e=>JSON.parse(n.responseText)),(()=>{throw new Error(n.statusText)}))};
2
+ //# sourceMappingURL=utils.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.cjs","sources":["../../../../src/components/file-input/utils.ts"],"sourcesContent":["/**\n * Hjelpefunksjon for å laste opp filer med progress-bar\n *\n * @param {string} url Endepunktet som skal lastes opp til\n * @param {FormData} data FormData med filen som skal lastes opp\n * @param progress Callback som blir kalt med oppdatert progresjon\n * @param {Record<string, string>} headers Eventuelle headers som skal sendes\n * med opplasingen. Her kan du f.eks. sende med CSRF-verdier.\n * @returns {T} Svaret fra endepunktet\n */\nexport async function upload<T>(\n url: string,\n data: FormData,\n progress: (progress: number) => void,\n headers?: Record<string, string>,\n): Promise<T> {\n // I skrivende stund er det ikke mulig å hente progress med fetch. Derfor bruker vi XMLHttpRequest.\n const xhr = new XMLHttpRequest();\n const request = new Promise<ProgressEvent<XMLHttpRequestEventTarget>>(\n (resolve, reject) => {\n xhr.upload.addEventListener(\"progress\", (e) => {\n if (e.lengthComputable && progress) {\n progress((e.loaded / e.total) * 100);\n }\n });\n\n xhr.addEventListener(\"load\", (e) => {\n if (xhr.status >= 400) {\n reject(e);\n }\n resolve(e);\n });\n\n xhr.addEventListener(\"error\", (e) => {\n reject(e);\n });\n\n xhr.addEventListener(\"abort\", (e) => {\n reject(e);\n });\n\n xhr.open(\"POST\", url);\n\n Object.entries(headers || {}).forEach(([header, value]) => {\n xhr.setRequestHeader(header, value);\n });\n\n xhr.send(data);\n },\n ).then(\n (e) => {\n const response: T = JSON.parse(xhr.responseText);\n return response;\n },\n () => {\n throw new Error(xhr.statusText);\n },\n );\n\n return request;\n}\n"],"names":["async","url","data","progress","headers","xhr","XMLHttpRequest","Promise","resolve","reject","upload","addEventListener","e","lengthComputable","loaded","total","status","open","Object","entries","forEach","header","value","setRequestHeader","send","then","JSON","parse","responseText","Error","statusText"],"mappings":"+FAUAA,eACIC,EACAC,EACAC,EACAC,GAGM,MAAAC,EAAM,IAAIC,eA0CT,OAzCS,IAAIC,SAChB,CAACC,EAASC,KACNJ,EAAIK,OAAOC,iBAAiB,YAAaC,IACjCA,EAAEC,kBAAoBV,GACtBA,EAAUS,EAAEE,OAASF,EAAEG,MAAS,IAAG,IAIvCV,EAAAM,iBAAiB,QAASC,IACtBP,EAAIW,QAAU,KACdP,EAAOG,GAEXJ,EAAQI,EAAC,IAGTP,EAAAM,iBAAiB,SAAUC,IAC3BH,EAAOG,EAAC,IAGRP,EAAAM,iBAAiB,SAAUC,IAC3BH,EAAOG,EAAC,IAGRP,EAAAY,KAAK,OAAQhB,GAEViB,OAAAC,QAAQf,GAAW,CAAE,GAAEgB,SAAQ,EAAEC,EAAQC,MACxCjB,EAAAkB,iBAAiBF,EAAQC,EAAK,IAGtCjB,EAAImB,KAAKtB,EAAI,IAEnBuB,MACGb,GACuBc,KAAKC,MAAMtB,EAAIuB,gBAGvC,KACU,MAAA,IAAIC,MAAMxB,EAAIyB,WAAU,GAK1C"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Hjelpefunksjon for å laste opp filer med progress-bar
3
+ *
4
+ * @param {string} url Endepunktet som skal lastes opp til
5
+ * @param {FormData} data FormData med filen som skal lastes opp
6
+ * @param progress Callback som blir kalt med oppdatert progresjon
7
+ * @param {Record<string, string>} headers Eventuelle headers som skal sendes
8
+ * med opplasingen. Her kan du f.eks. sende med CSRF-verdier.
9
+ * @returns {T} Svaret fra endepunktet
10
+ */
11
+ export declare function upload<T>(url: string, data: FormData, progress: (progress: number) => void, headers?: Record<string, string>): Promise<T>;
@@ -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"),l=require("react"),n=require("../../hooks/useAnimatedHeight/useAnimatedHeight.cjs"),r=require("../../hooks/useId/useId.cjs"),s=require("../../hooks/useListNavigation/useListNavigation.cjs"),a=require("../../hooks/usePreviousValue/usePreviousValue.cjs"),o=require("../../utilities/valuePair.cjs"),u=require("../icon/icons/animated/ArrowVerticalAnimated.cjs"),i=require("../input-group/InputGroup.cjs"),c=require("./select-utils.cjs"),d=()=>{},p=l.forwardRef(((p,v)=>{const{id:f,name:b,items:k,value:m,label:g,labelProps:j,onChange:h,onBlur:y,onFocus:w,className:_,helpLabel:x,errorLabel:P,invalid:C,searchable:E=!1,inline:D=!1,defaultPrompt:L="Velg",density:S,width:$,maxShownOptions:N=5,style:q,tooltipProps:A,...V}=p,F=r.useId(f||"jkl-select",{generateSuffix:!f}),T=`${F}_label`,I=`${F}_button`,M=`${F}_search-input`,[R,K]=l.useState(!1),B=l.useCallback((()=>{K((e=>!e))}),[]),O=!!E,H=O&&R,[G,U]=l.useState(""),z=l.useCallback((e=>!!e.label.toLowerCase().includes(G.toLowerCase())||"function"==typeof E&&E(G,e)),[E,G]),J=l.useMemo((()=>k.map(o.getValuePair).map((e=>{const t=!O||""===G||z(e);return{...e,visible:t}}))),[k,O,G,z]),Q=l.useMemo((()=>!(typeof m>"u")&&k.some((e=>"string"==typeof e?e===m:e.value===m))),[m,k]),[W,X]=l.useState(Q&&void 0!==m?m:""),Y=""!==W,Z=l.useMemo((()=>{var e;return(null==(e=J.find((e=>e.value===W)))?void 0:e.label)||L}),[J,W,L]),ee=l.useRef(null),te=l.useCallback((e=>{ee.current=e,v&&("function"==typeof v?v(e):v.current=e),e&&X(e.value)}),[ee,v]),le=a.usePreviousValue(m);l.useEffect((()=>{m!==le&&X(typeof m>"u"||!Q?"":m)}),[X,m,le,Q]);const ne=l.useCallback((e=>{const t=e.value;U(""),X(t),B()}),[U,X,B]),re=a.usePreviousValue(W);l.useEffect((()=>{typeof re>"u"||re===W||W===m||(h&&h({type:"change",target:{name:b,value:W}}),ee.current&&ee.current.dispatchEvent(new Event("change",{bubbles:!0})))}),[h,b,m,W,re]);const se=l.useRef(null),ae=l.useRef(!1),oe=l.useRef(null),ue=l.useRef(null),ie=l.useCallback(((e,t)=>{if(e&&!O){const e=t.current;e&&c.focusSelected(e,W)}else e?oe.current&&oe.current.focus():ae.current&&ue.current&&ue.current.focus()}),[O,W]),[ce]=n.useAnimatedHeight(R,{onFirstVisible:ie,onTransitionEnd:ie});s.useListNavigation({ref:ce});const de=l.useCallback((()=>{var e;O&&U(""),y&&(y({type:"blur",target:{name:b,value:W}}),null==(e=ee.current)||e.dispatchEvent(new Event("focusout",{bubbles:!0}))),ae.current=!1,K(!1)}),[y,U,K,O,b,W]),pe=l.useCallback((e=>{const t=se.current;t&&t.contains(e.relatedTarget)||de()}),[de]),ve=l.useCallback((()=>{ae.current||(w&&w({type:"change",target:{name:b,value:W}}),ae.current=!0)}),[w,W,b]),fe=l.useCallback((e=>{e.target.focus({preventScroll:!0})}),[]);l.useEffect((()=>{const e=ee.current,t=oe.current,l=ue.current,n=se.current;return null==e||e.addEventListener("focus",(()=>{H?null==t||t.focus():null==l||l.focus()})),null==e||e.addEventListener("blur",(function(e){n&&n.contains(e.relatedTarget)&&e.preventDefault()})),()=>{null==e||e.removeEventListener("focus",(()=>{H?null==t||t.focus():null==l||l.focus()})),null==e||e.removeEventListener("blur",(function(e){n&&n.contains(e.relatedTarget)&&e.preventDefault()}))}}),[H]);const be=l.useCallback((e=>{"ArrowDown"!==e.key&&" "!==e.key||R?"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),K(!1)):(e.preventDefault(),e.stopPropagation(),K(!0))}),[K,R]),ke=l.useCallback((e=>{if("ArrowDown"===e.key){e.preventDefault(),e.stopPropagation();const t=ce.current;t&&(O?c.focusSelected(t,void 0):c.focusSelected(t,W))}else if("Escape"===e.key)e.preventDefault(),e.stopPropagation(),K(!1);else if("Tab"!==e.key||e.shiftKey)"Enter"===e.key&&R&&(e.preventDefault(),e.stopPropagation());else{const t=ce.current;t&&(e.preventDefault(),e.stopPropagation(),c.focusSelected(t,W))}}),[K,ce,W,O,R]),me=l.useCallback((e=>{if("Tab"===e.key)e.preventDefault(),e.stopPropagation(),e.shiftKey&&oe.current?oe.current.focus():ue.current&&(X(e.currentTarget.value),K(!1),ue.current.focus());else if("ArrowUp"===e.key&&ce.current&&oe.current){const t=ce.current.querySelector('[role="option"]:not([hidden])');e.currentTarget.id===(null==t?void 0:t.id)&&oe.current&&oe.current.focus()}}),[K,ce]);return l.useEffect((()=>{const e=e=>{"Escape"===e.key&&R&&K(!1)};return typeof window<"u"&&R&&window.addEventListener("keydown",e),()=>{typeof window<"u"&&window.removeEventListener("keydown",e)}}),[K,R]),e.jsxs(e.Fragment,{children:[e.jsxs("select",{name:b,tabIndex:-1,"data-testid":"jkl-native-select",className:"jkl-sr-only","aria-hidden":!0,ref:te,value:W,onChange:d,children:[e.jsx("option",{value:""})," ",J.map((t=>e.jsx("option",{hidden:!t.visible,value:t.value,children:t.label},`${F}-opt-${t.value}`)))]}),e.jsx(i.InputGroup,{ref:se,"data-testid":"jkl-select",className:t.clsx("jkl-select",_,{"jkl-select--inline":D,"jkl-select--open":R&&J.some((e=>e.visible)),"jkl-select--no-value":!Y,"jkl-select--invalid":!!P||C}),tooltipProps:A&&{...A,triggerProps:{...A.triggerProps,onFocus:e=>{var t,l;null==(l=null==(t=A.triggerProps)?void 0:t.onFocus)||l.call(t,e),de()}}},...V,id:O?M:I,style:{"--jkl-select-max-shown-options":N,...q},density:S,label:g,labelProps:{id:T,srOnly:D,...j,htmlFor:O?M:I},helpLabel:x,errorLabel:P,render:l=>e.jsxs("div",{className:"jkl-select__outer-wrapper",style:{width:$},children:[O&&e.jsx("input",{...l,id:M,hidden:!H,ref:oe,placeholder:"Søk",value:G,onChange:e=>U(e.target.value),"data-testid":"jkl-select__search-input",className:"jkl-select__search-input","aria-autocomplete":"list","aria-activedescendant":Y?`${F}__${c.toLower(W)}`:void 0,"aria-controls":F,"aria-expanded":R,role:"combobox",onKeyDown:ke,onBlur:pe,onFocus:ve,onClick:e=>{e.stopPropagation()}}),e.jsx("button",{...l,id:I,ref:ue,hidden:H,type:"button",name:`${b}-btn`,className:t.clsx("jkl-select__button",{"jkl-select__button--active-value":!!W}),"data-testid":"jkl-select__button","aria-label":`${Z||"Velg"},${g}`,"aria-expanded":R,"aria-controls":F,onBlur:pe,onFocus:ve,onKeyDown:be,onClick:B,onMouseDown:e=>{var t;e.preventDefault(),null==(t=ue.current)||t.focus()},children:Z}),e.jsx("div",{id:F,ref:ce,role:"listbox",className:"jkl-select__options-menu",hidden:!R||J.every((e=>!e.visible)),"aria-labelledby":T,tabIndex:-1,"data-focus":"controlled",children:J.map(((t,l)=>t.visible?e.jsxs("button",{hidden:!t.visible,type:"button",id:`${F}__${c.toLower(t.value)}`,className:"jkl-select__option","data-testid":"jkl-select__option","aria-selected":t.value===W,role:"option",value:t.value,"data-testautoid":`jkl-select__option-${l}`,onBlur:pe,onFocus:ve,onKeyDown:me,onClick:e=>{e.preventDefault(),ne(t)},onMouseOver:fe,children:[t.label,t.description?e.jsx("span",{className:"jkl-select__option-description",children:t.description}):null]},`${F}-${t.value}`):null))}),e.jsx(u.ArrowVerticalAnimated,{variant:"medium",pointingDown:!R,className:"jkl-select__arrow"})]})})]})}));p.displayName="Select",exports.Select=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("../../../clsx-E3yX_9sL.cjs"),l=require("react"),n=require("../../hooks/useAnimatedHeight/useAnimatedHeight.cjs"),r=require("../../hooks/useId/useId.cjs"),a=require("../../hooks/useListNavigation/useListNavigation.cjs"),s=require("../../hooks/usePreviousValue/usePreviousValue.cjs"),o=require("../../utilities/valuePair.cjs"),u=require("../icon/icons/animated/ArrowVerticalAnimated.cjs"),i=require("../input-group/InputGroup.cjs"),c=require("./select-utils.cjs"),d=()=>{},p=l.forwardRef(((p,v)=>{const{id:f,name:b,items:k,value:m,label:g,labelProps:j,onChange:h,onBlur:y,onFocus:w,className:_,helpLabel:x,errorLabel:P,invalid:C,searchable:E=!1,inline:D=!1,defaultPrompt:L="Velg",density:S,width:$,maxShownOptions:N=5,style:q,tooltipProps:A,...V}=p,F=r.useId(f||"jkl-select",{generateSuffix:!f}),T=`${F}_label`,I=`${F}_button`,M=`${F}_search-input`,[R,K]=l.useState(!1),B=l.useCallback((()=>{K((e=>!e))}),[]),O=!!E,H=O&&R,[G,U]=l.useState(""),z=l.useCallback((e=>!!e.label.toLowerCase().includes(G.toLowerCase())||"function"==typeof E&&E(G,e)),[E,G]),J=l.useMemo((()=>k.map(o.getValuePair).map((e=>{const t=!O||""===G||z(e);return{...e,visible:t}}))),[k,O,G,z]),Q=l.useMemo((()=>!(typeof m>"u")&&k.some((e=>"string"==typeof e?e===m:e.value===m))),[m,k]),[W,X]=l.useState(Q&&void 0!==m?m:""),Y=""!==W,Z=l.useMemo((()=>{var e;return(null==(e=J.find((e=>e.value===W)))?void 0:e.label)||L}),[J,W,L]),ee=l.useRef(null),te=l.useCallback((e=>{ee.current=e,v&&("function"==typeof v?v(e):v.current=e),e&&X(e.value)}),[ee,v]),le=s.usePreviousValue(m);l.useEffect((()=>{m!==le&&X(typeof m>"u"||!Q?"":m)}),[X,m,le,Q]);const ne=l.useCallback((e=>{const t=e.value;U(""),X(t),B()}),[U,X,B]),re=s.usePreviousValue(W);l.useEffect((()=>{typeof re>"u"||re===W||W===m||(h&&h({type:"change",target:{name:b,value:W}}),ee.current&&ee.current.dispatchEvent(new Event("change",{bubbles:!0})))}),[h,b,m,W,re]);const ae=l.useRef(null),se=l.useRef(!1),oe=l.useRef(null),ue=l.useRef(null),ie=l.useCallback(((e,t)=>{if(e&&!O){const e=t.current;e&&c.focusSelected(e,W)}else e?oe.current&&oe.current.focus():se.current&&ue.current&&ue.current.focus()}),[O,W]),[ce]=n.useAnimatedHeight(R,{onFirstVisible:ie,onTransitionEnd:ie});a.useListNavigation({ref:ce});const de=l.useCallback((()=>{var e;O&&U(""),y&&(y({type:"blur",target:{name:b,value:W}}),null==(e=ee.current)||e.dispatchEvent(new Event("focusout",{bubbles:!0}))),se.current=!1,K(!1)}),[y,U,K,O,b,W]),pe=l.useCallback((e=>{const t=ae.current;t&&t.contains(e.relatedTarget)||de()}),[de]),ve=l.useCallback((()=>{se.current||(w&&w({type:"change",target:{name:b,value:W}}),se.current=!0)}),[w,W,b]),fe=l.useCallback((e=>{e.target.focus({preventScroll:!0})}),[]);l.useEffect((()=>{const e=ee.current,t=oe.current,l=ue.current,n=ae.current;return null==e||e.addEventListener("focus",(()=>{H?null==t||t.focus():null==l||l.focus()})),null==e||e.addEventListener("blur",(function(e){n&&n.contains(e.relatedTarget)&&e.preventDefault()})),()=>{null==e||e.removeEventListener("focus",(()=>{H?null==t||t.focus():null==l||l.focus()})),null==e||e.removeEventListener("blur",(function(e){n&&n.contains(e.relatedTarget)&&e.preventDefault()}))}}),[H]);const be=l.useCallback((e=>{"ArrowDown"!==e.key&&" "!==e.key||R?"Escape"===e.key&&(e.preventDefault(),e.stopPropagation(),K(!1)):(e.preventDefault(),e.stopPropagation(),K(!0))}),[K,R]),ke=l.useCallback((e=>{if("ArrowDown"===e.key){e.preventDefault(),e.stopPropagation();const t=ce.current;t&&(O?c.focusSelected(t,void 0):c.focusSelected(t,W))}else if("Escape"===e.key)e.preventDefault(),e.stopPropagation(),K(!1);else if("Tab"!==e.key||e.shiftKey)"Enter"===e.key&&R&&(e.preventDefault(),e.stopPropagation());else{const t=ce.current;t&&(e.preventDefault(),e.stopPropagation(),c.focusSelected(t,W))}}),[K,ce,W,O,R]),me=l.useCallback((e=>{if("Tab"===e.key)e.preventDefault(),e.stopPropagation(),e.shiftKey&&oe.current?oe.current.focus():ue.current&&(X(e.currentTarget.value),K(!1),ue.current.focus());else if("ArrowUp"===e.key&&ce.current&&oe.current){const t=ce.current.querySelector('[role="option"]:not([hidden])');e.currentTarget.id===(null==t?void 0:t.id)&&oe.current&&oe.current.focus()}}),[K,ce]);return l.useEffect((()=>{const e=e=>{"Escape"===e.key&&R&&K(!1)};return typeof window<"u"&&R&&window.addEventListener("keydown",e),()=>{typeof window<"u"&&window.removeEventListener("keydown",e)}}),[K,R]),e.jsxs(e.Fragment,{children:[e.jsxs("select",{name:b,tabIndex:-1,"data-testid":"jkl-native-select",className:"jkl-sr-only","aria-hidden":!0,ref:te,value:W,onChange:d,children:[e.jsx("option",{value:""})," ",J.map((t=>e.jsx("option",{hidden:!t.visible,value:t.value,children:t.label},`${F}-opt-${t.value}`)))]}),e.jsx(i.InputGroup,{ref:ae,"data-testid":"jkl-select",className:t.clsx("jkl-select",_,{"jkl-select--inline":D,"jkl-select--open":R&&J.some((e=>e.visible)),"jkl-select--no-value":!Y,"jkl-select--invalid":!!P||C}),tooltipProps:A&&{...A,triggerProps:{...A.triggerProps,onFocus:e=>{var t,l;null==(l=null==(t=A.triggerProps)?void 0:t.onFocus)||l.call(t,e),de()}}},...V,id:O?M:I,style:{"--jkl-select-max-shown-options":N,...q},density:S,label:g,labelProps:{id:T,srOnly:D,...j,htmlFor:O?M:I},helpLabel:x,errorLabel:P,render:({"aria-invalid":l,...n})=>e.jsxs("div",{className:"jkl-select__outer-wrapper",style:{width:$},children:[O&&e.jsx("input",{...n,"aria-invalid":l,id:M,hidden:!H,ref:oe,placeholder:"Søk",value:G,onChange:e=>U(e.target.value),"data-testid":"jkl-select__search-input",className:"jkl-select__search-input","aria-autocomplete":"list","aria-activedescendant":Y?`${F}__${c.toLower(W)}`:void 0,"aria-controls":F,"aria-expanded":R,role:"combobox",onKeyDown:ke,onBlur:pe,onFocus:ve,onClick:e=>{e.stopPropagation()}}),e.jsx("button",{"aria-invalid":l,...n,id:I,ref:ue,hidden:H,type:"button",name:`${b}-btn`,className:t.clsx("jkl-select__button",{"jkl-select__button--active-value":!!W}),"data-testid":"jkl-select__button","aria-label":`${Z||"Velg"},${g}`,"aria-expanded":R,"aria-controls":F,onBlur:pe,onFocus:ve,onKeyDown:be,onClick:B,onMouseDown:e=>{var t;e.preventDefault(),null==(t=ue.current)||t.focus()},children:Z}),e.jsx("div",{id:F,ref:ce,role:"listbox",className:"jkl-select__options-menu",hidden:!R||J.every((e=>!e.visible)),"aria-labelledby":T,tabIndex:-1,"data-focus":"controlled",children:J.map(((t,l)=>t.visible?e.jsxs("button",{hidden:!t.visible,type:"button",id:`${F}__${c.toLower(t.value)}`,className:"jkl-select__option","data-testid":"jkl-select__option","aria-selected":t.value===W,role:"option",value:t.value,"data-testautoid":`jkl-select__option-${l}`,onBlur:pe,onFocus:ve,onKeyDown:me,onClick:e=>{e.preventDefault(),ne(t)},onMouseOver:fe,children:[t.label,t.description?e.jsx("span",{className:"jkl-select__option-description",children:t.description}):null]},`${F}-${t.value}`):null))}),e.jsx(u.ArrowVerticalAnimated,{variant:"medium",pointingDown:!R,className:"jkl-select__arrow"})]})})]})}));p.displayName="Select",exports.Select=p;
2
2
  //# sourceMappingURL=Select.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select.cjs","sources":["../../../../src/components/select/Select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n ChangeEvent,\n CSSProperties,\n FocusEvent,\n forwardRef,\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DataTestAutoId, Density } from \"../../core/types.js\";\nimport { useAnimatedHeight } from \"../../hooks/useAnimatedHeight/useAnimatedHeight.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { useListNavigation } from \"../../hooks/useListNavigation/useListNavigation.js\";\nimport { usePreviousValue } from \"../../hooks/usePreviousValue/usePreviousValue.js\";\nimport { getValuePair, ValuePair } from \"../../utilities/valuePair.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup, InputGroupProps } from \"../input-group/InputGroup.js\";\nimport { LabelProps } from \"../input-group/Label.js\";\nimport { focusSelected, toLower } from \"./select-utils.js\";\n\ninterface PartialChangeEvent\n extends Partial<Omit<ChangeEvent<HTMLSelectElement>, \"target\">> {\n /** Kreves av react-hook-form, det skjer ulike ting avhengig av om det er blur eller change */\n type: \"change\" | \"blur\";\n target: {\n /** Kreves av react-hook-form for å vite hvilket skjemafelt som ble endret */\n name: string;\n value: string;\n };\n}\n\ntype ChangeEventHandler = (event: PartialChangeEvent) => void;\n\ninterface Option extends ValuePair {\n visible: boolean;\n}\n\nexport interface SelectProps\n extends Omit<InputGroupProps, \"children\">,\n DataTestAutoId {\n id?: string;\n name: string;\n label: string;\n labelProps?: Omit<\n LabelProps,\n \"children\" | \"density\" | \"htmlFor\" | \"standAlone\"\n >;\n items: Array<string | ValuePair>;\n /**\n * @default false\n */\n inline?: boolean;\n /**\n * @default \"Velg\"\n */\n defaultPrompt?: string;\n className?: string;\n value?: string;\n helpLabel?: string;\n errorLabel?: string;\n /**\n * @default false\n */\n searchable?:\n | boolean\n | ((searchValue: string, searchItem: string | ValuePair) => boolean);\n density?: Density;\n width?: string;\n onChange?: ChangeEventHandler;\n onBlur?: ChangeEventHandler;\n onFocus?: ChangeEventHandler;\n /**\n * Merk som ugyldig uten å sende inn en errorLabel.\n * NB! Brukes kun i tilfeller der valideringsfeil dukker opp andre steder, for eksempel i en FieldGroup.\n */\n invalid?: boolean;\n /**\n * Hvor mange valg skal vises i listen før den begynner å scrolle.\n * @default 5\n */\n maxShownOptions?: number;\n}\n\nconst noop = () => {\n return;\n};\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n (props, forwardedSelectRef) => {\n const {\n id,\n name,\n items,\n value,\n label,\n labelProps,\n onChange,\n onBlur,\n onFocus,\n className,\n helpLabel,\n errorLabel,\n invalid,\n searchable = false,\n inline = false,\n defaultPrompt = \"Velg\",\n density,\n width,\n maxShownOptions = 5,\n style,\n tooltipProps,\n ...rest\n } = props;\n\n const listId = useId(id || \"jkl-select\", { generateSuffix: !id });\n const labelId = `${listId}_label`;\n const buttonId = `${listId}_button`;\n const searchInputId = `${listId}_search-input`;\n\n const [dropdownIsShown, setShown] = useState(false);\n const toggleListVisibility = useCallback(() => {\n setShown((previousValue) => !previousValue);\n }, []);\n\n /// Søk\n\n const isSearchable = Boolean(searchable);\n const showSearchInputField = isSearchable && dropdownIsShown;\n const [searchValue, setSearchValue] = useState(\"\");\n const searchFn = useCallback(\n (item: ValuePair) => {\n if (\n item.label.toLowerCase().includes(searchValue.toLowerCase())\n ) {\n return true;\n }\n\n if (typeof searchable === \"function\") {\n return searchable(searchValue, item);\n }\n\n return false;\n },\n [searchable, searchValue],\n );\n const visibleItems: Option[] = useMemo(\n () =>\n items.map(getValuePair).map((item) => {\n const visible =\n !isSearchable || searchValue === \"\" || searchFn(item);\n return { ...item, visible };\n }),\n [items, isSearchable, searchValue, searchFn],\n );\n const valueIsInItems: boolean = useMemo(() => {\n if (typeof value === \"undefined\") {\n return false;\n }\n return items.some((item) =>\n typeof item === \"string\"\n ? item === value\n : item.value === value,\n );\n }, [value, items]);\n\n /// Valg av <option>\n\n const [selectedValue, setSelectedValue] = useState<string>(\n valueIsInItems && value !== undefined ? value : \"\",\n );\n const hasSelectedValue = selectedValue !== \"\";\n const selectedValueLabel = useMemo(\n () =>\n visibleItems.find((item) => item.value === selectedValue)\n ?.label || defaultPrompt,\n [visibleItems, selectedValue, defaultPrompt],\n );\n\n const selectRef = useRef<HTMLSelectElement | null>(null);\n // Hjelpefunksjon som gjør det enklere å forwarde refen og å bruke den selv internt\n const unifiedSelectRef = useCallback(\n (instance: HTMLSelectElement | null) => {\n selectRef.current = instance;\n if (forwardedSelectRef) {\n if (typeof forwardedSelectRef === \"function\") {\n forwardedSelectRef(instance);\n } else {\n forwardedSelectRef.current = instance;\n }\n }\n if (instance) {\n setSelectedValue(instance.value);\n }\n },\n [selectRef, forwardedSelectRef],\n );\n\n const previousValue = usePreviousValue(value);\n useEffect(() => {\n if (value === previousValue) {\n return;\n }\n if (typeof value === \"undefined\" || !valueIsInItems) {\n setSelectedValue(\"\");\n } else {\n setSelectedValue(value);\n }\n }, [setSelectedValue, value, previousValue, valueIsInItems]);\n\n const selectOption = useCallback(\n (item: Option) => {\n const nextValue = item.value;\n setSearchValue(\"\");\n setSelectedValue(nextValue);\n toggleListVisibility();\n },\n [setSearchValue, setSelectedValue, toggleListVisibility],\n );\n\n // La komponenten rendre <select> med den valgte verdien før onChange trigges, slik at\n // react-hook-form@>7.41.1 behandler feltet som at det har en verdi.\n const previousSelectedValue = usePreviousValue(selectedValue);\n useEffect(() => {\n // previousSelectedValue er undefined på første render, men da vil vi ikke ha en onChange uansett\n if (\n typeof previousSelectedValue === \"undefined\" ||\n previousSelectedValue === selectedValue ||\n selectedValue === value\n ) {\n return;\n }\n if (onChange) {\n onChange({\n type: \"change\",\n target: { name, value: selectedValue },\n });\n }\n if (selectRef.current) {\n selectRef.current.dispatchEvent(\n new Event(\"change\", { bubbles: true }),\n );\n }\n }, [onChange, name, value, selectedValue, previousSelectedValue]);\n\n /// Fokushåndtering\n\n const componentRootElementRef = useRef<HTMLDivElement>(null);\n const focusInsideRef = useRef(false);\n const searchFieldRef = useRef<HTMLInputElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const handleFocusPlacement = useCallback(\n (isOpen: boolean, ref: RefObject<HTMLElement>) => {\n if (isOpen && !isSearchable) {\n const listElement = ref.current;\n if (listElement) {\n focusSelected(listElement, selectedValue);\n }\n } else if (isOpen) {\n if (searchFieldRef.current) {\n searchFieldRef.current.focus();\n }\n } else {\n if (focusInsideRef.current && buttonRef.current) {\n buttonRef.current.focus();\n }\n }\n },\n [isSearchable, selectedValue],\n );\n\n const [dropdownRef] = useAnimatedHeight<HTMLDivElement>(\n dropdownIsShown,\n {\n onFirstVisible: handleFocusPlacement,\n onTransitionEnd: handleFocusPlacement,\n },\n );\n\n useListNavigation({ ref: dropdownRef });\n\n const close = useCallback(() => {\n if (isSearchable) {\n setSearchValue(\"\");\n }\n if (onBlur) {\n onBlur({\n type: \"blur\",\n target: { name, value: selectedValue },\n });\n selectRef.current?.dispatchEvent(\n new Event(\"focusout\", { bubbles: true }),\n );\n }\n focusInsideRef.current = false;\n setShown(false);\n }, [\n onBlur,\n setSearchValue,\n setShown,\n isSearchable,\n name,\n selectedValue,\n ]);\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLButtonElement | HTMLInputElement>) => {\n const componentRootElement = componentRootElementRef.current;\n // There are known issues in Firefox when using \"relatedTarget\" in onBlur events:\n // https://github.com/facebook/react/issues/2011\n // This might be fixed in react 17. Se issue above.\n const nextFocusIsInsideComponent =\n componentRootElement &&\n componentRootElement.contains(e.relatedTarget as Node);\n if (!nextFocusIsInsideComponent) {\n close();\n }\n },\n [close],\n );\n\n const handleFocus = useCallback(() => {\n if (!focusInsideRef.current) {\n if (onFocus) {\n onFocus({\n type: \"change\",\n target: { name, value: selectedValue },\n });\n }\n focusInsideRef.current = true;\n }\n }, [onFocus, selectedValue, name]);\n\n const handleMouseOver = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n // Ved mouseOver på options flytter vi fokus til dem for å unngå \"dobbel fokus\"\n // der det ser ut som to forskjellige elementer er fokusert/hovered samtidig\n (e.target as HTMLButtonElement).focus({ preventScroll: true });\n },\n [],\n );\n\n // Handle focus and blur of hidden select element\n useEffect(() => {\n const select = selectRef.current;\n const searchField = searchFieldRef.current;\n const button = buttonRef.current;\n const componentRootElement = componentRootElementRef.current;\n\n select?.addEventListener(\"focus\", () => {\n showSearchInputField ? searchField?.focus() : button?.focus();\n });\n select?.addEventListener(\"blur\", function (this, ev) {\n componentRootElement &&\n componentRootElement.contains(ev.relatedTarget as Node) &&\n ev.preventDefault();\n });\n\n return () => {\n select?.removeEventListener(\"focus\", () => {\n showSearchInputField\n ? searchField?.focus()\n : button?.focus();\n });\n select?.removeEventListener(\"blur\", function (this, ev) {\n componentRootElement &&\n componentRootElement.contains(\n ev.relatedTarget as Node,\n ) &&\n ev.preventDefault();\n });\n };\n }, [showSearchInputField]);\n\n /// Tastaturnavigasjon\n\n // Add support for opening dropdown with arrowkey down as expected from native select\n // onKeyDown to stop ArrowDown from scrolling the page\n const handleOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (\n (e.key === \"ArrowDown\" || e.key === \" \") &&\n !dropdownIsShown\n ) {\n e.preventDefault();\n e.stopPropagation();\n setShown(true);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShown(false);\n }\n },\n [setShown, dropdownIsShown],\n );\n\n // onKeyDown to stop ArrowDown from scrolling the page\n const handleSearchOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n\n const listElement = dropdownRef.current;\n if (listElement) {\n if (isSearchable) {\n // Flytt fokus til det første elementet i listen, ikke det forrige valgte.\n // Ved endring i filter er det ikke gitt at vi ønsker å ta utgangspunkt i\n // den valgte verdien.\n focusSelected(listElement, undefined);\n } else {\n focusSelected(listElement, selectedValue);\n }\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShown(false);\n } else if (e.key === \"Tab\" && !e.shiftKey) {\n const listElement = dropdownRef.current;\n if (listElement) {\n e.preventDefault();\n e.stopPropagation();\n focusSelected(listElement, selectedValue);\n }\n } else if (e.key === \"Enter\" && dropdownIsShown) {\n // Should not propagate Enter keyevent because form might submit\n e.preventDefault();\n e.stopPropagation();\n }\n },\n [\n setShown,\n dropdownRef,\n selectedValue,\n isSearchable,\n dropdownIsShown,\n ],\n );\n\n // onKeyDown so this Tab listener isn't triggered by tabbing from search field to option\n const handleOptionOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Tab\") {\n e.preventDefault();\n e.stopPropagation();\n\n if (e.shiftKey && searchFieldRef.current) {\n searchFieldRef.current.focus();\n } else if (buttonRef.current) {\n // Mimic behaviour of Firefox and native select, where Tab selects the current item and closes the menu\n setSelectedValue(e.currentTarget.value);\n setShown(false);\n buttonRef.current.focus();\n }\n } else if (e.key === \"ArrowUp\") {\n if (dropdownRef.current && searchFieldRef.current) {\n // Can't be based on index since the first item might be filtered out\n const firstVisible = dropdownRef.current.querySelector(\n '[role=\"option\"]:not([hidden])',\n );\n if (\n e.currentTarget.id === firstVisible?.id &&\n searchFieldRef.current\n ) {\n searchFieldRef.current.focus();\n }\n }\n }\n },\n [setShown, dropdownRef],\n );\n\n // Add support for closing the dropdown with Escape like native select. Unfortunately, Escape does not trigger the button onKeyDown.\n useEffect(() => {\n const handleEscape = (e: globalThis.KeyboardEvent) => {\n if (e.key === \"Escape\" && dropdownIsShown) {\n setShown(false);\n }\n };\n if (typeof window !== \"undefined\" && dropdownIsShown) {\n window.addEventListener(\"keydown\", handleEscape);\n }\n return () => {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", handleEscape);\n }\n };\n }, [setShown, dropdownIsShown]);\n\n return (\n <>\n <select\n name={name}\n tabIndex={-1}\n data-testid=\"jkl-native-select\"\n className=\"jkl-sr-only\"\n aria-hidden\n ref={unifiedSelectRef}\n value={selectedValue}\n onChange={noop} // React complains unless we give an onChange handler. This is technically a read-only field, but readOnly isn't an option here.\n >\n <option value=\"\"></option>{\" \"}\n {/* Tom option må være et valg, ellers vil <select> alltid ha en value */}\n {visibleItems.map((item) => (\n <option\n key={`${listId}-opt-${item.value}`}\n hidden={!item.visible}\n value={item.value}\n >\n {item.label}\n </option>\n ))}\n </select>\n <InputGroup\n ref={componentRootElementRef}\n data-testid=\"jkl-select\"\n className={clsx(\"jkl-select\", className, {\n \"jkl-select--inline\": inline,\n \"jkl-select--open\":\n dropdownIsShown &&\n visibleItems.some((item) => item.visible),\n \"jkl-select--no-value\": !hasSelectedValue,\n \"jkl-select--invalid\": !!errorLabel || invalid,\n })}\n tooltipProps={\n tooltipProps && {\n ...tooltipProps,\n triggerProps: {\n ...tooltipProps.triggerProps,\n onFocus: (e) => {\n tooltipProps.triggerProps?.onFocus?.(e);\n close();\n },\n },\n }\n }\n {...rest}\n id={isSearchable ? searchInputId : buttonId}\n style={\n {\n [\"--jkl-select-max-shown-options\"]: maxShownOptions,\n ...style,\n } as CSSProperties\n }\n density={density}\n label={label}\n labelProps={{\n id: labelId,\n srOnly: inline,\n ...labelProps,\n htmlFor: isSearchable ? searchInputId : buttonId,\n }}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n render={(inputProps) => (\n <div\n className=\"jkl-select__outer-wrapper\"\n style={{ width }}\n >\n {isSearchable && (\n <input\n {...inputProps}\n id={searchInputId}\n hidden={!showSearchInputField}\n ref={searchFieldRef}\n placeholder=\"Søk\"\n value={searchValue}\n onChange={(e) =>\n setSearchValue(e.target.value)\n }\n data-testid=\"jkl-select__search-input\"\n className=\"jkl-select__search-input\"\n aria-autocomplete=\"list\"\n aria-activedescendant={\n hasSelectedValue\n ? `${listId}__${toLower(\n selectedValue,\n )}`\n : undefined\n }\n aria-controls={listId}\n aria-expanded={dropdownIsShown}\n role=\"combobox\"\n onKeyDown={handleSearchOnKeyDown}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onClick={(e) => {\n e.stopPropagation();\n }}\n />\n )}\n <button\n {...inputProps}\n id={buttonId}\n ref={buttonRef}\n hidden={showSearchInputField}\n type=\"button\"\n name={`${name}-btn`}\n className={clsx(\"jkl-select__button\", {\n \"jkl-select__button--active-value\":\n !!selectedValue,\n })}\n data-testid=\"jkl-select__button\"\n aria-label={`${\n selectedValueLabel || \"Velg\"\n },${label}`}\n aria-expanded={dropdownIsShown}\n aria-controls={listId}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={handleOnKeyDown}\n onClick={toggleListVisibility}\n onMouseDown={(e) => {\n // Workaround for en Safari-bug hvor e.relatedTarget er null i onBlur\n // https://twitter.com/MilesSorce/status/1278762360669265925\n e.preventDefault();\n buttonRef.current?.focus();\n }}\n >\n {selectedValueLabel}\n </button>\n <div\n id={listId}\n ref={dropdownRef}\n role=\"listbox\"\n className=\"jkl-select__options-menu\"\n hidden={\n !dropdownIsShown ||\n visibleItems.every((item) => !item.visible)\n }\n aria-labelledby={labelId}\n tabIndex={-1}\n data-focus=\"controlled\" // lar oss styre markering av valg vha focus\n >\n {visibleItems.map((item, i) =>\n // Det er viktig at vi _fjerner_ elementer som ikke er synlige fra DOMen for at tastaturnavigasjon skal fungere.\n // For eksempel, hvis vi har elementene Apple, Samsung og LG i den rekkefølgen og søker etter \"l\"\n // vil Samsung ikke synes. Om vi bare setter hidden-attributtet på Samsung vil ArrowDown fra Apple ikke fungere.\n // Dette lar seg ikke gjenskape i en enhetstest med JSDOM + user-events, og Cypress lukker Select\n // ved første {downArrow} ¯\\_(ツ)_/¯. Så please test scenariet over manuelt om dette skaper trøbbel for deg.\n item.visible ? (\n <button\n key={`${listId}-${item.value}`}\n hidden={!item.visible}\n type=\"button\"\n id={`${listId}__${toLower(\n item.value,\n )}`}\n className=\"jkl-select__option\"\n data-testid=\"jkl-select__option\"\n aria-selected={\n item.value === selectedValue\n }\n role=\"option\"\n value={item.value}\n data-testautoid={`jkl-select__option-${i}`}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={handleOptionOnKeyDown}\n onClick={(e) => {\n e.preventDefault();\n selectOption(item);\n }}\n onMouseOver={handleMouseOver}\n >\n {item.label}\n {item.description ? (\n <span className=\"jkl-select__option-description\">\n {item.description}\n </span>\n ) : null}\n </button>\n ) : null,\n )}\n </div>\n <ArrowVerticalAnimated\n variant=\"medium\"\n pointingDown={!dropdownIsShown}\n className=\"jkl-select__arrow\"\n />\n </div>\n )}\n />\n </>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n"],"names":["noop","Select","forwardRef","props","forwardedSelectRef","id","name","items","value","label","labelProps","onChange","onBlur","onFocus","className","helpLabel","errorLabel","invalid","searchable","inline","defaultPrompt","density","width","maxShownOptions","style","tooltipProps","rest","listId","useId","generateSuffix","labelId","buttonId","searchInputId","dropdownIsShown","setShown","useState","toggleListVisibility","useCallback","previousValue","isSearchable","showSearchInputField","searchValue","setSearchValue","searchFn","item","toLowerCase","includes","visibleItems","useMemo","map","getValuePair","visible","valueIsInItems","some","selectedValue","setSelectedValue","hasSelectedValue","selectedValueLabel","_a","find","selectRef","useRef","unifiedSelectRef","instance","current","usePreviousValue","useEffect","selectOption","nextValue","previousSelectedValue","type","target","dispatchEvent","Event","bubbles","componentRootElementRef","focusInsideRef","searchFieldRef","buttonRef","handleFocusPlacement","isOpen","ref","listElement","focusSelected","focus","dropdownRef","useAnimatedHeight","onFirstVisible","onTransitionEnd","useListNavigation","close","handleBlur","e","componentRootElement","contains","relatedTarget","handleFocus","handleMouseOver","preventScroll","select","searchField","button","addEventListener","ev","preventDefault","removeEventListener","handleOnKeyDown","key","stopPropagation","handleSearchOnKeyDown","shiftKey","handleOptionOnKeyDown","currentTarget","firstVisible","querySelector","handleEscape","window","jsxs","Fragment","children","tabIndex","jsx","hidden","InputGroup","clsx","triggerProps","_b","call","srOnly","htmlFor","render","inputProps","placeholder","toLower","role","onKeyDown","onClick","onMouseDown","every","i","onMouseOver","description","ArrowVerticalAnimated","variant","pointingDown","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"Select.cjs","sources":["../../../../src/components/select/Select.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n ChangeEvent,\n CSSProperties,\n FocusEvent,\n forwardRef,\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DataTestAutoId, Density } from \"../../core/types.js\";\nimport { useAnimatedHeight } from \"../../hooks/useAnimatedHeight/useAnimatedHeight.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { useListNavigation } from \"../../hooks/useListNavigation/useListNavigation.js\";\nimport { usePreviousValue } from \"../../hooks/usePreviousValue/usePreviousValue.js\";\nimport { getValuePair, ValuePair } from \"../../utilities/valuePair.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup, InputGroupProps } from \"../input-group/InputGroup.js\";\nimport { LabelProps } from \"../input-group/Label.js\";\nimport { focusSelected, toLower } from \"./select-utils.js\";\n\ninterface PartialChangeEvent\n extends Partial<Omit<ChangeEvent<HTMLSelectElement>, \"target\">> {\n /** Kreves av react-hook-form, det skjer ulike ting avhengig av om det er blur eller change */\n type: \"change\" | \"blur\";\n target: {\n /** Kreves av react-hook-form for å vite hvilket skjemafelt som ble endret */\n name: string;\n value: string;\n };\n}\n\ntype ChangeEventHandler = (event: PartialChangeEvent) => void;\n\ninterface Option extends ValuePair {\n visible: boolean;\n}\n\nexport interface SelectProps\n extends Omit<InputGroupProps, \"children\">,\n DataTestAutoId {\n id?: string;\n name: string;\n label: string;\n labelProps?: Omit<\n LabelProps,\n \"children\" | \"density\" | \"htmlFor\" | \"standAlone\"\n >;\n items: Array<string | ValuePair>;\n /**\n * @default false\n */\n inline?: boolean;\n /**\n * @default \"Velg\"\n */\n defaultPrompt?: string;\n className?: string;\n value?: string;\n helpLabel?: string;\n errorLabel?: string;\n /**\n * @default false\n */\n searchable?:\n | boolean\n | ((searchValue: string, searchItem: string | ValuePair) => boolean);\n density?: Density;\n width?: string;\n onChange?: ChangeEventHandler;\n onBlur?: ChangeEventHandler;\n onFocus?: ChangeEventHandler;\n /**\n * Merk som ugyldig uten å sende inn en errorLabel.\n * NB! Brukes kun i tilfeller der valideringsfeil dukker opp andre steder, for eksempel i en FieldGroup.\n */\n invalid?: boolean;\n /**\n * Hvor mange valg skal vises i listen før den begynner å scrolle.\n * @default 5\n */\n maxShownOptions?: number;\n}\n\nconst noop = () => {\n return;\n};\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(\n (props, forwardedSelectRef) => {\n const {\n id,\n name,\n items,\n value,\n label,\n labelProps,\n onChange,\n onBlur,\n onFocus,\n className,\n helpLabel,\n errorLabel,\n invalid,\n searchable = false,\n inline = false,\n defaultPrompt = \"Velg\",\n density,\n width,\n maxShownOptions = 5,\n style,\n tooltipProps,\n ...rest\n } = props;\n\n const listId = useId(id || \"jkl-select\", { generateSuffix: !id });\n const labelId = `${listId}_label`;\n const buttonId = `${listId}_button`;\n const searchInputId = `${listId}_search-input`;\n\n const [dropdownIsShown, setShown] = useState(false);\n const toggleListVisibility = useCallback(() => {\n setShown((previousValue) => !previousValue);\n }, []);\n\n /// Søk\n\n const isSearchable = Boolean(searchable);\n const showSearchInputField = isSearchable && dropdownIsShown;\n const [searchValue, setSearchValue] = useState(\"\");\n const searchFn = useCallback(\n (item: ValuePair) => {\n if (\n item.label.toLowerCase().includes(searchValue.toLowerCase())\n ) {\n return true;\n }\n\n if (typeof searchable === \"function\") {\n return searchable(searchValue, item);\n }\n\n return false;\n },\n [searchable, searchValue],\n );\n const visibleItems: Option[] = useMemo(\n () =>\n items.map(getValuePair).map((item) => {\n const visible =\n !isSearchable || searchValue === \"\" || searchFn(item);\n return { ...item, visible };\n }),\n [items, isSearchable, searchValue, searchFn],\n );\n const valueIsInItems: boolean = useMemo(() => {\n if (typeof value === \"undefined\") {\n return false;\n }\n return items.some((item) =>\n typeof item === \"string\"\n ? item === value\n : item.value === value,\n );\n }, [value, items]);\n\n /// Valg av <option>\n\n const [selectedValue, setSelectedValue] = useState<string>(\n valueIsInItems && value !== undefined ? value : \"\",\n );\n const hasSelectedValue = selectedValue !== \"\";\n const selectedValueLabel = useMemo(\n () =>\n visibleItems.find((item) => item.value === selectedValue)\n ?.label || defaultPrompt,\n [visibleItems, selectedValue, defaultPrompt],\n );\n\n const selectRef = useRef<HTMLSelectElement | null>(null);\n // Hjelpefunksjon som gjør det enklere å forwarde refen og å bruke den selv internt\n const unifiedSelectRef = useCallback(\n (instance: HTMLSelectElement | null) => {\n selectRef.current = instance;\n if (forwardedSelectRef) {\n if (typeof forwardedSelectRef === \"function\") {\n forwardedSelectRef(instance);\n } else {\n forwardedSelectRef.current = instance;\n }\n }\n if (instance) {\n setSelectedValue(instance.value);\n }\n },\n [selectRef, forwardedSelectRef],\n );\n\n const previousValue = usePreviousValue(value);\n useEffect(() => {\n if (value === previousValue) {\n return;\n }\n if (typeof value === \"undefined\" || !valueIsInItems) {\n setSelectedValue(\"\");\n } else {\n setSelectedValue(value);\n }\n }, [setSelectedValue, value, previousValue, valueIsInItems]);\n\n const selectOption = useCallback(\n (item: Option) => {\n const nextValue = item.value;\n setSearchValue(\"\");\n setSelectedValue(nextValue);\n toggleListVisibility();\n },\n [setSearchValue, setSelectedValue, toggleListVisibility],\n );\n\n // La komponenten rendre <select> med den valgte verdien før onChange trigges, slik at\n // react-hook-form@>7.41.1 behandler feltet som at det har en verdi.\n const previousSelectedValue = usePreviousValue(selectedValue);\n useEffect(() => {\n // previousSelectedValue er undefined på første render, men da vil vi ikke ha en onChange uansett\n if (\n typeof previousSelectedValue === \"undefined\" ||\n previousSelectedValue === selectedValue ||\n selectedValue === value\n ) {\n return;\n }\n if (onChange) {\n onChange({\n type: \"change\",\n target: { name, value: selectedValue },\n });\n }\n if (selectRef.current) {\n selectRef.current.dispatchEvent(\n new Event(\"change\", { bubbles: true }),\n );\n }\n }, [onChange, name, value, selectedValue, previousSelectedValue]);\n\n /// Fokushåndtering\n\n const componentRootElementRef = useRef<HTMLDivElement>(null);\n const focusInsideRef = useRef(false);\n const searchFieldRef = useRef<HTMLInputElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const handleFocusPlacement = useCallback(\n (isOpen: boolean, ref: RefObject<HTMLElement>) => {\n if (isOpen && !isSearchable) {\n const listElement = ref.current;\n if (listElement) {\n focusSelected(listElement, selectedValue);\n }\n } else if (isOpen) {\n if (searchFieldRef.current) {\n searchFieldRef.current.focus();\n }\n } else {\n if (focusInsideRef.current && buttonRef.current) {\n buttonRef.current.focus();\n }\n }\n },\n [isSearchable, selectedValue],\n );\n\n const [dropdownRef] = useAnimatedHeight<HTMLDivElement>(\n dropdownIsShown,\n {\n onFirstVisible: handleFocusPlacement,\n onTransitionEnd: handleFocusPlacement,\n },\n );\n\n useListNavigation({ ref: dropdownRef });\n\n const close = useCallback(() => {\n if (isSearchable) {\n setSearchValue(\"\");\n }\n if (onBlur) {\n onBlur({\n type: \"blur\",\n target: { name, value: selectedValue },\n });\n selectRef.current?.dispatchEvent(\n new Event(\"focusout\", { bubbles: true }),\n );\n }\n focusInsideRef.current = false;\n setShown(false);\n }, [\n onBlur,\n setSearchValue,\n setShown,\n isSearchable,\n name,\n selectedValue,\n ]);\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLButtonElement | HTMLInputElement>) => {\n const componentRootElement = componentRootElementRef.current;\n // There are known issues in Firefox when using \"relatedTarget\" in onBlur events:\n // https://github.com/facebook/react/issues/2011\n // This might be fixed in react 17. Se issue above.\n const nextFocusIsInsideComponent =\n componentRootElement &&\n componentRootElement.contains(e.relatedTarget as Node);\n if (!nextFocusIsInsideComponent) {\n close();\n }\n },\n [close],\n );\n\n const handleFocus = useCallback(() => {\n if (!focusInsideRef.current) {\n if (onFocus) {\n onFocus({\n type: \"change\",\n target: { name, value: selectedValue },\n });\n }\n focusInsideRef.current = true;\n }\n }, [onFocus, selectedValue, name]);\n\n const handleMouseOver = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n // Ved mouseOver på options flytter vi fokus til dem for å unngå \"dobbel fokus\"\n // der det ser ut som to forskjellige elementer er fokusert/hovered samtidig\n (e.target as HTMLButtonElement).focus({ preventScroll: true });\n },\n [],\n );\n\n // Handle focus and blur of hidden select element\n useEffect(() => {\n const select = selectRef.current;\n const searchField = searchFieldRef.current;\n const button = buttonRef.current;\n const componentRootElement = componentRootElementRef.current;\n\n select?.addEventListener(\"focus\", () => {\n showSearchInputField ? searchField?.focus() : button?.focus();\n });\n select?.addEventListener(\"blur\", function (this, ev) {\n componentRootElement &&\n componentRootElement.contains(ev.relatedTarget as Node) &&\n ev.preventDefault();\n });\n\n return () => {\n select?.removeEventListener(\"focus\", () => {\n showSearchInputField\n ? searchField?.focus()\n : button?.focus();\n });\n select?.removeEventListener(\"blur\", function (this, ev) {\n componentRootElement &&\n componentRootElement.contains(\n ev.relatedTarget as Node,\n ) &&\n ev.preventDefault();\n });\n };\n }, [showSearchInputField]);\n\n /// Tastaturnavigasjon\n\n // Add support for opening dropdown with arrowkey down as expected from native select\n // onKeyDown to stop ArrowDown from scrolling the page\n const handleOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (\n (e.key === \"ArrowDown\" || e.key === \" \") &&\n !dropdownIsShown\n ) {\n e.preventDefault();\n e.stopPropagation();\n setShown(true);\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShown(false);\n }\n },\n [setShown, dropdownIsShown],\n );\n\n // onKeyDown to stop ArrowDown from scrolling the page\n const handleSearchOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n\n const listElement = dropdownRef.current;\n if (listElement) {\n if (isSearchable) {\n // Flytt fokus til det første elementet i listen, ikke det forrige valgte.\n // Ved endring i filter er det ikke gitt at vi ønsker å ta utgangspunkt i\n // den valgte verdien.\n focusSelected(listElement, undefined);\n } else {\n focusSelected(listElement, selectedValue);\n }\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShown(false);\n } else if (e.key === \"Tab\" && !e.shiftKey) {\n const listElement = dropdownRef.current;\n if (listElement) {\n e.preventDefault();\n e.stopPropagation();\n focusSelected(listElement, selectedValue);\n }\n } else if (e.key === \"Enter\" && dropdownIsShown) {\n // Should not propagate Enter keyevent because form might submit\n e.preventDefault();\n e.stopPropagation();\n }\n },\n [\n setShown,\n dropdownRef,\n selectedValue,\n isSearchable,\n dropdownIsShown,\n ],\n );\n\n // onKeyDown so this Tab listener isn't triggered by tabbing from search field to option\n const handleOptionOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Tab\") {\n e.preventDefault();\n e.stopPropagation();\n\n if (e.shiftKey && searchFieldRef.current) {\n searchFieldRef.current.focus();\n } else if (buttonRef.current) {\n // Mimic behaviour of Firefox and native select, where Tab selects the current item and closes the menu\n setSelectedValue(e.currentTarget.value);\n setShown(false);\n buttonRef.current.focus();\n }\n } else if (e.key === \"ArrowUp\") {\n if (dropdownRef.current && searchFieldRef.current) {\n // Can't be based on index since the first item might be filtered out\n const firstVisible = dropdownRef.current.querySelector(\n '[role=\"option\"]:not([hidden])',\n );\n if (\n e.currentTarget.id === firstVisible?.id &&\n searchFieldRef.current\n ) {\n searchFieldRef.current.focus();\n }\n }\n }\n },\n [setShown, dropdownRef],\n );\n\n // Add support for closing the dropdown with Escape like native select. Unfortunately, Escape does not trigger the button onKeyDown.\n useEffect(() => {\n const handleEscape = (e: globalThis.KeyboardEvent) => {\n if (e.key === \"Escape\" && dropdownIsShown) {\n setShown(false);\n }\n };\n if (typeof window !== \"undefined\" && dropdownIsShown) {\n window.addEventListener(\"keydown\", handleEscape);\n }\n return () => {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", handleEscape);\n }\n };\n }, [setShown, dropdownIsShown]);\n\n return (\n <>\n <select\n name={name}\n tabIndex={-1}\n data-testid=\"jkl-native-select\"\n className=\"jkl-sr-only\"\n aria-hidden\n ref={unifiedSelectRef}\n value={selectedValue}\n onChange={noop} // React complains unless we give an onChange handler. This is technically a read-only field, but readOnly isn't an option here.\n >\n <option value=\"\"></option>{\" \"}\n {/* Tom option må være et valg, ellers vil <select> alltid ha en value */}\n {visibleItems.map((item) => (\n <option\n key={`${listId}-opt-${item.value}`}\n hidden={!item.visible}\n value={item.value}\n >\n {item.label}\n </option>\n ))}\n </select>\n <InputGroup\n ref={componentRootElementRef}\n data-testid=\"jkl-select\"\n className={clsx(\"jkl-select\", className, {\n \"jkl-select--inline\": inline,\n \"jkl-select--open\":\n dropdownIsShown &&\n visibleItems.some((item) => item.visible),\n \"jkl-select--no-value\": !hasSelectedValue,\n \"jkl-select--invalid\": !!errorLabel || invalid,\n })}\n tooltipProps={\n tooltipProps && {\n ...tooltipProps,\n triggerProps: {\n ...tooltipProps.triggerProps,\n onFocus: (e) => {\n tooltipProps.triggerProps?.onFocus?.(e);\n close();\n },\n },\n }\n }\n {...rest}\n id={isSearchable ? searchInputId : buttonId}\n style={\n {\n [\"--jkl-select-max-shown-options\"]: maxShownOptions,\n ...style,\n } as CSSProperties\n }\n density={density}\n label={label}\n labelProps={{\n id: labelId,\n srOnly: inline,\n ...labelProps,\n htmlFor: isSearchable ? searchInputId : buttonId,\n }}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n render={({\n \"aria-invalid\": ariaInvalid,\n ...inputProps\n }) => (\n <div\n className=\"jkl-select__outer-wrapper\"\n style={{ width }}\n >\n {isSearchable && (\n <input\n {...inputProps}\n aria-invalid={ariaInvalid}\n id={searchInputId}\n hidden={!showSearchInputField}\n ref={searchFieldRef}\n placeholder=\"Søk\"\n value={searchValue}\n onChange={(e) =>\n setSearchValue(e.target.value)\n }\n data-testid=\"jkl-select__search-input\"\n className=\"jkl-select__search-input\"\n aria-autocomplete=\"list\"\n aria-activedescendant={\n hasSelectedValue\n ? `${listId}__${toLower(\n selectedValue,\n )}`\n : undefined\n }\n aria-controls={listId}\n aria-expanded={dropdownIsShown}\n role=\"combobox\"\n onKeyDown={handleSearchOnKeyDown}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onClick={(e) => {\n e.stopPropagation();\n }}\n />\n )}\n {/* eslint-disable-next-line jsx-a11y/role-supports-aria-props */}\n <button\n // Nei dette er ikke i henhold til speccen, men VoiceOver leser den likevel og det er oppførselen vi ønsker\n aria-invalid={ariaInvalid}\n {...inputProps}\n id={buttonId}\n ref={buttonRef}\n hidden={showSearchInputField}\n type=\"button\"\n name={`${name}-btn`}\n className={clsx(\"jkl-select__button\", {\n \"jkl-select__button--active-value\":\n !!selectedValue,\n })}\n data-testid=\"jkl-select__button\"\n aria-label={`${\n selectedValueLabel || \"Velg\"\n },${label}`}\n aria-expanded={dropdownIsShown}\n aria-controls={listId}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={handleOnKeyDown}\n onClick={toggleListVisibility}\n onMouseDown={(e) => {\n // Workaround for en Safari-bug hvor e.relatedTarget er null i onBlur\n // https://twitter.com/MilesSorce/status/1278762360669265925\n e.preventDefault();\n buttonRef.current?.focus();\n }}\n >\n {selectedValueLabel}\n </button>\n <div\n id={listId}\n ref={dropdownRef}\n role=\"listbox\"\n className=\"jkl-select__options-menu\"\n hidden={\n !dropdownIsShown ||\n visibleItems.every((item) => !item.visible)\n }\n aria-labelledby={labelId}\n tabIndex={-1}\n data-focus=\"controlled\" // lar oss styre markering av valg vha focus\n >\n {visibleItems.map((item, i) =>\n // Det er viktig at vi _fjerner_ elementer som ikke er synlige fra DOMen for at tastaturnavigasjon skal fungere.\n // For eksempel, hvis vi har elementene Apple, Samsung og LG i den rekkefølgen og søker etter \"l\"\n // vil Samsung ikke synes. Om vi bare setter hidden-attributtet på Samsung vil ArrowDown fra Apple ikke fungere.\n // Dette lar seg ikke gjenskape i en enhetstest med JSDOM + user-events, og Cypress lukker Select\n // ved første {downArrow} ¯\\_(ツ)_/¯. Så please test scenariet over manuelt om dette skaper trøbbel for deg.\n item.visible ? (\n <button\n key={`${listId}-${item.value}`}\n hidden={!item.visible}\n type=\"button\"\n id={`${listId}__${toLower(\n item.value,\n )}`}\n className=\"jkl-select__option\"\n data-testid=\"jkl-select__option\"\n aria-selected={\n item.value === selectedValue\n }\n role=\"option\"\n value={item.value}\n data-testautoid={`jkl-select__option-${i}`}\n onBlur={handleBlur}\n onFocus={handleFocus}\n onKeyDown={handleOptionOnKeyDown}\n onClick={(e) => {\n e.preventDefault();\n selectOption(item);\n }}\n onMouseOver={handleMouseOver}\n >\n {item.label}\n {item.description ? (\n <span className=\"jkl-select__option-description\">\n {item.description}\n </span>\n ) : null}\n </button>\n ) : null,\n )}\n </div>\n <ArrowVerticalAnimated\n variant=\"medium\"\n pointingDown={!dropdownIsShown}\n className=\"jkl-select__arrow\"\n />\n </div>\n )}\n />\n </>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n"],"names":["noop","Select","forwardRef","props","forwardedSelectRef","id","name","items","value","label","labelProps","onChange","onBlur","onFocus","className","helpLabel","errorLabel","invalid","searchable","inline","defaultPrompt","density","width","maxShownOptions","style","tooltipProps","rest","listId","useId","generateSuffix","labelId","buttonId","searchInputId","dropdownIsShown","setShown","useState","toggleListVisibility","useCallback","previousValue","isSearchable","showSearchInputField","searchValue","setSearchValue","searchFn","item","toLowerCase","includes","visibleItems","useMemo","map","getValuePair","visible","valueIsInItems","some","selectedValue","setSelectedValue","hasSelectedValue","selectedValueLabel","_a","find","selectRef","useRef","unifiedSelectRef","instance","current","usePreviousValue","useEffect","selectOption","nextValue","previousSelectedValue","type","target","dispatchEvent","Event","bubbles","componentRootElementRef","focusInsideRef","searchFieldRef","buttonRef","handleFocusPlacement","isOpen","ref","listElement","focusSelected","focus","dropdownRef","useAnimatedHeight","onFirstVisible","onTransitionEnd","useListNavigation","close","handleBlur","e","componentRootElement","contains","relatedTarget","handleFocus","handleMouseOver","preventScroll","select","searchField","button","addEventListener","ev","preventDefault","removeEventListener","handleOnKeyDown","key","stopPropagation","handleSearchOnKeyDown","shiftKey","handleOptionOnKeyDown","currentTarget","firstVisible","querySelector","handleEscape","window","jsxs","Fragment","children","tabIndex","jsx","hidden","InputGroup","clsx","triggerProps","_b","call","srOnly","htmlFor","render","ariaInvalid","inputProps","placeholder","toLower","role","onKeyDown","onClick","onMouseDown","every","i","onMouseOver","description","ArrowVerticalAnimated","variant","pointingDown","displayName"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";module.exports={breakpoint:{medium:"680px",large:"1200px",xl:"1600px"},color:{brand:{snohvit:"#F9F9F9",varde:"#E0DBD4",granitt:"#1B1917",hvit:"#FFFFFF",svart:"#000000",skifer:"#313030",fjellgra:"#444141",stein:"#636060",svaberg:"#C8C5C3",dis:"#ECE9E5",sand:"#F4F2EF"},functional:{info:"#D3D3F6",infoDark:"#A9A9CA",success:"#ACD3B5",successDark:"#94B79B",warning:"#EFDD9E",warningDark:"#DECC8D",error:"#F6B3B3",errorDark:"#DE9E9E"},background:{page:{light:"#F4F2EF",dark:"#1B1917"},pageVariant:{light:"#F9F9F9",dark:"#1B1917"},container:{light:"#F9F9F9",dark:"#313030"},containerLow:{light:"#ECE9E5",dark:"#000000"},containerHigh:{light:"#FFFFFF",dark:"#313030"},containerInverted:{light:"#1B1917",dark:"#F9F9F9"},containerSubdued:{light:"#C8C5C3",dark:"#636060"},input:{base:{light:"transparent",dark:"transparent"},focus:{light:"#FFFFFF",dark:"#313030"}},action:{light:"#1B1917",dark:"#F9F9F9"},interactive:{light:"transparent",dark:"transparent"},interactiveHover:{light:"#ECE9E5",dark:"#444141"},interactiveSelected:{light:"#E0DBD4",dark:"#636060"},alert:{neutral:{light:"#E0DBD4",dark:"#E0DBD4"},info:{light:"#D3D3F6",dark:"#A9A9CA"},success:{light:"#ACD3B5",dark:"#94B79B"},warning:{light:"#EFDD9E",dark:"#DECC8D"},error:{light:"#F6B3B3",dark:"#DE9E9E"}}},text:{default:{light:"#1B1917",dark:"#F9F9F9"},subdued:{light:"#636060",dark:"#C8C5C3"},inverted:{light:"#F9F9F9",dark:"#1B1917"},onAction:{light:"#F9F9F9",dark:"#1B1917"},interactive:{light:"#1B1917",dark:"#F9F9F9"},interactiveHover:{light:"#636060",dark:"#C8C5C3"},onAlert:{light:"#1B1917",dark:"#1B1917"}},border:{action:{light:"#1B1917",dark:"#F9F9F9"},input:{light:"#636060",dark:"#C8C5C3"},inputFocus:{light:"#1B1917",dark:"#F9F9F9"},separator:{light:"#C8C5C3",dark:"#636060"},separatorStrong:{light:"#636060",dark:"#C8C5C3"},separatorHover:{light:"#1B1917",dark:"#F9F9F9"},subdued:{light:"#C8C5C3",dark:"#636060"}},svart:"#000",granitt:"#1b1917",skifer:"#313030",fjellgra:"#444141",stein:"#636060",svaberg:"#c8c5c3",varde:"#e0dbd4",dis:"#ece9e5",sand:"#f4f2ef",snohvit:"#f9f9f9",hvit:"#fff",suksess:"#acd3b5",suksessDark:"#94b79b",feil:"#f6b3b3",feilDark:"#de9e9e",info:"#d3d3f6",infoDark:"#a9a9ca",advarsel:"#efdd9e",advarselDark:"#decc8d"},motion:{timing:{energetic:"75ms",snappy:"100ms",productive:"150ms",expressive:"250ms",lazy:"400ms"},easing:{standard:"ease",entrance:"ease-out",exit:"ease-in",easeInBounceOut:"cubic-bezier(0, 0, 0.375, 1.17)",focus:"cubic-bezier(0.6, 0.2, 0.35, 1)"}},spacing:{0:"0",2:"0.125rem",4:"0.25rem",8:"0.5rem",12:"0.75rem",16:"1rem",24:"1.5rem",32:"2rem",40:"2.5rem",64:"4rem",104:"6.5rem",168:"10.5rem"},icon:{weight:{normal:"300",bold:"500"}},typography:{weight:{normal:"400",bold:"700"},font:{size:{16:"1rem",18:"1.125rem",20:"1.25rem",21:"1.3125rem",23:"1.4375rem",25:"1.5625rem",26:"1.625rem",28:"1.75rem",30:"1.875rem",36:"2.25rem",44:"2.75rem",56:"3.5rem"}},line:{height:{24:"1.5rem",28:"1.75rem",32:"2rem",36:"2.25rem",40:"2.5rem",44:"2.75rem",52:"3.25rem",64:"4rem"}},title:{small:{fontSize:"2.25rem",lineHeight:"2.75rem",fontWeight:"400"},base:{fontSize:"3.5rem",lineHeight:"4rem",fontWeight:"400"}},titleSmall:{small:{fontSize:"1.875rem",lineHeight:"2.25rem",fontWeight:"400"},base:{fontSize:"2.75rem",lineHeight:"3.25rem",fontWeight:"400"}},heading_1:{small:{fontSize:"1.625rem",lineHeight:"2rem",fontWeight:"400"},base:{fontSize:"2.25rem",lineHeight:"2.75rem",fontWeight:"400"}},heading_2:{small:{fontSize:"1.4375rem",lineHeight:"2rem",fontWeight:"400"},base:{fontSize:"1.75rem",lineHeight:"2.5rem",fontWeight:"400"}},heading_3:{small:{fontSize:"1.3125rem",lineHeight:"1.75rem",fontWeight:"700"},base:{fontSize:"1.5625rem",lineHeight:"2rem",fontWeight:"700"}},heading_4:{small:{fontSize:"1.125rem",lineHeight:"1.5rem",fontWeight:"700"},base:{fontSize:"1.3125rem",lineHeight:"1.75rem",fontWeight:"700"}},heading_5:{small:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"700"},base:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"700"}},body:{small:{fontSize:"1.125rem",lineHeight:"1.75rem",fontWeight:"400"},base:{fontSize:"1.25rem",lineHeight:"2rem",fontWeight:"400"}},small:{small:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"400"},base:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"400"}}}};
1
+ "use strict";module.exports={breakpoint:{medium:"680px",large:"1200px",xl:"1600px"},color:{brand:{snohvit:"#F9F9F9",varde:"#E0DBD4",granitt:"#1B1917",hvit:"#FFFFFF",svart:"#000000",skifer:"#313030",fjellgra:"#444141",stein:"#636060",svaberg:"#C8C5C3",dis:"#ECE9E5",sand:"#F4F2EF"},functional:{info:"#D3D3F6",infoDark:"#A9A9CA",success:"#ACD3B5",successDark:"#94B79B",warning:"#EFDD9E",warningDark:"#DECC8D",error:"#F6B3B3",errorDark:"#DE9E9E"},background:{page:{light:"#F4F2EF",dark:"#1B1917"},pageVariant:{light:"#F9F9F9",dark:"#1B1917"},container:{light:"#F9F9F9",dark:"#313030"},containerLow:{light:"#ECE9E5",dark:"#000000"},containerHigh:{light:"#FFFFFF",dark:"#313030"},containerInverted:{light:"#1B1917",dark:"#F9F9F9"},containerSubdued:{light:"#C8C5C3",dark:"#636060"},input:{base:{light:"transparent",dark:"transparent"},focus:{light:"#FFFFFF",dark:"#313030"}},action:{light:"#1B1917",dark:"#F9F9F9"},interactive:{light:"transparent",dark:"transparent"},interactiveHover:{light:"#ECE9E5",dark:"#444141"},interactiveSelected:{light:"#E0DBD4",dark:"#636060"},alert:{neutral:{light:"#E0DBD4",dark:"#E0DBD4"},info:{light:"#D3D3F6",dark:"#A9A9CA"},success:{light:"#ACD3B5",dark:"#94B79B"},warning:{light:"#EFDD9E",dark:"#DECC8D"},error:{light:"#F6B3B3",dark:"#DE9E9E"}}},text:{default:{light:"#1B1917",dark:"#F9F9F9"},subdued:{light:"#636060",dark:"#C8C5C3"},inverted:{light:"#F9F9F9",dark:"#1B1917"},onAction:{light:"#F9F9F9",dark:"#1B1917"},interactive:{light:"#1B1917",dark:"#F9F9F9"},interactiveHover:{light:"#636060",dark:"#C8C5C3"},onAlert:{light:"#1B1917",dark:"#1B1917"},onAlertSubdued:{light:"#444141",dark:"#444141"}},border:{action:{light:"#1B1917",dark:"#F9F9F9"},input:{light:"#636060",dark:"#C8C5C3"},inputFocus:{light:"#1B1917",dark:"#F9F9F9"},separator:{light:"#C8C5C3",dark:"#636060"},separatorStrong:{light:"#636060",dark:"#C8C5C3"},separatorHover:{light:"#1B1917",dark:"#F9F9F9"},subdued:{light:"#C8C5C3",dark:"#636060"}},svart:"#000",granitt:"#1b1917",skifer:"#313030",fjellgra:"#444141",stein:"#636060",svaberg:"#c8c5c3",varde:"#e0dbd4",dis:"#ece9e5",sand:"#f4f2ef",snohvit:"#f9f9f9",hvit:"#fff",suksess:"#acd3b5",suksessDark:"#94b79b",feil:"#f6b3b3",feilDark:"#de9e9e",info:"#d3d3f6",infoDark:"#a9a9ca",advarsel:"#efdd9e",advarselDark:"#decc8d"},motion:{timing:{energetic:"75ms",snappy:"100ms",productive:"150ms",expressive:"250ms",lazy:"400ms"},easing:{standard:"ease",entrance:"ease-out",exit:"ease-in",easeInBounceOut:"cubic-bezier(0, 0, 0.375, 1.17)",focus:"cubic-bezier(0.6, 0.2, 0.35, 1)"}},spacing:{0:"0",2:"0.125rem",4:"0.25rem",8:"0.5rem",12:"0.75rem",16:"1rem",24:"1.5rem",32:"2rem",40:"2.5rem",64:"4rem",104:"6.5rem",168:"10.5rem"},icon:{weight:{normal:"300",bold:"500"}},typography:{weight:{normal:"400",bold:"700"},font:{size:{16:"1rem",18:"1.125rem",20:"1.25rem",21:"1.3125rem",23:"1.4375rem",25:"1.5625rem",26:"1.625rem",28:"1.75rem",30:"1.875rem",36:"2.25rem",44:"2.75rem",56:"3.5rem"}},line:{height:{24:"1.5rem",28:"1.75rem",32:"2rem",36:"2.25rem",40:"2.5rem",44:"2.75rem",52:"3.25rem",64:"4rem"}},title:{small:{fontSize:"2.25rem",lineHeight:"2.75rem",fontWeight:"400"},base:{fontSize:"3.5rem",lineHeight:"4rem",fontWeight:"400"}},titleSmall:{small:{fontSize:"1.875rem",lineHeight:"2.25rem",fontWeight:"400"},base:{fontSize:"2.75rem",lineHeight:"3.25rem",fontWeight:"400"}},heading_1:{small:{fontSize:"1.625rem",lineHeight:"2rem",fontWeight:"400"},base:{fontSize:"2.25rem",lineHeight:"2.75rem",fontWeight:"400"}},heading_2:{small:{fontSize:"1.4375rem",lineHeight:"2rem",fontWeight:"400"},base:{fontSize:"1.75rem",lineHeight:"2.5rem",fontWeight:"400"}},heading_3:{small:{fontSize:"1.3125rem",lineHeight:"1.75rem",fontWeight:"700"},base:{fontSize:"1.5625rem",lineHeight:"2rem",fontWeight:"700"}},heading_4:{small:{fontSize:"1.125rem",lineHeight:"1.5rem",fontWeight:"700"},base:{fontSize:"1.3125rem",lineHeight:"1.75rem",fontWeight:"700"}},heading_5:{small:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"700"},base:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"700"}},body:{small:{fontSize:"1.125rem",lineHeight:"1.75rem",fontWeight:"400"},base:{fontSize:"1.25rem",lineHeight:"2rem",fontWeight:"400"}},small:{small:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"400"},base:{fontSize:"1rem",lineHeight:"1.5rem",fontWeight:"400"}}}};
2
2
  //# sourceMappingURL=tokens.cjs.map