@linagora/twake-mui 9.13.0 → 9.14.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 +7 -0
- package/dist/components/ExtendableFab/ExtendableFab.stories.d.ts +7 -0
- package/dist/components/ExtendableFab/ExtendableFab.stories.js +43 -0
- package/dist/components/ExtendableFab/index.d.ts +16 -0
- package/dist/components/ExtendableFab/index.js +20 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# @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
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **twake-mui:** Migrate ExtendableFab from cozy-ui ([af9fb22](https://github.com/linagora/twake-ui/commit/af9fb22a17da746edb2cbb27f8a8bab0a2379fdc))
|
|
7
|
+
|
|
1
8
|
# @linagora/twake-mui [9.13.0](https://github.com/linagora/twake-ui/compare/@linagora/twake-mui@9.12.0...@linagora/twake-mui@9.13.0) (2026-09-29)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { ExtendableFab } from './index';
|
|
3
|
+
declare const meta: Meta<typeof ExtendableFab>;
|
|
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,43 @@
|
|
|
1
|
+
import { Plus } from '@linagora/twake-icons';
|
|
2
|
+
import { Box, Stack } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { ExtendableFab } from './index';
|
|
5
|
+
const meta = {
|
|
6
|
+
title: 'ExtendableFab',
|
|
7
|
+
component: ExtendableFab,
|
|
8
|
+
parameters: { layout: 'fullscreen' },
|
|
9
|
+
tags: ['autodocs'],
|
|
10
|
+
args: {
|
|
11
|
+
label: 'Add',
|
|
12
|
+
icon: Plus,
|
|
13
|
+
color: 'primary',
|
|
14
|
+
size: 'medium',
|
|
15
|
+
topLimit: 50,
|
|
16
|
+
scrollOptions: { delay: 250 }
|
|
17
|
+
},
|
|
18
|
+
argTypes: {
|
|
19
|
+
label: { control: 'text' },
|
|
20
|
+
icon: { control: false },
|
|
21
|
+
color: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
options: ['default', 'primary', 'secondary', 'inherit']
|
|
24
|
+
},
|
|
25
|
+
size: { control: 'select', options: ['small', 'medium', 'large'] },
|
|
26
|
+
topLimit: { control: 'number' },
|
|
27
|
+
scrollOptions: { control: 'object' },
|
|
28
|
+
disabled: { control: 'boolean' }
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export default meta;
|
|
32
|
+
export const Default = {
|
|
33
|
+
render: args => (React.createElement(Box, { sx: { p: 2 } },
|
|
34
|
+
React.createElement(ExtendableFab, { sx: { position: 'sticky', top: 16 }, ...args }),
|
|
35
|
+
React.createElement(Box, { sx: { py: 2 } }, "Scroll the page vertically"),
|
|
36
|
+
React.createElement(Box, { sx: { height: '200vh' } })))
|
|
37
|
+
};
|
|
38
|
+
export const Screenshot = {
|
|
39
|
+
tags: ['argos'],
|
|
40
|
+
render: () => (React.createElement(Stack, { spacing: 2, direction: "row", sx: { p: 4 } },
|
|
41
|
+
React.createElement(ExtendableFab, { label: "Add", icon: Plus, color: "primary" }),
|
|
42
|
+
React.createElement(ExtendableFab, { label: "Add", icon: Plus, color: "inherit" })))
|
|
43
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IconProps } from '@linagora/twake-icons';
|
|
2
|
+
import { FabProps } from '@mui/material';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export interface ScrollOptions {
|
|
5
|
+
/** Delay in ms before the window scroll position is read */
|
|
6
|
+
delay?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ExtendableFabProps extends Omit<FabProps, 'ref' | 'children'> {
|
|
9
|
+
label: string;
|
|
10
|
+
icon: IconProps['icon'];
|
|
11
|
+
/** Window scroll offset in px below which the Fab stays extended */
|
|
12
|
+
topLimit?: number;
|
|
13
|
+
scrollOptions?: ScrollOptions;
|
|
14
|
+
}
|
|
15
|
+
export declare const ExtendableFab: React.ForwardRefExoticComponent<ExtendableFabProps & React.RefAttributes<HTMLButtonElement>>;
|
|
16
|
+
export default ExtendableFab;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Icon } from '@linagora/twake-icons';
|
|
2
|
+
import { Fab, styled } from '@mui/material';
|
|
3
|
+
import React, { forwardRef, useEffect, useState } from 'react';
|
|
4
|
+
import { useDebounce } from 'rooks';
|
|
5
|
+
const GappedFab = styled(Fab)(({ theme }) => ({ gap: theme.spacing(1) }));
|
|
6
|
+
export const ExtendableFab = forwardRef(({ label, icon, topLimit = 50, scrollOptions, ...props }, ref) => {
|
|
7
|
+
const [isBelowTopLimit, setIsBelowTopLimit] = useState(true);
|
|
8
|
+
const handleScroll = useDebounce(() => {
|
|
9
|
+
setIsBelowTopLimit(window.scrollY < topLimit);
|
|
10
|
+
}, scrollOptions?.delay ?? 250);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
13
|
+
return () => window.removeEventListener('scroll', handleScroll);
|
|
14
|
+
}, [handleScroll]);
|
|
15
|
+
return (React.createElement(GappedFab, { ref: ref, "aria-label": label, variant: isBelowTopLimit ? 'extended' : 'circular', ...props },
|
|
16
|
+
React.createElement(Icon, { icon: icon }),
|
|
17
|
+
isBelowTopLimit && label));
|
|
18
|
+
});
|
|
19
|
+
ExtendableFab.displayName = 'ExtendableFab';
|
|
20
|
+
export default ExtendableFab;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { ContactPopover, default as ContactPopoverDefault } from './components/C
|
|
|
14
14
|
export { default as DropdownButton } from './components/DropdownButton';
|
|
15
15
|
export { default as DropdownText } from './components/DropdownText';
|
|
16
16
|
export { Empty, EmptySubTitle } from './components/Empty';
|
|
17
|
+
export { ExtendableFab } from './components/ExtendableFab';
|
|
17
18
|
export { default as ListItem } from './components/ListItem';
|
|
18
19
|
export { default as ListItemButton } from './components/ListItemButton';
|
|
19
20
|
export { default as ListItemText } from './components/ListItemText';
|
|
@@ -53,6 +54,7 @@ export type { DialogProps, DialogSize } from './components/Dialog';
|
|
|
53
54
|
export type { EmptyProps, EmptyIconSize, EmptyComponentsProps } from './components/Empty';
|
|
54
55
|
export type { DropdownButtonProps } from './components/DropdownButton';
|
|
55
56
|
export type { DropdownTextProps, DropdownTextVariant } from './components/DropdownText';
|
|
57
|
+
export type { ExtendableFabProps, ScrollOptions } from './components/ExtendableFab';
|
|
56
58
|
export type { ListItemProps, ListItemGutters, ListItemSize } from './components/ListItem';
|
|
57
59
|
export type { ListItemButtonProps } from './components/ListItemButton';
|
|
58
60
|
export type { ListItemTextProps } from './components/ListItemText';
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export { ContactPopover, default as ContactPopoverDefault } from './components/C
|
|
|
17
17
|
export { default as DropdownButton } from './components/DropdownButton';
|
|
18
18
|
export { default as DropdownText } from './components/DropdownText';
|
|
19
19
|
export { Empty, EmptySubTitle } from './components/Empty';
|
|
20
|
+
export { ExtendableFab } from './components/ExtendableFab';
|
|
20
21
|
export { default as ListItem } from './components/ListItem';
|
|
21
22
|
export { default as ListItemButton } from './components/ListItemButton';
|
|
22
23
|
export { default as ListItemText } from './components/ListItemText';
|