@webiny/admin-ui 6.5.0-beta.9 → 6.5.1-beta.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 (36) hide show
  1. package/AutoComplete/primitives/AutoCompletePrimitive.d.ts +6 -0
  2. package/AutoComplete/primitives/AutoCompletePrimitive.js +1 -0
  3. package/AutoComplete/primitives/AutoCompletePrimitive.js.map +1 -1
  4. package/DatePicker/DatePicker.stories.d.ts +10 -0
  5. package/DatePicker/DatePicker.stories.js +44 -1
  6. package/DatePicker/DatePicker.stories.js.map +1 -1
  7. package/DatePicker/primitives/BirthdayPicker.d.ts +13 -0
  8. package/DatePicker/primitives/BirthdayPicker.js +355 -0
  9. package/DatePicker/primitives/BirthdayPicker.js.map +1 -0
  10. package/DatePicker/primitives/BirthdayPickerCell.d.ts +14 -0
  11. package/DatePicker/primitives/BirthdayPickerCell.js +19 -0
  12. package/DatePicker/primitives/BirthdayPickerCell.js.map +1 -0
  13. package/DatePicker/primitives/BirthdayPickerSegments.d.ts +9 -0
  14. package/DatePicker/primitives/BirthdayPickerSegments.js +43 -0
  15. package/DatePicker/primitives/BirthdayPickerSegments.js.map +1 -0
  16. package/DatePicker/primitives/DatePickerPrimitive.js +3 -0
  17. package/DatePicker/primitives/DatePickerPrimitive.js.map +1 -1
  18. package/DatePicker/utils/birthdayHelpers.d.ts +77 -0
  19. package/DatePicker/utils/birthdayHelpers.js +145 -0
  20. package/DatePicker/utils/birthdayHelpers.js.map +1 -0
  21. package/DatePicker/utils/birthdayHelpers.test.d.ts +1 -0
  22. package/DatePicker/utils/birthdayHelpers.test.js +394 -0
  23. package/DatePicker/utils/birthdayHelpers.test.js.map +1 -0
  24. package/DatePicker/utils/index.d.ts +1 -0
  25. package/DatePicker/utils/index.js +1 -0
  26. package/DatePicker/utils/types.d.ts +13 -2
  27. package/MultiAutoComplete/primitives/MultiAutoCompletePrimitive.d.ts +6 -0
  28. package/MultiAutoComplete/primitives/MultiAutoCompletePrimitive.js +1 -0
  29. package/MultiAutoComplete/primitives/MultiAutoCompletePrimitive.js.map +1 -1
  30. package/Switch/Switch.d.ts +4 -4
  31. package/Switch/Switch.js +21 -7
  32. package/Switch/Switch.js.map +1 -1
  33. package/Switch/domains/SwitchItemDto.d.ts +1 -1
  34. package/Switch/primitives/SwitchPrimitive.js +4 -3
  35. package/Switch/primitives/SwitchPrimitive.js.map +1 -1
  36. package/package.json +18 -18
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatePicker/primitives/BirthdayPicker.js","sources":["../../../src/DatePicker/primitives/BirthdayPicker.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { Popover as RadixPopover } from \"radix-ui\";\nimport { ReactComponent as CalendarMonthIcon } from \"@webiny/icons/calendar_month.svg\";\nimport { ReactComponent as CloseIcon } from \"@webiny/icons/close.svg\";\nimport { Icon } from \"~/Icon/index.js\";\nimport { inputVariants } from \"~/Input/index.js\";\nimport { ScrollArea } from \"~/ScrollArea/index.js\";\nimport { useEscapeScrollLock } from \"~/hooks/index.js\";\nimport { cn, cva } from \"~/utils.js\";\nimport type { BirthdayPickerProps } from \"../utils/types.js\";\nimport { BirthdayPickerCell } from \"./BirthdayPickerCell.js\";\nimport { BirthdayPickerSegments } from \"./BirthdayPickerSegments.js\";\nimport { MONTH_NAMES_FULL } from \"../utils/constants.js\";\nimport {\n type BirthdayParts,\n type BirthdayStep,\n type BirthdayRange,\n birthdayYears,\n formatBirthdayValue,\n isDayDisabled,\n isMonthDisabled,\n isYearDisabled,\n nextBirthdayStep,\n pad,\n parseBirthdayValue,\n pickDay,\n pickMonth,\n pickYear\n} from \"../utils/birthdayHelpers.js\";\n\ntype Step = BirthdayStep;\n\nconst STEPS: Step[] = [\"day\", \"month\", \"year\"];\n\nconst STEP_LABELS: Record<Step, string> = {\n day: \"Select a day\",\n month: \"Select a month\",\n year: \"Select a year\"\n};\n\nconst DAYS = Array.from({ length: 31 }, (_, index) => index + 1);\nconst MONTHS = Array.from({ length: 12 }, (_, index) => index + 1);\n\n/** Timings, in ms. */\nconst EXPAND_MS = 250;\nconst SLIDE_MS = 300;\nconst FADE_OUT_MS = 120;\nconst COLLAPSE_MS = 200;\n\n/**\n * - `collapsed`: the card is mounted at the bar's height, about to grow (or done shrinking).\n * - `expanded`: the card is at full height with the step grid showing.\n * - `collapsing`: the body fades and the card shrinks back into the bar.\n */\ntype Phase = \"collapsed\" | \"expanded\" | \"collapsing\";\n\n/**\n * The card is the bar, grown: it keeps the focused input's border, its corner radius and, in the\n * header, its horizontal padding, so the date doesn't move when the card opens.\n */\nconst cardVariants = cva(\n [\n \"bg-neutral-base border-sm border-neutral-black shadow-lg overflow-hidden\",\n \"text-md text-neutral-strong fill-neutral-xstrong\",\n \"w-(--radix-popover-trigger-width) min-w-[320px]\"\n ],\n {\n variants: {\n size: {\n md: \"rounded-md\",\n lg: \"rounded-md\",\n xl: \"rounded-lg leading-6\"\n }\n },\n defaultVariants: {\n size: \"lg\"\n }\n }\n);\n\nconst cardHeaderVariants = cva(\"flex items-center justify-between gap-sm\", {\n variants: {\n size: {\n md: \"px-[calc(var(--padding-sm-extra)-(var(--border-width-sm)))]\",\n lg: \"px-[calc(var(--padding-sm-extra)-(var(--border-width-sm)))]\",\n xl: \"px-[calc(var(--padding-md)-(var(--border-width-sm)))]\"\n }\n },\n defaultVariants: {\n size: \"lg\"\n }\n});\n\n/**\n * Every step shares one grid height, the day grid's six rows plus the inset that keeps a cell's\n * focus ring inside the clipped area, so the card keeps its height as the steps slide. Only the\n * year grid scrolls inside it.\n */\nconst gridHeight = \"h-[calc(6*var(--spacing-xl)+5*var(--spacing-sm)+2*var(--spacing-xs))]\";\nconst dayGridWidth = \"max-w-[calc(6*var(--spacing-xxl)+5*var(--spacing-xs))]\";\nconst wideGridWidth = \"max-w-[calc(5*var(--spacing-3xl)+4*var(--spacing-sm))]\";\n\n/**\n * Picks a date one part at a time: a day, then a month, then a year. Each pick moves to the\n * next step. A pick that completes the date commits it, and the last step closes the picker.\n * Meant for dates far in the past, like a date of birth, where paging a calendar month by\n * month is slow.\n *\n * The value is a `YYYY-MM-DD` string, the same as the `date` picker's. Days, months and years\n * that can't make a date between `minDate` and `maxDate` can't be picked.\n */\nconst BirthdayPicker = ({\n value,\n onChange,\n disabled,\n size,\n variant,\n invalid,\n yearRange,\n minDate,\n maxDate,\n onOpenChange,\n className\n}: BirthdayPickerProps) => {\n const [open, setOpen] = useState(false);\n const [phase, setPhase] = useState<Phase>(\"collapsed\");\n const [step, setStep] = useState<Step>(\"day\");\n const [draft, setDraft] = useState<BirthdayParts>({});\n const [barHeight, setBarHeight] = useState(0);\n const [bodyHeight, setBodyHeight] = useState(0);\n\n const barRef = useRef<HTMLDivElement>(null);\n const cardRef = useRef<HTMLDivElement | null>(null);\n /** The divider and the step body: what the card adds to the bar's height when it grows. */\n const bodyRef = useRef<HTMLDivElement | null>(null);\n const panelRefs = useRef<Record<Step, HTMLDivElement | null>>({\n day: null,\n month: null,\n year: null\n });\n /** The steps picked since the card opened. */\n const picked = useRef<Set<Step>>(new Set());\n const closeTimer = useRef<ReturnType<typeof setTimeout>>();\n const escapeScrollLock = useEscapeScrollLock<HTMLDivElement>();\n\n const saved = useMemo(() => parseBirthdayValue(value), [value]);\n const years = useMemo(\n () => birthdayYears(yearRange, saved.year, { minDate, maxDate }),\n [yearRange, saved.year, minDate, maxDate]\n );\n const range = useMemo<BirthdayRange>(\n () => ({ years, minDate, maxDate }),\n [years, minDate, maxDate]\n );\n\n useEffect(() => () => clearTimeout(closeTimer.current), []);\n\n const expand = () => {\n if (disabled || open) {\n return;\n }\n clearTimeout(closeTimer.current);\n setBarHeight(barRef.current?.offsetHeight ?? 0);\n setDraft(saved);\n picked.current = new Set();\n setStep(\"day\");\n setPhase(\"collapsed\");\n setOpen(true);\n onOpenChange?.(true);\n };\n\n const collapse = () => {\n if (phase === \"collapsing\") {\n return;\n }\n setPhase(\"collapsing\");\n closeTimer.current = setTimeout(() => {\n setOpen(false);\n setPhase(\"collapsed\");\n onOpenChange?.(false);\n }, FADE_OUT_MS + COLLAPSE_MS);\n };\n\n /**\n * The card mounts at the bar's height. Wait for the popper to place it before growing,\n * or the first part of the growth happens off screen. The body is laid out by its own\n * spacing, so its height is measured here, once it exists, and the card grows by that much.\n */\n useLayoutEffect(() => {\n if (!open || phase !== \"collapsed\") {\n return;\n }\n let second = 0;\n const first = requestAnimationFrame(() => {\n second = requestAnimationFrame(() => {\n setBodyHeight(bodyRef.current?.offsetHeight ?? 0);\n setPhase(\"expanded\");\n });\n });\n return () => {\n cancelAnimationFrame(first);\n cancelAnimationFrame(second);\n };\n }, [open, phase]);\n\n /** A card that grows past the bottom of the viewport brings the field into view. */\n useEffect(() => {\n if (phase !== \"expanded\") {\n return;\n }\n const timer = setTimeout(() => {\n const rect = cardRef.current?.getBoundingClientRect();\n if (rect && rect.bottom > window.innerHeight) {\n barRef.current?.scrollIntoView({ block: \"center\", behavior: \"smooth\" });\n }\n }, EXPAND_MS);\n return () => clearTimeout(timer);\n }, [phase]);\n\n /**\n * Entering a step focuses its selected cell (or its first one) so the keyboard picks up\n * where the pointer would. The year grid also scrolls the selected year into view, or\n * back to the newest year when none is selected.\n *\n * The popover portal mounts its content a render after `open` flips, so this waits for\n * the card to expand, by which point the panels exist.\n */\n useEffect(() => {\n if (!open || phase !== \"expanded\") {\n return;\n }\n const panel = panelRefs.current[step];\n if (!panel) {\n return;\n }\n const selected = panel.querySelector<HTMLButtonElement>(\"[data-selected=true]\");\n const viewport = panel.querySelector<HTMLDivElement>(\"[data-slot=scroll-area-viewport]\");\n if (viewport) {\n if (selected) {\n const offset =\n selected.getBoundingClientRect().top - viewport.getBoundingClientRect().top;\n viewport.scrollTop +=\n offset - viewport.clientHeight / 2 + selected.offsetHeight / 2;\n } else {\n viewport.scrollTop = 0;\n }\n }\n const target = selected ?? panel.querySelector<HTMLButtonElement>(\"button:enabled\");\n target?.focus({ preventScroll: true });\n }, [open, phase, step]);\n\n const goToStep = (next: Step) => {\n setStep(next);\n };\n\n /**\n * Any pick that completes the date commits it, so closing the card early never drops a\n * date the header shows as filled. The header segments let parts be picked out of order.\n */\n const onPick = (pickedStep: Step, next: BirthdayParts) => {\n setDraft(next);\n picked.current.add(pickedStep);\n const nextValue = formatBirthdayValue(next);\n if (nextValue) {\n onChange?.(nextValue);\n }\n const nextStep = nextBirthdayStep(next, pickedStep, picked.current);\n if (nextStep) {\n goToStep(nextStep);\n return;\n }\n collapse();\n };\n\n const onPickDay = (day: number) => onPick(\"day\", pickDay(draft, day, range));\n\n const onPickMonth = (month: number) => onPick(\"month\", pickMonth(draft, month, range));\n\n const onPickYear = (year: number) => onPick(\"year\", pickYear(draft, year));\n\n const onBarKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) {\n return;\n }\n if (event.key === \"Enter\" || event.key === \" \" || event.key === \"ArrowDown\") {\n event.preventDefault();\n expand();\n }\n };\n\n const expanded = phase === \"expanded\";\n const cardHeight = expanded ? barHeight + bodyHeight : barHeight;\n const stepIndex = STEPS.indexOf(step);\n\n const icons = (interactive: boolean) => (\n <span className=\"flex items-center gap-xs shrink-0\">\n {interactive && value && !disabled ? (\n <button\n type=\"button\"\n aria-label=\"Clear date\"\n className=\"flex cursor-pointer rounded-xs outline-none focus-visible:ring-sm focus-visible:ring-primary-dimmed\"\n onClick={event => {\n event.stopPropagation();\n onChange?.(undefined);\n }}\n onKeyDown={event => event.stopPropagation()}\n >\n <Icon icon={<CloseIcon />} label=\"Clear\" size=\"sm\" color=\"inherit\" />\n </button>\n ) : null}\n <Icon icon={<CalendarMonthIcon />} label=\"Calendar\" size=\"sm\" color=\"inherit\" />\n </span>\n );\n\n const panelProps = (panelStep: Step) => ({\n ref: (element: HTMLDivElement | null) => {\n panelRefs.current[panelStep] = element;\n },\n \"aria-hidden\": step !== panelStep,\n \"data-step\": panelStep\n });\n\n return (\n <div className={className}>\n <RadixPopover.Root\n open={open}\n onOpenChange={isOpen => (isOpen ? expand() : collapse())}\n >\n <RadixPopover.Anchor asChild>\n <div\n ref={barRef}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n data-disabled={disabled}\n data-focused={open}\n onClick={expand}\n onKeyDown={onBarKeyDown}\n className={cn(\n inputVariants({ size, variant, invalid }),\n \"cursor-pointer justify-between select-none min-w-0 overflow-hidden outline-none\",\n disabled && \"pointer-events-none\"\n )}\n >\n <BirthdayPickerSegments parts={saved} />\n {icons(true)}\n </div>\n </RadixPopover.Anchor>\n <RadixPopover.Portal>\n <RadixPopover.Content\n ref={escapeScrollLock}\n side=\"bottom\"\n align=\"start\"\n sideOffset={-barHeight}\n avoidCollisions={false}\n onOpenAutoFocus={event => event.preventDefault()}\n onCloseAutoFocus={event => {\n event.preventDefault();\n barRef.current?.focus({ preventScroll: true });\n }}\n className=\"z-popover outline-none\"\n >\n <div\n ref={cardRef}\n role=\"dialog\"\n aria-label={STEP_LABELS[step]}\n data-phase={phase}\n className={cn(\n cardVariants({ size }),\n phase === \"collapsing\" && \"pointer-events-none\"\n )}\n style={{\n height: cardHeight,\n transition:\n phase === \"collapsing\"\n ? `height ${COLLAPSE_MS}ms ease-in ${FADE_OUT_MS}ms`\n : `height ${EXPAND_MS}ms ease-out`\n }}\n >\n <div\n className={cardHeaderVariants({ size })}\n style={{\n height: `calc(${barHeight}px - 2 * var(--border-width-sm))`\n }}\n >\n <BirthdayPickerSegments\n parts={draft}\n activeStep={step}\n onStepClick={goToStep}\n />\n {icons(false)}\n </div>\n <div ref={bodyRef}>\n <div\n className=\"h-px bg-neutral-dimmed origin-center\"\n style={{\n transform: expanded ? \"scaleX(1)\" : \"scaleX(0)\",\n transition: `transform ${EXPAND_MS}ms ease-out`\n }}\n />\n <div\n className=\"pb-md\"\n style={{\n opacity: expanded ? 1 : 0,\n transition: expanded\n ? `opacity 200ms ease-out ${EXPAND_MS - 100}ms`\n : `opacity ${FADE_OUT_MS}ms ease-in`\n }}\n >\n <div\n className=\"pt-sm-extra pb-xs text-center text-sm text-neutral-muted\"\n aria-live=\"polite\"\n >\n {STEP_LABELS[step]}\n </div>\n <div className={cn(\"overflow-hidden\", gridHeight)}>\n <div\n className=\"flex h-full w-[300%]\"\n style={{\n transform: `translateX(-${(stepIndex * 100) / 3}%)`,\n transition: `transform ${SLIDE_MS}ms ease-in-out`\n }}\n >\n <div\n {...panelProps(\"day\")}\n className=\"w-1/3 h-full px-md py-xs\"\n >\n <div\n className={cn(\n \"grid grid-cols-6 gap-x-xs gap-y-sm mx-auto\",\n dayGridWidth\n )}\n >\n {DAYS.map(day => (\n <BirthdayPickerCell\n key={day}\n selected={draft.day === day}\n disabled={isDayDisabled(day, range)}\n tabbable={step === \"day\"}\n onClick={() => onPickDay(day)}\n >\n {pad(day)}\n </BirthdayPickerCell>\n ))}\n </div>\n </div>\n <div\n {...panelProps(\"month\")}\n className=\"w-1/3 h-full px-md py-xs flex items-center\"\n >\n <div\n className={cn(\n \"grid grid-cols-3 gap-x-sm gap-y-md w-full mx-auto\",\n wideGridWidth\n )}\n >\n {MONTHS.map(month => (\n <BirthdayPickerCell\n key={month}\n selected={draft.month === month}\n disabled={isMonthDisabled(\n month,\n draft,\n range\n )}\n tabbable={step === \"month\"}\n onClick={() => onPickMonth(month)}\n >\n {MONTH_NAMES_FULL[month - 1]}\n </BirthdayPickerCell>\n ))}\n </div>\n </div>\n <div {...panelProps(\"year\")} className=\"w-1/3 h-full\">\n <ScrollArea className=\"h-full\">\n <div className=\"px-md py-xs\">\n <div\n className={cn(\n \"grid grid-cols-5 gap-sm w-full mx-auto\",\n wideGridWidth\n )}\n >\n {years.map(year => (\n <BirthdayPickerCell\n key={year}\n selected={draft.year === year}\n disabled={isYearDisabled(\n year,\n draft,\n range\n )}\n tabbable={step === \"year\"}\n onClick={() => onPickYear(year)}\n >\n {year}\n </BirthdayPickerCell>\n ))}\n </div>\n </div>\n </ScrollArea>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </RadixPopover.Content>\n </RadixPopover.Portal>\n </RadixPopover.Root>\n </div>\n );\n};\n\nexport { BirthdayPicker };\n"],"names":["STEPS","STEP_LABELS","DAYS","Array","_","index","MONTHS","EXPAND_MS","SLIDE_MS","FADE_OUT_MS","COLLAPSE_MS","cardVariants","cva","cardHeaderVariants","gridHeight","dayGridWidth","wideGridWidth","BirthdayPicker","value","onChange","disabled","size","variant","invalid","yearRange","minDate","maxDate","onOpenChange","className","open","setOpen","useState","phase","setPhase","step","setStep","draft","setDraft","barHeight","setBarHeight","bodyHeight","setBodyHeight","barRef","useRef","cardRef","bodyRef","panelRefs","picked","Set","closeTimer","escapeScrollLock","useEscapeScrollLock","saved","useMemo","parseBirthdayValue","years","birthdayYears","range","useEffect","clearTimeout","expand","collapse","setTimeout","useLayoutEffect","second","first","requestAnimationFrame","cancelAnimationFrame","timer","rect","window","panel","selected","viewport","offset","target","goToStep","next","onPick","pickedStep","nextValue","formatBirthdayValue","nextStep","nextBirthdayStep","onPickDay","day","pickDay","onPickMonth","month","pickMonth","onPickYear","year","pickYear","onBarKeyDown","event","expanded","cardHeight","stepIndex","icons","interactive","undefined","Icon","CloseIcon","CalendarMonthIcon","panelProps","panelStep","element","RadixPopover","isOpen","cn","inputVariants","BirthdayPickerSegments","BirthdayPickerCell","isDayDisabled","pad","isMonthDisabled","MONTH_NAMES_FULL","ScrollArea","isYearDisabled"],"mappings":";;;;;;;;;;;;;AAgCA,MAAMA,QAAgB;IAAC;IAAO;IAAS;CAAO;AAE9C,MAAMC,cAAoC;IACtC,KAAK;IACL,OAAO;IACP,MAAM;AACV;AAEA,MAAMC,OAAOC,MAAM,IAAI,CAAC;IAAE,QAAQ;AAAG,GAAG,CAACC,GAAGC,QAAUA,QAAQ;AAC9D,MAAMC,SAASH,MAAM,IAAI,CAAC;IAAE,QAAQ;AAAG,GAAG,CAACC,GAAGC,QAAUA,QAAQ;AAGhE,MAAME,YAAY;AAClB,MAAMC,WAAW;AACjB,MAAMC,cAAc;AACpB,MAAMC,cAAc;AAapB,MAAMC,eAAeC,IACjB;IACI;IACA;IACA;CACH,EACD;IACI,UAAU;QACN,MAAM;YACF,IAAI;YACJ,IAAI;YACJ,IAAI;QACR;IACJ;IACA,iBAAiB;QACb,MAAM;IACV;AACJ;AAGJ,MAAMC,qBAAqBD,IAAI,4CAA4C;IACvE,UAAU;QACN,MAAM;YACF,IAAI;YACJ,IAAI;YACJ,IAAI;QACR;IACJ;IACA,iBAAiB;QACb,MAAM;IACV;AACJ;AAOA,MAAME,aAAa;AACnB,MAAMC,eAAe;AACrB,MAAMC,gBAAgB;AAWtB,MAAMC,iBAAiB,CAAC,EACpBC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,IAAI,EACJC,OAAO,EACPC,OAAO,EACPC,SAAS,EACTC,OAAO,EACPC,OAAO,EACPC,YAAY,EACZC,SAAS,EACS;IAClB,MAAM,CAACC,MAAMC,QAAQ,GAAGC,SAAS;IACjC,MAAM,CAACC,OAAOC,SAAS,GAAGF,SAAgB;IAC1C,MAAM,CAACG,MAAMC,QAAQ,GAAGJ,SAAe;IACvC,MAAM,CAACK,OAAOC,SAAS,GAAGN,SAAwB,CAAC;IACnD,MAAM,CAACO,WAAWC,aAAa,GAAGR,SAAS;IAC3C,MAAM,CAACS,YAAYC,cAAc,GAAGV,SAAS;IAE7C,MAAMW,SAASC,OAAuB;IACtC,MAAMC,UAAUD,OAA8B;IAE9C,MAAME,UAAUF,OAA8B;IAC9C,MAAMG,YAAYH,OAA4C;QAC1D,KAAK;QACL,OAAO;QACP,MAAM;IACV;IAEA,MAAMI,SAASJ,OAAkB,IAAIK;IACrC,MAAMC,aAAaN;IACnB,MAAMO,mBAAmBC;IAEzB,MAAMC,QAAQC,QAAQ,IAAMC,mBAAmBpC,QAAQ;QAACA;KAAM;IAC9D,MAAMqC,QAAQF,QACV,IAAMG,cAAchC,WAAW4B,MAAM,IAAI,EAAE;YAAE3B;YAASC;QAAQ,IAC9D;QAACF;QAAW4B,MAAM,IAAI;QAAE3B;QAASC;KAAQ;IAE7C,MAAM+B,QAAQJ,QACV,IAAO;YAAEE;YAAO9B;YAASC;QAAQ,IACjC;QAAC6B;QAAO9B;QAASC;KAAQ;IAG7BgC,UAAU,IAAM,IAAMC,aAAaV,WAAW,OAAO,GAAG,EAAE;IAE1D,MAAMW,SAAS;QACX,IAAIxC,YAAYS,MACZ;QAEJ8B,aAAaV,WAAW,OAAO;QAC/BV,aAAaG,OAAO,OAAO,EAAE,gBAAgB;QAC7CL,SAASe;QACTL,OAAO,OAAO,GAAG,IAAIC;QACrBb,QAAQ;QACRF,SAAS;QACTH,QAAQ;QACRH,eAAe;IACnB;IAEA,MAAMkC,WAAW;QACb,IAAI7B,AAAU,iBAAVA,OACA;QAEJC,SAAS;QACTgB,WAAW,OAAO,GAAGa,WAAW;YAC5BhC,QAAQ;YACRG,SAAS;YACTN,eAAe;QACnB,GAAGlB,cAAcC;IACrB;IAOAqD,gBAAgB;QACZ,IAAI,CAAClC,QAAQG,AAAU,gBAAVA,OACT;QAEJ,IAAIgC,SAAS;QACb,MAAMC,QAAQC,sBAAsB;YAChCF,SAASE,sBAAsB;gBAC3BzB,cAAcI,QAAQ,OAAO,EAAE,gBAAgB;gBAC/CZ,SAAS;YACb;QACJ;QACA,OAAO;YACHkC,qBAAqBF;YACrBE,qBAAqBH;QACzB;IACJ,GAAG;QAACnC;QAAMG;KAAM;IAGhB0B,UAAU;QACN,IAAI1B,AAAU,eAAVA,OACA;QAEJ,MAAMoC,QAAQN,WAAW;YACrB,MAAMO,OAAOzB,QAAQ,OAAO,EAAE;YAC9B,IAAIyB,QAAQA,KAAK,MAAM,GAAGC,OAAO,WAAW,EACxC5B,OAAO,OAAO,EAAE,eAAe;gBAAE,OAAO;gBAAU,UAAU;YAAS;QAE7E,GAAGnC;QACH,OAAO,IAAMoD,aAAaS;IAC9B,GAAG;QAACpC;KAAM;IAUV0B,UAAU;QACN,IAAI,CAAC7B,QAAQG,AAAU,eAAVA,OACT;QAEJ,MAAMuC,QAAQzB,UAAU,OAAO,CAACZ,KAAK;QACrC,IAAI,CAACqC,OACD;QAEJ,MAAMC,WAAWD,MAAM,aAAa,CAAoB;QACxD,MAAME,WAAWF,MAAM,aAAa,CAAiB;QACrD,IAAIE,UACA,IAAID,UAAU;YACV,MAAME,SACFF,SAAS,qBAAqB,GAAG,GAAG,GAAGC,SAAS,qBAAqB,GAAG,GAAG;YAC/EA,SAAS,SAAS,IACdC,SAASD,SAAS,YAAY,GAAG,IAAID,SAAS,YAAY,GAAG;QACrE,OACIC,SAAS,SAAS,GAAG;QAG7B,MAAME,SAASH,YAAYD,MAAM,aAAa,CAAoB;QAClEI,QAAQ,MAAM;YAAE,eAAe;QAAK;IACxC,GAAG;QAAC9C;QAAMG;QAAOE;KAAK;IAEtB,MAAM0C,WAAW,CAACC;QACd1C,QAAQ0C;IACZ;IAMA,MAAMC,SAAS,CAACC,YAAkBF;QAC9BxC,SAASwC;QACT9B,OAAO,OAAO,CAAC,GAAG,CAACgC;QACnB,MAAMC,YAAYC,oBAAoBJ;QACtC,IAAIG,WACA7D,WAAW6D;QAEf,MAAME,WAAWC,iBAAiBN,MAAME,YAAYhC,OAAO,OAAO;QAClE,IAAImC,UAAU,YACVN,SAASM;QAGbrB;IACJ;IAEA,MAAMuB,YAAY,CAACC,MAAgBP,OAAO,OAAOQ,QAAQlD,OAAOiD,KAAK5B;IAErE,MAAM8B,cAAc,CAACC,QAAkBV,OAAO,SAASW,UAAUrD,OAAOoD,OAAO/B;IAE/E,MAAMiC,aAAa,CAACC,OAAiBb,OAAO,QAAQc,SAASxD,OAAOuD;IAEpE,MAAME,eAAe,CAACC;QAClB,IAAIA,MAAM,MAAM,KAAKA,MAAM,aAAa,EACpC;QAEJ,IAAIA,AAAc,YAAdA,MAAM,GAAG,IAAgBA,AAAc,QAAdA,MAAM,GAAG,IAAYA,AAAc,gBAAdA,MAAM,GAAG,EAAkB;YACzEA,MAAM,cAAc;YACpBlC;QACJ;IACJ;IAEA,MAAMmC,WAAW/D,AAAU,eAAVA;IACjB,MAAMgE,aAAaD,WAAWzD,YAAYE,aAAaF;IACvD,MAAM2D,YAAYjG,MAAM,OAAO,CAACkC;IAEhC,MAAMgE,QAAQ,CAACC,cAAAA,WAAAA,GACX,oBAAC;YAAK,WAAU;WACXA,eAAejF,SAAS,CAACE,WAAW,WAAXA,GACtB,oBAAC;YACG,MAAK;YACL,cAAW;YACX,WAAU;YACV,SAAS0E,CAAAA;gBACLA,MAAM,eAAe;gBACrB3E,WAAWiF;YACf;YACA,WAAWN,CAAAA,QAASA,MAAM,eAAe;yBAEzC,oBAACO,MAAIA;YAAC,oBAAM,oBAACC,0BAASA;YAAK,OAAM;YAAQ,MAAK;YAAK,OAAM;cAE7D,oBACJ,oBAACD,MAAIA;YAAC,oBAAM,oBAACE,gBAAiBA;YAAK,OAAM;YAAW,MAAK;YAAK,OAAM;;IAI5E,MAAMC,aAAa,CAACC,YAAqB;YACrC,KAAK,CAACC;gBACF5D,UAAU,OAAO,CAAC2D,UAAU,GAAGC;YACnC;YACA,eAAexE,SAASuE;YACxB,aAAaA;QACjB;IAEA,OAAO,WAAP,GACI,oBAAC;QAAI,WAAW7E;qBACZ,oBAAC+E,QAAAA,IAAiB;QACd,MAAM9E;QACN,cAAc+E,CAAAA,SAAWA,SAAShD,WAAWC;qBAE7C,oBAAC8C,QAAAA,MAAmB;QAAC;qBACjB,oBAAC;QACG,KAAKjE;QACL,MAAK;QACL,UAAUtB,WAAW,KAAK;QAC1B,iBAAc;QACd,iBAAeS;QACf,iBAAeT;QACf,gBAAcS;QACd,SAAS+B;QACT,WAAWiC;QACX,WAAWgB,GACPC,cAAc;YAAEzF;YAAMC;YAASC;QAAQ,IACvC,mFACAH,YAAY;qBAGhB,oBAAC2F,wBAAsBA;QAAC,OAAO3D;QAC9B8C,MAAM,uBAGf,oBAACS,QAAAA,MAAmB,sBAChB,oBAACA,QAAAA,OAAoB;QACjB,KAAKzD;QACL,MAAK;QACL,OAAM;QACN,YAAY,CAACZ;QACb,iBAAiB;QACjB,iBAAiBwD,CAAAA,QAASA,MAAM,cAAc;QAC9C,kBAAkBA,CAAAA;YACdA,MAAM,cAAc;YACpBpD,OAAO,OAAO,EAAE,MAAM;gBAAE,eAAe;YAAK;QAChD;QACA,WAAU;qBAEV,oBAAC;QACG,KAAKE;QACL,MAAK;QACL,cAAY3C,WAAW,CAACiC,KAAK;QAC7B,cAAYF;QACZ,WAAW6E,GACPlG,aAAa;YAAEU;QAAK,IACpBW,AAAU,iBAAVA,SAA0B;QAE9B,OAAO;YACH,QAAQgE;YACR,YACIhE,AAAU,iBAAVA,QACM,CAAC,OAAO,EAAEtB,YAAY,WAAW,EAAED,YAAY,EAAE,CAAC,GAClD,CAAC,OAAO,EAAEF,UAAU,WAAW,CAAC;QAC9C;qBAEA,oBAAC;QACG,WAAWM,mBAAmB;YAAEQ;QAAK;QACrC,OAAO;YACH,QAAQ,CAAC,KAAK,EAAEiB,UAAU,gCAAgC,CAAC;QAC/D;qBAEA,oBAACyE,wBAAsBA;QACnB,OAAO3E;QACP,YAAYF;QACZ,aAAa0C;QAEhBsB,MAAM,uBAEX,oBAAC;QAAI,KAAKrD;qBACN,oBAAC;QACG,WAAU;QACV,OAAO;YACH,WAAWkD,WAAW,cAAc;YACpC,YAAY,CAAC,UAAU,EAAExF,UAAU,WAAW,CAAC;QACnD;sBAEJ,oBAAC;QACG,WAAU;QACV,OAAO;YACH,SAASwF,WAAW,IAAI;YACxB,YAAYA,WACN,CAAC,uBAAuB,EAAExF,YAAY,IAAI,EAAE,CAAC,GAC7C,CAAC,QAAQ,EAAEE,YAAY,UAAU,CAAC;QAC5C;qBAEA,oBAAC;QACG,WAAU;QACV,aAAU;OAETR,WAAW,CAACiC,KAAK,iBAEtB,oBAAC;QAAI,WAAW2E,GAAG,mBAAmB/F;qBAClC,oBAAC;QACG,WAAU;QACV,OAAO;YACH,WAAW,CAAC,YAAY,EAAGmF,AAAY,MAAZA,YAAmB,EAAE,EAAE,CAAC;YACnD,YAAY,CAAC,UAAU,EAAEzF,SAAS,cAAc,CAAC;QACrD;qBAEA,oBAAC;QACI,GAAGgG,WAAW,MAAM;QACrB,WAAU;qBAEV,oBAAC;QACG,WAAWK,GACP,8CACA9F;OAGHb,KAAK,GAAG,CAACmF,CAAAA,MAAAA,WAAAA,GACN,oBAAC2B,oBAAkBA;YACf,KAAK3B;YACL,UAAUjD,MAAM,GAAG,KAAKiD;YACxB,UAAU4B,cAAc5B,KAAK5B;YAC7B,UAAUvB,AAAS,UAATA;YACV,SAAS,IAAMkD,UAAUC;WAExB6B,IAAI7B,UAAAA,WAAAA,GAKrB,oBAAC;QACI,GAAGmB,WAAW,QAAQ;QACvB,WAAU;qBAEV,oBAAC;QACG,WAAWK,GACP,qDACA7F;OAGHV,OAAO,GAAG,CAACkF,CAAAA,QAAAA,WAAAA,GACR,oBAACwB,oBAAkBA;YACf,KAAKxB;YACL,UAAUpD,MAAM,KAAK,KAAKoD;YAC1B,UAAU2B,gBACN3B,OACApD,OACAqB;YAEJ,UAAUvB,AAAS,YAATA;YACV,SAAS,IAAMqD,YAAYC;WAE1B4B,gBAAgB,CAAC5B,QAAQ,EAAE,oBAK5C,oBAAC;QAAK,GAAGgB,WAAW,OAAO;QAAE,WAAU;qBACnC,oBAACa,YAAUA;QAAC,WAAU;qBAClB,oBAAC;QAAI,WAAU;qBACX,oBAAC;QACG,WAAWR,GACP,0CACA7F;OAGHuC,MAAM,GAAG,CAACoC,CAAAA,OAAAA,WAAAA,GACP,oBAACqB,oBAAkBA;YACf,KAAKrB;YACL,UAAUvD,MAAM,IAAI,KAAKuD;YACzB,UAAU2B,eACN3B,MACAvD,OACAqB;YAEJ,UAAUvB,AAAS,WAATA;YACV,SAAS,IAAMwD,WAAWC;WAEzBA;AAiBrE"}
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ interface BirthdayPickerCellProps {
3
+ selected: boolean;
4
+ disabled?: boolean;
5
+ tabbable: boolean;
6
+ onClick: () => void;
7
+ children: React.ReactNode;
8
+ }
9
+ /**
10
+ * One day, month or year in a step's grid. It reads as a button: a ghost one, or a primary one
11
+ * for the picked value, the same as the month and year grids of the other pickers.
12
+ */
13
+ declare const BirthdayPickerCell: ({ selected, disabled, tabbable, onClick, children }: BirthdayPickerCellProps) => React.JSX.Element;
14
+ export { BirthdayPickerCell };
@@ -0,0 +1,19 @@
1
+ import react from "react";
2
+ import { buttonVariants } from "../../Button/index.js";
3
+ import { cn } from "../../utils.js";
4
+ const BirthdayPickerCell = ({ selected, disabled, tabbable, onClick, children })=>/*#__PURE__*/ react.createElement("button", {
5
+ type: "button",
6
+ disabled: disabled,
7
+ "aria-disabled": disabled,
8
+ "aria-pressed": selected,
9
+ "data-selected": selected,
10
+ tabIndex: tabbable && !disabled ? 0 : -1,
11
+ onClick: onClick,
12
+ className: cn(buttonVariants({
13
+ variant: selected ? "primary" : "ghost",
14
+ size: "md"
15
+ }), "w-full tabular-nums")
16
+ }, children);
17
+ export { BirthdayPickerCell };
18
+
19
+ //# sourceMappingURL=BirthdayPickerCell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatePicker/primitives/BirthdayPickerCell.js","sources":["../../../src/DatePicker/primitives/BirthdayPickerCell.tsx"],"sourcesContent":["import React from \"react\";\nimport { buttonVariants } from \"~/Button/index.js\";\nimport { cn } from \"~/utils.js\";\n\ninterface BirthdayPickerCellProps {\n selected: boolean;\n disabled?: boolean;\n tabbable: boolean;\n onClick: () => void;\n children: React.ReactNode;\n}\n\n/**\n * One day, month or year in a step's grid. It reads as a button: a ghost one, or a primary one\n * for the picked value, the same as the month and year grids of the other pickers.\n */\nconst BirthdayPickerCell = ({\n selected,\n disabled,\n tabbable,\n onClick,\n children\n}: BirthdayPickerCellProps) => (\n <button\n type=\"button\"\n disabled={disabled}\n aria-disabled={disabled}\n aria-pressed={selected}\n data-selected={selected}\n tabIndex={tabbable && !disabled ? 0 : -1}\n onClick={onClick}\n className={cn(\n buttonVariants({ variant: selected ? \"primary\" : \"ghost\", size: \"md\" }),\n \"w-full tabular-nums\"\n )}\n >\n {children}\n </button>\n);\n\nexport { BirthdayPickerCell };\n"],"names":["BirthdayPickerCell","selected","disabled","tabbable","onClick","children","cn","buttonVariants"],"mappings":";;;AAgBA,MAAMA,qBAAqB,CAAC,EACxBC,QAAQ,EACRC,QAAQ,EACRC,QAAQ,EACRC,OAAO,EACPC,QAAQ,EACc,iBACtB,oBAAC;QACG,MAAK;QACL,UAAUH;QACV,iBAAeA;QACf,gBAAcD;QACd,iBAAeA;QACf,UAAUE,YAAY,CAACD,WAAW,IAAI;QACtC,SAASE;QACT,WAAWE,GACPC,eAAe;YAAE,SAASN,WAAW,YAAY;YAAS,MAAM;QAAK,IACrE;OAGHI"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { type BirthdayParts, type BirthdayStep } from "../utils/birthdayHelpers.js";
3
+ interface BirthdayPickerSegmentsProps {
4
+ parts: BirthdayParts;
5
+ activeStep?: BirthdayStep;
6
+ onStepClick?: (step: BirthdayStep) => void;
7
+ }
8
+ declare const BirthdayPickerSegments: ({ parts, activeStep, onStepClick }: BirthdayPickerSegmentsProps) => React.JSX.Element;
9
+ export { BirthdayPickerSegments };
@@ -0,0 +1,43 @@
1
+ import react from "react";
2
+ import { cn } from "../../utils.js";
3
+ import { pad } from "../utils/birthdayHelpers.js";
4
+ const BirthdayPickerSegments = ({ parts, activeStep, onStepClick })=>{
5
+ const segments = [
6
+ {
7
+ step: "day",
8
+ text: parts.day ? pad(parts.day) : "DD",
9
+ filled: !!parts.day
10
+ },
11
+ {
12
+ step: "month",
13
+ text: parts.month ? pad(parts.month) : "MM",
14
+ filled: !!parts.month
15
+ },
16
+ {
17
+ step: "year",
18
+ text: parts.year ? String(parts.year) : "YYYY",
19
+ filled: !!parts.year
20
+ }
21
+ ];
22
+ return /*#__PURE__*/ react.createElement("span", {
23
+ className: "flex items-center gap-xs tabular-nums whitespace-nowrap"
24
+ }, segments.map((segment, index)=>{
25
+ const className = cn("transition-colors", !segment.filled && "text-neutral-dimmed", activeStep === segment.step && "text-accent-primary");
26
+ return /*#__PURE__*/ react.createElement(react.Fragment, {
27
+ key: segment.step
28
+ }, index > 0 ? /*#__PURE__*/ react.createElement("span", {
29
+ className: "text-neutral-dimmed"
30
+ }, "/") : null, onStepClick ? /*#__PURE__*/ react.createElement("button", {
31
+ type: "button",
32
+ tabIndex: -1,
33
+ "data-step": segment.step,
34
+ className: cn(className, "cursor-pointer outline-none"),
35
+ onClick: ()=>onStepClick(segment.step)
36
+ }, segment.text) : /*#__PURE__*/ react.createElement("span", {
37
+ className: className
38
+ }, segment.text));
39
+ }));
40
+ };
41
+ export { BirthdayPickerSegments };
42
+
43
+ //# sourceMappingURL=BirthdayPickerSegments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatePicker/primitives/BirthdayPickerSegments.js","sources":["../../../src/DatePicker/primitives/BirthdayPickerSegments.tsx"],"sourcesContent":["import React from \"react\";\nimport { cn } from \"~/utils.js\";\nimport { type BirthdayParts, type BirthdayStep, pad } from \"../utils/birthdayHelpers.js\";\n\ninterface BirthdayPickerSegmentsProps {\n parts: BirthdayParts;\n activeStep?: BirthdayStep;\n onStepClick?: (step: BirthdayStep) => void;\n}\n\nconst BirthdayPickerSegments = ({\n parts,\n activeStep,\n onStepClick\n}: BirthdayPickerSegmentsProps) => {\n const segments: Array<{ step: BirthdayStep; text: string; filled: boolean }> = [\n { step: \"day\", text: parts.day ? pad(parts.day) : \"DD\", filled: !!parts.day },\n { step: \"month\", text: parts.month ? pad(parts.month) : \"MM\", filled: !!parts.month },\n { step: \"year\", text: parts.year ? String(parts.year) : \"YYYY\", filled: !!parts.year }\n ];\n\n return (\n <span className=\"flex items-center gap-xs tabular-nums whitespace-nowrap\">\n {segments.map((segment, index) => {\n // A filled part takes the input's value colour; an empty one reads as its placeholder.\n const className = cn(\n \"transition-colors\",\n !segment.filled && \"text-neutral-dimmed\",\n activeStep === segment.step && \"text-accent-primary\"\n );\n return (\n <React.Fragment key={segment.step}>\n {index > 0 ? <span className=\"text-neutral-dimmed\">/</span> : null}\n {onStepClick ? (\n <button\n type=\"button\"\n tabIndex={-1}\n data-step={segment.step}\n className={cn(className, \"cursor-pointer outline-none\")}\n onClick={() => onStepClick(segment.step)}\n >\n {segment.text}\n </button>\n ) : (\n <span className={className}>{segment.text}</span>\n )}\n </React.Fragment>\n );\n })}\n </span>\n );\n};\n\nexport { BirthdayPickerSegments };\n"],"names":["BirthdayPickerSegments","parts","activeStep","onStepClick","segments","pad","String","segment","index","className","cn","React"],"mappings":";;;AAUA,MAAMA,yBAAyB,CAAC,EAC5BC,KAAK,EACLC,UAAU,EACVC,WAAW,EACe;IAC1B,MAAMC,WAAyE;QAC3E;YAAE,MAAM;YAAO,MAAMH,MAAM,GAAG,GAAGI,IAAIJ,MAAM,GAAG,IAAI;YAAM,QAAQ,CAAC,CAACA,MAAM,GAAG;QAAC;QAC5E;YAAE,MAAM;YAAS,MAAMA,MAAM,KAAK,GAAGI,IAAIJ,MAAM,KAAK,IAAI;YAAM,QAAQ,CAAC,CAACA,MAAM,KAAK;QAAC;QACpF;YAAE,MAAM;YAAQ,MAAMA,MAAM,IAAI,GAAGK,OAAOL,MAAM,IAAI,IAAI;YAAQ,QAAQ,CAAC,CAACA,MAAM,IAAI;QAAC;KACxF;IAED,OAAO,WAAP,GACI,oBAAC;QAAK,WAAU;OACXG,SAAS,GAAG,CAAC,CAACG,SAASC;QAEpB,MAAMC,YAAYC,GACd,qBACA,CAACH,QAAQ,MAAM,IAAI,uBACnBL,eAAeK,QAAQ,IAAI,IAAI;QAEnC,OAAO,WAAP,GACI,oBAACI,MAAAA,QAAc;YAAC,KAAKJ,QAAQ,IAAI;WAC5BC,QAAQ,IAAI,WAAJ,GAAI,oBAAC;YAAK,WAAU;WAAsB,OAAW,MAC7DL,cAAc,WAAdA,GACG,oBAAC;YACG,MAAK;YACL,UAAU;YACV,aAAWI,QAAQ,IAAI;YACvB,WAAWG,GAAGD,WAAW;YACzB,SAAS,IAAMN,YAAYI,QAAQ,IAAI;WAEtCA,QAAQ,IAAI,kBAGjB,oBAAC;YAAK,WAAWE;WAAYF,QAAQ,IAAI;IAIzD;AAGZ"}
@@ -1,6 +1,7 @@
1
1
  import react from "react";
2
2
  import { makeDecoratable } from "../../utils.js";
3
3
  import { DateOnlyPicker } from "./DateOnlyPicker.js";
4
+ import { BirthdayPicker } from "./BirthdayPicker.js";
4
5
  import { TimeOnlyPicker } from "./TimeOnlyPicker.js";
5
6
  import { DateTimePicker } from "./DateTimePicker.js";
6
7
  import { MonthPicker } from "./MonthPicker.js";
@@ -14,6 +15,8 @@ const DecoratableDatePickerPrimitive = (props)=>{
14
15
  switch(props.type){
15
16
  case "date":
16
17
  return /*#__PURE__*/ react.createElement(DateOnlyPicker, props);
18
+ case "birthday":
19
+ return /*#__PURE__*/ react.createElement(BirthdayPicker, props);
17
20
  case "time":
18
21
  return /*#__PURE__*/ react.createElement(TimeOnlyPicker, props);
19
22
  case "dateTimeLocal":
@@ -1 +1 @@
1
- {"version":3,"file":"DatePicker/primitives/DatePickerPrimitive.js","sources":["../../../src/DatePicker/primitives/DatePickerPrimitive.tsx"],"sourcesContent":["import React from \"react\";\nimport { makeDecoratable } from \"~/utils.js\";\nimport type { DatePickerPrimitiveProps } from \"../utils/types.js\";\nimport { DateOnlyPicker } from \"./DateOnlyPicker.js\";\nimport { TimeOnlyPicker } from \"./TimeOnlyPicker.js\";\nimport { DateTimePicker } from \"./DateTimePicker.js\";\nimport { MonthPicker } from \"./MonthPicker.js\";\nimport { WeekPicker } from \"./WeekPicker.js\";\nimport { YearPicker } from \"./YearPicker.js\";\nimport { DateRangePicker } from \"./DateRangePicker.js\";\nimport { MultipleDatesPicker } from \"./MultipleDatesPicker.js\";\nimport { MultipleMonthsPicker } from \"./MultipleMonthsPicker.js\";\nimport { MultipleYearsPicker } from \"./MultipleYearsPicker.js\";\n\nconst DecoratableDatePickerPrimitive = (props: DatePickerPrimitiveProps) => {\n switch (props.type) {\n case \"date\":\n return <DateOnlyPicker {...props} />;\n case \"time\":\n return <TimeOnlyPicker {...props} />;\n case \"dateTimeLocal\":\n return <DateTimePicker {...props} withTimezone={false} />;\n case \"dateTimeTz\":\n return <DateTimePicker {...props} withTimezone={true} />;\n case \"month\":\n return <MonthPicker {...props} />;\n case \"week\":\n return <WeekPicker {...props} />;\n case \"year\":\n return <YearPicker {...props} />;\n case \"dateRange\":\n return <DateRangePicker {...props} />;\n case \"multipleDates\":\n return <MultipleDatesPicker {...props} />;\n case \"multipleMonths\":\n return <MultipleMonthsPicker {...props} />;\n case \"multipleYears\":\n return <MultipleYearsPicker {...props} />;\n }\n};\n\nconst DatePickerPrimitive = makeDecoratable(\"DatePickerPrimitive\", DecoratableDatePickerPrimitive);\n\nexport { DatePickerPrimitive, type DatePickerPrimitiveProps };\n"],"names":["DecoratableDatePickerPrimitive","props","DateOnlyPicker","TimeOnlyPicker","DateTimePicker","MonthPicker","WeekPicker","YearPicker","DateRangePicker","MultipleDatesPicker","MultipleMonthsPicker","MultipleYearsPicker","DatePickerPrimitive","makeDecoratable"],"mappings":";;;;;;;;;;;;AAcA,MAAMA,iCAAiC,CAACC;IACpC,OAAQA,MAAM,IAAI;QACd,KAAK;YACD,OAAO,WAAP,GAAO,oBAACC,gBAAmBD;QAC/B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACE,gBAAmBF;QAC/B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACG,gBAAcA;gBAAE,GAAGH,KAAK;gBAAE,cAAc;;QACpD,KAAK;YACD,OAAO,WAAP,GAAO,oBAACG,gBAAcA;gBAAE,GAAGH,KAAK;gBAAE,cAAc;;QACpD,KAAK;YACD,OAAO,WAAP,GAAO,oBAACI,aAAgBJ;QAC5B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACK,YAAeL;QAC3B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACM,YAAeN;QAC3B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACO,iBAAoBP;QAChC,KAAK;YACD,OAAO,WAAP,GAAO,oBAACQ,qBAAwBR;QACpC,KAAK;YACD,OAAO,WAAP,GAAO,oBAACS,sBAAyBT;QACrC,KAAK;YACD,OAAO,WAAP,GAAO,oBAACU,qBAAwBV;IACxC;AACJ;AAEA,MAAMW,sBAAsBC,gBAAgB,uBAAuBb"}
1
+ {"version":3,"file":"DatePicker/primitives/DatePickerPrimitive.js","sources":["../../../src/DatePicker/primitives/DatePickerPrimitive.tsx"],"sourcesContent":["import React from \"react\";\nimport { makeDecoratable } from \"~/utils.js\";\nimport type { DatePickerPrimitiveProps } from \"../utils/types.js\";\nimport { DateOnlyPicker } from \"./DateOnlyPicker.js\";\nimport { BirthdayPicker } from \"./BirthdayPicker.js\";\nimport { TimeOnlyPicker } from \"./TimeOnlyPicker.js\";\nimport { DateTimePicker } from \"./DateTimePicker.js\";\nimport { MonthPicker } from \"./MonthPicker.js\";\nimport { WeekPicker } from \"./WeekPicker.js\";\nimport { YearPicker } from \"./YearPicker.js\";\nimport { DateRangePicker } from \"./DateRangePicker.js\";\nimport { MultipleDatesPicker } from \"./MultipleDatesPicker.js\";\nimport { MultipleMonthsPicker } from \"./MultipleMonthsPicker.js\";\nimport { MultipleYearsPicker } from \"./MultipleYearsPicker.js\";\n\nconst DecoratableDatePickerPrimitive = (props: DatePickerPrimitiveProps) => {\n switch (props.type) {\n case \"date\":\n return <DateOnlyPicker {...props} />;\n case \"birthday\":\n return <BirthdayPicker {...props} />;\n case \"time\":\n return <TimeOnlyPicker {...props} />;\n case \"dateTimeLocal\":\n return <DateTimePicker {...props} withTimezone={false} />;\n case \"dateTimeTz\":\n return <DateTimePicker {...props} withTimezone={true} />;\n case \"month\":\n return <MonthPicker {...props} />;\n case \"week\":\n return <WeekPicker {...props} />;\n case \"year\":\n return <YearPicker {...props} />;\n case \"dateRange\":\n return <DateRangePicker {...props} />;\n case \"multipleDates\":\n return <MultipleDatesPicker {...props} />;\n case \"multipleMonths\":\n return <MultipleMonthsPicker {...props} />;\n case \"multipleYears\":\n return <MultipleYearsPicker {...props} />;\n }\n};\n\nconst DatePickerPrimitive = makeDecoratable(\"DatePickerPrimitive\", DecoratableDatePickerPrimitive);\n\nexport { DatePickerPrimitive, type DatePickerPrimitiveProps };\n"],"names":["DecoratableDatePickerPrimitive","props","DateOnlyPicker","BirthdayPicker","TimeOnlyPicker","DateTimePicker","MonthPicker","WeekPicker","YearPicker","DateRangePicker","MultipleDatesPicker","MultipleMonthsPicker","MultipleYearsPicker","DatePickerPrimitive","makeDecoratable"],"mappings":";;;;;;;;;;;;;AAeA,MAAMA,iCAAiC,CAACC;IACpC,OAAQA,MAAM,IAAI;QACd,KAAK;YACD,OAAO,WAAP,GAAO,oBAACC,gBAAmBD;QAC/B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACE,gBAAmBF;QAC/B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACG,gBAAmBH;QAC/B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACI,gBAAcA;gBAAE,GAAGJ,KAAK;gBAAE,cAAc;;QACpD,KAAK;YACD,OAAO,WAAP,GAAO,oBAACI,gBAAcA;gBAAE,GAAGJ,KAAK;gBAAE,cAAc;;QACpD,KAAK;YACD,OAAO,WAAP,GAAO,oBAACK,aAAgBL;QAC5B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACM,YAAeN;QAC3B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACO,YAAeP;QAC3B,KAAK;YACD,OAAO,WAAP,GAAO,oBAACQ,iBAAoBR;QAChC,KAAK;YACD,OAAO,WAAP,GAAO,oBAACS,qBAAwBT;QACpC,KAAK;YACD,OAAO,WAAP,GAAO,oBAACU,sBAAyBV;QACrC,KAAK;YACD,OAAO,WAAP,GAAO,oBAACW,qBAAwBX;IACxC;AACJ;AAEA,MAAMY,sBAAsBC,gBAAgB,uBAAuBd"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Logic for the step-by-step birthday picker: the date is picked as day, then month, then year.
3
+ * Months are 1-based throughout (1 = January).
4
+ */
5
+ export interface BirthdayParts {
6
+ day?: number;
7
+ month?: number;
8
+ year?: number;
9
+ }
10
+ export type BirthdayStep = "day" | "month" | "year";
11
+ export declare const DEFAULT_BIRTHDAY_YEARS_BACK = 120;
12
+ /** The first and last date the picker may produce. Either may be left open. */
13
+ export interface BirthdayLimits {
14
+ minDate?: Date;
15
+ maxDate?: Date;
16
+ }
17
+ /** The dates the picker may produce: one of the offered years, within the limits. */
18
+ export interface BirthdayRange extends BirthdayLimits {
19
+ years: number[];
20
+ }
21
+ /**
22
+ * Reads the day, month and year from a `YYYY-MM-DD` value. A value that carries a time
23
+ * (`2026-05-01T00:00:00.000Z`) still yields its date part. Anything else yields no parts.
24
+ */
25
+ export declare function parseBirthdayValue(value: string | undefined | null): BirthdayParts;
26
+ /**
27
+ * Returns the `YYYY-MM-DD` value, or `undefined` while any part is still missing.
28
+ */
29
+ export declare function formatBirthdayValue(parts: BirthdayParts): string | undefined;
30
+ export declare function pad(value: number): string;
31
+ export declare function isLeapYear(year: number): boolean;
32
+ /**
33
+ * Days in a month. Without a year, February counts 29 days, because the year is picked
34
+ * after the month and a leap year may still be chosen.
35
+ */
36
+ export declare function daysInMonth(month: number, year?: number): number;
37
+ /**
38
+ * Whether the range holds a date with every part set in `parts`. An unset year is looked
39
+ * for among the offered years; an unset month or day can be any.
40
+ */
41
+ export declare function isInBirthdayRange(parts: BirthdayParts, range: BirthdayRange): boolean;
42
+ /** A day is unavailable when no date in the range falls on it. */
43
+ export declare function isDayDisabled(day: number, range?: BirthdayRange): boolean;
44
+ /**
45
+ * A month is unavailable when it can't hold the chosen day (31 rules out the 30-day months
46
+ * and February), or when no date in the range has the chosen day in that month.
47
+ */
48
+ export declare function isMonthDisabled(month: number, parts: BirthdayParts, range?: BirthdayRange): boolean;
49
+ /**
50
+ * A year is unavailable when it can't hold the chosen day and month (29 February in a
51
+ * non-leap year), or when the date it makes falls outside the range.
52
+ */
53
+ export declare function isYearDisabled(year: number, parts: BirthdayParts, range?: BirthdayRange): boolean;
54
+ /**
55
+ * Picking a day clears whatever comes after it that can no longer hold it: the month when
56
+ * the month is too short or the range has no such date, otherwise the year when only the
57
+ * year is the problem (29 February, or a date past a limit).
58
+ */
59
+ export declare function pickDay(parts: BirthdayParts, day: number, range?: BirthdayRange): BirthdayParts;
60
+ /**
61
+ * Picking a month keeps the day (only months that hold it can be picked) and clears the
62
+ * year when that year can't hold the date.
63
+ */
64
+ export declare function pickMonth(parts: BirthdayParts, month: number, range?: BirthdayRange): BirthdayParts;
65
+ export declare function pickYear(parts: BirthdayParts, year: number): BirthdayParts;
66
+ /**
67
+ * The step to show after a pick, or `undefined` when the picker should close. A missing part
68
+ * comes first. Once the date is complete, the picker walks on to the steps after `current`
69
+ * that weren't picked while it was open, so editing a saved date still goes day, month, year.
70
+ */
71
+ export declare function nextBirthdayStep(parts: BirthdayParts, current: BirthdayStep, picked: ReadonlySet<BirthdayStep>): BirthdayStep | undefined;
72
+ /**
73
+ * The years to offer, newest first. The default runs from this year back
74
+ * `DEFAULT_BIRTHDAY_YEARS_BACK` years, moved and cut to fit the limits. A year already set
75
+ * outside the range is added, so an existing value is never hidden.
76
+ */
77
+ export declare function birthdayYears(yearRange?: [number, number], includeYear?: number, limits?: BirthdayLimits): number[];
@@ -0,0 +1,145 @@
1
+ const DEFAULT_BIRTHDAY_YEARS_BACK = 120;
2
+ const ALL_MONTHS = Array.from({
3
+ length: 12
4
+ }, (_, index)=>index + 1);
5
+ function parseBirthdayValue(value) {
6
+ if (!value) return {};
7
+ const match = String(value).match(/^(\d{4})-(\d{2})-(\d{2})/);
8
+ if (!match) return {};
9
+ const year = Number(match[1]);
10
+ const month = Number(match[2]);
11
+ const day = Number(match[3]);
12
+ if (month < 1 || month > 12 || day < 1 || day > daysInMonth(month, year)) return {};
13
+ return {
14
+ day,
15
+ month,
16
+ year
17
+ };
18
+ }
19
+ function formatBirthdayValue(parts) {
20
+ const { day, month, year } = parts;
21
+ if (void 0 === day || void 0 === month || void 0 === year) return;
22
+ return `${String(year).padStart(4, "0")}-${pad(month)}-${pad(day)}`;
23
+ }
24
+ function pad(value) {
25
+ return String(value).padStart(2, "0");
26
+ }
27
+ function isLeapYear(year) {
28
+ return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
29
+ }
30
+ function daysInMonth(month, year) {
31
+ if (2 === month) return void 0 === year || isLeapYear(year) ? 29 : 28;
32
+ return [
33
+ 4,
34
+ 6,
35
+ 9,
36
+ 11
37
+ ].includes(month) ? 30 : 31;
38
+ }
39
+ function dateKey(year, month, day) {
40
+ return 10000 * year + 100 * month + day;
41
+ }
42
+ function limitKey(date, open) {
43
+ if (!date || isNaN(date.getTime())) return open;
44
+ return dateKey(date.getFullYear(), date.getMonth() + 1, date.getDate());
45
+ }
46
+ function limitYear(date) {
47
+ return date && !isNaN(date.getTime()) ? date.getFullYear() : void 0;
48
+ }
49
+ function isInBirthdayRange(parts, range) {
50
+ const min = limitKey(range.minDate, -1 / 0);
51
+ const max = limitKey(range.maxDate, 1 / 0);
52
+ const years = void 0 !== parts.year ? [
53
+ parts.year
54
+ ] : range.years;
55
+ const months = void 0 !== parts.month ? [
56
+ parts.month
57
+ ] : ALL_MONTHS;
58
+ for (const year of years)if (!(dateKey(year, 12, 31) < min || dateKey(year, 1, 1) > max)) for (const month of months){
59
+ const last = daysInMonth(month, year);
60
+ const first = parts.day ?? 1;
61
+ const final = parts.day ?? last;
62
+ if (!(final > last)) {
63
+ if (dateKey(year, month, final) >= min && dateKey(year, month, first) <= max) return true;
64
+ }
65
+ }
66
+ return false;
67
+ }
68
+ function isDayDisabled(day, range) {
69
+ return void 0 !== range && !isInBirthdayRange({
70
+ day
71
+ }, range);
72
+ }
73
+ function isMonthDisabled(month, parts, range) {
74
+ if (void 0 !== parts.day && parts.day > daysInMonth(month)) return true;
75
+ return void 0 !== range && !isInBirthdayRange({
76
+ day: parts.day,
77
+ month
78
+ }, range);
79
+ }
80
+ function isYearDisabled(year, parts, range) {
81
+ if (void 0 !== parts.day && void 0 !== parts.month && parts.day > daysInMonth(parts.month, year)) return true;
82
+ return void 0 !== range && !isInBirthdayRange({
83
+ day: parts.day,
84
+ month: parts.month,
85
+ year
86
+ }, range);
87
+ }
88
+ function pickDay(parts, day, range) {
89
+ const next = {
90
+ ...parts,
91
+ day
92
+ };
93
+ if (void 0 !== next.month && isMonthDisabled(next.month, next, range)) next.month = void 0;
94
+ if (void 0 !== next.year && isYearDisabled(next.year, next, range)) next.year = void 0;
95
+ return next;
96
+ }
97
+ function pickMonth(parts, month, range) {
98
+ const next = {
99
+ ...parts,
100
+ month
101
+ };
102
+ if (void 0 !== next.year && isYearDisabled(next.year, next, range)) next.year = void 0;
103
+ return next;
104
+ }
105
+ function pickYear(parts, year) {
106
+ return {
107
+ ...parts,
108
+ year
109
+ };
110
+ }
111
+ const BIRTHDAY_STEPS = [
112
+ "day",
113
+ "month",
114
+ "year"
115
+ ];
116
+ function nextBirthdayStep(parts, current, picked) {
117
+ const missing = BIRTHDAY_STEPS.find((step)=>void 0 === parts[step]);
118
+ if (missing) return missing;
119
+ return BIRTHDAY_STEPS.slice(BIRTHDAY_STEPS.indexOf(current) + 1).find((step)=>!picked.has(step));
120
+ }
121
+ function birthdayYears(yearRange, includeYear, limits) {
122
+ const [from, to] = yearRange ?? defaultBirthdayYearRange(limits);
123
+ let start = Math.min(from, to);
124
+ let end = Math.max(from, to);
125
+ if (void 0 !== includeYear) {
126
+ start = Math.min(start, includeYear);
127
+ end = Math.max(end, includeYear);
128
+ }
129
+ const years = [];
130
+ for(let year = end; year >= start; year--)years.push(year);
131
+ return years;
132
+ }
133
+ function defaultBirthdayYearRange(limits) {
134
+ const minYear = limitYear(limits?.minDate);
135
+ const maxYear = limitYear(limits?.maxDate);
136
+ const to = maxYear ?? Math.max(new Date().getFullYear(), minYear ?? -1 / 0);
137
+ const from = minYear ?? to - DEFAULT_BIRTHDAY_YEARS_BACK;
138
+ return [
139
+ from,
140
+ to
141
+ ];
142
+ }
143
+ export { DEFAULT_BIRTHDAY_YEARS_BACK, birthdayYears, daysInMonth, formatBirthdayValue, isDayDisabled, isInBirthdayRange, isLeapYear, isMonthDisabled, isYearDisabled, nextBirthdayStep, pad, parseBirthdayValue, pickDay, pickMonth, pickYear };
144
+
145
+ //# sourceMappingURL=birthdayHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatePicker/utils/birthdayHelpers.js","sources":["../../../src/DatePicker/utils/birthdayHelpers.ts"],"sourcesContent":["/**\n * Logic for the step-by-step birthday picker: the date is picked as day, then month, then year.\n * Months are 1-based throughout (1 = January).\n */\n\nexport interface BirthdayParts {\n day?: number;\n month?: number;\n year?: number;\n}\n\nexport type BirthdayStep = \"day\" | \"month\" | \"year\";\n\nexport const DEFAULT_BIRTHDAY_YEARS_BACK = 120;\n\n/** The first and last date the picker may produce. Either may be left open. */\nexport interface BirthdayLimits {\n minDate?: Date;\n maxDate?: Date;\n}\n\n/** The dates the picker may produce: one of the offered years, within the limits. */\nexport interface BirthdayRange extends BirthdayLimits {\n years: number[];\n}\n\nconst ALL_MONTHS = Array.from({ length: 12 }, (_, index) => index + 1);\n\n/**\n * Reads the day, month and year from a `YYYY-MM-DD` value. A value that carries a time\n * (`2026-05-01T00:00:00.000Z`) still yields its date part. Anything else yields no parts.\n */\nexport function parseBirthdayValue(value: string | undefined | null): BirthdayParts {\n if (!value) {\n return {};\n }\n const match = String(value).match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n if (!match) {\n return {};\n }\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n if (month < 1 || month > 12 || day < 1 || day > daysInMonth(month, year)) {\n return {};\n }\n return { day, month, year };\n}\n\n/**\n * Returns the `YYYY-MM-DD` value, or `undefined` while any part is still missing.\n */\nexport function formatBirthdayValue(parts: BirthdayParts): string | undefined {\n const { day, month, year } = parts;\n if (day === undefined || month === undefined || year === undefined) {\n return undefined;\n }\n return `${String(year).padStart(4, \"0\")}-${pad(month)}-${pad(day)}`;\n}\n\nexport function pad(value: number): string {\n return String(value).padStart(2, \"0\");\n}\n\nexport function isLeapYear(year: number): boolean {\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\n/**\n * Days in a month. Without a year, February counts 29 days, because the year is picked\n * after the month and a leap year may still be chosen.\n */\nexport function daysInMonth(month: number, year?: number): number {\n if (month === 2) {\n return year === undefined || isLeapYear(year) ? 29 : 28;\n }\n return [4, 6, 9, 11].includes(month) ? 30 : 31;\n}\n\nfunction dateKey(year: number, month: number, day: number): number {\n return year * 10000 + month * 100 + day;\n}\n\n/** The calendar day of a limit, in local time, the same day the calendar picker compares. */\nfunction limitKey(date: Date | undefined, open: number): number {\n if (!date || isNaN(date.getTime())) {\n return open;\n }\n return dateKey(date.getFullYear(), date.getMonth() + 1, date.getDate());\n}\n\nfunction limitYear(date: Date | undefined): number | undefined {\n return date && !isNaN(date.getTime()) ? date.getFullYear() : undefined;\n}\n\n/**\n * Whether the range holds a date with every part set in `parts`. An unset year is looked\n * for among the offered years; an unset month or day can be any.\n */\nexport function isInBirthdayRange(parts: BirthdayParts, range: BirthdayRange): boolean {\n const min = limitKey(range.minDate, -Infinity);\n const max = limitKey(range.maxDate, Infinity);\n const years = parts.year !== undefined ? [parts.year] : range.years;\n const months = parts.month !== undefined ? [parts.month] : ALL_MONTHS;\n for (const year of years) {\n if (dateKey(year, 12, 31) < min || dateKey(year, 1, 1) > max) {\n continue;\n }\n for (const month of months) {\n const last = daysInMonth(month, year);\n const first = parts.day ?? 1;\n const final = parts.day ?? last;\n if (final > last) {\n continue;\n }\n if (dateKey(year, month, final) >= min && dateKey(year, month, first) <= max) {\n return true;\n }\n }\n }\n return false;\n}\n\n/** A day is unavailable when no date in the range falls on it. */\nexport function isDayDisabled(day: number, range?: BirthdayRange): boolean {\n return range !== undefined && !isInBirthdayRange({ day }, range);\n}\n\n/**\n * A month is unavailable when it can't hold the chosen day (31 rules out the 30-day months\n * and February), or when no date in the range has the chosen day in that month.\n */\nexport function isMonthDisabled(\n month: number,\n parts: BirthdayParts,\n range?: BirthdayRange\n): boolean {\n if (parts.day !== undefined && parts.day > daysInMonth(month)) {\n return true;\n }\n return range !== undefined && !isInBirthdayRange({ day: parts.day, month }, range);\n}\n\n/**\n * A year is unavailable when it can't hold the chosen day and month (29 February in a\n * non-leap year), or when the date it makes falls outside the range.\n */\nexport function isYearDisabled(year: number, parts: BirthdayParts, range?: BirthdayRange): boolean {\n if (\n parts.day !== undefined &&\n parts.month !== undefined &&\n parts.day > daysInMonth(parts.month, year)\n ) {\n return true;\n }\n return (\n range !== undefined &&\n !isInBirthdayRange({ day: parts.day, month: parts.month, year }, range)\n );\n}\n\n/**\n * Picking a day clears whatever comes after it that can no longer hold it: the month when\n * the month is too short or the range has no such date, otherwise the year when only the\n * year is the problem (29 February, or a date past a limit).\n */\nexport function pickDay(parts: BirthdayParts, day: number, range?: BirthdayRange): BirthdayParts {\n const next: BirthdayParts = { ...parts, day };\n if (next.month !== undefined && isMonthDisabled(next.month, next, range)) {\n next.month = undefined;\n }\n if (next.year !== undefined && isYearDisabled(next.year, next, range)) {\n next.year = undefined;\n }\n return next;\n}\n\n/**\n * Picking a month keeps the day (only months that hold it can be picked) and clears the\n * year when that year can't hold the date.\n */\nexport function pickMonth(\n parts: BirthdayParts,\n month: number,\n range?: BirthdayRange\n): BirthdayParts {\n const next: BirthdayParts = { ...parts, month };\n if (next.year !== undefined && isYearDisabled(next.year, next, range)) {\n next.year = undefined;\n }\n return next;\n}\n\nexport function pickYear(parts: BirthdayParts, year: number): BirthdayParts {\n return { ...parts, year };\n}\n\nconst BIRTHDAY_STEPS: BirthdayStep[] = [\"day\", \"month\", \"year\"];\n\n/**\n * The step to show after a pick, or `undefined` when the picker should close. A missing part\n * comes first. Once the date is complete, the picker walks on to the steps after `current`\n * that weren't picked while it was open, so editing a saved date still goes day, month, year.\n */\nexport function nextBirthdayStep(\n parts: BirthdayParts,\n current: BirthdayStep,\n picked: ReadonlySet<BirthdayStep>\n): BirthdayStep | undefined {\n const missing = BIRTHDAY_STEPS.find(step => parts[step] === undefined);\n if (missing) {\n return missing;\n }\n return BIRTHDAY_STEPS.slice(BIRTHDAY_STEPS.indexOf(current) + 1).find(\n step => !picked.has(step)\n );\n}\n\n/**\n * The years to offer, newest first. The default runs from this year back\n * `DEFAULT_BIRTHDAY_YEARS_BACK` years, moved and cut to fit the limits. A year already set\n * outside the range is added, so an existing value is never hidden.\n */\nexport function birthdayYears(\n yearRange?: [number, number],\n includeYear?: number,\n limits?: BirthdayLimits\n): number[] {\n const [from, to] = yearRange ?? defaultBirthdayYearRange(limits);\n let start = Math.min(from, to);\n let end = Math.max(from, to);\n if (includeYear !== undefined) {\n start = Math.min(start, includeYear);\n end = Math.max(end, includeYear);\n }\n const years: number[] = [];\n for (let year = end; year >= start; year--) {\n years.push(year);\n }\n return years;\n}\n\n/**\n * From the latest allowed year down to the earliest. Without an upper limit the list starts at\n * this year (or the lower limit's year, if that's later); without a lower limit it ends\n * `DEFAULT_BIRTHDAY_YEARS_BACK` years before its start.\n */\nfunction defaultBirthdayYearRange(limits?: BirthdayLimits): [number, number] {\n const minYear = limitYear(limits?.minDate);\n const maxYear = limitYear(limits?.maxDate);\n const to = maxYear ?? Math.max(new Date().getFullYear(), minYear ?? -Infinity);\n const from = minYear ?? to - DEFAULT_BIRTHDAY_YEARS_BACK;\n return [from, to];\n}\n"],"names":["DEFAULT_BIRTHDAY_YEARS_BACK","ALL_MONTHS","Array","_","index","parseBirthdayValue","value","match","String","year","Number","month","day","daysInMonth","formatBirthdayValue","parts","undefined","pad","isLeapYear","dateKey","limitKey","date","open","isNaN","limitYear","isInBirthdayRange","range","min","max","Infinity","years","months","last","first","final","isDayDisabled","isMonthDisabled","isYearDisabled","pickDay","next","pickMonth","pickYear","BIRTHDAY_STEPS","nextBirthdayStep","current","picked","missing","step","birthdayYears","yearRange","includeYear","limits","from","to","defaultBirthdayYearRange","start","Math","end","minYear","maxYear","Date"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};