@trsys-tech/matrix-library 1.1.1 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/accordion.es.js +21 -19
  2. package/dist/accordion.es.js.map +1 -1
  3. package/dist/avatar.es.js +19 -19
  4. package/dist/avatar.es.js.map +1 -1
  5. package/dist/breadcrumb.es.js +7 -7
  6. package/dist/breadcrumb.es.js.map +1 -1
  7. package/dist/calendar.es.js +40 -33
  8. package/dist/calendar.es.js.map +1 -1
  9. package/dist/chip.es.js +28 -22
  10. package/dist/chip.es.js.map +1 -1
  11. package/dist/command.es.js +35 -32
  12. package/dist/command.es.js.map +1 -1
  13. package/dist/components/accordion/Accordion.d.ts.map +1 -1
  14. package/dist/components/chip/Chip.d.ts.map +1 -1
  15. package/dist/components/command/Command.d.ts.map +1 -1
  16. package/dist/components/date-picker/DesktopDatePicker.d.ts +1 -1
  17. package/dist/components/date-picker/DesktopDatePicker.d.ts.map +1 -1
  18. package/dist/components/date-picker/DesktopTimePicker.d.ts +2 -2
  19. package/dist/components/date-picker/DesktopTimePicker.d.ts.map +1 -1
  20. package/dist/components/date-picker/TimePickerContent.d.ts.map +1 -1
  21. package/dist/components/date-picker/calendar.d.ts.map +1 -1
  22. package/dist/components/gantt-chart/GanttChart.d.ts +104 -0
  23. package/dist/components/gantt-chart/GanttChart.d.ts.map +1 -0
  24. package/dist/components/gantt-chart/GanttToolbar.d.ts +14 -0
  25. package/dist/components/gantt-chart/GanttToolbar.d.ts.map +1 -0
  26. package/dist/components/gantt-chart/gantt-chart.types.d.ts +45 -0
  27. package/dist/components/gantt-chart/gantt-chart.types.d.ts.map +1 -0
  28. package/dist/components/gantt-chart/gantt-chart.utils.d.ts +34 -0
  29. package/dist/components/gantt-chart/gantt-chart.utils.d.ts.map +1 -0
  30. package/dist/components/multi-select/MultiSelect.d.ts +0 -8
  31. package/dist/components/multi-select/MultiSelect.d.ts.map +1 -1
  32. package/dist/components/rating/Rating.d.ts +1 -0
  33. package/dist/components/rating/Rating.d.ts.map +1 -1
  34. package/dist/components/sidebar/Sidebar.d.ts +1 -1
  35. package/dist/components/sidebar/Sidebar.d.ts.map +1 -1
  36. package/dist/components/tabs/Tabs.d.ts +5 -3
  37. package/dist/components/tabs/Tabs.d.ts.map +1 -1
  38. package/dist/components/timeline/Timeline.d.ts +81 -0
  39. package/dist/components/timeline/Timeline.d.ts.map +1 -0
  40. package/dist/components/tooltip/Tooltip.d.ts.map +1 -1
  41. package/dist/desktopdatepicker.es.js +2 -2
  42. package/dist/desktopdatepicker.es.js.map +1 -1
  43. package/dist/desktoptimepicker.es.js.map +1 -1
  44. package/dist/duration.es.js +1 -1
  45. package/dist/duration.es.js.map +1 -1
  46. package/dist/gantt-chart.es.js +93 -0
  47. package/dist/gantt-chart.es.js.map +1 -0
  48. package/dist/ganttchart.es.js +337 -0
  49. package/dist/ganttchart.es.js.map +1 -0
  50. package/dist/gantttoolbar.es.js +49 -0
  51. package/dist/gantttoolbar.es.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.es.js +191 -187
  55. package/dist/index.es.js.map +1 -1
  56. package/dist/multiselect.es.js +121 -130
  57. package/dist/multiselect.es.js.map +1 -1
  58. package/dist/rating.es.js +47 -50
  59. package/dist/rating.es.js.map +1 -1
  60. package/dist/sidebar.es.js +1 -1
  61. package/dist/sidebar.es.js.map +1 -1
  62. package/dist/styles.css +1 -1
  63. package/dist/switch.es.js +5 -5
  64. package/dist/switch.es.js.map +1 -1
  65. package/dist/tabs.es.js +25 -26
  66. package/dist/tabs.es.js.map +1 -1
  67. package/dist/textfield.es.js +18 -18
  68. package/dist/textfield.es.js.map +1 -1
  69. package/dist/timeline.es.js +328 -0
  70. package/dist/timeline.es.js.map +1 -0
  71. package/dist/timepickercontent.es.js +39 -42
  72. package/dist/timepickercontent.es.js.map +1 -1
  73. package/dist/tooltip.es.js +15 -13
  74. package/dist/tooltip.es.js.map +1 -1
  75. package/package.json +7 -1
@@ -1 +1 @@
1
- {"version":3,"file":"desktoptimepicker.es.js","sources":["../src/components/date-picker/DesktopTimePicker.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { HTMLAttributes, useState } from \"react\";\r\n\r\nimport { cn } from \"../../lib/utils\";\r\nimport { Button } from \"../button/Button\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover/Popover\";\r\nimport { Time, TimePickerContent } from \"./TimePickerContent\";\r\n\r\nconst formatTimeLabel = (time: Time, is24HourMode: boolean) => {\r\n const minute = time.minute.toString().padStart(2, \"0\");\r\n\r\n if (is24HourMode) {\r\n const hour = time.ampm ? (time.hour % 12) + (time.ampm === \"PM\" ? 12 : 0) : time.hour;\r\n return `${hour.toString().padStart(2, \"0\")} : ${minute}`;\r\n }\r\n\r\n const hourFromAmpm = time.ampm ? (time.hour % 12) + (time.ampm === \"PM\" ? 12 : 0) : time.hour;\r\n const hour = hourFromAmpm % 12 || 12;\r\n const ampm = time.ampm ?? (hourFromAmpm >= 12 ? \"PM\" : \"AM\");\r\n\r\n return `${hour.toString().padStart(2, \"0\")} : ${minute} ${ampm}`;\r\n};\r\n\r\n/**\r\n * Props for the desktop-only time picker.\r\n *\r\n * In 12-hour mode, the time value should include ampm.\r\n * In 24-hour mode, the time value should omit ampm and use hour values from 0-23.\r\n */\r\ntype DesktopTimePickerProps = HTMLAttributes<HTMLButtonElement> & {\r\n /** Current time value. */\r\n time: Time | undefined;\r\n /** Called whenever the selected time changes. */\r\n onTimeChange: (time: Time | undefined) => void;\r\n /** Enables 24-hour mode and hides the AM/PM column when true. */\r\n is24HourMode?: boolean;\r\n /** Accessible label and trigger fallback when no time is selected. */\r\n placeholder?: string;\r\n /** Disables the trigger button. */\r\n disabled?: boolean;\r\n /** Props forwarded to the popover content. */\r\n slotsProps?: {\r\n /** Props forwarded to the time picker content container. */\r\n content?: HTMLAttributes<HTMLDivElement>;\r\n };\r\n};\r\n\r\n/**\r\n * Desktop-only time picker rendered in a popover.\r\n * Use this component when you want the desktop interaction regardless of screen size.\r\n */\r\nconst DesktopTimePicker: React.FC<DesktopTimePickerProps> = ({\r\n time,\r\n onTimeChange,\r\n className,\r\n slotsProps,\r\n is24HourMode = false,\r\n placeholder = \"Pick a Time\",\r\n ...restProps\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n return (\r\n <Popover open={isOpen} onOpenChange={setIsOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n variant=\"text\"\r\n className={cn(\r\n \"mtx-flex mtx-h-8 mtx-w-full mtx-items-center mtx-justify-between mtx-whitespace-nowrap mtx-rounded-sm mtx-border mtx-border-input mtx-bg-transparent mtx-ps-3 mtx-pe-1 mtx-py-1.5 mtx-text-xs mtx-ring-offset-background data-[placeholder]:mtx-text-muted-foreground hover:mtx-border hover:mtx-border-primary hover:mtx-bg-transparent focus:mtx-border focus:mtx-border-primary focus:mtx-outline-none focus:mtx-ring focus:mtx-ring-primary-100 disabled:mtx-cursor-not-allowed disabled:mtx-bg-gray-100 disabled:mtx-text-text-300 disabled:mtx-border-gray-100 [&>span]:mtx-line-clamp-1 [&_svg]:disabled:mtx-text-text-300\",\r\n className,\r\n )}\r\n data-placeholder={!time ? \"\" : undefined}\r\n aria-label={time ? `Selected time: ${formatTimeLabel(time, is24HourMode)}` : placeholder}\r\n {...restProps}\r\n type=\"button\"\r\n >\r\n {time ? formatTimeLabel(time, is24HourMode) : \"-- : --\"}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent {...(slotsProps?.content ?? {})} className={cn(\"mtx-w-auto mtx-p-0\", slotsProps?.content?.className)}>\r\n <TimePickerContent isOpen={isOpen} is24HourMode={is24HourMode} onTimeChange={onTimeChange} time={time} slotsProps={slotsProps} />\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n};\r\nexport { DesktopTimePicker, type DesktopTimePickerProps };\r\n"],"names":["formatTimeLabel","time","is24HourMode","minute","hourFromAmpm","hour","ampm","DesktopTimePicker","onTimeChange","className","slotsProps","placeholder","restProps","isOpen","setIsOpen","useState","jsxs","Popover","jsx","PopoverTrigger","Button","cn","PopoverContent","TimePickerContent"],"mappings":";;;;;;AASA,MAAMA,IAAkB,CAACC,GAAYC,MAA0B;AAC7D,QAAMC,IAASF,EAAK,OAAO,WAAW,SAAS,GAAG,GAAG;AAErD,MAAIC;AAEF,WAAO,IADMD,EAAK,OAAQA,EAAK,OAAO,MAAOA,EAAK,SAAS,OAAO,KAAK,KAAKA,EAAK,MAClE,WAAW,SAAS,GAAG,GAAG,CAAC,MAAME,CAAM;AAGxD,QAAMC,IAAeH,EAAK,OAAQA,EAAK,OAAO,MAAOA,EAAK,SAAS,OAAO,KAAK,KAAKA,EAAK,MACnFI,IAAOD,IAAe,MAAM,IAC5BE,IAAOL,EAAK,SAASG,KAAgB,KAAK,OAAO;AAEvD,SAAO,GAAGC,EAAK,SAAA,EAAW,SAAS,GAAG,GAAG,CAAC,MAAMF,CAAM,IAAIG,CAAI;AAChE,GA8BMC,IAAsD,CAAC;AAAA,EAC3D,MAAAN;AAAA,EACA,cAAAO;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,cAAAR,IAAe;AAAA,EACf,aAAAS,IAAc;AAAA,EACd,GAAGC;AACL,MAAM;AACJ,QAAM,CAACC,GAAQC,CAAS,IAAIC,EAAS,EAAK;AAE1C,SACE,gBAAAC,EAACC,GAAA,EAAQ,MAAMJ,GAAQ,cAAcC,GACnC,UAAA;AAAA,IAAA,gBAAAI,EAACC,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,WAAWC;AAAA,UACT;AAAA,UACAZ;AAAA,QAAA;AAAA,QAEF,oBAAmBR,IAAY,SAAL;AAAA,QAC1B,cAAYA,IAAO,kBAAkBD,EAAgBC,GAAMC,CAAY,CAAC,KAAKS;AAAA,QAC5E,GAAGC;AAAA,QACJ,MAAK;AAAA,QAEJ,UAAAX,IAAOD,EAAgBC,GAAMC,CAAY,IAAI;AAAA,MAAA;AAAA,IAAA,GAElD;AAAA,IACA,gBAAAgB,EAACI,KAAgB,GAAIZ,GAAY,WAAW,CAAA,GAAK,WAAWW,EAAG,sBAAsBX,GAAY,SAAS,SAAS,GACjH,UAAA,gBAAAQ,EAACK,GAAA,EAAkB,QAAAV,GAAgB,cAAAX,GAA4B,cAAAM,GAA4B,MAAAP,GAAY,YAAAS,EAAA,CAAwB,EAAA,CACjI;AAAA,EAAA,GACF;AAEJ;"}
1
+ {"version":3,"file":"desktoptimepicker.es.js","sources":["../src/components/date-picker/DesktopTimePicker.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { useState, type FC, type HTMLAttributes } from \"react\";\r\n\r\nimport { cn } from \"../../lib/utils\";\r\nimport { Button } from \"../button/Button\";\r\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover/Popover\";\r\nimport { TimePickerContent, type Time } from \"./TimePickerContent\";\r\n\r\nconst formatTimeLabel = (time: Time, is24HourMode: boolean) => {\r\n const minute = time.minute.toString().padStart(2, \"0\");\r\n\r\n if (is24HourMode) {\r\n const hour = time.ampm ? (time.hour % 12) + (time.ampm === \"PM\" ? 12 : 0) : time.hour;\r\n return `${hour.toString().padStart(2, \"0\")} : ${minute}`;\r\n }\r\n\r\n const hourFromAmpm = time.ampm ? (time.hour % 12) + (time.ampm === \"PM\" ? 12 : 0) : time.hour;\r\n const hour = hourFromAmpm % 12 || 12;\r\n const ampm = time.ampm ?? (hourFromAmpm >= 12 ? \"PM\" : \"AM\");\r\n\r\n return `${hour.toString().padStart(2, \"0\")} : ${minute} ${ampm}`;\r\n};\r\n\r\n/**\r\n * Props for the desktop-only time picker.\r\n *\r\n * In 12-hour mode, the time value should include ampm.\r\n * In 24-hour mode, the time value should omit ampm and use hour values from 0-23.\r\n */\r\ntype DesktopTimePickerProps = HTMLAttributes<HTMLButtonElement> & {\r\n /** Current time value. */\r\n time: Time | undefined;\r\n /** Called whenever the selected time changes. */\r\n onTimeChange: (time: Time | undefined) => void;\r\n /** Enables 24-hour mode and hides the AM/PM column when true. */\r\n is24HourMode?: boolean;\r\n /** Accessible label and trigger fallback when no time is selected. */\r\n placeholder?: string;\r\n /** Disables the trigger button. */\r\n disabled?: boolean;\r\n /** Props forwarded to the popover content. */\r\n slotsProps?: {\r\n /** Props forwarded to the time picker content container. */\r\n content?: HTMLAttributes<HTMLDivElement>;\r\n };\r\n};\r\n\r\n/**\r\n * Desktop-only time picker rendered in a popover.\r\n * Use this component when you want the desktop interaction regardless of screen size.\r\n */\r\nconst DesktopTimePicker: FC<DesktopTimePickerProps> = ({\r\n time,\r\n onTimeChange,\r\n className,\r\n slotsProps,\r\n is24HourMode = false,\r\n placeholder = \"Pick a Time\",\r\n ...restProps\r\n}) => {\r\n const [isOpen, setIsOpen] = useState(false);\r\n\r\n return (\r\n <Popover open={isOpen} onOpenChange={setIsOpen}>\r\n <PopoverTrigger asChild>\r\n <Button\r\n variant=\"text\"\r\n className={cn(\r\n \"mtx-flex mtx-h-8 mtx-w-full mtx-items-center mtx-justify-between mtx-whitespace-nowrap mtx-rounded-sm mtx-border mtx-border-input mtx-bg-transparent mtx-ps-3 mtx-pe-1 mtx-py-1.5 mtx-text-xs mtx-ring-offset-background data-[placeholder]:mtx-text-muted-foreground hover:mtx-border hover:mtx-border-primary hover:mtx-bg-transparent focus:mtx-border focus:mtx-border-primary focus:mtx-outline-none focus:mtx-ring focus:mtx-ring-primary-100 disabled:mtx-cursor-not-allowed disabled:mtx-bg-gray-100 disabled:mtx-text-text-300 disabled:mtx-border-gray-100 [&>span]:mtx-line-clamp-1 [&_svg]:disabled:mtx-text-text-300\",\r\n className,\r\n )}\r\n data-placeholder={!time ? \"\" : undefined}\r\n aria-label={time ? `Selected time: ${formatTimeLabel(time, is24HourMode)}` : placeholder}\r\n {...restProps}\r\n type=\"button\"\r\n >\r\n {time ? formatTimeLabel(time, is24HourMode) : \"-- : --\"}\r\n </Button>\r\n </PopoverTrigger>\r\n <PopoverContent {...(slotsProps?.content ?? {})} className={cn(\"mtx-w-auto mtx-p-0\", slotsProps?.content?.className)}>\r\n <TimePickerContent isOpen={isOpen} is24HourMode={is24HourMode} onTimeChange={onTimeChange} time={time} slotsProps={slotsProps} />\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n};\r\nexport { DesktopTimePicker, type DesktopTimePickerProps };\r\n"],"names":["formatTimeLabel","time","is24HourMode","minute","hourFromAmpm","hour","ampm","DesktopTimePicker","onTimeChange","className","slotsProps","placeholder","restProps","isOpen","setIsOpen","useState","jsxs","Popover","jsx","PopoverTrigger","Button","cn","PopoverContent","TimePickerContent"],"mappings":";;;;;;AASA,MAAMA,IAAkB,CAACC,GAAYC,MAA0B;AAC7D,QAAMC,IAASF,EAAK,OAAO,WAAW,SAAS,GAAG,GAAG;AAErD,MAAIC;AAEF,WAAO,IADMD,EAAK,OAAQA,EAAK,OAAO,MAAOA,EAAK,SAAS,OAAO,KAAK,KAAKA,EAAK,MAClE,WAAW,SAAS,GAAG,GAAG,CAAC,MAAME,CAAM;AAGxD,QAAMC,IAAeH,EAAK,OAAQA,EAAK,OAAO,MAAOA,EAAK,SAAS,OAAO,KAAK,KAAKA,EAAK,MACnFI,IAAOD,IAAe,MAAM,IAC5BE,IAAOL,EAAK,SAASG,KAAgB,KAAK,OAAO;AAEvD,SAAO,GAAGC,EAAK,SAAA,EAAW,SAAS,GAAG,GAAG,CAAC,MAAMF,CAAM,IAAIG,CAAI;AAChE,GA8BMC,IAAgD,CAAC;AAAA,EACrD,MAAAN;AAAA,EACA,cAAAO;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,cAAAR,IAAe;AAAA,EACf,aAAAS,IAAc;AAAA,EACd,GAAGC;AACL,MAAM;AACJ,QAAM,CAACC,GAAQC,CAAS,IAAIC,EAAS,EAAK;AAE1C,SACE,gBAAAC,EAACC,GAAA,EAAQ,MAAMJ,GAAQ,cAAcC,GACnC,UAAA;AAAA,IAAA,gBAAAI,EAACC,GAAA,EAAe,SAAO,IACrB,UAAA,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,SAAQ;AAAA,QACR,WAAWC;AAAA,UACT;AAAA,UACAZ;AAAA,QAAA;AAAA,QAEF,oBAAmBR,IAAY,SAAL;AAAA,QAC1B,cAAYA,IAAO,kBAAkBD,EAAgBC,GAAMC,CAAY,CAAC,KAAKS;AAAA,QAC5E,GAAGC;AAAA,QACJ,MAAK;AAAA,QAEJ,UAAAX,IAAOD,EAAgBC,GAAMC,CAAY,IAAI;AAAA,MAAA;AAAA,IAAA,GAElD;AAAA,IACA,gBAAAgB,EAACI,KAAgB,GAAIZ,GAAY,WAAW,CAAA,GAAK,WAAWW,EAAG,sBAAsBX,GAAY,SAAS,SAAS,GACjH,UAAA,gBAAAQ,EAACK,GAAA,EAAkB,QAAAV,GAAgB,cAAAX,GAA4B,cAAAM,GAA4B,MAAAP,GAAY,YAAAS,EAAA,CAAwB,EAAA,CACjI;AAAA,EAAA,GACF;AAEJ;"}
@@ -48,7 +48,7 @@ const H = F({
48
48
  e.preventDefault();
49
49
  const r = e.currentTarget, n = r.selectionStart ?? 0;
50
50
  if (n === 0) return;
51
- let a = "", t = n - 1;
51
+ let a, t = n - 1;
52
52
  if (l[n - 1] === ":")
53
53
  a = `${l.substring(0, n - 2)}0${l.substring(n - 1)}`, t = n - 2;
54
54
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"duration.es.js","sources":["../src/components/duration/Duration.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { tv, VariantProps } from \"tailwind-variants\";\r\n\r\nimport { cn } from \"../../lib/utils\";\r\n\r\nconst textFieldVariants = tv({\r\n base: [\r\n \"mtx-flex mtx-items-center mtx-w-full mtx-rounded-sm mtx-border mtx-border-input mtx-text-text mtx-bg-transparent mtx-p-0 mtx-text-xs [&_input]:mtx-text-xs mtx-font-medium mtx-transition-colors file:mtx-border-0 file:mtx-bg-transparent file:mtx-text-sm file:mtx-font-medium file:mtx-text-foreground\",\r\n \"placeholder:mtx-text-text-300 hover:mtx-border-primary-400 focus-within:mtx-border-primary-400 focus-within:mtx-outline-none focus-within:mtx-ring focus-within:mtx-ring-primary-100\",\r\n \"aria-disabled:mtx-text-text-300 aria-disabled:mtx-bg-gray-100 aria-disabled:mtx-border-gray-100\",\r\n ],\r\n variants: {\r\n size: {\r\n sm: \"mtx-h-7\",\r\n md: \"mtx-h-8\",\r\n lg: \"mtx-h-11\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n },\r\n});\r\n\r\ninterface DurationProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof textFieldVariants> {\r\n disabled?: boolean;\r\n endAdornment?: React.ReactNode;\r\n startAdornment?: React.ReactNode;\r\n onChange?: React.ChangeEventHandler<HTMLInputElement>;\r\n value?: string;\r\n defaultValue?: string;\r\n showSeconds?: boolean;\r\n slotProps?: {\r\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\r\n };\r\n}\r\n\r\nconst Duration = React.forwardRef<HTMLInputElement, DurationProps>(\r\n (\r\n { className, slotProps, endAdornment, startAdornment, size, value: _value, onChange, defaultValue, disabled, showSeconds = false, ...props },\r\n ref,\r\n ) => {\r\n const getFormattedValue = React.useCallback(\r\n (val: string) => {\r\n const digits = val.replace(/\\D/g, \"\");\r\n const maxLength = showSeconds ? 6 : 4;\r\n const limitedDigits = digits.substring(0, maxLength).padEnd(maxLength, \"0\");\r\n\r\n let hours = limitedDigits.substring(0, 2);\r\n let minutes = limitedDigits.substring(2, 4);\r\n let seconds = showSeconds ? limitedDigits.substring(4, 6) : \"\";\r\n\r\n if (parseInt(hours, 10) > 23) hours = \"23\";\r\n if (parseInt(minutes, 10) > 59) minutes = \"59\";\r\n if (showSeconds && parseInt(seconds, 10) > 59) seconds = \"59\";\r\n\r\n let formatted = hours;\r\n if (maxLength >= 4) formatted += `:${minutes}`;\r\n if (showSeconds) formatted += `:${seconds}`;\r\n\r\n return formatted;\r\n },\r\n [showSeconds],\r\n );\r\n\r\n const [value, setValue] = React.useState(() => getFormattedValue(defaultValue || \"\"));\r\n const inputRef = React.useRef<HTMLInputElement>(null);\r\n\r\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\r\n\r\n React.useEffect(() => {\r\n if (_value !== undefined) {\r\n setValue(getFormattedValue(_value));\r\n }\r\n }, [_value, getFormattedValue]);\r\n\r\n const handleNumericInput = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const input = e.currentTarget;\r\n const { key } = e;\r\n const selection = input.selectionStart ?? 0;\r\n const nextValue = value.substring(0, selection) + key + value.substring(selection + 1);\r\n const formatted = getFormattedValue(nextValue);\r\n setValue(formatted);\r\n\r\n if (onChange) {\r\n const syntheticEvent = { ...e, target: { ...e.target, value: formatted } };\r\n onChange(syntheticEvent as unknown as React.ChangeEvent<HTMLInputElement>);\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n let nextCursor = selection + 1;\r\n if (formatted[nextCursor] === \":\") {\r\n nextCursor++;\r\n }\r\n input.setSelectionRange(nextCursor, nextCursor);\r\n });\r\n };\r\n\r\n const handleBackspace = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const input = e.currentTarget;\r\n const selection = input.selectionStart ?? 0;\r\n if (selection === 0) return;\r\n\r\n let nextValue = \"\";\r\n let nextCursor = selection - 1;\r\n\r\n if (value[selection - 1] === \":\") {\r\n nextValue = `${value.substring(0, selection - 2)}0${value.substring(selection - 1)}`;\r\n nextCursor = selection - 2;\r\n } else {\r\n const currentValue = value.replace(/\\D/g, \"\");\r\n const cursorIndex = selection - Math.floor((selection - 1) / 3);\r\n const nextDigits = `${currentValue.substring(0, cursorIndex - 1)}0${currentValue.substring(cursorIndex)}`;\r\n nextValue = getFormattedValue(nextDigits);\r\n }\r\n\r\n const formatted = getFormattedValue(nextValue);\r\n setValue(formatted);\r\n\r\n if (onChange) {\r\n const syntheticEvent = { ...e, target: { ...e.target, value: formatted } };\r\n onChange(syntheticEvent as unknown as React.ChangeEvent<HTMLInputElement>);\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n input.setSelectionRange(nextCursor, nextCursor);\r\n });\r\n };\r\n\r\n const handleArrowKey = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const input = e.currentTarget;\r\n const { key } = e;\r\n const increment = key === \"ArrowUp\" ? 1 : -1;\r\n const parts = value.split(\":\").map(Number);\r\n const selection = input.selectionStart ?? 0;\r\n\r\n if (selection <= 2) {\r\n // Hours\r\n parts[0] = (parts[0] + increment + 24) % 24;\r\n } else if (selection >= 3 && selection <= 5) {\r\n // Minutes\r\n const newMinutes = parts[1] + increment;\r\n if (newMinutes >= 60) {\r\n parts[0] = (parts[0] + 1) % 24;\r\n parts[1] = newMinutes % 60;\r\n } else if (newMinutes < 0) {\r\n parts[0] = (parts[0] - 1 + 24) % 24;\r\n parts[1] = 59;\r\n } else {\r\n parts[1] = newMinutes;\r\n }\r\n } else if (showSeconds && selection >= 6) {\r\n // Seconds\r\n const newSeconds = parts[2] + increment;\r\n if (newSeconds >= 60) {\r\n parts[1] += 1;\r\n parts[2] = newSeconds % 60;\r\n } else if (newSeconds < 0) {\r\n parts[1] -= 1;\r\n parts[2] = 59;\r\n } else {\r\n parts[2] = newSeconds;\r\n }\r\n\r\n if (parts[1] >= 60) {\r\n parts[0] = (parts[0] + 1) % 24;\r\n parts[1] %= 60;\r\n } else if (parts[1] < 0) {\r\n parts[0] = (parts[0] - 1 + 24) % 24;\r\n parts[1] = 59;\r\n }\r\n }\r\n\r\n const newValue = parts.map(part => String(part).padStart(2, \"0\")).join(\":\");\r\n setValue(newValue);\r\n if (onChange) {\r\n onChange({ target: { value: newValue } } as React.ChangeEvent<HTMLInputElement>);\r\n }\r\n requestAnimationFrame(() => {\r\n input.setSelectionRange(selection, selection);\r\n });\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n const { key, currentTarget } = e;\r\n const { selectionStart, selectionEnd } = currentTarget;\r\n\r\n if (key.length === 1 && /\\d/.test(key)) {\r\n handleNumericInput(e);\r\n } else if (key === \"Backspace\") {\r\n handleBackspace(e);\r\n } else if (key === \"ArrowUp\" || key === \"ArrowDown\") {\r\n handleArrowKey(e);\r\n } else if (key === \"ArrowRight\" || key === \"ArrowLeft\" || key.length > 1 || selectionStart !== selectionEnd) {\r\n // Allow navigation, control keys, and replacing a selection\r\n } else {\r\n e.preventDefault();\r\n }\r\n };\r\n\r\n return (\r\n <div {...props} className={cn(textFieldVariants({ size, className }))} aria-disabled={disabled}>\r\n {startAdornment}\r\n <input\r\n type=\"text\"\r\n inputMode=\"numeric\"\r\n ref={inputRef}\r\n onKeyDown={handleKeyDown}\r\n onChange={() => {}}\r\n value={value}\r\n placeholder={showSeconds ? \"HH:MM:SS\" : \"HH:MM\"}\r\n disabled={disabled}\r\n {...(slotProps?.inputProps ?? {})}\r\n className={cn(\r\n \"focus:mtx-outline-none mtx-w-full mtx-h-full mtx-py-1 mtx-rounded-sm file:mtx-border-0 file:mtx-bg-transparent file:mtx-text-sm file:mtx-font-medium file:mtx-text-foreground placeholder:mtx-text-text-300\",\r\n !startAdornment ? \"mtx-px-3\" : \"mtx-ps-1 mtx-pe-3\",\r\n slotProps?.inputProps?.className,\r\n )}\r\n />\r\n\r\n {endAdornment}\r\n </div>\r\n );\r\n },\r\n);\r\nDuration.displayName = \"Duration\";\r\n\r\nexport { Duration, type DurationProps };\r\n"],"names":["textFieldVariants","tv","Duration","React","className","slotProps","endAdornment","startAdornment","size","_value","onChange","defaultValue","disabled","showSeconds","props","ref","getFormattedValue","val","digits","maxLength","limitedDigits","hours","minutes","seconds","formatted","value","setValue","inputRef","handleNumericInput","input","key","selection","nextValue","syntheticEvent","nextCursor","handleBackspace","currentValue","cursorIndex","nextDigits","handleArrowKey","increment","parts","newMinutes","newSeconds","newValue","part","handleKeyDown","currentTarget","selectionStart","selectionEnd","jsxs","cn","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"duration.es.js","sources":["../src/components/duration/Duration.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport * as React from \"react\";\r\nimport { tv, VariantProps } from \"tailwind-variants\";\r\n\r\nimport { cn } from \"../../lib/utils\";\r\n\r\nconst textFieldVariants = tv({\r\n base: [\r\n \"mtx-flex mtx-items-center mtx-w-full mtx-rounded-sm mtx-border mtx-border-input mtx-text-text mtx-bg-transparent mtx-p-0 mtx-text-xs [&_input]:mtx-text-xs mtx-font-medium mtx-transition-colors file:mtx-border-0 file:mtx-bg-transparent file:mtx-text-sm file:mtx-font-medium file:mtx-text-foreground\",\r\n \"placeholder:mtx-text-text-300 hover:mtx-border-primary-400 focus-within:mtx-border-primary-400 focus-within:mtx-outline-none focus-within:mtx-ring focus-within:mtx-ring-primary-100\",\r\n \"aria-disabled:mtx-text-text-300 aria-disabled:mtx-bg-gray-100 aria-disabled:mtx-border-gray-100\",\r\n ],\r\n variants: {\r\n size: {\r\n sm: \"mtx-h-7\",\r\n md: \"mtx-h-8\",\r\n lg: \"mtx-h-11\",\r\n },\r\n },\r\n defaultVariants: {\r\n size: \"md\",\r\n },\r\n});\r\n\r\ninterface DurationProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof textFieldVariants> {\r\n disabled?: boolean;\r\n endAdornment?: React.ReactNode;\r\n startAdornment?: React.ReactNode;\r\n onChange?: React.ChangeEventHandler<HTMLInputElement>;\r\n value?: string;\r\n defaultValue?: string;\r\n showSeconds?: boolean;\r\n slotProps?: {\r\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\r\n };\r\n}\r\n\r\nconst Duration = React.forwardRef<HTMLInputElement, DurationProps>(\r\n (\r\n { className, slotProps, endAdornment, startAdornment, size, value: _value, onChange, defaultValue, disabled, showSeconds = false, ...props },\r\n ref,\r\n ) => {\r\n const getFormattedValue = React.useCallback(\r\n (val: string) => {\r\n const digits = val.replace(/\\D/g, \"\");\r\n const maxLength = showSeconds ? 6 : 4;\r\n const limitedDigits = digits.substring(0, maxLength).padEnd(maxLength, \"0\");\r\n\r\n let hours = limitedDigits.substring(0, 2);\r\n let minutes = limitedDigits.substring(2, 4);\r\n let seconds = showSeconds ? limitedDigits.substring(4, 6) : \"\";\r\n\r\n if (parseInt(hours, 10) > 23) hours = \"23\";\r\n if (parseInt(minutes, 10) > 59) minutes = \"59\";\r\n if (showSeconds && parseInt(seconds, 10) > 59) seconds = \"59\";\r\n\r\n let formatted = hours;\r\n if (maxLength >= 4) formatted += `:${minutes}`;\r\n if (showSeconds) formatted += `:${seconds}`;\r\n\r\n return formatted;\r\n },\r\n [showSeconds],\r\n );\r\n\r\n const [value, setValue] = React.useState(() => getFormattedValue(defaultValue || \"\"));\r\n const inputRef = React.useRef<HTMLInputElement>(null);\r\n\r\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\r\n\r\n React.useEffect(() => {\r\n if (_value !== undefined) {\r\n setValue(getFormattedValue(_value));\r\n }\r\n }, [_value, getFormattedValue]);\r\n\r\n const handleNumericInput = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const input = e.currentTarget;\r\n const { key } = e;\r\n const selection = input.selectionStart ?? 0;\r\n const nextValue = value.substring(0, selection) + key + value.substring(selection + 1);\r\n const formatted = getFormattedValue(nextValue);\r\n setValue(formatted);\r\n\r\n if (onChange) {\r\n const syntheticEvent = { ...e, target: { ...e.target, value: formatted } };\r\n onChange(syntheticEvent as unknown as React.ChangeEvent<HTMLInputElement>);\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n let nextCursor = selection + 1;\r\n if (formatted[nextCursor] === \":\") {\r\n nextCursor++;\r\n }\r\n input.setSelectionRange(nextCursor, nextCursor);\r\n });\r\n };\r\n\r\n const handleBackspace = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const input = e.currentTarget;\r\n const selection = input.selectionStart ?? 0;\r\n if (selection === 0) return;\r\n\r\n let nextValue: string;\r\n let nextCursor = selection - 1;\r\n\r\n if (value[selection - 1] === \":\") {\r\n nextValue = `${value.substring(0, selection - 2)}0${value.substring(selection - 1)}`;\r\n nextCursor = selection - 2;\r\n } else {\r\n const currentValue = value.replace(/\\D/g, \"\");\r\n const cursorIndex = selection - Math.floor((selection - 1) / 3);\r\n const nextDigits = `${currentValue.substring(0, cursorIndex - 1)}0${currentValue.substring(cursorIndex)}`;\r\n nextValue = getFormattedValue(nextDigits);\r\n }\r\n\r\n const formatted = getFormattedValue(nextValue);\r\n setValue(formatted);\r\n\r\n if (onChange) {\r\n const syntheticEvent = { ...e, target: { ...e.target, value: formatted } };\r\n onChange(syntheticEvent as unknown as React.ChangeEvent<HTMLInputElement>);\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n input.setSelectionRange(nextCursor, nextCursor);\r\n });\r\n };\r\n\r\n const handleArrowKey = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n e.preventDefault();\r\n const input = e.currentTarget;\r\n const { key } = e;\r\n const increment = key === \"ArrowUp\" ? 1 : -1;\r\n const parts = value.split(\":\").map(Number);\r\n const selection = input.selectionStart ?? 0;\r\n\r\n if (selection <= 2) {\r\n // Hours\r\n parts[0] = (parts[0] + increment + 24) % 24;\r\n } else if (selection >= 3 && selection <= 5) {\r\n // Minutes\r\n const newMinutes = parts[1] + increment;\r\n if (newMinutes >= 60) {\r\n parts[0] = (parts[0] + 1) % 24;\r\n parts[1] = newMinutes % 60;\r\n } else if (newMinutes < 0) {\r\n parts[0] = (parts[0] - 1 + 24) % 24;\r\n parts[1] = 59;\r\n } else {\r\n parts[1] = newMinutes;\r\n }\r\n } else if (showSeconds && selection >= 6) {\r\n // Seconds\r\n const newSeconds = parts[2] + increment;\r\n if (newSeconds >= 60) {\r\n parts[1] += 1;\r\n parts[2] = newSeconds % 60;\r\n } else if (newSeconds < 0) {\r\n parts[1] -= 1;\r\n parts[2] = 59;\r\n } else {\r\n parts[2] = newSeconds;\r\n }\r\n\r\n if (parts[1] >= 60) {\r\n parts[0] = (parts[0] + 1) % 24;\r\n parts[1] %= 60;\r\n } else if (parts[1] < 0) {\r\n parts[0] = (parts[0] - 1 + 24) % 24;\r\n parts[1] = 59;\r\n }\r\n }\r\n\r\n const newValue = parts.map(part => String(part).padStart(2, \"0\")).join(\":\");\r\n setValue(newValue);\r\n if (onChange) {\r\n onChange({ target: { value: newValue } } as React.ChangeEvent<HTMLInputElement>);\r\n }\r\n requestAnimationFrame(() => {\r\n input.setSelectionRange(selection, selection);\r\n });\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n const { key, currentTarget } = e;\r\n const { selectionStart, selectionEnd } = currentTarget;\r\n\r\n if (key.length === 1 && /\\d/.test(key)) {\r\n handleNumericInput(e);\r\n } else if (key === \"Backspace\") {\r\n handleBackspace(e);\r\n } else if (key === \"ArrowUp\" || key === \"ArrowDown\") {\r\n handleArrowKey(e);\r\n } else if (key === \"ArrowRight\" || key === \"ArrowLeft\" || key.length > 1 || selectionStart !== selectionEnd) {\r\n // Allow navigation, control keys, and replacing a selection\r\n } else {\r\n e.preventDefault();\r\n }\r\n };\r\n\r\n return (\r\n <div {...props} className={cn(textFieldVariants({ size, className }))} aria-disabled={disabled}>\r\n {startAdornment}\r\n <input\r\n type=\"text\"\r\n inputMode=\"numeric\"\r\n ref={inputRef}\r\n onKeyDown={handleKeyDown}\r\n onChange={() => {}}\r\n value={value}\r\n placeholder={showSeconds ? \"HH:MM:SS\" : \"HH:MM\"}\r\n disabled={disabled}\r\n {...(slotProps?.inputProps ?? {})}\r\n className={cn(\r\n \"focus:mtx-outline-none mtx-w-full mtx-h-full mtx-py-1 mtx-rounded-sm file:mtx-border-0 file:mtx-bg-transparent file:mtx-text-sm file:mtx-font-medium file:mtx-text-foreground placeholder:mtx-text-text-300\",\r\n !startAdornment ? \"mtx-px-3\" : \"mtx-ps-1 mtx-pe-3\",\r\n slotProps?.inputProps?.className,\r\n )}\r\n />\r\n\r\n {endAdornment}\r\n </div>\r\n );\r\n },\r\n);\r\nDuration.displayName = \"Duration\";\r\n\r\nexport { Duration, type DurationProps };\r\n"],"names":["textFieldVariants","tv","Duration","React","className","slotProps","endAdornment","startAdornment","size","_value","onChange","defaultValue","disabled","showSeconds","props","ref","getFormattedValue","val","digits","maxLength","limitedDigits","hours","minutes","seconds","formatted","value","setValue","inputRef","handleNumericInput","input","key","selection","nextValue","syntheticEvent","nextCursor","handleBackspace","currentValue","cursorIndex","nextDigits","handleArrowKey","increment","parts","newMinutes","newSeconds","newValue","part","handleKeyDown","currentTarget","selectionStart","selectionEnd","jsxs","cn","jsx"],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ const $ = /^(\d{4})-(\d{2})-(\d{2})$/, g = (t, e, n) => {
2
+ const r = /* @__PURE__ */ new Date(0);
3
+ return r.setFullYear(t, e, n), r.setHours(0, 0, 0, 0), r;
4
+ }, D = (t) => g(t.getFullYear(), t.getMonth(), t.getDate()), m = (t, e) => g(t.getFullYear(), t.getMonth(), t.getDate() + e), p = (t, e) => g(t.getFullYear(), t.getMonth() + e, 1), Y = (t) => {
5
+ const e = D(t), n = (e.getDay() + 6) % 7;
6
+ return m(e, -n);
7
+ }, b = (t) => g(t.getFullYear(), t.getMonth(), 1), I = (t) => g(t.getFullYear(), Math.floor(t.getMonth() / 3) * 3, 1), y = (t, e) => e === "week" ? Y(t) : e === "month" ? b(t) : I(t), F = (t, e) => e === "week" ? m(t, 7) : e === "month" ? p(t, 1) : p(t, 3), f = (t, e, n = "short") => new Intl.DateTimeFormat(e, { month: n }).format(t), N = (t, e, n, r) => {
8
+ if (n === "quarter")
9
+ return `${f(t, r)}–${f(m(e, -1), r)}`.toUpperCase();
10
+ if (n === "month")
11
+ return f(t, r).toUpperCase();
12
+ const o = m(e, -1);
13
+ return t.getMonth() === o.getMonth() ? `${t.getDate()}–${o.getDate()}` : `${f(t, r)} ${t.getDate()}–${f(o, r)} ${o.getDate()}`;
14
+ }, k = (t, e, n) => e === "week" ? {
15
+ key: `${t.getFullYear()}-${t.getMonth()}`,
16
+ label: `${f(t, n, "long")} ${t.getFullYear()}`
17
+ } : { key: String(t.getFullYear()), label: String(t.getFullYear()) }, c = (t) => {
18
+ if (t === void 0) return null;
19
+ if (t instanceof Date)
20
+ return Number.isNaN(t.getTime()) ? null : D(t);
21
+ const e = $.exec(t);
22
+ if (e) {
23
+ const r = Number(e[1]), o = Number(e[2]) - 1, u = Number(e[3]), s = g(r, o, u);
24
+ return s.getFullYear() !== r || s.getMonth() !== o || s.getDate() !== u ? null : s;
25
+ }
26
+ const n = new Date(t);
27
+ return Number.isNaN(n.getTime()) ? null : D(n);
28
+ }, x = () => {
29
+ const t = /* @__PURE__ */ new Date();
30
+ return {
31
+ start: g(t.getFullYear(), 0, 1),
32
+ end: g(t.getFullYear(), 11, 31)
33
+ };
34
+ }, O = (t, e, n) => {
35
+ const r = t.flatMap((a) => [c(a.start), c(a.end)]).filter((a) => a !== null), o = x();
36
+ let u = c(e) ?? (r.length > 0 ? new Date(Math.min(...r.map((a) => a.getTime()))) : o.start), s = c(n) ?? (r.length > 0 ? new Date(Math.max(...r.map((a) => a.getTime()))) : o.end);
37
+ return s < u && ([u, s] = [s, u]), { start: u, end: s };
38
+ }, P = (t, e, n, r) => {
39
+ const o = [], u = y(t, n), s = F(y(e, n), n);
40
+ let a = u;
41
+ for (; a < s; ) {
42
+ const l = F(a, n), i = k(a, n, r);
43
+ o.push({
44
+ start: a,
45
+ end: l,
46
+ label: N(a, l, n, r),
47
+ groupKey: i.key,
48
+ groupLabel: i.label
49
+ }), a = l;
50
+ }
51
+ const h = o.reduce((l, i, T) => {
52
+ const M = l.at(-1);
53
+ return M?.key === i.groupKey ? M.intervalCount += 1 : l.push({ key: i.groupKey, label: i.groupLabel, startIndex: T, intervalCount: 1 }), l;
54
+ }, []);
55
+ return { intervals: o, groups: h };
56
+ }, d = (t, e) => {
57
+ if (e.length === 0) return 0;
58
+ const n = e[0], r = e.at(-1);
59
+ if (t <= n.start) return 0;
60
+ if (t >= r.end) return 100;
61
+ const o = e.findIndex((a) => t >= a.start && t < a.end);
62
+ if (o < 0) return 0;
63
+ const u = e[o], s = (t.getTime() - u.start.getTime()) / (u.end.getTime() - u.start.getTime());
64
+ return (o + s) / e.length * 100;
65
+ }, R = (t, e) => {
66
+ if (e.length === 0) return null;
67
+ const n = e[0], r = e.at(-1);
68
+ return t < n.start || t >= r.end ? null : d(t, e);
69
+ }, E = (t, e) => {
70
+ const n = c(t.start), r = c(t.end);
71
+ if (!n || !r) return null;
72
+ const o = n <= r ? n : r, u = n <= r ? r : n, s = d(o, e), a = d(m(u, 1), e);
73
+ if (a <= 0 || s >= 100) return null;
74
+ const h = Math.max(0, s), l = Math.min(100, a);
75
+ return { left: h, width: Math.max(0, l - h) };
76
+ }, L = (t = 0) => Math.min(100, Math.max(0, t)), w = (t, e) => {
77
+ const n = c(t.start), r = c(t.end);
78
+ if (!n || !r) return "Invalid date";
79
+ const o = new Intl.DateTimeFormat(e, { month: "short", day: "numeric" });
80
+ return `${o.format(n)}–${o.format(r)}`;
81
+ }, C = (t, e) => !!(e && e >= t.start && e < t.end);
82
+ export {
83
+ m as addDays,
84
+ L as clampProgress,
85
+ P as createTimeline,
86
+ w as formatDateRange,
87
+ E as getBarPosition,
88
+ R as getMarkerPosition,
89
+ O as getTimelineRange,
90
+ C as includesDate,
91
+ c as toDate
92
+ };
93
+ //# sourceMappingURL=gantt-chart.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gantt-chart.es.js","sources":["../src/components/gantt-chart/gantt-chart.utils.ts"],"sourcesContent":["import type { GanttDate, GanttItem, GanttView } from \"./gantt-chart.types\";\n\nconst DATE_ONLY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\ntype TimelineInterval = {\n start: Date;\n end: Date;\n label: string;\n groupKey: string;\n groupLabel: string;\n};\n\ntype TimelineGroup = {\n key: string;\n label: string;\n startIndex: number;\n intervalCount: number;\n};\n\nconst createDate = (year: number, month: number, day: number) => {\n const date = new Date(0);\n\n date.setFullYear(year, month, day);\n date.setHours(0, 0, 0, 0);\n\n return date;\n};\n\nconst startOfDay = (date: Date) => createDate(date.getFullYear(), date.getMonth(), date.getDate());\n\nconst addDays = (date: Date, amount: number) => createDate(date.getFullYear(), date.getMonth(), date.getDate() + amount);\n\nconst addMonths = (date: Date, amount: number) => createDate(date.getFullYear(), date.getMonth() + amount, 1);\n\nconst startOfWeek = (date: Date) => {\n const normalizedDate = startOfDay(date);\n const dayFromMonday = (normalizedDate.getDay() + 6) % 7;\n\n return addDays(normalizedDate, -dayFromMonday);\n};\n\nconst startOfMonth = (date: Date) => createDate(date.getFullYear(), date.getMonth(), 1);\n\nconst startOfQuarter = (date: Date) => createDate(date.getFullYear(), Math.floor(date.getMonth() / 3) * 3, 1);\n\nconst getIntervalStart = (date: Date, view: GanttView) => {\n if (view === \"week\") return startOfWeek(date);\n if (view === \"month\") return startOfMonth(date);\n\n return startOfQuarter(date);\n};\n\nconst addInterval = (date: Date, view: GanttView) => {\n if (view === \"week\") return addDays(date, 7);\n if (view === \"month\") return addMonths(date, 1);\n\n return addMonths(date, 3);\n};\n\nconst formatMonth = (date: Date, locale: string, format: \"short\" | \"long\" = \"short\") =>\n new Intl.DateTimeFormat(locale, { month: format }).format(date);\n\nconst formatIntervalLabel = (start: Date, end: Date, view: GanttView, locale: string) => {\n if (view === \"quarter\") {\n return `${formatMonth(start, locale)}–${formatMonth(addDays(end, -1), locale)}`.toUpperCase();\n }\n\n if (view === \"month\") {\n return formatMonth(start, locale).toUpperCase();\n }\n\n const inclusiveEnd = addDays(end, -1);\n\n if (start.getMonth() === inclusiveEnd.getMonth()) {\n return `${start.getDate()}–${inclusiveEnd.getDate()}`;\n }\n\n return `${formatMonth(start, locale)} ${start.getDate()}–${formatMonth(inclusiveEnd, locale)} ${inclusiveEnd.getDate()}`;\n};\n\nconst getGroupDetails = (date: Date, view: GanttView, locale: string) => {\n if (view === \"week\") {\n return {\n key: `${date.getFullYear()}-${date.getMonth()}`,\n label: `${formatMonth(date, locale, \"long\")} ${date.getFullYear()}`,\n };\n }\n\n return { key: String(date.getFullYear()), label: String(date.getFullYear()) };\n};\n\nconst toDate = (value: GanttDate | undefined) => {\n if (value === undefined) return null;\n\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? null : startOfDay(value);\n }\n\n const dateOnlyMatch = DATE_ONLY_PATTERN.exec(value);\n\n if (dateOnlyMatch) {\n const year = Number(dateOnlyMatch[1]);\n const month = Number(dateOnlyMatch[2]) - 1;\n const day = Number(dateOnlyMatch[3]);\n const date = createDate(year, month, day);\n\n if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) {\n return null;\n }\n\n return date;\n }\n\n const date = new Date(value);\n\n return Number.isNaN(date.getTime()) ? null : startOfDay(date);\n};\n\nconst getDefaultRange = () => {\n const today = new Date();\n\n return {\n start: createDate(today.getFullYear(), 0, 1),\n end: createDate(today.getFullYear(), 11, 31),\n };\n};\n\nconst getTimelineRange = (items: GanttItem[], startDate?: GanttDate, endDate?: GanttDate) => {\n const validDates = items.flatMap(item => [toDate(item.start), toDate(item.end)]).filter((date): date is Date => date !== null);\n const defaultRange = getDefaultRange();\n let start = toDate(startDate) ?? (validDates.length > 0 ? new Date(Math.min(...validDates.map(date => date.getTime()))) : defaultRange.start);\n let end = toDate(endDate) ?? (validDates.length > 0 ? new Date(Math.max(...validDates.map(date => date.getTime()))) : defaultRange.end);\n\n if (end < start) {\n [start, end] = [end, start];\n }\n\n return { start, end };\n};\n\nconst createTimeline = (rangeStart: Date, rangeEnd: Date, view: GanttView, locale: string) => {\n const intervals: TimelineInterval[] = [];\n const start = getIntervalStart(rangeStart, view);\n const end = addInterval(getIntervalStart(rangeEnd, view), view);\n let cursor = start;\n\n while (cursor < end) {\n const intervalEnd = addInterval(cursor, view);\n const group = getGroupDetails(cursor, view, locale);\n\n intervals.push({\n start: cursor,\n end: intervalEnd,\n label: formatIntervalLabel(cursor, intervalEnd, view, locale),\n groupKey: group.key,\n groupLabel: group.label,\n });\n cursor = intervalEnd;\n }\n\n const groups = intervals.reduce<TimelineGroup[]>((result, interval, index) => {\n const currentGroup = result.at(-1);\n\n if (currentGroup?.key === interval.groupKey) {\n currentGroup.intervalCount += 1;\n } else {\n result.push({ key: interval.groupKey, label: interval.groupLabel, startIndex: index, intervalCount: 1 });\n }\n\n return result;\n }, []);\n\n return { intervals, groups };\n};\n\nconst getDatePosition = (date: Date, intervals: TimelineInterval[]) => {\n if (intervals.length === 0) return 0;\n\n const firstInterval = intervals[0];\n const lastInterval = intervals.at(-1) as TimelineInterval;\n\n if (date <= firstInterval.start) return 0;\n if (date >= lastInterval.end) return 100;\n\n const intervalIndex = intervals.findIndex(interval => date >= interval.start && date < interval.end);\n\n if (intervalIndex < 0) return 0;\n\n const interval = intervals[intervalIndex];\n const intervalProgress = (date.getTime() - interval.start.getTime()) / (interval.end.getTime() - interval.start.getTime());\n\n return ((intervalIndex + intervalProgress) / intervals.length) * 100;\n};\n\nconst getMarkerPosition = (date: Date, intervals: TimelineInterval[]) => {\n if (intervals.length === 0) return null;\n\n const firstInterval = intervals[0];\n const lastInterval = intervals.at(-1) as TimelineInterval;\n\n if (date < firstInterval.start || date >= lastInterval.end) return null;\n\n return getDatePosition(date, intervals);\n};\n\nconst getBarPosition = (item: GanttItem, intervals: TimelineInterval[]) => {\n const itemStart = toDate(item.start);\n const itemEnd = toDate(item.end);\n\n if (!itemStart || !itemEnd) return null;\n\n const start = itemStart <= itemEnd ? itemStart : itemEnd;\n const end = itemStart <= itemEnd ? itemEnd : itemStart;\n const left = getDatePosition(start, intervals);\n const right = getDatePosition(addDays(end, 1), intervals);\n\n if (right <= 0 || left >= 100) return null;\n\n const clampedLeft = Math.max(0, left);\n const clampedRight = Math.min(100, right);\n\n return { left: clampedLeft, width: Math.max(0, clampedRight - clampedLeft) };\n};\n\nconst clampProgress = (progress = 0) => Math.min(100, Math.max(0, progress));\n\nconst formatDateRange = (item: GanttItem, locale: string) => {\n const start = toDate(item.start);\n const end = toDate(item.end);\n\n if (!start || !end) return \"Invalid date\";\n\n const formatter = new Intl.DateTimeFormat(locale, { month: \"short\", day: \"numeric\" });\n\n return `${formatter.format(start)}–${formatter.format(end)}`;\n};\n\nconst includesDate = (interval: TimelineInterval, date: Date | null) => Boolean(date && date >= interval.start && date < interval.end);\n\nexport {\n addDays,\n clampProgress,\n createTimeline,\n formatDateRange,\n getBarPosition,\n getMarkerPosition,\n getTimelineRange,\n includesDate,\n toDate,\n type TimelineGroup,\n type TimelineInterval,\n};\n"],"names":["DATE_ONLY_PATTERN","createDate","year","month","day","date","startOfDay","addDays","amount","addMonths","startOfWeek","normalizedDate","dayFromMonday","startOfMonth","startOfQuarter","getIntervalStart","view","addInterval","formatMonth","locale","format","formatIntervalLabel","start","end","inclusiveEnd","getGroupDetails","toDate","value","dateOnlyMatch","getDefaultRange","today","getTimelineRange","items","startDate","endDate","validDates","item","defaultRange","createTimeline","rangeStart","rangeEnd","intervals","cursor","intervalEnd","group","groups","result","interval","index","currentGroup","getDatePosition","firstInterval","lastInterval","intervalIndex","intervalProgress","getMarkerPosition","getBarPosition","itemStart","itemEnd","left","right","clampedLeft","clampedRight","clampProgress","progress","formatDateRange","formatter","includesDate"],"mappings":"AAEA,MAAMA,IAAoB,6BAiBpBC,IAAa,CAACC,GAAcC,GAAeC,MAAgB;AAC/D,QAAMC,IAAO,oBAAI,KAAK,CAAC;AAEvB,SAAAA,EAAK,YAAYH,GAAMC,GAAOC,CAAG,GACjCC,EAAK,SAAS,GAAG,GAAG,GAAG,CAAC,GAEjBA;AACT,GAEMC,IAAa,CAACD,MAAeJ,EAAWI,EAAK,eAAeA,EAAK,SAAA,GAAYA,EAAK,QAAA,CAAS,GAE3FE,IAAU,CAACF,GAAYG,MAAmBP,EAAWI,EAAK,eAAeA,EAAK,SAAA,GAAYA,EAAK,QAAA,IAAYG,CAAM,GAEjHC,IAAY,CAACJ,GAAYG,MAAmBP,EAAWI,EAAK,YAAA,GAAeA,EAAK,aAAaG,GAAQ,CAAC,GAEtGE,IAAc,CAACL,MAAe;AAClC,QAAMM,IAAiBL,EAAWD,CAAI,GAChCO,KAAiBD,EAAe,OAAA,IAAW,KAAK;AAEtD,SAAOJ,EAAQI,GAAgB,CAACC,CAAa;AAC/C,GAEMC,IAAe,CAACR,MAAeJ,EAAWI,EAAK,eAAeA,EAAK,SAAA,GAAY,CAAC,GAEhFS,IAAiB,CAACT,MAAeJ,EAAWI,EAAK,YAAA,GAAe,KAAK,MAAMA,EAAK,SAAA,IAAa,CAAC,IAAI,GAAG,CAAC,GAEtGU,IAAmB,CAACV,GAAYW,MAChCA,MAAS,SAAeN,EAAYL,CAAI,IACxCW,MAAS,UAAgBH,EAAaR,CAAI,IAEvCS,EAAeT,CAAI,GAGtBY,IAAc,CAACZ,GAAYW,MAC3BA,MAAS,SAAeT,EAAQF,GAAM,CAAC,IACvCW,MAAS,UAAgBP,EAAUJ,GAAM,CAAC,IAEvCI,EAAUJ,GAAM,CAAC,GAGpBa,IAAc,CAACb,GAAYc,GAAgBC,IAA2B,YAC1E,IAAI,KAAK,eAAeD,GAAQ,EAAE,OAAOC,EAAA,CAAQ,EAAE,OAAOf,CAAI,GAE1DgB,IAAsB,CAACC,GAAaC,GAAWP,GAAiBG,MAAmB;AACvF,MAAIH,MAAS;AACX,WAAO,GAAGE,EAAYI,GAAOH,CAAM,CAAC,IAAID,EAAYX,EAAQgB,GAAK,EAAE,GAAGJ,CAAM,CAAC,GAAG,YAAA;AAGlF,MAAIH,MAAS;AACX,WAAOE,EAAYI,GAAOH,CAAM,EAAE,YAAA;AAGpC,QAAMK,IAAejB,EAAQgB,GAAK,EAAE;AAEpC,SAAID,EAAM,SAAA,MAAeE,EAAa,aAC7B,GAAGF,EAAM,QAAA,CAAS,IAAIE,EAAa,SAAS,KAG9C,GAAGN,EAAYI,GAAOH,CAAM,CAAC,IAAIG,EAAM,QAAA,CAAS,IAAIJ,EAAYM,GAAcL,CAAM,CAAC,IAAIK,EAAa,SAAS;AACxH,GAEMC,IAAkB,CAACpB,GAAYW,GAAiBG,MAChDH,MAAS,SACJ;AAAA,EACL,KAAK,GAAGX,EAAK,YAAA,CAAa,IAAIA,EAAK,UAAU;AAAA,EAC7C,OAAO,GAAGa,EAAYb,GAAMc,GAAQ,MAAM,CAAC,IAAId,EAAK,aAAa;AAAA,IAI9D,EAAE,KAAK,OAAOA,EAAK,YAAA,CAAa,GAAG,OAAO,OAAOA,EAAK,YAAA,CAAa,EAAA,GAGtEqB,IAAS,CAACC,MAAiC;AAC/C,MAAIA,MAAU,OAAW,QAAO;AAEhC,MAAIA,aAAiB;AACnB,WAAO,OAAO,MAAMA,EAAM,QAAA,CAAS,IAAI,OAAOrB,EAAWqB,CAAK;AAGhE,QAAMC,IAAgB5B,EAAkB,KAAK2B,CAAK;AAElD,MAAIC,GAAe;AACjB,UAAM1B,IAAO,OAAO0B,EAAc,CAAC,CAAC,GAC9BzB,IAAQ,OAAOyB,EAAc,CAAC,CAAC,IAAI,GACnCxB,IAAM,OAAOwB,EAAc,CAAC,CAAC,GAC7BvB,IAAOJ,EAAWC,GAAMC,GAAOC,CAAG;AAExC,WAAIC,EAAK,kBAAkBH,KAAQG,EAAK,SAAA,MAAeF,KAASE,EAAK,QAAA,MAAcD,IAC1E,OAGFC;AAAAA,EACT;AAEA,QAAMA,IAAO,IAAI,KAAKsB,CAAK;AAE3B,SAAO,OAAO,MAAMtB,EAAK,QAAA,CAAS,IAAI,OAAOC,EAAWD,CAAI;AAC9D,GAEMwB,IAAkB,MAAM;AAC5B,QAAMC,wBAAY,KAAA;AAElB,SAAO;AAAA,IACL,OAAO7B,EAAW6B,EAAM,YAAA,GAAe,GAAG,CAAC;AAAA,IAC3C,KAAK7B,EAAW6B,EAAM,YAAA,GAAe,IAAI,EAAE;AAAA,EAAA;AAE/C,GAEMC,IAAmB,CAACC,GAAoBC,GAAuBC,MAAwB;AAC3F,QAAMC,IAAaH,EAAM,QAAQ,OAAQ,CAACN,EAAOU,EAAK,KAAK,GAAGV,EAAOU,EAAK,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC/B,MAAuBA,MAAS,IAAI,GACvHgC,IAAeR,EAAA;AACrB,MAAIP,IAAQI,EAAOO,CAAS,MAAME,EAAW,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,GAAGA,EAAW,IAAI,CAAA9B,MAAQA,EAAK,SAAS,CAAC,CAAC,IAAIgC,EAAa,QACnId,IAAMG,EAAOQ,CAAO,MAAMC,EAAW,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,GAAGA,EAAW,IAAI,CAAA9B,MAAQA,EAAK,SAAS,CAAC,CAAC,IAAIgC,EAAa;AAEnI,SAAId,IAAMD,MACR,CAACA,GAAOC,CAAG,IAAI,CAACA,GAAKD,CAAK,IAGrB,EAAE,OAAAA,GAAO,KAAAC,EAAA;AAClB,GAEMe,IAAiB,CAACC,GAAkBC,GAAgBxB,GAAiBG,MAAmB;AAC5F,QAAMsB,IAAgC,CAAA,GAChCnB,IAAQP,EAAiBwB,GAAYvB,CAAI,GACzCO,IAAMN,EAAYF,EAAiByB,GAAUxB,CAAI,GAAGA,CAAI;AAC9D,MAAI0B,IAASpB;AAEb,SAAOoB,IAASnB,KAAK;AACnB,UAAMoB,IAAc1B,EAAYyB,GAAQ1B,CAAI,GACtC4B,IAAQnB,EAAgBiB,GAAQ1B,GAAMG,CAAM;AAElD,IAAAsB,EAAU,KAAK;AAAA,MACb,OAAOC;AAAA,MACP,KAAKC;AAAA,MACL,OAAOtB,EAAoBqB,GAAQC,GAAa3B,GAAMG,CAAM;AAAA,MAC5D,UAAUyB,EAAM;AAAA,MAChB,YAAYA,EAAM;AAAA,IAAA,CACnB,GACDF,IAASC;AAAA,EACX;AAEA,QAAME,IAASJ,EAAU,OAAwB,CAACK,GAAQC,GAAUC,MAAU;AAC5E,UAAMC,IAAeH,EAAO,GAAG,EAAE;AAEjC,WAAIG,GAAc,QAAQF,EAAS,WACjCE,EAAa,iBAAiB,IAE9BH,EAAO,KAAK,EAAE,KAAKC,EAAS,UAAU,OAAOA,EAAS,YAAY,YAAYC,GAAO,eAAe,EAAA,CAAG,GAGlGF;AAAA,EACT,GAAG,CAAA,CAAE;AAEL,SAAO,EAAE,WAAAL,GAAW,QAAAI,EAAA;AACtB,GAEMK,IAAkB,CAAC7C,GAAYoC,MAAkC;AACrE,MAAIA,EAAU,WAAW,EAAG,QAAO;AAEnC,QAAMU,IAAgBV,EAAU,CAAC,GAC3BW,IAAeX,EAAU,GAAG,EAAE;AAEpC,MAAIpC,KAAQ8C,EAAc,MAAO,QAAO;AACxC,MAAI9C,KAAQ+C,EAAa,IAAK,QAAO;AAErC,QAAMC,IAAgBZ,EAAU,UAAU,CAAAM,MAAY1C,KAAQ0C,EAAS,SAAS1C,IAAO0C,EAAS,GAAG;AAEnG,MAAIM,IAAgB,EAAG,QAAO;AAE9B,QAAMN,IAAWN,EAAUY,CAAa,GAClCC,KAAoBjD,EAAK,QAAA,IAAY0C,EAAS,MAAM,QAAA,MAAcA,EAAS,IAAI,QAAA,IAAYA,EAAS,MAAM;AAEhH,UAASM,IAAgBC,KAAoBb,EAAU,SAAU;AACnE,GAEMc,IAAoB,CAAClD,GAAYoC,MAAkC;AACvE,MAAIA,EAAU,WAAW,EAAG,QAAO;AAEnC,QAAMU,IAAgBV,EAAU,CAAC,GAC3BW,IAAeX,EAAU,GAAG,EAAE;AAEpC,SAAIpC,IAAO8C,EAAc,SAAS9C,KAAQ+C,EAAa,MAAY,OAE5DF,EAAgB7C,GAAMoC,CAAS;AACxC,GAEMe,IAAiB,CAACpB,GAAiBK,MAAkC;AACzE,QAAMgB,IAAY/B,EAAOU,EAAK,KAAK,GAC7BsB,IAAUhC,EAAOU,EAAK,GAAG;AAE/B,MAAI,CAACqB,KAAa,CAACC,EAAS,QAAO;AAEnC,QAAMpC,IAAQmC,KAAaC,IAAUD,IAAYC,GAC3CnC,IAAMkC,KAAaC,IAAUA,IAAUD,GACvCE,IAAOT,EAAgB5B,GAAOmB,CAAS,GACvCmB,IAAQV,EAAgB3C,EAAQgB,GAAK,CAAC,GAAGkB,CAAS;AAExD,MAAImB,KAAS,KAAKD,KAAQ,IAAK,QAAO;AAEtC,QAAME,IAAc,KAAK,IAAI,GAAGF,CAAI,GAC9BG,IAAe,KAAK,IAAI,KAAKF,CAAK;AAExC,SAAO,EAAE,MAAMC,GAAa,OAAO,KAAK,IAAI,GAAGC,IAAeD,CAAW,EAAA;AAC3E,GAEME,IAAgB,CAACC,IAAW,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAGA,CAAQ,CAAC,GAErEC,IAAkB,CAAC7B,GAAiBjB,MAAmB;AAC3D,QAAMG,IAAQI,EAAOU,EAAK,KAAK,GACzBb,IAAMG,EAAOU,EAAK,GAAG;AAE3B,MAAI,CAACd,KAAS,CAACC,EAAK,QAAO;AAE3B,QAAM2C,IAAY,IAAI,KAAK,eAAe/C,GAAQ,EAAE,OAAO,SAAS,KAAK,WAAW;AAEpF,SAAO,GAAG+C,EAAU,OAAO5C,CAAK,CAAC,IAAI4C,EAAU,OAAO3C,CAAG,CAAC;AAC5D,GAEM4C,IAAe,CAACpB,GAA4B1C,MAAsB,GAAQA,KAAQA,KAAQ0C,EAAS,SAAS1C,IAAO0C,EAAS;"}
@@ -0,0 +1,337 @@
1
+ import { jsxs as l, jsx as t, Fragment as V } from "react/jsx-runtime";
2
+ import a from "react";
3
+ import { Plus as me } from "@trsys-tech/matrix-icons";
4
+ import { cn as v } from "./utils.es.js";
5
+ import { GanttToolbar as oe } from "./gantttoolbar.es.js";
6
+ import { getTimelineRange as ie, createTimeline as xe, toDate as W, getMarkerPosition as ce, clampProgress as de, getBarPosition as ue, formatDateRange as fe, includesDate as j } from "./gantt-chart.es.js";
7
+ const be = {
8
+ week: "Weeks",
9
+ month: "Month",
10
+ quarter: "Quarter"
11
+ }, he = {
12
+ week: 72,
13
+ month: 120,
14
+ quarter: 220
15
+ }, S = 8, D = 12, k = 4, ge = 30, q = ({ markers: n, showLabels: c = !1 }) => {
16
+ const u = a.useRef(null), d = a.useRef(/* @__PURE__ */ new Map()), b = a.useRef(/* @__PURE__ */ new Map());
17
+ return a.useEffect(() => {
18
+ const e = u.current;
19
+ if (!e || !c) return;
20
+ const i = () => {
21
+ const m = e.clientWidth, $ = n.flatMap(({ marker: s, left: o }) => {
22
+ const w = String(s.id), h = d.current.get(w);
23
+ if (!h) return [];
24
+ const R = o / 100 * m, g = h.offsetWidth;
25
+ let p = R + D;
26
+ return p + g > m - S && (p = R - g - D), p = Math.max(S, Math.min(p, m - g - S)), [{ key: w, label: h, labelLeft: p, labelRight: p + g }];
27
+ }), N = [];
28
+ $.sort((s, o) => s.labelLeft - o.labelLeft).forEach((s) => {
29
+ let o = N.findIndex((R) => R + S <= s.labelLeft);
30
+ o === -1 && (o = N.length), N[o] = s.labelRight;
31
+ const w = k + o * ge;
32
+ s.label.style.left = `${s.labelLeft}px`, s.label.style.top = `${w}px`;
33
+ const h = b.current.get(s.key);
34
+ h && (h.style.top = `${w + 8}px`);
35
+ });
36
+ };
37
+ if (i(), typeof ResizeObserver > "u") return;
38
+ const x = new ResizeObserver(i);
39
+ return x.observe(e), d.current.forEach((m) => x.observe(m)), () => x.disconnect();
40
+ }, [n, c]), /* @__PURE__ */ t("div", { ref: u, className: "mtx-pointer-events-none mtx-absolute mtx-inset-0 mtx-z-20", children: n.map(({ marker: e, left: i }) => {
41
+ const x = String(e.id);
42
+ return /* @__PURE__ */ l(a.Fragment, { children: [
43
+ /* @__PURE__ */ t(
44
+ "div",
45
+ {
46
+ className: v("mtx-absolute mtx-inset-y-0 mtx-w-0.5 -mtx-translate-x-1/2", e.lineClassName),
47
+ style: { left: `${i}%`, backgroundColor: e.color },
48
+ "aria-hidden": "true"
49
+ }
50
+ ),
51
+ c ? /* @__PURE__ */ l(V, { children: [
52
+ /* @__PURE__ */ t(
53
+ "div",
54
+ {
55
+ ref: (m) => {
56
+ m ? b.current.set(x, m) : b.current.delete(x);
57
+ },
58
+ className: v(
59
+ "mtx-absolute mtx-z-20 mtx-h-2 mtx-w-2 -mtx-translate-x-1/2 mtx-rotate-45 mtx-border mtx-border-gray-0",
60
+ e.diamondClassName
61
+ ),
62
+ style: { left: `${i}%`, top: k + 8, backgroundColor: e.color },
63
+ "aria-hidden": "true"
64
+ }
65
+ ),
66
+ /* @__PURE__ */ t(
67
+ "div",
68
+ {
69
+ ref: (m) => {
70
+ m ? d.current.set(x, m) : d.current.delete(x);
71
+ },
72
+ className: v(
73
+ "mtx-absolute mtx-z-20 mtx-max-w-48 mtx-truncate mtx-whitespace-nowrap mtx-rounded-sm mtx-border mtx-bg-gray-0 mtx-px-2 mtx-py-1 mtx-text-xs mtx-font-semibold mtx-shadow-card",
74
+ e.labelClassName
75
+ ),
76
+ style: { left: `calc(${i}% + ${D}px)`, top: k, borderColor: e.color, color: e.color },
77
+ title: typeof e.label == "string" ? e.label : void 0,
78
+ role: "note",
79
+ children: e.label
80
+ }
81
+ )
82
+ ] }) : null
83
+ ] }, e.id);
84
+ }) });
85
+ }, I = ({ intervals: n, highlightedDate: c }) => /* @__PURE__ */ t(
86
+ "div",
87
+ {
88
+ "aria-hidden": "true",
89
+ className: "mtx-pointer-events-none mtx-absolute mtx-inset-0 mtx-grid",
90
+ style: { gridTemplateColumns: `repeat(${n.length}, minmax(0, 1fr))` },
91
+ children: n.map((u, d) => /* @__PURE__ */ t(
92
+ "div",
93
+ {
94
+ className: v(
95
+ "mtx-border-l mtx-border-gray-200",
96
+ d === n.length - 1 && "mtx-border-r",
97
+ j(u, c) && "mtx-bg-gray-50"
98
+ )
99
+ },
100
+ u.start.toISOString()
101
+ ))
102
+ }
103
+ ), pe = ({ intervals: n, groups: c, highlightedDate: u, nameColumnHeader: d, nameColumnWidth: b }) => /* @__PURE__ */ l("div", { className: "mtx-bg-primary-50", role: "rowgroup", children: [
104
+ /* @__PURE__ */ l(
105
+ "div",
106
+ {
107
+ className: "mtx-grid mtx-h-9 mtx-border-b mtx-border-gray-200",
108
+ style: { gridTemplateColumns: `${b}px repeat(${n.length}, minmax(0, 1fr))` },
109
+ role: "row",
110
+ children: [
111
+ /* @__PURE__ */ t(
112
+ "div",
113
+ {
114
+ className: "mtx-sticky mtx-left-0 mtx-z-20 mtx-flex mtx-items-center mtx-border-b mtx-border-r mtx-border-gray-200 mtx-bg-primary-50 mtx-px-4 mtx-text-sm mtx-font-semibold mtx-text-text-500",
115
+ style: { gridColumn: 1, height: 80 },
116
+ role: "columnheader",
117
+ "aria-colindex": 1,
118
+ "aria-rowspan": 2,
119
+ children: d
120
+ }
121
+ ),
122
+ c.map((e) => /* @__PURE__ */ t(
123
+ "div",
124
+ {
125
+ className: "mtx-flex mtx-items-start mtx-justify-center mtx-py-1.5 mtx-border-l mtx-border-gray-200 mtx-text-sm mtx-font-medium mtx-text-text-500",
126
+ style: { gridColumn: `${e.startIndex + 2} / span ${e.intervalCount}` },
127
+ role: "columnheader",
128
+ "aria-colindex": e.startIndex + 2,
129
+ "aria-colspan": e.intervalCount,
130
+ children: e.label
131
+ },
132
+ e.key
133
+ ))
134
+ ]
135
+ }
136
+ ),
137
+ /* @__PURE__ */ l("div", { className: "mtx-grid mtx-h-11", style: { gridTemplateColumns: `${b}px repeat(${n.length}, minmax(0, 1fr))` }, role: "row", children: [
138
+ /* @__PURE__ */ t("div", { "aria-hidden": "true" }),
139
+ n.map((e, i) => /* @__PURE__ */ t(
140
+ "div",
141
+ {
142
+ className: v(
143
+ "mtx-flex mtx-items-center mtx-justify-center mtx-border-l mtx-border-gray-200 mtx-px-2 mtx-text-center mtx-text-xs mtx-font-medium mtx-text-text-500",
144
+ j(e, u) && "mtx-bg-primary-100 mtx-font-semibold"
145
+ ),
146
+ role: "columnheader",
147
+ "aria-colindex": i + 2,
148
+ children: e.label
149
+ },
150
+ e.start.toISOString()
151
+ ))
152
+ ] })
153
+ ] }), ye = a.forwardRef(
154
+ ({
155
+ items: n,
156
+ view: c,
157
+ defaultView: u = "quarter",
158
+ views: d = ["week", "month", "quarter"],
159
+ viewLabels: b,
160
+ onViewChange: e,
161
+ startDate: i,
162
+ endDate: x,
163
+ markers: m = [],
164
+ highlightedDate: $,
165
+ locale: N = "en-US",
166
+ nameColumnWidth: s = 320,
167
+ rowHeight: o = 64,
168
+ cellWidths: w,
169
+ nameColumnHeader: h = "Name",
170
+ addItemLabel: R = "New item",
171
+ onAddItem: g,
172
+ onRefresh: p,
173
+ showFullscreen: B = !0,
174
+ toolbarActions: K,
175
+ renderItem: z,
176
+ renderBar: P,
177
+ formatDateRange: U,
178
+ className: H,
179
+ "aria-label": G = "Gantt chart",
180
+ ...Q
181
+ }, J) => {
182
+ const L = a.useRef(null), [X, Y] = a.useState(!1), [Z, ee] = a.useState(u), E = c ?? Z, C = a.useMemo(() => ie(n, i, x), [x, n, i]), y = a.useMemo(() => xe(C.start, C.end, E, N), [E, N, C.end, C.start]), _ = a.useMemo(() => $ === null ? null : W($ ?? /* @__PURE__ */ new Date()), [$]), te = { ...be, ...b }, O = a.useMemo(
183
+ () => m.flatMap((r) => {
184
+ const M = W(r.date), f = M ? ce(M, y.intervals) : null;
185
+ return f === null ? [] : [{ marker: r, left: f }];
186
+ }),
187
+ [m, y.intervals]
188
+ ), re = w?.[E] ?? he[E], F = y.intervals.length * re, le = s + F, ne = a.useCallback((r) => {
189
+ L.current = r, r && typeof document < "u" && Y(
190
+ document.fullscreenEnabled !== !1 && typeof r.requestFullscreen == "function" && typeof document.exitFullscreen == "function"
191
+ );
192
+ }, []);
193
+ a.useImperativeHandle(J, () => L.current);
194
+ const se = (r) => {
195
+ c === void 0 && ee(r), e?.(r);
196
+ }, ae = () => {
197
+ !L.current || typeof document > "u" || (document.fullscreenElement === L.current ? document.exitFullscreen().catch(() => {
198
+ }) : L.current.requestFullscreen().catch(() => {
199
+ }));
200
+ };
201
+ return /* @__PURE__ */ l(
202
+ "div",
203
+ {
204
+ ref: ne,
205
+ className: v("mtx-overflow-hidden mtx-rounded-lg mtx-border mtx-border-gray-200 mtx-bg-gray-0 mtx-[font-family:DMSans]", H),
206
+ "aria-label": G,
207
+ ...Q,
208
+ children: [
209
+ /* @__PURE__ */ t(
210
+ oe,
211
+ {
212
+ activeView: E,
213
+ views: d,
214
+ viewLabels: te,
215
+ onViewChange: se,
216
+ onRefresh: p,
217
+ onToggleFullscreen: B && X ? ae : void 0,
218
+ toolbarActions: K
219
+ }
220
+ ),
221
+ /* @__PURE__ */ t("div", { className: "mtx-overflow-auto", children: /* @__PURE__ */ l("div", { style: { minWidth: le }, role: "table", "aria-label": G, children: [
222
+ /* @__PURE__ */ t(
223
+ pe,
224
+ {
225
+ intervals: y.intervals,
226
+ groups: y.groups,
227
+ highlightedDate: _,
228
+ nameColumnHeader: h,
229
+ nameColumnWidth: s
230
+ }
231
+ ),
232
+ g ? /* @__PURE__ */ l("div", { className: "mtx-grid", style: { gridTemplateColumns: `${s}px minmax(${F}px, 1fr)` }, role: "row", children: [
233
+ /* @__PURE__ */ t(
234
+ "div",
235
+ {
236
+ className: "mtx-sticky mtx-left-0 mtx-z-30 mtx-flex mtx-items-center mtx-border-b mtx-border-r mtx-border-gray-200 mtx-bg-gray-0 mtx-px-4",
237
+ style: { height: o },
238
+ role: "cell",
239
+ children: /* @__PURE__ */ l(
240
+ "button",
241
+ {
242
+ type: "button",
243
+ className: "mtx-inline-flex mtx-items-center mtx-gap-2 mtx-text-sm mtx-font-medium mtx-text-primary hover:mtx-text-primary-700 focus-visible:mtx-outline-none focus-visible:mtx-ring focus-visible:mtx-ring-primary-300",
244
+ onClick: g,
245
+ children: [
246
+ /* @__PURE__ */ t(me, { className: "mtx-h-4 mtx-w-4" }),
247
+ R
248
+ ]
249
+ }
250
+ )
251
+ }
252
+ ),
253
+ /* @__PURE__ */ l("div", { className: "mtx-relative mtx-border-b mtx-border-gray-200", style: { height: o }, role: "cell", children: [
254
+ /* @__PURE__ */ t(I, { intervals: y.intervals, highlightedDate: _ }),
255
+ /* @__PURE__ */ t(q, { markers: O, showLabels: !0 })
256
+ ] })
257
+ ] }) : null,
258
+ /* @__PURE__ */ t("div", { role: "rowgroup", children: n.map((r, M) => {
259
+ const f = de(r.progress), T = ue(r, y.intervals), A = U?.(r) ?? fe(r, N);
260
+ return /* @__PURE__ */ l(
261
+ "div",
262
+ {
263
+ className: "mtx-grid",
264
+ style: { gridTemplateColumns: `${s}px minmax(${F}px, 1fr)` },
265
+ role: "row",
266
+ children: [
267
+ /* @__PURE__ */ t(
268
+ "div",
269
+ {
270
+ className: "mtx-sticky mtx-left-0 mtx-z-30 mtx-flex mtx-items-center mtx-border-b mtx-border-r mtx-border-gray-200 mtx-bg-gray-0 mtx-px-4",
271
+ style: { height: o },
272
+ role: "rowheader",
273
+ children: z ? z({ item: r, formattedDateRange: A }) : /* @__PURE__ */ l("div", { className: "mtx-flex mtx-w-full mtx-min-w-0 mtx-items-center mtx-justify-between mtx-gap-3", children: [
274
+ /* @__PURE__ */ t("span", { className: "mtx-truncate mtx-text-sm mtx-font-semibold mtx-text-text-500", children: r.name }),
275
+ /* @__PURE__ */ t("span", { className: "mtx-shrink-0 mtx-text-xs mtx-text-text-300", children: A })
276
+ ] })
277
+ }
278
+ ),
279
+ /* @__PURE__ */ l("div", { className: "mtx-relative mtx-border-b mtx-border-gray-200", style: { height: o }, role: "cell", children: [
280
+ /* @__PURE__ */ t(I, { intervals: y.intervals, highlightedDate: _ }),
281
+ /* @__PURE__ */ t(q, { markers: O, showLabels: !g && M === 0 }),
282
+ T && T.width > 0 ? /* @__PURE__ */ l(
283
+ "div",
284
+ {
285
+ className: v(
286
+ "mtx-absolute mtx-top-1/2 mtx-z-10 mtx-h-10 -mtx-translate-y-1/2 mtx-overflow-hidden mtx-rounded mtx-border-r-2 mtx-border-secondary-800 mtx-bg-secondary-200",
287
+ r.barClassName
288
+ ),
289
+ style: { left: `${T.left}%`, width: `${T.width}%` },
290
+ title: `${A}, ${f}% complete`,
291
+ role: "progressbar",
292
+ "aria-valuemin": 0,
293
+ "aria-valuemax": 100,
294
+ "aria-valuenow": f,
295
+ children: [
296
+ /* @__PURE__ */ t(
297
+ "div",
298
+ {
299
+ className: v("mtx-h-full mtx-bg-secondary-500", r.progressClassName),
300
+ style: { width: `${f}%` },
301
+ "aria-hidden": "true"
302
+ }
303
+ ),
304
+ /* @__PURE__ */ t(
305
+ "div",
306
+ {
307
+ className: "mtx-absolute mtx-top-1/2 mtx-min-w-max -mtx-translate-x-1/2 -mtx-translate-y-1/2 mtx-text-center mtx-text-xs mtx-leading-4 mtx-text-text-600",
308
+ style: { left: `clamp(3rem, ${f / 2}%, calc(100% - 3rem))` },
309
+ children: P ? P({ item: r, progress: f }) : /* @__PURE__ */ l(V, { children: [
310
+ /* @__PURE__ */ t("span", { className: "mtx-block", children: "Progress" }),
311
+ /* @__PURE__ */ l("strong", { className: "mtx-block mtx-text-sm", children: [
312
+ f,
313
+ "%"
314
+ ] })
315
+ ] })
316
+ }
317
+ )
318
+ ]
319
+ }
320
+ ) : null
321
+ ] })
322
+ ]
323
+ },
324
+ r.id
325
+ );
326
+ }) })
327
+ ] }) })
328
+ ]
329
+ }
330
+ );
331
+ }
332
+ );
333
+ ye.displayName = "GanttChart";
334
+ export {
335
+ ye as GanttChart
336
+ };
337
+ //# sourceMappingURL=ganttchart.es.js.map