@fremtind/jokul 5.5.2 → 5.5.4
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/datepicker/DatePicker.cjs +1 -1
- package/build/cjs/components/datepicker/DatePicker.cjs.map +1 -1
- package/build/cjs/components/popover/Popover.cjs +1 -1
- package/build/cjs/components/popover/Popover.cjs.map +1 -1
- package/build/cjs/components/popover/types.d.cts +13 -0
- package/build/cjs/hooks/index.cjs +1 -1
- package/build/cjs/hooks/index.d.cts +1 -0
- package/build/cjs/hooks/useMergeRefs/useMergeRefs.cjs +2 -0
- package/build/cjs/hooks/useMergeRefs/useMergeRefs.cjs.map +1 -0
- package/build/cjs/hooks/useMergeRefs/useMergeRefs.d.cts +8 -0
- package/build/cjs/utilities/index.cjs +1 -1
- package/build/cjs/utilities/index.d.cts +1 -0
- package/build/cjs/utilities/mergeRefs.cjs +1 -1
- package/build/cjs/utilities/mergeRefs.cjs.map +1 -1
- package/build/cjs/utilities/mergeRefs.d.cts +0 -8
- package/build/es/components/datepicker/DatePicker.js +1 -1
- package/build/es/components/datepicker/DatePicker.js.map +1 -1
- package/build/es/components/popover/Popover.js +1 -1
- package/build/es/components/popover/Popover.js.map +1 -1
- package/build/es/components/popover/types.d.ts +13 -0
- package/build/es/hooks/index.d.ts +1 -0
- package/build/es/hooks/index.js +1 -1
- package/build/es/hooks/useMergeRefs/useMergeRefs.d.ts +8 -0
- package/build/es/hooks/useMergeRefs/useMergeRefs.js +2 -0
- package/build/es/hooks/useMergeRefs/useMergeRefs.js.map +1 -0
- package/build/es/utilities/index.d.ts +1 -0
- package/build/es/utilities/index.js +1 -1
- package/build/es/utilities/mergeRefs.d.ts +0 -8
- package/build/es/utilities/mergeRefs.js +1 -1
- package/build/es/utilities/mergeRefs.js.map +1 -1
- package/package.json +1 -1
- package/styles/base.css +4 -2
- 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/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/popover/popover.css +4 -0
- package/styles/components/popover/popover.min.css +1 -1
- package/styles/components/popover/popover.scss +5 -0
- 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 +13 -13
- package/styles/components/segmented-control/segmented-control.min.css +1 -1
- package/styles/components/segmented-control/segmented-control.scss +2 -2
- 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 +39 -35
- package/styles/components.min.css +1 -1
- package/styles/tailwind.css +2 -2
- package/styles/theme/_tokens.scss +2 -2
- package/styles/theme/brands/dnb/_fonts.scss +2 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("../../../clsx-E3yX_9sL.cjs"),r=require("../../../utils-CD_aHC6R.cjs"),a=require("react"),n=require("react-dom"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("../../../clsx-E3yX_9sL.cjs"),r=require("../../../utils-CD_aHC6R.cjs"),a=require("react"),n=require("react-dom"),l=require("../../utilities/formatters/date/formatDate.cjs"),o=require("../icon-button/IconButton.cjs"),u=require("../icon/icons/CalendarIcon.cjs"),i=require("../input-group/InputGroup.cjs"),s=require("../popover/Popover.cjs"),c=require("../text-input/BaseTextInput.cjs"),d=require("./internal/Calendar.cjs"),p=require("./utils.cjs"),f=require("./validation.cjs"),v=a.forwardRef((v,D)=>{const{"data-testautoid":b,id:m,className:g="",label:h="Velg dato",labelProps:j,defaultValue:k,defaultShow:y=!1,value:x,disableBeforeDate:C,disableAfterDate:S,yearsToShow:L,name:P,helpLabel:q,errorLabel:w,invalid:I,days:O,months:T,monthLabel:B,yearLabel:E,placeholder:_="dd.mm.åååå",width:R="11.25rem",onChange:N,onBlur:U,onFocus:V,onKeyDown:F,action:A,showCalendarLabel:H="Åpne kalender",hideCalendarLabel:K="Lukk kalender",supportLabelProps:M,tooltip:W,textInputProps:G,description:$,...z}=v;"production"!==process.env.NODE_ENV&&x&&k&&console.warn("DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.");const J=p.parseDateString(C),Q=J?r.dayjs(J).startOf("day").toDate():void 0,X=p.parseDateString(S),Y=X?r.dayjs(X).startOf("day").toDate():void 0,[Z,ee]=a.useState(r.getInitialDate(x,k,Q,Y)),[te,re]=a.useState(null),[ae,ne]=a.useState(y),le=a.useRef(null),oe=a.useRef(null),ue=a.useRef(null),ie=a.useRef(null),se=a.useRef(!1),ce=a.useCallback(e=>{ie.current=e,D&&("function"==typeof D?D(e):D.current=e)},[D]),de=a.useCallback(e=>{V&&oe.current&&(oe.current.contains(e.relatedTarget)||V(e,Z,{error:te,value:e.target.value}))},[V,Z,te]),pe=a.useCallback(e=>{U&&U(e,Z,{error:te,value:e.target.value})},[U,Z,te]),fe=a.useCallback(e=>{"Escape"===e.key&&(ne(!1),e.preventDefault(),e.stopPropagation()),A?.onKeyDown&&A.onKeyDown(e)},[A]),ve=a.useCallback(e=>{const t=e.currentTarget.value,r=((e,t)=>{const r=e.replace(/\D/g,""),a=l.formatDateString(r,{partial:!0}),n=e.replace(/\D+$/,""),o=8===r.length?l.formatDateString(r):e,u=p.parseDateString(o)?o:null,i=t&&e!==r&&n===a&&void 0===p.parseDateString(e)&&null===u;return u??(i?r:e)})(t,se.current);r!==t&&((e,t)=>{const r=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set;r?r.call(e,t):e.value=t})(e.currentTarget,r);const a=t.replace(/\D/g,"");se.current=t===a&&r===l.formatDateString(a)&&r!==t&&void 0!==p.parseDateString(r);const{date:n,error:o}=(({value:e,minDate:t,maxDate:r})=>{if(!e)return{date:null,error:null};const a=p.parseDateString(e);return a?t&&!f.isWithinLowerBound(a,t)?{date:a,error:"OUTSIDE_LOWER_BOUND"}:r&&!f.isWithinUpperBound(a,r)?{date:a,error:"OUTSIDE_UPPER_BOUND"}:{date:a,error:null}:{date:null,error:"WRONG_FORMAT"}})({value:r,minDate:Q,maxDate:Y});n&&!o&&ne(!1),re(o),ee(n),N&&N(e,n,{error:o,value:r})},[N,Q,Y]),De=a.useCallback(e=>{n.flushSync(()=>{ne(!ae)});const t=le.current,r=t&&t.querySelector('[aria-pressed="true"]');window.requestAnimationFrame(()=>r?.focus()),A?.onClick&&A.onClick(e)},[ae,A]),be=a.useCallback(({date:e})=>{if(ne(!1),ee(e),ie.current){const t=ie.current;se.current=!1,t.value=p.formatInput(e);const r=document.createEvent("HTMLEvents");r.initEvent("input",!0,!1),t.dispatchEvent(r),t.focus(),N&&N(r,e,{error:null,value:t.value})}},[N]),me=a.useCallback(e=>{e.preventDefault(),ne(!1),ue.current?.focus()},[]);return e.jsx(i.InputGroup,{id:m,className:t.clsx("jkl-datepicker",g),...z,ref:oe,label:h,labelProps:j,helpLabel:q,errorLabel:w,supportLabelProps:M,tooltip:W,description:$,render:t=>e.jsx(c.BaseTextInput,{"data-focused":ae?"true":void 0,ref:ce,"data-testid":"jkl-datepicker__input","data-testautoid":b,className:"jkl-datepicker__input",name:P,defaultValue:k,value:x,type:"text",placeholder:_,width:R,onFocus:de,onBlur:pe,onChange:ve,actionButton:e.jsxs(s.Popover,{positionReference:ie,open:ae,onOpenChange:()=>ne(!ae),offset:8,fitAvailableHeight:!0,children:[e.jsx(s.Popover.Trigger,{...A,"data-testid":"jkl-datepicker__trigger",className:"jkl-text-input-action-button",title:ae?K:H,tabIndex:0,onClick:De,onKeyDown:fe,asChild:!0,children:e.jsx(o.IconButton,{children:e.jsx(u.CalendarIcon,{})})}),e.jsx(s.Popover.Content,{initialFocus:-1,padding:24,children:e.jsx(d.Calendar,{ref:le,date:Z,minDate:Q,maxDate:Y,days:O,months:T,monthLabel:B,yearLabel:E,yearsToShow:L,onDateSelected:be,onTabOutside:me})})]}),...G,...t,"aria-invalid":I||!!w})})});v.displayName="DatePicker",exports.DatePicker=v;
|
|
2
2
|
//# sourceMappingURL=DatePicker.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.cjs","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport React, {\n type ChangeEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { formatDateString } from \"../../utilities/formatters/date/formatDate.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CalendarIcon } from \"../icon/icons/CalendarIcon.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport Popover from \"../popover/Popover.js\";\nimport { BaseTextInput } from \"../text-input/BaseTextInput.js\";\nimport { Calendar } from \"./internal/Calendar.js\";\nimport { type DateInfo, getInitialDate } from \"./internal/utils.js\";\nimport type { DatePickerProps, DateValidationError } from \"./types.js\";\nimport { formatInput, parseDateString } from \"./utils.js\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation.js\";\n\nconst setInputValue = (input: HTMLInputElement, value: string) => {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set;\n\n if (nativeSetter) {\n nativeSetter.call(input, value);\n } else {\n input.value = value;\n }\n};\n\nconst normalizeInputValue = (\n rawValue: string,\n shouldStripAutoFormatting: boolean,\n) => {\n const digits = rawValue.replace(/\\D/g, \"\");\n const partialCompactDate = formatDateString(digits, {\n partial: true,\n });\n const rawValueWithoutTrailingPunctuation = rawValue.replace(/\\D+$/, \"\");\n const compactDateCandidate =\n digits.length === 8 ? formatDateString(digits) : rawValue;\n const validCompactDate = parseDateString(compactDateCandidate)\n ? compactDateCandidate\n : null;\n const shouldRemoveFormatting =\n shouldStripAutoFormatting &&\n rawValue !== digits &&\n rawValueWithoutTrailingPunctuation === partialCompactDate &&\n parseDateString(rawValue) === undefined &&\n validCompactDate === null;\n\n return validCompactDate ?? (shouldRemoveFormatting ? digits : rawValue);\n};\n\nconst getInputValidationState = ({\n value,\n minDate,\n maxDate,\n}: {\n value: string;\n minDate?: Date;\n maxDate?: Date;\n}): { date: Date | null; error: DateValidationError | null } => {\n if (!value) {\n return { date: null, error: null };\n }\n\n const parsedDate = parseDateString(value);\n\n if (!parsedDate) {\n return { date: null, error: \"WRONG_FORMAT\" };\n }\n\n if (minDate && !isWithinLowerBound(parsedDate, minDate)) {\n return { date: parsedDate, error: \"OUTSIDE_LOWER_BOUND\" };\n }\n\n if (maxDate && !isWithinUpperBound(parsedDate, maxDate)) {\n return { date: parsedDate, error: \"OUTSIDE_UPPER_BOUND\" };\n }\n\n return { date: parsedDate, error: null };\n};\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(\n (props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltip,\n textInputProps,\n description,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate\n ? dayjs(disableBeforeDate).startOf(\"day\").toDate()\n : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate\n ? dayjs(disableAfterDate).startOf(\"day\").toDate()\n : undefined;\n\n const [date, setDate] = useState(\n getInitialDate(value, defaultValue, minDate, maxDate),\n );\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n\n const calendarRef = useRef<HTMLDivElement>(null);\n const datepickerRef = useRef<HTMLDivElement>(null);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const didAutoFormatCompactInputRef = useRef(false);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [forwardedInputRef],\n );\n\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [action],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.currentTarget.value;\n const formattedValue = normalizeInputValue(\n rawValue,\n didAutoFormatCompactInputRef.current,\n );\n\n if (formattedValue !== rawValue) {\n setInputValue(e.currentTarget, formattedValue);\n }\n\n const digits = rawValue.replace(/\\D/g, \"\");\n didAutoFormatCompactInputRef.current =\n rawValue === digits &&\n formattedValue === formatDateString(digits) &&\n formattedValue !== rawValue &&\n parseDateString(formattedValue) !== undefined;\n\n const { date: nextDate, error: nextError } =\n getInputValidationState({\n value: formattedValue,\n minDate,\n maxDate,\n });\n\n if (nextDate && !nextError) {\n setShowCalendar(false);\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, {\n error: nextError,\n value: formattedValue,\n });\n }\n },\n [onChange, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button =\n calendarEl &&\n (calendarEl.querySelector(\n '[aria-pressed=\"true\"]',\n ) as HTMLButtonElement);\n // Make sure the popover-modal is correctly positioned before focusing a button\n // so we avoid accidentally scrolling to the top of the page\n window.requestAnimationFrame(() => button?.focus());\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [showCalendar, action],\n );\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n didAutoFormatCompactInputRef.current = false;\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(\n event as unknown as ChangeEvent<HTMLInputElement>,\n date,\n {\n error: null,\n value: node.value,\n },\n );\n }\n }\n },\n [onChange],\n );\n\n const handleTabOutsideCalendar = useCallback((e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current?.focus();\n }, []);\n\n return (\n <InputGroup\n id={id}\n className={clsx(\"jkl-datepicker\", className)}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltip={tooltip}\n description={description}\n render={(inputProps) => (\n <BaseTextInput\n data-focused={showCalendar ? \"true\" : undefined}\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n actionButton={\n <Popover\n positionReference={inputRef}\n open={showCalendar}\n onOpenChange={() =>\n setShowCalendar(!showCalendar)\n }\n offset={8}\n >\n <Popover.Trigger\n {...action}\n data-testid=\"jkl-datepicker__trigger\"\n className=\"jkl-text-input-action-button\"\n title={\n showCalendar\n ? hideCalendarLabel\n : showCalendarLabel\n }\n tabIndex={0}\n onClick={clickCalendar}\n onKeyDown={handleKeyDownAction}\n asChild\n >\n <IconButton>\n <CalendarIcon />\n </IconButton>\n </Popover.Trigger>\n <Popover.Content initialFocus={-1} padding={24}>\n <Calendar\n ref={calendarRef}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </Popover.Content>\n </Popover>\n }\n {...textInputProps}\n {...inputProps}\n aria-invalid={invalid || !!errorLabel}\n />\n )}\n />\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltip","textInputProps","description","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","dayjs","startOf","toDate","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useRef","datepickerRef","iconButtonRef","inputRef","didAutoFormatCompactInputRef","unifiedInputRef","useCallback","instance","current","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleChange","rawValue","currentTarget","formattedValue","shouldStripAutoFormatting","digits","replace","partialCompactDate","formatDateString","partial","rawValueWithoutTrailingPunctuation","compactDateCandidate","length","validCompactDate","shouldRemoveFormatting","normalizeInputValue","input","nativeSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","setInputValue","nextDate","nextError","parsedDate","isWithinLowerBound","isWithinUpperBound","getInputValidationState","clickCalendar","flushSync","calendarEl","button","querySelector","window","requestAnimationFrame","focus","onClick","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","jsx","InputGroup","clsx","ref","render","inputProps","BaseTextInput","type","actionButton","jsxs","Popover","positionReference","open","onOpenChange","offset","children","Trigger","title","tabIndex","asChild","IconButton","CalendarIcon","Content","initialFocus","padding","Calendar","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatePicker.cjs","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport React, {\n type ChangeEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { formatDateString } from \"../../utilities/formatters/date/formatDate.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CalendarIcon } from \"../icon/icons/CalendarIcon.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport Popover from \"../popover/Popover.js\";\nimport { BaseTextInput } from \"../text-input/BaseTextInput.js\";\nimport { Calendar } from \"./internal/Calendar.js\";\nimport { type DateInfo, getInitialDate } from \"./internal/utils.js\";\nimport type { DatePickerProps, DateValidationError } from \"./types.js\";\nimport { formatInput, parseDateString } from \"./utils.js\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation.js\";\n\nconst setInputValue = (input: HTMLInputElement, value: string) => {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set;\n\n if (nativeSetter) {\n nativeSetter.call(input, value);\n } else {\n input.value = value;\n }\n};\n\nconst normalizeInputValue = (\n rawValue: string,\n shouldStripAutoFormatting: boolean,\n) => {\n const digits = rawValue.replace(/\\D/g, \"\");\n const partialCompactDate = formatDateString(digits, {\n partial: true,\n });\n const rawValueWithoutTrailingPunctuation = rawValue.replace(/\\D+$/, \"\");\n const compactDateCandidate =\n digits.length === 8 ? formatDateString(digits) : rawValue;\n const validCompactDate = parseDateString(compactDateCandidate)\n ? compactDateCandidate\n : null;\n const shouldRemoveFormatting =\n shouldStripAutoFormatting &&\n rawValue !== digits &&\n rawValueWithoutTrailingPunctuation === partialCompactDate &&\n parseDateString(rawValue) === undefined &&\n validCompactDate === null;\n\n return validCompactDate ?? (shouldRemoveFormatting ? digits : rawValue);\n};\n\nconst getInputValidationState = ({\n value,\n minDate,\n maxDate,\n}: {\n value: string;\n minDate?: Date;\n maxDate?: Date;\n}): { date: Date | null; error: DateValidationError | null } => {\n if (!value) {\n return { date: null, error: null };\n }\n\n const parsedDate = parseDateString(value);\n\n if (!parsedDate) {\n return { date: null, error: \"WRONG_FORMAT\" };\n }\n\n if (minDate && !isWithinLowerBound(parsedDate, minDate)) {\n return { date: parsedDate, error: \"OUTSIDE_LOWER_BOUND\" };\n }\n\n if (maxDate && !isWithinUpperBound(parsedDate, maxDate)) {\n return { date: parsedDate, error: \"OUTSIDE_UPPER_BOUND\" };\n }\n\n return { date: parsedDate, error: null };\n};\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(\n (props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltip,\n textInputProps,\n description,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate\n ? dayjs(disableBeforeDate).startOf(\"day\").toDate()\n : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate\n ? dayjs(disableAfterDate).startOf(\"day\").toDate()\n : undefined;\n\n const [date, setDate] = useState(\n getInitialDate(value, defaultValue, minDate, maxDate),\n );\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n\n const calendarRef = useRef<HTMLDivElement>(null);\n const datepickerRef = useRef<HTMLDivElement>(null);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const didAutoFormatCompactInputRef = useRef(false);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [forwardedInputRef],\n );\n\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [action],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.currentTarget.value;\n const formattedValue = normalizeInputValue(\n rawValue,\n didAutoFormatCompactInputRef.current,\n );\n\n if (formattedValue !== rawValue) {\n setInputValue(e.currentTarget, formattedValue);\n }\n\n const digits = rawValue.replace(/\\D/g, \"\");\n didAutoFormatCompactInputRef.current =\n rawValue === digits &&\n formattedValue === formatDateString(digits) &&\n formattedValue !== rawValue &&\n parseDateString(formattedValue) !== undefined;\n\n const { date: nextDate, error: nextError } =\n getInputValidationState({\n value: formattedValue,\n minDate,\n maxDate,\n });\n\n if (nextDate && !nextError) {\n setShowCalendar(false);\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, {\n error: nextError,\n value: formattedValue,\n });\n }\n },\n [onChange, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button =\n calendarEl &&\n (calendarEl.querySelector(\n '[aria-pressed=\"true\"]',\n ) as HTMLButtonElement);\n // Make sure the popover-modal is correctly positioned before focusing a button\n // so we avoid accidentally scrolling to the top of the page\n window.requestAnimationFrame(() => button?.focus());\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [showCalendar, action],\n );\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n didAutoFormatCompactInputRef.current = false;\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(\n event as unknown as ChangeEvent<HTMLInputElement>,\n date,\n {\n error: null,\n value: node.value,\n },\n );\n }\n }\n },\n [onChange],\n );\n\n const handleTabOutsideCalendar = useCallback((e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current?.focus();\n }, []);\n\n return (\n <InputGroup\n id={id}\n className={clsx(\"jkl-datepicker\", className)}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltip={tooltip}\n description={description}\n render={(inputProps) => (\n <BaseTextInput\n data-focused={showCalendar ? \"true\" : undefined}\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n actionButton={\n <Popover\n positionReference={inputRef}\n open={showCalendar}\n onOpenChange={() =>\n setShowCalendar(!showCalendar)\n }\n offset={8}\n fitAvailableHeight\n >\n <Popover.Trigger\n {...action}\n data-testid=\"jkl-datepicker__trigger\"\n className=\"jkl-text-input-action-button\"\n title={\n showCalendar\n ? hideCalendarLabel\n : showCalendarLabel\n }\n tabIndex={0}\n onClick={clickCalendar}\n onKeyDown={handleKeyDownAction}\n asChild\n >\n <IconButton>\n <CalendarIcon />\n </IconButton>\n </Popover.Trigger>\n <Popover.Content initialFocus={-1} padding={24}>\n <Calendar\n ref={calendarRef}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </Popover.Content>\n </Popover>\n }\n {...textInputProps}\n {...inputProps}\n aria-invalid={invalid || !!errorLabel}\n />\n )}\n />\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltip","textInputProps","description","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","dayjs","startOf","toDate","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useRef","datepickerRef","iconButtonRef","inputRef","didAutoFormatCompactInputRef","unifiedInputRef","useCallback","instance","current","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleChange","rawValue","currentTarget","formattedValue","shouldStripAutoFormatting","digits","replace","partialCompactDate","formatDateString","partial","rawValueWithoutTrailingPunctuation","compactDateCandidate","length","validCompactDate","shouldRemoveFormatting","normalizeInputValue","input","nativeSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","setInputValue","nextDate","nextError","parsedDate","isWithinLowerBound","isWithinUpperBound","getInputValidationState","clickCalendar","flushSync","calendarEl","button","querySelector","window","requestAnimationFrame","focus","onClick","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","jsx","InputGroup","clsx","ref","render","inputProps","BaseTextInput","type","actionButton","jsxs","Popover","positionReference","open","onOpenChange","offset","fitAvailableHeight","children","Trigger","title","tabIndex","asChild","IconButton","CalendarIcon","Content","initialFocus","padding","Calendar","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),t=require("@floating-ui/react"),n=require("../../../clsx-E3yX_9sL.cjs"),o=require("react"),r=require("../../utilities/getThemeAndSize.cjs");const s=function(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,o.get?o:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}(o),i=s.createContext(null),l=()=>{const e=s.useContext(i);if(null==e)throw new Error("Popover komponenter må brukes innenfor en <Popover /> komponent");return e},a=({children:n,...o})=>{const r=(({open:e,onOpenChange:n,placement:o="bottom-start",strategy:r="absolute",modal:i=!0,offset:l=4,positionReference:a,onPlacementChange:c,matchReferenceWidth:u=!1,
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),t=require("@floating-ui/react"),n=require("../../../clsx-E3yX_9sL.cjs"),o=require("react"),r=require("../../utilities/getThemeAndSize.cjs");const s=function(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,o.get?o:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}(o),i=s.createContext(null),l=()=>{const e=s.useContext(i);if(null==e)throw new Error("Popover komponenter må brukes innenfor en <Popover /> komponent");return e},a=({children:n,...o})=>{const r=(({open:e,onOpenChange:n,placement:o="bottom-start",strategy:r="absolute",modal:i=!0,offset:l=4,positionReference:a,onPlacementChange:c,matchReferenceWidth:u=!1,fitAvailableHeight:d=!1,hoverOptions:f,focusOptions:p,clickOptions:g,roleOptions:m,dismissOptions:h})=>{const[b,x]=s.useState(e),v=e??b,j=n??x,y=t.useFloating({open:v,onOpenChange:j,placement:o,strategy:r,middleware:[t.offset(l),t.flip({padding:d?12:5,fallbackPlacements:["bottom","top"]}),t.shift({padding:12,crossAxis:d}),d&&t.size({padding:12,apply({availableHeight:e,elements:t}){t.floating.style.maxHeight=`${Math.max(0,e)}px`}}),...u?[t.size({apply({rects:e,elements:t}){t.floating.style.width=`${e.reference.width}px`}})]:[]],whileElementsMounted:t.autoUpdate}),O=y.context,P=t.useClick(O,{enabled:!1,...g}),R=t.useHover(O,{enabled:!1,...f}),k=t.useFocus(O,{enabled:!1,...p}),C=t.useDismiss(O,h),F=t.useRole(O,m),w=t.useInteractions([P,C,k,R,F]);return s.useLayoutEffect(()=>{a&&y.refs.setPositionReference(a?.current)},[a,y.refs]),s.useLayoutEffect(()=>{v&&c?.(y.placement)},[v,y.placement,c]),s.useMemo(()=>({open:v,onOpenChange:j,modal:i,fitAvailableHeight:d,...w,...y}),[v,j,i,d,w,y])})({...o});return e.jsx(i.Provider,{value:r,children:n})},c=s.forwardRef(function({children:o,asChild:r=!1,...i},a){const{refs:c,getReferenceProps:u,open:d,onOpenChange:f}=l(),p=o.ref,g=t.useMergeRefs([c.setReference,a,p]);return r&&s.isValidElement(o)?s.cloneElement(o,u({ref:g,...i,...o.props})):e.jsx("button",{ref:g,onClick:()=>f?.(!d),"aria-expanded":d,...u({...i,className:n.clsx("jkl-popover-trigger",i.className)}),children:o})}),u=s.forwardRef(function({style:o,className:i,padding:a=0,initialFocus:c=0,returnFocus:u=!0,...d},f){const{context:p,modal:g,refs:m,open:h,floatingStyles:b,getFloatingProps:x,isPositioned:v,fitAvailableHeight:j}=l(),y=t.useMergeRefs([m.setFloating,f]),O=m.reference.current,{theme:P,size:R}=(C=O)&&"contextElement"in C?r.getThemeAndSize(O.contextElement):r.getThemeAndSize(O),k=s.useRef(null);var C;return s.useEffect(()=>{k.current=p.elements.domReference?.closest("[data-portal]")||document.body},[p.elements.domReference]),h?e.jsx(t.FloatingPortal,{root:k.current,children:e.jsx(t.FloatingFocusManager,{context:p,modal:g,initialFocus:c,returnFocus:u,children:e.jsx("div",{"data-theme":P,"data-size":R,className:n.clsx("jkl jkl-popover",i,{"jkl-popover--fit-available-height":j}),ref:y,style:{...o,...b,"--popover-padding":`var(--jkl-spacing-${a})`,visibility:g||v?"visible":"hidden"},...x(d),children:d.children})})}):null});a.Trigger=c,a.Content=u,exports.Popover=a,exports.default=a;
|
|
2
2
|
//# sourceMappingURL=Popover.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.cjs","sources":["../../../../src/components/popover/Popover.tsx"],"sourcesContent":["import {\n FloatingFocusManager,\n FloatingPortal,\n type ReferenceElement,\n type VirtualElement,\n autoUpdate,\n flip,\n offset,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useInteractions,\n useMergeRefs,\n useRole,\n} from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport * as React from \"react\";\nimport { getThemeAndSize } from \"../../utilities/getThemeAndSize.js\";\nimport type { PopoverOptions } from \"./types.js\";\n\nconst usePopover = ({\n open: _open,\n onOpenChange: _onOpenChange,\n placement = \"bottom-start\",\n strategy = \"absolute\",\n modal = true,\n offset: _offset = 4,\n positionReference,\n onPlacementChange,\n matchReferenceWidth = false,\n hoverOptions,\n focusOptions,\n clickOptions,\n roleOptions,\n dismissOptions,\n}: PopoverOptions) => {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(_open);\n\n const open = _open ?? uncontrolledOpen;\n const onOpenChange = _onOpenChange ?? setUncontrolledOpen;\n\n const data = useFloating({\n open,\n onOpenChange,\n placement,\n strategy,\n middleware: [\n offset(_offset),\n flip({ padding: 5, fallbackPlacements: [\"bottom\", \"top\"] }),\n shift({ padding: 12 }),\n ...(matchReferenceWidth\n ? [\n size({\n apply({ rects, elements }) {\n elements.floating.style.width = `${rects.reference.width}px`;\n },\n }),\n ]\n : []),\n ],\n whileElementsMounted: autoUpdate,\n });\n\n const context = data.context;\n\n const click = useClick(context, {\n enabled: false,\n ...clickOptions,\n });\n const hover = useHover(context, { enabled: false, ...hoverOptions });\n const focus = useFocus(context, { enabled: false, ...focusOptions });\n const dismiss = useDismiss(context, dismissOptions);\n const role = useRole(context, roleOptions);\n\n const interactions = useInteractions([click, dismiss, focus, hover, role]);\n\n React.useLayoutEffect(() => {\n if (positionReference) {\n data.refs.setPositionReference(positionReference?.current);\n }\n }, [positionReference, data.refs]);\n\n // useLayoutEffect (i stedet for useEffect) sikrer at konsumenter får\n // riktig placement før paint — ellers ville første frame bruke default\n // placement og deretter snappe over til den faktiske, noe som gir et\n // synlig \"glitch\" på styling som er placement-avhengig (f.eks. flat side\n // / border-radius på Select-listboxen ved flip).\n React.useLayoutEffect(() => {\n if (!open) return;\n onPlacementChange?.(data.placement);\n }, [open, data.placement, onPlacementChange]);\n\n return React.useMemo(\n () => ({\n open,\n onOpenChange,\n modal,\n ...interactions,\n ...data,\n }),\n [open, onOpenChange, modal, interactions, data],\n );\n};\n\ntype PopoverContextType = ReturnType<typeof usePopover> | null;\n\nconst PopoverContext = React.createContext<PopoverContextType>(null);\n\nconst usePopoverContext = () => {\n const context = React.useContext(PopoverContext);\n\n if (context == null) {\n throw new Error(\n \"Popover komponenter må brukes innenfor en <Popover /> komponent\",\n );\n }\n\n return context;\n};\n\nexport const Popover = ({\n children,\n ...restOptions\n}: {\n children: React.ReactNode;\n} & PopoverOptions) => {\n const popover = usePopover({ ...restOptions });\n return (\n <PopoverContext.Provider value={popover}>\n {children}\n </PopoverContext.Provider>\n );\n};\n\ninterface PopoverTriggerProps {\n children: React.ReactNode;\n /**\n * Rendrer komponenten som child-elementet sitt, og slår sammen egenskaper og props.\n *\n * Default er `false`.\n *\n * @example\n * ```tsx\n * <Component asChild foo=\"bar\">\n * <Child baz=\"qux\" />\n * </Component>\n *\n * // Rendrer følgende:\n * <Child foo=\"bar\" baz=\"qux\" />\n * ```\n */\n asChild?: boolean;\n}\n\nconst PopoverTrigger = React.forwardRef<\n HTMLElement,\n React.HTMLProps<HTMLElement> & PopoverTriggerProps\n>(function PopoverTrigger({ children, asChild = false, ...props }, propRef) {\n const { refs, getReferenceProps, open, onOpenChange } = usePopoverContext();\n const childrenRef = (children as any).ref;\n const ref = useMergeRefs([refs.setReference, propRef, childrenRef]);\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(\n children,\n getReferenceProps({\n ref,\n ...props,\n ...children.props,\n }),\n );\n }\n\n return (\n <button\n ref={ref}\n onClick={() => onOpenChange?.(!open)}\n aria-expanded={open}\n {...getReferenceProps({\n ...props,\n className: clsx(\"jkl-popover-trigger\", props.className),\n })}\n >\n {children}\n </button>\n );\n});\n\ninterface PopoverContentProps {\n /**\n * Padding rundt innholdet i popoveren.\n *\n * Default er `0`.\n */\n padding?: 0 | 8 | 16 | 24;\n /**\n *\n * Angir hvilket element som skal motta fokus ved åpning.\n * Kan være en tabbar index eller en referanse til et element.\"\n *\n * Default er `0`, som betyr at det første fokuserbare elementet i popoveren får fokus.\n * @see https://floating-ui.com/docs/FloatingFocusManager#initialfocus\n */\n initialFocus?: number | React.RefObject<HTMLElement>;\n /**\n * Angir om fokus skal returneres til triggeren når popoveren lukkes.\n *\n * Default er `true`.\n * @see https://floating-ui.com/docs/FloatingFocusManager#returnfocus\n */\n returnFocus?: boolean;\n}\n\n// Er popover-elementet posisjonert i forhold til et annet element enn triggeren?\nconst isCustomPositioned = (\n referenceElement: ReferenceElement,\n): referenceElement is VirtualElement => {\n if (!referenceElement) return false;\n\n return \"contextElement\" in referenceElement;\n};\n\nconst PopoverContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLProps<HTMLDivElement> & PopoverContentProps\n>(function PopoverContent(\n {\n style,\n className,\n padding = 0,\n initialFocus = 0,\n returnFocus = true,\n ...props\n },\n propRef,\n) {\n const {\n context,\n modal,\n refs,\n open,\n floatingStyles,\n getFloatingProps,\n isPositioned,\n } = usePopoverContext();\n const ref = useMergeRefs([refs.setFloating, propRef]);\n\n const referenceElement = refs.reference.current as ReferenceElement;\n\n const { theme, size } = isCustomPositioned(referenceElement)\n ? getThemeAndSize(referenceElement.contextElement)\n : getThemeAndSize(referenceElement);\n\n const floatingPortalRef = React.useRef<HTMLElement | null>(null);\n\n // TODO: Løser et problem hvor nestede portaler ikke \"fester\" seg til det nærmeste portal-elementet. Fjernes når alle komponenter som rendres i en portal tar i bruk popover komponenten da den håndterer dette internt. Issue: https://github.com/fremtind/jokul/issues/4356\n React.useEffect(() => {\n floatingPortalRef.current =\n context.elements.domReference?.closest<HTMLElement>(\n \"[data-portal]\",\n ) || document.body;\n }, [context.elements.domReference]);\n\n if (!open) return null;\n\n return (\n <FloatingPortal root={floatingPortalRef.current}>\n <FloatingFocusManager\n context={context}\n modal={modal}\n initialFocus={initialFocus}\n returnFocus={returnFocus}\n >\n <div\n data-theme={theme}\n data-size={size}\n className={clsx(\"jkl jkl-popover\", className)}\n ref={ref}\n style={\n {\n ...style,\n ...floatingStyles,\n \"--popover-padding\": `var(--jkl-spacing-${padding})`,\n // Skjul popoveren inntil floating-ui har regnet\n // ut første posisjon — ellers blinker den\n // kort i (0,0) før den hopper på plass.\n // Bare for ikke-modale popovere; modale bruker\n // umiddelbar fokus-trap som forutsetter at\n // innholdet er fokuserbart fra første render.\n visibility:\n modal || isPositioned ? \"visible\" : \"hidden\",\n } as React.CSSProperties\n }\n {...getFloatingProps(props)}\n >\n {props.children}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n );\n});\n\nPopover.Trigger = PopoverTrigger;\nPopover.Content = PopoverContent;\n\nexport default Popover;\n"],"names":["PopoverContext","React","createContext","usePopoverContext","context","useContext","Error","Popover","children","restOptions","popover","open","_open","onOpenChange","_onOpenChange","placement","strategy","modal","offset","_offset","positionReference","onPlacementChange","matchReferenceWidth","hoverOptions","focusOptions","clickOptions","roleOptions","dismissOptions","uncontrolledOpen","setUncontrolledOpen","useState","data","useFloating","middleware","flip","padding","fallbackPlacements","shift","size","apply","rects","elements","floating","style","width","reference","whileElementsMounted","autoUpdate","click","useClick","enabled","hover","useHover","focus","useFocus","dismiss","useDismiss","role","useRole","interactions","useInteractions","useLayoutEffect","refs","setPositionReference","current","useMemo","usePopover","Provider","value","PopoverTrigger","forwardRef","asChild","props","propRef","getReferenceProps","childrenRef","ref","useMergeRefs","setReference","isValidElement","cloneElement","jsx","onClick","className","clsx","PopoverContent","initialFocus","returnFocus","floatingStyles","getFloatingProps","isPositioned","setFloating","referenceElement","theme","getThemeAndSize","contextElement","floatingPortalRef","useRef","useEffect","domReference","closest","document","body","FloatingPortal","root","FloatingFocusManager","visibility","Trigger","Content"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Popover.cjs","sources":["../../../../src/components/popover/Popover.tsx"],"sourcesContent":["import {\n FloatingFocusManager,\n FloatingPortal,\n type ReferenceElement,\n type VirtualElement,\n autoUpdate,\n flip,\n offset,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFocus,\n useHover,\n useInteractions,\n useMergeRefs,\n useRole,\n} from \"@floating-ui/react\";\nimport clsx from \"clsx\";\nimport * as React from \"react\";\nimport { getThemeAndSize } from \"../../utilities/getThemeAndSize.js\";\nimport type { PopoverOptions } from \"./types.js\";\n\nconst usePopover = ({\n open: _open,\n onOpenChange: _onOpenChange,\n placement = \"bottom-start\",\n strategy = \"absolute\",\n modal = true,\n offset: _offset = 4,\n positionReference,\n onPlacementChange,\n matchReferenceWidth = false,\n fitAvailableHeight = false,\n hoverOptions,\n focusOptions,\n clickOptions,\n roleOptions,\n dismissOptions,\n}: PopoverOptions) => {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(_open);\n\n const open = _open ?? uncontrolledOpen;\n const onOpenChange = _onOpenChange ?? setUncontrolledOpen;\n\n const data = useFloating({\n open,\n onOpenChange,\n placement,\n strategy,\n middleware: [\n offset(_offset),\n flip({\n padding: fitAvailableHeight ? 12 : 5,\n fallbackPlacements: [\"bottom\", \"top\"],\n }),\n shift({ padding: 12, crossAxis: fitAvailableHeight }),\n fitAvailableHeight &&\n size({\n padding: 12,\n apply({ availableHeight, elements }) {\n elements.floating.style.maxHeight = `${Math.max(0, availableHeight)}px`;\n },\n }),\n ...(matchReferenceWidth\n ? [\n size({\n apply({ rects, elements }) {\n elements.floating.style.width = `${rects.reference.width}px`;\n },\n }),\n ]\n : []),\n ],\n whileElementsMounted: autoUpdate,\n });\n\n const context = data.context;\n\n const click = useClick(context, {\n enabled: false,\n ...clickOptions,\n });\n const hover = useHover(context, { enabled: false, ...hoverOptions });\n const focus = useFocus(context, { enabled: false, ...focusOptions });\n const dismiss = useDismiss(context, dismissOptions);\n const role = useRole(context, roleOptions);\n\n const interactions = useInteractions([click, dismiss, focus, hover, role]);\n\n React.useLayoutEffect(() => {\n if (positionReference) {\n data.refs.setPositionReference(positionReference?.current);\n }\n }, [positionReference, data.refs]);\n\n // useLayoutEffect (i stedet for useEffect) sikrer at konsumenter får\n // riktig placement før paint — ellers ville første frame bruke default\n // placement og deretter snappe over til den faktiske, noe som gir et\n // synlig \"glitch\" på styling som er placement-avhengig (f.eks. flat side\n // / border-radius på Select-listboxen ved flip).\n React.useLayoutEffect(() => {\n if (!open) return;\n onPlacementChange?.(data.placement);\n }, [open, data.placement, onPlacementChange]);\n\n return React.useMemo(\n () => ({\n open,\n onOpenChange,\n modal,\n fitAvailableHeight,\n ...interactions,\n ...data,\n }),\n [open, onOpenChange, modal, fitAvailableHeight, interactions, data],\n );\n};\n\ntype PopoverContextType = ReturnType<typeof usePopover> | null;\n\nconst PopoverContext = React.createContext<PopoverContextType>(null);\n\nconst usePopoverContext = () => {\n const context = React.useContext(PopoverContext);\n\n if (context == null) {\n throw new Error(\n \"Popover komponenter må brukes innenfor en <Popover /> komponent\",\n );\n }\n\n return context;\n};\n\nexport const Popover = ({\n children,\n ...restOptions\n}: {\n children: React.ReactNode;\n} & PopoverOptions) => {\n const popover = usePopover({ ...restOptions });\n return (\n <PopoverContext.Provider value={popover}>\n {children}\n </PopoverContext.Provider>\n );\n};\n\ninterface PopoverTriggerProps {\n children: React.ReactNode;\n /**\n * Rendrer komponenten som child-elementet sitt, og slår sammen egenskaper og props.\n *\n * Default er `false`.\n *\n * @example\n * ```tsx\n * <Component asChild foo=\"bar\">\n * <Child baz=\"qux\" />\n * </Component>\n *\n * // Rendrer følgende:\n * <Child foo=\"bar\" baz=\"qux\" />\n * ```\n */\n asChild?: boolean;\n}\n\nconst PopoverTrigger = React.forwardRef<\n HTMLElement,\n React.HTMLProps<HTMLElement> & PopoverTriggerProps\n>(function PopoverTrigger({ children, asChild = false, ...props }, propRef) {\n const { refs, getReferenceProps, open, onOpenChange } = usePopoverContext();\n const childrenRef = (children as any).ref;\n const ref = useMergeRefs([refs.setReference, propRef, childrenRef]);\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(\n children,\n getReferenceProps({\n ref,\n ...props,\n ...children.props,\n }),\n );\n }\n\n return (\n <button\n ref={ref}\n onClick={() => onOpenChange?.(!open)}\n aria-expanded={open}\n {...getReferenceProps({\n ...props,\n className: clsx(\"jkl-popover-trigger\", props.className),\n })}\n >\n {children}\n </button>\n );\n});\n\ninterface PopoverContentProps {\n /**\n * Padding rundt innholdet i popoveren.\n *\n * Default er `0`.\n */\n padding?: 0 | 8 | 16 | 24;\n /**\n *\n * Angir hvilket element som skal motta fokus ved åpning.\n * Kan være en tabbar index eller en referanse til et element.\"\n *\n * Default er `0`, som betyr at det første fokuserbare elementet i popoveren får fokus.\n * @see https://floating-ui.com/docs/FloatingFocusManager#initialfocus\n */\n initialFocus?: number | React.RefObject<HTMLElement>;\n /**\n * Angir om fokus skal returneres til triggeren når popoveren lukkes.\n *\n * Default er `true`.\n * @see https://floating-ui.com/docs/FloatingFocusManager#returnfocus\n */\n returnFocus?: boolean;\n}\n\n// Er popover-elementet posisjonert i forhold til et annet element enn triggeren?\nconst isCustomPositioned = (\n referenceElement: ReferenceElement,\n): referenceElement is VirtualElement => {\n if (!referenceElement) return false;\n\n return \"contextElement\" in referenceElement;\n};\n\nconst PopoverContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLProps<HTMLDivElement> & PopoverContentProps\n>(function PopoverContent(\n {\n style,\n className,\n padding = 0,\n initialFocus = 0,\n returnFocus = true,\n ...props\n },\n propRef,\n) {\n const {\n context,\n modal,\n refs,\n open,\n floatingStyles,\n getFloatingProps,\n isPositioned,\n fitAvailableHeight,\n } = usePopoverContext();\n const ref = useMergeRefs([refs.setFloating, propRef]);\n\n const referenceElement = refs.reference.current as ReferenceElement;\n\n const { theme, size } = isCustomPositioned(referenceElement)\n ? getThemeAndSize(referenceElement.contextElement)\n : getThemeAndSize(referenceElement);\n\n const floatingPortalRef = React.useRef<HTMLElement | null>(null);\n\n // TODO: Løser et problem hvor nestede portaler ikke \"fester\" seg til det nærmeste portal-elementet. Fjernes når alle komponenter som rendres i en portal tar i bruk popover komponenten da den håndterer dette internt. Issue: https://github.com/fremtind/jokul/issues/4356\n React.useEffect(() => {\n floatingPortalRef.current =\n context.elements.domReference?.closest<HTMLElement>(\n \"[data-portal]\",\n ) || document.body;\n }, [context.elements.domReference]);\n\n if (!open) return null;\n\n return (\n <FloatingPortal root={floatingPortalRef.current}>\n <FloatingFocusManager\n context={context}\n modal={modal}\n initialFocus={initialFocus}\n returnFocus={returnFocus}\n >\n <div\n data-theme={theme}\n data-size={size}\n className={clsx(\"jkl jkl-popover\", className, {\n \"jkl-popover--fit-available-height\": fitAvailableHeight,\n })}\n ref={ref}\n style={\n {\n ...style,\n ...floatingStyles,\n \"--popover-padding\": `var(--jkl-spacing-${padding})`,\n // Skjul popoveren inntil floating-ui har regnet\n // ut første posisjon — ellers blinker den\n // kort i (0,0) før den hopper på plass.\n // Bare for ikke-modale popovere; modale bruker\n // umiddelbar fokus-trap som forutsetter at\n // innholdet er fokuserbart fra første render.\n visibility:\n modal || isPositioned ? \"visible\" : \"hidden\",\n } as React.CSSProperties\n }\n {...getFloatingProps(props)}\n >\n {props.children}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n );\n});\n\nPopover.Trigger = PopoverTrigger;\nPopover.Content = PopoverContent;\n\nexport default Popover;\n"],"names":["PopoverContext","React","createContext","usePopoverContext","context","useContext","Error","Popover","children","restOptions","popover","open","_open","onOpenChange","_onOpenChange","placement","strategy","modal","offset","_offset","positionReference","onPlacementChange","matchReferenceWidth","fitAvailableHeight","hoverOptions","focusOptions","clickOptions","roleOptions","dismissOptions","uncontrolledOpen","setUncontrolledOpen","useState","data","useFloating","middleware","flip","padding","fallbackPlacements","shift","crossAxis","size","apply","availableHeight","elements","floating","style","maxHeight","Math","max","rects","width","reference","whileElementsMounted","autoUpdate","click","useClick","enabled","hover","useHover","focus","useFocus","dismiss","useDismiss","role","useRole","interactions","useInteractions","useLayoutEffect","refs","setPositionReference","current","useMemo","usePopover","Provider","value","PopoverTrigger","forwardRef","asChild","props","propRef","getReferenceProps","childrenRef","ref","useMergeRefs","setReference","isValidElement","cloneElement","jsx","onClick","className","clsx","PopoverContent","initialFocus","returnFocus","floatingStyles","getFloatingProps","isPositioned","setFloating","referenceElement","theme","getThemeAndSize","contextElement","floatingPortalRef","useRef","useEffect","domReference","closest","document","body","FloatingPortal","root","FloatingFocusManager","visibility","Trigger","Content"],"mappings":"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"}
|
|
@@ -75,6 +75,19 @@ export interface PopoverOptions {
|
|
|
75
75
|
* @default false
|
|
76
76
|
*/
|
|
77
77
|
matchReferenceWidth?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Tilpasser popoverens plassering og høyde til det synlige området.
|
|
80
|
+
* Innholdet kan scrolles hvis det ikke får plass.
|
|
81
|
+
*
|
|
82
|
+
* Popoveren kan overlappe elementet den er festet til.
|
|
83
|
+
* Bruk en fast verdi mens popoveren er åpen: Høydebegrensningen fjernes
|
|
84
|
+
* ikke hvis du endrer verdien fra `true` til `false`.
|
|
85
|
+
*
|
|
86
|
+
* @see https://floating-ui.com/docs/shift#crossaxis
|
|
87
|
+
* @see https://floating-ui.com/docs/size
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
fitAvailableHeight?: boolean;
|
|
78
91
|
/**
|
|
79
92
|
* Options for hover-interaksjoner.
|
|
80
93
|
*
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useAnimatedDetails/useAnimatedDetails.cjs"),s=require("./useAnimatedHeight/useAnimatedHeight.cjs"),r=require("./useAnimatedHeight/useAnimatedHeightBetween.cjs"),u=require("./useAnimatedHeight/useAutoAnimateHeight.cjs"),i=require("./useBrowserPreferences/useBrowserPreferences.cjs"),t=require("./useIntersectionObserver/useIntersectionObserver.cjs"),o=require("./useLocalStorage/useLocalStorage.cjs"),n=require("./useMutationObserver/useMutationObserver.cjs"),c=require("./usePreviousValue/usePreviousValue.cjs"),a=require("./useProgressiveImg/useProgressiveImg.cjs"),g=require("./useScreen/useScreen.cjs"),l=require("./useScrollIntoView/useScrollIntoView.cjs"),d=require("./useAriaLiveRegion/useAriaLiveRegion.cjs"),m=require("./useClickOutside/useClickOutside.cjs"),p=require("./useFocusOutside/useFocusOutside.cjs"),v=require("./useElementDimensions/useElementDimensions.cjs"),A=require("./useId/useId.cjs"),j=require("./useKeyListener/useKeyListener.cjs"),x=require("./useListNavigation/useListNavigation.cjs"),q=require("./useSwipeGesture/useSwipeGesture.cjs");exports.useAnimatedDetails=e.useAnimatedDetails,exports.useAnimatedHeight=s.useAnimatedHeight,exports.useAnimatedHeightBetween=r.useAnimatedHeightBetween,exports.useAutoAnimatedHeight=u.useAutoAnimatedHeight,exports.useBrowserPreferences=i.useBrowserPreferences,exports.useIntersectionObserver=t.useIntersectionObserver,exports.useLocalStorage=o.useLocalStorage,exports.useMutationObserver=n.useMutationObserver,exports.usePreviousValue=c.usePreviousValue,exports.useProgressiveImg=a.useProgressiveImg,exports.useScreen=g.useScreen,exports.useScrollIntoView=l.useScrollIntoView,exports.useAriaLiveRegion=d.useAriaLiveRegion,exports.useClickOutside=m.useClickOutside,exports.useFocusOutside=p.useFocusOutside,exports.useElementDimensions=v.useElementDimensions,exports.useId=A.useId,exports.useKeyListener=j.useKeyListener,exports.useListNavigation=x.useListNavigation,exports.
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useAnimatedDetails/useAnimatedDetails.cjs"),s=require("./useAnimatedHeight/useAnimatedHeight.cjs"),r=require("./useAnimatedHeight/useAnimatedHeightBetween.cjs"),u=require("./useAnimatedHeight/useAutoAnimateHeight.cjs"),i=require("./useBrowserPreferences/useBrowserPreferences.cjs"),t=require("./useIntersectionObserver/useIntersectionObserver.cjs"),o=require("./useLocalStorage/useLocalStorage.cjs"),n=require("./useMutationObserver/useMutationObserver.cjs"),c=require("./usePreviousValue/usePreviousValue.cjs"),a=require("./useProgressiveImg/useProgressiveImg.cjs"),g=require("./useScreen/useScreen.cjs"),l=require("./useScrollIntoView/useScrollIntoView.cjs"),d=require("./useAriaLiveRegion/useAriaLiveRegion.cjs"),m=require("./useClickOutside/useClickOutside.cjs"),p=require("./useFocusOutside/useFocusOutside.cjs"),v=require("./useElementDimensions/useElementDimensions.cjs"),A=require("./useId/useId.cjs"),j=require("./useKeyListener/useKeyListener.cjs"),x=require("./useListNavigation/useListNavigation.cjs"),q=require("./useMergeRefs/useMergeRefs.cjs"),S=require("./useSwipeGesture/useSwipeGesture.cjs");exports.useAnimatedDetails=e.useAnimatedDetails,exports.useAnimatedHeight=s.useAnimatedHeight,exports.useAnimatedHeightBetween=r.useAnimatedHeightBetween,exports.useAutoAnimatedHeight=u.useAutoAnimatedHeight,exports.useBrowserPreferences=i.useBrowserPreferences,exports.useIntersectionObserver=t.useIntersectionObserver,exports.useLocalStorage=o.useLocalStorage,exports.useMutationObserver=n.useMutationObserver,exports.usePreviousValue=c.usePreviousValue,exports.useProgressiveImg=a.useProgressiveImg,exports.useScreen=g.useScreen,exports.useScrollIntoView=l.useScrollIntoView,exports.useAriaLiveRegion=d.useAriaLiveRegion,exports.useClickOutside=m.useClickOutside,exports.useFocusOutside=p.useFocusOutside,exports.useElementDimensions=v.useElementDimensions,exports.useId=A.useId,exports.useKeyListener=j.useKeyListener,exports.useListNavigation=x.useListNavigation,exports.useMergeRefs=q.useMergeRefs,exports.useSwipeGesture=S.useSwipeGesture;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -15,4 +15,5 @@ export { useElementDimensions, type Dimensions, } from './useElementDimensions/u
|
|
|
15
15
|
export { useId } from './useId/useId.cjs';
|
|
16
16
|
export { useKeyListener } from './useKeyListener/useKeyListener.cjs';
|
|
17
17
|
export { useListNavigation } from './useListNavigation/useListNavigation.cjs';
|
|
18
|
+
export { useMergeRefs } from './useMergeRefs/useMergeRefs.cjs';
|
|
18
19
|
export { useSwipeGesture, type SwipeChangeHandler, } from './useSwipeGesture/useSwipeGesture.cjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMergeRefs.cjs","sources":["../../../../src/hooks/useMergeRefs/useMergeRefs.ts"],"sourcesContent":["import {\n type ForwardedRef,\n type MutableRefObject,\n type RefCallback,\n useMemo,\n} from \"react\";\nimport { mergeRefs } from \"../../utilities/mergeRefs.js\";\n\n/**\n * Slår sammen flere refs til én callback som bare endres når en av refsene endres.\n * @param refs Liste over refs du vil slå sammen\n * @returns En `RefCallback` du kan sende videre til en komponent/element\n * @example const combinedRef = useMergeRefs(ref, forwardedRef, anotherRef);\n */\nexport function useMergeRefs<T>(\n ...refs: (ForwardedRef<T> | MutableRefObject<T> | undefined)[]\n): RefCallback<T> {\n // biome-ignore lint/correctness/useExhaustiveDependencies: Sammenlign hver ref for seg; [refs] blir ny ved hver rendring.\n return useMemo(() => mergeRefs(...refs), refs);\n}\n"],"names":["refs","useMemo","mergeRefs"],"mappings":"yKAcO,YACAA,GAGH,OAAOC,EAAAA,QAAQ,IAAMC,EAAAA,aAAaF,GAAOA,EAC7C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ForwardedRef, MutableRefObject, RefCallback } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Slår sammen flere refs til én callback som bare endres når en av refsene endres.
|
|
4
|
+
* @param refs Liste over refs du vil slå sammen
|
|
5
|
+
* @returns En `RefCallback` du kan sende videre til en komponent/element
|
|
6
|
+
* @example const combinedRef = useMergeRefs(ref, forwardedRef, anotherRef);
|
|
7
|
+
*/
|
|
8
|
+
export declare function useMergeRefs<T>(...refs: (ForwardedRef<T> | MutableRefObject<T> | undefined)[]): RefCallback<T>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../../index-CaISwoxr.cjs"),r=require("./formatters/util/formatNumber.cjs"),s=require("./formatters/util/parseNumber.cjs"),t=require("./formatters/util/registerWithMask.cjs"),i=require("./formatters/avstand/formatAvstand.cjs"),a=require("./formatters/bytes/formatBytes.cjs"),o=require("./formatters/date/formatDate.cjs"),m=require("./formatters/fodselsnummer/formatFodselsnummer.cjs"),n=require("./formatters/organisasjonsnummer/formatOrganisasjonsnummer.cjs"),u=require("./formatters/kontonummer/formatKontonummer.cjs"),l=require("./formatters/kortnummer/formatKortnummer.cjs"),d=require("./formatters/telefonnummer/formatTelefonnummer.cjs"),p=require("./formatters/valuta/formatValuta.cjs"),f=require("./getThemeAndSize.cjs"),g=require("./mergeRefs.cjs"),x=require("./polymorphism/mergeProps.cjs"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../../index-CaISwoxr.cjs"),r=require("./formatters/util/formatNumber.cjs"),s=require("./formatters/util/parseNumber.cjs"),t=require("./formatters/util/registerWithMask.cjs"),i=require("./formatters/avstand/formatAvstand.cjs"),a=require("./formatters/bytes/formatBytes.cjs"),o=require("./formatters/date/formatDate.cjs"),m=require("./formatters/fodselsnummer/formatFodselsnummer.cjs"),n=require("./formatters/organisasjonsnummer/formatOrganisasjonsnummer.cjs"),u=require("./formatters/kontonummer/formatKontonummer.cjs"),l=require("./formatters/kortnummer/formatKortnummer.cjs"),d=require("./formatters/telefonnummer/formatTelefonnummer.cjs"),p=require("./formatters/valuta/formatValuta.cjs"),f=require("./getThemeAndSize.cjs"),g=require("./mergeRefs.cjs"),x=require("../hooks/useMergeRefs/useMergeRefs.cjs"),c=require("./polymorphism/mergeProps.cjs"),E=require("./polymorphism/SlotComponent.cjs"),j=require("./tabListener.cjs"),M=require("./validators/isValidEpost/isValidEpost.cjs"),h=require("./validators/isValidTelefonnummer/isValidTelefonnummer.cjs"),R=require("./validators/isValidRegistreringsnummer/isValidRegistreringsnummer.cjs"),V=require("./validators/isValidChassisnummer/isValidChassisnummer.cjs"),N=require("./validators/isValidDogId/isValidDogId.cjs"),q=require("./validators/isExactLength/isExactLength.cjs"),O=require("./validators/isInteger/isInteger.cjs"),T=require("./validators/isValidFodselsnummer/isValidFodselsnummer.cjs"),S=require("./validators/isValidOrganisasjonsnummer/isValidOrganisasjonsnummer.cjs"),v=require("./validators/isValidName/isValidName.cjs"),W=require("./validators/hasMinimumWords/hasMinimumWords.cjs"),k=require("./validators/hasNoIllegalCharacters/hasNoIllegalCharacters.cjs"),I=require("./valuePair.cjs"),K=require("./types.cjs");exports.unicode=e.unicode,exports.formatNumber=r.formatNumber,exports.parseNumber=s.parseNumber,exports.registerWithFodselsnummerMask=t.registerWithFodselsnummerMask,exports.registerWithKontonummerMask=t.registerWithKontonummerMask,exports.registerWithKortnummerMask=t.registerWithKortnummerMask,exports.registerWithMasks=t.registerWithMasks,exports.registerWithTelefonnummerMask=t.registerWithTelefonnummerMask,exports.formatAvstand=i.formatAvstand,exports.formatBytes=a.formatBytes,exports.formatDate=o.formatDate,exports.FODSELSNUMMER_REGEX=m.FODSELSNUMMER_REGEX,exports.formatFodselsnummer=m.formatFodselsnummer,exports.ORGANISASJONSNUMMER_REGEX=n.ORGANISASJONSNUMMER_REGEX,exports.formatOrganisasjonsnummer=n.formatOrganisasjonsnummer,exports.KONTONUMMER_REGEX=u.KONTONUMMER_REGEX,exports.formatKontonummer=u.formatKontonummer,exports.KORTNUMMER_REGEX=l.KORTNUMMER_REGEX,exports.formatKortnummer=l.formatKortnummer,exports.TELEFONNUMMER_REGEX=d.TELEFONNUMMER_REGEX,exports.formatTelefonnummer=d.formatTelefonnummer,exports.formatValuta=p.formatValuta,exports.getThemeAndSize=f.getThemeAndSize,exports.mergeRefs=g.mergeRefs,exports.useMergeRefs=x.useMergeRefs,exports.mergeProps=c.mergeProps,exports.SlotComponent=E.SlotComponent,exports.initTabListener=j.initTabListener,exports.isValidEpost=M.isValidEpost,exports.isValidTelefonnummer=h.isValidTelefonnummer,exports.isValidRegistreringsnummer=R.isValidRegistreringsnummer,exports.isValidChassisnummer=V.isValidChassisnummer,exports.isValidDogId=N.isValidDogId,exports.isExactLength=q.isExactLength,exports.isInteger=O.isInteger,exports.isValidFodselsnummer=T.isValidFodselsnummer,exports.isValidOrganisasjonsnummer=S.isValidOrganisasjonsnummer,exports.isValidName=v.isValidName,exports.hasMinimumWords=W.hasMinimumWords,exports.hasNoIllegalCharacters=k.hasNoIllegalCharacters,exports.getValuePair=I.getValuePair,exports.BRANDS=K.BRANDS;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -2,6 +2,7 @@ export * from './constants/index.cjs';
|
|
|
2
2
|
export * from './formatters/index.cjs';
|
|
3
3
|
export * from './getThemeAndSize.cjs';
|
|
4
4
|
export * from './mergeRefs.cjs';
|
|
5
|
+
export { useMergeRefs } from '../hooks/useMergeRefs/useMergeRefs.cjs';
|
|
5
6
|
export * from './polymorphism/index.cjs';
|
|
6
7
|
export * from './tabListener.cjs';
|
|
7
8
|
export * from './validators/index.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"})
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),exports.mergeRefs=function(...e){return function(t){for(const o of e)o&&("function"==typeof o?o(t):o&&(o.current=t))}};
|
|
2
2
|
//# sourceMappingURL=mergeRefs.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergeRefs.cjs","sources":["../../../src/utilities/mergeRefs.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"mergeRefs.cjs","sources":["../../../src/utilities/mergeRefs.ts"],"sourcesContent":["import type { ForwardedRef, MutableRefObject, RefCallback } from \"react\";\n\n/**\n * Slår sammen flere refs til én, for eksempel hvis du har både en\n * egen ref i en komponent og også vil kunne ta inn en forwardRef\n * fra brukeren av komponenten.\n * @param refs Liste over refs du vil slå sammen\n * @returns En `RefCallback` du kan sende videre til en komponent/element\n * @example\n * const ref = useRef<HTMLElement>(null);\n * const combinedRef = mergeRefs(ref, forwardedRef, anotherRef);\n *\n * return <div ref={combinedRef} {...props} />;\n */\nexport function mergeRefs<T>(\n ...refs: (ForwardedRef<T> | MutableRefObject<T> | undefined)[]\n): RefCallback<T> {\n return function combinedRef(instance: T | null) {\n for (const ref of refs) {\n if (!ref) continue;\n\n if (typeof ref === \"function\") {\n ref(instance);\n } else if (ref) {\n ref.current = instance;\n }\n }\n };\n}\n"],"names":["refs","instance","ref","current"],"mappings":"kGAcO,YACAA,GAEH,OAAO,SAAqBC,GACxB,IAAA,MAAWC,KAAOF,EACTE,IAEc,mBAARA,EACPA,EAAID,GACGC,IACPA,EAAIC,QAAUF,GAG1B,CACJ"}
|
|
@@ -12,11 +12,3 @@ import { ForwardedRef, MutableRefObject, RefCallback } from 'react';
|
|
|
12
12
|
* return <div ref={combinedRef} {...props} />;
|
|
13
13
|
*/
|
|
14
14
|
export declare function mergeRefs<T>(...refs: (ForwardedRef<T> | MutableRefObject<T> | undefined)[]): RefCallback<T>;
|
|
15
|
-
/**
|
|
16
|
-
* Gjør det samme som {@link mergeRefs}, men wrappet i en `useMemo`, hvis du
|
|
17
|
-
* vil unngå å lage en ny funksjon ved hver render. Som regel ikke nødvendig.
|
|
18
|
-
* @param refs Liste over refs du vil slå sammen
|
|
19
|
-
* @returns En `RefCallback` du kan sende videre til en komponent/element
|
|
20
|
-
* @example const combinedRef = useMergeRefs(ref, forwardedRef, anotherRef);
|
|
21
|
-
*/
|
|
22
|
-
export declare function useMergeRefs<T>(...refs: (ForwardedRef<T> | MutableRefObject<T> | undefined)[]): RefCallback<T>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as r}from"../../../clsx-BeLtu-UY.js";import{d as a,g as o}from"../../../utils-C5AH4j8B.js";import{forwardRef as n,useState as l,useRef as s,useCallback as i}from"react";import{flushSync as u}from"react-dom";import{formatDateString as c}from"../../utilities/formatters/date/formatDate.js";import{IconButton as d}from"../icon-button/IconButton.js";import{CalendarIcon as p}from"../icon/icons/CalendarIcon.js";import{InputGroup as m}from"../input-group/InputGroup.js";import{Popover as f}from"../popover/Popover.js";import{BaseTextInput as v}from"../text-input/BaseTextInput.js";import{Calendar as D}from"./internal/Calendar.js";import{parseDateString as h,formatInput as b}from"./utils.js";import{isWithinLowerBound as g,isWithinUpperBound as k}from"./validation.js";const j=n((n,j)=>{const{"data-testautoid":y,id:L,className:w="",label:x="Velg dato",labelProps:C,defaultValue:I,defaultShow:O=!1,value:P,disableBeforeDate:T,disableAfterDate:B,yearsToShow:E,name:_,helpLabel:S,errorLabel:N,invalid:R,days:U,months:V,monthLabel:F,yearLabel:
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as r}from"../../../clsx-BeLtu-UY.js";import{d as a,g as o}from"../../../utils-C5AH4j8B.js";import{forwardRef as n,useState as l,useRef as s,useCallback as i}from"react";import{flushSync as u}from"react-dom";import{formatDateString as c}from"../../utilities/formatters/date/formatDate.js";import{IconButton as d}from"../icon-button/IconButton.js";import{CalendarIcon as p}from"../icon/icons/CalendarIcon.js";import{InputGroup as m}from"../input-group/InputGroup.js";import{Popover as f}from"../popover/Popover.js";import{BaseTextInput as v}from"../text-input/BaseTextInput.js";import{Calendar as D}from"./internal/Calendar.js";import{parseDateString as h,formatInput as b}from"./utils.js";import{isWithinLowerBound as g,isWithinUpperBound as k}from"./validation.js";const j=n((n,j)=>{const{"data-testautoid":y,id:L,className:w="",label:x="Velg dato",labelProps:C,defaultValue:I,defaultShow:O=!1,value:P,disableBeforeDate:T,disableAfterDate:B,yearsToShow:E,name:_,helpLabel:S,errorLabel:N,invalid:R,days:U,months:V,monthLabel:F,yearLabel:A,placeholder:H="dd.mm.åååå",width:K="11.25rem",onChange:W,onBlur:G,onFocus:M,onKeyDown:q,action:$,showCalendarLabel:z="Åpne kalender",hideCalendarLabel:J="Lukk kalender",supportLabelProps:Q,tooltip:X,textInputProps:Y,description:Z,...ee}=n;"production"!==process.env.NODE_ENV&&P&&I&&console.warn("DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.");const te=h(T),re=te?a(te).startOf("day").toDate():void 0,ae=h(B),oe=ae?a(ae).startOf("day").toDate():void 0,[ne,le]=l(o(P,I,re,oe)),[se,ie]=l(null),[ue,ce]=l(O),de=s(null),pe=s(null),me=s(null),fe=s(null),ve=s(!1),De=i(e=>{fe.current=e,j&&("function"==typeof j?j(e):j.current=e)},[j]),he=i(e=>{M&&pe.current&&(pe.current.contains(e.relatedTarget)||M(e,ne,{error:se,value:e.target.value}))},[M,ne,se]),be=i(e=>{G&&G(e,ne,{error:se,value:e.target.value})},[G,ne,se]),ge=i(e=>{"Escape"===e.key&&(ce(!1),e.preventDefault(),e.stopPropagation()),$?.onKeyDown&&$.onKeyDown(e)},[$]),ke=i(e=>{const t=e.currentTarget.value,r=((e,t)=>{const r=e.replace(/\D/g,""),a=c(r,{partial:!0}),o=e.replace(/\D+$/,""),n=8===r.length?c(r):e,l=h(n)?n:null,s=t&&e!==r&&o===a&&void 0===h(e)&&null===l;return l??(s?r:e)})(t,ve.current);r!==t&&((e,t)=>{const r=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value")?.set;r?r.call(e,t):e.value=t})(e.currentTarget,r);const a=t.replace(/\D/g,"");ve.current=t===a&&r===c(a)&&r!==t&&void 0!==h(r);const{date:o,error:n}=(({value:e,minDate:t,maxDate:r})=>{if(!e)return{date:null,error:null};const a=h(e);return a?t&&!g(a,t)?{date:a,error:"OUTSIDE_LOWER_BOUND"}:r&&!k(a,r)?{date:a,error:"OUTSIDE_UPPER_BOUND"}:{date:a,error:null}:{date:null,error:"WRONG_FORMAT"}})({value:r,minDate:re,maxDate:oe});o&&!n&&ce(!1),ie(n),le(o),W&&W(e,o,{error:n,value:r})},[W,re,oe]),je=i(e=>{u(()=>{ce(!ue)});const t=de.current,r=t&&t.querySelector('[aria-pressed="true"]');window.requestAnimationFrame(()=>r?.focus()),$?.onClick&&$.onClick(e)},[ue,$]),ye=i(({date:e})=>{if(ce(!1),le(e),fe.current){const t=fe.current;ve.current=!1,t.value=b(e);const r=document.createEvent("HTMLEvents");r.initEvent("input",!0,!1),t.dispatchEvent(r),t.focus(),W&&W(r,e,{error:null,value:t.value})}},[W]),Le=i(e=>{e.preventDefault(),ce(!1),me.current?.focus()},[]);return e(m,{id:L,className:r("jkl-datepicker",w),...ee,ref:pe,label:x,labelProps:C,helpLabel:S,errorLabel:N,supportLabelProps:Q,tooltip:X,description:Z,render:r=>e(v,{"data-focused":ue?"true":void 0,ref:De,"data-testid":"jkl-datepicker__input","data-testautoid":y,className:"jkl-datepicker__input",name:_,defaultValue:I,value:P,type:"text",placeholder:H,width:K,onFocus:he,onBlur:be,onChange:ke,actionButton:t(f,{positionReference:fe,open:ue,onOpenChange:()=>ce(!ue),offset:8,fitAvailableHeight:!0,children:[e(f.Trigger,{...$,"data-testid":"jkl-datepicker__trigger",className:"jkl-text-input-action-button",title:ue?J:z,tabIndex:0,onClick:je,onKeyDown:ge,asChild:!0,children:e(d,{children:e(p,{})})}),e(f.Content,{initialFocus:-1,padding:24,children:e(D,{ref:de,date:ne,minDate:re,maxDate:oe,days:U,months:V,monthLabel:F,yearLabel:A,yearsToShow:E,onDateSelected:ye,onTabOutside:Le})})]}),...Y,...r,"aria-invalid":R||!!N})})});j.displayName="DatePicker";export{j as DatePicker};
|
|
2
2
|
//# sourceMappingURL=DatePicker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatePicker.js","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport React, {\n type ChangeEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { formatDateString } from \"../../utilities/formatters/date/formatDate.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CalendarIcon } from \"../icon/icons/CalendarIcon.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport Popover from \"../popover/Popover.js\";\nimport { BaseTextInput } from \"../text-input/BaseTextInput.js\";\nimport { Calendar } from \"./internal/Calendar.js\";\nimport { type DateInfo, getInitialDate } from \"./internal/utils.js\";\nimport type { DatePickerProps, DateValidationError } from \"./types.js\";\nimport { formatInput, parseDateString } from \"./utils.js\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation.js\";\n\nconst setInputValue = (input: HTMLInputElement, value: string) => {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set;\n\n if (nativeSetter) {\n nativeSetter.call(input, value);\n } else {\n input.value = value;\n }\n};\n\nconst normalizeInputValue = (\n rawValue: string,\n shouldStripAutoFormatting: boolean,\n) => {\n const digits = rawValue.replace(/\\D/g, \"\");\n const partialCompactDate = formatDateString(digits, {\n partial: true,\n });\n const rawValueWithoutTrailingPunctuation = rawValue.replace(/\\D+$/, \"\");\n const compactDateCandidate =\n digits.length === 8 ? formatDateString(digits) : rawValue;\n const validCompactDate = parseDateString(compactDateCandidate)\n ? compactDateCandidate\n : null;\n const shouldRemoveFormatting =\n shouldStripAutoFormatting &&\n rawValue !== digits &&\n rawValueWithoutTrailingPunctuation === partialCompactDate &&\n parseDateString(rawValue) === undefined &&\n validCompactDate === null;\n\n return validCompactDate ?? (shouldRemoveFormatting ? digits : rawValue);\n};\n\nconst getInputValidationState = ({\n value,\n minDate,\n maxDate,\n}: {\n value: string;\n minDate?: Date;\n maxDate?: Date;\n}): { date: Date | null; error: DateValidationError | null } => {\n if (!value) {\n return { date: null, error: null };\n }\n\n const parsedDate = parseDateString(value);\n\n if (!parsedDate) {\n return { date: null, error: \"WRONG_FORMAT\" };\n }\n\n if (minDate && !isWithinLowerBound(parsedDate, minDate)) {\n return { date: parsedDate, error: \"OUTSIDE_LOWER_BOUND\" };\n }\n\n if (maxDate && !isWithinUpperBound(parsedDate, maxDate)) {\n return { date: parsedDate, error: \"OUTSIDE_UPPER_BOUND\" };\n }\n\n return { date: parsedDate, error: null };\n};\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(\n (props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltip,\n textInputProps,\n description,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate\n ? dayjs(disableBeforeDate).startOf(\"day\").toDate()\n : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate\n ? dayjs(disableAfterDate).startOf(\"day\").toDate()\n : undefined;\n\n const [date, setDate] = useState(\n getInitialDate(value, defaultValue, minDate, maxDate),\n );\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n\n const calendarRef = useRef<HTMLDivElement>(null);\n const datepickerRef = useRef<HTMLDivElement>(null);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const didAutoFormatCompactInputRef = useRef(false);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [forwardedInputRef],\n );\n\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [action],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.currentTarget.value;\n const formattedValue = normalizeInputValue(\n rawValue,\n didAutoFormatCompactInputRef.current,\n );\n\n if (formattedValue !== rawValue) {\n setInputValue(e.currentTarget, formattedValue);\n }\n\n const digits = rawValue.replace(/\\D/g, \"\");\n didAutoFormatCompactInputRef.current =\n rawValue === digits &&\n formattedValue === formatDateString(digits) &&\n formattedValue !== rawValue &&\n parseDateString(formattedValue) !== undefined;\n\n const { date: nextDate, error: nextError } =\n getInputValidationState({\n value: formattedValue,\n minDate,\n maxDate,\n });\n\n if (nextDate && !nextError) {\n setShowCalendar(false);\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, {\n error: nextError,\n value: formattedValue,\n });\n }\n },\n [onChange, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button =\n calendarEl &&\n (calendarEl.querySelector(\n '[aria-pressed=\"true\"]',\n ) as HTMLButtonElement);\n // Make sure the popover-modal is correctly positioned before focusing a button\n // so we avoid accidentally scrolling to the top of the page\n window.requestAnimationFrame(() => button?.focus());\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [showCalendar, action],\n );\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n didAutoFormatCompactInputRef.current = false;\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(\n event as unknown as ChangeEvent<HTMLInputElement>,\n date,\n {\n error: null,\n value: node.value,\n },\n );\n }\n }\n },\n [onChange],\n );\n\n const handleTabOutsideCalendar = useCallback((e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current?.focus();\n }, []);\n\n return (\n <InputGroup\n id={id}\n className={clsx(\"jkl-datepicker\", className)}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltip={tooltip}\n description={description}\n render={(inputProps) => (\n <BaseTextInput\n data-focused={showCalendar ? \"true\" : undefined}\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n actionButton={\n <Popover\n positionReference={inputRef}\n open={showCalendar}\n onOpenChange={() =>\n setShowCalendar(!showCalendar)\n }\n offset={8}\n >\n <Popover.Trigger\n {...action}\n data-testid=\"jkl-datepicker__trigger\"\n className=\"jkl-text-input-action-button\"\n title={\n showCalendar\n ? hideCalendarLabel\n : showCalendarLabel\n }\n tabIndex={0}\n onClick={clickCalendar}\n onKeyDown={handleKeyDownAction}\n asChild\n >\n <IconButton>\n <CalendarIcon />\n </IconButton>\n </Popover.Trigger>\n <Popover.Content initialFocus={-1} padding={24}>\n <Calendar\n ref={calendarRef}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </Popover.Content>\n </Popover>\n }\n {...textInputProps}\n {...inputProps}\n aria-invalid={invalid || !!errorLabel}\n />\n )}\n />\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltip","textInputProps","description","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","dayjs","startOf","toDate","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useRef","datepickerRef","iconButtonRef","inputRef","didAutoFormatCompactInputRef","unifiedInputRef","useCallback","instance","current","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleChange","rawValue","currentTarget","formattedValue","shouldStripAutoFormatting","digits","replace","partialCompactDate","formatDateString","partial","rawValueWithoutTrailingPunctuation","compactDateCandidate","length","validCompactDate","shouldRemoveFormatting","normalizeInputValue","input","nativeSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","setInputValue","nextDate","nextError","parsedDate","isWithinLowerBound","isWithinUpperBound","getInputValidationState","clickCalendar","flushSync","calendarEl","button","querySelector","window","requestAnimationFrame","focus","onClick","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","jsx","InputGroup","clsx","ref","render","inputProps","BaseTextInput","type","actionButton","jsxs","Popover","positionReference","open","onOpenChange","offset","children","Trigger","title","tabIndex","asChild","IconButton","CalendarIcon","Content","initialFocus","padding","Calendar","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatePicker.js","sources":["../../../../src/components/datepicker/DatePicker.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport React, {\n type ChangeEvent,\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n forwardRef,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { formatDateString } from \"../../utilities/formatters/date/formatDate.js\";\nimport { IconButton } from \"../icon-button/IconButton.js\";\nimport { CalendarIcon } from \"../icon/icons/CalendarIcon.js\";\nimport { InputGroup } from \"../input-group/InputGroup.js\";\nimport Popover from \"../popover/Popover.js\";\nimport { BaseTextInput } from \"../text-input/BaseTextInput.js\";\nimport { Calendar } from \"./internal/Calendar.js\";\nimport { type DateInfo, getInitialDate } from \"./internal/utils.js\";\nimport type { DatePickerProps, DateValidationError } from \"./types.js\";\nimport { formatInput, parseDateString } from \"./utils.js\";\nimport { isWithinLowerBound, isWithinUpperBound } from \"./validation.js\";\n\nconst setInputValue = (input: HTMLInputElement, value: string) => {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n \"value\",\n )?.set;\n\n if (nativeSetter) {\n nativeSetter.call(input, value);\n } else {\n input.value = value;\n }\n};\n\nconst normalizeInputValue = (\n rawValue: string,\n shouldStripAutoFormatting: boolean,\n) => {\n const digits = rawValue.replace(/\\D/g, \"\");\n const partialCompactDate = formatDateString(digits, {\n partial: true,\n });\n const rawValueWithoutTrailingPunctuation = rawValue.replace(/\\D+$/, \"\");\n const compactDateCandidate =\n digits.length === 8 ? formatDateString(digits) : rawValue;\n const validCompactDate = parseDateString(compactDateCandidate)\n ? compactDateCandidate\n : null;\n const shouldRemoveFormatting =\n shouldStripAutoFormatting &&\n rawValue !== digits &&\n rawValueWithoutTrailingPunctuation === partialCompactDate &&\n parseDateString(rawValue) === undefined &&\n validCompactDate === null;\n\n return validCompactDate ?? (shouldRemoveFormatting ? digits : rawValue);\n};\n\nconst getInputValidationState = ({\n value,\n minDate,\n maxDate,\n}: {\n value: string;\n minDate?: Date;\n maxDate?: Date;\n}): { date: Date | null; error: DateValidationError | null } => {\n if (!value) {\n return { date: null, error: null };\n }\n\n const parsedDate = parseDateString(value);\n\n if (!parsedDate) {\n return { date: null, error: \"WRONG_FORMAT\" };\n }\n\n if (minDate && !isWithinLowerBound(parsedDate, minDate)) {\n return { date: parsedDate, error: \"OUTSIDE_LOWER_BOUND\" };\n }\n\n if (maxDate && !isWithinUpperBound(parsedDate, maxDate)) {\n return { date: parsedDate, error: \"OUTSIDE_UPPER_BOUND\" };\n }\n\n return { date: parsedDate, error: null };\n};\n\nexport const DatePicker = forwardRef<HTMLInputElement, DatePickerProps>(\n (props, forwardedInputRef) => {\n const {\n \"data-testautoid\": testAutoId,\n id,\n className = \"\",\n label = \"Velg dato\",\n labelProps,\n defaultValue,\n defaultShow = false,\n value,\n disableBeforeDate: disableBefore,\n disableAfterDate: disableAfter,\n yearsToShow,\n name,\n helpLabel,\n errorLabel,\n invalid,\n days,\n months,\n monthLabel,\n yearLabel,\n placeholder = \"dd.mm.åååå\",\n width = \"11.25rem\",\n onChange,\n onBlur,\n onFocus,\n onKeyDown,\n action,\n showCalendarLabel = \"Åpne kalender\",\n hideCalendarLabel = \"Lukk kalender\",\n supportLabelProps,\n tooltip,\n textInputProps,\n description,\n ...rest\n } = props;\n\n if (process.env.NODE_ENV !== \"production\" && value && defaultValue) {\n console.warn(\n \"DatePicker må enten være controlled eller uncontrolled. Hvis du bruker defaultValue og value sammen vil defaultValue bli ignorert.\",\n );\n }\n /// Input state\n\n const disableBeforeDate = parseDateString(disableBefore);\n const minDate = disableBeforeDate\n ? dayjs(disableBeforeDate).startOf(\"day\").toDate()\n : undefined;\n const disableAfterDate = parseDateString(disableAfter);\n const maxDate = disableAfterDate\n ? dayjs(disableAfterDate).startOf(\"day\").toDate()\n : undefined;\n\n const [date, setDate] = useState(\n getInitialDate(value, defaultValue, minDate, maxDate),\n );\n const [error, setError] = useState<DateValidationError | null>(null);\n\n /// Calendar state\n\n const [showCalendar, setShowCalendar] = useState(defaultShow);\n\n const calendarRef = useRef<HTMLDivElement>(null);\n const datepickerRef = useRef<HTMLDivElement>(null);\n\n /// Input events\n\n const iconButtonRef = useRef<HTMLButtonElement | null>(null);\n const inputRef = useRef<HTMLInputElement | null>(null);\n const didAutoFormatCompactInputRef = useRef(false);\n\n // Hjelper for å gjøre det enklere å både forwarde refen men også bruke den selv internt\n const unifiedInputRef = useCallback(\n (instance: HTMLInputElement | null) => {\n inputRef.current = instance;\n if (forwardedInputRef) {\n if (typeof forwardedInputRef === \"function\") {\n forwardedInputRef(instance);\n } else {\n forwardedInputRef.current = instance;\n }\n }\n },\n [forwardedInputRef],\n );\n\n const handleFocus = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (!onFocus || !datepickerRef.current) {\n return;\n }\n\n const nextFocusIsInside = datepickerRef.current.contains(\n e.relatedTarget as Node,\n );\n if (!nextFocusIsInside) {\n onFocus(e, date, { error, value: e.target.value });\n }\n },\n [onFocus, date, error],\n );\n\n const handleBlur = useCallback(\n (e: FocusEvent<HTMLInputElement>) => {\n if (onBlur) {\n onBlur(e, date, { error, value: e.target.value });\n }\n },\n [onBlur, date, error],\n );\n\n const handleKeyDownAction = useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === \"Escape\") {\n setShowCalendar(false);\n e.preventDefault();\n e.stopPropagation();\n }\n\n if (action?.onKeyDown) {\n action.onKeyDown(e);\n }\n },\n [action],\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const rawValue = e.currentTarget.value;\n const formattedValue = normalizeInputValue(\n rawValue,\n didAutoFormatCompactInputRef.current,\n );\n\n if (formattedValue !== rawValue) {\n setInputValue(e.currentTarget, formattedValue);\n }\n\n const digits = rawValue.replace(/\\D/g, \"\");\n didAutoFormatCompactInputRef.current =\n rawValue === digits &&\n formattedValue === formatDateString(digits) &&\n formattedValue !== rawValue &&\n parseDateString(formattedValue) !== undefined;\n\n const { date: nextDate, error: nextError } =\n getInputValidationState({\n value: formattedValue,\n minDate,\n maxDate,\n });\n\n if (nextDate && !nextError) {\n setShowCalendar(false);\n }\n\n setError(nextError);\n setDate(nextDate);\n\n if (onChange) {\n onChange(e, nextDate, {\n error: nextError,\n value: formattedValue,\n });\n }\n },\n [onChange, minDate, maxDate],\n );\n\n /// Calendar events\n\n const clickCalendar = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n flushSync(() => {\n setShowCalendar(!showCalendar);\n });\n\n const calendarEl = calendarRef.current;\n const button =\n calendarEl &&\n (calendarEl.querySelector(\n '[aria-pressed=\"true\"]',\n ) as HTMLButtonElement);\n // Make sure the popover-modal is correctly positioned before focusing a button\n // so we avoid accidentally scrolling to the top of the page\n window.requestAnimationFrame(() => button?.focus());\n\n if (action?.onClick) {\n action.onClick(e);\n }\n },\n [showCalendar, action],\n );\n\n const handleClickCalendarDay = useCallback(\n ({ date }: DateInfo) => {\n setShowCalendar(false);\n setDate(date);\n\n if (inputRef.current) {\n const node = inputRef.current;\n\n didAutoFormatCompactInputRef.current = false;\n node.value = formatInput(date);\n\n // Simulér et change-event så APIet blir så likt som mulig en endring av inputfeltet\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"input\", true, false);\n node.dispatchEvent(event);\n\n node.focus();\n\n if (onChange) {\n // Det er ikke helt sant at dette er et React.SyntheticEvent, men it's fine – probably?\n // Den har tingene man kan forvente, men hvis du gjør serdeles fancy ting med events\n // så kan det hende du må utvide denne for å dekke behovet ditt.\n onChange(\n event as unknown as ChangeEvent<HTMLInputElement>,\n date,\n {\n error: null,\n value: node.value,\n },\n );\n }\n }\n },\n [onChange],\n );\n\n const handleTabOutsideCalendar = useCallback((e: KeyboardEvent) => {\n e.preventDefault();\n setShowCalendar(false);\n iconButtonRef.current?.focus();\n }, []);\n\n return (\n <InputGroup\n id={id}\n className={clsx(\"jkl-datepicker\", className)}\n {...rest}\n ref={datepickerRef}\n label={label}\n labelProps={labelProps}\n helpLabel={helpLabel}\n errorLabel={errorLabel}\n supportLabelProps={supportLabelProps}\n tooltip={tooltip}\n description={description}\n render={(inputProps) => (\n <BaseTextInput\n data-focused={showCalendar ? \"true\" : undefined}\n ref={unifiedInputRef}\n data-testid=\"jkl-datepicker__input\"\n data-testautoid={testAutoId}\n className=\"jkl-datepicker__input\"\n name={name}\n defaultValue={defaultValue}\n value={value}\n type=\"text\"\n placeholder={placeholder}\n width={width}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onChange={handleChange}\n actionButton={\n <Popover\n positionReference={inputRef}\n open={showCalendar}\n onOpenChange={() =>\n setShowCalendar(!showCalendar)\n }\n offset={8}\n fitAvailableHeight\n >\n <Popover.Trigger\n {...action}\n data-testid=\"jkl-datepicker__trigger\"\n className=\"jkl-text-input-action-button\"\n title={\n showCalendar\n ? hideCalendarLabel\n : showCalendarLabel\n }\n tabIndex={0}\n onClick={clickCalendar}\n onKeyDown={handleKeyDownAction}\n asChild\n >\n <IconButton>\n <CalendarIcon />\n </IconButton>\n </Popover.Trigger>\n <Popover.Content initialFocus={-1} padding={24}>\n <Calendar\n ref={calendarRef}\n date={date}\n minDate={minDate}\n maxDate={maxDate}\n days={days}\n months={months}\n monthLabel={monthLabel}\n yearLabel={yearLabel}\n yearsToShow={yearsToShow}\n onDateSelected={handleClickCalendarDay}\n onTabOutside={handleTabOutsideCalendar}\n />\n </Popover.Content>\n </Popover>\n }\n {...textInputProps}\n {...inputProps}\n aria-invalid={invalid || !!errorLabel}\n />\n )}\n />\n );\n },\n);\n\nDatePicker.displayName = \"DatePicker\";\n"],"names":["DatePicker","forwardRef","props","forwardedInputRef","testAutoId","id","className","label","labelProps","defaultValue","defaultShow","value","disableBeforeDate","disableBefore","disableAfterDate","disableAfter","yearsToShow","name","helpLabel","errorLabel","invalid","days","months","monthLabel","yearLabel","placeholder","width","onChange","onBlur","onFocus","onKeyDown","action","showCalendarLabel","hideCalendarLabel","supportLabelProps","tooltip","textInputProps","description","rest","process","env","NODE_ENV","console","warn","parseDateString","minDate","dayjs","startOf","toDate","maxDate","date","setDate","useState","getInitialDate","error","setError","showCalendar","setShowCalendar","calendarRef","useRef","datepickerRef","iconButtonRef","inputRef","didAutoFormatCompactInputRef","unifiedInputRef","useCallback","instance","current","handleFocus","e","contains","relatedTarget","target","handleBlur","handleKeyDownAction","key","preventDefault","stopPropagation","handleChange","rawValue","currentTarget","formattedValue","shouldStripAutoFormatting","digits","replace","partialCompactDate","formatDateString","partial","rawValueWithoutTrailingPunctuation","compactDateCandidate","length","validCompactDate","shouldRemoveFormatting","normalizeInputValue","input","nativeSetter","Object","getOwnPropertyDescriptor","HTMLInputElement","prototype","set","call","setInputValue","nextDate","nextError","parsedDate","isWithinLowerBound","isWithinUpperBound","getInputValidationState","clickCalendar","flushSync","calendarEl","button","querySelector","window","requestAnimationFrame","focus","onClick","handleClickCalendarDay","node","formatInput","event","document","createEvent","initEvent","dispatchEvent","handleTabOutsideCalendar","jsx","InputGroup","clsx","ref","render","inputProps","BaseTextInput","type","actionButton","jsxs","Popover","positionReference","open","onOpenChange","offset","fitAvailableHeight","children","Trigger","title","tabIndex","asChild","IconButton","CalendarIcon","Content","initialFocus","padding","Calendar","onDateSelected","onTabOutside","displayName"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import{useMergeRefs as t,FloatingPortal as n,FloatingFocusManager as o,useFloating as s,autoUpdate as
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{useMergeRefs as t,FloatingPortal as n,FloatingFocusManager as o,useFloating as s,autoUpdate as a,offset as r,flip as i,shift as l,size as c,useClick as p,useHover as f,useFocus as d,useDismiss as m,useRole as u,useInteractions as g}from"@floating-ui/react";import{c as h}from"../../../clsx-BeLtu-UY.js";import*as v from"react";import{getThemeAndSize as b}from"../../utilities/getThemeAndSize.js";const x=v.createContext(null),y=()=>{const e=v.useContext(x);if(null==e)throw new Error("Popover komponenter må brukes innenfor en <Popover /> komponent");return e},k=({children:t,...n})=>{const o=(({open:e,onOpenChange:t,placement:n="bottom-start",strategy:o="absolute",modal:h=!0,offset:b=4,positionReference:x,onPlacementChange:y,matchReferenceWidth:k=!1,fitAvailableHeight:R=!1,hoverOptions:C,focusOptions:F,clickOptions:P,roleOptions:j,dismissOptions:E})=>{const[O,w]=v.useState(e),A=e??O,H=t??w,z=s({open:A,onOpenChange:H,placement:n,strategy:o,middleware:[r(b),i({padding:R?12:5,fallbackPlacements:["bottom","top"]}),l({padding:12,crossAxis:R}),R&&c({padding:12,apply({availableHeight:e,elements:t}){t.floating.style.maxHeight=`${Math.max(0,e)}px`}}),...k?[c({apply({rects:e,elements:t}){t.floating.style.width=`${e.reference.width}px`}})]:[]],whileElementsMounted:a}),M=z.context,N=p(M,{enabled:!1,...P}),S=f(M,{enabled:!1,...C}),T=d(M,{enabled:!1,...F}),$=m(M,E),L=u(M,j),D=g([N,$,T,S,L]);return v.useLayoutEffect(()=>{x&&z.refs.setPositionReference(x?.current)},[x,z.refs]),v.useLayoutEffect(()=>{A&&y?.(z.placement)},[A,z.placement,y]),v.useMemo(()=>({open:A,onOpenChange:H,modal:h,fitAvailableHeight:R,...D,...z}),[A,H,h,R,D,z])})({...n});return e(x.Provider,{value:o,children:t})},R=v.forwardRef(function({children:n,asChild:o=!1,...s},a){const{refs:r,getReferenceProps:i,open:l,onOpenChange:c}=y(),p=n.ref,f=t([r.setReference,a,p]);return o&&v.isValidElement(n)?v.cloneElement(n,i({ref:f,...s,...n.props})):e("button",{ref:f,onClick:()=>c?.(!l),"aria-expanded":l,...i({...s,className:h("jkl-popover-trigger",s.className)}),children:n})}),C=v.forwardRef(function({style:s,className:a,padding:r=0,initialFocus:i=0,returnFocus:l=!0,...c},p){const{context:f,modal:d,refs:m,open:u,floatingStyles:g,getFloatingProps:x,isPositioned:k,fitAvailableHeight:R}=y(),C=t([m.setFloating,p]),F=m.reference.current,{theme:P,size:j}=b((O=F)&&"contextElement"in O?F.contextElement:F),E=v.useRef(null);var O;return v.useEffect(()=>{E.current=f.elements.domReference?.closest("[data-portal]")||document.body},[f.elements.domReference]),u?e(n,{root:E.current,children:e(o,{context:f,modal:d,initialFocus:i,returnFocus:l,children:e("div",{"data-theme":P,"data-size":j,className:h("jkl jkl-popover",a,{"jkl-popover--fit-available-height":R}),ref:C,style:{...s,...g,"--popover-padding":`var(--jkl-spacing-${r})`,visibility:d||k?"visible":"hidden"},...x(c),children:c.children})})}):null});k.Trigger=R,k.Content=C;export{k as Popover,k as default};
|
|
2
2
|
//# sourceMappingURL=Popover.js.map
|