@signalcore/ui 1.0.0-beta.3 → 1.0.0-beta.4
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 +79 -0
- package/dist/AgentChat.d.ts +19 -3
- package/dist/AgentChat.js +149 -27
- package/dist/AgentChat.js.map +1 -1
- package/dist/AgentSpace.d.ts +14 -2
- package/dist/AgentSpace.js +3 -1
- package/dist/AgentSpace.js.map +1 -1
- package/dist/View.d.ts +48 -0
- package/dist/View.js +101 -0
- package/dist/View.js.map +1 -0
- package/dist/blocks.d.ts +83 -2
- package/dist/client.d.ts +9 -1
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/es.js +12 -0
- package/dist/es.js.map +1 -1
- package/dist/index.d.ts +11 -5
- package/dist/index.js +7 -1
- package/dist/kit/Agenda.d.ts +25 -0
- package/dist/kit/Agenda.js +119 -0
- package/dist/kit/Agenda.js.map +1 -0
- package/dist/kit/Combobox.js +1 -1
- package/dist/kit/DateField.js +1 -1
- package/dist/kit/Kanban.d.ts +17 -0
- package/dist/kit/Kanban.js +157 -0
- package/dist/kit/Kanban.js.map +1 -0
- package/dist/kit/TimeField.js +1 -1
- package/dist/kit/Timeline.d.ts +14 -0
- package/dist/kit/Timeline.js +71 -0
- package/dist/kit/Timeline.js.map +1 -0
- package/dist/kit/context.d.ts +1 -1
- package/dist/kit/context.js.map +1 -1
- package/dist/kit/messages.d.ts +22 -0
- package/dist/kit/messages.js +10 -0
- package/dist/kit/messages.js.map +1 -1
- package/dist/surface/Placed.d.ts +20 -0
- package/dist/surface/Placed.js +70 -0
- package/dist/surface/Placed.js.map +1 -0
- package/dist/surface/Surface.d.ts +4 -2
- package/dist/surface/Surface.js +78 -2
- package/dist/surface/Surface.js.map +1 -1
- package/dist/surface/places.d.ts +16 -0
- package/dist/surface/places.js +15 -0
- package/dist/surface/places.js.map +1 -0
- package/dist/surface/scope.d.ts +17 -1
- package/dist/surface/scope.js +1 -0
- package/dist/surface/scope.js.map +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.js.map +1 -1
- package/dist/widget.js +17 -17
- package/package.json +1 -1
- package/src/AgentChat.tsx +215 -34
- package/src/AgentSpace.tsx +17 -1
- package/src/View.tsx +117 -0
- package/src/blocks.ts +100 -2
- package/src/client.ts +16 -0
- package/src/contract.ts +166 -5
- package/src/es.ts +9 -0
- package/src/index.ts +27 -2
- package/src/kit/Agenda.tsx +161 -0
- package/src/kit/Kanban.tsx +182 -0
- package/src/kit/Timeline.tsx +58 -0
- package/src/kit/context.tsx +45 -1
- package/src/kit/messages.ts +31 -0
- package/src/styles.css +568 -0
- package/src/surface/Placed.tsx +98 -0
- package/src/surface/Surface.tsx +92 -1
- package/src/surface/places.ts +19 -0
- package/src/surface/scope.ts +24 -1
- package/src/types.ts +13 -0
- package/src/widget/element.tsx +41 -3
package/src/styles.css
CHANGED
|
@@ -714,6 +714,124 @@
|
|
|
714
714
|
height: 14px;
|
|
715
715
|
}
|
|
716
716
|
|
|
717
|
+
/* Where the agent put what it showed apart: a quiet line in its reply, its glyph and words, that
|
|
718
|
+
opens it again; the one open reads in the ink. */
|
|
719
|
+
.sc-chat__placed {
|
|
720
|
+
display: inline-flex;
|
|
721
|
+
align-items: center;
|
|
722
|
+
gap: calc(var(--_space) * 2);
|
|
723
|
+
align-self: flex-start;
|
|
724
|
+
margin: calc(var(--_space) * 2) 0 0;
|
|
725
|
+
padding: 2px 0;
|
|
726
|
+
border: 0;
|
|
727
|
+
background: none;
|
|
728
|
+
color: var(--_muted);
|
|
729
|
+
font: inherit;
|
|
730
|
+
font-size: var(--_font-size-sm);
|
|
731
|
+
text-align: left;
|
|
732
|
+
white-space: normal;
|
|
733
|
+
cursor: pointer;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
.sc-chat__placed:hover {
|
|
737
|
+
color: var(--_fg);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.sc-chat__placed:hover > span {
|
|
741
|
+
text-decoration: underline;
|
|
742
|
+
text-decoration-color: var(--_line-hover);
|
|
743
|
+
text-underline-offset: 3px;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.sc-chat__placed:focus-visible {
|
|
747
|
+
outline: 2px solid var(--_accent);
|
|
748
|
+
outline-offset: 2px;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.sc-chat__placed--open {
|
|
752
|
+
color: var(--_fg);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
.sc-chat__placed > svg {
|
|
756
|
+
flex-shrink: 0;
|
|
757
|
+
width: 15px;
|
|
758
|
+
height: 15px;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/* A surface apart: its title and close over it, the surface scrolling under them. A panel stands
|
|
762
|
+
at the chat's right edge, the conversation beside it (under it, where the chat is narrow); a
|
|
763
|
+
modal over the page, on a dimmed backdrop. */
|
|
764
|
+
.sc-placed {
|
|
765
|
+
display: flex;
|
|
766
|
+
flex-direction: column;
|
|
767
|
+
min-height: 0;
|
|
768
|
+
color: var(--_fg);
|
|
769
|
+
background: var(--_surface);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
.sc-placed__head {
|
|
773
|
+
display: flex;
|
|
774
|
+
flex-shrink: 0;
|
|
775
|
+
align-items: center;
|
|
776
|
+
justify-content: space-between;
|
|
777
|
+
gap: 12px;
|
|
778
|
+
padding: 10px 10px 10px 16px;
|
|
779
|
+
border-bottom: 1px solid var(--_hair);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
.sc-placed__title {
|
|
783
|
+
margin: 0;
|
|
784
|
+
overflow: hidden;
|
|
785
|
+
font-size: var(--_font-size);
|
|
786
|
+
font-weight: var(--_font-weight-bold);
|
|
787
|
+
text-overflow: ellipsis;
|
|
788
|
+
white-space: nowrap;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.sc-placed__title::first-letter {
|
|
792
|
+
text-transform: uppercase;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
.sc-placed__body {
|
|
796
|
+
flex: 1;
|
|
797
|
+
min-height: 0;
|
|
798
|
+
padding: 16px;
|
|
799
|
+
overflow-y: auto;
|
|
800
|
+
overscroll-behavior: contain;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
.sc-placed--panel {
|
|
804
|
+
position: absolute;
|
|
805
|
+
inset: 0 0 0 auto;
|
|
806
|
+
z-index: 2;
|
|
807
|
+
width: min(440px, 100%);
|
|
808
|
+
border-left: 1px solid var(--_line);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
/* The conversation beside an open panel: what is left of the chat's width (none, where the panel
|
|
812
|
+
takes it all). */
|
|
813
|
+
.sc-chat--placed {
|
|
814
|
+
padding-right: min(440px, 100%);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
.sc-placed--modal {
|
|
818
|
+
width: min(600px, calc(100vw - 32px));
|
|
819
|
+
max-height: min(720px, calc(100dvh - 48px));
|
|
820
|
+
padding: 0;
|
|
821
|
+
overflow: hidden;
|
|
822
|
+
border: 1px solid var(--_line);
|
|
823
|
+
border-radius: var(--_radius);
|
|
824
|
+
box-shadow: var(--_shadow-overlay);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
.sc-placed--modal[open] {
|
|
828
|
+
display: flex;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
.sc-placed--modal::backdrop {
|
|
832
|
+
background: rgb(0 0 0 / 0.32);
|
|
833
|
+
}
|
|
834
|
+
|
|
717
835
|
/* Where who answers the conversation changed: the same quiet line, what changed and why centred
|
|
718
836
|
between the hairlines (a long reason wraps there), and when, quieter still. */
|
|
719
837
|
.sc-chat__handover {
|
|
@@ -2283,6 +2401,439 @@ button.sc-tile__main:focus-visible {
|
|
|
2283
2401
|
white-space: nowrap;
|
|
2284
2402
|
}
|
|
2285
2403
|
|
|
2404
|
+
/* A calendar: its days one under another, each its weekday and number at the left of its events
|
|
2405
|
+
(today's in the accent), an empty day a single quiet line; wide enough, the week stands as
|
|
2406
|
+
seven columns. Each event its hours in figures that line up, its title, a quiet line of detail;
|
|
2407
|
+
one to open or press lights under the pointer. */
|
|
2408
|
+
.sc-agenda {
|
|
2409
|
+
min-width: 0;
|
|
2410
|
+
container-type: inline-size;
|
|
2411
|
+
font-variant-numeric: tabular-nums;
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
.sc-agenda__days {
|
|
2415
|
+
display: flex;
|
|
2416
|
+
flex-direction: column;
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
.sc-agenda__day {
|
|
2420
|
+
display: grid;
|
|
2421
|
+
grid-template-columns: 44px minmax(0, 1fr);
|
|
2422
|
+
gap: 12px;
|
|
2423
|
+
padding: 10px 0;
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
.sc-agenda__day + .sc-agenda__day {
|
|
2427
|
+
border-top: 1px solid var(--_hair);
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
.sc-agenda--day .sc-agenda__day {
|
|
2431
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2432
|
+
padding: 0;
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
.sc-agenda__date {
|
|
2436
|
+
display: flex;
|
|
2437
|
+
flex-direction: column;
|
|
2438
|
+
align-items: flex-start;
|
|
2439
|
+
margin: 0;
|
|
2440
|
+
font-weight: var(--_font-weight);
|
|
2441
|
+
line-height: 1.2;
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
.sc-agenda__weekday {
|
|
2445
|
+
color: var(--_subtle);
|
|
2446
|
+
font-size: var(--_font-size-xs);
|
|
2447
|
+
text-transform: capitalize;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
.sc-agenda__number {
|
|
2451
|
+
color: var(--_fg);
|
|
2452
|
+
font-size: var(--_font-size-lg);
|
|
2453
|
+
font-weight: var(--_font-weight-medium);
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
.sc-agenda__day--today .sc-agenda__weekday,
|
|
2457
|
+
.sc-agenda__day--today .sc-agenda__number {
|
|
2458
|
+
color: var(--_accent);
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
.sc-agenda__events {
|
|
2462
|
+
display: flex;
|
|
2463
|
+
flex-direction: column;
|
|
2464
|
+
gap: 2px;
|
|
2465
|
+
min-width: 0;
|
|
2466
|
+
margin: 0;
|
|
2467
|
+
padding: 0;
|
|
2468
|
+
list-style: none;
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
.sc-agenda__event {
|
|
2472
|
+
display: grid;
|
|
2473
|
+
grid-template-columns: calc(var(--_font-size) * 7) minmax(0, 1fr);
|
|
2474
|
+
gap: 12px;
|
|
2475
|
+
align-items: baseline;
|
|
2476
|
+
width: 100%;
|
|
2477
|
+
margin: 0 -8px;
|
|
2478
|
+
padding: 6px 8px;
|
|
2479
|
+
border: 0;
|
|
2480
|
+
border-radius: var(--_inner);
|
|
2481
|
+
background: none;
|
|
2482
|
+
color: inherit;
|
|
2483
|
+
font: inherit;
|
|
2484
|
+
text-align: left;
|
|
2485
|
+
text-decoration: none;
|
|
2486
|
+
box-sizing: content-box;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
:is(a, button).sc-agenda__event {
|
|
2490
|
+
cursor: pointer;
|
|
2491
|
+
transition: background-color 0.12s;
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
:is(a, button).sc-agenda__event:hover:not(:disabled) {
|
|
2495
|
+
background: var(--_wash);
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
:is(a, button).sc-agenda__event:focus-visible {
|
|
2499
|
+
outline: 2px solid var(--_accent);
|
|
2500
|
+
outline-offset: -2px;
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
button.sc-agenda__event:disabled {
|
|
2504
|
+
cursor: default;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
.sc-agenda__time {
|
|
2508
|
+
color: var(--_muted);
|
|
2509
|
+
font-size: var(--_font-size-sm);
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
.sc-agenda__time > span {
|
|
2513
|
+
white-space: nowrap;
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
.sc-agenda__what {
|
|
2517
|
+
display: flex;
|
|
2518
|
+
flex-direction: column;
|
|
2519
|
+
min-width: 0;
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
.sc-agenda__title {
|
|
2523
|
+
overflow-wrap: anywhere;
|
|
2524
|
+
font-weight: var(--_font-weight-medium);
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
.sc-agenda__detail,
|
|
2528
|
+
.sc-agenda__empty {
|
|
2529
|
+
color: var(--_muted);
|
|
2530
|
+
font-size: var(--_font-size-sm);
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
.sc-agenda__empty {
|
|
2534
|
+
margin: 0;
|
|
2535
|
+
padding: 2px 0;
|
|
2536
|
+
color: var(--_subtle);
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
.sc-agenda__day--empty {
|
|
2540
|
+
align-items: center;
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
@container (min-width: 680px) {
|
|
2544
|
+
.sc-agenda:not(.sc-agenda--day) > .sc-agenda__days {
|
|
2545
|
+
display: grid;
|
|
2546
|
+
grid-template-columns: repeat(7, minmax(0, 1fr));
|
|
2547
|
+
border: 1px solid var(--_hair);
|
|
2548
|
+
border-radius: var(--_inner);
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
.sc-agenda:not(.sc-agenda--day) .sc-agenda__day {
|
|
2552
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2553
|
+
align-content: start;
|
|
2554
|
+
gap: 8px;
|
|
2555
|
+
min-height: 140px;
|
|
2556
|
+
padding: 10px;
|
|
2557
|
+
border-top: 0;
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
.sc-agenda:not(.sc-agenda--day) .sc-agenda__day + .sc-agenda__day {
|
|
2561
|
+
border-left: 1px solid var(--_hair);
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2564
|
+
.sc-agenda:not(.sc-agenda--day) .sc-agenda__event {
|
|
2565
|
+
grid-template-columns: minmax(0, 1fr);
|
|
2566
|
+
gap: 0;
|
|
2567
|
+
margin: 0 -6px;
|
|
2568
|
+
padding: 4px 6px;
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
.sc-agenda:not(.sc-agenda--day) .sc-agenda__time {
|
|
2572
|
+
font-size: var(--_font-size-xs);
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
.sc-agenda:not(.sc-agenda--day) .sc-agenda__empty {
|
|
2576
|
+
display: none;
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
|
|
2580
|
+
/* A timeline: a hairline down the left, a dot on it for each thing (hollow, or filled in its
|
|
2581
|
+
tone), its title with where it stands in a quiet word at its right, when under it, a line
|
|
2582
|
+
about it. */
|
|
2583
|
+
.sc-timeline {
|
|
2584
|
+
--_rail: 7px;
|
|
2585
|
+
|
|
2586
|
+
display: flex;
|
|
2587
|
+
flex-direction: column;
|
|
2588
|
+
min-width: 0;
|
|
2589
|
+
margin: 0;
|
|
2590
|
+
padding: 0;
|
|
2591
|
+
list-style: none;
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
.sc-timeline__item {
|
|
2595
|
+
--_dot: var(--_line-hover);
|
|
2596
|
+
|
|
2597
|
+
position: relative;
|
|
2598
|
+
display: grid;
|
|
2599
|
+
grid-template-columns: 16px minmax(0, 1fr);
|
|
2600
|
+
gap: 10px;
|
|
2601
|
+
padding-bottom: 14px;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
.sc-timeline__item:last-child {
|
|
2605
|
+
padding-bottom: 0;
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
.sc-timeline__item::before {
|
|
2609
|
+
content: "";
|
|
2610
|
+
position: absolute;
|
|
2611
|
+
top: 14px;
|
|
2612
|
+
bottom: -2px;
|
|
2613
|
+
left: var(--_rail);
|
|
2614
|
+
width: 1px;
|
|
2615
|
+
background: var(--_line);
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
.sc-timeline__item:last-child::before {
|
|
2619
|
+
display: none;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
.sc-timeline__item--info {
|
|
2623
|
+
--_dot: var(--_accent);
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
.sc-timeline__item--success {
|
|
2627
|
+
--_dot: var(--_success);
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
.sc-timeline__item--warning {
|
|
2631
|
+
--_dot: var(--_warning);
|
|
2632
|
+
}
|
|
2633
|
+
|
|
2634
|
+
.sc-timeline__item--danger {
|
|
2635
|
+
--_dot: var(--_danger);
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
.sc-timeline__dot {
|
|
2639
|
+
width: 9px;
|
|
2640
|
+
height: 9px;
|
|
2641
|
+
margin: 6px 0 0 3px;
|
|
2642
|
+
border: 2px solid var(--_dot);
|
|
2643
|
+
border-radius: var(--_radius-full);
|
|
2644
|
+
background: var(--_surface);
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
[class*="sc-timeline__item--"] > .sc-timeline__dot {
|
|
2648
|
+
background: var(--_dot);
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
.sc-timeline__body {
|
|
2652
|
+
display: flex;
|
|
2653
|
+
flex-direction: column;
|
|
2654
|
+
min-width: 0;
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2657
|
+
.sc-timeline__head {
|
|
2658
|
+
display: flex;
|
|
2659
|
+
align-items: baseline;
|
|
2660
|
+
justify-content: space-between;
|
|
2661
|
+
gap: 12px;
|
|
2662
|
+
margin: 0;
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2665
|
+
.sc-timeline__title {
|
|
2666
|
+
min-width: 0;
|
|
2667
|
+
overflow-wrap: anywhere;
|
|
2668
|
+
font-weight: var(--_font-weight-medium);
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
.sc-timeline__status {
|
|
2672
|
+
flex-shrink: 0;
|
|
2673
|
+
color: var(--_muted);
|
|
2674
|
+
font-size: var(--_font-size-sm);
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
.sc-timeline__when {
|
|
2678
|
+
color: var(--_subtle);
|
|
2679
|
+
font-size: var(--_font-size-xs);
|
|
2680
|
+
font-variant-numeric: tabular-nums;
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
.sc-timeline__text {
|
|
2684
|
+
margin: 2px 0 0;
|
|
2685
|
+
color: var(--_muted);
|
|
2686
|
+
font-size: var(--_font-size-sm);
|
|
2687
|
+
}
|
|
2688
|
+
|
|
2689
|
+
/* A board: its columns side by side on a sunken ground, scrolling across inside their own box
|
|
2690
|
+
when they don't fit, each its title and count over its cards; a card lifts a hair off the
|
|
2691
|
+
column, a moving one fades where it was, and the column it would land in lights. */
|
|
2692
|
+
.sc-board {
|
|
2693
|
+
display: grid;
|
|
2694
|
+
grid-auto-columns: minmax(200px, 1fr);
|
|
2695
|
+
grid-auto-flow: column;
|
|
2696
|
+
gap: 8px;
|
|
2697
|
+
min-width: 0;
|
|
2698
|
+
overflow-x: auto;
|
|
2699
|
+
overscroll-behavior-x: contain;
|
|
2700
|
+
scroll-snap-type: x proximity;
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
.sc-board__column {
|
|
2704
|
+
display: flex;
|
|
2705
|
+
flex-direction: column;
|
|
2706
|
+
gap: 8px;
|
|
2707
|
+
min-width: 0;
|
|
2708
|
+
padding: 10px;
|
|
2709
|
+
border: 1px solid transparent;
|
|
2710
|
+
border-radius: var(--_inner);
|
|
2711
|
+
background: var(--_sunken);
|
|
2712
|
+
scroll-snap-align: start;
|
|
2713
|
+
}
|
|
2714
|
+
|
|
2715
|
+
.sc-board__column--over {
|
|
2716
|
+
border-color: color-mix(in srgb, var(--_accent) 40%, transparent);
|
|
2717
|
+
background: var(--_picked);
|
|
2718
|
+
}
|
|
2719
|
+
|
|
2720
|
+
.sc-board__head {
|
|
2721
|
+
display: flex;
|
|
2722
|
+
align-items: baseline;
|
|
2723
|
+
justify-content: space-between;
|
|
2724
|
+
gap: 8px;
|
|
2725
|
+
margin: 0;
|
|
2726
|
+
padding: 0 2px;
|
|
2727
|
+
font-size: var(--_font-size-sm);
|
|
2728
|
+
font-weight: var(--_font-weight-medium);
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
.sc-board__count {
|
|
2732
|
+
color: var(--_subtle);
|
|
2733
|
+
font-weight: var(--_font-weight);
|
|
2734
|
+
font-variant-numeric: tabular-nums;
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
.sc-board__cards {
|
|
2738
|
+
display: flex;
|
|
2739
|
+
flex-direction: column;
|
|
2740
|
+
gap: 6px;
|
|
2741
|
+
margin: 0;
|
|
2742
|
+
padding: 0;
|
|
2743
|
+
list-style: none;
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
.sc-board__card {
|
|
2747
|
+
position: relative;
|
|
2748
|
+
display: flex;
|
|
2749
|
+
flex-direction: column;
|
|
2750
|
+
gap: 2px;
|
|
2751
|
+
padding: 10px 12px;
|
|
2752
|
+
border: 1px solid var(--_line);
|
|
2753
|
+
border-radius: var(--_inner);
|
|
2754
|
+
background: var(--_surface);
|
|
2755
|
+
box-shadow: var(--_shadow);
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
.sc-board__card[draggable="true"] {
|
|
2759
|
+
padding-right: 36px;
|
|
2760
|
+
cursor: grab;
|
|
2761
|
+
}
|
|
2762
|
+
|
|
2763
|
+
.sc-board__card--dragging {
|
|
2764
|
+
opacity: 0.45;
|
|
2765
|
+
}
|
|
2766
|
+
|
|
2767
|
+
.sc-board__card-title {
|
|
2768
|
+
overflow-wrap: anywhere;
|
|
2769
|
+
font-weight: var(--_font-weight-medium);
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2772
|
+
.sc-board__card-subtitle {
|
|
2773
|
+
color: var(--_muted);
|
|
2774
|
+
font-size: var(--_font-size-sm);
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
.sc-board__card-meta {
|
|
2778
|
+
margin-top: 4px;
|
|
2779
|
+
color: var(--_muted);
|
|
2780
|
+
font-size: var(--_font-size-xs);
|
|
2781
|
+
font-variant-numeric: tabular-nums;
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
.sc-board__empty {
|
|
2785
|
+
margin: 0;
|
|
2786
|
+
padding: 2px;
|
|
2787
|
+
color: var(--_subtle);
|
|
2788
|
+
font-size: var(--_font-size-sm);
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2791
|
+
.sc-board__move {
|
|
2792
|
+
position: absolute;
|
|
2793
|
+
top: 6px;
|
|
2794
|
+
right: 6px;
|
|
2795
|
+
display: grid;
|
|
2796
|
+
place-items: center;
|
|
2797
|
+
width: 26px;
|
|
2798
|
+
height: 26px;
|
|
2799
|
+
padding: 0;
|
|
2800
|
+
border: 0;
|
|
2801
|
+
border-radius: calc(var(--_inner) - 2px);
|
|
2802
|
+
background: none;
|
|
2803
|
+
color: var(--_subtle);
|
|
2804
|
+
cursor: pointer;
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
.sc-board__move:hover,
|
|
2808
|
+
.sc-board__move[aria-expanded="true"] {
|
|
2809
|
+
background: var(--_wash);
|
|
2810
|
+
color: var(--_fg);
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
.sc-board__move:focus-visible {
|
|
2814
|
+
outline: 2px solid var(--_accent);
|
|
2815
|
+
outline-offset: 0;
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
.sc-board__move > svg {
|
|
2819
|
+
width: 15px;
|
|
2820
|
+
height: 15px;
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
.sc-board__menu {
|
|
2824
|
+
display: flex;
|
|
2825
|
+
flex-direction: column;
|
|
2826
|
+
min-width: 160px;
|
|
2827
|
+
padding: 4px;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
.sc-board__menu > p {
|
|
2831
|
+
margin: 0;
|
|
2832
|
+
padding: 4px 8px 6px;
|
|
2833
|
+
color: var(--_subtle);
|
|
2834
|
+
font-size: var(--_font-size-xs);
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2286
2837
|
/* A note: its tone's mark and the words on a wash of it, edged by it. */
|
|
2287
2838
|
.sc-note {
|
|
2288
2839
|
--_tone: var(--_accent);
|
|
@@ -5211,6 +5762,23 @@ button.sc-attachment__main:focus-visible {
|
|
|
5211
5762
|
color: var(--_fg);
|
|
5212
5763
|
}
|
|
5213
5764
|
|
|
5765
|
+
/* A host's block this page doesn't draw: its words in a quiet hairline box where it would be. */
|
|
5766
|
+
.sc-surface__host {
|
|
5767
|
+
padding: 12px 14px;
|
|
5768
|
+
border: 1px solid var(--_line);
|
|
5769
|
+
border-radius: var(--_inner);
|
|
5770
|
+
background: var(--_surface);
|
|
5771
|
+
color: var(--_muted);
|
|
5772
|
+
}
|
|
5773
|
+
|
|
5774
|
+
.sc-surface__host > :first-child {
|
|
5775
|
+
margin-top: 0;
|
|
5776
|
+
}
|
|
5777
|
+
|
|
5778
|
+
.sc-surface__host > :last-child {
|
|
5779
|
+
margin-bottom: 0;
|
|
5780
|
+
}
|
|
5781
|
+
|
|
5214
5782
|
/* An automation that is not there any more: a quiet line in a dashed box where it would be. */
|
|
5215
5783
|
.sc-automation--gone {
|
|
5216
5784
|
margin: 0;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { XIcon } from "@phosphor-icons/react";
|
|
2
|
+
import { useEffect, useRef, type KeyboardEvent, type ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
import { classes } from "../classes";
|
|
5
|
+
import { Button } from "../kit/Button";
|
|
6
|
+
|
|
7
|
+
/** The parts of a surface shown apart from the conversation, by the class each carries. */
|
|
8
|
+
export type PlacedPart =
|
|
9
|
+
| "sc-placed"
|
|
10
|
+
| "sc-placed--panel"
|
|
11
|
+
| "sc-placed--modal"
|
|
12
|
+
| "sc-placed__head"
|
|
13
|
+
| "sc-placed__title"
|
|
14
|
+
| "sc-placed__body";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A surface the agent put apart from the conversation, tied to it all the same: in a `panel` that
|
|
18
|
+
* stands beside the conversation (over it where there is no room), or in a `modal` over the page,
|
|
19
|
+
* whose backdrop, Escape or cross close it. Its title heads it; closed, the conversation's line
|
|
20
|
+
* opens it again.
|
|
21
|
+
*/
|
|
22
|
+
export function Placed({
|
|
23
|
+
where,
|
|
24
|
+
title,
|
|
25
|
+
closeLabel,
|
|
26
|
+
onClose,
|
|
27
|
+
classNames,
|
|
28
|
+
children,
|
|
29
|
+
}: {
|
|
30
|
+
where: "panel" | "modal";
|
|
31
|
+
title: string;
|
|
32
|
+
closeLabel: string;
|
|
33
|
+
onClose: () => void;
|
|
34
|
+
classNames: Partial<Record<PlacedPart, string>> | undefined;
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
}) {
|
|
37
|
+
const dialog = useRef<HTMLDialogElement>(null);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const opened = dialog.current;
|
|
40
|
+
if (opened === null) return undefined;
|
|
41
|
+
// jsdom has no top layer: a dialog there is only shown.
|
|
42
|
+
if (typeof opened.showModal === "function") opened.showModal();
|
|
43
|
+
else opened.setAttribute("open", "");
|
|
44
|
+
return () => {
|
|
45
|
+
if (typeof opened.close === "function") opened.close();
|
|
46
|
+
};
|
|
47
|
+
}, []);
|
|
48
|
+
const head = (
|
|
49
|
+
<header className={classes(classNames, "sc-placed__head")}>
|
|
50
|
+
<h2 className={classes(classNames, "sc-placed__title")}>{title}</h2>
|
|
51
|
+
<Button
|
|
52
|
+
tone="ghost"
|
|
53
|
+
size="sm"
|
|
54
|
+
icon={XIcon}
|
|
55
|
+
aria-label={closeLabel}
|
|
56
|
+
title={closeLabel}
|
|
57
|
+
onClick={onClose}
|
|
58
|
+
/>
|
|
59
|
+
</header>
|
|
60
|
+
);
|
|
61
|
+
// Escape closes this, not the reply the conversation is writing.
|
|
62
|
+
const onKeyDown = (event: KeyboardEvent) => {
|
|
63
|
+
if (event.key !== "Escape") return;
|
|
64
|
+
event.stopPropagation();
|
|
65
|
+
if (where === "panel") onClose();
|
|
66
|
+
};
|
|
67
|
+
const body = <div className={classes(classNames, "sc-placed__body")}>{children}</div>;
|
|
68
|
+
if (where === "panel") {
|
|
69
|
+
return (
|
|
70
|
+
<aside
|
|
71
|
+
part="placed panel"
|
|
72
|
+
aria-label={title}
|
|
73
|
+
onKeyDown={onKeyDown}
|
|
74
|
+
className={classes(classNames, "sc-placed", "sc-placed--panel")}
|
|
75
|
+
>
|
|
76
|
+
{head}
|
|
77
|
+
{body}
|
|
78
|
+
</aside>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return (
|
|
82
|
+
<dialog
|
|
83
|
+
ref={dialog}
|
|
84
|
+
part="placed modal"
|
|
85
|
+
aria-label={title}
|
|
86
|
+
onKeyDown={onKeyDown}
|
|
87
|
+
onClose={onClose}
|
|
88
|
+
// A press on the backdrop (the dialog itself, outside its box) closes it.
|
|
89
|
+
onClick={(event) => {
|
|
90
|
+
if (event.target === event.currentTarget) onClose();
|
|
91
|
+
}}
|
|
92
|
+
className={`sc ${classes(classNames, "sc-placed", "sc-placed--modal")}`}
|
|
93
|
+
>
|
|
94
|
+
{head}
|
|
95
|
+
{body}
|
|
96
|
+
</dialog>
|
|
97
|
+
);
|
|
98
|
+
}
|