@gyramais/gyra-design 0.2.31 → 0.2.33

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,28 @@
1
+ import React from "react";
2
+ import "./index.css";
3
+ export type GaugeBandVariant = "neutral" | "success" | "warning" | "danger";
4
+ /** Formata o valor central: inteiro sem casas, fracionado com 1 casa, ausente "—". */
5
+ export declare const formatGaugeValue: (v?: number | null) => string;
6
+ export type GaugeProps = {
7
+ id?: string;
8
+ className?: string;
9
+ /** Valor atual (0..max). null/undefined => mostra "—" e anel vazio. */
10
+ value?: number | null;
11
+ /** Máximo da escala. Default 1000 (escala dos bureaus de crédito). */
12
+ max?: number;
13
+ /** Legenda curta acima do número (ex.: "GYRA+ Score"). */
14
+ label: string;
15
+ /** Pill de classificação abaixo do número (ex.: "Risco baixo"). Opcional. */
16
+ band?: string;
17
+ /** Cor do pill de banda; o anel permanece azul. Default "neutral". */
18
+ bandVariant?: GaugeBandVariant;
19
+ /** Diâmetro em px (escala número/legenda proporcionalmente). Default 240. */
20
+ size?: number;
21
+ };
22
+ /**
23
+ * Gauge circular de score (anel azul). Usado para o score da política de
24
+ * crédito, score setorial e afins. O número e a legenda escalam com `size`.
25
+ */
26
+ declare const Gauge: ({ id, className, value, max, label, band, bandVariant, size, }: GaugeProps) => React.JSX.Element;
27
+ export { Gauge };
28
+ export default Gauge;
@@ -0,0 +1,2 @@
1
+ export * from "./Gauge";
2
+ export { default } from "./Gauge";
@@ -11,7 +11,15 @@ type SyncChipProps = {
11
11
  errorTooltip?: string;
12
12
  /** Optional override for the tooltip when verified is false. */
13
13
  notVerifiedTooltip?: string;
14
+ /** When in error state and provided, renders a compact retry action to
15
+ the LEFT of the chip. Keeps the retry paired with its sync-status,
16
+ consistently across every usage. */
17
+ onRetry?: () => void;
18
+ /** Label for the retry action. */
19
+ retryLabel?: string;
20
+ /** Disables the retry action (e.g. while a retry is already in flight). */
21
+ retryDisabled?: boolean;
14
22
  };
15
- declare const SyncChip: ({ id, className, loading, date, error, verified, errorTooltip, notVerifiedTooltip, }: SyncChipProps) => React.JSX.Element;
23
+ declare const SyncChip: ({ id, className, loading, date, error, verified, errorTooltip, notVerifiedTooltip, onRetry, retryLabel, retryDisabled, }: SyncChipProps) => React.JSX.Element;
16
24
  export { SyncChip };
17
25
  export type { SyncChipProps };
@@ -21,6 +21,7 @@ import "./components/Empty/index.css";
21
21
  import "./components/Filter/index.css";
22
22
  import "./components/FloatingCard/index.css";
23
23
  import "./components/Form/index.css";
24
+ import "./components/Gauge/index.css";
24
25
  import "./components/HoverCard/index.css";
25
26
  import "./components/Icon/index.css";
26
27
  import "./components/IconDisplay/index.css";
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import "./index.css";
3
+ export type GaugeBandVariant = "neutral" | "success" | "warning" | "danger";
4
+ /** Formata o valor central: inteiro sem casas, fracionado com 1 casa, ausente "—". */
5
+ export declare const formatGaugeValue: (v?: number | null) => string;
6
+ export type GaugeProps = {
7
+ id?: string;
8
+ className?: string;
9
+ /** Valor atual (0..max). null/undefined => mostra "—" e anel vazio. */
10
+ value?: number | null;
11
+ /** Máximo da escala. Default 1000 (escala dos bureaus de crédito). */
12
+ max?: number;
13
+ /** Legenda curta acima do número (ex.: "GYRA+ Score"). */
14
+ label: string;
15
+ /** Pill de classificação abaixo do número (ex.: "Risco baixo"). Opcional. */
16
+ band?: string;
17
+ /** Cor do pill de banda; o anel permanece azul. Default "neutral". */
18
+ bandVariant?: GaugeBandVariant;
19
+ /** Diâmetro em px (escala número/legenda proporcionalmente). Default 240. */
20
+ size?: number;
21
+ };
22
+ /**
23
+ * Gauge circular de score (anel azul). Usado para o score da política de
24
+ * crédito, score setorial e afins. O número e a legenda escalam com `size`.
25
+ */
26
+ declare const Gauge: ({ id, className, value, max, label, band, bandVariant, size, }: GaugeProps) => React.JSX.Element;
27
+ export { Gauge };
28
+ export default Gauge;
@@ -0,0 +1,2 @@
1
+ export * from "./Gauge";
2
+ export { default } from "./Gauge";
@@ -11,7 +11,15 @@ type SyncChipProps = {
11
11
  errorTooltip?: string;
12
12
  /** Optional override for the tooltip when verified is false. */
13
13
  notVerifiedTooltip?: string;
14
+ /** When in error state and provided, renders a compact retry action to
15
+ the LEFT of the chip. Keeps the retry paired with its sync-status,
16
+ consistently across every usage. */
17
+ onRetry?: () => void;
18
+ /** Label for the retry action. */
19
+ retryLabel?: string;
20
+ /** Disables the retry action (e.g. while a retry is already in flight). */
21
+ retryDisabled?: boolean;
14
22
  };
15
- declare const SyncChip: ({ id, className, loading, date, error, verified, errorTooltip, notVerifiedTooltip, }: SyncChipProps) => React.JSX.Element;
23
+ declare const SyncChip: ({ id, className, loading, date, error, verified, errorTooltip, notVerifiedTooltip, onRetry, retryLabel, retryDisabled, }: SyncChipProps) => React.JSX.Element;
16
24
  export { SyncChip };
17
25
  export type { SyncChipProps };
@@ -21,6 +21,7 @@ import "./components/Empty/index.css";
21
21
  import "./components/Filter/index.css";
22
22
  import "./components/FloatingCard/index.css";
23
23
  import "./components/Form/index.css";
24
+ import "./components/Gauge/index.css";
24
25
  import "./components/HoverCard/index.css";
25
26
  import "./components/Icon/index.css";
26
27
  import "./components/IconDisplay/index.css";
package/dist/index.css CHANGED
@@ -6015,6 +6015,79 @@ h6 {
6015
6015
  color: var(--danger-color)
6016
6016
  }
6017
6017
 
6018
+ /* Gauge (CU-86ahzcm82) */
6019
+ /* Gauge circular de score. Diâmetro controlado por --gauge-size; número e
6020
+ legenda escalam proporcionalmente. Cores via design tokens (dark-mode safe). */
6021
+ .gyramais-gauge {
6022
+ position: relative;
6023
+ width: var(--gauge-size, 240px);
6024
+ height: var(--gauge-size, 240px);
6025
+ margin: 0 auto;
6026
+ }
6027
+ .gyramais-gauge svg {
6028
+ width: 100%;
6029
+ height: 100%;
6030
+ transform: rotate(-90deg);
6031
+ }
6032
+ .gyramais-gauge__track {
6033
+ stroke: var(--color-border-subtle, #f0f0f2);
6034
+ }
6035
+ .gyramais-gauge__arc {
6036
+ stroke: var(--gyra-blue, #1256ff);
6037
+ }
6038
+ .gyramais-gauge__center {
6039
+ position: absolute;
6040
+ inset: 0;
6041
+ display: flex;
6042
+ flex-direction: column;
6043
+ align-items: center;
6044
+ justify-content: center;
6045
+ gap: 2px;
6046
+ }
6047
+ .gyramais-gauge__caption {
6048
+ font-size: calc(var(--gauge-size, 240px) * 0.0458);
6049
+ color: var(--color-text-tertiary, #8e8e93);
6050
+ letter-spacing: 0.06em;
6051
+ text-transform: uppercase;
6052
+ font-weight: 600;
6053
+ }
6054
+ .gyramais-gauge__num {
6055
+ font-family: var(--font-display, "Lexend", "Inter", sans-serif);
6056
+ font-size: calc(var(--gauge-size, 240px) * 0.233);
6057
+ font-weight: 600;
6058
+ letter-spacing: -0.02em;
6059
+ color: var(--color-text-primary, #1d1d1f);
6060
+ line-height: 1;
6061
+ }
6062
+ .gyramais-gauge__max {
6063
+ font-size: calc(var(--gauge-size, 240px) * 0.05);
6064
+ color: var(--color-text-tertiary, #8e8e93);
6065
+ margin-top: 6px;
6066
+ }
6067
+ .gyramais-gauge__band {
6068
+ margin-top: 8px;
6069
+ font-size: calc(var(--gauge-size, 240px) * 0.0458);
6070
+ font-weight: 700;
6071
+ letter-spacing: 0.06em;
6072
+ text-transform: uppercase;
6073
+ padding: 4px 10px;
6074
+ border-radius: 9999px;
6075
+ background: var(--gyra-blue-light, #eef1fb);
6076
+ color: var(--gyra-blue, #1256ff);
6077
+ }
6078
+ .gyramais-gauge__band--success {
6079
+ background: var(--success-light, #e8f9ed);
6080
+ color: var(--status-success-text, #1a7d37);
6081
+ }
6082
+ .gyramais-gauge__band--warning {
6083
+ background: var(--warning-light, #fff4e0);
6084
+ color: var(--status-warning-text, #946200);
6085
+ }
6086
+ .gyramais-gauge__band--danger {
6087
+ background: var(--danger-light, #ffedec);
6088
+ color: var(--status-danger-text, #c93430);
6089
+ }
6090
+
6018
6091
  .gyramais-hover-card-trigger {
6019
6092
 
6020
6093
  display: block;
@@ -9973,6 +10046,58 @@ h6 {
9973
10046
  }
9974
10047
  }
9975
10048
 
10049
+ /* Retry action paired with the chip — sits to the LEFT of the pill,
10050
+ styled as a matching pill-button, so the retry stays visually tied to
10051
+ the sync-status it refers to. */
10052
+ .gyramais-sync-chip-wrap {
10053
+ display: inline-flex;
10054
+ width: -moz-fit-content;
10055
+ width: fit-content;
10056
+ align-items: center;
10057
+ gap: 8px;
10058
+ }
10059
+ .gyramais-sync-chip-retry {
10060
+ display: inline-flex;
10061
+ height: 28px;
10062
+ width: 28px;
10063
+ flex-shrink: 0;
10064
+ cursor: pointer;
10065
+ align-items: center;
10066
+ justify-content: center;
10067
+ border-radius: 9999px;
10068
+ border-width: 1px;
10069
+ border-color: var(--color-border-secondary);
10070
+ background-color: var(--color-surface-secondary);
10071
+ padding: 0px;
10072
+ color: var(--color-text-secondary);
10073
+ transition: background 150ms ease, color 150ms ease,
10074
+ border-color 150ms ease;
10075
+ }
10076
+ .gyramais-sync-chip-retry:hover {
10077
+ border-color: rgba(255,59,48,0.18);
10078
+ background-color: rgba(255,59,48,0.08);
10079
+ color: var(--status-danger-text);
10080
+ }
10081
+ .gyramais-sync-chip-retry:disabled {
10082
+ cursor: default;
10083
+ border-color: rgba(255,59,48,0.18);
10084
+ color: var(--status-danger-text);
10085
+ }
10086
+ .gyramais-sync-chip-retry .gyramais-sync-chip-retry-icon {
10087
+ height: 16px;
10088
+ width: 16px;
10089
+ font-size: 16px;
10090
+ }
10091
+ .gyramais-sync-chip-retry
10092
+ .gyramais-sync-chip-retry-icon.gyramais-sync-chip-retry-icon--spinning {
10093
+ animation: gyramais-sync-chip-spin 0.9s linear infinite;
10094
+ }
10095
+ @keyframes gyramais-sync-chip-spin {
10096
+ to {
10097
+ transform: rotate(360deg);
10098
+ }
10099
+ }
10100
+
9976
10101
  .gyramais-table-container {
9977
10102
  width: 100%;
9978
10103
  overflow-y: auto;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gyramais/gyra-design",
3
- "version": "0.2.31",
3
+ "version": "0.2.33",
4
4
  "description": "Gyramais Design System",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -1,21 +0,0 @@
1
- import React from "react";
2
- import "./index.css";
3
- type ListingPageProps = {
4
- id?: string;
5
- className?: string;
6
- title: string;
7
- description?: string;
8
- /** Right-aligned actions in the head (e.g. "+ Novo"). */
9
- actions?: React.ReactNode;
10
- /** Filters / search row below the head. */
11
- toolbar?: React.ReactNode;
12
- /** Result count / density toggle row. */
13
- meta?: React.ReactNode;
14
- /** Table or cards. */
15
- children?: React.ReactNode;
16
- /** Pagination strip. */
17
- footer?: React.ReactNode;
18
- };
19
- declare const ListingPage: ({ id, className, title, description, actions, toolbar, meta, children, footer, }: ListingPageProps) => React.JSX.Element;
20
- export { ListingPage };
21
- export type { ListingPageProps };
@@ -1 +0,0 @@
1
- export * from "./ListingPage";
@@ -1,7 +0,0 @@
1
- "use client";import e from"react";function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var a,r={exports:{}};
2
- /*!
3
- Copyright (c) 2018 Jed Watson.
4
- Licensed under the MIT License (MIT), see
5
- http://jedwatson.github.io/classnames
6
- */a=r,function(){var e={}.hasOwnProperty;function t(){for(var e="",t=0;t<arguments.length;t++){var a=arguments[t];a&&(e=n(e,r(a)))}return e}function r(a){if("string"==typeof a||"number"==typeof a)return a;if("object"!=typeof a)return"";if(Array.isArray(a))return t.apply(null,a);if(a.toString!==Object.prototype.toString&&!a.toString.toString().includes("[native code]"))return a.toString();var r="";for(var i in a)e.call(a,i)&&a[i]&&(r=n(r,i));return r}function n(e,t){return t?e?e+" "+t:e+t:e}a.exports?(t.default=t,a.exports=t):window.classNames=t}();var n=t(r.exports);const i=({id:t,className:a,title:r,description:i,actions:l,toolbar:s,meta:o,children:c,footer:m})=>e.createElement("div",{id:t,className:n("gyramais-listing-page",a)},e.createElement("div",{className:"gyramais-listing-page-head"},e.createElement("div",null,e.createElement("h1",null,r),i&&e.createElement("p",{className:"lead"},i)),l&&e.createElement("div",{className:"actions"},l)),s&&e.createElement("div",{className:"gyramais-listing-page-toolbar"},s),o&&e.createElement("div",{className:"gyramais-listing-page-meta"},o),e.createElement("div",{className:"gyramais-listing-page-content"},c),m&&e.createElement("div",{className:"gyramais-listing-page-foot"},m));export{i as ListingPage};
7
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../../node_modules/classnames/index.js","../../../src/components/ListingPage/ListingPage.tsx"],"sourcesContent":["/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = '';\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (arg) {\n\t\t\t\tclasses = appendClass(classes, parseValue(arg));\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction parseValue (arg) {\n\t\tif (typeof arg === 'string' || typeof arg === 'number') {\n\t\t\treturn arg;\n\t\t}\n\n\t\tif (typeof arg !== 'object') {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (Array.isArray(arg)) {\n\t\t\treturn classNames.apply(null, arg);\n\t\t}\n\n\t\tif (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {\n\t\t\treturn arg.toString();\n\t\t}\n\n\t\tvar classes = '';\n\n\t\tfor (var key in arg) {\n\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\tclasses = appendClass(classes, key);\n\t\t\t}\n\t\t}\n\n\t\treturn classes;\n\t}\n\n\tfunction appendClass (value, newClass) {\n\t\tif (!newClass) {\n\t\t\treturn value;\n\t\t}\n\t\n\t\tif (value) {\n\t\t\treturn value + ' ' + newClass;\n\t\t}\n\t\n\t\treturn value + newClass;\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","import React from \"react\";\nimport classNames from \"classnames\";\nimport \"./index.css\";\n\n/* Listing page layout — title + description, optional right-aligned\n actions, optional toolbar (filters/search), optional meta strip\n (counts/density), the table/cards body, and an optional pagination\n footer. The visual rhythm matches the v2 listing pattern shared\n across Relatórios, Lotes, Política de Crédito, etc. */\n\ntype ListingPageProps = {\n id?: string;\n className?: string;\n title: string;\n description?: string;\n /** Right-aligned actions in the head (e.g. \"+ Novo\"). */\n actions?: React.ReactNode;\n /** Filters / search row below the head. */\n toolbar?: React.ReactNode;\n /** Result count / density toggle row. */\n meta?: React.ReactNode;\n /** Table or cards. */\n children?: React.ReactNode;\n /** Pagination strip. */\n footer?: React.ReactNode;\n};\n\nconst ListingPage = ({\n id,\n className,\n title,\n description,\n actions,\n toolbar,\n meta,\n children,\n footer,\n}: ListingPageProps) => {\n return (\n <div id={id} className={classNames(\"gyramais-listing-page\", className)}>\n <div className=\"gyramais-listing-page-head\">\n <div>\n <h1>{title}</h1>\n {description && <p className=\"lead\">{description}</p>}\n </div>\n {actions && <div className=\"actions\">{actions}</div>}\n </div>\n\n {toolbar && (\n <div className=\"gyramais-listing-page-toolbar\">{toolbar}</div>\n )}\n\n {meta && <div className=\"gyramais-listing-page-meta\">{meta}</div>}\n\n <div className=\"gyramais-listing-page-content\">{children}</div>\n\n {footer && <div className=\"gyramais-listing-page-foot\">{footer}</div>}\n </div>\n );\n};\n\nexport { ListingPage };\nexport type { ListingPageProps };\n"],"names":["hasOwn","hasOwnProperty","classNames","classes","i","arguments","length","arg","appendClass","parseValue","Array","isArray","apply","toString","Object","prototype","includes","key","call","value","newClass","module","exports","default","window","ListingPage","id","className","title","description","actions","toolbar","meta","children","footer","React","createElement"],"mappings":";;;;;MAOC,WAGA,IAAIA,EAAS,CAAA,EAAGC,eAEhB,SAASC,IAGR,IAFA,IAAIC,EAAU,GAELC,EAAI,EAAGA,EAAIC,UAAUC,OAAQF,IAAK,CAC1C,IAAIG,EAAMF,UAAUD,GAChBG,IACHJ,EAAUK,EAAYL,EAASM,EAAWF,IAE9C,CAEE,OAAOJ,CACT,CAEC,SAASM,EAAYF,GACpB,GAAmB,iBAARA,GAAmC,iBAARA,EACrC,OAAOA,EAGR,GAAmB,iBAARA,EACV,MAAO,GAGR,GAAIG,MAAMC,QAAQJ,GACjB,OAAOL,EAAWU,MAAM,KAAML,GAG/B,GAAIA,EAAIM,WAAaC,OAAOC,UAAUF,WAAaN,EAAIM,SAASA,WAAWG,SAAS,iBACnF,OAAOT,EAAIM,WAGZ,IAAIV,EAAU,GAEd,IAAK,IAAIc,KAAOV,EACXP,EAAOkB,KAAKX,EAAKU,IAAQV,EAAIU,KAChCd,EAAUK,EAAYL,EAASc,IAIjC,OAAOd,CACT,CAEC,SAASK,EAAaW,EAAOC,GAC5B,OAAKA,EAIDD,EACIA,EAAQ,IAAMC,EAGfD,EAAQC,EAPPD,CAQV,CAEsCE,EAAOC,SAC3CpB,EAAWqB,QAAUrB,EACrBmB,UAAiBnB,GAOjBsB,OAAOtB,WAAaA,CAEtB,CArEA,sBCoBA,MAAMuB,EAAc,EAClBC,KACAC,YACAC,QACAC,cACAC,UACAC,UACAC,OACAC,WACAC,YAGEC,EAAAC,cAAA,MAAA,CAAKV,GAAIA,EAAIC,UAAWzB,EAAW,wBAAyByB,IAC1DQ,EAAAC,cAAA,MAAA,CAAKT,UAAU,8BACbQ,EAAAC,cAAA,MAAA,KACED,EAAAC,cAAA,KAAA,KAAKR,GACJC,GAAeM,qBAAGR,UAAU,QAAQE,IAEtCC,GAAWK,uBAAKR,UAAU,WAAWG,IAGvCC,GACCI,EAAAC,cAAA,MAAA,CAAKT,UAAU,iCAAiCI,GAGjDC,GAAQG,EAAAC,cAAA,MAAA,CAAKT,UAAU,8BAA8BK,GAEtDG,EAAAC,cAAA,MAAA,CAAKT,UAAU,iCAAiCM,GAE/CC,GAAUC,EAAAC,cAAA,MAAA,CAAKT,UAAU,8BAA8BO","x_google_ignoreList":[0]}