@helsenorge/datepicker 14.0.0-beta.7 → 14.0.0

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.
@@ -167,6 +167,7 @@
167
167
 
168
168
  &:hover:not(:disabled) {
169
169
  background: var(--core-color-neutral-50);
170
+ outline: 1px solid var(--color-base-border-onlight-emphasized);
170
171
 
171
172
  svg {
172
173
  fill: var(--color-action-graphics-onlight-hover);
@@ -144,6 +144,14 @@ var BaseDayPicker = (props) => {
144
144
  ...getResources(language),
145
145
  ...resources
146
146
  };
147
+ const mergedLabels = {
148
+ labelNext: () => mergedResources.nextMonth,
149
+ labelPrevious: () => mergedResources.previousMonth,
150
+ labelDayButton: () => mergedResources.dayButtonBase,
151
+ labelMonthDropdown: () => mergedResources.monthDropdown,
152
+ labelYearDropdown: () => mergedResources.yearDropdown,
153
+ ...labelsForCalendar
154
+ };
147
155
  const customLocale = {
148
156
  ...localeForCalendar,
149
157
  localize: {
@@ -196,7 +204,7 @@ var BaseDayPicker = (props) => {
196
204
  classNames: datePickerClassNames,
197
205
  locale: customLocale,
198
206
  modifiers: modifiersExtended,
199
- labels: labelsForCalendar,
207
+ labels: mergedLabels,
200
208
  footer: showGoToTodayButton ? /* @__PURE__ */ jsxs("div", {
201
209
  className: classNames(customstyles["datepicker-footer"], customstyles["datepicker-footer--with-today-button"]),
202
210
  children: [/* @__PURE__ */ jsx(Button, {
@@ -279,7 +287,7 @@ var TimeInputInternal = ({ value, onChange, onBlur, id, setErrorText, resources,
279
287
  if (mm !== newMm) setMm(newMm);
280
288
  }
281
289
  }, [value]);
282
- const combinedValue = hh && mm ? `${hh}:${mm}` : "";
290
+ const combinedValue = hh || mm ? `${hh}:${mm}` : "";
283
291
  useEffect(() => {
284
292
  if (onChange) onChange(combinedValue);
285
293
  }, [combinedValue]);
@@ -520,54 +528,30 @@ function isShadowRoot(value) {
520
528
  if (!hasWindow() || typeof ShadowRoot === "undefined") return false;
521
529
  return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
522
530
  }
523
- var invalidOverflowDisplayValues = /* @__PURE__ */ new Set(["inline", "contents"]);
524
531
  function isOverflowElement(element) {
525
532
  const { overflow, overflowX, overflowY, display } = getComputedStyle$1(element);
526
- return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
533
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== "inline" && display !== "contents";
527
534
  }
528
- var tableElements = /* @__PURE__ */ new Set([
529
- "table",
530
- "td",
531
- "th"
532
- ]);
533
535
  function isTableElement(element) {
534
- return tableElements.has(getNodeName(element));
536
+ return /^(table|td|th)$/.test(getNodeName(element));
535
537
  }
536
- var topLayerSelectors = [":popover-open", ":modal"];
537
538
  function isTopLayer(element) {
538
- return topLayerSelectors.some((selector) => {
539
- try {
540
- return element.matches(selector);
541
- } catch (_e) {
542
- return false;
543
- }
544
- });
539
+ try {
540
+ if (element.matches(":popover-open")) return true;
541
+ } catch (_e) {}
542
+ try {
543
+ return element.matches(":modal");
544
+ } catch (_e) {
545
+ return false;
546
+ }
545
547
  }
546
- var transformProperties = [
547
- "transform",
548
- "translate",
549
- "scale",
550
- "rotate",
551
- "perspective"
552
- ];
553
- var willChangeValues = [
554
- "transform",
555
- "translate",
556
- "scale",
557
- "rotate",
558
- "perspective",
559
- "filter"
560
- ];
561
- var containValues = [
562
- "paint",
563
- "layout",
564
- "strict",
565
- "content"
566
- ];
548
+ var willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
549
+ var containRe = /paint|layout|strict|content/;
550
+ var isNotNone = (value) => !!value && value !== "none";
551
+ var isWebKitValue;
567
552
  function isContainingBlock(elementOrCss) {
568
- const webkit = isWebKit();
569
553
  const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss;
570
- return transformProperties.some((value) => css[value] ? css[value] !== "none" : false) || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || willChangeValues.some((value) => (css.willChange || "").includes(value)) || containValues.some((value) => (css.contain || "").includes(value));
554
+ return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || "") || containRe.test(css.contain || "");
571
555
  }
572
556
  function getContainingBlock(element) {
573
557
  let currentNode = getParentNode(element);
@@ -579,16 +563,11 @@ function getContainingBlock(element) {
579
563
  return null;
580
564
  }
581
565
  function isWebKit() {
582
- if (typeof CSS === "undefined" || !CSS.supports) return false;
583
- return CSS.supports("-webkit-backdrop-filter", "none");
584
- }
585
- var lastTraversableNodeNames = /* @__PURE__ */ new Set([
586
- "html",
587
- "body",
588
- "#document"
589
- ]);
566
+ if (isWebKitValue == null) isWebKitValue = typeof CSS !== "undefined" && CSS.supports && CSS.supports("-webkit-backdrop-filter", "none");
567
+ return isWebKitValue;
568
+ }
590
569
  function isLastTraversableNode(node) {
591
- return lastTraversableNodeNames.has(getNodeName(node));
570
+ return /^(html|body|#document)$/.test(getNodeName(node));
592
571
  }
593
572
  function getComputedStyle$1(element) {
594
573
  return getWindow(element).getComputedStyle(element);
@@ -624,8 +603,7 @@ function getOverflowAncestors(node, list, traverseIframes) {
624
603
  if (isBody) {
625
604
  const frameElement = getFrameElement(win);
626
605
  return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
627
- }
628
- return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
606
+ } else return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
629
607
  }
630
608
  function getFrameElement(win) {
631
609
  return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
@@ -656,9 +634,9 @@ function getOppositeAxis(axis) {
656
634
  function getAxisLength(axis) {
657
635
  return axis === "y" ? "height" : "width";
658
636
  }
659
- var yAxisSides = /* @__PURE__ */ new Set(["top", "bottom"]);
660
637
  function getSideAxis(placement) {
661
- return yAxisSides.has(getSide(placement)) ? "y" : "x";
638
+ const firstChar = placement[0];
639
+ return firstChar === "t" || firstChar === "b" ? "y" : "x";
662
640
  }
663
641
  function getAlignmentAxis(placement) {
664
642
  return getOppositeAxis(getSideAxis(placement));
@@ -1198,9 +1176,13 @@ async function detectOverflow$1(state, options) {
1198
1176
  right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
1199
1177
  };
1200
1178
  }
1179
+ var MAX_RESET_COUNT = 50;
1201
1180
  var computePosition$1 = async (reference, floating, config) => {
1202
1181
  const { placement = "bottom", strategy = "absolute", middleware = [], platform: platform$1 } = config;
1203
- const validMiddleware = middleware.filter(Boolean);
1182
+ const platformWithDetectOverflow = platform$1.detectOverflow ? platform$1 : {
1183
+ ...platform$1,
1184
+ detectOverflow: detectOverflow$1
1185
+ };
1204
1186
  const rtl = await (platform$1.isRTL == null ? void 0 : platform$1.isRTL(floating));
1205
1187
  let rects = await platform$1.getElementRects({
1206
1188
  reference,
@@ -1209,11 +1191,12 @@ var computePosition$1 = async (reference, floating, config) => {
1209
1191
  });
1210
1192
  let { x, y } = computeCoordsFromPlacement(rects, placement, rtl);
1211
1193
  let statefulPlacement = placement;
1212
- let middlewareData = {};
1213
1194
  let resetCount = 0;
1214
- for (let i = 0; i < validMiddleware.length; i++) {
1215
- var _platform$detectOverf;
1216
- const { name, fn } = validMiddleware[i];
1195
+ const middlewareData = {};
1196
+ for (let i = 0; i < middleware.length; i++) {
1197
+ const currentMiddleware = middleware[i];
1198
+ if (!currentMiddleware) continue;
1199
+ const { name, fn } = currentMiddleware;
1217
1200
  const { x: nextX, y: nextY, data, reset } = await fn({
1218
1201
  x,
1219
1202
  y,
@@ -1222,10 +1205,7 @@ var computePosition$1 = async (reference, floating, config) => {
1222
1205
  strategy,
1223
1206
  middlewareData,
1224
1207
  rects,
1225
- platform: {
1226
- ...platform$1,
1227
- detectOverflow: (_platform$detectOverf = platform$1.detectOverflow) != null ? _platform$detectOverf : detectOverflow$1
1228
- },
1208
+ platform: platformWithDetectOverflow,
1229
1209
  elements: {
1230
1210
  reference,
1231
1211
  floating
@@ -1233,14 +1213,11 @@ var computePosition$1 = async (reference, floating, config) => {
1233
1213
  });
1234
1214
  x = nextX != null ? nextX : x;
1235
1215
  y = nextY != null ? nextY : y;
1236
- middlewareData = {
1237
- ...middlewareData,
1238
- [name]: {
1239
- ...middlewareData[name],
1240
- ...data
1241
- }
1216
+ middlewareData[name] = {
1217
+ ...middlewareData[name],
1218
+ ...data
1242
1219
  };
1243
- if (reset && resetCount <= 50) {
1220
+ if (reset && resetCount < MAX_RESET_COUNT) {
1244
1221
  resetCount++;
1245
1222
  if (typeof reset === "object") {
1246
1223
  if (reset.placement) statefulPlacement = reset.placement;
@@ -1485,7 +1462,7 @@ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
1485
1462
  const isOffsetParentAnElement = isHTMLElement(offsetParent);
1486
1463
  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
1487
1464
  if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) scroll = getNodeScroll(offsetParent);
1488
- if (isHTMLElement(offsetParent)) {
1465
+ if (isOffsetParentAnElement) {
1489
1466
  const offsetRect = getBoundingClientRect(offsetParent);
1490
1467
  scale = getScale(offsetParent);
1491
1468
  offsets.x = offsetRect.x + offsetParent.clientLeft;
@@ -1553,7 +1530,6 @@ function getViewportRect(element, strategy) {
1553
1530
  y
1554
1531
  };
1555
1532
  }
1556
- var absoluteOrFixed = /* @__PURE__ */ new Set(["absolute", "fixed"]);
1557
1533
  function getInnerBoundingClientRect(element, strategy) {
1558
1534
  const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
1559
1535
  const top = clientRect.top + element.clientTop;
@@ -1598,7 +1574,7 @@ function getClippingElementAncestors(element, cache) {
1598
1574
  const computedStyle = getComputedStyle$1(currentNode);
1599
1575
  const currentNodeIsContaining = isContainingBlock(currentNode);
1600
1576
  if (!currentNodeIsContaining && computedStyle.position === "fixed") currentContainingBlockComputedStyle = null;
1601
- if (elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode)) result = result.filter((ancestor) => ancestor !== currentNode);
1577
+ if (elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === "absolute" || currentContainingBlockComputedStyle.position === "fixed") || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode)) result = result.filter((ancestor) => ancestor !== currentNode);
1602
1578
  else currentContainingBlockComputedStyle = computedStyle;
1603
1579
  currentNode = getParentNode(currentNode);
1604
1580
  }
@@ -1608,20 +1584,23 @@ function getClippingElementAncestors(element, cache) {
1608
1584
  function getClippingRect(_ref) {
1609
1585
  let { element, boundary, rootBoundary, strategy } = _ref;
1610
1586
  const clippingAncestors = [...boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary), rootBoundary];
1611
- const firstClippingAncestor = clippingAncestors[0];
1612
- const clippingRect = clippingAncestors.reduce((accRect, clippingAncestor) => {
1613
- const rect = getClientRectFromClippingAncestor(element, clippingAncestor, strategy);
1614
- accRect.top = max$1(rect.top, accRect.top);
1615
- accRect.right = min$1(rect.right, accRect.right);
1616
- accRect.bottom = min$1(rect.bottom, accRect.bottom);
1617
- accRect.left = max$1(rect.left, accRect.left);
1618
- return accRect;
1619
- }, getClientRectFromClippingAncestor(element, firstClippingAncestor, strategy));
1587
+ const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
1588
+ let top = firstRect.top;
1589
+ let right = firstRect.right;
1590
+ let bottom = firstRect.bottom;
1591
+ let left = firstRect.left;
1592
+ for (let i = 1; i < clippingAncestors.length; i++) {
1593
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
1594
+ top = max$1(rect.top, top);
1595
+ right = min$1(rect.right, right);
1596
+ bottom = min$1(rect.bottom, bottom);
1597
+ left = max$1(rect.left, left);
1598
+ }
1620
1599
  return {
1621
- width: clippingRect.right - clippingRect.left,
1622
- height: clippingRect.bottom - clippingRect.top,
1623
- x: clippingRect.left,
1624
- y: clippingRect.top
1600
+ width: right - left,
1601
+ height: bottom - top,
1602
+ x: left,
1603
+ y: top
1625
1604
  };
1626
1605
  }
1627
1606
  function getDimensions(element) {
@@ -1775,7 +1754,7 @@ function autoUpdate(reference, floating, update, options) {
1775
1754
  if (options === void 0) options = {};
1776
1755
  const { ancestorScroll = true, ancestorResize = true, elementResize = typeof ResizeObserver === "function", layoutShift = typeof IntersectionObserver === "function", animationFrame = false } = options;
1777
1756
  const referenceEl = unwrapElement(reference);
1778
- const ancestors = ancestorScroll || ancestorResize ? [...referenceEl ? getOverflowAncestors(referenceEl) : [], ...getOverflowAncestors(floating)] : [];
1757
+ const ancestors = ancestorScroll || ancestorResize ? [...referenceEl ? getOverflowAncestors(referenceEl) : [], ...floating ? getOverflowAncestors(floating) : []] : [];
1779
1758
  ancestors.forEach((ancestor) => {
1780
1759
  ancestorScroll && ancestor.addEventListener("scroll", update, { passive: true });
1781
1760
  ancestorResize && ancestor.addEventListener("resize", update);
@@ -1786,7 +1765,7 @@ function autoUpdate(reference, floating, update, options) {
1786
1765
  if (elementResize) {
1787
1766
  resizeObserver = new ResizeObserver((_ref) => {
1788
1767
  let [firstEntry] = _ref;
1789
- if (firstEntry && firstEntry.target === referenceEl && resizeObserver) {
1768
+ if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {
1790
1769
  resizeObserver.unobserve(floating);
1791
1770
  cancelAnimationFrame(reobserveFrame);
1792
1771
  reobserveFrame = requestAnimationFrame(() => {
@@ -1797,7 +1776,7 @@ function autoUpdate(reference, floating, update, options) {
1797
1776
  update();
1798
1777
  });
1799
1778
  if (referenceEl && !animationFrame) resizeObserver.observe(referenceEl);
1800
- resizeObserver.observe(floating);
1779
+ if (floating) resizeObserver.observe(floating);
1801
1780
  }
1802
1781
  let frameId;
1803
1782
  let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;
@@ -2024,14 +2003,22 @@ function useFloating$1(options) {
2024
2003
  floatingStyles
2025
2004
  ]);
2026
2005
  }
2027
- var offset = (options, deps) => ({
2028
- ...offset$1(options),
2029
- options: [options, deps]
2030
- });
2031
- var shift = (options, deps) => ({
2032
- ...shift$1(options),
2033
- options: [options, deps]
2034
- });
2006
+ var offset = (options, deps) => {
2007
+ const result = offset$1(options);
2008
+ return {
2009
+ name: result.name,
2010
+ fn: result.fn,
2011
+ options: [options, deps]
2012
+ };
2013
+ };
2014
+ var shift = (options, deps) => {
2015
+ const result = shift$1(options);
2016
+ return {
2017
+ name: result.name,
2018
+ fn: result.fn,
2019
+ options: [options, deps]
2020
+ };
2021
+ };
2035
2022
  var FOCUSABLE_ATTRIBUTE = "data-floating-ui-focusable";
2036
2023
  var ACTIVE_KEY = "active";
2037
2024
  var SELECTED_KEY = "selected";
@@ -2128,7 +2115,10 @@ var uncontrolledElementsSet = /* @__PURE__ */ new WeakSet();
2128
2115
  var markerMap = {};
2129
2116
  var lockCount$1 = 0;
2130
2117
  var supportsInert = () => typeof HTMLElement !== "undefined" && "inert" in HTMLElement.prototype;
2131
- var unwrapHost = (node) => node && (node.host || unwrapHost(node.parentNode));
2118
+ function unwrapHost(node) {
2119
+ if (!node) return null;
2120
+ return isShadowRoot(node) ? node.host : unwrapHost(node.parentNode);
2121
+ }
2132
2122
  var correctElements = (parent, targets) => targets.map((target) => {
2133
2123
  if (parent.contains(target)) return target;
2134
2124
  const correctedTarget = unwrapHost(target);
@@ -2256,7 +2246,7 @@ function addPreviouslyFocusedElement(element) {
2256
2246
  clearDisconnectedPreviouslyFocusedElements();
2257
2247
  if (element && getNodeName(element) !== "body") {
2258
2248
  previouslyFocusedElements.push(new WeakRef(element));
2259
- if (previouslyFocusedElements.length > LIST_LIMIT) previouslyFocusedElements = previouslyFocusedElements.slice(-20);
2249
+ if (previouslyFocusedElements.length > LIST_LIMIT) previouslyFocusedElements = previouslyFocusedElements.slice(-LIST_LIMIT);
2260
2250
  }
2261
2251
  }
2262
2252
  function getPreviouslyFocusedElement() {
@@ -2949,18 +2939,20 @@ function useDismiss(context, props) {
2949
2939
  referencePress,
2950
2940
  referencePressEvent
2951
2941
  ]);
2952
- const floating = React$1.useMemo(() => ({
2953
- onKeyDown: closeOnEscapeKeyDown,
2954
- onMouseDown() {
2955
- endedOrStartedInsideRef.current = true;
2956
- },
2957
- onMouseUp() {
2942
+ const floating = React$1.useMemo(() => {
2943
+ function setMouseDownOrUpInside(event) {
2944
+ if (event.button !== 0) return;
2958
2945
  endedOrStartedInsideRef.current = true;
2959
- },
2960
- [captureHandlerKeys[outsidePressEvent]]: () => {
2961
- dataRef.current.insideReactTree = true;
2962
2946
  }
2963
- }), [
2947
+ return {
2948
+ onKeyDown: closeOnEscapeKeyDown,
2949
+ onMouseDown: setMouseDownOrUpInside,
2950
+ onMouseUp: setMouseDownOrUpInside,
2951
+ [captureHandlerKeys[outsidePressEvent]]: () => {
2952
+ dataRef.current.insideReactTree = true;
2953
+ }
2954
+ };
2955
+ }, [
2964
2956
  closeOnEscapeKeyDown,
2965
2957
  outsidePressEvent,
2966
2958
  dataRef
@@ -3186,103 +3178,113 @@ var DateInputInternal = ({ value, onChange, onBlur, inputId, legendId, setErrorT
3186
3178
  ];
3187
3179
  const clearButtonRef = useRef(null);
3188
3180
  const [isClearButtonFocused, setIsClearButtonFocused] = useState(false);
3189
- useEffect(() => {
3190
- if (!value || value === "") return;
3191
- const match = value.match(/^(\d{2})\.(\d{2})\.(\d{4})$/);
3192
- if (match) {
3193
- const [_, newDd, newMm, newYyyy] = match;
3194
- if (dd !== newDd) setDd(newDd);
3195
- if (mm !== newMm) setMm(newMm);
3196
- if (yyyy !== newYyyy) setYyyy(newYyyy);
3197
- }
3198
- }, [value]);
3199
- const combinedValue = dd && mm && yyyy ? `${dd}.${mm}.${yyyy}` : "";
3181
+ const combinedValue = `${dd}.${mm}.${yyyy}`;
3200
3182
  useEffect(() => {
3201
3183
  if (onChange) onChange(combinedValue);
3202
3184
  }, [combinedValue]);
3203
- const validateDd = (newDd) => {
3204
- if (newDd === "") {
3205
- setErrorTextDd("");
3185
+ const validateSegment = ({ segment, length, minValue, maxValue, errorTextSetter, errorMessage }) => {
3186
+ if (segment === "") {
3187
+ errorTextSetter("");
3206
3188
  return true;
3207
3189
  }
3208
- if (/^\d{0,2}$/.test(newDd)) {
3209
- const dayNum = parseInt(newDd, 10);
3210
- if (dayNum < 0 || dayNum > 31) {
3211
- setErrorTextDd(resources?.validateDefaultMessageDay || "Dag må være et tall mellom 01 og 31");
3190
+ if ((/* @__PURE__ */ new RegExp(`^\\d{0,${length}}$`)).test(segment)) {
3191
+ if (length === 2 && segment === "00") {
3192
+ errorTextSetter(errorMessage);
3193
+ return false;
3194
+ }
3195
+ const parsedSegment = parseInt(segment, 10);
3196
+ if (parsedSegment < minValue || parsedSegment > maxValue) {
3197
+ errorTextSetter(errorMessage);
3212
3198
  return false;
3213
3199
  } else {
3214
- setErrorTextDd("");
3200
+ errorTextSetter("");
3215
3201
  return true;
3216
3202
  }
3217
3203
  } else {
3218
- setErrorTextDd(resources?.validateDefaultMessageDay || "Dag må være et tall mellom 01 og 31");
3204
+ errorTextSetter(errorMessage);
3219
3205
  return false;
3220
3206
  }
3221
3207
  };
3222
3208
  const handleDdChange = (e) => {
3223
3209
  const newDd = e.target.value;
3224
3210
  setDd(newDd);
3225
- if (validateDd(newDd)) {
3211
+ if (validateSegment({
3212
+ segment: newDd,
3213
+ length: 2,
3214
+ minValue: 0,
3215
+ maxValue: 31,
3216
+ errorTextSetter: setErrorTextDd,
3217
+ errorMessage: resources?.validateDefaultMessageDay || "Dag må være et tall mellom 01 og 31"
3218
+ })) {
3226
3219
  if (newDd.length === 2) mmRef.current?.focus();
3227
3220
  }
3228
3221
  };
3229
- const validateMm = (newMm) => {
3230
- if (newMm === "") {
3231
- setErrorTextMm("");
3232
- return true;
3233
- }
3234
- if (/^\d{0,2}$/.test(newMm)) {
3235
- const dayNum = parseInt(newMm, 10);
3236
- if (dayNum < 0 || dayNum > 12) {
3237
- setErrorTextMm(resources?.validateDefaultMessageMonth || "Måned må være et tall mellom 01 og 12");
3238
- return false;
3239
- } else {
3240
- setErrorTextMm("");
3241
- return true;
3242
- }
3243
- } else {
3244
- setErrorTextMm(resources?.validateDefaultMessageMonth || "Måned må være et tall mellom 01 og 12");
3245
- return false;
3246
- }
3247
- };
3248
3222
  const handleMmChange = (e) => {
3249
3223
  const newMm = e.target.value;
3250
3224
  setMm(newMm);
3251
- if (validateMm(newMm)) {
3225
+ if (validateSegment({
3226
+ segment: newMm,
3227
+ length: 2,
3228
+ minValue: 0,
3229
+ maxValue: 12,
3230
+ errorTextSetter: setErrorTextMm,
3231
+ errorMessage: resources?.validateDefaultMessageMonth || "Måned må være et tall mellom 01 og 12"
3232
+ })) {
3252
3233
  if (newMm.length === 2) yyyyRef.current?.focus();
3253
3234
  }
3254
3235
  };
3255
- const validateYyyy = (newYyyy, strict) => {
3256
- if (newYyyy === "") {
3257
- setErrorTextYyyy("");
3258
- return true;
3259
- }
3260
- if (/^\d{0,4}$/.test(newYyyy)) {
3261
- const dayNum = parseInt(newYyyy, 10);
3262
- let minValue = 0;
3263
- if (strict) minValue = 1e3;
3264
- if (dayNum < minValue || dayNum > 9999) {
3265
- setErrorTextYyyy(resources?.validateDefaultMessageYear || "År må være et tall med 4 siffer");
3266
- return false;
3267
- } else {
3268
- setErrorTextYyyy("");
3269
- return true;
3270
- }
3271
- } else {
3272
- setErrorTextYyyy(resources?.validateDefaultMessageYear || "År må være et tall med 4 siffer");
3273
- return false;
3274
- }
3275
- };
3276
3236
  const handleYyyyChange = (e) => {
3277
3237
  const newYyyy = e.target.value;
3278
3238
  setYyyy(newYyyy);
3279
- validateYyyy(newYyyy);
3239
+ validateSegment({
3240
+ segment: newYyyy,
3241
+ length: 4,
3242
+ minValue: 0,
3243
+ maxValue: 9999,
3244
+ errorTextSetter: setErrorTextYyyy,
3245
+ errorMessage: resources?.validateDefaultMessageYear || "År må være et tall med 4 siffer"
3246
+ });
3247
+ };
3248
+ const validateAllSegments = (latestDd, latestMm, latestYyyy) => {
3249
+ validateSegment({
3250
+ segment: latestDd ?? dd,
3251
+ length: 2,
3252
+ minValue: 0,
3253
+ maxValue: 31,
3254
+ errorTextSetter: setErrorTextDd,
3255
+ errorMessage: resources?.validateDefaultMessageDay || "Dag må være et tall mellom 01 og 31"
3256
+ });
3257
+ validateSegment({
3258
+ segment: latestMm ?? mm,
3259
+ length: 2,
3260
+ minValue: 0,
3261
+ maxValue: 12,
3262
+ errorTextSetter: setErrorTextMm,
3263
+ errorMessage: resources?.validateDefaultMessageMonth || "Måned må være et tall mellom 01 og 12"
3264
+ });
3265
+ validateSegment({
3266
+ segment: latestYyyy ?? yyyy,
3267
+ length: 4,
3268
+ minValue: 0,
3269
+ maxValue: 9999,
3270
+ errorTextSetter: setErrorTextYyyy,
3271
+ errorMessage: resources?.validateDefaultMessageYear || "År må være et tall med 4 siffer"
3272
+ });
3280
3273
  };
3281
3274
  const handleBlurOnSegment = () => {
3282
- validateDd(dd);
3283
- validateMm(mm);
3284
- validateYyyy(yyyy, true);
3275
+ validateAllSegments();
3285
3276
  };
3277
+ useEffect(() => {
3278
+ if (!value || value === "") return;
3279
+ const match = value.match(/^(\d{2})\.(\d{2})\.(\d{4})$/);
3280
+ if (match) {
3281
+ const [_, newDd, newMm, newYyyy] = match;
3282
+ if (dd !== newDd) setDd(newDd);
3283
+ if (mm !== newMm) setMm(newMm);
3284
+ if (yyyy !== newYyyy) setYyyy(newYyyy);
3285
+ validateAllSegments(newDd, newMm, newYyyy);
3286
+ }
3287
+ }, [value]);
3286
3288
  useEffect(() => {
3287
3289
  const combinedErrors = [
3288
3290
  errorTextDd,
@@ -3629,22 +3631,13 @@ var Unsafe_DateAndTime = ({ value, onChange, legend, errorText, datepickerProps,
3629
3631
  return date.getHours() !== 0 || date.getMinutes() !== 0;
3630
3632
  };
3631
3633
  const [internalTime, setInternalTime] = useState(hasMeaningfulTime(value) ? toTimeString(value) : void 0);
3632
- const isTypingTimeRef = useRef(false);
3633
- const hasUserTimeRef = useRef(hasMeaningfulTime(value));
3634
- useEffect(() => {
3635
- if (!isTypingTimeRef.current && hasUserTimeRef.current) {
3636
- const newTimeString = toTimeString(value);
3637
- if (hasMeaningfulTime(value)) setInternalTime(newTimeString);
3638
- }
3639
- isTypingTimeRef.current = false;
3640
- }, [value]);
3634
+ const nextTimeString = hasMeaningfulTime(value) ? toTimeString(value) : void 0;
3635
+ if (internalTime !== nextTimeString) setInternalTime(nextTimeString);
3641
3636
  const handleDateChange = (newDate) => {
3642
3637
  const merged = mergeDateAndTime(newDate, internalTime);
3643
3638
  onChange?.(merged);
3644
3639
  };
3645
3640
  const handleTimeChange = (newTime) => {
3646
- hasUserTimeRef.current = !!newTime;
3647
- isTypingTimeRef.current = true;
3648
3641
  setInternalTime(newTime);
3649
3642
  const merged = mergeDateAndTime(value, newTime);
3650
3643
  onChange?.(merged);
@@ -3670,32 +3663,27 @@ var Unsafe_DateAndTime = ({ value, onChange, legend, errorText, datepickerProps,
3670
3663
  };
3671
3664
  var Unsafe_DateAndTime_default = Unsafe_DateAndTime;
3672
3665
  var Unsafe_ISODatePicker = ({ value, onChange, ...baseDateInputProps }) => {
3673
- const [internalDate, setInternalDate] = useState(value ? new Date(value) : void 0);
3674
- const dateToIso = (date) => {
3675
- if (!isValid(date) || !date) return "";
3676
- return formatISO(date, { representation: "date" });
3677
- };
3678
3666
  const isoToDate = (iso) => {
3667
+ if (!iso) return;
3679
3668
  const date = new Date(iso);
3680
3669
  if (!isValid(date)) return;
3681
3670
  return date;
3682
3671
  };
3683
- useEffect(() => {
3684
- if (value) setInternalDate(isoToDate(value));
3685
- else setInternalDate(void 0);
3686
- }, [value]);
3687
- useEffect(() => {
3688
- if (!internalDate) {
3689
- onChange?.("");
3690
- return;
3691
- }
3692
- const iso = dateToIso(internalDate);
3693
- onChange?.(iso);
3694
- }, [internalDate]);
3672
+ const dateToIso = (date) => {
3673
+ if (!isValid(date) || !date) return "";
3674
+ return formatISO(date, { representation: "date" });
3675
+ };
3676
+ const [internalDate, setInternalDate] = useState(isoToDate(value));
3677
+ const nextDateFromProp = isoToDate(value);
3678
+ if ((internalDate?.getTime() ?? void 0) !== (nextDateFromProp?.getTime() ?? void 0)) setInternalDate(nextDateFromProp);
3679
+ const handleDateChange = (newDate) => {
3680
+ setInternalDate(newDate);
3681
+ onChange?.(dateToIso(newDate));
3682
+ };
3695
3683
  return /* @__PURE__ */ jsx(Unsafe_DatePicker_default, {
3696
3684
  ...baseDateInputProps,
3697
3685
  value: internalDate,
3698
- onChange: setInternalDate
3686
+ onChange: handleDateChange
3699
3687
  });
3700
3688
  };
3701
3689
  var Unsafe_ISODatePicker_default = Unsafe_ISODatePicker;