@fremtind/jokul 6.0.0-next.3 → 6.0.0-next.5

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 (79) hide show
  1. package/build/build-stats.html +1 -1
  2. package/build/cjs/components/autosuggest/Autosuggest.cjs.map +1 -1
  3. package/build/cjs/components/autosuggest/Autosuggest.d.cts +5 -0
  4. package/build/cjs/components/combobox/Combobox.cjs.map +1 -1
  5. package/build/cjs/components/combobox/Combobox.d.cts +4 -0
  6. package/build/cjs/components/flex/Flex.cjs +1 -1
  7. package/build/cjs/components/flex/Flex.cjs.map +1 -1
  8. package/build/cjs/components/flex/types.cjs +1 -1
  9. package/build/cjs/components/flex/types.cjs.map +1 -1
  10. package/build/cjs/components/flex/types.d.cts +36 -26
  11. package/build/cjs/components/image/Image.cjs +1 -1
  12. package/build/cjs/components/image/Image.cjs.map +1 -1
  13. package/build/cjs/components/number-input/NumberInput.cjs.map +1 -1
  14. package/build/cjs/components/segmented-control/SegmentedControl.cjs +1 -1
  15. package/build/cjs/components/segmented-control/SegmentedControl.cjs.map +1 -1
  16. package/build/cjs/components/select/Option.cjs.map +1 -1
  17. package/build/cjs/components/select/Select.cjs.map +1 -1
  18. package/build/cjs/components/select/Select.d.cts +1 -1
  19. package/build/cjs/components/select/utils.cjs.map +1 -1
  20. package/build/cjs/components/table/stories/assets/table-data.cjs +2 -0
  21. package/build/cjs/components/table/stories/assets/table-data.cjs.map +1 -0
  22. package/build/cjs/components/table/stories/assets/table-data.d.cts +8 -0
  23. package/build/es/components/autosuggest/Autosuggest.d.ts +5 -0
  24. package/build/es/components/autosuggest/Autosuggest.js.map +1 -1
  25. package/build/es/components/combobox/Combobox.d.ts +4 -0
  26. package/build/es/components/combobox/Combobox.js.map +1 -1
  27. package/build/es/components/flex/Flex.js +1 -1
  28. package/build/es/components/flex/Flex.js.map +1 -1
  29. package/build/es/components/flex/types.d.ts +36 -26
  30. package/build/es/components/flex/types.js +1 -1
  31. package/build/es/components/flex/types.js.map +1 -1
  32. package/build/es/components/image/Image.js +1 -1
  33. package/build/es/components/image/Image.js.map +1 -1
  34. package/build/es/components/number-input/NumberInput.js.map +1 -1
  35. package/build/es/components/segmented-control/SegmentedControl.js +1 -1
  36. package/build/es/components/segmented-control/SegmentedControl.js.map +1 -1
  37. package/build/es/components/select/Option.js.map +1 -1
  38. package/build/es/components/select/Select.d.ts +1 -1
  39. package/build/es/components/select/Select.js.map +1 -1
  40. package/build/es/components/select/utils.js.map +1 -1
  41. package/build/es/components/table/stories/assets/table-data.d.ts +8 -0
  42. package/build/es/components/table/stories/assets/table-data.js +2 -0
  43. package/build/es/components/table/stories/assets/table-data.js.map +1 -0
  44. package/codemods/CODEMODS.md +115 -83
  45. package/codemods/__tests__/import-paths.test.mjs +107 -1
  46. package/codemods/import-paths.mjs +5 -1
  47. package/codemods/transforms/select.mjs +237 -0
  48. package/package.json +1 -2
  49. package/styles/base.css +4 -3
  50. package/styles/base.min.css +1 -1
  51. package/styles/components/countdown/countdown.css +2 -2
  52. package/styles/components/countdown/countdown.min.css +1 -1
  53. package/styles/components/feedback/feedback.css +2 -2
  54. package/styles/components/feedback/feedback.min.css +1 -1
  55. package/styles/components/file-input/file-input.css +9 -9
  56. package/styles/components/file-input/file-input.min.css +1 -1
  57. package/styles/components/flex/flex.css +16 -1343
  58. package/styles/components/flex/flex.min.css +1 -1
  59. package/styles/components/flex/flex.scss +14 -280
  60. package/styles/components/input-group/input-group.css +2 -2
  61. package/styles/components/input-group/input-group.min.css +1 -1
  62. package/styles/components/loader/loader.css +6 -6
  63. package/styles/components/loader/loader.min.css +1 -1
  64. package/styles/components/loader/skeleton-loader.css +3 -3
  65. package/styles/components/loader/skeleton-loader.min.css +1 -1
  66. package/styles/components/message/message.css +2 -2
  67. package/styles/components/message/message.min.css +1 -1
  68. package/styles/components/progress-bar/progress-bar.css +1 -1
  69. package/styles/components/progress-bar/progress-bar.min.css +1 -1
  70. package/styles/components/segmented-control/segmented-control.css +2 -2
  71. package/styles/components/segmented-control/segmented-control.min.css +1 -1
  72. package/styles/components/system-message/system-message.css +2 -2
  73. package/styles/components/system-message/system-message.min.css +1 -1
  74. package/styles/components/toast/toast.css +4 -4
  75. package/styles/components/toast/toast.min.css +1 -1
  76. package/styles/components.css +37 -1367
  77. package/styles/components.min.css +2 -2
  78. package/styles/theme/_tokens.scss +2 -1
  79. package/styles/theme/brands/dnb/_color-scheme.scss +2 -2
@@ -1,7 +1,7 @@
1
1
  import { ComponentPropsWithoutRef } from 'react';
2
+ import { DataTestAutoId } from '../../utilities/types.cjs';
2
3
  import { ValuePair } from '../../utilities/valuePair.cjs';
3
4
  import { InputGroupProps } from '../input-group/types.cjs';
4
- import { DataTestAutoId } from '../../utilities/types.cjs';
5
5
  export type SelectProps = Omit<InputGroupProps, "children" | "inline"> & DataTestAutoId & Omit<ComponentPropsWithoutRef<"select">, "size" | "children"> & {
6
6
  width?: string;
7
7
  items: (string | ValuePair)[];
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","sources":["../../../../src/components/select/utils.ts"],"sourcesContent":["import { type ReactNode, isValidElement } from \"react\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\n\nexport function getReactNodeText(node: ReactNode): string {\n if (typeof node === \"string\" || typeof node === \"number\") return String(node);\n if (Array.isArray(node)) return node.map(getReactNodeText).join(\"\");\n if (isValidElement(node)) return getReactNodeText(node.props.children);\n return \"\";\n}\n\nexport const getButtonText = (\n selected: Set<string>,\n valuePairs: ValuePair[],\n placeholderText: string,\n): string => {\n if (selected.size === 1) {\n return (\n valuePairs.find((p) => selected.has(p.value))?.label ??\n placeholderText\n );\n }\n return `${selected.size} valgt`;\n};\n\nexport const autofocus =\n (active: boolean | (() => boolean)) => (el: HTMLElement | null) => {\n if (el) el.autofocus = typeof active === \"boolean\" ? active : active();\n };\n"],"names":["active","el","autofocus","selected","valuePairs","placeholderText","size","find","p","has","value","label","getReactNodeText","node","String","Array","isArray","map","join","isValidElement","props","children"],"mappings":"2HAyBKA,GAAuCC,IAChCA,IAAIA,EAAGC,UAA8B,kBAAXF,EAAuBA,EAASA,4BAhBzC,CACzBG,EACAC,EACAC,IAEsB,IAAlBF,EAASG,KAELF,EAAWG,KAAMC,GAAML,EAASM,IAAID,EAAEE,SAASC,OAC/CN,EAGD,GAAGF,EAASG,sCAlBhB,SAASM,EAAiBC,GAC7B,MAAoB,iBAATA,GAAqC,iBAATA,EAA0BC,OAAOD,GACpEE,MAAMC,QAAQH,GAAcA,EAAKI,IAAIL,GAAkBM,KAAK,IAC5DC,EAAAA,eAAeN,GAAcD,EAAiBC,EAAKO,MAAMC,UACtD,EACX"}
1
+ {"version":3,"file":"utils.cjs","sources":["../../../../src/components/select/utils.ts"],"sourcesContent":["import { type ReactNode, isValidElement } from \"react\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\n\nexport function getReactNodeText(node: ReactNode): string {\n if (typeof node === \"string\" || typeof node === \"number\")\n return String(node);\n if (Array.isArray(node)) return node.map(getReactNodeText).join(\"\");\n if (isValidElement(node)) return getReactNodeText(node.props.children);\n return \"\";\n}\n\nexport const getButtonText = (\n selected: Set<string>,\n valuePairs: ValuePair[],\n placeholderText: string,\n): string => {\n if (selected.size === 1) {\n return (\n valuePairs.find((p) => selected.has(p.value))?.label ??\n placeholderText\n );\n }\n return `${selected.size} valgt`;\n};\n\nexport const autofocus =\n (active: boolean | (() => boolean)) => (el: HTMLElement | null) => {\n if (el) el.autofocus = typeof active === \"boolean\" ? active : active();\n };\n"],"names":["active","el","autofocus","selected","valuePairs","placeholderText","size","find","p","has","value","label","getReactNodeText","node","String","Array","isArray","map","join","isValidElement","props","children"],"mappings":"2HA0BKA,GAAuCC,IAChCA,IAAIA,EAAGC,UAA8B,kBAAXF,EAAuBA,EAASA,4BAhBzC,CACzBG,EACAC,EACAC,IAEsB,IAAlBF,EAASG,KAELF,EAAWG,KAAMC,GAAML,EAASM,IAAID,EAAEE,SAASC,OAC/CN,EAGD,GAAGF,EAASG,sCAnBhB,SAASM,EAAiBC,GAC7B,MAAoB,iBAATA,GAAqC,iBAATA,EAC5BC,OAAOD,GACdE,MAAMC,QAAQH,GAAcA,EAAKI,IAAIL,GAAkBM,KAAK,IAC5DC,EAAAA,eAAeN,GAAcD,EAAiBC,EAAKO,MAAMC,UACtD,EACX"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r={columns:["Forfallsdato","Type","Beløp","Status","Produkt","Kontonummer","KID","Betalingstype"],rows:[[new Date(2025,10,15),"Skade",612.32,"Faktura",["Bilforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,9,15),"Person",402.67,"Påminnelse",["Hundeforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,8,15),"Person",2412.67,"Inkassovarsel",["Bilforsikring","Katteforsikring","Båtforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,7,15),"Person",719.17,"Faktura",["Båtforsikring","Hundeforsikring","Bilforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,6,15),"Skade",992.01,"Faktura",["Bilforsikring","Hundeforsikring","Elsparkesykkel"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,5,15),"Person",772.79,"Faktura",["Bilforsikring","Hus","Bilforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,4,15),"Person",772.79,"Faktura",["Bilforsikring","Hundeforsikring","Bilforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,3,15),"Person",772.79,"Faktura",["Bilforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,2,15),"Person",772.79,"Faktura",["Bil","Hus","Innbo"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,1,15),"Person",772.79,"Faktura",["Bilforsikring","Hundeforsikring","Katteforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2025,0,15),"Person",772.79,"Faktura",["Hundeforsikring","Barneforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2024,11,15),"Person",772.79,"Faktura",["Elsparkesykkel"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2024,10,15),"Person",772.79,"Faktura",["Hundeforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2024,9,15),"Person",772.79,"Faktura",["Bilforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"],[new Date(2024,8,15),"Person",772.79,"Faktura",["Bilforsikring","Hundeforsikring"],"9001.17.00771","1631 4283 2245","eFaktura"]]};exports.faktura=r,exports.skadesaker={columns:["Dato","Saksnummer","Kundenummer","Kundenavn","Milepæl","Følger saken"],rows:[["24.02.2025","20-1234567","010203 99887","Ola Nordmann","Opprettet","Siri Saksbehandler"],["13.04.2019","20-8382811","010203 99887","Kari Nordkvinne","Opprettet","Siri Saksbehandler"],["31.07.2017","20-1111","010203 99887","Kari Nordkvinne","Opprettet","Per Persen"]]};
2
+ //# sourceMappingURL=table-data.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-data.cjs","sources":["../../../../../../src/components/table/stories/assets/table-data.ts"],"sourcesContent":["export const skadesaker = {\n columns: [\n \"Dato\",\n \"Saksnummer\",\n \"Kundenummer\",\n \"Kundenavn\",\n \"Milepæl\",\n \"Følger saken\",\n ],\n rows: [\n [\n \"24.02.2025\",\n \"20-1234567\",\n \"010203 99887\",\n \"Ola Nordmann\",\n \"Opprettet\",\n \"Siri Saksbehandler\",\n ],\n [\n \"13.04.2019\",\n \"20-8382811\",\n \"010203 99887\",\n \"Kari Nordkvinne\",\n \"Opprettet\",\n \"Siri Saksbehandler\",\n ],\n [\n \"31.07.2017\",\n \"20-1111\",\n \"010203 99887\",\n \"Kari Nordkvinne\",\n \"Opprettet\",\n \"Per Persen\",\n ],\n ],\n};\n\nexport const faktura = {\n columns: [\n \"Forfallsdato\",\n \"Type\",\n \"Beløp\",\n \"Status\",\n \"Produkt\",\n \"Kontonummer\",\n \"KID\",\n \"Betalingstype\",\n ],\n rows: [\n [\n new Date(2025, 10, 15),\n \"Skade\",\n 612.32,\n \"Faktura\",\n [\"Bilforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 9, 15),\n \"Person\",\n 402.67,\n \"Påminnelse\",\n [\"Hundeforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 8, 15),\n \"Person\",\n 2412.67,\n \"Inkassovarsel\",\n [\"Bilforsikring\", \"Katteforsikring\", \"Båtforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 7, 15),\n \"Person\",\n 719.17,\n \"Faktura\",\n [\"Båtforsikring\", \"Hundeforsikring\", \"Bilforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 6, 15),\n \"Skade\",\n 992.01,\n \"Faktura\",\n [\"Bilforsikring\", \"Hundeforsikring\", \"Elsparkesykkel\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 5, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Bilforsikring\", \"Hus\", \"Bilforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 4, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Bilforsikring\", \"Hundeforsikring\", \"Bilforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 3, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Bilforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 2, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Bil\", \"Hus\", \"Innbo\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 1, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Bilforsikring\", \"Hundeforsikring\", \"Katteforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2025, 0, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Hundeforsikring\", \"Barneforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2024, 11, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Elsparkesykkel\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2024, 10, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Hundeforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2024, 9, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Bilforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n [\n new Date(2024, 8, 15),\n \"Person\",\n 772.79,\n \"Faktura\",\n [\"Bilforsikring\", \"Hundeforsikring\"],\n \"9001.17.00771\",\n \"1631 4283 2245\",\n \"eFaktura\",\n ],\n ],\n};\n"],"names":["faktura","columns","rows","Date"],"mappings":"gFAAO,MAqCMA,EAAU,CACnBC,QAAS,CACL,eACA,OACA,QACA,SACA,UACA,cACA,MACA,iBAEJC,KAAM,CACF,CACI,IAAIC,KAAK,KAAM,GAAI,IACnB,QACA,OACA,UACA,CAAC,iBACD,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,aACA,CAAC,mBACD,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,QACA,gBACA,CAAC,gBAAiB,kBAAmB,iBACrC,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,gBAAiB,kBAAmB,iBACrC,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,QACA,OACA,UACA,CAAC,gBAAiB,kBAAmB,kBACrC,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,gBAAiB,MAAO,iBACzB,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,gBAAiB,kBAAmB,iBACrC,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,iBACD,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,MAAO,MAAO,SACf,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,gBAAiB,kBAAmB,mBACrC,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,kBAAmB,mBACpB,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,GAAI,IACnB,SACA,OACA,UACA,CAAC,kBACD,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,GAAI,IACnB,SACA,OACA,UACA,CAAC,mBACD,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,iBACD,gBACA,iBACA,YAEJ,CACI,IAAIA,KAAK,KAAM,EAAG,IAClB,SACA,OACA,UACA,CAAC,gBAAiB,mBAClB,gBACA,iBACA,mDArMc,CACtBF,QAAS,CACL,OACA,aACA,cACA,YACA,UACA,gBAEJC,KAAM,CACF,CACI,aACA,aACA,eACA,eACA,YACA,sBAEJ,CACI,aACA,aACA,eACA,kBACA,YACA,sBAEJ,CACI,aACA,UACA,eACA,kBACA,YACA"}
@@ -0,0 +1,8 @@
1
+ export declare const skadesaker: {
2
+ columns: string[];
3
+ rows: string[][];
4
+ };
5
+ export declare const faktura: {
6
+ columns: string[];
7
+ rows: (string | number | string[] | Date)[][];
8
+ };
@@ -1,2 +1,7 @@
1
1
  import { AutosuggestProps } from './types.js';
2
+ /**
3
+ * @deprecated Denne komponenten er utdatert, og vil fjernes i en kommende oppdatering.
4
+ * Bruk heller Select, eller en kombinasjon av Select og TextInput. Se mer om hvordan
5
+ * du gjør dette i portalen: https://jokul.fremtind.no/monster/eget-alternativ
6
+ */
2
7
  export declare const Autosuggest: ({ allItems, onChange, onConfirm, onInputValueChange, onStateChange, value, isOpen, ...rest }: AutosuggestProps) => JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"Autosuggest.js","sources":["../../../../src/components/autosuggest/Autosuggest.tsx"],"sourcesContent":["import type { StateChangeOptions } from \"downshift\";\nimport React, { useEffect, useState } from \"react\";\nimport BaseAutosuggest from \"./BaseAutosuggest.js\";\nimport type { AutosuggestProps } from \"./types.js\";\nimport { filter } from \"./utils.js\";\n\nexport const Autosuggest = ({\n allItems,\n onChange = () => {\n /* default noop */\n },\n onConfirm = () => {\n /* noop */\n },\n onInputValueChange,\n onStateChange,\n value,\n isOpen,\n ...rest\n}: AutosuggestProps): JSX.Element => {\n const [hits, setHits] = useState(allItems);\n\n useEffect(() => setHits(allItems), [allItems]);\n\n const handleStateChange = (changes: StateChangeOptions<string>) => {\n if (onStateChange) {\n onStateChange(changes);\n }\n\n if (changes.selectedItem !== undefined) {\n onChange(changes.selectedItem || \"\");\n } else if (changes.inputValue) {\n setHits(filter(allItems, changes.inputValue));\n }\n };\n\n const itemToString = (item: string | null) => (item ? item : \"\");\n\n return (\n <BaseAutosuggest\n {...rest}\n items={hits}\n itemToString={itemToString}\n onConfirm={onConfirm}\n downshiftProps={{\n selectedItem: value,\n onInputValueChange,\n onStateChange: handleStateChange,\n isOpen,\n }}\n />\n );\n};\n"],"names":["Autosuggest","allItems","onChange","onConfirm","onInputValueChange","onStateChange","value","isOpen","rest","hits","setHits","useState","useEffect","jsx","BaseAutosuggest","items","itemToString","item","downshiftProps","selectedItem","changes","inputValue","filter"],"mappings":"gKAMO,MAAMA,EAAc,EACvBC,SAAAA,EACAC,SAAAA,EAAW,OAGXC,UAAAA,EAAY,OAGZC,mBAAAA,EACAC,cAAAA,EACAC,MAAAA,EACAC,OAAAA,KACGC,MAEH,MAAOC,EAAMC,GAAWC,EAASV,GAEjC,OAAAW,EAAU,IAAMF,EAAQT,GAAW,CAACA,IAiBhCY,EAACC,EAAA,IACON,EACJO,MAAON,EACPO,aANcC,GAAyBA,GAAc,GAOrDd,UAAAA,EACAe,eAAgB,CACZC,aAAcb,EACdF,mBAAAA,EACAC,cAvBee,IACnBf,GACAA,EAAce,QAGW,IAAzBA,EAAQD,aACRjB,EAASkB,EAAQD,cAAgB,IAC1BC,EAAQC,YACfX,EAAQY,EAAOrB,EAAUmB,EAAQC,cAgB7Bd,OAAAA"}
1
+ {"version":3,"file":"Autosuggest.js","sources":["../../../../src/components/autosuggest/Autosuggest.tsx"],"sourcesContent":["import type { StateChangeOptions } from \"downshift\";\nimport React, { useEffect, useState } from \"react\";\nimport BaseAutosuggest from \"./BaseAutosuggest.js\";\nimport type { AutosuggestProps } from \"./types.js\";\nimport { filter } from \"./utils.js\";\n\n/**\n * @deprecated Denne komponenten er utdatert, og vil fjernes i en kommende oppdatering.\n * Bruk heller Select, eller en kombinasjon av Select og TextInput. Se mer om hvordan\n * du gjør dette i portalen: https://jokul.fremtind.no/monster/eget-alternativ\n */\nexport const Autosuggest = ({\n allItems,\n onChange = () => {\n /* default noop */\n },\n onConfirm = () => {\n /* noop */\n },\n onInputValueChange,\n onStateChange,\n value,\n isOpen,\n ...rest\n}: AutosuggestProps): JSX.Element => {\n const [hits, setHits] = useState(allItems);\n\n useEffect(() => setHits(allItems), [allItems]);\n\n const handleStateChange = (changes: StateChangeOptions<string>) => {\n if (onStateChange) {\n onStateChange(changes);\n }\n\n if (changes.selectedItem !== undefined) {\n onChange(changes.selectedItem || \"\");\n } else if (changes.inputValue) {\n setHits(filter(allItems, changes.inputValue));\n }\n };\n\n const itemToString = (item: string | null) => (item ? item : \"\");\n\n return (\n <BaseAutosuggest\n {...rest}\n items={hits}\n itemToString={itemToString}\n onConfirm={onConfirm}\n downshiftProps={{\n selectedItem: value,\n onInputValueChange,\n onStateChange: handleStateChange,\n isOpen,\n }}\n />\n );\n};\n"],"names":["Autosuggest","allItems","onChange","onConfirm","onInputValueChange","onStateChange","value","isOpen","rest","hits","setHits","useState","useEffect","jsx","BaseAutosuggest","items","itemToString","item","downshiftProps","selectedItem","changes","inputValue","filter"],"mappings":"gKAWO,MAAMA,EAAc,EACvBC,SAAAA,EACAC,SAAAA,EAAW,OAGXC,UAAAA,EAAY,OAGZC,mBAAAA,EACAC,cAAAA,EACAC,MAAAA,EACAC,OAAAA,KACGC,MAEH,MAAOC,EAAMC,GAAWC,EAASV,GAEjC,OAAAW,EAAU,IAAMF,EAAQT,GAAW,CAACA,IAiBhCY,EAACC,EAAA,IACON,EACJO,MAAON,EACPO,aANcC,GAAyBA,GAAc,GAOrDd,UAAAA,EACAe,eAAgB,CACZC,aAAcb,EACdF,mBAAAA,EACAC,cAvBee,IACnBf,GACAA,EAAce,QAGW,IAAzBA,EAAQD,aACRjB,EAASkB,EAAQD,cAAgB,IAC1BC,EAAQC,YACfX,EAAQY,EAAOrB,EAAUmB,EAAQC,cAgB7Bd,OAAAA"}
@@ -1,4 +1,8 @@
1
1
  import { FC } from 'react';
2
2
  import { ComboboxProps, ComboboxValuePair } from './types.js';
3
3
  export declare function getComboboxValuePair(item: string | ComboboxValuePair): ComboboxValuePair;
4
+ /**
5
+ * @deprecated Bruk heller Select med `multiple` og `searchable` satt til
6
+ * `true`. Combobox vil bli fjernet ved en senere oppdatering.
7
+ */
4
8
  export declare const Combobox: FC<ComboboxProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"Combobox.js","sources":["../../../../src/components/combobox/Combobox.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n type FC,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useAnimatedHeight } from \"../../hooks/useAnimatedHeight/useAnimatedHeight.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { useListNavigation } from \"../../hooks/useListNavigation/useListNavigation.js\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\nimport { Chip } from \"../chip/Chip.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CheckIcon } from \"../icon/icons/CheckIcon.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport { Tooltip } from \"../tooltip/Tooltip.js\";\nimport { TooltipContent } from \"../tooltip/TooltipContent.js\";\nimport { TooltipTrigger } from \"../tooltip/TooltipTrigger.js\";\nimport type { ComboboxProps, ComboboxValuePair } from \"./types.js\";\n\nexport function getComboboxValuePair(\n item: string | ComboboxValuePair,\n): ComboboxValuePair {\n return typeof item === \"string\" ? { value: item, label: item } : item;\n}\n\nexport const Combobox: FC<ComboboxProps> = (props) => {\n const {\n \"data-size\": dataSize,\n id,\n placeholder,\n items,\n onChange,\n onFocus,\n onBlur,\n value,\n label,\n noMatchingOption,\n labelProps,\n helpLabel,\n errorLabel,\n width,\n name,\n className,\n invalid,\n description,\n hasTagHover,\n tooltip,\n } = props;\n const listId = useId(id || \"jkl-combobox\", { generateSuffix: !id });\n const labelId = `${listId}_label`;\n const buttonId = `${listId}_button`;\n const inputId = `${listId}_search-input`;\n\n const [selectedValue, setSelectedValue] = useState<\n Array<ComboboxValuePair>\n >(value || []);\n const [showMenu, setShowMenu] = useState<boolean>(false);\n const [searchValue, setSearchValue] = useState<string>(\"\");\n const [noResults, setNoResults] = useState(false);\n const [marked, setMarked] = useState<boolean>(false);\n\n const searchRef = useRef<HTMLInputElement>(null);\n const inputRef = useRef<HTMLDivElement>(null);\n const focusInsideRef = useRef(false);\n\n useEffect(() => {\n setSearchValue(\"\");\n if (showMenu && searchRef.current) {\n searchRef.current.focus();\n }\n }, [showMenu]);\n\n useEffect(() => {\n setSelectedValue((prev) => value || prev);\n }, [value]);\n\n // Funksjon for å stile valgt element\n const isSelected = (option: ValuePair) => {\n if (!selectedValue) {\n return false;\n }\n\n return selectedValue.some((value) => value.value === option.value);\n };\n\n // Fjerne ett eller flere valg\n const removeOption = useCallback(\n (option: string) => {\n return selectedValue.filter((value) => value.value !== option);\n },\n [selectedValue],\n );\n\n const onTagRemove = useCallback(\n (\n e:\n | React.MouseEvent<HTMLButtonElement, globalThis.MouseEvent>\n | React.KeyboardEvent<HTMLInputElement>,\n option: string,\n ) => {\n const newValue = removeOption(option);\n setSelectedValue(newValue);\n onChange({\n type: \"change\",\n target: { name, value: option, selectedOptions: newValue },\n });\n e.stopPropagation();\n\n if (newValue.length === 0) {\n setMarked(false);\n }\n },\n [removeOption, onChange, name],\n );\n\n // Håndtere valgt verdi i listen\n const onItemClick = useCallback(\n (option: string) => {\n let newValue: Array<ValuePair>;\n\n if (selectedValue.some((value) => value.value === option)) {\n newValue = removeOption(option);\n } else {\n const item = items.find((i) => i.value === option);\n newValue = [...selectedValue, item as ValuePair];\n }\n searchRef.current?.focus();\n setSelectedValue(newValue);\n onChange({\n type: \"change\",\n target: { name, value: option, selectedOptions: newValue },\n });\n },\n [selectedValue, onChange, name, removeOption, items],\n );\n\n // Funksjon for søk\n const onSearch = (e: {\n target: { value: React.SetStateAction<string> };\n }) => {\n searchRef.current?.focus();\n setShowMenu(true);\n setSearchValue(e.target.value);\n };\n\n const options = useMemo(() => {\n if (!searchValue) {\n return items;\n }\n\n const filteredOptions = items.filter(\n (option) =>\n option.label.toLowerCase().indexOf(searchValue.toLowerCase()) >=\n 0,\n );\n\n setNoResults(filteredOptions.length === 0);\n\n return filteredOptions;\n }, [searchValue, items]);\n\n // Det første elementet i listen skal være aktivt fram til brukeren klikker på noe annet\n const [activeDescendant, setActiveDescendant] = useState<\n string | undefined\n >(options[0]?.value ? `${listId}-${options[0]?.value}` : undefined);\n\n // Håndtere arrow-state\n const isPointingDown = !showMenu;\n\n // Lukk meny med ESC\n useEffect(() => {\n const handleEscape = (e: globalThis.KeyboardEvent) => {\n if (e.key === \"Escape\" && showMenu) {\n setShowMenu(false);\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", handleEscape);\n }\n return () => {\n if (typeof window !== \"undefined\" && showMenu) {\n window.removeEventListener(\"keydown\", handleEscape);\n }\n };\n }, [showMenu]);\n\n // Fokushåndtering\n const handleFocusPlacement = useCallback((isOpen: boolean) => {\n if (isOpen) {\n if (searchRef.current) {\n searchRef.current.focus();\n }\n } else {\n if (focusInsideRef.current && inputRef.current) {\n inputRef.current.focus();\n }\n }\n }, []);\n\n const handleFocus = useCallback(() => {\n if (!focusInsideRef.current) {\n if (onFocus) {\n onFocus({\n type: \"change\",\n target: {\n name,\n value: selectedValue?.[0].value || \"\",\n selectedOptions: selectedValue,\n },\n });\n }\n focusInsideRef.current = true;\n setShowMenu(true);\n }\n }, [onFocus, selectedValue, name]);\n\n const [dropdownRef] = useAnimatedHeight<HTMLDivElement>(showMenu, {\n onFirstVisible: handleFocusPlacement,\n onTransitionEnd: handleFocusPlacement,\n });\n\n useListNavigation({ ref: dropdownRef });\n\n const componentRootElementRef = useRef<HTMLDivElement>(null);\n\n const handleBlur = useCallback(\n (\n e: FocusEvent<\n HTMLDivElement | HTMLInputElement | HTMLButtonElement\n >,\n ) => {\n const componentRootElement = componentRootElementRef.current;\n const nextFocusIsInsideComponent = componentRootElement?.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInsideComponent) {\n setSearchValue(\"\");\n\n if (onBlur) {\n onBlur({\n type: \"blur\",\n target: {\n name,\n value: selectedValue?.[0]?.value || \"\",\n selectedOptions: selectedValue,\n },\n });\n inputRef.current?.dispatchEvent(\n new Event(\"focusout\", { bubbles: true }),\n );\n }\n focusInsideRef.current = false;\n setShowMenu(false);\n }\n },\n [onBlur, name, selectedValue],\n );\n\n const handleMouseOver = useCallback((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 // Tastaturnavigasjon\n const handleSearchOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n const listElement = dropdownRef.current;\n if (listElement) {\n listElement\n .querySelector<HTMLButtonElement>('[role=\"option\"]')\n ?.focus();\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShowMenu(false);\n }\n\n if ((e.metaKey && e.key === \"a\") || (e.ctrlKey && e.key === \"a\")) {\n e.preventDefault();\n e.stopPropagation();\n const updatedSelectedValue = selectedValue.map((item) => ({\n ...item,\n isMarked: true,\n }));\n setMarked(true);\n setSelectedValue(updatedSelectedValue);\n } else if (e.key === \"Backspace\") {\n e.stopPropagation();\n setMarked(false);\n\n // Sjekk om selectedValue er markert\n const selectedValueIsMarked = selectedValue.some(\n (item) => item.isMarked,\n );\n\n if (selectedValueIsMarked) {\n const updatedSelectedValue = selectedValue.filter(\n (item) => !item.isMarked,\n );\n setSelectedValue(updatedSelectedValue);\n setSearchValue(\"\");\n } else if (selectedValue.length > 0 && searchValue === \"\") {\n // Hvis ingen items er markert, fjern siste valgte item\n onTagRemove(\n e,\n selectedValue[selectedValue.length - 1].value,\n );\n }\n }\n },\n [selectedValue, searchValue, dropdownRef, onTagRemove],\n );\n\n const handleOptionOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Tab\") {\n if (searchRef.current) {\n e.preventDefault();\n e.stopPropagation();\n\n if (e.shiftKey) {\n searchRef.current.focus();\n } else {\n setShowMenu(false);\n searchRef.current.focus();\n }\n }\n } else if (e.key === \"ArrowUp\") {\n if (dropdownRef.current && searchRef.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 searchRef.current\n ) {\n searchRef.current.focus();\n }\n }\n }\n },\n [dropdownRef],\n );\n\n const hasSelection = selectedValue.length >= 1;\n\n const renderSelectedOption = useCallback(\n (option: ComboboxValuePair) => (\n <Chip\n key={option.value}\n data-testid=\"jkl-chip\"\n aria-label={`Fjern ${option.tagLabel}`}\n className={`jkl-combobox__selected-option ${\n marked && \"jkl-combobox__selected-option--marked\"\n }`}\n variant=\"input\"\n onClick={(e) => {\n if (searchRef.current) {\n searchRef.current.focus();\n }\n onTagRemove(e, option.value);\n }}\n onBlur={handleBlur}\n >\n {option.tagLabel ? option.tagLabel : option.label}\n </Chip>\n ),\n [handleBlur, onTagRemove, marked],\n );\n\n return (\n <InputGroup\n label={label}\n id={inputId}\n ref={componentRootElementRef}\n data-testid=\"jkl-combobox\"\n data-size={dataSize}\n className={clsx(\"jkl-combobox\", className, {\n \"jkl-combobox--invalid\": !!errorLabel || invalid,\n \"jkl-combobox--menu-open\": showMenu,\n \"jkl-combobox--menu-closed\": !showMenu && hasSelection,\n })}\n labelProps={{\n id: labelId,\n ...labelProps,\n }}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n description={description}\n tooltip={tooltip}\n render={(inputProps) => (\n <div\n className={clsx(\"jkl-combobox__wrapper\", {\n \"jkl-combobox__wrapper--active-value\": hasSelection,\n })}\n style={{ width }}\n tabIndex={-1}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-invalid={!!errorLabel || invalid}\n >\n <div\n className=\"jkl-combobox__chips\"\n data-testid=\"jkl-combobox__chips\"\n >\n {selectedValue\n .map(getComboboxValuePair)\n .map((option) => {\n return hasTagHover ? (\n <Tooltip key={option.value}>\n <TooltipTrigger>\n {renderSelectedOption(option)}\n </TooltipTrigger>\n <TooltipContent>\n {option.label}\n </TooltipContent>\n </Tooltip>\n ) : (\n renderSelectedOption(option)\n );\n })}\n <input\n {...inputProps}\n className=\"jkl-combobox__search-input\"\n onChange={onSearch}\n data-testid=\"jkl-combobox__search-input\"\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleSearchOnKeyDown}\n value={searchValue}\n ref={searchRef}\n aria-controls={listId}\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={showMenu}\n placeholder={\n selectedValue.length > 0 ? \"\" : placeholder\n }\n autoComplete=\"off\"\n />\n </div>\n\n <div\n className=\"jkl-combobox__menu\"\n // biome-ignore lint/a11y/useSemanticElements: Dette er en reimplementering av en liste\n role=\"listbox\"\n ref={dropdownRef}\n id={listId}\n aria-labelledby={labelId}\n aria-multiselectable=\"true\"\n aria-activedescendant={activeDescendant}\n onFocus={handleFocus}\n onBlur={handleBlur}\n tabIndex={-1}\n >\n {options.map((option, i) => (\n <button\n key={`${listId}-${option.value}`}\n type=\"button\"\n id={`${listId}__${option.value}`}\n aria-selected={isSelected(option)}\n // biome-ignore lint/a11y/useSemanticElements: Dette er en reimplementering av en liste\n role=\"option\"\n value={option.value}\n onBlur={handleBlur}\n className={`jkl-combobox__option ${\n isSelected(option) &&\n \"jkl-combobox__option--selected\"\n }`}\n data-testid=\"jkl-combobox__option\"\n data-testautoid={`jkl-combobox__option-${i}`}\n onFocus={handleFocus}\n onKeyDown={handleOptionOnKeyDown}\n onClick={(e) => {\n setActiveDescendant(\n `${listId}__${option.value}`,\n ); // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role#required_javascript_features\n e.stopPropagation();\n onItemClick(option.value);\n setSearchValue(\"\");\n }}\n onMouseOver={handleMouseOver}\n >\n {option.description ? (\n <span>\n {option.label}\n <span className=\"jkl-combobox__option-description\">\n {option.description}\n </span>\n </span>\n ) : (\n option.label\n )}\n {isSelected(option) ? (\n <span>\n <CheckIcon />{\" \"}\n </span>\n ) : null}\n </button>\n ))}\n {noResults && (\n <div className=\"jkl-combobox__no-option\">\n {noMatchingOption}\n </div>\n )}\n </div>\n <IconButton\n id={buttonId}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"jkl-text-input-action-button\"\n data-testid=\"jkl-combobox__button\"\n aria-label=\"Åpne meny\"\n aria-expanded={showMenu}\n aria-controls={listId}\n onClick={() => setShowMenu((previous) => !previous)}\n onMouseDown={(e) => {\n e.preventDefault();\n inputRef.current?.focus();\n }}\n >\n <ArrowVerticalAnimated pointingDown={isPointingDown} />\n </IconButton>\n </div>\n )}\n />\n );\n};\nCombobox.displayName = \"Combobox\";\n"],"names":["getComboboxValuePair","item","value","label","Combobox","props","dataSize","id","placeholder","items","onChange","onFocus","onBlur","noMatchingOption","labelProps","helpLabel","errorLabel","width","name","className","invalid","description","hasTagHover","tooltip","listId","useId","generateSuffix","labelId","buttonId","inputId","selectedValue","setSelectedValue","useState","showMenu","setShowMenu","searchValue","setSearchValue","noResults","setNoResults","marked","setMarked","searchRef","useRef","inputRef","focusInsideRef","useEffect","current","focus","prev","isSelected","option","some","removeOption","useCallback","filter","onTagRemove","e","newValue","type","target","selectedOptions","stopPropagation","length","onItemClick","find","i","onSearch","options","useMemo","filteredOptions","toLowerCase","indexOf","activeDescendant","setActiveDescendant","isPointingDown","handleEscape","key","window","addEventListener","removeEventListener","handleFocusPlacement","isOpen","handleFocus","dropdownRef","useAnimatedHeight","onFirstVisible","onTransitionEnd","useListNavigation","ref","componentRootElementRef","handleBlur","contains","relatedTarget","dispatchEvent","Event","bubbles","handleMouseOver","preventScroll","handleSearchOnKeyDown","preventDefault","listElement","querySelector","metaKey","ctrlKey","updatedSelectedValue","map","isMarked","handleOptionOnKeyDown","shiftKey","firstVisible","currentTarget","hasSelection","renderSelectedOption","jsx","Chip","tagLabel","variant","onClick","children","InputGroup","clsx","render","inputProps","jsxs","style","tabIndex","Tooltip","TooltipTrigger","TooltipContent","onKeyDown","role","autoComplete","onMouseOver","CheckIcon","IconButton","previous","onMouseDown","ArrowVerticalAnimated","pointingDown","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"Combobox.js","sources":["../../../../src/components/combobox/Combobox.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n type FC,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useAnimatedHeight } from \"../../hooks/useAnimatedHeight/useAnimatedHeight.js\";\nimport { useId } from \"../../hooks/useId/useId.js\";\nimport { useListNavigation } from \"../../hooks/useListNavigation/useListNavigation.js\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\nimport { Chip } from \"../chip/Chip.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CheckIcon } from \"../icon/icons/CheckIcon.js\";\nimport { ArrowVerticalAnimated } from \"../icon/icons/animated/ArrowVerticalAnimated.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport { Tooltip } from \"../tooltip/Tooltip.js\";\nimport { TooltipContent } from \"../tooltip/TooltipContent.js\";\nimport { TooltipTrigger } from \"../tooltip/TooltipTrigger.js\";\nimport type { ComboboxProps, ComboboxValuePair } from \"./types.js\";\n\nexport function getComboboxValuePair(\n item: string | ComboboxValuePair,\n): ComboboxValuePair {\n return typeof item === \"string\" ? { value: item, label: item } : item;\n}\n\n/**\n * @deprecated Bruk heller Select med `multiple` og `searchable` satt til\n * `true`. Combobox vil bli fjernet ved en senere oppdatering.\n */\nexport const Combobox: FC<ComboboxProps> = (props) => {\n const {\n \"data-size\": dataSize,\n id,\n placeholder,\n items,\n onChange,\n onFocus,\n onBlur,\n value,\n label,\n noMatchingOption,\n labelProps,\n helpLabel,\n errorLabel,\n width,\n name,\n className,\n invalid,\n description,\n hasTagHover,\n tooltip,\n } = props;\n const listId = useId(id || \"jkl-combobox\", { generateSuffix: !id });\n const labelId = `${listId}_label`;\n const buttonId = `${listId}_button`;\n const inputId = `${listId}_search-input`;\n\n const [selectedValue, setSelectedValue] = useState<\n Array<ComboboxValuePair>\n >(value || []);\n const [showMenu, setShowMenu] = useState<boolean>(false);\n const [searchValue, setSearchValue] = useState<string>(\"\");\n const [noResults, setNoResults] = useState(false);\n const [marked, setMarked] = useState<boolean>(false);\n\n const searchRef = useRef<HTMLInputElement>(null);\n const inputRef = useRef<HTMLDivElement>(null);\n const focusInsideRef = useRef(false);\n\n useEffect(() => {\n setSearchValue(\"\");\n if (showMenu && searchRef.current) {\n searchRef.current.focus();\n }\n }, [showMenu]);\n\n useEffect(() => {\n setSelectedValue((prev) => value || prev);\n }, [value]);\n\n // Funksjon for å stile valgt element\n const isSelected = (option: ValuePair) => {\n if (!selectedValue) {\n return false;\n }\n\n return selectedValue.some((value) => value.value === option.value);\n };\n\n // Fjerne ett eller flere valg\n const removeOption = useCallback(\n (option: string) => {\n return selectedValue.filter((value) => value.value !== option);\n },\n [selectedValue],\n );\n\n const onTagRemove = useCallback(\n (\n e:\n | React.MouseEvent<HTMLButtonElement, globalThis.MouseEvent>\n | React.KeyboardEvent<HTMLInputElement>,\n option: string,\n ) => {\n const newValue = removeOption(option);\n setSelectedValue(newValue);\n onChange({\n type: \"change\",\n target: { name, value: option, selectedOptions: newValue },\n });\n e.stopPropagation();\n\n if (newValue.length === 0) {\n setMarked(false);\n }\n },\n [removeOption, onChange, name],\n );\n\n // Håndtere valgt verdi i listen\n const onItemClick = useCallback(\n (option: string) => {\n let newValue: Array<ValuePair>;\n\n if (selectedValue.some((value) => value.value === option)) {\n newValue = removeOption(option);\n } else {\n const item = items.find((i) => i.value === option);\n newValue = [...selectedValue, item as ValuePair];\n }\n searchRef.current?.focus();\n setSelectedValue(newValue);\n onChange({\n type: \"change\",\n target: { name, value: option, selectedOptions: newValue },\n });\n },\n [selectedValue, onChange, name, removeOption, items],\n );\n\n // Funksjon for søk\n const onSearch = (e: {\n target: { value: React.SetStateAction<string> };\n }) => {\n searchRef.current?.focus();\n setShowMenu(true);\n setSearchValue(e.target.value);\n };\n\n const options = useMemo(() => {\n if (!searchValue) {\n return items;\n }\n\n const filteredOptions = items.filter(\n (option) =>\n option.label.toLowerCase().indexOf(searchValue.toLowerCase()) >=\n 0,\n );\n\n setNoResults(filteredOptions.length === 0);\n\n return filteredOptions;\n }, [searchValue, items]);\n\n // Det første elementet i listen skal være aktivt fram til brukeren klikker på noe annet\n const [activeDescendant, setActiveDescendant] = useState<\n string | undefined\n >(options[0]?.value ? `${listId}-${options[0]?.value}` : undefined);\n\n // Håndtere arrow-state\n const isPointingDown = !showMenu;\n\n // Lukk meny med ESC\n useEffect(() => {\n const handleEscape = (e: globalThis.KeyboardEvent) => {\n if (e.key === \"Escape\" && showMenu) {\n setShowMenu(false);\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", handleEscape);\n }\n return () => {\n if (typeof window !== \"undefined\" && showMenu) {\n window.removeEventListener(\"keydown\", handleEscape);\n }\n };\n }, [showMenu]);\n\n // Fokushåndtering\n const handleFocusPlacement = useCallback((isOpen: boolean) => {\n if (isOpen) {\n if (searchRef.current) {\n searchRef.current.focus();\n }\n } else {\n if (focusInsideRef.current && inputRef.current) {\n inputRef.current.focus();\n }\n }\n }, []);\n\n const handleFocus = useCallback(() => {\n if (!focusInsideRef.current) {\n if (onFocus) {\n onFocus({\n type: \"change\",\n target: {\n name,\n value: selectedValue?.[0].value || \"\",\n selectedOptions: selectedValue,\n },\n });\n }\n focusInsideRef.current = true;\n setShowMenu(true);\n }\n }, [onFocus, selectedValue, name]);\n\n const [dropdownRef] = useAnimatedHeight<HTMLDivElement>(showMenu, {\n onFirstVisible: handleFocusPlacement,\n onTransitionEnd: handleFocusPlacement,\n });\n\n useListNavigation({ ref: dropdownRef });\n\n const componentRootElementRef = useRef<HTMLDivElement>(null);\n\n const handleBlur = useCallback(\n (\n e: FocusEvent<\n HTMLDivElement | HTMLInputElement | HTMLButtonElement\n >,\n ) => {\n const componentRootElement = componentRootElementRef.current;\n const nextFocusIsInsideComponent = componentRootElement?.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInsideComponent) {\n setSearchValue(\"\");\n\n if (onBlur) {\n onBlur({\n type: \"blur\",\n target: {\n name,\n value: selectedValue?.[0]?.value || \"\",\n selectedOptions: selectedValue,\n },\n });\n inputRef.current?.dispatchEvent(\n new Event(\"focusout\", { bubbles: true }),\n );\n }\n focusInsideRef.current = false;\n setShowMenu(false);\n }\n },\n [onBlur, name, selectedValue],\n );\n\n const handleMouseOver = useCallback((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 // Tastaturnavigasjon\n const handleSearchOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n e.stopPropagation();\n const listElement = dropdownRef.current;\n if (listElement) {\n listElement\n .querySelector<HTMLButtonElement>('[role=\"option\"]')\n ?.focus();\n }\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setShowMenu(false);\n }\n\n if ((e.metaKey && e.key === \"a\") || (e.ctrlKey && e.key === \"a\")) {\n e.preventDefault();\n e.stopPropagation();\n const updatedSelectedValue = selectedValue.map((item) => ({\n ...item,\n isMarked: true,\n }));\n setMarked(true);\n setSelectedValue(updatedSelectedValue);\n } else if (e.key === \"Backspace\") {\n e.stopPropagation();\n setMarked(false);\n\n // Sjekk om selectedValue er markert\n const selectedValueIsMarked = selectedValue.some(\n (item) => item.isMarked,\n );\n\n if (selectedValueIsMarked) {\n const updatedSelectedValue = selectedValue.filter(\n (item) => !item.isMarked,\n );\n setSelectedValue(updatedSelectedValue);\n setSearchValue(\"\");\n } else if (selectedValue.length > 0 && searchValue === \"\") {\n // Hvis ingen items er markert, fjern siste valgte item\n onTagRemove(\n e,\n selectedValue[selectedValue.length - 1].value,\n );\n }\n }\n },\n [selectedValue, searchValue, dropdownRef, onTagRemove],\n );\n\n const handleOptionOnKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Tab\") {\n if (searchRef.current) {\n e.preventDefault();\n e.stopPropagation();\n\n if (e.shiftKey) {\n searchRef.current.focus();\n } else {\n setShowMenu(false);\n searchRef.current.focus();\n }\n }\n } else if (e.key === \"ArrowUp\") {\n if (dropdownRef.current && searchRef.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 searchRef.current\n ) {\n searchRef.current.focus();\n }\n }\n }\n },\n [dropdownRef],\n );\n\n const hasSelection = selectedValue.length >= 1;\n\n const renderSelectedOption = useCallback(\n (option: ComboboxValuePair) => (\n <Chip\n key={option.value}\n data-testid=\"jkl-chip\"\n aria-label={`Fjern ${option.tagLabel}`}\n className={`jkl-combobox__selected-option ${\n marked && \"jkl-combobox__selected-option--marked\"\n }`}\n variant=\"input\"\n onClick={(e) => {\n if (searchRef.current) {\n searchRef.current.focus();\n }\n onTagRemove(e, option.value);\n }}\n onBlur={handleBlur}\n >\n {option.tagLabel ? option.tagLabel : option.label}\n </Chip>\n ),\n [handleBlur, onTagRemove, marked],\n );\n\n return (\n <InputGroup\n label={label}\n id={inputId}\n ref={componentRootElementRef}\n data-testid=\"jkl-combobox\"\n data-size={dataSize}\n className={clsx(\"jkl-combobox\", className, {\n \"jkl-combobox--invalid\": !!errorLabel || invalid,\n \"jkl-combobox--menu-open\": showMenu,\n \"jkl-combobox--menu-closed\": !showMenu && hasSelection,\n })}\n labelProps={{\n id: labelId,\n ...labelProps,\n }}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n description={description}\n tooltip={tooltip}\n render={(inputProps) => (\n <div\n className={clsx(\"jkl-combobox__wrapper\", {\n \"jkl-combobox__wrapper--active-value\": hasSelection,\n })}\n style={{ width }}\n tabIndex={-1}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-invalid={!!errorLabel || invalid}\n >\n <div\n className=\"jkl-combobox__chips\"\n data-testid=\"jkl-combobox__chips\"\n >\n {selectedValue\n .map(getComboboxValuePair)\n .map((option) => {\n return hasTagHover ? (\n <Tooltip key={option.value}>\n <TooltipTrigger>\n {renderSelectedOption(option)}\n </TooltipTrigger>\n <TooltipContent>\n {option.label}\n </TooltipContent>\n </Tooltip>\n ) : (\n renderSelectedOption(option)\n );\n })}\n <input\n {...inputProps}\n className=\"jkl-combobox__search-input\"\n onChange={onSearch}\n data-testid=\"jkl-combobox__search-input\"\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleSearchOnKeyDown}\n value={searchValue}\n ref={searchRef}\n aria-controls={listId}\n role=\"combobox\"\n aria-autocomplete=\"list\"\n aria-expanded={showMenu}\n placeholder={\n selectedValue.length > 0 ? \"\" : placeholder\n }\n autoComplete=\"off\"\n />\n </div>\n\n <div\n className=\"jkl-combobox__menu\"\n // biome-ignore lint/a11y/useSemanticElements: Dette er en reimplementering av en liste\n role=\"listbox\"\n ref={dropdownRef}\n id={listId}\n aria-labelledby={labelId}\n aria-multiselectable=\"true\"\n aria-activedescendant={activeDescendant}\n onFocus={handleFocus}\n onBlur={handleBlur}\n tabIndex={-1}\n >\n {options.map((option, i) => (\n <button\n key={`${listId}-${option.value}`}\n type=\"button\"\n id={`${listId}__${option.value}`}\n aria-selected={isSelected(option)}\n // biome-ignore lint/a11y/useSemanticElements: Dette er en reimplementering av en liste\n role=\"option\"\n value={option.value}\n onBlur={handleBlur}\n className={`jkl-combobox__option ${\n isSelected(option) &&\n \"jkl-combobox__option--selected\"\n }`}\n data-testid=\"jkl-combobox__option\"\n data-testautoid={`jkl-combobox__option-${i}`}\n onFocus={handleFocus}\n onKeyDown={handleOptionOnKeyDown}\n onClick={(e) => {\n setActiveDescendant(\n `${listId}__${option.value}`,\n ); // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role#required_javascript_features\n e.stopPropagation();\n onItemClick(option.value);\n setSearchValue(\"\");\n }}\n onMouseOver={handleMouseOver}\n >\n {option.description ? (\n <span>\n {option.label}\n <span className=\"jkl-combobox__option-description\">\n {option.description}\n </span>\n </span>\n ) : (\n option.label\n )}\n {isSelected(option) ? (\n <span>\n <CheckIcon />{\" \"}\n </span>\n ) : null}\n </button>\n ))}\n {noResults && (\n <div className=\"jkl-combobox__no-option\">\n {noMatchingOption}\n </div>\n )}\n </div>\n <IconButton\n id={buttonId}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"jkl-text-input-action-button\"\n data-testid=\"jkl-combobox__button\"\n aria-label=\"Åpne meny\"\n aria-expanded={showMenu}\n aria-controls={listId}\n onClick={() => setShowMenu((previous) => !previous)}\n onMouseDown={(e) => {\n e.preventDefault();\n inputRef.current?.focus();\n }}\n >\n <ArrowVerticalAnimated pointingDown={isPointingDown} />\n </IconButton>\n </div>\n )}\n />\n );\n};\nCombobox.displayName = \"Combobox\";\n"],"names":["getComboboxValuePair","item","value","label","Combobox","props","dataSize","id","placeholder","items","onChange","onFocus","onBlur","noMatchingOption","labelProps","helpLabel","errorLabel","width","name","className","invalid","description","hasTagHover","tooltip","listId","useId","generateSuffix","labelId","buttonId","inputId","selectedValue","setSelectedValue","useState","showMenu","setShowMenu","searchValue","setSearchValue","noResults","setNoResults","marked","setMarked","searchRef","useRef","inputRef","focusInsideRef","useEffect","current","focus","prev","isSelected","option","some","removeOption","useCallback","filter","onTagRemove","e","newValue","type","target","selectedOptions","stopPropagation","length","onItemClick","find","i","onSearch","options","useMemo","filteredOptions","toLowerCase","indexOf","activeDescendant","setActiveDescendant","isPointingDown","handleEscape","key","window","addEventListener","removeEventListener","handleFocusPlacement","isOpen","handleFocus","dropdownRef","useAnimatedHeight","onFirstVisible","onTransitionEnd","useListNavigation","ref","componentRootElementRef","handleBlur","contains","relatedTarget","dispatchEvent","Event","bubbles","handleMouseOver","preventScroll","handleSearchOnKeyDown","preventDefault","listElement","querySelector","metaKey","ctrlKey","updatedSelectedValue","map","isMarked","handleOptionOnKeyDown","shiftKey","firstVisible","currentTarget","hasSelection","renderSelectedOption","jsx","Chip","tagLabel","variant","onClick","children","InputGroup","clsx","render","inputProps","jsxs","style","tabIndex","Tooltip","TooltipTrigger","TooltipContent","onKeyDown","role","autoComplete","onMouseOver","CheckIcon","IconButton","previous","onMouseDown","ArrowVerticalAnimated","pointingDown","displayName"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsx as t}from"react/jsx-runtime";import{c as e}from"../../../clsx-BeLtu-UY.js";import{forwardRef as n}from"react";import{SlotComponent as i}from"../../utilities/polymorphism/SlotComponent.js";import{isResponsive as r}from"./types.js";const o=n(function(n,r){const{asChild:o,alignItems:l,alignContent:a,as:m="div",center:c=!1,className:p,direction:f="row",fill:$,gap:x="m",inline:u,justifyContent:g,layout:j={},textAlign:d,wrap:w="nowrap",...y}=n,C=o?i:m,v=s(x).flatMap(([t,e])=>{const[n,i=n]=e.trim().split(" ");return[`screen-${t}-row-gap-${n}`,`screen-${t}-col-gap-${i}`]}),h=s(j).map(([t,e])=>`screen-${t}-${e}`);return t(C,{...y,className:e("jkl-flex",!l||`align-items-${l}`,!a||`align-content-${a}`,!c||`center-${!0===c?"2xl":c}`,!$||"fill",!u||"inline-flex",!g||`justify-content-${g}`,!d||`text-align-${d}`,!w||`flex-wrap-${w}`,!f||`flex-direction-${f}`,...v,...h,p),ref:r})});function s(t){return r(t)?Object.entries(t).filter(([,t])=>void 0!==t):[["small",t]]}export{o as Flex};
1
+ import{jsx as t}from"react/jsx-runtime";import{c as r}from"../../../clsx-BeLtu-UY.js";import{forwardRef as n}from"react";import{SlotComponent as e}from"../../utilities/polymorphism/SlotComponent.js";const i=n(function(n,i){const{asChild:s,alignItems:o,alignContent:a,as:l="div",className:p,direction:c,gap:m,justifyContent:f,wrap:g,style:j,...u}=n;return t(s?e:l,{style:{"--wrap":!0===g?"wrap":!1===g?"nowrap":"reverse"===g?"wrap-reverse":g,"--gap":function(t){if(t?.toString().includes(" ")){const[r,n]=t.toString().trim().split(" ");return`var(--jkl-spacing-${r}) var(--jkl-spacing-${n})`}if(t)return`var(--jkl-spacing-${t})`}(m),"--align-items":o,"--align-content":a,"--justify-content":f,"--flex-direction":c,...j},...u,className:r("jkl-flex",p),ref:i})});export{i as Flex};
2
2
  //# sourceMappingURL=Flex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Flex.js","sources":["../../../../src/components/flex/Flex.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { forwardRef } from \"react\";\nimport { SlotComponent } from \"../../utilities/index.js\";\nimport type { PolymorphicRef } from \"../../utilities/polymorphism/polymorphism.js\";\nimport {\n type Breakpoint,\n type FlexComponent,\n type FlexProps,\n type Responsive,\n isResponsive,\n} from \"./types.js\";\n\nexport const Flex = forwardRef(function Flex<\n ElementType extends React.ElementType = \"div\",\n>(props: FlexProps<ElementType>, ref?: PolymorphicRef<ElementType>) {\n const {\n asChild,\n alignItems,\n alignContent,\n as = \"div\",\n center = false,\n className,\n direction = \"row\",\n fill,\n gap = \"m\",\n inline,\n justifyContent,\n layout = {},\n textAlign,\n wrap = \"nowrap\",\n ...rest\n } = props;\n\n const Tag = asChild ? SlotComponent : as;\n const gaps = toObjectEntries(gap).flatMap(([breakpoint, gap]) => {\n const [row, col = row] = gap.trim().split(\" \");\n return [\n `screen-${breakpoint}-row-gap-${row}`,\n `screen-${breakpoint}-col-gap-${col}`,\n ];\n });\n const layouts = toObjectEntries(layout).map(\n ([breakpoint, layout]) => `screen-${breakpoint}-${layout}`, // Convert to number to convert 2.10 to 2.1 and false to 0\n );\n\n return (\n <Tag\n {...rest}\n className={clsx(\n \"jkl-flex\",\n !alignItems || `align-items-${alignItems}`,\n !alignContent || `align-content-${alignContent}`,\n !center || `center-${center === true ? \"2xl\" : center}`,\n !fill || \"fill\",\n !inline || \"inline-flex\",\n !justifyContent || `justify-content-${justifyContent}`,\n !textAlign || `text-align-${textAlign}`,\n !wrap || `flex-wrap-${wrap}`,\n !direction || `flex-direction-${direction}`,\n ...gaps,\n ...layouts,\n className,\n )}\n ref={ref}\n />\n );\n}) as FlexComponent; // Needed to tell Typescript this does not return ReactNode but acutally JSX.Element\n\n/**\n * Gjør en enkeltstående eller responsiv verdi om til et nøstet array,\n * der hvert indre array inneholder et breakpoint med tilhørende verdi.\n * @example `{ small: \"12\", large: \"64\" }` -> `[[\"small\", \"12\"], [\"large\", \"64\"]]`\n * @example `\"24\"` -> `[[\"small\", \"24\"]]`\n * @param value enkeltstående eller responsiv verdi\n * @returns nøstet array med breakpoints og verdier\n */\nfunction toObjectEntries<T>(value: T | Responsive<T>): [Breakpoint, T][] {\n if (isResponsive(value)) {\n return (Object.entries(value) as [Breakpoint, T][]).filter(\n ([, v]) => v !== undefined,\n );\n }\n\n return [[\"small\", value]];\n}\n"],"names":["Flex","forwardRef","props","ref","asChild","alignItems","alignContent","as","center","className","direction","fill","gap","inline","justifyContent","layout","textAlign","wrap","rest","Tag","SlotComponent","gaps","toObjectEntries","flatMap","breakpoint","row","col","trim","split","layouts","map","jsx","clsx","value","isResponsive","Object","entries","filter","v"],"mappings":"iPAYO,MAAMA,EAAOC,EAAW,SAE7BC,EAA+BC,GAC7B,MACIC,QAAAA,EACAC,WAAAA,EACAC,aAAAA,EACAC,GAAAA,EAAK,MACLC,OAAAA,GAAS,EACTC,UAAAA,EACAC,UAAAA,EAAY,MACZC,KAAAA,EACAC,IAAAA,EAAM,IACNC,OAAAA,EACAC,eAAAA,EACAC,OAAAA,EAAS,CAAA,EACTC,UAAAA,EACAC,KAAAA,EAAO,YACJC,GACHhB,EAEEiB,EAAMf,EAAUgB,EAAgBb,EAChCc,EAAOC,EAAgBV,GAAKW,QAAQ,EAAEC,EAAYZ,MACpD,MAAOa,EAAKC,EAAMD,GAAOb,EAAIe,OAAOC,MAAM,KAC1C,MAAO,CACH,UAAUJ,aAAsBC,IAChC,UAAUD,aAAsBE,OAGlCG,EAAUP,EAAgBP,GAAQe,IACpC,EAAEN,EAAYT,KAAY,UAAUS,KAAcT,KAGtD,OACIgB,EAACZ,EAAA,IACOD,EACJT,UAAWuB,EACP,YACC3B,GAAc,eAAeA,KAC7BC,GAAgB,iBAAiBA,KACjCE,GAAU,WAAqB,IAAXA,EAAkB,MAAQA,KAC9CG,GAAQ,QACRE,GAAU,eACVC,GAAkB,mBAAmBA,KACrCE,GAAa,cAAcA,KAC3BC,GAAQ,aAAaA,KACrBP,GAAa,kBAAkBA,OAC7BW,KACAQ,EACHpB,GAEJN,IAAAA,GAGZ,GAUA,SAASmB,EAAmBW,GACxB,OAAIC,EAAaD,GACLE,OAAOC,QAAQH,GAA6BI,OAChD,EAAC,CAAGC,UAAa,IAANA,GAIZ,CAAC,CAAC,QAASL,GACtB"}
1
+ {"version":3,"file":"Flex.js","sources":["../../../../src/components/flex/Flex.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { type CSSProperties, forwardRef } from \"react\";\nimport { SlotComponent } from \"../../utilities/index.js\";\nimport type { PolymorphicRef } from \"../../utilities/polymorphism/polymorphism.js\";\nimport type { FlexComponent, FlexProps } from \"./types.js\";\n\nexport const Flex = forwardRef(function Flex<\n ElementType extends React.ElementType = \"div\",\n>(props: FlexProps<ElementType>, ref?: PolymorphicRef<ElementType>) {\n const {\n asChild,\n alignItems,\n alignContent,\n as = \"div\",\n className,\n direction,\n gap,\n justifyContent,\n wrap,\n style,\n ...rest\n } = props;\n\n const wrapping =\n wrap === true\n ? \"wrap\"\n : wrap === false\n ? \"nowrap\"\n : wrap === \"reverse\"\n ? \"wrap-reverse\"\n : wrap;\n\n function getGapValue(gap: FlexProps[\"gap\"]) {\n if (gap?.toString().includes(\" \")) {\n const [rowGap, columnGap] = gap.toString().trim().split(\" \");\n return `var(--jkl-spacing-${rowGap}) var(--jkl-spacing-${columnGap})`;\n }\n if (gap) {\n return `var(--jkl-spacing-${gap})`;\n }\n return undefined;\n }\n\n const Tag = asChild ? SlotComponent : as;\n\n return (\n <Tag\n style={\n {\n \"--wrap\": wrapping,\n \"--gap\": getGapValue(gap),\n \"--align-items\": alignItems,\n \"--align-content\": alignContent,\n \"--justify-content\": justifyContent,\n \"--flex-direction\": direction,\n ...style,\n } as CSSProperties\n }\n {...rest}\n className={clsx(\"jkl-flex\", className)}\n ref={ref}\n />\n );\n}) as FlexComponent;\n"],"names":["Flex","forwardRef","props","ref","asChild","alignItems","alignContent","as","className","direction","gap","justifyContent","wrap","style","rest","jsx","SlotComponent","toString","includes","rowGap","columnGap","trim","split","getGapValue","clsx"],"mappings":"uMAMO,MAAMA,EAAOC,EAAW,SAE7BC,EAA+BC,GAC7B,MACIC,QAAAA,EACAC,WAAAA,EACAC,aAAAA,EACAC,GAAAA,EAAK,MACLC,UAAAA,EACAC,UAAAA,EACAC,IAAAA,EACAC,eAAAA,EACAC,KAAAA,EACAC,MAAAA,KACGC,GACHZ,EAwBJ,OACIa,EAHQX,EAAUY,EAAgBT,EAGjC,CACGM,MACI,CACI,UAzBH,IAATD,EACM,QACS,IAATA,EACE,SACS,YAATA,EACE,eACAA,EAoBE,QAlBhB,SAAqBF,GACjB,GAAIA,GAAKO,WAAWC,SAAS,KAAM,CAC/B,MAAOC,EAAQC,GAAaV,EAAIO,WAAWI,OAAOC,MAAM,KACxD,MAAO,qBAAqBH,wBAA6BC,IAC7D,CACA,GAAIV,EACA,MAAO,qBAAqBA,IAGpC,CASyBa,CAAYb,GACrB,gBAAiBL,EACjB,kBAAmBC,EACnB,oBAAqBK,EACrB,mBAAoBF,KACjBI,MAGPC,EACJN,UAAWgB,EAAK,WAAYhB,GAC5BL,IAAAA,GAGZ"}
@@ -1,33 +1,43 @@
1
1
  import { default as React } from 'react';
2
- import { AsChildProps } from '../../utilities/polymorphism/as-child.js';
3
- import { PolymorphicPropsWithRef } from '../../utilities/polymorphism/polymorphism.js';
4
- export declare const SEMANTIC_SPACING: readonly ["none", "2xs", "xs", "s", "m", "l", "xl", "2xl"];
5
- export declare const STATIC_SPACING: readonly ["0", "2", "4", "8", "12", "16", "20", "24", "28", "32", "40", "48", "56", "64", "72", "80", "104", "168"];
6
- declare const BREAKPOINTS: readonly ["small", "medium", "large", "xl"];
7
- export type SemanticSpacing = (typeof SEMANTIC_SPACING)[number];
8
- export type StaticSpacing = (typeof STATIC_SPACING)[number];
9
- export type Breakpoint = (typeof BREAKPOINTS)[number];
10
- export type Responsive<T> = Partial<Record<Breakpoint, T>>;
11
- export declare function isResponsive<T>(value: unknown): value is Responsive<T>;
12
- export declare const LAYOUTS: readonly ["auto", "1", "2", "3", "4", "6", "4.8", "8.4", "2.10", "10.2", "3.9", "9.3", "5.7", "7.5"];
13
- export type Layout = (typeof LAYOUTS)[number];
14
- export type Center = "m" | "l" | "xl" | "2xl" | boolean;
15
- export type DynamicGap = `${SemanticSpacing}` | `${SemanticSpacing} ${SemanticSpacing}`;
16
- export type StaticGap = `${StaticSpacing}` | `${StaticSpacing} ${StaticSpacing}`;
17
- export type Gap = DynamicGap | StaticGap;
2
+ import { AsChildProps, PolymorphicPropsWithRef } from '../../utilities/index.js';
3
+ declare const staticSpacingTokens: {
4
+ 0: string;
5
+ 2: string;
6
+ 4: string;
7
+ 8: string;
8
+ 12: string;
9
+ 16: string;
10
+ 24: string;
11
+ 32: string;
12
+ 40: string;
13
+ 64: string;
14
+ 104: string;
15
+ 168: string;
16
+ none: string;
17
+ "2xs": string;
18
+ xs: string;
19
+ s: string;
20
+ m: string;
21
+ l: string;
22
+ xl: string;
23
+ "2xl": string;
24
+ };
25
+ type Spacing = keyof typeof staticSpacingTokens;
26
+ type SpacingValue = `${Spacing}`;
27
+ export type Gap = Spacing | SpacingValue | `${SpacingValue} ${SpacingValue}`;
18
28
  type FlexBaseProps = {
19
29
  alignItems?: "normal" | "start" | "center" | "end" | "baseline" | "stretch";
20
30
  alignContent?: "normal" | "start" | "center" | "end" | "stretch" | "baseline" | "space-between" | "space-around" | "space-evenly";
21
- center?: Center;
22
- direction?: "row" | "column" | "row-reverse" | "column-reverse";
23
- fill?: boolean;
24
- gap?: Gap | Responsive<Gap>;
25
- inline?: boolean;
26
- textAlign?: "left" | "right" | "center";
31
+ direction?: "row" | "row-reverse" | "column" | "column-reverse";
32
+ gap?: Gap;
27
33
  justifyContent?: "normal" | "start" | "center" | "end" | "space-between" | "space-around" | "space-evenly";
28
- layout?: Layout | Responsive<Layout>;
29
- wrap?: "wrap" | "nowrap" | "reverse";
34
+ /**
35
+ * Om elementene skal brytes over flere linjer.
36
+ * `true`/`false` setter `wrap`/`nowrap`, `"reverse"` som kortform for
37
+ * `"wrap-reverse"`.
38
+ */
39
+ wrap?: boolean | "wrap" | "nowrap" | "reverse";
30
40
  };
31
- export type FlexProps<As extends React.ElementType = "div"> = PolymorphicPropsWithRef<As, FlexBaseProps>;
32
- export type FlexComponent = <ElementType extends React.ElementType = "div">(props: FlexProps<ElementType> & AsChildProps) => React.ReactElement | null;
41
+ export type FlexProps<As extends React.ElementType = "div"> = PolymorphicPropsWithRef<As, FlexBaseProps> & AsChildProps;
42
+ export type FlexComponent = <ElementType extends React.ElementType = "div">(props: FlexProps<ElementType>) => React.ReactElement | null;
33
43
  export {};
@@ -1,2 +1,2 @@
1
- import"react";const s=["none","2xs","xs","s","m","l","xl","2xl"],e=["0","2","4","8","12","16","20","24","28","32","40","48","56","64","72","80","104","168"],t=["small","medium","large","xl"];function n(s){if("object"!=typeof s||null===s||Array.isArray(s))return!1;const e=Object.keys(s);return 0===e.length||t.includes(e[0])}const r=["auto","1","2","3","4","6","4.8","8.4","2.10","10.2","3.9","9.3","5.7","7.5"];export{r as LAYOUTS,s as SEMANTIC_SPACING,e as STATIC_SPACING,n as isResponsive};
1
+ import o from"../../tokens.js";o.spacing;
2
2
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../../../src/components/flex/types.ts"],"sourcesContent":["import React from \"react\";\nimport type { AsChildProps } from \"../../utilities/polymorphism/as-child.js\";\nimport type { PolymorphicPropsWithRef } from \"../../utilities/polymorphism/polymorphism.js\";\n\nexport const SEMANTIC_SPACING = [\n \"none\",\n \"2xs\",\n \"xs\",\n \"s\",\n \"m\",\n \"l\",\n \"xl\",\n \"2xl\",\n] as const;\n\nexport const STATIC_SPACING = [\n \"0\",\n \"2\",\n \"4\",\n \"8\",\n \"12\",\n \"16\",\n \"20\",\n \"24\",\n \"28\",\n \"32\",\n \"40\",\n \"48\",\n \"56\",\n \"64\",\n \"72\",\n \"80\",\n \"104\",\n \"168\",\n] as const;\n\nconst BREAKPOINTS = [\"small\", \"medium\", \"large\", \"xl\"] as const;\n\nexport type SemanticSpacing = (typeof SEMANTIC_SPACING)[number];\nexport type StaticSpacing = (typeof STATIC_SPACING)[number];\nexport type Breakpoint = (typeof BREAKPOINTS)[number];\n\nexport type Responsive<T> = Partial<Record<Breakpoint, T>>;\nexport function isResponsive<T>(value: unknown): value is Responsive<T> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const keys = Object.keys(value);\n return keys.length === 0 || BREAKPOINTS.includes(keys[0] as Breakpoint);\n}\n\nexport const LAYOUTS = [\n \"auto\",\n \"1\",\n \"2\",\n \"3\",\n \"4\",\n \"6\",\n \"4.8\",\n \"8.4\",\n \"2.10\",\n \"10.2\",\n \"3.9\",\n \"9.3\",\n \"5.7\",\n \"7.5\",\n] as const;\n\nexport type Layout = (typeof LAYOUTS)[number];\nexport type Center = \"m\" | \"l\" | \"xl\" | \"2xl\" | boolean;\n\nexport type DynamicGap =\n | `${SemanticSpacing}`\n | `${SemanticSpacing} ${SemanticSpacing}`;\nexport type StaticGap =\n | `${StaticSpacing}`\n | `${StaticSpacing} ${StaticSpacing}`;\nexport type Gap = DynamicGap | StaticGap;\n\ntype FlexBaseProps = {\n alignItems?: \"normal\" | \"start\" | \"center\" | \"end\" | \"baseline\" | \"stretch\";\n alignContent?:\n | \"normal\"\n | \"start\"\n | \"center\"\n | \"end\"\n | \"stretch\"\n | \"baseline\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\n center?: Center;\n direction?: \"row\" | \"column\" | \"row-reverse\" | \"column-reverse\";\n fill?: boolean;\n gap?: Gap | Responsive<Gap>;\n inline?: boolean;\n textAlign?: \"left\" | \"right\" | \"center\";\n justifyContent?:\n | \"normal\"\n | \"start\"\n | \"center\"\n | \"end\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\n layout?: Layout | Responsive<Layout>;\n wrap?: \"wrap\" | \"nowrap\" | \"reverse\";\n};\n\nexport type FlexProps<As extends React.ElementType = \"div\"> =\n PolymorphicPropsWithRef<As, FlexBaseProps>;\n\nexport type FlexComponent = <ElementType extends React.ElementType = \"div\">(\n props: FlexProps<ElementType> & AsChildProps,\n) => React.ReactElement | null;\n"],"names":["SEMANTIC_SPACING","STATIC_SPACING","BREAKPOINTS","isResponsive","value","Array","isArray","keys","Object","length","includes","LAYOUTS"],"mappings":"cAIO,MAAMA,EAAmB,CAC5B,OACA,MACA,KACA,IACA,IACA,IACA,KACA,OAGSC,EAAiB,CAC1B,IACA,IACA,IACA,IACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,MACA,OAGEC,EAAc,CAAC,QAAS,SAAU,QAAS,MAO1C,SAASC,EAAgBC,GAC5B,GAAqB,iBAAVA,GAAgC,OAAVA,GAAkBC,MAAMC,QAAQF,GAC7D,OAAO,EAEX,MAAMG,EAAOC,OAAOD,KAAKH,GACzB,OAAuB,IAAhBG,EAAKE,QAAgBP,EAAYQ,SAASH,EAAK,GAC1D,CAEO,MAAMI,EAAU,CACnB,OACA,IACA,IACA,IACA,IACA,IACA,MACA,MACA,OACA,OACA,MACA,MACA,MACA"}
1
+ {"version":3,"file":"types.js","sources":["../../../../src/components/flex/types.ts"],"sourcesContent":["import type React from \"react\";\nimport * as tokens from \"../../tokens.js\";\nimport type {\n AsChildProps,\n PolymorphicPropsWithRef,\n} from \"../../utilities/index.js\";\n\nconst staticSpacingTokens = tokens.default.spacing;\n\ntype Spacing = keyof typeof staticSpacingTokens;\ntype SpacingValue = `${Spacing}`;\n\nexport type Gap = Spacing | SpacingValue | `${SpacingValue} ${SpacingValue}`;\n\ntype FlexBaseProps = {\n alignItems?: \"normal\" | \"start\" | \"center\" | \"end\" | \"baseline\" | \"stretch\";\n alignContent?:\n | \"normal\"\n | \"start\"\n | \"center\"\n | \"end\"\n | \"stretch\"\n | \"baseline\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\n direction?: \"row\" | \"row-reverse\" | \"column\" | \"column-reverse\";\n gap?: Gap;\n justifyContent?:\n | \"normal\"\n | \"start\"\n | \"center\"\n | \"end\"\n | \"space-between\"\n | \"space-around\"\n | \"space-evenly\";\n /**\n * Om elementene skal brytes over flere linjer.\n * `true`/`false` setter `wrap`/`nowrap`, `\"reverse\"` som kortform for\n * `\"wrap-reverse\"`.\n */\n wrap?: boolean | \"wrap\" | \"nowrap\" | \"reverse\";\n};\n\nexport type FlexProps<As extends React.ElementType = \"div\"> =\n PolymorphicPropsWithRef<As, FlexBaseProps> & AsChildProps;\n\n// Nødvendig for å fortelle TypeScript at dette ikke returnerer ReactNode, men JSX.Element\nexport type FlexComponent = <ElementType extends React.ElementType = \"div\">(\n props: FlexProps<ElementType>,\n) => React.ReactElement | null;\n"],"names":["tokens.default","spacing"],"mappings":"+BAO4BA,EAAeC"}
@@ -1,2 +1,2 @@
1
- import{jsxs as e,jsx as s}from"react/jsx-runtime";import{c as a}from"../../../clsx-BeLtu-UY.js";import{forwardRef as m}from"react";import{useElementDimensions as i}from"../../hooks/useElementDimensions/useElementDimensions.js";import{useImageLoadingStatus as o}from"./useImageLoadingStatus.js";import{mergeRefs as t}from"../../utilities/mergeRefs.js";import"../../utilities/polymorphism/SlotComponent.js";const r=m(({className:m,placeholder:r,alt:l,...n},g)=>{const[c,d]=o(),[p,j]=i(400),f=t(g,c);return e("div",{ref:p,className:a("jkl-image",m,{"jkl-image--loading":!d}),children:[s("img",{className:"jkl-image__placeholder",alt:d?"":l,src:r||n.src}),s("img",{alt:l,className:"jkl-image__image","data-testid":"jkl-image__image",ref:f,sizes:`${j.width}px`,decoding:"async",loading:"lazy",...n})]})});r.displayName="Image";export{r as Image};
1
+ import{jsxs as e,jsx as s}from"react/jsx-runtime";import{c as a}from"../../../clsx-BeLtu-UY.js";import{forwardRef as m}from"react";import{useElementDimensions as i}from"../../hooks/useElementDimensions/useElementDimensions.js";import{mergeRefs as o}from"../../utilities/mergeRefs.js";import"../../utilities/polymorphism/SlotComponent.js";import{useImageLoadingStatus as t}from"./useImageLoadingStatus.js";const r=m(({className:m,placeholder:r,alt:l,...n},g)=>{const[c,d]=t(),[p,j]=i(400),f=o(g,c);return e("div",{ref:p,className:a("jkl-image",m,{"jkl-image--loading":!d}),children:[s("img",{className:"jkl-image__placeholder",alt:d?"":l,src:r||n.src}),s("img",{alt:l,className:"jkl-image__image","data-testid":"jkl-image__image",ref:f,sizes:`${j.width}px`,decoding:"async",loading:"lazy",...n})]})});r.displayName="Image";export{r as Image};
2
2
  //# sourceMappingURL=Image.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Image.js","sources":["../../../../src/components/image/Image.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { forwardRef } from \"react\";\nimport { useElementDimensions } from \"../../hooks/useElementDimensions/useElementDimensions.js\";\nimport { useImageLoadingStatus } from \"./useImageLoadingStatus.js\";\nimport { mergeRefs } from \"../../utilities/index.js\";\nimport type { ImageProps } from \"./types.js\";\n\nexport const Image = forwardRef<HTMLImageElement, ImageProps>(\n ({ className, placeholder, alt, ...imageProperties }, ref) => {\n const [imageRef, imageLoaded] = useImageLoadingStatus();\n const [containerRef, dimensions] =\n useElementDimensions<HTMLDivElement>(400);\n\n const mergedImageRef = mergeRefs(ref, imageRef);\n\n return (\n <div\n ref={containerRef}\n className={clsx(\"jkl-image\", className, {\n \"jkl-image--loading\": !imageLoaded,\n })}\n >\n {/* Placeholder er bevisst uten loading og decoding for å vises umiddelbart */}\n <img\n className=\"jkl-image__placeholder\"\n alt={imageLoaded ? \"\" : alt}\n src={placeholder || imageProperties.src}\n />\n {/* biome-ignore lint/a11y/useAltText: Den har da vitterlig en alt-attributt? */}\n <img\n alt={alt}\n className=\"jkl-image__image\"\n data-testid=\"jkl-image__image\"\n ref={mergedImageRef}\n sizes={`${dimensions.width}px`}\n decoding=\"async\"\n loading=\"lazy\"\n {...imageProperties}\n />\n </div>\n );\n },\n);\n\nImage.displayName = \"Image\";\n"],"names":["Image","forwardRef","className","placeholder","alt","imageProperties","ref","imageRef","imageLoaded","useImageLoadingStatus","containerRef","dimensions","useElementDimensions","mergedImageRef","mergeRefs","jsxs","clsx","children","jsx","src","sizes","width","decoding","loading","displayName"],"mappings":"qZAOO,MAAMA,EAAQC,EACjB,EAAGC,UAAAA,EAAWC,YAAAA,EAAaC,IAAAA,KAAQC,GAAmBC,KAClD,MAAOC,EAAUC,GAAeC,KACzBC,EAAcC,GACjBC,EAAqC,KAEnCC,EAAiBC,EAAUR,EAAKC,GAEtC,OACIQ,EAAC,MAAA,CACGT,IAAKI,EACLR,UAAWc,EAAK,YAAad,EAAW,CACpC,sBAAuBM,IAI3BS,SAAA,CAAAC,EAAC,MAAA,CACGhB,UAAU,yBACVE,IAAKI,EAAc,GAAKJ,EACxBe,IAAKhB,GAAeE,EAAgBc,MAGxCD,EAAC,MAAA,CACGd,IAAAA,EACAF,UAAU,mBACV,cAAY,mBACZI,IAAKO,EACLO,MAAO,GAAGT,EAAWU,UACrBC,SAAS,QACTC,QAAQ,UACJlB,SAOxBL,EAAMwB,YAAc"}
1
+ {"version":3,"file":"Image.js","sources":["../../../../src/components/image/Image.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { forwardRef } from \"react\";\nimport { useElementDimensions } from \"../../hooks/useElementDimensions/useElementDimensions.js\";\nimport { mergeRefs } from \"../../utilities/index.js\";\nimport type { ImageProps } from \"./types.js\";\nimport { useImageLoadingStatus } from \"./useImageLoadingStatus.js\";\n\nexport const Image = forwardRef<HTMLImageElement, ImageProps>(\n ({ className, placeholder, alt, ...imageProperties }, ref) => {\n const [imageRef, imageLoaded] = useImageLoadingStatus();\n const [containerRef, dimensions] =\n useElementDimensions<HTMLDivElement>(400);\n\n const mergedImageRef = mergeRefs(ref, imageRef);\n\n return (\n <div\n ref={containerRef}\n className={clsx(\"jkl-image\", className, {\n \"jkl-image--loading\": !imageLoaded,\n })}\n >\n {/* Placeholder er bevisst uten loading og decoding for å vises umiddelbart */}\n <img\n className=\"jkl-image__placeholder\"\n alt={imageLoaded ? \"\" : alt}\n src={placeholder || imageProperties.src}\n />\n {/* biome-ignore lint/a11y/useAltText: Den har da vitterlig en alt-attributt? */}\n <img\n alt={alt}\n className=\"jkl-image__image\"\n data-testid=\"jkl-image__image\"\n ref={mergedImageRef}\n sizes={`${dimensions.width}px`}\n decoding=\"async\"\n loading=\"lazy\"\n {...imageProperties}\n />\n </div>\n );\n },\n);\n\nImage.displayName = \"Image\";\n"],"names":["Image","forwardRef","className","placeholder","alt","imageProperties","ref","imageRef","imageLoaded","useImageLoadingStatus","containerRef","dimensions","useElementDimensions","mergedImageRef","mergeRefs","jsxs","clsx","children","jsx","src","sizes","width","decoding","loading","displayName"],"mappings":"qZAOO,MAAMA,EAAQC,EACjB,EAAGC,UAAAA,EAAWC,YAAAA,EAAaC,IAAAA,KAAQC,GAAmBC,KAClD,MAAOC,EAAUC,GAAeC,KACzBC,EAAcC,GACjBC,EAAqC,KAEnCC,EAAiBC,EAAUR,EAAKC,GAEtC,OACIQ,EAAC,MAAA,CACGT,IAAKI,EACLR,UAAWc,EAAK,YAAad,EAAW,CACpC,sBAAuBM,IAI3BS,SAAA,CAAAC,EAAC,MAAA,CACGhB,UAAU,yBACVE,IAAKI,EAAc,GAAKJ,EACxBe,IAAKhB,GAAeE,EAAgBc,MAGxCD,EAAC,MAAA,CACGd,IAAAA,EACAF,UAAU,mBACV,cAAY,mBACZI,IAAKO,EACLO,MAAO,GAAGT,EAAWU,UACrBC,SAAS,QACTC,QAAQ,UACJlB,SAOxBL,EAAMwB,YAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"NumberInput.js","sources":["../../../../src/components/number-input/NumberInput.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, {\n type ComponentType,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport { mergeRefs } from \"../../utilities/mergeRefs.js\";\nimport { MinusIcon, PlusIcon } from \"../icon/index.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport type { NumberInputProps } from \"./types.js\";\n\ntype NumberInputValue = string | number | readonly string[] | undefined;\n\ntype StepDirection = \"increment\" | \"decrement\";\n\nconst stepperConfig: Record<\n StepDirection,\n { label: string; Icon: ComponentType }\n> = {\n decrement: { label: \"Senk verdien\", Icon: MinusIcon },\n increment: { label: \"Øk verdien\", Icon: PlusIcon },\n};\n\nfunction toNumeric(value: NumberInputValue): number {\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\" && value.trim() !== \"\") {\n return Number(value);\n }\n return Number.NaN;\n}\n\ntype StepperButtonProps = {\n direction: StepDirection;\n disabled: boolean;\n onClick: () => void;\n};\n\nfunction StepperButton({ direction, disabled, onClick }: StepperButtonProps) {\n const { label, Icon } = stepperConfig[direction];\n\n return (\n <button\n type=\"button\"\n className=\"jkl-button jkl-button--ghost\"\n aria-label={label}\n data-direction={direction}\n onPointerDown={(event) => event.preventDefault()}\n onClick={onClick}\n disabled={disabled}\n >\n <span aria-hidden=\"true\">\n <Icon />\n </span>\n </button>\n );\n}\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n (props, ref) => {\n const {\n \"data-size\": dataSize,\n \"data-testautoid\": testAutoId,\n \"data-testid\": dataTestId,\n align = \"left\",\n id,\n label,\n className,\n style,\n errorLabel,\n helpLabel,\n inputClassName,\n labelProps,\n supportLabelProps,\n stepper = false,\n tooltip,\n description,\n width,\n onChange,\n ...rest\n } = props;\n const internalRef = useRef<HTMLInputElement>(null);\n const mergedRef = mergeRefs(internalRef, ref);\n const [uncontrolledValue, setUncontrolledValue] =\n useState<NumberInputValue>(rest.defaultValue);\n\n // I kontrollert bruk må vi lese direkte fra `value` for at disabled-\n // state på stepper-knappene skal følge prop-en i samme render. Bruker\n // intern state som fallback for ukontrollert bruk.\n const effectiveValue =\n rest.value !== undefined ? rest.value : uncontrolledValue;\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (rest.value === undefined) {\n setUncontrolledValue(event.target.value);\n }\n onChange?.(event);\n };\n\n const numericValue = toNumeric(effectiveValue);\n const minNumeric =\n rest.min !== undefined ? Number(rest.min) : Number.NaN;\n const maxNumeric =\n rest.max !== undefined ? Number(rest.max) : Number.NaN;\n const isAtOrBelowMin =\n Number.isFinite(numericValue) &&\n Number.isFinite(minNumeric) &&\n numericValue <= minNumeric;\n const isAtOrAboveMax =\n Number.isFinite(numericValue) &&\n Number.isFinite(maxNumeric) &&\n numericValue >= maxNumeric;\n\n const inputWrapperStyle =\n style || width\n ? {\n ...style,\n ...(width ? { width } : undefined),\n }\n : undefined;\n const inputGroupProps = {\n id,\n label,\n errorLabel,\n helpLabel,\n labelProps,\n supportLabelProps,\n tooltip,\n description,\n };\n\n const triggerStep = (direction: StepDirection) => {\n const input = internalRef.current;\n\n if (!input || input.disabled || input.readOnly) {\n return;\n }\n\n const previousValue = input.value;\n input.focus();\n\n try {\n if (direction === \"increment\") {\n input.stepUp();\n } else {\n input.stepDown();\n }\n } catch {\n return;\n }\n\n if (input.value === previousValue) {\n return;\n }\n\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n\n const stepperDisabled = rest.disabled || rest.readOnly;\n\n return (\n <InputGroup\n {...inputGroupProps}\n className={clsx(className, \"jkl-number-input\")}\n data-size={dataSize}\n data-testid={dataTestId ?? \"jkl-number-input\"}\n render={(inputProps) => (\n <div\n className={clsx(\"jkl-number-input__wrapper\", {\n \"jkl-number-input__wrapper--stepper\": stepper,\n })}\n data-invalid={inputProps[\"aria-invalid\"]}\n style={inputWrapperStyle}\n >\n {stepper && (\n <StepperButton\n direction=\"decrement\"\n disabled={stepperDisabled || isAtOrBelowMin}\n onClick={() => triggerStep(\"decrement\")}\n />\n )}\n <input\n {...inputProps}\n {...rest}\n ref={mergedRef}\n type=\"number\"\n onChange={handleChange}\n className={clsx(\n \"jkl-number-input__input\",\n {\n \"jkl-number-input__input--stepper\": stepper,\n \"jkl-number-input__input--align-right\":\n !stepper && align === \"right\",\n },\n inputClassName,\n )}\n data-testautoid={testAutoId}\n />\n {stepper && (\n <StepperButton\n direction=\"increment\"\n disabled={stepperDisabled || isAtOrAboveMax}\n onClick={() => triggerStep(\"increment\")}\n />\n )}\n </div>\n )}\n />\n );\n },\n);\n\nNumberInput.displayName = \"NumberInput\";\n"],"names":["stepperConfig","decrement","label","Icon","MinusIcon","increment","PlusIcon","StepperButton","direction","disabled","onClick","jsx","type","className","onPointerDown","event","preventDefault","children","NumberInput","forwardRef","props","ref","dataSize","testAutoId","dataTestId","align","id","style","errorLabel","helpLabel","inputClassName","labelProps","supportLabelProps","stepper","tooltip","description","width","onChange","rest","internalRef","useRef","mergedRef","mergeRefs","uncontrolledValue","setUncontrolledValue","useState","defaultValue","effectiveValue","value","handleChange","target","numericValue","trim","Number","NaN","toNumeric","minNumeric","min","maxNumeric","max","isAtOrBelowMin","isFinite","isAtOrAboveMax","inputWrapperStyle","inputGroupProps","triggerStep","input","current","readOnly","previousValue","focus","stepUp","stepDown","dispatchEvent","Event","bubbles","stepperDisabled","InputGroup","clsx","render","inputProps","jsxs","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"NumberInput.js","sources":["../../../../src/components/number-input/NumberInput.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport React, { type ComponentType, forwardRef, useRef, useState } from \"react\";\nimport { mergeRefs } from \"../../utilities/mergeRefs.js\";\nimport { MinusIcon, PlusIcon } from \"../icon/index.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport type { NumberInputProps } from \"./types.js\";\n\ntype NumberInputValue = string | number | readonly string[] | undefined;\n\ntype StepDirection = \"increment\" | \"decrement\";\n\nconst stepperConfig: Record<\n StepDirection,\n { label: string; Icon: ComponentType }\n> = {\n decrement: { label: \"Senk verdien\", Icon: MinusIcon },\n increment: { label: \"Øk verdien\", Icon: PlusIcon },\n};\n\nfunction toNumeric(value: NumberInputValue): number {\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\" && value.trim() !== \"\") {\n return Number(value);\n }\n return Number.NaN;\n}\n\ntype StepperButtonProps = {\n direction: StepDirection;\n disabled: boolean;\n onClick: () => void;\n};\n\nfunction StepperButton({ direction, disabled, onClick }: StepperButtonProps) {\n const { label, Icon } = stepperConfig[direction];\n\n return (\n <button\n type=\"button\"\n className=\"jkl-button jkl-button--ghost\"\n aria-label={label}\n data-direction={direction}\n onPointerDown={(event) => event.preventDefault()}\n onClick={onClick}\n disabled={disabled}\n >\n <span aria-hidden=\"true\">\n <Icon />\n </span>\n </button>\n );\n}\n\nexport const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(\n (props, ref) => {\n const {\n \"data-size\": dataSize,\n \"data-testautoid\": testAutoId,\n \"data-testid\": dataTestId,\n align = \"left\",\n id,\n label,\n className,\n style,\n errorLabel,\n helpLabel,\n inputClassName,\n labelProps,\n supportLabelProps,\n stepper = false,\n tooltip,\n description,\n width,\n onChange,\n ...rest\n } = props;\n const internalRef = useRef<HTMLInputElement>(null);\n const mergedRef = mergeRefs(internalRef, ref);\n const [uncontrolledValue, setUncontrolledValue] =\n useState<NumberInputValue>(rest.defaultValue);\n\n // I kontrollert bruk må vi lese direkte fra `value` for at disabled-\n // state på stepper-knappene skal følge prop-en i samme render. Bruker\n // intern state som fallback for ukontrollert bruk.\n const effectiveValue =\n rest.value !== undefined ? rest.value : uncontrolledValue;\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (rest.value === undefined) {\n setUncontrolledValue(event.target.value);\n }\n onChange?.(event);\n };\n\n const numericValue = toNumeric(effectiveValue);\n const minNumeric =\n rest.min !== undefined ? Number(rest.min) : Number.NaN;\n const maxNumeric =\n rest.max !== undefined ? Number(rest.max) : Number.NaN;\n const isAtOrBelowMin =\n Number.isFinite(numericValue) &&\n Number.isFinite(minNumeric) &&\n numericValue <= minNumeric;\n const isAtOrAboveMax =\n Number.isFinite(numericValue) &&\n Number.isFinite(maxNumeric) &&\n numericValue >= maxNumeric;\n\n const inputWrapperStyle =\n style || width\n ? {\n ...style,\n ...(width ? { width } : undefined),\n }\n : undefined;\n const inputGroupProps = {\n id,\n label,\n errorLabel,\n helpLabel,\n labelProps,\n supportLabelProps,\n tooltip,\n description,\n };\n\n const triggerStep = (direction: StepDirection) => {\n const input = internalRef.current;\n\n if (!input || input.disabled || input.readOnly) {\n return;\n }\n\n const previousValue = input.value;\n input.focus();\n\n try {\n if (direction === \"increment\") {\n input.stepUp();\n } else {\n input.stepDown();\n }\n } catch {\n return;\n }\n\n if (input.value === previousValue) {\n return;\n }\n\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n };\n\n const stepperDisabled = rest.disabled || rest.readOnly;\n\n return (\n <InputGroup\n {...inputGroupProps}\n className={clsx(className, \"jkl-number-input\")}\n data-size={dataSize}\n data-testid={dataTestId ?? \"jkl-number-input\"}\n render={(inputProps) => (\n <div\n className={clsx(\"jkl-number-input__wrapper\", {\n \"jkl-number-input__wrapper--stepper\": stepper,\n })}\n data-invalid={inputProps[\"aria-invalid\"]}\n style={inputWrapperStyle}\n >\n {stepper && (\n <StepperButton\n direction=\"decrement\"\n disabled={stepperDisabled || isAtOrBelowMin}\n onClick={() => triggerStep(\"decrement\")}\n />\n )}\n <input\n {...inputProps}\n {...rest}\n ref={mergedRef}\n type=\"number\"\n onChange={handleChange}\n className={clsx(\n \"jkl-number-input__input\",\n {\n \"jkl-number-input__input--stepper\": stepper,\n \"jkl-number-input__input--align-right\":\n !stepper && align === \"right\",\n },\n inputClassName,\n )}\n data-testautoid={testAutoId}\n />\n {stepper && (\n <StepperButton\n direction=\"increment\"\n disabled={stepperDisabled || isAtOrAboveMax}\n onClick={() => triggerStep(\"increment\")}\n />\n )}\n </div>\n )}\n />\n );\n },\n);\n\nNumberInput.displayName = \"NumberInput\";\n"],"names":["stepperConfig","decrement","label","Icon","MinusIcon","increment","PlusIcon","StepperButton","direction","disabled","onClick","jsx","type","className","onPointerDown","event","preventDefault","children","NumberInput","forwardRef","props","ref","dataSize","testAutoId","dataTestId","align","id","style","errorLabel","helpLabel","inputClassName","labelProps","supportLabelProps","stepper","tooltip","description","width","onChange","rest","internalRef","useRef","mergedRef","mergeRefs","uncontrolledValue","setUncontrolledValue","useState","defaultValue","effectiveValue","value","handleChange","target","numericValue","trim","Number","NaN","toNumeric","minNumeric","min","maxNumeric","max","isAtOrBelowMin","isFinite","isAtOrAboveMax","inputWrapperStyle","inputGroupProps","triggerStep","input","current","readOnly","previousValue","focus","stepUp","stepDown","dispatchEvent","Event","bubbles","stepperDisabled","InputGroup","clsx","render","inputProps","jsxs","displayName"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{jsx as e}from"react/jsx-runtime";import{c as o}from"../../../clsx-BeLtu-UY.js";import"react";import{FieldGroup as r}from"../input-group/FieldGroup.js";const s=s=>e(r,{...s,className:o("jkl-segmented-control",s.className)});s.displayName="Segmented Control";export{s as SegmentedControl};
1
+ import{jsx as e}from"react/jsx-runtime";import{c as o}from"../../../clsx-BeLtu-UY.js";import"react";import{FieldGroup as r}from"../input-group/FieldGroup.js";const s=s=>e(r,{...s,className:o("jkl-segmented-control",s.className)});s.displayName="SegmentedControl";export{s as SegmentedControl};
2
2
  //# sourceMappingURL=SegmentedControl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.js","sources":["../../../../src/components/segmented-control/SegmentedControl.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport React from \"react\";\nimport { FieldGroup } from \"../input-group/FieldGroup.js\";\nimport type { SegmentedControlProps } from \"./types.js\";\n\nexport const SegmentedControl = (props: SegmentedControlProps) => {\n return (\n <FieldGroup\n {...props}\n className={clsx(\"jkl-segmented-control\", props.className)}\n />\n );\n};\n\nSegmentedControl.displayName = \"Segmented Control\";\n"],"names":["SegmentedControl","props","jsx","FieldGroup","className","clsx","displayName"],"mappings":"8JAKO,MAAMA,EAAoBC,GAEzBC,EAACC,EAAA,IACOF,EACJG,UAAWC,EAAK,wBAAyBJ,EAAMG,aAK3DJ,EAAiBM,YAAc"}
1
+ {"version":3,"file":"SegmentedControl.js","sources":["../../../../src/components/segmented-control/SegmentedControl.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport React from \"react\";\nimport { FieldGroup } from \"../input-group/FieldGroup.js\";\nimport type { SegmentedControlProps } from \"./types.js\";\n\nexport const SegmentedControl = (props: SegmentedControlProps) => {\n return (\n <FieldGroup\n {...props}\n className={clsx(\"jkl-segmented-control\", props.className)}\n />\n );\n};\n\nSegmentedControl.displayName = \"SegmentedControl\";\n"],"names":["SegmentedControl","props","jsx","FieldGroup","className","clsx","displayName"],"mappings":"8JAKO,MAAMA,EAAoBC,GAEzBC,EAACC,EAAA,IACOF,EACJG,UAAWC,EAAK,wBAAyBJ,EAAMG,aAK3DJ,EAAiBM,YAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"Option.js","sources":["../../../../src/components/select/Option.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type RefObject,\n type MouseEvent,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\nimport { Flex } from \"../flex/Flex.js\";\nimport { Text } from \"../typography/Text.js\";\n\nexport type OptionProps = Omit<\n ComponentPropsWithoutRef<\"button\">,\n \"aria-selected\" | \"children\" | \"role\" | \"type\" | \"value\"\n> &\n ValuePair & {\n multiple?: boolean;\n selected?: boolean;\n selectRef: RefObject<HTMLSelectElement>;\n };\n\nexport const Option = forwardRef<HTMLButtonElement, OptionProps>(\n function Option(props, ref) {\n const {\n className = \"\",\n multiple = false,\n selected = false,\n selectRef,\n label,\n description,\n media,\n value,\n ...rest\n } = props;\n\n const mediaRef = useRef<HTMLSpanElement>(null);\n const labelRef = useRef<HTMLSpanElement>(null);\n\n const syncValueToSelect = useCallback(\n (event: KeyboardEvent | MouseEvent) => {\n const button = (\n event.target as HTMLElement\n ).closest<HTMLButtonElement>(\"button\");\n if (!button || !selectRef.current || selectRef.current.disabled)\n return;\n\n const option = Array.from(selectRef.current.options).find(\n (option) => option.value === button.value,\n );\n if (!option) return;\n\n option.selected = multiple ? !option.selected : true;\n selectRef.current.dispatchEvent(\n new Event(\"change\", { bubbles: true }),\n );\n },\n [selectRef, multiple],\n );\n\n useEffect(() => {\n if (!media || !labelRef.current || !mediaRef.current) return;\n const labelElement = labelRef.current;\n const mediaElement = mediaRef.current;\n const observer = new ResizeObserver(() => {\n mediaElement.style.setProperty(\n \"--media-size\",\n `${labelElement.offsetHeight}px`,\n );\n });\n observer.observe(labelElement);\n return () => observer.disconnect();\n }, [media]);\n\n return (\n <button\n ref={ref}\n // biome-ignore lint/a11y/useSemanticElements: vi kan ikke style option-elementet\n role=\"option\"\n type=\"button\"\n className={clsx(\"jkl-option\", className)}\n value={value}\n data-multiple={multiple || undefined}\n aria-selected={selected}\n {...rest}\n onClick={(event) => {\n rest.onClick?.(event);\n syncValueToSelect(event);\n }}\n >\n <Flex\n as=\"span\"\n direction=\"column\"\n gap=\"4\"\n className=\"jkl-option__label\"\n ref={labelRef}\n >\n <Text short as=\"span\">\n {label}\n </Text>\n {description && (\n <Text short subdued as=\"span\" size=\"xs\">\n {description}\n </Text>\n )}\n </Flex>\n {media && (\n <span className=\"jkl-option__media\" ref={mediaRef}>\n {media}\n </span>\n )}\n </button>\n );\n },\n);\n"],"names":["Option","forwardRef","props","ref","className","multiple","selected","selectRef","label","description","media","value","rest","mediaRef","useRef","labelRef","syncValueToSelect","useCallback","event","button","target","closest","current","disabled","option","Array","from","options","find","dispatchEvent","Event","bubbles","useEffect","labelElement","mediaElement","observer","ResizeObserver","style","setProperty","offsetHeight","observe","disconnect","jsxs","role","type","clsx","onClick","children","Flex","as","direction","gap","jsx","Text","short","subdued","size"],"mappings":"mQAwBO,MAAMA,EAASC,EAClB,SAAgBC,EAAOC,GACnB,MACIC,UAAAA,EAAY,GACZC,SAAAA,GAAW,EACXC,SAAAA,GAAW,EACXC,UAAAA,EACAC,MAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAC,MAAAA,KACGC,GACHV,EAEEW,EAAWC,EAAwB,MACnCC,EAAWD,EAAwB,MAEnCE,EAAoBC,EACrBC,IACG,MAAMC,EACFD,EAAME,OACRC,QAA2B,UAC7B,IAAKF,IAAWZ,EAAUe,SAAWf,EAAUe,QAAQC,SACnD,OAEJ,MAAMC,EAASC,MAAMC,KAAKnB,EAAUe,QAAQK,SAASC,KAChDJ,GAAWA,EAAOb,QAAUQ,EAAOR,OAEnCa,IAELA,EAAOlB,UAAWD,IAAYmB,EAAOlB,SACrCC,EAAUe,QAAQO,cACd,IAAIC,MAAM,SAAU,CAAEC,SAAS,OAGvC,CAACxB,EAAWF,IAGhB,OAAA2B,EAAU,KACN,IAAKtB,IAAUK,EAASO,UAAYT,EAASS,QAAS,OACtD,MAAMW,EAAelB,EAASO,QACxBY,EAAerB,EAASS,QACxBa,EAAW,IAAIC,eAAe,KAChCF,EAAaG,MAAMC,YACf,eACA,GAAGL,EAAaM,oBAGxB,OAAAJ,EAASK,QAAQP,GACV,IAAME,EAASM,cACvB,CAAC/B,IAGAgC,EAAC,SAAA,CACGvC,IAAAA,EAEAwC,KAAK,SACLC,KAAK,SACLxC,UAAWyC,EAAK,aAAczC,GAC9BO,MAAAA,EACA,gBAAeN,QAAY,EAC3B,gBAAeC,KACXM,EACJkC,QAAU5B,IACNN,EAAKkC,UAAU5B,GACfF,EAAkBE,IAGtB6B,SAAA,CAAAL,EAACM,EAAA,CACGC,GAAG,OACHC,UAAU,SACVC,IAAI,IACJ/C,UAAU,oBACVD,IAAKY,EAELgC,SAAA,CAAAK,EAACC,EAAA,CAAKC,OAAK,EAACL,GAAG,OACVF,SAAAvC,IAEJC,GACG2C,EAACC,EAAA,CAAKC,OAAK,EAACC,SAAO,EAACN,GAAG,OAAOO,KAAK,KAC9BT,SAAAtC,OAIZC,GACG0C,EAAC,OAAA,CAAKhD,UAAU,oBAAoBD,IAAKU,EACpCkC,SAAArC,MAKrB"}
1
+ {"version":3,"file":"Option.js","sources":["../../../../src/components/select/Option.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type MouseEvent,\n type RefObject,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport type { ValuePair } from \"../../utilities/valuePair.js\";\nimport { Flex } from \"../flex/Flex.js\";\nimport { Text } from \"../typography/Text.js\";\n\nexport type OptionProps = Omit<\n ComponentPropsWithoutRef<\"button\">,\n \"aria-selected\" | \"children\" | \"role\" | \"type\" | \"value\"\n> &\n ValuePair & {\n multiple?: boolean;\n selected?: boolean;\n selectRef: RefObject<HTMLSelectElement>;\n };\n\nexport const Option = forwardRef<HTMLButtonElement, OptionProps>(\n function Option(props, ref) {\n const {\n className = \"\",\n multiple = false,\n selected = false,\n selectRef,\n label,\n description,\n media,\n value,\n ...rest\n } = props;\n\n const mediaRef = useRef<HTMLSpanElement>(null);\n const labelRef = useRef<HTMLSpanElement>(null);\n\n const syncValueToSelect = useCallback(\n (event: KeyboardEvent | MouseEvent) => {\n const button = (\n event.target as HTMLElement\n ).closest<HTMLButtonElement>(\"button\");\n if (!button || !selectRef.current || selectRef.current.disabled)\n return;\n\n const option = Array.from(selectRef.current.options).find(\n (option) => option.value === button.value,\n );\n if (!option) return;\n\n option.selected = multiple ? !option.selected : true;\n selectRef.current.dispatchEvent(\n new Event(\"change\", { bubbles: true }),\n );\n },\n [selectRef, multiple],\n );\n\n useEffect(() => {\n if (!media || !labelRef.current || !mediaRef.current) return;\n const labelElement = labelRef.current;\n const mediaElement = mediaRef.current;\n const observer = new ResizeObserver(() => {\n mediaElement.style.setProperty(\n \"--media-size\",\n `${labelElement.offsetHeight}px`,\n );\n });\n observer.observe(labelElement);\n return () => observer.disconnect();\n }, [media]);\n\n return (\n <button\n ref={ref}\n // biome-ignore lint/a11y/useSemanticElements: vi kan ikke style option-elementet\n role=\"option\"\n type=\"button\"\n className={clsx(\"jkl-option\", className)}\n value={value}\n data-multiple={multiple || undefined}\n aria-selected={selected}\n {...rest}\n onClick={(event) => {\n rest.onClick?.(event);\n syncValueToSelect(event);\n }}\n >\n <Flex\n as=\"span\"\n direction=\"column\"\n gap=\"4\"\n className=\"jkl-option__label\"\n ref={labelRef}\n >\n <Text short as=\"span\">\n {label}\n </Text>\n {description && (\n <Text short subdued as=\"span\" size=\"xs\">\n {description}\n </Text>\n )}\n </Flex>\n {media && (\n <span className=\"jkl-option__media\" ref={mediaRef}>\n {media}\n </span>\n )}\n </button>\n );\n },\n);\n"],"names":["Option","forwardRef","props","ref","className","multiple","selected","selectRef","label","description","media","value","rest","mediaRef","useRef","labelRef","syncValueToSelect","useCallback","event","button","target","closest","current","disabled","option","Array","from","options","find","dispatchEvent","Event","bubbles","useEffect","labelElement","mediaElement","observer","ResizeObserver","style","setProperty","offsetHeight","observe","disconnect","jsxs","role","type","clsx","onClick","children","Flex","as","direction","gap","jsx","Text","short","subdued","size"],"mappings":"mQAwBO,MAAMA,EAASC,EAClB,SAAgBC,EAAOC,GACnB,MACIC,UAAAA,EAAY,GACZC,SAAAA,GAAW,EACXC,SAAAA,GAAW,EACXC,UAAAA,EACAC,MAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAC,MAAAA,KACGC,GACHV,EAEEW,EAAWC,EAAwB,MACnCC,EAAWD,EAAwB,MAEnCE,EAAoBC,EACrBC,IACG,MAAMC,EACFD,EAAME,OACRC,QAA2B,UAC7B,IAAKF,IAAWZ,EAAUe,SAAWf,EAAUe,QAAQC,SACnD,OAEJ,MAAMC,EAASC,MAAMC,KAAKnB,EAAUe,QAAQK,SAASC,KAChDJ,GAAWA,EAAOb,QAAUQ,EAAOR,OAEnCa,IAELA,EAAOlB,UAAWD,IAAYmB,EAAOlB,SACrCC,EAAUe,QAAQO,cACd,IAAIC,MAAM,SAAU,CAAEC,SAAS,OAGvC,CAACxB,EAAWF,IAGhB,OAAA2B,EAAU,KACN,IAAKtB,IAAUK,EAASO,UAAYT,EAASS,QAAS,OACtD,MAAMW,EAAelB,EAASO,QACxBY,EAAerB,EAASS,QACxBa,EAAW,IAAIC,eAAe,KAChCF,EAAaG,MAAMC,YACf,eACA,GAAGL,EAAaM,oBAGxB,OAAAJ,EAASK,QAAQP,GACV,IAAME,EAASM,cACvB,CAAC/B,IAGAgC,EAAC,SAAA,CACGvC,IAAAA,EAEAwC,KAAK,SACLC,KAAK,SACLxC,UAAWyC,EAAK,aAAczC,GAC9BO,MAAAA,EACA,gBAAeN,QAAY,EAC3B,gBAAeC,KACXM,EACJkC,QAAU5B,IACNN,EAAKkC,UAAU5B,GACfF,EAAkBE,IAGtB6B,SAAA,CAAAL,EAACM,EAAA,CACGC,GAAG,OACHC,UAAU,SACVC,IAAI,IACJ/C,UAAU,oBACVD,IAAKY,EAELgC,SAAA,CAAAK,EAACC,EAAA,CAAKC,OAAK,EAACL,GAAG,OACVF,SAAAvC,IAEJC,GACG2C,EAACC,EAAA,CAAKC,OAAK,EAACC,SAAO,EAACN,GAAG,OAAOO,KAAK,KAC9BT,SAAAtC,OAIZC,GACG0C,EAAC,OAAA,CAAKhD,UAAU,oBAAoBD,IAAKU,EACpCkC,SAAArC,MAKrB"}
@@ -1,7 +1,7 @@
1
1
  import { ComponentPropsWithoutRef } from 'react';
2
+ import { DataTestAutoId } from '../../utilities/types.js';
2
3
  import { ValuePair } from '../../utilities/valuePair.js';
3
4
  import { InputGroupProps } from '../input-group/types.js';
4
- import { DataTestAutoId } from '../../utilities/types.js';
5
5
  export type SelectProps = Omit<InputGroupProps, "children" | "inline"> & DataTestAutoId & Omit<ComponentPropsWithoutRef<"select">, "size" | "children"> & {
6
6
  width?: string;
7
7
  items: (string | ValuePair)[];