@dxos/plugin-registry 0.8.4-main.fd6878d → 0.8.4-main.fffef41
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/lib/browser/{app-graph-builder-6JQNRTEQ.mjs → app-graph-builder-6CNBP3A4.mjs} +26 -25
- package/dist/lib/browser/app-graph-builder-6CNBP3A4.mjs.map +7 -0
- package/dist/lib/browser/chunk-XPEFEID2.mjs +19 -0
- package/dist/lib/browser/chunk-XPEFEID2.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +5 -7
- package/dist/lib/browser/index.mjs.map +2 -2
- package/dist/lib/browser/{intent-resolver-UGDFPMAG.mjs → intent-resolver-LKNUYBTN.mjs} +4 -4
- package/dist/lib/browser/{intent-resolver-UGDFPMAG.mjs.map → intent-resolver-LKNUYBTN.mjs.map} +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-BQPO3F3E.mjs → react-surface-IGCXOVE2.mjs} +116 -90
- package/dist/lib/browser/react-surface-IGCXOVE2.mjs.map +7 -0
- package/dist/types/src/RegistryPlugin.d.ts +1 -1
- package/dist/types/src/RegistryPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +3 -3
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/PluginDetail.d.ts.map +1 -1
- package/dist/types/src/components/PluginDetail.stories.d.ts +29 -5
- package/dist/types/src/components/PluginDetail.stories.d.ts.map +1 -1
- package/dist/types/src/components/PluginItem.d.ts +1 -1
- package/dist/types/src/components/PluginItem.d.ts.map +1 -1
- package/dist/types/src/components/PluginList.d.ts.map +1 -1
- package/dist/types/src/components/PluginList.stories.d.ts +31 -8
- package/dist/types/src/components/PluginList.stories.d.ts.map +1 -1
- package/dist/types/src/components/RegistryContainer.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +0 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +3 -1
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +27 -29
- package/src/RegistryPlugin.tsx +22 -23
- package/src/capabilities/app-graph-builder.ts +26 -25
- package/src/capabilities/react-surface.tsx +9 -13
- package/src/components/PluginDetail.stories.tsx +7 -8
- package/src/components/PluginDetail.tsx +53 -34
- package/src/components/PluginItem.tsx +53 -52
- package/src/components/PluginList.stories.tsx +22 -25
- package/src/components/PluginList.tsx +2 -4
- package/src/components/RegistryContainer.tsx +3 -11
- package/src/meta.ts +6 -3
- package/src/types.ts +5 -1
- package/dist/lib/browser/app-graph-builder-6JQNRTEQ.mjs.map +0 -7
- package/dist/lib/browser/chunk-AEBASNOI.mjs +0 -16
- package/dist/lib/browser/chunk-AEBASNOI.mjs.map +0 -7
- package/dist/lib/browser/react-surface-BQPO3F3E.mjs.map +0 -7
- package/dist/types/src/components/Icon.stories.d.ts +0 -6
- package/dist/types/src/components/Icon.stories.d.ts.map +0 -1
- package/src/components/Icon.stories.tsx +0 -108
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-registry",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.fffef41",
|
|
4
4
|
"description": "Braneframe plugin gallery",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -25,40 +25,38 @@
|
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@preact-signals/safe-react": "^0.9.0",
|
|
28
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/react-ui-
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/util": "0.8.4-main.fd6878d"
|
|
28
|
+
"@dxos/app-framework": "0.8.4-main.fffef41",
|
|
29
|
+
"@dxos/invariant": "0.8.4-main.fffef41",
|
|
30
|
+
"@dxos/live-object": "0.8.4-main.fffef41",
|
|
31
|
+
"@dxos/echo": "0.8.4-main.fffef41",
|
|
32
|
+
"@dxos/plugin-graph": "0.8.4-main.fffef41",
|
|
33
|
+
"@dxos/react-ui-form": "0.8.4-main.fffef41",
|
|
34
|
+
"@dxos/util": "0.8.4-main.fffef41",
|
|
35
|
+
"@dxos/plugin-observability": "0.8.4-main.fffef41",
|
|
36
|
+
"@dxos/react-ui-stack": "0.8.4-main.fffef41"
|
|
38
37
|
},
|
|
39
38
|
"devDependencies": {
|
|
40
|
-
"@effect-
|
|
41
|
-
"@effect/platform": "0.
|
|
42
|
-
"@
|
|
43
|
-
"@types/react": "~
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"react": "~
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"@dxos/
|
|
50
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
51
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
52
|
-
"@dxos/storybook-utils": "0.8.4-main.fd6878d"
|
|
39
|
+
"@effect-atom/atom-react": "^0.3.4",
|
|
40
|
+
"@effect/platform": "0.92.1",
|
|
41
|
+
"@types/react": "~19.2.2",
|
|
42
|
+
"@types/react-dom": "~19.2.2",
|
|
43
|
+
"effect": "3.18.3",
|
|
44
|
+
"react": "~19.2.0",
|
|
45
|
+
"react-dom": "~19.2.0",
|
|
46
|
+
"vite": "7.1.9",
|
|
47
|
+
"@dxos/random": "0.8.4-main.fffef41",
|
|
48
|
+
"@dxos/storybook-utils": "0.8.4-main.fffef41",
|
|
49
|
+
"@dxos/react-ui-theme": "0.8.4-main.fffef41",
|
|
50
|
+
"@dxos/react-ui": "0.8.4-main.fffef41"
|
|
53
51
|
},
|
|
54
52
|
"peerDependencies": {
|
|
55
|
-
"@effect-
|
|
53
|
+
"@effect-atom/atom-react": "^0.3.4",
|
|
56
54
|
"@effect/platform": "^0.80.12",
|
|
57
55
|
"effect": "^3.13.3",
|
|
58
|
-
"react": "
|
|
59
|
-
"react-dom": "
|
|
60
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
61
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
56
|
+
"react": "^19.0.0",
|
|
57
|
+
"react-dom": "^19.0.0",
|
|
58
|
+
"@dxos/react-ui": "0.8.4-main.fffef41",
|
|
59
|
+
"@dxos/react-ui-theme": "0.8.4-main.fffef41"
|
|
62
60
|
},
|
|
63
61
|
"publishConfig": {
|
|
64
62
|
"access": "public"
|
package/src/RegistryPlugin.tsx
CHANGED
|
@@ -8,26 +8,25 @@ import { AppGraphBuilder, IntentResolver, ReactSurface } from './capabilities';
|
|
|
8
8
|
import { meta } from './meta';
|
|
9
9
|
import { translations } from './translations';
|
|
10
10
|
|
|
11
|
-
export const RegistryPlugin = () =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
]);
|
|
11
|
+
export const RegistryPlugin = definePlugin(meta, () => [
|
|
12
|
+
defineModule({
|
|
13
|
+
id: `${meta.id}/module/translations`,
|
|
14
|
+
activatesOn: Events.SetupTranslations,
|
|
15
|
+
activate: () => contributes(Capabilities.Translations, translations),
|
|
16
|
+
}),
|
|
17
|
+
defineModule({
|
|
18
|
+
id: `${meta.id}/module/react-surface`,
|
|
19
|
+
activatesOn: Events.SetupReactSurface,
|
|
20
|
+
activate: ReactSurface,
|
|
21
|
+
}),
|
|
22
|
+
defineModule({
|
|
23
|
+
id: `${meta.id}/module/intent-resolver`,
|
|
24
|
+
activatesOn: Events.SetupIntentResolver,
|
|
25
|
+
activate: IntentResolver,
|
|
26
|
+
}),
|
|
27
|
+
defineModule({
|
|
28
|
+
id: `${meta.id}/module/app-graph-builder`,
|
|
29
|
+
activatesOn: Events.SetupAppGraph,
|
|
30
|
+
activate: AppGraphBuilder,
|
|
31
|
+
}),
|
|
32
|
+
]);
|
|
@@ -2,32 +2,33 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
5
|
+
import { Atom } from '@effect-atom/atom-react';
|
|
6
|
+
import * as Function from 'effect/Function';
|
|
7
|
+
import * as Option from 'effect/Option';
|
|
7
8
|
|
|
8
9
|
import { Capabilities, type PluginContext, SettingsAction, contributes, createIntent } from '@dxos/app-framework';
|
|
9
10
|
import { createExtension } from '@dxos/plugin-graph';
|
|
10
11
|
|
|
11
|
-
import { REGISTRY_ID, REGISTRY_KEY,
|
|
12
|
+
import { REGISTRY_ID, REGISTRY_KEY, meta } from '../meta';
|
|
12
13
|
|
|
13
14
|
export default (context: PluginContext) =>
|
|
14
15
|
contributes(Capabilities.AppGraphBuilder, [
|
|
15
16
|
createExtension({
|
|
16
|
-
id:
|
|
17
|
+
id: meta.id,
|
|
17
18
|
actions: (node) =>
|
|
18
|
-
|
|
19
|
-
pipe(
|
|
19
|
+
Atom.make((get) =>
|
|
20
|
+
Function.pipe(
|
|
20
21
|
get(node),
|
|
21
22
|
Option.flatMap((node) => (node.id === 'root' ? Option.some(node) : Option.none())),
|
|
22
23
|
Option.map((node) => [
|
|
23
24
|
{
|
|
24
|
-
id:
|
|
25
|
+
id: meta.id,
|
|
25
26
|
data: async () => {
|
|
26
27
|
const { dispatchPromise: dispatch } = context.getCapability(Capabilities.IntentDispatcher);
|
|
27
28
|
await dispatch(createIntent(SettingsAction.OpenPluginRegistry));
|
|
28
29
|
},
|
|
29
30
|
properties: {
|
|
30
|
-
label: ['open plugin registry label', { ns:
|
|
31
|
+
label: ['open plugin registry label', { ns: meta.id }],
|
|
31
32
|
icon: 'ph--squares-four--regular',
|
|
32
33
|
disposition: 'menu',
|
|
33
34
|
},
|
|
@@ -38,18 +39,18 @@ export default (context: PluginContext) =>
|
|
|
38
39
|
),
|
|
39
40
|
}),
|
|
40
41
|
createExtension({
|
|
41
|
-
id:
|
|
42
|
+
id: meta.id,
|
|
42
43
|
connector: (node) =>
|
|
43
|
-
|
|
44
|
-
pipe(
|
|
44
|
+
Atom.make((get) =>
|
|
45
|
+
Function.pipe(
|
|
45
46
|
get(node),
|
|
46
47
|
Option.flatMap((node) => (node.id === 'root' ? Option.some(node) : Option.none())),
|
|
47
48
|
Option.map((node) => [
|
|
48
49
|
{
|
|
49
50
|
id: REGISTRY_ID,
|
|
50
|
-
type:
|
|
51
|
+
type: meta.id,
|
|
51
52
|
properties: {
|
|
52
|
-
label: ['plugin registry label', { ns:
|
|
53
|
+
label: ['plugin registry label', { ns: meta.id }],
|
|
53
54
|
icon: 'ph--squares-four--regular',
|
|
54
55
|
disposition: 'pin-end',
|
|
55
56
|
testId: 'treeView.pluginRegistry',
|
|
@@ -60,7 +61,7 @@ export default (context: PluginContext) =>
|
|
|
60
61
|
type: 'category',
|
|
61
62
|
data: `${REGISTRY_KEY}+all`,
|
|
62
63
|
properties: {
|
|
63
|
-
label: ['all plugins label', { ns:
|
|
64
|
+
label: ['all plugins label', { ns: meta.id }],
|
|
64
65
|
icon: 'ph--squares-four--regular',
|
|
65
66
|
key: REGISTRY_KEY,
|
|
66
67
|
testId: 'pluginRegistry.all',
|
|
@@ -71,7 +72,7 @@ export default (context: PluginContext) =>
|
|
|
71
72
|
type: 'category',
|
|
72
73
|
data: `${REGISTRY_KEY}+installed`,
|
|
73
74
|
properties: {
|
|
74
|
-
label: ['installed plugins label', { ns:
|
|
75
|
+
label: ['installed plugins label', { ns: meta.id }],
|
|
75
76
|
icon: 'ph--check--regular',
|
|
76
77
|
key: REGISTRY_KEY,
|
|
77
78
|
testId: 'pluginRegistry.installed',
|
|
@@ -82,7 +83,7 @@ export default (context: PluginContext) =>
|
|
|
82
83
|
type: 'category',
|
|
83
84
|
data: `${REGISTRY_KEY}+recommended`,
|
|
84
85
|
properties: {
|
|
85
|
-
label: ['recommended plugins label', { ns:
|
|
86
|
+
label: ['recommended plugins label', { ns: meta.id }],
|
|
86
87
|
icon: 'ph--star--regular',
|
|
87
88
|
key: REGISTRY_KEY,
|
|
88
89
|
testId: 'pluginRegistry.recommended',
|
|
@@ -93,7 +94,7 @@ export default (context: PluginContext) =>
|
|
|
93
94
|
type: 'category',
|
|
94
95
|
data: `${REGISTRY_KEY}+labs`,
|
|
95
96
|
properties: {
|
|
96
|
-
label: ['labs plugins label', { ns:
|
|
97
|
+
label: ['labs plugins label', { ns: meta.id }],
|
|
97
98
|
icon: 'ph--flask--regular',
|
|
98
99
|
key: REGISTRY_KEY,
|
|
99
100
|
testId: 'pluginRegistry.labs',
|
|
@@ -107,18 +108,18 @@ export default (context: PluginContext) =>
|
|
|
107
108
|
),
|
|
108
109
|
}),
|
|
109
110
|
createExtension({
|
|
110
|
-
id: `${
|
|
111
|
+
id: `${meta.id}/actions`,
|
|
111
112
|
actions: (node) =>
|
|
112
|
-
|
|
113
|
-
pipe(
|
|
113
|
+
Atom.make((get) =>
|
|
114
|
+
Function.pipe(
|
|
114
115
|
get(node),
|
|
115
116
|
Option.flatMap((node) => (node.id === REGISTRY_ID ? Option.some(node) : Option.none())),
|
|
116
117
|
Option.map(() => [
|
|
117
118
|
{
|
|
118
|
-
id: `${
|
|
119
|
+
id: `${meta.id}/load-by-url`,
|
|
119
120
|
data: async () => {},
|
|
120
121
|
properties: {
|
|
121
|
-
label: ['load by url label', { ns:
|
|
122
|
+
label: ['load by url label', { ns: meta.id }],
|
|
122
123
|
icon: 'ph--cloud-arrow-down--regular',
|
|
123
124
|
disabled: true,
|
|
124
125
|
},
|
|
@@ -129,10 +130,10 @@ export default (context: PluginContext) =>
|
|
|
129
130
|
),
|
|
130
131
|
}),
|
|
131
132
|
createExtension({
|
|
132
|
-
id: `${
|
|
133
|
+
id: `${meta.id}/plugins`,
|
|
133
134
|
connector: (node) =>
|
|
134
|
-
|
|
135
|
-
pipe(
|
|
135
|
+
Atom.make((get) =>
|
|
136
|
+
Function.pipe(
|
|
136
137
|
get(node),
|
|
137
138
|
Option.flatMap((node) => (node.id === REGISTRY_ID ? Option.some(node) : Option.none())),
|
|
138
139
|
Option.map(() => {
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { useCallback, useMemo } from 'react';
|
|
6
6
|
|
|
7
|
-
import { Capabilities, Plugin, contributes, createSurface
|
|
8
|
-
import {
|
|
7
|
+
import { Capabilities, Plugin, contributes, createSurface } from '@dxos/app-framework';
|
|
8
|
+
import { usePluginManager } from '@dxos/app-framework/react';
|
|
9
9
|
|
|
10
10
|
import { PluginDetail, RegistryContainer } from '../components';
|
|
11
|
-
import { REGISTRY_KEY,
|
|
11
|
+
import { REGISTRY_KEY, meta } from '../meta';
|
|
12
12
|
|
|
13
13
|
export default () =>
|
|
14
14
|
contributes(Capabilities.ReactSurface, [
|
|
15
15
|
createSurface({
|
|
16
|
-
id: `${
|
|
16
|
+
id: `${meta.id}/all`,
|
|
17
17
|
role: 'article',
|
|
18
18
|
filter: (data): data is any => data.subject === `${REGISTRY_KEY}+all`,
|
|
19
19
|
component: () => {
|
|
@@ -24,7 +24,7 @@ export default () =>
|
|
|
24
24
|
},
|
|
25
25
|
}),
|
|
26
26
|
createSurface({
|
|
27
|
-
id: `${
|
|
27
|
+
id: `${meta.id}/installed`,
|
|
28
28
|
role: 'article',
|
|
29
29
|
filter: (data): data is any => data.subject === `${REGISTRY_KEY}+installed`,
|
|
30
30
|
component: () => {
|
|
@@ -41,7 +41,7 @@ export default () =>
|
|
|
41
41
|
},
|
|
42
42
|
}),
|
|
43
43
|
createSurface({
|
|
44
|
-
id: `${
|
|
44
|
+
id: `${meta.id}/recommended`,
|
|
45
45
|
role: 'article',
|
|
46
46
|
filter: (data): data is any => data.subject === `${REGISTRY_KEY}+recommended`,
|
|
47
47
|
component: () => {
|
|
@@ -58,7 +58,7 @@ export default () =>
|
|
|
58
58
|
},
|
|
59
59
|
}),
|
|
60
60
|
createSurface({
|
|
61
|
-
id: `${
|
|
61
|
+
id: `${meta.id}/labs`,
|
|
62
62
|
role: 'article',
|
|
63
63
|
filter: (data): data is any => data.subject === `${REGISTRY_KEY}+labs`,
|
|
64
64
|
component: () => {
|
|
@@ -69,7 +69,7 @@ export default () =>
|
|
|
69
69
|
},
|
|
70
70
|
}),
|
|
71
71
|
createSurface({
|
|
72
|
-
id: `${
|
|
72
|
+
id: `${meta.id}/plugin-details`,
|
|
73
73
|
role: 'article',
|
|
74
74
|
filter: (data): data is { subject: Plugin } => data.subject instanceof Plugin,
|
|
75
75
|
component: ({ data: { subject } }) => {
|
|
@@ -80,11 +80,7 @@ export default () =>
|
|
|
80
80
|
[manager, subject.meta.id, enabled],
|
|
81
81
|
);
|
|
82
82
|
|
|
83
|
-
return
|
|
84
|
-
<StackItem.Content>
|
|
85
|
-
<PluginDetail plugin={subject} enabled={enabled} onEnable={handleEnable} />
|
|
86
|
-
</StackItem.Content>
|
|
87
|
-
);
|
|
83
|
+
return <PluginDetail plugin={subject} enabled={enabled} onEnable={handleEnable} />;
|
|
88
84
|
},
|
|
89
85
|
}),
|
|
90
86
|
]);
|
|
@@ -2,29 +2,27 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@dxos-theme';
|
|
6
|
-
|
|
7
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
|
|
9
7
|
import { faker } from '@dxos/random';
|
|
10
|
-
import { withLayout, withTheme } from '@dxos/
|
|
8
|
+
import { withLayout, withTheme } from '@dxos/react-ui/testing';
|
|
11
9
|
|
|
12
10
|
import { translations } from '../translations';
|
|
13
11
|
|
|
14
|
-
import { PluginDetail
|
|
12
|
+
import { PluginDetail } from './PluginDetail';
|
|
15
13
|
|
|
16
|
-
const meta
|
|
14
|
+
const meta = {
|
|
17
15
|
title: 'plugins/plugin-registry/PluginDetail',
|
|
18
16
|
component: PluginDetail,
|
|
19
|
-
decorators: [withTheme, withLayout({
|
|
17
|
+
decorators: [withTheme, withLayout({ container: 'column' })],
|
|
20
18
|
parameters: {
|
|
21
19
|
translations,
|
|
22
20
|
},
|
|
23
|
-
}
|
|
21
|
+
} satisfies Meta<typeof PluginDetail>;
|
|
24
22
|
|
|
25
23
|
export default meta;
|
|
26
24
|
|
|
27
|
-
type Story = StoryObj<
|
|
25
|
+
type Story = StoryObj<typeof meta>;
|
|
28
26
|
|
|
29
27
|
export const Default: Story = {
|
|
30
28
|
args: {
|
|
@@ -34,6 +32,7 @@ export const Default: Story = {
|
|
|
34
32
|
name: 'Test Plugin',
|
|
35
33
|
description: faker.lorem.paragraphs(2),
|
|
36
34
|
icon: 'ph--bug--regular',
|
|
35
|
+
iconHue: 'sky',
|
|
37
36
|
homePage: 'https://example.com',
|
|
38
37
|
source: 'https://github.com/example/test-plugin',
|
|
39
38
|
screenshots: [
|
|
@@ -6,9 +6,10 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { type Plugin } from '@dxos/app-framework';
|
|
8
8
|
import { Icon, Input, Link, useTranslation } from '@dxos/react-ui';
|
|
9
|
-
import {
|
|
9
|
+
import { StackItem } from '@dxos/react-ui-stack';
|
|
10
|
+
import { getStyles, mx } from '@dxos/react-ui-theme';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
+
import { meta } from '../meta';
|
|
12
13
|
|
|
13
14
|
export type PluginDetailProps = {
|
|
14
15
|
plugin: Plugin;
|
|
@@ -17,47 +18,65 @@ export type PluginDetailProps = {
|
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
export const PluginDetail = ({ plugin, enabled, onEnable }: PluginDetailProps) => {
|
|
20
|
-
const { t } = useTranslation(
|
|
21
|
-
const {
|
|
21
|
+
const { t } = useTranslation(meta.id);
|
|
22
|
+
const {
|
|
23
|
+
id,
|
|
24
|
+
name,
|
|
25
|
+
description,
|
|
26
|
+
homePage,
|
|
27
|
+
source,
|
|
28
|
+
screenshots,
|
|
29
|
+
icon = 'ph--circle--regular',
|
|
30
|
+
iconHue = 'neutral',
|
|
31
|
+
} = plugin.meta;
|
|
32
|
+
const styles = getStyles(iconHue);
|
|
22
33
|
|
|
23
34
|
return (
|
|
24
|
-
<
|
|
25
|
-
<div role='none' className='
|
|
26
|
-
<p>{id}</p>
|
|
27
|
-
<Input.Root>
|
|
28
|
-
<Input.Switch classNames='self-center' checked={enabled} onClick={onEnable} />
|
|
29
|
-
</Input.Root>
|
|
30
|
-
</div>
|
|
31
|
-
|
|
32
|
-
{screenshots && screenshots.length > 0 && (
|
|
35
|
+
<StackItem.Content scrollable>
|
|
36
|
+
<div role='none' className='grid grid-cols-[min-content_1fr] gap-4 container-max-width p-4'>
|
|
33
37
|
<div role='none'>
|
|
34
|
-
<
|
|
35
|
-
<img src={screenshots[0]} alt={name} className='aspect-video object-fit' />
|
|
38
|
+
<Icon classNames={mx('p-1 rounded', styles.bg, styles.icon)} icon={icon} size={14} />
|
|
36
39
|
</div>
|
|
37
|
-
|
|
40
|
+
<div role='none' className='flex flex-col gap-6'>
|
|
41
|
+
<div role='none' className='grid grid-cols-[1fr_min-content] gap-x-3 is-full pbs-1'>
|
|
42
|
+
<h2 className='text-xl'>{name}</h2>
|
|
43
|
+
<Input.Root>
|
|
44
|
+
<Input.Switch classNames='self-center' checked={enabled} onClick={onEnable} />
|
|
45
|
+
</Input.Root>
|
|
46
|
+
<p className='pbs-0.5 text-sm text-description'>{id}</p>
|
|
47
|
+
</div>
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
<div role='none'>
|
|
50
|
+
<p className='text-description'>{description}</p>
|
|
51
|
+
</div>
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
{t('home page label')}
|
|
49
|
-
<Icon icon='ph--arrow-square-out--bold' size={3} classNames='inline-block leading-none mli-1' />
|
|
50
|
-
</Link>
|
|
53
|
+
{screenshots && screenshots.length > 0 && (
|
|
54
|
+
<div role='none' className='flex flex-col gap-2'>
|
|
55
|
+
<h2>Preview</h2>
|
|
56
|
+
<img src={screenshots[0]} alt={name} className='aspect-video object-fit' />
|
|
57
|
+
</div>
|
|
51
58
|
)}
|
|
52
59
|
|
|
53
|
-
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
<div role='none' className='flex flex-col gap-2'>
|
|
61
|
+
<h2>Resources</h2>
|
|
62
|
+
<div className='flex gap-2'>
|
|
63
|
+
{homePage && (
|
|
64
|
+
<Link href={homePage} target='_blank' rel='noreferrer' classNames='text-sm text-description'>
|
|
65
|
+
{t('home page label')}
|
|
66
|
+
<Icon icon='ph--arrow-square-out--bold' size={3} classNames='inline-block leading-none mli-1' />
|
|
67
|
+
</Link>
|
|
68
|
+
)}
|
|
69
|
+
|
|
70
|
+
{source && (
|
|
71
|
+
<Link href={source} target='_blank' rel='noreferrer' classNames='text-sm text-description'>
|
|
72
|
+
{t('source label')}
|
|
73
|
+
<Icon icon='ph--arrow-square-out--bold' size={3} classNames='inline-block leading-none mli-1' />
|
|
74
|
+
</Link>
|
|
75
|
+
)}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
59
78
|
</div>
|
|
60
79
|
</div>
|
|
61
|
-
</
|
|
80
|
+
</StackItem.Content>
|
|
62
81
|
);
|
|
63
82
|
};
|
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
import React, { type MouseEvent, useCallback } from 'react';
|
|
6
6
|
|
|
7
7
|
import { type Plugin } from '@dxos/app-framework';
|
|
8
|
-
import { Icon, IconButton, Input, Link, ListItem, Tag, useTranslation } from '@dxos/react-ui';
|
|
8
|
+
import { type ChromaticPalette, Icon, IconButton, Input, Link, ListItem, Tag, useTranslation } from '@dxos/react-ui';
|
|
9
9
|
import { descriptionText, mx } from '@dxos/react-ui-theme';
|
|
10
|
+
import { getStyles } from '@dxos/react-ui-theme';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
+
import { meta } from '../meta';
|
|
13
|
+
import { type RegistryTagType } from '../types';
|
|
12
14
|
|
|
13
15
|
export type PluginItemProps = {
|
|
14
16
|
plugin: Plugin;
|
|
@@ -25,11 +27,11 @@ export const PluginItem = ({
|
|
|
25
27
|
enabled = [],
|
|
26
28
|
onClick,
|
|
27
29
|
onChange,
|
|
28
|
-
hasSettings:
|
|
30
|
+
hasSettings: hasSettingsParam,
|
|
29
31
|
onSettings,
|
|
30
32
|
}: PluginItemProps) => {
|
|
31
|
-
const { t } = useTranslation(
|
|
32
|
-
const { id, name, description, tags, icon = 'ph--circle--regular' } = plugin.meta;
|
|
33
|
+
const { t } = useTranslation(meta.id);
|
|
34
|
+
const { id, name, description, tags, icon = 'ph--circle--regular', iconHue = 'neutral' } = plugin.meta;
|
|
33
35
|
const isEnabled = enabled.includes(id);
|
|
34
36
|
const inputId = `${id}-input`;
|
|
35
37
|
const labelId = `${id}-label`;
|
|
@@ -44,8 +46,11 @@ export const PluginItem = ({
|
|
|
44
46
|
[id, isEnabled, onChange],
|
|
45
47
|
);
|
|
46
48
|
|
|
47
|
-
const hasSettings =
|
|
49
|
+
const hasSettings = hasSettingsParam?.(id) ?? false;
|
|
48
50
|
const handleSettings = useCallback(() => onSettings?.(id), [id, onSettings]);
|
|
51
|
+
const styles = getStyles(iconHue);
|
|
52
|
+
const gridCols = 'grid grid-cols-[5rem_1fr]';
|
|
53
|
+
const gridRows = 'grid grid-rows-[40px_1fr_min-content_40px]';
|
|
49
54
|
|
|
50
55
|
return (
|
|
51
56
|
<ListItem.Root
|
|
@@ -53,67 +58,63 @@ export const PluginItem = ({
|
|
|
53
58
|
labelId={labelId}
|
|
54
59
|
data-testid={`pluginList.${id}`}
|
|
55
60
|
aria-describedby={descriptionId}
|
|
56
|
-
|
|
57
|
-
classNames='is-full bs-full grid grid-cols-[48px_1fr_48px] grid-rows-[40px_1fr_32px] p-1 border border-separator rounded-md'
|
|
61
|
+
classNames={mx(gridCols, 'bs-[12rem] is-full gap-3 pie-2 border border-separator rounded-md overflow-hidden')}
|
|
58
62
|
>
|
|
59
|
-
{
|
|
60
|
-
|
|
61
|
-
<Icon icon={icon} size={
|
|
62
|
-
</div>
|
|
63
|
-
<div className='flex items-center overflow-hidden cursor-pointer' onClick={handleClick}>
|
|
64
|
-
<span className='truncate'>{name ?? id}</span>
|
|
65
|
-
</div>
|
|
66
|
-
<div className='flex justify-center items-center'>
|
|
67
|
-
<Input.Root id={inputId}>
|
|
68
|
-
<Input.Switch classNames='self-center' checked={isEnabled} onClick={handleChange} />
|
|
69
|
-
</Input.Root>
|
|
63
|
+
<div className={mx(gridRows, 'justify-center rounded-l-md', styles.bg)}>
|
|
64
|
+
<div />
|
|
65
|
+
<Icon classNames={mx('cursor-pointer', styles.icon)} icon={icon} size={14} onClick={handleClick} />
|
|
70
66
|
</div>
|
|
71
67
|
|
|
72
|
-
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<div id={descriptionId} className='col-span-2 flex flex-col w-full justify-between gap-2 pb-2'>
|
|
76
|
-
<div className='grow'>
|
|
77
|
-
<p className={mx(descriptionText, 'line-clamp-3 min-w-0 pie-2')}>{description}</p>
|
|
78
|
-
</div>
|
|
79
|
-
{tags && tags.length > 0 && (
|
|
80
|
-
<div>
|
|
81
|
-
{tags.map((tag) => (
|
|
82
|
-
<Tag key={tag} palette={'indigo'} classNames='text-xs capitalize'>
|
|
83
|
-
{tag}
|
|
84
|
-
</Tag>
|
|
85
|
-
))}
|
|
86
|
-
</div>
|
|
87
|
-
)}
|
|
68
|
+
<div className={mx(gridRows)}>
|
|
69
|
+
<div className='flex items-center overflow-hidden cursor-pointer' onClick={handleClick}>
|
|
70
|
+
<span className='text-lg truncate'>{name ?? id}</span>
|
|
88
71
|
</div>
|
|
89
|
-
)}
|
|
90
72
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<Link
|
|
95
|
-
aria-describedby={descriptionId}
|
|
96
|
-
classNames='text-sm text-description cursor-pointer'
|
|
97
|
-
onClick={handleClick}
|
|
98
|
-
>
|
|
99
|
-
{t('details label')}
|
|
100
|
-
</Link>
|
|
73
|
+
<div>
|
|
74
|
+
<p className={mx(descriptionText, 'line-clamp-4 min-is-0')}>{description}</p>
|
|
75
|
+
</div>
|
|
101
76
|
|
|
102
|
-
<div className='flex-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
77
|
+
<div className='flex -mis-0.5 overflow-x-auto scrollbar-none'>
|
|
78
|
+
{tags?.map((tag) => (
|
|
79
|
+
<Tag key={tag} palette={tagColors[tag as RegistryTagType]} classNames='text-xs uppercase font-thin'>
|
|
80
|
+
{tag}
|
|
81
|
+
</Tag>
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
|
|
85
|
+
<div className='flex gap-2 items-center text-sm'>
|
|
106
86
|
<IconButton
|
|
107
87
|
aria-describedby={descriptionId}
|
|
108
|
-
classNames='
|
|
88
|
+
classNames='cursor-pointer'
|
|
109
89
|
icon='ph--gear--regular'
|
|
110
90
|
label={t('settings label')}
|
|
111
91
|
iconOnly
|
|
112
92
|
size={4}
|
|
113
93
|
onClick={handleSettings}
|
|
94
|
+
disabled={!hasSettings}
|
|
114
95
|
/>
|
|
115
|
-
|
|
96
|
+
|
|
97
|
+
<Link aria-describedby={descriptionId} classNames='text-description cursor-pointer' onClick={handleClick}>
|
|
98
|
+
{t('details label')}
|
|
99
|
+
</Link>
|
|
100
|
+
|
|
101
|
+
<div className='grow' />
|
|
102
|
+
<div className='pie-1'>
|
|
103
|
+
<Input.Root id={inputId}>
|
|
104
|
+
<Input.Switch classNames='self-center' checked={isEnabled} onClick={handleChange} />
|
|
105
|
+
</Input.Root>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
116
108
|
</div>
|
|
117
109
|
</ListItem.Root>
|
|
118
110
|
);
|
|
119
111
|
};
|
|
112
|
+
|
|
113
|
+
const tagColors: Record<RegistryTagType, ChromaticPalette> = {
|
|
114
|
+
new: 'rose',
|
|
115
|
+
beta: 'teal',
|
|
116
|
+
labs: 'blue',
|
|
117
|
+
popular: 'green',
|
|
118
|
+
featured: 'pink',
|
|
119
|
+
experimental: 'amber',
|
|
120
|
+
};
|