@sbkbs/ui 1.0.5 → 1.0.6

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.
@@ -0,0 +1,11 @@
1
+ import type React from 'react';
2
+ export interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {
3
+ /** Texto alternativo / label acessível para a imagem ou iniciais. */
4
+ alt: string;
5
+ /** URL da imagem. Se ausente ou falhar no carregamento, exibe as iniciais. */
6
+ src?: string;
7
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
8
+ /** Formato do avatar. Padrão: 'circle' */
9
+ shape?: 'circle' | 'square';
10
+ }
11
+ export declare const Avatar: React.FC<AvatarProps>;
@@ -4,9 +4,9 @@ export interface FooterProps {
4
4
  className?: string;
5
5
  /** Texto alternativo do logo */
6
6
  logoAlt?: string;
7
- /** Texto exibido se a imagem do logo falhar (ex.: "SBK") */
7
+ /** Fallback textual — não utilizado no design padrão, mantido por compatibilidade */
8
8
  logoFallbackText?: string;
9
- /** URL da imagem do logo */
9
+ /** URL de imagem para substituir o logo SVG padrão */
10
10
  logoSrc?: string;
11
11
  /** Texto antes do logo (ex.: "Powered by") */
12
12
  poweredByText?: string;
@@ -1,54 +1,119 @@
1
- import { jsx as r, jsxs as n } from "react/jsx-runtime";
2
- import { useState as c } from "react";
3
- const p = ({
4
- poweredByText: t = "Powered by",
5
- logoSrc: e,
6
- logoAlt: i = "Logo",
7
- logoFallbackText: s,
8
- className: o = ""
9
- }) => {
10
- const [a, l] = c(!0);
11
- return /* @__PURE__ */ r(
12
- "footer",
1
+ import { jsx as e, jsxs as i } from "react/jsx-runtime";
2
+ import { useState as h, useEffect as f } from "react";
3
+ import { cn as u } from "../../utils/cn.js";
4
+ const d = () => typeof document > "u" ? "light" : document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light", p = ({ color: t, height: r = 28, opacity: s = 1 }) => {
5
+ const n = Math.round(r * 2.098961562306262);
6
+ return /* @__PURE__ */ e(
7
+ "svg",
13
8
  {
14
- className: [
15
- "relative z-[1] flex w-full shrink-0 items-center justify-center border-t border-[var(--border-color)] bg-[var(--bg-secondary)] px-[var(--spacing-2xl)] py-[var(--spacing-lg)]",
16
- o
17
- ].filter(Boolean).join(" "),
18
- children: /* @__PURE__ */ n("div", { className: "flex items-center gap-[var(--spacing-md)]", children: [
19
- t && /* @__PURE__ */ r("span", { className: "text-[0.95rem] font-normal text-[var(--text-secondary)]", children: t }),
20
- (e || s) && /* @__PURE__ */ n("div", { className: "flex items-center", children: [
21
- e && a && /* @__PURE__ */ r(
22
- "img",
9
+ "aria-label": "SBK",
10
+ height: r,
11
+ style: { opacity: s },
12
+ viewBox: "39.15 180.84 541.7 258.08",
13
+ width: n,
14
+ xmlns: "http://www.w3.org/2000/svg",
15
+ children: /* @__PURE__ */ e("g", { transform: "translate(-49, 122)", children: /* @__PURE__ */ i("g", { children: [
16
+ /* @__PURE__ */ i("g", { children: [
17
+ /* @__PURE__ */ e(
18
+ "path",
19
+ {
20
+ d: "m225.13 266.26c-27.48 0-47.67-12.07-50.38-41.01h14.16c0.62 21.44 17.69 29.56 36.85 29.56 18.11 0 39.14-7.91 39.14-29.14 0-16.24-13.12-23.74-32.48-29.99l-11.03-3.53c-24.36-7.71-42.27-16.66-42.27-40.19 0-28.1 24.78-39.97 49.76-39.97 22.9 0 46.64 8.54 47.05 35.18h-13.95c-1.87-18.32-15.82-23.94-32.47-23.94-17.29 0-36.65 7.71-36.65 27.69 0 14.78 11.04 22.28 34.36 29.77l12.49 3.96c24.36 7.7 38.3 15.82 38.93 38.73 0 30.18-26.65 42.88-53.51 42.88z",
21
+ fill: t,
22
+ stroke: t,
23
+ strokeMiterlimit: 10,
24
+ strokeWidth: 2
25
+ }
26
+ ),
27
+ /* @__PURE__ */ e(
28
+ "path",
29
+ {
30
+ d: "m351.42 264.39h-41.43v-150.53h41.43c8.53 0 17.9-0.2 26.23 2.09 16.24 4.58 27.48 17.9 27.48 35.18 0 18.74-10.41 29.98-27.9 34.56 20.82 2.71 34.15 15.2 34.15 36.85 0 34.56-31.86 41.85-59.96 41.85zm8.12-138.45h-36.02v56.49h32.06c19.16 0 34.98-8.81 34.98-30.26 0-18.74-14.16-26.23-31.02-26.23zm-1.46 63.19h-34.56v63.18h26.65c21.86 0 46.84-1.45 46.84-29.98 0-24.77-18.11-33.2-38.93-33.2z",
31
+ fill: t,
32
+ fillRule: "evenodd",
33
+ stroke: t,
34
+ strokeMiterlimit: 10,
35
+ strokeWidth: 2
36
+ }
37
+ ),
38
+ /* @__PURE__ */ e(
39
+ "path",
23
40
  {
24
- alt: i,
25
- className: "h-6 w-auto object-contain",
26
- onError: (m) => {
27
- l(!1);
28
- },
29
- src: e,
30
- style: {
31
- filter: "brightness(0)"
32
- }
41
+ d: "m443.77 264.39v-150.53h13.53v150.53zm88.07 0l-73.7-81.61 67.03-68.92h18.12l-68.91 67.88 75.99 82.65z",
42
+ fill: t,
43
+ stroke: t,
44
+ strokeMiterlimit: 10,
45
+ strokeWidth: 2
46
+ }
47
+ )
48
+ ] }),
49
+ /* @__PURE__ */ i("g", { children: [
50
+ /* @__PURE__ */ e(
51
+ "path",
52
+ {
53
+ d: "m99.09 118.17l-0.21 57.98-9.73 0.24 0.56-62.81c0.26-29.03 26.91-53.16 56.3-53.26l151.74-0.48c0.62 3.58 0.63 6.35 0.05 9.92l-150.35 0.22c-26.28 0.04-48.26 21.9-48.36 48.19z",
54
+ fill: t
33
55
  }
34
56
  ),
35
- s && /* @__PURE__ */ r(
36
- "span",
57
+ /* @__PURE__ */ e(
58
+ "path",
37
59
  {
38
- className: "flex items-center text-base font-bold tracking-[0.1em] text-[var(--md-primary)]",
39
- style: {
40
- display: e && a ? "none" : "flex",
41
- fontFamily: '"Orbitron", sans-serif'
42
- },
43
- children: s
60
+ d: "m419.9 315.79l0.22-9.33 149.3-0.15c25.73-0.02 48.97-20.27 49.14-45.96l0.4-60.49q4.64-0.28 9.57-0.07l0.32 52.61c0.21 33.16-23.62 63.29-57.93 63.33l-135.88 0.19z",
61
+ fill: t
44
62
  }
45
63
  )
46
64
  ] })
65
+ ] }) })
66
+ }
67
+ );
68
+ }, b = ({
69
+ poweredByText: t = "Powered by",
70
+ logoSrc: r,
71
+ logoAlt: s = "SBK",
72
+ className: o = ""
73
+ }) => {
74
+ const [n, m] = h(() => d());
75
+ f(() => {
76
+ const a = () => m(d());
77
+ if (a(), typeof MutationObserver > "u") return;
78
+ const c = new MutationObserver(a);
79
+ return c.observe(document.documentElement, { attributes: !0, attributeFilter: ["data-theme"] }), () => c.disconnect();
80
+ }, []);
81
+ const l = n === "dark";
82
+ return /* @__PURE__ */ e(
83
+ "footer",
84
+ {
85
+ className: u(
86
+ "relative z-[1] w-full shrink-0 box-border",
87
+ "flex items-center justify-center",
88
+ "py-5 px-14",
89
+ "border-t border-[var(--border-color)]",
90
+ "bg-[var(--bg-secondary)]",
91
+ o
92
+ ),
93
+ children: /* @__PURE__ */ i("div", { className: "flex items-center gap-2.5", children: [
94
+ t && /* @__PURE__ */ e("span", { className: "font-primary text-xs font-normal text-[var(--text-muted)]", children: t }),
95
+ r ? /* @__PURE__ */ e(
96
+ "img",
97
+ {
98
+ alt: s,
99
+ src: r,
100
+ className: "h-7 w-auto object-contain",
101
+ style: { opacity: l ? 0.65 : 0.75 }
102
+ }
103
+ ) : /* @__PURE__ */ e(
104
+ p,
105
+ {
106
+ color: l ? "#ffffff" : "#1F3A3A",
107
+ height: 28,
108
+ opacity: l ? 0.65 : 0.75
109
+ }
110
+ )
47
111
  ] })
48
112
  }
49
113
  );
50
114
  };
115
+ b.displayName = "Footer";
51
116
  export {
52
- p as Footer
117
+ b as Footer
53
118
  };
54
119
  //# sourceMappingURL=Footer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Footer.js","sources":["../../../src/components/Footer/Footer.tsx"],"sourcesContent":["import type React from 'react';\nimport { useState } from 'react';\n\nexport interface FooterProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** Texto exibido se a imagem do logo falhar (ex.: \"SBK\") */\n logoFallbackText?: string;\n /** URL da imagem do logo */\n logoSrc?: string;\n /** Texto antes do logo (ex.: \"Powered by\") */\n poweredByText?: string;\n}\n\nexport const Footer: React.FC<FooterProps> = ({\n poweredByText = 'Powered by',\n logoSrc,\n logoAlt = 'Logo',\n logoFallbackText,\n className = '',\n}) => {\n const [logoVisible, setLogoVisible] = useState(true);\n return (\n <footer\n className={[\n 'relative z-[1] flex w-full shrink-0 items-center justify-center border-t border-[var(--border-color)] bg-[var(--bg-secondary)] px-[var(--spacing-2xl)] py-[var(--spacing-lg)]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <div className=\"flex items-center gap-[var(--spacing-md)]\">\n {poweredByText && (\n <span className=\"text-[0.95rem] font-normal text-[var(--text-secondary)]\">\n {poweredByText}\n </span>\n )}\n {(logoSrc || logoFallbackText) && (\n <div className=\"flex items-center\">\n {logoSrc && logoVisible && (\n <img\n alt={logoAlt}\n className=\"h-6 w-auto object-contain\"\n onError={(_e) => {\n setLogoVisible(false);\n }}\n src={logoSrc}\n style={{\n filter: 'brightness(0)',\n }}\n />\n )}\n {logoFallbackText && (\n <span\n className=\"flex items-center text-base font-bold tracking-[0.1em] text-[var(--md-primary)]\"\n style={{\n display: logoSrc && logoVisible ? 'none' : 'flex',\n fontFamily: '\"Orbitron\", sans-serif',\n }}\n >\n {logoFallbackText}\n </span>\n )}\n </div>\n )}\n </div>\n </footer>\n );\n};\n"],"names":["Footer","poweredByText","logoSrc","logoAlt","logoFallbackText","className","logoVisible","setLogoVisible","useState","jsx","jsxs","_e"],"mappings":";;AAgBO,MAAMA,IAAgC,CAAC;AAAA,EAC5C,eAAAC,IAAgB;AAAA,EAChB,SAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,kBAAAC;AAAA,EACA,WAAAC,IAAY;AACd,MAAM;AACJ,QAAM,CAACC,GAAaC,CAAc,IAAIC,EAAS,EAAI;AACnD,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACAJ;AAAA,MAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MAEX,UAAA,gBAAAK,EAAC,OAAA,EAAI,WAAU,6CACZ,UAAA;AAAA,QAAAT,KACC,gBAAAQ,EAAC,QAAA,EAAK,WAAU,2DACb,UAAAR,GACH;AAAA,SAEAC,KAAWE,MACX,gBAAAM,EAAC,OAAA,EAAI,WAAU,qBACZ,UAAA;AAAA,UAAAR,KAAWI,KACV,gBAAAG;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKN;AAAA,cACL,WAAU;AAAA,cACV,SAAS,CAACQ,MAAO;AACf,gBAAAJ,EAAe,EAAK;AAAA,cACtB;AAAA,cACA,KAAKL;AAAA,cACL,OAAO;AAAA,gBACL,QAAQ;AAAA,cAAA;AAAA,YACV;AAAA,UAAA;AAAA,UAGHE,KACC,gBAAAK;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO;AAAA,gBACL,SAASP,KAAWI,IAAc,SAAS;AAAA,gBAC3C,YAAY;AAAA,cAAA;AAAA,cAGb,UAAAF;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,EAAA,CAEJ;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"Footer.js","sources":["../../../src/components/Footer/Footer.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface FooterProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** Fallback textual — não utilizado no design padrão, mantido por compatibilidade */\n logoFallbackText?: string;\n /** URL de imagem para substituir o logo SVG padrão */\n logoSrc?: string;\n /** Texto antes do logo (ex.: \"Powered by\") */\n poweredByText?: string;\n}\n\nconst detectTheme = () => {\n if (typeof document === 'undefined') return 'light';\n return document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';\n};\n\ninterface SbkLogoProps {\n color: string;\n height?: number;\n opacity?: number;\n}\n\nconst SbkLogo: React.FC<SbkLogoProps> = ({ color, height = 28, opacity = 1 }) => {\n const aspect = 541.7 / 258.08;\n const width = Math.round(height * aspect);\n return (\n <svg\n aria-label=\"SBK\"\n height={height}\n style={{ opacity }}\n viewBox=\"39.15 180.84 541.7 258.08\"\n width={width}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g transform=\"translate(-49, 122)\">\n <g>\n <g>\n {/* S */}\n <path\n d=\"m225.13 266.26c-27.48 0-47.67-12.07-50.38-41.01h14.16c0.62 21.44 17.69 29.56 36.85 29.56 18.11 0 39.14-7.91 39.14-29.14 0-16.24-13.12-23.74-32.48-29.99l-11.03-3.53c-24.36-7.71-42.27-16.66-42.27-40.19 0-28.1 24.78-39.97 49.76-39.97 22.9 0 46.64 8.54 47.05 35.18h-13.95c-1.87-18.32-15.82-23.94-32.47-23.94-17.29 0-36.65 7.71-36.65 27.69 0 14.78 11.04 22.28 34.36 29.77l12.49 3.96c24.36 7.7 38.3 15.82 38.93 38.73 0 30.18-26.65 42.88-53.51 42.88z\"\n fill={color}\n stroke={color}\n strokeMiterlimit={10}\n strokeWidth={2}\n />\n {/* B */}\n <path\n d=\"m351.42 264.39h-41.43v-150.53h41.43c8.53 0 17.9-0.2 26.23 2.09 16.24 4.58 27.48 17.9 27.48 35.18 0 18.74-10.41 29.98-27.9 34.56 20.82 2.71 34.15 15.2 34.15 36.85 0 34.56-31.86 41.85-59.96 41.85zm8.12-138.45h-36.02v56.49h32.06c19.16 0 34.98-8.81 34.98-30.26 0-18.74-14.16-26.23-31.02-26.23zm-1.46 63.19h-34.56v63.18h26.65c21.86 0 46.84-1.45 46.84-29.98 0-24.77-18.11-33.2-38.93-33.2z\"\n fill={color}\n fillRule=\"evenodd\"\n stroke={color}\n strokeMiterlimit={10}\n strokeWidth={2}\n />\n {/* K */}\n <path\n d=\"m443.77 264.39v-150.53h13.53v150.53zm88.07 0l-73.7-81.61 67.03-68.92h18.12l-68.91 67.88 75.99 82.65z\"\n fill={color}\n stroke={color}\n strokeMiterlimit={10}\n strokeWidth={2}\n />\n </g>\n <g>\n {/* Arco superior */}\n <path\n d=\"m99.09 118.17l-0.21 57.98-9.73 0.24 0.56-62.81c0.26-29.03 26.91-53.16 56.3-53.26l151.74-0.48c0.62 3.58 0.63 6.35 0.05 9.92l-150.35 0.22c-26.28 0.04-48.26 21.9-48.36 48.19z\"\n fill={color}\n />\n {/* Arco inferior */}\n <path\n d=\"m419.9 315.79l0.22-9.33 149.3-0.15c25.73-0.02 48.97-20.27 49.14-45.96l0.4-60.49q4.64-0.28 9.57-0.07l0.32 52.61c0.21 33.16-23.62 63.29-57.93 63.33l-135.88 0.19z\"\n fill={color}\n />\n </g>\n </g>\n </g>\n </svg>\n );\n};\n\nexport const Footer: React.FC<FooterProps> = ({\n poweredByText = 'Powered by',\n logoSrc,\n logoAlt = 'SBK',\n className = '',\n}) => {\n const [theme, setTheme] = useState<'light' | 'dark'>(() => detectTheme() as 'light' | 'dark');\n\n useEffect(() => {\n const sync = () => setTheme(detectTheme() as 'light' | 'dark');\n sync();\n if (typeof MutationObserver === 'undefined') return;\n const observer = new MutationObserver(sync);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });\n return () => observer.disconnect();\n }, []);\n\n const isDark = theme === 'dark';\n\n return (\n <footer\n className={cn(\n 'relative z-[1] w-full shrink-0 box-border',\n 'flex items-center justify-center',\n 'py-5 px-14',\n 'border-t border-[var(--border-color)]',\n 'bg-[var(--bg-secondary)]',\n className,\n )}\n >\n <div className=\"flex items-center gap-2.5\">\n {poweredByText && (\n <span className=\"font-primary text-xs font-normal text-[var(--text-muted)]\">\n {poweredByText}\n </span>\n )}\n\n {logoSrc ? (\n <img\n alt={logoAlt}\n src={logoSrc}\n className=\"h-7 w-auto object-contain\"\n style={{ opacity: isDark ? 0.65 : 0.75 }}\n />\n ) : (\n <SbkLogo\n color={isDark ? '#ffffff' : '#1F3A3A'}\n height={28}\n opacity={isDark ? 0.65 : 0.75}\n />\n )}\n </div>\n </footer>\n );\n};\n\nFooter.displayName = 'Footer';\n"],"names":["detectTheme","SbkLogo","color","height","opacity","width","jsx","jsxs","Footer","poweredByText","logoSrc","logoAlt","className","theme","setTheme","useState","useEffect","sync","observer","isDark","cn"],"mappings":";;;AAiBA,MAAMA,IAAc,MACd,OAAO,WAAa,MAAoB,UACrC,SAAS,gBAAgB,aAAa,YAAY,MAAM,SAAS,SAAS,SAS7EC,IAAkC,CAAC,EAAE,OAAAC,GAAO,QAAAC,IAAS,IAAI,SAAAC,IAAU,QAAQ;AAE/E,QAAMC,IAAQ,KAAK,MAAMF,IADV,iBACyB;AACxC,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,cAAW;AAAA,MACX,QAAAH;AAAA,MACA,OAAO,EAAE,SAAAC,EAAA;AAAA,MACT,SAAQ;AAAA,MACR,OAAAC;AAAA,MACA,OAAM;AAAA,MAEN,UAAA,gBAAAC,EAAC,KAAA,EAAE,WAAU,uBACX,4BAAC,KAAA,EACC,UAAA;AAAA,QAAA,gBAAAC,EAAC,KAAA,EAEC,UAAA;AAAA,UAAA,gBAAAD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAMJ;AAAA,cACN,QAAQA;AAAA,cACR,kBAAkB;AAAA,cAClB,aAAa;AAAA,YAAA;AAAA,UAAA;AAAA,UAGf,gBAAAI;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAMJ;AAAA,cACN,UAAS;AAAA,cACT,QAAQA;AAAA,cACR,kBAAkB;AAAA,cAClB,aAAa;AAAA,YAAA;AAAA,UAAA;AAAA,UAGf,gBAAAI;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAMJ;AAAA,cACN,QAAQA;AAAA,cACR,kBAAkB;AAAA,cAClB,aAAa;AAAA,YAAA;AAAA,UAAA;AAAA,QACf,GACF;AAAA,0BACC,KAAA,EAEC,UAAA;AAAA,UAAA,gBAAAI;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAMJ;AAAA,YAAA;AAAA,UAAA;AAAA,UAGR,gBAAAI;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,GAAE;AAAA,cACF,MAAMJ;AAAA,YAAA;AAAA,UAAA;AAAA,QACR,EAAA,CACF;AAAA,MAAA,EAAA,CACF,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN,GAEaM,IAAgC,CAAC;AAAA,EAC5C,eAAAC,IAAgB;AAAA,EAChB,SAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,WAAAC,IAAY;AACd,MAAM;AACJ,QAAM,CAACC,GAAOC,CAAQ,IAAIC,EAA2B,MAAMf,GAAiC;AAE5F,EAAAgB,EAAU,MAAM;AACd,UAAMC,IAAO,MAAMH,EAASd,GAAiC;AAE7D,QADAiB,EAAA,GACI,OAAO,mBAAqB,IAAa;AAC7C,UAAMC,IAAW,IAAI,iBAAiBD,CAAI;AAC1C,WAAAC,EAAS,QAAQ,SAAS,iBAAiB,EAAE,YAAY,IAAM,iBAAiB,CAAC,YAAY,GAAG,GACzF,MAAMA,EAAS,WAAA;AAAA,EACxB,GAAG,CAAA,CAAE;AAEL,QAAMC,IAASN,MAAU;AAEzB,SACE,gBAAAP;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWc;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAR;AAAA,MAAA;AAAA,MAGF,UAAA,gBAAAL,EAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,QAAAE,KACC,gBAAAH,EAAC,QAAA,EAAK,WAAU,6DACb,UAAAG,GACH;AAAA,QAGDC,IACC,gBAAAJ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKK;AAAA,YACL,KAAKD;AAAA,YACL,WAAU;AAAA,YACV,OAAO,EAAE,SAASS,IAAS,OAAO,KAAA;AAAA,UAAK;AAAA,QAAA,IAGzC,gBAAAb;AAAA,UAACL;AAAA,UAAA;AAAA,YACC,OAAOkB,IAAS,YAAY;AAAA,YAC5B,QAAQ;AAAA,YACR,SAASA,IAAS,OAAO;AAAA,UAAA;AAAA,QAAA;AAAA,MAC3B,EAAA,CAEJ;AAAA,IAAA;AAAA,EAAA;AAGN;AAEAX,EAAO,cAAc;"}
@@ -5,19 +5,25 @@ export interface HeaderProps {
5
5
  className?: string;
6
6
  /** Texto alternativo do logo */
7
7
  logoAlt?: string;
8
- /** URL da imagem do logo (tema escuro). Se não informado, usa logoSrc. */
8
+ /** URL de imagem para substituir o logo SVG padrão (tema escuro) */
9
9
  logoDarkSrc?: string;
10
- /** URL da imagem do logo (tema claro) */
10
+ /** URL de imagem para substituir o logo SVG padrão (tema claro) */
11
11
  logoSrc?: string;
12
+ /** Callback ao clicar no ícone de menu (hamburger) */
13
+ onMenuClick?: () => void;
12
14
  /** Callback ao clicar na área do logo/título */
13
15
  onLogoClick?: () => void;
14
- /** Conteúdo da área direita (ex.: seletor de idioma, toggle tema, menu usuário) */
16
+ /** Conteúdo da área direita (pills de idioma/tema, etc.) */
15
17
  rightContent?: React.ReactNode;
18
+ /** Exibe o ícone hamburger à esquerda — padrão: true */
19
+ showMenuIcon?: boolean;
16
20
  /** Subtítulo abaixo do título */
17
21
  subtitle?: React.ReactNode;
18
- /** Tema opcional para escolher o logo correto sem depender do ThemeProvider do UI */
22
+ /** Tema opcional para escolher o logo correto sem depender do ThemeProvider */
19
23
  theme?: Theme;
20
- /** Título exibido ao lado do logo (ex.: "OFÍCIO.IA") */
24
+ /** Título exibido ao lado do logo */
21
25
  title?: React.ReactNode;
26
+ /** Iniciais do usuário no avatar circular turquesa (ex.: "CF") */
27
+ userInitials?: string;
22
28
  }
23
29
  export declare const Header: React.FC<HeaderProps>;
@@ -1,114 +1,174 @@
1
- import { jsxs as a, jsx as r } from "react/jsx-runtime";
2
- import { useState as u, useEffect as x } from "react";
3
- const v = () => typeof document > "u" ? "light" : document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light", M = ({
4
- logoSrc: h,
5
- logoDarkSrc: i,
6
- logoAlt: p = "Logo",
7
- title: l,
1
+ import { jsxs as t, jsx as e } from "react/jsx-runtime";
2
+ import { useState as y, useEffect as N } from "react";
3
+ import { cn as o } from "../../utils/cn.js";
4
+ const p = () => typeof document > "u" ? "light" : document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light", z = ({ height: n = 36 }) => {
5
+ const l = Math.round(n * 2.098961562306262);
6
+ return /* @__PURE__ */ e(
7
+ "svg",
8
+ {
9
+ "aria-label": "SBK",
10
+ height: n,
11
+ viewBox: "39.15 180.84 541.7 258.08",
12
+ width: l,
13
+ xmlns: "http://www.w3.org/2000/svg",
14
+ children: /* @__PURE__ */ e("g", { transform: "translate(-49, 122)", children: /* @__PURE__ */ t("g", { children: [
15
+ /* @__PURE__ */ t("g", { children: [
16
+ /* @__PURE__ */ e(
17
+ "path",
18
+ {
19
+ d: "m225.13 266.26c-27.48 0-47.67-12.07-50.38-41.01h14.16c0.62 21.44 17.69 29.56 36.85 29.56 18.11 0 39.14-7.91 39.14-29.14 0-16.24-13.12-23.74-32.48-29.99l-11.03-3.53c-24.36-7.71-42.27-16.66-42.27-40.19 0-28.1 24.78-39.97 49.76-39.97 22.9 0 46.64 8.54 47.05 35.18h-13.95c-1.87-18.32-15.82-23.94-32.47-23.94-17.29 0-36.65 7.71-36.65 27.69 0 14.78 11.04 22.28 34.36 29.77l12.49 3.96c24.36 7.7 38.3 15.82 38.93 38.73 0 30.18-26.65 42.88-53.51 42.88z",
20
+ fill: "#ffffff",
21
+ stroke: "#ffffff",
22
+ strokeMiterlimit: 10,
23
+ strokeWidth: 2
24
+ }
25
+ ),
26
+ /* @__PURE__ */ e(
27
+ "path",
28
+ {
29
+ d: "m351.42 264.39h-41.43v-150.53h41.43c8.53 0 17.9-0.2 26.23 2.09 16.24 4.58 27.48 17.9 27.48 35.18 0 18.74-10.41 29.98-27.9 34.56 20.82 2.71 34.15 15.2 34.15 36.85 0 34.56-31.86 41.85-59.96 41.85zm8.12-138.45h-36.02v56.49h32.06c19.16 0 34.98-8.81 34.98-30.26 0-18.74-14.16-26.23-31.02-26.23zm-1.46 63.19h-34.56v63.18h26.65c21.86 0 46.84-1.45 46.84-29.98 0-24.77-18.11-33.2-38.93-33.2z",
30
+ fill: "#ffffff",
31
+ fillRule: "evenodd",
32
+ stroke: "#ffffff",
33
+ strokeMiterlimit: 10,
34
+ strokeWidth: 2
35
+ }
36
+ ),
37
+ /* @__PURE__ */ e(
38
+ "path",
39
+ {
40
+ d: "m443.77 264.39v-150.53h13.53v150.53zm88.07 0l-73.7-81.61 67.03-68.92h18.12l-68.91 67.88 75.99 82.65z",
41
+ fill: "#ffffff",
42
+ stroke: "#ffffff",
43
+ strokeMiterlimit: 10,
44
+ strokeWidth: 2
45
+ }
46
+ )
47
+ ] }),
48
+ /* @__PURE__ */ t("g", { children: [
49
+ /* @__PURE__ */ e(
50
+ "path",
51
+ {
52
+ d: "m99.09 118.17l-0.21 57.98-9.73 0.24 0.56-62.81c0.26-29.03 26.91-53.16 56.3-53.26l151.74-0.48c0.62 3.58 0.63 6.35 0.05 9.92l-150.35 0.22c-26.28 0.04-48.26 21.9-48.36 48.19z",
53
+ fill: "#ffffff"
54
+ }
55
+ ),
56
+ /* @__PURE__ */ e(
57
+ "path",
58
+ {
59
+ d: "m419.9 315.79l0.22-9.33 149.3-0.15c25.73-0.02 48.97-20.27 49.14-45.96l0.4-60.49q4.64-0.28 9.57-0.07l0.32 52.61c0.21 33.16-23.62 63.29-57.93 63.33l-135.88 0.19z",
60
+ fill: "#ffffff"
61
+ }
62
+ )
63
+ ] })
64
+ ] }) })
65
+ }
66
+ );
67
+ }, M = ({ onClick: n }) => /* @__PURE__ */ t(
68
+ "button",
69
+ {
70
+ "aria-label": "Abrir menu",
71
+ onClick: n,
72
+ type: "button",
73
+ className: o(
74
+ "flex flex-col gap-1 shrink-0 bg-transparent border-none p-1.5",
75
+ n ? "cursor-pointer" : "cursor-default"
76
+ ),
77
+ children: [
78
+ /* @__PURE__ */ e("span", { className: "block w-5 h-0.5 bg-sbk-verde-vibrante rounded-[2px]" }),
79
+ /* @__PURE__ */ e("span", { className: "block w-5 h-0.5 bg-sbk-verde-vibrante rounded-[2px]" }),
80
+ /* @__PURE__ */ e("span", { className: "block w-5 h-0.5 bg-sbk-verde-vibrante rounded-[2px]" })
81
+ ]
82
+ }
83
+ ), j = ({
84
+ logoSrc: n,
85
+ logoDarkSrc: f,
86
+ logoAlt: l = "SBK",
87
+ title: i,
8
88
  subtitle: d,
9
- theme: s,
10
- onLogoClick: e,
11
- rightContent: m,
12
- className: b = ""
89
+ theme: a,
90
+ onLogoClick: r,
91
+ onMenuClick: b,
92
+ rightContent: v,
93
+ showMenuIcon: x = !0,
94
+ userInitials: c,
95
+ className: g = ""
13
96
  }) => {
14
- const [o, w] = u(!1), [y, c] = u(() => s ?? v()), f = y === "dark" && i ? i : h;
15
- x(() => {
16
- const t = () => w(window.scrollY > 10);
17
- return window.addEventListener("scroll", t, { passive: !0 }), () => window.removeEventListener("scroll", t);
18
- }, []), x(() => {
19
- if (s) {
20
- c(s);
97
+ const [k, m] = y(() => a ?? p()), h = k === "dark" && f ? f : n;
98
+ N(() => {
99
+ if (a) {
100
+ m(a);
21
101
  return;
22
102
  }
23
- const t = () => c(v());
24
- if (t(), typeof MutationObserver > "u")
25
- return;
26
- const n = new MutationObserver(t);
27
- return n.observe(document.documentElement, {
28
- attributes: !0,
29
- attributeFilter: ["data-theme"]
30
- }), () => n.disconnect();
31
- }, [s]);
32
- const N = () => e == null ? void 0 : e(), E = (t) => {
33
- t.key === "Enter" && (e == null || e());
103
+ const s = () => m(p());
104
+ if (s(), typeof MutationObserver > "u") return;
105
+ const u = new MutationObserver(s);
106
+ return u.observe(document.documentElement, { attributes: !0, attributeFilter: ["data-theme"] }), () => u.disconnect();
107
+ }, [a]);
108
+ const w = (s) => {
109
+ s.key === "Enter" && (r == null || r());
34
110
  };
35
- return /* @__PURE__ */ a(
111
+ return /* @__PURE__ */ t(
36
112
  "header",
37
113
  {
38
- className: ["fixed inset-x-0 top-0 z-[1000] w-full backdrop-blur-[12px]", b].filter(Boolean).join(" "),
114
+ className: o(
115
+ "sticky top-0 z-[1000] w-full h-16 shrink-0 box-border",
116
+ "bg-sbk-verde-profundo",
117
+ "flex items-center justify-between",
118
+ "px-14",
119
+ g
120
+ ),
39
121
  children: [
40
- /* @__PURE__ */ r("div", { className: "h-0.5 w-full bg-[var(--md-primary)]" }),
41
- /* @__PURE__ */ a(
42
- "div",
43
- {
44
- className: "flex items-center justify-between px-6 py-2 shadow-[var(--shadow-sm)] max-md:flex-col max-md:gap-3 max-md:px-4 max-md:py-3",
45
- style: {
46
- color: "var(--md-on-surface)",
47
- background: `color-mix(in srgb, var(--md-surface) ${o ? "14%" : "18%"}, transparent)`,
48
- borderBottom: `1px solid color-mix(in srgb, var(--md-outline-variant) ${o ? "22%" : "30%"}, transparent)`
49
- },
50
- children: [
51
- /* @__PURE__ */ a(
52
- "div",
53
- {
54
- className: "flex cursor-pointer items-center gap-3 transition-opacity duration-200 ease-in-out hover:opacity-80",
55
- onClick: e ? N : void 0,
56
- onKeyDown: e ? E : void 0,
57
- role: e ? "button" : void 0,
58
- tabIndex: e ? 0 : void 0,
59
- children: [
60
- f && /* @__PURE__ */ a("div", { className: "flex h-16 w-16 shrink-0 items-center justify-center", children: [
61
- /* @__PURE__ */ r(
62
- "img",
63
- {
64
- alt: p,
65
- className: "h-full w-full object-contain",
66
- onError: (t) => {
67
- t.target.style.display = "none";
68
- const n = t.target.nextElementSibling;
69
- n && (n.style.display = "block");
70
- },
71
- src: f
72
- }
73
- ),
74
- /* @__PURE__ */ a(
75
- "svg",
76
- {
77
- className: "hidden h-full w-full",
78
- fill: "none",
79
- stroke: "currentColor",
80
- strokeWidth: "2",
81
- viewBox: "0 0 24 24",
82
- children: [
83
- /* @__PURE__ */ r("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
84
- /* @__PURE__ */ r("path", { d: "M2 17l10 5 10-5M2 12l10 5 10-5" })
85
- ]
86
- }
87
- )
88
- ] }),
89
- (l || d) && /* @__PURE__ */ a("div", { className: "flex flex-col gap-1", children: [
90
- l && /* @__PURE__ */ r(
91
- "h1",
92
- {
93
- className: "m-0 inline-flex items-baseline text-[1.375rem] font-bold leading-[1.2] tracking-[0.05em] text-[var(--md-on-surface)] max-md:text-xl",
94
- style: { fontFamily: "var(--font-logo)" },
95
- children: l
96
- }
97
- ),
98
- d && /* @__PURE__ */ r("p", { className: "m-0 text-[0.8125rem] font-normal text-[var(--md-on-surface-variant)] max-md:text-xs", children: d })
99
- ] })
100
- ]
101
- }
122
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-3 min-w-0", children: [
123
+ x && /* @__PURE__ */ e(M, { onClick: b }),
124
+ /* @__PURE__ */ t(
125
+ "div",
126
+ {
127
+ onClick: r,
128
+ onKeyDown: r ? w : void 0,
129
+ role: r ? "button" : void 0,
130
+ className: o(
131
+ "flex items-center gap-2.5 select-none",
132
+ r ? "cursor-pointer" : "cursor-default"
102
133
  ),
103
- m && /* @__PURE__ */ r("div", { className: "flex shrink-0 items-center gap-3 max-md:w-full max-md:flex-wrap max-md:justify-between", children: m })
104
- ]
105
- }
106
- )
134
+ tabIndex: r ? 0 : void 0,
135
+ children: [
136
+ h ? /* @__PURE__ */ e(
137
+ "img",
138
+ {
139
+ alt: l,
140
+ onError: (s) => {
141
+ s.target.style.display = "none";
142
+ },
143
+ src: h,
144
+ className: "h-9 w-auto object-contain shrink-0"
145
+ }
146
+ ) : /* @__PURE__ */ e(z, { height: 36 }),
147
+ (i || d) && /* @__PURE__ */ t("div", { className: "flex flex-col gap-[1px]", children: [
148
+ i && /* @__PURE__ */ e("span", { className: "font-logo text-[1.125rem] font-semibold text-white leading-[1.2] tracking-[0.02em]", children: i }),
149
+ d && /* @__PURE__ */ e("span", { className: "font-primary text-[11px] font-normal text-white/45 leading-[1.3]", children: d })
150
+ ] })
151
+ ]
152
+ }
153
+ )
154
+ ] }),
155
+ /* @__PURE__ */ t("div", { className: "flex items-center gap-2 shrink-0", children: [
156
+ v,
157
+ c && /* @__PURE__ */ e(
158
+ "div",
159
+ {
160
+ "aria-label": `Usuário: ${c}`,
161
+ className: "w-9 h-9 rounded-full bg-sbk-verde-vibrante flex items-center justify-center text-white font-primary font-semibold text-[13px] shrink-0 select-none",
162
+ children: c
163
+ }
164
+ )
165
+ ] })
107
166
  ]
108
167
  }
109
168
  );
110
169
  };
170
+ j.displayName = "Header";
111
171
  export {
112
- M as Header
172
+ j as Header
113
173
  };
114
174
  //# sourceMappingURL=Header.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Header.js","sources":["../../../src/components/Header/Header.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useState } from 'react';\nimport type { Theme } from '../../theme/ThemeProvider';\n\nexport interface HeaderProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** URL da imagem do logo (tema escuro). Se não informado, usa logoSrc. */\n logoDarkSrc?: string;\n /** URL da imagem do logo (tema claro) */\n logoSrc?: string;\n /** Callback ao clicar na área do logo/título */\n onLogoClick?: () => void;\n /** Conteúdo da área direita (ex.: seletor de idioma, toggle tema, menu usuário) */\n rightContent?: React.ReactNode;\n /** Subtítulo abaixo do título */\n subtitle?: React.ReactNode;\n /** Tema opcional para escolher o logo correto sem depender do ThemeProvider do UI */\n theme?: Theme;\n /** Título exibido ao lado do logo (ex.: \"OFÍCIO.IA\") */\n title?: React.ReactNode;\n}\n\nconst detectTheme = (): Theme => {\n if (typeof document === 'undefined') {\n return 'light';\n }\n\n return document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';\n};\n\nexport const Header: React.FC<HeaderProps> = ({\n logoSrc,\n logoDarkSrc,\n logoAlt = 'Logo',\n title,\n subtitle,\n theme,\n onLogoClick,\n rightContent,\n className = '',\n}) => {\n const [isScrolled, setIsScrolled] = useState(false);\n const [resolvedTheme, setResolvedTheme] = useState<Theme>(() => theme ?? detectTheme());\n\n const logoSrcResolved = resolvedTheme === 'dark' && logoDarkSrc ? logoDarkSrc : logoSrc;\n\n useEffect(() => {\n const handleScroll = () => setIsScrolled(window.scrollY > 10);\n window.addEventListener('scroll', handleScroll, { passive: true });\n return () => window.removeEventListener('scroll', handleScroll);\n }, []);\n\n useEffect(() => {\n if (theme) {\n setResolvedTheme(theme);\n return;\n }\n\n const syncTheme = () => setResolvedTheme(detectTheme());\n syncTheme();\n\n if (typeof MutationObserver === 'undefined') {\n return;\n }\n\n const observer = new MutationObserver(syncTheme);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-theme'],\n });\n\n return () => observer.disconnect();\n }, [theme]);\n\n const handleClick = () => onLogoClick?.();\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n onLogoClick?.();\n }\n };\n\n return (\n <header\n className={['fixed inset-x-0 top-0 z-[1000] w-full backdrop-blur-[12px]', className]\n .filter(Boolean)\n .join(' ')}\n >\n <div className=\"h-0.5 w-full bg-[var(--md-primary)]\" />\n <div\n className=\"flex items-center justify-between px-6 py-2 shadow-[var(--shadow-sm)] max-md:flex-col max-md:gap-3 max-md:px-4 max-md:py-3\"\n style={{\n color: 'var(--md-on-surface)',\n background: `color-mix(in srgb, var(--md-surface) ${\n isScrolled ? '14%' : '18%'\n }, transparent)`,\n borderBottom: `1px solid color-mix(in srgb, var(--md-outline-variant) ${\n isScrolled ? '22%' : '30%'\n }, transparent)`,\n }}\n >\n <div\n className=\"flex cursor-pointer items-center gap-3 transition-opacity duration-200 ease-in-out hover:opacity-80\"\n onClick={onLogoClick ? handleClick : undefined}\n onKeyDown={onLogoClick ? handleKeyDown : undefined}\n role={onLogoClick ? 'button' : undefined}\n tabIndex={onLogoClick ? 0 : undefined}\n >\n {logoSrcResolved && (\n <div className=\"flex h-16 w-16 shrink-0 items-center justify-center\">\n <img\n alt={logoAlt}\n className=\"h-full w-full object-contain\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none';\n const next = (e.target as HTMLElement).nextElementSibling as HTMLElement;\n if (next) {\n next.style.display = 'block';\n }\n }}\n src={logoSrcResolved}\n />\n <svg\n className=\"hidden h-full w-full\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\" />\n <path d=\"M2 17l10 5 10-5M2 12l10 5 10-5\" />\n </svg>\n </div>\n )}\n {(title || subtitle) && (\n <div className=\"flex flex-col gap-1\">\n {title && (\n <h1\n className=\"m-0 inline-flex items-baseline text-[1.375rem] font-bold leading-[1.2] tracking-[0.05em] text-[var(--md-on-surface)] max-md:text-xl\"\n style={{ fontFamily: 'var(--font-logo)' }}\n >\n {title}\n </h1>\n )}\n {subtitle && (\n <p className=\"m-0 text-[0.8125rem] font-normal text-[var(--md-on-surface-variant)] max-md:text-xs\">\n {subtitle}\n </p>\n )}\n </div>\n )}\n </div>\n {rightContent && (\n <div className=\"flex shrink-0 items-center gap-3 max-md:w-full max-md:flex-wrap max-md:justify-between\">\n {rightContent}\n </div>\n )}\n </div>\n </header>\n );\n};\n"],"names":["detectTheme","Header","logoSrc","logoDarkSrc","logoAlt","title","subtitle","theme","onLogoClick","rightContent","className","isScrolled","setIsScrolled","useState","resolvedTheme","setResolvedTheme","logoSrcResolved","useEffect","handleScroll","syncTheme","observer","handleClick","handleKeyDown","e","jsxs","jsx","next"],"mappings":"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"}
1
+ {"version":3,"file":"Header.js","sources":["../../../src/components/Header/Header.tsx"],"sourcesContent":["import type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { cn } from '../../utils/cn';\nimport type { Theme } from '../../theme/ThemeProvider';\n\nexport interface HeaderProps {\n /** Classe CSS adicional */\n className?: string;\n /** Texto alternativo do logo */\n logoAlt?: string;\n /** URL de imagem para substituir o logo SVG padrão (tema escuro) */\n logoDarkSrc?: string;\n /** URL de imagem para substituir o logo SVG padrão (tema claro) */\n logoSrc?: string;\n /** Callback ao clicar no ícone de menu (hamburger) */\n onMenuClick?: () => void;\n /** Callback ao clicar na área do logo/título */\n onLogoClick?: () => void;\n /** Conteúdo da área direita (pills de idioma/tema, etc.) */\n rightContent?: React.ReactNode;\n /** Exibe o ícone hamburger à esquerda — padrão: true */\n showMenuIcon?: boolean;\n /** Subtítulo abaixo do título */\n subtitle?: React.ReactNode;\n /** Tema opcional para escolher o logo correto sem depender do ThemeProvider */\n theme?: Theme;\n /** Título exibido ao lado do logo */\n title?: React.ReactNode;\n /** Iniciais do usuário no avatar circular turquesa (ex.: \"CF\") */\n userInitials?: string;\n}\n\nconst detectTheme = (): Theme => {\n if (typeof document === 'undefined') return 'light';\n return document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light';\n};\n\nconst SbkLogoWhite: React.FC<{ height?: number }> = ({ height = 36 }) => {\n const aspect = 541.7 / 258.08;\n const width = Math.round(height * aspect);\n return (\n <svg\n aria-label=\"SBK\"\n height={height}\n viewBox=\"39.15 180.84 541.7 258.08\"\n width={width}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g transform=\"translate(-49, 122)\">\n <g>\n <g>\n {/* S */}\n <path\n d=\"m225.13 266.26c-27.48 0-47.67-12.07-50.38-41.01h14.16c0.62 21.44 17.69 29.56 36.85 29.56 18.11 0 39.14-7.91 39.14-29.14 0-16.24-13.12-23.74-32.48-29.99l-11.03-3.53c-24.36-7.71-42.27-16.66-42.27-40.19 0-28.1 24.78-39.97 49.76-39.97 22.9 0 46.64 8.54 47.05 35.18h-13.95c-1.87-18.32-15.82-23.94-32.47-23.94-17.29 0-36.65 7.71-36.65 27.69 0 14.78 11.04 22.28 34.36 29.77l12.49 3.96c24.36 7.7 38.3 15.82 38.93 38.73 0 30.18-26.65 42.88-53.51 42.88z\"\n fill=\"#ffffff\"\n stroke=\"#ffffff\"\n strokeMiterlimit={10}\n strokeWidth={2}\n />\n {/* B */}\n <path\n d=\"m351.42 264.39h-41.43v-150.53h41.43c8.53 0 17.9-0.2 26.23 2.09 16.24 4.58 27.48 17.9 27.48 35.18 0 18.74-10.41 29.98-27.9 34.56 20.82 2.71 34.15 15.2 34.15 36.85 0 34.56-31.86 41.85-59.96 41.85zm8.12-138.45h-36.02v56.49h32.06c19.16 0 34.98-8.81 34.98-30.26 0-18.74-14.16-26.23-31.02-26.23zm-1.46 63.19h-34.56v63.18h26.65c21.86 0 46.84-1.45 46.84-29.98 0-24.77-18.11-33.2-38.93-33.2z\"\n fill=\"#ffffff\"\n fillRule=\"evenodd\"\n stroke=\"#ffffff\"\n strokeMiterlimit={10}\n strokeWidth={2}\n />\n {/* K */}\n <path\n d=\"m443.77 264.39v-150.53h13.53v150.53zm88.07 0l-73.7-81.61 67.03-68.92h18.12l-68.91 67.88 75.99 82.65z\"\n fill=\"#ffffff\"\n stroke=\"#ffffff\"\n strokeMiterlimit={10}\n strokeWidth={2}\n />\n </g>\n <g>\n {/* Arco superior */}\n <path\n d=\"m99.09 118.17l-0.21 57.98-9.73 0.24 0.56-62.81c0.26-29.03 26.91-53.16 56.3-53.26l151.74-0.48c0.62 3.58 0.63 6.35 0.05 9.92l-150.35 0.22c-26.28 0.04-48.26 21.9-48.36 48.19z\"\n fill=\"#ffffff\"\n />\n {/* Arco inferior */}\n <path\n d=\"m419.9 315.79l0.22-9.33 149.3-0.15c25.73-0.02 48.97-20.27 49.14-45.96l0.4-60.49q4.64-0.28 9.57-0.07l0.32 52.61c0.21 33.16-23.62 63.29-57.93 63.33l-135.88 0.19z\"\n fill=\"#ffffff\"\n />\n </g>\n </g>\n </g>\n </svg>\n );\n};\n\nconst HamburgerIcon: React.FC<{ onClick?: () => void }> = ({ onClick }) => (\n <button\n aria-label=\"Abrir menu\"\n onClick={onClick}\n type=\"button\"\n className={cn(\n 'flex flex-col gap-1 shrink-0 bg-transparent border-none p-1.5',\n onClick ? 'cursor-pointer' : 'cursor-default',\n )}\n >\n <span className=\"block w-5 h-0.5 bg-sbk-verde-vibrante rounded-[2px]\" />\n <span className=\"block w-5 h-0.5 bg-sbk-verde-vibrante rounded-[2px]\" />\n <span className=\"block w-5 h-0.5 bg-sbk-verde-vibrante rounded-[2px]\" />\n </button>\n);\n\nexport const Header: React.FC<HeaderProps> = ({\n logoSrc,\n logoDarkSrc,\n logoAlt = 'SBK',\n title,\n subtitle,\n theme,\n onLogoClick,\n onMenuClick,\n rightContent,\n showMenuIcon = true,\n userInitials,\n className = '',\n}) => {\n const [resolvedTheme, setResolvedTheme] = useState<Theme>(() => theme ?? detectTheme());\n\n const logoSrcResolved = resolvedTheme === 'dark' && logoDarkSrc ? logoDarkSrc : logoSrc;\n\n useEffect(() => {\n if (theme) {\n setResolvedTheme(theme);\n return;\n }\n const syncTheme = () => setResolvedTheme(detectTheme());\n syncTheme();\n if (typeof MutationObserver === 'undefined') return;\n const observer = new MutationObserver(syncTheme);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });\n return () => observer.disconnect();\n }, [theme]);\n\n const handleLogoKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') onLogoClick?.();\n };\n\n return (\n <header\n className={cn(\n 'sticky top-0 z-[1000] w-full h-16 shrink-0 box-border',\n 'bg-sbk-verde-profundo',\n 'flex items-center justify-between',\n 'px-14',\n className,\n )}\n >\n {/* ── Esquerda: hamburger + logo ── */}\n <div className=\"flex items-center gap-3 min-w-0\">\n {showMenuIcon && <HamburgerIcon onClick={onMenuClick} />}\n\n <div\n onClick={onLogoClick}\n onKeyDown={onLogoClick ? handleLogoKeyDown : undefined}\n role={onLogoClick ? 'button' : undefined}\n className={cn(\n 'flex items-center gap-2.5 select-none',\n onLogoClick ? 'cursor-pointer' : 'cursor-default',\n )}\n tabIndex={onLogoClick ? 0 : undefined}\n >\n {logoSrcResolved ? (\n <img\n alt={logoAlt}\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none';\n }}\n src={logoSrcResolved}\n className=\"h-9 w-auto object-contain shrink-0\"\n />\n ) : (\n <SbkLogoWhite height={36} />\n )}\n\n {(title || subtitle) && (\n <div className=\"flex flex-col gap-[1px]\">\n {title && (\n <span className=\"font-logo text-[1.125rem] font-semibold text-white leading-[1.2] tracking-[0.02em]\">\n {title}\n </span>\n )}\n {subtitle && (\n <span className=\"font-primary text-[11px] font-normal text-white/45 leading-[1.3]\">\n {subtitle}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n\n {/* ── Direita: pills + avatar ── */}\n <div className=\"flex items-center gap-2 shrink-0\">\n {rightContent}\n {userInitials && (\n <div\n aria-label={`Usuário: ${userInitials}`}\n className=\"w-9 h-9 rounded-full bg-sbk-verde-vibrante flex items-center justify-center text-white font-primary font-semibold text-[13px] shrink-0 select-none\"\n >\n {userInitials}\n </div>\n )}\n </div>\n </header>\n );\n};\n\nHeader.displayName = 'Header';\n"],"names":["detectTheme","SbkLogoWhite","height","width","jsx","jsxs","HamburgerIcon","onClick","cn","Header","logoSrc","logoDarkSrc","logoAlt","title","subtitle","theme","onLogoClick","onMenuClick","rightContent","showMenuIcon","userInitials","className","resolvedTheme","setResolvedTheme","useState","logoSrcResolved","useEffect","syncTheme","observer","handleLogoKeyDown","e"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type React from 'react';
2
+ export interface ProgressBarProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /** Label descritivo para leitores de tela. */
4
+ label?: string;
5
+ /** Valor atual (0–100). */
6
+ value: number;
7
+ size?: 'sm' | 'md' | 'lg';
8
+ tone?: 'primary' | 'success' | 'warning' | 'error' | 'info';
9
+ /** Exibe o percentual como texto ao lado da barra. */
10
+ showValue?: boolean;
11
+ }
12
+ export declare const ProgressBar: React.FC<ProgressBarProps>;
@@ -0,0 +1,7 @@
1
+ import type React from 'react';
2
+ export interface SpinnerProps extends React.SVGAttributes<SVGSVGElement> {
3
+ /** Texto anunciado para leitores de tela. Padrão: 'Carregando...' */
4
+ label?: string;
5
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
6
+ }
7
+ export declare const Spinner: React.FC<SpinnerProps>;