@toolr/ui-design 0.1.2 → 0.1.4

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 (55) hide show
  1. package/README.md +0 -7
  2. package/components/content/info-panel-primitives.tsx +3 -3
  3. package/components/lib/ai-tools.tsx +1 -1
  4. package/components/lib/form-colors.ts +3 -0
  5. package/components/lib/theme-engine.ts +10 -0
  6. package/components/sections/captured-issues/captured-issues-panel.tsx +1 -1
  7. package/components/sections/golden-snapshots/file-diff-viewer.tsx +2 -2
  8. package/components/sections/golden-snapshots/snapshot-manager.tsx +3 -3
  9. package/components/sections/golden-snapshots/status-overview.tsx +4 -4
  10. package/components/sections/golden-snapshots/version-manager.tsx +3 -3
  11. package/components/sections/report-bug/screenshot-uploader.tsx +2 -2
  12. package/components/sections/snapshot-browser/snapshot-tree.tsx +1 -1
  13. package/components/sections/snippets-editor/snippets-editor.tsx +5 -5
  14. package/components/ui/action-dialog.tsx +1 -1
  15. package/components/ui/badge.tsx +8 -6
  16. package/components/ui/breadcrumb.tsx +1 -1
  17. package/components/ui/confirm-badge.tsx +4 -2
  18. package/components/ui/file-structure-section.tsx +139 -74
  19. package/components/ui/file-tree.tsx +2 -2
  20. package/components/ui/files-panel.tsx +5 -5
  21. package/components/ui/filter-dropdown.tsx +3 -3
  22. package/components/ui/frontmatter-form-header.tsx +2 -2
  23. package/components/ui/icon-button.tsx +6 -2
  24. package/components/ui/input.tsx +1 -1
  25. package/components/ui/label.tsx +8 -5
  26. package/components/ui/modal.tsx +1 -1
  27. package/components/ui/nav-card.tsx +1 -1
  28. package/components/ui/navigation-bar.tsx +1 -1
  29. package/components/ui/number-input.tsx +1 -1
  30. package/components/ui/registry-card.tsx +7 -7
  31. package/components/ui/registry-detail.tsx +5 -2
  32. package/components/ui/resizable-textarea.tsx +2 -2
  33. package/components/ui/segmented-toggle.tsx +36 -18
  34. package/components/ui/select.tsx +3 -3
  35. package/components/ui/selection-grid.tsx +7 -19
  36. package/components/ui/settings-card.tsx +27 -0
  37. package/components/ui/settings-info-box.tsx +80 -0
  38. package/components/ui/settings-section-title.tsx +24 -0
  39. package/components/ui/snapshot-card.tsx +2 -2
  40. package/components/ui/snippets-panel.tsx +9 -9
  41. package/components/ui/sort-dropdown.tsx +1 -1
  42. package/components/ui/tab-bar.tsx +1 -1
  43. package/components/ui/tooltip.tsx +1 -1
  44. package/dist/content.js +3 -3
  45. package/dist/index.d.ts +93 -46
  46. package/dist/index.js +1452 -1236
  47. package/dist/tokens/primitives.css +10 -0
  48. package/dist/tokens/semantic.css +3 -0
  49. package/index.ts +4 -1
  50. package/package.json +1 -7
  51. package/tokens/primitives.css +10 -0
  52. package/tokens/semantic.css +3 -0
  53. package/dist/preset.d.ts +0 -24
  54. package/dist/preset.js +0 -17
  55. package/tailwind-preset.ts +0 -22
package/README.md CHANGED
@@ -14,19 +14,12 @@ Shared UI design system for toolr applications. Provides components, design toke
14
14
  @import "@toolr/ui-design/tokens";
15
15
  ```
16
16
 
17
- ```ts
18
- // tailwind.config.ts
19
- import { toolrPreset } from '@toolr/ui-design/preset'
20
- export default { presets: [toolrPreset] }
21
- ```
22
-
23
17
  ## Exports
24
18
 
25
19
  | Path | Content |
26
20
  |------|---------|
27
21
  | `@toolr/ui-design` | All components, hooks, types, utilities |
28
22
  | `@toolr/ui-design/tokens` | CSS design tokens (semantic + primitives + keyframes) |
29
- | `@toolr/ui-design/preset` | Tailwind preset (Inter font, extended breakpoints) |
30
23
  | `@toolr/ui-design/content` | Info panel primitives |
31
24
  | `@toolr/ui-design/diagrams` | Diagram utilities |
32
25
 
@@ -114,7 +114,7 @@ export function Callout({ color, children }: { color: string; children: ReactNod
114
114
  export function CalloutCode({ color, children }: { color: string; children: ReactNode }) {
115
115
  const c = CALLOUT_COLORS[color] ?? CALLOUT_COLORS.blue
116
116
  return (
117
- <code className={`block bg-neutral-800/80 px-2 py-1 rounded mt-1.5 text-[13px] ${c.codeText}`}>
117
+ <code className={`block bg-neutral-800/80 px-2 py-1 rounded mt-1.5 text-sm ${c.codeText}`}>
118
118
  {children}
119
119
  </code>
120
120
  )
@@ -204,7 +204,7 @@ export function TitledLI({ color, title, children }: { color: string; title: str
204
204
 
205
205
  export function CalloutDialog({ color, lines }: { color: string; lines: { speaker: string; text: string }[] }) {
206
206
  return (
207
- <div className="bg-neutral-800/80 rounded px-2 py-1 mt-1.5 flex flex-col gap-0.5 text-[13px]">
207
+ <div className="bg-neutral-800/80 rounded px-2 py-1 mt-1.5 flex flex-col gap-0.5 text-sm">
208
208
  {lines.map((line, idx) => (
209
209
  <div key={idx}>
210
210
  <span className={`text-${color}-300 font-semibold mr-1`}>{line.speaker}:</span>
@@ -238,7 +238,7 @@ export function StatusBadge({ value, badgeColor, label, children, even }: {
238
238
  <DLRow
239
239
  term={
240
240
  <span className="flex items-center gap-1.5">
241
- <span className={`inline-flex items-center justify-center w-5 h-5 rounded-full bg-${badgeColor}-500/20 text-${badgeColor}-400 text-[11px] font-bold shrink-0`}>{value}</span>
241
+ <span className={`inline-flex items-center justify-center w-5 h-5 rounded-full bg-${badgeColor}-500/20 text-${badgeColor}-400 text-xss font-bold shrink-0`}>{value}</span>
242
242
  <span className={`text-${badgeColor}-400 font-semibold`}>{label}</span>
243
243
  </span>
244
244
  }
@@ -38,7 +38,7 @@ export function AiToolIcon({ tool, size, showName, className, style }: {
38
38
  return (
39
39
  <span style={{ display: 'inline-flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
40
40
  {img}
41
- <span className="text-[11px] text-neutral-400">{AI_TOOL_NAMES[tool as AiToolKey] ?? tool}</span>
41
+ <span className="text-xss text-neutral-400">{AI_TOOL_NAMES[tool as AiToolKey] ?? tool}</span>
42
42
  </span>
43
43
  )
44
44
  }
@@ -1,6 +1,7 @@
1
1
  export type FormColor =
2
2
  | 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow'
3
3
  | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky'
4
+ | 'pink' | 'teal'
4
5
 
5
6
  interface FormColorConfig {
6
7
  /** Idle border class (e.g. 'border-blue-500/30') */
@@ -29,4 +30,6 @@ export const FORM_COLORS: Record<FormColor, FormColorConfig> = {
29
30
  violet: { border: 'border-violet-500/30', hover: 'hover:bg-violet-500/20 hover:border-violet-500/40', focus: 'focus:border-violet-500', selectedBg: 'bg-violet-600/20', accent: 'text-violet-400' },
30
31
  neutral: { border: 'border-neutral-500/30', hover: 'hover:bg-neutral-500/20 hover:border-neutral-500/40', focus: 'focus:border-neutral-500', selectedBg: 'bg-neutral-600/20', accent: 'text-neutral-400' },
31
32
  sky: { border: 'border-sky-500/30', hover: 'hover:bg-sky-500/20 hover:border-sky-500/40', focus: 'focus:border-sky-500', selectedBg: 'bg-sky-600/20', accent: 'text-sky-400' },
33
+ pink: { border: 'border-pink-500/30', hover: 'hover:bg-pink-500/20 hover:border-pink-500/40', focus: 'focus:border-pink-500', selectedBg: 'bg-pink-600/20', accent: 'text-pink-400' },
34
+ teal: { border: 'border-teal-500/30', hover: 'hover:bg-teal-500/20 hover:border-teal-500/40', focus: 'focus:border-teal-500', selectedBg: 'bg-teal-600/20', accent: 'text-teal-400' },
32
35
  }
@@ -109,6 +109,16 @@ export function isLightTheme(themeId: ThemeId): boolean {
109
109
  return LIGHT_THEMES.includes(themeId)
110
110
  }
111
111
 
112
+ /**
113
+ * Apply a theme to the document by setting CSS custom properties on the root element.
114
+ *
115
+ * IMPORTANT — body background: Portal-based components (Select, Tooltip) render at
116
+ * document.body via createPortal. Their backgrounds use --popover which is semi-transparent
117
+ * (rgba(0,0,0,0.8)). If <body> has no background-color, the browser default (white) bleeds
118
+ * through, making dropdowns/tooltips appear gray instead of dark.
119
+ *
120
+ * Consuming apps MUST set: body { background-color: var(--background); }
121
+ */
112
122
  export function applyTheme(themeId: ThemeId, accentHue: number | null, dims: Record<SurfaceKey, number> = DEFAULT_DIMS, outline: number = DEFAULT_OUTLINE, root: HTMLElement = document.documentElement): void {
113
123
  const scale = generateScale(themeId, accentHue, BASE_THEMES[themeId].maxSat, dims, outline)
114
124
  const light = isLightTheme(themeId)
@@ -163,7 +163,7 @@ export function CapturedIssuesPanel({
163
163
  <Check className="w-5 h-5 text-green-400" />
164
164
  </div>
165
165
  <div>
166
- <h3 className="text-neutral-300 font-medium">No Issues Captured</h3>
166
+ <h3 className="text-sm text-neutral-300 font-medium">No Issues Captured</h3>
167
167
  <p className="text-sm text-neutral-500">Everything is running smoothly.</p>
168
168
  </div>
169
169
  </div>
@@ -93,7 +93,7 @@ function DiffFileItem({ file, isSelected, onSelect, onReset, resettingFile, anyR
93
93
  {icon}
94
94
  <span className="truncate">{filename}</span>
95
95
  {statusLabel && (
96
- <span className={`text-[10px] font-medium ml-auto flex-shrink-0 ${statusColor}`}>
96
+ <span className={`text-xss font-medium ml-auto flex-shrink-0 ${statusColor}`}>
97
97
  {statusLabel}
98
98
  </span>
99
99
  )}
@@ -171,7 +171,7 @@ function DiffFileTreePanel({ sync, componentLabels, renderFileIcon }: DiffFileTr
171
171
  const chevronSize = isRoot ? 'w-4 h-4' : 'w-3 h-3'
172
172
 
173
173
  const countElement = isRoot ? (
174
- <span className={`ml-auto px-1.5 py-0.5 rounded-full text-[10px] font-medium ${color.pillBg} ${color.text}`}>
174
+ <span className={`ml-auto px-1.5 py-0.5 rounded-full text-xss font-medium ${color.pillBg} ${color.text}`}>
175
175
  {fileCount}
176
176
  </span>
177
177
  ) : (
@@ -54,7 +54,7 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
54
54
  <div className="bg-neutral-900 rounded-lg p-4 border border-neutral-700">
55
55
  <div className="flex items-center gap-3 mb-3">
56
56
  <Plus className="w-5 h-5 text-green-400" />
57
- <h4 className="text-neutral-300 font-medium">Create Snapshot</h4>
57
+ <h4 className="text-sm text-neutral-300 font-medium">Create Snapshot</h4>
58
58
  </div>
59
59
  <p className="text-xs text-neutral-600 mb-3">
60
60
  Archives the current live state. If components differ from golden, their patch version is auto-bumped.
@@ -85,7 +85,7 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
85
85
  <div className="flex items-center justify-between px-4 py-3 border-b border-neutral-700">
86
86
  <div className="flex items-center gap-2">
87
87
  <Archive className="w-4 h-4 text-neutral-500" />
88
- <h4 className="text-neutral-300 font-medium">Snapshots</h4>
88
+ <h4 className="text-sm text-neutral-300 font-medium">Snapshots</h4>
89
89
  <span className="text-xs text-neutral-500">({manifest?.snapshots.length ?? 0})</span>
90
90
  </div>
91
91
  <IconButton
@@ -114,7 +114,7 @@ export function SnapshotManager({ sync }: SnapshotManagerProps) {
114
114
  <div className="flex items-center gap-2">
115
115
  <span className="text-sm font-mono text-neutral-300">v{snap.version}</span>
116
116
  {snap.version === manifest.activeVersion && (
117
- <span className="px-1.5 py-0.5 bg-green-500/20 text-green-400 text-[10px] rounded font-medium">
117
+ <span className="px-1.5 py-0.5 bg-green-500/20 text-green-400 text-xss rounded font-medium">
118
118
  active
119
119
  </span>
120
120
  )}
@@ -84,7 +84,7 @@ export function StatusOverview({
84
84
  <div className="bg-neutral-900 rounded-lg p-4 border border-amber-500/30">
85
85
  <div className="flex items-center gap-3 mb-3">
86
86
  <Archive className="w-5 h-5 text-amber-400" />
87
- <h3 className="text-neutral-300 font-medium">Bundled Seed (App Distribution)</h3>
87
+ <h3 className="text-sm text-neutral-300 font-medium">Bundled Seed (App Distribution)</h3>
88
88
  {status?.seed.meta && renderVersionBadge(status.seed.meta, 'bg-amber-500/20 text-amber-400')}
89
89
  </div>
90
90
  <div className="grid grid-cols-2 gap-4 text-sm">
@@ -121,7 +121,7 @@ export function StatusOverview({
121
121
  <div className="bg-neutral-900 rounded-lg p-4 border border-blue-500/30">
122
122
  <div className="flex items-center gap-2 mb-3">
123
123
  <div className="w-3 h-3 rounded-full bg-blue-400" />
124
- <h4 className="text-neutral-300 font-medium">Golden (Reference)</h4>
124
+ <h4 className="text-sm text-neutral-300 font-medium">Golden (Reference)</h4>
125
125
  {renderVersionBadge(status?.goldenMeta, 'bg-blue-500/20 text-blue-400')}
126
126
  </div>
127
127
  <div className="space-y-2 text-sm">
@@ -153,7 +153,7 @@ export function StatusOverview({
153
153
  <div className="bg-neutral-900 rounded-lg p-4 border border-green-500/30">
154
154
  <div className="flex items-center gap-2 mb-3">
155
155
  <div className="w-3 h-3 rounded-full bg-green-400" />
156
- <h4 className="text-neutral-300 font-medium">Live (Working Copy)</h4>
156
+ <h4 className="text-sm text-neutral-300 font-medium">Live (Working Copy)</h4>
157
157
  {renderVersionBadge(status?.liveMeta, 'bg-green-500/20 text-green-400')}
158
158
  <div className="ml-auto relative" ref={resetMenuRef}>
159
159
  <IconButton
@@ -290,7 +290,7 @@ export function StatusOverview({
290
290
  <div className="bg-neutral-900 rounded-lg p-4 border border-neutral-700">
291
291
  <div className="flex items-center gap-2 mb-3">
292
292
  <Archive className="w-4 h-4 text-neutral-500" />
293
- <h4 className="text-neutral-300 font-medium">Local Snapshots</h4>
293
+ <h4 className="text-sm text-neutral-300 font-medium">Local Snapshots</h4>
294
294
  </div>
295
295
  <div className="flex gap-6 text-sm">
296
296
  <div>
@@ -56,7 +56,7 @@ export function VersionManager({ sync, components, componentLabels }: VersionMan
56
56
  <div className="bg-neutral-900 rounded-lg p-4 border border-teal-500/30">
57
57
  <div className="flex items-center gap-3 mb-3">
58
58
  <Tag className="w-5 h-5 text-teal-400" />
59
- <h4 className="text-neutral-300 font-medium">Golden Version</h4>
59
+ <h4 className="text-sm text-neutral-300 font-medium">Golden Version</h4>
60
60
  {status?.goldenMeta && (
61
61
  <span className="px-2 py-0.5 bg-teal-500/20 text-teal-400 text-xs rounded font-mono">
62
62
  {status.goldenMeta.version}
@@ -100,7 +100,7 @@ export function VersionManager({ sync, components, componentLabels }: VersionMan
100
100
  {/* Component Versions */}
101
101
  <div className="bg-neutral-900 rounded-lg border border-neutral-700 overflow-hidden">
102
102
  <div className="px-4 py-3 border-b border-neutral-700">
103
- <h4 className="text-neutral-300 font-medium">Component Versions</h4>
103
+ <h4 className="text-sm text-neutral-300 font-medium">Component Versions</h4>
104
104
  <p className="text-xs text-neutral-600 mt-1">
105
105
  Update individual component versions. Click a component to edit.
106
106
  </p>
@@ -122,7 +122,7 @@ export function VersionManager({ sync, components, componentLabels }: VersionMan
122
122
  <span className="text-xs font-mono text-neutral-500">v{currentVersion}</span>
123
123
  )}
124
124
  {mismatch && (
125
- <span className="text-[10px] text-yellow-400">
125
+ <span className="text-xss text-yellow-400">
126
126
  (live: v{liveVersion})
127
127
  </span>
128
128
  )}
@@ -195,7 +195,7 @@ export function ScreenshotUploader({
195
195
  alt={s.filename}
196
196
  className="w-full h-full object-cover"
197
197
  />
198
- <div className="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex flex-col justify-between p-2">
198
+ <div className="absolute inset-0 bg-[var(--background)]/60 opacity-0 group-hover:opacity-100 transition-opacity flex flex-col justify-between p-2">
199
199
  <button
200
200
  type="button"
201
201
  onClick={(e) => {
@@ -209,7 +209,7 @@ export function ScreenshotUploader({
209
209
  </button>
210
210
  <span className="text-xs text-white truncate">{s.filename}</span>
211
211
  </div>
212
- <div className="absolute bottom-1 right-1 px-1.5 py-0.5 bg-black/70 rounded text-xs text-neutral-400">
212
+ <div className="absolute bottom-1 right-1 px-1.5 py-0.5 bg-[var(--background)]/70 rounded text-xs text-neutral-400">
213
213
  {formatFileSize(s.size)}
214
214
  </div>
215
215
  </div>
@@ -201,7 +201,7 @@ function SnapshotEntryRow({
201
201
  <span className="text-xs flex-1 truncate">
202
202
  {searchQuery ? highlightMatch(displayName, searchQuery) : displayName}
203
203
  </span>
204
- <span className="text-[10px] text-neutral-500 shrink-0" title={formatFullDate(entry.savedAt)}>
204
+ <span className="text-xss text-neutral-500 shrink-0" title={formatFullDate(entry.savedAt)}>
205
205
  {formatRelativeTime(entry.savedAt)}
206
206
  </span>
207
207
  <IconButton
@@ -144,7 +144,7 @@ export function SnippetsEditor({
144
144
  <p className="text-xs text-neutral-500 mb-1">
145
145
  {searchQuery ? 'No matching snippets' : 'No snippets defined'}
146
146
  </p>
147
- <p className="text-[10px] text-neutral-600">
147
+ <p className="text-xss text-neutral-600">
148
148
  {searchQuery ? 'Try a different search term' : 'Click + to add your first snippet'}
149
149
  </p>
150
150
  </div>
@@ -228,11 +228,11 @@ function SnippetListItem({ snippet, selected, onSelect, onDelete }: SnippetListI
228
228
  <p className="text-xs font-mono font-medium text-neutral-300 truncate">
229
229
  {snippet.name}
230
230
  </p>
231
- <p className="text-[10px] text-neutral-500 truncate mt-0.5">
231
+ <p className="text-xss text-neutral-500 truncate mt-0.5">
232
232
  {snippet.description}
233
233
  </p>
234
234
  {snippet.value && (
235
- <p className="text-[10px] text-neutral-600 truncate mt-0.5 font-mono">
235
+ <p className="text-xss text-neutral-600 truncate mt-0.5 font-mono">
236
236
  {snippet.value.slice(0, 80)}{snippet.value.length > 80 ? '...' : ''}
237
237
  </p>
238
238
  )}
@@ -292,7 +292,7 @@ function SnippetForm({
292
292
  error={nameHasError}
293
293
  autoFocus={!isEditing}
294
294
  />
295
- <p className="mt-1 text-[10px] text-neutral-600">
295
+ <p className="mt-1 text-xss text-neutral-600">
296
296
  Use in prompts as <span className="font-mono text-purple-400">{'{{' + (formData.name || 'NAME') + '}}'}</span>
297
297
  </p>
298
298
  </div>
@@ -319,7 +319,7 @@ function SnippetForm({
319
319
  onChange={(val) => setFormField('value', val)}
320
320
  minHeight={160}
321
321
  />
322
- <p className="mt-1 text-[10px] text-neutral-600">
322
+ <p className="mt-1 text-xss text-neutral-600">
323
323
  Can be a single value, multi-line text, or an entire document
324
324
  </p>
325
325
  </div>
@@ -194,7 +194,7 @@ export function ActionDialog({
194
194
 
195
195
  return createPortal(
196
196
  <div className="fixed inset-0 z-50 flex items-center justify-center">
197
- <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onCancel} />
197
+ <div className="absolute inset-0 bg-[var(--dialog-backdrop)] backdrop-blur-sm" onClick={onCancel} />
198
198
  <div
199
199
  className={cn(
200
200
  'relative bg-neutral-950 border border-neutral-700 rounded-xl shadow-2xl w-full max-w-[800px] mx-4 flex flex-col',
@@ -9,11 +9,11 @@
9
9
  * Features:
10
10
  * - Outline variant matching IconButton outline style (border + text, no fill)
11
11
  * - Accepts numbers (auto-caps at 99+) or short strings ("New")
12
- * - 13 color variants
12
+ * - 15 color variants
13
13
  * - 5 size variants (xss, xs, sm, md, lg)
14
14
  */
15
15
 
16
- export type BadgeColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky'
16
+ export type BadgeColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky' | 'pink' | 'teal'
17
17
 
18
18
  export interface BadgeProps {
19
19
  value: number | string
@@ -37,13 +37,15 @@ const colorClasses: Record<BadgeColor, string> = {
37
37
  violet: 'border-violet-500/30 text-violet-400',
38
38
  neutral: 'border-neutral-500/30 text-neutral-400',
39
39
  sky: 'border-sky-500/30 text-sky-400',
40
+ pink: 'border-pink-500/30 text-pink-400',
41
+ teal: 'border-teal-500/30 text-teal-400',
40
42
  }
41
43
 
42
44
  const sizeClasses = {
43
- xss: 'min-w-[14px] h-[14px] px-0.5 text-[9px]',
44
- xs: 'min-w-[16px] h-[16px] px-1 text-[10px]',
45
- sm: 'min-w-[18px] h-[18px] px-1 text-[10px]',
46
- md: 'min-w-[20px] h-[20px] px-1.5 text-[11px]',
45
+ xss: 'min-w-[14px] h-[14px] px-0.5 text-xss',
46
+ xs: 'min-w-[16px] h-[16px] px-1 text-xss',
47
+ sm: 'min-w-[18px] h-[18px] px-1 text-xss',
48
+ md: 'min-w-[20px] h-[20px] px-1.5 text-xss',
47
49
  lg: 'min-w-[22px] h-[22px] px-1.5 text-xs',
48
50
  }
49
51
 
@@ -66,7 +66,7 @@ export interface BreadcrumbProps {
66
66
  }
67
67
 
68
68
  const sizeConfig = {
69
- xss: { text: 'text-[10px]', icon: 'w-2.5 h-2.5', px: 'px-1', py: 'py-0.5', gap: 'gap-0.5', sep: 'w-2 h-2' },
69
+ xss: { text: 'text-xss', icon: 'w-2.5 h-2.5', px: 'px-1', py: 'py-0.5', gap: 'gap-0.5', sep: 'w-2 h-2' },
70
70
  xs: { text: 'text-xs', icon: 'w-3 h-3', px: 'px-1.5', py: 'py-0.5', gap: 'gap-1', sep: 'w-2.5 h-2.5' },
71
71
  sm: { text: 'text-sm', icon: 'w-3.5 h-3.5', px: 'px-2', py: 'py-1', gap: 'gap-1.5', sep: 'w-3 h-3' },
72
72
  md: { text: 'text-base', icon: 'w-4 h-4', px: 'px-2.5', py: 'py-1', gap: 'gap-1.5', sep: 'w-3.5 h-3.5' },
@@ -7,13 +7,13 @@
7
7
  *
8
8
  * Features:
9
9
  * - Outline variant matching IconButton outline style (border + text, no fill)
10
- * - 13 color variants
10
+ * - 15 color variants
11
11
  * - 5 size variants (xss, xs, sm, md, lg)
12
12
  */
13
13
 
14
14
  import { Check } from 'lucide-react'
15
15
 
16
- export type ConfirmBadgeColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky'
16
+ export type ConfirmBadgeColor = 'blue' | 'green' | 'red' | 'orange' | 'cyan' | 'yellow' | 'purple' | 'indigo' | 'emerald' | 'amber' | 'violet' | 'neutral' | 'sky' | 'pink' | 'teal'
17
17
 
18
18
  export interface ConfirmBadgeProps {
19
19
  color?: ConfirmBadgeColor
@@ -36,6 +36,8 @@ const colorClasses: Record<ConfirmBadgeColor, string> = {
36
36
  violet: 'border-violet-500/30 text-violet-400',
37
37
  neutral: 'border-neutral-500/30 text-neutral-400',
38
38
  sky: 'border-sky-500/30 text-sky-400',
39
+ pink: 'border-pink-500/30 text-pink-400',
40
+ teal: 'border-teal-500/30 text-teal-400',
39
41
  }
40
42
 
41
43
  const sizeClasses = {