@frontfactory/readmore 1.2.0 → 1.3.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/README.md CHANGED
@@ -53,7 +53,8 @@ Or instantiate against a single element:
53
53
  const el = document.querySelector<HTMLElement>('#bio');
54
54
 
55
55
  if (el) new ReadMore(el, {
56
- lines: 4
56
+ lines: 4,
57
+ onToggle: (expanded) => console.log('expanded:', expanded)
57
58
  });
58
59
  ```
59
60
 
@@ -61,14 +62,15 @@ if (el) new ReadMore(el, {
61
62
 
62
63
  | Option | Type | Default | Description |
63
64
  |-----------------|----------|------------------|--------------------------------------------------------------------|
64
- | `lines` | `number` | `3` | Number of lines to clamp to. Ignored if `height` is set. |
65
- | `height` | `number` | — | Max height in pixels. Takes precedence over `lines` when provided. |
65
+ | `lines` | `number` | `3` | Number of lines to clamp to (min `1`). Ignored if `height` is set. |
66
+ | `height` | `number` | — | Max height in pixels (min `1`). Takes precedence over `lines`. |
66
67
  | `moreText` | `string` | `'Read more'` | Label of the button when the text is collapsed. |
67
68
  | `lessText` | `string` | `'Read less'` | Label of the button when the text is expanded. |
68
69
  | `buttonClass` | `string` | `'readmore-btn'` | Class applied to the toggle button. |
69
70
  | `expandedClass` | `string` | `'is-expanded'` | Class applied to the target element while expanded. |
70
71
  | `openingClass` | `string` | `'is-opening'` | Transient class applied while expanding, removed after transition. |
71
72
  | `closingClass` | `string` | `'is-closing'` | Transient class applied while collapsing, removed after transition.|
73
+ | `onToggle` | `(expanded: boolean) => void` | — | Callback fired after each toggle with the current `expanded` state. |
72
74
 
73
75
  ## API
74
76
 
@@ -7,9 +7,11 @@ export interface ReadMoreOptions {
7
7
  expandedClass?: string;
8
8
  openingClass?: string;
9
9
  closingClass?: string;
10
+ onToggle?: (expanded: boolean) => void;
10
11
  }
11
- type ResolvedOptions = Required<Omit<ReadMoreOptions, 'height'>> & {
12
+ type ResolvedOptions = Required<Omit<ReadMoreOptions, 'height' | 'onToggle'>> & {
12
13
  height?: number;
14
+ onToggle?: (expanded: boolean) => void;
13
15
  };
14
16
  export declare class ReadMore {
15
17
  #private;
package/dist/readmore.js CHANGED
@@ -19,10 +19,12 @@ var e = "readmore-clamp", t = "readmore-clamp--height", n = /* @__PURE__ */ new
19
19
  constructor(e, t = {}) {
20
20
  if (!(e instanceof HTMLElement)) throw TypeError("ReadMore: an HTMLElement is required.");
21
21
  if (n.has(e)) throw Error("ReadMore: element is already initialized. Call destroy() first.");
22
- this.el = e, this.options = {
22
+ if (this.el = e, this.options = {
23
23
  ...i,
24
24
  ...t
25
- }, this.#r = new ResizeObserver(() => this.#c()), n.set(e, this), this.#o();
25
+ }, this.options.height != null && this.options.height <= 0) throw RangeError("ReadMore: height must be greater than 0.");
26
+ if (this.options.lines < 1) throw RangeError("ReadMore: lines must be at least 1.");
27
+ this.#r = new ResizeObserver(() => this.#c()), n.set(e, this), this.#o();
26
28
  }
27
29
  static init(e, t) {
28
30
  let n = typeof e == "string" ? document.querySelectorAll(e) : e;
@@ -34,7 +36,7 @@ var e = "readmore-clamp", t = "readmore-clamp--height", n = /* @__PURE__ */ new
34
36
  toggle() {
35
37
  this.#t = !this.#t, this.el.classList.toggle(e, !this.#t), this.options.height != null && this.el.classList.toggle(t, !this.#t), this.el.classList.toggle(this.options.expandedClass, this.#t), this.#e && (this.#e.textContent = this.#t ? this.options.lessText : this.options.moreText, this.#e.setAttribute("aria-expanded", String(this.#t)));
36
38
  let n = this.#t ? this.options.openingClass : this.options.closingClass, r = this.#t ? this.options.closingClass : this.options.openingClass;
37
- this.el.classList.remove(r), this.#l(n), this.#t || this.#c();
39
+ this.el.classList.remove(r), this.#l(n), this.#t || this.#c(), this.options.onToggle?.(this.#t);
38
40
  }
39
41
  static getInstance(e) {
40
42
  return n.get(e);
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@frontfactory/readmore",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Lightweight plugin to clamp text to N lines with ellipsis and a read more action.",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite",
8
+ "lint:js": "eslint --fix .",
8
9
  "build": "vite build",
9
10
  "preview": "vite preview",
10
11
  "typecheck": "tsc --noEmit",
@@ -30,21 +31,25 @@
30
31
  "devDependencies": {
31
32
  "@commitlint/cli": "^20.5.3",
32
33
  "@commitlint/config-conventional": "^20.5.3",
34
+ "@front-factory/eslint-config": "^2.4.2",
33
35
  "@semantic-release/changelog": "^6.0.3",
34
36
  "@semantic-release/git": "^10.0.1",
35
37
  "@semantic-release/github": "^12.0.6",
36
38
  "@vitest/coverage-v8": "^4.1.5",
37
39
  "conventional-changelog-conventionalcommits": "^9.3.1",
40
+ "eslint": "^10.3.0",
38
41
  "husky": "^9.1.7",
39
42
  "jsdom": "^29.1.1",
40
43
  "lightningcss": "^1.32.0",
41
44
  "semantic-release": "^25.0.3",
42
45
  "typescript": "^5.4.0",
46
+ "typescript-eslint": "^8.59.2",
43
47
  "vite": "^8.0.11",
44
48
  "vite-plugin-dts": "^5.0.0",
45
49
  "vite-plugin-static-copy": "^4.1.0",
46
50
  "vitest": "^4.1.5"
47
51
  },
52
+ "sideEffects": false,
48
53
  "files": [
49
54
  "dist"
50
55
  ],