@linagora/twake-mui 17.1.0 → 18.1.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 CHANGED
@@ -1,3 +1,29 @@
1
+ # @linagora/twake-mui [18.1.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@18.0.0...@linagora/twake-mui@18.1.0) (2026-10-22)
2
+
3
+
4
+ ### Features
5
+
6
+ * **twake-mui:** Lighten the Backdrop to 12% black in light theme ([48ea234](https://github.com/linagora/twake-ui/commit/48ea234e6ccd1d69cc6164a291e0d5c4976c1897))
7
+
8
+ # @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)
9
+
10
+
11
+ * feat(twake-mui)!: Remove encryptedUrl from the download action ([bf7480f](https://github.com/linagora/twake-ui/commit/bf7480f37d89b166850cc50fdf566b421eef00cb))
12
+
13
+
14
+ ### Features
15
+
16
+ * **twake-mui:** Migrate ConfirmDialogProvider from cozy-ui ([eb9de6d](https://github.com/linagora/twake-ui/commit/eb9de6d3ac69b83455d127bb44f826f26af9e2ec))
17
+ * **twake-mui:** Migrate SelectionProvider from cozy-ui ([50b91f4](https://github.com/linagora/twake-ui/commit/50b91f446ca91c498514debe1034010db2ac5557))
18
+
19
+
20
+ ### BREAKING CHANGES
21
+
22
+ * `download` no longer accepts `encryptedUrl` and
23
+ `DownloadFileOptions` no longer has `url`. Apps that downloaded an
24
+ encrypted file through this option must pass its URL to their own
25
+ `downloadFile` implementation instead.
26
+
1
27
  # @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
28
 
3
29
 
@@ -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, encryptedUrl, downloadFile }: DownloadActionOptions<Client>) => Action;
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, encryptedUrl, downloadFile }) => {
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
  })
@@ -1,2 +1,2 @@
1
1
  import { Theme } from '@mui/material/styles';
2
- export declare const NavBadge: import("@emotion/styled").StyledComponent<import("@mui/material").BadgeOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "style" | "color" | "className" | "max" | "children" | "classes" | "sx" | "variant" | "slotProps" | "slots" | "anchorOrigin" | "badgeContent" | "invisible" | "overlap" | "showZero"> & import("@mui/system").MUIStyledCommonProps<Theme>, {}, {}>;
2
+ export declare const NavBadge: import("@emotion/styled").StyledComponent<import("@mui/material").BadgeOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "style" | "color" | "className" | "max" | "children" | "classes" | "sx" | "variant" | "slotProps" | "slots" | "invisible" | "anchorOrigin" | "badgeContent" | "overlap" | "showZero"> & import("@mui/system").MUIStyledCommonProps<Theme>, {}, {}>;
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';
@@ -424,6 +424,23 @@ export const overrides = {
424
424
  }
425
425
  }
426
426
  },
427
+ MuiBackdrop: {
428
+ styleOverrides: {
429
+ root: ({ theme }) => ({
430
+ variants: [
431
+ {
432
+ props: { invisible: false },
433
+ style: {
434
+ backgroundColor: alpha(theme.palette.common.black, 0.12),
435
+ ...theme.applyStyles('dark', {
436
+ backgroundColor: alpha(theme.palette.common.black, 0.5)
437
+ })
438
+ }
439
+ }
440
+ ]
441
+ })
442
+ }
443
+ },
427
444
  MuiDialog: {
428
445
  defaultProps: { disableEnforceFocus: true },
429
446
  styleOverrides: {
@@ -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,6 @@
1
+ import React, { ReactNode } from 'react';
2
+ export interface ConfirmDialogProviderProps {
3
+ children?: ReactNode;
4
+ }
5
+ declare const ConfirmDialogProvider: React.FC<ConfirmDialogProviderProps>;
6
+ export default ConfirmDialogProvider;
@@ -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,6 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import SelectionProvider from './index';
3
+ declare const meta: Meta<typeof SelectionProvider>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const Default: Story;
@@ -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
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@linagora/twake-mui",
3
3
  "type": "module",
4
- "version": "17.1.0",
4
+ "version": "18.1.0",
5
5
  "description": "MUI v9 theme system for Twake applications",
6
6
  "author": "Twake",
7
7
  "license": "MIT",