@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.
- package/build/build-stats.html +1 -1
- package/build/cjs/components/autosuggest/Autosuggest.cjs.map +1 -1
- package/build/cjs/components/autosuggest/Autosuggest.d.cts +5 -0
- package/build/cjs/components/combobox/Combobox.cjs.map +1 -1
- package/build/cjs/components/combobox/Combobox.d.cts +4 -0
- package/build/cjs/components/flex/Flex.cjs +1 -1
- package/build/cjs/components/flex/Flex.cjs.map +1 -1
- package/build/cjs/components/flex/types.cjs +1 -1
- package/build/cjs/components/flex/types.cjs.map +1 -1
- package/build/cjs/components/flex/types.d.cts +36 -26
- package/build/cjs/components/image/Image.cjs +1 -1
- package/build/cjs/components/image/Image.cjs.map +1 -1
- package/build/cjs/components/number-input/NumberInput.cjs.map +1 -1
- package/build/cjs/components/segmented-control/SegmentedControl.cjs +1 -1
- package/build/cjs/components/segmented-control/SegmentedControl.cjs.map +1 -1
- package/build/cjs/components/select/Option.cjs.map +1 -1
- package/build/cjs/components/select/Select.cjs.map +1 -1
- package/build/cjs/components/select/Select.d.cts +1 -1
- package/build/cjs/components/select/utils.cjs.map +1 -1
- package/build/cjs/components/table/stories/assets/table-data.cjs +2 -0
- package/build/cjs/components/table/stories/assets/table-data.cjs.map +1 -0
- package/build/cjs/components/table/stories/assets/table-data.d.cts +8 -0
- package/build/es/components/autosuggest/Autosuggest.d.ts +5 -0
- package/build/es/components/autosuggest/Autosuggest.js.map +1 -1
- package/build/es/components/combobox/Combobox.d.ts +4 -0
- package/build/es/components/combobox/Combobox.js.map +1 -1
- package/build/es/components/flex/Flex.js +1 -1
- package/build/es/components/flex/Flex.js.map +1 -1
- package/build/es/components/flex/types.d.ts +36 -26
- package/build/es/components/flex/types.js +1 -1
- package/build/es/components/flex/types.js.map +1 -1
- package/build/es/components/image/Image.js +1 -1
- package/build/es/components/image/Image.js.map +1 -1
- package/build/es/components/number-input/NumberInput.js.map +1 -1
- package/build/es/components/segmented-control/SegmentedControl.js +1 -1
- package/build/es/components/segmented-control/SegmentedControl.js.map +1 -1
- package/build/es/components/select/Option.js.map +1 -1
- package/build/es/components/select/Select.d.ts +1 -1
- package/build/es/components/select/Select.js.map +1 -1
- package/build/es/components/select/utils.js.map +1 -1
- package/build/es/components/table/stories/assets/table-data.d.ts +8 -0
- package/build/es/components/table/stories/assets/table-data.js +2 -0
- package/build/es/components/table/stories/assets/table-data.js.map +1 -0
- package/codemods/CODEMODS.md +115 -83
- package/codemods/__tests__/import-paths.test.mjs +107 -1
- package/codemods/import-paths.mjs +5 -1
- package/codemods/transforms/select.mjs +237 -0
- package/package.json +1 -2
- package/styles/base.css +4 -3
- package/styles/base.min.css +1 -1
- package/styles/components/countdown/countdown.css +2 -2
- package/styles/components/countdown/countdown.min.css +1 -1
- package/styles/components/feedback/feedback.css +2 -2
- package/styles/components/feedback/feedback.min.css +1 -1
- package/styles/components/file-input/file-input.css +9 -9
- package/styles/components/file-input/file-input.min.css +1 -1
- package/styles/components/flex/flex.css +16 -1343
- package/styles/components/flex/flex.min.css +1 -1
- package/styles/components/flex/flex.scss +14 -280
- package/styles/components/input-group/input-group.css +2 -2
- package/styles/components/input-group/input-group.min.css +1 -1
- package/styles/components/loader/loader.css +6 -6
- package/styles/components/loader/loader.min.css +1 -1
- package/styles/components/loader/skeleton-loader.css +3 -3
- package/styles/components/loader/skeleton-loader.min.css +1 -1
- package/styles/components/message/message.css +2 -2
- package/styles/components/message/message.min.css +1 -1
- package/styles/components/progress-bar/progress-bar.css +1 -1
- package/styles/components/progress-bar/progress-bar.min.css +1 -1
- package/styles/components/segmented-control/segmented-control.css +2 -2
- package/styles/components/segmented-control/segmented-control.min.css +1 -1
- package/styles/components/system-message/system-message.css +2 -2
- package/styles/components/system-message/system-message.min.css +1 -1
- package/styles/components/toast/toast.css +4 -4
- package/styles/components/toast/toast.min.css +1 -1
- package/styles/components.css +37 -1367
- package/styles/components.min.css +2 -2
- package/styles/theme/_tokens.scss +2 -1
- 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\")
|
|
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"}
|
|
@@ -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":"
|
|
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
|
|
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
|
|
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/
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
29
|
-
|
|
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>
|
|
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
|
|
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
|
|
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{
|
|
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 {
|
|
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="
|
|
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 = \"
|
|
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
|
|
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)[];
|