@fremtind/jokul 5.0.0-next.2 → 5.0.0-next.3

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 (144) hide show
  1. package/README.md +14 -13
  2. package/build/build-stats.html +1 -1
  3. package/build/cjs/components/text-area/BaseTextArea.cjs +1 -1
  4. package/build/cjs/components/text-area/BaseTextArea.cjs.map +1 -1
  5. package/build/cjs/components/text-area/counter.cjs +2 -0
  6. package/build/cjs/components/text-area/counter.cjs.map +1 -0
  7. package/build/cjs/components/text-area/counter.d.cts +2 -0
  8. package/build/cjs/components/text-area/types.d.cts +21 -1
  9. package/build/cjs/components/typography/Text.cjs +2 -0
  10. package/build/cjs/components/typography/Text.cjs.map +1 -0
  11. package/build/cjs/components/typography/Text.d.cts +5 -0
  12. package/build/cjs/components/typography/Title.cjs +2 -0
  13. package/build/cjs/components/typography/Title.cjs.map +1 -0
  14. package/build/cjs/components/typography/Title.d.cts +5 -0
  15. package/build/cjs/components/typography/index.cjs +2 -0
  16. package/build/cjs/components/typography/index.cjs.map +1 -0
  17. package/build/cjs/components/typography/index.d.cts +3 -0
  18. package/build/cjs/components/typography/types.cjs +2 -0
  19. package/build/cjs/components/typography/types.cjs.map +1 -0
  20. package/build/cjs/components/typography/types.d.cts +48 -0
  21. package/build/es/components/text-area/BaseTextArea.js +1 -1
  22. package/build/es/components/text-area/BaseTextArea.js.map +1 -1
  23. package/build/es/components/text-area/counter.d.ts +2 -0
  24. package/build/es/components/text-area/counter.js +2 -0
  25. package/build/es/components/text-area/counter.js.map +1 -0
  26. package/build/es/components/text-area/types.d.ts +21 -1
  27. package/build/es/components/typography/Text.d.ts +5 -0
  28. package/build/es/components/typography/Text.js +2 -0
  29. package/build/es/components/typography/Text.js.map +1 -0
  30. package/build/es/components/typography/Title.d.ts +5 -0
  31. package/build/es/components/typography/Title.js +2 -0
  32. package/build/es/components/typography/Title.js.map +1 -0
  33. package/build/es/components/typography/index.d.ts +3 -0
  34. package/build/es/components/typography/index.js +2 -0
  35. package/build/es/components/typography/index.js.map +1 -0
  36. package/build/es/components/typography/types.d.ts +48 -0
  37. package/build/es/components/typography/types.js +2 -0
  38. package/build/es/components/typography/types.js.map +1 -0
  39. package/package.json +1 -1
  40. package/src/fonts/brands/dnb/DNB-Bold.woff2 +0 -0
  41. package/src/fonts/brands/dnb/DNB-Medium.woff2 +0 -0
  42. package/src/fonts/brands/dnb/DNB-Regular.woff2 +0 -0
  43. package/src/fonts/brands/dnb/DNBMono-Regular.woff2 +0 -0
  44. package/src/fonts/brands/eika/OpenSans-Bold.woff2 +0 -0
  45. package/src/fonts/brands/eika/OpenSans-Light.woff2 +0 -0
  46. package/src/fonts/brands/eika/OpenSans-Regular.woff2 +0 -0
  47. package/src/fonts/brands/eika/OpenSans-SemiBold.woff2 +0 -0
  48. package/src/fonts/brands/fremtind/InterVariable-Italic.woff2 +0 -0
  49. package/src/fonts/brands/fremtind/InterVariable.woff2 +0 -0
  50. package/src/fonts/brands/sparebank1/SpareBank1-Medium-Web.woff2 +0 -0
  51. package/src/fonts/brands/sparebank1/SpareBank1-Regular-Web.woff2 +0 -0
  52. package/src/fonts/brands/sparebank1/SpareBank1-Title-Medium-Web.woff2 +0 -0
  53. package/styles/base.css +125 -18
  54. package/styles/base.min.css +1 -1
  55. package/styles/components/beta/nav-link/navlink.css +1 -1
  56. package/styles/components/beta/nav-link/navlink.min.css +1 -1
  57. package/styles/components/checkbox/checkbox.css +1 -1
  58. package/styles/components/checkbox/checkbox.min.css +1 -1
  59. package/styles/components/checkbox-panel/checkbox-panel.css +1 -1
  60. package/styles/components/checkbox-panel/checkbox-panel.min.css +1 -1
  61. package/styles/components/checkbox-panel/development/styles.scss +1 -1
  62. package/styles/components/countdown/countdown.css +2 -2
  63. package/styles/components/countdown/countdown.min.css +1 -1
  64. package/styles/components/feedback/_index.scss +1 -1
  65. package/styles/components/feedback/feedback.css +2 -2
  66. package/styles/components/feedback/feedback.min.css +1 -1
  67. package/styles/components/file-input/file-input.css +10 -10
  68. package/styles/components/file-input/file-input.min.css +1 -1
  69. package/styles/components/icon/_base-styles.scss +12 -14
  70. package/styles/components/icon/icon.css +1 -1
  71. package/styles/components/icon/icon.min.css +1 -1
  72. package/styles/components/input-group/input-group.css +2 -2
  73. package/styles/components/input-group/input-group.min.css +1 -1
  74. package/styles/components/link/link.css +1 -1
  75. package/styles/components/link/link.min.css +1 -1
  76. package/styles/components/link-list/link-list.css +1 -1
  77. package/styles/components/link-list/link-list.min.css +1 -1
  78. package/styles/components/loader/loader.css +6 -6
  79. package/styles/components/loader/loader.min.css +1 -1
  80. package/styles/components/loader/skeleton-loader.css +3 -3
  81. package/styles/components/loader/skeleton-loader.min.css +1 -1
  82. package/styles/components/message/message.css +2 -2
  83. package/styles/components/message/message.min.css +1 -1
  84. package/styles/components/pagination/development/styles.scss +1 -1
  85. package/styles/components/progress-bar/progress-bar.css +1 -1
  86. package/styles/components/progress-bar/progress-bar.min.css +1 -1
  87. package/styles/components/radio-button/radio-button.css +1 -1
  88. package/styles/components/radio-button/radio-button.min.css +1 -1
  89. package/styles/components/radio-panel/development/styles.scss +1 -1
  90. package/styles/components/search/search.css +2 -2
  91. package/styles/components/search/search.min.css +1 -1
  92. package/styles/components/search/search.scss +2 -2
  93. package/styles/components/segmented-control/segmented-control.css +4 -4
  94. package/styles/components/segmented-control/segmented-control.min.css +1 -1
  95. package/styles/components/segmented-control/segmented-control.scss +1 -1
  96. package/styles/components/summary-table/development/summary-table-example.scss +1 -1
  97. package/styles/components/system-message/system-message.css +2 -2
  98. package/styles/components/system-message/system-message.min.css +1 -1
  99. package/styles/components/table-of-contents/table-of-contents.css +1 -1
  100. package/styles/components/table-of-contents/table-of-contents.min.css +1 -1
  101. package/styles/components/table-of-contents/table-of-contents.scss +2 -2
  102. package/styles/components/toast/toast.css +4 -4
  103. package/styles/components/toast/toast.min.css +1 -1
  104. package/styles/components/typography/_index.scss +2 -0
  105. package/styles/components/typography/text.css +38 -0
  106. package/styles/components/typography/text.min.css +1 -0
  107. package/styles/components/typography/text.scss +54 -0
  108. package/styles/components/typography/title.css +55 -0
  109. package/styles/components/typography/title.min.css +1 -0
  110. package/styles/components/typography/title.scss +59 -0
  111. package/styles/components.css +120 -33
  112. package/styles/components.min.css +2 -2
  113. package/styles/components.scss +53 -52
  114. package/styles/core/utility/_paragraphs.scss +39 -0
  115. package/styles/global/_base-class.scss +2 -2
  116. package/styles/global/_top-layer.scss +1 -1
  117. package/styles/hooks/stories/styles.scss +1 -1
  118. package/styles/jkl/_typography.scss +13 -21
  119. package/styles/theme/_dynamic-spacing.scss +3 -3
  120. package/styles/theme/_fonts.scss +16 -28
  121. package/styles/theme/_index.scss +3 -0
  122. package/styles/theme/_tokens.scss +3 -3
  123. package/styles/theme/brands/dnb/_fonts.scss +46 -0
  124. package/styles/theme/brands/eika/_fonts.scss +46 -0
  125. package/styles/theme/brands/jokul/_color-scheme.scss +119 -0
  126. package/styles/theme/brands/jokul/_fonts.scss +46 -0
  127. package/styles/theme/brands/sparebank1/_fonts.scss +38 -0
  128. package/styles/utility/_headings.scss +1 -1
  129. package/styles/utility/_paragraphs.scss +2 -2
  130. package/styles/utility/_screen-reader.scss +1 -1
  131. package/styles/utility/_spacing.scss +2 -2
  132. package/src/fonts/FremtindGrotesk-Bold-Web.woff +0 -0
  133. package/src/fonts/FremtindGrotesk-Bold-Web.woff2 +0 -0
  134. package/src/fonts/FremtindGrotesk-BoldItalic-Web.woff +0 -0
  135. package/src/fonts/FremtindGrotesk-BoldItalic-Web.woff2 +0 -0
  136. package/src/fonts/FremtindGrotesk-Display-Web.woff +0 -0
  137. package/src/fonts/FremtindGrotesk-Display-Web.woff2 +0 -0
  138. package/src/fonts/FremtindGrotesk-Italic-Web.woff +0 -0
  139. package/src/fonts/FremtindGrotesk-Italic-Web.woff2 +0 -0
  140. package/src/fonts/FremtindGrotesk-Regular-Web.woff +0 -0
  141. package/src/fonts/FremtindGrotesk-Regular-Web.woff2 +0 -0
  142. package/src/fonts/FremtindGroteskMono-Regular-Web.woff +0 -0
  143. package/src/fonts/FremtindGroteskMono-Regular-Web.woff2 +0 -0
  144. /package/src/fonts/{Fremtind-Material-Symbols.woff2 → brands/fremtind/Fremtind-Material-Symbols.woff2} +0 -0
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),a=t.forwardRef((a,r)=>{const{autoExpand:s,counter:n,onBlur:o,onFocus:l,rows:i=7,placeholder:u=" ",startOpen:c,style:d,value:h,"aria-invalid":x,onChange:g,...v}=a,[f,p]=t.useState(()=>typeof h>"u"?0:"number"==typeof h?String(h).length:h.length),[j,y]=t.useState(!1),m=t.useRef(null),_=r||m;t.useEffect(()=>{const e=_.current;if(e){if(!s)return void(e.style.height="");j||h?(e.style.height="auto",e.style.height=`${e.scrollHeight}px`):e.style.height=""}},[s,_,h,j,f]);const k=n?.maxLength||0,w=k-f;const N=!(!x&&!(n&&f>k?`Du har skrevet ${f-k} tegn for mye`:void 0)),S={overflowX:s?"hidden":void 0};return e.jsxs("div",{className:"jkl-text-area-wrapper","data-invalid":N,"data-has-content":f>0,children:[e.jsx("textarea",{"aria-invalid":N,className:`jkl-text-area__text-area jkl-text-area__text-area--${i}-rows`,onBlur:function(e){y(!1),o&&o(e)},onFocus:function(e){y(!0),l&&l(e)},onChange:function(e){p(e.target.value.length),g&&g(e)},ref:_,style:{...d,...S},placeholder:u,value:h,...v}),n&&e.jsxs("div",{className:"jkl-text-area__counter","aria-hidden":"true",children:[e.jsxs("div",{className:"jkl-text-area__counter-count",children:[f," / ",k]}),!n.hideProgress&&e.jsx("div",{className:"jkl-text-area__counter-progress",style:{"--progress-width":(B=w,b=k,B<=0||0===b?0:100*B/b)+"%"}})]})]});var B,b});a.displayName="BaseTextArea",exports.BaseTextArea=a;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),a=require("./counter.cjs"),r=t.forwardRef((r,s)=>{const{autoExpand:l,counter:n,defaultValue:o,onBlur:u,onFocus:i,rows:c=7,placeholder:d=" ",startOpen:h,style:x,value:f,"aria-invalid":g,onChange:v,...j}=r,p=n?.strategy??"characters",y=typeof f<"u",[_,m]=t.useState(o),[k,w]=t.useState(!1),N=t.useRef(null),B=s||N,S=y?f:_,q=y?{value:f}:{defaultValue:o},C=a.getCounterValue(S,p),T=n?.maxLength||0,V=T-C,b=!(!g&&!!!(n&&C>T));t.useEffect(()=>{const e=B.current;if(e){if(!l)return void(e.style.height="");k||S?(e.style.height="auto",e.style.height=`${e.scrollHeight}px`):e.style.height=""}},[l,B,S,k,C]);const A={overflowX:l?"hidden":void 0};return e.jsxs("div",{className:"jkl-text-area-wrapper","data-invalid":b,"data-has-content":C>0,children:[e.jsx("textarea",{"aria-invalid":b,className:`jkl-text-area__text-area jkl-text-area__text-area--${c}-rows`,onBlur:function(e){w(!1),u&&u(e)},onFocus:function(e){w(!0),i&&i(e)},onChange:function(e){y||m(e.target.value),v&&v(e)},ref:B,style:{...x,...A},placeholder:d,...q,...j}),n&&e.jsxs("div",{className:"jkl-text-area__counter","aria-hidden":"true",children:[e.jsxs("div",{className:"jkl-text-area__counter-count",children:[C," / ",T]}),!n.hideProgress&&e.jsx("div",{className:"jkl-text-area__counter-progress",style:{"--progress-width":(E=V,F=T,E<=0||0===F?0:100*E/F)+"%"}})]})]});var E,F});r.displayName="BaseTextArea",exports.BaseTextArea=r;
2
2
  //# sourceMappingURL=BaseTextArea.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseTextArea.cjs","sources":["../../../../src/components/text-area/BaseTextArea.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { BaseTextAreaProps } from \"./types.js\";\n\nexport const BaseTextArea = forwardRef<HTMLTextAreaElement, BaseTextAreaProps>(\n (props, ref) => {\n const {\n autoExpand,\n counter,\n onBlur,\n onFocus,\n rows = 7,\n placeholder = \" \", // This space intentionally left blank. Denne + rows trengs for å få den ekspanderende effekten.\n startOpen,\n style,\n value,\n \"aria-invalid\": ariaInvalid,\n onChange,\n ...rest\n } = props;\n\n const [counterCurrent, setCounterCurrent] = useState(() => {\n if (typeof value === \"undefined\") {\n return 0;\n }\n\n if (typeof value === \"number\") {\n return String(value).length;\n }\n\n return value.length;\n });\n const [textAreaFocused, setTextAreaFocused] = useState(false);\n const internalRef = useRef<HTMLTextAreaElement>(null);\n const textAreaRef =\n (ref as RefObject<HTMLTextAreaElement>) || internalRef;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: counterCurrent trengs for å lytte på tekstendringer i textarea for auto-expand funksjonalitet\n useEffect(() => {\n const textAreaElement = textAreaRef.current;\n if (textAreaElement) {\n if (!autoExpand) {\n textAreaElement.style.height = \"\";\n return;\n }\n\n if (textAreaFocused || value) {\n textAreaElement.style.height = \"auto\"; // Sett til auto før scrollhøyden leses, sånn at redusering av høyde ved sletting av tekst fungerer\n textAreaElement.style.height = `${textAreaElement.scrollHeight}px`;\n } else {\n textAreaElement.style.height = \"\";\n }\n }\n }, [autoExpand, textAreaRef, value, textAreaFocused, counterCurrent]);\n\n function handleOnFocus(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(true);\n if (onFocus) {\n onFocus(e);\n }\n }\n\n function handleOnBlur(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(false);\n if (onBlur) {\n onBlur(e);\n }\n }\n\n function handleOnChange(e: ChangeEvent<HTMLTextAreaElement>) {\n setCounterCurrent(e.target.value.length);\n if (onChange) {\n onChange(e);\n }\n }\n\n const counterTotal: number = counter?.maxLength || 0;\n const progressCurrent: number = counterTotal - counterCurrent;\n function calculatePercentage(current: number, total: number): number {\n if (current <= 0) {\n return 0;\n }\n return total === 0 ? 0 : (current * 100) / total;\n }\n const counterLabel =\n counter && counterCurrent > counterTotal\n ? `Du har skrevet ${counterCurrent - counterTotal} tegn for mye`\n : undefined;\n\n const invalid = Boolean(ariaInvalid || counterLabel);\n\n const overflowStyle = {\n overflowX: autoExpand ? \"hidden\" : undefined, // Must set overflowX hidden for Firefox https://stackoverflow.com/a/22700700\n } as React.CSSProperties;\n\n return (\n <div\n className=\"jkl-text-area-wrapper\"\n data-invalid={invalid}\n data-has-content={counterCurrent > 0}\n >\n <textarea\n aria-invalid={invalid}\n className={`jkl-text-area__text-area jkl-text-area__text-area--${rows}-rows`}\n onBlur={handleOnBlur}\n onFocus={handleOnFocus}\n onChange={handleOnChange}\n ref={textAreaRef}\n style={{ ...style, ...overflowStyle }}\n placeholder={placeholder}\n value={value}\n {...rest}\n />\n {counter && (\n <div className=\"jkl-text-area__counter\" aria-hidden=\"true\">\n <div className=\"jkl-text-area__counter-count\">\n {counterCurrent}&nbsp;/&nbsp;{counterTotal}\n </div>\n {!counter.hideProgress && (\n <div\n className=\"jkl-text-area__counter-progress\"\n style={{\n [\"--progress-width\" as string]: `${calculatePercentage(\n progressCurrent,\n counterTotal,\n )}%`,\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n },\n);\nBaseTextArea.displayName = \"BaseTextArea\";\n"],"names":["BaseTextArea","forwardRef","props","ref","autoExpand","counter","onBlur","onFocus","rows","placeholder","startOpen","style","value","ariaInvalid","onChange","rest","counterCurrent","setCounterCurrent","useState","String","length","textAreaFocused","setTextAreaFocused","internalRef","useRef","textAreaRef","useEffect","textAreaElement","current","height","scrollHeight","counterTotal","maxLength","progressCurrent","invalid","overflowStyle","overflowX","jsxs","className","children","jsx","e","target","hideProgress","total","displayName"],"mappings":"wIAWaA,EAAeC,EAAAA,WACxB,CAACC,EAAOC,KACJ,MACIC,WAAAA,EACAC,QAAAA,EACAC,OAAAA,EACAC,QAAAA,EACAC,KAAAA,EAAO,EACPC,YAAAA,EAAc,IACdC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,eAAgBC,EAChBC,SAAAA,KACGC,GACHb,GAEGc,EAAgBC,GAAqBC,EAAAA,SAAS,WACtCN,EAAU,IACV,EAGU,iBAAVA,EACAO,OAAOP,GAAOQ,OAGlBR,EAAMQ,SAEVC,EAAiBC,GAAsBJ,EAAAA,UAAS,GACjDK,EAAcC,EAAAA,OAA4B,MAC1CC,EACDtB,GAA0CoB,EAG/CG,EAAAA,UAAU,KACN,MAAMC,EAAkBF,EAAYG,QACpC,GAAID,EAAiB,CACjB,IAAKvB,EAED,YADAuB,EAAgBhB,MAAMkB,OAAS,IAI/BR,GAAmBT,GACnBe,EAAgBhB,MAAMkB,OAAS,OAC/BF,EAAgBhB,MAAMkB,OAAS,GAAGF,EAAgBG,kBAElDH,EAAgBhB,MAAMkB,OAAS,EAEvC,GACD,CAACzB,EAAYqB,EAAab,EAAOS,EAAiBL,IAuBrD,MAAMe,EAAuB1B,GAAS2B,WAAa,EAC7CC,EAA0BF,EAAef,EAO/C,MAKMkB,KAAkBrB,KAJpBR,GAAWW,EAAiBe,EACtB,kBAAkBf,EAAiBe,sBACnC,IAIJI,EAAgB,CAClBC,UAAWhC,EAAa,cAAW,GAGvC,OACIiC,EAAAA,KAAC,MAAA,CACGC,UAAU,wBACV,eAAcJ,EACd,mBAAkBlB,EAAiB,EAEnCuB,SAAA,CAAAC,EAAAA,IAAC,WAAA,CACG,eAAcN,EACdI,UAAW,sDAAsD9B,SACjEF,OA1CZ,SAAsBmC,GAClBnB,GAAmB,GACfhB,GACAA,EAAOmC,EAEf,EAsCYlC,QAlDZ,SAAuBkC,GACnBnB,GAAmB,GACff,GACAA,EAAQkC,EAEhB,EA8CY3B,SArCZ,SAAwB2B,GACpBxB,EAAkBwB,EAAEC,OAAO9B,MAAMQ,QAC7BN,GACAA,EAAS2B,EAEjB,EAiCYtC,IAAKsB,EACLd,MAAO,IAAKA,KAAUwB,GACtB1B,YAAAA,EACAG,MAAAA,KACIG,IAEPV,GACGgC,EAAAA,KAAC,MAAA,CAAIC,UAAU,yBAAyB,cAAY,OAChDC,SAAA,CAAAF,EAAAA,KAAC,MAAA,CAAIC,UAAU,+BACVC,SAAA,CAAAvB,EAAe,MAAce,MAEhC1B,EAAQsC,cACNH,EAAAA,IAAC,MAAA,CACGF,UAAU,kCACV3B,MAAO,CACF,oBA5CAiB,EA6CGK,EA7CcW,EA8Cdb,EA7CxBH,GAAW,GAGE,IAAVgB,EAFI,EAEyB,IAAVhB,EAAiBgB,GAwCa,aA5C5D,IAA6BhB,EAAiBgB,IAyDtD5C,EAAa6C,YAAc"}
1
+ {"version":3,"file":"BaseTextArea.cjs","sources":["../../../../src/components/text-area/BaseTextArea.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { getCounterValue } from \"./counter.js\";\nimport type { BaseTextAreaProps } from \"./types.js\";\n\nexport const BaseTextArea = forwardRef<HTMLTextAreaElement, BaseTextAreaProps>(\n (props, ref) => {\n const {\n autoExpand,\n counter,\n defaultValue,\n onBlur,\n onFocus,\n rows = 7,\n placeholder = \" \", // This space intentionally left blank. Denne + rows trengs for å få den ekspanderende effekten.\n startOpen,\n style,\n value,\n \"aria-invalid\": ariaInvalid,\n onChange,\n ...rest\n } = props;\n\n const strategy = counter?.strategy ?? \"characters\";\n const isControlled = typeof value !== \"undefined\";\n\n const [uncontrolledValue, setUncontrolledValue] =\n useState(defaultValue);\n const [textAreaFocused, setTextAreaFocused] = useState(false);\n const internalRef = useRef<HTMLTextAreaElement>(null);\n const textAreaRef =\n (ref as RefObject<HTMLTextAreaElement>) || internalRef;\n\n // Hvis feltet styres utenfra bruker vi `value`, ellers holder vi styr på verdien selv.\n const textAreaValue = isControlled ? value : uncontrolledValue;\n const textAreaValueProps = isControlled ? { value } : { defaultValue };\n\n const counterCurrent = getCounterValue(textAreaValue, strategy);\n const counterTotal: number = counter?.maxLength || 0;\n const progressCurrent: number = counterTotal - counterCurrent;\n const isOverLimit = Boolean(counter && counterCurrent > counterTotal);\n const invalid = Boolean(ariaInvalid || isOverLimit);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: counterCurrent trengs for å lytte på tekstendringer i textarea for auto-expand funksjonalitet\n useEffect(() => {\n const textAreaElement = textAreaRef.current;\n if (textAreaElement) {\n if (!autoExpand) {\n textAreaElement.style.height = \"\";\n return;\n }\n\n if (textAreaFocused || textAreaValue) {\n textAreaElement.style.height = \"auto\"; // Sett til auto før scrollhøyden leses, sånn at redusering av høyde ved sletting av tekst fungerer\n textAreaElement.style.height = `${textAreaElement.scrollHeight}px`;\n } else {\n textAreaElement.style.height = \"\";\n }\n }\n }, [\n autoExpand,\n textAreaRef,\n textAreaValue,\n textAreaFocused,\n counterCurrent,\n ]);\n\n function handleOnFocus(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(true);\n if (onFocus) {\n onFocus(e);\n }\n }\n\n function handleOnBlur(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(false);\n if (onBlur) {\n onBlur(e);\n }\n }\n\n function handleOnChange(e: ChangeEvent<HTMLTextAreaElement>) {\n if (!isControlled) {\n setUncontrolledValue(e.target.value);\n }\n\n if (onChange) {\n onChange(e);\n }\n }\n function calculatePercentage(current: number, total: number): number {\n if (current <= 0) {\n return 0;\n }\n return total === 0 ? 0 : (current * 100) / total;\n }\n\n const overflowStyle = {\n overflowX: autoExpand ? \"hidden\" : undefined, // Must set overflowX hidden for Firefox https://stackoverflow.com/a/22700700\n } as React.CSSProperties;\n\n return (\n <div\n className=\"jkl-text-area-wrapper\"\n data-invalid={invalid}\n data-has-content={counterCurrent > 0}\n >\n <textarea\n aria-invalid={invalid}\n className={`jkl-text-area__text-area jkl-text-area__text-area--${rows}-rows`}\n onBlur={handleOnBlur}\n onFocus={handleOnFocus}\n onChange={handleOnChange}\n ref={textAreaRef}\n style={{ ...style, ...overflowStyle }}\n placeholder={placeholder}\n {...textAreaValueProps}\n {...rest}\n />\n {counter && (\n <div className=\"jkl-text-area__counter\" aria-hidden=\"true\">\n <div className=\"jkl-text-area__counter-count\">\n {counterCurrent}&nbsp;/&nbsp;{counterTotal}\n </div>\n {!counter.hideProgress && (\n <div\n className=\"jkl-text-area__counter-progress\"\n style={{\n [\"--progress-width\" as string]: `${calculatePercentage(\n progressCurrent,\n counterTotal,\n )}%`,\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n },\n);\nBaseTextArea.displayName = \"BaseTextArea\";\n"],"names":["BaseTextArea","forwardRef","props","ref","autoExpand","counter","defaultValue","onBlur","onFocus","rows","placeholder","startOpen","style","value","ariaInvalid","onChange","rest","strategy","isControlled","uncontrolledValue","setUncontrolledValue","useState","textAreaFocused","setTextAreaFocused","internalRef","useRef","textAreaRef","textAreaValue","textAreaValueProps","counterCurrent","getCounterValue","counterTotal","maxLength","progressCurrent","invalid","useEffect","textAreaElement","current","height","scrollHeight","overflowStyle","overflowX","jsxs","className","children","jsx","e","target","hideProgress","total","displayName"],"mappings":"mKAYaA,EAAeC,EAAAA,WACxB,CAACC,EAAOC,KACJ,MACIC,WAAAA,EACAC,QAAAA,EACAC,aAAAA,EACAC,OAAAA,EACAC,QAAAA,EACAC,KAAAA,EAAO,EACPC,YAAAA,EAAc,IACdC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,eAAgBC,EAChBC,SAAAA,KACGC,GACHd,EAEEe,EAAWZ,GAASY,UAAY,aAChCC,SAAsBL,EAAU,KAE/BM,EAAmBC,GACtBC,EAAAA,SAASf,IACNgB,EAAiBC,GAAsBF,EAAAA,UAAS,GACjDG,EAAcC,EAAAA,OAA4B,MAC1CC,EACDvB,GAA0CqB,EAGzCG,EAAgBT,EAAeL,EAAQM,EACvCS,EAAqBV,EAAe,CAAEL,MAAAA,GAAU,CAAEP,aAAAA,GAElDuB,EAAiBC,EAAAA,gBAAgBH,EAAeV,GAChDc,EAAuB1B,GAAS2B,WAAa,EAC7CC,EAA0BF,EAAeF,EAEzCK,KAAkBpB,OADIT,GAAWwB,EAAiBE,IAIxDI,EAAAA,UAAU,KACN,MAAMC,EAAkBV,EAAYW,QACpC,GAAID,EAAiB,CACjB,IAAKhC,EAED,YADAgC,EAAgBxB,MAAM0B,OAAS,IAI/BhB,GAAmBK,GACnBS,EAAgBxB,MAAM0B,OAAS,OAC/BF,EAAgBxB,MAAM0B,OAAS,GAAGF,EAAgBG,kBAElDH,EAAgBxB,MAAM0B,OAAS,EAEvC,GACD,CACClC,EACAsB,EACAC,EACAL,EACAO,IAiCJ,MAAMW,EAAgB,CAClBC,UAAWrC,EAAa,cAAW,GAGvC,OACIsC,EAAAA,KAAC,MAAA,CACGC,UAAU,wBACV,eAAcT,EACd,mBAAkBL,EAAiB,EAEnCe,SAAA,CAAAC,EAAAA,IAAC,WAAA,CACG,eAAcX,EACdS,UAAW,sDAAsDlC,SACjEF,OApCZ,SAAsBuC,GAClBvB,GAAmB,GACfhB,GACAA,EAAOuC,EAEf,EAgCYtC,QA5CZ,SAAuBsC,GACnBvB,GAAmB,GACff,GACAA,EAAQsC,EAEhB,EAwCY/B,SA/BZ,SAAwB+B,GACf5B,GACDE,EAAqB0B,EAAEC,OAAOlC,OAG9BE,GACAA,EAAS+B,EAEjB,EAwBY3C,IAAKuB,EACLd,MAAO,IAAKA,KAAU4B,GACtB9B,YAAAA,KACIkB,KACAZ,IAEPX,GACGqC,EAAAA,KAAC,MAAA,CAAIC,UAAU,yBAAyB,cAAY,OAChDC,SAAA,CAAAF,EAAAA,KAAC,MAAA,CAAIC,UAAU,+BACVC,SAAA,CAAAf,EAAe,MAAcE,MAEhC1B,EAAQ2C,cACNH,EAAAA,IAAC,MAAA,CACGF,UAAU,kCACV/B,MAAO,CACF,oBAtCAyB,EAuCGJ,EAvCcgB,EAwCdlB,EAvCxBM,GAAW,GAGE,IAAVY,EAFI,EAEyB,IAAVZ,EAAiBY,GAkCa,aAtC5D,IAA6BZ,EAAiBY,IAmDtDjD,EAAakD,YAAc"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=new TextEncoder;exports.getCounterValue=function(t,r="characters"){if(typeof t>"u")return 0;const n="string"==typeof t?t:Array.isArray(t)?t.join(""):String(t);return"bytes"===r?e.encode(n).length:n.length};
2
+ //# sourceMappingURL=counter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter.cjs","sources":["../../../../src/components/text-area/counter.ts"],"sourcesContent":["import type { CounterStrategy } from \"./types.js\";\n\nconst textEncoder = new TextEncoder();\n\nexport function getCounterValue(\n value: string | number | readonly string[] | undefined,\n strategy: CounterStrategy = \"characters\",\n): number {\n if (typeof value === \"undefined\") {\n return 0;\n }\n\n const normalizedValue =\n typeof value === \"string\"\n ? value\n : Array.isArray(value)\n ? value.join(\"\")\n : String(value);\n\n if (strategy === \"bytes\") {\n return textEncoder.encode(normalizedValue).length;\n }\n\n return normalizedValue.length;\n}\n"],"names":["textEncoder","TextEncoder","value","strategy","normalizedValue","Array","isArray","join","String","encode","length"],"mappings":"gFAEA,MAAMA,EAAc,IAAIC,oCAEjB,SACHC,EACAC,EAA4B,cAE5B,UAAWD,EAAU,IACjB,OAAO,EAGX,MAAME,EACe,iBAAVF,EACDA,EACAG,MAAMC,QAAQJ,GACZA,EAAMK,KAAK,IACXC,OAAON,GAEnB,MAAiB,UAAbC,EACOH,EAAYS,OAAOL,GAAiBM,OAGxCN,EAAgBM,MAC3B"}
@@ -0,0 +1,2 @@
1
+ import { CounterStrategy } from './types.cjs';
2
+ export declare function getCounterValue(value: string | number | readonly string[] | undefined, strategy?: CounterStrategy): number;
@@ -1,8 +1,28 @@
1
1
  import { TextareaHTMLAttributes } from 'react';
2
2
  import { InputGroupProps } from '../input-group/types.cjs';
3
+ export type CounterStrategy = "characters" | "bytes";
3
4
  export type Counter = {
4
- /** Antall tegn før telleren når maksimum og vi viser en feilmelding */
5
+ /**
6
+ * Maksverdi for telleren.
7
+ *
8
+ * Enheten avhenger av `strategy`:
9
+ * - `"characters"`: antall tegn
10
+ * - `"bytes"`: antall UTF-8-bytes
11
+ */
5
12
  maxLength: number;
13
+ /**
14
+ * Bestemmer hva telleren måler.
15
+ *
16
+ * - "characters" teller tekst på samme måte som i dag og er standard
17
+ * - "bytes" teller antall UTF-8-bytes, for usecaser der backend eller API
18
+ * håndhever en bytegrense
19
+ *
20
+ * Unngå å kombinere `strategy="bytes"` med native `maxLength` på
21
+ * `<textarea>`, siden nettleseren fortsatt håndhever `maxLength` som tegn.
22
+ *
23
+ * @default "characters"
24
+ */
25
+ strategy?: CounterStrategy;
6
26
  /**
7
27
  * Med teller vises en progress-bar i bunnen av tekstfeltet som krymper
8
28
  * ned fra 100% (null tegn skrevet) til 0% (maks antall tegn skrevet).
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("../../../clsx-E3yX_9sL.cjs"),r=require("react").forwardRef(function({as:r,className:s,size:o="m",bold:a,short:l,srOnly:c,...i},d){const n=r||"p";return e.jsx(n,{className:t.clsx("jkl-text",c&&"jkl-sr-only",s),"data-text-size":o,"data-bold":a||void 0,"data-short":l||void 0,ref:d,...i})});exports.Text=r;
2
+ //# sourceMappingURL=Text.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Text.cjs","sources":["../../../../src/components/typography/Text.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { forwardRef } from \"react\";\nimport type { PolymorphicRef } from \"../../utilities/index.js\";\nimport type { TextElement, TextProps } from \"./types.js\";\n\ntype TextComponent = <As extends TextElement = \"p\">(\n props: TextProps<As>,\n) => React.ReactElement | null;\n\nexport const Text: TextComponent = forwardRef(function Text<\n As extends TextElement = \"p\",\n>(\n { as, className, size = \"m\", bold, short, srOnly, ...rest }: TextProps<As>,\n ref?: PolymorphicRef<As>,\n) {\n const Component = (as || \"p\") as React.ElementType;\n return (\n <Component\n className={clsx(\"jkl-text\", srOnly && \"jkl-sr-only\", className)}\n data-text-size={size}\n data-bold={bold || undefined}\n data-short={short || undefined}\n ref={ref}\n {...rest}\n />\n );\n}) as TextComponent;\n"],"names":["Text","forwardRef","as","className","size","bold","short","srOnly","rest","ref","Component","jsx","clsx"],"mappings":"6JASaA,mBAAsBC,WAAW,UAGxCC,GAAAA,EAAIC,UAAAA,EAAWC,KAAAA,EAAO,IAAKC,KAAAA,EAAMC,MAAAA,EAAOC,OAAAA,KAAWC,GACrDC,GAEA,MAAMC,EAAaR,GAAM,IACzB,OACIS,EAAAA,IAACD,EAAA,CACGP,UAAWS,EAAAA,KAAK,WAAYL,GAAU,cAAeJ,GACrD,iBAAgBC,EAChB,YAAWC,QAAQ,EACnB,aAAYC,QAAS,EACrBG,IAAAA,KACID,GAGhB"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+ import { TextElement, TextProps } from './types.cjs';
3
+ type TextComponent = <As extends TextElement = "p">(props: TextProps<As>) => React.ReactElement | null;
4
+ export declare const Text: TextComponent;
5
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),r=require("../../../clsx-E3yX_9sL.cjs"),t=require("react").forwardRef(function({className:t,size:s="l",as:l,srOnly:a,...c},i){const o=l||"h2";return e.jsx(o,{className:r.clsx("jkl-title",a&&"jkl-sr-only",t),"data-text-size":s,ref:i,...c})});exports.Title=t;
2
+ //# sourceMappingURL=Title.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Title.cjs","sources":["../../../../src/components/typography/Title.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { forwardRef } from \"react\";\nimport type { PolymorphicRef } from \"../../utilities/index.js\";\nimport type { TitleElement, TitleProps } from \"./types.js\";\n\ntype TitleComponent = <As extends TitleElement = \"h2\">(\n props: TitleProps<As>,\n) => React.ReactElement | null;\n\nexport const Title: TitleComponent = forwardRef(function Title<\n As extends TitleElement = \"h2\",\n>(\n { className, size = \"l\", as, srOnly, ...rest }: TitleProps<As>,\n ref?: PolymorphicRef<As>,\n) {\n const Tag = (as || \"h2\") as React.ElementType;\n return (\n <Tag\n className={clsx(\"jkl-title\", srOnly && \"jkl-sr-only\", className)}\n data-text-size={size}\n ref={ref}\n {...rest}\n />\n );\n}) as TitleComponent;\n"],"names":["Title","forwardRef","className","size","as","srOnly","rest","ref","Tag","jsx","clsx"],"mappings":"6JASaA,mBAAwBC,WAAW,UAG1CC,UAAAA,EAAWC,KAAAA,EAAO,IAAKC,GAAAA,EAAIC,OAAAA,KAAWC,GACxCC,GAEA,MAAMC,EAAOJ,GAAM,KACnB,OACIK,EAAAA,IAACD,EAAA,CACGN,UAAWQ,EAAAA,KAAK,YAAaL,GAAU,cAAeH,GACtD,iBAAgBC,EAChBI,IAAAA,KACID,GAGhB"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+ import { TitleElement, TitleProps } from './types.cjs';
3
+ type TitleComponent = <As extends TitleElement = "h2">(props: TitleProps<As>) => React.ReactElement | null;
4
+ export declare const Title: TitleComponent;
5
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Text.cjs"),t=require("./Title.cjs");exports.Text=e.Text,exports.Title=t.Title;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export { Text } from './Text.cjs';
2
+ export { Title } from './Title.cjs';
3
+ export type { TextProps, TextSize, TitleProps, TitleSize } from './types.cjs';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { PolymorphicPropsWithRef } from '../../utilities/index.cjs';
2
+ export type TextElement = "p" | "span" | "label" | "legend" | "small" | "strong" | "em" | "code" | "kbd" | "samp" | "var";
3
+ export type TitleElement = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "label" | "legend";
4
+ export type TextSize = "xs" | "s" | "m" | "l";
5
+ export type TitleSize = "xs" | "s" | "m" | "l" | "xl";
6
+ type TextOwnProps = {
7
+ /**
8
+ * Visuell størrelse på teksten. Tilsvarer font-size-tokens i Jøkul.
9
+ * @default "m"
10
+ */
11
+ size?: TextSize;
12
+ /**
13
+ * Uthever teksten (font-weight: bold).
14
+ * @default false
15
+ */
16
+ bold?: boolean;
17
+ /**
18
+ * Setter mindre linjehøyde — bruk når teksten i all hovedsak går over
19
+ * én linje (f.eks. i tabellceller eller knapper).
20
+ * @default false
21
+ */
22
+ short?: boolean;
23
+ /**
24
+ * Skjuler elementet visuelt, men beholder det for skjermlesere.
25
+ * Bruk for å gi ekstra kontekst til assistive teknologier uten å
26
+ * påvirke det visuelle.
27
+ * @default false
28
+ */
29
+ srOnly?: boolean;
30
+ };
31
+ type TitleOwnProps = {
32
+ /**
33
+ * Visuell størrelse på tittelen. Frakoblet fra `as` — velg semantisk
34
+ * nivå via `as`, og visuell størrelse via `size`.
35
+ * @default "l"
36
+ */
37
+ size?: TitleSize;
38
+ /**
39
+ * Skjuler elementet visuelt, men beholder det for skjermlesere.
40
+ * Bruk for å beholde riktig overskrifts-hierarki i skjermlesere
41
+ * uten å vise tittelen visuelt.
42
+ * @default false
43
+ */
44
+ srOnly?: boolean;
45
+ };
46
+ export type TextProps<As extends TextElement = "p"> = PolymorphicPropsWithRef<As, TextOwnProps>;
47
+ export type TitleProps<As extends TitleElement = "h2"> = PolymorphicPropsWithRef<As, TitleOwnProps>;
48
+ export {};
@@ -1,2 +1,2 @@
1
- import{jsxs as e,jsx as t}from"react/jsx-runtime";import{forwardRef as a,useState as r,useRef as s,useEffect as n}from"react";const o=a((a,o)=>{const{autoExpand:l,counter:i,onBlur:c,onFocus:u,rows:d=7,placeholder:h=" ",startOpen:x,style:f,value:g,"aria-invalid":v,onChange:p,...m}=a,[y,_]=r(()=>typeof g>"u"?0:"number"==typeof g?String(g).length:g.length),[j,k]=r(!1),w=s(null),N=o||w;n(()=>{const e=N.current;if(e){if(!l)return void(e.style.height="");j||g?(e.style.height="auto",e.style.height=`${e.scrollHeight}px`):e.style.height=""}},[l,N,g,j,y]);const B=i?.maxLength||0,$=B-y;const A=!(!v&&!(i&&y>B?`Du har skrevet ${y-B} tegn for mye`:void 0));return e("div",{className:"jkl-text-area-wrapper","data-invalid":A,"data-has-content":y>0,children:[t("textarea",{"aria-invalid":A,className:`jkl-text-area__text-area jkl-text-area__text-area--${d}-rows`,onBlur:function(e){k(!1),c&&c(e)},onFocus:function(e){k(!0),u&&u(e)},onChange:function(e){_(e.target.value.length),p&&p(e)},ref:N,style:{...f,...{overflowX:l?"hidden":void 0}},placeholder:h,value:g,...m}),i&&e("div",{className:"jkl-text-area__counter","aria-hidden":"true",children:[e("div",{className:"jkl-text-area__counter-count",children:[y," / ",B]}),!i.hideProgress&&t("div",{className:"jkl-text-area__counter-progress",style:{"--progress-width":(C=$,E=B,C<=0||0===E?0:100*C/E)+"%"}})]})]});var C,E});o.displayName="BaseTextArea";export{o as BaseTextArea};
1
+ import{jsxs as e,jsx as a}from"react/jsx-runtime";import{forwardRef as t,useState as r,useRef as s,useEffect as o}from"react";import{getCounterValue as l}from"./counter.js";const n=t((t,n)=>{const{autoExpand:i,counter:u,defaultValue:c,onBlur:d,onFocus:h,rows:f=7,placeholder:x=" ",startOpen:p,style:g,value:m,"aria-invalid":v,onChange:j,...y}=t,_=u?.strategy??"characters",k=typeof m<"u",[w,N]=r(c),[B,C]=r(!1),V=s(null),A=n||V,E=k?m:w,F=k?{value:m}:{defaultValue:c},R=l(E,_),T=u?.maxLength||0,$=T-R,H=!(!v&&!!!(u&&R>T));o(()=>{const e=A.current;if(e){if(!i)return void(e.style.height="");B||E?(e.style.height="auto",e.style.height=`${e.scrollHeight}px`):e.style.height=""}},[i,A,E,B,R]);return e("div",{className:"jkl-text-area-wrapper","data-invalid":H,"data-has-content":R>0,children:[a("textarea",{"aria-invalid":H,className:`jkl-text-area__text-area jkl-text-area__text-area--${f}-rows`,onBlur:function(e){C(!1),d&&d(e)},onFocus:function(e){C(!0),h&&h(e)},onChange:function(e){k||N(e.target.value),j&&j(e)},ref:A,style:{...g,...{overflowX:i?"hidden":void 0}},placeholder:x,...F,...y}),u&&e("div",{className:"jkl-text-area__counter","aria-hidden":"true",children:[e("div",{className:"jkl-text-area__counter-count",children:[R," / ",T]}),!u.hideProgress&&a("div",{className:"jkl-text-area__counter-progress",style:{"--progress-width":(L=$,O=T,L<=0||0===O?0:100*L/O)+"%"}})]})]});var L,O});n.displayName="BaseTextArea";export{n as BaseTextArea};
2
2
  //# sourceMappingURL=BaseTextArea.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseTextArea.js","sources":["../../../../src/components/text-area/BaseTextArea.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { BaseTextAreaProps } from \"./types.js\";\n\nexport const BaseTextArea = forwardRef<HTMLTextAreaElement, BaseTextAreaProps>(\n (props, ref) => {\n const {\n autoExpand,\n counter,\n onBlur,\n onFocus,\n rows = 7,\n placeholder = \" \", // This space intentionally left blank. Denne + rows trengs for å få den ekspanderende effekten.\n startOpen,\n style,\n value,\n \"aria-invalid\": ariaInvalid,\n onChange,\n ...rest\n } = props;\n\n const [counterCurrent, setCounterCurrent] = useState(() => {\n if (typeof value === \"undefined\") {\n return 0;\n }\n\n if (typeof value === \"number\") {\n return String(value).length;\n }\n\n return value.length;\n });\n const [textAreaFocused, setTextAreaFocused] = useState(false);\n const internalRef = useRef<HTMLTextAreaElement>(null);\n const textAreaRef =\n (ref as RefObject<HTMLTextAreaElement>) || internalRef;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: counterCurrent trengs for å lytte på tekstendringer i textarea for auto-expand funksjonalitet\n useEffect(() => {\n const textAreaElement = textAreaRef.current;\n if (textAreaElement) {\n if (!autoExpand) {\n textAreaElement.style.height = \"\";\n return;\n }\n\n if (textAreaFocused || value) {\n textAreaElement.style.height = \"auto\"; // Sett til auto før scrollhøyden leses, sånn at redusering av høyde ved sletting av tekst fungerer\n textAreaElement.style.height = `${textAreaElement.scrollHeight}px`;\n } else {\n textAreaElement.style.height = \"\";\n }\n }\n }, [autoExpand, textAreaRef, value, textAreaFocused, counterCurrent]);\n\n function handleOnFocus(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(true);\n if (onFocus) {\n onFocus(e);\n }\n }\n\n function handleOnBlur(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(false);\n if (onBlur) {\n onBlur(e);\n }\n }\n\n function handleOnChange(e: ChangeEvent<HTMLTextAreaElement>) {\n setCounterCurrent(e.target.value.length);\n if (onChange) {\n onChange(e);\n }\n }\n\n const counterTotal: number = counter?.maxLength || 0;\n const progressCurrent: number = counterTotal - counterCurrent;\n function calculatePercentage(current: number, total: number): number {\n if (current <= 0) {\n return 0;\n }\n return total === 0 ? 0 : (current * 100) / total;\n }\n const counterLabel =\n counter && counterCurrent > counterTotal\n ? `Du har skrevet ${counterCurrent - counterTotal} tegn for mye`\n : undefined;\n\n const invalid = Boolean(ariaInvalid || counterLabel);\n\n const overflowStyle = {\n overflowX: autoExpand ? \"hidden\" : undefined, // Must set overflowX hidden for Firefox https://stackoverflow.com/a/22700700\n } as React.CSSProperties;\n\n return (\n <div\n className=\"jkl-text-area-wrapper\"\n data-invalid={invalid}\n data-has-content={counterCurrent > 0}\n >\n <textarea\n aria-invalid={invalid}\n className={`jkl-text-area__text-area jkl-text-area__text-area--${rows}-rows`}\n onBlur={handleOnBlur}\n onFocus={handleOnFocus}\n onChange={handleOnChange}\n ref={textAreaRef}\n style={{ ...style, ...overflowStyle }}\n placeholder={placeholder}\n value={value}\n {...rest}\n />\n {counter && (\n <div className=\"jkl-text-area__counter\" aria-hidden=\"true\">\n <div className=\"jkl-text-area__counter-count\">\n {counterCurrent}&nbsp;/&nbsp;{counterTotal}\n </div>\n {!counter.hideProgress && (\n <div\n className=\"jkl-text-area__counter-progress\"\n style={{\n [\"--progress-width\" as string]: `${calculatePercentage(\n progressCurrent,\n counterTotal,\n )}%`,\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n },\n);\nBaseTextArea.displayName = \"BaseTextArea\";\n"],"names":["BaseTextArea","forwardRef","props","ref","autoExpand","counter","onBlur","onFocus","rows","placeholder","startOpen","style","value","ariaInvalid","onChange","rest","counterCurrent","setCounterCurrent","useState","String","length","textAreaFocused","setTextAreaFocused","internalRef","useRef","textAreaRef","useEffect","textAreaElement","current","height","scrollHeight","counterTotal","maxLength","progressCurrent","invalid","jsxs","className","children","jsx","e","target","overflowX","hideProgress","total","displayName"],"mappings":"8HAWO,MAAMA,EAAeC,EACxB,CAACC,EAAOC,KACJ,MACIC,WAAAA,EACAC,QAAAA,EACAC,OAAAA,EACAC,QAAAA,EACAC,KAAAA,EAAO,EACPC,YAAAA,EAAc,IACdC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,eAAgBC,EAChBC,SAAAA,KACGC,GACHb,GAEGc,EAAgBC,GAAqBC,EAAS,WACtCN,EAAU,IACV,EAGU,iBAAVA,EACAO,OAAOP,GAAOQ,OAGlBR,EAAMQ,SAEVC,EAAiBC,GAAsBJ,GAAS,GACjDK,EAAcC,EAA4B,MAC1CC,EACDtB,GAA0CoB,EAG/CG,EAAU,KACN,MAAMC,EAAkBF,EAAYG,QACpC,GAAID,EAAiB,CACjB,IAAKvB,EAED,YADAuB,EAAgBhB,MAAMkB,OAAS,IAI/BR,GAAmBT,GACnBe,EAAgBhB,MAAMkB,OAAS,OAC/BF,EAAgBhB,MAAMkB,OAAS,GAAGF,EAAgBG,kBAElDH,EAAgBhB,MAAMkB,OAAS,EAEvC,GACD,CAACzB,EAAYqB,EAAab,EAAOS,EAAiBL,IAuBrD,MAAMe,EAAuB1B,GAAS2B,WAAa,EAC7CC,EAA0BF,EAAef,EAO/C,MAKMkB,KAAkBrB,KAJpBR,GAAWW,EAAiBe,EACtB,kBAAkBf,EAAiBe,sBACnC,IAQV,OACII,EAAC,MAAA,CACGC,UAAU,wBACV,eAAcF,EACd,mBAAkBlB,EAAiB,EAEnCqB,SAAA,CAAAC,EAAC,WAAA,CACG,eAAcJ,EACdE,UAAW,sDAAsD5B,SACjEF,OA1CZ,SAAsBiC,GAClBjB,GAAmB,GACfhB,GACAA,EAAOiC,EAEf,EAsCYhC,QAlDZ,SAAuBgC,GACnBjB,GAAmB,GACff,GACAA,EAAQgC,EAEhB,EA8CYzB,SArCZ,SAAwByB,GACpBtB,EAAkBsB,EAAEC,OAAO5B,MAAMQ,QAC7BN,GACAA,EAASyB,EAEjB,EAiCYpC,IAAKsB,EACLd,MAAO,IAAKA,KAjBF,CAClB8B,UAAWrC,EAAa,cAAW,IAiB3BK,YAAAA,EACAG,MAAAA,KACIG,IAEPV,GACG8B,EAAC,MAAA,CAAIC,UAAU,yBAAyB,cAAY,OAChDC,SAAA,CAAAF,EAAC,MAAA,CAAIC,UAAU,+BACVC,SAAA,CAAArB,EAAe,MAAce,MAEhC1B,EAAQqC,cACNJ,EAAC,MAAA,CACGF,UAAU,kCACVzB,MAAO,CACF,oBA5CAiB,EA6CGK,EA7CcU,EA8CdZ,EA7CxBH,GAAW,GAGE,IAAVe,EAFI,EAEyB,IAAVf,EAAiBe,GAwCa,aA5C5D,IAA6Bf,EAAiBe,IAyDtD3C,EAAa4C,YAAc"}
1
+ {"version":3,"file":"BaseTextArea.js","sources":["../../../../src/components/text-area/BaseTextArea.tsx"],"sourcesContent":["import React, {\n type ChangeEvent,\n type FocusEvent,\n forwardRef,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { getCounterValue } from \"./counter.js\";\nimport type { BaseTextAreaProps } from \"./types.js\";\n\nexport const BaseTextArea = forwardRef<HTMLTextAreaElement, BaseTextAreaProps>(\n (props, ref) => {\n const {\n autoExpand,\n counter,\n defaultValue,\n onBlur,\n onFocus,\n rows = 7,\n placeholder = \" \", // This space intentionally left blank. Denne + rows trengs for å få den ekspanderende effekten.\n startOpen,\n style,\n value,\n \"aria-invalid\": ariaInvalid,\n onChange,\n ...rest\n } = props;\n\n const strategy = counter?.strategy ?? \"characters\";\n const isControlled = typeof value !== \"undefined\";\n\n const [uncontrolledValue, setUncontrolledValue] =\n useState(defaultValue);\n const [textAreaFocused, setTextAreaFocused] = useState(false);\n const internalRef = useRef<HTMLTextAreaElement>(null);\n const textAreaRef =\n (ref as RefObject<HTMLTextAreaElement>) || internalRef;\n\n // Hvis feltet styres utenfra bruker vi `value`, ellers holder vi styr på verdien selv.\n const textAreaValue = isControlled ? value : uncontrolledValue;\n const textAreaValueProps = isControlled ? { value } : { defaultValue };\n\n const counterCurrent = getCounterValue(textAreaValue, strategy);\n const counterTotal: number = counter?.maxLength || 0;\n const progressCurrent: number = counterTotal - counterCurrent;\n const isOverLimit = Boolean(counter && counterCurrent > counterTotal);\n const invalid = Boolean(ariaInvalid || isOverLimit);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: counterCurrent trengs for å lytte på tekstendringer i textarea for auto-expand funksjonalitet\n useEffect(() => {\n const textAreaElement = textAreaRef.current;\n if (textAreaElement) {\n if (!autoExpand) {\n textAreaElement.style.height = \"\";\n return;\n }\n\n if (textAreaFocused || textAreaValue) {\n textAreaElement.style.height = \"auto\"; // Sett til auto før scrollhøyden leses, sånn at redusering av høyde ved sletting av tekst fungerer\n textAreaElement.style.height = `${textAreaElement.scrollHeight}px`;\n } else {\n textAreaElement.style.height = \"\";\n }\n }\n }, [\n autoExpand,\n textAreaRef,\n textAreaValue,\n textAreaFocused,\n counterCurrent,\n ]);\n\n function handleOnFocus(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(true);\n if (onFocus) {\n onFocus(e);\n }\n }\n\n function handleOnBlur(e: FocusEvent<HTMLTextAreaElement>) {\n setTextAreaFocused(false);\n if (onBlur) {\n onBlur(e);\n }\n }\n\n function handleOnChange(e: ChangeEvent<HTMLTextAreaElement>) {\n if (!isControlled) {\n setUncontrolledValue(e.target.value);\n }\n\n if (onChange) {\n onChange(e);\n }\n }\n function calculatePercentage(current: number, total: number): number {\n if (current <= 0) {\n return 0;\n }\n return total === 0 ? 0 : (current * 100) / total;\n }\n\n const overflowStyle = {\n overflowX: autoExpand ? \"hidden\" : undefined, // Must set overflowX hidden for Firefox https://stackoverflow.com/a/22700700\n } as React.CSSProperties;\n\n return (\n <div\n className=\"jkl-text-area-wrapper\"\n data-invalid={invalid}\n data-has-content={counterCurrent > 0}\n >\n <textarea\n aria-invalid={invalid}\n className={`jkl-text-area__text-area jkl-text-area__text-area--${rows}-rows`}\n onBlur={handleOnBlur}\n onFocus={handleOnFocus}\n onChange={handleOnChange}\n ref={textAreaRef}\n style={{ ...style, ...overflowStyle }}\n placeholder={placeholder}\n {...textAreaValueProps}\n {...rest}\n />\n {counter && (\n <div className=\"jkl-text-area__counter\" aria-hidden=\"true\">\n <div className=\"jkl-text-area__counter-count\">\n {counterCurrent}&nbsp;/&nbsp;{counterTotal}\n </div>\n {!counter.hideProgress && (\n <div\n className=\"jkl-text-area__counter-progress\"\n style={{\n [\"--progress-width\" as string]: `${calculatePercentage(\n progressCurrent,\n counterTotal,\n )}%`,\n }}\n />\n )}\n </div>\n )}\n </div>\n );\n },\n);\nBaseTextArea.displayName = \"BaseTextArea\";\n"],"names":["BaseTextArea","forwardRef","props","ref","autoExpand","counter","defaultValue","onBlur","onFocus","rows","placeholder","startOpen","style","value","ariaInvalid","onChange","rest","strategy","isControlled","uncontrolledValue","setUncontrolledValue","useState","textAreaFocused","setTextAreaFocused","internalRef","useRef","textAreaRef","textAreaValue","textAreaValueProps","counterCurrent","getCounterValue","counterTotal","maxLength","progressCurrent","invalid","useEffect","textAreaElement","current","height","scrollHeight","jsxs","className","children","jsx","e","target","overflowX","hideProgress","total","displayName"],"mappings":"6KAYO,MAAMA,EAAeC,EACxB,CAACC,EAAOC,KACJ,MACIC,WAAAA,EACAC,QAAAA,EACAC,aAAAA,EACAC,OAAAA,EACAC,QAAAA,EACAC,KAAAA,EAAO,EACPC,YAAAA,EAAc,IACdC,UAAAA,EACAC,MAAAA,EACAC,MAAAA,EACA,eAAgBC,EAChBC,SAAAA,KACGC,GACHd,EAEEe,EAAWZ,GAASY,UAAY,aAChCC,SAAsBL,EAAU,KAE/BM,EAAmBC,GACtBC,EAASf,IACNgB,EAAiBC,GAAsBF,GAAS,GACjDG,EAAcC,EAA4B,MAC1CC,EACDvB,GAA0CqB,EAGzCG,EAAgBT,EAAeL,EAAQM,EACvCS,EAAqBV,EAAe,CAAEL,MAAAA,GAAU,CAAEP,aAAAA,GAElDuB,EAAiBC,EAAgBH,EAAeV,GAChDc,EAAuB1B,GAAS2B,WAAa,EAC7CC,EAA0BF,EAAeF,EAEzCK,KAAkBpB,OADIT,GAAWwB,EAAiBE,IAIxDI,EAAU,KACN,MAAMC,EAAkBV,EAAYW,QACpC,GAAID,EAAiB,CACjB,IAAKhC,EAED,YADAgC,EAAgBxB,MAAM0B,OAAS,IAI/BhB,GAAmBK,GACnBS,EAAgBxB,MAAM0B,OAAS,OAC/BF,EAAgBxB,MAAM0B,OAAS,GAAGF,EAAgBG,kBAElDH,EAAgBxB,MAAM0B,OAAS,EAEvC,GACD,CACClC,EACAsB,EACAC,EACAL,EACAO,IAqCJ,OACIW,EAAC,MAAA,CACGC,UAAU,wBACV,eAAcP,EACd,mBAAkBL,EAAiB,EAEnCa,SAAA,CAAAC,EAAC,WAAA,CACG,eAAcT,EACdO,UAAW,sDAAsDhC,SACjEF,OApCZ,SAAsBqC,GAClBrB,GAAmB,GACfhB,GACAA,EAAOqC,EAEf,EAgCYpC,QA5CZ,SAAuBoC,GACnBrB,GAAmB,GACff,GACAA,EAAQoC,EAEhB,EAwCY7B,SA/BZ,SAAwB6B,GACf1B,GACDE,EAAqBwB,EAAEC,OAAOhC,OAG9BE,GACAA,EAAS6B,EAEjB,EAwBYzC,IAAKuB,EACLd,MAAO,IAAKA,KAjBF,CAClBkC,UAAW1C,EAAa,cAAW,IAiB3BM,YAAAA,KACIkB,KACAZ,IAEPX,GACGmC,EAAC,MAAA,CAAIC,UAAU,yBAAyB,cAAY,OAChDC,SAAA,CAAAF,EAAC,MAAA,CAAIC,UAAU,+BACVC,SAAA,CAAAb,EAAe,MAAcE,MAEhC1B,EAAQ0C,cACNJ,EAAC,MAAA,CACGF,UAAU,kCACV7B,MAAO,CACF,oBAtCAyB,EAuCGJ,EAvCce,EAwCdjB,EAvCxBM,GAAW,GAGE,IAAVW,EAFI,EAEyB,IAAVX,EAAiBW,GAkCa,aAtC5D,IAA6BX,EAAiBW,IAmDtDhD,EAAaiD,YAAc"}
@@ -0,0 +1,2 @@
1
+ import { CounterStrategy } from './types.js';
2
+ export declare function getCounterValue(value: string | number | readonly string[] | undefined, strategy?: CounterStrategy): number;
@@ -0,0 +1,2 @@
1
+ const e=new TextEncoder;function t(t,n="characters"){if(typeof t>"u")return 0;const r="string"==typeof t?t:Array.isArray(t)?t.join(""):String(t);return"bytes"===n?e.encode(r).length:r.length}export{t as getCounterValue};
2
+ //# sourceMappingURL=counter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter.js","sources":["../../../../src/components/text-area/counter.ts"],"sourcesContent":["import type { CounterStrategy } from \"./types.js\";\n\nconst textEncoder = new TextEncoder();\n\nexport function getCounterValue(\n value: string | number | readonly string[] | undefined,\n strategy: CounterStrategy = \"characters\",\n): number {\n if (typeof value === \"undefined\") {\n return 0;\n }\n\n const normalizedValue =\n typeof value === \"string\"\n ? value\n : Array.isArray(value)\n ? value.join(\"\")\n : String(value);\n\n if (strategy === \"bytes\") {\n return textEncoder.encode(normalizedValue).length;\n }\n\n return normalizedValue.length;\n}\n"],"names":["textEncoder","TextEncoder","getCounterValue","value","strategy","normalizedValue","Array","isArray","join","String","encode","length"],"mappings":"AAEA,MAAMA,EAAc,IAAIC,YAEjB,SAASC,EACZC,EACAC,EAA4B,cAE5B,UAAWD,EAAU,IACjB,OAAO,EAGX,MAAME,EACe,iBAAVF,EACDA,EACAG,MAAMC,QAAQJ,GACZA,EAAMK,KAAK,IACXC,OAAON,GAEnB,MAAiB,UAAbC,EACOJ,EAAYU,OAAOL,GAAiBM,OAGxCN,EAAgBM,MAC3B"}
@@ -1,8 +1,28 @@
1
1
  import { TextareaHTMLAttributes } from 'react';
2
2
  import { InputGroupProps } from '../input-group/types.js';
3
+ export type CounterStrategy = "characters" | "bytes";
3
4
  export type Counter = {
4
- /** Antall tegn før telleren når maksimum og vi viser en feilmelding */
5
+ /**
6
+ * Maksverdi for telleren.
7
+ *
8
+ * Enheten avhenger av `strategy`:
9
+ * - `"characters"`: antall tegn
10
+ * - `"bytes"`: antall UTF-8-bytes
11
+ */
5
12
  maxLength: number;
13
+ /**
14
+ * Bestemmer hva telleren måler.
15
+ *
16
+ * - "characters" teller tekst på samme måte som i dag og er standard
17
+ * - "bytes" teller antall UTF-8-bytes, for usecaser der backend eller API
18
+ * håndhever en bytegrense
19
+ *
20
+ * Unngå å kombinere `strategy="bytes"` med native `maxLength` på
21
+ * `<textarea>`, siden nettleseren fortsatt håndhever `maxLength` som tegn.
22
+ *
23
+ * @default "characters"
24
+ */
25
+ strategy?: CounterStrategy;
6
26
  /**
7
27
  * Med teller vises en progress-bar i bunnen av tekstfeltet som krymper
8
28
  * ned fra 100% (null tegn skrevet) til 0% (maks antall tegn skrevet).
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+ import { TextElement, TextProps } from './types.js';
3
+ type TextComponent = <As extends TextElement = "p">(props: TextProps<As>) => React.ReactElement | null;
4
+ export declare const Text: TextComponent;
5
+ export {};
@@ -0,0 +1,2 @@
1
+ import{jsx as s}from"react/jsx-runtime";import{c as t}from"../../../clsx-BeLtu-UY.js";import{forwardRef as r}from"react";const a=r(function({as:r,className:a,size:o="m",bold:e,short:m,srOnly:i,...l},c){return s(r||"p",{className:t("jkl-text",i&&"jkl-sr-only",a),"data-text-size":o,"data-bold":e||void 0,"data-short":m||void 0,ref:c,...l})});export{a as Text};
2
+ //# sourceMappingURL=Text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Text.js","sources":["../../../../src/components/typography/Text.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { forwardRef } from \"react\";\nimport type { PolymorphicRef } from \"../../utilities/index.js\";\nimport type { TextElement, TextProps } from \"./types.js\";\n\ntype TextComponent = <As extends TextElement = \"p\">(\n props: TextProps<As>,\n) => React.ReactElement | null;\n\nexport const Text: TextComponent = forwardRef(function Text<\n As extends TextElement = \"p\",\n>(\n { as, className, size = \"m\", bold, short, srOnly, ...rest }: TextProps<As>,\n ref?: PolymorphicRef<As>,\n) {\n const Component = (as || \"p\") as React.ElementType;\n return (\n <Component\n className={clsx(\"jkl-text\", srOnly && \"jkl-sr-only\", className)}\n data-text-size={size}\n data-bold={bold || undefined}\n data-short={short || undefined}\n ref={ref}\n {...rest}\n />\n );\n}) as TextComponent;\n"],"names":["Text","forwardRef","as","className","size","bold","short","srOnly","rest","ref","jsx","clsx"],"mappings":"yHASO,MAAMA,EAAsBC,EAAW,UAGxCC,GAAAA,EAAIC,UAAAA,EAAWC,KAAAA,EAAO,IAAKC,KAAAA,EAAMC,MAAAA,EAAOC,OAAAA,KAAWC,GACrDC,GAGA,OACIC,EAFeR,GAAM,IAEpB,CACGC,UAAWQ,EAAK,WAAYJ,GAAU,cAAeJ,GACrD,iBAAgBC,EAChB,YAAWC,QAAQ,EACnB,aAAYC,QAAS,EACrBG,IAAAA,KACID,GAGhB"}
@@ -0,0 +1,5 @@
1
+ import { default as React } from 'react';
2
+ import { TitleElement, TitleProps } from './types.js';
3
+ type TitleComponent = <As extends TitleElement = "h2">(props: TitleProps<As>) => React.ReactElement | null;
4
+ export declare const Title: TitleComponent;
5
+ export {};
@@ -0,0 +1,2 @@
1
+ import{jsx as s}from"react/jsx-runtime";import{c as r}from"../../../clsx-BeLtu-UY.js";import{forwardRef as t}from"react";const a=t(function({className:t,size:a="l",as:e,srOnly:o,...l},i){return s(e||"h2",{className:r("jkl-title",o&&"jkl-sr-only",t),"data-text-size":a,ref:i,...l})});export{a as Title};
2
+ //# sourceMappingURL=Title.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Title.js","sources":["../../../../src/components/typography/Title.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { forwardRef } from \"react\";\nimport type { PolymorphicRef } from \"../../utilities/index.js\";\nimport type { TitleElement, TitleProps } from \"./types.js\";\n\ntype TitleComponent = <As extends TitleElement = \"h2\">(\n props: TitleProps<As>,\n) => React.ReactElement | null;\n\nexport const Title: TitleComponent = forwardRef(function Title<\n As extends TitleElement = \"h2\",\n>(\n { className, size = \"l\", as, srOnly, ...rest }: TitleProps<As>,\n ref?: PolymorphicRef<As>,\n) {\n const Tag = (as || \"h2\") as React.ElementType;\n return (\n <Tag\n className={clsx(\"jkl-title\", srOnly && \"jkl-sr-only\", className)}\n data-text-size={size}\n ref={ref}\n {...rest}\n />\n );\n}) as TitleComponent;\n"],"names":["Title","forwardRef","className","size","as","srOnly","rest","ref","jsx","clsx"],"mappings":"yHASO,MAAMA,EAAwBC,EAAW,UAG1CC,UAAAA,EAAWC,KAAAA,EAAO,IAAKC,GAAAA,EAAIC,OAAAA,KAAWC,GACxCC,GAGA,OACIC,EAFSJ,GAAM,KAEd,CACGF,UAAWO,EAAK,YAAaJ,GAAU,cAAeH,GACtD,iBAAgBC,EAChBI,IAAAA,KACID,GAGhB"}
@@ -0,0 +1,3 @@
1
+ export { Text } from './Text.js';
2
+ export { Title } from './Title.js';
3
+ export type { TextProps, TextSize, TitleProps, TitleSize } from './types.js';
@@ -0,0 +1,2 @@
1
+ import{Text as t}from"./Text.js";import{Title as e}from"./Title.js";export{t as Text,e as Title};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,48 @@
1
+ import { PolymorphicPropsWithRef } from '../../utilities/index.js';
2
+ export type TextElement = "p" | "span" | "label" | "legend" | "small" | "strong" | "em" | "code" | "kbd" | "samp" | "var";
3
+ export type TitleElement = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "label" | "legend";
4
+ export type TextSize = "xs" | "s" | "m" | "l";
5
+ export type TitleSize = "xs" | "s" | "m" | "l" | "xl";
6
+ type TextOwnProps = {
7
+ /**
8
+ * Visuell størrelse på teksten. Tilsvarer font-size-tokens i Jøkul.
9
+ * @default "m"
10
+ */
11
+ size?: TextSize;
12
+ /**
13
+ * Uthever teksten (font-weight: bold).
14
+ * @default false
15
+ */
16
+ bold?: boolean;
17
+ /**
18
+ * Setter mindre linjehøyde — bruk når teksten i all hovedsak går over
19
+ * én linje (f.eks. i tabellceller eller knapper).
20
+ * @default false
21
+ */
22
+ short?: boolean;
23
+ /**
24
+ * Skjuler elementet visuelt, men beholder det for skjermlesere.
25
+ * Bruk for å gi ekstra kontekst til assistive teknologier uten å
26
+ * påvirke det visuelle.
27
+ * @default false
28
+ */
29
+ srOnly?: boolean;
30
+ };
31
+ type TitleOwnProps = {
32
+ /**
33
+ * Visuell størrelse på tittelen. Frakoblet fra `as` — velg semantisk
34
+ * nivå via `as`, og visuell størrelse via `size`.
35
+ * @default "l"
36
+ */
37
+ size?: TitleSize;
38
+ /**
39
+ * Skjuler elementet visuelt, men beholder det for skjermlesere.
40
+ * Bruk for å beholde riktig overskrifts-hierarki i skjermlesere
41
+ * uten å vise tittelen visuelt.
42
+ * @default false
43
+ */
44
+ srOnly?: boolean;
45
+ };
46
+ export type TextProps<As extends TextElement = "p"> = PolymorphicPropsWithRef<As, TextOwnProps>;
47
+ export type TitleProps<As extends TitleElement = "h2"> = PolymorphicPropsWithRef<As, TitleOwnProps>;
48
+ export {};
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fremtind/jokul",
3
- "version": "5.0.0-next.2",
3
+ "version": "5.0.0-next.3",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"