@tonyarbor/components 0.2.0 → 0.2.1

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 (108) hide show
  1. package/dist/Banner.d.mts +59 -0
  2. package/dist/Banner.d.ts +59 -0
  3. package/dist/Banner.js +222 -0
  4. package/dist/Banner.js.map +1 -0
  5. package/dist/Banner.mjs +7 -0
  6. package/dist/Banner.mjs.map +1 -0
  7. package/dist/Checkbox.d.mts +4 -0
  8. package/dist/Checkbox.d.ts +4 -0
  9. package/dist/Checkbox.js +45 -16
  10. package/dist/Checkbox.js.map +1 -1
  11. package/dist/Checkbox.mjs +1 -1
  12. package/dist/DatePicker.d.mts +68 -0
  13. package/dist/DatePicker.d.ts +68 -0
  14. package/dist/DatePicker.js +490 -0
  15. package/dist/DatePicker.js.map +1 -0
  16. package/dist/DatePicker.mjs +7 -0
  17. package/dist/DatePicker.mjs.map +1 -0
  18. package/dist/Pagination.d.mts +36 -0
  19. package/dist/Pagination.d.ts +36 -0
  20. package/dist/Pagination.js +301 -0
  21. package/dist/Pagination.js.map +1 -0
  22. package/dist/Pagination.mjs +7 -0
  23. package/dist/Pagination.mjs.map +1 -0
  24. package/dist/Radio.js +32 -12
  25. package/dist/Radio.js.map +1 -1
  26. package/dist/Radio.mjs +1 -1
  27. package/dist/Table.d.mts +80 -0
  28. package/dist/Table.d.ts +80 -0
  29. package/dist/Table.js +347 -0
  30. package/dist/Table.js.map +1 -0
  31. package/dist/Table.mjs +8 -0
  32. package/dist/Table.mjs.map +1 -0
  33. package/dist/TableControls.d.mts +76 -0
  34. package/dist/TableControls.d.ts +76 -0
  35. package/dist/TableControls.js +461 -0
  36. package/dist/TableControls.js.map +1 -0
  37. package/dist/TableControls.mjs +7 -0
  38. package/dist/TableControls.mjs.map +1 -0
  39. package/dist/TableFooterPagination.d.mts +56 -0
  40. package/dist/TableFooterPagination.d.ts +56 -0
  41. package/dist/TableFooterPagination.js +499 -0
  42. package/dist/TableFooterPagination.js.map +1 -0
  43. package/dist/TableFooterPagination.mjs +7 -0
  44. package/dist/TableFooterPagination.mjs.map +1 -0
  45. package/dist/Tabs.d.mts +50 -0
  46. package/dist/Tabs.d.ts +50 -0
  47. package/dist/Tabs.js +187 -0
  48. package/dist/Tabs.js.map +1 -0
  49. package/dist/Tabs.mjs +7 -0
  50. package/dist/Tabs.mjs.map +1 -0
  51. package/dist/TextArea.d.mts +64 -0
  52. package/dist/TextArea.d.ts +64 -0
  53. package/dist/TextArea.js +171 -0
  54. package/dist/TextArea.js.map +1 -0
  55. package/dist/TextArea.mjs +7 -0
  56. package/dist/TextArea.mjs.map +1 -0
  57. package/dist/Toast.d.mts +48 -0
  58. package/dist/Toast.d.ts +48 -0
  59. package/dist/Toast.js +169 -0
  60. package/dist/Toast.js.map +1 -0
  61. package/dist/Toast.mjs +7 -0
  62. package/dist/Toast.mjs.map +1 -0
  63. package/dist/Toggle.d.mts +48 -0
  64. package/dist/Toggle.d.ts +48 -0
  65. package/dist/Toggle.js +291 -0
  66. package/dist/Toggle.js.map +1 -0
  67. package/dist/Toggle.mjs +7 -0
  68. package/dist/Toggle.mjs.map +1 -0
  69. package/dist/Tooltip.d.mts +32 -0
  70. package/dist/Tooltip.d.ts +32 -0
  71. package/dist/Tooltip.js +109 -0
  72. package/dist/Tooltip.js.map +1 -0
  73. package/dist/Tooltip.mjs +7 -0
  74. package/dist/Tooltip.mjs.map +1 -0
  75. package/dist/chunk-52TG3BFX.mjs +463 -0
  76. package/dist/chunk-52TG3BFX.mjs.map +1 -0
  77. package/dist/chunk-AI2U34CF.mjs +159 -0
  78. package/dist/chunk-AI2U34CF.mjs.map +1 -0
  79. package/dist/chunk-C25FFMRQ.mjs +255 -0
  80. package/dist/chunk-C25FFMRQ.mjs.map +1 -0
  81. package/dist/{chunk-BCYJIUQX.mjs → chunk-CUTYEIFE.mjs} +47 -18
  82. package/dist/chunk-CUTYEIFE.mjs.map +1 -0
  83. package/dist/chunk-DULH2KRW.mjs +133 -0
  84. package/dist/chunk-DULH2KRW.mjs.map +1 -0
  85. package/dist/chunk-G5NVKF2G.mjs +434 -0
  86. package/dist/chunk-G5NVKF2G.mjs.map +1 -0
  87. package/dist/{chunk-ARBHNHO7.mjs → chunk-M6DVBEEL.mjs} +33 -13
  88. package/dist/chunk-M6DVBEEL.mjs.map +1 -0
  89. package/dist/chunk-MBUMR2XJ.mjs +135 -0
  90. package/dist/chunk-MBUMR2XJ.mjs.map +1 -0
  91. package/dist/chunk-MNH2TGUX.mjs +73 -0
  92. package/dist/chunk-MNH2TGUX.mjs.map +1 -0
  93. package/dist/chunk-RRMG2SSZ.mjs +265 -0
  94. package/dist/chunk-RRMG2SSZ.mjs.map +1 -0
  95. package/dist/chunk-U4JXKZZG.mjs +186 -0
  96. package/dist/chunk-U4JXKZZG.mjs.map +1 -0
  97. package/dist/chunk-W55QJIAN.mjs +467 -0
  98. package/dist/chunk-W55QJIAN.mjs.map +1 -0
  99. package/dist/chunk-YV4OXFIM.mjs +151 -0
  100. package/dist/chunk-YV4OXFIM.mjs.map +1 -0
  101. package/dist/index.d.mts +11 -0
  102. package/dist/index.d.ts +11 -0
  103. package/dist/index.js +2752 -30
  104. package/dist/index.js.map +1 -1
  105. package/dist/index.mjs +47 -3
  106. package/package.json +58 -1
  107. package/dist/chunk-ARBHNHO7.mjs.map +0 -1
  108. package/dist/chunk-BCYJIUQX.mjs.map +0 -1
@@ -0,0 +1,186 @@
1
+ // src/Banner/Banner.tsx
2
+ import * as React from "react";
3
+ import { clsx } from "clsx";
4
+ import { AlertCircle, AlertTriangle, Info, X } from "lucide-react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ var containerStyles = {
7
+ display: "flex",
8
+ alignItems: "flex-start",
9
+ padding: "16px",
10
+ borderRadius: "8px",
11
+ border: "1px solid",
12
+ width: "100%",
13
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
14
+ };
15
+ var iconContainerStyles = {
16
+ flexShrink: 0,
17
+ width: "24px",
18
+ height: "24px",
19
+ display: "flex",
20
+ alignItems: "center",
21
+ justifyContent: "center"
22
+ };
23
+ var contentContainerStyles = {
24
+ flex: 1,
25
+ display: "flex",
26
+ flexDirection: "column",
27
+ minWidth: 0
28
+ };
29
+ var titleStyles = {
30
+ fontSize: "18px",
31
+ fontWeight: 600,
32
+ lineHeight: "1.25",
33
+ marginBottom: "8px"
34
+ };
35
+ var messageStyles = {
36
+ fontSize: "13px",
37
+ fontWeight: 400,
38
+ lineHeight: "1.5",
39
+ margin: 0
40
+ };
41
+ var actionContainerStyles = {
42
+ display: "flex",
43
+ flexDirection: "column",
44
+ justifyContent: "flex-end",
45
+ alignItems: "flex-end",
46
+ alignSelf: "stretch",
47
+ flexShrink: 0
48
+ };
49
+ var actionButtonStyles = {
50
+ background: "none",
51
+ border: "none",
52
+ padding: 0,
53
+ fontSize: "13px",
54
+ fontWeight: 600,
55
+ lineHeight: "1.5",
56
+ textDecoration: "underline",
57
+ textUnderlinePosition: "from-font",
58
+ cursor: "pointer",
59
+ fontFamily: "inherit"
60
+ };
61
+ var closeButtonStyles = {
62
+ background: "none",
63
+ border: "none",
64
+ padding: "4px",
65
+ cursor: "pointer",
66
+ display: "flex",
67
+ alignItems: "center",
68
+ justifyContent: "center",
69
+ flexShrink: 0,
70
+ marginLeft: "8px"
71
+ };
72
+ var variantConfig = {
73
+ warning: {
74
+ backgroundColor: "#fffaf5",
75
+ borderColor: "#e4720d",
76
+ textColor: "#611f00",
77
+ actionColor: "#a74102",
78
+ icon: AlertTriangle
79
+ },
80
+ destructive: {
81
+ backgroundColor: "#fff5f5",
82
+ borderColor: "#c93232",
83
+ textColor: "#610202",
84
+ actionColor: "#920a0a",
85
+ icon: AlertCircle
86
+ },
87
+ information: {
88
+ backgroundColor: "#f5fbff",
89
+ borderColor: "#2c8bca",
90
+ textColor: "#053a61",
91
+ actionColor: "#024f83",
92
+ icon: Info
93
+ },
94
+ neutral: {
95
+ backgroundColor: "transparent",
96
+ borderColor: "#b3b3b3",
97
+ textColor: "#2f2f2f",
98
+ actionColor: "#2f2f2f",
99
+ icon: Info
100
+ }
101
+ };
102
+ var Banner = React.forwardRef(
103
+ ({
104
+ variant = "information",
105
+ title,
106
+ message,
107
+ icon = true,
108
+ actionLabel,
109
+ onAction,
110
+ onClose,
111
+ className,
112
+ style,
113
+ "data-testid": dataTestId
114
+ }, ref) => {
115
+ const config = variantConfig[variant];
116
+ const DefaultIcon = config.icon;
117
+ const showIcon = icon !== false;
118
+ const iconElement = icon === true || icon === void 0 ? /* @__PURE__ */ jsx(DefaultIcon, { size: 20, strokeWidth: 2 }) : icon;
119
+ const containerStylesCombined = {
120
+ ...containerStyles,
121
+ backgroundColor: config.backgroundColor,
122
+ borderColor: config.borderColor,
123
+ color: config.textColor,
124
+ gap: showIcon ? "16px" : "0px",
125
+ ...style
126
+ };
127
+ const titleStylesCombined = {
128
+ ...titleStyles,
129
+ color: config.textColor
130
+ };
131
+ const messageStylesCombined = {
132
+ ...messageStyles,
133
+ color: config.textColor
134
+ };
135
+ const actionButtonStylesCombined = {
136
+ ...actionButtonStyles,
137
+ color: config.actionColor
138
+ };
139
+ const closeButtonStylesCombined = {
140
+ ...closeButtonStyles,
141
+ color: config.textColor
142
+ };
143
+ return /* @__PURE__ */ jsxs(
144
+ "div",
145
+ {
146
+ ref,
147
+ className: clsx("arbor-banner", `arbor-banner--${variant}`, className),
148
+ style: containerStylesCombined,
149
+ "data-testid": dataTestId,
150
+ role: "alert",
151
+ children: [
152
+ showIcon && /* @__PURE__ */ jsx("div", { style: { ...iconContainerStyles, color: config.textColor }, children: iconElement }),
153
+ /* @__PURE__ */ jsxs("div", { style: contentContainerStyles, children: [
154
+ title && /* @__PURE__ */ jsx("div", { style: titleStylesCombined, children: title }),
155
+ /* @__PURE__ */ jsx("p", { style: messageStylesCombined, children: message })
156
+ ] }),
157
+ actionLabel && onAction && /* @__PURE__ */ jsx("div", { style: actionContainerStyles, children: /* @__PURE__ */ jsx(
158
+ "button",
159
+ {
160
+ type: "button",
161
+ onClick: onAction,
162
+ style: actionButtonStylesCombined,
163
+ children: actionLabel
164
+ }
165
+ ) }),
166
+ onClose && /* @__PURE__ */ jsx(
167
+ "button",
168
+ {
169
+ type: "button",
170
+ onClick: onClose,
171
+ style: closeButtonStylesCombined,
172
+ "aria-label": "Close banner",
173
+ children: /* @__PURE__ */ jsx(X, { size: 20 })
174
+ }
175
+ )
176
+ ]
177
+ }
178
+ );
179
+ }
180
+ );
181
+ Banner.displayName = "Banner";
182
+
183
+ export {
184
+ Banner
185
+ };
186
+ //# sourceMappingURL=chunk-U4JXKZZG.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Banner/Banner.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { AlertCircle, AlertTriangle, Info, X } from 'lucide-react';\n\nexport type BannerVariant = 'warning' | 'destructive' | 'information' | 'neutral';\n\nexport interface BannerProps {\n /**\n * Banner variant - determines color scheme\n */\n variant?: BannerVariant;\n /**\n * Optional title text\n */\n title?: string;\n /**\n * Main message/description text\n */\n message: string;\n /**\n * Optional icon (pass false to hide default icon, or pass custom ReactNode)\n */\n icon?: React.ReactNode | boolean;\n /**\n * Optional action button label\n */\n actionLabel?: string;\n /**\n * Action button click handler\n */\n onAction?: () => void;\n /**\n * Optional close button\n */\n onClose?: () => void;\n /**\n * Custom className\n */\n className?: string;\n /**\n * Custom style\n */\n style?: React.CSSProperties;\n /**\n * Test ID for testing\n */\n 'data-testid'?: string;\n}\n\nconst containerStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'flex-start',\n padding: '16px',\n borderRadius: '8px',\n border: '1px solid',\n width: '100%',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n};\n\nconst iconContainerStyles: React.CSSProperties = {\n flexShrink: 0,\n width: '24px',\n height: '24px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n};\n\nconst contentContainerStyles: React.CSSProperties = {\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n};\n\nconst titleStyles: React.CSSProperties = {\n fontSize: '18px',\n fontWeight: 600,\n lineHeight: '1.25',\n marginBottom: '8px',\n};\n\nconst messageStyles: React.CSSProperties = {\n fontSize: '13px',\n fontWeight: 400,\n lineHeight: '1.5',\n margin: 0,\n};\n\nconst actionContainerStyles: React.CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'flex-end',\n alignItems: 'flex-end',\n alignSelf: 'stretch',\n flexShrink: 0,\n};\n\nconst actionButtonStyles: React.CSSProperties = {\n background: 'none',\n border: 'none',\n padding: 0,\n fontSize: '13px',\n fontWeight: 600,\n lineHeight: '1.5',\n textDecoration: 'underline',\n textUnderlinePosition: 'from-font',\n cursor: 'pointer',\n fontFamily: 'inherit',\n};\n\nconst closeButtonStyles: React.CSSProperties = {\n background: 'none',\n border: 'none',\n padding: '4px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n marginLeft: '8px',\n};\n\nconst variantConfig = {\n warning: {\n backgroundColor: '#fffaf5',\n borderColor: '#e4720d',\n textColor: '#611f00',\n actionColor: '#a74102',\n icon: AlertTriangle,\n },\n destructive: {\n backgroundColor: '#fff5f5',\n borderColor: '#c93232',\n textColor: '#610202',\n actionColor: '#920a0a',\n icon: AlertCircle,\n },\n information: {\n backgroundColor: '#f5fbff',\n borderColor: '#2c8bca',\n textColor: '#053a61',\n actionColor: '#024f83',\n icon: Info,\n },\n neutral: {\n backgroundColor: 'transparent',\n borderColor: '#b3b3b3',\n textColor: '#2f2f2f',\n actionColor: '#2f2f2f',\n icon: Info,\n },\n};\n\n/**\n * Banner component - Arbor Design System\n *\n * Informational banners with 4 variants (warning, destructive, information, neutral)\n * and optional title, icon, and action button.\n *\n * IMPORTANT: Banners are always displayed inline with page content (not overlays).\n * They flow with the document layout and push other content down.\n *\n * For overlay notifications in the top-right corner, use the Toast component instead.\n */\nexport const Banner = React.forwardRef<HTMLDivElement, BannerProps>(\n (\n {\n variant = 'information',\n title,\n message,\n icon = true,\n actionLabel,\n onAction,\n onClose,\n className,\n style,\n 'data-testid': dataTestId,\n },\n ref\n ) => {\n const config = variantConfig[variant];\n const DefaultIcon = config.icon;\n\n // Determine what icon to show\n const showIcon = icon !== false;\n const iconElement =\n icon === true || icon === undefined ? (\n <DefaultIcon size={20} strokeWidth={2} />\n ) : (\n icon\n );\n\n const containerStylesCombined: React.CSSProperties = {\n ...containerStyles,\n backgroundColor: config.backgroundColor,\n borderColor: config.borderColor,\n color: config.textColor,\n gap: showIcon ? '16px' : '0px',\n ...style,\n };\n\n const titleStylesCombined: React.CSSProperties = {\n ...titleStyles,\n color: config.textColor,\n };\n\n const messageStylesCombined: React.CSSProperties = {\n ...messageStyles,\n color: config.textColor,\n };\n\n const actionButtonStylesCombined: React.CSSProperties = {\n ...actionButtonStyles,\n color: config.actionColor,\n };\n\n const closeButtonStylesCombined: React.CSSProperties = {\n ...closeButtonStyles,\n color: config.textColor,\n };\n\n return (\n <div\n ref={ref}\n className={clsx('arbor-banner', `arbor-banner--${variant}`, className)}\n style={containerStylesCombined}\n data-testid={dataTestId}\n role=\"alert\"\n >\n {showIcon && (\n <div style={{ ...iconContainerStyles, color: config.textColor }}>\n {iconElement}\n </div>\n )}\n\n <div style={contentContainerStyles}>\n {title && <div style={titleStylesCombined}>{title}</div>}\n <p style={messageStylesCombined}>{message}</p>\n </div>\n\n {actionLabel && onAction && (\n <div style={actionContainerStyles}>\n <button\n type=\"button\"\n onClick={onAction}\n style={actionButtonStylesCombined}\n >\n {actionLabel}\n </button>\n </div>\n )}\n\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n style={closeButtonStylesCombined}\n aria-label=\"Close banner\"\n >\n <X size={20} />\n </button>\n )}\n </div>\n );\n }\n);\n\nBanner.displayName = 'Banner';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,467 @@
1
+ // src/DatePicker/DatePicker.tsx
2
+ import * as React from "react";
3
+ import { clsx } from "clsx";
4
+ import * as Popover from "@radix-ui/react-popover";
5
+ import { Calendar, ChevronLeft, ChevronRight } from "lucide-react";
6
+ import {
7
+ format,
8
+ parse,
9
+ isValid,
10
+ startOfMonth,
11
+ endOfMonth,
12
+ eachDayOfInterval,
13
+ isSameDay,
14
+ isToday,
15
+ addMonths,
16
+ subMonths,
17
+ startOfWeek,
18
+ endOfWeek
19
+ } from "date-fns";
20
+ import { jsx, jsxs } from "react/jsx-runtime";
21
+ var wrapperStyles = {
22
+ display: "flex",
23
+ flexDirection: "column",
24
+ gap: "4px"
25
+ };
26
+ var labelStyles = {
27
+ fontSize: "11px",
28
+ fontWeight: 600,
29
+ color: "#2f2f2f",
30
+ textTransform: "uppercase",
31
+ letterSpacing: "0.5px",
32
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
33
+ };
34
+ var inputContainerStyles = {
35
+ position: "relative",
36
+ display: "flex",
37
+ alignItems: "center"
38
+ };
39
+ var inputStyles = {
40
+ width: "100%",
41
+ height: "36px",
42
+ padding: "0 36px 0 12px",
43
+ fontSize: "13px",
44
+ border: "1px solid #d1d1d1",
45
+ borderRadius: "8px",
46
+ outline: "none",
47
+ transition: "all 0.2s ease-in-out",
48
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
49
+ backgroundColor: "#ffffff",
50
+ color: "#2f2f2f"
51
+ };
52
+ var iconButtonStyles = {
53
+ position: "absolute",
54
+ right: "8px",
55
+ display: "flex",
56
+ alignItems: "center",
57
+ justifyContent: "center",
58
+ padding: "4px",
59
+ cursor: "pointer",
60
+ color: "#595959",
61
+ backgroundColor: "transparent",
62
+ border: "none"
63
+ };
64
+ var helperTextStyles = {
65
+ fontSize: "11px",
66
+ color: "#595959",
67
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
68
+ };
69
+ var calendarPopoverStyles = {
70
+ backgroundColor: "#ffffff",
71
+ border: "1px solid #efefef",
72
+ borderRadius: "8px",
73
+ padding: "16px",
74
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)",
75
+ minWidth: "320px",
76
+ zIndex: 1e3
77
+ };
78
+ var calendarHeaderStyles = {
79
+ display: "flex",
80
+ alignItems: "center",
81
+ justifyContent: "space-between",
82
+ marginBottom: "16px",
83
+ gap: "8px"
84
+ };
85
+ var monthYearContainerStyles = {
86
+ display: "flex",
87
+ gap: "8px",
88
+ flex: 1
89
+ };
90
+ var selectStyles = {
91
+ padding: "6px 8px",
92
+ fontSize: "13px",
93
+ border: "1px solid #d1d1d1",
94
+ borderRadius: "6px",
95
+ backgroundColor: "#ffffff",
96
+ color: "#2f2f2f",
97
+ cursor: "pointer",
98
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
99
+ outline: "none"
100
+ };
101
+ var navButtonStyles = {
102
+ display: "flex",
103
+ alignItems: "center",
104
+ justifyContent: "center",
105
+ width: "28px",
106
+ height: "28px",
107
+ border: "none",
108
+ backgroundColor: "transparent",
109
+ cursor: "pointer",
110
+ borderRadius: "4px",
111
+ color: "#2f2f2f",
112
+ transition: "background-color 0.2s"
113
+ };
114
+ var weekDaysStyles = {
115
+ display: "grid",
116
+ gridTemplateColumns: "repeat(7, 1fr)",
117
+ gap: "4px",
118
+ marginBottom: "8px"
119
+ };
120
+ var weekDayStyles = {
121
+ fontSize: "11px",
122
+ fontWeight: 600,
123
+ color: "#7e7e7e",
124
+ textAlign: "center",
125
+ padding: "4px",
126
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
127
+ };
128
+ var daysGridStyles = {
129
+ display: "grid",
130
+ gridTemplateColumns: "repeat(7, 1fr)",
131
+ gap: "4px"
132
+ };
133
+ var dayButtonStyles = {
134
+ width: "36px",
135
+ height: "36px",
136
+ display: "flex",
137
+ alignItems: "center",
138
+ justifyContent: "center",
139
+ border: "none",
140
+ backgroundColor: "transparent",
141
+ borderRadius: "50%",
142
+ cursor: "pointer",
143
+ fontSize: "13px",
144
+ color: "#2f2f2f",
145
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
146
+ transition: "all 0.2s"
147
+ };
148
+ var footerStyles = {
149
+ display: "flex",
150
+ justifyContent: "flex-end",
151
+ marginTop: "12px",
152
+ paddingTop: "12px",
153
+ borderTop: "1px solid #efefef"
154
+ };
155
+ var todayButtonStyles = {
156
+ padding: "6px 12px",
157
+ fontSize: "13px",
158
+ fontWeight: 500,
159
+ color: "#16a33d",
160
+ backgroundColor: "transparent",
161
+ border: "none",
162
+ cursor: "pointer",
163
+ borderRadius: "6px",
164
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
165
+ transition: "background-color 0.2s"
166
+ };
167
+ var MONTHS = [
168
+ "January",
169
+ "February",
170
+ "March",
171
+ "April",
172
+ "May",
173
+ "June",
174
+ "July",
175
+ "August",
176
+ "September",
177
+ "October",
178
+ "November",
179
+ "December"
180
+ ];
181
+ var WEEKDAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
182
+ var DatePicker = React.forwardRef(
183
+ ({
184
+ value,
185
+ onChange,
186
+ label,
187
+ placeholder = "DD/MM/YYYY",
188
+ helperText,
189
+ error,
190
+ state = "default",
191
+ disabled = false,
192
+ className,
193
+ style,
194
+ "data-testid": dataTestId,
195
+ minDate,
196
+ maxDate,
197
+ dateFormat = "dd/MM/yyyy"
198
+ }, ref) => {
199
+ const [open, setOpen] = React.useState(false);
200
+ const [inputValue, setInputValue] = React.useState("");
201
+ const [viewDate, setViewDate] = React.useState(value || /* @__PURE__ */ new Date());
202
+ const inputId = React.useId();
203
+ React.useEffect(() => {
204
+ if (value && isValid(value)) {
205
+ setInputValue(format(value, dateFormat));
206
+ } else {
207
+ setInputValue("");
208
+ }
209
+ }, [value, dateFormat]);
210
+ React.useEffect(() => {
211
+ if (value && isValid(value)) {
212
+ setViewDate(value);
213
+ }
214
+ }, [value]);
215
+ const handleInputChange = (e) => {
216
+ const newValue = e.target.value;
217
+ setInputValue(newValue);
218
+ const parsedDate = parse(newValue, dateFormat, /* @__PURE__ */ new Date());
219
+ if (isValid(parsedDate)) {
220
+ onChange?.(parsedDate);
221
+ setViewDate(parsedDate);
222
+ }
223
+ };
224
+ const handleInputBlur = () => {
225
+ if (value && isValid(value)) {
226
+ setInputValue(format(value, dateFormat));
227
+ } else if (!inputValue) {
228
+ onChange?.(void 0);
229
+ }
230
+ };
231
+ const handleDateSelect = (date) => {
232
+ onChange?.(date);
233
+ setOpen(false);
234
+ };
235
+ const handleTodayClick = () => {
236
+ const today = /* @__PURE__ */ new Date();
237
+ onChange?.(today);
238
+ setViewDate(today);
239
+ setOpen(false);
240
+ };
241
+ const handleMonthChange = (e) => {
242
+ const newMonth = parseInt(e.target.value, 10);
243
+ const newDate = new Date(viewDate);
244
+ newDate.setMonth(newMonth);
245
+ setViewDate(newDate);
246
+ };
247
+ const handleYearChange = (e) => {
248
+ const newYear = parseInt(e.target.value, 10);
249
+ const newDate = new Date(viewDate);
250
+ newDate.setFullYear(newYear);
251
+ setViewDate(newDate);
252
+ };
253
+ const handlePrevMonth = () => {
254
+ setViewDate(subMonths(viewDate, 1));
255
+ };
256
+ const handleNextMonth = () => {
257
+ setViewDate(addMonths(viewDate, 1));
258
+ };
259
+ const monthStart = startOfMonth(viewDate);
260
+ const monthEnd = endOfMonth(viewDate);
261
+ const startDate = startOfWeek(monthStart, { weekStartsOn: 1 });
262
+ const endDate = endOfWeek(monthEnd, { weekStartsOn: 1 });
263
+ const days = eachDayOfInterval({ start: startDate, end: endDate });
264
+ const isDateDisabled = (date) => {
265
+ if (minDate && date < minDate) return true;
266
+ if (maxDate && date > maxDate) return true;
267
+ return false;
268
+ };
269
+ const currentYear = viewDate.getFullYear();
270
+ const yearOptions = Array.from({ length: 201 }, (_, i) => currentYear - 100 + i);
271
+ const currentState = error ? "error" : state;
272
+ const getInputStyles = () => {
273
+ const styles = { ...inputStyles };
274
+ if (disabled) {
275
+ styles.backgroundColor = "#f8f8f8";
276
+ styles.borderColor = "#efefef";
277
+ styles.color = "#7e7e7e";
278
+ styles.cursor = "not-allowed";
279
+ } else if (currentState === "error") {
280
+ styles.borderColor = "#e02f1d";
281
+ } else if (currentState === "success") {
282
+ styles.borderColor = "#16a33d";
283
+ }
284
+ return styles;
285
+ };
286
+ return /* @__PURE__ */ jsxs(
287
+ "div",
288
+ {
289
+ className: clsx("arbor-datepicker-wrapper", className),
290
+ style: { ...wrapperStyles, ...style },
291
+ "data-testid": dataTestId,
292
+ children: [
293
+ label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, style: labelStyles, children: label }),
294
+ /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, children: [
295
+ /* @__PURE__ */ jsxs("div", { style: inputContainerStyles, children: [
296
+ /* @__PURE__ */ jsx(
297
+ "input",
298
+ {
299
+ ref,
300
+ id: inputId,
301
+ type: "text",
302
+ value: inputValue,
303
+ onChange: handleInputChange,
304
+ onBlur: handleInputBlur,
305
+ placeholder,
306
+ disabled,
307
+ style: getInputStyles(),
308
+ "aria-label": label || "Date picker"
309
+ }
310
+ ),
311
+ /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
312
+ "button",
313
+ {
314
+ type: "button",
315
+ style: {
316
+ ...iconButtonStyles,
317
+ cursor: disabled ? "not-allowed" : "pointer"
318
+ },
319
+ disabled,
320
+ "aria-label": "Open calendar",
321
+ children: /* @__PURE__ */ jsx(Calendar, { size: 16 })
322
+ }
323
+ ) })
324
+ ] }),
325
+ /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
326
+ Popover.Content,
327
+ {
328
+ align: "start",
329
+ sideOffset: 4,
330
+ style: calendarPopoverStyles,
331
+ children: [
332
+ /* @__PURE__ */ jsxs("div", { style: calendarHeaderStyles, children: [
333
+ /* @__PURE__ */ jsx(
334
+ "button",
335
+ {
336
+ type: "button",
337
+ onClick: handlePrevMonth,
338
+ style: navButtonStyles,
339
+ onMouseEnter: (e) => {
340
+ e.currentTarget.style.backgroundColor = "#f8f8f8";
341
+ },
342
+ onMouseLeave: (e) => {
343
+ e.currentTarget.style.backgroundColor = "transparent";
344
+ },
345
+ "aria-label": "Previous month",
346
+ children: /* @__PURE__ */ jsx(ChevronLeft, { size: 16 })
347
+ }
348
+ ),
349
+ /* @__PURE__ */ jsxs("div", { style: monthYearContainerStyles, children: [
350
+ /* @__PURE__ */ jsx(
351
+ "select",
352
+ {
353
+ value: viewDate.getMonth(),
354
+ onChange: handleMonthChange,
355
+ style: selectStyles,
356
+ "aria-label": "Select month",
357
+ children: MONTHS.map((month, index) => /* @__PURE__ */ jsx("option", { value: index, children: month }, month))
358
+ }
359
+ ),
360
+ /* @__PURE__ */ jsx(
361
+ "select",
362
+ {
363
+ value: viewDate.getFullYear(),
364
+ onChange: handleYearChange,
365
+ style: selectStyles,
366
+ "aria-label": "Select year",
367
+ children: yearOptions.map((year) => /* @__PURE__ */ jsx("option", { value: year, children: year }, year))
368
+ }
369
+ )
370
+ ] }),
371
+ /* @__PURE__ */ jsx(
372
+ "button",
373
+ {
374
+ type: "button",
375
+ onClick: handleNextMonth,
376
+ style: navButtonStyles,
377
+ onMouseEnter: (e) => {
378
+ e.currentTarget.style.backgroundColor = "#f8f8f8";
379
+ },
380
+ onMouseLeave: (e) => {
381
+ e.currentTarget.style.backgroundColor = "transparent";
382
+ },
383
+ "aria-label": "Next month",
384
+ children: /* @__PURE__ */ jsx(ChevronRight, { size: 16 })
385
+ }
386
+ )
387
+ ] }),
388
+ /* @__PURE__ */ jsx("div", { style: weekDaysStyles, children: WEEKDAYS.map((day) => /* @__PURE__ */ jsx("div", { style: weekDayStyles, children: day }, day)) }),
389
+ /* @__PURE__ */ jsx("div", { style: daysGridStyles, children: days.map((day) => {
390
+ const isCurrentMonth = day.getMonth() === viewDate.getMonth();
391
+ const isSelected = value && isSameDay(day, value);
392
+ const isTodayDate = isToday(day);
393
+ const isDayDisabled = isDateDisabled(day);
394
+ const getDayButtonStyles = () => {
395
+ const styles = { ...dayButtonStyles };
396
+ if (!isCurrentMonth) {
397
+ styles.color = "#d1d1d1";
398
+ }
399
+ if (isDayDisabled) {
400
+ styles.color = "#d1d1d1";
401
+ styles.cursor = "not-allowed";
402
+ }
403
+ if (isSelected) {
404
+ styles.backgroundColor = "#3cad51";
405
+ styles.color = "#ffffff";
406
+ } else if (isTodayDate && !isDayDisabled) {
407
+ styles.fontWeight = 600;
408
+ styles.color = "#16a33d";
409
+ }
410
+ return styles;
411
+ };
412
+ return /* @__PURE__ */ jsx(
413
+ "button",
414
+ {
415
+ type: "button",
416
+ onClick: () => !isDayDisabled && handleDateSelect(day),
417
+ disabled: isDayDisabled,
418
+ style: getDayButtonStyles(),
419
+ onMouseEnter: (e) => {
420
+ if (!isSelected && !isDayDisabled && isCurrentMonth) {
421
+ e.currentTarget.style.backgroundColor = "#f8f8f8";
422
+ }
423
+ },
424
+ onMouseLeave: (e) => {
425
+ if (!isSelected) {
426
+ e.currentTarget.style.backgroundColor = "transparent";
427
+ }
428
+ },
429
+ "aria-label": format(day, "MMMM d, yyyy"),
430
+ "aria-selected": isSelected,
431
+ children: format(day, "d")
432
+ },
433
+ day.toISOString()
434
+ );
435
+ }) }),
436
+ /* @__PURE__ */ jsx("div", { style: footerStyles, children: /* @__PURE__ */ jsx(
437
+ "button",
438
+ {
439
+ type: "button",
440
+ onClick: handleTodayClick,
441
+ style: todayButtonStyles,
442
+ onMouseEnter: (e) => {
443
+ e.currentTarget.style.backgroundColor = "#f8f8f8";
444
+ },
445
+ onMouseLeave: (e) => {
446
+ e.currentTarget.style.backgroundColor = "transparent";
447
+ },
448
+ children: "Today"
449
+ }
450
+ ) })
451
+ ]
452
+ }
453
+ ) })
454
+ ] }),
455
+ error && /* @__PURE__ */ jsx("span", { style: { ...helperTextStyles, color: "#e02f1d" }, children: error }),
456
+ !error && helperText && /* @__PURE__ */ jsx("span", { style: helperTextStyles, children: helperText })
457
+ ]
458
+ }
459
+ );
460
+ }
461
+ );
462
+ DatePicker.displayName = "DatePicker";
463
+
464
+ export {
465
+ DatePicker
466
+ };
467
+ //# sourceMappingURL=chunk-W55QJIAN.mjs.map