@workbench-kit/react 0.0.2-prototype.0.2.26 → 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.
- package/README.md +61 -14
- package/package.json +21 -11
- package/src/index.ts +2 -2
- package/src/jdw/fixtures/jdw-fixtures.ts +0 -15
- package/src/overlay/ContextMenu.tsx +4 -16
- package/src/overlay/context-menu-density.css +22 -0
- package/src/overlay/context-menu-item.ts +17 -0
- package/src/overlay/context-menu.css +2 -0
- package/src/primitives/app-icon/AppIcon.tsx +33 -0
- package/src/primitives/app-icon/app-icon.css +28 -0
- package/src/primitives/catalog-browse-pane/CatalogBrowsePane.tsx +24 -17
- package/src/primitives/catalog-browse-pane/catalog-browse-pane.css +4 -0
- package/src/primitives/index.ts +2 -0
- package/src/primitives/primitives.css +1 -0
- package/src/scrollbars.css +2 -6
- package/src/styles/core.css +16 -0
- package/src/styles/foundation.css +4 -0
- package/src/styles/overlay.css +2 -0
- package/src/styles.css +0 -1
- package/src/widget-tree/WidgetSourceEditor.tsx +0 -14
- package/src/widget-tree/WidgetTreeCanvasPreview.tsx +2 -6
- package/src/widget-tree/WidgetTreeLab.tsx +2 -23
- package/src/workbench/auth/WorkbenchLoginView.tsx +1 -2
- package/src/workbench/auth/auth-flows.css +14 -0
- package/src/workbench/chrome/workbench-layout-regions.css +13 -0
- package/src/workbench/chrome/workbench-shell-titlebar.css +0 -8
- package/src/workbench/commands/CommandList.tsx +1 -0
- package/src/workbench/management/WorkbenchNotice.tsx +19 -11
- package/src/workbench/settings/StructuredDataSchemaPanel.tsx +21 -40
- package/src/workbench/settings/sectionedPanelScrollSpy.ts +0 -81
- package/src/workbench/shell/workbenchSidebarLayoutContext.ts +0 -6
- package/src/workbench/views/command-list-density.css +36 -0
- package/src/workbench/views/command-list.css +2 -0
- package/src/workbench/workspace/WorkspaceExplorer.tsx +1 -1
- package/src/workbench/workspace/createVirtualWorkspaceExplorerPort.ts +1 -14
- package/src/workbench-menu-surfaces.css +3 -57
- package/src/brand/TilepaperAppIcon.tsx +0 -181
- package/src/brand/index.ts +0 -2
- package/src/brand/tilepaper-app-icon-geometry.ts +0 -201
- package/src/primitives/absolute-box/index.ts +0 -1
- package/src/primitives/catalog-browse-card/index.ts +0 -1
- package/src/primitives/catalog-browse-pane/index.ts +0 -3
- package/src/primitives/catalog-filter-overlay/index.ts +0 -1
- package/src/primitives/codicon/index.ts +0 -1
- package/src/primitives/external-link-button/index.ts +0 -1
- package/src/primitives/library-detail-layout/index.ts +0 -6
- package/src/primitives/library-facet-filter-panel/index.ts +0 -1
- package/src/primitives/library-facet-filter-strip/index.ts +0 -1
- package/src/primitives/panel-loading/index.ts +0 -1
- package/src/primitives/scroll-area-infinite-load/index.ts +0 -2
- 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
|
|
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/
|
|
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
|
|
54
|
-
|
|
|
55
|
-
| `@workbench-kit/react/primitives`
|
|
56
|
-
| `@workbench-kit/react/workbench/shell`
|
|
57
|
-
| `@workbench-kit/react/workbench/workspace`
|
|
58
|
-
| `@workbench-kit/react/workbench/chat`
|
|
59
|
-
| `@workbench-kit/react/overlay`
|
|
60
|
-
| `@workbench-kit/react/modal`
|
|
61
|
-
| `@workbench-kit/react/jdw`
|
|
62
|
-
| `@workbench-kit/react/styles.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.
|
|
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
|
-
"./
|
|
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/contracts": "0.0.2-prototype.0.2.
|
|
67
|
-
"@workbench-kit/
|
|
68
|
-
"@workbench-kit/
|
|
69
|
-
"@workbench-kit/
|
|
70
|
-
"@workbench-kit/
|
|
71
|
-
"@workbench-kit/
|
|
72
|
-
"@workbench-kit/
|
|
73
|
-
"@workbench-kit/tokens": "0.0.2-prototype.0.2.
|
|
74
|
-
"@workbench-kit/
|
|
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
|
|
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
|
+
};
|
|
@@ -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
|
-
<
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
package/src/primitives/index.ts
CHANGED
|
@@ -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';
|
package/src/scrollbars.css
CHANGED
|
@@ -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';
|
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
|
|
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 :
|
|
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
|
-
<
|
|
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;
|