@lerianstudio/sindarian-ui 1.4.0-beta.8 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/components/card/account-card/index.d.ts.map +1 -1
  2. package/dist/components/card/account-card/index.js +1 -1
  3. package/dist/components/card/entity-card/index.js +3 -3
  4. package/dist/components/dialog/confirmation-dialog/index.d.ts +36 -5
  5. package/dist/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
  6. package/dist/components/dialog/confirmation-dialog/index.js +2 -2
  7. package/dist/components/entity-box/index.js +1 -1
  8. package/dist/components/entity-data-table/index.d.ts.map +1 -1
  9. package/dist/components/entity-data-table/index.js +1 -1
  10. package/dist/components/form/file-upload-field/index.d.ts +11 -2
  11. package/dist/components/form/file-upload-field/index.d.ts.map +1 -1
  12. package/dist/components/form/file-upload-field/index.js +8 -3
  13. package/dist/components/form/input-field/index.d.ts +41 -2
  14. package/dist/components/form/input-field/index.d.ts.map +1 -1
  15. package/dist/components/form/input-field/index.js +73 -15
  16. package/dist/components/form/select-field/index.d.ts +9 -1
  17. package/dist/components/form/select-field/index.d.ts.map +1 -1
  18. package/dist/components/form/select-field/index.js +2 -2
  19. package/dist/components/page-header/index.d.ts.map +1 -1
  20. package/dist/components/page-header/index.js +2 -2
  21. package/dist/components/ui/autocomplete/index.d.ts +34 -6
  22. package/dist/components/ui/autocomplete/index.d.ts.map +1 -1
  23. package/dist/components/ui/autocomplete/index.js +72 -16
  24. package/dist/components/ui/badge/index.d.ts.map +1 -1
  25. package/dist/components/ui/badge/index.js +11 -1
  26. package/dist/components/ui/button/styles.css +31 -1
  27. package/dist/components/ui/calendar/index.d.ts.map +1 -1
  28. package/dist/components/ui/calendar/index.js +7 -1
  29. package/dist/components/ui/card/index.d.ts.map +1 -1
  30. package/dist/components/ui/card/index.js +1 -1
  31. package/dist/components/ui/dropdown-menu/index.d.ts.map +1 -1
  32. package/dist/components/ui/dropdown-menu/index.js +4 -1
  33. package/dist/components/ui/field/index.d.ts.map +1 -1
  34. package/dist/components/ui/field/index.js +5 -2
  35. package/dist/components/ui/file-upload/index.d.ts +76 -9
  36. package/dist/components/ui/file-upload/index.d.ts.map +1 -1
  37. package/dist/components/ui/file-upload/index.js +47 -12
  38. package/dist/components/ui/form.d.ts +4 -0
  39. package/dist/components/ui/form.d.ts.map +1 -1
  40. package/dist/components/ui/form.js +53 -8
  41. package/dist/components/ui/multiple-select/index.js +2 -2
  42. package/dist/components/ui/progress/index.d.ts +15 -1
  43. package/dist/components/ui/progress/index.d.ts.map +1 -1
  44. package/dist/components/ui/progress/index.js +25 -2
  45. package/dist/components/ui/sidebar/sidebar-expand-button.d.ts.map +1 -1
  46. package/dist/components/ui/sidebar/sidebar-expand-button.js +17 -1
  47. package/dist/components/ui/toggle-group/index.d.ts +1 -1
  48. package/dist/components/ui/toggle-group/index.d.ts.map +1 -1
  49. package/dist/components/ui/toggle-group/index.js +73 -4
  50. package/dist/components/ui/tooltip/index.d.ts +15 -0
  51. package/dist/components/ui/tooltip/index.d.ts.map +1 -1
  52. package/dist/components/ui/tooltip/index.js +16 -1
  53. package/dist/domain/blotter/index.d.ts +4 -2
  54. package/dist/domain/blotter/index.d.ts.map +1 -1
  55. package/dist/domain/delinquency-aging/aging-buckets.d.ts.map +1 -1
  56. package/dist/domain/delinquency-aging/aging-buckets.js +8 -3
  57. package/dist/domain/delinquency-aging/index.d.ts.map +1 -1
  58. package/dist/domain/delinquency-aging/index.js +8 -3
  59. package/dist/domain/key-id/index.js +1 -1
  60. package/dist/domain/status-rail/index.js +1 -1
  61. package/dist/domain/threshold-gauge/index.d.ts.map +1 -1
  62. package/dist/domain/threshold-gauge/index.js +9 -5
  63. package/dist/enterprise/stat-card/index.d.ts.map +1 -1
  64. package/dist/enterprise/stat-card/index.js +12 -4
  65. package/dist/esm/components/card/account-card/index.d.ts.map +1 -1
  66. package/dist/esm/components/card/account-card/index.js +1 -1
  67. package/dist/esm/components/card/entity-card/index.js +3 -3
  68. package/dist/esm/components/dialog/confirmation-dialog/index.d.ts +36 -5
  69. package/dist/esm/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
  70. package/dist/esm/components/dialog/confirmation-dialog/index.js +2 -2
  71. package/dist/esm/components/entity-box/index.js +1 -1
  72. package/dist/esm/components/entity-data-table/index.d.ts.map +1 -1
  73. package/dist/esm/components/entity-data-table/index.js +1 -1
  74. package/dist/esm/components/form/file-upload-field/index.d.ts +11 -2
  75. package/dist/esm/components/form/file-upload-field/index.d.ts.map +1 -1
  76. package/dist/esm/components/form/file-upload-field/index.js +8 -3
  77. package/dist/esm/components/form/input-field/index.d.ts +41 -2
  78. package/dist/esm/components/form/input-field/index.d.ts.map +1 -1
  79. package/dist/esm/components/form/input-field/index.js +73 -15
  80. package/dist/esm/components/form/select-field/index.d.ts +9 -1
  81. package/dist/esm/components/form/select-field/index.d.ts.map +1 -1
  82. package/dist/esm/components/form/select-field/index.js +2 -2
  83. package/dist/esm/components/page-header/index.d.ts.map +1 -1
  84. package/dist/esm/components/page-header/index.js +2 -2
  85. package/dist/esm/components/ui/autocomplete/index.d.ts +34 -6
  86. package/dist/esm/components/ui/autocomplete/index.d.ts.map +1 -1
  87. package/dist/esm/components/ui/autocomplete/index.js +72 -16
  88. package/dist/esm/components/ui/badge/index.d.ts.map +1 -1
  89. package/dist/esm/components/ui/badge/index.js +11 -1
  90. package/dist/esm/components/ui/calendar/index.d.ts.map +1 -1
  91. package/dist/esm/components/ui/calendar/index.js +8 -2
  92. package/dist/esm/components/ui/card/index.d.ts.map +1 -1
  93. package/dist/esm/components/ui/card/index.js +1 -1
  94. package/dist/esm/components/ui/dropdown-menu/index.d.ts.map +1 -1
  95. package/dist/esm/components/ui/dropdown-menu/index.js +4 -1
  96. package/dist/esm/components/ui/field/index.d.ts.map +1 -1
  97. package/dist/esm/components/ui/field/index.js +5 -2
  98. package/dist/esm/components/ui/file-upload/index.d.ts +76 -9
  99. package/dist/esm/components/ui/file-upload/index.d.ts.map +1 -1
  100. package/dist/esm/components/ui/file-upload/index.js +47 -13
  101. package/dist/esm/components/ui/form.d.ts +4 -0
  102. package/dist/esm/components/ui/form.d.ts.map +1 -1
  103. package/dist/esm/components/ui/form.js +53 -8
  104. package/dist/esm/components/ui/multiple-select/index.js +2 -2
  105. package/dist/esm/components/ui/progress/index.d.ts +15 -1
  106. package/dist/esm/components/ui/progress/index.d.ts.map +1 -1
  107. package/dist/esm/components/ui/progress/index.js +25 -2
  108. package/dist/esm/components/ui/sidebar/sidebar-expand-button.d.ts.map +1 -1
  109. package/dist/esm/components/ui/sidebar/sidebar-expand-button.js +17 -1
  110. package/dist/esm/components/ui/toggle-group/index.d.ts +1 -1
  111. package/dist/esm/components/ui/toggle-group/index.d.ts.map +1 -1
  112. package/dist/esm/components/ui/toggle-group/index.js +73 -4
  113. package/dist/esm/components/ui/tooltip/index.d.ts +15 -0
  114. package/dist/esm/components/ui/tooltip/index.d.ts.map +1 -1
  115. package/dist/esm/components/ui/tooltip/index.js +16 -1
  116. package/dist/esm/domain/blotter/index.d.ts +4 -2
  117. package/dist/esm/domain/blotter/index.d.ts.map +1 -1
  118. package/dist/esm/domain/delinquency-aging/aging-buckets.d.ts.map +1 -1
  119. package/dist/esm/domain/delinquency-aging/aging-buckets.js +8 -3
  120. package/dist/esm/domain/delinquency-aging/index.d.ts.map +1 -1
  121. package/dist/esm/domain/delinquency-aging/index.js +8 -3
  122. package/dist/esm/domain/key-id/index.js +1 -1
  123. package/dist/esm/domain/status-rail/index.js +1 -1
  124. package/dist/esm/domain/threshold-gauge/index.d.ts.map +1 -1
  125. package/dist/esm/domain/threshold-gauge/index.js +9 -5
  126. package/dist/esm/enterprise/stat-card/index.d.ts.map +1 -1
  127. package/dist/esm/enterprise/stat-card/index.js +12 -4
  128. package/dist/globals.css +24 -1
  129. package/package.json +1 -1
@@ -16,7 +16,11 @@ declare const useFormField: () => {
16
16
  formDescriptionId: string;
17
17
  formMessageId: string;
18
18
  required: boolean | undefined;
19
+ described: Record<DescribingSlot, boolean> | undefined;
20
+ onDescribedChange: ((slot: DescribingSlot, rendered: boolean) => void) | undefined;
19
21
  };
22
+ /** The two slots that can describe a control, in the order a reader hears them. */
23
+ type DescribingSlot = 'message' | 'description';
20
24
  export type FormItemProps = React.HTMLAttributes<HTMLDivElement> & {
21
25
  required?: boolean;
22
26
  };
@@ -1 +1 @@
1
- {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../src/components/ui/form.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAEL,eAAe,EACf,SAAS,EACT,WAAW,EAGZ,MAAM,iBAAiB,CAAA;AAKxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAS9D,QAAA,MAAM,IAAI,4MAAe,CAAA;AAazB,QAAA,MAAM,SAAS,GACb,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,cAEC,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC,sBAMtC,CAAA;AAED,QAAA,MAAM,YAAY;;;;;;;;;;;;CAyBjB,CAAA;AAWD,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,QAAA,MAAM,QAAQ;eAHD,OAAO;wCAanB,CAAA;AAGD,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,wBAAwB,CACzD,OAAO,cAAc,CAAC,IAAI,CAC3B,GAAG;IACF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB,CAAA;AAED,QAAA,MAAM,SAAS;YAHL,KAAK,CAAC,SAAS;0CA2BvB,CAAA;AAGF,eAAO,MAAM,WAAW,GAAI,yBAAyB,oBAAoB,sBASxE,CAAA;AAED,QAAA,MAAM,WAAW;;gFAmBf,CAAA;AAGF,QAAA,MAAM,eAAe,yHAcnB,CAAA;AAGF,QAAA,MAAM,WAAW,yHAuBf,CAAA;AAGF,OAAO,EACL,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,WAAW,EACX,eAAe,EACf,WAAW,EACX,SAAS,EACV,CAAA"}
1
+ {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../src/components/ui/form.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAEL,eAAe,EACf,SAAS,EACT,WAAW,EAGZ,MAAM,iBAAiB,CAAA;AAKxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAS9D,QAAA,MAAM,IAAI,4MAAe,CAAA;AAazB,QAAA,MAAM,SAAS,GACb,YAAY,SAAS,WAAW,GAAG,WAAW,EAC9C,KAAK,SAAS,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,EAC/D,cAEC,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC,sBAMtC,CAAA;AAED,QAAA,MAAM,YAAY;;;;;;;;;;;;;+BA4CW,cAAc,YAAY,OAAO,KAAK,IAAI;CAjBtE,CAAA;AAED,mFAAmF;AACnF,KAAK,cAAc,GAAG,SAAS,GAAG,aAAa,CAAA;AAwC/C,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,QAAA,MAAM,QAAQ;eAHD,OAAO;wCA8BnB,CAAA;AAGD,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,wBAAwB,CACzD,OAAO,cAAc,CAAC,IAAI,CAC3B,GAAG;IACF,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACxB,CAAA;AAED,QAAA,MAAM,SAAS;YAHL,KAAK,CAAC,SAAS;0CA6BvB,CAAA;AAGF,eAAO,MAAM,WAAW,GAAI,yBAAyB,oBAAoB,sBASxE,CAAA;AAED,QAAA,MAAM,WAAW;;gFAgCf,CAAA;AAGF,QAAA,MAAM,eAAe,yHAgBnB,CAAA;AAGF,QAAA,MAAM,WAAW,yHA6Bf,CAAA;AAGF,OAAO,EACL,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,WAAW,EACX,eAAe,EACf,WAAW,EACX,SAAS,EACV,CAAA"}
@@ -61,7 +61,7 @@ const useFormField = () => {
61
61
  const fieldState = form && fieldContext.name
62
62
  ? form.getFieldState(fieldContext.name, form.formState)
63
63
  : undefined;
64
- const { id, required } = itemContext;
64
+ const { id, required, described, onDescribedChange } = itemContext;
65
65
  return {
66
66
  id,
67
67
  name: fieldContext.name,
@@ -69,42 +69,87 @@ const useFormField = () => {
69
69
  formDescriptionId: `${id}-form-item-description`,
70
70
  formMessageId: `${id}-form-item-message`,
71
71
  required,
72
+ described,
73
+ onDescribedChange,
72
74
  ...fieldState
73
75
  };
74
76
  };
75
77
  exports.useFormField = useFormField;
76
78
  const FormItemContext = React.createContext({});
79
+ /**
80
+ * Announce that this slot is on the page, for as long as it is.
81
+ *
82
+ * `rendered` is a parameter rather than a caller-side condition because
83
+ * `FormMessage` returns null when it has nothing to say, and a hook cannot sit
84
+ * behind that early return.
85
+ */
86
+ function useDescribingSlot(slot, rendered) {
87
+ const { onDescribedChange } = React.useContext(FormItemContext);
88
+ React.useEffect(() => {
89
+ if (!rendered)
90
+ return;
91
+ onDescribedChange?.(slot, true);
92
+ return () => onDescribedChange?.(slot, false);
93
+ }, [onDescribedChange, slot, rendered]);
94
+ }
77
95
  const FormItem = React.forwardRef(({ className, required, ...props }, ref) => {
78
96
  const id = React.useId();
79
- return ((0, jsx_runtime_1.jsx)(FormItemContext.Provider, { value: { id, required }, children: (0, jsx_runtime_1.jsx)("div", { ref: ref, className: (0, utils_1.cn)('space-y-2', className), ...props }) }));
97
+ const [described, setDescribed] = React.useState({ message: false, description: false });
98
+ // Keeps the object identity when nothing moved, so a slot re-registering
99
+ // does not re-render the item for no reason.
100
+ const onDescribedChange = React.useCallback((slot, rendered) => setDescribed((current) => current[slot] === rendered
101
+ ? current
102
+ : { ...current, [slot]: rendered }), []);
103
+ return ((0, jsx_runtime_1.jsx)(FormItemContext.Provider, { value: { id, required, described, onDescribedChange }, children: (0, jsx_runtime_1.jsx)("div", { ref: ref, className: (0, utils_1.cn)('space-y-2', className), ...props }) }));
80
104
  });
81
105
  exports.FormItem = FormItem;
82
106
  FormItem.displayName = 'FormItem';
83
107
  const FormLabel = React.forwardRef(({ className, extra, children, ...props }, ref) => {
84
108
  const { required, error, formItemId } = useFormField();
85
- return ((0, jsx_runtime_1.jsxs)(label_1.Label, { ref: ref, className: (0, utils_1.cn)('text-muted-foreground flex justify-between text-sm font-semibold', error && 'text-destructive', className), htmlFor: formItemId, ...props, children: [(0, jsx_runtime_1.jsxs)("span", { children: [children, required ? ' *' : ''] }), extra] }));
109
+ return ((0, jsx_runtime_1.jsxs)(label_1.Label, { ref: ref, className: (0, utils_1.cn)('text-muted-foreground flex justify-between text-sm font-semibold',
110
+ // The error TEXT token, matching FormMessage below: `--destructive`
111
+ // is the badge/fill family and reads 3.80:1 as ink on the dark card.
112
+ error && 'text-system-error-h1a', className), htmlFor: formItemId, ...props, children: [(0, jsx_runtime_1.jsxs)("span", { children: [children, required ? ' *' : ''] }), extra] }));
86
113
  });
87
114
  exports.FormLabel = FormLabel;
88
115
  FormLabel.displayName = 'FormLabel';
89
116
  const FormTooltip = ({ children, ...others }) => ((0, jsx_runtime_1.jsx)(tooltip_1.TooltipProvider, { ...others, children: (0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { asChild: true, children: (0, jsx_runtime_1.jsx)(lucide_react_1.HelpCircle, { className: "text-container-text ml-2 h-4 w-4" }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { children: children })] }) }));
90
117
  exports.FormTooltip = FormTooltip;
91
118
  const FormControl = React.forwardRef(({ ...props }, ref) => {
92
- const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
93
- return ((0, jsx_runtime_1.jsx)(react_slot_1.Slot, { ref: ref, id: formItemId, "aria-describedby": !error
94
- ? `${formDescriptionId}`
95
- : `${formDescriptionId} ${formMessageId}`, "aria-invalid": !!error, ...props }));
119
+ const { error, formItemId, formDescriptionId, formMessageId, described } = useFormField();
120
+ // Only ids that resolve. A screen reader drops a dangling IDREF silently, so
121
+ // the barrier this removes is diagnostic rather than operational: a form with
122
+ // thirteen broken associations is a form where a real one cannot be spotted.
123
+ //
124
+ // Message first: a reader hears the error before the hint. `undefined` when
125
+ // both slots are empty, which drops the attribute — and, because Radix Slot
126
+ // OVERWRITES rather than merges, still lets the wrapped element carry its own
127
+ // (`ui/file-upload` merges the injected id with its own error id that way).
128
+ const describedBy = [
129
+ described?.message ? formMessageId : undefined,
130
+ described?.description ? formDescriptionId : undefined
131
+ ]
132
+ .filter(Boolean)
133
+ .join(' ') || undefined;
134
+ return ((0, jsx_runtime_1.jsx)(react_slot_1.Slot, { ref: ref, id: formItemId, "aria-describedby": describedBy, "aria-invalid": !!error, ...props }));
96
135
  });
97
136
  exports.FormControl = FormControl;
98
137
  FormControl.displayName = 'FormControl';
99
138
  const FormDescription = React.forwardRef(({ className, ...props }, ref) => {
100
139
  const { formDescriptionId } = useFormField();
101
- return ((0, jsx_runtime_1.jsx)("p", { ref: ref, id: formDescriptionId, className: (0, utils_1.cn)('text-shadcn-400 text-xs font-medium', className), ...props }));
140
+ useDescribingSlot('description', true);
141
+ return ((0, jsx_runtime_1.jsx)("p", { ref: ref, id: formDescriptionId, className: (0, utils_1.cn)('text-muted-foreground text-xs font-medium', className), ...props }));
102
142
  });
103
143
  exports.FormDescription = FormDescription;
104
144
  FormDescription.displayName = 'FormDescription';
105
145
  const FormMessage = React.forwardRef(({ className, children, ...props }, ref) => {
106
146
  const { error, formMessageId } = useFormField();
107
147
  const body = error ? String(error?.message) : children;
148
+ // Registered on `body`, not on `error`: a message given plain children
149
+ // renders copy that the control has to point at too. The old expression only
150
+ // added the message id when react-hook-form reported an error, so a
151
+ // standalone message was rendered and never associated.
152
+ useDescribingSlot('message', Boolean(body));
108
153
  if (!body) {
109
154
  return null;
110
155
  }
@@ -77,7 +77,7 @@ exports.MultipleSelectTrigger = react_1.default.forwardRef(({ className, childre
77
77
  setOpen(false);
78
78
  inputRef.current?.blur();
79
79
  });
80
- return ((0, jsx_runtime_1.jsxs)("div", { ref: _ref, className: (0, utils_1.cn)('bg-background ring-offset-background placeholder:text-shadcn-400 focus:ring-ring border-shadcn-400 flex flex-row rounded-md border text-sm focus:ring-2 focus:ring-offset-0 focus:outline-hidden focus-visible:outline-hidden md:text-sm [&>span]:line-clamp-1', {
80
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: _ref, className: (0, utils_1.cn)('bg-background ring-offset-background placeholder:text-input-placeholder focus:ring-ring border-input-border flex flex-row rounded-md border text-sm focus:ring-2 focus:ring-offset-0 focus:outline-hidden focus-visible:outline-hidden md:text-sm [&>span]:line-clamp-1', {
81
81
  'h-10': value.length === 0,
82
82
  'min-h-10': value.length > 0,
83
83
  'cursor-text': !disabled && !readOnly && value.length !== 0,
@@ -116,7 +116,7 @@ exports.MultipleSelectValue = react_1.default.forwardRef(({ className, ...props
116
116
  value?.map((value) => ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: "secondary", className: (0, utils_1.cn)('data-disabled:bg-muted-foreground data-fixed:bg-muted-foreground data-disabled:text-muted data-fixed:text-muted data-disabled:hover:bg-muted-foreground data-fixed:hover:bg-muted-foreground'), children: [showValue ? value : options[value], (0, jsx_runtime_1.jsx)("button", { type: "button", className: (0, utils_1.cn)('ring-offset-background focus:ring-ring ml-1 rounded-full outline-hidden focus:ring-2 focus:ring-offset-2', disabled && 'hidden'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "text-muted-foreground hover:text-foreground h-3 w-3", onClick: (event) => {
117
117
  event.stopPropagation();
118
118
  handleChange(value);
119
- } }) })] }, value))), (0, jsx_runtime_1.jsx)(cmdk_1.Command.Input, { ...props, ref: inputRef, disabled: disabled, className: (0, utils_1.cn)('placeholder:text-muted-foreground bg-transparent outline-hidden focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0', className) })] }));
119
+ } }) })] }, value))), (0, jsx_runtime_1.jsx)(cmdk_1.Command.Input, { ...props, ref: inputRef, disabled: disabled, className: (0, utils_1.cn)('placeholder:text-input-placeholder bg-transparent outline-hidden focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0', className) })] }));
120
120
  });
121
121
  exports.MultipleSelectValue.displayName = 'MultipleSelectValue';
122
122
  exports.MultipleSelectEmpty = react_1.default.forwardRef(({ className, ...props }, forwardedRef) => {
@@ -3,6 +3,20 @@ import * as ProgressPrimitive from '@radix-ui/react-progress';
3
3
  type ProgressProps = React.ComponentProps<typeof ProgressPrimitive.Root> & {
4
4
  indicatorColor?: string;
5
5
  };
6
- declare function Progress({ className, value, indicatorColor, ...props }: ProgressProps): React.JSX.Element;
6
+ /**
7
+ * `value` and `max` are Radix's own props, so the bar reports `aria-valuenow` /
8
+ * `aria-valuemax` and flips `data-state` between `loading` and `complete`.
9
+ * Omitting `value`, or passing `null`, is Radix's indeterminate state and draws
10
+ * an empty track.
11
+ *
12
+ * Both numbers are BOUNDED BEFORE THE ROOT SEES THEM, so the drawn width and
13
+ * the announced value can never disagree. Radix accepts a value only inside
14
+ * `[0, max]`: hand it one outside and the root drops `aria-valuenow`, sticks
15
+ * `data-state` on `indeterminate` and logs an error, while the indicator here
16
+ * goes on drawing the clamped bar. Substituting 100 for a non-positive max is
17
+ * Radix's own fallback, and is also what keeps a `max` of 0 from dividing by
18
+ * zero.
19
+ */
20
+ declare function Progress({ className, value, max, indicatorColor, ...props }: ProgressProps): React.JSX.Element;
7
21
  export { Progress };
8
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/progress/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAI7D,KAAK,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG;IACzE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,KAAK,EACL,cAA6B,EAC7B,GAAG,KAAK,EACT,EAAE,aAAa,qBAiBf;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/progress/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,iBAAiB,MAAM,0BAA0B,CAAA;AAI7D,KAAK,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG;IACzE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,KAAK,EACL,GAAG,EACH,cAA6B,EAC7B,GAAG,KAAK,EACT,EAAE,aAAa,qBA6Bf;AAED,OAAO,EAAE,QAAQ,EAAE,CAAA"}
@@ -38,6 +38,29 @@ exports.Progress = Progress;
38
38
  const jsx_runtime_1 = require("react/jsx-runtime");
39
39
  const ProgressPrimitive = __importStar(require("@radix-ui/react-progress"));
40
40
  const utils_1 = require("../../../lib/utils");
41
- function Progress({ className, value, indicatorColor = 'bg-primary', ...props }) {
42
- return ((0, jsx_runtime_1.jsx)(ProgressPrimitive.Root, { "data-slot": "progress", className: (0, utils_1.cn)('bg-primary/20 relative h-4 w-full overflow-hidden rounded-full', className), ...props, children: (0, jsx_runtime_1.jsx)(ProgressPrimitive.Indicator, { "data-slot": "progress-indicator", className: (0, utils_1.cn)('h-full w-full flex-1 transition-all', indicatorColor), style: { transform: `translateX(-${100 - (value || 0)}%)` } }) }));
41
+ /**
42
+ * `value` and `max` are Radix's own props, so the bar reports `aria-valuenow` /
43
+ * `aria-valuemax` and flips `data-state` between `loading` and `complete`.
44
+ * Omitting `value`, or passing `null`, is Radix's indeterminate state and draws
45
+ * an empty track.
46
+ *
47
+ * Both numbers are BOUNDED BEFORE THE ROOT SEES THEM, so the drawn width and
48
+ * the announced value can never disagree. Radix accepts a value only inside
49
+ * `[0, max]`: hand it one outside and the root drops `aria-valuenow`, sticks
50
+ * `data-state` on `indeterminate` and logs an error, while the indicator here
51
+ * goes on drawing the clamped bar. Substituting 100 for a non-positive max is
52
+ * Radix's own fallback, and is also what keeps a `max` of 0 from dividing by
53
+ * zero.
54
+ */
55
+ function Progress({ className, value, max, indicatorColor = 'bg-primary', ...props }) {
56
+ const scale = Number.isFinite(max) && max > 0 ? max : 100;
57
+ // Bound against `scale`, not against the rejected `max`: with `max={0}` the
58
+ // scale is already 100, and clamping to 0 would report a finished bar empty.
59
+ // Non-finite values are indeterminate, matching Radix without producing an
60
+ // invalid CSS transform.
61
+ const bounded = Number.isFinite(value)
62
+ ? Math.min(scale, Math.max(0, value))
63
+ : null;
64
+ const percent = ((bounded ?? 0) / scale) * 100;
65
+ return ((0, jsx_runtime_1.jsx)(ProgressPrimitive.Root, { "data-slot": "progress", value: bounded, max: scale, className: (0, utils_1.cn)('bg-primary/20 relative h-4 w-full overflow-hidden rounded-full', className), ...props, children: (0, jsx_runtime_1.jsx)(ProgressPrimitive.Indicator, { "data-slot": "progress-indicator", className: (0, utils_1.cn)('h-full w-full flex-1 transition-all', indicatorColor), style: { transform: `translateX(-${100 - percent}%)` } }) }));
43
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-expand-button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/sidebar/sidebar-expand-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAYzB,KAAK,wBAAwB,GAAG;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,aAAa,wBAAwB,sBA6CxE,CAAA"}
1
+ {"version":3,"file":"sidebar-expand-button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/sidebar/sidebar-expand-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAA;AAYzB,KAAK,wBAAwB,GAAG;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,aAAa,wBAAwB,sBAyDxE,CAAA"}
@@ -14,6 +14,22 @@ const tooltip_1 = require("../../ui/tooltip");
14
14
  const icon_button_1 = require("../icon-button");
15
15
  const SidebarExpandButton = ({ tooltip }) => {
16
16
  const { isCollapsed, toggleSidebar } = (0, sidebar_provider_1.useSidebar)();
17
- return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [!isCollapsed && ((0, jsx_runtime_1.jsx)("div", { "data-slot": "sidebar-expand-button", className: "border-border bg-card flex w-full", children: (0, jsx_runtime_1.jsx)("div", { className: "absolute right-[-20px] bottom-4", children: (0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { variant: "secondary", rounded: true, onClick: toggleSidebar, "aria-label": tooltip || 'Collapse sidebar', "aria-expanded": true, children: (0, jsx_runtime_1.jsx)(lucide_react_1.PanelLeftClose, { className: "text-shadcn-400" }) }) }) })), isCollapsed && ((0, jsx_runtime_1.jsx)(sidebar_components_1.SidebarFooter, { children: (0, jsx_runtime_1.jsx)(tooltip_1.TooltipProvider, { children: (0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger, { className: "group/expand-button text-shadcn-400 hover:bg-accent rounded-sm bg-transparent p-2", onClick: toggleSidebar, "aria-label": tooltip || 'Expand sidebar', "aria-expanded": false, children: (0, jsx_runtime_1.jsx)(lucide_react_1.PanelRightClose, { className: "group-hover/expand-button:text-white dark:text-white" }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: "right", children: tooltip || 'Expand' })] }) }) }))] }));
17
+ return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [!isCollapsed && ((0, jsx_runtime_1.jsx)("div", { "data-slot": "sidebar-expand-button", className: "border-border bg-card flex w-full", children: (0, jsx_runtime_1.jsx)("div", { className: "absolute right-[-20px] bottom-4", children: (0, jsx_runtime_1.jsx)(icon_button_1.IconButton, { variant: "secondary", rounded: true, onClick: toggleSidebar, "aria-label": tooltip || 'Collapse sidebar', "aria-expanded": true, children: (0, jsx_runtime_1.jsx)(lucide_react_1.PanelLeftClose, { className: "text-muted-foreground" }) }) }) })), isCollapsed && ((0, jsx_runtime_1.jsx)(sidebar_components_1.SidebarFooter, { children: (0, jsx_runtime_1.jsx)(tooltip_1.TooltipProvider, { children: (0, jsx_runtime_1.jsxs)(tooltip_1.Tooltip, { children: [(0, jsx_runtime_1.jsx)(tooltip_1.TooltipTrigger
18
+ // `hover:text-accent-foreground` on the TRIGGER, not only on
19
+ // the glyph below. The base ink here used to be base/400, which
20
+ // no rule paired with anything; now that it is the muted token,
21
+ // it is the ink anything inside this trigger inherits, and the
22
+ // muted token reads 1.07:1 on sunglow in dark. The glyph
23
+ // overrides it today, so this pairs the fill for whatever the
24
+ // trigger holds next.
25
+ , {
26
+ // `hover:text-accent-foreground` on the TRIGGER, not only on
27
+ // the glyph below. The base ink here used to be base/400, which
28
+ // no rule paired with anything; now that it is the muted token,
29
+ // it is the ink anything inside this trigger inherits, and the
30
+ // muted token reads 1.07:1 on sunglow in dark. The glyph
31
+ // overrides it today, so this pairs the fill for whatever the
32
+ // trigger holds next.
33
+ className: "group/expand-button text-muted-foreground hover:bg-accent hover:text-accent-foreground rounded-sm bg-transparent p-2", onClick: toggleSidebar, "aria-label": tooltip || 'Expand sidebar', "aria-expanded": false, children: (0, jsx_runtime_1.jsx)(lucide_react_1.PanelRightClose, { className: "group-hover/expand-button:text-accent-foreground dark:text-white" }) }), (0, jsx_runtime_1.jsx)(tooltip_1.TooltipContent, { side: "right", children: tooltip || 'Expand' })] }) }) }))] }));
18
34
  };
19
35
  exports.SidebarExpandButton = SidebarExpandButton;
@@ -13,6 +13,6 @@ declare const toggleVariants: (props?: ({
13
13
  declare function ToggleGroup({ className, variant, size, spacing, children, style, ...props }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants> & {
14
14
  spacing?: number;
15
15
  }): React.JSX.Element;
16
- declare function ToggleGroupItem({ className, children, variant, size, ...props }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>): React.JSX.Element;
16
+ declare function ToggleGroupItem({ className, children, variant, size, onFocus, ...props }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>): React.JSX.Element;
17
17
  export { ToggleGroup, ToggleGroupItem };
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/toggle-group/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,oBAAoB,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAIjE;;;;GAIG;AACH,QAAA,MAAM,cAAc;;;8EAoBnB,CAAA;AAYD,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAW,EACX,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GACvD,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,qBAwBF;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GACvD,YAAY,CAAC,OAAO,cAAc,CAAC,qBAuBpC;AAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/toggle-group/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,oBAAoB,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAIjE;;;;GAIG;AACH,QAAA,MAAM,cAAc;;;8EAoBnB,CAAA;AA4DD,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAW,EACX,QAAQ,EACR,KAAK,EACL,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GACvD,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,qBA+BF;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,OAAO,EACP,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GACvD,YAAY,CAAC,OAAO,cAAc,CAAC,qBAiDpC;AAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAA"}
@@ -63,12 +63,58 @@ const toggleVariants = (0, class_variance_authority_1.cva)("hover:bg-muted hover
63
63
  size: 'default'
64
64
  }
65
65
  });
66
+ const ARROW_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
67
+ /**
68
+ * Is an arrow key down right now?
69
+ *
70
+ * This is how an item tells keyboard navigation apart from a pointer press or a
71
+ * programmatic focus, and it is the seam Radix uses for the same job in its own
72
+ * `RadioGroup`. It works because `RovingFocusGroup` defers the focus move to a
73
+ * `setTimeout`: the keydown has already bubbled to `document` and set the flag
74
+ * by the time the item receives `focus`.
75
+ *
76
+ * The distinction is not cosmetic. A pointer press focuses BEFORE the click
77
+ * lands, so selecting on every focus would turn one click into
78
+ * select-then-deselect and break mouse selection outright.
79
+ *
80
+ * Returns null when disabled, so `type="multiple"` carries no flag to read.
81
+ */
82
+ function useArrowKeyPressed(enabled) {
83
+ const arrowKeyPressed = React.useRef(false);
84
+ React.useEffect(() => {
85
+ if (!enabled)
86
+ return;
87
+ const onKeyDown = (event) => {
88
+ if (ARROW_KEYS.includes(event.key))
89
+ arrowKeyPressed.current = true;
90
+ };
91
+ const onKeyUp = () => {
92
+ arrowKeyPressed.current = false;
93
+ };
94
+ document.addEventListener('keydown', onKeyDown);
95
+ document.addEventListener('keyup', onKeyUp);
96
+ window.addEventListener('blur', onKeyUp);
97
+ return () => {
98
+ document.removeEventListener('keydown', onKeyDown);
99
+ document.removeEventListener('keyup', onKeyUp);
100
+ window.removeEventListener('blur', onKeyUp);
101
+ // A group unmounted mid-keystroke never sees the keyup.
102
+ arrowKeyPressed.current = false;
103
+ };
104
+ }, [enabled]);
105
+ return enabled ? arrowKeyPressed : null;
106
+ }
66
107
  const ToggleGroupContext = React.createContext({
67
108
  size: 'default',
68
109
  variant: 'default',
69
- spacing: 0
110
+ spacing: 0,
111
+ arrowKeyPressed: null
70
112
  });
71
113
  function ToggleGroup({ className, variant, size, spacing = 0, children, style, ...props }) {
114
+ // Read, never destructured: `type` is the discriminant of the Radix props
115
+ // union, and pulling it out then spreading it back widens the union so the
116
+ // single/multiple props stop resolving.
117
+ const arrowKeyPressed = useArrowKeyPressed(props.type === 'single');
72
118
  return ((0, jsx_runtime_1.jsx)(ToggleGroupPrimitive.Root, { "data-slot": "toggle-group", "data-variant": variant, "data-size": size, "data-spacing": spacing,
73
119
  // Caller style first: `--gap` is ours and must survive, but everything
74
120
  // else the caller passes has to reach the element.
@@ -76,12 +122,35 @@ function ToggleGroup({ className, variant, size, spacing = 0, children, style, .
76
122
  // Legacy carried a `data-[spacing=default]:...:shadow-xs` rule here that
77
123
  // never matched — `data-spacing` is always a number. Removed rather than
78
124
  // activated, so the rendered pixels stay identical to sindarian-x.
79
- 'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md', className), ...props, children: (0, jsx_runtime_1.jsx)(ToggleGroupContext.Provider, { value: { variant, size, spacing }, children: children }) }));
125
+ 'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md', className), ...props, children: (0, jsx_runtime_1.jsx)(ToggleGroupContext.Provider, { value: { variant, size, spacing, arrowKeyPressed }, children: children }) }));
80
126
  }
81
- function ToggleGroupItem({ className, children, variant, size, ...props }) {
127
+ function ToggleGroupItem({ className, children, variant, size, onFocus, ...props }) {
82
128
  const context = React.useContext(ToggleGroupContext);
129
+ /**
130
+ * Selection follows focus, which is what `role="radio"` promises.
131
+ *
132
+ * With `type="single"` Radix puts the group on the ARIA radio pattern: the
133
+ * root is a `radiogroup`, each item a `radio` with `aria-checked`. Under that
134
+ * pattern an arrow key both moves focus and checks the item it lands on.
135
+ * Radix only moves focus, so a screen-reader operator used to arrow across
136
+ * "radio, not checked, 2 of 3" with nothing ever selected.
137
+ *
138
+ * `type="multiple"` is a `toolbar` of `aria-pressed` buttons and keeps its
139
+ * current behavior, where moving focus without pressing is correct: the flag
140
+ * is null there.
141
+ *
142
+ * Clicking the element rather than writing the value keeps a single
143
+ * activation path, so Radix's own toggle and any caller `onClick` both fire
144
+ * exactly as they do for a real click.
145
+ */
146
+ const handleFocus = (event) => {
147
+ onFocus?.(event);
148
+ if (context.arrowKeyPressed?.current) {
149
+ event.currentTarget.click();
150
+ }
151
+ };
83
152
  return ((0, jsx_runtime_1.jsx)(ToggleGroupPrimitive.Item, { "data-slot": "toggle-group-item", "data-variant": context.variant || variant, "data-size": context.size || size, "data-spacing": context.spacing, className: (0, utils_1.cn)(toggleVariants({
84
153
  variant: context.variant || variant,
85
154
  size: context.size || size
86
- }), 'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10', 'data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l', className), ...props, children: children }));
155
+ }), 'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10', 'data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l', className), ...props, onFocus: handleFocus, children: children }));
87
156
  }
@@ -6,6 +6,21 @@ export type TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root> &
6
6
  };
7
7
  declare function Tooltip({ open: _open, onOpenChange, disabled, ...props }: TooltipProps): React.JSX.Element;
8
8
  declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): React.JSX.Element;
9
+ /**
10
+ * The fill is a RAW palette step, not a theme token: `--color-shadcn-600` is a
11
+ * flat hex, so an inverted tooltip stays #27272A under both themes. The ink has
12
+ * to be theme-fixed too, which rules out `--primary-foreground` and
13
+ * `--background`: both invert, and both land on 1.00:1 against this fill in
14
+ * dark.
15
+ *
16
+ * base/400 was not unreadable here (5.81:1 on this fill; the 2.56:1 figure that
17
+ * class earns elsewhere is against a LIGHT ground, which this is not). It moved
18
+ * one step to base/300 because base/400 is banned kit-wide in
19
+ * `__tests__/ink-classes.test.ts`: its only safe ground is a fixed-dark fill,
20
+ * and that narrow exception had already leaked into eight slots that were not
21
+ * one. base/300 reads 10.08:1 here, and keeps this line quieter than the
22
+ * `text-white` a consumer puts beside it (`page-header/index.tsx:226`).
23
+ */
9
24
  declare function TooltipContent({ className, sideOffset, children, ...props }: React.ComponentProps<typeof TooltipPrimitive.Content>): React.JSX.Element;
10
25
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
11
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/tooltip/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAI3D,iBAAS,eAAe,CAAC,EACvB,aAAiB,EACjB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,qBAQxD;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,CAC7C,OAAO,gBAAgB,CAAC,IAAI,CAC7B,GAAG;IACF,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,iBAAS,OAAO,CAAC,EACf,IAAI,EAAE,KAAK,EACX,YAAY,EACZ,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,YAAY,qBAwBd;AAED,iBAAS,cAAc,CAAC,EACtB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAEvD;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,UAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAiBvD;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/tooltip/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,gBAAgB,MAAM,yBAAyB,CAAA;AAI3D,iBAAS,eAAe,CAAC,EACvB,aAAiB,EACjB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAC,qBAQxD;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC,cAAc,CAC7C,OAAO,gBAAgB,CAAC,IAAI,CAC7B,GAAG;IACF,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,iBAAS,OAAO,CAAC,EACf,IAAI,EAAE,KAAK,EACX,YAAY,EACZ,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,YAAY,qBAwBd;AAED,iBAAS,cAAc,CAAC,EACtB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAEvD;AAED;;;;;;;;;;;;;;GAcG;AACH,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,UAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,OAAO,CAAC,qBAiBvD;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA"}
@@ -61,6 +61,21 @@ function Tooltip({ open: _open, onOpenChange, disabled, ...props }) {
61
61
  function TooltipTrigger({ ...props }) {
62
62
  return (0, jsx_runtime_1.jsx)(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
63
63
  }
64
+ /**
65
+ * The fill is a RAW palette step, not a theme token: `--color-shadcn-600` is a
66
+ * flat hex, so an inverted tooltip stays #27272A under both themes. The ink has
67
+ * to be theme-fixed too, which rules out `--primary-foreground` and
68
+ * `--background`: both invert, and both land on 1.00:1 against this fill in
69
+ * dark.
70
+ *
71
+ * base/400 was not unreadable here (5.81:1 on this fill; the 2.56:1 figure that
72
+ * class earns elsewhere is against a LIGHT ground, which this is not). It moved
73
+ * one step to base/300 because base/400 is banned kit-wide in
74
+ * `__tests__/ink-classes.test.ts`: its only safe ground is a fixed-dark fill,
75
+ * and that narrow exception had already leaked into eight slots that were not
76
+ * one. base/300 reads 10.08:1 here, and keeps this line quieter than the
77
+ * `text-white` a consumer puts beside it (`page-header/index.tsx:226`).
78
+ */
64
79
  function TooltipContent({ className, sideOffset = 0, children, ...props }) {
65
- return ((0, jsx_runtime_1.jsx)(TooltipPrimitive.Portal, { children: (0, jsx_runtime_1.jsxs)(TooltipPrimitive.Content, { "data-slot": "tooltip-content", sideOffset: sideOffset, className: (0, utils_1.cn)('bg-shadcn-600 text-shadcn-400 motion-safe:animate-in fade-in-0 zoom-in-95 motion-safe:data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 rounded-md px-3 py-1.5 text-sm shadow-md', className), ...props, children: [children, (0, jsx_runtime_1.jsx)(TooltipPrimitive.Arrow, { className: "bg-shadcn-600 fill-shadcn-600 z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })] }) }));
80
+ return ((0, jsx_runtime_1.jsx)(TooltipPrimitive.Portal, { children: (0, jsx_runtime_1.jsxs)(TooltipPrimitive.Content, { "data-slot": "tooltip-content", sideOffset: sideOffset, className: (0, utils_1.cn)('bg-shadcn-600 text-shadcn-300 motion-safe:animate-in fade-in-0 zoom-in-95 motion-safe:data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 rounded-md px-3 py-1.5 text-sm shadow-md', className), ...props, children: [children, (0, jsx_runtime_1.jsx)(TooltipPrimitive.Arrow, { className: "bg-shadcn-600 fill-shadcn-600 z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })] }) }));
66
81
  }
@@ -5,8 +5,10 @@
5
5
  * — no zebra fills. Each row: a quiet sentence-case sans label on the left, a mono
6
6
  * `tabular-nums` value on the right, `hover:bg-body-surface` as the quiet row
7
7
  * affordance (the recessed page surface, one step behind `bg-card`, in both
8
- * themes). Escalate the value color (`text-credit`, `text-system-alert`) only
9
- * when a metric crosses a threshold.
8
+ * themes). Escalate the value color (`text-credit`, `text-system-alert-h1a`)
9
+ * only when a metric crosses a threshold — the INK tokens, never the bare
10
+ * `text-system-*` fills, which are picked to carry white and read as low as
11
+ * 1.78:1 on this surface in light.
10
12
  *
11
13
  * <Blotter>
12
14
  * <BlotterRow label="Resolved on time" value="128" />
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/blotter/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,YAAY,+BAE5D;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;IAChB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,cAAc,EACd,SAAS,EACT,OAAe,EACf,OAAe,EAChB,EAAE,eAAe,+BAkDjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/blotter/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,YAAY,+BAE5D;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;IAChB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,cAAc,EACd,SAAS,EACT,OAAe,EACf,OAAe,EAChB,EAAE,eAAe,+BAkDjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"aging-buckets.d.ts","sourceRoot":"","sources":["../../../src/domain/delinquency-aging/aging-buckets.tsx"],"names":[],"mappings":"AAyCA,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACvB;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;AAElE;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;IAC1C,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,yEAAyE;IACzE,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B;oFACgF;IAChF,WAAW,CAAC,EAAE,SAAS,GAAG,KAAK,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA2BD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAMlE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EAAE,EACtB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAiB,EACjB,MAAM,EACN,WAAuB,EACvB,SAAS,EACV,EAAE,iBAAiB,+BAkHnB"}
1
+ {"version":3,"file":"aging-buckets.d.ts","sourceRoot":"","sources":["../../../src/domain/delinquency-aging/aging-buckets.tsx"],"names":[],"mappings":"AAyCA,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACvB;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAA;AAElE;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;IAC1C,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,yEAAyE;IACzE,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B;oFACgF;IAChF,WAAW,CAAC,EAAE,SAAS,GAAG,KAAK,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAgCD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAMlE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EAAE,EACtB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAiB,EACjB,MAAM,EACN,WAAuB,EACvB,SAAS,EACV,EAAE,iBAAiB,+BAkHnB"}
@@ -43,11 +43,16 @@ const money_math_1 = require("../money-math");
43
43
  const money_text_1 = require("../money-text");
44
44
  /** Band → glyph + tint + accessible word. The glyph (and the sr-only word) is
45
45
  * the load-bearing severity cue; the tint only reinforces it, so the
46
- * escalation survives grayscale and color-vision deficiency. */
46
+ * escalation survives grayscale and color-vision deficiency.
47
+ *
48
+ * The tint is an INK token (`-h1a`). A load-bearing glyph answers to the 3:1
49
+ * floor of SC 1.4.11, and the bare fill token `--system-alert` reads 1.78:1 on
50
+ * `--card` and 1.62:1 on `--body-surface` in light — the cue was invisible on
51
+ * the row it escalates. */
47
52
  const BAND = {
48
53
  current: {
49
54
  Icon: lucide_react_1.CircleDot,
50
- tint: 'text-system-success',
55
+ tint: 'text-system-success-h1a',
51
56
  word: 'Em dia'
52
57
  },
53
58
  recent: {
@@ -57,7 +62,7 @@ const BAND = {
57
62
  },
58
63
  aging: {
59
64
  Icon: lucide_react_1.AlertTriangle,
60
- tint: 'text-system-alert',
65
+ tint: 'text-system-alert-h1a',
61
66
  word: 'Em atraso'
62
67
  },
63
68
  overdue: { Icon: lucide_react_1.AlertOctagon, tint: 'text-credit', word: 'Vencido' }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/delinquency-aging/index.tsx"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAKtE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAOpE;;wEAEwE;AACxE,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;oEACoE;AACpE,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,iFAAiF;IACjF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,6EAA6E;IAC7E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB;;0EAEsE;IACtE,aAAa,EAAE,OAAO,CAAA;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,KAAK,EAAE,MAAM,GACZ,eAAe,CAuDjB;AAoFD,MAAM,WAAW,qBAAqB;IACpC;yEACqE;IACrE,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;sBAGkB;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;IACnD,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;oBAEgB;IAChB,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC;;;mDAG+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;yEACqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,KAAK,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAA2B,EAC3B,cAAc,EACd,UAA2B,EAC3B,kBAAoC,EACpC,YAAY,EACZ,IAAW,EACX,MAAY,EACZ,SAAiB,EACjB,WAAuB,EACvB,SAAS,EACV,EAAE,qBAAqB,+BA6EvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/delinquency-aging/index.tsx"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAKtE,YAAY,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAOpE;;wEAEwE;AACxE,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;oEACoE;AACpE,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,iFAAiF;IACjF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,6EAA6E;IAC7E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB;;0EAEsE;IACtE,aAAa,EAAE,OAAO,CAAA;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,KAAK,EAAE,MAAM,GACZ,eAAe,CAuDjB;AAyFD,MAAM,WAAW,qBAAqB;IACpC;yEACqE;IACrE,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;sBAGkB;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;IACnD,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;oBAEgB;IAChB,YAAY,CAAC,EAAE,kBAAkB,CAAA;IACjC;;;mDAG+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;yEACqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,KAAK,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAA2B,EAC3B,cAAc,EACd,UAA2B,EAC3B,kBAAoC,EACpC,YAAY,EACZ,IAAW,EACX,MAAY,EACZ,SAAiB,EACjB,WAAuB,EACvB,SAAS,EACV,EAAE,qBAAqB,+BA6EvB"}
@@ -182,10 +182,15 @@ function exactBand(overdue, total, warn, breach) {
182
182
  /** Band → glyph + tint + accessible word. The glyph and sr-only word are the
183
183
  * load-bearing cue; the tint only reinforces, so the band survives grayscale
184
184
  * and color-vision deficiency. Mirrors the gauge's three-band canon, renamed
185
- * to the delinquency vocabulary. */
185
+ * to the delinquency vocabulary.
186
+ *
187
+ * The tint is an INK token (`-h1a`), because it is painted on the `Figure`
188
+ * below as well as on the glyph. The bare fill tokens read 1.78:1
189
+ * (`--system-alert`) and 3.35:1 (`--system-success`) on every light surface in
190
+ * the kit — the alert one under even the 3:1 floor a glyph answers to. */
186
191
  const RATE_BAND = {
187
- low: { Icon: lucide_react_1.ShieldCheck, tint: 'text-system-success', word: 'Saudável' },
188
- warn: { Icon: lucide_react_1.TriangleAlert, tint: 'text-system-alert', word: 'Elevada' },
192
+ low: { Icon: lucide_react_1.ShieldCheck, tint: 'text-system-success-h1a', word: 'Saudável' },
193
+ warn: { Icon: lucide_react_1.TriangleAlert, tint: 'text-system-alert-h1a', word: 'Elevada' },
189
194
  breach: { Icon: lucide_react_1.AlertOctagon, tint: 'text-credit', word: 'Em estresse' }
190
195
  };
191
196
  function DelinquencyAging({ buckets, currency, locale, rateLabel = 'Inadimplência', rateBandLabels, emptyLabel = 'sem carteira', indeterminateLabel = 'indeterminada', bucketLabels, warn = 0.05, breach = 0.1, showTotal = false, healthyTone = 'success', className }) {
@@ -170,5 +170,5 @@ function CopyValue({ value }) {
170
170
  setCopied(false);
171
171
  });
172
172
  };
173
- return ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: copy, "aria-label": copied ? 'Copiado para a área de transferência' : 'Copiar valor', className: "text-muted-foreground hover:text-foreground focus:ring-ring inline-flex size-5 shrink-0 items-center justify-center rounded-sm transition-colors duration-150 ease-out focus:ring-2 focus:outline-none", children: copied ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { "aria-hidden": true, className: "text-system-success size-3" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { "aria-hidden": true, className: "size-3" })) }));
173
+ return ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: copy, "aria-label": copied ? 'Copiado para a área de transferência' : 'Copiar valor', className: "text-muted-foreground hover:text-foreground focus:ring-ring inline-flex size-5 shrink-0 items-center justify-center rounded-sm transition-colors duration-150 ease-out focus:ring-2 focus:outline-none", children: copied ? ((0, jsx_runtime_1.jsx)(lucide_react_1.Check, { "aria-hidden": true, className: "text-system-success-h1a size-3" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.Copy, { "aria-hidden": true, className: "size-3" })) }));
174
174
  }
@@ -50,7 +50,7 @@ function StatusRail({ lead, items = [], chips = [], className }) {
50
50
  // Tiny mono token: raised a hair off the sunken tape by the
51
51
  // card surface + whisper shadow.
52
52
  'inline-flex items-center gap-1 rounded-sm border px-1.5 py-0.5 shadow-sm', chip.alarm
53
- ? 'border-destructive/40 bg-destructive/10 text-destructive'
53
+ ? 'border-destructive/40 bg-destructive/10 text-system-error-h1a'
54
54
  : 'border-border bg-card text-foreground'), children: [chip.alarm ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(lucide_react_1.TriangleAlert, { "aria-hidden": true, className: "size-3" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "(alarme)" })] })) : null, chip.value] })] }, chip.id ?? i))) })) : null] }));
55
55
  }
56
56
  /** A tape item preceded by a separator dot when it is not the first token. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/threshold-gauge/index.tsx"],"names":[],"mappings":"AAiDA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEjD;gFACgF;AAChF,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAA;AAEjE;;gDAEgD;AAChD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAEjE;;;;wEAIwE;AACxE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAA;AAE/C,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC;oEACgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb;;;;iDAI6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,qEAAqE;IACrE,SAAS,EAAE,cAAc,CAAA;IACzB,qDAAqD;IACrD,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;uCAImC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;0EAIsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAmCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,cAAc,GACxB,SAAS,CAUX;AA+CD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,YAAY,EACZ,GAAO,EACP,GAAG,EACH,IAAI,EACJ,MAAM,EACN,KAAK,EACL,SAAS,EACT,MAAkB,EAClB,QAAQ,EACR,MAAM,EACN,KAAK,EACL,SAAS,EACT,UAAU,EACV,SAAS,EACV,EAAE,mBAAmB,+BA8ErB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/threshold-gauge/index.tsx"],"names":[],"mappings":"AAiDA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEjD;gFACgF;AAChF,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAA;AAEjE;;gDAEgD;AAChD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAEjE;;;;wEAIwE;AACxE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAA;AAE/C,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAA;IACd,8EAA8E;IAC9E,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC;oEACgE;IAChE,KAAK,EAAE,MAAM,CAAA;IACb;;;;iDAI6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,wBAAwB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,kEAAkE;IAClE,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,qEAAqE;IACrE,SAAS,EAAE,cAAc,CAAA;IACzB,qDAAqD;IACrD,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;uCAImC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;0EAIsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAuCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,cAAc,GACxB,SAAS,CAUX;AA+CD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,YAAY,EACZ,GAAO,EACP,GAAG,EACH,IAAI,EACJ,MAAM,EACN,KAAK,EACL,SAAS,EACT,MAAkB,EAClB,QAAQ,EACR,MAAM,EACN,KAAK,EACL,SAAS,EACT,UAAU,EACV,SAAS,EACV,EAAE,mBAAmB,+BA8ErB"}
@@ -55,22 +55,26 @@ const money_text_1 = require("../money-text");
55
55
  const BAND = {
56
56
  low: {
57
57
  Icon: lucide_react_1.ShieldCheck,
58
- tint: 'text-system-success',
58
+ tint: 'text-system-success-h1a',
59
59
  word: 'Dentro do limite'
60
60
  },
61
61
  warn: {
62
62
  Icon: lucide_react_1.TriangleAlert,
63
- tint: 'text-system-alert',
63
+ tint: 'text-system-alert-h1a',
64
64
  word: 'Próximo do limite'
65
65
  },
66
66
  breach: {
67
67
  Icon: lucide_react_1.OctagonX,
68
- tint: 'text-destructive',
68
+ tint: 'text-system-error-h1a',
69
69
  word: 'Limite ultrapassado'
70
70
  }
71
71
  };
72
- /** Track fill tint per band — kept distinct from the glyph tint so the bar can
73
- * use the softer wash while the glyph carries the full tint. */
72
+ /** Track fill tint per band, and the reason it is a SEPARATE map from the
73
+ * tint above: these are the fill tokens, and a fill answers to no text floor.
74
+ * The tint above is painted on the band glyph AND on the `Figure`, so it has
75
+ * to be the ink family. Light `--system-alert` is #EAB308, about 1.9:1 on
76
+ * white, and `--system-success` about 3.3:1 — both were readable only as a
77
+ * bar wash, never as the number the reader is here to read. */
74
78
  const BAND_FILL = {
75
79
  low: 'bg-system-success',
76
80
  warn: 'bg-system-alert',
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/stat-card/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtC,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAA;AAoB5E,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,KAAK,EAAE,SAAS,CAAA;IAChB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,uDAAuD;IACvD,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,sDAAsD;IACtD,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;IAC7D,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yCAAyC;IACzC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAwED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAgB,EAChB,KAAK,EACL,QAAkB,EAClB,IAAI,EACJ,SAAS,EACV,EAAE,aAAa,+BAgCf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/stat-card/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAQtC,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAA;AA4B5E,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,SAAS,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,KAAK,EAAE,SAAS,CAAA;IAChB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,uDAAuD;IACvD,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,sDAAsD;IACtD,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;IAC7D,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yCAAyC;IACzC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAwED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAgB,EAChB,KAAK,EACL,QAAkB,EAClB,IAAI,EACJ,SAAS,EACV,EAAE,aAAa,+BAgCf"}