@pushwoosh/dumb-components 2.4.0 → 2.5.1

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/Banner/Banner.js CHANGED
@@ -80,7 +80,6 @@ export function Banner(props) {
80
80
  view: "filled"
81
81
  })
82
82
  }), _jsxs(BannerContent, {
83
- "$hasTitleAndChildren": hasTitle && hasChildren,
84
83
  children: [hasTitle && _jsx(H4, {
85
84
  children: title
86
85
  }), hasChildren && _jsx("div", {
@@ -11,9 +11,7 @@ export declare const BannerBox: import("styled-components").StyledComponent<"div
11
11
  $isOpen?: boolean;
12
12
  $isLoading: boolean;
13
13
  }, never>;
14
- export declare const BannerContent: import("styled-components").StyledComponent<"div", any, {
15
- $hasTitleAndChildren?: boolean;
16
- }, never>;
14
+ export declare const BannerContent: import("styled-components").StyledComponent<"div", any, {}, never>;
17
15
  export declare const IconContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
18
16
  export declare const BannerShape: import("styled-components").StyledComponent<"div", any, import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
19
17
  $isOpen?: boolean;
package/Banner/styles.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import styled from 'styled-components';
2
- import { ShapeRadius, FontWeight } from '@pushwoosh/kit-constants';
2
+ import { FontSize, FontWeight, LineHeight, ShapeRadius } from '@pushwoosh/kit-constants';
3
3
  import { colors } from './colors';
4
4
  export const BannerSpinner = styled.div.withConfig({
5
5
  displayName: "BannerSpinner",
@@ -8,7 +8,7 @@ export const BannerSpinner = styled.div.withConfig({
8
8
  export const ActionButton = styled.button.withConfig({
9
9
  displayName: "ActionButton",
10
10
  componentId: "sc-9uu4ap-1"
11
- })(["appearance:none !important;border:none;background:initial;cursor:pointer;padding:6px;position:relative;font-weight:", ";white-space:nowrap;height:fit-content;> span{visibility:", ";}opacity:", ";"], FontWeight.BOLD, ({
11
+ })(["appearance:none !important;border:none;background:initial;cursor:pointer;padding:6px;position:relative;font-size:", ";line-height:", ";font-weight:", ";text-transform:uppercase;white-space:nowrap;height:fit-content;> span{visibility:", ";}opacity:", ";"], FontSize.SMALL, LineHeight.SMALL, FontWeight.BOLD, ({
12
12
  $isLoading
13
13
  }) => $isLoading ? 'hidden' : 'visible', ({
14
14
  $isPressed,
@@ -27,9 +27,7 @@ export const BannerBox = styled.div.withConfig({
27
27
  export const BannerContent = styled.div.withConfig({
28
28
  displayName: "BannerContent",
29
29
  componentId: "sc-9uu4ap-4"
30
- })(["flex-grow:1;padding:", ";color:", ";"], ({
31
- $hasTitleAndChildren
32
- }) => $hasTitleAndChildren ? '16px' : '8px 16px', colors.error.shape.base.color);
30
+ })(["flex-grow:1;padding:12px 16px;color:", ";"], colors.error.shape.base.color);
33
31
  export const IconContainer = styled.div.withConfig({
34
32
  displayName: "IconContainer",
35
33
  componentId: "sc-9uu4ap-5"
@@ -1,6 +1,8 @@
1
1
  /**
2
- * Horizontal, scrollable row of {@link Tab}s with an optional title.
2
+ * Horizontal row of {@link Tab}s with an optional title. Scrolls when the tabs
3
+ * overflow, or stretches them to equal widths with `layout="stretch"`.
3
4
  */
4
5
  export declare const TabBar: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & Readonly<{
5
6
  title?: import("react").ReactNode;
7
+ layout?: import("./types").TabBarLayout;
6
8
  }> & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,15 +1,17 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { forwardRef } from 'react';
3
3
  import { H4 } from '@pushwoosh/kit-typography';
4
- import { TabBarTitleBox, TabBarContainer } from './styles';
4
+ import { TabBarTitleBox, TabBarContainer, TabBarStretchedContent } from './styles';
5
5
  import { TabBarScrollableFrame } from '../TabBarScrollableFrame';
6
6
  /**
7
- * Horizontal, scrollable row of {@link Tab}s with an optional title.
7
+ * Horizontal row of {@link Tab}s with an optional title. Scrolls when the tabs
8
+ * overflow, or stretches them to equal widths with `layout="stretch"`.
8
9
  */
9
10
  export const TabBar = forwardRef((props, ref) => {
10
11
  const {
11
12
  children,
12
13
  title,
14
+ layout = 'scroll',
13
15
  ...rest
14
16
  } = props;
15
17
  return _jsxs(TabBarContainer, {
@@ -20,7 +22,9 @@ export const TabBar = forwardRef((props, ref) => {
20
22
  children: _jsx(H4, {
21
23
  children: title
22
24
  })
23
- }), _jsx(TabBarScrollableFrame, {
25
+ }), layout === 'stretch' ? _jsx(TabBarStretchedContent, {
26
+ children: children
27
+ }) : _jsx(TabBarScrollableFrame, {
24
28
  children: children
25
29
  })]
26
30
  });
@@ -2,3 +2,4 @@ export declare const TabBarContainer: import("styled-components").StyledComponen
2
2
  hasTitle: boolean;
3
3
  }, never>;
4
4
  export declare const TabBarTitleBox: import("styled-components").StyledComponent<"div", any, {}, never>;
5
+ export declare const TabBarStretchedContent: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -9,4 +9,8 @@ export const TabBarContainer = styled.div.withConfig({
9
9
  export const TabBarTitleBox = styled.div.withConfig({
10
10
  displayName: "TabBarTitleBox",
11
11
  componentId: "sc-pu8yhh-1"
12
- })(["display:flex;align-items:center;position:relative;padding:0 12px 0 16px;"]);
12
+ })(["display:flex;align-items:center;position:relative;padding:0 12px 0 16px;"]);
13
+ export const TabBarStretchedContent = styled.div.withConfig({
14
+ displayName: "TabBarStretchedContent",
15
+ componentId: "sc-pu8yhh-2"
16
+ })(["display:flex;align-items:center;gap:4px;width:100%;height:32px;& > *{flex:1 1 0;min-width:0;}"]);
@@ -1,6 +1,18 @@
1
1
  import type { ReactNode } from 'react';
2
+ /** How a {@link TabBar} lays out its tabs. */
3
+ export type TabBarLayout =
4
+ /** Tabs take their content width; overflowing tabs scroll behind arrows. */
5
+ 'scroll'
6
+ /**
7
+ * Tabs share the bar width equally. Meant for narrow panels (drawers, sidebars,
8
+ * cards around 350px wide), not for page-level tabs. Nothing scrolls in this
9
+ * layout, so keep it to 3, at most 4, tabs with short labels.
10
+ */
11
+ | 'stretch';
2
12
  /** Props of {@link TabBar} — all `<div>` attributes plus an optional title. */
3
13
  export type TabBarProps = Omit<JSX.IntrinsicElements['div'], 'ref'> & Readonly<{
4
14
  /** Optional heading shown before the tabs. */
5
15
  title?: ReactNode;
16
+ /** Tab layout, `'scroll'` by default; see {@link TabBarLayout} for when to stretch. */
17
+ layout?: TabBarLayout;
6
18
  }>;
@@ -15,6 +15,8 @@ export const TabBarScrollableFrame = forwardRef(({
15
15
  const [scrollLeft, setScrollLeft] = useState(0);
16
16
  const scrollable = contentWidth > frameWidth;
17
17
  const minLeft = frameWidth - contentWidth;
18
+ const canScrollLeft = scrollable && scrollLeft < 0;
19
+ const canScrollRight = scrollable && scrollLeft > minLeft;
18
20
  const onClick = useCallback(event => {
19
21
  const {
20
22
  currentTarget
@@ -49,20 +51,22 @@ export const TabBarScrollableFrame = forwardRef(({
49
51
  ...props,
50
52
  ref: ref,
51
53
  children: [_jsx(TabBarWindow, {
54
+ "$clipLeft": canScrollLeft,
55
+ "$clipRight": canScrollRight,
52
56
  ref: windowRef,
53
57
  children: _jsx(TabBarContent, {
54
58
  left: scrollLeft,
55
59
  ref: contentRef,
56
60
  children: children
57
61
  })
58
- }), scrollable && scrollLeft < 0 && _jsx(TabBarArrowContainer, {
62
+ }), canScrollLeft && _jsx(TabBarArrowContainer, {
59
63
  "data-left": true,
60
64
  onClick: onClick,
61
65
  children: _jsx(ChevronIcon, {
62
66
  direction: "left",
63
67
  size: "small"
64
68
  })
65
- }), scrollable && scrollLeft > minLeft && _jsx(TabBarArrowContainer, {
69
+ }), canScrollRight && _jsx(TabBarArrowContainer, {
66
70
  "$right": true,
67
71
  onClick: onClick,
68
72
  children: _jsx(ChevronIcon, {
@@ -1,7 +1,10 @@
1
1
  export declare const TabBarArrowContainer: import("styled-components").StyledComponent<"div", any, {
2
2
  $right?: boolean;
3
3
  }, never>;
4
- export declare const TabBarWindow: import("styled-components").StyledComponent<"div", any, {}, never>;
4
+ export declare const TabBarWindow: import("styled-components").StyledComponent<"div", any, {
5
+ $clipLeft: boolean;
6
+ $clipRight: boolean;
7
+ }, never>;
5
8
  export declare const TabsListContentBase: import("styled-components").StyledComponent<"div", any, {}, never>;
6
9
  export declare const TabBarContent: import("styled-components").StyledComponent<"div", any, {
7
10
  left: number;
@@ -6,10 +6,15 @@ export const TabBarArrowContainer = styled.div.withConfig({
6
6
  })(["position:absolute;top:0;", ":0;display:flex;align-items:center;height:32px;cursor:pointer;color:", ";background-color:", ";box-shadow:", ";border-radius:", ";padding:8px 4px;&:hover{color:", ";}"], ({
7
7
  $right
8
8
  }) => $right ? 'right' : 'left', Color.MAIN, Color.CLEAR, Shadow.SMALL, ShapeRadius.CONTROL, Color.PRIMARY_HOVER);
9
+ const SHADOW_BLEED = '-4px';
9
10
  export const TabBarWindow = styled.div.withConfig({
10
11
  displayName: "TabBarWindow",
11
12
  componentId: "sc-1sonok9-1"
12
- })(["position:relative;width:100%;height:32px;overflow:hidden;"]);
13
+ })(["position:relative;width:100%;height:32px;clip-path:inset( ", " ", " ", " ", " );"], SHADOW_BLEED, ({
14
+ $clipRight
15
+ }) => $clipRight ? 0 : SHADOW_BLEED, SHADOW_BLEED, ({
16
+ $clipLeft
17
+ }) => $clipLeft ? 0 : SHADOW_BLEED);
13
18
  export const TabsListContentBase = styled.div.withConfig({
14
19
  displayName: "TabsListContentBase",
15
20
  componentId: "sc-1sonok9-2"
package/Tabs/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { Tab } from './components/Tab';
2
2
  export { TabBar } from './components/TabBar';
3
+ export type { TabBarLayout } from './components/TabBar/types';
3
4
  export { TabPanel } from './components/TabPanel';
4
5
  export { Tabs } from './components/Tabs';
5
6
  export type { TabCode } from './types';
package/index.d.ts CHANGED
@@ -29,7 +29,7 @@ export { ComboboxMulti, type ComboboxMultiProps } from './ComboboxMulti';
29
29
  export { Switch } from './Switch';
30
30
  export { TextSkeleton, RectangularSkeleton, CircularSkeleton } from './Skeleton';
31
31
  export { Tooltip, type TooltipPosition, type TooltipColor, TooltipTrigger } from './Tooltip';
32
- export { Tab, TabBar, TabPanel, Tabs, type TabCode } from './Tabs';
32
+ export { Tab, TabBar, TabPanel, Tabs, type TabCode, type TabBarLayout } from './Tabs';
33
33
  export { Link, type LinkPropsWithoutAs, type LinkPropsWithAsTag, type LinkPropsWithAsComponent, } from './Link';
34
34
  export { StatisticCard } from './StatisticCard';
35
35
  export { EmailTemplatePreview, NoEmailTemplatePreview, replaceLocalization, replacePlaceholders, matchClickMapItems, decorateClickMap, CLICK_MAP_BADGE_ATTRIBUTE, type EmailClickMapItem, type EmailClickMapPlacement, type EmailClickMapProps, type PreviewIframeProps, } from './EmailTemplatePreview';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",