@pushwoosh/dumb-components 1.1.124 → 1.1.126

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.
@@ -3,6 +3,7 @@ import React, { useState, useEffect } from 'react';
3
3
  import { flushSync } from 'react-dom';
4
4
  import { Place } from './styles';
5
5
  import { DropdownContext } from '../../context';
6
+ import { renderChildren } from '../../shared/renderChildren';
6
7
  const defaultPlacements = ['top-start', 'top-end', 'bottom-start', 'bottom-end'];
7
8
  export const DropdownMenu = ({
8
9
  renderHandler,
@@ -81,5 +82,5 @@ export const DropdownMenu = ({
81
82
  "$fitContent": windowWidth === null && !fullWidth,
82
83
  "$scrollable": isScrollable,
83
84
  "$zIndex": menuZIndex
84
- }, typeof children === 'function' ? children() : children));
85
+ }, renderChildren(children)));
85
86
  };
@@ -1,62 +1 @@
1
- export declare const Place: import("styled-components").StyledComponent<"div", any, {
2
- $alignContent?: "end" | "start" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | undefined;
3
- $alignItems?: "end" | "start" | "center" | "stretch" | "baseline" | undefined;
4
- $bgColor?: string | undefined;
5
- $border?: string | ({
6
- top?: string | undefined;
7
- right?: string | undefined;
8
- bottom?: string | undefined;
9
- left?: string | undefined;
10
- } | {
11
- horizontal: string;
12
- top?: string | undefined;
13
- bottom?: string | undefined;
14
- } | {
15
- vertical: string;
16
- right?: string | undefined;
17
- left?: string | undefined;
18
- }) | undefined;
19
- $borderRadius?: (string | number) | undefined;
20
- $boxShadow?: string | undefined;
21
- $gap?: (string | number) | undefined;
22
- $gridAutoFlow?: "row" | "column" | "dense" | "row dense" | "column dense" | undefined;
23
- $justifyContent?: "end" | "start" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | undefined;
24
- $justifyItems?: "end" | "start" | "center" | "stretch" | "baseline" | undefined;
25
- $margin?: (string | number) | ({
26
- top?: (string | number) | undefined;
27
- right?: (string | number) | undefined;
28
- bottom?: (string | number) | undefined;
29
- left?: (string | number) | undefined;
30
- } | {
31
- horizontal: string | number;
32
- top?: (string | number) | undefined;
33
- bottom?: (string | number) | undefined;
34
- } | {
35
- vertical: string | number;
36
- right?: (string | number) | undefined;
37
- left?: (string | number) | undefined;
38
- }) | undefined;
39
- $padding?: (string | number) | ({
40
- top?: (string | number) | undefined;
41
- right?: (string | number) | undefined;
42
- bottom?: (string | number) | undefined;
43
- left?: (string | number) | undefined;
44
- } | {
45
- horizontal: string | number;
46
- top?: (string | number) | undefined;
47
- bottom?: (string | number) | undefined;
48
- } | {
49
- vertical: string | number;
50
- right?: (string | number) | undefined;
51
- left?: (string | number) | undefined;
52
- }) | undefined;
53
- $placeItems?: "end" | "start" | "center" | "stretch" | undefined;
54
- } & {
55
- $gridAutoFlow: string;
56
- } & {
57
- $color?: string;
58
- $width: number | null;
59
- $fitContent?: boolean;
60
- $zIndex?: number;
61
- $scrollable?: boolean;
62
- }, "$gridAutoFlow">;
1
+ export { Place } from '../../shared/styles';
@@ -1,22 +1 @@
1
- import styled, { css } from 'styled-components';
2
- import { Color, Shadow, ShapeRadius } from '@pushwoosh/kit-constants';
3
- import { Vertical } from '@pushwoosh/kit-helpers';
4
- const scrollableCss = css(["max-height:248px;overflow-y:auto;"]);
5
- const getWidth = ($width, $fitContent) => {
6
- if ($fitContent) return 'max-content';
7
- if ($width) return `${$width}px`;
8
- return 'auto';
9
- };
10
- export const Place = styled(Vertical).withConfig({
11
- displayName: "Place",
12
- componentId: "sc-ij8wqc-0"
13
- })(["border:1px solid ", ";background:", ";width:", ";min-width:140px;max-width:480px;", " border-radius:", ";box-shadow:", ";z-index:", ";"], Color.FORM, ({
14
- $color
15
- }) => $color || Color.FROZEN, ({
16
- $width,
17
- $fitContent
18
- }) => getWidth($width, $fitContent), ({
19
- $scrollable
20
- }) => $scrollable && scrollableCss, ShapeRadius.CONTROL, Shadow.REGULAR, ({
21
- $zIndex
22
- }) => $zIndex || 10);
1
+ export { Place } from '../../shared/styles';
@@ -1,4 +1 @@
1
- export declare const DropdownMenuItemStyled: import("styled-components").StyledComponent<"button", any, {
2
- $active?: boolean;
3
- $danger?: boolean;
4
- }, never>;
1
+ export { DropdownMenuItemStyled } from '../../shared/styles';
@@ -1,12 +1 @@
1
- import styled from 'styled-components';
2
- import { Color, UnitSize } from '@pushwoosh/kit-constants';
3
- export const DropdownMenuItemStyled = styled.button.withConfig({
4
- displayName: "DropdownMenuItemStyled",
5
- componentId: "sc-1wmyvxp-0"
6
- })(["appearance:none;display:flex;align-items:center;white-space:nowrap;padding:0 12px;min-height:", ";border:none;overflow:hidden;color:", ";background:none;cursor:pointer;&:hover{background:", ";color:", ";}&:disabled{color:", ";cursor:not-allowed;}"], UnitSize.FIELD_HEIGHT, ({
7
- $active,
8
- $danger
9
- }) => {
10
- if ($danger) return Color.DANGER;
11
- return $active ? Color.PRIMARY : Color.MAIN;
12
- }, Color.SOFT_LIGHT, Color.MAIN, Color.LOCKED);
1
+ export { DropdownMenuItemStyled } from '../../shared/styles';
@@ -0,0 +1,3 @@
1
+ import { type FC } from 'react';
2
+ import { type DropdownMenuSubmenuProps } from './types';
3
+ export declare const DropdownMenuSubmenu: FC<DropdownMenuSubmenuProps>;
@@ -0,0 +1,85 @@
1
+ import { flip, shift, useFloating } from '@floating-ui/react-dom';
2
+ import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
3
+ import { ChevronIcon } from '@pushwoosh/kit-icons';
4
+ import { SubmenuTriggerInner } from './styles';
5
+ import { DropdownContext } from '../../context';
6
+ import { renderChildren } from '../../shared/renderChildren';
7
+ import { DropdownMenuItemStyled, Place } from '../../shared/styles';
8
+ const OPEN_DELAY = 100;
9
+ const CLOSE_DELAY = 200;
10
+ export const DropdownMenuSubmenu = ({
11
+ label,
12
+ isDanger,
13
+ disabled,
14
+ children
15
+ }) => {
16
+ const parentClose = useContext(DropdownContext);
17
+ const [isOpen, setIsOpen] = useState(false);
18
+ const openedByClick = useRef(false);
19
+ const {
20
+ refs,
21
+ floatingStyles
22
+ } = useFloating({
23
+ strategy: 'fixed',
24
+ placement: 'right-start',
25
+ middleware: [flip({
26
+ fallbackPlacements: ['left-start'],
27
+ boundary: document.body
28
+ }), shift({
29
+ padding: 4,
30
+ boundary: document.body
31
+ })]
32
+ });
33
+ const openTimer = useRef(null);
34
+ const closeTimer = useRef(null);
35
+ const clearTimers = useCallback(() => {
36
+ if (openTimer.current) clearTimeout(openTimer.current);
37
+ if (closeTimer.current) clearTimeout(closeTimer.current);
38
+ openTimer.current = null;
39
+ closeTimer.current = null;
40
+ }, []);
41
+ useEffect(() => () => clearTimers(), [clearTimers]);
42
+ const scheduleOpen = useCallback(() => {
43
+ if (disabled) return;
44
+ openedByClick.current = false;
45
+ clearTimers();
46
+ openTimer.current = setTimeout(() => setIsOpen(true), OPEN_DELAY);
47
+ }, [disabled, clearTimers]);
48
+ const scheduleClose = useCallback(() => {
49
+ if (openedByClick.current) return;
50
+ clearTimers();
51
+ closeTimer.current = setTimeout(() => setIsOpen(false), CLOSE_DELAY);
52
+ }, [clearTimers]);
53
+ const closeChain = useCallback(() => {
54
+ openedByClick.current = false;
55
+ setIsOpen(false);
56
+ parentClose === null || parentClose === void 0 || parentClose(false);
57
+ }, [parentClose]);
58
+ return React.createElement(DropdownContext.Provider, {
59
+ value: closeChain
60
+ }, React.createElement(DropdownMenuItemStyled, {
61
+ ref: refs.setReference,
62
+ type: "button",
63
+ "$active": isOpen,
64
+ "$danger": isDanger,
65
+ disabled: disabled,
66
+ onMouseEnter: scheduleOpen,
67
+ onMouseLeave: scheduleClose,
68
+ onClick: () => {
69
+ if (disabled) return;
70
+ clearTimers();
71
+ openedByClick.current = !isOpen;
72
+ setIsOpen(prev => !prev);
73
+ }
74
+ }, React.createElement(SubmenuTriggerInner, null, React.createElement("span", null, label), React.createElement(ChevronIcon, {
75
+ direction: "right",
76
+ size: "small"
77
+ }))), isOpen && React.createElement(Place, {
78
+ ref: refs.setFloating,
79
+ style: floatingStyles,
80
+ "$width": null,
81
+ "$fitContent": true,
82
+ onMouseEnter: clearTimers,
83
+ onMouseLeave: scheduleClose
84
+ }, renderChildren(children)));
85
+ };
@@ -0,0 +1 @@
1
+ export { DropdownMenuSubmenu } from './DropdownMenuSubmenu';
@@ -0,0 +1 @@
1
+ export { DropdownMenuSubmenu } from './DropdownMenuSubmenu';
@@ -0,0 +1 @@
1
+ export declare const SubmenuTriggerInner: import("styled-components").StyledComponent<"span", any, {}, never>;
@@ -0,0 +1,5 @@
1
+ import styled from 'styled-components';
2
+ export const SubmenuTriggerInner = styled.span.withConfig({
3
+ displayName: "SubmenuTriggerInner",
4
+ componentId: "sc-yns7at-0"
5
+ })(["display:flex;align-items:center;justify-content:space-between;gap:8px;flex:1;"]);
@@ -0,0 +1,7 @@
1
+ import { type ReactNode } from 'react';
2
+ export type DropdownMenuSubmenuProps = {
3
+ label: ReactNode;
4
+ isDanger?: boolean;
5
+ disabled?: boolean;
6
+ children: (() => ReactNode) | ReactNode;
7
+ };
@@ -2,3 +2,4 @@ export { DropdownMenu } from './components/DropdownMenu';
2
2
  export { DropdownMenuButton } from './components/DropdownMenuButton';
3
3
  export { DropdownMenuItem } from './components/DropdownMenuItem';
4
4
  export { DropdownMenuSection } from './components/DropdownMenuSection';
5
+ export { DropdownMenuSubmenu } from './components/DropdownMenuSubmenu';
@@ -1,4 +1,5 @@
1
1
  export { DropdownMenu } from './components/DropdownMenu';
2
2
  export { DropdownMenuButton } from './components/DropdownMenuButton';
3
3
  export { DropdownMenuItem } from './components/DropdownMenuItem';
4
- export { DropdownMenuSection } from './components/DropdownMenuSection';
4
+ export { DropdownMenuSection } from './components/DropdownMenuSection';
5
+ export { DropdownMenuSubmenu } from './components/DropdownMenuSubmenu';
@@ -0,0 +1,2 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare const renderChildren: (children: ReactNode | (() => ReactNode)) => ReactNode;
@@ -0,0 +1 @@
1
+ export const renderChildren = children => typeof children === 'function' ? children() : children;
@@ -0,0 +1,66 @@
1
+ export declare const Place: import("styled-components").StyledComponent<"div", any, {
2
+ $alignContent?: "end" | "start" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | undefined;
3
+ $alignItems?: "end" | "start" | "center" | "stretch" | "baseline" | undefined;
4
+ $bgColor?: string | undefined;
5
+ $border?: string | ({
6
+ top?: string | undefined;
7
+ right?: string | undefined;
8
+ bottom?: string | undefined;
9
+ left?: string | undefined;
10
+ } | {
11
+ horizontal: string;
12
+ top?: string | undefined;
13
+ bottom?: string | undefined;
14
+ } | {
15
+ vertical: string;
16
+ right?: string | undefined;
17
+ left?: string | undefined;
18
+ }) | undefined;
19
+ $borderRadius?: (string | number) | undefined;
20
+ $boxShadow?: string | undefined;
21
+ $gap?: (string | number) | undefined;
22
+ $gridAutoFlow?: "row" | "column" | "dense" | "row dense" | "column dense" | undefined;
23
+ $justifyContent?: "end" | "start" | "center" | "space-between" | "space-around" | "space-evenly" | "stretch" | undefined;
24
+ $justifyItems?: "end" | "start" | "center" | "stretch" | "baseline" | undefined;
25
+ $margin?: (string | number) | ({
26
+ top?: (string | number) | undefined;
27
+ right?: (string | number) | undefined;
28
+ bottom?: (string | number) | undefined;
29
+ left?: (string | number) | undefined;
30
+ } | {
31
+ horizontal: string | number;
32
+ top?: (string | number) | undefined;
33
+ bottom?: (string | number) | undefined;
34
+ } | {
35
+ vertical: string | number;
36
+ right?: (string | number) | undefined;
37
+ left?: (string | number) | undefined;
38
+ }) | undefined;
39
+ $padding?: (string | number) | ({
40
+ top?: (string | number) | undefined;
41
+ right?: (string | number) | undefined;
42
+ bottom?: (string | number) | undefined;
43
+ left?: (string | number) | undefined;
44
+ } | {
45
+ horizontal: string | number;
46
+ top?: (string | number) | undefined;
47
+ bottom?: (string | number) | undefined;
48
+ } | {
49
+ vertical: string | number;
50
+ right?: (string | number) | undefined;
51
+ left?: (string | number) | undefined;
52
+ }) | undefined;
53
+ $placeItems?: "end" | "start" | "center" | "stretch" | undefined;
54
+ } & {
55
+ $gridAutoFlow: string;
56
+ } & {
57
+ $color?: string;
58
+ $width: number | null;
59
+ $fitContent?: boolean;
60
+ $zIndex?: number;
61
+ $scrollable?: boolean;
62
+ }, "$gridAutoFlow">;
63
+ export declare const DropdownMenuItemStyled: import("styled-components").StyledComponent<"button", any, {
64
+ $active?: boolean;
65
+ $danger?: boolean;
66
+ }, never>;
@@ -0,0 +1,32 @@
1
+ import styled, { css } from 'styled-components';
2
+ import { Color, Shadow, ShapeRadius, UnitSize } from '@pushwoosh/kit-constants';
3
+ import { Vertical } from '@pushwoosh/kit-helpers';
4
+ const scrollableCss = css(["max-height:248px;overflow-y:auto;"]);
5
+ const getWidth = ($width, $fitContent) => {
6
+ if ($fitContent) return 'max-content';
7
+ if ($width) return `${$width}px`;
8
+ return 'auto';
9
+ };
10
+ export const Place = styled(Vertical).withConfig({
11
+ displayName: "Place",
12
+ componentId: "sc-hlq2pz-0"
13
+ })(["border:1px solid ", ";background:", ";width:", ";min-width:140px;max-width:480px;", " border-radius:", ";box-shadow:", ";z-index:", ";"], Color.FORM, ({
14
+ $color
15
+ }) => $color || Color.FROZEN, ({
16
+ $width,
17
+ $fitContent
18
+ }) => getWidth($width, $fitContent), ({
19
+ $scrollable
20
+ }) => $scrollable && scrollableCss, ShapeRadius.CONTROL, Shadow.REGULAR, ({
21
+ $zIndex
22
+ }) => $zIndex || 10);
23
+ export const DropdownMenuItemStyled = styled.button.withConfig({
24
+ displayName: "DropdownMenuItemStyled",
25
+ componentId: "sc-hlq2pz-1"
26
+ })(["appearance:none;display:flex;align-items:center;white-space:nowrap;padding:0 12px;min-height:", ";border:none;overflow:hidden;color:", ";background:none;cursor:pointer;&:hover{background:", ";color:", ";}&:disabled{color:", ";cursor:not-allowed;}"], UnitSize.FIELD_HEIGHT, ({
27
+ $active,
28
+ $danger
29
+ }) => {
30
+ if ($danger) return Color.DANGER;
31
+ return $active ? Color.PRIMARY : Color.MAIN;
32
+ }, Color.SOFT_LIGHT, Color.MAIN, Color.LOCKED);
package/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { CrashScreen } from './CrashScreen';
8
8
  export { Drawer, DrawerHeader, DrawerTitle, DrawerBody, DrawerDocs, useDocs, } from './Drawer';
9
9
  export { CalendarSuperForm, CalendarDropdown, addPeriod, compareStructs, dateToStruct, dateToStructTz, getTimezoneOffset, getPeriodEnd, getPeriodStart, structToDate, structToDateTz, stringifyValue, pickDateStruct, type CalendarDropdownProps, type CalendarDropdownRangeDateProps, type CalendarSuperFormProps, type DateStruct, type RangeValue, } from './Calendar';
10
10
  export { DatePicker, DatePickerField, DateTimePicker, DateTimePickerField, } from './DateTimePicker';
11
- export { DropdownMenu, DropdownMenuButton, DropdownMenuSection, DropdownMenuItem, } from './DropdownMenu';
11
+ export { DropdownMenu, DropdownMenuButton, DropdownMenuSection, DropdownMenuItem, DropdownMenuSubmenu, } from './DropdownMenu';
12
12
  export { GetStartedPage } from './GetStartedPage';
13
13
  export { EditableField } from './EditableField';
14
14
  export { InputFile } from './InputFile';
package/index.js CHANGED
@@ -8,7 +8,7 @@ export { CrashScreen } from './CrashScreen';
8
8
  export { Drawer, DrawerHeader, DrawerTitle, DrawerBody, DrawerDocs, useDocs } from './Drawer';
9
9
  export { CalendarSuperForm, CalendarDropdown, addPeriod, compareStructs, dateToStruct, dateToStructTz, getTimezoneOffset, getPeriodEnd, getPeriodStart, structToDate, structToDateTz, stringifyValue, pickDateStruct } from './Calendar';
10
10
  export { DatePicker, DatePickerField, DateTimePicker, DateTimePickerField } from './DateTimePicker';
11
- export { DropdownMenu, DropdownMenuButton, DropdownMenuSection, DropdownMenuItem } from './DropdownMenu';
11
+ export { DropdownMenu, DropdownMenuButton, DropdownMenuSection, DropdownMenuItem, DropdownMenuSubmenu } from './DropdownMenu';
12
12
  export { GetStartedPage } from './GetStartedPage';
13
13
  export { EditableField } from './EditableField';
14
14
  export { InputFile } from './InputFile';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushwoosh/dumb-components",
3
- "version": "1.1.124",
3
+ "version": "1.1.126",
4
4
  "description": "React components to build Pushwoosh products",
5
5
  "main": "index.js",
6
6
  "module": "index.js",