@trsys-tech/matrix-library 1.1.1 → 1.1.3

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 +40 -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 +182 -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":"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":"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"}
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ganttchart.es.js","sources":["../src/components/gantt-chart/GanttChart.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { Plus } from \"@trsys-tech/matrix-icons\";\n\nimport { cn } from \"../../lib/utils\";\nimport { GanttToolbar } from \"./GanttToolbar\";\nimport {\n clampProgress,\n createTimeline,\n formatDateRange as defaultFormatDateRange,\n getBarPosition,\n getMarkerPosition,\n getTimelineRange,\n includesDate,\n toDate,\n type TimelineGroup,\n type TimelineInterval,\n} from \"./gantt-chart.utils\";\nimport type {\n GanttDate,\n GanttItem,\n GanttMarker,\n GanttRenderBarContext,\n GanttRenderItemContext,\n GanttView,\n GanttViewLabels,\n} from \"./gantt-chart.types\";\n\nconst DEFAULT_VIEW_LABELS: GanttViewLabels = {\n week: \"Weeks\",\n month: \"Month\",\n quarter: \"Quarter\",\n};\n\nconst DEFAULT_CELL_WIDTHS: Record<GanttView, number> = {\n week: 72,\n month: 120,\n quarter: 220,\n};\n\ntype GanttChartProps = Omit<React.HTMLAttributes<HTMLDivElement>, \"children\"> & {\n /** Rows displayed by the chart. */\n items: GanttItem[];\n /** Controlled timeline scale. */\n view?: GanttView;\n /** Initial scale when the chart is uncontrolled. */\n defaultView?: GanttView;\n /** Scales available in the toolbar. */\n views?: GanttView[];\n /** Labels shown for the available scales. */\n viewLabels?: Partial<GanttViewLabels>;\n /** Called after the user selects a scale. */\n onViewChange?: (view: GanttView) => void;\n /** Optional beginning of the visible timeline. */\n startDate?: GanttDate;\n /** Optional end of the visible timeline. */\n endDate?: GanttDate;\n /** Dated vertical markers drawn over the timeline rows. */\n markers?: GanttMarker[];\n /** Date whose period is highlighted. Defaults to today; pass null to disable. */\n highlightedDate?: GanttDate | null;\n /** Locale used by timeline and range labels. */\n locale?: string;\n /** Width of the sticky row-name column in pixels. */\n nameColumnWidth?: number;\n /** Height of each item row in pixels. */\n rowHeight?: number;\n /** Minimum width of an individual timeline cell, by scale. */\n cellWidths?: Partial<Record<GanttView, number>>;\n /** Header shown above item names. */\n nameColumnHeader?: React.ReactNode;\n /** Label used for the add-row action. */\n addItemLabel?: React.ReactNode;\n /** Shows the add-row action when provided. */\n onAddItem?: () => void;\n /** Shows the refresh action when provided. */\n onRefresh?: () => void;\n /** Shows the native fullscreen action when supported. */\n showFullscreen?: boolean;\n /** Content inserted before the default toolbar actions. */\n toolbarActions?: React.ReactNode;\n /** Replaces the default item-name and date-range content. */\n renderItem?: (context: GanttRenderItemContext) => React.ReactNode;\n /** Replaces the default progress label inside a bar. */\n renderBar?: (context: GanttRenderBarContext) => React.ReactNode;\n /** Replaces the compact date range shown alongside each item. */\n formatDateRange?: (item: GanttItem) => string;\n /** Accessible label for the chart. */\n \"aria-label\"?: string;\n};\n\ntype TimelineGridProps = {\n intervals: TimelineInterval[];\n highlightedDate: Date | null;\n};\n\ntype PositionedGanttMarker = {\n marker: GanttMarker;\n left: number;\n};\n\ntype TimelineMarkersProps = {\n markers: PositionedGanttMarker[];\n showLabels?: boolean;\n};\n\nconst MARKER_LABEL_GAP = 8;\nconst MARKER_LABEL_OFFSET = 12;\nconst MARKER_LABEL_TOP = 4;\nconst MARKER_LABEL_LANE_HEIGHT = 30;\n\nconst TimelineMarkers: React.FC<TimelineMarkersProps> = ({ markers, showLabels = false }) => {\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n const labelRefs = React.useRef(new Map<string, HTMLDivElement>());\n const diamondRefs = React.useRef(new Map<string, HTMLDivElement>());\n\n React.useEffect(() => {\n const container = containerRef.current;\n\n if (!container || !showLabels) return;\n\n const positionLabels = () => {\n const containerWidth = container.clientWidth;\n const candidates = markers.flatMap(({ marker, left }) => {\n const key = String(marker.id);\n const label = labelRefs.current.get(key);\n\n if (!label) return [];\n\n const markerLeft = (left / 100) * containerWidth;\n const labelWidth = label.offsetWidth;\n let labelLeft = markerLeft + MARKER_LABEL_OFFSET;\n\n if (labelLeft + labelWidth > containerWidth - MARKER_LABEL_GAP) {\n labelLeft = markerLeft - labelWidth - MARKER_LABEL_OFFSET;\n }\n\n labelLeft = Math.max(MARKER_LABEL_GAP, Math.min(labelLeft, containerWidth - labelWidth - MARKER_LABEL_GAP));\n\n return [{ key, label, labelLeft, labelRight: labelLeft + labelWidth }];\n });\n\n const laneRightEdges: number[] = [];\n\n candidates\n .sort((first, second) => first.labelLeft - second.labelLeft)\n .forEach(candidate => {\n let lane = laneRightEdges.findIndex(rightEdge => rightEdge + MARKER_LABEL_GAP <= candidate.labelLeft);\n\n if (lane === -1) {\n lane = laneRightEdges.length;\n }\n\n laneRightEdges[lane] = candidate.labelRight;\n const top = MARKER_LABEL_TOP + lane * MARKER_LABEL_LANE_HEIGHT;\n\n candidate.label.style.left = `${candidate.labelLeft}px`;\n candidate.label.style.top = `${top}px`;\n\n const diamond = diamondRefs.current.get(candidate.key);\n\n if (diamond) {\n diamond.style.top = `${top + 8}px`;\n }\n });\n };\n\n positionLabels();\n\n if (typeof ResizeObserver === \"undefined\") return;\n\n const resizeObserver = new ResizeObserver(positionLabels);\n\n resizeObserver.observe(container);\n labelRefs.current.forEach(label => resizeObserver.observe(label));\n\n return () => resizeObserver.disconnect();\n }, [markers, showLabels]);\n\n return (\n <div ref={containerRef} className=\"mtx-pointer-events-none mtx-absolute mtx-inset-0 mtx-z-20\">\n {markers.map(({ marker, left }) => {\n const key = String(marker.id);\n\n return (\n <React.Fragment key={marker.id}>\n <div\n className={cn(\"mtx-absolute mtx-inset-y-0 mtx-w-0.5 -mtx-translate-x-1/2\", marker.lineClassName)}\n style={{ left: `${left}%`, backgroundColor: marker.color }}\n aria-hidden=\"true\"\n />\n {showLabels ? (\n <>\n <div\n ref={element => {\n if (element) diamondRefs.current.set(key, element);\n else diamondRefs.current.delete(key);\n }}\n className={cn(\n \"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\",\n marker.diamondClassName,\n )}\n style={{ left: `${left}%`, top: MARKER_LABEL_TOP + 8, backgroundColor: marker.color }}\n aria-hidden=\"true\"\n />\n <div\n ref={element => {\n if (element) labelRefs.current.set(key, element);\n else labelRefs.current.delete(key);\n }}\n className={cn(\n \"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\",\n marker.labelClassName,\n )}\n style={{ left: `calc(${left}% + ${MARKER_LABEL_OFFSET}px)`, top: MARKER_LABEL_TOP, borderColor: marker.color, color: marker.color }}\n title={typeof marker.label === \"string\" ? marker.label : undefined}\n role=\"note\"\n >\n {marker.label}\n </div>\n </>\n ) : null}\n </React.Fragment>\n );\n })}\n </div>\n );\n};\n\nconst TimelineGrid: React.FC<TimelineGridProps> = ({ intervals, highlightedDate }) => (\n <div\n aria-hidden=\"true\"\n className=\"mtx-pointer-events-none mtx-absolute mtx-inset-0 mtx-grid\"\n style={{ gridTemplateColumns: `repeat(${intervals.length}, minmax(0, 1fr))` }}\n >\n {intervals.map((interval, index) => (\n <div\n key={interval.start.toISOString()}\n className={cn(\n \"mtx-border-l mtx-border-gray-200\",\n index === intervals.length - 1 && \"mtx-border-r\",\n includesDate(interval, highlightedDate) && \"mtx-bg-gray-50\",\n )}\n />\n ))}\n </div>\n);\n\ntype TimelineHeaderProps = {\n intervals: TimelineInterval[];\n groups: TimelineGroup[];\n highlightedDate: Date | null;\n nameColumnHeader: React.ReactNode;\n nameColumnWidth: number;\n};\n\nconst TimelineHeader: React.FC<TimelineHeaderProps> = ({ intervals, groups, highlightedDate, nameColumnHeader, nameColumnWidth }) => (\n <div className=\"mtx-bg-primary-50\" role=\"rowgroup\">\n <div\n className=\"mtx-grid mtx-h-9 mtx-border-b mtx-border-gray-200\"\n style={{ gridTemplateColumns: `${nameColumnWidth}px repeat(${intervals.length}, minmax(0, 1fr))` }}\n role=\"row\"\n >\n <div\n 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\"\n style={{ gridColumn: 1, height: 80 }}\n role=\"columnheader\"\n aria-colindex={1}\n aria-rowspan={2}\n >\n {nameColumnHeader}\n </div>\n {groups.map(group => (\n <div\n key={group.key}\n 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\"\n style={{ gridColumn: `${group.startIndex + 2} / span ${group.intervalCount}` }}\n role=\"columnheader\"\n aria-colindex={group.startIndex + 2}\n aria-colspan={group.intervalCount}\n >\n {group.label}\n </div>\n ))}\n </div>\n <div className=\"mtx-grid mtx-h-11\" style={{ gridTemplateColumns: `${nameColumnWidth}px repeat(${intervals.length}, minmax(0, 1fr))` }} role=\"row\">\n <div aria-hidden=\"true\" />\n {intervals.map((interval, index) => (\n <div\n key={interval.start.toISOString()}\n className={cn(\n \"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\",\n includesDate(interval, highlightedDate) && \"mtx-bg-primary-100 mtx-font-semibold\",\n )}\n role=\"columnheader\"\n aria-colindex={index + 2}\n >\n {interval.label}\n </div>\n ))}\n </div>\n </div>\n);\n\nconst GanttChart = React.forwardRef<HTMLDivElement, GanttChartProps>(\n (\n {\n items,\n view,\n defaultView = \"quarter\",\n views = [\"week\", \"month\", \"quarter\"],\n viewLabels,\n onViewChange,\n startDate,\n endDate,\n markers = [],\n highlightedDate,\n locale = \"en-US\",\n nameColumnWidth = 320,\n rowHeight = 64,\n cellWidths,\n nameColumnHeader = \"Name\",\n addItemLabel = \"New item\",\n onAddItem,\n onRefresh,\n showFullscreen = true,\n toolbarActions,\n renderItem,\n renderBar,\n formatDateRange,\n className,\n \"aria-label\": ariaLabel = \"Gantt chart\",\n ...props\n },\n ref,\n ) => {\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const [fullscreenSupported, setFullscreenSupported] = React.useState(false);\n const [uncontrolledView, setUncontrolledView] = React.useState(defaultView);\n const activeView = view ?? uncontrolledView;\n const range = React.useMemo(() => getTimelineRange(items, startDate, endDate), [endDate, items, startDate]);\n const timeline = React.useMemo(() => createTimeline(range.start, range.end, activeView, locale), [activeView, locale, range.end, range.start]);\n const activeHighlightedDate = React.useMemo(() => (highlightedDate === null ? null : toDate(highlightedDate ?? new Date())), [highlightedDate]);\n const activeViewLabels = { ...DEFAULT_VIEW_LABELS, ...viewLabels };\n const positionedMarkers = React.useMemo(\n () =>\n markers.flatMap(marker => {\n const markerDate = toDate(marker.date);\n const left = markerDate ? getMarkerPosition(markerDate, timeline.intervals) : null;\n\n return left === null ? [] : [{ marker, left }];\n }),\n [markers, timeline.intervals],\n );\n const cellWidth = cellWidths?.[activeView] ?? DEFAULT_CELL_WIDTHS[activeView];\n const timelineWidth = timeline.intervals.length * cellWidth;\n const chartWidth = nameColumnWidth + timelineWidth;\n\n const handleRootRef = React.useCallback((element: HTMLDivElement | null) => {\n rootRef.current = element;\n\n if (element && typeof document !== \"undefined\") {\n setFullscreenSupported(\n document.fullscreenEnabled !== false && typeof element.requestFullscreen === \"function\" && typeof document.exitFullscreen === \"function\",\n );\n }\n }, []);\n\n React.useImperativeHandle(ref, () => rootRef.current as HTMLDivElement);\n\n const handleViewChange = (nextView: GanttView) => {\n if (view === undefined) {\n setUncontrolledView(nextView);\n }\n onViewChange?.(nextView);\n };\n\n const handleToggleFullscreen = () => {\n if (!rootRef.current || typeof document === \"undefined\") return;\n\n if (document.fullscreenElement === rootRef.current) {\n void document.exitFullscreen().catch(() => undefined);\n } else {\n void rootRef.current.requestFullscreen().catch(() => undefined);\n }\n };\n\n return (\n <div\n ref={handleRootRef}\n className={cn(\"mtx-overflow-hidden mtx-rounded-lg mtx-border mtx-border-gray-200 mtx-bg-gray-0 mtx-[font-family:DMSans]\", className)}\n aria-label={ariaLabel}\n {...props}\n >\n <GanttToolbar\n activeView={activeView}\n views={views}\n viewLabels={activeViewLabels}\n onViewChange={handleViewChange}\n onRefresh={onRefresh}\n onToggleFullscreen={showFullscreen && fullscreenSupported ? handleToggleFullscreen : undefined}\n toolbarActions={toolbarActions}\n />\n\n <div className=\"mtx-overflow-auto\">\n <div style={{ minWidth: chartWidth }} role=\"table\" aria-label={ariaLabel}>\n <TimelineHeader\n intervals={timeline.intervals}\n groups={timeline.groups}\n highlightedDate={activeHighlightedDate}\n nameColumnHeader={nameColumnHeader}\n nameColumnWidth={nameColumnWidth}\n />\n\n {onAddItem ? (\n <div className=\"mtx-grid\" style={{ gridTemplateColumns: `${nameColumnWidth}px minmax(${timelineWidth}px, 1fr)` }} role=\"row\">\n <div\n 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\"\n style={{ height: rowHeight }}\n role=\"cell\"\n >\n <button\n type=\"button\"\n 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\"\n onClick={onAddItem}\n >\n <Plus className=\"mtx-h-4 mtx-w-4\" />\n {addItemLabel}\n </button>\n </div>\n <div className=\"mtx-relative mtx-border-b mtx-border-gray-200\" style={{ height: rowHeight }} role=\"cell\">\n <TimelineGrid intervals={timeline.intervals} highlightedDate={activeHighlightedDate} />\n <TimelineMarkers markers={positionedMarkers} showLabels />\n </div>\n </div>\n ) : null}\n\n <div role=\"rowgroup\">\n {items.map((item, itemIndex) => {\n const progress = clampProgress(item.progress);\n const barPosition = getBarPosition(item, timeline.intervals);\n const formattedDateRange = formatDateRange?.(item) ?? defaultFormatDateRange(item, locale);\n\n return (\n <div\n key={item.id}\n className=\"mtx-grid\"\n style={{ gridTemplateColumns: `${nameColumnWidth}px minmax(${timelineWidth}px, 1fr)` }}\n role=\"row\"\n >\n <div\n 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\"\n style={{ height: rowHeight }}\n role=\"rowheader\"\n >\n {renderItem ? (\n renderItem({ item, formattedDateRange })\n ) : (\n <div className=\"mtx-flex mtx-w-full mtx-min-w-0 mtx-items-center mtx-justify-between mtx-gap-3\">\n <span className=\"mtx-truncate mtx-text-sm mtx-font-semibold mtx-text-text-500\">{item.name}</span>\n <span className=\"mtx-shrink-0 mtx-text-xs mtx-text-text-300\">{formattedDateRange}</span>\n </div>\n )}\n </div>\n\n <div className=\"mtx-relative mtx-border-b mtx-border-gray-200\" style={{ height: rowHeight }} role=\"cell\">\n <TimelineGrid intervals={timeline.intervals} highlightedDate={activeHighlightedDate} />\n <TimelineMarkers markers={positionedMarkers} showLabels={!onAddItem && itemIndex === 0} />\n {barPosition && barPosition.width > 0 ? (\n <div\n className={cn(\n \"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\",\n item.barClassName,\n )}\n style={{ left: `${barPosition.left}%`, width: `${barPosition.width}%` }}\n title={`${formattedDateRange}, ${progress}% complete`}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={progress}\n >\n <div\n className={cn(\"mtx-h-full mtx-bg-secondary-500\", item.progressClassName)}\n style={{ width: `${progress}%` }}\n aria-hidden=\"true\"\n />\n <div\n 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\"\n style={{ left: `clamp(3rem, ${progress / 2}%, calc(100% - 3rem))` }}\n >\n {renderBar ? (\n renderBar({ item, progress })\n ) : (\n <>\n <span className=\"mtx-block\">Progress</span>\n <strong className=\"mtx-block mtx-text-sm\">{progress}%</strong>\n </>\n )}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n );\n },\n);\n\nGanttChart.displayName = \"GanttChart\";\n\nexport {\n GanttChart,\n type GanttChartProps,\n type GanttDate,\n type GanttItem,\n type GanttMarker,\n type GanttRenderBarContext,\n type GanttRenderItemContext,\n type GanttView,\n};\n"],"names":["DEFAULT_VIEW_LABELS","DEFAULT_CELL_WIDTHS","MARKER_LABEL_GAP","MARKER_LABEL_OFFSET","MARKER_LABEL_TOP","MARKER_LABEL_LANE_HEIGHT","TimelineMarkers","markers","showLabels","containerRef","React","labelRefs","diamondRefs","container","positionLabels","containerWidth","candidates","marker","left","key","label","markerLeft","labelWidth","labelLeft","laneRightEdges","first","second","candidate","lane","rightEdge","top","diamond","resizeObserver","jsx","jsxs","cn","Fragment","element","TimelineGrid","intervals","highlightedDate","interval","index","includesDate","TimelineHeader","groups","nameColumnHeader","nameColumnWidth","group","GanttChart","items","view","defaultView","views","viewLabels","onViewChange","startDate","endDate","locale","rowHeight","cellWidths","addItemLabel","onAddItem","onRefresh","showFullscreen","toolbarActions","renderItem","renderBar","formatDateRange","className","ariaLabel","props","ref","rootRef","fullscreenSupported","setFullscreenSupported","uncontrolledView","setUncontrolledView","activeView","range","getTimelineRange","timeline","createTimeline","activeHighlightedDate","toDate","activeViewLabels","positionedMarkers","markerDate","getMarkerPosition","cellWidth","timelineWidth","chartWidth","handleRootRef","handleViewChange","nextView","handleToggleFullscreen","GanttToolbar","Plus","item","itemIndex","progress","clampProgress","barPosition","getBarPosition","formattedDateRange","defaultFormatDateRange"],"mappings":"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"}