contrib-graphs 0.0.0-stage → 0.1.0

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.
@@ -0,0 +1,291 @@
1
+ /* ============================================================
2
+ Contribution Graph — estilos base
3
+ Los colores llegan como --cg-*-light / --cg-*-dark desde el tema;
4
+ aquí se elige cuál aplicar según data-mode y el esquema de color.
5
+ ============================================================ */
6
+
7
+ .cg-root {
8
+ --cg-l0: var(--cg-l0-light);
9
+ --cg-l1: var(--cg-l1-light);
10
+ --cg-l2: var(--cg-l2-light);
11
+ --cg-l3: var(--cg-l3-light);
12
+ --cg-l4: var(--cg-l4-light);
13
+ --cg-text: var(--cg-text-light);
14
+ --cg-muted: var(--cg-muted-light);
15
+ --cg-surface: var(--cg-surface-light);
16
+ --cg-border: var(--cg-border-light);
17
+ --cg-tip-bg: #24292f;
18
+ --cg-tip-text: #ffffff;
19
+ --cg-mix: black;
20
+
21
+ position: relative;
22
+ display: block;
23
+ max-width: 100%;
24
+ color: var(--cg-text);
25
+ font: 12px/1.4 ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
26
+ border-radius: 8px;
27
+ -webkit-tap-highlight-color: transparent;
28
+ }
29
+
30
+ .cg-root[data-mode='dark'],
31
+ :root[data-theme='dark'] .cg-root[data-mode='auto'] {
32
+ --cg-l0: var(--cg-l0-dark);
33
+ --cg-l1: var(--cg-l1-dark);
34
+ --cg-l2: var(--cg-l2-dark);
35
+ --cg-l3: var(--cg-l3-dark);
36
+ --cg-l4: var(--cg-l4-dark);
37
+ --cg-text: var(--cg-text-dark);
38
+ --cg-muted: var(--cg-muted-dark);
39
+ --cg-surface: var(--cg-surface-dark);
40
+ --cg-border: var(--cg-border-dark);
41
+ --cg-tip-bg: #f0f3f6;
42
+ --cg-tip-text: #0d1117;
43
+ }
44
+
45
+ @media (prefers-color-scheme: dark) {
46
+ :root:not([data-theme='light']) .cg-root[data-mode='auto'] {
47
+ --cg-l0: var(--cg-l0-dark);
48
+ --cg-l1: var(--cg-l1-dark);
49
+ --cg-l2: var(--cg-l2-dark);
50
+ --cg-l3: var(--cg-l3-dark);
51
+ --cg-l4: var(--cg-l4-dark);
52
+ --cg-text: var(--cg-text-dark);
53
+ --cg-muted: var(--cg-muted-dark);
54
+ --cg-surface: var(--cg-surface-dark);
55
+ --cg-border: var(--cg-border-dark);
56
+ --cg-tip-bg: #f0f3f6;
57
+ --cg-tip-text: #0d1117;
58
+ }
59
+ }
60
+
61
+ .cg-root:focus {
62
+ outline: none;
63
+ }
64
+ .cg-root:focus-visible {
65
+ outline: 2px solid var(--cg-l3);
66
+ outline-offset: 4px;
67
+ }
68
+
69
+ .cg-root[data-surface] {
70
+ background: var(--cg-surface);
71
+ border: 1px solid var(--cg-border);
72
+ padding: 14px 16px;
73
+ }
74
+
75
+ .cg-header {
76
+ display: flex;
77
+ justify-content: space-between;
78
+ align-items: baseline;
79
+ gap: 12px;
80
+ margin-bottom: 8px;
81
+ font-size: 13px;
82
+ }
83
+ .cg-title strong {
84
+ font-weight: 600;
85
+ }
86
+ .cg-footer {
87
+ display: flex;
88
+ justify-content: space-between;
89
+ align-items: center;
90
+ gap: 12px;
91
+ margin-top: 8px;
92
+ color: var(--cg-muted);
93
+ font-size: 11px;
94
+ }
95
+ .cg-legend {
96
+ display: inline-flex;
97
+ align-items: center;
98
+ gap: 3px;
99
+ }
100
+ .cg-legend > span:first-child {
101
+ margin-right: 3px;
102
+ }
103
+ .cg-legend > span:last-child {
104
+ margin-left: 3px;
105
+ }
106
+ .cg-swatch {
107
+ display: inline-block;
108
+ width: 10px;
109
+ height: 10px;
110
+ border-radius: 2px;
111
+ outline: 1px solid color-mix(in srgb, var(--cg-text) 6%, transparent);
112
+ outline-offset: -1px;
113
+ }
114
+
115
+ .cg-body svg {
116
+ display: block;
117
+ max-width: 100%;
118
+ height: auto;
119
+ overflow: visible;
120
+ }
121
+ .cg-label {
122
+ fill: var(--cg-muted);
123
+ font-size: 9px;
124
+ }
125
+
126
+ /* ---------- Celdas ---------- */
127
+ .cg-cell {
128
+ cursor: pointer;
129
+ transition: opacity 0.15s ease, filter 0.15s ease;
130
+ }
131
+ .cg-cell[data-active] {
132
+ stroke: var(--cg-text);
133
+ stroke-width: 1.25px;
134
+ paint-order: stroke;
135
+ }
136
+ .cg-root[data-has-active] .cg-cell:not([data-active]) {
137
+ opacity: 0.6;
138
+ }
139
+ .cg-root[data-glow] .cg-glow {
140
+ filter: var(--cg-glow-filter);
141
+ }
142
+
143
+ /* ---------- Tooltip ---------- */
144
+ .cg-tooltip {
145
+ position: absolute;
146
+ z-index: 10;
147
+ transform: translate(-50%, calc(-100% - 8px));
148
+ padding: 5px 9px;
149
+ border-radius: 6px;
150
+ background: var(--cg-tip-bg);
151
+ color: var(--cg-tip-text);
152
+ font-size: 12px;
153
+ white-space: nowrap;
154
+ pointer-events: none;
155
+ box-shadow: 0 4px 14px rgb(0 0 0 / 0.18);
156
+ }
157
+ .cg-tooltip strong {
158
+ font-weight: 600;
159
+ }
160
+ .cg-tooltip span {
161
+ opacity: 0.75;
162
+ }
163
+ .cg-tooltip::after {
164
+ content: '';
165
+ position: absolute;
166
+ left: calc(50% + var(--cg-arrow, 0px));
167
+ top: 100%;
168
+ border: 5px solid transparent;
169
+ border-top-color: var(--cg-tip-bg);
170
+ transform: translateX(-50%);
171
+ }
172
+
173
+ .cg-sr-only {
174
+ position: absolute;
175
+ width: 1px;
176
+ height: 1px;
177
+ overflow: hidden;
178
+ clip: rect(0 0 0 0);
179
+ white-space: nowrap;
180
+ }
181
+
182
+ /* ---------- Animación de entrada ---------- */
183
+ .cg-root[data-animate] .cg-cell {
184
+ animation: cg-pop 0.5s cubic-bezier(0.2, 0.8, 0.3, 1.25) both;
185
+ animation-delay: calc(var(--cg-w, 0) * 12ms);
186
+ transform-box: fill-box;
187
+ transform-origin: center;
188
+ }
189
+ .cg-root[data-animate] .cg-rise {
190
+ animation-name: cg-rise;
191
+ transform-origin: bottom;
192
+ }
193
+ @keyframes cg-pop {
194
+ from {
195
+ opacity: 0;
196
+ transform: scale(0.2);
197
+ }
198
+ }
199
+ @keyframes cg-rise {
200
+ from {
201
+ opacity: 0;
202
+ transform: scaleY(0);
203
+ }
204
+ }
205
+ @media (prefers-reduced-motion: reduce) {
206
+ .cg-root[data-animate] .cg-cell {
207
+ animation: none;
208
+ }
209
+ }
210
+
211
+ /* ---------- Terminal ---------- */
212
+ .cg-terminal .cg-term {
213
+ margin: 0;
214
+ font: 12px/1.25 ui-monospace, 'JetBrains Mono', 'SFMono-Regular', Menlo, Consolas, monospace;
215
+ color: var(--cg-muted);
216
+ white-space: pre;
217
+ overflow: hidden;
218
+ }
219
+ .cg-terminal .cg-term .cg-cell {
220
+ transition: none;
221
+ border-radius: 2px;
222
+ }
223
+ .cg-terminal .cg-term .cg-cell[data-active] {
224
+ background: color-mix(in srgb, var(--cg-text) 18%, transparent);
225
+ color: var(--cg-text) !important;
226
+ }
227
+ .cg-terminal .cg-prompt {
228
+ color: var(--cg-text);
229
+ }
230
+ /* Las líneas de texto pueden partirse; la cuadrícula no (se recorta o escala). */
231
+ .cg-terminal .cg-wrap {
232
+ white-space: pre-wrap;
233
+ }
234
+ .cg-terminal .cg-foot {
235
+ display: flex;
236
+ flex-wrap: wrap;
237
+ column-gap: 3ch;
238
+ padding-left: 5ch;
239
+ white-space: pre-wrap;
240
+ }
241
+ .cg-terminal .cg-prompt b {
242
+ color: var(--cg-l4);
243
+ font-weight: 600;
244
+ }
245
+ .cg-terminal .cg-caret {
246
+ display: inline-block;
247
+ width: 0.6em;
248
+ height: 1.1em;
249
+ vertical-align: -0.2em;
250
+ background: var(--cg-l3);
251
+ animation: cg-blink 1.1s steps(1) infinite;
252
+ }
253
+ @keyframes cg-blink {
254
+ 50% {
255
+ opacity: 0;
256
+ }
257
+ }
258
+ .cg-terminal[data-animate] .cg-term .cg-cell {
259
+ animation-name: cg-type;
260
+ animation-duration: 0.01s;
261
+ animation-timing-function: linear;
262
+ animation-delay: calc(var(--cg-w, 0) * 18ms);
263
+ }
264
+ @keyframes cg-type {
265
+ from {
266
+ opacity: 0;
267
+ }
268
+ }
269
+
270
+ /* ---------- Compact ---------- */
271
+ .cg-compact {
272
+ display: inline-block;
273
+ }
274
+ .cg-compact .cg-header {
275
+ margin-bottom: 6px;
276
+ }
277
+
278
+ /* ---------- Stats ---------- */
279
+ .cg-stats {
280
+ display: flex;
281
+ gap: 16px;
282
+ color: var(--cg-muted);
283
+ font-size: 11px;
284
+ }
285
+ .cg-stats b {
286
+ display: block;
287
+ color: var(--cg-text);
288
+ font-size: 15px;
289
+ font-weight: 600;
290
+ font-variant-numeric: tabular-nums;
291
+ }
package/package.json CHANGED
@@ -1,6 +1,72 @@
1
1
  {
2
2
  "name": "contrib-graphs",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Contribution graph components for React: GitHub-style heatmaps in seven designs, with themes, dark mode, keyboard navigation and screen reader support.",
5
+ "keywords": [
6
+ "react",
7
+ "contribution-graph",
8
+ "heatmap",
9
+ "github",
10
+ "gitlab",
11
+ "calendar",
12
+ "portfolio",
13
+ "svg"
14
+ ],
15
+ "license": "MIT",
16
+ "author": "Francis Miguel Castillo Cruz (https://github.com/ingfranciscastillo)",
17
+ "homepage": "https://ingfranciscastillo.github.io/contrib-graphs/",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/ingfranciscastillo/contrib-graphs.git",
21
+ "directory": "packages/contrib-graphs"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/ingfranciscastillo/contrib-graphs/issues"
25
+ },
26
+ "type": "module",
27
+ "sideEffects": [
28
+ "*.css"
29
+ ],
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "scripts": {
34
+ "build": "tsdown && node scripts/check-dist.mjs",
35
+ "dev": "tsdown --watch",
36
+ "typecheck": "tsc --noEmit",
37
+ "test": "vitest run",
38
+ "test:watch": "vitest",
39
+ "prepublishOnly": "npm run build && npm test"
40
+ },
41
+ "peerDependencies": {
42
+ "react": ">=18"
43
+ },
44
+ "devDependencies": {
45
+ "@testing-library/dom": "^10.4.1",
46
+ "@testing-library/react": "^16.3.3",
47
+ "@types/react": "^18.3.31",
48
+ "@types/react-dom": "^18.3.7",
49
+ "jsdom": "^26.1.0",
50
+ "react": "18.3.1",
51
+ "react-dom": "18.3.1",
52
+ "tsdown": "^0.23.0",
53
+ "typescript": "^5.9.3",
54
+ "vite": "^6.4.6",
55
+ "vitest": "^4.1.12"
56
+ },
57
+ "main": "./dist/index.cjs",
58
+ "module": "./dist/index.js",
59
+ "types": "./dist/index.d.cts",
60
+ "exports": {
61
+ ".": {
62
+ "import": "./dist/index.js",
63
+ "require": "./dist/index.cjs"
64
+ },
65
+ "./data": {
66
+ "import": "./dist/data.js",
67
+ "require": "./dist/data.cjs"
68
+ },
69
+ "./package.json": "./package.json",
70
+ "./styles.css": "./dist/styles.css"
71
+ }
72
+ }