@linagora/twake-mui 17.1.0 → 18.0.0
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/CHANGELOG.md +19 -0
- package/dist/components/ActionsMenu/Actions/download.d.ts +1 -3
- package/dist/components/ActionsMenu/Actions/download.js +1 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +4 -0
- package/dist/providers/ConfirmDialogProvider/ConfirmDialogProvider.stories.d.ts +7 -0
- package/dist/providers/ConfirmDialogProvider/ConfirmDialogProvider.stories.js +31 -0
- package/dist/providers/ConfirmDialogProvider/index.d.ts +6 -0
- package/dist/providers/ConfirmDialogProvider/index.js +15 -0
- package/dist/providers/ConfirmDialogProvider/useConfirmDialog.d.ts +8 -0
- package/dist/providers/ConfirmDialogProvider/useConfirmDialog.js +9 -0
- package/dist/providers/SelectionProvider/SelectionProvider.stories.d.ts +6 -0
- package/dist/providers/SelectionProvider/SelectionProvider.stories.js +25 -0
- package/dist/providers/SelectionProvider/index.d.ts +7 -0
- package/dist/providers/SelectionProvider/index.js +28 -0
- package/dist/providers/SelectionProvider/useSelection.d.ts +13 -0
- package/dist/providers/SelectionProvider/useSelection.js +9 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# @linagora/twake-mui [18.0.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@17.1.0...@linagora/twake-mui@18.0.0) (2026-10-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
* feat(twake-mui)!: Remove encryptedUrl from the download action ([bf7480f](https://github.com/linagora/twake-ui/commit/bf7480f37d89b166850cc50fdf566b421eef00cb))
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **twake-mui:** Migrate ConfirmDialogProvider from cozy-ui ([eb9de6d](https://github.com/linagora/twake-ui/commit/eb9de6d3ac69b83455d127bb44f826f26af9e2ec))
|
|
10
|
+
* **twake-mui:** Migrate SelectionProvider from cozy-ui ([50b91f4](https://github.com/linagora/twake-ui/commit/50b91f446ca91c498514debe1034010db2ac5557))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* `download` no longer accepts `encryptedUrl` and
|
|
16
|
+
`DownloadFileOptions` no longer has `url`. Apps that downloaded an
|
|
17
|
+
encrypted file through this option must pass its URL to their own
|
|
18
|
+
`downloadFile` implementation instead.
|
|
19
|
+
|
|
1
20
|
# @linagora/twake-mui [17.1.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@17.0.0...@linagora/twake-mui@17.1.0) (2026-10-22)
|
|
2
21
|
|
|
3
22
|
|
|
@@ -3,13 +3,11 @@ import { Action, ActionDocument } from '../types';
|
|
|
3
3
|
export interface DownloadFileOptions<Client> {
|
|
4
4
|
client: Client;
|
|
5
5
|
file: ActionDocument;
|
|
6
|
-
url?: string;
|
|
7
6
|
webviewIntent?: WebviewService;
|
|
8
7
|
driveId?: string;
|
|
9
8
|
}
|
|
10
9
|
export interface DownloadActionOptions<Client> {
|
|
11
10
|
client: Client;
|
|
12
|
-
encryptedUrl?: string;
|
|
13
11
|
downloadFile: (options: DownloadFileOptions<Client>) => unknown;
|
|
14
12
|
}
|
|
15
|
-
export declare const download: <Client>({ client,
|
|
13
|
+
export declare const download: <Client>({ client, downloadFile }: DownloadActionOptions<Client>) => Action;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Download } from '@linagora/twake-icons';
|
|
2
2
|
import { makeAction } from './makeAction';
|
|
3
3
|
import { getActionsI18n } from '../locales';
|
|
4
|
-
export const download = ({ client,
|
|
4
|
+
export const download = ({ client, downloadFile }) => {
|
|
5
5
|
const { t } = getActionsI18n();
|
|
6
6
|
return makeAction({
|
|
7
7
|
name: 'download',
|
|
@@ -10,7 +10,6 @@ export const download = ({ client, encryptedUrl, downloadFile }) => {
|
|
|
10
10
|
action: (docs, { webviewIntent, driveId }) => downloadFile({
|
|
11
11
|
client,
|
|
12
12
|
file: docs[0],
|
|
13
|
-
url: encryptedUrl,
|
|
14
13
|
webviewIntent,
|
|
15
14
|
driveId
|
|
16
15
|
})
|
package/dist/index.d.ts
CHANGED
|
@@ -78,10 +78,12 @@ export { default as NestedSelectModal } from './components/NestedSelect/NestedSe
|
|
|
78
78
|
export { default as NestedSelectBottomSheet } from './components/NestedSelect/NestedSelectBottomSheet';
|
|
79
79
|
export { default as NestedSelectResponsive } from './components/NestedSelect/NestedSelectResponsive';
|
|
80
80
|
export { default as PointerAlert } from './components/PointerAlert';
|
|
81
|
-
export type { AlertProviderProps } from './providers/AlertProvider';
|
|
82
|
-
export type { AlertContextValue, ShowAlert, ShowAlertOptions } from './providers/AlertProvider/useAlert';
|
|
83
81
|
export { default as AlertProvider } from './providers/AlertProvider';
|
|
84
82
|
export { useAlert } from './providers/AlertProvider/useAlert';
|
|
83
|
+
export { default as ConfirmDialogProvider } from './providers/ConfirmDialogProvider';
|
|
84
|
+
export { useConfirmDialog } from './providers/ConfirmDialogProvider/useConfirmDialog';
|
|
85
|
+
export { default as SelectionProvider } from './providers/SelectionProvider';
|
|
86
|
+
export { useSelection } from './providers/SelectionProvider/useSelection';
|
|
85
87
|
export { default as ProgressionBanner } from './components/ProgressionBanner';
|
|
86
88
|
export { default as Tabs } from './components/Tabs';
|
|
87
89
|
export { default as Switch } from './components/Switch';
|
|
@@ -160,6 +162,12 @@ export type { DialogCloseButtonProps } from './components/Dialogs/DialogCloseBut
|
|
|
160
162
|
export type { DialogBackButtonProps } from './components/Dialogs/DialogBackButton';
|
|
161
163
|
export type { DialogCloseReason, DialogLayout, DialogLayoutComponentsProps, DialogLayoutProps } from './components/Dialogs/useDialogLayout';
|
|
162
164
|
export type { PointerAlertProps, PointerAlertDirection } from './components/PointerAlert';
|
|
165
|
+
export type { AlertProviderProps } from './providers/AlertProvider';
|
|
166
|
+
export type { AlertContextValue, ShowAlert, ShowAlertOptions } from './providers/AlertProvider/useAlert';
|
|
167
|
+
export type { ConfirmDialogProviderProps } from './providers/ConfirmDialogProvider';
|
|
168
|
+
export type { ConfirmDialogContextValue, ShowConfirmDialogOptions } from './providers/ConfirmDialogProvider/useConfirmDialog';
|
|
169
|
+
export type { SelectionProviderProps } from './providers/SelectionProvider';
|
|
170
|
+
export type { SelectionContextValue } from './providers/SelectionProvider/useSelection';
|
|
163
171
|
export type { ProgressionBannerProps } from './components/ProgressionBanner';
|
|
164
172
|
export type { EmptyProps, EmptyIconSize, EmptyComponentsProps } from './components/Empty';
|
|
165
173
|
export type { DropdownButtonProps } from './components/DropdownButton';
|
package/dist/index.js
CHANGED
|
@@ -83,6 +83,10 @@ export { default as NestedSelectResponsive } from './components/NestedSelect/Nes
|
|
|
83
83
|
export { default as PointerAlert } from './components/PointerAlert';
|
|
84
84
|
export { default as AlertProvider } from './providers/AlertProvider';
|
|
85
85
|
export { useAlert } from './providers/AlertProvider/useAlert';
|
|
86
|
+
export { default as ConfirmDialogProvider } from './providers/ConfirmDialogProvider';
|
|
87
|
+
export { useConfirmDialog } from './providers/ConfirmDialogProvider/useConfirmDialog';
|
|
88
|
+
export { default as SelectionProvider } from './providers/SelectionProvider';
|
|
89
|
+
export { useSelection } from './providers/SelectionProvider/useSelection';
|
|
86
90
|
export { default as ProgressionBanner } from './components/ProgressionBanner';
|
|
87
91
|
export { default as Tabs } from './components/Tabs';
|
|
88
92
|
export { default as Switch } from './components/Switch';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { ShowConfirmDialogOptions } from './useConfirmDialog';
|
|
3
|
+
type StoryArgs = Pick<ShowConfirmDialogOptions, 'title' | 'content'>;
|
|
4
|
+
declare const meta: Meta<StoryArgs>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type Story = StoryObj<typeof meta>;
|
|
7
|
+
export declare const Default: Story;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Button } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ConfirmDialogProvider from './index';
|
|
4
|
+
import { useConfirmDialog } from './useConfirmDialog';
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'ConfirmDialogProvider',
|
|
7
|
+
parameters: { layout: 'centered' },
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
argTypes: {
|
|
10
|
+
title: { control: 'text' },
|
|
11
|
+
content: { control: 'text' }
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
const ShowConfirmDialogButton = ({ args }) => {
|
|
16
|
+
const { showConfirmDialog, closeConfirmDialog } = useConfirmDialog();
|
|
17
|
+
return (React.createElement(Button, { onClick: () => showConfirmDialog({
|
|
18
|
+
...args,
|
|
19
|
+
actions: (React.createElement(React.Fragment, null,
|
|
20
|
+
React.createElement(Button, { variant: "outlined", onClick: closeConfirmDialog }, "Cancel"),
|
|
21
|
+
React.createElement(Button, null, "Ok")))
|
|
22
|
+
}) }, "Show ConfirmDialog"));
|
|
23
|
+
};
|
|
24
|
+
export const Default = {
|
|
25
|
+
args: {
|
|
26
|
+
title: 'Title of the ConfirmDialog',
|
|
27
|
+
content: 'Content of the ConfirmDialog'
|
|
28
|
+
},
|
|
29
|
+
render: args => (React.createElement(ConfirmDialogProvider, null,
|
|
30
|
+
React.createElement(ShowConfirmDialogButton, { args: args })))
|
|
31
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import { ConfirmDialogContext } from './useConfirmDialog';
|
|
3
|
+
import ConfirmDialog from '../../components/Dialogs/ConfirmDialog';
|
|
4
|
+
const ConfirmDialogProvider = ({ children }) => {
|
|
5
|
+
const [state, setState] = useState({ open: false });
|
|
6
|
+
const { open, ...confirmDialogProps } = state;
|
|
7
|
+
const value = useMemo(() => ({
|
|
8
|
+
showConfirmDialog: (options) => setState({ ...options, open: true }),
|
|
9
|
+
closeConfirmDialog: () => setState(current => ({ ...current, open: false }))
|
|
10
|
+
}), []);
|
|
11
|
+
return (React.createElement(ConfirmDialogContext.Provider, { value: value },
|
|
12
|
+
children,
|
|
13
|
+
open && (React.createElement(ConfirmDialog, { open: true, onClose: value.closeConfirmDialog, ...confirmDialogProps }))));
|
|
14
|
+
};
|
|
15
|
+
export default ConfirmDialogProvider;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ConfirmDialogProps } from '../../components/Dialogs/ConfirmDialog';
|
|
2
|
+
export type ShowConfirmDialogOptions = Omit<ConfirmDialogProps, 'open'>;
|
|
3
|
+
export interface ConfirmDialogContextValue {
|
|
4
|
+
showConfirmDialog: (options: ShowConfirmDialogOptions) => void;
|
|
5
|
+
closeConfirmDialog: () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const ConfirmDialogContext: import("react").Context<ConfirmDialogContextValue | null>;
|
|
8
|
+
export declare const useConfirmDialog: () => ConfirmDialogContextValue;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export const ConfirmDialogContext = createContext(null);
|
|
3
|
+
export const useConfirmDialog = () => {
|
|
4
|
+
const context = useContext(ConfirmDialogContext);
|
|
5
|
+
if (!context) {
|
|
6
|
+
throw new Error('useConfirmDialog must be used within a ConfirmDialogProvider');
|
|
7
|
+
}
|
|
8
|
+
return context;
|
|
9
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Button, Stack, Typography } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import SelectionProvider from './index';
|
|
4
|
+
import { useSelection } from './useSelection';
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'SelectionProvider',
|
|
7
|
+
component: SelectionProvider,
|
|
8
|
+
parameters: { layout: 'centered' },
|
|
9
|
+
tags: ['autodocs']
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
const SelectionExample = () => {
|
|
13
|
+
const { selectedItemsId, addSelectedItem, removeSelectedItem } = useSelection();
|
|
14
|
+
return (React.createElement(Stack, { spacing: 1 },
|
|
15
|
+
React.createElement(Typography, null,
|
|
16
|
+
"selectedItemsId : ",
|
|
17
|
+
JSON.stringify(selectedItemsId)),
|
|
18
|
+
React.createElement(Stack, { direction: "row", spacing: 1 },
|
|
19
|
+
React.createElement(Button, { onClick: () => addSelectedItem('01') }, "Add Item"),
|
|
20
|
+
React.createElement(Button, { onClick: () => removeSelectedItem('01') }, "Remove Item"))));
|
|
21
|
+
};
|
|
22
|
+
export const Default = {
|
|
23
|
+
render: () => (React.createElement(SelectionProvider, null,
|
|
24
|
+
React.createElement(SelectionExample, null)))
|
|
25
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
export interface SelectionProviderProps {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
}
|
|
5
|
+
/** Shares the ids of the selected items with its children */
|
|
6
|
+
declare const SelectionProvider: React.FC<SelectionProviderProps>;
|
|
7
|
+
export default SelectionProvider;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { SelectionContext } from './useSelection';
|
|
3
|
+
/** Shares the ids of the selected items with its children */
|
|
4
|
+
const SelectionProvider = ({ children }) => {
|
|
5
|
+
const [selectedItemsId, setSelectedItemsId] = useState([]);
|
|
6
|
+
const isSelectedItem = (itemId) => selectedItemsId.includes(itemId);
|
|
7
|
+
const addSelectedItem = (itemId) => setSelectedItemsId(current => [...current, itemId]);
|
|
8
|
+
const removeSelectedItem = (itemId) => setSelectedItemsId(current => current.filter(id => id !== itemId));
|
|
9
|
+
const toggleSelectedItem = (itemId) => isSelectedItem(itemId)
|
|
10
|
+
? removeSelectedItem(itemId)
|
|
11
|
+
: addSelectedItem(itemId);
|
|
12
|
+
const selectAll = (itemsId) => setSelectedItemsId(itemsId);
|
|
13
|
+
const unselectAll = () => setSelectedItemsId([]);
|
|
14
|
+
const isSelectedAllItems = (itemsId) => itemsId.length === selectedItemsId.length && itemsId.every(isSelectedItem);
|
|
15
|
+
const toggleSelectAllItems = (itemsId) => isSelectedAllItems(itemsId) ? unselectAll() : selectAll(itemsId);
|
|
16
|
+
return (React.createElement(SelectionContext.Provider, { value: {
|
|
17
|
+
selectedItemsId,
|
|
18
|
+
addSelectedItem,
|
|
19
|
+
removeSelectedItem,
|
|
20
|
+
toggleSelectedItem,
|
|
21
|
+
selectAll,
|
|
22
|
+
toggleSelectAllItems,
|
|
23
|
+
isSelectedItem,
|
|
24
|
+
isSelectionEnabled: selectedItemsId.length > 0,
|
|
25
|
+
isSelectedAllItems
|
|
26
|
+
} }, children));
|
|
27
|
+
};
|
|
28
|
+
export default SelectionProvider;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SelectionContextValue {
|
|
2
|
+
selectedItemsId: string[];
|
|
3
|
+
addSelectedItem: (itemId: string) => void;
|
|
4
|
+
removeSelectedItem: (itemId: string) => void;
|
|
5
|
+
toggleSelectedItem: (itemId: string) => void;
|
|
6
|
+
selectAll: (itemsId: string[]) => void;
|
|
7
|
+
toggleSelectAllItems: (itemsId: string[]) => void;
|
|
8
|
+
isSelectedItem: (itemId: string) => boolean;
|
|
9
|
+
isSelectionEnabled: boolean;
|
|
10
|
+
isSelectedAllItems: (itemsId: string[]) => boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const SelectionContext: import("react").Context<SelectionContextValue | null>;
|
|
13
|
+
export declare const useSelection: () => SelectionContextValue;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export const SelectionContext = createContext(null);
|
|
3
|
+
export const useSelection = () => {
|
|
4
|
+
const context = useContext(SelectionContext);
|
|
5
|
+
if (!context) {
|
|
6
|
+
throw new Error('useSelection must be used within a SelectionProvider');
|
|
7
|
+
}
|
|
8
|
+
return context;
|
|
9
|
+
};
|