rte-utils 1.1.0 → 1.2.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
@@ -30,8 +30,8 @@ function App() {
30
30
  return (
31
31
  <div>
32
32
  <Histogramme
33
- maxValue={100}
34
- relativeValue={56}
33
+ max={{ value: 100, color: "#D3D64E" }}
34
+ relative={{ value: 56, color: "#C0C402" }}
35
35
  value={56}
36
36
  unit="MWh"
37
37
  label="Soutirage"
@@ -56,8 +56,8 @@ function EnergyDashboard() {
56
56
  return (
57
57
  <div style={{ display: 'flex', gap: '1rem' }}>
58
58
  <Histogramme
59
- maxValue={100}
60
- relativeValue={currentValue}
59
+ max={{ value: 100, color: "#D3D64E" }}
60
+ relative={{ value: currentValue, color: "#C0C402" }}
61
61
  value={currentValue}
62
62
  unit="MWh"
63
63
  label="Consommation"
@@ -84,8 +84,8 @@ A histogram component with smooth animations for energy data visualization.
84
84
 
85
85
  | Prop | Type | Required | Default | Description |
86
86
  |------|------|----------|---------|-------------|
87
- | `maxValue` | `number` | ✅ | - | Maximum value for the bar chart |
88
- | `relativeValue` | `number` | ✅ | - | Relative/current value to compare against max |
87
+ | `max` | `{ value: number; color: string }` | ✅ | - | Maximum value configuration with value and color |
88
+ | `relative` | `{ value: number; color: string }` | ✅ | - | Relative/current value configuration with value and color |
89
89
  | `value` | `number` | ✅ | - | Value to display in text |
90
90
  | `unit` | `string` | ✅ | - | Unit label (e.g., "MWh") |
91
91
  | `label` | `string` | ✅ | - | Description label (e.g., "Soutirage") |
@@ -97,9 +97,9 @@ A histogram component with smooth animations for energy data visualization.
97
97
 
98
98
  - **Smooth animations**: 2-second Chart.js-style transitions
99
99
  - **Incremental updates**: Animations from previous to new values (not from 0)
100
- - **Two-color visualization**:
101
- - Background bar (`#D3D64E`) represents the maximum value
102
- - Foreground bar (`#C0C402`) represents the relative value
100
+ - **Dynamic two-color visualization**:
101
+ - Background bar color defined by `max.color` represents the maximum value
102
+ - Foreground bar color defined by `relative.color` represents the relative value
103
103
  - **Customizable**: Colors, dimensions, and styling options
104
104
  - **TypeScript support**: Full type definitions included
105
105
 
@@ -1,10 +1,16 @@
1
1
  import React from "react";
2
2
  import "./Histogramme.css";
3
3
  interface HistogrammeProps {
4
- /** Maximum value for the bar chart */
5
- maxValue: number;
6
- /** Relative/current value to compare against max */
7
- relativeValue: number;
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
+ };
8
14
  /** Value to display in text */
9
15
  value: number;
10
16
  /** Unit label (e.g., "MWh") */
@@ -15,8 +21,6 @@ interface HistogrammeProps {
15
21
  backgroundColor?: string;
16
22
  /** Height of the histogram bar in pixels */
17
23
  barHeight?: number;
18
- /** Width of the component in pixels */
19
- width?: number;
20
24
  }
21
25
  export declare const Histogramme: React.FC<HistogrammeProps>;
22
26
  export {};
package/dist/index.css CHANGED
@@ -1 +1 @@
1
- .histogramme-container{height:auto;padding:34px 0;position:relative}.histogramme-content{align-items:center;display:flex;flex-direction:column;gap:16px;width:100%}.histogramme-bar{position:relative}.histogramme-svg{display:block}.histogramme-text-container{align-items:center;display:flex;flex-direction:column;gap:2px;width:100%}.histogramme-value-container{text-align:center;width:40px}.histogramme-value{font-size:16px;line-height:14px}.histogramme-unit,.histogramme-value{color:#fff;display:block;font-family:Open Sans,sans-serif;font-weight:600;margin:0}.histogramme-unit{font-size:12px}.histogramme-label{color:#dddfe0;font-family:Open Sans,sans-serif;font-size:12px;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}.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 +1 @@
1
- .histogramme-container{height:auto;padding:34px 0;position:relative}.histogramme-content{align-items:center;display:flex;flex-direction:column;gap:16px;width:100%}.histogramme-bar{position:relative}.histogramme-svg{display:block}.histogramme-text-container{align-items:center;display:flex;flex-direction:column;gap:2px;width:100%}.histogramme-value-container{text-align:center;width:40px}.histogramme-value{font-size:16px;line-height:14px}.histogramme-unit,.histogramme-value{color:#fff;display:block;font-family:Open Sans,sans-serif;font-weight:600;margin:0}.histogramme-unit{font-size:12px}.histogramme-label{color:#dddfe0;font-family:Open Sans,sans-serif;font-size:12px;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}.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}
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 c=n.maxValue,m=n.relativeValue,l=n.value,o=n.unit,h=n.label,s=n.backgroundColor,u=void 0===s?"#005896":s,d=n.barHeight,v=void 0===d?103:d,g=n.width,w=void 0===g?54:g,x=r(0),p=x[0],f=x[1],N=r(!1),M=N[0],b=N[1],D=t(null),q=t(!0),y=Math.min(m/c*100,100),A=v,C=M?p:y/100*v;return i(function(){var e=Math.min(m/c*100,100)/100*v;if(q.current){q.current=!1,b(!0),f(0),D.current=m;var a=Date.now(),r=function(){var t=Date.now()-a,i=Math.min(t/1e3,1),n=1-Math.pow(1-i,4);f(e*n),i<1?requestAnimationFrame(r):b(!1)};requestAnimationFrame(r)}else{if(null!==D.current&&D.current!==m){var t=Math.min(D.current/c*100,100)/100*v;b(!0),f(t);var i=Date.now(),n=function(){var a=Date.now()-i,r=Math.min(a/2e3,1),c=1-Math.pow(1-r,4);f(t+(e-t)*c),r<1?requestAnimationFrame(n):b(!1)};requestAnimationFrame(n)}else null===D.current&&f(e);D.current=m}},[m,c,v]),e("div",{className:"histogramme-container",style:{backgroundColor:u,width:"".concat(w,"px")},children:a("div",{className:"histogramme-content",children:[e("div",{className:"histogramme-bar",style:{height:"".concat(v,"px"),width:"32px"},children:a("svg",{width:"32",height:v,viewBox:"0 0 32 ".concat(v),className:"histogramme-svg",children:[e("rect",{x:"0",y:v-A,width:"32",height:A,fill:"#D3D64E",rx:"2"}),e("rect",{x:"0",y:v-C,width:"32",height:C,fill:"#C0C402",rx:"2"})]})}),a("div",{className:"histogramme-text-container",children:[a("div",{className:"histogramme-value-container",children:[e("p",{className:"histogramme-value",children:l}),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 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};
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 for the bar chart */\n maxValue: number;\n /** Relative/current value to compare against max */\n relativeValue: number;\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 /** Width of the component in pixels */\n width?: number;\n}\n\nexport const Histogramme: React.FC<HistogrammeProps> = ({\n maxValue,\n relativeValue,\n value,\n unit,\n label,\n backgroundColor = \"#005896\",\n barHeight = 103,\n width = 54,\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 maxPercentage = 100;\n const relativePercentage = Math.min((relativeValue / maxValue) * 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((relativeValue / maxValue) * 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 = relativeValue;\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 !== relativeValue\n ) {\n const previousHeight =\n (Math.min((previousValueRef.current / maxValue) * 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 = relativeValue;\n }, [relativeValue, maxValue, barHeight]);\n\n return (\n <div \n className=\"histogramme-container\"\n style={{ \n backgroundColor,\n width: `${width}px`\n }}\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=\"#D3D64E\"\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=\"#C0C402\"\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","maxValue","relativeValue","value","unit","label","_b","backgroundColor","_c","barHeight","_d","width","_e","useState","animatedHeight","setAnimatedHeight","_f","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","style","concat","children","_jsxs","height","viewBox","x","y","fill","rx"],"mappings":"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"}
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"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react/jsx-runtime"),t=require("react");exports.Histogramme=function(a){var r=a.maxValue,i=a.relativeValue,n=a.value,s=a.unit,c=a.label,l=a.backgroundColor,m=void 0===l?"#005896":l,o=a.barHeight,h=void 0===o?103:o,u=a.width,d=void 0===u?54:u,v=t.useState(0),x=v[0],g=v[1],j=t.useState(!1),w=j[0],f=j[1],p=t.useRef(null),N=t.useRef(!0),M=Math.min(i/r*100,100),b=h,q=w?x:M/100*h;return t.useEffect(function(){var e=Math.min(i/r*100,100)/100*h;if(N.current){N.current=!1,f(!0),g(0),p.current=i;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!==i){var n=Math.min(p.current/r*100,100)/100*h;f(!0),g(n);var s=Date.now(),c=function(){var t=Date.now()-s,a=Math.min(t/2e3,1),r=1-Math.pow(1-a,4);g(n+(e-n)*r),a<1?requestAnimationFrame(c):f(!1)};requestAnimationFrame(c)}else null===p.current&&g(e);p.current=i}},[i,r,h]),e.jsx("div",{className:"histogramme-container",style:{backgroundColor:m,width:"".concat(d,"px")},children:e.jsxs("div",{className:"histogramme-content",children:[e.jsx("div",{className:"histogramme-bar",style:{height:"".concat(h,"px"),width:"32px"},children:e.jsxs("svg",{width:"32",height:h,viewBox:"0 0 32 ".concat(h),className:"histogramme-svg",children:[e.jsx("rect",{x:"0",y:h-b,width:"32",height:b,fill:"#D3D64E",rx:"2"}),e.jsx("rect",{x:"0",y:h-q,width:"32",height:q,fill:"#C0C402",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:n}),e.jsx("p",{className:"histogramme-unit",children:s})]}),e.jsx("div",{children:e.jsx("p",{className:"histogramme-label",children:c})})]})]})})};
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})})]})]})})};
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 for the bar chart */\n maxValue: number;\n /** Relative/current value to compare against max */\n relativeValue: number;\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 /** Width of the component in pixels */\n width?: number;\n}\n\nexport const Histogramme: React.FC<HistogrammeProps> = ({\n maxValue,\n relativeValue,\n value,\n unit,\n label,\n backgroundColor = \"#005896\",\n barHeight = 103,\n width = 54,\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 maxPercentage = 100;\n const relativePercentage = Math.min((relativeValue / maxValue) * 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((relativeValue / maxValue) * 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 = relativeValue;\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 !== relativeValue\n ) {\n const previousHeight =\n (Math.min((previousValueRef.current / maxValue) * 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 = relativeValue;\n }, [relativeValue, maxValue, barHeight]);\n\n return (\n <div \n className=\"histogramme-container\"\n style={{ \n backgroundColor,\n width: `${width}px`\n }}\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=\"#D3D64E\"\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=\"#C0C402\"\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","maxValue","relativeValue","value","unit","label","_b","backgroundColor","_c","barHeight","_d","width","_e","useState","animatedHeight","setAnimatedHeight","_f","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","jsx","className","style","concat","children","_jsxs","jsxs","height","viewBox","x","y","fill","rx"],"mappings":"uFAsBuD,SAACA,GACtD,IAAAC,EAAQD,EAAAC,SACRC,EAAaF,EAAAE,cACbC,EAAKH,EAAAG,MACLC,EAAIJ,EAAAI,KACJC,EAAKL,EAAAK,MACLC,EAA2BN,EAAAO,gBAA3BA,OAAe,IAAAD,EAAG,UAASA,EAC3BE,EAAAR,EAAAS,UAAAA,OAAS,IAAAD,EAAG,IAAGA,EACfE,EAAUV,EAAAW,MAAVA,OAAK,IAAAD,EAAG,GAAEA,EAGJE,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,GAIxBE,EAAqBC,KAAKC,IAAKtB,EAAgBD,EAAY,IAAK,KAGhEwB,EAAehB,EAEfiB,EAA2BT,EAC7BH,EAF6BQ,EAAqB,IAAOb,EAkF7D,OA5EAkB,EAAAA,UAAU,WACR,IAAMC,EACHL,KAAKC,IAAKtB,EAAgBD,EAAY,IAAK,KAAO,IAAOQ,EAG5D,GAAIY,EAAeQ,QAAnB,CACER,EAAeQ,SAAU,EACzBX,GAAe,GACfH,EAAkB,GAClBI,EAAiBU,QAAU3B,EAE3B,IAAM4B,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,UAAY3B,EAC7B,CACA,IAAMqC,EACHhB,KAAKC,IAAKL,EAAiBU,QAAU5B,EAAY,IAAK,KAAO,IAC9DQ,EACFS,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,QAAU3B,CAxC1B,CAyCF,EAAE,CAACA,EAAeD,EAAUQ,IAG3BiC,EACEC,IAAA,MAAA,CAAAC,UAAU,wBACVC,MAAO,CACLtC,gBAAeA,EACfI,MAAO,GAAGmC,OAAAnC,EAAS,OAGrBoC,SAAAC,EAAAC,KAAA,MAAA,CAAKL,UAAU,sBAAqBG,SAAA,CAClCL,EACEC,IAAA,MAAA,CAAAC,UAAU,kBACVC,MAAO,CACLK,OAAQ,GAAGJ,OAAArC,EAAa,MACxBE,MAAO,QAGToC,SAAAC,EAAAA,KAAA,MAAA,CACErC,MAAM,KACNuC,OAAQzC,EACR0C,QAAS,UAAUL,OAAArC,GACnBmC,UAAU,kBAGVG,SAAA,CAAAL,EAAAC,IAAA,OAAA,CACES,EAAE,IACFC,EAAG5C,EAAYgB,EACfd,MAAM,KACNuC,OAAQzB,EACR6B,KAAK,UACLC,GAAG,MAGLb,EAAAC,IAAA,OAAA,CACES,EAAE,IACFC,EAAG5C,EAAYiB,EACff,MAAM,KACNuC,OAAQxB,EACR4B,KAAK,UACLC,GAAG,WAITP,EAAAA,KAAA,MAAA,CAAKJ,UAAU,6BAA4BG,SAAA,CACzCC,EAAAA,KAAK,MAAA,CAAAJ,UAAU,8BACbG,SAAA,CAAAL,EAAAA,IAAA,IAAA,CAAGE,UAAU,oBAAqBG,SAAA5C,IAClCuC,EAAGC,IAAA,IAAA,CAAAC,UAAU,mBAAoBG,SAAA3C,OAEnCsC,EAAAC,IAAA,MAAA,CAAAI,SACEL,EAAAA,IAAG,IAAA,CAAAE,UAAU,oBAAqBG,SAAA1C,aAM9C"}
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rte-utils",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "React components library in TypeScript for agigox projects",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",