@open-mercato/ui 0.7.0 → 0.7.1-develop.7102.1.b41f7e3e51

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 (67) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/ai/records/ActivityCard.js +4 -3
  3. package/dist/ai/records/ActivityCard.js.map +2 -2
  4. package/dist/ai/records/DealCard.js +4 -3
  5. package/dist/ai/records/DealCard.js.map +2 -2
  6. package/dist/ai/records/ProductCard.js +3 -2
  7. package/dist/ai/records/ProductCard.js.map +2 -2
  8. package/dist/backend/AppShell.js +129 -106
  9. package/dist/backend/AppShell.js.map +2 -2
  10. package/dist/backend/DataTable.js +20 -7
  11. package/dist/backend/DataTable.js.map +2 -2
  12. package/dist/backend/detail/NotesSection.js +26 -20
  13. package/dist/backend/detail/NotesSection.js.map +2 -2
  14. package/dist/backend/icons/lucideRegistry.generated.js +4 -0
  15. package/dist/backend/icons/lucideRegistry.generated.js.map +2 -2
  16. package/dist/backend/injection/useRegisteredComponent.js +24 -6
  17. package/dist/backend/injection/useRegisteredComponent.js.map +2 -2
  18. package/dist/backend/inputs/ComboboxInput.js +8 -4
  19. package/dist/backend/inputs/ComboboxInput.js.map +2 -2
  20. package/dist/backend/inputs/LookupSelect.js +8 -8
  21. package/dist/backend/inputs/LookupSelect.js.map +2 -2
  22. package/dist/backend/sidebar/SidebarCustomizationEditor.js +36 -30
  23. package/dist/backend/sidebar/SidebarCustomizationEditor.js.map +2 -2
  24. package/dist/backend/utils/crud.js.map +2 -2
  25. package/dist/primitives/alert.js +1 -1
  26. package/dist/primitives/alert.js.map +2 -2
  27. package/dist/primitives/icon-button.js +20 -1
  28. package/dist/primitives/icon-button.js.map +2 -2
  29. package/dist/primitives/pagination.js +14 -9
  30. package/dist/primitives/pagination.js.map +2 -2
  31. package/dist/primitives/rich-editor.js +14 -7
  32. package/dist/primitives/rich-editor.js.map +2 -2
  33. package/dist/utils/format.js +5 -5
  34. package/dist/utils/format.js.map +2 -2
  35. package/package.json +5 -4
  36. package/src/ai/parts/__tests__/ConfirmationCard.test.tsx +2 -0
  37. package/src/ai/records/ActivityCard.tsx +4 -3
  38. package/src/ai/records/DealCard.tsx +4 -3
  39. package/src/ai/records/ProductCard.tsx +3 -2
  40. package/src/backend/AppShell.tsx +89 -58
  41. package/src/backend/DataTable.tsx +44 -10
  42. package/src/backend/__tests__/AppShell.test.tsx +162 -1
  43. package/src/backend/__tests__/DataTable.cappedPagination.test.tsx +122 -0
  44. package/src/backend/__tests__/DataTable.headerWrap.test.tsx +111 -0
  45. package/src/backend/__tests__/DataTable.render.test.tsx +37 -0
  46. package/src/backend/__tests__/NotesSection.test.tsx +89 -0
  47. package/src/backend/__tests__/useRegisteredComponent.identity.test.tsx +305 -0
  48. package/src/backend/detail/NotesSection.tsx +92 -67
  49. package/src/backend/icons/lucideRegistry.generated.tsx +4 -0
  50. package/src/backend/injection/useRegisteredComponent.tsx +49 -8
  51. package/src/backend/inputs/ComboboxInput.tsx +21 -5
  52. package/src/backend/inputs/LookupSelect.tsx +8 -8
  53. package/src/backend/inputs/__tests__/ComboboxInput.test.tsx +142 -0
  54. package/src/backend/inputs/__tests__/LookupSelect.test.tsx +75 -0
  55. package/src/backend/sidebar/SidebarCustomizationEditor.tsx +14 -11
  56. package/src/backend/utils/crud.ts +2 -0
  57. package/src/primitives/__tests__/alert.test.tsx +41 -1
  58. package/src/primitives/__tests__/icon-button.test.tsx +70 -0
  59. package/src/primitives/__tests__/notification.test.tsx +1 -1
  60. package/src/primitives/__tests__/pagination.test.tsx +54 -0
  61. package/src/primitives/__tests__/rich-editor.test.tsx +43 -0
  62. package/src/primitives/alert.tsx +5 -2
  63. package/src/primitives/icon-button.tsx +20 -1
  64. package/src/primitives/pagination.tsx +40 -9
  65. package/src/primitives/rich-editor.tsx +9 -4
  66. package/src/utils/__tests__/format.test.ts +27 -14
  67. package/src/utils/format.ts +10 -5
@@ -1,3 +1,3 @@
1
- Generated lucide registry with 159 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
1
+ Generated lucide registry with 161 icons -> /home/runner/work/open-mercato/open-mercato/packages/ui/src/backend/icons/lucideRegistry.generated.tsx
2
2
  [build:ui] found 400 entry points
3
3
  [build:ui] built successfully
@@ -10,7 +10,7 @@ import {
10
10
  Phone,
11
11
  StickyNote
12
12
  } from "lucide-react";
13
- import { useT } from "@open-mercato/shared/lib/i18n/context";
13
+ import { useT, useLocale } from "@open-mercato/shared/lib/i18n/context";
14
14
  import { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from "./RecordCardShell.js";
15
15
  import { formatDate } from "../../utils/format.js";
16
16
  function pickActivityIcon(type) {
@@ -26,10 +26,11 @@ function pickActivityIcon(type) {
26
26
  }
27
27
  function ActivityCard(props) {
28
28
  const t = useT();
29
+ const locale = useLocale();
29
30
  const Icon = pickActivityIcon(props.type);
30
31
  const status = props.status ? { label: props.status, variant: statusToTagVariant(props.status) } : null;
31
- const dueDate = formatDate(props.dueDate);
32
- const completedAt = formatDate(props.completedAt);
32
+ const dueDate = formatDate(props.dueDate, locale);
33
+ const completedAt = formatDate(props.completedAt, locale);
33
34
  const items = [
34
35
  props.type ? { label: t("ai_assistant.chat.records.fields.type", "Type"), value: props.type } : null,
35
36
  dueDate ? {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/ai/records/ActivityCard.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n Activity as ActivityIcon,\n CalendarClock,\n CheckCircle2,\n ListChecks,\n Mail,\n MessageSquare,\n Phone,\n StickyNote,\n} from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { ActivityRecordPayload } from './types'\nimport { formatDate } from '../../utils/format'\n\nfunction pickActivityIcon(type: string | null | undefined): LucideIcon {\n if (!type) return ActivityIcon\n const t = type.toLowerCase()\n if (t.includes('call')) return Phone\n if (t.includes('mail') || t.includes('email')) return Mail\n if (t.includes('meeting') || t.includes('chat')) return MessageSquare\n if (t.includes('task') || t.includes('todo')) return ListChecks\n if (t.includes('note')) return StickyNote\n if (t.includes('done') || t.includes('complete')) return CheckCircle2\n return ActivityIcon\n}\n\nexport interface ActivityCardProps extends ActivityRecordPayload {}\n\nexport function ActivityCard(props: ActivityCardProps) {\n const t = useT()\n const Icon = pickActivityIcon(props.type)\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const dueDate = formatDate(props.dueDate)\n const completedAt = formatDate(props.completedAt)\n\n const items = [\n props.type ? { label: t('ai_assistant.chat.records.fields.type', 'Type'), value: props.type } : null,\n dueDate\n ? {\n label: t('ai_assistant.chat.records.fields.due', 'Due'),\n value: (\n <span className=\"inline-flex items-center gap-1\">\n <CalendarClock className=\"size-3 text-muted-foreground\" aria-hidden />\n {dueDate}\n </span>\n ),\n }\n : null,\n completedAt\n ? {\n label: t('ai_assistant.chat.records.fields.completed', 'Completed'),\n value: (\n <span className=\"inline-flex items-center gap-1\">\n <CheckCircle2 className=\"size-3 text-status-success-icon\" aria-hidden />\n {completedAt}\n </span>\n ),\n }\n : null,\n props.relatedTo ? { label: t('ai_assistant.chat.records.fields.related', 'Related'), value: props.relatedTo } : null,\n props.ownerName ? { label: t('ai_assistant.chat.records.fields.owner', 'Owner'), value: props.ownerName } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n const subtitle = [props.type, props.relatedTo].filter(Boolean).join(' \u2022 ')\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.activity', 'Activity')}\n kindIcon={<Icon className=\"size-4\" aria-hidden />}\n title={props.title}\n subtitle={subtitle || undefined}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"activity\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-3 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default ActivityCard\n"],
5
- "mappings": ";AAgDY,SACE,KADF;AA7CZ;AAAA,EACE,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,YAAY;AACrB,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,kBAAkB;AAE3B,SAAS,iBAAiB,MAA6C;AACrE,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,IAAI,KAAK,YAAY;AAC3B,MAAI,EAAE,SAAS,MAAM,EAAG,QAAO;AAC/B,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,OAAO,EAAG,QAAO;AACtD,MAAI,EAAE,SAAS,SAAS,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACxD,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACrD,MAAI,EAAE,SAAS,MAAM,EAAG,QAAO;AAC/B,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,UAAU,EAAG,QAAO;AACzD,SAAO;AACT;AAIO,SAAS,aAAa,OAA0B;AACrD,QAAM,IAAI,KAAK;AACf,QAAM,OAAO,iBAAiB,MAAM,IAAI;AACxC,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,UAAU,WAAW,MAAM,OAAO;AACxC,QAAM,cAAc,WAAW,MAAM,WAAW;AAEhD,QAAM,QAAQ;AAAA,IACZ,MAAM,OAAO,EAAE,OAAO,EAAE,yCAAyC,MAAM,GAAG,OAAO,MAAM,KAAK,IAAI;AAAA,IAChG,UACI;AAAA,MACE,OAAO,EAAE,wCAAwC,KAAK;AAAA,MACtD,OACE,qBAAC,UAAK,WAAU,kCACd;AAAA,4BAAC,iBAAc,WAAU,gCAA+B,eAAW,MAAC;AAAA,QACnE;AAAA,SACH;AAAA,IAEJ,IACA;AAAA,IACJ,cACI;AAAA,MACE,OAAO,EAAE,8CAA8C,WAAW;AAAA,MAClE,OACE,qBAAC,UAAK,WAAU,kCACd;AAAA,4BAAC,gBAAa,WAAU,mCAAkC,eAAW,MAAC;AAAA,QACrE;AAAA,SACH;AAAA,IAEJ,IACA;AAAA,IACJ,MAAM,YAAY,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,IAChH,MAAM,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,EAC9G,EAAE,OAAO,OAAO;AAEhB,QAAM,WAAW,CAAC,MAAM,MAAM,MAAM,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,UAAK;AAEzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,4CAA4C,UAAU;AAAA,MACnE,UAAU,oBAAC,QAAK,WAAU,UAAS,eAAW,MAAC;AAAA,MAC/C,OAAO,MAAM;AAAA,MACb,UAAU,YAAY;AAAA,MACtB;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,uBAAQ;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n Activity as ActivityIcon,\n CalendarClock,\n CheckCircle2,\n ListChecks,\n Mail,\n MessageSquare,\n Phone,\n StickyNote,\n} from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\nimport { useT, useLocale } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { ActivityRecordPayload } from './types'\nimport { formatDate } from '../../utils/format'\n\nfunction pickActivityIcon(type: string | null | undefined): LucideIcon {\n if (!type) return ActivityIcon\n const t = type.toLowerCase()\n if (t.includes('call')) return Phone\n if (t.includes('mail') || t.includes('email')) return Mail\n if (t.includes('meeting') || t.includes('chat')) return MessageSquare\n if (t.includes('task') || t.includes('todo')) return ListChecks\n if (t.includes('note')) return StickyNote\n if (t.includes('done') || t.includes('complete')) return CheckCircle2\n return ActivityIcon\n}\n\nexport interface ActivityCardProps extends ActivityRecordPayload {}\n\nexport function ActivityCard(props: ActivityCardProps) {\n const t = useT()\n const locale = useLocale()\n const Icon = pickActivityIcon(props.type)\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const dueDate = formatDate(props.dueDate, locale)\n const completedAt = formatDate(props.completedAt, locale)\n\n const items = [\n props.type ? { label: t('ai_assistant.chat.records.fields.type', 'Type'), value: props.type } : null,\n dueDate\n ? {\n label: t('ai_assistant.chat.records.fields.due', 'Due'),\n value: (\n <span className=\"inline-flex items-center gap-1\">\n <CalendarClock className=\"size-3 text-muted-foreground\" aria-hidden />\n {dueDate}\n </span>\n ),\n }\n : null,\n completedAt\n ? {\n label: t('ai_assistant.chat.records.fields.completed', 'Completed'),\n value: (\n <span className=\"inline-flex items-center gap-1\">\n <CheckCircle2 className=\"size-3 text-status-success-icon\" aria-hidden />\n {completedAt}\n </span>\n ),\n }\n : null,\n props.relatedTo ? { label: t('ai_assistant.chat.records.fields.related', 'Related'), value: props.relatedTo } : null,\n props.ownerName ? { label: t('ai_assistant.chat.records.fields.owner', 'Owner'), value: props.ownerName } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n const subtitle = [props.type, props.relatedTo].filter(Boolean).join(' \u2022 ')\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.activity', 'Activity')}\n kindIcon={<Icon className=\"size-4\" aria-hidden />}\n title={props.title}\n subtitle={subtitle || undefined}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"activity\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-3 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default ActivityCard\n"],
5
+ "mappings": ";AAiDY,SACE,KADF;AA9CZ;AAAA,EACE,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,MAAM,iBAAiB;AAChC,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,kBAAkB;AAE3B,SAAS,iBAAiB,MAA6C;AACrE,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,IAAI,KAAK,YAAY;AAC3B,MAAI,EAAE,SAAS,MAAM,EAAG,QAAO;AAC/B,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,OAAO,EAAG,QAAO;AACtD,MAAI,EAAE,SAAS,SAAS,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACxD,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AACrD,MAAI,EAAE,SAAS,MAAM,EAAG,QAAO;AAC/B,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,UAAU,EAAG,QAAO;AACzD,SAAO;AACT;AAIO,SAAS,aAAa,OAA0B;AACrD,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,OAAO,iBAAiB,MAAM,IAAI;AACxC,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,UAAU,WAAW,MAAM,SAAS,MAAM;AAChD,QAAM,cAAc,WAAW,MAAM,aAAa,MAAM;AAExD,QAAM,QAAQ;AAAA,IACZ,MAAM,OAAO,EAAE,OAAO,EAAE,yCAAyC,MAAM,GAAG,OAAO,MAAM,KAAK,IAAI;AAAA,IAChG,UACI;AAAA,MACE,OAAO,EAAE,wCAAwC,KAAK;AAAA,MACtD,OACE,qBAAC,UAAK,WAAU,kCACd;AAAA,4BAAC,iBAAc,WAAU,gCAA+B,eAAW,MAAC;AAAA,QACnE;AAAA,SACH;AAAA,IAEJ,IACA;AAAA,IACJ,cACI;AAAA,MACE,OAAO,EAAE,8CAA8C,WAAW;AAAA,MAClE,OACE,qBAAC,UAAK,WAAU,kCACd;AAAA,4BAAC,gBAAa,WAAU,mCAAkC,eAAW,MAAC;AAAA,QACrE;AAAA,SACH;AAAA,IAEJ,IACA;AAAA,IACJ,MAAM,YAAY,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,IAChH,MAAM,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,EAC9G,EAAE,OAAO,OAAO;AAEhB,QAAM,WAAW,CAAC,MAAM,MAAM,MAAM,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,UAAK;AAEzE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,4CAA4C,UAAU;AAAA,MACnE,UAAU,oBAAC,QAAK,WAAU,UAAS,eAAW,MAAC;AAAA,MAC/C,OAAO,MAAM;AAAA,MACb,UAAU,YAAY;AAAA,MACtB;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,uBAAQ;",
6
6
  "names": []
7
7
  }
@@ -1,15 +1,16 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Briefcase, Building2, CalendarDays, CircleDollarSign, User } from "lucide-react";
4
- import { useT } from "@open-mercato/shared/lib/i18n/context";
4
+ import { useT, useLocale } from "@open-mercato/shared/lib/i18n/context";
5
5
  import { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from "./RecordCardShell.js";
6
6
  import { formatCurrency, formatDate } from "../../utils/format.js";
7
7
  function DealCard(props) {
8
8
  const t = useT();
9
+ const locale = useLocale();
9
10
  const status = props.status ? { label: props.status, variant: statusToTagVariant(props.status) } : null;
10
11
  const stage = props.stage && props.stage !== props.status ? props.stage : null;
11
- const amount = formatCurrency(props.amount, props.currency);
12
- const closeDate = formatDate(props.closeDate);
12
+ const amount = formatCurrency(props.amount, props.currency, locale);
13
+ const closeDate = formatDate(props.closeDate, locale);
13
14
  const items = [
14
15
  stage ? { label: t("ai_assistant.chat.records.fields.stage", "Stage"), value: stage } : null,
15
16
  amount ? { label: t("ai_assistant.chat.records.fields.amount", "Amount"), value: /* @__PURE__ */ jsx("span", { className: "font-medium", children: amount }) } : null,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/ai/records/DealCard.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Briefcase, Building2, CalendarDays, CircleDollarSign, User } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { DealRecordPayload } from './types'\nimport { formatCurrency, formatDate } from '../../utils/format'\n\nexport interface DealCardProps extends DealRecordPayload {}\n\nexport function DealCard(props: DealCardProps) {\n const t = useT()\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const stage = props.stage && props.stage !== props.status ? props.stage : null\n const amount = formatCurrency(props.amount, props.currency)\n const closeDate = formatDate(props.closeDate)\n\n const items = [\n stage ? { label: t('ai_assistant.chat.records.fields.stage', 'Stage'), value: stage } : null,\n amount ? { label: t('ai_assistant.chat.records.fields.amount', 'Amount'), value: <span className=\"font-medium\">{amount}</span> } : null,\n closeDate ? { label: t('ai_assistant.chat.records.fields.close', 'Close'), value: closeDate } : null,\n props.companyName ? { label: t('ai_assistant.chat.records.fields.company', 'Company'), value: props.companyName } : null,\n props.personName ? { label: t('ai_assistant.chat.records.fields.contact', 'Contact'), value: props.personName } : null,\n props.ownerName ? { label: t('ai_assistant.chat.records.fields.owner', 'Owner'), value: props.ownerName } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n const subtitleParts: string[] = []\n if (props.companyName) subtitleParts.push(props.companyName)\n if (props.personName && !props.companyName) subtitleParts.push(props.personName)\n if (amount) subtitleParts.push(amount)\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.deal', 'Deal')}\n kindIcon={<Briefcase className=\"size-4\" aria-hidden />}\n title={props.title}\n subtitle={subtitleParts.join(' \u2022 ')}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"deal\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-2 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default DealCard\n\n// Re-export icons consumers may want when extending the layout\nexport { Briefcase, Building2, CalendarDays, CircleDollarSign, User }\n"],
5
- "mappings": ";AAsBqF,cAwB/E,YAxB+E;AAnBrF,SAAS,WAAW,WAAW,cAAc,kBAAkB,YAAY;AAC3E,SAAS,YAAY;AACrB,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,gBAAgB,kBAAkB;AAIpC,SAAS,SAAS,OAAsB;AAC7C,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,SAAS,MAAM,QAAQ;AAC1E,QAAM,SAAS,eAAe,MAAM,QAAQ,MAAM,QAAQ;AAC1D,QAAM,YAAY,WAAW,MAAM,SAAS;AAE5C,QAAM,QAAQ;AAAA,IACZ,QAAQ,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,IAAI;AAAA,IACxF,SAAS,EAAE,OAAO,EAAE,2CAA2C,QAAQ,GAAG,OAAO,oBAAC,UAAK,WAAU,eAAe,kBAAO,EAAQ,IAAI;AAAA,IACnI,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,UAAU,IAAI;AAAA,IAChG,MAAM,cAAc,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,YAAY,IAAI;AAAA,IACpH,MAAM,aAAa,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,WAAW,IAAI;AAAA,IAClH,MAAM,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,EAC9G,EAAE,OAAO,OAAO;AAEhB,QAAM,gBAA0B,CAAC;AACjC,MAAI,MAAM,YAAa,eAAc,KAAK,MAAM,WAAW;AAC3D,MAAI,MAAM,cAAc,CAAC,MAAM,YAAa,eAAc,KAAK,MAAM,UAAU;AAC/E,MAAI,OAAQ,eAAc,KAAK,MAAM;AAErC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,wCAAwC,MAAM;AAAA,MAC3D,UAAU,oBAAC,aAAU,WAAU,UAAS,eAAW,MAAC;AAAA,MACpD,OAAO,MAAM;AAAA,MACb,UAAU,cAAc,KAAK,UAAK;AAAA,MAClC;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,mBAAQ;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Briefcase, Building2, CalendarDays, CircleDollarSign, User } from 'lucide-react'\nimport { useT, useLocale } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { DealRecordPayload } from './types'\nimport { formatCurrency, formatDate } from '../../utils/format'\n\nexport interface DealCardProps extends DealRecordPayload {}\n\nexport function DealCard(props: DealCardProps) {\n const t = useT()\n const locale = useLocale()\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const stage = props.stage && props.stage !== props.status ? props.stage : null\n const amount = formatCurrency(props.amount, props.currency, locale)\n const closeDate = formatDate(props.closeDate, locale)\n\n const items = [\n stage ? { label: t('ai_assistant.chat.records.fields.stage', 'Stage'), value: stage } : null,\n amount ? { label: t('ai_assistant.chat.records.fields.amount', 'Amount'), value: <span className=\"font-medium\">{amount}</span> } : null,\n closeDate ? { label: t('ai_assistant.chat.records.fields.close', 'Close'), value: closeDate } : null,\n props.companyName ? { label: t('ai_assistant.chat.records.fields.company', 'Company'), value: props.companyName } : null,\n props.personName ? { label: t('ai_assistant.chat.records.fields.contact', 'Contact'), value: props.personName } : null,\n props.ownerName ? { label: t('ai_assistant.chat.records.fields.owner', 'Owner'), value: props.ownerName } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n const subtitleParts: string[] = []\n if (props.companyName) subtitleParts.push(props.companyName)\n if (props.personName && !props.companyName) subtitleParts.push(props.personName)\n if (amount) subtitleParts.push(amount)\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.deal', 'Deal')}\n kindIcon={<Briefcase className=\"size-4\" aria-hidden />}\n title={props.title}\n subtitle={subtitleParts.join(' \u2022 ')}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"deal\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-2 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default DealCard\n\n// Re-export icons consumers may want when extending the layout\nexport { Briefcase, Building2, CalendarDays, CircleDollarSign, User }\n"],
5
+ "mappings": ";AAuBqF,cAwB/E,YAxB+E;AApBrF,SAAS,WAAW,WAAW,cAAc,kBAAkB,YAAY;AAC3E,SAAS,MAAM,iBAAiB;AAChC,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,gBAAgB,kBAAkB;AAIpC,SAAS,SAAS,OAAsB;AAC7C,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,QAAQ,MAAM,SAAS,MAAM,UAAU,MAAM,SAAS,MAAM,QAAQ;AAC1E,QAAM,SAAS,eAAe,MAAM,QAAQ,MAAM,UAAU,MAAM;AAClE,QAAM,YAAY,WAAW,MAAM,WAAW,MAAM;AAEpD,QAAM,QAAQ;AAAA,IACZ,QAAQ,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,IAAI;AAAA,IACxF,SAAS,EAAE,OAAO,EAAE,2CAA2C,QAAQ,GAAG,OAAO,oBAAC,UAAK,WAAU,eAAe,kBAAO,EAAQ,IAAI;AAAA,IACnI,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,UAAU,IAAI;AAAA,IAChG,MAAM,cAAc,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,YAAY,IAAI;AAAA,IACpH,MAAM,aAAa,EAAE,OAAO,EAAE,4CAA4C,SAAS,GAAG,OAAO,MAAM,WAAW,IAAI;AAAA,IAClH,MAAM,YAAY,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,MAAM,UAAU,IAAI;AAAA,EAC9G,EAAE,OAAO,OAAO;AAEhB,QAAM,gBAA0B,CAAC;AACjC,MAAI,MAAM,YAAa,eAAc,KAAK,MAAM,WAAW;AAC3D,MAAI,MAAM,cAAc,CAAC,MAAM,YAAa,eAAc,KAAK,MAAM,UAAU;AAC/E,MAAI,OAAQ,eAAc,KAAK,MAAM;AAErC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,wCAAwC,MAAM;AAAA,MAC3D,UAAU,oBAAC,aAAU,WAAU,UAAS,eAAW,MAAC;AAAA,MACpD,OAAO,MAAM;AAAA,MACb,UAAU,cAAc,KAAK,UAAK;AAAA,MAClC;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,mBAAQ;",
6
6
  "names": []
7
7
  }
@@ -1,13 +1,14 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Package, Tag as TagIcon } from "lucide-react";
4
- import { useT } from "@open-mercato/shared/lib/i18n/context";
4
+ import { useT, useLocale } from "@open-mercato/shared/lib/i18n/context";
5
5
  import { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from "./RecordCardShell.js";
6
6
  import { formatCurrency } from "../../utils/format.js";
7
7
  function ProductCard(props) {
8
8
  const t = useT();
9
+ const locale = useLocale();
9
10
  const status = props.status ? { label: props.status, variant: statusToTagVariant(props.status) } : null;
10
- const price = formatCurrency(props.price, props.currency);
11
+ const price = formatCurrency(props.price, props.currency, locale);
11
12
  const leading = props.imageUrl ? /* @__PURE__ */ jsx("div", { className: "relative size-12 overflow-hidden rounded-md border border-border bg-muted", children: /* @__PURE__ */ jsx(
12
13
  "img",
13
14
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/ai/records/ProductCard.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Package, Tag as TagIcon } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { ProductRecordPayload } from './types'\nimport { formatCurrency } from '../../utils/format'\n\nexport interface ProductCardProps extends ProductRecordPayload {}\n\nexport function ProductCard(props: ProductCardProps) {\n const t = useT()\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const price = formatCurrency(props.price, props.currency)\n\n const leading = props.imageUrl ? (\n <div className=\"relative size-12 overflow-hidden rounded-md border border-border bg-muted\">\n <img\n src={props.imageUrl}\n alt={props.name}\n className=\"size-full object-cover\"\n loading=\"lazy\"\n />\n </div>\n ) : (\n <div className=\"flex size-12 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground\" aria-hidden>\n <Package className=\"size-5\" />\n </div>\n )\n\n const items = [\n props.sku ? { label: t('ai_assistant.chat.records.fields.sku', 'SKU'), value: <span className=\"font-mono text-[11px]\">{props.sku}</span> } : null,\n price ? { label: t('ai_assistant.chat.records.fields.price', 'Price'), value: <span className=\"font-medium\">{price}</span> } : null,\n props.category ? { label: t('ai_assistant.chat.records.fields.category', 'Category'), value: props.category } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.product', 'Product')}\n kindIcon={<Package className=\"size-4\" aria-hidden />}\n leading={leading}\n title={props.name}\n subtitle={[props.sku, price].filter(Boolean).join(' \u2022 ') || undefined}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"product\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-2 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default ProductCard\n\nexport { Package, TagIcon }\n"],
5
- "mappings": ";AAoBM,cAgCA,YAhCA;AAjBN,SAAS,SAAS,OAAO,eAAe;AACxC,SAAS,YAAY;AACrB,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,sBAAsB;AAIxB,SAAS,YAAY,OAAyB;AACnD,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,QAAQ,eAAe,MAAM,OAAO,MAAM,QAAQ;AAExD,QAAM,UAAU,MAAM,WACpB,oBAAC,SAAI,WAAU,6EACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,MAAM;AAAA,MACX,KAAK,MAAM;AAAA,MACX,WAAU;AAAA,MACV,SAAQ;AAAA;AAAA,EACV,GACF,IAEA,oBAAC,SAAI,WAAU,2GAA0G,eAAW,MAClI,8BAAC,WAAQ,WAAU,UAAS,GAC9B;AAGF,QAAM,QAAQ;AAAA,IACZ,MAAM,MAAM,EAAE,OAAO,EAAE,wCAAwC,KAAK,GAAG,OAAO,oBAAC,UAAK,WAAU,yBAAyB,gBAAM,KAAI,EAAQ,IAAI;AAAA,IAC7I,QAAQ,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,oBAAC,UAAK,WAAU,eAAe,iBAAM,EAAQ,IAAI;AAAA,IAC/H,MAAM,WAAW,EAAE,OAAO,EAAE,6CAA6C,UAAU,GAAG,OAAO,MAAM,SAAS,IAAI;AAAA,EAClH,EAAE,OAAO,OAAO;AAEhB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,2CAA2C,SAAS;AAAA,MACjE,UAAU,oBAAC,WAAQ,WAAU,UAAS,eAAW,MAAC;AAAA,MAClD;AAAA,MACA,OAAO,MAAM;AAAA,MACb,UAAU,CAAC,MAAM,KAAK,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,UAAK,KAAK;AAAA,MAC5D;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,sBAAQ;",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Package, Tag as TagIcon } from 'lucide-react'\nimport { useT, useLocale } from '@open-mercato/shared/lib/i18n/context'\nimport { KeyValueList, RecordCardShell, TagRow, statusToTagVariant } from './RecordCardShell'\nimport type { ProductRecordPayload } from './types'\nimport { formatCurrency } from '../../utils/format'\n\nexport interface ProductCardProps extends ProductRecordPayload {}\n\nexport function ProductCard(props: ProductCardProps) {\n const t = useT()\n const locale = useLocale()\n const status = props.status\n ? { label: props.status, variant: statusToTagVariant(props.status) }\n : null\n const price = formatCurrency(props.price, props.currency, locale)\n\n const leading = props.imageUrl ? (\n <div className=\"relative size-12 overflow-hidden rounded-md border border-border bg-muted\">\n <img\n src={props.imageUrl}\n alt={props.name}\n className=\"size-full object-cover\"\n loading=\"lazy\"\n />\n </div>\n ) : (\n <div className=\"flex size-12 items-center justify-center rounded-md border border-border bg-muted text-muted-foreground\" aria-hidden>\n <Package className=\"size-5\" />\n </div>\n )\n\n const items = [\n props.sku ? { label: t('ai_assistant.chat.records.fields.sku', 'SKU'), value: <span className=\"font-mono text-[11px]\">{props.sku}</span> } : null,\n price ? { label: t('ai_assistant.chat.records.fields.price', 'Price'), value: <span className=\"font-medium\">{price}</span> } : null,\n props.category ? { label: t('ai_assistant.chat.records.fields.category', 'Category'), value: props.category } : null,\n ].filter(Boolean) as { label: string; value: React.ReactNode }[]\n\n return (\n <RecordCardShell\n kindLabel={t('ai_assistant.chat.records.kinds.product', 'Product')}\n kindIcon={<Package className=\"size-4\" aria-hidden />}\n leading={leading}\n title={props.name}\n subtitle={[props.sku, price].filter(Boolean).join(' \u2022 ') || undefined}\n status={status}\n href={props.href}\n id={props.id}\n className={props.className}\n dataKind=\"product\"\n >\n <div className=\"space-y-2\">\n <KeyValueList items={items} />\n {props.description ? (\n <p className=\"line-clamp-2 text-muted-foreground\">{props.description}</p>\n ) : null}\n {props.tags && props.tags.length > 0 ? <TagRow tags={props.tags} /> : null}\n </div>\n </RecordCardShell>\n )\n}\n\nexport default ProductCard\n\nexport { Package, TagIcon }\n"],
5
+ "mappings": ";AAqBM,cAgCA,YAhCA;AAlBN,SAAS,SAAS,OAAO,eAAe;AACxC,SAAS,MAAM,iBAAiB;AAChC,SAAS,cAAc,iBAAiB,QAAQ,0BAA0B;AAE1E,SAAS,sBAAsB;AAIxB,SAAS,YAAY,OAAyB;AACnD,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,SAAS,MAAM,SACjB,EAAE,OAAO,MAAM,QAAQ,SAAS,mBAAmB,MAAM,MAAM,EAAE,IACjE;AACJ,QAAM,QAAQ,eAAe,MAAM,OAAO,MAAM,UAAU,MAAM;AAEhE,QAAM,UAAU,MAAM,WACpB,oBAAC,SAAI,WAAU,6EACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,MAAM;AAAA,MACX,KAAK,MAAM;AAAA,MACX,WAAU;AAAA,MACV,SAAQ;AAAA;AAAA,EACV,GACF,IAEA,oBAAC,SAAI,WAAU,2GAA0G,eAAW,MAClI,8BAAC,WAAQ,WAAU,UAAS,GAC9B;AAGF,QAAM,QAAQ;AAAA,IACZ,MAAM,MAAM,EAAE,OAAO,EAAE,wCAAwC,KAAK,GAAG,OAAO,oBAAC,UAAK,WAAU,yBAAyB,gBAAM,KAAI,EAAQ,IAAI;AAAA,IAC7I,QAAQ,EAAE,OAAO,EAAE,0CAA0C,OAAO,GAAG,OAAO,oBAAC,UAAK,WAAU,eAAe,iBAAM,EAAQ,IAAI;AAAA,IAC/H,MAAM,WAAW,EAAE,OAAO,EAAE,6CAA6C,UAAU,GAAG,OAAO,MAAM,SAAS,IAAI;AAAA,EAClH,EAAE,OAAO,OAAO;AAEhB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,EAAE,2CAA2C,SAAS;AAAA,MACjE,UAAU,oBAAC,WAAQ,WAAU,UAAS,eAAW,MAAC;AAAA,MAClD;AAAA,MACA,OAAO,MAAM;AAAA,MACb,UAAU,CAAC,MAAM,KAAK,KAAK,EAAE,OAAO,OAAO,EAAE,KAAK,UAAK,KAAK;AAAA,MAC5D;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,UAAS;AAAA,MAET,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,gBAAa,OAAc;AAAA,QAC3B,MAAM,cACL,oBAAC,OAAE,WAAU,sCAAsC,gBAAM,aAAY,IACnE;AAAA,QACH,MAAM,QAAQ,MAAM,KAAK,SAAS,IAAI,oBAAC,UAAO,MAAM,MAAM,MAAM,IAAK;AAAA,SACxE;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,sBAAQ;",
6
6
  "names": []
7
7
  }
@@ -267,6 +267,12 @@ function resolveItemKey(item) {
267
267
  if (candidate && candidate.length > 0) return candidate;
268
268
  return item.href;
269
269
  }
270
+ function sidebarBlockPadding(compact) {
271
+ return `${compact ? "px-2" : "px-3"} transition-[padding] duration-200 ease-out`;
272
+ }
273
+ function sidebarInjectionWrapper(compact) {
274
+ return `${sidebarBlockPadding(compact)} empty:hidden`;
275
+ }
270
276
  function SerializedIcon({ markup }) {
271
277
  return /* @__PURE__ */ jsx("span", { "aria-hidden": "true", dangerouslySetInnerHTML: { __html: markup } });
272
278
  }
@@ -528,10 +534,6 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
528
534
  const key = resolveGroupKey(activeGroup);
529
535
  setOpenGroups((prev) => prev[key] === false ? { ...prev, [key]: true } : prev);
530
536
  }, [pathname, navGroups]);
531
- React.useEffect(() => {
532
- setHeaderTitle(currentTitle);
533
- setHeaderBreadcrumb(breadcrumb);
534
- }, [currentTitle, breadcrumb]);
535
537
  const prevPathname = React.useRef(pathname);
536
538
  useIsomorphicLayoutEffect(() => {
537
539
  if (pathname !== prevPathname.current) {
@@ -540,14 +542,19 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
540
542
  setHeaderBreadcrumb(void 0);
541
543
  }
542
544
  }, [pathname]);
545
+ useIsomorphicLayoutEffect(() => {
546
+ setHeaderTitle(currentTitle);
547
+ setHeaderBreadcrumb(breadcrumb);
548
+ }, [currentTitle, breadcrumb]);
543
549
  React.useEffect(() => {
544
550
  setNavGroups(cloneSidebarGroups(resolvedGroups));
545
551
  }, [resolvedGroups]);
546
552
  function renderSectionSidebar(sections, title, compact, hideHeader, hideSearch) {
547
553
  const sortedSections = [...sections].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
548
554
  const lastVisibleIndex = sortedSections.length - 1;
555
+ const blockPadding = sidebarBlockPadding(compact);
549
556
  return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col gap-3", children: [
550
- !hideHeader && /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs(
557
+ !hideHeader && /* @__PURE__ */ jsx("div", { className: `mb-2 ${blockPadding}`, children: /* @__PURE__ */ jsxs(
551
558
  Link,
552
559
  {
553
560
  href: "/backend",
@@ -559,7 +566,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
559
566
  ]
560
567
  }
561
568
  ) }),
562
- !compact && !hideSearch && /* @__PURE__ */ jsx(
569
+ !compact && !hideSearch && /* @__PURE__ */ jsx("div", { className: blockPadding, children: /* @__PURE__ */ jsx(
563
570
  SearchInput,
564
571
  {
565
572
  value: navQuery,
@@ -569,8 +576,8 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
569
576
  clearLabel: t("appShell.searchNavClear", "Clear search"),
570
577
  className: "mb-2"
571
578
  }
572
- ),
573
- /* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className: `flex flex-1 flex-col gap-3 overflow-y-auto scrollbar-hide pr-1 ${compact ? "-ml-2 pl-2" : "-ml-3 pl-3"}`, children: /* @__PURE__ */ jsx("nav", { className: "flex flex-col gap-2", children: sortedSections.map((section, sectionIndex) => {
579
+ ) }),
580
+ /* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className: "flex flex-1 flex-col gap-3 overflow-x-hidden overflow-y-auto scrollbar-hide", children: /* @__PURE__ */ jsx("nav", { className: "flex flex-col gap-2", children: sortedSections.map((section, sectionIndex) => {
574
581
  const sectionNavQueryActive = hideSearch ? false : navQueryActive;
575
582
  const matchesItemQuery = (item) => {
576
583
  if (!sectionNavQueryActive) return true;
@@ -627,29 +634,38 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
627
634
  showChildren ? childItems.map((child) => renderSectionItem(child, depth + 1)) : null
628
635
  ] }, item.id);
629
636
  };
630
- return /* @__PURE__ */ jsxs("div", { children: [
631
- !compact && /* @__PURE__ */ jsxs(
632
- Button,
633
- {
634
- variant: "muted",
635
- onClick: () => toggleGroup(sectionKey),
636
- className: "w-full px-1 justify-between flex text-xs font-medium uppercase tracking-wider text-muted-foreground/70 py-1",
637
- "aria-expanded": open,
638
- children: [
639
- /* @__PURE__ */ jsx("span", { children: sectionLabel }),
640
- /* @__PURE__ */ jsx(Chevron, { open })
641
- ]
642
- }
643
- ),
644
- (open || compact) && /* @__PURE__ */ jsx("div", { className: `flex flex-col ${compact ? "items-center" : ""} gap-1`, children: sortedItems.map((item) => renderSectionItem(item)) }),
645
- sectionIndex !== lastVisibleIndex && /* @__PURE__ */ jsx("div", { className: `my-2 border-t ${compact ? "-ml-2 -mr-3" : "-ml-3 -mr-4"}` })
646
- ] }, section.id);
637
+ return /* @__PURE__ */ jsxs(
638
+ "div",
639
+ {
640
+ className: `${blockPadding} ${sectionIndex !== lastVisibleIndex ? "border-b pb-2" : ""}`,
641
+ "data-sidebar-group": "true",
642
+ children: [
643
+ !compact && /* @__PURE__ */ jsxs(
644
+ Button,
645
+ {
646
+ variant: "muted",
647
+ onClick: () => toggleGroup(sectionKey),
648
+ className: "w-full px-1 justify-between flex text-xs font-medium uppercase tracking-wider text-muted-foreground/70 py-1",
649
+ "aria-expanded": open,
650
+ children: [
651
+ /* @__PURE__ */ jsx("span", { children: sectionLabel }),
652
+ /* @__PURE__ */ jsx(Chevron, { open })
653
+ ]
654
+ }
655
+ ),
656
+ (open || compact) && /* @__PURE__ */ jsx("div", { className: `flex flex-col ${compact ? "items-center" : ""} gap-1`, children: sortedItems.map((item) => renderSectionItem(item)) })
657
+ ]
658
+ },
659
+ section.id
660
+ );
647
661
  }) }) })
648
662
  ] });
649
663
  }
650
664
  function renderSidebar(compact, hideHeader, forceMainOnly) {
665
+ const blockPadding = sidebarBlockPadding(compact);
666
+ const injectionWrapper = sidebarInjectionWrapper(compact);
651
667
  if (!isChromeReady && isChromeLoading) {
652
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-h-full gap-3", "data-testid": "backend-chrome-loading", children: [
668
+ return /* @__PURE__ */ jsxs("div", { className: `flex min-h-full flex-col gap-3 ${blockPadding}`, "data-testid": "backend-chrome-loading", children: [
653
669
  !hideHeader ? /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs(
654
670
  Link,
655
671
  {
@@ -662,7 +678,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
662
678
  ]
663
679
  }
664
680
  ) }) : null,
665
- /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3 pr-1", children: [
681
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-3", children: [
666
682
  /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
667
683
  /* @__PURE__ */ jsx("div", { className: "h-8 rounded bg-muted/50" }),
668
684
  /* @__PURE__ */ jsxs("div", { className: "space-y-2 pl-1", children: [
@@ -710,7 +726,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
710
726
  const isMobileVariant = !!hideHeader;
711
727
  const shouldRenderSidebarInjectionSpots = !isMobileVariant;
712
728
  return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col gap-3", children: [
713
- !hideHeader && /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs(
729
+ !hideHeader && /* @__PURE__ */ jsx("div", { className: `mb-2 ${blockPadding}`, children: /* @__PURE__ */ jsxs(
714
730
  Link,
715
731
  {
716
732
  href: "/backend",
@@ -722,14 +738,14 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
722
738
  ]
723
739
  }
724
740
  ) }),
725
- shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
741
+ shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx("div", { className: injectionWrapper, "data-sidebar-injection-wrapper": "true", children: /* @__PURE__ */ jsx(
726
742
  InjectionSpot,
727
743
  {
728
744
  spotId: BACKEND_SIDEBAR_TOP_INJECTION_SPOT_ID,
729
745
  context: injectionContext
730
746
  }
731
- ) : null,
732
- !compact && /* @__PURE__ */ jsx(
747
+ ) }) : null,
748
+ !compact && /* @__PURE__ */ jsx("div", { className: blockPadding, children: /* @__PURE__ */ jsx(
733
749
  SearchInput,
734
750
  {
735
751
  value: navQuery,
@@ -739,8 +755,8 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
739
755
  clearLabel: t("appShell.searchNavClear", "Clear search"),
740
756
  className: "mb-2"
741
757
  }
742
- ),
743
- /* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className: `flex flex-1 flex-col gap-3 overflow-y-auto scrollbar-hide pr-1 ${compact ? "-ml-2 pl-2" : "-ml-3 pl-3"}`, children: (() => {
758
+ ) }),
759
+ /* @__PURE__ */ jsx("div", { "data-sidebar-scroll": "true", className: "flex flex-1 flex-col gap-3 overflow-x-hidden overflow-y-auto scrollbar-hide", children: (() => {
744
760
  const isSettingsPath = (href) => {
745
761
  if (href === "/backend/settings") return true;
746
762
  return resolvedSettingsPathPrefixes.some((prefix) => href.startsWith(prefix));
@@ -761,13 +777,13 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
761
777
  return -1;
762
778
  })();
763
779
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("nav", { className: "flex flex-col gap-2", "data-testid": "sidebar", children: [
764
- shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
780
+ shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx("div", { className: injectionWrapper, "data-sidebar-injection-wrapper": "true", children: /* @__PURE__ */ jsx(
765
781
  InjectionSpot,
766
782
  {
767
783
  spotId: BACKEND_SIDEBAR_NAV_INJECTION_SPOT_ID,
768
784
  context: injectionContext
769
785
  }
770
- ) : null,
786
+ ) }) : null,
771
787
  mainGroups.map((g, gi) => {
772
788
  const groupId = resolveGroupKey(g);
773
789
  const open = navQueryActive ? true : openGroups[groupId] !== false;
@@ -779,87 +795,94 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
779
795
  return itemChildren.some((c) => matchesQuery(c.title));
780
796
  });
781
797
  if (visibleItems.length === 0) return null;
782
- return /* @__PURE__ */ jsxs("div", { children: [
783
- !compact && /* @__PURE__ */ jsxs(
784
- Button,
785
- {
786
- variant: "muted",
787
- onClick: () => toggleGroup(groupId),
788
- className: "w-full px-1 justify-between flex text-xs font-medium uppercase tracking-wider text-muted-foreground/70 py-1",
789
- "aria-expanded": open,
790
- children: [
791
- /* @__PURE__ */ jsx("span", { children: g.name }),
792
- /* @__PURE__ */ jsx(Chevron, { open })
793
- ]
794
- }
795
- ),
796
- (open || compact) && /* @__PURE__ */ jsx("div", { className: `flex flex-col ${compact ? "items-center" : ""} gap-1`, children: visibleItems.map((i) => {
797
- const allChildItems = (i.children ?? []).filter((child) => child.hidden !== true);
798
- const matchingChildItems = navQueryActive ? allChildItems.filter((c) => matchesQuery(c.title)) : allChildItems;
799
- const childItems = navQueryActive ? matchingChildItems : allChildItems;
800
- const showChildren = navQueryActive ? matchingChildItems.length > 0 : !!pathname && allChildItems.length > 0 && pathname.startsWith(i.href);
801
- const hasActiveChild = !!(pathname && allChildItems.some((c) => pathname.startsWith(c.href)));
802
- const isParentActive = pathname === i.href || !navQueryActive && showChildren && !hasActiveChild;
803
- const base = compact ? "w-10 h-10 justify-center" : "w-full px-3 py-2 gap-2";
804
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
805
- /* @__PURE__ */ jsxs(
806
- Link,
798
+ return /* @__PURE__ */ jsxs(
799
+ "div",
800
+ {
801
+ className: `${blockPadding} ${gi !== mainLastVisibleGroupIndex ? "border-b pb-2" : ""}`,
802
+ "data-sidebar-group": "true",
803
+ children: [
804
+ !compact && /* @__PURE__ */ jsxs(
805
+ Button,
807
806
  {
808
- href: i.href,
809
- className: `relative text-sm font-medium rounded-lg inline-flex items-center ${base} ${isParentActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted"} ${i.enabled === false ? "pointer-events-none opacity-50" : ""}`,
810
- "aria-disabled": i.enabled === false,
811
- title: compact ? i.title : void 0,
812
- "data-menu-item-id": i.id ?? i.href,
813
- onClick: () => setMobileOpen(false),
807
+ variant: "muted",
808
+ onClick: () => toggleGroup(groupId),
809
+ className: "w-full px-1 justify-between flex text-xs font-medium uppercase tracking-wider text-muted-foreground/70 py-1",
810
+ "aria-expanded": open,
814
811
  children: [
815
- isParentActive ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `absolute ${compact ? "left-[-20px]" : "left-[-12px]"} top-2 w-1 h-5 rounded-r bg-foreground` }) : null,
816
- /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center shrink-0", children: renderIcon(
817
- i.icon,
818
- i.iconName,
819
- i.iconMarkup,
820
- DefaultIcon
821
- ) }),
822
- !compact && /* @__PURE__ */ jsx("span", { children: i.title })
812
+ /* @__PURE__ */ jsx("span", { children: g.name }),
813
+ /* @__PURE__ */ jsx(Chevron, { open })
823
814
  ]
824
815
  }
825
816
  ),
826
- showChildren ? /* @__PURE__ */ jsxs("div", { className: `relative flex flex-col ${compact ? "items-center" : ""} gap-1`, children: [
827
- !compact && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute left-1.5 top-1 bottom-1 w-px bg-border" }),
828
- childItems.map((c) => {
829
- const childActive = pathname?.startsWith(c.href);
830
- const childBase = compact ? "w-10 h-8 justify-center" : "w-full pl-5 pr-3 py-2 gap-2";
831
- return /* @__PURE__ */ jsxs(
817
+ (open || compact) && /* @__PURE__ */ jsx("div", { className: `flex flex-col ${compact ? "items-center" : ""} gap-1`, children: visibleItems.map((i) => {
818
+ const allChildItems = (i.children ?? []).filter((child) => child.hidden !== true);
819
+ const matchingChildItems = navQueryActive ? allChildItems.filter((c) => matchesQuery(c.title)) : allChildItems;
820
+ const childItems = navQueryActive ? matchingChildItems : allChildItems;
821
+ const showChildren = navQueryActive ? matchingChildItems.length > 0 : !!pathname && allChildItems.length > 0 && pathname.startsWith(i.href);
822
+ const hasActiveChild = !!(pathname && allChildItems.some((c) => pathname.startsWith(c.href)));
823
+ const isParentActive = pathname === i.href || !navQueryActive && showChildren && !hasActiveChild;
824
+ const base = compact ? "w-10 h-10 justify-center" : "w-full px-3 py-2 gap-2";
825
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
826
+ /* @__PURE__ */ jsxs(
832
827
  Link,
833
828
  {
834
- href: c.href,
835
- className: `relative text-sm font-medium rounded-lg inline-flex items-center ${childBase} ${childActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted"} ${c.enabled === false ? "pointer-events-none opacity-50" : ""}`,
836
- "aria-disabled": c.enabled === false,
837
- title: compact ? c.title : void 0,
838
- "data-menu-item-id": c.id ?? c.href,
829
+ href: i.href,
830
+ className: `relative text-sm font-medium rounded-lg inline-flex items-center ${base} ${isParentActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted"} ${i.enabled === false ? "pointer-events-none opacity-50" : ""}`,
831
+ "aria-disabled": i.enabled === false,
832
+ title: compact ? i.title : void 0,
833
+ "data-menu-item-id": i.id ?? i.href,
839
834
  onClick: () => setMobileOpen(false),
840
835
  children: [
841
- childActive ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `absolute ${compact ? "left-[-20px]" : "left-[-12px]"} top-2 w-1 h-5 rounded-r bg-foreground` }) : null,
836
+ isParentActive ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `absolute ${compact ? "left-[-20px]" : "left-[-12px]"} top-2 w-1 h-5 rounded-r bg-foreground` }) : null,
842
837
  /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center shrink-0", children: renderIcon(
843
- c.icon,
844
- c.iconName,
845
- c.iconMarkup,
846
- c.href.includes("/backend/entities/user/") && c.href.endsWith("/records") ? DataTableIcon : DefaultIcon
838
+ i.icon,
839
+ i.iconName,
840
+ i.iconMarkup,
841
+ DefaultIcon
847
842
  ) }),
848
- !compact && /* @__PURE__ */ jsx("span", { children: c.title })
843
+ !compact && /* @__PURE__ */ jsx("span", { children: i.title })
849
844
  ]
850
- },
851
- c.href
852
- );
853
- })
854
- ] }) : null
855
- ] }, i.href);
856
- }) }),
857
- gi !== mainLastVisibleGroupIndex && /* @__PURE__ */ jsx("div", { className: `my-2 border-t ${compact ? "-ml-2 -mr-3" : "-ml-3 -mr-4"}` })
858
- ] }, groupId);
845
+ }
846
+ ),
847
+ showChildren ? /* @__PURE__ */ jsxs("div", { className: `relative flex flex-col ${compact ? "items-center" : ""} gap-1`, children: [
848
+ !compact && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute left-1.5 top-1 bottom-1 w-px bg-border" }),
849
+ childItems.map((c) => {
850
+ const childActive = pathname?.startsWith(c.href);
851
+ const childBase = compact ? "w-10 h-8 justify-center" : "w-full pl-5 pr-3 py-2 gap-2";
852
+ return /* @__PURE__ */ jsxs(
853
+ Link,
854
+ {
855
+ href: c.href,
856
+ className: `relative text-sm font-medium rounded-lg inline-flex items-center ${childBase} ${childActive ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted"} ${c.enabled === false ? "pointer-events-none opacity-50" : ""}`,
857
+ "aria-disabled": c.enabled === false,
858
+ title: compact ? c.title : void 0,
859
+ "data-menu-item-id": c.id ?? c.href,
860
+ onClick: () => setMobileOpen(false),
861
+ children: [
862
+ childActive ? /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `absolute ${compact ? "left-[-20px]" : "left-[-12px]"} top-2 w-1 h-5 rounded-r bg-foreground` }) : null,
863
+ /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center shrink-0", children: renderIcon(
864
+ c.icon,
865
+ c.iconName,
866
+ c.iconMarkup,
867
+ c.href.includes("/backend/entities/user/") && c.href.endsWith("/records") ? DataTableIcon : DefaultIcon
868
+ ) }),
869
+ !compact && /* @__PURE__ */ jsx("span", { children: c.title })
870
+ ]
871
+ },
872
+ c.href
873
+ );
874
+ })
875
+ ] }) : null
876
+ ] }, i.href);
877
+ }) })
878
+ ]
879
+ },
880
+ groupId
881
+ );
859
882
  })
860
883
  ] }) });
861
884
  })() }),
862
- /* @__PURE__ */ jsxs("div", { className: "sticky bottom-0 bg-background pb-1", children: [
885
+ /* @__PURE__ */ jsxs("div", { className: `sticky bottom-0 bg-background pb-1 ${injectionWrapper}`, "data-sidebar-injection-wrapper": "true", children: [
863
886
  shouldRenderSidebarInjectionSpots ? /* @__PURE__ */ jsx(
864
887
  InjectionSpot,
865
888
  {
@@ -904,7 +927,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
904
927
  }
905
928
  if (!sections) return null;
906
929
  return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col gap-2", children: [
907
- /* @__PURE__ */ jsxs(
930
+ /* @__PURE__ */ jsx("div", { className: sidebarBlockPadding(false), children: /* @__PURE__ */ jsxs(
908
931
  Link,
909
932
  {
910
933
  href: "/backend",
@@ -916,7 +939,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
916
939
  /* @__PURE__ */ jsx("span", { className: "truncate", children: title })
917
940
  ]
918
941
  }
919
- ),
942
+ ) }),
920
943
  /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: renderSectionSidebar(sections, title, false, true, true) })
921
944
  ] });
922
945
  }
@@ -974,7 +997,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
974
997
  children: effectiveCollapsed ? /* @__PURE__ */ jsx(PanelLeftOpen, { className: "size-4" }) : /* @__PURE__ */ jsx(PanelLeftClose, { className: "size-4" })
975
998
  }
976
999
  ),
977
- /* @__PURE__ */ jsxs("aside", { ref: sidebarAsideRef, className: `${asideClassesBase} ${effectiveCollapsed ? "px-2" : "px-3"} hidden lg:block lg:sticky lg:top-0 lg:h-svh lg:self-start lg:overflow-hidden lg:relative transition-[width,padding] duration-200 ease-out`, style: { width: asideWidth }, children: [
1000
+ /* @__PURE__ */ jsxs("aside", { ref: sidebarAsideRef, className: `${asideClassesBase} px-0 hidden lg:block lg:sticky lg:top-0 lg:h-svh lg:self-start lg:overflow-hidden lg:relative transition-[width] duration-200 ease-out`, style: { width: asideWidth }, children: [
978
1001
  renderSidebar(effectiveCollapsed, false, isSectionView),
979
1002
  sidebarScrollState !== "none" ? /* @__PURE__ */ jsx(
980
1003
  "div",
@@ -1006,7 +1029,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
1006
1029
  isSectionView ? /* @__PURE__ */ jsxs(
1007
1030
  "aside",
1008
1031
  {
1009
- className: `${asideClassesBase} px-3 hidden lg:block lg:sticky lg:top-0 lg:h-svh lg:self-start lg:overflow-hidden lg:relative`,
1032
+ className: `${asideClassesBase} px-0 hidden lg:block lg:sticky lg:top-0 lg:h-svh lg:self-start lg:overflow-hidden lg:relative`,
1010
1033
  style: { width: "240px" },
1011
1034
  "data-testid": "appshell-section-sidebar",
1012
1035
  children: [
@@ -1166,7 +1189,7 @@ function AppShellBody({ productName, logo, email, canManageUpgradeActions = fals
1166
1189
  id: "mobile-drawer-tabpanel",
1167
1190
  role: sidebarMode !== "main" ? "tabpanel" : void 0,
1168
1191
  "aria-labelledby": sidebarMode !== "main" ? `mobile-drawer-tab-${mobileDrawerView === "main" ? "main" : "section"}` : void 0,
1169
- className: "min-h-0 flex-1 overflow-y-auto overflow-x-hidden p-3",
1192
+ className: "min-h-0 flex-1 overflow-y-auto overflow-x-hidden py-3",
1170
1193
  children: renderSidebar(false, true, mobileDrawerView === "main")
1171
1194
  }
1172
1195
  )