@macolmenerori/component-library 1.2.0 → 1.3.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.
package/README.md CHANGED
@@ -38,11 +38,12 @@ Import components from the library. You can use the main entry point or subpath
38
38
 
39
39
  ### Subpath Exports
40
40
 
41
- | Import Path | Components | Dependencies Required |
42
- | -------------------------------------------------- | -------------- | --------------------------------- |
43
- | `@macolmenerori/component-library` | All | react, react-markdown, remark-gfm |
44
- | `@macolmenerori/component-library/theme-switch` | ThemeSwitch | react |
45
- | `@macolmenerori/component-library/markdown-render` | MarkdownRender | react, react-markdown, remark-gfm |
41
+ | Import Path | Components | Dependencies Required |
42
+ | --------------------------------------------------- | --------------- | --------------------------------- |
43
+ | `@macolmenerori/component-library` | All | react, react-markdown, remark-gfm |
44
+ | `@macolmenerori/component-library/theme-switch` | ThemeSwitch | react |
45
+ | `@macolmenerori/component-library/monthly-calendar` | MonthlyCalendar | react |
46
+ | `@macolmenerori/component-library/markdown-render` | MarkdownRender | react, react-markdown, remark-gfm |
46
47
 
47
48
  ### Available Components
48
49
 
@@ -81,6 +82,40 @@ function App() {
81
82
 
82
83
  </details>
83
84
 
85
+ <details>
86
+ <summary><strong>MonthlyCalendar</strong> - A monthly calendar grid with annotation support</summary>
87
+
88
+ A zero-dependency monthly calendar component rendered as a semantic HTML table. Supports per-day annotations (any ReactNode), customizable headers, inline style overrides, and built-in light/dark themes.
89
+
90
+ **Props:**
91
+
92
+ - `year` (number, required): Full four-digit year (e.g. 2026)
93
+ - `month` (number, required): Month to display, 1-based (1 = January, 12 = December)
94
+ - `annotations` ((ReactNode | null | undefined)[], optional): Array of content per day. `annotations[0]` maps to Day 1
95
+ - `headers` (string[7], optional): Array of 7 weekday labels. Omit to hide the header row
96
+ - `style` (CSSProperties, optional): Inline styles merged onto the `<table>` element
97
+ - `darkMode` (boolean, optional): Enables dark color theme (default: `false`)
98
+
99
+ **Example:**
100
+
101
+ ```tsx
102
+ import { MonthlyCalendar } from '@macolmenerori/component-library/monthly-calendar';
103
+
104
+ function App() {
105
+ return (
106
+ <MonthlyCalendar
107
+ year={2026}
108
+ month={2}
109
+ headers={['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']}
110
+ />
111
+ );
112
+ }
113
+ ```
114
+
115
+ > **Note:** No CSS import is needed. MonthlyCalendar uses inline styles only.
116
+
117
+ </details>
118
+
84
119
  <details>
85
120
  <summary><strong>MarkdownRender</strong> - A component for rendering markdown strings as HTML</summary>
86
121
 
@@ -183,6 +218,7 @@ This will generate multiple entry points:
183
218
 
184
219
  - `dist/index.js` / `dist/index.cjs` - Main entry (all components)
185
220
  - `dist/theme-switch.js` / `dist/theme-switch.cjs` - ThemeSwitch only
221
+ - `dist/monthly-calendar.js` / `dist/monthly-calendar.cjs` - MonthlyCalendar only
186
222
  - `dist/markdown-render.js` / `dist/markdown-render.cjs` - MarkdownRender only
187
223
  - `dist/types/` - TypeScript declarations
188
224
 
@@ -190,8 +226,9 @@ This will generate multiple entry points:
190
226
 
191
227
  To publish a new version:
192
228
 
193
- 1. Build the library: `pnpm build`
194
- 2. Publish: `pnpm publish`
229
+ 1. Bump version with `pnpm release <major | minor | patch>`
230
+ 2. Build the library: `pnpm build`
231
+ 3. Publish: `pnpm publish`
195
232
 
196
233
  ## Technology Stack
197
234
 
@@ -0,0 +1,2 @@
1
+ "use strict";const e=require("react/jsx-runtime"),C=require("react"),j={dayColor:"#222",headerColor:"#555",annotationColor:"inherit"},b={dayColor:"#f0f0f0",headerColor:"#a0a0b8",annotationColor:"#d0d0e0"},w={borderCollapse:"collapse",border:"none",width:"100%",tableLayout:"fixed",fontFamily:"sans-serif"},y={border:"none",verticalAlign:"top",padding:0,position:"relative",textAlign:"center"},v=({year:s,month:i,annotations:d=[],headers:c,style:p={},darkMode:x=!1})=>{const a=x?b:j,g=C.useMemo(()=>{const t=new Date(s,i,0).getDate(),n=new Date(s,i-1,1).getDay(),o=Math.ceil((n+t)/7)*7,l=[];let r=1-n;for(let h=0;h<o/7;h++){const f=[];for(let u=0;u<7;u++)f.push(r>=1&&r<=t?r:null),r++;l.push(f)}return l},[s,i]),m={...w,...p};return e.jsxs("table",{style:m,children:[c&&e.jsx("thead",{children:e.jsx("tr",{children:c.map((t,n)=>e.jsx("th",{style:{...y,fontWeight:600,fontSize:"0.85rem",paddingBottom:6,color:a.headerColor},children:t},n))})}),e.jsx("tbody",{children:g.map((t,n)=>e.jsx("tr",{children:t.map((o,l)=>e.jsx("td",{style:y,children:e.jsx("div",{style:{width:"100%",paddingBottom:"100%",position:"relative"},children:e.jsx("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"flex-start",paddingTop:6,gap:4,overflow:"hidden"},children:o!==null&&e.jsxs(e.Fragment,{children:[e.jsx("span",{style:{fontFamily:"sans-serif",fontSize:"0.95rem",fontWeight:500,color:a.dayColor},children:o}),d[o-1]!=null&&e.jsx("div",{style:{fontSize:"0.75rem",lineHeight:1.2,overflow:"hidden",width:"100%",textAlign:"center",color:a.annotationColor},children:d[o-1]})]})})})},l))},n))})]})};exports.MonthlyCalendar=v;
2
+ //# sourceMappingURL=MonthlyCalendar-D-tD_2xK.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonthlyCalendar-D-tD_2xK.cjs","sources":["../src/components/MonthlyCalendar/MonthlyCalendar.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode, useMemo } from 'react';\n\n/**\n * Props for the MonthlyCalendar component\n */\nexport interface MonthlyCalendarProps {\n /** Full four-digit year (e.g. 2026) */\n year: number;\n /** Month to display, 1-based: 1 = January, 12 = December */\n month: number;\n /**\n * Array of React nodes, one per day of the month.\n * annotations[0] maps to Day 1, annotations[1] maps to Day 2, etc.\n * Use null or undefined for days with no annotation.\n */\n annotations?: (ReactNode | null | undefined)[];\n /**\n * Array of exactly 7 strings for the weekday header labels.\n * Omit to hide the header row entirely.\n */\n headers?: [string, string, string, string, string, string, string];\n /**\n * Inline styles merged onto the table element, overriding defaults via shallow spread.\n */\n style?: CSSProperties;\n /**\n * Enables the dark color theme for day numbers, headers, and annotation text.\n * The component does not set its own background — wrap it in a dark container when enabled.\n * @default false\n */\n darkMode?: boolean;\n}\n\n// ─── Theme definitions ───\n\nconst LIGHT_THEME = {\n dayColor: '#222',\n headerColor: '#555',\n annotationColor: 'inherit'\n};\n\nconst DARK_THEME = {\n dayColor: '#f0f0f0',\n headerColor: '#a0a0b8',\n annotationColor: '#d0d0e0'\n};\n\n// ─── Static style objects ───\n\nconst defaultTableStyle: CSSProperties = {\n borderCollapse: 'collapse',\n border: 'none',\n width: '100%',\n tableLayout: 'fixed',\n fontFamily: 'sans-serif'\n};\n\nconst defaultCellStyle: CSSProperties = {\n border: 'none',\n verticalAlign: 'top',\n padding: 0,\n position: 'relative',\n textAlign: 'center'\n};\n\n/**\n * MonthlyCalendar Component\n *\n * A zero-dependency monthly calendar grid rendered as a semantic HTML table.\n * Each day occupies a square cell with an optional annotation slot that accepts\n * any ReactNode (text, images, badges, icons, or entire sub-components).\n *\n * Features built-in light and dark themes, customizable headers, and\n * table-level style overrides. All styling is inline — no CSS files required.\n *\n * @component\n * @example\n * ```tsx\n * <MonthlyCalendar\n * year={2026}\n * month={2}\n * headers={['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']}\n * darkMode={false}\n * />\n * ```\n */\nconst MonthlyCalendar: React.FC<MonthlyCalendarProps> = ({\n year,\n month,\n annotations = [],\n headers,\n style = {},\n darkMode = false\n}) => {\n const theme = darkMode ? DARK_THEME : LIGHT_THEME;\n\n const weeks = useMemo(() => {\n const daysInMonth = new Date(year, month, 0).getDate();\n const startDay = new Date(year, month - 1, 1).getDay(); // 0=Sun\n const totalCells = Math.ceil((startDay + daysInMonth) / 7) * 7;\n const result: (number | null)[][] = [];\n let currentDay = 1 - startDay;\n\n for (let w = 0; w < totalCells / 7; w++) {\n const week: (number | null)[] = [];\n for (let d = 0; d < 7; d++) {\n week.push(currentDay >= 1 && currentDay <= daysInMonth ? currentDay : null);\n currentDay++;\n }\n result.push(week);\n }\n return result;\n }, [year, month]);\n\n const mergedTableStyle = { ...defaultTableStyle, ...style };\n\n return (\n <table style={mergedTableStyle}>\n {headers && (\n <thead>\n <tr>\n {headers.map((h, i) => (\n <th\n key={i}\n style={{\n ...defaultCellStyle,\n fontWeight: 600,\n fontSize: '0.85rem',\n paddingBottom: 6,\n color: theme.headerColor\n }}\n >\n {h}\n </th>\n ))}\n </tr>\n </thead>\n )}\n <tbody>\n {weeks.map((week, wi) => (\n <tr key={wi}>\n {week.map((day, di) => (\n <td key={di} style={defaultCellStyle}>\n <div\n style={{\n width: '100%',\n paddingBottom: '100%',\n position: 'relative'\n }}\n >\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'flex-start',\n paddingTop: 6,\n gap: 4,\n overflow: 'hidden'\n }}\n >\n {day !== null && (\n <>\n <span\n style={{\n fontFamily: 'sans-serif',\n fontSize: '0.95rem',\n fontWeight: 500,\n color: theme.dayColor\n }}\n >\n {day}\n </span>\n {annotations[day - 1] != null && (\n <div\n style={{\n fontSize: '0.75rem',\n lineHeight: 1.2,\n overflow: 'hidden',\n width: '100%',\n textAlign: 'center',\n color: theme.annotationColor\n }}\n >\n {annotations[day - 1]}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n );\n};\n\nexport default MonthlyCalendar;\n"],"names":["LIGHT_THEME","DARK_THEME","defaultTableStyle","defaultCellStyle","MonthlyCalendar","year","month","annotations","headers","style","darkMode","theme","weeks","useMemo","daysInMonth","startDay","totalCells","result","currentDay","w","week","d","mergedTableStyle","jsxs","jsx","h","i","wi","day","di","Fragment"],"mappings":"qEAmCMA,EAAc,CAClB,SAAU,OACV,YAAa,OACb,gBAAiB,SACnB,EAEMC,EAAa,CACjB,SAAU,UACV,YAAa,UACb,gBAAiB,SACnB,EAIMC,EAAmC,CACvC,eAAgB,WAChB,OAAQ,OACR,MAAO,OACP,YAAa,QACb,WAAY,YACd,EAEMC,EAAkC,CACtC,OAAQ,OACR,cAAe,MACf,QAAS,EACT,SAAU,WACV,UAAW,QACb,EAuBMC,EAAkD,CAAC,CACvD,KAAAC,EACA,MAAAC,EACA,YAAAC,EAAc,CAAA,EACd,QAAAC,EACA,MAAAC,EAAQ,CAAA,EACR,SAAAC,EAAW,EACb,IAAM,CACJ,MAAMC,EAAQD,EAAWT,EAAaD,EAEhCY,EAAQC,EAAAA,QAAQ,IAAM,CAC1B,MAAMC,EAAc,IAAI,KAAKT,EAAMC,EAAO,CAAC,EAAE,QAAA,EACvCS,EAAW,IAAI,KAAKV,EAAMC,EAAQ,EAAG,CAAC,EAAE,OAAA,EACxCU,EAAa,KAAK,MAAMD,EAAWD,GAAe,CAAC,EAAI,EACvDG,EAA8B,CAAA,EACpC,IAAIC,EAAa,EAAIH,EAErB,QAASI,EAAI,EAAGA,EAAIH,EAAa,EAAGG,IAAK,CACvC,MAAMC,EAA0B,CAAA,EAChC,QAASC,EAAI,EAAGA,EAAI,EAAGA,IACrBD,EAAK,KAAKF,GAAc,GAAKA,GAAcJ,EAAcI,EAAa,IAAI,EAC1EA,IAEFD,EAAO,KAAKG,CAAI,CAClB,CACA,OAAOH,CACT,EAAG,CAACZ,EAAMC,CAAK,CAAC,EAEVgB,EAAmB,CAAE,GAAGpB,EAAmB,GAAGO,CAAA,EAEpD,OACEc,EAAAA,KAAC,QAAA,CAAM,MAAOD,EACX,SAAA,CAAAd,GACCgB,EAAAA,IAAC,SACC,SAAAA,EAAAA,IAAC,KAAA,CACE,WAAQ,IAAI,CAACC,EAAGC,IACfF,EAAAA,IAAC,KAAA,CAEC,MAAO,CACL,GAAGrB,EACH,WAAY,IACZ,SAAU,UACV,cAAe,EACf,MAAOQ,EAAM,WAAA,EAGd,SAAAc,CAAA,EATIC,CAAA,CAWR,EACH,CAAA,CACF,QAED,QAAA,CACE,SAAAd,EAAM,IAAI,CAACQ,EAAMO,IAChBH,EAAAA,IAAC,KAAA,CACE,SAAAJ,EAAK,IAAI,CAACQ,EAAKC,IACdL,EAAAA,IAAC,KAAA,CAAY,MAAOrB,EAClB,SAAAqB,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,OACP,cAAe,OACf,SAAU,UAAA,EAGZ,SAAAA,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,WACV,MAAO,EACP,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,aAChB,WAAY,EACZ,IAAK,EACL,SAAU,QAAA,EAGX,SAAAI,IAAQ,MACPL,EAAAA,KAAAO,EAAAA,SAAA,CACE,SAAA,CAAAN,EAAAA,IAAC,OAAA,CACC,MAAO,CACL,WAAY,aACZ,SAAU,UACV,WAAY,IACZ,MAAOb,EAAM,QAAA,EAGd,SAAAiB,CAAA,CAAA,EAEFrB,EAAYqB,EAAM,CAAC,GAAK,MACvBJ,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,UACV,WAAY,IACZ,SAAU,SACV,MAAO,OACP,UAAW,SACX,MAAOb,EAAM,eAAA,EAGd,SAAAJ,EAAYqB,EAAM,CAAC,CAAA,CAAA,CACtB,CAAA,CAEJ,CAAA,CAAA,CAEJ,CAAA,GAjDKC,CAmDT,CACD,GAtDMF,CAuDT,CACD,CAAA,CACH,CAAA,EACF,CAEJ"}
@@ -0,0 +1,116 @@
1
+ import { jsxs as y, jsx as e, Fragment as w } from "react/jsx-runtime";
2
+ import { useMemo as x } from "react";
3
+ const v = {
4
+ dayColor: "#222",
5
+ headerColor: "#555",
6
+ annotationColor: "inherit"
7
+ }, D = {
8
+ dayColor: "#f0f0f0",
9
+ headerColor: "#a0a0b8",
10
+ annotationColor: "#d0d0e0"
11
+ }, M = {
12
+ borderCollapse: "collapse",
13
+ border: "none",
14
+ width: "100%",
15
+ tableLayout: "fixed",
16
+ fontFamily: "sans-serif"
17
+ }, m = {
18
+ border: "none",
19
+ verticalAlign: "top",
20
+ padding: 0,
21
+ position: "relative",
22
+ textAlign: "center"
23
+ }, A = ({
24
+ year: i,
25
+ month: a,
26
+ annotations: d = [],
27
+ headers: c,
28
+ style: g = {},
29
+ darkMode: u = !1
30
+ }) => {
31
+ const s = u ? D : v, C = x(() => {
32
+ const t = new Date(i, a, 0).getDate(), o = new Date(i, a - 1, 1).getDay(), l = Math.ceil((o + t) / 7) * 7, n = [];
33
+ let r = 1 - o;
34
+ for (let h = 0; h < l / 7; h++) {
35
+ const f = [];
36
+ for (let p = 0; p < 7; p++)
37
+ f.push(r >= 1 && r <= t ? r : null), r++;
38
+ n.push(f);
39
+ }
40
+ return n;
41
+ }, [i, a]), b = { ...M, ...g };
42
+ return /* @__PURE__ */ y("table", { style: b, children: [
43
+ c && /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ e("tr", { children: c.map((t, o) => /* @__PURE__ */ e(
44
+ "th",
45
+ {
46
+ style: {
47
+ ...m,
48
+ fontWeight: 600,
49
+ fontSize: "0.85rem",
50
+ paddingBottom: 6,
51
+ color: s.headerColor
52
+ },
53
+ children: t
54
+ },
55
+ o
56
+ )) }) }),
57
+ /* @__PURE__ */ e("tbody", { children: C.map((t, o) => /* @__PURE__ */ e("tr", { children: t.map((l, n) => /* @__PURE__ */ e("td", { style: m, children: /* @__PURE__ */ e(
58
+ "div",
59
+ {
60
+ style: {
61
+ width: "100%",
62
+ paddingBottom: "100%",
63
+ position: "relative"
64
+ },
65
+ children: /* @__PURE__ */ e(
66
+ "div",
67
+ {
68
+ style: {
69
+ position: "absolute",
70
+ inset: 0,
71
+ display: "flex",
72
+ flexDirection: "column",
73
+ alignItems: "center",
74
+ justifyContent: "flex-start",
75
+ paddingTop: 6,
76
+ gap: 4,
77
+ overflow: "hidden"
78
+ },
79
+ children: l !== null && /* @__PURE__ */ y(w, { children: [
80
+ /* @__PURE__ */ e(
81
+ "span",
82
+ {
83
+ style: {
84
+ fontFamily: "sans-serif",
85
+ fontSize: "0.95rem",
86
+ fontWeight: 500,
87
+ color: s.dayColor
88
+ },
89
+ children: l
90
+ }
91
+ ),
92
+ d[l - 1] != null && /* @__PURE__ */ e(
93
+ "div",
94
+ {
95
+ style: {
96
+ fontSize: "0.75rem",
97
+ lineHeight: 1.2,
98
+ overflow: "hidden",
99
+ width: "100%",
100
+ textAlign: "center",
101
+ color: s.annotationColor
102
+ },
103
+ children: d[l - 1]
104
+ }
105
+ )
106
+ ] })
107
+ }
108
+ )
109
+ }
110
+ ) }, n)) }, o)) })
111
+ ] });
112
+ };
113
+ export {
114
+ A as M
115
+ };
116
+ //# sourceMappingURL=MonthlyCalendar-D9jC2b2L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonthlyCalendar-D9jC2b2L.js","sources":["../src/components/MonthlyCalendar/MonthlyCalendar.tsx"],"sourcesContent":["import React, { CSSProperties, ReactNode, useMemo } from 'react';\n\n/**\n * Props for the MonthlyCalendar component\n */\nexport interface MonthlyCalendarProps {\n /** Full four-digit year (e.g. 2026) */\n year: number;\n /** Month to display, 1-based: 1 = January, 12 = December */\n month: number;\n /**\n * Array of React nodes, one per day of the month.\n * annotations[0] maps to Day 1, annotations[1] maps to Day 2, etc.\n * Use null or undefined for days with no annotation.\n */\n annotations?: (ReactNode | null | undefined)[];\n /**\n * Array of exactly 7 strings for the weekday header labels.\n * Omit to hide the header row entirely.\n */\n headers?: [string, string, string, string, string, string, string];\n /**\n * Inline styles merged onto the table element, overriding defaults via shallow spread.\n */\n style?: CSSProperties;\n /**\n * Enables the dark color theme for day numbers, headers, and annotation text.\n * The component does not set its own background — wrap it in a dark container when enabled.\n * @default false\n */\n darkMode?: boolean;\n}\n\n// ─── Theme definitions ───\n\nconst LIGHT_THEME = {\n dayColor: '#222',\n headerColor: '#555',\n annotationColor: 'inherit'\n};\n\nconst DARK_THEME = {\n dayColor: '#f0f0f0',\n headerColor: '#a0a0b8',\n annotationColor: '#d0d0e0'\n};\n\n// ─── Static style objects ───\n\nconst defaultTableStyle: CSSProperties = {\n borderCollapse: 'collapse',\n border: 'none',\n width: '100%',\n tableLayout: 'fixed',\n fontFamily: 'sans-serif'\n};\n\nconst defaultCellStyle: CSSProperties = {\n border: 'none',\n verticalAlign: 'top',\n padding: 0,\n position: 'relative',\n textAlign: 'center'\n};\n\n/**\n * MonthlyCalendar Component\n *\n * A zero-dependency monthly calendar grid rendered as a semantic HTML table.\n * Each day occupies a square cell with an optional annotation slot that accepts\n * any ReactNode (text, images, badges, icons, or entire sub-components).\n *\n * Features built-in light and dark themes, customizable headers, and\n * table-level style overrides. All styling is inline — no CSS files required.\n *\n * @component\n * @example\n * ```tsx\n * <MonthlyCalendar\n * year={2026}\n * month={2}\n * headers={['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']}\n * darkMode={false}\n * />\n * ```\n */\nconst MonthlyCalendar: React.FC<MonthlyCalendarProps> = ({\n year,\n month,\n annotations = [],\n headers,\n style = {},\n darkMode = false\n}) => {\n const theme = darkMode ? DARK_THEME : LIGHT_THEME;\n\n const weeks = useMemo(() => {\n const daysInMonth = new Date(year, month, 0).getDate();\n const startDay = new Date(year, month - 1, 1).getDay(); // 0=Sun\n const totalCells = Math.ceil((startDay + daysInMonth) / 7) * 7;\n const result: (number | null)[][] = [];\n let currentDay = 1 - startDay;\n\n for (let w = 0; w < totalCells / 7; w++) {\n const week: (number | null)[] = [];\n for (let d = 0; d < 7; d++) {\n week.push(currentDay >= 1 && currentDay <= daysInMonth ? currentDay : null);\n currentDay++;\n }\n result.push(week);\n }\n return result;\n }, [year, month]);\n\n const mergedTableStyle = { ...defaultTableStyle, ...style };\n\n return (\n <table style={mergedTableStyle}>\n {headers && (\n <thead>\n <tr>\n {headers.map((h, i) => (\n <th\n key={i}\n style={{\n ...defaultCellStyle,\n fontWeight: 600,\n fontSize: '0.85rem',\n paddingBottom: 6,\n color: theme.headerColor\n }}\n >\n {h}\n </th>\n ))}\n </tr>\n </thead>\n )}\n <tbody>\n {weeks.map((week, wi) => (\n <tr key={wi}>\n {week.map((day, di) => (\n <td key={di} style={defaultCellStyle}>\n <div\n style={{\n width: '100%',\n paddingBottom: '100%',\n position: 'relative'\n }}\n >\n <div\n style={{\n position: 'absolute',\n inset: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'flex-start',\n paddingTop: 6,\n gap: 4,\n overflow: 'hidden'\n }}\n >\n {day !== null && (\n <>\n <span\n style={{\n fontFamily: 'sans-serif',\n fontSize: '0.95rem',\n fontWeight: 500,\n color: theme.dayColor\n }}\n >\n {day}\n </span>\n {annotations[day - 1] != null && (\n <div\n style={{\n fontSize: '0.75rem',\n lineHeight: 1.2,\n overflow: 'hidden',\n width: '100%',\n textAlign: 'center',\n color: theme.annotationColor\n }}\n >\n {annotations[day - 1]}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n );\n};\n\nexport default MonthlyCalendar;\n"],"names":["LIGHT_THEME","DARK_THEME","defaultTableStyle","defaultCellStyle","MonthlyCalendar","year","month","annotations","headers","style","darkMode","theme","weeks","useMemo","daysInMonth","startDay","totalCells","result","currentDay","w","week","d","mergedTableStyle","jsxs","jsx","h","i","wi","day","di","Fragment"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MarkdownRender-BOGosy9w.cjs"),r=require("./ThemeSwitch-C7k1_MA4.cjs");exports.MarkdownRender=e.MarkdownRender;exports.ThemeSwitch=r.ThemeSwitch;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MarkdownRender-BOGosy9w.cjs"),r=require("./MonthlyCalendar-D-tD_2xK.cjs"),n=require("./ThemeSwitch-C7k1_MA4.cjs");exports.MarkdownRender=e.MarkdownRender;exports.MonthlyCalendar=r.MonthlyCalendar;exports.ThemeSwitch=n.ThemeSwitch;
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { M as o } from "./MarkdownRender-BmrS3q0l.js";
2
- import { T as m } from "./ThemeSwitch-DbaEio36.js";
2
+ import { M as t } from "./MonthlyCalendar-D9jC2b2L.js";
3
+ import { T as n } from "./ThemeSwitch-DbaEio36.js";
3
4
  export {
4
5
  o as MarkdownRender,
5
- m as ThemeSwitch
6
+ t as MonthlyCalendar,
7
+ n as ThemeSwitch
6
8
  };
7
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./MonthlyCalendar-D-tD_2xK.cjs");exports.MonthlyCalendar=e.MonthlyCalendar;
2
+ //# sourceMappingURL=monthly-calendar.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monthly-calendar.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { M as r } from "./MonthlyCalendar-D9jC2b2L.js";
2
+ export {
3
+ r as MonthlyCalendar
4
+ };
5
+ //# sourceMappingURL=monthly-calendar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monthly-calendar.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,54 @@
1
+ import { default as React, CSSProperties, ReactNode } from 'react';
2
+ /**
3
+ * Props for the MonthlyCalendar component
4
+ */
5
+ export interface MonthlyCalendarProps {
6
+ /** Full four-digit year (e.g. 2026) */
7
+ year: number;
8
+ /** Month to display, 1-based: 1 = January, 12 = December */
9
+ month: number;
10
+ /**
11
+ * Array of React nodes, one per day of the month.
12
+ * annotations[0] maps to Day 1, annotations[1] maps to Day 2, etc.
13
+ * Use null or undefined for days with no annotation.
14
+ */
15
+ annotations?: (ReactNode | null | undefined)[];
16
+ /**
17
+ * Array of exactly 7 strings for the weekday header labels.
18
+ * Omit to hide the header row entirely.
19
+ */
20
+ headers?: [string, string, string, string, string, string, string];
21
+ /**
22
+ * Inline styles merged onto the table element, overriding defaults via shallow spread.
23
+ */
24
+ style?: CSSProperties;
25
+ /**
26
+ * Enables the dark color theme for day numbers, headers, and annotation text.
27
+ * The component does not set its own background — wrap it in a dark container when enabled.
28
+ * @default false
29
+ */
30
+ darkMode?: boolean;
31
+ }
32
+ /**
33
+ * MonthlyCalendar Component
34
+ *
35
+ * A zero-dependency monthly calendar grid rendered as a semantic HTML table.
36
+ * Each day occupies a square cell with an optional annotation slot that accepts
37
+ * any ReactNode (text, images, badges, icons, or entire sub-components).
38
+ *
39
+ * Features built-in light and dark themes, customizable headers, and
40
+ * table-level style overrides. All styling is inline — no CSS files required.
41
+ *
42
+ * @component
43
+ * @example
44
+ * ```tsx
45
+ * <MonthlyCalendar
46
+ * year={2026}
47
+ * month={2}
48
+ * headers={['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']}
49
+ * darkMode={false}
50
+ * />
51
+ * ```
52
+ */
53
+ declare const MonthlyCalendar: React.FC<MonthlyCalendarProps>;
54
+ export default MonthlyCalendar;
@@ -0,0 +1,2 @@
1
+ export type { MonthlyCalendarProps } from './MonthlyCalendar';
2
+ export { default as MonthlyCalendar } from './MonthlyCalendar';
@@ -1,2 +1,3 @@
1
1
  export * from './components/MarkdownRender';
2
+ export * from './components/MonthlyCalendar';
2
3
  export * from './components/ThemeSwitch';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@macolmenerori/component-library",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "keywords": [],
@@ -47,6 +47,16 @@
47
47
  "types": "./dist/types/components/MarkdownRender/index.d.ts",
48
48
  "default": "./dist/markdown-render.cjs"
49
49
  }
50
+ },
51
+ "./monthly-calendar": {
52
+ "import": {
53
+ "types": "./dist/types/components/MonthlyCalendar/index.d.ts",
54
+ "default": "./dist/monthly-calendar.js"
55
+ },
56
+ "require": {
57
+ "types": "./dist/types/components/MonthlyCalendar/index.d.ts",
58
+ "default": "./dist/monthly-calendar.cjs"
59
+ }
50
60
  }
51
61
  },
52
62
  "sideEffects": [
@@ -115,6 +125,7 @@
115
125
  "types": "tsc --noEmit",
116
126
  "verify": "pnpm lint && pnpm prettify && pnpm types && pnpm test && pnpm audit --prod && pnpm build",
117
127
  "publish:npm": "pnpm publish --registry https://registry.npmjs.org/ --access public",
118
- "publish:github": "pnpm publish --registry https://npm.pkg.github.com"
128
+ "publish:github": "pnpm publish --registry https://npm.pkg.github.com",
129
+ "release": "npx tsx scripts/release.ts"
119
130
  }
120
131
  }