@dxos/plugin-registry 0.6.8-main.046e6cf

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 (40) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +1 -0
  3. package/dist/lib/browser/chunk-2FC6QNHB.mjs +12 -0
  4. package/dist/lib/browser/chunk-2FC6QNHB.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +200 -0
  6. package/dist/lib/browser/index.mjs.map +7 -0
  7. package/dist/lib/browser/meta.json +1 -0
  8. package/dist/lib/browser/meta.mjs +9 -0
  9. package/dist/lib/browser/meta.mjs.map +7 -0
  10. package/dist/types/src/RegistryPlugin.d.ts +7 -0
  11. package/dist/types/src/RegistryPlugin.d.ts.map +1 -0
  12. package/dist/types/src/components/Icon.stories.d.ts +12 -0
  13. package/dist/types/src/components/Icon.stories.d.ts.map +1 -0
  14. package/dist/types/src/components/PluginList.d.ts +11 -0
  15. package/dist/types/src/components/PluginList.d.ts.map +1 -0
  16. package/dist/types/src/components/PluginList.stories.d.ts +14 -0
  17. package/dist/types/src/components/PluginList.stories.d.ts.map +1 -0
  18. package/dist/types/src/components/PluginSettings.d.ts +6 -0
  19. package/dist/types/src/components/PluginSettings.d.ts.map +1 -0
  20. package/dist/types/src/components/index.d.ts +3 -0
  21. package/dist/types/src/components/index.d.ts.map +1 -0
  22. package/dist/types/src/index.d.ts +4 -0
  23. package/dist/types/src/index.d.ts.map +1 -0
  24. package/dist/types/src/meta.d.ts +7 -0
  25. package/dist/types/src/meta.d.ts.map +1 -0
  26. package/dist/types/src/sanity.test.d.ts +2 -0
  27. package/dist/types/src/sanity.test.d.ts.map +1 -0
  28. package/dist/types/src/translations.d.ts +15 -0
  29. package/dist/types/src/translations.d.ts.map +1 -0
  30. package/package.json +62 -0
  31. package/src/RegistryPlugin.tsx +43 -0
  32. package/src/components/Icon.stories.tsx +104 -0
  33. package/src/components/PluginList.stories.tsx +58 -0
  34. package/src/components/PluginList.tsx +108 -0
  35. package/src/components/PluginSettings.tsx +104 -0
  36. package/src/components/index.ts +6 -0
  37. package/src/index.ts +9 -0
  38. package/src/meta.ts +10 -0
  39. package/src/sanity.test.ts +13 -0
  40. package/src/translations.ts +21 -0
package/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ MIT License
2
+ Copyright (c) 2022 DXOS
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # @dxos/plugin-registry
@@ -0,0 +1,12 @@
1
+ // packages/plugins/plugin-registry/src/meta.ts
2
+ var REGISTRY_PLUGIN = "dxos.org/plugin/registry";
3
+ var meta_default = {
4
+ id: REGISTRY_PLUGIN,
5
+ name: "Plugins"
6
+ };
7
+
8
+ export {
9
+ REGISTRY_PLUGIN,
10
+ meta_default
11
+ };
12
+ //# sourceMappingURL=chunk-2FC6QNHB.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/meta.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nexport const REGISTRY_PLUGIN = 'dxos.org/plugin/registry';\n\nexport default {\n id: REGISTRY_PLUGIN,\n name: 'Plugins',\n};\n"],
5
+ "mappings": ";AAIO,IAAMA,kBAAkB;AAE/B,IAAA,eAAe;EACbC,IAAID;EACJE,MAAM;AACR;",
6
+ "names": ["REGISTRY_PLUGIN", "id", "name"]
7
+ }
@@ -0,0 +1,200 @@
1
+ import {
2
+ REGISTRY_PLUGIN,
3
+ meta_default
4
+ } from "./chunk-2FC6QNHB.mjs";
5
+
6
+ // packages/plugins/plugin-registry/src/RegistryPlugin.tsx
7
+ import React3 from "react";
8
+ import { LocalStorageStore } from "@dxos/local-storage";
9
+
10
+ // packages/plugins/plugin-registry/src/components/PluginList.tsx
11
+ import { ArrowClockwise, Circle } from "@phosphor-icons/react";
12
+ import React from "react";
13
+ import {
14
+ Button,
15
+ DensityProvider,
16
+ Input,
17
+ List,
18
+ ListItem,
19
+ useTranslation
20
+ } from "@dxos/react-ui";
21
+ import { descriptionText, fineBlockSize, getSize, ghostHover, mx } from "@dxos/react-ui-theme";
22
+ var PluginList = ({ plugins = [], loaded = [], enabled = [], onChange, onReload }) => {
23
+ const { t } = useTranslation(REGISTRY_PLUGIN);
24
+ return /* @__PURE__ */ React.createElement(DensityProvider, {
25
+ density: "fine"
26
+ }, /* @__PURE__ */ React.createElement(List, {
27
+ classNames: "select-none"
28
+ }, plugins.map(({ id, name, description, homePage, tags = [], iconComponent: Icon = Circle }) => {
29
+ const isEnabled = enabled.includes(id);
30
+ const isLoaded = loaded.includes(id);
31
+ const reloadRequired = isEnabled !== isLoaded;
32
+ const inputId = `${id}-input`;
33
+ const labelId = `${id}-label`;
34
+ const descriptionId = `${id}-description`;
35
+ return /* @__PURE__ */ React.createElement(Input.Root, {
36
+ key: id,
37
+ id: inputId
38
+ }, /* @__PURE__ */ React.createElement(ListItem.Root, {
39
+ labelId,
40
+ "data-testid": `pluginList.${id}`,
41
+ "aria-describedby": descriptionId,
42
+ classNames: [
43
+ "flex gap-2 cursor-pointer plb-2 pli-2 -mli-2 rounded",
44
+ ghostHover
45
+ ]
46
+ }, /* @__PURE__ */ React.createElement(Icon, {
47
+ weight: "duotone",
48
+ className: mx("shrink-0 mbs-1", getSize(6))
49
+ }), /* @__PURE__ */ React.createElement("div", {
50
+ role: "none",
51
+ className: mx(fineBlockSize, "grow pbs-1 pl-1")
52
+ }, /* @__PURE__ */ React.createElement("label", {
53
+ htmlFor: inputId,
54
+ id: labelId,
55
+ className: "truncate"
56
+ }, name ?? id), (description || reloadRequired || homePage) && /* @__PURE__ */ React.createElement("div", {
57
+ id: descriptionId,
58
+ className: "space-b-1 pbs-1 pbe-1"
59
+ }, /* @__PURE__ */ React.createElement("p", {
60
+ className: descriptionText
61
+ }, description), reloadRequired && /* @__PURE__ */ React.createElement(Button, {
62
+ variant: "ghost",
63
+ classNames: "p-0 gap-2",
64
+ onClick: onReload
65
+ }, /* @__PURE__ */ React.createElement(ArrowClockwise, null), /* @__PURE__ */ React.createElement("p", {
66
+ className: "text-sm font-medium"
67
+ }, t("reload required message"))))), /* @__PURE__ */ React.createElement("div", {
68
+ className: "pbs-1"
69
+ }, /* @__PURE__ */ React.createElement(Input.Switch, {
70
+ classNames: "self-center",
71
+ checked: !!isEnabled,
72
+ onClick: () => onChange?.(id, !isEnabled)
73
+ }))));
74
+ })));
75
+ };
76
+
77
+ // packages/plugins/plugin-registry/src/components/PluginSettings.tsx
78
+ import React2, { useMemo } from "react";
79
+ import { useIntentDispatcher, usePlugins } from "@dxos/app-framework";
80
+ import { ObservabilityAction } from "@dxos/plugin-observability/meta";
81
+ import { SettingsValue } from "@dxos/plugin-settings";
82
+ import { Input as Input2, useTranslation as useTranslation2 } from "@dxos/react-ui";
83
+ var PluginSettings = ({ settings }) => {
84
+ const { t } = useTranslation2(REGISTRY_PLUGIN);
85
+ const { enabled, core, plugins, setPlugin, ...pluginContext } = usePlugins();
86
+ const dispatch = useIntentDispatcher();
87
+ const sort = (a, b) => a.name?.localeCompare(b.name ?? "") ?? 0;
88
+ const installed = useMemo(() => plugins.filter(({ meta }) => !core.includes(meta.id)).filter(({ meta }) => enabled.includes(meta.id)).map(({ meta }) => meta).sort(sort), []);
89
+ const available = useMemo(() => pluginContext.available.filter(({ id }) => !enabled.includes(id)).sort(sort), []);
90
+ const recommended = available.filter((meta) => !meta.tags?.includes("experimental"));
91
+ const experimental = available.filter((meta) => meta.tags?.includes("experimental"));
92
+ const handleChange = (id, enabled2) => {
93
+ setPlugin(id, enabled2);
94
+ void dispatch({
95
+ action: ObservabilityAction.SEND_EVENT,
96
+ data: {
97
+ name: "plugins.toggle",
98
+ properties: {
99
+ plugin: id,
100
+ enabled: enabled2
101
+ }
102
+ }
103
+ });
104
+ };
105
+ const handleReload = () => {
106
+ window.location.reload();
107
+ };
108
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(SettingsValue, {
109
+ label: t("settings show experimental label")
110
+ }, /* @__PURE__ */ React2.createElement(Input2.Switch, {
111
+ "data-testid": "pluginSettings.experimental",
112
+ checked: settings.experimental,
113
+ onCheckedChange: (checked) => settings.experimental = !!checked
114
+ })), /* @__PURE__ */ React2.createElement(Section, {
115
+ label: t("settings section installed label")
116
+ }, /* @__PURE__ */ React2.createElement(PluginList, {
117
+ plugins: installed,
118
+ loaded: plugins.map(({ meta }) => meta.id),
119
+ enabled,
120
+ onChange: handleChange,
121
+ onReload: handleReload
122
+ })), /* @__PURE__ */ React2.createElement(Section, {
123
+ label: t("settings section recommended label")
124
+ }, /* @__PURE__ */ React2.createElement(PluginList, {
125
+ plugins: recommended,
126
+ loaded: plugins.map(({ meta }) => meta.id),
127
+ enabled,
128
+ onChange: handleChange,
129
+ onReload: handleReload
130
+ })), settings.experimental && /* @__PURE__ */ React2.createElement(Section, {
131
+ label: t("settings section experimental label")
132
+ }, /* @__PURE__ */ React2.createElement(PluginList, {
133
+ plugins: experimental,
134
+ loaded: plugins.map(({ meta }) => meta.id),
135
+ enabled,
136
+ onChange: handleChange,
137
+ onReload: handleReload
138
+ })));
139
+ };
140
+ var Section = ({ label, children }) => {
141
+ return /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("h2", {
142
+ className: "py-2 text-sm text-neutral-500"
143
+ }, label), children);
144
+ };
145
+
146
+ // packages/plugins/plugin-registry/src/translations.ts
147
+ var translations_default = [
148
+ {
149
+ "en-US": {
150
+ [REGISTRY_PLUGIN]: {
151
+ "plugin name": "Registry",
152
+ "reload required message": "Reload required.",
153
+ "settings show experimental label": "Show experimental plugins",
154
+ "settings section installed label": "Installed",
155
+ "settings section recommended label": "Recommended",
156
+ "settings section experimental label": "Experimental",
157
+ "home page label": "Home page"
158
+ }
159
+ }
160
+ }
161
+ ];
162
+
163
+ // packages/plugins/plugin-registry/src/RegistryPlugin.tsx
164
+ var RegistryPlugin = () => {
165
+ const settings = new LocalStorageStore(REGISTRY_PLUGIN);
166
+ return {
167
+ meta: meta_default,
168
+ ready: async () => {
169
+ settings.prop({
170
+ key: "experimental",
171
+ type: LocalStorageStore.bool({
172
+ allowUndefined: true
173
+ })
174
+ });
175
+ },
176
+ provides: {
177
+ settings: settings.values,
178
+ translations: translations_default,
179
+ surface: {
180
+ component: ({ data, role }) => {
181
+ switch (role) {
182
+ case "settings":
183
+ return data.plugin === meta_default.id ? /* @__PURE__ */ React3.createElement(PluginSettings, {
184
+ settings: settings.values
185
+ }) : null;
186
+ }
187
+ return null;
188
+ }
189
+ }
190
+ }
191
+ };
192
+ };
193
+
194
+ // packages/plugins/plugin-registry/src/index.ts
195
+ var src_default = RegistryPlugin;
196
+ export {
197
+ RegistryPlugin,
198
+ src_default as default
199
+ };
200
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/RegistryPlugin.tsx", "../../../src/components/PluginList.tsx", "../../../src/components/PluginSettings.tsx", "../../../src/translations.ts", "../../../src/index.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport type { PluginDefinition, SettingsProvides, SurfaceProvides, TranslationsProvides } from '@dxos/app-framework';\nimport { LocalStorageStore } from '@dxos/local-storage';\n\nimport { PluginSettings } from './components';\nimport meta, { REGISTRY_PLUGIN } from './meta';\nimport translations from './translations';\n\nexport type RegistrySettingsProps = {\n experimental?: boolean;\n};\n\nexport type RegistryPluginProvides = SurfaceProvides & TranslationsProvides & SettingsProvides<RegistrySettingsProps>;\n\nexport const RegistryPlugin = (): PluginDefinition<RegistryPluginProvides> => {\n const settings = new LocalStorageStore<RegistrySettingsProps>(REGISTRY_PLUGIN);\n\n return {\n meta,\n ready: async () => {\n settings.prop({ key: 'experimental', type: LocalStorageStore.bool({ allowUndefined: true }) });\n },\n provides: {\n settings: settings.values,\n translations,\n surface: {\n component: ({ data, role }) => {\n switch (role) {\n case 'settings':\n return data.plugin === meta.id ? <PluginSettings settings={settings.values} /> : null;\n }\n\n return null;\n },\n },\n },\n };\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { ArrowClockwise, Circle } from '@phosphor-icons/react';\nimport React from 'react';\n\nimport type { Plugin } from '@dxos/app-framework';\nimport {\n Button,\n // type ChromaticPalette,\n // type NeutralPalette,\n DensityProvider,\n Input,\n List,\n ListItem,\n useTranslation,\n // Link,\n} from '@dxos/react-ui';\nimport { descriptionText, fineBlockSize, getSize, ghostHover, mx } from '@dxos/react-ui-theme';\n\nimport { REGISTRY_PLUGIN } from '../meta';\n\n// TODO(burdon): Reconcile with theme.\n// const palette: { [tag: string]: ChromaticPalette | NeutralPalette } = {\n// default: 'neutral',\n// new: 'green',\n// beta: 'cyan',\n// alpha: 'purple',\n// experimental: 'indigo',\n// 新発売: 'red',\n// };\n\nexport type PluginListProps = {\n plugins?: Plugin['meta'][];\n loaded?: string[];\n enabled?: string[];\n onChange?: (id: string, enabled: boolean) => void;\n onReload?: () => void;\n};\n\nexport const PluginList = ({ plugins = [], loaded = [], enabled = [], onChange, onReload }: PluginListProps) => {\n const { t } = useTranslation(REGISTRY_PLUGIN);\n\n return (\n <DensityProvider density='fine'>\n <List classNames='select-none'>\n {plugins.map(({ id, name, description, homePage, tags = [], iconComponent: Icon = Circle }) => {\n const isEnabled = enabled.includes(id);\n const isLoaded = loaded.includes(id);\n const reloadRequired = isEnabled !== isLoaded;\n const inputId = `${id}-input`;\n const labelId = `${id}-label`;\n const descriptionId = `${id}-description`;\n\n return (\n <Input.Root key={id} id={inputId}>\n <ListItem.Root\n labelId={labelId}\n data-testid={`pluginList.${id}`}\n aria-describedby={descriptionId}\n classNames={['flex gap-2 cursor-pointer plb-2 pli-2 -mli-2 rounded', ghostHover]}\n >\n <Icon weight='duotone' className={mx('shrink-0 mbs-1', getSize(6))} />\n <div role='none' className={mx(fineBlockSize, 'grow pbs-1 pl-1')}>\n <label htmlFor={inputId} id={labelId} className='truncate'>\n {name ?? id}\n </label>\n {(description || reloadRequired || homePage) && (\n <div id={descriptionId} className='space-b-1 pbs-1 pbe-1'>\n <p className={descriptionText}>{description}</p>\n {/* TODO(wittjosiah): Include once plugin docs are available. */}\n {/* {homePage && (\n <Link\n href={homePage}\n target='_blank'\n rel='noreferrer'\n aria-describedby={descriptionId}\n classNames='text-xs'\n >\n {t('home page label')}\n <ArrowSquareOut weight='bold' className={mx(getSize(3), 'inline-block leading-none mli-1')} />\n </Link>\n )} */}\n {reloadRequired && (\n <Button variant='ghost' classNames='p-0 gap-2' onClick={onReload}>\n <ArrowClockwise />\n <p className='text-sm font-medium'>{t('reload required message')}</p>\n </Button>\n )}\n </div>\n )}\n </div>\n <div className='pbs-1'>\n <Input.Switch\n classNames='self-center'\n checked={!!isEnabled}\n onClick={() => onChange?.(id, !isEnabled)}\n />\n </div>\n </ListItem.Root>\n </Input.Root>\n );\n })}\n </List>\n </DensityProvider>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useMemo, type PropsWithChildren } from 'react';\n\nimport { type Plugin, useIntentDispatcher, usePlugins } from '@dxos/app-framework';\nimport { ObservabilityAction } from '@dxos/plugin-observability/meta';\nimport { SettingsValue } from '@dxos/plugin-settings';\nimport { Input, useTranslation } from '@dxos/react-ui';\n\nimport { PluginList } from './PluginList';\nimport { type RegistrySettingsProps } from '../RegistryPlugin';\nimport { REGISTRY_PLUGIN } from '../meta';\n\nexport const PluginSettings = ({ settings }: { settings: RegistrySettingsProps }) => {\n const { t } = useTranslation(REGISTRY_PLUGIN);\n const { enabled, core, plugins, setPlugin, ...pluginContext } = usePlugins();\n const dispatch = useIntentDispatcher();\n\n const sort = (a: Plugin['meta'], b: Plugin['meta']) => a.name?.localeCompare(b.name ?? '') ?? 0;\n\n // Memoize to prevent plugins from disappearing when toggling enabled.\n const installed = useMemo(\n () =>\n plugins\n .filter(({ meta }) => !core.includes(meta.id))\n .filter(({ meta }) => enabled.includes(meta.id))\n .map(({ meta }) => meta)\n .sort(sort),\n [],\n );\n const available = useMemo(() => pluginContext.available.filter(({ id }) => !enabled.includes(id)).sort(sort), []);\n const recommended = available.filter((meta) => !meta.tags?.includes('experimental'));\n const experimental = available.filter((meta) => meta.tags?.includes('experimental'));\n\n const handleChange = (id: string, enabled: boolean) => {\n setPlugin(id, enabled);\n void dispatch({\n action: ObservabilityAction.SEND_EVENT,\n data: {\n name: 'plugins.toggle',\n properties: { plugin: id, enabled },\n },\n });\n };\n\n const handleReload = () => {\n window.location.reload();\n };\n\n return (\n <>\n <SettingsValue label={t('settings show experimental label')}>\n <Input.Switch\n data-testid='pluginSettings.experimental'\n checked={settings.experimental}\n onCheckedChange={(checked) => (settings.experimental = !!checked)}\n />\n </SettingsValue>\n\n <Section label={t('settings section installed label')}>\n <PluginList\n plugins={installed}\n loaded={plugins.map(({ meta }) => meta.id)}\n enabled={enabled}\n onChange={handleChange}\n onReload={handleReload}\n />\n </Section>\n\n <Section label={t('settings section recommended label')}>\n <PluginList\n plugins={recommended}\n loaded={plugins.map(({ meta }) => meta.id)}\n enabled={enabled}\n onChange={handleChange}\n onReload={handleReload}\n />\n </Section>\n\n {settings.experimental && (\n <Section label={t('settings section experimental label')}>\n <PluginList\n plugins={experimental}\n loaded={plugins.map(({ meta }) => meta.id)}\n enabled={enabled}\n onChange={handleChange}\n onReload={handleReload}\n />\n </Section>\n )}\n </>\n );\n};\n\nconst Section = ({ label, children }: PropsWithChildren<{ label: string }>) => {\n return (\n <div>\n <h2 className='py-2 text-sm text-neutral-500'>{label}</h2>\n {children}\n </div>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { REGISTRY_PLUGIN } from './meta';\n\nexport default [\n {\n 'en-US': {\n [REGISTRY_PLUGIN]: {\n 'plugin name': 'Registry',\n 'reload required message': 'Reload required.',\n 'settings show experimental label': 'Show experimental plugins',\n 'settings section installed label': 'Installed',\n 'settings section recommended label': 'Recommended',\n 'settings section experimental label': 'Experimental',\n 'home page label': 'Home page',\n },\n },\n },\n];\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { RegistryPlugin } from './RegistryPlugin';\n\nexport default RegistryPlugin;\n\nexport * from './RegistryPlugin';\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "LocalStorageStore", "ArrowClockwise", "Circle", "React", "Button", "DensityProvider", "Input", "List", "ListItem", "useTranslation", "descriptionText", "fineBlockSize", "getSize", "ghostHover", "mx", "PluginList", "plugins", "loaded", "enabled", "onChange", "onReload", "t", "useTranslation", "REGISTRY_PLUGIN", "DensityProvider", "density", "List", "classNames", "map", "id", "name", "description", "homePage", "tags", "iconComponent", "Icon", "Circle", "isEnabled", "includes", "isLoaded", "reloadRequired", "inputId", "labelId", "descriptionId", "Input", "Root", "key", "ListItem", "data-testid", "aria-describedby", "ghostHover", "weight", "className", "mx", "getSize", "div", "role", "fineBlockSize", "label", "htmlFor", "p", "descriptionText", "Button", "variant", "onClick", "ArrowClockwise", "Switch", "checked", "React", "useMemo", "useIntentDispatcher", "usePlugins", "ObservabilityAction", "SettingsValue", "Input", "useTranslation", "PluginSettings", "settings", "t", "useTranslation", "REGISTRY_PLUGIN", "enabled", "core", "plugins", "setPlugin", "pluginContext", "usePlugins", "dispatch", "useIntentDispatcher", "sort", "a", "b", "name", "localeCompare", "installed", "useMemo", "filter", "meta", "includes", "id", "map", "available", "recommended", "tags", "experimental", "handleChange", "action", "ObservabilityAction", "SEND_EVENT", "data", "properties", "plugin", "handleReload", "window", "location", "reload", "React", "SettingsValue", "label", "Input", "Switch", "data-testid", "checked", "onCheckedChange", "Section", "PluginList", "loaded", "onChange", "onReload", "children", "div", "h2", "className", "REGISTRY_PLUGIN", "RegistryPlugin", "settings", "LocalStorageStore", "REGISTRY_PLUGIN", "meta", "ready", "prop", "key", "type", "bool", "allowUndefined", "provides", "values", "translations", "surface", "component", "data", "role", "plugin", "id", "React", "PluginSettings", "RegistryPlugin"]
7
+ }
@@ -0,0 +1 @@
1
+ {"inputs":{"packages/plugins/plugin-registry/src/meta.ts":{"bytes":851,"imports":[],"format":"esm"},"packages/plugins/plugin-registry/src/components/PluginList.tsx":{"bytes":11519,"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/plugins/plugin-registry/src/meta.ts","kind":"import-statement","original":"../meta"}],"format":"esm"},"packages/plugins/plugin-registry/src/components/PluginSettings.tsx":{"bytes":11868,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-framework","kind":"import-statement","external":true},{"path":"@dxos/plugin-observability/meta","kind":"import-statement","external":true},{"path":"@dxos/plugin-settings","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"packages/plugins/plugin-registry/src/components/PluginList.tsx","kind":"import-statement","original":"./PluginList"},{"path":"packages/plugins/plugin-registry/src/meta.ts","kind":"import-statement","original":"../meta"}],"format":"esm"},"packages/plugins/plugin-registry/src/components/index.ts":{"bytes":627,"imports":[{"path":"packages/plugins/plugin-registry/src/components/PluginList.tsx","kind":"import-statement","original":"./PluginList"},{"path":"packages/plugins/plugin-registry/src/components/PluginSettings.tsx","kind":"import-statement","original":"./PluginSettings"}],"format":"esm"},"packages/plugins/plugin-registry/src/translations.ts":{"bytes":2036,"imports":[{"path":"packages/plugins/plugin-registry/src/meta.ts","kind":"import-statement","original":"./meta"}],"format":"esm"},"packages/plugins/plugin-registry/src/RegistryPlugin.tsx":{"bytes":4337,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/local-storage","kind":"import-statement","external":true},{"path":"packages/plugins/plugin-registry/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/plugins/plugin-registry/src/meta.ts","kind":"import-statement","original":"./meta"},{"path":"packages/plugins/plugin-registry/src/translations.ts","kind":"import-statement","original":"./translations"}],"format":"esm"},"packages/plugins/plugin-registry/src/index.ts":{"bytes":804,"imports":[{"path":"packages/plugins/plugin-registry/src/RegistryPlugin.tsx","kind":"import-statement","original":"./RegistryPlugin"},{"path":"packages/plugins/plugin-registry/src/RegistryPlugin.tsx","kind":"import-statement","original":"./RegistryPlugin"}],"format":"esm"}},"outputs":{"packages/plugins/plugin-registry/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":15831},"packages/plugins/plugin-registry/dist/lib/browser/index.mjs":{"imports":[{"path":"packages/plugins/plugin-registry/dist/lib/browser/chunk-2FC6QNHB.mjs","kind":"import-statement"},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/local-storage","kind":"import-statement","external":true},{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/app-framework","kind":"import-statement","external":true},{"path":"@dxos/plugin-observability/meta","kind":"import-statement","external":true},{"path":"@dxos/plugin-settings","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true}],"exports":["RegistryPlugin","default"],"entryPoint":"packages/plugins/plugin-registry/src/index.ts","inputs":{"packages/plugins/plugin-registry/src/RegistryPlugin.tsx":{"bytesInOutput":830},"packages/plugins/plugin-registry/src/components/PluginList.tsx":{"bytesInOutput":2565},"packages/plugins/plugin-registry/src/components/index.ts":{"bytesInOutput":0},"packages/plugins/plugin-registry/src/components/PluginSettings.tsx":{"bytesInOutput":2976},"packages/plugins/plugin-registry/src/translations.ts":{"bytesInOutput":479},"packages/plugins/plugin-registry/src/index.ts":{"bytesInOutput":34}},"bytes":7413},"packages/plugins/plugin-registry/dist/lib/browser/meta.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":93},"packages/plugins/plugin-registry/dist/lib/browser/meta.mjs":{"imports":[{"path":"packages/plugins/plugin-registry/dist/lib/browser/chunk-2FC6QNHB.mjs","kind":"import-statement"}],"exports":["REGISTRY_PLUGIN","default"],"entryPoint":"packages/plugins/plugin-registry/src/meta.ts","inputs":{},"bytes":165},"packages/plugins/plugin-registry/dist/lib/browser/chunk-2FC6QNHB.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":377},"packages/plugins/plugin-registry/dist/lib/browser/chunk-2FC6QNHB.mjs":{"imports":[],"exports":["REGISTRY_PLUGIN","meta_default"],"inputs":{"packages/plugins/plugin-registry/src/meta.ts":{"bytesInOutput":115}},"bytes":254}}}
@@ -0,0 +1,9 @@
1
+ import {
2
+ REGISTRY_PLUGIN,
3
+ meta_default
4
+ } from "./chunk-2FC6QNHB.mjs";
5
+ export {
6
+ REGISTRY_PLUGIN,
7
+ meta_default as default
8
+ };
9
+ //# sourceMappingURL=meta.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,7 @@
1
+ import type { PluginDefinition, SettingsProvides, SurfaceProvides, TranslationsProvides } from '@dxos/app-framework';
2
+ export type RegistrySettingsProps = {
3
+ experimental?: boolean;
4
+ };
5
+ export type RegistryPluginProvides = SurfaceProvides & TranslationsProvides & SettingsProvides<RegistrySettingsProps>;
6
+ export declare const RegistryPlugin: () => PluginDefinition<RegistryPluginProvides>;
7
+ //# sourceMappingURL=RegistryPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegistryPlugin.d.ts","sourceRoot":"","sources":["../../../src/RegistryPlugin.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAOrH,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,oBAAoB,GAAG,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;AAEtH,eAAO,MAAM,cAAc,QAAO,gBAAgB,CAAC,sBAAsB,CAuBxE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import '@dxosTheme';
2
+ import React from 'react';
3
+ declare const _default: {
4
+ title: string;
5
+ render: () => React.JSX.Element;
6
+ parameters: {
7
+ layout: string;
8
+ };
9
+ };
10
+ export default _default;
11
+ export declare const Default: {};
12
+ //# sourceMappingURL=Icon.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Icon.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/Icon.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAGpB,OAAO,KAAuD,MAAM,OAAO,CAAC;;;;;;;;AAwF5E,wBAME;AAEF,eAAO,MAAM,OAAO,IAAK,CAAC"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import type { Plugin } from '@dxos/app-framework';
3
+ export type PluginListProps = {
4
+ plugins?: Plugin['meta'][];
5
+ loaded?: string[];
6
+ enabled?: string[];
7
+ onChange?: (id: string, enabled: boolean) => void;
8
+ onReload?: () => void;
9
+ };
10
+ export declare const PluginList: ({ plugins, loaded, enabled, onChange, onReload }: PluginListProps) => React.JSX.Element;
11
+ //# sourceMappingURL=PluginList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginList.d.ts","sourceRoot":"","sources":["../../../../src/components/PluginList.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA0BlD,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,UAAU,qDAAqE,eAAe,sBAkE1G,CAAC"}
@@ -0,0 +1,14 @@
1
+ import '@dxosTheme';
2
+ import React from 'react';
3
+ declare const _default: {
4
+ title: string;
5
+ component: ({ plugins, loaded, enabled, onChange, onReload }: import("./PluginList").PluginListProps) => React.JSX.Element;
6
+ render: () => React.JSX.Element;
7
+ decorators: import("@storybook/react/*").Decorator[];
8
+ parameters: {
9
+ layout: string;
10
+ };
11
+ };
12
+ export default _default;
13
+ export declare const Default: {};
14
+ //# sourceMappingURL=PluginList.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginList.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/PluginList.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAGpB,OAAO,KAAmB,MAAM,OAAO,CAAC;;;;;;;;;;AAwCxC,wBAQE;AAEF,eAAO,MAAM,OAAO,IAAK,CAAC"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { type RegistrySettingsProps } from '../RegistryPlugin';
3
+ export declare const PluginSettings: ({ settings }: {
4
+ settings: RegistrySettingsProps;
5
+ }) => React.JSX.Element;
6
+ //# sourceMappingURL=PluginSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PluginSettings.d.ts","sourceRoot":"","sources":["../../../../src/components/PluginSettings.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAQ/D,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAG/D,eAAO,MAAM,cAAc,iBAAkB;IAAE,QAAQ,EAAE,qBAAqB,CAAA;CAAE,sBA+E/E,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './PluginList';
2
+ export * from './PluginSettings';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { RegistryPlugin } from './RegistryPlugin';
2
+ export default RegistryPlugin;
3
+ export * from './RegistryPlugin';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAe,cAAc,CAAC;AAE9B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare const REGISTRY_PLUGIN = "dxos.org/plugin/registry";
2
+ declare const _default: {
3
+ id: string;
4
+ name: string;
5
+ };
6
+ export default _default;
7
+ //# sourceMappingURL=meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/meta.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,6BAA6B,CAAC;;;;;AAE1D,wBAGE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sanity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanity.test.d.ts","sourceRoot":"","sources":["../../../src/sanity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ declare const _default: {
2
+ 'en-US': {
3
+ "dxos.org/plugin/registry": {
4
+ 'plugin name': string;
5
+ 'reload required message': string;
6
+ 'settings show experimental label': string;
7
+ 'settings section installed label': string;
8
+ 'settings section recommended label': string;
9
+ 'settings section experimental label': string;
10
+ 'home page label': string;
11
+ };
12
+ };
13
+ }[];
14
+ export default _default;
15
+ //# sourceMappingURL=translations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../src/translations.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAMA,wBAcE"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@dxos/plugin-registry",
3
+ "version": "0.6.8-main.046e6cf",
4
+ "description": "Braneframe plugin gallery",
5
+ "homepage": "https://dxos.org",
6
+ "bugs": "https://github.com/dxos/dxos/issues",
7
+ "license": "MIT",
8
+ "author": "DXOS.org",
9
+ "exports": {
10
+ ".": {
11
+ "browser": "./dist/lib/browser/index.mjs",
12
+ "types": "./dist/types/src/index.d.ts"
13
+ },
14
+ "./meta": {
15
+ "browser": "./dist/lib/browser/meta.mjs",
16
+ "types": "./dist/types/src/meta.d.ts"
17
+ }
18
+ },
19
+ "types": "dist/types/src/index.d.ts",
20
+ "typesVersions": {
21
+ "*": {
22
+ "meta": [
23
+ "dist/types/src/meta.d.ts"
24
+ ]
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "src"
30
+ ],
31
+ "dependencies": {
32
+ "@dxos/local-storage": "0.6.8-main.046e6cf",
33
+ "@dxos/app-framework": "0.6.8-main.046e6cf",
34
+ "@dxos/plugin-observability": "0.6.8-main.046e6cf",
35
+ "@dxos/plugin-settings": "0.6.8-main.046e6cf",
36
+ "@dxos/util": "0.6.8-main.046e6cf"
37
+ },
38
+ "devDependencies": {
39
+ "@phosphor-icons/react": "^2.1.5",
40
+ "@types/react": "~18.2.0",
41
+ "@types/react-dom": "~18.2.0",
42
+ "react": "~18.2.0",
43
+ "react-dom": "~18.2.0",
44
+ "vite": "^5.3.4",
45
+ "@dxos/random": "0.6.8-main.046e6cf",
46
+ "@dxos/react-ui": "0.6.8-main.046e6cf",
47
+ "@dxos/react-ui-mosaic": "0.6.8-main.046e6cf",
48
+ "@dxos/react-ui-theme": "0.6.8-main.046e6cf",
49
+ "@dxos/storybook-utils": "0.6.8-main.046e6cf"
50
+ },
51
+ "peerDependencies": {
52
+ "@phosphor-icons/react": "^2.1.5",
53
+ "react": "^18.0.0",
54
+ "react-dom": "^18.0.0",
55
+ "@dxos/react-ui": "0.6.8-main.046e6cf",
56
+ "@dxos/react-ui-mosaic": "0.6.8-main.046e6cf",
57
+ "@dxos/react-ui-theme": "0.6.8-main.046e6cf"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public"
61
+ }
62
+ }
@@ -0,0 +1,43 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import type { PluginDefinition, SettingsProvides, SurfaceProvides, TranslationsProvides } from '@dxos/app-framework';
8
+ import { LocalStorageStore } from '@dxos/local-storage';
9
+
10
+ import { PluginSettings } from './components';
11
+ import meta, { REGISTRY_PLUGIN } from './meta';
12
+ import translations from './translations';
13
+
14
+ export type RegistrySettingsProps = {
15
+ experimental?: boolean;
16
+ };
17
+
18
+ export type RegistryPluginProvides = SurfaceProvides & TranslationsProvides & SettingsProvides<RegistrySettingsProps>;
19
+
20
+ export const RegistryPlugin = (): PluginDefinition<RegistryPluginProvides> => {
21
+ const settings = new LocalStorageStore<RegistrySettingsProps>(REGISTRY_PLUGIN);
22
+
23
+ return {
24
+ meta,
25
+ ready: async () => {
26
+ settings.prop({ key: 'experimental', type: LocalStorageStore.bool({ allowUndefined: true }) });
27
+ },
28
+ provides: {
29
+ settings: settings.values,
30
+ translations,
31
+ surface: {
32
+ component: ({ data, role }) => {
33
+ switch (role) {
34
+ case 'settings':
35
+ return data.plugin === meta.id ? <PluginSettings settings={settings.values} /> : null;
36
+ }
37
+
38
+ return null;
39
+ },
40
+ },
41
+ },
42
+ };
43
+ };
@@ -0,0 +1,104 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxosTheme';
6
+
7
+ import { IconBase, type IconWeight, GithubLogo, type IconProps } from '@phosphor-icons/react';
8
+ import React, { forwardRef, type SVGProps, type ReactElement } from 'react';
9
+
10
+ import { getSize, mx } from '@dxos/react-ui-theme';
11
+
12
+ /**
13
+ * Serializable icon props.
14
+ */
15
+ type StoryIconProps = {
16
+ name: string;
17
+ weights: Record<string, SVGProps<SVGPathElement>[]>;
18
+ };
19
+
20
+ /**
21
+ * Create icon from serializable data.
22
+ * https://github.com/phosphor-icons/react#custom-icons
23
+ * https://github.com/phosphor-icons/core/tree/main/assets
24
+ */
25
+ const createIcon = ({ name, weights }: StoryIconProps) => {
26
+ const CustomIcon = forwardRef<SVGSVGElement, IconProps>((props, ref) => (
27
+ <IconBase
28
+ ref={ref}
29
+ {...props}
30
+ weights={
31
+ new Map<IconWeight, ReactElement>(
32
+ Object.entries(weights).map(
33
+ ([key, paths]) =>
34
+ [
35
+ key,
36
+ <>
37
+ {paths.map((props, i) => (
38
+ <path key={`${key}-${i}`} {...props} />
39
+ ))}
40
+ </>,
41
+ ] as [IconWeight, ReactElement],
42
+ ),
43
+ )
44
+ }
45
+ />
46
+ ));
47
+ CustomIcon.displayName = name;
48
+ return CustomIcon;
49
+ };
50
+
51
+ const Story = () => {
52
+ const CustomIcon = createIcon({
53
+ name: 'GithubLogo',
54
+ weights: {
55
+ // https://github.com/phosphor-icons/core/tree/main/assets
56
+ // <path d="M119.83,56A52,52,0,0,0,76,32a51.92,51.92,0,0,0-3.49,44.7A49.28,49.28,0,0,0,64,104v8a48,48,0,0,0,48,48h48a48,48,0,0,0,48-48v-8a49.28,49.28,0,0,0-8.51-27.3A51.92,51.92,0,0,0,196,32a52,52,0,0,0-43.83,24Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
57
+ // <path d="M104,232V192a32,32,0,0,1,32-32h0a32,32,0,0,1,32,32v40" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
58
+ // <path d="M104,208H72a32,32,0,0,1-32-32A32,32,0,0,0,8,144" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16"/>
59
+ regular: [
60
+ {
61
+ d: 'M119.83,56A52,52,0,0,0,76,32a51.92,51.92,0,0,0-3.49,44.7A49.28,49.28,0,0,0,64,104v8a48,48,0,0,0,48,48h48a48,48,0,0,0,48-48v-8a49.28,49.28,0,0,0-8.51-27.3A51.92,51.92,0,0,0,196,32a52,52,0,0,0-43.83,24Z',
62
+ fill: 'none',
63
+ stroke: 'currentColor',
64
+ strokeLinecap: 'round',
65
+ strokeLinejoin: 'round',
66
+ strokeWidth: '16',
67
+ },
68
+ {
69
+ d: 'M104,232V192a32,32,0,0,1,32-32h0a32,32,0,0,1,32,32v40',
70
+ fill: 'none',
71
+ stroke: 'currentColor',
72
+ strokeLinecap: 'round',
73
+ strokeLinejoin: 'round',
74
+ strokeWidth: '16',
75
+ },
76
+ {
77
+ d: 'M104,208H72a32,32,0,0,1-32-32A32,32,0,0,0,8,144',
78
+ fill: 'none',
79
+ stroke: 'currentColor',
80
+ strokeLinecap: 'round',
81
+ strokeLinejoin: 'round',
82
+ strokeWidth: '16',
83
+ },
84
+ ],
85
+ },
86
+ });
87
+
88
+ return (
89
+ <div className='flex gap-4 p-8 ring'>
90
+ <CustomIcon weight={'regular'} className={mx(getSize(8))} />
91
+ <GithubLogo weight={'regular'} className={mx(getSize(8))} />
92
+ </div>
93
+ );
94
+ };
95
+
96
+ export default {
97
+ title: 'plugin-registry/Icon',
98
+ render: Story,
99
+ parameters: {
100
+ layout: 'centered',
101
+ },
102
+ };
103
+
104
+ export const Default = {};
@@ -0,0 +1,58 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import '@dxosTheme';
6
+
7
+ import { Bug, Compass, GithubLogo, Kanban, Gear, Table } from '@phosphor-icons/react';
8
+ import React, { useState } from 'react';
9
+
10
+ import type { Plugin } from '@dxos/app-framework';
11
+ import { faker } from '@dxos/random';
12
+ import { withTheme } from '@dxos/storybook-utils';
13
+
14
+ import { PluginList } from './PluginList';
15
+
16
+ faker.seed(1);
17
+
18
+ const icons = [Bug, Compass, Kanban, Table, Gear, GithubLogo];
19
+
20
+ const Story = () => {
21
+ const [plugins] = useState<Plugin['meta'][]>(
22
+ faker.helpers.multiple(
23
+ () => ({
24
+ id: `dxos.org/plugin/plugin-${faker.string.uuid()}`,
25
+ name: `${faker.lorem.sentence(3)}`,
26
+ description: faker.datatype.boolean() ? `${faker.lorem.sentences()}` : undefined,
27
+ tags: faker.datatype.boolean({ probability: 0.6 })
28
+ ? [faker.helpers.arrayElement(['experimental', 'beta', 'alpha', 'stable', 'new', '新発売'])]
29
+ : undefined,
30
+ iconComponent: faker.helpers.arrayElement(icons),
31
+ }),
32
+ { count: 16 },
33
+ ),
34
+ );
35
+ const [enabled, setEnabled] = useState<string[]>([]);
36
+
37
+ const handleChange = (id: string, enabled: boolean) => {
38
+ setEnabled((plugins) => (enabled ? [...plugins, id] : plugins.filter((plugin) => plugin === id)));
39
+ };
40
+
41
+ return (
42
+ <div className={'flex w-[400px] overflow-hidden'}>
43
+ <PluginList plugins={plugins} enabled={enabled} onChange={handleChange} />
44
+ </div>
45
+ );
46
+ };
47
+
48
+ export default {
49
+ title: 'plugin-registry/PluginList',
50
+ component: PluginList,
51
+ render: Story,
52
+ decorators: [withTheme],
53
+ parameters: {
54
+ layout: 'centered',
55
+ },
56
+ };
57
+
58
+ export const Default = {};
@@ -0,0 +1,108 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { ArrowClockwise, Circle } from '@phosphor-icons/react';
6
+ import React from 'react';
7
+
8
+ import type { Plugin } from '@dxos/app-framework';
9
+ import {
10
+ Button,
11
+ // type ChromaticPalette,
12
+ // type NeutralPalette,
13
+ DensityProvider,
14
+ Input,
15
+ List,
16
+ ListItem,
17
+ useTranslation,
18
+ // Link,
19
+ } from '@dxos/react-ui';
20
+ import { descriptionText, fineBlockSize, getSize, ghostHover, mx } from '@dxos/react-ui-theme';
21
+
22
+ import { REGISTRY_PLUGIN } from '../meta';
23
+
24
+ // TODO(burdon): Reconcile with theme.
25
+ // const palette: { [tag: string]: ChromaticPalette | NeutralPalette } = {
26
+ // default: 'neutral',
27
+ // new: 'green',
28
+ // beta: 'cyan',
29
+ // alpha: 'purple',
30
+ // experimental: 'indigo',
31
+ // 新発売: 'red',
32
+ // };
33
+
34
+ export type PluginListProps = {
35
+ plugins?: Plugin['meta'][];
36
+ loaded?: string[];
37
+ enabled?: string[];
38
+ onChange?: (id: string, enabled: boolean) => void;
39
+ onReload?: () => void;
40
+ };
41
+
42
+ export const PluginList = ({ plugins = [], loaded = [], enabled = [], onChange, onReload }: PluginListProps) => {
43
+ const { t } = useTranslation(REGISTRY_PLUGIN);
44
+
45
+ return (
46
+ <DensityProvider density='fine'>
47
+ <List classNames='select-none'>
48
+ {plugins.map(({ id, name, description, homePage, tags = [], iconComponent: Icon = Circle }) => {
49
+ const isEnabled = enabled.includes(id);
50
+ const isLoaded = loaded.includes(id);
51
+ const reloadRequired = isEnabled !== isLoaded;
52
+ const inputId = `${id}-input`;
53
+ const labelId = `${id}-label`;
54
+ const descriptionId = `${id}-description`;
55
+
56
+ return (
57
+ <Input.Root key={id} id={inputId}>
58
+ <ListItem.Root
59
+ labelId={labelId}
60
+ data-testid={`pluginList.${id}`}
61
+ aria-describedby={descriptionId}
62
+ classNames={['flex gap-2 cursor-pointer plb-2 pli-2 -mli-2 rounded', ghostHover]}
63
+ >
64
+ <Icon weight='duotone' className={mx('shrink-0 mbs-1', getSize(6))} />
65
+ <div role='none' className={mx(fineBlockSize, 'grow pbs-1 pl-1')}>
66
+ <label htmlFor={inputId} id={labelId} className='truncate'>
67
+ {name ?? id}
68
+ </label>
69
+ {(description || reloadRequired || homePage) && (
70
+ <div id={descriptionId} className='space-b-1 pbs-1 pbe-1'>
71
+ <p className={descriptionText}>{description}</p>
72
+ {/* TODO(wittjosiah): Include once plugin docs are available. */}
73
+ {/* {homePage && (
74
+ <Link
75
+ href={homePage}
76
+ target='_blank'
77
+ rel='noreferrer'
78
+ aria-describedby={descriptionId}
79
+ classNames='text-xs'
80
+ >
81
+ {t('home page label')}
82
+ <ArrowSquareOut weight='bold' className={mx(getSize(3), 'inline-block leading-none mli-1')} />
83
+ </Link>
84
+ )} */}
85
+ {reloadRequired && (
86
+ <Button variant='ghost' classNames='p-0 gap-2' onClick={onReload}>
87
+ <ArrowClockwise />
88
+ <p className='text-sm font-medium'>{t('reload required message')}</p>
89
+ </Button>
90
+ )}
91
+ </div>
92
+ )}
93
+ </div>
94
+ <div className='pbs-1'>
95
+ <Input.Switch
96
+ classNames='self-center'
97
+ checked={!!isEnabled}
98
+ onClick={() => onChange?.(id, !isEnabled)}
99
+ />
100
+ </div>
101
+ </ListItem.Root>
102
+ </Input.Root>
103
+ );
104
+ })}
105
+ </List>
106
+ </DensityProvider>
107
+ );
108
+ };
@@ -0,0 +1,104 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import React, { useMemo, type PropsWithChildren } from 'react';
6
+
7
+ import { type Plugin, useIntentDispatcher, usePlugins } from '@dxos/app-framework';
8
+ import { ObservabilityAction } from '@dxos/plugin-observability/meta';
9
+ import { SettingsValue } from '@dxos/plugin-settings';
10
+ import { Input, useTranslation } from '@dxos/react-ui';
11
+
12
+ import { PluginList } from './PluginList';
13
+ import { type RegistrySettingsProps } from '../RegistryPlugin';
14
+ import { REGISTRY_PLUGIN } from '../meta';
15
+
16
+ export const PluginSettings = ({ settings }: { settings: RegistrySettingsProps }) => {
17
+ const { t } = useTranslation(REGISTRY_PLUGIN);
18
+ const { enabled, core, plugins, setPlugin, ...pluginContext } = usePlugins();
19
+ const dispatch = useIntentDispatcher();
20
+
21
+ const sort = (a: Plugin['meta'], b: Plugin['meta']) => a.name?.localeCompare(b.name ?? '') ?? 0;
22
+
23
+ // Memoize to prevent plugins from disappearing when toggling enabled.
24
+ const installed = useMemo(
25
+ () =>
26
+ plugins
27
+ .filter(({ meta }) => !core.includes(meta.id))
28
+ .filter(({ meta }) => enabled.includes(meta.id))
29
+ .map(({ meta }) => meta)
30
+ .sort(sort),
31
+ [],
32
+ );
33
+ const available = useMemo(() => pluginContext.available.filter(({ id }) => !enabled.includes(id)).sort(sort), []);
34
+ const recommended = available.filter((meta) => !meta.tags?.includes('experimental'));
35
+ const experimental = available.filter((meta) => meta.tags?.includes('experimental'));
36
+
37
+ const handleChange = (id: string, enabled: boolean) => {
38
+ setPlugin(id, enabled);
39
+ void dispatch({
40
+ action: ObservabilityAction.SEND_EVENT,
41
+ data: {
42
+ name: 'plugins.toggle',
43
+ properties: { plugin: id, enabled },
44
+ },
45
+ });
46
+ };
47
+
48
+ const handleReload = () => {
49
+ window.location.reload();
50
+ };
51
+
52
+ return (
53
+ <>
54
+ <SettingsValue label={t('settings show experimental label')}>
55
+ <Input.Switch
56
+ data-testid='pluginSettings.experimental'
57
+ checked={settings.experimental}
58
+ onCheckedChange={(checked) => (settings.experimental = !!checked)}
59
+ />
60
+ </SettingsValue>
61
+
62
+ <Section label={t('settings section installed label')}>
63
+ <PluginList
64
+ plugins={installed}
65
+ loaded={plugins.map(({ meta }) => meta.id)}
66
+ enabled={enabled}
67
+ onChange={handleChange}
68
+ onReload={handleReload}
69
+ />
70
+ </Section>
71
+
72
+ <Section label={t('settings section recommended label')}>
73
+ <PluginList
74
+ plugins={recommended}
75
+ loaded={plugins.map(({ meta }) => meta.id)}
76
+ enabled={enabled}
77
+ onChange={handleChange}
78
+ onReload={handleReload}
79
+ />
80
+ </Section>
81
+
82
+ {settings.experimental && (
83
+ <Section label={t('settings section experimental label')}>
84
+ <PluginList
85
+ plugins={experimental}
86
+ loaded={plugins.map(({ meta }) => meta.id)}
87
+ enabled={enabled}
88
+ onChange={handleChange}
89
+ onReload={handleReload}
90
+ />
91
+ </Section>
92
+ )}
93
+ </>
94
+ );
95
+ };
96
+
97
+ const Section = ({ label, children }: PropsWithChildren<{ label: string }>) => {
98
+ return (
99
+ <div>
100
+ <h2 className='py-2 text-sm text-neutral-500'>{label}</h2>
101
+ {children}
102
+ </div>
103
+ );
104
+ };
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export * from './PluginList';
6
+ export * from './PluginSettings';
package/src/index.ts ADDED
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { RegistryPlugin } from './RegistryPlugin';
6
+
7
+ export default RegistryPlugin;
8
+
9
+ export * from './RegistryPlugin';
package/src/meta.ts ADDED
@@ -0,0 +1,10 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export const REGISTRY_PLUGIN = 'dxos.org/plugin/registry';
6
+
7
+ export default {
8
+ id: REGISTRY_PLUGIN,
9
+ name: 'Plugins',
10
+ };
@@ -0,0 +1,13 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { expect } from 'chai';
6
+
7
+ import { describe, test } from '@dxos/test';
8
+
9
+ describe('Sanity', () => {
10
+ test('Sanity', async () => {
11
+ expect(true).to.be.true;
12
+ });
13
+ });
@@ -0,0 +1,21 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { REGISTRY_PLUGIN } from './meta';
6
+
7
+ export default [
8
+ {
9
+ 'en-US': {
10
+ [REGISTRY_PLUGIN]: {
11
+ 'plugin name': 'Registry',
12
+ 'reload required message': 'Reload required.',
13
+ 'settings show experimental label': 'Show experimental plugins',
14
+ 'settings section installed label': 'Installed',
15
+ 'settings section recommended label': 'Recommended',
16
+ 'settings section experimental label': 'Experimental',
17
+ 'home page label': 'Home page',
18
+ },
19
+ },
20
+ },
21
+ ];