@punaro/react-datepicker 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/styles.css +7 -0
- package/package.json +9 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`react`),t=require(`react/jsx-runtime`);function n(e){let t=Object.prototype.toString.call(e);return e instanceof Date||typeof e==`object`&&t===`[object Date]`?new e.constructor(+e):typeof e==`number`||t===`[object Number]`||typeof e==`string`||t===`[object String]`?new Date(e):new Date(NaN)}function r(e,t){return e instanceof Date?new e.constructor(t):new Date(t)}function i(e){return e instanceof Date||typeof e==`object`&&Object.prototype.toString.call(e)===`[object Date]`}function a(e){if(!i(e)&&typeof e!=`number`)return!1;let t=n(e);return!isNaN(Number(t))}function o(e){let t=n(e),i=t.getFullYear(),a=t.getMonth(),o=r(e,0);return o.setFullYear(i,a+1,0),o.setHours(0,0,0,0),o.getDate()}function s(e){let t=/(dd|MM|yyyy)/g,n=[],r=0,i;for(;(i=t.exec(e))!==null;){i.index>r&&n.push({type:`sep`,value:e.slice(r,i.index)});let t=i[1];n.push({type:`field`,key:t,length:t===`yyyy`?4:2}),r=i.index+i[1].length}return r<e.length&&n.push({type:`sep`,value:e.slice(r)}),n}function c(e,t){return String(e).padStart(t,`0`)}var l={dd:`DD`,MM:`MM`,yyyy:`YYYY`},u={dd:`Day`,MM:`Month`,yyyy:`Year`},d={dd:``,MM:``,yyyy:``};function f(e){return!e||!a(e)?d:{dd:c(e.getDate(),2),MM:c(e.getMonth()+1,2),yyyy:c(e.getFullYear(),4)}}function p(e,t){let n=parseInt(e,10);if(!n||n<1||n>12)return 31;let r=t.length===4?parseInt(t,10):2e3;return o(new Date(r,n-1,1))}function m(e){if(e.dd.length!==2||e.MM.length!==2||e.yyyy.length!==4)return;let t=parseInt(e.dd,10),n=parseInt(e.MM,10),r=parseInt(e.yyyy,10),i=new Date(r,n-1,t);if(i.getFullYear()===r&&i.getMonth()===n-1&&i.getDate()===t)return i}function h({value:n,onChange:r,dateFormat:i=`dd/MM/yyyy`,disabled:o=!1,name:d,id:h,showDropdowns:g=!1,maxYear:_,yearRange:v=100,dropdownIcon:y,theme:b=`light`,outlined:x=!1,isPlainStyle:S=!1,classNames:C,styles:w,...T}){let E=_??new Date().getFullYear(),D=(0,e.useMemo)(()=>s(i),[i]),O=(0,e.useMemo)(()=>D.filter(e=>e.type===`field`).map(e=>e.key),[D]),[k,A]=(0,e.useState)(()=>f(n)),j=(0,e.useRef)({dd:null,MM:null,yyyy:null}),M=(0,e.useRef)(n&&a(n)?n.getTime():void 0),N=n&&a(n)?n.getTime():void 0;(0,e.useEffect)(()=>{N!==M.current&&(M.current=N,A(f(n)))},[N]);function P(e){let t=m(e);if(t){M.current=t.getTime(),r?.(t);return}M.current=void 0,r?.(void 0)}function F(e,t){let n=O[O.indexOf(e)+t];if(!n)return;let r=j.current[n];if(r)if(r.focus(),t===-1){let e=r.value.length;try{r.setSelectionRange(e,e)}catch{}}else try{r.setSelectionRange(0,r.value.length)}catch{}}function I(e,t,n){let r=t.replace(/\D/g,``).slice(0,n);A(t=>{let i={...t,[e]:r};if(r.length>0){let a=parseInt(r,10);if(r.length<n&&(e===`dd`&&parseInt(r[0],10)>3||e===`MM`&&parseInt(r[0],10)>1)||r.length===n&&(e===`dd`&&(a<1||a>p(i.MM,i.yyyy))||e===`MM`&&(a<1||a>12)||e===`yyyy`&&a<1))return t}return e!==`dd`&&i.dd.length===2&&parseInt(i.dd,10)>p(i.MM,i.yyyy)&&(i.dd=``),r.length===n&&queueMicrotask(()=>F(e,1)),P(i),i})}function L(e){if(e===`dd`){let e=p(k.MM,k.yyyy);return Array.from({length:e},(e,t)=>c(t+1,2))}return e===`MM`?Array.from({length:12},(e,t)=>c(t+1,2)):Array.from({length:v},(e,t)=>c(E-t,4))}function R(e,t,n){I(e,t,n)}function z(e,t){let n=t.currentTarget,r=n.selectionStart===0&&n.selectionEnd===0,i=n.selectionStart===n.value.length&&n.selectionEnd===n.value.length;if(t.key===`Backspace`&&n.value===``){t.preventDefault(),F(e,-1);return}if(t.key===`ArrowLeft`&&r){t.preventDefault(),F(e,-1);return}t.key===`ArrowRight`&&i&&(t.preventDefault(),F(e,1))}let B=S?{position:`relative`,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,width:`1em`,height:`1em`,cursor:o?`not-allowed`:`pointer`,userSelect:`none`,lineHeight:1}:{position:`relative`},V={position:`absolute`,inset:0,width:`100%`,height:`100%`,opacity:0,cursor:o?`not-allowed`:`pointer`,appearance:`none`,WebkitAppearance:`none`,MozAppearance:`none`,border:0,padding:0,margin:0,background:`transparent`,color:`transparent`,fontSize:`inherit`},H=S?{display:`inline-flex`,alignItems:`center`}:void 0,U=(e,t)=>{let n=C?.[t];return e?n?`${e} ${n}`:e:n},W=(e,t)=>{let n=w?.[t];return e?n?{...e,...n}:e:n};return(0,t.jsx)(`span`,{role:`group`,"aria-label":T[`aria-label`]??`Date`,id:h,className:U(S?void 0:`rdp-root`,`root`),style:W(void 0,`root`),"data-theme":S?void 0:b,"data-outlined":S?void 0:x?`true`:`false`,"data-disabled":S?void 0:o?`true`:`false`,children:D.map((e,n)=>e.type===`sep`?(0,t.jsx)(`span`,{"aria-hidden":`true`,className:U(S?void 0:`rdp-sep`,`separator`),style:W(void 0,`separator`),children:e.value},`s${n}`):(0,t.jsxs)(`span`,{className:U(S?void 0:`rdp-segment`,`segment`),style:W(H,`segment`),children:[(0,t.jsx)(`input`,{ref:t=>{j.current[e.key]=t},type:`text`,inputMode:`numeric`,pattern:`[0-9]*`,autoComplete:`off`,disabled:o,name:d?`${d}-${e.key}`:void 0,maxLength:e.length,size:e.length,placeholder:l[e.key],"aria-label":u[e.key],className:U(S?void 0:`rdp-input`,`input`),style:W(void 0,`input`),value:k[e.key],onChange:t=>I(e.key,t.target.value,e.length),onKeyDown:t=>z(e.key,t),onFocus:e=>e.currentTarget.select()}),g&&(0,t.jsxs)(`span`,{className:U(S?void 0:`rdp-trigger`,`trigger`),style:W(B,`trigger`),children:[(0,t.jsx)(`span`,{"aria-hidden":`true`,className:U(void 0,`dropdownIcon`),style:W(void 0,`dropdownIcon`),children:typeof y==`function`?y(e.key):y??`▾`}),(0,t.jsxs)(`select`,{"aria-label":`Pick ${u[e.key]}`,disabled:o,className:U(S?void 0:`rdp-select`,`select`),value:k[e.key],onChange:t=>R(e.key,t.target.value,e.length),style:W(V,`select`),children:[(0,t.jsx)(`option`,{value:``,disabled:!0,hidden:!0,children:u[e.key]}),L(e.key).map(e=>(0,t.jsx)(`option`,{value:e,children:e},e))]})]})]},e.key))})}exports.DatePicker=h;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`react`),t=require(`react/jsx-runtime`);function n(e){let t=Object.prototype.toString.call(e);return e instanceof Date||typeof e==`object`&&t===`[object Date]`?new e.constructor(+e):typeof e==`number`||t===`[object Number]`||typeof e==`string`||t===`[object String]`?new Date(e):new Date(NaN)}function r(e,t){return e instanceof Date?new e.constructor(t):new Date(t)}function i(e){return e instanceof Date||typeof e==`object`&&Object.prototype.toString.call(e)===`[object Date]`}function a(e){if(!i(e)&&typeof e!=`number`)return!1;let t=n(e);return!isNaN(Number(t))}function o(e){let t=n(e),i=t.getFullYear(),a=t.getMonth(),o=r(e,0);return o.setFullYear(i,a+1,0),o.setHours(0,0,0,0),o.getDate()}function s(e){let t=/(dd|MM|yyyy)/g,n=[],r=0,i;for(;(i=t.exec(e))!==null;){i.index>r&&n.push({type:`sep`,value:e.slice(r,i.index)});let t=i[1];n.push({type:`field`,key:t,length:t===`yyyy`?4:2}),r=i.index+i[1].length}return r<e.length&&n.push({type:`sep`,value:e.slice(r)}),n}function c(e,t){return String(e).padStart(t,`0`)}var l={dd:`DD`,MM:`MM`,yyyy:`YYYY`},u={dd:`Day`,MM:`Month`,yyyy:`Year`},d={dd:``,MM:``,yyyy:``};function f(e){return!e||!a(e)?d:{dd:c(e.getDate(),2),MM:c(e.getMonth()+1,2),yyyy:c(e.getFullYear(),4)}}function p(e,t){let n=parseInt(e,10);if(!n||n<1||n>12)return 31;let r=t.length===4?parseInt(t,10):2e3;return o(new Date(r,n-1,1))}function m(e){if(e.dd.length!==2||e.MM.length!==2||e.yyyy.length!==4)return;let t=parseInt(e.dd,10),n=parseInt(e.MM,10),r=parseInt(e.yyyy,10),i=new Date(r,n-1,t);if(i.getFullYear()===r&&i.getMonth()===n-1&&i.getDate()===t)return i}function h({value:n,onChange:r,dateFormat:i=`dd/MM/yyyy`,disabled:o=!1,name:d,id:h,showDropdowns:g=!1,maxYear:_,yearRange:v=100,dropdownIcon:y,theme:b=`light`,outlined:x=!1,isPlainStyle:S=!1,classNames:C,styles:w,...T}){let E=_??new Date().getFullYear(),D=(0,e.useMemo)(()=>s(i),[i]),O=(0,e.useMemo)(()=>D.filter(e=>e.type===`field`).map(e=>e.key),[D]),[k,A]=(0,e.useState)(()=>f(n)),j=(0,e.useRef)({dd:null,MM:null,yyyy:null}),M=(0,e.useRef)(n&&a(n)?n.getTime():void 0),N=n&&a(n)?n.getTime():void 0;(0,e.useEffect)(()=>{N!==M.current&&(M.current=N,A(f(n)))},[N]);function P(e){let t=m(e);if(t){M.current=t.getTime(),r?.(t);return}M.current=void 0,r?.(void 0)}function F(e,t){let n=O[O.indexOf(e)+t];if(!n)return;let r=j.current[n];if(r)if(r.focus(),t===-1){let e=r.value.length;try{r.setSelectionRange(e,e)}catch{}}else try{r.setSelectionRange(0,r.value.length)}catch{}}function I(e,t,n){let r=t.replace(/\D/g,``).slice(0,n);A(t=>{let i={...t,[e]:r};if(r.length>0){let a=parseInt(r,10);if(r.length<n&&(e===`dd`&&parseInt(r[0],10)>3||e===`MM`&&parseInt(r[0],10)>1)||r.length===n&&(e===`dd`&&(a<1||a>p(i.MM,i.yyyy))||e===`MM`&&(a<1||a>12)||e===`yyyy`&&a<1))return t}return e!==`dd`&&i.dd.length===2&&parseInt(i.dd,10)>p(i.MM,i.yyyy)&&(i.dd=``),r.length===n&&queueMicrotask(()=>F(e,1)),P(i),i})}function L(e){if(e===`dd`){let e=p(k.MM,k.yyyy);return Array.from({length:e},(e,t)=>c(t+1,2))}return e===`MM`?Array.from({length:12},(e,t)=>c(t+1,2)):Array.from({length:v},(e,t)=>c(E-t,4))}function R(e,t,n){I(e,t,n)}function z(e,t){let n=t.currentTarget,r=n.selectionStart===0&&n.selectionEnd===0,i=n.selectionStart===n.value.length&&n.selectionEnd===n.value.length;if(t.key===`Backspace`&&n.value===``){t.preventDefault(),F(e,-1);return}if(t.key===`ArrowLeft`&&r){t.preventDefault(),F(e,-1);return}t.key===`ArrowRight`&&i&&(t.preventDefault(),F(e,1))}let B=S?{position:`relative`,display:`inline-flex`,alignItems:`center`,justifyContent:`center`,width:`1em`,height:`1em`,cursor:o?`not-allowed`:`pointer`,userSelect:`none`,lineHeight:1}:{position:`relative`},V={position:`absolute`,inset:0,width:`100%`,height:`100%`,opacity:0,cursor:o?`not-allowed`:`pointer`,appearance:`none`,WebkitAppearance:`none`,MozAppearance:`none`,border:0,padding:0,margin:0,background:`transparent`,color:`transparent`,fontSize:`inherit`},H=S?{display:`inline-flex`,alignItems:`center`}:void 0,U=(e,t)=>{let n=C?.[t];return e?n?`${e} ${n}`:e:n},W=(e,t)=>{let n=w?.[t];return e?n?{...e,...n}:e:n};return(0,t.jsx)(`span`,{role:`group`,"aria-label":T[`aria-label`]??`Date`,id:h,className:U(S?void 0:`rdp-root`,`root`),style:W(void 0,`root`),"data-theme":S?void 0:b,"data-outlined":S?void 0:x?`true`:`false`,"data-disabled":S?void 0:o?`true`:`false`,children:D.map((e,n)=>e.type===`sep`?(0,t.jsx)(`span`,{"aria-hidden":`true`,className:U(S?void 0:`rdp-sep`,`separator`),style:W(void 0,`separator`),children:e.value},`s${n}`):(0,t.jsxs)(`span`,{className:U(S?void 0:`rdp-segment`,`segment`),style:W(H,`segment`),children:[(0,t.jsx)(`input`,{ref:t=>{j.current[e.key]=t},type:`text`,inputMode:`numeric`,pattern:`[0-9]*`,autoComplete:`off`,disabled:o,name:d?`${d}-${e.key}`:void 0,maxLength:e.length,size:e.length,placeholder:l[e.key],"aria-label":u[e.key],className:U(S?void 0:`rdp-input`,`input`),style:W(void 0,`input`),value:k[e.key],"data-segment":e.key,onChange:t=>I(e.key,t.target.value,e.length),onKeyDown:t=>z(e.key,t),onFocus:e=>e.currentTarget.select()}),g&&(0,t.jsxs)(`span`,{className:U(S?void 0:`rdp-trigger`,`trigger`),style:W(B,`trigger`),children:[(0,t.jsx)(`span`,{"aria-hidden":`true`,className:U(void 0,`dropdownIcon`),style:W(void 0,`dropdownIcon`),children:typeof y==`function`?y(e.key):y??`▾`}),(0,t.jsxs)(`select`,{"aria-label":`Pick ${u[e.key]}`,disabled:o,className:U(S?void 0:`rdp-select`,`select`),value:k[e.key],onChange:t=>R(e.key,t.target.value,e.length),style:W(V,`select`),children:[(0,t.jsx)(`option`,{value:``,disabled:!0,hidden:!0,children:u[e.key]}),L(e.key).map(e=>(0,t.jsx)(`option`,{value:e,children:e},e))]})]})]},e.key))})}exports.DatePicker=h;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["toDate","toDate","toDate"],"sources":["../node_modules/date-fns/toDate.mjs","../node_modules/date-fns/constructFrom.mjs","../node_modules/date-fns/isDate.mjs","../node_modules/date-fns/isValid.mjs","../node_modules/date-fns/getDaysInMonth.mjs","../src/utils/format.ts","../src/utils/string.ts","../src/utils/constants.ts","../src/utils/time.ts","../src/DatePicker.tsx"],"sourcesContent":["/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param argument - The value to convert\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nexport function toDate(argument) {\n const argStr = Object.prototype.toString.call(argument);\n\n // Clone the date\n if (\n argument instanceof Date ||\n (typeof argument === \"object\" && argStr === \"[object Date]\")\n ) {\n // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n return new argument.constructor(+argument);\n } else if (\n typeof argument === \"number\" ||\n argStr === \"[object Number]\" ||\n typeof argument === \"string\" ||\n argStr === \"[object String]\"\n ) {\n // TODO: Can we get rid of as?\n return new Date(argument);\n } else {\n // TODO: Can we get rid of as?\n return new Date(NaN);\n }\n}\n\n// Fallback for modularized imports:\nexport default toDate;\n","/**\n * @name constructFrom\n * @category Generic Helpers\n * @summary Constructs a date using the reference date and the value\n *\n * @description\n * The function constructs a new date using the constructor from the reference\n * date and the given value. It helps to build generic functions that accept\n * date extensions.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The reference date to take constructor from\n * @param value - The value to create the date\n *\n * @returns Date initialized using the given date and value\n *\n * @example\n * import { constructFrom } from 'date-fns'\n *\n * // A function that clones a date preserving the original type\n * function cloneDate<DateType extends Date(date: DateType): DateType {\n * return constructFrom(\n * date, // Use contrustor from the given date\n * date.getTime() // Use the date value to create a new date\n * )\n * }\n */\nexport function constructFrom(date, value) {\n if (date instanceof Date) {\n return new date.constructor(value);\n } else {\n return new Date(value);\n }\n}\n\n// Fallback for modularized imports:\nexport default constructFrom;\n","/**\n * @name isDate\n * @category Common Helpers\n * @summary Is the given value a date?\n *\n * @description\n * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.\n *\n * @param value - The value to check\n *\n * @returns True if the given value is a date\n *\n * @example\n * // For a valid date:\n * const result = isDate(new Date())\n * //=> true\n *\n * @example\n * // For an invalid date:\n * const result = isDate(new Date(NaN))\n * //=> true\n *\n * @example\n * // For some value:\n * const result = isDate('2014-02-31')\n * //=> false\n *\n * @example\n * // For an object:\n * const result = isDate({})\n * //=> false\n */\nexport function isDate(value) {\n return (\n value instanceof Date ||\n (typeof value === \"object\" &&\n Object.prototype.toString.call(value) === \"[object Date]\")\n );\n}\n\n// Fallback for modularized imports:\nexport default isDate;\n","import { isDate } from \"./isDate.mjs\";\nimport { toDate } from \"./toDate.mjs\";\n\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate](https://date-fns.org/docs/toDate)\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The date to check\n *\n * @returns The date is valid\n *\n * @example\n * // For the valid date:\n * const result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertable into a date:\n * const result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * const result = isValid(new Date(''))\n * //=> false\n */\nexport function isValid(date) {\n if (!isDate(date) && typeof date !== \"number\") {\n return false;\n }\n const _date = toDate(date);\n return !isNaN(Number(_date));\n}\n\n// Fallback for modularized imports:\nexport default isValid;\n","import { toDate } from \"./toDate.mjs\";\nimport { constructFrom } from \"./constructFrom.mjs\";\n\n/**\n * @name getDaysInMonth\n * @category Month Helpers\n * @summary Get the number of days in a month of the given date.\n *\n * @description\n * Get the number of days in a month of the given date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The given date\n *\n * @returns The number of days in a month\n *\n * @example\n * // How many days are in February 2000?\n * const result = getDaysInMonth(new Date(2000, 1))\n * //=> 29\n */\nexport function getDaysInMonth(date) {\n const _date = toDate(date);\n const year = _date.getFullYear();\n const monthIndex = _date.getMonth();\n const lastDayOfMonth = constructFrom(date, 0);\n lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);\n lastDayOfMonth.setHours(0, 0, 0, 0);\n return lastDayOfMonth.getDate();\n}\n\n// Fallback for modularized imports:\nexport default getDaysInMonth;\n","import type { SegmentKey, Token } from '../types'\n\n/**\n * Parse a date format string (e.g. `dd/MM/yyyy`) into an ordered list of\n * field and separator tokens. Recognized field tokens: `dd`, `MM`, `yyyy`.\n */\nexport function parseFormat(format: string): Token[] {\n const re = /(dd|MM|yyyy)/g\n const tokens: Token[] = []\n let last = 0\n let m: RegExpExecArray | null\n while ((m = re.exec(format)) !== null) {\n if (m.index > last) {\n tokens.push({ type: 'sep', value: format.slice(last, m.index) })\n }\n const key = m[1] as SegmentKey\n tokens.push({ type: 'field', key, length: key === 'yyyy' ? 4 : 2 })\n last = m.index + m[1].length\n }\n if (last < format.length) {\n tokens.push({ type: 'sep', value: format.slice(last) })\n }\n return tokens\n}\n","/** Left-pad a number to the given length with leading zeroes. */\nexport function pad(n: number, len: number): string {\n return String(n).padStart(len, '0')\n}\n","import type { SegmentKey, Values } from '../types'\n\nexport const PLACEHOLDER: Record<SegmentKey, string> = {\n dd: 'DD',\n MM: 'MM',\n yyyy: 'YYYY',\n}\n\nexport const LABEL: Record<SegmentKey, string> = {\n dd: 'Day',\n MM: 'Month',\n yyyy: 'Year',\n}\n\nexport const EMPTY: Values = { dd: '', MM: '', yyyy: '' }\n","import { getDaysInMonth, isValid } from 'date-fns'\nimport { pad } from './string'\nimport { EMPTY } from './constants'\nimport type { Values } from '../types'\n\n/** Build segment values from a `Date`. Returns empty values for invalid input. */\nexport function fromDate(date: Date | undefined): Values {\n if (!date || !isValid(date)) return EMPTY\n return {\n dd: pad(date.getDate(), 2),\n MM: pad(date.getMonth() + 1, 2),\n yyyy: pad(date.getFullYear(), 4),\n }\n}\n\n/**\n * Maximum allowed day for a given month/year segment context.\n * Falls back to a leap-safe year (2000) when the year is unknown so that\n * Feb 29 is initially permitted and re-validated once the year is provided.\n */\nexport function maxDay(monthStr: string, yearStr: string): number {\n const m = parseInt(monthStr, 10)\n if (!m || m < 1 || m > 12) return 31\n const y = yearStr.length === 4 ? parseInt(yearStr, 10) : 2000\n return getDaysInMonth(new Date(y, m - 1, 1))\n}\n\n/**\n * Build a `Date` from segment values if and only if they form a valid\n * calendar date. Returns `undefined` for partial or invalid values\n * (e.g. 31/02/2024).\n */\nexport function toDate(values: Values): Date | undefined {\n if (values.dd.length !== 2 || values.MM.length !== 2 || values.yyyy.length !== 4) {\n return undefined\n }\n const d = parseInt(values.dd, 10)\n const m = parseInt(values.MM, 10)\n const y = parseInt(values.yyyy, 10)\n const date = new Date(y, m - 1, d)\n if (\n date.getFullYear() === y &&\n date.getMonth() === m - 1 &&\n date.getDate() === d\n ) {\n return date\n }\n return undefined\n}\n","import { isValid } from 'date-fns'\nimport {\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { parseFormat } from './utils/format'\nimport { pad } from './utils/string'\nimport { fromDate, maxDay, toDate } from './utils/time'\nimport { LABEL, PLACEHOLDER } from './utils/constants'\nimport type { SegmentKey, Token, Values } from './types'\n\nexport interface DatePickerProps {\n value?: Date\n onChange?: (date: Date | undefined) => void\n /** Format using `dd`, `MM`, `yyyy` tokens. Defaults to `dd/MM/yyyy`. */\n dateFormat?: string\n disabled?: boolean\n name?: string\n id?: string\n 'aria-label'?: string\n /** When true, render a native `<select>` dropdown next to each segment. */\n showDropdowns?: boolean\n /** Latest selectable year in the year dropdown. Defaults to the current year. */\n maxYear?: number\n /** How many years to include in the year dropdown (descending from `maxYear`). Defaults to 100. */\n yearRange?: number\n /**\n * Custom dropdown trigger icon. Either a single node used for every segment,\n * or a render function that receives the segment key. Defaults to a chevron.\n * Only used when `showDropdowns` is true.\n */\n dropdownIcon?: ReactNode | ((segment: SegmentKey) => ReactNode)\n /** Color theme. Defaults to `'light'`. Ignored when `isPlainStyle` is true. */\n theme?: 'light' | 'dark'\n /** When true, draw a single border around the whole component. Defaults to false. */\n outlined?: boolean\n /** When true, no styles or class names are applied. Use this if you want to style from scratch. */\n isPlainStyle?: boolean\n /** Per-slot class names. Merged after the built-in `rdp-*` classes (or used alone in plain mode). */\n classNames?: Partial<Record<StyleSlot, string>>\n /** Per-slot inline styles. Merged on top of the component's own inline styles. */\n styles?: Partial<Record<StyleSlot, CSSProperties>>\n}\n\n/** Style slots a consumer can target via `classNames` / `styles` props. */\nexport type StyleSlot =\n | 'root'\n | 'segment'\n | 'input'\n | 'separator'\n | 'trigger'\n | 'dropdownIcon'\n | 'select'\n\nexport function DatePicker({\n value,\n onChange,\n dateFormat = 'dd/MM/yyyy',\n disabled = false,\n name,\n id,\n showDropdowns = false,\n maxYear,\n yearRange = 100,\n dropdownIcon,\n theme = 'light',\n outlined = false,\n isPlainStyle = false,\n classNames,\n styles: slotStyles,\n ...rest\n}: DatePickerProps) {\n const resolvedMaxYear = maxYear ?? new Date().getFullYear()\n const tokens = useMemo(() => parseFormat(dateFormat), [dateFormat])\n const fieldKeys = useMemo(\n () =>\n tokens\n .filter((t): t is Extract<Token, { type: 'field' }> => t.type === 'field')\n .map((t) => t.key),\n [tokens],\n )\n\n const [values, setValues] = useState<Values>(() => fromDate(value))\n const refs = useRef<Record<SegmentKey, HTMLInputElement | null>>({\n dd: null,\n MM: null,\n yyyy: null,\n })\n\n // Tracks the last value we emitted to the parent. Used to ignore the\n // controlled-parent's echo (which would otherwise overwrite an in-progress\n // partial edit, e.g. clearing one digit of the year).\n const lastEmittedTime = useRef<number | undefined>(\n value && isValid(value) ? value.getTime() : undefined,\n )\n\n // Sync from external value changes only when the incoming value is\n // genuinely different from what this component last emitted.\n const valueTime = value && isValid(value) ? value.getTime() : undefined\n useEffect(() => {\n if (valueTime === lastEmittedTime.current) return\n lastEmittedTime.current = valueTime\n setValues(fromDate(value))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [valueTime])\n\n function emit(next: Values) {\n const date = toDate(next)\n if (date) {\n lastEmittedTime.current = date.getTime()\n onChange?.(date)\n return\n }\n lastEmittedTime.current = undefined\n onChange?.(undefined)\n }\n\n function focusSibling(current: SegmentKey, dir: 1 | -1) {\n const idx = fieldKeys.indexOf(current)\n const target = fieldKeys[idx + dir]\n if (!target) return\n const el = refs.current[target]\n if (!el) return\n el.focus()\n if (dir === -1) {\n const len = el.value.length\n try {\n el.setSelectionRange(len, len)\n } catch {\n /* some input types don't support selection */\n }\n } else {\n try {\n el.setSelectionRange(0, el.value.length)\n } catch {\n /* noop */\n }\n }\n }\n\n function handleChange(key: SegmentKey, raw: string, maxLen: number) {\n // Strip non-digits and clamp length\n const digits = raw.replace(/\\D/g, '').slice(0, maxLen)\n\n setValues((prev) => {\n const next: Values = { ...prev, [key]: digits }\n\n if (digits.length > 0) {\n const num = parseInt(digits, 10)\n\n // Reject impossible first digits (so user can't even type 4-9 as first dd digit, etc.)\n if (digits.length < maxLen) {\n if (key === 'dd' && parseInt(digits[0]!, 10) > 3) return prev\n if (key === 'MM' && parseInt(digits[0]!, 10) > 1) return prev\n }\n\n // Reject full segments that exceed allowed range\n if (digits.length === maxLen) {\n if (key === 'dd' && (num < 1 || num > maxDay(next.MM, next.yyyy))) return prev\n if (key === 'MM' && (num < 1 || num > 12)) return prev\n if (key === 'yyyy' && num < 1) return prev\n }\n }\n\n // If month or year changed, ensure existing day is still valid; clear it otherwise.\n if (key !== 'dd' && next.dd.length === 2) {\n const dnum = parseInt(next.dd, 10)\n if (dnum > maxDay(next.MM, next.yyyy)) next.dd = ''\n }\n\n // Auto-advance once segment is full\n if (digits.length === maxLen) {\n queueMicrotask(() => focusSibling(key, 1))\n }\n\n emit(next)\n return next\n })\n }\n\n function getOptions(key: SegmentKey): string[] {\n if (key === 'dd') {\n const max = maxDay(values.MM, values.yyyy)\n return Array.from({ length: max }, (_, i) => pad(i + 1, 2))\n }\n if (key === 'MM') {\n return Array.from({ length: 12 }, (_, i) => pad(i + 1, 2))\n }\n // yyyy: descending from resolvedMaxYear\n return Array.from({ length: yearRange }, (_, i) => pad(resolvedMaxYear - i, 4))\n }\n\n function handleSelect(key: SegmentKey, raw: string, maxLen: 2 | 4) {\n // Route through handleChange so all validation + day re-check + emit happens.\n handleChange(key, raw, maxLen)\n }\n\n function handleKeyDown(key: SegmentKey, e: KeyboardEvent<HTMLInputElement>) {\n const target = e.currentTarget\n const atStart = target.selectionStart === 0 && target.selectionEnd === 0\n const atEnd =\n target.selectionStart === target.value.length &&\n target.selectionEnd === target.value.length\n\n if (e.key === 'Backspace' && target.value === '') {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowLeft' && atStart) {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowRight' && atEnd) {\n e.preventDefault()\n focusSibling(key, 1)\n }\n }\n\n // Inline styles only used in plain mode. The CSS file (when not plain)\n // handles layout via .rdp-* classes; the absolute positioning of the\n // invisible <select> over the icon is functional, not cosmetic, so it\n // must always be applied.\n const triggerStyle = isPlainStyle\n ? {\n position: 'relative' as const,\n display: 'inline-flex' as const,\n alignItems: 'center' as const,\n justifyContent: 'center' as const,\n width: '1em',\n height: '1em',\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n userSelect: 'none' as const,\n lineHeight: 1,\n }\n : { position: 'relative' as const }\n\n const selectStyle = {\n position: 'absolute' as const,\n inset: 0,\n width: '100%',\n height: '100%',\n opacity: 0,\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n appearance: 'none' as const,\n WebkitAppearance: 'none' as const,\n MozAppearance: 'none' as const,\n border: 0,\n padding: 0,\n margin: 0,\n background: 'transparent',\n color: 'transparent',\n fontSize: 'inherit',\n }\n\n const segmentStyle = isPlainStyle\n ? { display: 'inline-flex' as const, alignItems: 'center' as const }\n : undefined\n\n // Helper: combine the built-in class for a slot with any consumer-provided class.\n const cn = (builtin: string | undefined, slot: StyleSlot) => {\n const extra = classNames?.[slot]\n if (!builtin) return extra\n return extra ? `${builtin} ${extra}` : builtin\n }\n\n // Helper: merge built-in inline style with consumer slot style (consumer wins).\n const mergeStyle = (\n base: CSSProperties | undefined,\n slot: StyleSlot,\n ): CSSProperties | undefined => {\n const extra = slotStyles?.[slot]\n if (!base) return extra\n if (!extra) return base\n return { ...base, ...extra }\n }\n\n return (\n <span\n role=\"group\"\n aria-label={rest['aria-label'] ?? 'Date'}\n id={id}\n className={cn(isPlainStyle ? undefined : 'rdp-root', 'root')}\n style={mergeStyle(undefined, 'root')}\n data-theme={isPlainStyle ? undefined : theme}\n data-outlined={isPlainStyle ? undefined : outlined ? 'true' : 'false'}\n data-disabled={isPlainStyle ? undefined : disabled ? 'true' : 'false'}\n >\n {tokens.map((t, i) => {\n if (t.type === 'sep') {\n return (\n <span\n key={`s${i}`}\n aria-hidden=\"true\"\n className={cn(isPlainStyle ? undefined : 'rdp-sep', 'separator')}\n style={mergeStyle(undefined, 'separator')}\n >\n {t.value}\n </span>\n )\n }\n return (\n <span\n key={t.key}\n className={cn(isPlainStyle ? undefined : 'rdp-segment', 'segment')}\n style={mergeStyle(segmentStyle, 'segment')}\n >\n <input\n ref={(el) => {\n refs.current[t.key] = el\n }}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n autoComplete=\"off\"\n disabled={disabled}\n name={name ? `${name}-${t.key}` : undefined}\n maxLength={t.length}\n size={t.length}\n placeholder={PLACEHOLDER[t.key]}\n aria-label={LABEL[t.key]}\n className={cn(isPlainStyle ? undefined : 'rdp-input', 'input')}\n style={mergeStyle(undefined, 'input')}\n value={values[t.key]}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n handleChange(t.key, e.target.value, t.length)\n }\n onKeyDown={(e) => handleKeyDown(t.key, e)}\n onFocus={(e) => e.currentTarget.select()}\n />\n {showDropdowns && (\n <span\n className={cn(isPlainStyle ? undefined : 'rdp-trigger', 'trigger')}\n style={mergeStyle(triggerStyle, 'trigger')}\n >\n <span\n aria-hidden=\"true\"\n className={cn(undefined, 'dropdownIcon')}\n style={mergeStyle(undefined, 'dropdownIcon')}\n >\n {typeof dropdownIcon === 'function'\n ? dropdownIcon(t.key)\n : (dropdownIcon ?? '▾')}\n </span>\n <select\n aria-label={`Pick ${LABEL[t.key]}`}\n disabled={disabled}\n className={cn(isPlainStyle ? undefined : 'rdp-select', 'select')}\n value={values[t.key]}\n onChange={(e) => handleSelect(t.key, e.target.value, t.length)}\n style={mergeStyle(selectStyle, 'select')}\n >\n <option value=\"\" disabled hidden>\n {LABEL[t.key]}\n </option>\n {getOptions(t.key).map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n </span>\n )}\n </span>\n )\n })}\n </span>\n )\n}\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["toDate","toDate","toDate"],"sources":["../node_modules/date-fns/toDate.mjs","../node_modules/date-fns/constructFrom.mjs","../node_modules/date-fns/isDate.mjs","../node_modules/date-fns/isValid.mjs","../node_modules/date-fns/getDaysInMonth.mjs","../src/utils/format.ts","../src/utils/string.ts","../src/utils/constants.ts","../src/utils/time.ts","../src/DatePicker.tsx"],"sourcesContent":["/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param argument - The value to convert\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nexport function toDate(argument) {\n const argStr = Object.prototype.toString.call(argument);\n\n // Clone the date\n if (\n argument instanceof Date ||\n (typeof argument === \"object\" && argStr === \"[object Date]\")\n ) {\n // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n return new argument.constructor(+argument);\n } else if (\n typeof argument === \"number\" ||\n argStr === \"[object Number]\" ||\n typeof argument === \"string\" ||\n argStr === \"[object String]\"\n ) {\n // TODO: Can we get rid of as?\n return new Date(argument);\n } else {\n // TODO: Can we get rid of as?\n return new Date(NaN);\n }\n}\n\n// Fallback for modularized imports:\nexport default toDate;\n","/**\n * @name constructFrom\n * @category Generic Helpers\n * @summary Constructs a date using the reference date and the value\n *\n * @description\n * The function constructs a new date using the constructor from the reference\n * date and the given value. It helps to build generic functions that accept\n * date extensions.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The reference date to take constructor from\n * @param value - The value to create the date\n *\n * @returns Date initialized using the given date and value\n *\n * @example\n * import { constructFrom } from 'date-fns'\n *\n * // A function that clones a date preserving the original type\n * function cloneDate<DateType extends Date(date: DateType): DateType {\n * return constructFrom(\n * date, // Use contrustor from the given date\n * date.getTime() // Use the date value to create a new date\n * )\n * }\n */\nexport function constructFrom(date, value) {\n if (date instanceof Date) {\n return new date.constructor(value);\n } else {\n return new Date(value);\n }\n}\n\n// Fallback for modularized imports:\nexport default constructFrom;\n","/**\n * @name isDate\n * @category Common Helpers\n * @summary Is the given value a date?\n *\n * @description\n * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.\n *\n * @param value - The value to check\n *\n * @returns True if the given value is a date\n *\n * @example\n * // For a valid date:\n * const result = isDate(new Date())\n * //=> true\n *\n * @example\n * // For an invalid date:\n * const result = isDate(new Date(NaN))\n * //=> true\n *\n * @example\n * // For some value:\n * const result = isDate('2014-02-31')\n * //=> false\n *\n * @example\n * // For an object:\n * const result = isDate({})\n * //=> false\n */\nexport function isDate(value) {\n return (\n value instanceof Date ||\n (typeof value === \"object\" &&\n Object.prototype.toString.call(value) === \"[object Date]\")\n );\n}\n\n// Fallback for modularized imports:\nexport default isDate;\n","import { isDate } from \"./isDate.mjs\";\nimport { toDate } from \"./toDate.mjs\";\n\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate](https://date-fns.org/docs/toDate)\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The date to check\n *\n * @returns The date is valid\n *\n * @example\n * // For the valid date:\n * const result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertable into a date:\n * const result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * const result = isValid(new Date(''))\n * //=> false\n */\nexport function isValid(date) {\n if (!isDate(date) && typeof date !== \"number\") {\n return false;\n }\n const _date = toDate(date);\n return !isNaN(Number(_date));\n}\n\n// Fallback for modularized imports:\nexport default isValid;\n","import { toDate } from \"./toDate.mjs\";\nimport { constructFrom } from \"./constructFrom.mjs\";\n\n/**\n * @name getDaysInMonth\n * @category Month Helpers\n * @summary Get the number of days in a month of the given date.\n *\n * @description\n * Get the number of days in a month of the given date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The given date\n *\n * @returns The number of days in a month\n *\n * @example\n * // How many days are in February 2000?\n * const result = getDaysInMonth(new Date(2000, 1))\n * //=> 29\n */\nexport function getDaysInMonth(date) {\n const _date = toDate(date);\n const year = _date.getFullYear();\n const monthIndex = _date.getMonth();\n const lastDayOfMonth = constructFrom(date, 0);\n lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);\n lastDayOfMonth.setHours(0, 0, 0, 0);\n return lastDayOfMonth.getDate();\n}\n\n// Fallback for modularized imports:\nexport default getDaysInMonth;\n","import type { SegmentKey, Token } from '../types'\n\n/**\n * Parse a date format string (e.g. `dd/MM/yyyy`) into an ordered list of\n * field and separator tokens. Recognized field tokens: `dd`, `MM`, `yyyy`.\n */\nexport function parseFormat(format: string): Token[] {\n const re = /(dd|MM|yyyy)/g\n const tokens: Token[] = []\n let last = 0\n let m: RegExpExecArray | null\n while ((m = re.exec(format)) !== null) {\n if (m.index > last) {\n tokens.push({ type: 'sep', value: format.slice(last, m.index) })\n }\n const key = m[1] as SegmentKey\n tokens.push({ type: 'field', key, length: key === 'yyyy' ? 4 : 2 })\n last = m.index + m[1].length\n }\n if (last < format.length) {\n tokens.push({ type: 'sep', value: format.slice(last) })\n }\n return tokens\n}\n","/** Left-pad a number to the given length with leading zeroes. */\nexport function pad(n: number, len: number): string {\n return String(n).padStart(len, '0')\n}\n","import type { SegmentKey, Values } from '../types'\n\nexport const PLACEHOLDER: Record<SegmentKey, string> = {\n dd: 'DD',\n MM: 'MM',\n yyyy: 'YYYY',\n}\n\nexport const LABEL: Record<SegmentKey, string> = {\n dd: 'Day',\n MM: 'Month',\n yyyy: 'Year',\n}\n\nexport const EMPTY: Values = { dd: '', MM: '', yyyy: '' }\n","import { getDaysInMonth, isValid } from 'date-fns'\nimport { pad } from './string'\nimport { EMPTY } from './constants'\nimport type { Values } from '../types'\n\n/** Build segment values from a `Date`. Returns empty values for invalid input. */\nexport function fromDate(date: Date | undefined): Values {\n if (!date || !isValid(date)) return EMPTY\n return {\n dd: pad(date.getDate(), 2),\n MM: pad(date.getMonth() + 1, 2),\n yyyy: pad(date.getFullYear(), 4),\n }\n}\n\n/**\n * Maximum allowed day for a given month/year segment context.\n * Falls back to a leap-safe year (2000) when the year is unknown so that\n * Feb 29 is initially permitted and re-validated once the year is provided.\n */\nexport function maxDay(monthStr: string, yearStr: string): number {\n const m = parseInt(monthStr, 10)\n if (!m || m < 1 || m > 12) return 31\n const y = yearStr.length === 4 ? parseInt(yearStr, 10) : 2000\n return getDaysInMonth(new Date(y, m - 1, 1))\n}\n\n/**\n * Build a `Date` from segment values if and only if they form a valid\n * calendar date. Returns `undefined` for partial or invalid values\n * (e.g. 31/02/2024).\n */\nexport function toDate(values: Values): Date | undefined {\n if (values.dd.length !== 2 || values.MM.length !== 2 || values.yyyy.length !== 4) {\n return undefined\n }\n const d = parseInt(values.dd, 10)\n const m = parseInt(values.MM, 10)\n const y = parseInt(values.yyyy, 10)\n const date = new Date(y, m - 1, d)\n if (\n date.getFullYear() === y &&\n date.getMonth() === m - 1 &&\n date.getDate() === d\n ) {\n return date\n }\n return undefined\n}\n","import { isValid } from 'date-fns'\nimport {\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { parseFormat } from './utils/format'\nimport { pad } from './utils/string'\nimport { fromDate, maxDay, toDate } from './utils/time'\nimport { LABEL, PLACEHOLDER } from './utils/constants'\nimport type { SegmentKey, Token, Values } from './types'\n\nexport interface DatePickerProps {\n value?: Date\n onChange?: (date: Date | undefined) => void\n /** Format using `dd`, `MM`, `yyyy` tokens. Defaults to `dd/MM/yyyy`. */\n dateFormat?: string\n disabled?: boolean\n name?: string\n id?: string\n 'aria-label'?: string\n /** When true, render a native `<select>` dropdown next to each segment. */\n showDropdowns?: boolean\n /** Latest selectable year in the year dropdown. Defaults to the current year. */\n maxYear?: number\n /** How many years to include in the year dropdown (descending from `maxYear`). Defaults to 100. */\n yearRange?: number\n /**\n * Custom dropdown trigger icon. Either a single node used for every segment,\n * or a render function that receives the segment key. Defaults to a chevron.\n * Only used when `showDropdowns` is true.\n */\n dropdownIcon?: ReactNode | ((segment: SegmentKey) => ReactNode)\n /** Color theme. Defaults to `'light'`. Ignored when `isPlainStyle` is true. */\n theme?: 'light' | 'dark'\n /** When true, draw a single border around the whole component. Defaults to false. */\n outlined?: boolean\n /** When true, no styles or class names are applied. Use this if you want to style from scratch. */\n isPlainStyle?: boolean\n /** Per-slot class names. Merged after the built-in `rdp-*` classes (or used alone in plain mode). */\n classNames?: Partial<Record<StyleSlot, string>>\n /** Per-slot inline styles. Merged on top of the component's own inline styles. */\n styles?: Partial<Record<StyleSlot, CSSProperties>>\n}\n\n/** Style slots a consumer can target via `classNames` / `styles` props. */\nexport type StyleSlot =\n | 'root'\n | 'segment'\n | 'input'\n | 'separator'\n | 'trigger'\n | 'dropdownIcon'\n | 'select'\n\nexport function DatePicker({\n value,\n onChange,\n dateFormat = 'dd/MM/yyyy',\n disabled = false,\n name,\n id,\n showDropdowns = false,\n maxYear,\n yearRange = 100,\n dropdownIcon,\n theme = 'light',\n outlined = false,\n isPlainStyle = false,\n classNames,\n styles: slotStyles,\n ...rest\n}: DatePickerProps) {\n const resolvedMaxYear = maxYear ?? new Date().getFullYear()\n const tokens = useMemo(() => parseFormat(dateFormat), [dateFormat])\n const fieldKeys = useMemo(\n () =>\n tokens\n .filter((t): t is Extract<Token, { type: 'field' }> => t.type === 'field')\n .map((t) => t.key),\n [tokens],\n )\n\n const [values, setValues] = useState<Values>(() => fromDate(value))\n const refs = useRef<Record<SegmentKey, HTMLInputElement | null>>({\n dd: null,\n MM: null,\n yyyy: null,\n })\n\n // Tracks the last value we emitted to the parent. Used to ignore the\n // controlled-parent's echo (which would otherwise overwrite an in-progress\n // partial edit, e.g. clearing one digit of the year).\n const lastEmittedTime = useRef<number | undefined>(\n value && isValid(value) ? value.getTime() : undefined,\n )\n\n // Sync from external value changes only when the incoming value is\n // genuinely different from what this component last emitted.\n const valueTime = value && isValid(value) ? value.getTime() : undefined\n useEffect(() => {\n if (valueTime === lastEmittedTime.current) return\n lastEmittedTime.current = valueTime\n setValues(fromDate(value))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [valueTime])\n\n function emit(next: Values) {\n const date = toDate(next)\n if (date) {\n lastEmittedTime.current = date.getTime()\n onChange?.(date)\n return\n }\n lastEmittedTime.current = undefined\n onChange?.(undefined)\n }\n\n function focusSibling(current: SegmentKey, dir: 1 | -1) {\n const idx = fieldKeys.indexOf(current)\n const target = fieldKeys[idx + dir]\n if (!target) return\n const el = refs.current[target]\n if (!el) return\n el.focus()\n if (dir === -1) {\n const len = el.value.length\n try {\n el.setSelectionRange(len, len)\n } catch {\n /* some input types don't support selection */\n }\n } else {\n try {\n el.setSelectionRange(0, el.value.length)\n } catch {\n /* noop */\n }\n }\n }\n\n function handleChange(key: SegmentKey, raw: string, maxLen: number) {\n // Strip non-digits and clamp length\n const digits = raw.replace(/\\D/g, '').slice(0, maxLen)\n\n setValues((prev) => {\n const next: Values = { ...prev, [key]: digits }\n\n if (digits.length > 0) {\n const num = parseInt(digits, 10)\n\n // Reject impossible first digits (so user can't even type 4-9 as first dd digit, etc.)\n if (digits.length < maxLen) {\n if (key === 'dd' && parseInt(digits[0]!, 10) > 3) return prev\n if (key === 'MM' && parseInt(digits[0]!, 10) > 1) return prev\n }\n\n // Reject full segments that exceed allowed range\n if (digits.length === maxLen) {\n if (key === 'dd' && (num < 1 || num > maxDay(next.MM, next.yyyy))) return prev\n if (key === 'MM' && (num < 1 || num > 12)) return prev\n if (key === 'yyyy' && num < 1) return prev\n }\n }\n\n // If month or year changed, ensure existing day is still valid; clear it otherwise.\n if (key !== 'dd' && next.dd.length === 2) {\n const dnum = parseInt(next.dd, 10)\n if (dnum > maxDay(next.MM, next.yyyy)) next.dd = ''\n }\n\n // Auto-advance once segment is full\n if (digits.length === maxLen) {\n queueMicrotask(() => focusSibling(key, 1))\n }\n\n emit(next)\n return next\n })\n }\n\n function getOptions(key: SegmentKey): string[] {\n if (key === 'dd') {\n const max = maxDay(values.MM, values.yyyy)\n return Array.from({ length: max }, (_, i) => pad(i + 1, 2))\n }\n if (key === 'MM') {\n return Array.from({ length: 12 }, (_, i) => pad(i + 1, 2))\n }\n // yyyy: descending from resolvedMaxYear\n return Array.from({ length: yearRange }, (_, i) => pad(resolvedMaxYear - i, 4))\n }\n\n function handleSelect(key: SegmentKey, raw: string, maxLen: 2 | 4) {\n // Route through handleChange so all validation + day re-check + emit happens.\n handleChange(key, raw, maxLen)\n }\n\n function handleKeyDown(key: SegmentKey, e: KeyboardEvent<HTMLInputElement>) {\n const target = e.currentTarget\n const atStart = target.selectionStart === 0 && target.selectionEnd === 0\n const atEnd =\n target.selectionStart === target.value.length &&\n target.selectionEnd === target.value.length\n\n if (e.key === 'Backspace' && target.value === '') {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowLeft' && atStart) {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowRight' && atEnd) {\n e.preventDefault()\n focusSibling(key, 1)\n }\n }\n\n // Inline styles only used in plain mode. The CSS file (when not plain)\n // handles layout via .rdp-* classes; the absolute positioning of the\n // invisible <select> over the icon is functional, not cosmetic, so it\n // must always be applied.\n const triggerStyle = isPlainStyle\n ? {\n position: 'relative' as const,\n display: 'inline-flex' as const,\n alignItems: 'center' as const,\n justifyContent: 'center' as const,\n width: '1em',\n height: '1em',\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n userSelect: 'none' as const,\n lineHeight: 1,\n }\n : { position: 'relative' as const }\n\n const selectStyle = {\n position: 'absolute' as const,\n inset: 0,\n width: '100%',\n height: '100%',\n opacity: 0,\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n appearance: 'none' as const,\n WebkitAppearance: 'none' as const,\n MozAppearance: 'none' as const,\n border: 0,\n padding: 0,\n margin: 0,\n background: 'transparent',\n color: 'transparent',\n fontSize: 'inherit',\n }\n\n const segmentStyle = isPlainStyle\n ? { display: 'inline-flex' as const, alignItems: 'center' as const }\n : undefined\n\n // Helper: combine the built-in class for a slot with any consumer-provided class.\n const cn = (builtin: string | undefined, slot: StyleSlot) => {\n const extra = classNames?.[slot]\n if (!builtin) return extra\n return extra ? `${builtin} ${extra}` : builtin\n }\n\n // Helper: merge built-in inline style with consumer slot style (consumer wins).\n const mergeStyle = (\n base: CSSProperties | undefined,\n slot: StyleSlot,\n ): CSSProperties | undefined => {\n const extra = slotStyles?.[slot]\n if (!base) return extra\n if (!extra) return base\n return { ...base, ...extra }\n }\n\n return (\n <span\n role=\"group\"\n aria-label={rest['aria-label'] ?? 'Date'}\n id={id}\n className={cn(isPlainStyle ? undefined : 'rdp-root', 'root')}\n style={mergeStyle(undefined, 'root')}\n data-theme={isPlainStyle ? undefined : theme}\n data-outlined={isPlainStyle ? undefined : outlined ? 'true' : 'false'}\n data-disabled={isPlainStyle ? undefined : disabled ? 'true' : 'false'}\n >\n {tokens.map((t, i) => {\n if (t.type === 'sep') {\n return (\n <span\n key={`s${i}`}\n aria-hidden=\"true\"\n className={cn(isPlainStyle ? undefined : 'rdp-sep', 'separator')}\n style={mergeStyle(undefined, 'separator')}\n >\n {t.value}\n </span>\n )\n }\n return (\n <span\n key={t.key}\n className={cn(isPlainStyle ? undefined : 'rdp-segment', 'segment')}\n style={mergeStyle(segmentStyle, 'segment')}\n >\n <input\n ref={(el) => {\n refs.current[t.key] = el\n }}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n autoComplete=\"off\"\n disabled={disabled}\n name={name ? `${name}-${t.key}` : undefined}\n maxLength={t.length}\n size={t.length}\n placeholder={PLACEHOLDER[t.key]}\n aria-label={LABEL[t.key]}\n className={cn(isPlainStyle ? undefined : 'rdp-input', 'input')}\n style={mergeStyle(undefined, 'input')}\n value={values[t.key]}\n data-segment={t.key}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n handleChange(t.key, e.target.value, t.length)\n }\n onKeyDown={(e) => handleKeyDown(t.key, e)}\n onFocus={(e) => e.currentTarget.select()}\n />\n {showDropdowns && (\n <span\n className={cn(isPlainStyle ? undefined : 'rdp-trigger', 'trigger')}\n style={mergeStyle(triggerStyle, 'trigger')}\n >\n <span\n aria-hidden=\"true\"\n className={cn(undefined, 'dropdownIcon')}\n style={mergeStyle(undefined, 'dropdownIcon')}\n >\n {typeof dropdownIcon === 'function'\n ? dropdownIcon(t.key)\n : (dropdownIcon ?? '▾')}\n </span>\n <select\n aria-label={`Pick ${LABEL[t.key]}`}\n disabled={disabled}\n className={cn(isPlainStyle ? undefined : 'rdp-select', 'select')}\n value={values[t.key]}\n onChange={(e) => handleSelect(t.key, e.target.value, t.length)}\n style={mergeStyle(selectStyle, 'select')}\n >\n <option value=\"\" disabled hidden>\n {LABEL[t.key]}\n </option>\n {getOptions(t.key).map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n </span>\n )}\n </span>\n )\n })}\n </span>\n )\n}\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -230,6 +230,7 @@ function y({ value: o, onChange: s, dateFormat: c = "dd/MM/yyyy", disabled: u =
|
|
|
230
230
|
className: q(E ? void 0 : "rdp-input", "input"),
|
|
231
231
|
style: J(void 0, "input"),
|
|
232
232
|
value: N[e.key],
|
|
233
|
+
"data-segment": e.key,
|
|
233
234
|
onChange: (t) => B(e.key, t.target.value, e.length),
|
|
234
235
|
onKeyDown: (t) => U(e.key, t),
|
|
235
236
|
onFocus: (e) => e.currentTarget.select()
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["toDate","toDate","toDate"],"sources":["../node_modules/date-fns/toDate.mjs","../node_modules/date-fns/constructFrom.mjs","../node_modules/date-fns/isDate.mjs","../node_modules/date-fns/isValid.mjs","../node_modules/date-fns/getDaysInMonth.mjs","../src/utils/format.ts","../src/utils/string.ts","../src/utils/constants.ts","../src/utils/time.ts","../src/DatePicker.tsx"],"sourcesContent":["/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param argument - The value to convert\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nexport function toDate(argument) {\n const argStr = Object.prototype.toString.call(argument);\n\n // Clone the date\n if (\n argument instanceof Date ||\n (typeof argument === \"object\" && argStr === \"[object Date]\")\n ) {\n // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n return new argument.constructor(+argument);\n } else if (\n typeof argument === \"number\" ||\n argStr === \"[object Number]\" ||\n typeof argument === \"string\" ||\n argStr === \"[object String]\"\n ) {\n // TODO: Can we get rid of as?\n return new Date(argument);\n } else {\n // TODO: Can we get rid of as?\n return new Date(NaN);\n }\n}\n\n// Fallback for modularized imports:\nexport default toDate;\n","/**\n * @name constructFrom\n * @category Generic Helpers\n * @summary Constructs a date using the reference date and the value\n *\n * @description\n * The function constructs a new date using the constructor from the reference\n * date and the given value. It helps to build generic functions that accept\n * date extensions.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The reference date to take constructor from\n * @param value - The value to create the date\n *\n * @returns Date initialized using the given date and value\n *\n * @example\n * import { constructFrom } from 'date-fns'\n *\n * // A function that clones a date preserving the original type\n * function cloneDate<DateType extends Date(date: DateType): DateType {\n * return constructFrom(\n * date, // Use contrustor from the given date\n * date.getTime() // Use the date value to create a new date\n * )\n * }\n */\nexport function constructFrom(date, value) {\n if (date instanceof Date) {\n return new date.constructor(value);\n } else {\n return new Date(value);\n }\n}\n\n// Fallback for modularized imports:\nexport default constructFrom;\n","/**\n * @name isDate\n * @category Common Helpers\n * @summary Is the given value a date?\n *\n * @description\n * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.\n *\n * @param value - The value to check\n *\n * @returns True if the given value is a date\n *\n * @example\n * // For a valid date:\n * const result = isDate(new Date())\n * //=> true\n *\n * @example\n * // For an invalid date:\n * const result = isDate(new Date(NaN))\n * //=> true\n *\n * @example\n * // For some value:\n * const result = isDate('2014-02-31')\n * //=> false\n *\n * @example\n * // For an object:\n * const result = isDate({})\n * //=> false\n */\nexport function isDate(value) {\n return (\n value instanceof Date ||\n (typeof value === \"object\" &&\n Object.prototype.toString.call(value) === \"[object Date]\")\n );\n}\n\n// Fallback for modularized imports:\nexport default isDate;\n","import { isDate } from \"./isDate.mjs\";\nimport { toDate } from \"./toDate.mjs\";\n\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate](https://date-fns.org/docs/toDate)\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The date to check\n *\n * @returns The date is valid\n *\n * @example\n * // For the valid date:\n * const result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertable into a date:\n * const result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * const result = isValid(new Date(''))\n * //=> false\n */\nexport function isValid(date) {\n if (!isDate(date) && typeof date !== \"number\") {\n return false;\n }\n const _date = toDate(date);\n return !isNaN(Number(_date));\n}\n\n// Fallback for modularized imports:\nexport default isValid;\n","import { toDate } from \"./toDate.mjs\";\nimport { constructFrom } from \"./constructFrom.mjs\";\n\n/**\n * @name getDaysInMonth\n * @category Month Helpers\n * @summary Get the number of days in a month of the given date.\n *\n * @description\n * Get the number of days in a month of the given date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The given date\n *\n * @returns The number of days in a month\n *\n * @example\n * // How many days are in February 2000?\n * const result = getDaysInMonth(new Date(2000, 1))\n * //=> 29\n */\nexport function getDaysInMonth(date) {\n const _date = toDate(date);\n const year = _date.getFullYear();\n const monthIndex = _date.getMonth();\n const lastDayOfMonth = constructFrom(date, 0);\n lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);\n lastDayOfMonth.setHours(0, 0, 0, 0);\n return lastDayOfMonth.getDate();\n}\n\n// Fallback for modularized imports:\nexport default getDaysInMonth;\n","import type { SegmentKey, Token } from '../types'\n\n/**\n * Parse a date format string (e.g. `dd/MM/yyyy`) into an ordered list of\n * field and separator tokens. Recognized field tokens: `dd`, `MM`, `yyyy`.\n */\nexport function parseFormat(format: string): Token[] {\n const re = /(dd|MM|yyyy)/g\n const tokens: Token[] = []\n let last = 0\n let m: RegExpExecArray | null\n while ((m = re.exec(format)) !== null) {\n if (m.index > last) {\n tokens.push({ type: 'sep', value: format.slice(last, m.index) })\n }\n const key = m[1] as SegmentKey\n tokens.push({ type: 'field', key, length: key === 'yyyy' ? 4 : 2 })\n last = m.index + m[1].length\n }\n if (last < format.length) {\n tokens.push({ type: 'sep', value: format.slice(last) })\n }\n return tokens\n}\n","/** Left-pad a number to the given length with leading zeroes. */\nexport function pad(n: number, len: number): string {\n return String(n).padStart(len, '0')\n}\n","import type { SegmentKey, Values } from '../types'\n\nexport const PLACEHOLDER: Record<SegmentKey, string> = {\n dd: 'DD',\n MM: 'MM',\n yyyy: 'YYYY',\n}\n\nexport const LABEL: Record<SegmentKey, string> = {\n dd: 'Day',\n MM: 'Month',\n yyyy: 'Year',\n}\n\nexport const EMPTY: Values = { dd: '', MM: '', yyyy: '' }\n","import { getDaysInMonth, isValid } from 'date-fns'\nimport { pad } from './string'\nimport { EMPTY } from './constants'\nimport type { Values } from '../types'\n\n/** Build segment values from a `Date`. Returns empty values for invalid input. */\nexport function fromDate(date: Date | undefined): Values {\n if (!date || !isValid(date)) return EMPTY\n return {\n dd: pad(date.getDate(), 2),\n MM: pad(date.getMonth() + 1, 2),\n yyyy: pad(date.getFullYear(), 4),\n }\n}\n\n/**\n * Maximum allowed day for a given month/year segment context.\n * Falls back to a leap-safe year (2000) when the year is unknown so that\n * Feb 29 is initially permitted and re-validated once the year is provided.\n */\nexport function maxDay(monthStr: string, yearStr: string): number {\n const m = parseInt(monthStr, 10)\n if (!m || m < 1 || m > 12) return 31\n const y = yearStr.length === 4 ? parseInt(yearStr, 10) : 2000\n return getDaysInMonth(new Date(y, m - 1, 1))\n}\n\n/**\n * Build a `Date` from segment values if and only if they form a valid\n * calendar date. Returns `undefined` for partial or invalid values\n * (e.g. 31/02/2024).\n */\nexport function toDate(values: Values): Date | undefined {\n if (values.dd.length !== 2 || values.MM.length !== 2 || values.yyyy.length !== 4) {\n return undefined\n }\n const d = parseInt(values.dd, 10)\n const m = parseInt(values.MM, 10)\n const y = parseInt(values.yyyy, 10)\n const date = new Date(y, m - 1, d)\n if (\n date.getFullYear() === y &&\n date.getMonth() === m - 1 &&\n date.getDate() === d\n ) {\n return date\n }\n return undefined\n}\n","import { isValid } from 'date-fns'\nimport {\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { parseFormat } from './utils/format'\nimport { pad } from './utils/string'\nimport { fromDate, maxDay, toDate } from './utils/time'\nimport { LABEL, PLACEHOLDER } from './utils/constants'\nimport type { SegmentKey, Token, Values } from './types'\n\nexport interface DatePickerProps {\n value?: Date\n onChange?: (date: Date | undefined) => void\n /** Format using `dd`, `MM`, `yyyy` tokens. Defaults to `dd/MM/yyyy`. */\n dateFormat?: string\n disabled?: boolean\n name?: string\n id?: string\n 'aria-label'?: string\n /** When true, render a native `<select>` dropdown next to each segment. */\n showDropdowns?: boolean\n /** Latest selectable year in the year dropdown. Defaults to the current year. */\n maxYear?: number\n /** How many years to include in the year dropdown (descending from `maxYear`). Defaults to 100. */\n yearRange?: number\n /**\n * Custom dropdown trigger icon. Either a single node used for every segment,\n * or a render function that receives the segment key. Defaults to a chevron.\n * Only used when `showDropdowns` is true.\n */\n dropdownIcon?: ReactNode | ((segment: SegmentKey) => ReactNode)\n /** Color theme. Defaults to `'light'`. Ignored when `isPlainStyle` is true. */\n theme?: 'light' | 'dark'\n /** When true, draw a single border around the whole component. Defaults to false. */\n outlined?: boolean\n /** When true, no styles or class names are applied. Use this if you want to style from scratch. */\n isPlainStyle?: boolean\n /** Per-slot class names. Merged after the built-in `rdp-*` classes (or used alone in plain mode). */\n classNames?: Partial<Record<StyleSlot, string>>\n /** Per-slot inline styles. Merged on top of the component's own inline styles. */\n styles?: Partial<Record<StyleSlot, CSSProperties>>\n}\n\n/** Style slots a consumer can target via `classNames` / `styles` props. */\nexport type StyleSlot =\n | 'root'\n | 'segment'\n | 'input'\n | 'separator'\n | 'trigger'\n | 'dropdownIcon'\n | 'select'\n\nexport function DatePicker({\n value,\n onChange,\n dateFormat = 'dd/MM/yyyy',\n disabled = false,\n name,\n id,\n showDropdowns = false,\n maxYear,\n yearRange = 100,\n dropdownIcon,\n theme = 'light',\n outlined = false,\n isPlainStyle = false,\n classNames,\n styles: slotStyles,\n ...rest\n}: DatePickerProps) {\n const resolvedMaxYear = maxYear ?? new Date().getFullYear()\n const tokens = useMemo(() => parseFormat(dateFormat), [dateFormat])\n const fieldKeys = useMemo(\n () =>\n tokens\n .filter((t): t is Extract<Token, { type: 'field' }> => t.type === 'field')\n .map((t) => t.key),\n [tokens],\n )\n\n const [values, setValues] = useState<Values>(() => fromDate(value))\n const refs = useRef<Record<SegmentKey, HTMLInputElement | null>>({\n dd: null,\n MM: null,\n yyyy: null,\n })\n\n // Tracks the last value we emitted to the parent. Used to ignore the\n // controlled-parent's echo (which would otherwise overwrite an in-progress\n // partial edit, e.g. clearing one digit of the year).\n const lastEmittedTime = useRef<number | undefined>(\n value && isValid(value) ? value.getTime() : undefined,\n )\n\n // Sync from external value changes only when the incoming value is\n // genuinely different from what this component last emitted.\n const valueTime = value && isValid(value) ? value.getTime() : undefined\n useEffect(() => {\n if (valueTime === lastEmittedTime.current) return\n lastEmittedTime.current = valueTime\n setValues(fromDate(value))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [valueTime])\n\n function emit(next: Values) {\n const date = toDate(next)\n if (date) {\n lastEmittedTime.current = date.getTime()\n onChange?.(date)\n return\n }\n lastEmittedTime.current = undefined\n onChange?.(undefined)\n }\n\n function focusSibling(current: SegmentKey, dir: 1 | -1) {\n const idx = fieldKeys.indexOf(current)\n const target = fieldKeys[idx + dir]\n if (!target) return\n const el = refs.current[target]\n if (!el) return\n el.focus()\n if (dir === -1) {\n const len = el.value.length\n try {\n el.setSelectionRange(len, len)\n } catch {\n /* some input types don't support selection */\n }\n } else {\n try {\n el.setSelectionRange(0, el.value.length)\n } catch {\n /* noop */\n }\n }\n }\n\n function handleChange(key: SegmentKey, raw: string, maxLen: number) {\n // Strip non-digits and clamp length\n const digits = raw.replace(/\\D/g, '').slice(0, maxLen)\n\n setValues((prev) => {\n const next: Values = { ...prev, [key]: digits }\n\n if (digits.length > 0) {\n const num = parseInt(digits, 10)\n\n // Reject impossible first digits (so user can't even type 4-9 as first dd digit, etc.)\n if (digits.length < maxLen) {\n if (key === 'dd' && parseInt(digits[0]!, 10) > 3) return prev\n if (key === 'MM' && parseInt(digits[0]!, 10) > 1) return prev\n }\n\n // Reject full segments that exceed allowed range\n if (digits.length === maxLen) {\n if (key === 'dd' && (num < 1 || num > maxDay(next.MM, next.yyyy))) return prev\n if (key === 'MM' && (num < 1 || num > 12)) return prev\n if (key === 'yyyy' && num < 1) return prev\n }\n }\n\n // If month or year changed, ensure existing day is still valid; clear it otherwise.\n if (key !== 'dd' && next.dd.length === 2) {\n const dnum = parseInt(next.dd, 10)\n if (dnum > maxDay(next.MM, next.yyyy)) next.dd = ''\n }\n\n // Auto-advance once segment is full\n if (digits.length === maxLen) {\n queueMicrotask(() => focusSibling(key, 1))\n }\n\n emit(next)\n return next\n })\n }\n\n function getOptions(key: SegmentKey): string[] {\n if (key === 'dd') {\n const max = maxDay(values.MM, values.yyyy)\n return Array.from({ length: max }, (_, i) => pad(i + 1, 2))\n }\n if (key === 'MM') {\n return Array.from({ length: 12 }, (_, i) => pad(i + 1, 2))\n }\n // yyyy: descending from resolvedMaxYear\n return Array.from({ length: yearRange }, (_, i) => pad(resolvedMaxYear - i, 4))\n }\n\n function handleSelect(key: SegmentKey, raw: string, maxLen: 2 | 4) {\n // Route through handleChange so all validation + day re-check + emit happens.\n handleChange(key, raw, maxLen)\n }\n\n function handleKeyDown(key: SegmentKey, e: KeyboardEvent<HTMLInputElement>) {\n const target = e.currentTarget\n const atStart = target.selectionStart === 0 && target.selectionEnd === 0\n const atEnd =\n target.selectionStart === target.value.length &&\n target.selectionEnd === target.value.length\n\n if (e.key === 'Backspace' && target.value === '') {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowLeft' && atStart) {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowRight' && atEnd) {\n e.preventDefault()\n focusSibling(key, 1)\n }\n }\n\n // Inline styles only used in plain mode. The CSS file (when not plain)\n // handles layout via .rdp-* classes; the absolute positioning of the\n // invisible <select> over the icon is functional, not cosmetic, so it\n // must always be applied.\n const triggerStyle = isPlainStyle\n ? {\n position: 'relative' as const,\n display: 'inline-flex' as const,\n alignItems: 'center' as const,\n justifyContent: 'center' as const,\n width: '1em',\n height: '1em',\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n userSelect: 'none' as const,\n lineHeight: 1,\n }\n : { position: 'relative' as const }\n\n const selectStyle = {\n position: 'absolute' as const,\n inset: 0,\n width: '100%',\n height: '100%',\n opacity: 0,\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n appearance: 'none' as const,\n WebkitAppearance: 'none' as const,\n MozAppearance: 'none' as const,\n border: 0,\n padding: 0,\n margin: 0,\n background: 'transparent',\n color: 'transparent',\n fontSize: 'inherit',\n }\n\n const segmentStyle = isPlainStyle\n ? { display: 'inline-flex' as const, alignItems: 'center' as const }\n : undefined\n\n // Helper: combine the built-in class for a slot with any consumer-provided class.\n const cn = (builtin: string | undefined, slot: StyleSlot) => {\n const extra = classNames?.[slot]\n if (!builtin) return extra\n return extra ? `${builtin} ${extra}` : builtin\n }\n\n // Helper: merge built-in inline style with consumer slot style (consumer wins).\n const mergeStyle = (\n base: CSSProperties | undefined,\n slot: StyleSlot,\n ): CSSProperties | undefined => {\n const extra = slotStyles?.[slot]\n if (!base) return extra\n if (!extra) return base\n return { ...base, ...extra }\n }\n\n return (\n <span\n role=\"group\"\n aria-label={rest['aria-label'] ?? 'Date'}\n id={id}\n className={cn(isPlainStyle ? undefined : 'rdp-root', 'root')}\n style={mergeStyle(undefined, 'root')}\n data-theme={isPlainStyle ? undefined : theme}\n data-outlined={isPlainStyle ? undefined : outlined ? 'true' : 'false'}\n data-disabled={isPlainStyle ? undefined : disabled ? 'true' : 'false'}\n >\n {tokens.map((t, i) => {\n if (t.type === 'sep') {\n return (\n <span\n key={`s${i}`}\n aria-hidden=\"true\"\n className={cn(isPlainStyle ? undefined : 'rdp-sep', 'separator')}\n style={mergeStyle(undefined, 'separator')}\n >\n {t.value}\n </span>\n )\n }\n return (\n <span\n key={t.key}\n className={cn(isPlainStyle ? undefined : 'rdp-segment', 'segment')}\n style={mergeStyle(segmentStyle, 'segment')}\n >\n <input\n ref={(el) => {\n refs.current[t.key] = el\n }}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n autoComplete=\"off\"\n disabled={disabled}\n name={name ? `${name}-${t.key}` : undefined}\n maxLength={t.length}\n size={t.length}\n placeholder={PLACEHOLDER[t.key]}\n aria-label={LABEL[t.key]}\n className={cn(isPlainStyle ? undefined : 'rdp-input', 'input')}\n style={mergeStyle(undefined, 'input')}\n value={values[t.key]}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n handleChange(t.key, e.target.value, t.length)\n }\n onKeyDown={(e) => handleKeyDown(t.key, e)}\n onFocus={(e) => e.currentTarget.select()}\n />\n {showDropdowns && (\n <span\n className={cn(isPlainStyle ? undefined : 'rdp-trigger', 'trigger')}\n style={mergeStyle(triggerStyle, 'trigger')}\n >\n <span\n aria-hidden=\"true\"\n className={cn(undefined, 'dropdownIcon')}\n style={mergeStyle(undefined, 'dropdownIcon')}\n >\n {typeof dropdownIcon === 'function'\n ? dropdownIcon(t.key)\n : (dropdownIcon ?? '▾')}\n </span>\n <select\n aria-label={`Pick ${LABEL[t.key]}`}\n disabled={disabled}\n className={cn(isPlainStyle ? undefined : 'rdp-select', 'select')}\n value={values[t.key]}\n onChange={(e) => handleSelect(t.key, e.target.value, t.length)}\n style={mergeStyle(selectStyle, 'select')}\n >\n <option value=\"\" disabled hidden>\n {LABEL[t.key]}\n </option>\n {getOptions(t.key).map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n </span>\n )}\n </span>\n )\n })}\n </span>\n )\n}\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["toDate","toDate","toDate"],"sources":["../node_modules/date-fns/toDate.mjs","../node_modules/date-fns/constructFrom.mjs","../node_modules/date-fns/isDate.mjs","../node_modules/date-fns/isValid.mjs","../node_modules/date-fns/getDaysInMonth.mjs","../src/utils/format.ts","../src/utils/string.ts","../src/utils/constants.ts","../src/utils/time.ts","../src/DatePicker.tsx"],"sourcesContent":["/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param argument - The value to convert\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nexport function toDate(argument) {\n const argStr = Object.prototype.toString.call(argument);\n\n // Clone the date\n if (\n argument instanceof Date ||\n (typeof argument === \"object\" && argStr === \"[object Date]\")\n ) {\n // Prevent the date to lose the milliseconds when passed to new Date() in IE10\n return new argument.constructor(+argument);\n } else if (\n typeof argument === \"number\" ||\n argStr === \"[object Number]\" ||\n typeof argument === \"string\" ||\n argStr === \"[object String]\"\n ) {\n // TODO: Can we get rid of as?\n return new Date(argument);\n } else {\n // TODO: Can we get rid of as?\n return new Date(NaN);\n }\n}\n\n// Fallback for modularized imports:\nexport default toDate;\n","/**\n * @name constructFrom\n * @category Generic Helpers\n * @summary Constructs a date using the reference date and the value\n *\n * @description\n * The function constructs a new date using the constructor from the reference\n * date and the given value. It helps to build generic functions that accept\n * date extensions.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The reference date to take constructor from\n * @param value - The value to create the date\n *\n * @returns Date initialized using the given date and value\n *\n * @example\n * import { constructFrom } from 'date-fns'\n *\n * // A function that clones a date preserving the original type\n * function cloneDate<DateType extends Date(date: DateType): DateType {\n * return constructFrom(\n * date, // Use contrustor from the given date\n * date.getTime() // Use the date value to create a new date\n * )\n * }\n */\nexport function constructFrom(date, value) {\n if (date instanceof Date) {\n return new date.constructor(value);\n } else {\n return new Date(value);\n }\n}\n\n// Fallback for modularized imports:\nexport default constructFrom;\n","/**\n * @name isDate\n * @category Common Helpers\n * @summary Is the given value a date?\n *\n * @description\n * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.\n *\n * @param value - The value to check\n *\n * @returns True if the given value is a date\n *\n * @example\n * // For a valid date:\n * const result = isDate(new Date())\n * //=> true\n *\n * @example\n * // For an invalid date:\n * const result = isDate(new Date(NaN))\n * //=> true\n *\n * @example\n * // For some value:\n * const result = isDate('2014-02-31')\n * //=> false\n *\n * @example\n * // For an object:\n * const result = isDate({})\n * //=> false\n */\nexport function isDate(value) {\n return (\n value instanceof Date ||\n (typeof value === \"object\" &&\n Object.prototype.toString.call(value) === \"[object Date]\")\n );\n}\n\n// Fallback for modularized imports:\nexport default isDate;\n","import { isDate } from \"./isDate.mjs\";\nimport { toDate } from \"./toDate.mjs\";\n\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate](https://date-fns.org/docs/toDate)\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The date to check\n *\n * @returns The date is valid\n *\n * @example\n * // For the valid date:\n * const result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertable into a date:\n * const result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * const result = isValid(new Date(''))\n * //=> false\n */\nexport function isValid(date) {\n if (!isDate(date) && typeof date !== \"number\") {\n return false;\n }\n const _date = toDate(date);\n return !isNaN(Number(_date));\n}\n\n// Fallback for modularized imports:\nexport default isValid;\n","import { toDate } from \"./toDate.mjs\";\nimport { constructFrom } from \"./constructFrom.mjs\";\n\n/**\n * @name getDaysInMonth\n * @category Month Helpers\n * @summary Get the number of days in a month of the given date.\n *\n * @description\n * Get the number of days in a month of the given date.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The given date\n *\n * @returns The number of days in a month\n *\n * @example\n * // How many days are in February 2000?\n * const result = getDaysInMonth(new Date(2000, 1))\n * //=> 29\n */\nexport function getDaysInMonth(date) {\n const _date = toDate(date);\n const year = _date.getFullYear();\n const monthIndex = _date.getMonth();\n const lastDayOfMonth = constructFrom(date, 0);\n lastDayOfMonth.setFullYear(year, monthIndex + 1, 0);\n lastDayOfMonth.setHours(0, 0, 0, 0);\n return lastDayOfMonth.getDate();\n}\n\n// Fallback for modularized imports:\nexport default getDaysInMonth;\n","import type { SegmentKey, Token } from '../types'\n\n/**\n * Parse a date format string (e.g. `dd/MM/yyyy`) into an ordered list of\n * field and separator tokens. Recognized field tokens: `dd`, `MM`, `yyyy`.\n */\nexport function parseFormat(format: string): Token[] {\n const re = /(dd|MM|yyyy)/g\n const tokens: Token[] = []\n let last = 0\n let m: RegExpExecArray | null\n while ((m = re.exec(format)) !== null) {\n if (m.index > last) {\n tokens.push({ type: 'sep', value: format.slice(last, m.index) })\n }\n const key = m[1] as SegmentKey\n tokens.push({ type: 'field', key, length: key === 'yyyy' ? 4 : 2 })\n last = m.index + m[1].length\n }\n if (last < format.length) {\n tokens.push({ type: 'sep', value: format.slice(last) })\n }\n return tokens\n}\n","/** Left-pad a number to the given length with leading zeroes. */\nexport function pad(n: number, len: number): string {\n return String(n).padStart(len, '0')\n}\n","import type { SegmentKey, Values } from '../types'\n\nexport const PLACEHOLDER: Record<SegmentKey, string> = {\n dd: 'DD',\n MM: 'MM',\n yyyy: 'YYYY',\n}\n\nexport const LABEL: Record<SegmentKey, string> = {\n dd: 'Day',\n MM: 'Month',\n yyyy: 'Year',\n}\n\nexport const EMPTY: Values = { dd: '', MM: '', yyyy: '' }\n","import { getDaysInMonth, isValid } from 'date-fns'\nimport { pad } from './string'\nimport { EMPTY } from './constants'\nimport type { Values } from '../types'\n\n/** Build segment values from a `Date`. Returns empty values for invalid input. */\nexport function fromDate(date: Date | undefined): Values {\n if (!date || !isValid(date)) return EMPTY\n return {\n dd: pad(date.getDate(), 2),\n MM: pad(date.getMonth() + 1, 2),\n yyyy: pad(date.getFullYear(), 4),\n }\n}\n\n/**\n * Maximum allowed day for a given month/year segment context.\n * Falls back to a leap-safe year (2000) when the year is unknown so that\n * Feb 29 is initially permitted and re-validated once the year is provided.\n */\nexport function maxDay(monthStr: string, yearStr: string): number {\n const m = parseInt(monthStr, 10)\n if (!m || m < 1 || m > 12) return 31\n const y = yearStr.length === 4 ? parseInt(yearStr, 10) : 2000\n return getDaysInMonth(new Date(y, m - 1, 1))\n}\n\n/**\n * Build a `Date` from segment values if and only if they form a valid\n * calendar date. Returns `undefined` for partial or invalid values\n * (e.g. 31/02/2024).\n */\nexport function toDate(values: Values): Date | undefined {\n if (values.dd.length !== 2 || values.MM.length !== 2 || values.yyyy.length !== 4) {\n return undefined\n }\n const d = parseInt(values.dd, 10)\n const m = parseInt(values.MM, 10)\n const y = parseInt(values.yyyy, 10)\n const date = new Date(y, m - 1, d)\n if (\n date.getFullYear() === y &&\n date.getMonth() === m - 1 &&\n date.getDate() === d\n ) {\n return date\n }\n return undefined\n}\n","import { isValid } from 'date-fns'\nimport {\n type ChangeEvent,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { parseFormat } from './utils/format'\nimport { pad } from './utils/string'\nimport { fromDate, maxDay, toDate } from './utils/time'\nimport { LABEL, PLACEHOLDER } from './utils/constants'\nimport type { SegmentKey, Token, Values } from './types'\n\nexport interface DatePickerProps {\n value?: Date\n onChange?: (date: Date | undefined) => void\n /** Format using `dd`, `MM`, `yyyy` tokens. Defaults to `dd/MM/yyyy`. */\n dateFormat?: string\n disabled?: boolean\n name?: string\n id?: string\n 'aria-label'?: string\n /** When true, render a native `<select>` dropdown next to each segment. */\n showDropdowns?: boolean\n /** Latest selectable year in the year dropdown. Defaults to the current year. */\n maxYear?: number\n /** How many years to include in the year dropdown (descending from `maxYear`). Defaults to 100. */\n yearRange?: number\n /**\n * Custom dropdown trigger icon. Either a single node used for every segment,\n * or a render function that receives the segment key. Defaults to a chevron.\n * Only used when `showDropdowns` is true.\n */\n dropdownIcon?: ReactNode | ((segment: SegmentKey) => ReactNode)\n /** Color theme. Defaults to `'light'`. Ignored when `isPlainStyle` is true. */\n theme?: 'light' | 'dark'\n /** When true, draw a single border around the whole component. Defaults to false. */\n outlined?: boolean\n /** When true, no styles or class names are applied. Use this if you want to style from scratch. */\n isPlainStyle?: boolean\n /** Per-slot class names. Merged after the built-in `rdp-*` classes (or used alone in plain mode). */\n classNames?: Partial<Record<StyleSlot, string>>\n /** Per-slot inline styles. Merged on top of the component's own inline styles. */\n styles?: Partial<Record<StyleSlot, CSSProperties>>\n}\n\n/** Style slots a consumer can target via `classNames` / `styles` props. */\nexport type StyleSlot =\n | 'root'\n | 'segment'\n | 'input'\n | 'separator'\n | 'trigger'\n | 'dropdownIcon'\n | 'select'\n\nexport function DatePicker({\n value,\n onChange,\n dateFormat = 'dd/MM/yyyy',\n disabled = false,\n name,\n id,\n showDropdowns = false,\n maxYear,\n yearRange = 100,\n dropdownIcon,\n theme = 'light',\n outlined = false,\n isPlainStyle = false,\n classNames,\n styles: slotStyles,\n ...rest\n}: DatePickerProps) {\n const resolvedMaxYear = maxYear ?? new Date().getFullYear()\n const tokens = useMemo(() => parseFormat(dateFormat), [dateFormat])\n const fieldKeys = useMemo(\n () =>\n tokens\n .filter((t): t is Extract<Token, { type: 'field' }> => t.type === 'field')\n .map((t) => t.key),\n [tokens],\n )\n\n const [values, setValues] = useState<Values>(() => fromDate(value))\n const refs = useRef<Record<SegmentKey, HTMLInputElement | null>>({\n dd: null,\n MM: null,\n yyyy: null,\n })\n\n // Tracks the last value we emitted to the parent. Used to ignore the\n // controlled-parent's echo (which would otherwise overwrite an in-progress\n // partial edit, e.g. clearing one digit of the year).\n const lastEmittedTime = useRef<number | undefined>(\n value && isValid(value) ? value.getTime() : undefined,\n )\n\n // Sync from external value changes only when the incoming value is\n // genuinely different from what this component last emitted.\n const valueTime = value && isValid(value) ? value.getTime() : undefined\n useEffect(() => {\n if (valueTime === lastEmittedTime.current) return\n lastEmittedTime.current = valueTime\n setValues(fromDate(value))\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [valueTime])\n\n function emit(next: Values) {\n const date = toDate(next)\n if (date) {\n lastEmittedTime.current = date.getTime()\n onChange?.(date)\n return\n }\n lastEmittedTime.current = undefined\n onChange?.(undefined)\n }\n\n function focusSibling(current: SegmentKey, dir: 1 | -1) {\n const idx = fieldKeys.indexOf(current)\n const target = fieldKeys[idx + dir]\n if (!target) return\n const el = refs.current[target]\n if (!el) return\n el.focus()\n if (dir === -1) {\n const len = el.value.length\n try {\n el.setSelectionRange(len, len)\n } catch {\n /* some input types don't support selection */\n }\n } else {\n try {\n el.setSelectionRange(0, el.value.length)\n } catch {\n /* noop */\n }\n }\n }\n\n function handleChange(key: SegmentKey, raw: string, maxLen: number) {\n // Strip non-digits and clamp length\n const digits = raw.replace(/\\D/g, '').slice(0, maxLen)\n\n setValues((prev) => {\n const next: Values = { ...prev, [key]: digits }\n\n if (digits.length > 0) {\n const num = parseInt(digits, 10)\n\n // Reject impossible first digits (so user can't even type 4-9 as first dd digit, etc.)\n if (digits.length < maxLen) {\n if (key === 'dd' && parseInt(digits[0]!, 10) > 3) return prev\n if (key === 'MM' && parseInt(digits[0]!, 10) > 1) return prev\n }\n\n // Reject full segments that exceed allowed range\n if (digits.length === maxLen) {\n if (key === 'dd' && (num < 1 || num > maxDay(next.MM, next.yyyy))) return prev\n if (key === 'MM' && (num < 1 || num > 12)) return prev\n if (key === 'yyyy' && num < 1) return prev\n }\n }\n\n // If month or year changed, ensure existing day is still valid; clear it otherwise.\n if (key !== 'dd' && next.dd.length === 2) {\n const dnum = parseInt(next.dd, 10)\n if (dnum > maxDay(next.MM, next.yyyy)) next.dd = ''\n }\n\n // Auto-advance once segment is full\n if (digits.length === maxLen) {\n queueMicrotask(() => focusSibling(key, 1))\n }\n\n emit(next)\n return next\n })\n }\n\n function getOptions(key: SegmentKey): string[] {\n if (key === 'dd') {\n const max = maxDay(values.MM, values.yyyy)\n return Array.from({ length: max }, (_, i) => pad(i + 1, 2))\n }\n if (key === 'MM') {\n return Array.from({ length: 12 }, (_, i) => pad(i + 1, 2))\n }\n // yyyy: descending from resolvedMaxYear\n return Array.from({ length: yearRange }, (_, i) => pad(resolvedMaxYear - i, 4))\n }\n\n function handleSelect(key: SegmentKey, raw: string, maxLen: 2 | 4) {\n // Route through handleChange so all validation + day re-check + emit happens.\n handleChange(key, raw, maxLen)\n }\n\n function handleKeyDown(key: SegmentKey, e: KeyboardEvent<HTMLInputElement>) {\n const target = e.currentTarget\n const atStart = target.selectionStart === 0 && target.selectionEnd === 0\n const atEnd =\n target.selectionStart === target.value.length &&\n target.selectionEnd === target.value.length\n\n if (e.key === 'Backspace' && target.value === '') {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowLeft' && atStart) {\n e.preventDefault()\n focusSibling(key, -1)\n return\n }\n if (e.key === 'ArrowRight' && atEnd) {\n e.preventDefault()\n focusSibling(key, 1)\n }\n }\n\n // Inline styles only used in plain mode. The CSS file (when not plain)\n // handles layout via .rdp-* classes; the absolute positioning of the\n // invisible <select> over the icon is functional, not cosmetic, so it\n // must always be applied.\n const triggerStyle = isPlainStyle\n ? {\n position: 'relative' as const,\n display: 'inline-flex' as const,\n alignItems: 'center' as const,\n justifyContent: 'center' as const,\n width: '1em',\n height: '1em',\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n userSelect: 'none' as const,\n lineHeight: 1,\n }\n : { position: 'relative' as const }\n\n const selectStyle = {\n position: 'absolute' as const,\n inset: 0,\n width: '100%',\n height: '100%',\n opacity: 0,\n cursor: disabled ? ('not-allowed' as const) : ('pointer' as const),\n appearance: 'none' as const,\n WebkitAppearance: 'none' as const,\n MozAppearance: 'none' as const,\n border: 0,\n padding: 0,\n margin: 0,\n background: 'transparent',\n color: 'transparent',\n fontSize: 'inherit',\n }\n\n const segmentStyle = isPlainStyle\n ? { display: 'inline-flex' as const, alignItems: 'center' as const }\n : undefined\n\n // Helper: combine the built-in class for a slot with any consumer-provided class.\n const cn = (builtin: string | undefined, slot: StyleSlot) => {\n const extra = classNames?.[slot]\n if (!builtin) return extra\n return extra ? `${builtin} ${extra}` : builtin\n }\n\n // Helper: merge built-in inline style with consumer slot style (consumer wins).\n const mergeStyle = (\n base: CSSProperties | undefined,\n slot: StyleSlot,\n ): CSSProperties | undefined => {\n const extra = slotStyles?.[slot]\n if (!base) return extra\n if (!extra) return base\n return { ...base, ...extra }\n }\n\n return (\n <span\n role=\"group\"\n aria-label={rest['aria-label'] ?? 'Date'}\n id={id}\n className={cn(isPlainStyle ? undefined : 'rdp-root', 'root')}\n style={mergeStyle(undefined, 'root')}\n data-theme={isPlainStyle ? undefined : theme}\n data-outlined={isPlainStyle ? undefined : outlined ? 'true' : 'false'}\n data-disabled={isPlainStyle ? undefined : disabled ? 'true' : 'false'}\n >\n {tokens.map((t, i) => {\n if (t.type === 'sep') {\n return (\n <span\n key={`s${i}`}\n aria-hidden=\"true\"\n className={cn(isPlainStyle ? undefined : 'rdp-sep', 'separator')}\n style={mergeStyle(undefined, 'separator')}\n >\n {t.value}\n </span>\n )\n }\n return (\n <span\n key={t.key}\n className={cn(isPlainStyle ? undefined : 'rdp-segment', 'segment')}\n style={mergeStyle(segmentStyle, 'segment')}\n >\n <input\n ref={(el) => {\n refs.current[t.key] = el\n }}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n autoComplete=\"off\"\n disabled={disabled}\n name={name ? `${name}-${t.key}` : undefined}\n maxLength={t.length}\n size={t.length}\n placeholder={PLACEHOLDER[t.key]}\n aria-label={LABEL[t.key]}\n className={cn(isPlainStyle ? undefined : 'rdp-input', 'input')}\n style={mergeStyle(undefined, 'input')}\n value={values[t.key]}\n data-segment={t.key}\n onChange={(e: ChangeEvent<HTMLInputElement>) =>\n handleChange(t.key, e.target.value, t.length)\n }\n onKeyDown={(e) => handleKeyDown(t.key, e)}\n onFocus={(e) => e.currentTarget.select()}\n />\n {showDropdowns && (\n <span\n className={cn(isPlainStyle ? undefined : 'rdp-trigger', 'trigger')}\n style={mergeStyle(triggerStyle, 'trigger')}\n >\n <span\n aria-hidden=\"true\"\n className={cn(undefined, 'dropdownIcon')}\n style={mergeStyle(undefined, 'dropdownIcon')}\n >\n {typeof dropdownIcon === 'function'\n ? dropdownIcon(t.key)\n : (dropdownIcon ?? '▾')}\n </span>\n <select\n aria-label={`Pick ${LABEL[t.key]}`}\n disabled={disabled}\n className={cn(isPlainStyle ? undefined : 'rdp-select', 'select')}\n value={values[t.key]}\n onChange={(e) => handleSelect(t.key, e.target.value, t.length)}\n style={mergeStyle(selectStyle, 'select')}\n >\n <option value=\"\" disabled hidden>\n {LABEL[t.key]}\n </option>\n {getOptions(t.key).map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n </span>\n )}\n </span>\n )\n })}\n </span>\n )\n}\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
|
package/dist/styles.css
CHANGED
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/* Strip native <input> chrome so segments feel like one continuous field */
|
|
64
|
+
|
|
64
65
|
.rdp-input {
|
|
65
66
|
font: inherit;
|
|
66
67
|
color: inherit;
|
|
@@ -73,6 +74,12 @@
|
|
|
73
74
|
caret-color: var(--rdp-focus);
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
/* Give MM (month) segment a bit more width, only when not plain style */
|
|
78
|
+
/* Make MM (month) segment wider for better visibility */
|
|
79
|
+
.rdp-root:not([data-plain="true"]) .rdp-input[data-segment="MM"] {
|
|
80
|
+
min-width: 2.5em;
|
|
81
|
+
}
|
|
82
|
+
|
|
76
83
|
.rdp-input::placeholder {
|
|
77
84
|
color: var(--rdp-muted);
|
|
78
85
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@punaro/react-datepicker",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "A lightweight, accessible React date picker component",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -35,6 +35,14 @@
|
|
|
35
35
|
"component"
|
|
36
36
|
],
|
|
37
37
|
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/vinayvnvv/react-datepicker.git"
|
|
41
|
+
},
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/vinayvnvv/react-datepicker/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/vinayvnvv/react-datepicker#readme",
|
|
38
46
|
"peerDependencies": {
|
|
39
47
|
"react": ">=17.0.0",
|
|
40
48
|
"react-dom": ">=17.0.0"
|