@splendidlabz/utils 1.9.0 → 1.10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @splendidlabz/utils
2
2
 
3
+ ## 1.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4efacb3: - 6c636877 fix scroll observer
8
+ - 54effb06 add rlh
9
+
10
+ ## 1.9.1
11
+
12
+ ### Patch Changes
13
+
14
+ - Replace Markdown with Markdown-it
15
+
3
16
  ## 1.9.0
4
17
 
5
18
  ### Minor Changes
@@ -23,6 +23,7 @@ __export(font_size_exports, {
23
23
  getUnit: () => getUnit,
24
24
  lh: () => lh,
25
25
  rem: () => rem,
26
+ rlh: () => rlh,
26
27
  toPx: () => toPx
27
28
  });
28
29
  module.exports = __toCommonJS(font_size_exports);
@@ -41,13 +42,17 @@ function getUnit(value) {
41
42
  const [, unit] = splitUnit(value);
42
43
  return unit;
43
44
  }
45
+ function rem(multiple = 1) {
46
+ const value = parseFloat(getComputedStyle(document.body)["font-size"]);
47
+ return Math.round(value * multiple);
48
+ }
44
49
  function em(element = document.body, multiple = 1) {
45
50
  const value = parseFloat(getComputedStyle(element)["font-size"]);
46
51
  return Math.round(value * multiple);
47
52
  }
48
- function rem(multiple = 1) {
49
- const value = parseFloat(getComputedStyle(document.body)["font-size"]);
50
- return Math.round(value * multiple);
53
+ function rlh(multiple = 1) {
54
+ const lineHeight = parseFloat(getComputedStyle(document.body)["line-height"]);
55
+ return Math.round(lineHeight * multiple);
51
56
  }
52
57
  function lh(element = document.body, multiple = 1) {
53
58
  const lineHeight = getComputedStyle(element)["line-height"];
@@ -70,5 +75,6 @@ function toPx(value, element = null) {
70
75
  getUnit,
71
76
  lh,
72
77
  rem,
78
+ rlh,
73
79
  toPx
74
80
  });
@@ -77,6 +77,7 @@ __export(dom_exports, {
77
77
  rem: () => rem,
78
78
  removeListeners: () => removeListeners,
79
79
  resizeObserver: () => resizeObserver,
80
+ rlh: () => rlh,
80
81
  sanitize: () => sanitize2,
81
82
  scrollObserver: () => scrollObserver,
82
83
  scrollToElement: () => scrollToElement,
@@ -736,13 +737,17 @@ function getUnit(value) {
736
737
  const [, unit] = splitUnit(value);
737
738
  return unit;
738
739
  }
740
+ function rem(multiple = 1) {
741
+ const value = parseFloat(getComputedStyle(document.body)["font-size"]);
742
+ return Math.round(value * multiple);
743
+ }
739
744
  function em(element = document.body, multiple = 1) {
740
745
  const value = parseFloat(getComputedStyle(element)["font-size"]);
741
746
  return Math.round(value * multiple);
742
747
  }
743
- function rem(multiple = 1) {
744
- const value = parseFloat(getComputedStyle(document.body)["font-size"]);
745
- return Math.round(value * multiple);
748
+ function rlh(multiple = 1) {
749
+ const lineHeight = parseFloat(getComputedStyle(document.body)["line-height"]);
750
+ return Math.round(lineHeight * multiple);
746
751
  }
747
752
  function lh(element = document.body, multiple = 1) {
748
753
  const lineHeight = getComputedStyle(element)["line-height"];
@@ -915,40 +920,35 @@ var defaultOptions2 = {
915
920
  // Float between 0 to 1.
916
921
  tolerance: 0.1,
917
922
  // Float between 0 to 1. Tolerance for event firing
918
- throttle: 16,
919
- // Throttle interval in ms (default: ~60fps)
920
923
  once: false
921
924
  // Only fire threshold callback once
922
925
  };
923
926
  function scrollObserver(node, options = {}) {
924
927
  const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
925
928
  const opts = { ...defaultOptions2, ...userOpts };
926
- const { threshold, tolerance, throttle, once } = opts;
927
- const prevScrollDirection = null;
929
+ const { threshold, tolerance, once } = opts;
930
+ let prevScrollDirection = null;
928
931
  let prevScrollTop = 0;
929
932
  let prevScrollPercent = 0;
930
- let lastThrottleTime = 0;
931
933
  let thresholdFired = false;
932
934
  let rafId = null;
933
- const isDocumentScroll = node === document || node === window;
935
+ const isDocumentScroll = node === document || node === window || node === document.documentElement;
934
936
  const scrollElement = isDocumentScroll ? document.documentElement : node;
937
+ const eventTarget = isDocumentScroll ? window : node;
935
938
  let cachedScrollHeight = 0;
936
939
  let cachedClientHeight = 0;
937
940
  updateCache();
938
941
  const cacheObserver = resizeObserver(scrollElement, {
939
942
  callback: updateCache
940
943
  });
941
- node.addEventListener("scroll", throttledObserve, { passive: true });
944
+ eventTarget.addEventListener("scroll", throttledObserve, { passive: true });
945
+ function throttledObserve() {
946
+ rafId = requestAnimationFrame(observe);
947
+ }
942
948
  function updateCache() {
943
949
  cachedScrollHeight = scrollElement.scrollHeight;
944
950
  cachedClientHeight = scrollElement.clientHeight;
945
951
  }
946
- function throttledObserve() {
947
- const now = Date.now();
948
- if (now - lastThrottleTime < throttle) return;
949
- lastThrottleTime = now;
950
- rafId = requestAnimationFrame(observe);
951
- }
952
952
  function observe() {
953
953
  const scrollTop = scrollElement.scrollTop;
954
954
  if (Math.abs(scrollTop - prevScrollTop) < 1) return;
@@ -987,10 +987,11 @@ function scrollObserver(node, options = {}) {
987
987
  }
988
988
  prevScrollTop = scrollTop;
989
989
  prevScrollPercent = scrollPercent;
990
+ prevScrollDirection = scrollDirection;
990
991
  }
991
992
  return {
992
993
  destroy() {
993
- node.removeEventListener("scroll", throttledObserve);
994
+ eventTarget.removeEventListener("scroll", throttledObserve);
994
995
  if (rafId) cancelAnimationFrame(rafId);
995
996
  cacheObserver.destroy();
996
997
  }
@@ -1234,6 +1235,7 @@ function scrambleText(text) {
1234
1235
  rem,
1235
1236
  removeListeners,
1236
1237
  resizeObserver,
1238
+ rlh,
1237
1239
  sanitize,
1238
1240
  scrollObserver,
1239
1241
  scrollToElement,
@@ -156,40 +156,35 @@ var defaultOptions2 = {
156
156
  // Float between 0 to 1.
157
157
  tolerance: 0.1,
158
158
  // Float between 0 to 1. Tolerance for event firing
159
- throttle: 16,
160
- // Throttle interval in ms (default: ~60fps)
161
159
  once: false
162
160
  // Only fire threshold callback once
163
161
  };
164
162
  function scrollObserver(node, options = {}) {
165
163
  const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
166
164
  const opts = { ...defaultOptions2, ...userOpts };
167
- const { threshold, tolerance, throttle, once } = opts;
168
- const prevScrollDirection = null;
165
+ const { threshold, tolerance, once } = opts;
166
+ let prevScrollDirection = null;
169
167
  let prevScrollTop = 0;
170
168
  let prevScrollPercent = 0;
171
- let lastThrottleTime = 0;
172
169
  let thresholdFired = false;
173
170
  let rafId = null;
174
- const isDocumentScroll = node === document || node === window;
171
+ const isDocumentScroll = node === document || node === window || node === document.documentElement;
175
172
  const scrollElement = isDocumentScroll ? document.documentElement : node;
173
+ const eventTarget = isDocumentScroll ? window : node;
176
174
  let cachedScrollHeight = 0;
177
175
  let cachedClientHeight = 0;
178
176
  updateCache();
179
177
  const cacheObserver = resizeObserver(scrollElement, {
180
178
  callback: updateCache
181
179
  });
182
- node.addEventListener("scroll", throttledObserve, { passive: true });
180
+ eventTarget.addEventListener("scroll", throttledObserve, { passive: true });
181
+ function throttledObserve() {
182
+ rafId = requestAnimationFrame(observe);
183
+ }
183
184
  function updateCache() {
184
185
  cachedScrollHeight = scrollElement.scrollHeight;
185
186
  cachedClientHeight = scrollElement.clientHeight;
186
187
  }
187
- function throttledObserve() {
188
- const now = Date.now();
189
- if (now - lastThrottleTime < throttle) return;
190
- lastThrottleTime = now;
191
- rafId = requestAnimationFrame(observe);
192
- }
193
188
  function observe() {
194
189
  const scrollTop = scrollElement.scrollTop;
195
190
  if (Math.abs(scrollTop - prevScrollTop) < 1) return;
@@ -228,10 +223,11 @@ function scrollObserver(node, options = {}) {
228
223
  }
229
224
  prevScrollTop = scrollTop;
230
225
  prevScrollPercent = scrollPercent;
226
+ prevScrollDirection = scrollDirection;
231
227
  }
232
228
  return {
233
229
  destroy() {
234
- node.removeEventListener("scroll", throttledObserve);
230
+ eventTarget.removeEventListener("scroll", throttledObserve);
235
231
  if (rafId) cancelAnimationFrame(rafId);
236
232
  cacheObserver.destroy();
237
233
  }
@@ -83,40 +83,35 @@ var defaultOptions = {
83
83
  // Float between 0 to 1.
84
84
  tolerance: 0.1,
85
85
  // Float between 0 to 1. Tolerance for event firing
86
- throttle: 16,
87
- // Throttle interval in ms (default: ~60fps)
88
86
  once: false
89
87
  // Only fire threshold callback once
90
88
  };
91
89
  function scrollObserver(node, options = {}) {
92
90
  const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
93
91
  const opts = { ...defaultOptions, ...userOpts };
94
- const { threshold, tolerance, throttle, once } = opts;
95
- const prevScrollDirection = null;
92
+ const { threshold, tolerance, once } = opts;
93
+ let prevScrollDirection = null;
96
94
  let prevScrollTop = 0;
97
95
  let prevScrollPercent = 0;
98
- let lastThrottleTime = 0;
99
96
  let thresholdFired = false;
100
97
  let rafId = null;
101
- const isDocumentScroll = node === document || node === window;
98
+ const isDocumentScroll = node === document || node === window || node === document.documentElement;
102
99
  const scrollElement = isDocumentScroll ? document.documentElement : node;
100
+ const eventTarget = isDocumentScroll ? window : node;
103
101
  let cachedScrollHeight = 0;
104
102
  let cachedClientHeight = 0;
105
103
  updateCache();
106
104
  const cacheObserver = resizeObserver(scrollElement, {
107
105
  callback: updateCache
108
106
  });
109
- node.addEventListener("scroll", throttledObserve, { passive: true });
107
+ eventTarget.addEventListener("scroll", throttledObserve, { passive: true });
108
+ function throttledObserve() {
109
+ rafId = requestAnimationFrame(observe);
110
+ }
110
111
  function updateCache() {
111
112
  cachedScrollHeight = scrollElement.scrollHeight;
112
113
  cachedClientHeight = scrollElement.clientHeight;
113
114
  }
114
- function throttledObserve() {
115
- const now = Date.now();
116
- if (now - lastThrottleTime < throttle) return;
117
- lastThrottleTime = now;
118
- rafId = requestAnimationFrame(observe);
119
- }
120
115
  function observe() {
121
116
  const scrollTop = scrollElement.scrollTop;
122
117
  if (Math.abs(scrollTop - prevScrollTop) < 1) return;
@@ -155,10 +150,11 @@ function scrollObserver(node, options = {}) {
155
150
  }
156
151
  prevScrollTop = scrollTop;
157
152
  prevScrollPercent = scrollPercent;
153
+ prevScrollDirection = scrollDirection;
158
154
  }
159
155
  return {
160
156
  destroy() {
161
- node.removeEventListener("scroll", throttledObserve);
157
+ eventTarget.removeEventListener("scroll", throttledObserve);
162
158
  if (rafId) cancelAnimationFrame(rafId);
163
159
  cacheObserver.destroy();
164
160
  }
@@ -989,16 +989,23 @@ function parseSSE(message) {
989
989
  }
990
990
 
991
991
  // src/lib/strings/markdown.js
992
- var import_marked = require("marked");
993
- var import_marked_gfm_heading_id = require("marked-gfm-heading-id");
994
- var import_marked_mangle = require("marked-mangle");
992
+ var import_markdown_it = __toESM(require("markdown-it"), 1);
993
+ var import_markdown_it_anchor = __toESM(require("markdown-it-anchor"), 1);
994
+ var md = (0, import_markdown_it.default)({
995
+ html: true,
996
+ linkify: true,
997
+ typographer: true
998
+ });
999
+ md.use(import_markdown_it_anchor.default, {
1000
+ permalink: false,
1001
+ slugify: (s) => s.toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]/g, "")
1002
+ });
995
1003
  function markdown(content, options = {}) {
996
1004
  const defaultOptions = { inline: false };
997
1005
  const opts = { ...defaultOptions, ...options };
998
- import_marked.marked.use((0, import_marked_mangle.mangle)());
999
- import_marked.marked.use((0, import_marked_gfm_heading_id.gfmHeadingId)());
1000
1006
  const { content: treated } = treatMarkdownWhitespace(content, opts);
1001
- return import_marked.marked.parse(treated);
1007
+ if (opts.inline) return md.renderInline(treated);
1008
+ return md.render(treated);
1002
1009
  }
1003
1010
  function treatMarkdownWhitespace(content, { inline } = {}) {
1004
1011
  if (!content) return { content: "", inline };
@@ -104,16 +104,23 @@ function isDigit(char) {
104
104
  }
105
105
 
106
106
  // src/lib/strings/markdown.js
107
- var import_marked = require("marked");
108
- var import_marked_gfm_heading_id = require("marked-gfm-heading-id");
109
- var import_marked_mangle = require("marked-mangle");
107
+ var import_markdown_it = __toESM(require("markdown-it"), 1);
108
+ var import_markdown_it_anchor = __toESM(require("markdown-it-anchor"), 1);
109
+ var md = (0, import_markdown_it.default)({
110
+ html: true,
111
+ linkify: true,
112
+ typographer: true
113
+ });
114
+ md.use(import_markdown_it_anchor.default, {
115
+ permalink: false,
116
+ slugify: (s) => s.toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]/g, "")
117
+ });
110
118
  function markdown(content, options = {}) {
111
119
  const defaultOptions = { inline: false };
112
120
  const opts = { ...defaultOptions, ...options };
113
- import_marked.marked.use((0, import_marked_mangle.mangle)());
114
- import_marked.marked.use((0, import_marked_gfm_heading_id.gfmHeadingId)());
115
121
  const { content: treated } = treatMarkdownWhitespace(content, opts);
116
- return import_marked.marked.parse(treated);
122
+ if (opts.inline) return md.renderInline(treated);
123
+ return md.render(treated);
117
124
  }
118
125
  function treatMarkdownWhitespace(content, { inline } = {}) {
119
126
  if (!content) return { content: "", inline };
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __export = (target, all) => {
6
8
  for (var name in all)
@@ -14,6 +16,14 @@ var __copyProps = (to, from, except, desc) => {
14
16
  }
15
17
  return to;
16
18
  };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
17
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
28
 
19
29
  // src/lib/strings/markdown.js
@@ -23,16 +33,23 @@ __export(markdown_exports, {
23
33
  treatMarkdownWhitespace: () => treatMarkdownWhitespace
24
34
  });
25
35
  module.exports = __toCommonJS(markdown_exports);
26
- var import_marked = require("marked");
27
- var import_marked_gfm_heading_id = require("marked-gfm-heading-id");
28
- var import_marked_mangle = require("marked-mangle");
36
+ var import_markdown_it = __toESM(require("markdown-it"), 1);
37
+ var import_markdown_it_anchor = __toESM(require("markdown-it-anchor"), 1);
38
+ var md = (0, import_markdown_it.default)({
39
+ html: true,
40
+ linkify: true,
41
+ typographer: true
42
+ });
43
+ md.use(import_markdown_it_anchor.default, {
44
+ permalink: false,
45
+ slugify: (s) => s.toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]/g, "")
46
+ });
29
47
  function markdown(content, options = {}) {
30
48
  const defaultOptions = { inline: false };
31
49
  const opts = { ...defaultOptions, ...options };
32
- import_marked.marked.use((0, import_marked_mangle.mangle)());
33
- import_marked.marked.use((0, import_marked_gfm_heading_id.gfmHeadingId)());
34
50
  const { content: treated } = treatMarkdownWhitespace(content, opts);
35
- return import_marked.marked.parse(treated);
51
+ if (opts.inline) return md.renderInline(treated);
52
+ return md.render(treated);
36
53
  }
37
54
  function treatMarkdownWhitespace(content, { inline } = {}) {
38
55
  if (!content) return { content: "", inline };
@@ -12,13 +12,17 @@ function getUnit(value) {
12
12
  const [, unit] = splitUnit(value);
13
13
  return unit;
14
14
  }
15
+ function rem(multiple = 1) {
16
+ const value = parseFloat(getComputedStyle(document.body)["font-size"]);
17
+ return Math.round(value * multiple);
18
+ }
15
19
  function em(element = document.body, multiple = 1) {
16
20
  const value = parseFloat(getComputedStyle(element)["font-size"]);
17
21
  return Math.round(value * multiple);
18
22
  }
19
- function rem(multiple = 1) {
20
- const value = parseFloat(getComputedStyle(document.body)["font-size"]);
21
- return Math.round(value * multiple);
23
+ function rlh(multiple = 1) {
24
+ const lineHeight = parseFloat(getComputedStyle(document.body)["line-height"]);
25
+ return Math.round(lineHeight * multiple);
22
26
  }
23
27
  function lh(element = document.body, multiple = 1) {
24
28
  const lineHeight = getComputedStyle(element)["line-height"];
@@ -40,5 +44,6 @@ export {
40
44
  getUnit,
41
45
  lh,
42
46
  rem,
47
+ rlh,
43
48
  toPx
44
49
  };
@@ -640,13 +640,17 @@ function getUnit(value) {
640
640
  const [, unit] = splitUnit(value);
641
641
  return unit;
642
642
  }
643
+ function rem(multiple = 1) {
644
+ const value = parseFloat(getComputedStyle(document.body)["font-size"]);
645
+ return Math.round(value * multiple);
646
+ }
643
647
  function em(element = document.body, multiple = 1) {
644
648
  const value = parseFloat(getComputedStyle(element)["font-size"]);
645
649
  return Math.round(value * multiple);
646
650
  }
647
- function rem(multiple = 1) {
648
- const value = parseFloat(getComputedStyle(document.body)["font-size"]);
649
- return Math.round(value * multiple);
651
+ function rlh(multiple = 1) {
652
+ const lineHeight = parseFloat(getComputedStyle(document.body)["line-height"]);
653
+ return Math.round(lineHeight * multiple);
650
654
  }
651
655
  function lh(element = document.body, multiple = 1) {
652
656
  const lineHeight = getComputedStyle(element)["line-height"];
@@ -819,40 +823,35 @@ var defaultOptions2 = {
819
823
  // Float between 0 to 1.
820
824
  tolerance: 0.1,
821
825
  // Float between 0 to 1. Tolerance for event firing
822
- throttle: 16,
823
- // Throttle interval in ms (default: ~60fps)
824
826
  once: false
825
827
  // Only fire threshold callback once
826
828
  };
827
829
  function scrollObserver(node, options = {}) {
828
830
  const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
829
831
  const opts = { ...defaultOptions2, ...userOpts };
830
- const { threshold, tolerance, throttle, once } = opts;
831
- const prevScrollDirection = null;
832
+ const { threshold, tolerance, once } = opts;
833
+ let prevScrollDirection = null;
832
834
  let prevScrollTop = 0;
833
835
  let prevScrollPercent = 0;
834
- let lastThrottleTime = 0;
835
836
  let thresholdFired = false;
836
837
  let rafId = null;
837
- const isDocumentScroll = node === document || node === window;
838
+ const isDocumentScroll = node === document || node === window || node === document.documentElement;
838
839
  const scrollElement = isDocumentScroll ? document.documentElement : node;
840
+ const eventTarget = isDocumentScroll ? window : node;
839
841
  let cachedScrollHeight = 0;
840
842
  let cachedClientHeight = 0;
841
843
  updateCache();
842
844
  const cacheObserver = resizeObserver(scrollElement, {
843
845
  callback: updateCache
844
846
  });
845
- node.addEventListener("scroll", throttledObserve, { passive: true });
847
+ eventTarget.addEventListener("scroll", throttledObserve, { passive: true });
848
+ function throttledObserve() {
849
+ rafId = requestAnimationFrame(observe);
850
+ }
846
851
  function updateCache() {
847
852
  cachedScrollHeight = scrollElement.scrollHeight;
848
853
  cachedClientHeight = scrollElement.clientHeight;
849
854
  }
850
- function throttledObserve() {
851
- const now = Date.now();
852
- if (now - lastThrottleTime < throttle) return;
853
- lastThrottleTime = now;
854
- rafId = requestAnimationFrame(observe);
855
- }
856
855
  function observe() {
857
856
  const scrollTop = scrollElement.scrollTop;
858
857
  if (Math.abs(scrollTop - prevScrollTop) < 1) return;
@@ -891,10 +890,11 @@ function scrollObserver(node, options = {}) {
891
890
  }
892
891
  prevScrollTop = scrollTop;
893
892
  prevScrollPercent = scrollPercent;
893
+ prevScrollDirection = scrollDirection;
894
894
  }
895
895
  return {
896
896
  destroy() {
897
- node.removeEventListener("scroll", throttledObserve);
897
+ eventTarget.removeEventListener("scroll", throttledObserve);
898
898
  if (rafId) cancelAnimationFrame(rafId);
899
899
  cacheObserver.destroy();
900
900
  }
@@ -1137,6 +1137,7 @@ export {
1137
1137
  rem,
1138
1138
  removeListeners,
1139
1139
  resizeObserver,
1140
+ rlh,
1140
1141
  sanitize2 as sanitize,
1141
1142
  scrollObserver,
1142
1143
  scrollToElement,
@@ -128,40 +128,35 @@ var defaultOptions2 = {
128
128
  // Float between 0 to 1.
129
129
  tolerance: 0.1,
130
130
  // Float between 0 to 1. Tolerance for event firing
131
- throttle: 16,
132
- // Throttle interval in ms (default: ~60fps)
133
131
  once: false
134
132
  // Only fire threshold callback once
135
133
  };
136
134
  function scrollObserver(node, options = {}) {
137
135
  const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
138
136
  const opts = { ...defaultOptions2, ...userOpts };
139
- const { threshold, tolerance, throttle, once } = opts;
140
- const prevScrollDirection = null;
137
+ const { threshold, tolerance, once } = opts;
138
+ let prevScrollDirection = null;
141
139
  let prevScrollTop = 0;
142
140
  let prevScrollPercent = 0;
143
- let lastThrottleTime = 0;
144
141
  let thresholdFired = false;
145
142
  let rafId = null;
146
- const isDocumentScroll = node === document || node === window;
143
+ const isDocumentScroll = node === document || node === window || node === document.documentElement;
147
144
  const scrollElement = isDocumentScroll ? document.documentElement : node;
145
+ const eventTarget = isDocumentScroll ? window : node;
148
146
  let cachedScrollHeight = 0;
149
147
  let cachedClientHeight = 0;
150
148
  updateCache();
151
149
  const cacheObserver = resizeObserver(scrollElement, {
152
150
  callback: updateCache
153
151
  });
154
- node.addEventListener("scroll", throttledObserve, { passive: true });
152
+ eventTarget.addEventListener("scroll", throttledObserve, { passive: true });
153
+ function throttledObserve() {
154
+ rafId = requestAnimationFrame(observe);
155
+ }
155
156
  function updateCache() {
156
157
  cachedScrollHeight = scrollElement.scrollHeight;
157
158
  cachedClientHeight = scrollElement.clientHeight;
158
159
  }
159
- function throttledObserve() {
160
- const now = Date.now();
161
- if (now - lastThrottleTime < throttle) return;
162
- lastThrottleTime = now;
163
- rafId = requestAnimationFrame(observe);
164
- }
165
160
  function observe() {
166
161
  const scrollTop = scrollElement.scrollTop;
167
162
  if (Math.abs(scrollTop - prevScrollTop) < 1) return;
@@ -200,10 +195,11 @@ function scrollObserver(node, options = {}) {
200
195
  }
201
196
  prevScrollTop = scrollTop;
202
197
  prevScrollPercent = scrollPercent;
198
+ prevScrollDirection = scrollDirection;
203
199
  }
204
200
  return {
205
201
  destroy() {
206
- node.removeEventListener("scroll", throttledObserve);
202
+ eventTarget.removeEventListener("scroll", throttledObserve);
207
203
  if (rafId) cancelAnimationFrame(rafId);
208
204
  cacheObserver.destroy();
209
205
  }
@@ -58,40 +58,35 @@ var defaultOptions = {
58
58
  // Float between 0 to 1.
59
59
  tolerance: 0.1,
60
60
  // Float between 0 to 1. Tolerance for event firing
61
- throttle: 16,
62
- // Throttle interval in ms (default: ~60fps)
63
61
  once: false
64
62
  // Only fire threshold callback once
65
63
  };
66
64
  function scrollObserver(node, options = {}) {
67
65
  const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } = options;
68
66
  const opts = { ...defaultOptions, ...userOpts };
69
- const { threshold, tolerance, throttle, once } = opts;
70
- const prevScrollDirection = null;
67
+ const { threshold, tolerance, once } = opts;
68
+ let prevScrollDirection = null;
71
69
  let prevScrollTop = 0;
72
70
  let prevScrollPercent = 0;
73
- let lastThrottleTime = 0;
74
71
  let thresholdFired = false;
75
72
  let rafId = null;
76
- const isDocumentScroll = node === document || node === window;
73
+ const isDocumentScroll = node === document || node === window || node === document.documentElement;
77
74
  const scrollElement = isDocumentScroll ? document.documentElement : node;
75
+ const eventTarget = isDocumentScroll ? window : node;
78
76
  let cachedScrollHeight = 0;
79
77
  let cachedClientHeight = 0;
80
78
  updateCache();
81
79
  const cacheObserver = resizeObserver(scrollElement, {
82
80
  callback: updateCache
83
81
  });
84
- node.addEventListener("scroll", throttledObserve, { passive: true });
82
+ eventTarget.addEventListener("scroll", throttledObserve, { passive: true });
83
+ function throttledObserve() {
84
+ rafId = requestAnimationFrame(observe);
85
+ }
85
86
  function updateCache() {
86
87
  cachedScrollHeight = scrollElement.scrollHeight;
87
88
  cachedClientHeight = scrollElement.clientHeight;
88
89
  }
89
- function throttledObserve() {
90
- const now = Date.now();
91
- if (now - lastThrottleTime < throttle) return;
92
- lastThrottleTime = now;
93
- rafId = requestAnimationFrame(observe);
94
- }
95
90
  function observe() {
96
91
  const scrollTop = scrollElement.scrollTop;
97
92
  if (Math.abs(scrollTop - prevScrollTop) < 1) return;
@@ -130,10 +125,11 @@ function scrollObserver(node, options = {}) {
130
125
  }
131
126
  prevScrollTop = scrollTop;
132
127
  prevScrollPercent = scrollPercent;
128
+ prevScrollDirection = scrollDirection;
133
129
  }
134
130
  return {
135
131
  destroy() {
136
- node.removeEventListener("scroll", throttledObserve);
132
+ eventTarget.removeEventListener("scroll", throttledObserve);
137
133
  if (rafId) cancelAnimationFrame(rafId);
138
134
  cacheObserver.destroy();
139
135
  }
@@ -869,16 +869,23 @@ function parseSSE(message) {
869
869
  }
870
870
 
871
871
  // src/lib/strings/markdown.js
872
- import { marked } from "marked";
873
- import { gfmHeadingId } from "marked-gfm-heading-id";
874
- import { mangle } from "marked-mangle";
872
+ import markdownit from "markdown-it";
873
+ import anchor from "markdown-it-anchor";
874
+ var md = markdownit({
875
+ html: true,
876
+ linkify: true,
877
+ typographer: true
878
+ });
879
+ md.use(anchor, {
880
+ permalink: false,
881
+ slugify: (s) => s.toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]/g, "")
882
+ });
875
883
  function markdown(content, options = {}) {
876
884
  const defaultOptions = { inline: false };
877
885
  const opts = { ...defaultOptions, ...options };
878
- marked.use(mangle());
879
- marked.use(gfmHeadingId());
880
886
  const { content: treated } = treatMarkdownWhitespace(content, opts);
881
- return marked.parse(treated);
887
+ if (opts.inline) return md.renderInline(treated);
888
+ return md.render(treated);
882
889
  }
883
890
  function treatMarkdownWhitespace(content, { inline } = {}) {
884
891
  if (!content) return { content: "", inline };
@@ -55,16 +55,23 @@ function isDigit(char) {
55
55
  }
56
56
 
57
57
  // src/lib/strings/markdown.js
58
- import { marked } from "marked";
59
- import { gfmHeadingId } from "marked-gfm-heading-id";
60
- import { mangle } from "marked-mangle";
58
+ import markdownit from "markdown-it";
59
+ import anchor from "markdown-it-anchor";
60
+ var md = markdownit({
61
+ html: true,
62
+ linkify: true,
63
+ typographer: true
64
+ });
65
+ md.use(anchor, {
66
+ permalink: false,
67
+ slugify: (s) => s.toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]/g, "")
68
+ });
61
69
  function markdown(content, options = {}) {
62
70
  const defaultOptions = { inline: false };
63
71
  const opts = { ...defaultOptions, ...options };
64
- marked.use(mangle());
65
- marked.use(gfmHeadingId());
66
72
  const { content: treated } = treatMarkdownWhitespace(content, opts);
67
- return marked.parse(treated);
73
+ if (opts.inline) return md.renderInline(treated);
74
+ return md.render(treated);
68
75
  }
69
76
  function treatMarkdownWhitespace(content, { inline } = {}) {
70
77
  if (!content) return { content: "", inline };
@@ -1,14 +1,21 @@
1
1
  // src/lib/strings/markdown.js
2
- import { marked } from "marked";
3
- import { gfmHeadingId } from "marked-gfm-heading-id";
4
- import { mangle } from "marked-mangle";
2
+ import markdownit from "markdown-it";
3
+ import anchor from "markdown-it-anchor";
4
+ var md = markdownit({
5
+ html: true,
6
+ linkify: true,
7
+ typographer: true
8
+ });
9
+ md.use(anchor, {
10
+ permalink: false,
11
+ slugify: (s) => s.toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]/g, "")
12
+ });
5
13
  function markdown(content, options = {}) {
6
14
  const defaultOptions = { inline: false };
7
15
  const opts = { ...defaultOptions, ...options };
8
- marked.use(mangle());
9
- marked.use(gfmHeadingId());
10
16
  const { content: treated } = treatMarkdownWhitespace(content, opts);
11
- return marked.parse(treated);
17
+ if (opts.inline) return md.renderInline(treated);
18
+ return md.render(treated);
12
19
  }
13
20
  function treatMarkdownWhitespace(content, { inline } = {}) {
14
21
  if (!content) return { content: "", inline };
@@ -1,7 +1,8 @@
1
1
  declare function getUnit(value: any): any;
2
- declare function em(element?: HTMLElement, multiple?: number): number;
3
2
  declare function rem(multiple?: number): number;
3
+ declare function em(element?: HTMLElement, multiple?: number): number;
4
+ declare function rlh(multiple?: number): number;
4
5
  declare function lh(element?: HTMLElement, multiple?: number): number;
5
6
  declare function toPx(value: any, element?: any): number;
6
7
 
7
- export { em, getUnit, lh, rem, toPx };
8
+ export { em, getUnit, lh, rem, rlh, toPx };
@@ -8,7 +8,7 @@ export { cookies, getCookie } from './cookie.cjs';
8
8
  export { getCSSValue, getCSSVar, setCSSValue, setCSSVar } from './css-vars.cjs';
9
9
  export { CustomEventOptions, EventListener, ListenerManager, addListeners, dispatchEvent, removeListeners, updateEvent } from './events.cjs';
10
10
  export { Focusable, Focusables, getFocusableElements } from './focusable.cjs';
11
- export { em, getUnit, lh, rem, toPx } from './font-size.cjs';
11
+ export { em, getUnit, lh, rem, rlh, toPx } from './font-size.cjs';
12
12
  export { getAncestorWithSiblings, getChildrenElements, getElement, getNodeType, getParentElement, getSelfIndex, getSiblingElements, isAncestor } from './get-element.cjs';
13
13
  export { sha256Hash } from './hash.cjs';
14
14
  export { isArrowKey, isEscapeKey, isShiftTab, isTab, isTabKey } from './keyboard.cjs';
@@ -17,7 +17,7 @@ export { imagesLoaded, mediaLoaded, videosLoaded } from './media.cjs';
17
17
  export { intersectionObserver } from './observers/intersection-observer.cjs';
18
18
  export { mutationObserver } from './observers/mutation-observer.cjs';
19
19
  export { resizeObserver } from './observers/resize-observer.cjs';
20
- export { scrollObserver } from './observers/scroll-observer.cjs';
20
+ export { ScrollObserverOptions, scrollObserver } from './observers/scroll-observer.cjs';
21
21
  export { PKCE } from './pkce.cjs';
22
22
  export { queryParams } from './query-params.cjs';
23
23
  export { randomString, uuid } from './random-string.cjs';
@@ -1,4 +1,4 @@
1
1
  export { intersectionObserver } from './intersection-observer.cjs';
2
2
  export { mutationObserver } from './mutation-observer.cjs';
3
3
  export { resizeObserver } from './resize-observer.cjs';
4
- export { scrollObserver } from './scroll-observer.cjs';
4
+ export { ScrollObserverOptions, scrollObserver } from './scroll-observer.cjs';
@@ -1,27 +1,50 @@
1
+ /**
2
+ * @typedef {Object} ScrollObserverOptions
3
+ * @property {number} [threshold] - Float between 0 to 1. When to trigger callback (0.75 = 75% down page)
4
+ * @property {number} [tolerance] - Float between 0 to 1. Tolerance zone around threshold
5
+ * @property {boolean} [once] - Only fire threshold callback once (default: false)
6
+ * @property {Function} [callback] - Called on every scroll with scrollPercent
7
+ * @property {Function} [onScrollDown] - Called when scrolling down
8
+ * @property {Function} [onScrollUp] - Called when scrolling up
9
+ * @property {Function} [onEnterThreshold] - Called when entering threshold zone
10
+ */
1
11
  /**
2
12
  * Scroll Observer - Optimized for performance
3
13
  * @param {Element} node - The element to observe scroll events on
4
- * @param {Object} options - Configuration options
5
- * @param {Number} options.threshold - Float between 0 to 1. When to trigger callback (0.75 = 75% down page)
6
- * @param {Number} options.tolerance - Float between 0 to 1. Tolerance zone around threshold
7
- * @param {Number} options.throttle - Throttle interval in ms (default: 16ms for ~60fps)
8
- * @param {Boolean} options.once - Only fire threshold callback once (default: false)
9
- * @param {Function} options.callback - Called on every scroll with scrollPercent
10
- * @param {Function} options.onScrollDown - Called when scrolling down
11
- * @param {Function} options.onScrollUp - Called when scrolling up
12
- * @param {Function} options.onEnterThreshold - Called when entering threshold zone
14
+ * @param {ScrollObserverOptions} [options] - Configuration options
13
15
  */
14
- declare function scrollObserver(node: Element, options?: {
15
- threshold: number;
16
- tolerance: number;
17
- throttle: number;
18
- once: boolean;
19
- callback: Function;
20
- onScrollDown: Function;
21
- onScrollUp: Function;
22
- onEnterThreshold: Function;
23
- }): {
16
+ declare function scrollObserver(node: Element, options?: ScrollObserverOptions): {
24
17
  destroy(): void;
25
18
  };
19
+ type ScrollObserverOptions = {
20
+ /**
21
+ * - Float between 0 to 1. When to trigger callback (0.75 = 75% down page)
22
+ */
23
+ threshold?: number;
24
+ /**
25
+ * - Float between 0 to 1. Tolerance zone around threshold
26
+ */
27
+ tolerance?: number;
28
+ /**
29
+ * - Only fire threshold callback once (default: false)
30
+ */
31
+ once?: boolean;
32
+ /**
33
+ * - Called on every scroll with scrollPercent
34
+ */
35
+ callback?: Function;
36
+ /**
37
+ * - Called when scrolling down
38
+ */
39
+ onScrollDown?: Function;
40
+ /**
41
+ * - Called when scrolling up
42
+ */
43
+ onScrollUp?: Function;
44
+ /**
45
+ * - Called when entering threshold zone
46
+ */
47
+ onEnterThreshold?: Function;
48
+ };
26
49
 
27
- export { scrollObserver };
50
+ export { type ScrollObserverOptions, scrollObserver };
@@ -3,11 +3,11 @@
3
3
  * @param {string} content - Markdown content to convert
4
4
  * @param {Object} [options={}] - Conversion options
5
5
  * @param {boolean} [options.inline=false] - Whether content should be treated as inline markdown
6
- * @returns {string|Promise<string>} HTML string or Promise that resolves to HTML string
6
+ * @returns {string} Converted HTML string
7
7
  */
8
8
  declare function markdown(content: string, options?: {
9
9
  inline?: boolean;
10
- }): string | Promise<string>;
10
+ }): string;
11
11
  /**
12
12
  * Handles whitespace in markdown content to ensure proper rendering
13
13
  * @param {string} content - Markdown content to process
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splendidlabz/utils",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -54,6 +54,8 @@
54
54
  "deep-eql": "^5.0.2",
55
55
  "dompurify": "^3.2.4",
56
56
  "glob": "^11.0.0",
57
+ "markdown-it": "^14.1.0",
58
+ "markdown-it-anchor": "^9.2.0",
57
59
  "marked": "^15.0.7",
58
60
  "marked-gfm-heading-id": "^4.1.1",
59
61
  "marked-mangle": "^1.1.10",
@@ -5,14 +5,19 @@ export function getUnit(value) {
5
5
  return unit
6
6
  }
7
7
 
8
+ export function rem(multiple = 1) {
9
+ const value = parseFloat(getComputedStyle(document.body)['font-size'])
10
+ return Math.round(value * multiple)
11
+ }
12
+
8
13
  export function em(element = document.body, multiple = 1) {
9
14
  const value = parseFloat(getComputedStyle(element)['font-size'])
10
15
  return Math.round(value * multiple)
11
16
  }
12
17
 
13
- export function rem(multiple = 1) {
14
- const value = parseFloat(getComputedStyle(document.body)['font-size'])
15
- return Math.round(value * multiple)
18
+ export function rlh(multiple = 1) {
19
+ const lineHeight = parseFloat(getComputedStyle(document.body)['line-height'])
20
+ return Math.round(lineHeight * multiple)
16
21
  }
17
22
 
18
23
  export function lh(element = document.body, multiple = 1) {
@@ -4,40 +4,42 @@ import { resizeObserver } from './resize-observer.js'
4
4
  const defaultOptions = {
5
5
  threshold: 0, // Float between 0 to 1.
6
6
  tolerance: 0.1, // Float between 0 to 1. Tolerance for event firing
7
- throttle: 16, // Throttle interval in ms (default: ~60fps)
8
7
  once: false, // Only fire threshold callback once
9
8
  }
10
9
 
11
- // TODO: Move to Utils/Dom
10
+ /**
11
+ * @typedef {Object} ScrollObserverOptions
12
+ * @property {number} [threshold] - Float between 0 to 1. When to trigger callback (0.75 = 75% down page)
13
+ * @property {number} [tolerance] - Float between 0 to 1. Tolerance zone around threshold
14
+ * @property {boolean} [once] - Only fire threshold callback once (default: false)
15
+ * @property {Function} [callback] - Called on every scroll with scrollPercent
16
+ * @property {Function} [onScrollDown] - Called when scrolling down
17
+ * @property {Function} [onScrollUp] - Called when scrolling up
18
+ * @property {Function} [onEnterThreshold] - Called when entering threshold zone
19
+ */
20
+
12
21
  /**
13
22
  * Scroll Observer - Optimized for performance
14
23
  * @param {Element} node - The element to observe scroll events on
15
- * @param {Object} options - Configuration options
16
- * @param {Number} options.threshold - Float between 0 to 1. When to trigger callback (0.75 = 75% down page)
17
- * @param {Number} options.tolerance - Float between 0 to 1. Tolerance zone around threshold
18
- * @param {Number} options.throttle - Throttle interval in ms (default: 16ms for ~60fps)
19
- * @param {Boolean} options.once - Only fire threshold callback once (default: false)
20
- * @param {Function} options.callback - Called on every scroll with scrollPercent
21
- * @param {Function} options.onScrollDown - Called when scrolling down
22
- * @param {Function} options.onScrollUp - Called when scrolling up
23
- * @param {Function} options.onEnterThreshold - Called when entering threshold zone
24
+ * @param {ScrollObserverOptions} [options] - Configuration options
24
25
  */
25
26
  export function scrollObserver(node, options = {}) {
26
27
  const { callback, onScrollDown, onScrollUp, onEnterThreshold, ...userOpts } =
27
28
  options
28
29
  const opts = { ...defaultOptions, ...userOpts }
29
- const { threshold, tolerance, throttle, once } = opts
30
+ const { threshold, tolerance, once } = opts
30
31
 
31
- const prevScrollDirection = null
32
+ let prevScrollDirection = null
32
33
  let prevScrollTop = 0
33
34
  let prevScrollPercent = 0
34
- let lastThrottleTime = 0
35
35
  let thresholdFired = false
36
36
  let rafId = null
37
37
 
38
38
  // Determine scroll context once at initialization
39
- const isDocumentScroll = node === document || node === window
39
+ const isDocumentScroll =
40
+ node === document || node === window || node === document.documentElement
40
41
  const scrollElement = isDocumentScroll ? document.documentElement : node
42
+ const eventTarget = isDocumentScroll ? window : node
41
43
 
42
44
  // Cache DOM references and expensive calculations
43
45
  let cachedScrollHeight = 0
@@ -49,21 +51,17 @@ export function scrollObserver(node, options = {}) {
49
51
  callback: updateCache,
50
52
  })
51
53
 
52
- node.addEventListener('scroll', throttledObserve, { passive: true })
54
+ eventTarget.addEventListener('scroll', throttledObserve, { passive: true })
55
+
56
+ function throttledObserve() {
57
+ rafId = requestAnimationFrame(observe)
58
+ }
53
59
 
54
60
  function updateCache() {
55
61
  cachedScrollHeight = scrollElement.scrollHeight
56
62
  cachedClientHeight = scrollElement.clientHeight
57
63
  }
58
64
 
59
- function throttledObserve() {
60
- const now = Date.now()
61
- if (now - lastThrottleTime < throttle) return
62
-
63
- lastThrottleTime = now
64
- rafId = requestAnimationFrame(observe)
65
- }
66
-
67
65
  function observe() {
68
66
  const scrollTop = scrollElement.scrollTop
69
67
 
@@ -120,11 +118,12 @@ export function scrollObserver(node, options = {}) {
120
118
 
121
119
  prevScrollTop = scrollTop
122
120
  prevScrollPercent = scrollPercent
121
+ prevScrollDirection = scrollDirection
123
122
  }
124
123
 
125
124
  return {
126
125
  destroy() {
127
- node.removeEventListener('scroll', throttledObserve)
126
+ eventTarget.removeEventListener('scroll', throttledObserve)
128
127
  if (rafId) cancelAnimationFrame(rafId)
129
128
  cacheObserver.destroy()
130
129
  },
@@ -1,24 +1,36 @@
1
- import { marked } from 'marked'
2
- import { gfmHeadingId } from 'marked-gfm-heading-id'
3
- import { mangle } from 'marked-mangle'
1
+ import markdownit from 'markdown-it'
2
+ import anchor from 'markdown-it-anchor'
3
+
4
+ const md = markdownit({
5
+ html: true,
6
+ linkify: true,
7
+ typographer: true,
8
+ })
9
+
10
+ md.use(anchor, {
11
+ permalink: false,
12
+ slugify: s =>
13
+ s
14
+ .toLowerCase()
15
+ .replace(/\s+/g, '-')
16
+ .replace(/[^\w-]/g, ''),
17
+ })
4
18
 
5
19
  /**
6
20
  * Converts markdown content to HTML with whitespace handling
7
21
  * @param {string} content - Markdown content to convert
8
22
  * @param {Object} [options={}] - Conversion options
9
23
  * @param {boolean} [options.inline=false] - Whether content should be treated as inline markdown
10
- * @returns {string|Promise<string>} HTML string or Promise that resolves to HTML string
24
+ * @returns {string} Converted HTML string
11
25
  */
12
26
  export function markdown(content, options = {}) {
13
27
  const defaultOptions = { inline: false }
14
28
  const opts = { ...defaultOptions, ...options }
15
29
 
16
- // Prepare Marked
17
- marked.use(mangle())
18
- marked.use(gfmHeadingId())
19
-
20
30
  const { content: treated } = treatMarkdownWhitespace(content, opts)
21
- return marked.parse(treated)
31
+
32
+ if (opts.inline) return md.renderInline(treated)
33
+ return md.render(treated)
22
34
  }
23
35
 
24
36
  /**