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.
@@ -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.7.1",
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.1",
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.2",
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.0.5",
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
- highlightClassName={classnames(
36
+ className={classnames(
24
37
  styles["highlight"],
25
38
  {
26
39
  [styles[`highlight--${color}-color`]]: color,
27
40
  },
28
- highlightClassName
41
+ className
29
42
  )}
30
- activeClassName={classnames(styles["highlight--active"], activeClassName)}
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
- font-size: var(--highlight-font-size, inherit);
5
- font-weight: var(--highlight-font-weight, inherit);
6
- font-family: var(--highlight-font-family, inherit), sans-serif;
7
- line-height: var(--highlight-line-height, var(--line-height, 1rem));
8
- color: var(--highlight-color, #fff);
9
- background-color: var(--highlight-bg-color, #ffd60a);
10
- padding: var(--highlight-y-padding, 2px) var(--highlight-x-padding, 3px);
11
- margin: 0 calc(-1 * var(--highlight-x-padding, 3px));
12
- border-radius: var(--highlight-border-radius, 2px);
13
- transition:
14
- color var(--highlight-speed-color, var(--speed-color)),
15
- background-color var(--highlight-speed-bg, var(--speed-color));
16
-
17
- &--primary-color {
18
- color: var(--highlight-primary-color, #fff);
19
- background-color: var(--primary-color);
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
- &--secondary-color {
23
- color: var(--highlight-secondary-color, #fff);
24
- background-color: var(--secondary-color);
25
- }
25
+ .#{$root}--secondary-color & {
26
+ color: var(--highlight-secondary-color, #fff);
27
+ background-color: var(--secondary-color);
28
+ }
26
29
 
27
- &--accent-color {
28
- color: var(--highlight-accent-color, #fff);
29
- background-color: var(--accent-color);
30
- }
30
+ .#{$root}--accent-color & {
31
+ color: var(--highlight-accent-color, #fff);
32
+ background-color: var(--accent-color);
33
+ }
31
34
 
32
- &--active {
33
- color: var(--highlight-active-color, var(--highlight-color, #fff));
34
- background-color: var(--highlight-active-bg-color, #ff801f);
35
+ &--active {
36
+ color: var(--highlight-active-color, var(--highlight-color, #fff));
37
+ background-color: var(--highlight-active-bg-color, #ff801f);
35
38
 
36
- &.#{$root}--primary-color {
37
- color: var(--highlight-active-primary-color, var(--highlight-primary-color, #fff));
38
- background-color: color-mix(in srgb, black 40%, var(--primary-color));
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
- &.#{$root}--secondary-color {
42
- color: var(--highlight-active-secondary-color, var(--highlight-secondary-color, #fff));
43
- background-color: color-mix(in srgb, black 40%, var(--secondary-color));
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
- &.#{$root}--accent-color {
47
- color: var(--highlight-active-accent-color, var(--highlight-accent-color, #fff));
48
- background-color: color-mix(in srgb, black 40%, var(--accent-color));
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
  }
@@ -77,6 +77,7 @@ $root: modal;
77
77
  &-children {
78
78
  display: flex;
79
79
  flex-direction: column;
80
+ overflow: hidden;
80
81
  }
81
82
 
82
83
  &-close {
@@ -19,7 +19,10 @@ $border-width: 1px;
19
19
  position: relative;
20
20
  display: flex;
21
21
  justify-content: space-between;
22
- transition: border-bottom-color var(--tabs-speed-border-color, var(--speed-color));
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 {text = "", middle, separator = "...", className, ...other} = {...useComponentProps("truncate"), ...props};
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
- animationFrameId = requestAnimationFrame(() => {
69
- const newText = trimMiddle(el, text, separator);
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
- if ("ResizeObserver" in window) {
79
- observer = new ResizeObserver(() => {
80
- cancelAnimationFrame(animationFrameId);
81
- measureAndTrim();
82
- });
83
- observer.observe(el);
84
- }
88
+ observer = new ResizeObserver(() => measureAndTrim());
85
89
 
86
- window.addEventListener("resize", measureAndTrim);
90
+ observer.observe(el);
87
91
 
88
92
  return () => {
89
- window.removeEventListener("resize", measureAndTrim);
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
- {middle ? displayedText : text}
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
 
@@ -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;