@pushwoosh/dumb-components 0.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/EmailTemplatePreview/EmailTemplatePreview.d.ts +11 -0
- package/EmailTemplatePreview/EmailTemplatePreview.js +32 -0
- package/EmailTemplatePreview/helpers.d.ts +1 -0
- package/EmailTemplatePreview/helpers.js +8 -0
- package/EmailTemplatePreview/index.d.ts +1 -0
- package/EmailTemplatePreview/index.js +1 -0
- package/EmailTemplatePreview/styled.d.ts +5 -0
- package/EmailTemplatePreview/styled.js +22 -0
- package/ProgressBar/ProgressBar.d.ts +3 -0
- package/ProgressBar/ProgressBar.js +19 -0
- package/ProgressBar/index.d.ts +1 -0
- package/ProgressBar/index.js +1 -0
- package/ProgressBar/styled.d.ts +15 -0
- package/ProgressBar/styled.js +45 -0
- package/ProgressBar/types.d.ts +8 -0
- package/ProgressBar/types.js +1 -0
- package/Tabs/index.d.ts +5 -0
- package/Tabs/index.js +5 -0
- package/Tabs/tab/index.d.ts +2 -0
- package/Tabs/tab/index.js +2 -0
- package/Tabs/tab/tab.d.ts +8 -0
- package/Tabs/tab/tab.js +26 -0
- package/Tabs/tab/tab.types.d.ts +9 -0
- package/Tabs/tab/tab.types.js +1 -0
- package/Tabs/tab-bar/index.d.ts +2 -0
- package/Tabs/tab-bar/index.js +2 -0
- package/Tabs/tab-bar/tab-bar.d.ts +4 -0
- package/Tabs/tab-bar/tab-bar.js +16 -0
- package/Tabs/tab-bar/tab-bar.styles.d.ts +4 -0
- package/Tabs/tab-bar/tab-bar.styles.js +12 -0
- package/Tabs/tab-bar/tab-bar.types.d.ts +4 -0
- package/Tabs/tab-bar/tab-bar.types.js +1 -0
- package/Tabs/tab-base/index.d.ts +3 -0
- package/Tabs/tab-base/index.js +3 -0
- package/Tabs/tab-base/tab-base.d.ts +9 -0
- package/Tabs/tab-base/tab-base.js +22 -0
- package/Tabs/tab-base/tab-base.styles.d.ts +11 -0
- package/Tabs/tab-base/tab-base.styles.js +41 -0
- package/Tabs/tab-base/tab-base.types.d.ts +9 -0
- package/Tabs/tab-base/tab-base.types.js +1 -0
- package/Tabs/tab-panel/index.d.ts +2 -0
- package/Tabs/tab-panel/index.js +2 -0
- package/Tabs/tab-panel/styles.d.ts +1 -0
- package/Tabs/tab-panel/styles.js +5 -0
- package/Tabs/tab-panel/tab-panel.d.ts +3 -0
- package/Tabs/tab-panel/tab-panel.js +16 -0
- package/Tabs/tab-panel/tab-panel.types.d.ts +5 -0
- package/Tabs/tab-panel/tab-panel.types.js +1 -0
- package/Tabs/tabs/index.d.ts +2 -0
- package/Tabs/tabs/index.js +2 -0
- package/Tabs/tabs/styles.d.ts +1 -0
- package/Tabs/tabs/styles.js +6 -0
- package/Tabs/tabs/tabs.d.ts +3 -0
- package/Tabs/tabs/tabs.js +17 -0
- package/Tabs/tabs/tabs.types.d.ts +6 -0
- package/Tabs/tabs/tabs.types.js +1 -0
- package/Tabs/tabs-list-slide-frame/index.d.ts +3 -0
- package/Tabs/tabs-list-slide-frame/index.js +3 -0
- package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.d.ts +3 -0
- package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.js +68 -0
- package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.styles.d.ts +9 -0
- package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.styles.js +26 -0
- package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.types.d.ts +1 -0
- package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.types.js +1 -0
- package/Tabs/tabs.context.d.ts +4 -0
- package/Tabs/tabs.context.js +9 -0
- package/Tabs/tabs.helpers.d.ts +1 -0
- package/Tabs/tabs.helpers.js +18 -0
- package/Tabs/tabs.types.d.ts +5 -0
- package/Tabs/tabs.types.js +1 -0
- package/index.d.ts +3 -0
- package/index.js +3 -0
- package/package.json +47 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FC } from 'react';
|
|
2
|
+
type PreviewIframeProps = {
|
|
3
|
+
scale?: number;
|
|
4
|
+
width?: string;
|
|
5
|
+
height?: string;
|
|
6
|
+
template: string;
|
|
7
|
+
localization: Record<string, string>;
|
|
8
|
+
values: Record<string, any>;
|
|
9
|
+
};
|
|
10
|
+
export declare const EmailTemplatePreview: FC<PreviewIframeProps>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Liquid } from 'liquidjs';
|
|
2
|
+
import React, { useMemo, useState } from 'react';
|
|
3
|
+
import { replacePlaceholders } from './helpers';
|
|
4
|
+
import { IframeStyled } from './styled';
|
|
5
|
+
const createLiquidInstance = () => new Liquid();
|
|
6
|
+
export const EmailTemplatePreview = ({
|
|
7
|
+
scale,
|
|
8
|
+
width,
|
|
9
|
+
height,
|
|
10
|
+
template,
|
|
11
|
+
localization,
|
|
12
|
+
values
|
|
13
|
+
}) => {
|
|
14
|
+
const [liquidInstance] = useState(createLiquidInstance);
|
|
15
|
+
const src = useMemo(() => {
|
|
16
|
+
try {
|
|
17
|
+
return liquidInstance.parseAndRenderSync(replacePlaceholders(template, localization), values);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.error('Error in PreviewIframe', e);
|
|
20
|
+
return `<body style="font-size: 24px; color: darkred">${e.message}</body>`;
|
|
21
|
+
}
|
|
22
|
+
}, [template, localization, values, liquidInstance]);
|
|
23
|
+
return React.createElement(IframeStyled, {
|
|
24
|
+
"$scale": scale,
|
|
25
|
+
"$width": width,
|
|
26
|
+
"$height": height
|
|
27
|
+
}, React.createElement("iframe", {
|
|
28
|
+
srcDoc: src,
|
|
29
|
+
sandbox: "allow-same-origin",
|
|
30
|
+
title: "preview"
|
|
31
|
+
}));
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function replacePlaceholders(str: string, placeholders: Record<string, string>): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function replacePlaceholders(str, placeholders) {
|
|
2
|
+
const keys = Object.keys(placeholders);
|
|
3
|
+
return keys.reduce((acc, key) => {
|
|
4
|
+
const escaped = key.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&');
|
|
5
|
+
const pattern = new RegExp(`{{${escaped}(\\|[^}]*)?}}`, 'g');
|
|
6
|
+
return acc.replace(pattern, placeholders[key]);
|
|
7
|
+
}, str);
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EmailTemplatePreview } from './EmailTemplatePreview';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { EmailTemplatePreview } from './EmailTemplatePreview';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
export const IframeStyled = styled.div.withConfig({
|
|
3
|
+
displayName: "IframeStyled",
|
|
4
|
+
componentId: "sc-jqsau1-0"
|
|
5
|
+
})(["", " ", " overflow:hidden;background-color:#fff;& > iframe{", " ", " ", " border:none;padding:0;}"], ({
|
|
6
|
+
$width
|
|
7
|
+
}) => $width && `width: ${$width};`, ({
|
|
8
|
+
$height
|
|
9
|
+
}) => $height && `height: ${$height};`, ({
|
|
10
|
+
$scale
|
|
11
|
+
}) => {
|
|
12
|
+
if ($scale) {
|
|
13
|
+
const translate = -50 * ($scale - 1) / $scale;
|
|
14
|
+
return `transform: translateX(${translate}%) translateY(${translate}%) scale(${1 / $scale});`;
|
|
15
|
+
}
|
|
16
|
+
}, ({
|
|
17
|
+
$scale,
|
|
18
|
+
$width
|
|
19
|
+
}) => $width && `width: ${$scale ? `calc(${$scale}*${$width})` : $width};`, ({
|
|
20
|
+
$scale,
|
|
21
|
+
$height
|
|
22
|
+
}) => $height && `height: ${$scale ? `calc(${$scale}*${$height})` : $height};`);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Color } from '@pushwoosh/kit-constants';
|
|
3
|
+
import { Spinner } from '@pushwoosh/kit-spinner';
|
|
4
|
+
import { Container, LoadingHeader, LoadingText, ProgressLine, ProgressBarActive, ProgressBoxContainer, RightSlotContainer, SpinnerContainer, ProgressLineContainer } from './styled';
|
|
5
|
+
export const ProgressBar = ({
|
|
6
|
+
percentValue,
|
|
7
|
+
title,
|
|
8
|
+
rightSlot,
|
|
9
|
+
color = Color.BRIGHT,
|
|
10
|
+
backgroundColor = Color.BRIGHT_LIGHT
|
|
11
|
+
}) => React.createElement(Container, null, React.createElement(SpinnerContainer, {
|
|
12
|
+
"$backgroundColor": backgroundColor
|
|
13
|
+
}, React.createElement(Spinner, {
|
|
14
|
+
color: color,
|
|
15
|
+
size: "medium"
|
|
16
|
+
})), React.createElement(ProgressBoxContainer, null, React.createElement(LoadingHeader, null, React.createElement(LoadingText, null, title, ' ', `${percentValue}%`), rightSlot && React.createElement(RightSlotContainer, null, rightSlot)), React.createElement(ProgressLineContainer, null, React.createElement(ProgressLine, null, React.createElement(ProgressBarActive, {
|
|
17
|
+
"$width": percentValue,
|
|
18
|
+
"$color": color
|
|
19
|
+
})))));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ProgressBar } from './ProgressBar';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ProgressBar } from './ProgressBar';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { H5 } from '@pushwoosh/kit-typography';
|
|
2
|
+
export declare const ProgressLine: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
3
|
+
export declare const ProgressLineContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
4
|
+
export declare const ProgressBarActive: import("styled-components").StyledComponent<"div", any, {
|
|
5
|
+
$width: number;
|
|
6
|
+
$color: string;
|
|
7
|
+
}, never>;
|
|
8
|
+
export declare const Container: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
9
|
+
export declare const SpinnerContainer: import("styled-components").StyledComponent<"div", any, {
|
|
10
|
+
$backgroundColor: string;
|
|
11
|
+
}, never>;
|
|
12
|
+
export declare const ProgressBoxContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
13
|
+
export declare const LoadingHeader: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
14
|
+
export declare const LoadingText: import("styled-components").StyledComponent<typeof H5, any, {}, never>;
|
|
15
|
+
export declare const RightSlotContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Color, FontSize, ShapeRadius, Spacing } from '@pushwoosh/kit-constants';
|
|
3
|
+
import { H5 } from '@pushwoosh/kit-typography';
|
|
4
|
+
export const ProgressLine = styled.div.withConfig({
|
|
5
|
+
displayName: "ProgressLine",
|
|
6
|
+
componentId: "sc-1asyx7c-0"
|
|
7
|
+
})(["display:flex;height:5px;border-radius:", ";background:", ";"], ShapeRadius.CONTROL, Color.SOFT_LIGHT);
|
|
8
|
+
export const ProgressLineContainer = styled.div.withConfig({
|
|
9
|
+
displayName: "ProgressLineContainer",
|
|
10
|
+
componentId: "sc-1asyx7c-1"
|
|
11
|
+
})(["padding:", " 0;"], Spacing.S1);
|
|
12
|
+
export const ProgressBarActive = styled(ProgressLine).withConfig({
|
|
13
|
+
displayName: "ProgressBarActive",
|
|
14
|
+
componentId: "sc-1asyx7c-2"
|
|
15
|
+
})(["width:", ";background:", ";"], ({
|
|
16
|
+
$width
|
|
17
|
+
}) => `${$width}%`, ({
|
|
18
|
+
$color
|
|
19
|
+
}) => $color || Color.BRIGHT);
|
|
20
|
+
export const Container = styled.div.withConfig({
|
|
21
|
+
displayName: "Container",
|
|
22
|
+
componentId: "sc-1asyx7c-3"
|
|
23
|
+
})(["display:flex;width:100%;gap:", ";align-items:center;"], Spacing.S4);
|
|
24
|
+
export const SpinnerContainer = styled.div.withConfig({
|
|
25
|
+
displayName: "SpinnerContainer",
|
|
26
|
+
componentId: "sc-1asyx7c-4"
|
|
27
|
+
})(["background-color:", ";border-radius:", ";padding:", ";"], ({
|
|
28
|
+
$backgroundColor
|
|
29
|
+
}) => $backgroundColor, ShapeRadius.CONTROL, Spacing.S1);
|
|
30
|
+
export const ProgressBoxContainer = styled.div.withConfig({
|
|
31
|
+
displayName: "ProgressBoxContainer",
|
|
32
|
+
componentId: "sc-1asyx7c-5"
|
|
33
|
+
})(["display:flex;flex-direction:column;flex:1;"]);
|
|
34
|
+
export const LoadingHeader = styled.div.withConfig({
|
|
35
|
+
displayName: "LoadingHeader",
|
|
36
|
+
componentId: "sc-1asyx7c-6"
|
|
37
|
+
})(["display:flex;gap:", ";align-items:center;justify-content:space-between;"], Spacing.S2);
|
|
38
|
+
export const LoadingText = styled(H5).withConfig({
|
|
39
|
+
displayName: "LoadingText",
|
|
40
|
+
componentId: "sc-1asyx7c-7"
|
|
41
|
+
})(["color:", ";text-transform:uppercase;font-size:", ";"], Color.MAIN, FontSize.SMALL);
|
|
42
|
+
export const RightSlotContainer = styled.div.withConfig({
|
|
43
|
+
displayName: "RightSlotContainer",
|
|
44
|
+
componentId: "sc-1asyx7c-8"
|
|
45
|
+
})(["display:flex;right:0;"]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/Tabs/index.d.ts
ADDED
package/Tabs/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare const Tab: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref" | "onClick"> & Readonly<{
|
|
3
|
+
code: import("..").TabCode;
|
|
4
|
+
onActivate?: (code: import("..").TabCode) => void;
|
|
5
|
+
isDisabled?: boolean;
|
|
6
|
+
isNew?: boolean;
|
|
7
|
+
icon?: React.ReactNode;
|
|
8
|
+
}> & React.RefAttributes<HTMLDivElement>>;
|
package/Tabs/tab/tab.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { TabBase } from '../tab-base';
|
|
3
|
+
import { useTabsContext } from '../tabs.context';
|
|
4
|
+
export const Tab = forwardRef((props, ref) => {
|
|
5
|
+
const {
|
|
6
|
+
code,
|
|
7
|
+
children,
|
|
8
|
+
onActivate,
|
|
9
|
+
...rest
|
|
10
|
+
} = props;
|
|
11
|
+
const {
|
|
12
|
+
activeTabCode,
|
|
13
|
+
setActiveTabCode
|
|
14
|
+
} = useTabsContext();
|
|
15
|
+
return React.createElement(TabBase, {
|
|
16
|
+
isActive: code === activeTabCode,
|
|
17
|
+
ref: ref,
|
|
18
|
+
onClick: () => {
|
|
19
|
+
if (!rest.isDisabled) {
|
|
20
|
+
setActiveTabCode(code);
|
|
21
|
+
onActivate === null || onActivate === void 0 || onActivate(code);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
...rest
|
|
25
|
+
}, children);
|
|
26
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { TabCode } from '../tabs.types';
|
|
3
|
+
export type TabProps = Omit<JSX.IntrinsicElements['div'], 'ref' | 'onClick'> & Readonly<{
|
|
4
|
+
code: TabCode;
|
|
5
|
+
onActivate?: (code: TabCode) => void;
|
|
6
|
+
isDisabled?: boolean;
|
|
7
|
+
isNew?: boolean;
|
|
8
|
+
icon?: ReactNode;
|
|
9
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { H4 } from '@pushwoosh/kit-typography';
|
|
3
|
+
import { TabBarTitleBox, TabBarContainer } from './tab-bar.styles';
|
|
4
|
+
import { TabBarScrollableFrame } from '../tabs-list-slide-frame';
|
|
5
|
+
export const TabBar = forwardRef((props, ref) => {
|
|
6
|
+
const {
|
|
7
|
+
children,
|
|
8
|
+
title,
|
|
9
|
+
...rest
|
|
10
|
+
} = props;
|
|
11
|
+
return React.createElement(TabBarContainer, {
|
|
12
|
+
hasTitle: !!title,
|
|
13
|
+
ref: ref,
|
|
14
|
+
...rest
|
|
15
|
+
}, title && React.createElement(TabBarTitleBox, null, React.createElement(H4, null, title)), React.createElement(TabBarScrollableFrame, null, children));
|
|
16
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Color, Spacing } from '@pushwoosh/kit-constants';
|
|
3
|
+
export const TabBarContainer = styled.div.withConfig({
|
|
4
|
+
displayName: "TabBarContainer",
|
|
5
|
+
componentId: "sc-1z0lfzo-0"
|
|
6
|
+
})(["position:relative;display:grid;grid-template-columns:", ";width:100%;height:40px;background:", ";border-radius:8px;padding:", ";"], ({
|
|
7
|
+
hasTitle
|
|
8
|
+
}) => hasTitle ? 'max-content 1fr' : '1fr', Color.SOFT_LIGHT, Spacing.S1);
|
|
9
|
+
export const TabBarTitleBox = styled.div.withConfig({
|
|
10
|
+
displayName: "TabBarTitleBox",
|
|
11
|
+
componentId: "sc-1z0lfzo-1"
|
|
12
|
+
})(["display:flex;align-items:center;position:relative;padding:0 ", " 0 ", ";"], Spacing.S4, Spacing.S5);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare const TabBase: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & Readonly<{
|
|
3
|
+
isActive?: boolean;
|
|
4
|
+
isDisabled?: boolean;
|
|
5
|
+
isNew?: boolean;
|
|
6
|
+
icon?: React.ReactNode;
|
|
7
|
+
onClick: () => void;
|
|
8
|
+
className?: string;
|
|
9
|
+
}> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { TabIconBox, TabRedDot, TabBody, TabButtonLabel } from './tab-base.styles';
|
|
3
|
+
export const TabBase = forwardRef((props, ref) => {
|
|
4
|
+
const {
|
|
5
|
+
isActive,
|
|
6
|
+
isDisabled,
|
|
7
|
+
children,
|
|
8
|
+
isNew,
|
|
9
|
+
icon,
|
|
10
|
+
...rest
|
|
11
|
+
} = props;
|
|
12
|
+
return React.createElement(TabBody, {
|
|
13
|
+
as: "span",
|
|
14
|
+
"$isActive": isActive,
|
|
15
|
+
"$isDisabled": isDisabled,
|
|
16
|
+
"$hasIcon": !!icon,
|
|
17
|
+
ref: ref,
|
|
18
|
+
...rest
|
|
19
|
+
}, React.createElement(TabButtonLabel, {
|
|
20
|
+
"$isActive": isActive
|
|
21
|
+
}, children), icon && React.createElement(TabIconBox, null, icon), isNew && React.createElement(TabRedDot, null));
|
|
22
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { H4 } from '@pushwoosh/kit-typography';
|
|
2
|
+
export declare const TabBody: import("styled-components").StyledComponent<"div", any, {
|
|
3
|
+
$isActive?: boolean;
|
|
4
|
+
$isDisabled?: boolean;
|
|
5
|
+
$hasIcon?: boolean;
|
|
6
|
+
}, never>;
|
|
7
|
+
export declare const TabRedDot: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
8
|
+
export declare const TabButtonLabel: import("styled-components").StyledComponent<typeof H4, any, {
|
|
9
|
+
$isActive?: boolean;
|
|
10
|
+
}, never>;
|
|
11
|
+
export declare const TabIconBox: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import styled, { css } from 'styled-components';
|
|
2
|
+
import { Color, Shadow, ShapeRadius, Spacing } from '@pushwoosh/kit-constants';
|
|
3
|
+
import { H4 } from '@pushwoosh/kit-typography';
|
|
4
|
+
const tabBodyHover = css(["&:hover{color:", ";background-color:", ";}"], Color.PRIMARY_HOVER, Color.BRIGHT_LIGHT);
|
|
5
|
+
export const TabBody = styled.div.withConfig({
|
|
6
|
+
displayName: "TabBody",
|
|
7
|
+
componentId: "sc-1vksurj-0"
|
|
8
|
+
})(["display:flex;justify-content:center;align-items:center;position:relative;padding:", " ", " ", " ", ";background-color:", ";border-radius:", ";box-shadow:", ";cursor:", ";user-select:none;white-space:nowrap;color:", ";", ""], Spacing.S2, ({
|
|
9
|
+
$hasIcon
|
|
10
|
+
}) => $hasIcon ? Spacing.S4 : Spacing.S5, Spacing.S2, Spacing.S5, ({
|
|
11
|
+
$isActive
|
|
12
|
+
}) => $isActive ? Color.CLEAR : 'transparent', ShapeRadius.CONTROL, ({
|
|
13
|
+
$isActive
|
|
14
|
+
}) => $isActive ? Shadow.SMALL : 'none', ({
|
|
15
|
+
$isActive,
|
|
16
|
+
$isDisabled
|
|
17
|
+
}) => {
|
|
18
|
+
if ($isDisabled) {
|
|
19
|
+
return 'not-allowed';
|
|
20
|
+
}
|
|
21
|
+
return $isActive ? 'default' : 'pointer';
|
|
22
|
+
}, ({
|
|
23
|
+
$isDisabled
|
|
24
|
+
}) => $isDisabled ? Color.LOCKED : Color.MAIN, ({
|
|
25
|
+
$isActive,
|
|
26
|
+
$isDisabled
|
|
27
|
+
}) => !$isActive && !$isDisabled && tabBodyHover);
|
|
28
|
+
export const TabRedDot = styled.div.withConfig({
|
|
29
|
+
displayName: "TabRedDot",
|
|
30
|
+
componentId: "sc-1vksurj-1"
|
|
31
|
+
})(["width:4px;height:20px;position:relative;&::before{content:\"\";background-color:", ";position:absolute;top:0;left:0;width:4px;height:4px;border-radius:4px;}"], Color.DANGER);
|
|
32
|
+
export const TabButtonLabel = styled(H4).withConfig({
|
|
33
|
+
displayName: "TabButtonLabel",
|
|
34
|
+
componentId: "sc-1vksurj-2"
|
|
35
|
+
})(["opacity:", ";"], ({
|
|
36
|
+
$isActive
|
|
37
|
+
}) => $isActive ? 1 : 0.8);
|
|
38
|
+
export const TabIconBox = styled.div.withConfig({
|
|
39
|
+
displayName: "TabIconBox",
|
|
40
|
+
componentId: "sc-1vksurj-3"
|
|
41
|
+
})(["margin-left:", ";"], Spacing.S1);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TabPanelContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TabPanelContainer } from './styles';
|
|
3
|
+
import { useTabsContext } from '../tabs.context';
|
|
4
|
+
export const TabPanel = props => {
|
|
5
|
+
const {
|
|
6
|
+
code,
|
|
7
|
+
children
|
|
8
|
+
} = props;
|
|
9
|
+
const {
|
|
10
|
+
activeTabCode
|
|
11
|
+
} = useTabsContext();
|
|
12
|
+
if (code !== activeTabCode) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return React.createElement(TabPanelContainer, null, children);
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TabsContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Spacing } from '@pushwoosh/kit-constants';
|
|
3
|
+
export const TabsContainer = styled.div.withConfig({
|
|
4
|
+
displayName: "TabsContainer",
|
|
5
|
+
componentId: "sc-1z082s8-0"
|
|
6
|
+
})(["display:flex;flex-direction:column;gap:", ";width:100%;height:100%;"], Spacing.S5);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { TabsContainer } from './styles';
|
|
3
|
+
import { TabContext } from '../tabs.context';
|
|
4
|
+
export function Tabs(props) {
|
|
5
|
+
const {
|
|
6
|
+
activeCode: activeTabCode,
|
|
7
|
+
onChange: setActiveTabCode,
|
|
8
|
+
children
|
|
9
|
+
} = props;
|
|
10
|
+
const contextValue = useMemo(() => ({
|
|
11
|
+
activeTabCode,
|
|
12
|
+
setActiveTabCode
|
|
13
|
+
}), [activeTabCode, setActiveTabCode]);
|
|
14
|
+
return React.createElement(TabContext.Provider, {
|
|
15
|
+
value: contextValue
|
|
16
|
+
}, React.createElement(TabsContainer, null, children));
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import debounce from 'lodash/debounce';
|
|
2
|
+
import React, { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { ChevronIcon } from '@pushwoosh/kit-icons';
|
|
4
|
+
import { TabBarContent, TabBarFrame, TabBarArrowContainer, TabBarWindow } from './tabs-list-slide-frame.styles';
|
|
5
|
+
import { widthObserver } from '../tabs.helpers';
|
|
6
|
+
export const TabBarScrollableFrame = forwardRef(({
|
|
7
|
+
children,
|
|
8
|
+
...props
|
|
9
|
+
}, ref) => {
|
|
10
|
+
const windowRef = useRef(null);
|
|
11
|
+
const contentRef = useRef(null);
|
|
12
|
+
const [frameWidth, setFrameWidth] = useState(0);
|
|
13
|
+
const [contentWidth, setContentWidth] = useState(0);
|
|
14
|
+
const [scrollLeft, setScrollLeft] = useState(0);
|
|
15
|
+
const scrollable = contentWidth > frameWidth;
|
|
16
|
+
const minLeft = frameWidth - contentWidth;
|
|
17
|
+
const onClick = useCallback(event => {
|
|
18
|
+
const {
|
|
19
|
+
currentTarget
|
|
20
|
+
} = event;
|
|
21
|
+
setScrollLeft(curVal => {
|
|
22
|
+
if (currentTarget.dataset.left) {
|
|
23
|
+
const newVal = curVal + frameWidth * 0.75;
|
|
24
|
+
return newVal > 0 ? 0 : newVal;
|
|
25
|
+
}
|
|
26
|
+
const newVal = curVal - frameWidth * 0.75;
|
|
27
|
+
return newVal < minLeft ? minLeft : newVal;
|
|
28
|
+
});
|
|
29
|
+
}, [frameWidth, minLeft]);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (contentWidth > frameWidth) {
|
|
32
|
+
if (scrollLeft + contentWidth < frameWidth) {
|
|
33
|
+
setScrollLeft(frameWidth - contentWidth);
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
setScrollLeft(0);
|
|
37
|
+
}
|
|
38
|
+
}, [frameWidth, contentWidth, scrollLeft]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const stopFrameObserver = widthObserver(windowRef.current, setFrameWidth);
|
|
41
|
+
const stopContentObserver = widthObserver(contentRef.current, debounce(setContentWidth, 50));
|
|
42
|
+
return () => {
|
|
43
|
+
stopContentObserver();
|
|
44
|
+
stopFrameObserver();
|
|
45
|
+
};
|
|
46
|
+
}, [windowRef, setFrameWidth, contentRef, setContentWidth]);
|
|
47
|
+
return React.createElement(TabBarFrame, {
|
|
48
|
+
...props,
|
|
49
|
+
ref: ref
|
|
50
|
+
}, React.createElement(TabBarWindow, {
|
|
51
|
+
ref: windowRef
|
|
52
|
+
}, React.createElement(TabBarContent, {
|
|
53
|
+
left: scrollLeft,
|
|
54
|
+
ref: contentRef
|
|
55
|
+
}, children)), scrollable && scrollLeft < 0 && React.createElement(TabBarArrowContainer, {
|
|
56
|
+
"data-left": true,
|
|
57
|
+
onClick: onClick
|
|
58
|
+
}, React.createElement(ChevronIcon, {
|
|
59
|
+
direction: "left",
|
|
60
|
+
size: "small"
|
|
61
|
+
})), scrollable && scrollLeft > minLeft && React.createElement(TabBarArrowContainer, {
|
|
62
|
+
"$right": true,
|
|
63
|
+
onClick: onClick
|
|
64
|
+
}, React.createElement(ChevronIcon, {
|
|
65
|
+
direction: "right",
|
|
66
|
+
size: "small"
|
|
67
|
+
})));
|
|
68
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const TabBarArrowContainer: import("styled-components").StyledComponent<"div", any, {
|
|
2
|
+
$right?: boolean;
|
|
3
|
+
}, never>;
|
|
4
|
+
export declare const TabBarWindow: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
5
|
+
export declare const TabsListContentBase: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
6
|
+
export declare const TabBarContent: import("styled-components").StyledComponent<"div", any, {
|
|
7
|
+
left: number;
|
|
8
|
+
}, never>;
|
|
9
|
+
export declare const TabBarFrame: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
import { Color, Shadow, ShapeRadius, Spacing } from '@pushwoosh/kit-constants';
|
|
3
|
+
export const TabBarArrowContainer = styled.div.withConfig({
|
|
4
|
+
displayName: "TabBarArrowContainer",
|
|
5
|
+
componentId: "sc-u8lb05-0"
|
|
6
|
+
})(["position:absolute;top:0;", ":0;display:flex;align-items:center;height:32px;cursor:pointer;color:", ";background-color:", ";box-shadow:", ";border-radius:", ";padding:", " ", ";&:hover{color:", ";}"], ({
|
|
7
|
+
$right
|
|
8
|
+
}) => $right ? 'right' : 'left', Color.MAIN, Color.CLEAR, Shadow.SMALL, ShapeRadius.CONTROL, Spacing.S3, Spacing.S1, Color.PRIMARY_HOVER);
|
|
9
|
+
export const TabBarWindow = styled.div.withConfig({
|
|
10
|
+
displayName: "TabBarWindow",
|
|
11
|
+
componentId: "sc-u8lb05-1"
|
|
12
|
+
})(["position:relative;height:32px;width:100%;overflow:hidden;"]);
|
|
13
|
+
export const TabsListContentBase = styled.div.withConfig({
|
|
14
|
+
displayName: "TabsListContentBase",
|
|
15
|
+
componentId: "sc-u8lb05-2"
|
|
16
|
+
})(["position:absolute;top:0;display:flex;align-items:center;transition:left .4s ease-in;"]);
|
|
17
|
+
export const TabBarContent = styled(TabsListContentBase).withConfig({
|
|
18
|
+
displayName: "TabBarContent",
|
|
19
|
+
componentId: "sc-u8lb05-3"
|
|
20
|
+
})(["left:", "px;gap:", ";"], ({
|
|
21
|
+
left
|
|
22
|
+
}) => left, Spacing.S1);
|
|
23
|
+
export const TabBarFrame = styled.div.withConfig({
|
|
24
|
+
displayName: "TabBarFrame",
|
|
25
|
+
componentId: "sc-u8lb05-4"
|
|
26
|
+
})(["position:relative;width:100%;"]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type TabsListSlideFrameProps = Omit<JSX.IntrinsicElements['div'], 'ref'>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function widthObserver(element: Element, onWidthChanged: (width: number) => void): () => void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function widthObserver(element, onWidthChanged) {
|
|
2
|
+
if (!window.ResizeObserver) {
|
|
3
|
+
let lastWidth = 0;
|
|
4
|
+
const interval = setInterval(() => {
|
|
5
|
+
const {
|
|
6
|
+
width
|
|
7
|
+
} = element.getBoundingClientRect();
|
|
8
|
+
if (width !== lastWidth) {
|
|
9
|
+
lastWidth = width;
|
|
10
|
+
onWidthChanged(width);
|
|
11
|
+
}
|
|
12
|
+
}, 999);
|
|
13
|
+
return () => clearInterval(interval);
|
|
14
|
+
}
|
|
15
|
+
const observer = new ResizeObserver(entries => onWidthChanged(entries[0].contentRect.width));
|
|
16
|
+
observer.observe(element);
|
|
17
|
+
return () => observer.disconnect();
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/index.d.ts
ADDED
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pushwoosh/dumb-components",
|
|
3
|
+
"version": "0.0.8",
|
|
4
|
+
"description": "React components to build Pushwoosh products",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"module": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "npm run playground",
|
|
11
|
+
"build": "pushwoosh-engine lib:build",
|
|
12
|
+
"playground": "`pushwoosh-engine lib:command:playground`",
|
|
13
|
+
"check": "npm run check:lint && npm run check:types",
|
|
14
|
+
"check:lint": "echo \"Run check:lint\" && eslint .",
|
|
15
|
+
"check:types": "echo \"Run check:types\" && pushwoosh-engine lib:check-types"
|
|
16
|
+
},
|
|
17
|
+
"pre-commit": "check",
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@pushwoosh/frontend-builder-engine": "^1.0.4",
|
|
20
|
+
"@pushwoosh/kit-constants": "^1.6.0",
|
|
21
|
+
"@types/lodash": "^4.17.13",
|
|
22
|
+
"@types/react": "^18.2.69",
|
|
23
|
+
"@types/react-dom": "^18.2.22",
|
|
24
|
+
"@types/styled-components": "^5.1.34",
|
|
25
|
+
"pre-commit": "^1.2.2",
|
|
26
|
+
"react": "^18.2.0",
|
|
27
|
+
"react-dom": "^18.2.0",
|
|
28
|
+
"react-router-dom": "^6.22.3",
|
|
29
|
+
"styled-components": "^5.3.11"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"@pushwoosh/kit-constants": "^1.6.0",
|
|
33
|
+
"react": ">= 16.14.0",
|
|
34
|
+
"styled-components": "^5.3.3 || ^6.0.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">= 18",
|
|
38
|
+
"npm": ">= 7"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@pushwoosh/kit-icons": "^2.0.25",
|
|
42
|
+
"@pushwoosh/kit-spinner": "^1.5.1",
|
|
43
|
+
"@pushwoosh/kit-typography": "^1.7.1",
|
|
44
|
+
"liquidjs": "^10.18.0",
|
|
45
|
+
"lodash": "^4.17.21"
|
|
46
|
+
}
|
|
47
|
+
}
|