@leabankab/component-library 8.6.1 → 8.8.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.
Files changed (93) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/dist/component-library.es.js +1930 -1091
  3. package/dist/component-library.es.js.map +1 -1
  4. package/dist/component-library.umd.js +2 -2
  5. package/dist/component-library.umd.js.map +1 -1
  6. package/dist/components/buttons/action-button.d.ts +34 -4
  7. package/dist/components/buttons/button-base.d.ts +5 -2
  8. package/dist/components/buttons/icon-button.d.ts +16 -2
  9. package/dist/components/color-roles.d.ts +7 -1
  10. package/dist/components/data-display/arrow-circle.d.ts +21 -0
  11. package/dist/components/data-display/article-card.d.ts +88 -0
  12. package/dist/components/data-display/avatar.d.ts +33 -0
  13. package/dist/components/data-display/chip.d.ts +8 -3
  14. package/dist/components/data-display/featured-image.d.ts +42 -0
  15. package/dist/components/data-display/index.d.ts +12 -0
  16. package/dist/components/data-display/link-card.d.ts +52 -0
  17. package/dist/components/data-display/media-card.d.ts +102 -0
  18. package/dist/components/data-display/partner-row.d.ts +46 -0
  19. package/dist/components/data-display/rich-text.d.ts +27 -0
  20. package/dist/components/data-display/service-card.d.ts +80 -0
  21. package/dist/components/data-display/star-rating.d.ts +26 -0
  22. package/dist/components/data-display/table.d.ts +93 -0
  23. package/dist/components/data-display/testimonial-card.d.ts +43 -0
  24. package/dist/components/data-display/use-star-rating-labels.d.ts +5 -0
  25. package/dist/components/data-display/use-video-player-labels.d.ts +2 -0
  26. package/dist/components/data-display/video-player.d.ts +22 -0
  27. package/dist/components/data-display/website-card.d.ts +10 -0
  28. package/dist/components/feedback/index.d.ts +1 -0
  29. package/dist/components/feedback/skeleton.d.ts +22 -0
  30. package/dist/components/form/slider.d.ts +15 -2
  31. package/dist/components/navigation/breadcrumbs.d.ts +38 -0
  32. package/dist/components/navigation/index.d.ts +3 -0
  33. package/dist/components/navigation/pagination-dots.d.ts +34 -0
  34. package/dist/components/navigation/pagination.d.ts +37 -0
  35. package/dist/components/navigation/use-breadcrumbs-labels.d.ts +2 -0
  36. package/dist/components/navigation/use-pagination-labels.d.ts +7 -0
  37. package/dist/components/surfaces/accordion.d.ts +5 -1
  38. package/dist/components/surfaces/index.d.ts +1 -0
  39. package/dist/components/surfaces/panel.d.ts +30 -0
  40. package/dist/components/typography/link.d.ts +14 -1
  41. package/dist/cookie-consent-react.cjs +1 -1
  42. package/dist/cookie-consent-react.cjs.map +1 -1
  43. package/dist/cookie-consent-react.mjs +13 -13
  44. package/dist/cookie-consent-react.mjs.map +1 -1
  45. package/dist/cookie-consent.css +1 -1
  46. package/dist/date-picker.cjs +1 -1
  47. package/dist/date-picker.cjs.map +1 -1
  48. package/dist/date-picker.mjs +216 -203
  49. package/dist/date-picker.mjs.map +1 -1
  50. package/dist/index.css +1 -1
  51. package/dist/index.d.ts +1 -1
  52. package/dist/tailwind.css +16 -0
  53. package/dist/theme/index.d.ts +1 -1
  54. package/dist/theme/token-types.d.ts +13 -3
  55. package/dist/theme/tokens/breakpoints.d.ts +20 -0
  56. package/dist/theme/tokens/font-family.d.ts +6 -0
  57. package/dist/theme/tokens/index.d.ts +1 -0
  58. package/dist/theme/tokens/shadows.d.ts +6 -0
  59. package/dist/theme/tokens/text-styles.d.ts +8 -0
  60. package/dist/theme/tokens/widths.d.ts +10 -0
  61. package/dist/theme/types.d.ts +9 -1
  62. package/dist/website/brand-letters.d.ts +40 -0
  63. package/dist/website/calculator.d.ts +58 -0
  64. package/dist/website/carousel.d.ts +55 -0
  65. package/dist/website/cta-banner.d.ts +42 -0
  66. package/dist/website/expanding-cards-context.d.ts +8 -0
  67. package/dist/website/expanding-cards-item.d.ts +69 -0
  68. package/dist/website/expanding-cards.d.ts +48 -0
  69. package/dist/website/hero-service-grid.d.ts +52 -0
  70. package/dist/website/hero.d.ts +57 -0
  71. package/dist/website/index.d.ts +33 -0
  72. package/dist/website/navigation-grid.d.ts +39 -0
  73. package/dist/website/paragraphs.d.ts +11 -0
  74. package/dist/website/partner-list.d.ts +79 -0
  75. package/dist/website/payment-feature.d.ts +85 -0
  76. package/dist/website/promo-grid.d.ts +71 -0
  77. package/dist/website/section-header.d.ts +53 -0
  78. package/dist/website/section.d.ts +53 -0
  79. package/dist/website/service-card-grid.d.ts +33 -0
  80. package/dist/website/split-content.d.ts +69 -0
  81. package/dist/website/stats.d.ts +52 -0
  82. package/dist/website/testimonials.d.ts +100 -0
  83. package/dist/website/use-brand-letters-labels.d.ts +2 -0
  84. package/dist/website/use-carousel-labels.d.ts +6 -0
  85. package/dist/website/use-carousel.d.ts +50 -0
  86. package/dist/website/use-partner-list-labels.d.ts +6 -0
  87. package/dist/website/use-testimonials-labels.d.ts +6 -0
  88. package/dist/website.cjs +2 -0
  89. package/dist/website.cjs.map +1 -0
  90. package/dist/website.css +1 -0
  91. package/dist/website.mjs +1226 -0
  92. package/dist/website.mjs.map +1 -0
  93. package/package.json +7 -2
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.mjs","names":[],"sources":["../src/components/form/use-focus-target-ref.ts","../src/theme/tokens/breakpoints.ts","../src/theme/tokens/colors.ts","../src/theme/tokens/font-family.ts","../src/theme/tokens/font-sizes.ts","../src/theme/tokens/font-weights.ts","../src/theme/tokens/line-heights.ts","../src/theme/tokens/palette.ts","../src/theme/tokens/shadows.ts","../src/theme/tokens/shape.ts","../src/theme/tokens/spacing.ts","../src/theme/tokens/type-scale.ts","../src/theme/tokens/text-styles.ts","../src/theme/tokens/transitions.ts","../src/theme/utils/focus-visible-styles.ts","../src/date-picker/use-calendar-header-labels.ts","../src/date-picker/calendar-header.tsx","../src/date-picker/drawer-toolbar.tsx","../src/date-picker/theme/field-base.ts","../src/date-picker/theme/date-picker.theme.ts","../src/date-picker/theme/form-control.theme.ts","../src/date-picker/theme/icon-button.theme.ts","../src/date-picker/theme/input.theme.ts","../src/date-picker/theme/typography.ts","../src/date-picker/theme/index.ts","../src/date-picker/use-datepicker-title-labels.ts","../src/date-picker/use-view-toggle-labels.ts","../src/date-picker/view-toggle.tsx","../src/date-picker/view-renderers.tsx","../src/date-picker/datepicker.tsx"],"sourcesContent":["import { useEffect, useRef, type Ref, type RefObject } from \"react\";\n\ntype Attachment<T> = {\n ref: Ref<T>;\n target: T | null;\n cleanup?: () => void;\n};\n\nconst attach = <T>(ref: Ref<T>, target: T | null): Attachment<T> => {\n if (typeof ref === \"function\") {\n const cleanup = ref(target);\n return {\n ref,\n target,\n cleanup: typeof cleanup === \"function\" ? cleanup : undefined,\n };\n }\n if (ref) ref.current = target;\n return { ref, target };\n};\n\nconst detach = <T>(attachment: Attachment<T> | null) => {\n if (!attachment) return;\n const { ref, cleanup } = attachment;\n if (cleanup) cleanup();\n else if (typeof ref === \"function\") ref(null);\n else if (ref) ref.current = null;\n};\n\n/**\n * Internal. Points a control's `ref` at the element inside `rootRef` that\n * takes focus, for controls where that element is rendered by another library\n * or is one of several (the radios of a group). `selectors` are tried in\n * order and the first match wins.\n *\n * This is what lets `ref.current.focus()` work on those controls, which\n * react-hook-form relies on to move focus to the first invalid field.\n */\nexport function useFocusTargetRef<T extends HTMLElement>(\n ref: Ref<T> | undefined,\n rootRef: RefObject<HTMLElement | null>,\n selectors: readonly string[],\n) {\n const attachment = useRef<Attachment<T> | null>(null);\n\n // No dependency list: which element takes focus can change with any render\n // (another radio is picked, an option becomes disabled). The ref is only\n // touched when the answer differs from last time.\n useEffect(() => {\n const root = rootRef.current;\n let target: T | null = null;\n if (root) {\n for (const selector of selectors) {\n target = root.querySelector<T>(selector);\n if (target) break;\n }\n }\n\n const current = attachment.current;\n if (current && current.ref === ref && current.target === target) return;\n\n detach(current);\n attachment.current = ref ? attach(ref, target) : null;\n });\n\n useEffect(\n () => () => {\n detach(attachment.current);\n attachment.current = null;\n },\n [],\n );\n}\n","/**\n * Viewport widths in pixels where layouts may change. Mobile-first: each value\n * is the `min-width` at which the breakpoint starts. The values match MUI's\n * defaults, so the MUI wrappers and the CSS Modules switch at the same widths.\n *\n * CSS custom properties can't be used in `@media`, so CSS Modules write the\n * pixel value literally; tests/tokens.test.ts checks it against this scale.\n */\nexport const breakpoints = {\n xs: 0,\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1536,\n} as const;\n\nexport type Breakpoint = keyof typeof breakpoints;\n","export const colors = {\n purple: {\n 50: \"#FAF7FB\",\n 100: \"#E2D8E4\",\n 200: \"#C5B1CA\",\n 300: \"#C29AC2\",\n 400: \"#9E6DA8\",\n 500: \"#855888\",\n 600: \"#70427B\",\n 700: \"#5A3463\",\n 800: \"#422349\",\n 900: \"#2E1834\",\n 950: \"#1A0E1E\",\n },\n teal: {\n 50: \"#F0FCFA\",\n 100: \"#DAF6F1\",\n 200: \"#CEF3ED\",\n 300: \"#08C2A7\",\n 400: \"#46D1BD\",\n 500: \"#06A892\",\n 600: \"#058F7D\",\n 700: \"#047568\",\n 800: \"#035C53\",\n 900: \"#02433E\",\n 950: \"#012A28\",\n },\n blue: {\n 50: \"#EFF6FF\",\n 100: \"#CBE5FD\",\n 200: \"#93CBFC\",\n 300: \"#4DA8F7\",\n 400: \"#057EF2\",\n 500: \"#0468C9\",\n 600: \"#0354A3\",\n 700: \"#02417D\",\n 800: \"#012E57\",\n 900: \"#011B31\",\n 950: \"#000E19\",\n },\n orange: {\n 50: \"#FFF5F2\",\n 100: \"#FFDFD7\",\n 200: \"#FFC4B5\",\n 300: \"#FF9E87\",\n 400: \"#FE653E\",\n 500: \"#E54E28\",\n 600: \"#C43E1C\",\n 700: \"#A33218\",\n 800: \"#822814\",\n 900: \"#611E0F\",\n 950: \"#401408\",\n },\n amber: {\n 50: \"#FFF9EB\",\n 100: \"#FFEFC7\",\n 200: \"#FFE299\",\n 300: \"#FFCF5C\",\n 400: \"#F7A800\",\n 500: \"#D98F00\",\n 600: \"#B37400\",\n 700: \"#8C5A00\",\n 800: \"#6B4500\",\n 900: \"#4A3000\",\n 950: \"#2E1D00\",\n },\n red: {\n 50: \"#FEF2F2\",\n 100: \"#FCDCDC\",\n 200: \"#F9BBBB\",\n 300: \"#F28888\",\n 400: \"#E85555\",\n 500: \"#D32F2F\",\n 600: \"#AD2121\",\n 700: \"#8A1919\",\n 800: \"#6F1313\",\n 900: \"#4D0E0E\",\n 950: \"#2E0808\",\n },\n beige: {\n 50: \"#FAF7F5\",\n 100: \"#F0E9E5\",\n 200: \"#E0D4CD\",\n 300: \"#C9B8AD\",\n 400: \"#B09A8C\",\n 500: \"#977C6B\",\n 600: \"#7E6556\",\n 700: \"#654F42\",\n 800: \"#4C3A32\",\n 900: \"#332722\",\n 950: \"#1A1411\",\n },\n neutral: {\n 50: \"#F7F7F6\",\n 100: \"#EBEBEB\",\n 200: \"#DBDBDB\",\n 300: \"#C4C4C4\",\n 400: \"#A2A2A2\",\n 500: \"#757575\",\n 600: \"#5E5E5E\",\n 700: \"#454545\",\n 800: \"#2E2E2E\",\n 900: \"#1A1A1A\",\n 950: \"#0F1010\",\n },\n white: \"#FFFFFF\",\n black: \"#0F1010\",\n} as const;\n","/**\n * The font stack, emitted as `--lea-font-family`.\n *\n * `ClashGrotesk` is the variable font declared in `theme/fonts.css`.\n * `ClashGrotesk Fallback` is declared there too: Arial resized to Clash\n * Grotesk's average letter width, so text keeps its place while the font file\n * loads.\n */\nexport const fontFamily = '\"ClashGrotesk\", \"ClashGrotesk Fallback\", sans-serif';\n","/**\n * The first font-size scale, from before the text styles.\n *\n * @deprecated Use a text style (`textStyles`, `--lea-text-{role}-{size}-*`,\n * `text-heading-lg`) or, for a size on its own, a step on the type scale\n * (`fontStep`, `--lea-font-step-{n}`). Kept for the components that still use\n * it, and removed in a later major.\n */\nexport const fontSizes = {\n xs: \"0.75rem\",\n sm: \"0.875rem\",\n md: \"1rem\",\n lg: \"1.25rem\",\n xl: \"1.5rem\",\n \"2xl\": \"2rem\",\n \"3xl\": \"2.5rem\",\n \"4xl\": \"3rem\",\n \"5xl\": \"3.5rem\",\n \"6xl\": \"4rem\",\n} as const;\n","export const fontWeights = {\n thin: 200,\n light: 300,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n black: 800,\n} as const;\n","/**\n * Unitless, so a line height follows whichever font size it lands on. `none`\n * is for a display headline, `tight` for large headings and control labels,\n * `snug` for small headings and `normal` for running text.\n */\nexport const lineHeights = {\n none: 1,\n tight: 1.25,\n snug: 1.4,\n normal: 1.5,\n} as const;\n","import { Palette } from \"../types\";\nimport { colors } from \"./colors\";\n\nconst { purple, teal, blue, amber, red, neutral, white, beige } = colors;\n\n/** A scale colour at an opacity, written `rgba(15, 16, 16, 0.5)`. */\nconst alpha = (hex: string, opacity: number) => {\n const [r, g, b] = [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16));\n\n return `rgba(${r}, ${g}, ${b}, ${opacity})`;\n};\n\nexport const palette: Palette = {\n bg: {\n base: white,\n subtle: neutral[50],\n muted: beige[100],\n contrast: neutral[950],\n accent: purple[100],\n overlay: alpha(neutral[950], 0.5),\n },\n text: {\n base: neutral[950],\n subtle: neutral[500],\n muted: neutral[400],\n accent: purple[600],\n contrast: white,\n },\n border: {\n base: neutral[200],\n subtle: neutral[100],\n strong: neutral[950],\n accent: purple[600],\n contrast: white,\n },\n primary: {\n base: purple[600],\n hover: purple[700],\n subtle: purple[100],\n contrast: white,\n },\n secondary: {\n base: neutral[950],\n hover: neutral[800],\n subtle: neutral[100],\n contrast: white,\n },\n tertiary: {\n base: teal[300],\n hover: teal[400],\n subtle: teal[100],\n contrast: white,\n },\n status: {\n error: {\n base: red[500],\n subtle: red[100],\n },\n warning: {\n base: amber[400],\n subtle: amber[100],\n },\n info: {\n base: blue[400],\n subtle: blue[100],\n },\n success: {\n base: teal[400],\n subtle: teal[100],\n },\n },\n} as const;\n","export const shadows = {\n xs: \"0 1px 2px 0 rgb(0 0 0 / 0.05)\",\n sm: \"0px 1px 3px 0px rgba(0, 0, 0, 0.10), 0px 1px 2px -1px rgba(0, 0, 0, 0.10)\",\n md: \"0px 4px 6px -1px rgba(0, 0, 0, 0.10), 0px 2px 4px -2px rgba(0, 0, 0, 0.10)\",\n lg: \"0px 10px 15px -3px rgba(0, 0, 0, 0.10), 0px 4px 6px -4px rgba(0, 0, 0, 0.10)\",\n xl: \"0px 20px 25px -5px rgba(0, 0, 0, 0.10), 0px 8px 10px -6px rgba(0, 0, 0, 0.10)\",\n \"2xl\": \"0px 25px 50px -12px rgba(0, 0, 0, 0.25)\",\n inner: \"0px 2px 4px 0px rgba(0, 0, 0, 0.05) inset\",\n} as const;\n","export const shape = {\n sm: 4,\n md: 5,\n lg: 6,\n xl: 8,\n \"2xl\": 10,\n \"3xl\": 12,\n \"4xl\": 16,\n \"5xl\": 32,\n huge: 64,\n full: 100,\n} as const;\n","const BASE = 8;\nconst ROOT_FONT_SIZE = 16;\n\nexport const spacing = (factor: number) =>\n `${(factor * BASE) / ROOT_FONT_SIZE}rem`;\n\n/**\n * The steps emitted as `--lea-spacing-{step}`, the point of a half step written\n * as a hyphen: `--lea-spacing-1-5` is `spacing(1.5)`. Half steps stop at 2.5\n * and the gaps widen from there, so neighbouring steps stay visibly distinct.\n */\nexport const spacingSteps = [0.5, 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8] as const;\n","const ROOT_FONT_SIZE = 16;\n\n/**\n * The modular type scale behind the text styles: a font size is\n * `base × ratio^step`. Step 0 is body text and the ratio is a major second.\n */\nexport const typeScale = { base: 16, ratio: 1.125 } as const;\n\n/**\n * A step in pixels, rounded to a whole pixel. Figma variables can't calculate,\n * so rounding here is what lets `fontStep/6` in Figma and `--lea-font-step-6`\n * in CSS hold the same number.\n */\nexport const fontStepPx = (step: number) =>\n Math.round(typeScale.base * typeScale.ratio ** step);\n\nexport const fontStep = (step: number) =>\n `${fontStepPx(step) / ROOT_FONT_SIZE}rem`;\n\n/**\n * The steps emitted as `--lea-font-step-{step}`. A step below body text spells\n * out the minus sign: `--lea-font-step-minus-1` is `fontStep(-1)`.\n */\nexport const fontSteps = [\n -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n] as const;\n\nexport type FontStep = (typeof fontSteps)[number];\n","import { fontWeights } from \"./font-weights\";\nimport { lineHeights } from \"./line-heights\";\nimport { fontStep, type FontStep } from \"./type-scale\";\n\ntype TextStyleDefinition = {\n /** The step on the type scale, see type-scale.ts. */\n step: FontStep;\n fontWeight: keyof typeof fontWeights;\n lineHeight: keyof typeof lineHeights;\n letterSpacing: string;\n};\n\nconst style = (\n step: FontStep,\n fontWeight: TextStyleDefinition[\"fontWeight\"],\n lineHeight: TextStyleDefinition[\"lineHeight\"],\n letterSpacing = \"0\"\n): TextStyleDefinition => ({ step, fontWeight, lineHeight, letterSpacing });\n\n/**\n * Text styles, named `{role}-{size}` after what the text does, not after the\n * element it sits in: `heading-lg` is an `h1` on one page and an `h3` on the\n * next. Take the element from the page hierarchy and the style from the design.\n *\n * A style holds no values of its own. It points at a step on the type scale, a\n * font weight and a line height, so a size is retuned in one place. `body` and\n * `label` move one step at a time; `heading` and `display` move two, because\n * neighbouring steps are too close to tell two headings apart.\n *\n * The Figma text styles `heading/lg` and so on mirror this file.\n */\nexport const textStyles = {\n display: {\n sm: style(10, \"semibold\", \"none\"),\n md: style(12, \"semibold\", \"none\"),\n },\n heading: {\n xs: style(0, \"semibold\", \"snug\"),\n sm: style(2, \"semibold\", \"snug\"),\n md: style(4, \"semibold\", \"snug\"),\n lg: style(6, \"semibold\", \"tight\"),\n xl: style(8, \"semibold\", \"tight\"),\n },\n body: {\n xs: style(-2, \"regular\", \"normal\"),\n sm: style(-1, \"regular\", \"normal\"),\n md: style(0, \"regular\", \"normal\"),\n lg: style(1, \"regular\", \"normal\"),\n },\n label: {\n sm: style(-2, \"medium\", \"tight\"),\n md: style(-1, \"medium\", \"tight\"),\n lg: style(0, \"medium\", \"tight\"),\n },\n} satisfies Record<string, Record<string, TextStyleDefinition>>;\n\ntype TextStyles = typeof textStyles;\n\n/** `\"heading-lg\"`, `\"body-sm\"` and so on. */\nexport type TextStyleToken = {\n [Role in keyof TextStyles]: `${Role & string}-${keyof TextStyles[Role] &\n string}`;\n}[keyof TextStyles];\n\n/** Every style as `[name, definition]`, in the order above. */\nexport const textStyleEntries = Object.entries(textStyles).flatMap(\n ([role, sizes]) =>\n Object.entries(sizes).map(\n ([size, definition]) =>\n [`${role}-${size}` as TextStyleToken, definition] as const\n )\n);\n\nconst definitions = Object.fromEntries(textStyleEntries) as Record<\n TextStyleToken,\n TextStyleDefinition\n>;\n\n/** The CSS values of a text style, for `sx` and theme files. */\nexport const resolveTextStyle = (name: TextStyleToken) => {\n const { step, fontWeight, lineHeight, letterSpacing } = definitions[name];\n\n return {\n fontSize: fontStep(step),\n fontWeight: fontWeights[fontWeight],\n lineHeight: lineHeights[lineHeight],\n letterSpacing,\n };\n};\n","export const easings = {\n standard: \"ease-in-out\",\n spring: \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n} as const;\n\nexport const durations = {\n fast: \"0.15s\",\n normal: \"0.2s\",\n emphasis: \"0.3s\",\n} as const;\n\nexport const transition = (\n properties: string[],\n duration: string = durations.normal,\n easing: string = easings.standard,\n) => properties.map((p) => `${p} ${duration} ${easing}`).join(\", \");\n","import { palette } from \"../tokens\";\n\nexport const focusVisibleStyles = {\n \"&:focus-visible\": {\n outline: \"2px solid\",\n outlineColor: palette.text.base,\n },\n};\n","import { createTranslation } from \"../index\";\n\n/**\n * Translated labels for `CalendarHeader`: the prev/next month button names and\n * the month-year label's \"switch to year/day view\" suffix. Consumers can\n * override any of these per-instance via `DatePicker`'s `calendarHeaderLabels`\n * prop.\n */\nexport const useCalendarHeaderLabels = createTranslation({\n previousMonth: { no: \"Forrige måned\", se: \"Föregående månad\", fi: \"Edellinen kuukausi\", es: \"Mes anterior\" },\n nextMonth: { no: \"Neste måned\", se: \"Nästa månad\", fi: \"Seuraava kuukausi\", es: \"Mes siguiente\" },\n switchToYearView: { no: \"bytt til årsvisning\", se: \"byt till årsvy\", fi: \"vaihda vuosinäkymään\", es: \"cambiar a vista de año\" },\n switchToDayView: { no: \"bytt til datovisning\", se: \"byt till datumvy\", fi: \"vaihda päivänäkymään\", es: \"cambiar a vista de fecha\" },\n});\n\nexport type CalendarHeaderLabels = Partial<ReturnType<typeof useCalendarHeaderLabels>>;\n","import { focusVisibleStyles } from \"../theme/utils\";\nimport Box from \"@mui/material/Box\";\nimport IconButton from \"@mui/material/IconButton\";\nimport { usePickerAdapter } from \"@mui/x-date-pickers/hooks\";\nimport { type PickersCalendarHeaderProps } from \"@mui/x-date-pickers/PickersCalendarHeader\";\nimport { ChevronDown, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport {\n useCalendarHeaderLabels,\n type CalendarHeaderLabels,\n} from \"./use-calendar-header-labels\";\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nconst chevronButtonSx = {\n width: 40,\n height: 40,\n border: \"1px solid\",\n borderColor: \"border.base\",\n color: \"text.base\",\n \"&:hover\": { backgroundColor: \"bg.subtle\" },\n \"&.Mui-disabled\": { opacity: 0.45, color: \"text.base\" },\n} as const;\n\n/**\n * Replaces MUI's default calendar header for the day picker with the Lea Bank\n * layout: a previous / next month chevron on each side and a centered, clickable\n * month-year label (with a caret) that switches to the year view. The chevrons\n * are muted at the `minDate` / `maxDate` bounds. Month navigation is only shown\n * while the day grid is visible; in the year view only the label remains.\n */\nexport function CalendarHeader({\n currentMonth,\n onMonthChange,\n onViewChange,\n view,\n minDate,\n maxDate,\n disabled,\n labels,\n}: PickersCalendarHeaderProps & { labels?: CalendarHeaderLabels }) {\n const adapter = usePickerAdapter();\n const t = useCalendarHeaderLabels();\n const l = { ...t, ...labels };\n\n const isDayView = view === \"day\";\n const prevMuted =\n !!disabled ||\n (minDate != null && !adapter.isAfter(currentMonth, adapter.startOfMonth(minDate)));\n const nextMuted =\n !!disabled ||\n (maxDate != null &&\n !adapter.isBefore(\n adapter.startOfMonth(currentMonth),\n adapter.startOfMonth(maxDate),\n ));\n\n const label = `${cap(adapter.formatByString(currentMonth, \"LLLL\"))} ${adapter.getYear(\n currentMonth,\n )}`;\n const switchLabel = `${label}, ${\n isDayView ? l.switchToYearView : l.switchToDayView\n }`;\n\n return (\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 1,\n px: 0.5,\n pb: 1,\n }}\n >\n {isDayView ? (\n <IconButton\n aria-label={l.previousMonth}\n disabled={prevMuted}\n onClick={() => onMonthChange(adapter.addMonths(currentMonth, -1))}\n sx={chevronButtonSx}\n >\n <ChevronLeft size={20} aria-hidden />\n </IconButton>\n ) : (\n <Box sx={{ width: 40, height: 40 }} />\n )}\n\n <Box\n component=\"button\"\n type=\"button\"\n aria-label={switchLabel}\n disabled={!!disabled}\n onClick={() => onViewChange?.(isDayView ? \"year\" : \"day\")}\n sx={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 0.75,\n px: 1,\n py: 0.5,\n border: \"none\",\n borderRadius: 2,\n background: \"transparent\",\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n fontSize: \"1.0625rem\",\n fontWeight: \"fontWeightMedium\",\n color: \"text.base\",\n \"&:hover\": { backgroundColor: \"bg.subtle\" },\n \"&:disabled\": { cursor: \"default\", opacity: 0.45 },\n ...focusVisibleStyles,\n }}\n >\n {label}\n <Box\n component=\"span\"\n sx={{\n display: \"inline-flex\",\n color: \"primary.base\",\n transition: \"transform .15s\",\n transform: isDayView ? \"none\" : \"rotate(180deg)\",\n }}\n >\n <ChevronDown size={16} aria-hidden />\n </Box>\n </Box>\n\n {isDayView ? (\n <IconButton\n aria-label={l.nextMonth}\n disabled={nextMuted}\n onClick={() => onMonthChange(adapter.addMonths(currentMonth, 1))}\n sx={chevronButtonSx}\n >\n <ChevronRight size={20} aria-hidden />\n </IconButton>\n ) : (\n <Box sx={{ width: 40, height: 40 }} />\n )}\n </Box>\n );\n}\n","import Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\nimport { type ReactNode } from \"react\";\n\nexport type DrawerToolbarProps = {\n /** Small uppercase context label shown above the title. */\n eyebrow?: ReactNode;\n /** Drawer heading. */\n title?: ReactNode;\n /** id set on the title so the drawer dialog can reference it via `aria-labelledby`. */\n titleId?: string;\n /** Set by MUI's layout; when true the toolbar must not render. */\n hidden?: boolean;\n};\n\n/**\n * Replaces the default `DatePickerToolbar`. Renders the Lea Bank drawer header:\n * an optional purple uppercase eyebrow and a large title. Both are supplied by\n * `DatePicker` through `slotProps.toolbar`.\n */\nexport function DrawerToolbar({ eyebrow, title, titleId, hidden }: DrawerToolbarProps) {\n if (hidden) return null;\n\n return (\n <Box sx={{ px: 3, pt: 1, pb: 1.5 }}>\n {eyebrow != null && (\n <Typography\n component=\"p\"\n sx={{\n color: \"text.accent\",\n fontWeight: \"fontWeightBold\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n fontSize: \"0.8125rem\",\n mb: 0.5,\n }}\n >\n {eyebrow}\n </Typography>\n )}\n {title != null && (\n <Typography\n component=\"h2\"\n id={titleId}\n sx={{ color: \"text.base\", fontWeight: \"fontWeightMedium\", fontSize: \"1.75rem\" }}\n >\n {title}\n </Typography>\n )}\n </Box>\n );\n}\n","import { CSSObject } from \"@mui/material\";\nimport { palette } from \"../../theme/tokens\";\n\n/**\n * The outlined field of the date picker, the one field that still wraps MUI:\n * its height, padding, collapsed notch and border-state colours. The other\n * fields get the same look from `input.module.css`.\n */\n\n// The height of every single-line field.\nexport const FIELD_HEIGHT = \"54px\";\n\n// Vertical padding leaves room for the floated label above the value.\nexport const fieldPadding = {\n paddingInlineStart: \"0.9rem\",\n paddingBlockStart: \"1.5rem\",\n paddingBlockEnd: \"0.5rem\",\n} as const;\n\n/**\n * We draw the field border ourselves, so MUI's notch and its legend are\n * collapsed. Takes the class of the notched outline, which the picker's\n * `PickersOutlinedInput` names differently from MUI's `OutlinedInput`.\n */\nexport const collapsedNotch = (outlineClass: string): CSSObject => ({\n [`& .${outlineClass}`]: {\n top: 0,\n inset: 0,\n },\n [`& .${outlineClass} legend`]: {\n display: \"none\",\n },\n});\n\n/**\n * Hover / focus / error border treatment of the field. Takes the class of the\n * notched outline, for the same reason as `collapsedNotch`.\n */\nexport const fieldBorderStates = (outlineClass: string): CSSObject => ({\n [`&:hover:not(:focus-within):not(.Mui-disabled):not(.Mui-error) .${outlineClass}`]:\n {\n borderWidth: \"2px\",\n borderColor: palette.border.strong,\n },\n [`&:focus-within:not(.Mui-error) .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.border.accent,\n },\n [`&.Mui-error .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.status.error.base,\n },\n [`&.Mui-error:hover:not(:focus-within):not(.Mui-disabled) .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.status.error.base,\n },\n [`&.Mui-error:focus-within .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.status.error.base,\n },\n});\n","import { Components, Theme } from \"@mui/material\";\nimport { fontSizes, palette, shadows, shape, spacing } from \"../../theme/tokens\";\nimport {\n FIELD_HEIGHT,\n collapsedNotch,\n fieldBorderStates,\n fieldPadding,\n} from \"./field-base\";\n\n// The picker's accessible field (PickersOutlinedInput) shares the outlined-field\n// sizing/border treatment with the other inputs; only the notched-outline class\n// name differs.\nconst NOTCH = \"MuiPickersOutlinedInput-notchedOutline\";\n\n/**\n * Styling for the MUI X Date Pickers surfaces. The day picker uses MUI's\n * `DateCalendar` day grid (with a custom centered `calendarHeader`, see\n * `calendar-header.tsx`); month/year configurations use MUI's standard themed\n * month / year grids. This file owns the visual treatment of the trigger field,\n * the desktop popover and the day / month / year grids, using design tokens.\n *\n * In `@mui/x-date-pickers` v9 the legacy single-`TextField` field structure was\n * removed, so the trigger is always the accessible `PickersTextField`. We theme\n * `MuiPickersOutlinedInput` here to match the library's `MuiOutlinedInput`\n * (collapsed notch, fixed height, shared padding) — that is what fixes the\n * label-over-border and spacing issues, since those theme keys differ.\n */\nexport const datePickerTheme: Pick<\n Components<Theme>,\n | \"MuiPickersOutlinedInput\"\n | \"MuiDateCalendar\"\n | \"MuiDayCalendar\"\n | \"MuiPickerDay\"\n | \"MuiMonthCalendar\"\n | \"MuiYearCalendar\"\n | \"MuiPickerPopper\"\n | \"MuiPickersLayout\"\n> = {\n MuiPickersOutlinedInput: {\n styleOverrides: {\n root: {\n boxSizing: \"border-box\",\n alignItems: \"flex-start\",\n padding: 0,\n borderRadius: shape.xl,\n height: FIELD_HEIGHT,\n lineHeight: \"normal\",\n\n // We draw the border ourselves, so collapse the notch and its legend.\n ...collapsedNotch(NOTCH),\n\n // --- Border states (shared with the other outlined fields) ---\n ...fieldBorderStates(NOTCH),\n\n // --- Adornments (the open-picker icon button) ---\n \"& .MuiInputAdornment-root\": {\n alignSelf: \"center\",\n },\n \"& .MuiInputAdornment-positionEnd\": {\n marginRight: spacing(2),\n },\n },\n sectionsContainer: {\n ...fieldPadding,\n paddingInlineEnd: \"0.9rem\",\n },\n },\n },\n MuiPickersLayout: {\n styleOverrides: {\n root: {\n // Always stack vertically (toolbar → calendar). MUI's grid otherwise\n // switches to a side-by-side landscape layout on wide screens, which is\n // wrong for both the popover and the bottom drawer.\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: spacing(2),\n padding: spacing(3),\n paddingBlockEnd: spacing(1),\n \"& .MuiPickersLayout-contentWrapper\": {\n width: \"100%\",\n },\n },\n },\n },\n MuiDateCalendar: {\n styleOverrides: {\n root: {\n // Fill the input-width popover (see `sameWidthAsInput` in datepicker.tsx)\n // rather than MUI's fixed calendar width, so the grid lines up with the field.\n width: \"100%\",\n maxHeight: \"none\",\n },\n },\n },\n MuiDayCalendar: {\n styleOverrides: {\n header: {\n justifyContent: \"space-between\",\n },\n weekContainer: {\n justifyContent: \"space-between\",\n margin: 0,\n },\n weekDayLabel: {\n fontSize: fontSizes.sm,\n color: palette.text.subtle,\n },\n },\n },\n MuiPickerDay: {\n styleOverrides: {\n root: {\n width: 40,\n height: 40,\n fontSize: fontSizes.md,\n color: palette.text.base,\n backgroundColor: \"transparent\",\n \"&:hover, &:focus\": {\n backgroundColor: palette.bg.subtle,\n },\n \"&.MuiPickerDay-selected\": {\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n \"&:hover, &:focus\": {\n backgroundColor: palette.primary.hover,\n },\n },\n \"&.Mui-disabled, &.MuiPickerDay-disabled\": {\n color: palette.text.muted,\n },\n \"&.MuiPickerDay-today:not(.MuiPickerDay-selected)\": {\n outline: `1px solid ${palette.border.base}`,\n outlineOffset: -1,\n },\n },\n },\n },\n MuiMonthCalendar: {\n styleOverrides: {\n root: {\n width: \"100%\",\n justifyContent: \"space-between\",\n columnGap: 0,\n rowGap: spacing(1.5),\n },\n button: {\n flex: \"0 0 31%\",\n maxWidth: \"31%\",\n fontSize: fontSizes.md,\n fontWeight: 500,\n color: palette.text.base,\n backgroundColor: \"transparent\",\n borderRadius: shape[\"3xl\"],\n height: spacing(6),\n margin: 0,\n \"&:hover, &:focus\": {\n backgroundColor: palette.bg.subtle,\n },\n \"&.Mui-selected, &.MuiMonthCalendar-selected\": {\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n \"&:hover, &:focus\": {\n backgroundColor: palette.primary.hover,\n },\n },\n \"&.Mui-disabled, &.MuiMonthCalendar-disabled\": {\n backgroundColor: \"transparent\",\n color: palette.text.muted,\n },\n },\n },\n },\n MuiYearCalendar: {\n styleOverrides: {\n root: {\n width: \"100%\",\n justifyContent: \"space-between\",\n columnGap: 0,\n rowGap: spacing(1.5),\n // Keep MUI's default constrained, scrollable height so the calendar can\n // auto-scroll the current / selected year into view on open. Removing it\n // (maxHeight: none) makes the list grow full-height and never scroll.\n },\n button: {\n flex: \"0 0 31%\",\n maxWidth: \"31%\",\n fontSize: fontSizes.md,\n fontWeight: 500,\n color: palette.text.base,\n backgroundColor: \"transparent\",\n borderRadius: shape[\"3xl\"],\n height: spacing(6),\n margin: 0,\n \"&:hover, &:focus\": {\n backgroundColor: palette.bg.subtle,\n },\n \"&.Mui-selected, &.MuiYearCalendar-selected\": {\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n \"&:hover, &:focus\": {\n backgroundColor: palette.primary.hover,\n },\n },\n \"&.Mui-disabled, &.MuiYearCalendar-disabled\": {\n backgroundColor: \"transparent\",\n color: palette.text.muted,\n },\n },\n },\n },\n MuiPickerPopper: {\n styleOverrides: {\n paper: {\n // The popper itself is sized to the input width (see `sameWidthAsInput`);\n // make the paper fill it so the calendar lines up with the field.\n width: \"100%\",\n boxSizing: \"border-box\",\n borderRadius: shape.xl,\n boxShadow: shadows.md,\n border: `1px solid ${palette.border.subtle}`,\n },\n },\n },\n};\n","import { Components, Theme } from \"@mui/material\";\nimport { resolveTextStyle } from \"../../theme/tokens\";\n\nexport const formControlTheme: Components<Theme>[\"MuiFormControl\"] = {\n defaultProps: {\n variant: \"outlined\",\n },\n styleOverrides: {\n root: {\n position: \"relative\",\n },\n },\n};\n\n/**\n * Helper text under the date picker, the one field that still wraps MUI, in\n * the same text style as under the other fields (`field-parts.module.css`).\n */\nexport const formHelperTextTheme: Components<Theme>[\"MuiFormHelperText\"] = {\n styleOverrides: {\n root: resolveTextStyle(\"body-sm\"),\n },\n};\n","import { Components, Theme } from \"@mui/material\";\nimport {\n palette,\n durations,\n easings,\n shape,\n spacing,\n transition,\n} from \"../../theme/tokens\";\nimport { focusVisibleStyles } from \"../../theme/utils\";\n\nexport const iconButtonTheme: Components<Theme>[\"MuiIconButton\"] = {\n defaultProps: {\n size: \"large\",\n },\n styleOverrides: {\n root: {\n ...focusVisibleStyles,\n borderRadius: shape.full,\n textTransform: \"none\",\n border: \"2px solid\",\n transition: [\n transition([\"background-color\"], durations.emphasis, easings.spring),\n transition([\"color\"], durations.emphasis, easings.spring),\n ].join(\", \"),\n svg: {\n flexShrink: 0,\n },\n },\n sizeSmall: {\n padding: spacing(1),\n svg: {\n width: 16,\n height: 16,\n },\n },\n sizeLarge: {\n padding: spacing(1),\n svg: {\n width: 24,\n height: 24,\n },\n },\n },\n variants: [\n {\n props: {\n color: \"primary\",\n },\n style: {\n borderColor: palette.border.strong,\n color: palette.text.base,\n \"&:hover\": {\n borderColor: palette.primary.base,\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n },\n },\n },\n {\n props: {\n color: \"secondary\",\n },\n style: {\n borderColor: palette.primary.base,\n color: palette.primary.base,\n \"&:hover\": {\n borderColor: palette.border.strong,\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n },\n },\n },\n ],\n};\n","import { Components, Theme } from \"@mui/material\";\n\n/**\n * The floated label of the one field that still wraps MUI, the date picker,\n * at the height the label of `Input` floats to.\n */\nexport const inputLabelTheme: Components<Theme>[\"MuiInputLabel\"] = {\n styleOverrides: {\n shrink: {\n top: \"1rem\",\n },\n },\n};\n","import { fontFamily } from \"../../theme/tokens/font-family\";\nimport { fontSizes } from \"../../theme/tokens/font-sizes\";\nimport { fontWeights } from \"../../theme/tokens/font-weights\";\nimport { palette } from \"../../theme/tokens/palette\";\n\n/**\n *\n * We are not following the MUI typography tokens because\n * sometimes we need the size of an h1 but not the h1 component.\n * Overriding it here at the root will give us more control over the typography.\n *\n */\n\nexport const typography = {\n fontFamily: fontFamily,\n fontWeight: fontWeights.regular,\n color: palette.text.base,\n \"& strong\": {\n fontWeight: fontWeights.medium,\n },\n \"& a\": {\n color: `${palette.text.base} !important`,\n textDecorationColor: `${palette.text.base} !important`,\n fontWeight: fontWeights.regular,\n },\n h1: undefined,\n h2: undefined,\n h3: undefined,\n h4: undefined,\n h5: undefined,\n h6: undefined,\n subtitle1: undefined,\n subtitle2: undefined,\n heading: {\n fontFamily: fontFamily,\n fontWeight: fontWeights.medium,\n letterSpacing: \"0.02em\",\n },\n body1: {\n fontSize: fontSizes.md,\n fontWeight: fontWeights.regular,\n },\n body2: {\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.regular,\n },\n button: undefined,\n caption: undefined,\n};\n","import { createTheme, type ThemeOptions } from \"@mui/material/styles\";\n// Types only: registers the `@mui/x-date-pickers` component keys\n// (MuiPickerDay, MuiDayCalendar, …) so the overrides below type-check.\nimport type {} from \"@mui/x-date-pickers/themeAugmentation\";\nimport { breakpoints, palette } from \"../../theme/tokens\";\nimport type { BrandColor } from \"../../theme/types\";\nimport { datePickerTheme } from \"./date-picker.theme\";\nimport { formControlTheme, formHelperTextTheme } from \"./form-control.theme\";\nimport { iconButtonTheme } from \"./icon-button.theme\";\nimport { inputLabelTheme } from \"./input.theme\";\nimport { typography } from \"./typography\";\n\n/**\n * MUI's own components read a colour as `main`, `dark`, `light` and\n * `contrastText`, and `createTheme` throws without `main`. These four are an\n * adapter for MUI's internals, added here and nowhere else: the design tokens\n * only know `base`, `hover`, `subtle` and `contrast`.\n */\nconst muiColor = (color: BrandColor) => ({\n ...color,\n main: color.base,\n dark: color.hover,\n light: color.subtle,\n contrastText: color.contrast,\n});\n\n/**\n * The MUI theme of the date picker, the one component that still wraps MUI.\n * It is private: `DatePicker` puts it around itself, so an app neither\n * provides it nor sees it, and it does not reach any MUI component the app\n * renders on its own.\n *\n * The palette is the token palette as it is, so `sx` in the picker's own\n * parts can name a token by its path (\"text.subtle\", \"bg.base\"). MUI's types\n * do not know those groups, and are not told: a module augmentation would\n * change the theme types of every app that has MUI installed.\n */\nexport const theme = createTheme({\n breakpoints: { values: breakpoints },\n palette: {\n ...palette,\n primary: muiColor(palette.primary),\n secondary: muiColor(palette.secondary),\n } as ThemeOptions[\"palette\"],\n typography,\n components: {\n ...datePickerTheme,\n MuiIconButton: iconButtonTheme,\n MuiFormControl: formControlTheme,\n MuiFormHelperText: formHelperTextTheme,\n MuiInputLabel: inputLabelTheme,\n },\n});\n","import { createTranslation } from \"../index\";\n\n/**\n * Translated default titles for `DatePicker`'s mobile drawer header, used when\n * the `title` prop is omitted.\n */\nexport const useDatePickerTitleLabels = createTranslation({\n selectDate: { no: \"Velg dato\", se: \"Välj datum\", fi: \"Valitse päivä\", es: \"Seleccionar fecha\" },\n selectMonthYear: { no: \"Velg måned og år\", se: \"Välj månad och år\", fi: \"Valitse kuukausi ja vuosi\", es: \"Seleccionar mes y año\" },\n});\n","import { createTranslation } from \"../index\";\n\n/**\n * Translated labels for `ViewToggle`: the month/year segment labels and the\n * `role=\"group\"` accessible name. Consumers can override any of these\n * per-instance via `DatePicker`'s `viewToggleLabels` prop.\n */\nexport const useViewToggleLabels = createTranslation({\n month: { no: \"Måned\", se: \"Månad\", fi: \"Kuukausi\", es: \"Mes\" },\n year: { no: \"År\", se: \"År\", fi: \"Vuosi\", es: \"Año\" },\n selectView: { no: \"Velg visning\", se: \"Välj vy\", fi: \"Valitse näkymä\", es: \"Seleccionar vista\" },\n});\n\nexport type ViewToggleLabels = Partial<ReturnType<typeof useViewToggleLabels>>;\n","import { focusVisibleStyles } from \"../theme/utils\";\nimport Box from \"@mui/material/Box\";\nimport {\n useViewToggleLabels,\n type ViewToggleLabels,\n} from \"./use-view-toggle-labels\";\n\nexport type ToggleView = \"month\" | \"year\";\nexport type MonthYearOrder = \"month-year\" | \"year-month\";\n\nconst getSegments = (\n order: MonthYearOrder,\n labels: Record<\"month\" | \"year\", string>,\n): { view: ToggleView; label: string }[] => {\n const month = { view: \"month\" as const, label: labels.month };\n const year = { view: \"year\" as const, label: labels.year };\n return order === \"year-month\" ? [year, month] : [month, year];\n};\n\nexport type ViewToggleProps = {\n /** The currently active view. */\n currentView: ToggleView;\n /** Called with the view the user switched to. */\n onViewChange: (view: ToggleView) => void;\n /** Order of month and year segments. Default: \"month-year\" */\n order?: MonthYearOrder;\n /** Override the built-in translated labels per-instance. */\n labels?: ViewToggleLabels;\n};\n\n/**\n * Segmented control for the month/year-only picker. Shows two pill segments,\n * month first then year, with the active segment raised on a white pill. Used as\n * the header of the month/year `viewRenderers`; switching segments changes the\n * picker view. Each segment is a toggle button exposing `aria-pressed`, grouped\n * under a labelled `role=\"group\"`.\n */\nexport function ViewToggle({\n currentView,\n onViewChange,\n order = \"month-year\",\n labels,\n}: ViewToggleProps) {\n const t = useViewToggleLabels();\n const l = { ...t, ...labels };\n const segments = getSegments(order, l);\n return (\n <Box\n role=\"group\"\n aria-label={l.selectView}\n sx={{\n display: \"flex\",\n gap: 0.5,\n p: 0.5,\n mb: 1,\n borderRadius: \"999px\",\n backgroundColor: \"bg.subtle\",\n }}\n >\n {segments.map(({ view, label }) => {\n const active = view === currentView;\n return (\n <Box\n key={view}\n component=\"button\"\n type=\"button\"\n aria-pressed={active}\n onClick={() => onViewChange(view)}\n sx={{\n flex: 1,\n minHeight: 40,\n border: \"none\",\n borderRadius: \"999px\",\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n fontSize: \"0.9375rem\",\n fontWeight: \"fontWeightMedium\",\n backgroundColor: active ? \"bg.base\" : \"transparent\",\n color: active ? \"text.base\" : \"text.subtle\",\n boxShadow: active ? \"0px 1px 3px rgba(0, 0, 0, 0.12)\" : \"none\",\n transition: \"background-color .15s, color .15s\",\n \"&:hover\": {\n color: \"text.base\",\n },\n ...focusVisibleStyles,\n }}\n >\n {label}\n </Box>\n );\n })}\n </Box>\n );\n}\n","import { type DatePickerProps } from \"@mui/x-date-pickers/DatePicker\";\nimport { type DateViewRendererProps } from \"@mui/x-date-pickers/dateViewRenderers\";\nimport { usePickerActionsContext } from \"@mui/x-date-pickers/hooks\";\nimport { type DateView } from \"@mui/x-date-pickers/models\";\nimport { MonthCalendar } from \"@mui/x-date-pickers/MonthCalendar\";\nimport { YearCalendar } from \"@mui/x-date-pickers/YearCalendar\";\nimport { type MonthYearOrder, ViewToggle } from \"./view-toggle\";\nimport { type ViewToggleLabels } from \"./use-view-toggle-labels\";\n\ntype RendererProps = DateViewRendererProps<DateView>;\n\n/**\n * Factory function that creates `viewRenderers` for the month/year-only picker.\n * The day view is intentionally absent (that mode uses MUI's standard `DateCalendar`);\n * these only drive the `views={[\"year\", \"month\"]}` configuration with the Måned / År toggle\n * and a month to year drill. Supports configurable order via `monthYearOrder`.\n */\nexport const createDateViewRenderers = (\n order: MonthYearOrder = \"month-year\",\n labels?: ViewToggleLabels,\n): DatePickerProps[\"viewRenderers\"] => {\n const isYearFirst = order === \"year-month\";\n\n /**\n * Month view of the month/year-only picker: the segmented toggle above MUI's\n * `MonthCalendar`. Behavior depends on `order`:\n * - month-first: intermediate step, advances to year view\n * - year-first: final step, commits and closes\n */\n const MonthView = (props: RendererProps) => {\n const actions = usePickerActionsContext();\n return (\n <div>\n <ViewToggle\n currentView=\"month\"\n onViewChange={(view) => actions.setView(view)}\n order={order}\n labels={labels}\n />\n <MonthCalendar\n value={props.value ?? null}\n referenceDate={props.referenceDate}\n minDate={props.minDate}\n maxDate={props.maxDate}\n disableFuture={props.disableFuture}\n disablePast={props.disablePast}\n shouldDisableMonth={props.shouldDisableMonth}\n timezone={props.timezone}\n onChange={(date) => {\n if (isYearFirst) {\n // In year-first mode, month is the final step\n actions.setValue(date, { changeImportance: \"accept\" });\n } else {\n // In month-first mode, month is intermediate, advance to year\n actions.setValue(date, { changeImportance: \"set\" });\n actions.setView(\"year\");\n }\n }}\n />\n </div>\n );\n };\n\n /**\n * Year view of the month/year-only picker. Behavior depends on `order`:\n * - month-first: final step, commits and closes\n * - year-first: intermediate step, advances to month view\n */\n const YearView = (props: RendererProps) => {\n const actions = usePickerActionsContext();\n return (\n <div>\n <ViewToggle\n currentView=\"year\"\n onViewChange={(view) => actions.setView(view)}\n order={order}\n labels={labels}\n />\n <YearCalendar\n value={props.value ?? null}\n referenceDate={props.referenceDate}\n minDate={props.minDate}\n maxDate={props.maxDate}\n disableFuture={props.disableFuture}\n disablePast={props.disablePast}\n shouldDisableYear={props.shouldDisableYear}\n timezone={props.timezone}\n onChange={(date) => {\n if (isYearFirst) {\n // In year-first mode, year is intermediate, advance to month\n actions.setValue(date, { changeImportance: \"set\" });\n actions.setView(\"month\");\n } else {\n // In month-first mode, year is the final step\n actions.setValue(date, { changeImportance: \"accept\" });\n }\n }}\n />\n </div>\n );\n };\n\n return {\n month: (props) => <MonthView {...props} />,\n year: (props) => <YearView {...props} />,\n };\n};\n","\"use client\";\n\nimport { type DialogProps } from \"@mui/material/Dialog\";\nimport { type PopperProps } from \"@mui/material/Popper\";\nimport { ThemeProvider } from \"@mui/material/styles\";\nimport useMediaQuery from \"@mui/material/useMediaQuery\";\nimport { AdapterDateFns } from \"@mui/x-date-pickers/AdapterDateFns\";\nimport {\n DatePicker as MuiDatePicker,\n type DatePickerProps as MuiDatePickerProps,\n} from \"@mui/x-date-pickers/DatePicker\";\nimport { LocalizationProvider } from \"@mui/x-date-pickers/LocalizationProvider\";\nimport { esES, fiFI, nbNO, svSE } from \"@mui/x-date-pickers/locales\";\nimport { format as formatDate, type Locale } from \"date-fns\";\nimport { es, fi, nb, sv } from \"date-fns/locale\";\nimport { CalendarSearch } from \"lucide-react\";\nimport {\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { useFocusTargetRef } from \"../components/form/use-focus-target-ref\";\n// From the main entry, which this entry leaves out of its bundle: the drawer\n// and the language have to be the app's own copies. See ./index.ts.\nimport { Drawer, useLanguage, type Language } from \"../index\";\nimport { CalendarHeader } from \"./calendar-header\";\nimport { DrawerToolbar } from \"./drawer-toolbar\";\nimport { theme } from \"./theme\";\nimport { type CalendarHeaderLabels } from \"./use-calendar-header-labels\";\nimport { useDatePickerTitleLabels } from \"./use-datepicker-title-labels\";\nimport { type ViewToggleLabels } from \"./use-view-toggle-labels\";\nimport { createDateViewRenderers } from \"./view-renderers\";\nimport { type MonthYearOrder } from \"./view-toggle\";\n\nexport {\n type CalendarHeaderLabels,\n type MonthYearOrder,\n type ViewToggleLabels,\n};\n\ntype Slots = NonNullable<MuiDatePickerProps[\"slots\"]>;\n\nconst DEFAULT_VIEWS = [\"year\", \"month\", \"day\"] as const;\n\n// Where the popover takes over from the drawer, unless `desktopModeMediaQuery`\n// says otherwise.\nconst DESKTOP_QUERY = theme.breakpoints.up(\"sm\");\n\n/*\n * The picker sheet is rounder than the default drawer. There is no 24px step\n * in src/theme/tokens/shape.ts, so the value is set through the drawer's\n * `--drawer-radius` custom property rather than overriding `border-radius`,\n * which the drawer sets with a more specific selector.\n */\nconst SHEET_STYLE = { \"--drawer-radius\": \"1.5rem\" } as CSSProperties;\n\n// The field is a row of editable parts (day, month, year), each a spinbutton.\nconst FOCUS_TARGETS = ['[role=\"spinbutton\"]'] as const;\n\n// Maps the provider language to a `date-fns` locale, so month names and weekday\n// formatting follow the single `language` prop of `LeaProvider`.\nconst LOCALE_FOR_LANGUAGE: Record<Language, Locale> = {\n no: nb,\n se: sv,\n fi: fi,\n es: es,\n};\n\n// MUI X ships translations for the picker chrome (\"Velg dato\", \"Forrige\n// måned\", \"Avbryt\", …), which otherwise falls back to English.\nconst PICKER_TEXT: Record<Language, typeof nbNO> = {\n no: nbNO,\n se: svSE,\n fi: fiFI,\n es: esES,\n};\n\nconst localeTextFor = (language: Language) =>\n PICKER_TEXT[language].components.MuiLocalizationProvider.defaultProps\n .localeText;\n\nconst OpenPickerIcon = () => <CalendarSearch size={20} aria-hidden />;\n\n// Lowercase two-letter weekday labels to match the design, from the resolved\n// locale rather than a fixed array (`nb` is unchanged: sø ma ti on to fr lø).\nconst weekdayFormatter = (locale: Locale) => (date: Date) =>\n formatDate(date, \"EEEEEE\", { locale }).toLowerCase();\n\n/**\n * Sizes the desktop popover to the trigger field's width, so the calendar always\n * lines up with the input (rather than sizing to the calendar's own content).\n */\nconst sameWidthAsInput: NonNullable<PopperProps[\"modifiers\"]>[number] = {\n name: \"sameWidth\",\n enabled: true,\n phase: \"beforeWrite\",\n requires: [\"computeStyles\"],\n fn: ({ state }) => {\n state.styles.popper.width = `${state.rects.reference.width}px`;\n },\n effect: ({ state }) => {\n const reference = state.elements.reference as HTMLElement;\n state.elements.popper.style.width = `${reference.offsetWidth}px`;\n },\n};\n\n/**\n * Renders the mobile views inside a bottom sheet with the Lea Bank chrome\n * (rounded top corners + grab handle) instead of MUI's default modal `Dialog`.\n * The picker's `dialog` slot is called with `Dialog` props, so we adapt them to\n * the drawer's `open` / `onOpenChange` pair. MUI passes the generated dialog\n * name via `slotProps.paper[\"aria-labelledby\"]` (pointing at the toolbar title\n * id), so we forward it onto the popup (the `role=\"dialog\"` element) to give\n * the sheet an accessible name.\n */\nfunction DrawerDialog({ open, onClose, children, slotProps }: DialogProps) {\n const forwardedPaper =\n typeof slotProps?.paper === \"object\" ? slotProps.paper : undefined;\n const ariaLabelledby = (\n forwardedPaper as { \"aria-labelledby\"?: string } | undefined\n )?.[\"aria-labelledby\"];\n\n return (\n <Drawer.Root\n side=\"bottom\"\n open={open}\n onOpenChange={(nextOpen, eventDetails) => {\n if (nextOpen) return;\n // MUI X's handler ignores both arguments, but the reason is mapped so\n // the slot still honours the `DialogProps` contract.\n onClose?.(\n eventDetails.event,\n eventDetails.reason === \"outside-press\"\n ? \"backdropClick\"\n : \"escapeKeyDown\",\n );\n }}\n >\n <Drawer.Portal>\n <Drawer.Backdrop />\n <Drawer.Viewport>\n <Drawer.Popup aria-labelledby={ariaLabelledby} style={SHEET_STYLE}>\n <Drawer.Handle />\n {children}\n </Drawer.Popup>\n </Drawer.Viewport>\n </Drawer.Portal>\n </Drawer.Root>\n );\n}\n\nexport type DatePickerView = \"year\" | \"month\" | \"day\";\n\n/** Why the date in the field is not a valid choice. */\nexport type DatePickerValidationError =\n | \"invalidDate\"\n | \"minDate\"\n | \"maxDate\"\n | \"disablePast\"\n | \"disableFuture\";\n\nexport type DatePickerChangeDetails = {\n /**\n * Set when the date in the field is not one that can be chosen:\n * `\"invalidDate\"` for a date that does not exist (31.02., where the value\n * is an invalid `Date`), the others when it falls outside what `minDate`,\n * `maxDate`, `disablePast` or `disableFuture` allow. `null` when the date\n * is fine, and when the field is empty or only partly filled (the value is\n * then `null`).\n *\n * A year is reported while it is typed: \"2\", \"20\" and \"202\" each arrive as\n * a date in that year, with `\"minDate\"`, since nothing before 1900 can be\n * chosen.\n */\n validationError: DatePickerValidationError | null;\n};\n\nexport type DatePickerProps = {\n /** The chosen date (controlled). `null` means the field is empty. */\n value?: Date | null;\n /** The chosen date when first rendered, for uncontrolled use. */\n defaultValue?: Date | null;\n /**\n * Called with the new date when one is picked or typed, and with `null`\n * when the field is cleared.\n */\n onValueChange?: (\n value: Date | null,\n details: DatePickerChangeDetails,\n ) => void;\n /**\n * Called when focus leaves the field, and when the calendar closes.\n * Opening the calendar does not count as leaving.\n */\n onBlur?: () => void;\n /** The first part of the date in the field, which is where focus goes. */\n ref?: Ref<HTMLElement>;\n /** Submitted with a native form, as the date in the field's format. */\n name?: string;\n /** The floating label, linked to the field. */\n label?: ReactNode;\n /** Helper / error text shown below the control and linked via `aria-describedby`. */\n helperText?: ReactNode;\n /** Puts the control in an error state and styles the helper text accordingly. */\n error?: boolean;\n disabled?: boolean;\n /** Marks the control as required. */\n required?: boolean;\n /** The date can be read and copied, not changed. */\n readOnly?: boolean;\n /** The earliest date that can be chosen. */\n minDate?: Date;\n /** The latest date that can be chosen. */\n maxDate?: Date;\n /** Only today and later can be chosen. */\n disablePast?: boolean;\n /** Only today and earlier can be chosen. */\n disableFuture?: boolean;\n /**\n * What can be picked. The default is a full date; `[\"year\", \"month\"]` gives\n * the month/year picker.\n * @default [\"year\", \"month\", \"day\"]\n */\n views?: readonly DatePickerView[];\n /** Order of month and year in the month/year picker. Default: \"month-year\" */\n monthYearOrder?: MonthYearOrder;\n /**\n * How the date is written in the field, as a `date-fns` format string.\n * Defaults to the language's own format (\"dd.MM.yyyy\" in Norwegian).\n */\n format?: string;\n /**\n * The date the calendar shows while the field is empty. Defaults to today.\n */\n referenceDate?: Date;\n /** Whether the calendar is open (controlled). */\n open?: boolean;\n /** Called when the calendar opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * The media query above which the calendar is a popover; below it, it is a\n * drawer from the bottom of the screen. Defaults to the `sm` breakpoint.\n */\n desktopModeMediaQuery?: string;\n /** Small uppercase context label shown above the drawer title on mobile. */\n eyebrow?: ReactNode;\n /** Drawer heading on mobile. Defaults from `views` (\"Velg dato\" or \"Velg måned og år\"). */\n title?: ReactNode;\n /**\n * Override the month/year toggle's translated labels (`month`, `year`,\n * `selectView`) per-instance. Only used by the month/year picker\n * (`views={[\"year\", \"month\"]}`).\n */\n viewToggleLabels?: ViewToggleLabels;\n /**\n * Override the day calendar header's translated labels (`previousMonth`,\n * `nextMonth`, `switchToYearView`, `switchToDayView`) per-instance. Only\n * used by the day picker (default `views`).\n */\n calendarHeaderLabels?: CalendarHeaderLabels;\n /** On the field. */\n className?: string;\n /** On the field. */\n style?: CSSProperties;\n};\n\n/**\n * Date picker. It is the one component of the library that still wraps MUI\n * (`@mui/x-date-pickers`), which is why it has an import path of its own:\n *\n * ```tsx\n * import { DatePicker } from \"@leabankab/component-library/date-picker\";\n *\n * <DatePicker label=\"Ansatt siden\" value={value} onValueChange={setValue} />\n * ```\n *\n * An app that uses it installs `@mui/material`, `@mui/system`, `@mui/x-date-pickers`,\n * `@emotion/react`, `@emotion/styled` and `date-fns`. It needs no provider:\n * the picker brings its own MUI theme and localisation, and follows the\n * language of `LeaProvider`.\n *\n * Two calendar designs, chosen by `views`:\n * - **Day picker** (default): a day grid with a centered header (prev/next\n * month chevrons either side of a clickable month-year label that switches\n * to the year list) and lowercase Monday-first weekdays.\n * - **Month/year picker** (`views={[\"year\", \"month\"]}`): a Måned / År segmented\n * toggle above the month / year grids. Control the order via `monthYearOrder`:\n * \"month-year\" (default) or \"year-month\" (for Sweden and other locales).\n * Opens on the first view and drills through to the second.\n *\n * - **Desktop:** a compact popover (\"dropdown\").\n * - **Mobile:** a bottom `Drawer` with an `eyebrow` + `title` header. The switch\n * happens at the `sm` breakpoint by default; override with\n * `desktopModeMediaQuery`.\n *\n * Selecting a value commits immediately in both modes.\n */\nexport function DatePicker(props: DatePickerProps) {\n return (\n <ThemeProvider theme={theme}>\n <Picker {...props} />\n </ThemeProvider>\n );\n}\n\nfunction Picker({\n value,\n defaultValue,\n onValueChange,\n onBlur,\n ref,\n name,\n label,\n helperText,\n error,\n disabled,\n required,\n readOnly,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n views = DEFAULT_VIEWS,\n monthYearOrder = \"month-year\",\n format,\n referenceDate,\n open,\n onOpenChange,\n desktopModeMediaQuery = DESKTOP_QUERY,\n eyebrow,\n title,\n viewToggleLabels,\n calendarHeaderLabels,\n className,\n style,\n}: DatePickerProps) {\n const language = useLanguage();\n const titleLabels = useDatePickerTitleLabels();\n const isDesktop = useMediaQuery(desktopModeMediaQuery);\n const locale = LOCALE_FOR_LANGUAGE[language];\n\n const isMonthYear = !views.includes(\"day\");\n const resolvedTitle =\n title ??\n (isMonthYear ? titleLabels.selectMonthYear : titleLabels.selectDate);\n\n // For month/year mode with year-first order, default format to \"yyyy MMMM\" (e.g., \"2026 august\")\n const isYearFirst = isMonthYear && monthYearOrder === \"year-month\";\n const resolvedFormat = format ?? (isYearFirst ? \"yyyy MMMM\" : undefined);\n\n // Day mode uses the centered Lea Bank header and lowercase Monday-first\n // weekdays; month/year mode uses our Måned / År segmented toggle with\n // configurable order, drilling month -> year (or year -> month).\n const viewRenderers = isMonthYear\n ? createDateViewRenderers(monthYearOrder, viewToggleLabels)\n : undefined;\n // When using year-first order, open on the year view; otherwise default to month\n const openTo = isYearFirst ? \"year\" : isMonthYear ? \"month\" : undefined;\n const dayOfWeekFormatter = useMemo(() => weekdayFormatter(locale), [locale]);\n\n // MUI's own `inputRef` is a hidden input that only passes focus on to the\n // field some of the time, so the first part of the date is looked up.\n const fieldRef = useRef<HTMLDivElement>(null);\n useFocusTargetRef(ref, fieldRef, FOCUS_TARGETS);\n\n // Tracked so that focus moving into the calendar is not reported as\n // leaving the field.\n const [openState, setOpenState] = useState(false);\n const isOpen = open ?? openState;\n\n const handleFieldBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (isOpen) return;\n // Moving between the day, month and year, or to the calendar button.\n if (event.currentTarget.contains(event.relatedTarget)) return;\n onBlur?.();\n };\n\n const sharedSlots: Slots = {\n openPickerIcon: OpenPickerIcon,\n // The custom centered header only applies to the day calendar; the\n // month/year mode renders its own toggle via `viewRenderers`.\n ...(isMonthYear ? {} : { calendarHeader: CalendarHeader }),\n };\n const slots: Slots = isDesktop\n ? sharedSlots\n : {\n ...sharedSlots,\n dialog: DrawerDialog,\n toolbar: DrawerToolbar as unknown as Slots[\"toolbar\"],\n };\n\n const slotProps = {\n openPickerButton: {\n sx: {\n border: \"none\",\n color: \"text.subtle\",\n \"&:hover\": { backgroundColor: \"transparent\", color: \"text.base\" },\n },\n },\n // Desktop popover follows the input width (harmless on mobile, which uses a drawer).\n popper: { modifiers: [sameWidthAsInput] },\n ...(isMonthYear\n ? {}\n : { calendarHeader: { labels: calendarHeaderLabels } }),\n textField: {\n error,\n required,\n helperText,\n fullWidth: true,\n className,\n style,\n slotProps: {\n root: {\n ref: fieldRef,\n onBlur: handleFieldBlur,\n },\n },\n },\n ...(isDesktop\n ? {}\n : {\n // Commit on tap, so the drawer needs no Cancel / OK action bar.\n actionBar: { actions: [] },\n toolbar: { hidden: false, eyebrow, title: resolvedTitle },\n }),\n } as MuiDatePickerProps[\"slotProps\"];\n\n return (\n <LocalizationProvider\n dateAdapter={AdapterDateFns}\n adapterLocale={locale}\n localeText={localeTextFor(language)}\n >\n <MuiDatePicker\n value={value}\n defaultValue={defaultValue}\n onChange={(next, context) =>\n onValueChange?.(next, {\n validationError:\n context.validationError as DatePickerValidationError | null,\n })\n }\n name={name}\n label={label}\n disabled={disabled}\n readOnly={readOnly}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n views={views}\n openTo={openTo}\n format={resolvedFormat}\n referenceDate={referenceDate}\n viewRenderers={viewRenderers}\n dayOfWeekFormatter={dayOfWeekFormatter}\n desktopModeMediaQuery={desktopModeMediaQuery}\n closeOnSelect\n slots={slots}\n slotProps={slotProps}\n open={open}\n onOpen={() => {\n setOpenState(true);\n onOpenChange?.(true);\n }}\n onClose={() => {\n setOpenState(false);\n onOpenChange?.(false);\n // A date picked in the calendar never moves focus out of the\n // field, so closing it is the moment the field counts as visited.\n onBlur?.();\n }}\n />\n </LocalizationProvider>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"date-picker.mjs","names":[],"sources":["../src/components/form/use-focus-target-ref.ts","../src/theme/tokens/breakpoints.ts","../src/theme/tokens/colors.ts","../src/theme/tokens/font-family.ts","../src/theme/tokens/font-sizes.ts","../src/theme/tokens/font-weights.ts","../src/theme/tokens/line-heights.ts","../src/theme/tokens/palette.ts","../src/theme/tokens/shadows.ts","../src/theme/tokens/shape.ts","../src/theme/tokens/spacing.ts","../src/theme/tokens/type-scale.ts","../src/theme/tokens/text-styles.ts","../src/theme/tokens/transitions.ts","../src/theme/utils/focus-visible-styles.ts","../src/date-picker/use-calendar-header-labels.ts","../src/date-picker/calendar-header.tsx","../src/date-picker/drawer-toolbar.tsx","../src/date-picker/theme/field-base.ts","../src/date-picker/theme/date-picker.theme.ts","../src/date-picker/theme/form-control.theme.ts","../src/date-picker/theme/icon-button.theme.ts","../src/date-picker/theme/input.theme.ts","../src/date-picker/theme/typography.ts","../src/date-picker/theme/index.ts","../src/date-picker/use-datepicker-title-labels.ts","../src/date-picker/use-view-toggle-labels.ts","../src/date-picker/view-toggle.tsx","../src/date-picker/view-renderers.tsx","../src/date-picker/datepicker.tsx"],"sourcesContent":["import { useEffect, useRef, type Ref, type RefObject } from \"react\";\n\ntype Attachment<T> = {\n ref: Ref<T>;\n target: T | null;\n cleanup?: () => void;\n};\n\nconst attach = <T>(ref: Ref<T>, target: T | null): Attachment<T> => {\n if (typeof ref === \"function\") {\n const cleanup = ref(target);\n return {\n ref,\n target,\n cleanup: typeof cleanup === \"function\" ? cleanup : undefined,\n };\n }\n if (ref) ref.current = target;\n return { ref, target };\n};\n\nconst detach = <T>(attachment: Attachment<T> | null) => {\n if (!attachment) return;\n const { ref, cleanup } = attachment;\n if (cleanup) cleanup();\n else if (typeof ref === \"function\") ref(null);\n else if (ref) ref.current = null;\n};\n\n/**\n * Internal. Points a control's `ref` at the element inside `rootRef` that\n * takes focus, for controls where that element is rendered by another library\n * or is one of several (the radios of a group). `selectors` are tried in\n * order and the first match wins.\n *\n * This is what lets `ref.current.focus()` work on those controls, which\n * react-hook-form relies on to move focus to the first invalid field.\n */\nexport function useFocusTargetRef<T extends HTMLElement>(\n ref: Ref<T> | undefined,\n rootRef: RefObject<HTMLElement | null>,\n selectors: readonly string[],\n) {\n const attachment = useRef<Attachment<T> | null>(null);\n\n // No dependency list: which element takes focus can change with any render\n // (another radio is picked, an option becomes disabled). The ref is only\n // touched when the answer differs from last time.\n useEffect(() => {\n const root = rootRef.current;\n let target: T | null = null;\n if (root) {\n for (const selector of selectors) {\n target = root.querySelector<T>(selector);\n if (target) break;\n }\n }\n\n const current = attachment.current;\n if (current && current.ref === ref && current.target === target) return;\n\n detach(current);\n attachment.current = ref ? attach(ref, target) : null;\n });\n\n useEffect(\n () => () => {\n detach(attachment.current);\n attachment.current = null;\n },\n [],\n );\n}\n","/**\n * Viewport widths in pixels where layouts may change. Mobile-first: each value\n * is the `min-width` at which the breakpoint starts. The values match MUI's\n * defaults, so the MUI wrappers and the CSS Modules switch at the same widths.\n *\n * CSS custom properties can't be used in `@media`, so CSS Modules write the\n * pixel value literally; tests/tokens.test.ts checks it against this scale.\n */\nexport const breakpoints = {\n xs: 0,\n sm: 600,\n md: 900,\n lg: 1200,\n xl: 1536,\n} as const;\n\nexport type Breakpoint = keyof typeof breakpoints;\n\n/**\n * The website's own widths, for the website components only, so a layout on\n * leabank.no switches where it does today. Named as in the website's theme.\n * There each is a `max-width` (`mobile` is up to 640px); here, as everywhere in\n * the library, a CSS Module writes them mobile-first: `@media (min-width:\n * 640px)` starts above `mobile`, and `max-width: 639.95px` ends below it. That\n * moves each switch by one pixel, at exactly the width itself.\n *\n * They are not part of `Breakpoint`, so `Container` sizes and the responsive\n * props of `Stack` and `Grid` keep their five steps.\n */\nexport const websiteBreakpoints = {\n mobile: 640,\n tablet: 768,\n desktop: 1024,\n /** The website's `mobileHeader`: below it the header is the mobile one. */\n header: 1312,\n wide: 1440,\n} as const;\n\nexport type WebsiteBreakpoint = keyof typeof websiteBreakpoints;\n","export const colors = {\n purple: {\n 50: \"#FAF7FB\",\n 100: \"#E2D8E4\",\n 200: \"#C5B1CA\",\n 300: \"#C29AC2\",\n 400: \"#9E6DA8\",\n 500: \"#855888\",\n 600: \"#70427B\",\n 700: \"#5A3463\",\n 800: \"#422349\",\n 900: \"#2E1834\",\n 950: \"#1A0E1E\",\n },\n teal: {\n 50: \"#F0FCFA\",\n 100: \"#DAF6F1\",\n 200: \"#CEF3ED\",\n 300: \"#08C2A7\",\n 400: \"#46D1BD\",\n 500: \"#06A892\",\n 600: \"#058F7D\",\n 700: \"#047568\",\n 800: \"#035C53\",\n 900: \"#02433E\",\n 950: \"#012A28\",\n },\n blue: {\n 50: \"#EFF6FF\",\n 100: \"#CBE5FD\",\n 200: \"#93CBFC\",\n 300: \"#4DA8F7\",\n 400: \"#057EF2\",\n 500: \"#0468C9\",\n 600: \"#0354A3\",\n 700: \"#02417D\",\n 800: \"#012E57\",\n 900: \"#011B31\",\n 950: \"#000E19\",\n },\n orange: {\n 50: \"#FFF5F2\",\n 100: \"#FFDFD7\",\n 200: \"#FFC4B5\",\n 300: \"#FF9E87\",\n 400: \"#FE653E\",\n 500: \"#E54E28\",\n 600: \"#C43E1C\",\n 700: \"#A33218\",\n 800: \"#822814\",\n 900: \"#611E0F\",\n 950: \"#401408\",\n },\n amber: {\n 50: \"#FFF9EB\",\n 100: \"#FFEFC7\",\n 200: \"#FFE299\",\n 300: \"#FFCF5C\",\n 400: \"#F7A800\",\n 500: \"#D98F00\",\n 600: \"#B37400\",\n 700: \"#8C5A00\",\n 800: \"#6B4500\",\n 900: \"#4A3000\",\n 950: \"#2E1D00\",\n },\n red: {\n 50: \"#FEF2F2\",\n 100: \"#FCDCDC\",\n 200: \"#F9BBBB\",\n 300: \"#F28888\",\n 400: \"#E85555\",\n 500: \"#D32F2F\",\n 600: \"#AD2121\",\n 700: \"#8A1919\",\n 800: \"#6F1313\",\n 900: \"#4D0E0E\",\n 950: \"#2E0808\",\n },\n beige: {\n 50: \"#FAF7F5\",\n 100: \"#F0E9E5\",\n 200: \"#E0D4CD\",\n 300: \"#C9B8AD\",\n 400: \"#B09A8C\",\n 500: \"#977C6B\",\n 600: \"#7E6556\",\n 700: \"#654F42\",\n 800: \"#4C3A32\",\n 900: \"#332722\",\n 950: \"#1A1411\",\n },\n neutral: {\n 50: \"#F7F7F6\",\n 100: \"#EBEBEB\",\n 200: \"#DBDBDB\",\n 300: \"#C4C4C4\",\n 400: \"#A2A2A2\",\n 500: \"#757575\",\n 600: \"#5E5E5E\",\n 700: \"#454545\",\n 800: \"#2E2E2E\",\n 900: \"#1A1A1A\",\n 950: \"#0F1010\",\n },\n white: \"#FFFFFF\",\n black: \"#0F1010\",\n} as const;\n","/**\n * The font stack, emitted as `--lea-font-family`.\n *\n * `ClashGrotesk` is the variable font declared in `theme/fonts.css`.\n * `ClashGrotesk Fallback` is declared there too: Arial resized to Clash\n * Grotesk's average letter width, so text keeps its place while the font file\n * loads.\n */\nexport const fontFamily = '\"ClashGrotesk\", \"ClashGrotesk Fallback\", sans-serif';\n\n/**\n * The stack for code in CMS text (`RichText`'s `code` and `pre`), emitted as\n * `--lea-font-family-mono`: the website's Courier New, then the platform's own\n * monospace. Nothing else sets text in it, and no face is shipped for it.\n */\nexport const fontFamilyMono = '\"Courier New\", Courier, monospace';\n","/**\n * The first font-size scale, from before the text styles.\n *\n * @deprecated Use a text style (`textStyles`, `--lea-text-{role}-{size}-*`,\n * `text-heading-lg`) or, for a size on its own, a step on the type scale\n * (`fontStep`, `--lea-font-step-{n}`). Kept for the components that still use\n * it, and removed in a later major.\n */\nexport const fontSizes = {\n xs: \"0.75rem\",\n sm: \"0.875rem\",\n md: \"1rem\",\n lg: \"1.25rem\",\n xl: \"1.5rem\",\n \"2xl\": \"2rem\",\n \"3xl\": \"2.5rem\",\n \"4xl\": \"3rem\",\n \"5xl\": \"3.5rem\",\n \"6xl\": \"4rem\",\n} as const;\n","export const fontWeights = {\n thin: 200,\n light: 300,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n black: 800,\n} as const;\n","/**\n * Unitless, so a line height follows whichever font size it lands on. `none`\n * is for a display headline, `tight` for large headings and control labels,\n * `snug` for small headings and `normal` for running text.\n */\nexport const lineHeights = {\n none: 1,\n tight: 1.25,\n snug: 1.4,\n normal: 1.5,\n} as const;\n","import { Palette } from \"../types\";\nimport { colors } from \"./colors\";\n\nconst { purple, teal, blue, amber, red, neutral, white, beige } = colors;\n\n/** A scale colour at an opacity, written `rgba(15, 16, 16, 0.5)`. */\nconst alpha = (hex: string, opacity: number) => {\n const [r, g, b] = [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16));\n\n return `rgba(${r}, ${g}, ${b}, ${opacity})`;\n};\n\n/**\n * The website's hover colours, kept at its exact values rather than the\n * nearest step of the purple scale (purple 100 `#E2D8E4`, 950 `#1A0E1E` and\n * 300 `#C29AC2` are close, not the same). The Figma variables `bg/hover`,\n * `bg/contrast-hover` and `text/contrast-hover` hold the same raw values.\n */\nconst website = {\n hover: \"#E3D8DA\",\n contrastHover: \"#241B26\",\n textContrastHover: \"#CD86D6\",\n} as const;\n\nexport const palette: Palette = {\n bg: {\n base: white,\n subtle: neutral[50],\n muted: beige[100],\n contrast: neutral[950],\n accent: purple[100],\n overlay: alpha(neutral[950], 0.5),\n hover: website.hover,\n \"contrast-hover\": website.contrastHover,\n \"contrast-accent\": purple[800],\n },\n text: {\n base: neutral[950],\n subtle: neutral[500],\n muted: neutral[400],\n accent: purple[600],\n contrast: white,\n \"contrast-hover\": website.textContrastHover,\n },\n border: {\n base: neutral[200],\n subtle: neutral[100],\n strong: neutral[950],\n accent: purple[600],\n contrast: white,\n },\n primary: {\n base: purple[600],\n hover: purple[700],\n subtle: purple[100],\n contrast: white,\n },\n secondary: {\n base: neutral[950],\n hover: neutral[800],\n subtle: neutral[100],\n contrast: white,\n },\n tertiary: {\n base: teal[300],\n hover: teal[400],\n subtle: teal[100],\n contrast: white,\n },\n status: {\n error: {\n base: red[500],\n subtle: red[100],\n },\n warning: {\n base: amber[400],\n subtle: amber[100],\n },\n info: {\n base: blue[400],\n subtle: blue[100],\n },\n success: {\n base: teal[400],\n subtle: teal[100],\n },\n },\n} as const;\n","export const shadows = {\n xs: \"0 1px 2px 0 rgb(0 0 0 / 0.05)\",\n sm: \"0px 1px 3px 0px rgba(0, 0, 0, 0.10), 0px 1px 2px -1px rgba(0, 0, 0, 0.10)\",\n md: \"0px 4px 6px -1px rgba(0, 0, 0, 0.10), 0px 2px 4px -2px rgba(0, 0, 0, 0.10)\",\n lg: \"0px 10px 15px -3px rgba(0, 0, 0, 0.10), 0px 4px 6px -4px rgba(0, 0, 0, 0.10)\",\n xl: \"0px 20px 25px -5px rgba(0, 0, 0, 0.10), 0px 8px 10px -6px rgba(0, 0, 0, 0.10)\",\n \"2xl\": \"0px 25px 50px -12px rgba(0, 0, 0, 0.25)\",\n /**\n * The website's shadow: an even 6px halo with no offset, the exact value of\n * leabank.no. For the website components that float over a section (the\n * elevated `IconButton`, the partner logo tile, the header dropdown).\n */\n soft: \"0 0 6px 0 rgba(86, 86, 118, 0.10)\",\n inner: \"0px 2px 4px 0px rgba(0, 0, 0, 0.05) inset\",\n} as const;\n","export const shape = {\n sm: 4,\n md: 5,\n lg: 6,\n xl: 8,\n \"2xl\": 10,\n \"3xl\": 12,\n \"4xl\": 16,\n \"5xl\": 32,\n huge: 64,\n full: 100,\n} as const;\n","const BASE = 8;\nconst ROOT_FONT_SIZE = 16;\n\nexport const spacing = (factor: number) =>\n `${(factor * BASE) / ROOT_FONT_SIZE}rem`;\n\n/**\n * The steps emitted as `--lea-spacing-{step}`, the point of a half step written\n * as a hyphen: `--lea-spacing-1-5` is `spacing(1.5)`. Half steps stop at 2.5\n * and the gaps widen from there, so neighbouring steps stay visibly distinct.\n */\nexport const spacingSteps = [0.5, 1, 1.5, 2, 2.5, 3, 4, 5, 6, 8] as const;\n","const ROOT_FONT_SIZE = 16;\n\n/**\n * The modular type scale behind the text styles: a font size is\n * `base × ratio^step`. Step 0 is body text and the ratio is a major second.\n */\nexport const typeScale = { base: 16, ratio: 1.125 } as const;\n\n/**\n * A step in pixels, rounded to a whole pixel. Figma variables can't calculate,\n * so rounding here is what lets `fontStep/6` in Figma and `--lea-font-step-6`\n * in CSS hold the same number.\n */\nexport const fontStepPx = (step: number) =>\n Math.round(typeScale.base * typeScale.ratio ** step);\n\nexport const fontStep = (step: number) =>\n `${fontStepPx(step) / ROOT_FONT_SIZE}rem`;\n\n/**\n * The steps emitted as `--lea-font-step-{step}`. A step below body text spells\n * out the minus sign: `--lea-font-step-minus-1` is `fontStep(-1)`.\n */\nexport const fontSteps = [\n -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\n] as const;\n\nexport type FontStep = (typeof fontSteps)[number];\n","import { fontWeights } from \"./font-weights\";\nimport { lineHeights } from \"./line-heights\";\nimport { fontStep, type FontStep } from \"./type-scale\";\n\ntype TextStyleDefinition = {\n /** The step on the type scale, see type-scale.ts. */\n step: FontStep;\n fontWeight: keyof typeof fontWeights;\n lineHeight: keyof typeof lineHeights;\n letterSpacing: string;\n};\n\nconst style = (\n step: FontStep,\n fontWeight: TextStyleDefinition[\"fontWeight\"],\n lineHeight: TextStyleDefinition[\"lineHeight\"],\n letterSpacing = \"0\"\n): TextStyleDefinition => ({ step, fontWeight, lineHeight, letterSpacing });\n\n/**\n * Text styles, named `{role}-{size}` after what the text does, not after the\n * element it sits in: `heading-lg` is an `h1` on one page and an `h3` on the\n * next. Take the element from the page hierarchy and the style from the design.\n *\n * A style holds no values of its own. It points at a step on the type scale, a\n * font weight and a line height, so a size is retuned in one place. `body` and\n * `label` move one step at a time; `heading` and `display` move two, because\n * neighbouring steps are too close to tell two headings apart.\n *\n * `title` is a heading in the regular weight, for the website: the title of a\n * link card (`title-md`) and an uppercase promo title (`title-xl`). It takes\n * the sizes and line heights of `heading-md` and `heading-xl`.\n *\n * The Figma text styles `heading/lg` and so on mirror this file.\n */\nexport const textStyles = {\n display: {\n sm: style(10, \"semibold\", \"none\"),\n md: style(12, \"semibold\", \"none\"),\n },\n heading: {\n xs: style(0, \"semibold\", \"snug\"),\n sm: style(2, \"semibold\", \"snug\"),\n md: style(4, \"semibold\", \"snug\"),\n lg: style(6, \"semibold\", \"tight\"),\n xl: style(8, \"semibold\", \"tight\"),\n },\n title: {\n md: style(4, \"regular\", \"snug\"),\n xl: style(8, \"regular\", \"tight\"),\n },\n body: {\n xs: style(-2, \"regular\", \"normal\"),\n sm: style(-1, \"regular\", \"normal\"),\n md: style(0, \"regular\", \"normal\"),\n lg: style(1, \"regular\", \"normal\"),\n },\n label: {\n sm: style(-2, \"medium\", \"tight\"),\n md: style(-1, \"medium\", \"tight\"),\n lg: style(0, \"medium\", \"tight\"),\n },\n} satisfies Record<string, Record<string, TextStyleDefinition>>;\n\ntype TextStyles = typeof textStyles;\n\n/** `\"heading-lg\"`, `\"body-sm\"` and so on. */\nexport type TextStyleToken = {\n [Role in keyof TextStyles]: `${Role & string}-${keyof TextStyles[Role] &\n string}`;\n}[keyof TextStyles];\n\n/** Every style as `[name, definition]`, in the order above. */\nexport const textStyleEntries = Object.entries(textStyles).flatMap(\n ([role, sizes]) =>\n Object.entries(sizes).map(\n ([size, definition]) =>\n [`${role}-${size}` as TextStyleToken, definition] as const\n )\n);\n\nconst definitions = Object.fromEntries(textStyleEntries) as Record<\n TextStyleToken,\n TextStyleDefinition\n>;\n\n/** The CSS values of a text style, for `sx` and theme files. */\nexport const resolveTextStyle = (name: TextStyleToken) => {\n const { step, fontWeight, lineHeight, letterSpacing } = definitions[name];\n\n return {\n fontSize: fontStep(step),\n fontWeight: fontWeights[fontWeight],\n lineHeight: lineHeights[lineHeight],\n letterSpacing,\n };\n};\n","export const easings = {\n standard: \"ease-in-out\",\n spring: \"cubic-bezier(0.34, 1.56, 0.64, 1)\",\n} as const;\n\nexport const durations = {\n fast: \"0.15s\",\n normal: \"0.2s\",\n emphasis: \"0.3s\",\n} as const;\n\nexport const transition = (\n properties: string[],\n duration: string = durations.normal,\n easing: string = easings.standard,\n) => properties.map((p) => `${p} ${duration} ${easing}`).join(\", \");\n","import { palette } from \"../tokens\";\n\nexport const focusVisibleStyles = {\n \"&:focus-visible\": {\n outline: \"2px solid\",\n outlineColor: palette.text.base,\n },\n};\n","import { createTranslation } from \"../index\";\n\n/**\n * Translated labels for `CalendarHeader`: the prev/next month button names and\n * the month-year label's \"switch to year/day view\" suffix. Consumers can\n * override any of these per-instance via `DatePicker`'s `calendarHeaderLabels`\n * prop.\n */\nexport const useCalendarHeaderLabels = createTranslation({\n previousMonth: { no: \"Forrige måned\", se: \"Föregående månad\", fi: \"Edellinen kuukausi\", es: \"Mes anterior\" },\n nextMonth: { no: \"Neste måned\", se: \"Nästa månad\", fi: \"Seuraava kuukausi\", es: \"Mes siguiente\" },\n switchToYearView: { no: \"bytt til årsvisning\", se: \"byt till årsvy\", fi: \"vaihda vuosinäkymään\", es: \"cambiar a vista de año\" },\n switchToDayView: { no: \"bytt til datovisning\", se: \"byt till datumvy\", fi: \"vaihda päivänäkymään\", es: \"cambiar a vista de fecha\" },\n});\n\nexport type CalendarHeaderLabels = Partial<ReturnType<typeof useCalendarHeaderLabels>>;\n","import { focusVisibleStyles } from \"../theme/utils\";\nimport Box from \"@mui/material/Box\";\nimport IconButton from \"@mui/material/IconButton\";\nimport { usePickerAdapter } from \"@mui/x-date-pickers/hooks\";\nimport { type PickersCalendarHeaderProps } from \"@mui/x-date-pickers/PickersCalendarHeader\";\nimport { ChevronDown, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport {\n useCalendarHeaderLabels,\n type CalendarHeaderLabels,\n} from \"./use-calendar-header-labels\";\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nconst chevronButtonSx = {\n width: 40,\n height: 40,\n border: \"1px solid\",\n borderColor: \"border.base\",\n color: \"text.base\",\n \"&:hover\": { backgroundColor: \"bg.subtle\" },\n \"&.Mui-disabled\": { opacity: 0.45, color: \"text.base\" },\n} as const;\n\n/**\n * Replaces MUI's default calendar header for the day picker with the Lea Bank\n * layout: a previous / next month chevron on each side and a centered, clickable\n * month-year label (with a caret) that switches to the year view. The chevrons\n * are muted at the `minDate` / `maxDate` bounds. Month navigation is only shown\n * while the day grid is visible; in the year view only the label remains.\n */\nexport function CalendarHeader({\n currentMonth,\n onMonthChange,\n onViewChange,\n view,\n minDate,\n maxDate,\n disabled,\n labels,\n}: PickersCalendarHeaderProps & { labels?: CalendarHeaderLabels }) {\n const adapter = usePickerAdapter();\n const t = useCalendarHeaderLabels();\n const l = { ...t, ...labels };\n\n const isDayView = view === \"day\";\n const prevMuted =\n !!disabled ||\n (minDate != null && !adapter.isAfter(currentMonth, adapter.startOfMonth(minDate)));\n const nextMuted =\n !!disabled ||\n (maxDate != null &&\n !adapter.isBefore(\n adapter.startOfMonth(currentMonth),\n adapter.startOfMonth(maxDate),\n ));\n\n const label = `${cap(adapter.formatByString(currentMonth, \"LLLL\"))} ${adapter.getYear(\n currentMonth,\n )}`;\n const switchLabel = `${label}, ${\n isDayView ? l.switchToYearView : l.switchToDayView\n }`;\n\n return (\n <Box\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 1,\n px: 0.5,\n pb: 1,\n }}\n >\n {isDayView ? (\n <IconButton\n aria-label={l.previousMonth}\n disabled={prevMuted}\n onClick={() => onMonthChange(adapter.addMonths(currentMonth, -1))}\n sx={chevronButtonSx}\n >\n <ChevronLeft size={20} aria-hidden />\n </IconButton>\n ) : (\n <Box sx={{ width: 40, height: 40 }} />\n )}\n\n <Box\n component=\"button\"\n type=\"button\"\n aria-label={switchLabel}\n disabled={!!disabled}\n onClick={() => onViewChange?.(isDayView ? \"year\" : \"day\")}\n sx={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 0.75,\n px: 1,\n py: 0.5,\n border: \"none\",\n borderRadius: 2,\n background: \"transparent\",\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n fontSize: \"1.0625rem\",\n fontWeight: \"fontWeightMedium\",\n color: \"text.base\",\n \"&:hover\": { backgroundColor: \"bg.subtle\" },\n \"&:disabled\": { cursor: \"default\", opacity: 0.45 },\n ...focusVisibleStyles,\n }}\n >\n {label}\n <Box\n component=\"span\"\n sx={{\n display: \"inline-flex\",\n color: \"primary.base\",\n transition: \"transform .15s\",\n transform: isDayView ? \"none\" : \"rotate(180deg)\",\n }}\n >\n <ChevronDown size={16} aria-hidden />\n </Box>\n </Box>\n\n {isDayView ? (\n <IconButton\n aria-label={l.nextMonth}\n disabled={nextMuted}\n onClick={() => onMonthChange(adapter.addMonths(currentMonth, 1))}\n sx={chevronButtonSx}\n >\n <ChevronRight size={20} aria-hidden />\n </IconButton>\n ) : (\n <Box sx={{ width: 40, height: 40 }} />\n )}\n </Box>\n );\n}\n","import Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\nimport { type ReactNode } from \"react\";\n\nexport type DrawerToolbarProps = {\n /** Small uppercase context label shown above the title. */\n eyebrow?: ReactNode;\n /** Drawer heading. */\n title?: ReactNode;\n /** id set on the title so the drawer dialog can reference it via `aria-labelledby`. */\n titleId?: string;\n /** Set by MUI's layout; when true the toolbar must not render. */\n hidden?: boolean;\n};\n\n/**\n * Replaces the default `DatePickerToolbar`. Renders the Lea Bank drawer header:\n * an optional purple uppercase eyebrow and a large title. Both are supplied by\n * `DatePicker` through `slotProps.toolbar`.\n */\nexport function DrawerToolbar({ eyebrow, title, titleId, hidden }: DrawerToolbarProps) {\n if (hidden) return null;\n\n return (\n <Box sx={{ px: 3, pt: 1, pb: 1.5 }}>\n {eyebrow != null && (\n <Typography\n component=\"p\"\n sx={{\n color: \"text.accent\",\n fontWeight: \"fontWeightBold\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n fontSize: \"0.8125rem\",\n mb: 0.5,\n }}\n >\n {eyebrow}\n </Typography>\n )}\n {title != null && (\n <Typography\n component=\"h2\"\n id={titleId}\n sx={{ color: \"text.base\", fontWeight: \"fontWeightMedium\", fontSize: \"1.75rem\" }}\n >\n {title}\n </Typography>\n )}\n </Box>\n );\n}\n","import { CSSObject } from \"@mui/material\";\nimport { palette } from \"../../theme/tokens\";\n\n/**\n * The outlined field of the date picker, the one field that still wraps MUI:\n * its height, padding, collapsed notch and border-state colours. The other\n * fields get the same look from `input.module.css`.\n */\n\n// The height of every single-line field.\nexport const FIELD_HEIGHT = \"54px\";\n\n// Vertical padding leaves room for the floated label above the value.\nexport const fieldPadding = {\n paddingInlineStart: \"0.9rem\",\n paddingBlockStart: \"1.5rem\",\n paddingBlockEnd: \"0.5rem\",\n} as const;\n\n/**\n * We draw the field border ourselves, so MUI's notch and its legend are\n * collapsed. Takes the class of the notched outline, which the picker's\n * `PickersOutlinedInput` names differently from MUI's `OutlinedInput`.\n */\nexport const collapsedNotch = (outlineClass: string): CSSObject => ({\n [`& .${outlineClass}`]: {\n top: 0,\n inset: 0,\n },\n [`& .${outlineClass} legend`]: {\n display: \"none\",\n },\n});\n\n/**\n * Hover / focus / error border treatment of the field. Takes the class of the\n * notched outline, for the same reason as `collapsedNotch`.\n */\nexport const fieldBorderStates = (outlineClass: string): CSSObject => ({\n [`&:hover:not(:focus-within):not(.Mui-disabled):not(.Mui-error) .${outlineClass}`]:\n {\n borderWidth: \"2px\",\n borderColor: palette.border.strong,\n },\n [`&:focus-within:not(.Mui-error) .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.border.accent,\n },\n [`&.Mui-error .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.status.error.base,\n },\n [`&.Mui-error:hover:not(:focus-within):not(.Mui-disabled) .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.status.error.base,\n },\n [`&.Mui-error:focus-within .${outlineClass}`]: {\n borderWidth: \"2px\",\n borderColor: palette.status.error.base,\n },\n});\n","import { Components, Theme } from \"@mui/material\";\nimport { fontSizes, palette, shadows, shape, spacing } from \"../../theme/tokens\";\nimport {\n FIELD_HEIGHT,\n collapsedNotch,\n fieldBorderStates,\n fieldPadding,\n} from \"./field-base\";\n\n// The picker's accessible field (PickersOutlinedInput) shares the outlined-field\n// sizing/border treatment with the other inputs; only the notched-outline class\n// name differs.\nconst NOTCH = \"MuiPickersOutlinedInput-notchedOutline\";\n\n/**\n * Styling for the MUI X Date Pickers surfaces. The day picker uses MUI's\n * `DateCalendar` day grid (with a custom centered `calendarHeader`, see\n * `calendar-header.tsx`); month/year configurations use MUI's standard themed\n * month / year grids. This file owns the visual treatment of the trigger field,\n * the desktop popover and the day / month / year grids, using design tokens.\n *\n * In `@mui/x-date-pickers` v9 the legacy single-`TextField` field structure was\n * removed, so the trigger is always the accessible `PickersTextField`. We theme\n * `MuiPickersOutlinedInput` here to match the library's `MuiOutlinedInput`\n * (collapsed notch, fixed height, shared padding) — that is what fixes the\n * label-over-border and spacing issues, since those theme keys differ.\n */\nexport const datePickerTheme: Pick<\n Components<Theme>,\n | \"MuiPickersOutlinedInput\"\n | \"MuiDateCalendar\"\n | \"MuiDayCalendar\"\n | \"MuiPickerDay\"\n | \"MuiMonthCalendar\"\n | \"MuiYearCalendar\"\n | \"MuiPickerPopper\"\n | \"MuiPickersLayout\"\n> = {\n MuiPickersOutlinedInput: {\n styleOverrides: {\n root: {\n boxSizing: \"border-box\",\n alignItems: \"flex-start\",\n padding: 0,\n borderRadius: shape.xl,\n height: FIELD_HEIGHT,\n lineHeight: \"normal\",\n\n // We draw the border ourselves, so collapse the notch and its legend.\n ...collapsedNotch(NOTCH),\n\n // --- Border states (shared with the other outlined fields) ---\n ...fieldBorderStates(NOTCH),\n\n // --- Adornments (the open-picker icon button) ---\n \"& .MuiInputAdornment-root\": {\n alignSelf: \"center\",\n },\n \"& .MuiInputAdornment-positionEnd\": {\n marginRight: spacing(2),\n },\n },\n sectionsContainer: {\n ...fieldPadding,\n paddingInlineEnd: \"0.9rem\",\n },\n },\n },\n MuiPickersLayout: {\n styleOverrides: {\n root: {\n // Always stack vertically (toolbar → calendar). MUI's grid otherwise\n // switches to a side-by-side landscape layout on wide screens, which is\n // wrong for both the popover and the bottom drawer.\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: spacing(2),\n padding: spacing(3),\n paddingBlockEnd: spacing(1),\n \"& .MuiPickersLayout-contentWrapper\": {\n width: \"100%\",\n },\n },\n },\n },\n MuiDateCalendar: {\n styleOverrides: {\n root: {\n // Fill the input-width popover (see `sameWidthAsInput` in datepicker.tsx)\n // rather than MUI's fixed calendar width, so the grid lines up with the field.\n width: \"100%\",\n maxHeight: \"none\",\n },\n },\n },\n MuiDayCalendar: {\n styleOverrides: {\n header: {\n justifyContent: \"space-between\",\n },\n weekContainer: {\n justifyContent: \"space-between\",\n margin: 0,\n },\n weekDayLabel: {\n fontSize: fontSizes.sm,\n color: palette.text.subtle,\n },\n },\n },\n MuiPickerDay: {\n styleOverrides: {\n root: {\n width: 40,\n height: 40,\n fontSize: fontSizes.md,\n color: palette.text.base,\n backgroundColor: \"transparent\",\n \"&:hover, &:focus\": {\n backgroundColor: palette.bg.subtle,\n },\n \"&.MuiPickerDay-selected\": {\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n \"&:hover, &:focus\": {\n backgroundColor: palette.primary.hover,\n },\n },\n \"&.Mui-disabled, &.MuiPickerDay-disabled\": {\n color: palette.text.muted,\n },\n \"&.MuiPickerDay-today:not(.MuiPickerDay-selected)\": {\n outline: `1px solid ${palette.border.base}`,\n outlineOffset: -1,\n },\n },\n },\n },\n MuiMonthCalendar: {\n styleOverrides: {\n root: {\n width: \"100%\",\n justifyContent: \"space-between\",\n columnGap: 0,\n rowGap: spacing(1.5),\n },\n button: {\n flex: \"0 0 31%\",\n maxWidth: \"31%\",\n fontSize: fontSizes.md,\n fontWeight: 500,\n color: palette.text.base,\n backgroundColor: \"transparent\",\n borderRadius: shape[\"3xl\"],\n height: spacing(6),\n margin: 0,\n \"&:hover, &:focus\": {\n backgroundColor: palette.bg.subtle,\n },\n \"&.Mui-selected, &.MuiMonthCalendar-selected\": {\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n \"&:hover, &:focus\": {\n backgroundColor: palette.primary.hover,\n },\n },\n \"&.Mui-disabled, &.MuiMonthCalendar-disabled\": {\n backgroundColor: \"transparent\",\n color: palette.text.muted,\n },\n },\n },\n },\n MuiYearCalendar: {\n styleOverrides: {\n root: {\n width: \"100%\",\n justifyContent: \"space-between\",\n columnGap: 0,\n rowGap: spacing(1.5),\n // Keep MUI's default constrained, scrollable height so the calendar can\n // auto-scroll the current / selected year into view on open. Removing it\n // (maxHeight: none) makes the list grow full-height and never scroll.\n },\n button: {\n flex: \"0 0 31%\",\n maxWidth: \"31%\",\n fontSize: fontSizes.md,\n fontWeight: 500,\n color: palette.text.base,\n backgroundColor: \"transparent\",\n borderRadius: shape[\"3xl\"],\n height: spacing(6),\n margin: 0,\n \"&:hover, &:focus\": {\n backgroundColor: palette.bg.subtle,\n },\n \"&.Mui-selected, &.MuiYearCalendar-selected\": {\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n \"&:hover, &:focus\": {\n backgroundColor: palette.primary.hover,\n },\n },\n \"&.Mui-disabled, &.MuiYearCalendar-disabled\": {\n backgroundColor: \"transparent\",\n color: palette.text.muted,\n },\n },\n },\n },\n MuiPickerPopper: {\n styleOverrides: {\n paper: {\n // The popper itself is sized to the input width (see `sameWidthAsInput`);\n // make the paper fill it so the calendar lines up with the field.\n width: \"100%\",\n boxSizing: \"border-box\",\n borderRadius: shape.xl,\n boxShadow: shadows.md,\n border: `1px solid ${palette.border.subtle}`,\n },\n },\n },\n};\n","import { Components, Theme } from \"@mui/material\";\nimport { resolveTextStyle } from \"../../theme/tokens\";\n\nexport const formControlTheme: Components<Theme>[\"MuiFormControl\"] = {\n defaultProps: {\n variant: \"outlined\",\n },\n styleOverrides: {\n root: {\n position: \"relative\",\n },\n },\n};\n\n/**\n * Helper text under the date picker, the one field that still wraps MUI, in\n * the same text style as under the other fields (`field-parts.module.css`).\n */\nexport const formHelperTextTheme: Components<Theme>[\"MuiFormHelperText\"] = {\n styleOverrides: {\n root: resolveTextStyle(\"body-sm\"),\n },\n};\n","import { Components, Theme } from \"@mui/material\";\nimport {\n palette,\n durations,\n easings,\n shape,\n spacing,\n transition,\n} from \"../../theme/tokens\";\nimport { focusVisibleStyles } from \"../../theme/utils\";\n\nexport const iconButtonTheme: Components<Theme>[\"MuiIconButton\"] = {\n defaultProps: {\n size: \"large\",\n },\n styleOverrides: {\n root: {\n ...focusVisibleStyles,\n borderRadius: shape.full,\n textTransform: \"none\",\n border: \"2px solid\",\n transition: [\n transition([\"background-color\"], durations.emphasis, easings.spring),\n transition([\"color\"], durations.emphasis, easings.spring),\n ].join(\", \"),\n svg: {\n flexShrink: 0,\n },\n },\n sizeSmall: {\n padding: spacing(1),\n svg: {\n width: 16,\n height: 16,\n },\n },\n sizeLarge: {\n padding: spacing(1),\n svg: {\n width: 24,\n height: 24,\n },\n },\n },\n variants: [\n {\n props: {\n color: \"primary\",\n },\n style: {\n borderColor: palette.border.strong,\n color: palette.text.base,\n \"&:hover\": {\n borderColor: palette.primary.base,\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n },\n },\n },\n {\n props: {\n color: \"secondary\",\n },\n style: {\n borderColor: palette.primary.base,\n color: palette.primary.base,\n \"&:hover\": {\n borderColor: palette.border.strong,\n backgroundColor: palette.primary.base,\n color: palette.primary.contrast,\n },\n },\n },\n ],\n};\n","import { Components, Theme } from \"@mui/material\";\n\n/**\n * The floated label of the one field that still wraps MUI, the date picker,\n * at the height the label of `Input` floats to.\n */\nexport const inputLabelTheme: Components<Theme>[\"MuiInputLabel\"] = {\n styleOverrides: {\n shrink: {\n top: \"1rem\",\n },\n },\n};\n","import { fontFamily } from \"../../theme/tokens/font-family\";\nimport { fontSizes } from \"../../theme/tokens/font-sizes\";\nimport { fontWeights } from \"../../theme/tokens/font-weights\";\nimport { palette } from \"../../theme/tokens/palette\";\n\n/**\n *\n * We are not following the MUI typography tokens because\n * sometimes we need the size of an h1 but not the h1 component.\n * Overriding it here at the root will give us more control over the typography.\n *\n */\n\nexport const typography = {\n fontFamily: fontFamily,\n fontWeight: fontWeights.regular,\n color: palette.text.base,\n \"& strong\": {\n fontWeight: fontWeights.medium,\n },\n \"& a\": {\n color: `${palette.text.base} !important`,\n textDecorationColor: `${palette.text.base} !important`,\n fontWeight: fontWeights.regular,\n },\n h1: undefined,\n h2: undefined,\n h3: undefined,\n h4: undefined,\n h5: undefined,\n h6: undefined,\n subtitle1: undefined,\n subtitle2: undefined,\n heading: {\n fontFamily: fontFamily,\n fontWeight: fontWeights.medium,\n letterSpacing: \"0.02em\",\n },\n body1: {\n fontSize: fontSizes.md,\n fontWeight: fontWeights.regular,\n },\n body2: {\n fontSize: fontSizes.sm,\n fontWeight: fontWeights.regular,\n },\n button: undefined,\n caption: undefined,\n};\n","import { createTheme, type ThemeOptions } from \"@mui/material/styles\";\n// Types only: registers the `@mui/x-date-pickers` component keys\n// (MuiPickerDay, MuiDayCalendar, …) so the overrides below type-check.\nimport type {} from \"@mui/x-date-pickers/themeAugmentation\";\nimport { breakpoints, palette } from \"../../theme/tokens\";\nimport type { BrandColor } from \"../../theme/types\";\nimport { datePickerTheme } from \"./date-picker.theme\";\nimport { formControlTheme, formHelperTextTheme } from \"./form-control.theme\";\nimport { iconButtonTheme } from \"./icon-button.theme\";\nimport { inputLabelTheme } from \"./input.theme\";\nimport { typography } from \"./typography\";\n\n/**\n * MUI's own components read a colour as `main`, `dark`, `light` and\n * `contrastText`, and `createTheme` throws without `main`. These four are an\n * adapter for MUI's internals, added here and nowhere else: the design tokens\n * only know `base`, `hover`, `subtle` and `contrast`.\n */\nconst muiColor = (color: BrandColor) => ({\n ...color,\n main: color.base,\n dark: color.hover,\n light: color.subtle,\n contrastText: color.contrast,\n});\n\n/**\n * The MUI theme of the date picker, the one component that still wraps MUI.\n * It is private: `DatePicker` puts it around itself, so an app neither\n * provides it nor sees it, and it does not reach any MUI component the app\n * renders on its own.\n *\n * The palette is the token palette as it is, so `sx` in the picker's own\n * parts can name a token by its path (\"text.subtle\", \"bg.base\"). MUI's types\n * do not know those groups, and are not told: a module augmentation would\n * change the theme types of every app that has MUI installed.\n */\nexport const theme = createTheme({\n breakpoints: { values: breakpoints },\n palette: {\n ...palette,\n primary: muiColor(palette.primary),\n secondary: muiColor(palette.secondary),\n } as ThemeOptions[\"palette\"],\n typography,\n components: {\n ...datePickerTheme,\n MuiIconButton: iconButtonTheme,\n MuiFormControl: formControlTheme,\n MuiFormHelperText: formHelperTextTheme,\n MuiInputLabel: inputLabelTheme,\n },\n});\n","import { createTranslation } from \"../index\";\n\n/**\n * Translated default titles for `DatePicker`'s mobile drawer header, used when\n * the `title` prop is omitted.\n */\nexport const useDatePickerTitleLabels = createTranslation({\n selectDate: { no: \"Velg dato\", se: \"Välj datum\", fi: \"Valitse päivä\", es: \"Seleccionar fecha\" },\n selectMonthYear: { no: \"Velg måned og år\", se: \"Välj månad och år\", fi: \"Valitse kuukausi ja vuosi\", es: \"Seleccionar mes y año\" },\n});\n","import { createTranslation } from \"../index\";\n\n/**\n * Translated labels for `ViewToggle`: the month/year segment labels and the\n * `role=\"group\"` accessible name. Consumers can override any of these\n * per-instance via `DatePicker`'s `viewToggleLabels` prop.\n */\nexport const useViewToggleLabels = createTranslation({\n month: { no: \"Måned\", se: \"Månad\", fi: \"Kuukausi\", es: \"Mes\" },\n year: { no: \"År\", se: \"År\", fi: \"Vuosi\", es: \"Año\" },\n selectView: { no: \"Velg visning\", se: \"Välj vy\", fi: \"Valitse näkymä\", es: \"Seleccionar vista\" },\n});\n\nexport type ViewToggleLabels = Partial<ReturnType<typeof useViewToggleLabels>>;\n","import { focusVisibleStyles } from \"../theme/utils\";\nimport Box from \"@mui/material/Box\";\nimport {\n useViewToggleLabels,\n type ViewToggleLabels,\n} from \"./use-view-toggle-labels\";\n\nexport type ToggleView = \"month\" | \"year\";\nexport type MonthYearOrder = \"month-year\" | \"year-month\";\n\nconst getSegments = (\n order: MonthYearOrder,\n labels: Record<\"month\" | \"year\", string>,\n): { view: ToggleView; label: string }[] => {\n const month = { view: \"month\" as const, label: labels.month };\n const year = { view: \"year\" as const, label: labels.year };\n return order === \"year-month\" ? [year, month] : [month, year];\n};\n\nexport type ViewToggleProps = {\n /** The currently active view. */\n currentView: ToggleView;\n /** Called with the view the user switched to. */\n onViewChange: (view: ToggleView) => void;\n /** Order of month and year segments. Default: \"month-year\" */\n order?: MonthYearOrder;\n /** Override the built-in translated labels per-instance. */\n labels?: ViewToggleLabels;\n};\n\n/**\n * Segmented control for the month/year-only picker. Shows two pill segments,\n * month first then year, with the active segment raised on a white pill. Used as\n * the header of the month/year `viewRenderers`; switching segments changes the\n * picker view. Each segment is a toggle button exposing `aria-pressed`, grouped\n * under a labelled `role=\"group\"`.\n */\nexport function ViewToggle({\n currentView,\n onViewChange,\n order = \"month-year\",\n labels,\n}: ViewToggleProps) {\n const t = useViewToggleLabels();\n const l = { ...t, ...labels };\n const segments = getSegments(order, l);\n return (\n <Box\n role=\"group\"\n aria-label={l.selectView}\n sx={{\n display: \"flex\",\n gap: 0.5,\n p: 0.5,\n mb: 1,\n borderRadius: \"999px\",\n backgroundColor: \"bg.subtle\",\n }}\n >\n {segments.map(({ view, label }) => {\n const active = view === currentView;\n return (\n <Box\n key={view}\n component=\"button\"\n type=\"button\"\n aria-pressed={active}\n onClick={() => onViewChange(view)}\n sx={{\n flex: 1,\n minHeight: 40,\n border: \"none\",\n borderRadius: \"999px\",\n cursor: \"pointer\",\n fontFamily: \"inherit\",\n fontSize: \"0.9375rem\",\n fontWeight: \"fontWeightMedium\",\n backgroundColor: active ? \"bg.base\" : \"transparent\",\n color: active ? \"text.base\" : \"text.subtle\",\n boxShadow: active ? \"0px 1px 3px rgba(0, 0, 0, 0.12)\" : \"none\",\n transition: \"background-color .15s, color .15s\",\n \"&:hover\": {\n color: \"text.base\",\n },\n ...focusVisibleStyles,\n }}\n >\n {label}\n </Box>\n );\n })}\n </Box>\n );\n}\n","import { type DatePickerProps } from \"@mui/x-date-pickers/DatePicker\";\nimport { type DateViewRendererProps } from \"@mui/x-date-pickers/dateViewRenderers\";\nimport { usePickerActionsContext } from \"@mui/x-date-pickers/hooks\";\nimport { type DateView } from \"@mui/x-date-pickers/models\";\nimport { MonthCalendar } from \"@mui/x-date-pickers/MonthCalendar\";\nimport { YearCalendar } from \"@mui/x-date-pickers/YearCalendar\";\nimport { type MonthYearOrder, ViewToggle } from \"./view-toggle\";\nimport { type ViewToggleLabels } from \"./use-view-toggle-labels\";\n\ntype RendererProps = DateViewRendererProps<DateView>;\n\n/**\n * Factory function that creates `viewRenderers` for the month/year-only picker.\n * The day view is intentionally absent (that mode uses MUI's standard `DateCalendar`);\n * these only drive the `views={[\"year\", \"month\"]}` configuration with the Måned / År toggle\n * and a month to year drill. Supports configurable order via `monthYearOrder`.\n */\nexport const createDateViewRenderers = (\n order: MonthYearOrder = \"month-year\",\n labels?: ViewToggleLabels,\n): DatePickerProps[\"viewRenderers\"] => {\n const isYearFirst = order === \"year-month\";\n\n /**\n * Month view of the month/year-only picker: the segmented toggle above MUI's\n * `MonthCalendar`. Behavior depends on `order`:\n * - month-first: intermediate step, advances to year view\n * - year-first: final step, commits and closes\n */\n const MonthView = (props: RendererProps) => {\n const actions = usePickerActionsContext();\n return (\n <div>\n <ViewToggle\n currentView=\"month\"\n onViewChange={(view) => actions.setView(view)}\n order={order}\n labels={labels}\n />\n <MonthCalendar\n value={props.value ?? null}\n referenceDate={props.referenceDate}\n minDate={props.minDate}\n maxDate={props.maxDate}\n disableFuture={props.disableFuture}\n disablePast={props.disablePast}\n shouldDisableMonth={props.shouldDisableMonth}\n timezone={props.timezone}\n onChange={(date) => {\n if (isYearFirst) {\n // In year-first mode, month is the final step\n actions.setValue(date, { changeImportance: \"accept\" });\n } else {\n // In month-first mode, month is intermediate, advance to year\n actions.setValue(date, { changeImportance: \"set\" });\n actions.setView(\"year\");\n }\n }}\n />\n </div>\n );\n };\n\n /**\n * Year view of the month/year-only picker. Behavior depends on `order`:\n * - month-first: final step, commits and closes\n * - year-first: intermediate step, advances to month view\n */\n const YearView = (props: RendererProps) => {\n const actions = usePickerActionsContext();\n return (\n <div>\n <ViewToggle\n currentView=\"year\"\n onViewChange={(view) => actions.setView(view)}\n order={order}\n labels={labels}\n />\n <YearCalendar\n value={props.value ?? null}\n referenceDate={props.referenceDate}\n minDate={props.minDate}\n maxDate={props.maxDate}\n disableFuture={props.disableFuture}\n disablePast={props.disablePast}\n shouldDisableYear={props.shouldDisableYear}\n timezone={props.timezone}\n onChange={(date) => {\n if (isYearFirst) {\n // In year-first mode, year is intermediate, advance to month\n actions.setValue(date, { changeImportance: \"set\" });\n actions.setView(\"month\");\n } else {\n // In month-first mode, year is the final step\n actions.setValue(date, { changeImportance: \"accept\" });\n }\n }}\n />\n </div>\n );\n };\n\n return {\n month: (props) => <MonthView {...props} />,\n year: (props) => <YearView {...props} />,\n };\n};\n","\"use client\";\n\nimport { type DialogProps } from \"@mui/material/Dialog\";\nimport { type PopperProps } from \"@mui/material/Popper\";\nimport { ThemeProvider } from \"@mui/material/styles\";\nimport useMediaQuery from \"@mui/material/useMediaQuery\";\nimport { AdapterDateFns } from \"@mui/x-date-pickers/AdapterDateFns\";\nimport {\n DatePicker as MuiDatePicker,\n type DatePickerProps as MuiDatePickerProps,\n} from \"@mui/x-date-pickers/DatePicker\";\nimport { LocalizationProvider } from \"@mui/x-date-pickers/LocalizationProvider\";\nimport { esES, fiFI, nbNO, svSE } from \"@mui/x-date-pickers/locales\";\nimport { format as formatDate, type Locale } from \"date-fns\";\nimport { es, fi, nb, sv } from \"date-fns/locale\";\nimport { CalendarSearch } from \"lucide-react\";\nimport {\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type FocusEvent,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { useFocusTargetRef } from \"../components/form/use-focus-target-ref\";\n// From the main entry, which this entry leaves out of its bundle: the drawer\n// and the language have to be the app's own copies. See ./index.ts.\nimport { Drawer, useLanguage, type Language } from \"../index\";\nimport { CalendarHeader } from \"./calendar-header\";\nimport { DrawerToolbar } from \"./drawer-toolbar\";\nimport { theme } from \"./theme\";\nimport { type CalendarHeaderLabels } from \"./use-calendar-header-labels\";\nimport { useDatePickerTitleLabels } from \"./use-datepicker-title-labels\";\nimport { type ViewToggleLabels } from \"./use-view-toggle-labels\";\nimport { createDateViewRenderers } from \"./view-renderers\";\nimport { type MonthYearOrder } from \"./view-toggle\";\n\nexport {\n type CalendarHeaderLabels,\n type MonthYearOrder,\n type ViewToggleLabels,\n};\n\ntype Slots = NonNullable<MuiDatePickerProps[\"slots\"]>;\n\nconst DEFAULT_VIEWS = [\"year\", \"month\", \"day\"] as const;\n\n// Where the popover takes over from the drawer, unless `desktopModeMediaQuery`\n// says otherwise.\nconst DESKTOP_QUERY = theme.breakpoints.up(\"sm\");\n\n/*\n * The picker sheet is rounder than the default drawer. There is no 24px step\n * in src/theme/tokens/shape.ts, so the value is set through the drawer's\n * `--drawer-radius` custom property rather than overriding `border-radius`,\n * which the drawer sets with a more specific selector.\n */\nconst SHEET_STYLE = { \"--drawer-radius\": \"1.5rem\" } as CSSProperties;\n\n// The field is a row of editable parts (day, month, year), each a spinbutton.\nconst FOCUS_TARGETS = ['[role=\"spinbutton\"]'] as const;\n\n// Maps the provider language to a `date-fns` locale, so month names and weekday\n// formatting follow the single `language` prop of `LeaProvider`.\nconst LOCALE_FOR_LANGUAGE: Record<Language, Locale> = {\n no: nb,\n se: sv,\n fi: fi,\n es: es,\n};\n\n// MUI X ships translations for the picker chrome (\"Velg dato\", \"Forrige\n// måned\", \"Avbryt\", …), which otherwise falls back to English.\nconst PICKER_TEXT: Record<Language, typeof nbNO> = {\n no: nbNO,\n se: svSE,\n fi: fiFI,\n es: esES,\n};\n\nconst localeTextFor = (language: Language) =>\n PICKER_TEXT[language].components.MuiLocalizationProvider.defaultProps\n .localeText;\n\nconst OpenPickerIcon = () => <CalendarSearch size={20} aria-hidden />;\n\n// Lowercase two-letter weekday labels to match the design, from the resolved\n// locale rather than a fixed array (`nb` is unchanged: sø ma ti on to fr lø).\nconst weekdayFormatter = (locale: Locale) => (date: Date) =>\n formatDate(date, \"EEEEEE\", { locale }).toLowerCase();\n\n/**\n * Sizes the desktop popover to the trigger field's width, so the calendar always\n * lines up with the input (rather than sizing to the calendar's own content).\n */\nconst sameWidthAsInput: NonNullable<PopperProps[\"modifiers\"]>[number] = {\n name: \"sameWidth\",\n enabled: true,\n phase: \"beforeWrite\",\n requires: [\"computeStyles\"],\n fn: ({ state }) => {\n state.styles.popper.width = `${state.rects.reference.width}px`;\n },\n effect: ({ state }) => {\n const reference = state.elements.reference as HTMLElement;\n state.elements.popper.style.width = `${reference.offsetWidth}px`;\n },\n};\n\n/**\n * Renders the mobile views inside a bottom sheet with the Lea Bank chrome\n * (rounded top corners + grab handle) instead of MUI's default modal `Dialog`.\n * The picker's `dialog` slot is called with `Dialog` props, so we adapt them to\n * the drawer's `open` / `onOpenChange` pair. MUI passes the generated dialog\n * name via `slotProps.paper[\"aria-labelledby\"]` (pointing at the toolbar title\n * id), so we forward it onto the popup (the `role=\"dialog\"` element) to give\n * the sheet an accessible name.\n */\nfunction DrawerDialog({ open, onClose, children, slotProps }: DialogProps) {\n const forwardedPaper =\n typeof slotProps?.paper === \"object\" ? slotProps.paper : undefined;\n const ariaLabelledby = (\n forwardedPaper as { \"aria-labelledby\"?: string } | undefined\n )?.[\"aria-labelledby\"];\n\n return (\n <Drawer.Root\n side=\"bottom\"\n open={open}\n onOpenChange={(nextOpen, eventDetails) => {\n if (nextOpen) return;\n // MUI X's handler ignores both arguments, but the reason is mapped so\n // the slot still honours the `DialogProps` contract.\n onClose?.(\n eventDetails.event,\n eventDetails.reason === \"outside-press\"\n ? \"backdropClick\"\n : \"escapeKeyDown\",\n );\n }}\n >\n <Drawer.Portal>\n <Drawer.Backdrop />\n <Drawer.Viewport>\n <Drawer.Popup aria-labelledby={ariaLabelledby} style={SHEET_STYLE}>\n <Drawer.Handle />\n {children}\n </Drawer.Popup>\n </Drawer.Viewport>\n </Drawer.Portal>\n </Drawer.Root>\n );\n}\n\nexport type DatePickerView = \"year\" | \"month\" | \"day\";\n\n/** Why the date in the field is not a valid choice. */\nexport type DatePickerValidationError =\n | \"invalidDate\"\n | \"minDate\"\n | \"maxDate\"\n | \"disablePast\"\n | \"disableFuture\";\n\nexport type DatePickerChangeDetails = {\n /**\n * Set when the date in the field is not one that can be chosen:\n * `\"invalidDate\"` for a date that does not exist (31.02., where the value\n * is an invalid `Date`), the others when it falls outside what `minDate`,\n * `maxDate`, `disablePast` or `disableFuture` allow. `null` when the date\n * is fine, and when the field is empty or only partly filled (the value is\n * then `null`).\n *\n * A year is reported while it is typed: \"2\", \"20\" and \"202\" each arrive as\n * a date in that year, with `\"minDate\"`, since nothing before 1900 can be\n * chosen.\n */\n validationError: DatePickerValidationError | null;\n};\n\nexport type DatePickerProps = {\n /** The chosen date (controlled). `null` means the field is empty. */\n value?: Date | null;\n /** The chosen date when first rendered, for uncontrolled use. */\n defaultValue?: Date | null;\n /**\n * Called with the new date when one is picked or typed, and with `null`\n * when the field is cleared.\n */\n onValueChange?: (\n value: Date | null,\n details: DatePickerChangeDetails,\n ) => void;\n /**\n * Called when focus leaves the field, and when the calendar closes.\n * Opening the calendar does not count as leaving.\n */\n onBlur?: () => void;\n /** The first part of the date in the field, which is where focus goes. */\n ref?: Ref<HTMLElement>;\n /** Submitted with a native form, as the date in the field's format. */\n name?: string;\n /** The floating label, linked to the field. */\n label?: ReactNode;\n /** Helper / error text shown below the control and linked via `aria-describedby`. */\n helperText?: ReactNode;\n /** Puts the control in an error state and styles the helper text accordingly. */\n error?: boolean;\n disabled?: boolean;\n /** Marks the control as required. */\n required?: boolean;\n /** The date can be read and copied, not changed. */\n readOnly?: boolean;\n /** The earliest date that can be chosen. */\n minDate?: Date;\n /** The latest date that can be chosen. */\n maxDate?: Date;\n /** Only today and later can be chosen. */\n disablePast?: boolean;\n /** Only today and earlier can be chosen. */\n disableFuture?: boolean;\n /**\n * What can be picked. The default is a full date; `[\"year\", \"month\"]` gives\n * the month/year picker.\n * @default [\"year\", \"month\", \"day\"]\n */\n views?: readonly DatePickerView[];\n /** Order of month and year in the month/year picker. Default: \"month-year\" */\n monthYearOrder?: MonthYearOrder;\n /**\n * How the date is written in the field, as a `date-fns` format string.\n * Defaults to the language's own format (\"dd.MM.yyyy\" in Norwegian).\n */\n format?: string;\n /**\n * The date the calendar shows while the field is empty. Defaults to today.\n */\n referenceDate?: Date;\n /** Whether the calendar is open (controlled). */\n open?: boolean;\n /** Called when the calendar opens or closes. */\n onOpenChange?: (open: boolean) => void;\n /**\n * The media query above which the calendar is a popover; below it, it is a\n * drawer from the bottom of the screen. Defaults to the `sm` breakpoint.\n */\n desktopModeMediaQuery?: string;\n /** Small uppercase context label shown above the drawer title on mobile. */\n eyebrow?: ReactNode;\n /** Drawer heading on mobile. Defaults from `views` (\"Velg dato\" or \"Velg måned og år\"). */\n title?: ReactNode;\n /**\n * Override the month/year toggle's translated labels (`month`, `year`,\n * `selectView`) per-instance. Only used by the month/year picker\n * (`views={[\"year\", \"month\"]}`).\n */\n viewToggleLabels?: ViewToggleLabels;\n /**\n * Override the day calendar header's translated labels (`previousMonth`,\n * `nextMonth`, `switchToYearView`, `switchToDayView`) per-instance. Only\n * used by the day picker (default `views`).\n */\n calendarHeaderLabels?: CalendarHeaderLabels;\n /** On the field. */\n className?: string;\n /** On the field. */\n style?: CSSProperties;\n};\n\n/**\n * Date picker. It is the one component of the library that still wraps MUI\n * (`@mui/x-date-pickers`), which is why it has an import path of its own:\n *\n * ```tsx\n * import { DatePicker } from \"@leabankab/component-library/date-picker\";\n *\n * <DatePicker label=\"Ansatt siden\" value={value} onValueChange={setValue} />\n * ```\n *\n * An app that uses it installs `@mui/material`, `@mui/system`, `@mui/x-date-pickers`,\n * `@emotion/react`, `@emotion/styled` and `date-fns`. It needs no provider:\n * the picker brings its own MUI theme and localisation, and follows the\n * language of `LeaProvider`.\n *\n * Two calendar designs, chosen by `views`:\n * - **Day picker** (default): a day grid with a centered header (prev/next\n * month chevrons either side of a clickable month-year label that switches\n * to the year list) and lowercase Monday-first weekdays.\n * - **Month/year picker** (`views={[\"year\", \"month\"]}`): a Måned / År segmented\n * toggle above the month / year grids. Control the order via `monthYearOrder`:\n * \"month-year\" (default) or \"year-month\" (for Sweden and other locales).\n * Opens on the first view and drills through to the second.\n *\n * - **Desktop:** a compact popover (\"dropdown\").\n * - **Mobile:** a bottom `Drawer` with an `eyebrow` + `title` header. The switch\n * happens at the `sm` breakpoint by default; override with\n * `desktopModeMediaQuery`.\n *\n * Selecting a value commits immediately in both modes.\n */\nexport function DatePicker(props: DatePickerProps) {\n return (\n <ThemeProvider theme={theme}>\n <Picker {...props} />\n </ThemeProvider>\n );\n}\n\nfunction Picker({\n value,\n defaultValue,\n onValueChange,\n onBlur,\n ref,\n name,\n label,\n helperText,\n error,\n disabled,\n required,\n readOnly,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n views = DEFAULT_VIEWS,\n monthYearOrder = \"month-year\",\n format,\n referenceDate,\n open,\n onOpenChange,\n desktopModeMediaQuery = DESKTOP_QUERY,\n eyebrow,\n title,\n viewToggleLabels,\n calendarHeaderLabels,\n className,\n style,\n}: DatePickerProps) {\n const language = useLanguage();\n const titleLabels = useDatePickerTitleLabels();\n const isDesktop = useMediaQuery(desktopModeMediaQuery);\n const locale = LOCALE_FOR_LANGUAGE[language];\n\n const isMonthYear = !views.includes(\"day\");\n const resolvedTitle =\n title ??\n (isMonthYear ? titleLabels.selectMonthYear : titleLabels.selectDate);\n\n // For month/year mode with year-first order, default format to \"yyyy MMMM\" (e.g., \"2026 august\")\n const isYearFirst = isMonthYear && monthYearOrder === \"year-month\";\n const resolvedFormat = format ?? (isYearFirst ? \"yyyy MMMM\" : undefined);\n\n // Day mode uses the centered Lea Bank header and lowercase Monday-first\n // weekdays; month/year mode uses our Måned / År segmented toggle with\n // configurable order, drilling month -> year (or year -> month).\n const viewRenderers = isMonthYear\n ? createDateViewRenderers(monthYearOrder, viewToggleLabels)\n : undefined;\n // When using year-first order, open on the year view; otherwise default to month\n const openTo = isYearFirst ? \"year\" : isMonthYear ? \"month\" : undefined;\n const dayOfWeekFormatter = useMemo(() => weekdayFormatter(locale), [locale]);\n\n // MUI's own `inputRef` is a hidden input that only passes focus on to the\n // field some of the time, so the first part of the date is looked up.\n const fieldRef = useRef<HTMLDivElement>(null);\n useFocusTargetRef(ref, fieldRef, FOCUS_TARGETS);\n\n // Tracked so that focus moving into the calendar is not reported as\n // leaving the field.\n const [openState, setOpenState] = useState(false);\n const isOpen = open ?? openState;\n\n const handleFieldBlur = (event: FocusEvent<HTMLDivElement>) => {\n if (isOpen) return;\n // Moving between the day, month and year, or to the calendar button.\n if (event.currentTarget.contains(event.relatedTarget)) return;\n onBlur?.();\n };\n\n const sharedSlots: Slots = {\n openPickerIcon: OpenPickerIcon,\n // The custom centered header only applies to the day calendar; the\n // month/year mode renders its own toggle via `viewRenderers`.\n ...(isMonthYear ? {} : { calendarHeader: CalendarHeader }),\n };\n const slots: Slots = isDesktop\n ? sharedSlots\n : {\n ...sharedSlots,\n dialog: DrawerDialog,\n toolbar: DrawerToolbar as unknown as Slots[\"toolbar\"],\n };\n\n const slotProps = {\n openPickerButton: {\n sx: {\n border: \"none\",\n color: \"text.subtle\",\n \"&:hover\": { backgroundColor: \"transparent\", color: \"text.base\" },\n },\n },\n // Desktop popover follows the input width (harmless on mobile, which uses a drawer).\n popper: { modifiers: [sameWidthAsInput] },\n ...(isMonthYear\n ? {}\n : { calendarHeader: { labels: calendarHeaderLabels } }),\n textField: {\n error,\n required,\n helperText,\n fullWidth: true,\n className,\n style,\n slotProps: {\n root: {\n ref: fieldRef,\n onBlur: handleFieldBlur,\n },\n },\n },\n ...(isDesktop\n ? {}\n : {\n // Commit on tap, so the drawer needs no Cancel / OK action bar.\n actionBar: { actions: [] },\n toolbar: { hidden: false, eyebrow, title: resolvedTitle },\n }),\n } as MuiDatePickerProps[\"slotProps\"];\n\n return (\n <LocalizationProvider\n dateAdapter={AdapterDateFns}\n adapterLocale={locale}\n localeText={localeTextFor(language)}\n >\n <MuiDatePicker\n value={value}\n defaultValue={defaultValue}\n onChange={(next, context) =>\n onValueChange?.(next, {\n validationError:\n context.validationError as DatePickerValidationError | null,\n })\n }\n name={name}\n label={label}\n disabled={disabled}\n readOnly={readOnly}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n views={views}\n openTo={openTo}\n format={resolvedFormat}\n referenceDate={referenceDate}\n viewRenderers={viewRenderers}\n dayOfWeekFormatter={dayOfWeekFormatter}\n desktopModeMediaQuery={desktopModeMediaQuery}\n closeOnSelect\n slots={slots}\n slotProps={slotProps}\n open={open}\n onOpen={() => {\n setOpenState(true);\n onOpenChange?.(true);\n }}\n onClose={() => {\n setOpenState(false);\n onOpenChange?.(false);\n // A date picked in the calendar never moves focus out of the\n // field, so closing it is the moment the field counts as visited.\n onBlur?.();\n }}\n />\n </LocalizationProvider>\n );\n}\n"],"mappings":"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"}