@nextcloud/files 4.0.0-beta.9 → 4.0.0-rc.1
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 +117 -0
- package/dist/actions/fileAction.d.ts +4 -23
- package/dist/actions/fileListAction.d.ts +3 -15
- package/dist/actions/index.d.ts +4 -3
- package/dist/filters/functions.d.ts +20 -0
- package/dist/filters/index.d.ts +7 -0
- package/dist/{fileListFilters.d.ts → filters/listFilters.d.ts} +1 -20
- package/dist/headers/functions.d.ts +11 -0
- package/dist/headers/index.d.ts +3 -0
- package/dist/{fileListHeaders.d.ts → headers/listHeaders.d.ts} +5 -15
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +111 -781
- package/dist/index.mjs.map +1 -1
- package/dist/navigation/navigation.d.ts +2 -2
- package/dist/registry.d.ts +28 -0
- package/dist/sidebar/SidebarTab.d.ts +23 -7
- package/package.json +5 -6
package/README.md
CHANGED
|
@@ -53,6 +53,123 @@ const myEntry: Entry = {
|
|
|
53
53
|
addNewFileMenuEntry(myEntry)
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
#### Register a sidebar tab
|
|
57
|
+
|
|
58
|
+
It is possible to provide your own sidebar tabs for the files app.
|
|
59
|
+
For this you need to create a [custom web component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components),
|
|
60
|
+
which can either be done without any framework by using vanilla JavaScript but is also [possible with Vue](https://vuejs.org/guide/extras/web-components#building-custom-elements-with-vue).
|
|
61
|
+
|
|
62
|
+
This example will make use of the Vue framework for building a sidebar tab as this is the official UI framework for Nextcloud apps.
|
|
63
|
+
|
|
64
|
+
The sidebar tab consists of two parts:
|
|
65
|
+
1. The web component which will be rendered within the sidebar.
|
|
66
|
+
2. A definition object that provides all information needed by the files app.
|
|
67
|
+
|
|
68
|
+
##### SidebarTab definition object
|
|
69
|
+
|
|
70
|
+
This object provides the requires information such as:
|
|
71
|
+
- The order (to ensure a consistent tabs order)
|
|
72
|
+
- The display name for the tab navigation
|
|
73
|
+
- An icon, to be used in the tab navigation
|
|
74
|
+
- A callback to check if the sidebar tab is enabled for the current node shown in the sidebar.
|
|
75
|
+
- The web component tag name
|
|
76
|
+
|
|
77
|
+
The registration must happen in an `initScript`.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import type { ISidebarTab } from '@nextcloud/files'
|
|
81
|
+
|
|
82
|
+
import { getSidebar } from '@nextcloud/files'
|
|
83
|
+
import { t } from '@nextcloud/l10n'
|
|
84
|
+
|
|
85
|
+
const MyTab: ISidebarTab = {
|
|
86
|
+
// Unique ID of the tab
|
|
87
|
+
id: 'my_app',
|
|
88
|
+
|
|
89
|
+
// The display name in the tab list
|
|
90
|
+
displayName: t('my_app', 'Sharing'),
|
|
91
|
+
|
|
92
|
+
// Pass an SVG (string) to be used as the tab button icon
|
|
93
|
+
iconSvgInline: '<svg>...</svg>',
|
|
94
|
+
|
|
95
|
+
// Lower values mean a more prominent position
|
|
96
|
+
order: 50,
|
|
97
|
+
|
|
98
|
+
// The tag name of the web component
|
|
99
|
+
tagName: 'my_app-files_sidebar_tab',
|
|
100
|
+
|
|
101
|
+
// Optional callback to check if the tab should be shown
|
|
102
|
+
enabled({ node, folder, view }) {
|
|
103
|
+
// you can disable this tab for some cased based on:
|
|
104
|
+
// - node: The node the sidebar was opened for
|
|
105
|
+
// - folder: The folder currently shown in the files app
|
|
106
|
+
// - view: The currently active files view
|
|
107
|
+
return true
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
// Optional, recommended to large tabs
|
|
111
|
+
async onInit() {
|
|
112
|
+
// This is called when the tab is about to be activated the first time.
|
|
113
|
+
// So this can be used to do some initialization or even to define the web component.
|
|
114
|
+
},
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// the you need to register it in the sidebar
|
|
118
|
+
getSidebar()
|
|
119
|
+
.registerTab(MyTab)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
##### SidebarTab web component
|
|
123
|
+
|
|
124
|
+
The web component needs to have those properties:
|
|
125
|
+
- node of type `INode`
|
|
126
|
+
- folder of type `IFolder`
|
|
127
|
+
- view of type `IView`
|
|
128
|
+
- active of type `boolean`
|
|
129
|
+
|
|
130
|
+
When using Vue you need to first create the Vue component:
|
|
131
|
+
|
|
132
|
+
```vue
|
|
133
|
+
<script setup lang="ts">
|
|
134
|
+
import type { IFolder, INode, IView } from '@nextcloud/files'
|
|
135
|
+
|
|
136
|
+
defineProps<{
|
|
137
|
+
node: INode
|
|
138
|
+
folder: IFolder
|
|
139
|
+
view: IView
|
|
140
|
+
active: boolean
|
|
141
|
+
}>()
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
<template>
|
|
145
|
+
<div>
|
|
146
|
+
<div>Showing node: {{ node.source }}</div>
|
|
147
|
+
<div>... in folder: {{ folder.source }}</div>
|
|
148
|
+
<div>... with view: {{ view.id }}</div>
|
|
149
|
+
</div>
|
|
150
|
+
</template>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Which then can be wrapped in a web component and registered.
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { getSidebar } from '@nextcloud/files'
|
|
157
|
+
import { defineAsyncComponent, defineCustomElement } from 'vue'
|
|
158
|
+
|
|
159
|
+
getSidebar().registerTab({
|
|
160
|
+
// ...
|
|
161
|
+
|
|
162
|
+
tagName: `my_app-files_sidebar_tab`,
|
|
163
|
+
|
|
164
|
+
onInit() {
|
|
165
|
+
const MySidebarTab = defineAsyncComponent(() => import('./views/MySidebarTab.vue'))
|
|
166
|
+
// make sure to disable the shadow root to allow theming with Nextcloud provided global styles.
|
|
167
|
+
const MySidebarTabWebComponent = defineCustomElement(MySidebarTab, { shadowRoot: false })
|
|
168
|
+
customElements.define('my_app-files_sidebar_tab', MySidebarTabWebComponent)
|
|
169
|
+
},
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
56
173
|
### WebDAV
|
|
57
174
|
The `getClient` exported function returns a webDAV client that's a wrapper around [webdav's webDAV client](https://www.npmjs.com/package/webdav).
|
|
58
175
|
All its methods are available here.
|
|
@@ -31,7 +31,7 @@ export interface IHotkeyConfig {
|
|
|
31
31
|
*/
|
|
32
32
|
alt?: true;
|
|
33
33
|
}
|
|
34
|
-
export interface
|
|
34
|
+
export interface IFileAction {
|
|
35
35
|
/** Unique ID */
|
|
36
36
|
id: string;
|
|
37
37
|
/** Translatable string displayed in the menu */
|
|
@@ -97,32 +97,13 @@ export interface FileActionData {
|
|
|
97
97
|
*/
|
|
98
98
|
renderInline?: (context: ActionContextSingle) => Promise<HTMLElement | null>;
|
|
99
99
|
}
|
|
100
|
-
export declare class FileAction {
|
|
101
|
-
private _action;
|
|
102
|
-
constructor(action: FileActionData);
|
|
103
|
-
get id(): string;
|
|
104
|
-
get displayName(): (context: ActionContext) => string;
|
|
105
|
-
get title(): ((context: ActionContext) => string) | undefined;
|
|
106
|
-
get iconSvgInline(): (context: ActionContext) => string;
|
|
107
|
-
get enabled(): ((context: ActionContext) => boolean) | undefined;
|
|
108
|
-
get exec(): (context: ActionContextSingle) => Promise<boolean | null>;
|
|
109
|
-
get execBatch(): ((context: ActionContext) => Promise<(boolean | null)[]>) | undefined;
|
|
110
|
-
get hotkey(): IHotkeyConfig | undefined;
|
|
111
|
-
get order(): number | undefined;
|
|
112
|
-
get parent(): string | undefined;
|
|
113
|
-
get default(): TDefaultType | undefined;
|
|
114
|
-
get destructive(): boolean | undefined;
|
|
115
|
-
get inline(): ((context: ActionContextSingle) => boolean) | undefined;
|
|
116
|
-
get renderInline(): ((context: ActionContextSingle) => Promise<HTMLElement | null>) | undefined;
|
|
117
|
-
private validateAction;
|
|
118
|
-
}
|
|
119
100
|
/**
|
|
120
101
|
* Register a new file action.
|
|
121
102
|
*
|
|
122
103
|
* @param action - The file list action to register
|
|
123
104
|
*/
|
|
124
|
-
export declare function registerFileAction(action:
|
|
105
|
+
export declare function registerFileAction(action: IFileAction): void;
|
|
125
106
|
/**
|
|
126
|
-
*
|
|
107
|
+
* Get all registered file actions.
|
|
127
108
|
*/
|
|
128
|
-
export declare function getFileActions():
|
|
109
|
+
export declare function getFileActions(): IFileAction[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ViewActionContext } from '../types.ts';
|
|
2
|
-
interface
|
|
2
|
+
export interface IFileListAction {
|
|
3
3
|
/** Unique ID */
|
|
4
4
|
id: string;
|
|
5
5
|
/** Translated name of the action */
|
|
@@ -21,25 +21,13 @@ interface FileListActionData {
|
|
|
21
21
|
*/
|
|
22
22
|
exec: (context: ViewActionContext) => Promise<boolean | null>;
|
|
23
23
|
}
|
|
24
|
-
export declare class FileListAction {
|
|
25
|
-
private _action;
|
|
26
|
-
constructor(action: FileListActionData);
|
|
27
|
-
get id(): string;
|
|
28
|
-
get displayName(): (context: ViewActionContext) => string;
|
|
29
|
-
get iconSvgInline(): ((context: ViewActionContext) => string) | undefined;
|
|
30
|
-
get order(): number;
|
|
31
|
-
get enabled(): ((context: ViewActionContext) => boolean) | undefined;
|
|
32
|
-
get exec(): (context: ViewActionContext) => Promise<boolean | null>;
|
|
33
|
-
private validateAction;
|
|
34
|
-
}
|
|
35
24
|
/**
|
|
36
25
|
* Register a new file list action.
|
|
37
26
|
*
|
|
38
27
|
* @param action - The file list action to register
|
|
39
28
|
*/
|
|
40
|
-
export declare function registerFileListAction(action:
|
|
29
|
+
export declare function registerFileListAction(action: IFileListAction): void;
|
|
41
30
|
/**
|
|
42
31
|
* Get all currently registered file list actions.
|
|
43
32
|
*/
|
|
44
|
-
export declare function getFileListActions():
|
|
45
|
-
export {};
|
|
33
|
+
export declare function getFileListActions(): IFileListAction[];
|
package/dist/actions/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
1
|
+
export type { IFileAction, IHotkeyConfig } from './fileAction.ts';
|
|
2
|
+
export type { IFileListAction } from './fileListAction.ts';
|
|
3
|
+
export { DefaultType, getFileActions, registerFileAction } from './fileAction.ts';
|
|
4
|
+
export { getFileListActions, registerFileListAction } from './fileListAction.ts';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IFileListFilter } from './listFilters.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Register a new filter on the file list
|
|
4
|
+
*
|
|
5
|
+
* This only must be called once to register the filter,
|
|
6
|
+
* when the filter state changes you need to call `filterUpdated` on the filter instead.
|
|
7
|
+
*
|
|
8
|
+
* @param filter The filter to register on the file list
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerFileListFilter(filter: IFileListFilter): void;
|
|
11
|
+
/**
|
|
12
|
+
* Remove a registered filter from the file list
|
|
13
|
+
*
|
|
14
|
+
* @param filterId The unique ID of the filter to remove
|
|
15
|
+
*/
|
|
16
|
+
export declare function unregisterFileListFilter(filterId: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Get all registered file list filters
|
|
19
|
+
*/
|
|
20
|
+
export declare function getFileListFilters(): IFileListFilter[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
|
3
|
+
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
*/
|
|
5
|
+
export type * from './listFilters.ts';
|
|
6
|
+
export { getFileListFilters, registerFileListFilter, unregisterFileListFilter, } from './functions.ts';
|
|
7
|
+
export { FileListFilter } from './listFilters.ts';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INode } from '
|
|
1
|
+
import { INode } from '../node/index.ts';
|
|
2
2
|
import { TypedEventTarget } from 'typescript-event-target';
|
|
3
3
|
/**
|
|
4
4
|
* Active filters can provide one or more "chips" to show the currently active state.
|
|
@@ -106,23 +106,4 @@ export declare class FileListFilter extends TypedEventTarget<IFileListFilterEven
|
|
|
106
106
|
protected updateChips(chips: IFileListFilterChip[]): void;
|
|
107
107
|
protected filterUpdated(): void;
|
|
108
108
|
}
|
|
109
|
-
/**
|
|
110
|
-
* Register a new filter on the file list
|
|
111
|
-
*
|
|
112
|
-
* This only must be called once to register the filter,
|
|
113
|
-
* when the filter state changes you need to call `filterUpdated` on the filter instead.
|
|
114
|
-
*
|
|
115
|
-
* @param filter The filter to register on the file list
|
|
116
|
-
*/
|
|
117
|
-
export declare function registerFileListFilter(filter: IFileListFilter): void;
|
|
118
|
-
/**
|
|
119
|
-
* Remove a registered filter from the file list
|
|
120
|
-
*
|
|
121
|
-
* @param filterId The unique ID of the filter to remove
|
|
122
|
-
*/
|
|
123
|
-
export declare function unregisterFileListFilter(filterId: string): void;
|
|
124
|
-
/**
|
|
125
|
-
* Get all registered file list filters
|
|
126
|
-
*/
|
|
127
|
-
export declare function getFileListFilters(): IFileListFilter[];
|
|
128
109
|
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Header } from './listHeaders.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Register a new file list header.
|
|
4
|
+
*
|
|
5
|
+
* @param header - The header to register
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerFileListHeaders(header: Header): void;
|
|
8
|
+
/**
|
|
9
|
+
* Get all currently registered file list headers.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getFileListHeaders(): Header[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IView } from '
|
|
2
|
-
import { IFolder } from '
|
|
1
|
+
import { IView } from '../navigation/view.ts';
|
|
2
|
+
import { IFolder } from '../node/folder.ts';
|
|
3
3
|
export interface HeaderData {
|
|
4
4
|
/** Unique ID */
|
|
5
5
|
id: string;
|
|
@@ -8,9 +8,9 @@ export interface HeaderData {
|
|
|
8
8
|
/** Condition wether this header is shown or not */
|
|
9
9
|
enabled?: (folder: IFolder, view: IView) => boolean;
|
|
10
10
|
/** Executed when file list is initialized */
|
|
11
|
-
render
|
|
11
|
+
render(el: HTMLElement, folder: IFolder, view: IView): void;
|
|
12
12
|
/** Executed when root folder changed */
|
|
13
|
-
updated(folder: IFolder, view: IView):
|
|
13
|
+
updated(folder: IFolder, view: IView): void;
|
|
14
14
|
}
|
|
15
15
|
export declare class Header {
|
|
16
16
|
private _header;
|
|
@@ -19,16 +19,6 @@ export declare class Header {
|
|
|
19
19
|
get order(): number;
|
|
20
20
|
get enabled(): ((folder: IFolder, view: IView) => boolean) | undefined;
|
|
21
21
|
get render(): (el: HTMLElement, folder: IFolder, view: IView) => void;
|
|
22
|
-
get updated(): (folder: IFolder, view: IView) =>
|
|
22
|
+
get updated(): (folder: IFolder, view: IView) => void;
|
|
23
23
|
private validateHeader;
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Register a new file list header.
|
|
27
|
-
*
|
|
28
|
-
* @param header - The header to register
|
|
29
|
-
*/
|
|
30
|
-
export declare function registerFileListHeaders(header: Header): void;
|
|
31
|
-
/**
|
|
32
|
-
* Get all currently registered file list headers.
|
|
33
|
-
*/
|
|
34
|
-
export declare function getFileListHeaders(): Header[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export type * from './types.ts';
|
|
2
2
|
export * from './actions/index.ts';
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
3
|
+
export * from './filters/index.ts';
|
|
4
|
+
export * from './headers/index.ts';
|
|
5
5
|
export * from './navigation/index.ts';
|
|
6
6
|
export * from './newMenu/index.ts';
|
|
7
7
|
export * from './node/index.ts';
|
|
8
8
|
export * from './permissions.ts';
|
|
9
9
|
export * from './sidebar/index.ts';
|
|
10
10
|
export * from './utils/index.ts';
|
|
11
|
+
export { getFilesRegistry } from './registry.ts';
|