winui-svelte 0.0.2 → 0.0.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.
Files changed (108) hide show
  1. package/API.md +120 -6
  2. package/README.md +70 -90
  3. package/dist/bindings/.dynwinrt-managed +1 -1
  4. package/dist/components/convert.d.ts +3 -3
  5. package/dist/components/convert.d.ts.map +1 -1
  6. package/dist/components/fluent-glyph.d.ts +4 -0
  7. package/dist/components/fluent-glyph.d.ts.map +1 -1
  8. package/dist/components/generated/controls/FontIcon.svelte.d.ts +1 -1
  9. package/dist/components/generated/controls/FontIconSource.svelte.d.ts +1 -1
  10. package/dist/components/generated/controls/UIElement.svelte.d.ts +1 -1
  11. package/dist/components/index.d.ts +4 -2
  12. package/dist/components/index.d.ts.map +1 -1
  13. package/dist/components/index.js.map +1 -1
  14. package/dist/css/runtime/resources.d.ts +1 -1
  15. package/dist/dev/dev-window.d.ts +23 -0
  16. package/dist/dev/dev-window.d.ts.map +1 -0
  17. package/dist/dev/dev-window.js +42 -0
  18. package/dist/dev/dev-window.js.map +1 -0
  19. package/dist/dev/index.d.ts +3 -0
  20. package/dist/dev/index.d.ts.map +1 -0
  21. package/dist/dev/index.js +2 -0
  22. package/dist/dev/index.js.map +1 -0
  23. package/dist/dev/start-dev.d.ts +47 -0
  24. package/dist/dev/start-dev.d.ts.map +1 -0
  25. package/dist/dev/start-dev.js +81 -0
  26. package/dist/dev/start-dev.js.map +1 -0
  27. package/dist/enums.d.ts +2 -0
  28. package/dist/enums.d.ts.map +1 -1
  29. package/dist/enums.js +2 -0
  30. package/dist/enums.js.map +1 -1
  31. package/dist/media/media-player.d.ts +8 -0
  32. package/dist/media/media-player.d.ts.map +1 -1
  33. package/dist/media/media-player.js +15 -0
  34. package/dist/media/media-player.js.map +1 -1
  35. package/dist/web-apis/window-geometry.d.ts +39 -0
  36. package/dist/web-apis/window-geometry.d.ts.map +1 -0
  37. package/dist/web-apis/window-geometry.js +95 -0
  38. package/dist/web-apis/window-geometry.js.map +1 -0
  39. package/dist/win2d/Canvas.svelte +1 -0
  40. package/dist/window/anchor.d.ts +92 -0
  41. package/dist/window/anchor.d.ts.map +1 -0
  42. package/dist/window/anchor.js +100 -0
  43. package/dist/window/anchor.js.map +1 -0
  44. package/dist/window/backdrop.d.ts +4 -1
  45. package/dist/window/backdrop.d.ts.map +1 -1
  46. package/dist/window/backdrop.js +10 -2
  47. package/dist/window/backdrop.js.map +1 -1
  48. package/dist/window/create-window.d.ts +1 -1
  49. package/dist/window/create-window.d.ts.map +1 -1
  50. package/dist/window/create-window.js +3 -1
  51. package/dist/window/create-window.js.map +1 -1
  52. package/dist/window/css-pixels.d.ts +14 -0
  53. package/dist/window/css-pixels.d.ts.map +1 -0
  54. package/dist/window/css-pixels.js +12 -0
  55. package/dist/window/css-pixels.js.map +1 -0
  56. package/dist/window/dock.d.ts +51 -0
  57. package/dist/window/dock.d.ts.map +1 -0
  58. package/dist/window/dock.js +69 -0
  59. package/dist/window/dock.js.map +1 -0
  60. package/dist/window/index.d.ts +4 -0
  61. package/dist/window/index.d.ts.map +1 -1
  62. package/dist/window/index.js +2 -0
  63. package/dist/window/index.js.map +1 -1
  64. package/dist/window/native.d.ts +2 -0
  65. package/dist/window/native.d.ts.map +1 -1
  66. package/dist/window/native.js +10 -0
  67. package/dist/window/native.js.map +1 -1
  68. package/dist/window/transparent-backdrop.d.ts +11 -0
  69. package/dist/window/transparent-backdrop.d.ts.map +1 -0
  70. package/dist/window/transparent-backdrop.js +35 -0
  71. package/dist/window/transparent-backdrop.js.map +1 -0
  72. package/dist/window/window-handle.d.ts +17 -0
  73. package/dist/window/window-handle.d.ts.map +1 -1
  74. package/dist/window/window-handle.js +23 -0
  75. package/dist/window/window-handle.js.map +1 -1
  76. package/dist/window/window-host.svelte.d.ts +17 -12
  77. package/dist/window/window-host.svelte.d.ts.map +1 -1
  78. package/dist/window/window-host.svelte.js +208 -23
  79. package/dist/window/window-host.svelte.js.map +1 -1
  80. package/dist/winui.d.ts +5 -0
  81. package/dist/winui.d.ts.map +1 -1
  82. package/dist/winui.js +5 -0
  83. package/dist/winui.js.map +1 -1
  84. package/package.json +25 -7
  85. package/src/components/convert.ts +3 -3
  86. package/src/components/fluent-glyph.ts +6 -0
  87. package/src/components/generated/controls/FontIcon.svelte.ts +1 -1
  88. package/src/components/generated/controls/FontIconSource.svelte.ts +1 -1
  89. package/src/components/generated/controls/UIElement.svelte.ts +1 -1
  90. package/src/components/index.ts +13 -2
  91. package/src/dev/dev-window.ts +63 -0
  92. package/src/dev/index.ts +2 -0
  93. package/src/dev/start-dev.ts +120 -0
  94. package/src/enums.ts +2 -0
  95. package/src/media/media-player.ts +17 -0
  96. package/src/web-apis/window-geometry.ts +106 -0
  97. package/src/window/anchor.ts +156 -0
  98. package/src/window/backdrop.ts +11 -2
  99. package/src/window/create-window.ts +5 -1
  100. package/src/window/css-pixels.ts +18 -0
  101. package/src/window/dock.ts +99 -0
  102. package/src/window/index.ts +4 -0
  103. package/src/window/native.ts +12 -0
  104. package/src/window/transparent-backdrop.ts +38 -0
  105. package/src/window/window-handle.ts +26 -0
  106. package/src/window/window-host.svelte.ts +256 -36
  107. package/src/winui.ts +5 -0
  108. package/web-types.json +3203 -1507
@@ -1,3 +1,5 @@
1
+ import type { SizeToContent, WindowAnchor, WindowBounds, WindowSize } from "./anchor.ts";
2
+ import { fittedBounds, SizeToContent as SizeToContentKind, WindowAnchor as WindowAnchorKind } from "./anchor.ts";
1
3
  import {
2
4
  applyCaptionButtonColors,
3
5
  applyPresentation,
@@ -13,6 +15,7 @@ import { isBackgroundRun } from "./background-mode.ts";
13
15
  import { backgroundPlacement, keepInBackground } from "./background.ts";
14
16
  import type { CaptionButtonColors, CaptionButtonProperty, TitleBarHeight, WindowRegion } from "./chrome.ts";
15
17
  import { TitleBarHeight as TitleBarHeightKind, WindowPresentation, WindowTheme } from "./chrome.ts";
18
+ import { toDevicePixels } from "./css-pixels.ts";
16
19
  import {
17
20
  clearWindowClip,
18
21
  clipToRoundedRectangle,
@@ -28,22 +31,20 @@ import type { FrameworkElement } from "#src/winui.js";
28
31
  import {
29
32
  DisplayArea,
30
33
  DisplayAreaFallback,
34
+ Grid,
31
35
  NonClientRegionKind,
36
+ ScrollBarVisibility,
37
+ ScrollMode,
38
+ ScrollViewer,
32
39
  Window,
33
40
  WindowActivationState
34
41
  } from "#src/winui.js";
35
42
 
43
+ export type { WindowBounds, WindowSize } from "./anchor.ts";
44
+
36
45
  // What <Window> (components/hand-written/Window.svelte) does: a native window
37
46
  // around the component's content, kept in line with its props.
38
47
 
39
- /** The window's position and size, in device pixels, as AppWindow has them. */
40
- export interface WindowBounds {
41
- x: number;
42
- y: number;
43
- width: number;
44
- height: number;
45
- }
46
-
47
48
  /**
48
49
  * Where the window opens, in device pixels; a size left out is the width or
49
50
  * height prop's.
@@ -110,6 +111,23 @@ export interface WindowProps {
110
111
  width?: number;
111
112
  height?: number;
112
113
 
114
+ /**
115
+ * Which sides of the window follow its content: the content is measured
116
+ * after every layout pass and the window is resized to it (frame included,
117
+ * within the size limits) with one `AppWindow.MoveAndResize`, so a growing
118
+ * content never flickers. A side that follows the content ignores the
119
+ * `width` or `height` prop and the user's resizing. Windowed presentation
120
+ * only; the default is `none`.
121
+ */
122
+ sizeToContent?: SizeToContent | undefined;
123
+
124
+ /**
125
+ * The corner that stays where it is when the window is sized to its content
126
+ * (and when the scale changes the size): a window docked bottom-right whose
127
+ * content grows taller grows upward. The default is `topLeft`.
128
+ */
129
+ anchor?: WindowAnchor | undefined;
130
+
113
131
  /** The least the user can resize to, in device-independent pixels. */
114
132
  minWidth?: number;
115
133
  minHeight?: number;
@@ -228,12 +246,6 @@ export interface WindowProps {
228
246
  onboundschanged?: (bounds: WindowBounds) => void;
229
247
  }
230
248
 
231
- /** A size in device pixels. */
232
- export interface WindowSize {
233
- width: number;
234
- height: number;
235
- }
236
-
237
249
  /** What `attachWindow` opens a window around, and how. */
238
250
  export interface AttachOptions {
239
251
  content: FrameworkElement;
@@ -244,11 +256,40 @@ export interface AttachOptions {
244
256
  size?: WindowSize | undefined;
245
257
  }
246
258
 
247
- function round({ value, scale }: {
248
- value: number;
259
+ // A side of the window in device pixels: the prop's, unless the prop is left
260
+ // out or the content sets that side.
261
+ function sideOf({ value, current, isFitted, scale }: {
262
+ value: number | undefined;
263
+ current: number;
264
+ isFitted: boolean;
249
265
  scale: number;
250
266
  }) {
251
- return Math.round(value * scale);
267
+ const isKept = value === undefined || isFitted;
268
+ if (isKept) {
269
+ return current;
270
+ }
271
+
272
+ return toDevicePixels({
273
+ value,
274
+ scale
275
+ });
276
+ }
277
+
278
+ // A size limit in device pixels; `fallback` when the app names none.
279
+ function limitOf({ value, fallback, scale }: {
280
+ value: number | undefined;
281
+ fallback: number;
282
+ scale: number;
283
+ }) {
284
+ const isNamed = value !== undefined;
285
+ if (!isNamed) {
286
+ return fallback;
287
+ }
288
+
289
+ return toDevicePixels({
290
+ value,
291
+ scale
292
+ });
252
293
  }
253
294
 
254
295
  // A prop the app left out is undefined; a guard names the test.
@@ -256,6 +297,11 @@ function isGiven<Value>(value: Value | undefined): value is Value {
256
297
  return value !== undefined;
257
298
  }
258
299
 
300
+ // Windows whose component is gone while the application goes on, waiting one
301
+ // tick for the component that replaces it (a hot update re-creates it) to take
302
+ // the same window over; a window nobody takes is closed.
303
+ const orphans: Window[] = [];
304
+
259
305
  class WindowHost {
260
306
  readonly handle: WindowHandle;
261
307
  private readonly props: WindowProps;
@@ -276,13 +322,16 @@ class WindowHost {
276
322
  private isClipApplied = false;
277
323
  private isTopApplied = false;
278
324
  private hasShown = false;
325
+ private isFitting = false;
326
+ private scroller: ScrollViewer | null = null;
327
+ private readonly isTakenOver: boolean;
279
328
  private readonly openSize: WindowSize | undefined;
280
329
  private appliedSize: {
281
330
  width: number | undefined;
282
331
  height: number | undefined;
283
332
  };
284
333
 
285
- constructor({ content, props, titleBar, size }: AttachOptions) {
334
+ constructor({ content, props, titleBar, size }: AttachOptions, orphan: Window | undefined) {
286
335
  this.props = props;
287
336
  this.openSize = size;
288
337
  this.content = content;
@@ -297,15 +346,18 @@ class WindowHost {
297
346
  joinAppUserModel(appUserModelId);
298
347
  }
299
348
 
300
- const window = new Window();
349
+ const window = orphan ?? new Window();
350
+ this.isTakenOver = orphan !== undefined;
301
351
  this.handle = new WindowHandle(window);
302
352
 
303
- if (isBackgroundRun()) {
353
+ const isNewBackgroundWindow = isBackgroundRun() && !this.isTakenOver;
354
+ if (isNewBackgroundWindow) {
304
355
  keepInBackground(this.handle.appWindow.id.value);
305
356
  }
306
357
 
307
358
  this.handle.guardClose(() => this.isCloseRefused());
308
359
  window.content = content;
360
+ this.keepInLine(() => this.syncContainer());
309
361
  this.keepInLine(() => this.syncText());
310
362
  this.keepInLine(() => this.syncBackdrop());
311
363
  this.keepInLine(() => this.syncTheme());
@@ -316,8 +368,13 @@ class WindowHost {
316
368
  this.keepInLine(() => this.syncLimits());
317
369
  this.keepInLine(() => this.syncFrame());
318
370
  this.keepInLine(() => this.syncShape());
319
- this.placeFirst();
371
+
372
+ if (!this.isTakenOver) {
373
+ this.placeFirst();
374
+ }
375
+
320
376
  $effect(() => this.syncSize());
377
+ $effect(() => this.fitToContent());
321
378
  this.syncOwner();
322
379
  this.listen();
323
380
  this.watchScale();
@@ -325,7 +382,14 @@ class WindowHost {
325
382
  $effect(() => this.syncVisibility());
326
383
  }
327
384
 
328
- dispose() {
385
+ /**
386
+ * Ends the host. `isClosedLater`: its component is going while the
387
+ * application goes on (a hot update re-creates it). The window is not closed
388
+ * but offered for one tick to the component that replaces it, which takes it
389
+ * over (no relaunch), and closed if nobody does. Closing it during the
390
+ * component's teardown is no option: WinUI aborts Window.Close (E_ABORT).
391
+ */
392
+ dispose(isClosedLater: boolean) {
329
393
  this.releaseBackdrop?.();
330
394
  this.releaseBackdrop = null;
331
395
  for (const unsubscribe of this.unsubscribe.splice(0)) {
@@ -333,9 +397,26 @@ class WindowHost {
333
397
  }
334
398
 
335
399
  this.handle.guardClose(() => false);
400
+
401
+ if (isClosedLater) {
402
+ const { window } = this.handle;
403
+ orphans.push(window);
404
+ setTimeout(() => this.closeIfOrphan(window), 0);
405
+ return;
406
+ }
407
+
336
408
  this.handle.close();
337
409
  }
338
410
 
411
+ private closeIfOrphan(window: Window) {
412
+ const index = orphans.indexOf(window);
413
+ const isOrphan = index !== -1;
414
+ if (isOrphan) {
415
+ orphans.splice(index, 1);
416
+ this.handle.close();
417
+ }
418
+ }
419
+
339
420
  // Applied now, so the window opens as it is meant to, and again whenever
340
421
  // what `sync` reads changes.
341
422
  private keepInLine(sync: () => void) {
@@ -343,6 +424,51 @@ class WindowHost {
343
424
  $effect(sync);
344
425
  }
345
426
 
427
+ // A measure offers an element the space it has and clamps what it asks for
428
+ // to that, so a root as large as the window could never ask for more or
429
+ // less than the window is. Inside a ScrollViewer that may scroll along a
430
+ // side the content sets, the root is offered all the room there (the
431
+ // scroll bars stay hidden), and what it asks for is what it needs.
432
+ private syncContainer() {
433
+ const { isWidthFitted, isHeightFitted } = this.fittedSides;
434
+ const isAnySideFitted = isWidthFitted || isHeightFitted;
435
+ const isFitted = isAnySideFitted && this.isWindowed;
436
+ const { window } = this.handle;
437
+ if (!isFitted) {
438
+ this.uncontain();
439
+ return;
440
+ }
441
+
442
+ const scroller = this.scroller ?? new ScrollViewer();
443
+ scroller.horizontalScrollBarVisibility = isWidthFitted ? ScrollBarVisibility.Hidden : ScrollBarVisibility.Disabled;
444
+ scroller.horizontalScrollMode = isWidthFitted ? ScrollMode.Enabled : ScrollMode.Disabled;
445
+ scroller.verticalScrollBarVisibility = isHeightFitted ? ScrollBarVisibility.Hidden : ScrollBarVisibility.Disabled;
446
+ scroller.verticalScrollMode = isHeightFitted ? ScrollMode.Enabled : ScrollMode.Disabled;
447
+ const isContained = this.scroller !== null;
448
+ if (isContained) {
449
+ return;
450
+ }
451
+
452
+ window.content = new Grid();
453
+ scroller.content = this.content;
454
+ window.content = scroller;
455
+ this.scroller = scroller;
456
+ }
457
+
458
+ private uncontain() {
459
+ const { scroller } = this;
460
+ const isContained = scroller !== null;
461
+ if (!isContained) {
462
+ return;
463
+ }
464
+
465
+ const { window } = this.handle;
466
+ window.content = new Grid();
467
+ scroller.content = null;
468
+ window.content = this.content;
469
+ this.scroller = null;
470
+ }
471
+
346
472
  private syncText() {
347
473
  const { window } = this.handle;
348
474
  window.title = this.props.title ?? "";
@@ -504,28 +630,28 @@ class WindowHost {
504
630
  }
505
631
 
506
632
  if (isGiven(minWidth)) {
507
- presenter.preferredMinimumWidth = round({
633
+ presenter.preferredMinimumWidth = toDevicePixels({
508
634
  value: minWidth,
509
635
  scale
510
636
  });
511
637
  }
512
638
 
513
639
  if (isGiven(minHeight)) {
514
- presenter.preferredMinimumHeight = round({
640
+ presenter.preferredMinimumHeight = toDevicePixels({
515
641
  value: minHeight,
516
642
  scale
517
643
  });
518
644
  }
519
645
 
520
646
  if (isGiven(maxWidth)) {
521
- presenter.preferredMaximumWidth = round({
647
+ presenter.preferredMaximumWidth = toDevicePixels({
522
648
  value: maxWidth,
523
649
  scale
524
650
  });
525
651
  }
526
652
 
527
653
  if (isGiven(maxHeight)) {
528
- presenter.preferredMaximumHeight = round({
654
+ presenter.preferredMaximumHeight = toDevicePixels({
529
655
  value: maxHeight,
530
656
  scale
531
657
  });
@@ -629,7 +755,7 @@ class WindowHost {
629
755
  hwnd,
630
756
  width,
631
757
  height,
632
- radius: round({
758
+ radius: toDevicePixels({
633
759
  value: cornerRadius,
634
760
  scale: this.handle.scale
635
761
  })
@@ -684,11 +810,11 @@ class WindowHost {
684
810
  const { scale } = this.handle;
685
811
  const current = this.openSize ?? appWindow.size;
686
812
  const size = {
687
- width: props.width === undefined ? current.width : round({
813
+ width: props.width === undefined ? current.width : toDevicePixels({
688
814
  value: props.width,
689
815
  scale
690
816
  }),
691
- height: props.height === undefined ? current.height : round({
817
+ height: props.height === undefined ? current.height : toDevicePixels({
692
818
  value: props.height,
693
819
  scale
694
820
  })
@@ -733,7 +859,8 @@ class WindowHost {
733
859
  }
734
860
 
735
861
  // A new width or height resizes the window; the user's own resizing is not
736
- // undone, since the props did not change.
862
+ // undone, since the props did not change. A side that follows the content
863
+ // (sizeToContent) is the content's to set.
737
864
  private syncSize() {
738
865
  const { width, height } = this.props;
739
866
  const isChanged = width !== this.appliedSize.width || height !== this.appliedSize.height;
@@ -747,18 +874,108 @@ class WindowHost {
747
874
  };
748
875
  const { appWindow } = this.handle.window;
749
876
  const { scale } = this.handle;
877
+ const { isWidthFitted, isHeightFitted } = this.fittedSides;
750
878
  appWindow.resize({
751
- width: width === undefined ? appWindow.size.width : round({
879
+ width: sideOf({
752
880
  value: width,
881
+ current: appWindow.size.width,
882
+ isFitted: isWidthFitted,
753
883
  scale
754
884
  }),
755
- height: height === undefined ? appWindow.size.height : round({
885
+ height: sideOf({
756
886
  value: height,
887
+ current: appWindow.size.height,
888
+ isFitted: isHeightFitted,
757
889
  scale
758
890
  })
759
891
  });
760
892
  }
761
893
 
894
+ private get fittedSides() {
895
+ const mode = this.props.sizeToContent ?? SizeToContentKind.none;
896
+ return {
897
+ isWidthFitted: mode === SizeToContentKind.width || mode === SizeToContentKind.both,
898
+ isHeightFitted: mode === SizeToContentKind.height || mode === SizeToContentKind.both
899
+ };
900
+ }
901
+
902
+ // Sizes the window to what its content asks for, whenever the prop, the
903
+ // limits, the scale or a layout pass changes it: one MoveAndResize, so the
904
+ // anchor corner never moves between the size and the position.
905
+ private fitToContent() {
906
+ const mode = this.props.sizeToContent ?? SizeToContentKind.none;
907
+ const anchor = this.props.anchor ?? WindowAnchorKind.topLeft;
908
+ const { minWidth, minHeight, maxWidth, maxHeight } = this.props;
909
+ const isIdle = mode === SizeToContentKind.none || !this.isWindowed || this.isFitting;
910
+ if (isIdle) {
911
+ return;
912
+ }
913
+
914
+ const { desiredSize } = this.content;
915
+ const isMeasured = desiredSize.width > 0 && desiredSize.height > 0;
916
+ if (!isMeasured) {
917
+ return;
918
+ }
919
+
920
+ const { appWindow, scale } = this.handle;
921
+ const { size, position, clientSize } = appWindow;
922
+ const frame = {
923
+ width: size.width - clientSize.width,
924
+ height: size.height - clientSize.height
925
+ };
926
+ const target = fittedBounds({
927
+ bounds: {
928
+ ...position,
929
+ ...size
930
+ },
931
+ desired: {
932
+ width: toDevicePixels({
933
+ value: desiredSize.width,
934
+ scale
935
+ }) + frame.width,
936
+ height: toDevicePixels({
937
+ value: desiredSize.height,
938
+ scale
939
+ }) + frame.height
940
+ },
941
+ mode,
942
+ anchor,
943
+ limits: {
944
+ minWidth: limitOf({
945
+ value: minWidth,
946
+ fallback: 0,
947
+ scale
948
+ }),
949
+ minHeight: limitOf({
950
+ value: minHeight,
951
+ fallback: 0,
952
+ scale
953
+ }),
954
+ maxWidth: limitOf({
955
+ value: maxWidth,
956
+ fallback: Infinity,
957
+ scale
958
+ }),
959
+ maxHeight: limitOf({
960
+ value: maxHeight,
961
+ fallback: Infinity,
962
+ scale
963
+ })
964
+ }
965
+ });
966
+ const hasTarget = target !== null;
967
+ if (!hasTarget) {
968
+ return;
969
+ }
970
+
971
+ this.isFitting = true;
972
+ try {
973
+ appWindow.moveAndResize(target);
974
+ } finally {
975
+ this.isFitting = false;
976
+ }
977
+ }
978
+
762
979
  private isCloseRefused() {
763
980
  return this.props.onclosing?.() === true;
764
981
  }
@@ -779,6 +996,7 @@ class WindowHost {
779
996
  this.releaseBackdrop = null;
780
997
  this.props.onclosed?.();
781
998
  }),
999
+ this.content.onLayoutUpdated(() => this.fitToContent()),
782
1000
  window.appWindow.onChanged((_sender, event) => {
783
1001
  const isMoved = event.didPositionChange || event.didSizeChange;
784
1002
  if (isMoved) {
@@ -800,6 +1018,7 @@ class WindowHost {
800
1018
  this.syncLimits();
801
1019
  this.syncRegions();
802
1020
  this.syncShape();
1021
+ this.fitToContent();
803
1022
  this.props.onscalechanged?.(scale);
804
1023
  }
805
1024
  });
@@ -824,7 +1043,8 @@ class WindowHost {
824
1043
  // them (to reopen where the window was) needs them before the user moves it.
825
1044
  private show() {
826
1045
  const isHidden = this.props.isHidden === true;
827
- if (!isHidden) {
1046
+ const isToShow = !isHidden && !this.isTakenOver;
1047
+ if (isToShow) {
828
1048
  this.showWindow();
829
1049
  }
830
1050
 
@@ -850,14 +1070,14 @@ class WindowHost {
850
1070
  * where an effect can be created (a component, or an effect root).
851
1071
  */
852
1072
  export function attachWindow(options: AttachOptions) {
853
- const host = new WindowHost(options);
854
- const forget = onTeardown(() => host.dispose());
1073
+ const host = new WindowHost(options, orphans.shift());
1074
+ const forget = onTeardown(() => host.dispose(false));
855
1075
  host.handle.window.onClosed(forget);
856
1076
  return {
857
1077
  handle: host.handle,
858
1078
  dispose() {
859
1079
  forget();
860
- host.dispose();
1080
+ host.dispose(true);
861
1081
  }
862
1082
  };
863
1083
  }
package/src/winui.ts CHANGED
@@ -8,6 +8,9 @@ export { Application } from "#winui/microsoft/ui/xaml/Application";
8
8
  export { ColumnDefinition } from "#winui/microsoft/ui/xaml/controls/ColumnDefinition";
9
9
  export { Grid } from "#winui/microsoft/ui/xaml/controls/Grid";
10
10
  export { RowDefinition } from "#winui/microsoft/ui/xaml/controls/RowDefinition";
11
+ export { ScrollBarVisibility } from "#winui/microsoft/ui/xaml/controls/ScrollBarVisibility";
12
+ export { ScrollMode } from "#winui/microsoft/ui/xaml/controls/ScrollMode";
13
+ export { ScrollViewer } from "#winui/microsoft/ui/xaml/controls/ScrollViewer";
11
14
  export { Run } from "#winui/microsoft/ui/xaml/documents/Run";
12
15
  export { DispatcherQueue } from "#winui/microsoft/ui/dispatching/DispatcherQueue";
13
16
  export { DesktopAcrylicBackdrop } from "#winui/microsoft/ui/xaml/media/DesktopAcrylicBackdrop";
@@ -18,6 +21,8 @@ export { DesktopAcrylicKind } from "#winui/microsoft/ui/composition/system-backd
18
21
  export { SystemBackdropConfiguration } from "#winui/microsoft/ui/composition/system-backdrops/SystemBackdropConfiguration";
19
22
  export { SystemBackdropTheme } from "#winui/microsoft/ui/composition/system-backdrops/SystemBackdropTheme";
20
23
  export { ICompositionSupportsSystemBackdrop } from "#winui/microsoft/ui/composition/ICompositionSupportsSystemBackdrop";
24
+ export { Compositor as SystemCompositor } from "#winui/windows/ui/composition/Compositor";
25
+ export { CompositionColorBrush as SystemCompositionColorBrush } from "#winui/windows/ui/composition/CompositionColorBrush";
21
26
  export { MicaKind } from "#winui/microsoft/ui/composition/system-backdrops/MicaKind";
22
27
  export { AppWindow } from "#winui/microsoft/ui/windowing/AppWindow";
23
28
  export { AppWindowPresenterKind } from "#winui/microsoft/ui/windowing/AppWindowPresenterKind";