@linagora/twake-mui 9.14.0 → 9.15.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/PointerAlert/PointerAlert.stories.d.ts +7 -0
- package/dist/components/PointerAlert/PointerAlert.stories.js +88 -0
- package/dist/components/PointerAlert/index.d.ts +9 -0
- package/dist/components/PointerAlert/index.js +68 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/lib/overrides.d.ts +1 -0
- package/dist/lib/overrides.js +4 -3
- package/dist/stories/IconButton.stories.js +1 -1
- package/dist/stories/TextField.stories.js +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
# @linagora/twake-mui [9.15.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@9.14.1...@linagora/twake-mui@9.15.0) (2026-09-30)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **twake-mui:** Default Alert severity to primary ([9cdb94e](https://github.com/linagora/twake-ui/commit/9cdb94e7e636d54f2d93fdabb21c03ece9bfbff4))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **twake-mui:** Migrate PointerAlert from cozy-ui ([82aa564](https://github.com/linagora/twake-ui/commit/82aa5646f8da35d1a9986e045a0ed5ec8a5da003))
|
|
12
|
+
|
|
13
|
+
## @linagora/twake-mui [9.14.1](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@9.14.0...@linagora/twake-mui@9.14.1) (2026-09-30)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* **twake-mui:** Accept any twake-icons from 2.10.0 as peer ([e934d0e](https://github.com/linagora/twake-ui/commit/e934d0e9335c0a63c0caf2dde202aa46ddc33238))
|
|
19
|
+
|
|
1
20
|
# @linagora/twake-mui [9.14.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@9.13.0...@linagora/twake-mui@9.14.0) (2026-09-29)
|
|
2
21
|
|
|
3
22
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import PointerAlert from './index';
|
|
3
|
+
declare const meta: Meta<typeof PointerAlert>;
|
|
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,88 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { DeviceLaptop, Download, Icon } from '@linagora/twake-icons';
|
|
3
|
+
import { AlertTitle, Button, Stack, Typography } from '@mui/material';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import PointerAlert from './index';
|
|
6
|
+
const directions = ['top', 'bottom', 'left', 'right'];
|
|
7
|
+
const severities = [
|
|
8
|
+
'primary',
|
|
9
|
+
'secondary',
|
|
10
|
+
'success',
|
|
11
|
+
'error',
|
|
12
|
+
'warning',
|
|
13
|
+
'info'
|
|
14
|
+
];
|
|
15
|
+
const variants = ['standard', 'filled', 'outlined'];
|
|
16
|
+
const makeActionColor = (variant, severity) => {
|
|
17
|
+
if (variant === 'filled')
|
|
18
|
+
return 'inherit';
|
|
19
|
+
return severity === 'primary' || severity === 'secondary'
|
|
20
|
+
? undefined
|
|
21
|
+
: severity;
|
|
22
|
+
};
|
|
23
|
+
const text = 'Get Cozy Drive for Desktop and synchronise your files safely to make them accessible at all times.';
|
|
24
|
+
const downloadAction = (React.createElement(Button, { variant: "text", size: "small", startIcon: React.createElement(Icon, { icon: Download }) }, "Download"));
|
|
25
|
+
const meta = {
|
|
26
|
+
title: 'PointerAlert',
|
|
27
|
+
component: PointerAlert,
|
|
28
|
+
parameters: { layout: 'centered' },
|
|
29
|
+
tags: ['autodocs'],
|
|
30
|
+
argTypes: {
|
|
31
|
+
direction: { control: 'select', options: directions },
|
|
32
|
+
position: {
|
|
33
|
+
control: 'text',
|
|
34
|
+
description: 'Any CSS length or percentage, e.g. `30%` or `100px`'
|
|
35
|
+
},
|
|
36
|
+
severity: { control: 'select', options: severities },
|
|
37
|
+
variant: { control: 'select', options: variants },
|
|
38
|
+
color: {
|
|
39
|
+
control: 'select',
|
|
40
|
+
options: severities,
|
|
41
|
+
description: 'Overrides the colour taken from `severity`'
|
|
42
|
+
},
|
|
43
|
+
square: { control: 'boolean' }
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export default meta;
|
|
47
|
+
export const Default = {
|
|
48
|
+
args: {
|
|
49
|
+
direction: 'bottom',
|
|
50
|
+
position: '50%',
|
|
51
|
+
severity: 'primary',
|
|
52
|
+
variant: 'standard'
|
|
53
|
+
},
|
|
54
|
+
render: args => (React.createElement(PointerAlert, { ...args, sx: { width: 480 }, action: downloadAction }, text))
|
|
55
|
+
};
|
|
56
|
+
const Section = ({ title, children }) => (React.createElement("section", null,
|
|
57
|
+
React.createElement(Typography, { variant: "h4", gutterBottom: true }, title),
|
|
58
|
+
React.createElement(Stack, { spacing: 1, useFlexGap: true }, children)));
|
|
59
|
+
export const Screenshot = {
|
|
60
|
+
tags: ['argos'],
|
|
61
|
+
render: () => (React.createElement(Stack, { spacing: 3, sx: { width: 640 } },
|
|
62
|
+
React.createElement(Section, { title: "Directions" }, directions.map(direction => (React.createElement(PointerAlert, { key: direction, direction: direction, severity: "primary", action: downloadAction },
|
|
63
|
+
direction,
|
|
64
|
+
": ",
|
|
65
|
+
text)))),
|
|
66
|
+
React.createElement(Section, { title: "Positions" }, ['calc(0% + 0.75rem)', '30%', '100px', 'calc(100% - 0.75rem)'].map(position => (React.createElement(PointerAlert, { key: position, position: position, severity: "info" }, position)))),
|
|
67
|
+
variants.map(variant => (React.createElement(Section, { key: variant, title: `${variant} variant` }, severities.map(severity => (React.createElement(PointerAlert, { key: severity, variant: variant, severity: severity, action: React.createElement(Button, { variant: "text", size: "small", color: makeActionColor(variant, severity) }, "ACTION") },
|
|
68
|
+
React.createElement(AlertTitle, null, severity),
|
|
69
|
+
"This is a ",
|
|
70
|
+
severity,
|
|
71
|
+
" alert")))))),
|
|
72
|
+
React.createElement(Section, { title: "Content" },
|
|
73
|
+
React.createElement(PointerAlert, { severity: "primary" },
|
|
74
|
+
React.createElement(AlertTitle, null, "This is the title"),
|
|
75
|
+
text),
|
|
76
|
+
React.createElement(PointerAlert, { severity: "primary", color: "warning" },
|
|
77
|
+
"Colour overridden: ",
|
|
78
|
+
text),
|
|
79
|
+
React.createElement(PointerAlert, { severity: "primary", icon: React.createElement(Icon, { icon: DeviceLaptop, color: "var(--twake-palette-error-main)", size: 32 }) }, text),
|
|
80
|
+
React.createElement(PointerAlert, { severity: "primary", icon: false }, text),
|
|
81
|
+
React.createElement(PointerAlert, { severity: "primary", square: true },
|
|
82
|
+
"Square: ",
|
|
83
|
+
text),
|
|
84
|
+
React.createElement(PointerAlert, { severity: "primary", onClose: () => console.log('closed') }, text),
|
|
85
|
+
React.createElement(PointerAlert, { severity: "primary", action: React.createElement(React.Fragment, null,
|
|
86
|
+
downloadAction,
|
|
87
|
+
React.createElement(Button, { variant: "text", size: "small" }, "No, thanks!")) }, text))))
|
|
88
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AlertProps } from '@mui/material';
|
|
2
|
+
export type PointerAlertDirection = 'top' | 'right' | 'bottom' | 'left';
|
|
3
|
+
export interface PointerAlertProps extends AlertProps {
|
|
4
|
+
direction?: PointerAlertDirection;
|
|
5
|
+
/** Arrow offset along its edge, any CSS length or percentage. `calc(0% + 0.75rem)` puts it against the starting corner. */
|
|
6
|
+
position?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const PointerAlert: import("@emotion/styled").StyledComponent<AlertProps & import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & PointerAlertProps, {}, {}>;
|
|
9
|
+
export default PointerAlert;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Alert, alertClasses, styled } from '@mui/material';
|
|
2
|
+
import { capitalize } from '@mui/material/utils';
|
|
3
|
+
import { alertSeverities } from '../../lib/overrides';
|
|
4
|
+
const ARROW_SIZE = '0.75rem';
|
|
5
|
+
const ARROW_BASE = `calc(2 * ${ARROW_SIZE})`;
|
|
6
|
+
// The alert paints on whole pixels but a clip path cuts on fractional ones. Overshooting
|
|
7
|
+
// on the alert side leaves that edge to the arrow's box, snapped like the alert; the
|
|
8
|
+
// slopes are unchanged.
|
|
9
|
+
const BLEED = '1px';
|
|
10
|
+
const makeShape = (direction, position) => {
|
|
11
|
+
const horizontal = { left: position, marginLeft: `-${ARROW_SIZE}` };
|
|
12
|
+
const vertical = { top: position, marginTop: `-${ARROW_SIZE}` };
|
|
13
|
+
const shapes = {
|
|
14
|
+
top: {
|
|
15
|
+
...horizontal,
|
|
16
|
+
bottom: '100%',
|
|
17
|
+
width: ARROW_BASE,
|
|
18
|
+
height: ARROW_SIZE,
|
|
19
|
+
clipPath: `polygon(50% 0, calc(100% + ${BLEED}) calc(100% + ${BLEED}), -${BLEED} calc(100% + ${BLEED}))`
|
|
20
|
+
},
|
|
21
|
+
bottom: {
|
|
22
|
+
...horizontal,
|
|
23
|
+
top: '100%',
|
|
24
|
+
width: ARROW_BASE,
|
|
25
|
+
height: ARROW_SIZE,
|
|
26
|
+
clipPath: `polygon(-${BLEED} -${BLEED}, calc(100% + ${BLEED}) -${BLEED}, 50% 100%)`
|
|
27
|
+
},
|
|
28
|
+
left: {
|
|
29
|
+
...vertical,
|
|
30
|
+
right: '100%',
|
|
31
|
+
width: ARROW_SIZE,
|
|
32
|
+
height: ARROW_BASE,
|
|
33
|
+
clipPath: `polygon(calc(100% + ${BLEED}) -${BLEED}, calc(100% + ${BLEED}) calc(100% + ${BLEED}), 0 50%)`
|
|
34
|
+
},
|
|
35
|
+
right: {
|
|
36
|
+
...vertical,
|
|
37
|
+
left: '100%',
|
|
38
|
+
width: ARROW_SIZE,
|
|
39
|
+
height: ARROW_BASE,
|
|
40
|
+
clipPath: `polygon(-${BLEED} -${BLEED}, 100% 50%, -${BLEED} calc(100% + ${BLEED}))`
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
root: { [`margin-${direction}`]: ARROW_SIZE },
|
|
45
|
+
arrow: shapes[direction]
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const PointerAlert = styled(Alert, {
|
|
49
|
+
shouldForwardProp: prop => prop !== 'direction' && prop !== 'position'
|
|
50
|
+
})(({ theme, direction = 'bottom', position = '50%' }) => {
|
|
51
|
+
const { root, arrow } = makeShape(direction, position);
|
|
52
|
+
return {
|
|
53
|
+
...root,
|
|
54
|
+
position: 'relative',
|
|
55
|
+
'&::after': {
|
|
56
|
+
...arrow,
|
|
57
|
+
content: '""',
|
|
58
|
+
position: 'absolute',
|
|
59
|
+
backgroundColor: 'inherit'
|
|
60
|
+
},
|
|
61
|
+
// outlined alerts have no background for the arrow to inherit
|
|
62
|
+
...Object.fromEntries(alertSeverities.map(severity => [
|
|
63
|
+
`&.${alertClasses.outlined}.MuiAlert-color${capitalize(severity)}::after`,
|
|
64
|
+
{ backgroundColor: theme.vars.palette[severity].main }
|
|
65
|
+
]))
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
export default PointerAlert;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export { default as ListItemText } from './components/ListItemText';
|
|
|
21
21
|
export { default as ListItemSkeleton } from './components/ListItemSkeleton';
|
|
22
22
|
export { default as ListSkeleton } from './components/ListSkeleton';
|
|
23
23
|
export { default as ListSubheader } from './components/ListSubheader';
|
|
24
|
+
export { default as PointerAlert } from './components/PointerAlert';
|
|
24
25
|
export { Tabs, default as TabsDefault } from './components/Tabs';
|
|
25
26
|
export { Switch, default as SwitchDefault } from './components/Switch';
|
|
26
27
|
export { SearchBar, default as SearchBarDefault } from './components/SearchBar';
|
|
@@ -51,6 +52,7 @@ export type { ContactPopoverCalendarActionProps } from './components/ContactPopo
|
|
|
51
52
|
export type { ContactPopoverEmailActionProps } from './components/ContactPopover/ContactPopoverEmailAction';
|
|
52
53
|
export type { ChipProps } from './components/Chip';
|
|
53
54
|
export type { DialogProps, DialogSize } from './components/Dialog';
|
|
55
|
+
export type { PointerAlertProps, PointerAlertDirection } from './components/PointerAlert';
|
|
54
56
|
export type { EmptyProps, EmptyIconSize, EmptyComponentsProps } from './components/Empty';
|
|
55
57
|
export type { DropdownButtonProps } from './components/DropdownButton';
|
|
56
58
|
export type { DropdownTextProps, DropdownTextVariant } from './components/DropdownText';
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ export { default as ListItemText } from './components/ListItemText';
|
|
|
24
24
|
export { default as ListItemSkeleton } from './components/ListItemSkeleton';
|
|
25
25
|
export { default as ListSkeleton } from './components/ListSkeleton';
|
|
26
26
|
export { default as ListSubheader } from './components/ListSubheader';
|
|
27
|
+
export { default as PointerAlert } from './components/PointerAlert';
|
|
27
28
|
export { Tabs, default as TabsDefault } from './components/Tabs';
|
|
28
29
|
export { Switch, default as SwitchDefault } from './components/Switch';
|
|
29
30
|
export { SearchBar, default as SearchBarDefault } from './components/SearchBar';
|
package/dist/lib/overrides.d.ts
CHANGED
package/dist/lib/overrides.js
CHANGED
|
@@ -18,7 +18,7 @@ import { alpha, darken } from '@mui/material/styles';
|
|
|
18
18
|
import React from 'react';
|
|
19
19
|
import { radius } from './radius';
|
|
20
20
|
import AccordionExpandIcon from '../components/AccordionExpandIcon';
|
|
21
|
-
const alertSeverities = [
|
|
21
|
+
export const alertSeverities = [
|
|
22
22
|
'primary',
|
|
23
23
|
'secondary',
|
|
24
24
|
'success',
|
|
@@ -881,9 +881,10 @@ export const overrides = {
|
|
|
881
881
|
}
|
|
882
882
|
},
|
|
883
883
|
MuiAlert: {
|
|
884
|
-
// cozy-ui's 16px icons; the icon padding below centres them on the first
|
|
885
|
-
// line of the message.
|
|
886
884
|
defaultProps: {
|
|
885
|
+
severity: 'primary',
|
|
886
|
+
// 16px icons; the icon padding below centres them on the first line of
|
|
887
|
+
// the message.
|
|
887
888
|
iconMapping: {
|
|
888
889
|
primary: React.createElement(Icon, { icon: Info }),
|
|
889
890
|
secondary: React.createElement(Icon, { icon: Info }),
|
|
@@ -39,7 +39,7 @@ export const Screenshot = {
|
|
|
39
39
|
render: () => (React.createElement(Stack, { spacing: 4, sx: { p: 4 } },
|
|
40
40
|
sizes.map(size => (React.createElement("section", { key: size },
|
|
41
41
|
React.createElement("h3", null, size),
|
|
42
|
-
React.createElement(Stack, { direction: "row", spacing: 4 },
|
|
42
|
+
React.createElement(Stack, { direction: "row", spacing: 4, useFlexGap: true, sx: { flexWrap: 'wrap' } },
|
|
43
43
|
React.createElement(Stack, { spacing: 1 },
|
|
44
44
|
React.createElement(Typography, { variant: "caption" }, "default"),
|
|
45
45
|
React.createElement(Row, { size: size })),
|
|
@@ -39,7 +39,7 @@ const adornments = {
|
|
|
39
39
|
};
|
|
40
40
|
const items = options.map(option => (React.createElement(MenuItem, { key: option.value, value: option.value }, option.label)));
|
|
41
41
|
// One enabled and one disabled field
|
|
42
|
-
const Pair = props => (React.createElement(Stack, { direction: "row", spacing: 2 },
|
|
42
|
+
const Pair = props => (React.createElement(Stack, { direction: "row", spacing: 2, useFlexGap: true, sx: { flexWrap: 'wrap' } },
|
|
43
43
|
React.createElement(TextField, { ...props }),
|
|
44
44
|
React.createElement(TextField, { disabled: true, ...props })));
|
|
45
45
|
// Every example of the cozy-ui TextField doc, for one set of variant props
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linagora/twake-mui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "9.
|
|
4
|
+
"version": "9.15.0",
|
|
5
5
|
"description": "MUI v9 theme system for Twake applications",
|
|
6
6
|
"author": "Twake",
|
|
7
7
|
"license": "MIT",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@emotion/react": "^11.5.0",
|
|
52
52
|
"@emotion/styled": "^11.3.0",
|
|
53
|
-
"@linagora/twake-icons": "
|
|
53
|
+
"@linagora/twake-icons": ">=2.10.0",
|
|
54
54
|
"@mui/lab": "^9.0.0-beta.6",
|
|
55
55
|
"@mui/material": "^9.2.0",
|
|
56
56
|
"react": "^18",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"rooks": "7.14.1"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@argos-ci/cli": "
|
|
69
|
-
"@argos-ci/storybook": "
|
|
68
|
+
"@argos-ci/cli": "6.9.5",
|
|
69
|
+
"@argos-ci/storybook": "6.4.1",
|
|
70
70
|
"@emotion/react": "^11.5.0",
|
|
71
71
|
"@emotion/styled": "^11.3.0",
|
|
72
72
|
"@linagora/twake-icons": "^2.10.0",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"@types/lodash": "4.17.24",
|
|
83
83
|
"@types/react": "18.2.0",
|
|
84
84
|
"@types/react-dom": "^18.2.0",
|
|
85
|
-
"@vitest/browser-playwright": "4.1.
|
|
85
|
+
"@vitest/browser-playwright": "4.1.11",
|
|
86
86
|
"cozy-tsconfig": "^2.0.0",
|
|
87
87
|
"eslint": "10.2.1",
|
|
88
88
|
"eslint-config-cozy-app": "7.0.0",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"react-dom": "^18.2.0",
|
|
94
94
|
"storybook": "10.3.5",
|
|
95
95
|
"twake-i18n": "^0.5.0",
|
|
96
|
-
"vite": "8.
|
|
97
|
-
"vitest": "4.1.
|
|
96
|
+
"vite": "8.3.1",
|
|
97
|
+
"vitest": "4.1.11"
|
|
98
98
|
}
|
|
99
99
|
}
|