@pushwoosh/dumb-components 1.1.122 → 1.1.123
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/Button/ai-documentation.md +17 -12
- package/Chip/Chip.constants.d.ts +2 -0
- package/Chip/Chip.constants.js +9 -3
- package/Chip/Chip.d.ts +2 -0
- package/Chip/Chip.js +21 -9
- package/Chip/Chip.types.d.ts +3 -1
- package/Chip/ai-documentation.md +40 -0
- package/Chip/index.d.ts +1 -0
- package/Chip/styles.d.ts +7 -1
- package/Chip/styles.js +35 -11
- package/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -77,9 +77,12 @@ function App() {
|
|
|
77
77
|
</Button>
|
|
78
78
|
|
|
79
79
|
// Secondary button with icon
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
// Note: kit-icons require `size` and `view`. Match icon size to Button size:
|
|
81
|
+
// Button size="field" (default) → icon size="medium"
|
|
82
|
+
// Button size="compact" → icon size="small"
|
|
83
|
+
<Button
|
|
84
|
+
color="secondary"
|
|
85
|
+
icon={<PlusIcon size="medium" view="lined" />}
|
|
83
86
|
onClick={() => handleAdd()}
|
|
84
87
|
>
|
|
85
88
|
Add Item
|
|
@@ -94,28 +97,28 @@ function App() {
|
|
|
94
97
|
{isDeleting ? 'Deleting...' : 'Delete'}
|
|
95
98
|
</Button>
|
|
96
99
|
|
|
97
|
-
// Compact button with right icon
|
|
98
|
-
<Button
|
|
100
|
+
// Compact button with right icon (size="small" matches size="compact")
|
|
101
|
+
<Button
|
|
99
102
|
color="primary"
|
|
100
103
|
size="compact"
|
|
101
|
-
rightIcon={<ArrowIcon />}
|
|
104
|
+
rightIcon={<ArrowIcon size="small" view="lined" />}
|
|
102
105
|
>
|
|
103
106
|
Next
|
|
104
107
|
</Button>
|
|
105
108
|
|
|
106
109
|
// Ghost view button
|
|
107
|
-
<Button
|
|
110
|
+
<Button
|
|
108
111
|
color="primary"
|
|
109
112
|
view="ghost"
|
|
110
|
-
icon={<EditIcon />}
|
|
113
|
+
icon={<EditIcon size="medium" view="lined" />}
|
|
111
114
|
>
|
|
112
115
|
Edit
|
|
113
116
|
</Button>
|
|
114
117
|
|
|
115
118
|
// Icon-only button
|
|
116
|
-
<Button
|
|
119
|
+
<Button
|
|
117
120
|
color="secondary"
|
|
118
|
-
icon={<SearchIcon />}
|
|
121
|
+
icon={<SearchIcon size="medium" view="lined" />}
|
|
119
122
|
onClick={() => handleSearch()}
|
|
120
123
|
/>
|
|
121
124
|
|
|
@@ -188,8 +191,8 @@ A compact icon-only button with a built-in `CloseIcon` intended for "remove" / "
|
|
|
188
191
|
| isDisabled | boolean | false | Whether button is disabled |
|
|
189
192
|
| isLoading | boolean | false | Whether button shows loading state |
|
|
190
193
|
| isOpen | boolean | false | Whether button appears in "open" state |
|
|
191
|
-
| icon | ReactNode | undefined | Left icon element |
|
|
192
|
-
| rightIcon | ReactNode | undefined | Right icon element |
|
|
194
|
+
| icon | ReactNode | undefined | Left icon element. For `@pushwoosh/kit-icons` icons, pass `size` and `view` explicitly (both required). Match icon `size` to Button `size`: `size="medium"` for `field` (default), `size="small"` for `compact`. |
|
|
195
|
+
| rightIcon | ReactNode | undefined | Right icon element. Same icon size/view rules as `icon`. |
|
|
193
196
|
| children | ReactNode | undefined | Button text content |
|
|
194
197
|
| boxRef | Ref | undefined | Ref to button element |
|
|
195
198
|
| as | string \| Component | undefined | Render as different element/component |
|
|
@@ -218,6 +221,8 @@ A compact icon-only button with a built-in `CloseIcon` intended for "remove" / "
|
|
|
218
221
|
- Don't use loading state without showing loading text to user
|
|
219
222
|
- Avoid putting buttons inside other interactive elements
|
|
220
223
|
- Don't use `isDisabled` with `isLoading` simultaneously
|
|
224
|
+
- Don't pass icons without `size` and `view` — they are required on `@pushwoosh/kit-icons` and TypeScript won't catch it (Button's `icon` is typed as `ReactNode`)
|
|
225
|
+
- Don't mismatch icon size to button size: `size="small"` icons belong only in `size="compact"` buttons; `field`-sized buttons need `size="medium"` icons
|
|
221
226
|
- Avoid very long button text - keep concise
|
|
222
227
|
|
|
223
228
|
### Integration Tips
|
package/Chip/Chip.constants.d.ts
CHANGED
package/Chip/Chip.constants.js
CHANGED
|
@@ -2,14 +2,20 @@ import { Color } from '@pushwoosh/kit-constants';
|
|
|
2
2
|
export const variants = {
|
|
3
3
|
primary: {
|
|
4
4
|
color: Color.PRIMARY,
|
|
5
|
-
background: Color.BRIGHT_LIGHT
|
|
5
|
+
background: Color.BRIGHT_LIGHT,
|
|
6
|
+
hoverColor: Color.PRIMARY_HOVER,
|
|
7
|
+
hoverBackground: Color.BRIGHT_LIGHT_HOVER
|
|
6
8
|
},
|
|
7
9
|
danger: {
|
|
8
10
|
color: Color.DANGER,
|
|
9
|
-
background: Color.DANGER_LIGHT
|
|
11
|
+
background: Color.DANGER_LIGHT,
|
|
12
|
+
hoverColor: Color.DANGER_HOVER,
|
|
13
|
+
hoverBackground: Color.DANGER_LIGHT_HOVER
|
|
10
14
|
},
|
|
11
15
|
warning: {
|
|
12
16
|
color: Color.WARNING,
|
|
13
|
-
background: Color.WARNING_LIGHT
|
|
17
|
+
background: Color.WARNING_LIGHT,
|
|
18
|
+
hoverColor: Color.WARNING_HOVER,
|
|
19
|
+
hoverBackground: Color.WARNING_LIGHT_HOVER
|
|
14
20
|
}
|
|
15
21
|
};
|
package/Chip/Chip.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export declare const Chip: React.ForwardRefExoticComponent<{
|
|
|
5
5
|
$onClose?: React.HTMLAttributes<HTMLDivElement>["onClick"];
|
|
6
6
|
$readOnly?: boolean;
|
|
7
7
|
$maxWidth?: string;
|
|
8
|
+
$icon?: React.ReactNode;
|
|
9
|
+
$tooltip?: React.ReactNode;
|
|
8
10
|
as?: string;
|
|
9
11
|
} & {
|
|
10
12
|
children?: React.ReactNode | undefined;
|
package/Chip/Chip.js
CHANGED
|
@@ -1,31 +1,43 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { ChipStyled } from './styles';
|
|
2
|
+
import { TooltipTrigger } from '../Tooltip';
|
|
3
|
+
import { ChipCloseIcon, ChipLabel, ChipSlotIcon, ChipStyled } from './styles';
|
|
4
4
|
export const Chip = forwardRef(({
|
|
5
5
|
$variant = 'primary',
|
|
6
6
|
$selected,
|
|
7
7
|
$readOnly,
|
|
8
8
|
$onClose,
|
|
9
9
|
$maxWidth,
|
|
10
|
+
$icon,
|
|
11
|
+
$tooltip,
|
|
10
12
|
children,
|
|
11
13
|
as,
|
|
12
14
|
...rest
|
|
13
15
|
}, ref) => {
|
|
16
|
+
const isCloseable = !!$onClose && !$readOnly;
|
|
17
|
+
const hasTooltip = !isCloseable && $tooltip !== undefined;
|
|
18
|
+
if ($readOnly && $onClose) {
|
|
19
|
+
console.error('[Chip]: $onClose is ignored when $readOnly is true — read-only chips have no close button.');
|
|
20
|
+
}
|
|
14
21
|
return React.createElement(ChipStyled, {
|
|
15
22
|
ref: ref,
|
|
16
23
|
"$variant": $variant,
|
|
17
24
|
"$selected": $selected,
|
|
18
|
-
"$
|
|
25
|
+
"$hasLeadingIcon": !!$icon,
|
|
26
|
+
"$hasTrailingSlot": isCloseable || hasTooltip,
|
|
19
27
|
"$readOnly": $readOnly,
|
|
20
28
|
"$maxWidth": $maxWidth,
|
|
21
29
|
as: as,
|
|
22
30
|
...rest
|
|
23
|
-
}, React.createElement(
|
|
24
|
-
|
|
25
|
-
}, children),
|
|
31
|
+
}, $icon && React.createElement(ChipSlotIcon, null, $icon), React.createElement(ChipLabel, {
|
|
32
|
+
"$truncated": $maxWidth !== undefined
|
|
33
|
+
}, children), isCloseable && React.createElement(ChipCloseIcon, {
|
|
26
34
|
size: "small",
|
|
27
35
|
onClick: $onClose,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
forwardedAs: "span"
|
|
37
|
+
}), hasTooltip && React.createElement(ChipSlotIcon, null, React.createElement(TooltipTrigger, {
|
|
38
|
+
view: "question",
|
|
39
|
+
size: "small",
|
|
40
|
+
position: "top-middle",
|
|
41
|
+
content: $tooltip
|
|
42
|
+
})));
|
|
31
43
|
});
|
package/Chip/Chip.types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type HTMLAttributes, type PropsWithChildren } from 'react';
|
|
1
|
+
import { type HTMLAttributes, type PropsWithChildren, type ReactNode } from 'react';
|
|
2
2
|
export type ChipVariant = 'primary' | 'danger' | 'warning';
|
|
3
3
|
export type ChipProps = PropsWithChildren<{
|
|
4
4
|
$variant?: ChipVariant;
|
|
@@ -7,5 +7,7 @@ export type ChipProps = PropsWithChildren<{
|
|
|
7
7
|
$readOnly?: boolean;
|
|
8
8
|
/** CSS max-width value, e.g. "120px", "50%", "10rem". Enables label truncation with ellipsis. */
|
|
9
9
|
$maxWidth?: string;
|
|
10
|
+
$icon?: ReactNode;
|
|
11
|
+
$tooltip?: ReactNode;
|
|
10
12
|
as?: string;
|
|
11
13
|
}> & HTMLAttributes<HTMLDivElement>;
|
package/Chip/ai-documentation.md
CHANGED
|
@@ -21,6 +21,9 @@ interface ChipProps extends PropsWithChildren<HTMLAttributes<HTMLDivElement>> {
|
|
|
21
21
|
$selected?: boolean;
|
|
22
22
|
$onClose?: HTMLAttributes<HTMLDivElement>['onClick'];
|
|
23
23
|
$readOnly?: boolean;
|
|
24
|
+
$maxWidth?: string;
|
|
25
|
+
$icon?: ReactNode;
|
|
26
|
+
$tooltip?: ReactNode;
|
|
24
27
|
as?: string;
|
|
25
28
|
}
|
|
26
29
|
```
|
|
@@ -116,6 +119,26 @@ function App() {
|
|
|
116
119
|
{tag.name}
|
|
117
120
|
</Chip>
|
|
118
121
|
|
|
122
|
+
import { TagIcon } from '@pushwoosh/kit-icons';
|
|
123
|
+
|
|
124
|
+
// Chip with leading icon
|
|
125
|
+
<Chip $variant="primary" $icon={<TagIcon size="small" view="lined" />}>
|
|
126
|
+
Segment
|
|
127
|
+
</Chip>
|
|
128
|
+
|
|
129
|
+
// Icon + removable
|
|
130
|
+
<Chip
|
|
131
|
+
$icon={<TagIcon size="small" view="lined" />}
|
|
132
|
+
$onClose={() => removeTag(tag)}
|
|
133
|
+
>
|
|
134
|
+
{tag}
|
|
135
|
+
</Chip>
|
|
136
|
+
|
|
137
|
+
// Read-only chip with "?" tooltip
|
|
138
|
+
<Chip $readOnly $variant="primary" $tooltip="Explanation for this chip">
|
|
139
|
+
Label
|
|
140
|
+
</Chip>
|
|
141
|
+
|
|
119
142
|
// Status chips
|
|
120
143
|
function getStatusChip(status: string) {
|
|
121
144
|
const variantMap = {
|
|
@@ -139,6 +162,9 @@ function getStatusChip(status: string) {
|
|
|
139
162
|
| $variant | 'primary' \| 'danger' \| 'warning' | 'primary' | Visual style variant |
|
|
140
163
|
| $selected | boolean | false | Whether chip appears in selected state |
|
|
141
164
|
| $onClose | onClick handler | undefined | Makes chip removable with close icon |
|
|
165
|
+
| $maxWidth | string | undefined | CSS max-width; truncates label with ellipsis |
|
|
166
|
+
| $icon | ReactNode | undefined | Leading icon slot; pass a kit-icon with size="small" |
|
|
167
|
+
| $tooltip | ReactNode | undefined | Tooltip content; renders a trailing "?" trigger on read-only chips |
|
|
142
168
|
| $readOnly | boolean | false | Whether chip is interactive |
|
|
143
169
|
| as | string | 'div' | HTML element to render as |
|
|
144
170
|
| children | ReactNode | required | Chip content |
|
|
@@ -152,6 +178,18 @@ function getStatusChip(status: string) {
|
|
|
152
178
|
| danger | Errors, removable warnings | Error messages, dangerous actions |
|
|
153
179
|
| warning | Cautions, temporary states | Beta features, warnings, alerts |
|
|
154
180
|
|
|
181
|
+
## Hover States
|
|
182
|
+
|
|
183
|
+
Each variant darkens its background and tint on hover. Hover is only applied to
|
|
184
|
+
interactive chips — it is intentionally disabled when `$selected` (selected chips
|
|
185
|
+
keep the solid `MAIN` background) or `$readOnly` (non-interactive).
|
|
186
|
+
|
|
187
|
+
| Variant | Background → hover | Tint → hover |
|
|
188
|
+
|---------|--------------------|--------------|
|
|
189
|
+
| primary | BRIGHT_LIGHT → BRIGHT_LIGHT_HOVER | PRIMARY → PRIMARY_HOVER |
|
|
190
|
+
| danger | DANGER_LIGHT → DANGER_LIGHT_HOVER | DANGER → DANGER_HOVER |
|
|
191
|
+
| warning | WARNING_LIGHT → WARNING_LIGHT_HOVER | WARNING → WARNING_HOVER |
|
|
192
|
+
|
|
155
193
|
## AI Agent Guidelines
|
|
156
194
|
|
|
157
195
|
### ✅ Recommended Patterns
|
|
@@ -161,6 +199,8 @@ function getStatusChip(status: string) {
|
|
|
161
199
|
- Keep chip text short and descriptive
|
|
162
200
|
- Use semantic variants (danger for errors, warning for cautions)
|
|
163
201
|
- Group related chips together with consistent spacing
|
|
202
|
+
- When adding a leading icon, always use `size="small"` so it fits the chip's 24px height; pass `view` too if the icon defines one
|
|
203
|
+
- Slots are fixed: leading `$icon` on the left; the right side holds exactly one element — the close button on active chips (`$onClose`), or the `$tooltip` "?" trigger on read-only chips. A read-only chip never shows a close button, and the close button + tooltip are mutually exclusive.
|
|
164
204
|
|
|
165
205
|
### ❌ Common Mistakes to Avoid
|
|
166
206
|
- Don't use chips for very long text content
|
package/Chip/index.d.ts
CHANGED
package/Chip/styles.d.ts
CHANGED
|
@@ -2,7 +2,13 @@ import type { ChipVariant } from './Chip.types';
|
|
|
2
2
|
export declare const ChipStyled: import("styled-components").StyledComponent<"div", any, {
|
|
3
3
|
$variant: ChipVariant;
|
|
4
4
|
$selected?: boolean;
|
|
5
|
-
$
|
|
5
|
+
$hasLeadingIcon?: boolean;
|
|
6
|
+
$hasTrailingSlot?: boolean;
|
|
6
7
|
$readOnly?: boolean;
|
|
7
8
|
$maxWidth?: string;
|
|
8
9
|
}, never>;
|
|
10
|
+
export declare const ChipSlotIcon: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
11
|
+
export declare const ChipLabel: import("styled-components").StyledComponent<"span", any, {
|
|
12
|
+
$truncated?: boolean;
|
|
13
|
+
}, never>;
|
|
14
|
+
export declare const ChipCloseIcon: import("styled-components").StyledComponent<import("react").FC<import("@pushwoosh/kit-icons").CloseIconProps>, any, {}, never>;
|
package/Chip/styles.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
2
|
import { Color } from '@pushwoosh/kit-constants';
|
|
3
|
+
import { CloseIcon } from '@pushwoosh/kit-icons';
|
|
3
4
|
import { variants } from './Chip.constants';
|
|
4
5
|
export const ChipStyled = styled.div.withConfig({
|
|
5
6
|
displayName: "ChipStyled",
|
|
6
7
|
componentId: "sc-e2g39l-0"
|
|
7
|
-
})(["display:inline-flex;min-height:24px;", " padding:0 ", " 0
|
|
8
|
+
})(["display:inline-flex;min-height:24px;", " padding:0 ", " 0 ", ";align-items:center;gap:4px;cursor:", ";border-radius:4px;color:", ";background:", ";font-weight:400;line-height:140%;", ""], ({
|
|
8
9
|
$maxWidth
|
|
9
10
|
}) => $maxWidth !== undefined && `max-width: ${$maxWidth};`, ({
|
|
10
|
-
$
|
|
11
|
-
}) => $
|
|
11
|
+
$hasTrailingSlot
|
|
12
|
+
}) => $hasTrailingSlot ? '4px' : '8px', ({
|
|
13
|
+
$hasLeadingIcon
|
|
14
|
+
}) => $hasLeadingIcon ? '4px' : '8px', ({
|
|
12
15
|
$readOnly
|
|
13
16
|
}) => $readOnly ? 'default' : 'pointer', ({
|
|
14
17
|
$variant,
|
|
@@ -29,11 +32,32 @@ export const ChipStyled = styled.div.withConfig({
|
|
|
29
32
|
}
|
|
30
33
|
return $selected ? Color.MAIN : variants[$variant].background;
|
|
31
34
|
}, ({
|
|
32
|
-
$
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
$variant,
|
|
36
|
+
$selected,
|
|
37
|
+
$readOnly
|
|
38
|
+
}) => !$selected && !$readOnly && `
|
|
39
|
+
&:hover {
|
|
40
|
+
color: ${variants[$variant].hoverColor};
|
|
41
|
+
background: ${variants[$variant].hoverBackground};
|
|
42
|
+
}
|
|
43
|
+
`);
|
|
44
|
+
export const ChipSlotIcon = styled.span.withConfig({
|
|
45
|
+
displayName: "ChipSlotIcon",
|
|
46
|
+
componentId: "sc-e2g39l-1"
|
|
47
|
+
})(["display:inline-flex;flex-shrink:0;"]);
|
|
48
|
+
export const ChipLabel = styled.span.withConfig({
|
|
49
|
+
displayName: "ChipLabel",
|
|
50
|
+
componentId: "sc-e2g39l-2"
|
|
51
|
+
})(["", ""], ({
|
|
52
|
+
$truncated
|
|
53
|
+
}) => $truncated && `
|
|
54
|
+
flex: 1 1 0;
|
|
55
|
+
min-width: 0;
|
|
56
|
+
overflow: hidden;
|
|
57
|
+
text-overflow: ellipsis;
|
|
58
|
+
white-space: nowrap;
|
|
59
|
+
`);
|
|
60
|
+
export const ChipCloseIcon = styled(CloseIcon).withConfig({
|
|
61
|
+
displayName: "ChipCloseIcon",
|
|
62
|
+
componentId: "sc-e2g39l-3"
|
|
63
|
+
})(["flex-shrink:0;transition:transform 0.2s;&:hover{transform:scale(1.3);}"]);
|
package/index.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export { FieldBox } from './FieldBox';
|
|
|
39
39
|
export { NumberPicker } from './NumberPicker';
|
|
40
40
|
export { CodeEditor } from './CodeEditor';
|
|
41
41
|
export { EnhancedInput, SearchInput } from './EnhancedInput';
|
|
42
|
-
export { Chip } from './Chip';
|
|
42
|
+
export { Chip, type ChipProps, type ChipVariant } from './Chip';
|
|
43
43
|
export { RichmediaPreview, useRichmediaHtml } from './RichmediaPreview';
|
|
44
44
|
export { RichMessageEditor, RichMessageViewer, type DynamicContent, } from './RichMessageEditor';
|
|
45
45
|
export { FrequencyCappingEdit, FrequencyCappingReadonly, FrequencyCappingInApps, type LocalCapping, type CappingInAppBase, } from './FrequencyCapping';
|