@workbench-kit/react 0.0.2-prototype.0.2.25 → 0.0.2-prototype.0.2.27

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 (53) hide show
  1. package/README.md +61 -14
  2. package/package.json +21 -11
  3. package/src/index.ts +2 -2
  4. package/src/jdw/fixtures/jdw-fixtures.ts +0 -15
  5. package/src/overlay/ContextMenu.tsx +4 -16
  6. package/src/overlay/context-menu-density.css +22 -0
  7. package/src/overlay/context-menu-item.ts +17 -0
  8. package/src/overlay/context-menu.css +2 -0
  9. package/src/primitives/app-icon/AppIcon.tsx +33 -0
  10. package/src/primitives/app-icon/app-icon.css +28 -0
  11. package/src/primitives/catalog-browse-pane/CatalogBrowsePane.tsx +24 -17
  12. package/src/primitives/catalog-browse-pane/catalog-browse-pane.css +4 -0
  13. package/src/primitives/index.ts +2 -0
  14. package/src/primitives/primitives.css +1 -0
  15. package/src/scrollbars.css +2 -6
  16. package/src/styles/core.css +16 -0
  17. package/src/styles/foundation.css +4 -0
  18. package/src/styles/overlay.css +2 -0
  19. package/src/styles.css +0 -1
  20. package/src/widget-tree/WidgetSourceEditor.tsx +0 -14
  21. package/src/widget-tree/WidgetTreeCanvasPreview.tsx +2 -6
  22. package/src/widget-tree/WidgetTreeLab.tsx +2 -23
  23. package/src/workbench/auth/WorkbenchLoginView.tsx +1 -2
  24. package/src/workbench/auth/auth-flows.css +14 -0
  25. package/src/workbench/chrome/workbench-layout-regions.css +13 -0
  26. package/src/workbench/chrome/workbench-shell-titlebar.css +0 -8
  27. package/src/workbench/commands/CommandList.tsx +1 -0
  28. package/src/workbench/commands/commands.ts +28 -0
  29. package/src/workbench/index.ts +1 -0
  30. package/src/workbench/management/WorkbenchNotice.tsx +19 -11
  31. package/src/workbench/settings/StructuredDataSchemaPanel.tsx +21 -40
  32. package/src/workbench/settings/sectionedPanelScrollSpy.ts +0 -81
  33. package/src/workbench/shell/workbenchSidebarLayoutContext.ts +0 -6
  34. package/src/workbench/views/command-list-density.css +36 -0
  35. package/src/workbench/views/command-list.css +2 -0
  36. package/src/workbench/workspace/WorkspaceExplorer.tsx +1 -1
  37. package/src/workbench/workspace/createVirtualWorkspaceExplorerPort.ts +1 -14
  38. package/src/workbench-menu-surfaces.css +3 -57
  39. package/src/brand/TilepaperAppIcon.tsx +0 -181
  40. package/src/brand/index.ts +0 -2
  41. package/src/brand/tilepaper-app-icon-geometry.ts +0 -201
  42. package/src/primitives/absolute-box/index.ts +0 -1
  43. package/src/primitives/catalog-browse-card/index.ts +0 -1
  44. package/src/primitives/catalog-browse-pane/index.ts +0 -3
  45. package/src/primitives/catalog-filter-overlay/index.ts +0 -1
  46. package/src/primitives/codicon/index.ts +0 -1
  47. package/src/primitives/external-link-button/index.ts +0 -1
  48. package/src/primitives/library-detail-layout/index.ts +0 -6
  49. package/src/primitives/library-facet-filter-panel/index.ts +0 -1
  50. package/src/primitives/library-facet-filter-strip/index.ts +0 -1
  51. package/src/primitives/panel-loading/index.ts +0 -1
  52. package/src/primitives/scroll-area-infinite-load/index.ts +0 -2
  53. package/src/primitives/workbench-thumbnail/index.ts +0 -1
package/README.md CHANGED
@@ -15,14 +15,44 @@ Peer: React 19.
15
15
 
16
16
  ## Styles
17
17
 
18
- Import once at app entry:
18
+ Import one bundle at the app entry. A host that renders the broad Workbench feature
19
+ set should use the core bundle, which excludes only the optional Auth and Chat
20
+ surfaces:
19
21
 
20
22
  ```ts
21
- import '@workbench-kit/tokens/styles.css';
22
- import '@workbench-kit/react/styles.css';
23
- import '@workbench-kit/react/primitives.css';
23
+ import '@workbench-kit/react/styles/core.css';
24
24
  ```
25
25
 
26
+ Use `@workbench-kit/react/styles.css` when the host also renders Auth or Chat.
27
+ Component-only consumers can instead combine token styles with
28
+ `@workbench-kit/react/primitives.css`.
29
+
30
+ Focused entries avoid loading unrelated feature hubs:
31
+
32
+ | Entry | Owns |
33
+ | -------------------------------------------- | ------------------------------------------------------------------------------------------ |
34
+ | `@workbench-kit/react/styles/foundation.css` | Theme tokens, Codicons, and shared scrollbars |
35
+ | `@workbench-kit/react/styles/overlay.css` | Context-menu overlay rules and compact context-menu density; import after `foundation.css` |
36
+ | `@workbench-kit/react/styles/core.css` | Broad Workbench feature set except Auth and Chat |
37
+ | `@workbench-kit/react/styles.css` | Full compatibility bundle |
38
+
39
+ For a non-shell surface that only uses co-located component styles and overlays:
40
+
41
+ ```ts
42
+ import '@workbench-kit/react/styles/foundation.css';
43
+ import '@workbench-kit/react/styles/overlay.css';
44
+ ```
45
+
46
+ Use `core.css` for Workbench shell routes: shell composition commonly reaches Layout,
47
+ Settings, Views, Workspace, and modal styles that a narrower name would not safely imply.
48
+ When routes emit separate async CSS chunks, inspect the production manifest because
49
+ bundlers can repeat a shared CSS import across chunks.
50
+
51
+ The packed-consumer gate measures production `core.css` and focused overlay paths from
52
+ packed tarballs. It checks required/forbidden selectors, the focused-to-core ratio,
53
+ referenced static assets, and gzip budgets. Budget changes require an explicit initial-load
54
+ review.
55
+
26
56
  ## Quick start
27
57
 
28
58
  ```tsx
@@ -50,19 +80,34 @@ Full walkthrough: [Getting Started](../../docs/guides/getting-started.md).
50
80
 
51
81
  ## Common subpaths
52
82
 
53
- | Subpath | Purpose |
54
- | ------------------------------------------ | --------------------------------------- |
55
- | `@workbench-kit/react/primitives` | Buttons, editor chrome, library layouts |
56
- | `@workbench-kit/react/workbench/shell` | Workbench shell / activity bar |
57
- | `@workbench-kit/react/workbench/workspace` | Explorer, workspace editor panel |
58
- | `@workbench-kit/react/workbench/chat` | Chat panel and message surfaces |
59
- | `@workbench-kit/react/overlay` | Context menus, anchored overlays |
60
- | `@workbench-kit/react/modal` | Low-level modal frame |
61
- | `@workbench-kit/react/jdw` | JDW preview bridges |
62
- | `@workbench-kit/react/styles.css` | Shell chrome CSS |
83
+ | Subpath | Purpose |
84
+ | -------------------------------------------- | ------------------------------------ |
85
+ | `@workbench-kit/react/primitives` | App icons, controls, library layouts |
86
+ | `@workbench-kit/react/workbench/shell` | Workbench shell / activity bar |
87
+ | `@workbench-kit/react/workbench/workspace` | Explorer, workspace editor panel |
88
+ | `@workbench-kit/react/workbench/chat` | Chat panel and message surfaces |
89
+ | `@workbench-kit/react/overlay` | Context menus, anchored overlays |
90
+ | `@workbench-kit/react/modal` | Low-level modal frame |
91
+ | `@workbench-kit/react/jdw` | JDW preview bridges |
92
+ | `@workbench-kit/react/styles/foundation.css` | Theme/icon/scrollbar foundation |
93
+ | `@workbench-kit/react/styles/overlay.css` | Focused context-menu overlay CSS |
94
+ | `@workbench-kit/react/styles/core.css` | Core host CSS without Auth and Chat |
95
+ | `@workbench-kit/react/styles.css` | Full CSS including Auth and Chat |
63
96
 
64
97
  Import **only** through `exports`. Do not deep-import `src/` paths.
65
98
 
99
+ ## Host-owned app icon
100
+
101
+ `AppIcon` standardizes icon sizing and image fitting without embedding a product
102
+ mark. Supply either an image or custom content; the host remains responsible for
103
+ the artwork.
104
+
105
+ ```tsx
106
+ import { AppIcon } from '@workbench-kit/react/primitives';
107
+
108
+ const appIcon = <AppIcon alt="Example app" src="/app-icon.svg" />;
109
+ ```
110
+
66
111
  ## Quick Open providers
67
112
 
68
113
  `WorkbenchQuickOpen` is a file/provider overlay distinct from the command palette.
@@ -123,3 +168,5 @@ pnpm dev:storybook
123
168
  Storybook stays a curated set of interaction stories — not a full package gallery.
124
169
  Demo and story modules under this package are for development; published consumers
125
170
  rely on the `exports` map and CSS entry points above.
171
+ Storybook and the sample host intentionally keep `styles.css` so they exercise the
172
+ full compatibility graph; focused production consumers are covered by the packed gate.
package/package.json CHANGED
@@ -1,11 +1,18 @@
1
1
  {
2
2
  "name": "@workbench-kit/react",
3
- "version": "0.0.2-prototype.0.2.25",
3
+ "version": "0.0.2-prototype.0.2.27",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css"
7
7
  ],
8
8
  "type": "module",
9
+ "typesVersions": {
10
+ "*": {
11
+ "overlay/context-menu-item": [
12
+ "src/overlay/context-menu-item.ts"
13
+ ]
14
+ }
15
+ },
9
16
  "exports": {
10
17
  ".": "./src/index.ts",
11
18
  "./drag-mime": "./src/utils/dragMime.ts",
@@ -14,7 +21,7 @@
14
21
  "./editor-tabs": "./src/workbench/editor-tabs/index.ts",
15
22
  "./icons": "./src/icons/index.ts",
16
23
  "./overlay": "./src/overlay/index.ts",
17
- "./brand": "./src/brand/index.ts",
24
+ "./overlay/context-menu-item": "./src/overlay/context-menu-item.ts",
18
25
  "./primitives": "./src/primitives/index.ts",
19
26
  "./primitives.css": "./src/primitives/styles.css",
20
27
  "./workbench/auth": "./src/workbench/auth/index.ts",
@@ -47,6 +54,9 @@
47
54
  "./widget-tree": "./src/widget-tree/index.ts",
48
55
  "./widget-asset": "./src/widget-asset/index.ts",
49
56
  "./widget-studio": "./src/widget-studio/index.ts",
57
+ "./styles/core.css": "./src/styles/core.css",
58
+ "./styles/foundation.css": "./src/styles/foundation.css",
59
+ "./styles/overlay.css": "./src/styles/overlay.css",
50
60
  "./styles.css": "./src/styles.css",
51
61
  "./workbench-menu-surfaces.css": "./src/workbench-menu-surfaces.css"
52
62
  },
@@ -63,15 +73,15 @@
63
73
  "@vscode/codicons": "^0.0.45",
64
74
  "remark-gfm": "^4.0.1",
65
75
  "rehype-sanitize": "^6.0.0",
66
- "@workbench-kit/jdw": "0.0.2-prototype.0.2.25",
67
- "@workbench-kit/monaco": "0.0.2-prototype.0.2.25",
68
- "@workbench-kit/platform": "0.0.2-prototype.0.2.25",
69
- "@workbench-kit/runtime": "0.0.2-prototype.0.2.25",
70
- "@workbench-kit/contracts": "0.0.2-prototype.0.2.25",
71
- "@workbench-kit/adapters": "0.0.2-prototype.0.2.25",
72
- "@workbench-kit/services": "0.0.2-prototype.0.2.25",
73
- "@workbench-kit/tokens": "0.0.2-prototype.0.2.25",
74
- "@workbench-kit/workspace": "0.0.2-prototype.0.2.25"
76
+ "@workbench-kit/contracts": "0.0.2-prototype.0.2.27",
77
+ "@workbench-kit/jdw": "0.0.2-prototype.0.2.27",
78
+ "@workbench-kit/adapters": "0.0.2-prototype.0.2.27",
79
+ "@workbench-kit/monaco": "0.0.2-prototype.0.2.27",
80
+ "@workbench-kit/runtime": "0.0.2-prototype.0.2.27",
81
+ "@workbench-kit/services": "0.0.2-prototype.0.2.27",
82
+ "@workbench-kit/platform": "0.0.2-prototype.0.2.27",
83
+ "@workbench-kit/tokens": "0.0.2-prototype.0.2.27",
84
+ "@workbench-kit/workspace": "0.0.2-prototype.0.2.27"
75
85
  },
76
86
  "peerDependencies": {
77
87
  "react": "^19.0.0",
package/src/index.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export { Modal } from './modal/Modal';
2
2
  export type { ModalBodyLayout, ModalBodyPadding, ModalProps } from './modal/Modal';
3
- export { TilepaperAppIcon } from './brand/TilepaperAppIcon';
4
- export type { TilepaperAppIconProps } from './brand/TilepaperAppIcon';
5
3
  export {
6
4
  WorkbenchIcon,
7
5
  WorkbenchIconProvider,
@@ -604,6 +602,8 @@ export type {
604
602
  } from './workbench/shell/StatusBar';
605
603
  export { AbsoluteBox } from './primitives';
606
604
  export type { AbsoluteBoxProps, WorkbenchRect } from './primitives';
605
+ export { AppIcon } from './primitives';
606
+ export type { AppIconProps, AppIconSize } from './primitives';
607
607
  export { Badge } from './primitives';
608
608
  export type { BadgeProps } from './primitives';
609
609
  export { Button } from './primitives';
@@ -35,18 +35,3 @@ export const JDW_FIXTURE_ROW_FLEX = `{
35
35
  }
36
36
  }
37
37
  `;
38
-
39
- export const JDW_FIXTURE_GRID_CELLS = `{
40
- "type": "grid",
41
- "args": {
42
- "columns": 2,
43
- "gap": 8,
44
- "padding": 12,
45
- "children": [
46
- { "type": "text", "args": { "text": "A", "col": 0, "row": 0 } },
47
- { "type": "text", "args": { "text": "B", "col": 1, "row": 0 } },
48
- { "type": "text", "args": { "text": "Wide", "col": 0, "row": 1, "colSpan": 2 } }
49
- ]
50
- }
51
- }
52
- `;
@@ -1,25 +1,13 @@
1
- import { useEffect, useMemo, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';
1
+ import './context-menu.css';
2
+ import { useEffect, useMemo, useRef, useState, type KeyboardEvent } from 'react';
2
3
  import { Button } from '../primitives/button';
3
4
  import { cxCodicon } from '../utils/codicon';
4
5
  import { cx } from '../utils/cx';
6
+ import type { ContextMenuItem } from './context-menu-item';
5
7
  import { useClampedFixedOverlayPosition } from './useClampedFixedOverlayPosition';
6
8
  import { useFixedOverlayDismiss } from './useFixedOverlayDismiss';
7
9
 
8
- export type ContextMenuItem =
9
- | {
10
- type: 'separator';
11
- id?: string | undefined;
12
- }
13
- | {
14
- type?: 'item';
15
- id?: string | undefined;
16
- label: ReactNode;
17
- icon?: string | undefined;
18
- shortcut?: ReactNode | undefined;
19
- disabled?: boolean | undefined;
20
- danger?: boolean | undefined;
21
- onSelect: () => void;
22
- };
10
+ export type { ContextMenuItem } from './context-menu-item';
23
11
 
24
12
  export interface ContextMenuProps {
25
13
  ariaLabel?: string | undefined;
@@ -0,0 +1,22 @@
1
+ /* Compact density overrides for ContextMenu. Keep before context-menu.css. */
2
+
3
+ .ui-context-menu__item,
4
+ .ui-context-menu__item.ui-button {
5
+ --ui-button-min-height: 28px;
6
+ --ui-button-height: auto;
7
+ --ui-button-padding: 4px 10px;
8
+ --ui-button-border-radius: 0;
9
+ border-radius: 0;
10
+ min-height: 28px;
11
+ height: auto;
12
+ padding: 4px 10px;
13
+ }
14
+
15
+ .ui-context-menu__separator {
16
+ margin: 0;
17
+ }
18
+
19
+ .ui-context-menu__shortcut {
20
+ font-size: var(--font-size-xs);
21
+ color: var(--color-text-subtle);
22
+ }
@@ -0,0 +1,17 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ export type ContextMenuItem =
4
+ | {
5
+ type: 'separator';
6
+ id?: string | undefined;
7
+ }
8
+ | {
9
+ type?: 'item';
10
+ id?: string | undefined;
11
+ label: ReactNode;
12
+ icon?: string | undefined;
13
+ shortcut?: ReactNode | undefined;
14
+ disabled?: boolean | undefined;
15
+ danger?: boolean | undefined;
16
+ onSelect: () => void;
17
+ };
@@ -1,3 +1,5 @@
1
+ @import './context-menu-density.css';
2
+
1
3
  .ui-context-menu {
2
4
  position: fixed;
3
5
  z-index: var(--ui-context-menu-z-index, 260);
@@ -0,0 +1,33 @@
1
+ import './app-icon.css';
2
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
3
+
4
+ import { cx } from '../../utils/cx';
5
+
6
+ export type AppIconSize = 'sm' | 'md' | 'lg';
7
+
8
+ type AppIconBaseProps = Omit<ComponentPropsWithRef<'span'>, 'children'> & {
9
+ size?: AppIconSize;
10
+ };
11
+
12
+ type AppIconImageProps = {
13
+ /** Accessible image text. Use an empty string when the surrounding surface already names the app. */
14
+ alt: string;
15
+ children?: never;
16
+ src: string;
17
+ };
18
+
19
+ type AppIconCustomProps = {
20
+ alt?: never;
21
+ children: ReactNode;
22
+ src?: never;
23
+ };
24
+
25
+ export type AppIconProps = AppIconBaseProps & (AppIconImageProps | AppIconCustomProps);
26
+
27
+ export function AppIcon({ alt, children, className, size = 'md', src, ...props }: AppIconProps) {
28
+ return (
29
+ <span className={cx('ui-app-icon', className)} data-size={size} {...props}>
30
+ {src === undefined ? children : <img alt={alt} className="ui-app-icon__image" src={src} />}
31
+ </span>
32
+ );
33
+ }
@@ -0,0 +1,28 @@
1
+ .ui-app-icon {
2
+ --ui-app-icon-size: 20px;
3
+ box-sizing: border-box;
4
+ display: inline-flex;
5
+ flex: 0 0 auto;
6
+ align-items: center;
7
+ justify-content: center;
8
+ width: var(--ui-app-icon-size);
9
+ height: var(--ui-app-icon-size);
10
+ overflow: hidden;
11
+ border-radius: var(--shell-radius-xs, var(--radius-sm, 2px));
12
+ }
13
+
14
+ .ui-app-icon[data-size='sm'] {
15
+ --ui-app-icon-size: 16px;
16
+ }
17
+
18
+ .ui-app-icon[data-size='lg'] {
19
+ --ui-app-icon-size: 32px;
20
+ }
21
+
22
+ .ui-app-icon__image,
23
+ .ui-app-icon > svg {
24
+ display: block;
25
+ width: 100%;
26
+ height: 100%;
27
+ object-fit: contain;
28
+ }
@@ -240,25 +240,32 @@ export function CatalogBrowsePane({
240
240
  >
241
241
  {items.map((item) => {
242
242
  const selected = selectedItemId === item.id;
243
- if (renderGridItem) {
244
- return <Fragment key={item.id}>{renderGridItem(item, { selected })}</Fragment>;
245
- }
246
243
  return (
247
- <CatalogBrowseCard
248
- data-ui-catalog-browse-item={item.id}
249
- imageAlt={item.imageAlt ?? item.label}
250
- imageUrl={item.imageUrl ?? null}
244
+ <div
245
+ className="ui-catalog-browse__item"
246
+ data-ui-catalog-browse-item-container={item.id}
251
247
  key={item.id}
252
- label={item.label}
253
- meta={item.meta ?? undefined}
254
- onClick={() => onOpenItem(item.id)}
255
- onContextMenu={(event) => {
256
- onItemContextMenu?.(item.id, item.label, event);
257
- }}
258
- selected={selected}
259
- tooltip={item.label}
260
- variant="cover"
261
- />
248
+ role="listitem"
249
+ >
250
+ {renderGridItem ? (
251
+ renderGridItem(item, { selected })
252
+ ) : (
253
+ <CatalogBrowseCard
254
+ data-ui-catalog-browse-item={item.id}
255
+ imageAlt={item.imageAlt ?? item.label}
256
+ imageUrl={item.imageUrl ?? null}
257
+ label={item.label}
258
+ meta={item.meta ?? undefined}
259
+ onClick={() => onOpenItem(item.id)}
260
+ onContextMenu={(event) => {
261
+ onItemContextMenu?.(item.id, item.label, event);
262
+ }}
263
+ selected={selected}
264
+ tooltip={item.label}
265
+ variant="cover"
266
+ />
267
+ )}
268
+ </div>
262
269
  );
263
270
  })}
264
271
  <BrowseScrollFooter
@@ -50,6 +50,10 @@
50
50
  min-height: 0;
51
51
  }
52
52
 
53
+ .ui-catalog-browse__item {
54
+ min-width: 0;
55
+ }
56
+
53
57
  .ui-catalog-browse__grid {
54
58
  align-content: start;
55
59
  display: grid;
@@ -1,5 +1,7 @@
1
1
  export { AbsoluteBox } from './absolute-box/AbsoluteBox';
2
2
  export type { AbsoluteBoxProps, WorkbenchRect } from './absolute-box/AbsoluteBox';
3
+ export { AppIcon } from './app-icon/AppIcon';
4
+ export type { AppIconProps, AppIconSize } from './app-icon/AppIcon';
3
5
  export { Badge } from './badge/Badge';
4
6
  export type { BadgeProps } from './badge/Badge';
5
7
  export { Button } from './button/Button';
@@ -1,5 +1,6 @@
1
1
  /* Primitives component styles — co-located per component folder.
2
2
  * Leaf files are imported from owning TSX for HMR; this hub keeps CSS-only bundles working. */
3
+ @import './app-icon/app-icon.css';
3
4
  @import './badge/badge.css';
4
5
  @import './button/button.css';
5
6
  @import './chip/chip.css';
@@ -117,9 +117,7 @@
117
117
  background-clip: content-box;
118
118
  }
119
119
 
120
- .ui-workbench-scrollbar--hidden,
121
- .workbench-primary-sidebar .ui-sidebar-view__body,
122
- .workbench-primary-sidebar .ui-workbench-sidebar-section__content {
120
+ .ui-workbench-scrollbar--hidden {
123
121
  scrollbar-gutter: auto;
124
122
  scrollbar-width: none;
125
123
  }
@@ -136,9 +134,7 @@
136
134
  }
137
135
 
138
136
  .ui-workbench-scrollbar--hidden::-webkit-scrollbar,
139
- .ui-workbench-scrollbar--overlay::-webkit-scrollbar,
140
- .workbench-primary-sidebar .ui-sidebar-view__body::-webkit-scrollbar,
141
- .workbench-primary-sidebar .ui-workbench-sidebar-section__content::-webkit-scrollbar {
137
+ .ui-workbench-scrollbar--overlay::-webkit-scrollbar {
142
138
  width: 0;
143
139
  height: 0;
144
140
  }
@@ -0,0 +1,16 @@
1
+ /* Core Workbench host styles.
2
+ * Auth and Chat are intentionally excluded so hosts only pay for those
3
+ * product surfaces when they opt into the full `styles.css` bundle. */
4
+ @import '@workbench-kit/tokens/styles.css';
5
+ @import '@vscode/codicons/dist/codicon.css';
6
+ @import '../scrollbars.css';
7
+ @import '../workbench/settings/settings.css';
8
+ @import '../layout/layout.css';
9
+ @import '../overlay/overlay.css';
10
+ @import '../workbench/chrome/workbench-chrome.css';
11
+ @import '../workbench/management/management.css';
12
+ @import '../workbench/views/views.css';
13
+ @import '../workbench/workspace/workspace.css';
14
+ @import '../primitives/primitives.css';
15
+ @import '../workbench/widgets/widgets.css';
16
+ @import '../modal/modal.css';
@@ -0,0 +1,4 @@
1
+ /* Shared theme, icon, and scrollbar foundation for focused CSS compositions. */
2
+ @import '@workbench-kit/tokens/styles.css';
3
+ @import '@vscode/codicons/dist/codicon.css';
4
+ @import '../scrollbars.css';
@@ -0,0 +1,2 @@
1
+ /* Context-menu overlays for focused non-shell compositions. */
2
+ @import '../overlay/overlay.css';
package/src/styles.css CHANGED
@@ -1,7 +1,6 @@
1
1
  @import '@workbench-kit/tokens/styles.css';
2
2
  @import '@vscode/codicons/dist/codicon.css';
3
3
  @import './scrollbars.css';
4
- @import './workbench-menu-surfaces.css';
5
4
  @import './workbench/settings/settings.css';
6
5
  @import './layout/layout.css';
7
6
  @import './overlay/overlay.css';
@@ -11,7 +11,6 @@ import {
11
11
  import {
12
12
  JsonCodeEditorPane,
13
13
  type JsonEditorRange,
14
- type JsonEditorPosition,
15
14
  type JsonEditorProblem,
16
15
  } from '../jdw/JsonCodeEditorPane.js';
17
16
  import { JDW_WIDGET_DOCUMENT_MIME } from '../jdw/document.js';
@@ -34,19 +33,6 @@ export interface WidgetSourceEditorProps {
34
33
  readonly onSelectPath?: ((path: WidgetPath) => void) | undefined;
35
34
  }
36
35
 
37
- export function resolveWidgetSourceRevealPosition(
38
- source: string,
39
- path: WidgetPath | null | undefined,
40
- ): JsonEditorPosition | null {
41
- const position = resolveWidgetSourceActiveRange(source, path);
42
- if (!position) return null;
43
-
44
- return {
45
- column: position.startColumn,
46
- lineNumber: position.startLineNumber,
47
- };
48
- }
49
-
50
36
  export function resolveWidgetSourceActiveRange(
51
37
  source: string,
52
38
  path: WidgetPath | null | undefined,
@@ -41,6 +41,7 @@ import { usePreviewViewport } from '../layout/usePreviewViewport.js';
41
41
  import { JdwPreview } from '../jdw/JdwPreview.js';
42
42
  import { readWidgetPlacementAssetDragData } from './widget-placement-asset-dnd.js';
43
43
  import { canAddChildren, insertedWidgetPathForParent } from './widget-tree-layout.js';
44
+ import type { WidgetTreeAssetDropOperation } from './WidgetTreeView.js';
44
45
 
45
46
  const RESIZE_HANDLE_POSITIONS = [
46
47
  'n',
@@ -68,12 +69,7 @@ export interface WidgetTreeCanvasPreviewProps {
68
69
  readonly onSelectPath: (path: WidgetPath) => void;
69
70
  }
70
71
 
71
- export interface WidgetTreeCanvasAssetDropOperation {
72
- readonly asset: WidgetPlacementAsset;
73
- readonly parentPath: WidgetPath;
74
- readonly insertIndex: number;
75
- readonly nextPath: WidgetPath;
76
- }
72
+ export type WidgetTreeCanvasAssetDropOperation = WidgetTreeAssetDropOperation;
77
73
 
78
74
  interface WidgetTreeCanvasAssetDropTarget {
79
75
  readonly insertIndex: number;
@@ -31,10 +31,7 @@ import { WorkbenchLabeledPane } from '../layout/panel';
31
31
  import type { WorkspaceEditorTheme } from '../workbench/workspace/WorkspaceEditor.js';
32
32
  import type { JsonEditorProblem } from '../jdw/JsonCodeEditorPane.js';
33
33
  import { WidgetAssetPalette } from './WidgetAssetPalette.js';
34
- import {
35
- WidgetTreeCanvasPreview,
36
- type WidgetTreeCanvasAssetDropOperation,
37
- } from './WidgetTreeCanvasPreview.js';
34
+ import { WidgetTreeCanvasPreview } from './WidgetTreeCanvasPreview.js';
38
35
  import { WidgetInspectorPanel } from './WidgetInspectorPanel.js';
39
36
  import { WidgetSourceEditor } from './WidgetSourceEditor.js';
40
37
  import { WidgetTreeSidePanel } from './WidgetTreeSidePanel.js';
@@ -375,24 +372,6 @@ export function WidgetTreeLab({
375
372
  }
376
373
  };
377
374
 
378
- const handlePlaceAssetPreviewPath = (operation: WidgetTreeCanvasAssetDropOperation) => {
379
- if (!document.root) return;
380
-
381
- const parent = getWidgetAtPath(document.root, operation.parentPath);
382
- if (!parent || !canAddChildren(parent)) return;
383
-
384
- const changed = applyPatch({
385
- type: 'insert-child',
386
- parentPath: operation.parentPath,
387
- index: operation.insertIndex,
388
- child: materializeWidgetPlacementAsset(operation.asset, parent),
389
- });
390
- if (changed) {
391
- setSelection((current) => selectWidgetPath(current, operation.nextPath));
392
- focusPropertyDetailTab();
393
- }
394
- };
395
-
396
375
  const handleRemovePath = (pathToRemove: WidgetPath) => {
397
376
  if (pathToRemove.length === 0) return;
398
377
  const parentPath = pathToRemove.slice(0, -1);
@@ -518,7 +497,7 @@ export function WidgetTreeLab({
518
497
  root={document.root}
519
498
  selectedPath={selectedPath}
520
499
  onPatch={handleCanvasPatch}
521
- onPlaceAssetPath={readOnly ? undefined : handlePlaceAssetPreviewPath}
500
+ onPlaceAssetPath={readOnly ? undefined : handlePlaceAssetPath}
522
501
  onSelectPath={handlePreviewSelectPath}
523
502
  />
524
503
  </WorkbenchLabeledPane>
@@ -1,5 +1,4 @@
1
1
  import { useId, useState, type FormEvent, type ReactNode } from 'react';
2
- import { TilepaperAppIcon } from '../../brand/TilepaperAppIcon';
3
2
  import { Button } from '../../primitives/button';
4
3
  import { TextInput } from '../../primitives/text-input';
5
4
  import { cx } from '../../utils/cx';
@@ -165,7 +164,7 @@ export interface WorkbenchPasswordResetViewProps {
165
164
  export function WorkbenchLoginBrandMark() {
166
165
  return (
167
166
  <div className="workbench-login-brand-mark" aria-hidden>
168
- <TilepaperAppIcon />
167
+ <span className="workbench-login-brand-mark__glyph">W</span>
169
168
  </div>
170
169
  );
171
170
  }
@@ -135,8 +135,22 @@
135
135
  }
136
136
 
137
137
  .workbench-login-brand-mark {
138
+ box-sizing: border-box;
139
+ display: grid;
140
+ place-items: center;
138
141
  width: 100%;
139
142
  aspect-ratio: 1;
143
+ border: 1px solid var(--color-border);
144
+ border-radius: clamp(28px, 8vw, 72px);
145
+ background: var(--color-surface);
146
+ color: var(--color-text);
147
+ }
148
+
149
+ .workbench-login-brand-mark__glyph {
150
+ font-size: clamp(72px, 14vw, 160px);
151
+ font-weight: 650;
152
+ letter-spacing: -0.08em;
153
+ line-height: 1;
140
154
  }
141
155
 
142
156
  .workbench-login-view__footer-brand {
@@ -40,3 +40,16 @@
40
40
  --panel-bg-75: var(--color-primary-side-bar-bg-75);
41
41
  background: var(--panel-bg);
42
42
  }
43
+
44
+ /* Primary-sidebar residency owns its intentionally hidden native scrollbars. */
45
+ .workbench-primary-sidebar .ui-sidebar-view__body,
46
+ .workbench-primary-sidebar .ui-workbench-sidebar-section__content {
47
+ scrollbar-gutter: auto;
48
+ scrollbar-width: none;
49
+ }
50
+
51
+ .workbench-primary-sidebar .ui-sidebar-view__body::-webkit-scrollbar,
52
+ .workbench-primary-sidebar .ui-workbench-sidebar-section__content::-webkit-scrollbar {
53
+ width: 0;
54
+ height: 0;
55
+ }
@@ -60,18 +60,10 @@
60
60
  object-position: center;
61
61
  }
62
62
 
63
- .workbench-shell-titlebar__app-icon > .tilepaper-app-icon,
64
63
  .workbench-shell-titlebar__app-icon > svg {
65
64
  shape-rendering: geometricPrecision;
66
65
  }
67
66
 
68
- .tilepaper-app-icon {
69
- display: block;
70
- width: 100%;
71
- height: 100%;
72
- overflow: visible;
73
- }
74
-
75
67
  .workbench-shell-titlebar__title {
76
68
  min-width: 0;
77
69
  overflow: hidden;