@aseity/idocs-preview 0.4.0 → 0.5.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/view/ime.js CHANGED
@@ -98,7 +98,7 @@ export function createImeBridge(host) {
98
98
  textarea.style.left = `${left}px`;
99
99
  textarea.style.top = `${top}px`;
100
100
  textarea.style.height = `${height}px`;
101
- textarea.style.fontSize = `${Math.max(10, Math.round(height * 0.8))}px`;
101
+ textarea.style.fontSize = `${(caret.style?.size ?? caret.height) * scale}px`;
102
102
  };
103
103
  const onFocus = () => {
104
104
  focused = true;
@@ -153,10 +153,10 @@ export function createImeBridge(host) {
153
153
  const data = event.data;
154
154
  void enqueue(() => host.replaceSelection(data));
155
155
  }
156
- else if (event.inputType === 'insertParagraph') {
156
+ else if (event.inputType === 'insertLineBreak' || event.inputType === 'insertParagraph') {
157
157
  event.preventDefault();
158
158
  textarea.value = '';
159
- void enqueue(() => host.splitBlock());
159
+ void enqueue(event.inputType === 'insertLineBreak' ? () => host.replaceSelection('\n') : () => host.splitBlock());
160
160
  }
161
161
  };
162
162
  const onInput = (event) => {
@@ -279,9 +279,9 @@ export function createImeBridge(host) {
279
279
  void enqueue(() => host.deleteForward());
280
280
  return;
281
281
  }
282
- if (key === 'Enter' && !event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey) {
282
+ if (key === 'Enter' && !event.ctrlKey && !event.metaKey && !event.altKey) {
283
283
  event.preventDefault();
284
- void enqueue(() => host.splitBlock());
284
+ void enqueue(event.shiftKey ? () => host.replaceSelection('\n') : () => host.splitBlock());
285
285
  return;
286
286
  }
287
287
  if (key === 'ArrowLeft' || key === 'ArrowRight') {
@@ -28,4 +28,4 @@ export type { FindBar } from './find-bar.js';
28
28
  export * from './edit-selection.js';
29
29
  export * from './editor.js';
30
30
  export type { InputMode } from './ime.js';
31
- export { type EditorWorkspace, type EditorWorkspaceOptions, formatAskAssistantLabel, mountEditorWorkspace, type PickedImage, } from './workspace.js';
31
+ export { type EditorWorkspace, type EditorWorkspaceOptions, formatAskAssistantLabel, type InsertDockButton, mountEditorWorkspace, type PickedImage, } from './workspace.js';
@@ -50,6 +50,7 @@ const WORKSPACE_CSS = `
50
50
  --ws-danger: #b91c1c;
51
51
  --ws-menu-shadow: var(--idocs-menu-shadow, 0 8px 28px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.06), 0 0 0 0.5px rgba(0, 0, 0, 0.1));
52
52
  --ws-dock-shadow: var(--idocs-dock-shadow, 0 3px 6px rgba(0, 0, 0, 0.03), 0 4px 80px 8px rgba(0, 0, 0, 0.03), 0 0 1px rgba(0, 0, 0, 0.22));
53
+ --ws-toolbar-inset: 12px;
53
54
  color-scheme: light;
54
55
 
55
56
  display: flex;
@@ -107,6 +108,7 @@ ${DARK_TOKENS}
107
108
  }
108
109
 
109
110
  .idocs-ws-toolbar {
111
+ position: relative;
110
112
  min-height: 52px;
111
113
  height: 52px;
112
114
  flex-shrink: 0;
@@ -114,7 +116,7 @@ ${DARK_TOKENS}
114
116
  align-items: center;
115
117
  justify-content: space-between;
116
118
  gap: 8px;
117
- padding: 0 12px;
119
+ padding: 0 var(--ws-toolbar-inset);
118
120
  background: var(--ws-toolbar-bg);
119
121
  border-bottom: 1px solid var(--ws-border);
120
122
  user-select: none;
@@ -130,25 +132,58 @@ ${DARK_TOKENS}
130
132
  }
131
133
 
132
134
  .idocs-ws-tb-left {
135
+ flex-shrink: 0;
133
136
  gap: 6px;
134
137
  }
135
138
 
136
139
  .idocs-ws-tb-right {
140
+ flex-shrink: 0;
137
141
  gap: 2px;
138
142
  }
139
143
 
140
144
  .idocs-ws-tb-center {
141
145
  flex: 1;
142
- justify-content: center;
143
- overflow: visible;
144
146
  }
145
147
 
148
+ .idocs-ws-toolbar-viewport {
149
+ display: flex;
150
+ flex: 1;
151
+ min-width: 0;
152
+ overflow-x: auto;
153
+ overscroll-behavior-x: contain;
154
+ scrollbar-width: none;
155
+ }
156
+
157
+ .idocs-ws-toolbar-strip {
158
+ display: flex;
159
+ align-items: center;
160
+ flex-shrink: 0;
161
+ gap: 8px;
162
+ margin-inline: auto;
163
+ }
164
+
165
+ .idocs-ws-toolbar-content,
146
166
  .idocs-ws-ctx {
147
- display: inline-flex;
167
+ display: flex;
168
+ flex-shrink: 0;
148
169
  align-items: center;
149
170
  gap: 4px;
150
- max-width: 100%;
151
- flex-wrap: nowrap;
171
+ }
172
+
173
+ .idocs-ws-toolbar-content {
174
+ padding: 4px 3px;
175
+ }
176
+
177
+ .idocs-ws-tb-center > .idocs-ws-toolbar-arrow {
178
+ width: 24px;
179
+ }
180
+
181
+ .idocs-ws-toolbar-arrow:first-child svg {
182
+ transform: rotate(90deg);
183
+ }
184
+
185
+ .idocs-ws-toolbar-arrow:last-child svg {
186
+ transform: rotate(-90deg);
152
187
  }
153
188
 
154
189
  .idocs-ws-icon-btn {
@@ -218,6 +253,16 @@ ${DARK_TOKENS}
218
253
  background: rgba(255, 59, 48, 0.1);
219
254
  }
220
255
 
256
+ .idocs-ws-ctx.is-table .idocs-ws-pill-btn,
257
+ .idocs-ws-ctx.is-readonly-target .idocs-ws-pill-btn {
258
+ font-weight: 400;
259
+ }
260
+
261
+ .idocs-ws-ctx.is-readonly-target .idocs-ws-pill-btn > svg {
262
+ flex-shrink: 0;
263
+ transform: translateY(-1px);
264
+ }
265
+
221
266
  .idocs-ws-select-trigger {
222
267
  height: 28px;
223
268
  min-width: 88px;
@@ -279,7 +324,7 @@ ${DARK_TOKENS}
279
324
  background: transparent;
280
325
  color: var(--ws-ink-2);
281
326
  font-size: 12px;
282
- font-weight: 500;
327
+ font-weight: 400;
283
328
  }
284
329
 
285
330
  .idocs-ws-seg-btn[aria-pressed='true'] {
@@ -306,15 +351,7 @@ ${DARK_TOKENS}
306
351
  background: var(--ws-warn-bg);
307
352
  border: 1px solid var(--ws-warn-border);
308
353
  color: var(--ws-warn-ink);
309
- }
310
-
311
- .idocs-ws-note {
312
- font-size: 12px;
313
- color: var(--ws-muted);
314
- white-space: nowrap;
315
- overflow: hidden;
316
- text-overflow: ellipsis;
317
- max-width: 280px;
354
+ font-weight: 400;
318
355
  }
319
356
 
320
357
  .idocs-ws-zoom-label {
@@ -384,7 +421,7 @@ ${DARK_TOKENS}
384
421
  }
385
422
 
386
423
  .idocs-ws-body {
387
- --ws-rail-width: 208px;
424
+ --ws-rail-width: 184px;
388
425
  --ws-rail-ease: cubic-bezier(0.22, 1, 0.36, 1);
389
426
  --ws-rail-duration: 220ms;
390
427
  flex: 1;
@@ -451,7 +488,7 @@ ${DARK_TOKENS}
451
488
  .idocs-ws-rail-tabs {
452
489
  display: flex;
453
490
  gap: 2px;
454
- margin: 10px 12px 6px;
491
+ margin: 10px var(--ws-toolbar-inset) 6px;
455
492
  padding: 2px;
456
493
  border-radius: 8px;
457
494
  background: var(--ws-muted-fill);
@@ -494,10 +531,10 @@ ${DARK_TOKENS}
494
531
  min-height: 0;
495
532
  overflow-y: auto;
496
533
  scrollbar-gutter: stable;
497
- padding: 8px 16px 20px;
534
+ padding: 8px var(--ws-toolbar-inset) 20px;
498
535
  display: flex;
499
536
  flex-direction: column;
500
- gap: 14px;
537
+ gap: 4px;
501
538
  }
502
539
 
503
540
  .idocs-ws-rail-list.is-outline {
@@ -506,18 +543,29 @@ ${DARK_TOKENS}
506
543
  }
507
544
 
508
545
  .idocs-ws-thumb-card {
509
- position: relative;
510
546
  width: 100%;
511
547
  flex-shrink: 0;
512
548
  margin: 0;
513
- padding: 0;
549
+ padding: 8px;
514
550
  border: 0;
515
- border-radius: 6px;
551
+ border-radius: 16px;
516
552
  background: transparent;
517
- display: flex;
518
- flex-direction: column;
519
- align-items: center;
520
- gap: 6px;
553
+ display: grid;
554
+ grid-template-columns: minmax(20px, max-content) minmax(0, 1fr);
555
+ align-items: start;
556
+ gap: 8px;
557
+ }
558
+
559
+ .idocs-ws-thumb-card:hover {
560
+ background: var(--ws-hover);
561
+ }
562
+
563
+ .idocs-ws-thumb-card.is-active {
564
+ background: color-mix(in srgb, var(--ws-accent-soft) 40%, var(--ws-hover));
565
+ }
566
+
567
+ .idocs-ws .idocs-ws-thumb-card:focus-visible {
568
+ outline-offset: -2px;
521
569
  }
522
570
 
523
571
  .idocs-ws-thumb-sheet {
@@ -525,28 +573,19 @@ ${DARK_TOKENS}
525
573
  display: block;
526
574
  width: 100%;
527
575
  overflow: hidden;
528
- border-radius: 5px;
576
+ border-radius: 8px;
529
577
  background: #ffffff;
530
- transition: box-shadow 160ms ease;
531
578
  }
532
579
 
533
580
  .idocs-ws-thumb-sheet::after {
534
581
  content: "";
535
582
  position: absolute;
536
583
  inset: 0;
584
+ border: 1px solid rgba(15, 23, 42, 0.11);
537
585
  border-radius: inherit;
538
- box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.11);
539
586
  pointer-events: none;
540
587
  }
541
588
 
542
- .idocs-ws-thumb-card:hover .idocs-ws-thumb-sheet {
543
- box-shadow: 0 3px 10px rgba(15, 23, 42, 0.12);
544
- }
545
-
546
- .idocs-ws-thumb-card.is-active .idocs-ws-thumb-sheet::after {
547
- box-shadow: inset 0 0 0 2px var(--ws-accent);
548
- }
549
-
550
589
  .idocs-ws-thumb-canvas {
551
590
  display: block;
552
591
  width: 100%;
@@ -554,15 +593,16 @@ ${DARK_TOKENS}
554
593
  }
555
594
 
556
595
  .idocs-ws-thumb-label {
557
- font-size: 11px;
558
- line-height: 1;
596
+ padding-top: 2px;
597
+ font-size: 12px;
598
+ line-height: 16px;
599
+ text-align: right;
559
600
  font-variant-numeric: tabular-nums;
560
- color: var(--ws-muted);
601
+ color: var(--ws-ink-2);
561
602
  }
562
603
 
563
604
  .idocs-ws-thumb-card.is-active .idocs-ws-thumb-label {
564
605
  color: var(--ws-accent);
565
- font-weight: 600;
566
606
  }
567
607
 
568
608
  .idocs-ws-outline-item {
@@ -680,7 +720,8 @@ ${DARK_TOKENS}
680
720
  z-index: 20;
681
721
  display: inline-flex;
682
722
  align-items: center;
683
- gap: 2px;
723
+ width: max-content;
724
+ gap: 4px;
684
725
  padding: 5px;
685
726
  border: 0;
686
727
  border-radius: 15px;
@@ -690,27 +731,46 @@ ${DARK_TOKENS}
690
731
  }
691
732
 
692
733
  .idocs-ws-dock-btn {
734
+ width: 34px;
693
735
  height: 34px;
694
- padding: 0 11px;
736
+ padding: 0;
695
737
  border: 0;
696
738
  border-radius: 10px;
697
739
  background: transparent;
698
740
  color: var(--ws-ink-2);
699
- font-size: 12.5px;
700
- font-weight: 500;
701
- display: inline-flex;
702
- align-items: center;
703
- gap: 6px;
704
- white-space: nowrap;
741
+ display: grid;
742
+ place-items: center;
705
743
  transition: background 140ms ease, color 140ms ease;
706
744
  }
707
745
 
746
+ .idocs-ws-dock-btn > svg {
747
+ width: 20px;
748
+ height: 20px;
749
+ fill: none;
750
+ stroke: currentColor;
751
+ stroke-width: 1.33;
752
+ stroke-linecap: round;
753
+ stroke-linejoin: round;
754
+ }
755
+
708
756
  .idocs-ws-dock-btn:hover,
757
+ .idocs-ws-dock-btn:focus-visible,
709
758
  .idocs-ws-dock-btn[aria-expanded='true'] {
710
759
  background: var(--ws-hover);
711
760
  color: var(--ws-ink);
712
761
  }
713
762
 
763
+ @media (pointer: coarse) {
764
+ .idocs-ws-dock {
765
+ bottom: 10px;
766
+ }
767
+
768
+ .idocs-ws-dock-btn {
769
+ width: 44px;
770
+ height: 44px;
771
+ }
772
+ }
773
+
714
774
  .idocs-ws-popover-anchor {
715
775
  position: relative;
716
776
  display: inline-flex;
@@ -1,10 +1,17 @@
1
- import type { Anchor, BlockStyle, EditorSession, PreviewDocument, TextAlign } from '../core/index.js';
1
+ import type { Anchor, BlockStyle, CalloutColors, EditorSession, PreviewDocument, TextAlign } from '../core/index.js';
2
2
  import type { ReadOnlyTarget } from './edit-selection.js';
3
3
  import { type EditorView, type EditorViewOptions, type EditorViewSelection, type SelectedImageTarget } from './editor.js';
4
4
  export interface PickedImage {
5
5
  readonly src: string;
6
6
  readonly alt?: string;
7
7
  }
8
+ export interface InsertDockButton {
9
+ readonly container: HTMLElement;
10
+ readonly label: string;
11
+ readonly className: string;
12
+ activate(): void;
13
+ bind(button: HTMLButtonElement | null): void;
14
+ }
8
15
  export interface EditorWorkspaceOptions {
9
16
  readonly view?: EditorViewOptions;
10
17
  readonly readOnly?: boolean;
@@ -12,12 +19,14 @@ export interface EditorWorkspaceOptions {
12
19
  readonly busyLabel?: string;
13
20
  readonly railOpen?: boolean;
14
21
  readonly assistantName?: string;
22
+ readonly calloutColors?: CalloutColors;
15
23
  readonly onPickImage?: () => Promise<PickedImage | null>;
16
24
  readonly onQuoteSelection?: (selection: {
17
25
  text: string;
18
26
  path: string;
19
27
  page: number;
20
28
  }) => void;
29
+ readonly mountInsertButtons?: (buttons: readonly InsertDockButton[]) => () => void;
21
30
  }
22
31
  export interface EditorWorkspace {
23
32
  readonly view: EditorView;
@@ -41,8 +50,6 @@ export type ToolbarContext = {
41
50
  } | {
42
51
  readonly kind: 'readOnlyTarget';
43
52
  readonly target: ReadOnlyTarget;
44
- readonly badge: string;
45
- readonly message: string;
46
53
  } | {
47
54
  readonly kind: 'image';
48
55
  readonly target: SelectedImageTarget;