rte-utils 1.2.0 → 1.2.1

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
@@ -23,19 +23,25 @@ import 'rte-utils/dist/index.css'; // Import the CSS styles
23
23
 
24
24
  ```tsx
25
25
  import React from 'react';
26
- import { Histogramme } from 'rte-utils';
26
+ import { Histogram } from 'rte-utils';
27
27
  import 'rte-utils/dist/index.css';
28
28
 
29
29
  function App() {
30
30
  return (
31
31
  <div>
32
- <Histogramme
32
+ <Histogram
33
33
  max={{ value: 100, color: "#D3D64E" }}
34
34
  relative={{ value: 56, color: "#C0C402" }}
35
- value={56}
36
- unit="MWh"
37
- label="Soutirage"
38
- />
35
+ barWidth={32}
36
+ >
37
+ <div className="histogram-value-container">
38
+ <p className="histogram-value">56</p>
39
+ <p className="histogram-unit">MWh</p>
40
+ </div>
41
+ <div>
42
+ <p className="histogram-label">Soutirage</p>
43
+ </div>
44
+ </Histogram>
39
45
  </div>
40
46
  );
41
47
  }
@@ -47,7 +53,7 @@ export default App;
47
53
 
48
54
  ```tsx
49
55
  import React, { useState } from 'react';
50
- import { Histogramme } from 'rte-utils';
56
+ import { Histogram } from 'rte-utils';
51
57
  import 'rte-utils/dist/index.css';
52
58
 
53
59
  function EnergyDashboard() {
@@ -55,16 +61,20 @@ function EnergyDashboard() {
55
61
 
56
62
  return (
57
63
  <div style={{ display: 'flex', gap: '1rem' }}>
58
- <Histogramme
64
+ <Histogram
59
65
  max={{ value: 100, color: "#D3D64E" }}
60
66
  relative={{ value: currentValue, color: "#C0C402" }}
61
- value={currentValue}
62
- unit="MWh"
63
- label="Consommation"
64
- backgroundColor="#0066cc"
65
67
  barHeight={120}
66
- width={60}
67
- />
68
+ barWidth={40}
69
+ >
70
+ <div className="histogram-value-container">
71
+ <p className="histogram-value">{currentValue}</p>
72
+ <p className="histogram-unit">MWh</p>
73
+ </div>
74
+ <div>
75
+ <p className="histogram-label">Consommation</p>
76
+ </div>
77
+ </Histogram>
68
78
 
69
79
  <button onClick={() => setCurrentValue(prev => prev + 10)}>
70
80
  Increase (+10)
@@ -76,7 +86,7 @@ function EnergyDashboard() {
76
86
 
77
87
  ## Components
78
88
 
79
- ### Histogramme
89
+ ### Histogram
80
90
 
81
91
  A histogram component with smooth animations for energy data visualization.
82
92
 
@@ -86,12 +96,9 @@ A histogram component with smooth animations for energy data visualization.
86
96
  |------|------|----------|---------|-------------|
87
97
  | `max` | `{ value: number; color: string }` | ✅ | - | Maximum value configuration with value and color |
88
98
  | `relative` | `{ value: number; color: string }` | ✅ | - | Relative/current value configuration with value and color |
89
- | `value` | `number` | ✅ | - | Value to display in text |
90
- | `unit` | `string` | ✅ | - | Unit label (e.g., "MWh") |
91
- | `label` | `string` | ✅ | - | Description label (e.g., "Soutirage") |
92
- | `backgroundColor` | `string` | ❌ | `#005896` | Background color of the container |
93
99
  | `barHeight` | `number` | ❌ | `103` | Height of the histogram bar in pixels |
94
- | `width` | `number` | ❌ | `54` | Width of the component in pixels |
100
+ | `barWidth` | `number` | ❌ | `32` | Width of the histogram bar in pixels |
101
+ | `children` | `React.ReactNode` | ❌ | - | Child components (typically text content) |
95
102
 
96
103
  #### Features
97
104
 
@@ -113,15 +120,15 @@ import 'rte-utils/dist/index.css';
113
120
 
114
121
  You can override the default styles by targeting the CSS classes:
115
122
 
116
- - `.histogramme-container`
117
- - `.histogramme-content`
118
- - `.histogramme-bar`
119
- - `.histogramme-svg`
120
- - `.histogramme-text-container`
121
- - `.histogramme-value-container`
122
- - `.histogramme-value`
123
- - `.histogramme-unit`
124
- - `.histogramme-label`
123
+ - `.histogram-container`
124
+ - `.histogram-content`
125
+ - `.histogram-bar`
126
+ - `.histogram-svg`
127
+ - `.histogram-text-container`
128
+ - `.histogram-value-container`
129
+ - `.histogram-value`
130
+ - `.histogram-unit`
131
+ - `.histogram-label`
125
132
 
126
133
  ## License
127
134
 
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import "./Histogram.css";
3
+ interface HistogramProps {
4
+ /** Maximum value configuration with value and color */
5
+ max: {
6
+ value: number;
7
+ color: string;
8
+ };
9
+ /** Relative/current value configuration with value and color */
10
+ relative: {
11
+ value: number;
12
+ color: string;
13
+ };
14
+ /** Height of the histogram bar in pixels */
15
+ barHeight?: number;
16
+ /** Width of the histogram bar in pixels */
17
+ barWidth?: number;
18
+ /** Child components (typically text content) */
19
+ children?: React.ReactNode;
20
+ }
21
+ export declare const Histogram: React.FC<HistogramProps>;
22
+ export {};
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import "./Histogramme.css";
3
- interface HistogrammeProps {
3
+ interface HistogramProps {
4
4
  /** Maximum value configuration with value and color */
5
5
  max: {
6
6
  value: number;
@@ -11,16 +11,12 @@ interface HistogrammeProps {
11
11
  value: number;
12
12
  color: string;
13
13
  };
14
- /** Value to display in text */
15
- value: number;
16
- /** Unit label (e.g., "MWh") */
17
- unit: string;
18
- /** Description label (e.g., "Soutirage") */
19
- label: string;
20
- /** Background color of the container */
21
- backgroundColor?: string;
22
14
  /** Height of the histogram bar in pixels */
23
15
  barHeight?: number;
16
+ /** Width of the histogram bar in pixels */
17
+ barWidth?: number;
18
+ /** Child components (typically text content) */
19
+ children?: React.ReactNode;
24
20
  }
25
- export declare const Histogramme: React.FC<HistogrammeProps>;
21
+ export declare const Histogram: React.FC<HistogramProps>;
26
22
  export {};
@@ -1 +1 @@
1
- export { Histogramme } from './Histogramme';
1
+ export { Histogram } from './Histogram';
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogramme-container{border:3px solid #2c2f33;height:auto;max-width:54px;position:relative}.histogramme-content{align-items:center;display:flex;flex-direction:column;gap:8px;width:100%}.histogramme-bar{position:relative}.histogramme-svg{display:block}.histogramme-text-container{align-items:center;display:flex;flex-direction:column;gap:0;width:100%}.histogramme-value-container{text-align:center;width:40px}.histogramme-value{font-size:16px;line-height:14px}.histogramme-unit,.histogramme-value{color:#000;display:block;font-weight:600;margin:0}.histogramme-unit{font-size:12px}.histogramme-label{color:#6f6f6f;font-size:12px;font-style:normal;font-weight:400;line-height:18px;margin:0;text-align:left;white-space:nowrap}
1
+ @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogram-container{border:3px solid #2c2f33;height:auto;max-width:54px;position:relative}.histogram-content{align-items:center;display:flex;flex-direction:column;gap:8px;width:100%}.histogram-bar{position:relative}.histogram-svg{display:block}.histogram-text-container{align-items:center;display:flex;flex-direction:column;gap:0;width:100%}.histogram-value-container{text-align:center;width:40px}.histogram-value{font-size:16px;line-height:14px}.histogram-unit,.histogram-value{color:#000;display:block;font-weight:600;margin:0}.histogram-unit{font-size:12px}.histogram-label{color:#6f6f6f;font-size:12px;font-style:normal;font-weight:400;line-height:18px;margin:0;text-align:left;white-space:nowrap}
@@ -1 +1 @@
1
- @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogramme-container{border:3px solid #2c2f33;height:auto;max-width:54px;position:relative}.histogramme-content{align-items:center;display:flex;flex-direction:column;gap:8px;width:100%}.histogramme-bar{position:relative}.histogramme-svg{display:block}.histogramme-text-container{align-items:center;display:flex;flex-direction:column;gap:0;width:100%}.histogramme-value-container{text-align:center;width:40px}.histogramme-value{font-size:16px;line-height:14px}.histogramme-unit,.histogramme-value{color:#000;display:block;font-weight:600;margin:0}.histogramme-unit{font-size:12px}.histogramme-label{color:#6f6f6f;font-size:12px;font-style:normal;font-weight:400;line-height:18px;margin:0;text-align:left;white-space:nowrap}
1
+ @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogram-container{border:3px solid #2c2f33;height:auto;max-width:54px;position:relative}.histogram-content{align-items:center;display:flex;flex-direction:column;gap:8px;width:100%}.histogram-bar{position:relative}.histogram-svg{display:block}.histogram-text-container{align-items:center;display:flex;flex-direction:column;gap:0;width:100%}.histogram-value-container{text-align:center;width:40px}.histogram-value{font-size:16px;line-height:14px}.histogram-unit,.histogram-value{color:#000;display:block;font-weight:600;margin:0}.histogram-unit{font-size:12px}.histogram-label{color:#6f6f6f;font-size:12px;font-style:normal;font-weight:400;line-height:18px;margin:0;text-align:left;white-space:nowrap}
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import{jsx as e,jsxs as a}from"react/jsx-runtime";import{useState as r,useRef as t,useEffect as i}from"react";var n=function(n){var l=n.max,m=n.relative,c=n.value,o=n.unit,h=n.label,s=n.barHeight,u=void 0===s?103:s,v=r(0),d=v[0],g=v[1],w=r(!1),x=w[0],f=w[1],p=t(null),N=t(!0),M=Math.min(m.value/l.value*100,100),b=u,q=x?d:M/100*u;return i(function(){var e=Math.min(m.value/l.value*100,100)/100*u;if(N.current){N.current=!1,f(!0),g(0),p.current=m.value;var a=Date.now(),r=function(){var t=Date.now()-a,i=Math.min(t/1e3,1),n=1-Math.pow(1-i,4);g(e*n),i<1?requestAnimationFrame(r):f(!1)};requestAnimationFrame(r)}else{if(null!==p.current&&p.current!==m.value){var t=Math.min(p.current/l.value*100,100)/100*u;f(!0),g(t);var i=Date.now(),n=function(){var a=Date.now()-i,r=Math.min(a/2e3,1),l=1-Math.pow(1-r,4);g(t+(e-t)*l),r<1?requestAnimationFrame(n):f(!1)};requestAnimationFrame(n)}else null===p.current&&g(e);p.current=m.value}},[m.value,l.value,u]),e("div",{className:"histogramme-container",children:a("div",{className:"histogramme-content",children:[e("div",{className:"histogramme-bar",style:{height:"".concat(u,"px"),width:"32px"},children:a("svg",{width:"32",height:u,viewBox:"0 0 32 ".concat(u),className:"histogramme-svg",children:[e("rect",{x:"0",y:u-b,width:"32",height:b,fill:l.color,rx:"2"}),e("rect",{x:"0",y:u-q,width:"32",height:q,fill:m.color,rx:"2"})]})}),a("div",{className:"histogramme-text-container",children:[a("div",{className:"histogramme-value-container",children:[e("p",{className:"histogramme-value",children:c}),e("p",{className:"histogramme-unit",children:o})]}),e("div",{children:e("p",{className:"histogramme-label",children:h})})]})]})})};export{n as Histogramme};
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useState as a,useRef as r,useEffect as i}from"react";var n=function(n){var c=n.max,o=n.relative,l=n.barHeight,h=void 0===l?103:l,u=n.barWidth,m=void 0===u?32:u,v=n.children,s=a(0),d=s[0],g=s[1],w=a(!1),x=w[0],f=w[1],p=r(null),M=r(!0),N=Math.min(o.value/c.value*100,100),q=h,A=x?d:N/100*h;return i(function(){var e=Math.min(o.value/c.value*100,100)/100*h;if(M.current){M.current=!1,f(!0),g(0),p.current=o.value;var t=Date.now(),a=function(){var r=Date.now()-t,i=Math.min(r/1e3,1),n=1-Math.pow(1-i,4);g(e*n),i<1?requestAnimationFrame(a):f(!1)};requestAnimationFrame(a)}else{if(null!==p.current&&p.current!==o.value){var r=Math.min(p.current/c.value*100,100)/100*h;f(!0),g(r);var i=Date.now(),n=function(){var t=Date.now()-i,a=Math.min(t/2e3,1),c=1-Math.pow(1-a,4);g(r+(e-r)*c),a<1?requestAnimationFrame(n):f(!1)};requestAnimationFrame(n)}else null===p.current&&g(e);p.current=o.value}},[o.value,c.value,h]),e("div",{className:"histogram-container",children:t("div",{className:"histogram-content",children:[e("div",{className:"histogram-bar",style:{height:"".concat(h,"px"),width:"".concat(m,"px")},children:t("svg",{width:m,height:h,viewBox:"0 0 ".concat(m," ").concat(h),className:"histogram-svg",children:[e("rect",{x:"0",y:h-q,width:m,height:q,fill:c.color,rx:"2"}),e("rect",{x:"0",y:h-A,width:m,height:A,fill:o.color,rx:"2"})]})}),v&&e("div",{className:"histogram-text-container",children:v})]})})};export{n as Histogram};
2
2
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/components/Histogramme.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport \"./Histogramme.css\";\n\ninterface HistogrammeProps {\n /** Maximum value configuration with value and color */\n max: {\n value: number;\n color: string;\n };\n /** Relative/current value configuration with value and color */\n relative: {\n value: number;\n color: string;\n };\n /** Value to display in text */\n value: number;\n /** Unit label (e.g., \"MWh\") */\n unit: string;\n /** Description label (e.g., \"Soutirage\") */\n label: string;\n /** Background color of the container */\n backgroundColor?: string;\n /** Height of the histogram bar in pixels */\n barHeight?: number;\n}\n\nexport const Histogramme: React.FC<HistogrammeProps> = ({\n max,\n relative,\n value,\n unit,\n label,\n barHeight = 103,\n}) => {\n // Animation state\n const [animatedHeight, setAnimatedHeight] = useState(0);\n const [isAnimating, setIsAnimating] = useState(false);\n const previousValueRef = useRef<number | null>(null);\n const isInitialMount = useRef(true);\n\n // Calculate the height percentages for the two bars\n const relativePercentage = Math.min((relative.value / max.value) * 100, 100);\n\n // Calculate actual heights in pixels\n const maxBarHeight = barHeight;\n const targetRelativeBarHeight = (relativePercentage / 100) * barHeight;\n const currentRelativeBarHeight = isAnimating\n ? animatedHeight\n : targetRelativeBarHeight;\n\n // Animation effect\n useEffect(() => {\n const targetHeight =\n (Math.min((relative.value / max.value) * 100, 100) / 100) * barHeight;\n\n // On initial mount, start from 0\n if (isInitialMount.current) {\n isInitialMount.current = false;\n setIsAnimating(true);\n setAnimatedHeight(0);\n previousValueRef.current = relative.value;\n\n const startTime = Date.now();\n const duration = 1000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight = targetHeight * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n return;\n }\n\n // For subsequent updates, animate from previous value to new value\n if (\n previousValueRef.current !== null &&\n previousValueRef.current !== relative.value\n ) {\n const previousHeight =\n (Math.min((previousValueRef.current / max.value) * 100, 100) / 100) *\n barHeight;\n setIsAnimating(true);\n setAnimatedHeight(previousHeight);\n\n const startTime = Date.now();\n const duration = 2000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight =\n previousHeight + (targetHeight - previousHeight) * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n } else if (previousValueRef.current === null) {\n // Set initial value without animation if no previous value\n setAnimatedHeight(targetHeight);\n }\n\n previousValueRef.current = relative.value;\n }, [relative.value, max.value, barHeight]);\n\n return (\n <div \n className=\"histogramme-container\"\n >\n <div className=\"histogramme-content\">\n <div \n className=\"histogramme-bar\"\n style={{\n height: `${barHeight}px`,\n width: \"32px\"\n }}\n >\n <svg\n width=\"32\"\n height={barHeight}\n viewBox={`0 0 32 ${barHeight}`}\n className=\"histogramme-svg\"\n >\n {/* Background bar (max value) */}\n <rect\n x=\"0\"\n y={barHeight - maxBarHeight}\n width=\"32\"\n height={maxBarHeight}\n fill={max.color}\n rx=\"2\"\n />\n {/* Foreground bar (relative value) with animation */}\n <rect\n x=\"0\"\n y={barHeight - currentRelativeBarHeight}\n width=\"32\"\n height={currentRelativeBarHeight}\n fill={relative.color}\n rx=\"2\"\n />\n </svg>\n </div>\n <div className=\"histogramme-text-container\">\n <div className=\"histogramme-value-container\">\n <p className=\"histogramme-value\">{value}</p>\n <p className=\"histogramme-unit\">{unit}</p>\n </div>\n <div>\n <p className=\"histogramme-label\">{label}</p>\n </div>\n </div>\n </div>\n </div>\n );\n};\n"],"names":["Histogramme","_a","max","relative","value","unit","label","_b","barHeight","_c","useState","animatedHeight","setAnimatedHeight","_d","isAnimating","setIsAnimating","previousValueRef","useRef","isInitialMount","relativePercentage","Math","min","maxBarHeight","currentRelativeBarHeight","useEffect","targetHeight","current","startTime_1","Date","now","animate_1","elapsed","progress","easeOutQuart","pow","requestAnimationFrame","previousHeight_1","startTime_2","animate_2","_jsx","className","_jsxs","style","height","concat","width","children","viewBox","x","y","fill","color","rx"],"mappings":"8GA0BO,IAAMA,EAA0C,SAACC,GACtD,IAAAC,QACAC,aACAC,UACAC,SACAC,UACAC,EAAAN,EAAAO,UAAAA,OAAS,IAAAD,EAAG,IAAGA,EAGTE,EAAsCC,EAAS,GAA9CC,EAAcF,EAAA,GAAEG,EAAiBH,EAAA,GAClCI,EAAgCH,GAAS,GAAxCI,EAAWD,EAAA,GAAEE,EAAcF,EAAA,GAC5BG,EAAmBC,EAAsB,MACzCC,EAAiBD,GAAO,GAGxBE,EAAqBC,KAAKC,IAAKlB,EAASC,MAAQF,EAAIE,MAAS,IAAK,KAGlEkB,EAAed,EAEfe,EAA2BT,EAC7BH,EAF6BQ,EAAqB,IAAOX,EAkF7D,OA5EAgB,EAAU,WACR,IAAMC,EACHL,KAAKC,IAAKlB,EAASC,MAAQF,EAAIE,MAAS,IAAK,KAAO,IAAOI,EAG9D,GAAIU,EAAeQ,QAAnB,CACER,EAAeQ,SAAU,EACzBX,GAAe,GACfH,EAAkB,GAClBI,EAAiBU,QAAUvB,EAASC,MAEpC,IAAMuB,EAAYC,KAAKC,MAGjBC,EAAU,WACd,IAAMC,EAAUH,KAAKC,MAAQF,EACvBK,EAAWZ,KAAKC,IAAIU,EAJX,IAI+B,GAGxCE,EAAe,EAAIb,KAAKc,IAAI,EAAIF,EAAU,GAGhDpB,EADsBa,EAAeQ,GAGjCD,EAAW,EACbG,sBAAsBL,GAEtBf,GAAe,EAEnB,EAEAoB,sBAAsBL,EAEvB,KA5BD,CA+BA,GAC+B,OAA7Bd,EAAiBU,SACjBV,EAAiBU,UAAYvB,EAASC,MACtC,CACA,IAAMgC,EACHhB,KAAKC,IAAKL,EAAiBU,QAAUxB,EAAIE,MAAS,IAAK,KAAO,IAC/DI,EACFO,GAAe,GACfH,EAAkBwB,GAElB,IAAMC,EAAYT,KAAKC,MAGjBS,EAAU,WACd,IAAMP,EAAUH,KAAKC,MAAQQ,EACvBL,EAAWZ,KAAKC,IAAIU,EAJX,IAI+B,GAGxCE,EAAe,EAAIb,KAAKc,IAAI,EAAIF,EAAU,GAIhDpB,EADEwB,GAAkBX,EAAeW,GAAkBH,GAGjDD,EAAW,EACbG,sBAAsBG,GAEtBvB,GAAe,EAEnB,EAEAoB,sBAAsBG,EACvB,MAAuC,OAA7BtB,EAAiBU,SAE1Bd,EAAkBa,GAGpBT,EAAiBU,QAAUvB,EAASC,KAxCnC,CAyCH,EAAG,CAACD,EAASC,MAAOF,EAAIE,MAAOI,IAG7B+B,EACE,MAAA,CAAAC,UAAU,iCAEVC,EAAK,MAAA,CAAAD,UAAU,gCACbD,EACE,MAAA,CAAAC,UAAU,kBACVE,MAAO,CACLC,OAAQ,GAAGC,OAAApC,EAAa,MACxBqC,MAAO,QAGTC,SAAAL,EAAA,MAAA,CACEI,MAAM,KACNF,OAAQnC,EACRuC,QAAS,UAAUH,OAAApC,GACnBgC,UAAU,kBAAiBM,SAAA,CAG3BP,EACE,OAAA,CAAAS,EAAE,IACFC,EAAGzC,EAAYc,EACfuB,MAAM,KACNF,OAAQrB,EACR4B,KAAMhD,EAAIiD,MACVC,GAAG,MAGLb,EAAA,OAAA,CACES,EAAE,IACFC,EAAGzC,EAAYe,EACfsB,MAAM,KACNF,OAAQpB,EACR2B,KAAM/C,EAASgD,MACfC,GAAG,WAITX,EAAK,MAAA,CAAAD,UAAU,6BACbM,SAAA,CAAAL,EAAA,MAAA,CAAKD,UAAU,8BAA6BM,SAAA,CAC1CP,EAAG,IAAA,CAAAC,UAAU,oBAAqBM,SAAA1C,IAClCmC,EAAG,IAAA,CAAAC,UAAU,mBAAoBM,SAAAzC,OAEnCkC,EAAA,MAAA,CAAAO,SACEP,EAAG,IAAA,CAAAC,UAAU,oBAAqBM,SAAAxC,aAM9C"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/components/Histogram.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport \"./Histogram.css\";\n\ninterface HistogramProps {\n /** Maximum value configuration with value and color */\n max: {\n value: number;\n color: string;\n };\n /** Relative/current value configuration with value and color */\n relative: {\n value: number;\n color: string;\n };\n /** Height of the histogram bar in pixels */\n barHeight?: number;\n /** Width of the histogram bar in pixels */\n barWidth?: number;\n /** Child components (typically text content) */\n children?: React.ReactNode;\n}\n\nexport const Histogram: React.FC<HistogramProps> = ({\n max,\n relative,\n barHeight = 103,\n barWidth = 32,\n children,\n}) => {\n // Animation state\n const [animatedHeight, setAnimatedHeight] = useState(0);\n const [isAnimating, setIsAnimating] = useState(false);\n const previousValueRef = useRef<number | null>(null);\n const isInitialMount = useRef(true);\n\n // Calculate the height percentages for the two bars\n const relativePercentage = Math.min((relative.value / max.value) * 100, 100);\n\n // Calculate actual heights in pixels\n const maxBarHeight = barHeight;\n const targetRelativeBarHeight = (relativePercentage / 100) * barHeight;\n const currentRelativeBarHeight = isAnimating\n ? animatedHeight\n : targetRelativeBarHeight;\n\n // Animation effect\n useEffect(() => {\n const targetHeight =\n (Math.min((relative.value / max.value) * 100, 100) / 100) * barHeight;\n\n // On initial mount, start from 0\n if (isInitialMount.current) {\n isInitialMount.current = false;\n setIsAnimating(true);\n setAnimatedHeight(0);\n previousValueRef.current = relative.value;\n\n const startTime = Date.now();\n const duration = 1000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight = targetHeight * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n return;\n }\n\n // For subsequent updates, animate from previous value to new value\n if (\n previousValueRef.current !== null &&\n previousValueRef.current !== relative.value\n ) {\n const previousHeight =\n (Math.min((previousValueRef.current / max.value) * 100, 100) / 100) *\n barHeight;\n setIsAnimating(true);\n setAnimatedHeight(previousHeight);\n\n const startTime = Date.now();\n const duration = 2000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight =\n previousHeight + (targetHeight - previousHeight) * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n } else if (previousValueRef.current === null) {\n // Set initial value without animation if no previous value\n setAnimatedHeight(targetHeight);\n }\n\n previousValueRef.current = relative.value;\n }, [relative.value, max.value, barHeight]);\n\n return (\n <div \n className=\"histogram-container\"\n >\n <div className=\"histogram-content\">\n <div \n className=\"histogram-bar\"\n style={{\n height: `${barHeight}px`,\n width: `${barWidth}px`\n }}\n >\n <svg\n width={barWidth}\n height={barHeight}\n viewBox={`0 0 ${barWidth} ${barHeight}`}\n className=\"histogram-svg\"\n >\n {/* Background bar (max value) */}\n <rect\n x=\"0\"\n y={barHeight - maxBarHeight}\n width={barWidth}\n height={maxBarHeight}\n fill={max.color}\n rx=\"2\"\n />\n {/* Foreground bar (relative value) with animation */}\n <rect\n x=\"0\"\n y={barHeight - currentRelativeBarHeight}\n width={barWidth}\n height={currentRelativeBarHeight}\n fill={relative.color}\n rx=\"2\"\n />\n </svg>\n </div>\n {children && (\n <div className=\"histogram-text-container\">\n {children}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["Histogram","_a","max","relative","_b","barHeight","_c","barWidth","children","_d","useState","animatedHeight","setAnimatedHeight","_e","isAnimating","setIsAnimating","previousValueRef","useRef","isInitialMount","relativePercentage","Math","min","value","maxBarHeight","currentRelativeBarHeight","useEffect","targetHeight","current","startTime_1","Date","now","animate_1","elapsed","progress","easeOutQuart","pow","requestAnimationFrame","previousHeight_1","startTime_2","animate_2","_jsx","className","_jsxs","style","height","concat","width","viewBox","x","y","fill","color","rx"],"mappings":"8GAsBO,IAAMA,EAAsC,SAACC,OAClDC,EAAGD,EAAAC,IACHC,EAAQF,EAAAE,SACRC,EAAeH,EAAAI,UAAfA,OAAY,IAAAD,EAAA,MACZE,EAAAL,EAAAM,SAAAA,OAAQ,IAAAD,EAAG,GAAEA,EACbE,EAAQP,EAAAO,SAGFC,EAAsCC,EAAS,GAA9CC,EAAcF,EAAA,GAAEG,EAAiBH,EAAA,GAClCI,EAAgCH,GAAS,GAAxCI,EAAWD,EAAA,GAAEE,EAAcF,EAAA,GAC5BG,EAAmBC,EAAsB,MACzCC,EAAiBD,GAAO,GAGxBE,EAAqBC,KAAKC,IAAKlB,EAASmB,MAAQpB,EAAIoB,MAAS,IAAK,KAGlEC,EAAelB,EAEfmB,EAA2BV,EAC7BH,EAF6BQ,EAAqB,IAAOd,EAkF7D,OA5EAoB,EAAU,WACR,IAAMC,EACHN,KAAKC,IAAKlB,EAASmB,MAAQpB,EAAIoB,MAAS,IAAK,KAAO,IAAOjB,EAG9D,GAAIa,EAAeS,QAAnB,CACET,EAAeS,SAAU,EACzBZ,GAAe,GACfH,EAAkB,GAClBI,EAAiBW,QAAUxB,EAASmB,MAEpC,IAAMM,EAAYC,KAAKC,MAGjBC,EAAU,WACd,IAAMC,EAAUH,KAAKC,MAAQF,EACvBK,EAAWb,KAAKC,IAAIW,EAJX,IAI+B,GAGxCE,EAAe,EAAId,KAAKe,IAAI,EAAIF,EAAU,GAGhDrB,EADsBc,EAAeQ,GAGjCD,EAAW,EACbG,sBAAsBL,GAEtBhB,GAAe,EAEnB,EAEAqB,sBAAsBL,EAEvB,KA5BD,CA+BA,GAC+B,OAA7Bf,EAAiBW,SACjBX,EAAiBW,UAAYxB,EAASmB,MACtC,CACA,IAAMe,EACHjB,KAAKC,IAAKL,EAAiBW,QAAUzB,EAAIoB,MAAS,IAAK,KAAO,IAC/DjB,EACFU,GAAe,GACfH,EAAkByB,GAElB,IAAMC,EAAYT,KAAKC,MAGjBS,EAAU,WACd,IAAMP,EAAUH,KAAKC,MAAQQ,EACvBL,EAAWb,KAAKC,IAAIW,EAJX,IAI+B,GAGxCE,EAAe,EAAId,KAAKe,IAAI,EAAIF,EAAU,GAIhDrB,EADEyB,GAAkBX,EAAeW,GAAkBH,GAGjDD,EAAW,EACbG,sBAAsBG,GAEtBxB,GAAe,EAEnB,EAEAqB,sBAAsBG,EACvB,MAAuC,OAA7BvB,EAAiBW,SAE1Bf,EAAkBc,GAGpBV,EAAiBW,QAAUxB,EAASmB,KAxCnC,CAyCH,EAAG,CAACnB,EAASmB,MAAOpB,EAAIoB,MAAOjB,IAG7BmC,EACE,MAAA,CAAAC,UAAU,+BAEVC,EAAK,MAAA,CAAAD,UAAU,8BACbD,EACE,MAAA,CAAAC,UAAU,gBACVE,MAAO,CACLC,OAAQ,GAAGC,OAAAxC,EAAa,MACxByC,MAAO,GAAGD,OAAAtC,EAAY,OAGxBC,SAAAkC,EAAA,MAAA,CACEI,MAAOvC,EACPqC,OAAQvC,EACR0C,QAAS,OAAOF,OAAAtC,cAAYF,GAC5BoC,UAAU,gBAAejC,SAAA,CAGzBgC,EACE,OAAA,CAAAQ,EAAE,IACFC,EAAG5C,EAAYkB,EACfuB,MAAOvC,EACPqC,OAAQrB,EACR2B,KAAMhD,EAAIiD,MACVC,GAAG,MAGLZ,UACEQ,EAAE,IACFC,EAAG5C,EAAYmB,EACfsB,MAAOvC,EACPqC,OAAQpB,EACR0B,KAAM/C,EAASgD,MACfC,GAAG,WAIR5C,GACCgC,SAAKC,UAAU,2BACZjC,SAAAA,QAMb"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react/jsx-runtime"),a=require("react");exports.Histogramme=function(t){var r=t.max,i=t.relative,s=t.value,n=t.unit,l=t.label,c=t.barHeight,m=void 0===c?103:c,u=a.useState(0),h=u[0],o=u[1],v=a.useState(!1),x=v[0],d=v[1],g=a.useRef(null),j=a.useRef(!0),f=Math.min(i.value/r.value*100,100),w=m,N=x?h:f/100*m;return a.useEffect(function(){var e=Math.min(i.value/r.value*100,100)/100*m;if(j.current){j.current=!1,d(!0),o(0),g.current=i.value;var a=Date.now(),t=function(){var r=Date.now()-a,i=Math.min(r/1e3,1),s=1-Math.pow(1-i,4);o(e*s),i<1?requestAnimationFrame(t):d(!1)};requestAnimationFrame(t)}else{if(null!==g.current&&g.current!==i.value){var s=Math.min(g.current/r.value*100,100)/100*m;d(!0),o(s);var n=Date.now(),l=function(){var a=Date.now()-n,t=Math.min(a/2e3,1),r=1-Math.pow(1-t,4);o(s+(e-s)*r),t<1?requestAnimationFrame(l):d(!1)};requestAnimationFrame(l)}else null===g.current&&o(e);g.current=i.value}},[i.value,r.value,m]),e.jsx("div",{className:"histogramme-container",children:e.jsxs("div",{className:"histogramme-content",children:[e.jsx("div",{className:"histogramme-bar",style:{height:"".concat(m,"px"),width:"32px"},children:e.jsxs("svg",{width:"32",height:m,viewBox:"0 0 32 ".concat(m),className:"histogramme-svg",children:[e.jsx("rect",{x:"0",y:m-w,width:"32",height:w,fill:r.color,rx:"2"}),e.jsx("rect",{x:"0",y:m-N,width:"32",height:N,fill:i.color,rx:"2"})]})}),e.jsxs("div",{className:"histogramme-text-container",children:[e.jsxs("div",{className:"histogramme-value-container",children:[e.jsx("p",{className:"histogramme-value",children:s}),e.jsx("p",{className:"histogramme-unit",children:n})]}),e.jsx("div",{children:e.jsx("p",{className:"histogramme-label",children:l})})]})]})})};
1
+ "use strict";var e=require("react/jsx-runtime"),t=require("react");exports.Histogram=function(a){var r=a.max,i=a.relative,n=a.barHeight,s=void 0===n?103:n,c=a.barWidth,u=void 0===c?32:c,l=a.children,o=t.useState(0),h=o[0],v=o[1],m=t.useState(!1),x=m[0],d=m[1],g=t.useRef(null),f=t.useRef(!0),w=Math.min(i.value/r.value*100,100),j=s,M=x?h:w/100*s;return t.useEffect(function(){var e=Math.min(i.value/r.value*100,100)/100*s;if(f.current){f.current=!1,d(!0),v(0),g.current=i.value;var t=Date.now(),a=function(){var r=Date.now()-t,i=Math.min(r/1e3,1),n=1-Math.pow(1-i,4);v(e*n),i<1?requestAnimationFrame(a):d(!1)};requestAnimationFrame(a)}else{if(null!==g.current&&g.current!==i.value){var n=Math.min(g.current/r.value*100,100)/100*s;d(!0),v(n);var c=Date.now(),u=function(){var t=Date.now()-c,a=Math.min(t/2e3,1),r=1-Math.pow(1-a,4);v(n+(e-n)*r),a<1?requestAnimationFrame(u):d(!1)};requestAnimationFrame(u)}else null===g.current&&v(e);g.current=i.value}},[i.value,r.value,s]),e.jsx("div",{className:"histogram-container",children:e.jsxs("div",{className:"histogram-content",children:[e.jsx("div",{className:"histogram-bar",style:{height:"".concat(s,"px"),width:"".concat(u,"px")},children:e.jsxs("svg",{width:u,height:s,viewBox:"0 0 ".concat(u," ").concat(s),className:"histogram-svg",children:[e.jsx("rect",{x:"0",y:s-j,width:u,height:j,fill:r.color,rx:"2"}),e.jsx("rect",{x:"0",y:s-M,width:u,height:M,fill:i.color,rx:"2"})]})}),l&&e.jsx("div",{className:"histogram-text-container",children:l})]})})};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/components/Histogramme.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport \"./Histogramme.css\";\n\ninterface HistogrammeProps {\n /** Maximum value configuration with value and color */\n max: {\n value: number;\n color: string;\n };\n /** Relative/current value configuration with value and color */\n relative: {\n value: number;\n color: string;\n };\n /** Value to display in text */\n value: number;\n /** Unit label (e.g., \"MWh\") */\n unit: string;\n /** Description label (e.g., \"Soutirage\") */\n label: string;\n /** Background color of the container */\n backgroundColor?: string;\n /** Height of the histogram bar in pixels */\n barHeight?: number;\n}\n\nexport const Histogramme: React.FC<HistogrammeProps> = ({\n max,\n relative,\n value,\n unit,\n label,\n barHeight = 103,\n}) => {\n // Animation state\n const [animatedHeight, setAnimatedHeight] = useState(0);\n const [isAnimating, setIsAnimating] = useState(false);\n const previousValueRef = useRef<number | null>(null);\n const isInitialMount = useRef(true);\n\n // Calculate the height percentages for the two bars\n const relativePercentage = Math.min((relative.value / max.value) * 100, 100);\n\n // Calculate actual heights in pixels\n const maxBarHeight = barHeight;\n const targetRelativeBarHeight = (relativePercentage / 100) * barHeight;\n const currentRelativeBarHeight = isAnimating\n ? animatedHeight\n : targetRelativeBarHeight;\n\n // Animation effect\n useEffect(() => {\n const targetHeight =\n (Math.min((relative.value / max.value) * 100, 100) / 100) * barHeight;\n\n // On initial mount, start from 0\n if (isInitialMount.current) {\n isInitialMount.current = false;\n setIsAnimating(true);\n setAnimatedHeight(0);\n previousValueRef.current = relative.value;\n\n const startTime = Date.now();\n const duration = 1000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight = targetHeight * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n return;\n }\n\n // For subsequent updates, animate from previous value to new value\n if (\n previousValueRef.current !== null &&\n previousValueRef.current !== relative.value\n ) {\n const previousHeight =\n (Math.min((previousValueRef.current / max.value) * 100, 100) / 100) *\n barHeight;\n setIsAnimating(true);\n setAnimatedHeight(previousHeight);\n\n const startTime = Date.now();\n const duration = 2000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight =\n previousHeight + (targetHeight - previousHeight) * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n } else if (previousValueRef.current === null) {\n // Set initial value without animation if no previous value\n setAnimatedHeight(targetHeight);\n }\n\n previousValueRef.current = relative.value;\n }, [relative.value, max.value, barHeight]);\n\n return (\n <div \n className=\"histogramme-container\"\n >\n <div className=\"histogramme-content\">\n <div \n className=\"histogramme-bar\"\n style={{\n height: `${barHeight}px`,\n width: \"32px\"\n }}\n >\n <svg\n width=\"32\"\n height={barHeight}\n viewBox={`0 0 32 ${barHeight}`}\n className=\"histogramme-svg\"\n >\n {/* Background bar (max value) */}\n <rect\n x=\"0\"\n y={barHeight - maxBarHeight}\n width=\"32\"\n height={maxBarHeight}\n fill={max.color}\n rx=\"2\"\n />\n {/* Foreground bar (relative value) with animation */}\n <rect\n x=\"0\"\n y={barHeight - currentRelativeBarHeight}\n width=\"32\"\n height={currentRelativeBarHeight}\n fill={relative.color}\n rx=\"2\"\n />\n </svg>\n </div>\n <div className=\"histogramme-text-container\">\n <div className=\"histogramme-value-container\">\n <p className=\"histogramme-value\">{value}</p>\n <p className=\"histogramme-unit\">{unit}</p>\n </div>\n <div>\n <p className=\"histogramme-label\">{label}</p>\n </div>\n </div>\n </div>\n </div>\n );\n};\n"],"names":["_a","max","relative","value","unit","label","_b","barHeight","_c","useState","animatedHeight","setAnimatedHeight","_d","isAnimating","setIsAnimating","previousValueRef","useRef","isInitialMount","relativePercentage","Math","min","maxBarHeight","currentRelativeBarHeight","useEffect","targetHeight","current","startTime_1","Date","now","animate_1","elapsed","progress","easeOutQuart","pow","requestAnimationFrame","previousHeight_1","startTime_2","animate_2","_jsx","className","_jsxs","jsxs","jsx","style","height","concat","width","children","viewBox","x","y","fill","color","rx"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/components/Histogram.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef } from \"react\";\nimport \"./Histogram.css\";\n\ninterface HistogramProps {\n /** Maximum value configuration with value and color */\n max: {\n value: number;\n color: string;\n };\n /** Relative/current value configuration with value and color */\n relative: {\n value: number;\n color: string;\n };\n /** Height of the histogram bar in pixels */\n barHeight?: number;\n /** Width of the histogram bar in pixels */\n barWidth?: number;\n /** Child components (typically text content) */\n children?: React.ReactNode;\n}\n\nexport const Histogram: React.FC<HistogramProps> = ({\n max,\n relative,\n barHeight = 103,\n barWidth = 32,\n children,\n}) => {\n // Animation state\n const [animatedHeight, setAnimatedHeight] = useState(0);\n const [isAnimating, setIsAnimating] = useState(false);\n const previousValueRef = useRef<number | null>(null);\n const isInitialMount = useRef(true);\n\n // Calculate the height percentages for the two bars\n const relativePercentage = Math.min((relative.value / max.value) * 100, 100);\n\n // Calculate actual heights in pixels\n const maxBarHeight = barHeight;\n const targetRelativeBarHeight = (relativePercentage / 100) * barHeight;\n const currentRelativeBarHeight = isAnimating\n ? animatedHeight\n : targetRelativeBarHeight;\n\n // Animation effect\n useEffect(() => {\n const targetHeight =\n (Math.min((relative.value / max.value) * 100, 100) / 100) * barHeight;\n\n // On initial mount, start from 0\n if (isInitialMount.current) {\n isInitialMount.current = false;\n setIsAnimating(true);\n setAnimatedHeight(0);\n previousValueRef.current = relative.value;\n\n const startTime = Date.now();\n const duration = 1000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight = targetHeight * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n return;\n }\n\n // For subsequent updates, animate from previous value to new value\n if (\n previousValueRef.current !== null &&\n previousValueRef.current !== relative.value\n ) {\n const previousHeight =\n (Math.min((previousValueRef.current / max.value) * 100, 100) / 100) *\n barHeight;\n setIsAnimating(true);\n setAnimatedHeight(previousHeight);\n\n const startTime = Date.now();\n const duration = 2000; // 2 seconds\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing function (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n\n const currentHeight =\n previousHeight + (targetHeight - previousHeight) * easeOutQuart;\n setAnimatedHeight(currentHeight);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n } else {\n setIsAnimating(false);\n }\n };\n\n requestAnimationFrame(animate);\n } else if (previousValueRef.current === null) {\n // Set initial value without animation if no previous value\n setAnimatedHeight(targetHeight);\n }\n\n previousValueRef.current = relative.value;\n }, [relative.value, max.value, barHeight]);\n\n return (\n <div \n className=\"histogram-container\"\n >\n <div className=\"histogram-content\">\n <div \n className=\"histogram-bar\"\n style={{\n height: `${barHeight}px`,\n width: `${barWidth}px`\n }}\n >\n <svg\n width={barWidth}\n height={barHeight}\n viewBox={`0 0 ${barWidth} ${barHeight}`}\n className=\"histogram-svg\"\n >\n {/* Background bar (max value) */}\n <rect\n x=\"0\"\n y={barHeight - maxBarHeight}\n width={barWidth}\n height={maxBarHeight}\n fill={max.color}\n rx=\"2\"\n />\n {/* Foreground bar (relative value) with animation */}\n <rect\n x=\"0\"\n y={barHeight - currentRelativeBarHeight}\n width={barWidth}\n height={currentRelativeBarHeight}\n fill={relative.color}\n rx=\"2\"\n />\n </svg>\n </div>\n {children && (\n <div className=\"histogram-text-container\">\n {children}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["_a","max","relative","_b","barHeight","_c","barWidth","children","_d","useState","animatedHeight","setAnimatedHeight","_e","isAnimating","setIsAnimating","previousValueRef","useRef","isInitialMount","relativePercentage","Math","min","value","maxBarHeight","currentRelativeBarHeight","useEffect","targetHeight","current","startTime_1","Date","now","animate_1","elapsed","progress","easeOutQuart","pow","requestAnimationFrame","previousHeight_1","startTime_2","animate_2","_jsx","className","_jsxs","jsxs","jsx","style","height","concat","width","viewBox","x","y","fill","color","rx"],"mappings":"qFAsBmD,SAACA,OAClDC,EAAGD,EAAAC,IACHC,EAAQF,EAAAE,SACRC,EAAeH,EAAAI,UAAfA,OAAY,IAAAD,EAAA,MACZE,EAAAL,EAAAM,SAAAA,OAAQ,IAAAD,EAAG,GAAEA,EACbE,EAAQP,EAAAO,SAGFC,EAAsCC,EAAAA,SAAS,GAA9CC,EAAcF,EAAA,GAAEG,EAAiBH,EAAA,GAClCI,EAAgCH,EAAAA,UAAS,GAAxCI,EAAWD,EAAA,GAAEE,EAAcF,EAAA,GAC5BG,EAAmBC,SAAsB,MACzCC,EAAiBD,UAAO,GAGxBE,EAAqBC,KAAKC,IAAKlB,EAASmB,MAAQpB,EAAIoB,MAAS,IAAK,KAGlEC,EAAelB,EAEfmB,EAA2BV,EAC7BH,EAF6BQ,EAAqB,IAAOd,EAkF7D,OA5EAoB,EAAAA,UAAU,WACR,IAAMC,EACHN,KAAKC,IAAKlB,EAASmB,MAAQpB,EAAIoB,MAAS,IAAK,KAAO,IAAOjB,EAG9D,GAAIa,EAAeS,QAAnB,CACET,EAAeS,SAAU,EACzBZ,GAAe,GACfH,EAAkB,GAClBI,EAAiBW,QAAUxB,EAASmB,MAEpC,IAAMM,EAAYC,KAAKC,MAGjBC,EAAU,WACd,IAAMC,EAAUH,KAAKC,MAAQF,EACvBK,EAAWb,KAAKC,IAAIW,EAJX,IAI+B,GAGxCE,EAAe,EAAId,KAAKe,IAAI,EAAIF,EAAU,GAGhDrB,EADsBc,EAAeQ,GAGjCD,EAAW,EACbG,sBAAsBL,GAEtBhB,GAAe,EAEnB,EAEAqB,sBAAsBL,EAEvB,KA5BD,CA+BA,GAC+B,OAA7Bf,EAAiBW,SACjBX,EAAiBW,UAAYxB,EAASmB,MACtC,CACA,IAAMe,EACHjB,KAAKC,IAAKL,EAAiBW,QAAUzB,EAAIoB,MAAS,IAAK,KAAO,IAC/DjB,EACFU,GAAe,GACfH,EAAkByB,GAElB,IAAMC,EAAYT,KAAKC,MAGjBS,EAAU,WACd,IAAMP,EAAUH,KAAKC,MAAQQ,EACvBL,EAAWb,KAAKC,IAAIW,EAJX,IAI+B,GAGxCE,EAAe,EAAId,KAAKe,IAAI,EAAIF,EAAU,GAIhDrB,EADEyB,GAAkBX,EAAeW,GAAkBH,GAGjDD,EAAW,EACbG,sBAAsBG,GAEtBxB,GAAe,EAEnB,EAEAqB,sBAAsBG,EACvB,MAAuC,OAA7BvB,EAAiBW,SAE1Bf,EAAkBc,GAGpBV,EAAiBW,QAAUxB,EAASmB,KAxCnC,CAyCH,EAAG,CAACnB,EAASmB,MAAOpB,EAAIoB,MAAOjB,IAG7BmC,EAAAA,IACE,MAAA,CAAAC,UAAU,+BAEVC,EAAKC,KAAA,MAAA,CAAAF,UAAU,8BACbD,EACEI,IAAA,MAAA,CAAAH,UAAU,gBACVI,MAAO,CACLC,OAAQ,GAAGC,OAAA1C,EAAa,MACxB2C,MAAO,GAAGD,OAAAxC,EAAY,OAGxBC,SAAAkC,EAAAA,KAAA,MAAA,CACEM,MAAOzC,EACPuC,OAAQzC,EACR4C,QAAS,OAAOF,OAAAxC,cAAYF,GAC5BoC,UAAU,gBAAejC,SAAA,CAGzBgC,EACEI,IAAA,OAAA,CAAAM,EAAE,IACFC,EAAG9C,EAAYkB,EACfyB,MAAOzC,EACPuC,OAAQvB,EACR6B,KAAMlD,EAAImD,MACVC,GAAG,MAGLd,cACEU,EAAE,IACFC,EAAG9C,EAAYmB,EACfwB,MAAOzC,EACPuC,OAAQtB,EACR4B,KAAMjD,EAASkD,MACfC,GAAG,WAIR9C,GACCgC,EAAAA,WAAKC,UAAU,2BACZjC,SAAAA,QAMb"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rte-utils",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "React components library in TypeScript for agigox projects",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -49,6 +49,9 @@
49
49
  "tslib": "^2.8.1",
50
50
  "typescript": "^5.1.0"
51
51
  },
52
+ "optionalDependencies": {
53
+ "fsevents": "^2.3.3"
54
+ },
52
55
  "repository": {
53
56
  "type": "git",
54
57
  "url": "git+https://github.com/agigox/rte-utils.git"