@igstack/app-catalog-frontend-core 6.9.0 → 6.10.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.
- package/dist/esm/__tests__/modules/appCatalog/ui/detail/CommunitySection.feed.test.d.ts +0 -0
- package/dist/esm/__tests__/modules/appCatalog/ui/detail/CommunitySection.help.test.d.ts +0 -0
- package/dist/esm/__tests__/modules/appCatalog/ui/detail/CommunitySection.input.test.d.ts +0 -0
- package/dist/esm/__tests__/modules/appCatalog/ui/detail/composeComments.test.d.ts +1 -0
- package/dist/esm/__tests__/ui/detail/CommunityInput.test.d.ts +1 -0
- package/dist/esm/modules/appCatalog/hooks/useUpdateApp.d.ts +8 -0
- package/dist/esm/modules/appCatalog/ui/detail/AppDetails.js +254 -232
- package/dist/esm/modules/appCatalog/ui/detail/AppDetails.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/CommentsFeed.d.ts +17 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommentsFeed.js +187 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommentsFeed.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommentsHelp.d.ts +9 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommentsHelp.js +91 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommentsHelp.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommunityInput.d.ts +17 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommunityInput.js +328 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommunityInput.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommunitySection.d.ts +15 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommunitySection.js +26 -0
- package/dist/esm/modules/appCatalog/ui/detail/CommunitySection.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/DetailTabs.d.ts +8 -19
- package/dist/esm/modules/appCatalog/ui/detail/DetailTabs.js +49 -37
- package/dist/esm/modules/appCatalog/ui/detail/DetailTabs.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/communityDraft.d.ts +30 -0
- package/dist/esm/modules/appCatalog/ui/detail/communityDraft.js +50 -0
- package/dist/esm/modules/appCatalog/ui/detail/communityDraft.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/communityError.d.ts +6 -0
- package/dist/esm/modules/appCatalog/ui/detail/communityError.js +8 -0
- package/dist/esm/modules/appCatalog/ui/detail/communityError.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/composeComments.d.ts +27 -0
- package/dist/esm/modules/appCatalog/ui/detail/composeComments.js +66 -0
- package/dist/esm/modules/appCatalog/ui/detail/composeComments.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/usePendingCount.d.ts +11 -0
- package/dist/esm/modules/appCatalog/ui/detail/usePendingCount.js +15 -0
- package/dist/esm/modules/appCatalog/ui/detail/usePendingCount.js.map +1 -0
- package/dist/esm/modules/extensions/features/resourceDetail.d.ts +38 -0
- package/dist/esm/modules/extensions/features/resourceDetail.js +4 -0
- package/dist/esm/modules/extensions/features/resourceDetail.js.map +1 -1
- package/dist/esm/modules/extensions/index.d.ts +1 -1
- package/dist/esm/modules/extensions/index.js.map +1 -1
- package/dist/index.css +525 -49
- package/package.json +4 -4
- package/src/__tests__/modules/appCatalog/ui/catalog/AppDetailPanel.appSwitch.test.tsx +5 -2
- package/src/__tests__/modules/appCatalog/ui/catalog/AppDetailPanel.enter.test.tsx +5 -2
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.background.test.tsx +9 -10
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.behindThisCard.test.tsx +402 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.doorAndTabs.test.tsx +8 -4
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.escape.test.tsx +5 -2
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.knowMore.test.tsx +175 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.sectionOrder.test.tsx +5 -2
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.subResourceTab.test.tsx +5 -2
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.tags.test.tsx +5 -2
- package/src/__tests__/modules/appCatalog/ui/detail/CommunitySection.feed.test.tsx +281 -0
- package/src/__tests__/modules/appCatalog/ui/detail/CommunitySection.help.test.tsx +179 -0
- package/src/__tests__/modules/appCatalog/ui/detail/CommunitySection.input.test.tsx +423 -0
- package/src/__tests__/modules/appCatalog/ui/detail/composeComments.test.ts +170 -0
- package/src/__tests__/ui/detail/CommunityInput.test.tsx +39 -0
- package/src/index.css +525 -49
- package/src/modules/appCatalog/ui/detail/AppDetails.tsx +310 -295
- package/src/modules/appCatalog/ui/detail/CommentsFeed.tsx +254 -0
- package/src/modules/appCatalog/ui/detail/CommentsHelp.tsx +102 -0
- package/src/modules/appCatalog/ui/detail/CommunityInput.tsx +419 -0
- package/src/modules/appCatalog/ui/detail/CommunitySection.tsx +41 -0
- package/src/modules/appCatalog/ui/detail/DetailTabs.tsx +77 -71
- package/src/modules/appCatalog/ui/detail/communityDraft.ts +80 -0
- package/src/modules/appCatalog/ui/detail/communityError.ts +10 -0
- package/src/modules/appCatalog/ui/detail/composeComments.ts +103 -0
- package/src/modules/appCatalog/ui/detail/usePendingCount.ts +26 -0
- package/src/modules/extensions/features/resourceDetail.ts +28 -0
- package/src/modules/extensions/index.ts +2 -0
- package/dist/esm/modules/appCatalog/ui/detail/FeedbackSection.d.ts +0 -13
- package/dist/esm/modules/appCatalog/ui/detail/FeedbackSection.js +0 -433
- package/dist/esm/modules/appCatalog/ui/detail/FeedbackSection.js.map +0 -1
- package/src/__tests__/modules/appCatalog/ui/detail/FeedbackSection.emptyState.test.tsx +0 -181
- package/src/__tests__/modules/appCatalog/ui/detail/FeedbackSection.reviewStatus.test.tsx +0 -131
- package/src/modules/appCatalog/ui/detail/FeedbackSection.tsx +0 -605
- /package/dist/esm/__tests__/modules/appCatalog/ui/detail/{FeedbackSection.emptyState.test.d.ts → AppDetails.behindThisCard.test.d.ts} +0 -0
- /package/dist/esm/__tests__/modules/appCatalog/ui/detail/{FeedbackSection.reviewStatus.test.d.ts → AppDetails.knowMore.test.d.ts} +0 -0
package/dist/index.css
CHANGED
|
@@ -249,38 +249,27 @@
|
|
|
249
249
|
padding-left: 1.25rem;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
/*
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
override. Verify any change by measurement, not by eye: 60%/55% looks fine and
|
|
261
|
-
still fails. */
|
|
262
|
-
.comment-chip {
|
|
263
|
-
display: inline-flex;
|
|
264
|
-
align-items: center;
|
|
265
|
-
gap: 0.25rem;
|
|
252
|
+
/* Comment badges. Plain CSS rather than utilities: there is no success or
|
|
253
|
+
pending token in the palette, so each tints a chart colour, which already
|
|
254
|
+
shifts for dark mode. The text is mixed toward the foreground so it stays
|
|
255
|
+
readable at 10.5px in both themes: an untinted chart colour on its own pale
|
|
256
|
+
ground measured under 4.5:1. Verify any change by measurement, not by eye. */
|
|
257
|
+
.comment__badge {
|
|
258
|
+
margin-left: 0.375rem;
|
|
259
|
+
padding: 0 0.4375rem;
|
|
266
260
|
border-radius: 999px;
|
|
267
|
-
|
|
268
|
-
font-size: 0.6875rem;
|
|
261
|
+
font-size: 0.65625rem;
|
|
269
262
|
font-weight: 500;
|
|
270
|
-
line-height:
|
|
263
|
+
line-height: 1rem;
|
|
271
264
|
white-space: nowrap;
|
|
272
265
|
}
|
|
273
|
-
.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
background: color-mix(in oklab, var(--chart-3) 16%, var(--card));
|
|
277
|
-
border: 1px solid color-mix(in oklab, var(--chart-3) 35%, var(--card));
|
|
266
|
+
.comment__badge.is-pending {
|
|
267
|
+
color: color-mix(in oklab, var(--chart-1) 62%, var(--foreground));
|
|
268
|
+
background: color-mix(in oklab, var(--chart-1) 12%, var(--card));
|
|
278
269
|
}
|
|
279
|
-
.
|
|
280
|
-
color: var(--
|
|
281
|
-
background: var(--
|
|
282
|
-
border: 1px solid var(--border);
|
|
283
|
-
font-weight: 400;
|
|
270
|
+
.comment__badge.is-used {
|
|
271
|
+
color: color-mix(in oklab, var(--chart-3) 50%, var(--foreground));
|
|
272
|
+
background: color-mix(in oklab, var(--chart-3) 13%, var(--card));
|
|
284
273
|
}
|
|
285
274
|
|
|
286
275
|
/* One register for every section label inside the detail card.
|
|
@@ -431,16 +420,136 @@
|
|
|
431
420
|
|
|
432
421
|
/* The tab strip. Horizontally scrollable rather than wrapping: a wrapped strip
|
|
433
422
|
changes the band's height from one entry to the next. */
|
|
423
|
+
.detail-tabs-row {
|
|
424
|
+
display: flex;
|
|
425
|
+
border-bottom: 1px solid var(--border);
|
|
426
|
+
}
|
|
434
427
|
.detail-tabs {
|
|
435
428
|
display: flex;
|
|
429
|
+
flex: 1;
|
|
430
|
+
min-width: 0;
|
|
436
431
|
gap: 2px;
|
|
437
|
-
border-bottom: 1px solid var(--border);
|
|
438
432
|
overflow-x: auto;
|
|
439
433
|
scrollbar-width: none;
|
|
434
|
+
scroll-behavior: smooth;
|
|
440
435
|
}
|
|
441
436
|
.detail-tabs::-webkit-scrollbar {
|
|
442
437
|
display: none;
|
|
443
438
|
}
|
|
439
|
+
/* Outside the scrolling tablist, so the button never scrolls out of view. */
|
|
440
|
+
.detail-tabs-trailing {
|
|
441
|
+
flex: none;
|
|
442
|
+
align-self: center;
|
|
443
|
+
padding-left: 0.75rem;
|
|
444
|
+
}
|
|
445
|
+
.detail-share {
|
|
446
|
+
border: 1px solid var(--border);
|
|
447
|
+
border-radius: 999px;
|
|
448
|
+
background: var(--background);
|
|
449
|
+
color: var(--foreground);
|
|
450
|
+
font-size: 0.8125rem;
|
|
451
|
+
padding: 0.25rem 0.75rem;
|
|
452
|
+
white-space: nowrap;
|
|
453
|
+
cursor: pointer;
|
|
454
|
+
transition:
|
|
455
|
+
color 0.14s ease-out,
|
|
456
|
+
border-color 0.14s ease-out;
|
|
457
|
+
}
|
|
458
|
+
/* Below 640px, render the Share button compact: icon only, text visually hidden. */
|
|
459
|
+
@media (max-width: 639px) {
|
|
460
|
+
.detail-share {
|
|
461
|
+
padding: 0.4375rem;
|
|
462
|
+
width: 36px;
|
|
463
|
+
height: 36px;
|
|
464
|
+
display: inline-flex;
|
|
465
|
+
align-items: center;
|
|
466
|
+
justify-content: center;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
.detail-share:hover {
|
|
470
|
+
color: color-mix(in oklab, var(--primary) 85%, black);
|
|
471
|
+
border-color: color-mix(in oklab, var(--primary) 85%, black);
|
|
472
|
+
}
|
|
473
|
+
.detail-share:focus-visible {
|
|
474
|
+
outline: 2px solid color-mix(in oklab, var(--primary) 85%, black);
|
|
475
|
+
outline-offset: 2px;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/* Behind this card: one left-aligned reading column. The input and its
|
|
479
|
+
Comments come first; each later group sits under a hairline with generous
|
|
480
|
+
room either side, and a plain title. */
|
|
481
|
+
.behind-panel {
|
|
482
|
+
container-type: inline-size;
|
|
483
|
+
container-name: behind;
|
|
484
|
+
}
|
|
485
|
+
@container behind (min-width: 900px) {
|
|
486
|
+
.behind-layout {
|
|
487
|
+
display: grid;
|
|
488
|
+
grid-template-columns: minmax(0, 68ch) minmax(240px, 1fr);
|
|
489
|
+
column-gap: 3.5rem;
|
|
490
|
+
}
|
|
491
|
+
.behind-main {
|
|
492
|
+
grid-column: 1;
|
|
493
|
+
}
|
|
494
|
+
.behind-aside {
|
|
495
|
+
grid-column: 2;
|
|
496
|
+
}
|
|
497
|
+
.behind-aside .behind-group {
|
|
498
|
+
margin-top: 0;
|
|
499
|
+
padding-top: 0;
|
|
500
|
+
border-top: none;
|
|
501
|
+
}
|
|
502
|
+
.behind-aside .behind-group + .behind-group {
|
|
503
|
+
margin-top: 2.5rem;
|
|
504
|
+
padding-top: 0;
|
|
505
|
+
border-top: none;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
.behind-group + .behind-group {
|
|
509
|
+
margin-top: 3.5rem;
|
|
510
|
+
padding-top: 2.25rem;
|
|
511
|
+
border-top: 1px solid var(--border);
|
|
512
|
+
}
|
|
513
|
+
.behind-group__title {
|
|
514
|
+
font-size: 0.9375rem;
|
|
515
|
+
font-weight: 600;
|
|
516
|
+
color: var(--foreground);
|
|
517
|
+
margin-bottom: 0.875rem;
|
|
518
|
+
}
|
|
519
|
+
.behind-dates {
|
|
520
|
+
margin-top: 0.375rem;
|
|
521
|
+
font-size: 0.78125rem;
|
|
522
|
+
color: var(--muted-foreground);
|
|
523
|
+
}
|
|
524
|
+
/* Touch targets: inline links in Behind get ≥24px hit area on coarse pointers. */
|
|
525
|
+
@media (pointer: coarse) {
|
|
526
|
+
.behind-group a {
|
|
527
|
+
padding-block: 0.375rem;
|
|
528
|
+
display: inline-block;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
.behind-ai__label {
|
|
532
|
+
font-size: 0.75rem;
|
|
533
|
+
color: var(--muted-foreground);
|
|
534
|
+
margin: 0.5rem 0 0.25rem;
|
|
535
|
+
}
|
|
536
|
+
.behind-ai {
|
|
537
|
+
font-size: 0.8125rem;
|
|
538
|
+
white-space: pre-wrap;
|
|
539
|
+
color: var(--muted-foreground);
|
|
540
|
+
background: var(--muted);
|
|
541
|
+
border-radius: 0.5rem;
|
|
542
|
+
padding: 0.625rem 0.75rem;
|
|
543
|
+
margin-bottom: 0.5rem;
|
|
544
|
+
}
|
|
545
|
+
.behind-card-source {
|
|
546
|
+
margin-top: 2rem;
|
|
547
|
+
font-size: 0.75rem;
|
|
548
|
+
color: var(--muted-foreground);
|
|
549
|
+
}
|
|
550
|
+
.behind-card-source:empty {
|
|
551
|
+
display: none;
|
|
552
|
+
}
|
|
444
553
|
.detail-tab {
|
|
445
554
|
position: relative;
|
|
446
555
|
display: inline-flex;
|
|
@@ -516,27 +625,6 @@
|
|
|
516
625
|
background: var(--chart-4, oklch(0.72 0.16 70));
|
|
517
626
|
box-shadow: 0 0 0 2px
|
|
518
627
|
color-mix(in oklab, var(--chart-4, oklch(0.72 0.16 70)) 25%, transparent);
|
|
519
|
-
|
|
520
|
-
/* How many items are still waiting on a maintainer. Amber rather than red: an entry
|
|
521
|
-
with open feedback is disputed, not broken, and red is already the withdraw
|
|
522
|
-
affordance in the same thread. 5.45:1 light, 8.08:1 dark. */
|
|
523
|
-
.feedback-open-count {
|
|
524
|
-
display: inline-flex;
|
|
525
|
-
align-items: center;
|
|
526
|
-
justify-content: center;
|
|
527
|
-
min-width: 1.15rem;
|
|
528
|
-
border-radius: 999px;
|
|
529
|
-
padding: 0.15rem 0.35rem;
|
|
530
|
-
font-size: 0.6875rem;
|
|
531
|
-
font-weight: 600;
|
|
532
|
-
line-height: 1;
|
|
533
|
-
letter-spacing: normal;
|
|
534
|
-
text-transform: none;
|
|
535
|
-
white-space: nowrap;
|
|
536
|
-
color: color-mix(in oklab, var(--chart-4) 45%, var(--foreground));
|
|
537
|
-
background: color-mix(in oklab, var(--chart-4) 18%, var(--card));
|
|
538
|
-
border: 1px solid color-mix(in oklab, var(--chart-4) 38%, var(--card));
|
|
539
|
-
}
|
|
540
628
|
}
|
|
541
629
|
|
|
542
630
|
/* tw-animate-css ships no reduced-motion rules of its own, so honour the
|
|
@@ -551,3 +639,391 @@
|
|
|
551
639
|
scroll-behavior: auto !important;
|
|
552
640
|
}
|
|
553
641
|
}
|
|
642
|
+
|
|
643
|
+
/* Comments on Behind this card: the heading with its help, then one feed.
|
|
644
|
+
A comment is a small meta line above the words, like a thread. */
|
|
645
|
+
.comments-head {
|
|
646
|
+
position: relative;
|
|
647
|
+
display: flex;
|
|
648
|
+
align-items: center;
|
|
649
|
+
gap: 0.375rem;
|
|
650
|
+
margin-bottom: 0.875rem;
|
|
651
|
+
}
|
|
652
|
+
.comments-head .behind-group__title {
|
|
653
|
+
margin-bottom: 0;
|
|
654
|
+
}
|
|
655
|
+
.comments-help-button {
|
|
656
|
+
display: grid;
|
|
657
|
+
place-items: center;
|
|
658
|
+
width: 24px;
|
|
659
|
+
height: 24px;
|
|
660
|
+
border-radius: 999px;
|
|
661
|
+
color: var(--muted-foreground);
|
|
662
|
+
}
|
|
663
|
+
.comments-help-button:hover,
|
|
664
|
+
.comments-help-button[aria-expanded='true'] {
|
|
665
|
+
color: var(--foreground);
|
|
666
|
+
}
|
|
667
|
+
.comments-help-button:focus-visible {
|
|
668
|
+
outline: 2px solid var(--ring);
|
|
669
|
+
outline-offset: 1px;
|
|
670
|
+
}
|
|
671
|
+
/* Touch targets: ≥44×44px on coarse pointers, without moving the icon. */
|
|
672
|
+
@media (pointer: coarse) {
|
|
673
|
+
.comments-help-button {
|
|
674
|
+
width: 44px;
|
|
675
|
+
height: 44px;
|
|
676
|
+
margin: -10px;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
.comments-help {
|
|
680
|
+
position: absolute;
|
|
681
|
+
top: 100%;
|
|
682
|
+
left: 0;
|
|
683
|
+
z-index: 20;
|
|
684
|
+
width: min(24rem, 100%);
|
|
685
|
+
margin-top: 0.375rem;
|
|
686
|
+
padding: 0.75rem 0.875rem;
|
|
687
|
+
border: 1px solid var(--border);
|
|
688
|
+
border-radius: 10px;
|
|
689
|
+
background: var(--popover);
|
|
690
|
+
color: var(--popover-foreground);
|
|
691
|
+
box-shadow: 0 8px 24px rgb(0 0 0 / 0.08);
|
|
692
|
+
font-size: 0.8125rem;
|
|
693
|
+
line-height: 1.5;
|
|
694
|
+
}
|
|
695
|
+
.comments-help[hidden] {
|
|
696
|
+
display: none;
|
|
697
|
+
}
|
|
698
|
+
.comments-help__title {
|
|
699
|
+
font-weight: 600;
|
|
700
|
+
margin-bottom: 0.375rem;
|
|
701
|
+
}
|
|
702
|
+
.comments-help ul {
|
|
703
|
+
list-style: disc;
|
|
704
|
+
margin: 0 0 0.5rem;
|
|
705
|
+
padding-left: 1.125rem;
|
|
706
|
+
}
|
|
707
|
+
.comments-help__note {
|
|
708
|
+
color: var(--muted-foreground);
|
|
709
|
+
}
|
|
710
|
+
.comments {
|
|
711
|
+
display: grid;
|
|
712
|
+
gap: 1.375rem;
|
|
713
|
+
margin: 0;
|
|
714
|
+
padding: 0;
|
|
715
|
+
list-style: none;
|
|
716
|
+
}
|
|
717
|
+
.comment__meta {
|
|
718
|
+
display: flex;
|
|
719
|
+
flex-wrap: wrap;
|
|
720
|
+
align-items: center;
|
|
721
|
+
gap: 0 0.3rem;
|
|
722
|
+
font-size: 0.71875rem;
|
|
723
|
+
line-height: 1.3;
|
|
724
|
+
color: var(--muted-foreground);
|
|
725
|
+
}
|
|
726
|
+
.comment__who {
|
|
727
|
+
font-weight: 500;
|
|
728
|
+
color: color-mix(in oklab, var(--muted-foreground) 60%, var(--foreground));
|
|
729
|
+
}
|
|
730
|
+
.comment__text {
|
|
731
|
+
margin-top: 1px;
|
|
732
|
+
font-size: 0.9375rem;
|
|
733
|
+
line-height: 1.5;
|
|
734
|
+
color: var(--foreground);
|
|
735
|
+
white-space: pre-wrap;
|
|
736
|
+
}
|
|
737
|
+
.comment__text.is-empty {
|
|
738
|
+
font-style: italic;
|
|
739
|
+
color: var(--muted-foreground);
|
|
740
|
+
}
|
|
741
|
+
.comment__reply {
|
|
742
|
+
margin-top: 0.25rem;
|
|
743
|
+
font-size: 0.84375rem;
|
|
744
|
+
color: var(--muted-foreground);
|
|
745
|
+
white-space: pre-wrap;
|
|
746
|
+
}
|
|
747
|
+
.comment__actions {
|
|
748
|
+
display: flex;
|
|
749
|
+
gap: 0.75rem;
|
|
750
|
+
margin-top: 0.25rem;
|
|
751
|
+
font-size: 0.75rem;
|
|
752
|
+
color: var(--muted-foreground);
|
|
753
|
+
}
|
|
754
|
+
.comment__actions button {
|
|
755
|
+
text-decoration: underline;
|
|
756
|
+
}
|
|
757
|
+
.comment__actions button:hover {
|
|
758
|
+
color: var(--foreground);
|
|
759
|
+
}
|
|
760
|
+
.comment__actions button.is-destructive:hover {
|
|
761
|
+
color: var(--destructive);
|
|
762
|
+
}
|
|
763
|
+
.community-shots {
|
|
764
|
+
display: flex;
|
|
765
|
+
flex-wrap: wrap;
|
|
766
|
+
gap: 0.375rem;
|
|
767
|
+
margin-top: 0.375rem;
|
|
768
|
+
}
|
|
769
|
+
.community-shots img {
|
|
770
|
+
display: block;
|
|
771
|
+
width: 48px;
|
|
772
|
+
height: 36px;
|
|
773
|
+
object-fit: cover;
|
|
774
|
+
border-radius: 5px;
|
|
775
|
+
border: 1px solid var(--border);
|
|
776
|
+
}
|
|
777
|
+
.community-shots a:hover img {
|
|
778
|
+
border-color: var(--ring);
|
|
779
|
+
}
|
|
780
|
+
.comments-skeleton {
|
|
781
|
+
display: grid;
|
|
782
|
+
gap: 1.375rem;
|
|
783
|
+
}
|
|
784
|
+
.comments-skeleton__item {
|
|
785
|
+
display: grid;
|
|
786
|
+
gap: 0.375rem;
|
|
787
|
+
}
|
|
788
|
+
.comments-skeleton__item::before,
|
|
789
|
+
.comments-skeleton__item::after {
|
|
790
|
+
content: '';
|
|
791
|
+
height: 1em;
|
|
792
|
+
background: var(--muted);
|
|
793
|
+
border-radius: 4px;
|
|
794
|
+
}
|
|
795
|
+
.comments-skeleton__item::before {
|
|
796
|
+
width: 30%;
|
|
797
|
+
}
|
|
798
|
+
.comments-skeleton__item::after {
|
|
799
|
+
width: 80%;
|
|
800
|
+
margin-top: 0.125rem;
|
|
801
|
+
}
|
|
802
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
803
|
+
.comments-skeleton__item::before,
|
|
804
|
+
.comments-skeleton__item::after {
|
|
805
|
+
animation: skeleton-shimmer 2s ease-in-out infinite;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
@keyframes skeleton-shimmer {
|
|
809
|
+
0%,
|
|
810
|
+
100% {
|
|
811
|
+
opacity: 1;
|
|
812
|
+
}
|
|
813
|
+
50% {
|
|
814
|
+
opacity: 0.5;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
.comments-empty {
|
|
818
|
+
font-size: 0.9375rem;
|
|
819
|
+
line-height: 1.5;
|
|
820
|
+
color: var(--muted-foreground);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/* "Know more?" — the input at the top of Behind this card */
|
|
824
|
+
.know-more {
|
|
825
|
+
margin-bottom: 3rem;
|
|
826
|
+
}
|
|
827
|
+
/* "Share what you know" points here; a dragged file shows where it lands. */
|
|
828
|
+
.know-more.is-flash .know-more-field textarea:not(.know-more-mirror),
|
|
829
|
+
.know-more[data-drop] .know-more-field textarea:not(.know-more-mirror) {
|
|
830
|
+
border-color: color-mix(in oklab, var(--primary) 85%, black);
|
|
831
|
+
box-shadow: 0 0 0 4px color-mix(in oklab, var(--primary) 25%, transparent);
|
|
832
|
+
}
|
|
833
|
+
.know-more[data-drop] .know-more-field textarea:not(.know-more-mirror) {
|
|
834
|
+
border-style: dashed;
|
|
835
|
+
}
|
|
836
|
+
.know-more-field {
|
|
837
|
+
position: relative;
|
|
838
|
+
display: flex;
|
|
839
|
+
align-items: flex-end;
|
|
840
|
+
gap: 0.5rem;
|
|
841
|
+
}
|
|
842
|
+
.know-more-field textarea:not(.know-more-mirror) {
|
|
843
|
+
flex: 1;
|
|
844
|
+
min-height: 0;
|
|
845
|
+
resize: none;
|
|
846
|
+
font: inherit;
|
|
847
|
+
font-size: 0.9375rem;
|
|
848
|
+
line-height: 20px;
|
|
849
|
+
padding: 9px 14px;
|
|
850
|
+
border: 1px solid var(--border);
|
|
851
|
+
border-radius: 10px;
|
|
852
|
+
background: var(--card);
|
|
853
|
+
outline: none;
|
|
854
|
+
transition:
|
|
855
|
+
height 0.22s cubic-bezier(0.2, 0.8, 0.2, 1),
|
|
856
|
+
border-color 0.15s,
|
|
857
|
+
background 0.15s,
|
|
858
|
+
box-shadow 0.15s;
|
|
859
|
+
}
|
|
860
|
+
/* iOS zooms inputs under 16px on mobile; use 16px below 640px. */
|
|
861
|
+
@media (max-width: 639px) {
|
|
862
|
+
.know-more-field textarea:not(.know-more-mirror) {
|
|
863
|
+
font-size: 1rem;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
.know-more-field textarea:not(.know-more-mirror):focus {
|
|
867
|
+
border-color: var(--ring);
|
|
868
|
+
box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 25%, transparent);
|
|
869
|
+
}
|
|
870
|
+
.know-more-field textarea:not(.know-more-mirror)::placeholder {
|
|
871
|
+
white-space: nowrap;
|
|
872
|
+
overflow: hidden;
|
|
873
|
+
text-overflow: ellipsis;
|
|
874
|
+
}
|
|
875
|
+
.know-more-clip {
|
|
876
|
+
flex: none;
|
|
877
|
+
display: grid;
|
|
878
|
+
place-items: center;
|
|
879
|
+
width: 40px;
|
|
880
|
+
height: 40px;
|
|
881
|
+
border-radius: 10px;
|
|
882
|
+
color: var(--muted-foreground);
|
|
883
|
+
opacity: 0.6;
|
|
884
|
+
transition: opacity 0.15s;
|
|
885
|
+
}
|
|
886
|
+
/* Touch targets: ≥44×44px on coarse pointers. */
|
|
887
|
+
@media (pointer: coarse) {
|
|
888
|
+
.know-more-clip {
|
|
889
|
+
width: 44px;
|
|
890
|
+
height: 44px;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
.know-more-clip:hover:not(:disabled),
|
|
894
|
+
.know-more-clip:focus-visible {
|
|
895
|
+
opacity: 1;
|
|
896
|
+
background: var(--muted);
|
|
897
|
+
}
|
|
898
|
+
.know-more-clip:disabled {
|
|
899
|
+
cursor: not-allowed;
|
|
900
|
+
opacity: 0.3;
|
|
901
|
+
}
|
|
902
|
+
.know-more-thumbs {
|
|
903
|
+
display: flex;
|
|
904
|
+
flex-wrap: wrap;
|
|
905
|
+
gap: 0.5rem;
|
|
906
|
+
margin: 0 0 0.5rem;
|
|
907
|
+
padding: 0;
|
|
908
|
+
list-style: none;
|
|
909
|
+
}
|
|
910
|
+
.know-more-thumb {
|
|
911
|
+
position: relative;
|
|
912
|
+
width: 56px;
|
|
913
|
+
height: 42px;
|
|
914
|
+
overflow: hidden;
|
|
915
|
+
border-radius: 6px;
|
|
916
|
+
border: 1px solid var(--border);
|
|
917
|
+
}
|
|
918
|
+
.know-more-thumb img {
|
|
919
|
+
display: block;
|
|
920
|
+
width: 100%;
|
|
921
|
+
height: 100%;
|
|
922
|
+
object-fit: cover;
|
|
923
|
+
}
|
|
924
|
+
.know-more-thumb button {
|
|
925
|
+
position: absolute;
|
|
926
|
+
top: 1px;
|
|
927
|
+
right: 1px;
|
|
928
|
+
display: grid;
|
|
929
|
+
place-items: center;
|
|
930
|
+
width: 16px;
|
|
931
|
+
height: 16px;
|
|
932
|
+
border-radius: 999px;
|
|
933
|
+
background: rgb(0 0 0 / 0.55);
|
|
934
|
+
color: white;
|
|
935
|
+
}
|
|
936
|
+
/* Always there, so the input never shifts; grey until there is something to send. */
|
|
937
|
+
.know-more-send {
|
|
938
|
+
flex: none;
|
|
939
|
+
height: 40px;
|
|
940
|
+
padding-inline: 1rem;
|
|
941
|
+
border-radius: 10px;
|
|
942
|
+
font-size: 0.875rem;
|
|
943
|
+
}
|
|
944
|
+
@media (pointer: coarse) {
|
|
945
|
+
.know-more-send {
|
|
946
|
+
height: 44px;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
.know-more-send:disabled {
|
|
950
|
+
opacity: 1;
|
|
951
|
+
background: var(--muted);
|
|
952
|
+
color: var(--muted-foreground);
|
|
953
|
+
}
|
|
954
|
+
.know-more-mirror {
|
|
955
|
+
position: absolute;
|
|
956
|
+
visibility: hidden;
|
|
957
|
+
height: 0;
|
|
958
|
+
overflow: hidden;
|
|
959
|
+
top: 0;
|
|
960
|
+
left: 0;
|
|
961
|
+
padding: 9px 14px;
|
|
962
|
+
font: inherit;
|
|
963
|
+
font-size: 0.9375rem;
|
|
964
|
+
line-height: 20px;
|
|
965
|
+
border: 1px solid transparent;
|
|
966
|
+
resize: none;
|
|
967
|
+
}
|
|
968
|
+
@media (max-width: 639px) {
|
|
969
|
+
.know-more-mirror {
|
|
970
|
+
font-size: 1rem;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
.know-more-hint {
|
|
974
|
+
font-size: 0.75rem;
|
|
975
|
+
color: var(--muted-foreground);
|
|
976
|
+
max-height: 0;
|
|
977
|
+
opacity: 0;
|
|
978
|
+
overflow: hidden;
|
|
979
|
+
transition:
|
|
980
|
+
max-height 0.2s ease,
|
|
981
|
+
opacity 0.2s ease,
|
|
982
|
+
margin 0.2s ease;
|
|
983
|
+
}
|
|
984
|
+
.know-more-hint.is-on {
|
|
985
|
+
/* Room for two lines: on a narrow card the hint wraps. */
|
|
986
|
+
max-height: 3rem;
|
|
987
|
+
opacity: 1;
|
|
988
|
+
margin-top: 0.375rem;
|
|
989
|
+
}
|
|
990
|
+
.know-more-attaching {
|
|
991
|
+
margin-top: 0.375rem;
|
|
992
|
+
font-size: 0.75rem;
|
|
993
|
+
color: var(--muted-foreground);
|
|
994
|
+
}
|
|
995
|
+
.know-more-attaching:empty {
|
|
996
|
+
display: none;
|
|
997
|
+
}
|
|
998
|
+
.know-more-clip[aria-busy] {
|
|
999
|
+
cursor: progress;
|
|
1000
|
+
}
|
|
1001
|
+
.know-more-error {
|
|
1002
|
+
margin-top: 0.5rem;
|
|
1003
|
+
font-size: 0.8125rem;
|
|
1004
|
+
color: var(--destructive);
|
|
1005
|
+
}
|
|
1006
|
+
.know-more-sent {
|
|
1007
|
+
font-size: 0.8125rem;
|
|
1008
|
+
color: oklch(0.52 0.14 150);
|
|
1009
|
+
max-height: 0;
|
|
1010
|
+
opacity: 0;
|
|
1011
|
+
overflow: hidden;
|
|
1012
|
+
transition:
|
|
1013
|
+
max-height 0.25s ease,
|
|
1014
|
+
opacity 0.25s ease;
|
|
1015
|
+
}
|
|
1016
|
+
.know-more-sent.is-on {
|
|
1017
|
+
max-height: 1.5rem;
|
|
1018
|
+
opacity: 1;
|
|
1019
|
+
margin-top: 0.5rem;
|
|
1020
|
+
}
|
|
1021
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1022
|
+
.know-more-field textarea:not(.know-more-mirror),
|
|
1023
|
+
.know-more-clip,
|
|
1024
|
+
.know-more-hint,
|
|
1025
|
+
.know-more-sent,
|
|
1026
|
+
.detail-share {
|
|
1027
|
+
transition: none;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@igstack/app-catalog-frontend-core",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.10.0",
|
|
4
4
|
"description": "Frontend core library for App Catalog",
|
|
5
5
|
"homepage": "https://github.com/lislon/app-catalog",
|
|
6
6
|
"repository": {
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"tailwindcss": "^4.1.7",
|
|
119
119
|
"tiptap-markdown": "^0.8.0",
|
|
120
120
|
"tslib": "^2.3.0",
|
|
121
|
-
"@igstack/app-catalog-shared-core": "6.
|
|
121
|
+
"@igstack/app-catalog-shared-core": "6.10.0"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@tailwindcss/vite": "^4.0.5",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"vite-plugin-static-copy": "^3.1.4",
|
|
147
147
|
"vite-plugin-svgr": "^4.2.0",
|
|
148
148
|
"vitest": "^4.1.2",
|
|
149
|
-
"@igstack/app-catalog-backend-core": "6.
|
|
149
|
+
"@igstack/app-catalog-backend-core": "6.10.0"
|
|
150
150
|
},
|
|
151
151
|
"peerDependencies": {
|
|
152
152
|
"@tanstack/react-router": "1.170.41",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
"vite": "^6.3.5",
|
|
157
157
|
"vite-plugin-svgr": "^4.2.0"
|
|
158
158
|
},
|
|
159
|
-
"gitHead": "
|
|
159
|
+
"gitHead": "8a9a5fb554ef3414c474c608d32f830907dfcc72",
|
|
160
160
|
"scripts": {
|
|
161
161
|
"build": "vite build",
|
|
162
162
|
"build:lenient": "vite build --mode lenient",
|
|
@@ -36,8 +36,11 @@ vi.mock('~/modules/auth', () => ({
|
|
|
36
36
|
useUser: vi.fn(() => null),
|
|
37
37
|
useOptionalUser: vi.fn(() => null),
|
|
38
38
|
}))
|
|
39
|
-
vi.mock('~/modules/appCatalog/ui/detail/
|
|
40
|
-
|
|
39
|
+
vi.mock('~/modules/appCatalog/ui/detail/CommunitySection', () => ({
|
|
40
|
+
CommunitySection: () => <div />,
|
|
41
|
+
}))
|
|
42
|
+
vi.mock('~/modules/appCatalog/ui/detail/usePendingCount', () => ({
|
|
43
|
+
usePendingCount: () => 0,
|
|
41
44
|
}))
|
|
42
45
|
|
|
43
46
|
const { AppDetailPanel } =
|
|
@@ -30,8 +30,11 @@ vi.mock('~/modules/auth', () => ({
|
|
|
30
30
|
useUser: vi.fn(() => null),
|
|
31
31
|
useOptionalUser: vi.fn(() => null),
|
|
32
32
|
}))
|
|
33
|
-
vi.mock('~/modules/appCatalog/ui/detail/
|
|
34
|
-
|
|
33
|
+
vi.mock('~/modules/appCatalog/ui/detail/CommunitySection', () => ({
|
|
34
|
+
CommunitySection: () => <div />,
|
|
35
|
+
}))
|
|
36
|
+
vi.mock('~/modules/appCatalog/ui/detail/usePendingCount', () => ({
|
|
37
|
+
usePendingCount: () => 0,
|
|
35
38
|
}))
|
|
36
39
|
vi.mock('~/modules/appCatalog/ui/components/SubResourceDetailPanel', () => ({
|
|
37
40
|
SubResourceDetailPanel: () => null,
|
|
@@ -28,8 +28,11 @@ vi.mock('~/modules/appCatalog/ui/context/AppCatalogFiltersContext', () => ({
|
|
|
28
28
|
useAppCatalogFilters: vi.fn(() => ({ selectedTags: [], toggleTag: vi.fn() })),
|
|
29
29
|
}))
|
|
30
30
|
vi.mock('~/modules/auth', () => ({ useUser: vi.fn(() => null) }))
|
|
31
|
-
vi.mock('~/modules/appCatalog/ui/detail/
|
|
32
|
-
|
|
31
|
+
vi.mock('~/modules/appCatalog/ui/detail/CommunitySection', () => ({
|
|
32
|
+
CommunitySection: () => <div />,
|
|
33
|
+
}))
|
|
34
|
+
vi.mock('~/modules/appCatalog/ui/detail/usePendingCount', () => ({
|
|
35
|
+
usePendingCount: () => 0,
|
|
33
36
|
}))
|
|
34
37
|
|
|
35
38
|
const { AppDetails } = await import('~/modules/appCatalog/ui/detail/AppDetails')
|
|
@@ -66,17 +69,13 @@ describe('AppDetails — Background', () => {
|
|
|
66
69
|
).toBeInTheDocument()
|
|
67
70
|
})
|
|
68
71
|
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
it('leaves no empty section when the entry has no history recorded', () => {
|
|
72
|
+
// With neither links nor history the tab has nothing to say, so it is not
|
|
73
|
+
// offered at all — an empty tab is the same dead end as an empty section.
|
|
74
|
+
it('offers no Documentation tab when the entry has no history recorded', () => {
|
|
73
75
|
const { background: _omitted, ...withoutBackground } = app
|
|
74
76
|
render(<AppDetails app={withoutBackground as Resource} />)
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
expect(screen.queryByRole('tab', { name: /documentation/i })).toBeNull()
|
|
78
79
|
expect(screen.queryByRole('heading', { name: 'Background' })).toBeNull()
|
|
79
|
-
// Proves the panel really is open, so the absence above means something.
|
|
80
|
-
expect(screen.getByRole('heading', { name: 'Sources' })).toBeVisible()
|
|
81
80
|
})
|
|
82
81
|
})
|