@linagora/twake-mui 11.2.0 → 11.4.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 +14 -0
- package/dist/components/ColorList/ColorList.stories.d.ts +7 -0
- package/dist/components/ColorList/ColorList.stories.js +48 -0
- package/dist/components/ColorList/helpers.d.ts +1 -0
- package/dist/components/ColorList/helpers.js +22 -0
- package/dist/components/ColorList/index.d.ts +29 -0
- package/dist/components/ColorList/index.js +35 -0
- package/dist/components/ProgressionBanner/ProgressionBanner.stories.d.ts +7 -0
- package/dist/components/ProgressionBanner/ProgressionBanner.stories.js +47 -0
- package/dist/components/ProgressionBanner/ProgressionBannerProgress.d.ts +2 -0
- package/dist/components/ProgressionBanner/ProgressionBannerProgress.js +7 -0
- package/dist/components/ProgressionBanner/ProgressionBannerRoot.d.ts +4 -0
- package/dist/components/ProgressionBanner/ProgressionBannerRoot.js +21 -0
- package/dist/components/ProgressionBanner/index.d.ts +14 -0
- package/dist/components/ProgressionBanner/index.js +11 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# @linagora/twake-mui [11.4.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@11.3.0...@linagora/twake-mui@11.4.0) (2026-10-08)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **twake-mui:** Migrate ColorList from cozy-ui ([870fd92](https://github.com/linagora/twake-ui/commit/870fd9265f0a23904570e910644a74700cd41178))
|
|
7
|
+
|
|
8
|
+
# @linagora/twake-mui [11.3.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@11.2.0...@linagora/twake-mui@11.3.0) (2026-10-08)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **twake-mui:** Migrate ProgressionBanner from cozy-ui ([f3fb9a1](https://github.com/linagora/twake-ui/commit/f3fb9a11f9f91a15a5cb27d399c1956bcc1927c3))
|
|
14
|
+
|
|
1
15
|
# @linagora/twake-mui [11.2.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@11.1.0...@linagora/twake-mui@11.2.0) (2026-10-08)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import ColorList from './index';
|
|
3
|
+
declare const meta: Meta<typeof ColorList>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Screenshot: Story;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Box, Stack } from '@mui/material';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { COLORS } from './helpers';
|
|
4
|
+
import ColorList from './index';
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'ColorList',
|
|
7
|
+
component: ColorList,
|
|
8
|
+
parameters: { layout: 'padded' },
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
argTypes: {
|
|
11
|
+
size: {
|
|
12
|
+
control: 'select',
|
|
13
|
+
options: [undefined, 'small', 'medium']
|
|
14
|
+
},
|
|
15
|
+
selectedColor: {
|
|
16
|
+
control: 'select',
|
|
17
|
+
options: [undefined, ...COLORS]
|
|
18
|
+
},
|
|
19
|
+
customColorProps: { control: 'object' }
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export default meta;
|
|
23
|
+
const SelectableColorList = props => {
|
|
24
|
+
const [selectedColor, setSelectedColor] = useState(props.selectedColor);
|
|
25
|
+
return (React.createElement(ColorList, { ...props, selectedColor: selectedColor, onClick: setSelectedColor }));
|
|
26
|
+
};
|
|
27
|
+
export const Default = {
|
|
28
|
+
args: {
|
|
29
|
+
customColorProps: { enabled: true }
|
|
30
|
+
},
|
|
31
|
+
render: args => (React.createElement(Box, { sx: { width: args.size === 'medium' ? '100%' : { xs: '100%', md: 200 } } },
|
|
32
|
+
React.createElement(SelectableColorList, { key: args.selectedColor, ...args })))
|
|
33
|
+
};
|
|
34
|
+
const Section = ({ title, width, children }) => (React.createElement("section", null,
|
|
35
|
+
React.createElement("h3", { style: { marginBottom: '12px' } }, title),
|
|
36
|
+
React.createElement(Box, { sx: { width } }, children)));
|
|
37
|
+
const customColorProps = { enabled: true };
|
|
38
|
+
// Visual Regression - Combined view for Argos testing
|
|
39
|
+
export const Screenshot = {
|
|
40
|
+
tags: ['argos'],
|
|
41
|
+
render: () => (React.createElement(Stack, { spacing: 4 },
|
|
42
|
+
React.createElement(Section, { title: "Small", width: 200 },
|
|
43
|
+
React.createElement(ColorList, { size: "small", selectedColor: COLORS[4], customColorProps: customColorProps })),
|
|
44
|
+
React.createElement(Section, { title: "Medium" },
|
|
45
|
+
React.createElement(ColorList, { size: "medium", selectedColor: COLORS[4], customColorProps: customColorProps })),
|
|
46
|
+
React.createElement(Section, { title: "Without custom color", width: 200 },
|
|
47
|
+
React.createElement(ColorList, { size: "small" }))))
|
|
48
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const COLORS: string[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const COLORS = [
|
|
2
|
+
'#273891',
|
|
3
|
+
'#7E57E3',
|
|
4
|
+
'#9E83E8',
|
|
5
|
+
'#91CEF6',
|
|
6
|
+
'#2D83FF', // file-folder color, don't remove it
|
|
7
|
+
'#006BD8',
|
|
8
|
+
'#038199',
|
|
9
|
+
'#51B588',
|
|
10
|
+
'#457D6C',
|
|
11
|
+
'#1EBBCC',
|
|
12
|
+
'#E0465C',
|
|
13
|
+
'#ED20A4',
|
|
14
|
+
'#ED768D',
|
|
15
|
+
'#B85B17',
|
|
16
|
+
'#EDA91D',
|
|
17
|
+
'#BA8144',
|
|
18
|
+
'#ED916B',
|
|
19
|
+
'#EDC661',
|
|
20
|
+
'#131326',
|
|
21
|
+
'#646580'
|
|
22
|
+
];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ImageListProps } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
declare const sizes: {
|
|
4
|
+
small: {
|
|
5
|
+
avatar: number;
|
|
6
|
+
icon: number;
|
|
7
|
+
cols: number;
|
|
8
|
+
gap: number;
|
|
9
|
+
};
|
|
10
|
+
medium: {
|
|
11
|
+
avatar: number;
|
|
12
|
+
icon: number;
|
|
13
|
+
cols: number;
|
|
14
|
+
gap: number;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export type ColorListSize = keyof typeof sizes;
|
|
18
|
+
export interface ColorListProps extends Omit<ImageListProps, 'children' | 'onClick'> {
|
|
19
|
+
/** Defaults to `medium` on mobile and `small` otherwise */
|
|
20
|
+
size?: ColorListSize;
|
|
21
|
+
selectedColor?: string;
|
|
22
|
+
customColorProps?: {
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
25
|
+
};
|
|
26
|
+
onClick?: (color: string) => void;
|
|
27
|
+
}
|
|
28
|
+
declare const ColorList: React.FC<ColorListProps>;
|
|
29
|
+
export default ColorList;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Icon, Check, Palette } from '@linagora/twake-icons';
|
|
2
|
+
import { ButtonBase, ImageList, ImageListItem, imageListItemClasses } from '@mui/material';
|
|
3
|
+
import { styled } from '@mui/material/styles';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { useBreakpoints } from '../../hooks/useBreakpoints';
|
|
6
|
+
import { Avatar } from '../Avatar';
|
|
7
|
+
import { COLORS } from './helpers';
|
|
8
|
+
const sizes = {
|
|
9
|
+
small: { avatar: 21, icon: 10, cols: 7, gap: 5 },
|
|
10
|
+
medium: { avatar: 41, icon: 16, cols: 5, gap: 16 }
|
|
11
|
+
};
|
|
12
|
+
const ColorListRoot = styled(ImageList)({
|
|
13
|
+
margin: 0,
|
|
14
|
+
[`& .${imageListItemClasses.root}`]: { alignItems: 'center' }
|
|
15
|
+
});
|
|
16
|
+
const ColorList = ({ size, selectedColor, customColorProps, onClick, ...props }) => {
|
|
17
|
+
const { isMobile } = useBreakpoints();
|
|
18
|
+
const { avatar, icon, cols, gap } = sizes[size ?? (isMobile ? 'medium' : 'small')];
|
|
19
|
+
return (React.createElement(ColorListRoot, { cols: cols, rowHeight: avatar, gap: gap, ...props },
|
|
20
|
+
COLORS.map(color => (React.createElement(ImageListItem, { key: color },
|
|
21
|
+
React.createElement(ButtonBase, { component: "div", className: "u-bdrs-circle", onClick: () => onClick?.(color) },
|
|
22
|
+
React.createElement(Avatar, { color: color, size: avatar }, selectedColor?.toUpperCase() === color ? (React.createElement(Icon, { icon: Check, size: icon })) : (' ')))))),
|
|
23
|
+
customColorProps?.enabled && (React.createElement(ImageListItem, null,
|
|
24
|
+
React.createElement(ButtonBase, { sx: {
|
|
25
|
+
width: avatar,
|
|
26
|
+
height: avatar,
|
|
27
|
+
borderRadius: '50%',
|
|
28
|
+
border: '1px solid transparent',
|
|
29
|
+
backgroundImage: 'linear-gradient(#fff, #fff), conic-gradient(from 0deg, #FB2C36, #AD46FF, #2B7FFF, #FB2C36)',
|
|
30
|
+
backgroundOrigin: 'border-box',
|
|
31
|
+
backgroundClip: 'padding-box, border-box'
|
|
32
|
+
}, onClick: customColorProps.onClick },
|
|
33
|
+
React.createElement(Icon, { icon: Palette, size: icon, color: "#000" }))))));
|
|
34
|
+
};
|
|
35
|
+
export default ColorList;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import ProgressionBanner from './index';
|
|
3
|
+
declare const meta: Meta<typeof ProgressionBanner>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof meta>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Screenshot: Story;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { CloudSync2, Icon } from '@linagora/twake-icons';
|
|
3
|
+
import { Button, Stack } from '@mui/material';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import ProgressionBanner from './index';
|
|
6
|
+
const icon = React.createElement(Icon, { icon: CloudSync2 });
|
|
7
|
+
const errorLight = 'var(--twake-palette-error-light)';
|
|
8
|
+
const manageButton = (React.createElement(Button, { variant: "text", color: "primary", onClick: () => console.log('clicked') }, "Manage your storage space"));
|
|
9
|
+
const meta = {
|
|
10
|
+
title: 'ProgressionBanner',
|
|
11
|
+
component: ProgressionBanner,
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
argTypes: {
|
|
14
|
+
value: { control: { type: 'range', min: 0, max: 100, step: 1 } },
|
|
15
|
+
text: { control: 'text' },
|
|
16
|
+
progressBar: { control: 'boolean' },
|
|
17
|
+
color: { control: 'color' }
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
export default meta;
|
|
21
|
+
export const Default = {
|
|
22
|
+
args: {
|
|
23
|
+
value: 25,
|
|
24
|
+
text: '4 remaining items',
|
|
25
|
+
progressBar: true,
|
|
26
|
+
icon
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const Row = ({ title, children }) => (React.createElement("section", null,
|
|
30
|
+
React.createElement("h3", { style: { marginBottom: '12px' } }, title),
|
|
31
|
+
children));
|
|
32
|
+
export const Screenshot = {
|
|
33
|
+
tags: ['argos'],
|
|
34
|
+
render: () => (React.createElement(Stack, { spacing: 4 },
|
|
35
|
+
React.createElement(Row, { title: "Determinate" },
|
|
36
|
+
React.createElement(ProgressionBanner, { value: 25, text: "4 remaining items", icon: icon })),
|
|
37
|
+
React.createElement(Row, { title: "Indeterminate" },
|
|
38
|
+
React.createElement(ProgressionBanner, { text: "4 remaining items", icon: icon })),
|
|
39
|
+
React.createElement(Row, { title: "Without progress bar" },
|
|
40
|
+
React.createElement(ProgressionBanner, { progressBar: false, text: "4 remaining items", icon: icon })),
|
|
41
|
+
React.createElement(Row, { title: "With button" },
|
|
42
|
+
React.createElement(ProgressionBanner, { value: 25, text: "Storage limit nearly reached", icon: icon, button: manageButton })),
|
|
43
|
+
React.createElement(Row, { title: "Custom color" },
|
|
44
|
+
React.createElement(ProgressionBanner, { value: 25, color: errorLight, text: "Storage limit nearly reached", icon: icon, button: manageButton })),
|
|
45
|
+
React.createElement(Row, { title: "Default icon" },
|
|
46
|
+
React.createElement(ProgressionBanner, { value: 25, text: "4 remaining items" }))))
|
|
47
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Alert, alertClasses, styled } from '@mui/material';
|
|
2
|
+
const ProgressionBannerRoot = styled(Alert, {
|
|
3
|
+
shouldForwardProp: prop => prop !== 'background'
|
|
4
|
+
})(({ theme, background }) => ({
|
|
5
|
+
borderRadius: 0,
|
|
6
|
+
// outranks the severity tint, which the dark scheme re-applies after this rule
|
|
7
|
+
'&&': {
|
|
8
|
+
backgroundColor: background ?? theme.vars.palette.background.contrast
|
|
9
|
+
},
|
|
10
|
+
[theme.breakpoints.down('md')]: {
|
|
11
|
+
flexWrap: 'wrap',
|
|
12
|
+
// keeps the message beside the icon so only the action wraps
|
|
13
|
+
[`& .${alertClasses.message}`]: { flexBasis: 0 },
|
|
14
|
+
[`& .${alertClasses.action}`]: {
|
|
15
|
+
width: '100%',
|
|
16
|
+
paddingLeft: 0,
|
|
17
|
+
justifyContent: 'end'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}));
|
|
21
|
+
export default ProgressionBannerRoot;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AlertProps } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface ProgressionBannerProps extends Omit<AlertProps, 'color' | 'children'> {
|
|
4
|
+
/** Percentage of progression, between 0 and 100. Without it the bar is indeterminate. */
|
|
5
|
+
value?: number;
|
|
6
|
+
text?: React.ReactNode;
|
|
7
|
+
/** Rendered as the alert action */
|
|
8
|
+
button?: React.ReactNode;
|
|
9
|
+
progressBar?: boolean;
|
|
10
|
+
/** Background colour of the banner, any CSS colour */
|
|
11
|
+
color?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const ProgressionBanner: React.FC<ProgressionBannerProps>;
|
|
14
|
+
export default ProgressionBanner;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Typography } from '@mui/material';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ProgressionBannerProgress from './ProgressionBannerProgress';
|
|
4
|
+
import ProgressionBannerRoot from './ProgressionBannerRoot';
|
|
5
|
+
const ProgressionBanner = ({ value, text, icon, button, progressBar = true, color, ...props }) => (React.createElement(React.Fragment, null,
|
|
6
|
+
React.createElement(ProgressionBannerRoot, { icon: React.isValidElement(icon)
|
|
7
|
+
? React.cloneElement(icon, { size: icon.props.size ?? 32 })
|
|
8
|
+
: icon, action: button, background: color, ...props },
|
|
9
|
+
React.createElement(Typography, { component: "span", variant: "h6" }, text)),
|
|
10
|
+
progressBar && (React.createElement(ProgressionBannerProgress, { variant: value ? 'determinate' : 'indeterminate', value: value }))));
|
|
11
|
+
export default ProgressionBanner;
|
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export { default as BottomSheetItem } from './components/BottomSheet/BottomSheet
|
|
|
37
37
|
export { default as BottomSheetHeader } from './components/BottomSheet/BottomSheetHeader';
|
|
38
38
|
export { default as BottomSheetTitle } from './components/BottomSheet/BottomSheetTitle';
|
|
39
39
|
export { default as Chip } from './components/Chip';
|
|
40
|
+
export { default as ColorList } from './components/ColorList';
|
|
40
41
|
export { Dialog, default as DialogDefault } from './components/Dialog';
|
|
41
42
|
export { ContactPopover, default as ContactPopoverDefault } from './components/ContactPopover';
|
|
42
43
|
export { default as DropdownButton } from './components/DropdownButton';
|
|
@@ -51,6 +52,7 @@ export { default as ListSkeleton } from './components/ListSkeleton';
|
|
|
51
52
|
export { default as ListSubheader } from './components/ListSubheader';
|
|
52
53
|
export { default as Markdown } from './components/Markdown';
|
|
53
54
|
export { default as PointerAlert } from './components/PointerAlert';
|
|
55
|
+
export { default as ProgressionBanner } from './components/ProgressionBanner';
|
|
54
56
|
export { Tabs, default as TabsDefault } from './components/Tabs';
|
|
55
57
|
export { Switch, default as SwitchDefault } from './components/Switch';
|
|
56
58
|
export { SearchBar, default as SearchBarDefault } from './components/SearchBar';
|
|
@@ -66,6 +68,7 @@ export { default as NavText } from './components/NavText';
|
|
|
66
68
|
export { NavDesktopLimiter } from './components/NavDesktopLimiter';
|
|
67
69
|
export { NavDesktopDropdown } from './components/NavDesktopDropdown';
|
|
68
70
|
export { nameToColor, supportedColors, getInitials } from './components/Avatar/helpers';
|
|
71
|
+
export { COLORS } from './components/ColorList/helpers';
|
|
69
72
|
export { default as AccordionExpandIcon } from './components/AccordionExpandIcon';
|
|
70
73
|
export { default as VirtualizedTable } from './components/VirtualizedTable';
|
|
71
74
|
export { VirtuosoMockContext } from 'react-virtuoso';
|
|
@@ -108,8 +111,10 @@ export type { SpaceOverlay, SpaceOverlayStatus } from './components/SpaceOverlay
|
|
|
108
111
|
export type { SpaceOverlayProviderProps } from './components/SpaceOverlay/SpaceOverlay';
|
|
109
112
|
export type { OverlayBox, OverlayRegion } from './components/SpaceOverlay/region';
|
|
110
113
|
export type { OverlayFrameProps } from './components/SpaceOverlay/OverlayFrame';
|
|
114
|
+
export type { ColorListProps, ColorListSize } from './components/ColorList';
|
|
111
115
|
export type { DialogProps, DialogSize } from './components/Dialog';
|
|
112
116
|
export type { PointerAlertProps, PointerAlertDirection } from './components/PointerAlert';
|
|
117
|
+
export type { ProgressionBannerProps } from './components/ProgressionBanner';
|
|
113
118
|
export type { EmptyProps, EmptyIconSize, EmptyComponentsProps } from './components/Empty';
|
|
114
119
|
export type { DropdownButtonProps } from './components/DropdownButton';
|
|
115
120
|
export type { DropdownTextProps, DropdownTextVariant } from './components/DropdownText';
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ export { default as BottomSheetItem } from './components/BottomSheet/BottomSheet
|
|
|
40
40
|
export { default as BottomSheetHeader } from './components/BottomSheet/BottomSheetHeader';
|
|
41
41
|
export { default as BottomSheetTitle } from './components/BottomSheet/BottomSheetTitle';
|
|
42
42
|
export { default as Chip } from './components/Chip';
|
|
43
|
+
export { default as ColorList } from './components/ColorList';
|
|
43
44
|
export { Dialog, default as DialogDefault } from './components/Dialog';
|
|
44
45
|
export { ContactPopover, default as ContactPopoverDefault } from './components/ContactPopover';
|
|
45
46
|
export { default as DropdownButton } from './components/DropdownButton';
|
|
@@ -54,6 +55,7 @@ export { default as ListSkeleton } from './components/ListSkeleton';
|
|
|
54
55
|
export { default as ListSubheader } from './components/ListSubheader';
|
|
55
56
|
export { default as Markdown } from './components/Markdown';
|
|
56
57
|
export { default as PointerAlert } from './components/PointerAlert';
|
|
58
|
+
export { default as ProgressionBanner } from './components/ProgressionBanner';
|
|
57
59
|
export { Tabs, default as TabsDefault } from './components/Tabs';
|
|
58
60
|
export { Switch, default as SwitchDefault } from './components/Switch';
|
|
59
61
|
export { SearchBar, default as SearchBarDefault } from './components/SearchBar';
|
|
@@ -69,6 +71,7 @@ export { default as NavText } from './components/NavText';
|
|
|
69
71
|
export { NavDesktopLimiter } from './components/NavDesktopLimiter';
|
|
70
72
|
export { NavDesktopDropdown } from './components/NavDesktopDropdown';
|
|
71
73
|
export { nameToColor, supportedColors, getInitials } from './components/Avatar/helpers';
|
|
74
|
+
export { COLORS } from './components/ColorList/helpers';
|
|
72
75
|
export { default as AccordionExpandIcon } from './components/AccordionExpandIcon';
|
|
73
76
|
export { default as VirtualizedTable } from './components/VirtualizedTable';
|
|
74
77
|
export { VirtuosoMockContext } from 'react-virtuoso';
|