@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.
Files changed (73) hide show
  1. package/EmailTemplatePreview/EmailTemplatePreview.d.ts +11 -0
  2. package/EmailTemplatePreview/EmailTemplatePreview.js +32 -0
  3. package/EmailTemplatePreview/helpers.d.ts +1 -0
  4. package/EmailTemplatePreview/helpers.js +8 -0
  5. package/EmailTemplatePreview/index.d.ts +1 -0
  6. package/EmailTemplatePreview/index.js +1 -0
  7. package/EmailTemplatePreview/styled.d.ts +5 -0
  8. package/EmailTemplatePreview/styled.js +22 -0
  9. package/ProgressBar/ProgressBar.d.ts +3 -0
  10. package/ProgressBar/ProgressBar.js +19 -0
  11. package/ProgressBar/index.d.ts +1 -0
  12. package/ProgressBar/index.js +1 -0
  13. package/ProgressBar/styled.d.ts +15 -0
  14. package/ProgressBar/styled.js +45 -0
  15. package/ProgressBar/types.d.ts +8 -0
  16. package/ProgressBar/types.js +1 -0
  17. package/Tabs/index.d.ts +5 -0
  18. package/Tabs/index.js +5 -0
  19. package/Tabs/tab/index.d.ts +2 -0
  20. package/Tabs/tab/index.js +2 -0
  21. package/Tabs/tab/tab.d.ts +8 -0
  22. package/Tabs/tab/tab.js +26 -0
  23. package/Tabs/tab/tab.types.d.ts +9 -0
  24. package/Tabs/tab/tab.types.js +1 -0
  25. package/Tabs/tab-bar/index.d.ts +2 -0
  26. package/Tabs/tab-bar/index.js +2 -0
  27. package/Tabs/tab-bar/tab-bar.d.ts +4 -0
  28. package/Tabs/tab-bar/tab-bar.js +16 -0
  29. package/Tabs/tab-bar/tab-bar.styles.d.ts +4 -0
  30. package/Tabs/tab-bar/tab-bar.styles.js +12 -0
  31. package/Tabs/tab-bar/tab-bar.types.d.ts +4 -0
  32. package/Tabs/tab-bar/tab-bar.types.js +1 -0
  33. package/Tabs/tab-base/index.d.ts +3 -0
  34. package/Tabs/tab-base/index.js +3 -0
  35. package/Tabs/tab-base/tab-base.d.ts +9 -0
  36. package/Tabs/tab-base/tab-base.js +22 -0
  37. package/Tabs/tab-base/tab-base.styles.d.ts +11 -0
  38. package/Tabs/tab-base/tab-base.styles.js +41 -0
  39. package/Tabs/tab-base/tab-base.types.d.ts +9 -0
  40. package/Tabs/tab-base/tab-base.types.js +1 -0
  41. package/Tabs/tab-panel/index.d.ts +2 -0
  42. package/Tabs/tab-panel/index.js +2 -0
  43. package/Tabs/tab-panel/styles.d.ts +1 -0
  44. package/Tabs/tab-panel/styles.js +5 -0
  45. package/Tabs/tab-panel/tab-panel.d.ts +3 -0
  46. package/Tabs/tab-panel/tab-panel.js +16 -0
  47. package/Tabs/tab-panel/tab-panel.types.d.ts +5 -0
  48. package/Tabs/tab-panel/tab-panel.types.js +1 -0
  49. package/Tabs/tabs/index.d.ts +2 -0
  50. package/Tabs/tabs/index.js +2 -0
  51. package/Tabs/tabs/styles.d.ts +1 -0
  52. package/Tabs/tabs/styles.js +6 -0
  53. package/Tabs/tabs/tabs.d.ts +3 -0
  54. package/Tabs/tabs/tabs.js +17 -0
  55. package/Tabs/tabs/tabs.types.d.ts +6 -0
  56. package/Tabs/tabs/tabs.types.js +1 -0
  57. package/Tabs/tabs-list-slide-frame/index.d.ts +3 -0
  58. package/Tabs/tabs-list-slide-frame/index.js +3 -0
  59. package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.d.ts +3 -0
  60. package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.js +68 -0
  61. package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.styles.d.ts +9 -0
  62. package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.styles.js +26 -0
  63. package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.types.d.ts +1 -0
  64. package/Tabs/tabs-list-slide-frame/tabs-list-slide-frame.types.js +1 -0
  65. package/Tabs/tabs.context.d.ts +4 -0
  66. package/Tabs/tabs.context.js +9 -0
  67. package/Tabs/tabs.helpers.d.ts +1 -0
  68. package/Tabs/tabs.helpers.js +18 -0
  69. package/Tabs/tabs.types.d.ts +5 -0
  70. package/Tabs/tabs.types.js +1 -0
  71. package/index.d.ts +3 -0
  72. package/index.js +3 -0
  73. 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,5 @@
1
+ export declare const IframeStyled: import("styled-components").StyledComponent<"div", any, {
2
+ $scale?: number;
3
+ $width?: string;
4
+ $height?: string;
5
+ }, never>;
@@ -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,3 @@
1
+ import React from 'react';
2
+ import { type ProgressBoxProps } from './types';
3
+ export declare const ProgressBar: ({ percentValue, title, rightSlot, color, backgroundColor, }: ProgressBoxProps) => React.JSX.Element;
@@ -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,8 @@
1
+ import { type ReactNode } from 'react';
2
+ export type ProgressBoxProps = {
3
+ percentValue: number;
4
+ title: string;
5
+ rightSlot?: ReactNode;
6
+ color?: string;
7
+ backgroundColor?: string;
8
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export * from './tabs.types';
2
+ export * from './tab';
3
+ export * from './tabs';
4
+ export * from './tab-bar';
5
+ export * from './tab-panel';
package/Tabs/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './tabs.types';
2
+ export * from './tab';
3
+ export * from './tabs';
4
+ export * from './tab-bar';
5
+ export * from './tab-panel';
@@ -0,0 +1,2 @@
1
+ export * from './tab.types';
2
+ export * from './tab';
@@ -0,0 +1,2 @@
1
+ export * from './tab.types';
2
+ export * from './tab';
@@ -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>>;
@@ -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,2 @@
1
+ export * from './tab-bar.types';
2
+ export * from './tab-bar';
@@ -0,0 +1,2 @@
1
+ export * from './tab-bar.types';
2
+ export * from './tab-bar';
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ export declare const TabBar: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & Readonly<{
3
+ title?: React.ReactNode;
4
+ }> & React.RefAttributes<HTMLDivElement>>;
@@ -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,4 @@
1
+ export declare const TabBarContainer: import("styled-components").StyledComponent<"div", any, {
2
+ hasTitle: boolean;
3
+ }, never>;
4
+ export declare const TabBarTitleBox: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -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,4 @@
1
+ import type { ReactNode } from 'react';
2
+ export type TabBarProps = Omit<JSX.IntrinsicElements['div'], 'ref'> & Readonly<{
3
+ title?: ReactNode;
4
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './tab-base.styles';
2
+ export * from './tab-base.types';
3
+ export * from './tab-base';
@@ -0,0 +1,3 @@
1
+ export * from './tab-base.styles';
2
+ export * from './tab-base.types';
3
+ export * from './tab-base';
@@ -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,9 @@
1
+ import type { ReactNode } from 'react';
2
+ export type TabBaseProps = Omit<JSX.IntrinsicElements['div'], 'ref'> & Readonly<{
3
+ isActive?: boolean;
4
+ isDisabled?: boolean;
5
+ isNew?: boolean;
6
+ icon?: ReactNode;
7
+ onClick: () => void;
8
+ className?: string;
9
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './tab-panel.types';
2
+ export * from './tab-panel';
@@ -0,0 +1,2 @@
1
+ export * from './tab-panel.types';
2
+ export * from './tab-panel';
@@ -0,0 +1 @@
1
+ export declare const TabPanelContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,5 @@
1
+ import styled from 'styled-components';
2
+ export const TabPanelContainer = styled.div.withConfig({
3
+ displayName: "TabPanelContainer",
4
+ componentId: "sc-1kewjsc-0"
5
+ })(["overflow:auto;flex:1;"]);
@@ -0,0 +1,3 @@
1
+ import { type FC } from 'react';
2
+ import type { TabPanelProps } from './tab-panel.types';
3
+ export declare const TabPanel: FC<TabPanelProps>;
@@ -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,5 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import type { TabCode } from '../tabs.types';
3
+ export type TabPanelProps = PropsWithChildren<Readonly<{
4
+ code: TabCode;
5
+ }>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from './tabs.types';
2
+ export * from './tabs';
@@ -0,0 +1,2 @@
1
+ export * from './tabs.types';
2
+ export * from './tabs';
@@ -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,3 @@
1
+ import { type ReactElement } from 'react';
2
+ import type { TabsProps } from './tabs.types';
3
+ export declare function Tabs(props: TabsProps): ReactElement;
@@ -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,6 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import { type TabCode } from '../tabs.types';
3
+ export type TabsProps = PropsWithChildren<Readonly<{
4
+ activeCode: TabCode;
5
+ onChange: (code: TabCode) => void;
6
+ }>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './tabs-list-slide-frame.styles';
2
+ export * from './tabs-list-slide-frame.types';
3
+ export * from './tabs-list-slide-frame';
@@ -0,0 +1,3 @@
1
+ export * from './tabs-list-slide-frame.styles';
2
+ export * from './tabs-list-slide-frame.types';
3
+ export * from './tabs-list-slide-frame';
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { type TabsListSlideFrameProps } from './tabs-list-slide-frame.types';
3
+ export declare const TabBarScrollableFrame: React.ForwardRefExoticComponent<TabsListSlideFrameProps & React.RefAttributes<HTMLDivElement>>;
@@ -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,4 @@
1
+ import React from 'react';
2
+ import type { TabContextType } from './tabs.types';
3
+ export declare const TabContext: React.Context<TabContextType>;
4
+ export declare function useTabsContext(): TabContextType;
@@ -0,0 +1,9 @@
1
+ import React, { useContext } from 'react';
2
+ export const TabContext = React.createContext(null);
3
+ export function useTabsContext() {
4
+ const context = useContext(TabContext);
5
+ if (!context) {
6
+ throw new Error('no tabs context');
7
+ }
8
+ return context;
9
+ }
@@ -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,5 @@
1
+ export type TabCode = string | number;
2
+ export type TabContextType = {
3
+ activeTabCode: TabCode;
4
+ setActiveTabCode: (code: TabCode) => void;
5
+ };
@@ -0,0 +1 @@
1
+ export {};
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { ProgressBar } from './ProgressBar';
2
+ export * from './Tabs';
3
+ export { EmailTemplatePreview } from './EmailTemplatePreview/EmailTemplatePreview';
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { ProgressBar } from './ProgressBar';
2
+ export * from './Tabs';
3
+ export { EmailTemplatePreview } from './EmailTemplatePreview/EmailTemplatePreview';
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
+ }