@nocoo/basalt 2.0.0-rc.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/charts/area.d.ts +8 -4
  2. package/dist/charts/area.js +41 -42
  3. package/dist/charts/area.js.map +1 -1
  4. package/dist/charts/bar.d.ts +7 -4
  5. package/dist/charts/bar.js +34 -27
  6. package/dist/charts/bar.js.map +1 -1
  7. package/dist/charts/bullet.d.ts +6 -4
  8. package/dist/charts/bullet.js +18 -23
  9. package/dist/charts/bullet.js.map +1 -1
  10. package/dist/charts/chart-colors.d.ts +3 -0
  11. package/dist/charts/charts.d.ts +6 -4
  12. package/dist/charts/charts.js +4 -3
  13. package/dist/charts/charts.js.map +1 -1
  14. package/dist/charts/config.d.ts +26 -15
  15. package/dist/charts/config.js +58 -44
  16. package/dist/charts/config.js.map +1 -1
  17. package/dist/charts/custom-chart.d.ts +6 -4
  18. package/dist/charts/custom-chart.js +4 -3
  19. package/dist/charts/custom-chart.js.map +1 -1
  20. package/dist/charts/date-navigation.d.ts +5 -0
  21. package/dist/charts/date-navigation.js.map +1 -1
  22. package/dist/charts/donut.d.ts +6 -4
  23. package/dist/charts/donut.js +38 -28
  24. package/dist/charts/donut.js.map +1 -1
  25. package/dist/charts/frame.d.ts +7 -3
  26. package/dist/charts/frame.js +30 -7
  27. package/dist/charts/frame.js.map +1 -1
  28. package/dist/charts/funnel.d.ts +6 -4
  29. package/dist/charts/funnel.js +16 -17
  30. package/dist/charts/funnel.js.map +1 -1
  31. package/dist/charts/gauge.d.ts +6 -3
  32. package/dist/charts/gauge.js +18 -17
  33. package/dist/charts/gauge.js.map +1 -1
  34. package/dist/charts/grouped-bar.d.ts +8 -4
  35. package/dist/charts/grouped-bar.js +36 -29
  36. package/dist/charts/grouped-bar.js.map +1 -1
  37. package/dist/charts/heatmap-calendar.d.ts +11 -5
  38. package/dist/charts/heatmap-calendar.js +25 -20
  39. package/dist/charts/heatmap-calendar.js.map +1 -1
  40. package/dist/charts/item-list.d.ts +9 -7
  41. package/dist/charts/item-list.js +1 -5
  42. package/dist/charts/item-list.js.map +1 -1
  43. package/dist/charts/legend.d.ts +7 -0
  44. package/dist/charts/legend.js +56 -0
  45. package/dist/charts/legend.js.map +1 -0
  46. package/dist/charts/line.d.ts +7 -4
  47. package/dist/charts/line.js +33 -41
  48. package/dist/charts/line.js.map +1 -1
  49. package/dist/charts/palette.d.ts +3 -2
  50. package/dist/charts/palette.js.map +1 -1
  51. package/dist/charts/radar.d.ts +6 -4
  52. package/dist/charts/radar.js +18 -18
  53. package/dist/charts/radar.js.map +1 -1
  54. package/dist/charts/sample.d.ts +8 -42
  55. package/dist/charts/sample.js.map +1 -1
  56. package/dist/charts/sankey.d.ts +5 -4
  57. package/dist/charts/sankey.js +15 -16
  58. package/dist/charts/sankey.js.map +1 -1
  59. package/dist/charts/series.d.ts +48 -0
  60. package/dist/charts/series.js +19 -0
  61. package/dist/charts/series.js.map +1 -0
  62. package/dist/charts/slot-bar.d.ts +12 -5
  63. package/dist/charts/slot-bar.js +27 -22
  64. package/dist/charts/slot-bar.js.map +1 -1
  65. package/dist/charts/sparkline.d.ts +6 -4
  66. package/dist/charts/sparkline.js +12 -11
  67. package/dist/charts/sparkline.js.map +1 -1
  68. package/dist/charts/stacked-bar.d.ts +8 -4
  69. package/dist/charts/stacked-bar.js +40 -37
  70. package/dist/charts/stacked-bar.js.map +1 -1
  71. package/dist/charts/stat-card.d.ts +7 -5
  72. package/dist/charts/stat-card.js +1 -1
  73. package/dist/charts/stat-card.js.map +1 -1
  74. package/dist/charts/timeline.d.ts +15 -8
  75. package/dist/charts/timeline.js +9 -14
  76. package/dist/charts/timeline.js.map +1 -1
  77. package/dist/charts/timeseries.d.ts +6 -4
  78. package/dist/charts/timeseries.js +4 -3
  79. package/dist/charts/timeseries.js.map +1 -1
  80. package/dist/charts/tooltip.d.ts +16 -0
  81. package/dist/charts/tooltip.js +105 -0
  82. package/dist/charts/tooltip.js.map +1 -0
  83. package/dist/components/confirm-dialog.d.ts +5 -1
  84. package/dist/components/confirm-dialog.js +52 -25
  85. package/dist/components/confirm-dialog.js.map +1 -1
  86. package/dist/components/delete-resource.d.ts +5 -0
  87. package/dist/components/delete-resource.js +38 -0
  88. package/dist/components/delete-resource.js.map +1 -0
  89. package/dist/components/loading-screen.js +9 -5
  90. package/dist/components/loading-screen.js.map +1 -1
  91. package/dist/components/resource-list.d.ts +10 -0
  92. package/dist/components/resource-list.js +30 -0
  93. package/dist/components/resource-list.js.map +1 -0
  94. package/dist/providers/accent.d.ts +22 -0
  95. package/dist/providers/accent.js +110 -0
  96. package/dist/providers/accent.js.map +1 -0
  97. package/dist/styles/standalone.css +5 -19
  98. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"timeline.js","names":[],"sources":["../../src/charts/timeline.tsx"],"sourcesContent":["import { cn } from \"../utils/cn\";\n\nexport type TimelineEvent = {\n\tid: string;\n\ttime: string;\n\ttitle: string;\n\tsubtitle?: string;\n\tcolor?: string;\n};\n\nconst hours = Array.from({ length: 24 }, (_, index) => index);\n\nfunction getHour(time: string) {\n\treturn Number.parseInt(time.split(\":\")[0] ?? \"0\", 10);\n}\n\nexport function Timeline({\n\titems = [\n\t\t{ title: \"Created\", at: \"Mon\" },\n\t\t{ title: \"Shipped\", at: \"Tue\" },\n\t],\n\tevents,\n\tariaLabel = \"Timeline\",\n\tclassName,\n}: {\n\titems?: { id?: string; title: string; at?: string }[];\n\tevents?: TimelineEvent[];\n\tariaLabel?: string;\n\tclassName?: string;\n}) {\n\tif (events) {\n\t\treturn <HourTimeline events={events} ariaLabel={ariaLabel} className={className} />;\n\t}\n\treturn (\n\t\t<ol className={cn(\"space-y-2 text-sm\", className)} aria-label={ariaLabel}>\n\t\t\t{items.map((item, index) => (\n\t\t\t\t<li key={item.id ?? `${item.at ?? \"\"}-${item.title}-${index}`} className=\"flex gap-2\">\n\t\t\t\t\t<span className=\"text-basalt-muted-foreground\">{item.at}</span>\n\t\t\t\t\t<span>{item.title}</span>\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</ol>\n\t);\n}\n\nfunction HourTimeline({\n\tevents,\n\tariaLabel,\n\tclassName,\n}: {\n\tevents: TimelineEvent[];\n\tariaLabel: string;\n\tclassName?: string;\n}) {\n\tconst eventsByHour = new Map<number, TimelineEvent[]>();\n\tfor (const event of events) {\n\t\tconst hour = getHour(event.time);\n\t\tconst existing = eventsByHour.get(hour) ?? [];\n\t\teventsByHour.set(hour, [...existing, event]);\n\t}\n\treturn (\n\t\t<ol className={cn(\"flex flex-col pl-14\", className)} aria-label={ariaLabel}>\n\t\t\t{hours.map((hour) => {\n\t\t\t\tconst hourEvents = eventsByHour.get(hour) ?? [];\n\t\t\t\tconst hasEvents = hourEvents.length > 0;\n\t\t\t\treturn (\n\t\t\t\t\t<li\n\t\t\t\t\t\tkey={hour}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"relative flex items-start border-l-2 py-2 pl-4\",\n\t\t\t\t\t\t\thasEvents ? \"border-basalt-primary\" : \"border-basalt-border\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"absolute left-0 w-12 -translate-x-full pr-2 text-right text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t{hour.toString().padStart(2, \"0\")}:00\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"absolute -left-[5px] top-2 h-2 w-2 rounded-full\",\n\t\t\t\t\t\t\t\thasEvents ? \"bg-basalt-primary\" : \"bg-basalt-border\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<div className=\"flex min-h-[24px] w-full flex-col gap-1\">\n\t\t\t\t\t\t\t{hourEvents.map((event) => (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={event.id}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\"flex items-center gap-2 rounded-md px-2 py-1 text-xs\",\n\t\t\t\t\t\t\t\t\t\tevent.color\n\t\t\t\t\t\t\t\t\t\t\t? `${event.color} text-white`\n\t\t\t\t\t\t\t\t\t\t\t: \"bg-basalt-muted text-basalt-foreground\",\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">{event.time}</span>\n\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{event.title}</span>\n\t\t\t\t\t\t\t\t\t{event.subtitle ? (\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\"truncate\",\n\t\t\t\t\t\t\t\t\t\t\t\tevent.color ? \"text-white/80\" : \"text-basalt-muted-foreground\",\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{event.subtitle}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t);\n\t\t\t})}\n\t\t</ol>\n\t);\n}\n"],"mappings":";;;;AAUA,IAAM,IAAQ,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAU,CAAK;AAE5D,SAAS,EAAQ,GAAc;CAC9B,OAAO,OAAO,SAAS,EAAK,MAAM,GAAG,CAAC,CAAC,MAAM,KAAK,EAAE;AACrD;AAEA,SAAgB,EAAS,EACxB,WAAQ,CACP;CAAE,OAAO;CAAW,IAAI;AAAM,GAC9B;CAAE,OAAO;CAAW,IAAI;AAAM,CAC/B,GACA,WACA,eAAY,YACZ,gBAME;CAIF,OAHI,IACI,kBAAC,GAAD;EAAsB;EAAmB;EAAsB;CAAY,CAAA,IAGlF,kBAAC,MAAD;EAAI,WAAW,EAAG,qBAAqB,CAAS;EAAG,cAAY;EAC7D,UAAA,EAAM,KAAK,GAAM,MACjB,kBAAC,MAAD;GAA+D,WAAU;GAAzE,UAAA,CACC,kBAAC,QAAD;IAAM,WAAU;IAAgC,UAAA,EAAK;GAAS,CAAA,GAC9D,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA,CACrB;EAHK,GAAA,EAAK,MAAM,GAAG,EAAK,MAAM,GAAG,GAAG,EAAK,MAAM,GAAG,GAGlD,CACJ;CACE,CAAA;AAEN;AAEA,SAAS,EAAa,EACrB,WACA,cACA,gBAKE;CACF,IAAM,oBAAe,IAAI,IAA6B;CACtD,KAAK,IAAM,KAAS,GAAQ;EAC3B,IAAM,IAAO,EAAQ,EAAM,IAAI,GACzB,IAAW,EAAa,IAAI,CAAI,KAAK,CAAC;EAC5C,EAAa,IAAI,GAAM,CAAC,GAAG,GAAU,CAAK,CAAC;CAC5C;CACA,OACC,kBAAC,MAAD;EAAI,WAAW,EAAG,uBAAuB,CAAS;EAAG,cAAY;EAC/D,UAAA,EAAM,KAAK,MAAS;GACpB,IAAM,IAAa,EAAa,IAAI,CAAI,KAAK,CAAC,GACxC,IAAY,EAAW,SAAS;GACtC,OACC,kBAAC,MAAD;IAEC,WAAW,EACV,kDACA,IAAY,0BAA0B,sBACvC;IALD,UAAA;KAOC,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,EAAK,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG,GAAE,KAC9B;;KACL,kBAAC,OAAD,EACC,WAAW,EACV,mDACA,IAAY,sBAAsB,kBACnC,EACA,CAAA;KACD,kBAAC,OAAD;MAAK,WAAU;MACb,UAAA,EAAW,KAAK,MAChB,kBAAC,OAAD;OAEC,WAAW,EACV,wDACA,EAAM,QACH,GAAG,EAAM,MAAM,eACf,wCACJ;OAPD,UAAA;QASC,kBAAC,QAAD;SAAM,WAAU;SAAe,UAAA,EAAM;QAAW,CAAA;QAChD,kBAAC,QAAD;SAAM,WAAU;SAAY,UAAA,EAAM;QAAY,CAAA;QAC7C,EAAM,WACN,kBAAC,QAAD;SACC,WAAW,EACV,YACA,EAAM,QAAQ,kBAAkB,8BACjC;SAEC,UAAA,EAAM;QACF,CAAA,IACH;OACA;MApBC,GAAA,EAAM,EAoBP,CACL;KACG,CAAA;IACF;GAzCE,GAAA,CAyCF;EAEN,CAAC;CACE,CAAA;AAEN"}
1
+ {"version":3,"file":"timeline.js","names":[],"sources":["../../src/charts/timeline.tsx"],"sourcesContent":["import { cn } from \"../utils/cn\";\n\nexport type TimelineEvent = {\n\tid: string;\n\ttime: string;\n\ttitle: string;\n\tsubtitle?: string;\n\tcolor?: string;\n};\n\nconst hours = Array.from({ length: 24 }, (_, index) => index);\n\nfunction getHour(time: string) {\n\treturn Number.parseInt(time.split(\":\")[0] ?? \"0\", 10);\n}\n\nexport type TimelineItem = { id?: string; title: string; at?: string };\n\nexport type TimelineItemsProps = {\n\titems: TimelineItem[];\n\tariaLabel?: string;\n\tclassName?: string;\n};\nexport type TimelineEventsProps = {\n\tevents: TimelineEvent[];\n\tariaLabel?: string;\n\tclassName?: string;\n};\nexport type TimelineProps = TimelineItemsProps | TimelineEventsProps;\n\nexport function Timeline(props: TimelineProps) {\n\tconst { ariaLabel = \"Timeline\", className } = props;\n\tif (\"events\" in props) {\n\t\treturn <HourTimeline events={props.events} ariaLabel={ariaLabel} className={className} />;\n\t}\n\treturn (\n\t\t<ol className={cn(\"space-y-2 text-sm\", className)} aria-label={ariaLabel}>\n\t\t\t{props.items.map((item, index) => (\n\t\t\t\t<li key={item.id ?? `${item.at ?? \"\"}-${item.title}-${index}`} className=\"flex gap-2\">\n\t\t\t\t\t<span className=\"text-basalt-muted-foreground\">{item.at}</span>\n\t\t\t\t\t<span>{item.title}</span>\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</ol>\n\t);\n}\n\nfunction HourTimeline({\n\tevents,\n\tariaLabel,\n\tclassName,\n}: {\n\tevents: TimelineEvent[];\n\tariaLabel: string;\n\tclassName?: string;\n}) {\n\tconst eventsByHour = new Map<number, TimelineEvent[]>();\n\tfor (const event of events) {\n\t\tconst hour = getHour(event.time);\n\t\tconst existing = eventsByHour.get(hour) ?? [];\n\t\teventsByHour.set(hour, [...existing, event]);\n\t}\n\treturn (\n\t\t<ol className={cn(\"flex flex-col pl-14\", className)} aria-label={ariaLabel}>\n\t\t\t{hours.map((hour) => {\n\t\t\t\tconst hourEvents = eventsByHour.get(hour) ?? [];\n\t\t\t\tconst hasEvents = hourEvents.length > 0;\n\t\t\t\treturn (\n\t\t\t\t\t<li\n\t\t\t\t\t\tkey={hour}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"relative flex items-start border-l-2 py-2 pl-4\",\n\t\t\t\t\t\t\thasEvents ? \"border-basalt-primary\" : \"border-basalt-border\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"absolute left-0 w-12 -translate-x-full pr-2 text-right text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t{hour.toString().padStart(2, \"0\")}:00\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"absolute -left-[5px] top-2 h-2 w-2 rounded-full\",\n\t\t\t\t\t\t\t\thasEvents ? \"bg-basalt-primary\" : \"bg-basalt-border\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<div className=\"flex min-h-[24px] w-full flex-col gap-1\">\n\t\t\t\t\t\t\t{hourEvents.map((event) => (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tkey={event.id}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\"flex items-center gap-2 rounded-md px-2 py-1 text-xs\",\n\t\t\t\t\t\t\t\t\t\tevent.color\n\t\t\t\t\t\t\t\t\t\t\t? `${event.color} text-white`\n\t\t\t\t\t\t\t\t\t\t\t: \"bg-basalt-muted text-basalt-foreground\",\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"font-medium\">{event.time}</span>\n\t\t\t\t\t\t\t\t\t<span className=\"truncate\">{event.title}</span>\n\t\t\t\t\t\t\t\t\t{event.subtitle ? (\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\"truncate\",\n\t\t\t\t\t\t\t\t\t\t\t\tevent.color ? \"text-white/80\" : \"text-basalt-muted-foreground\",\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{event.subtitle}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t);\n\t\t\t})}\n\t\t</ol>\n\t);\n}\n"],"mappings":";;;;AAUA,IAAM,IAAQ,MAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAU,CAAK;AAE5D,SAAS,EAAQ,GAAc;CAC9B,OAAO,OAAO,SAAS,EAAK,MAAM,GAAG,CAAC,CAAC,MAAM,KAAK,EAAE;AACrD;AAgBA,SAAgB,EAAS,GAAsB;CAC9C,IAAM,EAAE,eAAY,YAAY,iBAAc;CAI9C,OAHI,YAAY,IACR,kBAAC,GAAD;EAAc,QAAQ,EAAM;EAAmB;EAAsB;CAAY,CAAA,IAGxF,kBAAC,MAAD;EAAI,WAAW,EAAG,qBAAqB,CAAS;EAAG,cAAY;EAC7D,UAAA,EAAM,MAAM,KAAK,GAAM,MACvB,kBAAC,MAAD;GAA+D,WAAU;GAAzE,UAAA,CACC,kBAAC,QAAD;IAAM,WAAU;IAAgC,UAAA,EAAK;GAAS,CAAA,GAC9D,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA,CACrB;EAHK,GAAA,EAAK,MAAM,GAAG,EAAK,MAAM,GAAG,GAAG,EAAK,MAAM,GAAG,GAGlD,CACJ;CACE,CAAA;AAEN;AAEA,SAAS,EAAa,EACrB,WACA,cACA,gBAKE;CACF,IAAM,oBAAe,IAAI,IAA6B;CACtD,KAAK,IAAM,KAAS,GAAQ;EAC3B,IAAM,IAAO,EAAQ,EAAM,IAAI,GACzB,IAAW,EAAa,IAAI,CAAI,KAAK,CAAC;EAC5C,EAAa,IAAI,GAAM,CAAC,GAAG,GAAU,CAAK,CAAC;CAC5C;CACA,OACC,kBAAC,MAAD;EAAI,WAAW,EAAG,uBAAuB,CAAS;EAAG,cAAY;EAC/D,UAAA,EAAM,KAAK,MAAS;GACpB,IAAM,IAAa,EAAa,IAAI,CAAI,KAAK,CAAC,GACxC,IAAY,EAAW,SAAS;GACtC,OACC,kBAAC,MAAD;IAEC,WAAW,EACV,kDACA,IAAY,0BAA0B,sBACvC;IALD,UAAA;KAOC,kBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,EAAK,SAAS,CAAC,CAAC,SAAS,GAAG,GAAG,GAAE,KAC9B;;KACL,kBAAC,OAAD,EACC,WAAW,EACV,mDACA,IAAY,sBAAsB,kBACnC,EACA,CAAA;KACD,kBAAC,OAAD;MAAK,WAAU;MACb,UAAA,EAAW,KAAK,MAChB,kBAAC,OAAD;OAEC,WAAW,EACV,wDACA,EAAM,QACH,GAAG,EAAM,MAAM,eACf,wCACJ;OAPD,UAAA;QASC,kBAAC,QAAD;SAAM,WAAU;SAAe,UAAA,EAAM;QAAW,CAAA;QAChD,kBAAC,QAAD;SAAM,WAAU;SAAY,UAAA,EAAM;QAAY,CAAA;QAC7C,EAAM,WACN,kBAAC,QAAD;SACC,WAAW,EACV,YACA,EAAM,QAAQ,kBAAkB,8BACjC;SAEC,UAAA,EAAM;QACF,CAAA,IACH;OACA;MApBC,GAAA,EAAM,EAoBP,CACL;KACG,CAAA;IACF;GAzCE,GAAA,CAyCF;EAEN,CAAC;CACE,CAAA;AAEN"}
@@ -1,6 +1,8 @@
1
- import type { XYPoint } from "./sample.js";
2
- export declare function Timeseries({ data, ariaLabel, className, }: {
3
- data?: XYPoint[];
1
+ import type { XYPoint, XYSeriesDescriptor } from "./series.js";
2
+ export type TimeseriesProps = {
3
+ data: XYPoint[];
4
+ series?: XYSeriesDescriptor[];
4
5
  ariaLabel?: string;
5
6
  className?: string;
6
- }): import("react").JSX.Element;
7
+ };
8
+ export declare function Timeseries({ data, series, ariaLabel, className }: TimeseriesProps): import("react").JSX.Element;
@@ -2,11 +2,12 @@
2
2
  import { LineChart as e } from "./line.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  //#region src/charts/timeseries.tsx
5
- function n({ data: n, ariaLabel: r = "Timeseries", className: i }) {
5
+ function n({ data: n, series: r, ariaLabel: i = "Timeseries", className: a }) {
6
6
  return /* @__PURE__ */ t(e, {
7
7
  data: n,
8
- ariaLabel: r,
9
- className: i
8
+ series: r,
9
+ ariaLabel: i,
10
+ className: a
10
11
  });
11
12
  }
12
13
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"timeseries.js","names":[],"sources":["../../src/charts/timeseries.tsx"],"sourcesContent":["import { LineChart } from \"./line\";\nimport type { XYPoint } from \"./sample\";\n\nexport function Timeseries({\n\tdata,\n\tariaLabel = \"Timeseries\",\n\tclassName,\n}: {\n\tdata?: XYPoint[];\n\tariaLabel?: string;\n\tclassName?: string;\n}) {\n\treturn <LineChart data={data} ariaLabel={ariaLabel} className={className} />;\n}\n"],"mappings":";;;;AAGA,SAAgB,EAAW,EAC1B,SACA,eAAY,cACZ,gBAKE;CACF,OAAO,kBAAC,GAAD;EAAiB;EAAiB;EAAsB;CAAY,CAAA;AAC5E"}
1
+ {"version":3,"file":"timeseries.js","names":[],"sources":["../../src/charts/timeseries.tsx"],"sourcesContent":["import { LineChart } from \"./line\";\nimport type { XYPoint, XYSeriesDescriptor } from \"./series\";\n\nexport type TimeseriesProps = {\n\tdata: XYPoint[];\n\tseries?: XYSeriesDescriptor[];\n\tariaLabel?: string;\n\tclassName?: string;\n};\n\nexport function Timeseries({ data, series, ariaLabel = \"Timeseries\", className }: TimeseriesProps) {\n\treturn <LineChart data={data} series={series} ariaLabel={ariaLabel} className={className} />;\n}\n"],"mappings":";;;;AAUA,SAAgB,EAAW,EAAE,SAAM,WAAQ,eAAY,cAAc,gBAA8B;CAClG,OAAO,kBAAC,GAAD;EAAiB;EAAc;EAAmB;EAAsB;CAAY,CAAA;AAC5F"}
@@ -0,0 +1,16 @@
1
+ export type ChartTooltipItem = {
2
+ name?: string;
3
+ value?: number | string;
4
+ color?: string;
5
+ fill?: string;
6
+ stroke?: string;
7
+ dataKey?: string | number;
8
+ };
9
+ export type ChartTooltipContentProps = {
10
+ active?: boolean;
11
+ payload?: readonly ChartTooltipItem[];
12
+ label?: string | number;
13
+ formatter?: (value: number) => string;
14
+ };
15
+ export declare function formatChartNumber(value: number): string;
16
+ export declare function ChartTooltipContent({ active, payload, label, formatter, }: ChartTooltipContentProps): import("react").JSX.Element | null;
@@ -0,0 +1,105 @@
1
+ "use client";
2
+ import { jsx as e, jsxs as t } from "react/jsx-runtime";
3
+ //#region src/charts/tooltip.tsx
4
+ var n = /* @__PURE__ */ new Set([
5
+ "y",
6
+ "y2",
7
+ "y3",
8
+ "value",
9
+ "target"
10
+ ]), r = 12, i = 12, a = 8;
11
+ function o(e) {
12
+ return Number.isFinite(e) ? new Intl.NumberFormat(void 0, { maximumFractionDigits: +!Number.isInteger(e) }).format(e) : "—";
13
+ }
14
+ function s(e) {
15
+ let t = e.name == null ? "" : String(e.name), r = e.dataKey == null ? "" : String(e.dataKey);
16
+ if (!(n.has(t) || n.has(r))) return t || void 0;
17
+ }
18
+ function c(e) {
19
+ return e.color ?? e.fill ?? e.stroke ?? "hsl(var(--basalt-chart-1))";
20
+ }
21
+ function l({ active: n, payload: l, label: u, formatter: d }) {
22
+ if (!n || !l?.length) return null;
23
+ let f = d ?? o, p = u == null || u === "" ? void 0 : String(u);
24
+ return /* @__PURE__ */ t("div", {
25
+ "data-testid": "chart-tooltip",
26
+ style: {
27
+ background: "hsl(var(--basalt-popover))",
28
+ border: "1px solid hsl(var(--basalt-border) / 0.55)",
29
+ borderRadius: 10,
30
+ boxShadow: "0 12px 28px -8px rgb(0 0 0 / 0.28), 0 4px 10px -4px rgb(0 0 0 / 0.16)",
31
+ color: "hsl(var(--basalt-popover-foreground))",
32
+ maxWidth: 220,
33
+ minWidth: 128,
34
+ padding: "8px 12px"
35
+ },
36
+ children: [p ? /* @__PURE__ */ e("p", {
37
+ style: {
38
+ color: "hsl(var(--basalt-popover-foreground))",
39
+ fontSize: r,
40
+ fontWeight: 600,
41
+ letterSpacing: "-0.01em",
42
+ lineHeight: 1.2,
43
+ margin: "0 0 8px"
44
+ },
45
+ children: p
46
+ }) : null, /* @__PURE__ */ e("div", {
47
+ style: {
48
+ display: "flex",
49
+ flexDirection: "column",
50
+ gap: 4
51
+ },
52
+ children: l.map((n, r) => {
53
+ let o = n.value, l = typeof o == "number" ? o : typeof o == "string" ? Number(o) : NaN, u = s(n), d = `${String(n.dataKey ?? n.name ?? r)}-${String(r)}`;
54
+ return /* @__PURE__ */ t("div", {
55
+ style: {
56
+ alignItems: "center",
57
+ display: "flex",
58
+ fontSize: i,
59
+ gap: 8,
60
+ lineHeight: "20px",
61
+ minWidth: 0
62
+ },
63
+ children: [
64
+ /* @__PURE__ */ e("span", {
65
+ "aria-hidden": "true",
66
+ style: {
67
+ background: c(n),
68
+ borderRadius: 999,
69
+ boxShadow: "0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)",
70
+ flexShrink: 0,
71
+ height: a,
72
+ width: a
73
+ }
74
+ }),
75
+ u ? /* @__PURE__ */ e("span", {
76
+ style: {
77
+ color: "hsl(var(--basalt-muted-foreground))",
78
+ flex: 1,
79
+ minWidth: 0,
80
+ overflow: "hidden",
81
+ textOverflow: "ellipsis",
82
+ whiteSpace: "nowrap"
83
+ },
84
+ children: u
85
+ }) : null,
86
+ /* @__PURE__ */ e("span", {
87
+ style: {
88
+ color: "hsl(var(--basalt-popover-foreground))",
89
+ flexShrink: 0,
90
+ fontVariantNumeric: "tabular-nums",
91
+ fontWeight: 600,
92
+ marginLeft: u ? 0 : "auto"
93
+ },
94
+ children: Number.isFinite(l) ? f(l) : String(o ?? "—")
95
+ })
96
+ ]
97
+ }, d);
98
+ })
99
+ })]
100
+ });
101
+ }
102
+ //#endregion
103
+ export { l as ChartTooltipContent, o as formatChartNumber };
104
+
105
+ //# sourceMappingURL=tooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltip.js","names":[],"sources":["../../src/charts/tooltip.tsx"],"sourcesContent":["const HIDDEN_SERIES_KEYS = new Set([\"y\", \"y2\", \"y3\", \"value\", \"target\"]);\nconst TITLE_SIZE = 12;\nconst BODY_SIZE = 12;\nconst DOT_SIZE = 8;\n\nexport type ChartTooltipItem = {\n\tname?: string;\n\tvalue?: number | string;\n\tcolor?: string;\n\tfill?: string;\n\tstroke?: string;\n\tdataKey?: string | number;\n};\n\nexport type ChartTooltipContentProps = {\n\tactive?: boolean;\n\tpayload?: readonly ChartTooltipItem[];\n\tlabel?: string | number;\n\tformatter?: (value: number) => string;\n};\n\nexport function formatChartNumber(value: number): string {\n\tif (!Number.isFinite(value)) {\n\t\treturn \"—\";\n\t}\n\treturn new Intl.NumberFormat(undefined, {\n\t\tmaximumFractionDigits: Number.isInteger(value) ? 0 : 1,\n\t}).format(value);\n}\n\nfunction seriesLabel(item: ChartTooltipItem): string | undefined {\n\tconst name = item.name == null ? \"\" : String(item.name);\n\tconst key = item.dataKey == null ? \"\" : String(item.dataKey);\n\tif (HIDDEN_SERIES_KEYS.has(name) || HIDDEN_SERIES_KEYS.has(key)) {\n\t\treturn undefined;\n\t}\n\treturn name || undefined;\n}\n\nfunction seriesSwatch(item: ChartTooltipItem): string {\n\treturn item.color ?? item.fill ?? item.stroke ?? \"hsl(var(--basalt-chart-1))\";\n}\n\nexport function ChartTooltipContent({\n\tactive,\n\tpayload,\n\tlabel,\n\tformatter,\n}: ChartTooltipContentProps) {\n\tif (!active || !payload?.length) {\n\t\treturn null;\n\t}\n\tconst format = formatter ?? formatChartNumber;\n\tconst title = label == null || label === \"\" ? undefined : String(label);\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip\"\n\t\t\tstyle={{\n\t\t\t\tbackground: \"hsl(var(--basalt-popover))\",\n\t\t\t\tborder: \"1px solid hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborderRadius: 10,\n\t\t\t\tboxShadow: \"0 12px 28px -8px rgb(0 0 0 / 0.28), 0 4px 10px -4px rgb(0 0 0 / 0.16)\",\n\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\tmaxWidth: 220,\n\t\t\t\tminWidth: 128,\n\t\t\t\tpadding: \"8px 12px\",\n\t\t\t}}\n\t\t>\n\t\t\t{title ? (\n\t\t\t\t<p\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\t\tfontSize: TITLE_SIZE,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tletterSpacing: \"-0.01em\",\n\t\t\t\t\t\tlineHeight: 1.2,\n\t\t\t\t\t\tmargin: \"0 0 8px\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{title}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<div style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n\t\t\t\t{payload.map((item, index) => {\n\t\t\t\t\tconst raw = item.value;\n\t\t\t\t\tconst numeric =\n\t\t\t\t\t\ttypeof raw === \"number\" ? raw : typeof raw === \"string\" ? Number(raw) : Number.NaN;\n\t\t\t\t\tconst labelText = seriesLabel(item);\n\t\t\t\t\tconst key = `${String(item.dataKey ?? item.name ?? index)}-${String(index)}`;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t\t\t\tlineHeight: \"20px\",\n\t\t\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackground: seriesSwatch(item),\n\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\tboxShadow: \"0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)\",\n\t\t\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t\t\t\theight: DOT_SIZE,\n\t\t\t\t\t\t\t\t\twidth: DOT_SIZE,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{labelText ? (\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{labelText}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\t\t\tmarginLeft: labelText ? 0 : \"auto\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{Number.isFinite(numeric) ? format(numeric) : String(raw ?? \"—\")}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;AAAA,IAAM,oBAAqB,IAAI,IAAI;CAAC;CAAK;CAAM;CAAM;CAAS;AAAQ,CAAC,GACjE,IAAa,IACb,IAAY,IACZ,IAAW;AAkBjB,SAAgB,EAAkB,GAAuB;CAIxD,OAHK,OAAO,SAAS,CAAK,IAGnB,IAAI,KAAK,aAAa,KAAA,GAAW,EACvC,uBAAuB,SAAO,UAAU,CAAK,EAC9C,CAAC,CAAC,CAAC,OAAO,CAAK,IAJP;AAKT;AAEA,SAAS,EAAY,GAA4C;CAChE,IAAM,IAAO,EAAK,QAAQ,OAAO,KAAK,OAAO,EAAK,IAAI,GAChD,IAAM,EAAK,WAAW,OAAO,KAAK,OAAO,EAAK,OAAO;CACvD,QAAmB,IAAI,CAAI,KAAK,EAAmB,IAAI,CAAG,IAG9D,OAAO,KAAQ,KAAA;AAChB;AAEA,SAAS,EAAa,GAAgC;CACrD,OAAO,EAAK,SAAS,EAAK,QAAQ,EAAK,UAAU;AAClD;AAEA,SAAgB,EAAoB,EACnC,WACA,YACA,UACA,gBAC4B;CAC5B,IAAI,CAAC,KAAU,CAAC,GAAS,QACxB,OAAO;CAER,IAAM,IAAS,KAAa,GACtB,IAAQ,KAAS,QAAQ,MAAU,KAAK,KAAA,IAAY,OAAO,CAAK;CACtE,OACC,kBAAC,OAAD;EACC,eAAY;EACZ,OAAO;GACN,YAAY;GACZ,QAAQ;GACR,cAAc;GACd,WAAW;GACX,OAAO;GACP,UAAU;GACV,UAAU;GACV,SAAS;EACV;EAXD,UAAA,CAaE,IACA,kBAAC,KAAD;GACC,OAAO;IACN,OAAO;IACP,UAAU;IACV,YAAY;IACZ,eAAe;IACf,YAAY;IACZ,QAAQ;GACT;GAEC,UAAA;EACC,CAAA,IACA,MACJ,kBAAC,OAAD;GAAK,OAAO;IAAE,SAAS;IAAQ,eAAe;IAAU,KAAK;GAAE;GAC7D,UAAA,EAAQ,KAAK,GAAM,MAAU;IAC7B,IAAM,IAAM,EAAK,OACX,IACL,OAAO,KAAQ,WAAW,IAAM,OAAO,KAAQ,WAAW,OAAO,CAAG,IAAI,KACnE,IAAY,EAAY,CAAI,GAC5B,IAAM,GAAG,OAAO,EAAK,WAAW,EAAK,QAAQ,CAAK,EAAE,GAAG,OAAO,CAAK;IACzE,OACC,kBAAC,OAAD;KAEC,OAAO;MACN,YAAY;MACZ,SAAS;MACT,UAAU;MACV,KAAK;MACL,YAAY;MACZ,UAAU;KACX;KATD,UAAA;MAWC,kBAAC,QAAD;OACC,eAAY;OACZ,OAAO;QACN,YAAY,EAAa,CAAI;QAC7B,cAAc;QACd,WAAW;QACX,YAAY;QACZ,QAAQ;QACR,OAAO;OACR;MACA,CAAA;MACA,IACA,kBAAC,QAAD;OACC,OAAO;QACN,OAAO;QACP,MAAM;QACN,UAAU;QACV,UAAU;QACV,cAAc;QACd,YAAY;OACb;OAEC,UAAA;MACI,CAAA,IACH;MACJ,kBAAC,QAAD;OACC,OAAO;QACN,OAAO;QACP,YAAY;QACZ,oBAAoB;QACpB,YAAY;QACZ,YAAY,IAAY,IAAI;OAC7B;OAEC,UAAA,OAAO,SAAS,CAAO,IAAI,EAAO,CAAO,IAAI,OAAO,KAAO,GAAG;MAC1D,CAAA;KACF;IA9CC,GAAA,CA8CD;GAEP,CAAC;EACG,CAAA,CACD;;AAEP"}
@@ -31,6 +31,10 @@ export interface ConfirmDialogProps {
31
31
  * @default false
32
32
  */
33
33
  loading?: boolean;
34
+ /**
35
+ * Control that opens the dialog. When set, closing restores focus to it.
36
+ */
37
+ trigger?: React.ReactElement;
34
38
  }
35
39
  export interface UseConfirmOptions {
36
40
  /** The dialog title. */
@@ -48,5 +52,5 @@ export interface UseConfirmResult {
48
52
  confirm: (options: UseConfirmOptions) => Promise<boolean>;
49
53
  dialogProps: ConfirmDialogProps;
50
54
  }
51
- export declare function ConfirmDialog({ cancelLabel, confirmLabel, description, loading, onConfirm, onOpenChange, open, title, variant, }: ConfirmDialogProps): React.JSX.Element;
55
+ export declare function ConfirmDialog({ cancelLabel, confirmLabel, description, loading, onConfirm, onOpenChange, open, title, trigger, variant, }: ConfirmDialogProps): React.JSX.Element;
52
56
  export declare function useConfirm(): UseConfirmResult;
@@ -1,42 +1,69 @@
1
1
  "use client";
2
2
  import { Button as e } from "./button.js";
3
- import { AlertDialog as t, AlertDialogContent as n, AlertDialogDescription as r, AlertDialogFooter as i, AlertDialogHeader as a, AlertDialogTitle as o } from "./alert-dialog.js";
4
- import * as s from "react";
5
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
3
+ import { AlertDialog as t, AlertDialogContent as n, AlertDialogDescription as r, AlertDialogFooter as i, AlertDialogHeader as a, AlertDialogTitle as o, AlertDialogTrigger as s } from "./alert-dialog.js";
4
+ import * as c from "@radix-ui/react-alert-dialog";
5
+ import * as l from "react";
6
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
6
7
  //#region src/components/confirm-dialog.tsx
7
- function u({ cancelLabel: s = "Cancel", confirmLabel: u = "Confirm", description: d, loading: f = !1, onConfirm: p, onOpenChange: m, open: h, title: g, variant: _ = "default" }) {
8
- return /* @__PURE__ */ c(t, {
9
- open: h,
8
+ function f({ cancelLabel: f = "Cancel", confirmLabel: p = "Confirm", description: m, loading: h = !1, onConfirm: g, onOpenChange: _, open: v, title: y, trigger: b, variant: x = "default" }) {
9
+ let S = l.useRef(null), C = l.useRef(null), w = l.useRef(null), T = l.useRef(v);
10
+ return l.useEffect(() => {
11
+ T.current && !v && S.current?.focus(), T.current = v;
12
+ }, [v]), /* @__PURE__ */ d(t, {
13
+ open: v,
10
14
  onOpenChange: (e) => {
11
- f && !e || m(e);
15
+ h && !e || _(e);
12
16
  },
13
- children: /* @__PURE__ */ l(n, { children: [/* @__PURE__ */ l(a, { children: [/* @__PURE__ */ c(o, { children: g }), /* @__PURE__ */ c(r, { children: d })] }), /* @__PURE__ */ l(i, { children: [/* @__PURE__ */ c(e, {
14
- disabled: f,
15
- variant: "outline",
16
- onClick: () => m(!1),
17
- children: s
18
- }), /* @__PURE__ */ c(e, {
19
- loading: f,
20
- variant: _,
21
- onClick: () => {
22
- f || p();
17
+ children: [l.isValidElement(b) ? /* @__PURE__ */ u(s, {
18
+ ref: S,
19
+ asChild: !0,
20
+ children: b
21
+ }) : null, /* @__PURE__ */ d(n, {
22
+ ref: C,
23
+ onOpenAutoFocus: (e) => {
24
+ if (e.preventDefault(), w.current && !w.current.disabled) {
25
+ w.current.focus();
26
+ return;
27
+ }
28
+ C.current?.focus();
23
29
  },
24
- children: u
25
- })] })] })
30
+ onCloseAutoFocus: (e) => {
31
+ e.preventDefault(), S.current?.focus();
32
+ },
33
+ children: [/* @__PURE__ */ d(a, { children: [/* @__PURE__ */ u(o, { children: y }), /* @__PURE__ */ u(r, { children: m })] }), /* @__PURE__ */ d(i, { children: [/* @__PURE__ */ u(c.Cancel, {
34
+ asChild: !0,
35
+ children: /* @__PURE__ */ u(e, {
36
+ ref: w,
37
+ disabled: h,
38
+ variant: "outline",
39
+ children: f
40
+ })
41
+ }), /* @__PURE__ */ u(c.Action, {
42
+ asChild: !0,
43
+ children: /* @__PURE__ */ u(e, {
44
+ loading: h,
45
+ variant: x,
46
+ onClick: (e) => {
47
+ e.preventDefault(), h || g();
48
+ },
49
+ children: p
50
+ })
51
+ })] })]
52
+ })]
26
53
  });
27
54
  }
28
- function d() {
29
- let [e, t] = s.useState(!1), [n, r] = s.useState({
55
+ function p() {
56
+ let [e, t] = l.useState(!1), [n, r] = l.useState({
30
57
  title: "",
31
58
  description: ""
32
- }), i = s.useRef(null), a = s.useCallback((e) => {
59
+ }), i = l.useRef(null), a = l.useCallback((e) => {
33
60
  let t = i.current;
34
61
  i.current = null, t?.(e);
35
62
  }, []);
36
- return s.useEffect(() => () => {
63
+ return l.useEffect(() => () => {
37
64
  a(!1);
38
65
  }, [a]), {
39
- confirm: s.useCallback((e) => (a(!1), r(e), t(!0), new Promise((e) => {
66
+ confirm: l.useCallback((e) => (a(!1), r(e), t(!0), new Promise((e) => {
40
67
  i.current = e;
41
68
  })), [a]),
42
69
  dialogProps: {
@@ -56,6 +83,6 @@ function d() {
56
83
  };
57
84
  }
58
85
  //#endregion
59
- export { u as ConfirmDialog, d as useConfirm };
86
+ export { f as ConfirmDialog, p as useConfirm };
60
87
 
61
88
  //# sourceMappingURL=confirm-dialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"confirm-dialog.js","names":[],"sources":["../../src/components/confirm-dialog.tsx"],"sourcesContent":["import * as React from \"react\";\nimport {\n\tAlertDialog,\n\tAlertDialogContent,\n\tAlertDialogDescription,\n\tAlertDialogFooter,\n\tAlertDialogHeader,\n\tAlertDialogTitle,\n} from \"./alert-dialog\";\nimport { Button } from \"./button\";\n\nexport type ConfirmDialogVariant = \"default\" | \"destructive\";\n\nexport interface ConfirmDialogProps {\n\t/** Whether the confirmation dialog is shown. */\n\topen: boolean;\n\t/** Called when the dialog requests to open or close. */\n\tonOpenChange: (open: boolean) => void;\n\t/** Called once when the user confirms. The dialog does not close itself. */\n\tonConfirm: () => void | Promise<void>;\n\t/** The dialog title. */\n\ttitle: React.ReactNode;\n\t/** Supporting copy that describes the action. */\n\tdescription: React.ReactNode;\n\t/**\n\t * Label for the confirm button.\n\t * @default \"Confirm\"\n\t */\n\tconfirmLabel?: React.ReactNode;\n\t/**\n\t * Label for the cancel button.\n\t * @default \"Cancel\"\n\t */\n\tcancelLabel?: React.ReactNode;\n\t/**\n\t * Appearance of the confirm button.\n\t * @default \"default\"\n\t */\n\tvariant?: ConfirmDialogVariant;\n\t/**\n\t * Disable both actions and ignore close requests while work is pending.\n\t * @default false\n\t */\n\tloading?: boolean;\n}\n\nexport interface UseConfirmOptions {\n\t/** The dialog title. */\n\ttitle: React.ReactNode;\n\t/** Supporting copy that describes the action. */\n\tdescription: React.ReactNode;\n\t/** Label for the confirm button. */\n\tconfirmLabel?: React.ReactNode;\n\t/** Label for the cancel button. */\n\tcancelLabel?: React.ReactNode;\n\t/** Appearance of the confirm button. */\n\tvariant?: ConfirmDialogVariant;\n}\n\nexport interface UseConfirmResult {\n\tconfirm: (options: UseConfirmOptions) => Promise<boolean>;\n\tdialogProps: ConfirmDialogProps;\n}\n\nexport function ConfirmDialog({\n\tcancelLabel = \"Cancel\",\n\tconfirmLabel = \"Confirm\",\n\tdescription,\n\tloading = false,\n\tonConfirm,\n\tonOpenChange,\n\topen,\n\ttitle,\n\tvariant = \"default\",\n}: ConfirmDialogProps) {\n\treturn (\n\t\t<AlertDialog\n\t\t\topen={open}\n\t\t\tonOpenChange={(next) => {\n\t\t\t\tif (loading && !next) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonOpenChange(next);\n\t\t\t}}\n\t\t>\n\t\t\t<AlertDialogContent>\n\t\t\t\t<AlertDialogHeader>\n\t\t\t\t\t<AlertDialogTitle>{title}</AlertDialogTitle>\n\t\t\t\t\t<AlertDialogDescription>{description}</AlertDialogDescription>\n\t\t\t\t</AlertDialogHeader>\n\t\t\t\t<AlertDialogFooter>\n\t\t\t\t\t<Button disabled={loading} variant=\"outline\" onClick={() => onOpenChange(false)}>\n\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tloading={loading}\n\t\t\t\t\t\tvariant={variant}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tif (!loading) {\n\t\t\t\t\t\t\t\tvoid onConfirm();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{confirmLabel}\n\t\t\t\t\t</Button>\n\t\t\t\t</AlertDialogFooter>\n\t\t\t</AlertDialogContent>\n\t\t</AlertDialog>\n\t);\n}\n\nexport function useConfirm(): UseConfirmResult {\n\tconst [open, setOpen] = React.useState(false);\n\tconst [options, setOptions] = React.useState<UseConfirmOptions>({\n\t\ttitle: \"\",\n\t\tdescription: \"\",\n\t});\n\tconst resolverRef = React.useRef<((value: boolean) => void) | null>(null);\n\n\tconst settle = React.useCallback((value: boolean) => {\n\t\tconst resolve = resolverRef.current;\n\t\tresolverRef.current = null;\n\t\tresolve?.(value);\n\t}, []);\n\n\tReact.useEffect(() => {\n\t\treturn () => {\n\t\t\tsettle(false);\n\t\t};\n\t}, [settle]);\n\n\tconst confirm = React.useCallback(\n\t\t(next: UseConfirmOptions) => {\n\t\t\tsettle(false);\n\t\t\tsetOptions(next);\n\t\t\tsetOpen(true);\n\t\t\treturn new Promise<boolean>((resolve) => {\n\t\t\t\tresolverRef.current = resolve;\n\t\t\t});\n\t\t},\n\t\t[settle],\n\t);\n\n\treturn {\n\t\tconfirm,\n\t\tdialogProps: {\n\t\t\topen,\n\t\t\ttitle: options.title,\n\t\t\tdescription: options.description,\n\t\t\tconfirmLabel: options.confirmLabel,\n\t\t\tcancelLabel: options.cancelLabel,\n\t\t\tvariant: options.variant,\n\t\t\tonOpenChange: (next) => {\n\t\t\t\tsetOpen(next);\n\t\t\t\tif (!next) {\n\t\t\t\t\tsettle(false);\n\t\t\t\t}\n\t\t\t},\n\t\t\tonConfirm: () => {\n\t\t\t\tsettle(true);\n\t\t\t\tsetOpen(false);\n\t\t\t},\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;AAgEA,SAAgB,EAAc,EAC7B,iBAAc,UACd,kBAAe,WACf,gBACA,aAAU,IACV,cACA,iBACA,SACA,UACA,aAAU,aACY;CACtB,OACC,kBAAC,GAAD;EACO;EACN,eAAe,MAAS;GACnB,KAAW,CAAC,KAGhB,EAAa,CAAI;EAClB;EAEA,UAAA,kBAAC,GAAD,EAAA,UAAA,CACC,kBAAC,GAAD,EAAA,UAAA,CACC,kBAAC,GAAD,EAAA,UAAmB,EAAwB,CAAA,GAC3C,kBAAC,GAAD,EAAA,UAAyB,EAAoC,CAAA,CAC3C,EAAA,CAAA,GACnB,kBAAC,GAAD,EAAA,UAAA,CACC,kBAAC,GAAD;GAAQ,UAAU;GAAS,SAAQ;GAAU,eAAe,EAAa,EAAK;GAC5E,UAAA;EACM,CAAA,GACR,kBAAC,GAAD;GACU;GACA;GACT,eAAe;IACd,AAAK,KACJ,EAAe;GAEjB;GAEC,UAAA;EACM,CAAA,CACU,EAAA,CAAA,CACA,EAAA,CAAA;CACR,CAAA;AAEf;AAEA,SAAgB,IAA+B;CAC9C,IAAM,CAAC,GAAM,KAAW,EAAM,SAAS,EAAK,GACtC,CAAC,GAAS,KAAc,EAAM,SAA4B;EAC/D,OAAO;EACP,aAAa;CACd,CAAC,GACK,IAAc,EAAM,OAA0C,IAAI,GAElE,IAAS,EAAM,aAAa,MAAmB;EACpD,IAAM,IAAU,EAAY;EAE5B,AADA,EAAY,UAAU,MACtB,IAAU,CAAK;CAChB,GAAG,CAAC,CAAC;CAoBL,OAlBA,EAAM,sBACQ;EACZ,EAAO,EAAK;CACb,GACE,CAAC,CAAM,CAAC,GAcJ;EACN,SAbe,EAAM,aACpB,OACA,EAAO,EAAK,GACZ,EAAW,CAAI,GACf,EAAQ,EAAI,GACL,IAAI,SAAkB,MAAY;GACxC,EAAY,UAAU;EACvB,CAAC,IAEF,CAAC,CAAM,CAIP;EACA,aAAa;GACZ;GACA,OAAO,EAAQ;GACf,aAAa,EAAQ;GACrB,cAAc,EAAQ;GACtB,aAAa,EAAQ;GACrB,SAAS,EAAQ;GACjB,eAAe,MAAS;IAEvB,AADA,EAAQ,CAAI,GACP,KACJ,EAAO,EAAK;GAEd;GACA,iBAAiB;IAEhB,AADA,EAAO,EAAI,GACX,EAAQ,EAAK;GACd;EACD;CACD;AACD"}
1
+ {"version":3,"file":"confirm-dialog.js","names":[],"sources":["../../src/components/confirm-dialog.tsx"],"sourcesContent":["import * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\nimport * as React from \"react\";\nimport {\n\tAlertDialog,\n\tAlertDialogContent,\n\tAlertDialogDescription,\n\tAlertDialogFooter,\n\tAlertDialogHeader,\n\tAlertDialogTitle,\n\tAlertDialogTrigger,\n} from \"./alert-dialog\";\nimport { Button } from \"./button\";\n\nexport type ConfirmDialogVariant = \"default\" | \"destructive\";\n\nexport interface ConfirmDialogProps {\n\t/** Whether the confirmation dialog is shown. */\n\topen: boolean;\n\t/** Called when the dialog requests to open or close. */\n\tonOpenChange: (open: boolean) => void;\n\t/** Called once when the user confirms. The dialog does not close itself. */\n\tonConfirm: () => void | Promise<void>;\n\t/** The dialog title. */\n\ttitle: React.ReactNode;\n\t/** Supporting copy that describes the action. */\n\tdescription: React.ReactNode;\n\t/**\n\t * Label for the confirm button.\n\t * @default \"Confirm\"\n\t */\n\tconfirmLabel?: React.ReactNode;\n\t/**\n\t * Label for the cancel button.\n\t * @default \"Cancel\"\n\t */\n\tcancelLabel?: React.ReactNode;\n\t/**\n\t * Appearance of the confirm button.\n\t * @default \"default\"\n\t */\n\tvariant?: ConfirmDialogVariant;\n\t/**\n\t * Disable both actions and ignore close requests while work is pending.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Control that opens the dialog. When set, closing restores focus to it.\n\t */\n\ttrigger?: React.ReactElement;\n}\n\nexport interface UseConfirmOptions {\n\t/** The dialog title. */\n\ttitle: React.ReactNode;\n\t/** Supporting copy that describes the action. */\n\tdescription: React.ReactNode;\n\t/** Label for the confirm button. */\n\tconfirmLabel?: React.ReactNode;\n\t/** Label for the cancel button. */\n\tcancelLabel?: React.ReactNode;\n\t/** Appearance of the confirm button. */\n\tvariant?: ConfirmDialogVariant;\n}\n\nexport interface UseConfirmResult {\n\tconfirm: (options: UseConfirmOptions) => Promise<boolean>;\n\tdialogProps: ConfirmDialogProps;\n}\n\nexport function ConfirmDialog({\n\tcancelLabel = \"Cancel\",\n\tconfirmLabel = \"Confirm\",\n\tdescription,\n\tloading = false,\n\tonConfirm,\n\tonOpenChange,\n\topen,\n\ttitle,\n\ttrigger,\n\tvariant = \"default\",\n}: ConfirmDialogProps) {\n\tconst triggerRef = React.useRef<HTMLButtonElement>(null);\n\tconst panelRef = React.useRef<HTMLDivElement>(null);\n\tconst cancelRef = React.useRef<HTMLButtonElement>(null);\n\tconst wasOpenRef = React.useRef(open);\n\tReact.useEffect(() => {\n\t\tif (wasOpenRef.current && !open) {\n\t\t\ttriggerRef.current?.focus();\n\t\t}\n\t\twasOpenRef.current = open;\n\t}, [open]);\n\treturn (\n\t\t<AlertDialog\n\t\t\topen={open}\n\t\t\tonOpenChange={(next) => {\n\t\t\t\tif (loading && !next) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonOpenChange(next);\n\t\t\t}}\n\t\t>\n\t\t\t{React.isValidElement(trigger) ? (\n\t\t\t\t<AlertDialogTrigger ref={triggerRef} asChild>\n\t\t\t\t\t{trigger}\n\t\t\t\t</AlertDialogTrigger>\n\t\t\t) : null}\n\t\t\t<AlertDialogContent\n\t\t\t\tref={panelRef}\n\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tif (cancelRef.current && !cancelRef.current.disabled) {\n\t\t\t\t\t\tcancelRef.current.focus();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tpanelRef.current?.focus();\n\t\t\t\t}}\n\t\t\t\tonCloseAutoFocus={(event) => {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\ttriggerRef.current?.focus();\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<AlertDialogHeader>\n\t\t\t\t\t<AlertDialogTitle>{title}</AlertDialogTitle>\n\t\t\t\t\t<AlertDialogDescription>{description}</AlertDialogDescription>\n\t\t\t\t</AlertDialogHeader>\n\t\t\t\t<AlertDialogFooter>\n\t\t\t\t\t<AlertDialogPrimitive.Cancel asChild>\n\t\t\t\t\t\t<Button ref={cancelRef} disabled={loading} variant=\"outline\">\n\t\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</AlertDialogPrimitive.Cancel>\n\t\t\t\t\t<AlertDialogPrimitive.Action asChild>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tloading={loading}\n\t\t\t\t\t\t\tvariant={variant}\n\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tif (!loading) {\n\t\t\t\t\t\t\t\t\tvoid onConfirm();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{confirmLabel}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</AlertDialogPrimitive.Action>\n\t\t\t\t</AlertDialogFooter>\n\t\t\t</AlertDialogContent>\n\t\t</AlertDialog>\n\t);\n}\n\nexport function useConfirm(): UseConfirmResult {\n\tconst [open, setOpen] = React.useState(false);\n\tconst [options, setOptions] = React.useState<UseConfirmOptions>({\n\t\ttitle: \"\",\n\t\tdescription: \"\",\n\t});\n\tconst resolverRef = React.useRef<((value: boolean) => void) | null>(null);\n\n\tconst settle = React.useCallback((value: boolean) => {\n\t\tconst resolve = resolverRef.current;\n\t\tresolverRef.current = null;\n\t\tresolve?.(value);\n\t}, []);\n\n\tReact.useEffect(() => {\n\t\treturn () => {\n\t\t\tsettle(false);\n\t\t};\n\t}, [settle]);\n\n\tconst confirm = React.useCallback(\n\t\t(next: UseConfirmOptions) => {\n\t\t\tsettle(false);\n\t\t\tsetOptions(next);\n\t\t\tsetOpen(true);\n\t\t\treturn new Promise<boolean>((resolve) => {\n\t\t\t\tresolverRef.current = resolve;\n\t\t\t});\n\t\t},\n\t\t[settle],\n\t);\n\n\treturn {\n\t\tconfirm,\n\t\tdialogProps: {\n\t\t\topen,\n\t\t\ttitle: options.title,\n\t\t\tdescription: options.description,\n\t\t\tconfirmLabel: options.confirmLabel,\n\t\t\tcancelLabel: options.cancelLabel,\n\t\t\tvariant: options.variant,\n\t\t\tonOpenChange: (next) => {\n\t\t\t\tsetOpen(next);\n\t\t\t\tif (!next) {\n\t\t\t\t\tsettle(false);\n\t\t\t\t}\n\t\t\t},\n\t\t\tonConfirm: () => {\n\t\t\t\tsettle(true);\n\t\t\t\tsetOpen(false);\n\t\t\t},\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;AAsEA,SAAgB,EAAc,EAC7B,iBAAc,UACd,kBAAe,WACf,gBACA,aAAU,IACV,cACA,iBACA,SACA,UACA,YACA,aAAU,aACY;CACtB,IAAM,IAAa,EAAM,OAA0B,IAAI,GACjD,IAAW,EAAM,OAAuB,IAAI,GAC5C,IAAY,EAAM,OAA0B,IAAI,GAChD,IAAa,EAAM,OAAO,CAAI;CAOpC,OANA,EAAM,gBAAgB;EAIrB,AAHI,EAAW,WAAW,CAAC,KAC1B,EAAW,SAAS,MAAM,GAE3B,EAAW,UAAU;CACtB,GAAG,CAAC,CAAI,CAAC,GAER,kBAAC,GAAD;EACO;EACN,eAAe,MAAS;GACnB,KAAW,CAAC,KAGhB,EAAa,CAAI;EAClB;EAPD,UAAA,CASE,EAAM,eAAe,CAAO,IAC5B,kBAAC,GAAD;GAAoB,KAAK;GAAY,SAAA;GACnC,UAAA;EACkB,CAAA,IACjB,MACJ,kBAAC,GAAD;GACC,KAAK;GACL,kBAAkB,MAAU;IAE3B,IADA,EAAM,eAAe,GACjB,EAAU,WAAW,CAAC,EAAU,QAAQ,UAAU;KACrD,EAAU,QAAQ,MAAM;KACxB;IACD;IACA,EAAS,SAAS,MAAM;GACzB;GACA,mBAAmB,MAAU;IAE5B,AADA,EAAM,eAAe,GACrB,EAAW,SAAS,MAAM;GAC3B;GAbD,UAAA,CAeC,kBAAC,GAAD,EAAA,UAAA,CACC,kBAAC,GAAD,EAAA,UAAmB,EAAwB,CAAA,GAC3C,kBAAC,GAAD,EAAA,UAAyB,EAAoC,CAAA,CAC3C,EAAA,CAAA,GACnB,kBAAC,GAAD,EAAA,UAAA,CACC,kBAAC,EAAqB,QAAtB;IAA6B,SAAA;IAC5B,UAAA,kBAAC,GAAD;KAAQ,KAAK;KAAW,UAAU;KAAS,SAAQ;KACjD,UAAA;IACM,CAAA;GACoB,CAAA,GAC7B,kBAAC,EAAqB,QAAtB;IAA6B,SAAA;IAC5B,UAAA,kBAAC,GAAD;KACU;KACA;KACT,UAAU,MAAU;MAEnB,AADA,EAAM,eAAe,GAChB,KACJ,EAAe;KAEjB;KAEC,UAAA;IACM,CAAA;GACoB,CAAA,CACX,EAAA,CAAA,CACA;EACR,CAAA,CAAA;;AAEf;AAEA,SAAgB,IAA+B;CAC9C,IAAM,CAAC,GAAM,KAAW,EAAM,SAAS,EAAK,GACtC,CAAC,GAAS,KAAc,EAAM,SAA4B;EAC/D,OAAO;EACP,aAAa;CACd,CAAC,GACK,IAAc,EAAM,OAA0C,IAAI,GAElE,IAAS,EAAM,aAAa,MAAmB;EACpD,IAAM,IAAU,EAAY;EAE5B,AADA,EAAY,UAAU,MACtB,IAAU,CAAK;CAChB,GAAG,CAAC,CAAC;CAoBL,OAlBA,EAAM,sBACQ;EACZ,EAAO,EAAK;CACb,GACE,CAAC,CAAM,CAAC,GAcJ;EACN,SAbe,EAAM,aACpB,OACA,EAAO,EAAK,GACZ,EAAW,CAAI,GACf,EAAQ,EAAI,GACL,IAAI,SAAkB,MAAY;GACxC,EAAY,UAAU;EACvB,CAAC,IAEF,CAAC,CAAM,CAIP;EACA,aAAa;GACZ;GACA,OAAO,EAAQ;GACf,aAAa,EAAQ;GACrB,cAAc,EAAQ;GACtB,aAAa,EAAQ;GACrB,SAAS,EAAQ;GACjB,eAAe,MAAS;IAEvB,AADA,EAAQ,CAAI,GACP,KACJ,EAAO,EAAK;GAEd;GACA,iBAAiB;IAEhB,AADA,EAAO,EAAI,GACX,EAAQ,EAAK;GACd;EACD;CACD;AACD"}
@@ -0,0 +1,5 @@
1
+ export type DeleteResourceProps = {
2
+ name: string;
3
+ onDelete: () => void | Promise<void>;
4
+ };
5
+ export declare function DeleteResource({ name, onDelete }: DeleteResourceProps): import("react").JSX.Element;
@@ -0,0 +1,38 @@
1
+ "use client";
2
+ import { Button as e } from "./button.js";
3
+ import { ConfirmDialog as t } from "./confirm-dialog.js";
4
+ import { useState as n } from "react";
5
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
6
+ //#region src/components/delete-resource.tsx
7
+ function a({ name: a, onDelete: o }) {
8
+ let [s, c] = n(!1), [l, u] = n(!1);
9
+ return /* @__PURE__ */ r(t, {
10
+ trigger: /* @__PURE__ */ i(e, {
11
+ variant: "destructive",
12
+ children: ["Delete ", a]
13
+ }),
14
+ open: s,
15
+ loading: l,
16
+ variant: "destructive",
17
+ title: `Delete ${a}?`,
18
+ description: "This cannot be undone.",
19
+ confirmLabel: "Delete",
20
+ onOpenChange: (e) => {
21
+ l && !e || (c(e), e || u(!1));
22
+ },
23
+ onConfirm: async () => {
24
+ u(!0);
25
+ try {
26
+ await o(), c(!1);
27
+ } catch {
28
+ c(!0);
29
+ } finally {
30
+ u(!1);
31
+ }
32
+ }
33
+ });
34
+ }
35
+ //#endregion
36
+ export { a as DeleteResource };
37
+
38
+ //# sourceMappingURL=delete-resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-resource.js","names":[],"sources":["../../src/components/delete-resource.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"./button\";\nimport { ConfirmDialog } from \"./confirm-dialog\";\n\nexport type DeleteResourceProps = {\n\tname: string;\n\tonDelete: () => void | Promise<void>;\n};\n\nexport function DeleteResource({ name, onDelete }: DeleteResourceProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [loading, setLoading] = useState(false);\n\treturn (\n\t\t<ConfirmDialog\n\t\t\ttrigger={<Button variant=\"destructive\">Delete {name}</Button>}\n\t\t\topen={open}\n\t\t\tloading={loading}\n\t\t\tvariant=\"destructive\"\n\t\t\ttitle={`Delete ${name}?`}\n\t\t\tdescription=\"This cannot be undone.\"\n\t\t\tconfirmLabel=\"Delete\"\n\t\t\tonOpenChange={(next) => {\n\t\t\t\tif (loading && !next) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsetOpen(next);\n\t\t\t\tif (!next) {\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t}}\n\t\t\tonConfirm={async () => {\n\t\t\t\tsetLoading(true);\n\t\t\t\ttry {\n\t\t\t\t\tawait onDelete();\n\t\t\t\t\tsetOpen(false);\n\t\t\t\t} catch {\n\t\t\t\t\tsetOpen(true);\n\t\t\t\t} finally {\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;AASA,SAAgB,EAAe,EAAE,SAAM,eAAiC;CACvE,IAAM,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,CAAC,GAAS,KAAc,EAAS,EAAK;CAC5C,OACC,kBAAC,GAAD;EACC,SAAS,kBAAC,GAAD;GAAQ,SAAQ;GAAhB,UAAA,CAA8B,WAAQ,CAAa;;EACtD;EACG;EACT,SAAQ;EACR,OAAO,UAAU,EAAK;EACtB,aAAY;EACZ,cAAa;EACb,eAAe,MAAS;GACnB,KAAW,CAAC,MAGhB,EAAQ,CAAI,GACP,KACJ,EAAW,EAAK;EAElB;EACA,WAAW,YAAY;GACtB,EAAW,EAAI;GACf,IAAI;IAEH,AADA,MAAM,EAAS,GACf,EAAQ,EAAK;GACd,QAAQ;IACP,EAAQ,EAAI;GACb,UAAU;IACT,EAAW,EAAK;GACjB;EACD;CACA,CAAA;AAEH"}
@@ -10,11 +10,15 @@ function i({ label: i = "Loading", mark: a, className: o, ...s }) {
10
10
  className: e("fixed inset-0 z-50 flex items-center justify-center bg-basalt-background", o),
11
11
  ...s,
12
12
  children: /* @__PURE__ */ r("div", {
13
- className: "relative",
14
- children: [/* @__PURE__ */ n("div", {
15
- className: "flex h-72 w-72 items-center justify-center overflow-hidden rounded-full bg-basalt-secondary p-6 ring-1 ring-basalt-border",
16
- children: a ?? /* @__PURE__ */ n(t, { className: "h-28 w-28 text-basalt-muted-foreground" })
17
- }), /* @__PURE__ */ n("div", { className: "absolute inset-[-4px] animate-basalt-spin rounded-full border-[3px] border-transparent border-t-basalt-primary motion-reduce:animate-none" })]
13
+ className: "flex flex-col items-center gap-4",
14
+ children: [a ?? /* @__PURE__ */ n(t, { className: "h-8 w-8 text-basalt-foreground" }), /* @__PURE__ */ n("div", {
15
+ className: "relative h-px overflow-hidden rounded-full bg-basalt-border",
16
+ style: { width: "6rem" },
17
+ children: /* @__PURE__ */ n("span", {
18
+ className: "absolute inset-0 animate-basalt-shimmer motion-reduce:animate-none",
19
+ style: { background: "linear-gradient(to right, transparent, hsl(var(--basalt-foreground) / 0.5), transparent)" }
20
+ })
21
+ })]
18
22
  })
19
23
  });
20
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loading-screen.js","names":[],"sources":["../../src/components/loading-screen.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BasaltMark } from \"./basalt-mark\";\n\nexport function LoadingScreen({\n\tlabel = \"Loading\",\n\tmark,\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLDivElement> & {\n\tlabel?: string;\n\tmark?: ReactNode;\n}) {\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\n\t\t\t\t\"fixed inset-0 z-50 flex items-center justify-center bg-basalt-background\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"relative\">\n\t\t\t\t<div className=\"flex h-72 w-72 items-center justify-center overflow-hidden rounded-full bg-basalt-secondary p-6 ring-1 ring-basalt-border\">\n\t\t\t\t\t{mark ?? <BasaltMark className=\"h-28 w-28 text-basalt-muted-foreground\" />}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"absolute inset-[-4px] animate-basalt-spin rounded-full border-[3px] border-transparent border-t-basalt-primary motion-reduce:animate-none\" />\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;AAIA,SAAgB,EAAc,EAC7B,WAAQ,WACR,SACA,cACA,GAAG,KAID;CACF,OACC,kBAAC,OAAD;EACC,MAAK;EACL,cAAY;EACZ,WAAW,EACV,4EACA,CACD;EACA,GAAI;EAEJ,UAAA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACC,kBAAC,OAAD;IAAK,WAAU;IACb,UAAA,KAAQ,kBAAC,GAAD,EAAY,WAAU,yCAA0C,CAAA;GACrE,CAAA,GACL,kBAAC,OAAD,EAAK,WAAU,4IAA6I,CAAA,CACxJ;;CACD,CAAA;AAEP"}
1
+ {"version":3,"file":"loading-screen.js","names":[],"sources":["../../src/components/loading-screen.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BasaltMark } from \"./basalt-mark\";\n\nexport function LoadingScreen({\n\tlabel = \"Loading\",\n\tmark,\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLDivElement> & {\n\tlabel?: string;\n\tmark?: ReactNode;\n}) {\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\n\t\t\t\t\"fixed inset-0 z-50 flex items-center justify-center bg-basalt-background\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"flex flex-col items-center gap-4\">\n\t\t\t\t{mark ?? <BasaltMark className=\"h-8 w-8 text-basalt-foreground\" />}\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative h-px overflow-hidden rounded-full bg-basalt-border\"\n\t\t\t\t\tstyle={{ width: \"6rem\" }}\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName=\"absolute inset-0 animate-basalt-shimmer motion-reduce:animate-none\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground:\n\t\t\t\t\t\t\t\t\"linear-gradient(to right, transparent, hsl(var(--basalt-foreground) / 0.5), transparent)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;AAIA,SAAgB,EAAc,EAC7B,WAAQ,WACR,SACA,cACA,GAAG,KAID;CACF,OACC,kBAAC,OAAD;EACC,MAAK;EACL,cAAY;EACZ,WAAW,EACV,4EACA,CACD;EACA,GAAI;EAEJ,UAAA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,KAAQ,kBAAC,GAAD,EAAY,WAAU,iCAAkC,CAAA,GACjE,kBAAC,OAAD;IACC,WAAU;IACV,OAAO,EAAE,OAAO,OAAO;IAEvB,UAAA,kBAAC,QAAD;KACC,WAAU;KACV,OAAO,EACN,YACC,2FACF;IACA,CAAA;GACG,CAAA,CACD;;CACD,CAAA;AAEP"}
@@ -0,0 +1,10 @@
1
+ export type ResourceListRow = {
2
+ name: string;
3
+ status: string;
4
+ };
5
+ export type ResourceListProps = {
6
+ title: string;
7
+ description?: string;
8
+ data: ResourceListRow[];
9
+ };
10
+ export declare function ResourceList({ title, description, data }: ResourceListProps): import("react").JSX.Element;
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { DataTable as e } from "./data-table.js";
3
+ import { PageHeader as t } from "./page-header.js";
4
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
+ //#region src/components/resource-list.tsx
6
+ var i = [{
7
+ id: "name",
8
+ header: "Name",
9
+ accessor: (e) => e.name
10
+ }, {
11
+ id: "status",
12
+ header: "Status",
13
+ accessor: (e) => e.status
14
+ }];
15
+ function a({ title: a, description: o, data: s }) {
16
+ return /* @__PURE__ */ r("div", {
17
+ className: "space-y-4",
18
+ children: [/* @__PURE__ */ n(t, {
19
+ title: a,
20
+ description: o
21
+ }), /* @__PURE__ */ n(e, {
22
+ data: s,
23
+ columns: i
24
+ })]
25
+ });
26
+ }
27
+ //#endregion
28
+ export { a as ResourceList };
29
+
30
+ //# sourceMappingURL=resource-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-list.js","names":[],"sources":["../../src/components/resource-list.tsx"],"sourcesContent":["import { DataTable, type DataTableColumn } from \"./data-table\";\nimport { PageHeader } from \"./page-header\";\n\nexport type ResourceListRow = {\n\tname: string;\n\tstatus: string;\n};\n\nexport type ResourceListProps = {\n\ttitle: string;\n\tdescription?: string;\n\tdata: ResourceListRow[];\n};\n\nconst COLUMNS: DataTableColumn<ResourceListRow>[] = [\n\t{ id: \"name\", header: \"Name\", accessor: (row) => row.name },\n\t{ id: \"status\", header: \"Status\", accessor: (row) => row.status },\n];\n\nexport function ResourceList({ title, description, data }: ResourceListProps) {\n\treturn (\n\t\t<div className=\"space-y-4\">\n\t\t\t<PageHeader title={title} description={description} />\n\t\t\t<DataTable data={data} columns={COLUMNS} />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;AAcA,IAAM,IAA8C,CACnD;CAAE,IAAI;CAAQ,QAAQ;CAAQ,WAAW,MAAQ,EAAI;AAAK,GAC1D;CAAE,IAAI;CAAU,QAAQ;CAAU,WAAW,MAAQ,EAAI;AAAO,CACjE;AAEA,SAAgB,EAAa,EAAE,UAAO,gBAAa,WAA2B;CAC7E,OACC,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACC,kBAAC,GAAD;GAAmB;GAAoB;EAAc,CAAA,GACrD,kBAAC,GAAD;GAAiB;GAAM,SAAS;EAAU,CAAA,CACtC;;AAEP"}
@@ -0,0 +1,22 @@
1
+ import { type ReactNode } from "react";
2
+ export type AccentSwatch = {
3
+ id: string;
4
+ label: string;
5
+ light: string;
6
+ dark: string;
7
+ foreground: string;
8
+ };
9
+ export declare const ACCENT_SWATCHES: readonly AccentSwatch[];
10
+ export declare const DEFAULT_ACCENT_ID = "blue";
11
+ type AccentContextValue = {
12
+ accent: string;
13
+ setAccent: (id: string) => void;
14
+ swatches: readonly AccentSwatch[];
15
+ };
16
+ export declare function accentSwatchById(id: string | null | undefined): AccentSwatch;
17
+ export declare function applyAccent(id: string, dark?: boolean): void;
18
+ export declare function AccentProvider({ children }: {
19
+ children: ReactNode;
20
+ }): import("react").JSX.Element;
21
+ export declare function useAccent(): AccentContextValue;
22
+ export {};
@@ -0,0 +1,110 @@
1
+ "use client";
2
+ import { createContext as e, useCallback as t, useContext as n, useEffect as r, useMemo as i, useSyncExternalStore as a } from "react";
3
+ import { jsx as o } from "react/jsx-runtime";
4
+ //#region src/providers/accent.tsx
5
+ var s = [
6
+ {
7
+ id: "blue",
8
+ label: "Blue",
9
+ light: "217 80% 36%",
10
+ dark: "217 80% 38%",
11
+ foreground: "0 0% 100%"
12
+ },
13
+ {
14
+ id: "teal",
15
+ label: "Teal",
16
+ light: "186 72% 28%",
17
+ dark: "186 72% 32%",
18
+ foreground: "0 0% 100%"
19
+ },
20
+ {
21
+ id: "green",
22
+ label: "Green",
23
+ light: "142 64% 28%",
24
+ dark: "142 64% 32%",
25
+ foreground: "0 0% 100%"
26
+ },
27
+ {
28
+ id: "amber",
29
+ label: "Amber",
30
+ light: "38 88% 44%",
31
+ dark: "38 88% 56%",
32
+ foreground: "0 0% 10%"
33
+ },
34
+ {
35
+ id: "orange",
36
+ label: "Orange",
37
+ light: "24 86% 36%",
38
+ dark: "24 86% 38%",
39
+ foreground: "0 0% 100%"
40
+ },
41
+ {
42
+ id: "rose",
43
+ label: "Rose",
44
+ light: "340 72% 36%",
45
+ dark: "340 72% 38%",
46
+ foreground: "0 0% 100%"
47
+ },
48
+ {
49
+ id: "purple",
50
+ label: "Purple",
51
+ light: "270 52% 36%",
52
+ dark: "270 52% 38%",
53
+ foreground: "0 0% 100%"
54
+ },
55
+ {
56
+ id: "indigo",
57
+ label: "Indigo",
58
+ light: "250 52% 36%",
59
+ dark: "250 52% 38%",
60
+ foreground: "0 0% 100%"
61
+ }
62
+ ], c = "blue", l = "basalt-accent", u = e(null);
63
+ function d(e) {
64
+ return s.find((t) => t.id === e) ?? s[0];
65
+ }
66
+ function f(e, t = !1) {
67
+ let n = d(e), r = t ? n.dark : n.light, i = document.documentElement;
68
+ i.style.setProperty("--basalt-primary", r), i.style.setProperty("--basalt-primary-foreground", n.foreground), i.style.setProperty("--basalt-ring", r), i.style.setProperty("--basalt-chart-1", r), i.dataset.accent = n.id;
69
+ }
70
+ function p() {
71
+ return d(window.localStorage.getItem(l)).id;
72
+ }
73
+ function m(e) {
74
+ return window.addEventListener("storage", e), () => window.removeEventListener("storage", e);
75
+ }
76
+ function h() {
77
+ return document.documentElement.classList.contains("dark");
78
+ }
79
+ function g({ children: e }) {
80
+ let n = a(m, p, () => c);
81
+ r(() => {
82
+ f(n, h());
83
+ let e = new MutationObserver(() => f(n, h()));
84
+ return e.observe(document.documentElement, {
85
+ attributes: !0,
86
+ attributeFilter: ["class"]
87
+ }), () => e.disconnect();
88
+ }, [n]);
89
+ let g = t((e) => {
90
+ let t = d(e).id;
91
+ window.localStorage.setItem(l, t), f(t, h()), window.dispatchEvent(new Event("storage"));
92
+ }, []), _ = i(() => ({
93
+ accent: n,
94
+ setAccent: g,
95
+ swatches: s
96
+ }), [n, g]);
97
+ return /* @__PURE__ */ o(u.Provider, {
98
+ value: _,
99
+ children: e
100
+ });
101
+ }
102
+ function _() {
103
+ let e = n(u);
104
+ if (!e) throw Error("useAccent must be used within AccentProvider");
105
+ return e;
106
+ }
107
+ //#endregion
108
+ export { s as ACCENT_SWATCHES, g as AccentProvider, c as DEFAULT_ACCENT_ID, d as accentSwatchById, f as applyAccent, _ as useAccent };
109
+
110
+ //# sourceMappingURL=accent.js.map