addon-ui 0.7.1 → 0.8.0
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/dist-types/components/Highlight/Highlight.d.ts +2 -1
- package/dist-types/components/Truncate/Truncate.d.ts +2 -0
- package/dist-types/components/types.d.ts +1 -1
- package/package.json +10 -5
- package/src/components/Accordion/accordion.module.scss +1 -0
- package/src/components/Checkbox/checkbox.module.scss +1 -1
- package/src/components/Highlight/Highlight.tsx +22 -6
- package/src/components/Highlight/highlight.module.scss +43 -39
- package/src/components/Modal/modal.module.scss +1 -0
- package/src/components/Tabs/tabs.module.scss +4 -1
- package/src/components/Truncate/Truncate.tsx +26 -23
- package/src/components/Truncate/truncate.module.scss +10 -0
- package/src/components/types.ts +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { HighlighterProps } from "react-highlight-words";
|
|
3
3
|
import { HighlightColor } from "./types";
|
|
4
|
-
export interface HighlightProps extends HighlighterProps {
|
|
4
|
+
export interface HighlightProps extends Omit<HighlighterProps, "searchWords"> {
|
|
5
5
|
color?: HighlightColor;
|
|
6
|
+
searchWords?: string | RegExp | (string | RegExp)[];
|
|
6
7
|
}
|
|
7
8
|
declare const _default: React.NamedExoticComponent<HighlightProps>;
|
|
8
9
|
export default _default;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React, { ComponentProps } from "react";
|
|
2
|
+
import { HighlightProps } from "../Highlight";
|
|
2
3
|
export interface TruncateProps extends ComponentProps<"span"> {
|
|
3
4
|
text?: string;
|
|
4
5
|
middle?: boolean;
|
|
5
6
|
separator?: string;
|
|
7
|
+
highlight?: Omit<HighlightProps, "textToHighlight">;
|
|
6
8
|
}
|
|
7
9
|
declare const _default: React.NamedExoticComponent<Omit<TruncateProps, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
8
10
|
export default _default;
|
|
@@ -7,7 +7,7 @@ export interface ComponentsProps {
|
|
|
7
7
|
drawer?: DrawerProps;
|
|
8
8
|
footer?: FooterProps;
|
|
9
9
|
header?: Pick<HeaderProps, "alignCenter" | "before" | "after">;
|
|
10
|
-
highlight?: HighlightProps
|
|
10
|
+
highlight?: Omit<HighlightProps, "textToHighlight">;
|
|
11
11
|
icon?: Omit<IconProps, "name">;
|
|
12
12
|
iconButton?: Pick<IconButtonProps, "variant" | "size" | "radius">;
|
|
13
13
|
list?: ListProps;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "addon-ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0",
|
|
5
5
|
"description": "A comprehensive React UI component library designed exclusively for the AddonBone browser extension framework with customizable theming and consistent design patterns",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"react",
|
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "https://github.com/addon-stack/addon-ui"
|
|
25
|
+
"url": "git+https://github.com/addon-stack/addon-ui.git"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public",
|
|
29
|
+
"provenance": true
|
|
26
30
|
},
|
|
27
31
|
"bugs": {
|
|
28
32
|
"url": "https://github.com/addon-stack/addon-ui/issues"
|
|
@@ -80,6 +84,7 @@
|
|
|
80
84
|
"@types/react-highlight-words": "^0.20.0",
|
|
81
85
|
"autosize": "^6.0.1",
|
|
82
86
|
"classnames": "^2.5.1",
|
|
87
|
+
"debounce": "^2.2.0",
|
|
83
88
|
"odometer": "^0.4.8",
|
|
84
89
|
"radix-ui": "^1.1.3",
|
|
85
90
|
"react-highlight-words": "^0.21.0",
|
|
@@ -91,7 +96,7 @@
|
|
|
91
96
|
"@commitlint/cli": "^20.0.0",
|
|
92
97
|
"@commitlint/config-conventional": "^20.0.0",
|
|
93
98
|
"@eslint/js": "^9.21.0",
|
|
94
|
-
"@release-it/conventional-changelog": "^10.0.
|
|
99
|
+
"@release-it/conventional-changelog": "^10.0.4",
|
|
95
100
|
"@rsbuild/plugin-sass": "^1.4.0",
|
|
96
101
|
"@storybook/react": "^9.1.3",
|
|
97
102
|
"@types/chrome": "^0.1.12",
|
|
@@ -100,7 +105,7 @@
|
|
|
100
105
|
"@types/node": "^22.13.10",
|
|
101
106
|
"@types/react": "^19.0.10",
|
|
102
107
|
"@types/react-dom": "^19.0.4",
|
|
103
|
-
"adnbn": "^0.4
|
|
108
|
+
"adnbn": "^0.5.4",
|
|
104
109
|
"depcheck": "^1.4.7",
|
|
105
110
|
"eslint": "^9.21.0",
|
|
106
111
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
@@ -111,7 +116,7 @@
|
|
|
111
116
|
"prettier": "^3.5.3",
|
|
112
117
|
"react": "^19.1.0",
|
|
113
118
|
"react-dom": "^19.1.0",
|
|
114
|
-
"release-it": "^19.
|
|
119
|
+
"release-it": "^19.2.3",
|
|
115
120
|
"rspack-plugin-virtual-module": "^1.0.0",
|
|
116
121
|
"storybook": "^9.1.3",
|
|
117
122
|
"storybook-react-rsbuild": "^2.1.0",
|
|
@@ -28,6 +28,7 @@ $root: accordion;
|
|
|
28
28
|
background-color: var(--accordion-content-bg-color);
|
|
29
29
|
will-change: background-color;
|
|
30
30
|
transition: background-color var(--accordion-speed-bg, var(--speed-color));
|
|
31
|
+
overflow: hidden;
|
|
31
32
|
|
|
32
33
|
&[data-state="open"] {
|
|
33
34
|
animation: slideDown var(--accordion-speed-animation, var(--speed-sm)) ease-in-out;
|
|
@@ -5,7 +5,7 @@ $root: checkbox;
|
|
|
5
5
|
align-items: center;
|
|
6
6
|
justify-content: center;
|
|
7
7
|
cursor: pointer;
|
|
8
|
-
padding: 2px;
|
|
8
|
+
padding: var(--checkbox-padding, 2px);
|
|
9
9
|
width: var(--checkbox-size, 18px);
|
|
10
10
|
height: var(--checkbox-size, 18px);
|
|
11
11
|
border-radius: var(--checkbox-border-radius, 4px);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {FC, memo} from "react";
|
|
1
|
+
import React, {FC, memo, useMemo} from "react";
|
|
2
2
|
import classnames from "classnames";
|
|
3
3
|
import Highlighter, {HighlighterProps} from "react-highlight-words";
|
|
4
4
|
|
|
@@ -8,26 +8,42 @@ import {HighlightColor} from "./types";
|
|
|
8
8
|
|
|
9
9
|
import styles from "./highlight.module.scss";
|
|
10
10
|
|
|
11
|
-
export interface HighlightProps extends HighlighterProps {
|
|
11
|
+
export interface HighlightProps extends Omit<HighlighterProps, "searchWords"> {
|
|
12
12
|
color?: HighlightColor;
|
|
13
|
+
searchWords?: string | RegExp | (string | RegExp)[];
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const Highlight: FC<HighlightProps> = props => {
|
|
16
|
-
const {color, activeClassName, highlightClassName, ...other} = {
|
|
17
|
+
const {color, className, activeClassName, highlightClassName, searchWords, textToHighlight, ...other} = {
|
|
17
18
|
...useComponentProps("highlight"),
|
|
18
19
|
...props,
|
|
19
20
|
};
|
|
20
21
|
|
|
22
|
+
const search = useMemo(() => {
|
|
23
|
+
if (!searchWords) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (Array.isArray(searchWords)) {
|
|
28
|
+
return searchWords;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return [searchWords];
|
|
32
|
+
}, [searchWords]);
|
|
33
|
+
|
|
21
34
|
return (
|
|
22
35
|
<Highlighter
|
|
23
|
-
|
|
36
|
+
className={classnames(
|
|
24
37
|
styles["highlight"],
|
|
25
38
|
{
|
|
26
39
|
[styles[`highlight--${color}-color`]]: color,
|
|
27
40
|
},
|
|
28
|
-
|
|
41
|
+
className
|
|
29
42
|
)}
|
|
30
|
-
|
|
43
|
+
highlightClassName={classnames(styles["highlight-mark"], highlightClassName)}
|
|
44
|
+
activeClassName={classnames(styles["highlight-mark--active"], activeClassName)}
|
|
45
|
+
searchWords={search}
|
|
46
|
+
textToHighlight={textToHighlight}
|
|
31
47
|
{...other}
|
|
32
48
|
/>
|
|
33
49
|
);
|
|
@@ -1,51 +1,55 @@
|
|
|
1
1
|
$root: highlight;
|
|
2
2
|
|
|
3
3
|
.#{$root} {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
4
|
+
display: inline;
|
|
5
|
+
|
|
6
|
+
&-mark {
|
|
7
|
+
font-size: var(--highlight-font-size, inherit);
|
|
8
|
+
font-weight: var(--highlight-font-weight, inherit);
|
|
9
|
+
font-family: var(--highlight-font-family, inherit), sans-serif;
|
|
10
|
+
line-height: var(--highlight-line-height, var(--line-height, 1rem));
|
|
11
|
+
color: var(--highlight-color, #fff);
|
|
12
|
+
background-color: var(--highlight-bg-color, #ffd60a);
|
|
13
|
+
padding: var(--highlight-y-padding, 2px) var(--highlight-x-padding, 3px);
|
|
14
|
+
margin: 0 calc(-1 * var(--highlight-x-padding, 3px));
|
|
15
|
+
border-radius: var(--highlight-border-radius, 2px);
|
|
16
|
+
transition:
|
|
17
|
+
color var(--highlight-speed-color, var(--speed-color)),
|
|
18
|
+
background-color var(--highlight-speed-bg, var(--speed-color));
|
|
19
|
+
|
|
20
|
+
.#{$root}--primary-color & {
|
|
21
|
+
color: var(--highlight-primary-color, #fff);
|
|
22
|
+
background-color: var(--primary-color);
|
|
23
|
+
}
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
.#{$root}--secondary-color & {
|
|
26
|
+
color: var(--highlight-secondary-color, #fff);
|
|
27
|
+
background-color: var(--secondary-color);
|
|
28
|
+
}
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
.#{$root}--accent-color & {
|
|
31
|
+
color: var(--highlight-accent-color, #fff);
|
|
32
|
+
background-color: var(--accent-color);
|
|
33
|
+
}
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
&--active {
|
|
36
|
+
color: var(--highlight-active-color, var(--highlight-color, #fff));
|
|
37
|
+
background-color: var(--highlight-active-bg-color, #ff801f);
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
.#{$root}--primary-color & {
|
|
40
|
+
color: var(--highlight-active-primary-color, var(--highlight-primary-color, #fff));
|
|
41
|
+
background-color: color-mix(in srgb, black 40%, var(--primary-color));
|
|
42
|
+
}
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
.#{$root}--secondary-color & {
|
|
45
|
+
color: var(--highlight-active-secondary-color, var(--highlight-secondary-color, #fff));
|
|
46
|
+
background-color: color-mix(in srgb, black 40%, var(--secondary-color));
|
|
47
|
+
}
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
.#{$root}--accent-color & {
|
|
50
|
+
color: var(--highlight-active-accent-color, var(--highlight-accent-color, #fff));
|
|
51
|
+
background-color: color-mix(in srgb, black 40%, var(--accent-color));
|
|
52
|
+
}
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
}
|
|
@@ -19,7 +19,10 @@ $border-width: 1px;
|
|
|
19
19
|
position: relative;
|
|
20
20
|
display: flex;
|
|
21
21
|
justify-content: space-between;
|
|
22
|
-
|
|
22
|
+
background-color: var(--tabs-list-bg-color);
|
|
23
|
+
transition:
|
|
24
|
+
border-bottom-color var(--tabs-speed-border-color, var(--speed-color)),
|
|
25
|
+
background-color var(--tabs-speed-bg-list-color, var(--speed-color));
|
|
23
26
|
|
|
24
27
|
@include theme.rtl() {
|
|
25
28
|
& {
|
|
@@ -5,19 +5,24 @@ import React, {
|
|
|
5
5
|
memo,
|
|
6
6
|
useImperativeHandle,
|
|
7
7
|
useLayoutEffect,
|
|
8
|
+
useMemo,
|
|
8
9
|
useRef,
|
|
9
10
|
useState,
|
|
10
11
|
} from "react";
|
|
12
|
+
import debounce from "debounce";
|
|
11
13
|
import classnames from "classnames";
|
|
12
14
|
|
|
13
15
|
import {useComponentProps} from "../../providers";
|
|
14
16
|
|
|
17
|
+
import {Highlight, HighlightProps} from "../Highlight";
|
|
18
|
+
|
|
15
19
|
import styles from "./truncate.module.scss";
|
|
16
20
|
|
|
17
21
|
export interface TruncateProps extends ComponentProps<"span"> {
|
|
18
22
|
text?: string;
|
|
19
23
|
middle?: boolean;
|
|
20
24
|
separator?: string;
|
|
25
|
+
highlight?: Omit<HighlightProps, "textToHighlight">;
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
const trimMiddle = (el: HTMLElement, text: string, separator: string) => {
|
|
@@ -50,52 +55,48 @@ const trimMiddle = (el: HTMLElement, text: string, separator: string) => {
|
|
|
50
55
|
};
|
|
51
56
|
|
|
52
57
|
const Truncate: ForwardRefRenderFunction<HTMLSpanElement, TruncateProps> = (props, ref) => {
|
|
53
|
-
const {
|
|
58
|
+
const {
|
|
59
|
+
text = "",
|
|
60
|
+
middle,
|
|
61
|
+
separator = "...",
|
|
62
|
+
className,
|
|
63
|
+
highlight,
|
|
64
|
+
...other
|
|
65
|
+
} = {...useComponentProps("truncate"), ...props};
|
|
54
66
|
|
|
55
67
|
const innerRef = useRef<HTMLSpanElement | null>(null);
|
|
56
68
|
const [displayedText, setDisplayedText] = useState(text);
|
|
57
69
|
|
|
70
|
+
const finalText = useMemo(() => {
|
|
71
|
+
return middle ? displayedText : text;
|
|
72
|
+
}, [displayedText, text, middle]);
|
|
73
|
+
|
|
58
74
|
useImperativeHandle(ref, () => innerRef.current!, []);
|
|
59
75
|
|
|
60
76
|
useLayoutEffect(() => {
|
|
61
77
|
const el = innerRef.current;
|
|
62
78
|
if (!el || !middle) return;
|
|
63
79
|
|
|
64
|
-
let animationFrameId: number;
|
|
65
80
|
let observer: ResizeObserver | null = null;
|
|
66
81
|
|
|
67
|
-
const measureAndTrim = () => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (newText !== displayedText) {
|
|
71
|
-
setDisplayedText(newText);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
};
|
|
82
|
+
const measureAndTrim = debounce(() => {
|
|
83
|
+
setDisplayedText(trimMiddle(el, text, separator));
|
|
84
|
+
}, 150);
|
|
75
85
|
|
|
76
86
|
measureAndTrim();
|
|
77
87
|
|
|
78
|
-
|
|
79
|
-
observer = new ResizeObserver(() => {
|
|
80
|
-
cancelAnimationFrame(animationFrameId);
|
|
81
|
-
measureAndTrim();
|
|
82
|
-
});
|
|
83
|
-
observer.observe(el);
|
|
84
|
-
}
|
|
88
|
+
observer = new ResizeObserver(() => measureAndTrim());
|
|
85
89
|
|
|
86
|
-
|
|
90
|
+
observer.observe(el);
|
|
87
91
|
|
|
88
92
|
return () => {
|
|
89
|
-
|
|
93
|
+
measureAndTrim.clear();
|
|
90
94
|
observer?.disconnect();
|
|
91
|
-
cancelAnimationFrame(animationFrameId);
|
|
92
95
|
};
|
|
93
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
94
96
|
}, [text, separator, middle]);
|
|
95
97
|
|
|
96
98
|
return (
|
|
97
99
|
<span
|
|
98
|
-
ref={innerRef}
|
|
99
100
|
className={classnames(
|
|
100
101
|
styles["truncate"],
|
|
101
102
|
{
|
|
@@ -105,7 +106,9 @@ const Truncate: ForwardRefRenderFunction<HTMLSpanElement, TruncateProps> = (prop
|
|
|
105
106
|
)}
|
|
106
107
|
{...other}
|
|
107
108
|
>
|
|
108
|
-
{
|
|
109
|
+
<span ref={innerRef} className={styles["truncate__hidden"]} />
|
|
110
|
+
|
|
111
|
+
{highlight ? <Highlight {...highlight} textToHighlight={finalText} /> : finalText}
|
|
109
112
|
</span>
|
|
110
113
|
);
|
|
111
114
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
@use "../../styles/mixins" as theme;
|
|
2
2
|
|
|
3
3
|
.truncate {
|
|
4
|
+
position: relative;
|
|
4
5
|
display: block;
|
|
5
6
|
width: 100%;
|
|
6
7
|
white-space: nowrap;
|
|
@@ -8,6 +9,15 @@
|
|
|
8
9
|
text-overflow: ellipsis;
|
|
9
10
|
transition: color var(--truncate-speed-color, var(--speed-color));
|
|
10
11
|
|
|
12
|
+
&__hidden {
|
|
13
|
+
opacity: 0;
|
|
14
|
+
position: absolute;
|
|
15
|
+
width: 100%;
|
|
16
|
+
white-space: nowrap;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
text-overflow: ellipsis;
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
&--middle {
|
|
12
22
|
text-overflow: clip;
|
|
13
23
|
|
package/src/components/types.ts
CHANGED
|
@@ -39,7 +39,7 @@ export interface ComponentsProps {
|
|
|
39
39
|
drawer?: DrawerProps;
|
|
40
40
|
footer?: FooterProps;
|
|
41
41
|
header?: Pick<HeaderProps, "alignCenter" | "before" | "after">;
|
|
42
|
-
highlight?: HighlightProps
|
|
42
|
+
highlight?: Omit<HighlightProps, "textToHighlight">;
|
|
43
43
|
icon?: Omit<IconProps, "name">;
|
|
44
44
|
iconButton?: Pick<IconButtonProps, "variant" | "size" | "radius">;
|
|
45
45
|
list?: ListProps;
|