ngx-astro-highlighter 1.0.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.
Files changed (2) hide show
  1. package/package.json +32 -0
  2. package/src/Highlighter.astro +129 -0
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "ngx-astro-highlighter",
3
+ "version": "1.0.0",
4
+ "description": "Text highlighter effect for Astro. Port of @omnedia/ngx-highlighter without Angular runtime.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "exports": {
8
+ ".": "./src/Highlighter.astro",
9
+ "./Highlighter.astro": "./src/Highlighter.astro"
10
+ },
11
+ "files": [
12
+ "src"
13
+ ],
14
+ "dependencies": {
15
+ "rough-notation": "^0.5.1"
16
+ },
17
+ "peerDependencies": {
18
+ "astro": ">=5.0.0"
19
+ },
20
+ "keywords": [
21
+ "astro",
22
+ "astro-component",
23
+ "highlighter",
24
+ "rough-notation",
25
+ "effect",
26
+ "annotation"
27
+ ],
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/whitedotjsx/ngx-ui-to-astro.git"
31
+ }
32
+ }
@@ -0,0 +1,129 @@
1
+ ---
2
+ type AnnotationAction =
3
+ | 'highlight'
4
+ | 'underline'
5
+ | 'box'
6
+ | 'circle'
7
+ | 'strike-through'
8
+ | 'crossed-off'
9
+ | 'bracket';
10
+
11
+ type BracketType = 'left' | 'right' | 'top' | 'bottom';
12
+
13
+ interface Props {
14
+ action?: AnnotationAction;
15
+ color?: string;
16
+ strokeWidth?: number;
17
+ animationDuration?: number;
18
+ iterations?: number;
19
+ padding?: number;
20
+ multiline?: boolean;
21
+ animateOnlyOnce?: boolean;
22
+ brackets?: BracketType | BracketType[];
23
+ animate?: boolean;
24
+ class?: string;
25
+ }
26
+
27
+ const {
28
+ action = 'highlight',
29
+ color = '#d1daff',
30
+ strokeWidth = 1.5,
31
+ animationDuration = 600,
32
+ iterations = 2,
33
+ padding = 2,
34
+ multiline = true,
35
+ animateOnlyOnce = false,
36
+ brackets = ['left', 'right'],
37
+ animate = true,
38
+ class: className = '',
39
+ } = Astro.props;
40
+
41
+ const options = JSON.stringify({
42
+ action,
43
+ color,
44
+ strokeWidth,
45
+ animationDuration,
46
+ iterations,
47
+ padding,
48
+ multiline,
49
+ brackets,
50
+ animateOnlyOnce,
51
+ animate,
52
+ });
53
+ ---
54
+
55
+ <span
56
+ class:list={['om-highlighter', className]}
57
+ data-om-highlighter
58
+ data-options={options}
59
+ ><slot /></span>
60
+
61
+ <style>
62
+ .om-highlighter {
63
+ position: relative;
64
+ display: inline-block;
65
+ background-color: transparent;
66
+ }
67
+ </style>
68
+
69
+ <script>
70
+ import { annotate } from 'rough-notation';
71
+
72
+ (() => {
73
+ const wrappers = document.querySelectorAll<HTMLElement>('[data-om-highlighter]');
74
+ if (!wrappers.length) return;
75
+
76
+ wrappers.forEach((wrapper) => {
77
+ const options = JSON.parse(wrapper.dataset.options!);
78
+
79
+ let animatedOnce = false;
80
+ let isInView = false;
81
+
82
+ let annotation = annotate(wrapper, {
83
+ type: options.action,
84
+ color: options.color,
85
+ strokeWidth: options.strokeWidth,
86
+ animationDuration: options.animationDuration,
87
+ iterations: options.iterations,
88
+ padding: options.padding,
89
+ multiline: options.multiline,
90
+ brackets: options.brackets,
91
+ animate: options.animate,
92
+ });
93
+
94
+ function recreate(): void {
95
+ annotation.remove();
96
+ annotation = annotate(wrapper, {
97
+ type: options.action,
98
+ color: options.color,
99
+ strokeWidth: options.strokeWidth,
100
+ animationDuration: options.animationDuration,
101
+ iterations: options.iterations,
102
+ padding: options.padding,
103
+ multiline: options.multiline,
104
+ brackets: options.brackets,
105
+ animate: options.animate,
106
+ });
107
+ if (isInView) annotation.show();
108
+ }
109
+
110
+ const observer = new IntersectionObserver(([entry]) => {
111
+ isInView = entry.isIntersecting;
112
+ if (entry.isIntersecting && (!options.animateOnlyOnce || (options.animateOnlyOnce && !animatedOnce))) {
113
+ annotation.show();
114
+ animatedOnce = true;
115
+ } else if (!options.animateOnlyOnce) {
116
+ annotation.hide();
117
+ }
118
+ });
119
+ observer.observe(wrapper);
120
+
121
+ const attrObserver = new MutationObserver(() => {
122
+ const next = JSON.parse(wrapper.dataset.options!);
123
+ Object.assign(options, next);
124
+ recreate();
125
+ });
126
+ attrObserver.observe(wrapper, { attributes: true, attributeFilter: ['data-options'] });
127
+ });
128
+ })();
129
+ </script>