grok-digest 0.1.0 → 0.2.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,529 @@
1
+ @theme inline {
2
+ @keyframes accordion-down {
3
+ from {
4
+ height: 0;
5
+ }
6
+ to {
7
+ height: var(--radix-accordion-content-height, var(--accordion-panel-height, auto));
8
+ }
9
+ }
10
+
11
+ @keyframes accordion-up {
12
+ from {
13
+ height: var(--radix-accordion-content-height, var(--accordion-panel-height, auto));
14
+ }
15
+ to {
16
+ height: 0;
17
+ }
18
+ }
19
+ }
20
+
21
+ @custom-variant data-open {
22
+ &:where([data-state="open"]),
23
+ &:where([data-open]:not([data-open="false"])) {
24
+ @slot;
25
+ }
26
+ }
27
+
28
+ @custom-variant data-closed {
29
+ &:where([data-state="closed"]),
30
+ &:where([data-closed]:not([data-closed="false"])) {
31
+ @slot;
32
+ }
33
+ }
34
+
35
+ @custom-variant data-checked {
36
+ &:where([data-state="checked"]),
37
+ &:where([data-checked]:not([data-checked="false"])) {
38
+ @slot;
39
+ }
40
+ }
41
+
42
+ @custom-variant data-unchecked {
43
+ &:where([data-state="unchecked"]),
44
+ &:where([data-unchecked]:not([data-unchecked="false"])) {
45
+ @slot;
46
+ }
47
+ }
48
+
49
+ @custom-variant data-selected {
50
+ &:where([data-selected="true"]) {
51
+ @slot;
52
+ }
53
+ }
54
+
55
+ @custom-variant data-disabled {
56
+ &:where([data-disabled="true"]),
57
+ &:where([data-disabled]:not([data-disabled="false"])) {
58
+ @slot;
59
+ }
60
+ }
61
+
62
+ @custom-variant data-active {
63
+ &:where([data-state="active"]),
64
+ &:where([data-active]:not([data-active="false"])) {
65
+ @slot;
66
+ }
67
+ }
68
+
69
+ @custom-variant data-horizontal {
70
+ &:where([data-orientation="horizontal"]) {
71
+ @slot;
72
+ }
73
+ }
74
+
75
+ @custom-variant data-vertical {
76
+ &:where([data-orientation="vertical"]) {
77
+ @slot;
78
+ }
79
+ }
80
+
81
+ @utility no-scrollbar {
82
+ -ms-overflow-style: none;
83
+ scrollbar-width: none;
84
+
85
+ &::-webkit-scrollbar {
86
+ display: none;
87
+ }
88
+ }
89
+
90
+ @property --scroll-fade-t {
91
+ syntax: "<length-percentage>";
92
+ inherits: false;
93
+ initial-value: 0px;
94
+ }
95
+ @property --scroll-fade-b {
96
+ syntax: "<length-percentage>";
97
+ inherits: false;
98
+ initial-value: 0px;
99
+ }
100
+ @property --scroll-fade-s {
101
+ syntax: "<length-percentage>";
102
+ inherits: false;
103
+ initial-value: 0px;
104
+ }
105
+ @property --scroll-fade-e {
106
+ syntax: "<length-percentage>";
107
+ inherits: false;
108
+ initial-value: 0px;
109
+ }
110
+ @property --scroll-fade-mask {
111
+ syntax: "*";
112
+ inherits: false;
113
+ }
114
+
115
+ @theme inline {
116
+ @keyframes scroll-fade-reveal-t {
117
+ from {
118
+ --scroll-fade-t: 0px;
119
+ }
120
+ to {
121
+ --scroll-fade-t: var(--_scroll-fade-size-t, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
122
+ }
123
+ }
124
+ @keyframes scroll-fade-reveal-b {
125
+ from {
126
+ --scroll-fade-b: var(--_scroll-fade-size-b, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
127
+ }
128
+ to {
129
+ --scroll-fade-b: 0px;
130
+ }
131
+ }
132
+ @keyframes scroll-fade-reveal-s {
133
+ from {
134
+ --scroll-fade-s: 0px;
135
+ }
136
+ to {
137
+ --scroll-fade-s: var(--_scroll-fade-size-s, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
138
+ }
139
+ }
140
+ @keyframes scroll-fade-reveal-e {
141
+ from {
142
+ --scroll-fade-e: var(--_scroll-fade-size-e, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
143
+ }
144
+ to {
145
+ --scroll-fade-e: 0px;
146
+ }
147
+ }
148
+ }
149
+
150
+ @utility scroll-fade {
151
+ --_scroll-fade-size-t: var(--scroll-fade-t-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
152
+ --_scroll-fade-size-b: var(--scroll-fade-b-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
153
+ --scroll-fade-block: linear-gradient(
154
+ to bottom,
155
+ transparent 0,
156
+ #000 var(--scroll-fade-t, 0px),
157
+ #000 calc(100% - var(--scroll-fade-b, 0px)),
158
+ transparent 100%
159
+ );
160
+ -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
161
+ mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
162
+ -webkit-mask-composite: source-in;
163
+ mask-composite: intersect;
164
+ -webkit-mask-repeat: no-repeat;
165
+ mask-repeat: no-repeat;
166
+
167
+ @supports (animation-timeline: scroll()) {
168
+ animation:
169
+ scroll-fade-reveal-t 1ms ease-in-out,
170
+ scroll-fade-reveal-b 1ms ease-in-out;
171
+ animation-timeline: scroll(self y), scroll(self y);
172
+ animation-range:
173
+ 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
174
+ calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
175
+ animation-fill-mode: both;
176
+ }
177
+
178
+ @supports not (animation-timeline: scroll()) {
179
+ --scroll-fade-t: var(--_scroll-fade-size-t);
180
+ --scroll-fade-b: var(--_scroll-fade-size-b);
181
+ }
182
+ }
183
+
184
+ @utility scroll-fade-y {
185
+ --_scroll-fade-size-t: var(--scroll-fade-t-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
186
+ --_scroll-fade-size-b: var(--scroll-fade-b-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
187
+ --scroll-fade-block: linear-gradient(
188
+ to bottom,
189
+ transparent 0,
190
+ #000 var(--scroll-fade-t, 0px),
191
+ #000 calc(100% - var(--scroll-fade-b, 0px)),
192
+ transparent 100%
193
+ );
194
+ -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
195
+ mask-image: var(--scroll-fade-mask, var(--scroll-fade-block));
196
+ -webkit-mask-composite: source-in;
197
+ mask-composite: intersect;
198
+ -webkit-mask-repeat: no-repeat;
199
+ mask-repeat: no-repeat;
200
+
201
+ @supports (animation-timeline: scroll()) {
202
+ animation:
203
+ scroll-fade-reveal-t 1ms ease-in-out,
204
+ scroll-fade-reveal-b 1ms ease-in-out;
205
+ animation-timeline: scroll(self y), scroll(self y);
206
+ animation-range:
207
+ 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
208
+ calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
209
+ animation-fill-mode: both;
210
+ }
211
+
212
+ @supports not (animation-timeline: scroll()) {
213
+ --scroll-fade-t: var(--_scroll-fade-size-t);
214
+ --scroll-fade-b: var(--_scroll-fade-size-b);
215
+ }
216
+ }
217
+
218
+ @utility scroll-fade-x {
219
+ --_scroll-fade-size-s: var(--scroll-fade-s-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
220
+ --_scroll-fade-size-e: var(--scroll-fade-e-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
221
+ --scroll-fade-inline: linear-gradient(
222
+ to right,
223
+ transparent 0,
224
+ #000 var(--scroll-fade-s, 0px),
225
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
226
+ transparent 100%
227
+ );
228
+ &:where([dir="rtl"], [dir="rtl"] *) {
229
+ --scroll-fade-inline: linear-gradient(
230
+ to left,
231
+ transparent 0,
232
+ #000 var(--scroll-fade-s, 0px),
233
+ #000 calc(100% - var(--scroll-fade-e, 0px)),
234
+ transparent 100%
235
+ );
236
+ }
237
+ -webkit-mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
238
+ mask-image: var(--scroll-fade-mask, var(--scroll-fade-inline));
239
+ -webkit-mask-composite: source-in;
240
+ mask-composite: intersect;
241
+ -webkit-mask-repeat: no-repeat;
242
+ mask-repeat: no-repeat;
243
+
244
+ @supports (animation-timeline: scroll()) {
245
+ animation:
246
+ scroll-fade-reveal-s 1ms ease-in-out,
247
+ scroll-fade-reveal-e 1ms ease-in-out;
248
+ animation-timeline: scroll(self inline), scroll(self inline);
249
+ animation-range:
250
+ 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24)),
251
+ calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
252
+ animation-fill-mode: both;
253
+ }
254
+
255
+ @supports not (animation-timeline: scroll()) {
256
+ --scroll-fade-s: var(--_scroll-fade-size-s);
257
+ --scroll-fade-e: var(--_scroll-fade-size-e);
258
+ }
259
+ }
260
+
261
+ @utility scroll-fade-t {
262
+ --_scroll-fade-size-t: var(--scroll-fade-t-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
263
+ --scroll-fade-mask: linear-gradient(to bottom, transparent 0, #000 var(--scroll-fade-t, 0px), #000 100%);
264
+ -webkit-mask-image: var(--scroll-fade-mask);
265
+ mask-image: var(--scroll-fade-mask);
266
+ -webkit-mask-composite: source-in;
267
+ mask-composite: intersect;
268
+ -webkit-mask-repeat: no-repeat;
269
+ mask-repeat: no-repeat;
270
+
271
+ @supports (animation-timeline: scroll()) {
272
+ animation: scroll-fade-reveal-t 1ms ease-in-out;
273
+ animation-timeline: scroll(self y);
274
+ animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
275
+ animation-fill-mode: both;
276
+ }
277
+
278
+ @supports not (animation-timeline: scroll()) {
279
+ --scroll-fade-t: var(--_scroll-fade-size-t);
280
+ }
281
+ }
282
+
283
+ @utility scroll-fade-b {
284
+ --_scroll-fade-size-b: var(--scroll-fade-b-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
285
+ --scroll-fade-mask: linear-gradient(to bottom, #000 0, #000 calc(100% - var(--scroll-fade-b, 0px)), transparent 100%);
286
+ -webkit-mask-image: var(--scroll-fade-mask);
287
+ mask-image: var(--scroll-fade-mask);
288
+ -webkit-mask-composite: source-in;
289
+ mask-composite: intersect;
290
+ -webkit-mask-repeat: no-repeat;
291
+ mask-repeat: no-repeat;
292
+
293
+ @supports (animation-timeline: scroll()) {
294
+ animation: scroll-fade-reveal-b 1ms ease-in-out;
295
+ animation-timeline: scroll(self y);
296
+ animation-range: calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
297
+ animation-fill-mode: both;
298
+ }
299
+
300
+ @supports not (animation-timeline: scroll()) {
301
+ --scroll-fade-b: var(--_scroll-fade-size-b);
302
+ }
303
+ }
304
+
305
+ @utility scroll-fade-l {
306
+ --_scroll-fade-size-s: var(--scroll-fade-s-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
307
+ --scroll-fade-mask: linear-gradient(to right, transparent 0, #000 var(--scroll-fade-s, 0px), #000 100%);
308
+ -webkit-mask-image: var(--scroll-fade-mask);
309
+ mask-image: var(--scroll-fade-mask);
310
+ -webkit-mask-composite: source-in;
311
+ mask-composite: intersect;
312
+ -webkit-mask-repeat: no-repeat;
313
+ mask-repeat: no-repeat;
314
+
315
+ @supports (animation-timeline: scroll()) {
316
+ animation: scroll-fade-reveal-s 1ms ease-in-out;
317
+ animation-timeline: scroll(self x);
318
+ animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
319
+ animation-fill-mode: both;
320
+ }
321
+
322
+ @supports not (animation-timeline: scroll()) {
323
+ --scroll-fade-s: var(--_scroll-fade-size-s);
324
+ }
325
+ }
326
+
327
+ @utility scroll-fade-r {
328
+ --_scroll-fade-size-e: var(--scroll-fade-e-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
329
+ --scroll-fade-mask: linear-gradient(to right, #000 0, #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100%);
330
+ -webkit-mask-image: var(--scroll-fade-mask);
331
+ mask-image: var(--scroll-fade-mask);
332
+ -webkit-mask-composite: source-in;
333
+ mask-composite: intersect;
334
+ -webkit-mask-repeat: no-repeat;
335
+ mask-repeat: no-repeat;
336
+
337
+ @supports (animation-timeline: scroll()) {
338
+ animation: scroll-fade-reveal-e 1ms ease-in-out;
339
+ animation-timeline: scroll(self x);
340
+ animation-range: calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
341
+ animation-fill-mode: both;
342
+ }
343
+
344
+ @supports not (animation-timeline: scroll()) {
345
+ --scroll-fade-e: var(--_scroll-fade-size-e);
346
+ }
347
+ }
348
+
349
+ @utility scroll-fade-s {
350
+ --_scroll-fade-size-s: var(--scroll-fade-s-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
351
+ --scroll-fade-mask: linear-gradient(to right, transparent 0, #000 var(--scroll-fade-s, 0px), #000 100%);
352
+ &:where([dir="rtl"], [dir="rtl"] *) {
353
+ --scroll-fade-mask: linear-gradient(to left, transparent 0, #000 var(--scroll-fade-s, 0px), #000 100%);
354
+ }
355
+ -webkit-mask-image: var(--scroll-fade-mask);
356
+ mask-image: var(--scroll-fade-mask);
357
+ -webkit-mask-composite: source-in;
358
+ mask-composite: intersect;
359
+ -webkit-mask-repeat: no-repeat;
360
+ mask-repeat: no-repeat;
361
+
362
+ @supports (animation-timeline: scroll()) {
363
+ animation: scroll-fade-reveal-s 1ms ease-in-out;
364
+ animation-timeline: scroll(self inline);
365
+ animation-range: 0 var(--scroll-fade-reveal, calc(var(--spacing) * 24));
366
+ animation-fill-mode: both;
367
+ }
368
+
369
+ @supports not (animation-timeline: scroll()) {
370
+ --scroll-fade-s: var(--_scroll-fade-size-s);
371
+ }
372
+ }
373
+
374
+ @utility scroll-fade-e {
375
+ --_scroll-fade-size-e: var(--scroll-fade-e-size, var(--scroll-fade-size, min(12%, calc(var(--spacing) * 10))));
376
+ --scroll-fade-mask: linear-gradient(to right, #000 0, #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100%);
377
+ &:where([dir="rtl"], [dir="rtl"] *) {
378
+ --scroll-fade-mask: linear-gradient(to left, #000 0, #000 calc(100% - var(--scroll-fade-e, 0px)), transparent 100%);
379
+ }
380
+ -webkit-mask-image: var(--scroll-fade-mask);
381
+ mask-image: var(--scroll-fade-mask);
382
+ -webkit-mask-composite: source-in;
383
+ mask-composite: intersect;
384
+ -webkit-mask-repeat: no-repeat;
385
+ mask-repeat: no-repeat;
386
+
387
+ @supports (animation-timeline: scroll()) {
388
+ animation: scroll-fade-reveal-e 1ms ease-in-out;
389
+ animation-timeline: scroll(self inline);
390
+ animation-range: calc(100% - var(--scroll-fade-reveal, calc(var(--spacing) * 24))) 100%;
391
+ animation-fill-mode: both;
392
+ }
393
+
394
+ @supports not (animation-timeline: scroll()) {
395
+ --scroll-fade-e: var(--_scroll-fade-size-e);
396
+ }
397
+ }
398
+
399
+ @utility scroll-fade-* {
400
+ --scroll-fade-size: calc(var(--spacing) * --value(integer));
401
+ --scroll-fade-size: --value([length], [percentage]);
402
+ }
403
+
404
+ @utility scroll-fade-t-* {
405
+ --scroll-fade-t-size: calc(var(--spacing) * --value(integer));
406
+ --scroll-fade-t-size: --value([length], [percentage]);
407
+ }
408
+
409
+ @utility scroll-fade-b-* {
410
+ --scroll-fade-b-size: calc(var(--spacing) * --value(integer));
411
+ --scroll-fade-b-size: --value([length], [percentage]);
412
+ }
413
+
414
+ @utility scroll-fade-s-* {
415
+ --scroll-fade-s-size: calc(var(--spacing) * --value(integer));
416
+ --scroll-fade-s-size: --value([length], [percentage]);
417
+ }
418
+
419
+ @utility scroll-fade-e-* {
420
+ --scroll-fade-e-size: calc(var(--spacing) * --value(integer));
421
+ --scroll-fade-e-size: --value([length], [percentage]);
422
+ }
423
+
424
+ @utility scroll-fade-none {
425
+ --scroll-fade-mask: none;
426
+ }
427
+
428
+ @property --shimmer-angle {
429
+ syntax: "<angle>";
430
+ inherits: true;
431
+ initial-value: 20deg;
432
+ }
433
+ @property --shimmer-image {
434
+ syntax: "*";
435
+ inherits: false;
436
+ }
437
+ @property --shimmer-text-fill {
438
+ syntax: "*";
439
+ inherits: false;
440
+ }
441
+
442
+ @theme inline {
443
+ @keyframes tw-shimmer {
444
+ from {
445
+ background-position: 100% 0;
446
+ }
447
+ to {
448
+ background-position: 0 0;
449
+ }
450
+ }
451
+ }
452
+
453
+ @utility shimmer {
454
+ --_spread: var(--shimmer-spread, calc(3ch + 40px));
455
+ --_base: currentColor;
456
+ --_highlight: var(--shimmer-color, oklch(from currentColor l c h / calc(alpha* 0.2)));
457
+
458
+ background-image: var(
459
+ --shimmer-image,
460
+ linear-gradient(
461
+ calc(90deg + var(--shimmer-angle)),
462
+ var(--_base) calc(50% - var(--_spread)),
463
+ color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% - var(--_spread) * 0.5),
464
+ var(--_highlight) 50%,
465
+ color-mix(in oklch, var(--_highlight), var(--_base) 50%) calc(50% + var(--_spread) * 0.5),
466
+ var(--_base) calc(50% + var(--_spread))
467
+ )
468
+ );
469
+ background-repeat: no-repeat;
470
+ background-size: calc(200% + var(--_spread) * 2) 100%;
471
+ background-position: 0 0;
472
+ background-clip: text;
473
+ -webkit-background-clip: text;
474
+ -webkit-text-fill-color: var(--shimmer-text-fill, transparent);
475
+ animation: tw-shimmer var(--shimmer-duration, 2s) linear infinite;
476
+
477
+ @variant dark {
478
+ --_highlight: var(--shimmer-color, oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4)));
479
+ }
480
+
481
+ &:where([dir="rtl"], [dir="rtl"] *) {
482
+ animation-direction: reverse;
483
+ }
484
+
485
+ @media (prefers-reduced-motion: reduce) {
486
+ animation: none;
487
+ background-image: none;
488
+ -webkit-text-fill-color: currentColor;
489
+ }
490
+ }
491
+
492
+ @utility shimmer-once {
493
+ animation-iteration-count: 1;
494
+ }
495
+
496
+ @utility shimmer-reverse {
497
+ animation-direction: reverse;
498
+ }
499
+
500
+ @utility shimmer-none {
501
+ --shimmer-image: none;
502
+ --shimmer-text-fill: currentColor;
503
+ }
504
+
505
+ @utility shimmer-color-* {
506
+ --shimmer-color: --value(--color, [color]);
507
+ --shimmer-color: color-mix(in oklch, --value(--color, [color]) calc(--modifier(integer) * 1%), transparent);
508
+ }
509
+
510
+ @utility shimmer-duration-* {
511
+ --shimmer-duration: calc(--value(integer) * 1ms);
512
+ }
513
+
514
+ @utility shimmer-spread-* {
515
+ --shimmer-spread: calc(var(--spacing) * --value(integer));
516
+ --shimmer-spread: --value([length], [percentage]);
517
+ }
518
+
519
+ @utility shimmer-angle-* {
520
+ --shimmer-angle: calc(--value(integer) * 1deg);
521
+ }
522
+
523
+ @media (prefers-reduced-motion: reduce) {
524
+ .shimmer {
525
+ animation: none;
526
+ background-image: none;
527
+ -webkit-text-fill-color: currentColor;
528
+ }
529
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grok-digest",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Astro integration that renders a Grok Digest site: X bookmarks summarized by Grok, searchable, sorted by topic, with RSS feeds.",
5
5
  "keywords": [
6
6
  "astro",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "files": [
22
22
  "dist",
23
- "CHANGELOG.md"
23
+ "LICENSE-THIRD-PARTY"
24
24
  ],
25
25
  "type": "module",
26
26
  "exports": {
@@ -48,7 +48,7 @@
48
48
  "lint": "oxlint",
49
49
  "lint:fix": "oxlint --fix",
50
50
  "lint:comments": "node scripts/lint-comments.mjs",
51
- "lint:dup": "jscpd --threshold 0 --exit-code 1 --no-tips --reporters ai --ignore '**/bun.lock,**/data/*.json,**/test/fixtures/**,**/dist/**,**/.github/workflows/**' .",
51
+ "lint:dup": "jscpd --threshold 0 --exit-code 1 --no-tips --reporters ai --ignore '**/bun.lock,**/src/styles/shadcn-tailwind.css,**/data/*.json,**/test/fixtures/**,**/dist/**,**/.github/workflows/**' .",
52
52
  "knip": "knip",
53
53
  "format": "oxfmt",
54
54
  "format:check": "oxfmt --check",
@@ -67,7 +67,6 @@
67
67
  "radix-ui": "^1.8.1",
68
68
  "react": "^19.3.0",
69
69
  "react-dom": "^19.3.0",
70
- "shadcn": "^4.21.5",
71
70
  "tailwindcss": "^4.3.3",
72
71
  "tw-animate-css": "^1.4.0",
73
72
  "zod": "^4.6.7"
package/CHANGELOG.md DELETED
@@ -1,10 +0,0 @@
1
- # Changelog
2
-
3
- ## 0.1.0
4
-
5
- First release of the `grok-digest` package.
6
-
7
- - Astro integration that serves the bookmarks page, topic feeds, favicon, and `robots.txt`.
8
- - Schema version 1, the `bookmarks.json` array existing sites already use. `SCHEMA_VERSION` is exported from `grok-digest/schema`.
9
- - `grok-digest validate` checks `bookmarks.json` and, when present, `processed.json` and `removed.json`.
10
- - `grok-digest build`, `dev`, and `preview` run the site with the Astro version the package depends on, so a site needs no Astro config. `SITE_URL` and `BASE_PATH` set Astro's `site` and `base`.
@@ -1,32 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { SearchIcon } from "lucide-react";
3
- import { useEffect, useMemo, useState } from "react";
4
- import { Button } from "./ui/button.js";
5
- import { Input } from "./ui/input.js";
6
- import { filterSearch, parseFilter } from "../lib/filter.js";
7
- import { matchingIds } from "../lib/search.js";
8
- import { TOPIC_LABELS, TOPICS } from "../lib/topics.js";
9
- export function BookmarkFilters({ entries }) {
10
- const initial = parseFilter(window.location.search);
11
- const [query, setQuery] = useState(initial.query);
12
- const [topic, setTopic] = useState(initial.topic);
13
- const visible = useMemo(() => matchingIds({ entries, query, topic }), [entries, query, topic]);
14
- const topicsInUse = useMemo(() => TOPICS.filter((t) => entries.some((entry) => entry.topic === t)), [entries]);
15
- useEffect(() => {
16
- for (const card of document.querySelectorAll("[data-bookmark-id]")) {
17
- card.hidden = !visible.has(card.dataset["bookmarkId"] ?? "");
18
- }
19
- }, [visible]);
20
- useEffect(() => {
21
- const next = `${window.location.pathname}${filterSearch({ query, topic })}${window.location.hash}`;
22
- const current = `${window.location.pathname}${window.location.search}${window.location.hash}`;
23
- if (current !== next)
24
- window.history.replaceState(null, "", next);
25
- }, [query, topic]);
26
- return (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "relative", children: [_jsx(SearchIcon, { className: "pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { type: "search", value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search authors, posts, summaries, key points", "aria-label": "Search bookmarks", className: "h-10 rounded-full bg-card pl-9 dark:bg-card" })] }), _jsxs("fieldset", { "aria-label": "Filter by topic", className: "flex min-w-0 flex-wrap gap-2", children: [_jsx(TopicChip, { label: "All", pressed: topic === null, onClick: () => setTopic(null) }), topicsInUse.map((t) => (_jsx(TopicChip, { label: TOPIC_LABELS[t], pressed: topic === t, onClick: () => setTopic(topic === t ? null : t) }, t)))] }), _jsxs("p", { "aria-live": "polite", className: "text-sm text-muted-foreground", children: [visible.size === entries.length
27
- ? `${entries.length} ${entries.length === 1 ? "bookmark" : "bookmarks"}`
28
- : `Showing ${visible.size} of ${entries.length}`, visible.size === 0 && entries.length > 0 ? ". No bookmarks match your search." : ""] })] }));
29
- }
30
- function TopicChip({ label, pressed, onClick }) {
31
- return (_jsx(Button, { type: "button", size: "sm", variant: pressed ? "default" : "outline", "aria-pressed": pressed, onClick: onClick, className: "rounded-full px-3", children: label }));
32
- }