kelt-ui-kit-react 2.0.5 → 2.0.8
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/dist/index.js +1629 -1626
- package/dist/style.css +1 -1
- package/dist/toaster/store/useToasterStore.d.ts +4 -0
- package/package.json +1 -1
- package/src/expands/expand/expand.tsx +9 -4
- package/src/grid/Grid.tsx +34 -34
- package/src/grid/col/Col.tsx +24 -24
- package/src/grid/col/col.css +3 -3
- package/src/grid/col/colStyled/ColStyled.tsx +59 -59
- package/src/grid/row/Row.tsx +49 -49
- package/src/toaster/Toaster.tsx +2 -1
- package/src/toaster/store/useToasterStore.tsx +11 -0
- package/src/toaster/toaster.css +13 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
export type ToasterPosition = "top-right" | "top-center" | "bottom-right" | "bottom-center";
|
|
2
3
|
type ToasterState = {
|
|
3
4
|
title: string;
|
|
4
5
|
description?: string;
|
|
@@ -7,12 +8,15 @@ type ToasterState = {
|
|
|
7
8
|
visible: boolean;
|
|
8
9
|
duration: number;
|
|
9
10
|
close?: boolean;
|
|
11
|
+
position: ToasterPosition;
|
|
10
12
|
showToast: (title: string, options?: {
|
|
11
13
|
description?: string;
|
|
12
14
|
severity?: "info" | "success" | "error" | "warning";
|
|
13
15
|
duration?: number;
|
|
14
16
|
children?: React.ReactNode;
|
|
15
17
|
close?: boolean;
|
|
18
|
+
/** Position à l'écran (défaut : "top-right") */
|
|
19
|
+
position?: ToasterPosition;
|
|
16
20
|
}) => void;
|
|
17
21
|
hideToast: () => void;
|
|
18
22
|
};
|
package/package.json
CHANGED
|
@@ -37,6 +37,11 @@ export const Expand = ({
|
|
|
37
37
|
}
|
|
38
38
|
}, [currentExpand, setActive, item, active]);
|
|
39
39
|
|
|
40
|
+
// Si catchFocusCaptureId est fourni, seul l'expand portant cet id gère le focus / scroll
|
|
41
|
+
const canCatchFocus =
|
|
42
|
+
catchfocusCapture &&
|
|
43
|
+
(catchFocusCaptureId === undefined || catchFocusCaptureId === item.id);
|
|
44
|
+
|
|
40
45
|
const scrollToHeader = useCallback(() => {
|
|
41
46
|
const expandElement = expandRef.current;
|
|
42
47
|
if (!expandElement) return;
|
|
@@ -70,7 +75,7 @@ export const Expand = ({
|
|
|
70
75
|
}, []);
|
|
71
76
|
|
|
72
77
|
useEffect(() => {
|
|
73
|
-
if (!
|
|
78
|
+
if (!canCatchFocus) return;
|
|
74
79
|
if (active) {
|
|
75
80
|
const timer1 = setTimeout(() => {
|
|
76
81
|
scrollToHeader();
|
|
@@ -83,11 +88,11 @@ export const Expand = ({
|
|
|
83
88
|
clearTimeout(timer2);
|
|
84
89
|
};
|
|
85
90
|
}
|
|
86
|
-
}, [active, scrollToHeader,
|
|
91
|
+
}, [active, scrollToHeader, canCatchFocus]);
|
|
87
92
|
|
|
88
93
|
const handleFocusCapture = useCallback(
|
|
89
94
|
(e: React.FocusEvent<HTMLDivElement>) => {
|
|
90
|
-
if (!
|
|
95
|
+
if (!canCatchFocus) return;
|
|
91
96
|
const target = e.target as HTMLElement;
|
|
92
97
|
if (
|
|
93
98
|
active &&
|
|
@@ -137,7 +142,7 @@ export const Expand = ({
|
|
|
137
142
|
setTimeout(performScroll, 300);
|
|
138
143
|
}
|
|
139
144
|
},
|
|
140
|
-
[active,
|
|
145
|
+
[active, canCatchFocus],
|
|
141
146
|
);
|
|
142
147
|
|
|
143
148
|
const handleChange = useCallback(
|
package/src/grid/Grid.tsx
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { Col } from "./col/Col";
|
|
2
|
-
import { Container } from "./container/Container";
|
|
3
|
-
import { GridInterface, GridResponsive } from "./grid.interface";
|
|
4
|
-
import { GridGap, Row } from "./row/Row";
|
|
5
|
-
type GridProps = {
|
|
6
|
-
items: GridInterface[];
|
|
7
|
-
className?: string;
|
|
8
|
-
scroll?: boolean;
|
|
9
|
-
gap?: GridGap;
|
|
10
|
-
responsive?: GridResponsive;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const Grid = ({
|
|
14
|
-
items,
|
|
15
|
-
className,
|
|
16
|
-
scroll,
|
|
17
|
-
gap,
|
|
18
|
-
responsive,
|
|
19
|
-
}: GridProps) => {
|
|
20
|
-
return (
|
|
21
|
-
<Container>
|
|
22
|
-
<Row
|
|
23
|
-
scroll={scroll}
|
|
24
|
-
className={className}
|
|
25
|
-
gap={gap}
|
|
26
|
-
responsive={responsive}
|
|
27
|
-
>
|
|
28
|
-
{items.map((item, id) => (
|
|
29
|
-
<Col key={id} {...item} />
|
|
30
|
-
))}
|
|
31
|
-
</Row>
|
|
32
|
-
</Container>
|
|
33
|
-
);
|
|
34
|
-
};
|
|
1
|
+
import { Col } from "./col/Col";
|
|
2
|
+
import { Container } from "./container/Container";
|
|
3
|
+
import { GridInterface, GridResponsive } from "./grid.interface";
|
|
4
|
+
import { GridGap, Row } from "./row/Row";
|
|
5
|
+
type GridProps = {
|
|
6
|
+
items: GridInterface[];
|
|
7
|
+
className?: string;
|
|
8
|
+
scroll?: boolean;
|
|
9
|
+
gap?: GridGap;
|
|
10
|
+
responsive?: GridResponsive;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const Grid = ({
|
|
14
|
+
items,
|
|
15
|
+
className,
|
|
16
|
+
scroll,
|
|
17
|
+
gap,
|
|
18
|
+
responsive,
|
|
19
|
+
}: GridProps) => {
|
|
20
|
+
return (
|
|
21
|
+
<Container>
|
|
22
|
+
<Row
|
|
23
|
+
scroll={scroll}
|
|
24
|
+
className={className}
|
|
25
|
+
gap={gap}
|
|
26
|
+
responsive={responsive}
|
|
27
|
+
>
|
|
28
|
+
{items.map((item, id) => (
|
|
29
|
+
<Col key={id} {...item} />
|
|
30
|
+
))}
|
|
31
|
+
</Row>
|
|
32
|
+
</Container>
|
|
33
|
+
);
|
|
34
|
+
};
|
package/src/grid/col/Col.tsx
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { useContext } from "react";
|
|
2
|
-
import { ColStyled } from "./colStyled/ColStyled";
|
|
3
|
-
import { GridBreakpoints } from "../grid.interface";
|
|
4
|
-
import { RowResponsiveContext } from "../row/Row";
|
|
5
|
-
import "./col.css"
|
|
6
|
-
type ColProps = GridBreakpoints & {
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
};
|
|
9
|
-
export const Col: React.FC<ColProps> = ({ xs, sm, md, lg, xl, children }) => {
|
|
10
|
-
const responsive = useContext(RowResponsiveContext);
|
|
11
|
-
return (
|
|
12
|
-
<ColStyled
|
|
13
|
-
className="col"
|
|
14
|
-
$responsive={responsive}
|
|
15
|
-
$xs={xs}
|
|
16
|
-
$sm={sm}
|
|
17
|
-
$md={md}
|
|
18
|
-
$lg={lg}
|
|
19
|
-
$xl={xl}
|
|
20
|
-
>
|
|
21
|
-
{children}
|
|
22
|
-
</ColStyled>
|
|
23
|
-
);
|
|
24
|
-
};
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { ColStyled } from "./colStyled/ColStyled";
|
|
3
|
+
import { GridBreakpoints } from "../grid.interface";
|
|
4
|
+
import { RowResponsiveContext } from "../row/Row";
|
|
5
|
+
import "./col.css"
|
|
6
|
+
type ColProps = GridBreakpoints & {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
export const Col: React.FC<ColProps> = ({ xs, sm, md, lg, xl, children }) => {
|
|
10
|
+
const responsive = useContext(RowResponsiveContext);
|
|
11
|
+
return (
|
|
12
|
+
<ColStyled
|
|
13
|
+
className="col"
|
|
14
|
+
$responsive={responsive}
|
|
15
|
+
$xs={xs}
|
|
16
|
+
$sm={sm}
|
|
17
|
+
$md={md}
|
|
18
|
+
$lg={lg}
|
|
19
|
+
$xl={xl}
|
|
20
|
+
>
|
|
21
|
+
{children}
|
|
22
|
+
</ColStyled>
|
|
23
|
+
);
|
|
24
|
+
};
|
package/src/grid/col/col.css
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
.col {
|
|
2
|
-
padding: 0;
|
|
3
|
-
}
|
|
1
|
+
.col {
|
|
2
|
+
padding: 0;
|
|
3
|
+
}
|
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import styled, { css } from "styled-components";
|
|
2
|
-
import { GridColumnSpan, GridResponsive } from "../../grid.interface";
|
|
3
|
-
|
|
4
|
-
// Largeur = part de la ligne moins la part des gaps qui revient à la colonne.
|
|
5
|
-
// Pour une ligne dont les spans font 12, la somme des largeurs + les gaps = 100%.
|
|
6
|
-
const getColWidth = (size: number) =>
|
|
7
|
-
`calc(${(size / 12) * 100}% - var(--grid-gutter, 0px) * ${1 - size / 12})`;
|
|
8
|
-
|
|
9
|
-
// "auto" : base 0 et grow 1, les colonnes "auto" d'une ligne se partagent
|
|
10
|
-
// la place restante (gaps déduits) à parts égales.
|
|
11
|
-
const colSize = (size: GridColumnSpan = 12) =>
|
|
12
|
-
size === "auto"
|
|
13
|
-
? `flex: 1 1 0; max-width: 100%;`
|
|
14
|
-
: `flex: 0 0 ${getColWidth(size)}; max-width: ${getColWidth(size)};`;
|
|
15
|
-
|
|
16
|
-
// Règle de breakpoint selon la largeur de référence choisie sur la Row
|
|
17
|
-
const breakpoint = (responsive: GridResponsive, minWidth: number) => {
|
|
18
|
-
switch (responsive) {
|
|
19
|
-
case "viewport":
|
|
20
|
-
return `@media (min-width: ${minWidth}px)`;
|
|
21
|
-
case "row":
|
|
22
|
-
return `@container kelt-grid (min-width: ${minWidth}px)`;
|
|
23
|
-
default:
|
|
24
|
-
return `@container app-container (min-width: ${minWidth}px)`;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
type ColStyledProps = {
|
|
29
|
-
$responsive: GridResponsive;
|
|
30
|
-
$xs?: GridColumnSpan;
|
|
31
|
-
$sm?: GridColumnSpan;
|
|
32
|
-
$md?: GridColumnSpan;
|
|
33
|
-
$lg?: GridColumnSpan;
|
|
34
|
-
$xl?: GridColumnSpan;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const colAt = (
|
|
38
|
-
responsive: GridResponsive,
|
|
39
|
-
minWidth: number,
|
|
40
|
-
size?: GridColumnSpan
|
|
41
|
-
) =>
|
|
42
|
-
size &&
|
|
43
|
-
css`
|
|
44
|
-
${breakpoint(responsive, minWidth)} {
|
|
45
|
-
${colSize(size)}
|
|
46
|
-
}
|
|
47
|
-
`;
|
|
48
|
-
|
|
49
|
-
export const ColStyled = styled.div<ColStyledProps>`
|
|
50
|
-
box-sizing: border-box;
|
|
51
|
-
min-width: 0;
|
|
52
|
-
${({ $xs }) => colSize($xs)}
|
|
53
|
-
margin-bottom: 0.5rem;
|
|
54
|
-
margin-top: 0.5rem;
|
|
55
|
-
${({ $responsive, $sm }) => colAt($responsive, 576, $sm)}
|
|
56
|
-
${({ $responsive, $md }) => colAt($responsive, 768, $md)}
|
|
57
|
-
${({ $responsive, $lg }) => colAt($responsive, 992, $lg)}
|
|
58
|
-
${({ $responsive, $xl }) => colAt($responsive, 1200, $xl)}
|
|
59
|
-
`;
|
|
1
|
+
import styled, { css } from "styled-components";
|
|
2
|
+
import { GridColumnSpan, GridResponsive } from "../../grid.interface";
|
|
3
|
+
|
|
4
|
+
// Largeur = part de la ligne moins la part des gaps qui revient à la colonne.
|
|
5
|
+
// Pour une ligne dont les spans font 12, la somme des largeurs + les gaps = 100%.
|
|
6
|
+
const getColWidth = (size: number) =>
|
|
7
|
+
`calc(${(size / 12) * 100}% - var(--grid-gutter, 0px) * ${1 - size / 12})`;
|
|
8
|
+
|
|
9
|
+
// "auto" : base 0 et grow 1, les colonnes "auto" d'une ligne se partagent
|
|
10
|
+
// la place restante (gaps déduits) à parts égales.
|
|
11
|
+
const colSize = (size: GridColumnSpan = 12) =>
|
|
12
|
+
size === "auto"
|
|
13
|
+
? `flex: 1 1 0; max-width: 100%;`
|
|
14
|
+
: `flex: 0 0 ${getColWidth(size)}; max-width: ${getColWidth(size)};`;
|
|
15
|
+
|
|
16
|
+
// Règle de breakpoint selon la largeur de référence choisie sur la Row
|
|
17
|
+
const breakpoint = (responsive: GridResponsive, minWidth: number) => {
|
|
18
|
+
switch (responsive) {
|
|
19
|
+
case "viewport":
|
|
20
|
+
return `@media (min-width: ${minWidth}px)`;
|
|
21
|
+
case "row":
|
|
22
|
+
return `@container kelt-grid (min-width: ${minWidth}px)`;
|
|
23
|
+
default:
|
|
24
|
+
return `@container app-container (min-width: ${minWidth}px)`;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type ColStyledProps = {
|
|
29
|
+
$responsive: GridResponsive;
|
|
30
|
+
$xs?: GridColumnSpan;
|
|
31
|
+
$sm?: GridColumnSpan;
|
|
32
|
+
$md?: GridColumnSpan;
|
|
33
|
+
$lg?: GridColumnSpan;
|
|
34
|
+
$xl?: GridColumnSpan;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const colAt = (
|
|
38
|
+
responsive: GridResponsive,
|
|
39
|
+
minWidth: number,
|
|
40
|
+
size?: GridColumnSpan
|
|
41
|
+
) =>
|
|
42
|
+
size &&
|
|
43
|
+
css`
|
|
44
|
+
${breakpoint(responsive, minWidth)} {
|
|
45
|
+
${colSize(size)}
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
export const ColStyled = styled.div<ColStyledProps>`
|
|
50
|
+
box-sizing: border-box;
|
|
51
|
+
min-width: 0;
|
|
52
|
+
${({ $xs }) => colSize($xs)}
|
|
53
|
+
margin-bottom: 0.5rem;
|
|
54
|
+
margin-top: 0.5rem;
|
|
55
|
+
${({ $responsive, $sm }) => colAt($responsive, 576, $sm)}
|
|
56
|
+
${({ $responsive, $md }) => colAt($responsive, 768, $md)}
|
|
57
|
+
${({ $responsive, $lg }) => colAt($responsive, 992, $lg)}
|
|
58
|
+
${({ $responsive, $xl }) => colAt($responsive, 1200, $xl)}
|
|
59
|
+
`;
|
package/src/grid/row/Row.tsx
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { createContext } from "react";
|
|
2
|
-
import { GridResponsive } from "../grid.interface";
|
|
3
|
-
import "./row.css";
|
|
4
|
-
|
|
5
|
-
export type GridGap = boolean | number | string;
|
|
6
|
-
|
|
7
|
-
export const RowResponsiveContext = createContext<GridResponsive>("app");
|
|
8
|
-
|
|
9
|
-
type RowProps = {
|
|
10
|
-
children: React.ReactNode;
|
|
11
|
-
className?: string;
|
|
12
|
-
scroll?: boolean;
|
|
13
|
-
/** true (défaut) : gap par défaut, false : pas de gap, number : px, string : valeur CSS ("1rem") */
|
|
14
|
-
gap?: GridGap;
|
|
15
|
-
/** Largeur sur laquelle se basent les breakpoints des Col (défaut : "app") */
|
|
16
|
-
responsive?: GridResponsive;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const getGutter = (gap: GridGap) => {
|
|
20
|
-
if (gap === true) return undefined; // garde la valeur par défaut du CSS
|
|
21
|
-
if (gap === false) return "0px";
|
|
22
|
-
return typeof gap === "number" ? `${gap}px` : gap;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const Row: React.FC<RowProps> = ({
|
|
26
|
-
children,
|
|
27
|
-
className,
|
|
28
|
-
scroll,
|
|
29
|
-
gap = true,
|
|
30
|
-
responsive = "app",
|
|
31
|
-
}) => {
|
|
32
|
-
const gutter = getGutter(gap);
|
|
33
|
-
return (
|
|
34
|
-
<RowResponsiveContext.Provider value={responsive}>
|
|
35
|
-
<div
|
|
36
|
-
className={`grid-row ${className ?? ""} ${scroll ? "scroll" : ""} ${
|
|
37
|
-
responsive === "row" ? "grid-row--responsive" : ""
|
|
38
|
-
}`}
|
|
39
|
-
style={
|
|
40
|
-
gutter
|
|
41
|
-
? ({ "--grid-gutter": gutter } as React.CSSProperties)
|
|
42
|
-
: undefined
|
|
43
|
-
}
|
|
44
|
-
>
|
|
45
|
-
{children}
|
|
46
|
-
</div>
|
|
47
|
-
</RowResponsiveContext.Provider>
|
|
48
|
-
);
|
|
49
|
-
};
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
import { GridResponsive } from "../grid.interface";
|
|
3
|
+
import "./row.css";
|
|
4
|
+
|
|
5
|
+
export type GridGap = boolean | number | string;
|
|
6
|
+
|
|
7
|
+
export const RowResponsiveContext = createContext<GridResponsive>("app");
|
|
8
|
+
|
|
9
|
+
type RowProps = {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
scroll?: boolean;
|
|
13
|
+
/** true (défaut) : gap par défaut, false : pas de gap, number : px, string : valeur CSS ("1rem") */
|
|
14
|
+
gap?: GridGap;
|
|
15
|
+
/** Largeur sur laquelle se basent les breakpoints des Col (défaut : "app") */
|
|
16
|
+
responsive?: GridResponsive;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const getGutter = (gap: GridGap) => {
|
|
20
|
+
if (gap === true) return undefined; // garde la valeur par défaut du CSS
|
|
21
|
+
if (gap === false) return "0px";
|
|
22
|
+
return typeof gap === "number" ? `${gap}px` : gap;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const Row: React.FC<RowProps> = ({
|
|
26
|
+
children,
|
|
27
|
+
className,
|
|
28
|
+
scroll,
|
|
29
|
+
gap = true,
|
|
30
|
+
responsive = "app",
|
|
31
|
+
}) => {
|
|
32
|
+
const gutter = getGutter(gap);
|
|
33
|
+
return (
|
|
34
|
+
<RowResponsiveContext.Provider value={responsive}>
|
|
35
|
+
<div
|
|
36
|
+
className={`grid-row ${className ?? ""} ${scroll ? "scroll" : ""} ${
|
|
37
|
+
responsive === "row" ? "grid-row--responsive" : ""
|
|
38
|
+
}`}
|
|
39
|
+
style={
|
|
40
|
+
gutter
|
|
41
|
+
? ({ "--grid-gutter": gutter } as React.CSSProperties)
|
|
42
|
+
: undefined
|
|
43
|
+
}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
</div>
|
|
47
|
+
</RowResponsiveContext.Provider>
|
|
48
|
+
);
|
|
49
|
+
};
|
package/src/toaster/Toaster.tsx
CHANGED
|
@@ -14,6 +14,7 @@ export const Toaster = () => {
|
|
|
14
14
|
duration,
|
|
15
15
|
hideToast,
|
|
16
16
|
close,
|
|
17
|
+
position,
|
|
17
18
|
} = useToasterStore();
|
|
18
19
|
const onClose = useCallback(() => {
|
|
19
20
|
hideToast();
|
|
@@ -32,7 +33,7 @@ export const Toaster = () => {
|
|
|
32
33
|
if (!toasterRoot) return null;
|
|
33
34
|
|
|
34
35
|
return ReactDOM.createPortal(
|
|
35
|
-
<div className={`toaster toaster-${severity}`}>
|
|
36
|
+
<div className={`toaster toaster-${severity} toaster--${position}`}>
|
|
36
37
|
{close && (
|
|
37
38
|
<button
|
|
38
39
|
type="button"
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { create } from "zustand";
|
|
2
2
|
|
|
3
|
+
export type ToasterPosition =
|
|
4
|
+
| "top-right"
|
|
5
|
+
| "top-center"
|
|
6
|
+
| "bottom-right"
|
|
7
|
+
| "bottom-center";
|
|
8
|
+
|
|
3
9
|
type ToasterState = {
|
|
4
10
|
title: string;
|
|
5
11
|
description?: string;
|
|
@@ -8,6 +14,7 @@ type ToasterState = {
|
|
|
8
14
|
visible: boolean;
|
|
9
15
|
duration: number;
|
|
10
16
|
close?: boolean;
|
|
17
|
+
position: ToasterPosition;
|
|
11
18
|
showToast: (
|
|
12
19
|
title: string,
|
|
13
20
|
options?: {
|
|
@@ -16,6 +23,8 @@ type ToasterState = {
|
|
|
16
23
|
duration?: number;
|
|
17
24
|
children?: React.ReactNode;
|
|
18
25
|
close?: boolean;
|
|
26
|
+
/** Position à l'écran (défaut : "top-right") */
|
|
27
|
+
position?: ToasterPosition;
|
|
19
28
|
}
|
|
20
29
|
) => void;
|
|
21
30
|
hideToast: () => void;
|
|
@@ -28,6 +37,7 @@ export const useToasterStore = create<ToasterState>((set) => ({
|
|
|
28
37
|
visible: false,
|
|
29
38
|
duration: 2500,
|
|
30
39
|
close: true,
|
|
40
|
+
position: "top-right",
|
|
31
41
|
children: null,
|
|
32
42
|
showToast: (title, options = {}) =>
|
|
33
43
|
set(() => ({
|
|
@@ -38,6 +48,7 @@ export const useToasterStore = create<ToasterState>((set) => ({
|
|
|
38
48
|
visible: true,
|
|
39
49
|
children: options.children || null,
|
|
40
50
|
close: options.close ?? true,
|
|
51
|
+
position: options.position ?? "top-right",
|
|
41
52
|
})),
|
|
42
53
|
hideToast: () => set(() => ({ visible: false })),
|
|
43
54
|
}));
|
package/src/toaster/toaster.css
CHANGED
|
@@ -11,6 +11,19 @@
|
|
|
11
11
|
width: 300px;
|
|
12
12
|
border-radius: 4px;
|
|
13
13
|
border: 1px solid #dede;
|
|
14
|
+
&.toaster--bottom-right,
|
|
15
|
+
&.toaster--bottom-center {
|
|
16
|
+
top: auto;
|
|
17
|
+
bottom: 0.5rem;
|
|
18
|
+
}
|
|
19
|
+
&.toaster--top-center,
|
|
20
|
+
&.toaster--bottom-center {
|
|
21
|
+
right: auto;
|
|
22
|
+
left: 50%;
|
|
23
|
+
transform: translateX(-50%);
|
|
24
|
+
max-width: calc(100vw - 1rem);
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
}
|
|
14
27
|
.toaster--close {
|
|
15
28
|
position: absolute;
|
|
16
29
|
top: 2px;
|